import React, { Component } from 'react';
import { connect } from 'dva';
import { routerRedux } from 'dva/router';
import queryString from 'query-string';
import {
Tooltip,
Popover,
Modal,
Card,
List,
Form,
Table,
Button,
Input,
InputNumber,
Select,
Icon,
} from 'antd';
import PageHeaderLayout from '../../../layouts/PageHeaderLayout';
import FooterToolbar from '../../../components/FooterToolbar';
import TerminalSelectModal from './terminal';
import MerchantProductSelectModal from './product';
import { productType, pageSize, Codes } from '../../../utils/config';
import styles from './index.less';
@Form.create()
@connect(state => ({
terminal: state.terminal,
orderDetail: state.orderDetail,
mproduct: state.mproduct,
}))
export default class CreateOrder extends Component {
state = {
userInfo: {}, //记录终端用户信息
products: [], //记录选择的产品
tableDatas: [], //记录选择的商品
};
// 终端选择弹框,显示 -> 加载数据
handleTerminalSelectBtnClick = () => {
this.props.dispatch({ type: 'orderDetail/showTerminalModal' });
this.props.dispatch({
type: 'terminal/query',
payload: {
pageNo: 1,
pageSize,
}
});
}
// 选择终端
handleTerminalModalOk = (record) => {
this.setState({
userInfo: {
uid: record.id,
userCode: record.code,
userName: record.name,
campusName: record.campusName,
merchantName: record.merchantName,
merchantId: record.merchantId,
contactName: record.contactName,
mobile: record.mobile,
address: record.address,
}
});
this.props.dispatch({ type: 'orderDetail/hideTerminalModal' });
}
handleTerminalModalCancel = () => {
this.props.dispatch({ type: 'orderDetail/hideTerminalModal' });
}
handleTerminalModalSearch = (data) => {
const newData = { ...data };
if (newData.keyword) {
newData[newData.field] = newData.keyword;
}
delete newData.field;
delete newData.keyword;
this.props.dispatch({
type: `terminal/query`,
payload: { ...newData, pageNo: 1, pageSize },
});
}
handleTerminalModalTableChange = (pagination, filterArgs, filters) => {
const newFilters = { ...filters };
if (newFilters.keyword) {
newFilters[newFilters.field] = newFilters.keyword;
}
delete newFilters.field;
delete newFilters.keyword;
const getValue = obj => Object.keys(obj).map(key => obj[key]).join(',');
const tableFilters = Object.keys(filterArgs).reduce((obj, key) => {
const newObj = { ...obj };
newObj[key] = getValue(filterArgs[key]);
return newObj;
}, {});
const data = { ...newFilters, ...tableFilters, pageNo: pagination.current, pageSize: pagination.pageSize };
Object.keys(data).map(key => data[key] ? null : delete data[key]);
this.props.dispatch({ type: `terminal/query`, payload: data });
}
// 产品选择弹框
handleProductSelectBtnClick = () => {
const { userInfo } = this.state;
const { merchantId } = userInfo;
this.props.dispatch({ type: 'orderDetail/showProductModal' });
this.props.dispatch({
type: 'mproduct/query',
payload: {
pageNo: 1,
pageSize,
merchantId,
},
});
}
handleProductModalSearch = (data) => {
const { userInfo } = this.state;
const { merchantId } = userInfo;
const newData = { ...data };
if (newData.keyword) {
newData[newData.field] = newData.keyword;
}
delete newData.field;
delete newData.keyword;
this.props.dispatch({
type: 'mproduct/query',
payload: { ...newData, merchantId, pageNo: 1, pageSize },
});
}
handleProductModalTableChange = (pagination, filterArgs, filters) => {
const { userInfo } = this.state;
const { merchantId } = userInfo;
const newFilters = { ...filters };
if (newFilters.keyword) {
newFilters[newFilters.field] = newFilters.keyword;
}
delete newFilters.field;
delete newFilters.keyword;
const getValue = obj => Object.keys(obj).map(key => obj[key]).join(',');
const tableFilters = Object.keys(filterArgs).reduce((obj, key) => {
const newObj = { ...obj };
newObj[key] = getValue(filterArgs[key]);
return newObj;
}, {});
const data = { ...newFilters, ...tableFilters, pageNo: pagination.current, pageSize: pagination.pageSize, merchantId };
Object.keys(data).map(key => data[key] ? null : delete data[key]);
this.props.dispatch({ type: 'mporduct/query', payload: data });
}
// 选择产品
handleProductModalOk = (data) => {
const formatedData = this.tableDataConventer(data);
this.setState({
products: data || [],
tableDatas: formatedData,
});
this.props.dispatch({ type: 'orderDetail/hideProductModal' });
}
handleProductModalCancel = () => {
this.props.dispatch({ type: 'orderDetail/hideProductModal' });
}
// 对待选的产品进行过滤,如果没有goods则不可选
productListFilter = (list) => {
const newList = [...list];
newList.map(item =>
(!item.goods || item.goods.length == 0) ? item.selectable = true : item.selectable = false);
return newList;
}
handleListItemDel = (record) => {
const { products, tableDatas } = this.state;
Modal.confirm({
title: '确定从清单中删除此商品?',
cancelText: '取消',
okText: '确认',
onOk: () => {
const newProducts = products.filter(item => item.id !== record.key);
const newTableDatas = tableDatas.filter(item => item.key.indexOf(record.key) == -1);
this.setState({
products: newProducts,
tableDatas: newTableDatas,
});
},
});
}
PKGPriceCalculator = (item, tableDatas) => {
// 根据key找到该课程包内的所有配套
const parentId = item.key;
const subSupports = tableDatas.filter(row =>
row.key.indexOf(`${parentId}[sub]`) !== -1 && row.type == Codes.CODE_SUPPORT
);
// 计算该课程包的价格
let sumSupportsPrice = 0;
subSupports.map(one => {
sumSupportsPrice += one.price1 * one.quantity;
});
item.rowSum = item.quantity * item.price3 + sumSupportsPrice;
}
handleInputNumberChange = (record, value) => {
const { tableDatas } = this.state;
const newTableDatas = [...tableDatas];
newTableDatas.map(item => {
if (item.key == record.key) {
item.quantity = value;
if (record.type == Codes.CODE_PACKAGE) {
this.PKGPriceCalculator(item, newTableDatas);
} else if (record.type == Codes.CODE_SUPPORT && item.parent) {
const parentId = item.key.split('[sub]')[0];
newTableDatas.map(item => item.key == parentId ? this.PKGPriceCalculator(item, newTableDatas) : null);
} else {
item.rowSum = item.quantity * item.price3;
}
}
});
this.setState({ tableDatas: newTableDatas });
}
handleSelectChange = (record, value) => {
const { tableDatas } = this.state;
const newTableDatas = [...tableDatas];
newTableDatas.map(item => {
if (item.key == record.key) {
const match = item.options.filter(one => one.goodsId == value)[0];
item.price1 = match.price1;
item.price2 = match.price2;
item.price3 = match.price3;
item.chargeUnit = match.chargeUnit;
item.goodsId = value;
if (record.type == Codes.CODE_PACKAGE) {
this.PKGPriceCalculator(item, newTableDatas);
} else if (record.type == Codes.CODE_SUPPORT && item.parent) {
const parentId = item.key.split('[sub]')[0];
newTableDatas.map(item => item.key == parentId ? this.PKGPriceCalculator(item, newTableDatas) : null);
} else {
item.rowSum = item.quantity * item.price3;
}
}
});
this.setState({ tableDatas: newTableDatas });
}
handlePageCancel = () => {
const { orderDetail, dispatch } = this.props;
const { filters } = orderDetail;
dispatch(routerRedux.push({
pathname: '/order',
search: queryString.stringify(filters),
}));
}
handlePageSubmit = () => {
const { form, dispatch, orderDetail } = this.props;
const { userInfo, tableDatas } = this.state;
const { getFieldsValue, validateFields } = form;
const { filters } = orderDetail;
const { uid } = userInfo;
validateFields((errors) => {
if (errors) return;
const postData = getFieldsValue();
const detailList = [];
tableDatas.map(item => {
const { goodsId, quantity } = item;
if (!item.parent || item.type == Codes.CODE_SUPPORT) {
detailList.push({ goodsId, quantity });
}
});
postData.uid = uid;
postData.goods = detailList;
postData.adjustPrice = 0;
postData.orderStatus = Codes.CODE_UNPAID,
dispatch({
type: 'orderDetail/create',
payload: postData,
callback: () => {
dispatch(routerRedux.push({
pathname: '/order',
search: queryString.stringify(filters),
}));
}
});
});
}
/**
* @desc 对选择的产品列表进行加工,以适应table的展示样式,并进行数量及价格调整
* @param {[json]} data
* @return {[json]}
*/
tableDataConventer = (data) => {
let rowSort = 1;
const formatedData = new Array();
const rowDataMaker = (item) => {
const first = item.goods[0];
return {
name: item.name,
code: item.code,
type: item.type,
goodsId: first.id,
price1: first.cpPrice,
price2: first.merchantPrice,
price3: first.terminalPrice,
rowSum: first.terminalPrice,
chargeUnit: first.chargeUnit,
};
};
data.map(item => {
if (!item.goods || item.goods.length == 0) return;
if (item.type == Codes.CODE_COURSE) {
const newObj = rowDataMaker(item);
newObj.sumRows = 1;
newObj.quantity = 1;
newObj.key = item.id; // table row, type course, key is id
newObj.options = item.goods.map(
one => ({
goodsId: one.id,
price1: one.cpPrice,
price2: one.merchantPrice,
price3: one.terminalPrice,
chargeUnit: one.chargeUnit,
})
);
newObj.rowSort = rowSort;
rowSort += 1;
formatedData.push(newObj);
} else if (item.type == Codes.CODE_SUPPORT) {
const newObj = rowDataMaker(item);
newObj.sumRows = 1;
newObj.quantity = 1;
newObj.key = item.id; // table row, type support, key is id
newObj.rowSort = rowSort;
rowSort += 1;
formatedData.push(newObj);
} else if (item.type == Codes.CODE_PACKAGE) {
const products = item.products;
const specials = item.specials;
// 产品包为一行
const newObj = rowDataMaker(item);
newObj.sumRows = products ? products.length + 1 : 1;
newObj.quantity = 1;
newObj.key = item.id; // table row, type package, key is id
newObj.options = item.goods.map(
one => ({
goodsId: one.id,
price1: one.cpPrice,
price2: one.merchantPrice,
price3: one.terminalPrice,
chargeUnit: one.chargeUnit,
})
);
newObj.rowSort = rowSort;
rowSort += 1;
formatedData.push(newObj);
// 产品包中products每一项为一行
products.map(subItem => {
const matchGoods = specials.filter(specialsItem => specialsItem.pid == subItem.pid)[0];
const newObj = new Object();
newObj.sumRows = 0;
newObj.name = subItem.name;
newObj.code = subItem.code;
newObj.type = subItem.type;
newObj.key = `${item.id}[sub]${subItem.id}`; // table row, type package subPro, key is pkgId[sub]pid
// 产品包中的配套 - 显示价格及支持数量调整
if (subItem.type == Codes.CODE_SUPPORT) {
newObj.parent = true;
newObj.goodsId = matchGoods.id;
newObj.chargeUnit = '件';
newObj.price1 = matchGoods.cpPrice;
newObj.price2 = '-';
newObj.price3 = '-';
newObj.quantity = 0;
// 产品包中的课程 - 不显示价格并且不支持数量调整
} else if (subItem.type == Codes.CODE_COURSE) {
newObj.parent = true;
newObj.chargeUnit = '-';
newObj.price1 = '-';
newObj.price2 = '-';
newObj.price3 = '-';
newObj.quantity = '-';
}
formatedData.push(newObj);
});
}
});
return formatedData;
}
render() {
const { orderDetail, terminal, mproduct, form } = this.props;
const { userInfo, products, tableDatas } = this.state;
const { getFieldDecorator } = form;
const { terminalModalShow, productModalShow } = orderDetail;
const listData = tableDatas;
const productList = this.productListFilter(mproduct.list);
const formItemLayout = {
labelCol: {
xs: { span: 24 },
sm: { span: 2 },
},
wrapperCol: {
xs: { span: 24 },
sm: { span: 12 },
md: { span: 22 },
},
};
const columns = [{
title: '序号',
dataIndex: 'rowSort',
width: '6%',
key: 0,
render: (text, row) => ({ children: text, props: { rowSpan: row.sumRows } }),
},{
title: '编号',
dataIndex: 'code',
key: 1,
width: '10%',
},{
title: '名称',
dataIndex: 'name',
key: 2,
width: '10%',
},{
title: '类型',
dataIndex: 'type',
key: 3,
render: (text) => productType[text],
width: '10%',
},{
title: '价格类型',
dataIndex: 'goods',
key: 4,
render: (text, row) => {
// 既不是单独课程也不是课程包里的配套
if (!row.options && row.type !== Codes.CODE_SUPPORT) {
return '-';
// 单独的课程
} else if (row.options) {
return (
);
// 课程包里的配套(显示价格和数量)
} else if (!row.options && row.type == Codes.CODE_SUPPORT) {
return `¥${row.price1} / ${row.chargeUnit}`;
}
},
width: '13%',
},{
title: '供应商售价(¥)',
dataIndex: 'price1',
key: 5,
width: '10%',
},{
title: '领教售价(¥)',
dataIndex: 'price2',
key: 6,
width: '10%',
},{
title: '渠道售价(¥)',
dataIndex: 'price3',
key: 7,
width: '10%',
},{
title: '数量',
dataIndex: 'quantity',
key: 8,
render: (text, row) => {
// 课程
if (row.type == Codes.CODE_COURSE && !row.parent) {
return (
this.handleInputNumberChange(row, value)}
min={1}
placeholder="请填写"
/>
);
// 配套
} else if (row.type == Codes.CODE_SUPPORT && !row.parent) {
return (
this.handleInputNumberChange(row, value)}
min={1}
placeholder="请填写"
/>
);
// 课程包
} else if (row.type == Codes.CODE_PACKAGE) {
return (
this.handleInputNumberChange(row, value)}
min={1}
placeholder="请填写"
/>
);
// 课程包内的配套
} else if (row.type == Codes.CODE_SUPPORT && row.parent) {
return (
this.handleInputNumberChange(row, value)}
min={0}
placeholder="请填写"
/>
);
} else {
return text;
}
},
width: '6%',
},{
title: '小计(¥)',
dataIndex: 'rowSum',
key: 9,
render: (text, row) => ({ children: text, props: { rowSpan: row.sumRows } }),
width: '8%',
},{
title: '操作',
dataIndex: 'operation',
key: 10,
render: (text, row) => ({ children: this.handleListItemDel(row)}>删除, props: { rowSpan: row.sumRows } }),
width: '7%',
}];
let total = 0;
listData.map(item => item.rowSum ? total += item.rowSum : null);
return (
{userInfo.userCode ?
{item}}
/>
: null}
{getFieldDecorator('name', {
rules: [{ required: true, type: 'string', message: '请填写收货人!' }],
initialValue: userInfo.contactName,
})(
)}
{getFieldDecorator('mobile', {
rules: [{ required: true, type: 'string', message: '请填写联系电话!' }],
initialValue: userInfo.mobile,
})(
)}
{getFieldDecorator('address', {
rules: [{ required: true, type: 'string', message: '请填写收货地址!' }],
initialValue: userInfo.address,
})(
)}
{getFieldDecorator('note', {
initialValue: userInfo.note,
})(
)}
{userInfo.merchantId ?
:
}
{`价格总计: ${total}元`}}
/>
{/*终端选择弹框*/}
{/*渠道产品选择弹框*/}
);
}
}