Commit c89daffdcb177f6131e3fccdb8780f44b1039ceb

Authored by 柏杨
2 parents 1243cef9 4dc9675c

Merge branch 'bugfix-invoicestatus' into dev

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 }) =&gt; {
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 &#39;@/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 }) =&gt; {
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 }) =&gt; {
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 &#39;@/constants/enum&#39;;
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 &#39;react&#39;;
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 = () =&gt; {
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 = () =&gt; {
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 = () =&gt; {
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 = () =&gt; {
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 = () =&gt; {
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 = () =&gt; {
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 }) =&gt; {
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 }) =&gt; {
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 }) =&gt; {
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 }) =&gt; {
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 = () =&gt; {
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 = () =&gt; {
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 }) =&gt; {
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&lt;
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&lt;
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&lt;
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 }) =&gt; {
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 }) =&gt; {
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 }) =&gt; {
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 }) =&gt; {
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 }) =&gt; {
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 }) =&gt; {
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 }) =&gt; {
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 }) =&gt; {
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')}
... ...