华西海圻ELN前端工程
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

523 lines
22 KiB

import _ from "lodash";
import { getuuid, isEqual, isValueEmpty } from "@/utils/index.js";
import { isShowOtherByCheckboxTree } from "@/utils/formPackageCommon.js";
export default {
inject: ["getZdxgjl", "updateZdxgjl"],
watch: {
formData: {
immediate: true,
deep: true, // 深度监听,以便检测嵌套对象变化
handler(v) {
if (v) {
this.handleFormField(true);
}
}
},
fieldItemLabel: {
immediate: true,
deep: true, // 深度监听,以便检测嵌套对象变化
handler(v) {
if (v) {
console.log(v, "fieldItemLabel")
}
}
},
formConfig: {
immediate: true,
deep: true, // 深度监听,以便检测嵌套对象变化
handler(v) {
this.handleFormField();
}
}
},
data() {
return {
uuid: getuuid(),
oldFormFields: {},
clickableKey: "",
}
},
mounted() {
this.handleFormField();
},
unmounted() {
this.formFields = {};//清空当前填写的数据
},
methods: {
onSelectChange(key, val, type) {
// 获取对应的配置
const currentConfig = this.allFieldsConfig[key];
if (currentConfig?.selectTo) {
this.formFields[currentConfig?.selectTo] = val;
}
this.onValueChangeCompareTo(key, val);
this.formFields[key] = val;
this.$emit("select", { key, value: val, type, ...this.formFields });
// 清除该表单项的错误状态
if (this.errors[key]) {
this.$set(this.errors, key, false);
}
},
//试剂/仪器等弹窗提交
onRegentSubmit(data, inputValue, key, item) {
this.updateFormData(key, inputValue);
this.$emit("onRegentSubmit", { selectInfo: data, inputValue, key, config: item });
},
getRegentItem(item, fieldCode = "type") {
const type = item[fieldCode];
console.log(item, "type")
return {
label: "",
type,
fillType: item.subFillType || item.fillType,
parentLabel: item.label,
filledCodes: item.filledCodes,
qxbdType: item.qxbdType,
checkType: item.checkType,
regentFillType: item.regentFillType,
}
},
handleClickButton(key) {
this.$emit("clickButton", key)
},
getFillType(type) {
const typeObj = {
actFill: "orange-border",//实际填写的边框颜色
green: "green-border",
preFill: "blue-border",//预填写的边框颜色
}
return typeObj[type] || ""
},
onInputNumberChange(key, val) {
this.formFields[key] = val;
// 清除该表单项的错误状态
if (this.errors[key]) {
this.$set(this.errors, key, false);
}
},
//批量更新表单数据
batchUpdateFormData(data) {
const cloneFormFields = JSON.parse(JSON.stringify(this.formFields));
Object.keys(data).forEach(key => {
this.oldFormFields[key] = cloneFormFields[key];
this.formFields[key] = data[key];
// 清除该表单项的错误状态
if (this.errors[key]) {
this.$set(this.errors, key, false);
}
})
},
//更新表单数据
updateFormData(key, value, data) {
const { isUpdateRecord, signData } = data || {};
// 深拷贝当前表单数据,避免直接修改原数据
const cloneFormFields = JSON.parse(JSON.stringify(this.formFields));
this.oldFormFields[key] = cloneFormFields[key];
this.formFields[key] = value;
// 清除该表单项的错误状态
if (this.errors[key]) {
this.$set(this.errors, key, false);
}
if (isUpdateRecord) {
setTimeout(() => {
this.$refs[key][0].handleUpdateRecord(signData, { oldValue: this.oldFormFields[key], inputValue: value });
}, 10);
}
},
handleClickable(sItem, key) {
if (this.templateFillType !== 'actFill') {
return
}
this.clickableKey = key;
this.$emit("clickable", sItem)
},
//根据span判断一行显示几列
getSpanClass(sItem) {
const spanArr = ["full-row", "", "three-row"]
if (sItem.span) {
return spanArr[sItem.span - 1]
}
return ""
},
//获取其他下拉框的配置
getOtherItem(sItem) {
return {
label: sItem.otherLabel ? this.$t(sItem.otherLabel) : this.$t("template.common.other"),
fillType: sItem.fillType,
maxlength: sItem.otherMaxlength || 50,
parentLabel: sItem.label,
}
},
getRadioOtherItem(sItem) {
return {
// label: sItem.otherLabel ? this.$t(sItem.otherLabel) : this.$t("template.common.other"),
fillType: sItem.fillType,
maxlength: sItem.otherMaxlength || 50,
parentLabel: sItem.label,
}
},
getClickableItem(sItem) {
return {
label: "",
type: "clickable",
fillType: sItem.subFillType || sItem.fillType,
parentLabel: sItem.label,
}
},
getSubItem(sItem) {
const config = {
label: "",
options: sItem.subOptions || [],
fillType: sItem.subFillType || sItem.fillType,
parentLabel: sItem.label,
}
if (sItem.subDisabled) {
config.disabled = sItem.subDisabled;
}
return config;
},
// 根据formConfig回填form表单数据
handleFormField(update = false) {
const result = {};
let config = {};
const { formConfig, formData, formFields } = this;
// 遍历配置
formConfig.forEach((item) => {
if (item.config) {
// 合并配置项
config = { ...config, ...item.config }
// 处理每个配置项
Object.keys(item.config).forEach(key => {
const currentConfig = item.config[key];
let value = formData[key];
// 如果formFields中已经有值,保持原值(用户输入或之前设置的值)
if (formFields[key] !== null &&
formFields[key] !== undefined &&
formFields[key] !== ''
// typeof formFields[key] !== 'object'
) {
// 保留原值,不使用formData中的值
result[key] = formFields[key];
} else {
// 使用formData中的值
result[key] = value;
}
// 处理特殊字段 - "其他"字段
if (currentConfig.otherCode) {
const { otherCode, type } = currentConfig;
//如果是更新的话,优先使用formFields中的值
if (update) {
result[otherCode] = formFields[otherCode] || formData[otherCode] || '';
} else {
result[otherCode] = formData[otherCode] || formFields[otherCode] || '';
}
config[otherCode] = { label: "template.common.other", parentType: type, parentKey: key, type: "input", fillType: currentConfig.fillType }
}
if (currentConfig.subKey) {
const { subKey } = currentConfig;
if (update) {
result[subKey] = formFields[subKey] || formData[subKey] || '';
} else {
result[subKey] = formData[subKey] || formFields[subKey] || '';
}
config[subKey] = { label: currentConfig.label, subKey, type: currentConfig.subType, fillType: currentConfig.subFillType || currentConfig.fillType, selectTo: currentConfig.selectTo }
}
// 检查compareTo字段
if (currentConfig.compareTo && formData[currentConfig.compareTo] && result[key]) {
const compareToValue = formData[currentConfig.compareTo];
const currentValue = result[key];
this.compareFieldsIsEqual(currentValue, compareToValue, key)
}
// 检查compareTo字段
if (currentConfig.subCompareTo && formData[currentConfig.subCompareTo] && result[currentConfig.subKey]) {
const compareToValue = formData[currentConfig.subCompareTo];
const currentValue = result[currentConfig.subKey];
this.compareFieldsIsEqual(currentValue, compareToValue, currentConfig.subKey)
}
});
// 处理可能存在的直接otherCode字段
if (item.config?.otherCode) {
config[item.config?.otherCode] = item.config?.otherCode;
}
}
});
// 处理selectInfo_开头的字段,步骤表单需要保留selectInfo_开头的字段
const selectInfoKeys = Object.keys(formData).filter(key => key.startsWith("selectInfo_"));
selectInfoKeys.forEach(key => {
result[key] = formData[key];
})
// 更新表单字段
this.formFields = result;
this.allFieldsConfig = config;
},
//比较值是否相等
compareFieldsIsEqual(currentValue, compareToValue, key) {
if (!currentValue || !compareToValue) return;
// 如果当前值与compareTo字段的值不相等,则设置橙色背景
if (isEqual(currentValue, compareToValue)) {
// 如果相等,移除橙色背景(如果之前设置了的话)
this.$set(this.orangeBgFields, key, false);
} else {
this.$set(this.orangeBgFields, key, true);
}
},
//判断是否禁用
getDisabled() {
const { item } = this;
const { fillType } = item;
if (item.hasOwnProperty("disabled")) {
return item.disabled
} else {
if (fillType === "actFill") {//当模板状态是实际填写时,只有当fillType是actFill时才能填写
return this.templateFillType !== "actFill"
} else if (fillType === "preFill") {//当模板状态是预填写时,只有当fillType是preFill才能填写
return this.templateFillType !== "preFill"
} else {
return true
}
}
},
// 表单数据校验
validateFormData() {
const { formFields, allFieldsConfig } = this;
const errors = [];
// 清空之前的错误状态
this.errors = {};
for (const key in allFieldsConfig) {
const o = allFieldsConfig[key];
if (o.otherCode) {//
if (o.type === "select") {
const isSelectedOther = this.isShowOther(formFields[key],o);
if (!isSelectedOther) {//如果其他选项没有被选择,清空其他字段
formFields[o.otherCode] = "";
}
} else if (o.subType === "select") {
const isSelectedOther = this.isShowOther(formFields[o.subKey],o);
if (!isSelectedOther) {//如果其他选项没有被选择,清空其他字段
formFields[o.otherCode] = "";
}
} else if (o.type === "radioAndOther") {
const isSelectedOther = this.isShowOtherByRadioAndOther(formFields[key],o);
if (!isSelectedOther) {//如果其他选项没有被选择,清空其他字段
formFields[o.otherCode] = "";
}
}
}
if (o.type === "attachment"&&o.fillType === this.templateFillType) {
const attValue = formFields[key];
if (!attValue || attValue == "[]") {
errors.push({
field: key,
label: o.label,
error: "请上传附件"
});
this.$set(this.errors, key, true);
}
} else if (o.type === "fqyq" &&o.fillType === this.templateFillType) {
const fqyqValue = formFields[key] || {};
const {mainRadio, subRadio,inputValue} = fqyqValue;
if (!mainRadio) {
errors.push({
field: key,
label: o.label,
error: "请选择是否在规定时间完成"
});
this.$set(this.errors, key, true);
} else {
if (mainRadio==="是") {
if (!subRadio) {
errors.push({
field: key,
label: o.label,
error: "请选择是否在规定时间完成"
});
this.$set(this.errors, key, true);
}else if(!inputValue){
errors.push({
field: key,
label: o.label,
error: "请输入信息"
});
this.$set(this.errors, key, true);
}
}
}
continue
}else if(o.type === "checkboxTree"&&o.fillType === this.templateFillType){
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]);
if (!isChecked || !isHasOtherInfo) {
errors.push({
field: key,
label: o.label,
error: "请选择方法学验证"
});
this.$set(this.errors, key, true);
}
continue
}else if(o.type === "radioAndOther"&&o.fillType === this.templateFillType){
const radioValue = formFields[key] || {};
const {otherCode} = o;
const otherValue = formFields[otherCode] || "";
const isShow = this.isShowOtherByRadioAndOther(radioValue,o)
if(isShow&&!otherValue){
errors.push({
field: key,
label: o.label,
error: "请输入信息"
});
this.$set(this.errors, key, true);
}
// if (!radioValue) {
// errors.push({
// field: key,
// label: o.label,
// error: "请选择方法学验证"
// });
// this.$set(this.errors, key, true);
// }
continue
}
if (isValueEmpty(formFields[key])) {
// 其他字段需要判断是否显示再校验
if (o.label === "template.common.other" && !this.isShowOther(formFields[o.parentKey])) {
continue
}
//span的字段不校验
if (o.type === "span" || o.type === "text" || o.type === "button") {
continue
}
if (o.fillType === this.templateFillType && !o.disabled) {
let prefix = "";
if (o.type === "input" || o.type === "inputNumber" || o.type === "textarea") {
prefix = "填写";
} else {
prefix = "选择";
}
const errorItem = {
field: key,
label: o.label,
error: `${prefix}${o.label}`
};
errors.push(errorItem);
this.$set(this.errors, key, true);
}
}
}
console.log(errors, "errors")
return {
valid: errors.length === 0,
errors: errors
};
},
getFormData() {
// 同时执行数据校验和子组件校验
const validateResult = this.validateFormData();
const subComponentValidateResult = this.validateSubComponents();
// const subComponentValidateResult = {valid: true, error: ''};
return new Promise((resolve, reject) => {
if (validateResult.valid && subComponentValidateResult.valid) {
resolve(this.formFields);
} else if (!validateResult.valid) {
// this.$message.error("表单内容未填完,请填写后再提交");
reject(validateResult.errors[0].error);
} else {
reject(subComponentValidateResult.error);
}
});
},
// 子组件校验钩子方法,子组件可以重写此方法来添加额外的校验逻辑
validateSubComponents() {
return {
valid: true,
error: ''
};
},
//直接获取表单数据,不做校验
getFilledFormData() {
return this.formFields;
},
getFormDataByKey(key) {
return this.formFields[key];
},
onBlur(key, val) {
// compareTo 功能:当fillType==="actFill"时,判断当前值是否与compareTo字段的值一样,如果不一样则将当前input框的背景色标记成橙色
this.onValueChangeCompareTo(key, val);
if (this.errors[key]) {
this.$set(this.errors, key, false);
}
this.$emit("blur", { key, value: val, ...this.formFields });
},
onValueChangeCompareTo(key, val, compKey) {
// compareTo 功能:当fillType==="actFill"时,判断当前值是否与compareTo字段的值一样,如果不一样则将当前input框的背景色标记成橙色
const currentFieldConfig = this.allFieldsConfig[key];
if (currentFieldConfig && currentFieldConfig.fillType === "actFill" && (currentFieldConfig.compareTo || compKey)) {
const compareToKey = compKey || currentFieldConfig.compareTo;
const compareToValue = this.formFields[compareToKey];
this.compareFieldsIsEqual(val, compareToValue, key);
}
},
onAttachmentChange(key, val) {
this.formFields[key] = val;
// 清除该表单项的错误状态
if (this.errors[key]) {
this.$set(this.errors, key, false);
}
// 如果是checkboxList类型,需要处理otherValues
if (val && typeof val === 'object' && val.otherValues) {
// 将otherValues中的每个值也保存到formFields中
Object.keys(val.otherValues).forEach(otherCode => {
this.formFields[otherCode] = val.otherValues[otherCode];
});
}
},
//复制
onCopy(config, key) {
const { formFields } = this;
if (config.copyFrom) {
formFields[key] = formFields[config.copyFrom];
this.onBlur(key, formFields[key]);
}
},
resetRecord(key) {
this.formFields = { ...this.formFields, ...this.oldFormFields };
this.oldFormFields = {};
},
}
}