调整项目列表入口和操作按钮

This commit is contained in:
wjj
2026-07-02 17:26:43 +08:00
parent 21c4e91f41
commit 6d2f40843a
3 changed files with 75 additions and 118 deletions

View File

@@ -0,0 +1,31 @@
# 项目列表整行进入与操作按钮收敛实施记录
## 修改时间
2026-07-01 15:52:04
## 需求背景
项目管理列表中“进入项目 / 查看结果 / 重新分析”操作含义接近,用户希望点击项目行任意位置即可进入项目详情;列表页只保留真正的操作按钮,项目结果、分析、明细统一进入详情页后查看。
## 修改内容
- 调整项目列表交互:项目表格整行点击进入项目详情。
- 行点击进入项目详情时明确默认页签:
- 进行中、打标中、打标失败项目进入“上传数据”。
- 已完成、已归档或当前用户不可操作的项目进入“结果总览”。
- 移除列表操作列中的“进入项目”“查看结果”“重新分析”按钮。
- 操作列保留“归档”“删除”:
- 已完成项目显示“归档”。
- 删除按钮调用既有删除接口。
- 不调整后端权限、删除字段和查询逻辑。
- 删除、归档按钮点击时阻止行点击,避免误进入项目详情。
## 影响范围
- 项目管理列表页。
- 不涉及后端接口、权限、数据库字段和查询逻辑。
## 验证情况
- 前端已通过 `nvm use 14.21.3` 切换 Node 版本,并执行生产构建,构建通过;仅存在既有资源体积 warning。

View File

@@ -4,6 +4,8 @@
v-loading="loading" v-loading="loading"
:data="dataList" :data="dataList"
style="width: 100%" style="width: 100%"
class="project-entry-table"
@row-click="handleOpen"
> >
<el-table-column <el-table-column
label="项目名称" label="项目名称"
@@ -92,7 +94,7 @@
<el-table-column <el-table-column
label="操作" label="操作"
width="390" width="180"
align="left" align="left"
fixed="right" fixed="right"
> >
@@ -102,74 +104,34 @@
size="mini" size="mini"
type="text" type="text"
icon="el-icon-refresh-left" icon="el-icon-refresh-left"
@click="handleRestore(scope.row)" @click.stop="handleRestore(scope.row)"
> >
恢复 恢复
</el-button> </el-button>
</template> </template>
<template v-else> <template v-else>
<div class="row-actions">
<el-button <el-button
v-if="['0', '3', '4'].includes(scope.row.status)" v-if="scope.row.status === '1' && canOperate(scope.row)"
size="mini"
type="text"
:icon="canOperate(scope.row) ? 'el-icon-right' : 'el-icon-view'"
@click="handleEnter(scope.row)"
>
{{ canOperate(scope.row) ? "进入项目" : "查看项目" }}
</el-button>
<template v-if="scope.row.status === '1'">
<el-button
size="mini"
type="text"
icon="el-icon-view"
@click="handleViewResult(scope.row)"
>
查看结果
</el-button>
<el-button
v-if="canOperate(scope.row)"
size="mini"
type="text"
icon="el-icon-refresh"
:loading="reAnalyzeLoadingMap[String(scope.row.projectId)]"
:disabled="reAnalyzeLoadingMap[String(scope.row.projectId)]"
@click="handleReAnalyze(scope.row)"
>
重新分析
</el-button>
<el-button
v-if="canOperate(scope.row)"
size="mini" size="mini"
type="text" type="text"
icon="el-icon-folder" icon="el-icon-folder"
@click="handleArchive(scope.row)" @click.stop="handleArchive(scope.row)"
> >
归档 归档
</el-button> </el-button>
</template>
<el-button
v-if="scope.row.status === '2'"
size="mini"
type="text"
icon="el-icon-view"
@click="handleViewResult(scope.row)"
>
查看结果
</el-button>
<el-button <el-button
v-if="canDelete(scope.row) && scope.row.status !== '5'" v-if="canDelete(scope.row) && scope.row.status !== '5'"
size="mini" size="mini"
type="text" type="text"
class="delete-button" class="delete-button"
icon="el-icon-delete" icon="el-icon-delete"
@click="handleDelete(scope.row)" @click.stop="handleDelete(scope.row)"
> >
删除 删除
</el-button> </el-button>
</div>
</template> </template>
</template> </template>
</el-table-column> </el-table-column>
@@ -213,10 +175,6 @@ export default {
pageSize: 10, pageSize: 10,
}), }),
}, },
reAnalyzeLoadingMap: {
type: Object,
default: () => ({}),
},
deletedList: { deletedList: {
type: Boolean, type: Boolean,
default: false, default: false,
@@ -247,14 +205,8 @@ export default {
} }
return ""; return "";
}, },
handleEnter(row) { handleOpen(row) {
this.$emit("enter", row); this.$emit("open", row);
},
handleViewResult(row) {
this.$emit("view-result", row);
},
handleReAnalyze(row) {
this.$emit("re-analyze", row);
}, },
handleArchive(row) { handleArchive(row) {
this.$emit("archive", row); this.$emit("archive", row);
@@ -296,6 +248,14 @@ export default {
} }
} }
::v-deep .project-entry-table .el-table__body tr {
cursor: pointer;
}
::v-deep .project-entry-table .el-table__body tr:hover > td {
background-color: #f5f9ff;
}
.status-tag { .status-tag {
display: inline-flex; display: inline-flex;
align-items: center; align-items: center;

View File

@@ -20,12 +20,9 @@
:data-list="projectList" :data-list="projectList"
:total="total" :total="total"
:page-params="queryParams" :page-params="queryParams"
:re-analyze-loading-map="reAnalyzeLoadingMap"
:deleted-list="queryParams.includeDeleted === true" :deleted-list="queryParams.includeDeleted === true"
@pagination="handlePagination" @pagination="handlePagination"
@enter="handleEnter" @open="handleOpenProject"
@view-result="handleViewResult"
@re-analyze="handleReAnalyze"
@archive="handleArchive" @archive="handleArchive"
@delete="handleDelete" @delete="handleDelete"
@restore="handleRestore" @restore="handleRestore"
@@ -67,7 +64,8 @@
</template> </template>
<script> <script>
import {archiveProject, delProject, getStatusCounts, listProject, rebuildProjectTags, restoreProject} from '@/api/ccdiProject' import {archiveProject, delProject, getStatusCounts, listProject} from '@/api/ccdiProject'
import { restoreProject } from '@/api/ccdiProject'
import SearchBar from './components/SearchBar' import SearchBar from './components/SearchBar'
import ProjectTable from './components/ProjectTable' import ProjectTable from './components/ProjectTable'
import QuickEntry from './components/QuickEntry' import QuickEntry from './components/QuickEntry'
@@ -122,8 +120,6 @@ export default {
// 归档确认弹窗 // 归档确认弹窗
archiveDialogVisible: false, archiveDialogVisible: false,
currentArchiveProject: null, currentArchiveProject: null,
// 重新分析按钮提交态
reAnalyzeLoadingMap: {},
}; };
}, },
created() { created() {
@@ -267,52 +263,22 @@ export default {
this.addDialogTitle = "创建高风险专项项目"; this.addDialogTitle = "创建高风险专项项目";
this.addDialogVisible = true; this.addDialogVisible = true;
}, },
/** 进入项目 */ /** 打开项目 */
handleEnter(row) { handleOpenProject(row) {
if (this.queryParams.includeDeleted) {
return
}
this.$router.push({ this.$router.push({
path: `/ccdiProject/detail/${row.projectId}`, path: `/ccdiProject/detail/${row.projectId}`,
query: { tab: this.canOperate(row) ? "upload" : "overview" }, query: { tab: this.resolveProjectEntryTab(row) },
});
// this.$modal.msgSuccess("进入项目: " + row.projectName);
},
/** 查看结果 */
handleViewResult(row) {
this.$router.push({
path: `/ccdiProject/detail/${row.projectId}`,
query: { tab: "overview" },
}); });
}, },
/** 重新分析 */ resolveProjectEntryTab(row) {
async handleReAnalyze(row) { const status = row && row.status !== undefined ? String(row.status) : ""
if (!this.canOperate(row)) { if (row && row.canOperate === false) {
this.$modal.msgWarning("当前项目仅可查看,不能重新分析") return "overview"
return
}
const projectKey = String(row.projectId)
if (this.reAnalyzeLoadingMap[projectKey]) {
return
}
try {
await this.$modal.confirm(
`确认对项目“${row.projectName}”重新分析吗?重新分析将重新计算项目标签。`
)
} catch (confirmError) {
if (confirmError === "cancel" || confirmError === "close") {
return
}
throw confirmError
}
this.$set(this.reAnalyzeLoadingMap, projectKey, true)
try {
await rebuildProjectTags({ projectId: row.projectId })
this.$modal.msgSuccess("已开始重新分析")
this.getList()
} catch (error) {
const message = error && error.message ? error.message : "重新分析失败,请稍后重试"
this.$modal.msgError(message)
} finally {
this.$set(this.reAnalyzeLoadingMap, projectKey, false)
} }
return ["1", "2"].includes(status) ? "overview" : "upload"
}, },
/** 归档项目 */ /** 归档项目 */
handleArchive(row) { handleArchive(row) {