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