【Reactjs】多层展示报表信息

需求:

从后端返回的数据为层层嵌套的树状结构,前端如何层层遍历并展示?

json 文件
items: [
    {
      fieldName: 'allFlowMoney',
      fieldChineseName: '本期账单消费',
      totalFee: 0,
      existRebateReport: false,
      subItems: [
        {
          fieldName: 'fltConMoneyHasPost',
          fieldChineseName: '月结机票',
          totalFee: 0,
          existRebateReport: false,
          subItems: [
            {
              fieldName: 'fltTicketFee',
              fieldChineseName: '机票金额',
              totalFee: 0,
              existRebateReport: false,
              subItems: [],
            },
            {
              fieldName: 'fltRefund',
              fieldChineseName: '退票费',
              totalFee: 0,
              existRebateReport: false,
              subItems: [],
            },
            {
              fieldName: 'fltInsurancefee',
              fieldChineseName: '保险',
              totalFee: 0,
              existRebateReport: false,
              subItems: [],
            },
            {
              fieldName: 'fltServicePackagePrice',
              fieldChineseName: '服务包',
              totalFee: 0,
              existRebateReport: false,
              subItems: [],
            },
            {
              fieldName: 'fltCoupon',
              fieldChineseName: '优惠券',
              totalFee: 0,
              existRebateReport: false,
              subItems: [],
            },
            {
              fieldName: 'fltServiceFeeSummary',
              fieldChineseName: '服务费',
              totalFee: 0,
              existRebateReport: false,
              subItems: [],
            },
          ],
        },
        {
          fieldName: 'fltPostServiceFeeX',
          fieldChineseName: '现付机票服务费',
          totalFee: 0,
          existRebateReport: false,
          subItems: [],
        },
        {
          fieldName: 'htlXconMoney',
          fieldChineseName: '月结协议酒店',
          totalFee: 0,
          existRebateReport: false,
          subItems: [
            {
              fieldName: 'htlXRoomCharge',
              fieldChineseName: '酒店房费',
              totalFee: 0,
              existRebateReport: false,
              subItems: [],
            },
            {
              fieldName: 'htlXServiceFeeSummary',
              fieldChineseName: '酒店服务费',
              totalFee: 0,
              existRebateReport: false,
              subItems: [],
            },
            {
              fieldName: 'htlXServiceCharge',
              fieldChineseName: '手续费',
              totalFee: 0,
              existRebateReport: false,
              subItems: [],
            },
          ],
        },
        {
          fieldName: 'htlHconMoney',
          fieldChineseName: '月结会员酒店',
          totalFee: 0,
          existRebateReport: false,
          subItems: [
            {
              fieldName: 'htlHRoomCharge',
              fieldChineseName: '酒店房费',
              totalFee: 0,
              existRebateReport: false,
              subItems: [],
            },
            {
              fieldName: 'htlHServiceFeeSummary',
              fieldChineseName: '酒店服务费',
              totalFee: 0,
              existRebateReport: false,
              subItems: [],
            },
            {
              fieldName: 'htlHServiceCharge',
              fieldChineseName: '手续费',
              totalFee: 0,
              existRebateReport: false,
              subItems: [],
            },
          ],
        },
        {
          fieldName: 'htlXPaySummaryX',
          fieldChineseName: '月结协议酒店',
          totalFee: 0,
          existRebateReport: false,
          subItems: [
            {
              fieldName: 'htlXAfterServiceFeeX',
              fieldChineseName: '酒店服务费',
              totalFee: 0,
              existRebateReport: false,
              subItems: [],
            },
            {
              fieldName: 'htlXServiceChargeX',
              fieldChineseName: '手续费',
              totalFee: 0,
              existRebateReport: false,
              subItems: [],
            },
          ],
        },
        {
          fieldName: 'htlHPaySummaryX',
          fieldChineseName: '现付会员酒店',
          totalFee: 0,
          existRebateReport: false,
          subItems: [
            {
              fieldName: 'htlHAfterServiceFeeX',
              fieldChineseName: '酒店服务费',
              totalFee: 0,
              existRebateReport: false,
              subItems: [],
            },
            {
              fieldName: 'htlHServiceChargeX',
              fieldChineseName: '手续费',
              totalFee: 0,
              existRebateReport: false,
              subItems: [],
            },
          ],
        },
        {
          fieldName: 'trainRealAmountHasPost',
          fieldChineseName: '月结火车票',
          totalFee: 0,
          existRebateReport: false,
          subItems: [
            {
              fieldName: 'trainRealAmount',
              fieldChineseName: '火车票金额',
              totalFee: 0,
              existRebateReport: false,
              subItems: [],
            },
            {
              fieldName: 'fltRefund',
              fieldChineseName: '退票费服务费',
              totalFee: 0,
              existRebateReport: false,
              subItems: [],
            },
          ],
        },
        {
          fieldName: 'trainPostServiceFeeX',
          fieldChineseName: '现付火车票服务费',
          totalFee: 0,
          existRebateReport: false,
          subItems: [],
        },
        {
          fieldName: 'vasRealAmountHasPost',
          fieldChineseName: '月结增值',
          totalFee: 0,
          existRebateReport: false,
          subItems: [
            {
              fieldName: 'vasRealAmount',
              fieldChineseName: '增值金额',
              totalFee: 0,
              existRebateReport: false,
              subItems: [],
            },
            {
              fieldName: 'vasPostServiceFee',
              fieldChineseName: '增值服务费',
              totalFee: 0,
              existRebateReport: false,
              subItems: [],
            },
            {
              fieldName: 'vasCommissionFee',
              fieldChineseName: '增值手续费',
              totalFee: 0,
              existRebateReport: false,
              subItems: [],
            },
          ],
        },
        {
          fieldName: 'carPostServiceFeeX',
          fieldChineseName: '现付用车服务费',
          totalFee: 0,
          existRebateReport: false,
          subItems: [],
        },
        {
          fieldName: 'busRealFeeHasPost',
          fieldChineseName: '月结汽车票',
          totalFee: 0,
          existRebateReport: false,
          subItems: [
            {
              fieldName: 'busRealFee',
              fieldChineseName: '汽车票金额',
              totalFee: 0,
              existRebateReport: false,
              subItems: [],
            },
            {
              fieldName: 'busServiceFeeSummary',
              fieldChineseName: '汽车票服务费',
              totalFee: 0,
              existRebateReport: false,
              subItems: [],
            },
          ],
        },
        {
          fieldName: 'busLaterServiceFeeX',
          fieldChineseName: '现付汽车票服务费',
          totalFee: 0,
          existRebateReport: false,
          subItems: [],
        },
      ],
    },
    {
      fieldName: 'otherRebateSummary',
      fieldChineseName: '返利',
      totalFee: 0,
      existRebateReport: false,
      subItems: [
        {
          fieldName: 'otherFltRebate',
          fieldChineseName: 'FLIGHTREBATE',
          totalFee: 0,
          existRebateReport: false,
          subItems: [],
        },
        {
          fieldName: 'otherHtlRebate',
          fieldChineseName: '酒店返利',
          totalFee: 0,
          existRebateReport: false,
          subItems: [],
        },
        {
          fieldName: 'otherRebateAdjust',
          fieldChineseName: '调整返利',
          totalFee: 0,
          existRebateReport: false,
          subItems: [],
        },
      ],
    },
    {
      fieldName: 'otherAdjustSummary',
      fieldChineseName: '其他调整',
      totalFee: 0,
      existRebateReport: false,
      remark: '10000000000000',
      subItems: [],
    },
    {
      fieldName: 'otherLateFeeSummary',
      fieldChineseName: '滞纳金',
      totalFee: 0,
      existRebateReport: false,
      subItems: [
        {
          fieldName: 'otherLateFee',
          fieldChineseName: '滞纳金应收',
          totalFee: 0,
          existRebateReport: false,
          subItems: [],
        },
        {
          fieldName: 'otherOxlf',
          fieldChineseName: '滞纳金调整',
          totalFee: 0,
          existRebateReport: false,
          subItems: [],
        },
      ],
    },
  ],

前端展示

在这里插入图片描述

解决方案:

ant design collapse组件 + 递归

import React, { Fragment } from 'react';
import { Collapse } from 'antd';
import toThousands from '../../../utils/function';
import './index.less';
import { CaretRightOutlined } from '@ant-design/icons';

const { Panel } = Collapse;  

function callback(key: any) {
  // console.log(key)
}

function subItem(dataSource: any[]) {
  return Array.isArray(dataSource) ? (
    <Collapse
      bordered={false}
      onChange={callback}
      className="collapse"
      expandIcon={({ isActive }) => (
        <CaretRightOutlined rotate={isActive ? 90 : 0} />
      )}
    >
      {dataSource.map((v, index) =>
        v?.subItems?.length > 0 ? (
          <Panel
            header={
              <Fragment>
                <span className="chineseName">{v.fieldChineseName}</span>
                <span className="fee">{toThousands(v.totalFee)}</span>
                {v.existRebateReport && (
                  <span className="downloadReport">下载报表</span>
                )}
                {v.hasOwnProperty('remark') ? <div>{v.remark}</div> : ''}
              </Fragment>
            }
            key={`${v.fieldChineseName}-${index}`}
          >
            {subItem(v.subItems)}
          </Panel>
        ) : (
          <div className="detailBox clearfix">
            <span className="chineseNameLast">{v.fieldChineseName}</span>
            <span className="feeLast">{toThousands(v.totalFee)}</span>
            {v.existRebateReport && (
              <span className="downloadReport">下载报表</span>
            )}
            {v.hasOwnProperty('remark') ? (
              <div className="remark">{v.remark}</div>
            ) : (
              ''
            )}
          </div>
        ),
      )}
    </Collapse>
  ) : null;
}

export default function ConsumeDetail(props: any) {
  let { dataSource = [] } = props;

  // console.log('dataSource', dataSource);
  return (
    <Fragment>
      <div className="showCash">{subItem(dataSource)}</div>
    </Fragment>
  );
}

index.less

.ant-collapse {
  width : 100%;
 
  .ant-collapse-content>.ant-collapse-content-box {
    padding     : 0;
    padding-left: 14px;
  }
}
.ant-collapse-borderless > .ant-collapse-item {
  border: none;
}

.ant-collapse>.ant-collapse-item>.ant-collapse-header {
  border-bottom: 1px solid #d9d9d9;
}

// .ant-collapse-borderless > .ant-collapse-item:last-child,
// .ant-collapse-borderless > .ant-collapse-item:last-child .ant-collapse-header {
//   //border: none;
//   //padding-bottom: 0;
// }
.clearfix {
  display: block;
  content: "";
  clear  : both;
}

.showCash {
  margin: 12px 0 0 12px;

  .collapse {
    border: none;
    .chineseName {
      color         : #1b234d;
      font-family   : 'PingFang SC';
      font-size     : 14px;
      font-weight   : 500;
      height        : 22px;
      letter-spacing: px;
    }

    .fee {
      color          : #1b234d;
      font-family    : 'PingFang SC';
      font-size      : 16px;
      font-weight    : 500;
      height         : 24px;
      letter-spacing : px;
      float          : right;
      //padding-right: 14px;
    }

    .detailBox {
      padding      : 10px 0;
      border-bottom: 1px solid #e9e9e9;

      .chineseNameLast {
        color      : #1b234d;
        font-family: 'PingFang SC';
        font-size  : 14px;
        font-weight: 500;
        height     : 22px;
        margin-left: 40px;
      }

      .feeLast {
        color       : #1b234d;
        font-family : 'PingFang SC';
        font-size   : 16px;
        font-weight : 500;
        height      : 24px;
        float       : right;
        margin-right: 16px;
      }
    }

    .subChineseName {
      color      : #4d5580;
      font-family: 'PingFang SC';
      font-size  : 13px;
      font-weight: normal;
      height     : 22px;
    }

    .subFee {
      color          : #4c5a75;
      font-family    : 'PingFang SC';
      font-size      : 14px;
      font-weight    : normal;
      height         : 22px;
      float          : right;
      //padding-right: 14px;
    }

    .remark {
      color      : #8790a3;
      font-family: 'PingFang SC';
      font-size  : 12px;
      font-weight: 500;
      height     : 20px;
      margin     : 10px 0 0 30px;
    }

    .downloadReport {
      color      : #1658dc;
      font-family: 'PingFang SC';
      font-size  : 12px;
      font-weight: 500;
      height     : 20px;
      width      : 48px;
      margin-left: 24px;
    }
  }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值