Browse Source

feat:[模板管理][table组件抽离]

master
luojie 1 week ago
parent
commit
e68d19dec1
8 changed files with 149 additions and 57 deletions
  1. +14
    -2
      src/components/Template/BaseInfoFormPcakge.vue
  2. +43
    -37
      src/components/Template/CustomTable.vue
  3. +5
    -1
      src/components/Template/DecimalInput.vue
  4. +2
    -0
      src/components/Template/HandleFormItem.vue
  5. +1
    -2
      src/views/business/comps/template/TemplateTable.vue
  6. +1
    -1
      src/views/business/comps/template/comps/sp/Demo.vue
  7. +69
    -9
      src/views/business/comps/template/comps/sp/SWYPBQGZYZBB.vue
  8. +14
    -5
      src/views/business/comps/template/mixins/templateMixin.js

+ 14
- 2
src/components/Template/BaseInfoFormPcakge.vue View File

@ -94,7 +94,10 @@
<HandleFormItem v-if="sItem.subType === 'select'" type="select" class="sub-select" :item="getSubItem(sItem)" v-model="formFields[sItem.subKey]" <HandleFormItem v-if="sItem.subType === 'select'" type="select" class="sub-select" :item="getSubItem(sItem)" v-model="formFields[sItem.subKey]"
@copy="onCopy(sItem, key)" @change="onSelectChange(sItem.subKey, $event)" /> @copy="onCopy(sItem, key)" @change="onSelectChange(sItem.subKey, $event)" />
<div v-else-if="sItem.subType === 'span'">{{ formFields[sItem.subKey] }}</div> <div v-else-if="sItem.subType === 'span'">{{ formFields[sItem.subKey] }}</div>
<div class="clickable" :class="getFillType(sItem.subFillType)" v-else-if = "sItem.subType ==='clickable'" @click="handleClickable(sItem)">{{ formFields[sItem.subKey] }}</div>
<div class="clickable" :class="getFillType(sItem.subFillType)" v-else-if = "sItem.subType ==='clickable'" @click="handleClickable(sItem)">
<span v-if="formFields[sItem.subKey]">{{ formFields[sItem.subKey] }}</span>
<span v-else class="default-placeholder-text">请选择</span>
</div>
</div> </div>
<div v-else-if="sItem.type === 'inputNumber'" class="flex flex1"> <div v-else-if="sItem.type === 'inputNumber'" class="flex flex1">
<HandleFormItem type = "inputNumber" @blur="onBlur(key, $event)" class="flex1" :item="sItem" @input = "onInputNumberChange(key, $event)" :value = "formFields[key]" <HandleFormItem type = "inputNumber" @blur="onBlur(key, $event)" class="flex1" :item="sItem" @input = "onInputNumberChange(key, $event)" :value = "formFields[key]"
@ -102,7 +105,10 @@
<HandleFormItem v-if="sItem.subType === 'select'" type="select" class="sub-select" :item="getSubItem(sItem)" v-model="formFields[sItem.subKey]" <HandleFormItem v-if="sItem.subType === 'select'" type="select" class="sub-select" :item="getSubItem(sItem)" v-model="formFields[sItem.subKey]"
@copy="onCopy(sItem, key)" @change="onSelectChange(sItem.subKey, $event)" /> @copy="onCopy(sItem, key)" @change="onSelectChange(sItem.subKey, $event)" />
<div v-else-if="sItem.subType === 'span'">{{ formFields[sItem.subKey] }}</div> <div v-else-if="sItem.subType === 'span'">{{ formFields[sItem.subKey] }}</div>
<div class="clickable" :class="getFillType(sItem.subFillType)" v-else-if = "sItem.subType ==='clickable'" @click="handleClickable(sItem)">{{ formFields[sItem.subKey] }}</div>
<div class="clickable" :class="getFillType(sItem.subFillType)" v-else-if = "sItem.subType ==='clickable'" @click="handleClickable(sItem)">
<span v-if="formFields[sItem.subKey]">{{ formFields[sItem.subKey] }}</span>
<span v-else class="default-placeholder-text">请选择</span>
</div>
</div> </div>
</div> </div>
</div> </div>
@ -374,6 +380,9 @@ export default {
padding-right: 20px; padding-right: 20px;
} }
} }
.default-placeholder-text{
color: #C0C4CC;
}
.form-title { .form-title {
margin-bottom: 12px; margin-bottom: 12px;
font-size: 14px; font-size: 14px;
@ -428,6 +437,9 @@ export default {
height: 28px; height: 28px;
border-radius: 4px; border-radius: 4px;
border:1px solid #4ea2ff; border:1px solid #4ea2ff;
display: flex;
align-items: center;
justify-content: center;
} }
.orange-border { .orange-border {

+ 43
- 37
src/components/Template/CustomTable.vue View File

@ -7,7 +7,7 @@
<div class="header-cell-content"> <div class="header-cell-content">
<div>{{ col.label }}</div> <div>{{ col.label }}</div>
<template v-if="col.headerSelectKey && col.headerOptions"> <template v-if="col.headerSelectKey && col.headerOptions">
<HandleFormItem type="select" class="header-select" :item="getHeaderItem(col)"
<HandleFormItem type="select" class="header-select" :item="getHeaderItem(col)"
v-model="headerSelectFields[col.headerSelectKey]" @change="onHeaderSelectChange(index, $event)" /> v-model="headerSelectFields[col.headerSelectKey]" @change="onHeaderSelectChange(index, $event)" />
</template> </template>
</div> </div>
@ -29,29 +29,24 @@
<div class="inner-table-cell"> <div class="inner-table-cell">
<div> <div>
<template v-if="col.bodyType === 'input'"> <template v-if="col.bodyType === 'input'">
<HandleFormItem type="input" class="body-input" :item="getBodyItem(col)" v-model="row[col.prop]" @change="onBodyValueChange(rowIndex, colIndex, $event)" />
<HandleFormItem type="input" class="body-input" :item="getBodyItem(col,rowIndex)" v-model="row[col.prop]" @change="onBodyValueChange(rowIndex, colIndex, $event)" />
</template> </template>
<template v-else-if="col.bodyType === 'inputNumber'"> <template v-else-if="col.bodyType === 'inputNumber'">
<HandleFormItem type="inputNumber" class="body-input-number" :item="getBodyItem(col)"
<HandleFormItem type="inputNumber" class="body-input-number" :item="getBodyItem(col,rowIndex)"
v-model="row[col.prop]" @change="onBodyValueChange(rowIndex, colIndex, $event)" /> v-model="row[col.prop]" @change="onBodyValueChange(rowIndex, colIndex, $event)" />
</template> </template>
<template v-else-if="col.bodyType === 'select'"> <template v-else-if="col.bodyType === 'select'">
<HandleFormItem type="select" class="body-select" :item="getBodyItem(col)" v-model="row[col.prop]" @change="onBodyValueChange(rowIndex, colIndex, $event)" />
<HandleFormItem type="select" class="body-select" :item="getBodyItem(col,rowIndex)" v-model="row[col.prop]" @change="onBodyValueChange(rowIndex, colIndex, $event)" />
</template> </template>
<template v-else> <template v-else>
{{ row[col.prop] }} {{ row[col.prop] }}
</template> </template>
</div> </div>
<div class="m-l-5"> <div class="m-l-5">
<template v-if="col.bodySubType === 'inputNumber'">
<template v-if="col.bodySubType === 'inputNumber' && col.showBodySub">
<HandleFormItem type="inputNumber" :item="getBodySubItem(col)" <HandleFormItem type="inputNumber" :item="getBodySubItem(col)"
v-model="row[col.bodySubKey]" @change="onBodySubValueChange(rowIndex, colIndex, $event)" /> v-model="row[col.bodySubKey]" @change="onBodySubValueChange(rowIndex, colIndex, $event)" />
</template> </template>
<!-- 预填才显示精度输入框 -->
<template v-else-if="col.bodySubType === 'precisionNumber'&& $store.state.template.templateStatus === 'preFill'">
<HandleFormItem type="inputNumber" class="sub-input-number" :item="getPrecisionNumberItem(col)"
v-model="row[col.bodySubKey]" @change="onBodySubValueChange(rowIndex, colIndex, $event)" />
</template>
<template v-else> <template v-else>
{{ row[col.bodySubKey] }} {{ row[col.bodySubKey] }}
</template> </template>
@ -98,10 +93,15 @@ export default {
// { label: '', prop: 'status', type: 'select', options: [{value:1,label:''},...], selected: null } // { label: '', prop: 'status', type: 'select', options: [{value:1,label:''},...], selected: null }
// ] // ]
}, },
dataSource: {
type: Array,
required: true
}
formData: {
type: Object,
default:()=>{
return {
stepTableFormData: [],
headerSelectFields: {}
}
}
},
}, },
data() { data() {
return { return {
@ -110,19 +110,18 @@ export default {
} }
}, },
watch: { watch: {
dataSource: {
formData:{
immediate: true, immediate: true,
handler(newData) { handler(newData) {
this.localDataSource = JSON.parse(JSON.stringify(newData));
//
console.log(newData,"newData")
const {stepTableFormData = [], headerSelectFields = {}} = newData;
this.updateDataSource(stepTableFormData);
this.headerSelectFields = JSON.parse(JSON.stringify(headerSelectFields))
} }
}, },
columns: {
immediate: true,
handler(newColumns) {
this.initHeaderSelectValues();
}
}
},
mounted() {
this.initHeaderSelectValues();
}, },
methods: { methods: {
// //
@ -133,7 +132,6 @@ export default {
headerSelectObj[col.headerSelectKey] = col.defaultValue || col.headerOptions[0].value || "" headerSelectObj[col.headerSelectKey] = col.defaultValue || col.headerOptions[0].value || ""
} }
}); });
console.log(headerSelectObj,"headerSelectObj")
this.headerSelectFields = headerSelectObj; this.headerSelectFields = headerSelectObj;
}, },
// //
@ -146,7 +144,7 @@ export default {
return new Promise((resolve,reject)=>{ return new Promise((resolve,reject)=>{
if(validateResult.valid){ if(validateResult.valid){
resolve({ resolve({
dataSource: [...this.localDataSource],
stepTableFormData: [...this.localDataSource],
headerSelectFields: this.headerSelectFields, headerSelectFields: this.headerSelectFields,
}) })
}else{ }else{
@ -238,33 +236,41 @@ export default {
label: "" label: ""
} }
}, },
getBodyItem(col) {
return {
getBodyItem(col,rowIndex) {
const currentItem = this.localDataSource[rowIndex];
const item = {
fillType: col.bodyFillType, fillType: col.bodyFillType,
options: col.bodyOptions, options: col.bodyOptions,
maxLength: col.bodyMaxLength,
label: ""
maxlength: col.bodyMaxlength,
label: col.label,
precision: currentItem[col.bodyPrecisionKey] || col.precision || 0,
};
if(col.bodyDisabled){
item.disabled = col.bodyDisabled;
} }
return item
}, },
getBodySubItem(col) { getBodySubItem(col) {
return {
const item = {
fillType: col.bodySubFillType, fillType: col.bodySubFillType,
options: col.bodySubOptions, options: col.bodySubOptions,
maxlength: col.bodySubMaxlength,
label: "", label: "",
placeholder:col.bodySubPlaceholder||"请输入"
} }
},
getPrecisionNumberItem(col) {
return {
fillType: col.bodySubFillType,
options: col.bodySubOptions,
label: "",
placeholder:"请输入保留小数位数"
if(col.bodySubDisabled){
item.disabled = col.bodySubDisabled;
} }
}, },
// //
deleteRow(rowIndex) { deleteRow(rowIndex) {
this.localDataSource.splice(rowIndex, 1); this.localDataSource.splice(rowIndex, 1);
this.$emit('row-delete', rowIndex); this.$emit('row-delete', rowIndex);
},
// formData
updateDataSource(dataSource = []) {
//
this.localDataSource = JSON.parse(JSON.stringify(dataSource || []));
} }
} }
}; };

+ 5
- 1
src/components/Template/DecimalInput.vue View File

@ -1,5 +1,5 @@
<template> <template>
<el-input v-model="internalValue" @input="handleInput" @blur="handleBlur" :placeholder="placeholder" type="text" />
<el-input v-model="internalValue" @input="handleInput" @blur="handleBlur" :placeholder="placeholder" :disabled="disabled" type="text" />
</template> </template>
<script> <script>
@ -17,6 +17,10 @@ export default {
placeholder: { placeholder: {
type: String, type: String,
default: '请输入' default: '请输入'
},
disabled: {
type: Boolean,
default: false
} }
}, },
data() { data() {

+ 2
- 0
src/components/Template/HandleFormItem.vue View File

@ -118,8 +118,10 @@ export default {
const { item } = this; const { item } = this;
const { fillType } = item; const { fillType } = item;
if (item.hasOwnProperty("disabled")) { if (item.hasOwnProperty("disabled")) {
console.log(item,item.disabled,"item.disabled")
return item.disabled return item.disabled
} else { } else {
console.log(item,"else")
const { templateStatus } = this.$store.state.template; const { templateStatus } = this.$store.state.template;
if (fillType === "actFill") {//fillTypeactFill if (fillType === "actFill") {//fillTypeactFill
return templateStatus !== "actFill" return templateStatus !== "actFill"

+ 1
- 2
src/views/business/comps/template/TemplateTable.vue View File

@ -39,8 +39,7 @@ export default {
if (!this.componentMap) { if (!this.componentMap) {
this.componentMap = { this.componentMap = {
'SP001': 'SWYPFXRYPZB', 'SP001': 'SWYPFXRYPZB',
// 'SP002': 'SWYPFXCBYPZB',
'SP002': 'SWYPBQGZYZBB',
'SP002': 'SWYPFXCBYPZB',
'SP003': 'SWYPBQGZYZBB', 'SP003': 'SWYPBQGZYZBB',
// 'SP001': 'Demo', // 'SP001': 'Demo',
} }

+ 1
- 1
src/views/business/comps/template/comps/sp/Demo.vue View File

@ -75,7 +75,7 @@ export default {
width: 280, width: 280,
bodyType:"input", bodyType:"input",
bodyFillType:"actFill", bodyFillType:"actFill",
bodyMaxLength:10,
bodyMaxlength:10,
}, },
{ {
label:"预设起始溶液体积",prop:"code3", label:"预设起始溶液体积",prop:"code3",

+ 69
- 9
src/views/business/comps/template/comps/sp/SWYPBQGZYZBB.vue View File

@ -17,13 +17,14 @@
<BaseInfoFormPcakge ref="stepFormPackageRef" :formConfig="stepFormConfig" <BaseInfoFormPcakge ref="stepFormPackageRef" :formConfig="stepFormConfig"
@blur = "onHandleBlur" @blur = "onHandleBlur"
:formData="formData" /> :formData="formData" />
<CustomTable ref = "stepTable" :columns = "stepColumns" :formData = "formData"/>
</div> </div>
<Step ref="stepRef" :formData="formData"></Step> <Step ref="stepRef" :formData="formData"></Step>
<BaseInfoFormPcakge label="备注" ref="remarkRef" :formConfig="remarkConig" :formData="formData" /> <BaseInfoFormPcakge label="备注" ref="remarkRef" :formConfig="remarkConig" :formData="formData" />
</div> </div>
</div> </div>
<!-- <button @click = "onSave">保存</button> -->
<button @click = "onSave">保存</button>
</div> </div>
</div> </div>
</template> </template>
@ -36,9 +37,8 @@ import Step from "@/components/Template/Step";
import templateMixin from "../../mixins/templateMixin"; import templateMixin from "../../mixins/templateMixin";
import CustomTable from '@/components/Template/CustomTable.vue'; import CustomTable from '@/components/Template/CustomTable.vue';
export default { export default {
name: "SWYPFXRYPZB",
name: "SWYPBQGZYZBB",
components: { BaseInfoFormPcakge, LineLabel, TableList, Step, CustomTable }, components: { BaseInfoFormPcakge, LineLabel, TableList, Step, CustomTable },
mixins: [templateMixin], mixins: [templateMixin],
props: { props: {
@ -60,6 +60,7 @@ export default {
} }
}, },
computed: { computed: {
//
storageFormConfig() { storageFormConfig() {
return [ return [
{ {
@ -77,6 +78,7 @@ export default {
} }
]; ];
}, },
//
remarkConig() { remarkConig() {
return [ return [
{ {
@ -95,6 +97,7 @@ export default {
} }
] ]
}, },
//
baseInfoFormConfig() { baseInfoFormConfig() {
return [ return [
{ {
@ -175,6 +178,7 @@ export default {
} }
] ]
}, },
//
stepFormConfig() { stepFormConfig() {
return [ return [
{ {
@ -209,7 +213,7 @@ export default {
subKey: "subSolution", subKey: "subSolution",
subFillType: "actFill", subFillType: "actFill",
}, },
startSTD: {
codeSTD: {
label: "起始编号STD", label: "起始编号STD",
type: "input", type: "input",
maxlength: 10, maxlength: 10,
@ -239,10 +243,57 @@ export default {
} }
] ]
}, },
//
stepColumns(){
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.$store.state.template.volumeOptions,
defaultValue:"mg",
bodyType:"inputNumber",
bodySubType:"inputNumber",
bodySubKey:"subTargetStartSolutionPrecision",
bodyFillType:"preFill",
bodySubFillType:"preFill",
showBodySub:this.fillType === "preFill",
bodyDisabled: true,
bodyPrecisionKey:"subTargetStartSolutionPrecision",
},
{
label:"实际起始溶液体积",prop:"actStartSolutionVolume",
width: 280,
headerSelectKey:"actStartSolutionVolumeUnit",
fillType:"preFill",
headerOptions:this.$store.state.template.volumeOptions,
bodyType:"inputNumber",
bodyFillType:"actFill",
},
]
},
}, },
data() { data() {
return { return {
dataSource: [], dataSource: [],
stepTableDataSource: [],
sysjColumns: [ sysjColumns: [
{ label: "试剂名称", prop: "reagentName" }, { label: "试剂名称", prop: "reagentName" },
{ label: "编号", prop: "reagentCode" }, { label: "编号", prop: "reagentCode" },
@ -258,8 +309,6 @@ export default {
{ label: "下次测试/校准/检定日期", prop: "nextTestDate" }, { label: "下次测试/校准/检定日期", prop: "nextTestDate" },
], ],
formData: {}
}; };
}, },
mounted() { mounted() {
@ -267,6 +316,14 @@ export default {
this.formData = { this.formData = {
effectivePeriodUnit: "days",// effectivePeriodUnit: "days",//
createTime: "2026-01-02 18:05:36",// createTime: "2026-01-02 18:05:36",//
stepTableFormData:[
{actStartSolutionVolume:1,subActStartSolutionVolume:"ul",subTargetStartSolutionPrecision:3},
{targetStartSolutionVolume:3,subTargetStartSolutionVolume:"mg",subTargetStartSolutionPrecision:2},
],
headerSelectFields: {
targetStartSolutionVolumeUnit: "mg",
actStartSolutionVolumeUnit: "ul",
}
} }
} }
}, },
@ -275,6 +332,7 @@ export default {
const baseData = await this.$refs.baseInfoRef.getFormData(); const baseData = await this.$refs.baseInfoRef.getFormData();
const conditionData = await this.$refs.storageConditionRef.getFormData(); const conditionData = await this.$refs.storageConditionRef.getFormData();
const stepFormData = await this.$refs.stepFormPackageRef.getFormData(); const stepFormData = await this.$refs.stepFormPackageRef.getFormData();
const stepDataFormData = await this.$refs.stepTable.getFormData();
const stepData = await this.$refs.stepRef.getFormData(); const stepData = await this.$refs.stepRef.getFormData();
if (!stepData.length) { if (!stepData.length) {
this.$message.error("请添加步骤"); this.$message.error("请添加步骤");
@ -286,12 +344,14 @@ export default {
...conditionData, ...conditionData,
...stepData, ...stepData,
stepData: stepFormData, stepData: stepFormData,
...remarkData
...remarkData,
...stepDataFormData
} }
}, },
async onSave() { async onSave() {
const formData = await this.getFormData();
console.log(formData, "formData")
// const formData = await this.getFormData();
const stepDataFormData = await this.$refs.stepTable.getFormData();
console.log(stepDataFormData, "formData")
} }
} }
}; };

+ 14
- 5
src/views/business/comps/template/mixins/templateMixin.js View File

@ -1,3 +1,4 @@
import moment from "moment";
export default { export default {
props: { props: {
templateData: { templateData: {
@ -12,16 +13,19 @@ export default {
if(v){ if(v){
let n = {...v}; let n = {...v};
if(v.bdnr){ if(v.bdnr){
n = {...n,...JSON.parse(v.bdnr)};
this.formData = JSON.parse(v.bdnr);
} }
this.formData = n;
this.templateDetail = n;
this.setTemplateData(n); this.setTemplateData(n);
} }
} }
} }
}, },
data() { data() {
return {
formData: {},
templateDetail:{}
}
}, },
mounted() { mounted() {
@ -52,13 +56,18 @@ export default {
}, },
//统一处理blur事件,因为有效周期和过期日期是相关的,所以需要在有效周期失焦时更新过期日期 //统一处理blur事件,因为有效周期和过期日期是相关的,所以需要在有效周期失焦时更新过期日期
onHandleBlur(fields){ onHandleBlur(fields){
const {key ,effectivePeriodUnit,effectivePeriod} = fields;
const {key ,effectivePeriodUnit,effectivePeriod,codeSTD} = fields;
const {createTime} = this.formData; const {createTime} = this.formData;
if(key ==="effectivePeriod"){//统一处理有效周期失焦,计算失效事件,保证字段名不能变 if(key ==="effectivePeriod"){//统一处理有效周期失焦,计算失效事件,保证字段名不能变
const start = moment(createTime); const start = moment(createTime);
const end = start.add(Number(effectivePeriod), effectivePeriodUnit).format("YYYY-MM-DD HH:mm:ss"); const end = start.add(Number(effectivePeriod), effectivePeriodUnit).format("YYYY-MM-DD HH:mm:ss");
this.$refs.stepFormPackageRef.updateFormField("expireDate", end); this.$refs.stepFormPackageRef.updateFormField("expireDate", end);
}
}else if(key === "codeSTD"){//起始编号STD失焦时,更新stepDataSource
const arr = Array.from({length:codeSTD},(item,index) => ({
subTargetStartSolutionPrecision:3,//小数点精度默认为3
}));
this.stepTableDataSource = arr;
}
} }
}, },

Loading…
Cancel
Save