From f04f35b562760afbac0c477357e2a29f77aec3b9 Mon Sep 17 00:00:00 2001 From: lrj <owen.stl@gmail.com> Date: 星期四, 02 十月 2025 13:51:47 +0800 Subject: [PATCH] fix: 修复评审次数重复显示问题 --- web/src/views/review-detail.vue | 150 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 146 insertions(+), 4 deletions(-) diff --git a/web/src/views/review-detail.vue b/web/src/views/review-detail.vue index f59bbe1..2dcace8 100644 --- a/web/src/views/review-detail.vue +++ b/web/src/views/review-detail.vue @@ -118,6 +118,7 @@ :step="0.5" size="small" style="width: 100%; margin-top: 8px;" + :disabled="!canModifyRating" /> </div> @@ -128,17 +129,29 @@ 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"> @@ -170,7 +183,9 @@ 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() @@ -185,8 +200,114 @@ 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韬唤锛屾鏌udge韬唤鍜屾潈闄� + 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 () => { @@ -202,6 +323,14 @@ score: 0 })) } + + // 椤圭洰璇︽儏鍔犺浇瀹屾垚鍚庯紝杩涜鏉冮檺楠岃瘉 + const hasPermission = await checkPermissions() + if (hasPermission) { + // 鏉冮檺楠岃瘉閫氳繃鍚庯紝鍔犺浇宸叉湁璇勫垎鏁版嵁 + await loadExistingRating() + } + } catch (error) { ElMessage.error('鍔犺浇椤圭洰璇︽儏澶辫触') console.error(error) @@ -222,6 +351,18 @@ // 鎻愪氦璇勫垎 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) { @@ -239,7 +380,8 @@ 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 -- Gitblit v1.8.0