user API restful

This commit is contained in:
zuiidea
2017-04-27 17:29:50 +08:00
parent 0b0c7c3f91
commit 19ee8eacce
18 changed files with 214 additions and 178 deletions
+1 -2
View File
@@ -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
+76 -60
View File
@@ -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)
}
},
}
+27 -36
View File
@@ -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 ({
View File
+4 -4
View File
@@ -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',
+19 -24
View File
@@ -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',
}),
},
{
@@ -35,7 +35,7 @@ function list ({ loading, dataSource, pagination, onPageChange, onDeleteItem, on
title: '姓名',
dataIndex: 'name',
key: 'name',
render: (text, record) => <Link to={`users/${record.id}`}>{text}</Link>,
render: (text, record) => <Link to={`user/${record.id}`}>{text}</Link>,
}, {
title: '昵称',
dataIndex: 'nickName',
View File
@@ -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)
+35
View File
@@ -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,
})
}
-24
View File
@@ -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,
})
}
+2 -1
View File
@@ -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',
},
}
+2 -2
View File
@@ -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,
+35 -12
View File
@@ -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 }
})
}