From c8dffd157cd8b62023b26e62a0b92c152d959423 Mon Sep 17 00:00:00 2001
From: Codex Assistant <codex@example.com>
Date: 星期三, 08 十月 2025 21:19:28 +0800
Subject: [PATCH] build(backend): switch to thin-jar layout (split libs into target/lib); chore: remove test-* files; misc updates

---
 wx/pages/project/detail.js |  362 ++++++++++++++++++++++++++-------------------------
 1 files changed, 187 insertions(+), 175 deletions(-)

diff --git a/wx/pages/project/detail.js b/wx/pages/project/detail.js
index 6ce3629..779d642 100644
--- a/wx/pages/project/detail.js
+++ b/wx/pages/project/detail.js
@@ -5,18 +5,18 @@
   data: {
     projectId: '',
     projectDetail: null,
-    timeline: [],
+    ratingStats: null,
     loading: true,
     error: '',
     statusText: '',
     genderText: '',
     educationText: '',
+    // 鏃堕棿杞寸浉鍏虫暟鎹�
+    timeline: [],
     timelineLoading: false,
     timelineError: '',
     showRatingDetail: false,
-    ratingDetail: null,
-    ratingDetailLoading: false,
-    ratingDetailError: ''
+    ratingDetail: null
   },
 
   onLoad(options) {
@@ -36,48 +36,70 @@
   // 鍔犺浇椤圭洰璇︽儏
   async loadProjectDetail() {
     try {
-      this.setData({
-        loading: true,
-        error: ''
+      this.setData({ 
+        loading: true, 
+        error: '' 
       })
 
+      // 璋冪敤API鑾峰彇椤圭洰璇︽儏
       const projectDetail = await this.getProjectDetailFromAPI(this.data.projectId)
+      
+      if (projectDetail) {
+        // 澶勭悊鏂囦欢澶у皬鏄剧ず
+        if (projectDetail.submissionFiles) {
+          projectDetail.submissionFiles.forEach(file => {
+            file.fileSizeText = this.formatFileSize(file.fileSize)
+          })
+        }
 
-      if (!projectDetail) {
+        // 鑾峰彇璇勫垎缁熻
+        const ratingStats = await this.getRatingStatsFromAPI(this.data.projectId)
+        
+        // 澶勭悊璇勫垎鏃堕棿鏄剧ず
+        if (ratingStats && ratingStats.judgeRatings) {
+          ratingStats.judgeRatings.forEach(rating => {
+            if (rating.ratingTime) {
+              rating.ratingTimeText = this.formatDateTime(rating.ratingTime)
+            }
+          })
+        }
+
+        this.setData({
+          projectDetail,
+          ratingStats,
+          statusText: this.getStatusText(projectDetail.state),
+          genderText: this.getGenderText(projectDetail.playerInfo?.gender),
+          educationText: this.getEducationText(projectDetail.playerInfo?.education),
+          loading: false
+        })
+
+        // 鍔犺浇鏃堕棿杞存暟鎹�
+        this.loadProjectTimeline()
+      } else {
         throw new Error('椤圭洰璇︽儏鑾峰彇澶辫触')
       }
-
-      if (projectDetail.submissionFiles) {
-        projectDetail.submissionFiles.forEach(file => {
-          file.fileSizeText = this.formatFileSize(file.fileSize)
-        })
-      }
-
-      this.setData({
-        projectDetail,
-        statusText: this.getStatusText(projectDetail.state),
-        genderText: this.getGenderText(projectDetail.playerInfo?.gender),
-        educationText: this.getEducationText(projectDetail.playerInfo?.education)
-      })
-
-      await this.loadProjectTimeline(this.data.projectId)
     } catch (error) {
       console.error('鍔犺浇椤圭洰璇︽儏澶辫触:', error)
       this.setData({
-        error: error.message || '鍔犺浇澶辫触锛岃閲嶈瘯'
+        error: error.message || '鍔犺浇澶辫触锛岃閲嶈瘯',
+        loading: false
       })
-    } finally {
-      this.setData({ loading: false })
     }
   },
 
   // 浠嶢PI鑾峰彇椤圭洰璇︽儏
   async getProjectDetailFromAPI(projectId) {
-    // 鏋勫缓GraphQL鏌ヨ
+    // 鏋勫缓GraphQL鏌ヨ - 涓庡悗绔痵chema鍖归厤
     const query = `
       query GetProjectDetail($id: ID!) {
         activityPlayerDetail(id: $id) {
           id
+          activityName
+          projectName
+          description
+          feedback
+          state
+          stageId
           playerInfo {
             id
             name
@@ -90,17 +112,19 @@
             avatarUrl
             avatar {
               id
-              fullUrl
-              fullThumbUrl
               name
-              fileSize
-              fileExt
+              path
             }
             userInfo {
               userId
               name
               phone
               avatarUrl
+              avatar {
+                id
+                name
+                path
+              }
             }
           }
           regionInfo {
@@ -108,31 +132,27 @@
             name
             fullPath
           }
-          activityName
-          projectName
-          description
-          feedback
-          state
-          stageId
           submissionFiles {
             id
+            name
+            path
+            url
             fullUrl
             fullThumbUrl
-            name
-            fileSize
             fileExt
-            mediaType
+            fileSize
+            thumbUrl
           }
           ratingForm {
             schemeId
             schemeName
+            totalMaxScore
             items {
               id
               name
               maxScore
-              orderNo
+              weight
             }
-            totalMaxScore
           }
         }
       }
@@ -146,23 +166,108 @@
     }
   },
 
-  async loadProjectTimeline(activityPlayerId) {
-    if (!activityPlayerId) {
-      return
-    }
-
-    const idNumber = Number(activityPlayerId)
-    const variables = {
-      activityPlayerId: Number.isNaN(idNumber) ? activityPlayerId : idNumber
-    }
-
-    this.setData({
-      timelineLoading: true,
-      timelineError: ''
-    })
-
+  // 鑾峰彇璇勫垎缁熻
+  async getRatingStatsFromAPI(projectId) {
     const query = `
-      query ProjectStageTimeline($activityPlayerId: ID!) {
+      query GetRatingStats($activityPlayerId: ID!) {
+        judgeRatingsForPlayer(activityPlayerId: $activityPlayerId) {
+          judgeId
+          judgeName
+          hasRated
+          totalScore
+          ratingTime
+        }
+        averageScoreForPlayer(activityPlayerId: $activityPlayerId)
+      }
+    `
+
+    try {
+      const result = await app.graphqlRequest(query, { activityPlayerId: projectId })
+      const ratings = result.judgeRatingsForPlayer || []
+      const averageScore = result.averageScoreForPlayer || 0
+      
+      // 鍙绠楀凡璇勫垎鐨勮瘎濮�
+      const ratedJudges = ratings.filter(rating => rating.hasRated)
+      
+      return {
+        averageScore: averageScore,
+        totalRatings: ratedJudges.length,
+        ratings: ratings
+      }
+    } catch (error) {
+      throw error
+    }
+  },
+
+  // 鑾峰彇璇勫璇勫垎璇︽儏
+  async getJudgeRatingDetail(activityPlayerId, judgeId) {
+    const query = `
+      query GetJudgeRatingDetail($activityPlayerId: ID!, $judgeId: ID!) {
+        judgeRatingDetail(activityPlayerId: $activityPlayerId, judgeId: $judgeId) {
+          remark
+        }
+      }
+    `
+
+    try {
+      const result = await app.graphqlRequest(query, { activityPlayerId, judgeId })
+      return result.judgeRatingDetail
+    } catch (error) {
+      throw error
+    }
+  },
+
+  // 鍔犺浇椤圭洰鏃堕棿杞�
+  async loadProjectTimeline() {
+    try {
+      this.setData({ 
+        timelineLoading: true, 
+        timelineError: '' 
+      })
+
+      const timeline = await this.getProjectTimelineFromAPI(this.data.projectId)
+      
+      if (timeline && timeline.stages) {
+        // 澶勭悊鏃堕棿杞存暟鎹�
+        const processedTimeline = timeline.stages.map(stage => {
+          return {
+            stageId: stage.stageId,
+            stageName: stage.stageName,
+            matchTime: stage.matchTime,
+            matchTimeText: stage.matchTime ? this.formatDateTime(stage.matchTime) : '鏃堕棿寰呭畾',
+            participated: stage.participated,
+            activityPlayerId: stage.activityPlayerId,
+            averageScore: stage.averageScore,
+            ratingCount: stage.ratingCount,
+            hasRating: stage.hasRating,
+            scoreText: stage.averageScore ? `${stage.averageScore.toFixed(1)}鍒哷 : '',
+            isClickable: stage.hasRating && stage.activityPlayerId
+          }
+        })
+
+        this.setData({
+          timeline: processedTimeline,
+          timelineLoading: false
+        })
+      } else {
+        this.setData({
+          timeline: [],
+          timelineLoading: false
+        })
+      }
+    } catch (error) {
+      console.error('鍔犺浇鏃堕棿杞村け璐�:', error)
+      this.setData({
+        timelineError: error.message || '鏃堕棿杞村姞杞藉け璐�',
+        timelineLoading: false
+      })
+    }
+  },
+
+  // 浠嶢PI鑾峰彇椤圭洰鏃堕棿杞�
+  async getProjectTimelineFromAPI(activityPlayerId) {
+    const query = `
+      query GetProjectTimeline($activityPlayerId: ID!) {
         projectStageTimeline(activityPlayerId: $activityPlayerId) {
           activityId
           activityName
@@ -183,136 +288,36 @@
     `
 
     try {
-      const result = await app.graphqlRequest(query, variables)
-      const projectStageTimeline = result && result.projectStageTimeline ? result.projectStageTimeline : null
-      const stages = projectStageTimeline && projectStageTimeline.stages ? projectStageTimeline.stages : []
-
-      const timeline = stages.map(stage => {
-        const hasScore = stage.hasRating && stage.averageScore !== null && stage.averageScore !== undefined
-        let scoreText = '鏈弬璧�'
-        if (stage.participated) {
-          scoreText = hasScore ? `骞冲潎鍒嗭細${Number(stage.averageScore).toFixed(2)}` : '鏈瘎鍒�'
-        }
-
-        return {
-          ...stage,
-          matchTimeText: stage.matchTime ? this.formatDateTime(stage.matchTime) : '',
-          scoreText,
-          displayAverageScore: hasScore ? Number(stage.averageScore).toFixed(2) : null,
-          isClickable: stage.participated && hasScore && !!stage.activityPlayerId
-        }
-      })
-
-      this.setData({
-        timeline,
-        timelineLoading: false
-      })
+      const result = await app.graphqlRequest(query, { activityPlayerId })
+      return result.projectStageTimeline
     } catch (error) {
-      console.error('鍔犺浇闃舵鏃堕棿杞村け璐�:', error)
-      this.setData({
-        timelineError: error.message || '鏃堕棿杞村姞杞藉け璐�',
-        timelineLoading: false
-      })
+      throw error
     }
   },
 
-  async fetchStageRatingDetail(activityPlayerId) {
-    const idNumber = Number(activityPlayerId)
-    const variables = {
-      activityPlayerId: Number.isNaN(idNumber) ? activityPlayerId : idNumber
-    }
-
-    const query = `
-      query StageJudgeRatings($activityPlayerId: ID!) {
-        stageJudgeRatings(activityPlayerId: $activityPlayerId) {
-          activityPlayerId
-          stageId
-          stageName
-          matchTime
-          ratingCount
-          averageScore
-          judgeRatings {
-            judgeId
-            judgeName
-            totalScore
-            feedback
-            ratingTime
-          }
-        }
-      }
-    `
-
-    const result = await app.graphqlRequest(query, variables)
-    const detail = result && result.stageJudgeRatings ? result.stageJudgeRatings : null
-
-    const sourceJudgeRatings = detail && detail.judgeRatings ? detail.judgeRatings : []
-    const judgeRatings = sourceJudgeRatings.map(item => ({
-      ...item,
-      totalScoreText: item.totalScore !== null && item.totalScore !== undefined ? `${Number(item.totalScore).toFixed(2)}鍒哷 : '鏈瘎鍒�',
-      ratingTimeText: item.ratingTime ? this.formatDateTime(item.ratingTime) : ''
-    }))
-
-    const averageScoreValue = detail && detail.averageScore !== undefined && detail.averageScore !== null
-      ? detail.averageScore
-      : null
-
-    return {
-      activityPlayerId: detail && detail.activityPlayerId ? detail.activityPlayerId : variables.activityPlayerId,
-      stageId: detail && detail.stageId ? detail.stageId : null,
-      stageName: detail && detail.stageName ? detail.stageName : '闃舵淇℃伅',
-      matchTime: detail && detail.matchTime ? detail.matchTime : null,
-      matchTimeText: detail && detail.matchTime ? this.formatDateTime(detail.matchTime) : '',
-      ratingCount: detail && detail.ratingCount ? detail.ratingCount : 0,
-      averageScore: averageScoreValue,
-      averageScoreText: averageScoreValue !== null ? Number(averageScoreValue).toFixed(2) : '鏆傛棤璇勫垎',
-      judgeRatings
-    }
-  },
-
-  async openStageDetail(e) {
-    const { playerId } = e.currentTarget.dataset
-    const clickable = e.currentTarget.dataset.clickable === true || e.currentTarget.dataset.clickable === 'true'
-    const participated = e.currentTarget.dataset.participated === true || e.currentTarget.dataset.participated === 'true'
-
-    if (!playerId || !participated) {
-      return
-    }
-
-    if (!clickable) {
+  // 鎵撳紑闃舵璇︽儏
+  openStageDetail(e) {
+    const { playerId, clickable, participated } = e.currentTarget.dataset
+    
+    if (!clickable || !participated || !playerId) {
       wx.showToast({
-        title: '鏆傛棤璇勫垎',
+        title: '鏆傛棤璇勫垎璇︽儏',
         icon: 'none'
       })
       return
     }
 
-    this.setData({
-      showRatingDetail: true,
-      ratingDetailLoading: true,
-      ratingDetailError: '',
-      ratingDetail: { judgeRatings: [] }
+    // 璺宠浆鍒拌瘎鍒嗚鎯呴〉闈㈡垨鏄剧ず璇︽儏寮圭獥
+    wx.navigateTo({
+      url: `/pages/review/stage-detail?playerId=${playerId}`
     })
-
-    try {
-      const detail = await this.fetchStageRatingDetail(playerId)
-      this.setData({
-        ratingDetail: detail,
-        ratingDetailLoading: false
-      })
-    } catch (error) {
-      console.error('鍔犺浇闃舵璇勫垎璇︽儏澶辫触:', error)
-      this.setData({
-        ratingDetailError: error.message || '鍔犺浇澶辫触',
-        ratingDetailLoading: false
-      })
-    }
   },
 
+  // 鍏抽棴闃舵璇︽儏
   closeStageDetail() {
     this.setData({
       showRatingDetail: false,
-      ratingDetail: null,
-      ratingDetailError: ''
+      ratingDetail: null
     })
   },
 
@@ -572,6 +577,8 @@
   // 鑾峰彇鎬у埆鏂囨湰
   getGenderText(gender) {
     const genderMap = {
+      1: '鐢�',
+      2: '濂�',
       'MALE': '鐢�',
       'FEMALE': '濂�'
     }
@@ -585,9 +592,14 @@
       'COLLEGE': '澶т笓',
       'BACHELOR': '鏈',
       'MASTER': '纭曞+',
-      'DOCTOR': '鍗氬+'
+      'DOCTOR': '鍗氬+',
+      '楂樹腑鍙婁互涓�': '楂樹腑鍙婁互涓�',
+      '澶т笓': '澶т笓',
+      '鏈': '鏈',
+      '纭曞+': '纭曞+',
+      '鍗氬+': '鍗氬+'
     }
-    return educationMap[education] || ''
+    return educationMap[education] || education || ''
   },
 
   // 鍒嗕韩鍔熻兘
@@ -597,4 +609,4 @@
       path: `/pages/project/detail?id=${this.data.projectId}`
     }
   }
-})
+})
\ No newline at end of file

--
Gitblit v1.8.0