Commit 2ae24a7d3c217a6022762fc079e5e98c81d0d61f

Authored by boyang
1 parent 37038e0f

修改首页路由

Showing 27 changed files with 124 additions and 4427 deletions

Too many changes to show.

To preserve performance only 27 of 44 files are displayed.

.umirc.ts
@@ -29,7 +29,7 @@ export default defineConfig({ @@ -29,7 +29,7 @@ export default defineConfig({
29 routes: [ 29 routes: [
30 { 30 {
31 path: '/', 31 path: '/',
32 - redirect: '/order', 32 + redirect: '/order/order',
33 }, 33 },
34 { 34 {
35 name: '登录', 35 name: '登录',
src/pages/Order/Order/components/OrderDrawer copy.tsx
@@ -36,7 +36,7 @@ import { @@ -36,7 +36,7 @@ import {
36 PAYMENT_CHANNEL_OPTIONS, 36 PAYMENT_CHANNEL_OPTIONS,
37 PAYMENT_METHOD_OPTIONS, 37 PAYMENT_METHOD_OPTIONS,
38 PRODUCT_BELONG_DEPARTMENT_OPTIONS, 38 PRODUCT_BELONG_DEPARTMENT_OPTIONS,
39 -} from '../constant'; 39 +} from '../../constant';
40 import KingdeeCustomerModal from './KingdeeCustomerModal'; 40 import KingdeeCustomerModal from './KingdeeCustomerModal';
41 41
42 export default ({ onClose, data, subOrders, orderOptType }) => { 42 export default ({ onClose, data, subOrders, orderOptType }) => {
@@ -554,7 +554,7 @@ export default ({ onClose, data, subOrders, orderOptType }) => { @@ -554,7 +554,7 @@ export default ({ onClose, data, subOrders, orderOptType }) => {
554 onChange={(_, option) => { 554 onChange={(_, option) => {
555 autoFillSalesInfo(option); 555 autoFillSalesInfo(option);
556 }} 556 }}
557 - // disabled={mainInfoDisbled} 557 + // disabled={mainInfoDisbled}
558 /> 558 />
559 559
560 <ProFormText 560 <ProFormText
@@ -642,7 +642,7 @@ export default ({ onClose, data, subOrders, orderOptType }) =&gt; { @@ -642,7 +642,7 @@ export default ({ onClose, data, subOrders, orderOptType }) =&gt; {
642 }, 642 },
643 }} 643 }}
644 debounceTime={1000} 644 debounceTime={1000}
645 - request={async (value, {}) => { 645 + request={async (value, { }) => {
646 const keywords = value.keyWords; 646 const keywords = value.keyWords;
647 const res = await postKingdeeRepCustomer({ 647 const res = await postKingdeeRepCustomer({
648 data: { search: keywords }, 648 data: { search: keywords },
@@ -740,7 +740,7 @@ export default ({ onClose, data, subOrders, orderOptType }) =&gt; { @@ -740,7 +740,7 @@ export default ({ onClose, data, subOrders, orderOptType }) =&gt; {
740 </Button> 740 </Button>
741 ), 741 ),
742 }} 742 }}
743 - // disabled={mainInfoDisbled} 743 + // disabled={mainInfoDisbled}
744 /> 744 />
745 </div> 745 </div>
746 746
@@ -752,7 +752,7 @@ export default ({ onClose, data, subOrders, orderOptType }) =&gt; { @@ -752,7 +752,7 @@ export default ({ onClose, data, subOrders, orderOptType }) =&gt; {
752 label="支付渠道" 752 label="支付渠道"
753 options={enumToSelect(PAYMENT_CHANNEL_OPTIONS)} 753 options={enumToSelect(PAYMENT_CHANNEL_OPTIONS)}
754 rules={[{ required: true, message: '支付渠道必填' }]} 754 rules={[{ required: true, message: '支付渠道必填' }]}
755 - // disabled={mainInfoDisbled} 755 + // disabled={mainInfoDisbled}
756 /> 756 />
757 <ProFormSelect 757 <ProFormSelect
758 placeholder="请输入支付方式" 758 placeholder="请输入支付方式"
@@ -762,7 +762,7 @@ export default ({ onClose, data, subOrders, orderOptType }) =&gt; { @@ -762,7 +762,7 @@ export default ({ onClose, data, subOrders, orderOptType }) =&gt; {
762 label="支付方式" 762 label="支付方式"
763 options={enumToSelect(PAYMENT_METHOD_OPTIONS)} 763 options={enumToSelect(PAYMENT_METHOD_OPTIONS)}
764 rules={[{ required: true, message: '支付方式必填' }]} 764 rules={[{ required: true, message: '支付方式必填' }]}
765 - // disabled={mainInfoDisbled} 765 + // disabled={mainInfoDisbled}
766 /> 766 />
767 <ProFormSelect 767 <ProFormSelect
768 placeholder="选择是否需要开票" 768 placeholder="选择是否需要开票"
@@ -1094,7 +1094,7 @@ export default ({ onClose, data, subOrders, orderOptType }) =&gt; { @@ -1094,7 +1094,7 @@ export default ({ onClose, data, subOrders, orderOptType }) =&gt; {
1094 options={enumToSelect(PRODUCT_BELONG_DEPARTMENT_OPTIONS)} 1094 options={enumToSelect(PRODUCT_BELONG_DEPARTMENT_OPTIONS)}
1095 initialValue={'EXPERIMENTAL_CONSUMABLES'} 1095 initialValue={'EXPERIMENTAL_CONSUMABLES'}
1096 rules={[{ required: true, message: '所属事业部必填' }]} 1096 rules={[{ required: true, message: '所属事业部必填' }]}
1097 - // disabled={mainInfoDisbled} 1097 + // disabled={mainInfoDisbled}
1098 />, 1098 />,
1099 <ProFormTextArea 1099 <ProFormTextArea
1100 key={'notes' + listMeta.index} 1100 key={'notes' + listMeta.index}
src/pages/Order/Order/index.css 0 → 100644
  1 +.order-page-container .ant-table .ant-table-middle {
  2 + margin-inline: 0 !important;
  3 +}
  4 +.order-page-container td {
  5 + font-family: 'San Francisco', 'Helvetica Neue', Helvetica, Arial, 'Microsoft YaHei', 'PingFang SC', 'Hiragino Sans GB', 'Heiti SC', 'WenQuanYi Micro Hei', sans-serif;
  6 + font-size: 13px;
  7 +}
  8 +#total-payment .ant-input-number-group-addon {
  9 + padding: 0 !important;
  10 +}
  11 +.order-page-container table:hover,
  12 +.order-page-container tr:hover,
  13 +.order-page-container thead:hover {
  14 + background: none !important;
  15 +}
  16 +#main-table .ant-table-tbody > tr.ant-table-row:hover > td {
  17 + background: none !important;
  18 +}
  19 +.order-page-container .ant-pro-card {
  20 + background-color: transparent;
  21 +}
  22 +#main-table .ant-table-tbody .ant-table-cell {
  23 + padding: 10px 0 0;
  24 +}
  25 +.order-page-container .ant-pagination {
  26 + background-color: #fff !important;
  27 + padding: 10px;
  28 + border-radius: 8px;
  29 +}
  30 +.order-page-container .ant-pro-table .ant-form {
  31 + background-color: #fff;
  32 + border-radius: 8px;
  33 +}
  34 +#main-table .ant-table-tbody {
  35 + background-color: #f5f5f5;
  36 +}
  37 +.order-page-container .ant-pro-card-body {
  38 + padding: 0 !important;
  39 +}
  40 +.order-page-container .ant-table-thead .ant-table-cell {
  41 + background-color: #fff !important;
  42 + border-radius: 8px !important;
  43 +}
  44 +#sub-table tbody td {
  45 + padding: 10px 0 !important;
  46 +}
  47 +#sub-table tbody tr:first-child td:first-child {
  48 + border-top-left-radius: 8px;
  49 +}
  50 +#sub-table tbody tr:first-child td:nth-child(2) {
  51 + border-top-right-radius: 8px;
  52 +}
  53 +#sub-table tbody tr:last-child td:first-child {
  54 + border-bottom-left-radius: 8px;
  55 +}
  56 +#sub-table tbody tr:last-child td:nth-child(2) {
  57 + border-bottom-right-radius: 8px;
  58 +}
  59 +#sub-table tbody tr td:first-child {
  60 + border-top: 1px solid #d7d6d6;
  61 + /* 设置行与行之间分割线的颜色 */
  62 + border-bottom: 1px solid #d7d6d6;
  63 + /* 设置行与行之间分割线的颜色 */
  64 + border-left: 1px solid #d7d6d6;
  65 + /* 设置行与行之间分割线的颜色 */
  66 +}
  67 +#sub-table tbody tr td:nth-child(2) {
  68 + border-top: 1px solid #d7d6d6;
  69 + /* 设置行与行之间分割线的颜色 */
  70 + border-bottom: 1px solid #d7d6d6;
  71 + /* 设置行与行之间分割线的颜色 */
  72 + border-right: 1px solid #d7d6d6;
  73 + /* 设置行与行之间分割线的颜色 */
  74 +}
src/pages/Order/Order/index.less
@@ -9,7 +9,6 @@ @@ -9,7 +9,6 @@
9 'WenQuanYi Micro Hei', sans-serif; 9 'WenQuanYi Micro Hei', sans-serif;
10 font-size: 13px; 10 font-size: 13px;
11 } 11 }
12 -  
13 //订单编辑抽屉中,订单总额addonAfter的padding去除 12 //订单编辑抽屉中,订单总额addonAfter的padding去除
14 #total-payment .ant-input-number-group-addon { 13 #total-payment .ant-input-number-group-addon {
15 padding: 0 !important; 14 padding: 0 !important;
src/pages/Order/OrderWarning/components/OrderDrawer copy.tsx
@@ -36,7 +36,7 @@ import { @@ -36,7 +36,7 @@ import {
36 PAYMENT_CHANNEL_OPTIONS, 36 PAYMENT_CHANNEL_OPTIONS,
37 PAYMENT_METHOD_OPTIONS, 37 PAYMENT_METHOD_OPTIONS,
38 PRODUCT_BELONG_DEPARTMENT_OPTIONS, 38 PRODUCT_BELONG_DEPARTMENT_OPTIONS,
39 -} from '../constant'; 39 +} from '../../constant';
40 import KingdeeCustomerModal from './KingdeeCustomerModal'; 40 import KingdeeCustomerModal from './KingdeeCustomerModal';
41 41
42 export default ({ onClose, data, subOrders, orderOptType }) => { 42 export default ({ onClose, data, subOrders, orderOptType }) => {
src/pages/Order/OrderWarning/index.tsx
@@ -1841,19 +1841,6 @@ const OrderPage = () =&gt; { @@ -1841,19 +1841,6 @@ const OrderPage = () =&gt; {
1841 ) : ( 1841 ) : (
1842 '' 1842 ''
1843 )} 1843 )}
1844 - {optRecord.paths?.includes('applyInvoicing') ? (  
1845 - <Button  
1846 - className="p-0"  
1847 - type="link"  
1848 - onClick={() => {  
1849 - console.log('5656confirminvoice');  
1850 - }}  
1851 - >  
1852 - 确认开票  
1853 - </Button>  
1854 - ) : (  
1855 - ''  
1856 - )}  
1857 1844
1858 {optRecord.paths?.includes('applyInvoicing_old') ? ( 1845 {optRecord.paths?.includes('applyInvoicing_old') ? (
1859 <Button 1846 <Button
@@ -3426,6 +3413,20 @@ const OrderPage = () =&gt; { @@ -3426,6 +3413,20 @@ const OrderPage = () =&gt; {
3426 '' 3413 ''
3427 )} 3414 )}
3428 3415
  3416 + {record.paths?.includes('applyInvoicing') ? (
  3417 + <Button
  3418 + type="link"
  3419 + className="p-0"
  3420 + onClick={() => {
  3421 + console.log('5656confirm');
  3422 + }}
  3423 + >
  3424 + 确认开票
  3425 + </Button>
  3426 + ) : (
  3427 + ''
  3428 + )}
  3429 +
3429 {record.paths?.includes('updateOrder') ? ( 3430 {record.paths?.includes('updateOrder') ? (
3430 <Button 3431 <Button
3431 className="p-0" 3432 className="p-0"
@@ -5833,8 +5834,6 @@ const OrderPage = () =&gt; { @@ -5833,8 +5834,6 @@ const OrderPage = () =&gt; {
5833 去处理 5834 去处理
5834 </Button> 5835 </Button>
5835 ]} 5836 ]}
5836 - // style={{ width: '1500px', height: '1500px' }} // 设置 Modal 的宽度和高度  
5837 - // bodyStyle={{ padding: '20px', color: 'red' }} // 设置 Modal 内容的样式  
5838 > 5837 >
5839 <Row 5838 <Row
5840 gutter={16} 5839 gutter={16}
@@ -5842,7 +5841,7 @@ const OrderPage = () =&gt; { @@ -5842,7 +5841,7 @@ const OrderPage = () =&gt; {
5842 align="middle" // Vertically center contents 5841 align="middle" // Vertically center contents
5843 > 5842 >
5844 <Col span={12}> 5843 <Col span={12}>
5845 - <div style={{ display: 'flex', justifyContent: 'center' }}> 5844 + <div style={{ display: 'flex', justifyContent: 'center', marginTop: '20px' }}>
5846 <Card 5845 <Card
5847 bordered={true} 5846 bordered={true}
5848 style={{ 5847 style={{
@@ -5859,12 +5858,23 @@ const OrderPage = () =&gt; { @@ -5859,12 +5858,23 @@ const OrderPage = () =&gt; {
5859 color: 'black', // 字体颜色 5858 color: 'black', // 字体颜色
5860 fontSize: '20px', // 字体大小 5859 fontSize: '20px', // 字体大小
5861 }}> 5860 }}>
5862 - Card content 5861 + <div style={{
  5862 + fontWeight: 'bold', // 字体加粗
  5863 + color: 'black', // 字体颜色
  5864 + fontSize: '40px', // 字体大小
  5865 + justifyContent: 'center',
  5866 + display: 'flex',
  5867 + alignItems: 'center',
  5868 + marginBottom: '20px',
  5869 + }}>
  5870 + {invoiceWarningNum}
  5871 + </div>
  5872 + 发票待确认订单
5863 </div> 5873 </div>
5864 </Card> 5874 </Card>
5865 </div></Col> 5875 </div></Col>
5866 <Col span={12}> 5876 <Col span={12}>
5867 - <div style={{ display: 'flex', justifyContent: 'center' }}> 5877 + <div style={{ display: 'flex', justifyContent: 'center', marginTop: '20px' }}>
5868 <Card 5878 <Card
5869 bordered={true} 5879 bordered={true}
5870 style={{ 5880 style={{
@@ -5881,12 +5891,23 @@ const OrderPage = () =&gt; { @@ -5881,12 +5891,23 @@ const OrderPage = () =&gt; {
5881 color: 'black', // 字体颜色 5891 color: 'black', // 字体颜色
5882 fontSize: '20px', // 字体大小 5892 fontSize: '20px', // 字体大小
5883 }}> 5893 }}>
5884 - Card content 5894 + <div style={{
  5895 + fontWeight: 'bold', // 字体加粗
  5896 + color: 'black', // 字体颜色
  5897 + fontSize: '40px', // 字体大小
  5898 + justifyContent: 'center',
  5899 + display: 'flex',
  5900 + alignItems: 'center',
  5901 + marginBottom: '20px',
  5902 + }}>
  5903 + {invoiceRefundWarningNum}
  5904 + </div>
  5905 + 回款待确认订单
5885 </div> 5906 </div>
5886 </Card> 5907 </Card>
5887 </div></Col> 5908 </div></Col>
5888 </Row> 5909 </Row>
5889 - <div style={{ color: 'red' }}> 5910 + <div style={{ color: 'red', padding: '40px' }}>
5890 <p>预警说明:</p> 5911 <p>预警说明:</p>
5891 <p>1、从订单确认收货之日起,超过5天未和客户确认发票(不开票的订单除外)的订单将会进行第一次提醒;超过15天未和客户确认发票(不开票的订单除外)的订单将会每天进行一次提醒,并限制下单功能</p> 5912 <p>1、从订单确认收货之日起,超过5天未和客户确认发票(不开票的订单除外)的订单将会进行第一次提醒;超过15天未和客户确认发票(不开票的订单除外)的订单将会每天进行一次提醒,并限制下单功能</p>
5892 <p>2、从发票确认之日起,超过15天未确认回款的订单将会进行第一次提醒,超过25天未确认回款的订单将会每天进行一次提醒,并限制下单功能</p> 5913 <p>2、从发票确认之日起,超过15天未确认回款的订单将会进行第一次提醒,超过25天未确认回款的订单将会每天进行一次提醒,并限制下单功能</p>
src/pages/Order/WarningWhitelist/components/AfterSalesDrawer.tsx deleted 100644 → 0
1 -import { RESPONSE_CODE } from '@/constants/enum';  
2 -import { postServiceOrderApplyAfterSales } from '@/services';  
3 -import { enumToSelect } from '@/utils';  
4 -import {  
5 - DrawerForm,  
6 - ProFormDigit,  
7 - ProFormSelect,  
8 - ProFormTextArea,  
9 - ProFormUploadDragger,  
10 -} from '@ant-design/pro-components';  
11 -import { Form, message } from 'antd';  
12 -import { AFTE_SALES_PLAN_OPTIONS } from '../../constant';  
13 -export default ({ setVisible, mainOrder, subOrders, onClose }) => {  
14 - let subOrderIds = subOrders?.map((item: { id: any }) => {  
15 - return item.id;  
16 - });  
17 -  
18 - let mainOrderId = mainOrder.id;  
19 - const [form] = Form.useForm<{  
20 - afterSalesNotes: string;  
21 - afterSalesPlan: string;  
22 - ids: [];  
23 - totalPayment: number;  
24 - filePaths: any[];  
25 - }>();  
26 -  
27 - return (  
28 - <DrawerForm<{  
29 - afterSalesNotes: string;  
30 - afterSalesPlan: string;  
31 - subOrderIds: [];  
32 - totalPayment: number;  
33 - mainId: number;  
34 - filePaths: any[];  
35 - }>  
36 - title="申请售后"  
37 - open  
38 - resize={{  
39 - onResize() {  
40 - console.log('resize!');  
41 - },  
42 - maxWidth: window.innerWidth * 0.8,  
43 - minWidth: 500,  
44 - }}  
45 - form={form}  
46 - autoFocusFirstInput  
47 - drawerProps={{  
48 - destroyOnClose: true,  
49 - onClose: () => {  
50 - setVisible(false);  
51 - },  
52 - }}  
53 - onFinish={async (values) => {  
54 - values.subOrderIds = subOrderIds;  
55 - values.mainId = mainOrderId;  
56 - values.filePaths = values.filePaths?.map((file) => {  
57 - return { url: file.response.data[0] };  
58 - });  
59 - let res = await postServiceOrderApplyAfterSales({ data: values });  
60 - if (res?.result === RESPONSE_CODE.SUCCESS) {  
61 - message.success(res.message);  
62 - onClose();  
63 - }  
64 - }}  
65 - >  
66 - <ProFormSelect  
67 - key="key"  
68 - label="售后方案"  
69 - width="lg"  
70 - showSearch  
71 - name="afterSalesPlan"  
72 - options={enumToSelect(AFTE_SALES_PLAN_OPTIONS)}  
73 - placeholder="请搜索"  
74 - rules={[{ required: true, message: '售后方案必填' }]}  
75 - ></ProFormSelect>  
76 - <ProFormDigit  
77 - width="lg"  
78 - name="totalPayment"  
79 - label="总金额调整"  
80 - min={0}  
81 - initialValue={mainOrder.totalPayment}  
82 - rules={[{ required: true, message: '总金额必填' }]}  
83 - />  
84 - <ProFormTextArea  
85 - width="lg"  
86 - label="售后原因"  
87 - name="afterSalesNotes"  
88 - rules={[{ required: true, message: '售后原因必填' }]}  
89 - />  
90 - <ProFormUploadDragger  
91 - key="filePaths"  
92 - label="附件"  
93 - name="filePaths"  
94 - action="/api/service/order/fileProcess"  
95 - fieldProps={{  
96 - headers: { Authorization: localStorage.getItem('token') },  
97 - }}  
98 - />  
99 - </DrawerForm>  
100 - );  
101 -};  
src/pages/Order/WarningWhitelist/components/ApplyForInvoicingModal.tsx deleted 100644 → 0
1 -import { RESPONSE_CODE } from '@/constants/enum';  
2 -import { postServiceOrderApplyInvoicing } from '@/services';  
3 -import { enumToSelect, getAliYunOSSFileNameFromUrl } from '@/utils';  
4 -import {  
5 - ModalForm,  
6 - ProFormSelect,  
7 - ProFormText,  
8 - ProFormTextArea,  
9 - ProFormUploadDragger,  
10 -} from '@ant-design/pro-components';  
11 -import { Form, message } from 'antd';  
12 -import { useEffect, useState } from 'react';  
13 -import { PAYEE_OPTIONS } from '../../constant';  
14 -export default ({  
15 - setCheckVisible,  
16 - isEdit,  
17 - subOrders,  
18 - isMainOrder,  
19 - totalPayment,  
20 - onClose,  
21 -}) => {  
22 - const [isUrgent, setIsUrgent] = useState('');  
23 - let sumPrice = totalPayment;  
24 -  
25 - let ids = subOrders?.map((item) => {  
26 - return item.id;  
27 - });  
28 -  
29 - let mainIdSet = new Set();  
30 - subOrders?.forEach((item: { mainOrderId: unknown }) => {  
31 - mainIdSet.add(item.mainOrderId);  
32 - });  
33 -  
34 - let mainIds = Array.from(mainIdSet).join(',');  
35 -  
36 - let newListAnnex = [];  
37 -  
38 - //回显,子订单可以编辑备注跟附件  
39 - if (isEdit) {  
40 - newListAnnex = subOrders.afterAnnexList?.map((path) => {  
41 - let i = 0;  
42 - return {  
43 - uid: i++,  
44 - name: getAliYunOSSFileNameFromUrl(path),  
45 - status: 'uploaded',  
46 - url: path,  
47 - response: { data: [path] },  
48 - };  
49 - });  
50 - subOrders.filePaths = newListAnnex;  
51 - }  
52 -  
53 - const [form] = Form.useForm<{  
54 - applyInvoicingNotes: string;  
55 - filePaths: any;  
56 - subIds: any[];  
57 - afterInvoicingUpdate: boolean;  
58 - receivingCompany: string;  
59 - isUrgent: boolean;  
60 - deadline: string;  
61 - }>();  
62 -  
63 - useEffect(() => {  
64 - //显示拼接的主订单id  
65 - form.setFieldValue('applyInvoicingNotes', mainIds);  
66 - }, []);  
67 -  
68 - return (  
69 - <ModalForm<{  
70 - applyInvoicingNotes: string;  
71 - filePaths: any;  
72 - subIds: any[];  
73 - afterInvoicingUpdate: boolean;  
74 - }>  
75 - width={500}  
76 - open  
77 - title={isEdit ? '修改信息' : '申请开票'}  
78 - initialValues={subOrders}  
79 - form={form}  
80 - autoFocusFirstInput  
81 - modalProps={{  
82 - okText: '确认',  
83 - cancelText: '取消',  
84 - destroyOnClose: true,  
85 - onCancel: () => {  
86 - setCheckVisible(false);  
87 - },  
88 - }}  
89 - submitter={{  
90 - render: (props, defaultDoms) => {  
91 - return defaultDoms;  
92 - },  
93 - }}  
94 - submitTimeout={2000}  
95 - onFinish={async (values) => {  
96 - values.subIds = ids;  
97 - //附件处理  
98 - values.filePaths = values.filePaths?.map((item) => {  
99 - return { url: item.response.data[0] };  
100 - });  
101 -  
102 - if (isEdit) {  
103 - values.afterInvoicingUpdate = true;  
104 - } else {  
105 - values.afterInvoicingUpdate = false;  
106 - }  
107 -  
108 - const res = await postServiceOrderApplyInvoicing({ data: values });  
109 -  
110 - if (res.result === RESPONSE_CODE.SUCCESS) {  
111 - message.success(res.message);  
112 - onClose();  
113 - }  
114 - }}  
115 - onOpenChange={setCheckVisible}  
116 - >  
117 - {isMainOrder ? (  
118 - <div className="mb-[24px]">  
119 - <span>选中子订单金额之和:</span>  
120 - <span className="text-red-500">{sumPrice}¥</span>  
121 - </div>  
122 - ) : (  
123 - ''  
124 - )}  
125 -  
126 - <div className="mb-1">  
127 - 如果需要合并订单,请将需要合并的订单id写在备注中,id之间用英文逗号隔开。  
128 - </div>  
129 - <ProFormTextArea  
130 - width="lg"  
131 - name="applyInvoicingNotes"  
132 - key="applyInvoicingNotes"  
133 - placeholder="请输入备注"  
134 - onMetaChange={(val) => {  
135 - console.log(val);  
136 - }}  
137 - proFieldProps={{  
138 - onchange: () => {  
139 - message.info('change');  
140 - },  
141 - }}  
142 - />  
143 - <ProFormText  
144 - width="lg"  
145 - name="purchaser"  
146 - label="抬头名称"  
147 - key="purchaser"  
148 - placeholder="请输入抬头名称"  
149 - rules={[{ required: true, message: '抬头名称必填' }]}  
150 - />  
151 - <ProFormSelect  
152 - placeholder="选择收款单位"  
153 - name="receivingCompany"  
154 - width="lg"  
155 - key="receivingCompany"  
156 - label={  
157 - <div>  
158 - <span>开票收款单位</span>  
159 - <span className="pl-2 text-xs text-gray-400">  
160 - 财务开票将依据这个字段,选择对应的公司开票(若对[收款单位]没有要求,请任意选择一个)  
161 - </span>  
162 - </div>  
163 - }  
164 - options={enumToSelect(PAYEE_OPTIONS)}  
165 - rules={[{ required: true, message: '开票收款单位必填' }]}  
166 - />  
167 - <ProFormSelect  
168 - placeholder="选择是否加急"  
169 - name="isUrgent"  
170 - width="lg"  
171 - key="isUrgent"  
172 - label="是否加急"  
173 - options={[  
174 - { label: '是', value: 'true' },  
175 - { label: '否', value: 'false' },  
176 - ]}  
177 - rules={[{ required: true, message: '是否加急必填' }]}  
178 - onChange={(val: any) => {  
179 - setIsUrgent(val);  
180 - }}  
181 - />  
182 -  
183 - {/* <ProFormDatePicker  
184 - key="deadline"  
185 - label="期望开票时间"  
186 - name="deadline"  
187 - rules={[{ required: isUrgent === 'true', message: '期望开票时间必填' }]}  
188 - hidden={isUrgent !== 'true'}  
189 - /> */}  
190 -  
191 - <ProFormTextArea  
192 - key="invoicingUrgentCause"  
193 - label="加急开票原因"  
194 - name="invoicingUrgentCause"  
195 - rules={[{ required: isUrgent === 'true', message: '加急开票原因' }]}  
196 - hidden={isUrgent !== 'true'}  
197 - />  
198 -  
199 - <ProFormUploadDragger  
200 - key="2"  
201 - label={  
202 - <div>  
203 - <span>开票明细确认表</span>  
204 - <span className="pl-2 text-xs text-gray-400">  
205 - 如果开票信息有变更,如开票内容跟下单内容不一致、下单抬头和付款抬头不一致,请上传开票明细确认表。  
206 - </span>  
207 - </div>  
208 - }  
209 - name="filePaths"  
210 - action="/api/service/order/fileProcess"  
211 - fieldProps={{  
212 - headers: { Authorization: localStorage.getItem('token') },  
213 - }}  
214 - />  
215 - </ModalForm>  
216 - );  
217 -};  
src/pages/Order/WarningWhitelist/components/AttachmentModal.tsx deleted 100644 → 0
1 -import { getAliYunOSSFileNameFromUrl, isImageName } from '@/utils';  
2 -import { ModalForm } from '@ant-design/pro-components';  
3 -import { Button, Card, Divider, Empty, Form, Image, List, message } from 'antd';  
4 -import Base64 from 'base-64';  
5 -import { cloneDeep } from 'lodash';  
6 -import React, { useEffect, useState } from 'react';  
7 -  
8 -export default ({ data, onClose }) => {  
9 - let newData = cloneDeep(data);  
10 - const [fileList, setFileList] = useState<[]>([]);  
11 - console.log(fileList);  
12 - const [form] = Form.useForm<{  
13 - subOrderId: '';  
14 - listAnnex: [];  
15 - }>();  
16 -  
17 - let newListAnnex = newData.listAnnex?.map((path) => {  
18 - let i = 0;  
19 - return {  
20 - uid: i++,  
21 - name: getAliYunOSSFileNameFromUrl(path),  
22 - status: 'uploaded',  
23 - url: path,  
24 - response: { data: [path] },  
25 - };  
26 - });  
27 - newData.listAnnex = newListAnnex;  
28 -  
29 - //将图片和其他文件区分开  
30 - let images: any[] = [];  
31 - let otherAnnex: any[] = [];  
32 - newListAnnex.forEach((item: any) => {  
33 - if (isImageName(item.name)) {  
34 - images.push(item);  
35 - } else {  
36 - otherAnnex.push(item);  
37 - }  
38 - });  
39 -  
40 - useEffect(() => {  
41 - setFileList(newData.listAnnex);  
42 - }, []);  
43 -  
44 - return (  
45 - <ModalForm  
46 - width={800}  
47 - open  
48 - title="查看附件"  
49 - initialValues={newData}  
50 - form={form}  
51 - modalProps={{  
52 - onCancel: onClose,  
53 - }}  
54 - submitter={{  
55 - render: () => {  
56 - return [  
57 - <Button  
58 - key="back"  
59 - onClick={() => {  
60 - onClose();  
61 - }}  
62 - >  
63 - 返回  
64 - </Button>,  
65 - ];  
66 - },  
67 - }}  
68 - >  
69 - {newListAnnex?.length <= 0 ? (  
70 - <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />  
71 - ) : (  
72 - // <ProFormUploadDragger  
73 - // name="listAnnex"  
74 - // action="/api/service/order/fileProcess"  
75 - // disabled  
76 - // fieldProps={{  
77 - // headers: { Authorization: localStorage.getItem('token') },  
78 - // // onRemove: (file) => {  
79 - // // const index = fileList[listMeta.index].indexOf(file);  
80 - // // console.log(index);  
81 - // // const newFileList = fileList.slice();  
82 - // // newFileList.splice(index, 1);  
83 - // // setFileList(newFileList);  
84 - // // },  
85 - // // beforeUpload: (file) => {  
86 - // // fileList[listMeta.index] = [...fileList[listMeta.index], file as RcFile];  
87 - // // setFileList(fileList);  
88 - // // return true;  
89 - // // },  
90 - // fileList,  
91 - // // defaultFileList: itemFileList  
92 - // }}  
93 - // />  
94 - <>  
95 - <Card>  
96 - <Image.PreviewGroup  
97 - className="mr-10"  
98 - preview={{  
99 - onChange: (current, prev) =>  
100 - console.log(`current index: ${current}, prev index: ${prev}`),  
101 - }}  
102 - >  
103 - {images.map((item, index) => (  
104 - <React.Fragment key={index}>  
105 - <Image  
106 - className="max-h-[200px] max-w-[200px]"  
107 - src={item.url}  
108 - title={item.name}  
109 - />{' '}  
110 - <Divider type="vertical" />  
111 - </React.Fragment>  
112 - ))}  
113 - </Image.PreviewGroup>  
114 - </Card>  
115 - <Divider />  
116 -  
117 - <div>  
118 - <List  
119 - size="small"  
120 - header={<div>其他类型文件</div>}  
121 - bordered  
122 - dataSource={otherAnnex}  
123 - renderItem={(item) => (  
124 - <List.Item  
125 - actions={[  
126 - <Button  
127 - type="link"  
128 - key="key"  
129 - href={item.url}  
130 - target="blank"  
131 - className="py-1"  
132 - >  
133 - 下载  
134 - </Button>,  
135 - <Button  
136 - type="link"  
137 - key="key"  
138 - className="py-1"  
139 - onClick={() => {  
140 - message.info(item.url);  
141 - window.open(  
142 - '/previewApi/onlinePreview?url=' +  
143 - encodeURIComponent(Base64.encode(item.url)),  
144 - );  
145 - }}  
146 - >  
147 - 预览  
148 - </Button>,  
149 - ]}  
150 - >  
151 - <div>  
152 - <span>{item.name}</span>  
153 - </div>  
154 - </List.Item>  
155 - )}  
156 - />  
157 - </div>  
158 - </>  
159 - )}  
160 - </ModalForm>  
161 - );  
162 -};  
src/pages/Order/WarningWhitelist/components/BaseModal.tsx deleted 100644 → 0
1 -import { ModalForm } from '@ant-design/pro-components';  
2 -import { Form } from 'antd';  
3 -  
4 -// import { cloneDeep } from 'lodash';  
5 -export default ({ setVisible, onClose }) => {  
6 - const [form] = Form.useForm<{ name: string; company: string }>();  
7 -  
8 - return (  
9 - <>  
10 - <ModalForm<{  
11 - name: string;  
12 - company: string;  
13 - }>  
14 - width={500}  
15 - open  
16 - title="标题"  
17 - form={form}  
18 - autoFocusFirstInput  
19 - modalProps={{  
20 - okText: '通过',  
21 - cancelText: '取消',  
22 - destroyOnClose: true,  
23 - onCancel: () => {  
24 - setVisible(false);  
25 - },  
26 - }}  
27 - onFinish={async (values) => {  
28 - console.log(values);  
29 - onClose();  
30 - }}  
31 - onOpenChange={setVisible}  
32 - ></ModalForm>  
33 - </>  
34 - );  
35 -};  
src/pages/Order/WarningWhitelist/components/CheckModal.tsx deleted 100644 → 0
1 -import { RESPONSE_CODE } from '@/constants/enum';  
2 -import {  
3 - postPrepaidAudit,  
4 - postServiceOrderAfterSalesCheck,  
5 - postServiceOrderAudit,  
6 - postServiceOrderFileProcess,  
7 - postServiceOrderFinanceCheckOrder,  
8 - postServiceOrderLeaderAudit,  
9 - postServiceOrderToProcureAudit,  
10 -} from '@/services';  
11 -import {  
12 - ModalForm,  
13 - ProFormTextArea,  
14 - ProList,  
15 -} from '@ant-design/pro-components';  
16 -import {  
17 - Button,  
18 - Col,  
19 - Divider,  
20 - Form,  
21 - Image,  
22 - Modal,  
23 - Row,  
24 - Space,  
25 - Tag,  
26 - UploadFile,  
27 - message,  
28 -} from 'antd';  
29 -import Upload, { RcFile, UploadProps } from 'antd/es/upload';  
30 -import { useEffect, useRef, useState } from 'react';  
31 -import {  
32 - AFTE_SALES_PLAN_OPTIONS,  
33 - CHECK_TYPE,  
34 - COMFIR_RECEIPT_IMAGES_NUMBER,  
35 -} from '../../constant';  
36 -// import { cloneDeep } from 'lodash';  
37 -import InvoiceSubOrderInfoTable from '@/pages/Order/Order/components/InvoiceSubOrderInfoTable';  
38 -import { enumValueToLabel, transImageFile } from '@/utils';  
39 -import { PlusOutlined } from '@ant-design/icons';  
40 -import { cloneDeep } from 'lodash';  
41 -  
42 -export default ({  
43 - setCheckVisible,  
44 - data,  
45 - subOrders,  
46 - orderCheckType,  
47 - openOrderDrawer,  
48 - onClose,  
49 -}) => {  
50 - const [previewOpen, setPreviewOpen] = useState(false);  
51 - const [aPopoverTitle, setAPopoverTitle] = useState('审核');  
52 - const [previewImage, setPreviewImage] = useState('');  
53 - const [previewTitle, setPreviewTitle] = useState('');  
54 - const [paymentReceiptsImages, setPymentReceiptsImages] = useState<any[]>([]);  
55 - const fileListObj = useRef<UploadFile[]>([]); //使用引用类型,使得在useEffect里面设置监听事件后,不用更新监听事件也能保持obj与外界一致  
56 - const getBase64 = (file: RcFile): Promise<string> =>  
57 - new Promise((resolve, reject) => {  
58 - const reader = new FileReader();  
59 - reader.readAsDataURL(file);  
60 - reader.onload = () => resolve(reader.result as string);  
61 - reader.onerror = (error) => reject(error);  
62 - });  
63 - const [fileList, setFileList] = useState<UploadFile[]>([]);  
64 - const handleCancel = () => setPreviewOpen(false);  
65 - const [messageApi, contextHolder] = message.useMessage();  
66 - const [form] = Form.useForm<{ name: string; company: string }>();  
67 - let subOrderIds: any[] = subOrders?.map((subOrder) => subOrder.id);  
68 - const [mainOrderId] = useState(data.id);  
69 -  
70 - const [afterSalesInfo, setAfterSalesInfo] = useState<any>();  
71 - const [prepaidProofImages, setPrepaidProofImages] = useState<any[]>([]);  
72 - /**  
73 - * 审核类型  
74 - */  
75 - function checkType(check: string) {  
76 - if (orderCheckType === check) {  
77 - return true;  
78 - }  
79 - return false;  
80 - }  
81 -  
82 - const getOrderAfterSalesInfo = async () => {  
83 - // let res = await postServiceOrderQueryAfterSalesInfoSnapshot({  
84 - // data: { subOrderIds: subOrderIds },  
85 - // });  
86 -  
87 - //附件  
88 - let annex = subOrders[0].afterSalesAnnexList;  
89 - let index = 1;  
90 - let annexLinks = annex?.map((f) => {  
91 - return (  
92 - <Button className="p-0 pr-1" type="link" key="key" href={f}>  
93 - {'附件' + index++}  
94 - </Button>  
95 - );  
96 - });  
97 -  
98 - console.log(annexLinks);  
99 -  
100 - setAfterSalesInfo(  
101 - <div className="my-5">  
102 - <Row gutter={[16, 24]}>  
103 - <Col span={6}>  
104 - <span className="text-[#333333]">售后方案</span>  
105 - </Col>  
106 - <Col span={18}>  
107 - {enumValueToLabel(  
108 - subOrders[0]?.afterSalesPlan,  
109 - AFTE_SALES_PLAN_OPTIONS,  
110 - )}  
111 - </Col>  
112 - <Col span={6}>  
113 - <span className="className='text-[#333333]'">售后原因</span>  
114 - </Col>  
115 - <Col span={18}>{subOrders[0]?.afterSalesNotes}</Col>  
116 - <Col span={6}>  
117 - <span className="className='text-[#333333]'">附件</span>  
118 - </Col>  
119 - <Col span={18}>{annexLinks}</Col>  
120 - </Row>  
121 - </div>,  
122 - );  
123 - };  
124 -  
125 - useEffect(() => {  
126 - if (checkType(CHECK_TYPE.CONFIRM_DELIVER)) {  
127 - setAPopoverTitle('确认发货');  
128 - }  
129 - getOrderAfterSalesInfo();  
130 -  
131 - let paymentReceiptsImagesList: any[] = [];  
132 - subOrders?.forEach((item: any) => {  
133 - if (item.paymentReceiptAnnexList) {  
134 - paymentReceiptsImagesList.push(...item.paymentReceiptAnnexList);  
135 - }  
136 - });  
137 - //去重  
138 - paymentReceiptsImagesList = [...new Set(paymentReceiptsImagesList)];  
139 - setPymentReceiptsImages(paymentReceiptsImagesList);  
140 -  
141 - //预存审核的凭证  
142 - let proofImages: any[] = [];  
143 - subOrders?.forEach((item) => {  
144 - let images = item.proofImages;  
145 - if (images !== null && images !== undefined) {  
146 - proofImages.push(...images);  
147 - }  
148 - });  
149 - setPrepaidProofImages(proofImages);  
150 - }, []);  
151 -  
152 - const handleChange: UploadProps['onChange'] = ({ fileList: newFileList }) => {  
153 - //fileListObj得在change里变化,change的参数是已经处理过的file数组  
154 - //beforeUpload中的参数file是未处理过,还需要Base64拿到文件数据处理  
155 - fileListObj.current = newFileList;  
156 - setFileList(newFileList);  
157 - };  
158 -  
159 - /** 粘贴快捷键的回调 */  
160 - const onPaste = async (e: any) => {  
161 - /** 获取剪切板的数据clipboardData */  
162 - let clipboardData = e.clipboardData,  
163 - i = 0,  
164 - items,  
165 - item,  
166 - types;  
167 -  
168 - /** 为空判断 */  
169 - if (clipboardData) {  
170 - items = clipboardData.items;  
171 - if (!items) {  
172 - message.info('您的剪贴板中没有照片');  
173 - return;  
174 - }  
175 -  
176 - item = items[0];  
177 - types = clipboardData.types || [];  
178 - /** 遍历剪切板的数据 */  
179 - for (; i < types.length; i++) {  
180 - if (types[i] === 'Files') {  
181 - item = items[i];  
182 - break;  
183 - }  
184 - }  
185 -  
186 - /** 判断文件是否为图片 */  
187 - if (item && item.kind === 'file' && item.type.match(/^image\//i)) {  
188 - const imgItem = item.getAsFile();  
189 - const newFileList = cloneDeep(fileListObj.current);  
190 - let filteredArray = newFileList.filter(  
191 - (obj) => obj.status !== 'removed',  
192 - ); //过滤掉状态为已删除的照片  
193 - const listItem = {  
194 - ...imgItem,  
195 - status: 'done',  
196 - url: await getBase64(imgItem),  
197 - originFileObj: imgItem,  
198 - };  
199 -  
200 - if (filteredArray.length >= COMFIR_RECEIPT_IMAGES_NUMBER) {  
201 - message.info('发货照片数量不能超过3');  
202 - return;  
203 - }  
204 - fileListObj.current = filteredArray;  
205 - filteredArray.push(listItem);  
206 - setFileList(filteredArray);  
207 - return;  
208 - }  
209 - }  
210 -  
211 - message.info('您的剪贴板中没有照片');  
212 - };  
213 - useEffect(() => {  
214 - //回显售后信息  
215 - // if (checkType(CHECK_TYPE.AFTER_SALES)) {  
216 - // getOrderAfterSalesInfo();  
217 - // }  
218 -  
219 - document.addEventListener('paste', onPaste);  
220 - return () => {  
221 - document.removeEventListener('paste', onPaste);  
222 - };  
223 - }, []);  
224 - const uploadButton = (  
225 - <div>  
226 - <PlusOutlined />  
227 - <div style={{ marginTop: 8 }}>上传凭证</div>  
228 - </div>  
229 - );  
230 - const handlePreview = async (file: UploadFile) => {  
231 - if (!file.url && !file.preview) {  
232 - file.preview = await getBase64(file.originFileObj as RcFile);  
233 - }  
234 - setPreviewImage(file.url || (file.preview as string));  
235 - setPreviewOpen(true);  
236 - setPreviewTitle(  
237 - file.name ||  
238 - file.originFileObj?.name ||  
239 - file.url!.substring(file.url!.lastIndexOf('/') + 1),  
240 - );  
241 - };  
242 -  
243 - const handleBeforeUpload = (file: any) => {  
244 - setFileList([...fileList, file]);  
245 - return false;  
246 - };  
247 -  
248 - const props: UploadProps = {  
249 - onRemove: (file) => {  
250 - const index = fileList.indexOf(file);  
251 - const newFileList = fileList.slice();  
252 - newFileList.splice(index, 1);  
253 - setFileList(newFileList);  
254 - },  
255 - beforeUpload: handleBeforeUpload,  
256 - listType: 'picture-card',  
257 - onPreview: handlePreview,  
258 - fileList,  
259 - onChange: handleChange,  
260 - accept: 'image/png, image/jpeg, image/png',  
261 - // action: '/api/service/order/fileProcess',  
262 - name: 'files',  
263 - headers: { Authorization: localStorage.getItem('token') },  
264 - };  
265 -  
266 - //仓库审核  
267 - async function doCheck(body: object) {  
268 - const data = await postServiceOrderAudit({  
269 - data: body,  
270 - });  
271 - if (data.result === RESPONSE_CODE.SUCCESS) {  
272 - message.success(data.message);  
273 - onClose();  
274 - }  
275 - }  
276 -  
277 - /**  
278 - *  
279 - * @param body 财务审核  
280 - */  
281 - async function doFinancailCheck(values: any, isAgree: boolean) {  
282 - if (fileList.length <= 0) {  
283 - message.error('凭证不能为空');  
284 - return;  
285 - }  
286 - messageApi.open({  
287 - type: 'loading',  
288 - content: '正在上传图片...',  
289 - duration: 0,  
290 - });  
291 - //附件处理  
292 - let formData = new FormData();  
293 - //附件处理  
294 - for (let file of fileList) {  
295 - if (file.originFileObj) {  
296 - formData.append('files', file.originFileObj as RcFile);  
297 - } else {  
298 - //有url的话取url(源文件),没url取thumbUrl。有url的时候thumbUrl是略缩图  
299 - if (file?.url === undefined || file?.url === null) {  
300 - formData.append(  
301 - 'files',  
302 - transImageFile(file?.thumbUrl),  
303 - file?.originFileObj?.name,  
304 - );  
305 - } else {  
306 - formData.append(  
307 - 'files',  
308 - transImageFile(file?.url),  
309 - file?.originFileObj?.name,  
310 - );  
311 - }  
312 - }  
313 - }  
314 - let res = await postServiceOrderFileProcess({  
315 - data: formData,  
316 - });  
317 - messageApi.destroy();  
318 - if (res.result === RESPONSE_CODE.SUCCESS) {  
319 - message.success('上传成功!');  
320 -  
321 - let fileUrls = res?.data?.map((item) => {  
322 - return { url: item };  
323 - });  
324 - //财务审核  
325 - const data = await postServiceOrderFinanceCheckOrder({  
326 - data: {  
327 - checkNotes: values.name,  
328 - ids: subOrderIds,  
329 - checkPassOrReject: isAgree,  
330 - invoicingCheckAnnex: fileUrls,  
331 - },  
332 - });  
333 - if (data.result === RESPONSE_CODE.SUCCESS) {  
334 - message.success(data.message);  
335 - onClose();  
336 - }  
337 - } else {  
338 - message.success('上传失败');  
339 - }  
340 - }  
341 -  
342 - /**  
343 - *  
344 - * @param body 售后审核  
345 - */  
346 - async function doAfterSalesCheck(body: object) {  
347 - const data = await postServiceOrderAfterSalesCheck({  
348 - data: body,  
349 - });  
350 - if (data.result === RESPONSE_CODE.SUCCESS) {  
351 - message.success(data.message);  
352 - onClose();  
353 - }  
354 - }  
355 -  
356 - /**  
357 - *  
358 - * @param body 领导审核  
359 - */  
360 - async function doLeaderCheck(body: object) {  
361 - const data = await postServiceOrderLeaderAudit({  
362 - data: body,  
363 - });  
364 - if (data.result === RESPONSE_CODE.SUCCESS) {  
365 - message.success(data.message);  
366 - onClose();  
367 - }  
368 - }  
369 -  
370 - /**  
371 - * 预存审核  
372 - * @param body  
373 - */  
374 - async function doPrepaidAudit(body: any) {  
375 - const data = await postPrepaidAudit({  
376 - data: body,  
377 - });  
378 - if (data.result === RESPONSE_CODE.SUCCESS) {  
379 - message.success(data.message);  
380 - onClose();  
381 - }  
382 - }  
383 -  
384 - function computeType() {  
385 - let type: string = '';  
386 - if (checkType(CHECK_TYPE.CONFIRM_DELIVER)) {  
387 - type = 'confirm_deliver';  
388 - }  
389 - if (checkType(CHECK_TYPE.WEARHOUSE_KEEPER)) {  
390 - type = 'warehouse_audit';  
391 - }  
392 - if (checkType(CHECK_TYPE.WAITING_FOR_POST_AUDIT)) {  
393 - type = 'post_audit';  
394 - }  
395 - if (checkType(CHECK_TYPE.NODE_OPERATING_AUDIT)) {  
396 - type = 'node_operating_audit';  
397 - }  
398 - if (checkType(CHECK_TYPE.MODIFY_LEADER_AUDIT)) {  
399 - type = 'modify_leader_audit';  
400 - }  
401 - if (checkType(CHECK_TYPE.URGENT_INVOICE_AUDITING)) {  
402 - type = 'urgent_invoice_audit';  
403 - }  
404 - if (checkType(CHECK_TYPE.PAYMENT_RECEIPTS_AUDIT)) {  
405 - type = 'payment_receipt_audit';  
406 - }  
407 - if (checkType(CHECK_TYPE.CONFIRM_REISSUE)) {  
408 - type = 'confirm_reissue';  
409 - }  
410 - if (checkType(CHECK_TYPE.CREDIT_AUDIT)) {  
411 - type = 'credit_audit';  
412 - }  
413 - if (checkType(CHECK_TYPE.URGENT_INVOICE_AUDITING_OLD)) {  
414 - type = 'urgent_invoice_audit_old';  
415 - }  
416 - if (checkType(CHECK_TYPE.CONFIRM_REISSUE_OLD)) {  
417 - type = 'confirm_reissue_old';  
418 - }  
419 - return type;  
420 - }  
421 -  
422 - return (  
423 - <>  
424 - <ModalForm<{  
425 - name: string;  
426 - company: string;  
427 - }>  
428 - width={500}  
429 - open  
430 - title={aPopoverTitle}  
431 - form={form}  
432 - autoFocusFirstInput  
433 - modalProps={{  
434 - okText: '通过',  
435 - cancelText: '驳回',  
436 - destroyOnClose: true,  
437 - onCancel: () => {  
438 - setCheckVisible(false);  
439 - },  
440 - }}  
441 - submitter={{  
442 - render: (props, defaultDoms) => {  
443 - let myDoms = [];  
444 - if (!checkType(CHECK_TYPE.CONFIRM_DELIVER)) {  
445 - myDoms.push(  
446 - <Button  
447 - key="驳回"  
448 - onClick={async () => {  
449 - if (checkType(CHECK_TYPE.AFTER_SALES)) {  
450 - doAfterSalesCheck({  
451 - applyType: 'after-sales',  
452 - isAfterSalesSuccess: false,  
453 - subOrderIds: subOrderIds,  
454 - mainId: mainOrderId,  
455 - afterSalesRejectionNotes: form.getFieldValue('name'),  
456 - });  
457 - return;  
458 - }  
459 -  
460 - if (checkType(CHECK_TYPE.FINALCIAL)) {  
461 - let values = { name: form.getFieldValue('name') };  
462 - doFinancailCheck(values, false);  
463 - return;  
464 - }  
465 -  
466 - if (checkType(CHECK_TYPE.LEADER_AUDIT)) {  
467 - doLeaderCheck({  
468 - pass: false,  
469 - subOrderIds: subOrderIds,  
470 - reason: form.getFieldValue('name'),  
471 - });  
472 - return;  
473 - }  
474 -  
475 - if (checkType(CHECK_TYPE.MODIFY_APPLY_WAIT_FOR_AUDIT)) {  
476 - doAfterSalesCheck({  
477 - applyType: 'order-change-normal',  
478 - isAfterSalesSuccess: false,  
479 - subOrderIds: subOrderIds,  
480 - mainId: mainOrderId,  
481 - afterSalesRejectionNotes: form.getFieldValue('name'),  
482 - });  
483 - return;  
484 - }  
485 -  
486 - //预存审核,先暂时共用同一个审核弹窗  
487 - if (checkType(CHECK_TYPE.PREPAID_AUDIT)) {  
488 - return doPrepaidAudit({  
489 - pass: false,  
490 - ids: subOrderIds,  
491 - auditNotes: form.getFieldValue('name'),  
492 - });  
493 - }  
494 -  
495 - let type = '';  
496 - type = computeType();  
497 - console.log('type:' + type);  
498 - doCheck({  
499 - pass: false,  
500 - subOrderIds: subOrderIds,  
501 - type: type,  
502 - notes: form.getFieldValue('name'),  
503 - });  
504 - }}  
505 - >  
506 - 驳回  
507 - </Button>,  
508 - );  
509 - }  
510 -  
511 - //如果是仓库审核,那么显示这个外部采购  
512 - if (checkType(CHECK_TYPE.WEARHOUSE_KEEPER)) {  
513 - myDoms.push(  
514 - <Button  
515 - key="外部采购"  
516 - onClick={async () => {  
517 - let res = await postServiceOrderToProcureAudit({  
518 - data: {  
519 - subOrderIds: subOrderIds,  
520 - },  
521 - });  
522 -  
523 - if (res && res.result === RESPONSE_CODE.SUCCESS) {  
524 - message.success(res.message);  
525 - onClose();  
526 - }  
527 - }}  
528 - >  
529 - 外部采购  
530 - </Button>,  
531 - );  
532 - }  
533 -  
534 - //确认  
535 - myDoms.push(defaultDoms[1]);  
536 - return myDoms;  
537 - },  
538 - }}  
539 - submitTimeout={2000}  
540 - onFinish={async (values) => {  
541 - if (checkType(CHECK_TYPE.AFTER_SALES)) {  
542 - //审核通过  
543 - return doAfterSalesCheck({  
544 - applyType: 'after-sales',  
545 - isAfterSalesSuccess: true,  
546 - subOrderIds: subOrderIds,  
547 - mainId: mainOrderId,  
548 - afterSalesRejectionNotes: values.name,  
549 - });  
550 - }  
551 - console.log('h');  
552 - if (checkType(CHECK_TYPE.FINALCIAL)) {  
553 - doFinancailCheck(values, true);  
554 - return;  
555 - }  
556 -  
557 - if (checkType(CHECK_TYPE.LEADER_AUDIT)) {  
558 - doLeaderCheck({  
559 - pass: true,  
560 - subOrderIds: subOrderIds,  
561 - reason: values.name,  
562 - });  
563 - return;  
564 - }  
565 -  
566 - if (checkType(CHECK_TYPE.MODIFY_APPLY_WAIT_FOR_AUDIT)) {  
567 - //审核通过  
568 - return doAfterSalesCheck({  
569 - applyType: 'order-change-normal',  
570 - isAfterSalesSuccess: true,  
571 - subOrderIds: subOrderIds,  
572 - mainId: mainOrderId,  
573 - afterSalesRejectionNotes: values.name,  
574 - });  
575 - }  
576 -  
577 - //预存审核,先暂时共用同一个审核弹窗  
578 - if (checkType(CHECK_TYPE.PREPAID_AUDIT)) {  
579 - return doPrepaidAudit({  
580 - pass: true,  
581 - ids: subOrderIds,  
582 - auditNotes: form.getFieldValue('name'),  
583 - });  
584 - }  
585 -  
586 - let type = '';  
587 - type = computeType();  
588 - doCheck({  
589 - pass: true,  
590 - subOrderIds: subOrderIds,  
591 - type: type,  
592 - notes: form.getFieldValue('name'),  
593 - });  
594 - }}  
595 - onOpenChange={setCheckVisible}  
596 - >  
597 - {checkType(CHECK_TYPE.AFTER_SALES) ? (  
598 - <>  
599 - {afterSalesInfo}  
600 - <Button  
601 - className="px-0"  
602 - type="link"  
603 - onClick={() => {  
604 - console.log(data);  
605 - openOrderDrawer('after-sales-check', mainOrderId);  
606 - }}  
607 - >  
608 - 查看旧订单  
609 - </Button>  
610 - </>  
611 - ) : (  
612 - ''  
613 - )}  
614 -  
615 - {checkType(CHECK_TYPE.PAYMENT_RECEIPTS_AUDIT) ? (  
616 - <>  
617 - <Divider orientation="center">  
618 - <span className="text-sm">回款凭证</span>  
619 - </Divider>  
620 - <Image.PreviewGroup  
621 - className="mr-10"  
622 - preview={{  
623 - onChange: (current, prev) =>  
624 - console.log(`current index: ${current}, prev index: ${prev}`),  
625 - }}  
626 - >  
627 - {paymentReceiptsImages.map((url) => (  
628 - <>  
629 - <Image width={120} src={url} /> <Divider type="vertical" />  
630 - </>  
631 - ))}  
632 - </Image.PreviewGroup>  
633 - <Divider></Divider>  
634 - </>  
635 - ) : (  
636 - ''  
637 - )}  
638 -  
639 - {checkType(CHECK_TYPE.PREPAID_AUDIT) && (  
640 - <>  
641 - <Divider orientation="center">  
642 - <span className="text-sm">凭证</span>  
643 - </Divider>  
644 - <Image.PreviewGroup  
645 - className="mr-10"  
646 - preview={{  
647 - onChange: (current, prev) =>  
648 - console.log(`current index: ${current}, prev index: ${prev}`),  
649 - }}  
650 - >  
651 - {prepaidProofImages.map((url) => (  
652 - <>  
653 - <Image width={120} src={url} /> <Divider type="vertical" />  
654 - </>  
655 - ))}  
656 - </Image.PreviewGroup>  
657 - <Divider></Divider>  
658 - </>  
659 - )}  
660 -  
661 - {checkType('prepaidAudit') ? (  
662 - <div>请特别注意手机号码和充值金额。</div>  
663 - ) : (  
664 - <div>请特别注意订单总金额与订单金额。</div>  
665 - )}  
666 - {!checkType(CHECK_TYPE.CONFIRM_DELIVER) ? (  
667 - <ProFormTextArea  
668 - width="lg"  
669 - name="name"  
670 - placeholder="若驳回,请填写驳回理由"  
671 - />  
672 - ) : (  
673 - <></>  
674 - )}  
675 - {checkType(CHECK_TYPE.FINALCIAL) ? (  
676 - <>  
677 - <div className="pb-4 text-xs decoration-gray-50">  
678 - 可复制照片粘贴  
679 - </div>  
680 - <Upload {...props}>  
681 - {fileList.length < COMFIR_RECEIPT_IMAGES_NUMBER  
682 - ? uploadButton  
683 - : ''}  
684 - </Upload>  
685 - </>  
686 - ) : (  
687 - ''  
688 - )}  
689 - {checkType(CHECK_TYPE.CONFIRM_REISSUE) && (  
690 - <>  
691 - <InvoiceSubOrderInfoTable  
692 - subOrderIds={subOrderIds}  
693 - ></InvoiceSubOrderInfoTable>  
694 - </>  
695 - )}  
696 - {checkType(CHECK_TYPE.URGENT_INVOICE_AUDITING) ? (  
697 - <>  
698 - <ProList  
699 - rowKey="id"  
700 - headerTitle="发票信息"  
701 - metas={{  
702 - title: {  
703 - dataIndex: 'name',  
704 - },  
705 - avatar: {  
706 - dataIndex: 'image',  
707 - editable: false,  
708 - },  
709 - description: {  
710 - dataIndex: 'desc',  
711 - },  
712 - subTitle: {  
713 - render: () => {  
714 - return (  
715 - <Space size={0}>  
716 - <Tag color="blue">Ant Design</Tag>  
717 - <Tag color="#5BD8A6">TechUI</Tag>  
718 - </Space>  
719 - );  
720 - },  
721 - },  
722 - actions: {  
723 - render: (text, row, index, action) => [  
724 - <a  
725 - onClick={() => {  
726 - action?.startEditable(row.id);  
727 - }}  
728 - key="link"  
729 - >  
730 - 编辑  
731 - </a>,  
732 - ],  
733 - },  
734 - }}  
735 - ></ProList>  
736 - </>  
737 - ) : (  
738 - ''  
739 - )}  
740 - </ModalForm>  
741 -  
742 - <Modal  
743 - open={previewOpen}  
744 - title={previewTitle}  
745 - footer={null}  
746 - onCancel={handleCancel}  
747 - >  
748 - <img alt="图片预览" style={{ width: '100%' }} src={previewImage} />  
749 - </Modal>  
750 - {contextHolder}  
751 - </>  
752 - );  
753 -};  
src/pages/Order/WarningWhitelist/components/ConfirmReceiptModal.tsx deleted 100644 → 0
1 -import { RESPONSE_CODE } from '@/constants/enum';  
2 -import { postServiceOrderConfirmReceipt } from '@/services';  
3 -import { PlusOutlined } from '@ant-design/icons';  
4 -import { Button, Modal, Upload, message } from 'antd';  
5 -import { RcFile, UploadFile, UploadProps } from 'antd/es/upload';  
6 -import { cloneDeep } from 'lodash';  
7 -import { useEffect, useRef, useState } from 'react';  
8 -import { COMFIR_RECEIPT_IMAGES_NUMBER } from '../../constant';  
9 -export default ({ data, onClose }) => {  
10 - const subIds = data?.map((item) => {  
11 - return item.id;  
12 - });  
13 - // const [form] = Form.useForm<{ name: string; company: string }>();  
14 - const [previewOpen, setPreviewOpen] = useState(false);  
15 - const [previewImage, setPreviewImage] = useState('');  
16 - const [previewTitle, setPreviewTitle] = useState('');  
17 - const fileListObj = useRef<UploadFile[]>([]); //使用引用类型,使得在useEffect里面设置监听事件后,不用更新监听事件也能保持obj与外界一致  
18 - const getBase64 = (file: RcFile): Promise<string> =>  
19 - new Promise((resolve, reject) => {  
20 - const reader = new FileReader();  
21 - reader.readAsDataURL(file);  
22 - reader.onload = () => resolve(reader.result as string);  
23 - reader.onerror = (error) => reject(error);  
24 - });  
25 - const [fileList, setFileList] = useState<UploadFile[]>([]);  
26 - const [uploading, setUploading] = useState(false);  
27 - const handleCancel = () => setPreviewOpen(false);  
28 -  
29 - const handleChange: UploadProps['onChange'] = ({ fileList: newFileList }) => {  
30 - //fileListObj得在change里变化,change的参数是已经处理过的file数组  
31 - //beforeUpload中的参数file是未处理过,还需要Base64拿到文件数据处理  
32 - fileListObj.current = newFileList;  
33 - setFileList(newFileList);  
34 - };  
35 -  
36 - /** 粘贴快捷键的回调 */  
37 - const onPaste = async (e: any) => {  
38 - /** 获取剪切板的数据clipboardData */  
39 - let clipboardData = e.clipboardData,  
40 - i = 0,  
41 - items,  
42 - item,  
43 - types;  
44 -  
45 - /** 为空判断 */  
46 - if (clipboardData) {  
47 - items = clipboardData.items;  
48 - if (!items) {  
49 - message.info('您的剪贴板中没有照片');  
50 - return;  
51 - }  
52 -  
53 - item = items[0];  
54 - types = clipboardData.types || [];  
55 - /** 遍历剪切板的数据 */  
56 - for (; i < types.length; i++) {  
57 - if (types[i] === 'Files') {  
58 - item = items[i];  
59 - break;  
60 - }  
61 - }  
62 -  
63 - /** 判断文件是否为图片 */  
64 - if (item && item.kind === 'file' && item.type.match(/^image\//i)) {  
65 - const imgItem = item.getAsFile();  
66 - const newFileList = cloneDeep(fileListObj.current);  
67 - let filteredArray = newFileList.filter(  
68 - (obj) => obj.status !== 'removed',  
69 - ); //过滤掉状态为已删除的照片  
70 - const listItem = {  
71 - ...imgItem,  
72 - status: 'done',  
73 - url: await getBase64(imgItem),  
74 - originFileObj: imgItem,  
75 - };  
76 -  
77 - if (filteredArray.length >= COMFIR_RECEIPT_IMAGES_NUMBER) {  
78 - message.info('发货凭证照片数量不能超过3');  
79 - return;  
80 - }  
81 - fileListObj.current = filteredArray;  
82 - filteredArray.push(listItem);  
83 - setFileList(filteredArray);  
84 - return;  
85 - }  
86 - }  
87 -  
88 - message.info('您的剪贴板中没有照片');  
89 - };  
90 - useEffect(() => {  
91 - document.addEventListener('paste', onPaste);  
92 - return () => {  
93 - document.removeEventListener('paste', onPaste);  
94 - };  
95 - }, []);  
96 - const uploadButton = (  
97 - <div>  
98 - <PlusOutlined />  
99 - <div style={{ marginTop: 8 }}>上传凭证</div>  
100 - </div>  
101 - );  
102 - const handlePreview = async (file: UploadFile) => {  
103 - if (!file.url && !file.preview) {  
104 - file.preview = await getBase64(file.originFileObj as RcFile);  
105 - }  
106 - setPreviewImage(file.url || (file.preview as string));  
107 - setPreviewOpen(true);  
108 - setPreviewTitle(  
109 - file.name ||  
110 - file.originFileObj?.name ||  
111 - file.url!.substring(file.url!.lastIndexOf('/') + 1),  
112 - );  
113 - };  
114 -  
115 - const handleUpload = async () => {  
116 - const formData = new FormData();  
117 - fileList.forEach((file) => {  
118 - //originFileObj二进制文件  
119 - formData.append('files', file.originFileObj as RcFile);  
120 - });  
121 - // console.log(fileList[0] as RcFile)  
122 - // formData.append('file', fileList[0] as RcFile);  
123 - formData.append('subIds', subIds);  
124 - setUploading(true);  
125 - // You can use any AJAX library you like  
126 - const res = await postServiceOrderConfirmReceipt({  
127 - data: formData,  
128 - headers: {  
129 - 'Content-Type':  
130 - 'multipart/form-data; boundary=----WebKitFormBoundarynl6gT1BKdPWIejNq',  
131 - },  
132 - });  
133 -  
134 - if (res.result === RESPONSE_CODE.SUCCESS) {  
135 - message.success(res.message);  
136 - onClose();  
137 - }  
138 -  
139 - setUploading(false);  
140 - };  
141 -  
142 - const props: UploadProps = {  
143 - onRemove: (file) => {  
144 - const index = fileList.indexOf(file);  
145 - const newFileList = fileList.slice();  
146 - newFileList.splice(index, 1);  
147 - setFileList(newFileList);  
148 - },  
149 - beforeUpload: (file) => {  
150 - setFileList([...fileList, file]);  
151 - return false;  
152 - },  
153 - listType: 'picture-card',  
154 - onPreview: handlePreview,  
155 - fileList,  
156 - onChange: handleChange,  
157 - accept: 'image/png, image/jpeg, image/png',  
158 - };  
159 -  
160 - return (  
161 - <>  
162 - <Modal  
163 - width={500}  
164 - open  
165 - title="确认收货"  
166 - footer={[  
167 - <Button key="cancel" onClick={onClose}>  
168 - 取消  
169 - </Button>,  
170 - <Button  
171 - type="primary"  
172 - key="ok"  
173 - onClick={handleUpload}  
174 - disabled={fileList.length === 0}  
175 - loading={uploading}  
176 - >  
177 - {uploading ? '上传中' : '提交'}  
178 - </Button>,  
179 - ]}  
180 - onCancel={async () => {  
181 - onClose();  
182 - }}  
183 - >  
184 - <div className="pt-4 font-semibold">请将买家确认收货的凭证照片上传</div>  
185 - <div className="pb-4 text-xs decoration-gray-50">可复制照片粘贴</div>  
186 - <Upload {...props}>  
187 - {fileList.length < COMFIR_RECEIPT_IMAGES_NUMBER ? uploadButton : ''}  
188 - </Upload>  
189 - </Modal>  
190 - <Modal  
191 - open={previewOpen}  
192 - title={previewTitle}  
193 - footer={null}  
194 - onCancel={handleCancel}  
195 - >  
196 - <img alt="图片预览" style={{ width: '100%' }} src={previewImage} />  
197 - </Modal>  
198 - </>  
199 - );  
200 -};  
src/pages/Order/WarningWhitelist/components/DeliverInfoDrawer.tsx deleted 100644 → 0
1 -import { postDistrictSelOrderProvince } from '@/services';  
2 -import { enumValueToLabel } from '@/utils';  
3 -import { getReceivingCompanyOptions } from '@/utils/order';  
4 -import { Col, Drawer, Row } from 'antd';  
5 -import { useEffect, useState } from 'react';  
6 -import { PAYEE_OPTIONS } from '../../constant';  
7 -  
8 -export default ({ data, onClose }) => {  
9 - const [province, setProvince] = useState('');  
10 - const [city, setCity] = useState('');  
11 - const [district, setDistrict] = useState('');  
12 -  
13 - useEffect(() => {  
14 - const fetchData = async () => {  
15 - if (data.id !== undefined) {  
16 - const resp = await postDistrictSelOrderProvince({  
17 - data: data.id,  
18 - });  
19 - if (resp && resp.data) {  
20 - if (resp.data.province) {  
21 - setProvince(resp.data.province);  
22 - }  
23 - if (resp.data.city) {  
24 - setCity(resp.data.city);  
25 - }  
26 - if (resp.data.district) {  
27 - setDistrict(resp.data.district);  
28 - }  
29 - }  
30 - }  
31 - };  
32 -  
33 - fetchData();  
34 - }, [data.id]);  
35 - return (  
36 - <>  
37 - <Drawer  
38 - width={500}  
39 - title="基本信息"  
40 - placement="right"  
41 - onClose={onClose}  
42 - open  
43 - >  
44 - <Row gutter={[16, 24]}>  
45 - <Col span={6}>  
46 - <span className="text-[#333333]">收货人</span>  
47 - </Col>  
48 - <Col span={18}>{data.customerName}</Col>  
49 - <Col span={6}>  
50 - <span className="className='text-[#333333]'">联系方式</span>  
51 - </Col>  
52 - <Col span={18}>{data.customerContactNumber}</Col>  
53 - <Col span={6}>  
54 - <span className="className='text-[#333333]'">省市区</span>  
55 - </Col>  
56 - <Col span={18}>  
57 - {province}&nbsp;{city}&nbsp;{district}  
58 - </Col>  
59 - <Col span={6}>  
60 - <span className="className='text-[#333333]'">收货地址</span>  
61 - </Col>  
62 - <Col span={18}>{data.customerShippingAddress}</Col>  
63 - <Col span={6}>  
64 - <span className="className='text-[#333333]'">课题组老师</span>  
65 - </Col>  
66 - <Col span={18}>{data.institutionContactName}</Col>  
67 - <Col span={6}>  
68 - <span className="className='text-[#333333]'">单位名称</span>  
69 - </Col>  
70 - <Col span={18}>{data.institution}</Col>  
71 - <Col span={6}>  
72 - <span className="className='text-[#333333]'">开户银行</span>  
73 - </Col>  
74 - <Col span={18}>{data.bank}</Col>  
75 -  
76 - <Col span={6}>  
77 - <span className="className='text-[#333333]'">开票收款单位</span>  
78 - </Col>  
79 - <Col span={18}>  
80 - {enumValueToLabel(  
81 - data.receivingCompany,  
82 - getReceivingCompanyOptions(PAYEE_OPTIONS),  
83 - )}  
84 - </Col>  
85 -  
86 - <Col span={6}>  
87 - <span className="className='text-[#333333]'">银行账号</span>  
88 - </Col>  
89 - <Col span={18}>{data.bankAccountNumber}</Col>  
90 - <Col span={6}>  
91 - <span className="className='text-[#333333]'">开票识别号</span>  
92 - </Col>  
93 - <Col span={18}>{data.invoiceIdentificationNumber}</Col>  
94 - </Row>  
95 - </Drawer>  
96 - </>  
97 - );  
98 -};  
src/pages/Order/WarningWhitelist/components/DeliverModal.tsx deleted 100644 → 0
1 -import { RESPONSE_CODE } from '@/constants/enum';  
2 -import {  
3 - postServiceOrderProcureSend,  
4 - postServiceOrderSendProduct,  
5 - postServiceOrderSupplierSendOrder,  
6 -} from '@/services';  
7 -import { enumToSelect } from '@/utils';  
8 -import {  
9 - ProColumns,  
10 - ProForm,  
11 - ProFormSelect,  
12 - ProFormText,  
13 - ProTable,  
14 -} from '@ant-design/pro-components';  
15 -import {  
16 - Button,  
17 - Col,  
18 - Flex,  
19 - Input,  
20 - InputNumber,  
21 - Modal,  
22 - Row,  
23 - Select,  
24 - message,  
25 -} from 'antd';  
26 -import { cloneDeep } from 'lodash';  
27 -import { useEffect, useRef, useState } from 'react';  
28 -import { CHECK_TYPE, LOGISTICS_STATUS_OPTIONS } from '../../constant';  
29 -  
30 -const DeliverModal = ({  
31 - data: propsData,  
32 - isSendProduct,  
33 - setVisible,  
34 - sendType,  
35 - onClose,  
36 -}) => {  
37 - const [data, setData] = useState(propsData || {});  
38 - const form = useRef();  
39 -  
40 - /**  
41 - * 是供应商发货还是普通发货  
42 - * @param typeString  
43 - * @returns  
44 - */  
45 - function optType(typeString: string) {  
46 - if (sendType === typeString) {  
47 - return true;  
48 - }  
49 -  
50 - return false;  
51 - }  
52 -  
53 - useEffect(() => {  
54 - setData(propsData);  
55 - }, [propsData]);  
56 -  
57 - const handleChange = (key: string, index: number, obj: any) => {  
58 - const newData = cloneDeep(data);  
59 - if (typeof obj !== 'object') {  
60 - newData[index][key] = obj;  
61 - } else {  
62 - newData[index][key] = obj.target?.value;  
63 - }  
64 - setData(newData);  
65 - };  
66 - const columns: ProColumns<any>[] = [  
67 - {  
68 - title: 'ID',  
69 - dataIndex: 'id',  
70 - width: 120,  
71 - render: (_, record) => <Input value={record.id} disabled />,  
72 - },  
73 - {  
74 - title: '商品编号',  
75 - dataIndex: 'productCode',  
76 - width: 120,  
77 - render: (_, record) => <Input value={record.productCode} disabled />,  
78 - },  
79 - {  
80 - title: '商品名称',  
81 - dataIndex: 'productName',  
82 - width: 120,  
83 - render: (_, record) => <Input value={record.productName} disabled />,  
84 - },  
85 - {  
86 - title: '商品参数',  
87 - dataIndex: 'parameters',  
88 - width: 80,  
89 - render: (_, record) => <Input value={record.parameters} disabled />,  
90 - },  
91 - {  
92 - title: '商品数量',  
93 - dataIndex: 'status',  
94 - render: (_, record) => <InputNumber value={record.quantity} disabled />,  
95 - },  
96 - {  
97 - title: '包裹数量',  
98 - dataIndex: 'packageNumber',  
99 - render: (_, record, index) => (  
100 - <InputNumber  
101 - min={1}  
102 - value={record.packageNumber}  
103 - defaultValue={1}  
104 - onChange={(value) => handleChange('packageNumber', index, value)}  
105 - />  
106 - ),  
107 - },  
108 - {  
109 - title: '物流方式',  
110 - key: 'logisticsMethod',  
111 - render: (_, record, index) => (  
112 - <Select  
113 - style={{ minWidth: 150 }}  
114 - placeholder="请输入物流方式"  
115 - value={record.logisticsMethod}  
116 - options={enumToSelect(LOGISTICS_STATUS_OPTIONS)}  
117 - onChange={(value) => {  
118 - handleChange('logisticsMethod', index, value); //修改时更改record数据  
119 - if (value === 'OTHER_LOGISTICS') {  
120 - message.info(  
121 - '您选择的是[其他物流方式],请将该物流方式写在备注中',  
122 - );  
123 - }  
124 - }}  
125 - />  
126 - ),  
127 - },  
128 - {  
129 - title: '物流单号',  
130 - key: 'serialNumber',  
131 - render: (_, record, index) => (  
132 - <Input  
133 - placeholder="请输入物流单号"  
134 - value={record.serialNumber}  
135 - onChange={(value) => {  
136 - handleChange('serialNumber', index, value);  
137 - }}  
138 - />  
139 - ),  
140 - },  
141 - {  
142 - title: '物流备注',  
143 - dataIndex: 'packageNumber',  
144 - render: (_, record, index) => (  
145 - <Input.TextArea  
146 - value={record.logisticsNotes}  
147 - onChange={(value) => handleChange('logisticsNotes', index, value)}  
148 - />  
149 - ),  
150 - },  
151 - ];  
152 -  
153 - return (  
154 - <Modal  
155 - open  
156 - width={1000}  
157 - title={isSendProduct ? '发货' : '修改发货信息'}  
158 - onOk={async () => {  
159 - //请求体封装  
160 - let list = data.map((item) => {  
161 - return {  
162 - id: item.id,  
163 - logisticsMethod: item.logisticsMethod,  
164 - serialNumber: item.serialNumber,  
165 - packageNumber:  
166 - item.packageNumber === null || item.packageNumber === undefined  
167 - ? 1  
168 - : item.packageNumber,  
169 - logisticsNotes: item.logisticsNotes,  
170 - };  
171 - });  
172 -  
173 - for (let item of list) {  
174 - let method = item.logisticsMethod;  
175 - let notes = item.logisticsNotes;  
176 - if (  
177 - method === 'OTHER_LOGISTICS' &&  
178 - (notes === '' || notes === undefined)  
179 - ) {  
180 - message.error(  
181 - '请检查:物流方式为[其他物流方式]的记录中,物流备注不能为空!请将实际的物流方式填写在备注中!',  
182 - );  
183 - return;  
184 - }  
185 - }  
186 - let body = { id: data[0].mainOrderId, list: list, flag: false };  
187 - if (isSendProduct) {  
188 - body.flag = true;  
189 - }  
190 - //发货请求  
191 - let res;  
192 - if (optType(CHECK_TYPE.SUPPLIER)) {  
193 - res = await postServiceOrderSupplierSendOrder({ data: body });  
194 - } else if (optType(CHECK_TYPE.PROCURE)) {  
195 - res = await postServiceOrderProcureSend({ data: body });  
196 - } else {  
197 - res = await postServiceOrderSendProduct({ data: body });  
198 - }  
199 -  
200 - if (res.result === RESPONSE_CODE.SUCCESS) {  
201 - message.success(res.message);  
202 - onClose();  
203 - }  
204 - }}  
205 - onCancel={() => {  
206 - setVisible(false);  
207 - }}  
208 - footer={[  
209 - <Button  
210 - key="back"  
211 - onClick={() => {  
212 - setVisible(false);  
213 - }}  
214 - >  
215 - 取消  
216 - </Button>,  
217 - <Button  
218 - key="selfDeliver"  
219 - type="primary"  
220 - onClick={async () => {  
221 - //请求体封装  
222 - let list = data.map((item) => {  
223 - return {  
224 - id: item.id,  
225 - deliverType: 'SELF_DELIVER',  
226 - };  
227 - });  
228 -  
229 - let body = { id: data[0].mainOrderId, list: list, flag: false };  
230 - if (isSendProduct) {  
231 - body.flag = true;  
232 - }  
233 - //发货请求  
234 - let res;  
235 - if (optType(CHECK_TYPE.SUPPLIER)) {  
236 - res = await postServiceOrderSupplierSendOrder({ data: body });  
237 - } else if (optType(CHECK_TYPE.PROCURE)) {  
238 - res = await postServiceOrderProcureSend({ data: body });  
239 - } else {  
240 - res = await postServiceOrderSendProduct({ data: body });  
241 - }  
242 -  
243 - if (res.result === RESPONSE_CODE.SUCCESS) {  
244 - message.success(res.message);  
245 - onClose();  
246 - }  
247 - }}  
248 - >  
249 - 自行派送  
250 - </Button>,  
251 - <Button  
252 - key="submit"  
253 - type="primary"  
254 - onClick={async () => {  
255 - //请求体封装  
256 - let list = data.map((item) => {  
257 - return {  
258 - id: item.id,  
259 - logisticsMethod: item.logisticsMethod,  
260 - serialNumber: item.serialNumber,  
261 - packageNumber:  
262 - item.packageNumber === null ||  
263 - item.packageNumber === undefined  
264 - ? 1  
265 - : item.packageNumber,  
266 - logisticsNotes: item.logisticsNotes,  
267 - };  
268 - });  
269 -  
270 - for (let item of list) {  
271 - let method = item.logisticsMethod;  
272 - let notes = item.logisticsNotes;  
273 - if (  
274 - method === 'OTHER_LOGISTICS' &&  
275 - (notes === '' || notes === undefined)  
276 - ) {  
277 - message.error(  
278 - '请检查:物流方式为[其他物流方式]的记录中,物流备注不能为空!请将实际的物流方式填写在备注中!',  
279 - );  
280 - return;  
281 - }  
282 - }  
283 - let body = { id: data[0].mainOrderId, list: list, flag: false };  
284 - if (isSendProduct) {  
285 - body.flag = true;  
286 - }  
287 - //发货请求  
288 - let res;  
289 - if (optType(CHECK_TYPE.SUPPLIER)) {  
290 - res = await postServiceOrderSupplierSendOrder({ data: body });  
291 - } else if (optType(CHECK_TYPE.PROCURE)) {  
292 - res = await postServiceOrderProcureSend({ data: body });  
293 - } else {  
294 - res = await postServiceOrderSendProduct({ data: body });  
295 - }  
296 -  
297 - if (res.result === RESPONSE_CODE.SUCCESS) {  
298 - message.success(res.message);  
299 - onClose();  
300 - }  
301 - }}  
302 - >  
303 - 确认  
304 - </Button>,  
305 - ]}  
306 - >  
307 - <Flex vertical>  
308 - <strong>将物流方式和物流单号更新到下方所有订单</strong>  
309 - <span className="text-[red] py-1">  
310 - 选择【其他物流方式】时,需要将对应的物流方式填写在备注中。例如:如果发圆通快递,系统上没有这个选项,就需要选【其他物流方式】,然后把“圆通快递”填在备注上。  
311 - </span>  
312 - </Flex>  
313 -  
314 - <ProForm  
315 - layout="inline"  
316 - submitter={false}  
317 - className="mb-8"  
318 - formRef={form}  
319 - >  
320 - <Row gutter={[0, 6]}>  
321 - <Col>  
322 - <ProFormSelect  
323 - placeholder="请输入物流方式"  
324 - name="logisticsMethod"  
325 - width="sm"  
326 - label="物流方式"  
327 - options={enumToSelect(LOGISTICS_STATUS_OPTIONS)}  
328 - />  
329 - <ProFormText name="logisticsNotes" label="物流备注"></ProFormText>  
330 - </Col>  
331 - <Col>  
332 - <ProFormText name="serialNumber" label="物流单号"></ProFormText>  
333 - </Col>  
334 - </Row>  
335 -  
336 - <Button  
337 - type="primary"  
338 - onClick={() => {  
339 - const values = form.current.getFieldsValue();  
340 - if (values.logisticsMethod === 'OTHER_LOGISTICS') {  
341 - message.info(  
342 - '自动填充成功!您选择的是其他物流方式,请将物流方式写在物流备注中!',  
343 - );  
344 - }  
345 - let newData = cloneDeep(data);  
346 - newData = newData.map((item) => ({  
347 - ...item,  
348 - logisticsMethod: values.logisticsMethod,  
349 - serialNumber: values.serialNumber,  
350 - logisticsNotes: values.logisticsNotes,  
351 - }));  
352 - setData(newData);  
353 - }}  
354 - >  
355 - 批量更新  
356 - </Button>  
357 - </ProForm>  
358 - <ProTable<any>  
359 - className="px-0"  
360 - dataSource={data}  
361 - rowKey="id"  
362 - pagination={false}  
363 - columns={columns}  
364 - search={false}  
365 - dateFormatter="string"  
366 - options={false}  
367 - scroll={{ x: 1400 }}  
368 - />  
369 - </Modal>  
370 - );  
371 -};  
372 -  
373 -export default DeliverModal;  
src/pages/Order/WarningWhitelist/components/FinancialDrawer.tsx deleted 100644 → 0
1 -import { RESPONSE_CODE } from '@/constants/enum';  
2 -import {  
3 - postServiceOrderEditOrder,  
4 - postServiceOrderInvoicing,  
5 -} from '@/services';  
6 -import { FloatAdd, enumToSelect, enumValueToLabel } from '@/utils';  
7 -import { getReceivingCompanyOptions } from '@/utils/order';  
8 -import {  
9 - DrawerForm,  
10 - ProFormDatePicker,  
11 - ProFormDigit,  
12 - ProFormSelect,  
13 - ProFormText,  
14 - ProFormTextArea,  
15 -} from '@ant-design/pro-components';  
16 -import { Button, Form, message } from 'antd';  
17 -import { useEffect, useState } from 'react';  
18 -import { INVOCING_STATUS_OPTIONS_OLD, PAYEE_OPTIONS } from '../../constant';  
19 -  
20 -export default ({  
21 - mainOrder,  
22 - subOrders,  
23 - isEdit,  
24 - isMainOrder,  
25 - cancel,  
26 - onClose,  
27 -}) => {  
28 - const [invoicingStatus, setInvoicingStatus] = useState('');  
29 - const subIds = subOrders.map((item) => item.id);  
30 - useEffect(() => {  
31 - // 在组件挂载或数据变化时,更新组件状态  
32 - if (mainOrder) {  
33 - setInvoicingStatus(subOrders[0]?.invoicingStatus);  
34 - }  
35 - }, [mainOrder]);  
36 - useEffect(() => {  
37 - console.log(JSON.stringify(subOrders));  
38 - }, []);  
39 -  
40 - const [form] = Form.useForm<{ name: string; company: string }>();  
41 -  
42 - /**  
43 - * 自动选择收款公司  
44 - * @param receivingCompany  
45 - */  
46 - function chooseReceivingCompany(receivingCompany: any) {  
47 - form.setFieldValue('payee', receivingCompany);  
48 - }  
49 -  
50 - /**  
51 - * 计算选中子订单的主订单金额之和  
52 - */  
53 - function computeTotalPayment() {  
54 - let distinctMap = new Map();  
55 -  
56 - subOrders?.forEach((item: any) => {  
57 - distinctMap.set(item.mainOrderId, item.totalPayment);  
58 - });  
59 -  
60 - let sum = 0;  
61 - for (let p of distinctMap.values()) {  
62 - sum = FloatAdd(p, sum);  
63 - }  
64 -  
65 - form.setFieldValue('money', sum);  
66 - }  
67 -  
68 - return (  
69 - <DrawerForm<{  
70 - name: string;  
71 - company: string;  
72 - }>  
73 - open  
74 - title="财务信息"  
75 - resize={{  
76 - onResize() {  
77 - console.log('resize!');  
78 - },  
79 - maxWidth: window.innerWidth * 0.8,  
80 - minWidth: 400,  
81 - }}  
82 - initialValues={mainOrder}  
83 - form={form}  
84 - autoFocusFirstInput  
85 - drawerProps={{  
86 - destroyOnClose: true,  
87 - }}  
88 - submitTimeout={2000}  
89 - onFinish={async (values) => {  
90 - let res;  
91 - let body = values;  
92 - body.subIds = subIds;  
93 - if (isEdit) {  
94 - res = await postServiceOrderEditOrder({ data: body });  
95 - } else {  
96 - res = await postServiceOrderInvoicing({ data: body });  
97 - }  
98 - if (res.result === RESPONSE_CODE.SUCCESS) {  
99 - message.success(res.message);  
100 - onClose();  
101 - }  
102 - }}  
103 - onOpenChange={(val) => {  
104 - return !val && cancel();  
105 - }}  
106 - >  
107 - {isMainOrder ? (  
108 - <ProFormSelect  
109 - placeholder="选择是否需要开票"  
110 - name="invoicingStatus"  
111 - width="lg"  
112 - label="是否需要开票"  
113 - options={enumToSelect(INVOCING_STATUS_OPTIONS_OLD)}  
114 - onChange={setInvoicingStatus}  
115 - initialValue={subOrders[0]?.invoicingStatus}  
116 - // disabled={mainInfoDisbled}  
117 - rules={[{ required: true, message: '是否需要开票必填' }]}  
118 - />  
119 - ) : (  
120 - ''  
121 - )}  
122 -  
123 - <ProFormTextArea  
124 - width="lg"  
125 - name="invoiceIdentificationNumber"  
126 - label="开票信息"  
127 - placeholder="请输入开票信息"  
128 - disabled  
129 - />  
130 - <ProFormText  
131 - width="lg"  
132 - name="bank"  
133 - label="开户银行"  
134 - placeholder="请输入开户银行"  
135 - disabled  
136 - />  
137 - <ProFormText  
138 - width="lg"  
139 - name="bankAccountNumber"  
140 - label="开户银行账号"  
141 - placeholder="请输入开户银行账号"  
142 - disabled  
143 - />  
144 -  
145 - {invoicingStatus !== 'UN_INVOICE'  
146 - ? [  
147 - <ProFormDatePicker  
148 - key="invoicingTime"  
149 - width="lg"  
150 - name="invoicingTime"  
151 - label="开票时间"  
152 - disabled={isEdit}  
153 - rules={[  
154 - { required: !isEdit ? true : false, message: '这是必填项' },  
155 - ]}  
156 - initialValue={subOrders[0]?.invoicingTime}  
157 - />,  
158 - <ProFormText  
159 - key="purchaser"  
160 - width="lg"  
161 - name="purchaser"  
162 - label="抬头名称"  
163 - disabled={isEdit}  
164 - rules={[  
165 - { required: !isEdit ? true : false, message: '这是必填项' },  
166 - ]}  
167 - initialValue={subOrders[0]?.purchaser}  
168 - />,  
169 - <ProFormDatePicker  
170 - key="financialReceiptIssuanceTime"  
171 - width="lg"  
172 - name="financialReceiptIssuanceTime"  
173 - label="开收据时间"  
174 - initialValue={subOrders[0]?.financialReceiptIssuanceTime}  
175 - />,  
176 - <ProFormDatePicker  
177 - key="collectMoneyTime"  
178 - width="lg"  
179 - name="collectMoneyTime"  
180 - label="收款时间"  
181 - initialValue={subOrders[0]?.collectMoneyTime}  
182 - />,  
183 - <ProFormText  
184 - width="lg"  
185 - key="invoiceNumber"  
186 - name="invoiceNumber"  
187 - label="发票号码"  
188 - initialValue={subOrders[0]?.invoiceNumber}  
189 - rules={[{ required: true, message: '发票号码必填' }]}  
190 - />,  
191 - <div  
192 - key="salesChooseReceivingCompany"  
193 - hidden={subOrders[0].receivingCompany === null}  
194 - >  
195 - <span className={'pl-2 text-xs text-gray-400'}>  
196 - 销售申请开票时选择了:  
197 - {enumValueToLabel(  
198 - subOrders[0].receivingCompany,  
199 - getReceivingCompanyOptions(PAYEE_OPTIONS),  
200 - )}  
201 - </span>  
202 - <span  
203 - hidden={subOrders[0].receivingCompany === 'ANY'}  
204 - className={  
205 - 'pl-2 text-xs text-[#1677ff] cursor-pointer hover:text-[#64abf7]'  
206 - }  
207 - onClick={() => {  
208 - chooseReceivingCompany(subOrders[0].receivingCompany);  
209 - }}  
210 - >  
211 - 选择  
212 - </span>  
213 - </div>,  
214 - <ProFormSelect  
215 - key="payee"  
216 - placeholder="选择收款单位"  
217 - name="payee"  
218 - width="lg"  
219 - showSearch  
220 - label="收款单位"  
221 - options={enumToSelect(PAYEE_OPTIONS)}  
222 - initialValue={subOrders[0]?.payee}  
223 - rules={[{ required: true, message: '收款单位必填' }]}  
224 - />,  
225 -  
226 - <div id="total-payment" key="money">  
227 - <ProFormDigit  
228 - key="money"  
229 - name="money"  
230 - width="lg"  
231 - label="金额"  
232 - rules={[{ required: true, message: '金额必填' }]}  
233 - tooltip="点击计算,合计所有子订单对应主订单总额"  
234 - fieldProps={{  
235 - addonAfter: (  
236 - <Button  
237 - className="rounded-l-none"  
238 - type="primary"  
239 - onClick={computeTotalPayment}  
240 - >  
241 - 计算  
242 - </Button>  
243 - ),  
244 - }}  
245 - />  
246 - </div>,  
247 - ]  
248 - : ''}  
249 -  
250 - <ProFormSelect  
251 - placeholder="是否完全开票"  
252 - name="afterInvoicingStatus"  
253 - width="lg"  
254 - label="是否完全开票"  
255 - options={[  
256 - { label: '完全开票', value: 'COMPLETE_INVOICING' },  
257 - { label: '部分开票', value: 'PARTIAL_INVOICING' },  
258 - ]}  
259 - // disabled={mainInfoDisbled}  
260 - initialValue={  
261 - subOrders[0]?.afterInvoicingStatus === 'APPLY_FOR_INVOICING'  
262 - ? 'COMPLETE_INVOICING'  
263 - : subOrders[0]?.afterInvoicingStatus  
264 - }  
265 - rules={[{ required: true, message: '是否完全开票必填' }]}  
266 - />  
267 - <ProFormTextArea  
268 - width="lg"  
269 - name="invoicingNotes"  
270 - label="备注"  
271 - initialValue={subOrders[0]?.invoicingNotes}  
272 - />  
273 - </DrawerForm>  
274 - );  
275 -};  
src/pages/Order/WarningWhitelist/components/FinancialEditDrawer.tsx deleted 100644 → 0
1 -import { RESPONSE_CODE } from '@/constants/enum';  
2 -import { postServiceOrderNoNeedInvoicingEdit } from '@/services';  
3 -import { enumToSelect } from '@/utils';  
4 -import {  
5 - DrawerForm,  
6 - ProFormDatePicker,  
7 - ProFormSelect,  
8 - ProFormText,  
9 -} from '@ant-design/pro-components';  
10 -import { Form, message } from 'antd';  
11 -import { useEffect, useState } from 'react';  
12 -import { INVOCING_STATUS_OPTIONS_OLD } from '../../constant';  
13 -  
14 -export default ({ mainOrder, subOrders, setVisible, isMainOrder, onClose }) => {  
15 - const [invoicingStatus, setInvoicingStatus] = useState('');  
16 - useEffect(() => {  
17 - setInvoicingStatus(subOrders[0]?.invoicingStatus);  
18 - }, []);  
19 - const subOrderIds = subOrders?.map((subOrder) => {  
20 - return subOrder?.id;  
21 - });  
22 - const mainOrderId = mainOrder.id;  
23 - const [form] = Form.useForm<{  
24 - collectMoneyTime: string;  
25 - subIds: [];  
26 - financialReceiptIssuanceTime: string;  
27 - }>();  
28 -  
29 - //回显开收据时间和收款时间  
30 - if (!isMainOrder) {  
31 - form.setFieldValue('collectMoneyTime', subOrders[0].collectMoneyTime);  
32 - form.setFieldValue(  
33 - 'financialReceiptIssuanceTime',  
34 - subOrders[0].financialReceiptIssuanceTime,  
35 - );  
36 - }  
37 -  
38 - return (  
39 - <DrawerForm<{  
40 - collectMoneyTime: string;  
41 - financialReceiptIssuanceTime: string;  
42 - subIds: [];  
43 - }>  
44 - open  
45 - title={isMainOrder ? '编辑开票信息' : '编辑收款时间'}  
46 - resize={{  
47 - onResize() {  
48 - console.log('resize!');  
49 - },  
50 - maxWidth: window.innerWidth * 0.8,  
51 - minWidth: 400,  
52 - }}  
53 - initialValues={mainOrder}  
54 - form={form}  
55 - autoFocusFirstInput  
56 - drawerProps={{  
57 - destroyOnClose: true,  
58 - }}  
59 - submitTimeout={2000}  
60 - onFinish={async (values) => {  
61 - let body = {  
62 - ...values,  
63 - mainOrderId: mainOrderId,  
64 - subIds: subOrderIds,  
65 - };  
66 -  
67 - if (!isMainOrder) {  
68 - body.invoicingStatus = 'UN_INVOICE';  
69 - }  
70 -  
71 - let res = await postServiceOrderNoNeedInvoicingEdit({  
72 - data: body,  
73 - });  
74 - if (res.result === RESPONSE_CODE.SUCCESS) {  
75 - message.success(res.message);  
76 - onClose();  
77 - }  
78 - }}  
79 - onOpenChange={(val) => {  
80 - return !val && setVisible(val);  
81 - }}  
82 - >  
83 - {isMainOrder ? (  
84 - <ProFormSelect  
85 - placeholder="选择是否需要开票"  
86 - name="invoicingStatus"  
87 - width="lg"  
88 - label="是否需要开票"  
89 - options={enumToSelect(INVOCING_STATUS_OPTIONS_OLD)}  
90 - onChange={setInvoicingStatus}  
91 - initialValue={subOrders[0]?.invoicingStatus}  
92 - // disabled={mainInfoDisbled}  
93 - rules={[{ required: true, message: '是否需要开票必填' }]}  
94 - />  
95 - ) : (  
96 - ''  
97 - )}  
98 -  
99 - {invoicingStatus !== 'UN_INVOICE' ? (  
100 - <>  
101 - <ProFormText  
102 - key="invoiceIdentificationNumber"  
103 - width="lg"  
104 - name="invoiceIdentificationNumber"  
105 - label="开票信息"  
106 - placeholder="请输入开票信息"  
107 - rules={[{ required: true, message: '开票信息必填' }]}  
108 - />  
109 - <ProFormText  
110 - key="bank"  
111 - width="lg"  
112 - name="bank"  
113 - label="开户银行"  
114 - placeholder="请输入开户银行"  
115 - />  
116 - <ProFormText  
117 - key="bankAccountNumber"  
118 - width="lg"  
119 - name="bankAccountNumber"  
120 - label="开户银行账号"  
121 - placeholder="请输入开户银行账号"  
122 - />  
123 - </>  
124 - ) : (  
125 - ''  
126 - )}  
127 -  
128 - <ProFormDatePicker  
129 - key="financialReceiptIssuanceTime"  
130 - width="lg"  
131 - name="financialReceiptIssuanceTime"  
132 - label="开收据时间"  
133 - // rules={[  
134 - // {  
135 - // required: !isMainOrder && invoicingStatus === 'UN_INVOICE',  
136 - // message: '开收据时间必填',  
137 - // },  
138 - // ]}  
139 - />  
140 - <ProFormDatePicker  
141 - key="collectMoneyTime"  
142 - width="lg"  
143 - name="collectMoneyTime"  
144 - label="收款时间"  
145 - // rules={[  
146 - // {  
147 - // required: !isMainOrder && invoicingStatus === 'UN_INVOICE',  
148 - // message: '收款时间必填',  
149 - // },  
150 - // ]}  
151 - />  
152 - </DrawerForm>  
153 - );  
154 -};  
src/pages/Order/WarningWhitelist/components/FinancialMergeDrawer.tsx deleted 100644 → 0
1 -import { RESPONSE_CODE } from '@/constants/enum';  
2 -import { enumToSelect } from '@/utils';  
3 -import {  
4 - DrawerForm,  
5 - ProFormDatePicker,  
6 - ProFormDigit,  
7 - ProFormSelect,  
8 - ProFormText,  
9 - ProFormTextArea,  
10 -} from '@ant-design/pro-components';  
11 -import { Form, message } from 'antd';  
12 -import { PAYEE_OPTIONS } from '../../constant';  
13 -  
14 -export default ({ dataList, setVisible, onClose }) => {  
15 - // let subOrderIds = dataList?.map((item) => {  
16 - // return item.id;  
17 - // });  
18 - let firstMainOrder = dataList[0];  
19 - let bank = firstMainOrder?.bank;  
20 - let bankAccountNumber = firstMainOrder?.bankAccountNumber;  
21 - let invoiceIdentificationNumber = firstMainOrder?.invoiceIdentificationNumber;  
22 -  
23 - const [form] = Form.useForm<{  
24 - invoicingTime: string;  
25 - financialReceiptIssuanceTime: string;  
26 - invoicingNotes: string;  
27 - afterInvoicingStatus: string;  
28 - collectMoneyTime: string;  
29 - }>();  
30 - return (  
31 - <DrawerForm  
32 - open  
33 - title="合并开票"  
34 - resize={{  
35 - onResize() {  
36 - console.log('resize!');  
37 - },  
38 - maxWidth: window.innerWidth * 0.8,  
39 - minWidth: 400,  
40 - }}  
41 - form={form}  
42 - autoFocusFirstInput  
43 - drawerProps={{  
44 - destroyOnClose: true,  
45 - }}  
46 - submitTimeout={2000}  
47 - onFinish={async (values) => {  
48 - console.log(values);  
49 - let res;  
50 - let body = values;  
51 - body.subIds = subIds;  
52 - body.mainOrderId = mainOrder.id;  
53 - body.mainorderOrSubOrderInvoicing = isMainOrder;  
54 - if (isEdit) {  
55 - res = await postServiceOrderEditOrder({ data: body });  
56 - } else {  
57 - res = await postServiceOrderInvoicing({ data: body });  
58 - }  
59 - if (res.result === RESPONSE_CODE.SUCCESS) {  
60 - message.success(res.message);  
61 - onClose();  
62 - }  
63 - }}  
64 - onOpenChange={(val) => {  
65 - return !val && setVisible();  
66 - }}  
67 - >  
68 - <ProFormText  
69 - width="lg"  
70 - name="invoiceIdentificationNumber"  
71 - label="开票信息"  
72 - placeholder="请输入开票信息"  
73 - initialValue={invoiceIdentificationNumber}  
74 - disabled  
75 - />  
76 - <ProFormText  
77 - width="lg"  
78 - name="bank"  
79 - label="开户银行"  
80 - placeholder="请输入开户银行"  
81 - initialValue={bank}  
82 - disabled  
83 - />  
84 - <ProFormText  
85 - width="lg"  
86 - name="bankAccountNumber"  
87 - label="开户银行账号"  
88 - placeholder="请输入开户银行账号"  
89 - initialValue={bankAccountNumber}  
90 - disabled  
91 - />  
92 -  
93 - <ProFormDatePicker  
94 - key="invoicingTime"  
95 - width="lg"  
96 - name="invoicingTime"  
97 - label="开票时间"  
98 - rules={[{ required: true, message: '这是必填项' }]}  
99 - />  
100 - <ProFormDatePicker  
101 - key="financialReceiptIssuanceTime"  
102 - width="lg"  
103 - name="financialReceiptIssuanceTime"  
104 - label="开收据时间"  
105 - />  
106 - <ProFormDatePicker  
107 - key="collectMoneyTime"  
108 - width="lg"  
109 - name="collectMoneyTime"  
110 - label="收款时间"  
111 - />  
112 - <ProFormText  
113 - width="lg"  
114 - key="invoiceNumber"  
115 - name="invoiceNumber"  
116 - label="发票号码"  
117 - rules={[{ required: true, message: '发票号码必填' }]}  
118 - />  
119 - <ProFormSelect  
120 - key="payee"  
121 - placeholder="选择收款单位"  
122 - name="payee"  
123 - width="lg"  
124 - label="收款单位"  
125 - options={enumToSelect(PAYEE_OPTIONS)}  
126 - rules={[{ required: true, message: '收款单位必填' }]}  
127 - />  
128 -  
129 - <ProFormDigit  
130 - key="money"  
131 - name="money"  
132 - width="lg"  
133 - label="金额"  
134 - rules={[{ required: true, message: '金额必填' }]}  
135 - />  
136 - <ProFormSelect  
137 - placeholder="是否完全开票"  
138 - name="afterInvoicingStatus"  
139 - width="lg"  
140 - label="是否完全开票"  
141 - options={[  
142 - { label: '完全开票', value: 'COMPLETE_INVOICING' },  
143 - { label: '部分开票', value: 'PARTIAL_INVOICING' },  
144 - ]}  
145 - initialValue={'COMPLETE_INVOICING'}  
146 - />  
147 - <ProFormTextArea width="lg" name="invoicingNotes" label="备注" />  
148 - </DrawerForm>  
149 - );  
150 -};  
src/pages/Order/WarningWhitelist/components/FinancialReceiptsModal.tsx deleted 100644 → 0
1 -import { postServiceOrderUpdateHirePurchase } from '@/services';  
2 -import {  
3 - EditableProTable,  
4 - ModalForm,  
5 - ProColumns,  
6 - ProForm,  
7 -} from '@ant-design/pro-components';  
8 -import { Form } from 'antd';  
9 -import { useState } from 'react';  
10 -  
11 -// import { cloneDeep } from 'lodash';  
12 -export default ({ setVisible, datas, onClose }) => {  
13 - const [form] = Form.useForm<{ name: string; company: string }>();  
14 - type DataSourceType = {  
15 - id: React.Key;  
16 - hirePurchaseMethod?: string;  
17 - hirePurchaseMethodName?: string;  
18 - money?: number;  
19 - updateTime?: string;  
20 - notes?: string;  
21 - };  
22 - const defaultData: DataSourceType[] = [  
23 - {  
24 - id: 1,  
25 - hirePurchaseMethod: 'ADVANCE_CHARGE',  
26 - hirePurchaseMethodName: '预付款',  
27 - money: undefined,  
28 - updateTime: undefined,  
29 - notes: undefined,  
30 - },  
31 - {  
32 - id: 2,  
33 - hirePurchaseMethod: 'PAYMENT_FOR_SHIPMENT',  
34 - hirePurchaseMethodName: '发货款',  
35 - money: undefined,  
36 - updateTime: undefined,  
37 - notes: undefined,  
38 - },  
39 - {  
40 - id: 3,  
41 - hirePurchaseMethod: 'ACCEPTANCE_PAYMENT',  
42 - hirePurchaseMethodName: '验收款',  
43 - money: undefined,  
44 - updateTime: undefined,  
45 - notes: undefined,  
46 - },  
47 - {  
48 - id: 4,  
49 - hirePurchaseMethod: 'BALANCE_PAYMENT',  
50 - hirePurchaseMethodName: '尾款',  
51 - money: undefined,  
52 - updateTime: undefined,  
53 - notes: undefined,  
54 - },  
55 - ];  
56 - const [editableKeys, setEditableRowKeys] = useState<React.Key[]>(() =>  
57 - // defaultData.map((item) => item.id),  
58 - [1, 2, 3, 4],  
59 - );  
60 - const columns: ProColumns<DataSourceType>[] = [  
61 - {  
62 - title: '款项',  
63 - dataIndex: 'hirePurchaseMethodName',  
64 - editable: false,  
65 - width: '10%',  
66 - },  
67 - {  
68 - title: '已收金额',  
69 - dataIndex: 'money',  
70 - valueType: 'digit',  
71 - width: '15%',  
72 - },  
73 - {  
74 - title: '收款时间',  
75 - dataIndex: 'updateTime',  
76 - valueType: 'dateTime',  
77 - width: '25%',  
78 - },  
79 - {  
80 - title: '备注',  
81 - dataIndex: 'receiptsNotes',  
82 - },  
83 - ];  
84 - return (  
85 - <>  
86 - <ModalForm<{  
87 - name: string;  
88 - company: string;  
89 - }>  
90 - width={1100}  
91 - open  
92 - title="收款记录"  
93 - form={form}  
94 - autoFocusFirstInput  
95 - modalProps={{  
96 - okText: '保存',  
97 - cancelText: '取消',  
98 - destroyOnClose: true,  
99 - onCancel: () => {  
100 - setVisible(false);  
101 - },  
102 - }}  
103 - onFinish={async (values) => {  
104 - let res = await postServiceOrderUpdateHirePurchase({  
105 - data: {  
106 - mainOrderId: datas[0].id,  
107 - list: values.dataSource,  
108 - },  
109 - });  
110 - console.log(res);  
111 - onClose();  
112 - }}  
113 - onOpenChange={setVisible}  
114 - >  
115 - <ProForm.Item  
116 - label=""  
117 - name="dataSource"  
118 - initialValue={defaultData}  
119 - trigger="onValuesChange"  
120 - >  
121 - <EditableProTable<DataSourceType>  
122 - rowKey="id"  
123 - toolBarRender={false}  
124 - columns={columns}  
125 - recordCreatorProps={{  
126 - newRecordType: 'dataSource',  
127 - position: 'top',  
128 - record: () => ({  
129 - id: Date.now(),  
130 - addonBefore: 'ccccccc',  
131 - decs: 'testdesc',  
132 - }),  
133 - style: {  
134 - display: 'none',  
135 - },  
136 - }}  
137 - editable={{  
138 - type: 'multiple',  
139 - editableKeys,  
140 - onChange: setEditableRowKeys,  
141 - actionRender: (row, _, dom) => {  
142 - return [dom.delete];  
143 - },  
144 - }}  
145 - />  
146 - </ProForm.Item>  
147 -  
148 - {/* <ProForm.Group>  
149 - <ProFormText  
150 - width="sm"  
151 - name="name1"  
152 - label="款项"  
153 - tooltip="最长为 24 位"  
154 - initialValue={"预付款"}  
155 - disabled  
156 - placeholder="请输入名称"  
157 - />  
158 -  
159 - <ProFormText  
160 - width="sm"  
161 - name="company"  
162 - label="收款时间"  
163 - placeholder="请输入名称"  
164 - />  
165 -  
166 - <ProFormText  
167 - width="sm"  
168 - name="price"  
169 - label="收款金额"  
170 - placeholder="请输入名称"  
171 - />  
172 -  
173 - <ProFormText  
174 - width="sm"  
175 - name="notes"  
176 - label="备注"  
177 - placeholder="请输入名称"  
178 - />  
179 - </ProForm.Group>  
180 -  
181 - <ProForm.Group>  
182 - <ProFormText  
183 - width="sm"  
184 - name="name2"  
185 - initialValue={"发货款"}  
186 - disabled  
187 - tooltip="最长为 24 位"  
188 - placeholder="请输入名称"  
189 - />  
190 -  
191 - <ProFormText  
192 - width="sm"  
193 - name="company"  
194 - placeholder="请输入名称"  
195 - />  
196 -  
197 - <ProFormText  
198 - width="sm"  
199 - name="price"  
200 - placeholder="请输入名称"  
201 - />  
202 -  
203 - <ProFormText  
204 - width="sm"  
205 - name="notes"  
206 - placeholder="请输入名称"  
207 - />  
208 - </ProForm.Group>  
209 -  
210 - <ProForm.Group>  
211 - <ProFormText  
212 - width="sm"  
213 - name="name3"  
214 - initialValue={"验收款"}  
215 - disabled  
216 - tooltip="最长为 24 位"  
217 - placeholder="请输入名称"  
218 - />  
219 -  
220 - <ProFormText  
221 - width="sm"  
222 - name="company"  
223 - placeholder="请输入名称"  
224 - />  
225 -  
226 - <ProFormText  
227 - width="sm"  
228 - name="price"  
229 - placeholder="请输入名称"  
230 - />  
231 -  
232 - <ProFormText  
233 - width="sm"  
234 - name="notes"  
235 - placeholder="请输入名称"  
236 - />  
237 - </ProForm.Group>  
238 -  
239 - <ProForm.Group>  
240 - <ProFormText  
241 - width="sm"  
242 - name="name4"  
243 - disabled  
244 - initialValue={"尾款"}  
245 - tooltip="最长为 24 位"  
246 - placeholder="请输入名称"  
247 - />  
248 -  
249 - <ProFormText  
250 - width="sm"  
251 - name="company"  
252 - placeholder="请输入名称"  
253 - />  
254 -  
255 - <ProFormText  
256 - width="sm"  
257 - name="price"  
258 - placeholder="请输入名称"  
259 - />  
260 -  
261 - <ProFormText  
262 - width="sm"  
263 - name="notes"  
264 - placeholder="请输入名称"  
265 - />  
266 - </ProForm.Group> */}  
267 - </ModalForm>  
268 - </>  
269 - );  
270 -};  
src/pages/Order/WarningWhitelist/components/HistoryModal.tsx deleted 100644 → 0
1 -import { postServiceOrderQueryHistoryOrderRecord } from '@/services';  
2 -import { formatDateTime } from '@/utils';  
3 -import { Button, Col, Empty, Flex, Modal, Row, Spin } from 'antd';  
4 -import { useEffect, useState } from 'react';  
5 -  
6 -export default ({ subOrders, isCancelledOrder, onClose }) => {  
7 - let subOrderIds = subOrders?.map((subOrder: any) => {  
8 - return subOrder.id;  
9 - });  
10 -  
11 - const [data, setData] = useState([]);  
12 - const [loading, setLoading] = useState(true);  
13 - let i = 0;  
14 -  
15 - const handleOk = () => {  
16 - onClose();  
17 - };  
18 -  
19 - /**  
20 - * 获取历史记录  
21 - */  
22 - const getHistory = async () => {  
23 - let res = await postServiceOrderQueryHistoryOrderRecord({  
24 - data: { ids: subOrderIds, isDeleteQueryOrder: isCancelledOrder },  
25 - });  
26 - setData(res.data);  
27 - setLoading(false);  
28 - };  
29 -  
30 - const getRecord = (history: any) => {  
31 - let record = [];  
32 - record.push(  
33 - <span className="pr-2 text-[#5E5E5E]">  
34 - {formatDateTime(history.createTime)}  
35 - </span>,  
36 - );  
37 -  
38 - record.push(<span className="text-[#3b83e5]">{history.createByName}</span>);  
39 -  
40 - record.push(<span>进行了</span>);  
41 -  
42 - // let label = enumValueToLabel(history.status, ORDER_STATUS_OPTIONS);  
43 -  
44 - // if (  
45 - // history.record !== 'INVOICING' && history.record !== 'order-change-normal' && history.record !== 'order-change-normal-CHECK' &&  
46 - // history.record?.indexOf(':') === -1 &&  
47 - // label !== undefined &&  
48 - // label !== ''  
49 - // ) {  
50 - // record.push(  
51 - // <>  
52 - // <span>,订单状态为:</span>  
53 - // <span className="text-[#3b83e5]">{label}</span>  
54 - // </>,  
55 - // );  
56 - // }  
57 -  
58 - if (history.record?.indexOf(':') !== -1) {  
59 - let values = history.record?.split(':');  
60 - let type = values[0];  
61 - let target = values[1];  
62 - if (target === 'null') {  
63 - target = '未指定';  
64 - }  
65 - //采购转发  
66 - if (type === 'PROCURE_CONVERT_PROCURE') {  
67 - record.push(  
68 - <>  
69 - <span>采购转发,{history.createByName}将订单转发给了</span>  
70 - <span className="text-[#3b83e5]">{target}</span>  
71 - </>,  
72 - );  
73 - }  
74 - } else {  
75 - record.push(  
76 - <span className="text-[#3b83e5]">  
77 - {history.recordText +  
78 - (history.record === 'INVOICING'  
79 - ? '(开票号码:' + history.invoiceNumber + ')'  
80 - : '')}  
81 - </span>,  
82 - );  
83 - }  
84 -  
85 - if (history.notes !== null) {  
86 - record.push(<span className="pl-1">{'备注:' + history.notes}</span>);  
87 - }  
88 -  
89 - if (history.description !== null) {  
90 - record.push(  
91 - <span className="pl-1">{'描述:' + history.description}</span>,  
92 - );  
93 - }  
94 -  
95 - return record;  
96 - };  
97 -  
98 - useEffect(() => {  
99 - getHistory();  
100 - }, []);  
101 -  
102 - const handleCancel = () => {  
103 - onClose();  
104 - };  
105 -  
106 - return (  
107 - <>  
108 - <Modal  
109 - title="订单历史记录"  
110 - open  
111 - width={650}  
112 - onOk={handleOk}  
113 - onCancel={handleCancel}  
114 - footer={() => (  
115 - <>  
116 - <Button onClick={handleCancel}>返回</Button>  
117 - </>  
118 - )}  
119 - >  
120 - <Spin tip="加载中" spinning={loading}>  
121 - <Row className="max-h-[500px] overflow-auto" gutter={[0, 14]}>  
122 - {data.map((item) => {  
123 - return (  
124 - <Col span={24} key={i}>  
125 - <Flex vertical>  
126 - <div>  
127 - <span className="py-2 text-[#5E5E5E]">  
128 - {'商品' + ++i}  
129 - </span>  
130 - <span className="text-[#8C8C8C]">  
131 - -【{item.productName}】  
132 - </span>  
133 - </div>  
134 -  
135 - <Flex vertical>  
136 - {item.historySubOrderRecordDto?.map((history) => {  
137 - return (  
138 - <div className="py-1" key={history.id}>  
139 - {getRecord(history)}  
140 - </div>  
141 - );  
142 - })}  
143 - </Flex>  
144 - </Flex>  
145 - </Col>  
146 - );  
147 - })}  
148 - </Row>  
149 - {data?.length <= 0 ? (  
150 - <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />  
151 - ) : (  
152 - ''  
153 - )}  
154 - </Spin>  
155 - </Modal>  
156 - </>  
157 - );  
158 -};  
src/pages/Order/WarningWhitelist/components/ImagesViewerModal.tsx deleted 100644 → 0
1 -import { postServiceOrderViewImages } from '@/services';  
2 -import { Button, Divider, Image, Modal } from 'antd';  
3 -import { useEffect, useState } from 'react';  
4 -export default ({ setVisible, optType, onClose, orderRow }) => {  
5 - const [images, setImages] = useState<any[]>([]);  
6 - const [title, setTitle] = useState("收货凭证");  
7 - const handleOk = () => {  
8 - onClose();  
9 - setVisible(false);  
10 - };  
11 -  
12 - const handleCancel = () => {  
13 - onClose();  
14 - setVisible(false);  
15 - };  
16 -  
17 - async function getImages() {  
18 - const res = await postServiceOrderViewImages({  
19 - data: { subId: orderRow.id },  
20 - });  
21 - const images = res.data;  
22 - setImages(images);  
23 - }  
24 - useEffect(() => {  
25 - if (optType === 'shippingReceipt') {  
26 - setTitle("收货凭证");  
27 - getImages();  
28 - } else if (optType === 'paymentReceipt') {  
29 - let paymentReceiptsImagesList: any[] = [];  
30 - if (orderRow.paymentReceiptAnnexList) {  
31 - paymentReceiptsImagesList.push(...orderRow.paymentReceiptAnnexList);  
32 - }  
33 - //去重  
34 - paymentReceiptsImagesList = [...new Set(paymentReceiptsImagesList)];  
35 - setImages(paymentReceiptsImagesList);  
36 - }  
37 -  
38 - }, []);  
39 -  
40 - return (  
41 - <>  
42 - <Modal  
43 - title={title}  
44 - open  
45 - onOk={handleOk}  
46 - onCancel={handleCancel}  
47 - footer={[  
48 - <Button key="back" onClick={handleCancel}>  
49 - 返回  
50 - </Button>,  
51 - ]}  
52 - >  
53 - <Image.PreviewGroup  
54 - className="mr-10"  
55 - preview={{  
56 - onChange: (current, prev) =>  
57 - console.log(`current index: ${current}, prev index: ${prev}`),  
58 - }}  
59 - >  
60 - {images.map((url) => (  
61 - <>  
62 - <Image width={120} src={url} /> <Divider type="vertical" />  
63 - </>  
64 - ))}  
65 - </Image.PreviewGroup>  
66 - </Modal>  
67 - </>  
68 - );  
69 -};  
src/pages/Order/WarningWhitelist/components/ImportExpressBillModal.tsx deleted 100644 → 0
1 -import { RESPONSE_CODE } from '@/constants/enum';  
2 -import { postOrderImportImportWeightAndVolume } from '@/services';  
3 -import { ModalForm, ProFormUploadDragger } from '@ant-design/pro-components';  
4 -import { Button, Form, message } from 'antd';  
5 -  
6 -export default () => {  
7 - const [form] = Form.useForm();  
8 - const [messageApi, contextHolder] = message.useMessage();  
9 - return (  
10 - <>  
11 - <ModalForm  
12 - title="导入重量、体积"  
13 - trigger={<Button type="primary">导入重量、体积</Button>}  
14 - form={form}  
15 - autoFocusFirstInput  
16 - modalProps={{  
17 - destroyOnClose: true,  
18 - }}  
19 - submitTimeout={2000}  
20 - onFinish={async (values) => {  
21 - console.log(values);  
22 - const formData = new FormData();  
23 - formData.append('file', values.express[0].originFileObj);  
24 - messageApi.open({  
25 - type: 'loading',  
26 - content: '正在导入...',  
27 - duration: 0,  
28 - });  
29 - const res = await postOrderImportImportWeightAndVolume({  
30 - data: formData,  
31 - headers: {  
32 - 'Content-Type':  
33 - 'multipart/form-data; boundary=----WebKitFormBoundarynl6gT1BKdPWIejNq',  
34 - },  
35 - });  
36 - if (res.result === RESPONSE_CODE.SUCCESS) {  
37 - message.error('导入成功');  
38 - } else {  
39 - message.error('导入失败');  
40 - }  
41 - messageApi.destroy();  
42 - return true;  
43 - }}  
44 - >  
45 - <ProFormUploadDragger max={1} label="上传快递单" name="express" />  
46 - </ModalForm>  
47 - {contextHolder}  
48 - </>  
49 - );  
50 -};  
src/pages/Order/WarningWhitelist/components/ImportModal.tsx deleted 100644 → 0
1 -import { RESPONSE_CODE } from '@/constants/enum';  
2 -import { postServiceOrderImportExcel } from '@/services';  
3 -import { orderExport } from '@/services/order';  
4 -import { UploadOutlined } from '@ant-design/icons';  
5 -import { Button, Modal, Upload, message } from 'antd';  
6 -import { RcFile, UploadFile, UploadProps } from 'antd/es/upload';  
7 -import { useState } from 'react';  
8 -export default ({ onClose }) => {  
9 - // const [form] = Form.useForm<{ name: string; company: string }>();  
10 - const [messageApi, contextHolder] = message.useMessage();  
11 - const [fileList, setFileList] = useState<UploadFile[]>([]);  
12 - const [uploading, setUploading] = useState(false);  
13 - const handleChange: UploadProps['onChange'] = ({ fileList: newFileList }) =>  
14 - setFileList(newFileList);  
15 -  
16 - const exportLoading = (content: string) => {  
17 - messageApi.open({  
18 - type: 'loading',  
19 - content: content,  
20 - duration: 0,  
21 - });  
22 - };  
23 -  
24 - const exportLoadingDestory = () => {  
25 - messageApi.destroy();  
26 - };  
27 - const downloadTemplate = async () => {  
28 - exportLoading('正在下载模板...');  
29 - orderExport(  
30 - '/api/service/order/exportTemplate',  
31 - '订单.xlsx',  
32 - 'post',  
33 - {},  
34 - exportLoadingDestory,  
35 - );  
36 - };  
37 -  
38 - const handleUpload = async () => {  
39 - const formData = new FormData();  
40 - fileList.forEach((file) => {  
41 - //originFileObj二进制文件  
42 - formData.append('file', file.originFileObj as RcFile);  
43 - });  
44 - // console.log(fileList[0] as RcFile)  
45 - // formData.append('file', fileList[0] as RcFile);  
46 - setUploading(true);  
47 - // You can use any AJAX library you like  
48 - const res = await postServiceOrderImportExcel({  
49 - data: formData,  
50 - headers: {  
51 - 'Content-Type':  
52 - 'multipart/form-data; boundary=----WebKitFormBoundarynl6gT1BKdPWIejNq',  
53 - },  
54 - });  
55 -  
56 - if (res.result === RESPONSE_CODE.SUCCESS) {  
57 - message.success(res.message);  
58 - onClose();  
59 - } else {  
60 - if (res.message === '表格中没有数据') {  
61 - setUploading(false);  
62 - return;  
63 - }  
64 - //存在错误信息,下载错误信息模板  
65 - exportLoading('正在下载错误信息...');  
66 - orderExport(  
67 - '/api/service/order/errorExcelInformation',  
68 - '订单.xlsx',  
69 - 'post',  
70 - formData,  
71 - exportLoadingDestory,  
72 - );  
73 - }  
74 -  
75 - setUploading(false);  
76 - };  
77 -  
78 - const props: UploadProps = {  
79 - onRemove: (file) => {  
80 - const index = fileList.indexOf(file);  
81 - const newFileList = fileList.slice();  
82 - newFileList.splice(index, 1);  
83 - setFileList(newFileList);  
84 - },  
85 - beforeUpload: (file) => {  
86 - setFileList([...fileList, file]);  
87 -  
88 - return false;  
89 - },  
90 - fileList,  
91 - onChange: handleChange,  
92 - accept: '.xlsx',  
93 - };  
94 -  
95 - return (  
96 - <>  
97 - <Modal  
98 - width={500}  
99 - open  
100 - title="批量发货"  
101 - footer={[  
102 - <Button key="cancel" onClick={onClose}>  
103 - 取消  
104 - </Button>,  
105 - <Button  
106 - type="primary"  
107 - key="ok"  
108 - onClick={handleUpload}  
109 - disabled={fileList.length === 0}  
110 - loading={uploading}  
111 - >  
112 - {uploading ? '上传中' : '提交'}  
113 - </Button>,  
114 - ]}  
115 - onCancel={async () => {  
116 - onClose();  
117 - }}  
118 - >  
119 - <div className="py-4 font-semibold">  
120 - 导入发货信息  
121 - <Button type="link" onClick={downloadTemplate}>  
122 - 下载模板  
123 - </Button>  
124 - </div>  
125 - <Upload {...props}>  
126 - <Button icon={<UploadOutlined />} disabled={fileList.length > 0}>  
127 - 点击选择文件  
128 - </Button>  
129 - </Upload>  
130 - </Modal>  
131 - {contextHolder}  
132 - </>  
133 - );  
134 -};  
src/pages/Order/WarningWhitelist/components/InvoiceSubOrderInfoTable.tsx deleted 100644 → 0
1 -import { postServiceOrderGetReissueInfo } from '@/services';  
2 -import type { ProColumns } from '@ant-design/pro-components';  
3 -import { ProTable } from '@ant-design/pro-components';  
4 -import { Button, Divider } from 'antd';  
5 -import { useEffect, useState } from 'react';  
6 -  
7 -const columns: ProColumns[] = [  
8 - {  
9 - title: '发票号码',  
10 - width: 80,  
11 - dataIndex: 'invoiceNumber',  
12 - render: (_) => _,  
13 - },  
14 - {  
15 - title: '关联订单',  
16 - dataIndex: 'subOrderIds',  
17 - render: (_, { subOrderIds }) => {  
18 - console.log(JSON.stringify(_));  
19 - console.log(JSON.stringify(subOrderIds));  
20 - return (  
21 - <>  
22 - {subOrderIds.map((subOrderId, index) => {  
23 - return (  
24 - <>  
25 - <Button  
26 - key={index}  
27 - className="pl-1 pr-0"  
28 - type="link"  
29 - target="_blank"  
30 - href={'/order?id=' + subOrderId}  
31 - >  
32 - {subOrderId}  
33 - </Button>  
34 - <Divider type="vertical" />  
35 - </>  
36 - );  
37 - })}  
38 - </>  
39 - );  
40 - },  
41 - },  
42 -];  
43 -  
44 -export default ({ subOrderIds }) => {  
45 - const [reissueInfos, setReissueInfos] = useState([]);  
46 - useEffect(() => {  
47 - console.log('info');  
48 - const getReissueInfo = async () => {  
49 - let res = await postServiceOrderGetReissueInfo({  
50 - data: subOrderIds,  
51 - });  
52 - setReissueInfos(res.data);  
53 - };  
54 - getReissueInfo();  
55 - }, []);  
56 - return (  
57 - <ProTable  
58 - dataSource={reissueInfos}  
59 - rowKey="key"  
60 - pagination={false}  
61 - size={'small'}  
62 - //设置左右下边距为0  
63 - options={false}  
64 - columns={columns}  
65 - search={false}  
66 - dateFormatter="string"  
67 - headerTitle="发票信息"  
68 - />  
69 - );  
70 -};  
src/pages/Order/WarningWhitelist/components/InvoicingDrawerForm.tsx deleted 100644 → 0
1 -// import { PlusOutlined } from '@ant-design/icons';  
2 -import InvoiceModal from '@/pages/Invoice/InvoiceVerification/components/InvoiceModal';  
3 -import {  
4 - postServiceConstGetPayeeEnum,  
5 - postServiceConstInitInvoiceDetailNames,  
6 - postServiceConstInvoiceType,  
7 - postServiceConstInvoicingType,  
8 - postServiceConstListInvoiceDetailNames,  
9 - postServiceInvoiceApplyInvoice,  
10 - postServiceInvoiceQueryCompanyInfo,  
11 - postServiceInvoiceWaitReissueInvoices,  
12 -} from '@/services';  
13 -import { FloatAdd, FloatSub, enum2ReverseSelect, enumToSelect } from '@/utils';  
14 -import { convertCurrency } from '@/utils/numberUtil';  
15 -import {  
16 - DrawerForm,  
17 - FormListActionType,  
18 - ProCard,  
19 - ProFormDigit,  
20 - ProFormGroup,  
21 - ProFormInstance,  
22 - ProFormList,  
23 - ProFormMoney,  
24 - ProFormSelect,  
25 - ProFormText,  
26 - ProFormTextArea,  
27 -} from '@ant-design/pro-components';  
28 -import { Button, Divider, Form, Space, Tooltip, message } from 'antd';  
29 -import { useEffect, useRef, useState } from 'react';  
30 -  
31 -export default ({ dataList, setVisible, mainOrder, onClose }) => {  
32 - // let subOrderIds = dataList?.map((item) => {  
33 - // return item.id;  
34 - // })  
35 - const [form] = Form.useForm();  
36 - const [projectOptions] = useState();  
37 - const [dataListCopy] = useState(dataList);  
38 - const listActionRef = useRef<FormListActionType>();  
39 - const formRef = useRef<ProFormInstance>();  
40 - useEffect(() => {  
41 - const initOptions = async () => {  
42 - const res = await postServiceConstInitInvoiceDetailNames({  
43 - data: dataListCopy.map((item) => {  
44 - return item.productName;  
45 - }),  
46 - });  
47 - const options = res.data;  
48 - const datas = dataListCopy.map((item) => {  
49 - return {  
50 - ...item,  
51 - projectName: options[item.productName],  
52 - };  
53 - });  
54 - const initialValue = datas.map((item) => {  
55 - return {  
56 - productName: item.productName,  
57 - projectName: item.projectName,  
58 - subOrderId: item.id,  
59 - specification: item.parameters,  
60 - unit: item.unit,  
61 - quantity: item.quantity,  
62 - price: item.productPrice,  
63 - totalPrice: item.subOrderPayment,  
64 - };  
65 - });  
66 - form.setFieldValue('invoiceDetails', initialValue);  
67 - form.setFieldValue('contacts', mainOrder.customerName);  
68 - };  
69 - initOptions();  
70 - }, []);  
71 -  
72 - useEffect(() => {}, [projectOptions]);  
73 -  
74 - function copyToClipboard(text: string) {  
75 - // 创建一个临时的textarea元素  
76 - const textarea = document.createElement('textarea');  
77 - textarea.value = text;  
78 -  
79 - // 将textarea元素添加到DOM中  
80 - document.body.appendChild(textarea);  
81 -  
82 - // 选中textarea中的文本  
83 - textarea.select();  
84 -  
85 - try {  
86 - // 尝试执行复制命令  
87 - document.execCommand('copy');  
88 - return true;  
89 - } catch (err) {  
90 - return false;  
91 - } finally {  
92 - // 移除临时的textarea元素  
93 - document.body.removeChild(textarea);  
94 - }  
95 - }  
96 -  
97 - useEffect(() => {}, []);  
98 - return (  
99 - <DrawerForm  
100 - open  
101 - title="申请开票"  
102 - resize={{  
103 - maxWidth: window.innerWidth * 0.8,  
104 - minWidth: 500,  
105 - }}  
106 - form={form}  
107 - formRef={formRef}  
108 - autoFocusFirstInput  
109 - drawerProps={{  
110 - destroyOnClose: true,  
111 - }}  
112 - submitter={{  
113 - render: (props, defaultDoms) => {  
114 - return [  
115 - <InvoiceModal  
116 - key={'invoicePreview'}  
117 - button={<Button type="primary"> 发票预览 </Button>}  
118 - getRecord={() => {  
119 - const totalPrice = form  
120 - .getFieldValue('invoiceDetails')  
121 - .reduce((accumulator, currentValue) => {  
122 - return FloatAdd(accumulator, currentValue.totalPrice);  
123 - }, 0);  
124 - const partyBName = form.getFieldValue('partyBName');  
125 - const openBank = form.getFieldValue('openBank');  
126 - const bankAccount = form.getFieldValue('bankAccount');  
127 - const bankCode = form.getFieldValue('bankCode');  
128 - return {  
129 - ...form.getFieldsValue(),  
130 - totalPrice: totalPrice,  
131 - totalPriceText: convertCurrency(totalPrice),  
132 - comment:  
133 - '开户名称: ' +  
134 - partyBName +  
135 - '\n' +  
136 - '开户行: ' +  
137 - openBank +  
138 - '\n' +  
139 - '账号: ' +  
140 - bankAccount +  
141 - '\n' +  
142 - '银行联行号: ' +  
143 - bankCode,  
144 - };  
145 - }}  
146 - />,  
147 - ...defaultDoms,  
148 - ];  
149 - },  
150 - }}  
151 - submitTimeout={2000}  
152 - onFinish={async (values) => {  
153 - postServiceInvoiceApplyInvoice({  
154 - data: {  
155 - ...values,  
156 - subOrderIds: dataListCopy.map((item) => {  
157 - return item.id;  
158 - }),  
159 - },  
160 - });  
161 - onClose();  
162 - }}  
163 - onOpenChange={(val) => {  
164 - return !val && setVisible();  
165 - }}  
166 - >  
167 - <ProFormList  
168 - name="subOrderIdObjs"  
169 - readonly={true}  
170 - label="开票订单"  
171 - initialValue={dataListCopy.map((item) => {  
172 - return {  
173 - value: item.id,  
174 - };  
175 - })}  
176 - deleteIconProps={false}  
177 - copyIconProps={false}  
178 - >  
179 - <ProFormGroup key="group">  
180 - <ProFormText readonly={true} name="value" label="" />  
181 - </ProFormGroup>  
182 - </ProFormList>  
183 - <ProFormSelect  
184 - name="ReissueInvoiceRecordIds"  
185 - label="重开的发票"  
186 - fieldProps={{  
187 - mode: 'multiple',  
188 - }}  
189 - placeholder="请选择重开发票"  
190 - request={async () => {  
191 - let reissueIds = dataListCopy.map((item) => {  
192 - return item.id;  
193 - });  
194 - let res = await postServiceInvoiceWaitReissueInvoices({  
195 - data: reissueIds,  
196 - });  
197 - return enum2ReverseSelect(res.data);  
198 - }}  
199 - />  
200 - <ProFormSelect  
201 - key="key"  
202 - label="购方名称"  
203 - width="lg"  
204 - showSearch  
205 - name="partyAName"  
206 - placeholder="请搜索购方"  
207 - rules={[{ required: true, message: '购方名称必填' }]}  
208 - onChange={(_, option) => {  
209 - form.setFieldValue('partyATaxid', option.taxId);  
210 - }}  
211 - fieldProps={{  
212 - optionItemRender(item) {  
213 - if (item.type === 'add') {  
214 - return <>{item.name}</>;  
215 - }  
216 - return (  
217 - <>  
218 - {item.name}  
219 - <Divider type="vertical" />  
220 - {item.taxId}  
221 - </>  
222 - );  
223 - },  
224 - }}  
225 - debounceTime={1000}  
226 - request={async (value) => {  
227 - const keywords = value.keyWords;  
228 - const res = await postServiceInvoiceQueryCompanyInfo({  
229 - data: {  
230 - nameLike: keywords,  
231 - taxIdIsNotNull: true,  
232 - },  
233 - });  
234 - let options = res?.data?.map((company) => {  
235 - return {  
236 - ...company,  
237 - label: company.name,  
238 - value: company.name,  
239 - key: company.id,  
240 - };  
241 - });  
242 -  
243 - //第一个商品默认为要新增的商品  
244 - if (keywords.trim() !== '') {  
245 - options.unshift({  
246 - name: keywords,  
247 - type: 'add',  
248 - label: keywords,  
249 - value: keywords,  
250 - key: keywords,  
251 - });  
252 - }  
253 - return options;  
254 - }}  
255 - />  
256 - <ProFormText  
257 - width="md"  
258 - name="partyATaxid"  
259 - label="购方税号"  
260 - rules={[{ required: true, message: '购方税号必填' }]}  
261 - placeholder="请输入名称"  
262 - />  
263 - <ProFormText  
264 - width="md"  
265 - name="partyAOpenBank"  
266 - label="开户银行"  
267 - placeholder="请输入名称"  
268 - />  
269 - <ProFormText  
270 - width="md"  
271 - name="partyABankAccount"  
272 - label="开户行账号"  
273 - placeholder="请输入名称"  
274 - />  
275 - <ProFormText  
276 - name="contacts"  
277 - label="联系人"  
278 - rules={[{ required: true, message: '请选择银行联行号!' }]}  
279 - />  
280 - <ProFormSelect  
281 - name="invoicingType"  
282 - label="开具类型"  
283 - request={async () => {  
284 - let invoicingTypeRet = await postServiceConstInvoicingType();  
285 - let options = enumToSelect(invoicingTypeRet.data);  
286 - return options;  
287 - }}  
288 - placeholder="请选择开具类型"  
289 - rules={[{ required: true, message: '请选择开具类型!' }]}  
290 - />  
291 - <ProFormSelect  
292 - name="type"  
293 - label="开票类型"  
294 - placeholder="请选择开票类型"  
295 - rules={[{ required: true, message: '请选择开票类型!' }]}  
296 - request={async () => {  
297 - let invoiceTypeRet = await postServiceConstInvoiceType();  
298 - let options = enumToSelect(invoiceTypeRet.data);  
299 - return options;  
300 - }}  
301 - />  
302 - <ProFormSelect  
303 - name="partyB"  
304 - label="开票收款单位"  
305 - request={async () => {  
306 - const res = await postServiceConstGetPayeeEnum();  
307 - let options = res?.data?.map((payee: any) => {  
308 - return {  
309 - ...payee,  
310 - label: payee.payeeName,  
311 - value: payee.name,  
312 - };  
313 - });  
314 - return options;  
315 - }}  
316 - onChange={(_, option) => {  
317 - if (option) {  
318 - form.setFieldsValue({  
319 - partyBName: option.payeeName,  
320 - partyBTaxid: option.taxId,  
321 - bankAccount: option.bankAccount,  
322 - openBank: option.openBank,  
323 - bankCode: option.bankCode,  
324 - });  
325 - }  
326 - }}  
327 - placeholder="请选择收款单位"  
328 - rules={[{ required: true, message: '请选择收款单位!' }]}  
329 - />  
330 - <ProFormText  
331 - name="partyBName"  
332 - label="开票收款单位名称"  
333 - hidden  
334 - rules={[{ required: true, message: '请选择收款单位!' }]}  
335 - />  
336 - <ProFormText  
337 - name="partyBTaxid"  
338 - label="开票收款单位税号"  
339 - hidden  
340 - rules={[{ required: true, message: '请选择收款单位!' }]}  
341 - />  
342 - <ProFormText  
343 - name="bankAccount"  
344 - label="账号"  
345 - hidden  
346 - rules={[{ required: true, message: '请选择账号!' }]}  
347 - />  
348 - <ProFormText  
349 - name="openBank"  
350 - label="开户行"  
351 - hidden  
352 - rules={[{ required: true, message: '请选择开户行!' }]}  
353 - />  
354 - <ProFormText  
355 - name="bankCode"  
356 - label="银行联行号"  
357 - hidden  
358 - rules={[{ required: true, message: '请选择银行联行号!' }]}  
359 - />  
360 - <ProFormSelect  
361 - name="isUrgent"  
362 - label="是否加急"  
363 - valueEnum={{  
364 - true: '是',  
365 - false: '否',  
366 - }}  
367 - placeholder="请选择是否加急"  
368 - rules={[{ required: true, message: '请选择是否加急!' }]}  
369 - />  
370 - <ProFormMoney  
371 - label="开票金额"  
372 - name="price"  
373 - locale="zh-CN"  
374 - disabled={true}  
375 - rules={[{ required: true, message: '请填写开票金额!' }]}  
376 - initialValue={dataListCopy.reduce((accumulator, currentValue) => {  
377 - return accumulator + currentValue.subOrderPayment;  
378 - }, 0)}  
379 - />  
380 - <ProFormList  
381 - name="invoiceDetails"  
382 - label="开票明细"  
383 - actionRef={listActionRef}  
384 - actionGuard={{  
385 - beforeRemoveRow: async (index) => {  
386 - const list = listActionRef.current?.getList();  
387 - const totalPrice = list[index].totalPrice;  
388 - form.setFieldValue(  
389 - 'price',  
390 - FloatSub(form.getFieldValue('price'), totalPrice),  
391 - );  
392 - return true;  
393 - },  
394 - }}  
395 - rules={[  
396 - {  
397 - required: true,  
398 - validator: async (_, value) => {  
399 - if (value && value.length > 0) {  
400 - return;  
401 - }  
402 - throw new Error('至少要有一项!');  
403 - },  
404 - },  
405 - ]}  
406 - itemRender={(doms, listMeta) => {  
407 - return (  
408 - <ProCard  
409 - bordered  
410 - extra={doms.action}  
411 - title={'明细' + (listMeta.index + 1)}  
412 - style={{  
413 - marginBlockEnd: 8,  
414 - }}  
415 - >  
416 - <Tooltip title="点击复制商品名称">  
417 - <Space  
418 - className="hover:cursor-pointer"  
419 - style={{  
420 - margin: 16,  
421 - marginTop: 4,  
422 - marginLeft: 0,  
423 - fontSize: 15,  
424 - }}  
425 - onClick={() => {  
426 - copyToClipboard(listMeta.record.productName);  
427 - message.info('商品名称复制成功!');  
428 - }}  
429 - >  
430 - 商品名称:{listMeta.record.productName}  
431 - </Space>  
432 - </Tooltip>  
433 - <ProFormSelect  
434 - key={'projectName' + listMeta.index}  
435 - width="md"  
436 - showSearch  
437 - name="projectName"  
438 - rules={[{ required: true, message: '请输入开票项目名称!' }]}  
439 - request={async (value) => {  
440 - const keywords = value.keyWords;  
441 - const res = await postServiceConstListInvoiceDetailNames({  
442 - data: {  
443 - nameLike: keywords,  
444 - },  
445 - });  
446 - let options = res?.data?.map((c: any) => {  
447 - return {  
448 - ...c,  
449 - label:  
450 - '*' +  
451 - c.productAndServiceCatagoryAbbreviation +  
452 - '*' +  
453 - c.name,  
454 - value:  
455 - '*' +  
456 - c.productAndServiceCatagoryAbbreviation +  
457 - '*' +  
458 - c?.name,  
459 - key: c.id,  
460 - };  
461 - });  
462 - return options;  
463 - }}  
464 - fieldProps={{  
465 - filterOption() {  
466 - return true;  
467 - },  
468 - }}  
469 - onChange={(_, option) => {  
470 - let index = listMeta.index;  
471 - let copyList = form.getFieldValue('invoiceDetails');  
472 - let currentData = copyList[index];  
473 - currentData.projectName =  
474 - '*' +  
475 - option.productAndServiceCatagoryAbbreviation +  
476 - '*' +  
477 - option.name;  
478 - form.setFieldValue('invoiceDetails', copyList);  
479 - }}  
480 - debounceTime={1000}  
481 - label="项目名称"  
482 - initialValue={listMeta.record.projectName}  
483 - placeholder="请输入名称"  
484 - />  
485 - <ProFormText  
486 - key={'specification' + listMeta.index}  
487 - name="specification"  
488 - label="规格型号"  
489 - rules={[  
490 - {  
491 - message: '规格型号不能为空!',  
492 - required: true,  
493 - },  
494 - {  
495 - validator: (_, value) => {  
496 - let len = 0;  
497 - // 判断是否为全角字符  
498 - for (let i = 0; i < value.length; i++) {  
499 - // 获取字符的Unicode值  
500 - const code = value.charCodeAt(i);  
501 - // 判断是否为全角字符  
502 - if (  
503 - (code >= 0xff01 && code <= 0xff5e) ||  
504 - (code >= 0x4e00 && code <= 0x9fff)  
505 - ) {  
506 - len += 2; // 全角字符  
507 - } else {  
508 - len += 1; // 半角字符  
509 - }  
510 - }  
511 - if (len <= 40) {  
512 - return Promise.resolve();  
513 - }  
514 - return Promise.reject(  
515 - new Error('规格型号不能超过40个字符!'),  
516 - );  
517 - },  
518 - },  
519 - ]}  
520 - placeholder="请输入名称"  
521 - />  
522 - <ProFormText  
523 - key={'unit' + listMeta.index}  
524 - name="unit"  
525 - label="单位"  
526 - placeholder="请输入名称"  
527 - />  
528 - <ProFormDigit  
529 - key={'quantity' + listMeta.index}  
530 - label="数量"  
531 - name="quantity"  
532 - rules={[  
533 - {  
534 - validator: (_, value) => {  
535 - if (value === undefined || value > 0) {  
536 - return Promise.resolve();  
537 - }  
538 - return Promise.reject(new Error('数量必须大于0'));  
539 - },  
540 - },  
541 - ]}  
542 - />  
543 - <ProFormDigit  
544 - key={'price' + listMeta.index}  
545 - label="单价"  
546 - name="price"  
547 - rules={[  
548 - {  
549 - validator: (_, value) => {  
550 - if (value === undefined || value > 0) {  
551 - return Promise.resolve();  
552 - }  
553 - return Promise.reject(new Error('单价必须大于0'));  
554 - },  
555 - },  
556 - ]}  
557 - />  
558 - <ProFormMoney  
559 - key={'totalPrice' + listMeta.index}  
560 - label="金额"  
561 - name="totalPrice"  
562 - onChange={() => {  
563 - const invoiceDetails = form.getFieldValue('invoiceDetails');  
564 - console.log('invoiceDetails', invoiceDetails);  
565 - const totalPrice = invoiceDetails.reduce(  
566 - (accumulator, currentValue) => {  
567 - return FloatAdd(accumulator, currentValue.totalPrice);  
568 - },  
569 - 0,  
570 - );  
571 - console.log('totalPrice', totalPrice);  
572 - form.setFieldValue('price', totalPrice);  
573 - }}  
574 - rules={[  
575 - {  
576 - validator: (_, value) => {  
577 - if (value === undefined || value > 0) {  
578 - return Promise.resolve();  
579 - }  
580 - return Promise.reject(new Error('金额必须大于0'));  
581 - },  
582 - },  
583 - ]}  
584 - locale="zh-CN"  
585 - />  
586 - </ProCard>  
587 - );  
588 - }}  
589 - ></ProFormList>  
590 - <ProFormTextArea  
591 - name="applyInvoicingNotes"  
592 - label="备注"  
593 - placeholder="请输入名称"  
594 - />  
595 - </DrawerForm>  
596 - );  
597 -};  
src/pages/Order/WarningWhitelist/components/KingdeeCustomerModal.tsx deleted 100644 → 0
1 -import {  
2 - postKingdeeRepCustomerDetail,  
3 - postKingdeeRepCustomerSave,  
4 -} from '@/services';  
5 -import { getTeacherCustomFieldNumber } from '@/utils/kingdee';  
6 -import { CloseCircleOutlined } from '@ant-design/icons';  
7 -import {  
8 - ModalForm,  
9 - ProFormGroup,  
10 - ProFormList,  
11 - ProFormText,  
12 -} from '@ant-design/pro-components';  
13 -import { Form, message } from 'antd';  
14 -  
15 -// import { cloneDeep } from 'lodash';  
16 -export default ({ setVisible, data, onClose }) => {  
17 - const [form] = Form.useForm();  
18 -  
19 - /**  
20 - * 回显客户信息  
21 - * @param id  
22 - */  
23 - async function queryAndShowCustomer(id: any) {  
24 - //查询客户信息  
25 - let res = await postKingdeeRepCustomerDetail({  
26 - data: {  
27 - id: id,  
28 - },  
29 - });  
30 -  
31 - if (res) {  
32 - form.setFieldValue('name', res.name);  
33 - form.setFieldValue('id', res.id);  
34 - form.setFieldValue('contact_persons', res.bomentity);  
35 - let customFiledNumber = await getTeacherCustomFieldNumber();  
36 - form.setFieldValue('teacherName', res.custom_field[customFiledNumber]);  
37 - }  
38 - }  
39 -  
40 - if (data) {  
41 - //修改  
42 - if (data.id) {  
43 - queryAndShowCustomer(data.id);  
44 - } else {  
45 - //新增  
46 - form.setFieldValue('name', data.name);  
47 - form.setFieldValue('contact_persons', [{}]);  
48 - }  
49 - }  
50 - return (  
51 - <>  
52 - <ModalForm  
53 - width={900}  
54 - open  
55 - title="客户信息"  
56 - form={form}  
57 - autoFocusFirstInput  
58 - modalProps={{  
59 - okText: '保存',  
60 - cancelText: '取消',  
61 - destroyOnClose: true,  
62 - onCancel: () => {  
63 - setVisible(false);  
64 - },  
65 - }}  
66 - onFinish={async (values) => {  
67 - //查询客户自定义字段,课题组  
68 - let custom_field_umber = await getTeacherCustomFieldNumber();  
69 -  
70 - if (custom_field_umber) {  
71 - let customFieldObj = {};  
72 - customFieldObj[custom_field_umber] = values.teacherName;  
73 - values.custom_field = customFieldObj;  
74 - }  
75 - let customSaveRes = await postKingdeeRepCustomerSave({  
76 - data: values,  
77 - });  
78 - if (customSaveRes) {  
79 - let id_number_map = customSaveRes.id_number_map;  
80 - let ids = customSaveRes.ids;  
81 - if (id_number_map && ids) {  
82 - message.success('保存成功');  
83 - let id = ids[0];  
84 - onClose(id);  
85 - }  
86 - }  
87 - }}  
88 - onOpenChange={setVisible}  
89 - >  
90 - <ProFormText key="key" name="id" label="id" placeholder="id" hidden />  
91 - <ProFormGroup key="group">  
92 - <ProFormText  
93 - name="name"  
94 - width="md"  
95 - label={  
96 - <>  
97 - <span>客户名称</span>  
98 - <span className="pl-2 text-xs text-gray-400">  
99 - 请按照[单位]-[姓名][手机号]命名,例如:清华大学-张三12345678919  
100 - </span>  
101 - </>  
102 - }  
103 - initialValue={data}  
104 - placeholder="请输入客户名称"  
105 - rules={[  
106 - {  
107 - required: true,  
108 - pattern: new RegExp('^.+-.+$'),  
109 - message:  
110 - '格式错误,若无单位可写:“无-姓名手机号”,例如:无-张三12345678919',  
111 - },  
112 - { required: true, message: '客户名称必填' },  
113 - ]}  
114 - />  
115 - <ProFormText  
116 - name="teacherName"  
117 - width="md"  
118 - label="课题组老师"  
119 - placeholder="请输入课题组老师"  
120 - rules={[  
121 - { required: true, message: '课题组老师必填,若没有请填“无”' },  
122 - ]}  
123 - />  
124 - </ProFormGroup>  
125 -  
126 - <ProFormList  
127 - creatorButtonProps={{ disabled: false }}  
128 - name="contact_persons"  
129 - label="联系人信息"  
130 - actionGuard={{  
131 - beforeRemoveRow: async () => {  
132 - return new Promise((resolve) => {  
133 - let contactPersons = form.getFieldValue('contact_persons');  
134 - if (contactPersons.length === 1) {  
135 - message.error('至少要有一个联系人');  
136 - resolve(false);  
137 - return;  
138 - }  
139 - resolve(true);  
140 - });  
141 - },  
142 - beforeAddRow: (defaultValue) => {  
143 - defaultValue.id = undefined; //复制的时候要把id去掉  
144 - return defaultValue;  
145 - },  
146 - }}  
147 - deleteIconProps={{  
148 - Icon: CloseCircleOutlined,  
149 - tooltipText: '不需要这行了',  
150 - }}  
151 - >  
152 - <ProFormGroup key="group">  
153 - {[  
154 - <ProFormText  
155 - key="key"  
156 - name="id"  
157 - label="id"  
158 - placeholder="id"  
159 - hidden  
160 - />,  
161 - <ProFormText  
162 - key="key"  
163 - name="contact_person"  
164 - label="收货人姓名"  
165 - placeholder="联系人姓名"  
166 - rules={[{ required: true, message: '收货人姓名必填' }]}  
167 - />,  
168 - <ProFormText  
169 - key="key"  
170 - name="mobile"  
171 - label="联系方式"  
172 - placeholder="联系方式"  
173 - rules={[{ required: true, message: '联系方式必填' }]}  
174 - />,  
175 - <ProFormText  
176 - key="key"  
177 - name="contact_address"  
178 - label="收货地址"  
179 - width="md"  
180 - placeholder="请输入收货地址"  
181 - rules={[{ required: true, message: '收货地址必填' }]}  
182 - />,  
183 - ]}  
184 - </ProFormGroup>  
185 - </ProFormList>  
186 - </ModalForm>  
187 - </>  
188 - );  
189 -};  
src/pages/Order/WarningWhitelist/components/LazySelect.tsx deleted 100644 → 0
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/WarningWhitelist/components/MessageListDrawer.tsx deleted 100644 → 0
1 -import ButtonConfirm from '@/components/ButtomConfirm';  
2 -import { RESPONSE_CODE } from '@/constants/enum';  
3 -import {  
4 - postOrderErpMessageQueryMyMessage,  
5 - postOrderErpMessageRead,  
6 - postOrderErpMessageReadAll,  
7 -} from '@/services';  
8 -import { formatDateTime, getUserInfo } from '@/utils';  
9 -import { UserOutlined } from '@ant-design/icons';  
10 -import {  
11 - Avatar,  
12 - Badge,  
13 - Button,  
14 - Checkbox,  
15 - Drawer,  
16 - Flex,  
17 - List,  
18 - message,  
19 -} from 'antd';  
20 -import { useEffect, useState } from 'react';  
21 -  
22 -export default ({ setVisible }) => {  
23 - const userInfo = getUserInfo();  
24 - const [current, setCurrent] = useState<number>(1); //当前页码  
25 - const [total, setTotal] = useState(0);  
26 - const [messageListData, setMessageListData] = useState<any[]>([]); //列表数据  
27 - const [loading, setLoading] = useState(false);  
28 - const [initLoading, setInitLoading] = useState(true);  
29 - const [onlyUnread, setOnlyUnread] = useState(false);  
30 - const [readFlagList, setReadFlagList] = useState<any[]>([]); //消息未读标识  
31 -  
32 - /**  
33 - * 获取消息列表  
34 - */  
35 - async function getMessageListData() {  
36 - setLoading(true);  
37 - let res = await postOrderErpMessageQueryMyMessage({  
38 - data: {  
39 - username: userInfo.username,  
40 - current: current,  
41 - isReaded: onlyUnread ? onlyUnread : null,  
42 - },  
43 - }).finally(() => {  
44 - setLoading(false);  
45 - });  
46 - if (res && res.result === RESPONSE_CODE.SUCCESS) {  
47 - setMessageListData([...messageListData, ...res?.data?.data]);  
48 - let reqReadNumList = res?.data?.data?.map((item: any) => {  
49 - return item.isReaded;  
50 - });  
51 -  
52 - setReadFlagList([...readFlagList, ...reqReadNumList]);  
53 - setTotal(res?.data?.total);  
54 - }  
55 - }  
56 -  
57 - /**  
58 - * 跳转到订单列表  
59 - */  
60 - function toOrderList(mainOrderIds: any) {  
61 - window.open('/order?id=' + mainOrderIds.join(","), '_blank');  
62 - }  
63 -  
64 - /**  
65 - * 仅展示未读  
66 - */  
67 - function onlyUnreadChange() {  
68 - setOnlyUnread(!onlyUnread);  
69 - setCurrent(1);  
70 - setMessageListData([]);  
71 - setReadFlagList([]);  
72 - }  
73 -  
74 - /**  
75 - * 仅展示未读  
76 - */  
77 - async function read(ids: any[]) {  
78 - let res = await postOrderErpMessageRead({  
79 - data: ids,  
80 - });  
81 -  
82 - if (res && res.result === RESPONSE_CODE.SUCCESS) {  
83 - message.success('已读');  
84 - return true;  
85 - }  
86 -  
87 - return false;  
88 - }  
89 -  
90 - /**  
91 - * 全部标记为已读  
92 - */  
93 - async function readAll() {  
94 - let res = await postOrderErpMessageReadAll();  
95 - if (res && res.result === RESPONSE_CODE.SUCCESS) {  
96 - message.success(res.message);  
97 - let newReadFlagList = readFlagList.map(() => true);  
98 - setReadFlagList(newReadFlagList);  
99 - }  
100 - }  
101 -  
102 - const loadMore =  
103 - !initLoading && !loading && messageListData.length < total ? (  
104 - <div  
105 - style={{  
106 - textAlign: 'center',  
107 - marginTop: 12,  
108 - height: 32,  
109 - lineHeight: '32px',  
110 - }}  
111 - >  
112 - <Button  
113 - onClick={() => {  
114 - setCurrent(current + 1);  
115 - }}  
116 - >  
117 - 加载更多  
118 - </Button>  
119 - </div>  
120 - ) : messageListData.length > 0 && messageListData.length >= total ? (  
121 - <span>没有更多消息了</span>  
122 - ) : null;  
123 -  
124 - useEffect(() => {  
125 - getMessageListData().finally(() => {  
126 - setInitLoading(false);  
127 - });  
128 - }, [onlyUnread, current]);  
129 -  
130 - return (  
131 - <>  
132 - <Drawer  
133 - title="消息列表"  
134 - onClose={() => {  
135 - setVisible(false);  
136 - }}  
137 - open={true}  
138 - width={450}  
139 - styles={{ body: { paddingTop: 0 } }}  
140 - >  
141 - <Flex align="center" justify="space-between">  
142 - <div>  
143 - <Checkbox onChange={onlyUnreadChange} checked={onlyUnread}>  
144 - 仅展示未读  
145 - </Checkbox>  
146 - </div>  
147 -  
148 - <ButtonConfirm  
149 - title={'是否全部标记为已读?'}  
150 - text={'全部标记为已读'}  
151 - className="p-0"  
152 - onConfirm={readAll}  
153 - placement="bottomLeft"  
154 - />  
155 - </Flex>  
156 -  
157 - <List  
158 - className="demo-loadmore-list"  
159 - loading={initLoading}  
160 - itemLayout="horizontal"  
161 - loadMore={loadMore}  
162 - dataSource={messageListData}  
163 - renderItem={(item: any, index: any) => (  
164 - <List.Item key={item.id}>  
165 - <List.Item.Meta  
166 - avatar={  
167 - <Badge dot={!readFlagList[index]}>  
168 - <Avatar shape="square" icon={<UserOutlined />} />  
169 - </Badge>  
170 - }  
171 - />  
172 - <Flex  
173 - vertical  
174 - className="w-full hover:cursor-pointer"  
175 - onClick={async () => {  
176 - toOrderList(item.mainOrderIds);  
177 -  
178 - let readSuccess = await read([item.mesUsrRelId]);  
179 - if (readSuccess) {  
180 - let newUnreadNumList = [...readFlagList];  
181 - newUnreadNumList[index] = true;  
182 - setReadFlagList([...newUnreadNumList]);  
183 - }  
184 - }}  
185 - >  
186 - <Flex>  
187 - <div>  
188 - {item.content}  
189 - {/* <span className="text-[#8C8C8C]">  
190 - (点击跳转到对应主订单)  
191 - </span> */}  
192 - </div>  
193 - </Flex>  
194 - <Flex>  
195 - <span className="text-xs text-[#8C8C8C] pt-1">  
196 - {formatDateTime(item.createTime)}  
197 - </span>  
198 - </Flex>  
199 - </Flex>  
200 - </List.Item>  
201 - )}  
202 - />  
203 - </Drawer>  
204 - </>  
205 - );  
206 -};