项目资金计划表组件说明文档

138 阅读3分钟

功能概述

项目资金计划表组件是一个基于 Vue 3 和 Element Plus 的表格组件,用于展示和管理项目的资金计划。该组件支持多个项目的资金计划展示,包括各类款项和月度资金分配的详细信息。

主要特性

  1. 项目信息展示

    • 项目基本信息(名称、装机容量、开工/竣工日期)
    • 固定左侧关键信息列
    • 合并相同项目的信息单元格
  2. 资金计划管理

    • 显示合同金额、变更金额、审定金额
    • 自动计算项目小计
    • 自动汇总所有项目总计
  3. 月度计划展示

    • 按月展示资金使用计划
    • 支持跨年度计划(2025-2026年)
    • 自动计算月度汇总数据

技术实现

1. 数据结构

项目选择接口

interface Project {
  value: string  // 项目的唯一标识值
  label: string  // 项目的显示名称
}

表格行数据接口

interface TableRowData {
  index: number           // 项目序号
  projectName: string     // 项目名称
  capacity: string        // 装机容量(kwp)
  startDate: string       // 开工日期
  endDate: string        // 竣工日期
  paymentType: string    // 款项类型(设计、EPC、组件等)
  contractAmount: string // 合同金额
  changeAmount: string   // 变更金额
  approvedAmount: string // 审定金额
  [key: string]: string | number  // 动态属性,用于存储月度计划金额
}

小计数据接口

interface SubtotalData {
  contractAmount: number  // 合同金额小计
  changeAmount: number    // 变更金额小计
  approvedAmount: number  // 审定金额小计
  [key: string]: number  // 动态属性,用于存储月度计划金额小计
}

2. 核心功能实现

2.1 单元格合并处理

/**
 * 处理单元格合并
 * @param {object} param0 - 合并参数对象
 * @param {number} param0.rowIndex - 当前行的索引,用于计算是否需要合并行
 * @param {number} param0.columnIndex - 当前列的索引,用于判断是否是需要合并的列
 * @returns {object | undefined} 返回合并配置对象或undefined
 */
function objectSpanMethod({ rowIndex, columnIndex }: SpanMethodProps) {
  if (columnIndex < 5) { // 序号、项目名称、装机容量、开工日期、竣工日期需要合并
    if (rowIndex % 6 === 0) {
      return {
        rowspan: 6,
        colspan: 1,
      }
    }
    return {
      rowspan: 0,
      colspan: 0,
    }
  }
  return undefined
}

2.2 小计计算

function calculateSubtotal(projectData: TableRowData[]): SubtotalData {
  const subtotal: SubtotalData = {
    contractAmount: 0,
    changeAmount: 0,
    approvedAmount: 0,
  }

  projectData.forEach((row) => {
    if (row.paymentType !== '小计') {
      // 累加基本金额
      subtotal.contractAmount += Number(row.contractAmount) || 0
      subtotal.changeAmount += Number(row.changeAmount) || 0
      subtotal.approvedAmount += Number(row.approvedAmount) || 0

      // 计算月度金额
      for (let month = 1; month <= 12; month++) {
        const monthKey = `month2025${month}`
        subtotal[monthKey] = (subtotal[monthKey] || 0) + (Number(row[monthKey]) || 0)
      }
      for (let month = 1; month <= 3; month++) {
        const monthKey = `month2026${month}`
        subtotal[monthKey] = (subtotal[monthKey] || 0) + (Number(row[monthKey]) || 0)
      }
    }
  })

  return subtotal
}

3. 组件布局

<template>
  <div class="project-funding-plan">
    <!-- 操作区域 -->
    <div class="header-actions">
      <el-select v-model="selectedProject" placeholder="请选择项目">
        <el-option
          v-for="item in projects"
          :key="item.value"
          :label="item.label"
          :value="item.value"
        />
      </el-select>
      <el-button type="primary" @click="handleQuery">
        查询
      </el-button>
      <el-button type="success" @click="handleExport">
        导出
      </el-button>
    </div>

    <!-- 表格区域 -->
    <el-table
      :data="[...tableData, totalRow]"
      border
      style="width: 100%;"
      :span-method="objectSpanMethod"
      :fixed="true"
    >
      <!-- 基本信息列 -->
      <el-table-column label="序号" width="60" align="center" fixed="left">
        <template #default="scope">
          {{ scope.row.index }}
        </template>
      </el-table-column>
      <!-- 其他列配置... -->
    </el-table>
  </div>
</template>

4. 样式设置

.project-funding-plan {
  padding: 20px;
  
  .header-actions {
    margin-bottom: 20px;
    display: flex;
    gap: 10px;
  }
}

:deep(.el-table__fixed) {
  height: 100% !important;
}

:deep(.el-table__fixed-right) {
  right: 0;
  height: 100% !important;
}

:deep(.el-table .fixed-right-patch) {
  background-color: #fff;
}

使用示例

基本使用

<template>
  <project-funding-plan />
</template>

<script setup lang="ts">
import ProjectFundingPlan from './components/ProjectFundingPlan.vue'
</script>

数据格式示例

// 项目数据示例
const projects = [
  { value: '1', label: '光伏发电项目A' },
  { value: '2', label: '风电项目B' },
]

// 表格行数据示例
const tableData = [
  {
    index: 1,
    projectName: '光伏发电项目A',
    capacity: '100000',
    startDate: '2025-03-01',
    endDate: '2025-12-31',
    paymentType: '设计',
    contractAmount: '2500000',
    changeAmount: '150000',
    approvedAmount: '2650000',
    month20251: '200000',
    // ... 其他月度数据
  },
  // ... 其他行数据
]

注意事项

  1. 数据格式要求

    • 金额类数据必须为字符串类型
    • 日期格式为 'YYYY-MM-DD'
    • 装机容量单位为 kwp
  2. 性能考虑

    • 大量数据时注意表格渲染性能
    • 合并单元格可能影响滚动性能
  3. 样式调整

    • 固定列宽度需要合理设置
    • 注意表格整体宽度的控制

后续优化建议

  1. 功能增强

    • 添加数据导入功能
    • 支持更多的数据筛选条件
    • 添加数据编辑功能
  2. 性能优化

    • 实现虚拟滚动
    • 优化大数据量渲染
  3. 交互优化

    • 添加更多的数据可视化图表
    • 优化移动端适配