BankChooseModal.tsx 8.36 KB
import EllipsisDiv from '@/components/Div/EllipsisDiv';
import { RESPONSE_CODE } from '@/constants/enum';
import { INVOCING_STATUS, PAYEE_OPTIONS } from '@/pages/Order/constant';
import {
  postServiceBankStatementQueryBankStatement,
  postServiceInvoiceInvoiceWriteOff,
} from '@/services';
import { FloatAdd, FloatSub, enumValueToLabel, formatDateTime } from '@/utils';
import { formatDate } from '@/utils/time';

import { ActionType, ProCard, ProTable } from '@ant-design/pro-components';
import { Button, Divider, Flex, Modal, Tag, message } from 'antd';
import { useRef, useState } from 'react';
import { BANK_STATEMENT_COLUMNS, INVOICE_STATUS } from '../constant';
import '../index.less';
export default ({ invoiceId, setVisible, onClose }) => {
  const [selectedStatement, setSelectedStatement] = useState([]);
  const [selectedStatementIdSet, setSelectedStatementIdSet] = useState(
    new Set(),
  );
  const [totalAmount, setTotalAmount] = useState(0);

  // 添加元素到Set
  const addElement = (element) => {
    setSelectedStatementIdSet((prevSet) => new Set([...prevSet, element]));
  };

  // 从Set中删除元素
  const removeElement = (element) => {
    setSelectedStatementIdSet((prevSet) => {
      const newSet = new Set(prevSet);
      newSet.delete(element);
      return newSet;
    });
  };

  const [btnLoading, setBtnLoading] = useState(false);

  const actionRef = useRef<ActionType>();
  const getTableCellText = (target: any) => {
    if (!target) {
      return '';
    }

    if (target.props) {
      return target.props.text;
    }

    return target;
  };

  /**
   * 加载银行流水列表表格的各个列格式
   */
  const bankStatementColumnsInit = () => {
    let columns = BANK_STATEMENT_COLUMNS.map((item) => {
      let newItem = { ...item };
      let dataIndex = item.dataIndex;
      let dataType = item.valueType;

      if (item.dataIndex === 'status') {
        newItem.hideInSearch = true;
      }

      newItem.render = (text, record) => {
        let textValue = record[dataIndex];

        if (dataType === 'date') {
          textValue = formatDate(textValue);
        }

        if (dataType === 'dateTime') {
          textValue = formatDateTime(textValue);
        }

        if (dataType === 'money') {
          textValue = '¥' + textValue;
        }

        switch (dataIndex) {
          case 'invoiceStatus':
            return (
              <EllipsisDiv
                text={enumValueToLabel(
                  getTableCellText(textValue),
                  INVOCING_STATUS,
                )}
              />
            );

          case 'status': {
            //这里状态不显示在筛选条件中,只能筛异常的流水
            return (
              <EllipsisDiv
                text={enumValueToLabel(
                  getTableCellText(textValue),
                  INVOICE_STATUS,
                )}
              />
            );
          }
          case 'payee':
            return (
              <EllipsisDiv
                text={enumValueToLabel(
                  getTableCellText(textValue),
                  PAYEE_OPTIONS,
                )}
              />
            );

          default:
            return <EllipsisDiv text={getTableCellText(textValue)} />;
        }
      };

      return newItem;
    });

    columns.push({
      title: '操作',
      valueType: 'option',
      key: 'option',
      fixed: 'right',
      width: 70,
      render: (text, record) => [
        <Button
          className="p-0"
          key="choose"
          type="link"
          onClick={() => {
            let amount = record.loanAmount || record.transactionAmount || 0;

            //已经选中,取消选中
            if (selectedStatementIdSet.has(record.id)) {
              setSelectedStatement(
                selectedStatement.filter((item) => {
                  return item.id !== record.id;
                }),
              );
              removeElement(record.id);
              setTotalAmount(parseFloat(FloatSub(totalAmount, amount)));
            } else {
              //添加到已选中区域中
              let newSelectedStatement = [...selectedStatement];
              newSelectedStatement.push(record);
              setSelectedStatement(newSelectedStatement);
              addElement(record.id);
              setTotalAmount(FloatAdd(totalAmount, amount));
            }
          }}
        >
          {selectedStatementIdSet.has(record.id) ? '取消选中' : '选中'}
        </Button>,
      ],
    });

    return columns;
  };

  /**
   * 删除已选中
   * @param record
   */
  const removeSelectedStatement = (record: any) => {
    setSelectedStatement(
      selectedStatement.filter((item) => {
        return item.id !== record.id;
      }),
    );
    removeElement(record.id);
  };

  const showSelectedStatement = () => {
    let i = 0;

    let tags = selectedStatement.map((item) => {
      console.log(item);
      let tagText = item.id;

      if (item.payeePayerName) {
        tagText += ' ' + item.payeePayerName + ' ';
      }

      if (item.loanAmount) {
        tagText += item.loanAmount + ' ';
      }

      if (item.transactionAmount) {
        tagText += item.transactionAmount;
      }

      return (
        <Tag
          key={i++}
          closable={true}
          style={{ userSelect: 'none' }}
          color="blue"
          onClose={(e) => {
            e.preventDefault(); //需要加上这句代码,不然删除tag时,当前tag的下一个tag会被设置ant-tag-hidden
            removeSelectedStatement(item);
          }}
        >
          <span>{tagText}</span>
        </Tag>
      );
    });

    console.log(tags);

    return tags;
  };

  return (
    <>
      <Modal
        open
        width="80%"
        title="添加银行流水"
        className="bank-statement-choose"
        onOk={async () => {
          setBtnLoading(true);
          let bankStatementIds = selectedStatement?.map((item) => {
            return item.id;
          });
          let res = await postServiceInvoiceInvoiceWriteOff({
            data: {
              invoiceId: invoiceId,
              bankStatementIds: bankStatementIds,
            },
          });

          if (res.result === RESPONSE_CODE.SUCCESS) {
            if (res.data?.length > 0) {
              message.info(res.data);
            } else {
              message.success(res.message);
            }

            onClose();
          }

          setBtnLoading(false);
        }}
        okButtonProps={{
          loading: btnLoading,
        }}
        onCancel={() => {
          setVisible(false);
        }}
      >
        <Divider orientation="left" plain>
          已选中(合计:¥{totalAmount})
        </Divider>
        <ProCard className="mb-[16px]" bordered style={{}}>
          <Flex wrap="wrap" gap="small">
            {showSelectedStatement()}
          </Flex>
        </ProCard>

        <ProTable
          columns={bankStatementColumnsInit()}
          actionRef={actionRef}
          cardBordered
          pagination={{
            pageSize: 10,
          }}
          editable={{
            type: 'multiple',
            onSave: async (rowKey, data) => {
              console.log(rowKey, data);
            },
            actionRender: (row, config, defaultDom) => [
              defaultDom.save,
              defaultDom.cancel,
            ],
          }}
          request={async (params) => {
            const res = await postServiceBankStatementQueryBankStatement({
              data: { ...params, status: 'ABNORMAL' },
            });
            if (res) {
              return {
                data: res?.data?.data || [],
                total: res?.data?.total || 0,
              };
            }
          }}
          columnsState={{
            persistenceKey: 'pro-table-singe-demos',
            persistenceType: 'localStorage',
            defaultValue: {
              option: { fixed: 'right', disable: true },
            },
            onChange(value) {
              console.log('value: ', value);
            },
          }}
          rowKey="id"
          search={{
            labelWidth: 'auto',
          }}
          options={{
            setting: {
              listsHeight: 400,
            },
          }}
          form={{}}
          dateFormatter="string"
          headerTitle="银行流水列表"
          scroll={{ x: 1400, y: 360 }}
          toolBarRender={() => []}
        />
      </Modal>
    </>
  );
};