From 8b3cd24d366282b56ff5a321b1c2fca3c7dfced1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=AC=A7=E9=AA=9E?= Date: Thu, 12 Mar 2026 18:30:26 +0800 Subject: [PATCH] =?UTF-8?q?feat:[=E6=A8=A1=E6=9D=BF=E7=AE=A1=E7=90=86][DL0?= =?UTF-8?q?07~DL009=E5=89=8D=E5=BA=8F=E8=A1=A8=E5=8D=95=E9=80=BB=E8=BE=91]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/lang/en/template/dl.js | 11 +- src/lang/zh/template/dl.js | 11 +- .../business/comps/template/comps/dl/DL007.vue | 19 +- .../business/comps/template/comps/dl/DL008.vue | 409 +++++++++++---- .../business/comps/template/comps/dl/DL009.vue | 554 +++++++++++++++++++-- 5 files changed, 849 insertions(+), 155 deletions(-) diff --git a/src/lang/en/template/dl.js b/src/lang/en/template/dl.js index 9986b57..697f361 100644 --- a/src/lang/en/template/dl.js +++ b/src/lang/en/template/dl.js @@ -77,7 +77,8 @@ export default { czxx: 'Operation Information', pykssj: 'Cultivation Start Time', pyjssj: 'Cultivation End Time', - jsButton: 'End' + jsButton: 'End', + yqsyxxEmpty: 'Please add instrument usage information first' }, dl008: { ...common, @@ -87,7 +88,9 @@ export default { jzbh1: 'Strain Number', jzbh2: 'Strain Number', jzbh3: 'Strain Number', - jzbh4: 'Strain Number' + jzbh4: 'Strain Number', + yqsyxxEmpty: 'Instrument usage information cannot be empty', + cxqkEmpty: 'Imaging status cannot be empty' }, dl009: { ...common, @@ -103,7 +106,9 @@ export default { jls: 'Colony Count', czqkDesc: 'Precipitation codes: "P-" = "None"; "P+" = "Slight"; "P++" = "Moderate"; "P+++" = "Severe".', bjjtDesc: 'Background lawn codes: "N" = "Normal"; "R1" = "Weak, lawn covers 70%-90% of plate area"; "R2" = "Medium, lawn covers 40%-70% of plate area"; "R3" = "Strong, lawn covers 10%-40% of plate area"; "A" = "Absent, no lawn on plate"; "O" = "Precipitation present, affecting lawn assessment";', - jlsDesc: 'Colony count special case: "*" indicates pinpoint colonies visible on plate;' + jlsDesc: 'Colony count special case: "*" indicates pinpoint colonies visible on plate;', + yqsyxxEmpty: 'Instrument usage information cannot be empty', + jgxxEmpty: 'Result information cannot be empty' }, dl010: { ...common, diff --git a/src/lang/zh/template/dl.js b/src/lang/zh/template/dl.js index 7e49c41..7a84046 100644 --- a/src/lang/zh/template/dl.js +++ b/src/lang/zh/template/dl.js @@ -80,7 +80,8 @@ export default { czxx: '操作信息', pykssj: '培养开始时间', pyjssj: '培养结束时间', - jsButton: '结束' + jsButton: '结束', + yqsyxxEmpty: '请先添加仪器使用信息' }, dl008: { ...common, @@ -90,7 +91,9 @@ export default { jzbh1: '菌种编号', jzbh2: '菌种编号', jzbh3: '菌种编号', - jzbh4: '菌种编号' + jzbh4: '菌种编号', + yqsyxxEmpty: '仪器使用信息不能为空', + cxqkEmpty: '成像情况不能为空' }, dl009: { ...common, @@ -106,7 +109,9 @@ export default { jls: '菌落数(个)', czqkDesc: '沉淀量以代码填入:"P-" 代表 "无沉淀";"P+" 代表 "少量";"P++" 代表 "中等";"P+++" 代表 "严重"。', bjjtDesc: '背景菌苔以代码填入:"N" 代表 "正常";"R1" 代表 "弱,菌苔约占平皿面积 70%-90%";"R2" 代表 "中,菌苔约占平皿面积 40%-70%";"R3" 代表 "强,菌苔约占平皿面积 10%-40%";"A" 代表 "消失,平皿上无菌苔";"O" 代表 "产生沉淀,影响背景菌苔判断";', - jlsDesc: '菌落数特殊情况:"*" 该平皿可见针尖样菌落;' + jlsDesc: '菌落数特殊情况:"*" 该平皿可见针尖样菌落;', + yqsyxxEmpty: '仪器使用信息不能为空', + jgxxEmpty: '结果信息不能为空' }, dl010: { ...common, diff --git a/src/views/business/comps/template/comps/dl/DL007.vue b/src/views/business/comps/template/comps/dl/DL007.vue index e177c8e..ad9fccd 100644 --- a/src/views/business/comps/template/comps/dl/DL007.vue +++ b/src/views/business/comps/template/comps/dl/DL007.vue @@ -50,7 +50,7 @@ fieldItemLabel="template.dl.dl007.bz" label="template.dl.dl007.bz" :ref="refConf.remark" - :formConfig="remarkConig" + :formConfig="remarkConfig" :formData="formData" /> @@ -79,6 +79,7 @@ const refNames = Object.values(refConf) export default { name: 'DL007', + dicts: ['business_sydd'], components: { BaseInfoFormPackage, LineLabel, @@ -96,7 +97,7 @@ export default { }, computed: { // 备注表单配置 - remarkConig() { + remarkConfig() { return [ { type: 'cellItem', @@ -257,10 +258,21 @@ export default { }, // 获取填写完成的表单数据 async getFormData() { - return await this.validFormFields(refNames) + // 先执行自定义校验(包括表格非空校验) + return await this.validFields() }, // 只做校验 async validFields() { + // 1. 校验仪器使用信息表格是否为空 + const yqsyTableRef = this.$refs[refConf.yqsy] + const yqsyTableData = yqsyTableRef?.getDataSource() || [] + + if (yqsyTableData.length === 0) { + this.$message.warning(this.$t('template.dl.dl007.yqsyxxEmpty')) + return Promise.reject(this.$t('template.dl.dl007.yqsyxxEmpty')) + } + + // 2. 执行其他表单字段校验 return await this.validFormFields(refNames) }, getResource() { @@ -307,7 +319,6 @@ export default { // 保存 async onSave() { const formData = this.getStepResource() - console.log(formData, 'formData') } } } diff --git a/src/views/business/comps/template/comps/dl/DL008.vue b/src/views/business/comps/template/comps/dl/DL008.vue index c3b3023..84a8128 100644 --- a/src/views/business/comps/template/comps/dl/DL008.vue +++ b/src/views/business/comps/template/comps/dl/DL008.vue @@ -85,7 +85,6 @@ import TableOpertaionDelete from '@/components/Template/operation/TableOpertaion import CustomTable from '@/components/Template/CustomTable.vue' import LineLabel from '@/components/Template/LineLabel' import TableList from '@/components/Template/Table' -import Step from '@/components/Template/Step' import templateMixin from '../../mixins/templateMixin' import moment from 'moment' const refConf = { @@ -100,11 +99,11 @@ const refNames = Object.values(refConf) export default { name: 'DL008', + dicts: ['business_sydd', 'business_dl_ameswrqk'], components: { BaseInfoFormPackage, LineLabel, TableList, - Step, CustomTable, TableOpertaionDelete }, @@ -213,44 +212,8 @@ export default { }, // 成像情况-checkbox网格配置 cxqkColumns() { - return [ - { - label: 'template.dl.dl008.jlzb', - prop: 'jlzb', - bodyType: 'input', - bodyFillType: 'actFill', - disabled: true, - width: 100 - }, - { - label: 'template.dl.dl008.jzbh1', - prop: 'jzbh1', - bodyType: 'checkbox', - bodyFillType: 'actFill', - width: 150 - }, - { - label: 'template.dl.dl008.jzbh2', - prop: 'jzbh2', - bodyType: 'checkbox', - bodyFillType: 'actFill', - width: 150 - }, - { - label: 'template.dl.dl008.jzbh3', - prop: 'jzbh3', - bodyType: 'checkbox', - bodyFillType: 'actFill', - width: 150 - }, - { - label: 'template.dl.dl008.jzbh4', - prop: 'jzbh4', - bodyType: 'checkbox', - bodyFillType: 'actFill', - width: 150 - } - ] + // 只有在有动态列配置时才返回列配置,否则返回空数组(不显示表格) + return this.dynamicCxqkColumns }, // 仪器使用信息 yqsyColumns() { @@ -296,7 +259,7 @@ export default { config: { cxqkqxbd: { label: 'template.dl.dl007.qxbd', - qxbdType: 'DL006', + // qxbdType: 'DL006', type: 'qxbd', fillType: 'actFill', filledCodes: ['bdmc', 'bdbh'] @@ -309,15 +272,105 @@ export default { data() { return { formData: {}, - refConf + refConf, + dynamicCxqkColumns: [], // 动态成像情况表格列配置 + isDataLoaded: false // 标记数据是否已加载 + } + }, + mounted() { + // 组件挂载后,检查是否有已填报的数据需要回显 + this.$nextTick(() => { + this.initializeTableFromFormData() + }) + }, + watch: { + // 监听 formData 变化,用于数据回显 + 'formData.stepTableFormData_1': { + handler(newVal) { + if (newVal && newVal.length > 0 && !this.isDataLoaded) { + this.initializeTableFromFormData() + } + }, + deep: true, + immediate: true } }, - mounted() {}, methods: { // 删除表格行 deleteTableRow(rowIndex, refName) { this.$refs[refName].deleteRow(rowIndex) }, + // 从已填报数据初始化表格(用于数据回显) + initializeTableFromFormData() { + try { + const stepTableFormData_1 = this.formData.stepTableFormData_1 + const headerSelectFields = this.formData.headerSelectFields || {} + + // 如果没有数据或已经加载过,不处理 + if (!stepTableFormData_1 || stepTableFormData_1.length === 0 || this.isDataLoaded) { + return + } + + // 从第一行数据中提取列信息(查找 jzbh 开头的 Label 字段) + const firstRow = stepTableFormData_1[0] + const labelKeys = Object.keys(firstRow).filter(key => key.match(/^jzbh\d+Label$/)) + + if (labelKeys.length === 0) { + return + } + + // 根据已有的 Label 字段生成动态列配置 + const dynamicColumns = [ + { + label: 'template.dl.dl008.jlzb', + prop: 'jlzb', + bodyType: 'input', + bodyFillType: 'actFill', + bodyDisabled: true, + disabled: true, + width: 100 + } + ] + + // 从 headerSelectFields 生成表头 + labelKeys.sort().forEach((labelKey, index) => { + const colIndex = index + 1 + + // 收集该列的所有 headerSelectFields 值(如 1_1, 1_2, 1_3) + const headerValues = [] + let rowIndex = 1 + while (headerSelectFields[`${colIndex}_${rowIndex}`]) { + headerValues.push(headerSelectFields[`${colIndex}_${rowIndex}`]) + rowIndex++ + } + + // 将多个值用空格拼接,如果没有则使用默认值 + const headerLabel = headerValues.length > 0 ? headerValues.join(' ') : `菌种${colIndex}` + + dynamicColumns.push({ + label: headerLabel, + prop: `jzbh${colIndex}`, + bodyType: 'checkbox', + bodyFillType: 'actFill', + checkboxLabel: '', + width: 150 + }) + }) + + // 更新动态列配置 + this.dynamicCxqkColumns = dynamicColumns + this.isDataLoaded = true + + // 等待列配置更新后,更新表格数据 + this.$nextTick(() => { + if (this.$refs[refConf.cxqk]) { + this.$refs[refConf.cxqk].updateDataSource(stepTableFormData_1) + } + }) + } catch (error) { + console.error('初始化表格数据失败:', error) + } + }, // 点击按钮 handleClickButton(_item, signData) { this.$refs.cxqkqxbbInfoRef.updateFormData( @@ -328,79 +381,249 @@ export default { }, //获取已填写的表单数据 getFilledFormData() { - return this.getFilledFormDataByRefs(refNames) + const baseData = this.getFilledFormDataByRefs(refNames) + + // 从成像情况表格中获取最新数据 + const cxqkTableRef = this.$refs[refConf.cxqk] + if (cxqkTableRef) { + const cxqkData = cxqkTableRef.getFilledFormData() + baseData.stepTableFormData_1 = cxqkData.stepTableFormData || [] + } + + // 确保 headerSelectFields 被包含在返回的数据中 + if (this.formData.headerSelectFields) { + baseData.headerSelectFields = this.formData.headerSelectFields + } + + return baseData }, //获取填写完成的表单数据 async getFormData() { - return await this.validFormFields(refNames) + // 先执行自定义校验(包括表格非空校验) + return await this.validFields() }, //只做校验 async validFields() { + // 1. 校验仪器使用信息表格是否为空 + const yqsyTableRef = this.$refs[refConf.yqsy] + const yqsyTableData = yqsyTableRef?.getDataSource() || [] + + if (yqsyTableData.length === 0) { + this.$message.warning(this.$t('template.dl.dl008.yqsyxxEmpty')) + return Promise.reject(this.$t('template.dl.dl008.yqsyxxEmpty')) + } + + // 2. 校验成像情况表格是否为空 + const cxqkTableRef = this.$refs[refConf.cxqk] + const cxqkTableData = cxqkTableRef?.getDataSource() || [] + + if (cxqkTableData.length === 0) { + this.$message.warning(this.$t('template.dl.dl008.cxqkEmpty')) + return Promise.reject(this.$t('template.dl.dl008.cxqkEmpty')) + } + + // 3. 执行其他表单字段校验 return await this.validFormFields(refNames) }, getResource() { - const stepResource = this.$refs.yqsyTableRef.getStepResource() - // 使用的试剂、仪器 - this.resourceTmp = stepResource.sjResource || [] - this.yqResourceTmp = stepResource.yqResource || [] + const yqsyData = this.$refs.yqsyTableRef?.getFilledFormData() + const yqsyList = yqsyData?.stepTableFormData || [] + + // 从仪器使用信息表格中提取仪器资源 + this.yqResourceTmp = yqsyList + .filter((item) => item.yqbh) + .map((item) => ({ + bh: item.yqbh, + type: 'yq' + })) + + this.resourceTmp = [] return this.resourceTmp }, onRegentSubmit(e) { const { selectInfo, key, rowIndex } = e const { row } = selectInfo + // 处理仪器编号选择 if (key === 'yqbh') { - const params = { - yqmc: row.mc, - yqxh: row.xh, - jzrq: row.jzrq - } - this.$refs.yqsyTableRef.updateDataSourceByRowIndex(rowIndex, params) + this.handleYqbhSelect(row, rowIndex) + return } + + // 处理成像情况前序表单选择 if (key === 'cxqkqxbd') { - // MOCK:模拟数据回显 - const mockData = [ - { - jlzb: 'A', - jzbh1: undefined, - jzbh2: undefined, - jzbh3: undefined, - jzbh4: undefined, - jzbh1Label: '001', - jzbh2Label: '004', - jzbh3Label: '007', - jzbh4Label: '010' - }, - { - jlzb: 'A', - jzbh1: undefined, - jzbh2: undefined, - jzbh3: undefined, - jzbh4: undefined, - jzbh1Label: '002', - jzbh2Label: '005', - jzbh3Label: '008', - jzbh4Label: '011' - }, - { - jlzb: 'A', - jzbh1: undefined, - jzbh2: undefined, - jzbh3: undefined, - jzbh4: undefined, - jzbh1Label: '003', - jzbh2Label: '006', - jzbh3Label: '009', - jzbh4Label: '012' - } - ] - this.$refs[refConf.cxqk].updateDataSource(mockData) + this.handleCxqkQxbdSelect(row) } }, + + // 处理仪器编号选择 + handleYqbhSelect(row, rowIndex) { + const params = { + yqmc: row.mc, + yqxh: row.xh, + jzrq: row.jzrq + } + this.$refs.yqsyTableRef.updateDataSourceByRowIndex(rowIndex, params) + }, + + // 处理成像情况前序表单选择 + handleCxqkQxbdSelect(row) { + // 重置加载标记,允许重新加载数据 + this.isDataLoaded = false + + try { + const bdnr = JSON.parse(row.bdnr) + + const headerFields = bdnr.headerFields || {} + const stepTableFormData_1 = bdnr.stepTableFormData_1 || [] + + // 验证数据有效性 + if (!stepTableFormData_1 || stepTableFormData_1.length === 0) { + this.clearCxqkTable() + return + } + + // 1. 生成动态列配置 + const dynamicColumns = this.generateDynamicColumns(headerFields) + if (!dynamicColumns) { + this.clearCxqkTable() + return + } + + // 2. 生成表格数据 + const tableData = this.generateTableData(stepTableFormData_1, dynamicColumns.columnKeys) + if (tableData.length === 0) { + this.clearCxqkTable() + return + } + + // 3. 更新表格 + this.updateCxqkTable(dynamicColumns.columns, tableData, headerFields) + + } catch (error) { + console.error('解析前序表单数据失败:', error) + this.clearCxqkTable() + } + }, + + // 生成动态列配置 + generateDynamicColumns(headerFields) { + // 获取所有以 _1 结尾的 key,这些代表列的索引 + const columnKeys = Object.keys(headerFields) + .filter(key => key.endsWith('_1')) + .sort((a, b) => parseInt(a.split('_')[0]) - parseInt(b.split('_')[0])) + + if (columnKeys.length === 0) { + return null + } + + const columns = [ + { + label: 'template.dl.dl008.jlzb', + prop: 'jlzb', + bodyType: 'input', + bodyFillType: 'actFill', + bodyDisabled: true, + disabled: true, + width: 100 + } + ] + + columnKeys.forEach((key, index) => { + const colIndex = index + 1 + const baseColIndex = key.split('_')[0] // 获取列索引,如 "1_1" -> "1" + + // 收集该列的所有 headerFields 值(如 1_1, 1_2, 1_3) + const headerValues = [] + let rowIndex = 1 + while (headerFields[`${baseColIndex}_${rowIndex}`]) { + headerValues.push(headerFields[`${baseColIndex}_${rowIndex}`]) + rowIndex++ + } + + // 将多个值用空格拼接 + const headerLabel = headerValues.join(' ') + + columns.push({ + label: headerLabel, + prop: `jzbh${colIndex}`, + bodyType: 'checkbox', + bodyFillType: 'actFill', + checkboxLabel: '', + width: 150 + }) + }) + + return { columns, columnKeys } + }, + + // 生成表格数据 + generateTableData(stepTableFormData_1, columnKeys) { + const tableData = [] + + stepTableFormData_1.forEach((item) => { + const rowData = { jlzb: item.jlzb || '' } + + columnKeys.forEach((_key, index) => { + const colIndex = index + 1 + const valueKey = `jzbh${colIndex}` + + // 从 DL006 生成的数据中获取 label 值 + // DL006 使用的字段名格式是 czrxm_${index}Label + const labelValue = item[`czrxm_${index}Label`] || '' + + rowData[`${valueKey}Label`] = labelValue + rowData[valueKey] = '' // 空字符串表示初始未填写,不会触发修改确认框 + }) + + tableData.push(rowData) + }) + + return tableData + }, + + // 更新成像情况表格 + updateCxqkTable(columns, tableData, headerFields) { + // 更新动态列配置 + this.dynamicCxqkColumns = columns + + // 保存 headerFields 到 formData,用于数据回显 + if (!this.formData.headerSelectFields) { + this.$set(this.formData, 'headerSelectFields', {}) + } + Object.keys(headerFields).forEach(key => { + this.$set(this.formData.headerSelectFields, key, headerFields[key]) + }) + + this.$nextTick(() => { + const tableRef = this.$refs[refConf.cxqk] + if (tableRef) { + // 更新表格数据 + tableRef.updateDataSource(tableData) + + // 将 oldLocalDataSource 设置为当前数据的副本 + // 这样初始加载时不会触发修改确认框,但后续修改会正常触发 + this.$nextTick(() => { + tableRef.oldLocalDataSource = JSON.parse(JSON.stringify(tableRef.localDataSource)) + }) + } + + this.$set(this.formData, 'stepTableFormData_1', tableData) + this.isDataLoaded = true + }) + }, + + // 清空成像情况表格 + clearCxqkTable() { + this.dynamicCxqkColumns = [] + this.$set(this.formData, 'stepTableFormData_1', []) + this.$nextTick(() => { + this.$refs[refConf.cxqk]?.updateDataSource([]) + }) + }, // 保存 async onSave() { const formData = this.getStepResource() - console.log(formData, 'formData') } } } diff --git a/src/views/business/comps/template/comps/dl/DL009.vue b/src/views/business/comps/template/comps/dl/DL009.vue index 53271e4..9c700fc 100644 --- a/src/views/business/comps/template/comps/dl/DL009.vue +++ b/src/views/business/comps/template/comps/dl/DL009.vue @@ -29,7 +29,7 @@ @onRegentSubmit="(e) => onRegentSubmit(e)" :showOperation="fillType === 'actFill'" :showAddRow="fillType === 'actFill'" - :formData="formData" + :formData="yqsyFormData" :prefixKey="`yqsyTable`" >