/* eslint-disable no-trailing-spaces */ import React, { Component } from 'react'; import { connect } from 'dva'; import { Tooltip, Card, Modal, Form, Table, List, Steps, Select, Button, Input, Icon } from 'antd'; import Ellipsis from '../../../components/Ellipsis'; import Selector from '../../../components/AXTableSelector/Selector'; import FooterToolbar from '../../../components/FooterToolbar'; import { checkProductType, toDecimal2 } from '../../../utils/utils'; import { Hotax } from '../../../utils/config'; import styles from './OrderCreate.less'; const formItemLayout = { labelCol: { xs: { span: 24 }, sm: { span: 7 }, }, wrapperCol: { xs: { span: 24 }, sm: { span: 14 }, md: { span: 10 }, }, }; @connect(({ terminal, shelves, trade, loading }) => ({ trade, shelves, terminal, sLoading: loading.models.shelves, tLoading: loading.models.terminal, submitting: loading.models.trade, })) @Form.create() export default class OrderCreatePage extends Component { state = { currentStep: 0, selectedGoods: [], adjustPrice: 0, deliveryInfo: {}, terminalSelectorDestroy: true, goodsSelectorDestroy: true, packageFixModalDestroy: true, packageContent: {}, width: '100%', }; componentDidMount() { // 监听视图窗口变化 window.addEventListener('resize', this.resizeFooterToolbar); this.resizeFooterToolbar(); } componentWillUnmount() { window.removeEventListener('resize', this.resizeFooterToolbar); } resizeFooterToolbar = () => { const sider = document.querySelectorAll('.ant-layout-sider')[0]; const width = `calc(100% - ${sider.style.width})`; if (this.state.width !== width) { this.setState({ width }); } }; // 终端模态选择器显示 handleTerminalSelectorModalShow = () => { this.setState({ terminalSelectorDestroy: false, }); this.props.dispatch({ type: 'terminal/fetchTerminalList', payload: {}, }); }; // 终端模态选择器完成 handleTerminalSelectorFinish = (rows) => { this.setState({ terminalSelectorDestroy: true, }); if (!rows || !rows.length) { return; } const { id, code, name, campusName, merchantId, contactName, mobile, address, } = rows[0]; this.setState({ deliveryInfo: { id, code, name, campusName, merchantId, contactName, mobile, address, }, }); }; // 终端模态选择器取消 handleTerminalSelectorCancel = () => { this.setState({ terminalSelectorDestroy: true, }); }; // 终端模态选择器变化 handleTerminalSelectorChange = (params) => { this.props.dispatch({ type: 'terminal/fetchTerminalList', payload: params, }); }; // 商品模态选择器展现 handleGoodsSelectorModalShow = () => { const { deliveryInfo } = this.state; const { merchantId } = deliveryInfo; this.setState({ goodsSelectorDestroy: false, }); this.props.dispatch({ type: 'shelves/fetchItemList', payload: { merchantId }, }); }; // 商品模态选择器变化 handleGoodsSelectorChange = (params) => { const { deliveryInfo } = this.state; const { merchantId } = deliveryInfo; this.props.dispatch({ type: 'shelves/fetchItemList', payload: { merchantId, ...params }, }); }; // 商品模态选择器完成 handleGoodsSelectorFinish = (rows) => { // 去掉没有定价的商品 const newRows = rows.filter((row) => { return !(!row.goods || !row.goods.length); }); this.setState({ goodsSelectorDestroy: true, selectedGoods: newRows, }); }; // 商品模态选择器取消 handleGoodsSelectorCancel = () => { this.setState({ goodsSelectorDestroy: true, }); }; // 套餐包详情模态框展现 handlePackageFixModalShow = (contents) => { this.setState({ packageFixModalDestroy: false, packageContent: contents, }); }; // 套餐包详情模态框取消 handlePackageFixCancel = () => { this.setState({ packageFixModalDestroy: true, }); }; // 响应价格变化 handleGoodsSelectChange = (rowIndex, goodsId) => { const { selectedGoods } = this.state; const targetRow = selectedGoods[rowIndex]; const { goods } = targetRow; const targetGoods = goods.find(goodsItem => goodsItem.id === goodsId); if (targetGoods) { targetRow.selectedGoodsId = targetGoods.id; targetRow.selectedChargeUnit = targetGoods.chargeUnit; targetRow.selectedPrice = targetGoods.merchantPrice; selectedGoods[rowIndex] = targetRow; this.setState({ selectedGoods }); } }; // 响应数量变化 - 填写 handleQuantityInputChange = (rowIndex, e) => { const { selectedGoods } = this.state; const targetRow = selectedGoods[rowIndex]; targetRow.quantity = e.target.value; selectedGoods[rowIndex] = targetRow; this.setState({ selectedGoods }); }; // 响应数量变化 - 加减 handleQuantityStepChange = (rowIndex, type) => { const { selectedGoods } = this.state; const targetRow = selectedGoods[rowIndex]; const { quantity } = targetRow; if (type === 'plus') { targetRow.quantity = quantity + 1; } else if (type === 'minus' && quantity > 1) { targetRow.quantity = quantity - 1; } selectedGoods[rowIndex] = targetRow; this.setState({ selectedGoods }); }; // 优惠价格调整 handleAdjustPriceChange = (value) => { this.setState({ adjustPrice: value }); }; // 下一步 nextStep = () => { const { currentStep } = this.state; if (currentStep === 0) { this.props.form.validateFieldsAndScroll((error, values) => { if (!error) { this.setState({ currentStep: this.state.currentStep + 1, deliveryInfo: { ...this.state.deliveryInfo, ...values, }, }); } }); return; } this.setState({ currentStep: this.state.currentStep + 1 }); }; // 上一步 prevStep = () => { this.setState({ currentStep: this.state.currentStep - 1 }); }; // 提交订单 handleSubmitOrder = (goodsList) => { const { deliveryInfo, adjustPrice } = this.state; const { id, contactName, mobile, address } = deliveryInfo; const goods = goodsList.map(item => ({ goodsId: item.selectedGoodsId, quantity: item.quantity, })); const jsonBody = { mobile, address, goods, adjustPrice, uid: id, name: contactName, status: Hotax.ORDER_UNPAID, }; this.props.dispatch({ type: 'trade/createOrderItem', payload: jsonBody, }); }; render() { const { currentStep, selectedGoods, adjustPrice = 0, deliveryInfo, packageContent, terminalSelectorDestroy, goodsSelectorDestroy, packageFixModalDestroy, } = this.state; const { code, name, campusName, contactName, mobile, address, } = deliveryInfo; const { terminal, tLoading, shelves, sLoading, form } = this.props; const { getFieldDecorator } = form; // ##### Card1: 终端选择及收货信息填写 ##### const terminalInfoCard = () => { const getTerminalModal = () => { return ( ); }; return (
选择终端} > {item}} /> {getFieldDecorator('contactName', { rules: [{ required: true, message: '请填写收货人' }], initialValue: contactName, })( )} {getFieldDecorator('address', { rules: [{ required: true, message: '请填写收货地址' }], initialValue: address, })( )} {getFieldDecorator('mobile', { rules: [ { required: true, message: '请填写联系电话', }, { pattern: /^[1][34578][0-9]{9}$/g, message: '请输入11位有效手机号!', }, ], initialValue: mobile, })( )}
{!terminalSelectorDestroy && getTerminalModal()}
); }; // ##### Card2: 商品选择 ##### const rowDataFormatter = (rows) => { // 默认选定第一个价格类型 const findSelectedPrice = (goodsArr) => { if (!goodsArr) { return; } let selectedGoodsId = null; let selectedChargeUnit = null; let selectedPrice = null; goodsArr.forEach((item, index) => { if (index === 0) { selectedGoodsId = item.id; selectedChargeUnit = item.chargeUnit; selectedPrice = parseInt(item.merchantPrice, 10); } }); return { selectedGoodsId, selectedChargeUnit, selectedPrice }; }; const newRows = []; for (let row of rows) { // 设置默认数量 if (!row.quantity) { row.quantity = 1; } // 设置默认选中价格 if (!row.selectedGoodsId) { const price = findSelectedPrice(row.goods); row = { ...row, ...price }; } // 小计 row.subTotal = row.quantity * row.selectedPrice; newRows.push(row); } return newRows; }; // 按需求处理后的数据 const formattedDataSource = rowDataFormatter(selectedGoods); // 计算总价 const computeTotalPrice = (rows) => { let sum = 0; rows.forEach((row) => { sum += row.subTotal; }); return sum; }; const totalPrice = computeTotalPrice(formattedDataSource); const goodsSelectCard = () => { const getGoodsModal = () => { return ( ); }; // 修正课程包内配套数量 const getPackageFixModal = () => { const { products } = packageContent; const packageColumns = [{ title: '产品编号', dataIndex: 'code', key: 'code', width: '20%', }, { title: '产品名称', dataIndex: 'name', key: 'name', width: '40%', }, { title: '产品类型', dataIndex: 'type', key: 'type', render: text => checkProductType(text), width: '20%', align: 'center', }, { title: '单价', dataIndex: 'merchantPrice', key: 'merchantPrice', width: '20%', render: (text, record) => { if (record.type !== Hotax.PRODUCT_SUPPORT) { return '-'; } return `¥${text}/件`; }, align: 'center', /* TODO: 套餐包内配套数量修改 }, { title: '数量', dataIndex: 'quantity', key: 'quantity', width: '20%', render: (text, record, index) => { if (record.type !== Hotax.PRODUCT_SUPPORT) { return '-'; } return ( this.handleQuantityStepChange(index, 'minus', record.id)} /> } addonAfter={ this.handleQuantityStepChange(index, 'plus', record.id)} /> } value={text} onChange={e => this.handleQuantityInputChange(index, e, record.id)} /> ); }, align: 'center', */ }]; return ( record.id} scroll={{ y: 500 }} /> ); }; const goodsColumns = [{ title: '商品编号', dataIndex: 'code', key: 0, render: (text, record) => { if (record.type === Hotax.PRODUCT_PACKAGE) { return ( this.handlePackageFixModalShow(record)}>{text} ); } return text; }, width: '17%', }, { title: '商品名称', dataIndex: 'name', key: 1, width: '28%', render: text => ( {text} ), }, { title: '商品类型', key: 2, dataIndex: 'type', render: text => checkProductType(text), width: '12%', align: 'center', }, { title: '单价', key: 3, dataIndex: 'goods', render: (goodsArr, record, index) => { if (!goodsArr) { return null; } return ( ); }, width: '12%', align: 'center', }, { title: '数量', key: 4, dataIndex: 'quantity', width: '13%', render: (text, _, index) => { return ( this.handleQuantityStepChange(index, 'minus')} /> } addonAfter={ this.handleQuantityStepChange(index, 'plus')} /> } value={text} onChange={e => this.handleQuantityInputChange(index, e)} /> ); }, align: 'center', }, { title: '小计', key: 5, dataIndex: 'subTotal', width: '13%', render: text => ( {`¥${text}`} ), align: 'center', }]; return ( 选择商品} style={{ marginTop: 10, marginBottom: 70 }} >
record.id} /> {!goodsSelectorDestroy && getGoodsModal()} {!packageFixModalDestroy && getPackageFixModal()} ); }; // ##### Card3: 确认订单 ##### const confirmInfoCard = () => { const columns = [{ title: '商品名称', dataIndex: 'name', key: 1, width: '20%', }, { title: '商品编号', dataIndex: 'code', key: 2, width: '20%', }, { title: '商品类型', dataIndex: 'type', key: 3, align: 'center', render: text => checkProductType(text), width: '12%', }, { title: '单价', dataIndex: 'selectedPrice', key: 4, align: 'center', render: text => `¥${text}`, width: '12%', }, { title: '数量', dataIndex: 'quantity', key: 5, align: 'center', render: text => `×${text}`, width: '12%', }, { title: '单位', dataIndex: 'selectedChargeUnit', key: 6, align: 'center', width: '12%', }, { title: '小计', dataIndex: 'subTotal', key: 7, align: 'center', render: text => `¥${text}`, width: '12%', }]; return (
record.id} dataSource={formattedDataSource} /> {item}} /> ); }; // 步骤条配置 const steps = [{ title: '选择购买终端', stepKey: 0, icon: 'shop', content: terminalInfoCard(), }, { title: '选择商品', stepKey: 1, icon: 'environment', content: goodsSelectCard(), }, { title: '确认订单', stepKey: 2, icon: 'profile', content: confirmInfoCard(), }]; return (
{steps.map((item, index) => ( } /> ) )} {steps[currentStep].content} 已选择  {selectedGoods.length}  件商品 {/* 优惠:  ¥  */} 总价:    {`¥ ${toDecimal2(totalPrice - adjustPrice)}`}
} style={{ width: this.state.width }} > { (currentStep > 0) && ( ) } {/* 步骤一:选择终端 */} { (currentStep === 0) && ( ) } {/* 步骤二:选择产品 */} { (currentStep === 1) && ( ) } {/* 步骤三:确认订单 */} { (currentStep === 2) && ( ) } ); } }