Commit 88d8c72aeb8066aefacd3fbeb549d36440d690b4

Authored by zhongnanhuang
2 parents 051aac20 3553409f

Merge branch 'znh231128' into 'develop'

feat: update



See merge request !9
src/pages/Order/components/CheckModal.tsx
... ... @@ -6,7 +6,7 @@ export default ({ setCheckVisible, data, subOrders, onClose }) => {
6 6 const [form] = Form.useForm<{ name: string; company: string }>();
7 7 let subOrderIds: any[] = [];
8 8 //是单条子订单审核
9   - if (subOrders === null) {
  9 + if (subOrders === undefined) {
10 10 subOrderIds = [data.id];
11 11 } else {
12 12 subOrderIds = subOrders.map((subOrder) => subOrder.id);
... ... @@ -17,9 +17,8 @@ export default ({ setCheckVisible, data, subOrders, onClose }) =&gt; {
17 17 });
18 18 if (data.result === RESPONSE_CODE.SUCCESS) {
19 19 message.success(data.message);
  20 + onClose();
20 21 }
21   - onClose();
22   - return true;
23 22 }
24 23 return (
25 24 <ModalForm<{
... ...
src/pages/Order/components/DeliverModal.tsx
... ... @@ -13,7 +13,7 @@ import { cloneDeep } from &#39;lodash&#39;;
13 13 import { useEffect, useRef, useState } from 'react';
14 14 import { LOGISTICS_STATUS_OPTIONS } from '../constant';
15 15  
16   -const DeliverModal = ({ data: propsData, onClose }) => {
  16 +const DeliverModal = ({ data: propsData, isSendProduct, onClose }) => {
17 17 const [data, setData] = useState(propsData || {});
18 18 const form = useRef();
19 19  
... ... @@ -21,9 +21,14 @@ const DeliverModal = ({ data: propsData, onClose }) =&gt; {
21 21 setData(propsData);
22 22 }, [propsData]);
23 23  
24   - const handleChange = (key: string, index: number) => (e) => {
  24 + const handleChange = (key: string, index: number, obj: any) => {
25 25 const newData = cloneDeep(data);
26   - newData[index][key] = e.target.value;
  26 + if (typeof obj !== 'object') {
  27 + newData[index][key] = obj;
  28 + } else {
  29 + newData[index][key] = obj.target?.value;
  30 + }
  31 +
27 32 setData(newData);
28 33 };
29 34 const columns: ProColumns<any>[] = [
... ... @@ -60,15 +65,29 @@ const DeliverModal = ({ data: propsData, onClose }) =&gt; {
60 65 render: (_, record) => <InputNumber value={record.quantity} disabled />,
61 66 },
62 67 {
  68 + title: '包裹数量',
  69 + width: 80,
  70 + dataIndex: 'packageNumber',
  71 + render: (_, record) => (
  72 + <InputNumber
  73 + value={record.packageNumber}
  74 + onChange={(value) => (record.packageNumber = value)}
  75 + />
  76 + ),
  77 + },
  78 + {
63 79 title: '物流方式',
64 80 width: 150,
65 81 key: 'logisticsMethod',
66   - render: (_, record) => (
  82 + render: (_, record, index) => (
67 83 <Select
  84 + style={{ minWidth: 150 }}
68 85 placeholder="请输入物流方式"
69 86 value={record.logisticsMethod}
70 87 options={enumToSelect(LOGISTICS_STATUS_OPTIONS)}
71   - onChange={(value) => (record.logisticsMethod = value)} //修改时更改record数据
  88 + onChange={(value) => {
  89 + handleChange('logisticsMethod', index, value);
  90 + }} //修改时更改record数据
72 91 />
73 92 ),
74 93 },
... ... @@ -80,7 +99,9 @@ const DeliverModal = ({ data: propsData, onClose }) =&gt; {
80 99 <Input
81 100 placeholder="请输入物流单号"
82 101 value={record.serialNumber}
83   - onChange={handleChange('serialNumber', index)}
  102 + onChange={(value) => {
  103 + handleChange('serialNumber', index, value);
  104 + }}
84 105 />
85 106 ),
86 107 },
... ... @@ -89,8 +110,8 @@ const DeliverModal = ({ data: propsData, onClose }) =&gt; {
89 110 return (
90 111 <Modal
91 112 open
92   - width={800}
93   - title="发货"
  113 + width={900}
  114 + title={isSendProduct ? '发货' : '修改发货信息'}
94 115 onOk={async () => {
95 116 //请求体封装
96 117 let list = data.map((item) => {
... ... @@ -98,10 +119,13 @@ const DeliverModal = ({ data: propsData, onClose }) =&gt; {
98 119 id: item.id,
99 120 logisticsMethod: item.logisticsMethod,
100 121 serialNumber: item.serialNumber,
  122 + packageNumber: item.packageNumber,
101 123 };
102 124 });
103   - let body = { id: data[0].mainOrderId, list: list };
104   - console.log(body);
  125 + let body = { id: data[0].mainOrderId, list: list, flag: false };
  126 + if (isSendProduct) {
  127 + body.flag = true;
  128 + }
105 129 //发货请求
106 130 const res = await postServiceOrderSendProduct({ data: body });
107 131 if (res.result === RESPONSE_CODE.SUCCESS) {
... ...
src/pages/Order/components/FinancialDrawer.tsx
... ... @@ -8,17 +8,10 @@ import {
8 8 DrawerForm,
9 9 ProFormDatePicker,
10 10 ProFormText,
  11 + ProFormTextArea,
11 12 } from '@ant-design/pro-components';
12 13 import { Form, message } from 'antd';
13 14  
14   -// const waitTime = (time: number = 100) => {
15   -// return new Promise((resolve) => {
16   -// setTimeout(() => {
17   -// resolve(true);
18   -// }, time);
19   -// });
20   -// };
21   -
22 15 export default ({ mainOrder, subOrders, isEdit, onClose }) => {
23 16 const subIds = subOrders.map((item) => item.id);
24 17 console.log(subOrders);
... ... @@ -49,10 +42,10 @@ export default ({ mainOrder, subOrders, isEdit, onClose }) =&gt; {
49 42 let body = {
50 43 invoicingTime: form.getFieldValue('invoicingTime'),
51 44 subIds: subIds,
52   - collectMoneyTime: undefined,
  45 + collectMoneyTime: form.getFieldValue('collectMoneyTime'),
  46 + invoicingNotes: form.getFieldValue('invoicingNotes'),
53 47 };
54 48 if (isEdit) {
55   - body.collectMoneyTime = form.getFieldValue('collectMoneyTime');
56 49 res = await postServiceOrderEditOrder({ data: body });
57 50 } else {
58 51 res = await postServiceOrderInvoicing({ data: body });
... ... @@ -101,6 +94,13 @@ export default ({ mainOrder, subOrders, isEdit, onClose }) =&gt; {
101 94 label="收款时间"
102 95 initialValue={subOrders[0].collectMoneyTime}
103 96 />
  97 +
  98 + <ProFormTextArea
  99 + width="lg"
  100 + name="invoicingNotes"
  101 + label="备注"
  102 + initialValue={subOrders[0].invoicingNotes}
  103 + />
104 104 </DrawerForm>
105 105 );
106 106 };
... ...
src/pages/Order/components/LazySelect.tsx 0 → 100644
  1 +import { Select, Spin } from 'antd';
  2 +import debounce from 'lodash/debounce';
  3 +import difference from 'lodash/difference';
  4 +import { useEffect, useState } from 'react';
  5 +
  6 +/**
  7 + * 懒加载 Select ,适用于数据超大的下拉框
  8 + * @param {Select 官方属性} props
  9 + */
  10 +const LazySelect = (props) => {
  11 + const { value, onChange, query, pageSize } = props;
  12 + // 清除 porps 中 query,避免控制台警告
  13 + const selectProps = { ...props, query: undefined };
  14 +
  15 + const [selected, setSelected] = useState(value);
  16 + const [data, setData] = useState([]);
  17 + const [loading, setLoading] = useState(false);
  18 + const [current, setCurrent] = useState(1);
  19 + const [total, setTotal] = useState(0);
  20 + const [searchText] = useState('');
  21 +
  22 + const getSelectedArray = (obj) => {
  23 + let selectedValues = obj;
  24 + // 如果是单选,将值封装为数组
  25 + if (obj && obj instanceof Array === false) {
  26 + selectedValues = [obj];
  27 + }
  28 + return selectedValues;
  29 + };
  30 +
  31 + // 添加 300 毫秒防抖
  32 + const handleQuery = debounce(async (param) => {
  33 + setLoading(true);
  34 + const resp = await query(param);
  35 + const resData = resp.data;
  36 + let options = resData?.data?.map((p: any) => {
  37 + return {
  38 + ...p,
  39 + label: p.productName,
  40 + value: p.productName,
  41 + key: p.id,
  42 + };
  43 + });
  44 + // 搜索服务端异步加载
  45 + // const handleSearch = (filter) => {
  46 + // setSearchText(filter);
  47 + // handleQuery({
  48 + // filter,
  49 + // selectedValues: getSelectedArray(selected),
  50 + // pageSize,
  51 + // current
  52 + // });
  53 + // };
  54 +
  55 + //第一个商品默认为要新增的商品
  56 + // if (searchValue?.trim() !== "") {
  57 + // options.unshift({ productName: searchValue, type: "add", label: searchValue, value: searchValue })
  58 + // }
  59 + // return options;
  60 + setTotal(resData.total);
  61 + setData(data.concat(options));
  62 + setLoading(false);
  63 + }, 300);
  64 +
  65 + // 组件初始化时加载一次数据
  66 + useEffect(() => {
  67 + handleQuery({
  68 + filter: '',
  69 + selectedValues: getSelectedArray(value),
  70 + });
  71 + }, []);
  72 +
  73 + // 外部注入的 value 变化后,如果 value 在 data 中不存在,则加载数据
  74 + useEffect(() => {
  75 + setSelected(value);
  76 + const dataKeys = data.map((item) => item.value);
  77 + const diff = difference(getSelectedArray(value), dataKeys);
  78 + if (diff && diff.length > 0) {
  79 + handleQuery({
  80 + filter: '',
  81 + selectedValues: getSelectedArray(value),
  82 + });
  83 + }
  84 + }, [value]);
  85 +
  86 + const keywordChange = (newWord: string) => {
  87 + setData([]);
  88 + setTotal(0);
  89 + setCurrent(1);
  90 + handleSearch(newWord);
  91 + };
  92 +
  93 + const handleChange = (newValue, option) => {
  94 + setSelected(newValue);
  95 + if (onChange) {
  96 + // 将值通过 onChange 传递到外部
  97 + onChange(newValue, option);
  98 + }
  99 + };
  100 +
  101 + const scrollEnd = (e) => {
  102 + e.persist();
  103 + const { target } = e;
  104 + // 滚动 触底 看接口是否还有剩余的值没传过来
  105 + if (target.scrollTop + target.offsetHeight === target.scrollHeight) {
  106 + if (current * pageSize < total) {
  107 + setCurrent(current + 1);
  108 + handleSearch(searchText);
  109 + }
  110 + }
  111 + };
  112 +
  113 + return (
  114 + <Select
  115 + {...selectProps}
  116 + value={selected}
  117 + loading={loading}
  118 + onSearch={keywordChange}
  119 + onChange={handleChange}
  120 + onPopupScroll={scrollEnd}
  121 + filterOption={false}
  122 + options={data}
  123 + showSearch
  124 + showArrow
  125 + notFoundContent={loading ? <Spin size="small" /> : null}
  126 + >
  127 + {/* {data.map(d => (
  128 + <Option key={d.value} title={d.label}>
  129 + {d.label}
  130 + </Option>
  131 + ))} */}
  132 + </Select>
  133 + );
  134 +};
  135 +
  136 +export default LazySelect;
... ...
src/pages/Order/components/OrderDrawer.tsx
... ... @@ -17,17 +17,19 @@ import {
17 17 ProFormTextArea,
18 18 } from '@ant-design/pro-components';
19 19 import { Form, message } from 'antd';
  20 +import { cloneDeep } from 'lodash';
20 21 import { useEffect, useRef, useState } from 'react';
21 22 import {
22 23 INVOCING_STATUS_OPTIONS,
23 24 PAYMENT_CHANNEL_OPTIONS,
24 25 PAYMENT_METHOD_OPTIONS,
25 26 PRODUCT_BELONG_DEPARTMENT_OPTIONS,
  27 + SALES_CODE_OPTIONS,
26 28 } from '../constant';
27 29  
28 30 export default ({ onClose, data, subOrders, orderOptType }) => {
29 31 const [invoicingStatus, setInvoicingStatus] = useState('');
30   -
  32 + let originSubOrders = cloneDeep(subOrders);
31 33 /**
32 34 * 获取当前的操作类型boolean值
33 35 * @param type 操作类型,如果与当前匹配返回true
... ... @@ -35,6 +37,15 @@ export default ({ onClose, data, subOrders, orderOptType }) =&gt; {
35 37 function optType(type: string) {
36 38 return orderOptType === type;
37 39 }
  40 + // 页码,及搜索值变化时,发请求
  41 + // const fatchData = async (params:string) => {
  42 + // console.log(params);
  43 + // const res =
  44 + // await postServiceOrderQueryProductInformation({
  45 + // data: { productName: params.filter }
  46 + // });
  47 + // return res;
  48 + // }
38 49  
39 50 useEffect(() => {
40 51 // 在组件挂载或数据变化时,更新组件状态
... ... @@ -92,8 +103,6 @@ export default ({ onClose, data, subOrders, orderOptType }) =&gt; {
92 103 name: string;
93 104 }>
94 105 >();
95   - //作为商品行号
96   - const rowNumber = useRef(0);
97 106  
98 107 useEffect(() => {
99 108 form.setFieldsValue({ ...data });
... ... @@ -141,6 +150,7 @@ export default ({ onClose, data, subOrders, orderOptType }) =&gt; {
141 150 autoFocusFirstInput
142 151 drawerProps={{
143 152 destroyOnClose: true,
  153 + maskClosable: false,
144 154 }}
145 155 submitTimeout={2000}
146 156 onFinish={async (values) => {
... ... @@ -149,7 +159,7 @@ export default ({ onClose, data, subOrders, orderOptType }) =&gt; {
149 159 res = await postServiceOrderAddOrder({ data: values });
150 160 } else {
151 161 //计算已删除的子订单id
152   - const originIds = data.subOrderInformationLists.map((item) => {
  162 + const originIds = originSubOrders.map((item) => {
153 163 return item.id;
154 164 });
155 165 console.log('originIds:' + originIds);
... ... @@ -158,9 +168,6 @@ export default ({ onClose, data, subOrders, orderOptType }) =&gt; {
158 168 });
159 169 console.log('curIds:' + curIds);
160 170 let diff = originIds.filter((item) => !curIds.includes(item));
161   - if (mainInfoDisbled) {
162   - diff = [];
163   - }
164 171 values.deleteSubOrderLists = diff;
165 172 res = await postServiceOrderUpdateOrder({ data: values });
166 173 }
... ... @@ -168,7 +175,7 @@ export default ({ onClose, data, subOrders, orderOptType }) =&gt; {
168 175 if (res.result === RESPONSE_CODE.SUCCESS) {
169 176 message.success(res.message);
170 177 // 不返回不会关闭弹框
171   - onClose();
  178 + onClose(true);
172 179 return true;
173 180 }
174 181 }}
... ... @@ -185,13 +192,15 @@ export default ({ onClose, data, subOrders, orderOptType }) =&gt; {
185 192 placeholder="id"
186 193 hidden
187 194 />
188   - <ProFormText
  195 + <ProFormSelect
189 196 name="salesCode"
190 197 width="lg"
191   - disabled
  198 + showSearch
192 199 label="销售代表"
193 200 placeholder="请输入销售代表"
194   - initialValue={getUserInfo().nickName}
  201 + options={SALES_CODE_OPTIONS}
  202 + rules={[{ required: true, message: '销售代表必填' }]}
  203 + disabled={mainInfoDisbled}
195 204 />
196 205 <ProFormText
197 206 name="customerName"
... ... @@ -275,8 +284,12 @@ export default ({ onClose, data, subOrders, orderOptType }) =&gt; {
275 284 options={enumToSelect(INVOCING_STATUS_OPTIONS)}
276 285 disabled={mainInfoDisbled}
277 286 onChange={(_, option) => {
278   - console.log(option);
279 287 setInvoicingStatus(option.value);
  288 + if (option.value === 'UN_INVOICE') {
  289 + form.setFieldValue('invoiceIdentificationNumber', undefined);
  290 + form.setFieldValue('bank', undefined);
  291 + form.setFieldValue('bankAccountNumber', undefined);
  292 + }
280 293 }}
281 294 rules={[{ required: true, message: '是否需要开票必填' }]}
282 295 />
... ... @@ -336,98 +349,6 @@ export default ({ onClose, data, subOrders, orderOptType }) =&gt; {
336 349 placeholder="请输入备注"
337 350 />
338 351  
339   - {/* <h2>商品基本信息</h2>
340   - <ProFormText width="lg" name="totalPayment" label="支付总金额" />
341   - <ProFormSelect
342   - disabled
343   - placeholder="请输入物流方式"
344   - name="logisticsMethod"
345   - width="lg"
346   - label="物流方式"
347   - request={async () => {
348   - // 发送请求获取选项数据
349   - const { data } = await getServiceOrderProvideLogisticsStatus();
350   - return enumToSelect(data);
351   - }}
352   - />
353   - <ProFormText
354   - width="lg"
355   - name="paymentStatus"
356   - label="支付状态"
357   - placeholder="请输入支付状态"
358   - />
359   -
360   - <ProFormSelect
361   - placeholder="请输入支付方式"
362   - name="paymentMethod"
363   - width="lg"
364   - label="支付方式"
365   - request={async () => {
366   - // 发送请求获取选项数据
367   - const { data } = await getServiceOrderProvidePaymentMethod();
368   - return enumToSelect(data);
369   - }}
370   - />
371   - <ProFormSelect
372   - placeholder="请输入支付渠道"
373   - name="paymentChannel"
374   - width="lg"
375   - label="支付渠道"
376   - request={async () => {
377   - // 发送请求获取选项数据
378   - const { data } = await getServiceOrderProvidePaymentChannel();
379   - return enumToSelect(data);
380   - }}
381   - />
382   - <ProFormText
383   - width="lg"
384   - name="paymentTransactionId"
385   - label="支付流水号"
386   - placeholder="请输入支付流水号"
387   - />
388   - <ProFormText
389   - width="lg"
390   - name="invoiceInformation"
391   - label="发票信息"
392   - placeholder="请输入发票信息"
393   - />
394   - <ProFormText
395   - width="lg"
396   - name="invoicingStatus"
397   - label="开票状态"
398   - placeholder="请输入开票状态"
399   - />
400   - <ProFormText
401   - width="lg"
402   - name="productBelongDepartment"
403   - label="商品所属部门"
404   - placeholder="请输入商品所属部门"
405   - />
406   - <ProFormText
407   - width="lg"
408   - name="waybillNumber"
409   - label="运单号"
410   - placeholder="请输入运单号"
411   - />
412   - <ProFormText
413   - width="lg"
414   - name="notes"
415   - label="备注"
416   - placeholder="请输入备注"
417   - />
418   - <ProFormText
419   - width="lg"
420   - name="examineNotes"
421   - label="审核备注"
422   - placeholder="请输入审核备注"
423   - />
424   - <ProFormText
425   - width="lg"
426   - name="orderStatus"
427   - label="订单状态"
428   - placeholder="请输入订单状态"
429   - /> */}
430   -
431 352 <h2>商品信息</h2>
432 353 <ProFormList
433 354 creatorButtonProps={{ disabled: false }}
... ... @@ -444,12 +365,11 @@ export default ({ onClose, data, subOrders, orderOptType }) =&gt; {
444 365 },
445 366 ]}
446 367 actionGuard={{
447   - beforeAddRow: async () => {
448   - return new Promise((resolve) => {
449   - rowNumber.current = 1;
450   - setTimeout(() => resolve(true), 1000);
451   - });
452   - },
  368 + // beforeAddRow: async () => {
  369 + // return new Promise((resolve) => {
  370 + // setTimeout(() => resolve(true), 1000);
  371 + // });
  372 + // },
453 373 beforeRemoveRow: async (index) => {
454 374 return new Promise((resolve) => {
455 375 if (index === 0) {
... ... @@ -457,7 +377,6 @@ export default ({ onClose, data, subOrders, orderOptType }) =&gt; {
457 377 resolve(false);
458 378 return;
459 379 }
460   - rowNumber.current = 1;
461 380 setTimeout(() => {
462 381 resolve(true);
463 382 }, 1000);
... ... @@ -470,30 +389,77 @@ export default ({ onClose, data, subOrders, orderOptType }) =&gt; {
470 389 <ProCard
471 390 bordered
472 391 extra={doms.action}
473   - title={'商品' + rowNumber.current++}
  392 + title={'商品' + (listMeta.index + 1)}
474 393 style={{
475 394 marginBlockEnd: 8,
476 395 }}
477 396 >
478 397 {[
  398 + // <LazySelect query={fatchData} pageSize={10}></LazySelect>
  399 + // ,
479 400 <ProFormSelect
480 401 key="key"
481 402 label="商品名称"
482 403 width="lg"
483 404 showSearch
484 405 name="productName"
  406 + // options={options}
485 407 placeholder="请搜索商品"
486 408 rules={[{ required: true, message: '商品名称必填' }]}
487 409 onChange={(_, option) => {
488 410 autoFillProductInfo(option, listMeta);
489 411 }}
490   - request={async (value) => {
491   - console.log(value);
  412 + fieldProps={{
  413 + // filterOption:false,
  414 + // onSearch: searchDataset,
  415 + // onPopupScroll: scrollEnd,
  416 + optionItemRender(item) {
  417 + if (item.type === 'add') {
  418 + return (
  419 + <div title={item.productName + '(新增商品信息)'}>
  420 + <span style={{ color: '#333333' }}>
  421 + {item.productName}
  422 + </span>
  423 + {' | '}
  424 + <span style={{ color: 'orange' }}>新增商品</span>
  425 + </div>
  426 + );
  427 + }
  428 + return (
  429 + <div
  430 + title={
  431 + item.label +
  432 + ' | ' +
  433 + (item.specifications === undefined
  434 + ? '无参数'
  435 + : item.specifications) +
  436 + ' | ' +
  437 + item.unit
  438 + }
  439 + >
  440 + <span style={{ color: '#333333' }}>{item.label}</span>
  441 + {' | '}
  442 + <span style={{ color: '#339999' }}>
  443 + {item.specifications === undefined
  444 + ? '无参数'
  445 + : item.specifications}
  446 + </span>
  447 + {' | '}
  448 + <span style={{ color: '#666666' }}>
  449 + {item.unit === undefined ? '无单位' : item.unit}
  450 + </span>
  451 + </div>
  452 + );
  453 + },
  454 + }}
  455 + request={async (value, { params }) => {
  456 + const keywords = value.keyWords;
492 457 const { data } =
493 458 await postServiceOrderQueryProductInformation({
494   - data: { productName: value.keyWords },
  459 + data: { productName: keywords },
  460 + params: params,
495 461 });
496   - return data.map((p: any) => {
  462 + let options = data.map((p: any) => {
497 463 return {
498 464 ...p,
499 465 label: p.productName,
... ... @@ -501,6 +467,17 @@ export default ({ onClose, data, subOrders, orderOptType }) =&gt; {
501 467 key: p.id,
502 468 };
503 469 });
  470 +
  471 + //第一个商品默认为要新增的商品
  472 + if (keywords.trim() !== '') {
  473 + options.unshift({
  474 + productName: keywords,
  475 + type: 'add',
  476 + label: keywords,
  477 + value: keywords,
  478 + });
  479 + }
  480 + return options;
504 481 }}
505 482 />,
506 483 doms.listDom,
... ... @@ -514,15 +491,22 @@ export default ({ onClose, data, subOrders, orderOptType }) =&gt; {
514 491 width="lg"
515 492 name="productCode"
516 493 disabled
517   - label="商品编码"
  494 + label={
  495 + <>
  496 + <span>商品编码</span>
  497 + <span className="text-gray-400 text-xs pl-2">
  498 + 新增商品时,商品编码由系统自动生成
  499 + </span>
  500 + </>
  501 + }
518 502 placeholder="未输入商品名称"
519 503 />
520 504 <ProFormText
521 505 width="lg"
522   - disabled
523 506 name="parameters"
524 507 label="商品参数"
525 508 placeholder="请输入商品参数"
  509 + rules={[{ required: true, message: '商品参数必填' }]}
526 510 />
527 511 <ProFormDigit
528 512 width="lg"
... ... @@ -541,7 +525,6 @@ export default ({ onClose, data, subOrders, orderOptType }) =&gt; {
541 525 <ProFormText
542 526 width="lg"
543 527 name="unit"
544   - disabled
545 528 label="商品单位"
546 529 placeholder="请输入商品单位"
547 530 rules={[{ required: true, message: '商品单位必填' }]}
... ...
src/pages/Order/components/SubOrderNotesEditModal.tsx renamed to src/pages/Order/components/OrderNotesEditModal.tsx
... ... @@ -2,7 +2,7 @@ import { RESPONSE_CODE } from &#39;@/constants/enum&#39;;
2 2 import { postServiceOrderDetails } from '@/services';
3 3 import { ModalForm, ProFormTextArea } from '@ant-design/pro-components';
4 4 import { Form, message } from 'antd';
5   -export default ({ setNotesEditVisible, data, onClose }) => {
  5 +export default ({ setNotesEditVisible, data, isMianOrder, onClose }) => {
6 6 const [form] = Form.useForm<{ name: string; company: string }>();
7 7 return (
8 8 <ModalForm<{
... ... @@ -24,7 +24,11 @@ export default ({ setNotesEditVisible, data, onClose }) =&gt; {
24 24 }}
25 25 submitTimeout={2000}
26 26 onFinish={async (values) => {
27   - let body = { id: data.id, notes: values.name };
  27 + let body = {
  28 + id: data.id,
  29 + notes: values.name,
  30 + checkSubOrderOrMainOrder: isMianOrder,
  31 + };
28 32 const res = await postServiceOrderDetails({ data: body });
29 33 if (res.result === RESPONSE_CODE.SUCCESS) {
30 34 message.success(res.message);
... ...
src/pages/Order/components/SubOrderComfirmReceiptImagesModal.tsx 0 → 100644
  1 +import { postServiceOrderViewImages } from '@/services';
  2 +import { Button, Divider, Image, Modal } from 'antd';
  3 +import { useEffect, useState } from 'react';
  4 +export default ({ setVisible, onClose, orderRow }) => {
  5 + const [images, setImages] = useState([]);
  6 + const handleOk = () => {
  7 + onClose();
  8 + setVisible(false);
  9 + };
  10 +
  11 + const handleCancel = () => {
  12 + onClose();
  13 + setVisible(false);
  14 + };
  15 +
  16 + async function getImages() {
  17 + const res = await postServiceOrderViewImages({
  18 + data: { subId: orderRow.id },
  19 + });
  20 + const images = res.data;
  21 + setImages(images);
  22 + }
  23 + useEffect(() => {
  24 + getImages();
  25 + }, []);
  26 +
  27 + return (
  28 + <>
  29 + <Modal
  30 + title="收货凭证"
  31 + open
  32 + onOk={handleOk}
  33 + onCancel={handleCancel}
  34 + footer={[
  35 + <Button key="back" onClick={handleCancel}>
  36 + 返回
  37 + </Button>,
  38 + ]}
  39 + >
  40 + <Image.PreviewGroup
  41 + className="mr-10"
  42 + preview={{
  43 + onChange: (current, prev) =>
  44 + console.log(`current index: ${current}, prev index: ${prev}`),
  45 + }}
  46 + >
  47 + {images.map((url) => (
  48 + <>
  49 + <Image width={120} src={url} /> <Divider type="vertical" />
  50 + </>
  51 + ))}
  52 + </Image.PreviewGroup>
  53 + </Modal>
  54 + </>
  55 + );
  56 +};
... ...
src/pages/Order/constant.ts
... ... @@ -9,6 +9,8 @@ export const PAYMENT_CHANNEL_OPTIONS = {
9 9 export const PAYMENT_METHOD_OPTIONS = {
10 10 PAYMENT_IN_ADVANCE: '预付',
11 11 CASH_ON_DELIVERY: '货到付款',
  12 + UNPAID: '未付款',
  13 + PLATFORM_SETTLEMENT: '平台结算',
12 14 };
13 15  
14 16 export const PRODUCT_BELONG_DEPARTMENT_OPTIONS = {
... ... @@ -25,7 +27,8 @@ export const INVOCING_STATUS_OPTIONS = {
25 27 };
26 28  
27 29 export const LOGISTICS_STATUS_OPTIONS = {
28   - JINGDONG_LOGISTICS: '京东物流',
  30 + JINGDONG_LOGISTICS: '京东',
  31 + SF_EXPRESS: '顺丰',
29 32 DEBANG_LOGISTICS: '德邦物流',
30 33 };
31 34  
... ... @@ -38,6 +41,51 @@ export const ORDER_STATUS_OPTIONS = {
38 41 SHIPPED: '已发货',
39 42 };
40 43  
  44 +export const TAGS_COLOR = new Map<string, string>([
  45 + ['UN_INVOICE', 'success'],
  46 + ['INVOICED', 'processing'],
  47 + ['AFTER_INVOICED', 'success'],
  48 + ['UNAUDITED', 'warning'],
  49 + ['AUDITED', 'processing'],
  50 + ['WAIT_SHIP', 'processing'],
  51 + ['SHIPPED', 'processing'],
  52 + ['AUDIT_FAILED', 'error'],
  53 + ['CONFIRM_RECEIPT', 'success'],
  54 +]);
  55 +
  56 +export const SALES_CODE_OPTIONS = [
  57 + { label: 'HQ_唐华琼', value: 'HQ_唐华琼' },
  58 + { label: 'HQ-1_陆金丽', value: 'HQ-1_陆金丽' },
  59 + { label: 'HQ-2_易琼', value: 'HQ-2_易琼' },
  60 + { label: 'HQ-3_梁董玲', value: 'HQ-3_梁董玲' },
  61 + { label: 'HQ-4_麦倩莹', value: 'HQ-4_麦倩莹' },
  62 + { label: 'HQ-5_刘璐', value: 'HQ-5_刘璐' },
  63 + { label: 'HQ-6_李云', value: 'HQ-6_李云' },
  64 + { label: 'HQ-7_陈方', value: 'HQ-7_陈方' },
  65 + { label: 'HQ-8_袁友辉', value: 'HQ-8_袁友辉' },
  66 + { label: 'TB_储能淘宝店铺', value: 'TB_储能淘宝店铺' },
  67 + { label: 'W-1_Alice', value: 'W-1_Alice' },
  68 + { label: 'W-4_龙青', value: 'W-4_龙青' },
  69 + { label: 'HCTB_耗材淘宝店铺', value: 'HCTB_耗材淘宝店铺' },
  70 + { label: 'TBC_电池品牌店', value: 'TBC_电池品牌店' },
  71 + { label: 'W-3_田菁菁', value: 'W-3_田菁菁' },
  72 + { label: 'W-2_黄宁', value: 'W-2_黄宁' },
  73 + { label: 'W_宋学文', value: 'W_宋学文' },
  74 + { label: 'W-5_黎艳', value: 'W-5_黎艳' },
  75 + { label: 'W-6_黄丹', value: 'W-6_黄丹' },
  76 + { label: 'W-7_黄花梅', value: 'W-7_黄花梅' },
  77 + { label: 'XX_Tina', value: 'XX_Tina' },
  78 + { label: 'XX-P_校平台共用代码', value: 'XX-P_校平台共用代码' },
  79 + { label: 'XX-2_Vivi', value: 'XX-2_Vivi' },
  80 + { label: 'XX-N1_Nancy', value: 'XX-N1_Nancy' },
  81 + { label: 'XX-N2_Sara', value: 'XX-N2_Sara' },
  82 + { label: 'XX-A1_Ada', value: 'XX-A1_Ada' },
  83 + { label: 'XX-A2_Amy', value: 'XX-A2_Amy' },
  84 + { label: 'XX-C_CC', value: 'XX-C_CC' },
  85 + { label: 'XX-L1_Lucy', value: 'XX-L1_Lucy' },
  86 + { label: 'XX-L2_Lulu', value: 'XX-L2_Lulu' },
  87 +];
  88 +
41 89 export const MAIN_ORDER_COLUMNS = [
42 90 {
43 91 title: '订单列表',
... ... @@ -48,7 +96,7 @@ export const MAIN_ORDER_COLUMNS = [
48 96 {
49 97 title: '订单编号',
50 98 dataIndex: 'id',
51   - valueType: 'text',
  99 + valueType: 'digit',
52 100 hideInTable: true,
53 101 },
54 102 {
... ... @@ -108,7 +156,7 @@ export const MAIN_ORDER_COLUMNS = [
108 156 },
109 157 {
110 158 title: '支付方式',
111   - dataIndex: 'paymentStatus',
  159 + dataIndex: 'paymentMethod',
112 160 valueType: 'select',
113 161 hideInTable: true,
114 162 valueEnum: enumToProTableEnumValue(PAYMENT_METHOD_OPTIONS),
... ...
src/pages/Order/index.less
1 1 // 嵌套表格去掉左方多余部分
2   -.ant-table .ant-table-middle{
3   - margin-inline: 0 !important;
  2 +.ant-table .ant-table-middle {
  3 + margin-inline: 0 !important;
4 4 }
5 5  
  6 +td {
  7 + font-family: 'San Francisco', 'Helvetica Neue', Helvetica, Arial,
  8 + 'Microsoft YaHei', 'PingFang SC', 'Hiragino Sans GB', 'Heiti SC',
  9 + 'WenQuanYi Micro Hei', sans-serif;
  10 + font-size: 13px;
  11 +}
... ...
src/pages/Order/index.tsx
... ... @@ -5,7 +5,7 @@ import {
5 5 postServiceOrderQueryServiceOrder,
6 6 } from '@/services';
7 7 import { orderExport } from '@/services/order';
8   -import { enumValueToLabel } from '@/utils';
  8 +import { enumValueToLabel, formatDateTime } from '@/utils';
9 9 import { DownOutlined, EllipsisOutlined } from '@ant-design/icons';
10 10 import {
11 11 PageContainer,
... ... @@ -33,7 +33,8 @@ import ConfirmReceiptModal from &#39;./components/ConfirmReceiptModal&#39;;
33 33 import DeliverModal from './components/DeliverModal';
34 34 import FinancialDrawer from './components/FinancialDrawer';
35 35 import OrderDrawer from './components/OrderDrawer';
36   -import SubOrderNotesEditModal from './components/SubOrderNotesEditModal';
  36 +import OrderNotesEditModal from './components/OrderNotesEditModal';
  37 +import SubOrderComfirmReceiptImagesModal from './components/SubOrderComfirmReceiptImagesModal';
37 38 import {
38 39 INVOCING_STATUS_OPTIONS,
39 40 LOGISTICS_STATUS_OPTIONS,
... ... @@ -42,6 +43,7 @@ import {
42 43 PAYMENT_CHANNEL_OPTIONS,
43 44 PAYMENT_METHOD_OPTIONS,
44 45 SUB_ORDER_COLUMNS,
  46 + TAGS_COLOR,
45 47 } from './constant';
46 48 import './index.less';
47 49 import { OrderListItemType, OrderType } from './type.d';
... ... @@ -50,8 +52,15 @@ const OrderPage = () =&gt; {
50 52 const [orderDrawerVisible, setOrderDrawerVisible] = useState<boolean>(false);
51 53 const [checkVisible, setCheckVisible] = useState<boolean>(false);
52 54 const [orderPrintVisible, setOrderPrintVisible] = useState<boolean>(false);
  55 + const [
  56 + subOrderConfirmReceiptImagesVisible,
  57 + setSubOrderConfirmReceiptImagesVisible,
  58 + ] = useState<boolean>(false);
53 59 const [notesEditVisible, setNotesEditVisible] = useState<boolean>(false);
54 60 const [financialVisible, setFinancialVisible] = useState<boolean>(false);
  61 + const [isRePrintOrder, setIsRePrintOrder] = useState<boolean>(false);
  62 + const [isSendProduct, setIsSendProduct] = useState<boolean>(false);
  63 + const [isMainOrder, setIsMainOrder] = useState<boolean>(false);
55 64 const [confirmReceiptVisible, setConfirmReceiptVisible] =
56 65 useState<boolean>(false);
57 66 const [deliverVisible, setDeliverVisible] = useState<boolean>(false);
... ... @@ -66,7 +75,29 @@ const OrderPage = () =&gt; {
66 75 const [selectedRows, setSelectedRows] = useState({});
67 76 const [selectedRowObj, setSelectedRowObj] = useState({});
68 77 const [selectedItems, setSelectedItems] = useState([]);
  78 + const [selectedRowKeys, setSelectedRowKeys] = useState([]);
69 79 const mainTableRef = useRef();
  80 + const [messageApi, contextHolder] = message.useMessage();
  81 +
  82 + const exportLoading = () => {
  83 + messageApi.open({
  84 + type: 'loading',
  85 + content: '正在导出文件...',
  86 + duration: 0,
  87 + });
  88 + };
  89 +
  90 + const exportLoadingDestory = () => {
  91 + messageApi.destroy();
  92 + };
  93 +
  94 + const refreshTable = () => {
  95 + mainTableRef.current?.reload();
  96 + //刷新表格数据的时候,取消选中行
  97 + setSelectedRowObj([]);
  98 + setSelectedRows([]);
  99 + setSelectedRowKeys([]);
  100 + };
70 101  
71 102 const resize = () => {
72 103 // 计算元素底部到视口顶部的距离
... ... @@ -125,7 +156,7 @@ const OrderPage = () =&gt; {
125 156 checked={selectedItems.includes(record.id)}
126 157 >
127 158 <Flex wrap="wrap" gap="middle">
128   - <div>{record.createTime}</div>
  159 + <div>{formatDateTime(record.createTime)}</div>
129 160 <div>订单编号:{record.id}</div>
130 161 </Flex>
131 162 </Checkbox>
... ... @@ -134,7 +165,6 @@ const OrderPage = () =&gt; {
134 165  
135 166 {rolePath?.includes('addOrder') ? (
136 167 <Button
137   - type="primary"
138 168 size="small"
139 169 onClick={() => {
140 170 setOrderOptType('copy');
... ... @@ -174,6 +204,7 @@ const OrderPage = () =&gt; {
174 204 {record.institutionContactName}
175 205 </span>
176 206 <span>单位名称:{record.institution}</span>
  207 + {/* className='whitespace-pre-wrap max-w-sm' */}
177 208 <span> 收货地址:{record.customerShippingAddress}</span>
178 209 </Space>
179 210 </div>
... ... @@ -217,6 +248,7 @@ const OrderPage = () =&gt; {
217 248 }
218 249 setSelectedRows(selectedRowObj[record.id]);
219 250 setDeliverVisible(true);
  251 + setIsSendProduct(true);
220 252 }}
221 253 >
222 254 发货
... ... @@ -242,6 +274,55 @@ const OrderPage = () =&gt; {
242 274 ) : (
243 275 ''
244 276 )}
  277 + {record.mainPath.includes('rePrintOrder') ? (
  278 + <Button
  279 + className="p-0"
  280 + type="link"
  281 + onClick={() => {
  282 + if (!selectedRowObj[record.id]?.length) {
  283 + return message.error('请选择选择子订单');
  284 + }
  285 + setSelectedRows(selectedRowObj[record.id]);
  286 + setOrderRow(record);
  287 + setOrderPrintVisible(true);
  288 + setIsRePrintOrder(true);
  289 + }}
  290 + >
  291 + 重新打印
  292 + </Button>
  293 + ) : (
  294 + ''
  295 + )}
  296 + {record.mainPath.includes('modifySendInformation') ? (
  297 + <Button
  298 + className="p-0"
  299 + type="link"
  300 + onClick={() => {
  301 + if (!selectedRowObj[record.id]?.length) {
  302 + return message.error(
  303 + '请选择已经发货或者已经确认收货的子订单',
  304 + );
  305 + }
  306 + for (let row of selectedRowObj[record.id]) {
  307 + if (
  308 + row.orderStatus !== 'CONFIRM_RECEIPT' &&
  309 + row.orderStatus !== 'SHIPPED'
  310 + ) {
  311 + return message.error(
  312 + '请选择已经发货或者已经确认收货的子订单',
  313 + );
  314 + }
  315 + }
  316 + setSelectedRows(selectedRowObj[record.id]);
  317 + setDeliverVisible(true);
  318 + setIsSendProduct(false);
  319 + }}
  320 + >
  321 + 修改发货信息
  322 + </Button>
  323 + ) : (
  324 + ''
  325 + )}
245 326 {record.mainPath.includes('invoicing') ? (
246 327 <Button
247 328 type="link"
... ... @@ -293,6 +374,7 @@ const OrderPage = () =&gt; {
293 374 }
294 375 setOrderDrawerVisible(true);
295 376 setOrderRow(record);
  377 + setSelectedRows(selectedSubOrders);
296 378 setOrderOptType('edit');
297 379 }}
298 380 >
... ... @@ -307,10 +389,9 @@ const OrderPage = () =&gt; {
307 389 className="p-0"
308 390 type="link"
309 391 onClick={() => {
310   - console.log('!!!!!!!!!!!');
311 392 let selectedSubOrders = selectedRowObj[record.id];
312 393 setSelectedRows(selectedSubOrders);
313   - if (selectedSubOrders === undefined) {
  394 + if (selectedSubOrders === null) {
314 395 setSelectedRows(record.subOrderInformationLists);
315 396 }
316 397 for (let i = 0; i < selectedRows.length; i++) {
... ... @@ -346,13 +427,25 @@ const OrderPage = () =&gt; {
346 427 });
347 428 if (data.result === RESPONSE_CODE.SUCCESS) {
348 429 message.success(data.message);
349   - mainTableRef.current?.reload();
  430 + refreshTable();
350 431 }
351 432 }}
352 433 />
353 434 ) : (
354 435 ''
355 436 )}
  437 +
  438 + <Button
  439 + className="p-0"
  440 + type="link"
  441 + onClick={() => {
  442 + setNotesEditVisible(true);
  443 + setOrderRow(record);
  444 + setIsMainOrder(true);
  445 + }}
  446 + >
  447 + 备注
  448 + </Button>
356 449 </Space>
357 450 </Space.Compact>
358 451 <Space.Compact direction="vertical">
... ... @@ -397,21 +490,19 @@ const OrderPage = () =&gt; {
397 490 return {
398 491 ...item,
399 492 render: (text: string, optRecord) => {
  493 + let newText = text;
400 494 let label = enumValueToLabel(text, ORDER_STATUS_OPTIONS);
401 495 if (label === undefined) {
402 496 label = enumValueToLabel(text, INVOCING_STATUS_OPTIONS);
403 497 }
404   - let color = 'gold';
405   - if (label === '需要开票' || label === '已审核') {
406   - color = 'green';
407   - }
408 498 if (
409 499 label === '需要开票' &&
410 500 optRecord.invoicingTime !== undefined
411 501 ) {
412 502 label = '已开票';
  503 + newText = 'AFTER_INVOICED';
413 504 }
414   - return <Tag color={color}>{label}</Tag>;
  505 + return <Tag color={TAGS_COLOR.get(newText)}>{label}</Tag>;
415 506 },
416 507 };
417 508 } else if (
... ... @@ -434,17 +525,10 @@ const OrderPage = () =&gt; {
434 525 },
435 526 };
436 527 } else {
437   - //普通字段,超出长度自动换行
438 528 return {
439 529 ...item,
440 530 render: (text: string) => {
441   - return (
442   - <div
443   - style={{ wordWrap: 'break-word', wordBreak: 'break-all' }}
444   - >
445   - {text}
446   - </div>
447   - );
  531 + return <span>{text}</span>;
448 532 },
449 533 };
450 534 }
... ... @@ -456,8 +540,9 @@ const OrderPage = () =&gt; {
456 540 dataIndex: 'operation',
457 541 key: 'operation',
458 542 align: 'center',
  543 + fixed: 'right',
459 544 render: (optText, optRecord) => (
460   - <Flex>
  545 + <Flex gap="small">
461 546 {optRecord.subPath.includes('sendProduct') ? (
462 547 <Button
463 548 className="p-0"
... ... @@ -466,6 +551,7 @@ const OrderPage = () =&gt; {
466 551 optRecord.mainOrderId = record.id;
467 552 setSelectedRows([cloneDeep(optRecord)]); //克隆一份数据,避免后续修改污染
468 553 setDeliverVisible(true);
  554 + setIsSendProduct(true);
469 555 }}
470 556 >
471 557 发货
... ... @@ -473,29 +559,32 @@ const OrderPage = () =&gt; {
473 559 ) : (
474 560 ''
475 561 )}
  562 +
  563 + {optRecord.subPath.includes('modifySendInformation') ? (
  564 + <Button
  565 + className="p-0"
  566 + type="link"
  567 + onClick={() => {
  568 + optRecord.mainOrderId = record.id;
  569 + setSelectedRows([cloneDeep(optRecord)]); //克隆一份数据,避免后续修改污染
  570 + setDeliverVisible(true);
  571 + setIsSendProduct(false);
  572 + }}
  573 + >
  574 + 修改发货信息
  575 + </Button>
  576 + ) : (
  577 + ''
  578 + )}
  579 +
476 580 {optRecord.subPath.includes('printOrder') ? (
477 581 <Button
478 582 className="p-0"
479 583 type="link"
480 584 onClick={async () => {
481   - //调用打印接口
482   - // let body = { subIds: [optRecord.id] };
483   - // const data = await postServiceOrderPrintOrder({
484   - // data: body,
485   - // });
486   - // if (data.result === RESPONSE_CODE.SUCCESS) {
487   - // message.success(data.message);
488   - // setOrderPrintVisible(true);
489   - // setSelectedRows([optRecord]);
490   - // setOrderRow(record);
491   - // mainTableRef.current?.reload();
492   - // }
493   -
494   - // message.success(data.message);
495 585 setOrderPrintVisible(true);
496 586 setSelectedRows([optRecord]);
497 587 setOrderRow(record);
498   - mainTableRef.current?.reload();
499 588 }}
500 589 >
501 590 打印
... ... @@ -551,6 +640,23 @@ const OrderPage = () =&gt; {
551 640 ''
552 641 )}
553 642  
  643 + {optRecord.subPath.includes('rePrintOrder') ? (
  644 + <Button
  645 + className="p-0"
  646 + type="link"
  647 + onClick={() => {
  648 + setOrderPrintVisible(true);
  649 + setSelectedRows([optRecord]);
  650 + setOrderRow(record);
  651 + setIsRePrintOrder(true);
  652 + }}
  653 + >
  654 + 重新打印
  655 + </Button>
  656 + ) : (
  657 + ''
  658 + )}
  659 +
554 660 {optRecord.subPath.includes('confirmReceipt') ? (
555 661 <Button
556 662 className="p-0"
... ... @@ -565,17 +671,20 @@ const OrderPage = () =&gt; {
565 671 ) : (
566 672 ''
567 673 )}
568   -
569   - {/* {optRecord.subPath.includes("OrderCancel") ?
570   - <ButtonConfirm
571   - className="p-0"
572   - title="确认作废?"
573   - text="作废"
574   - onConfirm={() => {
575   - }}
576   - />
577   - : ''
578   - } */}
  674 + {optRecord.subPath.includes('viewImages') ? (
  675 + <Button
  676 + className="p-0"
  677 + type="link"
  678 + onClick={() => {
  679 + setSubOrderConfirmReceiptImagesVisible(true);
  680 + setOrderRow(optRecord);
  681 + }}
  682 + >
  683 + 查看收货凭证
  684 + </Button>
  685 + ) : (
  686 + ''
  687 + )}
579 688 </Flex>
580 689 ),
581 690 },
... ... @@ -591,6 +700,7 @@ const OrderPage = () =&gt; {
591 700 onClick={() => {
592 701 setNotesEditVisible(true);
593 702 setOrderRow(optRecord);
  703 + setIsMainOrder(false);
594 704 }}
595 705 >
596 706 详情
... ... @@ -600,6 +710,7 @@ const OrderPage = () =&gt; {
600 710 ])}
601 711 rowSelection={{
602 712 onChange: (selectedRowKeys: any, selectedRows: any) => {
  713 + setSelectedRowKeys(selectedRowKeys);
603 714 setSelectedRowObj({
604 715 ...setSelectedRowObj,
605 716 [record.id]: selectedRows,
... ... @@ -607,6 +718,7 @@ const OrderPage = () =&gt; {
607 718 selectedRowObj[record.id] = selectedRows;
608 719 setSelectedRows(selectedRows);
609 720 },
  721 + selectedRowKeys: selectedRowKeys,
610 722 // 自定义选择项参考: https://ant.design/components/table-cn/#components-table-demo-row-selection-custom
611 723 // 注释该行则默认不显示下拉选项
612 724 // selections: [Table.SELECTION_ALL, Table.SELECTION_INVERT],
... ... @@ -636,11 +748,8 @@ const OrderPage = () =&gt; {
636 748 return;
637 749 }
638 750 let body = { flag: true, ids: selectedItems };
639   - // const data = await postServiceOrderExport({ data: { flag: true, ids: selectedItems } });
640   - orderExport(body);
641   - // if (data.result === RESPONSE_CODE.SUCCESS) {
642   - // message.success(data.message);
643   - // }
  751 + exportLoading();
  752 + orderExport(body, exportLoadingDestory);
644 753 },
645 754 },
646 755 {
... ... @@ -651,28 +760,18 @@ const OrderPage = () =&gt; {
651 760 message.error('当前没有订单');
652 761 return;
653 762 }
654   - // const data = await postServiceOrderExport({
655   - // data: { flag: true, ids: mainOrderAllItemKeys },
656   - // });
657   - // if (data.result === RESPONSE_CODE.SUCCESS) {
658   - // message.success(data.message);
659   - // }
660 763 let body = { flag: true, ids: mainOrderAllItemKeys };
661   - orderExport(body);
  764 + exportLoading();
  765 + orderExport(body, exportLoadingDestory);
662 766 },
663 767 },
664 768 {
665 769 label: '导出所有订单',
666 770 key: '3',
667 771 onClick: async () => {
668   - // const data = await postServiceOrderExport({
669   - // data: { flag: false, ids: [] },
670   - // });
671   - // if (data.result === RESPONSE_CODE.SUCCESS) {
672   - // message.success(data.message);
673   - // }
674 772 let body = { flag: false, ids: [] };
675   - orderExport(body);
  773 + exportLoading();
  774 + orderExport(body, exportLoadingDestory);
676 775 },
677 776 },
678 777 ];
... ... @@ -730,8 +829,9 @@ const OrderPage = () =&gt; {
730 829 title: '订单管理',
731 830 extra: [
732 831 <Avatar key="0" style={{ verticalAlign: 'middle' }} size="large">
733   - {userInfo?.nickName}
  832 + {userInfo?.username}
734 833 </Avatar>,
  834 + <Tag key="nickName">{userInfo?.nickName}</Tag>,
735 835 <Dropdown
736 836 key="dropdown"
737 837 trigger={['click']}
... ... @@ -818,10 +918,12 @@ const OrderPage = () =&gt; {
818 918 <OrderDrawer
819 919 data={orderRow}
820 920 subOrders={selectedRows}
821   - onClose={() => {
  921 + onClose={(isSuccess: boolean) => {
822 922 setOrderDrawerVisible(false);
823 923 setOrderRow({});
824   - mainTableRef.current?.reload();
  924 + if (isSuccess) {
  925 + refreshTable();
  926 + }
825 927 }}
826 928 orderOptType={orderOptType}
827 929 />
... ... @@ -836,19 +938,20 @@ const OrderPage = () =&gt; {
836 938 setCheckVisible(false);
837 939 setOrderRow({});
838 940 setSelectedRows({});
839   - mainTableRef.current?.reload();
  941 + refreshTable();
840 942 }}
841 943 />
842 944 )}
843 945  
844 946 {notesEditVisible && (
845   - <SubOrderNotesEditModal
  947 + <OrderNotesEditModal
846 948 setNotesEditVisible={setNotesEditVisible}
847 949 data={orderRow}
  950 + isMianOrder={isMainOrder}
848 951 onClose={() => {
849 952 setNotesEditVisible(false);
850 953 setOrderRow({});
851   - mainTableRef.current?.reload();
  954 + refreshTable();
852 955 }}
853 956 />
854 957 )}
... ... @@ -856,10 +959,12 @@ const OrderPage = () =&gt; {
856 959 {deliverVisible && (
857 960 <DeliverModal
858 961 data={selectedRows}
  962 + isSendProduct={isSendProduct}
859 963 onClose={() => {
860 964 setDeliverVisible(false);
861 965 setOrderRow({});
862   - mainTableRef.current?.reload();
  966 + setIsSendProduct(false);
  967 + refreshTable();
863 968 }}
864 969 />
865 970 )}
... ... @@ -872,7 +977,7 @@ const OrderPage = () =&gt; {
872 977 onClose={() => {
873 978 setFinancialVisible(false);
874 979 setOrderRow({});
875   - mainTableRef.current?.reload();
  980 + refreshTable();
876 981 }}
877 982 />
878 983 )}
... ... @@ -881,10 +986,12 @@ const OrderPage = () =&gt; {
881 986 <OrderPrintModal
882 987 mainOrder={orderRow}
883 988 subOrders={selectedRows}
  989 + isRePrint={isRePrintOrder}
884 990 onClose={() => {
885 991 setOrderPrintVisible(false);
886 992 setOrderRow({});
887   - mainTableRef.current?.reload();
  993 + setIsRePrintOrder(false);
  994 + refreshTable();
888 995 }}
889 996 />
890 997 )}
... ... @@ -895,10 +1002,22 @@ const OrderPage = () =&gt; {
895 1002 onClose={() => {
896 1003 setConfirmReceiptVisible(false);
897 1004 setOrderRow({});
898   - mainTableRef.current?.reload();
  1005 + refreshTable();
899 1006 }}
900 1007 />
901 1008 )}
  1009 +
  1010 + {subOrderConfirmReceiptImagesVisible && (
  1011 + <SubOrderComfirmReceiptImagesModal
  1012 + setVisible={setSubOrderConfirmReceiptImagesVisible}
  1013 + onClose={() => {
  1014 + setSubOrderConfirmReceiptImagesVisible(false);
  1015 + }}
  1016 + orderRow={orderRow}
  1017 + />
  1018 + )}
  1019 +
  1020 + {contextHolder}
902 1021 </PageContainer>
903 1022 );
904 1023 };
... ...
src/pages/OrderPrint/OrderPrintModal.tsx
... ... @@ -9,16 +9,16 @@ import DalangPrinter from &#39;./components/DalangPrinter&#39;;
9 9 import HoujiePrinter from './components/HoujiePrinter';
10 10 import ZhuguangPrinter from './components/ZhuguangPrinter';
11 11  
12   -export default ({ mainOrder, subOrders, onClose }) => {
13   - console.log(mainOrder);
14   - console.log(subOrders);
15   -
  12 +export default ({ mainOrder, subOrders, isRePrint, onClose }) => {
16 13 const [printerType, setPrinterType] = useState('Houjie');
17 14 const { confirm } = Modal;
18 15 const handleChange = (value: string) => {
19 16 setPrinterType(value);
20 17 };
21 18 const showPropsConfirm = () => {
  19 + if (isRePrint) {
  20 + return;
  21 + }
22 22 confirm({
23 23 title: '确认打印出货单',
24 24 icon: <ExclamationCircleFilled />,
... ... @@ -54,12 +54,14 @@ export default ({ mainOrder, subOrders, onClose }) =&gt; {
54 54 //printJS打印出货单
55 55 printJS({
56 56 printable: 'printArea', // 元素id,不支持多个
  57 + scanStyles: true,
57 58 type: 'html',
58 59 targetStyle: ['* '],
59 60 targetStyles: ['*'],
60 61 style:
61   - '@page{size:auto; margin: 0;}' +
62   - '@media print { @page {size: landscape } }', // landscape 默认横向打印
  62 + '@page{size:auto;margin: 0mm;}' +
  63 + '@media print { body{margin:0 auto;padding:0;#title{font-size:24px}}' +
  64 + 'body{zoom:1.6;margin:0;', // landscape 默认横向打印
63 65 onPrintDialogClose: () => {
64 66 showPropsConfirm();
65 67 },
... ...
src/pages/OrderPrint/components/DalangPrinter.tsx
1 1 import '@/pages/OrderPrint/index.less';
  2 +import { formatDateTime } from '@/utils';
2 3  
3 4 export default ({ mainOrder, subOrders }) => {
4 5 console.log(subOrders);
... ... @@ -21,7 +22,7 @@ export default ({ mainOrder, subOrders }) =&gt; {
21 22 {subOrder.quantity}
22 23 </td>
23 24 <td className="xl72" colSpan={1}>
24   - {subOrder.unit}
  25 + {subOrder.productPrice}
25 26 </td>
26 27 <td className="xl72" colSpan={1}>
27 28 {subOrder.subOrderPayment}
... ... @@ -50,12 +51,10 @@ export default ({ mainOrder, subOrders }) =&gt; {
50 51 }
51 52  
52 53 return (
53   - <div
54   - id="printArea"
55   - className="flex items-center justify-center bg-gray-100"
56   - >
  54 + <div className="flex items-center justify-center bg-gray-100">
57 55 <div className="w-full max-w-4xl p-10 my-10 bg-white border border-gray-300">
58 56 <table
  57 + id="printArea"
59 58 className="p-10"
60 59 width="855"
61 60 border={0}
... ... @@ -82,10 +81,13 @@ export default ({ mainOrder, subOrders }) =&gt; {
82 81 <col width="57" />
83 82 <col width="57" />
84 83 <col width="57" />
85   -
  84 + <tr height="42" style={{ height: '21.00pt' }}></tr>
  85 + <tr height="42" style={{ height: '21.00pt' }}></tr>
  86 + <tr height="42" style={{ height: '21.00pt' }}></tr>
86 87 <tr height="42" style={{ height: '21.00pt' }}>
87 88 <td height="42" colSpan={5} style={{ height: '21.00pt' }}></td>
88 89 <td
  90 + id="title"
89 91 className="xl65"
90 92 colSpan={5}
91 93 style={{ borderRight: 'none', borderBottom: 'none' }}
... ... @@ -134,17 +136,10 @@ export default ({ mainOrder, subOrders }) =&gt; {
134 136 ></td>
135 137 <td
136 138 className="xl69"
137   - colSpan="1"
138   - style={{ borderRight: 'none', borderBottom: 'none' }}
139   - >
140   - 单位名称:
141   - </td>
142   - <td
143   - className="xl69"
144   - colSpan="4"
  139 + colSpan="5"
145 140 style={{ borderRight: 'none', borderBottom: 'none' }}
146 141 >
147   - {mainOrder.institution}
  142 + 单位名称:{mainOrder.institution}
148 143 </td>
149 144 <td
150 145 className="xl69"
... ... @@ -153,62 +148,38 @@ export default ({ mainOrder, subOrders }) =&gt; {
153 148 ></td>
154 149 <td
155 150 className="xl69"
156   - colSpan={1}
157   - style={{ borderRight: 'none', borderBottom: 'none' }}
158   - >
159   - 单号:
160   - </td>
161   - <td
162   - className="xl69"
163   - colSpan={6}
  151 + colSpan={7}
164 152 style={{ borderRight: 'none', borderBottom: 'none' }}
165 153 >
166   - {mainOrder.id}
  154 + 单号:{mainOrder.id}
167 155 </td>
168 156 </tr>
169 157 <tr height="30" style={{ height: '15.00pt' }}>
170 158 <td height="30" colSpan={1} style={{ height: '15.00pt' }}></td>
171 159 <td
172 160 className="xl69"
173   - colSpan={1}
174   - style={{ borderRight: 'none', borderBottom: 'none' }}
175   - >
176   - 联系人:
177   - </td>
178   - <td
179   - className="xl69"
180   - colSpan={4}
  161 + colSpan={5}
181 162 style={{ borderRight: 'none', borderBottom: 'none' }}
182 163 >
183   - {mainOrder.customerName}
  164 + 联系人:{mainOrder.customerName}
184 165 </td>
185 166 <td height="30" colSpan={2} style={{ height: '15.00pt' }}></td>
186 167 <td
187 168 className="xl69"
188   - colSpan={1}
189   - style={{ borderRight: 'none', borderBottom: 'none' }}
190   - >
191   - 开单日期:
192   - </td>
193   - <td
194   - className="xl69"
195   - colSpan={6}
  169 + colSpan={7}
196 170 style={{ borderRight: 'none', borderBottom: 'none' }}
197 171 >
198   - {mainOrder.createTime}
  172 + 开单日期:{formatDateTime(mainOrder.createTime)}
199 173 </td>
200 174 </tr>
201 175 <tr height="30" style={{ height: '15.00pt' }}>
202 176 <td height="30" colSpan={1} style={{ height: '15.00pt' }}></td>
203 177 <td
204 178 className="xl69"
205   - colSpan={1}
  179 + colSpan={5}
206 180 style={{ borderRight: 'none', borderBottom: 'none' }}
207 181 >
208   - 联系电话:
209   - </td>
210   - <td className="xl70" colSpan={4} style={{ msoIgnore: 'colSpan' }}>
211   - {mainOrder.customerContactNumber}
  182 + 联系电话:{mainOrder.customerContactNumber}
212 183 </td>
213 184 <td className="xl70"></td>
214 185 </tr>
... ... @@ -216,17 +187,10 @@ export default ({ mainOrder, subOrders }) =&gt; {
216 187 <td height="30" colSpan={1} style={{ height: '15.00pt' }}></td>
217 188 <td
218 189 className="xl69"
219   - colSpan={1}
220   - style={{ borderRight: 'none', borderBottom: 'none' }}
221   - >
222   - 送货地址:
223   - </td>
224   - <td
225   - className="xl69"
226   - colSpan={4}
  190 + colSpan={5}
227 191 style={{ borderRight: 'none', borderBottom: 'none' }}
228 192 >
229   - {mainOrder.customerShippingAddress}
  193 + 送货地址:{mainOrder.customerShippingAddress}
230 194 </td>
231 195 </tr>
232 196 <tr height="30" style={{ height: '15.00pt' }}>
... ... @@ -366,7 +330,7 @@ export default ({ mainOrder, subOrders }) =&gt; {
366 330 colSpan={2}
367 331 style={{ borderRight: 'none', borderBottom: 'none' }}
368 332 >
369   - 开单人:丽娟
  333 + 开单人:丽娟
370 334 </td>
371 335 </tr>
372 336 <tr style={{ display: 'none', width: 0 }}>
... ...
src/pages/OrderPrint/components/HoujiePrinter.tsx
1 1 import '@/pages/OrderPrint/index.less';
  2 +import { formatDateTime } from '@/utils';
2 3  
3 4 export default ({ mainOrder, subOrders }) => {
4 5 console.log(subOrders);
... ... @@ -42,6 +43,7 @@ export default ({ mainOrder, subOrders }) =&gt; {
42 43 >
43 44 <div className="w-full max-w-4xl p-10 my-10 bg-white border border-gray-300">
44 45 <table
  46 + id="printArea"
45 47 className="p-10"
46 48 width="846"
47 49 border={0}
... ... @@ -143,7 +145,7 @@ export default ({ mainOrder, subOrders }) =&gt; {
143 145 colSpan="3"
144 146 style={{ borderRight: 'none', borderBottom: 'none' }}
145 147 >
146   - 开单日期:{mainOrder.createTime}
  148 + 开单日期:{formatDateTime(mainOrder.createTime)}
147 149 </td>
148 150 </tr>
149 151 <tr height="30" style={{ height: '15.00pt' }}>
... ...
src/pages/OrderPrint/components/ZhuguangPrinter.tsx
1 1 import '@/pages/OrderPrint/index.less';
  2 +import { formatDateTime } from '@/utils';
2 3  
3 4 export default ({ mainOrder, subOrders }) => {
4 5 console.log(subOrders);
... ... @@ -15,10 +16,10 @@ export default ({ mainOrder, subOrders }) =&gt; {
15 16 {subOrder.parameters}
16 17 </td>
17 18 <td className="xl72" colSpan={2}>
18   - {subOrder.quantity}
  19 + {subOrder.unit}
19 20 </td>
20 21 <td className="xl72" colSpan={1}>
21   - {subOrder.unit}
  22 + {subOrder.quantity}
22 23 </td>
23 24 <td className="xl72" colSpan={4} style={{ textAlign: 'left' }}>
24 25 {subOrder.notes}
... ... @@ -42,12 +43,10 @@ export default ({ mainOrder, subOrders }) =&gt; {
42 43 }
43 44  
44 45 return (
45   - <div
46   - id="printArea"
47   - className="flex items-center justify-center bg-gray-100"
48   - >
  46 + <div className="flex items-center justify-center bg-gray-100">
49 47 <div className="w-full max-w-4xl p-10 my-10 bg-white border border-gray-300">
50 48 <table
  49 + id="printArea"
51 50 className="p-10"
52 51 width="855"
53 52 border={0}
... ... @@ -74,7 +73,9 @@ export default ({ mainOrder, subOrders }) =&gt; {
74 73 <col width="57" />
75 74 <col width="57" />
76 75 <col width="57" />
77   -
  76 + <tr height="42" style={{ height: '21.00pt' }}></tr>
  77 + <tr height="42" style={{ height: '21.00pt' }}></tr>
  78 + <tr height="42" style={{ height: '21.00pt' }}></tr>
78 79 <tr height="42" style={{ height: '21.00pt' }}>
79 80 <td height="42" colSpan={5} style={{ height: '21.00pt' }}></td>
80 81 <td
... ... @@ -126,17 +127,10 @@ export default ({ mainOrder, subOrders }) =&gt; {
126 127 ></td>
127 128 <td
128 129 className="xl69"
129   - colSpan="1"
130   - style={{ borderRight: 'none', borderBottom: 'none' }}
131   - >
132   - 单位名称:
133   - </td>
134   - <td
135   - className="xl69"
136   - colSpan="4"
  130 + colSpan="5"
137 131 style={{ borderRight: 'none', borderBottom: 'none' }}
138 132 >
139   - {mainOrder.institution}
  133 + 单位名称:{mainOrder.institution}
140 134 </td>
141 135 <td
142 136 className="xl69"
... ... @@ -145,62 +139,38 @@ export default ({ mainOrder, subOrders }) =&gt; {
145 139 ></td>
146 140 <td
147 141 className="xl69"
148   - colSpan={1}
149   - style={{ borderRight: 'none', borderBottom: 'none' }}
150   - >
151   - 单号:
152   - </td>
153   - <td
154   - className="xl69"
155   - colSpan={6}
  142 + colSpan={7}
156 143 style={{ borderRight: 'none', borderBottom: 'none' }}
157 144 >
158   - {mainOrder.id}
  145 + 单号:{mainOrder.id}
159 146 </td>
160 147 </tr>
161 148 <tr height="30" style={{ height: '15.00pt' }}>
162 149 <td height="30" colSpan={1} style={{ height: '15.00pt' }}></td>
163 150 <td
164 151 className="xl69"
165   - colSpan={1}
166   - style={{ borderRight: 'none', borderBottom: 'none' }}
167   - >
168   - 联系人:
169   - </td>
170   - <td
171   - className="xl69"
172   - colSpan={4}
  152 + colSpan={5}
173 153 style={{ borderRight: 'none', borderBottom: 'none' }}
174 154 >
175   - {mainOrder.customerName}
  155 + 联系人:{mainOrder.customerName}
176 156 </td>
177 157 <td height="30" colSpan={2} style={{ height: '15.00pt' }}></td>
178 158 <td
179 159 className="xl69"
180   - colSpan={1}
  160 + colSpan={7}
181 161 style={{ borderRight: 'none', borderBottom: 'none' }}
182 162 >
183   - 开单日期:
184   - </td>
185   - <td
186   - className="xl69"
187   - colSpan={6}
188   - style={{ borderRight: 'none', borderBottom: 'none' }}
189   - >
190   - {mainOrder.createTime}
  163 + 开单日期:{formatDateTime(mainOrder.createTime)}
191 164 </td>
192 165 </tr>
193 166 <tr height="30" style={{ height: '15.00pt' }}>
194 167 <td height="30" colSpan={1} style={{ height: '15.00pt' }}></td>
195 168 <td
196 169 className="xl69"
197   - colSpan={1}
  170 + colSpan={5}
198 171 style={{ borderRight: 'none', borderBottom: 'none' }}
199 172 >
200   - 联系电话:
201   - </td>
202   - <td className="xl70" colSpan={4} style={{ msoIgnore: 'colSpan' }}>
203   - {mainOrder.customerContactNumber}
  173 + 联系电话:{mainOrder.customerContactNumber}
204 174 </td>
205 175 <td className="xl70"></td>
206 176 </tr>
... ... @@ -208,17 +178,10 @@ export default ({ mainOrder, subOrders }) =&gt; {
208 178 <td height="30" colSpan={1} style={{ height: '15.00pt' }}></td>
209 179 <td
210 180 className="xl69"
211   - colSpan={1}
212   - style={{ borderRight: 'none', borderBottom: 'none' }}
213   - >
214   - 送货地址:
215   - </td>
216   - <td
217   - className="xl69"
218   - colSpan={4}
  181 + colSpan={5}
219 182 style={{ borderRight: 'none', borderBottom: 'none' }}
220 183 >
221   - {mainOrder.customerShippingAddress}
  184 + 送货地址:{mainOrder.customerShippingAddress}
222 185 </td>
223 186 </tr>
224 187 <tr height="30" style={{ height: '15.00pt' }}>
... ... @@ -352,7 +315,7 @@ export default ({ mainOrder, subOrders }) =&gt; {
352 315 colSpan={2}
353 316 style={{ borderRight: 'none', borderBottom: 'none' }}
354 317 >
355   - 开单人:丽娟
  318 + 开单人:丽娟
356 319 </td>
357 320 </tr>
358 321 <tr style={{ display: 'none', width: 0 }}>
... ...
src/pages/OrderPrint/index.less
... ... @@ -11,6 +11,17 @@ col {
11 11 br {
12 12 // mso-data-placement: same-cell;
13 13 }
  14 +@media print {
  15 + body {
  16 + color: black;
  17 + }
  18 + .printed-text {
  19 + color: #333;
  20 + }
  21 + .printed-background {
  22 + background-color: #fff;
  23 + }
  24 +}
14 25  
15 26 .font0 {
16 27 color: windowtext;
... ...
src/services/order.ts
1 1 import axios from 'axios';
2 2  
3   -export const orderExport = async (data: any = {}) => {
4   - // const res = await defHttp.post<any>({ url: Api.EXPORT, data });
5   -
  3 +export const orderExport = async (
  4 + data: any = {},
  5 + exportLoadingDestory: any,
  6 +) => {
6 7 axios({
7 8 url: '/api/service/order/export',
8 9 method: 'post',
... ... @@ -25,5 +26,8 @@ export const orderExport = async (data: any = {}) =&gt; {
25 26 .catch((error) => {
26 27 // 处理错误
27 28 console.error('导出错误', error);
  29 + })
  30 + .finally(() => {
  31 + exportLoadingDestory();
28 32 });
29 33 };
... ...
src/services/request.ts
... ... @@ -6031,3 +6031,74 @@ export const postServiceOrderUpdateOrder = /* #__PURE__ */ (() =&gt; {
6031 6031 request.url = url;
6032 6032 return request;
6033 6033 })();
  6034 +
  6035 +/** @description request parameter type for postServiceOrderViewImages */
  6036 +export interface PostServiceOrderViewImagesOption {
  6037 + /**
  6038 + * @description
  6039 + * dto
  6040 + */
  6041 + body: {
  6042 + /**
  6043 + @description
  6044 + dto */
  6045 + dto: Dto;
  6046 + };
  6047 +}
  6048 +
  6049 +/** @description response type for postServiceOrderViewImages */
  6050 +export interface PostServiceOrderViewImagesResponse {
  6051 + /**
  6052 + * @description
  6053 + * OK
  6054 + */
  6055 + 200: ServerResult;
  6056 + /**
  6057 + * @description
  6058 + * Created
  6059 + */
  6060 + 201: any;
  6061 + /**
  6062 + * @description
  6063 + * Unauthorized
  6064 + */
  6065 + 401: any;
  6066 + /**
  6067 + * @description
  6068 + * Forbidden
  6069 + */
  6070 + 403: any;
  6071 + /**
  6072 + * @description
  6073 + * Not Found
  6074 + */
  6075 + 404: any;
  6076 +}
  6077 +
  6078 +export type PostServiceOrderViewImagesResponseSuccess =
  6079 + PostServiceOrderViewImagesResponse[200];
  6080 +/**
  6081 + * @description
  6082 + * 查看确认收货后的证明图片
  6083 + * @tags 内部订单
  6084 + * @produces *
  6085 + * @consumes application/json
  6086 + */
  6087 +export const postServiceOrderViewImages = /* #__PURE__ */ (() => {
  6088 + const method = 'post';
  6089 + const url = '/service/order/viewImages';
  6090 + function request(
  6091 + option: PostServiceOrderViewImagesOption,
  6092 + ): Promise<PostServiceOrderViewImagesResponseSuccess> {
  6093 + return requester(request.url, {
  6094 + method: request.method,
  6095 + ...option,
  6096 + }) as unknown as Promise<PostServiceOrderViewImagesResponseSuccess>;
  6097 + }
  6098 +
  6099 + /** http method */
  6100 + request.method = method;
  6101 + /** request url */
  6102 + request.url = url;
  6103 + return request;
  6104 +})();
... ...
src/utils/index.ts
... ... @@ -41,11 +41,24 @@ function enumToProTableEnumValue(enumConstants: any) {
41 41  
42 42 return result;
43 43 }
  44 +function formatDateTime(inputDateTime: string) {
  45 + const parsedDateTime = new Date(inputDateTime);
44 46  
  47 + const year = parsedDateTime.getFullYear();
  48 + const month = String(parsedDateTime.getMonth() + 1).padStart(2, '0');
  49 + const day = String(parsedDateTime.getDate()).padStart(2, '0');
  50 + const hour = String(parsedDateTime.getHours()).padStart(2, '0');
  51 + const minute = String(parsedDateTime.getMinutes()).padStart(2, '0');
  52 + const second = String(parsedDateTime.getSeconds()).padStart(2, '0');
  53 +
  54 + const formattedDateTime = `${year}-${month}-${day} ${hour}:${minute}:${second}`;
  55 + return formattedDateTime;
  56 +}
45 57 export {
46 58 customMessage,
47 59 enumToProTableEnumValue,
48 60 enumToSelect,
49 61 enumValueToLabel,
  62 + formatDateTime,
50 63 getUserInfo,
51 64 };
... ...
src/utils/validators.ts 0 → 100644
  1 +export const validatePhoneNumber = (_: any, value: any) => {
  2 + const phoneNumberRegex = /^1[3456789]\d{9}$/;
  3 + if (!value || phoneNumberRegex.test(value)) {
  4 + return Promise.resolve();
  5 + }
  6 + return Promise.reject('请输入正确的电话号码格式(例如:13789758969)');
  7 +};
... ...