Commit 1206ec5f5162227af06c4bc68d181e9475a90b74

Authored by zhongnanhuang
2 parents c4c7f263 c2de444b

Merge branch 'znh-invoice' into znh

# Conflicts:
#	src/services/definition.ts
#	src/utils/index.ts
.umirc.ts
@@ -45,13 +45,13 @@ export default defineConfig({ @@ -45,13 +45,13 @@ export default defineConfig({
45 icon: 'LineChartOutlined', 45 icon: 'LineChartOutlined',
46 access: 'canReadAdmin', 46 access: 'canReadAdmin',
47 }, 47 },
48 - // {  
49 - // name: '发票管理',  
50 - // path: '/invoiceManage',  
51 - // component: './Invoice',  
52 - // icon: 'BookOutlined',  
53 - // access: 'canReadAdmin',  
54 - // }, 48 + {
  49 + name: '发票管理',
  50 + path: '/invoiceManage',
  51 + component: './Invoice',
  52 + icon: 'BookOutlined',
  53 + access: 'canReadAdminAndFinance',
  54 + },
55 { 55 {
56 name: '打印', 56 name: '打印',
57 path: '/print', 57 path: '/print',
src/access.ts
@@ -6,5 +6,7 @@ export default (initialState: API.UserInfo) => { @@ -6,5 +6,7 @@ export default (initialState: API.UserInfo) => {
6 return { 6 return {
7 canReadAdmin: roleSmallVO?.code === 'admin', 7 canReadAdmin: roleSmallVO?.code === 'admin',
8 canReadProcure: roleSmallVO?.code === 'procure', 8 canReadProcure: roleSmallVO?.code === 'procure',
  9 + canReadAdminAndFinance:
  10 + roleSmallVO?.code === 'admin' || roleSmallVO?.code === 'finance',
9 }; 11 };
10 }; 12 };
src/components/Div/EllipsisDiv.tsx 0 → 100644
  1 +const EllipsisDiv = ({ text }: { text: string }) => {
  2 + return (
  3 + <div
  4 + title={text}
  5 + className="overflow-hidden whitespace-no-wrap overflow-ellipsis whitespace-nowrap"
  6 + >
  7 + {text}
  8 + </div>
  9 + );
  10 +};
  11 +
  12 +export default EllipsisDiv;
src/pages/Invoice/components/BankChooseModal.tsx 0 → 100644
  1 +import EllipsisDiv from '@/components/Div/EllipsisDiv';
  2 +import { RESPONSE_CODE } from '@/constants/enum';
  3 +import { INVOCING_STATUS, PAYEE_OPTIONS } from '@/pages/Order/constant';
  4 +import {
  5 + postServiceBankStatementQueryBankStatement,
  6 + postServiceInvoiceInvoiceWriteOff,
  7 +} from '@/services';
  8 +import { FloatAdd, FloatSub, enumValueToLabel, formatDateTime } from '@/utils';
  9 +import { formatDate } from '@/utils/time';
  10 +
  11 +import { ActionType, ProCard, ProTable } from '@ant-design/pro-components';
  12 +import { Button, Divider, Flex, Modal, Tag, message } from 'antd';
  13 +import { useRef, useState } from 'react';
  14 +import { BANK_STATEMENT_COLUMNS, INVOICE_STATUS } from '../constant';
  15 +import '../index.less';
  16 +export default ({ invoiceId, setVisible, onClose }) => {
  17 + const [selectedStatement, setSelectedStatement] = useState([]);
  18 + const [selectedStatementIdSet, setSelectedStatementIdSet] = useState(
  19 + new Set(),
  20 + );
  21 + const [totalAmount, setTotalAmount] = useState(0);
  22 +
  23 + // 添加元素到Set
  24 + const addElement = (element) => {
  25 + setSelectedStatementIdSet((prevSet) => new Set([...prevSet, element]));
  26 + };
  27 +
  28 + // 从Set中删除元素
  29 + const removeElement = (element) => {
  30 + setSelectedStatementIdSet((prevSet) => {
  31 + const newSet = new Set(prevSet);
  32 + newSet.delete(element);
  33 + return newSet;
  34 + });
  35 + };
  36 +
  37 + const [btnLoading, setBtnLoading] = useState(false);
  38 +
  39 + const actionRef = useRef<ActionType>();
  40 + const getTableCellText = (target: any) => {
  41 + if (!target) {
  42 + return '';
  43 + }
  44 +
  45 + if (target.props) {
  46 + return target.props.text;
  47 + }
  48 +
  49 + return target;
  50 + };
  51 +
  52 + /**
  53 + * 加载银行流水列表表格的各个列格式
  54 + */
  55 + const bankStatementColumnsInit = () => {
  56 + let columns = BANK_STATEMENT_COLUMNS.map((item) => {
  57 + let newItem = { ...item };
  58 + let dataIndex = item.dataIndex;
  59 + let dataType = item.valueType;
  60 +
  61 + if (item.dataIndex === 'status') {
  62 + newItem.hideInSearch = true;
  63 + }
  64 +
  65 + newItem.render = (text, record) => {
  66 + let textValue = record[dataIndex];
  67 +
  68 + if (dataType === 'date') {
  69 + textValue = formatDate(textValue);
  70 + }
  71 +
  72 + if (dataType === 'dateTime') {
  73 + textValue = formatDateTime(textValue);
  74 + }
  75 +
  76 + if (dataType === 'money') {
  77 + textValue = '¥' + textValue;
  78 + }
  79 +
  80 + switch (dataIndex) {
  81 + case 'invoiceStatus':
  82 + return (
  83 + <EllipsisDiv
  84 + text={enumValueToLabel(
  85 + getTableCellText(textValue),
  86 + INVOCING_STATUS,
  87 + )}
  88 + />
  89 + );
  90 +
  91 + case 'status': {
  92 + //这里状态不显示在筛选条件中,只能筛异常的流水
  93 + return (
  94 + <EllipsisDiv
  95 + text={enumValueToLabel(
  96 + getTableCellText(textValue),
  97 + INVOICE_STATUS,
  98 + )}
  99 + />
  100 + );
  101 + }
  102 + case 'payee':
  103 + return (
  104 + <EllipsisDiv
  105 + text={enumValueToLabel(
  106 + getTableCellText(textValue),
  107 + PAYEE_OPTIONS,
  108 + )}
  109 + />
  110 + );
  111 +
  112 + default:
  113 + return <EllipsisDiv text={getTableCellText(textValue)} />;
  114 + }
  115 + };
  116 +
  117 + return newItem;
  118 + });
  119 +
  120 + columns.push({
  121 + title: '操作',
  122 + valueType: 'option',
  123 + key: 'option',
  124 + fixed: 'right',
  125 + width: 70,
  126 + render: (text, record) => [
  127 + <Button
  128 + className="p-0"
  129 + key="choose"
  130 + type="link"
  131 + onClick={() => {
  132 + let amount = record.loanAmount || record.transactionAmount || 0;
  133 +
  134 + //已经选中,取消选中
  135 + if (selectedStatementIdSet.has(record.id)) {
  136 + setSelectedStatement(
  137 + selectedStatement.filter((item) => {
  138 + return item.id !== record.id;
  139 + }),
  140 + );
  141 + removeElement(record.id);
  142 + setTotalAmount(parseFloat(FloatSub(totalAmount, amount)));
  143 + } else {
  144 + //添加到已选中区域中
  145 + let newSelectedStatement = [...selectedStatement];
  146 + newSelectedStatement.push(record);
  147 + setSelectedStatement(newSelectedStatement);
  148 + addElement(record.id);
  149 + setTotalAmount(FloatAdd(totalAmount, amount));
  150 + }
  151 + }}
  152 + >
  153 + {selectedStatementIdSet.has(record.id) ? '取消选中' : '选中'}
  154 + </Button>,
  155 + ],
  156 + });
  157 +
  158 + return columns;
  159 + };
  160 +
  161 + /**
  162 + * 删除已选中
  163 + * @param record
  164 + */
  165 + const removeSelectedStatement = (record: any) => {
  166 + setSelectedStatement(
  167 + selectedStatement.filter((item) => {
  168 + return item.id !== record.id;
  169 + }),
  170 + );
  171 + removeElement(record.id);
  172 + };
  173 +
  174 + const showSelectedStatement = () => {
  175 + let i = 0;
  176 +
  177 + let tags = selectedStatement.map((item) => {
  178 + console.log(item);
  179 + let tagText = item.id;
  180 +
  181 + if (item.payeePayerName) {
  182 + tagText += ' ' + item.payeePayerName + ' ';
  183 + }
  184 +
  185 + if (item.loanAmount) {
  186 + tagText += item.loanAmount + ' ';
  187 + }
  188 +
  189 + if (item.transactionAmount) {
  190 + tagText += item.transactionAmount;
  191 + }
  192 +
  193 + return (
  194 + <Tag
  195 + key={i++}
  196 + closable={true}
  197 + style={{ userSelect: 'none' }}
  198 + color="blue"
  199 + onClose={(e) => {
  200 + e.preventDefault(); //需要加上这句代码,不然删除tag时,当前tag的下一个tag会被设置ant-tag-hidden
  201 + removeSelectedStatement(item);
  202 + }}
  203 + >
  204 + <span>{tagText}</span>
  205 + </Tag>
  206 + );
  207 + });
  208 +
  209 + console.log(tags);
  210 +
  211 + return tags;
  212 + };
  213 +
  214 + return (
  215 + <>
  216 + <Modal
  217 + open
  218 + width="80%"
  219 + title="添加银行流水"
  220 + className="bank-statement-choose"
  221 + onOk={async () => {
  222 + setBtnLoading(true);
  223 + let bankStatementIds = selectedStatement?.map((item) => {
  224 + return item.id;
  225 + });
  226 + let res = await postServiceInvoiceInvoiceWriteOff({
  227 + data: {
  228 + invoiceId: invoiceId,
  229 + bankStatementIds: bankStatementIds,
  230 + },
  231 + });
  232 +
  233 + if (res.result === RESPONSE_CODE.SUCCESS) {
  234 + if (res.data?.length > 0) {
  235 + message.info(res.data);
  236 + } else {
  237 + message.success(res.message);
  238 + }
  239 +
  240 + onClose();
  241 + }
  242 +
  243 + setBtnLoading(false);
  244 + }}
  245 + okButtonProps={{
  246 + loading: btnLoading,
  247 + }}
  248 + onCancel={() => {
  249 + setVisible(false);
  250 + }}
  251 + >
  252 + <Divider orientation="left" plain>
  253 + 已选中(合计:¥{totalAmount})
  254 + </Divider>
  255 + <ProCard className="mb-[16px]" bordered style={{}}>
  256 + <Flex wrap="wrap" gap="small">
  257 + {showSelectedStatement()}
  258 + </Flex>
  259 + </ProCard>
  260 +
  261 + <ProTable
  262 + columns={bankStatementColumnsInit()}
  263 + actionRef={actionRef}
  264 + cardBordered
  265 + pagination={{
  266 + pageSize: 10,
  267 + }}
  268 + editable={{
  269 + type: 'multiple',
  270 + onSave: async (rowKey, data) => {
  271 + console.log(rowKey, data);
  272 + },
  273 + actionRender: (row, config, defaultDom) => [
  274 + defaultDom.save,
  275 + defaultDom.cancel,
  276 + ],
  277 + }}
  278 + request={async (params) => {
  279 + const res = await postServiceBankStatementQueryBankStatement({
  280 + data: { ...params, status: 'ABNORMAL' },
  281 + });
  282 + if (res) {
  283 + return {
  284 + data: res?.data?.data || [],
  285 + total: res?.data?.total || 0,
  286 + };
  287 + }
  288 + }}
  289 + columnsState={{
  290 + persistenceKey: 'pro-table-singe-demos',
  291 + persistenceType: 'localStorage',
  292 + defaultValue: {
  293 + option: { fixed: 'right', disable: true },
  294 + },
  295 + onChange(value) {
  296 + console.log('value: ', value);
  297 + },
  298 + }}
  299 + rowKey="id"
  300 + search={{
  301 + labelWidth: 'auto',
  302 + }}
  303 + options={{
  304 + setting: {
  305 + listsHeight: 400,
  306 + },
  307 + }}
  308 + form={{}}
  309 + dateFormatter="string"
  310 + headerTitle="银行流水列表"
  311 + scroll={{ x: 1400, y: 360 }}
  312 + toolBarRender={() => []}
  313 + />
  314 + </Modal>
  315 + </>
  316 + );
  317 +};
src/pages/Invoice/components/BankImportModal.tsx 0 → 100644
  1 +import { RESPONSE_CODE } from '@/constants/enum';
  2 +import { blobToJson } from '@/utils';
  3 +
  4 +import { UploadOutlined } from '@ant-design/icons';
  5 +import { ModalForm } from '@ant-design/pro-components';
  6 +import { Button, Form, Upload, UploadFile, UploadProps, message } from 'antd';
  7 +import { RcFile } from 'antd/es/upload';
  8 +import axios from 'axios';
  9 +import { useState } from 'react';
  10 +
  11 +// import { cloneDeep } from 'lodash';
  12 +export default ({ setVisible, onClose }) => {
  13 + const [form] = Form.useForm<{ name: string; company: string }>();
  14 + const [fileList, setFileList] = useState<UploadFile[]>([]);
  15 + const handleChange: UploadProps['onChange'] = ({ fileList: newFileList }) =>
  16 + setFileList(newFileList);
  17 +
  18 + const [messageApi, contextHolder] = message.useMessage();
  19 + const [uploadLoading, setUploading] = useState(false);
  20 + console.log(uploadLoading);
  21 +
  22 + const exportLoading = (content: string) => {
  23 + messageApi.open({
  24 + type: 'loading',
  25 + content: content,
  26 + duration: 0,
  27 + });
  28 + };
  29 +
  30 + const downloadImportTemplate = async () => {
  31 + exportLoading('正在下载......');
  32 + axios({
  33 + url: '/api/service/bankStatement/exportTemplate',
  34 + method: 'post',
  35 + responseType: 'blob',
  36 + headers: { Authorization: localStorage.getItem('token') },
  37 + })
  38 + .then((response) => {
  39 + console.log(response);
  40 + // 创建一个新的 Blob 对象,它包含了服务器响应的数据(即你的 Excel 文件)
  41 + const blob = new Blob([response.data]); // Excel 的 MIME 类型
  42 + const downloadUrl = window.URL.createObjectURL(blob);
  43 + const a = document.createElement('a');
  44 + a.href = downloadUrl;
  45 + a.download = '银行流水导入模板.xlsx'; // 你可以为文件命名
  46 + document.body.appendChild(a);
  47 + a.click(); // 模拟点击操作来下载文件
  48 + URL.revokeObjectURL(downloadUrl); // 释放掉 blob 对象所占用的内存
  49 + document.body.removeChild(a);
  50 + })
  51 + .catch((error) => {
  52 + // 处理错误
  53 + console.error('导出错误', error);
  54 + })
  55 + .finally(() => {
  56 + messageApi.destroy();
  57 + });
  58 + };
  59 + const handleUpload = async () => {
  60 + exportLoading('正在导入......');
  61 +
  62 + const formData = new FormData();
  63 + fileList.forEach((file) => {
  64 + formData.append('file', file.originFileObj as RcFile);
  65 + });
  66 +
  67 + setUploading(true);
  68 +
  69 + axios({
  70 + url: '/api/service/bankStatement/importBankStatementForm',
  71 + method: 'post',
  72 + responseType: 'blob',
  73 + headers: {
  74 + Authorization: localStorage.getItem('token'),
  75 + 'Content-Type':
  76 + 'multipart/form-data; boundary=----WebKitFormBoundarynl6gT1BKdPWIejNq',
  77 + },
  78 + data: formData,
  79 + })
  80 + .then((response) => {
  81 + let data = response.data;
  82 + if (data.type === 'application/json') {
  83 + blobToJson(data).then((dataJson) => {
  84 + if (dataJson?.result === RESPONSE_CODE.SUCCESS) {
  85 + message.success(dataJson?.message);
  86 + } else {
  87 + message.error(dataJson?.message);
  88 + }
  89 + });
  90 + } else {
  91 + message.error('上传失败,已下载错误信息表格');
  92 + // 创建一个新的 Blob 对象,它包含了服务器响应的数据(即你的 Excel 文件)
  93 + const blob = new Blob([response.data]); // Excel 的 MIME 类型
  94 + const downloadUrl = window.URL.createObjectURL(blob);
  95 + const a = document.createElement('a');
  96 + a.href = downloadUrl;
  97 + a.download = '银行流水导入模板.xlsx'; // 你可以为文件命名
  98 + document.body.appendChild(a);
  99 + a.click(); // 模拟点击操作来下载文件
  100 + URL.revokeObjectURL(downloadUrl); // 释放掉 blob 对象所占用的内存
  101 + document.body.removeChild(a);
  102 + onClose();
  103 + }
  104 + })
  105 + .catch((error) => {
  106 + // 处理错误
  107 + message.error('系统出现异常了,请联系管理员', error);
  108 + })
  109 + .finally(() => {
  110 + setUploading(false);
  111 + messageApi.destroy();
  112 + });
  113 + };
  114 + const props: UploadProps = {
  115 + onRemove: (file) => {
  116 + const index = fileList.indexOf(file);
  117 + const newFileList = fileList.slice();
  118 + newFileList.splice(index, 1);
  119 + setFileList(newFileList);
  120 + },
  121 + beforeUpload: (file) => {
  122 + setFileList([...fileList, file]);
  123 +
  124 + return false;
  125 + },
  126 + fileList,
  127 + onChange: handleChange,
  128 + accept: '.xlsx',
  129 + };
  130 +
  131 + return (
  132 + <>
  133 + <ModalForm<{
  134 + name: string;
  135 + company: string;
  136 + }>
  137 + width={500}
  138 + open
  139 + title="银行流水导入"
  140 + form={form}
  141 + autoFocusFirstInput
  142 + modalProps={{
  143 + okText: '确定',
  144 + cancelText: '取消',
  145 + destroyOnClose: true,
  146 + onCancel: () => {
  147 + setVisible(false);
  148 + },
  149 + }}
  150 + onFinish={async () => {
  151 + handleUpload();
  152 + onClose();
  153 + }}
  154 + onOpenChange={setVisible}
  155 + >
  156 + <div className="py-4 font-semibold">
  157 + 导入银行流水
  158 + <Button type="link" onClick={downloadImportTemplate}>
  159 + 下载导入模板
  160 + </Button>
  161 + </div>
  162 + <Upload {...props}>
  163 + <Button icon={<UploadOutlined />} disabled={fileList.length > 0}>
  164 + 点击选择文件
  165 + </Button>
  166 + </Upload>
  167 + </ModalForm>
  168 +
  169 + {contextHolder}
  170 + </>
  171 + );
  172 +};
src/pages/Invoice/components/InvoiceVerificationModal.tsx 0 → 100644
  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';
  5 +import {
  6 + postServiceInvoiceCancelInvoiceAndBankStatement,
  7 + postServiceInvoiceQueryInvoiceDetail,
  8 +} from '@/services';
  9 +import { enumValueToLabel, formatDateTime } from '@/utils';
  10 +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';
  18 +import {
  19 + Button,
  20 + Descriptions,
  21 + DescriptionsProps,
  22 + Divider,
  23 + Flex,
  24 + Form,
  25 + message,
  26 +} from 'antd';
  27 +import { useEffect, useRef, useState } from 'react';
  28 +import { BANK_STATEMENT_COLUMNS, INVOICE_STATUS } from '../constant';
  29 +import '../index.less';
  30 +import BankChooseModal from './BankChooseModal';
  31 +
  32 +export default ({ invoiceId, setVisible, onClose }) => {
  33 + const [form] = Form.useForm<{ id: string }>();
  34 + const [bankChooseModalVisible, setBankChooseModalVisible] = useState(false);
  35 + const [invoiceInfo, setInvoiceInfo] = useState({});
  36 + const [relationOrderIds, setRelationOrderIds] = useState([]);
  37 + const [relationBankStatements, setRelationBankStatements] = useState([]);
  38 + const actionRef = useRef<ActionType>();
  39 +
  40 + const loadInvoiceData = async () => {
  41 + let res = await postServiceInvoiceQueryInvoiceDetail({
  42 + data: { invoiceId: invoiceId },
  43 + });
  44 + if (res && res.data) {
  45 + setInvoiceInfo(res.data);
  46 + setRelationOrderIds(res.data.mainOrderIds);
  47 + setRelationBankStatements(res.data.bankStatementResponseDtos);
  48 + }
  49 + };
  50 +
  51 + const showRelationOrders = () => {
  52 + return relationOrderIds?.map((item) => {
  53 + return (
  54 + <>
  55 + <Button
  56 + className="pl-1 pr-0"
  57 + type="link"
  58 + target="_blank"
  59 + href={'/order?id=' + item}
  60 + >
  61 + {item}
  62 + </Button>
  63 + <Divider type="vertical" />
  64 + </>
  65 + );
  66 + });
  67 + };
  68 +
  69 + const items: DescriptionsProps['items'] = [
  70 + {
  71 + key: '1',
  72 + label: '发票号码',
  73 + children: invoiceInfo?.invoiceNumber,
  74 + span: 6,
  75 + },
  76 + {
  77 + key: '2',
  78 + label: '发票类型',
  79 + children: enumValueToLabel(invoiceInfo?.invoiceStatus, INVOCING_STATUS),
  80 + span: 6,
  81 + },
  82 + {
  83 + key: '3',
  84 + label: '状态',
  85 + children: enumValueToLabel(invoiceInfo?.status, INVOICE_STATUS),
  86 + span: 4,
  87 + },
  88 + {
  89 + key: '4',
  90 + label: '购买方',
  91 + children: invoiceInfo?.purchaser,
  92 + span: 8,
  93 + },
  94 + {
  95 + key: '5',
  96 + label: '收款单位',
  97 + children: enumValueToLabel(invoiceInfo?.payee, PAYEE_OPTIONS),
  98 + span: 12,
  99 + },
  100 + {
  101 + key: '6',
  102 + label: '联系人',
  103 + children: invoiceInfo?.contacts,
  104 + span: 4,
  105 + },
  106 + {
  107 + key: '7',
  108 + label: '销售',
  109 + children: invoiceInfo?.sale,
  110 + span: 8,
  111 + },
  112 +
  113 + {
  114 + key: '9',
  115 + label: '开票日期',
  116 + children: formatDate(invoiceInfo?.invoicingTime),
  117 + span: 12,
  118 + },
  119 + {
  120 + key: '10',
  121 + label: '收款时间',
  122 + children: formatDate(invoiceInfo?.collectionTime),
  123 + span: 4,
  124 + },
  125 + {
  126 + key: '8',
  127 + label: '金额',
  128 + children: invoiceInfo?.money,
  129 + span: 10,
  130 + },
  131 + {
  132 + key: '11',
  133 + label: '备注',
  134 + children: invoiceInfo?.notes,
  135 + span: 24,
  136 + },
  137 + ];
  138 +
  139 + const getTableCellText = (target: any) => {
  140 + if (!target) {
  141 + return '';
  142 + }
  143 +
  144 + if (target.props) {
  145 + return target.props.text;
  146 + }
  147 +
  148 + return target;
  149 + };
  150 +
  151 + /**
  152 + * 加载银行流水列表表格的各个列格式
  153 + */
  154 + const bankStatementColumnsInit = () => {
  155 + let columns = BANK_STATEMENT_COLUMNS.map((item) => {
  156 + let newItem = { ...item };
  157 + let dataIndex = item.dataIndex;
  158 + let dataType = item.valueType;
  159 +
  160 + newItem.render = (text, record) => {
  161 + let textValue = record[dataIndex];
  162 +
  163 + if (dataType === 'date') {
  164 + textValue = formatDate(textValue);
  165 + }
  166 +
  167 + if (dataType === 'dateTime') {
  168 + textValue = formatDateTime(textValue);
  169 + }
  170 +
  171 + if (dataType === 'money') {
  172 + textValue = '¥' + textValue;
  173 + }
  174 +
  175 + switch (dataIndex) {
  176 + case 'invoiceStatus':
  177 + return (
  178 + <EllipsisDiv
  179 + text={enumValueToLabel(
  180 + getTableCellText(textValue),
  181 + INVOCING_STATUS,
  182 + )}
  183 + />
  184 + );
  185 +
  186 + case 'status':
  187 + return (
  188 + <EllipsisDiv
  189 + text={enumValueToLabel(
  190 + getTableCellText(textValue),
  191 + INVOICE_STATUS,
  192 + )}
  193 + />
  194 + );
  195 +
  196 + case 'payee':
  197 + return (
  198 + <EllipsisDiv
  199 + text={enumValueToLabel(
  200 + getTableCellText(textValue),
  201 + PAYEE_OPTIONS,
  202 + )}
  203 + />
  204 + );
  205 +
  206 + default:
  207 + return <EllipsisDiv text={getTableCellText(textValue)} />;
  208 + }
  209 + };
  210 +
  211 + return newItem;
  212 + });
  213 +
  214 + columns.push({
  215 + title: '操作',
  216 + valueType: 'option',
  217 + key: 'option',
  218 + fixed: 'right',
  219 + width: 70,
  220 + render: (text, record) => {
  221 + let optBtns = [];
  222 + if (invoiceInfo?.status === 'VERIFIED') {
  223 + return [];
  224 + }
  225 +
  226 + optBtns.push(
  227 + <ButtonConfirm
  228 + key="delete"
  229 + className="p-0"
  230 + title={'确认删除此项吗?'}
  231 + text="删除"
  232 + onConfirm={async () => {
  233 + let res = await postServiceInvoiceCancelInvoiceAndBankStatement({
  234 + data: {
  235 + invoiceId: invoiceId,
  236 + cancelId: [record.id],
  237 + },
  238 + });
  239 + if (res.result === RESPONSE_CODE.SUCCESS) {
  240 + message.success(res.message);
  241 + loadInvoiceData();
  242 + }
  243 + }}
  244 + />,
  245 + );
  246 + return optBtns;
  247 + },
  248 + });
  249 +
  250 + return columns;
  251 + };
  252 +
  253 + useEffect(() => {
  254 + loadInvoiceData();
  255 + }, []);
  256 +
  257 + return (
  258 + <>
  259 + <ModalForm<{
  260 + id: string;
  261 + }>
  262 + className="invoice-detail"
  263 + open
  264 + width="80%"
  265 + title="发票详情"
  266 + form={form}
  267 + autoFocusFirstInput
  268 + modalProps={{
  269 + okText: '确定',
  270 + cancelText: '返回',
  271 + destroyOnClose: true,
  272 + onCancel: () => {
  273 + setVisible(false);
  274 + onClose();
  275 + },
  276 + }}
  277 + submitter={{
  278 + render: (props, defaultDoms) => {
  279 + return [defaultDoms[0]];
  280 + },
  281 + }}
  282 + onFinish={async () => {
  283 + onClose();
  284 + }}
  285 + onOpenChange={setVisible}
  286 + >
  287 + <Divider orientation="left" plain>
  288 + 发票信息
  289 + </Divider>
  290 +
  291 + <Descriptions
  292 + bordered
  293 + column={24}
  294 + size="small"
  295 + title=""
  296 + items={items}
  297 + />
  298 +
  299 + <Divider orientation="left" plain>
  300 + 订单号
  301 + </Divider>
  302 +
  303 + <ProCard bordered style={{}}>
  304 + <Flex>
  305 + <div>{showRelationOrders()}</div>
  306 + </Flex>
  307 + </ProCard>
  308 +
  309 + <Divider plain></Divider>
  310 +
  311 + <ProTable
  312 + columns={bankStatementColumnsInit()}
  313 + actionRef={actionRef}
  314 + cardBordered
  315 + pagination={{
  316 + pageSize: 10,
  317 + }}
  318 + dataSource={relationBankStatements}
  319 + columnsState={{
  320 + persistenceKey: 'pro-table-singe-demos',
  321 + persistenceType: 'localStorage',
  322 + defaultValue: {
  323 + option: { fixed: 'right', disable: true },
  324 + },
  325 + onChange(value) {
  326 + console.log('value: ', value);
  327 + },
  328 + }}
  329 + rowKey="id"
  330 + search={false}
  331 + options={{
  332 + setting: {
  333 + listsHeight: 400,
  334 + },
  335 + reload: false,
  336 + }}
  337 + form={{
  338 + // 由于配置了 transform,提交的参与与定义的不同这里需要转化一下
  339 + syncToUrl: (values, type) => {
  340 + if (type === 'get') {
  341 + return {
  342 + ...values,
  343 + created_at: [values.startTime, values.endTime],
  344 + };
  345 + }
  346 + return values;
  347 + },
  348 + }}
  349 + dateFormatter="string"
  350 + headerTitle="银行流水"
  351 + scroll={{ x: 1400, y: 360 }}
  352 + toolBarRender={() => [
  353 + <Button
  354 + key="button"
  355 + icon={<PlusOutlined />}
  356 + onClick={() => {
  357 + setBankChooseModalVisible(true);
  358 + }}
  359 + hidden={invoiceInfo?.status === 'VERIFIED'}
  360 + type="primary"
  361 + >
  362 + 添加
  363 + </Button>,
  364 + ]}
  365 + />
  366 + </ModalForm>
  367 +
  368 + {bankChooseModalVisible ? (
  369 + <BankChooseModal
  370 + setVisible={setBankChooseModalVisible}
  371 + invoiceId={invoiceId}
  372 + onClose={() => {
  373 + setBankChooseModalVisible(false);
  374 + loadInvoiceData();
  375 + actionRef.current?.reload();
  376 + }}
  377 + ></BankChooseModal>
  378 + ) : (
  379 + ''
  380 + )}
  381 + </>
  382 + );
  383 +};
src/pages/Invoice/constant.tsx
1 -import { TableDropdown } from '@ant-design/pro-components'; 1 +import { enumToProTableEnumValue } from '@/utils';
  2 +import { PAYEE_OPTIONS } from '../Order/constant';
2 3
3 export type InvoiceItem = { 4 export type InvoiceItem = {
4 id: number; //id 5 id: number; //id
@@ -15,92 +16,341 @@ export type InvoiceItem = { @@ -15,92 +16,341 @@ export type InvoiceItem = {
15 notes: string; //备注 16 notes: string; //备注
16 }; 17 };
17 18
  19 +export const INVOICE_STATUS = {
  20 + UNVERIFIED: '未核销',
  21 + VERIFIED: '已核销',
  22 + ABNORMAL: '异常',
  23 + PARTIAL_VERIFICATION: '部分核销',
  24 +};
  25 +
18 export const INVOICE_COLUMNS = [ 26 export const INVOICE_COLUMNS = [
19 { 27 {
  28 + dataIndex: 'invoiceId',
  29 + title: 'id',
  30 + valueType: 'text',
  31 + hideInTable: true,
  32 + hideInSearch: true,
  33 + width: 100,
  34 + },
  35 + {
20 dataIndex: 'invoiceNumber', 36 dataIndex: 'invoiceNumber',
21 title: '发票号码', 37 title: '发票号码',
22 valueType: 'text', 38 valueType: 'text',
  39 + width: 100,
23 }, 40 },
24 { 41 {
25 dataIndex: 'invoiceStatus', 42 dataIndex: 'invoiceStatus',
26 title: '发票类型', 43 title: '发票类型',
27 valueType: 'select', 44 valueType: 'select',
  45 + width: 100,
  46 + valueEnum: enumToProTableEnumValue({
  47 + SPECIALLY_INVOICED: '专票',
  48 + COMMON_INVOICED: '普票',
  49 + }),
28 }, 50 },
29 { 51 {
30 title: '状态', 52 title: '状态',
31 dataIndex: 'status', 53 dataIndex: 'status',
32 valueType: 'text', 54 valueType: 'text',
  55 + width: 100,
  56 + valueEnum: enumToProTableEnumValue({
  57 + UNVERIFIED: '未核销',
  58 + VERIFIED: '已核销',
  59 + PARTIAL_VERIFICATION: '部分核销',
  60 + }),
33 }, 61 },
34 { 62 {
35 title: '购买方', 63 title: '购买方',
36 dataIndex: 'purchaser', 64 dataIndex: 'purchaser',
37 valueType: 'text', 65 valueType: 'text',
  66 + width: 180,
38 }, 67 },
39 { 68 {
40 title: '收款单位', 69 title: '收款单位',
41 dataIndex: 'payee', 70 dataIndex: 'payee',
42 valueType: 'text', 71 valueType: 'text',
  72 + width: 180,
  73 + valueEnum: enumToProTableEnumValue(PAYEE_OPTIONS),
43 }, 74 },
44 { 75 {
45 title: '联系人', 76 title: '联系人',
46 dataIndex: 'contacts', 77 dataIndex: 'contacts',
47 valueType: 'text', 78 valueType: 'text',
  79 + width: 100,
48 }, 80 },
49 { 81 {
50 title: '销售', 82 title: '销售',
51 dataIndex: 'sale', 83 dataIndex: 'sale',
52 valueType: 'text', 84 valueType: 'text',
  85 + width: 100,
53 }, 86 },
54 { 87 {
55 title: '金额', 88 title: '金额',
56 dataIndex: 'money', 89 dataIndex: 'money',
57 valueType: 'money', 90 valueType: 'money',
  91 + width: 100,
58 }, 92 },
59 { 93 {
60 title: '开票日期', 94 title: '开票日期',
61 dataIndex: 'invoicingTime', 95 dataIndex: 'invoicingTime',
62 - valueType: 'date', 96 + valueType: 'dateRange',
  97 + width: 150,
  98 + search: {
  99 + transform: (value) => {
  100 + if (value) {
  101 + return {
  102 + invoicingBeginTime: value[0],
  103 + invoicingEndTime: value[1],
  104 + };
  105 + }
  106 + },
  107 + },
63 }, 108 },
64 { 109 {
65 title: '收款时间', 110 title: '收款时间',
66 dataIndex: 'collectionTime', 111 dataIndex: 'collectionTime',
67 - valueType: 'dateTime', 112 + valueType: 'dateRange',
  113 + width: 200,
  114 + search: {
  115 + transform: (value) => {
  116 + if (value) {
  117 + return {
  118 + collectionBeginTime: value[0],
  119 + collectionEndTime: value[1],
  120 + };
  121 + }
  122 + },
  123 + },
68 }, 124 },
69 { 125 {
70 title: '备注', 126 title: '备注',
71 dataIndex: 'notes', 127 dataIndex: 'notes',
72 valueType: 'text', 128 valueType: 'text',
  129 + width: 250,
  130 + },
  131 +];
  132 +
  133 +export const BANK_STATEMENT_COLUMNS = [
  134 + {
  135 + dataIndex: 'id',
  136 + title: '编号',
  137 + valueType: 'text',
  138 + width: 160,
  139 + copyable: true,
  140 + // hideInTable: true,
  141 + // hideInSearch: true,
  142 + editable: false,
  143 + },
  144 + {
  145 + dataIndex: 'status',
  146 + title: '状态',
  147 + valueType: 'select',
  148 + width: 100,
  149 + editable: false,
  150 + valueEnum: enumToProTableEnumValue({
  151 + ABNORMAL: '异常',
  152 + VERIFIED: '已核销',
  153 + }),
  154 + },
  155 + {
  156 + dataIndex: 'serialNumber',
  157 + title: '流水号',
  158 + valueType: 'text',
  159 + width: 100,
73 }, 160 },
74 { 161 {
75 - title: '操作',  
76 - valueType: 'option',  
77 - key: 'option',  
78 - fixed: 'right',  
79 - render: (text, record, _, action) => [  
80 - <a  
81 - key="editable"  
82 - onClick={() => {  
83 - action?.startEditable?.(record.id);  
84 - }}  
85 - >  
86 - 编辑  
87 - </a>,  
88 - <a href={record.url} target="_blank" rel="noopener noreferrer" key="view">  
89 - 查看  
90 - </a>,  
91 - <TableDropdown  
92 - key="actionGroup"  
93 - onSelect={() => action?.reload()}  
94 - menus={[  
95 - { key: 'copy', name: '复制' },  
96 - { key: 'delete', name: '删除' },  
97 - ]}  
98 - />,  
99 - ], 162 + dataIndex: 'merchantOrderNumber',
  163 + title: '商户订单号',
  164 + valueType: 'text',
  165 + width: 100,
  166 + },
  167 + {
  168 + dataIndex: 'bankOrderNumber',
  169 + title: '银行订单号',
  170 + valueType: 'text',
  171 + width: 100,
  172 + },
  173 + {
  174 + dataIndex: 'thirdPartyOrderNumber',
  175 + title: '第三方订单号',
  176 + valueType: 'text',
  177 + width: 100,
  178 + },
  179 + {
  180 + dataIndex: 'accountNumber',
  181 + title: '账号',
  182 + valueType: 'text',
  183 + width: 180,
  184 + },
  185 + {
  186 + dataIndex: 'accountName',
  187 + title: '帐号名称',
  188 + valueType: 'text',
  189 + width: 260,
  190 + },
  191 + {
  192 + dataIndex: 'currency',
  193 + title: '币种',
  194 + valueType: 'text',
  195 + width: 100,
  196 + },
  197 + {
  198 + dataIndex: 'transactionDate',
  199 + title: '交易日',
  200 + valueType: 'dateRange',
  201 + width: 100,
  202 + search: {
  203 + transform: (value) => {
  204 + if (value) {
  205 + return {
  206 + beginTransactionDate: value[0],
  207 + endTransactionDate: value[1],
  208 + };
  209 + }
  210 + },
  211 + },
  212 + },
  213 + {
  214 + dataIndex: 'transactionTime',
  215 + title: '交易时间',
  216 + valueType: 'text',
  217 + hideInSearch: true,
  218 + width: 100,
  219 + },
  220 + {
  221 + dataIndex: 'transactionType',
  222 + title: '交易类型',
  223 + valueType: 'text',
  224 + width: 100,
  225 + },
  226 + {
  227 + dataIndex: 'transactionBankBranch',
  228 + title: '交易行所',
  229 + valueType: 'text',
  230 + width: 100,
  231 + },
  232 + {
  233 + dataIndex: 'valueDate',
  234 + title: '起息日',
  235 + valueType: 'dateRange',
  236 + width: 100,
  237 + search: {
  238 + transform: (value) => {
  239 + if (value) {
  240 + return {
  241 + beginValueDate: value[0],
  242 + endValueDate: value[1],
  243 + };
  244 + }
  245 + },
  246 + },
  247 + },
  248 + {
  249 + dataIndex: 'loanAmount',
  250 + title: '贷方金额',
  251 + valueType: 'money',
  252 + width: 100,
  253 + },
  254 + {
  255 + dataIndex: 'borrowedAmount',
  256 + title: '借方金额',
  257 + valueType: 'money',
  258 + width: 100,
  259 + },
  260 + {
  261 + dataIndex: 'transactionAmount',
  262 + title: '交易金额',
  263 + valueType: 'money',
  264 + width: 100,
  265 + },
  266 + {
  267 + dataIndex: 'balance',
  268 + title: '余额',
  269 + valueType: 'money',
  270 + width: 100,
  271 + },
  272 + {
  273 + dataIndex: 'actualPaymentAmount',
  274 + title: '实付金额',
  275 + valueType: 'money',
  276 + width: 100,
  277 + },
  278 + {
  279 + dataIndex: 'collectionChannel',
  280 + title: '收款渠道',
  281 + valueType: 'text',
  282 + width: 100,
  283 + },
  284 + {
  285 + dataIndex: 'paymentType',
  286 + title: '支付类型',
  287 + valueType: 'text',
  288 + width: 100,
  289 + },
  290 + {
  291 + dataIndex: 'summary',
  292 + title: '摘要',
  293 + valueType: 'text',
  294 + width: 300,
  295 + },
  296 + {
  297 + dataIndex: 'cashier',
  298 + title: '收银员',
  299 + valueType: 'text',
  300 + width: 100,
  301 + },
  302 + {
  303 + dataIndex: 'payeePayerUnit',
  304 + title: '收(付)方单位',
  305 + valueType: 'text',
  306 + width: 260,
  307 + },
  308 + {
  309 + dataIndex: 'payeePayerName',
  310 + title: '收(付)方名称',
  311 + valueType: 'text',
  312 + width: 260,
  313 + },
  314 + {
  315 + dataIndex: 'payeePayerAccountNumber',
  316 + title: '收(付)方账号',
  317 + valueType: 'text',
  318 + width: 260,
  319 + },
  320 + {
  321 + dataIndex: 'payeePayerBankBranchCode',
  322 + title: '收(付)方开户行行号',
  323 + valueType: 'text',
  324 + width: 260,
  325 + },
  326 + {
  327 + dataIndex: 'payeePayerBankName',
  328 + title: '收(付)方开户行名',
  329 + valueType: 'text',
  330 + width: 260,
  331 + },
  332 + {
  333 + dataIndex: 'payeePayerBankAddress',
  334 + title: '收(付)方开户行地址',
  335 + valueType: 'text',
  336 + width: 260,
  337 + },
  338 + {
  339 + dataIndex: 'extendedSummary',
  340 + title: '扩展摘要',
  341 + valueType: 'text',
  342 + width: 100,
  343 + },
  344 + {
  345 + dataIndex: 'transactionAnalysisCode',
  346 + title: '交易分析码',
  347 + valueType: 'text',
  348 + width: 100,
  349 + },
  350 + {
  351 + dataIndex: 'remarkNote',
  352 + title: '附言',
  353 + valueType: 'text',
  354 + width: 100,
100 }, 355 },
101 ]; 356 ];
102 -  
103 -export const INVOICE_STATUS = {  
104 - UNVERIFIED: '未核销',  
105 - VERIFIED: '已核销',  
106 -};  
src/pages/Invoice/index.less
@@ -4,3 +4,17 @@ @@ -4,3 +4,17 @@
4 'WenQuanYi Micro Hei', sans-serif; 4 'WenQuanYi Micro Hei', sans-serif;
5 font-size: 14px; 5 font-size: 14px;
6 } 6 }
  7 +
  8 +.invoice-detail td {
  9 + font-family: 'San Francisco', 'Helvetica Neue', Helvetica, Arial,
  10 + 'Microsoft YaHei', 'PingFang SC', 'Hiragino Sans GB', 'Heiti SC',
  11 + 'WenQuanYi Micro Hei', sans-serif;
  12 + font-size: 14px;
  13 +}
  14 +
  15 +.bank-statement-choose td {
  16 + font-family: 'San Francisco', 'Helvetica Neue', Helvetica, Arial,
  17 + 'Microsoft YaHei', 'PingFang SC', 'Hiragino Sans GB', 'Heiti SC',
  18 + 'WenQuanYi Micro Hei', sans-serif;
  19 + font-size: 14px;
  20 +}
src/pages/Invoice/index.tsx
1 -import { INVOICE_COLUMNS, INVOICE_STATUS } from '@/pages/Invoice/constant';  
2 -import { postServiceInvoiceQueryInvoice } from '@/services';  
3 -import { enumValueToLabel } from '@/utils'; 1 +import ButtonConfirm from '@/components/ButtomConfirm';
  2 +import EllipsisDiv from '@/components/Div/EllipsisDiv';
  3 +import { RESPONSE_CODE } from '@/constants/enum';
  4 +import {
  5 + BANK_STATEMENT_COLUMNS,
  6 + INVOICE_COLUMNS,
  7 + INVOICE_STATUS,
  8 +} from '@/pages/Invoice/constant';
  9 +import {
  10 + postServiceBankStatementDeleteBankStatement,
  11 + postServiceBankStatementEditBankStatement,
  12 + postServiceBankStatementQueryBankStatement,
  13 + postServiceInvoiceDeleteInvoice,
  14 + postServiceInvoiceQueryInvoice,
  15 +} from '@/services';
  16 +import { enumValueToLabel, formatDateTime } from '@/utils';
  17 +import { formatDate } from '@/utils/time';
4 import { getUserInfo } from '@/utils/user'; 18 import { getUserInfo } from '@/utils/user';
5 -import { EllipsisOutlined } from '@ant-design/icons'; 19 +import { EllipsisOutlined, PlusOutlined } from '@ant-design/icons';
6 import { 20 import {
7 ActionType, 21 ActionType,
8 PageContainer, 22 PageContainer,
9 ProTable, 23 ProTable,
10 } from '@ant-design/pro-components'; 24 } from '@ant-design/pro-components';
11 import { history } from '@umijs/max'; 25 import { history } from '@umijs/max';
12 -import { Avatar, Button, Dropdown, Tag } from 'antd';  
13 -import { useRef } from 'react'; 26 +import { Avatar, Button, Dropdown, Tabs, Tag, message } from 'antd';
  27 +import { useRef, useState } from 'react';
14 import { INVOCING_STATUS, PAYEE_OPTIONS } from '../Order/constant'; 28 import { INVOCING_STATUS, PAYEE_OPTIONS } from '../Order/constant';
  29 +import BankImportModal from './components/BankImportModal';
  30 +import InvoiceVerificationModal from './components/InvoiceVerificationModal';
15 import './index.less'; 31 import './index.less';
16 -  
17 -const userInfo = getUserInfo();  
18 const InvoicePage = () => { 32 const InvoicePage = () => {
19 - const actionRef = useRef<ActionType>();  
20 - // const [pageSize, setPageSize] = useState(10);  
21 - // const [currentPage, setCurrentPage] = useState(1);  
22 - return (  
23 - <>  
24 - <PageContainer  
25 - className="invoice-index"  
26 - header={{  
27 - title: '发票管理',  
28 - extra: [  
29 - <Avatar key="0" style={{ verticalAlign: 'middle' }} size="large">  
30 - {userInfo?.username}  
31 - </Avatar>,  
32 - <Tag key="nickName">{userInfo?.nickName}</Tag>,  
33 - <Dropdown  
34 - key="dropdown"  
35 - trigger={['click']}  
36 - menu={{  
37 - items: [  
38 - {  
39 - label: '退出登录',  
40 - key: '1',  
41 - onClick: () => {  
42 - localStorage.removeItem('token');  
43 - history.push('/login');  
44 - },  
45 - },  
46 - // {  
47 - // label: '修改密码',  
48 - // key: '2',  
49 - // },  
50 - ], 33 + const invoiceActionRef = useRef<ActionType>();
  34 + const bankActionRef = useRef<ActionType>();
  35 + const [bankImportModalVisible, setBankImportModalVisible] = useState(false);
  36 + const [invoiceVerificationVisible, setInvoiceVerificationVisible] =
  37 + useState(false);
  38 + const [invoiceId, setInvoiceId] = useState(undefined);
  39 +
  40 + const userInfo = getUserInfo();
  41 +
  42 + const reloadInvoiceTable = () => {
  43 + invoiceActionRef.current?.reload();
  44 + };
  45 +
  46 + const reloadBankStatementTable = () => {
  47 + bankActionRef.current?.reload();
  48 + };
  49 +
  50 + const getTableCellText = (target: any) => {
  51 + if (!target) {
  52 + return '';
  53 + }
  54 +
  55 + if (target.props) {
  56 + return target.props.text;
  57 + }
  58 +
  59 + return target;
  60 + };
  61 +
  62 + /**
  63 + * 加载发票列表表格的各个列格式
  64 + */
  65 + const invoicecColumnsInit = () => {
  66 + let columns = INVOICE_COLUMNS.map((item) => {
  67 + let newItem = { ...item };
  68 + let dataIndex = item.dataIndex;
  69 + let dataType = item.valueType;
  70 +
  71 + newItem.render = (text, record) => {
  72 + let textValue = record[dataIndex];
  73 +
  74 + if (dataType === 'dateRange' || dataType === 'date') {
  75 + textValue = formatDate(textValue);
  76 + }
  77 +
  78 + if (dataType === 'dateTime') {
  79 + textValue = formatDateTime(textValue);
  80 + }
  81 +
  82 + if (dataType === 'money') {
  83 + textValue = '¥' + textValue;
  84 + }
  85 +
  86 + switch (dataIndex) {
  87 + case 'invoiceStatus':
  88 + return (
  89 + <EllipsisDiv
  90 + text={enumValueToLabel(
  91 + getTableCellText(textValue),
  92 + INVOCING_STATUS,
  93 + )}
  94 + />
  95 + );
  96 +
  97 + case 'status':
  98 + return (
  99 + <EllipsisDiv
  100 + text={enumValueToLabel(
  101 + getTableCellText(textValue),
  102 + INVOICE_STATUS,
  103 + )}
  104 + />
  105 + );
  106 +
  107 + case 'payee':
  108 + return (
  109 + <EllipsisDiv
  110 + text={enumValueToLabel(
  111 + getTableCellText(textValue),
  112 + PAYEE_OPTIONS,
  113 + )}
  114 + />
  115 + );
  116 +
  117 + default:
  118 + return <EllipsisDiv text={getTableCellText(textValue)} />;
  119 + }
  120 + };
  121 +
  122 + return newItem;
  123 + });
  124 +
  125 + columns.push({
  126 + title: '操作',
  127 + valueType: 'option',
  128 + key: 'option',
  129 + fixed: 'right',
  130 + width: 120,
  131 + render: (text, record) => {
  132 + let btns = [];
  133 + if (record.path?.includes('writeOff')) {
  134 + btns.push(
  135 + <a
  136 + key="editable"
  137 + onClick={() => {
  138 + setInvoiceVerificationVisible(true);
  139 + setInvoiceId(record.invoiceId);
51 }} 140 }}
52 > 141 >
53 - <Button key="4" style={{ padding: '0 8px' }}>  
54 - <EllipsisOutlined />  
55 - </Button>  
56 - </Dropdown>,  
57 - ],  
58 - }}  
59 - >  
60 - <ProTable  
61 - columns={INVOICE_COLUMNS.map((item) => {  
62 - let newItem = { ...item };  
63 - if (item.dataIndex === 'invoiceStatus') {  
64 - newItem.render = (text) => {  
65 - return enumValueToLabel(text.props.text, INVOCING_STATUS);  
66 - };  
67 - } 142 + 核销
  143 + </a>,
  144 + );
  145 + }
68 146
69 - if (item.dataIndex === 'status') {  
70 - newItem.render = (text) => {  
71 - return enumValueToLabel(text, INVOICE_STATUS);  
72 - };  
73 - } 147 + if (record.path?.includes('queryInvoiceDetails')) {
  148 + btns.push(
  149 + <Button
  150 + className="p-0"
  151 + key="view"
  152 + type="link"
  153 + onClick={() => {
  154 + setInvoiceVerificationVisible(true);
  155 + setInvoiceId(record.invoiceId);
  156 + }}
  157 + >
  158 + 查看
  159 + </Button>,
  160 + );
  161 + }
74 162
75 - if (item.dataIndex === 'payee') {  
76 - newItem.render = (text) => {  
77 - return enumValueToLabel(text, PAYEE_OPTIONS);  
78 - };  
79 - }  
80 - return newItem;  
81 - })}  
82 - actionRef={actionRef} 163 + if (record.path?.includes('deleteInvoice')) {
  164 + btns.push(
  165 + <ButtonConfirm
  166 + key="delete"
  167 + className="p-0"
  168 + title={
  169 + '确认删除发票号码为[ ' + record.invoiceNumber + ' ]的发票吗?'
  170 + }
  171 + text="删除"
  172 + onConfirm={async () => {
  173 + let res = await postServiceInvoiceDeleteInvoice({
  174 + data: { invoiceId: record.invoiceId },
  175 + });
  176 + if (res) {
  177 + message.success(res.message);
  178 + reloadInvoiceTable();
  179 + }
  180 + }}
  181 + />,
  182 + );
  183 + }
  184 + return btns;
  185 + },
  186 + });
  187 +
  188 + return columns;
  189 + };
  190 +
  191 + const bankStatemetColumnsInit = () => {
  192 + let columns = BANK_STATEMENT_COLUMNS.map((item) => {
  193 + let newItem = { ...item };
  194 + let dataIndex = item.dataIndex;
  195 + let dataType = item.valueType;
  196 +
  197 + newItem.render = (text, record) => {
  198 + let textValue = record[dataIndex];
  199 +
  200 + if (dataType === 'date') {
  201 + textValue = formatDate(textValue);
  202 + }
  203 +
  204 + if (dataType === 'dateTime') {
  205 + textValue = formatDateTime(textValue);
  206 + }
  207 +
  208 + if (dataType === 'money') {
  209 + if (textValue === null || textValue === undefined) {
  210 + textValue = '';
  211 + } else {
  212 + textValue = '¥' + textValue;
  213 + }
  214 + }
  215 +
  216 + switch (dataIndex) {
  217 + case 'invoiceStatus':
  218 + return (
  219 + <EllipsisDiv
  220 + text={enumValueToLabel(
  221 + getTableCellText(textValue),
  222 + INVOCING_STATUS,
  223 + )}
  224 + />
  225 + );
  226 +
  227 + case 'status':
  228 + return (
  229 + <EllipsisDiv
  230 + text={enumValueToLabel(
  231 + getTableCellText(textValue),
  232 + INVOICE_STATUS,
  233 + )}
  234 + />
  235 + );
  236 +
  237 + case 'payee':
  238 + return (
  239 + <EllipsisDiv
  240 + text={enumValueToLabel(
  241 + getTableCellText(textValue),
  242 + PAYEE_OPTIONS,
  243 + )}
  244 + />
  245 + );
  246 +
  247 + default:
  248 + return <EllipsisDiv text={getTableCellText(textValue)} />;
  249 + }
  250 + };
  251 +
  252 + return newItem;
  253 + });
  254 +
  255 + columns.push({
  256 + title: '操作',
  257 + valueType: 'option',
  258 + key: 'option',
  259 + fixed: 'right',
  260 + width: 120,
  261 + render: (text, record, _, action) => {
  262 + let btns = [];
  263 + if (record.path?.includes('editBankStatement')) {
  264 + btns.push(
  265 + <a
  266 + key="editable"
  267 + onClick={() => {
  268 + action?.startEditable?.(record.id);
  269 + }}
  270 + >
  271 + 编辑
  272 + </a>,
  273 + );
  274 + }
  275 +
  276 + if (record.path?.includes('deleteBankStatement')) {
  277 + btns.push(
  278 + <ButtonConfirm
  279 + key="delete"
  280 + className="p-0"
  281 + title={'是否删除该银行流水记录?'}
  282 + text="删除"
  283 + onConfirm={async () => {
  284 + let res = await postServiceBankStatementDeleteBankStatement({
  285 + data: { id: record.id },
  286 + });
  287 + if (res.result === RESPONSE_CODE.SUCCESS) {
  288 + message.success(res.message);
  289 + reloadBankStatementTable();
  290 + }
  291 + }}
  292 + />,
  293 + );
  294 + }
  295 + return btns;
  296 + },
  297 + });
  298 +
  299 + return columns;
  300 + };
  301 +
  302 + const tabsItems = [
  303 + {
  304 + key: 1,
  305 + label: '发票管理',
  306 + children: (
  307 + <ProTable
  308 + columns={invoicecColumnsInit()}
  309 + actionRef={invoiceActionRef}
83 cardBordered 310 cardBordered
84 pagination={{ 311 pagination={{
85 pageSize: 10, 312 pageSize: 10,
@@ -114,23 +341,159 @@ const InvoicePage = () =&gt; { @@ -114,23 +341,159 @@ const InvoicePage = () =&gt; {
114 listsHeight: 400, 341 listsHeight: 400,
115 }, 342 },
116 }} 343 }}
117 - form={{  
118 - // 由于配置了 transform,提交的参与与定义的不同这里需要转化一下  
119 - syncToUrl: (values, type) => {  
120 - if (type === 'get') {  
121 - return {  
122 - ...values,  
123 - created_at: [values.startTime, values.endTime],  
124 - };  
125 - }  
126 - return values; 344 + form={{}}
  345 + dateFormatter="string"
  346 + headerTitle="发票列表"
  347 + scroll={{ x: 1400, y: 360 }}
  348 + />
  349 + ),
  350 + },
  351 + {
  352 + key: 2,
  353 + label: '银行流水',
  354 + children: (
  355 + <ProTable
  356 + columns={bankStatemetColumnsInit()}
  357 + actionRef={bankActionRef}
  358 + cardBordered
  359 + pagination={{
  360 + pageSize: 10,
  361 + }}
  362 + editable={{
  363 + type: 'multiple',
  364 + onSave: async (rowKey, data) => {
  365 + await postServiceBankStatementEditBankStatement({ data: data });
127 }, 366 },
  367 + actionRender: (row, config, defaultDom) => [
  368 + defaultDom.save,
  369 + defaultDom.cancel,
  370 + ],
  371 + }}
  372 + request={async (params) => {
  373 + const res = await postServiceBankStatementQueryBankStatement({
  374 + data: { ...params },
  375 + });
  376 + if (res) {
  377 + return {
  378 + data: res?.data?.data || [],
  379 + total: res?.data?.total || 0,
  380 + };
  381 + }
128 }} 382 }}
  383 + columnsState={{
  384 + persistenceKey: 'pro-table-singe-demos',
  385 + persistenceType: 'localStorage',
  386 + defaultValue: {
  387 + option: { fixed: 'right', disable: true },
  388 + },
  389 + onChange(value) {
  390 + console.log('value: ', value);
  391 + },
  392 + }}
  393 + rowKey="id"
  394 + search={{
  395 + labelWidth: 'auto',
  396 + }}
  397 + options={{
  398 + setting: {
  399 + listsHeight: 400,
  400 + },
  401 + }}
  402 + form={{}}
129 dateFormatter="string" 403 dateFormatter="string"
130 - headerTitle="发票列表"  
131 - scroll={{ x: true }} 404 + headerTitle="银行流水列表"
  405 + scroll={{ x: 1400, y: 360 }}
  406 + toolBarRender={() => [
  407 + <Button
  408 + key="button"
  409 + icon={<PlusOutlined />}
  410 + onClick={() => {
  411 + setBankImportModalVisible(true);
  412 + }}
  413 + type="primary"
  414 + >
  415 + 导入
  416 + </Button>,
  417 + ]}
  418 + />
  419 + ),
  420 + },
  421 + ];
  422 + return (
  423 + <>
  424 + <PageContainer
  425 + className="invoice-index"
  426 + header={{
  427 + title: '发票管理',
  428 + extra: [
  429 + <Avatar key="0" style={{ verticalAlign: 'middle' }} size="large">
  430 + {userInfo?.username}
  431 + </Avatar>,
  432 + <Tag key="nickName">{userInfo?.nickName}</Tag>,
  433 + <Dropdown
  434 + key="dropdown"
  435 + trigger={['click']}
  436 + menu={{
  437 + items: [
  438 + {
  439 + label: '退出登录',
  440 + key: '1',
  441 + onClick: () => {
  442 + localStorage.removeItem('token');
  443 + history.push('/login');
  444 + },
  445 + },
  446 + // {
  447 + // label: '修改密码',
  448 + // key: '2',
  449 + // },
  450 + ],
  451 + }}
  452 + >
  453 + <Button key="4" style={{ padding: '0 8px' }}>
  454 + <EllipsisOutlined />
  455 + </Button>
  456 + </Dropdown>,
  457 + ],
  458 + }}
  459 + >
  460 + <Tabs
  461 + defaultActiveKey="1"
  462 + items={tabsItems}
  463 + onChange={(value) => {
  464 + if (value === 1) {
  465 + invoiceActionRef.current?.reload();
  466 + } else {
  467 + bankActionRef.current?.reload();
  468 + }
  469 + }}
132 /> 470 />
133 </PageContainer> 471 </PageContainer>
  472 +
  473 + {bankImportModalVisible ? (
  474 + <BankImportModal
  475 + setVisible={setBankImportModalVisible}
  476 + onClose={() => {
  477 + invoiceActionRef.current?.reload();
  478 + bankActionRef.current?.reload();
  479 + }}
  480 + ></BankImportModal>
  481 + ) : (
  482 + ''
  483 + )}
  484 +
  485 + {invoiceVerificationVisible ? (
  486 + <InvoiceVerificationModal
  487 + setVisible={setInvoiceVerificationVisible}
  488 + invoiceId={invoiceId}
  489 + onClose={() => {
  490 + invoiceActionRef.current?.reload();
  491 + bankActionRef.current?.reload();
  492 + }}
  493 + ></InvoiceVerificationModal>
  494 + ) : (
  495 + ''
  496 + )}
134 </> 497 </>
135 ); 498 );
136 }; 499 };
src/pages/Order/components/FinancialDrawer.tsx
@@ -8,13 +8,14 @@ import { enumToSelect } from &#39;@/utils&#39;; @@ -8,13 +8,14 @@ import { enumToSelect } from &#39;@/utils&#39;;
8 import { 8 import {
9 DrawerForm, 9 DrawerForm,
10 ProFormDatePicker, 10 ProFormDatePicker,
  11 + ProFormDigit,
11 ProFormSelect, 12 ProFormSelect,
12 ProFormText, 13 ProFormText,
13 ProFormTextArea, 14 ProFormTextArea,
14 } from '@ant-design/pro-components'; 15 } from '@ant-design/pro-components';
15 import { Form, message } from 'antd'; 16 import { Form, message } from 'antd';
16 import { useEffect, useState } from 'react'; 17 import { useEffect, useState } from 'react';
17 -import { INVOCING_STATUS_OPTIONS_OLD } from '../constant'; 18 +import { INVOCING_STATUS_OPTIONS_OLD, PAYEE_OPTIONS } from '../constant';
18 19
19 export default ({ 20 export default ({
20 mainOrder, 21 mainOrder,
@@ -141,32 +142,32 @@ export default ({ @@ -141,32 +142,32 @@ export default ({
141 label="收款时间" 142 label="收款时间"
142 initialValue={subOrders[0]?.collectMoneyTime} 143 initialValue={subOrders[0]?.collectMoneyTime}
143 />, 144 />,
144 - // <ProFormText  
145 - // width="lg"  
146 - // key="invoiceNumber"  
147 - // name="invoiceNumber"  
148 - // label="发票号码"  
149 - // initialValue={subOrders[0]?.invoiceNumber}  
150 - // rules={[{ required: true, message: '发票号码必填' }]}  
151 - // />,  
152 - // <ProFormSelect  
153 - // key="payee"  
154 - // placeholder="选择收款单位"  
155 - // name="payee"  
156 - // width="lg"  
157 - // label="收款单位"  
158 - // options={enumToSelect(PAYEE_OPTIONS)}  
159 - // initialValue={subOrders[0]?.payee}  
160 - // rules={[{ required: true, message: '收款单位必填' }]}  
161 - // />, 145 + <ProFormText
  146 + width="lg"
  147 + key="invoiceNumber"
  148 + name="invoiceNumber"
  149 + label="发票号码"
  150 + initialValue={subOrders[0]?.invoiceNumber}
  151 + rules={[{ required: true, message: '发票号码必填' }]}
  152 + />,
  153 + <ProFormSelect
  154 + key="payee"
  155 + placeholder="选择收款单位"
  156 + name="payee"
  157 + width="lg"
  158 + label="收款单位"
  159 + options={enumToSelect(PAYEE_OPTIONS)}
  160 + initialValue={subOrders[0]?.payee}
  161 + rules={[{ required: true, message: '收款单位必填' }]}
  162 + />,
162 163
163 - // <ProFormDigit  
164 - // key="money"  
165 - // name="money"  
166 - // width="lg"  
167 - // label="金额"  
168 - // rules={[{ required: true, message: '金额必填' }]}  
169 - // />, 164 + <ProFormDigit
  165 + key="money"
  166 + name="money"
  167 + width="lg"
  168 + label="金额"
  169 + rules={[{ required: true, message: '金额必填' }]}
  170 + />,
170 ] 171 ]
171 : ''} 172 : ''}
172 173
src/pages/Order/components/FinancialMergeDrawer.tsx
1 // import { PlusOutlined } from '@ant-design/icons'; 1 // import { PlusOutlined } from '@ant-design/icons';
2 import { RESPONSE_CODE } from '@/constants/enum'; 2 import { RESPONSE_CODE } from '@/constants/enum';
3 import { postServiceOrderMergeInvoicing } from '@/services'; 3 import { postServiceOrderMergeInvoicing } from '@/services';
  4 +import { enumToSelect } from '@/utils';
4 import { 5 import {
5 DrawerForm, 6 DrawerForm,
6 ProFormDatePicker, 7 ProFormDatePicker,
  8 + ProFormDigit,
7 ProFormSelect, 9 ProFormSelect,
8 ProFormText, 10 ProFormText,
9 ProFormTextArea, 11 ProFormTextArea,
10 } from '@ant-design/pro-components'; 12 } from '@ant-design/pro-components';
11 import { Form, message } from 'antd'; 13 import { Form, message } from 'antd';
  14 +import { PAYEE_OPTIONS } from '../constant';
12 15
13 export default ({ dataList, setVisible, onClose }) => { 16 export default ({ dataList, setVisible, onClose }) => {
14 let mainOrderIds = dataList?.map((item) => { 17 let mainOrderIds = dataList?.map((item) => {
@@ -104,7 +107,30 @@ export default ({ dataList, setVisible, onClose }) =&gt; { @@ -104,7 +107,30 @@ export default ({ dataList, setVisible, onClose }) =&gt; {
104 name="collectMoneyTime" 107 name="collectMoneyTime"
105 label="收款时间" 108 label="收款时间"
106 /> 109 />
  110 + <ProFormText
  111 + width="lg"
  112 + key="invoiceNumber"
  113 + name="invoiceNumber"
  114 + label="发票号码"
  115 + rules={[{ required: true, message: '发票号码必填' }]}
  116 + />
  117 + <ProFormSelect
  118 + key="payee"
  119 + placeholder="选择收款单位"
  120 + name="payee"
  121 + width="lg"
  122 + label="收款单位"
  123 + options={enumToSelect(PAYEE_OPTIONS)}
  124 + rules={[{ required: true, message: '收款单位必填' }]}
  125 + />
107 126
  127 + <ProFormDigit
  128 + key="money"
  129 + name="money"
  130 + width="lg"
  131 + label="金额"
  132 + rules={[{ required: true, message: '金额必填' }]}
  133 + />
108 <ProFormSelect 134 <ProFormSelect
109 placeholder="是否完全开票" 135 placeholder="是否完全开票"
110 name="afterInvoicingStatus" 136 name="afterInvoicingStatus"
src/pages/Order/index.tsx
@@ -27,8 +27,10 @@ import { @@ -27,8 +27,10 @@ import {
27 QuestionCircleOutlined, 27 QuestionCircleOutlined,
28 } from '@ant-design/icons'; 28 } from '@ant-design/icons';
29 import { 29 import {
  30 + ActionType,
30 PageContainer, 31 PageContainer,
31 ProColumns, 32 ProColumns,
  33 + ProFormInstance,
32 ProTable, 34 ProTable,
33 } from '@ant-design/pro-components'; 35 } from '@ant-design/pro-components';
34 import { history } from '@umijs/max'; 36 import { history } from '@umijs/max';
@@ -47,7 +49,7 @@ import { @@ -47,7 +49,7 @@ import {
47 message, 49 message,
48 } from 'antd'; 50 } from 'antd';
49 import { cloneDeep } from 'lodash'; 51 import { cloneDeep } from 'lodash';
50 -import React, { Key, useRef, useState } from 'react'; 52 +import React, { Key, useEffect, useRef, useState } from 'react';
51 import OrderPrintModal from '../OrderPrint/OrderPrintModal'; 53 import OrderPrintModal from '../OrderPrint/OrderPrintModal';
52 import AfterSalesDrawer from './components/AfterSalesDrawer'; 54 import AfterSalesDrawer from './components/AfterSalesDrawer';
53 import ApplyForInvoicingModal from './components/ApplyForInvoicingModal'; 55 import ApplyForInvoicingModal from './components/ApplyForInvoicingModal';
@@ -145,7 +147,8 @@ const OrderPage = () =&gt; { @@ -145,7 +147,8 @@ const OrderPage = () =&gt; {
145 const [mainOrderSelectedRows, setMainOrderSelectedRows] = useState([]); //选中的主订单集合 147 const [mainOrderSelectedRows, setMainOrderSelectedRows] = useState([]); //选中的主订单集合
146 const [onlyShowFinancialToBeProcessed, setOnlyShowFinancialToBeProcessed] = 148 const [onlyShowFinancialToBeProcessed, setOnlyShowFinancialToBeProcessed] =
147 useState(false); 149 useState(false);
148 - const mainTableRef = useRef(); 150 + const mainTableRef = useRef<ActionType>();
  151 + const mainTableFormRef = useRef<ProFormInstance>();
149 let [searchParams, setSearchParam] = useState(Object); //表格的查询条件存储 152 let [searchParams, setSearchParam] = useState(Object); //表格的查询条件存储
150 const [messageApi, contextHolder] = message.useMessage(); 153 const [messageApi, contextHolder] = message.useMessage();
151 154
@@ -2286,7 +2289,10 @@ const OrderPage = () =&gt; { @@ -2286,7 +2289,10 @@ const OrderPage = () =&gt; {
2286 mainOrderSelectedMap.forEach((value) => { 2289 mainOrderSelectedMap.forEach((value) => {
2287 mainOrders.push(value); 2290 mainOrders.push(value);
2288 for (let subOrder of value.subOrderInformationLists) { 2291 for (let subOrder of value.subOrderInformationLists) {
2289 - if (subOrder.afterInvoicingStatus !== 'APPLY_FOR_INVOICING') { 2292 + if (
  2293 + subOrder.afterInvoicingStatus !== 'APPLY_FOR_INVOICING' &&
  2294 + subOrder.afterInvoicingStatus !== 'PARTIAL_INVOICING'
  2295 + ) {
2290 errorIds.push(value.id); 2296 errorIds.push(value.id);
2291 return; 2297 return;
2292 } 2298 }
@@ -2296,7 +2302,7 @@ const OrderPage = () =&gt; { @@ -2296,7 +2302,7 @@ const OrderPage = () =&gt; {
2296 message.error( 2302 message.error(
2297 '订单号为:' + 2303 '订单号为:' +
2298 errorIds.join(',') + 2304 errorIds.join(',') +
2299 - '的订单存在不是[申请开票]状态的子订单,请检查!', 2305 + '的订单存在不是[申请开票]或者[部分开票]状态的子订单,请检查!',
2300 ); 2306 );
2301 return; 2307 return;
2302 } 2308 }
@@ -2369,6 +2375,15 @@ const OrderPage = () =&gt; { @@ -2369,6 +2375,15 @@ const OrderPage = () =&gt; {
2369 return toolBtns; 2375 return toolBtns;
2370 } 2376 }
2371 2377
  2378 + useEffect(() => {
  2379 + // 使用URLSearchParams来解析查询参数
  2380 + const params = new URLSearchParams(location.search);
  2381 + const id = params.get('id');
  2382 + if (id) {
  2383 + mainTableFormRef.current?.setFieldValue('id', id);
  2384 + }
  2385 + }, []);
  2386 +
2372 return ( 2387 return (
2373 <PageContainer 2388 <PageContainer
2374 className="order-page-container" 2389 className="order-page-container"
@@ -2412,6 +2427,7 @@ const OrderPage = () =&gt; { @@ -2412,6 +2427,7 @@ const OrderPage = () =&gt; {
2412 // tableStyle={{backgroundColor:'red'}} 2427 // tableStyle={{backgroundColor:'red'}}
2413 2428
2414 actionRef={mainTableRef} 2429 actionRef={mainTableRef}
  2430 + formRef={mainTableFormRef}
2415 expandIconColumnIndex={-1} 2431 expandIconColumnIndex={-1}
2416 columns={mainOrdersColumns} 2432 columns={mainOrdersColumns}
2417 rowKey="id" 2433 rowKey="id"
@@ -2443,6 +2459,12 @@ const OrderPage = () =&gt; { @@ -2443,6 +2459,12 @@ const OrderPage = () =&gt; {
2443 filter, 2459 filter,
2444 ) => { 2460 ) => {
2445 //订单id处理 2461 //订单id处理
  2462 + /**
  2463 + * 以params中的id为主,如果params没id,则取url中的id
  2464 + * 第一次进来这个页面,url带有id的话,会自动填充到查询表单中,但是第一次查询params不会带这个id进来
  2465 + */
  2466 + let orderIds = mainTableFormRef.current?.getFieldValue('id');
  2467 + params.id = params.id || orderIds;
2446 if (params.id !== '') { 2468 if (params.id !== '') {
2447 if (params.id?.indexOf(',')) { 2469 if (params.id?.indexOf(',')) {
2448 params.id = params.id.split(','); 2470 params.id = params.id.split(',');
src/pages/OrderReport/components/OrderStatisticCard.tsx
@@ -238,8 +238,8 @@ export default ({ data, statisticsMethod, reFreshData }) =&gt; { @@ -238,8 +238,8 @@ export default ({ data, statisticsMethod, reFreshData }) =&gt; {
238 > 238 >
239 <CardContent 239 <CardContent
240 unit="¥" 240 unit="¥"
241 - content={data.totalPayment}  
242 - sameMonthPercentageChange={data.totalPaymentTrend} 241 + content={data?.totalPayment}
  242 + sameMonthPercentageChange={data?.totalPaymentTrend}
243 /> 243 />
244 </ProCard> 244 </ProCard>
245 <ProCard 245 <ProCard
@@ -247,7 +247,7 @@ export default ({ data, statisticsMethod, reFreshData }) =&gt; { @@ -247,7 +247,7 @@ export default ({ data, statisticsMethod, reFreshData }) =&gt; {
247 title={<CardTitle title={'指标'} />} 247 title={<CardTitle title={'指标'} />}
248 bordered 248 bordered
249 > 249 >
250 - <CardContent unit="¥" content={data.target} editable={true} /> 250 + <CardContent unit="¥" content={data?.target} editable={true} />
251 </ProCard> 251 </ProCard>
252 <ProCard 252 <ProCard
253 className="order-statictis-card" 253 className="order-statictis-card"
@@ -256,8 +256,8 @@ export default ({ data, statisticsMethod, reFreshData }) =&gt; { @@ -256,8 +256,8 @@ export default ({ data, statisticsMethod, reFreshData }) =&gt; {
256 > 256 >
257 <CardContent 257 <CardContent
258 unit="单" 258 unit="单"
259 - content={data.totalOrderNumber}  
260 - sameMonthPercentageChange={data.totalOrderNumberTrend} 259 + content={data?.totalOrderNumber}
  260 + sameMonthPercentageChange={data?.totalOrderNumberTrend}
261 /> 261 />
262 </ProCard> 262 </ProCard>
263 <ProCard 263 <ProCard
@@ -265,21 +265,21 @@ export default ({ data, statisticsMethod, reFreshData }) =&gt; { @@ -265,21 +265,21 @@ export default ({ data, statisticsMethod, reFreshData }) =&gt; {
265 title={<CardTitle title={'总子订单量'} />} 265 title={<CardTitle title={'总子订单量'} />}
266 bordered 266 bordered
267 > 267 >
268 - <CardContent unit="单" content={data.subTotalOrderNumber} /> 268 + <CardContent unit="单" content={data?.subTotalOrderNumber} />
269 </ProCard> 269 </ProCard>
270 <ProCard 270 <ProCard
271 className="order-statictis-card" 271 className="order-statictis-card"
272 title={<CardTitle title={'未审核子订单'} />} 272 title={<CardTitle title={'未审核子订单'} />}
273 bordered 273 bordered
274 > 274 >
275 - <CardContent unit="单" content={data.unCheckOrderNumber} /> 275 + <CardContent unit="单" content={data?.unCheckOrderNumber} />
276 </ProCard> 276 </ProCard>
277 <ProCard 277 <ProCard
278 className="order-statictis-card" 278 className="order-statictis-card"
279 title={<CardTitle title={'待发货子订单'} />} 279 title={<CardTitle title={'待发货子订单'} />}
280 bordered 280 bordered
281 > 281 >
282 - <CardContent unit="单" content={data.unSendOrderNumber} /> 282 + <CardContent unit="单" content={data?.unSendOrderNumber} />
283 </ProCard> 283 </ProCard>
284 </ProCard> 284 </ProCard>
285 285