lrj
4 天以前 4fa9591629721797386fc11836e3a9deb69cd58c
web/src/components/RatingForm.vue
@@ -2,8 +2,52 @@
  <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>
    
@@ -82,7 +126,8 @@
<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: {
@@ -92,6 +137,26 @@
  activityPlayerId: {
    type: [String, Number],
    required: true
  },
  // 新增:当前评委信息
  currentJudgeName: {
    type: String,
    default: ''
  },
  // 新增:所有评委评分状态
  judgeRatings: {
    type: Array,
    default: () => []
  },
  // 新增:平均分
  averageScore: {
    type: Number,
    default: null
  },
  // 新增:当前评委的已有评分
  existingRating: {
    type: Object,
    default: null
  }
})
@@ -110,8 +175,19 @@
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
  }
}
@@ -185,6 +261,11 @@
watch(() => props.ratingForm, () => {
  initScores()
}, { immediate: true })
// 监听已有评分变化,重新初始化
watch(() => props.existingRating, () => {
  initScores()
}, { immediate: true })
</script>
<style scoped>
@@ -196,19 +277,29 @@
}
.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 {
@@ -220,6 +311,69 @@
  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;
}