Browse Source

feat:[模板管理][优化交互]

lkf
luojie 3 months ago
parent
commit
f2f056f95b
4 changed files with 146 additions and 65 deletions
  1. +6
    -2
      src/components/Template/BaseInfoFormPcakge.vue
  2. +98
    -49
      src/components/Template/HandleFormItem.vue
  3. +32
    -10
      src/views/business/comps/template/TemplateTable.vue
  4. +10
    -4
      src/views/business/comps/template/comps/sp/SWYPFXRYPZB.vue

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

@ -124,7 +124,7 @@
@change="onSelectChange(sItem.subKey, $event)" :error="errors[sItem.subKey]" @change="onSelectChange(sItem.subKey, $event)" :error="errors[sItem.subKey]"
@update:error="errors[sItem.subKey] = false" @update:error="errors[sItem.subKey] = false"
:orange-bg="orangeBgFields[sItem.subKey]" /> :orange-bg="orangeBgFields[sItem.subKey]" />
<div class="ml-10" v-else-if="sItem.subType === 'span'">{{ formFields[sItem.subKey] }}</div>
<div class="ml-10 item-span" v-else-if="sItem.subType === 'span'">{{ formFields[sItem.subKey] }}</div>
<HandleFormItem :field-item-label="fieldItemLabel" :field-key="sItem.subKey" 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)" @clickable="handleClickable(sItem, $event)" :item="getClickableItem(sItem)"
:value="formFields[sItem.subKey]" /> :value="formFields[sItem.subKey]" />
@ -152,7 +152,7 @@
@change="onSelectChange(sItem.subKey, $event)" :error="errors[sItem.subKey]" @change="onSelectChange(sItem.subKey, $event)" :error="errors[sItem.subKey]"
@update:error="errors[sItem.subKey] = false" @update:error="errors[sItem.subKey] = false"
:orange-bg="orangeBgFields[sItem.subKey]" /> :orange-bg="orangeBgFields[sItem.subKey]" />
<div class="ml-10" v-else-if="sItem.subType === 'span'">{{ formFields[sItem.subKey] }}</div>
<div class="ml-10 item-span" v-else-if="sItem.subType === 'span'">{{ formFields[sItem.subKey] }}</div>
<HandleFormItem :field-item-label="fieldItemLabel" :field-key="sItem.subKey" 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" @clickable="handleClickable(sItem, $event)" type="clickable"
:item="getClickableItem(sItem)" :value="formFields[sItem.subKey]" /> :item="getClickableItem(sItem)" :value="formFields[sItem.subKey]" />
@ -669,4 +669,8 @@ export default {
.ml-10 { .ml-10 {
margin-left: 10px; margin-left: 10px;
} }
.item-span{
color: #606266;
font-size: 14px;
}
</style> </style>

+ 98
- 49
src/components/Template/HandleFormItem.vue View File

@ -15,7 +15,7 @@
:placeholder="getPlaceholder()" v-model="inputValue" @input="onInputChange" @change="onInputChange" /> :placeholder="getPlaceholder()" v-model="inputValue" @input="onInputChange" @change="onInputChange" />
<el-select v-else-if="type === 'select'" class="flex1" :multiple="item.multiple" <el-select v-else-if="type === 'select'" class="flex1" :multiple="item.multiple"
:class="getFillTypeStyle() + (orangeBg ? ' orange-bg' : '')" v-model="inputValue" :class="getFillTypeStyle() + (orangeBg ? ' orange-bg' : '')" v-model="inputValue"
:disabled="getDisabled()" :placeholder="getPlaceholder()" @visible-change="onSelectBlur"
:disabled="getDisabled()" :placeholder="getPlaceholder()" @remove-tag = "onRemoveTag" @visible-change="onSelectBlur"
@change="onInputChange"> @change="onInputChange">
<el-option v-for="op in item.options" :key="op.value" :label="op.label" :value="op.value"> <el-option v-for="op in item.options" :key="op.value" :label="op.label" :value="op.value">
</el-option> </el-option>
@ -34,10 +34,11 @@
</div> </div>
<!-- qc才能操作 --> <!-- qc才能操作 -->
<div class="handle-row" v-if="isShowHandle()"> <div class="handle-row" v-if="isShowHandle()">
<el-checkbox :checked = "getChecked()" v-if = "this.templateFillType === 'qc'" class="mr-5" @change="onCheckboxChange"></el-checkbox>
<el-checkbox :checked="getChecked()" v-if="this.templateFillType === 'qc'" class="mr-5"
@change="onCheckboxChange"></el-checkbox>
<div class="handle-icon" v-if="getIsShowQuestionIcon()" @click="onClickQuestion" <div class="handle-icon" v-if="getIsShowQuestionIcon()" @click="onClickQuestion"
@mouseenter="(e) => onMouseEnter('replyRecord', e)" @mouseleave="onMouseLeave"> @mouseenter="(e) => onMouseEnter('replyRecord', e)" @mouseleave="onMouseLeave">
<Question :class="getQuestionColor()" />
<Question :class="getQuestionColor()" />
</div> </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="" /> alt="" />
@ -81,9 +82,10 @@
</div> </div>
</div> </div>
</div> </div>
<el-dialog append-to-body :title="templateFillType=='actFill'?'回复意见':'复核意见'" :visible.sync="visible" width="30%" >
<el-input v-model="replyContent" type="textarea" show-word-limit
resize="none" rows="8" placeholder="输入内容" maxlength = "500" />
<el-dialog append-to-body :title="templateFillType == 'actFill' ? '回复意见' : '复核意见'" :visible.sync="visible"
width="30%">
<el-input v-model="replyContent" type="textarea" show-word-limit resize="none" rows="8" placeholder="输入内容"
maxlength="500" />
<span slot="footer" class="dialog-footer"> <span slot="footer" class="dialog-footer">
<el-button @click="visible = false"> </el-button> <el-button @click="visible = false"> </el-button>
<el-button type="primary" @click="onReplyConfirm"> </el-button> <el-button type="primary" @click="onReplyConfirm"> </el-button>
@ -97,9 +99,9 @@ import Question from "./icons/Question.vue";
import DecimalInput from "./DecimalInput.vue"; import DecimalInput from "./DecimalInput.vue";
import { EventBus } from "@/utils/eventBus"; import { EventBus } from "@/utils/eventBus";
import moment from "moment"; import moment from "moment";
import {deepClone} from "@/utils/index";
import { deepClone } from "@/utils/index";
export default { export default {
inject: ['templateFillType', "zdxgjl", "fhyjjl", "updateZdxgjl", "replaceFhyjjl", "updateFhyjjl","fieldCheckObj", "updateFieldCheckObj"],
inject: ['templateFillType', "getZdxgjl", "getFhyjjl", "updateZdxgjl", "replaceFhyjjl", "updateFhyjjl", "getFieldCheckObj", "updateFieldCheckObj"],
components: { components: {
Question, Question,
DecimalInput DecimalInput
@ -155,8 +157,8 @@ export default {
isHoveringMain: false, // isHoveringMain: false, //
currentRecordType: '', // replyRecord modifyRecord currentRecordType: '', // replyRecord modifyRecord
replyContent: '', // replyContent: '', //
visible:false,//
checked:false,//
visible: false,//
checked: false,//
} }
}, },
watch: { watch: {
@ -173,8 +175,8 @@ export default {
}, },
methods: { methods: {
getChecked(){
return !!this.fieldCheckObj[this.fieldKey]?.checked;
getChecked() {
return !!this.getFieldCheckObj()[this.fieldKey]?.checked;
}, },
getFillTypeStyle(type) { getFillTypeStyle(type) {
const { fillType } = this.item; const { fillType } = this.item;
@ -190,7 +192,7 @@ export default {
return typeObj[fillType] || "" return typeObj[fillType] || ""
}, },
// //
onReplyConfirm(){
onReplyConfirm() {
if (!this.replyContent) { if (!this.replyContent) {
this.$message({ this.$message({
message: '请输入内容', message: '请输入内容',
@ -202,33 +204,48 @@ export default {
const record = { const record = {
...baseInfo, ...baseInfo,
title: this.templateFillType == 'actFill' ? "回复意见" : "复核意见", title: this.templateFillType == 'actFill' ? "回复意见" : "复核意见",
time: moment().format("YYYY-MM-DD HH:mm:ss"),
} }
if(this.templateFillType == 'actFill'){
if (this.templateFillType == 'actFill') {
record.replay = this.replyContent; record.replay = this.replyContent;
const deepList = deepClone(this.fhyjjl);//
const deepList = deepClone(this.getFhyjjl());//
const item = deepList.find(o => o.key == record.key); const item = deepList.find(o => o.key == record.key);
if(item){
if (item) {
item.replay = this.replyContent; item.replay = this.replyContent;
} }
this.replaceFhyjjl(deepList);// this.replaceFhyjjl(deepList);//
}else{
} else {
const records = this.getReplyRecords();
record.content = this.replyContent; record.content = this.replyContent;
this.updateFhyjjl(record);//qc
}
const params = {
type: "reply",
newRecord: record,
resourceList: deepClone(this.fhyjjl),
if (records.length > 0) {
const o = records[0];
if (o.reply && o.content) {//
this.updateFhyjjl(record);//qc
} else {//
const deepList = deepClone(this.getFhyjjl());
const item = deepList.find(it => it.key == record.key);
if (item) {
item.content = this.replyContent;
} }
this.replaceFhyjjl(deepList);
}
} else {
this.updateFhyjjl(record);//qc
}
}
const params = {
type: "reply",
newRecord: record,
resourceList: deepClone(this.getFhyjjl()),
}
// //
EventBus.$emit('onModifyRecord', params); EventBus.$emit('onModifyRecord', params);
// //
this.replyContent = ''; this.replyContent = '';
// //
this.visible = false; this.visible = false;
}, },
//question //question
getQuestionColor() { getQuestionColor() {
@ -249,20 +266,23 @@ export default {
}, },
// //
onCheckboxChange(val) { onCheckboxChange(val) {
console.log(JSON.stringify({...this.fieldCheckObj,[this.fieldKey]:{checked:val}}),"kkk")
// //
EventBus.$emit('onModifyRecord', { EventBus.$emit('onModifyRecord', {
type: "checkbox", type: "checkbox",
fieldCheckObj:JSON.stringify({...this.fieldCheckObj,[this.fieldKey]:{checked:val}}),//
fieldCheckObj: JSON.stringify({ ...this.getFieldCheckObj(), [this.fieldKey]: { checked: val } }),//
}); });
this.updateFieldCheckObj({[this.fieldKey]:{checked:val}});
this.updateFieldCheckObj({ [this.fieldKey]: { checked: val } });
// this.$emit('input', val); // this.$emit('input', val);
// this.$emit('change', val); // this.$emit('change', val);
}, },
onRemoveTag(e){
this.onCommonHandleSaveRecord(this.inputValue);
},
// //
onSelectBlur(visible) { onSelectBlur(visible) {
if (!visible) { if (!visible) {
console.log(this.inputValue,"onSelectBlur")
this.onCommonHandleSaveRecord(this.inputValue); this.onCommonHandleSaveRecord(this.inputValue);
} }
}, },
@ -286,15 +306,29 @@ export default {
}, },
// question // question
onClickQuestion() { onClickQuestion() {
if(this.templateFillType == 'actFill' || this.templateFillType){
const field = this.fieldCheckObj[this.fieldKey];
if(field && field.checked){
this.$message({
message: '该字段已勾选复核框,请先取消勾选后再进行提交疑问',
type: 'error'
});
return;
const {templateFillType} = this;
if (templateFillType == 'actFill' || templateFillType == 'qc') {
if (templateFillType == 'qc') {
const field = this.getFieldCheckObj()[this.fieldKey];
if (field && field.checked) {
this.$message({
message: '该字段已勾选复核框,请先取消勾选后再进行提交疑问',
type: 'error'
});
return;
}
}
const records = this.getReplyRecords();
let content = "";
if (records.length > 0) {
const o = records[0];
if (!o.reply && templateFillType == 'qc') {//qc
content = o.content;
}else if(!o.content&& templateFillType == 'actFill'){//qc
content = o.replay;
}
} }
this.replyContent = content;
this.visible = true; this.visible = true;
} }
}, },
@ -310,7 +344,8 @@ export default {
if (this.templateFillType === "actFill") { if (this.templateFillType === "actFill") {
// //
try { try {
if (this.oldValue && this.oldValue !== this.inputValue) {
const isSame = this.isEqual(this.oldValue, this.inputValue);
if (this.oldValue && !isSame) {
const passwordResult = await this.$prompt('请输入密码以确认修改', '密码验证', { const passwordResult = await this.$prompt('请输入密码以确认修改', '密码验证', {
confirmButtonText: '确定', confirmButtonText: '确定',
cancelButtonText: '取消', cancelButtonText: '取消',
@ -326,16 +361,18 @@ export default {
oldValue: this.oldValue, oldValue: this.oldValue,
value: this.inputValue, value: this.inputValue,
title: this.oldValue ? "修改记录" : "填写", title: this.oldValue ? "修改记录" : "填写",
time: moment().format("YYYY-MM-DD HH:mm:ss"),
} }
const params = { const params = {
type: "fieldChanged", type: "fieldChanged",
newRecord: record, newRecord: record,
password: passwordResult, password: passwordResult,
resourceList: deepClone(this.zdxgjl),
resourceList: deepClone(this.getZdxgjl()),
} }
this.$emit("onModifyRecord", params,) this.$emit("onModifyRecord", params,)
this.updateZdxgjl(record); this.updateZdxgjl(record);
console.log(params, "params") console.log(params, "params")
} }
// //
@ -360,6 +397,17 @@ export default {
} }
}, },
//
isEqual(oldValue, nowValue){
if (oldValue === null || nowValue === null) {
return oldValue === nowValue;
}
if (typeof oldValue === 'object' && typeof nowValue === 'object') {
return JSON.stringify(oldValue) === JSON.stringify(nowValue);
}
return oldValue === nowValue;
},
// //
getCommonRecordInfo() { getCommonRecordInfo() {
const { nickName, name } = this.$store.getters; const { nickName, name } = this.$store.getters;
@ -377,7 +425,6 @@ export default {
userNameEn: name, userNameEn: name,
key: this.fieldKey, key: this.fieldKey,
field: `${this.fieldItemLabel}-${fieldLabel}`, field: `${this.fieldItemLabel}-${fieldLabel}`,
time: moment().format("YYYY-MM-DD HH:mm:ss"),
} }
return commonInfo; return commonInfo;
}, },
@ -409,7 +456,7 @@ export default {
// //
isShowHandle() { isShowHandle() {
// //
return this.templateFillType !== "preFill"
return this.templateFillType !== "preFill"
}, },
// //
getDisabled() { getDisabled() {
@ -460,14 +507,14 @@ export default {
}, },
// //
getReplyRecords() { getReplyRecords() {
const { fieldKey, fhyjjl = [] } = this;
const records = fhyjjl.filter(item => item.key === fieldKey);
const { fieldKey, getFhyjjl } = this;
const records = getFhyjjl()?.filter(item => item.key === fieldKey) || [];
return records; return records;
}, },
// //
getModifyRecords() { getModifyRecords() {
const { fieldKey, zdxgjl = [] } = this;
const records = zdxgjl.filter(item => item.key === fieldKey);
const { fieldKey, getZdxgjl } = this;
const records = getZdxgjl().filter(item => item.key === fieldKey);
return records; return records;
}, },
// //
@ -580,12 +627,13 @@ export default {
.handle-icon { .handle-icon {
width: 18px; width: 18px;
height: 18px; height: 18px;
&:not(:last-child) { &:not(:last-child) {
margin-right: 5px; margin-right: 5px;
} }
} }
.mr-5{
.mr-5 {
margin-right: 5px !important; margin-right: 5px !important;
} }
@ -797,7 +845,8 @@ export default {
border-color: #f56c6c !important; border-color: #f56c6c !important;
} }
} }
.dialog-footer{
.dialog-footer {
display: flex; display: flex;
justify-content: flex-end; justify-content: flex-end;
} }

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

@ -66,39 +66,58 @@ export default {
handler(v) { handler(v) {
console.log(v, "sn") console.log(v, "sn")
} }
},
templateData: {
immediate: true,
deep: true,
handler(v) {
if(v.zdxgjl){
this.zdxgjl = v.zdxgjl || [];
}
if(v.fhyjjl){
this.fhyjjl = v.fhyjjl || [];
}
if(v.fieldCheckObj){
this.fieldCheckObj = v.fieldCheckObj || {};
}
}
} }
}, },
provide() { provide() {
return { return {
//fillType //fillType
templateFillType: this.fillType, templateFillType: this.fillType,
zdxgjl: this.templateData?.zdxgjl || [
getZdxgjl: ()=>(this.zdxgjl || [
{key:"versionNum",title:'提交',filed:'试验基本信息-其他信息',value:'新值',oldValue:'',reason:'修改原因',userName:'签名人',time:'2026-01-01 14:22:22'}, {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:"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:"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'}, {key:"startSolutionCode_0",title:'修改记录',filed:'试验基本信息-其他信息',value:'ss',oldValue:'old1',reason:'修改原因1',userName:'签名人',time:'2026-01-01 14:22:22'},
],
fhyjjl: this.templateData?.fhyjjl || [
]),
getFhyjjl: ()=>(
this.fhyjjl || [
{key:"versionNum",title:'复核意见',field:'试验基本信息-其他信息',content:'复核意见内容',replay:'',userName:'签名人',time:'2026-01-01 14:22:22',sfhf:'1'} {key:"versionNum",title:'复核意见',field:'试验基本信息-其他信息',content:'复核意见内容',replay:'',userName:'签名人',time:'2026-01-01 14:22:22',sfhf:'1'}
],
fieldCheckObj:{
]
),
getFieldCheckObj: ()=>(
this.fieldCheckObj || {
versionNum:{checked:true}, versionNum:{checked:true},
act:{checked:true}, act:{checked:true},
},
}
),
// //
updateZdxgjl(data){
updateZdxgjl:(data)=>{
this.zdxgjl.unshift(data); this.zdxgjl.unshift(data);
}, },
// //
updateFhyjjl(data){
updateFhyjjl:(data)=>{
this.fhyjjl.unshift(data); this.fhyjjl.unshift(data);
}, },
// //
replaceFhyjjl(data){
replaceFhyjjl:(data)=>{
this.fhyjjl = data; this.fhyjjl = data;
}, },
// //
updateFieldCheckObj(data){
updateFieldCheckObj:(data)=>{
this.fieldCheckObj = {...this.fieldCheckObj, ...data}; this.fieldCheckObj = {...this.fieldCheckObj, ...data};
}, },
@ -107,6 +126,9 @@ export default {
data() { data() {
return { return {
info: {}, info: {},
zdxgjl: [],
fhyjjl: [],
fieldCheckObj: {},
}; };
}, },
mounted() { mounted() {

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

@ -254,12 +254,18 @@ export default {
}; };
}, },
mounted() { mounted() {
if(this.fillType === "actFill"){
this.getCode();
}
}, },
watch: {
formData: {
immediate: true,
handler(v) {
if(!v.targetCodeSn && this.fillType === "actFill"){
this.getCode();
}
}
}
},
methods: { methods: {
// //
async getCode(){ async getCode(){

Loading…
Cancel
Save