Commit bad46fae authored by superman's avatar superman

update

parent 11ac5abf
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -2,6 +2,6 @@
// - https://github.com/dora-js/dora-plugin-proxy#规则定义
module.exports = {
// '/api/*': 'http://react.yanky.cn/',
'/api/*': 'http://192.168.1.126:8080/'
'/api/*': 'http://react.yanky.cn/',
// '/api/*': 'http://192.168.1.126:8080/'
};
.layout {
font-size: 14px;
display: flex;
flex-direction: column;
height: 100%;
......@@ -11,6 +10,18 @@
width: 100%;
& > div {
height: 100%;
&:global(.ant-spin.ant-spin-spinning) {
width: 100%;
position: relative;
:global {
.ant-spin-dot {
position: absolute;
top: 50%;
left: 50%;
margin: -25px 0 0 -25px;
}
}
}
& > :global(.ant-spin-container) {
height: 100%;
& > :global(.ant-form-horizontal) {
......
......@@ -3,7 +3,8 @@ import React, {Component, PropTypes} from 'react';
import {
Row,
Col,
Breadcrumb
Breadcrumb,
Icon
} from 'antd';
......@@ -24,6 +25,7 @@ export default class MainHeader extends Component {
<Row className={styles.header} type="flex" justify="space-around" align="middle">
<Col span="16" style={{paddingLeft: 20}}>
<h1>{title}</h1>
<Icon type="heart"/>
<Breadcrumb>
{ breadcrumb.map((b, i)=><Breadcrumb.Item key={i}>{b}</Breadcrumb.Item>) }
</Breadcrumb>
......
......@@ -17,14 +17,21 @@
font-size: 18px;
margin-top: 5px;
}
:global {
.ant-breadcrumb {
color: #ccc;
font-weight: 300;
display: inline-block;
& > span:last-child {
color: #aaa;
}
}
.anticon.anticon-heart {
color: #93cc93;
margin-right: 5px;
font-size: 10px;
}
}
}
......@@ -32,4 +39,5 @@
padding: 10px 20px;
.borderBottom;
}
}
......@@ -27,12 +27,15 @@ import {formItemLayout, footerFormSubmitLayout} from '../../utils';
@connect(state=>({
loading: state.announcement.loading,
announcement: state.announcement.item,
item: state.announcement.item,
}))
@Form.create()
export default class EditItem extends Component {
constructor() {
super(...arguments);
this.state = {
isEdit: false
}
}
......@@ -40,6 +43,10 @@ export default class EditItem extends Component {
this.fetchItem(this.props.params.id);
};
componentWillReceiveProps(nextProps){
}
fetchItem(id) {
this.props.dispatch({
type: 'FETCH_ANNOUNCEMENT_ITEM',
......@@ -50,7 +57,7 @@ export default class EditItem extends Component {
handleSubmit(e) {
e.preventDefault();
const data = this.props.form.getFieldsValue();
data.id = this.props.announcement.id;
data.id = this.props.item.id;
console.log(data);
this.props.dispatch({
type: 'UPDATE_ANNOUNCEMENT_ITEM',
......@@ -59,48 +66,80 @@ export default class EditItem extends Component {
}
render() {
const {announcement, loading, form:{getFieldProps}, location:{query}} = this.props;
const {item, loading, form:{getFieldProps}, location:{query}} = this.props;
const {isEdit} = this.state;
const operation = (
<div style={{textAlign:'right'}}>
<Button.Group>
<Button type="ghost" onClick={e=>{e.preventDefault(); this.props.history.goBack();}}>
<Button type="ghost" onClick={e=>{e.preventDefault(); this.setState({isEdit: !this.state.isEdit})}}>
<Icon type="edit"/>
</Button>
<Button type="ghost" onClick={e=>{
e.preventDefault();
isEdit ? this.setState({isEdit: !this.state.isEdit}) : this.props.history.goBack();
}}>
<Icon type="rollback"/>
</Button>
</Button.Group>
</div>
);
const breadcrumb = ['产品管理', '产品详情'];
const titlePart = isEdit ? '修改公告' : '公告详情';
const title = (item && item.title ? item.title + ' - ' : '') + titlePart;
breadcrumb.push(titlePart);
const header = (
<MainHeader breadcrumb={['产品管理', '产品详情', '修改公告']}
title={(query && query.title ? query.title + ' - ' : '') + '修改公告'}
operation={operation}
/>
<MainHeader breadcrumb={breadcrumb} title={title} operation={operation}/>
);
return (
<Layout header={header}>
<Spin spinning={loading}>
{
announcement &&
item &&
<Form className="main-form" horizontal onSubmit={this.handleSubmit.bind(this)}>
<Form.Item label="标题" {...formItemLayout}>
{
isEdit ?
<Input placeholder="公告标题"
{...getFieldProps('title', {
initialValue: announcement.title
initialValue: item.title
})} />
:
item.title
}
</Form.Item>
<Form.Item label="内容" {...formItemLayout}>
{
isEdit ?
<Input placeholder="公告内容" autosize={{ minRows: 5 }} type="textarea"
{...getFieldProps('announcement', {
initialValue: announcement.announcement
initialValue: item.announcement
})} />
: item.announcement
}
</Form.Item>
<Form.Item {...footerFormSubmitLayout} style={{marginTop:30}}>
<Button type="primary" htmlType="submit" loading={loading}><Icon
type="save"/>修改</Button>
<Button onClick={e=>{e.preventDefault(); this.props.history.goBack();}}
style={{marginLeft:'1em'}}>
{
isEdit ?
<Button type="primary" htmlType="submit" loading={loading}>
<Icon type="save"/>修改
</Button>
:
<Button type="primary"
onClick={e=>{e.preventDefault(); this.setState({isEdit: !this.state.isEdit})}}>
<Icon type="edit"/>编辑
</Button>
}
<Button style={{marginLeft:'1em'}} onClick={e=>{
e.preventDefault();
isEdit ? this.setState({isEdit: !this.state.isEdit}) : this.props.history.goBack();
}}>
<Icon type="rollback"/>返回
</Button>
</Form.Item>
......
......@@ -33,7 +33,7 @@ export default class List extends Component {
};
handleRowClick({id}) {
this.props.history.push('/announcement/' + id + '/edit');
this.props.history.push('/announcement/' + id );
}
handleFilterVisible() {
......
......@@ -23,7 +23,11 @@ export default class App extends Component {
render() {
const styles = require('./App.less');
const mainMenu = [
const menu = [
{
title: '业务管理',
icon: 'mail',
items: [
{
title: '产品管理',
items: [
......@@ -73,7 +77,42 @@ export default class App extends Component {
}
]
}
];
]
}, {
title: '基础功能',
icon: 'folder',
items: [
{
title: '文件管理',
items: [
{
to: '/upload',
cn: '图片上传',
en: 'Upload Images'
}
]
}
]
}, {
title: '管理员',
icon: 'folder',
items: [
{
title: '用户管理',
items: [
{
to: '/admin/users',
cn: '用户列表',
en: 'Users'
}, {
to: '/admin/users/create',
cn: '创建用户',
en: 'Create user'
}
]
}
]
}];
const {user} = this.props;
......@@ -86,37 +125,22 @@ export default class App extends Component {
</header>
<section>
<Menu mode="inline" defaultOpenKeys={['sub1']}>
<SubMenu key="sub1" title={<span><Icon type="mail" /><span>业务管理</span></span>}>
{
user && user.token &&
mainMenu.map((menu, mi)=>
<MenuItemGroup title={menu.title} key={mi}>
{
menu.items.map((item, ii)=>
<Menu.Item key={[mi,ii].join('-')}>
{user && user.token &&
menu.map((submenu, si)=>
<SubMenu key={'submenu'+si} title={
<span><Icon type={submenu.icon} /><span>{submenu.title}</span></span>
}>
{submenu.items.map((menus, mi)=>
<MenuItemGroup key={'menu-item-group-'+si+'-'+ mi} title={menus.title}>
{menus.items.map((item, ii)=>
<Menu.Item key={[si, mi,ii].join('-')}>
<MenuItemContent {...item}/>
</Menu.Item>
)
}
</MenuItemGroup>
)
}
</SubMenu>
<SubMenu key="sub2" title={<span><Icon type="folder" /><span>基本功能</span></span>}>
<Menu.Item>
<MenuItemContent to="/upload" cn="图片上传" en="Upload Images"/>
</Menu.Item>
</SubMenu>
<SubMenu key="sub3" title={<span><Icon type="folder" /><span>管理员</span></span>}>
<MenuItemGroup title='用户管理' key='users'>
<Menu.Item>
<MenuItemContent to="/admin/users" cn="用户列表" en="Users"/>
</Menu.Item>
<Menu.Item>
<MenuItemContent to="/admin/users/create" cn="创建用户" en="Create users"/>
</Menu.Item>
)}
</MenuItemGroup>
)}
</SubMenu>
)}
</Menu>
</section>
<footer>
......@@ -173,6 +197,37 @@ class MenuItemContent extends Component {
//<div className={styles.normal}></div>
// <SubMenu key="sub1" title={<span><Icon type="mail" /><span>业务管理</span></span>}>
// {
// user && user.token &&
// mainMenu.map((menu, mi)=>
// <MenuItemGroup title={menu.title} key={mi}>
// {
// menu.items.map((item, ii)=>
// <Menu.Item key={[mi,ii].join('-')}>
// <MenuItemContent {...item}/>
// </Menu.Item>
// )
// }
// </MenuItemGroup>
// )
// }
// </SubMenu>
// <SubMenu key="sub2" title={<span><Icon type="folder" /><span>基本功能</span></span>}>
// <Menu.Item>
// <MenuItemContent to="/upload" cn="图片上传" en="Upload Images"/>
// </Menu.Item>
// </SubMenu>
// <SubMenu key="sub3" title={<span><Icon type="folder" /><span>管理员</span></span>}>
// <MenuItemGroup title='用户管理' key='users'>
// <Menu.Item>
// <MenuItemContent to="/admin/users" cn="用户列表" en="Users"/>
// </Menu.Item>
// <Menu.Item>
// <MenuItemContent to="/admin/users/create" cn="创建用户" en="Create users"/>
// </Menu.Item>
// </MenuItemGroup>
// </SubMenu>
......
......@@ -48,11 +48,14 @@ export default class EditItem extends Component {
constructor() {
super(...arguments);
this.state = {
isEdit: false
}
}
componentWillMount() {
if (!this.props.cates.length) {
componentDidMount() {
if (!(this.props.cates && this.props.cates.length)) {
this.fetchCates();
}
this.fetchItem(this.props.params.id);
......@@ -78,43 +81,53 @@ export default class EditItem extends Component {
const styles = require('./Product.less');
const tabs = [{
tab: '基本信息',
children: BaseInfoForm
}, {
tab: '收益佣金',
children: ShouyiYongjingForm
}, {
tab: '汇款账号',
children: HuikuanInfoForm
}, {
tab: '基本要素',
children: ElementForm
}, {
tab: '时间状态',
children: DateTimeStatusForm
}, {
tab: '相关附件',
children: DocumentsForm
}, {
tab: '服务经理',
children: ContactForm
}].map((tabPane, index)=> {
const tabs = [
{ tab: '基本信息', children: BaseInfoForm },
{ tab: '收益佣金', children: ShouyiYongjingForm },
{ tab: '汇款账号', children: HuikuanInfoForm },
{ tab: '基本要素', children: ElementForm },
{ tab: '时间状态', children: DateTimeStatusForm },
{ tab: '相关附件', children: DocumentsForm },
{ tab: '服务经理', children: ContactForm }
].map((tabPane, index)=> {
tabPane.key = 'tabs-pane-' + (index + 1);
return tabPane;
});
const {isEdit} = this.state;
const operation = (
<div style={{textAlign:'right'}}>
<Button.Group>
{
product &&
<Button type="ghost"
onClick={e=>{e.preventDefault(); this.setState({isEdit: !this.state.isEdit})}}>
<Icon type="edit"/>
</Button>
}
<Button type="ghost" onClick={e=>{
e.preventDefault();
isEdit ?
this.setState({isEdit: !this.state.isEdit}) :
this.props.history.goBack();
}}>
<Icon type="rollback"/>
</Button>
</Button.Group>
</div>
);
const header = (<MainHeader breadcrumb={['产品管理', '产品详情']}
title={(product && product.itemShortTitle ? product.itemShortTitle + ' - ' : '') + '产品详情'}/>);
const title = (product && product.itemShortTitle ? product.itemShortTitle + ' - ' : '') + '产品详情';
const header = (<MainHeader breadcrumb={['产品管理', '产品详情']} title={title} operation={operation}/>);
return (
<Layout header={header}>
<Tabs className={styles.tabs} tabPosition="left">
{ tabs.map(tp=>
<Tabs.TabPane tab={tp.tab} key={tp.key}>
{product && <tp.children {...this.props} /> }
{product && <tp.children {...this.props} isEdit={isEdit} /> }
</Tabs.TabPane>
)}
</Tabs>
......
......@@ -12,7 +12,8 @@ import {
footerFormSubmitLayout,
handleUpload,
filterFormItemLayout,
PRODUCT_STATUS
PRODUCT_STATUS,
filterFormItemStyle
} from '../../utils';
import {Link} from 'react-router';
......@@ -197,10 +198,7 @@ export default class List extends Component {
</div>
);
const searchStyle = {
size: 'default',
style: {width: 100}
}
const header = (
<MainHeader breadcrumb={['产品管理', '产品列表']}
......@@ -211,21 +209,21 @@ export default class List extends Component {
this.state.filterVisible &&
<Form className="filterForm" inline onSubmit={this.handleFilterSubmit.bind(this)}>
<Form.Item label="ID">
<Input placeholder="请输入搜索ID" {...searchStyle} {...getFieldProps('id')}/>
<Input placeholder="请输入搜索ID" {...filterFormItemStyle} {...getFieldProps('id')}/>
</Form.Item>
<Form.Item label="类目">
{
cates &&
<Cascader options={cates} placeholder="请选产品类目" {...searchStyle}
<Cascader options={cates} placeholder="请选产品类目" {...filterFormItemStyle}
{...getFieldProps('categoryId')}
/>
}
</Form.Item>
<Form.Item label="标题">
<Input placeholder="请输入搜索标题" {...searchStyle} {...getFieldProps('title')}/>
<Input placeholder="请输入搜索标题" {...filterFormItemStyle} {...getFieldProps('title')}/>
</Form.Item>
<Form.Item label="状态">
<Select placeholder="请选择状态" {...searchStyle} {...getFieldProps('status')}>
<Select placeholder="请选择状态" {...filterFormItemStyle} {...getFieldProps('status')}>
<Select.Option key="status-option-default"
value={null}>请选择</Select.Option>
{
......
This diff is collapsed.
import React, {Component, PropTypes} from 'react';
import {connect} from 'react-redux';
import {
Row,
Col,
Form,
Input,
Button,
Checkbox,
Select,
message,
Tabs,
Cascader,
Radio,
Upload,
Icon,
Modal,
DatePicker,
Table,
Spin
} from 'antd';
import Layout from '../../components/Layout/Layout';
import MainHeader from '../../components/MainHeader/MainHeader';
import {
formItemLayout,
smallFormItemLayout,
footerFormSubmitLayout,
userStatusToString,
formatDateTime
} from '../../utils';
@connect(state=>({
loading: state.user.loading,
item: state.user.item,
}))
@Form.create()
export default class EditItem extends Component {
constructor() {
super(...arguments);
this.state = {
isEdit: false
}
}
componentDidMount() {
this.fetchItem(this.props.params.id);
};
fetchItem(id) {
this.props.dispatch({
type: 'FETCH_USER_ITEM',
id
});
};
handleSubmit(status, e) {
e.preventDefault();
let data = {};
if (status == 1 || status == 0) {
data.status = status;
} else {
data = this.props.form.getFieldsValue();
}
data.id = this.props.params.id;
console.log(data);
this.props.dispatch({
type: 'UPDATE_USER_ITEM',
data
});
}
render() {
const {item, loading, form:{getFieldProps}, location:{query}} = this.props;
const {isEdit} = this.state;
const operation = (
<div style={{textAlign:'right'}}>
<Button.Group>
<Button type="ghost" onClick={e=>{e.preventDefault(); this.setState({isEdit: !this.state.isEdit})}}>
<Icon type="edit"/>
</Button>
<Button type="ghost" onClick={e=>{e.preventDefault(); this.props.history.goBack();}}>
<Icon type="rollback"/>
</Button>
</Button.Group>
</div>
);
const header = (
<MainHeader breadcrumb={['用户管理', '用户详情']}
title={(query && query.title ? query.title + ' - ' : '') + '用户详情'}
operation={operation}
/>
);
return (
<Layout header={header}>
<Spin spinning={loading}>
{
item &&
<Form className="main-form" horizontal>
<Form.Item label="用户名" {...smallFormItemLayout}>
{ item.username }
</Form.Item>
<Form.Item label="状态" {...smallFormItemLayout}>
{userStatusToString(item.status)}
</Form.Item>
<Form.Item label="昵称" {...smallFormItemLayout}>
{
isEdit ?
<Input {...getFieldProps('nick', {initialValue: item.nick})} />
:
item.nick
}
</Form.Item>
<Form.Item label="E-mail" {...smallFormItemLayout}>
{
isEdit ?
<Input {...getFieldProps('email', {initialValue: item.email})} />
:
item.email
}
</Form.Item>
<Form.Item label="手机号" {...smallFormItemLayout}>
{
isEdit ?
<Input {...getFieldProps('mobile', {initialValue: item.mobile})} />
:
item.mobile
}
</Form.Item>
<Form.Item label="注册时间" {...smallFormItemLayout}>
{item.dateCreated && formatDateTime(item.dateCreated)}
</Form.Item>
<Form.Item {...footerFormSubmitLayout} style={{marginTop:30}}>
{
isEdit ?
<Button type="primary" onClick={this.handleSubmit.bind(this, -1)}
loading={loading}>
<Icon type="save"/>修改
</Button>
:
item.status ?
<Button type="primary" onClick={this.handleSubmit.bind(this, 0)}
loading={loading}>
<Icon type="save"/>禁用
</Button>
:
<Button type="primary" onClick={this.handleSubmit.bind(this, 1)}
loading={loading}>
<Icon type="save"/>激活
</Button>
}
<Button onClick={e=>{e.preventDefault(); this.props.history.goBack();}}
style={{marginLeft:'1em'}}>
<Icon type="rollback"/>返回
</Button>
</Form.Item>
</Form>
}
</Spin>
</Layout>
);
}
}
......@@ -2,78 +2,57 @@ import React, {Component, PropTypes} from 'react';
import {connect} from 'react-redux';
import {Table, Icon, Row, Col, Button, Form, Input, Cascader, Select} from 'antd';
import {Link} from 'react-router';
import {serialize, formatDateTime, tradeStatusToString} from '../../utils';
import {serialize, formatDateTime, userStatusToString, filterFormItemStyle} from '../../utils';
import Layout from '../../components/Layout/Layout';
import MainHeader from '../../components/MainHeader/MainHeader';
const columns = [
{
title: '用户ID',
title: 'ID',
dataIndex: 'id',
key: 'id',
width: 70,
// fixed:'left'
}, {
title: '用户名',
dataIndex: 'shortTitle',
key: 'shortTitle',
render: (shortTitle, record)=>(<span title={shortTitle}>{(shortTitle + '').substring(0, 15)}</span>)
dataIndex: 'username',
key: 'username',
width:100,
}, {
title: '预约时间',
dataIndex: 'reservationTime',
key: 'reservationTime',
title: '注册时间',
dataIndex: 'dateCreated',
key: 'dateCreated',
width: 150,
className: 'tac',
render: (reservationTime, record)=>(
render: (dateCreated, record)=>(
<span>
{reservationTime && formatDateTime(reservationTime)}
{dateCreated && formatDateTime(dateCreated)}
</span>
)
}, {
title: '投资人',
title: '角色',
dataIndex: 'buyerName',
key: 'buyerName',
width: 80,
width: 200,
className: 'tac',
}, {
title: '预约额度',
dataIndex: 'reservationAmount',
key: 'reservationAmount',
width: 100,
className: 'tac',
title: 'E-mail',
dataIndex: 'email',
key: 'email',
width: 200,
}, {
title: '实际打款',
dataIndex: 'remittanceAmount',
key: 'remittanceAmount',
width: 100,
title: '手机号',
dataIndex: 'mobile',
key: 'mobile',
width: 80,
className: 'tac',
}, {
title: '状态',
dataIndex: 'status',
key: 'status',
width: 160,
className: 'tac',
render: (status, record)=>(<span data-status={status}>{tradeStatusToString(status)}</span>)
}, {
title: '操作',
key: 'operation',
width: 140,
// fixed:'right',
width: 60,
className: 'tac',
render: (text, record)=>(
<span>
<Link to={'/trades/contract/'+ record.id} onClick={e=>e.stopPropagation()}>合同</Link>
{
(record.status == 11 || record.status == 21) &&
<span>
<span className="ant-divider"></span>
<Link to={'/trades/commission/'+ record.id} onClick={e=>e.stopPropagation()}>佣金</Link>
</span>
}
</span>
)
render: (status, record)=>(<span data-status={status}>{userStatusToString(status)}</span>)
}
];
......@@ -186,21 +165,13 @@ export default class List extends Component {
this.state.filterVisible &&
<Form className="filterForm" inline onSubmit={this.handleFilterSubmit.bind(this)}>
<Form.Item label="ID">
<Input placeholder="请输入搜索ID" {...searchStyle} {...getFieldProps('id')}/>
</Form.Item>
<Form.Item label="类目">
{
cates &&
<Cascader options={cates} placeholder="请选产品类目" {...searchStyle}
{...getFieldProps('categoryId')}
/>
}
<Input placeholder="请输入搜索ID" {...filterFormItemStyle} {...getFieldProps('id')}/>
</Form.Item>
<Form.Item label="标题">
<Input placeholder="请输入搜索标题" {...searchStyle} {...getFieldProps('title')}/>
<Form.Item label="用户名">
<Input placeholder="请输入搜索用户名" {...filterFormItemStyle} {...getFieldProps('title')}/>
</Form.Item>
<Form.Item label="状态">
<Select placeholder="请选择状态" {...searchStyle} {...getFieldProps('status')}>
<Select placeholder="请选择状态" {...filterFormItemStyle} {...getFieldProps('status')}>
<Select.Option key="status-option-default"
value={null}>请选择</Select.Option>
......@@ -220,6 +191,8 @@ export default class List extends Component {
</MainHeader>
);
return (
<Layout header={header}>
<Table className="list-table" columns={columns}
......
......@@ -23,4 +23,5 @@ export CustomMessageItem from './CustomMessage/Item';
export BaseUpload from './BaseFunction/BaseUpload';
export UsersAddItem from './Users/Additem';
export UsersList from './Users/List';
export UsersItem from './Users/EditItem';
......@@ -84,6 +84,15 @@
margin: 5px 0;
}
.ant-menu-vertical > .ant-menu-item,
.ant-menu-inline > .ant-menu-item,
.ant-menu-item-group-list > .ant-menu-item,
.ant-menu-vertical > .ant-menu-submenu > .ant-menu-submenu-title,
.ant-menu-inline > .ant-menu-submenu > .ant-menu-submenu-title,
.ant-menu-item-group-list > .ant-menu-submenu > .ant-menu-submenu-title {
line-height: 36px;
height: 36px;
}
.list-table {
display: flex;
flex-direction: column;
......@@ -115,13 +124,12 @@
background-color: #fcfcfc;
}
&.ant-table-row-hover,
&:hover{
&:hover {
background-color: #eaf8fe;
}
}
}
& > div {
&:first-child {
flex: 1;
......@@ -136,16 +144,49 @@
.tac {
text-align: center !important;
}
}
body {
.ant-modal-mask{
animation-duration: 300ms !important;
}
.img-priview-dialog {
animation-duration: 300ms !important;
height: 100vh;
width: 100vw;
display: flex;
top: 0;
align-items: center;
justify-content: center;
.ant-modal-content {
background-color: transparent;
padding-bottom: 0;
img {
margin: auto;
display: block;
max-width: 100vw !important;
max-height: 100vh !important;
}
.ant-modal-close {
background: rgba(255, 255, 255, .25);
border-radius: 50%;
width: 20px;
height: 20px;
padding: 3px;
top: -10px;
right: -10px;
}
.ant-modal-body {
display: flex;
align-items: center;
justify-content: center;
padding: 0;
}
}
}
}
}
......@@ -33,7 +33,7 @@ const announcement = handleActions({
return {...state, loading: true}
},
['UPDATE_ANNOUNCEMENT_ITEM_SUCCESS'](state, action){
return {...state, loading: false, item: action.item}
return {...state, loading: false, item: {...state.item, ...action.item}}
},
['UPDATE_ANNOUNCEMENT_ITEM_FAILED'](state, action){
return {...state, err: action.err, loading: false}
......
......@@ -41,7 +41,28 @@ const user = handleActions({
},
['FETCH_USER_LIST_FAILED'](state, action){
return {...state, loading: false, err: action.err};
}
},
['FETCH_USER_ITEM'](state){
return {...state, loading:true};
},
['FETCH_USER_ITEM_SUCCESS'](state, action){
return {...state, loading: false, item: action.item};
},
['FETCH_USER_ITEM_FAILED'](state, action){
return {...state, loading: false, err: action.err};
},
['UPDATE_USER_ITEM'](state){
return {...state, loading:true};
},
['UPDATE_USER_ITEM_SUCCESS'](state, action){
return {...state, loading: false, item: {...state.item, ...action.item}};
},
['UPDATE_USER_ITEM_FAILED'](state, action){
return {...state, loading: false, err: action.err};
},
}, {
..._user,
loading: false,
......
......@@ -25,7 +25,8 @@ import {
CustomMessageItem,
BaseUpload,
UsersAddItem,
UsersList
UsersList,
UsersItem
} from '../containers/index';
export default (store)=> {
......@@ -55,7 +56,7 @@ export default (store)=> {
<Route path="announcement">
<IndexRoute component={AnnouncementList}/>
<Route path="create" component={AnnouncementAddItem}/>
<Route path=":id/edit" component={AnnouncementEditItem}/>
<Route path=":id" component={AnnouncementEditItem}/>
</Route>
<Route path="remittance">
<Route path="audits">
......@@ -79,6 +80,7 @@ export default (store)=> {
<Route path="users">
<IndexRoute component={UsersList} />
<Route path="create" component={UsersAddItem} />
<Route path=":id" component={UsersItem} />
</Route>
</Route>
</Route>
......
......@@ -80,10 +80,10 @@ function* watchAdd() {
function* editItem(data) {
try{
const item = yield call(updateItem, data);
yield call(updateItem, data);
yield put({
type: 'UPDATE_ANNOUNCEMENT_ITEM_SUCCESS',
item
item: data
});
}catch(err){
console.log(err);
......
import {takeLatest} from 'redux-saga';
import {take, call, put, fork, cancel} from 'redux-saga/effects';
import {fetch, clear, save, create, fetchList} from '../services/user';
import {fetch, clear, save, create, fetchList, fetchItem, updateItem} from '../services/user';
import {message} from 'antd';
function* authorize(username, password, push) {
......@@ -26,32 +26,32 @@ function* loginFlow() {
}
function* addItem(data) {
try{
try {
yield call(create, data);
yield put({type: 'CREATE_USER_ITEM_SUCCESS'});
}catch(err){
} catch (err) {
console.log(err);
message.error(err);
yield put({type: 'CREATE_USER_ITEM_FAILED', err});
}
}
function* watchAddItem(){
while(true){
function* watchAddItem() {
while (true) {
const {data} = yield take('CREATE_USER_ITEM');
yield fork(addItem, data);
}
}
function* getList(query){
try{
const {items, total} = yield call(fetchList, query);
function* getList(query) {
try {
const {users, total} = yield call(fetchList, query);
yield put({
type:'FETCH_USER_LIST_SUCCESS',
items: items,
type: 'FETCH_USER_LIST_SUCCESS',
items: users,
total
});
}catch(err){
} catch (err) {
console.log(err);
message.error(err);
yield put({type: 'FETCH_USER_LIST_FAILED', err});
......@@ -59,15 +59,66 @@ function* getList(query){
}
function* watchList() {
while(true){
while (true) {
const {query} = yield take('FETCH_USER_LIST');
yield fork(getList, query);
}
}
export default function* () {
function* getItem(id) {
try {
const item = yield call(fetchItem, id);
yield put({
type: 'FETCH_USER_ITEM_SUCCESS',
item: item
});
} catch (err) {
console.log(err);
message.error(err);
yield put({
type: 'FETCH_USER_ITEM_FAILED',
err
});
}
}
function* watchItem() {
while (true) {
const {id} = yield take('FETCH_USER_ITEM');
yield fork(getItem, id);
}
}
function* modifyItem(data) {
try {
yield call(updateItem, data);
yield put({
type: 'UPDATE_USER_ITEM_SUCCESS',
item: data
});
} catch (err) {
console.log(err);
message.error(err);
yield put({
type: 'UPDATE_USER_ITEM_FAILED',
err
});
}
}
function* watchMidfiyItem(){
while(true){
const {data} = yield take('UPDATE_USER_ITEM');
yield fork(modifyItem, data);
}
}
export default function*() {
yield fork(loginFlow);
yield fork(watchAddItem);
yield fork(watchList);
yield fork(watchItem);
yield fork(watchMidfiyItem);
}
......@@ -10,15 +10,26 @@ export async function fetch(username, password) {
export async function create(data) {
return xFetch('/api/users', {
method:'POST',
method: 'POST',
body: serialize(data)
});
}
export async function fetchList(query){
export async function fetchList(query) {
return xFetch('/api/admin/users' + '?' + serialize(query));
}
export async function fetchItem(id) {
return xFetch('/api/admin/users/' + id);
}
export async function updateItem(data) {
return xFetch('/api/admin/users/' + data.id, {
method: 'PUT',
body: serialize(data)
})
}
export async function clear() {
sessionStorage.clear();
return Promise.resolve();
......
......@@ -20,11 +20,9 @@ function check404(res) {
}
function jsonParse(res) {
try {
return res.json().then(json => ({...res, json}));
}catch(err){
return Promise.reject(err);
}
return res.json().then(json => ({...res, json})).catch(err=> ({...res, json:{status:0, message: '数据加载错误!'}}));
}
function errorMessageParse(res) {
......
......@@ -59,7 +59,16 @@ export const productStatusToString = status => {
export const productEnableCreateTrade = status => {
return status > 1 && status < 17;
}
};
export const USER_STATUS = {
0: '未激活',
1: '正常'
};
export const userStatusToString = status => {
return USER_STATUS[status] || '未定义';
};
export const tradeStatusToString = status => {
......@@ -141,9 +150,14 @@ export const footerFormSubmitLayout = {
};
export const filterFormItemLayout = {
labelCol:{ span: 10 },
wrapperCol:{ span: 14 }
}
labelCol: {span: 10},
wrapperCol: {span: 14}
};
export const filterFormItemStyle = {
size: 'default',
style: {width: 100}
};
export function filterUploadSuccess(fileList) {
......@@ -171,17 +185,17 @@ export function transformUploadThumbUrl(fileList) {
type: file.type,
url: file.url,
thumbUrl: file.thumbUrl,
name:file.name,
size:file.size
name: file.name,
size: file.size
}
}
return file;
});
}
export function handleUpload(info, limit){
export function handleUpload(info, limit) {
let fileList = filterUploadSuccess(info.fileList);
if(limit){
if (limit) {
fileList = fileList.slice(-1 * limit);
}
return transformUploadThumbUrl(fileList);
......@@ -189,7 +203,9 @@ export function handleUpload(info, limit){
export function remittanceAuditStatusToString(status) {
switch (status){
switch (status) {
case 0:
return '已删除';
case 1:
return '待审核';
case 5:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment