feat:样品分析

This commit is contained in:
houjunxiang
2025-10-14 18:16:51 +08:00
parent b5aed8573a
commit 5916b8c833
14 changed files with 574 additions and 671 deletions

View File

@@ -5,70 +5,65 @@
<u-col span="1"></u-col>
<u-col span="10">
<scroll-view scroll-y scroll-with-animation :scroll-top="scrollTop">
<u-form :model="taskInstance" ref="uForm" label-width="210">
<view class="form-item-my" v-for="(field, index) in formFields" :key="'field_' + index">
<view
class="label-my"
:style="{ fontWeight: checkFeadToDetailField(field.headToDetailField) ? 'bold' : 'normal' }"
>{{ field.label }}</view
>
<view class="content-my">
<view v-if="field.type == 'title' && field.display" class="content-title">
{{ field.textValue }}
</view>
<!--普通输入框-->
<u-input
v-if="
field.type == 'input' &&
(field.decimalCount == null || field.decimalCount == '' || Number(field.decimalCount) < 0)
"
v-model="field.value"
clearable
:placeholder="field.placeholder"
:disabled="field.fillingWay != '1'"
/>
<!--数字,限制小数位数-->
<u-input
v-if="field.type == 'input' && field.decimalCount != null && Number(field.decimalCount) >= 0"
type="number"
clearable
@blur="event => checkDecimal(event, field)"
v-model="field.value"
:placeholder="field.placeholder"
:disabled="field.fillingWay != '1'"
/>
<!--select-->
<view v-if="field.type == 'select'" class="x-bc select-my" @click="handleFieldClick(field)">
<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="displayName"
@cancel="field.showPicker = false"
@confirm="event => pickerConfirm(event, field)"
/>
<!--日期-->
<view v-if="field.type == 'date'" class="x-bc select-my" @click="handleFieldClick(field)">
<text v-if="field.value">{{ field.value }}</text>
<text v-else>请选择</text>
<u-icon name="calendar-fill" size="20"></u-icon>
</view>
<u-datetime-picker
v-if="field.type == 'date'"
:show="field.showPicker"
v-model="curDate"
mode="date"
@cancel="field.showPicker = false"
@confirm="event => pickerConfirm(event, field)"
></u-datetime-picker>
<view class="form-item-my" v-for="(field, index) in formFields" :key="'field_' + index">
<view
class="label-my"
:style="{ fontWeight: checkFeadToDetailField(field.headToDetailField) ? 'bold' : 'normal' }"
>{{ field.label }}</view
>
<view class="content-my">
<view v-if="field.type == 'title'" class="content-title">
{{ field.value }}
</view>
<!--普通输入框-->
<u-input
v-if="field.type == 'Input'"
v-model="field.value"
clearable
:placeholder="field.placeholder"
:disabled="field.disabled || field.fillingWay == 3"
/>
<!--数字限制小数位数-->
<u-input
v-if="field.type == 'decimal'"
type="number"
clearable
@blur="event => checkDecimal(event, field)"
v-model="field.value"
:placeholder="field.placeholder"
:disabled="field.disabled || field.fillingWay == 3"
/>
<!--select-->
<view v-if="field.type == 'select'" class="x-bc select-my" @click="handleFieldClick(field)">
<text v-if="field.value">{{ field.value }}</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="displayName"
@cancel="field.showPicker = false"
@confirm="event => pickerConfirm(event, field)"
/>
<!--日期-->
<view v-if="field.type == 'date'" class="x-bc select-my" @click="handleFieldClick(field)">
<text v-if="field.value">{{ nx.$dayjs(field.value).format('YYYY-MM-DD HH:mm:ss') }}</text>
<text v-else>请选择</text>
<u-icon name="calendar-fill" size="20"></u-icon>
</view>
<u-datetime-picker
v-if="field.type == 'date'"
:show="field.showPicker"
v-model="curDate"
mode="datetime"
@cancel="field.showPicker = false"
@confirm="event => pickerConfirm(event, field)"
></u-datetime-picker>
</view>
</u-form>
</view>
</scroll-view>
<u-button type="primary" @click="saveHeadData">保存</u-button>
</u-col>
@@ -85,8 +80,6 @@ import { calcAnalysisValue } from '@/nx/helper/calcAnalysisValue'
import nx from '@/nx'
import { onLoad } from '@dcloudio/uni-app'
// ========== data ==========
// 标题
const title = ref('编辑指派单')
// 表单模型
@@ -95,6 +88,7 @@ const taskInstance = ref({})
const scrollTop = ref(0)
// 当前任务样品
const currentTaskNo = ref('')
const currentTaskId = ref('')
// 字典选择器显示
const showDicPicker = ref(false)
// 当前日期(用于日期选择器)
@@ -111,23 +105,54 @@ const sampleList = ref([])
// 表单引用
const uForm = ref(null)
const staticFormSchema = [
{ type: 'title', value: '分析原始记录单' },
{ label: '检测方法', type: 'Input', fieldKey: 'configAssayMethodName', disabled: true },
{ label: '分析人', type: 'Input', fieldKey: 'assayOperator', disabled: true },
{ label: '检测时间', type: 'date', fieldKey: 'assayTime' },
{ label: '小数值', type: 'decimal', fieldKey: 'num', decimalPosition: 4, placeholder: '请输入' }
]
let dynamicFormSchema = []
// 页面加载
onLoad(param => {
if (param.currentTaskNo) {
currentTaskNo.value = param.currentTaskNo
if (param.currentTaskId) {
currentTaskId.value = param.currentTaskId
}
title.value = '样品分析-任务指派单:' + currentTaskNo.value
loadHeadFieldsAndValueByTaskNo()
getSampleList(currentTaskNo.value)
// loadHeadFieldsAndValueByTaskNo()
// getSampleList(currentTaskNo.value)
loadTaskDetail()
})
// ========== methods ==========
function loadTaskDetail() {
nx.$api.assayTask.getSampleAnalysisByTaskId(currentTaskId.value).then(async res => {
taskInstance.value = res
formValue.value = {
configAssayMethodName: res.configAssayMethodName,
assayOperator: res.assayOperator,
assayTime: res.assayTime,
...JSON.parse(res.formValue)
}
title.value = '样品分析-任务指派单:' + res.businessAssayTasNo
const data = await nx.$api.assayTask.getDynamicBaseFormSchema({ dataCollectionId: res.dataCollectionId })
dynamicFormSchema = data.map(item => ({
label: item.fieldName,
fieldKey: item.fieldKey,
type: item.fieldType,
value: '',
placeholder: '请输入'
}))
formFields.value = [...staticFormSchema, ...dynamicFormSchema]
bindFormValue()
})
}
// 点击字段(打开选择器)
function handleFieldClick(field) {
if (field.type == 'date') {
field.showPicker = true
if (field.fillingWay == '1') {
field.showPicker = true
}
return
}
@@ -155,22 +180,11 @@ function getSampleList(taskNo) {
})
}
// 返回上一页(原注释保留,未启用)
// function customBack() {
// uni.redirectTo({
// url: "/pages/sample/sample-work-detail"
// });
// }
// 右上角导航点击(空实现)
function navRightClick() {}
// 处理小数位数补0或去除多余位数
function checkDecimal(e, field) {
if (e == '') return
const decimalCount = field.decimalCount
if (decimalCount == null || decimalCount == '' || isNaN(decimalCount)) return
const count = Number(field.decimalCount)
const decimalCount = field.decimalPosition
const count = Number(decimalCount)
const value = field.value
const pos = value.indexOf('.') + 1
let length = value.length - pos
@@ -207,21 +221,18 @@ function assembleFields() {
formFieldsArr.push(field)
}
//先序列化再转json避免json里定义的方法丢失
formFields.value = JSON.parse(JSON.stringify(formFieldsArr, replacer), reviver)
formFields.value = JSON.parse(JSON.stringify(formFieldsArr, nx.$helper.replacer), nx.$helper.reviver)
}
// 绑定数据(将 formValue 填入字段)
function bindFormValue() {
//formValue
for (const field of formFields.value) {
const prop = field.prop
if (prop) {
const value = formValue.value[prop]
const fieldKey = field.fieldKey
if (fieldKey) {
const value = formValue.value[fieldKey]
if (value) {
field.value = value
if (field.type == 'select') {
field.valueText = value
}
}
}
}
@@ -473,7 +484,7 @@ async function loadFieldApiData() {
}
if (changeFlag) {
// 重新序列化以触发响应式更新(保留函数)
formFields.value = JSON.parse(JSON.stringify(formFieldsVal, replacer), reviver)
formFields.value = JSON.parse(JSON.stringify(formFieldsVal, nx.$helper.replacer), nx.$helper.reviver)
}
}
@@ -553,24 +564,6 @@ function getFieldByKey(key) {
}
// ========== 工具函数(保留原位置) ==========
// 自定义 replacer将函数转换为字符串。json序列化和反序列化时避免函数丢失
function replacer(key, value) {
if (typeof value === 'function') {
return value.toString()
}
return value
}
// 自定义 reviver将字符串转换回函数.json序列化和反序列化时避免函数丢失
const functionKeys = ['change', 'dicFormatter']
function reviver(key, value) {
if (functionKeys.includes(key)) {
// 将字符串转换为函数
return new Function('return ' + value)()
}
return value
}
</script>
<style lang="scss" scoped>