From e68cc316aee505fa987da3803db63c991608abe6 Mon Sep 17 00:00:00 2001 From: luojie <125330818@qq.com> Date: Thu, 8 Jan 2026 22:32:41 +0800 Subject: [PATCH] =?UTF-8?q?feat:[=E6=A8=A1=E6=9D=BF=E7=AE=A1=E7=90=86][upd?= =?UTF-8?q?ate]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Template/BaseInfoFormPcakge.vue | 74 ++++-- src/components/Template/CustomTable.vue | 289 +++++++++++++-------- src/components/Template/HandleFormItem.vue | 28 +- .../business/comps/template/comps/gy/MJYLQSQD.vue | 24 +- .../business/comps/template/comps/gy/SYWZPZJHB.vue | 24 +- .../comps/template/comps/sp/SWYPBQGZYZBB.vue | 44 +--- .../comps/template/comps/sp/SWYPFXCBYPZB.vue | 17 +- .../comps/template/comps/sp/SWYPFXRYPZB.vue | 20 +- .../comps/template/comps/sp/SWYPNBGZYZBB.vue | 7 +- 9 files changed, 263 insertions(+), 264 deletions(-) diff --git a/src/components/Template/BaseInfoFormPcakge.vue b/src/components/Template/BaseInfoFormPcakge.vue index 8bff540..fbf19ae 100644 --- a/src/components/Template/BaseInfoFormPcakge.vue +++ b/src/components/Template/BaseInfoFormPcakge.vue @@ -210,7 +210,7 @@ export default { }) }, handleClickable(sItem,event){ - if(this.fillType !== 'actFill'){ + if(this.$store.state.template.templateStatus !== 'actFill'){ return } this.$emit("clickable",sItem) @@ -320,19 +320,17 @@ export default { } } }, - validateFormData(){ - - }, - getFormData() { + // 表单数据校验 + validateFormData() { const { formFields, allFieldsConfig } = this; const { templateStatus } = this.$store.state.template; + const errors = []; - // 重置错误状态 + // 清空之前的错误状态 this.errors = {}; - const errors = {}; - let firstError = null; + for (const key in allFieldsConfig) { - if (!formFields[key]) { + if (this.isValueEmpty(formFields[key])) { const o = allFieldsConfig[key]; // 其他字段需要判断是否显示再校验 if (o.label === "其他" && !this.isShowOther(formFields[o.parentKey])) { @@ -343,32 +341,52 @@ export default { continue } if (o.fillType == templateStatus && !o.disabled) { - // 标记为错误状态 - errors[key] = true; - - if (!firstError) { - let prefix = ""; - if (o.type === "input" || o.type === "inputNumber" || o.type === "textarea") { - prefix = "填写"; - } else { - prefix = "选择"; - } - firstError = { label: o.label, prefix }; + 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); } } } - // 设置错误状态 - this.errors = errors; - + return { + valid: errors.length === 0, + 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(); return new Promise((resolve, reject) => { - if (Object.keys(errors).length > 0) { - // 显示第一个错误的提示信息 - // this.$message.error(`表单内容未填完,请填写后再提交`); - reject(`${firstError.label}还未${firstError.prefix}`); + if (validateResult.valid) { + resolve(this.formFields); } else { - resolve(formFields); + // this.$message.error("表单内容未填完,请填写后再提交"); + reject(validateResult.errors[0].error); } }); }, diff --git a/src/components/Template/CustomTable.vue b/src/components/Template/CustomTable.vue index 237677e..18a1ecf 100644 --- a/src/components/Template/CustomTable.vue +++ b/src/components/Template/CustomTable.vue @@ -1,71 +1,96 @@ @@ -81,6 +106,10 @@ export default { // 是否显示表头选择器 showHeaderSelect: { type: Boolean, + default: false, + }, + showAddRow: { + type: Boolean, default: true, }, // 是否显示操作栏 @@ -99,7 +128,7 @@ export default { }, formData: { type: Object, - default:()=>{ + default: () => { return { stepTableFormData: [], headerSelectFields: {} @@ -115,27 +144,34 @@ export default { } }, watch: { - formData:{ + formData: { immediate: true, handler(newData) { - console.log(newData,"newData") - const {stepTableFormData = [], headerSelectFields = {}} = newData; + console.log(newData, "newData") + const { stepTableFormData = [], headerSelectFields = {} } = newData; this.updateDataSource(stepTableFormData); this.headerSelectFields = JSON.parse(JSON.stringify(headerSelectFields)) } }, }, mounted() { - this.initHeaderSelectValues(); + // 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'; + }, // 复制值 - onCopy(rowIndex, col){ - - if(col.copyFrom){ - if(!this.localDataSource[rowIndex][col.copyFrom]){//没有值就不用复制了 - return - } + onCopy(rowIndex, col) { + + if (col.copyFrom) { + if (!this.localDataSource[rowIndex][col.copyFrom]) {//没有值就不用复制了 + return + } this.$set(this.localDataSource[rowIndex], col.prop, this.localDataSource[rowIndex][col.copyFrom]) } }, @@ -143,7 +179,7 @@ export default { initHeaderSelectValues() { const headerSelectObj = {}; this.columns.map(col => { - if(col.headerSelectKey){ + if (col.headerSelectKey) { headerSelectObj[col.headerSelectKey] = col.defaultValue || col.headerOptions[0].value || "" } }); @@ -152,17 +188,17 @@ export default { // 获取最新数据 getFormData() { // 合并表头选择器值到 columns - - + + // 数据校验 const validateResult = this.validateFormData(); - return new Promise((resolve,reject)=>{ - if(validateResult.valid){ + return new Promise((resolve, reject) => { + if (validateResult.valid) { resolve({ stepTableFormData: [...this.localDataSource], headerSelectFields: this.headerSelectFields, }) - }else{ + } else { // this.$message.error("表单内容未填完,请填写后再提交"); reject(validateResult.errors[0].error) } @@ -173,10 +209,28 @@ export default { validateFormData() { const templateStatus = this.$store.state.template.templateStatus; const errors = []; - + // 清空之前的错误状态 this.formErrors = []; - + + // 校验表头的 HandleFormItem + this.columns.forEach((col, colIndex) => { + if (col.headerSelectKey && col.headerOptions && col.fillType === templateStatus) { + const headerValue = this.headerSelectFields[col.headerSelectKey]; + if (this.isValueEmpty(headerValue)) { + const errorItem = { + rowIndex: -1, // 表头特殊标记 + colIndex, + field: col.headerSelectKey, + label: col.label, + error: `请选择${col.label}` + }; + errors.push(errorItem); + this.formErrors.push(errorItem); + } + } + }); + // 遍历数据行 this.localDataSource.forEach((row, rowIndex) => { // 遍历列 @@ -196,11 +250,11 @@ export default { errors.push(errorItem); this.formErrors.push(errorItem); } - + // 检查子字段(如果有) - if (col.bodySubKey&& !col.bodySubDisabled) { + if (col.bodySubKey && !col.bodySubDisabled) { const subValue = row[col.bodySubKey]; - console.log(col,subValue,"subValue") + console.log(col, subValue, "subValue") if (this.isValueEmpty(subValue)) { const errorItem = { rowIndex, @@ -216,7 +270,7 @@ export default { } }); }); - + return { valid: errors.length === 0, errors: errors @@ -238,15 +292,20 @@ export default { // 表头选择器变化 onHeaderSelectChange(col, value) { this.headerSelectFields[col.headerSelectKey] = value; + // 输入时清除对应表单项的错误状态 + this.formErrors = this.formErrors.filter(error => + !(error.rowIndex === -1 && + error.field === col.headerSelectKey) + ); }, // 表体值变化 onBodyValueChange(rowIndex, colIndex, value) { const col = this.columns[colIndex]; this.localDataSource[rowIndex][col.prop] = value; // 输入时清除对应表单项的错误状态 - this.formErrors = this.formErrors.filter(error => - !(error.rowIndex === rowIndex && - error.colIndex === colIndex && + this.formErrors = this.formErrors.filter(error => + !(error.rowIndex === rowIndex && + error.colIndex === colIndex && error.field === col.prop) ); this.$emit('body-value-change', rowIndex, colIndex, value); @@ -256,9 +315,9 @@ export default { const col = this.columns[colIndex]; this.localDataSource[rowIndex][col.bodySubKey] = value; // 输入时清除对应表单项的错误状态 - this.formErrors = this.formErrors.filter(error => - !(error.rowIndex === rowIndex && - error.colIndex === colIndex && + this.formErrors = this.formErrors.filter(error => + !(error.rowIndex === rowIndex && + error.colIndex === colIndex && error.field === col.bodySubKey) ); this.$emit('body-sub-value-change', rowIndex, colIndex, value); @@ -270,9 +329,9 @@ export default { label: "" } }, - getBodyItem(col,rowIndex) { + getBodyItem(col, rowIndex) { const currentItem = this.localDataSource[rowIndex]; - const item = { + const item = { fillType: col.bodyFillType, options: col.bodyOptions, maxlength: col.bodyMaxlength, @@ -280,21 +339,21 @@ export default { precision: currentItem[col.bodyPrecisionKey] || col.precision || 0, copyFrom: col.copyFrom || "", }; - if(col.bodyDisabled){ + if (col.bodyDisabled) { item.disabled = col.bodyDisabled; } return item }, getBodySubItem(col) { - const item = { + const item = { fillType: col.bodySubFillType, options: col.bodySubOptions, maxlength: col.bodySubMaxlength || 10, label: "", - placeholder:col.bodySubPlaceholder||"请输入", + placeholder: col.bodySubPlaceholder || "请输入", precision: col.subPrecision || 0, } - if(col.bodySubDisabled){ + if (col.bodySubDisabled) { item.disabled = col.bodySubDisabled; } return item @@ -310,42 +369,42 @@ export default { this.localDataSource = JSON.parse(JSON.stringify(dataSource || [])); }, // 添加行 - addRow(row) { + addRow(row = {}) { this.localDataSource.push(row); }, - getDataSource(){ + getDataSource() { return this.localDataSource; }, // 根据行索引更新数据 - updateDataSourceByRowIndex(rowIndex,data){ - this.localDataSource[rowIndex] = {...this.localDataSource[rowIndex],...data}; - console.log(this.localDataSource,"this.localDataSource") + updateDataSourceByRowIndex(rowIndex, data) { + this.localDataSource[rowIndex] = { ...this.localDataSource[rowIndex], ...data }; + console.log(this.localDataSource, "this.localDataSource") this.localDataSource = [...this.localDataSource]; }, // 判断表单项是否有错误 hasError(rowIndex, colIndex, field) { - return this.formErrors.some(error => - error.rowIndex === rowIndex && - error.colIndex === colIndex && + return this.formErrors.some(error => + error.rowIndex === rowIndex && + error.colIndex === colIndex && error.field === field ); }, // 处理错误状态更新 onErrorUpdate(rowIndex, colIndex, field, isError) { if (!isError) { - this.formErrors = this.formErrors.filter(error => - !(error.rowIndex === rowIndex && - error.colIndex === colIndex && + this.formErrors = this.formErrors.filter(error => + !(error.rowIndex === rowIndex && + error.colIndex === colIndex && error.field === field) ); } }, onSubBlur(rowIndex, colKey, value) { - this.$emit("blur", {rowIndex, colKey, value,item:this.localDataSource[rowIndex]}); + this.$emit("blur", { rowIndex, colKey, value, item: this.localDataSource[rowIndex] }); }, onBlur(rowIndex, colKey) { const value = this.localDataSource[rowIndex][colKey]; - this.$emit("blur", {rowIndex, colKey, value,item:this.localDataSource[rowIndex]}); + this.$emit("blur", { rowIndex, colKey, value, item: this.localDataSource[rowIndex] }); } } }; @@ -361,17 +420,20 @@ export default { margin-top: 20px; } -.inner-table-cell{ +.inner-table-cell { display: flex; - align-items: center; + align-items: center; justify-content: center; } -.m-l-5{ + +.m-l-5 { margin-left: 5px; } -.sub-input-number{ + +.sub-input-number { width: 145px; - .el-input-number--mini{ + + .el-input-number--mini { width: 145px; } } @@ -406,6 +468,7 @@ export default { display: table; width: 100%; table-layout: fixed; + &:not(:last-child) { border-bottom: 1px solid #ebeef5; } @@ -473,9 +536,17 @@ export default { width: 100px; margin-left: 5px; } -.no-data{ + +.no-data { text-align: center; padding: 20px 0; color: rgb(144, 147, 153) } + +.add-row { + display: flex; + justify-content: center; + padding: 20px 0; + margin-top: 20px; +} \ No newline at end of file diff --git a/src/components/Template/HandleFormItem.vue b/src/components/Template/HandleFormItem.vue index 8a5eb06..1baf768 100644 --- a/src/components/Template/HandleFormItem.vue +++ b/src/components/Template/HandleFormItem.vue @@ -115,11 +115,28 @@ export default { const value = val !== undefined ? val : this.inputValue; this.$emit('input', value); this.$emit('change', value); - // 输入时清除错误状态 - if (this.error) { + + // 根据输入值判断是否显示错误状态 + const isEmpty = this.isValueEmpty(value); + if (this.error && !isEmpty) { this.$emit('update:error', false); + } else if (!this.error && isEmpty) { + this.$emit('update:error', true); } }, + // 判断值是否为空 + 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; + }, handleClickable(item,event){ if(item.fillType !== 'actFill'){ return @@ -176,9 +193,12 @@ export default { this.$emit("copy") }, onBlur(val) { - // 输入框失去焦点时清除错误状态 - if (this.error) { + // 根据输入值判断是否显示错误状态 + const isEmpty = this.isValueEmpty(this.inputValue); + if (this.error && !isEmpty) { this.$emit('update:error', false); + } else if (!this.error && isEmpty) { + this.$emit('update:error', true); } this.$emit("blur", val) }, diff --git a/src/views/business/comps/template/comps/gy/MJYLQSQD.vue b/src/views/business/comps/template/comps/gy/MJYLQSQD.vue index d201d1c..de1d6ef 100644 --- a/src/views/business/comps/template/comps/gy/MJYLQSQD.vue +++ b/src/views/business/comps/template/comps/gy/MJYLQSQD.vue @@ -18,9 +18,6 @@ -
- 添加行 -
@@ -190,20 +187,7 @@ export default { methods: { async getFormData() { - const baseData = await this.$refs.baseInfoRef.getFormData(); - const stepFormData = await this.$refs.stepFormPackageRef.getFormData(); - const stepTableFormData = await this.$refs.stepTableRef.getFormData(); - const remarkData = await this.$refs.remarkRef.getFormData(); - if(!stepTableFormData.stepTableFormData.length){ - this.$message.error("请添加计划信息"); - return; - } - return { - ...baseData, - ...stepFormData, - ...remarkData, - ...stepTableFormData - } + return await this.validFormFields(["baseInfoRef", "stepFormPackageRef","stepTableRef","remarkRef"]); }, async onSave() { const formData = await this.getFormData(); @@ -225,9 +209,5 @@ export default { .mt-20 { margin-top: 20px; } -.add-row{ - display: flex; - justify-content: center; - padding: 20px 0; -} + \ No newline at end of file diff --git a/src/views/business/comps/template/comps/gy/SYWZPZJHB.vue b/src/views/business/comps/template/comps/gy/SYWZPZJHB.vue index 922d60d..9363521 100644 --- a/src/views/business/comps/template/comps/gy/SYWZPZJHB.vue +++ b/src/views/business/comps/template/comps/gy/SYWZPZJHB.vue @@ -18,9 +18,6 @@ -
- 添加行 -
@@ -191,20 +188,7 @@ export default { methods: { async getFormData() { - const baseData = await this.$refs.baseInfoRef.getFormData(); - const stepFormData = await this.$refs.stepFormPackageRef.getFormData(); - const stepTableFormData = await this.$refs.stepTableRef.getFormData(); - const remarkData = await this.$refs.remarkRef.getFormData(); - if(!stepTableFormData.stepTableFormData.length){ - this.$message.error("请添加计划信息"); - return; - } - return { - ...baseData, - ...stepFormData, - ...remarkData, - ...stepTableFormData - } + return await this.validFormFields(["baseInfoRef", "stepFormPackageRef","stepTableRef","remarkRef"]); }, async onSave() { const formData = await this.getFormData(); @@ -226,9 +210,5 @@ export default { .mt-20 { margin-top: 20px; } -.add-row{ - display: flex; - justify-content: center; - padding: 20px 0; -} + \ No newline at end of file diff --git a/src/views/business/comps/template/comps/sp/SWYPBQGZYZBB.vue b/src/views/business/comps/template/comps/sp/SWYPBQGZYZBB.vue index cbce7b9..4a66cc9 100644 --- a/src/views/business/comps/template/comps/sp/SWYPBQGZYZBB.vue +++ b/src/views/business/comps/template/comps/sp/SWYPBQGZYZBB.vue @@ -16,7 +16,7 @@
-