优化学员:移除无真实依据的个人雷达评分展示

This commit is contained in:
wangzhibiao committed 2026-09-20 20:36:40 +08:00
1 parent 207491213b
commit 48e94aa889
1 file changed
+74 -58
+74 -58
View File
@@ -227,20 +227,77 @@
</el-table>
</el-tab-pane>
<!-- Tab 5: 多维能力画像 -->
<el-tab-pane label="个人画像" name="portrait">
<!-- Tab 5: 学员客观概况 (取代无量纲依据的伪雷达图) -->
<el-tab-pane label="学业与纪律概况" name="portrait">
<div class="tab-header">
<div class="header-desc">
<i class="el-icon-data-analysis" /> 多维能力成长画像(真实能力模型分析)
<i class="el-icon-data-analysis" /> 个人培训全生命周期客观表现全景(严格展示真实事实,无算法虚假评分)
</div>
<el-button icon="el-icon-refresh" size="mini" plain @click="loadPortrait">刷新</el-button>
</div>
<div v-loading="portraitLoading" style="margin-top: 20px;">
<div v-if="hasPortraitData" class="portrait-container">
<div ref="radarChart" style="width: 100%; height: 380px;" />
</div>
<el-empty v-else description="暂无综合能力画像数据(待培训考核评估完成后生成)" :image-size="90" />
<!-- 考勤与参训客观事实 -->
<el-row :gutter="16">
<el-col :xs="24" :sm="12">
<el-card shadow="never" class="box-card">
<div slot="header" class="clearfix">
<span><i class="el-icon-time" style="color: #67C23A;" /> 课堂考勤打卡事实</span>
</div>
<div style="padding: 10px 0;">
<p><b>正常出勤打卡:</b>{{ attendanceNormalCount }} 次</p>
<p><b>异常打卡流水:</b>{{ attendanceAbnormalCount }} 次(迟到/早退/请假/缺勤)</p>
<p><b>应出勤总课次:</b>{{ timetableList.length }} 节</p>
</div>
</el-card>
</el-col>
<el-col :xs="24" :sm="12">
<el-card shadow="never" class="box-card">
<div slot="header" class="clearfix">
<span><i class="el-icon-collection" style="color: #409EFF;" /> 班级参训与开班报到</span>
</div>
<div style="padding: 10px 0;">
<p><b>当前参与班级:</b>{{ enrollmentList.length }} 个</p>
<p><b>开班报到确认:</b>
<el-tag size="mini" :type="reportDetail ? 'success' : 'info'">
{{ reportDetail ? '已完成报到' : '待确认报到' }}
</el-tag>
</p>
<p><b>累计已计学时:</b>{{ totalHours }} 小时</p>
</div>
</el-card>
</el-col>
</el-row>
<!-- 成绩与自学状态客观提示 -->
<el-row :gutter="16" style="margin-top: 16px;">
<el-col :xs="24" :sm="12">
<el-card shadow="never" class="box-card">
<div slot="header" class="clearfix">
<span><i class="el-icon-medal" style="color: #E6A23C;" /> 考核成绩状态</span>
</div>
<el-result icon="info" title="成绩暂未发布" sub-title="培训班级各考核项成绩正在录入评定中,待教务处审核后发布。">
<template slot="extra">
<el-tag size="small" type="info">待考务录入</el-tag>
</template>
</el-result>
</el-card>
</el-col>
<el-col :xs="24" :sm="12">
<el-card shadow="never" class="box-card">
<div slot="header" class="clearfix">
<span><i class="el-icon-reading" style="color: #67C23A;" /> 自主实训与学习平台</span>
</div>
<el-result icon="info" title="外部自学待同步" sub-title="在线学习与 VR 实训设备平台正在联调数据通道,学时流水将自动同步。">
<template slot="extra">
<el-tag size="small" type="warning">待平台联调</el-tag>
</template>
</el-result>
</el-card>
</el-col>
</el-row>
</div>
</el-tab-pane>
</el-tabs>
@@ -291,6 +348,14 @@ export default {
totalHours() {
if (!this.durationList || this.durationList.length === 0) return 0
return this.durationList.reduce((acc, cur) => acc + Number(cur.totalDurationHours || cur.duration || 0), 0)
},
attendanceNormalCount() {
if (!this.attendanceList || this.attendanceList.length === 0) return 0
return this.attendanceList.filter(i => i.checkinStatus === 1).length
},
attendanceAbnormalCount() {
if (!this.attendanceList || this.attendanceList.length === 0) return 0
return this.attendanceList.filter(i => i.checkinStatus != null && i.checkinStatus !== 1).length
}
},
created() {
@@ -398,64 +463,15 @@ export default {
getMyPortrait()
.then(res => {
this.portraitData = res.data
// 仅当后端返回真实有效实体且具有 portraitId 时才判定为有数据,杜绝伪造数据
if (this.portraitData && this.portraitData.portraitId) {
this.hasPortraitData = true
this.$nextTick(() => {
this.renderRadarChart()
})
} else {
this.hasPortraitData = false
}
this.portraitLoading = false
})
.catch(() => {
this.hasPortraitData = false
this.portraitData = null
this.portraitLoading = false
})
},
renderRadarChart() {
if (!this.$refs.radarChart) return
if (!this.chartInstance) {
this.chartInstance = echarts.init(this.$refs.radarChart)
}
const data = this.portraitData || {}
const option = {
title: {
text: (data.planName ? data.planName + ' · ' : '') + '综合成长能力画像',
left: 'center',
textStyle: { fontSize: 15, color: '#303133' }
},
tooltip: {},
radar: {
indicator: [
{ name: '出勤纪律(%)', max: 100 },
{ name: '理论成绩', max: 100 },
{ name: '实操成绩', max: 100 },
{ name: '学时评价', max: 100 }
],
radius: '65%'
},
series: [{
name: '能力评价',
type: 'radar',
data: [{
value: [
Number(data.attendanceRate || 0),
Number(data.theoryScore || 0),
Number(data.practicalScore || 0),
Number(data.totalStudyHour || 0)
],
name: '综合评分'
}]
}]
}
this.chartInstance.setOption(option)
},
handleResize() {
if (this.chartInstance) {
this.chartInstance.resize()
}
// 预留扩展
},
formatEnrollmentStatusText(status) {
const map = { 0: '待报到', 1: '已报到', 2: '请假', 3: '退训', 4: '已完成' }