Commit 7dd98321 authored by superman's avatar superman

update

parent 55cc492a
This diff is collapsed.
......@@ -23,7 +23,8 @@
"redux": "^3.5.2",
"redux-actions": "0.9.x",
"redux-async-connect": "^1.0.0-rc4",
"redux-saga": "^0.10.4"
"redux-saga": "^0.10.4",
"src": "^1.1.2"
},
"devDependencies": {
"atool-test-mocha": "^0.1.4",
......@@ -44,6 +45,9 @@
"pre-commit": "1.x",
"redbox-react": "^1.2.2"
},
"theme": {
"primary-color": "#1DA57A"
},
"pre-commit": [
"lint"
],
......
......@@ -74,6 +74,6 @@ module.exports = {
})
},100);
},
// '/api/*': 'http://react.yanky.cn/',
'/api/*': 'http://192.168.1.126:8080/'
'/api/*': 'http://react.yanky.cn/',
// '/api/*': 'http://192.168.1.126:8080/'
};
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';
@Form.create()
export default class HuikuanInfoForm extends Component {
constructor(props, context) {
super(props, context);
}
static propsType = {
product: PropTypes.object
};
handleSubmit(e){
e.preventDefault();
const data = this.props.form.getFieldsValue();
const {product} = this.props;
data.id = product.id;
console.log('收到表单值:', data);
this.props.dispatch({
type:'UPDATE_PRODUCT_ITEM',
item: data
});
}
render() {
const formItemLayout = {
labelCol: {span: 4},
wrapperCol: {span: 14},
};
const {form:{getFieldProps}, product:{fundRaisedAccount}} = this.props;
return (
<Form horizontal onSubmit={this.handleSubmit.bind(this)}>
<Form.Item label="名称" {...formItemLayout} wrapperCol={{span:6}}>
<Input placeholder="" {...getFieldProps('fundRaisedAccount.name', {initialValue: fundRaisedAccount.name})} />
</Form.Item>
<Form.Item label="银行帐号" {...formItemLayout} wrapperCol={{span:6}}>
<Input placeholder="" {...getFieldProps('fundRaisedAccount.number',{initialValue:fundRaisedAccount.number})} />
</Form.Item>
<Form.Item label="开户行" {...formItemLayout}>
<Input placeholder="" {...getFieldProps('fundRaisedAccount.bank',{initialValue:fundRaisedAccount.bank})} />
</Form.Item>
<Form.Item label="打款须知" {...formItemLayout}>
<Input type="textarea" rows={10} placeholder="" {...getFieldProps('fundRaisedAccount.memo',{initialValue:fundRaisedAccount.memo})} />
</Form.Item>
<Form.Item wrapperCol={{offset: 4, span:10}} style={{marginTop:30}}>
<Button type="primary" htmlType="submit"><Icon type="save"/>保存</Button>
</Form.Item>
</Form>
);
}
}
import React, {Component, PropTypes} from 'react';
import {Router, Route, IndexRoute, Link} from 'react-router';
export default class Layout extends Component {
render() {
const {children, headerClassName, contentClassName, footerClassName, header, footer} = this.props;
const styles = require('./Layout.less');
return (
<section className={styles.layout}>
{header}
<div className={[styles.content, contentClassName].join(' ')}>
{children}
</div>
{footer}
</section>
);
}
}
.layout {
font-size: 14px;
display: flex;
flex-direction: column;
height: 100%;
overflow: hidden;
& > .content {
flex: 1;
overflow: auto;
}
}
import React, {Component, PropTypes} from 'react';
import {
Row,
Col,
Breadcrumb
} from 'antd';
export default class MainHeader extends Component {
static propType = {
breadcrumb: PropTypes.array,
title: PropTypes.node
};
render() {
const {breadcrumb, title} = this.props;
return (
<div className="main-header">
<Row>
<Col span="8">
<Breadcrumb>
{ breadcrumb.map((b, i)=><Breadcrumb.Item key={i}>{b}</Breadcrumb.Item>) }
</Breadcrumb>
</Col>
</Row>
<Row>
<Col span="20">
<h1 className="tac">{title}</h1>
</Col>
</Row>
</div>
);
}
}
.imgPriviewDialog{
:global(.ant-modal-content){
background-color: transparent;
}
}
......@@ -16,26 +16,15 @@ import {
Icon,
Modal,
DatePicker,
Table
Table,
Spin
} from 'antd';
import {arrayRemoveIndex, UUID, formItemLayout, smallFormItemLayout, footerFormSubmitLayout} from '../../utils';
import {arrayRemoveIndex, UUID} from '../../utils';
export function CreateBaseElement() {
return {key: UUID()};
}
export function BaseElementTransform(arr) {
return Object.keys(objs).map(key=>({
key: UUID(),
name: key,
mobile: objs[key]
}));
}
@Form.create()
export default class ProductContactForm extends Component {
export default class ContactForm extends Component {
constructor(props, context) {
super(props, context);
this.state = {
......@@ -98,8 +87,9 @@ export default class ProductContactForm extends Component {
}
render() {
const {form:{getFieldProps}} = this.props;
const {form:{getFieldProps}, loading} = this.props;
return (
<Spin spinning={loading}>
<Form horizontal onSubmit={this.handleSubmit.bind(this)}>
<Form.Item>
{
......@@ -119,19 +109,27 @@ export default class ProductContactForm extends Component {
})}/>
</Col>
<Col span="4">
<Icon type="cross" onClick={this.handleRemove.bind(this, index)}/>
<Icon type="cross" title="删除" onClick={this.handleRemove.bind(this, index)}/>
</Col>
</Input.Group>
</div>
)
}
</Form.Item>
<Form.Item wrapperCol={{offset: 4, span:10}} style={{marginTop:30}}>
<Form.Item {...footerFormSubmitLayout} style={{marginTop:30}}>
<Button onClick={this.handleAdd.bind(this)} style={{marginRight:'1em'}}><Icon
type="plus"/>添加</Button>
<Button type="primary" htmlType="submit"><Icon type="save"/>保存</Button>
<Button type="primary" htmlType="submit" loading={loading}><Icon type="save"/>保存</Button>
{
!this.props.isCreate &&
<Button onClick={e=>{e.preventDefault(); this.props.history.goBack();}}
style={{marginLeft:'1em'}}>
<Icon type="rollback" />返回
</Button>
}
</Form.Item>
</Form>
</Spin>
);
}
}
......@@ -16,17 +16,25 @@ import {
Icon,
Modal,
DatePicker,
Table
Table,
Spin
} from 'antd';
import {
PRODUCT_STATUS,
formatDateTime,
arrayRemoveIndex,
UUID,
formItemLayout,
smallFormItemLayout,
footerFormSubmitLayout
} from '../../utils';
import {PRODUCT_STATUS, formatDateTime} from '../../utils';
const ProductStatus = Object.keys(PRODUCT_STATUS);
const ProductStatus = Object.keys(PRODUCT_STATUS).filter(key=>key != -9);
@Form.create()
export default class ProductDateTimeForm extends Component {
export default class DateTimeSatausForm extends Component {
constructor(props, context) {
super(props, context);
......@@ -69,11 +77,8 @@ export default class ProductDateTimeForm extends Component {
}
render() {
const formItemLayout = {
labelCol: {span: 4},
wrapperCol: {span: 14},
};
const {cates, product, form:{getFieldProps}, isCreate} = this.props;
const {product, loading, form:{getFieldProps}, isCreate} = this.props;
const {
fundReservationStartTime,
fundRaisedEndTime,
......@@ -84,10 +89,11 @@ export default class ProductDateTimeForm extends Component {
return (
<Spin spinning={loading}>
<Form horizontal onSubmit={this.handleSubmit.bind(this)}>
{
!isCreate &&
<Form.Item label="商品状态" {...formItemLayout} wrapperCol={{span:20}}>
<Form.Item label="产品状态" {...formItemLayout} wrapperCol={{span:20}}>
<Radio.Group {...getFieldProps('status', {initialValue: product.status + ''})}>
{
ProductStatus.map((status, index)=>
......@@ -132,10 +138,18 @@ export default class ProductDateTimeForm extends Component {
})}
/>
</Form.Item>
<Form.Item wrapperCol={{offset: 4, span:10}} style={{marginTop:30}}>
<Button type="primary" htmlType="submit"><Icon type="save"/>保存</Button>
<Form.Item {...footerFormSubmitLayout} style={{marginTop:30}}>
<Button type="primary" htmlType="submit" loading={loading}><Icon type="save"/>保存</Button>
{
!this.props.isCreate &&
<Button onClick={e=>{e.preventDefault(); this.props.history.goBack();}}
style={{marginLeft:'1em'}}>
<Icon type="rollback" />返回
</Button>
}
</Form.Item>
</Form>
</Spin>
);
}
}
......@@ -16,13 +16,21 @@ import {
Icon,
Modal,
DatePicker,
Table
Table,
Spin
} from 'antd';
import {UUID} from '../../utils';
import {
arrayRemoveIndex,
UUID,
formItemLayout,
smallFormItemLayout,
footerFormSubmitLayout,
handleUpload
} from '../../utils';
@Form.create()
export default class ProductDocumentsForm extends Component {
export default class DocumentsForm extends Component {
constructor(props, context) {
super(props, context);
this.state = {
......@@ -41,37 +49,14 @@ export default class ProductDocumentsForm extends Component {
};
handleUpload(info) {
let fileList = info.fileList;
componentWillMount(){
// 3. 按照服务器返回信息筛选成功上传的文件
fileList = fileList.filter((file) => {
if (file.response) {
return file.response.status === 1;
}
return true;
});
// 2. 读取远程路径并显示链接
fileList = fileList.map((file) => {
if (file.response) {
// 组件会将 file.url 作为链接进行展示
//file.url = file.response.url;
const {result, status, message} = file.response;
if (status === 1 && result && result.length >= 1 && result[0].url) {
file.url = result[0].url;
}
}
return file;
});
this.setState({fileList});
}
handleSubmit(e){
handleSubmit(e) {
e.preventDefault();
const files = [];
this.state.fileList.forEach(file=>{
this.state.fileList.forEach(file=> {
files.push({
name: file.name,
file: file.url
......@@ -89,9 +74,11 @@ export default class ProductDocumentsForm extends Component {
item: data
});
}
render() {
const {user, product} = this.props;
const {user, loading} = this.props;
return (
<Spin spinning={loading}>
<Form horizontal onSubmit={this.handleSubmit.bind(this)} style={{maxWidth:'800px', margin:'auto'}}>
<Form.Item>
<Upload.Dragger action="/api/fileUpload/upload"
......@@ -99,7 +86,7 @@ export default class ProductDocumentsForm extends Component {
headers={{
authorization: user && user.token,
}}
onChange={this.handleUpload.bind(this)}
onChange={info=>this.setState({fileList: handleUpload(info)})}
fileList={this.state.fileList}>
<p className="ant-upload-drag-icon">
<Icon type="inbox"/>
......@@ -109,9 +96,17 @@ export default class ProductDocumentsForm extends Component {
</Upload.Dragger>
</Form.Item>
<Form.Item style={{marginTop:30, textAlign:'center'}}>
<Button type="primary" htmlType="submit"><Icon type="save"/>保存</Button>
<Button type="primary" htmlType="submit" loading={loading}><Icon type="save"/>保存</Button>
{
!this.props.isCreate &&
<Button onClick={e=>{e.preventDefault(); this.props.history.goBack();}}
style={{marginLeft:'1em'}}>
<Icon type="rollback" />返回
</Button>
}
</Form.Item>
</Form>
</Spin>
);
}
}
......@@ -16,12 +16,12 @@ import {
Icon,
Modal,
DatePicker,
Table
Table,
Spin
} from 'antd';
import {arrayRemoveIndex, UUID, formItemLayout, smallFormItemLayout, footerFormSubmitLayout} from '../../utils';
import {arrayRemoveIndex, UUID} from '../../utils';
export function CreateBaseElement() {
return {key: UUID()};
}
......@@ -35,7 +35,7 @@ export function BaseElementTransform(objs) {
}
@Form.create()
export default class HuikuanInfoForm extends Component {
export default class ElementForm extends Component {
constructor(props, context) {
super(props, context);
this.state = {
......@@ -97,8 +97,9 @@ export default class HuikuanInfoForm extends Component {
}
render() {
const {form:{getFieldProps}} = this.props;
const {form:{getFieldProps}, loading} = this.props;
return (
<Spin spinning={loading}>
<Form horizontal onSubmit={this.handleSubmit.bind(this)}>
<Form.Item>
<h3>可以设置以下要素,或者自定义其他要素</h3>
......@@ -110,27 +111,42 @@ export default class HuikuanInfoForm extends Component {
<div key={item.key} style={{marginBottom:8}}>
<Input.Group>
<Col span="6">
<Input
placeholder="标题" {...getFieldProps(index + '.title', {initialValue: item.title})} />
<Input placeholder="标题"
{...getFieldProps(index + '.title', {
initialValue: item.title
})}
/>
</Col>
<Col span="10">
<Input type="textarea" placeholder="内容" autosize
{...getFieldProps(index + '.content', {initialValue: item.content})}/>
{...getFieldProps(index + '.content', {
initialValue: item.content
})}
/>
</Col>
<Col span="4">
<Icon type="cross" onClick={this.handleRemoveElement.bind(this, index)}/>
<Icon type="cross" title="删除"
onClick={this.handleRemoveElement.bind(this, index)}/>
</Col>
</Input.Group>
</div>
)
}
</Form.Item>
<Form.Item wrapperCol={{offset: 4, span:10}} style={{marginTop:30}}>
<Form.Item {...footerFormSubmitLayout} style={{marginTop:30}}>
<Button onClick={this.handleAddElement.bind(this)} style={{marginRight:'1em'}}><Icon
type="plus"/>添加</Button>
<Button type="primary" htmlType="submit"><Icon type="save"/>保存</Button>
<Button type="primary" htmlType="submit" loading={loading}><Icon type="save"/>保存</Button>
{
!this.props.isCreate &&
<Button onClick={e=>{e.preventDefault(); this.props.history.goBack();}}
style={{marginLeft:'1em'}}>
<Icon type="rollback" />返回
</Button>
}
</Form.Item>
</Form>
</Spin>
);
}
}
import React, {Component, PropTypes} from 'react';
import {
Row,
Col,
Form,
Input,
Button,
Checkbox,
Select,
message,
Tabs,
Cascader,
Radio,
Upload,
Icon,
Modal,
DatePicker,
Table,
Spin
} from 'antd';
import {arrayRemoveIndex, UUID, formItemLayout, smallFormItemLayout, footerFormSubmitLayout} from '../../utils';
@Form.create()
export default class HuikuanInfoForm extends Component {
constructor(props, context) {
super(props, context);
}
static propsType = {
product: PropTypes.object
};
handleSubmit(e) {
e.preventDefault();
const data = this.props.form.getFieldsValue();
const {product} = this.props;
data.id = product.id;
console.log('收到表单值:', data);
this.props.dispatch({
type: 'UPDATE_PRODUCT_ITEM',
item: data
});
}
render() {
const {form:{getFieldProps}, product:{fundRaisedAccount}, loading} = this.props;
return (
<Spin spinning={loading}>
<Form horizontal onSubmit={this.handleSubmit.bind(this)}>
<Form.Item label="名称" help="接收打款帐户名称" {...smallFormItemLayout} >
<Input placeholder="名称"
{...getFieldProps('fundRaisedAccount.name', {
initialValue: fundRaisedAccount.name
})}
/>
</Form.Item>
<Form.Item label="银行帐号" help="接收打款银行帐号" {...smallFormItemLayout}>
<Input placeholder="银行帐号"
{...getFieldProps('fundRaisedAccount.number', {
initialValue: fundRaisedAccount.number
})}
/>
</Form.Item>
<Form.Item label="开户行" help="接收打款银行开户行" {...formItemLayout}>
<Input placeholder="开户行"
{...getFieldProps('fundRaisedAccount.bank', {
initialValue: fundRaisedAccount.bank
})}
/>
</Form.Item>
<Form.Item label="打款须知" help="接收打款的一些必要告知信息" {...formItemLayout}>
<Input type="textarea" rows={10} placeholder=""
{...getFieldProps('fundRaisedAccount.memo', {
initialValue: fundRaisedAccount.memo
})}
/>
</Form.Item>
<Form.Item {...footerFormSubmitLayout} style={{marginTop:30}}>
<Button type="primary" htmlType="submit" loading={loading}><Icon type="save"/>保存</Button>
{
!this.props.isCreate &&
<Button onClick={e=>{e.preventDefault(); this.props.history.goBack();}}
style={{marginLeft:'1em'}}>
<Icon type="rollback" />返回
</Button>
}
</Form.Item>
</Form>
</Spin>
);
}
}
......@@ -16,13 +16,13 @@ import {
Icon,
Modal,
DatePicker,
Table
Table,
Spin
} from 'antd';
import {arrayRemoveIndex, formatMoney} from '../../utils';
import {arrayRemoveIndex, UUID, formItemLayout, smallFormItemLayout, footerFormSubmitLayout} from '../../utils';
import {UUID} from '../../utils';
export function YongjingTransform(arr) {
return arr.map(item=>({
......@@ -76,7 +76,7 @@ export default class ShouyiYongjingForm extends Component {
this.setState({yongjing: yongjing});
}
handleSubmit(e){
handleSubmit(e) {
e.preventDefault();
const formData = this.props.form.getFieldsValue();
......@@ -84,10 +84,10 @@ export default class ShouyiYongjingForm extends Component {
const data = {
id: this.props.product.id
};
Object.keys(formData).forEach(key=>{
if(/^[\d]+$/g.test(key)){
Object.keys(formData).forEach(key=> {
if (/^[\d]+$/g.test(key)) {
commissionAlg.push(formData[key]);
}else{
} else {
data[key] = formData[key];
}
});
......@@ -96,32 +96,32 @@ export default class ShouyiYongjingForm extends Component {
console.log(data);
this.props.dispatch({
type:'UPDATE_PRODUCT_ITEM',
type: 'UPDATE_PRODUCT_ITEM',
item: data
});
}
render() {
const formItemLayout = {
labelCol: {span: 4},
wrapperCol: {span: 14},
};
const {form:{getFieldProps}, product} = this.props;
const {form:{getFieldProps}, product, loading} = this.props;
return (
<Spin spinning={loading}>
<Form horizontal onSubmit={this.handleSubmit.bind(this)}>
<Form.Item label="佣金结算方式" help="例如: 打款结佣、成立结佣" {...formItemLayout} wrapperCol={{span:6}}>
<Input placeholder="佣金结算方式" {...getFieldProps('settlement', {
initialValue:product.settlement
})} />
<Form.Item label="佣金结算方式" help="例如: 打款结佣、成立结佣" {...smallFormItemLayout}>
<Input placeholder="佣金结算方式"
{...getFieldProps('settlement', {
initialValue: product.settlement
})}
/>
</Form.Item>
<Form.Item label="产品的预期收益" {...formItemLayout} wrapperCol={{span:6}}>
<Input placeholder="产品的预期收益" {...getFieldProps('productProspectiveReturn', {
initialValue:product.productProspectiveReturn
})} />
<Form.Item label="产品的预期收益" help="浮动或百分比" {...smallFormItemLayout}>
<Input placeholder="产品的预期收益"
{...getFieldProps('productProspectiveReturn', {
initialValue: product.productProspectiveReturn
})}
/>
</Form.Item>
<Form.Item label="佣金算法" {...formItemLayout}>
<Input.Group>
......@@ -138,13 +138,13 @@ export default class ShouyiYongjingForm extends Component {
<Input {...getFieldProps(index + '.min', {initialValue: item.min})} />
</Col>
<Col span="5">
<Input {...getFieldProps(index+ '.max', {initialValue: item.max})}/>
<Input {...getFieldProps(index + '.max', {initialValue: item.max})}/>
</Col>
<Col span="5">
<Input {...getFieldProps(index+'.sy', {initialValue: item.sy})}/>
<Input {...getFieldProps(index + '.sy', {initialValue: item.sy})}/>
</Col>
<Col span="5">
<Input {...getFieldProps(index+'.yj', {initialValue: item.yj})}/>
<Input {...getFieldProps(index + '.yj', {initialValue: item.yj})}/>
</Col>
<Col span="4">
<Icon type="cross" onClick={this.handleRemoveYongjin.bind(this, index)}/>
......@@ -155,16 +155,25 @@ export default class ShouyiYongjingForm extends Component {
}
<Row style={{marginTop:15}}>
<Col span="20" className="tac">
<Button style={{marginRight:'.5em'}}
onClick={this.handleAddYongjing.bind(this)}><Icon
type="plus"/>添加</Button>
</Col>
</Row>
</Form.Item>
<Form.Item wrapperCol={{offset: 4, span:10}} style={{marginTop:30}}>
<Button type="primary" htmlType="submit"><Icon type="save"/>保存</Button>
<Form.Item {...footerFormSubmitLayout} style={{marginTop:30}}>
<Button style={{marginRight:'1em'}}
onClick={this.handleAddYongjing.bind(this)}><Icon
type="plus"/>添加</Button>
<Button type="primary" htmlType="submit" loading={loading}><Icon type="save"/>保存</Button>
{
!this.props.isCreate &&
<Button onClick={e=>{e.preventDefault(); this.props.history.goBack();}}
style={{marginLeft:'1em'}}>
<Icon type="rollback" />返回
</Button>
}
</Form.Item>
</Form>
</Spin>
);
}
}
......
......@@ -17,35 +17,42 @@ import {
Modal,
DatePicker,
Table,
Spin
} from 'antd';
import Layout from '../../components/Layout/Layout';
import MainHeader from '../../components/MainHeader';
import {formItemLayout, footerFormSubmitLayout} from '../../utils';
@connect(state=>({
loading: state.announcement.loading,
}))
@Form.create()
export default class AddItem extends Component{
export default class AddItem extends Component {
constructor(props, content) {
super(props, content);
}
handleSubmit(e){
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',
type: 'CREATE_ANNOUNCEMENT_ITEM',
data
});
}
render = ()=> {
const {loading, form:{getFieldProps}} = this.props;
const formItemLayout = {
labelCol: {span: 4},
wrapperCol: {span: 14},
};
return(
const {loading, form:{getFieldProps}, location:{query}} = this.props;
const header = (<MainHeader breadcrumb={['产品管理', '产品详情', '添加公告']}
title={(query.title ? query.title + ' - ' : '') + '添加公告'}/>);
return (
<Layout header={header}>
<Spin spinning={loading}>
<Form horizontal onSubmit={this.handleSubmit.bind(this)}>
<Form.Item label="标题" {...formItemLayout}>
<Input placeholder="公告标题" {...getFieldProps('title')} />
......@@ -53,10 +60,16 @@ export default class AddItem extends Component{
<Form.Item label="内容" {...formItemLayout}>
<Input placeholder="公告内容" type="textarea" {...getFieldProps('announcement')} />
</Form.Item>
<Form.Item wrapperCol={{offset: 4, span:10}} style={{marginTop:30}}>
<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>
);
}
}
......@@ -17,8 +17,14 @@ import {
Modal,
DatePicker,
Table,
Spin
} from 'antd';
import Layout from '../../components/Layout/Layout';
import MainHeader from '../../components/MainHeader';
import {formItemLayout, footerFormSubmitLayout} from '../../utils';
@connect(state=>({
loading: state.announcement.loading,
announcement: state.announcement.item,
......@@ -30,10 +36,8 @@ export default class EditItem extends Component {
}
componentWillMount() {
if (!(this.props.announcement && this.props.announcement.id)) {
componentDidMount() {
this.fetchItem(this.props.params.id);
}
};
fetchItem(id) {
......@@ -46,28 +50,50 @@ export default class EditItem extends Component {
handleSubmit(e) {
e.preventDefault();
const data = this.props.form.getFieldsValue();
data.id = this.props.announcement.id;
console.log(data);
this.props.dispatch({
type: 'UPDATE_ANNOUNCEMENT_ITEM',
data
});
}
render() {
const {announcement, loading, form:{getFieldProps}} = this.props;
const formItemLayout = {
labelCol: {span: 4},
wrapperCol: {span: 14},
};
const {announcement, loading, form:{getFieldProps}, location:{query}} = this.props;
const header = (<MainHeader breadcrumb={['产品管理', '产品详情', '修改公告']}
title={(query && query.title ? query.title + ' - ' : '') + '修改公告'}/>);
return (
<Layout header={header}>
<Spin spinning={loading}>
{
announcement &&
<Form horizontal onSubmit={this.handleSubmit.bind(this)}>
<Form.Item label="标题" {...formItemLayout}>
<Input placeholder="公告标题" {...getFieldProps('title', {initialValue: announcement.title})} />
<Input placeholder="公告标题"
{...getFieldProps('title', {
initialValue: announcement.title
})} />
</Form.Item>
<Form.Item label="内容" {...formItemLayout}>
<Input placeholder="公告内容" type="textarea" {...getFieldProps('announcement', {initialValue: announcement.announcement})} />
<Input placeholder="公告内容" autosize={{ minRows: 5 }} type="textarea"
{...getFieldProps('announcement', {
initialValue: announcement.announcement
})} />
</Form.Item>
<Form.Item wrapperCol={{offset: 4, span:10}} style={{marginTop:30}}>
<Button type="primary" htmlType="submit" loading={loading}><Icon type="save"/>保存</Button>
<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>
);
}
}
import React, {Component, PropTypes} from 'react';
import {connect} from 'react-redux';
import {Table, Icon, Button} from 'antd';
import {serialize, formatDateTime, productStatusToString} from '../../utils';
import {Table, Icon, Button, Switch, Form} from 'antd';
import {serialize, formatDateTime, productStatusToString, footerFormSubmitLayout} from '../../utils';
import {Link} from 'react-router';
import Layout from '../../components/Layout/Layout';
import MainHeader from '../../components/MainHeader';
const columns = [
{
title: 'ID',
dataIndex: 'id',
key: 'id',
width: 60
}, {
title: '标题',
dataIndex: 'title',
key: 'title',
}, {
title: '创建时间',
dataIndex: 'dateCreated',
key: 'dateCreated',
width: 150,
className: 'tac',
render: (dateCreated, record)=>(
<span>
{dateCreated && formatDateTime(dateCreated)}
</span>
)
}, {
title: '状态',
dataIndex: 'status',
key: 'status',
width: 120,
className: 'tac',
render: (status, record)=>(<span data-status={status}>{status?'有效':'无效'}</span>)
}, {
title: '操作',
key: 'operation',
width: 120,
className: 'tac',
render: (text, record)=>(
<span>
<a href={'/product/item?id='+ record.id}></a>
</span>
)
}
];
@connect(state=>({
items: state.announcement.items,
loading: state.announcement.loading,
......@@ -58,7 +19,7 @@ export default class List extends Component {
}
componentWillMount() {
componentDidMount() {
this.fetchList(this.props.location.query);
};
......@@ -74,13 +35,10 @@ export default class List extends Component {
}
render() {
const {total, items, loading, history:{replace}, location:{pathname, query}} = this.props;
const pagination = {
total: total,
pageSize: parseInt(query.s, 10) || 10,
......@@ -101,17 +59,79 @@ export default class List extends Component {
}
};
return <div>
<h1>公告列表</h1>
<Link to={'/announcement/create?itemId='+ query.itemId}><Button><Icon type="plus"/>添加</Button></Link>
const columns = [
{
title: 'ID',
dataIndex: 'id',
key: 'id',
width: 60
}, {
title: '标题',
dataIndex: 'title',
key: 'title',
}, {
title: '内容',
dataIndex: 'announcement',
key: 'announcement'
}, {
title: '创建时间',
dataIndex: 'dateCreated',
key: 'dateCreated',
width: 150,
className: 'tac',
render: (dateCreated, record)=>(
<span>
{dateCreated && formatDateTime(dateCreated)}
</span>
)
}, {
title: '状态',
dataIndex: 'status',
key: 'status',
width: 120,
className: 'tac',
render: (text, record)=>(
<span onClick={e=>{e.stopPropagation(); e.preventDefault();}}>
<Switch checkedChildren="开" unCheckedChildren="关" defaultChecked={record.status}
onChange={checked=>{
this.props.dispatch({
type:'UPDATE_ANNOUNCEMENT_ITEM',
data:{
id: record.id,
status: checked ? 1: 0
}
})
}}
/>
</span>
)
}
];
const header = (<MainHeader breadcrumb={['产品管理', '产品详情', '公告列表']}
title={(query.title ? query.title + ' - ' : '') + '公告列表'}/>);
return (
<Layout header={header}>
<Form horizontal>
<Table className="ant-table" columns={columns}
dataSource={Array.isArray(items)?items:[]}
loading={loading}
pagination={pagination}
scroll={{ y: window.innerHeight-290 }}
onRowClick={this.handleRowClick.bind(this)}
/>
</div>;
<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>
</Form>
</Layout>
);
}
}
......
import React, { Component, PropTypes } from 'react';
import { Router, Route, IndexRoute, Link } from 'react-router';
import React, {Component, PropTypes} from 'react';
import {Router, Route, IndexRoute, Link} from 'react-router';
import Layout from '../../components/Layout/Layout';
import { Collapse } from 'antd';
import {Collapse, Menu, Icon} from 'antd';
const Panel = Collapse.Panel;
const SubMenu = Menu.SubMenu;
const MenuItemGroup = Menu.ItemGroup;
export default class App extends Component {
......@@ -19,37 +19,99 @@ export default class App extends Component {
store: PropTypes.object.isRequired
};
render(){
render() {
const styles = require('./App.less');
const mainMenu = [
{
title: '产品管理',
items: [
{
to: '/products',
cn: '产品列表',
en: 'Products'
}, {
to: '/products/create',
cn: '添加产品',
en: 'Add Products'
}
]
}, {
title: '订单管理',
items: [
{
to: '/trades',
cn: '订单列表',
en: 'Trades'
}
]
}, {
title: '审核管理',
items: [
{
to: '/remittance/audits',
cn: '报单审核',
en: 'Remittance Audits'
}
]
}
];
const logo = require('./images/logo.png');
return (
<div className={styles.normal}>
<div className={styles.head}>
<h1>枢纽科技</h1>
<img className="page-logo" src={'/'+logo} title="枢纽科技" alt="枢纽科技"/>
</div>
<div className={styles.content}>
<div className={styles.side}>
<Collapse accordion>
<Panel header="产品管理">
<Link to="/products">产品列表</Link><br/>
<Link to="/products/create">增加产品</Link>
</Panel>
<Panel header="订单管理">
<Link to="/trades">订单列表</Link><br/>
</Panel>
</Collapse>
<Menu mode="inline" defaultOpenKeys={['sub1']}>
<SubMenu key="sub1" title={<span><Icon type="mail" /><span>业务管理</span></span>}>
{
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>
</Menu>
</div>
<div className={styles.main}>
{this.props.children}
</div>
</div>
<div className={styles.foot}>
Built with react, react-router, redux, redux-saga, ant-tool, css-modules, antd...
杭州枢纽科技有限公司 荣誉出品 <a href="mailto:bainx@vip.qq.com">问题反馈</a>
</div>
</div>
);
}
}
class MenuItemContent extends Component {
static propType = {
to: PropTypes.string,
cn: PropTypes.string,
en: PropTypes.string,
}
render() {
const {to, cn, en} = this.props;
return (
<Link to={to}>
<span>
<span className="cn">{cn}</span>
<span className="en">{en}</span>
</span>
</Link>
);
}
}
......
......@@ -6,40 +6,144 @@
}
.head {
background: #364171;
height: 80px;
background: #fff;
height: 75px;
padding: 8px;
color: #fff;
border-bottom: 1px solid #ccc;
color: #364171;
border-bottom: 1px solid #e0e0e0;
:global {
.page-logo {
margin: 20px 0 0 30px;
}
}
}
.content {
flex: 1;
display: flex;
background-color: #e9ecf3;
padding: 20px 30px 0;
}
.side {
padding: 8px;
width: 20%;
min-width: 200px;
max-width: 250px;
background: #fafafa;
border-right: 1px solid #ccc;
/**/
width: 250px;
//min-width: 250px;
//max-width: 300px;
background: #fff;
border-right: 1px solid #e9e9e9;
margin-right: 0px;
padding: 30px 0 0;
border-radius: 5px 0 0 5px;
:global {
.ant-menu-inline,
.ant-menu-vertical {
border-right: 0;
}
}
}
.main {
padding: 8px;
display: flex;
flex-direction: column;
height: 100%;
padding: 10px 20px;
flex: 1 0 auto;
overflow: auto;
overflow: hidden;
background: #fff;
border-radius: 0 5px 5px 0;
h1 {
font-size: 24px;
color: #404040;
font-weight: 400;
line-height: 40px;
margin-bottom: 24px;
margin-top: 8px;
font-family: lato, Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, Arial, sans-serif;
}
h2 {
font-size: 22px;
color: #505050;
font-weight: 400;
line-height: 36px;
}
h3 {
font-size: 18px;
color: #606060;
font-weight: 400;
line-height: 30px;
}
//& > section {
// display: flex;
// flex-direction: column;
// height: 100%;
// overflow: auto;
// & > header {
// h1 {
// line-height: 30px;
// margin: 0;
// }
// :global {
// .ant-breadcrumb {
// & > span {
// line-height: 42px;
// }
// }
// }
// }
// & > * {
// &:nth-child(2){
// flex: 1;
// overflow: auto;
// display: flex;
// flex-direction: column;
// :global{
// .content{
// flex:1;
// }
// }
//
// }
// }
//}
:global {
.tac {
text-align: center !important;
}
.main-header {
border-bottom: 1px solid #eaeaea;
margin-bottom: 20px;
h1 {
margin-bottom: 10px;
}
}
}
}
.foot {
background: #fafafa;
border-top: 1px solid #ccc;
//background: #fafafa;
//border-top: 1px solid #e0e0e0;
padding: 8px;
font-size: 12px;
text-align: center;
a {
margin-left: .5em;
opacity: .8;
}
}
:global(.tac){
text-align: center !important;
:global {
.img-priview-dialog {
.ant-modal-content {
background-color: transparent;
img {
margin: auto;
display: block;
}
}
}
}
......@@ -18,16 +18,18 @@ import {
DatePicker,
Table,
Spin,
Breadcrumb
} from 'antd';
import HuikuanInfoForm from '../../components/HuikuanInfoForm/HuikuanInfoForm';
import ProductBaseInfoForm from '../../components/ProductBaseInfoForm/ProductBaseInfoForm';
import ShouyiYongjingForm from '../../components/ShouyiYongjingForm/ShouyiYongjingForm';
import ProductElementForm from '../../components/ProductElementForm/ProductElementForm';
import ProductDateTimeForm from '../../components/ProductDateTimeForm/ProductDateTimeForm';
import ProductDocumentsForm from '../../components/ProductDocumentsForm/ProductDocumentsForm';
import ProductContactForm from '../../components/ProductContactForm/ProductContactForm';
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 MainHeader from '../../components/MainHeader';
import Layout from '../../components/Layout/Layout';
class PublishForm extends Component {
constructor(props, content) {
......@@ -51,7 +53,7 @@ class PublishForm extends Component {
return (
<div style={{textAlign:'center'}}>
<h1>请确认产品各项信息已经填写完整!</h1>
<Button type="primary" loading={this.props.loading} onClick={this.handlePublish.bind(this)} >
<Button type="primary" loading={this.props.loading} onClick={this.handlePublish.bind(this)}>
<Icon type="solution"/>发布
</Button>
</div>
......@@ -85,15 +87,15 @@ export default class AddItem extends Component {
componentWillMount() {
const {product, cates} = this.props;
const {cates} = this.props;
if (!cates || !cates.length) {
this.fetchCates();
}
if (!product || !product.id) {
this.props.dispatch({
type: 'CREATE_PRODUCT_ITEM'
});
}
};
fetchCates() {
......@@ -111,7 +113,7 @@ export default class AddItem extends Component {
const tabs = [{
tab: '基本信息',
children: ProductBaseInfoForm
children: BaseInfoForm
}, {
tab: '收益佣金',
children: ShouyiYongjingForm
......@@ -120,37 +122,37 @@ export default class AddItem extends Component {
children: HuikuanInfoForm
}, {
tab: '基本要素',
children: ProductElementForm
children: ElementForm
}, {
tab: '时间',
children: ProductDateTimeForm
children: DateTimeStatusForm
}, {
tab: '相关附件',
children: ProductDocumentsForm
children: DocumentsForm
}, {
tab: '服务经理',
children: ProductContactForm
children: ContactForm
}, {
tab: '发布',
children: PublishForm
}].map((tabPane, index)=> {
tabPane.key = 'tabs-pane-' + (index + 1);
tabPane.disabled = index != this.state.step - 1;
//tabPane.disabled = index != this.state.step - 1;
return tabPane;
});
const header = <MainHeader breadcrumb={['产品管理', '添加产品']} title="添加产品"/>;
return (
<div className={styles.normal}>
<Tabs ref="tabs" className={styles.tabs} tabPosition="left" >
<Layout header={header}>
<Tabs className={styles.tabs} tabPosition="left">
{ tabs.map(tp=>
<Tabs.TabPane tab={tp.tab} key={tp.key} >
<Tabs.TabPane tab={tp.tab} key={tp.key}>
{product && <tp.children {...this.props} /> }
</Tabs.TabPane>
)}
</Tabs>
</div>
</Layout>
);
}
}
......
......@@ -17,17 +17,19 @@ import {
Modal,
DatePicker,
Table,
Spin
Spin,
Breadcrumb
} from 'antd';
import HuikuanInfoForm from '../../components/HuikuanInfoForm/HuikuanInfoForm';
import ProductBaseInfoForm from '../../components/ProductBaseInfoForm/ProductBaseInfoForm';
import ShouyiYongjingForm from '../../components/ShouyiYongjingForm/ShouyiYongjingForm';
import ProductElementForm from '../../components/ProductElementForm/ProductElementForm';
import ProductDateTimeForm from '../../components/ProductDateTimeForm/ProductDateTimeForm';
import ProductDocumentsForm from '../../components/ProductDocumentsForm/ProductDocumentsForm';
import ProductContactForm from '../../components/ProductContactForm/ProductContactForm';
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 MainHeader from '../../components/MainHeader';
import Layout from '../../components/Layout/Layout';
@connect(state=>({
cates: state.product.cates,
......@@ -53,9 +55,7 @@ export default class EditItem extends Component {
if (!this.props.cates.length) {
this.fetchCates();
}
if (!(this.props.product && this.props.product.id)) {
this.fetchItem(this.props.params.id);
}
};
fetchCates() {
......@@ -76,32 +76,49 @@ export default class EditItem extends Component {
const {product} = 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
}].map((tabPane, index)=> {
tabPane.key = 'tabs-pane-' + (index + 1);
return tabPane;
});
const header = (<MainHeader breadcrumb={['产品管理', '产品详情']}
title={(product && product.itemShortTitle ? product.itemShortTitle + ' - ' : '') + '产品详情'}/>);
return (
<Spin spinning={this.props.loading}>
<Tabs tabPosition="top">
<Tabs.TabPane tab="基本信息" key="tab-pane-1">
{ product && <ProductBaseInfoForm {...this.props}/> }
</Tabs.TabPane>
<Tabs.TabPane tab="收益与佣金" key="tab-pane-2">
{ product && <ShouyiYongjingForm {...this.props}/> }
</Tabs.TabPane>
<Tabs.TabPane tab="汇款账号" key="tab-pane-4">
{ product && <HuikuanInfoForm {...this.props}/> }
</Tabs.TabPane>
<Tabs.TabPane tab="基本要素" key="tab-pane-5">
{ product && <ProductElementForm {...this.props} /> }
</Tabs.TabPane>
<Tabs.TabPane tab="时间状态" key="tab-pane-6">
{ product && <ProductDateTimeForm {...this.props} /> }
</Tabs.TabPane>
<Tabs.TabPane tab="相关附件" key="tab-pane-7">
{ product && <ProductDocumentsForm {...this.props} /> }
</Tabs.TabPane>
<Tabs.TabPane tab="服务经理" key="tab-pane-8">
{ product && <ProductContactForm {...this.props} /> }
<Layout header={header}>
<Tabs className={styles.tabs} tabPosition="left">
{ tabs.map(tp=>
<Tabs.TabPane tab={tp.tab} key={tp.key}>
{product && <tp.children {...this.props} /> }
</Tabs.TabPane>
)}
</Tabs>
</Spin>
</Layout>
);
}
}
import React, {Component, PropTypes} from 'react';
import {connect} from 'react-redux';
import {Link} from 'react-router';
import {
Row,
Col,
Form,
Input,
Button,
Checkbox,
Select,
message,
Tabs,
Cascader,
Radio,
Upload,
Icon,
Modal,
DatePicker,
Table,
Spin
} from 'antd';
@connect(state=>({
item: state.product.item,
loading: state.product.loading
}))
export default class Item extends Component {
componentWillMount() {
this.fetchItem(this.props.params.id);
};
fetchItem(id) {
this.props.dispatch({
type: 'FETCH_PRODUCT_ITEM',
id
});
};
handleGoBack(e) {
e.preventDefault();
this.props.history.goBack();
};
render() {
const tw = 6;
const vw = 18;
const styles = require('../Trade/Item.less');
const {item, loading} = this.props;
return (
<Spin spinning={loading}>
{
item &&
<div className={styles.trade}>
<div className={styles.tradeTable}>
<Row type="flex" justify="space-around" align="middle">
<Col span={tw}>产品标题</Col>
<Col span={vw}>{item.itemTitle}</Col>
</Row>
<Row type="flex" justify="space-around" align="middle">
<Col span={tw}>产品短标题</Col>
<Col span={vw}>{item.itemShortTitle}</Col>
</Row>
<Row type="flex" justify="space-around" align="middle">
<Col span={tw}>产品标题</Col>
<Col span={vw}>{item.itemTitle}</Col>
</Row>
<Row type="flex" justify="space-around" align="middle">
<Col span={tw}>产品标题</Col>
<Col span={vw}>{item.itemTitle}</Col>
</Row>
<Row type="flex" justify="space-around" align="middle">
<Col span={tw}>产品标题</Col>
<Col span={vw}>{item.itemTitle}</Col>
</Row>
</div>
<p>
<Button onClick={this.handleGoBack.bind(this)}>返回</Button>
<Link to={'/products/'+ item.id+'/edit'}><Button>编辑</Button></Link>
<Link to={'/announcement?itemId='+item.id}><Button>公告</Button></Link>
<Link
to={'/trades/create/'+ item.id+'?title='+ item.itemShortTitle}><Button>报单</Button></Link>
</p>
</div>
}
</Spin>
);
}
}
import React, {Component, PropTypes} from 'react';
import {connect} from 'react-redux';
import {Table, Icon} from 'antd';
import {serialize, formatDateTime, productStatusToString} from '../../utils';
import {Table, Icon, Breadcrumb, Row, Col, Pagination} from 'antd';
import {
serialize,
formatDateTime,
productStatusToString,
productEnableCreateTrade
} from '../../utils';
import {Link} from 'react-router';
import Layout from '../../components/Layout/Layout';
import MainHeader from '../../components/MainHeader';
const columns = [
{
......@@ -16,32 +24,32 @@ const columns = [
dataIndex: 'cateId',
key: 'cateId',
width: 80,
className:'tac',
className: 'tac',
render: (cateId, record)=>(<span data-cate-id={cateId}>{record.cateName}</span>)
}, {
title: '标题',
dataIndex: 'shortTitle',
key: 'shortTitle',
render: (shortTitle, record)=>(<span title={shortTitle}>{(shortTitle + '').substring(0, 20)}</span>)
render: (shortTitle, record)=>(<span title={shortTitle}>{(shortTitle + '').substring(0, 15)}</span>)
}, {
title: '募集比率',
dataIndex: 'rate',
key: 'rate',
width:120,
className:'tac',
width: 120,
className: 'tac',
}, {
title: '状态',
dataIndex: 'status',
key: 'status',
width:120,
className:'tac',
width: 80,
className: 'tac',
render: (status, record)=>(<span data-status={status}>{productStatusToString(status)}</span>)
}, {
title: '创建时间',
dataIndex: 'dateCreated',
key: 'dateCreated',
width:150,
className:'tac',
width: 150,
className: 'tac',
render: (dateCreated, record)=>(
<span>
{dateCreated && formatDateTime(dateCreated)}
......@@ -50,15 +58,21 @@ const columns = [
}, {
title: '操作',
key: 'operation',
width:120,
className:'tac',
render: (text, record)=>(
width: 120,
className: 'tac',
render: (text, product)=>(
<span>
<Link to={'/announcement?itemId='+product.id+'&title='+product.shortTitle}
onClick={e=>e.stopPropagation()}>公告</Link>
{
productEnableCreateTrade(product.status) &&
<span>
<a href={'/product/item?id='+ record.id}>详情</a>
<span className="ant-divider"></span>
<Link to={'/announcement?itemId='+record.id} onClick={e=>e.stopPropagation()}>公告</Link>
<span className="ant-divider"></span>
<Link to={'/trades/add/'+record.id+'?title='+record.shortTitle}>报单</Link>
<Link to={'/trades/create?itemId='+product.id+'&title='+product.shortTitle}
onClick={e=>e.stopPropagation()}>报单</Link>
</span>
}
</span>
)
}
......@@ -76,7 +90,7 @@ export default class List extends Component {
}
componentWillMount() {
componentDidMount() {
this.fetchList(this.props.location.query);
};
......@@ -87,8 +101,8 @@ export default class List extends Component {
});
};
handleRowClick({id}){
this.props.history.push('/products/'+id+'/edit');
handleRowClick({id}) {
this.props.history.push('/products/' + id);
}
......@@ -117,16 +131,20 @@ export default class List extends Component {
}
};
return <div>
<h1>产品列表</h1>
const header = (<MainHeader breadcrumb={['产品管理', '产品列表']}
title="产品列表"/>);
return (
<Layout header={header}>
<Table className="ant-table" columns={columns}
dataSource={Array.isArray(items)?items:[]}
loading={loading}
pagination={pagination}
scroll={{ y: window.innerHeight-290 }}
scroll={{ y: window.innerHeight-380 }}
onRowClick={this.handleRowClick.bind(this)}
/>
</div>;
</Layout>
);
}
}
......
.normal {
.tabs {
flex: 1;
display: flex;
flex-direction: column;
height: 100%;
.tabs {
flex: 1;
&:global(.ant-tabs-top) {
flex-direction: column;
:global {
.ant-tabs-content {
display: flex;
& > div {
flex: 1;
}
}
}
}
:global {
.tablist {
}
.ant-tabs-content{
.ant-tabs-content {
flex: 1;
height: 100%;
.ant-tabs-tabpane {
height: 100%;
overflow: auto;
}
}
}
......
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';
import {formItemLayout, footerFormSubmitLayout} from '../../utils';
@connect(state=>({
loading: state.remittance.loading,
audit: state.remittance.audit,
}))
@Form.create()
export default class EditItem extends Component {
constructor() {
super(...arguments);
}
componentDidMount() {
this.fetchItem(this.props.params.id);
};
fetchItem(id) {
this.props.dispatch({
type: 'FETCH_AUDIT_ITEM',
id
});
};
handleSubmit(e) {
e.preventDefault();
const data = this.props.form.getFieldsValue();
data.id = this.props.audit.id;
console.log(data);
// this.props.dispatch({
// type: 'UPDATE_AUDIT_ITEM',
// data
// });
}
render() {
const {audit, loading, form:{getFieldProps}, location:{query}} = this.props;
const header = (<MainHeader breadcrumb={['审核管理', '报单审核','审核详情']}
title={(audit && audit.title ? audit.title + ' - ' : '') + '审核详情'}/>);
return (
<Layout header={header}>
<Spin spinning={loading}>
{
audit &&
<Form horizontal onSubmit={this.handleSubmit.bind(this)}>
<Form.Item label="产品募集情况" {...formItemLayout}>
<Input placeholder="公告标题"
{...getFieldProps('title', {
initialValue: audit.title
})} />
</Form.Item>
<Form.Item label="内容" {...formItemLayout}>
<Input placeholder="公告内容" autosize={{ minRows: 5 }} type="textarea"
{...getFieldProps('announcement', {
initialValue: audit.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>
);
}
}
import React, {Component, PropTypes} from 'react';
import {connect} from 'react-redux';
import {Table, Icon} from 'antd';
import {Link} from 'react-router';
import {serialize, formatDateTime, tradeStatusToString} from '../../../utils';
import Layout from '../../../components/Layout/Layout';
import MainHeader from '../../../components/MainHeader';
const columns = [
{
title: 'ID',
dataIndex: 'id',
key: 'id',
width: 70
}, {
title: '产品',
dataIndex: 'itemShortTitle',
key: 'itemShortTitle',
render: (shortTitle, record)=>(<span title={shortTitle}>{(shortTitle + '').substring(0, 20)}</span>)
}, {
title: '投资人',
dataIndex: 'buyerName',
key: 'buyerName',
width: 100,
className: 'tac',
}, {
title: '预约额度',
dataIndex: 'reservationAmount',
key: 'reservationAmount',
width: 80,
className: 'tac',
}, {
title: '报单时间',
dataIndex: 'submitReceiptTime',
key: 'submitReceiptTime',
width: 150,
className: 'tac',
render: (submitReceiptTime, record)=>(
<span>
{submitReceiptTime && formatDateTime(submitReceiptTime)}
</span>
)
}, {
title: '状态',
dataIndex: 'status',
key: 'status',
width: 120,
className: 'tac',
render: (status, record)=>(<span data-status={status}>{tradeStatusToString(status)}</span>)
}, {
title: '操作',
key: 'operation',
width: 60,
// fixed:'right',
className: 'tac',
render: (text, record)=>(
<span>
<Link to={'/trades/contract/'+ record.id} onClick={e=>e.stopPropagation()}>审核</Link>
</span>
)
}
];
@connect(state=>({
items: state.remittance.audits,
loading: state.remittance.loading,
total: state.remittance.total,
}))
export default class List extends Component {
constructor(props, context) {
super(props, context);
}
componentDidMount() {
this.fetchList(this.props.location.query);
};
fetchList(query) {
this.props.dispatch({
type: 'FETCH_AUDIT_LIST',
query
});
}
handleRowClick({id}) {
this.props.history.push('/remittance/audits/' + id);
}
render() {
const {total, items, loading, history:{replace}, location:{pathname, query}} = this.props;
const pagination = {
total: total,
pageSize: parseInt(query.s, 10) || 10,
current: parseInt(query.p, 10) || 1,
showSizeChanger: true,
onShowSizeChange: (current, pageSize)=> {
console.log('Current: ', current, '; PageSize: ', pageSize);
query.p = current;
query.s = pageSize;
replace(pathname + '?' + serialize(query));
this.fetchList(query);
},
onChange: (current) => {
console.log('Current: ', current);
query.p = current;
replace(pathname + '?' + serialize(query));
this.fetchList(query);
}
};
const header = (<MainHeader breadcrumb={['审核管理', '报单审核']}
title="审核列表"/>);
return (
<Layout header={header}>
<Table className="ant-table" columns={columns}
dataSource={Array.isArray(items)?items:[]}
loading={loading}
pagination={pagination}
scroll={{ y: window.innerHeight-380 }}
onRowClick={this.handleRowClick.bind(this)}
/>
</Layout>
);
}
}
This diff is collapsed.
import React, {Component, PropTypes} from 'react';
import {connect} from 'react-redux';
import {Form, Input, Button, Checkbox, message, Row, Col} from 'antd';
import {
Row,
Col,
Form,
Input,
Button,
Checkbox,
Select,
message,
Tabs,
Cascader,
Radio,
Upload,
Icon,
Modal,
DatePicker,
Table,
Spin
} from 'antd';
import {
formatDateTime,
formItemLayout,
smallFormItemLayout,
footerFormSubmitLayout,
handleUpload
} from '../../utils';
import Layout from '../../components/Layout/Layout';
import MainHeader from '../../components/MainHeader';
@connect(state=>({
item: state.trade.item
item: state.trade.item,
loading: state.trade.loading
}))
@Form.create()
export default class Commission extends Component {
componentWillMount() {
......@@ -16,45 +46,81 @@ export default class Commission extends Component {
});
};
handleGoBack(e) {
e.preventDefault();
this.props.history.goBack();
};
handleCommission(e){
handleSubmit(e) {
e.preventDefault();
alert('二次确认后发放');
alert('ok');
this.props.dispatch({
type: 'SETTLEMENT_TRADE_ITEM',
id: this.props.item.id
})
}
render() {
const {item} = this.props;
const styles = require('./Item.less');
const tw = 8;
const vw = 16;
const {item, loading, form:{getFieldProps}, location:{query}} = this.props;
const header = (<MainHeader breadcrumb={['订单管理', '订单详情', '佣金发放']}
title={(item && item.shortTitle + ' - ' || '') + '佣金发放'}/>);
return (
<div className={styles.trade}>
<h1 className="tac">佣金发放</h1>
<div className={styles.tradeTable}>
<Row type="flex" justify="space-around" align="middle">
<Col span={tw}>产品</Col>
<Col span={vw}>{item.title}</Col>
</Row>
<Row type="flex" justify="space-around" align="middle">
<Col span={tw}>确认打款金额</Col>
<Col span={vw}>{item.remittanceAmount}</Col>
</Row>
<Row type="flex" justify="space-around" align="middle">
<Col span={tw}>实际佣金</Col>
<Col span={vw}>{item.realReturn && item.realReturn.yj}</Col>
</Row>
</div>
<p>
<Button onClick={this.handleGoBack.bind(this)}>返回</Button>
<Button onClick={this.handleCommission.bind(this)}>发放</Button>
</p>
</div>
<Layout header={header}>
<Spin spinning={loading}>
<Form horizontal onSubmit={this.handleSubmit.bind(this)}>
<Form.Item label="产品" {...smallFormItemLayout}>
<p>{item && item.title}</p>
</Form.Item>
<Form.Item label="确认打款金额" {...smallFormItemLayout}>
<Input placeholder="确认打款金额"
readOnly
{...getFieldProps('remittanceAmount', {
initialValue: item && item.remittanceAmount
})} />
</Form.Item>
<Form.Item label="实际佣金" {...smallFormItemLayout}>
<Input placeholder="实际佣金"
readOnly
{...getFieldProps('realReturn', {
initialValue: item && item.realReturn && item.realReturn.yj
})} />
</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>
);
}
}
// <div className={styles.trade}>
// <div className={styles.tradeTable}>
// <Row type="flex" justify="space-around" align="middle">
// <Col span={tw}>产品</Col>
// <Col span={vw}>{item.title}</Col>
// </Row>
// <Row type="flex" justify="space-around" align="middle">
// <Col span={tw}>确认打款金额</Col>
// <Col span={vw}>{item.remittanceAmount}</Col>
// </Row>
//
// <Row type="flex" justify="space-around" align="middle">
// <Col span={tw}>实际佣金</Col>
// <Col span={vw}>{item.realReturn && item.realReturn.yj}</Col>
// </Row>
// </div>
// <p>
// <Button onClick={this.handleGoBack.bind(this)}>返回</Button>
// {
// (item.status == 11 || item.status == 21) &&
// <Button onClick={this.handleCommission.bind(this)}>发放</Button>
// }
// </p>
// </div>
import React, {Component, PropTypes} from 'react';
import {connect} from 'react-redux';
import {Form, Input, Button, Checkbox, message, Row, Col} from 'antd';
import {
Row,
Col,
Form,
Input,
Button,
Checkbox,
Select,
message,
Tabs,
Cascader,
Radio,
Upload,
Icon,
Modal,
DatePicker,
Table,
Spin
} from 'antd';
import {
formatDateTime,
formItemLayout,
smallFormItemLayout,
footerFormSubmitLayout,
handleUpload
} from '../../utils';
import Layout from '../../components/Layout/Layout';
import MainHeader from '../../components/MainHeader';
@connect(state=>({
item: state.trade.item
loading: state.contract.loading,
trade: state.contract.trade,
shipping: state.contract.shipping
}))
@Form.create()
export default class Contract extends Component {
componentWillMount() {
componentDidMount() {
const {dispatch, params:{id}} = this.props;
dispatch({
type: 'FETCH_TRADE_ITEM',
type: 'FETCH_CONTRACT_ITEM',
id
});
};
handleGoBack(e) {
e.preventDefault();
this.props.history.goBack();
};
handleSubmit(e){
handleSubmit(e) {
e.preventDefault();
alert('实现保存物流订单号的流程');
const data = this.props.form.getFieldsValue();
data.id = this.props.trade.id;
console.log(data);
this.props.dispatch({
type: 'UPDATE_CONTRACT_ITEM',
data
});
}
render() {
const {item} = this.props;
const styles = require('./Item.less');
const tw = 8;
const vw = 16;
const {trade, shipping, loading, form:{getFieldProps}, location:{query}} = this.props;
const header = (<MainHeader breadcrumb={['订单管理', '订单详情', '合同物流']}
title="合同物流详情"/>);
return (
<div className={styles.trade}>
<h1 className="tac">合同物流</h1>
<div className={styles.tradeTable}>
<Row type="flex" justify="space-around" align="middle">
<Col span={tw}>产品</Col>
<Col span={vw}>{item.title}</Col>
</Row>
<Row type="flex" justify="space-around" align="middle">
<Col span={tw}>确认打款金额</Col>
<Col span={vw}>{item.remittanceAmount}</Col>
</Row>
<Row type="flex" justify="space-around" align="middle">
<Col span={tw}>实际佣金</Col>
<Col span={vw}>{item.realReturn && item.realReturn.yj}</Col>
</Row>
<Row type="flex" justify="space-around" align="middle">
<Col span={tw} className="isRequire">顺丰运单</Col>
<Col span={vw}><Input placeholder="请填写顺丰运单编号" /></Col>
</Row>
</div>
<p>
<Button onClick={this.handleGoBack.bind(this)}>返回</Button>
<Button onClick={this.handleSubmit.bind(this)}>保存</Button>
</p>
</div>
<Layout header={header} >
<Spin spinning={loading}>
<Form horizontal onSubmit={this.handleSubmit.bind(this)}>
<Form.Item label="产品" {...smallFormItemLayout}>
<p>{trade && trade.itemTitle}</p>
</Form.Item>
<Form.Item label="顺丰运单" {...smallFormItemLayout}>
<Input placeholder="请填写顺丰运单编号"
{...getFieldProps('expressNO', {
initialValue: shipping && shipping.expressNO
})} />
</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>
);
}
}
This diff is collapsed.
import React, {Component, PropTypes} from 'react';
import {connect} from 'react-redux';
import {Link} from 'react-router';
import {Form, Input, Button, Checkbox, message, Row, Col} from 'antd';
import {Form, Input, Button, Checkbox, message, Row, Col, Spin, Icon} from 'antd';
import {
formatDateTime,
tradeStatusToString,
tradeCreateTypeToString
} from '../../utils';
import Layout from '../../components/Layout/Layout';
import MainHeader from '../../components/MainHeader';
@connect(state=>({
loading: state.trade.loading,
item: state.trade.item
}))
export default class Item extends Component {
componentWillMount() {
componentDidMount() {
const {dispatch, params:{id}} = this.props;
dispatch({
type: 'FETCH_TRADE_ITEM',
......@@ -21,31 +25,37 @@ export default class Item extends Component {
});
};
handleGoBack(e){
handleGoBack(e) {
e.preventDefault();
this.props.history.goBack();
};
render() {
const {item} = this.props;
const {item, loading} = this.props;
const styles = require('./Item.less');
const tw = 8;
const vw = 16;
const header = (<MainHeader breadcrumb={['订单管理', '订单详情']}
title={((item && item.title) ? item.title + ' - ' : '') + '订单详情'}/>);
return (
<Layout header={header}>
{
item ?
<div className={styles.trade}>
<div className={styles.tradeTable}>
<Row type="flex" justify="space-around" align="middle">
<Col span={tw}>产品</Col>
<Col span={vw}>{item.title}</Col>
</Row>
<Row type="flex" justify="space-around" align="middle">
<Col span={tw}>募集开始时间</Col>
<Col span={vw}>{formatDateTime(item.fundRaisedStartTime)}</Col>
<Col
span={vw}>{item.fundRaisedStartTime && formatDateTime(item.fundRaisedStartTime)}</Col>
</Row>
<Row type="flex" justify="space-around" align="middle">
<Col span={tw}>募集结束时间</Col>
<Col span={vw}>{formatDateTime(item.fundRaisedEndTime)}</Col>
<Col
span={vw}>{item.fundRaisedEndTime && formatDateTime(item.fundRaisedEndTime)}</Col>
</Row>
<Row type="flex" justify="space-around" align="middle">
<Col span={tw}>状态</Col>
......@@ -78,11 +88,13 @@ export default class Item extends Component {
</Row>
<Row type="flex" justify="space-around" align="middle">
<Col span={tw}>报单时间</Col>
<Col span={vw}>{formatDateTime(item.submitReceiptTime)}</Col>
<Col
span={vw}>{item.submitReceiptTime && formatDateTime(item.submitReceiptTime)}</Col>
</Row>
<Row type="flex" justify="space-around" align="middle">
<Col span={tw}>打款审核时间</Col>
<Col span={vw}>{formatDateTime(item.remittanceAuditTime)}</Col>
<Col
span={vw}>{item.remittanceAuditTime && formatDateTime(item.remittanceAuditTime)}</Col>
</Row>
<Row type="flex" justify="space-around" align="middle">
<Col span={tw}>确认打款金额</Col>
......@@ -112,15 +124,25 @@ export default class Item extends Component {
</Row>
<Row type="flex" justify="space-around" align="middle">
<Col span={tw}>创建时间</Col>
<Col span={vw}>{formatDateTime(item.dateCreated)}</Col>
<Col span={vw}>{item.dateCreated && formatDateTime(item.dateCreated)}</Col>
</Row>
</div>
<p>
<Button onClick={this.handleGoBack.bind(this)}>返回</Button>
{
(item.status == 11 || item.status == 21) &&
<Link to={'/trades/commission/'+ item.id}><Button>发放佣金</Button></Link>
}
<Link to={'/trades/contract/'+ item.id}><Button>邮寄合同</Button></Link>
<Button onClick={e=>{e.preventDefault(); this.props.history.goBack();}}
style={{marginLeft:'1em'}}>
<Icon type="rollback"/>返回
</Button>
</p>
</div>
:
<Spin loading={loading}/>
}
</Layout>
);
}
......
......@@ -11,7 +11,7 @@
}
.tradeTable {
border-top: 1px solid #e9e9e9;
//border-top: 1px solid #e9e9e9;
border-bottom: 1px solid #e9e9e9;
//max-width: 800px;
//margin: auto;
......
import React, {Component, PropTypes} from 'react';
import {connect} from 'react-redux';
import {Table, Icon} from 'antd';
import { Link } from 'react-router';
import {Table, Icon, Breadcrumb, Row, Col} from 'antd';
import {Link} from 'react-router';
import {serialize, formatDateTime, tradeStatusToString} from '../../utils';
import Layout from '../../components/Layout/Layout';
const columns = [
{
title: '订单ID',
dataIndex: 'id',
key: 'id',
width:80,
width: 70,
// fixed:'left'
}, {
title: '产品',
dataIndex: 'shortTitle',
key: 'shortTitle',
render: (shortTitle, record)=>(<span title={shortTitle}>{(shortTitle + '').substring(0, 20)}</span>)
render: (shortTitle, record)=>(<span title={shortTitle}>{(shortTitle + '').substring(0, 15)}</span>)
}, {
title: '预约时间',
dataIndex: 'reservationTime',
key: 'reservationTime',
width:130,
className:'tac',
width: 150,
className: 'tac',
render: (reservationTime, record)=>(
<span>
{reservationTime && formatDateTime(reservationTime)}
......@@ -33,39 +33,45 @@ const columns = [
title: '投资人',
dataIndex: 'buyerName',
key: 'buyerName',
width:100,
className:'tac',
width: 80,
className: 'tac',
}, {
title: '预约额度',
dataIndex: 'reservationAmount',
key: 'reservationAmount',
width:100,
className:'tac',
width: 100,
className: 'tac',
}, {
title: '实际打款',
dataIndex: 'remittanceAmount',
key: 'remittanceAmount',
width:100,
className:'tac',
width: 100,
className: 'tac',
}, {
title: '进度',
dataIndex: 'status',
key: 'status',
width:150,
className:'tac',
width: 160,
className: 'tac',
render: (status, record)=>(<span data-status={status}>{tradeStatusToString(status)}</span>)
}, {
title: '操作',
key: 'operation',
width:140,
width: 140,
// fixed:'right',
className:'tac',
className: 'tac',
render: (text, record)=>(
<span>
<Link to={'/trades/contract/'+ record.id} onClick={e=>e.stopPropagation()}>合同</Link>
{
(record.status == 11 || record.status == 21) &&
<span>
<span className="ant-divider"></span>
<Link to={'/trades/commission/'+ record.id} onClick={e=>e.stopPropagation()}>佣金</Link>
</span>
}
</span>
)
}
];
......@@ -86,20 +92,20 @@ export default class List extends Component {
this.fetchList(this.props.location.query);
};
fetchList(query){
fetchList(query) {
this.props.dispatch({
type: 'FETCH_TRADE_LIST',
query
});
}
handleRowClick({id}){
this.props.history.push('/trades/'+id);
handleRowClick({id}) {
this.props.history.push('/trades/' + id);
}
render() {
const { total, items, loading, history:{replace}, location:{pathname, query}} = this.props;
const {total, items, loading, history:{replace}, location:{pathname, query}} = this.props;
const pagination = {
total: total,
......@@ -121,13 +127,36 @@ export default class List extends Component {
}
};
return <Table className="ant-table" columns={columns}
const breadcrumb = ['订单管理', '订单列表'];
const header = (
<div className="main-header">
<Row>
<Col span="8">
<Breadcrumb>
{ breadcrumb.map((b, i)=><Breadcrumb.Item key={i}>{b}</Breadcrumb.Item>) }
</Breadcrumb>
</Col>
</Row>
<Row>
<Col span="20">
<h1 className="tac">订单列表</h1>
</Col>
</Row>
</div>
);
return (
<Layout header={header}>
<Table className="ant-table" columns={columns}
dataSource={Array.isArray(items)?items:[]}
loading={loading}
pagination={pagination}
scroll={{ y: window.innerHeight-245 }}
scroll={{ y: window.innerHeight-380 }}
onRowClick={this.handleRowClick.bind(this)}
/>;
/>
</Layout>
);
}
}
......
export Home from './Home/Home';
export NotFound from './NotFound/NotFound';
export Login from './Login/Login';
export App from './App/App';
export ProductList from './Product/List';
export ProductAddItem from './Product/AddItem';
export ProductEditItem from './Product/EditItem';
export TradeList from './Trade/List';
export TradeItem from './Trade/Item';
export Commission from './Trade/Commission';
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/Audit/List';
......@@ -3,8 +3,48 @@
html, body, #root {
height: 100%;
font-size: 14px;
background-color: #e9ecf3;
}
.ant-table{
label,
.ant-form-item {
font-size: 14px !important;
.ant-form-explain {
font-size: 12px;
}
}
.ant-btn {
font-weight: 400 !important;
}
.ant-table {
font-size: 14px !important;
display: flex;
flex-direction: column;
height: 100%;
overflow: hidden;
& > div {
&:first-child {
flex: 1
}
}
}
.ant-menu-vertical,
.ant-menu-inline,
.ant-menu-item-group-list {
& > .ant-menu-item,
& > .ant-menu-submenu > .ant-menu-submenu-title {
.cn {
font-size: 14px;
}
.en {
font-size: 10px;
margin-left: .5em;
opacity: .45;
font-style: italic;
font-weight: 300;
}
}
}
}
......@@ -29,6 +29,15 @@ const announcement = handleActions({
['CREATE_ANNOUNCEMENT_ITEM_FAILED'](state, action){
return {...state, err: action.err, loading: false}
},
['UPDATE_ANNOUNCEMENT_ITEM'](state){
return {...state, loading: true}
},
['UPDATE_ANNOUNCEMENT_ITEM_SUCCESS'](state, action){
return {...state, loading: false, item: action.item}
},
['UPDATE_ANNOUNCEMENT_ITEM_FAILED'](state, action){
return {...state, err: action.err, loading: false}
},
}, {
items: [],
loading: false,
......
import {handleActions} from 'redux-actions';
import {combineReducer} from 'redux';
const contract = handleActions({
['FETCH_CONTRACT_ITEM'](state){
return {...state, loading: true}
},
['FETCH_CONTRACT_ITEM_SUCCESS'](state, action){
return {...state, loading: false, trade:action.trade, shipping:action.shipping}
},
['FETCH_CONTRACT_ITEM_FAILED'](state, action){
return {...state, err: action.err, loading: false}
},
['UPDATE_CONTRACT_ITEM'](state){
return {...state, loading: true}
},
['UPDATE_CONTRACT_ITEM_SUCCESS'](state, action){
return {...state, loading: false, shipping:action.shipping}
},
['UPDATE_CONTRACT_ITEM_FAILED'](state, action){
return {...state, err: action.err, loading: false}
}
}, {
loading: false,
});
export default contract;
import {handleActions} from 'redux-actions';
import {combineReducer} from 'redux';
const audit = handleActions({
['FETCH_AUDIT_LIST'](state) {
return {...state, loading: true,};
},
['FETCH_AUDIT_LIST_SUCCESS'](state, action) {
return {...state, loading: false, audits: action.items, total: action.total};
},
['FETCH_AUDIT_LIST_FAILED'](state, action) {
return {...state, err: action.err, loading: false};
},
['FETCH_AUDIT_ITEM'](state) {
return {...state, loading: true,};
},
['FETCH_AUDIT_ITEM_SUCCESS'](state, action) {
return {...state, loading: false, audit: action.item};
},
['FETCH_AUDIT_ITEM_FAILED'](state, action) {
return {...state, err: action.err, loading: false};
},
}, {
audits: [],
loading: false,
});
export default audit;
import {handleActions} from 'redux-actions';
import {combineReducer} from 'redux';
const initState = {
items: [],
loading: false,
};
const trade = handleActions({
['INIT_TRADE'](){
return {...initState};
},
['FETCH_TRADE_LIST'](state) {
return {...state, loading: true,};
},
......@@ -19,11 +27,25 @@ const trade = handleActions({
},
['FETCH_TRADE_ITEM_FAILED'](state, action){
return {...state, err: action.err, loading: false}
},
['CREATE_TRADE_ITEM'](state){
return {...state, loading: true}
},
['CREATE_TRADE_ITEM_SUCCESS'](state, action){
return {...state, loading: false, item: action.item, createSuccess: true}
},
['CREATE_TRADE_ITEM_FAILED'](state, action){
return {...state, err: action.err, loading: false}
},
['SETTLEMENT_TRADE_ITEM'](state){
return {...state, loading: true};
},
['SETTLEMENT_TRADE_ITEM_SUCCESS'](state, action){
return {...state, loading: false,};
},
['SETTLEMENT_TRADE_ITEM_FAILED'](state, action){
return {...state, err: action.err, loading: false};
}
}, {
item: {},
items: [],
loading: false,
});
}, initState);
export default trade;
import React, {PropTypes, Component} from 'react';
import {Route, IndexRoute, Link} from 'react-router';
import Home from '../containers/Home/Home';
import NotFound from '../containers/NotFound/NotFound';
import Login from '../containers/Login/Login';
import App from '../containers/App/App';
import ProductList from '../containers/Product/List';
import ProductAddItem from '../containers/Product/AddItem';
import ProductEditItem from '../containers/Product/EditItem';
import ProductItem from '../containers/Product/Item';
import TradeList from '../containers/Trade/List';
import TradeItem from '../containers/Trade/Item';
import Commission from '../containers/Trade/Commission';
import Contract from '../containers/Trade/Contract';
import TradeAddItem from '../containers/Trade/AddItem';
import AnnouncementList from '../containers/Announcement/List';
import AnnouncementEditItem from '../containers/Announcement/EditItem';
import AnnouncementAddItem from '../containers/Announcement/AddItem';
import {
Home,
NotFound,
Login,
App,
ProductList,
ProductAddItem,
ProductEditItem,
TradeList,
TradeItem,
Commission,
Contract,
TradeAddItem,
AnnouncementList,
AnnouncementEditItem,
AnnouncementAddItem,
RemittanceAuditList ,
} from '../containers/index';
export default (store)=> {
const requireAuth = (nextState, replace, cb) => {
......@@ -30,28 +31,32 @@ export default (store)=> {
<Route path="/">
<Route onEnter={requireAuth} component={App}>
<IndexRoute component={Home}/>
<Route path="products" >
<IndexRoute component={ProductList} />
<Route path="create" component={ProductAddItem} />
<Route path=":id" component={ProductItem} />
<Route path=":id/edit" component={ProductEditItem} />
<Route path="products">
<IndexRoute component={ProductList}/>
<Route path="create" component={ProductAddItem}/>
<Route path=":id" component={ProductEditItem}/>
</Route>
<Route path="trades" >
<IndexRoute component={TradeList} />
<Route path=":id" component={TradeItem} />
<Route path="commission/:id" component={Commission} />
<Route path="contract/:id" component={Contract} />
<Route path="create/:pid" component={TradeAddItem} />
<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}/>
</Route>
<Route path="announcement">
<IndexRoute component={AnnouncementList} />
<Route path="create" component={AnnouncementAddItem} />
<Route path=":id/edit" component={AnnouncementEditItem} />
<IndexRoute component={AnnouncementList}/>
<Route path="create" component={AnnouncementAddItem}/>
<Route path=":id/edit" component={AnnouncementEditItem}/>
</Route>
<Route path="remittance">
<Route path="audits">
<IndexRoute component={RemittanceAuditList} />
</Route>
</Route>
<Route path="/actived" component={Home}/>
<Route path="/completed" component={Home}/>
</Route>
<Route path="/login" component={Login} />
<Route path="/login" component={Login}/>
<Route path="*" component={NotFound}/>
</Route>
);
......
import {takeLatest} from 'redux-saga';
import {take, call, put, fork, cancel, select} from 'redux-saga/effects';
import {fetchList, fetchItem, createItem} from '../services/announcement';
import {fetchList, fetchItem, createItem, updateItem} from '../services/announcement';
import {message} from 'antd';
function* getList(query) {
......@@ -56,9 +56,10 @@ function* watchItem() {
function* addItem(data) {
try{
const item = yield call(createItem, data);
message.success('创建成功!');
yield put({
type: 'CREATE_ANNOUNCEMENT_ITEM_SUCCESS',
item
item: {...item, ...data}
});
}catch(err){
console.log(err);
......@@ -77,8 +78,33 @@ function* watchAdd() {
}
}
function* editItem(data) {
try{
const item = yield call(updateItem, data);
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) {
const {data} = yield take('UPDATE_ANNOUNCEMENT_ITEM');
yield fork(editItem, data);
}
}
export default function*() {
yield fork(watchList);
yield fork(watchItem);
yield fork(watchAdd);
yield fork(watchEdit);
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -16,7 +16,6 @@ export async function fetchItem(id) {
}
export async function updateItem(item){
return xFetch('/api/products/'+ item.id, {
method:'PUT',
body: serialize(item)
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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