diff --git a/nx/helper/calcAnalysisValue.js b/nx/helper/calcAnalysisValue.js
index a236161..b2900df 100644
--- a/nx/helper/calcAnalysisValue.js
+++ b/nx/helper/calcAnalysisValue.js
@@ -64,8 +64,11 @@ const Get_C_KNO3 = function (weight, sValue, operator) {
//判断sValue是数字
const S = number(sValue)
const W = number(weight)
+ console.log(S, W)
+
//如果样重为0就不计算
if (W === 0) {
+ console.log('结束')
return ''
}
if (W === 0) return ''
@@ -127,7 +130,7 @@ export function calcAnalysisValue(group, externalFormData, taskIngredientsWay) {
v = math.evaluate(formulaVal).toString()
v = isFinite(v) ? v.toString() : 0
}
- ele.value = handleRoundFiveNumber(v, ele.decimalPosition, ele.type === 'project')
+ ele.value = handleRoundFiveNumber(v, ele.decimalPosition)
changed = true
}
}
@@ -149,11 +152,13 @@ export function evaluateGetFromFormula(formula, parse, externalFormData, current
relFormulaVal = relFormulaVal.replace(key, value || 0)
}
}
+ console.log(relFormulaVal)
+
try {
let v = math.evaluate(relFormulaVal).toString()
v = isFinite(v) ? v : 0
if (parse) {
- return handleRoundFiveNumber(v, currentColumn.decimalPosition, currentColumn.type === 'project')
+ return handleRoundFiveNumber(v, currentColumn.decimalPosition)
}
return v
} catch (e) {
@@ -207,8 +212,7 @@ export function calcRowAnalysisValue(row, columnObj, dynamicsColumns, externalFo
v = math.evaluate(formulaVal).toString()
v = isFinite(v) ? v : 0
}
- let rowObj = row[curItem.fieldIndex]
- rowObj.value = handleRoundFiveNumber(Number(v), rowObj.decimalPosition, rowObj.type === 'project')
+ row[curItem.fieldIndex].value = handleRoundFiveNumber(Number(v), row[curItem.fieldIndex].decimalPosition)
calcRowAnalysisValue(row, curItem, dynamicsColumns, externalFormData)
}
}
@@ -231,56 +235,24 @@ const findFieldInGroup = function (paramNo, group, p) {
* 3.四舍,六入
* 传入数值和保留位数
*/
-export function handleRoundFiveNumber(number, fixed = 0, useTwoSignificantDigits = false) {
+export function handleRoundFiveNumber(number, fixed = 0) {
if (number == null || number === '' || isNaN(number)) return number
if (fixed === -1) return number
number = String(number)
//可以考虑清掉末尾的0,暂时限制了不会有,因为传入数值,末尾0是去掉的
- // 保留2位有效数字:小数点后面大于0的才叫有效数字,从小数点后面查找两位有效数字 ,如果末尾的有效数字的位数大于所设置的精度 以及 如果查找的有效数字没有两位的 ,就按照所设置的精度逻辑来计算,两位有效数字的最后 一位是在第几位,就用这个位数充当精度来按照原来精度的逻辑计算,
- // ===== 新增:按小数点后前两个非零数字确定精度 =====
- let actualFixed = fixed
- if (useTwoSignificantDigits) {
- const numStr = String(number)
- const dotIndex = numStr.indexOf('.')
-
- if (dotIndex !== -1) {
- const decimalPart = numStr.slice(dotIndex + 1)
- let nonZeroCount = 0
- let secondNonZeroPos = -1
-
- for (let i = 0; i < decimalPart.length; i++) {
- if (decimalPart[i] !== '0') {
- nonZeroCount++
- if (nonZeroCount === 2) {
- secondNonZeroPos = i + 1 // 小数点后第几位(从1开始)
- break
- }
- }
- }
-
- // 只有同时满足:
- // 1. 找到两个非零数字
- // 2. 第二个的位置 <= 用户指定的 fixed
- // 才使用该位置作为精度
- if (secondNonZeroPos !== -1 && secondNonZeroPos <= fixed) {
- actualFixed = secondNonZeroPos
- }
- }
- }
- console.log(actualFixed)
const index = number.indexOf('.')
if (index == -1) {
- if (actualFixed > 0) {
+ if (fixed > 0) {
number += '.'
}
- for (let i = 0; i < actualFixed; i++) {
+ for (let i = 0; i < fixed; i++) {
number += '0'
}
//补0返回
return number
}
//取到保留小数位的下一位,5.5555取保留俩位,那就是小数点后第三位
- const indexFixed = index + actualFixed + 1
+ const indexFixed = index + fixed + 1
if (indexFixed >= number.length) {
//如果小数位数不够, 补0直接返回
const zerolen = indexFixed - number.length
@@ -293,16 +265,16 @@ export function handleRoundFiveNumber(number, fixed = 0, useTwoSignificantDigits
const endNumber = number.substr(indexFixed, 1)
if (endNumber != '5') {
//如果做判断的数不是五,就按正常的四舍五入,即忽略了5,后面补0的那些由于是数字传进来,0已经去掉,此处不做处理
- return Number(number).toFixed(actualFixed)
+ return Number(number).toFixed(fixed)
}
if (indexFixed != number.length - 1) {
//由于当前判断位不是最后一位,而又去除了0,那么后面后的位数应该直接入位,五后不为0时入,由于会有小于五的,四舍五入肯定不行,那么只能截取到当前保留位数,然后转成数字加上10的负fixed的次方即可
number = number.substring(0, indexFixed)
if (number.indexOf('-') != -1) {
//需要考虑到负数的情况
- return (Number(number) - Number(Math.pow(10, -actualFixed))).toFixed(actualFixed)
+ return (Number(number) - Number(Math.pow(10, -fixed))).toFixed(fixed)
}
- return (Number(number) + Number(Math.pow(10, -actualFixed))).toFixed(actualFixed)
+ return (Number(number) + Number(Math.pow(10, -fixed))).toFixed(fixed)
//return this.accAdd(number,Math.pow(10,-fixed))
}
//接下来就时五后没有值也就是0的需要看前面的奇入偶不入了,取当前位的上一位
@@ -316,9 +288,9 @@ export function handleRoundFiveNumber(number, fixed = 0, useTwoSignificantDigits
number = number.substring(0, indexFixed)
if (number.indexOf('-') != -1) {
//需要考虑到负数的情况
- return (Number(number) - Math.pow(10, -actualFixed)).toFixed(actualFixed)
+ return (Number(number) - Math.pow(10, -fixed)).toFixed(fixed)
}
- return (Number(number) + Math.pow(10, -actualFixed)).toFixed(actualFixed)
+ return (Number(number) + Math.pow(10, -fixed)).toFixed(fixed)
}
//偶不进,将取值的当前位数,直接截取字符即可
return number.substr(0, indexFixed)
diff --git a/nx/helper/calcAnalysisValue.js.bak b/nx/helper/calcAnalysisValue.js.bak
new file mode 100644
index 0000000..a236161
--- /dev/null
+++ b/nx/helper/calcAnalysisValue.js.bak
@@ -0,0 +1,511 @@
+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 (weight, sValue, operator) {
+ //判断sValue是数字
+ const S = number(sValue)
+ const W = number(weight)
+ //如果样重为0就不计算
+ if (W === 0) {
+ return ''
+ }
+ 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
+ let changed = true
+ while (changed && iterations < MAX_ITERATIONS) {
+ changed = false
+ iterations++
+ try {
+ for (const g of group) {
+ for (const ele of g.fields) {
+ if (!ele.formula || ele.formula == '' || ele.formula.startsWith('From')) continue
+ let formula = ele.formula
+ let formulas = formula.split('|')
+ let formulaVal = ''
+ formulas.forEach(f => {
+ let value = ''
+ if (f.charAt(0) === 'p') {
+ let o = findFieldInGroup(f, group, 'p')
+ value = o.value || 0
+ } else if (f.charAt(0) === 'e') {
+ let o = findFieldInGroup(f, group, 'e')
+ value = o.value || 0
+ } else if (f.charAt(0) === '<' || f.charAt(0) === '>') {
+ value = "'" + f + "'"
+ } else {
+ value = f
+ }
+
+ formulaVal += value
+ })
+
+ let v = ''
+ if (formulaVal.startsWith('Get_')) {
+ //计算公式为Get开头的,都是执行方法,只有人工配料才执行
+ if (taskIngredientsWay !== 'manual') continue
+ v = eval(formulaVal)
+ } else if (formulaVal.startsWith('GetFrom')) {
+ v = evaluateGetFromFormula(formulaVal, false, externalFormData)
+ } else {
+ v = math.evaluate(formulaVal).toString()
+ v = isFinite(v) ? v.toString() : 0
+ }
+ ele.value = handleRoundFiveNumber(v, ele.decimalPosition, ele.type === 'project')
+ changed = true
+ }
+ }
+ } catch (error) {
+ console.log(error)
+ }
+ }
+}
+
+// parse: 是否解析公式
+export function evaluateGetFromFormula(formula, parse, externalFormData, currentColumn, row, dynamicsColumns) {
+ let formulaVal = formula
+ if (parse) {
+ formulaVal = parseFormula(formulaVal, row, dynamicsColumns)
+ }
+ let relFormulaVal = formulaVal.split(':')[1]
+ for (const [key, value] of Object.entries(externalFormData)) {
+ if (relFormulaVal.includes(key)) {
+ relFormulaVal = relFormulaVal.replace(key, value || 0)
+ }
+ }
+ try {
+ let v = math.evaluate(relFormulaVal).toString()
+ v = isFinite(v) ? v : 0
+ if (parse) {
+ return handleRoundFiveNumber(v, currentColumn.decimalPosition, currentColumn.type === 'project')
+ }
+ return v
+ } catch (e) {
+ console.warn('GetFrom formula evaluate error:', relFormulaVal, e)
+ return 0
+ }
+}
+// 解析公式
+function parseFormula(formula, row, dynamicsColumns) {
+ let formulas = formula.split('|')
+ let formulaVal = ''
+ formulas.forEach(f => {
+ if (f.charAt(0) === 'p') {
+ let o = dynamicsColumns.find(i => 'p' + i.paramNo === f && i.type !== 'project')
+ const currentColumnData = row[o.fieldIndex]
+ formulaVal += currentColumnData.value ? currentColumnData.value : 0
+ } else if (f.charAt(0) === 'e') {
+ let o = dynamicsColumns.find(i => 'e' + i.paramNo === f)
+ formulaVal += row[o.fieldIndex]?.value ? row[o.fieldIndex].value : 0
+ } else {
+ formulaVal += f
+ }
+ })
+ return formulaVal
+}
+// 根据样品和配置列计算分析值
+export function calcRowAnalysisValue(row, columnObj, dynamicsColumns, externalFormData, taskIngredientsWay) {
+ if (!columnObj.paramNo || !row[columnObj.fieldIndex]) return
+
+ for (let i = 0; i < dynamicsColumns.length; i++) {
+ let curItem = dynamicsColumns[i]
+ if (curItem.fieldIndex === columnObj.fieldIndex) continue
+
+ let param = columnObj.fieldIndex.charAt(0) === 'p' ? 'p' + columnObj.paramNo : 'e' + columnObj.paramNo
+ if (curItem.formula && curItem.formula.includes(param)) {
+ let formula = curItem.formula
+ let formulaVal = parseFormula(formula, row, dynamicsColumns)
+ let v
+ if (formulaVal.startsWith('Get_')) {
+ if (taskIngredientsWay !== 'manual') continue
+ 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 {
+ v = math.evaluate(formulaVal).toString()
+ v = isFinite(v) ? v : 0
+ }
+ let rowObj = row[curItem.fieldIndex]
+ rowObj.value = handleRoundFiveNumber(Number(v), rowObj.decimalPosition, rowObj.type === 'project')
+ calcRowAnalysisValue(row, curItem, dynamicsColumns, externalFormData)
+ }
+ }
+}
+const findFieldInGroup = function (paramNo, group, p) {
+ for (const g of group) {
+ for (const f of g.fields) {
+ if (p === 'p' && f.type == 'project') continue
+ if (p + f.paramNo === paramNo) {
+ return f
+ }
+ }
+ }
+ return { value: null }
+}
+
+/** 处理数值数据:四舍六入奇进偶不进
+ * 1,如果取小数的最后一位为5,5前为奇数进位,为偶不进,五后非零就进一,五后皆零看奇偶,五前为偶应舍去,五前为奇要进一
+ * 2.5后不为0时就入,为0时看5前,奇进偶不进
+ * 3.四舍,六入
+ * 传入数值和保留位数
+ */
+export function handleRoundFiveNumber(number, fixed = 0, useTwoSignificantDigits = false) {
+ if (number == null || number === '' || isNaN(number)) return number
+ if (fixed === -1) return number
+ number = String(number)
+ //可以考虑清掉末尾的0,暂时限制了不会有,因为传入数值,末尾0是去掉的
+ // 保留2位有效数字:小数点后面大于0的才叫有效数字,从小数点后面查找两位有效数字 ,如果末尾的有效数字的位数大于所设置的精度 以及 如果查找的有效数字没有两位的 ,就按照所设置的精度逻辑来计算,两位有效数字的最后 一位是在第几位,就用这个位数充当精度来按照原来精度的逻辑计算,
+ // ===== 新增:按小数点后前两个非零数字确定精度 =====
+ let actualFixed = fixed
+ if (useTwoSignificantDigits) {
+ const numStr = String(number)
+ const dotIndex = numStr.indexOf('.')
+
+ if (dotIndex !== -1) {
+ const decimalPart = numStr.slice(dotIndex + 1)
+ let nonZeroCount = 0
+ let secondNonZeroPos = -1
+
+ for (let i = 0; i < decimalPart.length; i++) {
+ if (decimalPart[i] !== '0') {
+ nonZeroCount++
+ if (nonZeroCount === 2) {
+ secondNonZeroPos = i + 1 // 小数点后第几位(从1开始)
+ break
+ }
+ }
+ }
+
+ // 只有同时满足:
+ // 1. 找到两个非零数字
+ // 2. 第二个的位置 <= 用户指定的 fixed
+ // 才使用该位置作为精度
+ if (secondNonZeroPos !== -1 && secondNonZeroPos <= fixed) {
+ actualFixed = secondNonZeroPos
+ }
+ }
+ }
+ console.log(actualFixed)
+ const index = number.indexOf('.')
+ if (index == -1) {
+ if (actualFixed > 0) {
+ number += '.'
+ }
+ for (let i = 0; i < actualFixed; i++) {
+ number += '0'
+ }
+ //补0返回
+ return number
+ }
+ //取到保留小数位的下一位,5.5555取保留俩位,那就是小数点后第三位
+ const indexFixed = index + actualFixed + 1
+ if (indexFixed >= number.length) {
+ //如果小数位数不够, 补0直接返回
+ const zerolen = indexFixed - number.length
+ for (let i = 0; i < zerolen; i++) {
+ number += '0'
+ }
+ return number
+ }
+ //取保留位数的后一位做判断,以下是有5的判断
+ const endNumber = number.substr(indexFixed, 1)
+ if (endNumber != '5') {
+ //如果做判断的数不是五,就按正常的四舍五入,即忽略了5,后面补0的那些由于是数字传进来,0已经去掉,此处不做处理
+ return Number(number).toFixed(actualFixed)
+ }
+ if (indexFixed != number.length - 1) {
+ //由于当前判断位不是最后一位,而又去除了0,那么后面后的位数应该直接入位,五后不为0时入,由于会有小于五的,四舍五入肯定不行,那么只能截取到当前保留位数,然后转成数字加上10的负fixed的次方即可
+ number = number.substring(0, indexFixed)
+ if (number.indexOf('-') != -1) {
+ //需要考虑到负数的情况
+ return (Number(number) - Number(Math.pow(10, -actualFixed))).toFixed(actualFixed)
+ }
+ return (Number(number) + Number(Math.pow(10, -actualFixed))).toFixed(actualFixed)
+ //return this.accAdd(number,Math.pow(10,-fixed))
+ }
+ //接下来就时五后没有值也就是0的需要看前面的奇入偶不入了,取当前位的上一位
+ let twoNumber = number.substr(indexFixed - 1, 1)
+ if (twoNumber == '.') {
+ //取到小数点,再取一次,要取到小数点左边第一位
+ twoNumber = number.substr(indexFixed - 2, 1)
+ }
+ if ('13579'.indexOf(twoNumber) != -1) {
+ //奇进
+ number = number.substring(0, indexFixed)
+ if (number.indexOf('-') != -1) {
+ //需要考虑到负数的情况
+ return (Number(number) - Math.pow(10, -actualFixed)).toFixed(actualFixed)
+ }
+ return (Number(number) + Math.pow(10, -actualFixed)).toFixed(actualFixed)
+ }
+ //偶不进,将取值的当前位数,直接截取字符即可
+ return number.substr(0, indexFixed)
+}
+
+/**
+ ** 除法函数,用来得到精确的除法结果
+ ** 说明:javascript的除法结果会有误差,在两个浮点数相除的时候会比较明显。这个函数返回较为精确的除法结果。
+ ** 调用:accDiv(arg1,arg2)
+ ** 返回值:arg1除以arg2的精确结果
+ **/
+function accDiv(arg1, arg2) {
+ var t1 = 0,
+ t2 = 0,
+ r1,
+ r2
+ try {
+ t1 = arg1.toString().split('.')[1].length
+ } catch (e) {}
+ try {
+ t2 = arg2.toString().split('.')[1].length
+ } catch (e) {}
+ r1 = Number(arg1.toString().replace('.', ''))
+ r2 = Number(arg2.toString().replace('.', ''))
+ return (r1 / r2) * pow(10, t2 - t1)
+}
+
+/**
+ ** 乘法函数,用来得到精确的乘法结果
+ ** 说明:javascript的乘法结果会有误差,在两个浮点数相乘的时候会比较明显。这个函数返回较为精确的乘法结果。
+ ** 调用:accMul(arg1,arg2)
+ ** 返回值:arg1乘以 arg2的精确结果
+ **/
+function accMul(arg1, arg2) {
+ var m = 0,
+ s1 = arg1.toString(),
+ s2 = arg2.toString()
+ try {
+ m += s1.split('.')[1].length
+ } catch (e) {}
+ try {
+ m += s2.split('.')[1].length
+ } catch (e) {}
+ return (Number(s1.replace('.', '')) * Number(s2.replace('.', ''))) / Math.pow(10, m)
+}
+
+/**
+ ** 减法函数,用来得到精确的减法结果
+ ** 说明:javascript的减法结果会有误差,在两个浮点数相减的时候会比较明显。这个函数返回较为精确的减法结果。
+ ** 调用:accSub(arg1,arg2)
+ ** 返回值:arg1加上arg2的精确结果
+ **/
+function accSub(arg1, arg2) {
+ var r1, r2, m, n
+ try {
+ r1 = arg1.toString().split('.')[1].length
+ } catch (e) {
+ r1 = 0
+ }
+ try {
+ r2 = arg2.toString().split('.')[1].length
+ } catch (e) {
+ r2 = 0
+ }
+ m = Math.pow(10, Math.max(r1, r2)) //last modify by deeka //动态控制精度长度
+ n = r1 >= r2 ? r1 : r2
+ return ((arg1 * m - arg2 * m) / m).toFixed(n)
+}
+
+/**
+ ** 加法函数,用来得到精确的加法结果
+ ** 说明:javascript的加法结果会有误差,在两个浮点数相加的时候会比较明显。这个函数返回较为精确的加法结果。
+ ** 调用:accAdd(arg1,arg2)
+ ** 返回值:arg1加上arg2的精确结果
+ **/
+function accAdd(arg1, arg2) {
+ var r1, r2, m, c
+ try {
+ r1 = arg1.toString().split('.')[1].length
+ } catch (e) {
+ r1 = 0
+ }
+ try {
+ r2 = arg2.toString().split('.')[1].length
+ } catch (e) {
+ r2 = 0
+ }
+ c = Math.abs(r1 - r2)
+ m = Math.pow(10, Math.max(r1, r2))
+ if (c > 0) {
+ var cm = Math.pow(10, c)
+ if (r1 > r2) {
+ arg1 = Number(arg1.toString().replace('.', ''))
+ arg2 = Number(arg2.toString().replace('.', '')) * cm
+ } else {
+ arg1 = Number(arg1.toString().replace('.', '')) * cm
+ arg2 = Number(arg2.toString().replace('.', ''))
+ }
+ } else {
+ arg1 = Number(arg1.toString().replace('.', ''))
+ arg2 = Number(arg2.toString().replace('.', ''))
+ }
+ return (arg1 + arg2) / m
+}
+
+// 通过配置项分组
+export function groupByField(list, cupNumFieldIndex, groupKey = 'groupDictionaryBusinessKey') {
+ const groupMap = new Map()
+
+ // 插入“全部”项
+ list.unshift({ groupDictionaryBusinessKey: 'all', groupDictionaryBusinessName: '全部' })
+
+ for (const item of list) {
+ // 赋值杯号 fieldIndex
+ if (item.title === '杯号') {
+ cupNumFieldIndex.value = item.fieldIndex
+ }
+
+ let key = item[groupKey]
+
+ // 如果没有有效 key,统一归入自定义分组
+ if (!key) {
+ key = 'customParameter' // 使用固定字符串作为无 key 项的分组标识
+ }
+
+ // 如果该分组不存在,初始化
+ if (!groupMap.has(key)) {
+ groupMap.set(key, {
+ value: key,
+ label: key === 'customParameter' ? '分析项目' : item.groupDictionaryBusinessName || '未知分组',
+ fields: []
+ })
+ }
+
+ // 将当前项加入对应分组
+ groupMap.get(key).fields.push(item)
+ }
+
+ return Array.from(groupMap.values())
+}
+
+export function validateElementRange(fieldIndex, row, conRangeElementAnalysisList) {
+ if (!conRangeElementAnalysisList?.length) return null
+ const rangeElementAnalysis = conRangeElementAnalysisList.find(
+ ele => ele.dictionaryProjectId === row[fieldIndex]?.dicId && row[fieldIndex]['type'] === 'project'
+ )
+
+ if (!rangeElementAnalysis) return null
+
+ const val = row[fieldIndex]?.value
+
+ if (val == '' || val == null) return null
+ const value = Number(val)
+
+ let result = { promptType: '', promptMsg: '' }
+
+ switch (Number(rangeElementAnalysis.rangeType)) {
+ case 1:
+ //如果值小于最小警告值或者大于最大警告值,则校验不通过
+ if (value < rangeElementAnalysis.minimumWarningValue || value > rangeElementAnalysis.maximumWarningValue) {
+ result.promptType = 'warning'
+ result.promptMsg = `警告:值超出范围(${rangeElementAnalysis.minimumWarningValue} ~ ${rangeElementAnalysis.maximumWarningValue})`
+ }
+ break
+ case 2:
+ //如果值小于最小限制值或者大于最大限制值,则校验不通过
+ if (value < rangeElementAnalysis.minimumValue || value > rangeElementAnalysis.maximumValue) {
+ result.promptType = 'error'
+ result.promptMsg = `错误:值超出范围(${rangeElementAnalysis.minimumValue} ~ ${rangeElementAnalysis.maximumValue})`
+ }
+ break
+ case 3:
+ //如果值小于最小限制值或者大于最大限制值,则校验不通过
+ if (value < rangeElementAnalysis.minimumValue || value > rangeElementAnalysis.maximumValue) {
+ result.promptType = 'error'
+ result.promptMsg = `错误:值超出范围(${rangeElementAnalysis.minimumValue} ~ ${rangeElementAnalysis.maximumValue})`
+ } else if (
+ (rangeElementAnalysis.minimumValue < value && value < rangeElementAnalysis.minimumWarningValue) ||
+ (rangeElementAnalysis.maximumWarningValue < value && value <= rangeElementAnalysis.maximumValue)
+ ) {
+ result.promptType = 'warning'
+ result.promptMsg = `警告:值超出范围(${rangeElementAnalysis.minimumWarningValue} ~ ${rangeElementAnalysis.maximumWarningValue})`
+ }
+ break
+ default:
+ return null
+ }
+
+ return result
+}
diff --git a/pages/analysis/sample/sample-work-detail.vue b/pages/analysis/sample/sample-work-detail.vue
index f41d47f..79d82b1 100644
--- a/pages/analysis/sample/sample-work-detail.vue
+++ b/pages/analysis/sample/sample-work-detail.vue
@@ -674,7 +674,7 @@ const saveDetail = async () => {
if (item.calcMethod === 'calculateAverageValue') {
item.value = calcAverageValue(sourceKey, currentAssayType.value.tableData)
} else {
- item.value = handleRoundFiveNumber(row[sourceKey].value, row.decimalPosition, row.type === 'project')
+ item.value = handleRoundFiveNumber(row[sourceKey].value, row.decimalPosition)
}
// 如果处理后的值不为空,重新赋值该字段到其他样品类型下的样品上,并触发每一个样品的计算
for (const col of currentAssayType.value.columns) {
@@ -707,10 +707,9 @@ const saveDetail = async () => {
function calcAverageValue(fieldIndex, tableData) {
const rows = tableData.map(row => row[fieldIndex])
const decimalPosition = rows[0].decimalPosition
- const isProject = rows[0].type === 'project'
const values = rows.map(row => Number(row.value))
if (values.some(item => item == null)) return null
- return handleRoundFiveNumber(math.mean(values), decimalPosition, isProject)
+ return handleRoundFiveNumber(math.mean(values), decimalPosition)
}
// 表格数据更新后重新计算
@@ -1110,13 +1109,12 @@ const listenNumKeyboard = () => {
}
//自动补全小数位数
const decimalPosition = selectedField.value.decimalPosition
- const isProject = selectedField.value.type === 'project'
let val = res.val
const symbol = res.symbol
if (decimalPosition == null) {
selectedField.value.value = val
} else {
- selectedField.value.value = handleRoundFiveNumber(val, decimalPosition, isProject)
+ selectedField.value.value = handleRoundFiveNumber(val, decimalPosition)
}
if (symbol) {
selectedField.value.symbol = symbol
diff --git a/pages/analysis/sample/sample-work-detail.vue.bak b/pages/analysis/sample/sample-work-detail.vue.bak
new file mode 100644
index 0000000..f41d47f
--- /dev/null
+++ b/pages/analysis/sample/sample-work-detail.vue.bak
@@ -0,0 +1,1515 @@
+
+
+
+
+ 填写任务单
+
+
+
+
+
+
+
+
+
+
+
+ {{ currentSampleData.sampleCode }}
+ 数据采集或录入
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ sample.sampleCode }}
+
+ {{ sample.sampleName }}
+
+
+
+
+
+ 自动配料
+ 人工配料
+
+
+ 数据上报
+ 等待配料
+
+
+ 数据上报
+
+
+
+
+
+
+
+
+
+ {{ currentAuncel.code }}
+ 杯号:{{ currentCupNum }}
+
+
+
+ {{ currentAuncel.weightData }}
+
+
+ {{ currentAuncel.weightUnit }}
+
+
+
+
+ 确认采集
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ fields.label }}
+
+
+
+
+
+
+
+ {{
+ !field.fillingWay || field.fillingWay == 'calculate'
+ ? '计算值'
+ : field.fillingWay == 'datetime'
+ ? '请选择时间'
+ : '请输入'
+ }}
+ {{ field.symbol }}{{ field.value }}
+
+
+
+ {{ field.validation?.promptMsg }}
+
+
+
+
+
+
+ 保存样品数据
+
+
+
+
+
+
+
+
+
+
+
+