mirror of
https://github.com/zuiidea/antd-admin
synced 2026-10-21 23:23:43 +00:00
add Posts Page
This commit is contained in:
@@ -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",
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
@@ -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,
|
||||
})
|
||||
},
|
||||
}
|
||||
@@ -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,
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
},
|
||||
},
|
||||
})
|
||||
+11
-36
@@ -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 }
|
||||
},
|
||||
|
||||
},
|
||||
|
||||
}
|
||||
})
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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) => <img alt="Feture" width={26} src={text} />,
|
||||
}, {
|
||||
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 (
|
||||
<div>
|
||||
<Table
|
||||
{...tableProps}
|
||||
bordered
|
||||
scroll={{ x: 1200 }}
|
||||
columns={columns}
|
||||
simple
|
||||
className={styles.table}
|
||||
rowKey={record => record.id}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default List
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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 (<div className="content-inner">
|
||||
<Tabs activeKey={query.status === String(EnumPostStatus.UNPUBLISH) ? String(EnumPostStatus.UNPUBLISH) : String(EnumPostStatus.PUBLISHED)} onTabClick={handleTabClick}>
|
||||
<TabPane tab="Publised" key={String(EnumPostStatus.PUBLISHED)}>
|
||||
<List {...listProps} />
|
||||
</TabPane>
|
||||
<TabPane tab="Unpublish" key={String(EnumPostStatus.UNPUBLISH)}>
|
||||
<List {...listProps} />
|
||||
</TabPane>
|
||||
</Tabs>
|
||||
</div>)
|
||||
}
|
||||
|
||||
Index.propTypes = {
|
||||
post: PropTypes.object,
|
||||
loading: PropTypes.object,
|
||||
location: PropTypes.object,
|
||||
dispatch: PropTypes.func,
|
||||
}
|
||||
|
||||
export default connect(({ post, loading }) => ({ post, loading }))(Index)
|
||||
@@ -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,
|
||||
})
|
||||
}
|
||||
@@ -15,6 +15,7 @@ module.exports = {
|
||||
userLogout: '/user/logout',
|
||||
userInfo: '/userInfo',
|
||||
users: '/users',
|
||||
posts: '/posts',
|
||||
user: '/user/:id',
|
||||
dashboard: '/dashboard',
|
||||
},
|
||||
|
||||
+8
-1
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user