diff --git a/src/components/Layout/Bread.js b/src/components/Layout/Bread.js index 4e25869..7566c54 100644 --- a/src/components/Layout/Bread.js +++ b/src/components/Layout/Bread.js @@ -6,7 +6,7 @@ import styles from './Bread.less' import pathToRegexp from 'path-to-regexp' import { queryArray } from '../../utils' -const Bread = ({ location, menu }) => { +const Bread = ({ menu }) => { // 匹配当前路由 let pathArray = [] let current @@ -63,7 +63,6 @@ const Bread = ({ location, menu }) => { Bread.propTypes = { menu: PropTypes.array, - location: PropTypes.object, } export default Bread diff --git a/src/mock/users.js b/src/mock/users.js index 0a87912..8c8f335 100644 --- a/src/mock/users.js +++ b/src/mock/users.js @@ -6,7 +6,7 @@ const { apiPrefix } = config let usersListData = Mock.mock({ 'data|100': [ { - 'id|+1': 1, + id: '@id', name: '@cname', nickName: '@last', phone: /^1[34578]\d{9}$/, @@ -20,12 +20,11 @@ let usersListData = Mock.mock({ }, }, ], - page: { - total: 100, - current: 1, - }, }) + +let database = usersListData.data + const userPermission = { DEFAULT: [ 'dashboard', 'chart', @@ -55,6 +54,31 @@ const adminUsers = [ }, ] + +const queryArray = (array, key, keyAlias = 'key') => { + if (!(array instanceof Array)) { + return null + } + let data + + for (let 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', +} + module.exports = { [`POST ${apiPrefix}/user/login`] (req, res) { @@ -105,83 +129,75 @@ module.exports = { }, [`GET ${apiPrefix}/users`] (req, res) { - const page = req.query - const pageSize = page.pageSize || 10 - const currentPage = page.page || 1 + const { query } = req + const pageSize = query.pageSize || 10 + const currentPage = query.page || 1 let data - let newPage + let total - let newData = usersListData.data.concat() - - if (page.field) { - const d = newData.filter((item) => { - return item[page.field].indexOf(decodeURI(page.keyword)) > -1 - }) - - data = d.slice((currentPage - 1) * pageSize, currentPage * pageSize) - - newPage = { - current: currentPage * 1, - total: d.length, - } + if (query.field) { + const newData = database.filter((item) => item[query.field].indexOf(decodeURI(query.keyword)) > -1) + data = newData.slice((currentPage - 1) * pageSize, currentPage * pageSize) + total = newData.length } else { - data = usersListData.data.slice((currentPage - 1) * pageSize, currentPage * pageSize) - usersListData.page.current = currentPage * 1 - newPage = usersListData.page + data = database.slice((currentPage - 1) * pageSize, currentPage * pageSize) + total = database.length } - res.json({ - success: true, + + res.status(200).json({ data, - page: { - ...newPage, - pageSize: Number(pageSize), - }, + total, }) }, - [`POST ${apiPrefix}/users`] (req, res) { + [`POST ${apiPrefix}/user`] (req, res) { const newData = req.body newData.createTime = Mock.mock('@now') - newData.avatar = Mock.Random.image('100x100', Mock.Random.color(), '#757575', 'png', newData.nickName.substr(0, 1)) + newData.avatar = newData.avatar || Mock.Random.image('100x100', Mock.Random.color(), '#757575', 'png', newData.nickName.substr(0, 1)) + newData.id = Mock.mock('@id') - newData.id = usersListData.data.length + 1 - usersListData.data.unshift(newData) + database.unshift(newData) - usersListData.page.total = usersListData.data.length - usersListData.page.current = 1 - - res.json({ success: true, data: usersListData.data, page: usersListData.page }) + res.status(200).end() }, - [`DELETE ${apiPrefix}/users`] (req, res) { - const deleteItem = req.body - - usersListData.data = usersListData.data.filter((item) => { - if (item.id === deleteItem.id) { - return false - } - return true - }) - - usersListData.page.total = usersListData.data.length - - res.json({ success: true, data: usersListData.data, page: usersListData.page }) + [`GET ${apiPrefix}/user/:id`] (req, res) { + const { id } = req.params + const data = queryArray(database, id, 'id') + if (data) { + res.status(200).json(data) + } else { + res.status(404).json(NOTFOUND) + } }, - [`PUT ${apiPrefix}/users`] (req, res) { + [`DELETE ${apiPrefix}/user/:id`] (req, res) { + const { id } = req.params + if (!id) { + res.status(400).end() + } + database = database.filter((item) => item.id !== id) + res.status(204).end() + }, + + [`PATCH ${apiPrefix}/user/:id`] (req, res) { + const { id } = req.params const editItem = req.body + let isExist = false - editItem.createTime = Mock.mock('@now') - editItem.avatar = Mock.Random.image('100x100', Mock.Random.color(), '#757575', 'png', editItem.nickName.substr(0, 1)) - - usersListData.data = usersListData.data.map((item) => { - if (item.id === editItem.id) { - return editItem + database = database.map((item) => { + if (item.id === id) { + isExist = true + return Object.assign({}, item, editItem) } return item }) - res.json({ success: true, data: usersListData.data, page: usersListData.page }) + if (isExist) { + res.status(201).end() + } else { + res.status(404).json(NOTFOUND) + } }, } diff --git a/src/models/users.js b/src/models/user.js similarity index 68% rename from src/models/users.js rename to src/models/user.js index 4d432c1..80a80e2 100644 --- a/src/models/users.js +++ b/src/models/user.js @@ -1,9 +1,11 @@ -import { create, remove, update, query } from '../services/users' +import { create, remove, update } from '../services/user' +import { query } from '../services/users' +import { routerRedux } from 'dva/router' import { parse } from 'qs' export default { - namespace: 'users', + namespace: 'user', state: { list: [], @@ -23,7 +25,7 @@ export default { subscriptions: { setup ({ dispatch, history }) { history.listen(location => { - if (location.pathname === '/users') { + if (location.pathname === '/user') { dispatch({ type: 'query', payload: location.query, @@ -34,14 +36,24 @@ export default { }, effects: { + *requery ({ payload }, { put }) { + yield put(routerRedux.push({ + pathname: location.pathname, + query: parse(location.search.substr(1)), + })) + }, *query ({ payload }, { call, put }) { - const data = yield call(query, parse(payload)) + const data = yield call(query, payload) if (data) { yield put({ type: 'querySuccess', payload: { list: data.data, - pagination: data.page, + pagination: { + current: Number(payload.page) || 1, + pageSize: Number(payload.pageSize) || 10, + total: data.total, + }, }, }) } @@ -49,50 +61,29 @@ export default { *'delete' ({ payload }, { call, put }) { const data = yield call(remove, { id: payload }) if (data && data.success) { - yield put({ - type: 'querySuccess', - payload: { - list: data.data, - pagination: { - total: data.page.total, - current: data.page.current, - }, - }, - }) + yield put({ type: 'requery' }) + } else { + throw data } }, *create ({ payload }, { call, put }) { yield put({ type: 'hideModal' }) const data = yield call(create, payload) if (data && data.success) { - yield put({ - type: 'querySuccess', - payload: { - list: data.data, - pagination: { - total: data.page.total, - current: data.page.current, - }, - }, - }) + yield put({ type: 'requery' }) + } else { + throw data } }, *update ({ payload }, { select, call, put }) { yield put({ type: 'hideModal' }) - const id = yield select(({ users }) => users.currentItem.id) + const id = yield select(({ user }) => user.currentItem.id) const newUser = { ...payload, id } const data = yield call(update, newUser) if (data && data.success) { - yield put({ - type: 'querySuccess', - payload: { - list: data.data, - pagination: { - total: data.page.total, - current: data.page.current, - }, - }, - }) + yield put({ type: 'requery' }) + } else { + throw data } }, *switchIsMotion ({ diff --git a/src/routes/users/detail/index.js b/src/models/user/detail.js similarity index 100% rename from src/routes/users/detail/index.js rename to src/models/user/detail.js diff --git a/src/models/user/index.js b/src/models/user/index.js new file mode 100644 index 0000000..e69de29 diff --git a/src/router.js b/src/router.js index 7d080d7..318af94 100644 --- a/src/router.js +++ b/src/router.js @@ -30,12 +30,12 @@ const Routers = function ({ history, app }) { }, 'dashboard') }, }, { - path: 'users', + path: 'user', getComponent (nextState, cb) { require.ensure([], require => { - registerModel(app, require('./models/users')) - cb(null, require('./routes/users/')) - }, 'users') + registerModel(app, require('./models/user')) + cb(null, require('./routes/user/')) + }, 'user') }, }, { path: 'login', diff --git a/src/routes/request/index.js b/src/routes/request/index.js index 1d68abb..42afd83 100644 --- a/src/routes/request/index.js +++ b/src/routes/request/index.js @@ -11,7 +11,7 @@ import { Button, } from 'antd' const { api, baseURL } = config -const { userInfo, dashboard, users, userLogin } = api +const { userInfo, dashboard, users, userLogin, user } = api const requestOptions = [ { @@ -22,25 +22,31 @@ const requestOptions = [ url: baseURL + dashboard, desc: 'intercept request by mock.js', }, - { - url: baseURL + users, - desc: 'intercept request by mock.js', - }, { url: baseURL + userLogin, method: 'post', data: { - username: 'admin', - password: 'admin6', + username: 'guest', + password: 'guest', }, desc: 'intercept request by mock.js', }, { url: baseURL + users, desc: 'intercept request by mock.js', + }, + { + url: baseURL + user, + desc: 'intercept request by mock.js', + data: Mock.mock({ + id: '@id', + }), + }, + { + url: baseURL + user.replace('/:id', ''), + desc: 'intercept request by mock.js', method: 'post', data: Mock.mock({ - 'id|+1': 1000, name: '@cname', nickName: '@last', phone: /^1[34578]\d{9}$/, @@ -48,37 +54,26 @@ const requestOptions = [ address: '@county(true)', isMale: '@boolean', email: '@email', - createTime: '@datetime', avatar () { return Mock.Random.image('100x100', Mock.Random.color(), '#757575', 'png', this.nickName.substr(0, 1)) }, }), }, { - url: baseURL + users, + url: baseURL + user, desc: 'intercept request by mock.js', - method: 'put', + method: 'patch', data: Mock.mock({ - id: 1, + id: '@id', name: '@cname', - nickName: '@last', - phone: /^1[34578]\d{9}$/, - 'age|11-99': 1, - address: '@county(true)', - isMale: '@boolean', - email: '@email', - createTime: '@datetime', - avatar () { - return Mock.Random.image('100x100', Mock.Random.color(), '#757575', 'png', this.nickName.substr(0, 1)) - }, }), }, { - url: baseURL + users, + url: baseURL + user, desc: 'intercept request by mock.js', method: 'delete', data: Mock.mock({ - id: 10, + id: '@id', }), }, { diff --git a/src/routes/users/UserFilter.js b/src/routes/user/UserFilter.js similarity index 100% rename from src/routes/users/UserFilter.js rename to src/routes/user/UserFilter.js diff --git a/src/routes/users/UserList.js b/src/routes/user/UserList.js similarity index 97% rename from src/routes/users/UserList.js rename to src/routes/user/UserList.js index 19983b6..0c5593c 100644 --- a/src/routes/users/UserList.js +++ b/src/routes/user/UserList.js @@ -35,7 +35,7 @@ function list ({ loading, dataSource, pagination, onPageChange, onDeleteItem, on title: '姓名', dataIndex: 'name', key: 'name', - render: (text, record) => {text}, + render: (text, record) => {text}, }, { title: '昵称', dataIndex: 'nickName', diff --git a/src/routes/users/UserList.less b/src/routes/user/UserList.less similarity index 100% rename from src/routes/users/UserList.less rename to src/routes/user/UserList.less diff --git a/src/routes/users/UserModal.js b/src/routes/user/UserModal.js similarity index 100% rename from src/routes/users/UserModal.js rename to src/routes/user/UserModal.js diff --git a/src/routes/user/detail/index.js b/src/routes/user/detail/index.js new file mode 100644 index 0000000..e69de29 diff --git a/src/routes/users/index.js b/src/routes/user/index.js similarity index 80% rename from src/routes/users/index.js rename to src/routes/user/index.js index b8c7530..cddc2ce 100644 --- a/src/routes/users/index.js +++ b/src/routes/user/index.js @@ -6,8 +6,8 @@ import UserList from './UserList' import UserFilter from './UserFilter' import UserModal from './UserModal' -function Users ({ location, dispatch, users, loading }) { - const { list, pagination, currentItem, modalVisible, modalType, isMotion } = users +function Users ({ location, dispatch, user, loading }) { + const { list, pagination, currentItem, modalVisible, modalType, isMotion } = user const { field, keyword } = location.query const userModalProps = { @@ -16,13 +16,13 @@ function Users ({ location, dispatch, users, loading }) { visible: modalVisible, onOk (data) { dispatch({ - type: `users/${modalType}`, + type: `user/${modalType}`, payload: data, }) }, onCancel () { dispatch({ - type: 'users/hideModal', + type: 'user/hideModal', }) }, } @@ -46,13 +46,13 @@ function Users ({ location, dispatch, users, loading }) { }, onDeleteItem (id) { dispatch({ - type: 'users/delete', + type: 'user/delete', payload: id, }) }, onEditItem (item) { dispatch({ - type: 'users/showModal', + type: 'user/showModal', payload: { modalType: 'update', currentItem: item, @@ -67,25 +67,25 @@ function Users ({ location, dispatch, users, loading }) { isMotion, onSearch (fieldsValue) { fieldsValue.keyword.length ? dispatch(routerRedux.push({ - pathname: '/users', + pathname: '/user', query: { field: fieldsValue.field, keyword: fieldsValue.keyword, }, })) : dispatch(routerRedux.push({ - pathname: '/users', + pathname: '/user', })) }, onAdd () { dispatch({ - type: 'users/showModal', + type: 'user/showModal', payload: { modalType: 'create', }, }) }, switchIsMotion () { - dispatch({ type: 'users/switchIsMotion' }) + dispatch({ type: 'user/switchIsMotion' }) }, } @@ -102,10 +102,10 @@ function Users ({ location, dispatch, users, loading }) { } Users.propTypes = { - users: PropTypes.object, + user: PropTypes.object, location: PropTypes.object, dispatch: PropTypes.func, loading: PropTypes.bool, } -export default connect(({ users, loading }) => ({ users, loading: loading.models.users }))(Users) +export default connect(({ user, loading }) => ({ user, loading: loading.models.user }))(Users) diff --git a/src/services/user.js b/src/services/user.js new file mode 100644 index 0000000..2dca4e3 --- /dev/null +++ b/src/services/user.js @@ -0,0 +1,35 @@ +import { request, config } from '../utils' +const { api } = config +const { user } = api + +export async function query (params) { + return request({ + url: user, + method: 'get', + data: params, + }) +} + +export async function create (params) { + return request({ + url: user.replace('/:id', ''), + method: 'post', + data: params, + }) +} + +export async function remove (params) { + return request({ + url: user, + method: 'delete', + data: params, + }) +} + +export async function update (params) { + return request({ + url: user, + method: 'patch', + data: params, + }) +} diff --git a/src/services/users.js b/src/services/users.js index bb4645c..06b1b90 100644 --- a/src/services/users.js +++ b/src/services/users.js @@ -9,27 +9,3 @@ export async function query (params) { data: params, }) } - -export async function create (params) { - return request({ - url: users, - method: 'post', - data: params, - }) -} - -export async function remove (params) { - return request({ - url: users, - method: 'delete', - data: params, - }) -} - -export async function update (params) { - return request({ - url: users, - method: 'put', - data: params, - }) -} diff --git a/src/utils/config.js b/src/utils/config.js index e9eb85c..110d53d 100644 --- a/src/utils/config.js +++ b/src/utils/config.js @@ -6,7 +6,7 @@ module.exports = { iconFontUrl: '//at.alicdn.com/t/font_c4y7asse3q1cq5mi.js', baseURL: 'http://localhost:8000/api/v1', YQL: ['http://www.zuimeitianqi.com'], - CORS: ['http://localhost:7001'], + CORS: ['http://localhost:7001', 'http://192.168.1.110:8000'], openPages: ['/login'], apiPrefix: '/api/v1', api: { @@ -14,6 +14,7 @@ module.exports = { userLogout: '/user/logout', userInfo: '/userInfo', users: '/users', + user: '/user/:id', dashboard: '/dashboard', }, } diff --git a/src/utils/menu.js b/src/utils/menu.js index ebfbe95..4042682 100644 --- a/src/utils/menu.js +++ b/src/utils/menu.js @@ -10,14 +10,14 @@ module.exports = [ bpid: 1, name: 'User Manage', icon: 'user', - router: '/users', + router: '/user', }, { id: 21, mpid: -1, bpid: 2, name: 'User Detail', - router: '/users/:id', + router: '/user/:id', }, { id: 3, diff --git a/src/utils/request.js b/src/utils/request.js index eb4816c..8050786 100644 --- a/src/utils/request.js +++ b/src/utils/request.js @@ -3,10 +3,11 @@ import qs from 'qs' import { YQL, CORS, baseURL } from './config' import jsonp from 'jsonp' import lodash from 'lodash' +import pathToRegexp from 'path-to-regexp' +import { message } from 'antd' axios.defaults.baseURL = baseURL - const fetch = (options) => { let { method = 'get', @@ -15,6 +16,26 @@ const fetch = (options) => { url, } = options + const cloneData = lodash.cloneDeep(data) + + try { + let domin = '' + if (url.match(/[a-zA-z]+:\/\/[^/]*/)) { + domin = url.match(/[a-zA-z]+:\/\/[^/]*/)[0] + url = url.slice(domin.length) + } + const match = pathToRegexp.parse(url) + url = pathToRegexp.compile(url)(data) + for (let item of match) { + if (item instanceof Object && item.name in cloneData) { + delete cloneData[item.name] + } + } + url = domin + url + } catch (e) { + message.error(e.message) + } + if (fetchType === 'JSONP') { return new Promise((resolve, reject) => { jsonp(url, { @@ -35,17 +56,19 @@ const fetch = (options) => { switch (method.toLowerCase()) { case 'get': - return axios.get(`${url}${!lodash.isEmpty(data) ? `?${qs.stringify(data)}` : ''}`) + return axios.get(url, { + params: cloneData, + }) case 'delete': - return axios.delete(url, { data }) - case 'head': - return axios.head(url, data) + return axios.delete(url, { + data: cloneData, + }) case 'post': - return axios.post(url, data) + return axios.post(url, cloneData) case 'put': - return axios.put(url, data) + return axios.put(url, cloneData) case 'patch': - return axios.patch(url, data) + return axios.patch(url, cloneData) default: return axios(options) } @@ -76,16 +99,16 @@ export default function request (options) { } }).catch((error) => { const { response } = error - let message + let msg let status if (response) { status = response.status const { data, statusText } = response - message = data.message || statusText + msg = data.message || statusText } else { status = 600 - message = 'Network Error' + msg = 'Network Error' } - return { success: false, status, message } + return { success: false, status, message: msg } }) }