page.tsx 10.4 KB
/* eslint-disable max-lines */
import { useEffect, useState, useMemo } from 'react';
import { helper, PageProvider, PoolTable, usePagination, useUrlParams, FilePreview } from '@feewee/h5app-common';
import { useNavigate } from '@modern-js/runtime/router';
import { cloneDeep } from 'lodash';
import dayjs from 'dayjs';

import type { DimensionEnum, QueryTypeEnum } from '../entity';
import { QueryItemTypeEnum, QueryItemTypeNameMap } from '../entity';
import { reviewListApi, type ReviewListResult } from '../service';
import rmb from '@/utils/rmb';

interface PageParams {
  applyId: number;
  queryType: QueryTypeEnum;
  queryItemType: QueryItemTypeEnum;
  type: DimensionEnum | QueryTypeEnum.USER_PUNISH;
  typeId: number;
}

/**
 * 单数明细
 */
const DetailList = () => {
  const params = useUrlParams<PageParams>();
  const navigate = useNavigate();

  const { queryType, queryItemType } = params;

  // 添加了动态数据后的 list 和 columns
  const [assembledList, setAssembledList] = useState<ReviewListResult[]>([]);

  const [delay, setDelay] = useState(true);
  const { list, param, setParams, loading, errMsg, resetParam, pagination } = usePagination(reviewListApi, params, delay);
  const { current = 1, pageSize = 15 } = param;

  useEffect(() => {
    if (params.applyId) {
      setDelay(false);
      setParams({ ...params, pageSize: 50 }, true);
    }
  }, []);

  function renderSecondaryAmount(val: number) {
    return (
      <span>
        <span>{rmb.p(val)}</span>元
      </span>
    );
  }

  const columns = useMemo(() => {
    let baseColumns = [
      {
        title: '索赔单号',
        dataIndex: 'claimNo',
        width: 120,
      },
      {
        title: '附件',
        dataIndex: 'fid',
        width: 150,
        render: val => <div style={{ maxWidth: 400 }}>{/* <FeeweeUploadAttachment maxCount={1} fidList={val ? [val] : []} disabled /> */}</div>,
      },
      {
        title: '索赔类型',
        dataIndex: 'claimTypeName',
        render: text => text || '--',
      },
    ];

    // 根据 queryItemType 展示不同列
    if ([QueryItemTypeEnum.SYSTEM_TOTAL, QueryItemTypeEnum.SYSTEM_ONLY].includes(queryItemType)) {
      baseColumns = baseColumns.concat([
        {
          title: '车牌号',
          dataIndex: 'plateNo',
          render: text => text || '--',
        },
        {
          title: '车架号',
          dataIndex: 'vin',
          render: text => text || '--',
        },
        {
          title: '车辆名称',
          dataIndex: 'carName',
          render: text => text || '--',
        },
        {
          title: '系统生成金额',
          dataIndex: 'totalFee',
          align: 'right',
          render: renderSecondaryAmount,
        },
        {
          title: '差异原因',
          dataIndex: 'differenceReason',
          render: text => text || '--',
        },
      ]);
    } else if (queryItemType === QueryItemTypeEnum.IMPORT_ONLY) {
      baseColumns = baseColumns.concat([
        {
          title: '厂家兑现金额',
          dataIndex: 'amount',
          width: 100,
          align: 'right',
          render: renderSecondaryAmount,
        },
      ]);
    } else if (queryItemType === QueryItemTypeEnum.DIFFERENCE_COUNT) {
      baseColumns = baseColumns.concat([
        {
          title: '系统生成金额',
          dataIndex: 'totalFee',
          align: 'center',
          children: [
            {
              title: '小计',
              dataIndex: 'totalFee',
              width: 100,
              align: 'right',
              render: renderSecondaryAmount,
            },
            {
              title: '工时费',
              dataIndex: 'systemManHoursFee',
              width: 100,
              align: 'right',
              render: renderSecondaryAmount,
            },
            {
              title: '材料费',
              dataIndex: 'systemPartFee',
              width: 100,
              align: 'right',
              render: renderSecondaryAmount,
            },
          ],
        },
        {
          title: '提报金额',
          dataIndex: 'submitAmount',
          align: 'center',
          children: [
            {
              title: '小计',
              dataIndex: 'submitAmount',
              width: 100,
              align: 'right',
              render: renderSecondaryAmount,
            },
            {
              title: '工时费',
              dataIndex: 'submitManHoursFee',
              width: 100,
              align: 'right',
              render: renderSecondaryAmount,
            },
            {
              title: '材料费',
              dataIndex: 'submitPartFee',
              width: 100,
              align: 'right',
              render: renderSecondaryAmount,
            },
          ],
        },
        {
          title: '厂家兑现金额',
          dataIndex: 'factoryAmount', // @note 前端定义,仅作数据查找
          align: 'center',
          children: [
            {
              title: '小计',
              dataIndex: 'amount',
              width: 100,
              align: 'right',
              render: renderSecondaryAmount,
            },
            // @slot 存放 importData 中的数据
          ],
        },
        {
          title: '差异金额',
          dataIndex: 'claimNo',
          align: 'center',
          children: [
            {
              title: '系统生成与厂家兑现差异',
              dataIndex: 'differenceAmount',
              width: 100,
              align: 'right',
              render: val => (
                <span>
                  <span className="danger">{rmb.p(val)}</span>元
                </span>
              ),
            },
            {
              title: '索赔提报与厂家兑现差异',
              dataIndex: 'differenceSubmitAmount',
              width: 100,
              align: 'right',
              render: val => (
                <span>
                  <span className="danger">{rmb.p(val)}</span>元
                </span>
              ),
            },
          ],
        },
        {
          title: '车牌号',
          dataIndex: 'plateNo',
          render: text => text || '--',
        },
        {
          title: '车架号',
          dataIndex: 'vin',
          render: text => text || '--',
        },
        {
          title: '车辆名称',
          dataIndex: 'carName',
          render: text => text || '--',
        },
      ]);
    } else {
      baseColumns = baseColumns.concat([
        {
          title: '车牌号',
          dataIndex: 'plateNo',
          render: text => text || '--',
        },
        {
          title: '车架号',
          dataIndex: 'vin',
          render: text => text || '--',
        },
        {
          title: '车辆名称',
          dataIndex: 'carName',
          render: text => text || '--',
        },
        {
          title: '厂家兑现金额',
          dataIndex: 'amount',
          align: 'right',
          render: renderSecondaryAmount,
        },
        {
          title: '系统生成金额',
          dataIndex: 'totalFee',
          align: 'right',
          render: renderSecondaryAmount,
        },
        {
          title: '差异金额',
          dataIndex: 'differenceAmount',
          align: 'right',
          render: val => (
            <span>
              <span className="danger">{rmb.p(val)}</span>元
            </span>
          ),
        },
      ]);
    }

    // 动态列:工时费、配件费、救援费等,差异时放到厂家兑现列中,其余情况追加在列后面
    const extraColumns = [];
    // 添加额外动态列数据
    const newList = cloneDeep(list);
    if (newList.length > 0) {
      // 构建表头
      if (newList[0].importData && ![QueryItemTypeEnum.SYSTEM_TOTAL, QueryItemTypeEnum.SYSTEM_ONLY].includes(queryItemType)) {
        const { importData } = newList[0];
        if (importData) {
          try {
            // { "工时费": 10, "配件费": 20, "救援费": 30, ... }
            const data = JSON.parse(importData);
            for (const key in data) {
              extraColumns.push({
                title: key,
                dataIndex: key,
                align: 'right',
                width: 100,
                render: val => <span className="warning">{val}</span>,
              });
            }
          } catch (e) {
            console.error('parse importData fail:', e);
          }
        }
      }

      // 构建表格数据
      // 2. 解析数据,若数据列有 importData 则解析为对象形式
      for (let i = 0; i < newList.length; i++) {
        if (newList[i].importData) {
          try {
            const data = JSON.parse(newList[i].importData);
            Object.assign(newList[i], data);
          } catch (e) {
            console.error('parse importData fail:', e);
          }
        }
      }

      // 处理分页数据
      if (current === 1) {
        setAssembledList(newList);
      } else {
        // 替换当前页数据
        const start = (current - 1) * pageSize;
        const end = start + pageSize;
        const newPageList = [...assembledList];
        newPageList.splice(start, end - start, ...newList);
        setAssembledList(newPageList);
      }
    }

    // 跟进差异类型,添加额外列
    if (queryItemType === QueryItemTypeEnum.DIFFERENCE_COUNT) {
      for (const column of baseColumns) {
        // @ts-ignore
        if (column.dataIndex === 'factoryAmount') {
          // @ts-ignore
          column.children = column.children.concat(extraColumns);
          break;
        }
      }
    } else {
      baseColumns = baseColumns.concat(extraColumns);
    }

    // 添加提报信息
    baseColumns = baseColumns.concat([
      {
        title: '提报人',
        dataIndex: 'claimer',
        width: 80,
        render: val => val || '--',
      },
      {
        title: '提报商家',
        dataIndex: 'submitDealerName',
        render: val => val || '--',
      },
      {
        title: '提报时间',
        dataIndex: 'commitTime',
        render: val => dayjs(val).format('YYYY-MM-DD HH:mm:ss'),
      },
    ]);
    return baseColumns;
  }, [queryType, queryItemType, list]);

  return (
    <PageProvider
      tittle={QueryItemTypeNameMap[params.queryItemType]}
      loading={loading}
      errMsg={errMsg}
      onBackClick={() => helper.checkBack(() => navigate(-1))}
    >
      <PoolTable list={assembledList} columns={columns} rowKey="claimNo" {...pagination} />
    </PageProvider>
  );
};

export default DetailList;