|
|
@@ -101,6 +101,7 @@
|
|
|
style="width: 100%"
|
|
|
:default-sort="{ prop: sort_field, order: sort_order }"
|
|
|
@sort-change="handleSortChange"
|
|
|
+ :row-class-name="getRowClassName"
|
|
|
>
|
|
|
<el-table-column prop="sequence" label="排序" sortable width="80">
|
|
|
<template slot-scope="scope">
|
|
|
@@ -114,7 +115,12 @@
|
|
|
</div>
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
- <el-table-column prop="name" label="项目名称" sortable />
|
|
|
+ <el-table-column prop="name" label="项目名称" sortable>
|
|
|
+ <template slot-scope="scope">
|
|
|
+ <span v-if="currentModifiedItem === scope.row.id" class="modified-indicator"></span>
|
|
|
+ {{ scope.row.name }}
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
<el-table-column prop="tech_report_location" label="技术报告位置" />
|
|
|
<el-table-column prop="department" label="部门" sortable />
|
|
|
<el-table-column prop="content" label="内容" width="450">
|
|
|
@@ -188,7 +194,7 @@
|
|
|
</el-table>
|
|
|
<div class="pagination-container">
|
|
|
<el-pagination
|
|
|
- :current-page="currentPage"
|
|
|
+ :current-page.sync="currentPage"
|
|
|
:page-sizes="[30, 50]"
|
|
|
:page-size="pageSize"
|
|
|
layout="total, sizes, prev, pager, next, jumper"
|
|
|
@@ -603,6 +609,10 @@ export default {
|
|
|
previewContent: "",
|
|
|
currentPage: 1,
|
|
|
pageSize: 30,
|
|
|
+ // 修改状态跟踪
|
|
|
+ currentModifiedItem: null, // 当前高亮的项ID(只保持一个)
|
|
|
+ originalData: new Map(), // 存储原始数据用于对比
|
|
|
+ clearTimer: null, // 自动清理定时器
|
|
|
};
|
|
|
},
|
|
|
mounted() {
|
|
|
@@ -697,6 +707,9 @@ export default {
|
|
|
(p) => p.id === this.selectedProjectId
|
|
|
);
|
|
|
|
|
|
+ // 保存原始数据用于对比
|
|
|
+ this.saveOriginalData(row);
|
|
|
+
|
|
|
// 处理 content 内容,将文本格式转换为 HTML 并清理空样式
|
|
|
const processedContent = this.cleanEmptyStyles(
|
|
|
this.convertTextToHtml(row.content)
|
|
|
@@ -796,6 +809,13 @@ export default {
|
|
|
await projectUpdate(submitData);
|
|
|
this.$message.success("内容更新成功");
|
|
|
this.contentDialogVisible = false;
|
|
|
+
|
|
|
+ // 检查数据是否有变化,如果有则标记为已修改
|
|
|
+ const originalData = this.originalData.get(this.contentForm.id);
|
|
|
+ if (this.checkDataChanged(submitData, originalData)) {
|
|
|
+ this.markAsModified(this.contentForm.id);
|
|
|
+ }
|
|
|
+
|
|
|
this.fetchGsprData();
|
|
|
} catch (error) {
|
|
|
this.$message.error("内容更新失败");
|
|
|
@@ -804,6 +824,9 @@ export default {
|
|
|
|
|
|
// 修改现有的 handleEditRemark 方法
|
|
|
handleEditRemark(row) {
|
|
|
+ // 保存原始数据用于对比
|
|
|
+ this.saveOriginalData(row);
|
|
|
+
|
|
|
// 只复制需要的字段
|
|
|
this.remarkForm = {
|
|
|
id: row.id,
|
|
|
@@ -831,6 +854,13 @@ export default {
|
|
|
await projectUpdate(updateData);
|
|
|
this.$message.success("备注更新成功");
|
|
|
this.remarkDialogVisible = false;
|
|
|
+
|
|
|
+ // 检查数据是否有变化,如果有则标记为已修改
|
|
|
+ const originalData = this.originalData.get(this.remarkForm.id);
|
|
|
+ if (this.checkDataChanged(updateData, originalData)) {
|
|
|
+ this.markAsModified(this.remarkForm.id);
|
|
|
+ }
|
|
|
+
|
|
|
this.fetchGsprData();
|
|
|
} catch (error) {
|
|
|
this.$message.error("备注更新失败");
|
|
|
@@ -839,6 +869,11 @@ export default {
|
|
|
/* 修改评分 */
|
|
|
async rateScope(value, row) {
|
|
|
try {
|
|
|
+ // 保存原始数据用于对比
|
|
|
+ if (!this.originalData.has(row.id)) {
|
|
|
+ this.saveOriginalData(row);
|
|
|
+ }
|
|
|
+
|
|
|
const response = await rateScope({
|
|
|
id: row.id,
|
|
|
score: value,
|
|
|
@@ -853,6 +888,12 @@ export default {
|
|
|
if (index !== -1) {
|
|
|
this.gsprTableData[index].score = value;
|
|
|
}
|
|
|
+
|
|
|
+ // 检查数据是否有变化,如果有则标记为已修改
|
|
|
+ const originalData = this.originalData.get(row.id);
|
|
|
+ if (originalData && originalData.score !== value) {
|
|
|
+ this.markAsModified(row.id);
|
|
|
+ }
|
|
|
} else {
|
|
|
throw new Error(response.message || "评分更新失败");
|
|
|
}
|
|
|
@@ -864,6 +905,9 @@ export default {
|
|
|
},
|
|
|
/* 修改序号 */
|
|
|
handleEditSequence(row) {
|
|
|
+ // 保存原始数据用于对比
|
|
|
+ this.saveOriginalData(row);
|
|
|
+
|
|
|
this.sequenceForm.sequence = row.sequence;
|
|
|
this.sequenceForm.id = row.id;
|
|
|
this.dialogVisible = true;
|
|
|
@@ -877,6 +921,13 @@ export default {
|
|
|
});
|
|
|
this.$message.success("修改序号成功");
|
|
|
this.dialogVisible = false;
|
|
|
+
|
|
|
+ // 检查数据是否有变化,如果有则标记为已修改
|
|
|
+ const originalData = this.originalData.get(this.sequenceForm.id);
|
|
|
+ if (originalData && originalData.sequence !== this.sequenceForm.sequence) {
|
|
|
+ this.markAsModified(this.sequenceForm.id);
|
|
|
+ }
|
|
|
+
|
|
|
// 重新加载数据
|
|
|
this.fetchGsprData();
|
|
|
} catch (error) {
|
|
|
@@ -1294,6 +1345,24 @@ export default {
|
|
|
})
|
|
|
);
|
|
|
|
|
|
+ // 恢复该项目上次的分页设置
|
|
|
+ try {
|
|
|
+ const savedPage = Number(
|
|
|
+ localStorage.getItem(`gspr_page_${this.selectedProjectId}`)
|
|
|
+ );
|
|
|
+ const savedPageSize = Number(
|
|
|
+ localStorage.getItem(`gspr_page_size_${this.selectedProjectId}`)
|
|
|
+ );
|
|
|
+ if (!Number.isNaN(savedPage) && savedPage > 0) {
|
|
|
+ this.currentPage = savedPage;
|
|
|
+ }
|
|
|
+ if (!Number.isNaN(savedPageSize) && savedPageSize > 0) {
|
|
|
+ this.pageSize = savedPageSize;
|
|
|
+ }
|
|
|
+ } catch (e) {
|
|
|
+ // 忽略本地存储异常
|
|
|
+ }
|
|
|
+
|
|
|
this.gsprSearchForm.project_id = this.selectedProjectId;
|
|
|
this.fetchGsprData();
|
|
|
},
|
|
|
@@ -1510,6 +1579,13 @@ export default {
|
|
|
this.gsprTableData = responseData.list; //filteredItems
|
|
|
this.gsprTotal = responseData.total; // 使用API返回的总数
|
|
|
this.hasExistingData = this.gsprTableData.length > 0;
|
|
|
+
|
|
|
+ // 保存原始数据用于后续对比
|
|
|
+ this.gsprTableData.forEach(item => {
|
|
|
+ if (!this.originalData.has(item.id)) {
|
|
|
+ this.saveOriginalData(item);
|
|
|
+ }
|
|
|
+ });
|
|
|
} catch (error) {
|
|
|
console.error("数据加载失败:", error);
|
|
|
this.$message.error(error.message || "获取数据失败");
|
|
|
@@ -1529,8 +1605,12 @@ export default {
|
|
|
},
|
|
|
|
|
|
handleGsprSearch() {
|
|
|
- this.currentPage = 1; // 搜索时重置到第一页
|
|
|
+ this.currentPage = Number(
|
|
|
+ localStorage.getItem(`gspr_page_${this.selectedProjectId}`)
|
|
|
+ ) ; // 搜索时重置到第一页
|
|
|
+ console.log(this.currentPage);
|
|
|
this.searchList();
|
|
|
+ /* this.fetchGsprData(); */
|
|
|
},
|
|
|
/* 搜索 */
|
|
|
async searchList() {
|
|
|
@@ -1561,7 +1641,16 @@ export default {
|
|
|
});
|
|
|
this.gsprTableData = response.data.list; //filteredItems
|
|
|
this.gsprTotal = response.data.total; // 使用API返回的总数
|
|
|
+ /* this.currentPage = response.data.current_page; */
|
|
|
this.hasExistingData = this.gsprTableData.length > 0;
|
|
|
+
|
|
|
+ // 保存原始数据用于后续对比
|
|
|
+ this.gsprTableData.forEach(item => {
|
|
|
+ if (!this.originalData.has(item.id)) {
|
|
|
+ this.saveOriginalData(item);
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
console.log(response);
|
|
|
} finally {
|
|
|
loading.close();
|
|
|
@@ -1602,14 +1691,90 @@ export default {
|
|
|
|
|
|
handleGsprSizeChange(val) {
|
|
|
this.pageSize = val;
|
|
|
- this.currentPage = 1; // 切换每页显示数量时重置到第一页
|
|
|
+ // this.currentPage = 1; // 切换每页显示数量时重置到第一页
|
|
|
+ try {
|
|
|
+ localStorage.setItem(
|
|
|
+ `gspr_page_size_${this.selectedProjectId}`,
|
|
|
+ String(this.pageSize)
|
|
|
+ );
|
|
|
+ localStorage.setItem(
|
|
|
+ `gspr_page_${this.selectedProjectId}`,
|
|
|
+ String(this.currentPage)
|
|
|
+ );
|
|
|
+ } catch (e) {
|
|
|
+ // 忽略本地存储异常
|
|
|
+ }
|
|
|
this.fetchGsprData();
|
|
|
},
|
|
|
|
|
|
handleGsprCurrentChange(val) {
|
|
|
this.currentPage = val;
|
|
|
+ try {
|
|
|
+ localStorage.setItem(
|
|
|
+ `gspr_page_${this.selectedProjectId}`,
|
|
|
+ String(this.currentPage)
|
|
|
+ );
|
|
|
+ } catch (e) {
|
|
|
+ // 忽略本地存储异常
|
|
|
+ }
|
|
|
this.fetchGsprData();
|
|
|
},
|
|
|
+
|
|
|
+ // 获取行样式类名
|
|
|
+ getRowClassName({ row }) {
|
|
|
+ if (this.currentModifiedItem === row.id) {
|
|
|
+ return 'modified-row';
|
|
|
+ }
|
|
|
+ return '';
|
|
|
+ },
|
|
|
+
|
|
|
+ // 标记项为已修改(只保持一个高亮)
|
|
|
+ markAsModified(itemId) {
|
|
|
+ // 清除之前的定时器
|
|
|
+ if (this.clearTimer) {
|
|
|
+ clearTimeout(this.clearTimer);
|
|
|
+ this.clearTimer = null;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 设置新的高亮项
|
|
|
+ this.currentModifiedItem = itemId;
|
|
|
+
|
|
|
+ // 设置10秒后自动清除
|
|
|
+ this.clearTimer = setTimeout(() => {
|
|
|
+ this.currentModifiedItem = null;
|
|
|
+ this.clearTimer = null;
|
|
|
+ }, 10000); // 10秒
|
|
|
+ },
|
|
|
+
|
|
|
+ // 清除修改标记
|
|
|
+ clearModifiedMark() {
|
|
|
+ if (this.clearTimer) {
|
|
|
+ clearTimeout(this.clearTimer);
|
|
|
+ this.clearTimer = null;
|
|
|
+ }
|
|
|
+ this.currentModifiedItem = null;
|
|
|
+ },
|
|
|
+
|
|
|
+ // 检查数据是否有变化
|
|
|
+ checkDataChanged(newData, originalData) {
|
|
|
+ if (!originalData) return true;
|
|
|
+
|
|
|
+ const fieldsToCheck = ['name', 'tech_report_location', 'department', 'content', 'remarks', 'score'];
|
|
|
+ return fieldsToCheck.some(field => newData[field] !== originalData[field]);
|
|
|
+ },
|
|
|
+
|
|
|
+ // 保存原始数据
|
|
|
+ saveOriginalData(item) {
|
|
|
+ this.originalData.set(item.id, { ...item });
|
|
|
+ },
|
|
|
+ },
|
|
|
+
|
|
|
+ // 组件销毁时清理定时器
|
|
|
+ beforeDestroy() {
|
|
|
+ if (this.clearTimer) {
|
|
|
+ clearTimeout(this.clearTimer);
|
|
|
+ this.clearTimer = null;
|
|
|
+ }
|
|
|
},
|
|
|
};
|
|
|
</script>
|
|
|
@@ -1689,4 +1854,44 @@ export default {
|
|
|
::v-deep .el-dialog {
|
|
|
margin-top: 0 !important;
|
|
|
}
|
|
|
+
|
|
|
+/* 修改项高亮样式 */
|
|
|
+.modified-row {
|
|
|
+ background-color: #e6f7ff !important; /* 浅蓝色背景 */
|
|
|
+ border-left: 4px solid #1890ff !important; /* 左侧蓝色边框 */
|
|
|
+ transition: all 0.3s ease; /* 添加过渡效果 */
|
|
|
+}
|
|
|
+
|
|
|
+.modified-row:hover {
|
|
|
+ background-color: #bae7ff !important; /* 悬停时更深的蓝色 */
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+@keyframes pulse {
|
|
|
+ 0% {
|
|
|
+ opacity: 1;
|
|
|
+ transform: scale(1);
|
|
|
+ }
|
|
|
+ 50% {
|
|
|
+ opacity: 0.7;
|
|
|
+ transform: scale(1.1);
|
|
|
+ }
|
|
|
+ 100% {
|
|
|
+ opacity: 1;
|
|
|
+ transform: scale(1);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+@keyframes fadeOut {
|
|
|
+ 0% {
|
|
|
+ opacity: 1;
|
|
|
+ }
|
|
|
+ 90% {
|
|
|
+ opacity: 1;
|
|
|
+ }
|
|
|
+ 100% {
|
|
|
+ opacity: 0;
|
|
|
+ }
|
|
|
+}
|
|
|
</style>
|