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

289 lines
7.1 KiB
Vue
Raw Normal View History

2026-01-30 11:01:13 +08:00
<template>
<div class="project-table-container">
<el-table
:data="dataList"
:loading="loading"
border
style="width: 100%"
>
<!-- 项目名称含描述 -->
<el-table-column
label="项目名称"
min-width="300"
align="left"
2026-01-30 11:01:13 +08:00
>
<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>
2026-01-30 11:01:13 +08:00
<!-- 项目状态 -->
<el-table-column
prop="status"
label="项目状态"
width="160"
align="center"
>
<template slot-scope="scope">
<el-tag :type="getStatusType(scope.row.status)">
<dict-tag :options="dict.type.ccdi_project_status" :value="scope.row.status"/>
</el-tag>
</template>
</el-table-column>
2026-01-30 11:01:13 +08:00
<!-- 目标人数 -->
<el-table-column
prop="targetCount"
label="目标人数"
width="100"
align="center"
/>
2026-01-30 11:01:13 +08:00
<!-- 预警人数带悬停详情 -->
<el-table-column
label="预警人数"
width="120"
align="center"
>
<template slot-scope="scope">
<el-tooltip placement="top" effect="light">
<div slot="content">
<div style="padding: 8px;">
<div style="margin-bottom: 8px; font-weight: bold; color: #303133;">
风险人数统计
</div>
<div style="margin-bottom: 6px;">
<span style="color: #f56c6c;"> 高风险</span>
<span style="font-weight: bold;">{{ scope.row.highRiskCount }} </span>
</div>
<div style="margin-bottom: 6px;">
<span style="color: #e6a23c;"> 中风险</span>
<span style="font-weight: bold;">{{ scope.row.mediumRiskCount }} </span>
</div>
<div>
<span style="color: #909399;"> 低风险</span>
<span style="font-weight: bold;">{{ scope.row.lowRiskCount }} </span>
</div>
</div>
</div>
<div class="warning-count-wrapper">
<span :class="getWarningClass(scope.row)" style="cursor: pointer;">
{{ scope.row.highRiskCount + scope.row.mediumRiskCount + scope.row.lowRiskCount }}
</span>
</div>
</el-tooltip>
</template>
</el-table-column>
2026-01-30 11:01:13 +08:00
<!-- 创建人 -->
<el-table-column
prop="createByName"
label="创建人"
width="120"
align="center"
/>
2026-01-30 11:01:13 +08:00
<!-- 创建时间 -->
<el-table-column
prop="createTime"
label="创建时间"
width="160"
align="center"
>
<template slot-scope="scope">
<span>{{ parseTime(scope.row.createTime) }}</span>
</template>
</el-table-column>
2026-01-30 11:01:13 +08:00
<!-- 操作列 -->
<el-table-column
label="操作"
width="200"
align="center"
fixed="right"
>
<template slot-scope="scope">
<!-- 进行中状态 (status = '0') -->
<el-button
v-if="scope.row.status === '0'"
size="mini"
type="text"
icon="el-icon-right"
@click="handleEnter(scope.row)"
>进入项目</el-button>
<!-- 已完成状态 (status = '1') -->
<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"
@click="handleReAnalyze(scope.row)"
>重新分析</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-folder"
@click="handleArchive(scope.row)"
>归档</el-button>
</template>
<!-- 已归档状态 (status = '2') -->
<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>
2026-01-30 11:01:13 +08:00
<!-- 分页 -->
<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;"
/>
2026-01-30 11:01:13 +08:00
</div>
</template>
<script>
export default {
name: 'ProjectTable',
dicts: ['ccdi_project_status', 'ccdi_config_type'],
2026-01-30 11:01:13 +08:00
props: {
dataList: {
type: Array,
default: () => []
},
loading: {
type: Boolean,
default: false
},
2026-01-30 11:01:13 +08:00
total: {
type: Number,
default: 0
},
pageParams: {
type: Object,
default: () => ({
pageNum: 1,
pageSize: 10
})
}
},
methods: {
getStatusType(status) {
const statusMap = {
'0': 'primary', // 进行中
'1': 'success', // 已完成
'2': 'info' // 已归档
2026-01-30 11:01:13 +08:00
}
return statusMap[status] || 'info'
},
2026-01-30 11:01:13 +08:00
getWarningClass(row) {
const total = row.highRiskCount + row.mediumRiskCount + row.lowRiskCount
if (row.highRiskCount > 0) {
return 'text-danger text-bold'
} else if (row.mediumRiskCount > 0) {
return 'text-warning text-bold'
} else if (total > 0) {
return 'text-info'
}
return ''
2026-01-30 11:01:13 +08:00
},
handleEnter(row) {
this.$emit('enter', row)
},
handleViewResult(row) {
this.$emit('view-result', row)
2026-01-30 11:01:13 +08:00
},
handleReAnalyze(row) {
this.$emit('re-analyze', row)
2026-01-30 11:01:13 +08:00
},
handleArchive(row) {
this.$emit('archive', row)
2026-01-30 11:01:13 +08:00
},
2026-01-30 11:01:13 +08:00
handleSizeChange(val) {
this.$emit('pagination', { pageNum: this.pageParams.pageNum, pageSize: val })
2026-01-30 11:01:13 +08:00
},
2026-01-30 11:01:13 +08:00
handleCurrentChange(val) {
this.$emit('pagination', { pageNum: val, pageSize: this.pageParams.pageSize })
2026-01-30 11:01:13 +08:00
}
}
}
</script>
<style lang="scss" scoped>
.project-table-container {
margin-top: 16px;
2026-01-30 11:01:13 +08:00
}
.project-info-cell {
padding: 8px 0;
line-height: 1.5;
2026-01-30 11:01:13 +08:00
.project-name {
2026-01-30 11:01:13 +08:00
font-size: 14px;
font-weight: 600;
color: #303133;
margin-bottom: 4px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
2026-01-30 11:01:13 +08:00
}
.project-desc {
2026-01-30 11:01:13 +08:00
font-size: 12px;
color: #909399;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
2026-01-30 11:01:13 +08:00
}
}
.warning-count-wrapper {
display: inline-block;
2026-01-30 11:01:13 +08:00
}
.text-danger {
color: #f56c6c;
2026-01-30 11:01:13 +08:00
}
.text-warning {
color: #e6a23c;
2026-01-30 11:01:13 +08:00
}
.text-info {
color: #909399;
2026-01-30 11:01:13 +08:00
}
.text-bold {
font-weight: bold;
2026-01-30 11:01:13 +08:00
}
</style>