20241118

<template>
  <a-table
    :columns="columns"
    :data-source="processedData"
    :scroll="{ x: '100%' }"
    :pagination="false"
    bordered
    size="small"
  >
    <template #summary>
      <a-table-summary-row>
        <a-table-summary-cell :index="0" :col-span="5">
          <span style="font-weight: bold">DDR汇总</span>
        </a-table-summary-cell>
        <a-table-summary-cell
          v-for="(month, index) in newData.head"
          :key="month"
          :index="index + 5"
          align="center"
        >
          <a-typography-text
            :type="totals[month] < 0 ? 'danger' : undefined"
            style="font-weight: bold; font-size: 10px"
          >
            {{ totals[month] }}
          </a-typography-text>
        </a-table-summary-cell>
      </a-table-summary-row>
    </template>
  </a-table>
</template>

<script setup lang="ts">
import { computed } from "vue";
import type { TableColumnType } from "ant-design-vue";

interface TableItem {
  productFamily: string;
  data: Record<string, number>;
}

interface TableGroup {
  productType: string;
  techNode: string;
  nickName: string;
  qg: string;
  items: TableItem[];
}

const getConsecutiveCount = (
  array: any[],
  startIndex: number,
  key: string
): number => {
  const value = array[startIndex][key];
  let count = 1;

  for (let i = startIndex + 1; i < array.length; i++) {
    if (array[i][key] === value) {
      count++;
    } else {
      break;
    }
  }

  return count;
};

const newData = {
  head: [
    "202410",
    "202411",
    "202412",
    "2024H1",
    "2024H2",
    "2024 TTL",
    "2025H1",
    "2025H2",
    "2025TTL",
  ],
  items: [
    {
      productType: "DDR",
      techNodes: [
        {
          techNode: "G1",
          nicknames: [
            {
              nickname: "DQRMB",
              qgs: [
                {
                  qg: "Non-QG5",
                  subFamilys: [
                    {
                      subFamily: "Wafer",
                      items: [
                        { name: "202410", outputValue: 0 },
                        { name: "202411", outputValue: 0 },
                        { name: "202412", outputValue: 0 },
                        { name: "2024H1", outputValue: 0 },
                        { name: "2024H2", outputValue: 0 },
                        { name: "2024 TTL", outputValue: 0 },
                        { name: "2025H1", outputValue: 0 },
                        { name: "2025H2", outputValue: 0 },
                        { name: "2025TTL", outputValue: 0 },
                      ],
                    },
                    {
                      subFamily: "4Gb x16 DG",
                      items: [
                        { name: "202410", outputValue: -9 },
                        { name: "202411", outputValue: -2 },
                        { name: "202412", outputValue: 10 },
                        { name: "2024H1", outputValue: 0 },
                        { name: "2024H2", outputValue: 0 },
                        { name: "2024 TTL", outputValue: 29 },
                        { name: "2025H1", outputValue: 126 },
                        { name: "2025H2", outputValue: 125 },
                        { name: "2025TTL", outputValue: 0 },
                      ],
                    },
                    {
                      subFamily: "8Gb x16",
                      items: [
                        { name: "202410", outputValue: -27 },
                        { name: "202411", outputValue: 93 },
                        { name: "202412", outputValue: 120 },
                        { name: "2024H1", outputValue: 0 },
                        { name: "2024H2", outputValue: 0 },
                        { name: "2024 TTL", outputValue: 126 },
                        { name: "2025H1", outputValue: 126 },
                        { name: "2025H2", outputValue: 0 },
                        { name: "2025TTL", outputValue: 0 },
                      ],
                    },
                    {
                      subFamily: "8Gb x4",
                      items: [
                        { name: "202410", outputValue: 2 },
                        { name: "202411", outputValue: -100 },
                        { name: "202412", outputValue: -10 },
                        { name: "2024H1", outputValue: -108 },
                        { name: "2024H2", outputValue: -108 },
                        { name: "2024 TTL", outputValue: 458 },
                        { name: "2025H1", outputValue: 458 },
                        { name: "2025H2", outputValue: 0 },
                        { name: "2025TTL", outputValue: 458 },
                      ],
                    },
                  ],
                },
                {
                  qg: "QG5",
                  subFamilys: [
                    {
                      subFamily: "x8 DG&Hwe",
                      items: [
                        { name: "202410", outputValue: 107 },
                        { name: "202411", outputValue: -237 },
                        { name: "202412", outputValue: -190 },
                        { name: "2024H1", outputValue: -320 },
                        { name: "2024H2", outputValue: -320 },
                        { name: "2024 TTL", outputValue: -122 },
                        { name: "2025H1", outputValue: -122 },
                        { name: "2025H2", outputValue: -122 },
                        { name: "2025TTL", outputValue: 0 },
                      ],
                    },
                  ],
                },
              ],
            },
          ],
        },
        {
          techNode: "G3",
          nicknames: [
            {
              nickname: "DGPQA",
              qgs: [
                {
                  qg: "Non-QG5",
                  subFamilys: [
                    {
                      subFamily: "16Gb x8",
                      items: [
                        { name: "202410", outputValue: 0 },
                        { name: "202411", outputValue: 0 },
                        { name: "202412", outputValue: 80 },
                        { name: "2024H1", outputValue: 80 },
                        { name: "2024H2", outputValue: 80 },
                        { name: "2024 TTL", outputValue: 148 },
                        { name: "2025H1", outputValue: 148 },
                        { name: "2025H2", outputValue: 0 },
                        { name: "2025TTL", outputValue: 0 },
                      ],
                    },
                  ],
                },
                {
                  qg: "QG5",
                  subFamilys: [
                    {
                      subFamily: "16Gb x16",
                      items: [
                        { name: "202410", outputValue: 6 },
                        { name: "202411", outputValue: 6 },
                        { name: "202412", outputValue: 0 },
                        { name: "2024H1", outputValue: 0 },
                        { name: "2024H2", outputValue: 0 },
                        { name: "2024 TTL", outputValue: -1068 },
                        { name: "2025H1", outputValue: -1068 },
                        { name: "2025H2", outputValue: -147 },
                        { name: "2025TTL", outputValue: -218 },
                      ],
                    },
                    {
                      subFamily: "16Gb x4",
                      items: [
                        { name: "202410", outputValue: 380 },
                        { name: "202411", outputValue: 449 },
                        { name: "202412", outputValue: -1684 },
                        { name: "2024H1", outputValue: 2140 },
                        { name: "2024H2", outputValue: 2140 },
                        { name: "2024 TTL", outputValue: -8825 },
                        { name: "2025H1", outputValue: -8825 },
                        { name: "2025H2", outputValue: -2522 },
                        { name: "2025TTL", outputValue: 818 },
                      ],
                    },
                  ],
                },
              ],
            },
          ],
        },
      ],
    },
  ],
};

// 处理数据为扁平结构的函数也需要相应调整:
const processedData = computed(() => {
  const result: any[] = [];
  let currentIndex = 0;

  // 数据扁平化
  const flattenData = (data: typeof newData) => {
    data.items.forEach((productTypeGroup) => {
      productTypeGroup.techNodes.forEach((techNodeGroup) => {
        techNodeGroup.nicknames.forEach((nicknameGroup) => {
          nicknameGroup.qgs.forEach((qgGroup) => {
            qgGroup.subFamilys.forEach((subFamily) => {
              const monthValues: Record<string, number> = {};
              subFamily.items.forEach((item) => {
                monthValues[item.name] = item.outputValue;
              });

              result.push({
                key: currentIndex++,
                productType: productTypeGroup.productType,
                techNode: techNodeGroup.techNode,
                nickName: nicknameGroup.nickname,
                qg: qgGroup.qg,
                productFamily: subFamily.subFamily,
                ...monthValues,
              });
            });
          });
        });
      });
    });
  };

  flattenData(newData);

  // 计算合并单元格信息
  const processRowSpans = (rows: any[]) => {
    rows.forEach((row, index) => {
      row._isFirst = {
        productType:
          index === 0 || rows[index - 1].productType !== row.productType,
        techNode: index === 0 || rows[index - 1].techNode !== row.techNode,
        nickName: index === 0 || rows[index - 1].nickName !== row.nickName,
        qg: index === 0 || rows[index - 1].qg !== row.qg,
      };

      row._rowSpan = {};
      if (row._isFirst.productType) {
        row._rowSpan.productType = getConsecutiveCount(
          rows,
          index,
          "productType"
        );
      }
      if (row._isFirst.techNode) {
        row._rowSpan.techNode = getConsecutiveCount(rows, index, "techNode");
      }
      if (row._isFirst.nickName) {
        row._rowSpan.nickName = getConsecutiveCount(rows, index, "nickName");
      }
      if (row._isFirst.qg) {
        row._rowSpan.qg = getConsecutiveCount(rows, index, "qg");
      }
    });
  };

  processRowSpans(result);
  return result;
});

// 计算汇总数据
const totals = computed(() => {
  const sums: Record<string, number> = {};

  newData.head.forEach((month) => {
    sums[month] = 0;
  });

  processedData.value.forEach((row) => {
    newData.head.forEach((month) => {
      sums[month] += Number(row[month]) || 0;
    });
  });

  return sums;
});

// 列定义
const columns = [
  {
    title: "分类",
    dataIndex: "productType",
    fixed: "left",
    width: 120,
    align: "center",
    customRender: ({ text, record }: { text: string; record: any }) => ({
      children: text,
      props: {
        rowSpan: record._isFirst.productType ? record._rowSpan.productType : 0,
      },
    }),
  },
  {
    title: "Tech Node",
    dataIndex: "techNode",
    fixed: "left",
    width: 120,
    align: "center",
    customRender: ({ text, record }: { text: string; record: any }) => ({
      children: text,
      props: {
        rowSpan: record._isFirst.techNode ? record._rowSpan.techNode : 0,
      },
    }),
  },
  {
    title: "Nick Name",
    dataIndex: "nickName",
    fixed: "left",
    width: 120,
    align: "center",
    customRender: ({ text, record }: { text: string; record: any }) => ({
      children: text,
      props: {
        rowSpan: record._isFirst.nickName ? record._rowSpan.nickName : 0,
      },
    }),
  },
  {
    title: "QG分类",
    dataIndex: "qg",
    fixed: "left",
    width: 120,
    align: "center",
    customRender: ({ text, record }: { text: string; record: any }) => ({
      children: text,
      props: {
        rowSpan: record._isFirst.qg ? record._rowSpan.qg : 0,
      },
    }),
  },
  {
    title: "Product分类",
    dataIndex: "productFamily",
    fixed: "left",
    width: 150,
    align: "center",
  },
  // 动态月份列
  ...newData.head.map((month) => ({
    title: month,
    dataIndex: month,
    align: "center",
    width: 100,
    // 这里修改一下统计列的标识逻辑
    className: /(H1|H2|TTL)/.test(month) ? "statistics-column1" : "",
  })),
];
</script>

<style scoped>
:deep(.ant-table-thead > tr > th.statistics-column1) {
  /* 统计列样式1 */
  background-color: rgb(255, 128, 0) !important;
  font-weight: bold;
}

:deep(.ant-table-thead > tr > th.statistics-column2) {
  /* 统计列样式2 */
  background-color: #g5g5g5 !important;
  font-weight: bold;
}

:deep(.ant-table-thead > tr > th) {
  text-align: center;
  background: #e6f4ff !important; /* 改为浅蓝色背景 */
  padding: 0px;
  border-top: 1px solid black !important; /* 加粗汇总行顶边框 */
  border-bottom: 1px solid black !important; /* 加粗表头底边框 */
}

:deep(.ant-table-tbody > tr > td) {
  padding: 0px;
}

:deep(.ant-table-tbody > tr:hover > td) {
  background: #f0f7ff;
}

:deep(.ant-table-summary) {
  background: #e6f4ff !important; /* 改为浅蓝色背景 */
  font-size: 10px;
}

:deep(.ant-table-summary > tr > td) {
  padding: 0px;
  border-top: 1px solid black !important; /* 加粗汇总行顶边框 */
  border-bottom: 1px solid black !important; /* 加粗汇总行底边框 */
}

:deep(.ant-table) {
  border-radius: 0 !important;
}

/* 去掉表格圆角 */
:deep(.ant-table) {
  border-radius: 0 !important;
}

:deep(.ant-table-container) {
  border-radius: 0 !important;
}

:deep(.ant-table-content) {
  border-radius: 0 !important;
}

/* 去掉表头圆角 */
:deep(.ant-table-thead > tr:first-child > th:first-child) {
  border-top-left-radius: 0 !important;
}

:deep(.ant-table-thead > tr:first-child > th:last-child) {
  border-top-right-radius: 0 !important;
}
:deep(.ant-table-cell) {
  white-space: nowrap;
}

:deep(table) {
  font-size: 10px !important;
}

/* 更具体的表头 padding 控制 */
:deep(.ant-table-thead > tr > th.ant-table-cell) {
  padding: 0 !important;
  height: 24px !important; /* 可以通过调整高度来控制行高 */
}

/* 更具体的单元格 padding 控制 */
:deep(.ant-table-tbody > tr > td.ant-table-cell) {
  padding: 0 !important;
  height: 24px !important;
}

/* 更具体的汇总行 padding 控制 */
:deep(.ant-table-summary > tr > td.ant-table-cell) {
  height: 24px !important;
}

/* 如果还有内部的 padding,可以再添加这个 */
:deep(.ant-table-cell-content) {
  padding: 0 !important;
}

/* 如果需要保持一些最小的左右间距,可以这样设置 */
:deep(.ant-table-cell) {
  padding-left: 4px !important;
  padding-right: 4px !important;
  padding-top: 0 !important;
  padding-bottom: 0 !important;
}
</style>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值