Commit 4ef9f6a06eaea3e40c3f288e0b1eafe948b3afaa

Authored by 曾国涛
2 parents 95615f10 d38ab3b5

Merge branch 'veri'

#### 1. 优化表格列配置
在`AddBankStatementModal`组件中,将‘编号’列配置从表格中隐藏,并确保‘收款方’列在搜索时隐藏,以优化列的显示和搜索体验。
#### 2. 精简用户列表API请求
在`ResearchGroupAddModal`组件中,优化用户列表API请求参数构造逻辑,仅在存在`accountIds`或`phones`时才包含这些参数,从而提高API请求效率。```在发票注销模态框中启用列标题和内容的自动换行

通过在发票数据表格的各个列定义中添加`ellipsis`属性,确保当列内容或标题超过列宽时能够正确显示省略号,从而改善发票注销模态框的用户体验。此变更适用于发票和流水号相关的所有列
src/models/enum.ts 0 → 100644
  1 +import { postServiceConstPayees } from '@/services';
  2 +import { useCallback } from 'react';
  3 +
  4 +export default () => {
  5 + const getPayees = useCallback(async () => {
  6 + const result = await postServiceConstPayees();
  7 + return result.data;
  8 + }, []);
  9 + return { getPayees };
  10 +};
src/pages/Invoice/Invoice/components/AddBankStatementModal.tsx 0 → 100644
  1 +import { postServiceBankStatementQueryBankStatement } from '@/services';
  2 +import { ModalForm, ProCard, ProTable } from '@ant-design/pro-components';
  3 +import { Button, Divider, Flex, Form, Tag } from 'antd';
  4 +import React from 'react';
  5 +
  6 +export default ({ getRows, onFinish }) => {
  7 + const [form] = Form.useForm();
  8 + const [selectedRows, setSelectedRows] = React.useState<any[]>([]);
  9 +
  10 + const columns = [
  11 + {
  12 + title: '编号',
  13 + hideInSearch: true,
  14 + dataIndex: 'id',
  15 + },
  16 + {
  17 + title: '编号',
  18 + hideInTable: true,
  19 + dataIndex: 'id',
  20 + },
  21 + {
  22 + title: '流水号',
  23 + hideInSearch: true,
  24 + dataIndex: 'serialNumber',
  25 + },
  26 + {
  27 + title: '收款时间',
  28 + dataIndex: 'collectionDatetime',
  29 + hideInSearch: true,
  30 + valueType: 'date',
  31 + },
  32 + {
  33 + title: '收款方',
  34 + hideInSearch: true,
  35 + dataIndex: 'payeeText',
  36 + },
  37 + {
  38 + title: '付款方',
  39 + hideInSearch: true,
  40 + dataIndex: 'payer',
  41 + },
  42 + {
  43 + title: '金额',
  44 + dataIndex: 'amount',
  45 + hideInSearch: true,
  46 + valueType: 'money',
  47 + },
  48 + {
  49 + title: '操作',
  50 + valueType: 'option',
  51 + width: 200,
  52 + render: (text, record) => [
  53 + <a
  54 + key="selected"
  55 + onClick={() => {
  56 + let selectedRowsCopy;
  57 + if (!selectedRows || !Array.isArray(selectedRows)) {
  58 + selectedRowsCopy = []; // 初始化为一个空数组
  59 + } else {
  60 + selectedRowsCopy = selectedRows;
  61 + }
  62 + if (!selectedRows?.map((item) => item.id).includes(record.id)) {
  63 + setSelectedRows([...selectedRowsCopy, record]);
  64 + } else {
  65 + setSelectedRows(
  66 + selectedRowsCopy.filter((item) => item.id !== record.id),
  67 + );
  68 + }
  69 + }}
  70 + >
  71 + {selectedRows?.map((item) => item.id).includes(record.id)
  72 + ? '取消选中'
  73 + : '选中'}
  74 + </a>,
  75 + ],
  76 + },
  77 + ];
  78 + return (
  79 + <ModalForm
  80 + title="添加银行流水"
  81 + trigger={<Button type="primary">添加</Button>}
  82 + form={form}
  83 + autoFocusFirstInput
  84 + modalProps={{
  85 + destroyOnClose: true,
  86 + onCancel: () => console.log('run'),
  87 + }}
  88 + onOpenChange={(visible) => {
  89 + if (visible) {
  90 + setSelectedRows(getRows());
  91 + }
  92 + }}
  93 + layout={'horizontal'}
  94 + width={1500}
  95 + submitTimeout={2000}
  96 + onFinish={async (values) => {
  97 + onFinish(selectedRows);
  98 + console.log(values);
  99 + return true;
  100 + }}
  101 + >
  102 + <Divider orientation="left" plain>
  103 + 已选中(合计:¥
  104 + {selectedRows?.reduce((acc, cur) => acc + cur.amount, 0)}元)
  105 + </Divider>
  106 + <ProCard className="mb-[16px]" bordered style={{}}>
  107 + <Flex wrap="wrap" gap="small">
  108 + {selectedRows?.map((item, i) => {
  109 + return (
  110 + <Tag
  111 + key={i + ''}
  112 + closable={true}
  113 + style={{ userSelect: 'none' }}
  114 + color="blue"
  115 + onClose={(e) => {
  116 + e.preventDefault(); //需要加上这句代码,不然删除tag时,当前tag的下一个tag会被设置ant-tag-hidden
  117 + }}
  118 + >
  119 + <span>{item.serialNumber}</span>
  120 + </Tag>
  121 + );
  122 + })}
  123 + </Flex>
  124 + </ProCard>
  125 + <ProTable
  126 + columns={columns}
  127 + request={async (params) => {
  128 + const res = await postServiceBankStatementQueryBankStatement({
  129 + data: {
  130 + ...params,
  131 + writeOffIdIsNull: true,
  132 + },
  133 + });
  134 + return res.data;
  135 + }}
  136 + options={false}
  137 + rowKey="id"
  138 + headerTitle="添加银行流水"
  139 + />
  140 + </ModalForm>
  141 + );
  142 +};
src/pages/Invoice/Invoice/components/AddInvoiceModal.tsx 0 → 100644
  1 +import { postServiceInvoiceQueryInvoice } from '@/services';
  2 +import { enumToSelect } from '@/utils';
  3 +import { ModalForm, ProCard, ProTable } from '@ant-design/pro-components';
  4 +import { useModel } from '@umijs/max';
  5 +import { Button, Divider, Flex, Form, Tag } from 'antd';
  6 +import React from 'react';
  7 +
  8 +export default ({ getRows, onFinish }) => {
  9 + const [form] = Form.useForm();
  10 + const [selectedRows, setSelectedRows] = React.useState<any[]>([]);
  11 + const { getPayees } = useModel('enum');
  12 + const columns = [
  13 + {
  14 + title: '发票号码',
  15 + hideInSearch: true,
  16 + dataIndex: 'invoiceNumber',
  17 + },
  18 + {
  19 + title: '发票号码',
  20 + hideInTable: true,
  21 + dataIndex: 'invoiceNumber',
  22 + },
  23 + {
  24 + title: '收款方',
  25 + hideInTable: true,
  26 + valueType: 'select',
  27 + dataIndex: 'payee',
  28 + request: async () => {
  29 + const payees = await getPayees();
  30 + return enumToSelect(payees);
  31 + },
  32 + },
  33 + {
  34 + title: '收款方',
  35 + hideInSearch: true,
  36 + dataIndex: 'payeeText',
  37 + },
  38 + {
  39 + title: '付款方',
  40 + hideInSearch: true,
  41 + dataIndex: 'purchaser',
  42 + },
  43 + {
  44 + title: '付款方',
  45 + hideInTable: true,
  46 + dataIndex: 'purchaser',
  47 + },
  48 + {
  49 + title: '金额',
  50 + dataIndex: 'money',
  51 + hideInSearch: true,
  52 + valueType: 'money',
  53 + },
  54 + {
  55 + title: '日期',
  56 + dataIndex: 'invoicingTime',
  57 + hideInSearch: true,
  58 + valueType: 'date',
  59 + },
  60 + {
  61 + title: '操作',
  62 + valueType: 'option',
  63 + width: 200,
  64 + render: (text, record) => [
  65 + <a
  66 + key="selected"
  67 + onClick={() => {
  68 + let selectedRowsCopy;
  69 + if (!selectedRows || !Array.isArray(selectedRows)) {
  70 + selectedRowsCopy = []; // 初始化为一个空数组
  71 + } else {
  72 + selectedRowsCopy = selectedRows;
  73 + }
  74 + if (!selectedRows?.map((item) => item.id).includes(record.id)) {
  75 + setSelectedRows([...selectedRowsCopy, record]);
  76 + } else {
  77 + setSelectedRows(
  78 + selectedRowsCopy.filter((item) => item.id !== record.id),
  79 + );
  80 + }
  81 + }}
  82 + >
  83 + {selectedRows?.map((item) => item.id).includes(record.id)
  84 + ? '取消选中'
  85 + : '选中'}
  86 + </a>,
  87 + ],
  88 + },
  89 + ];
  90 + return (
  91 + <ModalForm
  92 + title="添加发票"
  93 + trigger={<Button type="primary">添加</Button>}
  94 + form={form}
  95 + autoFocusFirstInput
  96 + onOpenChange={(visible) => {
  97 + if (visible) {
  98 + setSelectedRows(getRows());
  99 + }
  100 + }}
  101 + modalProps={{
  102 + destroyOnClose: true,
  103 +
  104 + onCancel: () => console.log('run'),
  105 + }}
  106 + layout={'horizontal'}
  107 + width={1500}
  108 + submitTimeout={2000}
  109 + onFinish={async () => {
  110 + onFinish(selectedRows);
  111 + return true;
  112 + }}
  113 + >
  114 + <Divider orientation="left" plain>
  115 + 已选中(合计:¥{selectedRows?.reduce((acc, cur) => acc + cur.money, 0)}
  116 + )
  117 + </Divider>
  118 + <ProCard className="mb-[16px]" bordered style={{}}>
  119 + <Flex wrap="wrap" gap="small">
  120 + {selectedRows?.map((item, i) => {
  121 + return (
  122 + <Tag
  123 + key={i}
  124 + closable={true}
  125 + style={{ userSelect: 'none' }}
  126 + color="blue"
  127 + onClose={(e) => {
  128 + e.preventDefault(); //需要加上这句代码,不然删除tag时,当前tag的下一个tag会被设置ant-tag-hidden
  129 + }}
  130 + >
  131 + <span>{item.invoiceNumber}</span>
  132 + </Tag>
  133 + );
  134 + })}
  135 + </Flex>
  136 + </ProCard>
  137 + <ProTable
  138 + columns={columns}
  139 + request={async (params) => {
  140 + const res = await postServiceInvoiceQueryInvoice({
  141 + data: {
  142 + ...params,
  143 + writeOffIdIsNull: true,
  144 + },
  145 + });
  146 + return res.data;
  147 + }}
  148 + options={false}
  149 + rowKey="id"
  150 + headerTitle="添加发票"
  151 + />
  152 + </ModalForm>
  153 + );
  154 +};
src/pages/Invoice/Invoice/components/InvoiceDetailImportModal.tsx deleted 100644 → 0
1 -import { RESPONSE_CODE } from '@/constants/enum';  
2 -import { postServiceInvoiceImportInvoiceDetails } from '@/services';  
3 -import { ModalForm, ProFormUploadDragger } from '@ant-design/pro-components';  
4 -import { Button, Form, message } from 'antd';  
5 -  
6 -export default ({ recordId }) => {  
7 - const [form] = Form.useForm();  
8 - return (  
9 - <ModalForm  
10 - title="新建表单"  
11 - trigger={<Button type="primary">导入明细</Button>}  
12 - form={form}  
13 - autoFocusFirstInput  
14 - modalProps={{  
15 - destroyOnClose: true,  
16 - onCancel: () => console.log('run'),  
17 - }}  
18 - submitTimeout={2000}  
19 - onFinish={async (values) => {  
20 - const formData = new FormData();  
21 - // console.log(fileList[0] as RcFile)  
22 - // formData.append('file', fileList[0] as RcFile);  
23 - formData.append('invoiceRecordId', recordId);  
24 - formData.append('detailsExcel', values.detailsExcel[0].originFileObj);  
25 - // You can use any AJAX library you like  
26 - const res = await postServiceInvoiceImportInvoiceDetails({  
27 - data: formData,  
28 - headers: {  
29 - 'Content-Type':  
30 - 'multipart/form-data; boundary=----WebKitFormBoundarynl6gT1BKdPWIejNq',  
31 - },  
32 - });  
33 - if (res.result === RESPONSE_CODE.SUCCESS) {  
34 - message.success('导入成功');  
35 - return true;  
36 - }  
37 - }}  
38 - >  
39 - <ProFormUploadDragger name="detailsExcel" label="导入明细表" />  
40 - </ModalForm>  
41 - );  
42 -};  
src/pages/Invoice/Invoice/components/InvoiceDetailTable.tsx deleted 100644 → 0
1 -import InvoiceDetailImportModal from '@/pages/Invoice/Invoice/components/InvoiceDetailImportModal';  
2 -import { InvoiceProjectSelect } from '@/pages/Invoice/Invoice/components/InvoiceProjectSelect';  
3 -import {  
4 - ActionType,  
5 - EditableProTable,  
6 - ProCard,  
7 - ProColumns,  
8 - ProFormField,  
9 -} from '@ant-design/pro-components';  
10 -import { useEffect, useRef, useState } from 'react';  
11 -  
12 -export default ({ recordId, details, updateDetails, readOnly }) => {  
13 - const [editableKeys, setEditableRowKeys] = useState([]);  
14 - const ref = useRef<ActionType>();  
15 - useEffect(() => {  
16 - updateDetails(details);  
17 - }, []);  
18 -  
19 - useEffect(() => {  
20 - setEditableRowKeys(details?.map((item) => item.tid));  
21 - }, [details]);  
22 - const columns: ProColumns[] = [  
23 - {  
24 - title: '项目名称',  
25 - dataIndex: 'projectName',  
26 - width: 200,  
27 - ellipsis: true,  
28 - readonly: readOnly,  
29 - renderFormItem: () => {  
30 - return <InvoiceProjectSelect readOnly={readOnly} />;  
31 - },  
32 - },  
33 - {  
34 - title: '规格型号',  
35 - readonly: readOnly,  
36 - dataIndex: 'specification',  
37 - valueType: 'text',  
38 - ellipsis: true,  
39 - },  
40 - {  
41 - title: '单位',  
42 - readonly: readOnly,  
43 - dataIndex: 'unit',  
44 - valueType: 'text',  
45 - ellipsis: true,  
46 - },  
47 - {  
48 - title: '数量',  
49 - readonly: readOnly,  
50 - dataIndex: 'quantity',  
51 - valueType: 'digit',  
52 - ellipsis: true,  
53 - },  
54 - {  
55 - title: '单价',  
56 - readonly: readOnly,  
57 - dataIndex: 'price',  
58 - valueType: 'digit',  
59 - ellipsis: true,  
60 - },  
61 - {  
62 - title: '金额',  
63 - readonly: readOnly,  
64 - dataIndex: 'totalPrice',  
65 - valueType: 'digit',  
66 - ellipsis: true,  
67 - },  
68 - {  
69 - title: '税率/征收率',  
70 - readonly: true,  
71 - dataIndex: 'taxRate',  
72 - valueType: () => ({  
73 - type: 'percent',  
74 - }),  
75 - ellipsis: true,  
76 - },  
77 - {  
78 - title: '税额',  
79 - readonly: true,  
80 - dataIndex: 'taxPrice',  
81 - valueType: 'digit',  
82 - ellipsis: true,  
83 - },  
84 - {  
85 - title: '操作',  
86 - valueType: 'option',  
87 - width: 100,  
88 - render: () => {  
89 - return null;  
90 - },  
91 - },  
92 - ];  
93 -  
94 - return (  
95 - <>  
96 - <EditableProTable  
97 - columns={columns}  
98 - actionRef={ref}  
99 - rowKey="tid"  
100 - scroll={{  
101 - x: 960,  
102 - }}  
103 - value={details}  
104 - controlled={true}  
105 - recordCreatorProps={  
106 - readOnly  
107 - ? false  
108 - : {  
109 - newRecordType: 'dataSource',  
110 - record: () => ({  
111 - tid: Date.now(),  
112 - }),  
113 - }  
114 - }  
115 - toolBarRender={() => {  
116 - return [  
117 - <InvoiceDetailImportModal key={'import'} recordId={recordId} />,  
118 - ];  
119 - }}  
120 - editable={{  
121 - type: 'multiple',  
122 - editableKeys,  
123 - actionRender: (row, config, defaultDoms) => {  
124 - return [defaultDoms.delete];  
125 - },  
126 -  
127 - onValuesChange: (record, recordList) => {  
128 - //修改recordList中tid为record.tid的元素,将它的specification属性设置为invoiceProject的specification属性  
129 - const records = recordList.map((item) => {  
130 - return item;  
131 - });  
132 - updateDetails(records);  
133 - },  
134 - }}  
135 - />  
136 - {  
137 - <ProCard title="表格数据" headerBordered collapsible defaultCollapsed>  
138 - <ProFormField  
139 - ignoreFormItem  
140 - fieldProps={{  
141 - style: {  
142 - width: '100%',  
143 - },  
144 - }}  
145 - mode="read"  
146 - valueType="jsonCode"  
147 - text={JSON.stringify(details)}  
148 - />  
149 - </ProCard>  
150 - }  
151 - </>  
152 - );  
153 -};  
src/pages/Invoice/Invoice/components/InvoiceProjectSelect.tsx deleted 100644 → 0
1 -import { postServiceConstListInvoiceDetailNames } from '@/services';  
2 -import { Select, Tooltip } from 'antd';  
3 -import { useState } from 'react';  
4 -  
5 -export const InvoiceProjectSelect = ({ readOnly, value, onChange }) => {  
6 - const [options, setOptions] = useState<any[]>([]);  
7 - // 定义防抖函数  
8 - let timeoutId = null;  
9 - const fetchOptions = async (keywords) => {  
10 - clearTimeout(timeoutId);  
11 - timeoutId = setTimeout(async () => {  
12 - const res = await postServiceConstListInvoiceDetailNames({  
13 - data: {  
14 - nameLike: keywords,  
15 - },  
16 - });  
17 - const data = res.data;  
18 -  
19 - setOptions(  
20 - data.map((item) => {  
21 - console.log(item);  
22 - return {  
23 - key: item.id,  
24 - label:  
25 - '*' +  
26 - item.productAndServiceCatagoryAbbreviation +  
27 - '*' +  
28 - item?.name,  
29 - value:  
30 - '*' +  
31 - item.productAndServiceCatagoryAbbreviation +  
32 - '*' +  
33 - item?.name,  
34 - ...item,  
35 - };  
36 - }),  
37 - );  
38 - // 这里可以放置实际的搜索逻辑,比如发起网络请求等  
39 - }, 500); // 设置延迟时间,单位毫秒  
40 - };  
41 -  
42 - return readOnly ? (  
43 - <Tooltip title={value}>{value}</Tooltip>  
44 - ) : (  
45 - <Select  
46 - key="project"  
47 - /*readonly={readonly}*/  
48 - showSearch  
49 - placeholder="请选择开票项目"  
50 - filterOption={(input, option) => (option?.label ?? '').includes(input)}  
51 - onChange={(e) => {  
52 - onChange(e);  
53 - }}  
54 - defaultValue={value}  
55 - options={options}  
56 - onSearch={(e) => {  
57 - fetchOptions(e);  
58 - }}  
59 - />  
60 - );  
61 -};  
src/pages/Invoice/Invoice/components/InvoiceVerificationModal.tsx
1 -import ButtonConfirm from '@/components/ButtomConfirm';  
2 -import EllipsisDiv from '@/components/Div/EllipsisDiv';  
3 -import { RESPONSE_CODE } from '@/constants/enum';  
4 import { INVOCING_STATUS, PAYEE_OPTIONS } from '@/pages/Order/constant'; 1 import { INVOCING_STATUS, PAYEE_OPTIONS } from '@/pages/Order/constant';
5 -import {  
6 - postServiceInvoiceCancelInvoiceAndBankStatement,  
7 - postServiceInvoiceQueryInvoiceDetail,  
8 -} from '@/services';  
9 -import { enumValueToLabel, formatDateTime } from '@/utils'; 2 +import { postServiceInvoiceQueryInvoiceDetail } from '@/services';
  3 +import { enumValueToLabel } from '@/utils';
10 import { formatDate } from '@/utils/time'; 4 import { formatDate } from '@/utils/time';
11 -import { PlusOutlined } from '@ant-design/icons';  
12 -import {  
13 - ActionType,  
14 - ModalForm,  
15 - ProCard,  
16 - ProTable,  
17 -} from '@ant-design/pro-components'; 5 +import { ActionType, ModalForm, ProCard } from '@ant-design/pro-components';
18 import { 6 import {
19 Button, 7 Button,
20 Descriptions, 8 Descriptions,
@@ -22,10 +10,8 @@ import { @@ -22,10 +10,8 @@ import {
22 Divider, 10 Divider,
23 Flex, 11 Flex,
24 Form, 12 Form,
25 - message,  
26 } from 'antd'; 13 } from 'antd';
27 import { useEffect, useRef, useState } from 'react'; 14 import { useEffect, useRef, useState } from 'react';
28 -import { BANK_STATEMENT_COLUMNS, INVOICE_STATUS } from '../../constant';  
29 import '../index.less'; 15 import '../index.less';
30 import BankChooseModal from './BankChooseModal'; 16 import BankChooseModal from './BankChooseModal';
31 17
@@ -34,7 +20,7 @@ export default ({ invoiceId, setVisible, onClose }) =&gt; { @@ -34,7 +20,7 @@ export default ({ invoiceId, setVisible, onClose }) =&gt; {
34 const [bankChooseModalVisible, setBankChooseModalVisible] = useState(false); 20 const [bankChooseModalVisible, setBankChooseModalVisible] = useState(false);
35 const [invoiceInfo, setInvoiceInfo] = useState({}); 21 const [invoiceInfo, setInvoiceInfo] = useState({});
36 const [relationOrderIds, setRelationOrderIds] = useState([]); 22 const [relationOrderIds, setRelationOrderIds] = useState([]);
37 - const [relationBankStatements, setRelationBankStatements] = useState([]); 23 + const [setRelationBankStatements] = useState([]);
38 const actionRef = useRef<ActionType>(); 24 const actionRef = useRef<ActionType>();
39 25
40 const loadInvoiceData = async () => { 26 const loadInvoiceData = async () => {
@@ -137,116 +123,6 @@ export default ({ invoiceId, setVisible, onClose }) =&gt; { @@ -137,116 +123,6 @@ export default ({ invoiceId, setVisible, onClose }) =&gt; {
137 }, 123 },
138 ]; 124 ];
139 125
140 - const getTableCellText = (target: any) => {  
141 - if (!target) {  
142 - return '';  
143 - }  
144 -  
145 - if (target.props) {  
146 - return target.props.text;  
147 - }  
148 -  
149 - return target;  
150 - };  
151 -  
152 - /**  
153 - * 加载表格的各个列格式  
154 - */  
155 - const bankStatementColumnsInit = () => {  
156 - let columns = BANK_STATEMENT_COLUMNS.map((item) => {  
157 - let newItem = { ...item };  
158 - let dataIndex = item.dataIndex;  
159 - let dataType = item.valueType;  
160 -  
161 - newItem.render = (text, record) => {  
162 - let textValue = record[dataIndex];  
163 -  
164 - if (dataType === 'date') {  
165 - textValue = formatDate(textValue);  
166 - }  
167 -  
168 - if (dataType === 'dateTime') {  
169 - textValue = formatDateTime(textValue);  
170 - }  
171 -  
172 - if (dataType === 'money') {  
173 - textValue = '¥' + textValue;  
174 - }  
175 -  
176 - switch (dataIndex) {  
177 - case 'invoiceStatus':  
178 - return (  
179 - <EllipsisDiv  
180 - text={enumValueToLabel(  
181 - getTableCellText(textValue),  
182 - INVOCING_STATUS,  
183 - )}  
184 - />  
185 - );  
186 -  
187 - case 'status':  
188 - return (  
189 - <EllipsisDiv  
190 - text={enumValueToLabel(  
191 - getTableCellText(textValue),  
192 - INVOICE_STATUS,  
193 - )}  
194 - />  
195 - );  
196 -  
197 - case 'payee':  
198 - return (  
199 - <EllipsisDiv  
200 - text={enumValueToLabel(  
201 - getTableCellText(textValue),  
202 - PAYEE_OPTIONS,  
203 - )}  
204 - />  
205 - );  
206 -  
207 - default:  
208 - return <EllipsisDiv text={getTableCellText(textValue)} />;  
209 - }  
210 - };  
211 -  
212 - return newItem;  
213 - });  
214 -  
215 - columns.push({  
216 - title: '操作',  
217 - valueType: 'option',  
218 - key: 'option',  
219 - fixed: 'right',  
220 - width: 70,  
221 - render: (text, record) => {  
222 - let optBtns = [];  
223 - optBtns.push(  
224 - <ButtonConfirm  
225 - key="delete"  
226 - className="p-0"  
227 - title={'确认删除此项吗?'}  
228 - text="删除"  
229 - onConfirm={async () => {  
230 - let res = await postServiceInvoiceCancelInvoiceAndBankStatement({  
231 - data: {  
232 - invoiceId: invoiceId,  
233 - cancelId: [record.id],  
234 - },  
235 - });  
236 - if (res.result === RESPONSE_CODE.SUCCESS) {  
237 - message.success(res.message);  
238 - loadInvoiceData();  
239 - }  
240 - }}  
241 - />,  
242 - );  
243 - return optBtns;  
244 - },  
245 - });  
246 -  
247 - return columns;  
248 - };  
249 -  
250 useEffect(() => { 126 useEffect(() => {
251 loadInvoiceData(); 127 loadInvoiceData();
252 }, []); 128 }, []);
@@ -304,61 +180,6 @@ export default ({ invoiceId, setVisible, onClose }) =&gt; { @@ -304,61 +180,6 @@ export default ({ invoiceId, setVisible, onClose }) =&gt; {
304 </ProCard> 180 </ProCard>
305 181
306 <Divider plain></Divider> 182 <Divider plain></Divider>
307 -  
308 - <ProTable  
309 - columns={bankStatementColumnsInit()}  
310 - actionRef={actionRef}  
311 - cardBordered  
312 - pagination={{  
313 - pageSize: 10,  
314 - }}  
315 - dataSource={relationBankStatements}  
316 - columnsState={{  
317 - persistenceKey: 'pro-table-singe-demos',  
318 - persistenceType: 'localStorage',  
319 - defaultValue: {  
320 - option: { fixed: 'right', disable: true },  
321 - },  
322 - onChange(value) {  
323 - console.log('value: ', value);  
324 - },  
325 - }}  
326 - rowKey="id"  
327 - search={false}  
328 - options={{  
329 - setting: {  
330 - listsHeight: 400,  
331 - },  
332 - reload: false,  
333 - }}  
334 - form={{  
335 - // 由于配置了 transform,提交的参与与定义的不同这里需要转化一下  
336 - syncToUrl: (values, type) => {  
337 - if (type === 'get') {  
338 - return {  
339 - ...values,  
340 - created_at: [values.startTime, values.endTime],  
341 - };  
342 - }  
343 - return values;  
344 - },  
345 - }}  
346 - dateFormatter="string"  
347 - headerTitle="银行流水"  
348 - scroll={{ x: 1400, y: 360 }}  
349 - toolBarRender={() => [  
350 - <Button  
351 - key="button"  
352 - icon={<PlusOutlined />}  
353 - onClick={() => {  
354 - setBankChooseModalVisible(true);  
355 - }}  
356 - type="primary"  
357 - >  
358 - 添加  
359 - </Button>,  
360 - ]}  
361 - />  
362 </ModalForm> 183 </ModalForm>
363 184
364 {bankChooseModalVisible ? ( 185 {bankChooseModalVisible ? (
src/pages/Invoice/Invoice/components/invoiceWriteOffModal.tsx 0 → 100644
  1 +import { RESPONSE_CODE } from '@/constants/enum';
  2 +import AddBankStatementModal from '@/pages/Invoice/Invoice/components/AddBankStatementModal';
  3 +import AddInvoiceModal from '@/pages/Invoice/Invoice/components/AddInvoiceModal';
  4 +import { postServiceInvoiceInvoiceWriteOff } from '@/services';
  5 +import {
  6 + EditableFormInstance,
  7 + EditableProTable,
  8 + ModalForm,
  9 + ProCard,
  10 + ProForm,
  11 + ProFormDependency,
  12 + ProFormField,
  13 + ProFormInstance,
  14 + ProFormText,
  15 +} from '@ant-design/pro-components';
  16 +import { Button, Divider, Flex, message } from 'antd';
  17 +import React, { useRef, useState } from 'react';
  18 +
  19 +let i = 0;
  20 +
  21 +export default ({ getData, triggerButton, readOnly }) => {
  22 + const [InvoiceEditableKeys, setInvoiceEditableKeys] = useState<React.Key[]>(
  23 + () => [],
  24 + );
  25 + const formRef = useRef<ProFormInstance<any>>();
  26 +
  27 + const invoiceEditorFormRef = useRef<EditableFormInstance>();
  28 + const getInvoiceColumns = () => {
  29 + let columns = [
  30 + {
  31 + title: '发票号码',
  32 + dataIndex: 'invoiceNumber',
  33 + ellipsis: true,
  34 + },
  35 + {
  36 + title: '收款方',
  37 + dataIndex: 'payeeText',
  38 + ellipsis: true,
  39 + },
  40 + {
  41 + title: '付款方',
  42 + dataIndex: 'purchaser',
  43 + ellipsis: true,
  44 + },
  45 + {
  46 + title: '金额',
  47 + dataIndex: 'money',
  48 + valueType: 'money',
  49 + },
  50 + {
  51 + title: '日期',
  52 + dataIndex: 'invoicingTime',
  53 + valueType: 'date',
  54 + },
  55 + ];
  56 + if (!readOnly) {
  57 + columns.push({
  58 + title: '操作',
  59 + valueType: 'option',
  60 + render: (text, record) => [
  61 + <a
  62 + key="delete"
  63 + onClick={() => {
  64 + const tableDataSource =
  65 + formRef.current?.getFieldValue('invoices');
  66 + console.log(JSON.stringify(tableDataSource));
  67 + formRef.current?.setFieldValue(
  68 + 'invoices',
  69 + tableDataSource.filter((item) => item.id !== record.id),
  70 + );
  71 + }}
  72 + >
  73 + 删除
  74 + </a>,
  75 + ],
  76 + });
  77 + }
  78 + return columns;
  79 + };
  80 +
  81 + const [bankStatementEditableKeys, setBankStatementEditableKeys] = useState<
  82 + React.Key[]
  83 + >(() => []);
  84 + const bankStatementEditorFormRef = useRef<EditableFormInstance>();
  85 + const getBankStatementColumns = () => {
  86 + let columns = [
  87 + {
  88 + title: '流水号',
  89 + dataIndex: 'serialNumber',
  90 + ellipsis: true,
  91 + },
  92 + {
  93 + title: '收款方',
  94 + dataIndex: 'payeeText',
  95 + ellipsis: true,
  96 + },
  97 + {
  98 + title: '付款方',
  99 + dataIndex: 'payer',
  100 + ellipsis: true,
  101 + },
  102 + {
  103 + title: '金额',
  104 + dataIndex: 'amount',
  105 + valueType: 'money',
  106 + },
  107 + {
  108 + title: '日期',
  109 + dataIndex: 'collectionDatetime',
  110 + valueType: 'date',
  111 + },
  112 + ];
  113 + if (!readOnly) {
  114 + columns.push({
  115 + title: '操作',
  116 + valueType: 'option',
  117 + width: 200,
  118 + render: (text, record) => [
  119 + <a
  120 + key="delete"
  121 + onClick={() => {
  122 + const tableDataSource =
  123 + formRef.current?.getFieldValue('bankStatements');
  124 + console.log(JSON.stringify(tableDataSource));
  125 + formRef.current?.setFieldValue(
  126 + 'bankStatements',
  127 + tableDataSource.filter((item) => item.id !== record.id),
  128 + );
  129 + }}
  130 + >
  131 + 删除
  132 + </a>,
  133 + ],
  134 + });
  135 + }
  136 + return columns;
  137 + };
  138 +
  139 + return (
  140 + <ModalForm
  141 + title={'发票核销'}
  142 + formRef={formRef}
  143 + onFinish={async (values) => {
  144 + const body = {
  145 + invoiceWriteOffId: values.invoiceWriteOffId,
  146 + invoiceIds: values.invoices?.map((item) => item.id),
  147 + bankStatementIds: values.bankStatements?.map((item) => item.id),
  148 + };
  149 + const res = await postServiceInvoiceInvoiceWriteOff({
  150 + data: body,
  151 + });
  152 + if (res.result === RESPONSE_CODE.SUCCESS) {
  153 + message.success('核销成功');
  154 + return true;
  155 + }
  156 + //return true;
  157 + }}
  158 + trigger={triggerButton}
  159 + validateTrigger="onBlur"
  160 + request={async () => {
  161 + return getData();
  162 + }}
  163 + /*initialValues={{
  164 + invoiceWriteOffId:invoiceWriteOffId,
  165 + invoices:originInvoices,
  166 + }}*/
  167 + >
  168 + <ProFormText name={'invoiceWriteOffId'} hidden={true}></ProFormText>
  169 +
  170 + <EditableProTable
  171 + key={'invoices'}
  172 + rowKey="id"
  173 + editableFormRef={invoiceEditorFormRef}
  174 + headerTitle="发票"
  175 + maxLength={10}
  176 + name="invoices"
  177 + controlled={true}
  178 + recordCreatorProps={false}
  179 + toolBarRender={() => [
  180 + <>
  181 + {!readOnly && (
  182 + <AddInvoiceModal
  183 + key={'addInvoice'}
  184 + getRows={() => formRef.current?.getFieldValue('invoices')}
  185 + onFinish={(datas) => {
  186 + const invoices = formRef.current?.getFieldValue('invoices');
  187 + // 添加非空判断,并处理为空的情况
  188 + const mergedInvoices =
  189 + invoices && Array.isArray(invoices) ? invoices : [];
  190 + const mergedDatas =
  191 + datas && Array.isArray(datas) ? datas : [];
  192 + let res = [...mergedInvoices, ...mergedDatas];
  193 + //对res 进行去重处理,根据id去重
  194 + const resMap = new Map();
  195 + res.forEach((item) => {
  196 + resMap.set(item.id, item);
  197 + });
  198 + res = Array.from(resMap.values());
  199 + formRef.current?.setFieldValue('invoices', res);
  200 + }}
  201 + />
  202 + )}
  203 + </>,
  204 + ]}
  205 + columns={getInvoiceColumns()}
  206 + editable={{
  207 + type: 'multiple',
  208 + editableKeys: InvoiceEditableKeys,
  209 + onChange: setInvoiceEditableKeys,
  210 + actionRender: (row, config, defaultDom) => {
  211 + return [
  212 + defaultDom.save,
  213 + defaultDom.delete,
  214 + defaultDom.cancel,
  215 + <a
  216 + key="set"
  217 + onClick={() => {
  218 + console.log(config.index);
  219 + i++;
  220 + invoiceEditorFormRef.current?.setRowData?.(config.index!, {
  221 + title: '动态设置的title' + i,
  222 + });
  223 + }}
  224 + >
  225 + 动态设置此项
  226 + </a>,
  227 + ];
  228 + },
  229 + }}
  230 + />
  231 + <ProForm.Item>
  232 + <ProCard
  233 + hidden={true}
  234 + title="表格数据"
  235 + headerBordered
  236 + collapsible
  237 + defaultCollapsed
  238 + >
  239 + <ProFormDependency name={['invoices']}>
  240 + {({ invoices }) => {
  241 + return (
  242 + <ProFormField
  243 + ignoreFormItem
  244 + fieldProps={{
  245 + style: {
  246 + width: '100%',
  247 + },
  248 + }}
  249 + mode="read"
  250 + valueType="jsonCode"
  251 + text={JSON.stringify(invoices)}
  252 + />
  253 + );
  254 + }}
  255 + </ProFormDependency>
  256 + </ProCard>
  257 + </ProForm.Item>
  258 +
  259 + <Divider orientation="left" plain>
  260 + 发票关联订单号
  261 + </Divider>
  262 + <ProCard bordered style={{}}>
  263 + <Flex>
  264 + <div>
  265 + <ProFormDependency name={['invoices']}>
  266 + {({ invoices }) => {
  267 + return invoices?.map((item) => (
  268 + <>
  269 + {item.invoiceNumber}(
  270 + {item.mainOrderIds?.map((mainId) => (
  271 + <>
  272 + <Button
  273 + className="pl-1 pr-0"
  274 + type="link"
  275 + target="_blank"
  276 + href={'/order?id=' + mainId}
  277 + >
  278 + {mainId}
  279 + </Button>
  280 + <Divider type="vertical" />
  281 + </>
  282 + ))}
  283 + )
  284 + <Divider type="vertical" />
  285 + </>
  286 + ));
  287 + }}
  288 + </ProFormDependency>
  289 + </div>
  290 + </Flex>
  291 + </ProCard>
  292 +
  293 + <EditableProTable
  294 + key={'bankStatements'}
  295 + rowKey="id"
  296 + editableFormRef={bankStatementEditorFormRef}
  297 + headerTitle="流水"
  298 + maxLength={10}
  299 + name="bankStatements"
  300 + controlled={true}
  301 + recordCreatorProps={false}
  302 + toolBarRender={() => [
  303 + <>
  304 + {!readOnly && (
  305 + <AddBankStatementModal
  306 + getRows={() => formRef.current?.getFieldValue('bankStatements')}
  307 + onFinish={(datas) => {
  308 + const bankStatements =
  309 + formRef.current?.getFieldValue('bankStatements');
  310 + // 添加非空判断,并处理为空的情况
  311 + const mergedBankStatements =
  312 + bankStatements && Array.isArray(bankStatements)
  313 + ? bankStatements
  314 + : [];
  315 + const mergedDatas =
  316 + datas && Array.isArray(datas) ? datas : [];
  317 + let res = [...mergedBankStatements, ...mergedDatas];
  318 + //对res 进行去重处理,根据id去重
  319 + const resMap = new Map();
  320 + res.forEach((item) => {
  321 + resMap.set(item.id, item);
  322 + });
  323 + res = Array.from(resMap.values());
  324 + formRef.current?.setFieldValue('bankStatements', res);
  325 + }}
  326 + />
  327 + )}
  328 + </>,
  329 + ]}
  330 + columns={getBankStatementColumns()}
  331 + editable={{
  332 + type: 'multiple',
  333 + editableKeys: bankStatementEditableKeys,
  334 + onChange: setBankStatementEditableKeys,
  335 + actionRender: (row, config, defaultDom) => {
  336 + return [
  337 + defaultDom.save,
  338 + defaultDom.delete,
  339 + defaultDom.cancel,
  340 + <a
  341 + key="set"
  342 + onClick={() => {
  343 + console.log(config.index);
  344 + i++;
  345 + bankStatementEditorFormRef.current?.setRowData?.(
  346 + config.index!,
  347 + {
  348 + title: '动态设置的title' + i,
  349 + },
  350 + );
  351 + }}
  352 + >
  353 + 动态设置此项
  354 + </a>,
  355 + ];
  356 + },
  357 + }}
  358 + />
  359 + <ProForm.Item>
  360 + <ProCard
  361 + hidden={true}
  362 + title="表格数据"
  363 + headerBordered
  364 + collapsible
  365 + defaultCollapsed
  366 + >
  367 + <ProFormDependency name={['bankStatements']}>
  368 + {({ bankStatements }) => {
  369 + return (
  370 + <ProFormField
  371 + ignoreFormItem
  372 + fieldProps={{
  373 + style: {
  374 + width: '100%',
  375 + },
  376 + }}
  377 + mode="read"
  378 + valueType="jsonCode"
  379 + text={JSON.stringify(bankStatements)}
  380 + />
  381 + );
  382 + }}
  383 + </ProFormDependency>
  384 + </ProCard>
  385 + </ProForm.Item>
  386 + </ModalForm>
  387 + );
  388 +};
src/pages/Invoice/Invoice/index.tsx
@@ -3,10 +3,12 @@ import EllipsisDiv from &#39;@/components/Div/EllipsisDiv&#39;; @@ -3,10 +3,12 @@ import EllipsisDiv from &#39;@/components/Div/EllipsisDiv&#39;;
3 import AddInvoiceDrawerForm from '@/pages/Invoice/Invoice/components/AddInvoiceDrawerForm'; 3 import AddInvoiceDrawerForm from '@/pages/Invoice/Invoice/components/AddInvoiceDrawerForm';
4 import BankImportModal from '@/pages/Invoice/Invoice/components/BankImportModal'; 4 import BankImportModal from '@/pages/Invoice/Invoice/components/BankImportModal';
5 import InvoiceVerificationModal from '@/pages/Invoice/Invoice/components/InvoiceVerificationModal'; 5 import InvoiceVerificationModal from '@/pages/Invoice/Invoice/components/InvoiceVerificationModal';
  6 +import InvoiceWriteOffModal from '@/pages/Invoice/Invoice/components/invoiceWriteOffModal';
6 import { INVOICE_COLUMNS } from '@/pages/Invoice/constant'; 7 import { INVOICE_COLUMNS } from '@/pages/Invoice/constant';
7 import { INVOCING_STATUS, PAYEE_OPTIONS } from '@/pages/Order/constant'; 8 import { INVOCING_STATUS, PAYEE_OPTIONS } from '@/pages/Order/constant';
8 import { 9 import {
9 postServiceInvoiceDeleteInvoice, 10 postServiceInvoiceDeleteInvoice,
  11 + postServiceInvoiceGetWriteOffRecord,
10 postServiceInvoiceQueryInvoice, 12 postServiceInvoiceQueryInvoice,
11 } from '@/services'; 13 } from '@/services';
12 import { enumValueToLabel, formatDateTime } from '@/utils'; 14 import { enumValueToLabel, formatDateTime } from '@/utils';
@@ -94,21 +96,46 @@ const InvoiceRecord = () =&gt; { @@ -94,21 +96,46 @@ const InvoiceRecord = () =&gt; {
94 valueType: 'option', 96 valueType: 'option',
95 key: 'option', 97 key: 'option',
96 fixed: 'right', 98 fixed: 'right',
97 - width: 120, 99 + width: 160,
98 render: (text, record) => { 100 render: (text, record) => {
99 let btns = []; 101 let btns = [];
100 - if (record.paths?.includes('writeOff')) { 102 + if (!record.writeOffId) {
101 btns.push( 103 btns.push(
102 - <a  
103 - key="editable"  
104 - onClick={() => {  
105 - console.log(JSON.stringify(record));  
106 - setInvoiceVerificationVisible(true);  
107 - setInvoiceId(record.id); 104 + <InvoiceWriteOffModal
  105 + getData={() => {
  106 + return {
  107 + invoices: [record],
  108 + };
108 }} 109 }}
109 - >  
110 - 核销  
111 - </a>, 110 + key="writeOff"
  111 + triggerButton={
  112 + <Button size={'small'} type="link">
  113 + 核销
  114 + </Button>
  115 + }
  116 + readOnly={false}
  117 + />,
  118 + );
  119 + }
  120 +
  121 + if (record.writeOffId) {
  122 + btns.push(
  123 + <InvoiceWriteOffModal
  124 + getData={async () => {
  125 + const res = await postServiceInvoiceGetWriteOffRecord({
  126 + data: { id: record.writeOffId },
  127 + });
  128 + const data = res.data;
  129 + return {
  130 + invoiceWriteOffId: data.id,
  131 + invoices: data.invoiceDtos,
  132 + bankStatements: data.bankStatementDtos,
  133 + };
  134 + }}
  135 + key="writeOff"
  136 + triggerButton={<Button type="link">核销记录</Button>}
  137 + readOnly={true}
  138 + />,
112 ); 139 );
113 } 140 }
114 141
@@ -206,6 +233,12 @@ const InvoiceRecord = () =&gt; { @@ -206,6 +233,12 @@ const InvoiceRecord = () =&gt; {
206 }} 233 }}
207 key="add" 234 key="add"
208 ></AddInvoiceDrawerForm>, 235 ></AddInvoiceDrawerForm>,
  236 + <InvoiceWriteOffModal
  237 + readOnly={false}
  238 + getData={() => ({})}
  239 + key="writeOff"
  240 + triggerButton={<Button type="primary">核销</Button>}
  241 + />,
209 ]} 242 ]}
210 /> 243 />
211 244
src/pages/Invoice/InvoiceRecord/components/InvoiceRecordDetailModal.tsx
@@ -30,7 +30,6 @@ export default ({ id, setVisible, reloadTable }) =&gt; { @@ -30,7 +30,6 @@ export default ({ id, setVisible, reloadTable }) =&gt; {
30 const [form] = Form.useForm(); 30 const [form] = Form.useForm();
31 31
32 useEffect(() => { 32 useEffect(() => {
33 - console.log('id' + id);  
34 const getPayees = async () => { 33 const getPayees = async () => {
35 let res = await postServiceConstGetPayeeEnum(); 34 let res = await postServiceConstGetPayeeEnum();
36 setPayees(res.data); 35 setPayees(res.data);
src/pages/Invoice/InvoiceVerification/components/AddInvoiceDrawerForm.tsx deleted 100644 → 0
1 -import { RESPONSE_CODE } from '@/constants/enum';  
2 -import { PAYEE_OPTIONS } from '@/pages/Order/constant';  
3 -import {  
4 - postServiceInvoiceAddInvoice,  
5 - postServiceOrderQuerySalesCode,  
6 -} from '@/services';  
7 -import { enumToSelect } from '@/utils';  
8 -import { PlusOutlined } from '@ant-design/icons';  
9 -import {  
10 - DrawerForm,  
11 - ProFormDateTimePicker,  
12 - ProFormGroup,  
13 - ProFormList,  
14 - ProFormMoney,  
15 - ProFormSelect,  
16 - ProFormText,  
17 - ProFormTextArea,  
18 -} from '@ant-design/pro-components';  
19 -import { Button, Form, message } from 'antd';  
20 -import { useEffect, useState } from 'react';  
21 -  
22 -export default ({ onClose }) => {  
23 - const [form] = Form.useForm<{  
24 - invoiceNumber: '';  
25 - invoiceStatus: '';  
26 - purchaser: '';  
27 - payee: '';  
28 - contacts: '';  
29 - sale: '';  
30 - invoicingTime: '';  
31 - notes: '';  
32 - mainOrderIdObjs: [  
33 - {  
34 - mainOrderId: '';  
35 - },  
36 - ];  
37 - money: '';  
38 - }>();  
39 - const [salesCodeOptions, setSalesCodeOptions] = useState([]);  
40 - const getSalesCodeOptions = async () => {  
41 - const res = await postServiceOrderQuerySalesCode();  
42 - let options = res.data?.map((item) => {  
43 - return {  
44 - label: item.userName,  
45 - value: item.userName,  
46 - number: item.number,  
47 - };  
48 - });  
49 - setSalesCodeOptions(options);  
50 - };  
51 - useEffect(() => {  
52 - getSalesCodeOptions();  
53 - }, []);  
54 - return (  
55 - <DrawerForm<{  
56 - invoiceNumber: string;  
57 - invoiceStatus: string;  
58 - purchaser: string;  
59 - payee: string;  
60 - contacts: string;  
61 - sale: string;  
62 - invoicingTime: Date;  
63 - notes: string;  
64 - mainOrderIdObjs: [  
65 - {  
66 - mainOrderId: string;  
67 - },  
68 - ];  
69 - money: string;  
70 - }>  
71 - title="新增开票"  
72 - resize={{  
73 - onResize() {  
74 - console.log('resize!');  
75 - },  
76 - maxWidth: window.innerWidth * 0.8,  
77 - minWidth: 500,  
78 - }}  
79 - form={form}  
80 - trigger={  
81 - <Button type="primary">  
82 - <PlusOutlined />  
83 - 新增  
84 - </Button>  
85 - }  
86 - autoFocusFirstInput  
87 - drawerProps={{  
88 - destroyOnClose: true,  
89 - }}  
90 - submitTimeout={2000}  
91 - onFinish={async (values) => {  
92 - console.log(values);  
93 - const mainOrderIds = values.mainOrderIdObjs.flatMap(  
94 - (item) => item.mainOrderId,  
95 - );  
96 - let attrs = { ...values, mainOrderIds };  
97 - let res = await postServiceInvoiceAddInvoice({  
98 - data: { ...attrs },  
99 - });  
100 - if (res.result === RESPONSE_CODE.SUCCESS) {  
101 - message.success(res.message);  
102 - } else {  
103 - message.error(res.message);  
104 - return false;  
105 - }  
106 - onClose();  
107 - // 不返回不会关闭弹框  
108 - return true;  
109 - }}  
110 - >  
111 - <ProFormText  
112 - name="invoiceNumber"  
113 - width="md"  
114 - label="发票号码"  
115 - placeholder="请输入名称"  
116 - rules={[{ required: true, message: '请输入名称!' }]}  
117 - />  
118 - <ProFormSelect  
119 - name="invoiceStatus"  
120 - label="发票类型"  
121 - valueEnum={{  
122 - SPECIALLY_INVOICED: '专票',  
123 - COMMON_INVOICED: '普票',  
124 - }}  
125 - rules={[{ required: true, message: '请选择发票类型!' }]}  
126 - />  
127 - <ProFormText  
128 - name="purchaser"  
129 - width="md"  
130 - label="购买方"  
131 - placeholder="请输入购买方"  
132 - rules={[{ required: true, message: '请输入购买方!' }]}  
133 - />  
134 - <ProFormSelect  
135 - placeholder="收款单位"  
136 - name="payee"  
137 - width="lg"  
138 - key="payee"  
139 - showSearch  
140 - label="开票收款单位"  
141 - tooltip="财务开票将依据这个字段,选择对应的公司开票"  
142 - options={enumToSelect(PAYEE_OPTIONS)}  
143 - />  
144 - <ProFormText  
145 - name="contacts"  
146 - width="md"  
147 - label="联系人"  
148 - placeholder="请输入联系人"  
149 - rules={[{ required: true, message: '请输入联系人!' }]}  
150 - />  
151 - <ProFormSelect  
152 - name="sale"  
153 - key="sale"  
154 - width="lg"  
155 - showSearch  
156 - label="销售代表"  
157 - placeholder="请选择销售代表"  
158 - options={salesCodeOptions}  
159 - />  
160 - <ProFormDateTimePicker  
161 - name="invoicingTime"  
162 - label="开票时间"  
163 - fieldProps={{  
164 - format: (value) => value.format('YYYY-MM-DD'),  
165 - }}  
166 - rules={[{ required: true, message: '请输入开票时间!' }]}  
167 - />  
168 - <ProFormTextArea name="notes" label="备注" placeholder="请输入名称" />  
169 - <ProFormList  
170 - name="mainOrderIdObjs"  
171 - label="订单号"  
172 - min={1}  
173 - copyIconProps={false}  
174 - deleteIconProps={{  
175 - tooltipText: '删除',  
176 - }}  
177 - initialValue={[  
178 - {  
179 - mainOrderId: '',  
180 - },  
181 - ]}  
182 - >  
183 - <ProFormGroup key="group">  
184 - <ProFormText  
185 - rules={[{ required: true, message: '请输入关联订单!' }]}  
186 - name="mainOrderId"  
187 - />  
188 - </ProFormGroup>  
189 - </ProFormList>  
190 - <ProFormMoney  
191 - label="金额"  
192 - name="money"  
193 - customSymbol="¥"  
194 - min={0}  
195 - rules={[{ required: true, message: '请输入金额!' }]}  
196 - />  
197 - </DrawerForm>  
198 - );  
199 -};  
src/pages/Invoice/InvoiceVerification/components/InvoiceVerificationModal.tsx
1 -import ButtonConfirm from '@/components/ButtomConfirm';  
2 -import EllipsisDiv from '@/components/Div/EllipsisDiv';  
3 -import { RESPONSE_CODE } from '@/constants/enum';  
4 import { INVOCING_STATUS, PAYEE_OPTIONS } from '@/pages/Order/constant'; 1 import { INVOCING_STATUS, PAYEE_OPTIONS } from '@/pages/Order/constant';
5 -import {  
6 - postServiceInvoiceCancelInvoiceAndBankStatement,  
7 - postServiceInvoiceQueryInvoiceDetail,  
8 -} from '@/services';  
9 -import { enumValueToLabel, formatDateTime } from '@/utils'; 2 +import { postServiceInvoiceQueryInvoiceDetail } from '@/services';
  3 +import { enumValueToLabel } from '@/utils';
10 import { formatDate } from '@/utils/time'; 4 import { formatDate } from '@/utils/time';
11 -import { PlusOutlined } from '@ant-design/icons';  
12 -import {  
13 - ActionType,  
14 - ModalForm,  
15 - ProCard,  
16 - ProTable,  
17 -} from '@ant-design/pro-components'; 5 +import { ActionType, ModalForm, ProCard } from '@ant-design/pro-components';
18 import { 6 import {
19 Button, 7 Button,
20 Descriptions, 8 Descriptions,
@@ -22,10 +10,9 @@ import { @@ -22,10 +10,9 @@ import {
22 Divider, 10 Divider,
23 Flex, 11 Flex,
24 Form, 12 Form,
25 - message,  
26 } from 'antd'; 13 } from 'antd';
27 import { useEffect, useRef, useState } from 'react'; 14 import { useEffect, useRef, useState } from 'react';
28 -import { BANK_STATEMENT_COLUMNS, INVOICE_STATUS } from '../../constant'; 15 +import { INVOICE_STATUS } from '../../constant';
29 import '../index.less'; 16 import '../index.less';
30 import BankChooseModal from './BankChooseModal'; 17 import BankChooseModal from './BankChooseModal';
31 18
@@ -34,7 +21,7 @@ export default ({ invoiceId, setVisible, onClose }) =&gt; { @@ -34,7 +21,7 @@ export default ({ invoiceId, setVisible, onClose }) =&gt; {
34 const [bankChooseModalVisible, setBankChooseModalVisible] = useState(false); 21 const [bankChooseModalVisible, setBankChooseModalVisible] = useState(false);
35 const [invoiceInfo, setInvoiceInfo] = useState({}); 22 const [invoiceInfo, setInvoiceInfo] = useState({});
36 const [relationOrderIds, setRelationOrderIds] = useState([]); 23 const [relationOrderIds, setRelationOrderIds] = useState([]);
37 - const [relationBankStatements, setRelationBankStatements] = useState([]); 24 + const [setRelationBankStatements] = useState([]);
38 const actionRef = useRef<ActionType>(); 25 const actionRef = useRef<ActionType>();
39 26
40 const loadInvoiceData = async () => { 27 const loadInvoiceData = async () => {
@@ -137,120 +124,6 @@ export default ({ invoiceId, setVisible, onClose }) =&gt; { @@ -137,120 +124,6 @@ export default ({ invoiceId, setVisible, onClose }) =&gt; {
137 }, 124 },
138 ]; 125 ];
139 126
140 - const getTableCellText = (target: any) => {  
141 - if (!target) {  
142 - return '';  
143 - }  
144 -  
145 - if (target.props) {  
146 - return target.props.text;  
147 - }  
148 -  
149 - return target;  
150 - };  
151 -  
152 - /**  
153 - * 加载表格的各个列格式  
154 - */  
155 - const bankStatementColumnsInit = () => {  
156 - let columns = BANK_STATEMENT_COLUMNS.map((item) => {  
157 - let newItem = { ...item };  
158 - let dataIndex = item.dataIndex;  
159 - let dataType = item.valueType;  
160 -  
161 - newItem.render = (text, record) => {  
162 - let textValue = record[dataIndex];  
163 -  
164 - if (dataType === 'date') {  
165 - textValue = formatDate(textValue);  
166 - }  
167 -  
168 - if (dataType === 'dateTime') {  
169 - textValue = formatDateTime(textValue);  
170 - }  
171 -  
172 - if (dataType === 'money') {  
173 - textValue = '¥' + textValue;  
174 - }  
175 -  
176 - switch (dataIndex) {  
177 - case 'invoiceStatus':  
178 - return (  
179 - <EllipsisDiv  
180 - text={enumValueToLabel(  
181 - getTableCellText(textValue),  
182 - INVOCING_STATUS,  
183 - )}  
184 - />  
185 - );  
186 -  
187 - case 'status':  
188 - return (  
189 - <EllipsisDiv  
190 - text={enumValueToLabel(  
191 - getTableCellText(textValue),  
192 - INVOICE_STATUS,  
193 - )}  
194 - />  
195 - );  
196 -  
197 - case 'payee':  
198 - return (  
199 - <EllipsisDiv  
200 - text={enumValueToLabel(  
201 - getTableCellText(textValue),  
202 - PAYEE_OPTIONS,  
203 - )}  
204 - />  
205 - );  
206 -  
207 - default:  
208 - return <EllipsisDiv text={getTableCellText(textValue)} />;  
209 - }  
210 - };  
211 -  
212 - return newItem;  
213 - });  
214 -  
215 - columns.push({  
216 - title: '操作',  
217 - valueType: 'option',  
218 - key: 'option',  
219 - fixed: 'right',  
220 - width: 70,  
221 - render: (text, record) => {  
222 - let optBtns = [];  
223 - if (invoiceInfo?.status === 'VERIFIED') {  
224 - return [];  
225 - }  
226 -  
227 - optBtns.push(  
228 - <ButtonConfirm  
229 - key="delete"  
230 - className="p-0"  
231 - title={'确认删除此项吗?'}  
232 - text="删除"  
233 - onConfirm={async () => {  
234 - let res = await postServiceInvoiceCancelInvoiceAndBankStatement({  
235 - data: {  
236 - invoiceId: invoiceId,  
237 - cancelId: [record.id],  
238 - },  
239 - });  
240 - if (res.result === RESPONSE_CODE.SUCCESS) {  
241 - message.success(res.message);  
242 - loadInvoiceData();  
243 - }  
244 - }}  
245 - />,  
246 - );  
247 - return optBtns;  
248 - },  
249 - });  
250 -  
251 - return columns;  
252 - };  
253 -  
254 useEffect(() => { 127 useEffect(() => {
255 loadInvoiceData(); 128 loadInvoiceData();
256 }, []); 129 }, []);
@@ -308,61 +181,6 @@ export default ({ invoiceId, setVisible, onClose }) =&gt; { @@ -308,61 +181,6 @@ export default ({ invoiceId, setVisible, onClose }) =&gt; {
308 </ProCard> 181 </ProCard>
309 182
310 <Divider plain></Divider> 183 <Divider plain></Divider>
311 -  
312 - <ProTable  
313 - columns={bankStatementColumnsInit()}  
314 - actionRef={actionRef}  
315 - cardBordered  
316 - pagination={{  
317 - pageSize: 10,  
318 - }}  
319 - dataSource={relationBankStatements}  
320 - columnsState={{  
321 - persistenceKey: 'pro-table-singe-demos',  
322 - persistenceType: 'localStorage',  
323 - defaultValue: {  
324 - option: { fixed: 'right', disable: true },  
325 - },  
326 - onChange(value) {  
327 - console.log('value: ', value);  
328 - },  
329 - }}  
330 - rowKey="id"  
331 - search={false}  
332 - options={{  
333 - setting: {  
334 - listsHeight: 400,  
335 - },  
336 - reload: false,  
337 - }}  
338 - form={{  
339 - // 由于配置了 transform,提交的参与与定义的不同这里需要转化一下  
340 - syncToUrl: (values, type) => {  
341 - if (type === 'get') {  
342 - return {  
343 - ...values,  
344 - created_at: [values.startTime, values.endTime],  
345 - };  
346 - }  
347 - return values;  
348 - },  
349 - }}  
350 - dateFormatter="string"  
351 - headerTitle="银行流水"  
352 - scroll={{ x: 1400, y: 360 }}  
353 - toolBarRender={() => [  
354 - <Button  
355 - key="button"  
356 - icon={<PlusOutlined />}  
357 - onClick={() => {  
358 - setBankChooseModalVisible(true);  
359 - }}  
360 - type="primary"  
361 - >  
362 - 添加  
363 - </Button>,  
364 - ]}  
365 - />  
366 </ModalForm> 184 </ModalForm>
367 185
368 {bankChooseModalVisible ? ( 186 {bankChooseModalVisible ? (
src/pages/Invoice/InvoiceVerification/components/InvoicingModal.tsx deleted 100644 → 0
1 -import { RESPONSE_CODE } from '@/constants/enum';  
2 -import { postServiceInvoiceInvoicing } from '@/services';  
3 -import { ModalForm } from '@ant-design/pro-components';  
4 -import { Button, Form, message } from 'antd';  
5 -  
6 -export default ({ selectedRowKeys, reloadRecordTable }) => {  
7 - const [form] = Form.useForm<{ name: string; company: string }>();  
8 - return (  
9 - <ModalForm<{  
10 - name: string;  
11 - company: string;  
12 - }>  
13 - title="开票"  
14 - trigger={  
15 - <Button type="primary" disabled={selectedRowKeys?.length === 0}>  
16 - 开票  
17 - </Button>  
18 - }  
19 - form={form}  
20 - autoFocusFirstInput  
21 - modalProps={{  
22 - destroyOnClose: true,  
23 - onCancel: () => console.log('run'),  
24 - }}  
25 - submitTimeout={2000}  
26 - onFinish={async (values) => {  
27 - let res = await postServiceInvoiceInvoicing({  
28 - data: {  
29 - ...values,  
30 - invoiceRecordIds: selectedRowKeys,  
31 - },  
32 - });  
33 - if (res.result === RESPONSE_CODE.SUCCESS) {  
34 - message.success(res.message);  
35 - }  
36 - reloadRecordTable();  
37 - message.success('提交成功');  
38 - return true;  
39 - }}  
40 - >  
41 - {/*<ProFormSelect  
42 - name="invoicingAccount"  
43 - label="开票账号"  
44 - request={async () => {  
45 - const res = await postServiceInvoiceGetInvoicingAccount();  
46 - return res.data.map((item) => {  
47 - return {  
48 - label: item.accountText,  
49 - value: item.account,  
50 - };  
51 - });  
52 - }}  
53 - placeholder="请选择开票账号"  
54 - rules={[{ required: true, message: '请选择开票账号!' }]}  
55 - />*/}  
56 - </ModalForm>  
57 - );  
58 -};  
src/pages/Invoice/InvoiceVerification/components/ManualInvoicingModal.tsx deleted 100644 → 0
1 -import { RESPONSE_CODE } from '@/constants/enum';  
2 -import UploadC from '@/pages/Invoice/InvoiceVerification/components/UploadSingleImg';  
3 -import {  
4 - postOrderErpOrderStagesUpload,  
5 - postServiceInvoiceDealInvoicingResult,  
6 -} from '@/services';  
7 -import {  
8 - ModalForm,  
9 - ProFormDatePicker,  
10 - ProFormText,  
11 -} from '@ant-design/pro-components';  
12 -import { Col, Form, Row, message } from 'antd';  
13 -import { RcFile } from 'antd/es/upload';  
14 -import { useEffect } from 'react';  
15 -  
16 -export default ({ record }) => {  
17 - useEffect(() => {  
18 - console.log('invoicing');  
19 - }, []);  
20 - const [form] = Form.useForm();  
21 - return (  
22 - <ModalForm  
23 - title="手动开票"  
24 - trigger={<a type="primary">手动开票</a>}  
25 - width={600}  
26 - layout={'horizontal'}  
27 - form={form}  
28 - autoFocusFirstInput  
29 - modalProps={{  
30 - destroyOnClose: true,  
31 - onCancel: () => console.log('run'),  
32 - }}  
33 - submitTimeout={2000}  
34 - onFinish={async (values) => {  
35 - const res = await postServiceInvoiceDealInvoicingResult({  
36 - data: {  
37 - ...values,  
38 - isSuccess: true,  
39 - invoiceRecordId: record.id,  
40 - manual: true,  
41 - },  
42 - });  
43 - if (res.result === RESPONSE_CODE.SUCCESS) {  
44 - message.success('开票成功');  
45 - return true;  
46 - } else {  
47 - message.error('开票失败');  
48 - }  
49 - }}  
50 - >  
51 - {/*<ProFormText  
52 - rules={[{ required: true, message: '此项为必填项' }]}  
53 - width={'md'}  
54 - name="invoicingPerson"  
55 - label="开票人"  
56 - />*/}  
57 - <ProFormText  
58 - rules={[{ required: true, message: '此项为必填项' }]}  
59 - width={'md'}  
60 - name="invoiceNumber"  
61 - label="发票号码"  
62 - />  
63 - <ProFormDatePicker  
64 - rules={[{ required: true, message: '此项为必填项' }]}  
65 - fieldProps={{  
66 - format: 'YYYY-MM-DD',  
67 - }}  
68 - name="invoicingDate"  
69 - label="开票日期"  
70 - />  
71 - <ProFormText  
72 - rules={[{ required: true, message: '发票必须上传' }]}  
73 - hidden  
74 - name="url"  
75 - label="發票地址"  
76 - />  
77 - <Row>  
78 - <Col span={4}>上传发票</Col>  
79 - <Col span={20}>  
80 - <UploadC  
81 - onFilesChange={async (newFileList) => {  
82 - if (newFileList.length > 0) {  
83 - const formData = new FormData();  
84 - formData.append('file', newFileList[0].originFileObj as RcFile);  
85 - const res = await postOrderErpOrderStagesUpload({  
86 - data: formData,  
87 - headers: {  
88 - 'Content-Type':  
89 - 'multipart/form-data; boundary=----WebKitFormBoundarynl6gT1BKdPWIejNq',  
90 - },  
91 - });  
92 - const url = res.data;  
93 - form.setFieldValue('url', url);  
94 - } else {  
95 - form.setFieldValue('url', null);  
96 - }  
97 - }}  
98 - ></UploadC>  
99 - </Col>  
100 - </Row>  
101 - {/*<ProFormList  
102 - name="invoiceDetailDtoList"  
103 - label="明细"  
104 - creatorButtonProps={false}  
105 - copyIconProps={false}  
106 - itemRender={({ listDom }, { index }) => (  
107 - <ProCard  
108 - bordered  
109 - style={{ marginBlockEnd: 8 }}  
110 - title={`明细${index + 1}`}  
111 - bodyStyle={{ paddingBlockEnd: 0 }}  
112 - >  
113 - {listDom}  
114 - </ProCard>  
115 - )}  
116 - creatorRecord={{ name: '', items: [{ name: '' }] }}  
117 - initialValue={record.invoiceDetails}  
118 - >  
119 - <ProFormText  
120 - name="projectName"  
121 - label="名称"  
122 - placeholder="请输入名称"  
123 - readonly  
124 - />  
125 - <ProFormDigit label="税率" name="taxRate" min={0} max={100} />  
126 - <ProFormMoney label="税额" name="taxPrice" locale="zh-CN" min={0} />  
127 - </ProFormList>*/}  
128 - </ModalForm>  
129 - );  
130 -};  
src/pages/Invoice/InvoiceVerification/index.tsx
@@ -117,10 +117,10 @@ const InvoiceRecord = () =&gt; { @@ -117,10 +117,10 @@ const InvoiceRecord = () =&gt; {
117 valueType: 'option', 117 valueType: 'option',
118 key: 'option', 118 key: 'option',
119 fixed: 'right', 119 fixed: 'right',
120 - width: 120, 120 + width: 80,
121 render: (text, record, _, action) => { 121 render: (text, record, _, action) => {
122 let btns = []; 122 let btns = [];
123 - if (record.path?.includes('editBankStatement')) { 123 + if (record.paths?.includes('editBankStatement')) {
124 btns.push( 124 btns.push(
125 <a 125 <a
126 key="editable" 126 key="editable"
@@ -133,7 +133,7 @@ const InvoiceRecord = () =&gt; { @@ -133,7 +133,7 @@ const InvoiceRecord = () =&gt; {
133 ); 133 );
134 } 134 }
135 135
136 - if (record.path?.includes('deleteBankStatement')) { 136 + if (record.paths?.includes('deleteBankStatement')) {
137 btns.push( 137 btns.push(
138 <ButtonConfirm 138 <ButtonConfirm
139 key="delete" 139 key="delete"
src/pages/Invoice/constant.tsx
@@ -62,13 +62,19 @@ export const INVOICE_COLUMNS = [ @@ -62,13 +62,19 @@ export const INVOICE_COLUMNS = [
62 }, 62 },
63 { 63 {
64 title: '状态', 64 title: '状态',
65 - dataIndex: 'status', 65 + dataIndex: 'writeOffIdIsNull',
66 valueType: 'select', 66 valueType: 'select',
67 width: 100, 67 width: 100,
68 - valueEnum: enumToProTableEnumValue({  
69 - UNVERIFIED: '未核销',  
70 - VERIFIED: '已核销',  
71 - }), 68 + valueEnum: {
  69 + true: {
  70 + text: '未核销',
  71 + status: false,
  72 + },
  73 + false: {
  74 + text: '已核销',
  75 + status: true,
  76 + },
  77 + },
72 hideInTable: true, 78 hideInTable: true,
73 }, 79 },
74 { 80 {
@@ -170,6 +176,30 @@ export const BANK_STATEMENT_COLUMNS = [ @@ -170,6 +176,30 @@ export const BANK_STATEMENT_COLUMNS = [
170 editable: false, 176 editable: false,
171 }, 177 },
172 { 178 {
  179 + dataIndex: 'statusText',
  180 + title: '状态',
  181 + hideInSearch: true,
  182 + valueType: 'text',
  183 + width: 100,
  184 + },
  185 + {
  186 + dataIndex: 'writeOffIdIsNull',
  187 + title: '状态',
  188 + hideInTable: true,
  189 + valueType: 'select',
  190 + valueEnum: {
  191 + true: {
  192 + text: '未核销',
  193 + status: false,
  194 + },
  195 + false: {
  196 + text: '已核销',
  197 + status: true,
  198 + },
  199 + },
  200 + width: 100,
  201 + },
  202 + {
173 dataIndex: 'serialNumber', 203 dataIndex: 'serialNumber',
174 title: '流水号', 204 title: '流水号',
175 valueType: 'text', 205 valueType: 'text',
src/pages/Order/index.tsx
@@ -10,6 +10,7 @@ import { @@ -10,6 +10,7 @@ import {
10 postServiceConstCanApplyAfterInvoicingStatus, 10 postServiceConstCanApplyAfterInvoicingStatus,
11 postServiceInvoiceCancelApply, 11 postServiceInvoiceCancelApply,
12 postServiceOrderCancelSend, 12 postServiceOrderCancelSend,
  13 + postServiceOrderConfirmInvoice,
13 postServiceOrderGetCurrentOptNode, 14 postServiceOrderGetCurrentOptNode,
14 postServiceOrderNoNeedSend, 15 postServiceOrderNoNeedSend,
15 postServiceOrderOrderCancel, 16 postServiceOrderOrderCancel,
@@ -2072,6 +2073,25 @@ const OrderPage = () =&gt; { @@ -2072,6 +2073,25 @@ const OrderPage = () =&gt; {
2072 '' 2073 ''
2073 )} 2074 )}
2074 2075
  2076 + {optRecord.paths?.includes('confirmInvoice') ? (
  2077 + <ButtonConfirm
  2078 + className="p-0"
  2079 + title="已和客户确认发票??"
  2080 + text="确认发票"
  2081 + onConfirm={async () => {
  2082 + let body = { ids: [optRecord.id] };
  2083 + const data = await postServiceOrderConfirmInvoice({
  2084 + data: body,
  2085 + });
  2086 + if (data.result === RESPONSE_CODE.SUCCESS) {
  2087 + message.success(data.message);
  2088 + refreshTable();
  2089 + }
  2090 + }}
  2091 + />
  2092 + ) : (
  2093 + ''
  2094 + )}
2075 {optRecord.paths?.includes('orderCancel') ? ( 2095 {optRecord.paths?.includes('orderCancel') ? (
2076 <ButtonConfirm 2096 <ButtonConfirm
2077 className="p-0" 2097 className="p-0"
@@ -3846,6 +3866,32 @@ const OrderPage = () =&gt; { @@ -3846,6 +3866,32 @@ const OrderPage = () =&gt; {
3846 '' 3866 ''
3847 )} 3867 )}
3848 3868
  3869 + {record.paths?.includes('confirmInvoice') ? (
  3870 + <ButtonConfirm
  3871 + className="p-0"
  3872 + title="已和客户确认发票?"
  3873 + text="确认发票"
  3874 + onConfirm={async () => {
  3875 + let body = {
  3876 + ids: [
  3877 + ...record.subOrderInformationLists.map(
  3878 + (subOrder) => subOrder.id,
  3879 + ),
  3880 + ],
  3881 + };
  3882 + const data = await postServiceOrderConfirmInvoice({
  3883 + data: body,
  3884 + });
  3885 + if (data.result === RESPONSE_CODE.SUCCESS) {
  3886 + message.success(data.message);
  3887 + refreshTable();
  3888 + }
  3889 + }}
  3890 + />
  3891 + ) : (
  3892 + ''
  3893 + )}
  3894 +
3849 {record.paths?.includes('orderCancel') ? ( 3895 {record.paths?.includes('orderCancel') ? (
3850 <ButtonConfirm 3896 <ButtonConfirm
3851 className="p-0" 3897 className="p-0"
src/pages/ResearchGroup/components/ResearchGroupAddModal.tsx
@@ -267,9 +267,15 @@ export default ({ setVisible, researchGroupId, onClose }) =&gt; { @@ -267,9 +267,15 @@ export default ({ setVisible, researchGroupId, onClose }) =&gt; {
267 let uidIdMap = new Map( 267 let uidIdMap = new Map(
268 accounts.map((item: any) => [item.accountId, item.id]), 268 accounts.map((item: any) => [item.accountId, item.id]),
269 ); 269 );
270 - let res = await postCanrdApiUserList({  
271 - data: { uids: accountIds, phones: phones },  
272 - }); 270 + let data = {};
  271 + if (accountIds.length > 0) {
  272 + data = { ...data, uids: accountIds };
  273 + }
  274 + if (phones.length > 0) {
  275 + data = { ...data, phones: phones };
  276 + }
  277 +
  278 + let res = await postCanrdApiUserList({ data });
273 if (res && res.result === RESPONSE_CODE.SUCCESS) { 279 if (res && res.result === RESPONSE_CODE.SUCCESS) {
274 let accountList = res?.data?.data; 280 let accountList = res?.data?.data;
275 console.log(accountList); 281 console.log(accountList);
src/services/definition.ts
@@ -1472,6 +1472,7 @@ export interface InvoiceDto { @@ -1472,6 +1472,7 @@ export interface InvoiceDto {
1472 * 收款单位 1472 * 收款单位
1473 */ 1473 */
1474 payee?: string; 1474 payee?: string;
  1475 + payeeText?: string;
1475 /** 1476 /**
1476 * @description 1477 * @description
1477 * 购买方 1478 * 购买方
@@ -1500,6 +1501,8 @@ export interface InvoiceDto { @@ -1500,6 +1501,8 @@ export interface InvoiceDto {
1500 updateByName?: string; 1501 updateByName?: string;
1501 /** @format date-time */ 1502 /** @format date-time */
1502 updateTime?: string; 1503 updateTime?: string;
  1504 + /** @format int64 */
  1505 + writeOffId?: number;
1503 } 1506 }
1504 1507
1505 export interface InvoiceRecordDTO { 1508 export interface InvoiceRecordDTO {
@@ -2782,6 +2785,9 @@ export interface QueryBankStatementDto { @@ -2782,6 +2785,9 @@ export interface QueryBankStatementDto {
2782 status?: string; 2785 status?: string;
2783 /** @format int32 */ 2786 /** @format int32 */
2784 total?: number; 2787 total?: number;
  2788 + /** @format int64 */
  2789 + writeOffId?: number;
  2790 + writeOffIdIsNull?: boolean;
2785 } 2791 }
2786 2792
2787 export interface QueryClientDto { 2793 export interface QueryClientDto {
@@ -3166,6 +3172,14 @@ export interface QueryUseOldInvoicingDto { @@ -3166,6 +3172,14 @@ export interface QueryUseOldInvoicingDto {
3166 total?: number; 3172 total?: number;
3167 } 3173 }
3168 3174
  3175 +export interface QueryWriteOffRecordDto {
  3176 + /** @format int64 */
  3177 + id?: number;
  3178 + idIn?: Array<number>;
  3179 + /** @format int64 */
  3180 + invoiceId?: number;
  3181 +}
  3182 +
3169 export interface ReissueInvoiceDto { 3183 export interface ReissueInvoiceDto {
3170 /** @format int64 */ 3184 /** @format int64 */
3171 invoiceId?: number; 3185 invoiceId?: number;
src/services/request.ts
@@ -63,7 +63,6 @@ import type { @@ -63,7 +63,6 @@ import type {
63 MaterialUnitListRes, 63 MaterialUnitListRes,
64 MeasureUnitListRes, 64 MeasureUnitListRes,
65 MessageQueryDTO, 65 MessageQueryDTO,
66 - ModelAndView,  
67 OrderAddVO, 66 OrderAddVO,
68 OrderAuditLogQueryVO, 67 OrderAuditLogQueryVO,
69 OrderBaseInfoQueryVO, 68 OrderBaseInfoQueryVO,
@@ -101,6 +100,7 @@ import type { @@ -101,6 +100,7 @@ import type {
101 QueryProcureReturnBillDto, 100 QueryProcureReturnBillDto,
102 QueryReportFormsDto, 101 QueryReportFormsDto,
103 QueryUseOldInvoicingDto, 102 QueryUseOldInvoicingDto,
  103 + QueryWriteOffRecordDto,
104 ReissueInvoiceDto, 104 ReissueInvoiceDto,
105 ResearchGroupAddRequest, 105 ResearchGroupAddRequest,
106 ResearchGroupDeleteRequest, 106 ResearchGroupDeleteRequest,
@@ -3232,7 +3232,9 @@ export interface GetErrorResponse { @@ -3232,7 +3232,9 @@ export interface GetErrorResponse {
3232 * @description 3232 * @description
3233 * OK 3233 * OK
3234 */ 3234 */
3235 - 200: ModelAndView; 3235 + 200: {
  3236 + [propertyName: string]: any;
  3237 + };
3236 /** 3238 /**
3237 * @description 3239 * @description
3238 * Unauthorized 3240 * Unauthorized
@@ -3253,9 +3255,9 @@ export interface GetErrorResponse { @@ -3253,9 +3255,9 @@ export interface GetErrorResponse {
3253 export type GetErrorResponseSuccess = GetErrorResponse[200]; 3255 export type GetErrorResponseSuccess = GetErrorResponse[200];
3254 /** 3256 /**
3255 * @description 3257 * @description
3256 - * errorHtml 3258 + * error
3257 * @tags basic-error-controller 3259 * @tags basic-error-controller
3258 - * @produces text/html 3260 + * @produces *
3259 */ 3261 */
3260 export const getError = /* #__PURE__ */ (() => { 3262 export const getError = /* #__PURE__ */ (() => {
3261 const method = 'get'; 3263 const method = 'get';
@@ -3279,7 +3281,9 @@ export interface PutErrorResponse { @@ -3279,7 +3281,9 @@ export interface PutErrorResponse {
3279 * @description 3281 * @description
3280 * OK 3282 * OK
3281 */ 3283 */
3282 - 200: ModelAndView; 3284 + 200: {
  3285 + [propertyName: string]: any;
  3286 + };
3283 /** 3287 /**
3284 * @description 3288 * @description
3285 * Created 3289 * Created
@@ -3305,9 +3309,9 @@ export interface PutErrorResponse { @@ -3305,9 +3309,9 @@ export interface PutErrorResponse {
3305 export type PutErrorResponseSuccess = PutErrorResponse[200]; 3309 export type PutErrorResponseSuccess = PutErrorResponse[200];
3306 /** 3310 /**
3307 * @description 3311 * @description
3308 - * errorHtml 3312 + * error
3309 * @tags basic-error-controller 3313 * @tags basic-error-controller
3310 - * @produces text/html 3314 + * @produces *
3311 * @consumes application/json 3315 * @consumes application/json
3312 */ 3316 */
3313 export const putError = /* #__PURE__ */ (() => { 3317 export const putError = /* #__PURE__ */ (() => {
@@ -3332,7 +3336,9 @@ export interface PostErrorResponse { @@ -3332,7 +3336,9 @@ export interface PostErrorResponse {
3332 * @description 3336 * @description
3333 * OK 3337 * OK
3334 */ 3338 */
3335 - 200: ModelAndView; 3339 + 200: {
  3340 + [propertyName: string]: any;
  3341 + };
3336 /** 3342 /**
3337 * @description 3343 * @description
3338 * Created 3344 * Created
@@ -3358,9 +3364,9 @@ export interface PostErrorResponse { @@ -3358,9 +3364,9 @@ export interface PostErrorResponse {
3358 export type PostErrorResponseSuccess = PostErrorResponse[200]; 3364 export type PostErrorResponseSuccess = PostErrorResponse[200];
3359 /** 3365 /**
3360 * @description 3366 * @description
3361 - * errorHtml 3367 + * error
3362 * @tags basic-error-controller 3368 * @tags basic-error-controller
3363 - * @produces text/html 3369 + * @produces *
3364 * @consumes application/json 3370 * @consumes application/json
3365 */ 3371 */
3366 export const postError = /* #__PURE__ */ (() => { 3372 export const postError = /* #__PURE__ */ (() => {
@@ -3385,7 +3391,9 @@ export interface DeleteErrorResponse { @@ -3385,7 +3391,9 @@ export interface DeleteErrorResponse {
3385 * @description 3391 * @description
3386 * OK 3392 * OK
3387 */ 3393 */
3388 - 200: ModelAndView; 3394 + 200: {
  3395 + [propertyName: string]: any;
  3396 + };
3389 /** 3397 /**
3390 * @description 3398 * @description
3391 * No Content 3399 * No Content
@@ -3406,9 +3414,9 @@ export interface DeleteErrorResponse { @@ -3406,9 +3414,9 @@ export interface DeleteErrorResponse {
3406 export type DeleteErrorResponseSuccess = DeleteErrorResponse[200]; 3414 export type DeleteErrorResponseSuccess = DeleteErrorResponse[200];
3407 /** 3415 /**
3408 * @description 3416 * @description
3409 - * errorHtml 3417 + * error
3410 * @tags basic-error-controller 3418 * @tags basic-error-controller
3411 - * @produces text/html 3419 + * @produces *
3412 */ 3420 */
3413 export const deleteError = /* #__PURE__ */ (() => { 3421 export const deleteError = /* #__PURE__ */ (() => {
3414 const method = 'delete'; 3422 const method = 'delete';
@@ -3432,7 +3440,9 @@ export interface OptionsErrorResponse { @@ -3432,7 +3440,9 @@ export interface OptionsErrorResponse {
3432 * @description 3440 * @description
3433 * OK 3441 * OK
3434 */ 3442 */
3435 - 200: ModelAndView; 3443 + 200: {
  3444 + [propertyName: string]: any;
  3445 + };
3436 /** 3446 /**
3437 * @description 3447 * @description
3438 * No Content 3448 * No Content
@@ -3453,9 +3463,9 @@ export interface OptionsErrorResponse { @@ -3453,9 +3463,9 @@ export interface OptionsErrorResponse {
3453 export type OptionsErrorResponseSuccess = OptionsErrorResponse[200]; 3463 export type OptionsErrorResponseSuccess = OptionsErrorResponse[200];
3454 /** 3464 /**
3455 * @description 3465 * @description
3456 - * errorHtml 3466 + * error
3457 * @tags basic-error-controller 3467 * @tags basic-error-controller
3458 - * @produces text/html 3468 + * @produces *
3459 * @consumes application/json 3469 * @consumes application/json
3460 */ 3470 */
3461 export const optionsError = /* #__PURE__ */ (() => { 3471 export const optionsError = /* #__PURE__ */ (() => {
@@ -3480,7 +3490,9 @@ export interface HeadErrorResponse { @@ -3480,7 +3490,9 @@ export interface HeadErrorResponse {
3480 * @description 3490 * @description
3481 * OK 3491 * OK
3482 */ 3492 */
3483 - 200: ModelAndView; 3493 + 200: {
  3494 + [propertyName: string]: any;
  3495 + };
3484 /** 3496 /**
3485 * @description 3497 * @description
3486 * No Content 3498 * No Content
@@ -3501,9 +3513,9 @@ export interface HeadErrorResponse { @@ -3501,9 +3513,9 @@ export interface HeadErrorResponse {
3501 export type HeadErrorResponseSuccess = HeadErrorResponse[200]; 3513 export type HeadErrorResponseSuccess = HeadErrorResponse[200];
3502 /** 3514 /**
3503 * @description 3515 * @description
3504 - * errorHtml 3516 + * error
3505 * @tags basic-error-controller 3517 * @tags basic-error-controller
3506 - * @produces text/html 3518 + * @produces *
3507 * @consumes application/json 3519 * @consumes application/json
3508 */ 3520 */
3509 export const headError = /* #__PURE__ */ (() => { 3521 export const headError = /* #__PURE__ */ (() => {
@@ -3528,7 +3540,9 @@ export interface PatchErrorResponse { @@ -3528,7 +3540,9 @@ export interface PatchErrorResponse {
3528 * @description 3540 * @description
3529 * OK 3541 * OK
3530 */ 3542 */
3531 - 200: ModelAndView; 3543 + 200: {
  3544 + [propertyName: string]: any;
  3545 + };
3532 /** 3546 /**
3533 * @description 3547 * @description
3534 * No Content 3548 * No Content
@@ -3549,9 +3563,9 @@ export interface PatchErrorResponse { @@ -3549,9 +3563,9 @@ export interface PatchErrorResponse {
3549 export type PatchErrorResponseSuccess = PatchErrorResponse[200]; 3563 export type PatchErrorResponseSuccess = PatchErrorResponse[200];
3550 /** 3564 /**
3551 * @description 3565 * @description
3552 - * errorHtml 3566 + * error
3553 * @tags basic-error-controller 3567 * @tags basic-error-controller
3554 - * @produces text/html 3568 + * @produces *
3555 * @consumes application/json 3569 * @consumes application/json
3556 */ 3570 */
3557 export const patchError = /* #__PURE__ */ (() => { 3571 export const patchError = /* #__PURE__ */ (() => {
@@ -13443,6 +13457,60 @@ export const postServiceConstNotCanModifyInvoiceRecordStatus = @@ -13443,6 +13457,60 @@ export const postServiceConstNotCanModifyInvoiceRecordStatus =
13443 return request; 13457 return request;
13444 })(); 13458 })();
13445 13459
  13460 +/** @description response type for postServiceConstPayees */
  13461 +export interface PostServiceConstPayeesResponse {
  13462 + /**
  13463 + * @description
  13464 + * OK
  13465 + */
  13466 + 200: ServerResult;
  13467 + /**
  13468 + * @description
  13469 + * Created
  13470 + */
  13471 + 201: any;
  13472 + /**
  13473 + * @description
  13474 + * Unauthorized
  13475 + */
  13476 + 401: any;
  13477 + /**
  13478 + * @description
  13479 + * Forbidden
  13480 + */
  13481 + 403: any;
  13482 + /**
  13483 + * @description
  13484 + * Not Found
  13485 + */
  13486 + 404: any;
  13487 +}
  13488 +
  13489 +export type PostServiceConstPayeesResponseSuccess =
  13490 + PostServiceConstPayeesResponse[200];
  13491 +/**
  13492 + * @description
  13493 + * 开具类型
  13494 + * @tags front-const-controller
  13495 + * @produces *
  13496 + * @consumes application/json
  13497 + */
  13498 +export const postServiceConstPayees = /* #__PURE__ */ (() => {
  13499 + const method = 'post';
  13500 + const url = '/service/const/payees';
  13501 + function request(): Promise<PostServiceConstPayeesResponseSuccess> {
  13502 + return requester(request.url, {
  13503 + method: request.method,
  13504 + }) as unknown as Promise<PostServiceConstPayeesResponseSuccess>;
  13505 + }
  13506 +
  13507 + /** http method */
  13508 + request.method = method;
  13509 + /** request url */
  13510 + request.url = url;
  13511 + return request;
  13512 +})();
  13513 +
13446 /** @description response type for postServiceConstProcureReturnBills */ 13514 /** @description response type for postServiceConstProcureReturnBills */
13447 export interface PostServiceConstProcureReturnBillsResponse { 13515 export interface PostServiceConstProcureReturnBillsResponse {
13448 /** 13516 /**
@@ -14639,6 +14707,77 @@ export const postServiceInvoiceGetInvoicingAccount = /* #__PURE__ */ (() =&gt; { @@ -14639,6 +14707,77 @@ export const postServiceInvoiceGetInvoicingAccount = /* #__PURE__ */ (() =&gt; {
14639 return request; 14707 return request;
14640 })(); 14708 })();
14641 14709
  14710 +/** @description request parameter type for postServiceInvoiceGetWriteOffRecord */
  14711 +export interface PostServiceInvoiceGetWriteOffRecordOption {
  14712 + /**
  14713 + * @description
  14714 + * dto
  14715 + */
  14716 + body: {
  14717 + /**
  14718 + @description
  14719 + dto */
  14720 + dto: QueryWriteOffRecordDto;
  14721 + };
  14722 +}
  14723 +
  14724 +/** @description response type for postServiceInvoiceGetWriteOffRecord */
  14725 +export interface PostServiceInvoiceGetWriteOffRecordResponse {
  14726 + /**
  14727 + * @description
  14728 + * OK
  14729 + */
  14730 + 200: ServerResult;
  14731 + /**
  14732 + * @description
  14733 + * Created
  14734 + */
  14735 + 201: any;
  14736 + /**
  14737 + * @description
  14738 + * Unauthorized
  14739 + */
  14740 + 401: any;
  14741 + /**
  14742 + * @description
  14743 + * Forbidden
  14744 + */
  14745 + 403: any;
  14746 + /**
  14747 + * @description
  14748 + * Not Found
  14749 + */
  14750 + 404: any;
  14751 +}
  14752 +
  14753 +export type PostServiceInvoiceGetWriteOffRecordResponseSuccess =
  14754 + PostServiceInvoiceGetWriteOffRecordResponse[200];
  14755 +/**
  14756 + * @description
  14757 + * 获取核销记录
  14758 + * @tags 发票
  14759 + * @produces *
  14760 + * @consumes application/json
  14761 + */
  14762 +export const postServiceInvoiceGetWriteOffRecord = /* #__PURE__ */ (() => {
  14763 + const method = 'post';
  14764 + const url = '/service/invoice/getWriteOffRecord';
  14765 + function request(
  14766 + option: PostServiceInvoiceGetWriteOffRecordOption,
  14767 + ): Promise<PostServiceInvoiceGetWriteOffRecordResponseSuccess> {
  14768 + return requester(request.url, {
  14769 + method: request.method,
  14770 + ...option,
  14771 + }) as unknown as Promise<PostServiceInvoiceGetWriteOffRecordResponseSuccess>;
  14772 + }
  14773 +
  14774 + /** http method */
  14775 + request.method = method;
  14776 + /** request url */
  14777 + request.url = url;
  14778 + return request;
  14779 +})();
  14780 +
14642 /** @description request parameter type for postServiceInvoiceImportInvoiceDetails */ 14781 /** @description request parameter type for postServiceInvoiceImportInvoiceDetails */
14643 export interface PostServiceInvoiceImportInvoiceDetailsOption { 14782 export interface PostServiceInvoiceImportInvoiceDetailsOption {
14644 /** 14783 /**
@@ -16332,6 +16471,77 @@ export const postServiceOrderCancelSend = /* #__PURE__ */ (() =&gt; { @@ -16332,6 +16471,77 @@ export const postServiceOrderCancelSend = /* #__PURE__ */ (() =&gt; {
16332 return request; 16471 return request;
16333 })(); 16472 })();
16334 16473
  16474 +/** @description request parameter type for postServiceOrderConfirmInvoice */
  16475 +export interface PostServiceOrderConfirmInvoiceOption {
  16476 + /**
  16477 + * @description
  16478 + * subIds
  16479 + */
  16480 + query: {
  16481 + /**
  16482 + @description
  16483 + subIds */
  16484 + subIds: Array<number>;
  16485 + };
  16486 +}
  16487 +
  16488 +/** @description response type for postServiceOrderConfirmInvoice */
  16489 +export interface PostServiceOrderConfirmInvoiceResponse {
  16490 + /**
  16491 + * @description
  16492 + * OK
  16493 + */
  16494 + 200: ServerResult;
  16495 + /**
  16496 + * @description
  16497 + * Created
  16498 + */
  16499 + 201: any;
  16500 + /**
  16501 + * @description
  16502 + * Unauthorized
  16503 + */
  16504 + 401: any;
  16505 + /**
  16506 + * @description
  16507 + * Forbidden
  16508 + */
  16509 + 403: any;
  16510 + /**
  16511 + * @description
  16512 + * Not Found
  16513 + */
  16514 + 404: any;
  16515 +}
  16516 +
  16517 +export type PostServiceOrderConfirmInvoiceResponseSuccess =
  16518 + PostServiceOrderConfirmInvoiceResponse[200];
  16519 +/**
  16520 + * @description
  16521 + * 确认发票
  16522 + * @tags 内部订单
  16523 + * @produces *
  16524 + * @consumes application/json
  16525 + */
  16526 +export const postServiceOrderConfirmInvoice = /* #__PURE__ */ (() => {
  16527 + const method = 'post';
  16528 + const url = '/service/order/confirmInvoice';
  16529 + function request(
  16530 + option: PostServiceOrderConfirmInvoiceOption,
  16531 + ): Promise<PostServiceOrderConfirmInvoiceResponseSuccess> {
  16532 + return requester(request.url, {
  16533 + method: request.method,
  16534 + ...option,
  16535 + }) as unknown as Promise<PostServiceOrderConfirmInvoiceResponseSuccess>;
  16536 + }
  16537 +
  16538 + /** http method */
  16539 + request.method = method;
  16540 + /** request url */
  16541 + request.url = url;
  16542 + return request;
  16543 +})();
  16544 +
16335 /** @description request parameter type for postServiceOrderConfirmReceipt */ 16545 /** @description request parameter type for postServiceOrderConfirmReceipt */
16336 export interface PostServiceOrderConfirmReceiptOption { 16546 export interface PostServiceOrderConfirmReceiptOption {
16337 /** 16547 /**