From 5d1d4b7232a44a05f2657403bd65e4ff171b4256 Mon Sep 17 00:00:00 2001 From: houjunxiang Date: Fri, 30 Jan 2026 21:01:30 +0800 Subject: [PATCH] =?UTF-8?q?feat:=E8=AE=A1=E7=AE=97=E5=85=AC=E5=BC=8F?= =?UTF-8?q?=E6=98=A0=E5=B0=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- defaultBaseUrl.js | 12 +-- nx/helper/calcAnalysisValue.js | 159 ++++++++++++++++++--------------- nx/helper/parseSafeArgs.js | 27 ++++++ 3 files changed, 118 insertions(+), 80 deletions(-) create mode 100644 nx/helper/parseSafeArgs.js diff --git a/defaultBaseUrl.js b/defaultBaseUrl.js index 1b95b15..17f3b7e 100644 --- a/defaultBaseUrl.js +++ b/defaultBaseUrl.js @@ -1,14 +1,14 @@ // 在此不用配置接口前缀 const isDev = process.env.NODE_ENV === 'development' // 正式环境 -const BaseUrl = isDev ? 'http://172.17.19.29:48080/admin-api' : 'http://172.17.19.29:48080/admin-api' -const upgradeBaseUrl = isDev ? 'http://172.17.19.29:48080/admin-api' : 'http://172.17.19.29:48080/admin-api' -const websocketUrl = isDev ? 'ws://172.17.19.11:30330' : 'ws://172.17.19.11:30330' +// const BaseUrl = isDev ? 'http://172.17.19.29:48080/admin-api' : 'http://172.17.19.29:48080/admin-api' +// const upgradeBaseUrl = isDev ? 'http://172.17.19.29:48080/admin-api' : 'http://172.17.19.29:48080/admin-api' +// const websocketUrl = isDev ? 'ws://172.17.19.11:30330' : 'ws://172.17.19.11:30330' // 公司测试环境 -// const BaseUrl = isDev ? 'http://192.168.26.116:888/admin-api' : 'http://192.168.26.116:888/admin-api' -// const upgradeBaseUrl = isDev ? 'http://192.168.26.116:888/admin-api' : 'http://192.168.26.116:888/admin-api' -// const websocketUrl = isDev ? 'ws://192.168.26.116:888/ws' : 'ws://192.168.26.116:888/ws' +const BaseUrl = isDev ? 'http://192.168.26.116:888/admin-api' : 'http://192.168.26.116:888/admin-api' +const upgradeBaseUrl = isDev ? 'http://192.168.26.116:888/admin-api' : 'http://192.168.26.116:888/admin-api' +const websocketUrl = isDev ? 'ws://192.168.26.116:888/ws' : 'ws://192.168.26.116:888/ws' const tenantId = '1' export const clientId = 'zgty_lims' diff --git a/nx/helper/calcAnalysisValue.js b/nx/helper/calcAnalysisValue.js index 8648a3a..75fafdb 100644 --- a/nx/helper/calcAnalysisValue.js +++ b/nx/helper/calcAnalysisValue.js @@ -1,13 +1,90 @@ import { create, all, number, pow } from 'mathjs' +import parseSafeArgs from './parseSafeArgs' const math = create(all) math.config({ number: 'BigNumber', precision: 64 }) export { math } + +const GetRecoveryRate = function (elementFormulaCode, value) { + // //读取conRecoveryRateList + const conRecoveryRateList = uni.getStorageSync('ConRecoveryRateList') + if (!conRecoveryRateList) return + let o = conRecoveryRateList.find(i => { + //console.log("取得的" + i + "回收率:" + i); + if (value === 0) { + return i.elementFormulaCode === elementFormulaCode && i.minValue === value + } + return i.elementFormulaCode === elementFormulaCode && i.minValue < value && value <= i.maxValue + }) + // console.log(o); + const rate = o ? o.rate : 100 + // console.log("取得的" + elementFormulaCode + "回收率:" + rate); + return rate + // console.log("执行方法:GetRecoveryRate"); + // return 100; +} +/* + * 根据硫值计算:支持碳、硝酸钾(滇中) + * 当S%<22%时,需加入淀粉的量=(75-S%*22*M)/12 + * 当 S%>22%时,需加入硝酸钾的量=(S%*22*M-75)/4 + * 当 S%==22%时,硝酸钾为0,淀粉为空 + * sValueKey:硫值对应的dicKey + * weightKey:重量对应的dicKey + * percent:计算参数 + * + * 举例:Get_C_KNO3_bySValue|(|p14|, |p2|, |>|) + * */ +const Get_C_KNO3_bySValue = function (sValue, weight, operator) { + //判断sValue是数字 + if (isNaN(sValue) || isNaN(weight)) { + return '' + } + let v = number(sValue) + const w = number(weight) + if (w === 0) return '' + v = v * 0.01 + //当S%<22%时,需加入淀粉的量=(75-S%*22*M)/12 + if (operator === '<' && v < 0.22) { + // return ( 75 - v * 22 * w )/12; + return accDiv(accSub(75, accMul(accMul(v, 22), w)), 12) + } + //S%>22%时,需加入硝酸钾的量=(S%*22*M-75)/4 + if (operator === '>=' && v >= 0.22) { + //S%==22%时,硝酸钾为0,淀粉为空 + if (v === 22) return 0 + // return ( v * 22 * w - 75 ) + 44; + return accDiv(accSub(accMul(v, accMul(22, w)), 75), 4) + } + + return '' +} +const Get_C_KNO3 = function (sValue, weight, operator) { + //判断sValue是数字 + + if (sValue === 0 || weight === 0) { + return '' + } + let S = number(sValue) + const W = number(weight) + if (W === 0) return '' + const V = ((W * S) / 100) * 22 - 75 + if (operator === '<' && V < 0) { + return math.abs(V / 12) + } + if (operator === '>=' && V >= 0) { + return V / 4 + } + return '' +} +const FORMULA_FUNCTIONS = { + GetRecoveryRate, + Get_C_KNO3_bySValue, + Get_C_KNO3 +} /* * 计算当前样品分析值*/ - export function calcAnalysisValue(group, externalFormData, taskIngredientsWay) { const MAX_ITERATIONS = 5 // 防止无限循环 let iterations = 0 @@ -119,7 +196,13 @@ export function calcRowAnalysisValue(row, columnObj, dynamicsColumns, externalFo let v if (formulaVal.startsWith('Get_')) { if (taskIngredientsWay !== 'manual') continue - v = eval(formulaVal) + const match = formulaVal.match(/^([a-zA-Z_]\w*)\((.*)\)$/) + const funcName = match[1] + const argsStr = match[2].trim() + const func = FORMULA_FUNCTIONS[funcName] + // 安全解析参数(支持数字、字符串) + const args = parseSafeArgs(argsStr) + v = func(...args) } else if (formulaVal.startsWith('GetFrom')) { v = evaluateGetFromFormula(formulaVal, false, externalFormData) } else { @@ -143,78 +226,6 @@ const findFieldInGroup = function (paramNo, group, p) { return { value: null } } -const GetRecoveryRate = function (elementFormulaCode, value) { - // //读取conRecoveryRateList - const conRecoveryRateList = uni.getStorageSync('ConRecoveryRateList') - if (!conRecoveryRateList) return - let o = conRecoveryRateList.find(i => { - //console.log("取得的" + i + "回收率:" + i); - if (value === 0) { - return i.elementFormulaCode === elementFormulaCode && i.minValue === value - } - return i.elementFormulaCode === elementFormulaCode && i.minValue < value && value <= i.maxValue - }) - // console.log(o); - const rate = o ? o.rate : 100 - // console.log("取得的" + elementFormulaCode + "回收率:" + rate); - return rate - // console.log("执行方法:GetRecoveryRate"); - // return 100; -} -/* - * 根据硫值计算:支持碳、硝酸钾(滇中) - * 当S%<22%时,需加入淀粉的量=(75-S%*22*M)/12 - * 当 S%>22%时,需加入硝酸钾的量=(S%*22*M-75)/4 - * 当 S%==22%时,硝酸钾为0,淀粉为空 - * sValueKey:硫值对应的dicKey - * weightKey:重量对应的dicKey - * percent:计算参数 - * - * 举例:Get_C_KNO3_bySValue|(|p14|, |p2|, |>|) - * */ -const Get_C_KNO3_bySValue = function (sValue, weight, operator) { - //判断sValue是数字 - if (isNaN(sValue) || isNaN(weight)) { - return '' - } - let v = number(sValue) - const w = number(weight) - if (w === 0) return '' - v = v * 0.01 - //当S%<22%时,需加入淀粉的量=(75-S%*22*M)/12 - if (operator === '<' && v < 0.22) { - // return ( 75 - v * 22 * w )/12; - return accDiv(accSub(75, accMul(accMul(v, 22), w)), 12) - } - //S%>22%时,需加入硝酸钾的量=(S%*22*M-75)/4 - if (operator === '>=' && v >= 0.22) { - //S%==22%时,硝酸钾为0,淀粉为空 - if (v === 22) return 0 - // return ( v * 22 * w - 75 ) + 44; - return accDiv(accSub(accMul(v, accMul(22, w)), 75), 4) - } - - return '' -} -function Get_C_KNO3(sValue, weight, operator) { - //判断sValue是数字 - - if (sValue === 0 || weight === 0) { - return '' - } - let S = number(sValue) - const W = number(weight) - if (W === 0) return '' - const V = ((W * S) / 100) * 22 - 75 - if (operator === '<' && V < 0) { - return math.abs(V / 12) - } - if (operator === '>=' && V >= 0) { - return V / 4 - } - return '' -} - /** 处理数值数据:四舍六入奇进偶不进 * 1,如果取小数的最后一位为5,5前为奇数进位,为偶不进,五后非零就进一,五后皆零看奇偶,五前为偶应舍去,五前为奇要进一 * 2.5后不为0时就入,为0时看5前,奇进偶不进 diff --git a/nx/helper/parseSafeArgs.js b/nx/helper/parseSafeArgs.js new file mode 100644 index 0000000..f190fcd --- /dev/null +++ b/nx/helper/parseSafeArgs.js @@ -0,0 +1,27 @@ +export default function parseSafeArgs(argsStr) { + if (!argsStr.trim()) return [] + + // 将 ', ' 或 '(' 后的单引号字符串转换为合法 JSON 字符串 + // 思路:匹配所有 '...' 并替换为 "..." + let jsonLike = + '[' + + argsStr + .replace(/\s*,\s*/g, ',') // 去掉参数间空格 + .replace(/'/g, '"') + // 单引号 → 双引号 + ']' + + try { + const parsed = JSON.parse(jsonLike) + // 确保数字不被转成字符串(JSON 会自动处理) + return parsed.map(item => { + if (typeof item === 'string') { + // 如果是 '<' 或 '>',保留字符串 + return item + } + return item // number + }) + } catch (e) { + console.warn('Failed to parse args:', argsStr, e) + return [] + } +}