| | |
| | | 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) { |
| | |
| | | // 加载项目详情 |
| | | 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 |
| | |
| | | avatarUrl |
| | | avatar { |
| | | id |
| | | fullUrl |
| | | fullThumbUrl |
| | | name |
| | | fileSize |
| | | fileExt |
| | | path |
| | | } |
| | | userInfo { |
| | | userId |
| | | name |
| | | phone |
| | | avatarUrl |
| | | avatar { |
| | | id |
| | | name |
| | | path |
| | | } |
| | | } |
| | | } |
| | | regionInfo { |
| | |
| | | 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 |
| | | } |
| | | } |
| | | } |
| | |
| | | } |
| | | }, |
| | | |
| | | 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 |
| | |
| | | ` |
| | | |
| | | 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 |
| | | }) |
| | | }, |
| | | |
| | |
| | | // 获取性别文本 |
| | | getGenderText(gender) { |
| | | const genderMap = { |
| | | 1: '男', |
| | | 2: '女', |
| | | 'MALE': '男', |
| | | 'FEMALE': '女' |
| | | } |
| | |
| | | 'COLLEGE': '大专', |
| | | 'BACHELOR': '本科', |
| | | 'MASTER': '硕士', |
| | | 'DOCTOR': '博士' |
| | | 'DOCTOR': '博士', |
| | | '高中及以下': '高中及以下', |
| | | '大专': '大专', |
| | | '本科': '本科', |
| | | '硕士': '硕士', |
| | | '博士': '博士' |
| | | } |
| | | return educationMap[education] || '' |
| | | return educationMap[education] || education || '' |
| | | }, |
| | | |
| | | // 分享功能 |
| | |
| | | path: `/pages/project/detail?id=${this.data.projectId}` |
| | | } |
| | | } |
| | | }) |
| | | }) |