From 0295da63264cd0e356a432bf5bfb2d6fc3f3b42f Mon Sep 17 00:00:00 2001 From: zuiidea Date: Wed, 7 Jun 2017 14:24:26 +0800 Subject: [PATCH] add Posts Page --- package.json | 1 + src/mock/common.js | 63 +++++++++++++++++++++++++++++++++++++ src/mock/post.js | 31 +++++++++++++++++++ src/models/common.js | 47 ++++++++++++++++++++++++++++ src/models/post.js | 44 ++++++++++++++++++++++++++ src/models/user.js | 47 +++++++--------------------- src/router.js | 8 +++++ src/routes/post/List.js | 55 +++++++++++++++++++++++++++++++++ src/routes/post/List.less | 16 ++++++++++ src/routes/post/index.js | 65 +++++++++++++++++++++++++++++++++++++++ src/services/posts.js | 11 +++++++ src/utils/config.js | 1 + src/utils/menu.js | 9 +++++- 13 files changed, 361 insertions(+), 37 deletions(-) create mode 100644 src/mock/common.js create mode 100644 src/mock/post.js create mode 100644 src/models/common.js create mode 100644 src/models/post.js create mode 100644 src/routes/post/List.js create mode 100644 src/routes/post/List.less create mode 100644 src/routes/post/index.js create mode 100644 src/services/posts.js diff --git a/package.json b/package.json index 1d45fb4..0592a2c 100644 --- a/package.json +++ b/package.json @@ -26,6 +26,7 @@ "babel-polyfill": "^6.23.0", "babel-runtime": "^6.9.2", "draftjs-to-html": "^0.7.0", + "dva-model-extend": "^0.1.1", "eslint": "^3.17.1", "eslint-config-airbnb": "^9.0.1", "eslint-plugin-import": "^1.16.0", diff --git a/src/mock/common.js b/src/mock/common.js new file mode 100644 index 0000000..c8b79e9 --- /dev/null +++ b/src/mock/common.js @@ -0,0 +1,63 @@ +const Mock = require('mockjs') +const config = require('../utils/config') + +const queryArray = (array, key, keyAlias = 'key') => { + if (!(array instanceof Array)) { + return null + } + let data + + for (const item of array) { + if (item[keyAlias] === key) { + data = item + break + } + } + + if (data) { + return data + } + return null +} + +const NOTFOUND = { + message: 'Not Found', + documentation_url: 'http://localhost:8000/request', +} + + +let postId = 0 +const posts = Mock.mock({ + 'data|100': [ + { + id () { + postId += 1 + return postId + 10000 + }, + 'status|1-2': 1, + title: '@title', + author: '@last', + categories: '@word', + tags: '@word', + 'views|10-200': 1, + 'comments|10-200': 1, + visibility: () => { + return Mock.mock('@pick(["Public",' + + '"Password protected", ' + + '"Private"])') + }, + date: '@dateTime', + image () { + return Mock.Random.image('100x100', Mock.Random.color(), '#757575', 'png', this.author.substr(0, 1)) + }, + }, + ], +}).data + +module.exports = { + queryArray, + NOTFOUND, + Mock, + posts, + config, +} diff --git a/src/mock/post.js b/src/mock/post.js new file mode 100644 index 0000000..002fa19 --- /dev/null +++ b/src/mock/post.js @@ -0,0 +1,31 @@ +const { config, posts } = require('./common') + +const { apiPrefix } = config +let database = posts + +module.exports = { + + [`GET ${apiPrefix}/posts`] (req, res) { + const { query } = req + let { pageSize, page, ...other } = query + pageSize = pageSize || 10 + page = page || 1 + + let newData = database + for (let key in other) { + if ({}.hasOwnProperty.call(other, key)) { + newData = newData.filter((item) => { + if ({}.hasOwnProperty.call(item, key)) { + return String(item[key]).trim().indexOf(decodeURI(other[key]).trim()) > -1 + } + return true + }) + } + } + + res.status(200).json({ + data: newData.slice((page - 1) * pageSize, page * pageSize), + total: newData.length, + }) + }, +} diff --git a/src/models/common.js b/src/models/common.js new file mode 100644 index 0000000..3522d42 --- /dev/null +++ b/src/models/common.js @@ -0,0 +1,47 @@ +import modelExtend from 'dva-model-extend' + +const model = { + reducers: { + updateState (state, { payload }) { + return { + ...state, + ...payload, + } + }, + }, +} + +const pageModel = modelExtend(model, { + + state: { + list: [], + pagination: { + showSizeChanger: true, + showQuickJumper: true, + showTotal: total => `Total ${total} Items`, + current: 1, + total: 0, + }, + }, + + reducers: { + querySuccess (state, { payload }) { + const { list, pagination } = payload + return { + ...state, + list, + pagination: { + ...state.pagination, + ...pagination, + }, + } + }, + }, + +}) + + +module.exports = { + model, + pageModel, +} diff --git a/src/models/post.js b/src/models/post.js new file mode 100644 index 0000000..7480028 --- /dev/null +++ b/src/models/post.js @@ -0,0 +1,44 @@ +import modelExtend from 'dva-model-extend' +import { query } from '../services/posts' +import { pageModel } from './common' + +export default modelExtend(pageModel, { + + namespace: 'post', + + subscriptions: { + setup ({ dispatch, history }) { + history.listen(location => { + if (location.pathname === '/post') { + dispatch({ type: 'query', payload: { + status: 2, + ...location.query, + } }) + } + }) + }, + }, + + effects: { + *query ({ + payload, + }, { call, put }) { + const data = yield call(query, payload) + if (data.success) { + yield put({ + type: 'querySuccess', + payload: { + list: data.data, + pagination: { + current: Number(payload.page) || 1, + pageSize: Number(payload.pageSize) || 10, + total: data.total, + }, + }, + }) + } else { + throw data + } + }, + }, +}) diff --git a/src/models/user.js b/src/models/user.js index 7221dde..7db44c5 100644 --- a/src/models/user.js +++ b/src/models/user.js @@ -1,27 +1,21 @@ +import modelExtend from 'dva-model-extend' import { create, remove, update } from '../services/user' import * as usersService from '../services/users' -import { parse } from 'qs' +import { pageModel } from './common' +import { config } from '../utils' const { query } = usersService +const { prefix } = config -export default { - +export default modelExtend(pageModel, { namespace: 'user', state: { - list: [], currentItem: {}, modalVisible: false, modalType: 'create', selectedRowKeys: [], - isMotion: localStorage.getItem('antdAdminUserIsMotion') === 'true', - pagination: { - showSizeChanger: true, - showQuickJumper: true, - showTotal: total => `共 ${total} 条`, - current: 1, - total: null, - }, + isMotion: localStorage.getItem(`${prefix}userIsMotion`) === 'true', }, subscriptions: { @@ -39,8 +33,7 @@ export default { effects: { - *query ({ payload }, { call, put }) { - payload = parse(location.search.substr(1)) + *query ({ payload = {} }, { call, put }) { const data = yield call(query, payload) if (data) { yield put({ @@ -104,25 +97,8 @@ export default { reducers: { - querySuccess (state, action) { - const { list, pagination } = action.payload - return { ...state, - list, - pagination: { - ...state.pagination, - ...pagination, - } } - }, - - updateState (state, { payload }) { - return { - ...state, - ...payload, - } - }, - - showModal (state, action) { - return { ...state, ...action.payload, modalVisible: true } + showModal (state, { payload }) { + return { ...state, ...{ payload }, modalVisible: true } }, hideModal (state) { @@ -130,10 +106,9 @@ export default { }, switchIsMotion (state) { - localStorage.setItem('antdAdminUserIsMotion', !state.isMotion) + localStorage.setItem(`${prefix}userIsMotion`, !state.isMotion) return { ...state, isMotion: !state.isMotion } }, }, - -} +}) diff --git a/src/router.js b/src/router.js index ac52a9a..21d637d 100644 --- a/src/router.js +++ b/src/router.js @@ -123,6 +123,14 @@ const Routers = function ({ history, app }) { cb(null, require('./routes/chart/areaChart/')) }, 'chart-areaChart') }, + }, { + path: 'post', + getComponent (nextState, cb) { + require.ensure([], require => { + registerModel(app, require('./models/post')) + cb(null, require('./routes/post/')) + }, 'post') + }, }, { path: '*', getComponent (nextState, cb) { diff --git a/src/routes/post/List.js b/src/routes/post/List.js new file mode 100644 index 0000000..46771f0 --- /dev/null +++ b/src/routes/post/List.js @@ -0,0 +1,55 @@ +import React from 'react' +import { Table } from 'antd' +import styles from './List.less' + +const List = ({ ...tableProps }) => { + const columns = [ + { + title: 'Image', + dataIndex: 'image', + className: styles.image, + width: 64, + render: (text) => Feture, + }, { + title: 'Title', + dataIndex: 'title', + }, { + title: 'Author', + dataIndex: 'author', + }, { + title: 'Categories', + dataIndex: 'categories', + }, { + title: 'Tags', + dataIndex: 'tags', + }, { + title: 'Visibility', + dataIndex: 'visibility', + }, { + title: 'Comments', + dataIndex: 'comments', + }, { + title: 'Views', + dataIndex: 'views', + }, { + title: 'Date', + dataIndex: 'date', + }, + ] + + return ( +
+ record.id} + /> + + ) +} + +export default List diff --git a/src/routes/post/List.less b/src/routes/post/List.less new file mode 100644 index 0000000..941c0fc --- /dev/null +++ b/src/routes/post/List.less @@ -0,0 +1,16 @@ +.table { + td.image { + line-height: 1; + + img { + border-radius: 2px; + } + } + + :global { + .ant-table-tbody > tr > td, + .ant-table-thead > tr > th { + height: 60px; + } + } +} diff --git a/src/routes/post/index.js b/src/routes/post/index.js new file mode 100644 index 0000000..40be20d --- /dev/null +++ b/src/routes/post/index.js @@ -0,0 +1,65 @@ +import React from 'react' +import PropTypes from 'prop-types' +import { connect } from 'dva' +import { Tabs } from 'antd' +import { routerRedux } from 'dva/router' +import List from './List' + +const TabPane = Tabs.TabPane + +const EnumPostStatus = { + UNPUBLISH: 1, + PUBLISHED: 2, +} + + +const Index = ({ post, dispatch, loading, location }) => { + const { list, pagination } = post + const { query = {}, pathname } = location + + const listProps = { + pagination, + dataSource: list, + loading: loading.effects['post/query'], + onChange (page) { + dispatch(routerRedux.push({ + pathname, + query: { + ...query, + page: page.current, + pageSize: page.pageSize, + }, + })) + }, + } + + const handleTabClick = (key) => { + dispatch(routerRedux.push({ + pathname, + query: { + status: key, + }, + })) + } + + + return (
+ + + + + + + + +
) +} + +Index.propTypes = { + post: PropTypes.object, + loading: PropTypes.object, + location: PropTypes.object, + dispatch: PropTypes.func, +} + +export default connect(({ post, loading }) => ({ post, loading }))(Index) diff --git a/src/services/posts.js b/src/services/posts.js new file mode 100644 index 0000000..584acbe --- /dev/null +++ b/src/services/posts.js @@ -0,0 +1,11 @@ +import { request, config } from '../utils' +const { api } = config +const { posts } = api + +export async function query (params) { + return request({ + url: posts, + method: 'get', + data: params, + }) +} diff --git a/src/utils/config.js b/src/utils/config.js index 6682ae7..1e80155 100644 --- a/src/utils/config.js +++ b/src/utils/config.js @@ -15,6 +15,7 @@ module.exports = { userLogout: '/user/logout', userInfo: '/userInfo', users: '/users', + posts: '/posts', user: '/user/:id', dashboard: '/dashboard', }, diff --git a/src/utils/menu.js b/src/utils/menu.js index 8bc2340..9242b9e 100644 --- a/src/utils/menu.js +++ b/src/utils/menu.js @@ -8,10 +8,17 @@ module.exports = [ { id: 2, bpid: 1, - name: 'User Manage', + name: 'Users', icon: 'user', router: '/user', }, + { + id: 7, + bpid: 1, + name: 'Posts', + icon: 'shopping-cart', + router: '/post', + }, { id: 21, mpid: -1,