| | |
| | | <div class="rating-form"> |
| | | <div class="form-header"> |
| | | <h3>{{ ratingForm.schemeName || '评分表单' }}</h3> |
| | | <div class="total-score"> |
| | | 总分:{{ totalScore }} / {{ ratingForm.totalMaxScore }} |
| | | <div class="header-info"> |
| | | <div class="judge-info"> |
| | | <el-tag type="primary" size="large"> |
| | | <el-icon><User /></el-icon> |
| | | 当前评委:{{ currentJudgeName || '未知评委' }} |
| | | </el-tag> |
| | | </div> |
| | | <div class="total-score"> |
| | | 总分:{{ totalScore }} / {{ ratingForm.totalMaxScore }} |
| | | </div> |
| | | </div> |
| | | </div> |
| | | |
| | | <!-- 多评委评分状态 --> |
| | | <div v-if="judgeRatings && judgeRatings.length > 0" class="judge-ratings-status"> |
| | | <h4>评委评分状态</h4> |
| | | <div class="judge-status-list"> |
| | | <div |
| | | v-for="judgeRating in judgeRatings" |
| | | :key="judgeRating.judgeId" |
| | | class="judge-status-item" |
| | | :class="{ 'current-judge': judgeRating.isCurrentJudge }" |
| | | > |
| | | <div class="judge-name"> |
| | | <el-icon v-if="judgeRating.isCurrentJudge"><Star /></el-icon> |
| | | {{ judgeRating.judgeName }} |
| | | </div> |
| | | <div class="judge-score"> |
| | | <el-tag |
| | | :type="judgeRating.status === 1 ? 'success' : 'info'" |
| | | size="small" |
| | | > |
| | | {{ judgeRating.status === 1 ? `已评分: ${judgeRating.totalScore}分` : '未评分' }} |
| | | </el-tag> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | |
| | | <!-- 平均分显示 --> |
| | | <div v-if="averageScore !== null" class="average-score"> |
| | | <el-statistic |
| | | title="当前平均分" |
| | | :value="averageScore" |
| | | :precision="2" |
| | | suffix="分" |
| | | /> |
| | | </div> |
| | | </div> |
| | | |
| | |
| | | |
| | | <script setup> |
| | | import { ref, reactive, computed, watch } from 'vue' |
| | | import { ElForm, ElFormItem, ElInputNumber, ElInput, ElButton, ElMessage } from 'element-plus' |
| | | import { ElForm, ElFormItem, ElInputNumber, ElInput, ElButton, ElMessage, ElTag, ElIcon, ElStatistic } from 'element-plus' |
| | | import { User, Star } from '@element-plus/icons-vue' |
| | | |
| | | const props = defineProps({ |
| | | ratingForm: { |
| | |
| | | activityPlayerId: { |
| | | type: [String, Number], |
| | | required: true |
| | | }, |
| | | // 新增:当前评委信息 |
| | | currentJudgeName: { |
| | | type: String, |
| | | default: '' |
| | | }, |
| | | // 新增:所有评委评分状态 |
| | | judgeRatings: { |
| | | type: Array, |
| | | default: () => [] |
| | | }, |
| | | // 新增:平均分 |
| | | averageScore: { |
| | | type: Number, |
| | | default: null |
| | | }, |
| | | // 新增:当前评委的已有评分 |
| | | existingRating: { |
| | | type: Object, |
| | | default: null |
| | | } |
| | | }) |
| | | |
| | |
| | | const initScores = () => { |
| | | if (props.ratingForm.items) { |
| | | props.ratingForm.items.forEach(item => { |
| | | formData.scores[item.id] = null |
| | | // 如果有已有评分,则加载已有分数 |
| | | if (props.existingRating && props.existingRating.items) { |
| | | const existingItem = props.existingRating.items.find(ratingItem => ratingItem.ratingItemId === item.id) |
| | | formData.scores[item.id] = existingItem ? existingItem.score : null |
| | | } else { |
| | | formData.scores[item.id] = null |
| | | } |
| | | }) |
| | | } |
| | | |
| | | // 加载已有评语 |
| | | if (props.existingRating && props.existingRating.remark) { |
| | | formData.comment = props.existingRating.remark |
| | | } |
| | | } |
| | | |
| | |
| | | watch(() => props.ratingForm, () => { |
| | | initScores() |
| | | }, { immediate: true }) |
| | | |
| | | // 监听已有评分变化,重新初始化 |
| | | watch(() => props.existingRating, () => { |
| | | initScores() |
| | | }, { immediate: true }) |
| | | </script> |
| | | |
| | | <style scoped> |
| | |
| | | } |
| | | |
| | | .form-header { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | margin-bottom: 20px; |
| | | padding-bottom: 16px; |
| | | border-bottom: 1px solid #EBEEF5; |
| | | } |
| | | |
| | | .form-header h3 { |
| | | margin: 0; |
| | | margin: 0 0 12px 0; |
| | | color: #303133; |
| | | font-size: 18px; |
| | | font-weight: 600; |
| | | } |
| | | |
| | | .header-info { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | flex-wrap: wrap; |
| | | gap: 12px; |
| | | } |
| | | |
| | | .judge-info { |
| | | display: flex; |
| | | align-items: center; |
| | | } |
| | | |
| | | .total-score { |
| | |
| | | border-radius: 20px; |
| | | } |
| | | |
| | | .judge-ratings-status { |
| | | margin-bottom: 24px; |
| | | padding: 16px; |
| | | background: #F8F9FA; |
| | | border-radius: 8px; |
| | | border: 1px solid #E9ECEF; |
| | | } |
| | | |
| | | .judge-ratings-status h4 { |
| | | margin: 0 0 16px 0; |
| | | color: #303133; |
| | | font-size: 16px; |
| | | font-weight: 600; |
| | | } |
| | | |
| | | .judge-status-list { |
| | | display: grid; |
| | | grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); |
| | | gap: 12px; |
| | | margin-bottom: 16px; |
| | | } |
| | | |
| | | .judge-status-item { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | padding: 12px; |
| | | background: white; |
| | | border-radius: 6px; |
| | | border: 1px solid #E4E7ED; |
| | | transition: all 0.3s ease; |
| | | } |
| | | |
| | | .judge-status-item:hover { |
| | | border-color: #409EFF; |
| | | box-shadow: 0 2px 4px rgba(64, 158, 255, 0.1); |
| | | } |
| | | |
| | | .judge-status-item.current-judge { |
| | | border-color: #409EFF; |
| | | background: #ECF5FF; |
| | | } |
| | | |
| | | .judge-name { |
| | | display: flex; |
| | | align-items: center; |
| | | gap: 6px; |
| | | font-weight: 500; |
| | | color: #303133; |
| | | } |
| | | |
| | | .judge-score { |
| | | flex-shrink: 0; |
| | | } |
| | | |
| | | .average-score { |
| | | text-align: center; |
| | | padding: 16px; |
| | | background: white; |
| | | border-radius: 6px; |
| | | border: 1px solid #E4E7ED; |
| | | } |
| | | |
| | | .rating-items { |
| | | margin-bottom: 20px; |
| | | } |