From 8337c34fcc761d07acaad796d10f3e12e9bbe2d1 Mon Sep 17 00:00:00 2001
From: lrj <owen.stl@gmail.com>
Date: 星期日, 05 十月 2025 08:56:04 +0800
Subject: [PATCH] feat: 微信项目详情支持阶段评分时间轴

---
 wx/pages/project/detail.js |  330 +++++++++++++++++++++++++++++++++++++++---------------
 1 files changed, 236 insertions(+), 94 deletions(-)

diff --git a/wx/pages/project/detail.js b/wx/pages/project/detail.js
index 9e95a97..6ce3629 100644
--- a/wx/pages/project/detail.js
+++ b/wx/pages/project/detail.js
@@ -5,12 +5,18 @@
   data: {
     projectId: '',
     projectDetail: null,
-    ratingStats: null,
+    timeline: [],
     loading: true,
     error: '',
     statusText: '',
     genderText: '',
-    educationText: ''
+    educationText: '',
+    timelineLoading: false,
+    timelineError: '',
+    showRatingDetail: false,
+    ratingDetail: null,
+    ratingDetailLoading: false,
+    ratingDetailError: ''
   },
 
   onLoad(options) {
@@ -30,51 +36,38 @@
   // 鍔犺浇椤圭洰璇︽儏
   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)
-          })
-        }
 
-        // 鑾峰彇璇勫垎缁熻
-        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
-        })
-      } else {
+      if (!projectDetail) {
         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 || '鍔犺浇澶辫触锛岃閲嶈瘯',
-        loading: false
+        error: error.message || '鍔犺浇澶辫触锛岃閲嶈瘯'
       })
+    } finally {
+      this.setData({ loading: false })
     }
   },
 
@@ -85,42 +78,62 @@
       query GetProjectDetail($id: ID!) {
         activityPlayerDetail(id: $id) {
           id
-          activityId
-          playerId
-          playerName
-          playerGender
-          playerPhone
-          playerEducation
-          playerBirthDate
-          playerIdCard
-          playerAddress
+          playerInfo {
+            id
+            name
+            phone
+            gender
+            birthday
+            education
+            introduction
+            description
+            avatarUrl
+            avatar {
+              id
+              fullUrl
+              fullThumbUrl
+              name
+              fileSize
+              fileExt
+            }
+            userInfo {
+              userId
+              name
+              phone
+              avatarUrl
+            }
+          }
+          regionInfo {
+            id
+            name
+            fullPath
+          }
+          activityName
           projectName
-          projectDescription
-          projectCategory
-          projectTags
-          projectFiles {
-            id
-            fileName
-            fileUrl
-            fileSize
-            fileType
-            uploadTime
-          }
-          submitTime
-          reviewTime
-          reviewerId
-          reviewerName
-          score
-          rating {
-            id
-            judgeId
-            judgeName
-            score
-            feedback
-            ratingTime
-          }
-          state
+          description
           feedback
+          state
+          stageId
+          submissionFiles {
+            id
+            fullUrl
+            fullThumbUrl
+            name
+            fileSize
+            fileExt
+            mediaType
+          }
+          ratingForm {
+            schemeId
+            schemeName
+            items {
+              id
+              name
+              maxScore
+              orderNo
+            }
+            totalMaxScore
+          }
         }
       }
     `
@@ -133,45 +146,174 @@
     }
   },
 
-  // 鑾峰彇璇勫垎缁熻
-  async getRatingStatsFromAPI(projectId) {
+  async loadProjectTimeline(activityPlayerId) {
+    if (!activityPlayerId) {
+      return
+    }
+
+    const idNumber = Number(activityPlayerId)
+    const variables = {
+      activityPlayerId: Number.isNaN(idNumber) ? activityPlayerId : idNumber
+    }
+
+    this.setData({
+      timelineLoading: true,
+      timelineError: ''
+    })
+
     const query = `
-      query GetRatingStats($activityPlayerId: ID!) {
-        ratingStats(activityPlayerId: $activityPlayerId) {
-          averageScore
-          totalRatings
-          scoreDistribution {
-            score
-            count
+      query ProjectStageTimeline($activityPlayerId: ID!) {
+        projectStageTimeline(activityPlayerId: $activityPlayerId) {
+          activityId
+          activityName
+          stages {
+            stageId
+            stageName
+            matchTime
+            sortOrder
+            participated
+            activityPlayerId
+            averageScore
+            ratingCount
+            hasRating
+            latestRatingTime
           }
         }
       }
     `
 
     try {
-      const result = await app.graphqlRequest(query, { activityPlayerId: projectId })
-      return result.ratingStats
+      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
+      })
     } catch (error) {
-      throw error
+      console.error('鍔犺浇闃舵鏃堕棿杞村け璐�:', error)
+      this.setData({
+        timelineError: error.message || '鏃堕棿杞村姞杞藉け璐�',
+        timelineLoading: false
+      })
     }
   },
 
-  // 鑾峰彇璇勫璇勫垎璇︽儏
-  async getJudgeRatingDetail(activityPlayerId, judgeId) {
+  async fetchStageRatingDetail(activityPlayerId) {
+    const idNumber = Number(activityPlayerId)
+    const variables = {
+      activityPlayerId: Number.isNaN(idNumber) ? activityPlayerId : idNumber
+    }
+
     const query = `
-      query GetJudgeRatingDetail($activityPlayerId: ID!, $judgeId: ID!) {
-        judgeRatingDetail(activityPlayerId: $activityPlayerId, judgeId: $judgeId) {
-          remark
+      query StageJudgeRatings($activityPlayerId: ID!) {
+        stageJudgeRatings(activityPlayerId: $activityPlayerId) {
+          activityPlayerId
+          stageId
+          stageName
+          matchTime
+          ratingCount
+          averageScore
+          judgeRatings {
+            judgeId
+            judgeName
+            totalScore
+            feedback
+            ratingTime
+          }
         }
       }
     `
 
-    try {
-      const result = await app.graphqlRequest(query, { activityPlayerId, judgeId })
-      return result.judgeRatingDetail
-    } catch (error) {
-      throw error
+    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) {
+      wx.showToast({
+        title: '鏆傛棤璇勫垎',
+        icon: 'none'
+      })
+      return
+    }
+
+    this.setData({
+      showRatingDetail: true,
+      ratingDetailLoading: true,
+      ratingDetailError: '',
+      ratingDetail: { judgeRatings: [] }
+    })
+
+    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: ''
+    })
   },
 
   // 棰勮鏂囦欢
@@ -455,4 +597,4 @@
       path: `/pages/project/detail?id=${this.data.projectId}`
     }
   }
-})
\ No newline at end of file
+})

--
Gitblit v1.8.0