Files
zgty-mas-m/pages/analysis/sample/sample-work-detail.vue
houjunxiang 386f1e7466 1
2025-10-09 18:19:55 +08:00

1435 lines
43 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<view>
<navbar-back :autoBack="false" titleWidth="800" :title="title" @leftClick="customBack">
<view class="navbar-right" @click="navRightClick">
<text>填写指派单</text>
<u-icon color="" name="edit-pen" size="19"></u-icon>
</view>
</navbar-back>
<u-row gutter="8">
<u-col span="3">
<view class="content-title-name">
<text>待化验样品</text>
</view>
<u-gap height="5" bg-color="#0055A2"></u-gap>
</u-col>
<u-col span="6">
<view class="content-title-name">
<view class="current-sample-code">{{ currentSample.sampleCode }}</view>
<view>数据采集或录入</view>
</view>
<u-gap height="5" bg-color="#0055A2"></u-gap>
</u-col>
<u-col span="3">
<view class="content-title-name">
<text>样品详情</text>
</view>
<u-gap height="5" bg-color="#0055A2"></u-gap>
</u-col>
</u-row>
<u-row gutter="8" align="top">
<u-col span="3">
<u-dropdown>
<u-dropdown-item
v-model="curParameterClassify"
:title="curParameterTitle"
height="340px"
:options="optionParameterClassify"
@change="parameterClassifyChange"
></u-dropdown-item>
</u-dropdown>
<scroll-view class="content-left-scroll" scroll-with-animation scroll-y :scroll-top="scrollTop">
<view
v-for="(sample, index) in leftList"
:key="index"
class="u-tab-item"
:class="[current == index ? 'u-tab-item-active' : '']"
:data-current="index"
@tap.stop="switchSample(index, false)"
>
<view class="pr5"> {{ sample.sort }} </view>
<view>
<view>
{{ sample.sampleCode }}
</view>
<view> {{ getDataSourceTypeShow(sample.dataSourceType) }}{{ sample.sampleName }} </view>
</view>
</view>
</scroll-view>
<u-button class="btn-operation" type="primary" @click="submitTask()">提交指派单</u-button>
</u-col>
<u-col span="6">
<view class="field-name" v-html="selectedField.name" />
<zzjc-num-keyboard
ref="myKeyboard"
v-show="selectedField.fillingWay == '1' && selectedField.type != 'select'"
:numKeyboardParam="numKeyboardParam"
></zzjc-num-keyboard>
<view v-if="selectedField.fillingWay == '2'" class="y-f">
<view class="auncel" @click="selectAuncel">
<view class="auncel-title"> {{ currentAuncel.code }}</view>
<view class="auncel-weight">
<view class="weight">
<view
:class="
currentAuncel.weightStable == 0
? 'weight-data-yellow'
: currentAuncel.weightStable == 1
? 'weight-data'
: 'weight-data-warning'
"
>
{{ currentAuncel.weightData }}
</view>
</view>
<view class="weight-unit">{{ currentAuncel.weightUnit }}</view>
</view>
</view>
<u-button
class="btn-operation"
v-if="currentAuncel.code == ''"
type="success"
:disabled="confirmWeightDisabled"
shape="circle"
@click="saveAuncelData"
>
确认采集
</u-button>
</view>
</u-col>
<u-col span="3">
<view>
<scroll-view class="content-right-scroll" scroll-y scroll-with-animation>
<view>
<u-form :model="curSample" ref="uForm" label-width="140">
<template v-for="(fields, groupIndex) in fieldGroup">
<view :key="'group_' + groupIndex" v-if="curParameterKey == '' || curParameterKey == fields.title">
<!-- 组名 -->
<view class="my-collapse" @click="fields.open = !fields.open">
<text class="title">{{ fields.title }}</text
><u-icon :name="fields.open ? 'arrow-up' : 'arrow-down'"></u-icon>
</view>
<view
class="content"
:id="'elId' + groupIndex"
:style="{ height: fields.open ? collaHeights[groupIndex] + 'px' : '0' }"
>
<view
class="form-item-my"
v-for="(field, fieldIndex) in fields.fields"
@click="fieldClick(field, groupIndex + '-' + fieldIndex)"
:key="groupIndex + '-' + fieldIndex"
v-show="field.hidden != 1 && field.hidden != '1'"
:class="{ 'selected-field': selectedFieldIndex === groupIndex + '-' + fieldIndex }"
>
<view
:class="['label-my', { 'label-high-light': field.highlight == 1 || field.highlight == '1' }]"
v-html="
field.name +
(typeof field.unit != 'undefined' && field.unit != null && field.unit != ''
? '(' + field.unit + ')'
: '')
"
></view>
<view class="content-my">
<!--
如果是select渲染2个组件1个input、1个picker.
field.valueText用于显示picker选中的文本
-->
<u-input
style="width: 120px"
v-if="field.fillingWay == 4"
v-model="field.value"
:placeholder="field.placeholder"
type="text"
/>
<view v-if="field.type == 'select'" class="x-bc select-my" @click="field.showPicker = true">
<text v-if="field.valueText">{{ field.valueText }}</text>
<text v-else>请选择</text>
<u-icon name="arrow-down" size="20"></u-icon>
</view>
<u-picker
v-if="field.type == 'select'"
:show="field.showPicker"
:columns="[field.options]"
keyName="dictValue"
@cancel="field.showPicker = false"
@confirm="event => dicPickerConfirm(event, field)"
/>
<!--普通输入框 使用文本显示-->
<view class="content-my-text" v-if="field.type != 'select' && field.fillingWay != 4">
<text v-if="!field.value || field.value == ''" class="content-my-text-placeholder">{{
field.placeholder
}}</text>
<text
v-else
:class="[
'content-my-text-value',
{ 'field-high-light': field.highlight == 1 || field.highlight == '1' }
]"
>{{ field.value }}</text
>
</view>
</view>
</view>
</view>
</view>
</template>
</u-form>
</view>
</scroll-view>
<u-button class="btn-operation" type="success" @click="saveDetail()">保存样品数据</u-button>
</view>
</u-col>
</u-row>
<!-- 天平选择-->
<auncel-select-popup
ref="auncelSelector"
v-model:showAuncelSelector="showAuncelSelector"
:previousAuncelId="currentAuncel.id"
></auncel-select-popup>
</view>
</template>
<script>
import request from '@/nx/request'
import { calcAnalysisValue } from '@/nx/helper/calcAnalysisValue'
import { number } from 'mathjs'
import AuncelSelectPopup from '@/components/sample/auncel-select-popup.vue'
import { getTenantId } from '@/defaultBaseUrl'
import { useScreenOrientation } from '@/nx/hooks/useScreenOrientation'
import nx from '@/nx'
export default {
components: { AuncelSelectPopup },
data() {
return {
elId: this.$u.guid(),
scrollTop: 0, //tab标题的滚动条位置
current: 0, // 预设当前项的值
menuHeight: 0, // 左边菜单的高度
menuItemHeight: 0, // 左边菜单item的高度
orderGenBH: true, //顺序生成杯号
weightDataIsToZero: false, //重量数据是否归零
currentSample: {}, //当前样品
currentTaskNo: '', //当前任务指派单号
currentTaskId: '', //当前任务指派单id
currentTaskType: '', //当前任务类型
title: '',
numKeyboardParam: {
decimal: '-1' //数字键盘小数位数,-1为不限制
},
showAuncelSelector: false, //显示天平选择框
currentAuncel: {
id: '',
name: '',
code: '',
weightStable: 0,
weightData: '请选天平',
weightUnit: ''
},
selectedField: {},
selectedFieldIndex: '',
leftList: [],
curSample: {},
showDicPicker: false,
curParameterTitle: '选择字段分类',
curParameterKey: '',
curParameterClassify: '',
conAssayTaskId: '',
busSubCSampleId: '',
optionParameterClassify: [],
paramFieldApiRet: [],
fieldGroup: [],
collaHeights: []
}
},
computed: {
dynamicFieldPlaceholder(field) {
return '请输入'
},
confirmWeightDisabled() {
if (
this.currentSample.sampleCode &&
this.currentAuncel.weightStable == 1 &&
Number(this.currentAuncel.weightData) > 0
) {
return false
}
return true
},
checkCupNumReadonly() {
if (!this.currentAuncel || this.currentAuncel.id == '') return true
return false
},
userInfo() {
return nx.$store('user').userInfo
}
},
onLoad(param) {
const { lockOrientation } = useScreenOrientation()
lockOrientation('landscape')
const me = this
if (param.currentTaskNo) {
this.currentTaskNo = param.currentTaskNo
this.currentTaskType = param.currentTaskType
}
this.title = '样品分析-任务指派单:' + param.currentTaskNo
this.getAssayTaskDetail(this.currentTaskNo)
this.loadFieldApiData(this.fieldGroup)
this.listenNumKeyboard()
this.listenAuncelSelect()
},
onShow() {
console.log('onShow')
this.loadDevice()
this.listenDeviceData()
},
onHide() {
console.log('onHide')
//移除监听websocket返回来的数据
// this.closeDeviceLink();
this.closeDeviceListener()
// this.closeEventListener();
},
onUnload() {
console.log('onUnload')
//移除监听websocket返回来的数据
this.closeDeviceLink()
this.closeDeviceListener()
this.closeEventListener()
},
onBackPress(options) {
this.customBack()
return true
},
methods: {
getDomHeight() {
this.collaHeights = []
this.$nextTick(() => {
if (this.fieldGroup.length) {
this.fieldGroup.forEach((item, index) => {
this.$u.getRect('#elId' + index).then(res => {
this.collaHeights.push(res.height)
})
})
}
})
},
//返回上一页
customBack() {
uni.redirectTo({
url: '/pages/analysis/sample/sample-work-list'
})
},
navRightClick() {
let url = '/pages/analysis/sample/sample-work-edit-task'
url += '?currentTaskNo=' + this.currentTaskNo
uni.navigateTo({
url: url
})
},
parameterClassifyChange(v, a) {
const me = this
let groupIndex = 0
me.curParameterKey = v
me.optionParameterClassify.forEach(function (item, index) {
if (item.value == v) {
groupIndex = index
me.curParameterTitle = item.label
}
})
if (v == '') groupIndex = 0
if (groupIndex > 0) groupIndex--
//自动选中字段
me.selectedFieldIndex = groupIndex + '-'
me.autoNextField()
},
fieldClick(field, key) {
try {
this.$refs.myKeyboard.clearNum()
} catch (e) {
console.error(e)
}
if (field.fillingWay == 4) return
this.selectedField = field
this.selectedFieldIndex = key
//判断小数位数
let dataType = field.dataType
if (dataType == null || dataType < -1) dataType = -1
this.numKeyboardParam.decimal = dataType
if (field.fillingWay == 2) {
this.listenDeviceData()
} else {
this.closeDeviceListener()
}
},
//自动切换到下一个字段
autoNextField() {
const me = this
//selectedFieldIndex是groupIndex-fieldIndex
let groupIndex = 0
let fieldIndex = 0
if (typeof me.selectedFieldIndex == 'undefined' || me.selectedFieldIndex == '') me.selectedFieldIndex = '0-'
const indexV = me.selectedFieldIndex.split('-')
groupIndex = number(indexV[0])
fieldIndex = indexV[1] == '' ? -1 : number(indexV[1])
const group = me.fieldGroup[groupIndex]
const fields = group.fields
if (fields.length > fieldIndex + 1) {
//如果下一个字段是计算,不自动切换
const fillingWay = fields[fieldIndex + 1].fillingWay || ''
if (fillingWay == '3') return
//切换到下一个字段
const key = groupIndex + '-' + (fieldIndex + 1)
me.fieldClick(fields[fieldIndex + 1], key)
}
},
//自动切换到下一个样品
autoNextSample() {
//仅在顺序称重时自动切换
// if (!this.orderWeighChecked)
// return;
if (this.leftList.length <= this.current + 1) return
const index = this.current + 1
this.switchSample(index, true)
},
//手动切换样品
async switchSample(index, autoFlag) {
const me = this
//重置天平归0
this.weightDataIsToZero = false
//清空数字键盘数据
this.$refs.myKeyboard.clearNum()
if (index == this.current) return
// if (this.orderWeighChecked && !autoFlag) return;//顺序称重不允许选中
this.current = index
// 如果为0意味着尚未初始化
if (this.menuHeight == 0 || this.menuItemHeight == 0) {
// await this.getElRect('menu-scroll-view', 'menuHeight');
await this.getElRect('u-tab-item', 'menuItemHeight')
}
// 将菜单菜单活动item垂直居中
this.scrollTop = index * this.menuItemHeight + this.menuItemHeight / 2 - this.menuHeight / 2 - 50
//修改当前选中的me.selectedFieldIndex
if (typeof me.selectedFieldIndex != 'undefined' && me.selectedFieldIndex.indexOf('-') > 0) {
me.selectedFieldIndex = me.selectedFieldIndex.split('-')[0] + '-'
}
this.currentSample = this.leftList[index]
//读取样品明细字段
this.getDetailFieldsAndStatus(true)
},
// 获取一个目标元素的高度
getElRect(elClass, dataVal) {
new Promise((resolve, reject) => {
const query = uni.createSelectorQuery().in(this)
query
.select('.' + elClass)
.fields({ size: true }, res => {
// 如果节点尚未生成res值为null循环调用执行
if (!res) {
setTimeout(() => {
this.getElRect(elClass)
}, 10)
return
}
this[dataVal] = res.height
})
.exec()
})
},
//读取样品明细字段
getDetailFieldsAndStatus(autoSelectNextField) {
const me = this
const taskDetailId = this.currentSample.id
uni.showLoading({
title: '加载中...'
})
//读取回收率配置
this.loadConRecoveryList()
//查询字段
this.$u.api
.queryFieldsByTaskDetail({ taskDetailId: taskDetailId })
.then(res => {
me.fieldGroup = []
if (!res.success) {
this.$helper.showToast({
title: res.message
})
return
}
//处理“填写&计算”字段:如果后台存了值,则不自动计算
const groupList = res.result
for (const g of groupList) {
g.open = true
for (const f of g.fields) {
if (f.fillingWay == '1' && f.value != null && f.value != '') {
f.valueTypeManual = '1'
}
}
}
me.fieldGroup = groupList
const arr = [
{
label: '全部',
value: ''
}
]
for (const g of me.fieldGroup) {
const title = g.title
const o = {
label: title,
value: title
}
arr.push(o)
}
// 计算样品详情高度
me.getDomHeight()
me.optionParameterClassify = arr //字段分类
me.conAssayTaskId = res.additionalProperties.conAssayTaskId
me.busSubCSampleId = res.additionalProperties.busSubCSampleId
const detail = res.additionalProperties.taskDetail
// console.log('detail', JSON.stringify(detail));
//处理硫值、硫量:未保存过的数据,读取接口返回的硫值、硫量
this.loadSValue(detail)
//自动生成杯号
me.autoGenerateCupNum()
//自动选择下一个字段
if (autoSelectNextField) me.autoNextField()
//按公式计算值,并检查原数据与计算后的数据是否一致
me.calAndCheck()
})
.finally(() => {
uni.hideLoading()
})
},
checkLoadSValue() {
const vKey = 'sRange'
const vF = this.getFieldByKey(vKey)
if (vF == null) return false
const v = vF.value
if (v == null || v == '') return true
try {
if (v == 0 || number(v) == 0) return true
} catch (e) {}
return false
},
//读取硫值、硫量
loadSValue(detail) {
let flag = this.checkLoadSValue()
// console.log('detail', JSON.stringify(detail));
// console.log('this.fieldGroup', JSON.stringify(this.fieldGroup));
if (!flag) return
const vKey = 'sValue'
const rKey = 'sRange'
const vF = this.getFieldByKey(vKey)
if (vF != null) {
vF.value = detail.svalue
}
const rF = this.getFieldByKey(rKey)
if (rF != null) {
rF.value = detail.srange
}
},
getFieldByKey(key) {
const group = this.fieldGroup
let field = null
for (let g of group) {
for (let f of g.fields) {
const dicKey = f.dicKey
if (dicKey && dicKey == key) {
field = f
break
}
}
}
// console.log('field', JSON.stringify(field));
return field
},
//按公式计算值,并检查原数据与计算后的数据是否一致
calAndCheck() {
const me = this
//提取原本数值
const oldVal = me.fitUpValues()
calcAnalysisValue(me.fieldGroup)
if (me.checkDataNew(oldVal)) return
const newVal = me.fitUpValues(oldVal)
//检查是否一致
let modifyFlag = false
for (const o in oldVal) {
let old = oldVal[o]
if (old == null) old = 0
//判断是否number
try {
// console.log(o + '----oldVal[o]=' + old, 'newVal[o]=' + newVal[o]);
if (number(old) != number(newVal[o])) {
modifyFlag = true
}
} catch (e) {
// console.error(e);
if (old != newVal[o]) modifyFlag = true
}
}
if (modifyFlag)
uni.showToast({
title: '数据有修改,请检查所有样品,并重新保存!',
duration: 2000,
icon: 'error'
})
},
//检查是否是新数据
checkDataNew(data) {
for (const o in data) {
if (data[o] != null && data[o] != '0') return false
}
return true
},
//组装表单值,用于数据比对
fitUpValues() {
const val = {}
for (const g of this.fieldGroup) {
for (const f of g.fields) {
const detailId = f.detailId
if (!detailId) continue
val[detailId] = f.value
}
}
return val
},
clearFieldVal() {
uni.showModal({
title: '提示',
content: '清空当前字段的值,是否继续?',
cancelColor: '#0055A2',
confirmColor: '#0055A2',
success: res => {
if (res.cancel) {
return
}
this.selectedField.value = ''
this.selectedField.valueTypeManual = '0'
//重新计算
calcAnalysisValue(this.fieldGroup)
// const dataType = this.selectedField.dataType || 0;
// //数字类型改为0
// if(dataType > 0){
// let val = '0';
// let dotLen = 0;
// if(val.indexOf('.') > 0)
// dotLen = val.length - val.indexOf('.') - 1;
// else
// val += '.';
// while(dotLen < dataType){
// dotLen ++;
// val += '0';
// }
// this.selectedField.value = val;
// }else{
// //文本类型,直接清空
// this.selectedField.value = '';
// }
}
})
},
listenNumKeyboard() {
const me = this
//键盘监听
uni.$on('keyboardOK', res => {
if (res == null) {
this.clearFieldVal()
return
}
//自动补全小数位数
const dataType = me.selectedField.dataType || 0
let val = res.val
//判断val小数位如果小于设定位数则补全
if (dataType > 0) {
if (val == '') val = '0'
if (typeof val == 'number') val += ''
let dotLen = 0
if (val.indexOf('.') > 0) dotLen = val.length - val.indexOf('.') - 1
else val += '.'
while (dotLen < dataType) {
dotLen++
val += '0'
}
}
me.selectedField.value = val
me.selectedField.valueTypeManual = '1' //标记为手动值,不参与计算
const dicKey = me.selectedField.dicKey
if (dicKey && dicKey == 'bh_down') {
me.autoFillBhUp(val)
}
calcAnalysisValue(me.fieldGroup)
//自动跳转下一个字段
setTimeout(() => {
me.autoNextField()
}, 60)
})
},
//自动填写筛上杯号
autoFillBhUp(val) {
const bh = Number(val) + 1
for (const g of this.fieldGroup) {
for (const f of g.fields) {
if (f.dicKey && f.dicKey == 'bh_up') {
f.value = bh + ''
return
}
}
}
},
selectAuncel() {
// if (this.currentAuncel.weightData != '请选天平') {
// return;
// }
this.showAuncelSelector = true
// this.closeDeviceListener();
},
listenAuncelSelect() {
//天平选择框监听
uni.$on('auncelSelector_close', res => {
this.showAuncelSelector = false
// this.listenDeviceData();
})
uni.$on('auncelSelector_doSelect', res => {
this.showAuncelSelector = false
// console.log('auncelSelector_doSelect', res);
//如果控制了天平,释放控制
const data = res.data
// console.log('主页面 res', JSON.stringify(res));
if (data) {
this.currentAuncel.id = data.deviceId
this.currentAuncel.name = data.deviceName
this.currentAuncel.code = data.deviceCode
}
// console.log('主页面this.currentAuncel', JSON.stringify(this.currentAuncel));
// const deviceId = this.currentAuncel.id;
// if(typeof deviceId != 'undefined' && deviceId != null){
// this.releaseDeviceControl(deviceId);
// }
// this.listenDeviceData();
})
},
checkBh() {
//检查杯号
let hasHb = true
for (const g of this.fieldGroup) {
for (const f of g.fields) {
if (f.dicKey && f.dicKey.indexOf('bh_') >= 0) {
if (typeof f.value == 'undefined' || f.value == null || f.value == '') hasHb = false
}
}
}
if (!hasHb) {
this.$helper.showToast({
title: '杯号不能为空,请填写杯号!'
})
return false
}
return true
},
saveAuncelData() {
//检查杯号
if (!this.checkBh()) return
//保存数据
if (!this.weightDataIsToZero) {
this.$helper.showToast({
title: '天平必须先回零!'
})
return
}
//获取当前重量
let weight = this.currentAuncel.weightData
this.selectedField.value = weight
const curFieldDicKey = this.selectedField.dicKey
let upDownFlag = ''
if (curFieldDicKey && curFieldDicKey != '' && curFieldDicKey.indexOf('_') > 0) {
upDownFlag = curFieldDicKey.substring(curFieldDicKey.lastIndexOf('_') + 1)
}
//这里不修改weightDataIsToZero在切换样品是修改
// this.weightDataIsToZero = false;
//保存天平编号、天平名称、称重时间。支持筛上、筛下
if (curFieldDicKey && curFieldDicKey.indexOf('sampleWeight') >= 0) {
let auncelNoFieldKey = 'auncelNo'
let measureTimeFieldKey = 'measureTime'
if (upDownFlag && upDownFlag !== '') {
auncelNoFieldKey += '_' + upDownFlag
measureTimeFieldKey += '_' + upDownFlag
}
const auncelNoField = this.getFieldByKey(auncelNoFieldKey)
if (auncelNoField != null) {
auncelNoField.value = this.currentAuncel.code
}
const measureTimeField = this.getFieldByKey(measureTimeFieldKey)
if (measureTimeField != null) {
measureTimeField.value = this.$helper.dateFormat(new Date(), 'yyyy-MM-dd hh:mm:ss')
}
}
// for(const g of this.fieldGroup){
// for(const f of g.fields){
// //天平编号
// if(f.dicKey == 'auncelNo' || f.dicKey == 'auncelNo_' + upDownFlag)
// f.value = this.currentAuncel.code;
// //样重
// if(f.dicKey == 'sampleWeight' || f.dicKey == 'sampleWeight_' + upDownFlag)
// f.value = weight;
// //称重时间
// if(f.dicKey == 'measureTime' || f.dicKey == 'measureTime_' + upDownFlag)
// f.value = this.$helper.dateFormat(new Date(), 'yyyy-MM-dd hh:mm:ss');
// }
// }
//指派单明细上的称重时间
this.curSample.measureTime = this.$helper.dateFormat(new Date(), 'yyyy-MM-dd hh:mm:ss')
//计算
try {
calcAnalysisValue(this.fieldGroup)
} catch (e) {
console.error(e)
}
//自动跳转下一个字段
setTimeout(() => {
this.autoNextField()
}, 100)
},
checkSubmit() {
//检查必填字段
let fieldNames = ''
for (const g of this.fieldGroup) {
for (const f of g.fields) {
let name = f.shortName
if (name == null || name == '') name = f.name
if (f.allowNull == 1 || f.allowNull == '1') continue
if (f.value == null || f.value == '') {
fieldNames += name + ''
}
}
}
if (fieldNames != '') {
this.$helper.showToast({
title: '请填写必填字段:' + fieldNames
})
return false
}
//检查不能为0的字段
fieldNames = ''
for (const g of this.fieldGroup) {
for (const f of g.fields) {
let name = f.shortName
if (name == null || name == '') name = f.name
//检查不可为0的数据
if (f.notZero == 1 || f.notZero == '1') {
if (f.value == null || f.value == '' || number(f.value) == 0) {
fieldNames += name + ''
}
}
}
}
if (fieldNames != '') {
this.$helper.showToast({
title: '这几个值不能为0请检查' + fieldNames
})
return false
}
return true
},
saveDetail() {
//检查杯号
if (!this.checkBh()) return
const valueList = []
let cupNum = 0
let detailId = this.currentSample.id
for (const g of this.fieldGroup) {
for (const f of g.fields) {
// if(f.value == null || f.value == '') //空值也要传入后端
// continue;
if (f.dicKey == 'bh' || f.dicKey == 'bh_up') cupNum = f.value
valueList.push({
id: f.detailId,
type: f.pOrE,
value: f.value,
name: f.name,
dataType: f.dataType
})
}
}
const data = {
busSubCSampleId: this.busSubCSampleId,
conAssayTaskId: this.conAssayTaskId,
measureTime: this.curSample.measureTime,
elementParamValueList: valueList,
busAssayTaskDetailId: detailId
}
if (typeof cupNum != 'undefined' && cupNum != null && cupNum != '' && cupNum != 0 && cupNum != '0') {
//提交杯号,保存到后台
data.cupNum = cupNum
//标记当前杯号
this.markCurCupNum(cupNum)
}
uni.showLoading({
title: '请稍后...'
})
this.$u.api
.saveDetailValue(data)
.then(res => {
//如果仅保存,在这里触发切换
setTimeout(() => {
this.autoNextSample()
}, 1000)
})
.catch(err => {
console.error(err)
})
.finally(() => {
uni.hideLoading()
})
},
//提交任务指派单
submitTask() {
const data = {
taskNo: this.currentTaskNo
}
const msg = '请确认所有样品数据都已保存,然后再提交指派单!是否继续?'
uni.showModal({
title: '提示',
content: msg,
cancelColor: '#0055A2',
confirmColor: '#0055A2',
success: res => {
if (res.cancel) return
uni.showLoading({
title: '请稍后...'
})
this.$u.api
.submitTask(data)
.then(res => {
this.$helper.showToast({
title: '提交成功!'
})
uni.navigateTo({
url: '/pages/analysis/sample/sample-report'
})
})
.catch(err => {
console.error(err)
})
.finally(() => {
uni.hideLoading()
})
}
})
},
//自动生成杯号(仅顺序称重):第一杯:手填,后续杯 = 上一杯 + 1
autoGenerateCupNum() {
if (!this.orderGenBH) return
let cupNum = 0
let current = this.current
if (typeof current == 'undefined' || current == null) current = 0
//第一杯
if (current == 0) {
cupNum = 1
this.putCupNum(cupNum)
return
}
//取上一个样品的杯号
const sample = this.leftList[current - 1]
cupNum = sample.cupNum
if (typeof cupNum == 'undefined' || cupNum == null || cupNum == '') return
//杯号赋值到当前样品
this.putCupNum(Number(cupNum) + 1, current, Number(cupNum))
},
markCurCupNum(cupNum) {
this.currentSample.cupNum = cupNum
},
putCupNum(cupNum, sampleIndex, lastCupNum) {
if (typeof sampleIndex == 'undefined' || sampleIndex == null) sampleIndex = 0
const cupNumKey = 'bh'
for (const fields of this.fieldGroup) {
if (typeof fields == 'undefined') continue
//杯号
for (const field of fields.fields) {
if (field.dicKey == cupNumKey) {
if (typeof field.value == 'undefined' || field.value == null || field.value == '') {
field.value = cupNum
return true
}
}
}
}
//处理筛上筛下
if (lastCupNum && lastCupNum == sampleIndex) {
//上一个杯号 == 默认杯号
cupNum = sampleIndex * 2 + 1
}
for (const fields of this.fieldGroup) {
if (typeof fields == 'undefined') continue
//杯号-筛下
for (const field of fields.fields) {
if (field.dicKey == cupNumKey + '_down') {
if (typeof field.value == 'undefined' || field.value == null || field.value == '') {
field.value = cupNum
cupNum++
break
}
}
}
//杯号-筛上
for (const field of fields.fields) {
if (field.dicKey == cupNumKey + '_up') {
if (typeof field.value == 'undefined' || field.value == null || field.value == '') {
field.value = cupNum
return true
}
}
}
}
return false
},
loadConRecoveryList() {
const conBaseSampleId = this.currentSample.conBaseSampleId
const rParam = {
pageNo: 1,
pageSize: -1,
conBaseSampleId: conBaseSampleId
}
const storageKey = 'ConRecoveryRateList'
this.$u.api
.queryConRecoveryRateList(rParam)
.then(res => {
const result = res.result
if (typeof result == 'undefined' || result == null || !result) {
uni.setStorage(storageKey, [])
return
}
const records = result.records
if (!records || records.length == 0) {
uni.setStorage(storageKey, [])
return
}
uni.setStorageSync(storageKey, records)
// this.conRecoveryList = res.result;
})
.catch(err => {
console.error(err)
})
},
getAssayTaskDetail(taskNo) {
this.leftList = []
this.$u.api
.getAssayTaskDetailListByTaskNo({ taskNo: taskNo })
.then(res => {
let dataList = res.result
dataList.forEach((item, index) => {
this.leftList.push(item)
})
if (this.leftList.length == 0) {
return
}
this.current = 0
this.currentSample = this.leftList[0]
this.getDetailFieldsAndStatus(true)
// if (this.orderWeighChecked) {
// this.current = 0;
// this.currentSample = this.leftList[0];
// this.getDetailFieldsAndStatus(true);
// } else {
// this.current = -1;
// this.currentSample = {};
// }
})
.catch(err => {
console.error(err)
})
},
orderWeighChange(e) {
if (e && this.leftList.length > 0) {
//this.current = 0;
//this.currentSample = this.leftList[0];
this.getAssayTaskDetail(this.currentTaskNo)
return
}
this.current = -1
this.currentSample = {}
},
async apiRequest(url) {
return request({
url: url,
method: 'GET',
custom: {
isApiEncryption: true
}
})
},
//读取字段里的API选项
async loadFieldApiData(fieldGroups) {
for (const fields of fieldGroups) {
for (const field of fields.fields) {
const api = field.api
const type = field.type
if (type == 'select' && api && api != '') {
//读取API选项
try {
const res = await this.apiRequest(api)
const data = res
field.options = data
field.rangeKey = 'displayName'
} catch (e) {}
}
}
}
},
/*
* 选择器组件确认事件
* event 事件默认参数
* field 当前字段
* 处理逻辑:
* field.value = 选中的值
* field.valueText = 选中的文本
* */
dicPickerConfirm(event, field) {
const me = this
const checked = event.value[0]
const displayName = checked.displayName
const value = checked.dictValue
const extField1 = checked.extField1
field.value = value
field.valueText = value
const relatedFieldNo = '8'
//查找并处理关联字段
for (const fieldGroup of this.fieldGroup) {
for (const field of fieldGroup.fields) {
if (field.paramNo == relatedFieldNo) {
field.value = extField1
break
}
}
}
//触发计算公式
calcAnalysisValue(me.fieldGroup)
},
listenDeviceData() {
//监听websocket返回来的数据
//设备数据
uni.$on('deviceData', res => {
// console.log('deviceData', res);
switch (res.deviceType) {
case 'auncel':
if (this.currentAuncel.id === res.deviceId) {
this.currentAuncel.weightData = res.weightData
this.currentAuncel.weightUnit = res.weightUnit
this.currentAuncel.weightStable = res.weightStable
this.currentAuncel.isConnected = 1
if (Number(res.weightData) == 0) {
this.weightDataIsToZero = true
}
}
break
default:
break
}
})
//设备状态
uni.$on('deviceStatus', res => {
if (this.currentAuncel.id === res.deviceId) {
// console.log('deviceStatus', res);
if (res.connected == 0) {
this.currentAuncel.weightStable = 0
this.currentAuncel.weightData = '天平断开'
this.currentAuncel.weightUnit = ''
}
}
this.currentAuncel.isConnected = res.connected
})
//控制设备状态
uni.$on('controlDevice', res => {
if (this.currentAuncel.id === res.deviceId) {
// console.log('controlDevice', res);
this.currentAuncel.id = ''
this.currentAuncel.name = ''
this.currentAuncel.code = ''
this.currentAuncel.weightStable = 0
this.currentAuncel.weightData = '请选天平'
this.currentAuncel.weightUnit = ''
}
})
//连接断开
uni.$on('connClose', res => {
//重置
this.currentAuncel.weightData = ''
this.currentAuncel.weightUnit = ''
this.currentAuncel.weightStable = 0
this.currentAuncel.controlUserName = ''
this.currentAuncel.isConnected = 0
})
},
loadDevice() {
//注册websocket
let regData = {
msgId: this.$helper.uuid(),
cmd: 'register',
clientType: 'caaClient',
data: {
userId: this.userInfo.id,
tenantId: getTenantId(),
userRealName: this.userInfo.realname
}
}
this.$measure.setRegData(JSON.stringify(regData))
this.$measure.reOpen()
},
closeEventListener() {
uni.$off('keyboardOK')
// uni.$off('auncelSelector_close');
// uni.$off('auncelSelector_doSelect');
},
closeDeviceListener() {
uni.$off('deviceData')
uni.$off('deviceStatus')
uni.$off('controlDevice')
uni.$off('connClose')
},
closeDeviceLink() {
const deviceId = this.currentAuncel.id
this.releaseDeviceControl(deviceId)
},
//释放设备控制
releaseDeviceControl(deviceId) {
if (!deviceId || deviceId == '') return
let controlDevice = {
msgId: deviceId,
cmd: 'controlDevice',
clientType: 'caaClient',
data: {
deviceId: deviceId,
isControl: false,
controlRealName: this.userInfo.realname
}
}
//发送控制数据
this.$measure.send(JSON.stringify(controlDevice))
},
getDataSourceTypeShow(val) {
if (val == 2) return '【筛上】'
if (val == 3) return '【筛下】'
return ''
}
}
}
</script>
<style lang="scss" scoped>
.navbar-right {
font-size: 16px;
color: #fff;
display: flex;
}
.content-title-name {
font-size: 18px;
font-weight: 300;
padding: 4px 0;
display: flex;
justify-content: center;
}
.current-sample-code {
font-weight: bold;
margin-right: 20px;
}
.form-item-my {
display: flex;
align-items: center;
margin-bottom: 10px;
height: 35px;
font-size: 13px;
}
.selected-field {
background-color: #bada55;
}
.label-my {
flex: 5;
}
.label-high-light {
color: #000;
font-weight: 600;
font-size: 1.2em;
}
.field-high-light {
color: #000;
font-weight: 600;
font-size: 1.2em;
}
.label-my sub {
font-size: 0.6em;
vertical-align: sub;
}
.content-my {
flex: 2;
text-align: right;
.select-my {
color: #303133;
font-size: 15px;
padding: 6px 8px;
border: 1px solid #dcdcdc;
border-radius: 5px;
}
}
.content-my-text-value {
color: rgb(48, 49, 51);
}
.content-my-text-placeholder {
color: #c0c4cc;
}
.content-left-scroll {
height: 60vh;
}
.content-right-scroll {
height: 68vh;
}
.u-tab-item {
display: flex;
align-items: center;
justify-content: space-around;
font-size: 16px;
color: #444;
font-weight: 400;
padding: 4px 0;
border-bottom: 2px dotted #444;
}
.u-tab-item-active {
color: #0055a2;
font-weight: 600;
}
.btn-operation {
width: 80%;
font-size: 18px;
margin-top: 10px;
}
.auncel {
width: 100%;
height: 55vh;
background-image: url(/static/images/auncel.png);
background-repeat: no-repeat;
background-size: 100% 100%;
background-position: center;
display: flex;
flex-direction: column;
}
.auncel-title {
flex: 3;
display: flex;
justify-content: center;
align-items: center;
font-size: 32px;
}
.auncel-weight {
flex: 2.5;
display: flex;
align-items: center;
padding-bottom: 20px;
box-sizing: border-box;
position: relative;
}
.weight {
font-size: 42px;
width: 100%;
padding-right: 10px;
}
.weight-data {
color: #4cd964;
text-align: right;
font-family: zzjc-lcd;
}
.weight-data-yellow {
color: #ffff00;
text-align: center;
font-family: zzjc-lcd;
}
.weight-data-warning {
color: #ff3333;
text-align: right;
font-family: zzjc-lcd;
}
.weight-unit {
color: #ffffff;
font-size: 32px;
padding-right: 30px;
}
@media (max-width: 700px) {
.auncel {
height: 45vh;
}
.auncel-title {
font-size: 20px;
}
.auncel-weight {
padding-bottom: 15px;
}
.weight {
font-size: 26px;
}
.weight-unit {
font-size: 20px;
}
}
.field-name {
font-size: 26px;
padding: 8px;
}
.my-collapse {
display: flex;
align-items: center;
justify-content: space-between;
padding: 5px 10px 5px 0;
.title {
font-weight: bold;
}
}
.content {
overflow: hidden;
padding-right: 10px;
transition: height 100ms;
}
@media (max-width: 700px) {
.content-left-scroll {
height: 45vh;
}
.content-right-scroll {
height: 55vh;
}
.field-name {
font-size: 16px;
}
}
</style>