Merge remote-tracking branch 'origin/master'

This commit is contained in:
YunaiV 2019-03-31 18:43:49 +08:00
commit 7fe2541e2e
28 changed files with 1946 additions and 83 deletions

View File

@ -65,7 +65,7 @@ if (APP_TYPE === 'site') {
export default { export default {
// add for transfer to umi // add for transfer to umi
base: basePath, base: basePath,
publicPath: basePath, // publicPath: basePath,
plugins, plugins,
define: { define: {
APP_TYPE: APP_TYPE || '', APP_TYPE: APP_TYPE || '',

View File

@ -69,6 +69,11 @@ export default [
name: 'order-list', name: 'order-list',
component: './Order/OrderList', component: './Order/OrderList',
}, },
{
path: '/order/order-refunds',
name: 'order-refunds',
component: './Order/OrderRefunds',
},
], ],
}, },
// product // product

View File

@ -0,0 +1,8 @@
// import React, { PureComponent } from 'react';
// import {} from 'antd';
//
// export default class OrderTable extends PureComponent {
// render() {
// return <div>cc</div>;
// }
// }

View File

@ -52,6 +52,7 @@ export default {
// 订单 // 订单
'menu.order': '订单管理', 'menu.order': '订单管理',
'menu.order.order-list': '订单管理', 'menu.order.order-list': '订单管理',
'menu.order.order-refunds': '退货维权',
// 营销相关 // 营销相关
'menu.promotion.promotion-banner-list': 'Banner 管理' 'menu.promotion.promotion-banner-list': 'Banner 管理',
}; };

View File

@ -0,0 +1,25 @@
// import { cancelOrder } from '../../services/order';
//
// export default {
// namespace: 'orderDelivery',
//
// state: {
// orderId: 0,
// visible: false,
// },
//
// effects: {
// *getLogistics({ payload }, { call, put }) {},
// },
//
// reducers: {
// changeVisible(state, { payload }) {
// const { orderId, visible } = payload;
// return {
// ...state,
// orderId,
// visible,
// };
// },
// },
// };

View File

@ -1,5 +1,11 @@
import { message } from 'antd'; import { message } from 'antd';
import { orderPage, updateOrderItem, updateOrderItemPayAmount } from '../../services/order'; import {
orderPage,
updateOrderItem,
updateOrderItemPayAmount,
updateRemark,
cancelOrder,
} from '../../services/order';
export default { export default {
namespace: 'orderList', namespace: 'orderList',
@ -18,6 +24,12 @@ export default {
orderId: 0, orderId: 0,
orderItemId: 0, orderItemId: 0,
searchParams: {}, searchParams: {},
remarkVisible: false,
remark: '',
orderCancelVisible: false,
orderCancelShowOther: false,
}, },
effects: { effects: {
@ -70,6 +82,40 @@ export default {
}, },
}); });
yield put({
type: 'queryPage',
payload: {
...searchParams,
},
});
},
*updateRemake({ payload }, { call, put }) {
const { searchParams, params } = payload;
yield call(updateRemark, params);
yield put({
type: 'changeRemakeVisible',
payload: {
remarkVisible: false,
},
});
yield put({
type: 'queryPage',
payload: {
...searchParams,
},
});
},
*cancelOrder({ payload }, { call, put }) {
const { searchParams, params } = payload;
yield call(cancelOrder, params);
yield put({
type: 'changeOrderCancelVisible',
payload: {
orderCancelVisible: false,
},
});
yield put({ yield put({
type: 'queryPage', type: 'queryPage',
payload: { payload: {
@ -99,5 +145,23 @@ export default {
...payload, ...payload,
}; };
}, },
changeRemakeVisible(state, { payload }) {
return {
...state,
...payload,
};
},
changeOrderCancelVisible(state, { payload }) {
return {
...state,
...payload,
};
},
changeOrderCancelShowOther(state, { payload }) {
return {
...state,
...payload,
};
},
}, },
}; };

View File

@ -0,0 +1,84 @@
import React from 'react';
import { Form, Input, Modal } from 'antd';
import DictionarySelect from '@/components/Dictionary/DictionarySelect';
import dictionary from '@/utils/dictionary';
const FormItem = Form.Item;
// 订单 - 更新支付金额
const OrderCancel = Form.create()(props => {
const { form, dispatch, loading } = props;
const { orderId, orderCancelVisible, orderCancelShowOther, searchParams } = props.orderList;
const { getFieldDecorator } = props.form;
const handleOk = e => {
e.preventDefault();
form.validateFields((err, fields) => {
if (err) return;
dispatch({
type: 'orderList/cancelOrder',
payload: {
params: {
orderId,
reasons: fields.reasons,
otherReasons: fields.otherReasons,
},
searchParams,
},
});
});
};
const handleCancel = () => {
dispatch({
type: 'orderList/changeRemakeVisible',
payload: {
remarkVisible: false,
},
});
};
const handleReasonsChange = key => {
dispatch({
type: 'orderList/changeOrderCancelShowOther',
payload: {
orderCancelShowOther: key === '20',
},
});
};
return (
<Modal
destroyOnClose
title="取消订单"
visible={orderCancelVisible}
onOk={handleOk}
okText="保存"
onCancel={handleCancel}
confirmLoading={loading}
>
<FormItem labelCol={{ span: 5 }} wrapperCol={{ span: 15 }} label="原因">
{getFieldDecorator('reasons', {
rules: [{ required: true, message: '请选择取消原因!' }],
})(
<DictionarySelect
onChange={handleReasonsChange}
style={{ minWidth: '100%' }}
dicKey={dictionary.ORDER_CANCEL_REASONS}
/>
)}
</FormItem>
{orderCancelShowOther ? (
<FormItem labelCol={{ span: 5 }} wrapperCol={{ span: 15 }} label="其他原因">
{getFieldDecorator('otherReasons', {
rules: [{ required: true, message: '请输填写退款原因!' }],
})(<Input.TextArea autosize={{ minRows: 3, maxRows: 6 }} placeholder="请输入退款原因" />)}
</FormItem>
) : (
''
)}
</Modal>
);
});
export default OrderCancel;

View File

@ -0,0 +1,5 @@
// import React, { PureComponent } from 'react';
//
// class OrderDelivery extends PureComponent {}
//
// export default OrderDelivery;

View File

@ -0,0 +1,691 @@
import React, { PureComponent, Fragment } from 'react';
import { connect } from 'dva';
import moment from 'moment';
import router from 'umi/router';
import {
Row,
Col,
Card,
Form,
Input,
Select,
Icon,
Button,
Dropdown,
Menu,
InputNumber,
DatePicker,
Modal,
message,
Badge,
Divider,
Steps,
Radio,
} from 'antd';
import StandardTable from '@/components/StandardTable';
import PageHeaderWrapper from '@/components/PageHeaderWrapper';
import styles from './OrderDetails.less';
const FormItem = Form.Item;
const { Step } = Steps;
const { TextArea } = Input;
const { Option } = Select;
const RadioGroup = Radio.Group;
const getValue = obj =>
Object.keys(obj)
.map(key => obj[key])
.join(',');
const statusMap = ['default', 'processing', 'success', 'error'];
const status = ['关闭', '运行中', '已上线', '异常'];
const CreateForm = Form.create()(props => {
const { modalVisible, form, handleAdd, handleModalVisible } = props;
const okHandle = () => {
form.validateFields((err, fieldsValue) => {
if (err) return;
form.resetFields();
handleAdd(fieldsValue);
});
};
return (
<Modal
destroyOnClose
title="新建规则"
visible={modalVisible}
onOk={okHandle}
onCancel={() => handleModalVisible()}
>
<FormItem labelCol={{ span: 5 }} wrapperCol={{ span: 15 }} label="描述">
{form.getFieldDecorator('desc', {
rules: [{ required: true, message: '请输入至少五个字符的规则描述!', min: 5 }],
})(<Input placeholder="请输入" />)}
</FormItem>
</Modal>
);
});
@Form.create()
class UpdateForm extends PureComponent {
static defaultProps = {
handleUpdate: () => {},
handleUpdateModalVisible: () => {},
values: {},
};
constructor(props) {
super(props);
this.state = {
formVals: {
name: props.values.name,
desc: props.values.desc,
key: props.values.key,
target: '0',
template: '0',
type: '1',
time: '',
frequency: 'month',
},
currentStep: 0,
};
this.formLayout = {
labelCol: { span: 7 },
wrapperCol: { span: 13 },
};
}
handleNext = currentStep => {
const { form, handleUpdate } = this.props;
const { formVals: oldValue } = this.state;
form.validateFields((err, fieldsValue) => {
if (err) return;
const formVals = { ...oldValue, ...fieldsValue };
this.setState(
{
formVals,
},
() => {
if (currentStep < 2) {
this.forward();
} else {
handleUpdate(formVals);
}
}
);
});
};
backward = () => {
const { currentStep } = this.state;
this.setState({
currentStep: currentStep - 1,
});
};
forward = () => {
const { currentStep } = this.state;
this.setState({
currentStep: currentStep + 1,
});
};
renderContent = (currentStep, formVals) => {
const { form } = this.props;
if (currentStep === 1) {
return [
<FormItem key="target" {...this.formLayout} label="监控对象">
{form.getFieldDecorator('target', {
initialValue: formVals.target,
})(
<Select style={{ width: '100%' }}>
<Option value="0">表一</Option>
<Option value="1">表二</Option>
</Select>
)}
</FormItem>,
<FormItem key="template" {...this.formLayout} label="规则模板">
{form.getFieldDecorator('template', {
initialValue: formVals.template,
})(
<Select style={{ width: '100%' }}>
<Option value="0">规则模板一</Option>
<Option value="1">规则模板二</Option>
</Select>
)}
</FormItem>,
<FormItem key="type" {...this.formLayout} label="规则类型">
{form.getFieldDecorator('type', {
initialValue: formVals.type,
})(
<RadioGroup>
<Radio value="0"></Radio>
<Radio value="1"></Radio>
</RadioGroup>
)}
</FormItem>,
];
}
if (currentStep === 2) {
return [
<FormItem key="time" {...this.formLayout} label="开始时间">
{form.getFieldDecorator('time', {
rules: [{ required: true, message: '请选择开始时间!' }],
})(
<DatePicker
style={{ width: '100%' }}
showTime
format="YYYY-MM-DD HH:mm:ss"
placeholder="选择开始时间"
/>
)}
</FormItem>,
<FormItem key="frequency" {...this.formLayout} label="调度周期">
{form.getFieldDecorator('frequency', {
initialValue: formVals.frequency,
})(
<Select style={{ width: '100%' }}>
<Option value="month"></Option>
<Option value="week"></Option>
</Select>
)}
</FormItem>,
];
}
return [
<FormItem key="name" {...this.formLayout} label="规则名称">
{form.getFieldDecorator('name', {
rules: [{ required: true, message: '请输入规则名称!' }],
initialValue: formVals.name,
})(<Input placeholder="请输入" />)}
</FormItem>,
<FormItem key="desc" {...this.formLayout} label="规则描述">
{form.getFieldDecorator('desc', {
rules: [{ required: true, message: '请输入至少五个字符的规则描述!', min: 5 }],
initialValue: formVals.desc,
})(<TextArea rows={4} placeholder="请输入至少五个字符" />)}
</FormItem>,
];
};
renderFooter = currentStep => {
const { handleUpdateModalVisible, values } = this.props;
if (currentStep === 1) {
return [
<Button key="back" style={{ float: 'left' }} onClick={this.backward}>
上一步
</Button>,
<Button key="cancel" onClick={() => handleUpdateModalVisible(false, values)}>
取消
</Button>,
<Button key="forward" type="primary" onClick={() => this.handleNext(currentStep)}>
下一步
</Button>,
];
}
if (currentStep === 2) {
return [
<Button key="back" style={{ float: 'left' }} onClick={this.backward}>
上一步
</Button>,
<Button key="cancel" onClick={() => handleUpdateModalVisible(false, values)}>
取消
</Button>,
<Button key="submit" type="primary" onClick={() => this.handleNext(currentStep)}>
完成
</Button>,
];
}
return [
<Button key="cancel" onClick={() => handleUpdateModalVisible(false, values)}>
取消
</Button>,
<Button key="forward" type="primary" onClick={() => this.handleNext(currentStep)}>
下一步
</Button>,
];
};
render() {
const { updateModalVisible, handleUpdateModalVisible, values } = this.props;
const { currentStep, formVals } = this.state;
return (
<Modal
width={640}
bodyStyle={{ padding: '32px 40px 48px' }}
destroyOnClose
title="规则配置"
visible={updateModalVisible}
footer={this.renderFooter(currentStep)}
onCancel={() => handleUpdateModalVisible(false, values)}
afterClose={() => handleUpdateModalVisible()}
>
<Steps style={{ marginBottom: 28 }} size="small" current={currentStep}>
<Step title="基本信息" />
<Step title="配置规则属性" />
<Step title="设定调度周期" />
</Steps>
{this.renderContent(currentStep, formVals)}
</Modal>
);
}
}
/* eslint react/no-multi-comp:0 */
@connect(({ rule, loading }) => ({
rule,
loading: loading.models.rule,
}))
@Form.create()
class TableList extends PureComponent {
state = {
modalVisible: false,
updateModalVisible: false,
expandForm: false,
selectedRows: [],
formValues: {},
stepFormValues: {},
};
columns = [
{
title: '规则名称',
dataIndex: 'name',
render: text => <a onClick={() => this.previewItem(text)}>{text}</a>,
},
{
title: '描述',
dataIndex: 'desc',
},
{
title: '服务调用次数',
dataIndex: 'callNo',
sorter: true,
render: val => `${val}`,
// mark to display a total number
needTotal: true,
},
{
title: '状态',
dataIndex: 'status',
filters: [
{
text: status[0],
value: 0,
},
{
text: status[1],
value: 1,
},
{
text: status[2],
value: 2,
},
{
text: status[3],
value: 3,
},
],
render(val) {
return <Badge status={statusMap[val]} text={status[val]} />;
},
},
{
title: '上次调度时间',
dataIndex: 'updatedAt',
sorter: true,
render: val => <span>{moment(val).format('YYYY-MM-DD HH:mm:ss')}</span>,
},
{
title: '操作',
render: (text, record) => (
<Fragment>
<a onClick={() => this.handleUpdateModalVisible(true, record)}>配置</a>
<Divider type="vertical" />
<a href="">订阅警报</a>
</Fragment>
),
},
];
componentDidMount() {
const { dispatch } = this.props;
dispatch({
type: 'rule/fetch',
});
}
handleStandardTableChange = (pagination, filtersArg, sorter) => {
const { dispatch } = this.props;
const { formValues } = this.state;
const filters = Object.keys(filtersArg).reduce((obj, key) => {
const newObj = { ...obj };
newObj[key] = getValue(filtersArg[key]);
return newObj;
}, {});
const params = {
currentPage: pagination.current,
pageSize: pagination.pageSize,
...formValues,
...filters,
};
if (sorter.field) {
params.sorter = `${sorter.field}_${sorter.order}`;
}
dispatch({
type: 'rule/fetch',
payload: params,
});
};
previewItem = id => {
router.push(`/profile/basic/${id}`);
};
handleFormReset = () => {
const { form, dispatch } = this.props;
form.resetFields();
this.setState({
formValues: {},
});
dispatch({
type: 'rule/fetch',
payload: {},
});
};
toggleForm = () => {
const { expandForm } = this.state;
this.setState({
expandForm: !expandForm,
});
};
handleMenuClick = e => {
const { dispatch } = this.props;
const { selectedRows } = this.state;
if (selectedRows.length === 0) return;
switch (e.key) {
case 'remove':
dispatch({
type: 'rule/remove',
payload: {
key: selectedRows.map(row => row.key),
},
callback: () => {
this.setState({
selectedRows: [],
});
},
});
break;
default:
break;
}
};
handleSelectRows = rows => {
this.setState({
selectedRows: rows,
});
};
handleSearch = e => {
e.preventDefault();
const { dispatch, form } = this.props;
form.validateFields((err, fieldsValue) => {
if (err) return;
const values = {
...fieldsValue,
updatedAt: fieldsValue.updatedAt && fieldsValue.updatedAt.valueOf(),
};
this.setState({
formValues: values,
});
dispatch({
type: 'rule/fetch',
payload: values,
});
});
};
handleModalVisible = flag => {
this.setState({
modalVisible: !!flag,
});
};
handleUpdateModalVisible = (flag, record) => {
this.setState({
updateModalVisible: !!flag,
stepFormValues: record || {},
});
};
handleAdd = fields => {
const { dispatch } = this.props;
dispatch({
type: 'rule/add',
payload: {
desc: fields.desc,
},
});
message.success('添加成功');
this.handleModalVisible();
};
handleUpdate = fields => {
const { dispatch } = this.props;
const { formValues } = this.state;
dispatch({
type: 'rule/update',
payload: {
query: formValues,
body: {
name: fields.name,
desc: fields.desc,
key: fields.key,
},
},
});
message.success('配置成功');
this.handleUpdateModalVisible();
};
renderSimpleForm() {
const {
form: { getFieldDecorator },
} = this.props;
return (
<Form onSubmit={this.handleSearch} layout="inline">
<Row gutter={{ md: 8, lg: 24, xl: 48 }}>
<Col md={8} sm={24}>
<FormItem label="规则名称">
{getFieldDecorator('name')(<Input placeholder="请输入" />)}
</FormItem>
</Col>
<Col md={8} sm={24}>
<FormItem label="使用状态">
{getFieldDecorator('status')(
<Select placeholder="请选择" style={{ width: '100%' }}>
<Option value="0">关闭</Option>
<Option value="1">运行中</Option>
</Select>
)}
</FormItem>
</Col>
<Col md={8} sm={24}>
<span className={styles.submitButtons}>
<Button type="primary" htmlType="submit">
查询
</Button>
<Button style={{ marginLeft: 8 }} onClick={this.handleFormReset}>
重置
</Button>
<a style={{ marginLeft: 8 }} onClick={this.toggleForm}>
展开 <Icon type="down" />
</a>
</span>
</Col>
</Row>
</Form>
);
}
renderAdvancedForm() {
const {
form: { getFieldDecorator },
} = this.props;
return (
<Form onSubmit={this.handleSearch} layout="inline">
<Row gutter={{ md: 8, lg: 24, xl: 48 }}>
<Col md={8} sm={24}>
<FormItem label="规则名称">
{getFieldDecorator('name')(<Input placeholder="请输入" />)}
</FormItem>
</Col>
<Col md={8} sm={24}>
<FormItem label="使用状态">
{getFieldDecorator('status')(
<Select placeholder="请选择" style={{ width: '100%' }}>
<Option value="0">关闭</Option>
<Option value="1">运行中</Option>
</Select>
)}
</FormItem>
</Col>
<Col md={8} sm={24}>
<FormItem label="调用次数">
{getFieldDecorator('number')(<InputNumber style={{ width: '100%' }} />)}
</FormItem>
</Col>
</Row>
<Row gutter={{ md: 8, lg: 24, xl: 48 }}>
<Col md={8} sm={24}>
<FormItem label="更新日期">
{getFieldDecorator('date')(
<DatePicker style={{ width: '100%' }} placeholder="请输入更新日期" />
)}
</FormItem>
</Col>
<Col md={8} sm={24}>
<FormItem label="使用状态">
{getFieldDecorator('status3')(
<Select placeholder="请选择" style={{ width: '100%' }}>
<Option value="0">关闭</Option>
<Option value="1">运行中</Option>
</Select>
)}
</FormItem>
</Col>
<Col md={8} sm={24}>
<FormItem label="使用状态">
{getFieldDecorator('status4')(
<Select placeholder="请选择" style={{ width: '100%' }}>
<Option value="0">关闭</Option>
<Option value="1">运行中</Option>
</Select>
)}
</FormItem>
</Col>
</Row>
<div style={{ overflow: 'hidden' }}>
<div style={{ marginBottom: 24 }}>
<Button type="primary" htmlType="submit">
查询
</Button>
<Button style={{ marginLeft: 8 }} onClick={this.handleFormReset}>
重置
</Button>
<a style={{ marginLeft: 8 }} onClick={this.toggleForm}>
收起 <Icon type="up" />
</a>
</div>
</div>
</Form>
);
}
renderForm() {
const { expandForm } = this.state;
return expandForm ? this.renderAdvancedForm() : this.renderSimpleForm();
}
render() {
const {
rule: { data },
loading,
} = this.props;
const { selectedRows, modalVisible, updateModalVisible, stepFormValues } = this.state;
const menu = (
<Menu onClick={this.handleMenuClick} selectedKeys={[]}>
<Menu.Item key="remove">删除</Menu.Item>
<Menu.Item key="approval">批量审批</Menu.Item>
</Menu>
);
const parentMethods = {
handleAdd: this.handleAdd,
handleModalVisible: this.handleModalVisible,
};
const updateMethods = {
handleUpdateModalVisible: this.handleUpdateModalVisible,
handleUpdate: this.handleUpdate,
};
return (
<PageHeaderWrapper title="查询表格">
<Card bordered={false}>
<div className={styles.tableList}>
<div className={styles.tableListForm}>{this.renderForm()}</div>
<div className={styles.tableListOperator}>
<Button icon="plus" type="primary" onClick={() => this.handleModalVisible(true)}>
新建
</Button>
{selectedRows.length > 0 && (
<span>
<Button>批量操作</Button>
<Dropdown overlay={menu}>
<Button>
更多操作 <Icon type="down" />
</Button>
</Dropdown>
</span>
)}
</div>
<StandardTable
selectedRows={selectedRows}
loading={loading}
data={data}
columns={this.columns}
onSelectRow={this.handleSelectRows}
onChange={this.handleStandardTableChange}
/>
</div>
</Card>
<CreateForm {...parentMethods} modalVisible={modalVisible} />
{stepFormValues && Object.keys(stepFormValues).length ? (
<UpdateForm
{...updateMethods}
updateModalVisible={updateModalVisible}
values={stepFormValues}
/>
) : null}
</PageHeaderWrapper>
);
}
}
export default TableList;

View File

@ -0,0 +1,49 @@
@import '~antd/lib/style/themes/default.less';
@import '~@/utils/utils.less';
.tableList {
.tableListOperator {
margin-bottom: 16px;
button {
margin-right: 8px;
}
}
}
.tableListForm {
:global {
.ant-form-item {
display: flex;
margin-right: 0;
margin-bottom: 24px;
> .ant-form-item-label {
width: auto;
padding-right: 8px;
line-height: 32px;
}
.ant-form-item-control {
line-height: 32px;
}
}
.ant-form-item-control-wrapper {
flex: 1;
}
}
.submitButtons {
display: block;
margin-bottom: 24px;
white-space: nowrap;
}
}
@media screen and (max-width: @screen-lg) {
.tableListForm :global(.ant-form-item) {
margin-right: 24px;
}
}
@media screen and (max-width: @screen-md) {
.tableListForm :global(.ant-form-item) {
margin-right: 8px;
}
}

View File

@ -6,6 +6,8 @@ import { Button, Card, Col, Divider, Form, Input, Row, Tabs, DatePicker, List }
import PageHeaderWrapper from '@/components/PageHeaderWrapper'; import PageHeaderWrapper from '@/components/PageHeaderWrapper';
import DictionaryText from '@/components/Dictionary/DictionaryText'; import DictionaryText from '@/components/Dictionary/DictionaryText';
import OrderUpdatePayAmount from './OrderUpdatePayAmount'; import OrderUpdatePayAmount from './OrderUpdatePayAmount';
import OrderRemark from './OrderRemark';
import OrderCancel from './OrderCancel';
import dictionary from '@/utils/dictionary'; import dictionary from '@/utils/dictionary';
import styles from './OrderList.less'; import styles from './OrderList.less';
@ -14,8 +16,10 @@ const { RangePicker } = DatePicker;
const FormItem = Form.Item; const FormItem = Form.Item;
const { TabPane } = Tabs; const { TabPane } = Tabs;
const OrderContent = orderItem => { const OrderContent = props => {
const { dispatch, skuName, skuImage, quantity, price, payAmount, createTime, status } = orderItem; const { dispatch, item } = props;
const { createTime, status, payAmount } = item;
const { name, mobile } = item.orderRecipient;
const handleUpdatePayAmount = updateOrderItem => { const handleUpdatePayAmount = updateOrderItem => {
dispatch({ dispatch({
@ -29,27 +33,58 @@ const OrderContent = orderItem => {
}); });
}; };
// const handleCancelOrder = ({ orderId }) => {
// dispatch({
// type: 'orderList/changeOrderCancelVisible',
// payload: {
// orderCancelVisible: true,
// orderId,
// },
// });
// };
//
// const handleRenderGoods = () => {};
const renderStatusButtons = () => {
let res = '';
if (status === 1) {
res = <Button>取消订单</Button>;
} else if (status === 2) {
res = <Button>发货</Button>;
}
return res;
};
const renderGoods = orderItems => {
return orderItems.map(({ skuName, skuImage, quantity, price }) => {
return (
<div className={styles.orderGoods}>
<img alt={skuName} className={`${styles.image}`} src={skuImage} />
<div className={styles.contentItem}>
<div>
<a>{skuName}</a>
</div>
<div>秋季精选</div>
</div>
<div className={styles.contentItem}>
<div>{quantity}</div>
<div>
{price / 100} /{quantity * (price / 100)}
</div>
</div>
</div>
);
});
};
return ( return (
<div className={styles.order}> <div className={styles.order}>
<img alt={skuName} className={`${styles.image}`} src={skuImage} /> <div className={`${styles.contentItem} ${styles.goodsContainer}`}>
<div className={styles.contentItem}> {renderGoods(item.orderItems)}
<div className={styles.columnName}>(名称)</div>
<div>
<a>{skuName}</a>
</div>
<div>秋季精选</div>
</div> </div>
<div className={styles.contentItem}> <div className={styles.contentItem}>
<div className={styles.columnName}>(金额/物件)</div> <div>{name}</div>
<div>{quantity}</div> <div>{mobile}</div>
<div>
{price / 100} /{quantity * (price / 100)}
</div>
</div>
<div className={styles.contentItem}>
<div className={styles.columnName}>(购买人)</div>
<div>范先生</div>
<div>13302926050</div>
</div> </div>
<div className={styles.contentItem}> <div className={styles.contentItem}>
<div className={styles.columnName}>(下单时间)</div> <div className={styles.columnName}>(下单时间)</div>
@ -57,17 +92,16 @@ const OrderContent = orderItem => {
<div>&nbsp;</div> <div>&nbsp;</div>
</div> </div>
<div className={styles.contentItem}> <div className={styles.contentItem}>
<div className={styles.columnName}>(订单状态)</div>
<div> <div>
<DictionaryText dicKey={dictionary.ORDER_STATUS} dicValue={status} /> <DictionaryText dicKey={dictionary.ORDER_STATUS} dicValue={status} />
</div> </div>
<div>{[0, 1, 2].indexOf(status) ? <Button>取消订单</Button> : ''}</div> <div>{renderStatusButtons()}</div>
</div> </div>
<div className={styles.contentItem}> <div className={styles.contentItem}>
<div className={styles.columnName}>(实付金额)</div> <div className={styles.columnName}>(实付金额)</div>
<div>{payAmount / 100}</div> <div>{payAmount / 100}</div>
<div> <div>
<a onClick={() => handleUpdatePayAmount(orderItem)}>修改价格</a> <a onClick={() => handleUpdatePayAmount(props)}>修改价格</a>
</div> </div>
</div> </div>
</div> </div>
@ -82,6 +116,18 @@ const OrderList = props => {
...pagination, ...pagination,
}; };
const handleRemakeClick = item => {
const { id, remark } = item;
dispatch({
type: 'orderList/changeRemakeVisible',
payload: {
remarkVisible: true,
orderId: id,
remark,
},
});
};
return ( return (
<List <List
size="large" size="large"
@ -102,13 +148,11 @@ const OrderList = props => {
<div> <div>
<a>查看详情</a> <a>查看详情</a>
<Divider type="vertical" /> <Divider type="vertical" />
<a>备注</a> <a onClick={() => handleRemakeClick(item)}>备注</a>
</div> </div>
</div> </div>
{item.orderItems.map(orderItem => { <OrderContent item={item} dispatch={dispatch} />
return <OrderContent key={orderItem.id} dispatch={dispatch} {...orderItem} />;
})}
</div> </div>
</List.Item> </List.Item>
)} )}
@ -131,11 +175,9 @@ const SearchForm = Form.create()(props => {
form.validateFields((err, fields) => { form.validateFields((err, fields) => {
const buildTime = (fieldValue, key) => { const buildTime = (fieldValue, key) => {
const res = {}; const res = {};
if (fieldValue) { if (fieldValue && fieldValue.length >= 2) {
const keySuffix = key.substring(0, 1).toUpperCase() + key.substring(1); const keySuffix = key.substring(0, 1).toUpperCase() + key.substring(1);
// res[`start${keySuffix}`] = fieldValue[0].valueOf();
res[`start${keySuffix}`] = fieldValue[0].format('YYYY-MM-DD HH:mm:ss'); res[`start${keySuffix}`] = fieldValue[0].format('YYYY-MM-DD HH:mm:ss');
// res[`end${keySuffix}`] = fieldValue[1].valueOf();
res[`end${keySuffix}`] = fieldValue[1].format('YYYY-MM-DD HH:mm:ss'); res[`end${keySuffix}`] = fieldValue[1].format('YYYY-MM-DD HH:mm:ss');
} }
return res; return res;
@ -186,9 +228,6 @@ const SearchForm = Form.create()(props => {
<Col md={8} sm={24}> <Col md={8} sm={24}>
<FormItem label="创建时间">{getFieldDecorator('createTime')(<RangePicker />)}</FormItem> <FormItem label="创建时间">{getFieldDecorator('createTime')(<RangePicker />)}</FormItem>
</Col> </Col>
<Col md={8} sm={24}>
<FormItem label="成交时间">{getFieldDecorator('closingTime')(<RangePicker />)}</FormItem>
</Col>
<Col md={8} sm={24}> <Col md={8} sm={24}>
<span className={styles.submitButtons}> <span className={styles.submitButtons}>
<Button type="primary" htmlType="submit"> <Button type="primary" htmlType="submit">
@ -234,9 +273,7 @@ class BasicList extends PureComponent {
}); });
}; };
handleEditorClick = () => { handleEditorClick = () => {};
console.info('edit');
};
handleSearch = fields => { handleSearch = fields => {
const { const {
@ -287,6 +324,8 @@ class BasicList extends PureComponent {
</div> </div>
<OrderUpdatePayAmount {...this.props} /> <OrderUpdatePayAmount {...this.props} />
<OrderRemark {...this.props} />
<OrderCancel {...this.props} />
</PageHeaderWrapper> </PageHeaderWrapper>
); );
} }

View File

@ -239,6 +239,8 @@
// 订单content // 订单content
.orderGroup { .orderGroup {
@padding-slid: 10px; @padding-slid: 10px;
@solid-color: rgba(167, 157, 160, 0.92);
@header-background: rgba(210, 219, 238, 0.99);
display: flex; display: flex;
flex: 1; flex: 1;
@ -254,7 +256,26 @@
font-weight: bold; font-weight: bold;
font-size: 15px; font-size: 15px;
line-height: 35px; line-height: 35px;
background-color: #c0bfb9; background-color: @header-background;
}
.goodsContainer {
:first-child {
border-top: none;
border-bottom: none;
}
:last-child {
border-bottom: none;
}
}
.orderGoods {
display: flex;
flex: 2;
flex-direction: row;
width: 500px;
border: 1px solid @solid-color;
} }
.order { .order {
@ -264,7 +285,7 @@
padding-right: @padding-slid; padding-right: @padding-slid;
padding-left: @padding-slid; padding-left: @padding-slid;
line-height: 100px; line-height: 100px;
border: 1px solid #c0bfb9; border: 1px solid @solid-color;
.contentItem { .contentItem {
display: flex; display: flex;
@ -285,8 +306,8 @@
} }
.image { .image {
width: 100px; width: 80px;
height: 100px; height: 80px;
} }
} }
} }

View File

@ -0,0 +1,321 @@
import React, { PureComponent } from 'react';
import moment from 'moment';
import { connect } from 'dva';
import { Button, Card, Col, Divider, Form, Input, Row, Tabs, DatePicker, List } from 'antd';
import PageHeaderWrapper from '@/components/PageHeaderWrapper';
import DictionaryText from '@/components/Dictionary/DictionaryText';
import OrderUpdatePayAmount from './OrderUpdatePayAmount';
import OrderRemark from './OrderRemark';
import dictionary from '@/utils/dictionary';
import styles from './OrderList.less';
const { RangePicker } = DatePicker;
const FormItem = Form.Item;
const { TabPane } = Tabs;
const OrderContent = props => {
const {
dispatch,
skuName,
skuImage,
quantity,
price,
payAmount,
createTime,
status,
item,
} = props;
const { name, mobile } = item.orderLogistics;
const handleUpdatePayAmount = updateOrderItem => {
dispatch({
type: 'orderList/changePayAmountVisible',
payload: {
payAmountVisible: true,
payAmount: updateOrderItem.payAmount,
orderId: updateOrderItem.orderId,
orderItemId: updateOrderItem.id,
},
});
};
const renderStatusButtons = () => {
let res = '';
if (status === 1) {
res = <Button>取消订单</Button>;
} else if (status === 2) {
res = <Button>发货</Button>;
}
return res;
};
return (
<div className={styles.order}>
<img alt={skuName} className={`${styles.image}`} src={skuImage} />
<div className={styles.contentItem}>
<div>
<a>{skuName}</a>
</div>
<div>秋季精选</div>
</div>
<div className={styles.contentItem}>
<div>{quantity}</div>
<div>
{price / 100} /{quantity * (price / 100)}
</div>
</div>
<div className={styles.contentItem}>
<div>{name}</div>
<div>{mobile}</div>
</div>
<div className={styles.contentItem}>
<div className={styles.columnName}>(下单时间)</div>
<div>{moment(createTime).format('YYYY-MM-DD HH:mm')}</div>
<div>&nbsp;</div>
</div>
<div className={styles.contentItem}>
<div>
<DictionaryText dicKey={dictionary.ORDER_STATUS} dicValue={status} />
</div>
<div>{renderStatusButtons()}</div>
</div>
<div className={styles.contentItem}>
<div className={styles.columnName}>(实付金额)</div>
<div>{payAmount / 100}</div>
<div>
<a onClick={() => handleUpdatePayAmount(props)}>修改价格</a>
</div>
</div>
</div>
);
};
const OrderList = props => {
const { list, dispatch, loading } = props;
const { pagination, dataSource } = list;
const paginationProps = {
...pagination,
};
const handleRemakeClick = item => {
const { id, remark } = item;
dispatch({
type: 'orderList/changeRemakeVisible',
payload: {
remarkVisible: true,
orderId: id,
remark,
},
});
};
return (
<List
size="large"
rowKey="id"
loading={loading}
pagination={paginationProps}
dataSource={dataSource}
renderItem={item => (
<List.Item>
<div className={styles.orderGroup}>
<div className={styles.header}>
<div>
<span>订单号: {item.orderNo}</span>
<Divider type="vertical" />
<span>支付金额: {item.payAmount / 100} </span>
</div>
<div>
<a>查看详情</a>
<Divider type="vertical" />
<a onClick={() => handleRemakeClick(item)}>备注</a>
</div>
</div>
{item.orderItems.map(orderItem => {
return (
<OrderContent key={orderItem.id} item={item} dispatch={dispatch} {...orderItem} />
);
})}
</div>
</List.Item>
)}
/>
);
};
// SearchForm
const SearchForm = Form.create()(props => {
const {
form: { getFieldDecorator },
form,
handleSearch,
} = props;
const handleFormReset = () => {};
const onSubmit = e => {
e.preventDefault();
form.validateFields((err, fields) => {
const buildTime = (fieldValue, key) => {
const res = {};
if (fieldValue && fieldValue.length >= 2) {
const keySuffix = key.substring(0, 1).toUpperCase() + key.substring(1);
res[`start${keySuffix}`] = fieldValue[0].format('YYYY-MM-DD HH:mm:ss');
res[`end${keySuffix}`] = fieldValue[1].format('YYYY-MM-DD HH:mm:ss');
}
return res;
};
const timeFields = ['createTime', 'closingTime'];
const buildSearchParams = fields2 => {
let res = {};
Object.keys(fields).map(objectKey => {
const fieldValue = fields2[objectKey];
if (timeFields.indexOf(objectKey) !== -1) {
// 处理时间
res = {
...res,
...buildTime(fieldValue, objectKey),
};
} else if (fieldValue !== undefined) {
res[objectKey] = fieldValue;
}
return true;
});
return res;
};
const searchParams = buildSearchParams(fields);
if (handleSearch) {
handleSearch(searchParams);
}
});
};
return (
<Form onSubmit={onSubmit} layout="inline">
<Row gutter={{ md: 8, lg: 24, xl: 48 }}>
<Col md={8} sm={24}>
<FormItem label="订单id">
{getFieldDecorator('id')(<Input placeholder="请输入订单id" />)}
</FormItem>
</Col>
<Col md={8} sm={24}>
<FormItem label="订单号">
{getFieldDecorator('orderNo')(<Input placeholder="请输入订单号" />)}
</FormItem>
</Col>
</Row>
<Row gutter={{ md: 8, lg: 24, xl: 48 }}>
<Col md={8} sm={24}>
<FormItem label="创建时间">{getFieldDecorator('createTime')(<RangePicker />)}</FormItem>
</Col>
<Col md={8} sm={24}>
<span className={styles.submitButtons}>
<Button type="primary" htmlType="submit">
查询
</Button>
<Button style={{ marginLeft: 8 }} onClick={handleFormReset}>
重置
</Button>
</span>
</Col>
</Row>
</Form>
);
});
@connect(({ orderList, loading }) => ({
orderList,
list: orderList.list,
loading: loading.models.orderList,
}))
class BasicList extends PureComponent {
componentDidMount() {
const {
list: { pagination },
} = this.props;
this.queryList({
pageNo: pagination.current,
pageSize: pagination.pageSize,
});
}
queryList = params => {
const { dispatch } = this.props;
// 保存每次操作 searchParams
this.searchParams = params;
// dispatch
dispatch({
type: 'orderList/queryPage',
payload: {
...params,
},
});
};
handleEditorClick = () => {};
handleSearch = fields => {
const {
list: { pagination },
} = this.props;
this.queryList({
...fields,
pageNo: pagination.current,
pageSize: pagination.pageSize,
});
};
handleTabsChange = key => {
const params = {
...this.searchParams,
status: key,
};
this.queryList(params);
};
render() {
return (
<PageHeaderWrapper>
<div className={styles.standardList}>
<Card
className={styles.listCard}
bordered={false}
title="订单列表"
style={{ marginTop: 24 }}
bodyStyle={{ padding: '0 32px 40px 32px' }}
>
<div className={styles.tableListForm}>
<SearchForm {...this.props} handleSearch={this.handleSearch} />
</div>
<Tabs defaultActiveKey={null} onChange={this.handleTabsChange}>
<TabPane tab="全部" key={null} />
<TabPane tab="待付款" key={0} />
<TabPane tab="待发货" key={1} />
<TabPane tab="已发货" key={2} />
<TabPane tab="已完成" key={3} />
<TabPane tab="已关闭" key={4} />
</Tabs>
<OrderList {...this.props} handleEditorClick={this.handleEditorClick} />
</Card>
</div>
<OrderUpdatePayAmount {...this.props} />
<OrderRemark {...this.props} />
</PageHeaderWrapper>
);
}
}
export default BasicList;

View File

@ -0,0 +1,56 @@
import React from 'react';
import { Form, Input, Modal } from 'antd';
const FormItem = Form.Item;
// 订单 - 更新支付金额
const OrderRemark = Form.create()(props => {
const { dispatch, loading } = props;
const { orderId, remark, remarkVisible, searchParams } = props.orderList;
const { getFieldDecorator, getFieldsValue } = props.form;
const handleOk = e => {
e.preventDefault();
const fieldsValue = getFieldsValue();
dispatch({
type: 'orderList/updateRemake',
payload: {
params: {
remark: fieldsValue.remark,
orderId,
},
searchParams,
},
});
};
const handleCancel = () => {
dispatch({
type: 'orderList/changeRemakeVisible',
payload: {
remarkVisible: false,
},
});
};
return (
<Modal
destroyOnClose
title="添加备注信息"
visible={remarkVisible}
onOk={handleOk}
okText="保存"
onCancel={handleCancel}
confirmLoading={loading}
>
<FormItem labelCol={{ span: 5 }} wrapperCol={{ span: 15 }} label="备注">
{getFieldDecorator('remark', {
initialValue: remark,
})(<Input.TextArea autosize={{ minRows: 2, maxRows: 6 }} placeholder="请输入备注信息" />)}
</FormItem>
</Modal>
);
});
export default OrderRemark;

View File

@ -1,5 +1,5 @@
import React from 'react'; import React from 'react';
import { Form, Input, Modal } from 'antd'; import { Form, InputNumber, Modal } from 'antd';
const FormItem = Form.Item; const FormItem = Form.Item;
@ -52,7 +52,7 @@ const OrderUpdatePayAmount = Form.create()(props => {
{ max: 10000, min: 0, message: '金额值 0 - 100000 元' }, { max: 10000, min: 0, message: '金额值 0 - 100000 元' },
], ],
initialValue: payAmount / 100, initialValue: payAmount / 100,
})(<Input placeholder="请输入修改的金额" />)} })(<InputNumber min={0} max={100000} placeholder="请输入修改的金额" />)}
</FormItem> </FormItem>
</Modal> </Modal>
); );

View File

@ -14,6 +14,18 @@ export async function updateOrderItemPayAmount(params) {
}); });
} }
export async function updateRemark(params) {
return request(`/order-api/admins/order/update_remark?${stringify(params)}`, {
method: 'PUT',
});
}
export async function cancelOrder(params) {
return request(`/order-api/admins/order/cancel_order?${stringify(params)}`, {
method: 'PUT',
});
}
export async function updateOrderItem(params) { export async function updateOrderItem(params) {
return request(`/order-api/admins/order_item/update?${stringify(params)}`, { return request(`/order-api/admins/order_item/update?${stringify(params)}`, {
method: 'PUT', method: 'PUT',
@ -22,3 +34,12 @@ export async function updateOrderItem(params) {
}, },
}); });
} }
export async function getLogistics(params) {
return request(`/order-api/admins/order_item/update?${stringify(params)}`, {
method: 'PUT',
body: {
...params,
},
});
}

View File

@ -3,6 +3,7 @@
const DictionaryConstants = { const DictionaryConstants = {
GENDER: 'gender', GENDER: 'gender',
ORDER_STATUS: 'order_status', ORDER_STATUS: 'order_status',
ORDER_CANCEL_REASONS: 'order_cancel_reasons',
}; };
export default DictionaryConstants; export default DictionaryConstants;

View File

@ -9,11 +9,9 @@ import qs from 'qs';
function filterEmptyStr(params) { function filterEmptyStr(params) {
function filterObject(object) { function filterObject(object) {
const res = {}; const res = {};
for (const key in params) { for (const key in object) {
const val = params[key]; const val = object[key];
if (typeof val === 'string' && val) { if (val !== undefined && val !== 'undefined' && val !== null && val !== 'null') {
res[key] = val;
} else {
res[key] = val; res[key] = val;
} }
} }

View File

@ -56,6 +56,14 @@ public interface OrderService {
*/ */
CommonResult cancelOrder(Integer orderId, Integer reasons, String otherReasons); CommonResult cancelOrder(Integer orderId, Integer reasons, String otherReasons);
/**
* 订单发货
*
* @param orderDelivery
* @return
*/
CommonResult orderDelivery(OrderDeliveryDTO orderDelivery);
/** /**
* 更新订单 - 备注 * 更新订单 - 备注
* *

View File

@ -90,7 +90,7 @@ public class OrderBO implements Serializable {
/** /**
* 订单物流信息 * 订单物流信息
*/ */
private OrderLogisticsBO orderLogistics; private OrderRecipientBO orderRecipient;
@Override @Override
public String toString() { public String toString() {
@ -108,7 +108,7 @@ public class OrderBO implements Serializable {
", status=" + status + ", status=" + status +
", remark='" + remark + '\'' + ", remark='" + remark + '\'' +
", orderItems=" + orderItems + ", orderItems=" + orderItems +
", orderLogistics=" + orderLogistics + ", orderRecipient=" + orderRecipient +
'}'; '}';
} }
@ -229,12 +229,12 @@ public class OrderBO implements Serializable {
return this; return this;
} }
public OrderLogisticsBO getOrderLogistics() { public OrderRecipientBO getOrderRecipient() {
return orderLogistics; return orderRecipient;
} }
public OrderBO setOrderLogistics(OrderLogisticsBO orderLogistics) { public OrderBO setOrderRecipient(OrderRecipientBO orderRecipient) {
this.orderLogistics = orderLogistics; this.orderRecipient = orderRecipient;
return this; return this;
} }
} }

View File

@ -0,0 +1,103 @@
package cn.iocoder.mall.order.api.bo;
import cn.iocoder.common.framework.dataobject.BaseDO;
/**
* 订单收件人信息 order_recipient
*
* @author Sin
* @time 2019-03-31 11:37
*/
public class OrderRecipientBO extends BaseDO {
/**
* 编号
*/
private Integer id;
/**
* 订单id
*/
private Integer orderId;
/**
* 收件区域编号
*/
private String areaNo;
/**
* 收件人名称
*/
private String name;
/**
* 收件手机号
*/
private String mobile;
/**
* 收件详细地址
*/
private String address;
@Override
public String toString() {
return "OrderRecipientBO{" +
"id=" + id +
", orderId=" + orderId +
", areaNo='" + areaNo + '\'' +
", name='" + name + '\'' +
", mobile='" + mobile + '\'' +
", address='" + address + '\'' +
'}';
}
public Integer getId() {
return id;
}
public OrderRecipientBO setId(Integer id) {
this.id = id;
return this;
}
public Integer getOrderId() {
return orderId;
}
public OrderRecipientBO setOrderId(Integer orderId) {
this.orderId = orderId;
return this;
}
public String getAreaNo() {
return areaNo;
}
public OrderRecipientBO setAreaNo(String areaNo) {
this.areaNo = areaNo;
return this;
}
public String getName() {
return name;
}
public OrderRecipientBO setName(String name) {
this.name = name;
return this;
}
public String getMobile() {
return mobile;
}
public OrderRecipientBO setMobile(String mobile) {
this.mobile = mobile;
return this;
}
public String getAddress() {
return address;
}
public OrderRecipientBO setAddress(String address) {
this.address = address;
return this;
}
}

View File

@ -0,0 +1,41 @@
package cn.iocoder.mall.order.api.constant;
/**
* 物流信息
*
* @author Sin
* @time 2019-03-30 22:33
*/
public enum LogisticsEnum {
LOGISTICS_1(1, "顺丰快递"),
LOGISTICS_2(2, "圆通快递"),
LOGISTICS_3(3, "申通快递"),
LOGISTICS_4(4, "韵答快递"),
LOGISTICS_5(5, "天天快递"),
LOGISTICS_6(6, "EMS中国邮政"),
;
/**
* 状态值
*/
private Integer value;
/**
* 状态名
*/
private String name;
LogisticsEnum(int value, String name) {
this.value = value;
this.name = name;
}
public int getValue() {
return value;
}
public String getName() {
return name;
}
}

View File

@ -0,0 +1,122 @@
package cn.iocoder.mall.order.api.dto;
import java.io.Serializable;
import java.util.List;
/**
* 订单发货
*
* @author Sin
* @time 2019-03-30 22:31
*/
public class OrderDeliveryDTO implements Serializable {
/**
* 收件区域编号
*/
private String areaNo;
/**
* 收件人名称
*/
private String name;
/**
* 收件手机号
*/
private String mobile;
/**
* 收件详细地址
*/
private String address;
/**
* 物流 (字典)
*/
private Integer logistics;
/**
* 物流编号
*/
private String logisticsNo;
///
/// 物理信息是跟 orderItem
/**
* 订单 orderItemId
*/
private List<Integer> orderItemIds;
@Override
public String toString() {
return "OrderDeliverGoodsDTO{" +
"areaNo='" + areaNo + '\'' +
", name='" + name + '\'' +
", mobile='" + mobile + '\'' +
", address='" + address + '\'' +
", logistics=" + logistics +
", logisticsNo='" + logisticsNo + '\'' +
", orderItemIds=" + orderItemIds +
'}';
}
public String getAreaNo() {
return areaNo;
}
public OrderDeliveryDTO setAreaNo(String areaNo) {
this.areaNo = areaNo;
return this;
}
public String getName() {
return name;
}
public OrderDeliveryDTO setName(String name) {
this.name = name;
return this;
}
public String getMobile() {
return mobile;
}
public OrderDeliveryDTO setMobile(String mobile) {
this.mobile = mobile;
return this;
}
public String getAddress() {
return address;
}
public OrderDeliveryDTO setAddress(String address) {
this.address = address;
return this;
}
public Integer getLogistics() {
return logistics;
}
public OrderDeliveryDTO setLogistics(Integer logistics) {
this.logistics = logistics;
return this;
}
public String getLogisticsNo() {
return logisticsNo;
}
public OrderDeliveryDTO setLogisticsNo(String logisticsNo) {
this.logisticsNo = logisticsNo;
return this;
}
public List<Integer> getOrderItemIds() {
return orderItemIds;
}
public OrderDeliveryDTO setOrderItemIds(List<Integer> orderItemIds) {
this.orderItemIds = orderItemIds;
return this;
}
}

View File

@ -0,0 +1,28 @@
package cn.iocoder.mall.order.biz.convert;
import cn.iocoder.mall.order.api.bo.OrderRecipientBO;
import cn.iocoder.mall.order.api.dto.OrderCreateDTO;
import cn.iocoder.mall.order.biz.dataobject.OrderRecipientDO;
import org.mapstruct.Mapper;
import org.mapstruct.Mappings;
import org.mapstruct.factory.Mappers;
import java.util.List;
/**
* 订单收件人信息
*
* @author Sin
* @time 2019-03-31 12:50
*/
@Mapper
public interface OrderRecipientConvert {
OrderRecipientConvert INSTANCE = Mappers.getMapper(OrderRecipientConvert.class);
@Mappings({})
OrderRecipientDO convert(OrderCreateDTO orderCreateDTO);
@Mappings({})
List<OrderRecipientBO> convert(List<OrderRecipientDO> orderRecipientDOList);
}

View File

@ -0,0 +1,36 @@
package cn.iocoder.mall.order.biz.dao;
import cn.iocoder.mall.order.biz.dataobject.OrderRecipientDO;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import java.util.Collection;
import java.util.List;
/**
* 订单收件人 信息
*
* @author Sin
* @time 2019-03-31 12:16
*/
@Repository
public interface OrderRecipientMapper {
/**
* 插入 - 订单收件人
*
* @param orderRecipient
* @return
*/
int insert(OrderRecipientDO orderRecipient);
/**
* 查询 - 根据 orderIds
*
* @param orderIds
* @return
*/
List<OrderRecipientDO> selectByOrderIds(
@Param("orderIds")Collection<Integer> orderIds
);
}

View File

@ -0,0 +1,103 @@
package cn.iocoder.mall.order.biz.dataobject;
import cn.iocoder.common.framework.dataobject.BaseDO;
/**
* 订单收件人信息 order_recipient
*
* @author Sin
* @time 2019-03-31 11:37
*/
public class OrderRecipientDO extends BaseDO {
/**
* 编号
*/
private Integer id;
/**
* 订单id
*/
private Integer orderId;
/**
* 收件区域编号
*/
private String areaNo;
/**
* 收件人名称
*/
private String name;
/**
* 收件手机号
*/
private String mobile;
/**
* 收件详细地址
*/
private String address;
@Override
public String toString() {
return "OrderRecipientDO{" +
"id=" + id +
", orderId=" + orderId +
", areaNo='" + areaNo + '\'' +
", name='" + name + '\'' +
", mobile='" + mobile + '\'' +
", address='" + address + '\'' +
'}';
}
public Integer getId() {
return id;
}
public OrderRecipientDO setId(Integer id) {
this.id = id;
return this;
}
public Integer getOrderId() {
return orderId;
}
public OrderRecipientDO setOrderId(Integer orderId) {
this.orderId = orderId;
return this;
}
public String getAreaNo() {
return areaNo;
}
public OrderRecipientDO setAreaNo(String areaNo) {
this.areaNo = areaNo;
return this;
}
public String getName() {
return name;
}
public OrderRecipientDO setName(String name) {
this.name = name;
return this;
}
public String getMobile() {
return mobile;
}
public OrderRecipientDO setMobile(String mobile) {
this.mobile = mobile;
return this;
}
public String getAddress() {
return address;
}
public OrderRecipientDO setAddress(String address) {
this.address = address;
return this;
}
}

View File

@ -13,14 +13,9 @@ import cn.iocoder.mall.order.biz.OrderCommon;
import cn.iocoder.mall.order.biz.convert.OrderConvert; import cn.iocoder.mall.order.biz.convert.OrderConvert;
import cn.iocoder.mall.order.biz.convert.OrderItemConvert; import cn.iocoder.mall.order.biz.convert.OrderItemConvert;
import cn.iocoder.mall.order.biz.convert.OrderLogisticsConvert; import cn.iocoder.mall.order.biz.convert.OrderLogisticsConvert;
import cn.iocoder.mall.order.biz.dao.OrderCancelMapper; import cn.iocoder.mall.order.biz.convert.OrderRecipientConvert;
import cn.iocoder.mall.order.biz.dao.OrderItemMapper; import cn.iocoder.mall.order.biz.dao.*;
import cn.iocoder.mall.order.biz.dao.OrderLogisticsMapper; import cn.iocoder.mall.order.biz.dataobject.*;
import cn.iocoder.mall.order.biz.dao.OrderMapper;
import cn.iocoder.mall.order.biz.dataobject.OrderCancelDO;
import cn.iocoder.mall.order.biz.dataobject.OrderDO;
import cn.iocoder.mall.order.biz.dataobject.OrderItemDO;
import cn.iocoder.mall.order.biz.dataobject.OrderLogisticsDO;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@ -47,6 +42,8 @@ public class OrderServiceImpl implements OrderService {
@Autowired @Autowired
private OrderLogisticsMapper orderLogisticsMapper; private OrderLogisticsMapper orderLogisticsMapper;
@Autowired @Autowired
private OrderRecipientMapper orderRecipientMapper;
@Autowired
private OrderCancelMapper orderCancelMapper; private OrderCancelMapper orderCancelMapper;
@Autowired @Autowired
private OrderCommon orderCommon; private OrderCommon orderCommon;
@ -67,16 +64,11 @@ public class OrderServiceImpl implements OrderService {
.map(orderDO -> orderDO.getId()) .map(orderDO -> orderDO.getId())
.collect(Collectors.toSet()); .collect(Collectors.toSet());
Set<Integer> orderLogisticsIds = orderDOList.stream()
.map(orderDO -> orderDO.getOrderLogisticsId())
.collect(Collectors.toSet());
// 获取物流信息 // 获取物流信息
List<OrderLogisticsDO> orderLogisticsDOList = orderLogisticsMapper.selectByIds(orderLogisticsIds); List<OrderRecipientDO> orderRecipientDOList = orderRecipientMapper.selectByOrderIds(orderIds);
List<OrderLogisticsBO> orderLogisticsBOList List<OrderRecipientBO> orderRecipientBOList = OrderRecipientConvert.INSTANCE.convert(orderRecipientDOList);
= OrderLogisticsConvert.INSTANCE.convertOrderLogisticsBO(orderLogisticsDOList); Map<Integer, OrderRecipientBO> orderRecipientBOMap
Map<Integer, OrderLogisticsBO> orderLogisticsDOMap = orderRecipientBOList.stream().collect(Collectors.toMap(OrderRecipientBO::getOrderId, obj -> obj));
= orderLogisticsBOList.stream().collect(Collectors.toMap(OrderLogisticsBO::getId, obj -> obj));
// 获取 订单的 items // 获取 订单的 items
List<OrderItemDO> orderItemDOList = orderItemMapper List<OrderItemDO> orderItemDOList = orderItemMapper
@ -100,8 +92,8 @@ public class OrderServiceImpl implements OrderService {
if (orderItemBOMultimap.containsKey(orderBO.getId())) { if (orderItemBOMultimap.containsKey(orderBO.getId())) {
orderBO.setOrderItems(orderItemBOMultimap.get(orderBO.getId())); orderBO.setOrderItems(orderItemBOMultimap.get(orderBO.getId()));
} }
if (orderLogisticsDOMap.containsKey(orderBO.getOrderLogisticsId())) { if (orderRecipientBOMap.containsKey(orderBO.getId())) {
orderBO.setOrderLogistics(orderLogisticsDOMap.get(orderBO.getOrderLogisticsId())); orderBO.setOrderRecipient(orderRecipientBOMap.get(orderBO.getId()));
} }
return orderBO; return orderBO;
}).collect(Collectors.toList()); }).collect(Collectors.toList());
@ -117,7 +109,7 @@ public class OrderServiceImpl implements OrderService {
@Transactional @Transactional
public CommonResult<OrderCreateBO> createOrder(Integer userId, OrderCreateDTO orderCreateDTO) { public CommonResult<OrderCreateBO> createOrder(Integer userId, OrderCreateDTO orderCreateDTO) {
List<OrderCreateItemDTO> orderItemDTOList = orderCreateDTO.getOrderItems(); List<OrderCreateItemDTO> orderItemDTOList = orderCreateDTO.getOrderItems();
OrderLogisticsDO orderLogisticsDO = OrderLogisticsConvert.INSTANCE.convert(orderCreateDTO); OrderRecipientDO orderRecipientDO = OrderRecipientConvert.INSTANCE.convert(orderCreateDTO);
List<OrderItemDO> orderItemDOList = OrderItemConvert.INSTANCE.convert(orderItemDTOList); List<OrderItemDO> orderItemDOList = OrderItemConvert.INSTANCE.convert(orderItemDTOList);
// TODO: 2019-03-24 sin 校验商品是否存在 // TODO: 2019-03-24 sin 校验商品是否存在
@ -137,17 +129,10 @@ public class OrderServiceImpl implements OrderService {
// orderItemDO.setPrice(1000); // orderItemDO.setPrice(1000);
// } // }
// 物流信息
orderLogisticsDO
.setLogisticsNo("")
.setCreateTime(new Date())
.setUpdateTime(null);
orderLogisticsMapper.insert(orderLogisticsDO);
// order // order
OrderDO orderDO = new OrderDO() OrderDO orderDO = new OrderDO()
.setUserId(userId) .setUserId(userId)
.setOrderLogisticsId(orderLogisticsDO.getId()) .setOrderLogisticsId(null)
.setOrderNo(UUID.randomUUID().toString().replace("-", "")) .setOrderNo(UUID.randomUUID().toString().replace("-", ""))
.setPayAmount(-1) // 先设置一个默认值金额在下面计算 .setPayAmount(-1) // 先设置一个默认值金额在下面计算
.setClosingTime(null) .setClosingTime(null)
@ -162,6 +147,14 @@ public class OrderServiceImpl implements OrderService {
orderDO.setUpdateTime(null); orderDO.setUpdateTime(null);
orderMapper.insert(orderDO); orderMapper.insert(orderDO);
// 收件人信息
orderRecipientDO
.setOrderId(orderDO.getId())
.setCreateTime(new Date())
.setUpdateTime(null);
orderRecipientMapper.insert(orderRecipientDO);
// order item // order item
orderItemDOList.forEach(orderItemDO -> { orderItemDOList.forEach(orderItemDO -> {
int goodsPrice = 1000; // 商品单价 int goodsPrice = 1000; // 商品单价
@ -271,6 +264,11 @@ public class OrderServiceImpl implements OrderService {
return CommonResult.success(null); return CommonResult.success(null);
} }
@Override
public CommonResult orderDelivery(OrderDeliveryDTO orderDelivery) {
return null;
}
@Override @Override
public CommonResult updateOrderRemake(Integer orderId, String remake) { public CommonResult updateOrderRemake(Integer orderId, String remake) {
// 此处不做订单校验直接设置备注即可 // 此处不做订单校验直接设置备注即可

View File

@ -0,0 +1,35 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.iocoder.mall.order.biz.dao.OrderRecipientMapper">
<sql id="FIELDS">
id, order_id, `area_no`, `name`, mobile, address,
create_time, update_time
</sql>
<!--
插入数据
-->
<insert id="insert" parameterType="OrderRecipientDO" useGeneratedKeys="true" keyColumn="id" keyProperty="id">
INSERT INTO `order_recipient` (
order_id, `area_no`, `name`, mobile, address,
create_time, update_time
) VALUES (
#{orderId}, #{areaNo}, #{name}, #{mobile}, #{address},
#{createTime}, #{updateTime}
)
</insert>
<!--
查询 - 根据 orderIds
-->
<select id="selectByOrderIds" resultType="cn.iocoder.mall.order.biz.dataobject.OrderRecipientDO">
SELECT
<include refid="FIELDS" />
FROM `order_recipient`
WHERE order_id IN
<foreach collection="orderIds" item="orderId" separator="," open="(" close=")">
#{orderId}
</foreach>
</select>
</mapper>