<template>
  <div>
    
    <el-radio-group v-model="isEdit" @change='handleChangeIsEdit'>
    </el-radio-group>
    <el-table style="width: 100%;" :data="tableData" v-if='tableData.length' show-summary :summary-method="getSummaries">
      <el-table-column fixed prop="org_name" label="研究所名称" width="150">
      </el-table-column>
      <el-table-column v-for='(item,index) in timeList' :key='item' :label="`${item}年度`" header-align="center">
        <el-table-column label="费用化预算(万元)" width='250'>
          <template slot-scope="scope">
            <el-input-number :min="0" :controls='false' placeholder="请输入费用化预算(万元" v-model="scope.row[item].funds" @change='handleChangeMoney(scope.row, index, scope.$index)'></el-input-number>
          </template>
        </el-table-column>
        <el-table-column label="资本化预算(万元)" width='250'>
          <template slot-scope="scope">
            <el-input-number :disabled='scope.row.isEdit' :min="0" :controls='false' placeholder="请输入资本化预算(万元" v-model="scope.row[item].captialized_budget" @change='handleChangeMoney(scope.row, index, scope.$index)'></el-input-number>
          </template>
        </el-table-column>
      </el-table-column>
      <el-table-column fixed='right' prop="row_money" label="小计" width="150">
      </el-table-column>
    </el-table>
  </div>
</template>

<script>
/**
 * 判断是不是整数
 */
const isInteger = (obj) => {
  return Math.floor(obj) === obj;
};
/*
 * 将一个浮点数转成整数,返回整数和倍数。如 3.14 >> 314,倍数是 100
 * @param floatNum {number} 小数
 * @return {object}
 * {times:100, num: 314}
 */
const toInteger = (floatNum) => {
  const ret = { times: 1, num: 0 };
  if (isInteger(floatNum)) {
    ret.num = floatNum;
    return ret;
  }
  const strfi = floatNum + '';
  const dotPos = strfi.indexOf('.');
  const len = strfi.substr(dotPos + 1).length;
  const times = Math.pow(10, len);
  const intNum = parseInt(floatNum * times + 0.5, 10);
  ret.times = times;
  ret.num = intNum;
  return ret;
};
/*
 * 核心方法,实现加减乘除运算,确保不丢失精度
 * 思路:把小数放大为整数(乘),进行算术运算,再缩小为小数(除)
 *
 * @param a {number} 运算数1
 * @param b {number} 运算数2
 * @param op {string} 运算类型,有加减乘除(add/subtract/multiply/divide)
 *
 */
export const operation = (a, b, op) => {
  const o1 = toInteger(a);
  const o2 = toInteger(b);
  const n1 = o1.num;
  const n2 = o2.num;
  const t1 = o1.times;
  const t2 = o2.times;
  const max = t1 > t2 ? t1 : t2;
  let result = null;
  switch (op) {
    case 'add':
      if (t1 === t2) {
        // 两个小数位数相同
        result = n1 + n2;
      } else if (t1 > t2) {
        // o1 小数位 大于 o2
        result = n1 + n2 * (t1 / t2);
      } else {
        // o1 小数位 小于 o2
        result = n1 * (t2 / t1) + n2;
      }
      return result / max;
    case 'subtract':
      if (t1 === t2) {
        result = n1 - n2;
      } else if (t1 > t2) {
        result = n1 - n2 * (t1 / t2);
      } else {
        result = n1 * (t2 / t1) - n2;
      }
      return result / max;
    case 'multiply':
      result = (n1 * n2) / (t1 * t2);
      return result;
    case 'divide':
      result = (n1 / n2) * (t2 / t1);
      return result;
  }
};
// 加减乘除的四个接口
export const add = (a, b) => {
  return operation(a, b, 'add');
};
export const subtract = (a, b) => {
  return operation(a, b, 'subtract');
};
export const multiply = (a, b) => {
  return operation(a, b, 'multiply');
};
export const divide = (a, b) => {
  return operation(a, b, 'divide');
};
export default {
  data() {
    return {
      startTime: '2020',
      endTime: '2023',
      isEdit: false, // 这个是切换时修改的值
      timeList: [],
      tableData: [],
      companyList: [
        {
          org_id: '11',
          org_name: '奥利给研究所1',
          org_code: 11,
          force_project_id: 11,
          org_total_fund: '',
        },
        {
          org_id: '12',
          org_name: '奥利给研究所2',
          org_code: 12,
          force_project_id: 12,
          org_total_fund: '',
        },
        {
          org_id: '13',
          org_name: '奥利给研究所3',
          org_code: 13,
          force_project_id: 13,
          org_total_fund: '',
        },
        {
          org_id: '14',
          org_name: '奥利给研究所3',
          org_code: 14,
          force_project_id: 14,
          org_total_fund: '',
        },
      ],
    };
  },
  methods: {
    initTableData() {
      let timeList = (this.timeList = Array.from(
        {
          length: Number(this.endTime) - Number(this.startTime) + 1,
        },
        (item, index) => {
          return Number(this.startTime) + index;
        }
      ));
      let tableData = this.companyList.map((tableItem, tableIndex) => {
        timeList.forEach((timeItem, timeIndex) => {
          this.$set(tableItem, 'row_money', 0);
          this.$set(tableItem, 'column_money', 0);
          this.$set(tableItem, 'column1_money', 0);
          this.$set(tableItem, 'isEdit', this.isEdit);
          this.$set(tableItem, timeItem, {
            funds: '',
            captialized_budget: '',
          });
        });
        return tableItem;
      });
      this.tableData = tableData;
    },
    handleChangeMoney(row, index, oldIndex) {
      let handleReckonMoney = (row) => {
        let row_money = 0;
        let column_money = 0;
        let column1_money = 0;
        this.timeList.forEach((item) => {
          row_money = add(
            Number(row_money),
            add(Number(row[item].captialized_budget), Number(row[item].funds))
          );
          this.$set(row, 'row_money', row_money);
        });
      };
      handleReckonMoney(row);
    },
    getSummaries(param) {
      const { columns, data } = param;
      const sums = [];
      columns.forEach((column, index) => {
        if (index === 0) {
          sums[index] = '合计(万元)';
          return;
        } else if (index < columns.length - 1) {
          let ret = 0;
          if (index % 2 === 1) {
            data.forEach((itemData) => {
              ret = add(
                Number(ret),
                Number(itemData[this.timeList[Math.ceil(index / 2) - 1]].funds)
              );
            });
            sums[index] = ret;
          } else {
            data.forEach((itemData) => {
              ret = add(
                Number(ret),
                Number(
                  itemData[this.timeList[Math.ceil(index / 2) - 1]]
                    .captialized_budget
                )
              );
            });
            sums[index] = ret;
          }
        } else {
          let ret = 0;
          for (let i = 1; i < columns.length - 1; i++) {
            ret = add(Number(ret), Number(sums[i]));
          }
          sums[index] = ret;
        }
      });
      return sums;
    },
    handleChangeIsEdit(e) {
      this.tableData.forEach((item) => {
        this.$set(item, 'isEdit', this.isEdit);
      });
    },
  },
  created() {
    this.initTableData();
  },
};
</script>
发送给后端的数据格式
tableData: [
        {
          org_id: '11',
          org_name: '奥利给研究所1',
          org_code: 11,
          force_project_id: 11,
          org_total_fund: '',
          '2020': {},
          '2021': {},
          '2022': {},
          '2023': {},
          '2024': {}
        }
      ]