| @ -0,0 +1,985 @@ | |||||
| <!-- 生物样品内标工作液制备表 --> | |||||
| <template> | |||||
| <div> | |||||
| <div class="detail-container"> | |||||
| <div class="detail-title"><img src="@/assets/images/detail-title.png">生物样品内标工作液制备表<img | |||||
| src="@/assets/images/detail-title.png" /></div> | |||||
| <div class="detail-content"> | |||||
| <div class="content"> | |||||
| <BaseInfoFormPcakge label="试验基本信息" ref="baseInfoRef" :formConfig="baseInfoFormConfig" | |||||
| :formData="formData" /> | |||||
| <TableList label="试验试剂信息" :columns="sysjColumns" :dataSource="dataSource" /> | |||||
| <TableList label="仪器使用信息" :columns="yqsColumns" :dataSource="dataSource" /> | |||||
| <BaseInfoFormPcakge label="存储条件" ref="storageConditionRef" :formConfig="storageFormConfig" | |||||
| :formData="formData" /> | |||||
| <LineLabel label="操作步骤" /> | |||||
| <div class = "mt-20"> | |||||
| <el-button type="primary" @click="handleAddParalle">新增平行配制</el-button> | |||||
| <el-button type="primary" @click="handleAddLadder">新增阶梯配制</el-button> | |||||
| </div> | |||||
| <!-- 阶梯配制区域 --> | |||||
| <div | |||||
| label="阶梯配制" | |||||
| v-for="(ladderConfig, ladderIndex) in formData.ladderConfigs" | |||||
| :key="'ladder_' + ladderIndex" | |||||
| > | |||||
| <div class="template-form-item"> | |||||
| <div class="config-header"> | |||||
| <div>阶梯配制</div> | |||||
| <el-button | |||||
| type="text" | |||||
| icon="el-icon-delete" | |||||
| @click="deleteLadderConfig(ladderIndex)" | |||||
| >删除</el-button> | |||||
| </div> | |||||
| <BaseInfoFormPcakge | |||||
| @clickable="handleClickable" | |||||
| :ref="`ladderStepFormPackageRef_${ladderIndex}`" | |||||
| :formConfig="ladderStepFormConfig" | |||||
| @blur="onHandleBlur" | |||||
| :formData="ladderConfig" | |||||
| /> | |||||
| <CustomTable | |||||
| @blur="onHandleTableBlur" | |||||
| :showOperation="fillType === 'actFill'" | |||||
| :ref="`ladderStepTableRef_${ladderIndex}`" | |||||
| :columns="ladderStepColumns" | |||||
| :formData="ladderConfig" | |||||
| > | |||||
| <template slot="operation" slot-scope="{ row, rowIndex}"> | |||||
| <TableOpertaion | |||||
| :fillType="fillType" | |||||
| :row="row" | |||||
| :rowIndex="rowIndex" | |||||
| @deleteRow="(rowIndex) => deleteRow(rowIndex, 'ladder', ladderIndex)" | |||||
| ></TableOpertaion> | |||||
| </template> | |||||
| </CustomTable> | |||||
| <div class="add-row"> | |||||
| <el-button @click="handleAddRow('ladder', undefined, ladderIndex)">添加行</el-button> | |||||
| </div> | |||||
| <Step | |||||
| class="mt-0" | |||||
| :ref="`ladderStepRef_${ladderIndex}`" | |||||
| :formData="ladderConfig.ladderStepData" | |||||
| ></Step> | |||||
| </div> | |||||
| </div> | |||||
| <!-- 平行配制区域 --> | |||||
| <div | |||||
| label="平行配制" | |||||
| v-for="(paralleConfig, paralleIndex) in formData.paralleConfigs" | |||||
| :key="'paralle_' + paralleIndex" | |||||
| > | |||||
| <div class="template-form-item"> | |||||
| <div class="config-header"> | |||||
| <div>平行配制</div> | |||||
| <el-button | |||||
| type="text" | |||||
| icon="el-icon-delete" | |||||
| @click="deleteParalleConfig(paralleIndex)" | |||||
| >删除</el-button> | |||||
| </div> | |||||
| <BaseInfoFormPcakge | |||||
| @clickable="handleClickable" | |||||
| :ref="`paralleStepFormPackageRef_${paralleIndex}`" | |||||
| :formConfig="paralleStepFormConfig" | |||||
| @blur="onHandleBlur" | |||||
| :formData="paralleConfig" | |||||
| /> | |||||
| <CustomTable | |||||
| @blur="onHandleTableBlur" | |||||
| :showOperation="fillType === 'actFill'" | |||||
| :ref="`paralleStepTableRef_${paralleIndex}`" | |||||
| :columns="paralleStepColumns" | |||||
| :formData="paralleConfig" | |||||
| > | |||||
| <template slot="operation" slot-scope="{ row, rowIndex}"> | |||||
| <TableOpertaion | |||||
| :fillType="fillType" | |||||
| :row="row" | |||||
| :rowIndex="rowIndex" | |||||
| @deleteRow="(rowIndex) => deleteRow(rowIndex, 'paralle', paralleIndex)" | |||||
| ></TableOpertaion> | |||||
| </template> | |||||
| </CustomTable> | |||||
| <div class="add-row"> | |||||
| <el-button @click="handleAddRow('paralle', undefined, paralleIndex)">添加行</el-button> | |||||
| </div> | |||||
| <Step | |||||
| class="mt-0" | |||||
| :ref="`paralleStepRef_${paralleIndex}`" | |||||
| :formData="paralleConfig.paralleStepData" | |||||
| ></Step> | |||||
| </div> | |||||
| </div> | |||||
| <BaseInfoFormPcakge label="备注" ref="remarkRef" :formConfig="remarkConig" :formData="formData" /> | |||||
| </div> | |||||
| </div> | |||||
| <button @click="onSave">保存</button> | |||||
| </div> | |||||
| <SelectReagentDialog @submit="onSelectReagentSubmit" @cancel="selectReagentVisible = false" | |||||
| ref="selectReagentDialogRef" :visible.sync="selectReagentVisible"> | |||||
| </SelectReagentDialog> | |||||
| </div> | |||||
| </template> | |||||
| <script> | |||||
| import BaseInfoFormPcakge from "@/components/Template/BaseInfoFormPcakge"; | |||||
| import LineLabel from "@/components/Template/LineLabel"; | |||||
| import TableList from "@/components/Template/Table"; | |||||
| import Step from "@/components/Template/Step"; | |||||
| import templateMixin from "../../mixins/templateMixin"; | |||||
| import CustomTable from '@/components/Template/CustomTable.vue'; | |||||
| import SelectReagentDialog from '../../dialog/SelectReagentDialog.vue'; | |||||
| import TableOpertaion from "@/components/Template/operation/TableOpertaion.vue" | |||||
| export default { | |||||
| name: "SWYPBQGZYZBB", | |||||
| components: { BaseInfoFormPcakge, LineLabel, TableList, Step, CustomTable, SelectReagentDialog, TableOpertaion }, | |||||
| mixins: [templateMixin], | |||||
| props: { | |||||
| value: { | |||||
| type: {}, | |||||
| default: () => { }, | |||||
| }, | |||||
| fillType: { | |||||
| type: String, | |||||
| default: 'preFill', | |||||
| }, | |||||
| }, | |||||
| watch: { | |||||
| value: { | |||||
| immediate: true, | |||||
| handler(v) { | |||||
| // 数据回显 | |||||
| if (v && Object.keys(v).length > 0) { | |||||
| this.formData = { ...this.formData, ...v }; | |||||
| // 处理阶梯配制配置 | |||||
| if (v.ladderConfigs && Array.isArray(v.ladderConfigs) && v.ladderConfigs.length > 0) { | |||||
| // 确保 ladderConfigs 是数组 | |||||
| if (!this.formData.ladderConfigs || !Array.isArray(this.formData.ladderConfigs)) { | |||||
| this.$set(this.formData, 'ladderConfigs', []); | |||||
| } | |||||
| // 回显每个阶梯配制配置的数据 | |||||
| v.ladderConfigs.forEach((ladderConfig, index) => { | |||||
| // 确保配置项有必要的属性 | |||||
| if (!this.formData.ladderConfigs[index]) { | |||||
| this.formData.ladderConfigs[index] = { | |||||
| ladderStepData: [], | |||||
| ladderTableFormData: [], | |||||
| showLadderConfig: true | |||||
| }; | |||||
| } | |||||
| // 回显表格数据 | |||||
| if (ladderConfig.ladderTableFormData && ladderConfig.ladderTableFormData.length > 0 && this.$refs[`ladderStepTableRef_${index}`]) { | |||||
| this.$refs[`ladderStepTableRef_${index}`].updateDataSource(ladderConfig.ladderTableFormData); | |||||
| } | |||||
| // 确保步骤数据有值 | |||||
| if (!ladderConfig.ladderStepData) { | |||||
| this.$set(this.formData.ladderConfigs[index], 'ladderStepData', []); | |||||
| } | |||||
| // 确保显示状态有值 | |||||
| if (ladderConfig.showLadderConfig === undefined) { | |||||
| this.$set(this.formData.ladderConfigs[index], 'showLadderConfig', !!ladderConfig.ladderStepData && ladderConfig.ladderStepData.length > 0); | |||||
| } | |||||
| }); | |||||
| } | |||||
| // 处理平行配制配置 | |||||
| if (v.paralleConfigs && Array.isArray(v.paralleConfigs) && v.paralleConfigs.length > 0) { | |||||
| // 确保 paralleConfigs 是数组 | |||||
| if (!this.formData.paralleConfigs || !Array.isArray(this.formData.paralleConfigs)) { | |||||
| this.$set(this.formData, 'paralleConfigs', []); | |||||
| } | |||||
| // 回显每个平行配制配置的数据 | |||||
| v.paralleConfigs.forEach((paralleConfig, index) => { | |||||
| // 确保配置项有必要的属性 | |||||
| if (!this.formData.paralleConfigs[index]) { | |||||
| this.formData.paralleConfigs[index] = { | |||||
| paralleStepData: [], | |||||
| paralleTableFormData: [], | |||||
| showParalleConfig: true | |||||
| }; | |||||
| } | |||||
| // 回显表格数据 | |||||
| if (paralleConfig.paralleTableFormData && paralleConfig.paralleTableFormData.length > 0 && this.$refs[`paralleStepTableRef_${index}`]) { | |||||
| this.$refs[`paralleStepTableRef_${index}`].updateDataSource(paralleConfig.paralleTableFormData); | |||||
| } | |||||
| // 确保步骤数据有值 | |||||
| if (!paralleConfig.paralleStepData) { | |||||
| this.$set(this.formData.paralleConfigs[index], 'paralleStepData', []); | |||||
| } | |||||
| // 确保显示状态有值 | |||||
| if (paralleConfig.showParalleConfig === undefined) { | |||||
| this.$set(this.formData.paralleConfigs[index], 'showParalleConfig', !!paralleConfig.paralleStepData && paralleConfig.paralleStepData.length > 0); | |||||
| } | |||||
| }); | |||||
| } | |||||
| // 兼容旧数据格式(单个配置) | |||||
| if (v.ladderTableFormData && v.ladderTableFormData.length > 0 && (!v.ladderConfigs || v.ladderConfigs.length === 0)) { | |||||
| this.formData.ladderConfigs = [{ | |||||
| ladderStepData: v.ladderStepData || [], | |||||
| ladderTableFormData: v.ladderTableFormData, | |||||
| showLadderConfig: v.showLadderConfig !== undefined ? v.showLadderConfig : true | |||||
| }]; | |||||
| } | |||||
| if (v.paralleTableFormData && v.paralleTableFormData.length > 0 && (!v.paralleConfigs || v.paralleConfigs.length === 0)) { | |||||
| this.formData.paralleConfigs = [{ | |||||
| paralleStepData: v.paralleStepData || [], | |||||
| paralleTableFormData: v.paralleTableFormData, | |||||
| showParalleConfig: v.showParalleConfig !== undefined ? v.showParalleConfig : true | |||||
| }]; | |||||
| } | |||||
| } | |||||
| } | |||||
| }, | |||||
| fillType: { | |||||
| immediate: true, | |||||
| handler(v) { | |||||
| console.log(v, "fillType") | |||||
| } | |||||
| }, | |||||
| }, | |||||
| computed: { | |||||
| // 存储条件表单配置 | |||||
| storageFormConfig() { | |||||
| return [ | |||||
| { | |||||
| type: "conditionItem", | |||||
| config: { | |||||
| storageCondition1: { | |||||
| label: "存储条件", | |||||
| type: "select", | |||||
| fillType: "preFill", | |||||
| options: this.getDictOptions('business_cctj'), | |||||
| otherCode: "other1", | |||||
| }, | |||||
| } | |||||
| } | |||||
| ]; | |||||
| }, | |||||
| // 备注表单配置 | |||||
| remarkConig() { | |||||
| return [ | |||||
| { | |||||
| type: "cellItem", | |||||
| config: { | |||||
| remark: { | |||||
| label: "", | |||||
| type: "textarea", | |||||
| fillType: "actFill", | |||||
| span: 1, | |||||
| placeholder: "请输入备注", | |||||
| maxlength: 1000, | |||||
| rows: 5 | |||||
| } | |||||
| } | |||||
| } | |||||
| ] | |||||
| }, | |||||
| // 试验基本信息表单配置 | |||||
| baseInfoFormConfig() { | |||||
| return [ | |||||
| { | |||||
| type: "cardItem", | |||||
| config: { | |||||
| studyMc: { | |||||
| label: "试验名称", | |||||
| type: "input", | |||||
| disabled: true, | |||||
| }, | |||||
| studySn: { | |||||
| label: "试验编号", | |||||
| type: "input", | |||||
| disabled: true, | |||||
| }, | |||||
| methodCode: { | |||||
| label: "方法编号", | |||||
| type: "input", | |||||
| fillType: "preFill", | |||||
| maxlength: 50, | |||||
| }, | |||||
| versionNum: { | |||||
| label: "版本号", | |||||
| type: "inputNumber", | |||||
| fillType: "actFill", | |||||
| prepend: "V", | |||||
| maxlength: 50, | |||||
| }, | |||||
| } | |||||
| }, | |||||
| { | |||||
| type: "conditionItem", | |||||
| label: "试验配制条件", | |||||
| config: { | |||||
| pre: { | |||||
| label: "预填", | |||||
| type: "select", | |||||
| multiple: true, | |||||
| fillType: "preFill", | |||||
| options: this.getDictOptions('business_pztj'), | |||||
| otherCode: "preOther", | |||||
| }, | |||||
| act: { | |||||
| label: "实际", | |||||
| type: "select", | |||||
| fillType: "actFill", | |||||
| otherCode: "actOther", | |||||
| multiple: true, | |||||
| options: this.getDictOptions('business_pztj') | |||||
| } | |||||
| } | |||||
| }, | |||||
| { | |||||
| type: "cellItem", | |||||
| config: { | |||||
| containerMaterial: { | |||||
| label: "容器材质", | |||||
| type: "select", | |||||
| options: this.getDictOptions('business_rqcz'), | |||||
| fillType: "actFill", | |||||
| otherCode: "containerMaterialOther", | |||||
| } | |||||
| } | |||||
| }, | |||||
| { | |||||
| type: "cellItem", | |||||
| label: "处理时间", | |||||
| config: { | |||||
| createTime: { | |||||
| label: "开始时间", | |||||
| type: "input", | |||||
| }, | |||||
| endTime: { | |||||
| label: "结束时间", | |||||
| type: "input", | |||||
| }, | |||||
| } | |||||
| } | |||||
| ] | |||||
| }, | |||||
| paralleStepFormConfig(){ | |||||
| return[ | |||||
| { | |||||
| type:"step", | |||||
| config:{ | |||||
| solution: { | |||||
| label: "稀释液", | |||||
| type: "input", | |||||
| fillType: "preFill", | |||||
| subType: "clickable", | |||||
| subKey: "subSolution", | |||||
| subFillType: "actFill", | |||||
| maxlength: 20, | |||||
| }, | |||||
| stepStorageCondition: { | |||||
| label: "存储条件", | |||||
| type: "select", | |||||
| fillType: "preFill", | |||||
| options: this.getDictOptions('business_cctj'), | |||||
| otherCode: "stepStorageConditionOther", | |||||
| }, | |||||
| } | |||||
| } | |||||
| ] | |||||
| }, | |||||
| // 操作步骤表单配置 | |||||
| ladderStepFormConfig() { | |||||
| return [ | |||||
| { | |||||
| type: "step", | |||||
| config: { | |||||
| startSolution: { | |||||
| label: "起始源溶液", | |||||
| type: "input", | |||||
| fillType: "preFill", | |||||
| subType: "clickable", | |||||
| subKey: "subStartSolution", | |||||
| subFillType: "actFill", | |||||
| maxlength: 20, | |||||
| }, | |||||
| targetStartSolution: { | |||||
| label: "预设起始源溶液浓度", | |||||
| type: "inputNumber", | |||||
| subType: "select", | |||||
| fillType: "preFill", | |||||
| subOptions: this.getDictOptions('business_nddw'), | |||||
| subKey: "subTargetStartSolution", | |||||
| maxlength: 10, | |||||
| }, | |||||
| targetAcSolution: { | |||||
| label: "实际起始源溶液浓度", | |||||
| type: "input", | |||||
| fillType: "actFill", | |||||
| disabled: true, | |||||
| maxlength: 10, | |||||
| }, | |||||
| solution: { | |||||
| label: "稀释液", | |||||
| type: "input", | |||||
| fillType: "preFill", | |||||
| subType: "clickable", | |||||
| subKey: "subSolution", | |||||
| subFillType: "actFill", | |||||
| maxlength: 20, | |||||
| }, | |||||
| codeSTD: { | |||||
| label: "起始编号STD", | |||||
| type: "input", | |||||
| maxlength: 10, | |||||
| fillType: "preFill", | |||||
| }, | |||||
| stepStorageCondition: { | |||||
| label: "存储条件", | |||||
| type: "select", | |||||
| fillType: "preFill", | |||||
| options: this.getDictOptions('business_cctj'), | |||||
| otherCode: "stepStorageConditionOther", | |||||
| }, | |||||
| effectivePeriod: { | |||||
| label: "目标溶液有效周期", | |||||
| type: "input", | |||||
| subType: "select", | |||||
| subKey: "effectivePeriodUnit", | |||||
| fillType: "preFill", | |||||
| subOptions: this.getDictOptions('business_yxqdw'), | |||||
| }, | |||||
| expireDate: { | |||||
| label: "目标溶液失效日", | |||||
| type: "input", | |||||
| }, | |||||
| } | |||||
| } | |||||
| ] | |||||
| }, | |||||
| paralleStepColumns() { | |||||
| return [ | |||||
| { | |||||
| label: "目标溶液编号", | |||||
| prop: "targetSolutionCode", | |||||
| bodyType: "input", | |||||
| subType: "span", | |||||
| subKey: "subTargetSolutionCode", | |||||
| bodyFillType: "preFill", | |||||
| width: 280 | |||||
| }, | |||||
| { | |||||
| label: "起始溶液编号", | |||||
| prop: "startSolutionCode", | |||||
| width: 280, | |||||
| bodyType: "input", | |||||
| bodyFillType: "actFill", | |||||
| bodyMaxlength: 10, | |||||
| }, | |||||
| { | |||||
| label: "预设起始溶液体积", | |||||
| prop: "targetStartSolutionVolume", | |||||
| width: 280, | |||||
| headerSelectKey: "targetStartSolutionVolumeUnit", | |||||
| fillType: "preFill", | |||||
| headerOptions: this.getDictOptions('business_tjdw'), | |||||
| defaultValue: "mg", | |||||
| bodyType: "inputNumber", | |||||
| bodySubType: "inputNumber", | |||||
| bodySubKey: "targetStartSolutionVolumePrecision", | |||||
| bodyFillType: "preFill", | |||||
| bodySubFillType: "preFill", | |||||
| showBodySub: this.fillType === "preFill", | |||||
| bodyDisabled: true, | |||||
| bodyPrecisionKey: "targetStartSolutionVolumePrecision", | |||||
| bodyMaxlength: 10, | |||||
| bodySubPlaceholder: "请输入保留小数位数", | |||||
| }, | |||||
| { | |||||
| label: "实际起始溶液体积", | |||||
| prop: "actStartSolutionVolume", | |||||
| width: 280, | |||||
| headerSelectKey: "actStartSolutionVolumeUnit", | |||||
| fillType: "preFill", | |||||
| headerOptions: this.getDictOptions('business_tjdw'), | |||||
| bodyType: "inputNumber", | |||||
| bodyFillType: "actFill", | |||||
| bodyMaxlength: 10, | |||||
| copyFrom: "targetStartSolutionVolume",//复制哪个字段 | |||||
| }, | |||||
| { | |||||
| label: "预设稀释液体积", | |||||
| prop: "targetDiluentVolume", | |||||
| width: 280, | |||||
| headerSelectKey: "targetDiluentVolumeUnit", | |||||
| fillType: "preFill", | |||||
| headerOptions: this.getDictOptions('business_tjdw'), | |||||
| defaultValue: "mg", | |||||
| bodyType: "inputNumber", | |||||
| bodySubType: "inputNumber", | |||||
| bodySubKey: "targetDiluentVolumePrecision", | |||||
| bodyFillType: "preFill", | |||||
| bodySubFillType: "preFill", | |||||
| showBodySub: this.fillType === "preFill", | |||||
| bodyDisabled: true, | |||||
| bodyPrecisionKey: "targetDiluentVolumePrecision", | |||||
| bodyMaxlength: 10, | |||||
| bodySubPlaceholder: "请输入保留小数位数", | |||||
| }, | |||||
| { | |||||
| label: "实际稀释液体积", | |||||
| prop: "actDiluentVolume", | |||||
| width: 280, | |||||
| headerSelectKey: "actDiluentVolumeUnit", | |||||
| fillType: "preFill", | |||||
| headerOptions: this.getDictOptions('business_tjdw'), | |||||
| bodyType: "inputNumber", | |||||
| bodyFillType: "actFill", | |||||
| bodyMaxlength: 10, | |||||
| copyFrom: "targetDiluentVolume",//复制哪个字段 | |||||
| }, | |||||
| { | |||||
| label: "预设目标溶液浓度", | |||||
| prop: "targetSolutionConcentration", | |||||
| width: 280, | |||||
| headerSelectKey: "targetSolutionConcentrationUnit", | |||||
| fillType: "preFill", | |||||
| headerOptions: this.getDictOptions('business_nddw'), | |||||
| bodyType: "inputNumber", | |||||
| bodyFillType: "preFill", | |||||
| bodyMaxlength: 10, | |||||
| }, | |||||
| { | |||||
| label: "实际目标溶液浓度", | |||||
| prop: "actSolutionConcentration", | |||||
| width: 280, | |||||
| headerSelectKey: "actSolutionConcentrationUnit", | |||||
| fillType: "preFill", | |||||
| headerOptions: this.getDictOptions('business_nddw'), | |||||
| defaultValue: "mg", | |||||
| bodyType: "inputNumber", | |||||
| bodySubType: "inputNumber", | |||||
| bodySubKey: "actSolutionConcentrationPrecision", | |||||
| bodyFillType: "actFill", | |||||
| bodySubFillType: "preFill", | |||||
| showBodySub: this.fillType === "preFill", | |||||
| bodyDisabled: true, | |||||
| bodyPrecisionKey: "actSolutionConcentrationPrecision", | |||||
| bodyMaxlength: 10, | |||||
| copyFrom: "targetSolutionConcentration",//复制哪个字段 | |||||
| bodySubPlaceholder: "请输入保留小数位数", | |||||
| }, | |||||
| { | |||||
| label: "预设目标溶液体积", | |||||
| prop: "targetSolutionVolume", | |||||
| width: 280, | |||||
| headerSelectKey: "targetSolutionVolumeUnit", | |||||
| fillType: "preFill", | |||||
| headerOptions: this.getDictOptions('business_tjdw'), | |||||
| bodyType: "inputNumber", | |||||
| bodyFillType: "preFill", | |||||
| bodyMaxlength: 10, | |||||
| }, | |||||
| { | |||||
| label: "实际目标溶液体积", | |||||
| prop: "actSolutionVolume", | |||||
| width: 280, | |||||
| headerSelectKey: "actSolutionVolumeUnit", | |||||
| fillType: "preFill", | |||||
| headerOptions: this.getDictOptions('business_tjdw'), | |||||
| defaultValue: "mg", | |||||
| bodyType: "inputNumber", | |||||
| bodySubType: "inputNumber", | |||||
| bodySubKey: "actSolutionVolumePrecision", | |||||
| bodyFillType: "actFill", | |||||
| bodySubFillType: "preFill", | |||||
| showBodySub: this.fillType === "preFill", | |||||
| bodyDisabled: true, | |||||
| bodyPrecisionKey: "actSolutionVolumePrecision", | |||||
| bodyMaxlength: 10, | |||||
| copyFrom: "targetSolutionVolume",//复制哪个字段 | |||||
| bodySubPlaceholder: "请输入保留小数位数", | |||||
| }, | |||||
| ] | |||||
| }, | |||||
| // 步骤表格列配置 | |||||
| ladderStepColumns() { | |||||
| return [ | |||||
| { | |||||
| label: "目标溶液编号", | |||||
| prop: "targetSolutionCode", | |||||
| bodyType: "input", | |||||
| subType: "span", | |||||
| subKey: "subTargetSolutionCode", | |||||
| bodyFillType: "preFill", | |||||
| width: 280 | |||||
| }, | |||||
| { | |||||
| label: "起始溶液编号", | |||||
| prop: "startSolutionCode", | |||||
| width: 280, | |||||
| bodyType: "input", | |||||
| bodyFillType: "actFill", | |||||
| bodyMaxlength: 10, | |||||
| }, | |||||
| { | |||||
| label: "预设起始溶液体积", | |||||
| prop: "targetStartSolutionVolume", | |||||
| width: 280, | |||||
| headerSelectKey: "targetStartSolutionVolumeUnit", | |||||
| fillType: "preFill", | |||||
| headerOptions: this.getDictOptions('business_tjdw'), | |||||
| defaultValue: "mg", | |||||
| bodyType: "inputNumber", | |||||
| bodySubType: "inputNumber", | |||||
| bodySubKey: "targetStartSolutionVolumePrecision", | |||||
| bodyFillType: "preFill", | |||||
| bodySubFillType: "preFill", | |||||
| showBodySub: this.fillType === "preFill", | |||||
| bodyDisabled: true, | |||||
| bodyPrecisionKey: "targetStartSolutionVolumePrecision", | |||||
| bodyMaxlength: 10, | |||||
| bodySubPlaceholder: "请输入保留小数位数", | |||||
| }, | |||||
| { | |||||
| label: "实际起始溶液体积", | |||||
| prop: "actStartSolutionVolume", | |||||
| width: 280, | |||||
| headerSelectKey: "actStartSolutionVolumeUnit", | |||||
| fillType: "preFill", | |||||
| headerOptions: this.getDictOptions('business_tjdw'), | |||||
| bodyType: "inputNumber", | |||||
| bodyFillType: "actFill", | |||||
| bodyMaxlength: 10, | |||||
| copyFrom: "targetStartSolutionVolume",//复制哪个字段 | |||||
| }, | |||||
| { | |||||
| label: "预设稀释液体积", | |||||
| prop: "targetDiluentVolume", | |||||
| width: 280, | |||||
| headerSelectKey: "targetDiluentVolumeUnit", | |||||
| fillType: "preFill", | |||||
| headerOptions: this.getDictOptions('business_tjdw'), | |||||
| defaultValue: "mg", | |||||
| bodyType: "inputNumber", | |||||
| bodySubType: "inputNumber", | |||||
| bodySubKey: "targetDiluentVolumePrecision", | |||||
| bodyFillType: "preFill", | |||||
| bodySubFillType: "preFill", | |||||
| showBodySub: this.fillType === "preFill", | |||||
| bodyDisabled: true, | |||||
| bodyPrecisionKey: "targetDiluentVolumePrecision", | |||||
| bodyMaxlength: 10, | |||||
| bodySubPlaceholder: "请输入保留小数位数", | |||||
| }, | |||||
| { | |||||
| label: "实际稀释液体积", | |||||
| prop: "actDiluentVolume", | |||||
| width: 280, | |||||
| headerSelectKey: "actDiluentVolumeUnit", | |||||
| fillType: "preFill", | |||||
| headerOptions: this.getDictOptions('business_tjdw'), | |||||
| bodyType: "inputNumber", | |||||
| bodyFillType: "actFill", | |||||
| bodyMaxlength: 10, | |||||
| copyFrom: "targetDiluentVolume",//复制哪个字段 | |||||
| }, | |||||
| { | |||||
| label: "预设目标溶液浓度", | |||||
| prop: "targetSolutionConcentration", | |||||
| width: 280, | |||||
| headerSelectKey: "targetSolutionConcentrationUnit", | |||||
| fillType: "preFill", | |||||
| headerOptions: this.getDictOptions('business_nddw'), | |||||
| bodyType: "inputNumber", | |||||
| bodyFillType: "preFill", | |||||
| bodyMaxlength: 10, | |||||
| }, | |||||
| { | |||||
| label: "实际目标溶液浓度", | |||||
| prop: "actSolutionConcentration", | |||||
| width: 280, | |||||
| headerSelectKey: "actSolutionConcentrationUnit", | |||||
| fillType: "preFill", | |||||
| headerOptions: this.getDictOptions('business_nddw'), | |||||
| defaultValue: "mg", | |||||
| bodyType: "inputNumber", | |||||
| bodySubType: "inputNumber", | |||||
| bodySubKey: "actSolutionConcentrationPrecision", | |||||
| bodyFillType: "actFill", | |||||
| bodySubFillType: "preFill", | |||||
| showBodySub: this.fillType === "preFill", | |||||
| bodyDisabled: true, | |||||
| bodyPrecisionKey: "actSolutionConcentrationPrecision", | |||||
| bodyMaxlength: 10, | |||||
| copyFrom: "targetSolutionConcentration",//复制哪个字段 | |||||
| bodySubPlaceholder: "请输入保留小数位数", | |||||
| }, | |||||
| { | |||||
| label: "预设目标溶液体积", | |||||
| prop: "targetSolutionVolume", | |||||
| width: 280, | |||||
| headerSelectKey: "targetSolutionVolumeUnit", | |||||
| fillType: "preFill", | |||||
| headerOptions: this.getDictOptions('business_tjdw'), | |||||
| bodyType: "inputNumber", | |||||
| bodyFillType: "preFill", | |||||
| bodyMaxlength: 10, | |||||
| }, | |||||
| { | |||||
| label: "实际目标溶液体积", | |||||
| prop: "actSolutionVolume", | |||||
| width: 280, | |||||
| headerSelectKey: "actSolutionVolumeUnit", | |||||
| fillType: "preFill", | |||||
| headerOptions: this.getDictOptions('business_tjdw'), | |||||
| defaultValue: "mg", | |||||
| bodyType: "inputNumber", | |||||
| bodySubType: "inputNumber", | |||||
| bodySubKey: "actSolutionVolumePrecision", | |||||
| bodyFillType: "actFill", | |||||
| bodySubFillType: "preFill", | |||||
| showBodySub: this.fillType === "preFill", | |||||
| bodyDisabled: true, | |||||
| bodyPrecisionKey: "actSolutionVolumePrecision", | |||||
| bodyMaxlength: 10, | |||||
| copyFrom: "targetSolutionVolume",//复制哪个字段 | |||||
| bodySubPlaceholder: "请输入保留小数位数", | |||||
| }, | |||||
| ] | |||||
| }, | |||||
| }, | |||||
| data() { | |||||
| return { | |||||
| selectReagentVisible: false, | |||||
| subSolutionVisible: false, | |||||
| currentSubKey: "",//当前点击的子项key | |||||
| dataSource: [], | |||||
| stepTableDataSource: [], | |||||
| sysjColumns: [ | |||||
| { label: "试剂名称", prop: "reagentName" }, | |||||
| { label: "编号", prop: "reagentCode" }, | |||||
| { label: "批号", prop: "reagentNo" }, | |||||
| { label: "浓度/含量/纯度", prop: "concentration" }, | |||||
| { label: "来源", prop: "source" }, | |||||
| { label: "失效日", prop: "expireDate" }, | |||||
| ], | |||||
| yqsColumns: [ | |||||
| { label: "仪器名称", prop: "instrumentName" }, | |||||
| { label: "仪器型号", prop: "instrumentModel" }, | |||||
| { label: "仪器编号", prop: "instrumentCode" }, | |||||
| { label: "下次测试/校准/检定日期", prop: "nextTestDate" }, | |||||
| ], | |||||
| }; | |||||
| }, | |||||
| mounted() { | |||||
| if (this.fillType === "preFill") { | |||||
| this.formData = { | |||||
| effectivePeriodUnit: "days",//设置默认值 | |||||
| createTime: "2026-01-02 18:05:36",//设置默认值 | |||||
| versionNum: 1, | |||||
| stepTableFormData: [], | |||||
| ladderConfigs: [], // 阶梯配制配置列表 | |||||
| paralleConfigs: [], // 平行配制配置列表 | |||||
| headerSelectFields: { | |||||
| targetStartSolutionVolumeUnit: "mg", | |||||
| actStartSolutionVolumeUnit: "mg", | |||||
| targetDiluentVolumeUnit: "mg", | |||||
| actDiluentVolumeUnit: "mg", | |||||
| targetSolutionConcentrationUnit: "mg", | |||||
| actSolutionConcentrationUnit: "mg", | |||||
| targetSolutionVolumeUnit: "mg", | |||||
| actSolutionVolumeUnit: "mg", | |||||
| } | |||||
| } | |||||
| } | |||||
| }, | |||||
| methods: { | |||||
| //新增平行配制 | |||||
| handleAddParalle() { | |||||
| // 初始化平行配制配置列表 | |||||
| if (!this.formData.paralleConfigs) { | |||||
| this.$set(this.formData, 'paralleConfigs', []); | |||||
| } | |||||
| // 添加新的平行配制配置 | |||||
| this.formData.paralleConfigs.push({ | |||||
| paralleStepData: [], | |||||
| paralleTableFormData: [], | |||||
| showParalleConfig: true | |||||
| }); | |||||
| }, | |||||
| //新增阶梯配制 | |||||
| handleAddLadder() { | |||||
| // 初始化阶梯配制配置列表 | |||||
| if (!this.formData.ladderConfigs) { | |||||
| this.$set(this.formData, 'ladderConfigs', []); | |||||
| } | |||||
| // 添加新的阶梯配制配置 | |||||
| this.formData.ladderConfigs.push({ | |||||
| ladderStepData: [], | |||||
| ladderTableFormData: [], | |||||
| showLadderConfig: true | |||||
| }); | |||||
| }, | |||||
| // 删除阶梯配制配置 | |||||
| deleteLadderConfig(index) { | |||||
| this.formData.ladderConfigs.splice(index, 1); | |||||
| }, | |||||
| // 删除平行配制配置 | |||||
| deleteParalleConfig(index) { | |||||
| this.formData.paralleConfigs.splice(index, 1); | |||||
| }, | |||||
| // 添加表格行 | |||||
| handleAddRow(type, rowIndex, configIndex = 0) { | |||||
| const tableRef = type === 'ladder' ? | |||||
| this.$refs[`ladderStepTableRef_${configIndex}`] : | |||||
| this.$refs[`paralleStepTableRef_${configIndex}`]; | |||||
| console.log(tableRef,"refff") | |||||
| if (tableRef && tableRef[0].addRow) { | |||||
| tableRef[0].addRow({}); | |||||
| } | |||||
| }, | |||||
| // 删除表格行 | |||||
| deleteRow(rowIndex, type, configIndex = 0) { | |||||
| // 根据类型删除对应的表格行 | |||||
| if (type === 'ladder') { | |||||
| const tableRef = this.$refs[`ladderStepTableRef_${configIndex}`]; | |||||
| if (tableRef) { | |||||
| tableRef.deleteRow(rowIndex); | |||||
| } | |||||
| } else if (type === 'paralle') { | |||||
| const tableRef = this.$refs[`paralleStepTableRef_${configIndex}`]; | |||||
| if (tableRef) { | |||||
| tableRef.deleteRow(rowIndex); | |||||
| } | |||||
| } | |||||
| }, | |||||
| handleClickable(item) { | |||||
| if (this.fillType === "preFill") { | |||||
| // return; | |||||
| } | |||||
| const { subKey = "" } = item; | |||||
| if (subKey === "subStartSolution" || subKey === "subSolution") {//起始源溶液点击事件 | |||||
| this.selectReagentVisible = true; | |||||
| this.currentSubKey = subKey; | |||||
| } | |||||
| }, | |||||
| //选择试剂提交事件 | |||||
| onSelectReagentSubmit(code) { | |||||
| this.$refs.stepFormPackageRef.updateFormData(this.currentSubKey, code); | |||||
| this.selectReagentVisible = false; | |||||
| }, | |||||
| async getFormData() { | |||||
| const baseData = await this.$refs.baseInfoRef.getFormData(); | |||||
| const conditionData = await this.$refs.storageConditionRef.getFormData(); | |||||
| // 获取所有阶梯配制数据 | |||||
| const ladderConfigsData = []; | |||||
| if (this.formData.ladderConfigs && this.formData.ladderConfigs.length > 0) { | |||||
| for (let i = 0; i < this.formData.ladderConfigs.length; i++) { | |||||
| const ladderFormData = await this.$refs[`ladderStepFormPackageRef_${i}`][0].getFormData(); | |||||
| const ladderTableFormData = await this.$refs[`ladderStepTableRef_${i}`][0].getFormData(); | |||||
| const ladderStepData = await this.$refs[`ladderStepRef_${i}`][0].getFormData(); | |||||
| ladderConfigsData.push({ | |||||
| ...ladderFormData, | |||||
| ...ladderTableFormData, | |||||
| ladderStepData, | |||||
| showLadderConfig: true | |||||
| }); | |||||
| } | |||||
| } | |||||
| // 获取所有平行配制数据 | |||||
| const paralleConfigsData = []; | |||||
| if (this.formData.paralleConfigs && this.formData.paralleConfigs.length > 0) { | |||||
| for (let i = 0; i < this.formData.paralleConfigs.length; i++) { | |||||
| const paralleFormData = await this.$refs[`paralleStepFormPackageRef_${i}`][0].getFormData(); | |||||
| const paralleTableFormData = await this.$refs[`paralleStepTableRef_${i}`][0].getFormData(); | |||||
| const paralleStepData = await this.$refs[`paralleStepRef_${i}`][0].getFormData(); | |||||
| paralleConfigsData.push({ | |||||
| ...paralleFormData, | |||||
| ...paralleTableFormData, | |||||
| paralleStepData, | |||||
| showParalleConfig: true | |||||
| }); | |||||
| } | |||||
| } | |||||
| const remarkData = await this.$refs.remarkRef.getFormData(); | |||||
| return { | |||||
| ...baseData, | |||||
| ...conditionData, | |||||
| ladderConfigs: ladderConfigsData, | |||||
| paralleConfigs: paralleConfigsData, | |||||
| ...remarkData | |||||
| } | |||||
| }, | |||||
| async onSave() { | |||||
| const formData = await this.getFormData(); | |||||
| console.log(formData, "formData") | |||||
| } | |||||
| } | |||||
| }; | |||||
| </script> | |||||
| <style rel="stylesheet/scss" lang="scss"> | |||||
| .mt-20 { | |||||
| margin-top: 20px; | |||||
| } | |||||
| .config-section { | |||||
| margin-bottom: 20px; | |||||
| padding: 15px; | |||||
| border: 1px solid #ebeef5; | |||||
| border-radius: 4px; | |||||
| background-color: #fafafa; | |||||
| } | |||||
| .config-header { | |||||
| display: flex; | |||||
| justify-content: space-between; | |||||
| align-items: center; | |||||
| margin-bottom: 15px; | |||||
| font-weight: bold; | |||||
| font-size: 16px; | |||||
| color: #303133; | |||||
| } | |||||
| .config-header .el-button { | |||||
| color: #f56c6c; | |||||
| font-size: 14px; | |||||
| } | |||||
| .config-header .el-button:hover { | |||||
| color: #f78989; | |||||
| } | |||||
| .add-row { | |||||
| display: flex; | |||||
| align-items: center; | |||||
| padding: 20px 0; | |||||
| border-bottom: 1px solid #ebeef5; | |||||
| } | |||||
| .mt-0{ | |||||
| margin-top: 0; | |||||
| } | |||||
| </style> | |||||