| | |
| | | :step="0.5" |
| | | size="small" |
| | | style="width: 100%; margin-top: 8px;" |
| | | :disabled="!canModifyRating" |
| | | /> |
| | | </div> |
| | | |
| | |
| | | v-model="ratingComment" |
| | | type="textarea" |
| | | :rows="4" |
| | | placeholder="请输入评语(可选)" |
| | | :placeholder="canModifyRating ? '请输入评语(可选)' : '评语(只读)'" |
| | | maxlength="500" |
| | | show-word-limit |
| | | :disabled="!canModifyRating" |
| | | /> |
| | | </div> |
| | | |
| | | <!-- 提交按钮 --> |
| | | <div class="submit-section"> |
| | | <div class="submit-section" v-if="canModifyRating"> |
| | | <el-button type="primary" @click="handleSubmitRating" :loading="submitting" style="width: 100%;"> |
| | | 提交评分 |
| | | </el-button> |
| | | </div> |
| | | |
| | | <!-- Employee用户提示 --> |
| | | <div class="readonly-notice" v-if="isEmployee && !canModifyRating"> |
| | | <el-alert |
| | | title="只读模式" |
| | | description="您以员工身份查看此评审详情,只能查看不能修改评分" |
| | | type="info" |
| | | :closable="false" |
| | | show-icon |
| | | /> |
| | | </div> |
| | | </div> |
| | | <div v-else class="no-template"> |
| | |
| | | import { useRoute, useRouter } from 'vue-router' |
| | | import { ElMessage, ElMessageBox } from 'element-plus' |
| | | import { Document, UserFilled } from '@element-plus/icons-vue' |
| | | import { getProjectDetail, getRatingStats, submitRating } from '@/api/projectReview' |
| | | import { getProjectDetail, getRatingStats, submitRating, getCurrentJudgeRating } from '@/api/projectReview' |
| | | import { userApi } from '@/api/user' |
| | | import { getUserInfo } from '@/utils/auth' |
| | | |
| | | const route = useRoute() |
| | | const router = useRouter() |
| | |
| | | const previewVisible = ref(false) |
| | | const previewUrl = ref('') |
| | | |
| | | // 权限验证相关 |
| | | const currentJudge = ref(null) |
| | | const hasJudgePermission = ref(false) |
| | | const isJudgeInActivity = ref(false) |
| | | const permissionChecked = ref(false) |
| | | const existingRating = ref(null) |
| | | const isEmployee = ref(false) |
| | | const canModifyRating = ref(false) |
| | | |
| | | // 计算属性 |
| | | const projectId = computed(() => route.params.id) |
| | | const stageId = computed(() => route.query.stageId) |
| | | |
| | | // 权限验证方法 |
| | | const checkPermissions = async () => { |
| | | try { |
| | | // 获取当前用户信息 |
| | | const userInfo = getUserInfo() |
| | | |
| | | if (!userInfo) { |
| | | ElMessage.error('用户信息获取失败,请重新登录') |
| | | router.push('/project-review') |
| | | return false |
| | | } |
| | | |
| | | // 检查是否有employee身份 |
| | | if (userInfo.employee) { |
| | | isEmployee.value = true |
| | | canModifyRating.value = false // employee只能查看,不能修改 |
| | | permissionChecked.value = true |
| | | ElMessage.info('您以员工身份查看评审详情,只能查看不能修改评分') |
| | | return true |
| | | } |
| | | |
| | | // 如果没有employee身份,检查judge身份和权限 |
| | | const judgeInfo = await userApi.getCurrentJudgeInfo() |
| | | |
| | | if (!judgeInfo) { |
| | | hasJudgePermission.value = false |
| | | ElMessage.error('您没有评委权限,无法进行评审') |
| | | router.push('/project-review') |
| | | return false |
| | | } |
| | | |
| | | currentJudge.value = judgeInfo |
| | | hasJudgePermission.value = true |
| | | |
| | | // 检查是否在当前比赛阶段的评委列表中 |
| | | if (projectDetail.value && projectDetail.value.stageId) { |
| | | const isInActivity = await userApi.checkJudgeInActivity( |
| | | projectDetail.value.stageId, |
| | | judgeInfo.judgeId |
| | | ) |
| | | |
| | | if (!isInActivity) { |
| | | isJudgeInActivity.value = false |
| | | ElMessage.error('您不是当前比赛的评委,无法进行评审') |
| | | router.push('/project-review') |
| | | return false |
| | | } |
| | | |
| | | isJudgeInActivity.value = true |
| | | canModifyRating.value = true // judge有权限修改评分 |
| | | } |
| | | |
| | | permissionChecked.value = true |
| | | return true |
| | | } catch (error) { |
| | | console.error('权限验证失败:', error) |
| | | hasJudgePermission.value = false |
| | | ElMessage.error('权限验证失败,请重新登录') |
| | | router.push('/project-review') |
| | | return false |
| | | } |
| | | } |
| | | |
| | | // 加载当前评委已有的评审数据 |
| | | const loadExistingRating = async () => { |
| | | // employee用户不需要加载评委的评分数据 |
| | | if (isEmployee.value || !hasJudgePermission.value) return |
| | | |
| | | try { |
| | | const rating = await getCurrentJudgeRating(parseInt(projectId.value)) |
| | | if (rating) { |
| | | existingRating.value = rating |
| | | |
| | | // 如果有已有评分,填充到表单中 |
| | | if (rating.items && rating.items.length > 0) { |
| | | ratingItems.value = rating.items.map(item => ({ |
| | | id: item.ratingItemId, |
| | | name: item.ratingItemName, |
| | | score: item.score, |
| | | maxScore: item.maxScore || 100 |
| | | })) |
| | | } |
| | | |
| | | // 填充评语 |
| | | if (rating.remark) { |
| | | ratingComment.value = rating.remark |
| | | } |
| | | |
| | | ElMessage.success('已加载您之前的评分数据,可以继续编辑') |
| | | } |
| | | } catch (error) { |
| | | console.error('加载已有评分失败:', error) |
| | | // 不显示错误消息,因为可能是第一次评分 |
| | | } |
| | | } |
| | | |
| | | // 加载项目详情 |
| | | const loadProjectDetail = async () => { |
| | |
| | | score: 0 |
| | | })) |
| | | } |
| | | |
| | | // 项目详情加载完成后,进行权限验证 |
| | | const hasPermission = await checkPermissions() |
| | | if (hasPermission) { |
| | | // 权限验证通过后,加载已有评分数据 |
| | | await loadExistingRating() |
| | | } |
| | | |
| | | } catch (error) { |
| | | ElMessage.error('加载项目详情失败') |
| | | console.error(error) |
| | |
| | | |
| | | // 提交评分 |
| | | const handleSubmitRating = async () => { |
| | | // 权限检查:employee用户不能提交评分 |
| | | if (!canModifyRating.value) { |
| | | ElMessage.error('您没有权限提交评分') |
| | | return |
| | | } |
| | | |
| | | // 验证stageId |
| | | if (!stageId.value) { |
| | | ElMessage.error('缺少比赛阶段信息,请重新进入页面') |
| | | return |
| | | } |
| | | |
| | | // 验证评分 |
| | | const hasEmptyScore = ratingItems.value.some(item => item.score === 0 || item.score === null) |
| | | if (hasEmptyScore) { |
| | |
| | | submitting.value = true |
| | | |
| | | const ratingData = { |
| | | activityPlayerId: projectId.value, |
| | | activityPlayerId: parseInt(projectId.value), |
| | | stageId: parseInt(stageId.value), |
| | | ratings: ratingItems.value.map(item => ({ |
| | | itemId: item.id, |
| | | score: item.score |