Commit d0a905f0 authored by FE-安焕焕's avatar FE-安焕焕 👣

优化功能

parent 651d3bf1
......@@ -97,6 +97,11 @@ export default {
name: 'deliveryOrder',
component: './orderManage/deliveryOrder',
},
{
path: '/orderManage/batchDelivery',
name: 'batchDeliveryOrder',
component: './orderManage/batchDelivery',
},
{
component: './404',
},
......
......@@ -3,13 +3,13 @@ const isProduction = process.env.NODE_ENV === 'production';
let envAPi = {
api: '//backstms-vcc2.liangkebang.net',
// kdspApi: '//yapi.quantgroups.com/mock/351',
// kdspApi: '//192.168.28.66:80',
kdspApi: 'https://kdsp-op-vcc2.liangkebang.net',
kdspApi: 'http://192.168.28.172:8042',
// kdspApi: 'https://kdsp-op-vcc2.liangkebang.net',
};
let prodApi = {
api: '//backstms.q-gp.com',
kdspApi: '//kdsp-operation.q-gp.com',
kdspApi: '//kdsp-op.q-gp.com',
};
let exportApi;
......
......@@ -47,7 +47,18 @@ const MenuModel = {
return value;
};
const menuData = initializationData(payload);
return { ...state, menuData};
menuData[0].children.push({
children: [],
icon: null,
id: 'b3831ed2-5be8-4dab-a9b4-0965de8a0a5d',
name: '批量发货',
path: '/orderManage/batchDelivery',
picture: null,
type: { name: '菜单', value: 3 },
uri: '/orderManage/batchDelivery',
});
return { ...state, menuData };
},
},
};
......
import { Button, Upload, notification } from 'antd';
import React, { useRef } from 'react';
import { PageHeaderWrapper } from '@ant-design/pro-layout';
import ProTable from '@ant-design/pro-table';
import {
queryToBatchSend,
uploadFile,
downTemplate,
downUploadeOrder,
} from '../pendingDeliveryOrder/service';
const TableList = () => {
const actionRef = useRef();
const columns = [
{
title: '批次号',
dataIndex: 'batchNo',
key: 'batchNo',
align: 'center',
},
{
title: '时间',
key: 'dateTimeRange',
dataIndex: 'createdAtRange',
valueType: 'dateTimeRange',
width: 300,
hideInTable: true,
initialValue: [],
align: 'center',
},
{
title: '操作时间',
dataIndex: 'createdAt',
key: 'createdAt',
hideInSearch: true,
align: 'center',
},
{
title: '操作人',
dataIndex: 'userName',
key: 'userName',
hideInSearch: true,
width: 120,
align: 'center',
},
{
title: '发货单数',
dataIndex: 'totalNum',
key: 'totalNum',
hideInSearch: true,
width: 120,
align: 'center',
},
{
title: '成功发货单数',
dataIndex: 'succNum',
key: 'succNum',
hideInSearch: true,
width: 120,
align: 'center',
},
{
title: '状态',
dataIndex: 'status',
key: 'status',
width: 120,
align: 'center',
filters: [],
valueEnum: {
0: { text: '全部失败' },
1: { text: '全部成功' },
2: { text: '部分成功' },
99: { text: '全部' },
},
initialValue: 1,
},
{
title: '操作',
dataIndex: 'option',
key: 'option',
valueType: 'option',
align: 'center',
render: (_, record) => (
<React.Fragment>
<Button
type="primary"
style={{
marginRight: '10px',
}}
onClick={async () => {
downUploadeOrder({ batchNo: record.batchNo, status: 2 });
}}
>
导出全部数据
</Button>
{record.status === 1 ? (
''
) : (
<Button
type="primary"
style={{
marginRottom: '10px',
}}
onClick={() => {
downUploadeOrder({ batchNo: record.batchNo, status: 0 });
}}
>
导出失败数据
</Button>
)}
</React.Fragment>
),
},
];
const reload = () => {
if (actionRef.current) {
actionRef.current.reload();
}
};
const uploadProps = {
name: 'file',
async customRequest(info) {
const result = await uploadFile(info.file);
if (result.businessCode === '0000') {
reload();
notification.success({ message: '导入成功' });
}
},
accept: '.xlsx',
showUploadList: false,
};
const searchRender = ({ searchText, resetText }, { form }) => {
const exportBtn = [
<Upload {...uploadProps}>
<Button type="primary" style={{ marginRight: '10px' }} key="export">
批量发货
</Button>
</Upload>,
<Button
type="primary"
key="exportTemplate"
onClick={downTemplate}
style={{ marginRight: '10px' }}
>
模板下载
</Button>,
];
return [
<Button
key="search"
type="primary"
style={{ marginRight: '10px' }}
onClick={() => {
// eslint-disable-next-line no-unused-expressions
form?.submit();
}}
>
{searchText}
</Button>,
<Button
key="rest"
style={{ marginRight: '10px' }}
onClick={() => {
// eslint-disable-next-line no-unused-expressions
form?.resetFields();
}}
>
{resetText}
</Button>,
[...exportBtn],
];
};
return (
<PageHeaderWrapper>
<ProTable
actionRef={actionRef}
request={params => queryToBatchSend({ ...params })}
columns={columns}
rowKey={r => r.batchNo}
search={{
collapsed: false,
optionRender: searchRender,
}}
bordered
scroll={{ x: 1500 }}
/>
</PageHeaderWrapper>
);
};
export default TableList;
import React from 'react';
const Image = ({ width, url }) => <img width={width} src={url} alt="" />;
export default Image;
/* eslint-disable no-restricted-syntax */
/* eslint-disable guard-for-in */
import React, { useState, useEffect } from 'react';
import { Modal, Timeline, Tabs } from 'antd';
import style from '../index.less';
import { getLogisticsInfo } from '../service';
const { TabPane } = Tabs;
const LogisticsCom = props => {
const { modalVisible, onCancel } = props;
const [result, setResult] = useState({});
const getInfo = async (companyCode, logisticsNo) => {
const data = await getLogisticsInfo(companyCode, logisticsNo);
return data;
};
useEffect(() => {
setResult(props.value);
});
const callback = async key => {
const params = key.split('+');
if (result[params[1]]?.detailList) {
return;
}
const data = getInfo(params[0], params[1]);
result[params[1]].detailList = data?.logisticsList?.[0]?.detailList ?? [];
};
const render = () => {
const dom = [];
// eslint-disable-next-line guard-for-in
// eslint-disable-next-line no-restricted-syntax
for (const key in result) {
const value = result[key];
dom.push(
<TabPane
className={style.tabpane}
tab={value?.expressCompanyName + value?.deliveryNo}
key={`${value?.expressCompanyCode} + ${key}`}
tabBarStyle={{ height: '200px' }}
>
{value?.detailList?.length ? (
<Timeline>
{value?.detailList?.map((item, index) => (
<Timeline.Item color={index > 0 ? 'gray' : 'blue'}>
<p>{item.desc}</p>
<p>{item.logisticsTime}</p>
</Timeline.Item>
))}
</Timeline>
) : (
'暂无物流信息'
)}
</TabPane>,
);
}
return dom;
};
return (
<Modal
destroyOnClose
title="企业物流信息"
visible={modalVisible}
onCancel={() => onCancel()}
onOk={() => onCancel()}
afterClose={() => setResult({})}
bodyStyle={{ maxHeight: '600px', minHeight: '200px', overflow: 'auto' }}
>
<Tabs defaultActiveKey="1" onChange={callback}>
{render()}
</Tabs>
</Modal>
);
};
export default LogisticsCom;
import React from 'react';
import { Popover } from 'antd';
import Image from './Image';
const PopoverDom = ({ name, url }) => {
const content = <Image width={300} url={url} />;
return (
<Popover content={content} title={name}>
{Image({ width: 50, url })}
</Popover>
);
};
export default PopoverDom;
import { Button, Upload, notification } from 'antd';
import { Button } from 'antd';
import React, { useState, useEffect, useRef } from 'react';
import { PageHeaderWrapper } from '@ant-design/pro-layout';
import ProTable from '@ant-design/pro-table';
import { FormInstance } from 'antd/lib/form';
import LogisticsForm from './components/LogisticsForm';
import style from './styles.less';
import PopoverDom from './components/PreviewImage';
import LogisticsCom from './components/LogisticsCom';
import {
queryToSend,
queryExpress,
getGoods,
uploadFile,
getLogistics,
downTemplate,
downOrder,
getLogisticsInfo,
} from './service';
const TableList = props => {
......@@ -21,6 +22,8 @@ const TableList = props => {
const [skuList, setSkuList] = useState([]);
const [LogisticsData, setLogisticsData] = useState([{}]);
const [ShowUpdateBtn] = useState([2, 5]);
const [LogisticsComList, setLogisticsComList] = useState({});
const [LogisticsComModalVisible, handleComModalVisible] = useState(false);
const actionRef = useRef();
const ref = useRef(FormInstance);
......@@ -32,9 +35,29 @@ const TableList = props => {
index < record?.mchOrderSkuVoList?.length - 1 ? 'border' : null,
].join(' ')}
>
{key === 'skuName' ? <PopoverDom name={item[key]} url={item.imageUrl} /> : ''}
{item[key]}
</p>
));
const handleCom = async record => {
const tempObj = {};
// eslint-disable-next-line no-unused-expressions
record?.mchOrderSkuVoList?.forEach(item => {
if (!(item.deliveryNo in tempObj)) {
tempObj[item.deliveryNo] = {
deliveryNo: item.deliveryNo,
expressCompanyCode: item.expressCompanyCode,
expressCompanyName: item.expressCompanyName,
};
}
});
const keys = Object.keys(tempObj);
const firstObj = tempObj[keys[0]];
const data = await getLogisticsInfo(firstObj?.expressCompanyCode, firstObj?.deliveryNo);
tempObj[keys[0]].detailList = data?.logisticsList?.[0]?.detailList || [];
setLogisticsComList(tempObj);
handleComModalVisible(true);
};
const columns = [
{
title: '订单ID',
......@@ -58,36 +81,6 @@ const TableList = props => {
hideInSearch: true,
width: 200,
},
{
title: '收货人手机',
dataIndex: 'receiverPhone',
key: 'receiverPhone',
order: 4,
width: 150,
},
{
title: '收货人姓名',
dataIndex: 'receiverName',
key: 'receiverName',
order: 3,
width: 120,
},
{
title: '收货地址',
dataIndex: 'fullAddress',
key: 'fullAddress',
hideInSearch: true,
width: 350,
},
{
title: '商品自编码',
dataIndex: 'thirdSpuNo',
key: 'thirdSpuNo',
width: 120,
hideInSearch: true,
className: 'colStyle',
render: (_, record) => renderContent(record, 'thirdSpuNo'),
},
{
title: '商品名称',
dataIndex: 'skuName',
......@@ -115,6 +108,37 @@ const TableList = props => {
hideInSearch: true,
render: (_, record) => renderContent(record, 'count'),
},
{
title: '商品自编码',
dataIndex: 'thirdSpuNo',
key: 'thirdSpuNo',
width: 120,
hideInSearch: true,
className: 'colStyle',
render: (_, record) => renderContent(record, 'thirdSpuNo'),
},
{
title: '收货人手机',
dataIndex: 'receiverPhone',
key: 'receiverPhone',
order: 4,
width: 150,
},
{
title: '收货人姓名',
dataIndex: 'receiverName',
key: 'receiverName',
order: 3,
width: 120,
},
{
title: '收货地址',
dataIndex: 'fullAddress',
key: 'fullAddress',
hideInSearch: true,
width: 350,
},
{
title: '物流公司',
dataIndex: 'expressCompanyName',
......@@ -193,11 +217,25 @@ const TableList = props => {
{props.type === 2 ? '更新物流信息' : '填写物流信息'}
</Button>
)}
{props.type === 2 ? (
<Button
type="primary"
style={{
marginBottom: '10px',
}}
onClick={() => {
handleCom(record);
}}
>
查询物流信息
</Button>
) : (
''
)}
</React.Fragment>
),
},
];
const reload = () => {
handleModalVisible(false);
if (actionRef.current) {
......@@ -212,17 +250,6 @@ const TableList = props => {
};
getCompanys();
}, []);
const uploadProps = {
name: 'file',
async customRequest(info) {
const result = await uploadFile(info.file);
if (result.businessCode === '0000') {
notification.success({ message: '导入成功' });
}
},
accept: '.xlsx',
showUploadList: false,
};
const queryToSendFn = params => {
const transformedParam = {
......@@ -234,47 +261,30 @@ const TableList = props => {
};
return queryToSend(transformedParam);
};
const searchRender = ({ searchText, resetText }, { form }) => {
const exportBtn = [
<Upload {...uploadProps}>
<Button type="primary" style={{ marginRight: '10px' }} key="export">
导入
</Button>
</Upload>,
<Button
type="primary"
key="exportTemplate"
onClick={downTemplate}
style={{ marginRight: '10px' }}
>
导入模板下载
</Button>,
];
return [
<Button
key="search"
type="primary"
style={{ marginRight: '10px' }}
onClick={() => {
// eslint-disable-next-line no-unused-expressions
form?.submit();
}}
>
{searchText}
</Button>,
<Button
key="rest"
style={{ marginRight: '10px' }}
onClick={() => {
// eslint-disable-next-line no-unused-expressions
form?.resetFields();
}}
>
{resetText}
</Button>,
props.type === 2 ? null : [...exportBtn],
];
};
const searchRender = ({ searchText, resetText }, { form }) => [
<Button
key="search"
type="primary"
style={{ marginRight: '10px' }}
onClick={() => {
// eslint-disable-next-line no-unused-expressions
form?.submit();
}}
>
{searchText}
</Button>,
<Button
key="rest"
style={{ marginRight: '10px' }}
onClick={() => {
// eslint-disable-next-line no-unused-expressions
form?.resetFields();
}}
>
{resetText}
</Button>,
// props.type === 2 ? null : [...exportBtn],
];
const toolBarRenderFn = () => [
<Button
......@@ -314,6 +324,12 @@ const TableList = props => {
modalVisible={LogisticsModalVisible}
value={LogisticsData}
/>
<LogisticsCom
onSubmit={reload}
onCancel={() => handleComModalVisible(false)}
modalVisible={LogisticsComModalVisible}
value={LogisticsComList}
/>
</PageHeaderWrapper>
);
};
......
......@@ -76,3 +76,56 @@ export async function downOrder(params) {
const blob = new Blob([data]);
saveAs(blob, `商户订单列表-${format(new Date(), 'yyyyMMddHHmmss')}.xlsx`);
}
export async function getLogisticsInfo(companyCode, logisticsNo) {
const { data } = await request.get(
`/api/kdsp/op/logistics/kd100/track-list?companyCode=${companyCode}&logisticsNo=${logisticsNo}`,
{
prefix: config.kdspApi,
},
);
return data;
}
// 批量发货订单
export async function queryToBatchSend(params) {
const transformedParam = {
pageNo: params.current,
pageSize: params.pageSize || 20,
startTime: params.dateTimeRange?.[0],
endTime: params.dateTimeRange?.[1],
status: params?.status ?? 99,
batchNo: params.batchNo,
};
const {
data: { current, records, total, size },
} = await request.get('/api/kdsp/op/mch-order/delivery-batch-list', {
prefix: config.kdspApi,
params: _.omitBy(transformedParam, v => !v),
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
});
return {
current,
data: records.map(v => ({ ...v })),
total,
pageSize: size,
};
}
export async function downUploadeOrder(params) {
const data = await request.get('/api/kdsp/op/mch-order/delivery-batch-order-downLoad', {
params,
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
prefix: config.kdspApi,
responseType: 'arrayBuffer',
});
const blob = new Blob([data]);
const status = {
0: '失败数据',
1: '成功数据',
2: '全部数据',
};
saveAs(blob, `批量发货-${status[params.status]}-${format(new Date(), 'yyyyMMddHHmmss')}.xlsx`);
}
......@@ -2,7 +2,7 @@
:global {
.tableContent {
display: flex;
align-items: flex-end;
align-items: center;
height: 60px;
padding: 16px;
}
......@@ -12,5 +12,18 @@
tbody .colStyle {
padding: 0;
}
.ant-popover-title {
max-width: 300px;
overflow: hidden;
}
}
}
.tabpane {
:global {
.ant-tabs-content {
min-height: 200px;
max-height: 700px;
overflow: auto;
}
}
}
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