From 1bef995d9a6cc817bea0318a2a33ea013fe69deb Mon Sep 17 00:00:00 2001
From: zouyu <2723363702@qq.com>
Date: 星期三, 12 十一月 2025 16:31:14 +0800
Subject: [PATCH] 计算精度问题修复
---
src/views/business/outsourcingFinishProduct/index.vue | 12 +-
src/utils/bigEval.js | 118 +++++++++++++++++++++++
src/views/business/productOrder/components/addOrder.vue | 48 +++++++++
src/main.js | 3
src/views/business/reportPreparation/index.vue | 22 ++++
src/views/business/inspectionTask/inspection.vue | 4
src/views/business/inspectionTask/index.vue | 7 +
src/views/business/materialOrder/customsInspectionOrder.vue | 48 +++++++++
8 files changed, 250 insertions(+), 12 deletions(-)
diff --git a/src/main.js b/src/main.js
index 4f02aa2..5f2db03 100644
--- a/src/main.js
+++ b/src/main.js
@@ -50,7 +50,10 @@
// 鏃堕棿杞崲
import Moment from "moment";
+import Big from 'big.js'
+
// 鍏ㄥ眬鏂规硶鎸傝浇
+Vue.prototype.$Big = Big;
Vue.prototype.getDicts = getDicts;
Vue.prototype.getConfigKey = getConfigKey;
Vue.prototype.parseTime = parseTime;
diff --git a/src/utils/bigEval.js b/src/utils/bigEval.js
new file mode 100644
index 0000000..280d5ef
--- /dev/null
+++ b/src/utils/bigEval.js
@@ -0,0 +1,118 @@
+import Big from "big.js";
+
+/**
+ * 瀹夊叏璁$畻鍣紙鏀寔 + - * / 鍜屾嫭鍙凤級
+ * @param {string} expr 鏁板琛ㄨ揪寮忥紝濡� "(0.1 + 0.2) * 3"
+ * @returns {string} 璁$畻缁撴灉瀛楃涓�
+ */
+export function bigEval(expr) {
+ console.log(expr)
+ // 姝ラ1锛氳瘝娉曞垎鏋�
+ const tokens = tokenize(expr);
+ // 姝ラ2锛氳浆鎹负閫嗘尝鍏拌〃杈惧紡锛堝悗缂�琛ㄨ揪寮忥級
+ const rpn = shuntingYard(tokens);
+ // 姝ラ3锛氭墽琛岃绠�
+ return evaluateRPN(rpn);
+}
+
+// 璇嶆硶鍒嗘瀽鍣�
+function tokenize(expr) {
+ const tokens = [];
+ let numBuffer = "";
+ let prevToken = null;
+
+ const flushNumber = () => {
+ if (numBuffer) {
+ // 鏂板锛氶獙璇佹暟瀛楁牸寮忥紙鏀寔璐熸暟銆佸皬鏁帮級
+ if (!/^-?(\d+(\.\d*)?|\.\d+)$/.test(numBuffer)) {
+ throw new Error(`鏃犳晥鏁板瓧鏍煎紡: ${numBuffer}`);
+ }
+ if (numBuffer.startsWith(".")) numBuffer = "0" + numBuffer;
+ tokens.push({ type: "number", value: numBuffer });
+ numBuffer = "";
+ }
+ };
+
+ for (let i = 0; i < expr.length; i++) {
+ const c = expr[i];
+ if (/\d|\./.test(c)) {
+ numBuffer += c;
+ } else if ("+-*/()".includes(c)) {
+ // 淇敼锛氬鍔� numBuffer 涓虹┖鐨勫垽鏂紝纭繚璐熷彿鍙兘浣滀负鏁板瓧鍓嶇紑锛堝叧閿慨澶嶏級
+ if (c === "-" && numBuffer === "" && (
+ !prevToken ||
+ (prevToken.type === "operator" && prevToken.value !== ")")
+ )) {
+ numBuffer += c;
+ } else {
+ flushNumber();
+ tokens.push({ type: "operator", value: c });
+ }
+ prevToken = tokens[tokens.length - 1];
+ } else if (c !== " ") {
+ throw new Error(`闈炴硶瀛楃: ${c}`);
+ }
+ }
+
+ flushNumber();
+ return tokens;
+}
+
+// 璋冨害鍦虹畻娉曠敓鎴愰�嗘尝鍏拌〃杈惧紡
+function shuntingYard(tokens) {
+ const output = [];
+ const stack = [];
+ const precedence = { "+": 1, "-": 1, "*": 2, "/": 2 };
+
+ for (const token of tokens) {
+ if (token.type === "number") {
+ output.push(token.value);
+ } else if (token.value === "(") {
+ stack.push(token.value);
+ } else if (token.value === ")") {
+ while (stack.length && stack[stack.length - 1] !== "(") {
+ output.push(stack.pop());
+ }
+ stack.pop(); // 寮瑰嚭宸︽嫭鍙�
+ } else {
+ while (
+ stack.length &&
+ stack[stack.length - 1] !== "(" &&
+ precedence[stack[stack.length - 1]] >= precedence[token.value]
+ ) {
+ output.push(stack.pop());
+ }
+ stack.push(token.value);
+ }
+ }
+
+ while (stack.length) output.push(stack.pop());
+ return output;
+}
+
+// 鎵ц閫嗘尝鍏拌〃杈惧紡璁$畻
+function evaluateRPN(rpn) {
+ const stack = [];
+
+ for (const token of rpn) {
+ if (/[-]?\d|\./.test(token)) {
+ stack.push(new Big(token));
+ } else {
+ const b = stack.pop();
+ const a = stack.pop();
+
+ switch (token) {
+ case "+": stack.push(a.plus(b)); break;
+ case "-": stack.push(a.minus(b)); break;
+ case "*": stack.push(a.times(b)); break;
+ case "/":
+ if (b.eq(0)) throw new Error("闄ゆ暟涓嶈兘涓洪浂");
+ stack.push(a.div(b));
+ break;
+ default: throw new Error(`鏈煡杩愮畻绗�: ${token}`);
+ }
+ }
+ }
+
+ return stack.pop().toString();
+}
diff --git a/src/views/business/inspectionTask/index.vue b/src/views/business/inspectionTask/index.vue
index 841df1e..19b48a4 100644
--- a/src/views/business/inspectionTask/index.vue
+++ b/src/views/business/inspectionTask/index.vue
@@ -18,6 +18,11 @@
:value="a.value"></el-option>
</el-select>
</el-form-item>
+ <el-form-item label="渚涘簲鍟嗗悕绉�" prop="supplierName" v-if="tabIndex===2">
+ <el-input v-model="queryParams.supplierName" clearable placeholder="璇疯緭鍏�" size="small"
+ @keyup.enter.native="goSearch">
+ </el-input>
+ </el-form-item>
<el-form-item>
<el-button size="mini" type="primary" @click="refreshTable()">鏌ヨ</el-button>
<el-button size="mini" @click="refresh()">閲嶇疆</el-button>
@@ -247,6 +252,7 @@
import {upReportUrl} from "@/api/business/insReport";
import onlyoffice from "@/components/Onlyoffice/onlyoffice.vue";
import filePreview from "@/components/Preview/filePreview.vue";
+import tab from "../../../plugins/tab";
export default {
name: 'InspectionTask',
components: {
@@ -377,6 +383,7 @@
}
},
},
+ { label: "闆朵欢鎻忚堪", prop: "partDesc", width: "150px" },
{ label: "鏍峰搧鍨嬪彿", prop: "sampleModel", width: "120px" },
{
label: "绱ф�ョ▼搴�",
diff --git a/src/views/business/inspectionTask/inspection.vue b/src/views/business/inspectionTask/inspection.vue
index 976df1d..2714171 100644
--- a/src/views/business/inspectionTask/inspection.vue
+++ b/src/views/business/inspectionTask/inspection.vue
@@ -1013,7 +1013,8 @@
calcInbondLength(startMeterMark,endMeterMark){
let inboundLength = null;
if((startMeterMark!=null && startMeterMark!=='') && (endMeterMark!=null&&endMeterMark!=='')){
- inboundLength = Math.abs(endMeterMark - startMeterMark)
+ let minus = this.$Big(endMeterMark).minus(this.$Big(startMeterMark));
+ inboundLength = Math.abs(minus)
}
return inboundLength;
},
@@ -1564,6 +1565,7 @@
});
});
// 鑾峰彇鍒版渶澶ф楠屽�艰緭鍏ヤ釜鏁板悗閲嶇粍鏁版嵁
+ console.log("鏈�澶т釜鏁帮細", maxNum);
let obj0 = {
name: j,
arr: data[i][j].result,
diff --git a/src/views/business/materialOrder/customsInspectionOrder.vue b/src/views/business/materialOrder/customsInspectionOrder.vue
index 949c6b5..e8aee87 100644
--- a/src/views/business/materialOrder/customsInspectionOrder.vue
+++ b/src/views/business/materialOrder/customsInspectionOrder.vue
@@ -462,6 +462,7 @@
import {dateFormat} from "@/utils/date";
import AuxiliaryWireCore from "../productOrder/components/auxiliaryWireCore.vue";
import cableConfig from "../productOrder/components/cable-config.vue";
+import {bigEval} from "../../../utils/bigEval";
export default {
name: "CustomsInspectionOrder",
dicts: ['check_type', 'urgency_level'],
@@ -1206,6 +1207,37 @@
this.saveLoad = false
})
},
+ /**
+ * 鑾峰彇灏忔暟鐨勬渶澶т綅鏁�
+ * @param number 鍨嬪彿鍙傛暟
+ * @param ask 瑕佹眰鍊�
+ * @param calcNum 璁$畻鍊�
+ */
+ getDecimalPlaces(number, ask, calcNum) {
+ console.log("璁$畻灏忔暟鐐�-->", number, ask, calcNum);
+ let count1 = 0;
+ let count2 = 0;
+ const reg = /(\d+\.)(\d+)/g;
+ let matches = [];
+ if (ask) {
+ matches = ask.match(reg);
+ }
+ if (
+ matches &&
+ matches.length > 0 &&
+ matches[0].toString().indexOf(".") > -1
+ ) {
+ count1 = matches[0].toString().split(".")[1].length;
+ }
+ if (number.toString().indexOf(".") > -1) {
+ count2 = number.toString().split(".")[1].length;
+ }
+ if (calcNum.toString().indexOf(".") > -1) {
+ const pointLength2 = calcNum.toString().split(".")[1].length;
+ count2 = count2 > pointLength2 ? count2 : pointLength2;
+ }
+ return count1 > count2 ? count1 : count2;
+ },
handleAsk(ask,symbolItem, value) {
try{
let code = [">", "<", "=", "锛�", "锛�", "鈮�", "鈮�", "卤", "*", "/"];
@@ -1218,7 +1250,13 @@
let index = code.findIndex(b => m.includes(b))
if (index > -1) {
let arr = m.split(code[index]).filter(b => !!b)
- let num = eval(this.replaceAll(arr[0], symbolItem, value))
+ let calcNum = this.$Big(
+ bigEval(this.replaceAll(arr[0], symbolItem, value))
+ );
+ let num = calcNum.toFixed(
+ this.getDecimalPlaces(value, ask, calcNum)
+ );
+ // let num = eval(this.replaceAll(arr[0], symbolItem, value))
m = code[index] + '' + num
arr1.push(m)
}
@@ -1247,7 +1285,13 @@
let index = code.findIndex(b => ask.includes(b))
if (index > -1) {
let arr = ask.split(code[index]).filter(b => !!b)
- let num = eval(this.replaceAll(arr[0], symbolItem, value))
+ let calcNum = this.$Big(
+ bigEval(this.replaceAll(arr[0], symbolItem, value))
+ );
+ let num = calcNum.toFixed(
+ this.getDecimalPlaces(value, ask, calcNum)
+ );
+ // let num = eval(this.replaceAll(arr[0], symbolItem, value))
return code[index] + '' + num
}
}
diff --git a/src/views/business/outsourcingFinishProduct/index.vue b/src/views/business/outsourcingFinishProduct/index.vue
index ae67b91..175af48 100644
--- a/src/views/business/outsourcingFinishProduct/index.vue
+++ b/src/views/business/outsourcingFinishProduct/index.vue
@@ -23,6 +23,11 @@
@keyup.enter.native="goSearch">
</el-input>
</el-form-item>
+ <el-form-item label="渚涘簲鍟嗗悕绉�" prop="supplierName" >
+ <el-input v-model="entity.supplierName" clearable placeholder="璇疯緭鍏�" size="small"
+ @keyup.enter.native="goSearch">
+ </el-input>
+ </el-form-item>
<el-form-item>
<el-button v-if="tabIndex === 2 || tabIndex === 3 || tabIndex === 4"
:icon="!more ? 'el-icon-arrow-down' : 'el-icon-arrow-up'" style="color: #3A7BFA;" type="text"
@@ -30,12 +35,7 @@
<el-button size="mini" type="primary" @click="goSearch">鏌ヨ</el-button>
<el-button size="mini" @click="refresh()">閲嶇疆</el-button>
</el-form-item>
- <el-form-item label="渚涘簲鍟嗗悕绉�" prop="supplierName"
- v-if="(tabIndex === 2 || tabIndex === 3 || tabIndex === 4) && more">
- <el-input v-model="entity.supplierName" clearable placeholder="璇疯緭鍏�" size="small"
- @keyup.enter.native="goSearch">
- </el-input>
- </el-form-item>
+
<el-form-item label="鏍峰搧鍨嬪彿" prop="sampleModel"
v-if="(tabIndex === 2 || tabIndex === 3 || tabIndex === 4) && more">
<el-input v-model="entity.sampleModel" clearable placeholder="璇疯緭鍏�" size="small"
diff --git a/src/views/business/productOrder/components/addOrder.vue b/src/views/business/productOrder/components/addOrder.vue
index 5e40926..14c305a 100644
--- a/src/views/business/productOrder/components/addOrder.vue
+++ b/src/views/business/productOrder/components/addOrder.vue
@@ -601,6 +601,7 @@
import {selectsStandardMethodByFLSSM} from "@/api/standard/standardLibrary";
import limsTable from "@/components/Table/lims-table.vue";
import {selectCustomPageList} from "@/api/system/customer";
+import { bigEval } from "@/utils/bigEval";
import {mapGetters} from "vuex";
import {addQuarter, updateQuarterOnOrder} from "@/api/business/finishedProductSampling";
@@ -1033,6 +1034,37 @@
return symbolItem
}
},
+ /**
+ * 鑾峰彇灏忔暟鐨勬渶澶т綅鏁�
+ * @param number 鍨嬪彿鍙傛暟
+ * @param ask 瑕佹眰鍊�
+ * @param calcNum 璁$畻鍊�
+ */
+ getDecimalPlaces(number, ask, calcNum) {
+ console.log("璁$畻灏忔暟鐐�-->", number, ask, calcNum);
+ let count1 = 0;
+ let count2 = 0;
+ const reg = /(\d+\.)(\d+)/g;
+ let matches = [];
+ if (ask) {
+ matches = ask.match(reg);
+ }
+ if (
+ matches &&
+ matches.length > 0 &&
+ matches[0].toString().indexOf(".") > -1
+ ) {
+ count1 = matches[0].toString().split(".")[1].length;
+ }
+ if (number.toString().indexOf(".") > -1) {
+ count2 = number.toString().split(".")[1].length;
+ }
+ if (calcNum.toString().indexOf(".") > -1) {
+ const pointLength2 = calcNum.toString().split(".")[1].length;
+ count2 = count2 > pointLength2 ? count2 : pointLength2;
+ }
+ return count1 > count2 ? count1 : count2;
+ },
handleAsk(ask,symbolItem, value) {
try{
let code = [">", "<", "=", "锛�", "锛�", "鈮�", "鈮�", "卤"];
@@ -1045,7 +1077,13 @@
let index = code.findIndex(b => m.includes(b))
if (index > -1) {
let arr = m.split(code[index]).filter(b => !!b)
- let num = eval(this.replaceAll(arr[0], symbolItem, value))
+ let calcNum = this.$Big(
+ bigEval(this.replaceAll(arr[0], symbolItem, value))
+ );
+ let num = calcNum.toFixed(
+ this.getDecimalPlaces(value, ask, calcNum)
+ );
+ // let num = eval(this.replaceAll(arr[0], symbolItem, value))
m = code[index] + '' + num
arr1.push(m)
}
@@ -1074,7 +1112,13 @@
let index = code.findIndex(b => ask.includes(b))
if (index > -1) {
let arr = ask.split(code[index]).filter(b => !!b)
- let num = eval(this.replaceAll(arr[0], symbolItem, value))
+ let calcNum = this.$Big(
+ bigEval(this.replaceAll(arr[0], symbolItem, value))
+ );
+ let num = calcNum.toFixed(
+ this.getDecimalPlaces(value, ask, calcNum)
+ );
+ // let num = eval(this.replaceAll(arr[0], symbolItem, value))
return code[index] + '' + num
}
}
diff --git a/src/views/business/reportPreparation/index.vue b/src/views/business/reportPreparation/index.vue
index b9a04e8..ad48bbb 100644
--- a/src/views/business/reportPreparation/index.vue
+++ b/src/views/business/reportPreparation/index.vue
@@ -26,6 +26,16 @@
<el-option v-for="(a, i) in orderTypeList" :key="i" :label="a.label" :value="a.value"></el-option>
</el-select>
</el-form-item>
+ <el-form-item label="闆朵欢鎻忚堪" prop="partDesc" >
+ <el-input v-model="entity.partDesc" clearable placeholder="璇疯緭鍏�" size="small"
+ @keyup.enter.native="refreshTable">
+ </el-input>
+ </el-form-item>
+ <el-form-item label="渚涘簲鍟嗗悕绉�" prop="supplierName" >
+ <el-input v-model="entity.supplierName" clearable placeholder="璇疯緭鍏�" size="small"
+ @keyup.enter.native="refreshTable">
+ </el-input>
+ </el-form-item>
<el-form-item>
<el-button size="mini" type="primary" @click="refreshTable()">鏌ヨ</el-button>
<el-button size="mini" @click="refresh()">閲嶇疆</el-button>
@@ -38,7 +48,7 @@
</div>
<div>
<lims-table :tableData="valueTableData" :column="column" :page="page" :tableLoading="tableLoading"
- :isSelection="true" :handleSelectionChange="handleChange" :height="'calc(100vh - 290px)'"
+ :isSelection="true" :handleSelectionChange="handleChange" :height="'calc(100vh - 320px)'"
@pagination="pagination" key="valueTableData">
<div slot="action" slot-scope="scope">
<el-button size="small" type="text" @click="viewIssued(scope.row)">鏌ョ湅鎶ュ憡</el-button>
@@ -351,6 +361,16 @@
width: "120px",
},
{
+ label: "闆朵欢鎻忚堪",
+ prop: "partDesc",
+ width: "120px",
+ },
+ {
+ label: "渚涘簲鍟嗗悕绉�",
+ prop: "supplierName",
+ width: "120px",
+ },
+ {
label: "鎶ュ憡缂栧彿",
prop: "code",
width: "160px",
--
Gitblit v1.9.3