|
|
@ -12,9 +12,41 @@ |
|
|
@change="handleCheckAllChange"></el-checkbox> |
|
|
@change="handleCheckAllChange"></el-checkbox> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
<div v-for="(col, index) in columns" :key="index" class="custom-table-cell header-cell" |
|
|
|
|
|
|
|
|
<div v-for="(col, colIndex) in columns" :key="colIndex" class="custom-table-cell header-cell" |
|
|
:style="getCellWidth(col)"> |
|
|
:style="getCellWidth(col)"> |
|
|
<div class="header-cell-content"> |
|
|
|
|
|
|
|
|
<div class="header-cell-content" v-if="col.headerColumns && col.headerColumns.length > 0"> |
|
|
|
|
|
<div class="header-columns-grid" |
|
|
|
|
|
:style="{ 'grid-template-columns': `repeat(${col.span || 2}, 1fr)` }"> |
|
|
|
|
|
<div v-for="(headerCol, headerIndex) in col.headerColumns" :key="headerIndex" |
|
|
|
|
|
class="header-column-item"> |
|
|
|
|
|
<template v-if="headerCol.type === 'span'"> |
|
|
|
|
|
<div class="span-content">{{ $t(headerCol.label) }}</div> |
|
|
|
|
|
</template> |
|
|
|
|
|
<template v-else-if="isRegent(headerCol)"> |
|
|
|
|
|
<HandleFormItem |
|
|
|
|
|
:fieldKey="prefixKey + colIndex + '_' + headerCol.key + '_' + headerIndex" |
|
|
|
|
|
:fieldItemLabel="fieldItemLabel" :type="headerCol.type" |
|
|
|
|
|
class="body-clickable" sourceFrom="customTable" |
|
|
|
|
|
:item="getHeaderColumnItem(headerCol)" |
|
|
|
|
|
:value="headerFields[`${colIndex}_${headerIndex}`]" |
|
|
|
|
|
:error="hasHeaderError(colIndex, headerIndex, headerCol.key)" |
|
|
|
|
|
@update:error="onHeaderColumnErrorUpdate(colIndex, headerIndex, headerCol.key, $event)" |
|
|
|
|
|
@onRegentSubmit="(data, inputValue) => onHeaderRegentSubmit(data, inputValue, colIndex, headerIndex)" /> |
|
|
|
|
|
</template> |
|
|
|
|
|
<template v-else-if="headerCol.type === 'input' || headerCol.type === 'select'|| headerCol.type === 'inputNumber'"> |
|
|
|
|
|
<HandleFormItem |
|
|
|
|
|
:fieldKey="prefixKey + '_header_' + colIndex + '_' + headerIndex" |
|
|
|
|
|
:fieldItemLabel="fieldItemLabel" :type="headerCol.type" |
|
|
|
|
|
:item="getHeaderColumnItem(headerCol)" |
|
|
|
|
|
v-model="headerFields[`${colIndex}_${headerIndex}`]" |
|
|
|
|
|
@change="onHeaderColumnChange(colIndex, headerIndex, headerCol, $event)" |
|
|
|
|
|
:error="hasHeaderError(colIndex, headerIndex, headerCol.key)" |
|
|
|
|
|
@update:error="onHeaderColumnErrorUpdate(colIndex, headerIndex, headerCol.key, $event)" /> |
|
|
|
|
|
</template> |
|
|
|
|
|
</div> |
|
|
|
|
|
</div> |
|
|
|
|
|
</div> |
|
|
|
|
|
<div class="header-cell-content" v-else> |
|
|
<div>{{ $t(col.label) }}</div> |
|
|
<div>{{ $t(col.label) }}</div> |
|
|
<template |
|
|
<template |
|
|
v-if="col.headerSelectKey && col.headerOptions && (showHeaderSelect || templateFillType === 'preFill')"> |
|
|
v-if="col.headerSelectKey && col.headerOptions && (showHeaderSelect || templateFillType === 'preFill')"> |
|
|
@ -22,8 +54,8 @@ |
|
|
:fieldItemLabel="fieldItemLabel" type="select" class="header-select" |
|
|
:fieldItemLabel="fieldItemLabel" type="select" class="header-select" |
|
|
:item="getHeaderItem(col)" v-model="headerSelectFields[col.headerSelectKey]" |
|
|
:item="getHeaderItem(col)" v-model="headerSelectFields[col.headerSelectKey]" |
|
|
@change="onHeaderSelectChange(col, $event)" |
|
|
@change="onHeaderSelectChange(col, $event)" |
|
|
:error="hasError(-1, index, col.headerSelectKey)" |
|
|
|
|
|
@update:error="onErrorUpdate(-1, index, col.headerSelectKey, $event)" /> |
|
|
|
|
|
|
|
|
:error="hasError(-1, colIndex, col.headerSelectKey)" |
|
|
|
|
|
@update:error="onErrorUpdate(-1, colIndex, col.headerSelectKey, $event)" /> |
|
|
</template> |
|
|
</template> |
|
|
<div v-else-if="headerSelectFields[col.headerSelectKey]" class="fill-type-icon" |
|
|
<div v-else-if="headerSelectFields[col.headerSelectKey]" class="fill-type-icon" |
|
|
:style="{ width: (templateFillType !== 'actFill') ? '60px' : 'auto' }">({{ |
|
|
:style="{ width: (templateFillType !== 'actFill') ? '60px' : 'auto' }">({{ |
|
|
@ -203,7 +235,7 @@ import HandleFormItem from "./HandleFormItem.vue"; |
|
|
import { isEqual } from "@/utils/index.js"; |
|
|
import { isEqual } from "@/utils/index.js"; |
|
|
import { isShowOther } from "@/utils/formPackageCommon.js"; |
|
|
import { isShowOther } from "@/utils/formPackageCommon.js"; |
|
|
import { EventBus } from "@/utils/eventBus"; |
|
|
import { EventBus } from "@/utils/eventBus"; |
|
|
import { getuuid } from "@/utils/index.js"; |
|
|
|
|
|
|
|
|
import { getuuid, justUpdateFilledFormData } from "@/utils/index.js"; |
|
|
import { isRegent } from "@/utils/index.js"; |
|
|
import { isRegent } from "@/utils/index.js"; |
|
|
import { isValueEmpty } from '@/utils/index.js'; |
|
|
import { isValueEmpty } from '@/utils/index.js'; |
|
|
|
|
|
|
|
|
@ -247,7 +279,7 @@ export default { |
|
|
default: () => { |
|
|
default: () => { |
|
|
return { |
|
|
return { |
|
|
stepTableFormData: [], |
|
|
stepTableFormData: [], |
|
|
headerSelectFields: {} |
|
|
|
|
|
|
|
|
headerSelectFields: {}, |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
}, |
|
|
}, |
|
|
@ -279,6 +311,7 @@ export default { |
|
|
return { |
|
|
return { |
|
|
localDataSource: [], |
|
|
localDataSource: [], |
|
|
headerSelectFields: {}, |
|
|
headerSelectFields: {}, |
|
|
|
|
|
headerFields: {}, // 存储 headerColumns 的数据 |
|
|
formErrors: [], // 表单错误状态管理 |
|
|
formErrors: [], // 表单错误状态管理 |
|
|
orangeBgCells: {}, // 存储需要橙色背景的单元格 {rowIndex-colIndex: true/false} |
|
|
orangeBgCells: {}, // 存储需要橙色背景的单元格 {rowIndex-colIndex: true/false} |
|
|
isShowOther, |
|
|
isShowOther, |
|
|
@ -294,9 +327,10 @@ export default { |
|
|
formData: { |
|
|
formData: { |
|
|
immediate: true, |
|
|
immediate: true, |
|
|
handler(newData) { |
|
|
handler(newData) { |
|
|
const { stepTableFormData = [], headerSelectFields = {} } = newData; |
|
|
|
|
|
|
|
|
const { stepTableFormData = [], headerSelectFields = {}, headerFields = {} } = newData; |
|
|
this.updateDataSource(stepTableFormData); |
|
|
this.updateDataSource(stepTableFormData); |
|
|
this.headerSelectFields = JSON.parse(JSON.stringify(headerSelectFields)); |
|
|
this.headerSelectFields = JSON.parse(JSON.stringify(headerSelectFields)); |
|
|
|
|
|
this.headerFields = JSON.parse(JSON.stringify(headerFields)); |
|
|
// 在数据加载后检查 compareTo 逻辑 |
|
|
// 在数据加载后检查 compareTo 逻辑 |
|
|
this.checkCompareToOnDataLoad(); |
|
|
this.checkCompareToOnDataLoad(); |
|
|
} |
|
|
} |
|
|
@ -318,11 +352,56 @@ export default { |
|
|
this.oldLocalDataSource = []; |
|
|
this.oldLocalDataSource = []; |
|
|
}, |
|
|
}, |
|
|
methods: { |
|
|
methods: { |
|
|
|
|
|
getHeaderColumnItem(headerCol) { |
|
|
|
|
|
return { |
|
|
|
|
|
label: headerCol.label || '', |
|
|
|
|
|
fillType: headerCol.fillType, |
|
|
|
|
|
options: headerCol.options, |
|
|
|
|
|
maxlength: headerCol.maxlength, |
|
|
|
|
|
checkType: headerCol.checkType, |
|
|
|
|
|
regentFillType: headerCol.regentFillType, |
|
|
|
|
|
type: headerCol.type, |
|
|
|
|
|
}; |
|
|
|
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
onHeaderColumnChange(colIndex, headerIndex, headerCol, value) { |
|
|
|
|
|
const fieldKey = `${colIndex}_${headerIndex}`; |
|
|
|
|
|
this.headerFields[fieldKey] = value; |
|
|
|
|
|
this.$emit('headerColumnChange', { |
|
|
|
|
|
colIndex, |
|
|
|
|
|
headerIndex, |
|
|
|
|
|
key: fieldKey, |
|
|
|
|
|
value, |
|
|
|
|
|
headerFields: this.headerFields |
|
|
|
|
|
}); |
|
|
|
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
hasHeaderError(colIndex, headerIndex, key) { |
|
|
|
|
|
console.log(colIndex, headerIndex, key,this.formErrors,"headerError") |
|
|
|
|
|
return this.formErrors.some(error => |
|
|
|
|
|
error.rowIndex === -1 && |
|
|
|
|
|
error.colIndex === colIndex && |
|
|
|
|
|
error.headerIndex === headerIndex && |
|
|
|
|
|
error.field === key |
|
|
|
|
|
); |
|
|
|
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
onHeaderColumnErrorUpdate(colIndex, headerIndex, key, isError) { |
|
|
|
|
|
if (!isError) { |
|
|
|
|
|
this.formErrors = this.formErrors.filter(error => |
|
|
|
|
|
!(error.rowIndex === -1 && |
|
|
|
|
|
error.colIndex === colIndex && |
|
|
|
|
|
error.headerIndex === headerIndex && |
|
|
|
|
|
error.field === key) |
|
|
|
|
|
); |
|
|
|
|
|
} |
|
|
|
|
|
}, |
|
|
|
|
|
|
|
|
// 删除checkboxTag |
|
|
// 删除checkboxTag |
|
|
onDeleteCheckboxTag(rowIndex, col, tagIndex) { |
|
|
onDeleteCheckboxTag(rowIndex, col, tagIndex) { |
|
|
this.localDataSource[rowIndex][col.prop].splice(tagIndex, 1); |
|
|
this.localDataSource[rowIndex][col.prop].splice(tagIndex, 1); |
|
|
this.$emit("onDeleteTag", rowIndex, col, tagIndex); |
|
|
this.$emit("onDeleteTag", rowIndex, col, tagIndex); |
|
|
this.justUpdateFilledFormData(); |
|
|
|
|
|
|
|
|
justUpdateFilledFormData(); |
|
|
}, |
|
|
}, |
|
|
onCheckboxTagChange(rowIndex, colIndex, col, value) { |
|
|
onCheckboxTagChange(rowIndex, colIndex, col, value) { |
|
|
// value 现在是整个数组 |
|
|
// value 现在是整个数组 |
|
|
@ -349,7 +428,7 @@ export default { |
|
|
error.field === col.prop) |
|
|
error.field === col.prop) |
|
|
); |
|
|
); |
|
|
this.$emit("onCheckboxChange", rowIndex, col, value); |
|
|
this.$emit("onCheckboxChange", rowIndex, col, value); |
|
|
this.justUpdateFilledFormData(); |
|
|
|
|
|
|
|
|
justUpdateFilledFormData(); |
|
|
}, |
|
|
}, |
|
|
handleClickButton(e, data, key, rowIndex, colIndex) { |
|
|
handleClickButton(e, data, key, rowIndex, colIndex) { |
|
|
this.$emit("clickButton", key, rowIndex, colIndex, e, data,) |
|
|
this.$emit("clickButton", key, rowIndex, colIndex, e, data,) |
|
|
@ -408,10 +487,16 @@ export default { |
|
|
} |
|
|
} |
|
|
this.$emit("beforeReagentSubmit", { selectData: data, callback, key: col.prop, rowData: row }) |
|
|
this.$emit("beforeReagentSubmit", { selectData: data, callback, key: col.prop, rowData: row }) |
|
|
}, |
|
|
}, |
|
|
|
|
|
onHeaderRegentSubmit(data, inputValue, colIndex, headerIndex) { |
|
|
|
|
|
this.headerFields[`${colIndex}_${headerIndex}`] = inputValue; |
|
|
|
|
|
console.log("onHeaderRegentSubmit", data, inputValue, colIndex, headerIndex,this.headerFields) |
|
|
|
|
|
|
|
|
|
|
|
this.$emit("onHeaderRegentSubmit", { selectInfo: data, headerIndex, colIndex, headerFields: this.headerFields }) |
|
|
|
|
|
}, |
|
|
onRegentSubmit(data, inputValue, col, rowIndex, colIndex, row) { |
|
|
onRegentSubmit(data, inputValue, col, rowIndex, colIndex, row) { |
|
|
if (this.templateFillType !== 'actFill') { |
|
|
|
|
|
return |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
// if (this.templateFillType !== 'actFill') { |
|
|
|
|
|
// return |
|
|
|
|
|
// } |
|
|
this.updateDataSourceByRowIndex(rowIndex, { [col.prop]: inputValue }) |
|
|
this.updateDataSourceByRowIndex(rowIndex, { [col.prop]: inputValue }) |
|
|
this.$emit("onRegentSubmit", { selectInfo: data, key: col.prop, col, rowIndex, colIndex, rowData: row }) |
|
|
this.$emit("onRegentSubmit", { selectInfo: data, key: col.prop, col, rowIndex, colIndex, rowData: row }) |
|
|
}, |
|
|
}, |
|
|
@ -447,6 +532,7 @@ export default { |
|
|
return { |
|
|
return { |
|
|
stepTableFormData: [...this.localDataSource], |
|
|
stepTableFormData: [...this.localDataSource], |
|
|
headerSelectFields: this.headerSelectFields, |
|
|
headerSelectFields: this.headerSelectFields, |
|
|
|
|
|
headerFields: this.headerFields, |
|
|
}; |
|
|
}; |
|
|
}, |
|
|
}, |
|
|
// 获取最新数据 |
|
|
// 获取最新数据 |
|
|
@ -461,6 +547,7 @@ export default { |
|
|
resolve({ |
|
|
resolve({ |
|
|
stepTableFormData: [...this.localDataSource], |
|
|
stepTableFormData: [...this.localDataSource], |
|
|
headerSelectFields: this.headerSelectFields, |
|
|
headerSelectFields: this.headerSelectFields, |
|
|
|
|
|
headerFields: this.headerFields, |
|
|
}) |
|
|
}) |
|
|
} else { |
|
|
} else { |
|
|
// this.$message.error("表单内容未填完,请填写后再提交"); |
|
|
// this.$message.error("表单内容未填完,请填写后再提交"); |
|
|
@ -478,6 +565,7 @@ export default { |
|
|
|
|
|
|
|
|
// 校验表头的 HandleFormItem |
|
|
// 校验表头的 HandleFormItem |
|
|
this.columns.forEach((col, colIndex) => { |
|
|
this.columns.forEach((col, colIndex) => { |
|
|
|
|
|
console.log(col.headerColumns, col, "ttt") |
|
|
if (col.headerSelectKey && col.headerOptions && col.fillType === this.templateFillType) { |
|
|
if (col.headerSelectKey && col.headerOptions && col.fillType === this.templateFillType) { |
|
|
const headerValue = this.headerSelectFields[col.headerSelectKey]; |
|
|
const headerValue = this.headerSelectFields[col.headerSelectKey]; |
|
|
if (isValueEmpty(headerValue)) { |
|
|
if (isValueEmpty(headerValue)) { |
|
|
@ -491,6 +579,26 @@ export default { |
|
|
errors.push(errorItem); |
|
|
errors.push(errorItem); |
|
|
this.formErrors.push(errorItem); |
|
|
this.formErrors.push(errorItem); |
|
|
} |
|
|
} |
|
|
|
|
|
} else if (col.headerColumns && col.headerColumns.length > 0) { |
|
|
|
|
|
col.headerColumns.forEach((headerCol, headerColIndex) => { |
|
|
|
|
|
const headerValue = this.headerFields[`${colIndex}_${headerColIndex}`]; |
|
|
|
|
|
if (headerCol.fillType === this.templateFillType) { |
|
|
|
|
|
if (isValueEmpty(headerValue) && headerCol.type !== "span") { |
|
|
|
|
|
const errorItem = { |
|
|
|
|
|
rowIndex: -1, // 表头特殊标记 |
|
|
|
|
|
colIndex, |
|
|
|
|
|
field: headerCol.key, |
|
|
|
|
|
label: this.$t(headerCol.label), |
|
|
|
|
|
headerIndex: headerColIndex, |
|
|
|
|
|
error: `请选择${this.$t(headerCol.label)}` |
|
|
|
|
|
}; |
|
|
|
|
|
errors.push(errorItem); |
|
|
|
|
|
this.formErrors.push(errorItem); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
} |
|
|
} |
|
|
}); |
|
|
}); |
|
|
|
|
|
|
|
|
@ -819,6 +927,12 @@ export default { |
|
|
}); |
|
|
}); |
|
|
|
|
|
|
|
|
}, |
|
|
}, |
|
|
|
|
|
deleteSelectedRows(rowsIndex){ |
|
|
|
|
|
this.deleteRows(rowsIndex); |
|
|
|
|
|
this.selectedRows = []; |
|
|
|
|
|
this.isIndeterminate = false; |
|
|
|
|
|
this.$emit('selectionChange', this.selectedRows); |
|
|
|
|
|
}, |
|
|
// 更新数据方法,可在formData变更时调用,也可由父组件调用 |
|
|
// 更新数据方法,可在formData变更时调用,也可由父组件调用 |
|
|
updateDataSource(dataSource = []) { |
|
|
updateDataSource(dataSource = []) { |
|
|
this.oldLocalDataSource = JSON.parse(JSON.stringify(this.localDataSource)); |
|
|
this.oldLocalDataSource = JSON.parse(JSON.stringify(this.localDataSource)); |
|
|
@ -836,7 +950,7 @@ export default { |
|
|
this.localDataSource[rowIndex] = { ...this.localDataSource[rowIndex], ...data }; |
|
|
this.localDataSource[rowIndex] = { ...this.localDataSource[rowIndex], ...data }; |
|
|
this.localDataSource = [...this.localDataSource]; |
|
|
this.localDataSource = [...this.localDataSource]; |
|
|
this.checkCompareToOnDataLoad(); |
|
|
this.checkCompareToOnDataLoad(); |
|
|
this.justUpdateFilledFormData(); |
|
|
|
|
|
|
|
|
justUpdateFilledFormData(); |
|
|
}, |
|
|
}, |
|
|
// 比较newData和oldData的值是否相等,只要有一对不相等就返回false |
|
|
// 比较newData和oldData的值是否相等,只要有一对不相等就返回false |
|
|
compareOldAndCurrentFormFields(newData, oldData) { |
|
|
compareOldAndCurrentFormFields(newData, oldData) { |
|
|
@ -852,15 +966,6 @@ export default { |
|
|
|
|
|
|
|
|
return true; |
|
|
return true; |
|
|
}, |
|
|
}, |
|
|
// 只是更新已填写的表单数据,不触发校验 |
|
|
|
|
|
justUpdateFilledFormData() { |
|
|
|
|
|
const params = { |
|
|
|
|
|
type: "fieldChanged", |
|
|
|
|
|
newRecord: null, |
|
|
|
|
|
resourceList: null, |
|
|
|
|
|
} |
|
|
|
|
|
EventBus.$emit('onModifyRecord', params,) |
|
|
|
|
|
}, |
|
|
|
|
|
// 处理全选 |
|
|
// 处理全选 |
|
|
handleCheckAllChange(val) { |
|
|
handleCheckAllChange(val) { |
|
|
this.localDataSource.forEach(row => { |
|
|
this.localDataSource.forEach(row => { |
|
|
@ -898,7 +1003,7 @@ export default { |
|
|
targetDiluentVolumePrecision: 3,//小数点精度默认为3 |
|
|
targetDiluentVolumePrecision: 3,//小数点精度默认为3 |
|
|
targetStartSolutionVolumePrecision: 3,//小数点精度默认为3 |
|
|
targetStartSolutionVolumePrecision: 3,//小数点精度默认为3 |
|
|
}); |
|
|
}); |
|
|
this.justUpdateFilledFormData() |
|
|
|
|
|
|
|
|
justUpdateFilledFormData() |
|
|
}, |
|
|
}, |
|
|
|
|
|
|
|
|
// 添加行 |
|
|
// 添加行 |
|
|
@ -1054,6 +1159,17 @@ export default { |
|
|
justify-content: center; |
|
|
justify-content: center; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
.header-columns-grid { |
|
|
|
|
|
display: grid; |
|
|
|
|
|
gap: 10px; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
.header-column-item { |
|
|
|
|
|
display: flex; |
|
|
|
|
|
align-items: center; |
|
|
|
|
|
padding: 0 5px; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
/* 共同行样式 */ |
|
|
/* 共同行样式 */ |
|
|
.custom-table-row { |
|
|
.custom-table-row { |
|
|
display: table; |
|
|
display: table; |
|
|
@ -1211,4 +1327,9 @@ export default { |
|
|
.c-cell { |
|
|
.c-cell { |
|
|
width: 50px; |
|
|
width: 50px; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
.span-content { |
|
|
|
|
|
width: -webkit-fill-available; |
|
|
|
|
|
text-align: center; |
|
|
|
|
|
} |
|
|
</style> |
|
|
</style> |