InvoiceAnalysis.vue 6.4 KB
<template>
  <BasicModal
    v-bind="$attrs"
    @register="register"
    title="收款单分析"
    width="60%"
    okText="导出"
    :isDetail="true"
    :showDetailBack="false"
    @ok="handleOk"
    @visible-change="handleShow"
  >
    <div class="p-4">
      <BasicTable @register="registerTable">
        <template #bodyCell="{ column, record }">
          <template v-if="column.key === 'action'"> </template>
        </template>
      </BasicTable>
    </div>
  </BasicModal>
</template>
<script lang="ts" setup>
  import { BasicModal, useModalInner } from '@/components/Modal';
  import { computed, ref, watch } from 'vue';
  import { invoiceAnalysis, exportAnalysis } from '@/api/project/invoice';
  import { BasicColumn, useTable, BasicTable, ColumnChangeParam } from '/@/components/Table';
  // 处理弹窗的确定按钮点击事件
  import axios from 'axios';
  import { useDataStoreWithOut } from '/@/store/modules/data';
  import { useOrderStoreWithOut } from '/@/store/modules/order';
  import { store } from '/@/store';
  import { useUserStoreWithOut } from '/@/store/modules/user';

  const userStore = useUserStoreWithOut();

  const columnsAnalysis: BasicColumn[] = [
    {
      title: '客户编码',
      dataIndex: 'actualPayedAmount',
      width: 50,
      customRender: (res) => {
        return res?.record?.exportVOS[0]?.customerCode;
      },
    },
    {
      title: '客户总金额汇总$',
      dataIndex: 'customerTotalPrice',
      width: 50,
      customRender: (res) => {
        return res?.record?.customerTotalPrice.toFixed(2);
      },
    },
    {
      title: '客户扣款金额汇总$',
      dataIndex: 'deductAmount',
      width: 50,
      customRender: (res) => {
        return res?.record?.deductAmount.toFixed(2);
      },
    },
    {
      title: '实际应收款$',
      dataIndex: 'otherAmount',
      width: 50,
      customRender: (res) => {
        return res?.record?.otherAmount.toFixed(2);
      },
    },
    {
      title: '实际收款金额汇总$',
      dataIndex: 'actualReceivableAmount',
      width: 50,
      customRender: (res) => {
        return res?.record?.actualReceivableAmount.toFixed(2);
      },
    },
    {
      title: '其他费用金额汇总$',
      dataIndex: 'otherTotalAmount',
      width: 50,
      customRender: (res) => {
        return res?.record?.otherTotalAmount.toFixed(2);
      },
    },
    {
      title: '未收金额合计$',
      dataIndex: 'actualPayedAmount',
      width: 50,
      customRender: (res) => {
        return res?.record?.actualPayedAmount.toFixed(2);
      },
    },
  ];
  // const ids = ref<number[]>([]);
  const ids = ref();
  const orderIds = ref();
  const tableData = ref([]);
  const dataStore = useOrderStoreWithOut(); // 获取 store 实例
  const queryVO = ref();
  watch(
    () => store.state, // 监控 queryVO
    (newQueryVO, oldQueryVO) => {
      queryVO.value = dataStore.getQueryVO;
      // 在这里可以根据 queryVO 的变化进行其他操作,比如重新请求数据等
    },
    { deep: true }, // 深度监控 queryVO 数组或对象的变化
  );
  // const res = ref();

  const [register, { closeModal }] = useModalInner(async (data) => {
    ids.value = data.data;
    orderIds.value = data.id;
    setTimeout(() => {
      reload();
    }, 50);
  });
  const [registerTable, { reload }] = useTable({
    // api: () => invoiceAnalysis({ ids: ids.value }),
    api: async () => {
      const res = await invoiceAnalysis({
        ids: ids.value,
        orderIds: orderIds.value,
        queryVO: queryVO.value,
      });
      // 计算合计行
      const sum = {
        customerTotalPrice: 0,
        deductAmount: 0,
        otherAmount: 0,
        actualReceivableAmount: 0,
        otherTotalAmount: 0,
        actualPayedAmount: 0,
        exportVOS: res[0].exportVOS ? JSON.parse(JSON.stringify(res[0].exportVOS)) : [],
      };

      res.forEach((item: any) => {
        sum.customerTotalPrice += item.customerTotalPrice || 0;
        sum.deductAmount += item.deductAmount || 0;
        sum.otherAmount += item.otherAmount || 0;
        sum.actualReceivableAmount += item.actualReceivableAmount || 0;
        sum.otherTotalAmount += item.otherTotalAmount || 0;
        sum.actualPayedAmount += item.actualPayedAmount || 0;
      });
      if (sum.exportVOS && sum.exportVOS[0]) {
        sum.exportVOS[0].customerCode = '合计';
      }
      res.push(sum);
      return res;
    },
    columns: columnsAnalysis,
    bordered: true,
  });
  function handleShow(visible: boolean) {
    reload();
  }
  const searchData = ref({});
  async function handleOk() {
    // 构造符合 API 要求的参数
    const idss = ids.value;
    const token = userStore.getToken;
    // await exportAnalysis({ ids: ids });
    axios
      .post(
        '/basic-api/order/erp/invoice_bill/export',
        {
          ids: idss,
          orderIds: orderIds.value,
          queryVO: queryVO.value,
        },
        {
          headers: {
            Authorization: `${token}`, // 去掉引号
          },
          responseType: 'blob', // 设置响应类型为 'blob'
        },
      )
      .then((response) => {
        // 创建一个 Blob 对象来保存二进制数据
        const blob = new Blob([response.data], { type: 'application/zip' });
        const getFormattedDate = (): string => {
          const date = new Date();

          const year = date.getFullYear();
          const month = String(date.getMonth() + 1).padStart(2, '0');
          const day = String(date.getDate()).padStart(2, '0');

          const hours = String(date.getHours()).padStart(2, '0');
          const minutes = String(date.getMinutes()).padStart(2, '0');
          const seconds = String(date.getSeconds()).padStart(2, '0');

          return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
        };
        const date = getFormattedDate();
        // 创建一个链接元素用于下载
        const link = document.createElement('a');
        link.href = window.URL.createObjectURL(blob);
        link.download = `收款单分析${date}.xlsx`; // 你可以为文件命名
        document.body.appendChild(link);
        link.click(); // 自动点击链接,触发下载
        document.body.removeChild(link); // 下载完成后移除链接
      })
      .catch((error) => {
        console.error(error);
      });
    closeModal();
  }
</script>
<style scoped>
  .divAll {
    display: flex;
    justify-content: center;
    align-items: center;
  }
</style>