From f4d6a613ce7483a6847966b3c9385b4518939b72 Mon Sep 17 00:00:00 2001
From: luojie <125330818@qq.com>
Date: Wed, 4 Mar 2026 16:48:23 +0800
Subject: [PATCH] =?UTF-8?q?feat:[=E6=A8=A1=E6=9D=BF=E7=AE=A1=E7=90=86][sp0?=
=?UTF-8?q?020]?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/components/Template/BaseInfoFormPackage.vue | 20 +-
src/components/Template/HandleFormItem.vue | 203 ++++++++-------------
.../Template/mixins/formPackageMixins.js | 46 +++--
src/utils/formPackageCommon.js | 2 +-
src/utils/index.js | 2 +-
.../business/comps/template/comps/sp/SP0020.vue | 27 ++-
.../comps/template/formConfig/sp/SP0020.js | 75 ++++++++
7 files changed, 220 insertions(+), 155 deletions(-)
diff --git a/src/components/Template/BaseInfoFormPackage.vue b/src/components/Template/BaseInfoFormPackage.vue
index cb4705b..e212fcf 100644
--- a/src/components/Template/BaseInfoFormPackage.vue
+++ b/src/components/Template/BaseInfoFormPackage.vue
@@ -78,9 +78,9 @@
{{ $t(sItem.label) }}
-
+
@@ -303,15 +303,23 @@
{{ $t(item.label) }}
-
{{ $t(sItem.label) }}
+
{{ $t(sItem.label) }}
onAttachmentChange(key, e)"
:error="errors[key]" @update:error="errors[key] = false"
:orange-bg="orangeBgFields[key]" />
+
+
@@ -571,4 +579,8 @@ export default {
border-radius: 4px;
border: 1px solid #ff5d5d;
}
+.checkboxList-title{
+ width: 120px;
+ text-align: center;
+}
\ No newline at end of file
diff --git a/src/components/Template/HandleFormItem.vue b/src/components/Template/HandleFormItem.vue
index 2aeee30..e4471c4 100644
--- a/src/components/Template/HandleFormItem.vue
+++ b/src/components/Template/HandleFormItem.vue
@@ -33,25 +33,10 @@
{{ option.label }}
-
-
-
-
- {{ option.label }}
-
-
-
-
-
-
-
-
+ :class="getFillTypeStyle() + (orangeBg ? ' orange-bg' : '') + (error ? ' form-error-border' : '')">
+
-
+
-
onDateChange(val, 'yyyy/MM/DD HH:mm:ss')">
-
-
onDateChange(val, 'yyyy/MM/DD')">
+ :picker-options="pickerOptions" :disabled="getDisabled()"
+ :format="type === 'dateTime' ? 'yyyy/MM/dd HH:mm:ss' : 'yyyy/MM/dd'" :placeholder="getPlaceholder()"
+ @change="(val) => onDateChange(val, type === 'dateTime' ? 'yyyy/MM/DD HH:mm:ss' : 'yyyy/MM/DD')">
@@ -229,7 +213,7 @@ import Question from "./icons/Question.vue";
import DecimalInput from "./DecimalInput.vue";
import { EventBus } from "@/utils/eventBus";
import moment from "moment";
-import { getuuid,isEqual ,deepClone,getDefaultValueByOptions,isValueEmpty} from "@/utils/index.js";
+import { getuuid, isEqual, deepClone, getDefaultValueByOptions, isValueEmpty } from "@/utils/index.js";
import { getToken } from "@/utils/auth";
import { isShowOtherByCheckboxTree } from "@/utils/formPackageCommon";
@@ -293,13 +277,7 @@ export default {
console.log(this.value, "check value");
let initialOtherValues = {}, checkboxTagList = [];
- if (this.type === 'checkboxList' && !this.value) {
- initialValue = {
- checkboxValues: [],
- otherValues: {}
- };
-
- } else if (this.type === 'checkboxTag' && Array.isArray(this.value)) {
+ if (this.type === 'checkboxTag' && Array.isArray(this.value)) {
// checkboxTag类型,value是数组格式
checkboxTagList = this.value.map(tag => ({
checked: tag.checked,
@@ -327,8 +305,6 @@ export default {
oldCheckboxTagList: JSON.parse(JSON.stringify(checkboxTagList)), // 记录上一次的checkboxTagList
fqyqValue: initialValue, // fqyq类型的值
oldFqyqValue: { ...initialValue }, // 记录上一次的fqyq值
- checkboxListValue: initialValue, // checkboxList类型的值
- oldCheckboxListValue: JSON.parse(JSON.stringify(initialValue)), // 记录上一次的checkboxList值
uuid: getuuid(), // 唯一标识符,用于EventBus事件匹配
regentType: ['sj', 'gsp', 'mix', 'xj', 'xb', 'gyzj', 'mjy', 'yq', 'jcb', 'qxbd'], //试剂/仪器/供试品等类型
selectRegentInfo: {},//选择的试剂/仪器/供试品等信息
@@ -343,17 +319,26 @@ export default {
currentHandleType: '',//当前操作的类型
currentOtherCode: '',//当前操作的otherCode
currentCheckboxTreeValue: '',//当前操作的checkboxTree值
- isShowOtherByCheckboxTree
-
+ isShowOtherByCheckboxTree,
+ pickerOptions: {
+ disabledDate(time) {
+ return time.getTime() > Date.now();
+ },
+ shortcuts: [{
+ text: '今天',
+ onClick(picker) {
+ picker.$emit('pick', new Date());
+ }
+ }]
+ }
+
}
},
watch: {
value(newVal) {
console.log(newVal, "newVal")
- if (this.type === 'checkboxList' && newVal && typeof newVal === 'object') {
- this.checkboxListValue = JSON.parse(JSON.stringify(newVal));
- } else if (this.type === 'checkboxTag' && Array.isArray(newVal)) {
+ if (this.type === 'checkboxTag' && Array.isArray(newVal)) {
// checkboxTag类型,value是数组格式
this.checkboxTagList = newVal.map(tag => ({
checked: tag.checked,
@@ -864,20 +849,6 @@ export default {
this.emitCheckboxTagValue();
this.onCommonHandleSaveRecord();
},
- // 检查是否显示显示checkboxList的其他输入框
- isShowCheckboxListOther(option) {
- const { checkboxValues } = this.checkboxListValue
- if (!checkboxValues) {
- return false;
- }
- return option.otherCode && checkboxValues.includes(option.value);
- },
- // checkboxList的checkbox变化处理
- onCheckboxListChange(val) {
- this.currentHandleType = 'checkboxListValue';
- this.checkboxListValue.checkboxValues = val;
- this.onCommonHandleSaveRecord();
- },
// tag输入框失去焦点
onTagBlur(tagIndex) {
@@ -918,13 +889,6 @@ export default {
onBlur(e) {
this.onCommonHandleSaveRecord(e.target.value);
},
- // checkboxList的其他输入框失去焦点处理
- onCheckboxListOtherBlur(e, otherCode) {
- this.currentHandleType = "checkboxListOther";
- this.currentOtherCode = otherCode;
- this.checkboxListValue.otherValues[otherCode] = e.target.value;
- this.onCommonHandleSaveRecord(e.target.value);
- },
// 检查checkboxTree的某个值是否被选中
isCheckboxTreeChecked(value) {
@@ -964,11 +928,11 @@ export default {
onCheckboxTreeParentChange(group, checked) {
this.currentHandleType = 'checkboxTreeCheckbox';
this.currentCheckboxTreeValue = group.value;
-
+
// 设置父级状态
const parentItem = this.getOrCreateCheckedItem(group.value);
parentItem.checked = checked;
-
+
// 同步所有子级状态
if (group.children && group.children.length > 0) {
group.children.forEach(child => {
@@ -980,7 +944,7 @@ export default {
}
});
}
-
+
this.onCommonHandleSaveRecord();
},
@@ -988,40 +952,40 @@ export default {
onCheckboxTreeChildChange(group, childValue, checked) {
this.currentHandleType = 'checkboxTreeCheckbox';
this.currentCheckboxTreeValue = childValue;
-
+
// 设置子级状态
const childItem = this.getOrCreateCheckedItem(childValue);
childItem.checked = checked;
-
+
// 如果取消选中,清除otherValues
if (!checked) {
delete this.inputValue.otherValues[childValue];
}
-
+
// 更新父级状态
this.updateParentState(group);
-
+
this.onCommonHandleSaveRecord();
},
// 更新父级状态(根据子级状态)
updateParentState(group) {
if (!group.children || group.children.length === 0) return;
-
+
const parentItem = this.getOrCreateCheckedItem(group.value);
const childValues = group.children.map(child => child.value);
-
+
// 统计子级选中状态
let checkedCount = 0;
let totalCount = childValues.length;
-
+
childValues.forEach(childValue => {
const childItem = this.inputValue.checkedValues.find(item => item.label === childValue);
if (childItem && childItem.checked) {
checkedCount++;
}
});
-
+
// 根据子级状态设置父级状态
if (checkedCount === 0) {
// 全部未选中,父级取消选中
@@ -1038,23 +1002,23 @@ export default {
if (!this.inputValue || !this.inputValue.checkedValues) {
return false;
}
-
+
// 找到对应的group
const group = this.item.options.find(opt => opt.value === groupValue);
if (!group || !group.children || group.children.length === 0) {
return false;
}
-
+
const childValues = group.children.map(child => child.value);
let checkedCount = 0;
-
+
childValues.forEach(childValue => {
const childItem = this.inputValue.checkedValues.find(item => item.label === childValue);
if (childItem && childItem.checked) {
checkedCount++;
}
});
-
+
// 半选状态:有子级被选中但不是全部
return checkedCount > 0 && checkedCount < childValues.length;
},
@@ -1095,15 +1059,6 @@ export default {
this.visible = true;
}
},
- getCheckboxListInfo() {
- const { otherValues, checkboxValues } = this.checkboxListValue;
- const { otherValues: oldOtherValues, checkboxValues: oldCheckboxValues } = this.oldCheckboxListValue;
- const o = {
- "checkboxListValue": { oldValue: oldCheckboxValues, newValue: checkboxValues, des: "" },
- "checkboxListOther": { oldValue: oldOtherValues[this.currentOtherCode], newValue: otherValues[this.currentOtherCode], des: "样品信息:" },
- }
- return o[this.currentHandleType];
- },
getFqyqInfo() {
const { mainRadio, inputValue, subRadio } = this.fqyqValue;
const { mainRadio: oldMainRadio, inputValue: oldInputValue, subRadio: oldSubRadio } = this.oldFqyqValue;
@@ -1172,17 +1127,12 @@ export default {
// 值发生了变化,需要弹出密码输入框
let isSame = true, isOldValueEmpty = true;
const { currentHandleType } = this;
- // 如果是checkboxList类型,需要同时比较otherValues
- if (this.type === 'checkboxList') {
- const current = this.getCheckboxListInfo();
- isSame = isEqual(current.oldValue, current.newValue);
- isOldValueEmpty = isValueEmpty(current.oldValue);
- } else if (this.type === "checkboxTag") {
+ if (this.type === "checkboxTag") {
// checkboxTag类型,只比较当前tagIndex的数据
const currentTag = this.checkboxTagList[this.currentTagIndex];
const oldTag = this.oldCheckboxTagList[this.currentTagIndex] || {};
isSame = isEqual(oldTag.checked, currentTag.checked);
- isOldValueEmpty = oldTag.checked===undefined;
+ isOldValueEmpty = oldTag.checked === undefined;
} else if (this.type === "fqyq") {
const current = this.getFqyqInfo();
isSame = isEqual(current.oldValue, current.newValue);
@@ -1192,7 +1142,7 @@ export default {
const { oldValue, newValue } = current;
if (currentHandleType === "checkboxTreeCheckbox") {
isSame = isEqual(oldValue.checked, newValue.checked);
- isOldValueEmpty = oldValue.checked===undefined;
+ isOldValueEmpty = oldValue.checked === undefined;
} else {
isSame = isEqual(current.oldValue, current.newValue);
isOldValueEmpty = isValueEmpty(current.oldValue);
@@ -1219,12 +1169,7 @@ export default {
resetRecord() {
// 用户点击取消,还原数据
let oldValue = this.oldValue;
- if (this.type === 'checkboxList') {
- oldValue = {
- checkboxValues: this.oldCheckboxListValue.checkboxValues,
- otherValues: this.oldCheckboxListValue.otherValues
- };
- } else if (this.type === "checkboxTag") {
+ if (this.type === "checkboxTag") {
// checkboxTag类型,只回退当前tagIndex的数据
if (this.currentTagIndex >= 0 && this.currentTagIndex < this.oldCheckboxTagList.length) {
const oldTag = this.oldCheckboxTagList[this.currentTagIndex];
@@ -1269,11 +1214,6 @@ export default {
recordOldVlaue = `${current.des + current.oldValue}`;
recordValue = `${current.des + current.newValue}`;
isModify = !!this.oldFqyqValue.mainRadio
- } else if (this.type === "checkboxList") {
- const current = this.getCheckboxListInfo();
- recordOldVlaue = `${current.des + (current.oldValue || '')}`;
- recordValue = `${current.des + (current.newValue || '')}`;
- isModify = !!current.oldValue;
} else if (this.type === "checkboxTree") {
// checkboxTree类型,记录当前操作的值变化
const current = this.getCheckboxTreeInfo();
@@ -1283,7 +1223,7 @@ export default {
recordValue = `${newValue.label || ''}:${newValue.checked ? '勾选' : '未勾选'}`;
isModify = newValue.checked !== undefined;
} else {
- recordOldVlaue = `${current.des +( current.oldValue || '')}`;
+ recordOldVlaue = `${current.des + (current.oldValue || '')}`;
recordValue = `${current.des + (current.newValue || '')}`;
isModify = !!current.oldValue;
}
@@ -1306,9 +1246,7 @@ export default {
}
// 更新oldValue和oldOtherValues
- if (this.type === 'checkboxList') {
- this.oldCheckboxListValue = JSON.parse(JSON.stringify(this.checkboxListValue));
- } else if (this.type === "checkboxTag") {
+ if (this.type === "checkboxTag") {
// checkboxTag类型,只更新当前tagIndex的数据
if (this.currentTagIndex >= 0 && this.currentTagIndex < this.checkboxTagList.length) {
this.oldCheckboxTagList[this.currentTagIndex] = { ...this.checkboxTagList[this.currentTagIndex] };
@@ -1321,12 +1259,7 @@ export default {
this.oldFqyqValue = JSON.parse(JSON.stringify(this.fqyqValue));
}
let value = this.inputValue;
- if (this.type === 'checkboxList') {
- value = {
- checkboxValues: this.checkboxListValue.checkboxValues,
- otherValues: this.checkboxListValue.otherValues
- };
- } else if (this.type === "checkboxTag") {
+ if (this.type === "checkboxTag") {
value = [...this.checkboxTagList];
} else if (this.type === "fqyq") {
value = { ...this.fqyqValue };
@@ -1380,14 +1313,6 @@ export default {
}
return commonInfo;
},
- // 判断checkboxList中特定otherCode输入框是否有错误
- isOtherInputError(otherCode) {
- if (!this.error) {
- return false;
- }
- // 检查该otherCode对应的输入框是否为空
- return isValueEmpty(this.otherValues[otherCode]);
- },
handleClickable(item, event) {
if (this.templateFillType !== 'actFill') {
return
@@ -1443,7 +1368,7 @@ export default {
return this.$t("template.common.pleaseSelect")
}
let prex = "template.common.pleaseFillIn"
- if (type === "select" || type === "dateTime") {
+ if (type === "select" || type === "dateTime" || type === "datePicker") {
prex = "template.common.pleaseSelect"
}
return placeholder ? this.$t(placeholder) : (this.$t(prex) + this.$t(label))
@@ -1938,6 +1863,11 @@ export default {
}
}
+ .el-checkbox__input.is-indeterminate .el-checkbox__inner {
+ background-color: #f9c588;
+ border-color: #f9c588;
+ }
+
.el-radio {
&.is-checked {
.el-radio__label {
@@ -2038,12 +1968,25 @@ export default {
display: flex;
align-items: center;
}
-.checkbox-tree-input-container{
+
+.checkbox-tree-input-container {
margin-left: 10px;
width: 500px;
}
-.item-center{
+
+.item-center {
display: flex;
align-items: center;
}
+
+.checkbox-tree-group {
+ padding: 5px 0;
+}
+
+.form-error-border {
+ box-shadow: 0 0 6px #ffc3c3;
+ padding: 8px;
+ border-radius: 4px;
+ border: 1px solid #ff5d5d;
+}
\ No newline at end of file
diff --git a/src/components/Template/mixins/formPackageMixins.js b/src/components/Template/mixins/formPackageMixins.js
index 17b7357..d3e9bfe 100644
--- a/src/components/Template/mixins/formPackageMixins.js
+++ b/src/components/Template/mixins/formPackageMixins.js
@@ -1,7 +1,6 @@
import _ from "lodash";
-import { getuuid, isEqual } from "@/utils/index.js";
-import { EventBus } from "@/utils/eventBus";
-import moment from "moment";
+import { getuuid, isEqual, isValueEmpty } from "@/utils/index.js";
+import { isShowOtherByCheckboxTree } from "@/utils/formPackageCommon.js";
export default {
inject: ["getZdxgjl", "updateZdxgjl"],
watch: {
@@ -361,8 +360,34 @@ export default {
}
continue
+ }else if(o.type === "checkboxTree"){
+ const checkboxTreeValue = formFields[key] || {};
+ const {checkedValues=[],otherValues = {}} = checkboxTreeValue;;
+ const {options = []} = o;
+ //需要校验第一层是否有选中项
+ const parentOptions = options.map(item => item.label);
+ const isChecked = parentOptions.some(option => {
+ var found = checkedValues.find(item => item.label === option);
+ return found && found.checked === true;
+ });
+ //获取所有选中的选项
+ const allCheckedOptions = checkedValues.filter(item => item.checked).map(item => item.label);
+ //再筛选出需要显示其他输入框的选项
+ const otherOptions = allCheckedOptions.filter((label)=>isShowOtherByCheckboxTree(label))
+ const isHasOtherInfo = otherOptions.every(item => otherValues[item]);
+ console.log(otherOptions,allCheckedOptions,isHasOtherInfo,"otherOptions")
+ console.log(o,checkedValues,otherValues,options,isChecked,"checkboxTreeValue")
+ if (!isChecked || !isHasOtherInfo) {
+ errors.push({
+ field: key,
+ label: o.label,
+ error: "请选择方法学验证"
+ });
+ this.$set(this.errors, key, true);
+ }
+ continue
}
- if (this.isValueEmpty(formFields[key])) {
+ if (isValueEmpty(formFields[key])) {
// 其他字段需要判断是否显示再校验
if (o.label === "template.common.other" && !this.isShowOther(formFields[o.parentKey]) && o.parentType !== "radioAndOther") {
continue
@@ -399,19 +424,6 @@ export default {
errors: errors
};
},
- // 判断值是否为空
- isValueEmpty(value) {
- if (value === null || value === undefined || value === '') {
- return true;
- }
- if (typeof value === 'string' && value.trim() === '') {
- return true;
- }
- if (Array.isArray(value) && value.length === 0) {
- return true;
- }
- return false;
- },
getFormData() {
// 同时执行数据校验和子组件校验
const validateResult = this.validateFormData();
diff --git a/src/utils/formPackageCommon.js b/src/utils/formPackageCommon.js
index d33bb12..9fb003e 100644
--- a/src/utils/formPackageCommon.js
+++ b/src/utils/formPackageCommon.js
@@ -20,6 +20,6 @@ export const isShowOtherByRadioAndOther = (v = '', col) => {
//checkboxTree判断是否显示其他输入框
export const isShowOtherByCheckboxTree = (v = "")=>{
- const otherArr = ['其他', '样品信息', '样品']
+ const otherArr = ['其他', '样品信息', '样品','部分接受']
return otherArr.includes(v)
}
diff --git a/src/utils/index.js b/src/utils/index.js
index 017a517..c84cf5f 100644
--- a/src/utils/index.js
+++ b/src/utils/index.js
@@ -432,7 +432,7 @@ export function getuuid() {
// 判断值是否为空
export function isValueEmpty(value) {
- if (value === null || value === undefined || value === '') {
+ if (value === null || value === undefined || value === '' || value === false) {
return true
}
if (typeof value === 'string' && value.trim() === '') {
diff --git a/src/views/business/comps/template/comps/sp/SP0020.vue b/src/views/business/comps/template/comps/sp/SP0020.vue
index 55b0f15..93a4ab5 100644
--- a/src/views/business/comps/template/comps/sp/SP0020.vue
+++ b/src/views/business/comps/template/comps/sp/SP0020.vue
@@ -10,6 +10,12 @@
:ref="refConfig.baseInfoRef" :formConfig="baseInfoFormConfig" :formData="formData" />
+
+
+
@@ -29,12 +35,15 @@ import CustomTable from '@/components/Template/CustomTable.vue';
import TableOpertaionDelete from "@/components/Template/operation/TableOpertaionDelete.vue"
import { getBaseInfoFormConfig} from "../../formConfig/sp/SP0019";
-import { getSynrFormConfig} from "../../formConfig/sp/SP0020";
+import { getSynrFormConfig, getYqjgFormConfig, getCjrqFormConfig, getFxpsjwjFormConfig} from "../../formConfig/sp/SP0020";
const refConfig = {
baseInfoRef: "baseInfoRef",
remarkRef: "remarkRef",
synrRef: "synrRef",
+ yqjgRef: "yqjgRef",
+ cjrqRef: "cjrqRef",
+ fxpsjwjRef: "fxpsjwjRef",
}
const compRefs = Object.values(refConfig);
@@ -50,6 +59,19 @@ export default {
},
},
computed: {
+ //分析批数据文件
+ fxpsjwjFormConfig(){
+ return getFxpsjwjFormConfig(this);
+ },
+ //采集日期
+ cjrqFormConfig(){
+ return getCjrqFormConfig(this);
+ },
+ //仪器结果
+ yqjgFormConfig(){
+ return getYqjgFormConfig(this);
+ },
+ //试验内容
synrFormConfig(){
return getSynrFormConfig(this);
},
@@ -113,7 +135,8 @@ export default {
},
//保存
async onSave() {
-
+ const formData = await this.getFormData();
+ console.log(formData)
},
}
};
diff --git a/src/views/business/comps/template/formConfig/sp/SP0020.js b/src/views/business/comps/template/formConfig/sp/SP0020.js
index 21af9f2..cc4f90e 100644
--- a/src/views/business/comps/template/formConfig/sp/SP0020.js
+++ b/src/views/business/comps/template/formConfig/sp/SP0020.js
@@ -56,4 +56,79 @@ export const getSynrFormConfig = ()=>{
}
},
]
+}
+
+//仪器结果
+export const getYqjgFormConfig = ()=>{
+ return [
+ {
+ type: 'checkboxList',
+ config: {
+ jg: {
+ type: 'checkboxTree',
+ label: '结果',
+ options:[
+ { label: '分析批接受', value: '分析批接受' },
+ { label: '分析批拒绝', value: '分析批拒绝' },
+ { label: '部分接受', value: '部分接受' },
+ ],
+ span:1,
+ fillType:"actFill"
+ },
+ yzkcjg: {
+ type: 'textarea',
+ label: '验证考察结果',
+ span:1,
+ fillType:"actFill",
+ maxlength: 1000,
+ rows: 5
+ },
+ }
+ },
+ ]
+}
+//分析批数据文件
+export const getFxpsjwjFormConfig = ()=>{
+ return [
+ {
+ type: 'checkboxList',
+ config: {
+ fxpsjwjm: {
+ type: 'input',
+ label: '分析批数据文件名',
+ span:1,
+ fillType:"actFill",
+ maxlength: 100,
+ },
+ fxpsjlj: {
+ type: 'input',
+ label: '分析批数据路径',
+ span:1,
+ fillType:"actFill",
+ maxlength: 150,
+ },
+ }
+ },
+ ]
+}
+
+//采集日期
+export const getCjrqFormConfig = ()=>{
+ return [
+ {
+ type: 'cellItem',
+ config: {
+ cjksrq: {
+ type: 'datePicker',
+ label: '采集开始日期',
+ fillType:"actFill"
+ },
+ cjjsrq: {
+ type: 'datePicker',
+ label: '采集结束日期',
+ fillType:"actFill"
+ },
+ }
+ },
+ ]
}
\ No newline at end of file