yxh
2026-09-20 c870390bfc28b314f30240352895c5d6c466c148
AI修复
已删除2个文件
已修改28个文件
已添加2个文件
1440 ■■■■■ 文件已修改
README.md 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
build/checkMoney.js 148 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
dist.rar 补丁 | 查看 | 原始文档 | blame | 历史
package.json 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/money.js 240 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/home/components/BarChart/index.vue 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/home/components/BarChart2/index.vue 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/home/components/BarChart3/index.vue 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/home/components/BarChartH/index.vue 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/home/components/MapChart/index.vue 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/home/components/line1Chart/index.vue 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/home/components/line2Chart/index.vue 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/home/components/lineChart/index.vue 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/project/donorcharge/donorchargedetail/index.vue 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/project/fund/applyDetail/index.vue 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/project/fund/applyDetail0/index.vue 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/project/fund/ethicalExpertFeeApply/index.vue 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/project/fund/expertFeeApply/index.vue 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/project/fund/medicalCostApply/index.vue 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/project/fund/officeExpenseApply/index.vue 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/project/fund/performancedetails/index.vue 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/project/fundcheck/ethicalExpertFeeCheck/index.vue 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/project/fundcheck/medicalCostCheck/index.vue 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/project/fundcheck/officeExpenseCheck/index.vue 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/project/tallage/computingBill/index.vue 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/project/travelexpenseapply/edit.vue 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/project/travelexpenseapply/index.vue 292 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/project/travelexpenseapply/travelexpensedetail/index.vue 107 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/project/travelexpensecheck/index.vue 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/project/unitCost/particulars/index.vue 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
vue.config.js 4 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
省人民opo.zip 补丁 | 查看 | 原始文档 | blame | 历史
README.md
@@ -1,12 +1,9 @@
## å¼€å‘
> æœ¬ç›®å½• `opo-web/` å³ PC å‰ç«¯å·¥ç¨‹æ ¹ç›®å½•(原若依模板名为 `ruoyi-ui`,此处已改名)。
> ä»¥ä¸‹å‘½ä»¤**均在 `opo-web/` ä¸‹æ‰§è¡Œ**。
```bash
# å…‹éš†é¡¹ç›®
git clone https://gitee.com/y_project/RuoYi-Vue
# è¿›å…¥é¡¹ç›®ç›®å½•
cd ruoyi-ui
# å®‰è£…依赖
npm install
build/checkMoney.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,148 @@
#!/usr/bin/env node
/**
 * é‡‘额精度检查(防复发门禁)
 *
 * èƒŒæ™¯ï¼šé‡‘额浮点累加在本项目反复引发线上问题,典型症状是
 * ã€Œåˆè®¡å¯¹ä¸ä¸Šã€ã€Œå‡ºçް -0.00」「金额带一长串小数」。根因是 JS çš„ Number
 * æ˜¯ IEEE-754 åŒç²¾åº¦æµ®ç‚¹ï¼Œå¯¹ 2 ä½å°æ•°é‡‘额做 + - * ä¼šå¼•入二进制舍入误差,
 * ä¸”误差会随明细条数累积(实测约 39% çš„多明细组合会出现尾差)。
 *
 * å› æ­¤çº¦å®šï¼šé‡‘额运算一律使用 @/utils/money(内部基于 decimal.js,十进制精确运算)。
 *
 * æœ¬è„šæœ¬æ‰«æ src ä¸‹çš„ .js / .vue,找出「疑似对金额做浮点累加」的写法并报错退出,
 * ä»¥ä¾¿åœ¨æäº¤å‰æ‹¦ä½å›žå½’。建议挂到 pre-commit æˆ– CI。
 *
 * ç”¨æ³•:
 *   node build/checkMoney.js
 * æˆ– npm run check:money
 *
 * è‹¥ç¡®è®¤æŸå¤„是误报(例如累加的不是金额,而是数量、天数等),
 * åœ¨è¯¥è¡Œä¸Šæ–¹åŠ æ³¨é‡Šï¼š// money-check-ignore
 */
const fs = require("fs");
const path = require("path");
const SRC_DIR = path.resolve(__dirname, "../src");
const IGNORE_COMMENT = "money-check-ignore";
// å±é™©å†™æ³•:对 parseFloat ç»“果做累加,或以 parseFloat ç›¸ä¹˜åŽå‚与累加
const RULES = [
  {
    id: "float-accumulate",
    // å½¢å¦‚ totalFee += parseFloat(...)
    pattern: /\+=\s*parseFloat\s*\(/,
    message: "对 parseFloat ç»“果做累加,金额会累积浮点误差"
  },
  {
    id: "float-subtract-assign",
    // å½¢å¦‚ totalFee -= parseFloat(...)
    pattern: /-=\s*parseFloat\s*\(/,
    message: "对 parseFloat ç»“果做减法累加,金额会累积浮点误差"
  },
  {
    id: "float-text-math",
    // å½¢å¦‚ a = (parseFloat(x) - parseFloat(y)).toFixed(2)
    pattern: /=\s*\(?\s*parseFloat\s*\([^)]*\)\s*[-+*]\s*parseFloat\s*\(/,
    message: "parseFloat ä¹‹é—´ç›´æŽ¥åšç®—术运算再格式化,结果可能带浮点尾差"
  }
];
// æŽ’除第三方库与构建产物,仅检查业务源码
const EXCLUDE_DIRS = [
  path.join(SRC_DIR, "echarts"), // echarts ç¬¬ä¸‰æ–¹åº“源码
  path.join(SRC_DIR, "assets")
];
// å…è®¸çš„写法:这些是对单个值的合法性/零值校验,不构成累加,不会放大误差
const ALLOW = [/parseFloat\([^)]*\)\s*==\s*0/, /parseFloat\([^)]*\)\s*!=\s*0/];
function walk(dir, out) {
  for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
    const full = path.join(dir, entry.name);
    if (entry.isDirectory()) {
      if (entry.name === "node_modules") continue;
      if (EXCLUDE_DIRS.indexOf(full) >= 0) continue;
      walk(full, out);
    } else if (/\.(js|vue)$/.test(entry.name)) {
      out.push(full);
    }
  }
  return out;
}
function checkFile(file) {
  const lines = fs.readFileSync(file, "utf8").split(/\r?\n/);
  const hits = [];
  let inBlockComment = false;
  lines.forEach((line, idx) => {
    const code = line.trim();
    // è·Ÿè¸ªè·¨è¡Œå—注释:块注释中的代码不参与检查(避免对已注释掉的代码误报)
    if (inBlockComment) {
      if (code.indexOf("*/") >= 0) inBlockComment = false;
      return;
    }
    if (code.indexOf("/*") === 0) {
      if (code.indexOf("*/") < 0) inBlockComment = true;
      return;
    }
    // è¡Œæ³¨é‡Š
    if (code.indexOf("//") === 0 || code.indexOf("*") === 0) return;
    // å…è®¸çš„写法:单个值的合法性/零值校验
    if (ALLOW.some((re) => re.test(line))) return;
    // æ˜¾å¼è¯¯æŠ¥æ ‡è®°
    const prev = idx > 0 ? lines[idx - 1] : "";
    if (prev.indexOf(IGNORE_COMMENT) >= 0) return;
    RULES.forEach((rule) => {
      if (rule.pattern.test(line)) {
        hits.push({ line: idx + 1, id: rule.id, message: rule.message, code: code.slice(0, 120) });
      }
    });
  });
  return hits;
}
function main() {
  if (!fs.existsSync(SRC_DIR)) {
    console.error(`找不到源码目录:${SRC_DIR}`);
    process.exit(1);
  }
  const files = walk(SRC_DIR, []);
  let total = 0;
  const report = [];
  files.forEach((file) => {
    const hits = checkFile(file);
    if (hits.length) {
      total += hits.length;
      report.push({ file: path.relative(path.resolve(__dirname, ".."), file), hits });
    }
  });
  if (total === 0) {
    console.log(`金额精度检查通过(已扫描 ${files.length} ä¸ªæ–‡ä»¶ï¼‰`);
    process.exit(0);
  }
  console.error("金额精度检查未通过:发现疑似金额浮点累加\n");
  report.forEach(({ file, hits }) => {
    console.error(`  ${file}`);
    hits.forEach((h) => {
      console.error(`    L${h.line}  [${h.id}] ${h.message}`);
      console.error(`           ${h.code}`);
    });
    console.error("");
  });
  console.error("请改用 @/utils/money æä¾›çš„æ–¹æ³•,例如:");
  console.error('  import { moneySum, moneyAdd, moneyMul, moneyRound } from "@/utils/money";');
  console.error("  const total = moneyRound(moneySum(list, \"amount\"));");
  console.error("  é‡‘额相等比较用 moneyEq(),不要用 parseFloat(...) == æˆ– ===。");
  console.error("  ç¡®å±žè¯¯æŠ¥æ—¶ï¼Œåœ¨è¯¥è¡Œä¸Šæ–¹åŠ æ³¨é‡Š // money-check-ignore");
  process.exit(1);
}
main();
dist.rar
Binary files differ
package.json
@@ -9,7 +9,8 @@
    "build": "vue-cli-service build",
    "build:stage": "vue-cli-service build --mode staging",
    "preview": "node build/index.js --preview",
    "lint": "eslint --ext .js,.vue src"
    "lint": "eslint --ext .js,.vue src",
    "check:money": "node build/checkMoney.js"
  },
  "husky": {
    "hooks": {
src/utils/money.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,240 @@
/**
 * é‡‘额计算工具
 *
 * èƒŒæ™¯ï¼šæœ¬ç³»ç»Ÿé‡‘额一律以「元」为单位、保留 2 ä½å°æ•°ï¼Œå±žè´¢åŠ¡æ•°æ®ã€‚
 * JS çš„ Number æ˜¯ IEEE-754 åŒç²¾åº¦æµ®ç‚¹ï¼Œç›´æŽ¥åšåŠ å‡ä¹˜ä¼šå¼•å…¥äºŒè¿›åˆ¶èˆå…¥è¯¯å·®ï¼Œ
 * å…¸åž‹è¡¨çŽ°ï¼š
 *   0.1 + 0.2        -> 0.30000000000000004
 *   1.1 * 3          -> 3.3000000000000003
 *   0.3 - 0.2 - 0.1  -> -2.7755575615628914e-17   ï¼ˆé€€è´¹/扣税相减后残留尾差)
 * è¿™ç±»å°¾å·®å¯¼è‡´ã€Œåˆè®¡å¯¹ä¸ä¸Šã€ã€Œé‡‘额显示为 -0」「相等判断失败」等线上问题,
 * ä¸”会随单据流转被写入数据库,事后难以追溯。
 *
 * å› æ­¤ï¼šæ‰€æœ‰é‡‘额运算统一走本模块,禁止直接对金额使用 + - * / ä¸Ž parseFloat ç´¯åŠ ã€‚
 * å†…部基于 decimal.js(package.json å·²å¼•入),保证十进制精确运算。
 *
 * ç”¨æ³•示例:
 *   import { moneySum, moneyMul, moneySub, moneyRound, moneyEq } from "@/utils/money";
 *
 *   // ç´¯åŠ æ˜Žç»†ï¼ˆè¿‡æ»¤éžæ•°å­—ä¸Žç©ºå€¼ï¼Œä¸ä¼šæŠŠ NaN ä¼ æŸ“给合计)
 *   const total = moneySum(this.rbDetails, "amount");
 *
 *   // å•ä»· Ã— æ•°é‡
 *   const preTax = moneyMul(row.price, row.quantity);
 *
 *   // ç¨Žå‰ - æ‰£ç¨Ž = ç¨ŽåŽ
 *   const afterTax = moneySub(row.amount, row.taxamount);
 *
 *   // è½åº“/展示前统一保留 2 ä½ï¼ˆå››èˆäº”入)
 *   this.form.amountrequested = moneyRound(total);
 *
 *   // é‡‘额比较(勿用 == / === æˆ– parseFloat åŽç›¸å‡ï¼‰
 *   if (!moneyEq(sumOfPayees, this.form.amountrequested)) { ... }
 */
import Decimal from 'decimal.js'
/** é‡‘额保留小数位 */
export const MONEY_SCALE = 2
/**
 * è½¬ä¸º Decimal;无法识别的值(空串/undefined/null/NaN/非数字)一律按 0 å¤„理。
 * æŒ‰ 0 å¤„理而非抛错,是为了保持既有页面「!isNaN(parseFloat(x)) æ‰ç´¯åŠ ã€çš„è¡Œä¸ºï¼Œ
 * åŒæ—¶é¿å… NaN æ±¡æŸ“整条合计链。
 *
 * @param {string|number|Decimal|null|undefined} value
 * @returns {Decimal}
 */
export function toMoney(value) {
  if (value === null || value === undefined || value === '') {
    return new Decimal(0)
  }
  if (value instanceof Decimal) {
    return value
  }
  let d
  try {
    d = new Decimal(value)
  } catch (e) {
    return new Decimal(0)
  }
  return d.isFinite() ? d : new Decimal(0)
}
/**
 * åˆ¤æ–­æ˜¯å¦ä¸ºæœ‰æ•ˆé‡‘额(可参与计算)。用于原本 !isNaN(parseFloat(x)) çš„æ ¡éªŒåœºæ™¯ã€‚
 *
 * @param {*} value
 * @returns {boolean}
 */
export function isValidMoney(value) {
  if (value === null || value === undefined || value === '') {
    return false
  }
  if (value instanceof Decimal) {
    return value.isFinite()
  }
  if (typeof value === 'number') {
    return Number.isFinite(value)
  }
  const s = String(value).trim()
  if (s === '') {
    return false
  }
  try {
    return new Decimal(s).isFinite()
  } catch (e) {
    return false
  }
}
/**
 * ç´¯åŠ æ±‚å’Œã€‚
 *
 * @param {Array} list å¾…累加的数组
 * @param {string|Function} [selector] å–金额的方式:
 *        å­—符串 -> å–该项的该属性名,如 "amount";
 *        å‡½æ•°   -> ç”¨è¿”回值,如 (item) => item.detail && item.detail.amount;
 *        çœç•¥   -> ç›´æŽ¥ç´¯åŠ æ•°ç»„å…ƒç´ æœ¬èº«ã€‚
 * @returns {number} æ±‚和结果(Number,便于赋值给表单字段)
 */
export function moneySum(list, selector) {
  if (!Array.isArray(list) || list.length === 0) {
    return 0
  }
  let acc = new Decimal(0)
  for (let i = 0; i < list.length; i++) {
    const raw =
      selector === undefined
        ? list[i]
        : typeof selector === 'function'
          ? selector(list[i])
          : list[i][selector]
    acc = acc.plus(toMoney(raw))
  }
  return acc.toNumber()
}
/**
 * æ±‚和后保留 2 ä½å°æ•°ï¼ˆä¼˜å…ˆåœ¨å±•示/落库时使用)。
 */
export function moneySumRound(list, selector) {
  return roundNumber(moneySum(list, selector))
}
/**
 * ç²¾ç¡®åŠ æ³•ã€‚æ”¯æŒå¤šå‚æ•°æˆ–æ•°ç»„ï¼šmoneyAdd(1.1, 2.2) / moneyAdd([1.1, 2.2])
 */
export function moneyAdd(...args) {
  const list = args.length === 1 && Array.isArray(args[0]) ? args[0] : args
  let acc = new Decimal(0)
  list.forEach((v) => {
    acc = acc.plus(toMoney(v))
  })
  return acc.toNumber()
}
/**
 * ç²¾ç¡®å‡æ³• a - b(可传多个:a - b - c)
 */
export function moneySub(a, ...rest) {
  let acc = toMoney(a)
  rest.forEach((v) => {
    acc = acc.minus(toMoney(v))
  })
  return acc.toNumber()
}
/**
 * ç²¾ç¡®ä¹˜æ³•(单价 Ã— æ•°é‡ã€é‡‘额 Ã— ç¨ŽçŽ‡ï¼‰
 */
export function moneyMul(a, ...rest) {
  let acc = toMoney(a)
  rest.forEach((v) => {
    acc = acc.times(toMoney(v))
  })
  return acc.toNumber()
}
/**
 * ç²¾ç¡®é™¤æ³•(金额 Ã· æ•°é‡ï¼‰ï¼ŒdivideBy ä¸º 0 æ—¶è¿”回 0,不产生 Infinity
 */
export function moneyDiv(a, b) {
  const divisor = toMoney(b)
  if (divisor.isZero()) {
    return 0
  }
  return toMoney(a).div(divisor).toNumber()
}
/**
 * é‡‘额是否相等(十进制精确比较,不受浮点尾差影响)。
 * ä¼šè‡ªåŠ¨å½’ä¸€åŒ–åˆ° 2 ä½ï¼Œé¿å… 100 ä¸Ž 100.001 è¿™ç±»è¾¹ç•Œè¯¯åˆ¤ã€‚
 *
 * @returns {boolean}
 */
export function moneyEq(a, b) {
  return roundDecimal(a).eq(roundDecimal(b))
}
/**
 * é‡‘额大小比较:a > b è¿”回 1,a < b è¿”回 -1,相等返回 0
 */
export function moneyCmp(a, b) {
  return roundDecimal(a).cmp(roundDecimal(b))
}
/**
 * ä¿ç•™ 2 ä½å°æ•°å¹¶è¿”回 Number(四舍五入,ROUND_HALF_UP)。
 * ç”¨äºŽèµ‹å€¼ç»™è¡¨å•字段、参与后端交互。
 *
 * @param {*} value
 * @param {number} [scale=2]
 * @returns {number}
 */
export function moneyRound(value, scale = MONEY_SCALE) {
  return roundDecimal(value, scale).toNumber()
}
/**
 * ä¿ç•™ 2 ä½å°æ•°å¹¶è¿”回字符串(用于金额展示,避免大额时出现科学计数法)。
 *
 * @param {*} value
 * @param {number} [scale=2]
 * @returns {string}
 */
export function moneyText(value, scale = MONEY_SCALE) {
  return roundDecimal(value, scale).toFixed(scale)
}
/**
 * ä¿ç•™ 2 ä½å°æ•°å¹¶è¿”回 Decimal,供后续继续精确运算
 */
export function moneyDecimal(value, scale = MONEY_SCALE) {
  return roundDecimal(value, scale)
}
function roundDecimal(value, scale = MONEY_SCALE) {
  return toMoney(value).toDecimalPlaces(scale, Decimal.ROUND_HALF_UP)
}
// moneySum å†…部已返回 Number,这里统一走同一套四舍五入
function roundNumber(value) {
  return roundDecimal(value).toNumber()
}
export default {
  MONEY_SCALE,
  toMoney,
  isValidMoney,
  moneySum,
  moneySumRound,
  moneyAdd,
  moneySub,
  moneyMul,
  moneyDiv,
  moneyEq,
  moneyCmp,
  moneyRound,
  moneyText,
  moneyDecimal
}
src/views/home/components/BarChart/index.vue
@@ -37,8 +37,16 @@
  data() {
    return {
      options: {},
      // è‡ªåŠ¨è½®æ’­å®šæ—¶å™¨å¥æŸ„ï¼›ä¸æ¸…ç†ä¼šåœ¨ç»„ä»¶é”€æ¯åŽç»§ç»­è§¦å‘ï¼Œå¯¼è‡´å¯¹å·²é”€æ¯å®žä¾‹æ“ä½œ
      intervalId: null,
    };
  },
  beforeDestroy() {
    if (this.intervalId !== null) {
      clearInterval(this.intervalId);
      this.intervalId = null;
    }
  },
  components: {
    Echart,
  },
src/views/home/components/BarChart2/index.vue
@@ -37,8 +37,16 @@
  data() {
    return {
      options: {},
      // è‡ªåŠ¨è½®æ’­å®šæ—¶å™¨å¥æŸ„ï¼›ä¸æ¸…ç†ä¼šåœ¨ç»„ä»¶é”€æ¯åŽç»§ç»­è§¦å‘ï¼Œå¯¼è‡´å¯¹å·²é”€æ¯å®žä¾‹æ“ä½œ
      intervalId: null,
    };
  },
  beforeDestroy() {
    if (this.intervalId !== null) {
      clearInterval(this.intervalId);
      this.intervalId = null;
    }
  },
  components: {
    Echart,
  },
src/views/home/components/BarChart3/index.vue
@@ -37,8 +37,16 @@
  data() {
    return {
      options: {},
      // è‡ªåŠ¨è½®æ’­å®šæ—¶å™¨å¥æŸ„ï¼›ä¸æ¸…ç†ä¼šåœ¨ç»„ä»¶é”€æ¯åŽç»§ç»­è§¦å‘ï¼Œå¯¼è‡´å¯¹å·²é”€æ¯å®žä¾‹æ“ä½œ
      intervalId: null,
    };
  },
  beforeDestroy() {
    if (this.intervalId !== null) {
      clearInterval(this.intervalId);
      this.intervalId = null;
    }
  },
  components: {
    Echart,
  },
src/views/home/components/BarChartH/index.vue
@@ -41,8 +41,16 @@
  data() {
    return {
      options: {},
      // è‡ªåŠ¨è½®æ’­å®šæ—¶å™¨å¥æŸ„ï¼›ä¸æ¸…ç†ä¼šåœ¨ç»„ä»¶é”€æ¯åŽç»§ç»­è§¦å‘ï¼Œå¯¼è‡´å¯¹å·²é”€æ¯å®žä¾‹æ“ä½œ
      intervalId: null,
    };
  },
  beforeDestroy() {
    if (this.intervalId !== null) {
      clearInterval(this.intervalId);
      this.intervalId = null;
    }
  },
  components: {
    Echart,
  },
src/views/home/components/MapChart/index.vue
@@ -41,8 +41,16 @@
  data() {
    return {
      options: {},
      // è‡ªåŠ¨è½®æ’­å®šæ—¶å™¨å¥æŸ„ï¼›ä¸æ¸…ç†ä¼šåœ¨ç»„ä»¶é”€æ¯åŽç»§ç»­è§¦å‘ï¼Œå¯¼è‡´å¯¹å·²é”€æ¯å®žä¾‹æ“ä½œ
      intervalId: null,
    };
  },
  beforeDestroy() {
    if (this.intervalId !== null) {
      clearInterval(this.intervalId);
      this.intervalId = null;
    }
  },
  components: {
    Echart,
  },
src/views/home/components/line1Chart/index.vue
@@ -37,8 +37,16 @@
  data() {
    return {
      options: {},
      // è‡ªåŠ¨è½®æ’­å®šæ—¶å™¨å¥æŸ„ï¼›ä¸æ¸…ç†ä¼šåœ¨ç»„ä»¶é”€æ¯åŽç»§ç»­è§¦å‘ï¼Œå¯¼è‡´å¯¹å·²é”€æ¯å®žä¾‹æ“ä½œ
      intervalId: null,
    };
  },
  beforeDestroy() {
    if (this.intervalId !== null) {
      clearInterval(this.intervalId);
      this.intervalId = null;
    }
  },
  components: {
    Echart,
  },
src/views/home/components/line2Chart/index.vue
@@ -37,8 +37,16 @@
  data() {
    return {
      options: {},
      // è‡ªåŠ¨è½®æ’­å®šæ—¶å™¨å¥æŸ„ï¼›ä¸æ¸…ç†ä¼šåœ¨ç»„ä»¶é”€æ¯åŽç»§ç»­è§¦å‘ï¼Œå¯¼è‡´å¯¹å·²é”€æ¯å®žä¾‹æ“ä½œ
      intervalId: null,
    };
  },
  beforeDestroy() {
    if (this.intervalId !== null) {
      clearInterval(this.intervalId);
      this.intervalId = null;
    }
  },
  components: {
    Echart,
  },
src/views/home/components/lineChart/index.vue
@@ -36,9 +36,17 @@
  },
  data() {
    return {
      options: {}
      options: {},
      // è‡ªåŠ¨è½®æ’­å®šæ—¶å™¨å¥æŸ„ï¼›ä¸æ¸…ç†ä¼šåœ¨ç»„ä»¶é”€æ¯åŽç»§ç»­è§¦å‘ï¼Œå¯¼è‡´å¯¹å·²é”€æ¯å®žä¾‹æ“ä½œ
      intervalId: null
    };
  },
  beforeDestroy() {
    if (this.intervalId !== null) {
      clearInterval(this.intervalId);
      this.intervalId = null;
    }
  },
  components: {
    Echart
  },
src/views/project/donorcharge/donorchargedetail/index.vue
@@ -294,6 +294,7 @@
import Li_area_select from "@/components/Address";
import { getUserProfile } from "@/api/system/user";
import { getToken } from "@/utils/auth";
import { moneySum, moneyRound } from "@/utils/money";
import debounce from "lodash/debounce";
export default {
  components: {
@@ -667,27 +668,23 @@
    submitForm: debounce(function(data) {
      this.$refs["form"].validate(valid => {
        if (valid) {
          //校验、费用合计
          let ChargeSum = 0;
          let ChargeamountSum = 0;
          //校验、费用合计(金额一律走精确运算)
          let organname = "";
          try {
            for (let i = 0; i < this.donorchargeorgans.length; i++) {
              organname += this.donorchargeorgans[i].organname + ",";
              if (!isNaN(parseFloat(this.donorchargeorgans[i].organcharge))) {
                ChargeSum += parseFloat(this.donorchargeorgans[i].organcharge);
              }
              if (!isNaN(parseFloat(this.donorchargeorgans[i].amount))) {
                ChargeamountSum += parseFloat(this.donorchargeorgans[i].amount);
              }
            }
            this.form.donateorgan = organname.substring(
              0,
              organname.lastIndexOf(",")
            );
            this.form.chargeamount = ChargeSum.toFixed(2);
            this.form.chargeamounted = ChargeamountSum.toFixed(2);
            this.form.chargeamount = moneyRound(
              moneySum(this.donorchargeorgans, "organcharge")
            ).toFixed(2);
            this.form.chargeamounted = moneyRound(
              moneySum(this.donorchargeorgans, "amount")
            ).toFixed(2);
          } catch {}
          //保存
@@ -728,24 +725,16 @@
      });
    }, 500),
    //计算费用合计
    //计算费用合计(金额一律走精确运算)
    chargeSum() {
      let ChargeSum = 0;
      let ChargeamountSum = 0;
      //费用合计
      try {
        for (let i = 0; i < this.donorchargeorgans.length; i++) {
          if (!isNaN(parseFloat(this.donorchargeorgans[i].organcharge))) {
            ChargeSum += parseFloat(this.donorchargeorgans[i].organcharge);
          }
          if (!isNaN(parseFloat(this.donorchargeorgans[i].amount))) {
            ChargeamountSum += parseFloat(this.donorchargeorgans[i].amount);
          }
        }
        this.form.chargeamount = ChargeSum.toFixed(2);
        this.form.chargeamounted = ChargeamountSum.toFixed(2);
        this.form.chargeamount = moneyRound(
          moneySum(this.donorchargeorgans, "organcharge")
        ).toFixed(2);
        this.form.chargeamounted = moneyRound(
          moneySum(this.donorchargeorgans, "amount")
        ).toFixed(2);
      } catch {}
    },
src/views/project/fund/applyDetail/index.vue
@@ -786,6 +786,7 @@
import Li_area_select from "@/components/Address";
import OrgSelecter from "@/views/project/components/orgselect";
import { getToken } from "@/utils/auth";
import { moneySum, moneyMul, moneySub, moneyRound } from "@/utils/money";
import CustomImageViewer from "@/components/CustomImageViewer"; // æ ¹æ®ä½ çš„路径调整
export default {
@@ -1607,7 +1608,7 @@
              let tempDetail = this.rbDetails[j];
              if (
                isNaN(parseFloat(tempDetail.amount)) ||
                parseFloat(tempDetail.amount) == 0
                moneyRound(tempDetail.amount) == 0
              ) {
                this.$modal.msgWarning(
                  "服务项目表中,第" +
@@ -1622,7 +1623,7 @@
              let tempDetail = this.rbDetails[j];
              if (
                isNaN(parseFloat(tempDetail.amount)) ||
                parseFloat(tempDetail.amount) == 0
                moneyRound(tempDetail.amount) == 0
              ) {
                this.$modal.msgWarning(
                  "服务项目表中,第" +
@@ -1633,7 +1634,7 @@
              }
              if (
                isNaN(parseFloat(tempDetail.taxamount)) ||
                parseFloat(tempDetail.taxamount) == 0
                moneyRound(tempDetail.taxamount) == 0
              ) {
                tempDetail.taxedamount = parseFloat(tempDetail.amount);
              } else {
@@ -2105,14 +2106,13 @@
    //计算个税:type(A:已知税前金额,计算税后金额;B:已知税后金额,计算税前金额)
    calculateTax(row, type) {
      let targetValue = 0;
      for (let i = 0; i < this.rbDetails.length; i++) {
        if (!this.rbDetails[i].amount) {
          this.rbDetails[i].amount = 0;
        }
        targetValue += parseFloat(this.rbDetails[i].amount); // å‡è®¾æ¯ä¸ªå¯¹è±¡ä¸­çš„特定值存储在'specificValue'属性下
      }
      this.form.pretaxcost = targetValue;
      // åˆè®¡é‡‘额必须精确累加,否则会写入 form.pretaxcost å¹¶è½åº“
      this.form.pretaxcost = moneySum(this.rbDetails, "amount");
    },
    //导入所有项目
@@ -2274,7 +2274,7 @@
              let tempDetail = this.rbDetails[j];
              if (
                isNaN(parseFloat(tempDetail.amount)) ||
                parseFloat(tempDetail.amount) == 0
                moneyRound(tempDetail.amount) == 0
              ) {
                this.$modal.msgWarning(
                  "服务项目表中,第" +
@@ -2289,7 +2289,7 @@
              let tempDetail = this.rbDetails[j];
              if (
                isNaN(parseFloat(tempDetail.amount)) ||
                parseFloat(tempDetail.amount) == 0
                moneyRound(tempDetail.amount) == 0
              ) {
                this.$modal.msgWarning(
                  "服务项目表中,第" +
@@ -2300,7 +2300,7 @@
              }
              if (
                isNaN(parseFloat(tempDetail.taxamount)) ||
                parseFloat(tempDetail.taxamount) == 0
                moneyRound(tempDetail.taxamount) == 0
              ) {
                tempDetail.taxedamount = parseFloat(tempDetail.amount);
              } else {
@@ -2581,33 +2581,32 @@
        });
      //全部删除后添加一条新行
    },
    //计算总金额
    //计算总金额(金额一律走精确运算,禁止 parseFloat ç´¯åŠ ï¼‰
    sumTotalFee(row) {
      let allSum = 0;
      const detailsArr = [];
      if (this.form.applytype != null) {
        for (let i = 0; i < this.rbDetails.length; i++) {
          const detail = this.rbDetails[i];
          let totalFee = 0;
          let taxFee = 0;
          if (this.form.applytype == 1 || this.form.applytype == 2) {
            //计算当前报销内容费用合计
            if (!isNaN(parseFloat(this.rbDetails[i].amount))) {
              totalFee += parseFloat(this.rbDetails[i].amount);
              taxFee += parseFloat(this.rbDetails[i].amount);
            //计算当前报销内容费用合计:税前 - æ‰£ç¨Ž
            if (!isNaN(parseFloat(detail.amount))) {
              totalFee = moneySub(totalFee, -parseFloat(detail.amount));
              taxFee = moneySub(taxFee, -parseFloat(detail.amount));
            }
            if (!isNaN(parseFloat(this.rbDetails[i].taxamount))) {
              totalFee -= parseFloat(this.rbDetails[i].taxamount);
              taxFee -= parseFloat(this.rbDetails[i].taxamount);
            if (!isNaN(parseFloat(detail.taxamount))) {
              totalFee = moneySub(totalFee, detail.taxamount);
              taxFee = moneySub(taxFee, detail.taxamount);
            }
          } else if (this.form.applytype == 3 || this.form.applytype == 4) {
            //单价*数量=税前金额
            if (
              !isNaN(parseFloat(this.rbDetails[i].price)) &&
              !isNaN(parseFloat(this.rbDetails[i].quantity))
              !isNaN(parseFloat(detail.price)) &&
              !isNaN(parseFloat(detail.quantity))
            ) {
              totalFee +=
                parseFloat(this.rbDetails[i].price) *
                parseFloat(this.rbDetails[i].quantity);
              this.rbDetails[i].amount = totalFee;
              totalFee = moneyMul(detail.price, detail.quantity);
              detail.amount = totalFee;
            }
          }
@@ -2616,9 +2615,10 @@
          //   this.rbDetails[i].taxedamount = taxFee.toFixed(2);
          // }
          allSum += totalFee;
          detailsArr.push(totalFee);
        }
      }
      const allSum = moneyRound(moneySum(detailsArr));
      // this.form.amountrequested = allSum.toFixed(2);
      // this.$forceUpdate();
    },
@@ -3321,7 +3321,9 @@
  //生命周期 - æŒ‚载完成(可以访问DOM元素)
  mounted() {
    window.addEventListener("beforeunload", e => this.beforeunloadHandler(e));
    // å­˜ä½åŒä¸€ä¸ªå¼•用,否则 removeEventListener ä¼ æ–°ç®­å¤´å‡½æ•°æ— æ³•真正移除,会泄漏监听器
    this._beforeUnloadHandler = e => this.beforeunloadHandler(e);
    window.addEventListener("beforeunload", this._beforeUnloadHandler);
    this.getUserList();
    let apiaccountselectform = this.accountselectform;
    let apiform = this.form;
@@ -3337,7 +3339,10 @@
  updated() { }, //生命周期 - æ›´æ–°ä¹‹åŽ
  beforeDestroy() { }, //生命周期 - é”€æ¯ä¹‹å‰
  destroyed() {
    window.removeEventListener("beforeunload", e => this.beforeunloadFn(e));
    if (this._beforeUnloadHandler) {
      window.removeEventListener("beforeunload", this._beforeUnloadHandler);
      this._beforeUnloadHandler = null;
    }
  }, //生命周期 - é”€æ¯å®Œæˆ
  activated() { } //如果页面有keep-alive缓存功能,这个函数会触发
};
src/views/project/fund/applyDetail0/index.vue
@@ -1227,6 +1227,7 @@
import Li_area_select from "@/components/Address";
import OrgSelecter from "@/views/project/components/orgselect";
import { getToken } from "@/utils/auth";
import { moneySum, moneyAdd, moneySub, moneyMul, moneyRound } from "@/utils/money";
export default {
  //import引入的组件需要注入到对象中才能使用
@@ -2876,32 +2877,28 @@
      }
    },
    //计算总金额
    //计算总金额(金额一律走精确运算)
    sumTotalFee(row) {
      let allSum = 0;
      const detailsArr = [];
      if (this.form.applytype != null) {
        for (let i = 0; i < this.rbDetails.length; i++) {
          const detail = this.rbDetails[i];
          let totalFee = 0;
          let taxFee = 0;
          if (this.form.applytype == 1 || this.form.applytype == 2) {
            //计算当前报销内容费用合计
            if (!isNaN(parseFloat(this.rbDetails[i].amount))) {
              totalFee += parseFloat(this.rbDetails[i].amount);
              taxFee += parseFloat(this.rbDetails[i].amount);
            //计算当前报销内容费用合计:税前 - æ‰£ç¨Ž
            if (!isNaN(parseFloat(detail.amount))) {
              totalFee = moneyAdd(totalFee, detail.amount);
            }
            if (!isNaN(parseFloat(this.rbDetails[i].taxamount))) {
              totalFee -= parseFloat(this.rbDetails[i].taxamount);
              taxFee -= parseFloat(this.rbDetails[i].taxamount);
            if (!isNaN(parseFloat(detail.taxamount))) {
              totalFee = moneySub(totalFee, detail.taxamount);
            }
          } else if (this.form.applytype == 3 || this.form.applytype == 4) {
            //单价*数量=税前金额
            if (
              !isNaN(parseFloat(this.rbDetails[i].price)) &&
              !isNaN(parseFloat(this.rbDetails[i].quantity))
              !isNaN(parseFloat(detail.price)) &&
              !isNaN(parseFloat(detail.quantity))
            ) {
              totalFee +=
                parseFloat(this.rbDetails[i].price) *
                parseFloat(this.rbDetails[i].quantity);
              totalFee = moneyMul(detail.price, detail.quantity);
              this.rbDetails[i].amount = totalFee;
            }
          }
@@ -2911,10 +2908,10 @@
          //   this.rbDetails[i].taxedamount = taxFee.toFixed(2);
          // }
          allSum += totalFee;
          detailsArr.push(totalFee);
        }
      }
      // this.form.amountrequested = allSum.toFixed(2);
      // this.form.amountrequested = moneyRound(moneySum(detailsArr)).toFixed(2);
      // this.$forceUpdate();
    },
@@ -3279,13 +3276,13 @@
  //生命周期 - æŒ‚载完成(可以访问DOM元素)
  mounted() {
    window.addEventListener("beforeunload", e => this.beforeunloadHandler(e));
    // å­˜ä½åŒä¸€ä¸ªå¼•用,否则 removeEventListener ä¼ æ–°ç®­å¤´å‡½æ•°æ— æ³•真正移除,会泄漏监听器
    this._beforeUnloadHandler = e => this.beforeunloadHandler(e);
    window.addEventListener("beforeunload", this._beforeUnloadHandler);
    this.getUserList();
    this.getUserProfile();
    let apifunddetailForm = this.funddetailForm;
    let apiform = this.form;
    console.log(apiform);
    console.log(apifunddetailForm);
    // this.getFeeUnitList();
  },
@@ -3294,7 +3291,12 @@
  beforeMount() {}, //生命周期 - æŒ‚载之前
  beforeUpdate() {}, //生命周期 - æ›´æ–°ä¹‹å‰
  updated() {}, //生命周期 - æ›´æ–°ä¹‹åŽ
  beforeDestroy() {}, //生命周期 - é”€æ¯ä¹‹å‰
  beforeDestroy() {
    if (this._beforeUnloadHandler) {
      window.removeEventListener("beforeunload", this._beforeUnloadHandler);
      this._beforeUnloadHandler = null;
    }
  }, //生命周期 - é”€æ¯ä¹‹å‰
  destroyed() {}, //生命周期 - é”€æ¯å®Œæˆ
  activated() {} //如果页面有keep-alive缓存功能,这个函数会触发
};
src/views/project/fund/ethicalExpertFeeApply/index.vue
@@ -960,6 +960,7 @@
import { getUserProfile } from "@/api/system/user";
import { listFundflow } from "@/api/project/fundflow";
import { getToken } from "@/utils/auth";
import { moneySum, moneyAdd, moneySub, moneyMul, moneyRound } from "@/utils/money";
export default {
  //import引入的组件需要注入到对象中才能使用
@@ -1360,15 +1361,11 @@
            // } catch {
            //   tempDetail.unitname = tempDetail.unitno;
            // }
            if (!isNaN(parseFloat(tempDetail.amount))) {
              totalPreTaxAmount += parseFloat(tempDetail.amount);
              totalAmount += parseFloat(tempDetail.amount);
            }
            if (!isNaN(parseFloat(tempDetail.taxedamount))) {
              totalAfterTaxAmount += parseFloat(tempDetail.taxedamount);
              totalAmount += parseFloat(tempDetail.taxedamount);
            }
          }
          //金额一律走精确运算,禁止 parseFloat ç´¯åŠ 
          totalPreTaxAmount = moneySum(this.fundDetailArr, "amount");
          totalAfterTaxAmount = moneySum(this.fundDetailArr, "taxedamount");
          totalAmount = moneyAdd(totalPreTaxAmount, totalAfterTaxAmount);
          try {
            this.form.unitname = this.$refs.orgSelecter.getOptionByValue(
              this.form.unitno
@@ -1736,49 +1733,45 @@
        });
    },
    //计算总金额
    //计算总金额(金额一律走精确运算,禁止 parseFloat ç´¯åŠ ï¼‰
    sumTotalFee() {
      let allSum = 0;
      const detailsArr = [];
      let preTaxSum = 0;
      let taxedSum = 0;
      if (this.form.applytype != null) {
        for (let i = 0; i < this.fundDetailArr.length; i++) {
          const detail = this.fundDetailArr[i];
          let totalFee = 0;
          let taxFee = 0;
          if (this.form.applytype == 1 || this.form.applytype == 2) {
            //计算当前报销内容费用合计
            if (!isNaN(parseFloat(this.fundDetailArr[i].amount))) {
              totalFee += parseFloat(this.fundDetailArr[i].amount);
              taxFee += parseFloat(this.fundDetailArr[i].amount);
              preTaxSum += parseFloat(this.fundDetailArr[i].amount);
            //计算当前报销内容费用合计:税前 - æ‰£ç¨Ž
            if (!isNaN(parseFloat(detail.amount))) {
              totalFee = moneyAdd(totalFee, detail.amount);
              preTaxSum = moneyAdd(preTaxSum, detail.amount);
            }
            if (!isNaN(parseFloat(this.fundDetailArr[i].taxamount))) {
              totalFee -= parseFloat(this.fundDetailArr[i].taxamount);
              taxFee -= parseFloat(this.fundDetailArr[i].taxamount);
            if (!isNaN(parseFloat(detail.taxamount))) {
              totalFee = moneySub(totalFee, detail.taxamount);
            }
            //taxedamount
            if (!isNaN(parseFloat(this.fundDetailArr[i].taxedamount))) {
              taxedSum += parseFloat(this.fundDetailArr[i].taxedamount);
            if (!isNaN(parseFloat(detail.taxedamount))) {
              taxedSum = moneyAdd(taxedSum, detail.taxedamount);
            }
          } else if (this.form.applytype == 3) {
            if (
              !isNaN(parseFloat(this.fundDetailArr[i].price)) &&
              !isNaN(parseFloat(this.fundDetailArr[i].quantity))
              !isNaN(parseFloat(detail.price)) &&
              !isNaN(parseFloat(detail.quantity))
            ) {
              totalFee +=
                parseFloat(this.fundDetailArr[i].price) *
                parseFloat(this.fundDetailArr[i].quantity);
              totalFee = moneyMul(detail.price, detail.quantity);
            }
          }
          // if (!isNaN(parseFloat(taxFee))) {
          //   this.fundDetailArr[i].taxedamount = taxFee.toFixed(2);
          // }
          allSum += totalFee;
          detailsArr.push(totalFee);
        }
      }
      this.form.amountrequested = allSum.toFixed(2);
      this.form.pretaxcost = preTaxSum.toFixed(2);
      this.form.taxedcost = taxedSum.toFixed(2);
      this.form.amountrequested = moneyRound(moneySum(detailsArr)).toFixed(2);
      this.form.pretaxcost = moneyRound(preTaxSum).toFixed(2);
      this.form.taxedcost = moneyRound(taxedSum).toFixed(2);
      this.$forceUpdate();
    },
src/views/project/fund/expertFeeApply/index.vue
@@ -1159,6 +1159,7 @@
import OrgSelecter from "@/views/project/components/orgselect";
import elementIcons from "../../../components/icons/element-icons";
import { getToken } from "@/utils/auth";
import { moneySum, moneyAdd, moneySub, moneyMul, moneyRound } from "@/utils/money";
export default {
  //import引入的组件需要注入到对象中才能使用
@@ -2451,43 +2452,34 @@
    //计算个税
    calculateTax() {},
    //计算总金额
    //计算总金额(金额一律走精确运算)
    sumTotalFee(row) {
      let allSum = 0;
      const detailsArr = [];
      if (this.form.applytype != null) {
        for (let i = 0; i < this.fundDetails.length; i++) {
          const detail = this.fundDetails[i];
          let totalFee = 0;
          let taxFee = 0;
          if (this.form.applytype == 1 || this.form.applytype == 2) {
            //计算当前报销内容费用合计
            if (!isNaN(parseFloat(this.fundDetails[i].amount))) {
              totalFee += parseFloat(this.fundDetails[i].amount);
              taxFee += parseFloat(this.fundDetails[i].amount);
            //计算当前报销内容费用合计:税前 - æ‰£ç¨Ž
            if (!isNaN(parseFloat(detail.amount))) {
              totalFee = moneyAdd(totalFee, detail.amount);
            }
            if (!isNaN(parseFloat(this.fundDetails[i].taxamount))) {
              totalFee -= parseFloat(this.fundDetails[i].taxamount);
              taxFee -= parseFloat(this.fundDetails[i].taxamount);
            if (!isNaN(parseFloat(detail.taxamount))) {
              totalFee = moneySub(totalFee, detail.taxamount);
            }
          } else if (this.form.applytype == 3) {
            if (
              !isNaN(parseFloat(this.fundDetails[i].price)) &&
              !isNaN(parseFloat(this.fundDetails[i].quantity))
              !isNaN(parseFloat(detail.price)) &&
              !isNaN(parseFloat(detail.quantity))
            ) {
              totalFee +=
                parseFloat(this.fundDetails[i].price) *
                parseFloat(this.fundDetails[i].quantity);
              totalFee = moneyMul(detail.price, detail.quantity);
            }
          }
          //税前、税后需要独立录入
          // if (!isNaN(parseFloat(taxFee))) {
          //   this.fundDetails[i].taxedamount = taxFee.toFixed(2);
          // }
          allSum += totalFee;
          detailsArr.push(totalFee);
        }
      }
      // this.form.amountrequested = allSum.toFixed(2);
      // åˆè®¡ä»åœ¨ç¡®è®¤å£å¾„后启用;先保证计算本身是精确的
      // this.form.amountrequested = moneyRound(moneySum(detailsArr)).toFixed(2);
      // this.$forceUpdate();
    },
src/views/project/fund/medicalCostApply/index.vue
@@ -335,6 +335,7 @@
import { getUserProfile } from "@/api/system/user";
import { listFundflow } from "@/api/project/fundflow";
import { getToken } from "@/utils/auth";
import { moneySum, moneyAdd, moneySub, moneyMul, moneyRound } from "@/utils/money";
export default {
  //import引入的组件需要注入到对象中才能使用
@@ -1190,41 +1191,40 @@
        });
    },
    //计算总金额
    //计算总金额(金额一律走精确运算,禁止 parseFloat ç´¯åŠ ï¼‰
    sumTotalFee(row) {
      let allSum = 0;
      const detailsArr = [];
      if (this.form.applytype != null) {
        for (let i = 0; i < this.fundDetails.length; i++) {
          const detail = this.fundDetails[i];
          let totalFee = 0;
          let taxFee = 0;
          if (this.form.applytype == 1 || this.form.applytype == 2) {
            //计算当前报销内容费用合计
            if (!isNaN(parseFloat(this.fundDetails[i].amount))) {
              totalFee += parseFloat(this.fundDetails[i].amount);
              taxFee += parseFloat(this.fundDetails[i].amount);
            //计算当前报销内容费用合计:税前 - æ‰£ç¨Ž
            if (!isNaN(parseFloat(detail.amount))) {
              totalFee = moneyAdd(totalFee, detail.amount);
              taxFee = moneyAdd(taxFee, detail.amount);
            }
            if (!isNaN(parseFloat(this.fundDetails[i].taxamount))) {
              totalFee -= parseFloat(this.fundDetails[i].taxamount);
              taxFee -= parseFloat(this.fundDetails[i].taxamount);
            if (!isNaN(parseFloat(detail.taxamount))) {
              totalFee = moneySub(totalFee, detail.taxamount);
              taxFee = moneySub(taxFee, detail.taxamount);
            }
          } else if (this.form.applytype == 3) {
            if (
              !isNaN(parseFloat(this.fundDetails[i].price)) &&
              !isNaN(parseFloat(this.fundDetails[i].quantity))
              !isNaN(parseFloat(detail.price)) &&
              !isNaN(parseFloat(detail.quantity))
            ) {
              totalFee +=
                parseFloat(this.fundDetails[i].price) *
                parseFloat(this.fundDetails[i].quantity);
              totalFee = moneyMul(detail.price, detail.quantity);
            }
          }
          if (!isNaN(parseFloat(taxFee))) {
            this.fundDetails[i].taxedamount = taxFee.toFixed(2);
            this.fundDetails[i].taxedamount = moneyRound(taxFee).toFixed(2);
          }
          allSum += totalFee;
          detailsArr.push(totalFee);
        }
      }
      //this.form.amountrequested = allSum.toFixed(2);
      this.$set(this.form, "amountrequested", allSum.toFixed(2));
      this.$set(this.form, "amountrequested", moneyRound(moneySum(detailsArr)).toFixed(2));
      //this.$forceUpdate();
    },
src/views/project/fund/officeExpenseApply/index.vue
@@ -1709,41 +1709,40 @@
        });
    },
    //计算总金额
    //计算总金额(金额一律走精确运算,禁止 parseFloat ç´¯åŠ ï¼‰
    sumTotalFee(row) {
      let allSum = 0;
      const detailsArr = [];
      if (this.form.applytype != null) {
        for (let i = 0; i < this.fundDetails.length; i++) {
          const detail = this.fundDetails[i];
          let totalFee = 0;
          let taxFee = 0;
          if (this.form.applytype == 1 || this.form.applytype == 2) {
            //计算当前报销内容费用合计
            if (!isNaN(parseFloat(this.fundDetails[i].amount))) {
              totalFee += parseFloat(this.fundDetails[i].amount);
              taxFee += parseFloat(this.fundDetails[i].amount);
            //计算当前报销内容费用合计:税前 - æ‰£ç¨Ž
            if (!isNaN(parseFloat(detail.amount))) {
              totalFee = moneyAdd(totalFee, detail.amount);
              taxFee = moneyAdd(taxFee, detail.amount);
            }
            if (!isNaN(parseFloat(this.fundDetails[i].taxamount))) {
              totalFee -= parseFloat(this.fundDetails[i].taxamount);
              taxFee -= parseFloat(this.fundDetails[i].taxamount);
            if (!isNaN(parseFloat(detail.taxamount))) {
              totalFee = moneySub(totalFee, detail.taxamount);
              taxFee = moneySub(taxFee, detail.taxamount);
            }
          } else if (this.form.applytype == 3) {
            if (
              !isNaN(parseFloat(this.fundDetails[i].price)) &&
              !isNaN(parseFloat(this.fundDetails[i].quantity))
              !isNaN(parseFloat(detail.price)) &&
              !isNaN(parseFloat(detail.quantity))
            ) {
              totalFee +=
                parseFloat(this.fundDetails[i].price) *
                parseFloat(this.fundDetails[i].quantity);
              totalFee = moneyMul(detail.price, detail.quantity);
            }
          }
          if (!isNaN(parseFloat(taxFee))) {
            this.fundDetails[i].taxedamount = taxFee.toFixed(2);
            this.fundDetails[i].taxedamount = moneyRound(taxFee).toFixed(2);
          }
          allSum += totalFee;
          detailsArr.push(totalFee);
        }
      }
      //this.form.amountrequested = allSum.toFixed(2);
      this.$set(this.form, "amountrequested", allSum.toFixed(2));
      this.$set(this.form, "amountrequested", moneyRound(moneySum(detailsArr)).toFixed(2));
      //this.$forceUpdate();
    },
src/views/project/fund/performancedetails/index.vue
@@ -876,6 +876,7 @@
import Li_area_select from "@/components/Address";
import OrgSelecter from "@/views/project/components/orgselect";
import { getToken } from "@/utils/auth";
import { moneySum, moneyAdd, moneySub, moneyRound } from "@/utils/money";
import CustomImageViewer from "@/components/CustomImageViewer";
export default {
@@ -2065,9 +2066,8 @@
      }
    },
    //税前扣税算税后
    //税前扣税算税后(金额一律走精确运算)
    chargeSum(row, type) {
      let targetValue = 0;
      for (let i = 0; i < this.rbDetails.length; i++) {
        if (!this.rbDetails[i].amount) {
          this.rbDetails[i].amount = 0;
@@ -2075,17 +2075,16 @@
        if (!this.rbDetails[i].taxamount) {
          this.rbDetails[i].taxamount = 0;
        }
        this.rbDetails[i].taxedamount = (
          parseFloat(this.rbDetails[i].amount) -
          parseFloat(this.rbDetails[i].taxamount)
        //税前 - æ‰£ç¨Ž = ç¨ŽåŽï¼ˆæµ®ç‚¹ç›¸å‡ä¼šæ®‹ç•™æžå°å°¾å·®ï¼Œå¯¼è‡´å‡ºçް -0.00)
        this.rbDetails[i].taxedamount = moneySub(
          this.rbDetails[i].amount,
          this.rbDetails[i].taxamount
        ).toFixed(2);
        targetValue += parseFloat(this.rbDetails[i].amount); // å‡è®¾æ¯ä¸ªå¯¹è±¡ä¸­çš„特定值存储在'specificValue'属性下
        console.log(this.rbDetails[i].taxedamount, "合计");
      }
      console.log(targetValue, "合计");
      this.form.pretaxcost = targetValue;
      //合计必须精确累加,否则会写入 form.pretaxcost å¹¶è½åº“
      this.form.pretaxcost = moneySum(this.rbDetails, "amount");
    },
    //税后扣税算税前
    //税后扣税算税前(金额一律走精确运算)
    queenchargeSum(row, type) {
      for (let i = 0; i < this.rbDetails.length; i++) {
        if (!this.rbDetails[i].amount) {
@@ -2094,9 +2093,10 @@
        if (!this.rbDetails[i].taxamount) {
          this.rbDetails[i].taxamount = 0;
        }
        this.rbDetails[i].amount =
          parseFloat(this.rbDetails[i].taxamount) +
          parseFloat(this.rbDetails[i].taxedamount);
        //扣税 + ç¨ŽåŽ = ç¨Žå‰ï¼ˆå¿…须精确相加并归一化到 2 ä½ï¼Œå¦åˆ™ä¼šæ®‹ç•™é•¿å°æ•°ï¼‰
        this.rbDetails[i].amount = moneyRound(
          moneyAdd(this.rbDetails[i].taxamount, this.rbDetails[i].taxedamount)
        );
      }
    },
src/views/project/fundcheck/ethicalExpertFeeCheck/index.vue
@@ -437,6 +437,7 @@
// å¯¼å…¥æœ¬åœ°å­˜å‚¨çš„æ–¹æ³•
import { setItem, grtItem, removeItem } from "@/utils/storage.js";
import { moneySum, moneyAdd, moneySub, moneyMul, moneyRound } from "@/utils/money";
export default {
  components: {
@@ -1469,49 +1470,45 @@
      });
    },
    //计算总金额
    //计算总金额(金额一律走精确运算,禁止 parseFloat ç´¯åŠ ï¼‰
    sumTotalFee() {
      let allSum = 0;
      const detailsArr = [];
      let preTaxSum = 0;
      let taxedSum = 0;
      if (this.form.applytype != null) {
        for (let i = 0; i < this.fundDetailArr.length; i++) {
          const detail = this.fundDetailArr[i];
          let totalFee = 0;
          let taxFee = 0;
          if (this.form.applytype == 1 || this.form.applytype == 2) {
            //计算当前报销内容费用合计
            if (!isNaN(parseFloat(this.fundDetailArr[i].amount))) {
              totalFee += parseFloat(this.fundDetailArr[i].amount);
              taxFee += parseFloat(this.fundDetailArr[i].amount);
              preTaxSum += parseFloat(this.fundDetailArr[i].amount);
            //计算当前报销内容费用合计:税前 - æ‰£ç¨Ž
            if (!isNaN(parseFloat(detail.amount))) {
              totalFee = moneyAdd(totalFee, detail.amount);
              preTaxSum = moneyAdd(preTaxSum, detail.amount);
            }
            if (!isNaN(parseFloat(this.fundDetailArr[i].taxamount))) {
              totalFee -= parseFloat(this.fundDetailArr[i].taxamount);
              taxFee -= parseFloat(this.fundDetailArr[i].taxamount);
            if (!isNaN(parseFloat(detail.taxamount))) {
              totalFee = moneySub(totalFee, detail.taxamount);
            }
            //taxedamount
            if (!isNaN(parseFloat(this.fundDetailArr[i].taxedamount))) {
              taxedSum += parseFloat(this.fundDetailArr[i].taxedamount);
            if (!isNaN(parseFloat(detail.taxedamount))) {
              taxedSum = moneyAdd(taxedSum, detail.taxedamount);
            }
          } else if (this.form.applytype == 3) {
            if (
              !isNaN(parseFloat(this.fundDetailArr[i].price)) &&
              !isNaN(parseFloat(this.fundDetailArr[i].quantity))
              !isNaN(parseFloat(detail.price)) &&
              !isNaN(parseFloat(detail.quantity))
            ) {
              totalFee +=
                parseFloat(this.fundDetailArr[i].price) *
                parseFloat(this.fundDetailArr[i].quantity);
              totalFee = moneyMul(detail.price, detail.quantity);
            }
          }
          // if (!isNaN(parseFloat(taxFee))) {
          //   this.fundDetailArr[i].taxedamount = taxFee.toFixed(2);
          // }
          allSum += totalFee;
          detailsArr.push(totalFee);
        }
      }
      this.form.amountrequested = allSum.toFixed(2);
      this.form.pretaxcost = preTaxSum.toFixed(2);
      this.form.taxedcost = taxedSum.toFixed(2);
      this.form.amountrequested = moneyRound(moneySum(detailsArr)).toFixed(2);
      this.form.pretaxcost = moneyRound(preTaxSum).toFixed(2);
      this.form.taxedcost = moneyRound(taxedSum).toFixed(2);
      this.$forceUpdate();
      console.log(this.form);
    },
src/views/project/fundcheck/medicalCostCheck/index.vue
@@ -496,6 +496,7 @@
import { listDept } from "@/api/system/dept";
import { getToken } from "@/utils/auth";
import { setItem, grtItem, removeItem } from "@/utils/storage.js";
import { moneySum, moneyAdd, moneySub, moneyMul, moneyRound } from "@/utils/money";
export default {
  components: {
@@ -1443,41 +1444,40 @@
      // });
    },
    //计算总金额
    //计算总金额(金额一律走精确运算,禁止 parseFloat ç´¯åŠ ï¼‰
    sumTotalFee() {
      let allSum = 0;
      const detailsArr = [];
      if (this.form.applytype != null) {
        for (let i = 0; i < this.fundDetailArr.length; i++) {
          const detail = this.fundDetailArr[i];
          let totalFee = 0;
          let taxFee = 0;
          if (this.form.applytype == 1 || this.form.applytype == 2) {
            //计算当前报销内容费用合计
            if (!isNaN(parseFloat(this.fundDetailArr[i].amount))) {
              totalFee += parseFloat(this.fundDetailArr[i].amount);
              taxFee += parseFloat(this.fundDetailArr[i].amount);
            //计算当前报销内容费用合计:税前 - æ‰£ç¨Ž
            if (!isNaN(parseFloat(detail.amount))) {
              totalFee = moneyAdd(totalFee, detail.amount);
              taxFee = moneyAdd(taxFee, detail.amount);
            }
            if (!isNaN(parseFloat(this.fundDetailArr[i].taxamount))) {
              totalFee -= parseFloat(this.fundDetailArr[i].taxamount);
              taxFee -= parseFloat(this.fundDetailArr[i].taxamount);
            if (!isNaN(parseFloat(detail.taxamount))) {
              totalFee = moneySub(totalFee, detail.taxamount);
              taxFee = moneySub(taxFee, detail.taxamount);
            }
          } else if (this.form.applytype == 3) {
            if (
              !isNaN(parseFloat(this.fundDetailArr[i].price)) &&
              !isNaN(parseFloat(this.fundDetailArr[i].quantity))
              !isNaN(parseFloat(detail.price)) &&
              !isNaN(parseFloat(detail.quantity))
            ) {
              totalFee +=
                parseFloat(this.fundDetailArr[i].price) *
                parseFloat(this.fundDetailArr[i].quantity);
              totalFee = moneyMul(detail.price, detail.quantity);
            }
          }
          if (!isNaN(parseFloat(taxFee))) {
            this.fundDetailArr[i].taxedamount = taxFee.toFixed(2);
            this.fundDetailArr[i].taxedamount = moneyRound(taxFee).toFixed(2);
          }
          allSum += totalFee;
          detailsArr.push(totalFee);
        }
      }
      //this.form.amountrequested = allSum.toFixed(2);
      this.$set(this.form, "amountrequested", allSum.toFixed(2));
      this.$set(this.form, "amountrequested", moneyRound(moneySum(detailsArr)).toFixed(2));
      //this.$forceUpdate();
    },
src/views/project/fundcheck/officeExpenseCheck/index.vue
@@ -499,6 +499,7 @@
import { listDept } from "@/api/system/dept";
import { getToken } from "@/utils/auth";
import { setItem, grtItem, removeItem } from "@/utils/storage.js";
import { moneySum, moneyAdd, moneySub, moneyMul, moneyRound } from "@/utils/money";
export default {
  components: {
@@ -1448,41 +1449,40 @@
      // });
    },
    //计算总金额
    //计算总金额(金额一律走精确运算,禁止 parseFloat ç´¯åŠ ï¼‰
    sumTotalFee() {
      let allSum = 0;
      const detailsArr = [];
      if (this.form.applytype != null) {
        for (let i = 0; i < this.fundDetailArr.length; i++) {
          const detail = this.fundDetailArr[i];
          let totalFee = 0;
          let taxFee = 0;
          if (this.form.applytype == 1 || this.form.applytype == 2) {
            //计算当前报销内容费用合计
            if (!isNaN(parseFloat(this.fundDetailArr[i].amount))) {
              totalFee += parseFloat(this.fundDetailArr[i].amount);
              taxFee += parseFloat(this.fundDetailArr[i].amount);
            //计算当前报销内容费用合计:税前 - æ‰£ç¨Ž
            if (!isNaN(parseFloat(detail.amount))) {
              totalFee = moneyAdd(totalFee, detail.amount);
              taxFee = moneyAdd(taxFee, detail.amount);
            }
            if (!isNaN(parseFloat(this.fundDetailArr[i].taxamount))) {
              totalFee -= parseFloat(this.fundDetailArr[i].taxamount);
              taxFee -= parseFloat(this.fundDetailArr[i].taxamount);
            if (!isNaN(parseFloat(detail.taxamount))) {
              totalFee = moneySub(totalFee, detail.taxamount);
              taxFee = moneySub(taxFee, detail.taxamount);
            }
          } else if (this.form.applytype == 3) {
            if (
              !isNaN(parseFloat(this.fundDetailArr[i].price)) &&
              !isNaN(parseFloat(this.fundDetailArr[i].quantity))
              !isNaN(parseFloat(detail.price)) &&
              !isNaN(parseFloat(detail.quantity))
            ) {
              totalFee +=
                parseFloat(this.fundDetailArr[i].price) *
                parseFloat(this.fundDetailArr[i].quantity);
              totalFee = moneyMul(detail.price, detail.quantity);
            }
          }
          if (!isNaN(parseFloat(taxFee))) {
            this.fundDetailArr[i].taxedamount = taxFee.toFixed(2);
            this.fundDetailArr[i].taxedamount = moneyRound(taxFee).toFixed(2);
          }
          allSum += totalFee;
          detailsArr.push(totalFee);
        }
      }
      //this.form.amountrequested = allSum.toFixed(2);
      this.$set(this.form, "amountrequested", allSum.toFixed(2));
      this.$set(this.form, "amountrequested", moneyRound(moneySum(detailsArr)).toFixed(2));
      //this.$forceUpdate();
    },
src/views/project/tallage/computingBill/index.vue
@@ -570,6 +570,7 @@
import Li_area_select from "@/components/Address";
import { getUserProfile } from "@/api/system/user";
import { getToken } from "@/utils/auth";
import { moneySum, moneyRound } from "@/utils/money";
import {
  ExpertfeeListnb,
  getFundtax,
@@ -1110,23 +1111,16 @@
        this.$modal.msgError("注意实收金额不等于应收金额,请核对数据!");
      }
    },
    //修改实收或应收后触发
    //修改实收或应收后触发(金额一律走精确运算)
    chargeSum() {
      let ChargeSum = 0;
      let ChargeamountSum = 0;
      //费用合计
      try {
        for (let i = 0; i < this.donorchargeorgans.length; i++) {
          if (!isNaN(parseFloat(this.donorchargeorgans[i].organcharge))) {
            ChargeSum += parseFloat(this.donorchargeorgans[i].organcharge);
          }
          if (!isNaN(parseFloat(this.donorchargeorgans[i].amount))) {
            ChargeamountSum += parseFloat(this.donorchargeorgans[i].amount);
          }
        }
        this.form.receivableamount = ChargeSum.toFixed(2);
        this.form.receivedamount = ChargeamountSum.toFixed(2);
        this.form.receivableamount = moneyRound(
          moneySum(this.donorchargeorgans, "organcharge")
        ).toFixed(2);
        this.form.receivedamount = moneyRound(
          moneySum(this.donorchargeorgans, "amount")
        ).toFixed(2);
      } catch {}
    },
src/views/project/travelexpenseapply/edit.vue
@@ -340,6 +340,7 @@
} from "@/api/project/organization";
import { listDonatebaseinfo } from "@/api/project/donatebaseinfo";
import { getToken } from "@/utils/auth";
import { moneySum } from "@/utils/money";
export default {
    data() {
        return {
@@ -673,41 +674,25 @@
                    //几点取消的提示
                });
        },
        //计算费用合计
        //计算费用合计(金额一律走精确运算,禁止 parseFloat ç´¯åŠ ï¼‰
        sumTotalFee() {
            let allSum = 0;
            try {
                for (let i = 0; i < this.applicationDetailArr.length; i++) {
                    let totalFee = 0;
                    const row = this.applicationDetailArr[i];
                    //计算当前报销内容费用合计
                    if (!isNaN(parseFloat(this.applicationDetailArr[i].trafficexpense))) {
                        totalFee += parseFloat(this.applicationDetailArr[i].trafficexpense);
                    const totalFee = moneySum([
                        row.trafficexpense,
                        row.cityfee,
                        row.hotelexpense,
                        row.otherexpense,
                        row.foodexpenses,
                        row.foodallowance,
                        row.otherfeeamount
                    ]);
                    row.total = totalFee.toFixed(2);
                    this.$set(this.applicationDetailArr, i, row);
                    }
                    if (!isNaN(parseFloat(this.applicationDetailArr[i].cityfee))) {
                        totalFee += parseFloat(this.applicationDetailArr[i].cityfee);
                    }
                    if (!isNaN(parseFloat(this.applicationDetailArr[i].hotelexpense))) {
                        totalFee += parseFloat(this.applicationDetailArr[i].hotelexpense);
                    }
                    if (!isNaN(parseFloat(this.applicationDetailArr[i].otherexpense))) {
                        totalFee += parseFloat(this.applicationDetailArr[i].otherexpense);
                    }
                    if (!isNaN(parseFloat(this.applicationDetailArr[i].foodexpenses))) {
                        totalFee += parseFloat(this.applicationDetailArr[i].foodexpenses);
                    }
                    if (!isNaN(parseFloat(this.applicationDetailArr[i].foodallowance))) {
                        totalFee += parseFloat(this.applicationDetailArr[i].foodallowance);
                    }
                    if (!isNaN(parseFloat(this.applicationDetailArr[i].otherfeeamount))) {
                        totalFee += parseFloat(this.applicationDetailArr[i].otherfeeamount);
                    }
                    this.applicationDetailArr[i].total = parseFloat(totalFee).toFixed(2);
                    this.$set(this.applicationDetailArr, i, this.applicationDetailArr[i]);
                    if (!isNaN(parseFloat(this.applicationDetailArr[i].total))) {
                        allSum += parseFloat(this.applicationDetailArr[i].total);
                    }
                }
                this.form.amountrequested = allSum.toFixed(2);
                this.form.amountrequested = moneySum(this.applicationDetailArr, "total").toFixed(2);
                this.form.bigstrmoney = this.convertCurrency(this.form.amountrequested);
            } catch { }
        },
src/views/project/travelexpenseapply/index.vue
@@ -642,7 +642,7 @@
        </el-row>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button type="primary" @click="submitForm" v-if="dialogType == 'edit'">保 å­˜</el-button>
        <el-button type="primary" :loading="saveLoading" @click="submitForm" v-if="dialogType == 'edit'">保 å­˜</el-button>
        <el-button @click="cancel">取 æ¶ˆ</el-button>
      </div>
    </el-dialog>
@@ -687,6 +687,7 @@
import { addorupdateFund } from "@/api/project/fund";
import { listReportname, listUser } from "@/api/project/organization";
import { getToken } from "@/utils/auth";
import { moneySum, moneyAdd } from "@/utils/money";
export default {
  components: {
    Treeselect,
@@ -738,6 +739,8 @@
      loading: true,
      // å¯¼å‡ºé®ç½©å±‚
      exportLoading: false,
      // ä¿å­˜æŒ‰é’® loading,防止重复提交
      saveLoading: false,
      // é€‰ä¸­æ•°ç»„
      ids: [],
      // éžå•个禁用
@@ -1335,7 +1338,8 @@
      //获取报销主信息
      const id = row.id || this.ids;
      getReimbursement(id).then(response => {
      getReimbursement(id)
        .then(async response => {
        this.form = response.data;
        this.fileList = this.form.annexfiles
          ? this.form.annexfiles
@@ -1344,10 +1348,16 @@
          : [];
        this.form.recordstatus = response.data.recordstatus + "";
        let ids = response.data.id;
        //获取报销明细信息
        getReimbursementdetaillist(ids).then(res => {
          this.rbDetails = res.data;
          const ids = response.data.id;
          this.queryParamsPayee.rbid = ids;
          //明细与打款信息互不依赖,并发获取,减少等待时间
          const [detailRes, payeeRes] = await Promise.all([
            getReimbursementdetaillist(ids),
            listReimbursementpayee(this.queryParamsPayee)
          ]);
          this.rbDetails = detailRes.data;
          if (this.rbDetails.length == 0) {
            this.addDetailRow(0);
          }
@@ -1366,16 +1376,14 @@
          //实时合计金额
          //this.sumTotalFee();
        });
        //获取报销打款信息
        this.queryParamsPayee.rbid = ids;
        listReimbursementpayee(this.queryParamsPayee).then(res => {
          this.rbPayees = res.rows;
          this.rbPayees = payeeRes.rows;
          if (this.rbPayees.length == 0) {
            this.addPayeeRow(0);
          }
        });
        })
        .catch(() => {
          this.$modal.msgError("报销单信息加载失败,请重试!");
      });
    },
@@ -1393,7 +1401,8 @@
      this.open = true;
      const id = row.id || this.ids;
      getReimbursement(id).then(response => {
      getReimbursement(id)
        .then(async response => {
        this.form = response.data;
        //附件
        this.fileList = this.form.annexfiles
@@ -1405,47 +1414,43 @@
        //审核状态
        this.form.recordstatus = response.data.recordstatus + "";
        let ids = response.data.id;
        let listFundflowparams = {
          const ids = response.data.id;
          const listFundflowparams = {
          fundid: row.id,
          fundtype: 1
        };
        listFundflow(listFundflowparams).then(res => {
          this.fundflowList = res.rows;
        });
          this.queryParamsPayee.rbid = ids;
        //报销明细
        getReimbursementdetaillist(ids).then(res => {
          this.rbDetails = res.data;
          /*
          for (let i = 0; i < this.rbDetails.length; i++) {
            this.rbDetails[i].index = i;
            this.rbDetails[i].searchAddress = {
              sheng: this.rbDetails[i].travelprovincename,
              shi: this.rbDetails[i].travelcityname,
              qu: this.rbDetails[i].traveltownname,
            };
          }
          */
        });
          //资金流水、报销明细、打款信息互不依赖,并发获取
          const [fundflowRes, detailRes, payeeRes] = await Promise.all([
            listFundflow(listFundflowparams),
            getReimbursementdetaillist(ids),
            listReimbursementpayee(this.queryParamsPayee)
          ]);
          this.fundflowList = fundflowRes.rows;
          this.rbDetails = detailRes.data;
          //明细加载完成后再计算合计,修复原代码在明细返回前就 sumTotalFee çš„竞态问题
        if (this.rbDetails.length > 0) this.sumTotalFee();
        //付款信息
        this.queryParamsPayee.rbid = ids;
        listReimbursementpayee(this.queryParamsPayee).then(res => {
          this.rbPayees = res.rows;
          this.rbPayees = payeeRes.rows;
          if (this.rbPayees.length == 0) {
            this.addPayeeRow(0);
          }
        });
        })
        .catch(() => {
          this.$modal.msgError("报销单信息加载失败,请重试!");
      });
    },
    /** æäº¤æŒ‰é’® */
    submitForm() {
      this.$refs["form"].validate(valid => {
        if (valid) {
      //防止重复提交:保存中直接忽略再次点击
      if (this.saveLoading) return;
      this.$refs["form"].validate(async valid => {
        if (!valid) return;
          /**
           let indexErrTime = this.rbDetails.findIndex((item) => {
             if (item.endtime && item.starttime) {
@@ -1502,6 +1507,8 @@
          }
          */
          try {
          this.saveLoading = true;
          //附件文件处理
          let list = this.fileList;
          if (list.length > 0) {
@@ -1527,71 +1534,75 @@
          const rbDetails = [...this.rbDetails];
          const rbPayees = [...this.rbPayees];
          if (this.form.id != null) {
            updateReimbursement(this.form)
              .then(res => {
                //保存明细
                for (let i = 0; i < rbDetails.length; i++) {
                  if (rbDetails[i].rbid != null) {
                    updateReimbursementdetail(rbDetails[i]);
                  } else {
                    //rbid关联主表Id
                    rbDetails[i].rbid = this.form.id;
                    addReimbursementdetail(rbDetails[i]);
                  }
                }
            //第1步:更新主表,成功后再处理子表
            await updateReimbursement(this.form);
                //保存账户
                for (let i = 0; i < rbPayees.length; i++) {
                  if (rbPayees[i].rbid != null) {
                    updateReimbursementpayee(rbPayees[i]);
                  } else {
            //第2步:并发保存明细,等待全部完成,任一失败则走 catch æç¤º
            await Promise.all(
              rbDetails.map(detail => {
                if (detail.rbid != null) {
                  return updateReimbursementdetail(detail);
                }
                    //rbid关联主表Id
                    rbPayees[i].rbid = this.form.id;
                    addReimbursementpayee(rbPayees[i]);
                detail.rbid = this.form.id;
                return addReimbursementdetail(detail);
              })
            );
            //第3步:并发保存账户
            await Promise.all(
              rbPayees.map(payee => {
                if (payee.rbid != null) {
                  return updateReimbursementpayee(payee);
                  }
                }
                //rbid关联主表Id
                payee.rbid = this.form.id;
                return addReimbursementpayee(payee);
              })
            );
                this.$modal.msgSuccess("修改报销单保存成功!");
                this.open = false;
                this.getList();
              })
              .catch(err => {
                this.$modal.msgError("修改报销单保存失败!");
              });
          } else {
            this.form.recordstatus = -1;
            addReimbursement(this.form)
              .then(response => {
                //保存明细
                for (let i = 0; i < rbDetails.length; i++) {
                  //rbid关联主表Id
                  rbDetails[i].rbid = response.data;
                  addReimbursementdetail(rbDetails[i]);
                }
            //第1步:新增主表,返回主表Id
            const response = await addReimbursement(this.form);
                //保存账号
                for (let i = 0; i < rbPayees.length; i++) {
            //第2步:并发保存明细
            await Promise.all(
              rbDetails.map(detail => {
                  //rbid关联主表Id
                  rbPayees[i].rbid = response.data;
                  addReimbursementpayee(rbPayees[i]);
                }
                detail.rbid = response.data;
                return addReimbursementdetail(detail);
              })
            );
            //第3步:并发保存账号
            await Promise.all(
              rbPayees.map(payee => {
                //rbid关联主表Id
                payee.rbid = response.data;
                return addReimbursementpayee(payee);
              })
            );
                this.$modal.msgSuccess("新增报销单保存成功!");
          }
          //所有保存步骤全部成功后才关闭弹窗并刷新列表
                this.open = false;
                this.getList();
              })
              .catch(err => {
                this.$modal.msgError("新增报销单保存失败!");
              });
          } catch (err) {
            this.$modal.msgError("报销单保存失败,请重试!");
          } finally {
            this.saveLoading = false;
          }
        }
      });
      );
    },
    /** åˆ é™¤æŒ‰é’®æ“ä½œ */
    handleDelete(row) {
      const ids = row.id || this.ids;
      console.log(ids);
      this.$modal
        .confirm("是否确认删除该条记录?")
        .then(function () {
@@ -1599,7 +1610,10 @@
          return delReimbursement(ids);
        })
        .then(() => {
          delReimbursementdetail(ids);
          //等待明细删除完成后再刷新列表,避免列表刷新时明细尚未删除
          return delReimbursementdetail(ids);
        })
        .then(() => {
          this.getList();
          this.$modal.msgSuccess("删除成功");
        })
@@ -1619,7 +1633,10 @@
          this.$download.name(response.msg);
          this.exportLoading = false;
        })
        .catch(() => { });
        .catch(() => {
          //失败时也要复位 loading,否则按钮永久转圈
          this.exportLoading = false;
        });
    },
    //新增一行
@@ -1800,107 +1817,30 @@
    },
    //计算一行合计
    //计算当前行报销内容费用合计
    //计算当前行报销内容费用合计(金额一律走精确运算)
    sumRowFee(row) {
      let totalFee = 0;
      if (!isNaN(parseFloat(row.trafficexpense))) {
        totalFee += parseFloat(row.trafficexpense);
      }
      if (!isNaN(parseFloat(row.cityfee))) {
        totalFee += parseFloat(row.cityfee);
      }
      if (!isNaN(parseFloat(row.hotelexpense))) {
        totalFee += parseFloat(row.hotelexpense);
      }
      if (!isNaN(parseFloat(row.otherexpense))) {
        totalFee += parseFloat(row.otherexpense);
      }
      if (!isNaN(parseFloat(row.foodexpenses))) {
        totalFee += parseFloat(row.foodexpenses);
      }
      if (!isNaN(parseFloat(row.foodallowance))) {
        totalFee += parseFloat(row.foodallowance);
      }
      if (!isNaN(parseFloat(row.otherfeeamount))) {
        totalFee += parseFloat(row.otherfeeamount);
      }
      row.total = totalFee;
      row.total = moneySum([
        row.trafficexpense,
        row.cityfee,
        row.hotelexpense,
        row.otherexpense,
        row.foodexpenses,
        row.foodallowance,
        row.otherfeeamount
      ]);
      /*
      if (!isNaN(parseFloat(this.rbDetails[rowIndex].trafficexpense))) {
        totalFee += parseFloat(this.rbDetails[rowIndex].trafficexpense);
      }
      if (!isNaN(parseFloat(this.rbDetails[rowIndex].cityfee))) {
        totalFee += parseFloat(this.rbDetails[rowIndex].cityfee);
      }
      if (!isNaN(parseFloat(this.rbDetails[rowIndex].hotelexpense))) {
        totalFee += parseFloat(this.rbDetails[rowIndex].hotelexpense);
      }
      if (!isNaN(parseFloat(this.rbDetails[rowIndex].otherexpense))) {
        totalFee += parseFloat(this.rbDetails[rowIndex].otherexpense);
      }
      if (!isNaN(parseFloat(this.rbDetails[rowIndex].foodexpenses))) {
        totalFee += parseFloat(this.rbDetails[rowIndex].foodexpenses);
      }
      if (!isNaN(parseFloat(this.rbDetails[rowIndex].foodallowance))) {
        totalFee += parseFloat(this.rbDetails[rowIndex].foodallowance);
      }
      if (!isNaN(parseFloat(this.rbDetails[rowIndex].otherfeeamount))) {
        totalFee += parseFloat(this.rbDetails[rowIndex].otherfeeamount);
      }
      this.rbDetails[rowIndex].total = parseFloat(totalFee).toFixed(2);
      this.$set(this.rbDetails, rowIndex, this.rbDetails[rowIndex]);
      */
      //重新计算整个报销单的合计
      this.sumTotalFee();
    },
    //计算费用合计
    sumTotalFee() {
      let allSum = 0;
      //捐献者家属费用
      if (!isNaN(parseFloat(this.form.donoramount))) {
        allSum += parseFloat(this.form.donoramount);
      }
      //报销明细费用
      try {
        for (let i = 0; i < this.rbDetails.length; i++) {
          /*
          let totalFee = 0;
          //计算当前报销内容费用合计
          if (!isNaN(parseFloat(this.rbDetails[i].total))) {
            totalFee += parseFloat(this.rbDetails[i].total);
          }
          if (!isNaN(parseFloat(this.rbDetails[i].cityfee))) {
            totalFee += parseFloat(this.rbDetails[i].cityfee);
          }
          if (!isNaN(parseFloat(this.rbDetails[i].hotelexpense))) {
            totalFee += parseFloat(this.rbDetails[i].hotelexpense);
          }
          if (!isNaN(parseFloat(this.rbDetails[i].otherexpense))) {
            totalFee += parseFloat(this.rbDetails[i].otherexpense);
          }
          if (!isNaN(parseFloat(this.rbDetails[i].foodexpenses))) {
            totalFee += parseFloat(this.rbDetails[i].foodexpenses);
          }
          if (!isNaN(parseFloat(this.rbDetails[i].foodallowance))) {
            totalFee += parseFloat(this.rbDetails[i].foodallowance);
          }
          if (!isNaN(parseFloat(this.rbDetails[i].otherfeeamount))) {
            totalFee += parseFloat(this.rbDetails[i].otherfeeamount);
          }
          this.rbDetails[i].total = parseFloat(totalFee).toFixed(2);
          this.$set(this.rbDetails, i, this.rbDetails[i]);
          */
          if (!isNaN(parseFloat(this.rbDetails[i].total))) {
            allSum += parseFloat(this.rbDetails[i].total);
          }
        }
        this.form.amountrequested = allSum.toFixed(2);
        this.form.amountrequested = moneyAdd(
          moneySum(this.rbDetails, "total"),
          this.form.donoramount
        ).toFixed(2);
        this.form.bigstrmoney = this.convertCurrency(this.form.amountrequested);
      } catch { }
    },
src/views/project/travelexpenseapply/travelexpensedetail/index.vue
@@ -1305,6 +1305,7 @@
import { listReportname, listUser } from "@/api/project/organization";
import { getToken } from "@/utils/auth";
import debounce from "lodash/debounce";
import { moneySum, moneyAdd, moneyRound } from "@/utils/money";
export default {
  components: {
    Treeselect,
@@ -3251,107 +3252,31 @@
    },
    //计算一行合计
    //计算当前行报销内容费用合计
    //计算当前行报销内容费用合计(金额一律走精确运算)
    sumRowFee(row) {
      let totalFee = 0;
      if (!isNaN(parseFloat(row.trafficexpense))) {
        totalFee += parseFloat(row.trafficexpense);
      }
      if (!isNaN(parseFloat(row.cityfee))) {
        totalFee += parseFloat(row.cityfee);
      }
      if (!isNaN(parseFloat(row.hotelexpense))) {
        totalFee += parseFloat(row.hotelexpense);
      }
      if (!isNaN(parseFloat(row.otherexpense))) {
        totalFee += parseFloat(row.otherexpense);
      }
      if (!isNaN(parseFloat(row.foodexpenses))) {
        totalFee += parseFloat(row.foodexpenses);
      }
      if (!isNaN(parseFloat(row.foodallowance))) {
        totalFee += parseFloat(row.foodallowance);
      }
      if (!isNaN(parseFloat(row.otherfeeamount))) {
        totalFee += parseFloat(row.otherfeeamount);
      }
      row.total = totalFee.toFixed(2);
      const totalFee = moneySum([
        row.trafficexpense,
        row.cityfee,
        row.hotelexpense,
        row.otherexpense,
        row.foodexpenses,
        row.foodallowance,
        row.otherfeeamount
      ]);
      row.total = moneyRound(totalFee).toFixed(2);
      /*
      if (!isNaN(parseFloat(this.rbDetails[rowIndex].trafficexpense))) {
        totalFee += parseFloat(this.rbDetails[rowIndex].trafficexpense);
      }
      if (!isNaN(parseFloat(this.rbDetails[rowIndex].cityfee))) {
        totalFee += parseFloat(this.rbDetails[rowIndex].cityfee);
      }
      if (!isNaN(parseFloat(this.rbDetails[rowIndex].hotelexpense))) {
        totalFee += parseFloat(this.rbDetails[rowIndex].hotelexpense);
      }
      if (!isNaN(parseFloat(this.rbDetails[rowIndex].otherexpense))) {
        totalFee += parseFloat(this.rbDetails[rowIndex].otherexpense);
      }
      if (!isNaN(parseFloat(this.rbDetails[rowIndex].foodexpenses))) {
        totalFee += parseFloat(this.rbDetails[rowIndex].foodexpenses);
      }
      if (!isNaN(parseFloat(this.rbDetails[rowIndex].foodallowance))) {
        totalFee += parseFloat(this.rbDetails[rowIndex].foodallowance);
      }
      if (!isNaN(parseFloat(this.rbDetails[rowIndex].otherfeeamount))) {
        totalFee += parseFloat(this.rbDetails[rowIndex].otherfeeamount);
      }
      this.rbDetails[rowIndex].total = parseFloat(totalFee).toFixed(2);
      this.$set(this.rbDetails, rowIndex, this.rbDetails[rowIndex]);
      */
      //重新计算整个报销单的合计
      this.sumTotalFee();
    },
    //计算费用合计
    sumTotalFee() {
      let allSum = 0;
      //捐献者家属费用
      if (!isNaN(parseFloat(this.form.donoramount))) {
        allSum += parseFloat(this.form.donoramount);
      }
      //报销明细费用
      try {
        for (let i = 0; i < this.rbDetails.length; i++) {
          /*
          let totalFee = 0;
          //计算当前报销内容费用合计
          if (!isNaN(parseFloat(this.rbDetails[i].total))) {
            totalFee += parseFloat(this.rbDetails[i].total);
          }
          if (!isNaN(parseFloat(this.rbDetails[i].cityfee))) {
            totalFee += parseFloat(this.rbDetails[i].cityfee);
          }
          if (!isNaN(parseFloat(this.rbDetails[i].hotelexpense))) {
            totalFee += parseFloat(this.rbDetails[i].hotelexpense);
          }
          if (!isNaN(parseFloat(this.rbDetails[i].otherexpense))) {
            totalFee += parseFloat(this.rbDetails[i].otherexpense);
          }
          if (!isNaN(parseFloat(this.rbDetails[i].foodexpenses))) {
            totalFee += parseFloat(this.rbDetails[i].foodexpenses);
          }
          if (!isNaN(parseFloat(this.rbDetails[i].foodallowance))) {
            totalFee += parseFloat(this.rbDetails[i].foodallowance);
          }
          if (!isNaN(parseFloat(this.rbDetails[i].otherfeeamount))) {
            totalFee += parseFloat(this.rbDetails[i].otherfeeamount);
          }
          this.rbDetails[i].total = parseFloat(totalFee).toFixed(2);
          this.$set(this.rbDetails, i, this.rbDetails[i]);
          */
          if (!isNaN(parseFloat(this.rbDetails[i].total))) {
            allSum += parseFloat(this.rbDetails[i].total);
          }
        }
        this.form.amountrequested = allSum.toFixed(2);
        this.form.amountrequested = moneyAdd(
          moneySum(this.rbDetails, "total"),
          this.form.donoramount
        ).toFixed(2);
        this.form.bigstrmoney = this.convertCurrency(this.form.amountrequested);
      } catch { }
    },
src/views/project/travelexpensecheck/index.vue
@@ -678,6 +678,7 @@
import { getUserProfile } from "@/api/system/user";
import { getToken } from "@/utils/auth";
import { setItem, grtItem, removeItem } from "@/utils/storage.js";
import { moneySum } from "@/utils/money";
export default {
  components: {
@@ -1294,41 +1295,25 @@
        });
    },
    //计算费用合计
    //计算费用合计(金额一律走精确运算,禁止 parseFloat ç´¯åŠ ï¼‰
    sumTotalFee(scope) {
      let allSum = 0;
      try {
        for (let i = 0; i < this.rbDetails.length; i++) {
          let totalFee = 0;
          const row = this.rbDetails[i];
          //计算当前报销内容费用合计
          if (!isNaN(parseFloat(this.rbDetails[i].trafficexpense))) {
            totalFee += parseFloat(this.rbDetails[i].trafficexpense);
          const totalFee = moneySum([
            row.trafficexpense,
            row.cityfee,
            row.hotelexpense,
            row.otherexpense,
            row.foodexpenses,
            row.foodallowance,
            row.otherfeeamount
          ]);
          row.total = totalFee.toFixed(2);
          this.$set(this.rbDetails, scope.$index, row);
          }
          if (!isNaN(parseFloat(this.rbDetails[i].cityfee))) {
            totalFee += parseFloat(this.rbDetails[i].cityfee);
          }
          if (!isNaN(parseFloat(this.rbDetails[i].hotelexpense))) {
            totalFee += parseFloat(this.rbDetails[i].hotelexpense);
          }
          if (!isNaN(parseFloat(this.rbDetails[i].otherexpense))) {
            totalFee += parseFloat(this.rbDetails[i].otherexpense);
          }
          if (!isNaN(parseFloat(this.rbDetails[i].foodexpenses))) {
            totalFee += parseFloat(this.rbDetails[i].foodexpenses);
          }
          if (!isNaN(parseFloat(this.rbDetails[i].foodallowance))) {
            totalFee += parseFloat(this.rbDetails[i].foodallowance);
          }
          if (!isNaN(parseFloat(this.rbDetails[i].otherfeeamount))) {
            totalFee += parseFloat(this.rbDetails[i].otherfeeamount);
          }
          this.rbDetails[i].total = parseFloat(totalFee).toFixed(2);
          this.$set(this.rbDetails, scope.$index, this.rbDetails[i]);
          if (!isNaN(parseFloat(this.rbDetails[i].total))) {
            allSum += parseFloat(this.rbDetails[i].total);
          }
        }
        this.form.amountrequested = allSum.toFixed(2);
        this.form.amountrequested = moneySum(this.rbDetails, "total").toFixed(2);
        this.form.bigstrmoney = this.convertCurrency(this.form.amountrequested);
      } catch { }
    },
src/views/project/unitCost/particulars/index.vue
@@ -575,6 +575,7 @@
import Li_area_select from "@/components/Address";
import { getUserProfile } from "@/api/system/user";
import { getToken } from "@/utils/auth";
import { moneySum, moneyRound } from "@/utils/money";
import debounce from "lodash/debounce";
export default {
  components: {
@@ -1089,23 +1090,16 @@
        this.$modal.msgError("注意实收金额不等于应收金额,请核对数据!");
      }
    },
    //修改实收或应收后触发
    //修改实收或应收后触发(金额一律走精确运算)
    chargeSum() {
      let ChargeSum = 0;
      let ChargeamountSum = 0;
      //费用合计
      try {
        for (let i = 0; i < this.donorchargeorgans.length; i++) {
          if (!isNaN(parseFloat(this.donorchargeorgans[i].organcharge))) {
            ChargeSum += parseFloat(this.donorchargeorgans[i].organcharge);
          }
          if (!isNaN(parseFloat(this.donorchargeorgans[i].amount))) {
            ChargeamountSum += parseFloat(this.donorchargeorgans[i].amount);
          }
        }
        this.form.receivableamount = ChargeSum.toFixed(2);
        this.form.receivedamount = ChargeamountSum.toFixed(2);
        this.form.receivableamount = moneyRound(
          moneySum(this.donorchargeorgans, "organcharge")
        ).toFixed(2);
        this.form.receivedamount = moneyRound(
          moneySum(this.donorchargeorgans, "amount")
        ).toFixed(2);
      } catch {}
    },
vue.config.js
@@ -33,8 +33,8 @@
    proxy: {
      // detail: https://cli.vuejs.org/config/#devserver-proxy
      [process.env.VUE_APP_BASE_API]: {
        // target:`http://localhost:8080`,
        target:`http://192.168.100.10:8081`,
        target:`http://localhost:8080`,
        // target:`http://192.168.100.10:8081`,
        // target:`http://192.168.100.137:8080`,
        // target: `https://slb.hospitalstar.com:9093`,
        changeOrigin: true,
Ê¡ÈËÃñopo.zip
Binary files differ