lrj
1 天以前 93eb6b470773bc49ea6e1a9d4cbd914eb95d525b
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
import { graphqlRequest } from '@/config/api'
 
// GraphQL 查询语句
 
// 获取进行中的比赛列表(包括阶段)
const GET_ACTIVE_ACTIVITIES_QUERY = `
  query GetActiveActivities {
    allActivities {
      id
      pid
      name
      state
      parent {
        id
        name
      }
    }
  }
`
 
// 获取比赛项目列表(分页)
const GET_COMPETITION_PROJECTS_QUERY = `
  query GetCompetitionProjects($activityId: ID, $page: Int, $size: Int) {
    activityPlayerApplications(activityId: $activityId, page: $page, size: $size) {
      id
      playerName
      activityName
      projectName
      phone
      applyTime
      state
    }
  }
`
 
// 获取项目详情
export const GET_PROJECT_DETAIL_QUERY = `
  query GetProjectDetail($id: ID!) {
    activityPlayerDetail(id: $id) {
      id
      playerInfo {
        id
        name
        phone
        gender
        education
        introduction
        avatarUrl
        birthday
      }
      regionInfo {
        name
      }
      activityName
      projectName
      description
      submissionFiles {
        id
        name
        url
        thumbUrl
        fileExt
        fileSize
        mediaType
      }
      ratingForm {
        schemeId
        schemeName
        totalMaxScore
        items {
          id
          name
          maxScore
          orderNo
        }
      }
      state
      feedback
    }
  }
`
 
// 获取评审统计信息
export const GET_RATING_STATS_QUERY = `
  query GetRatingStats($activityPlayerId: ID!) {
    judgeRatingsForPlayer(activityPlayerId: $activityPlayerId) {
      judgeId
      judgeName
      hasRated
      totalScore
      ratingTime
    }
    averageScoreForPlayer(activityPlayerId: $activityPlayerId)
  }
`
 
// 获取当前评委的评分信息
const GET_CURRENT_JUDGE_RATING_QUERY = `
  query GetCurrentJudgeRating($activityPlayerId: ID!) {
    currentJudgeRating(activityPlayerId: $activityPlayerId) {
      id
      totalScore
      comments
      ratingItems {
        itemId
        itemName
        score
        maxScore
      }
    }
  }
`
 
// 提交评分
const SUBMIT_RATING_MUTATION = `
  mutation SubmitRating($input: ActivityPlayerRatingInput!) {
    saveActivityPlayerRating(input: $input)
  }
`
 
// API 函数
 
/**
 * 获取进行中的比赛阶段列表(state=1且pid>0的比赛阶段)
 * 按比赛分组排序,显示格式为"比赛名 + 阶段名"
 */
export const getActiveActivities = async () => {
  try {
    const data = await graphqlRequest(GET_ACTIVE_ACTIVITIES_QUERY)
    
    // 过滤出state=1且pid>0的比赛阶段
    const stages = data.allActivities.filter(activity => 
      activity.state === 1 && activity.pid > 0
    )
    
    // 按比赛ID(pid)分组排序,确保同一比赛的不同阶段放在一起
    stages.sort((a, b) => {
      // 首先按比赛ID排序
      if (a.pid !== b.pid) {
        return a.pid - b.pid
      }
      // 同一比赛内按阶段ID排序
      return a.id - b.id
    })
    
    return stages
  } catch (error) {
    console.error('获取活动列表失败:', error)
    throw new Error(error.message || '获取活动列表失败')
  }
}
 
/**
 * 获取比赛项目列表
 */
export const getCompetitionProjects = async (activityId, page = 0, size = 10) => {
  try {
    const data = await graphqlRequest(GET_COMPETITION_PROJECTS_QUERY, {
      activityId,
      page,
      size
    })
    
    const projects = data.activityPlayerApplications || []
    
    // 为每个项目获取评分统计
    const enrichedProjects = await Promise.all(
      projects.map(async (project) => {
        try {
          const stats = await getRatingStats(project.id)
          return {
            id: project.id,
            playerName: project.playerName,
            activityName: project.activityName,
            phone: project.phone,
            applyTime: project.applyTime,
            state: project.state,
            projectName: project.projectName || project.playerName + '的项目', // 使用真实项目名称,如果为空则使用默认名称
            ratingCount: stats.ratingCount,
            averageScore: stats.averageScore
          }
        } catch (error) {
          console.warn(`Failed to get rating stats for project ${project.id}:`, error)
          return {
            id: project.id,
            playerName: project.playerName,
            activityName: project.activityName,
            phone: project.phone,
            applyTime: project.applyTime,
            state: project.state,
            projectName: project.projectName || project.playerName + '的项目', // 使用真实项目名称,如果为空则使用默认名称
            ratingCount: 0,
            averageScore: 0
          }
        }
      })
    )
    
    // 模拟分页信息,因为API返回的是数组而不是分页对象
    const totalElements = projects.length
    const totalPages = Math.ceil(totalElements / size)
    
    return {
      content: enrichedProjects,
      totalElements,
      totalPages,
      number: page,
      size
    }
  } catch (error) {
    console.error('Error fetching competition projects:', error)
    throw error
  }
}
 
/**
 * 获取项目详情
 */
export const getProjectDetail = async (id) => {
  try {
    const data = await graphqlRequest(GET_PROJECT_DETAIL_QUERY, { id })
    return data.activityPlayerDetail
  } catch (error) {
    throw new Error(error.message || '获取项目详情失败')
  }
}
 
/**
 * 获取评审统计信息
 */
export const getRatingStats = async (activityPlayerId) => {
  try {
    const data = await graphqlRequest(GET_RATING_STATS_QUERY, { activityPlayerId })
    
    const ratings = data.judgeRatingsForPlayer || []
    const averageScore = data.averageScoreForPlayer || 0
    
    // 只计算已评分的评委
    const ratedJudges = ratings.filter(rating => rating.hasRated)
    
    return {
      ratingCount: ratedJudges.length,
      averageScore: averageScore,
      ratings: ratings
    }
  } catch (error) {
    console.error('Error fetching rating stats:', error)
    // 返回默认值而不是抛出错误,避免影响主要功能
    return {
      ratingCount: 0,
      averageScore: 0,
      ratings: []
    }
  }
}
 
/**
 * 获取当前评委的评分信息
 */
export const getCurrentJudgeRating = async (activityPlayerId) => {
  try {
    const data = await graphqlRequest(GET_CURRENT_JUDGE_RATING_QUERY, { activityPlayerId })
    return data.currentJudgeRating
  } catch (error) {
    throw new Error(error.message || '获取当前评委评分失败')
  }
}
 
/**
 * 提交评分
 */
export const submitRating = async (ratingInput) => {
  try {
    const data = await graphqlRequest(SUBMIT_RATING_MUTATION, { input: ratingInput })
    return data.saveActivityPlayerRating
  } catch (error) {
    throw new Error(error.message || '提交评分失败')
  }
}