Files
ccdi/ruoyi-ui/src/views/ccdiProject/components/ProjectTable.vue

393 lines
8.6 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<div class="project-table-container">
<el-table
v-loading="loading"
:data="dataList"
style="width: 100%"
>
<el-table-column
label="项目名称"
min-width="180"
align="left"
>
<template slot-scope="scope">
<div class="project-info-cell">
<div class="project-name">{{ scope.row.projectName }}</div>
<div class="project-desc">{{ scope.row.description || "暂无描述" }}</div>
</div>
</template>
</el-table-column>
<el-table-column
prop="updateTime"
label="更新/创建时间"
width="180"
align="center"
>
<template slot-scope="scope">
<span>{{ parseTime(scope.row.updateTime || scope.row.createTime) }}</span>
</template>
</el-table-column>
<el-table-column
prop="createByName"
label="创建人"
width="120"
align="center"
/>
<el-table-column
prop="status"
label="状态"
width="120"
align="center"
>
<template slot-scope="scope">
<div class="status-tag">
<span class="status-dot" :style="{ color: getStatusColor(scope.row.status) }"></span>
<dict-tag :options="dict.type.ccdi_project_status" :value="scope.row.status" />
</div>
</template>
</el-table-column>
<el-table-column
prop="targetCount"
label="目标人数"
width="100"
align="center"
/>
<el-table-column
label="预警人数"
width="120"
align="center"
>
<template slot-scope="scope">
<el-tooltip placement="top" effect="light">
<div slot="content">
<div class="risk-tooltip">
<div class="risk-tooltip-title">风险人数统计</div>
<div class="risk-tooltip-item risk-tooltip-item--high">
<span> 高风险</span>
<span class="risk-tooltip-count">{{ scope.row.highRiskCount }} </span>
</div>
<div class="risk-tooltip-item risk-tooltip-item--medium">
<span> 中风险</span>
<span class="risk-tooltip-count">{{ scope.row.mediumRiskCount }} </span>
</div>
<div class="risk-tooltip-item risk-tooltip-item--low">
<span> 低风险</span>
<span class="risk-tooltip-count">{{ scope.row.lowRiskCount }} </span>
</div>
</div>
</div>
<div class="warning-count-wrapper">
<span :class="getWarningClass(scope.row)" class="warning-count">
{{ scope.row.highRiskCount + scope.row.mediumRiskCount + scope.row.lowRiskCount }}
</span>
</div>
</el-tooltip>
</template>
</el-table-column>
<el-table-column
label="操作"
width="350"
align="left"
fixed="right"
>
<template slot-scope="scope">
<el-button
v-if="['0', '3', '4'].includes(scope.row.status)"
size="mini"
type="text"
icon="el-icon-right"
@click="handleEnter(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
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
size="mini"
type="text"
icon="el-icon-folder"
@click="handleArchive(scope.row)"
>
归档
</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>
</template>
</el-table-column>
</el-table>
<el-pagination
v-show="total > 0"
:current-page="pageParams.pageNum"
:page-size="pageParams.pageSize"
:page-sizes="[10, 20, 30, 50]"
:total="total"
layout="total, sizes, prev, pager, next, jumper"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
style="margin-top: 16px; text-align: right"
/>
</div>
</template>
<script>
export default {
name: "ProjectTable",
dicts: ["ccdi_project_status", "ccdi_config_type"],
props: {
dataList: {
type: Array,
default: () => [],
},
loading: {
type: Boolean,
default: false,
},
total: {
type: Number,
default: 0,
},
pageParams: {
type: Object,
default: () => ({
pageNum: 1,
pageSize: 10,
}),
},
reAnalyzeLoadingMap: {
type: Object,
default: () => ({}),
},
},
methods: {
getStatusColor(status) {
const colorMap = {
0: "#1890ff",
1: "#52c41a",
2: "#8c8c8c",
3: "#fa8c16",
4: "#f56c6c",
};
return colorMap[status] || "#8c8c8c";
},
getWarningClass(row) {
const total = row.highRiskCount + row.mediumRiskCount + row.lowRiskCount;
if (row.highRiskCount > 0) {
return "text-danger text-bold";
}
if (row.mediumRiskCount > 0) {
return "text-warning text-bold";
}
if (total > 0) {
return "text-info";
}
return "";
},
handleEnter(row) {
this.$emit("enter", row);
},
handleViewResult(row) {
this.$emit("view-result", row);
},
handleReAnalyze(row) {
this.$emit("re-analyze", row);
},
handleArchive(row) {
this.$emit("archive", row);
},
handleSizeChange(val) {
this.$emit("pagination", {
pageNum: this.pageParams.pageNum,
pageSize: val,
});
},
handleCurrentChange(val) {
this.$emit("pagination", {
pageNum: val,
pageSize: this.pageParams.pageSize,
});
},
},
};
</script>
<style lang="scss" scoped>
.project-table-container {
margin-top: 16px;
:deep(.el-table) {
box-shadow: var(--ccdi-shadow);
}
}
.status-tag {
display: inline-flex;
align-items: center;
gap: 6px;
.status-dot {
font-size: 10px;
line-height: 1;
}
}
.project-info-cell {
padding: 4px 0;
line-height: 1.4;
.project-name {
font-size: 14px;
font-weight: 600;
color: var(--ccdi-text-primary);
margin-bottom: 2px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.project-desc {
font-size: 12px;
color: var(--ccdi-text-muted);
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
.risk-tooltip {
padding: 8px;
}
.risk-tooltip-title {
margin-bottom: 8px;
font-weight: 600;
color: var(--ccdi-text-primary);
}
.risk-tooltip-item {
margin-bottom: 6px;
}
.risk-tooltip-item--high {
color: #b55252;
}
.risk-tooltip-item--medium {
color: #a56a2a;
}
.risk-tooltip-item--low {
color: #6c7a89;
}
.risk-tooltip-count {
font-weight: 600;
}
.warning-count-wrapper {
display: inline-block;
}
.warning-count {
cursor: pointer;
}
.text-danger {
color: #f56c6c;
}
.text-warning {
color: #e6a23c;
}
.text-info {
color: #909399;
}
.text-bold {
font-weight: 700;
}
::v-deep .el-button--text {
color: #1890ff;
padding: 8px 12px;
border-radius: 4px;
transition: all 0.2s ease;
&:hover {
color: #096dd9;
background-color: rgba(24, 144, 255, 0.08);
text-decoration: none;
}
&:first-child {
padding-left: 0;
}
& + .el-button--text {
margin-left: 4px;
}
}
::v-deep .el-pagination {
margin-top: 24px;
text-align: right;
.btn-prev,
.btn-next,
.el-pager li {
border: none;
background-color: transparent;
&:hover {
background-color: #f5f5f5;
}
}
.el-pager li.active {
background-color: #1890ff;
color: #fff;
border-radius: 4px;
}
.el-pagination__total,
.el-pagination__sizes,
.el-pagination__jump {
color: #666;
}
}
</style>