Commit f6d0dab0 authored by superman's avatar superman

权限系统 用户登出 用户注册

parent 45b2a018
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -11,6 +11,7 @@
"es3ify-loader": "^0.2.0",
"form-data": "^1.0.0-rc4",
"history": "^2.0.1",
"images": "^3.0.0",
"isomorphic-fetch": "^2.2.1",
"js-cookie": "^2.1.1",
"rc-animate": "^2.3.0",
......
......@@ -3,5 +3,6 @@
module.exports = {
'/api/*': 'http://react.yanky.cn/',
// '/api/*': 'http://192.168.1.126:8080/'
// '/api/*': 'http://192.168.1.126:8080/',
// '/api/*': 'http://localhost:8080/'
};
import React, {Component, PropTypes} from 'react';
import {Button, Icon, Form} from 'antd';
import {footerFormSubmitLayout} from '../../utils';
export default class FooterOperation extends Component {
static propTypes = {
isEdit: PropTypes.bool,
command: PropTypes.string,
dispatch: PropTypes.func,
history: PropTypes.object,
layout: PropTypes.object,
beforeButtons: PropTypes.node,
afterButtons: PropTypes.node
};
render() {
const {isEdit, hasCancel=true, command, dispatch, history, loading, layout, beforeButtons, afterButtons} = this.props;
const UPDATE_COMMAND = 'UPDATE_' + command;
const CANCEL_UPDATE_COMMAND = 'CANCEL_' + UPDATE_COMMAND;
const handleEditBtnClick = e => {
e.preventDefault();
dispatch({
type: UPDATE_COMMAND
});
};
const handleRollbackBtnClick = e => {
e.preventDefault();
isEdit ? dispatch({type: CANCEL_UPDATE_COMMAND}) : history.goBack();
};
return (
<Form.Item {...footerFormSubmitLayout} {...layout} style={{marginTop:30}}>
{beforeButtons}
{
isEdit ?
<Button type="primary" htmlType="submit" loading={loading}>
<Icon type="save"/>保存
</Button>
:
<Button type="primary" onClick={handleEditBtnClick}>
<Icon type="edit"/>编辑
</Button>
}
{
hasCancel &&
<Button onClick={handleRollbackBtnClick} style={{marginLeft:'1em'}}>
<Icon type="rollback"/>{isEdit ? '取消' : '返回'}
</Button>
}
{afterButtons}
</Form.Item>
);
}
}
import React, {Component, PropTypes} from 'react';
import {Button, Icon, Popconfirm, Menu, Row, Col, Popover} from 'antd';
import {connect} from 'react-redux';
import {Link} from 'react-router';
@connect(state=>({
user: state.user
}))
export default class HeaderOperation extends Component {
static propTypes = {
dispatch: PropTypes.func,
history: PropTypes.object,
user: PropTypes.object,
buttons: PropTypes.array,
};
componentWillReceiveProps(nextProps) {
if (nextProps.removed) {
this.props.history.goBack();
}
}
render() {
const {history, user, buttons = []} = this.props;
const defaultButtons = {
edit: {
title: '编辑',
icon: 'edit',
onClick: ()=> {
console.error('没有实现的编辑操作');
}
},
remove: {
title: '删除',
icon: 'cross-circle-o',
confirm: '',
onConfirm: ()=> {
console.error('没有实现的删除操作');
}
},
cancel: {
title: '取消',
icon: 'rollback',
onClick: ()=> {
console.error('没有实现的取消操作');
}
},
rollback: {
title: '返回',
icon: 'rollback',
onClick: (e)=> {
e.preventDefault();
history.goBack();
}
},
add: {
title: '添加',
icon: 'plus',
onClick: ()=> {
console.error('没有实现的添加操作');
}
},
filter: {
title: '筛选',
icon: 'filter',
onClick: ()=> {
console.error('没有实现的筛选操作');
}
}
};
const operations = buttons.length ? (
<Button.Group>
{
buttons.map(button=> {
const props = {...defaultButtons[button.key], ...button};
if (props.link) {
const icon = props.icon;
const link = props.link;
delete props.icon;
delete props.link;
return (
<Button type="ghost" {...props} >
<Link to={link}>
<Icon type={icon}/>
</Link>
</Button>
);
}
const btn = (
<Button type="ghost" {...props} />
);
if (props.onConfirm) {
return (
<Popconfirm title={props.confirm || "确定要删除吗?"}
onConfirm={props.onConfirm}>
{btn}
</Popconfirm>
);
}
return btn;
})
}
</Button.Group>
) : null;
const handleExit = (e)=> {
e.preventDefault();
this.props.dispatch({
type: 'LOGIN_REQUEST',
replace: this.props.history.replace
});
this.props.dispatch({
type: 'LOGOUT'
});
};
const userOperations = user ? (
<ul>
<li><a href="javascript:void('退出');" onClick={handleExit}>退出</a></li>
<li><Link to="/my/modifyPassword">修改密码</Link></li>
</ul>
) : null;
return (
<div style={{textAlign: 'right'}}>
{operations}
{
userOperations &&
<Popover content={userOperations}>
<Button type="ghost" style={{marginLeft: '2em'}}>
<Icon type="user"/>{user.username}
</Button>
</Popover>
}
</div>
);
}
}
export function DetailOperations(command, id, isEdit, dispatch) {
const buttons = [];
if (id) {
!isEdit && buttons.push({
key: 'edit',
onClick: (e)=> {
e.preventDefault();
dispatch({type: 'UPDATE_' + command});
}
});
isEdit && buttons.push({
key: 'cancel',
onClick: (e)=> {
e.preventDefault();
dispatch({type: 'CANCEL_UPDATE_' + command});
}
});
}
(!isEdit || !id) && buttons.push({
key: 'rollback',
});
return buttons;
}
import React, {Component, PropTypes} from 'react';
import {
Row,
Col,
Form,
Input,
Button,
Checkbox,
Select,
message,
Tabs,
Cascader,
Radio,
Upload,
Icon,
Modal,
DatePicker,
Table
} from 'antd';
export default class NextPrve extends Component {
constructor(props, context) {
super(props, context);
}
render(){
function handleStep (s){
this.props.handleStep(s);
}
return (
<div style={{textAlign:'center', borderTop:'1px solid #eee', height:60, paddingTop:20 }}>
{
this.state.step > 1 &&
<Button loading={this.props.loading}
style={{margin:'0 1em'}}
onClick={handleStep.bind(this, -1)}><Icon type="save"/>上一步</Button>
}
{
this.state.step < tabs.length &&
<Button type="primary" loading={this.props.loading}
style={{margin:'0 1em'}}
onClick={handleStep.bind(this, 1)}><Icon type="save"/>下一步</Button>
}
{
this.state.step == tabs.length &&
<Button type="primary" loading={this.props.loading}
><Icon type="solution"/>发布</Button>
}
</div>
);
}
}
......@@ -30,6 +30,8 @@ import {
FILE_UPLOAD
} from '../../utils';
import FooterOperation from '../FooterOperation/FooterOperation';
@Form.create()
export default class BaseInfoForm extends Component {
......@@ -99,7 +101,7 @@ export default class BaseInfoForm extends Component {
};
render() {
const {user, cates, product, loading, form:{getFieldProps}, isEdit} = this.props;
const {user, cates, product, loading, form:{getFieldProps}, isEdit, isCreate} = this.props;
......@@ -234,38 +236,7 @@ export default class BaseInfoForm extends Component {
<img src={this.state.priviewImage} style={{maxWidth:'100%'}}/>
</Modal>
</Form.Item>
<Form.Item wrapperCol={{span: 16, offset: 6}} style={{marginTop:30}}>
{
isEdit ?
<Button type="primary" htmlType="submit" loading={loading}>
<Icon type="save"/>保存
</Button>
:
<Button type="primary" onClick={e=>{
e.preventDefault();
this.props.dispatch({
type:'UPDATE_PRODUCT'
});
}}>
<Icon type="edit"/>编辑
</Button>
}
{
!this.props.isCreate &&
<Button onClick={e=>{
e.preventDefault();
isEdit ?
this.props.dispatch({
type: 'CANCEL_UPDATE_PRODUCT'
}) :
this.props.history.goBack();
}}
style={{marginLeft:'1em'}}>
<Icon type="rollback"/>
{isEdit ? '取消' : '返回'}
</Button>
}
</Form.Item>
<FooterOperation {...this.props} layout={{wrapperCol:{span: 16, offset: 6}}} command="PRODUCT" hasCancel={!isCreate} />
</Col>
<Col span="12">
<Form.Item label="募集目标" help={ isEdit && "本期额度, 可以输入100万, 2亿等"}
......
......@@ -29,6 +29,8 @@ import {
footerFormSubmitLayout
} from '../../utils';
import FooterOperation from '../FooterOperation/FooterOperation';
@Form.create()
export default class ContactForm extends Component {
......@@ -112,7 +114,7 @@ export default class ContactForm extends Component {
}
render() {
const {form:{getFieldProps}, loading, isEdit} = this.props;
const {form:{getFieldProps}, loading, isEdit, isCreate} = this.props;
return (
<Spin spinning={loading}>
<Form horizontal onSubmit={this.handleSubmit.bind(this)}>
......@@ -176,44 +178,13 @@ export default class ContactForm extends Component {
}
<Form.Item {...footerFormSubmitLayout} style={{marginTop:30}}>
{
isEdit ?
<span>
<FooterOperation {...this.props} command="PRODUCT" hasCancel={!isCreate} beforeButtons={
isEdit &&
<Button size="large" onClick={this.handleAdd.bind(this)}
style={{marginRight:'1em'}}>
<Icon type="plus"/>添加
</Button>
<Button size="large" type="primary" htmlType="submit" loading={loading}>
<Icon type="save"/>保存
</Button>
</span>
:
<Button type="primary" onClick={e=>{
e.preventDefault();
this.props.dispatch({
type:'UPDATE_PRODUCT'
});
}}>
<Icon type="edit"/>编辑
</Button>
}
{
!this.props.isCreate &&
<Button onClick={e=>{
e.preventDefault();
isEdit ?
this.props.dispatch({
type: 'CANCEL_UPDATE_PRODUCT'
}) :
this.props.history.goBack();
}}
style={{marginLeft:'1em'}}>
<Icon type="rollback"/>
{isEdit ? '取消' : '返回'}
</Button>
}
</Form.Item>
} />
</Col>
</Row>
</Form>
......
......@@ -52,20 +52,20 @@ export default class DateTimeSatausForm extends Component {
if (formData.fundReservationStartTime) {
data.fundReservationStartTime = formatDateTime(formData.fundReservationStartTime);
}
if (formData.fundRaisedStartTime[0]) {
data.fundRaisedStartTime = formatDateTime(formData.fundRaisedStartTime[0]);
if (formData.fundRaisedStartTime) {
data.fundRaisedStartTime = formatDateTime(formData.fundRaisedStartTime);
}
if (formData.fundRaisedStartTime[1]) {
data.fundRaisedEndTime = formatDateTime(formData.fundRaisedStartTime[1])
if (formData.fundRaisedEndTime) {
data.fundRaisedEndTime = formatDateTime(formData.fundRaisedEndTime);
}
if (formData.remittanceEndTime) {
data.remittanceEndTime = formatDateTime(formData.remittanceEndTime);
}
if (formData.fundEstablishedTime[0]) {
data.fundEstablishedTime = formatDateTime(formData.fundEstablishedTime[0]);
if (formData.fundEstablishedTime) {
data.fundEstablishedTime = formatDateTime(formData.fundEstablishedTime);
}
if (formData.fundEstablishedTime[1]) {
data.fundExpireTime = formatDateTime(formData.fundEstablishedTime[1]);
if (formData.fundExpireTime[1]) {
data.fundExpireTime = formatDateTime(formData.fundExpireTime);
}
data.status = formData.status;
......@@ -94,11 +94,11 @@ export default class DateTimeSatausForm extends Component {
return (
<Spin spinning={loading}>
<Form horizontal onSubmit={this.handleSubmit.bind(this)}>
<Row style={{padding:'0 20px'}}>
<Row style={{padding: '0 20px'}}>
<Col span="24">
{
!isCreate &&
<Form.Item label="产品状态" {...formItemLayout} wrapperCol={{span:20}}>
<Form.Item label="产品状态" {...formItemLayout} wrapperCol={{span: 20}}>
{
isEdit ?
<Radio.Group {...getFieldProps('status', {initialValue: product.status + ''})}>
......@@ -131,14 +131,17 @@ export default class DateTimeSatausForm extends Component {
<Form.Item label="募集开始与结束时间" {...formItemLayout}>
{
isEdit ?
<DatePicker.RangePicker showTime format="yyyy-MM-dd HH:mm:ss"
<span>
<DatePicker showTime format="yyyy-MM-dd HH:mm:ss" placeholder="请选择募集开始时间"
{...getFieldProps('fundRaisedStartTime', {
initialValue: [
fundRaisedStartTime ? formatDateTime(fundRaisedStartTime) : '',
fundRaisedEndTime ? formatDateTime(fundRaisedEndTime) : ''
]
initialValue: fundRaisedStartTime ? formatDateTime(fundRaisedStartTime) : ''
})}
/> - <DatePicker showTime format="yyyy-MM-dd HH:mm:ss" placeholder="请选择募集结束时间"
{...getFieldProps('fundRaisedEndTime', {
initialValue: fundRaisedEndTime ? formatDateTime(fundRaisedEndTime) : ''
})}
/>
</span>
:
((fundRaisedStartTime ? formatDateTime(fundRaisedStartTime) : NULL)
+ ' 、' +
......@@ -163,31 +166,35 @@ export default class DateTimeSatausForm extends Component {
<Form.Item label="基金成立与到期时间" {...formItemLayout}>
{
isEdit ?
<DatePicker.RangePicker showTime format="yyyy-MM-dd HH:mm:ss"
<span>
<DatePicker showTime format="yyyy-MM-dd HH:mm:ss" placeholder="请选择基金成立时间"
{...getFieldProps('fundEstablishedTime', {
initialValue: [
fundEstablishedTime ? formatDateTime(fundEstablishedTime) : '',
fundExpireTime ? formatDateTime(fundExpireTime) : ''
]
initialValue: fundEstablishedTime ? formatDateTime(fundEstablishedTime) : ''
})}
/> - <DatePicker showTime format="yyyy-MM-dd HH:mm:ss" placeholder="请选择基金到期时间"
{...getFieldProps('fundExpireTime', {
initialValue: fundExpireTime ? formatDateTime(fundExpireTime) : ''
})}
/>
</span>
:
((fundEstablishedTime ? formatDateTime(fundEstablishedTime) : NULL)
+ ' 、' +
(fundExpireTime ? formatDateTime(fundExpireTime) : NULL))
}
</Form.Item>
<Form.Item {...footerFormSubmitLayout} style={{marginTop:30}}>
<Form.Item {...footerFormSubmitLayout} style={{marginTop: 30}}>
{
isEdit ?
<Button type="primary" htmlType="submit" loading={loading}>
<Icon type="save"/>保存
</Button>
:
<Button type="primary" onClick={e=>{
<Button type="primary" onClick={e=> {
e.preventDefault();
this.props.dispatch({
type:'UPDATE_PRODUCT'
type: 'UPDATE_PRODUCT'
});
}}>
<Icon type="edit"/>编辑
......@@ -195,7 +202,7 @@ export default class DateTimeSatausForm extends Component {
}
{
!this.props.isCreate &&
<Button onClick={e=>{
<Button onClick={e=> {
e.preventDefault();
isEdit ?
this.props.dispatch({
......@@ -203,7 +210,7 @@ export default class DateTimeSatausForm extends Component {
}) :
this.props.history.goBack();
}}
style={{marginLeft:'1em'}}>
style={{marginLeft: '1em'}}>
<Icon type="rollback"/>
{isEdit ? '取消' : '返回'}
</Button>
......
......@@ -77,7 +77,7 @@ export default class DocumentsForm extends Component {
}
render() {
const {user, loading, isEdit} = this.props;
const {user, loading, isEdit, isCreate} = this.props;
return (
<Spin spinning={loading}>
<Form horizontal onSubmit={this.handleSubmit.bind(this)} style={{maxWidth:'1000px', margin:'auto'}}>
......
......@@ -125,7 +125,7 @@ export default class ElementForm extends Component {
render() {
const {form:{getFieldProps}, loading, isEdit} = this.props;
const {form:{getFieldProps}, loading, isEdit, isCreate} = this.props;
return (
<Spin spinning={loading}>
<Form horizontal onSubmit={this.handleSubmit.bind(this)} style={{padding:'0 20px'}}>
......
......@@ -49,7 +49,7 @@ export default class HuikuanInfoForm extends Component {
render() {
const {form:{getFieldProps}, product:{fundRaisedAccount}, loading, isEdit} = this.props;
const {form:{getFieldProps}, product:{fundRaisedAccount}, loading, isEdit, isCreate} = this.props;
return (
......
......@@ -141,7 +141,7 @@ export default class ShouyiYongjingForm extends Component {
render() {
const {form:{getFieldProps}, product, loading, isEdit} = this.props;
const {form:{getFieldProps}, product, loading, isEdit, isCreate} = this.props;
return (
<Spin spinning={loading}>
......
export HuikuanInfoForm from './HuikuanInfoForm';
export BaseInfoForm from './BaseInfoForm';
export ShouyiYongjingForm from './ShouyiYongjingForm';
export ElementForm from './ElementForm';
export DateTimeStatusForm from './DateTimeStatusForm';
export DocumentsForm from './DocumentsForm';
export ContactForm from './ContactForm';
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, footerFormSubmitLayout} from '../../utils';
@connect(state=>({
loading: state.announcement.loading,
item: state.announcement.item
}))
@Form.create()
export default class AddItem extends Component {
constructor(props, content) {
super(props, content);
}
componentDidMount(){
const {item} = this.props;
if (item && item.id) {
this.props.dispatch({
type: 'INIT_ANNOUNCEMENT'
});
}
}
componentWillReceiveProps(nextProps) {
const {item} = nextProps;
if (item && item.id) {
this.props.history.replace('/announcement/' + item.id);
this.props.dispatch({
type: 'INIT_ANNOUNCEMENT'
});
}
}
handleSubmit(e) {
e.preventDefault();
const data = this.props.form.getFieldsValue();
data.itemId = this.props.location.query.itemId;
console.log(data);
this.props.dispatch({
type: 'CREATE_ANNOUNCEMENT_ITEM',
data
});
}
render = ()=> {
const {loading, form:{getFieldProps}, location:{query}} = this.props;
const operation = (
<div style={{textAlign:'right'}}>
<Button.Group>
<Button type="ghost" onClick={e=>{e.preventDefault(); this.props.history.goBack();}}>
<Icon type="rollback"/>
</Button>
</Button.Group>
</div>
);
const header = (
<MainHeader breadcrumb={['产品管理', '产品详情', '添加公告']}
title={(query.title ? query.title + ' - ' : '') + '添加公告'}
operation={operation}
/>
);
return (
<Layout header={header}>
<Spin spinning={loading}>
<Form className="main-form" horizontal onSubmit={this.handleSubmit.bind(this)}>
<Form.Item label="标题" {...formItemLayout}>
<Input placeholder="公告标题" {...getFieldProps('title')} />
</Form.Item>
<Form.Item label="内容" {...formItemLayout}>
<Input placeholder="公告内容" type="textarea"
autosize={{minRows:5, maxRows:20}} {...getFieldProps('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'}}>
<Icon type="rollback"/>返回
</Button>
</Form.Item>
</Form>
</Spin>
</Layout>
);
}
}
......@@ -22,6 +22,8 @@ import {
import Layout from '../../components/Layout/Layout';
import MainHeader from '../../components/MainHeader/MainHeader';
import HeaderOperation, {DetailOperations} from '../../components/HeaderOperation/HeaderOperation';
import FooterOperation from '../../components/FooterOperation/FooterOperation';
import {formItemLayout, footerFormSubmitLayout, innerHTML} from '../../utils';
......@@ -34,19 +36,25 @@ import {formItemLayout, footerFormSubmitLayout, innerHTML} from '../../utils';
export default class EditItem extends Component {
constructor() {
super(...arguments);
this.state = {
isEdit: false
}
}
componentDidMount() {
this.fetchItem(this.props.params.id);
const {params:{id}} = this.props;
if (id) {
this.fetchItem(id);
}
};
componentWillReceiveProps(nextProps) {
this.setState({isEdit: nextProps.isEdit});
const {params:{id}, history} = this.props;
const {item} = nextProps;
if (!id && item && item.id) {
history.replace('/announcement/' + item.id);
return;
}
};
fetchItem(id) {
this.props.dispatch({
......@@ -57,56 +65,46 @@ export default class EditItem extends Component {
handleSubmit(e) {
e.preventDefault();
const data = this.props.form.getFieldsValue();
data.id = this.props.item.id;
console.log(data);
this.props.dispatch({
type: 'UPDATE_ANNOUNCEMENT_ITEM',
const {form, dispatch, params:{id}, location:{query:{itemId}}} = this.props;
const data = form.getFieldsValue();
if (id) {
data.id = id;
} else {
data.itemId = itemId;
}
console.log(data, id, data.id ? 'CREATE_ANNOUNCEMENT_ITEM' : 'UPDATE_ANNOUNCEMENT_ITEM');
dispatch({
type: data.id ? 'UPDATE_ANNOUNCEMENT_ITEM' : 'CREATE_ANNOUNCEMENT_ITEM',
item: data
});
}
render() {
const {item, loading, form:{getFieldProps}, location:{query}} = this.props;
let {item, loading, form:{getFieldProps}, location:{query}, isEdit, params, dispatch} = this.props;
const {isEdit} = this.state;
const isCreate = !params.id;
const operation = (
<div style={{textAlign:'right'}}>
<Button.Group>
<Button type="ghost"
onClick={
e=>{
e.preventDefault();
this.props.dispatch({
type: isEdit ? 'CANCEL_UPDATE_ANNOUNCEMENT' : 'UPDATE_ANNOUNCEMENT'
});
if (!params.id) {
item = {
status: 1
};
isEdit = true;
}
}>
<Icon type="edit"/>
</Button>
<Button type="ghost" onClick={e=>{
e.preventDefault();
isEdit ?
this.props.dispatch({
type: 'CANCEL_UPDATE_ANNOUNCEMENT'
}) :
this.props.history.goBack();
}}>
<Icon type="rollback"/>
</Button>
</Button.Group>
</div>
);
const breadcrumb = ['产品管理', '产品详情'];
const titlePart = '公告详情';
const title = (item && item.title ? item.title + ' - ' : '') + titlePart + (isEdit ? ' - 编辑' :'');
breadcrumb.push(titlePart);
const breadcrumb = isCreate ? ['产品管理', '添加公告'] : ['产品管理', '公告详情'];
const title = (query.title ? query.title + ' - ' : '') + (isCreate ? '添加公告' : ('公告详情' + (isEdit ? ' - 编辑' : '')) );
const operation = (
<HeaderOperation history={this.props.history}
buttons={DetailOperations('ANNOUNCEMENT', params.id, isEdit, dispatch)}/>
);
const header = (
<MainHeader breadcrumb={breadcrumb} title={title} operation={operation}/>
<MainHeader breadcrumb={breadcrumb} title={title}
operation={operation}
/>
);
return (
......@@ -130,45 +128,16 @@ export default class EditItem extends Component {
<Form.Item label="内容" {...formItemLayout}>
{
isEdit ?
<Input placeholder="公告内容" autosize={{ minRows: 5 }} type="textarea"
<Input placeholder="公告内容" autosize={{minRows: 5}} type="textarea"
{...getFieldProps('announcement', {
initialValue: item.announcement
})} />
:
<p style={{maxWidth:500}} {...innerHTML(item.announcement, true)} />
<p style={{maxWidth: 500}} {...innerHTML(item.announcement, true)} />
}
</Form.Item>
<Form.Item {...footerFormSubmitLayout} style={{marginTop:30}}>
{
isEdit ?
<Button type="primary" onClick={this.handleSubmit.bind(this)}
loading={loading}>
<Icon type="save"/>保存
</Button>
:
<Button type="primary" onClick={e=>{
e.preventDefault();
this.props.dispatch({
type:'UPDATE_ANNOUNCEMENT'
});
}}>
<Icon type="edit"/>编辑
</Button>
}
<Button onClick={e=>{
e.preventDefault();
isEdit ?
this.props.dispatch({
type: 'CANCEL_UPDATE_ANNOUNCEMENT'
}) :
this.props.history.goBack();
}}
style={{marginLeft:'1em'}}>
<Icon type="rollback"/>
{isEdit ? '取消' : '返回'}
</Button>
</Form.Item>
<FooterOperation {...this.props} isEdit={isEdit} command="ANNOUNCEMENT"
hasCancel={!isCreate}/>
</Form>
}
</Spin>
......
......@@ -5,6 +5,7 @@ import {serialize, formatDateTime, productStatusToString, footerFormSubmitLayout
import {Link} from 'react-router';
import Layout from '../../components/Layout/Layout';
import MainHeader from '../../components/MainHeader/MainHeader';
import HeaderOperation from '../../components/HeaderOperation/HeaderOperation';
@connect(state=>({
......@@ -32,9 +33,7 @@ export default class List extends Component {
});
};
handleRowClick({id}) {
this.props.history.push('/announcement/' + id);
}
handleFilterVisible() {
......@@ -42,7 +41,7 @@ export default class List extends Component {
render() {
const {total, items, loading, history:{replace}, location:{pathname, query}} = this.props;
const {total, items, loading, history, location:{pathname, query}} = this.props;
const pagination = {
total: total,
......@@ -50,18 +49,18 @@ export default class List extends Component {
current: parseInt(query.p, 10) || 1,
showSizeChanger: true,
showTotal: total => `共 ${total} 条`,
pageSizeOptions:['10', '30', '50', '100'],
pageSizeOptions: ['10', '30', '50', '100'],
onShowSizeChange: (current, pageSize)=> {
console.log('Current: ', current, '; PageSize: ', pageSize);
query.p = current;
query.s = pageSize;
replace(pathname + '?' + serialize(query));
history.replace(pathname + '?' + serialize(query));
this.fetchList(query);
},
onChange: (current)=> {
console.log('Current: ', current);
query.p = current;
replace(pathname + '?' + serialize(query));
history.replace(pathname + '?' + serialize(query));
this.fetchList(query);
}
};
......@@ -105,14 +104,17 @@ export default class List extends Component {
width: 120,
className: 'tac',
render: (text, record)=>(
<span onClick={e=>{e.stopPropagation(); e.preventDefault();}}>
<span onClick={e=> {
e.stopPropagation();
e.preventDefault();
}}>
<Switch checkedChildren="开" unCheckedChildren="关" defaultChecked={record.status}
onChange={checked=>{
onChange={checked=> {
this.props.dispatch({
type:'UPDATE_ANNOUNCEMENT_ITEM',
item:{
type: 'UPDATE_ANNOUNCEMENT_ITEM',
item: {
id: record.id,
status: checked ? 1: 0
status: checked ? 1 : 0
}
})
}}
......@@ -122,22 +124,18 @@ export default class List extends Component {
}
];
const buttons = [{
key: 'add',
link: '/announcement/create?itemId=' + query.itemId + '&title=' + query.title,
onClick: ()=> {}
}, {
key: 'filter',
}, {
key: 'rollback'
}];
const operation = (
<div style={{textAlign:'right'}}>
<Button.Group>
<Button type="ghost">
<Link to={'/announcement/create?itemId='+ query.itemId + '&title='+ query.title}>
<Icon type="plus"/>
</Link>
</Button>
<Button type="ghost" onClick={this.handleFilterVisible.bind(this)}>
<Icon type="filter"/>
</Button>
<Button type="ghost" onClick={e=>{e.preventDefault(); this.props.history.goBack();}}>
<Icon type="rollback"/>
</Button>
</Button.Group>
</div>
<HeaderOperation history={history} buttons={buttons}/>
);
const header = (
......@@ -147,43 +145,18 @@ export default class List extends Component {
/>
);
const footer = (
<div style={{margin:'10px 0'}}>
<Link to={'/announcement/create?itemId='+ query.itemId + '&title='+ query.title}>
<Button type="primary">
<Icon type="plus"/>添加
</Button>
</Link>
<Button style={{margin:'0 1em'}} type="ghost"
onClick={e=>{e.preventDefault(); this.props.history.goBack();}}>
<Icon type="rollback"/>返回
</Button>
</div>
);
return (
<Layout header={header}>
<Layout header={header} >
<Table className="list-table" columns={columns}
dataSource={Array.isArray(items)?items:[]}
dataSource={Array.isArray(items) ? items : []}
loading={loading}
pagination={pagination}
scroll={{ y: window.innerHeight-(this.state.filterVisible? 203 :150) }}
onRowClick={this.handleRowClick.bind(this)}
scroll={{y: window.innerHeight - (this.state.filterVisible ? 203 : 150)}}
onRowClick={({id})=> {
history.push('/announcement/' + id);
}}
/>
</Layout>
);
}
}
// <Form.Item {...footerFormSubmitLayout} style={{marginTop:30}}>
// <Link to={'/announcement/create?itemId='+ query.itemId + '&title='+ query.title}>
// <Button size="large"><Icon type="plus"/>添加</Button>
// </Link>
// <Button onClick={e=>{e.preventDefault(); this.props.history.goBack();}}
// style={{marginLeft:'1em'}}>
// <Icon type="rollback"/>返回
// </Button>
// </Form.Item>
......@@ -21,16 +21,16 @@ export default class App extends Component {
store: PropTypes.object.isRequired
};
componentDidMount(){
this.fetchAuthorityList();
}
fetchAuthorityList() {
this.props.dispatch({
type: 'FETCH_AUTHORITY_LIST',
query: {s: 100}
});
};
// componentDidMount(){
// this.fetchAuthorityList();
// }
//
// fetchAuthorityList() {
// this.props.dispatch({
// type: 'FETCH_AUTHORITY_LIST',
// query: {s: 100}
// });
// };
render() {
const styles = require('./App.less');
......@@ -118,10 +118,6 @@ export default class App extends Component {
to: '/admin/users',
cn: '用户列表',
en: 'Users'
}, {
to: '/admin/users/create',
cn: '创建用户',
en: 'Create user'
}
]
}, {
......@@ -206,60 +202,6 @@ class MenuItemContent extends Component {
}
// <div className={styles.head}>
// <Row type="flex" justify="space-around" align="middle" style={{height:'100%'}}>
// <Col span="12">
// <img className="page-logo" src={'/'+logo} title="枢纽科技" alt="枢纽科技"/>
// </Col>
// <Col span="12">
// <div style={{float:'right', marginRight:30}}>
// {user.username}
// </div>
// </Col>
// </Row>
// </div>
// <div className={styles.foot}>
// 杭州枢纽科技有限公司 荣誉出品 <a href="mailto:bainx@vip.qq.com">问题反馈</a>
// </div>
//<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>
......@@ -23,6 +23,8 @@ import {
import Layout from '../../components/Layout/Layout';
import MainHeader from '../../components/MainHeader/MainHeader';
import HeaderOperation, {DetailOperations} from '../../components/HeaderOperation/HeaderOperation';
import FooterOperation from '../../components/FooterOperation/FooterOperation';
import {
formItemLayout,
......@@ -44,26 +46,37 @@ import './EditItem.less';
item: state.authority.item,
isEdit: state.authority.isEdit,
resources: state.resource.items,
resourcesTotal: state.resource.total
resourcesTotal: state.resource.total,
removed: state.authority.removed
}))
@Form.create()
export default class EditItem extends Component {
constructor() {
super(...arguments);
this.state = {
resourcesCategoryMap:{},
resourcesCategoryMap: {},
checkedKeys: []
}
}
componentDidMount() {
this.fetchItem(this.props.params.id);
const {params:{id}} = this.props;
if (id) {
this.fetchItem(id);
if (id !== 'ROLE_ADMIN') {
this.fetchResourceList();
}
}
};
componentWillReceiveProps(nextProps) {
if (nextProps.item && nextProps.item.permissions && nextProps.resources) {
const {params:{id}, history} = this.props;
const {item, resources} = nextProps;
if (!id && item && item.id) {
history.replace('/admin/authorities/' + item.id);
return;
}
if (item && item.permissions && resources) {
this.analysisCheckedKeys(nextProps);
}
};
......@@ -86,12 +99,15 @@ export default class EditItem extends Component {
e.preventDefault();
let data = {};
data = this.props.form.getFieldsValue();
if (this.props.params.id) {
data.id = this.props.params.id;
}
const permissions = {};
this.state.checkedKeys.forEach(key=>{
this.state.checkedKeys.forEach(key=> {
const [ka, cn, mask] = key.split('-');
if(ka === 'a' && mask){
permissions[cn] =( permissions[cn]|| 0) + parseInt(mask, 10);
if (ka === 'a' && mask) {
permissions[cn] = ( permissions[cn] || 0) + parseInt(mask, 10);
}
});
data.permissions = JSON.stringify(permissions);
......@@ -105,7 +121,7 @@ export default class EditItem extends Component {
}
console.log(data);
this.props.dispatch({
type: 'UPDATE_AUTHORITY_ITEM',
type: data.id ? 'UPDATE_AUTHORITY_ITEM' : 'CREATE_AUTHORITY_ITEM',
item: data
});
}
......@@ -127,16 +143,16 @@ export default class EditItem extends Component {
if (permisAction.length) {
permisAction.forEach(pac=> {
permisActionMap[pac.mask] = pac;
permisActionMap[pac.value] = pac;
});
}
if (isEdit) {
res.action = resourceActions(res.actionMask);
res.action.forEach(ac=> {
if (permisActionMap[ac.mask]) {
if (permisActionMap[ac.value]) {
ac.checked = true;
checkedKeys.push(['a', res.controllerName, ac.mask].join('-'));
checkedKeys.push(['a', res.controllerName, ac.value].join('-'));
}
});
} else {
......@@ -158,34 +174,22 @@ export default class EditItem extends Component {
render() {
const {item, resources, loading, form:{getFieldProps}, location:{query}, isEdit} = this.props;
let {params, item, resources, loading, form:{getFieldProps}, location:{query}, dispatch, isEdit} = this.props;
const operation = (
<div style={{textAlign:'right'}}>
<Button.Group>
<Button type="ghost"
onClick={
e=>{
e.preventDefault();
this.props.dispatch({
type: isEdit ? 'CANCEL_UPDATE_AUTHORITY' : 'UPDATE_AUTHORITY'
});
const isCreate = !params.id;
if (!params.id) {
item = {
status: 1
};
isEdit = true;
}
}>
<Icon type="edit"/>
</Button>
<Button type="ghost" onClick={e=>{
e.preventDefault();
isEdit ?
this.props.dispatch({
type: 'CANCEL_UPDATE_AUTHORITY'
}) :
this.props.history.goBack();
}}>
<Icon type="rollback"/>
</Button>
</Button.Group>
</div>
const operation = (
<HeaderOperation history={this.props.history}
buttons={DetailOperations('AUTHORITY', params.id, isEdit, dispatch)}/>
);
const header = (
......@@ -200,12 +204,14 @@ export default class EditItem extends Component {
<Spin spinning={loading}>
{
item &&
<Form className="main-form" horizontal>
<Row>
<Form className="main-form" horizontal onSubmit={this.handleSubmit.bind(this)}>
<Row style={{marginLeft: 20}}>
<Col span="12">
<Form.Item label="角色ID" {...smallFormItemLayout}>
{
isCreate ?
<Input {...getFieldProps('name', {initialValue: item.name})} />
:
item.name || NULL
}
</Form.Item>
......@@ -230,70 +236,52 @@ export default class EditItem extends Component {
(typeof item.status !== 'undefined' ? enableStatusToString(item.status) : NULL)
}
</Form.Item>
{
!isCreate &&
<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)}
loading={loading}>
<Icon type="save"/>保存
</Button>
item.dateCreated ?
formatDateTime(item.dateCreated)
:
<Button type="primary" onClick={e=>{
e.preventDefault();
this.props.dispatch({
type:'UPDATE_AUTHORITY'
});
}}>
<Icon type="edit"/>编辑
</Button>
NULL
}
<Button onClick={e=>{
e.preventDefault();
isEdit ?
this.props.dispatch({
type: 'CANCEL_UPDATE_AUTHORITY'
}) :
this.props.history.goBack();
}}
style={{marginLeft:'1em'}}>
<Icon type="rollback"/>
{isEdit ? '取消' : '返回'}
</Button>
</Form.Item>
}
<FooterOperation {...this.props} isEdit={isEdit} command="AUTHORITY"
hasCancel={!isCreate}/>
</Col>
<Col span="12">
<Tree checkable={isEdit}
defaultExpandAll={true}
checkedKeys={this.state.checkedKeys}
onCheck={(checkedKeys)=>{this.setState({checkedKeys});}}>
onCheck={(checkedKeys)=> {
this.setState({checkedKeys});
}}>
{
Object.keys(this.state.resourcesCategoryMap).map((key, index)=>
<Tree.TreeNode className="resource-category" key={'c-'+key}
<Tree.TreeNode className="resource-category" key={'c-' + key}
title={key}>
{
this.state.resourcesCategoryMap[key].map(res=>
<Tree.TreeNode className="resource-item"
key={
res.action.length===1 ?
('a-'+res.controllerName+'-'+res.action[0].mask) :
res.action.length === 1 ?
('a-' + res.controllerName + '-' + res.action[0].value) :
('r-' + res.id)
}
title={
res.description + (
res.action.length===1 ? ' - '+res.action[0].title :''
res.action.length === 1 ? ' - ' + res.action[0].label : ''
)
}>
{
res.action.length > 1 && res.action.map(action=>
<Tree.TreeNode className="resource-action"
key={'a-' + res.controllerName + '-' + action.mask}
title={action.title}/>
key={'a-' + res.controllerName + '-' + action.value}
title={action.label}/>
)
}
</Tree.TreeNode>
......
import React, {Component, PropTypes} from 'react';
import {connect} from 'react-redux';
import {Table, Icon, Row, Col, Button, Form, Input, Cascader, Select} from 'antd';
import {Table, Icon, Popconfirm, Row, Col, Button, Form, Input, Cascader, Select} from 'antd';
import {
serialize,
formatDateTime,
......@@ -14,12 +14,13 @@ import {
filterFormItemLayout,
PRODUCT_STATUS,
filterFormItemStyle,
enableStatusToString
enableStatusToString,
} from '../../utils';
import {Link} from 'react-router';
import Layout from '../../components/Layout/Layout';
import MainHeader from '../../components/MainHeader/MainHeader';
import HeaderOperation from '../../components/HeaderOperation/HeaderOperation';
@connect(state=>({
......@@ -88,9 +89,17 @@ export default class List extends Component {
total, cates, items, loading,
form:{getFieldProps},
history:{replace},
location:{pathname, query}
location:{pathname, query},
dispatch
} = this.props;
const handleRemove = (id)=>{
dispatch({
type: 'DELETE_AUTHORITY_ITEM',
id
});
};
const columns = [
{
title: '角色ID',
......@@ -122,6 +131,18 @@ export default class List extends Component {
render: (status)=>(
<span>{enableStatusToString(status)}</span>
)
},{
title: '操作',
key: 'operation',
width: 120,
className: 'tac',
render: (text, record)=>(
<Popconfirm title="确定要删除这个角色吗?"
onClick={e=>{e.preventDefault();e.stopPropagation();}}
onConfirm={handleRemove.bind(this, record.name )} >
<a href="javascript:void('删除')">删除</a>
</Popconfirm>
)
}
];
......@@ -148,19 +169,24 @@ export default class List extends Component {
}
};
const buttons = [{
key:'add',
link:'/admin/authorities/create',
onClick:()=>{}
},{
key:'filter',
}];
const operation = (
<div style={{textAlign:'right'}}>
<Button.Group>
<Button type="ghost" onClick={this.handleFilterVisible.bind(this)}>
<Icon type="filter"/>
</Button>
</Button.Group>
</div>
<HeaderOperation history={this.props.history} buttons={buttons}/>
);
const header = (
<MainHeader breadcrumb={['权限管理', '权限资源列表']}
title="权限资源列表"
<MainHeader breadcrumb={['角色管理', '角色列表']}
title="角色列表"
operation={operation}
>
{
......
......@@ -22,6 +22,7 @@ import {
import Layout from '../../components/Layout/Layout';
import MainHeader from '../../components/MainHeader/MainHeader';
import HeaderOperation, {DetailOperations} from '../../components/HeaderOperation/HeaderOperation';
import {formItemLayout, footerFormSubmitLayout} from '../../utils';
......@@ -54,22 +55,22 @@ export default class AddItem extends Component {
}
render = ()=> {
const {loading, form:{getFieldProps}, location:{query}} = this.props;
const {loading, form:{getFieldProps}, location:{query}, dispatch} = this.props;
const operation = (
<HeaderOperation history={this.props.history} buttons={[{key:'rollback'}]}/>
);
const header = (
<MainHeader breadcrumb={['消息管理', '推送消息']} title="推送消息"/>
<MainHeader breadcrumb={['消息管理', '推送消息']} title="推送消息"
operation={operation}
/>
);
const redirectNamePlaceholder = {0: '无需填写', 1: '请输入一个产品ID', 2: '请输入消息跳转指定的URL地址'};
const sendNamePlaceholder = {1: '无需填写', 2: '请输入一个产品ID', 3: '请输入接收消息的人员的手机号码'};
// <Select placeholder="请选择" {...getFieldProps('customMessage.channelType')} >
// <Select.Option value="1">微信</Select.Option>
// <Select.Option value="3">APP</Select.Option>
// </Select>
const {channelType} = this.state;
return (
......
......@@ -10,6 +10,7 @@ import {
import Layout from '../../components/Layout/Layout';
import MainHeader from '../../components/MainHeader/MainHeader';
import HeaderOperation, {DetailOperations} from '../../components/HeaderOperation/HeaderOperation';
@connect(state=>({
loading: state.customMessage.loading,
......@@ -28,12 +29,23 @@ export default class Item extends Component {
render() {
const {item, loading} = this.props;
const {item, loading, dispatch} = this.props;
const styles = require('../Trade/Item.less');
const tw = 8;
const vw = 16;
const header = (<MainHeader breadcrumb={['消息管理', '消息详情']}
title={((item && item.title) ? item.title + ' - ' : '') + '消息详情'}/>);
const operation = (
<HeaderOperation history={this.props.history} buttons={[{key:'rollback'}]}/>
);
const header = (
<MainHeader breadcrumb={['消息管理', '消息详情']}
title={((item && item.title) ? item.title + ' - ' : '') + '消息详情'}
operation={operation}
/>
);
return (
<Layout header={header}>
{
......
......@@ -5,6 +5,7 @@ import {serialize, formatDateTime, productStatusToString, footerFormSubmitLayout
import {Link} from 'react-router';
import Layout from '../../components/Layout/Layout';
import MainHeader from '../../components/MainHeader/MainHeader';
import HeaderOperation from '../../components/HeaderOperation/HeaderOperation';
@connect(state=>({
......@@ -93,7 +94,21 @@ export default class List extends Component {
}
];
const header = (<MainHeader breadcrumb={['消息管理', '消息列表']} title="消息列表"/>);
const buttons = [{
key:'add',
link:'/customMessages/create',
onClick:()=>{}
},{
key:'filter',
}];
const operation = (
<HeaderOperation history={this.props.history} buttons={buttons}/>
);
const header = (
<MainHeader breadcrumb={['消息管理', '消息列表']} title="消息列表" operation={operation}/>
);
return (
<Layout header={header}>
......
import React, {Component, PropTypes} from 'react';
import {connect} from 'react-redux';
import {Form, Input, Button, Checkbox, message, Spin} from 'antd';
import {Link} from 'react-router';
@connect(state=>({
loading: state.user.loading
......@@ -17,10 +18,9 @@ export default class Login extends Component {
handleSubmit = (e)=> {
e.preventDefault();
const data = this.props.form.getFieldsValue();
console.log('收到表单值:', data);
this.props.dispatch({
...data,
push: this.props.history.push,
replace: this.props.history.replace,
type: 'LOGIN_REQUEST'
});
};
......@@ -34,9 +34,7 @@ export default class Login extends Component {
<div className={styles.normal}>
<div className={styles.content}>
<div className={styles['login-bg']}>
<img src={bg}/>
</div>
<div className={styles['login-bg']} style={{backgroundImage: 'url(' + bg + ')'}}/>
<div className={styles['login-container']}>
<div>
<div>
......@@ -56,6 +54,10 @@ export default class Login extends Component {
<Checkbox {...getFieldProps('agreement')}>记住我</Checkbox>
</Form.Item>
<Button type="primary" htmlType="submit">登录</Button>
<Link to="/register">
<Button type="ghost">注册</Button>
</Link>
</div>
</Form>
</div>
......
......@@ -11,8 +11,11 @@
.login-bg {
width: 50%;
height:100vh;
height: 100vh;
overflow: hidden;
background-repeat: no-repeat;
background-position: left center;
background-size: cover;
}
.login-container {
......@@ -53,8 +56,8 @@
button {
float: right;
margin-right: 10px;
background-color: #32c5d2;
border-color: #32c5d2;
//background-color: #32c5d2;
//border-color: #32c5d2;
border-radius: 0;
}
}
......@@ -62,6 +65,7 @@
}
:global(.fade-enter) {
opacity: 0;
animation-duration: 2s;
......@@ -97,7 +101,6 @@
}
}
@keyframes fadeIn {
0% {
opacity: 0;
......
......@@ -20,13 +20,8 @@ import {
Spin,
Breadcrumb
} from 'antd';
import HuikuanInfoForm from '../../components/ProductForm/HuikuanInfoForm';
import BaseInfoForm from '../../components/ProductForm/BaseInfoForm';
import ShouyiYongjingForm from '../../components/ProductForm/ShouyiYongjingForm';
import ElementForm from '../../components/ProductForm/ElementForm';
import DateTimeStatusForm from '../../components/ProductForm/DateTimeStatusForm';
import DocumentsForm from '../../components/ProductForm/DocumentsForm';
import ContactForm from '../../components/ProductForm/ContactForm';
import * as ProductForm from '../../components/ProductForm/index';
import MainHeader from '../../components/MainHeader/MainHeader';
import Layout from '../../components/Layout/Layout';
......@@ -69,7 +64,7 @@ class PublishForm extends Component {
product: state.product.item,
loading: state.product.loading,
isCreate: true,
isEdit: state.product.isEdit
isEdit: true
}))
export default class AddItem extends Component {
......@@ -100,8 +95,7 @@ export default class AddItem extends Component {
};
componentWillReceiveProps(nextProps) {
this.setState({isEdit: nextProps.isEdit});
if(nextProps.product && nextProps.product.id){
if (nextProps.product && nextProps.product.id) {
this.props.dispatch({
type: 'UPDATE_PRODUCT'
});
......@@ -117,39 +111,22 @@ export default class AddItem extends Component {
render = ()=> {
const {product} = this.props;
const {product, isEdit, isCreate} = this.props;
const {isEdit} = this.state;
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
}, {
tab: '发布',
children: PublishForm
}].map((tabPane, index)=> {
const tabs = [
{tab: '基本信息', children: ProductForm.BaseInfoForm},
{tab: '收益佣金', children: ProductForm.ShouyiYongjingForm},
{tab: '汇款账号', children: ProductForm.HuikuanInfoForm},
{tab: '基本要素', children: ProductForm.ElementForm},
{tab: '时间', children: ProductForm.DateTimeStatusForm},
{tab: '相关附件', children: ProductForm.DocumentsForm},
{tab: '服务经理', children: ProductForm.ContactForm},
{tab: '发布', children: PublishForm}
].map((tabPane, index)=> {
tabPane.key = 'tabs-pane-' + (index + 1);
//tabPane.disabled = index != this.state.step - 1;
return tabPane;
});
......@@ -160,7 +137,7 @@ export default class AddItem extends Component {
<Tabs className={styles.tabs} tabPosition="left">
{ tabs.map(tp=>
<Tabs.TabPane tab={tp.tab} key={tp.key}>
{product && <tp.children {...this.props} isEdit={isEdit} /> }
{product && <tp.children {...this.props} isEdit={isEdit} isCreate={true}/> }
</Tabs.TabPane>
)}
</Tabs>
......@@ -168,26 +145,3 @@ export default class AddItem extends Component {
);
}
}
// <div style={{textAlign:'center', borderTop:'1px solid #eee', height:60, paddingTop:20 }}>
// {
// this.state.step > 1 &&
// <Button loading={this.props.loading}
// style={{margin:'0 1em'}}
// onClick={handleStep.bind(this, -1)}><Icon type="save"/>上一步</Button>
// }
//
// {
// this.state.step < tabs.length &&
// <Button type="primary" loading={this.props.loading}
// style={{margin:'0 1em'}}
// onClick={handleStep.bind(this, 1)}><Icon type="save"/>下一步</Button>
// }
//
// {
// this.state.step == tabs.length &&
// <Button type="primary" loading={this.props.loading}
// ><Icon type="solution"/>发布</Button>
// }
// </div>
......@@ -21,16 +21,12 @@ import {
Breadcrumb
} from 'antd';
import HuikuanInfoForm from '../../components/ProductForm/HuikuanInfoForm';
import BaseInfoForm from '../../components/ProductForm/BaseInfoForm';
import ShouyiYongjingForm from '../../components/ProductForm/ShouyiYongjingForm';
import ElementForm from '../../components/ProductForm/ElementForm';
import DateTimeStatusForm from '../../components/ProductForm/DateTimeStatusForm';
import DocumentsForm from '../../components/ProductForm/DocumentsForm';
import ContactForm from '../../components/ProductForm/ContactForm';
import * as ProductForm from '../../components/ProductForm/index';
import HeaderOperation, {DetailOperations} from '../../components/HeaderOperation/HeaderOperation';
import MainHeader from '../../components/MainHeader/MainHeader';
import Layout from '../../components/Layout/Layout';
@connect(state=>({
cates: state.product.cates,
product: state.product.item,
......@@ -49,9 +45,6 @@ export default class EditItem extends Component {
constructor(props, content) {
super(props, content);
this.state = {
isEdit: false
}
}
......@@ -62,10 +55,6 @@ export default class EditItem extends Component {
this.fetchItem(this.props.params.id);
};
componentWillReceiveProps(nextProps) {
this.setState({isEdit: nextProps.isEdit});
};
fetchCates() {
this.props.dispatch({
type: 'FETCH_PRODUCT_CATES'
......@@ -82,59 +71,38 @@ export default class EditItem extends Component {
render = ()=> {
const {product} = this.props;
const {product, isEdit, params, dispatch} = this.props;
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}
{tab: '基本信息', children: ProductForm.BaseInfoForm},
{tab: '收益佣金', children: ProductForm.ShouyiYongjingForm},
{tab: '汇款账号', children: ProductForm.HuikuanInfoForm},
{tab: '基本要素', children: ProductForm.ElementForm},
{tab: '时间状态', children: ProductForm.DateTimeStatusForm},
{tab: '相关附件', children: ProductForm.DocumentsForm},
{tab: '服务经理', children: ProductForm.ContactForm}
].map((tabPane, index)=> {
tabPane.key = 'tabs-pane-' + (index + 1);
return tabPane;
});
const {isEdit} = this.state;
const title = (product && product.itemShortTitle ? product.itemShortTitle + ' - ' : '') + '产品详情' + (isEdit ? ' - 编辑中' : '');
const operation = (
<div style={{textAlign:'right'}}>
<Button.Group>
{
product &&
<Button type="ghost"
onClick={
e=>{
e.preventDefault();
this.props.dispatch({
type: isEdit ? 'CANCEL_UPDATE_PRODUCT' : 'UPDATE_PRODUCT'
});
}
}>
<Icon type="edit"/>
</Button>
}
<Button type="ghost" onClick={e=>{
e.preventDefault();
isEdit ?
this.props.dispatch({
type: 'CANCEL_UPDATE_PRODUCT'
}) :
this.props.history.goBack();
}}>
<Icon type="rollback"/>
</Button>
</Button.Group>
</div>
<HeaderOperation history={this.props.history}
buttons={product && DetailOperations('PRODUCT', params.id, isEdit, dispatch)}/>
);
const title = (product && product.itemShortTitle ? product.itemShortTitle + ' - ' : '') + '产品详情' + (isEdit ? ' - 编辑中' : '');
const header = (
<MainHeader breadcrumb={['产品管理', '产品详情']}
title={title}
operation={operation}
/>
);
const header = (<MainHeader breadcrumb={['产品管理', '产品详情']} title={title} operation={operation}/>);
return (
<Layout header={header}>
......
......@@ -19,6 +19,7 @@ import {Link} from 'react-router';
import Layout from '../../components/Layout/Layout';
import MainHeader from '../../components/MainHeader/MainHeader';
import HeaderOperation from '../../components/HeaderOperation/HeaderOperation';
const ProductStatus = Object.keys(PRODUCT_STATUS).filter(key=>key != -9);
......@@ -73,13 +74,13 @@ const columns = [
className: 'tac',
render: (text, product)=>(
<span>
<Link to={'/announcement?itemId='+product.id+'&title='+product.shortTitle}
<Link to={'/announcement?itemId=' + product.id + '&title=' + product.shortTitle}
onClick={e=>e.stopPropagation()}>公告</Link>
{
productEnableCreateTrade(product.status) &&
<span>
<span className="ant-divider"></span>
<Link to={'/trades/create?itemId='+product.id+'&title='+product.shortTitle}
<Link to={'/trades/create?itemId=' + product.id + '&title=' + product.shortTitle}
onClick={e=>e.stopPropagation()}>报单</Link>
</span>
}
......@@ -175,7 +176,7 @@ export default class List extends Component {
current: parseInt(query.p, 10) || 1,
showSizeChanger: true,
showTotal: total => `共 ${total} 条`,
pageSizeOptions:['10', '30', '50', '100'],
pageSizeOptions: ['10', '30', '50', '100'],
onShowSizeChange: (current, pageSize)=> {
console.log('Current: ', current, '; PageSize: ', pageSize);
query.p = current;
......@@ -191,16 +192,13 @@ export default class List extends Component {
}
};
const operation = (
<div style={{textAlign:'right'}}>
<Button.Group>
<Button type="ghost" onClick={this.handleFilterVisible.bind(this)}>
<Icon type="filter"/>
</Button>
</Button.Group>
</div>
<HeaderOperation history={this.props.history}
buttons={[{key: 'filter', onClick: this.handleFilterVisible.bind(this)}]}/>
);
const header = (
<MainHeader breadcrumb={['产品管理', '产品列表']}
title="产品列表"
......@@ -252,10 +250,10 @@ export default class List extends Component {
return (
<Layout header={header}>
<Table className="list-table" columns={columns}
dataSource={Array.isArray(items)?items:[]}
dataSource={Array.isArray(items) ? items : []}
loading={loading}
pagination={pagination}
scroll={{ y: window.innerHeight-(this.state.filterVisible? 203 :150) }}
scroll={{y: window.innerHeight - (this.state.filterVisible ? 203 : 150)}}
onRowClick={this.handleRowClick.bind(this)}
/>
</Layout>
......
......@@ -5,6 +5,7 @@ import {Link} from 'react-router';
import {serialize, formatDateTime, remittanceAuditStatusToString} from '../../utils';
import Layout from '../../components/Layout/Layout';
import MainHeader from '../../components/MainHeader/MainHeader';
import HeaderOperation from '../../components/HeaderOperation/HeaderOperation';
const columns = [
{
......@@ -121,8 +122,17 @@ export default class List extends Component {
}
};
const operation = (
<HeaderOperation history={this.props.history} buttons={[{
key:'filter',
}]}/>
);
const header = (<MainHeader breadcrumb={['审核管理', '报单审核']}
title="报单审核列表"/>);
title="报单审核列表"
operation={operation}
/>);
return (
<Layout header={header}>
......
......@@ -22,6 +22,7 @@ import {
import Layout from '../../components/Layout/Layout';
import MainHeader from '../../components/MainHeader/MainHeader';
import HeaderOperation, {DetailOperations} from '../../components/HeaderOperation/HeaderOperation';
import {
formatDateTime,
......@@ -42,9 +43,9 @@ export default class PassItem extends Component {
constructor() {
super(...arguments);
this.state = {
isEdit: false,
priviewVisible: false,
priviewImage: ''
priviewImage: '',
isEdit: false
}
}
......@@ -75,13 +76,12 @@ export default class PassItem extends Component {
}
render() {
const {audit, loading, form:{getFieldProps}, location:{query}} = this.props;
const {audit, loading, form:{getFieldProps}, location:{query}, params, dispatch} = this.props;
let title = (audit && audit.itemShortTitle ? audit.itemShortTitle + ' - ' : '');
const isEdit = audit && audit.status == 1 && this.state.isEdit;
if (audit) {
switch (audit.status) {
case 1:
......@@ -97,29 +97,32 @@ export default class PassItem extends Component {
title += '报单审核详情';
}
const operation = (
<div style={{textAlign:'right'}}>
<Button.Group>
{
audit && audit.status == 1 &&
<Button type="ghost"
onClick={e=>{e.preventDefault(); this.setState({isEdit: !this.state.isEdit})}}>
<Icon type="edit"/>
</Button>
}
<Button type="ghost" onClick={e=>{
const buttons = [{
key: 'rollback',
onClick: e=> {
e.preventDefault();
isEdit ?
this.setState({isEdit: !this.state.isEdit}) :
this.props.history.goBack();
}}>
<Icon type="rollback"/>
</Button>
</Button.Group>
</div>
}
}];
if(audit && audit.status == 1){
buttons.unshift({
key:'edit',
onClick:e=> {
e.preventDefault();
this.setState({isEdit: !this.state.isEdit})
}
});
}
const operation = (
<HeaderOperation history={this.props.history} buttons={buttons}/>
);
const header = (<MainHeader breadcrumb={['审核管理', '报单审核','审核详情']} title={title} operation={operation}/>);
const header = (<MainHeader breadcrumb={['审核管理', '报单审核', '审核详情']} title={title} operation={operation}/>);
const imgProps = (src)=>({
......@@ -141,7 +144,7 @@ export default class PassItem extends Component {
{
audit &&
<Form className="main-form" horizontal>
<Row style={{padding:'0 20px'}}>
<Row style={{padding: '0 20px'}}>
<Col span="12">
<Form.Item label="报单时间" {...leftRightFormItemLayout}>
{audit.dateCreated && formatDateTime(audit.dateCreated) || '错误的时间'}
......@@ -216,7 +219,7 @@ export default class PassItem extends Component {
})} />
</Form.Item>
}
<Form.Item wrapperCol={{span: 16, offset: 6}} style={{marginTop:30}}>
<Form.Item wrapperCol={{span: 16, offset: 6}} style={{marginTop: 30}}>
{
audit.status == 1 && (
isEdit ?
......@@ -227,14 +230,14 @@ export default class PassItem extends Component {
</Button>
<Button size="large" type="ghost"
onClick={this.handleSubmit.bind(this, 5)}
style={{margin:'auto 1em' }}>
style={{margin: 'auto 1em'}}>
<Icon type="cross-circle-o"/>拒绝
</Button>
</span>
:
<Button type="primary"
style={{marginRight:'1em'}}
onClick={ e=>{
style={{marginRight: '1em'}}
onClick={ e=> {
e.preventDefault();
this.setState({isEdit: !this.state.isEdit})
}}>
......@@ -242,7 +245,7 @@ export default class PassItem extends Component {
</Button>
)
}
<Button onClick={e=>{
<Button onClick={e=> {
e.preventDefault();
isEdit ?
this.setState({isEdit: !this.state.isEdit}) :
......@@ -258,8 +261,8 @@ export default class PassItem extends Component {
audit.identityCardFront ?
<img {...imgProps(audit.identityCardFront)}/>
:
<p style={{color:'#f00'}}>
<Icon type="cross-circle-o" style={{ marginRight:'.5em'}}/>
<p style={{color: '#f00'}}>
<Icon type="cross-circle-o" style={{marginRight: '.5em'}}/>
身份证正面照片未上传,请拒绝!
</p>
}
......@@ -267,8 +270,8 @@ export default class PassItem extends Component {
audit.identityCardBack ?
<img {...imgProps(audit.identityCardBack)}/>
:
<p style={{color:'#f00'}}>
<Icon type="cross-circle-o" style={{ marginRight:'.5em'}}/>
<p style={{color: '#f00'}}>
<Icon type="cross-circle-o" style={{marginRight: '.5em'}}/>
身份证反面照片未上传,请拒绝!
</p>
}
......@@ -279,8 +282,8 @@ export default class PassItem extends Component {
audit.bankCardPic ?
<img {...imgProps(audit.bankCardPic)}/>
:
<p style={{color:'#f00'}}>
<Icon type="cross-circle-o" style={{ marginRight:'.5em'}}/>
<p style={{color: '#f00'}}>
<Icon type="cross-circle-o" style={{marginRight: '.5em'}}/>
银行卡照片未上传,请拒绝!
</p>
}
......@@ -290,8 +293,8 @@ export default class PassItem extends Component {
audit.remittanceReceipt ?
<img {...imgProps(audit.remittanceReceipt)}/>
:
<p style={{color:'#f00'}}>
<Icon type="cross-circle-o" style={{ marginRight:'.5em'}}/>
<p style={{color: '#f00'}}>
<Icon type="cross-circle-o" style={{marginRight: '.5em'}}/>
打款凭条照片未上传,请拒绝!
</p>
}
......@@ -304,8 +307,8 @@ export default class PassItem extends Component {
<img key={index} {...imgProps(img)}/>
)
:
<p style={{color:'#f00'}}>
<Icon type="cross-circle-o" style={{ marginRight:'.5em'}}/>
<p style={{color: '#f00'}}>
<Icon type="cross-circle-o" style={{marginRight: '.5em'}}/>
签字页照片未上传,请拒绝!
</p>
}
......@@ -314,7 +317,7 @@ export default class PassItem extends Component {
</Row>
<Modal className="img-priview-dialog" footer={null}
visible={this.state.priviewVisible}
onCancel={()=>this.setState({ priviewVisible: false })}>
onCancel={()=>this.setState({priviewVisible: false})}>
<img src={this.state.priviewImage}/>
</Modal>
</Form>
......
......@@ -22,6 +22,8 @@ import {
import Layout from '../../components/Layout/Layout';
import MainHeader from '../../components/MainHeader/MainHeader';
import HeaderOperation,{DetailOperations} from '../../components/HeaderOperation/HeaderOperation';
import {
formItemLayout,
......@@ -35,6 +37,7 @@ import {
ENABLE_STATUS_LIST
} from '../../utils';
@connect(state=>({
loading: state.resource.loading,
item: state.resource.item,
......@@ -54,10 +57,6 @@ export default class EditItem extends Component {
this.fetchItem(this.props.params.id);
};
componentWillReceiveProps(nextProps) {
this.setState({isEdit: nextProps.isEdit});
};
fetchItem(id) {
this.props.dispatch({
type: 'FETCH_RESOURCE_ITEM',
......@@ -86,42 +85,14 @@ export default class EditItem extends Component {
}
render() {
const {item, loading, form:{getFieldProps}, location:{query}} = this.props;
const {item, loading, form:{getFieldProps}, location:{query}, isEdit, dispatch} = this.props;
const {isEdit} = this.state;
const operation = (
<div style={{textAlign:'right'}}>
<Button.Group>
<Button type="ghost"
onClick={
e=>{
e.preventDefault();
this.props.dispatch({
type: isEdit ? 'CANCEL_UPDATE_RESOURCE' : 'UPDATE_RESOURCE'
});
}
}>
<Icon type="edit"/>
</Button>
<Button type="ghost" onClick={e=>{
e.preventDefault();
isEdit ?
this.props.dispatch({
type: 'CANCEL_UPDATE_PRODUCT'
}) :
this.props.history.goBack();
}}>
<Icon type="rollback"/>
</Button>
</Button.Group>
</div>
);
const header = (
<MainHeader breadcrumb={['权限管理', '权限资源详情']}
title={'权限资源详情' + (isEdit ? ' - 编辑' : '')}
operation={operation}
operation={<HeaderOperation buttons={item && DetailOperations('RESOURCE', item.id, isEdit, dispatch)} />}
/>
);
......@@ -171,8 +142,8 @@ export default class EditItem extends Component {
</Form.Item>
<Form.Item label="Actions" {...smallFormItemLayout}>
{
resourceActions(item.actionMask).map(({title, mask})=>
<span key={mask} style={{marginRight:'1em'}}>{title}</span>
resourceActions(item.actionMask).map(({label, value})=>
<span key={value} style={{marginRight:'1em'}}>{label}</span>
)
}
</Form.Item>
......
......@@ -15,13 +15,14 @@ import {
PRODUCT_STATUS,
filterFormItemStyle,
ENABLE_STATUS_LIST,
enableStatusToString
enableStatusToString,
resourceActions
} from '../../utils';
import {Link} from 'react-router';
import Layout from '../../components/Layout/Layout';
import MainHeader from '../../components/MainHeader/MainHeader';
import HeaderOperation from '../../components/HeaderOperation/HeaderOperation';
@connect(state=>({
......@@ -108,18 +109,18 @@ export default class List extends Component {
title: '名称',
dataIndex: 'description',
key: 'description',
width: 200
width: 80
}, {
title: '资源',
dataIndex: 'controllerName',
key: 'controllerName',
width: 180,
}, {
title: '权限',
title: '权限',
dataIndex: 'actionMask',
key: 'actionMask',
width: 80,
className: 'tac'
width: 320,
render: mask => resourceActions(mask).map(ra => <span key={ra.value} style={{marginRight:'1em'}}>{ra.label}</span>)
}, {
title: '创建时间',
dataIndex: 'dateCreated',
......@@ -167,13 +168,7 @@ export default class List extends Component {
};
const operation = (
<div style={{textAlign:'right'}}>
<Button.Group>
<Button type="ghost" onClick={this.handleFilterVisible.bind(this)}>
<Icon type="filter"/>
</Button>
</Button.Group>
</div>
<HeaderOperation history={this.props.history} buttons={[{key:'filter'}]}/>
);
const header = (
......
......@@ -19,6 +19,7 @@ import {
import Layout from '../../components/Layout/Layout';
import MainHeader from '../../components/MainHeader/MainHeader';
import HeaderOperation, {DetailOperations} from '../../components/HeaderOperation/HeaderOperation';
import {
formatDateTime,
......@@ -116,7 +117,12 @@ export default class AddItem extends Component {
const {loading, form:{getFieldProps}, location:{query}, user} = this.props;
const operation = (
<HeaderOperation history={this.props.history} buttons={[{key:'rollback'}]}/>
);
const header = (<MainHeader breadcrumb={['订单管理', '创建订单']}
operation={operation}
title={(query.title ? query.title + ' - ' : '') + '报单'}/>);
return (
......
......@@ -17,7 +17,8 @@ import {
Modal,
DatePicker,
Table,
Spin
Spin,
Popconfirm
} from 'antd';
import {
......@@ -32,6 +33,8 @@ import {
import Layout from '../../components/Layout/Layout';
import MainHeader from '../../components/MainHeader/MainHeader';
import HeaderOperation, {DetailOperations} from '../../components/HeaderOperation/HeaderOperation';
@connect(state=>({
item: state.trade.item,
......@@ -49,8 +52,7 @@ export default class Commission extends Component {
};
handleSubmit(e) {
e.preventDefault();
handleSubmit() {
this.props.dispatch({
type: 'SETTLEMENT_TRADE_ITEM',
id: this.props.item.id
......@@ -61,7 +63,12 @@ export default class Commission extends Component {
const {item, loading, form:{getFieldProps}, location:{query}} = this.props;
const operation = (
<HeaderOperation history={this.props.history} buttons={[{key:'rollback'}]}/>
);
const header = (<MainHeader breadcrumb={['订单管理', '订单详情', '佣金发放']}
operation={operation}
title={(item && item.shortTitle + ' - ' || '') + '佣金发放'}/>);
return (
......@@ -69,7 +76,7 @@ export default class Commission extends Component {
<Spin spinning={loading}>
{
item &&
<Form className="main-form" horizontal onSubmit={this.handleSubmit.bind(this)}>
<Form className="main-form" horizontal >
<Form.Item label="产品" {...smallFormItemLayout}>
<p>{item.title || NULL}</p>
</Form.Item>
......@@ -95,9 +102,12 @@ export default class Commission extends Component {
<Form.Item {...footerFormSubmitLayout} style={{marginTop:30}}>
{
(item.status == 11 || item.status == 21) && (! item.commissionId) &&
<Button type="primary" htmlType="submit" loading={loading}>
<Popconfirm title="确定要发放佣金吗?" onConfirm={this.handleSubmit.bind(this)} >
<Button type="primary" size="large" loading={loading}>
<Icon type="save"/>发放
</Button>
</Popconfirm>
}
<Button onClick={e=>{e.preventDefault(); this.props.history.goBack();}}
style={{marginLeft:'1em'}}>
......
......@@ -30,6 +30,7 @@ import {
import Layout from '../../components/Layout/Layout';
import MainHeader from '../../components/MainHeader/MainHeader';
import HeaderOperation, {DetailOperations} from '../../components/HeaderOperation/HeaderOperation';
@connect(state=>({
loading: state.contract.loading,
......@@ -63,8 +64,12 @@ export default class Contract extends Component {
render() {
const {trade, shipping, loading, form:{getFieldProps}, location:{query}} = this.props;
const operation = (
<HeaderOperation history={this.props.history} buttons={[{key:'rollback'}]}/>
);
const header = (<MainHeader breadcrumb={['订单管理', '订单详情', '合同物流']}
operation={operation}
title="合同物流详情"/>);
return (
......
......@@ -10,6 +10,8 @@ import {
import Layout from '../../components/Layout/Layout';
import MainHeader from '../../components/MainHeader/MainHeader';
import HeaderOperation, {DetailOperations} from '../../components/HeaderOperation/HeaderOperation';
@connect(state=>({
loading: state.trade.loading,
......@@ -38,8 +40,16 @@ export default class Item extends Component {
const styles = require('./Item.less');
const tw = 8;
const vw = 16;
const operation = (
<HeaderOperation history={this.props.history} buttons={[{key:'rollback'}]}/>
);
const header = (<MainHeader breadcrumb={['订单管理', '订单详情']}
operation={operation}
title={((item && item.title) ? item.title + ' - ' : '') + '订单详情'}/>);
return (
<Layout header={header}>
{
......
......@@ -5,6 +5,7 @@ import {Link} from 'react-router';
import {serialize, formatDateTime, tradeStatusToString} from '../../utils';
import Layout from '../../components/Layout/Layout';
import MainHeader from '../../components/MainHeader/MainHeader';
import HeaderOperation from '../../components/HeaderOperation/HeaderOperation';
const columns = [
{
......@@ -169,16 +170,11 @@ export default class List extends Component {
};
const operation = (
<div style={{textAlign:'right'}}>
<Button.Group>
<Button type="ghost" onClick={this.handleFilterVisible.bind(this)}>
<Icon type="filter"/>
</Button>
</Button.Group>
</div>
<HeaderOperation history={this.props.history} buttons={[{
key:'filter',
}]}/>
);
const header = (
<MainHeader breadcrumb={['订单管理', '订单列表']}
operation={operation}
......
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, footerFormSubmitLayout} from '../../utils';
@connect(state=>({
loading: state.user.loading,
}))
@Form.create()
export default class AddItem extends Component {
constructor(props, content) {
super(props, content);
}
handleSubmit(e) {
e.preventDefault();
const data = this.props.form.getFieldsValue();
console.log(data);
this.props.dispatch({
type: 'CREATE_USER_ITEM',
data
});
}
render = ()=> {
const {loading, form:{getFieldProps}, location:{query}} = this.props;
const operation = (
<div style={{textAlign:'right'}}>
<Button.Group>
<Button type="ghost" onClick={e=>{e.preventDefault(); this.props.history.goBack();}}>
<Icon type="rollback"/>
</Button>
</Button.Group>
</div>
);
const header = (
<MainHeader breadcrumb={['用户管理', '添加用户']}
title="添加用户"
operation={operation}
/>
);
return (
<Layout header={header}>
<Spin spinning={loading}>
<Form className="main-form" horizontal onSubmit={this.handleSubmit.bind(this)}>
<Form.Item label="用户名" help="请使用手机号" {...formItemLayout}>
<Input placeholder="用户名" {...getFieldProps('username')} />
</Form.Item>
<Form.Item label="密码" {...formItemLayout}>
<Input placeholder="密码" type="password"
{...getFieldProps('password')} />
</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'}}>
<Icon type="rollback"/>返回
</Button>
</Form.Item>
</Form>
</Spin>
</Layout>
);
}
}
......@@ -22,6 +22,7 @@ import {
import Layout from '../../components/Layout/Layout';
import MainHeader from '../../components/MainHeader/MainHeader';
import HeaderOperation, {DetailOperations} from '../../components/HeaderOperation/HeaderOperation';
import {
formItemLayout,
......@@ -97,40 +98,13 @@ export default class EditItem extends Component {
}
render() {
const {item, loading, form:{getFieldProps}, location:{query}, isEdit, authorities} = this.props;
const operation = (
<div style={{textAlign:'right'}}>
<Button.Group>
<Button type="ghost"
onClick={
e=>{
e.preventDefault();
this.props.dispatch({
type: isEdit ? 'CANCEL_UPDATE_USER' : 'UPDATE_USER'
});
}
}>
<Icon type="edit"/>
</Button>
<Button type="ghost" onClick={e=>{
e.preventDefault();
isEdit ?
this.props.dispatch({
type: 'CANCEL_UPDATE_USER'
}) :
this.props.history.goBack();
}}>
<Icon type="rollback"/>
</Button>
</Button.Group>
</div>
);
const {item, loading, form:{getFieldProps}, location:{query}, isEdit, authorities, dispatch, history} = this.props;
const header = (
<MainHeader breadcrumb={['用户管理', '用户详情']}
title={'用户详情' + (isEdit ? ' - 编辑' : '')}
operation={operation}
operation={<HeaderOperation history={history}
buttons={item && DetailOperations('USER', item.id, isEdit, dispatch)}/>}
/>
);
......@@ -176,7 +150,7 @@ export default class EditItem extends Component {
{ isEdit ?
<Checkbox.Group options={authorities}
value={this.state.authoritiesCheckedValues}
onChange={(checkedValues)=>{
onChange={(checkedValues)=> {
this.setState({
authoritiesCheckedValues: checkedValues
})
......@@ -212,7 +186,7 @@ export default class EditItem extends Component {
<Form.Item label="注册时间" {...smallFormItemLayout}>
{item.dateCreated && formatDateTime(item.dateCreated)}
</Form.Item>
<Form.Item {...footerFormSubmitLayout} style={{marginTop:30}}>
<Form.Item {...footerFormSubmitLayout} style={{marginTop: 30}}>
{
isEdit ?
<Button type="primary" onClick={this.handleSubmit.bind(this)}
......@@ -220,17 +194,17 @@ export default class EditItem extends Component {
<Icon type="save"/>保存
</Button>
:
<Button type="primary" onClick={e=>{
<Button type="primary" onClick={e=> {
e.preventDefault();
this.props.dispatch({
type:'UPDATE_USER'
type: 'UPDATE_USER'
});
}}>
<Icon type="edit"/>编辑
</Button>
}
<Button onClick={e=>{
<Button onClick={e=> {
e.preventDefault();
isEdit ?
this.props.dispatch({
......@@ -238,7 +212,7 @@ export default class EditItem extends Component {
}) :
this.props.history.goBack();
}}
style={{marginLeft:'1em'}}>
style={{marginLeft: '1em'}}>
<Icon type="rollback"/>
{isEdit ? '取消' : '返回'}
</Button>
......
......@@ -5,6 +5,7 @@ import {Link} from 'react-router';
import {serialize, formatDateTime, userStatusToString, filterFormItemStyle} from '../../utils';
import Layout from '../../components/Layout/Layout';
import MainHeader from '../../components/MainHeader/MainHeader';
import HeaderOperation from '../../components/HeaderOperation/HeaderOperation';
const columns = [
{
......@@ -60,7 +61,7 @@ const columns = [
];
@connect(state=>({
items: state.user.list,
items: state.user.items,
loading: state.user.loading,
total: state.user.total,
}))
......@@ -151,21 +152,16 @@ export default class List extends Component {
}
};
const operation = (
<div style={{textAlign:'right'}}>
<Button.Group>
<Button type="ghost" onClick={this.handleFilterVisible.bind(this)}>
<Icon type="filter"/>
</Button>
</Button.Group>
</div>
<HeaderOperation history={this.props.history} buttons={[{key:'filter'}]}/>
);
const header = (
<MainHeader breadcrumb={['用户管理', '用户列表']}
operation={operation}
title="用户列表">
title="用户列表"
operation={operation}>
{
this.state.filterVisible &&
<Form className="filterForm" inline onSubmit={this.handleFilterSubmit.bind(this)}>
......
import React, {Component, PropTypes} from 'react';
import {connect} from 'react-redux';
import {
Row,
Col,
Form,
Input,
Button,
message,
Icon,
Modal,
Spin
} from 'antd';
import Layout from '../../components/Layout/Layout';
import MainHeader from '../../components/MainHeader/MainHeader';
import HeaderOperation from '../../components/HeaderOperation/HeaderOperation';
import FooterOperation from '../../components/FooterOperation/FooterOperation';
import {
formItemLayout,
smallFormItemLayout,
footerFormSubmitLayout,
NULL,
} from '../../utils';
@connect(state=>({
loading: state.user.loading,
user: state.user,
}))
@Form.create()
export default class EditItem extends Component {
constructor() {
super(...arguments);
}
componentDidMount() {
};
componentWillReceiveProps(nextProps) {
}
handleSubmit(e) {
e.preventDefault();
const data = this.props.form.getFieldsValue();
data.username = this.props.user.username;
if (data.password && data.newPassword && data.confirmPassword) {
if (data.confirmPassword !== data.newPassword) {
message.error('新密码与重复密码不相同!');
return;
}
this.props.dispatch({
type: 'MODIFY_USER_PASSWORD',
data
});
} else {
message.error('密码不能为空!');
}
}
render() {
const {user, loading, form:{getFieldProps}, history} = this.props;
const header = (
<MainHeader breadcrumb={['用户管理', '用户详情']}
title={'修改密码'}
operation={<HeaderOperation history={history}/>}
/>
);
return (
<Layout header={header}>
<Spin spinning={loading}>
{
user &&
<Form className="main-form" horizontal onSubmit={this.handleSubmit.bind(this)}>
<Form.Item label="用户名" {...smallFormItemLayout}>
{ user.username }
</Form.Item>
<Form.Item label="原密码" {...smallFormItemLayout}>
<Input type="password" {...getFieldProps('password')} />
</Form.Item>
<Form.Item label="新密码" {...smallFormItemLayout}>
<Input type="password" {...getFieldProps('newPassword')} />
</Form.Item>
<Form.Item label="重复密码" {...smallFormItemLayout}>
<Input type="password" {...getFieldProps('confirmPassword')} />
</Form.Item>
<FooterOperation {...this.props} isEdit={true} hasCancel={false} afterButtons={
<Button onClick={(e)=> {
e.preventDefault();
this.props.history.goBack()
}} style={{marginLeft: '1em'}}>
<Icon type="rollback"/>返回
</Button>
}/>
</Form>
}
</Spin>
</Layout>
);
}
}
import React, {Component, PropTypes} from 'react';
import {connect} from 'react-redux';
import {Form, Input, Button, Checkbox, message, Spin} from 'antd';
import Layout from '../../components/Layout/Layout';
import MainHeader from '../../components/MainHeader/MainHeader';
import {formItemLayout, footerFormSubmitLayout} from '../../utils';
@connect(state=>({
loading: state.user.loading,
created: state.user.created
}))
@Form.create()
export default class Register extends Component {
componentWillReceiveProps(nextProps) {
if (nextProps.created) {
// this.props.history.replace('/login');
}
}
handleSubmit(e) {
e.preventDefault();
const data = this.props.form.getFieldsValue();
console.log(data);
this.props.dispatch({
type: 'CREATE_USER',
data
});
}
render() {
const {form:{getFieldProps}, loading} = this.props;
return (
<Layout>
<Spin spinning={loading}>
<Form className="main-form" horizontal onSubmit={this.handleSubmit.bind(this)}>
<div style={{width: 400, margin: 'auto', paddingTop: 200}}>
<Form.Item label="用户名" {...formItemLayout}>
<Input placeholder="请输入账户名" {...getFieldProps('username')} />
</Form.Item>
<Form.Item label="密码" {...formItemLayout}>
<Input type="password" placeholder="请输入密码" {...getFieldProps('password')} />
</Form.Item>
<Form.Item label="重复密码" {...formItemLayout}>
<Input type="password" placeholder="请再次输入密码" {...getFieldProps('confirmPassword')} />
</Form.Item>
<Form.Item label="昵称" {...formItemLayout}>
<Input placeholder="请输入昵称" {...getFieldProps('nick')} />
</Form.Item>
<Form.Item label="E-mail" {...formItemLayout}>
<Input placeholder="请输入E-mail" {...getFieldProps('email')} />
</Form.Item>
<Form.Item label="手机号" {...formItemLayout}>
<Input placeholder="请输入手机号" {...getFieldProps('mobile')} />
</Form.Item>
<Form.Item {...footerFormSubmitLayout}>
<Button type="primary" htmlType="submit">注册</Button>
</Form.Item>
</div>
</Form>
</Spin>
</Layout>
);
}
}
......@@ -6,6 +6,7 @@ import {serialize, formatDateTime, remittanceAuditStatusToString} from '../../ut
import Layout from '../../components/Layout/Layout';
import MainHeader from '../../components/MainHeader/MainHeader';
import HeaderOperation from '../../components/HeaderOperation/HeaderOperation';
const columns = [
{
......@@ -117,7 +118,14 @@ export default class List extends Component {
}
};
const operation = (
<HeaderOperation history={this.props.history} buttons={[{
key:'filter',
}]}/>
);
const header = (<MainHeader breadcrumb={['审核管理', '提现审核']}
operation={operation}
title="提现审核列表"/>);
return (
......
......@@ -22,6 +22,7 @@ import {
import Layout from '../../components/Layout/Layout';
import MainHeader from '../../components/MainHeader/MainHeader';
import HeaderOperation from '../../components/HeaderOperation/HeaderOperation';
import {
formatDateTime,
......@@ -74,60 +75,6 @@ export default class PassItem extends Component {
render() {
const {audit, loading, form:{getFieldProps}, location:{query}} = this.props;
//
// const {isEdit} = this.state;
//
// let title = (audit && audit.nickname ? audit.nickname + ' - ' : '');
//
// let readOnly = true;
//
// if (audit) {
// switch (audit.status) {
// case 1:
// title += '提现审核详情';
// readOnly = false;
// break;
// case 5:
// title += '审核失败';
// break;
// case 9:
// title += '审核成功';
// }
// } else {
// title += '提现审核详情';
// }
//
// const header = (<MainHeader breadcrumb={['审核管理', '提现审核','审核详情']} title={title}/>);
//
// let memo = [];
//
// if (audit) {
// if (audit.status == 1) {
// const {bankCard, balance, balanceLong, amountLong} = audit;
// if (!balance) {
// memo.push('无余额可用');
// } else if (balanceLong < amountLong) {
// memo.push('余额不足');
// }
//
// const {username, bank, bankBranch, num} = bankCard;
//
// if (!username) {
// memo.push('无持卡人信息');
// }
// if (!num) {
// memo.push('无银行卡号');
// }
// if (!bank || !bankBranch) {
// memo.push('无开户行信息');
// }
// } else {
// memo.push(audit.memo);
// }
// }
//
// memo = memo.length && memo[0] || '';
let title = (audit && audit.nickname ? audit.nickname + ' - ' : '');
......@@ -149,29 +96,38 @@ export default class PassItem extends Component {
title += '报单审核详情';
}
const operation = (
<div style={{textAlign:'right'}}>
<Button.Group>
{
audit && audit.status == 1 &&
<Button type="ghost"
onClick={e=>{e.preventDefault(); this.setState({isEdit: !this.state.isEdit})}}>
<Icon type="edit"/>
</Button>
}
<Button type="ghost" onClick={e=>{
const buttons = [{
key: 'rollback',
onClick: e=> {
e.preventDefault();
isEdit ?
this.setState({isEdit: !this.state.isEdit}) :
this.props.history.goBack();
}}>
<Icon type="rollback"/>
</Button>
</Button.Group>
</div>
}
}];
if(audit && audit.status == 1){
buttons.unshift({
key:'edit',
onClick:e=> {
e.preventDefault();
this.setState({isEdit: !this.state.isEdit})
}
});
}
const operation = (
<HeaderOperation history={this.props.history} buttons={buttons}/>
);
const header = (<MainHeader breadcrumb={['审核管理', '提现审核','审核详情']} title={title} operation={operation}/>);
const header = (
<MainHeader breadcrumb={['审核管理', '提现审核','审核详情']}
title={title}
operation={operation}
/>
);
return (
......
......@@ -12,7 +12,6 @@ export Contract from './Trade/Contract';
export TradeAddItem from './Trade/AddItem';
export AnnouncementList from './Announcement/List';
export AnnouncementEditItem from './Announcement/EditItem';
export AnnouncementAddItem from './Announcement/AddItem';
export RemittanceAuditList from './Remittance/List';
export RemittanceAuditPassItem from './Remittance/PassItem';
export WithDrawList from './Withdraw/List';
......@@ -21,11 +20,13 @@ export CustomMessageList from './CustomMessage/List';
export CustomMessageAddItem from './CustomMessage/AddItem';
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';
export ResourceList from './Resource/List';
export ResourceItem from './Resource/EditItem';
export AuthorityList from './Authority/List';
export AuthorityItem from './Authority/EditItem';
export ModifyPassword from './Users/ModifyPassword';
export Register from './Users/Register';
......@@ -141,10 +141,12 @@
}
}
.tac {
text-align: center !important;
}
.tac {
text-align: center !important;
}
body {
......
......@@ -17,7 +17,7 @@ const announcement = handleActions({
return {...state, loading: false, items: action.items, total: action.total};
},
['FETCH_ANNOUNCEMENT_LIST_FAILED'](state, action) {
return {...state, err: action.err, loading: false};
return {...state, err: action.err, loading: false, items: [], total: 0};
},
['FETCH_ANNOUNCEMENT_ITEM'](state){
return {...state, loading: true}
......@@ -26,7 +26,7 @@ const announcement = handleActions({
return {...state, loading: false, item: action.item}
},
['FETCH_ANNOUNCEMENT_ITEM_FAILED'](state, action){
return {...state, err: action.err, loading: false}
return {...state, err: action.err, loading: false, item: null}
},
['CREATE_ANNOUNCEMENT_ITEM'](state){
return {...state, loading: true}
......@@ -35,7 +35,7 @@ const announcement = handleActions({
return {...state, loading: false, item: action.item}
},
['CREATE_ANNOUNCEMENT_ITEM_FAILED'](state, action){
return {...state, err: action.err, loading: false}
return {...state, err: action.err, loading: false, item: null}
},
['UPDATE_ANNOUNCEMENT_START'](state){
return {...state, isEdit: true}
......@@ -47,10 +47,10 @@ const announcement = handleActions({
return {...state, loading: true}
},
['UPDATE_ANNOUNCEMENT_ITEM_SUCCESS'](state, action){
return {...state, loading: false, isEdit:false, item: {...state.item, ...action.item}}
return {...state, loading: false, isEdit: false, item: {...state.item, ...action.item}}
},
['UPDATE_ANNOUNCEMENT_ITEM_FAILED'](state, action){
return {...state, err: action.err, loading: false, isEdit:false}
return {...state, err: action.err, loading: false, isEdit: false, item: null}
},
}, initState);
......
......@@ -3,13 +3,15 @@ import {combineReducer} from 'redux';
const authority = handleActions({
['FETCH_AUTHORITY_LIST'](state) {
delete state.removed;
delete state.item;
return {...state, loading: true};
},
['FETCH_AUTHORITY_LIST_SUCCESS'](state, action) {
return {...state, loading: false, items: action.items, total: action.total};
},
['FETCH_AUTHORITY_LIST_FAILED'](state, action) {
return {...state, err: action.err, loading: false};
return {...state, err: action.err, loading: false, items:[], total:0};
},
['FETCH_AUTHORITY_ITEM'](state) {
return {...state, loading: true};
......@@ -18,7 +20,28 @@ const authority = handleActions({
return {...state, loading: false, item: action.item};
},
['FETCH_AUTHORITY_ITEM_FAILED'](state, action) {
return {...state, err: action.err, loading: false};
return {...state, err: action.err, loading: false, item:null};
},
['CREATE_AUTHORITY_ITEM'](state){
return {...state, loading: true}
},
['CREATE_AUTHORITY_ITEM_SUCCESS'](state, action){
return {...state, loading: false, item: action.item}
},
['CREATE_AUTHORITY_ITEM_FAILED'](state, action){
return {...state, err: action.err, loading: false, item:null}
},
['DELETE_AUTHORITY_ITEM'](state){
return {...state, loading: true}
},
['DELETE_AUTHORITY_ITEM_SUCCESS'](state, action){
state.items = state.items.filter(item=>item.name!=action.removed);
return {...state, loading: false, removed:action.removed }
},
['DELETE_AUTHORITY_ITEM_FAILED'](state, action){
return {...state, err: action.err, loading: false}
},
['UPDATE_AUTHORITY_START'](state){
......@@ -35,13 +58,13 @@ const authority = handleActions({
if (action.item.permissions) {
action.item.permissions = JSON.parse(action.item.permissions)
}
}catch(err){
} catch (err) {
}
return {...state, loading: false, item: {...state.item, ...action.item}}
return {...state, loading: false, item: {...state.item, ...action.item}, isEdit: false}
},
['UPDATE_AUTHORITY_ITEM_FAILED'](state, action){
return {...state, err: action.err, loading: false}
return {...state, err: action.err, loading: false, isEdit: false}
},
}, {
items: [],
......
......@@ -6,16 +6,16 @@ const contract = handleActions({
return {...state, loading: true}
},
['FETCH_CONTRACT_ITEM_SUCCESS'](state, action){
return {...state, loading: false, trade:action.trade, shipping:action.shipping}
return {...state, loading: false, trade: action.trade, shipping: action.shipping}
},
['FETCH_CONTRACT_ITEM_FAILED'](state, action){
return {...state, err: action.err, loading: false}
return {...state, err: action.err, loading: false, trade: null, shipping: null}
},
['UPDATE_CONTRACT_ITEM'](state){
return {...state, loading: true}
},
['UPDATE_CONTRACT_ITEM_SUCCESS'](state, action){
return {...state, loading: false, shipping:action.shipping}
return {...state, loading: false, shipping: action.shipping}
},
['UPDATE_CONTRACT_ITEM_FAILED'](state, action){
return {...state, err: action.err, loading: false}
......
......@@ -9,7 +9,7 @@ const message = handleActions({
return {...state, loading: false, items: action.items, total: action.total};
},
['FETCH_MESSAGE_LIST_FAILED'](state, action) {
return {...state, err: action.err, loading: false};
return {...state, err: action.err, loading: false, items: [], total: 0};
},
['FETCH_MESSAGE_ITEM'](state){
return {...state, loading: true}
......@@ -18,7 +18,7 @@ const message = handleActions({
return {...state, loading: false, item: action.item}
},
['FETCH_MESSAGE_ITEM_FAILED'](state, action){
return {...state, err: action.err, loading: false}
return {...state, err: action.err, loading: false, item: null}
},
['CREATE_MESSAGE_ITEM'](state){
return {...state, loading: true}
......@@ -27,7 +27,7 @@ const message = handleActions({
return {...state, loading: false, item: action.item}
},
['CREATE_MESSAGE_ITEM_FAILED'](state, action){
return {...state, err: action.err, loading: false}
return {...state, err: action.err, loading: false, item: null}
}
}, {
items: [],
......
......@@ -9,7 +9,7 @@ const product = handleActions({
return {...state, loading: false, items: action.items, total: action.total};
},
['FETCH_PRODUCT_LIST_FAILED'](state, action) {
return {...state, err: action.err, loading: false,};
return {...state, err: action.err, loading: false, items: [], total: 0};
},
['FETCH_PRODUCT_CATES'](state){
return {...state, loading: true};
......@@ -18,7 +18,7 @@ const product = handleActions({
return {...state, loading: false, cates: action.cates};
},
['FETCH_PRODUCT_CATES_FAILED'](state, action){
return {...state, err: action.err, loading: false};
return {...state, err: action.err, loading: false, cates: []};
},
['FETCH_PRODUCT_ITEM'](state){
return {...state, loading: true}
......@@ -27,7 +27,7 @@ const product = handleActions({
return {...state, loading: false, item: action.item}
},
['FETCH_PRODUCT_ITEM_FAILED'](state, action){
return {...state, err: action.err, loading: false}
return {...state, err: action.err, loading: false, item: null}
},
......@@ -41,29 +41,29 @@ const product = handleActions({
return {...state, loading: true};
},
['UPDATE_PRODUCT_ITEM_SUCCESS'](state, action){
if(action.item && action.item.commissionAlg && typeof action.item.commissionAlg === 'string'){
try{
if (action.item && action.item.commissionAlg && typeof action.item.commissionAlg === 'string') {
try {
action.item.commissionAlg = JSON.parse(action.item.commissionAlg);
}catch(err){
} catch (err) {
console.log('UPDATE_PRODUCT_ITEM_SUCCESS commissionAlg Error:', action.item.commissionAlg);
}
}
if(action.item && action.item.elements && typeof action.item.elements === 'string'){
if (action.item && action.item.elements && typeof action.item.elements === 'string') {
try {
action.item.elements = JSON.parse(action.item.elements);
}catch(err){
} catch (err) {
console.log('UPDATE_PRODUCT_ITEM_SUCCESS elements Error:', action.item.elements);
}
}
if(action.item && action.item.staffs && typeof action.item.staffs === 'string'){
try{
if (action.item && action.item.staffs && typeof action.item.staffs === 'string') {
try {
action.item.staffs = JSON.parse(action.item.staffs);
}catch(err){
} catch (err) {
console.log('UPDATE_PRODUCT_ITEM_SUCCESS staffs Error:', action.item.staffs);
}
}
return {...state, loading: false, item:{...state.item, ...action.item}, isEdit: false};
return {...state, loading: false, item: {...state.item, ...action.item}, isEdit: false};
},
['UPDATE_PRODUCT_ITEM_FAILED'](state, action){
return {...state, loading: false, err: action.err, isEdit: false};
......@@ -77,7 +77,7 @@ const product = handleActions({
return {...state, item: action.item, loading: false};
},
['CREATE_PRODUCT_FAILED'](state, action){
return {...state, loading: false, err: action.err};
return {...state, loading: false, err: action.err, item: null};
}
}, {
items: [],
......
......@@ -9,7 +9,7 @@ const remittance = handleActions({
return {...state, loading: false, audits: action.items, total: action.total};
},
['FETCH_REMITTANCE_LIST_FAILED'](state, action) {
return {...state, err: action.err, loading: false};
return {...state, err: action.err, loading: false, audits: [], total: 0};
},
['FETCH_REMITTANCE_ITEM'](state) {
return {...state, loading: true,};
......@@ -18,19 +18,19 @@ const remittance = handleActions({
return {...state, loading: false, audit: action.item};
},
['FETCH_REMITTANCE_ITEM_FAILED'](state, action) {
return {...state, err: action.err, loading: false};
return {...state, err: action.err, loading: false, audit: null};
},
['PASS_REMITTANCE_ITEM'](state){
return {...state, loading: true};
},
['PASS_REMITTANCE_ITEM_SUCCESS'](state, action){
return {...state, loading: false, audit: {...state.audit, ...action.item}};
return {...state, loading: false, audit: {...state.audit, ...action.data}};
},
['PASS_REMITTANCE_ITEM_FAILED'](state, action){
return {...state, loading: false, err: action.err};
}
}, {
drawMoneys:[],
drawMoneys: [],
audits: [],
loading: false,
});
......
......@@ -9,7 +9,7 @@ const resources = handleActions({
return {...state, loading: false, items: action.items, total: action.total};
},
['FETCH_RESOURCE_LIST_FAILED'](state, action) {
return {...state, err: action.err, loading: false};
return {...state, err: action.err, loading: false, items: [], total: 0};
},
['FETCH_RESOURCE_ITEM'](state) {
return {...state, loading: true};
......@@ -18,7 +18,7 @@ const resources = handleActions({
return {...state, loading: false, item: action.item};
},
['FETCH_RESOURCE_ITEM_FAILED'](state, action) {
return {...state, err: action.err, loading: false};
return {...state, err: action.err, loading: false, item: null};
},
['UPDATE_RESOURCE_START'](state){
......@@ -31,10 +31,10 @@ const resources = handleActions({
return {...state, loading: true}
},
['UPDATE_RESOURCE_ITEM_SUCCESS'](state, action){
return {...state, loading: false, item: {...state.item, ...action.item}}
return {...state, loading: false, item: {...state.item, ...action.item}, isEdit: false}
},
['UPDATE_RESOURCE_ITEM_FAILED'](state, action){
return {...state, err: action.err, loading: false}
return {...state, err: action.err, loading: false, isEdit: false}
},
}, {
items: [],
......
......@@ -17,7 +17,7 @@ const trade = handleActions({
return {...state, loading: false, items: action.items, total: action.total};
},
['FETCH_TRADE_LIST_FAILED'](state, action) {
return {...state, err: action.err, loading: false};
return {...state, err: action.err, loading: false, items:[], total:0};
},
['FETCH_TRADE_ITEM'](state){
return {...state, loading: true}
......@@ -26,7 +26,7 @@ const trade = handleActions({
return {...state, loading: false, item: action.item}
},
['FETCH_TRADE_ITEM_FAILED'](state, action){
return {...state, err: action.err, loading: false}
return {...state, err: action.err, loading: false, item:null}
},
['CREATE_TRADE_ITEM'](state){
return {...state, loading: true}
......
......@@ -4,6 +4,11 @@ import {combineReducer} from 'redux';
let _user = sessionStorage.getItem('user');
try {
_user = JSON.parse(_user);
if (_user && Date.now() - _user.time < 24 * 3600000) {
_user = _user.data;
} else {
_user = {};
}
} catch (ex) {
_user = {};
}
......@@ -13,7 +18,6 @@ const user = handleActions({
return {...state, loading: true};
},
['LOGIN_SUCCESS'](state, action) {
sessionStorage.setItem('user', JSON.stringify(action.user));
return {...state, loading: false, ...action.user};
},
['LOGIN_ERROR'](state, action) {
......@@ -23,13 +27,13 @@ const user = handleActions({
return {...state, auth: {}, loading: false};
},
['CREATE_USER_ITEM'](state){
['CREATE_USER'](state){
return {...state, loading: true};
},
['CREATE_USER_ITEM_SUCCESS'](state, action){
return {...state, loading: false};
['CREATE_USER_SUCCESS'](state, action){
return {...state, loading: false, created: action.result.id};
},
['CREATE_USER_ITEM_FAILED'](state, action){
['CREATE_USER_FAILED'](state, action){
return {...state, loading: false, err: action.err};
},
......@@ -37,20 +41,20 @@ const user = handleActions({
return {...state, loading: true};
},
['FETCH_USER_LIST_SUCCESS'](state, action){
return {...state, loading: false, ...action.result};
return {...state, loading: false, items: action.items, total: action.total};
},
['FETCH_USER_LIST_FAILED'](state, action){
return {...state, loading: false, err: action.err};
return {...state, loading: false, err: action.err, items: [], total: 0};
},
['FETCH_USER_ITEM'](state){
return {...state, loading: true};
},
['FETCH_USER_ITEM_SUCCESS'](state, action){
return {...state, loading: false, item: action.result};
return {...state, loading: false, item: action.item};
},
['FETCH_USER_ITEM_FAILED'](state, action){
return {...state, loading: false, err: action.err};
return {...state, loading: false, err: action.err, item: null};
},
['UPDATE_USER_START'](state){
......@@ -68,6 +72,15 @@ const user = handleActions({
['UPDATE_USER_ITEM_FAILED'](state, action){
return {...state, loading: false, err: action.err, isEdit: false};
},
['MODIFY_USER_PASSWORD'](state){
return {...state, loading: true};
},
['MODIFY_USER_PASSWORD_SUCCESS'](state){
return {...state, loading: false};
},
['MODIFY_USER_PASSWORD_FAILED'](state, action){
return {...state, loading: false, err: action.err};
},
}, {
..._user,
......
......@@ -9,7 +9,7 @@ const withdraw = handleActions({
return {...state, loading: false, audits: action.items, total: action.total};
},
['FETCH_WITHDRAW_LIST_FAILED'](state, action) {
return {...state, err: action.err, loading: false};
return {...state, err: action.err, loading: false, audits: [], total: 0};
},
['FETCH_WITHDRAW_ITEM'](state) {
return {...state, loading: true};
......@@ -18,14 +18,14 @@ const withdraw = handleActions({
return {...state, loading: false, audit: action.item};
},
['FETCH_WITHDRAW_ITEM_FAILED'](state, action) {
return {...state, err: action.err, loading: false};
return {...state, err: action.err, loading: false, audit: null};
},
['PASS_WITHDRAW_ITEM'](state){
return {...state, loading: true};
},
['PASS_WITHDRAW_ITEM_SUCCESS'](state, action){
const audit = {...state.audit, status: action.status};
if(action.status == 5){
if (action.status == 5) {
audit.memo = action.memo;
}
return {...state, loading: false, audit};
......
import React, {PropTypes, Component} from 'react';
import {Route, IndexRoute, Link} from 'react-router';
import {
Home,
NotFound,
Login,
App,
ProductList,
ProductAddItem,
ProductEditItem,
TradeList,
TradeItem,
Commission,
Contract,
TradeAddItem,
AnnouncementList,
AnnouncementEditItem,
AnnouncementAddItem,
RemittanceAuditList,
RemittanceAuditPassItem,
WithDrawList,
PassWithDrawItem,
CustomMessageList,
CustomMessageAddItem,
CustomMessageItem,
BaseUpload,
UsersAddItem,
UsersList,
UsersItem,
ResourceList,
ResourceItem,
AuthorityList,
AuthorityItem
} from '../containers/index';
import * as Containers from '../containers/index';
export default (store)=> {
const requireAuth = (nextState, replace, cb) => {
......@@ -43,61 +12,65 @@ export default (store)=> {
};
return (
<Route path="/">
<Route onEnter={requireAuth} component={App}>
<IndexRoute component={Home}/>
<Route onEnter={requireAuth} component={Containers.App}>
<IndexRoute component={Containers.Home}/>
<Route path="products">
<IndexRoute component={ProductList}/>
<Route path="create" component={ProductAddItem}/>
<Route path=":id" component={ProductEditItem}/>
<IndexRoute component={Containers.ProductList}/>
<Route path="create" component={Containers.ProductAddItem}/>
<Route path=":id" component={Containers.ProductEditItem}/>
</Route>
<Route path="trades">
<IndexRoute component={TradeList}/>
<Route path="create" component={TradeAddItem}/>
<Route path=":id" component={TradeItem}/>
<Route path="commission/:id" component={Commission}/>
<Route path="contract/:id" component={Contract}/>
<IndexRoute component={Containers.TradeList}/>
<Route path="create" component={Containers.TradeAddItem}/>
<Route path=":id" component={Containers.TradeItem}/>
<Route path="commission/:id" component={Containers.Commission}/>
<Route path="contract/:id" component={Containers.Contract}/>
</Route>
<Route path="announcement">
<IndexRoute component={AnnouncementList}/>
<Route path="create" component={AnnouncementAddItem}/>
<Route path=":id" component={AnnouncementEditItem}/>
<IndexRoute component={Containers.AnnouncementList}/>
<Route path="create" component={Containers.AnnouncementEditItem}/>
<Route path=":id" component={Containers.AnnouncementEditItem}/>
</Route>
<Route path="remittance">
<Route path="audits">
<IndexRoute component={RemittanceAuditList}/>
<Route path=":id" component={RemittanceAuditPassItem}/>
<IndexRoute component={Containers.RemittanceAuditList}/>
<Route path=":id" component={Containers.RemittanceAuditPassItem}/>
</Route>
</Route>
<Route path="withdraw">
<Route path="audits">
<IndexRoute component={WithDrawList}/>
<Route path=":id" component={PassWithDrawItem}/>
<IndexRoute component={Containers.WithDrawList}/>
<Route path=":id" component={Containers.PassWithDrawItem}/>
</Route>
</Route>
<Route path="customMessages">
<IndexRoute component={CustomMessageList}/>
<Route path="create" component={CustomMessageAddItem}/>
<Route path=":id" component={CustomMessageItem}/>
<IndexRoute component={Containers.CustomMessageList}/>
<Route path="create" component={Containers.CustomMessageAddItem}/>
<Route path=":id" component={Containers.CustomMessageItem}/>
</Route>
<Route path="upload" component={BaseUpload}/>
<Route path="upload" component={Containers.BaseUpload}/>
<Route path="admin">
<Route path="users">
<IndexRoute component={UsersList}/>
<Route path="create" component={UsersAddItem}/>
<Route path=":id" component={UsersItem}/>
<IndexRoute component={Containers.UsersList}/>
<Route path=":id" component={Containers.UsersItem}/>
</Route>
<Route path="resources">
<IndexRoute component={ResourceList}/>
<Route path=":id" component={ResourceItem}/>
<IndexRoute component={Containers.ResourceList}/>
<Route path=":id" component={Containers.ResourceItem}/>
</Route>
<Route path="authorities">
<IndexRoute component={AuthorityList}/>
<Route path=":id" component={AuthorityItem}/>
<IndexRoute component={Containers.AuthorityList}/>
<Route path="create" component={Containers.AuthorityItem}/>
<Route path=":id" component={Containers.AuthorityItem}/>
</Route>
</Route>
<Route path="my">
<Route path="modifyPassword" component={Containers.ModifyPassword} />
</Route>
<Route path="/login" component={Login}/>
<Route path="*" component={NotFound}/>
</Route>
<Route path="/login" component={Containers.Login}/>
<Route path="/register" component={Containers.Register} />
<Route path="*" component={Containers.NotFound}/>
</Route>
);
};
......
......@@ -2,16 +2,17 @@ import {takeLatest} from 'redux-saga';
import {take, call, put, fork, cancel, select, race} from 'redux-saga/effects';
import {message} from 'antd';
export function index(id, api){
return function* (query) {
export function index(id, api) {
return function*(query) {
try {
const result = yield call(api, query);
const {list, total} = yield call(api, query);
yield put({
type: 'FETCH_' + id + '_LIST_SUCCESS',
result
items: list,
total
});
} catch (err) {
console.log(err);
console.error(err);
message.error(err);
yield put({
type: 'FETCH_' + id + '_LIST_FAILED',
......@@ -21,7 +22,7 @@ export function index(id, api){
}
}
export function watchIndex(id, api){
export function watchIndex(id, api) {
return function*() {
while (true) {
const {query} = yield take('FETCH_' + id + '_LIST');
......@@ -33,13 +34,13 @@ export function watchIndex(id, api){
export function show(rid, api) {
return function*(id) {
try {
const result = yield call(api, id);
const item = yield call(api, id);
yield put({
type: 'FETCH_' + rid + '_ITEM_SUCCESS',
result
item
});
} catch (err) {
console.log(err);
console.error(err);
message.error(err);
yield put({
type: 'FETCH_' + rid + '_ITEM_FAILED',
......@@ -61,13 +62,13 @@ export function watchShow(rid, api) {
export function create(id, api) {
return function*(data) {
try {
const result = yield call(api, data);
const item = yield call(api, data);
yield put({
type: 'CREATE_' + id + '_ITEM_SUCCESS',
result
item: {...data, ...item, dateCreated: Date.now()}
});
} catch (err) {
console.log(err);
console.error(err);
message.error(err);
yield put({
type: 'CREATE_' + id + '_ITEM_FAILED',
......@@ -80,63 +81,23 @@ export function create(id, api) {
export function watchCreate(id, api) {
return function*() {
while (true) {
const {data} = yield take('CREATE_' + id + '_ITEM');
yield fork(create(id, api), data);
const {item} = yield take('CREATE_' + id + '_ITEM');
yield fork(create(id, api), item);
}
}
}
/*
export default class RESTful {
constructor(id) {
this.id = id;
}
create() {
const {api, id} = this;
return function*(data) {
try {
const result = yield call(api.create, data);
yield put({
type: 'CREATE_' + id + '_ITEM_SUCCESS',
result
});
} catch (err) {
console.log(err);
message.error(err);
yield put({
type: 'CREATE_' + id + '_ITEM_FAILED',
err
});
}
}
}
watchCreate() {
const self = this;
return function*() {
while (true) {
const {data} = yield take('CREATE_' + self.id + '_ITEM');
yield fork(self.create(), data);
}
}
}
update() {
const {api, id} = this;
export function update(id, api) {
return function*(data) {
try {
yield call(api.update, data);
yield call(api, data);
message.success('修改成功!');
yield put({
type: 'UPDATE_' + id + '_ITEM_SUCCESS',
item: data
});
} catch (err) {
console.log(err);
console.error(err);
message.error(err);
yield put({
type: 'UPDATE_' + id + '_ITEM_FAILED',
......@@ -144,161 +105,96 @@ export default class RESTful {
});
}
}
}
}
watchUpdate() {
const self = this;
export function watchEdit(id, api) {
return function*() {
while (true) {
yield take('UPDATE_' + self.id);
yield take('UPDATE_' + id);
yield put({
type: 'UPDATE_' + self.id + '_START'
type: 'UPDATE_' + id + '_START'
});
const {data} = yield race({
data: take('UPDATE_' + self.id + '_ITEM'),
canceled: take('CANCEL_UPDATE_' + self.id)
data: take('UPDATE_' + id + '_ITEM'),
canceled: take('CANCEL_UPDATE_' + id)
});
if (data && data.item) {
yield fork(self.update(), data.item);
}
yield fork(update(id, api), data.item);
} else {
yield put({
type: 'UPDATE_' + self.id + '_END'
type: 'UPDATE_' + id + '_END'
});
}
}
}
}
delete() {
const self = this;
const {api} = this;
export function watchUpdate(id, api) {
return function*() {
while (true) {
const {item} = yield take('UPDATE_' + id + '_ITEM');
yield fork(update(id, api), item);
}
}
}
export function deleteItem(rid, api) {
return function*(id) {
try {
const result = yield call(api.show, id);
yield call(api, id);
message.success('删除成功!');
yield put({
type: 'DELETE_' + self.id + '_ITEM_SUCCESS',
result
type: 'DELETE_' + rid + '_ITEM_SUCCESS',
removed: id,
});
} catch (err) {
console.log(err);
console.error(err);
message.error(err);
yield put({
type: 'DELETE_' + self.id + '_ITEM_FAILED',
type: 'DELETE_' + rid + '_ITEM_FAILED',
err
});
}
}
}
}
watchDelete() {
const self = this;
export function watchDelete(rid, api) {
return function*() {
while (true) {
const {id} = yield take('DELETE_' + self.id + '_ITEM');
yield fork(self.delete(), id);
}
const {id} = yield take('DELETE_' + rid + '_ITEM');
yield fork(deleteItem(rid, api), id);
}
}
}
patch() {
const {api, id} = this;
export function invoke(command, api, msg = '') {
return function*(data) {
try {
yield call(api.update, data);
message.success('操作成功!');
const result = yield call(api, data);
message.success(msg + '成功!');
yield put({
type: 'PATCH_' + id + '_ITEM_SUCCESS',
item: data
type: command + '_SUCCESS',
result,
data
});
} catch (err) {
console.log(err);
console.error(msg, err);
message.error(err);
yield put({
type: 'PATCH_' + id + '_ITEM_FAILED',
err
type: command + '_FAILED',
err,
data
});
}
}
}
}
watchPatch() {
const self = this;
export function watch(command, api, msg = '') {
return function*() {
while (true) {
const {id} = yield take('PATCH_' + self.id + '_ITEM');
yield fork(self.patch(), id);
}
}
}
watch() {
const self = this;
const mask = this.mask;
const tasks = [
self.watchIndex,
self.watchCreate,
//savenull,
self.watchShow,
//editnull,
self.watchUpdate,
self.watchDelete,
self.watchPatch
];
return function*() {
tasks.forEach((task, index)=> {
const mi = 1 << index;
if (task && ((mask & mi ) === mi)) {
yield fork(task());
}
});
}
}
actions() {
const loadingFn = function (state) {
return {...state, loading: true};
};
const failedFn = function (state, action) {
return {...state, loading: false, err: action.err}
};
const editStartFn = function (state) {
return {...state, isEdit: true}
};
const editEndFn = function (state) {
return {...state, isEdit: false};
};
const itemsFn = function (state, action) {
return {...state, loading: false, items: action.items, total: action.total}
};
const itemFn = function (state, action) {
return {...state, loading: false, item: {...state.item, ...action.item}}
};
const id = this.id;
return {
['INDEX_' + id ]: loadingFn,
['INDEX_' + id + '_SUCCESS']: itemsFn,
['INDEX_' + id + '_FAILED']: failedFn,
['SHOW_' + id]: loadingFn,
['SHOW_' + id + '_SUCCESS']: itemFn,
['SHOW_' + id + '_FAILED']: failedFn,
['CREATE_' + id]: loadingFn,
['CREATE_' + id + '_SUCCESS']: itemFn,
['CREATE_' + id + '_FAILED']: failedFn,
['UPDATE_' + id]: loadingFn,
['UPDATE_' + id + '_SUCCESS']: itemFn,
['UPDATE_' + id + '_FAILED']: failedFn,
['ENTER_EDIT' + id]: editStartFn,
['EXIT_EDIT_' + id]: editEndFn,
['DELETE_' + id]: loadingFn,
['DELETE_' + id + '_SUCCESS']: itemFn,
['DELETE_' + id + '_FAILED']: failedFn,
['PATCH_' + id]: loadingFn,
['PATCH_' + id + '_SUCCESS']: itemFn,
['PATCH_' + id + '_FAILED']: failedFn,
const {data} = yield take(command);
yield fork(invoke(command, api, msg), data);
}
}
}
*/
......@@ -2,132 +2,13 @@ import {takeLatest} from 'redux-saga';
import {take, call, put, fork, cancel, select, race} from 'redux-saga/effects';
import {fetchList, fetchItem, createItem, updateItem} from '../services/announcement';
import {message} from 'antd';
function* getList(query) {
try {
const {total, list} = yield call(fetchList, query);
yield put({
type: 'FETCH_ANNOUNCEMENT_LIST_SUCCESS',
total,
items: list
});
} catch (err) {
console.log(err);
message.error(err);
yield put({
type: 'FETCH_ANNOUNCEMENT_LIST_FAILED',
err,
});
}
}
function* watchList() {
while (true) {
const {query} = yield take('FETCH_ANNOUNCEMENT_LIST');
yield fork(getList, query);
}
}
function* getItem(id) {
try {
const item = yield call(fetchItem, id);
yield put({
type: 'FETCH_ANNOUNCEMENT_ITEM_SUCCESS',
item
});
} catch (err) {
console.log(err);
message.error(err);
yield put({
type: 'FETCH_ANNOUNCEMENT_ITEM_FAILED',
err
});
}
}
function* watchItem() {
while (true) {
const {id} = yield take('FETCH_ANNOUNCEMENT_ITEM');
yield fork(getItem, id);
}
}
function* addItem(data) {
try{
const item = yield call(createItem, data);
message.success('创建成功!');
yield put({
type: 'CREATE_ANNOUNCEMENT_ITEM_SUCCESS',
item: {...item, ...data}
});
}catch(err){
console.log(err);
message.error(err);
yield put({
type:'CREATE_ANNOUNCEMENT_ITEM_FAILED',
err
});
}
}
function* watchAdd() {
while (true) {
const {data} = yield take('CREATE_ANNOUNCEMENT_ITEM');
yield fork(addItem, data);
}
}
function* editItem(item) {
try{
yield call(updateItem, item);
message.success('修改成功!');
yield put({
type: 'UPDATE_ANNOUNCEMENT_ITEM_SUCCESS',
item
});
}catch(err){
console.log(err);
message.error(err);
yield put({
type:'UPDATE_ANNOUNCEMENT_ITEM_FAILED',
err
});
}
}
function* watchEdit() {
while (true) {
yield take('UPDATE_ANNOUNCEMENT');
yield put({
type: 'UPDATE_ANNOUNCEMENT_START'
});
const {data} = yield race({
data: take('UPDATE_ANNOUNCEMENT_ITEM'),
canceled: take('CANCEL_UPDATE_ANNOUNCEMENT')
});
if (data && data.item) {
yield fork(editItem, data.item);
}else{
yield put({
type: 'UPDATE_ANNOUNCEMENT_END'
});
}
}
}
function* watchSwidth() {
while(true){
const {item} = yield take('UPDATE_ANNOUNCEMENT_ITEM');
yield fork(editItem, item);
}
}
import {watchIndex, watchShow, watchCreate, watchUpdate, watchEdit} from './RESTful';
export default function*() {
yield fork(watchList);
yield fork(watchItem);
yield fork(watchAdd);
yield fork(watchEdit);
yield fork(watchSwidth);
const ID = 'ANNOUNCEMENT';
yield fork(watchCreate(ID, createItem));
yield fork(watchIndex(ID, fetchList));
yield fork(watchShow(ID, fetchItem));
yield fork(watchEdit(ID, updateItem));
yield fork(watchUpdate(ID, updateItem));
}
import {takeLatest} from 'redux-saga';
import {take, call, put, fork, cancel, select, race} from 'redux-saga/effects';
import { fetchList, fetchItem, updateItem } from '../services/admin/authority';
import { fetchList, fetchItem, updateItem, createItem, deleteItem } from '../services/admin/authority';
import {message} from 'antd';
function* getList(query) {
try {
const {total, list} = yield call(fetchList, query);
yield put({
type: 'FETCH_AUTHORITY_LIST_SUCCESS',
total,
items: list
});
} catch (err) {
console.log(err);
message.error(err);
yield put({
type: 'FETCH_AUTHORITY_LIST_FAILED',
err,
});
}
}
function* watchList() {
while (true) {
const {query} = yield take('FETCH_AUTHORITY_LIST');
yield fork(getList, query);
}
}
function* getItem(id) {
try {
const item = yield call(fetchItem, id);
yield put({
type: 'FETCH_AUTHORITY_ITEM_SUCCESS',
item
});
} catch (err) {
console.log(err);
message.error(err);
yield put({
type: 'FETCH_AUTHORITY_ITEM_FAILED',
err
});
}
}
function* watchItem() {
while (true) {
const {id} = yield take('FETCH_AUTHORITY_ITEM');
yield fork(getItem, id);
}
}
function* editItem(data) {
try{
yield call(updateItem, data);
message.success('修改成功!');
yield put({
type: 'UPDATE_AUTHORITY_ITEM_SUCCESS',
item: data
});
}catch(err){
console.log(err);
message.error(err);
yield put({
type:'UPDATE_AUTHORITY_ITEM_FAILED',
err
});
}
}
function* watchEdit() {
while (true) {
yield take('UPDATE_AUTHORITY');
yield put({
type: 'UPDATE_AUTHORITY_START'
});
const {data} = yield race({
data: take('UPDATE_AUTHORITY_ITEM'),
canceled: take('CANCEL_UPDATE_AUTHORITY')
});
if (data && data.item) {
yield fork(editItem, data.item);
}
yield put({
type: 'UPDATE_AUTHORITY_END'
});
}
}
import {watchIndex, watchShow, watchCreate, watchUpdate, watchEdit, watchDelete} from './RESTful';
export default function*() {
yield fork(watchList);
yield fork(watchItem);
yield fork(watchEdit);
const ID = 'AUTHORITY';
yield fork(watchCreate(ID, createItem));
yield fork(watchIndex(ID, fetchList));
yield fork(watchShow(ID, fetchItem));
yield fork(watchEdit(ID, updateItem));
yield fork(watchDelete(ID, deleteItem));
}
......@@ -3,57 +3,65 @@ import {take, call, put, fork, cancel, select} from 'redux-saga/effects';
import {fetchItem, updateItem} from '../services/contract';
import {message} from 'antd';
function* getItem(id) {
try {
const {trade, shipping} = yield call(fetchItem, id);
yield put({
type: 'FETCH_CONTRACT_ITEM_SUCCESS',
trade,
shipping
});
} catch (err) {
console.log(err);
message.error(err);
yield put({
type: 'FETCH_CONTRACT_ITEM_FAILED',
err,
});
}
}
function* watchItem() {
while (true) {
const {id} = yield take('FETCH_CONTRACT_ITEM');
yield fork(getItem, id);
}
}
function* editItem(data) {
try{
yield call(updateItem, data);
message.success('修改成功!');
yield put({
type: 'UPDATE_CONTRACT_ITEM_SUCCESS'
});
}catch(err){
console.log(err);
message.error(err);
yield put({
type:'UPDATE_CONTRACT_ITEM_FAILED',
err
});
}
}
function* watchEdit() {
while (true) {
const {data} = yield take('UPDATE_CONTRACT_ITEM');
yield fork(editItem, data);
}
}
import {watchIndex, watchShow, watchCreate, watchUpdate, watchEdit} from './RESTful';
export default function*() {
yield fork(watchItem);
yield fork(watchEdit);
const ID = 'CONTRACT';
yield fork(watchShow(ID, fetchItem));
yield fork(watchUpdate(ID, updateItem));
}
//
// function* getItem(id) {
// try {
// const {trade, shipping} = yield call(fetchItem, id);
// yield put({
// type: 'FETCH_CONTRACT_ITEM_SUCCESS',
// trade,
// shipping
// });
// } catch (err) {
// console.log(err);
// message.error(err);
// yield put({
// type: 'FETCH_CONTRACT_ITEM_FAILED',
// err,
// });
// }
// }
//
// function* watchItem() {
// while (true) {
// const {id} = yield take('FETCH_CONTRACT_ITEM');
// yield fork(getItem, id);
// }
// }
//
// function* editItem(data) {
// try{
// yield call(updateItem, data);
// message.success('修改成功!');
// yield put({
// type: 'UPDATE_CONTRACT_ITEM_SUCCESS'
// });
// }catch(err){
// console.log(err);
// message.error(err);
// yield put({
// type:'UPDATE_CONTRACT_ITEM_FAILED',
// err
// });
// }
// }
//
// function* watchEdit() {
// while (true) {
// const {data} = yield take('UPDATE_CONTRACT_ITEM');
// yield fork(editItem, data);
// }
// }
//
// export default function*() {
// yield fork(watchItem);
// yield fork(watchEdit);
// }
......@@ -3,83 +3,93 @@ import {take, call, put, fork, cancel, select} from 'redux-saga/effects';
import {fetchList, fetchItem, createItem} from '../services/customMessage';
import {message} from 'antd';
function* getList(query) {
try {
const {total, list} = yield call(fetchList, query);
yield put({
type: 'FETCH_MESSAGE_LIST_SUCCESS',
total,
items: list
});
} catch (err) {
console.log(err);
message.error(err);
yield put({
type: 'FETCH_MESSAGE_LIST_FAILED',
err,
});
}
}
function* watchList() {
while (true) {
const {query} = yield take('FETCH_MESSAGE_LIST');
yield fork(getList, query);
}
}
function* getItem(id) {
try {
const item = yield call(fetchItem, id);
yield put({
type: 'FETCH_MESSAGE_ITEM_SUCCESS',
item
});
} catch (err) {
console.log(err);
message.error(err);
yield put({
type: 'FETCH_MESSAGE_ITEM_FAILED',
err
});
}
}
function* watchItem() {
while (true) {
const {id} = yield take('FETCH_MESSAGE_ITEM');
yield fork(getItem, id);
}
}
import {watchIndex, watchShow, watchCreate, watchUpdate, watchEdit} from './RESTful';
function* addItem(data) {
try{
const item = yield call(createItem, data);
message.success('创建成功!');
yield put({
type: 'CREATE_MESSAGE_ITEM_SUCCESS',
item: {...item, ...data}
});
}catch(err){
console.log(err);
message.error(err);
yield put({
type:'CREATE_MESSAGE_ITEM_FAILED',
err
});
}
}
export default function*() {
const ID = 'MESSAGE';
yield fork(watchIndex(ID, fetchList));
yield fork(watchShow(ID, fetchItem));
yield fork(watchCreate(ID, createItem));
function* watchAdd() {
while (true) {
const {data} = yield take('CREATE_MESSAGE_ITEM');
yield fork(addItem, data);
}
}
export default function*() {
yield fork(watchList);
yield fork(watchItem);
yield fork(watchAdd);
}
// function* getList(query) {
// try {
// const {total, list} = yield call(fetchList, query);
// yield put({
// type: 'FETCH_MESSAGE_LIST_SUCCESS',
// total,
// items: list
// });
// } catch (err) {
// console.log(err);
// message.error(err);
// yield put({
// type: 'FETCH_MESSAGE_LIST_FAILED',
// err,
// });
// }
// }
//
// function* watchList() {
// while (true) {
// const {query} = yield take('FETCH_MESSAGE_LIST');
// yield fork(getList, query);
// }
// }
//
// function* getItem(id) {
// try {
// const item = yield call(fetchItem, id);
// yield put({
// type: 'FETCH_MESSAGE_ITEM_SUCCESS',
// item
// });
// } catch (err) {
// console.log(err);
// message.error(err);
// yield put({
// type: 'FETCH_MESSAGE_ITEM_FAILED',
// err
// });
// }
// }
//
// function* watchItem() {
// while (true) {
// const {id} = yield take('FETCH_MESSAGE_ITEM');
// yield fork(getItem, id);
// }
// }
//
//
// function* addItem(data) {
// try{
// const item = yield call(createItem, data);
// message.success('创建成功!');
// yield put({
// type: 'CREATE_MESSAGE_ITEM_SUCCESS',
// item: {...item, ...data}
// });
// }catch(err){
// console.log(err);
// message.error(err);
// yield put({
// type:'CREATE_MESSAGE_ITEM_FAILED',
// err
// });
// }
// }
//
// function* watchAdd() {
// while (true) {
// const {data} = yield take('CREATE_MESSAGE_ITEM');
// yield fork(addItem, data);
// }
// }
//
// export default function*() {
// yield fork(watchList);
// yield fork(watchItem);
// yield fork(watchAdd);
// }
......@@ -2,6 +2,7 @@ import {takeLatest} from 'redux-saga';
import {take, call, put, fork, cancel, select, race} from 'redux-saga/effects';
import {fetchList, fetchCates, fetchItem, updateItem, createItem} from '../services/product';
import {message} from 'antd';
import {watchIndex, watchShow, watchCreate, watchEdit} from './RESTful';
function* getList(query) {
try {
......@@ -136,9 +137,14 @@ function* watchAddItem() {
export default function*() {
yield fork(watchProductList);
// yield fork(watchProductList);
yield fork(watchProductCates);
yield fork(watchProductItem);
yield fork(watchEditProductItem);
// yield fork(watchProductItem);
// yield fork(watchEditProductItem);
yield fork(watchAddItem);
const ID = 'PRODUCT';
// yield fork(watchCreate(ID, createItem));
yield fork(watchIndex(ID, fetchList));
yield fork(watchShow(ID, fetchItem));
yield fork(watchEdit(ID, updateItem));
}
import {takeLatest} from 'redux-saga';
import {take, call, put, fork, cancel, select} from 'redux-saga/effects';
import {
fetchList, fetchItem, pass,
} from '../services/remittance';
import {fetchList, fetchItem, pass} from '../services/remittance';
import {message} from 'antd';
function* getList(query) {
try {
const {total, list} = yield call(fetchList, query);
yield put({
type: 'FETCH_REMITTANCE_LIST_SUCCESS',
total,
items: list
});
} catch (err) {
console.log(err);
message.error(err);
yield put({
type: 'FETCH_REMITTANCE_LIST_FAILED',
err,
});
}
}
function* watchList() {
while (true) {
const {query} = yield take('FETCH_REMITTANCE_LIST');
yield fork(getList, query);
}
}
function* getItem(id) {
try {
const item = yield call(fetchItem, id);
yield put({
type: 'FETCH_REMITTANCE_ITEM_SUCCESS',
item
});
} catch (err) {
console.log(err);
message.error(err);
yield put({
type: 'FETCH_REMITTANCE_ITEM_FAILED',
err
});
}
}
function* watchItem() {
while (true) {
const {id} = yield take('FETCH_REMITTANCE_ITEM');
yield fork(getItem, id);
}
}
function* passItem(item){
try {
yield call(pass, item);
yield put({
type: 'PASS_REMITTANCE_ITEM_SUCCESS',
item
});
} catch (err) {
console.log(err);
message.error(err);
yield put({
type: 'PASS_REMITTANCE_ITEM_FAILED',
err
});
}
}
function* watchPassItem() {
while (true) {
const {data} = yield take('PASS_REMITTANCE_ITEM');
yield fork(passItem, data);
}
}
import {watchIndex, watchShow, watchCreate, watchEdit, watch} from './RESTful';
// function* passItem(item){
// try {
// yield call(pass, item);
//
// yield put({
// type: 'PASS_REMITTANCE_ITEM_SUCCESS',
// item
// });
// } catch (err) {
// console.log(err);
// message.error(err);
// yield put({
// type: 'PASS_REMITTANCE_ITEM_FAILED',
// err
// });
// }
// }
// function* watchPassItem() {
// while (true) {
// const {data} = yield take('PASS_REMITTANCE_ITEM');
// yield fork(passItem, data);
// }
// }
export default function*() {
yield fork(watchList);
yield fork(watchItem);
yield fork(watchPassItem);
const ID = 'REMITTANCE';
// yield fork(watchPassItem);
yield fork(watchIndex(ID, fetchList));
yield fork(watchShow(ID, fetchItem));
yield fork(watch('PASS_REMITTANCE_ITEM', pass, '审核'));
}
......@@ -2,96 +2,11 @@ import {takeLatest} from 'redux-saga';
import {take, call, put, fork, cancel, select, race} from 'redux-saga/effects';
import { fetchList, fetchItem, updateItem } from '../services/admin/resource';
import {message} from 'antd';
function* getList(query) {
try {
const {total, list} = yield call(fetchList, query);
yield put({
type: 'FETCH_RESOURCE_LIST_SUCCESS',
total,
items: list
});
} catch (err) {
console.log(err);
message.error(err);
yield put({
type: 'FETCH_RESOURCE_LIST_FAILED',
err,
});
}
}
function* watchList() {
while (true) {
const {query} = yield take('FETCH_RESOURCE_LIST');
yield fork(getList, query);
}
}
function* getItem(id) {
try {
const item = yield call(fetchItem, id);
yield put({
type: 'FETCH_RESOURCE_ITEM_SUCCESS',
item
});
} catch (err) {
console.log(err);
message.error(err);
yield put({
type: 'FETCH_RESOURCE_ITEM_FAILED',
err
});
}
}
function* watchItem() {
while (true) {
const {id} = yield take('FETCH_RESOURCE_ITEM');
yield fork(getItem, id);
}
}
function* editItem(data) {
try{
yield call(updateItem, data);
message.success('修改成功!');
yield put({
type: 'UPDATE_RESOURCE_ITEM_SUCCESS',
item: data
});
}catch(err){
console.log(err);
message.error(err);
yield put({
type:'UPDATE_RESOURCE_ITEM_FAILED',
err
});
}
}
function* watchEdit() {
while (true) {
yield take('UPDATE_RESOURCE');
yield put({
type: 'UPDATE_RESOURCE_START'
});
const {data} = yield race({
data: take('UPDATE_RESOURCE_ITEM'),
canceled: take('CANCEL_UPDATE_RESOURCE')
});
if (data && data.item) {
yield fork(editItem, data.item);
}
yield put({
type: 'UPDATE_RESOURCE_END'
});
}
}
import {watchIndex, watchShow, watchCreate, watchEdit} from './RESTful';
export default function*() {
yield fork(watchList);
yield fork(watchItem);
yield fork(watchEdit);
const ID = 'RESOURCE';
yield fork(watchIndex(ID, fetchList));
yield fork(watchShow(ID, fetchItem));
yield fork(watchEdit(ID, updateItem));
}
......@@ -2,80 +2,7 @@ import {takeLatest} from 'redux-saga';
import {take, call, put, fork, cancel, select} from 'redux-saga/effects';
import {fetchList, fetchItem, createItem, settlementItem, establish} from '../services/trade';
import {message} from 'antd';
function* getList(query) {
try {
const {total, list} = yield call(fetchList, query);
yield put({
type: 'FETCH_TRADE_LIST_SUCCESS',
total,
items: list
});
} catch (err) {
console.log(err);
message.error(err);
yield put({
type: 'FETCH_TRADE_LIST_FAILED',
err,
});
}
}
function* watchTradeList() {
while (true) {
const {query} = yield take('FETCH_TRADE_LIST');
yield fork(getList, query);
}
}
function* getItem(id) {
try {
const item = yield call(fetchItem, id);
yield put({
type: 'FETCH_TRADE_ITEM_SUCCESS',
item
});
} catch (err) {
console.log(err);
message.error(err);
yield put({
type: 'FETCH_TRADE_ITEM_FAILED',
err,
});
}
}
function* watchTradeItem() {
while (true) {
const {id} = yield take('FETCH_TRADE_ITEM');
yield fork(getItem, id);
}
}
function* addItem(data) {
try {
const item = yield call(createItem, data);
message.success('创建成功!');
yield put({
type: 'CREATE_TRADE_ITEM_SUCCESS',
item
});
} catch (err) {
console.log(err);
message.error(err);
yield put({
type: 'CREATE_TRADE_ITEM_FAILED',
err,
});
}
}
function* watchAdd() {
while (true) {
const {data} = yield take('CREATE_TRADE_ITEM');
yield fork(addItem, data);
}
}
import {watchIndex, watchShow, watchCreate, watchEdit} from './RESTful';
function* settlement(id) {
try {
......@@ -131,9 +58,10 @@ function* watchEstablishItem() {
export default function*() {
yield fork(watchTradeList);
yield fork(watchTradeItem);
yield fork(watchAdd);
const ID = 'TRADE';
yield fork(watchCreate(ID, createItem));
yield fork(watchIndex(ID, fetchList));
yield fork(watchShow(ID, fetchItem));
yield fork(watchSettlement);
yield fork(watchEstablishItem);
}
import {takeLatest} from 'redux-saga';
import {take, call, put, fork, cancel, race } from 'redux-saga/effects';
import {fetch, clear, save, create, fetchList, fetchItem, updateItem} from '../services/user';
import {take, call, put, fork, cancel, race} from 'redux-saga/effects';
import {fetch, create, fetchList, fetchItem, updateItem, modifyPassword} from '../services/user';
import {message} from 'antd';
import {watchIndex, watchShow, watchCreate} from './RESTful';
import {watchIndex, watchShow, watchCreate, watchEdit, watch} from './RESTful';
function* authorize(username, password, push) {
function* authorize(username, password, replace) {
try {
const user = yield call(fetch, username, password);
console.log(user);
if (user && user.username && user.token) {
sessionStorage.setItem('user', JSON.stringify({
time: Date.now(),
data: user
}));
yield put({type: 'LOGIN_SUCCESS', user});
console.log('login ok');
push('/');
} catch (err) {
yield put({type: 'LOGIN_ERROR', err})
}
}
function* loginFlow() {
while (true) {
console.log('login flow');
const {username, password, push} = yield take('LOGIN_REQUEST');
yield fork(authorize, username, password, push);
yield take(['LOGOUT', 'LOGIN_ERROR']);
yield call(clear);
}
}
function* addItem(data) {
try {
yield call(create, data);
yield put({type: 'CREATE_USER_ITEM_SUCCESS'});
} catch (err) {
console.log(err);
message.error(err);
yield put({type: 'CREATE_USER_ITEM_FAILED', err});
replace('/');
} else {
throw 'Server is Error: Token is invalid';
}
}
function* watchAddItem() {
while (true) {
const {data} = yield take('CREATE_USER_ITEM');
yield fork(addItem, data);
}
}
function* modifyItem(item) {
try {
yield call(updateItem, item);
yield put({
type: 'UPDATE_USER_ITEM_SUCCESS',
item
});
} catch (err) {
console.log(err);
console.error(err);
message.error(err);
yield put({
type: 'UPDATE_USER_ITEM_FAILED',
err
});
yield put({type: 'LOGIN_ERROR', err})
}
}
function* watchMidfiyItem(){
function* loginFlow() {
while (true) {
yield take('UPDATE_USER');
yield put({
type: 'UPDATE_USER_START'
});
const {data} = yield race({
data: take('UPDATE_USER_ITEM'),
canceled: take('CANCEL_UPDATE_USER')
});
if (data && data.item) {
yield fork(modifyItem, data.item);
}else{
yield put({
type: 'UPDATE_USER_END'
});
const {username, password, replace} = yield take('LOGIN_REQUEST');
if (username && password) {
yield fork(authorize, username, password, replace);
}
yield take(['LOGOUT', 'LOGIN_ERROR']);
sessionStorage.clear();
replace('/login');
}
}
export default function*() {
const ID = 'USER';
yield fork(loginFlow);
yield fork(watchCreate('USER', create));
yield fork(watchIndex('USER', fetchList));
yield fork(watchShow('USER', fetchItem));
yield fork(watchMidfiyItem);
yield fork(watchIndex(ID, fetchList));
yield fork(watchShow(ID, fetchItem));
yield fork(watchEdit(ID, updateItem));
yield fork(watch('CREATE_USER', create, '创建用户'));
yield fork(watch('MODIFY_USER_PASSWORD', modifyPassword, '修改密码'));
}
......@@ -16,4 +16,15 @@ export async function updateItem(item) {
body: serialize(item)
});
}
//sessionStorage
export async function createItem(item) {
return xFetch('/api/admin/authorities', {
method: 'POST',
body: serialize(item)
});
}
export async function deleteItem(id) {
return xFetch('/api/admin/authorities/' + id, {
method: 'DELETE'
});
}
......@@ -16,7 +16,7 @@ export async function create(data) {
}
export async function fetchList(query) {
return xFetch('/api/admin/users' + '?' + serialize({s:30, ...query}));
return xFetch('/api/admin/users' + '?' + serialize({s: 30, ...query}));
}
export async function fetchItem(id) {
......@@ -30,14 +30,12 @@ export async function updateItem(data) {
})
}
export async function clear() {
sessionStorage.clear();
return Promise.resolve();
export async function modifyPassword(data) {
return xFetch('/api/users/' + data.username, {
method: 'PATCH',
body: serialize(data)
});
}
export async function save(user) {
sessionStorage.setItem('user', user);
return Promise.resolve(user);
}
......@@ -6,7 +6,6 @@ const errorMessages = (res) => `${res.status} ${res.statusText}`;
function check401(res) {
if (res.status === 401) {
location.href = '/login';
//console.log('401');
}
return res;
}
......@@ -21,7 +20,7 @@ function check404(res) {
function jsonParse(res) {
return res.json().then(json => ({...res, json})).catch(err=> ({...res, json:{status:0, message: '数据加载错误!'}}));
return res.json().then(json => ({...res, json})).catch(err=> ({...res, json: {status: 0, message: '数据加载错误!'}}));
}
......@@ -38,6 +37,7 @@ function xFetch(url, options) {
let user;
try {
user = JSON.parse(sessionStorage.getItem('user')) || {};
user = user.data || {};
} catch (ex) {
user = {};
}
......
......@@ -270,7 +270,7 @@ export function resourceActions(mask) {
return resourceActions.enum.reduce((arr, action, index)=> {
const value = 1 << index;
if ((mask & value) === value) {
arr.push({title: action, mask: value});
arr.push({label: action, value});
}
return arr;
}, []);
......@@ -286,7 +286,11 @@ export const ENABLE_STATUS = {
};
export function enableStatusToString(status) {
return ENABLE_STATUS[status] || '未定义('+ status+')';
if(status) {
return ENABLE_STATUS[status] || '未定义(' + status + ')';
}else{
return '已删除';
}
}
export const ENABLE_STATUS_LIST = Object.keys(ENABLE_STATUS).map(key=> {
......
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