Browse Source

feat:[模板管理][update]

lkf
luojie 3 months ago
parent
commit
5ebeebb3bf
11 changed files with 165 additions and 305 deletions
  1. +41
    -26
      src/components/Template/BaseInfoFormPcakge.vue
  2. +14
    -11
      src/components/Template/CustomTable.vue
  3. +88
    -247
      src/components/Template/HandleFormItem.vue
  4. +2
    -2
      src/components/Template/Step.vue
  5. +1
    -4
      src/store/modules/template.js
  6. +10
    -0
      src/views/business/comps/template/TemplateTable.vue
  7. +1
    -1
      src/views/business/comps/template/comps/sp/SWYPBQGZYZBB.vue
  8. +1
    -2
      src/views/business/comps/template/comps/sp/SWYPFXCBYPZB.vue
  9. +4
    -5
      src/views/business/comps/template/comps/sp/SWYPFXRYPZB.vue
  10. +2
    -1
      src/views/business/comps/template/comps/sp/SWYPNBGZYZBB.vue
  11. +1
    -6
      src/views/business/comps/template/mixins/templateMixin.js

+ 41
- 26
src/components/Template/BaseInfoFormPcakge.vue View File

@ -8,13 +8,14 @@
:class="sItem.span == 1 ? 'full-row' : ''" :key="key">
<template v-if="sItem.type === 'input'">
<div class="form-title">{{ sItem.label }}</div>
<HandleFormItem @blur="onBlur(key, $event)" :item="sItem" v-model="formFields[key]"
<HandleFormItem :field-item-label="fieldItemLabel" @blur="onBlur(key, $event)" :item="sItem" v-model="formFields[key]"
:field-key="key"
@copy="onCopy(sItem, key)" :error="errors[key]" @update:error="errors[key] = false"
:orange-bg="orangeBgFields[key]" />
</template>
<template v-else-if="sItem.type === 'inputNumber'">
<div class="form-title">{{ sItem.label }}</div>
<HandleFormItem type="inputNumber" @blur="onBlur(key, $event)" :item="sItem"
<HandleFormItem :field-item-label="fieldItemLabel" :field-key="key" type="inputNumber" @blur="onBlur(key, $event)" :item="sItem"
@input="onInputNumberChange(key, $event)" v-model="formFields[key]"
@copy="onCopy(sItem, key)" :error="errors[key]" @update:error="errors[key] = false"
:orange-bg="orangeBgFields[key]" />
@ -29,7 +30,7 @@
<div class="p-r-20">
<div class="form-title">{{ sItem.label }}</div>
<div class="flex flex1">
<HandleFormItem type="select" :item="sItem" v-model="formFields[key]"
<HandleFormItem :field-item-label="fieldItemLabel" :field-key="key" type="select" :item="sItem" v-model="formFields[key]"
@copy="onCopy(sItem, key)" @change="onSelectChange(key, $event)"
:error="errors[key]" @update:error="errors[key] = false"
:orange-bg="orangeBgFields[key]" />
@ -40,7 +41,7 @@
<div v-show="isShowOther(formFields[key])">
<div class="form-title">其他</div>
<div class="flex flex1">
<HandleFormItem @blur="onBlur(key, $event)" :item="getOtherItem(sItem)"
<HandleFormItem :field-item-label="fieldItemLabel" :field-key="sItem.otherCode" @blur="onBlur(key, $event)" :item="getOtherItem(sItem)"
v-model="formFields[sItem.otherCode]" @copy="onCopy(sItem, key)"
:error="errors[sItem.otherCode]"
@update:error="errors[sItem.otherCode] = false" />
@ -59,28 +60,28 @@
<div v-for="(sItem, key) in item.config" class="c-Item" :class="getSpanClass(sItem)" :key="key">
<div class="form-title" v-if="sItem.label">{{ sItem.label }}</div>
<div v-if="sItem.type === 'dateTime'" class="flex1">
<HandleFormItem type="dateTime" :item="sItem" v-model="formFields[key]"
<HandleFormItem :field-item-label="fieldItemLabel" :field-key="key" type="dateTime" :item="sItem" v-model="formFields[key]"
@copy="onCopy(sItem, key)" :error="errors[key]" @update:error="errors[key] = false"
:orange-bg="orangeBgFields[key]" />
</div>
<div v-else-if="sItem.type === 'select'">
<HandleFormItem type="select" :item="sItem" v-model="formFields[key]"
<HandleFormItem :field-item-label="fieldItemLabel" :field-key="key" type="select" :item="sItem" v-model="formFields[key]"
@copy="onCopy(sItem, key)" @change="onSelectChange(key, $event)"
:error="errors[key]" @update:error="errors[key] = false"
:orange-bg="orangeBgFields[key]" />
</div>
<div v-else-if="sItem.type === 'input'">
<HandleFormItem @blur="onBlur(key, $event)" :item="sItem" v-model="formFields[key]"
<HandleFormItem :field-item-label="fieldItemLabel" :field-key="key" @blur="onBlur(key, $event)" :item="sItem" v-model="formFields[key]"
@copy="onCopy(sItem, key)" :error="errors[key]" @update:error="errors[key] = false"
:orange-bg="orangeBgFields[key]" />
</div>
<div v-else-if="sItem.type === 'textarea'">
<HandleFormItem @blur="onBlur(key, $event)" type="textarea" :item="sItem"
<HandleFormItem :field-item-label="fieldItemLabel" :field-key="key" @blur="onBlur(key, $event)" type="textarea" :item="sItem"
v-model="formFields[key]" @copy="onCopy(sItem, key)" :error="errors[key]"
@update:error="errors[key] = false" :orange-bg="orangeBgFields[key]" />
</div>
<div v-else-if="sItem.type === 'clickable'" class="flex1">
<HandleFormItem type="clickable" @clickable="handleClickable(sItem, $event)"
<HandleFormItem :field-item-label="fieldItemLabel" :field-key="key" type="clickable" @clickable="handleClickable(sItem, $event)"
:item="sItem" :value="formFields[key]" />
</div>
@ -95,19 +96,19 @@
:class="getSpanClass(sItem)" :key="key">
<div class="step-form-title" v-if="sItem.label">{{ sItem.label }}</div>
<div v-if="sItem.type === 'dateTime'" class="flex1">
<HandleFormItem type="dateTime" :item="sItem" v-model="formFields[key]"
<HandleFormItem :field-item-label="fieldItemLabel" :field-key="key" type="dateTime" :item="sItem" v-model="formFields[key]"
@copy="onCopy(sItem, key)" :error="errors[key]" @update:error="errors[key] = false"
:orange-bg="orangeBgFields[key]" />
</div>
<div v-else-if="sItem.type === 'select'" class="flex flex1">
<HandleFormItem type="select" :item="sItem" style="width: auto;flex:1"
<HandleFormItem :field-item-label="fieldItemLabel" :field-key="key" type="select" :item="sItem" style="width: auto;flex:1"
v-model="formFields[key]" @copy="onCopy(sItem, key)"
@change="onSelectChange(key, $event)" :error="errors[key]"
@update:error="errors[key] = false" :orange-bg="orangeBgFields[key]" />
<div v-show="isShowOther(formFields[key])" class="flex flex1">
<div class="other-title">其他</div>
<div class="flex">
<HandleFormItem @blur="onBlur(key, $event)" :item="getOtherItem(sItem)"
<HandleFormItem :field-item-label="fieldItemLabel" :field-key="sItem.otherCode" @blur="onBlur(key, $event)" :item="getOtherItem(sItem)"
v-model="formFields[sItem.otherCode]" @copy="onCopy(sItem, key)"
:error="errors[sItem.otherCode]" @update:error="errors[sItem.otherCode] = false"
:orange-bg="orangeBgFields[sItem.otherCode]" />
@ -115,22 +116,22 @@
</div>
</div>
<div v-else-if="sItem.type === 'input'" class="flex flex1">
<HandleFormItem @blur="onBlur(key, $event)" class="flex1" :item="sItem"
<HandleFormItem :field-item-label="fieldItemLabel" :field-key="key" @blur="onBlur(key, $event)" class="flex1" :item="sItem"
v-model="formFields[key]" @copy="onCopy(sItem, key)" :error="errors[key]"
@update:error="errors[key] = false" :orange-bg="orangeBgFields[key]" />
<HandleFormItem class="ml-10" v-if="sItem.subType === 'select'" type="select"
<HandleFormItem :field-item-label="fieldItemLabel" :field-key="sItem.subKey" class="ml-10" v-if="sItem.subType === 'select'" type="select"
:item="getSubItem(sItem)" v-model="formFields[sItem.subKey]" @copy="onCopy(sItem, key)"
@change="onSelectChange(sItem.subKey, $event)" :error="errors[sItem.subKey]"
@update:error="errors[sItem.subKey] = false"
:orange-bg="orangeBgFields[sItem.subKey]" />
<div class="ml-10" v-else-if="sItem.subType === 'span'">{{ formFields[sItem.subKey] }}</div>
<HandleFormItem class="ml-10" v-else-if="sItem.subType === 'clickable'" type="clickable"
<HandleFormItem :field-item-label="fieldItemLabel" :field-key="sItem.subKey" class="ml-10" v-else-if="sItem.subType === 'clickable'" type="clickable"
@clickable="handleClickable(sItem, $event)" :item="getClickableItem(sItem)"
:value="formFields[sItem.subKey]" />
<div v-show="isShowOther(formFields[sItem.subKey])" class="flex flex1">
<div class="other-title">其他</div>
<div class="flex">
<HandleFormItem @blur="onBlur(key, $event)" :item="getOtherItem(sItem)"
<HandleFormItem :field-item-label="fieldItemLabel" :field-key="sItem.otherCode" @blur="onBlur(key, $event)" :item="getOtherItem(sItem)"
v-model="formFields[sItem.otherCode]" @copy="onCopy(sItem, key)"
:error="errors[sItem.otherCode]" @update:error="errors[sItem.otherCode] = false"
:orange-bg="orangeBgFields[sItem.otherCode]" />
@ -142,17 +143,17 @@
</div> -->
</div>
<div v-else-if="sItem.type === 'inputNumber'" class="flex flex1">
<HandleFormItem type="inputNumber" @blur="onBlur(key, $event)" class="flex1" :item="sItem"
<HandleFormItem :field-item-label="fieldItemLabel" :field-key="key" type="inputNumber" @blur="onBlur(key, $event)" class="flex1" :item="sItem"
@input="onInputNumberChange(key, $event)" :value="formFields[key]"
@copy="onCopy(sItem, key)" :error="errors[key]" @update:error="errors[key] = false"
:orange-bg="orangeBgFields[key]" />
<HandleFormItem class="ml-10" v-if="sItem.subType === 'select'" type="select"
<HandleFormItem :field-item-label="fieldItemLabel" :field-key="sItem.subKey" class="ml-10" v-if="sItem.subType === 'select'" type="select"
:item="getSubItem(sItem)" v-model="formFields[sItem.subKey]" @copy="onCopy(sItem, key)"
@change="onSelectChange(sItem.subKey, $event)" :error="errors[sItem.subKey]"
@update:error="errors[sItem.subKey] = false"
:orange-bg="orangeBgFields[sItem.subKey]" />
<div class="ml-10" v-else-if="sItem.subType === 'span'">{{ formFields[sItem.subKey] }}</div>
<HandleFormItem class="ml-10" v-else-if="sItem.subType === 'clickable'"
<HandleFormItem :field-item-label="fieldItemLabel" :field-key="sItem.subKey" class="ml-10" v-else-if="sItem.subType === 'clickable'"
@clickable="handleClickable(sItem, $event)" type="clickable"
:item="getClickableItem(sItem)" :value="formFields[sItem.subKey]" />
<!-- <div class="clickable" :class="getFillType(sItem.subFillType)" v-else-if = "sItem.subType ==='clickable'" @click="handleClickable(sItem,$event)">
@ -161,7 +162,7 @@
</div> -->
</div>
<div v-else-if="sItem.type === 'clickable'" class="flex flex1">
<HandleFormItem type="clickable" @clickable="handleClickable(sItem, $event)"
<HandleFormItem :field-item-label="fieldItemLabel" :field-key="key" type="clickable" @clickable="handleClickable(sItem, $event)"
:error="errors[key]" :item="sItem" :value="formFields[key]" />
</div>
</div>
@ -175,6 +176,7 @@
import HandleFormItem from "./HandleFormItem.vue";
import LineLabel from "./LineLabel.vue";
export default {
inject: ['templateFillType'],
components: {
HandleFormItem,
LineLabel
@ -191,6 +193,11 @@ export default {
formData: {
type: Object,
value: () => ({})
},
//
fieldItemLabel: {
type: String,
default: "",
}
},
data() {
@ -202,6 +209,7 @@ export default {
};
},
watch: {
formData: {
immediate: true,
deep: true, // 便
@ -211,6 +219,15 @@ export default {
}
}
},
fieldItemLabel: {
immediate: true,
deep: true, // 便
handler(v) {
if (v) {
console.log(v,"fieldItemLabel")
}
}
},
formConfig: {
immediate: true,
deep: true, // 便
@ -263,7 +280,7 @@ export default {
},
handleClickable(sItem, event) {
console.log("clickable", sItem)
if (this.$store.state.template.templateStatus !== 'actFill') {
if (this.templateFillType !== 'actFill') {
return
}
this.$emit("clickable", sItem)
@ -374,11 +391,10 @@ export default {
if (item.hasOwnProperty("disabled")) {
return item.disabled
} else {
const { templateStatus } = this.$store.state.template;
if (fillType === "actFill") {//fillTypeactFill
return templateStatus !== "actFill"
return this.templateFillType !== "actFill"
} else if (fillType === "preFill") {//fillTypepreFill
return templateStatus !== "preFill"
return this.templateFillType !== "preFill"
} else {
return true
}
@ -387,7 +403,6 @@ export default {
//
validateFormData() {
const { formFields, allFieldsConfig } = this;
const { templateStatus } = this.$store.state.template;
const errors = [];
//
@ -418,7 +433,7 @@ export default {
if (o.type === "span") {
continue
}
if (o.fillType == templateStatus && !o.disabled) {
if (o.fillType === this.templateFillType && !o.disabled) {
let prefix = "";
if (o.type === "input" || o.type === "inputNumber" || o.type === "textarea") {
prefix = "填写";

+ 14
- 11
src/components/Template/CustomTable.vue View File

@ -8,8 +8,8 @@
<div class="header-cell-content">
<div>{{ col.label }}</div>
<template
v-if="col.headerSelectKey && col.headerOptions && (showHeaderSelect || $store.state.template.templateStatus === 'preFill')">
<HandleFormItem type="select" class="header-select" :item="getHeaderItem(col)"
v-if="col.headerSelectKey && col.headerOptions && (showHeaderSelect || templateFillType === 'preFill')">
<HandleFormItem :fieldKey="col.headerSelectKey+'_'+rowIndex" :fieldItemLabel="fieldItemLabel" type="select" class="header-select" :item="getHeaderItem(col)"
v-model="headerSelectFields[col.headerSelectKey]" @change="onHeaderSelectChange(col, $event)"
:error="hasError(-1, index, col.headerSelectKey)"
@update:error="onErrorUpdate(-1, index, col.headerSelectKey, $event)" />
@ -36,7 +36,7 @@
<div class="inner-table-cell">
<div>
<template v-if="col.bodyType === 'input'">
<HandleFormItem type="input" @blur="onBlur(rowIndex, col.prop, $event)" @copy="onCopy(rowIndex, col)"
<HandleFormItem :fieldKey="col.prop+'_'+rowIndex" :fieldItemLabel="fieldItemLabel" type="input" @blur="onBlur(rowIndex, col.prop, $event)" @copy="onCopy(rowIndex, col)"
class="body-input" :item="getBodyItem(col, rowIndex)" v-model="row[col.prop]"
@change="onBodyValueChange(rowIndex, colIndex, $event)"
:error="hasError(rowIndex, colIndex, col.prop)"
@ -44,7 +44,7 @@
:orange-bg="hasOrangeBg(rowIndex, colIndex, col.prop)" />
</template>
<template v-else-if="col.bodyType === 'inputNumber'">
<HandleFormItem type="inputNumber" @copy="onCopy(rowIndex, col)" class="body-input-number"
<HandleFormItem :fieldKey="col.prop+'_'+rowIndex" :fieldItemLabel="fieldItemLabel" type="inputNumber" @copy="onCopy(rowIndex, col)" class="body-input-number"
:item="getBodyItem(col, rowIndex)" v-model="row[col.prop]" @blur="onBlur(rowIndex, col.prop, $event)"
@change="onBodyValueChange(rowIndex, colIndex, $event)"
:error="hasError(rowIndex, colIndex, col.prop)"
@ -52,7 +52,7 @@
:orange-bg="hasOrangeBg(rowIndex, colIndex, col.prop)" />
</template>
<template v-else-if="col.bodyType === 'select'">
<HandleFormItem type="select" class="body-select" @blur="onBlur(rowIndex, col.prop, $event)"
<HandleFormItem :fieldKey="col.prop+'_'+rowIndex" :fieldItemLabel="fieldItemLabel" type="select" class="body-select" @blur="onBlur(rowIndex, col.prop, $event)"
:item="getBodyItem(col, rowIndex)" v-model="row[col.prop]"
@change="onBodyValueChange(rowIndex, colIndex, $event)"
:error="hasError(rowIndex, colIndex, col.prop)"
@ -65,7 +65,7 @@
</div>
<div class="m-l-5" v-if="col.showBodySub">
<template v-if="col.bodySubType === 'inputNumber'">
<HandleFormItem type="inputNumber" @blur="onSubBlur(rowIndex, col.bodySubKey, $event)"
<HandleFormItem :fieldKey="col.bodySubKey+'_'+rowIndex" :fieldItemLabel="fieldItemLabel" type="inputNumber" @blur="onSubBlur(rowIndex, col.bodySubKey, $event)"
@copy="onCopy(rowIndex, col)" :item="getBodySubItem(col)" v-model="row[col.bodySubKey]"
@change="onBodySubValueChange(rowIndex, colIndex, $event)"
:error="hasError(rowIndex, colIndex, col.bodySubKey)"
@ -102,6 +102,7 @@
<script>
import HandleFormItem from "./HandleFormItem.vue"
export default {
inject: ['templateFillType'],
name: 'CustomTable',
components: {
HandleFormItem
@ -139,6 +140,10 @@ export default {
}
}
},
fieldItemLabel: {
type: String,
default: '',
},
},
data() {
return {
@ -161,14 +166,13 @@ export default {
},
mounted() {
// this.initHeaderSelectValues();
console.log(this.$store.state.template.templateStatus, "this.$store.state.template.templateStatus")
},
methods: {
isShowAddRos() {
if(!this.showAddRow) {
return false;
}
return this.$store.state.template.templateStatus === 'preFill';
return this.templateFillType === 'preFill';
},
//
onCopy(rowIndex, col) {
@ -220,7 +224,6 @@ export default {
},
//
validateFormData() {
const templateStatus = this.$store.state.template.templateStatus;
const errors = [];
//
@ -228,7 +231,7 @@ export default {
// HandleFormItem
this.columns.forEach((col, colIndex) => {
if (col.headerSelectKey && col.headerOptions && col.fillType === templateStatus) {
if (col.headerSelectKey && col.headerOptions && col.fillType === this.templateFillType) {
const headerValue = this.headerSelectFields[col.headerSelectKey];
if (this.isValueEmpty(headerValue)) {
const errorItem = {
@ -249,7 +252,7 @@ export default {
//
this.columns.forEach((col, colIndex) => {
// fillType
if (col.bodyFillType === templateStatus || col.bodySubFillType === templateStatus) {
if (col.bodyFillType === this.templateFillType || col.bodySubFillType === this.templateFillType) {
//
const mainValue = row[col.prop];
if (this.isValueEmpty(mainValue) && !col.bodyDisabled) {

+ 88
- 247
src/components/Template/HandleFormItem.vue View File

@ -34,12 +34,12 @@
<!-- qc才能操作 -->
<div class="handle-row" v-if="isShowHandle()">
<el-checkbox class="ml-5" @change="onCheckboxChange"></el-checkbox>
<div @mouseenter="onMouseEnter" @mouseleave="onMouseLeave">
<div v-if="getIsShowQuestionIcon()" @mouseenter="(e)=>onMouseEnter('replyRecord',e)" @mouseleave="onMouseLeave">
<Question class="handle-icon" :class="getQuestionColor()" />
</div>
<img v-if="getIsShowCopyIcon()" @click="onCopy" src="@/assets/images/copy-icon.svg" class="handle-icon"
<img v-if="getIsShowCopyIcon()" @click="onCopy" src="@/assets/images/copy-icon.svg" class="handle-icon"
alt="" />
<img src="@/assets/images/record-icon.svg" class="handle-icon" alt="" />
<img v-if="getIsShowRecordIcon()" @mouseenter="(e)=>onMouseEnter('modifyRecord',e)" @mouseleave="onMouseLeave" src="@/assets/images/record-icon.svg" class="handle-icon" alt="" />
</div>
<!-- 修改记录模态框 -->
@ -51,21 +51,38 @@
@mouseleave="onModalLeave"
>
<div class="modal-content">
<h4>修改记录</h4>
<div class="records-list">
<div
v-for="(record, index) in modificationRecords"
:key="index"
class="record-item"
>
<p><strong>时间:</strong> {{ record.timestamp }}</p>
<p><strong>旧值:</strong> {{ record.oldValue }}</p>
<p><strong>新值:</strong> {{ record.newValue }}</p>
<!-- 字段修改记录 -->
<div class="record-row" v-if="currentRecordType === 'modifyRecord'">
<div>
<span>{{index+1}}.</span>
<span> {{ record.userName }} </span>
<span>{{ record.time }} </span>
<span>{{ record.title }}</span>
</div>
<div v-if="record.oldValue && record.value">
<div>原值{{record.oldValue}}</div>
<div>修改值{{record.value}}</div>
</div>
</div>
<!-- 回复记录 -->
<div class="record-row" v-if="currentRecordType === 'replyRecord'">
<div>
<span> {{ record.userName }} </span>
<span>{{ record.time }} </span>
</div>
<div>
<div v-if="record.content">复核意见{{record.content}}</div>
<div v-if="record.replay">回复意见{{record.replay}}</div>
</div>
</div>
<hr v-if="index < modificationRecords.length - 1">
</div>
<div v-if="!modificationRecords || modificationRecords.length === 0" class="no-records">
暂无修改记录
</div>
</div>
</div>
</div>
@ -77,7 +94,7 @@ import Question from "./icons/Question.vue";
import DecimalInput from "./DecimalInput.vue";
import { EventBus } from "@/utils/eventBus"
export default {
inject: ['templateFillType'],
inject: ['templateFillType',"zdxgjl","fhyjjl"],
components: {
Question,
DecimalInput
@ -113,6 +130,14 @@ export default {
type: Boolean,
default: false
},
fieldKey: {
type: String,
default: ""
},
fieldItemLabel: {
type: String,
default: "",
}
},
data() {
return {
@ -123,7 +148,7 @@ export default {
modalTimer: null, //
isHoveringModal: false, //
isHoveringMain: false, //
db: null, // IndexedDB
currentRecordType: '', // replyRecord modifyRecord
}
},
watch: {
@ -135,7 +160,11 @@ export default {
},
mounted() {
console.log(this.$i18n.locale,"locale")
},
methods: {
getFillTypeStyle(type) {
const {fillType} = this.item;
const typeObj = {
@ -156,8 +185,7 @@ export default {
},
//
onCheckboxChange(val) {
const {templateStatus} = this.$store.state.template;
console.log(this.templateFillType,"templateStatus")
console.log(this.zdxgjl,"zdxgjl")
//
EventBus.$emit('onModifyRecord', {
timestamp: new Date().toLocaleString(),
@ -167,6 +195,7 @@ export default {
// this.$emit('input', val);
// this.$emit('change', val);
},
//
onSelectBlur(visible) {
if (!visible) {
this.onCommonHandleSaveRecord(this.inputValue);
@ -198,9 +227,8 @@ export default {
} else if (!this.error && isEmpty) {
this.$emit('update:error', true);
}
const {templateStatus} = this.$store.state.template;
//
if (templateStatus === "actFill") {
if (this.templateFillType === "actFill") {
//
try {
if(this.oldValue && this.oldValue !== this.inputValue){
@ -213,6 +241,15 @@ export default {
zIndex: 10000,
});
}
const {nickName,name} = this.$store.getters;
//locale:zh-CN en-US
const lang = this.$i18n.locale === "zh-CN"?"cn":"en";
const commonInfo = {
userNameCn:nickName,
userNameEn:name,
key:this.fieldKey,
field:`${this.fieldItemLabel}-${this.item.label}`
}
this.$emit("onModifyRecord", {
timestamp: new Date().toLocaleString(),
oldValue: this.oldValue,
@ -264,16 +301,13 @@ export default {
//
getIsShowCopyIcon() {
const { copyFrom } = this.item;
const { templateStatus } = this.$store.state.template;
return copyFrom && templateStatus === "actFill";
return copyFrom && this.templateFillType === "actFill";
},
//
isShowHandle() {
const { fillType } = this.item;
const { templateStatus } = this.$store.state.template;
return true;
//qc
return (templateStatus === "qc" || templateStatus === "actFill") && fillType === "actFill";
return (this.templateFillType === "qc" || this.templateFillType === "actFill") && fillType === "actFill";
},
//
getDisabled() {
@ -282,11 +316,10 @@ export default {
if (item.hasOwnProperty("disabled")) {
return item.disabled
} else {
const { templateStatus } = this.$store.state.template;
if (fillType === "actFill") {//fillTypeactFill
return templateStatus !== "actFill"
return this.templateFillType !== "actFill"
} else if (fillType === "preFill") {//fillTypepreFill
return templateStatus !== "preFill"
return this.templateFillType !== "preFill"
} else {
return true
}
@ -311,210 +344,41 @@ export default {
onCopy() {
this.$emit("copy")
},
//
//
// IndexedDB
initDB() {
return new Promise((resolve, reject) => {
const request = indexedDB.open('ModificationRecordsDB', 1);
request.onerror = (event) => {
console.error('IndexedDB error:', event.target.error);
reject(event.target.error);
};
request.onsuccess = (event) => {
this.db = event.target.result;
resolve(this.db);
};
request.onupgradeneeded = (event) => {
const db = event.target.result;
if (!db.objectStoreNames.contains('modificationRecords')) {
const objectStore = db.createObjectStore('modificationRecords', { keyPath: 'id' });
objectStore.createIndex('fieldId', 'fieldId', { unique: false });
objectStore.createIndex('timestamp', 'timestamp', { unique: false });
}
};
});
},
// ID (id + key)
getFieldId() {
const templateId = 'template_123'; // id
const fieldKey = this.item.key || this.item.prop || this.item.label || 'default_key';
// CustomTablekey
//
const tableRowIndex = this.item.rowIndex !== undefined ? `_${this.item.rowIndex}` : '';
return `${templateId}_${fieldKey}${tableRowIndex}`;
},
// IndexedDB
async getObjectStore(storeName = 'modificationRecords', mode = 'readonly') {
if (!this.db) {
await this.initDB();
//
getIsShowQuestionIcon(){
if(this.templateFillType === "qc"){//qc
return true;
}
const transaction = this.db.transaction([storeName], mode);
return transaction.objectStore(storeName);
},
// IndexedDB
async saveRecordToDB(record) {
const objectStore = await this.getObjectStore('modificationRecords', 'readwrite');
const fieldId = this.getFieldId();
const newRecord = {
id: `${fieldId}_${Date.now()}`, // 使
fieldId: fieldId,
oldValue: record.oldValue,
newValue: record.newValue,
timestamp: new Date().toLocaleString(),
};
return new Promise((resolve, reject) => {
const request = objectStore.add(newRecord);
request.onsuccess = () => {
resolve(request.result);
};
request.onerror = (event) => {
reject(event.target.error);
};
});
},
// IndexedDB
async getRecordsFromDB() {
if (!this.db) {
await this.initDB();
}
const transaction = this.db.transaction(['modificationRecords'], 'readonly');
const objectStore = transaction.objectStore('modificationRecords');
const fieldIdIndex = objectStore.index('fieldId');
const fieldId = this.getFieldId();
return new Promise((resolve, reject) => {
const request = fieldIdIndex.getAll(IDBKeyRange.only(fieldId));
request.onsuccess = (event) => {
//
const records = event.target.result.sort((a, b) => {
return new Date(b.timestamp) - new Date(a.timestamp);
});
resolve(records);
};
request.onerror = (event) => {
reject(event.target.error);
};
});
//
getIsShowRecordIcon(){
return this.getModifyRecords().length>0
},
// IndexedDB
async syncRecordsToDB(backendRecords) {
//
await this.clearFieldRecords();
// IndexedDB
const objectStore = await this.getObjectStore('modificationRecords', 'readwrite');
const fieldId = this.getFieldId();
return new Promise((resolve, reject) => {
let completed = 0;
const total = backendRecords.length;
if (total === 0) {
resolve();
return;
}
backendRecords.forEach((record) => {
// IndexedDB
const newRecord = {
id: `${fieldId}_${Date.parse(record.timestamp) || Date.now()}`, // 使 ID
fieldId: fieldId,
oldValue: record.oldValue,
newValue: record.newValue,
timestamp: record.timestamp || new Date().toLocaleString(),
password: record.password ? '***' : '' //
};
const request = objectStore.add(newRecord);
request.onsuccess = () => {
completed++;
if (completed === total) {
resolve();
}
};
request.onerror = (event) => {
console.error('同步单条记录失败:', event.target.error);
completed++;
if (completed === total) {
resolve(); // 使
}
};
});
});
//
getReplyRecords(){
const {fieldKey,fhyjjl = []} = this;
const records = fhyjjl.filter(item => item.key === fieldKey);
return records;
},
//
async clearFieldRecords() {
if (!this.db) {
await this.initDB();
}
const transaction = this.db.transaction(['modificationRecords'], 'readwrite');
const objectStore = transaction.objectStore('modificationRecords');
const fieldIdIndex = objectStore.index('fieldId');
const fieldId = this.getFieldId();
return new Promise((resolve, reject) => {
const request = fieldIdIndex.openCursor(IDBKeyRange.only(fieldId));
request.onsuccess = (event) => {
const cursor = event.target.result;
if (cursor) {
cursor.delete(); //
cursor.continue();
} else {
//
resolve();
}
};
request.onerror = (event) => {
reject(event.target.error);
};
});
//
getModifyRecords(){
const {fieldKey,zdxgjl = []} = this;
const records = zdxgjl.filter(item => item.key === fieldKey);
return records;
},
//
async onMouseEnter(event) {
async onMouseEnter(type,event) {
this.currentRecordType = type;
clearTimeout(this.modalTimer);
// IndexedDB
try {
const records = await this.getRecordsFromDB();
this.modificationRecords = records;
} catch (error) {
console.error('获取修改记录失败:', error);
this.modificationRecords = [];
let record = [];
if(type === "modifyRecord"){
record = this.getModifyRecords();
}else if(type === "replyRecord"){
record = this.getReplyRecords();
}
console.log(record,"reeee")
this.modificationRecords = record;
//
this.showModal = true;
this.$nextTick(() => {
@ -531,6 +395,8 @@ export default {
//
onMouseLeave() {
this.currentRecordType = '';
this.modificationRecords = [];//
//
this.modalTimer = setTimeout(() => {
if (!this.isHoveringModal) {
@ -548,37 +414,12 @@ export default {
//
onModalLeave() {
this.isHoveringModal = false;
this.currentRecordType = "";
this.modificationRecords = [];//
this.modalTimer = setTimeout(() => {
this.showModal = false;
}, 300);
},
//
async saveModificationRecord() {
//
const record = {
oldValue: this.oldValue,
newValue: this.inputValue,
timestamp: new Date().toLocaleString(), //
};
// IndexedDB
try {
await this.saveRecordToDB(record);
//
// const records = await this.getRecordsFromDB();
// this.modificationRecords = records;
} catch (error) {
console.error('保存修改记录失败:', error);
}
//
this.$emit('modification-recorded', {
field: this.item.label || '',
oldValue: this.oldValue,
newValue: this.inputValue,
});
}
},
}
</script>

+ 2
- 2
src/components/Template/Step.vue View File

@ -78,6 +78,7 @@ const stepTypes = [
];
export default {
inject: ['templateFillType'],
name: 'Step',
props: {
formData: {
@ -180,8 +181,7 @@ export default {
},
methods: {
isShowAddStep() {
const {templateStatus} = this.$store.state.template
return templateStatus === 'preFill';
return this.templateFillType === 'preFill';
},
addStep() {
try {

+ 1
- 4
src/store/modules/template.js View File

@ -1,7 +1,6 @@
const template = {
namespaced: true,
state: {
templateStatus: "",//模板状态 "actFill"(实际填报) "preFill"(预填) ”qc“(qc) "detail"(详情)
templateData: {},//模板数据
//浓度单位
mgOptions: [
@ -34,9 +33,7 @@ const template = {
],
},
mutations: {
SET_TEMPLATE_STATUS: (state, status) => {
state.templateStatus = status
},
SET_TEMPLATE_DATA: (state, data) => {
state.templateData = data
},

+ 10
- 0
src/views/business/comps/template/TemplateTable.vue View File

@ -72,6 +72,16 @@ export default {
return {
//fillType
templateFillType: this.fillType,
zdxgjl: this.templateData?.zdxgjl || [
{key:"versionNum",title:'提交',filed:'试验基本信息-其他信息',value:'新值',oldValue:'',reason:'修改原因',userName:'签名人',time:'2026-01-01 14:22:22'},
{key:"versionNum",title:'修改记录',filed:'试验基本信息-其他信息',value:'新值',oldValue:'原值3',reason:'修改原因',userName:'签名人',time:'2026-01-01 14:22:22'},
{key:"act",title:'修改记录',filed:'试验基本信息-其他信息',value:'ss',oldValue:'old1',reason:'修改原因1',userName:'签名人',time:'2026-01-01 14:22:22'},
{key:"startSolutionCode_0",title:'修改记录',filed:'试验基本信息-其他信息',value:'ss',oldValue:'old1',reason:'修改原因1',userName:'签名人',time:'2026-01-01 14:22:22'},
],
fhyjjl: this.templateData?.fhyjjl || [
{key:"versionNum",title:'复核意见',field:'试验基本信息-其他信息',content:'复核意见内容',replay:'意见回复内容',userName:'签名人',time:'2026-01-01 14:22:22',sfhf:'1'}
],
}
},
data() {

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

@ -16,7 +16,7 @@
<div class="template-form-item">
<BaseInfoFormPcakge @clickable="handleClickable" ref="stepFormPackageRef" :formConfig="stepFormConfig" @blur="onHandleBlur"
:formData="formData" />
<CustomTable :showAddRow="fillType === 'actFill'" @blur="onHandleTableBlur" :showOperation="fillType === 'actFill'" ref="stepTableRef" :columns="stepColumns"
<CustomTable fieldItemLabel = "操作步骤" :showAddRow="fillType === 'actFill'" @blur="onHandleTableBlur" :showOperation="fillType === 'actFill'" ref="stepTableRef" :columns="stepColumns"
:formData="formData" >
<template slot="operation" slot-scope="{ row, rowIndex}">
<TableOpertaion :fillType="fillType" :row="row" :rowIndex="rowIndex" @deleteRow="deleteRow"></TableOpertaion>

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

@ -33,12 +33,11 @@ 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';
export default {
name: "SWYPFXRYPZB",
components: { BaseInfoFormPcakge, LineLabel, TableList, Step, CustomTable },
components: { BaseInfoFormPcakge, LineLabel, TableList, Step },
mixins: [templateMixin],
props: {
fillType: {

+ 4
- 5
src/views/business/comps/template/comps/sp/SWYPFXRYPZB.vue View File

@ -6,26 +6,25 @@
$t('template.common.pageTitle') }}<img src="@/assets/images/detail-title.png" /></div>
<div class="detail-content">
<div class="content">
<BaseInfoFormPcakge :label="$t('template.common.baseInfo')" ref="baseInfoRef"
<BaseInfoFormPcakge :fieldItemLabel="$t('template.common.baseInfo')" :label="$t('template.common.baseInfo')" ref="baseInfoRef"
:formConfig="baseInfoFormConfig" :formData="formData" />
<TableList :label="$t('template.common.reagentInfo')" :columns="sysjColumns"
:dataSource="resource" />
<TableList :label="$t('template.common.instrumentInfo')" :columns="yqsColumns"
:dataSource="resource" />
<BaseInfoFormPcakge :label="$t('template.common.storageCondition')" ref="storageConditionRef"
<BaseInfoFormPcakge :fieldItemLabel="$t('template.common.storageCondition')" :label="$t('template.common.storageCondition')" ref="storageConditionRef"
:formConfig="storageFormConfig" :formData="formData" />
<LineLabel :label="$t('template.common.operationSteps')" />
<div class="template-form-item">
<BaseInfoFormPcakge ref="stepFormPackageRef" :formConfig="stepFormConfig" @blur="onHandleBlur"
<BaseInfoFormPcakge :fieldItemLabel="$t('template.common.operationSteps')" ref="stepFormPackageRef" :formConfig="stepFormConfig" @blur="onHandleBlur"
:formData="formData" />
</div>
<Step ref="stepRef" :formData="formData.stepData"></Step>
<BaseInfoFormPcakge :label="$t('template.common.remark')" ref="remarkRef" :formConfig="remarkConig"
<BaseInfoFormPcakge :fieldItemLabel="$t('template.common.remark')" :label="$t('template.common.remark')" ref="remarkRef" :formConfig="remarkConig"
:formData="formData" />
</div>
</div>
<button @click="onSave">{{ $t('template.common.saveBtn') }}</button>
</div>
</div>
</template>

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

@ -20,7 +20,6 @@
<!-- 阶梯配制区域 -->
<div
label="阶梯配制"
v-for="(ladderConfig, ladderIndex) in formData.ladderConfigs"
:key="'ladder_' + ladderIndex"
>
@ -47,6 +46,7 @@
:ref="`ladderStepTableRef_${ladderIndex}`"
:columns="ladderStepColumns"
:formData="ladderConfig"
fieldItemLabel = "阶梯配制"
>
<template slot="operation" slot-scope="{ row, rowIndex}">
<TableOpertaion
@ -95,6 +95,7 @@
:ref="`paralleStepTableRef_${paralleIndex}`"
:columns="paralleStepColumns"
:formData="paralleConfig"
fieldItemLabel = "平行配制"
>
<template slot="operation" slot-scope="{ row, rowIndex}">
<TableOpertaion

+ 1
- 6
src/views/business/comps/template/mixins/templateMixin.js View File

@ -35,11 +35,8 @@ export default {
}
},
mounted() {
// this.setTemplateStatus("actFill");
this.setTemplateStatus(this.fillType);
},
unmounted() {
this.setTemplateStatus("");
this.setTemplateData({});
},
methods: {
@ -88,9 +85,7 @@ export default {
getDictOptions(dictType) {
return this.dict.type[dictType] || [];
},
setTemplateStatus(status) {
this.$store.commit('template/SET_TEMPLATE_STATUS', status)
},
setTemplateData(data) {
this.$store.commit('template/SET_TEMPLATE_DATA', data)
},

Loading…
Cancel
Save