Commit c89daffdcb177f6131e3fccdb8780f44b1039ceb
Merge branch 'bugfix-invoicestatus' into dev
Showing
15 changed files
with
1248 additions
and
247 deletions
Too many changes to show.
To preserve performance only 15 of 24 files are displayed.
src/pages/Invoice/InvoiceRecord/components/InvoiceRecordDetailModal.tsx
... | ... | @@ -3,7 +3,6 @@ import InvoiceDetailTable from '@/pages/Invoice/InvoiceRecord/components/Invoice |
3 | 3 | import { |
4 | 4 | postServiceConstGetPayeeEnum, |
5 | 5 | postServiceConstInvoiceType, |
6 | - postServiceConstInvoicingType, | |
7 | 6 | postServiceInvoiceGetInvoiceRecord, |
8 | 7 | postServiceInvoiceModifyRecord, |
9 | 8 | } from '@/services'; |
... | ... | @@ -230,7 +229,7 @@ export default ({ id, setVisible, reloadTable }) => { |
230 | 229 | { required: true, message: 'Please select your country!' }, |
231 | 230 | ]} |
232 | 231 | /> |
233 | - <ProFormSelect | |
232 | + {/* <ProFormSelect | |
234 | 233 | name="invoicingType" |
235 | 234 | readonly={readOnly} |
236 | 235 | label="开具类型" |
... | ... | @@ -246,7 +245,7 @@ export default ({ id, setVisible, reloadTable }) => { |
246 | 245 | rules={[ |
247 | 246 | { required: true, message: 'Please select your country!' }, |
248 | 247 | ]} |
249 | - /> | |
248 | + /> */} | |
250 | 249 | <ProFormList |
251 | 250 | label="订单号" |
252 | 251 | name="orderIdList" | ... | ... |
src/pages/Invoice/InvoiceVerification/components/InvoiceRecordDetailModal.tsx
... | ... | @@ -3,7 +3,6 @@ import InvoiceDetailTable from '@/pages/Invoice/InvoiceVerification/components/I |
3 | 3 | import { |
4 | 4 | postServiceConstGetPayeeEnum, |
5 | 5 | postServiceConstInvoiceType, |
6 | - postServiceConstInvoicingType, | |
7 | 6 | postServiceInvoiceGetInvoiceRecord, |
8 | 7 | postServiceInvoiceModifyRecord, |
9 | 8 | } from '@/services'; |
... | ... | @@ -229,7 +228,7 @@ export default ({ id, setVisible }) => { |
229 | 228 | { required: true, message: 'Please select your country!' }, |
230 | 229 | ]} |
231 | 230 | /> |
232 | - <ProFormSelect | |
231 | + {/* <ProFormSelect | |
233 | 232 | name="invoicingType" |
234 | 233 | readonly={readOnly} |
235 | 234 | label="开具类型" |
... | ... | @@ -245,7 +244,7 @@ export default ({ id, setVisible }) => { |
245 | 244 | rules={[ |
246 | 245 | { required: true, message: 'Please select your country!' }, |
247 | 246 | ]} |
248 | - /> | |
247 | + /> */} | |
249 | 248 | <ProFormList |
250 | 249 | label="订单号" |
251 | 250 | name="orderIdList" | ... | ... |
src/pages/Invoice/waitProcessRecord/components/ManualInvoiceModal.tsx
0 → 100644
1 | +import { RESPONSE_CODE } from '@/constants/enum'; | |
2 | +import { PAYEE_OPTIONS } from '@/pages/Order/constant'; | |
3 | +import { postServiceOrderInvoicing } from '@/services'; | |
4 | +import { | |
5 | + ModalForm, | |
6 | + ProFormDatePicker, | |
7 | + ProFormDigit, | |
8 | + ProFormSelect, | |
9 | + ProFormText, | |
10 | +} from '@ant-design/pro-components'; | |
11 | +import { Form, message } from 'antd'; | |
12 | +import { useState } from 'react'; | |
13 | + | |
14 | +interface ManualInvoiceModalProps { | |
15 | + record: any; | |
16 | + onSuccess?: () => void; | |
17 | +} | |
18 | + | |
19 | +const ManualInvoiceModal: React.FC<ManualInvoiceModalProps> = ({ | |
20 | + record, | |
21 | + onSuccess, | |
22 | +}) => { | |
23 | + const [form] = Form.useForm(); | |
24 | + const [visible, setVisible] = useState(false); | |
25 | + | |
26 | + // 转换PAYEE_OPTIONS为Select组件需要的格式 | |
27 | + const payeeOptions = Object.entries(PAYEE_OPTIONS).map(([value, label]) => ({ | |
28 | + value, | |
29 | + label, | |
30 | + })); | |
31 | + | |
32 | + return ( | |
33 | + <ModalForm | |
34 | + title="手动开票" | |
35 | + trigger={ | |
36 | + <a | |
37 | + key="invoice" | |
38 | + style={{ color: '#1890ff' }} | |
39 | + onClick={() => setVisible(true)} | |
40 | + > | |
41 | + 开票 | |
42 | + </a> | |
43 | + } | |
44 | + width={600} | |
45 | + layout={'horizontal'} | |
46 | + form={form} | |
47 | + open={visible} | |
48 | + onOpenChange={setVisible} | |
49 | + autoFocusFirstInput | |
50 | + modalProps={{ | |
51 | + destroyOnClose: true, | |
52 | + }} | |
53 | + initialValues={{ | |
54 | + purchaser: record.partyAName, | |
55 | + payee: record.partyB, | |
56 | + money: record.price, | |
57 | + }} | |
58 | + submitTimeout={2000} | |
59 | + onFinish={async (values) => { | |
60 | + try { | |
61 | + const body = { | |
62 | + invoiceIdentificationNumber: values.purchaser, | |
63 | + invoicingTime: values.invoicingTime, | |
64 | + purchaser: values.purchaser, | |
65 | + financialReceiptIssuanceTime: | |
66 | + values.financialReceiptIssuanceTime || values.invoicingTime, | |
67 | + collectMoneyTime: values.collectMoneyTime || values.invoicingTime, | |
68 | + invoiceNumber: values.invoiceNumber, | |
69 | + payee: values.payee, | |
70 | + money: values.money, | |
71 | + afterInvoicingStatus: [record.type], | |
72 | + mainOrderIds: record.mainOrderIds, | |
73 | + invoiceRecordIds: [record.id], | |
74 | + }; | |
75 | + | |
76 | + // 根据现有组件实现,使用data来传递参数 | |
77 | + const res = await postServiceOrderInvoicing({ | |
78 | + data: body, | |
79 | + }); | |
80 | + | |
81 | + if (res.result === RESPONSE_CODE.SUCCESS) { | |
82 | + message.success('开票成功'); | |
83 | + if (onSuccess) { | |
84 | + onSuccess(); | |
85 | + } | |
86 | + return true; | |
87 | + } else { | |
88 | + message.error('开票失败'); | |
89 | + return false; | |
90 | + } | |
91 | + } catch (error) { | |
92 | + message.error('操作失败'); | |
93 | + return false; | |
94 | + } | |
95 | + }} | |
96 | + > | |
97 | + <ProFormText | |
98 | + width="md" | |
99 | + name="purchaser" | |
100 | + label="抬头名称" | |
101 | + rules={[{ required: true, message: '请输入抬头名称' }]} | |
102 | + disabled | |
103 | + /> | |
104 | + | |
105 | + <ProFormText | |
106 | + width="md" | |
107 | + name="invoiceType" | |
108 | + label="发票类型" | |
109 | + initialValue="普票" | |
110 | + disabled | |
111 | + /> | |
112 | + | |
113 | + <ProFormDigit | |
114 | + width="md" | |
115 | + name="money" | |
116 | + label="发票金额" | |
117 | + fieldProps={{ | |
118 | + precision: 2, | |
119 | + prefix: '¥', | |
120 | + }} | |
121 | + rules={[{ required: true, message: '请输入发票金额' }]} | |
122 | + disabled | |
123 | + /> | |
124 | + | |
125 | + <ProFormSelect | |
126 | + width="md" | |
127 | + name="payee" | |
128 | + label="收款单位" | |
129 | + options={payeeOptions} | |
130 | + rules={[{ required: true, message: '请选择收款单位' }]} | |
131 | + disabled | |
132 | + /> | |
133 | + | |
134 | + <ProFormText | |
135 | + width="md" | |
136 | + name="invoiceNumber" | |
137 | + label="发票号码" | |
138 | + rules={[{ required: true, message: '请输入发票号码' }]} | |
139 | + /> | |
140 | + | |
141 | + <ProFormDatePicker | |
142 | + width="md" | |
143 | + name="invoicingTime" | |
144 | + label="开票时间" | |
145 | + rules={[{ required: true, message: '请选择开票时间' }]} | |
146 | + fieldProps={{ | |
147 | + format: 'YYYY-MM-DD', | |
148 | + }} | |
149 | + /> | |
150 | + </ModalForm> | |
151 | + ); | |
152 | +}; | |
153 | + | |
154 | +export default ManualInvoiceModal; | ... | ... |
src/pages/Invoice/waitProcessRecord/index.tsx
... | ... | @@ -2,6 +2,7 @@ import { RESPONSE_CODE } from '@/constants/enum'; |
2 | 2 | import InvoiceRecordDetailModal from '@/pages/Invoice/InvoiceRecord/components/InvoiceRecordDetailModal'; |
3 | 3 | import InvoiceModal from '@/pages/Invoice/waitProcessRecord/components/InvoiceModal'; |
4 | 4 | import InvoicingModal from '@/pages/Invoice/waitProcessRecord/components/InvoicingModal'; |
5 | +import ManualInvoiceModal from '@/pages/Invoice/waitProcessRecord/components/ManualInvoiceModal'; | |
5 | 6 | import ManualInvoicingModal from '@/pages/Invoice/waitProcessRecord/components/ManualInvoicingModal'; |
6 | 7 | import { PAYEE_OPTIONS } from '@/pages/Order/constant'; |
7 | 8 | import { |
... | ... | @@ -20,6 +21,7 @@ import { |
20 | 21 | Popconfirm, |
21 | 22 | Space, |
22 | 23 | Table, |
24 | + Tabs, | |
23 | 25 | Tooltip, |
24 | 26 | message, |
25 | 27 | } from 'antd'; |
... | ... | @@ -27,12 +29,15 @@ import { useEffect, useRef, useState } from 'react'; |
27 | 29 | |
28 | 30 | const InvoiceRecord = () => { |
29 | 31 | const waitDealrecordActionRef = useRef<ActionType>(); |
32 | + const manualInvoiceActionRef = useRef<ActionType>(); | |
30 | 33 | const [invoiceTypeValueEnum, setInvoiceTypeValueEnum] = useState({}); |
31 | 34 | const [invoicingTypeValueEnum, setInvoicingTypeValueEnum] = useState({}); |
32 | 35 | const [salesCodeValueEnum, setSalesCodeValueEnum] = useState({}); |
33 | 36 | const [invoiceRecordDetailVisible, setInvoiceRecordDetailVisible] = |
34 | 37 | useState(false); |
35 | 38 | const [invoiceRecord, setInvoiceRecord] = useState({}); |
39 | + const [activeTab, setActiveTab] = useState('auto'); | |
40 | + | |
36 | 41 | useEffect(() => { |
37 | 42 | async function extracted() { |
38 | 43 | let invoiceTypeRet = await postServiceConstInvoiceType(); |
... | ... | @@ -65,7 +70,11 @@ const InvoiceRecord = () => { |
65 | 70 | }, []); |
66 | 71 | |
67 | 72 | const reloadRecordTable = () => { |
68 | - waitDealrecordActionRef.current?.reload(); | |
73 | + if (activeTab === 'auto') { | |
74 | + waitDealrecordActionRef.current?.reload(); | |
75 | + } else { | |
76 | + manualInvoiceActionRef.current?.reload(); | |
77 | + } | |
69 | 78 | }; |
70 | 79 | |
71 | 80 | const waitDealRecordColumns = [ |
... | ... | @@ -287,11 +296,11 @@ const InvoiceRecord = () => { |
287 | 296 | valueEnum: { |
288 | 297 | true: { |
289 | 298 | text: '是', |
290 | - status: true, | |
299 | + status: 'true', | |
291 | 300 | }, |
292 | 301 | false: { |
293 | 302 | text: '否', |
294 | - status: false, | |
303 | + status: 'false', | |
295 | 304 | }, |
296 | 305 | }, |
297 | 306 | }, |
... | ... | @@ -319,15 +328,6 @@ const InvoiceRecord = () => { |
319 | 328 | width: 200, |
320 | 329 | render: (text, record) => { |
321 | 330 | return [ |
322 | - /*<InvoiceRecordDetailModal | |
323 | - key="detail" | |
324 | - id={record.id} | |
325 | - subOrderIds={record.subOrderIds} | |
326 | - onClose={()=>{ | |
327 | - waitDealrecordActionRef.current?.reload(); | |
328 | - } | |
329 | - } | |
330 | - />*/ | |
331 | 331 | <> |
332 | 332 | {record.paths.includes('DETAIL') && ( |
333 | 333 | <a |
... | ... | @@ -368,7 +368,7 @@ const InvoiceRecord = () => { |
368 | 368 | if (res.result === RESPONSE_CODE.SUCCESS) { |
369 | 369 | message.success('取消成功'); |
370 | 370 | } |
371 | - waitDealrecordActionRef?.current?.reload(); | |
371 | + reloadRecordTable(); | |
372 | 372 | }} |
373 | 373 | okText="确定" |
374 | 374 | cancelText="取消" |
... | ... | @@ -383,74 +383,327 @@ const InvoiceRecord = () => { |
383 | 383 | }, |
384 | 384 | }, |
385 | 385 | ]; |
386 | - return ( | |
387 | - <div className="invoice-index"> | |
388 | - <ProTable | |
389 | - columns={waitDealRecordColumns} | |
390 | - actionRef={waitDealrecordActionRef} | |
391 | - cardBordered | |
392 | - pagination={{ | |
393 | - showSizeChanger: true, // 显示可以选择每页显示条数的下拉菜单 | |
394 | - pageSizeOptions: ['10', '20', '50', '100'], // 设置可以选择的每页显示条数选项 | |
395 | - }} | |
396 | - rowSelection={{ | |
397 | - selections: [Table.SELECTION_ALL, Table.SELECTION_INVERT], | |
398 | - alwaysShowAlert: true, | |
399 | - }} | |
400 | - tableAlertOptionRender={({ selectedRowKeys, selectedRows }) => { | |
401 | - console.log(selectedRows); | |
402 | - console.log(selectedRowKeys); | |
403 | - return ( | |
404 | - <Space size={16}> | |
405 | - <InvoicingModal | |
406 | - reloadRecordTable={reloadRecordTable} | |
407 | - key="button" | |
408 | - selectedRowKeys={selectedRowKeys} | |
409 | - /> | |
410 | - </Space> | |
411 | - ); | |
412 | - }} | |
413 | - request={async (params) => { | |
414 | - let res = await postServiceInvoiceQueryInvoiceRecordList({ | |
415 | - data: { | |
416 | - ...params, | |
417 | - statusIn: [ | |
418 | - 'WAITING_FOR_INVOICING', | |
419 | - 'AUDITING', | |
420 | - 'AUDITING_NOT_PASSED', | |
421 | - ], | |
422 | - needBuildDetails: true, | |
423 | - needBuildSubOrders: true, | |
424 | - }, | |
386 | + | |
387 | + // 手动开票表格列配置 | |
388 | + const manualInvoiceColumns = [ | |
389 | + { | |
390 | + dataIndex: 'index', | |
391 | + valueType: 'indexBorder', | |
392 | + hideInSearch: true, | |
393 | + ellipsis: true, | |
394 | + width: 48, | |
395 | + }, | |
396 | + { | |
397 | + title: '开票编号', | |
398 | + valueType: 'text', | |
399 | + dataIndex: 'id', | |
400 | + copyable: true, | |
401 | + hideInSearch: true, | |
402 | + ellipsis: true, | |
403 | + width: 100, | |
404 | + }, | |
405 | + { | |
406 | + title: '订单号', | |
407 | + valueType: 'text', | |
408 | + dataIndex: 'mainOrderIds', | |
409 | + hideInSearch: true, | |
410 | + ellipsis: true, | |
411 | + width: 150, | |
412 | + }, | |
413 | + { | |
414 | + title: '开票金额', | |
415 | + valueType: 'money', | |
416 | + dataIndex: 'price', | |
417 | + width: 100, | |
418 | + hideInSearch: true, | |
419 | + ellipsis: true, | |
420 | + }, | |
421 | + { | |
422 | + title: '购方名称', | |
423 | + valueType: 'text', | |
424 | + dataIndex: 'partyAName', | |
425 | + width: 150, | |
426 | + hideInSearch: true, | |
427 | + ellipsis: true, | |
428 | + }, | |
429 | + { | |
430 | + title: '收款单位', | |
431 | + valueType: 'text', | |
432 | + hideInSearch: true, | |
433 | + width: 150, | |
434 | + dataIndex: 'partyBName', | |
435 | + ellipsis: true, | |
436 | + }, | |
437 | + { | |
438 | + title: '开票类型', | |
439 | + valueType: 'Text', | |
440 | + dataIndex: 'typeText', | |
441 | + width: 100, | |
442 | + hideInSearch: true, | |
443 | + ellipsis: true, | |
444 | + }, | |
445 | + { | |
446 | + title: '是否加急', | |
447 | + valueType: 'Text', | |
448 | + dataIndex: 'isUrgentText', | |
449 | + width: 80, | |
450 | + hideInSearch: true, | |
451 | + ellipsis: true, | |
452 | + }, | |
453 | + { | |
454 | + title: '附件', | |
455 | + key: 'filePaths', | |
456 | + ellipsis: true, | |
457 | + width: 100, | |
458 | + hideInSearch: true, | |
459 | + render: (_, record) => { | |
460 | + if (record.filePaths && record.filePaths.length > 0) { | |
461 | + return record.filePaths.map((item) => { | |
462 | + const url = item; | |
463 | + const filenameMatch = url.match(/\/([^/]+)\?/); | |
464 | + const filename = filenameMatch ? filenameMatch[1] : 'file'; | |
465 | + | |
466 | + const decodedFilename = decodeURIComponent(filename); | |
467 | + | |
468 | + const cleanFilename = decodedFilename.replace(/^\d+-\d+-/, ''); | |
469 | + | |
470 | + return ( | |
471 | + <div style={{ marginBottom: '5px' }} key={url}> | |
472 | + <a | |
473 | + href={url} | |
474 | + rel="noopener noreferrer" | |
475 | + download={cleanFilename} | |
476 | + > | |
477 | + {cleanFilename} | |
478 | + </a> | |
479 | + </div> | |
480 | + ); | |
425 | 481 | }); |
426 | - return { | |
427 | - data: res?.data?.data, | |
428 | - total: res?.data?.total || 0, | |
429 | - }; | |
430 | - }} | |
431 | - columnsState={{ | |
432 | - persistenceKey: 'pro-table-singe-demos', | |
433 | - persistenceType: 'localStorage', | |
434 | - defaultValue: { | |
435 | - option: { fixed: 'right', disable: true }, | |
482 | + } | |
483 | + return '-'; | |
484 | + }, | |
485 | + }, | |
486 | + { | |
487 | + title: '申请时间', | |
488 | + dataIndex: 'createTime', | |
489 | + valueType: 'dateTime', | |
490 | + width: 160, | |
491 | + hideInSearch: true, | |
492 | + ellipsis: true, | |
493 | + }, | |
494 | + { | |
495 | + title: '申请人', | |
496 | + valueType: 'text', | |
497 | + hideInSearch: false, | |
498 | + ellipsis: true, | |
499 | + width: 100, | |
500 | + dataIndex: 'createByName', | |
501 | + }, | |
502 | + { | |
503 | + title: '操作', | |
504 | + valueType: 'option', | |
505 | + key: 'option', | |
506 | + width: 120, | |
507 | + render: (_, record) => { | |
508 | + return [ | |
509 | + <ManualInvoiceModal | |
510 | + key="invoice" | |
511 | + record={record} | |
512 | + onSuccess={() => reloadRecordTable()} | |
513 | + />, | |
514 | + <Popconfirm | |
515 | + key="cancel" | |
516 | + title="取消开票" | |
517 | + description="确认取消开票?" | |
518 | + onConfirm={async () => { | |
519 | + let res = await postServiceInvoiceCancelInvoiceRecord({ | |
520 | + data: { | |
521 | + invoiceRecordIds: [record.id], | |
522 | + }, | |
523 | + }); | |
524 | + if (res.result === RESPONSE_CODE.SUCCESS) { | |
525 | + message.success('取消成功'); | |
526 | + } | |
527 | + reloadRecordTable(); | |
528 | + }} | |
529 | + okText="确定" | |
530 | + cancelText="取消" | |
531 | + > | |
532 | + <a key="cancel" style={{ color: '#ff4d4f' }}> | |
533 | + 取消 | |
534 | + </a> | |
535 | + </Popconfirm>, | |
536 | + ]; | |
537 | + }, | |
538 | + }, | |
539 | + // 搜索项 | |
540 | + { | |
541 | + title: '订单号', | |
542 | + valueType: 'Text', | |
543 | + dataIndex: 'mainOrderIds', | |
544 | + hideInTable: true, | |
545 | + }, | |
546 | + { | |
547 | + title: '购方名称', | |
548 | + valueType: 'Text', | |
549 | + dataIndex: 'partyANameLike', | |
550 | + hideInTable: true, | |
551 | + }, | |
552 | + { | |
553 | + title: '收款单位', | |
554 | + valueType: 'select', | |
555 | + dataIndex: 'partyB', | |
556 | + filters: true, | |
557 | + onFilter: true, | |
558 | + hideInTable: true, | |
559 | + valueEnum: enumToProTableEnumValue(PAYEE_OPTIONS), | |
560 | + }, | |
561 | + { | |
562 | + title: '发票类型', | |
563 | + valueType: 'select', | |
564 | + dataIndex: 'type', | |
565 | + filters: true, | |
566 | + onFilter: true, | |
567 | + hideInTable: true, | |
568 | + valueEnum: enumToProTableEnumValue(invoiceTypeValueEnum), | |
569 | + }, | |
570 | + { | |
571 | + title: '是否加急', | |
572 | + valueType: 'select', | |
573 | + dataIndex: 'isUrgent', | |
574 | + filters: true, | |
575 | + onFilter: true, | |
576 | + hideInTable: true, | |
577 | + valueEnum: { | |
578 | + true: { | |
579 | + text: '是', | |
580 | + status: 'true', | |
581 | + }, | |
582 | + false: { | |
583 | + text: '否', | |
584 | + status: 'false', | |
585 | + }, | |
586 | + }, | |
587 | + }, | |
588 | + { | |
589 | + title: '申请时间', | |
590 | + dataIndex: 'createTime', | |
591 | + valueType: 'dateTimeRange', | |
592 | + width: 200, | |
593 | + hideInTable: true, | |
594 | + search: { | |
595 | + transform: (value) => { | |
596 | + if (value) { | |
597 | + return { | |
598 | + createTimeGe: value[0], | |
599 | + createTimeLe: value[1], | |
600 | + }; | |
601 | + } | |
602 | + }, | |
603 | + }, | |
604 | + }, | |
605 | + ]; | |
606 | + | |
607 | + const renderProTable = (isManual) => { | |
608 | + const tableProps = { | |
609 | + columns: isManual ? manualInvoiceColumns : waitDealRecordColumns, | |
610 | + actionRef: isManual ? manualInvoiceActionRef : waitDealrecordActionRef, | |
611 | + cardBordered: true, | |
612 | + pagination: { | |
613 | + showSizeChanger: true, // 显示可以选择每页显示条数的下拉菜单 | |
614 | + pageSizeOptions: ['10', '20', '50', '100'], // 设置可以选择的每页显示条数选项 | |
615 | + }, | |
616 | + request: async (params) => { | |
617 | + let res = await postServiceInvoiceQueryInvoiceRecordList({ | |
618 | + data: { | |
619 | + ...params, | |
620 | + isManual: isManual, | |
621 | + statusIn: [ | |
622 | + 'WAITING_FOR_INVOICING', | |
623 | + 'AUDITING', | |
624 | + 'AUDITING_NOT_PASSED', | |
625 | + ], | |
626 | + needBuildDetails: true, | |
627 | + needBuildSubOrders: true, | |
436 | 628 | }, |
437 | - onChange(value) { | |
438 | - console.log('value: ', value); | |
629 | + }); | |
630 | + return { | |
631 | + data: res?.data?.data, | |
632 | + total: res?.data?.total || 0, | |
633 | + }; | |
634 | + }, | |
635 | + columnsState: { | |
636 | + persistenceKey: isManual | |
637 | + ? 'manual-invoice-table' | |
638 | + : 'auto-invoice-table', | |
639 | + persistenceType: 'localStorage', | |
640 | + defaultValue: { | |
641 | + option: { fixed: 'right', disable: true }, | |
642 | + }, | |
643 | + onChange(value) { | |
644 | + console.log('value: ', value); | |
645 | + }, | |
646 | + }, | |
647 | + rowKey: 'id', | |
648 | + search: { | |
649 | + labelWidth: 'auto', | |
650 | + }, | |
651 | + options: { | |
652 | + setting: { | |
653 | + listsHeight: 400, | |
654 | + }, | |
655 | + }, | |
656 | + form: {}, | |
657 | + dateFormatter: 'string', | |
658 | + headerTitle: isManual ? '手动开票列表' : '自动开票列表', | |
659 | + scroll: { x: 2000, y: 500 }, | |
660 | + }; | |
661 | + | |
662 | + // 如果不是手动开票,添加多选功能 | |
663 | + if (!isManual) { | |
664 | + tableProps.rowSelection = { | |
665 | + selections: [Table.SELECTION_ALL, Table.SELECTION_INVERT], | |
666 | + alwaysShowAlert: true, | |
667 | + }; | |
668 | + | |
669 | + tableProps.tableAlertOptionRender = ({ | |
670 | + selectedRowKeys, | |
671 | + selectedRows, | |
672 | + }) => { | |
673 | + console.log(selectedRows); | |
674 | + console.log(selectedRowKeys); | |
675 | + return ( | |
676 | + <Space size={16}> | |
677 | + <InvoicingModal | |
678 | + reloadRecordTable={reloadRecordTable} | |
679 | + key="button" | |
680 | + selectedRowKeys={selectedRowKeys} | |
681 | + /> | |
682 | + </Space> | |
683 | + ); | |
684 | + }; | |
685 | + } | |
686 | + | |
687 | + return <ProTable {...tableProps} />; | |
688 | + }; | |
689 | + | |
690 | + return ( | |
691 | + <div className="invoice-index"> | |
692 | + <Tabs | |
693 | + activeKey={activeTab} | |
694 | + onChange={(key) => setActiveTab(key)} | |
695 | + items={[ | |
696 | + { | |
697 | + key: 'auto', | |
698 | + label: '自动开票', | |
699 | + children: renderProTable(false), | |
439 | 700 | }, |
440 | - }} | |
441 | - rowKey="id" | |
442 | - search={{ | |
443 | - labelWidth: 'auto', | |
444 | - }} | |
445 | - options={{ | |
446 | - setting: { | |
447 | - listsHeight: 400, | |
701 | + { | |
702 | + key: 'manual', | |
703 | + label: '手动开票', | |
704 | + children: renderProTable(true), | |
448 | 705 | }, |
449 | - }} | |
450 | - form={{}} | |
451 | - dateFormatter="string" | |
452 | - headerTitle="待开票列表" | |
453 | - scroll={{ x: 2000, y: 500 }} | |
706 | + ]} | |
454 | 707 | /> |
455 | 708 | {invoiceRecordDetailVisible ? ( |
456 | 709 | <InvoiceRecordDetailModal |
... | ... | @@ -458,7 +711,7 @@ const InvoiceRecord = () => { |
458 | 711 | id={invoiceRecord.id} |
459 | 712 | setVisible={setInvoiceRecordDetailVisible} |
460 | 713 | reloadTable={() => { |
461 | - waitDealrecordActionRef?.current?.reload(); | |
714 | + reloadRecordTable(); | |
462 | 715 | }} |
463 | 716 | /> |
464 | 717 | ) : ( | ... | ... |
src/pages/Order/FeedBack/InvoicingDrawerForm.tsx
... | ... | @@ -4,7 +4,6 @@ import { |
4 | 4 | postServiceConstGetPayeeEnum, |
5 | 5 | postServiceConstInitInvoiceDetailNames, |
6 | 6 | postServiceConstInvoiceType, |
7 | - postServiceConstInvoicingType, | |
8 | 7 | postServiceConstListInvoiceDetailNames, |
9 | 8 | postServiceInvoiceApplyInvoice, |
10 | 9 | postServiceInvoiceQueryCompanyInfo, |
... | ... | @@ -298,7 +297,7 @@ export default ({ dataList, setVisible, mainOrder, onClose }) => { |
298 | 297 | label="联系人" |
299 | 298 | rules={[{ required: true, message: '请选择银行联行号!' }]} |
300 | 299 | /> |
301 | - <ProFormSelect | |
300 | + {/* <ProFormSelect | |
302 | 301 | name="invoicingType" |
303 | 302 | label="开具类型" |
304 | 303 | request={async () => { |
... | ... | @@ -308,7 +307,7 @@ export default ({ dataList, setVisible, mainOrder, onClose }) => { |
308 | 307 | }} |
309 | 308 | placeholder="请选择开具类型" |
310 | 309 | rules={[{ required: true, message: '请选择开具类型!' }]} |
311 | - /> | |
310 | + /> */} | |
312 | 311 | <ProFormSelect |
313 | 312 | name="type" |
314 | 313 | label="开票类型" | ... | ... |
src/pages/Order/FeedBack/OrderDrawer.tsx
... | ... | @@ -1492,7 +1492,19 @@ export default ({ onClose, data, subOrders, orderOptType }) => { |
1492 | 1492 | onChange={(val: any) => { |
1493 | 1493 | setPaymentMethod(val); |
1494 | 1494 | }} |
1495 | - options={enumToSelect(PAYMENT_METHOD_OPTIONS)} | |
1495 | + options={(() => { | |
1496 | + // 使用Set记录已经处理过的选项值,避免重复 | |
1497 | + const processedValues = new Set(); | |
1498 | + const finalOptions = []; | |
1499 | + | |
1500 | + // 处理可选项 | |
1501 | + enumToSelect(PAYMENT_METHOD_OPTIONS).forEach((option) => { | |
1502 | + finalOptions.push(option); | |
1503 | + processedValues.add(option.value); | |
1504 | + }); | |
1505 | + | |
1506 | + return finalOptions; | |
1507 | + })()} | |
1496 | 1508 | rules={[{ required: true, message: '支付方式必填' }]} |
1497 | 1509 | disabled={optType('after-sales-check')} |
1498 | 1510 | /> | ... | ... |
src/pages/Order/FeedBack/constant.ts
... | ... | @@ -24,9 +24,10 @@ export const RECEIPTS_RECORD_TYPES = { |
24 | 24 | export const PAYMENT_METHOD_OPTIONS = { |
25 | 25 | UNPAID: '未付款', |
26 | 26 | TAOBAO_ORDER_HAS_BEEN_PAID: '淘宝订单已付款', |
27 | - OFFICIAL_WEBSITE_ORDER_HAS_BEEN_PAID: '官网订单已付款', | |
28 | - PAYMENT_IN_ADVANCE: '预付款', | |
29 | - WITHHOLDING_ADVANCE_DEPOSIT: '扣预存', | |
27 | + OFFICIAL_WEBSITE_ORDER_HAS_BEEN_PAID: '官网已付', | |
28 | + PAYMENT_IN_ADVANCE: '预付', | |
29 | + PAYMENT_IN_TAOBAO: '淘宝', | |
30 | + WITHHOLDING_ADVANCE_DEPOSIT: '预付', | |
30 | 31 | PLATFORM_SETTLEMENT: '平台结算', |
31 | 32 | CASH_ON_DELIVERY: '货到付款', |
32 | 33 | HIRE_PURCHASE: '分期付款', |
... | ... | @@ -250,12 +251,8 @@ export const FINANCIAL_STATUS_OPTIONS = { |
250 | 251 | export const AFTER_INVOICING_STATUS = { |
251 | 252 | NOT_YET_INVOICED: '尚未开票', |
252 | 253 | APPLY_FOR_INVOICING: '申请开票', |
253 | - URGENT_INVOICE_AUDITING: '加急待审核', | |
254 | - URGENT_INVOICE_AUDIT_NOTPASS: '加急审核失败', | |
255 | 254 | PARTIAL_INVOICING: '部分开票', |
256 | 255 | COMPLETE_INVOICING: '完全开票', |
257 | - INVOICING: '开票中', | |
258 | - REISSUE: '重新开票', | |
259 | 256 | }; |
260 | 257 | |
261 | 258 | export const TAGS_COLOR = new Map<string, string>([ | ... | ... |
src/pages/Order/Order/components/InvoicingDrawerForm.tsx
... | ... | @@ -4,7 +4,6 @@ import { |
4 | 4 | postServiceConstGetPayeeEnum, |
5 | 5 | postServiceConstInitInvoiceDetailNames, |
6 | 6 | postServiceConstInvoiceType, |
7 | - postServiceConstInvoicingType, | |
8 | 7 | postServiceConstListInvoiceDetailNames, |
9 | 8 | postServiceInvoiceApplyInvoice, |
10 | 9 | postServiceInvoiceQueryCompanyInfo, |
... | ... | @@ -326,7 +325,7 @@ export default ({ |
326 | 325 | label="联系人" |
327 | 326 | rules={[{ required: true, message: '请选择银行联行号!' }]} |
328 | 327 | /> |
329 | - <ProFormSelect | |
328 | + {/* <ProFormSelect | |
330 | 329 | name="invoicingType" |
331 | 330 | label="开具类型" |
332 | 331 | request={async () => { |
... | ... | @@ -336,7 +335,7 @@ export default ({ |
336 | 335 | }} |
337 | 336 | placeholder="请选择开具类型" |
338 | 337 | rules={[{ required: true, message: '请选择开具类型!' }]} |
339 | - /> | |
338 | + /> */} | |
340 | 339 | <ProFormSelect |
341 | 340 | name="type" |
342 | 341 | label="开票类型" | ... | ... |
src/pages/Order/Order/components/OrderDrawer.tsx
... | ... | @@ -1501,7 +1501,19 @@ export default ({ onClose, data, subOrders, orderOptType }) => { |
1501 | 1501 | onChange={(val: any) => { |
1502 | 1502 | setPaymentMethod(val); |
1503 | 1503 | }} |
1504 | - options={enumToSelect(PAYMENT_METHOD_OPTIONS)} | |
1504 | + options={(() => { | |
1505 | + // 使用Set记录已经处理过的选项值,避免重复 | |
1506 | + const processedValues = new Set(); | |
1507 | + const finalOptions = []; | |
1508 | + | |
1509 | + // 处理可选项 | |
1510 | + enumToSelect(PAYMENT_METHOD_OPTIONS).forEach((option) => { | |
1511 | + finalOptions.push(option); | |
1512 | + processedValues.add(option.value); | |
1513 | + }); | |
1514 | + | |
1515 | + return finalOptions; | |
1516 | + })()} | |
1505 | 1517 | rules={[{ required: true, message: '支付方式必填' }]} |
1506 | 1518 | disabled={optType('after-sales-check')} |
1507 | 1519 | /> | ... | ... |
src/pages/Order/Order/index.tsx
... | ... | @@ -120,7 +120,7 @@ const OrderPage = () => { |
120 | 120 | <div className="order-page-container"> |
121 | 121 | <div id="resizeDiv"></div> |
122 | 122 | <div id="resizeDiv"></div> |
123 | - {roleCode === 'SALES_MANAGER' && ( | |
123 | + {roleCode !== 'SALES_MANAGER' && ( | |
124 | 124 | <Modal |
125 | 125 | title="订单预警提醒" |
126 | 126 | open={open} |
... | ... | @@ -135,6 +135,11 @@ const OrderPage = () => { |
135 | 135 | > |
136 | 136 | 去处理 |
137 | 137 | </Button>, |
138 | + roleCode === 'ADMIN' && ( | |
139 | + <Button key="cancel" size="large" onClick={() => setOpen(false)}> | |
140 | + 取消 | |
141 | + </Button> | |
142 | + ), | |
138 | 143 | ]} |
139 | 144 | > |
140 | 145 | <ProCard | ... | ... |
src/pages/Order/OrderList/ApplyForInvoicingModal.tsx
1 | 1 | import { RESPONSE_CODE } from '@/constants/enum'; |
2 | -import { postServiceOrderApplyInvoicing } from '@/services'; | |
3 | -import { enumToSelect, getAliYunOSSFileNameFromUrl } from '@/utils'; | |
2 | +import { | |
3 | + postServiceOrderApplyInvoicing, | |
4 | + postServiceOrderQueryServiceOrder, | |
5 | +} from '@/services'; | |
6 | +import { FloatAdd, enumToSelect, getAliYunOSSFileNameFromUrl } from '@/utils'; | |
4 | 7 | import { |
5 | 8 | ModalForm, |
9 | + ProFormMoney, | |
6 | 10 | ProFormSelect, |
7 | 11 | ProFormText, |
8 | 12 | ProFormTextArea, |
... | ... | @@ -11,21 +15,140 @@ import { |
11 | 15 | import { Form, message } from 'antd'; |
12 | 16 | import { useEffect, useState } from 'react'; |
13 | 17 | import { PAYEE_OPTIONS } from '../constant'; |
18 | + | |
19 | +// 定义选项类型 | |
20 | +interface SelectOption { | |
21 | + label: string; | |
22 | + value: string; | |
23 | +} | |
24 | + | |
14 | 25 | export default ({ |
15 | 26 | setCheckVisible, |
16 | 27 | isEdit, |
17 | 28 | subOrders, |
18 | - isMainOrder, | |
19 | - totalPayment, | |
29 | + mainOrders, | |
20 | 30 | onClose, |
31 | +}: { | |
32 | + setCheckVisible: (val: boolean) => void; | |
33 | + isEdit?: boolean; | |
34 | + subOrders: any[]; | |
35 | + mainOrders: any[]; | |
36 | + onClose: () => void; | |
21 | 37 | }) => { |
22 | 38 | const [isUrgent, setIsUrgent] = useState(''); |
23 | - let sumPrice = totalPayment; | |
39 | + const [receivingCompanyOptions, setReceivingCompanyOptions] = useState< | |
40 | + SelectOption[] | |
41 | + >([]); | |
42 | + const [additionalMainOrders, setAdditionalMainOrders] = useState<any[]>([]); | |
24 | 43 | |
25 | 44 | let ids = subOrders?.map((item) => { |
26 | 45 | return item.id; |
27 | 46 | }); |
28 | 47 | |
48 | + // 定义返回类型接口 | |
49 | + interface MainOrderData { | |
50 | + value: string | number; | |
51 | + totalPayment: number; | |
52 | + invoiceIssuedAmount: number; | |
53 | + availableAmount: number; | |
54 | + } | |
55 | + | |
56 | + // 解析输入框内容,识别格式如 "23123,2507310003" | |
57 | + const parseInputContent = (content: string): string[] => { | |
58 | + if (!content) return []; | |
59 | + return content | |
60 | + .split(',') | |
61 | + .map((id) => id.trim()) | |
62 | + .filter((id) => id); | |
63 | + }; | |
64 | + | |
65 | + // 查询未选择的订单数据 | |
66 | + const queryMissingOrders = async (missingIds: string[]) => { | |
67 | + try { | |
68 | + const { data } = await postServiceOrderQueryServiceOrder({ | |
69 | + // @ts-ignore | |
70 | + data: { | |
71 | + current: 1, | |
72 | + pageSize: 10, | |
73 | + id: missingIds, | |
74 | + condition: 0, | |
75 | + sorted: false, | |
76 | + isDeleteQueryOrder: false, | |
77 | + }, | |
78 | + }); | |
79 | + | |
80 | + if (data?.data) { | |
81 | + setAdditionalMainOrders(data.data); | |
82 | + } | |
83 | + } catch (error) { | |
84 | + console.error('查询订单失败:', error); | |
85 | + message.error('查询订单数据失败'); | |
86 | + } | |
87 | + }; | |
88 | + | |
89 | + // 获取唯一的主订单ID及其相关金额信息 | |
90 | + const getUniqueMainOrderIds = (): MainOrderData[] => { | |
91 | + console.log(subOrders, mainOrders); | |
92 | + const mainOrderIds = subOrders?.map((item: any) => item.mainOrderId); | |
93 | + const uniqueIds = [...new Set(mainOrderIds)].filter(Boolean); | |
94 | + | |
95 | + const result = uniqueIds.map((id) => { | |
96 | + // 获取该主订单的数据 | |
97 | + const mainOrder = mainOrders | |
98 | + ? mainOrders.find((item: any) => item.id === id) | |
99 | + : null; | |
100 | + | |
101 | + // 获取该主订单下所有子订单 | |
102 | + const orderSubOrders = subOrders.filter( | |
103 | + (item: any) => item.mainOrderId === id, | |
104 | + ); | |
105 | + | |
106 | + // 计算该主订单的总金额 | |
107 | + let totalPayment = mainOrder ? mainOrder.totalPayment : 0; | |
108 | + if (!totalPayment) { | |
109 | + orderSubOrders.forEach((item: any) => { | |
110 | + totalPayment = FloatAdd(totalPayment, item.totalPayment || 0); | |
111 | + }); | |
112 | + } | |
113 | + | |
114 | + // 计算已开票金额(如果有的话) | |
115 | + let invoiceIssuedAmount = mainOrder | |
116 | + ? mainOrder.invoiceIssuedAmount || 0 | |
117 | + : 0; | |
118 | + if (!invoiceIssuedAmount) { | |
119 | + orderSubOrders.forEach((item: any) => { | |
120 | + invoiceIssuedAmount = FloatAdd( | |
121 | + invoiceIssuedAmount, | |
122 | + item.invoiceIssuedAmount || 0, | |
123 | + ); | |
124 | + }); | |
125 | + } | |
126 | + | |
127 | + // 计算可开票金额 | |
128 | + const availableAmount = Math.max(0, totalPayment - invoiceIssuedAmount); | |
129 | + | |
130 | + return { | |
131 | + value: String(id), | |
132 | + totalPayment, | |
133 | + invoiceIssuedAmount, | |
134 | + availableAmount, | |
135 | + }; | |
136 | + }); | |
137 | + | |
138 | + // 添加额外查询到的订单数据 | |
139 | + const additionalOrders = additionalMainOrders.map((order) => ({ | |
140 | + value: String(order.id), | |
141 | + totalPayment: order.totalPayment || 0, | |
142 | + invoiceIssuedAmount: order.invoiceIssuedAmount || 0, | |
143 | + availableAmount: Math.max( | |
144 | + 0, | |
145 | + (order.totalPayment || 0) - (order.invoiceIssuedAmount || 0), | |
146 | + ), | |
147 | + })); | |
148 | + | |
149 | + return [...result, ...additionalOrders]; | |
150 | + }; | |
151 | + | |
29 | 152 | let mainIdSet = new Set(); |
30 | 153 | subOrders?.forEach((item: { mainOrderId: unknown }) => { |
31 | 154 | mainIdSet.add(item.mainOrderId); |
... | ... | @@ -58,13 +181,58 @@ export default ({ |
58 | 181 | receivingCompany: string; |
59 | 182 | isUrgent: boolean; |
60 | 183 | deadline: string; |
184 | + invoiceType: string; // 新增发票类型字段 | |
61 | 185 | }>(); |
62 | 186 | |
187 | + // 处理备注内容变化 | |
188 | + const handleNotesChange = async (value: string) => { | |
189 | + const inputIds = parseInputContent(value); | |
190 | + const selectedMainOrderIds = Array.from(mainIdSet).map((id) => String(id)); | |
191 | + | |
192 | + console.log('输入的订单ID:', inputIds); | |
193 | + console.log('已选择的主订单ID:', selectedMainOrderIds); | |
194 | + | |
195 | + // 找出输入框中存在但未选择的订单ID | |
196 | + const missingIds = inputIds.filter( | |
197 | + (id) => !selectedMainOrderIds.includes(id), | |
198 | + ); | |
199 | + | |
200 | + console.log('缺失的订单ID:', missingIds); | |
201 | + | |
202 | + if (missingIds.length > 0) { | |
203 | + await queryMissingOrders(missingIds); | |
204 | + } else { | |
205 | + // 如果没有缺失的订单,清空额外的订单数据 | |
206 | + setAdditionalMainOrders([]); | |
207 | + } | |
208 | + }; | |
209 | + | |
63 | 210 | useEffect(() => { |
64 | 211 | //显示拼接的主订单id |
65 | 212 | form.setFieldValue('applyInvoicingNotes', mainIds); |
213 | + | |
214 | + // 转换收款单位选项并保存 | |
215 | + const options = enumToSelect(PAYEE_OPTIONS); | |
216 | + setReceivingCompanyOptions(options); | |
66 | 217 | }, []); |
67 | 218 | |
219 | + useEffect(() => { | |
220 | + // 当额外的主订单数据变化时,设置可开票金额初始值 | |
221 | + const mainOrders = getUniqueMainOrderIds(); | |
222 | + mainOrders.forEach((order) => { | |
223 | + // 只为新添加的订单设置初始值,避免覆盖用户已输入的值 | |
224 | + const currentValue = form.getFieldValue( | |
225 | + `invoiceAvailableAmount_${order.value}`, | |
226 | + ); | |
227 | + if (currentValue === undefined || currentValue === null) { | |
228 | + form.setFieldValue( | |
229 | + `invoiceAvailableAmount_${order.value}`, | |
230 | + order.availableAmount, | |
231 | + ); | |
232 | + } | |
233 | + }); | |
234 | + }, [additionalMainOrders]); | |
235 | + | |
68 | 236 | return ( |
69 | 237 | <ModalForm<{ |
70 | 238 | applyInvoicingNotes: string; |
... | ... | @@ -93,7 +261,26 @@ export default ({ |
93 | 261 | }} |
94 | 262 | submitTimeout={2000} |
95 | 263 | onFinish={async (values) => { |
96 | - values.subIds = ids; | |
264 | + // 收集所有相关的子订单ID,包括额外查询到的主订单下的子订单 | |
265 | + const allSubIds = [...ids]; // 原始选择的子订单ID | |
266 | + | |
267 | + console.log('原始子订单ID:', ids); | |
268 | + console.log('额外查询的主订单:', additionalMainOrders); | |
269 | + | |
270 | + // 添加额外查询到的主订单下的子订单ID | |
271 | + additionalMainOrders.forEach((mainOrder: any) => { | |
272 | + if (mainOrder.subOrderInformationLists) { | |
273 | + mainOrder.subOrderInformationLists.forEach((subOrder: any) => { | |
274 | + if (subOrder.id && !allSubIds.includes(subOrder.id)) { | |
275 | + console.log('添加子订单ID:', subOrder.id); | |
276 | + allSubIds.push(subOrder.id); | |
277 | + } | |
278 | + }); | |
279 | + } | |
280 | + }); | |
281 | + | |
282 | + console.log('最终子订单ID列表:', allSubIds); | |
283 | + values.subIds = allSubIds; | |
97 | 284 | //附件处理 |
98 | 285 | values.filePaths = values.filePaths?.map((item) => { |
99 | 286 | return { url: item.response.data[0] }; |
... | ... | @@ -105,7 +292,43 @@ export default ({ |
105 | 292 | values.afterInvoicingUpdate = false; |
106 | 293 | } |
107 | 294 | |
108 | - const res = await postServiceOrderApplyInvoicing({ data: values }); | |
295 | + // 收集主订单可开票金额 | |
296 | + const invoiceOrderAmounts = getUniqueMainOrderIds().map((item) => ({ | |
297 | + orderId: Number(item.value), // 确保为 number 类型 | |
298 | + availableAmount: values[`invoiceAvailableAmount_${item.value}`], | |
299 | + })); | |
300 | + // 校验所有主订单可开票金额之和等于price字段 | |
301 | + const price = values.price; | |
302 | + let sumAvailable = 0; | |
303 | + invoiceOrderAmounts.forEach((item) => { | |
304 | + sumAvailable = FloatAdd(sumAvailable, item.availableAmount || 0); | |
305 | + }); | |
306 | + if (Math.abs(sumAvailable - price) > 0.01) { | |
307 | + message.error( | |
308 | + `所有主订单可开票金额之和(${sumAvailable})必须等于开票金额(${price})`, | |
309 | + ); | |
310 | + return; | |
311 | + } | |
312 | + | |
313 | + // 获取receivingCompany对应的名称 | |
314 | + const selectedOption = receivingCompanyOptions.find( | |
315 | + (option) => option.value === values.receivingCompany, | |
316 | + ); | |
317 | + const receivingCompanyName = selectedOption ? selectedOption.label : ''; | |
318 | + | |
319 | + // 构建包含所有订单的mainOrderIds字符串 | |
320 | + const allMainOrderIds = getUniqueMainOrderIds() | |
321 | + .map((item) => item.value) | |
322 | + .join(','); | |
323 | + | |
324 | + // 添加到请求数据中 | |
325 | + const reqData = { | |
326 | + ...values, | |
327 | + receivingCompanyName, // 添加收款单位名称 | |
328 | + mainOrderIds: allMainOrderIds, // 使用包含所有订单的ID字符串 | |
329 | + invoiceOrderAmounts, | |
330 | + }; | |
331 | + const res = await postServiceOrderApplyInvoicing({ data: reqData }); | |
109 | 332 | |
110 | 333 | if (res.result === RESPONSE_CODE.SUCCESS) { |
111 | 334 | message.success(res.message); |
... | ... | @@ -114,14 +337,86 @@ export default ({ |
114 | 337 | }} |
115 | 338 | onOpenChange={setCheckVisible} |
116 | 339 | > |
117 | - {isMainOrder ? ( | |
118 | - <div className="mb-[24px]"> | |
119 | - <span>选中子订单金额之和:</span> | |
120 | - <span className="text-red-500">{sumPrice}¥</span> | |
340 | + {/* 主订单金额表格,任何情况都显示 */} | |
341 | + <div style={{ marginBottom: 24 }}> | |
342 | + <div | |
343 | + style={{ | |
344 | + display: 'flex', | |
345 | + fontWeight: 'bold', | |
346 | + marginBottom: 8, | |
347 | + padding: '8px 0', | |
348 | + borderBottom: '1px solid #f0f0f0', | |
349 | + }} | |
350 | + > | |
351 | + <div style={{ flex: 25 }}>订单号</div> | |
352 | + <div style={{ flex: 18, textAlign: 'right' }}>订单金额</div> | |
353 | + <div style={{ flex: 18, textAlign: 'right' }}>已开票金额</div> | |
354 | + <div style={{ flex: 39, textAlign: 'right' }}>可开票金额</div> | |
121 | 355 | </div> |
122 | - ) : ( | |
123 | - '' | |
124 | - )} | |
356 | + {getUniqueMainOrderIds().map((item, index) => { | |
357 | + const maxAvailable = Math.max( | |
358 | + 0, | |
359 | + item.totalPayment - item.invoiceIssuedAmount, | |
360 | + ); | |
361 | + | |
362 | + // 检查是否是额外查询到的订单 | |
363 | + const isAdditionalOrder = additionalMainOrders.some( | |
364 | + (order) => String(order.id) === String(item.value), | |
365 | + ); | |
366 | + | |
367 | + return ( | |
368 | + <div | |
369 | + key={index} | |
370 | + style={{ | |
371 | + display: 'flex', | |
372 | + marginBottom: 8, | |
373 | + padding: '8px 0', | |
374 | + borderBottom: '1px solid #f0f0f0', | |
375 | + backgroundColor: isAdditionalOrder ? '#f6ffed' : 'transparent', // 浅绿色背景表示新查询的订单 | |
376 | + border: isAdditionalOrder ? '1px solid #b7eb8f' : 'none', | |
377 | + borderRadius: isAdditionalOrder ? '4px' : '0', | |
378 | + }} | |
379 | + > | |
380 | + <div style={{ flex: 25 }}> | |
381 | + {item.value} | |
382 | + {isAdditionalOrder} | |
383 | + </div> | |
384 | + <div style={{ flex: 18, textAlign: 'right' }}> | |
385 | + ¥ {item.totalPayment.toFixed(2)} | |
386 | + </div> | |
387 | + <div style={{ flex: 18, textAlign: 'right' }}> | |
388 | + ¥ {item.invoiceIssuedAmount.toFixed(2)} | |
389 | + </div> | |
390 | + <div style={{ flex: 39, textAlign: 'right' }}> | |
391 | + <ProFormMoney | |
392 | + name={`invoiceAvailableAmount_${item.value}`} | |
393 | + locale="zh-CN" | |
394 | + fieldProps={{ | |
395 | + precision: 2, | |
396 | + style: { width: '70%' }, | |
397 | + }} | |
398 | + initialValue={item.availableAmount} | |
399 | + rules={[ | |
400 | + { required: true, message: '请填写可开票金额!' }, | |
401 | + { | |
402 | + validator: (_, value) => { | |
403 | + if (value > maxAvailable) { | |
404 | + return Promise.reject( | |
405 | + `可开票金额不能超过${maxAvailable.toFixed(2)}`, | |
406 | + ); | |
407 | + } else if (value === 0) { | |
408 | + return Promise.reject(`可开票金额不能为0`); | |
409 | + } | |
410 | + return Promise.resolve(); | |
411 | + }, | |
412 | + }, | |
413 | + ]} | |
414 | + /> | |
415 | + </div> | |
416 | + </div> | |
417 | + ); | |
418 | + })} | |
419 | + </div> | |
125 | 420 | |
126 | 421 | <div className="mb-1"> |
127 | 422 | 如果需要合并订单,请将需要合并的订单id写在备注中,id之间用英文逗号隔开。 |
... | ... | @@ -131,12 +426,9 @@ export default ({ |
131 | 426 | name="applyInvoicingNotes" |
132 | 427 | key="applyInvoicingNotes" |
133 | 428 | placeholder="请输入备注" |
134 | - onMetaChange={(val) => { | |
135 | - console.log(val); | |
136 | - }} | |
137 | - proFieldProps={{ | |
138 | - onchange: () => { | |
139 | - message.info('change'); | |
429 | + fieldProps={{ | |
430 | + onChange: (e) => { | |
431 | + handleNotesChange(e.target.value); | |
140 | 432 | }, |
141 | 433 | }} |
142 | 434 | /> |
... | ... | @@ -161,9 +453,24 @@ export default ({ |
161 | 453 | </span> |
162 | 454 | </div> |
163 | 455 | } |
164 | - options={enumToSelect(PAYEE_OPTIONS)} | |
456 | + options={receivingCompanyOptions} | |
165 | 457 | rules={[{ required: true, message: '开票收款单位必填' }]} |
166 | 458 | /> |
459 | + | |
460 | + {/* 新增发票类型选择 */} | |
461 | + <ProFormSelect | |
462 | + placeholder="选择发票类型" | |
463 | + name="invoiceType" | |
464 | + width="lg" | |
465 | + key="invoiceType" | |
466 | + label="发票类型" | |
467 | + options={[ | |
468 | + { label: '普票', value: 'ORDINARY_TICKET' }, | |
469 | + { label: '专票', value: 'SPECIAL_TICKET' }, | |
470 | + ]} | |
471 | + rules={[{ required: true, message: '发票类型必填' }]} | |
472 | + /> | |
473 | + | |
167 | 474 | <ProFormSelect |
168 | 475 | placeholder="选择是否加急" |
169 | 476 | name="isUrgent" | ... | ... |
src/pages/Order/OrderList/FinancialMergeDrawer.tsx
... | ... | @@ -142,7 +142,6 @@ export default ({ dataList, setVisible, onClose }) => { |
142 | 142 | { label: '完全开票', value: 'COMPLETE_INVOICING' }, |
143 | 143 | { label: '部分开票', value: 'PARTIAL_INVOICING' }, |
144 | 144 | ]} |
145 | - initialValue={'COMPLETE_INVOICING'} | |
146 | 145 | /> |
147 | 146 | <ProFormTextArea width="lg" name="invoicingNotes" label="备注" /> |
148 | 147 | </DrawerForm> | ... | ... |
src/pages/Order/OrderList/HirePurchaseUploadPayBillModal.tsx
... | ... | @@ -22,6 +22,14 @@ interface HirePurchaseUploadPayBillModalProps { |
22 | 22 | subOrders?: any[]; |
23 | 23 | } |
24 | 24 | |
25 | +// Helper function to display dash for empty values | |
26 | +// const displayValue = (value: any, formatter?: (val: any) => string): string => { | |
27 | +// if (value === null || value === undefined || value === '') { | |
28 | +// return '-'; | |
29 | +// } | |
30 | +// return formatter ? formatter(value) : String(value); | |
31 | +// }; | |
32 | + | |
25 | 33 | const HirePurchaseUploadPayBillModal: React.FC< |
26 | 34 | HirePurchaseUploadPayBillModalProps |
27 | 35 | > = ({ |
... | ... | @@ -309,7 +317,12 @@ const HirePurchaseUploadPayBillModal: React.FC< |
309 | 317 | }} |
310 | 318 | > |
311 | 319 | <span>订单总金额:</span> |
312 | - <span>{totalPayment.toFixed(2)}元</span> | |
320 | + <span> | |
321 | + {totalPayment !== null && totalPayment !== undefined | |
322 | + ? totalPayment.toFixed(2) | |
323 | + : '-'} | |
324 | + 元 | |
325 | + </span> | |
313 | 326 | </div> |
314 | 327 | <div |
315 | 328 | style={{ |
... | ... | @@ -319,7 +332,12 @@ const HirePurchaseUploadPayBillModal: React.FC< |
319 | 332 | }} |
320 | 333 | > |
321 | 334 | <span>已回款金额:</span> |
322 | - <span>{installedMoney.toFixed(2)}元</span> | |
335 | + <span> | |
336 | + {installedMoney !== null && installedMoney !== undefined | |
337 | + ? installedMoney.toFixed(2) | |
338 | + : '-'} | |
339 | + 元 | |
340 | + </span> | |
323 | 341 | </div> |
324 | 342 | <div |
325 | 343 | style={{ |
... | ... | @@ -329,7 +347,12 @@ const HirePurchaseUploadPayBillModal: React.FC< |
329 | 347 | }} |
330 | 348 | > |
331 | 349 | <span>待回款金额:</span> |
332 | - <span>{remainingMoney.toFixed(2)}元</span> | |
350 | + <span> | |
351 | + {remainingMoney !== null && remainingMoney !== undefined | |
352 | + ? remainingMoney.toFixed(2) | |
353 | + : '-'} | |
354 | + 元 | |
355 | + </span> | |
333 | 356 | </div> |
334 | 357 | </div> |
335 | 358 | <Form.Item | ... | ... |
src/pages/Order/OrderList/InvoicingDrawerForm.tsx
... | ... | @@ -4,7 +4,6 @@ import { |
4 | 4 | postServiceConstGetPayeeEnum, |
5 | 5 | postServiceConstInitInvoiceDetailNames, |
6 | 6 | postServiceConstInvoiceType, |
7 | - postServiceConstInvoicingType, | |
8 | 7 | postServiceConstListInvoiceDetailNames, |
9 | 8 | postServiceInvoiceApplyInvoice, |
10 | 9 | postServiceInvoiceQueryCompanyInfo, |
... | ... | @@ -16,7 +15,6 @@ import { |
16 | 15 | FormListActionType, |
17 | 16 | ProCard, |
18 | 17 | ProFormDigit, |
19 | - ProFormGroup, | |
20 | 18 | ProFormInstance, |
21 | 19 | ProFormList, |
22 | 20 | ProFormMoney, |
... | ... | @@ -31,8 +29,16 @@ export default ({ |
31 | 29 | dataList, |
32 | 30 | setVisible, |
33 | 31 | mainOrder, |
32 | + mainOrders, | |
34 | 33 | onClose, |
35 | 34 | type = 'applyInvoicing', |
35 | +}: { | |
36 | + dataList: any[]; | |
37 | + setVisible: (val: boolean) => void; | |
38 | + mainOrder: any; | |
39 | + mainOrders?: any[]; | |
40 | + onClose: () => void; | |
41 | + type?: string; | |
36 | 42 | }) => { |
37 | 43 | // let subOrderIds = dataList?.map((item) => { |
38 | 44 | // return item.id; |
... | ... | @@ -82,6 +88,60 @@ export default ({ |
82 | 88 | }); |
83 | 89 | types.set('reissue', { title: '重新申请', subOrderIdsName: '重开订单' }); |
84 | 90 | |
91 | + // Get unique main order IDs from the dataList | |
92 | + // 定义返回类型接口 | |
93 | + interface MainOrderData { | |
94 | + value: string | number; | |
95 | + totalPayment: number; | |
96 | + invoiceIssuedAmount: number; | |
97 | + availableAmount: number; | |
98 | + } | |
99 | + | |
100 | + const getUniqueMainOrderIds = (): MainOrderData[] => { | |
101 | + // Extract main order IDs from dataList | |
102 | + const mainOrderIds = dataListCopy.map( | |
103 | + (item: any) => item.mainOrderId || item.orderId, | |
104 | + ); | |
105 | + // Get unique IDs | |
106 | + const uniqueIds = [...new Set(mainOrderIds)].filter(Boolean); | |
107 | + return uniqueIds.map((id) => { | |
108 | + // 确保id是string或number类型 | |
109 | + const orderId = String(id); | |
110 | + | |
111 | + // 优先从传入的mainOrders中获取数据 | |
112 | + const mainOrderData = mainOrders | |
113 | + ? mainOrders.find((item: any) => item.id === id) | |
114 | + : null; | |
115 | + | |
116 | + // 如果没有找到主订单数据,则从dataList中查找 | |
117 | + const orderData = | |
118 | + mainOrderData || | |
119 | + dataListCopy.find((d: any) => d.mainOrderId === id || d.orderId === id); | |
120 | + | |
121 | + const totalPayment = orderData?.totalPayment || 0; | |
122 | + const invoiceIssuedAmount = orderData?.invoiceIssuedAmount || 0; | |
123 | + const availableAmount = Math.max(0, totalPayment - invoiceIssuedAmount); | |
124 | + | |
125 | + return { | |
126 | + value: orderId, | |
127 | + totalPayment, | |
128 | + invoiceIssuedAmount, | |
129 | + availableAmount, | |
130 | + }; | |
131 | + }); | |
132 | + }; | |
133 | + | |
134 | + // Set initial values for invoice available amounts | |
135 | + useEffect(() => { | |
136 | + const mainOrders = getUniqueMainOrderIds(); | |
137 | + mainOrders.forEach((order) => { | |
138 | + form.setFieldValue( | |
139 | + `invoiceAvailableAmount_${order.value}`, | |
140 | + order.availableAmount, | |
141 | + ); | |
142 | + }); | |
143 | + }, []); | |
144 | + | |
85 | 145 | function copyToClipboard(text: string) { |
86 | 146 | // 创建一个临时的textarea元素 |
87 | 147 | const textarea = document.createElement('textarea'); |
... | ... | @@ -135,6 +195,8 @@ export default ({ |
135 | 195 | autoFocusFirstInput |
136 | 196 | drawerProps={{ |
137 | 197 | destroyOnClose: true, |
198 | + maskClosable: false, | |
199 | + onClose: () => setVisible(false), | |
138 | 200 | }} |
139 | 201 | submitter={{ |
140 | 202 | render: (props, defaultDoms) => { |
... | ... | @@ -177,9 +239,31 @@ export default ({ |
177 | 239 | }} |
178 | 240 | submitTimeout={2000} |
179 | 241 | onFinish={async (values) => { |
242 | + // Collect invoice available amounts in the recommended format | |
243 | + const invoiceOrderAmounts = getUniqueMainOrderIds().map((item) => ({ | |
244 | + orderId: item.value, | |
245 | + availableAmount: values[`invoiceAvailableAmount_${item.value}`], | |
246 | + })); | |
247 | + | |
248 | + // 获取开票金额(price 字段) | |
249 | + const price = values.price; | |
250 | + // 计算所有主订单可开票金额之和 | |
251 | + let sumAvailable = 0; | |
252 | + invoiceOrderAmounts.forEach((item) => { | |
253 | + sumAvailable = FloatAdd(sumAvailable, item.availableAmount || 0); | |
254 | + }); | |
255 | + // 允许0.01误差 | |
256 | + if (Math.abs(sumAvailable - price) > 0.01) { | |
257 | + message.error( | |
258 | + `所有主订单可开票金额之和(${sumAvailable})必须等于开票金额(${price})`, | |
259 | + ); | |
260 | + return; | |
261 | + } | |
262 | + | |
180 | 263 | postServiceInvoiceApplyInvoice({ |
181 | 264 | data: { |
182 | 265 | ...values, |
266 | + invoiceOrderAmounts, // 使用数组对象格式 | |
183 | 267 | subOrderIds: dataListCopy.map((item) => { |
184 | 268 | return item.id; |
185 | 269 | }), |
... | ... | @@ -192,22 +276,73 @@ export default ({ |
192 | 276 | return !val && setVisible(); |
193 | 277 | }} |
194 | 278 | > |
195 | - <ProFormList | |
196 | - name="subOrderIdObjs" | |
197 | - readonly={true} | |
198 | - label={types.get(type).subOrderIdsName} | |
199 | - initialValue={dataListCopy.map((item) => { | |
200 | - return { | |
201 | - value: item.id, | |
202 | - }; | |
279 | + <div style={{ marginBottom: 24 }}> | |
280 | + <div | |
281 | + style={{ | |
282 | + display: 'flex', | |
283 | + fontWeight: 'bold', | |
284 | + marginBottom: 8, | |
285 | + padding: '8px 0', | |
286 | + borderBottom: '1px solid #f0f0f0', | |
287 | + }} | |
288 | + > | |
289 | + <div style={{ flex: 25 }}>订单号</div> | |
290 | + <div style={{ flex: 18, textAlign: 'right' }}>订单金额</div> | |
291 | + <div style={{ flex: 18, textAlign: 'right' }}>已开票金额</div> | |
292 | + <div style={{ flex: 39, textAlign: 'right' }}>可开票金额</div> | |
293 | + </div> | |
294 | + {getUniqueMainOrderIds().map((item, index) => { | |
295 | + const maxAvailable = Math.max( | |
296 | + 0, | |
297 | + item.totalPayment - item.invoiceIssuedAmount, | |
298 | + ); | |
299 | + return ( | |
300 | + <div | |
301 | + key={index} | |
302 | + style={{ | |
303 | + display: 'flex', | |
304 | + marginBottom: 8, | |
305 | + padding: '8px 0', | |
306 | + borderBottom: '1px solid #f0f0f0', | |
307 | + }} | |
308 | + > | |
309 | + <div style={{ flex: 25 }}>{item.value}</div> | |
310 | + <div style={{ flex: 18, textAlign: 'right' }}> | |
311 | + ¥ {item.totalPayment.toFixed(2)} | |
312 | + </div> | |
313 | + <div style={{ flex: 18, textAlign: 'right' }}> | |
314 | + ¥ {item.invoiceIssuedAmount.toFixed(2)} | |
315 | + </div> | |
316 | + <div style={{ flex: 39, textAlign: 'right' }}> | |
317 | + <ProFormMoney | |
318 | + name={`invoiceAvailableAmount_${item.value}`} | |
319 | + locale="zh-CN" | |
320 | + fieldProps={{ | |
321 | + precision: 2, | |
322 | + style: { width: '70%' }, | |
323 | + }} | |
324 | + initialValue={item.availableAmount} | |
325 | + rules={[ | |
326 | + { required: true, message: '请填写可开票金额!' }, | |
327 | + { | |
328 | + validator: (_, value) => { | |
329 | + if (value > maxAvailable) { | |
330 | + return Promise.reject( | |
331 | + `可开票金额不能超过${maxAvailable.toFixed(2)}`, | |
332 | + ); | |
333 | + } else if (value === 0) { | |
334 | + return Promise.reject(`可开票金额不能为0`); | |
335 | + } | |
336 | + return Promise.resolve(); | |
337 | + }, | |
338 | + }, | |
339 | + ]} | |
340 | + /> | |
341 | + </div> | |
342 | + </div> | |
343 | + ); | |
203 | 344 | })} |
204 | - deleteIconProps={false} | |
205 | - copyIconProps={false} | |
206 | - > | |
207 | - <ProFormGroup key="group"> | |
208 | - <ProFormText readonly={true} name="value" label="" /> | |
209 | - </ProFormGroup> | |
210 | - </ProFormList> | |
345 | + </div> | |
211 | 346 | {/*<ProFormSelect |
212 | 347 | name="ReissueInvoiceRecordIds" |
213 | 348 | label="重开的发票" |
... | ... | @@ -320,17 +455,6 @@ export default ({ |
320 | 455 | rules={[{ required: true, message: '请选择银行联行号!' }]} |
321 | 456 | /> |
322 | 457 | <ProFormSelect |
323 | - name="invoicingType" | |
324 | - label="开具类型" | |
325 | - request={async () => { | |
326 | - let invoicingTypeRet = await postServiceConstInvoicingType(); | |
327 | - let options = enumToSelect(invoicingTypeRet.data); | |
328 | - return options; | |
329 | - }} | |
330 | - placeholder="请选择开具类型" | |
331 | - rules={[{ required: true, message: '请选择开具类型!' }]} | |
332 | - /> | |
333 | - <ProFormSelect | |
334 | 458 | name="type" |
335 | 459 | label="开票类型" |
336 | 460 | placeholder="请选择开票类型" | ... | ... |
src/pages/Order/OrderList/OrderDrawer.tsx
... | ... | @@ -156,7 +156,7 @@ export default ({ onClose, data, subOrders, orderOptType }) => { |
156 | 156 | let entity_number = await getTeacherCustomFieldNumber(); |
157 | 157 | |
158 | 158 | //在单位详细信息中拿到自定义字段的值 |
159 | - let customField = res?.custom_field; | |
159 | + let customField = res?.customField; | |
160 | 160 | if (customField) { |
161 | 161 | let teacherName = customField[entity_number]; |
162 | 162 | //填充到课题组老师表单字段中 |
... | ... | @@ -309,22 +309,22 @@ export default ({ onClose, data, subOrders, orderOptType }) => { |
309 | 309 | |
310 | 310 | copyData.customerNameString = copyData.customerName; |
311 | 311 | |
312 | - // 清空支付方式和支付渠道 | |
313 | - if ( | |
314 | - copyData.paymentChannel === 'TAOBAO' || | |
315 | - [ | |
316 | - 'UNPAID', | |
317 | - 'TAOBAO_ORDER_HAS_BEEN_PAID', | |
318 | - 'OFFICIAL_WEBSITE_ORDER_HAS_BEEN_PAID', | |
319 | - 'WITHHOLDING_ADVANCE_DEPOSIT', | |
320 | - 'PLATFORM_SETTLEMENT', | |
321 | - 'PAYMENT_RECEIPT', | |
322 | - 'PREPAID_NO_NEED_SEND', | |
323 | - ].includes(copyData.paymentMethod) | |
324 | - ) { | |
325 | - copyData.paymentMethod = ''; | |
326 | - copyData.paymentChannel = ''; | |
327 | - } | |
312 | + // // 清空支付方式和支付渠道 | |
313 | + // if ( | |
314 | + // copyData.paymentChannel === 'TAOBAO' || | |
315 | + // [ | |
316 | + // 'UNPAID', | |
317 | + // 'TAOBAO_ORDER_HAS_BEEN_PAID', | |
318 | + // 'OFFICIAL_WEBSITE_ORDER_HAS_BEEN_PAID', | |
319 | + // 'WITHHOLDING_ADVANCE_DEPOSIT', | |
320 | + // 'PLATFORM_SETTLEMENT', | |
321 | + // 'PAYMENT_RECEIPT', | |
322 | + // 'PREPAID_NO_NEED_SEND', | |
323 | + // ].includes(copyData.paymentMethod) | |
324 | + // ) { | |
325 | + // copyData.paymentMethod = ''; | |
326 | + // copyData.paymentChannel = ''; | |
327 | + // } | |
328 | 328 | |
329 | 329 | setPaymentMethod(copyData.paymentMethod); |
330 | 330 | |
... | ... | @@ -396,7 +396,18 @@ export default ({ onClose, data, subOrders, orderOptType }) => { |
396 | 396 | */ |
397 | 397 | function getInvoicingSelect() { |
398 | 398 | if (optType('edit') || optType('after-sales-check')) { |
399 | - return enumToSelect(INVOCING_STATUS_OPTIONS_OLD); | |
399 | + const options = enumToSelect(INVOCING_STATUS_OPTIONS_OLD); | |
400 | + | |
401 | + // 永远禁止选择专票和普票,但保留这些选项用于显示历史数据 | |
402 | + return options.map((option: any) => { | |
403 | + if ( | |
404 | + option.value === 'SPECIALLY_INVOICED' || | |
405 | + option.value === 'COMMON_INVOICED' | |
406 | + ) { | |
407 | + return { ...option, disabled: true }; | |
408 | + } | |
409 | + return option; | |
410 | + }); | |
400 | 411 | } |
401 | 412 | return enumToSelect(INVOCING_STATUS_OPTIONS); |
402 | 413 | } |
... | ... | @@ -437,6 +448,34 @@ export default ({ onClose, data, subOrders, orderOptType }) => { |
437 | 448 | if (optType('add')) { |
438 | 449 | form.resetFields(['list']); |
439 | 450 | } |
451 | + | |
452 | + // 如果是复制操作,检查销售代码是否为淘宝相关代码 | |
453 | + if (optType('copy')) { | |
454 | + const salesCode = data?.salesCode; | |
455 | + const isTaobaoSalesCode = [ | |
456 | + 'TB', | |
457 | + 'TBC', | |
458 | + 'HCTB', | |
459 | + '淘宝', | |
460 | + 'TAOBAO', | |
461 | + '新能源材料网', | |
462 | + 'scilab固态电解质商城', | |
463 | + 'T-ACG', | |
464 | + 'ALBB', | |
465 | + ].includes(salesCode); | |
466 | + | |
467 | + if (isTaobaoSalesCode) { | |
468 | + // 锁定支付渠道和支付方式,但保留原有值 | |
469 | + setPaymentChannelDisabled(true); | |
470 | + setPaymentMethodDisabled(true); | |
471 | + | |
472 | + // 确保控制台日志 | |
473 | + console.log('复制淘宝订单,锁定支付渠道和支付方式:', { | |
474 | + paymentChannel: data?.paymentChannel, | |
475 | + paymentMethod: data?.paymentMethod, | |
476 | + }); | |
477 | + } | |
478 | + } | |
440 | 479 | }, [data]); |
441 | 480 | |
442 | 481 | /** |
... | ... | @@ -1152,35 +1191,65 @@ export default ({ onClose, data, subOrders, orderOptType }) => { |
1152 | 1191 | autoFillSalesInfo(option); |
1153 | 1192 | |
1154 | 1193 | // 检查是否是特殊的淘宝销售代码 |
1155 | - const isTaobaoSalesCode = ['TB', 'TBC', 'HCTB'].includes(value); | |
1156 | - | |
1157 | - // 清空支付渠道和支付方式 | |
1158 | - form.setFieldsValue({ | |
1159 | - paymentChannel: undefined, | |
1160 | - paymentMethod: undefined, | |
1161 | - }); | |
1162 | - | |
1163 | - // 重置支付渠道和支付方式的禁用状态 | |
1164 | - setPaymentChannelDisabled(false); | |
1165 | - setPaymentMethodDisabled(false); | |
1166 | - | |
1167 | - if (isTaobaoSalesCode) { | |
1168 | - // 设置支付渠道为淘宝并锁定 | |
1169 | - form.setFieldsValue({ paymentChannel: 'TAOBAO' }); | |
1194 | + const isTaobaoSalesCode = [ | |
1195 | + 'TB', | |
1196 | + 'TBC', | |
1197 | + 'HCTB', | |
1198 | + '淘宝', | |
1199 | + 'TAOBAO', | |
1200 | + '新能源材料网', | |
1201 | + 'scilab固态电解质商城', | |
1202 | + 'T-ACG', | |
1203 | + 'ALBB', | |
1204 | + ].includes(value); | |
1205 | + | |
1206 | + // 如果是复制操作且是淘宝销售代码,锁定支付方式和支付渠道,不清空值 | |
1207 | + if (optType('copy') && isTaobaoSalesCode) { | |
1208 | + // 保留当前的支付渠道和支付方式值,只锁定选择器 | |
1170 | 1209 | setPaymentChannelDisabled(true); |
1171 | - | |
1172 | - // 支付方式默认锁定为预付 | |
1173 | - form.setFieldsValue({ paymentMethod: 'PAYMENT_IN_ADVANCE' }); | |
1174 | - setPaymentMethod('PAYMENT_IN_ADVANCE'); | |
1175 | 1210 | setPaymentMethodDisabled(true); |
1176 | - } else { | |
1177 | - // 如果不是淘宝销售代码,解除锁定 | |
1178 | - setPaymentChannelDisabled(false); | |
1179 | - // 只有当前支付渠道不是扣预存时才解除付款方式的锁定 | |
1211 | + | |
1212 | + // 如果当前没有值,则设置默认值 | |
1180 | 1213 | const currentPaymentChannel = |
1181 | 1214 | form.getFieldValue('paymentChannel'); |
1182 | - if (currentPaymentChannel !== 'BALANCE') { | |
1183 | - setPaymentMethodDisabled(false); | |
1215 | + if (!currentPaymentChannel) { | |
1216 | + form.setFieldsValue({ paymentChannel: 'TAOBAO' }); | |
1217 | + } | |
1218 | + | |
1219 | + const currentPaymentMethod = form.getFieldValue('paymentMethod'); | |
1220 | + if (!currentPaymentMethod) { | |
1221 | + form.setFieldsValue({ paymentMethod: 'PAYMENT_IN_TAOBAO' }); | |
1222 | + setPaymentMethod('PAYMENT_IN_TAOBAO'); | |
1223 | + } | |
1224 | + } else if (!optType('copy')) { | |
1225 | + // 非复制操作时,清空支付渠道和支付方式 | |
1226 | + form.setFieldsValue({ | |
1227 | + paymentChannel: undefined, | |
1228 | + paymentMethod: undefined, | |
1229 | + }); | |
1230 | + | |
1231 | + // 重置支付渠道和支付方式的禁用状态 | |
1232 | + setPaymentChannelDisabled(false); | |
1233 | + setPaymentMethodDisabled(false); | |
1234 | + | |
1235 | + if (isTaobaoSalesCode) { | |
1236 | + // 设置支付渠道为淘宝并锁定 | |
1237 | + form.setFieldsValue({ paymentChannel: 'TAOBAO' }); | |
1238 | + setPaymentChannelDisabled(true); | |
1239 | + | |
1240 | + // 支付方式默认锁定为淘宝 | |
1241 | + form.setFieldsValue({ paymentMethod: 'PAYMENT_IN_TAOBAO' }); | |
1242 | + setPaymentMethod('PAYMENT_IN_TAOBAO'); | |
1243 | + setPaymentMethodDisabled(true); | |
1244 | + } else { | |
1245 | + // 如果不是淘宝销售代码,解除锁定 | |
1246 | + setPaymentChannelDisabled(false); | |
1247 | + // 只有当前支付渠道不是扣预存时才解除付款方式的锁定 | |
1248 | + const currentPaymentChannel = | |
1249 | + form.getFieldValue('paymentChannel'); | |
1250 | + if (currentPaymentChannel !== 'BALANCE') { | |
1251 | + setPaymentMethodDisabled(false); | |
1252 | + } | |
1184 | 1253 | } |
1185 | 1254 | } |
1186 | 1255 | }} |
... | ... | @@ -1845,22 +1914,112 @@ export default ({ onClose, data, subOrders, orderOptType }) => { |
1845 | 1914 | disabled={optType('after-sales-check')} |
1846 | 1915 | /> |
1847 | 1916 | </div> |
1917 | + <ProFormSelect | |
1918 | + placeholder="请输入支付方式" | |
1919 | + name="paymentMethod" | |
1920 | + width="lg" | |
1921 | + key="paymentMethod" | |
1922 | + label="支付方式" | |
1923 | + onChange={(val: any) => { | |
1924 | + setPaymentMethod(val); | |
1925 | + }} | |
1926 | + options={(() => { | |
1927 | + // 使用Set记录已经处理过的选项值,避免重复 | |
1928 | + const processedValues = new Set(); | |
1929 | + const finalOptions = []; | |
1930 | + | |
1931 | + // 先处理默认可选项 | |
1932 | + enumToSelect(PAYMENT_METHOD_OPTIONS_4_ADD).forEach((option) => { | |
1933 | + // 将淘宝选项设置为禁用状态,使其无法手动选择 | |
1934 | + if (option.value === 'PAYMENT_IN_TAOBAO') { | |
1935 | + finalOptions.push({ ...option, disabled: true }); | |
1936 | + } else { | |
1937 | + finalOptions.push(option); | |
1938 | + } | |
1939 | + processedValues.add(option.value); | |
1940 | + }); | |
1941 | + | |
1942 | + // 添加强制禁用项,但只添加尚未存在的选项 | |
1943 | + const disabledOptions = [ | |
1944 | + { | |
1945 | + label: '淘宝订单已付款', | |
1946 | + value: 'TAOBAO_ORDER_HAS_BEEN_PAID', | |
1947 | + disabled: true, | |
1948 | + }, | |
1949 | + { | |
1950 | + label: '官网已付', | |
1951 | + value: 'OFFICIAL_WEBSITE_ORDER_HAS_BEEN_PAID', | |
1952 | + disabled: true, | |
1953 | + }, | |
1954 | + { label: '淘宝', value: 'PAYMENT_IN_TAOBAO', disabled: true }, | |
1955 | + { | |
1956 | + label: '预付', | |
1957 | + value: 'WITHHOLDING_ADVANCE_DEPOSIT', | |
1958 | + disabled: true, | |
1959 | + }, | |
1960 | + { | |
1961 | + label: '平台结算', | |
1962 | + value: 'PLATFORM_SETTLEMENT', | |
1963 | + disabled: true, | |
1964 | + }, | |
1965 | + { | |
1966 | + label: '预存款无需发货', | |
1967 | + value: 'PREPAID_NO_NEED_SEND', | |
1968 | + disabled: true, | |
1969 | + }, | |
1970 | + ]; | |
1971 | + | |
1972 | + disabledOptions.forEach((option) => { | |
1973 | + if (!processedValues.has(option.value)) { | |
1974 | + finalOptions.push(option); | |
1975 | + processedValues.add(option.value); | |
1976 | + } | |
1977 | + }); | |
1848 | 1978 | |
1979 | + return finalOptions; | |
1980 | + })()} | |
1981 | + rules={[{ required: true, message: '支付方式必填' }]} | |
1982 | + disabled={optType('after-sales-check') || paymentMethodDisabled} | |
1983 | + fieldProps={{ | |
1984 | + style: paymentMethodDisabled ? { backgroundColor: '#f5f5f5' } : {}, | |
1985 | + }} | |
1986 | + /> | |
1849 | 1987 | <ProFormSelect |
1850 | 1988 | placeholder="请输入支付渠道" |
1851 | 1989 | name="paymentChannel" |
1852 | 1990 | width="lg" |
1853 | 1991 | key="paymentChannel" |
1854 | 1992 | label="支付渠道" |
1855 | - options={enumToSelect(PAYMENT_CHANNEL_OPTIONS).map((option) => { | |
1856 | - // 将淘宝选项设置为禁用状态,使其无法手动选择 | |
1857 | - if (option.value === 'TAOBAO') { | |
1858 | - return { ...option, disabled: true }; | |
1859 | - } | |
1860 | - return option; | |
1861 | - })} | |
1993 | + options={(() => { | |
1994 | + // 获取当前支付方式 | |
1995 | + const currentPaymentMethod = | |
1996 | + paymentMethod || form.getFieldValue('paymentMethod'); | |
1997 | + | |
1998 | + return enumToSelect(PAYMENT_CHANNEL_OPTIONS).map((option) => { | |
1999 | + // 将淘宝选项设置为禁用状态,使其无法手动选择 | |
2000 | + if (option.value === 'TAOBAO') { | |
2001 | + return { ...option, disabled: true }; | |
2002 | + } | |
2003 | + | |
2004 | + // 如果选择了"预存款无需发货",禁用"平台结算"和"官网已付"选项 | |
2005 | + if (currentPaymentMethod === 'PREPAID_NO_NEED_SEND') { | |
2006 | + if ( | |
2007 | + option.value === 'PLATFORM' || | |
2008 | + option.value === 'OFFICIAL_WEBSITE' || | |
2009 | + option.value === 'BALANCE' | |
2010 | + ) { | |
2011 | + return { ...option, disabled: true }; | |
2012 | + } | |
2013 | + } | |
2014 | + | |
2015 | + return option; | |
2016 | + }); | |
2017 | + })()} | |
1862 | 2018 | rules={[{ required: true, message: '支付渠道必填' }]} |
1863 | 2019 | disabled={optType('after-sales-check') || paymentChannelDisabled} |
2020 | + fieldProps={{ | |
2021 | + style: paymentChannelDisabled ? { backgroundColor: '#f5f5f5' } : {}, | |
2022 | + }} | |
1864 | 2023 | onChange={(val: any) => { |
1865 | 2024 | // 根据支付渠道设置不同的支付方式 |
1866 | 2025 | if (val === 'BALANCE') { |
... | ... | @@ -1871,56 +2030,16 @@ export default ({ onClose, data, subOrders, orderOptType }) => { |
1871 | 2030 | }); |
1872 | 2031 | setPaymentMethod('WITHHOLDING_ADVANCE_DEPOSIT'); |
1873 | 2032 | } else if (val === 'TAOBAO') { |
1874 | - // 支付渠道为淘宝时,支付方式设置为预付 | |
2033 | + // 支付渠道为淘宝时,支付方式设置为淘宝 | |
1875 | 2034 | setPaymentMethodDisabled(true); |
1876 | - form.setFieldsValue({ paymentMethod: 'PAYMENT_IN_ADVANCE' }); | |
1877 | - setPaymentMethod('PAYMENT_IN_ADVANCE'); | |
2035 | + form.setFieldsValue({ paymentMethod: 'PAYMENT_IN_TAOBAO' }); | |
2036 | + setPaymentMethod('PAYMENT_IN_TAOBAO'); | |
1878 | 2037 | } else { |
1879 | 2038 | // 支付渠道修改为其他的去除锁定状态 |
1880 | 2039 | setPaymentMethodDisabled(false); |
1881 | 2040 | } |
1882 | 2041 | }} |
1883 | 2042 | /> |
1884 | - <ProFormSelect | |
1885 | - placeholder="请输入支付方式" | |
1886 | - name="paymentMethod" | |
1887 | - width="lg" | |
1888 | - key="paymentMethod" | |
1889 | - label="支付方式" | |
1890 | - onChange={(val: any) => { | |
1891 | - setPaymentMethod(val); | |
1892 | - }} | |
1893 | - options={[ | |
1894 | - // 默认可选项 | |
1895 | - ...enumToSelect(PAYMENT_METHOD_OPTIONS_4_ADD), | |
1896 | - // 强制禁用项 | |
1897 | - { label: '未付款', value: 'UNPAID', disabled: true }, | |
1898 | - { | |
1899 | - label: '淘宝订单已付款', | |
1900 | - value: 'TAOBAO_ORDER_HAS_BEEN_PAID', | |
1901 | - disabled: true, | |
1902 | - }, | |
1903 | - { | |
1904 | - label: '官网订单已付款', | |
1905 | - value: 'OFFICIAL_WEBSITE_ORDER_HAS_BEEN_PAID', | |
1906 | - disabled: true, | |
1907 | - }, | |
1908 | - { | |
1909 | - label: '预付', | |
1910 | - value: 'WITHHOLDING_ADVANCE_DEPOSIT', | |
1911 | - disabled: true, | |
1912 | - }, | |
1913 | - { label: '平台结算', value: 'PLATFORM_SETTLEMENT', disabled: true }, | |
1914 | - { label: '已回款', value: 'PAYMENT_RECEIPT', disabled: true }, | |
1915 | - { | |
1916 | - label: '预存款无需发货', | |
1917 | - value: 'PREPAID_NO_NEED_SEND', | |
1918 | - disabled: true, | |
1919 | - }, | |
1920 | - ]} | |
1921 | - rules={[{ required: true, message: '支付方式必填' }]} | |
1922 | - disabled={optType('after-sales-check') || paymentMethodDisabled} | |
1923 | - /> | |
1924 | 2043 | {/* 隐藏字段用于存储真实UID和privatePocket标志 */} |
1925 | 2044 | <ProFormText name="realPrepaidUid" hidden /> |
1926 | 2045 | <ProFormText name="privatePocket" hidden /> |
... | ... | @@ -2050,7 +2169,7 @@ export default ({ onClose, data, subOrders, orderOptType }) => { |
2050 | 2169 | placeholder="选择是否需要开票" |
2051 | 2170 | name="invoicingStatus" |
2052 | 2171 | width="lg" |
2053 | - key="invoicingStatus" | |
2172 | + key={`invoicingStatus-${invoicingStatus}`} | |
2054 | 2173 | label="是否需要开票" |
2055 | 2174 | options={getInvoicingSelect()} |
2056 | 2175 | disabled={optType('after-sales-check')} | ... | ... |