mirror of
https://github.com/zuiidea/antd-admin
synced 2026-10-21 06:53:47 +00:00
user
This commit is contained in:
@@ -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) => <a href="#">{text}</a>,
|
||||
}, {
|
||||
title: '年龄',
|
||||
dataIndex: 'age',
|
||||
key: 'age',
|
||||
}, {
|
||||
title: '住址',
|
||||
dataIndex: 'address',
|
||||
key: 'address',
|
||||
}, {
|
||||
title: '操作',
|
||||
key: 'operation',
|
||||
render: (text, record) => (
|
||||
<p>
|
||||
<a onClick={() => onEditItem(record)}>编辑</a>
|
||||
|
||||
<Popconfirm title="确定要删除吗?" onConfirm={() => onDeleteItem(record.id)}>
|
||||
<a>删除</a>
|
||||
</Popconfirm>
|
||||
</p>
|
||||
),
|
||||
}];
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Table
|
||||
columns={columns}
|
||||
dataSource={dataSource}
|
||||
loading={loading}
|
||||
rowKey={record => record.id}
|
||||
pagination={false}
|
||||
/>
|
||||
<Pagination
|
||||
className="ant-table-pagination"
|
||||
total={total}
|
||||
current={current}
|
||||
pageSize={10}
|
||||
onChange={onPageChange}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
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;
|
||||
@@ -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 (
|
||||
<Modal {...modalOpts}>
|
||||
<Form horizontal>
|
||||
<FormItem
|
||||
label="姓名:"
|
||||
hasFeedback
|
||||
{...formItemLayout}
|
||||
>
|
||||
{getFieldDecorator('name', {
|
||||
initialValue: item.name,
|
||||
rules: [
|
||||
{ required: true, message: '名称未填写' },
|
||||
],
|
||||
})(
|
||||
<Input type="text" />
|
||||
)}
|
||||
</FormItem>
|
||||
<FormItem
|
||||
label="年龄:"
|
||||
hasFeedback
|
||||
{...formItemLayout}
|
||||
>
|
||||
{getFieldDecorator('age', {
|
||||
initialValue: item.age,
|
||||
rules: [
|
||||
{ required: true, message: '年龄未填写' },
|
||||
{ validator: checkNumber },
|
||||
],
|
||||
})(
|
||||
<Input type="text" />
|
||||
)}
|
||||
</FormItem>
|
||||
<FormItem
|
||||
label="住址:"
|
||||
hasFeedback
|
||||
{...formItemLayout}
|
||||
>
|
||||
{getFieldDecorator('address', {
|
||||
initialValue: item.address,
|
||||
rules: [
|
||||
{ required: true, message: '不能为空' },
|
||||
],
|
||||
})(
|
||||
<Input type="address" />
|
||||
)}
|
||||
</FormItem>
|
||||
</Form>
|
||||
</Modal>
|
||||
)
|
||||
}
|
||||
|
||||
UserModal.propTypes = {
|
||||
visible: PropTypes.any,
|
||||
form: PropTypes.object,
|
||||
item: PropTypes.object,
|
||||
onOk: PropTypes.func,
|
||||
onCancel: PropTypes.func,
|
||||
}
|
||||
|
||||
export default Form.create()(UserModal)
|
||||
@@ -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 (
|
||||
<div className={styles.normal}>
|
||||
<div className={styles.search}>
|
||||
<Form inline onSubmit={handleSubmit}>
|
||||
<Form.Item>
|
||||
{getFieldDecorator('field', {
|
||||
initialValue: field || 'name'
|
||||
})(
|
||||
<Select>
|
||||
<Select.Option value="name">名字</Select.Option>
|
||||
<Select.Option value="address">地址</Select.Option>
|
||||
</Select>
|
||||
)}
|
||||
</Form.Item>
|
||||
<Form.Item hasFeedback>
|
||||
{getFieldDecorator('keyword', {
|
||||
initialValue: keyword || ''
|
||||
})(<Input type="text"/>)}
|
||||
</Form.Item>
|
||||
<Button style={{
|
||||
marginRight: '10px'
|
||||
}} type="primary" htmlType="submit">搜索</Button>
|
||||
</Form>
|
||||
</div>
|
||||
<div className={styles.create}>
|
||||
<Button type="ghost" onClick={onAdd}>添加</Button>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
UserSearch.propTypes = {
|
||||
form: PropTypes.object.isRequired,
|
||||
onSearch: PropTypes.func,
|
||||
onAdd: PropTypes.func,
|
||||
field: PropTypes.string,
|
||||
keyword: PropTypes.string
|
||||
}
|
||||
|
||||
export default Form.create()(UserSearch)
|
||||
@@ -0,0 +1,8 @@
|
||||
.normal {
|
||||
display: flex;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.search {
|
||||
flex: 1;
|
||||
}
|
||||
@@ -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 };
|
||||
},
|
||||
},
|
||||
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user