element表格的計算


<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': {}
        }
      ]


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM