From 34ccb19f4cef73b90e22cd540d334371f31cdd07 Mon Sep 17 00:00:00 2001 From: zuiidea Date: Mon, 10 Oct 2016 22:25:56 +0800 Subject: [PATCH] user --- .../{ => Layout}/Breadcrumb/index.js | 0 src/components/{ => Layout}/Footer/index.js | 0 src/components/{ => Layout}/Header/index.js | 0 src/components/{ => Layout}/Header/index.less | 0 src/components/{ => Layout}/Sidebar/index.js | 0 src/components/Users/UserList.jsx | 67 ++++++++ src/components/Users/UserModal.jsx | 109 +++++++++++++ src/components/Users/UserSearch.jsx | 65 ++++++++ src/components/Users/UserSearch.less | 8 + src/models/example.js | 24 --- src/models/users.js | 144 ++++++++++++++++++ 11 files changed, 393 insertions(+), 24 deletions(-) rename src/components/{ => Layout}/Breadcrumb/index.js (100%) rename src/components/{ => Layout}/Footer/index.js (100%) rename src/components/{ => Layout}/Header/index.js (100%) rename src/components/{ => Layout}/Header/index.less (100%) rename src/components/{ => Layout}/Sidebar/index.js (100%) create mode 100644 src/components/Users/UserList.jsx create mode 100644 src/components/Users/UserModal.jsx create mode 100644 src/components/Users/UserSearch.jsx create mode 100644 src/components/Users/UserSearch.less delete mode 100644 src/models/example.js create mode 100644 src/models/users.js diff --git a/src/components/Breadcrumb/index.js b/src/components/Layout/Breadcrumb/index.js similarity index 100% rename from src/components/Breadcrumb/index.js rename to src/components/Layout/Breadcrumb/index.js diff --git a/src/components/Footer/index.js b/src/components/Layout/Footer/index.js similarity index 100% rename from src/components/Footer/index.js rename to src/components/Layout/Footer/index.js diff --git a/src/components/Header/index.js b/src/components/Layout/Header/index.js similarity index 100% rename from src/components/Header/index.js rename to src/components/Layout/Header/index.js diff --git a/src/components/Header/index.less b/src/components/Layout/Header/index.less similarity index 100% rename from src/components/Header/index.less rename to src/components/Layout/Header/index.less diff --git a/src/components/Sidebar/index.js b/src/components/Layout/Sidebar/index.js similarity index 100% rename from src/components/Sidebar/index.js rename to src/components/Layout/Sidebar/index.js diff --git a/src/components/Users/UserList.jsx b/src/components/Users/UserList.jsx new file mode 100644 index 0000000..3f8a68f --- /dev/null +++ b/src/components/Users/UserList.jsx @@ -0,0 +1,67 @@ +import React, { PropTypes } from 'react'; +import { Table, Popconfirm, Pagination } from 'antd'; + +function UserList({ + total, current, loading, dataSource, + onPageChange, + onDeleteItem, + onEditItem, + }) { + const columns = [{ + title: '姓名', + dataIndex: 'name', + key: 'name', + render: (text) => {text}, + }, { + title: '年龄', + dataIndex: 'age', + key: 'age', + }, { + title: '住址', + dataIndex: 'address', + key: 'address', + }, { + title: '操作', + key: 'operation', + render: (text, record) => ( +

+ onEditItem(record)}>编辑 +   + onDeleteItem(record.id)}> + 删除 + +

+ ), + }]; + + return ( +
+ record.id} + pagination={false} + /> + + + ); +} + +UserList.propTypes = { + onPageChange: PropTypes.func, + onDeleteItem: PropTypes.func, + onEditItem: PropTypes.func, + dataSource: PropTypes.array, + loading: PropTypes.any, + total: PropTypes.any, + current: PropTypes.any, +}; + +export default UserList; diff --git a/src/components/Users/UserModal.jsx b/src/components/Users/UserModal.jsx new file mode 100644 index 0000000..116126e --- /dev/null +++ b/src/components/Users/UserModal.jsx @@ -0,0 +1,109 @@ +import React, { PropTypes } from 'react' +import { Form, Input, Modal } from 'antd' +const FormItem = Form.Item + +const formItemLayout = { + labelCol: { + span: 6, + }, + wrapperCol: { + span: 14, + }, +} + +const UserModal = ({ + visible, + item = {}, + onOk, + onCancel, + form: { + getFieldDecorator, + validateFields, + getFieldsValue, + }, + }) => { + function handleOk() { + validateFields((errors) => { + if (errors) { + return + } + const data = { ...getFieldsValue(), key: item.key } + onOk(data) + }) + } + + function checkNumber(rule, value, callback) { + if (!/^[\d]{1,2}$/.test(value)) { + callback(new Error('年龄不合法')) + } else { + callback() + } + } + + const modalOpts = { + title: '修改用户', + visible, + onOk: handleOk, + onCancel, + } + + return ( + +
+ + {getFieldDecorator('name', { + initialValue: item.name, + rules: [ + { required: true, message: '名称未填写' }, + ], + })( + + )} + + + {getFieldDecorator('age', { + initialValue: item.age, + rules: [ + { required: true, message: '年龄未填写' }, + { validator: checkNumber }, + ], + })( + + )} + + + {getFieldDecorator('address', { + initialValue: item.address, + rules: [ + { required: true, message: '不能为空' }, + ], + })( + + )} + + +
+ ) +} + +UserModal.propTypes = { + visible: PropTypes.any, + form: PropTypes.object, + item: PropTypes.object, + onOk: PropTypes.func, + onCancel: PropTypes.func, +} + +export default Form.create()(UserModal) diff --git a/src/components/Users/UserSearch.jsx b/src/components/Users/UserSearch.jsx new file mode 100644 index 0000000..503ac73 --- /dev/null +++ b/src/components/Users/UserSearch.jsx @@ -0,0 +1,65 @@ +import React, {PropTypes} from 'react' +import {Form, Input, Button, Select} from 'antd' +import styles from './UserSearch.less' + +const UserSearch = ({ + field, + keyword, + onSearch, + onAdd, + form: { + getFieldDecorator, + validateFields, + getFieldsValue + } +}) => { + function handleSubmit(e) { + e.preventDefault() + validateFields((errors) => { + if (!!errors) { + return + } + onSearch(getFieldsValue()) + }) + } + + return ( +
+
+
+ + {getFieldDecorator('field', { + initialValue: field || 'name' + })( + + )} + + + {getFieldDecorator('keyword', { + initialValue: keyword || '' + })()} + + + +
+
+ +
+
+ ) +} + +UserSearch.propTypes = { + form: PropTypes.object.isRequired, + onSearch: PropTypes.func, + onAdd: PropTypes.func, + field: PropTypes.string, + keyword: PropTypes.string +} + +export default Form.create()(UserSearch) diff --git a/src/components/Users/UserSearch.less b/src/components/Users/UserSearch.less new file mode 100644 index 0000000..14d06b2 --- /dev/null +++ b/src/components/Users/UserSearch.less @@ -0,0 +1,8 @@ +.normal { + display: flex; + margin-bottom: 20px; +} + +.search { + flex: 1; +} diff --git a/src/models/example.js b/src/models/example.js deleted file mode 100644 index c54bf1c..0000000 --- a/src/models/example.js +++ /dev/null @@ -1,24 +0,0 @@ - -export default { - - namespace: 'example', - - state: {}, - - subscriptions: { - setup({ dispatch, history }) { - }, - }, - - effects: { - *fetchRemote({ payload }, { call, put }) { - }, - }, - - reducers: { - fetch(state, action) { - return { ...state, ...action.payload }; - }, - }, - -} diff --git a/src/models/users.js b/src/models/users.js new file mode 100644 index 0000000..f8fd859 --- /dev/null +++ b/src/models/users.js @@ -0,0 +1,144 @@ +import {create, remove, update, query} from '../services/users' +import {parse} from 'qs' + +export default { + + namespace : 'users', + + state : { + list: [], + loading: false, + total: null, + current: 1, + currentItem: {}, + modalVisible: false, + modalType: 'create' + }, + + subscriptions : { + setup({dispatch, history}) { + history.listen(location => { + if (location.pathname === '/users') { + dispatch({type: 'query', payload: location.query}) + } + }) + } + }, + + effects : { + *query({ + payload + }, {call, put}) { + yield put({type: 'showLoading'}) + const {data} = yield call(query, parse(payload)) + if (data) { + yield put({ + type: 'querySuccess', + payload: { + list: data.data, + total: data.page.total, + current: data.page.current + } + }) + } + }, + * 'delete' ({ + payload + }, {call, put}) { + yield put({type: 'showLoading'}) + const {data} = yield call(remove, {id: payload})if (data && data.success) { + yield put({type: 'deleteSuccess', payload}) + } + }, + *create({ + payload + }, {call, put}) { + yield put({type: 'hideModal'}) + yield put({type: 'showLoading'}) + const {data} = yield call(create, payload) + if (data && data.success) { + yield put({type: 'createSuccess', payload}) + } + }, + *update({ + payload + }, {select, call, put}) { + yield put({type: 'hideModal'}) + yield put({type: 'showLoading'}) + const id = yield select(({users}) => users.currentItem.id) + const newUser = { + ...payload, + id + } + const {data} = yield call(update, newUser) + if (data && data.success) { + yield put({type: 'updateSuccess', payload: newUser}) + } + } + }, + + reducers : { + showLoading(state) { + return { + ...state, + loading: true + } + }, + createSuccess(state, action) { + const newUser = action.payload + return { + ...state, + list: [ + newUser, ...state.list + ], + loading: false + } + }, + deleteSuccess(state, action) { + const id = action.payload + const newList = state.list.filter(user => user.id !== id) + return { + ...state, + list: newList, + loading: false + } + }, + updateSuccess(state, action) { + const updateUser = action.payload + const newList = state.list.map(user => { + if (user.id === updateUser.id) { + return { + ...user, + ...updateUser + } + } + return user + }) + return { + ...state, + list: newList, + loading: false + } + }, + querySuccess(state, action) { + return { + ...state, + ...action.payload, + loading: false + } + }, + showModal(state, action) { + return { + ...state, + ...action.payload, + modalVisible: true + } + }, + hideModal(state) { + return { + ...state, + modalVisible: false + } + } + } +}