Browse Source

feat:[模板管理][update]

luojie
luojie 2 weeks ago
parent
commit
495c6915ce
8 changed files with 387 additions and 108 deletions
  1. +12
    -3
      src/components/Template/HandleFormItem.vue
  2. +252
    -0
      src/components/Template/StepComponents/CdmdComp.vue
  3. +2
    -0
      src/components/Template/StepComponents/JcbComp.vue
  4. +4
    -0
      src/components/Template/StepComponents/xbjzpz/cdmd.vue
  5. +5
    -0
      src/components/Template/StepFormPackage.vue
  6. +17
    -15
      src/components/Template/mixins/stepMixins.js
  7. +82
    -85
      src/views/business/comps/template/comps/dl/DL016.vue
  8. +13
    -5
      src/views/business/comps/template/formConfig/sp/SP0020.js

+ 12
- 3
src/components/Template/HandleFormItem.vue View File

@ -404,7 +404,7 @@ export default {
return false;
},
getFlexClass() {
const noFlexArr = ["radio", "checkboxTag", "fqyq","button"]
const noFlexArr = ["radio", "checkboxTag", "fqyq", "button"]
return noFlexArr.includes(this.type) ? '' : 'flex1'
},
getDecimalDigits() {
@ -657,7 +657,7 @@ export default {
//
handleClickButton(item) {
this.inputValue = `button-${new Date().getTime()}`;
if(item.noSign){//emit
if (item.noSign) {//emit
this.$emit("clickButton", item);
return;
}
@ -1152,7 +1152,7 @@ export default {
if (!this.isFieldsRecord) {//
this.$emit("blur", this.inputValue);
this.$emit('input', this.inputValue);
this.$emit("change", this.inputValue,"change");
this.$emit("change", this.inputValue, "change");
return;
}
//
@ -1891,6 +1891,15 @@ export default {
box-shadow: 0 0 6px #ffc3c3 !important;
}
.el-checkbox__label {
white-space: normal;
}
.checkbox-tree-item .el-checkbox {
display: flex;
align-items: center;
}
.checkbox-item {
margin-right: 16px;
display: flex;

+ 252
- 0
src/components/Template/StepComponents/CdmdComp.vue View File

@ -0,0 +1,252 @@
<template>
<div class="cdmd-container">
<!-- 使用一个table包含所有测定组 -->
<table class="cdmd-table" cellspacing="0" cellpadding="0">
<!-- 根据cs值循环生成每个测定组 -->
<div v-for="index in Math.min(cs, 10)" :key="index">
<!-- 第一行 -->
<tr>
<td rowspan="3" class="first-col">{{ index }}</td>
<td class="fixed-text">稀释倍数</td>
<td class="fixed-text">1</td>
<td class="fixed-text">细胞密度/mL</td>
<td>
<el-button type="success" size="mini" class="formula-btn">公式</el-button>
</td>
</tr>
<!-- 第二行 -->
<tr>
<td class="fixed-text">左上格()</td>
<td class="fixed-text">右上格()</td>
<td class="fixed-text">左下格()</td>
<td class="fixed-text">右下格()</td>
</tr>
<!-- 第三行 -->
<tr>
<td>
<el-input
v-model="formData['zs' + index + '_1']"
size="mini"
placeholder="整数"
class="orange-input"
@blur="handleDataChange"
/>
</td>
<td>
<el-input
v-model="formData['zs' + index + '_2']"
size="mini"
placeholder="整数"
class="orange-input"
@blur="handleDataChange"
/>
</td>
<td>
<el-input
v-model="formData['zs' + index + '_3']"
size="mini"
placeholder="整数"
class="orange-input"
@blur="handleDataChange"
/>
</td>
<td>
<el-input
v-model="formData['zs' + index + '_4']"
size="mini"
placeholder="整数"
class="orange-input"
@blur="handleDataChange"
/>
</td>
</tr>
</div>
</table>
<!-- 如果cs大于10显示提示信息 -->
<div v-if="cs > 10" class="cdmd-warning">
注意当前仅支持最多10次测定如需更多次数请调整参数
</div>
</div>
</template>
<script>
export default {
props: {
cs: {
type: Number,
default: 4
},
item: {
type: Object,
default: () => ({})
},
formData: {
type: Object,
default: () => ({})
},
stepIndex: {
type: String,
default: ''
},
prefixKey: {
type: String,
default: ''
},
type: {
type: String,
default: 'cdmd'
}
},
data() {
return {
localFormData: {
jcbInfo: {
stepTableFormData: []
}
}
}
},
watch: {
formData: {
immediate: true,
handler(newVal) {
this.localFormData = { ...newVal };
this.onDataChange();
},
deep: true
},
cs: {
immediate: true,
handler() {
this.onDataChange();
}
}
},
mounted() {
this.onDataChange();
},
methods: {
//
handleDataChange() {
this.onDataChange();
},
//
onDataChange() {
//
const tableData = [];
const maxCols = Math.min(this.cs, 10);
for (let i = 1; i <= maxCols; i++) {
tableData.push({
index: i,
zs1: this.formData['zs' + i + '_1'] || '',
zs2: this.formData['zs' + i + '_2'] || '',
zs3: this.formData['zs' + i + '_3'] || '',
zs4: this.formData['zs' + i + '_4'] || '',
xbmd: '个/mL',
xsb: '1'
});
}
//
this.localFormData.jcbInfo = {
stepTableFormData: tableData
};
//
this.$emit('update', {
jcbInfo: {
stepTableFormData: tableData
}
});
},
//
getFormData() {
return this.localFormData;
}
}
}
</script>
<style lang="scss" scoped>
.cdmd-container {
width: 100%;
margin: 10px 0;
}
.cdmd-table {
width: 100%;
border-collapse: collapse;
border: 1px solid #e8e8e8;
border-radius: 4px;
overflow: hidden;
background-color: #fff;
td {
padding: 8px;
text-align: center;
border: 1px solid #e8e8e8;
vertical-align: middle;
}
}
.first-col {
width: 100px;
font-weight: 500;
color: #333;
background-color: #f9f9f9;
}
.orange-input {
width: 80px;
margin: 0 auto;
::v-deep .el-input__inner {
background-color: #fff7e6 !important;
border-color: #ffa940 !important;
color: #d46b08 !important;
text-align: center;
&:focus {
border-color: #d46b08 !important;
box-shadow: 0 0 0 2px rgba(255, 169, 64, 0.2) !important;
}
}
}
.fixed-text {
color: #595959;
font-size: 14px;
}
.formula-btn {
background-color: #52c41a !important;
border-color: #52c41a !important;
color: #fff !important;
font-size: 12px;
padding: 4px 12px;
&:hover {
background-color: #73d13d !important;
border-color: #73d13d !important;
}
&:active {
background-color: #389e0d !important;
border-color: #389e0d !important;
}
}
.cdmd-warning {
margin-top: 8px;
padding: 8px 12px;
background-color: #fff2e8;
border: 1px solid #ffbb96;
border-radius: 4px;
color: #d46b08;
font-size: 12px;
}
</style>

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

@ -61,6 +61,8 @@ export default {
bodyType: "jcb",
bodyKey: "clpClick",
bodyFillType: "preFill",
bodySubType: 'span',
bodySubKey: 'bh',
},
{
label: '时间',

+ 4
- 0
src/components/Template/StepComponents/xbjzpz/cdmd.vue View File

@ -75,10 +75,14 @@ export default {
fillType: "actFill",
type: "inputNumber",
},
cdmds:{
type:"cdmd"
},
text6:{
label: "个/mL。",
type: "text",
},
}
}]
return config

+ 5
- 0
src/components/Template/StepFormPackage.vue View File

@ -56,6 +56,9 @@
<template v-else-if="isShowJcb(sItem,key)">
<JcbComp @update="(data)=>onJcbUpdate(data,key)" :type = "sItem.type" :ref="'jcbComp_'+key" :stepIndex="stepIndex" :prefixKey="prefixKey+'_'+index" @resetRecord = "resetRecord" :item="sItem" :formData="formData[key]" />
</template>
<template v-else-if="sItem.type === 'cdmd'">
<CdmdComp @update="(data)=>onJcbUpdate(data,key)" :type = "sItem.type" :ref="'cdmdComp_'+key" :stepIndex="stepIndex" :prefixKey="prefixKey+'_'+index" :item="sItem" :formData="formData[key]" />
</template>
<div v-show="isShowOther(formFields[key])" class="flex flex1">
<div class="other-title">{{sItem.otherLabel ? $t(sItem.otherLabel) : $t("template.common.other") }}</div>
@ -74,6 +77,7 @@
import HandleFormItem from '@/components/Template/HandleFormItem.vue'
import formPackageMixins from '@/components/Template/mixins/formPackageMixins.js'
import JcbComp from '@/components/Template/StepComponents/JcbComp.vue'
import CdmdComp from '@/components/Template/StepComponents/CdmdComp.vue'
import ZLSubPackage from '@/components/Template/StepComponents/ZLSubPackage.vue'
import { isShowOther } from "@/utils/formPackageCommon.js";
import { EventBus } from "@/utils/eventBus";
@ -85,6 +89,7 @@ export default {
HandleFormItem,
ZLSubPackage,
JcbComp,
CdmdComp,
},
mixins: [formPackageMixins],
props: {

+ 17
- 15
src/components/Template/mixins/stepMixins.js View File

@ -74,15 +74,17 @@ export default {
commonHandleJcbUpdate() {
this.localFormData = this.formData;
if (!this.formData.jcb && this.templateFillType === 'actFill') {
const qbData = this.getQbData();
this.localFormData = { ...this.localFormData, jcb: qbData };
justUpdateFilledFormData();
setTimeout(() => {
const qbData = this.getQbData();
this.localFormData = { ...this.localFormData, jcb: qbData };
justUpdateFilledFormData();
}, 3000);
}
},
//获取取板数据
getQbData() {
let qbData = [];
if (this.templateSn === "LBA003") {//只有lba003才会有取板步骤,所以检测板数据从取板数据里面获取;
if (this.templateSn === "LBA003" || this.templateSn === "ADA003") {//只有lba003才会有取板步骤,所以检测板数据从取板数据里面获取;
const stepData = this.getStepData() || [];
const filterData = stepData.filter((item) => item.type === "qb");
const allQbData = [];
@ -92,12 +94,12 @@ export default {
allQbData.push(...parseData);
})
qbData = [...new Map(allQbData.map(item => [item.mc, item])).values()]
} else if (this.templateSn === "LBA002") {//lba002没有取板步骤,所以检测板数据从检测板数据里面获取;
const {stepTableFormData=[]} = this.getJcbData() || {};
qbData = JSON.parse(JSON.stringify(stepTableFormData));
} else if (this.templateSn === "LBA002" || this.templateSn === "ADA002") {//lba002没有取板步骤,所以检测板数据从检测板数据里面获取;
const { stepTableFormData = [] } = this.getJcbData() || {};
qbData = stepTableFormData;
}
return { stepTableFormData: qbData }
return { stepTableFormData: JSON.parse(JSON.stringify(qbData)) }
},
//回填编号 preField 前缀 updateField 需要更新的字段
async handleBackfillCode(preField, updateField) {
@ -163,16 +165,16 @@ export default {
let maxVolume, maxVolumeUnit;
if (this.getMybh || this.getMybhByIndex) {//某些表单的步骤需要分装表单上的数据
let result = {};
if(this.getMybh){
if (this.getMybh) {
result = this.getMybh()
}else if(this.getMybhByIndex){
result = this.getMybhByIndex(this.formIndex,this.formType)
} else if (this.getMybhByIndex) {
result = this.getMybhByIndex(this.formIndex, this.formType)
}
const { mybh, mybhOptions = [], maxVolume: max, maxVolumeUnit: unit } = result
if ((!mybh && !mybhOptions.length) || !max || !unit) {
this.$message.warning('请先填写分装数据')
return
}
// if ((!mybh && !mybhOptions.length) || !max || !unit) {
// this.$message.warning('请先填写分装数据')
// return
// }
options = mybhOptions
fields.push(mybh)
maxVolume = max || ''

+ 82
- 85
src/views/business/comps/template/comps/dl/DL016.vue View File

@ -11,18 +11,16 @@
<TableList label="template.common.reagentInfo" :columns="sysjColumns" :dataSource="resourceSj" />
<TableList label="template.common.instrumentInfo" :columns="yqColumns" :dataSource="yqResource" />
<BaseInfoFormPackage fieldItemLabel="template.dl.dl016.xbxx" label="template.dl.dl016.xbxx"
ref="swypyjInfoRef" :formConfig="swypyjInfoFormConfig" :formData="formData" @onRegentSubmit="onRegentSubmit"
/>
<BaseInfoFormPackage fieldItemLabel="template.dl.dl016.xbxx" label="template.dl.dl016.xbxx"
ref="swypyjInfoRef" :formConfig="swypyjInfoFormConfig" :formData="formData"
@onRegentSubmit="onRegentSubmit" />
<LineLabel label="template.dl.dl016.qcxjjyqk" />
<CustomTable
@headerSelectChange="onHeaderSelectChange"
fieldItemLabel="template.common.operationSteps" @blur="onHandleTableBlur"
@beforeSaveRecord = "beforeSaveRecord"
:showAddRow="false" :showOperation="false"
ref="qcxjjyqkTableRef" :columns="stepColumns" :formData="tableFormData">
</CustomTable>
<LineLabel label="template.dl.dl016.qcxjjyqk" />
<CustomTable @headerSelectChange="onHeaderSelectChange"
fieldItemLabel="template.common.operationSteps" @blur="onHandleTableBlur"
@beforeSaveRecord="beforeSaveRecord" :showAddRow="false" :showOperation="false"
ref="qcxjjyqkTableRef" :columns="stepColumns" :formData="formData">
</CustomTable>
<LineLabel label="template.dl.dl016.czbz" />
<Step ref="stepRef" :formData="formData.stepData"></Step>
@ -49,10 +47,10 @@ import TableOpertaionDelete from "@/components/Template/operation/TableOpertaion
export default {
name: "DL016",
dicts: [
'business_dl_qsxjbltj','business_tjdw','business_nddw'
],
components: { BaseInfoFormPackage, LineLabel, TableList, Step, CustomTable,TableOpertaionDelete },
dicts: [
'business_dl_qsxjbltj', 'business_tjdw', 'business_nddw'
],
components: { BaseInfoFormPackage, LineLabel, TableList, Step, CustomTable, TableOpertaionDelete },
mixins: [templateMixin],
props: {
fillType: {
@ -61,13 +59,13 @@ export default {
},
},
computed: {
//
tableFormData() {
return {
stepTableFormData: this.formData.stepTableFormData || [],
headerSelectFields: {}
}
},
//
tableFormData() {
return {
stepTableFormData: this.formData.stepTableFormData || [],
headerSelectFields: {}
}
},
//
remarkConig() {
return [
@ -132,7 +130,7 @@ export default {
}
]
},
//
//
swypyjInfoFormConfig() {
return [
{
@ -142,16 +140,16 @@ export default {
label: 'template.dl.dl016.qxbd',
type: 'qxbd',
fillType: 'actFill',
qxbdType:'DL014',
filledCodes:['bdmc','bdbh'],
qxbdType: 'DL014',
filledCodes: ['bdmc', 'bdbh'],
},
bltj: {
bltj: {
label: 'template.dl.dl016.bltj',
type: 'select',
fillType: 'preFill',
options: this.getDictOptions('business_dl_qsxjbltj'),
otherCode: 'bltjOther',
showOtherLabel:false
showOtherLabel: false
},
}
}
@ -166,7 +164,7 @@ export default {
bodyType: "input",
bodyFillType: "actFill",
width: 180,
bodyDisabled: true,
bodyDisabled: true,
},
{
label: "template.dl.dl016.xybh",
@ -183,20 +181,20 @@ export default {
// width: 180,
// bodyFillType: "actFill",
// bodyMaxlength: 10,
// headerSelectKey: 'qsxjjrldw',
// fillType: "actFill",
// headerOptions: this.getDictOptions('business_nddw'),
// bodyType: 'inputNumber',
label: "template.dl.dl016.qsxjjrl",
prop: 'qsxjjrl',
width: 280,
headerSelectKey: 'qsxjjrldw',
fillType: "preFill",
headerOptions: this.getDictOptions('business_tjdw'),
bodyType: 'inputNumber',
bodyFillType: 'actFill',
copyFrom: 'ysqyl',
compareTo: 'ysqyl',
// headerSelectKey: 'qsxjjrldw',
// fillType: "actFill",
// headerOptions: this.getDictOptions('business_nddw'),
// bodyType: 'inputNumber',
label: "template.dl.dl016.qsxjjrl",
prop: 'qsxjjrl',
width: 280,
headerSelectKey: 'qsxjjrldw',
fillType: "preFill",
headerOptions: this.getDictOptions('business_tjdw'),
bodyType: 'inputNumber',
bodyFillType: 'actFill',
copyFrom: 'ysqyl',
compareTo: 'ysqyl',
}
]
},
@ -207,69 +205,69 @@ export default {
};
},
methods: {
onRegentSubmit(e) {
const { selectInfo, key, rowIndex } = e
const { row } = selectInfo
if (key === 'qxbd') {
try {
//
const bdnr = JSON.parse(row.bdnr)
//
const stepTableFormData = bdnr.jlzTableData || []
onRegentSubmit(e) {
const { selectInfo, key, rowIndex } = e
const { row } = selectInfo
if (key === 'qxbd') {
try {
//
const bdnr = JSON.parse(row.bdnr)
//
const stepTableFormData = bdnr.jlzTableData || []
if (stepTableFormData.length === 0) {
//
this.$set(this.formData, 'stepTableFormData', [])
this.$message.warning('前序表单中没有剂量组数据')
return
}
if (stepTableFormData.length === 0) {
//
this.$set(this.formData, 'stepTableFormData', [])
this.$message.warning('前序表单中没有剂量组数据')
return
}
//
const itemData = stepTableFormData.map(item => ({
jlzb: item.jlzb || '', //
xybh: item.xybh || '', //
qsxjjrl: '', //
}))
// 使 $set formData CustomTable
this.$set(this.formData, 'stepTableFormData', itemData)
//
const itemData = stepTableFormData.map(item => ({
jlzb: item.jlzb || '', //
xybh: item.xybh || '', //
qsxjjrl: '', //
}))
// 使 $set formData CustomTable
this.$set(this.formData, 'stepTableFormData', itemData)
this.$message.success(`已从前序表单加载 ${itemData.length} 条剂量组数据`)
} catch (error) {
console.error('解析前序表单数据失败:', error)
this.$message.error('解析前序表单数据失败')
}
}
},
//table header
onHeaderSelectChange(data){
const {key, headerSelectFields,dataSource=[]} = data;
this.$message.success(`已从前序表单加载 ${itemData.length} 条剂量组数据`)
} catch (error) {
console.error('解析前序表单数据失败:', error)
this.$message.error('解析前序表单数据失败')
}
}
},
//table header
onHeaderSelectChange(data) {
const { key, headerSelectFields, dataSource = [] } = data;
const keys = [
'targetStartSolutionVolumeUnit',
'targetDiluentVolumeUnit',
'targetSolutionConcentrationUnit',
'targetSolutionVolumeUnit',
]
if(keys.includes(key)){
const {targetStartSolution,subTargetStartSolution} = this.$refs.swypyjInfoRef?.getFilledFormData();
if (keys.includes(key)) {
const { targetStartSolution, subTargetStartSolution } = this.$refs.swypyjInfoRef?.getFilledFormData();
const params = {
subTargetStartSolution,
headerSelectFields
}
this.batchUpdateTargetStartSolutionVolume(dataSource,targetStartSolution,params)
this.batchUpdateTargetStartSolutionVolume(dataSource, targetStartSolution, params)
}
},
beforeSaveRecord(data){
beforeSaveRecord(data) {
const formFields = this.$refs.swypyjInfoRef?.getFilledFormData();
this.onCommonVerifyNdException(formFields,data);
this.onCommonVerifyNdException(formFields, data);
},
//
getFilledFormData() {
return this.getFilledFormDataByRefs(["baseInfoRef", "swypyjInfoRef", "qcxjjyqkTableRef", "stepRef","remarkRef"])
return this.getFilledFormDataByRefs(["baseInfoRef", "swypyjInfoRef", "qcxjjyqkTableRef", "stepRef", "remarkRef"])
},
//
async getFormData() {
let content = await this.validFormFields(["baseInfoRef", "swypyjInfoRef", "qcxjjyqkTableRef", "stepRef","remarkRef"]);
return content;
let content = await this.validFormFields(["baseInfoRef", "swypyjInfoRef", "qcxjjyqkTableRef", "stepRef", "remarkRef"]);
return content;
},
getResource() {
//使
@ -292,5 +290,4 @@ export default {
}
};
</script>
<style rel="stylesheet/scss" lang="scss">
</style>
<style rel="stylesheet/scss" lang="scss"></style>

+ 13
- 5
src/views/business/comps/template/formConfig/sp/SP0020.js View File

@ -31,14 +31,22 @@ const getOptions = (sn) => {
{ label: '精密度与准确性', value: '精密度与准确性' },
{ label: '检测限', value: '检测限' },
{ label: '提取精密度', value: '提取精密度' },
{ label: '提取前样品稳定性', value: '提取前样品稳定性' },
{ label: '提取后样品稳定性', value: '提取后样品稳定性' },
{ label: 'cDNA样品稳定性', value: 'cDNA样品稳定性' },
{ label: '提取前样品冰浴放置稳定性', value: '提取前样品冰浴放置稳定性' },
{ label: '提取前样品反复冻融稳定性', value: '提取前样品反复冻融稳定性' },
{ label: '提取前样品长期冻存稳定性', value: '提取前样品长期冻存稳定性' },
{ label: '方法适用性', value: '方法适用性' },
{ label: '基因组DNA残留测定', value: '基因组DNA残留测定' },
{ label: '稀释线性', value: '稀释线性' },
{ label: '反复动态稳定性', value: '反复动态稳定性' },
{ label: '标准工作液稳定性', value: '标准工作液稳定性' }
{ label: '提取前组织样品裂解液中冰浴放置稳定性', value: '提取前组织样品裂解液中冰浴放置稳定性' },
{ label: '标准工作液稳定性', value: '标准工作液稳定性' },
{ label: '提取前组织样品裂解液中反复冻融稳定性', value: '提取前组织样品裂解液中反复冻融稳定性' },
{ label: '提取前组织样品裂解液中长期冻存稳定性', value: '提取前组织样品裂解液中长期冻存稳定性' },
{ label: '提取后样品室温(10~30℃)放置稳定性', value: '提取后样品室温(10~30℃)放置稳定性' },
{ label: '提取后样品2~8℃放置稳定性', value: '提取后样品2~8℃放置稳定性' },
{ label: '提取后样品反复冻融稳定性', value: '提取后样品反复冻融稳定性' },
{ label: '提取后样品长期冻存稳定性', value: '提取后样品长期冻存稳定性' },
{ label: 'cDNA样品室温(10~30℃)放置稳定性', value: 'cDNA样品室温(10~30℃)放置稳定性' },
{ label: 'cDNA样品2~8℃放置稳定性', value: 'cDNA样品2~8℃放置稳定性' }
]
}

Loading…
Cancel
Save