diff --git a/src/views/modules/project/modules/projectPartModelTable.vue b/src/views/modules/project/modules/projectPartModelTable.vue index 410ec3e..5c40695 100644 --- a/src/views/modules/project/modules/projectPartModelTable.vue +++ b/src/views/modules/project/modules/projectPartModelTable.vue @@ -661,6 +661,36 @@ export default { // 清空原始数据 this.originalProjectPartModel = [] }, + isBatchRowModified(currentRow, originalRow) { + const compareFields = [ + 'daysNumber', + 'planStartDate', + 'planEndDate', + 'completionProgress', + 'excalCompletionDate', + 'roleId', + 'partLeaderCode', + 'partLeader', + ] + return compareFields.some((field) => { + const currentValue = currentRow && currentRow[field] !== undefined && currentRow[field] !== null ? String(currentRow[field]) : '' + const originalValue = originalRow && originalRow[field] !== undefined && originalRow[field] !== null ? String(originalRow[field]) : '' + return currentValue !== originalValue + }) + }, + buildBatchParams() { + const originalMap = new Map( + (this.originalProjectPartModel || []).map((row) => [row.modelId, row]) + ) + return this.projectPartModel.map((row) => { + const originalRow = originalMap.get(row.modelId) || {} + const isModified = this.isBatchRowModified(row, originalRow) ? 'Y' : 'N' + return { + ...row, + isModified, + } + }) + }, batchModel() { for (var i = 0; i < this.projectPartModel.length; i++) { /* if (!this.projectPartModel[i].daysNumber) { @@ -678,8 +708,7 @@ export default { } } } - let params = [] - params = this.projectPartModel + const params = this.buildBatchParams() this.batchLoading = true updateBatchPartModel(params) .then(({ data }) => { diff --git a/src/views/modules/project/modules/projectPartModelTableDetail.vue b/src/views/modules/project/modules/projectPartModelTableDetail.vue index c6fd18b..fb816ec 100644 --- a/src/views/modules/project/modules/projectPartModelTableDetail.vue +++ b/src/views/modules/project/modules/projectPartModelTableDetail.vue @@ -693,6 +693,37 @@ export default { // 清空原始数据 this.originalProjectPartModel = [] }, + isBatchRowModified(currentRow, originalRow) { + + const compareFields = [ + 'detailDaysNumber', + 'detailPlanStartDate', + 'detailPlanEndDate', + 'detailCompletionProgress', + 'detailExcalCompletionDate', + 'roleId', + 'detailPartLeaderCode', + 'detailPartLeader', + ] + return compareFields.some((field) => { + const currentValue = currentRow && currentRow[field] !== undefined && currentRow[field] !== null ? String(currentRow[field]) : '' + const originalValue = originalRow && originalRow[field] !== undefined && originalRow[field] !== null ? String(originalRow[field]) : '' + return currentValue !== originalValue + }) + }, + buildBatchParams() { + const originalMap = new Map( + (this.originalProjectPartModel || []).map((row) => [row.partModelDetailId, row]) + ) + return this.projectPartModel.map((row) => { + const originalRow = originalMap.get(row.partModelDetailId) || {} + const isModified = this.isBatchRowModified(row, originalRow) ? 'Y' : 'N' + return { + ...row, + isModified, + } + }) + }, batchModel() { for (var i = 0; i < this.projectPartModel.length; i++) { /* if (!this.projectPartModel[i].detailDaysNumber) { @@ -712,8 +743,8 @@ export default { return } } - let params = [] - params = this.projectPartModel + + const params = this.buildBatchParams() this.batchLoading = true updateBatchPartDetailModel(params) .then(({ data }) => { diff --git a/src/views/modules/project/projectIndex.vue b/src/views/modules/project/projectIndex.vue index ecdd18f..8c46e0c 100644 --- a/src/views/modules/project/projectIndex.vue +++ b/src/views/modules/project/projectIndex.vue @@ -685,6 +685,9 @@ export default { this.getTableUserColumn(this.$route.meta.menuId + 'table1', 1) this.getDataList() }, + activated() { + this.getDataList() + }, watch: { activeTable(newVal, oldVal) { if (this.tabRollbacking) return diff --git a/src/views/modules/project/projectPartIndex.vue b/src/views/modules/project/projectPartIndex.vue index 2bfe285..bfd645f 100644 --- a/src/views/modules/project/projectPartIndex.vue +++ b/src/views/modules/project/projectPartIndex.vue @@ -709,6 +709,9 @@ export default { this.getDataList() }, + activated() { + this.getDataList() + }, watch: { activeTable(newVal, oldVal) { if (this.tabRollbacking) return diff --git a/src/views/modules/project/projectPartProgress.vue b/src/views/modules/project/projectPartProgress.vue index 2fe73b1..6c9eb38 100644 --- a/src/views/modules/project/projectPartProgress.vue +++ b/src/views/modules/project/projectPartProgress.vue @@ -823,6 +823,9 @@ export default { } this.fetchGanttData() }, + activated() { + this.fetchGanttData() + }, } diff --git a/src/views/modules/project/sysBusinessLogIndex.vue b/src/views/modules/project/sysBusinessLogIndex.vue index 15f3438..f5ce1ca 100644 --- a/src/views/modules/project/sysBusinessLogIndex.vue +++ b/src/views/modules/project/sysBusinessLogIndex.vue @@ -51,13 +51,37 @@ - - - + +
- - -
{{ prettyJson(detailRow.oldValue) }}
-
- -
{{ prettyJson(detailRow.newValue) }}
-
-
+ + + + +
@@ -116,6 +137,7 @@ export default { tableHeight: 500, detailVisible: false, detailRow: {}, + dynamicColumns: [], } }, created() { @@ -127,6 +149,85 @@ export default { }) }, methods: { + isIdField(key) { + if (!key) return false + return /(^id$|_id$|Id$)/.test(String(key)) + }, + parseJsonObject(val) { + if (val === null || val === undefined || val === '') return {} + if (typeof val === 'object') return val || {} + try { + const parsed = JSON.parse(String(val)) + return parsed && typeof parsed === 'object' ? parsed : {} + } catch (e) { + return {} + } + }, + getFieldLabelMap() { + return { + detailPlanStartDate: '计划开始时间', + detailPlanEndDate: '计划结束时间', + projectStartDate: '项目开始时间', + planStartDate: '项目计划开始时间', + planEndDate: '项目计划结束时间', + daysNumber: '天数', + } + }, + getMappedFieldKeys() { + // 固定列顺序,避免不同数据导致列顺序变化影响阅读 + return [ + 'detailPlanStartDate', + 'detailPlanEndDate', + 'projectStartDate', + 'planStartDate', + 'planEndDate', + 'daysNumber', + ] + }, + getFieldRawValue(parsedValue, fieldKey) { + if (parsedValue === null || parsedValue === undefined || parsedValue === '') return undefined + // 支持 parsedValue 是数组的情况(例如 key 在数组元素对象里) + if (Array.isArray(parsedValue)) { + const values = [] + parsedValue.forEach((item) => { + if (item && typeof item === 'object' && !Array.isArray(item) && Object.prototype.hasOwnProperty.call(item, fieldKey)) { + values.push(item[fieldKey]) + } + }) + return values.length ? values : undefined + } + if (typeof parsedValue === 'object') { + return Object.prototype.hasOwnProperty.call(parsedValue, fieldKey) ? parsedValue[fieldKey] : undefined + } + return undefined + }, + buildDynamicColumns(list) { + // 这里直接固定为你约定的字段集合,避免出现数组下标(0/1/2...)被当成“列名” + this.dynamicColumns = this.getMappedFieldKeys() + }, + getFieldLabel(key) { + const map = this.getFieldLabelMap() + return map[key] || key + }, + flattenDisplayValue(val) { + if (val === null || val === undefined || val === '') return '-' + const values = [] + const pushLeaf = (v) => { + if (v === null || v === undefined || v === '') return + if (Array.isArray(v)) { + v.forEach((it) => pushLeaf(it)) + return + } + if (typeof v === 'object') { + Object.values(v).forEach((it) => pushLeaf(it)) + return + } + values.push(String(v)) + } + pushLeaf(val) + if (!values.length) return '-' + return values.join(';') + }, getDataList() { this.dataListLoading = true const params = { @@ -137,10 +238,21 @@ export default { querySysBusinessLogPage(params) .then(({ data }) => { if (data && data.code === 0 && data.page) { - this.dataList = data.page.list || [] + const list = data.page.list || [] + this.dataList = list.map((item) => { + const parsedOldValue = this.parseJsonObject(item.oldValue) + const parsedNewValue = this.parseJsonObject(item.newValue) + return { + ...item, + parsedOldValue, + parsedNewValue, + } + }) + this.buildDynamicColumns(this.dataList) this.totalPage = data.page.totalCount || 0 } else { this.dataList = [] + this.dynamicColumns = [] this.totalPage = 0 } }) @@ -166,21 +278,18 @@ export default { this.detailRow = JSON.parse(JSON.stringify(row || {})) this.detailVisible = true }, - prettyJson(val) { - if (val === null || val === undefined || val === '') return '' - if (typeof val === 'object') { - try { - return JSON.stringify(val, null, 2) - } catch (e) { - return String(val) - } - } - const str = String(val) - try { - return JSON.stringify(JSON.parse(str), null, 2) - } catch (e) { - return str - } + getDetailDiffList(row) { + const oldObj = this.parseJsonObject(row.oldValue) + const newObj = this.parseJsonObject(row.newValue) + const mappedKeys = this.getMappedFieldKeys() + return mappedKeys + .filter((k) => !this.isIdField(k)) + .map((key) => ({ + key, + label: this.getFieldLabel(key), + oldValue: this.flattenDisplayValue(this.getFieldRawValue(oldObj, key)), + newValue: this.flattenDisplayValue(this.getFieldRawValue(newObj, key)), + })) }, getReviewedLabel(flag) { if (flag === 'Y') return '已审核' @@ -192,18 +301,15 @@ export default { return 'status-yellow' }, }, + computed: { + detailDiffList() { + return this.getDetailDiffList(this.detailRow || {}) + }, + }, }