diff --git a/components/checkbox-switch/checkbox-switch.vue b/components/checkbox-switch/checkbox-switch.vue new file mode 100644 index 0000000..6f10dcf --- /dev/null +++ b/components/checkbox-switch/checkbox-switch.vue @@ -0,0 +1,73 @@ + + + + + + diff --git a/components/da-tree/index.vue b/components/da-tree/index.vue index c264fdc..a4bc692 100644 --- a/components/da-tree/index.vue +++ b/components/da-tree/index.vue @@ -49,7 +49,8 @@ class="da-tree-item__label" :class="'da-tree-item__label--' + item.checkedStatus" @click="handleLabelClick(item)" - >{{ item.label }} {{ item.append }}{{ item.label }} {{ item.append }} @@ -1154,8 +1155,8 @@ export default defineComponent({ flex: 1; margin-left: 2px; color: #555; - display: flex; - flex-direction: column; + display: flex; + flex-direction: column; &--2 { color: var(--theme-color, #007aff); diff --git a/components/sample/auncel-select-popup.vue b/components/sample/auncel-select-popup.vue index 470ceda..42b2e1a 100644 --- a/components/sample/auncel-select-popup.vue +++ b/components/sample/auncel-select-popup.vue @@ -86,8 +86,7 @@ const getPageData = () => { pageNo: 1, pageSize: 999, collectDeviceType: 'balance', - deviceStatus: '0', - isEnable: '1', + deviceStatus: "{\"Enable\":\"1\"}", deployLocation: deployLocation.value === '全部' ? '' : deployLocation.value }) .then(res => { diff --git a/components/zzjc-num-keyboard/zzjc-num-keyboard.vue b/components/zzjc-num-keyboard/zzjc-num-keyboard.vue index 30ea2f0..93014af 100644 --- a/components/zzjc-num-keyboard/zzjc-num-keyboard.vue +++ b/components/zzjc-num-keyboard/zzjc-num-keyboard.vue @@ -125,13 +125,13 @@ const changeNums = (item, index) => { } // 检查小数位数限制 - let decimal = props.numKeyboardParam?.decimal ?? -1 - const parts = nums.value.split('.') - if (parts.length === 2 && decimal !== -1) { - if (parts[1].length >= decimal) { - return false - } - } + // let decimal = props.numKeyboardParam?.decimal ?? -1 + // const parts = nums.value.split('.') + // if (parts.length === 2 && decimal !== -1) { + // if (parts[1].length >= decimal) { + // return false + // } + // } nums.value += inputChar } diff --git a/defaultBaseUrl.js b/defaultBaseUrl.js index e048450..179ca34 100644 --- a/defaultBaseUrl.js +++ b/defaultBaseUrl.js @@ -1,14 +1,15 @@ // 在此不用配置接口前缀 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.253:48080/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.163:48080/admin-api' : 'http://192.168.26.116:888/admin-api' +// 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/manifest.json b/manifest.json index b7336a2..0bc9b69 100644 --- a/manifest.json +++ b/manifest.json @@ -1,31 +1,31 @@ { - "name" : "实验室管理系统", - "appid" : "__UNI__4B3B4B0", - "description" : "实验室管理系统", - "versionName" : "1.1.2", - "versionCode" : 112, - "transformPx" : false, - "app-plus" : { - "usingComponents" : true, - "nvueCompiler" : "uni-app", - "compilerVersion" : 3, - "splashscreen" : { - "alwaysShowBeforeRender" : true, - "waiting" : true, - "autoclose" : true, - "delay" : 0 + "name": "实验室管理系统", + "appid": "__UNI__4B3B4B0", + "description": "实验室管理系统", + "versionName": "1.1.6", + "versionCode": 116, + "transformPx": false, + "app-plus": { + "usingComponents": true, + "nvueCompiler": "uni-app", + "compilerVersion": 3, + "splashscreen": { + "alwaysShowBeforeRender": true, + "waiting": true, + "autoclose": true, + "delay": 0 }, - "modules" : { - "LivePusher" : {}, - "Camera" : {} + "modules": { + "LivePusher": {}, + "Camera": {} }, - "distribute" : { - "android" : { - "packagename" : "tech.zzjc.mas.zgtylims", - "keystore" : "zzjc_android.jks", - "password" : "zzjc@20190226", - "aliasname" : "app", - "permissions" : [ + "distribute": { + "android": { + "packagename": "tech.zzjc.mas.zgtylims", + "keystore": "zzjc_android.jks", + "password": "zzjc@20190226", + "aliasname": "app", + "permissions": [ "", "", "", @@ -50,155 +50,158 @@ "" ] }, - "ios" : { - "dSYMs" : false + "ios": { + "dSYMs": false }, - "harmony" : { - "permissions" : [ "ohos.permission.INTERNET", "ohos.permission.GET_NETWORK_INFO" ], - "package" : "zzjc.test.app", - "compatibleSdkVersion" : 5 + "harmony": { + "permissions": [ + "ohos.permission.INTERNET", + "ohos.permission.GET_NETWORK_INFO" + ], + "package": "zzjc.test.app", + "compatibleSdkVersion": 5 }, - "sdkConfigs" : {}, - "icons" : { - "android" : { - "hdpi" : "unpackage/res/icons/72x72.png", - "xhdpi" : "unpackage/res/icons/96x96.png", - "xxhdpi" : "unpackage/res/icons/144x144.png", - "xxxhdpi" : "unpackage/res/icons/192x192.png" + "sdkConfigs": {}, + "icons": { + "android": { + "hdpi": "unpackage/res/icons/72x72.png", + "xhdpi": "unpackage/res/icons/96x96.png", + "xxhdpi": "unpackage/res/icons/144x144.png", + "xxxhdpi": "unpackage/res/icons/192x192.png" }, - "ios" : { - "appstore" : "unpackage/res/icons/1024x1024.png", - "ipad" : { - "app" : "unpackage/res/icons/76x76.png", - "app@2x" : "unpackage/res/icons/152x152.png", - "notification" : "unpackage/res/icons/20x20.png", - "notification@2x" : "unpackage/res/icons/40x40.png", - "proapp@2x" : "unpackage/res/icons/167x167.png", - "settings" : "unpackage/res/icons/29x29.png", - "settings@2x" : "unpackage/res/icons/58x58.png", - "spotlight" : "unpackage/res/icons/40x40.png", - "spotlight@2x" : "unpackage/res/icons/80x80.png" + "ios": { + "appstore": "unpackage/res/icons/1024x1024.png", + "ipad": { + "app": "unpackage/res/icons/76x76.png", + "app@2x": "unpackage/res/icons/152x152.png", + "notification": "unpackage/res/icons/20x20.png", + "notification@2x": "unpackage/res/icons/40x40.png", + "proapp@2x": "unpackage/res/icons/167x167.png", + "settings": "unpackage/res/icons/29x29.png", + "settings@2x": "unpackage/res/icons/58x58.png", + "spotlight": "unpackage/res/icons/40x40.png", + "spotlight@2x": "unpackage/res/icons/80x80.png" }, - "iphone" : { - "app@2x" : "unpackage/res/icons/120x120.png", - "app@3x" : "unpackage/res/icons/180x180.png", - "notification@2x" : "unpackage/res/icons/40x40.png", - "notification@3x" : "unpackage/res/icons/60x60.png", - "settings@2x" : "unpackage/res/icons/58x58.png", - "settings@3x" : "unpackage/res/icons/87x87.png", - "spotlight@2x" : "unpackage/res/icons/80x80.png", - "spotlight@3x" : "unpackage/res/icons/120x120.png" + "iphone": { + "app@2x": "unpackage/res/icons/120x120.png", + "app@3x": "unpackage/res/icons/180x180.png", + "notification@2x": "unpackage/res/icons/40x40.png", + "notification@3x": "unpackage/res/icons/60x60.png", + "settings@2x": "unpackage/res/icons/58x58.png", + "settings@3x": "unpackage/res/icons/87x87.png", + "spotlight@2x": "unpackage/res/icons/80x80.png", + "spotlight@3x": "unpackage/res/icons/120x120.png" } } } }, /* 可选,JSON对象,应用UserAgent相关配置 **/ - "useragent" : { + "useragent": { /* 可选,字符串类型,设置的默认userAgent值 */ - "value" : "LIMS-PDA/1.1.2", + "value": "LIMS-PDA/1.1.6", /* 可选,Boolean类型,是否将value值作为追加值连接到系统默认userAgent值之后 */ - "concatenate" : true + "concatenate": true }, /* 可选,JSON对象,Android平台应用UserAgent相关配置,优先级高于useragent配置 */ - "useragent_android" : { + "useragent_android": { /* 可选,字符串类型,设置的默认userAgent值 */ - "value" : "LIMS-PDA/1.1.2", + "value": "LIMS-PDA/1.1.6", /* 可选,Boolean类型,是否将value值作为追加值连接到系统默认userAgent值之后 */ - "concatenate" : true + "concatenate": true }, /* 可选,JSON对象,iOS平台应用UserAgent相关配置,优先级高于useragent配置 */ - "useragent_ios" : { + "useragent_ios": { /* 可选,字符串类型,设置的默认userAgent值 */ - "value" : "LIMS-PDA/1.1.2", + "value": "LIMS-PDA/1.1.6", /* 可选,Boolean类型,是否将value值作为追加值连接到系统默认userAgent值之后 */ - "concatenate" : true + "concatenate": true } }, - "quickapp" : {}, - "mp-weixin" : { - "appid" : "", - "setting" : { - "urlCheck" : false, - "minified" : false + "quickapp": {}, + "mp-weixin": { + "appid": "", + "setting": { + "urlCheck": false, + "minified": false }, - "optimization" : { - "subPackages" : true + "optimization": { + "subPackages": true }, - "usingComponents" : true, - "mergeVirtualHostAttributes" : true + "usingComponents": true, + "mergeVirtualHostAttributes": true }, - "mp-alipay" : { - "usingComponents" : true + "mp-alipay": { + "usingComponents": true }, - "mp-baidu" : { - "usingComponents" : true + "mp-baidu": { + "usingComponents": true }, - "mp-toutiao" : { - "usingComponents" : true + "mp-toutiao": { + "usingComponents": true }, - "uniStatistics" : { - "enable" : false + "uniStatistics": { + "enable": false }, - "vueVersion" : "3", - "h5" : { - "devServer" : { - "port" : 33888, - "https" : false, - "proxy" : { - "/api" : { + "vueVersion": "3", + "h5": { + "devServer": { + "port": 33888, + "https": false, + "proxy": { + "/api": { // "target" : "http://mas.new.will-way.cn/api/", //"target" : "http://192.168.31.180:9090/", - "target" : "http://127.0.0.1:9999/", - "changeOrigin" : true, - "ws" : true, - "pathRewrite" : { - "^/api" : "" + "target": "http://127.0.0.1:9999/", + "changeOrigin": true, + "ws": true, + "pathRewrite": { + "^/api": "" } }, - "/sys" : { + "/sys": { // "target" : "http://mas.new.will-way.cn/api/", //"target" : "http://192.168.31.180:9090/", - "target" : "http://127.0.0.1:9999/sys", - "changeOrigin" : true, - "ws" : true, - "pathRewrite" : { - "^/api" : "" + "target": "http://127.0.0.1:9999/sys", + "changeOrigin": true, + "ws": true, + "pathRewrite": { + "^/api": "" } }, - "/report" : { - "target" : "http://127.0.0.1:9999/report/", - "changeOrigin" : true, - "ws" : true, - "pathRewrite" : { - "^/api" : "" + "/report": { + "target": "http://127.0.0.1:9999/report/", + "changeOrigin": true, + "ws": true, + "pathRewrite": { + "^/api": "" } } } }, - "optimization" : { - "treeShaking" : { - "enable" : true + "optimization": { + "treeShaking": { + "enable": true } }, - "router" : { - "base" : "./" + "router": { + "base": "./" }, - "template" : "template.h5.html" + "template": "template.h5.html" }, - "app-harmony" : { - "distribute" : { - "bundleName" : "zzjc.test.app", - "signingConfigs" : { - "default" : { - "certpath" : "certs\\DebugCert.cer", - "keyAlias" : "zzjc-test", - "keyPassword" : "0000001A62465932FE19E037517BC61FE03A8F9D69CB7892019EEC82A5A07691ECAE824A92BAD8FAEB34", - "profile" : "certs\\DebugProfileDebug.p7b", - "signAlg" : "SHA256withECDSA", - "storeFile" : "certs\\.p12", - "storePassword" : "0000001ACE8F050DA6F2E36A4D0EC332ECF3A78E16F485E7C0B9DA5919649626428710609023E1DD99FD" + "app-harmony": { + "distribute": { + "bundleName": "zzjc.test.app", + "signingConfigs": { + "default": { + "certpath": "certs\\DebugCert.cer", + "keyAlias": "zzjc-test", + "keyPassword": "0000001A62465932FE19E037517BC61FE03A8F9D69CB7892019EEC82A5A07691ECAE824A92BAD8FAEB34", + "profile": "certs\\DebugProfileDebug.p7b", + "signAlg": "SHA256withECDSA", + "storeFile": "certs\\.p12", + "storePassword": "0000001ACE8F050DA6F2E36A4D0EC332ECF3A78E16F485E7C0B9DA5919649626428710609023E1DD99FD" } } } } -} +} \ No newline at end of file diff --git a/nx/api/dailyCheck.js b/nx/api/dailyCheck.js index 9e37fff..1782565 100644 --- a/nx/api/dailyCheck.js +++ b/nx/api/dailyCheck.js @@ -32,7 +32,7 @@ export default { request({ url: '/qms/resource/device-maintain/getLastDailyCheckOfToday', method: 'GET', - params, + params }), createDailyCheck: data => request({ diff --git a/nx/api/deviceInfo.js b/nx/api/deviceInfo.js index ccb017c..73c6ad3 100644 --- a/nx/api/deviceInfo.js +++ b/nx/api/deviceInfo.js @@ -2,21 +2,21 @@ import request from '@/nx/request' export function getDeviceBusInfoById(id) { return request({ - url: '/lims/bus/deviceBusInfo/queryById', + url: '/qms/resource/device-infomation/get', method: 'GET', params: { id } }) } export function deviceList(params) { return request({ - url: '/lims/bus/deviceBusInfo/list', + url: '/qms/resource/device-infomation/page', method: 'GET', params }) } export function treeData(params) { return request({ - url: '/lims/bus/deviceBusProduct/listTree', + url: '/qms/resource/device-product/getProductTreeData', method: 'GET', params }) @@ -74,6 +74,3 @@ export function stopList(params) { params }) } -export default{ - getDeviceBusInfoById -} diff --git a/nx/api/material.js b/nx/api/material.js index 1641864..64422e3 100644 --- a/nx/api/material.js +++ b/nx/api/material.js @@ -7,11 +7,79 @@ export default { method: 'GET', params }), + // 查询大类 + queryMaterialCategory: params => + request({ + url: '/qms/resource/material-product/category-data', + method: 'GET', + params + }), + // 查询物料实例 + queryMaterialInformation: params => + request({ + url: '/qms/resource/material-infomation/page', + method: 'GET', + params + }), // 物料出库 execMaterialOut: data => request({ url: '/qms/resource/material-inventory-outbound/add', method: 'POST', data + }), + // 新增使用记录 + addUseRecord: data => + request({ + url: '/qms/resource/material-use-record/add', + method: 'POST', + data + }), + // 删除使用记录 + deleteUseRecord: params => + request({ + url: '/qms/resource/material-use-record/delete', + method: 'DELETE', + params + }), + getUseRecord: params => + request({ + url: '/qms/resource/material-use-record/page', + method: 'GET', + params + }), + // 使用确认 + confirmUseRecord: data => + request({ + url: '/qms/resource/material-use-record/review', + method: 'PUT', + data + }), + // 新增危化品配置信息 + addHazardousMake: data => + request({ + url: '/qms/resource/material-use-record/hzrd-make', + method: 'POST', + data + }), + // 新增用完标记和清洗回收 + addUseOver: data => + request({ + url: '/qms/resource/material-use-end-reuse/add', + method: 'POST', + data + }), + getMaterialUseEndReuseDetailPage: params => + request({ + url: `/qms/resource/material-use-end-reuse-detail/page`, + method: 'GET', + params + }), + // 试剂瓶回收 + reuse: data => + request({ + url: '/qms/resource/material-use-end-reuse/reuse', + method: 'PUT', + data }) } diff --git a/nx/api/sampleWarehouse.js b/nx/api/sampleWarehouse.js index 91e2135..864cf36 100644 --- a/nx/api/sampleWarehouse.js +++ b/nx/api/sampleWarehouse.js @@ -79,9 +79,10 @@ export default { data }), // 根据权限查询样品库 - querySampleLocation: () => + querySampleLocation: params => request({ url: '/qms/config-warehouse-location/selectListWithPermission', - method: 'GET' + method: 'GET', + params }) } diff --git a/nx/api/sys.js b/nx/api/sys.js index 1dfd3d8..f50c87b 100644 --- a/nx/api/sys.js +++ b/nx/api/sys.js @@ -35,5 +35,11 @@ export default { isTransformResponse: false } }) + }, + getDataListByCategoryKey: key => { + return request({ + url: `/qms/dictionary-business/getDataListByCategoryKey?key=` + key, + method: 'GET' + }) } } diff --git a/nx/helper/calcAnalysisValue.js b/nx/helper/calcAnalysisValue.js index fc9145a..77d9990 100644 --- a/nx/helper/calcAnalysisValue.js +++ b/nx/helper/calcAnalysisValue.js @@ -327,6 +327,79 @@ export function handleRoundFiveNumber(number, fixed = 0) { //偶不进,将取值的当前位数,直接截取字符即可 return number.substr(0, indexFixed) } +export function handleEfficaciousNumber(number, fixed, effectiveDigit) { + // 1. 先将数字补全到 fixed 位小数 + const numStr = String(number) + const dotIndex = numStr.indexOf('.') // dotIndex = 1 + let actualFixed = fixed // 默认为 fixed + + if (dotIndex !== -1) { + const decimalPart = numStr.slice(dotIndex + 1) // decimalPart = "0400" + console.log(`小数部分: ${decimalPart}`) + + let nonZeroCount = 0 + let targetEffectiveDigitPos = -1 + + // 2. 循环 "0400",寻找有效数字 + for (let i = 0; i < decimalPart.length; i++) { + // i=0 to 3 + const char = decimalPart[i] + console.log(`检查第 ${i + 1} 位: '${char}', 当前 nonZeroCount: ${nonZeroCount}`) + + if (nonZeroCount === 0) { + // 寻找第一个非零数字 + if (char !== '0') { + // i=0, '0' -> false; i=1, '4' -> true + nonZeroCount++ // nonZeroCount = 1 + console.log(` -> 找到第 1 个有效数字: '${char}'`) + } + } else { + // 已经找到第一个非零数字,后续所有数字都算有效 + if (nonZeroCount < effectiveDigit) { + // 1 < 2 -> true + nonZeroCount++ // nonZeroCount = 2 + console.log(` -> 找到第 2 个有效数字: '${char}'`) + } + } + + if (nonZeroCount === effectiveDigit) { + // 2 === 2 -> true when i=2 + targetEffectiveDigitPos = i + 1 // i=2, so pos is 3 + console.log(` -> 目标有效数字 (${effectiveDigit}) 已找到,位于第 ${targetEffectiveDigitPos} 位`) + break + } + } + console.log(`targetEffectiveDigitPos: ${targetEffectiveDigitPos}`) + + // 3. 判断并设置最终精度 + if (targetEffectiveDigitPos !== -1 && targetEffectiveDigitPos <= fixed) { + // 3 !== -1 and 3 <= 4 -> true + actualFixed = targetEffectiveDigitPos // actualFixed = 3 + } + const finalNumber = handleRoundFiveNumber(Number(number), actualFixed) + // 获取整数部分 + const finalIntegerPart = finalNumber.slice(0, dotIndex + 1) // 包含小数点 + const finalDecimalPart = finalNumber.slice(dotIndex + 1) + // 截取指定长度的小数部分 + let truncatedDecimalPart = '' + if (Number(finalDecimalPart) === 0) { + truncatedDecimalPart = finalDecimalPart.substring(0, effectiveDigit) + }else{ + truncatedDecimalPart = finalDecimalPart.substring(0, actualFixed) + } + + + // 拼接最终结果 + let result = finalIntegerPart + truncatedDecimalPart + + // 特殊情况处理:如果截取后小数部分为空,则去掉小数点 + if (actualFixed === 0) { + result = finalIntegerPart.slice(0, -1) // 去掉最后的 "." + } + + return result + } +} /** ** 除法函数,用来得到精确的除法结果 diff --git a/nx/helper/calcAnalysisValue.js.bak b/nx/helper/calcAnalysisValue.js.bak deleted file mode 100644 index a236161..0000000 --- a/nx/helper/calcAnalysisValue.js.bak +++ /dev/null @@ -1,511 +0,0 @@ -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/nx/helper/index.js b/nx/helper/index.js index 3c43f83..6abb065 100644 --- a/nx/helper/index.js +++ b/nx/helper/index.js @@ -1,5 +1,6 @@ import test from './test.js' import { round } from './digit.js' +import dayjs from 'dayjs' /** * @description 如果value小于min,取min;如果value大于max,取max * @param {number} min @@ -741,7 +742,76 @@ function isJsonString(str) { return false } } +/** + * 构造树型结构数据 + * @param {*} data 数据源 + * @param {*} id id字段 默认 'id' + * @param {*} parentId 父节点字段 默认 'parentId' + * @param {*} children 孩子节点字段 默认 'children' + */ +const handleTree = (data, id, parentId, children) => { + if (!Array.isArray(data)) { + console.warn('data must be an array') + return [] + } + const config = { + id: id || 'id', + parentId: parentId || 'parentId', + childrenList: children || 'children' + } + const childrenListMap = {} + const nodeIds = {} + const tree = [] + + for (const d of data) { + const parentId = d[config.parentId] + if (childrenListMap[parentId] == null) { + childrenListMap[parentId] = [] + } + nodeIds[d[config.id]] = d + childrenListMap[parentId].push(d) + } + + for (const d of data) { + const parentId = d[config.parentId] + if (nodeIds[parentId] == null) { + tree.push(d) + } + } + + for (const t of tree) { + adaptToChildrenList(t) + } + + function adaptToChildrenList(o) { + if (childrenListMap[o[config.id]] !== null) { + o[config.childrenList] = childrenListMap[o[config.id]] + } + if (o[config.childrenList]) { + for (const c of o[config.childrenList]) { + adaptToChildrenList(c) + } + } + } + + return tree +} + +function formateToDate(date) { + if (date) { + return dayjs(date).format('YYYY-MM-DD') + } else { + return '' + } +} +function formateToDateTime(date) { + if (date) { + return dayjs(date).format('YYYY-MM-DD HH:mm:ss') + } else { + return '' + } +} export default { range, getPx, @@ -777,5 +847,8 @@ export default { uuid, replacer, reviver, - isJsonString + isJsonString, + handleTree, + formateToDate, + formateToDateTime } diff --git a/nx/hooks/usePageListData.js b/nx/hooks/usePageListData.js index 67a6841..33346d7 100644 --- a/nx/hooks/usePageListData.js +++ b/nx/hooks/usePageListData.js @@ -7,7 +7,7 @@ export function useListData({ searchParams, api, needInitListData = false, proce const loadingData = ref(true) const pageParams = reactive({ pageNo: 1, - pageSize: 10 + pageSize: 15 }) const total = ref(0) const loadStatus = ref('loadmore') @@ -16,8 +16,8 @@ export function useListData({ searchParams, api, needInitListData = false, proce // 模拟获取数据的方法 const getListData = async () => { const params = { - ...unref(searchParams), - ...pageParams + ...pageParams, + ...unref(searchParams) } let { list, total: pageTotal } = await api(params) total.value = pageTotal diff --git a/nx/request/index.js b/nx/request/index.js index 4839155..978cf7a 100644 --- a/nx/request/index.js +++ b/nx/request/index.js @@ -74,10 +74,7 @@ http.interceptors.request.use( LoadingInstance.count === 1 && uni.showLoading({ title: config.custom.loadingMsg, - mask: true, - fail: () => { - uni.hideLoading() - } + mask: true }) } config.baseURL = getBaseUrl() diff --git a/nx/utils/call-check-version.js b/nx/utils/call-check-version.js index 35246d7..f07ae03 100644 --- a/nx/utils/call-check-version.js +++ b/nx/utils/call-check-version.js @@ -7,6 +7,10 @@ export default function () { const osName = plus.os.name let appId = plus.runtime.appid appId = clientId + uni.showLoading({ + title: '请求更新中...', + mask: true + }) uni.request({ url: getUpgradeBaseUrl() + @@ -15,6 +19,7 @@ export default function () { '&updatePlatform=android', method: 'GET', success: res => { + uni.hideLoading() console.log(res) const data = res.data.data diff --git a/pages.json b/pages.json index 56f0bf5..ebc3dbb 100644 --- a/pages.json +++ b/pages.json @@ -309,6 +309,41 @@ "navigationStyle": "custom" } }, + { + "path": "pages/material/useRecord/index", + "style": { + "navigationBarTitleText": "使用记录", + "navigationStyle": "custom" + } + }, + { + "path": "pages/material/useRecord/useConfirm", + "style": { + "navigationBarTitleText": "使用确认", + "navigationStyle": "custom" + } + }, + { + "path": "pages/material/useUpMark/index", + "style": { + "navigationBarTitleText": "用完标记", + "navigationStyle": "custom" + } + }, + { + "path": "pages/material/recycle/index", + "style": { + "navigationBarTitleText": "回收", + "navigationStyle": "custom" + } + }, + { + "path": "pages/material/wash/index", + "style": { + "navigationBarTitleText": "清洗", + "navigationStyle": "custom" + } + }, { "path": "pages/setting/UrlConfig", "style": { @@ -382,7 +417,10 @@ "navigationBarTextStyle": "white", "navigationBarTitleText": "lims", "navigationBarBackgroundColor": "#0055A2", - "backgroundColor": "#F8F8F8" + "backgroundColor": "#F8F8F8", + "app-plus": { + "bounce": "none" // 关闭所有页面的弹性效果 + } }, "tabBar": { "custom": true, diff --git a/pages/analysis/auncel/auncel-status.vue b/pages/analysis/auncel/auncel-status.vue index 28db681..4d3f739 100644 --- a/pages/analysis/auncel/auncel-status.vue +++ b/pages/analysis/auncel/auncel-status.vue @@ -99,8 +99,7 @@ function getPageData() { pageNo: 1, pageSize: 999, collectDeviceType: 'balance', - deviceStatus: '0', - isEnable: '1', + deviceStatus: "{\"Enable\":\"1\"}", deployLocation: deployLocation.value === '全部' ? '' : deployLocation.value }) .then(res => { diff --git a/pages/analysis/sample/sample-work-detail.vue b/pages/analysis/sample/sample-work-detail.vue index 5f4b722..bbbe53f 100644 --- a/pages/analysis/sample/sample-work-detail.vue +++ b/pages/analysis/sample/sample-work-detail.vue @@ -230,6 +230,7 @@ import request from '@/nx/request' import { calcAnalysisValue, handleRoundFiveNumber, + handleEfficaciousNumber, calcRowAnalysisValue, evaluateGetFromFormula, math, @@ -655,6 +656,7 @@ const saveAuncelData = () => { }, 100) } let dynamicFormData = reactive({}) + const saveDetail = async () => { //检查杯号 if (!checkBh()) return @@ -677,7 +679,14 @@ const saveDetail = async () => { if (item.calcMethod === 'calculateAverageValue') { item.value = calcAverageValue(sourceKey, currentAssayType.value.tableData) } else { - item.value = handleRoundFiveNumber(row[sourceKey].value, row.decimalPosition) + const rowObj = row[selectedField.value.fieldIndex] + const isProject = rowObj.type === 'project' + const flagValue = handleRoundFiveNumber(row[sourceKey].value, row.decimalPosition) + if (isProject) { + item.value = handleEfficaciousNumber(flagValue, rowObj.decimalPosition, rowObj.effectiveDigit) + } else { + item.value = flagValue + } } // 如果处理后的值不为空,重新赋值该字段到其他样品类型下的样品上,并触发每一个样品的计算 for (const col of currentAssayType.value.columns) { @@ -710,9 +719,16 @@ 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 effectiveDigit = rows[0].effectiveDigit const values = rows.map(row => Number(row.value)) if (values.some(item => item == null)) return null - return handleRoundFiveNumber(math.mean(values), decimalPosition) + const flagValue = handleRoundFiveNumber(math.mean(values), decimalPosition) + if (isProject) { + return handleEfficaciousNumber(flagValue, decimalPosition, effectiveDigit) + } else { + return flagValue + } } // 表格数据更新后重新计算 @@ -1113,12 +1129,19 @@ const listenNumKeyboard = () => { } //自动补全小数位数 const decimalPosition = selectedField.value.decimalPosition + const isProject = selectedField.value.type === 'project' + const effectiveDigit = currentSampleData.value[selectedField.value.fieldIndex]?.effectiveDigit || decimalPosition let val = res.val const symbol = res.symbol if (decimalPosition == null) { selectedField.value.value = val } else { - selectedField.value.value = handleRoundFiveNumber(val, decimalPosition) + const flagValue = handleRoundFiveNumber(val, decimalPosition) + if (isProject) { + selectedField.value.value = handleEfficaciousNumber(flagValue, decimalPosition, effectiveDigit) + } else { + selectedField.value.value = flagValue + } } 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 deleted file mode 100644 index f41d47f..0000000 --- a/pages/analysis/sample/sample-work-detail.vue.bak +++ /dev/null @@ -1,1515 +0,0 @@ - - - - - diff --git a/pages/device/calibrationList/calibration.api.js b/pages/device/calibrationList/calibration.api.js index 357826f..924a5b9 100644 --- a/pages/device/calibrationList/calibration.api.js +++ b/pages/device/calibrationList/calibration.api.js @@ -2,7 +2,7 @@ import request from '@/nx/request' export function list(params) { return request({ - url: '/lims/bus/deviceBusCalibration/queryPageList', + url: '/qms/device-calibration/page', method: 'GET', params }) diff --git a/pages/device/deviceBusInfo/baseInfo.vue b/pages/device/deviceBusInfo/baseInfo.vue index 0ae952a..3da4748 100644 --- a/pages/device/deviceBusInfo/baseInfo.vue +++ b/pages/device/deviceBusInfo/baseInfo.vue @@ -1,7 +1,7 @@ @@ -101,4 +114,7 @@ function handleOpen() { :deep(.uicon-close) { font-size: 22px !important; } +:deep(.u-popup__content__close--top-right) { + top: 30px; +} diff --git a/pages/device/deviceBusUseRecord/index.vue b/pages/device/deviceBusUseRecord/index.vue index 8ea55d3..589904a 100644 --- a/pages/device/deviceBusUseRecord/index.vue +++ b/pages/device/deviceBusUseRecord/index.vue @@ -14,7 +14,12 @@ - + @@ -51,28 +56,49 @@ - 样品类别/个数/任务: - - - - - - {{ useIng ? '结束使用人' : '开始使用人' }}: - - + 检测项目: + 备注: - + - + + + + + + + + + + @@ -98,10 +127,12 @@ import { ref, reactive, onMounted, onUnmounted, watch, toRefs } from 'vue' import { onShow, onLoad } from '@dcloudio/uni-app' import { getDeviceBusInfoById } from '@/nx/api/deviceInfo' -import { getUseRecordById, addUseRecord, editUseRecord } from './useRecord.api' +import { getUseRecordById, addUseRecord, editUseRecord, getDetailList } from './useRecord.api' import dailyCheckApi from '@/nx/api/dailyCheck' import { useScreenOrientation } from '@/nx/hooks/useScreenOrientation' import { useGridCol } from '@/nx/hooks/useGridCol' +import SampleSelectPopup from './SampleSelectPopup.vue' +import StandardSelectPopup from './StandardSelectPopup.vue' import nx from '@/nx' const { gridCol } = useGridCol([700], [6, 4]) @@ -116,53 +147,116 @@ const detailSchema = [ { label: '设备编码', value: 'deviceCode' }, { label: '使用班组', value: 'deptName' } ] +const columns = ref([ + { title: '样品名称', key: 'sampleName', align: 'center' }, + { title: '样品编号', key: 'sampleCode', align: 'center' }, + { title: '操作', key: 'action', width: '100px', align: 'center' } +]) +const tableData = ref([]) + +const sampleSelectPopupRef = ref() +const standardSelectPopupRef = ref() +function handleSelect(type) { + if (type === 'sample') { + sampleSelectPopupRef.value.show() + } else { + standardSelectPopupRef.value.show() + } +} +function handleSampleSelect(dataList, type) { + const transformData = newData => { + if (type === 'sample') { + return { + id: newData.id, + detailType: 'sample', + sampleCode: newData.sampleCode, + sampleName: newData.sampleName, + taskNo: newData.taskNo, + taskId: newData.businessAssayTaskId + } + } else { + return { + id: newData.id, + detailType: 'standard', + sampleCode: newData.code, + sampleName: newData.name + } + } + } + + for (const newData of dataList) { + const index = tableData.value.findIndex(item => item.id === newData.id) + const transformedItem = transformData(newData) + + if (index > -1) { + // 找到匹配的项,直接替换 + tableData.value[index] = transformedItem + } else { + // 没有找到匹配的项,添加到末尾 + tableData.value.push(transformedItem) + } + } +} + +function handleDelete(row) { + tableData.value = tableData.value.filter(item => item.id !== row.id) +} const pageLoading = ref(false) const userId = nx.$store('user').userInfo['id'] const userName = nx.$store('user').userInfo['realname'] let detailInfo = ref({}) -const { scanQRInfo } = toRefs(nx.$store('biz')) -watch(scanQRInfo, newVal => { - if (newVal && nx.$router.getCurrentPage().route == 'pages/device/deviceBusUseRecord/index') { - try { - const codeObj = JSON.parse(newVal) - if (!pageLoading.value) { - getLastDailyCheckOfToday(codeObj.id) - } - scanQRInfo.value = '' - } catch (error) { - scanQRInfo.value = '' - uni.showToast({ - title: '请扫描设备码', - icon: 'none' - }) - } - } -}) -onShow(() => { - scanQRInfo.value = '' -}) +// const { scanQRInfo } = toRefs(nx.$store('biz')) +// watch(scanQRInfo, newVal => { +// if (newVal && nx.$router.getCurrentPage().route == 'pages/device/deviceBusUseRecord/index') { +// try { +// const codeObj = JSON.parse(newVal) +// if (!pageLoading.value) { +// getLastDailyCheckOfToday(codeObj.id) +// } +// scanQRInfo.value = '' +// } catch (error) { +// scanQRInfo.value = '' +// uni.showToast({ +// title: '请扫描设备码', +// icon: 'none' +// }) +// } +// } +// }) +// onShow(() => { +// scanQRInfo.value = '' +// }) +function handleScanResult(result) { + const codeObj = JSON.parse(result) + if (!pageLoading.value) { + getLastDailyCheckOfToday(codeObj.id) + } +} // 检查该设备在使用前是否已经点检过 -function getLastDailyCheckOfToday(id) { +async function getLastDailyCheckOfToday(id) { pageLoading.value = true try { - dailyCheckApi.getLastDailyCheckOfToday({ deviceId: id }).then(async res => { - if (!res || res.submitFlag == '0') { - setTimeout(() => { - uni.showToast({ - title: '设备使用前请先进行设备点检', - icon: 'none' - }) - }, 100) - pageLoading.value = false - nx.$router.go('/pages/device/deviceBusDailyCheck/index', { deviceId: id }) - } else { - getDeviceInfo(id) - await getUseIngRecord(id) - pageLoading.value = false - } - }) + // dailyCheckApi.getLastDailyCheckOfToday({ deviceId: id }).then(async res => { + // if (!res || res.submitFlag == '0') { + // setTimeout(() => { + // uni.showToast({ + // title: '设备使用前请先进行设备点检', + // icon: 'none' + // }) + // }, 100) + // pageLoading.value = false + // nx.$router.go('/pages/device/deviceBusDailyCheck/index', { deviceId: id }) + // } else { + // getDeviceInfo(id) + // await getUseIngRecord(id) + // pageLoading.value = false + // } + // }) + getDeviceInfo(id) + await getUseIngRecord(id) + pageLoading.value = false } catch (error) { pageLoading.value = false } @@ -186,11 +280,17 @@ async function getUseIngRecord(id) { formData.value = res formData.value.userIdEnd = userId formData.value.userNameEnd = userName + getUseRecordDetailList(res.id) + // checkUseStatusIsMySelf(res) } else { useIng.value = false } } +async function getUseRecordDetailList(id) { + const res = await getDetailList({ parentId: id }) + tableData.value = res +} // 定义一个变量,用于标记当前是否有 modal 正在显示 let isModalShowing = false // 如果设备在使用中,检查设备使用记录是否是所登录用户的 @@ -217,8 +317,6 @@ function checkUseStatusIsMySelf(useInfo) { } let formData = ref({ - userName, - userId, stateBefore: '正常' }) @@ -244,15 +342,15 @@ function handleValidate() { }) } } - if (!formData.value.userName) { + if (!formData.value.useItem) { return uni.showToast({ - title: '请输入使用人', + title: '请输入检测项目', icon: 'none' }) } - if (!formData.value.useRemark) { + if (tableData.value.length === 0) { return uni.showToast({ - title: '请输入样品类别/个数/任务', + title: '请选择样品和标准物质', icon: 'none' }) } @@ -266,7 +364,8 @@ async function submitConfirm() { ...formData.value, deviceId: detailInfo.value.id, temperature: formData.value.temperature || '/', - humidity: formData.value.humidity || '/' + humidity: formData.value.humidity || '/', + detailList: tableData.value } // 如果在使用中加入使用结束参数 let currentTime = nx.$dayjs().format('YYYY-MM-DD HH:mm:ss') @@ -288,10 +387,9 @@ async function submitConfirm() { }) } function reset() { - formData.value = { - userName: nx.$store('user').userInfo['realname'] - } + formData.value = {} detailInfo.value = {} + tableData.value = [] } function handleUseRecord() { nx.$store('biz').deviceInfo = detailInfo.value @@ -308,7 +406,8 @@ function handleUseRecord() { background-color: #fff; height: 100%; padding: 16px; - padding-top: 10px; + padding-top: 0px; + padding-bottom: 0px; font-size: 16px; .title { font-size: 22px; diff --git a/pages/device/deviceBusUseRecord/list.vue b/pages/device/deviceBusUseRecord/list.vue index 533fa32..3d3adfb 100644 --- a/pages/device/deviceBusUseRecord/list.vue +++ b/pages/device/deviceBusUseRecord/list.vue @@ -1,8 +1,6 @@