Codex Assistant
1 天以前 c8dffd157cd8b62023b26e62a0b92c152d959423
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 })
    }
  },
  // 从API获取项目详情
  async getProjectDetailFromAPI(projectId) {
    // 构建GraphQL查询
    // 构建GraphQL查询 - 与后端schema匹配
    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
      })
    }
  },
  // 从API获取项目时间轴
  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}`
    }
  }
})
})