BirdNETM | 8bcf85f | 2025-06-09 16:07:21 +0800 | [diff] [blame^] | 1 | // service.ts - 活动系统服务层文件 |
| 2 | |
| 3 | import { request } from '@umijs/max'; |
| 4 | import type { |
| 5 | GetActivityListResponse, |
| 6 | GetLeaderboardResponse, |
| 7 | ParticipateActivityResponse, |
| 8 | ActivityListParams, |
| 9 | LeaderboardParams, |
| 10 | SysActivity, |
| 11 | LeaderboardEntry, |
| 12 | StandardizedActivityListResponse, |
| 13 | StandardizedLeaderboardResponse |
| 14 | } from './data'; |
| 15 | |
| 16 | // 开发环境模拟数据开关 |
| 17 | const USE_MOCK = process.env.NODE_ENV === 'development' && false; |
| 18 | |
| 19 | // 模拟活动数据 - 适配后端格式 |
| 20 | const mockActivities: SysActivity[] = [ |
| 21 | { |
| 22 | createBy: null, |
| 23 | createTime: null, |
| 24 | updateBy: null, |
| 25 | updateTime: null, |
| 26 | remark: null, |
| 27 | activityId: 1, |
| 28 | activityName: '新手上传挑战', |
| 29 | rewardBonus: 100, |
| 30 | conditionValue: '10GB', |
| 31 | startTime: '2025-06-01T00:00:00.000+08:00', |
| 32 | endTime: '2025-06-30T23:59:59.000+08:00', |
| 33 | status: 1, |
| 34 | activityType: 'UPLOAD' |
| 35 | }, |
| 36 | { |
| 37 | createBy: null, |
| 38 | createTime: null, |
| 39 | updateBy: null, |
| 40 | updateTime: null, |
| 41 | remark: null, |
| 42 | activityId: 2, |
| 43 | activityName: '种子下载任务', |
| 44 | rewardBonus: 50, |
| 45 | conditionValue: '94', |
| 46 | startTime: '2025-06-01T00:00:00.000+08:00', |
| 47 | endTime: '2025-06-15T23:59:59.000+08:00', |
| 48 | status: 1, |
| 49 | activityType: 'DOWNLOAD' |
| 50 | } |
| 51 | ]; |
| 52 | |
| 53 | // 模拟排行榜数据 |
| 54 | const mockLeaderboard: LeaderboardEntry[] = [ |
| 55 | { userId: 1, userName: 'user001', score: 1500 }, |
| 56 | { userId: 2, userName: 'user002', score: 1200 }, |
| 57 | { userId: 3, userName: 'user003', score: 1000 } |
| 58 | ]; |
| 59 | |
| 60 | /** |
| 61 | * 时间格式转换工具函数 |
| 62 | * 将 ISO 8601 格式转换为显示格式 |
| 63 | */ |
| 64 | export function formatDateTime(isoString: string): string { |
| 65 | const date = new Date(isoString); |
| 66 | return date.toLocaleString('zh-CN', { |
| 67 | year: 'numeric', |
| 68 | month: '2-digit', |
| 69 | day: '2-digit', |
| 70 | hour: '2-digit', |
| 71 | minute: '2-digit', |
| 72 | second: '2-digit' |
| 73 | }).replace(/\//g, '-'); |
| 74 | } |
| 75 | |
| 76 | /** |
| 77 | * 数据格式标准化函数 |
| 78 | * 将后端返回格式转换为前端组件期望的格式 |
| 79 | */ |
| 80 | function normalizeActivityListResponse( |
| 81 | backendResponse: GetActivityListResponse, |
| 82 | params?: ActivityListParams |
| 83 | ): StandardizedActivityListResponse { |
| 84 | return { |
| 85 | code: backendResponse.code === 200 ? 0 : backendResponse.code, // 后端成功码是200,前端期望0 |
| 86 | msg: backendResponse.msg, |
| 87 | data: { |
| 88 | list: backendResponse.rows, |
| 89 | total: backendResponse.total, |
| 90 | pageSize: params?.pageSize || 10, |
| 91 | current: params?.pageNum || 1, |
| 92 | } |
| 93 | }; |
| 94 | } |
| 95 | |
| 96 | function normalizeLeaderboardResponse( |
| 97 | backendResponse: GetLeaderboardResponse, |
| 98 | params?: LeaderboardParams |
| 99 | ): StandardizedLeaderboardResponse { |
| 100 | return { |
| 101 | code: backendResponse.code === 200 ? 0 : backendResponse.code, |
| 102 | msg: backendResponse.msg, |
| 103 | data: { |
| 104 | list: backendResponse.rows, |
| 105 | total: backendResponse.total, |
| 106 | pageSize: params?.pageSize || 10, |
| 107 | current: params?.pageNum || 1, |
| 108 | } |
| 109 | }; |
| 110 | } |
| 111 | |
| 112 | /** |
| 113 | * 获取活动列表 |
| 114 | */ |
| 115 | export async function getActivityList(params?: ActivityListParams): Promise<StandardizedActivityListResponse> { |
| 116 | if (USE_MOCK) { |
| 117 | let filteredList = mockActivities; |
| 118 | |
| 119 | // 按状态筛选 |
| 120 | if (params?.status !== undefined) { |
| 121 | filteredList = filteredList.filter(item => item.status === params.status); |
| 122 | } |
| 123 | |
| 124 | // 按活动类型筛选 |
| 125 | if (params?.activityType) { |
| 126 | filteredList = filteredList.filter(item => item.activityType === params.activityType); |
| 127 | } |
| 128 | |
| 129 | // 按活动名称搜索 |
| 130 | if (params?.activityName) { |
| 131 | filteredList = filteredList.filter(item => |
| 132 | item.activityName.includes(params.activityName!) |
| 133 | ); |
| 134 | } |
| 135 | |
| 136 | // 模拟后端返回格式 |
| 137 | const mockBackendResponse: GetActivityListResponse = { |
| 138 | total: filteredList.length, |
| 139 | rows: filteredList, |
| 140 | code: 200, |
| 141 | msg: '查询成功' |
| 142 | }; |
| 143 | |
| 144 | return normalizeActivityListResponse(mockBackendResponse, params); |
| 145 | } |
| 146 | |
| 147 | try { |
| 148 | // 调用实际后端接口 |
| 149 | const response: GetActivityListResponse = await request('/api/system/activity/list', { |
| 150 | method: 'GET', |
| 151 | params: { |
| 152 | pageNum: params?.pageNum, |
| 153 | pageSize: params?.pageSize, |
| 154 | activityName: params?.activityName, |
| 155 | activityType: params?.activityType, |
| 156 | status: params?.status, |
| 157 | }, |
| 158 | }); |
| 159 | |
| 160 | // 标准化响应格式 |
| 161 | return normalizeActivityListResponse(response, params); |
| 162 | } catch (error) { |
| 163 | console.error('获取活动列表失败:', error); |
| 164 | throw error; |
| 165 | } |
| 166 | } |
| 167 | |
| 168 | /** |
| 169 | * 参与活动 |
| 170 | */ |
| 171 | export async function participateActivity(activityId: number): Promise<ParticipateActivityResponse> { |
| 172 | if (USE_MOCK) { |
| 173 | return Promise.resolve({ |
| 174 | code: 0, |
| 175 | msg: '参与成功', |
| 176 | data: null, |
| 177 | }); |
| 178 | } |
| 179 | |
| 180 | try { |
| 181 | return await request(`/api/system/activity/participate/${activityId}`, { |
| 182 | method: 'POST', |
| 183 | }); |
| 184 | } catch (error) { |
| 185 | console.error('参与活动失败:', error); |
| 186 | throw error; |
| 187 | } |
| 188 | } |
| 189 | |
| 190 | /** |
| 191 | * 获取排行榜 |
| 192 | */ |
| 193 | export async function getLeaderboard(params?: LeaderboardParams): Promise<StandardizedLeaderboardResponse> { |
| 194 | if (USE_MOCK) { |
| 195 | const mockBackendResponse: GetLeaderboardResponse = { |
| 196 | total: mockLeaderboard.length, |
| 197 | rows: mockLeaderboard, |
| 198 | code: 200, |
| 199 | msg: '查询成功' |
| 200 | }; |
| 201 | |
| 202 | return normalizeLeaderboardResponse(mockBackendResponse, params); |
| 203 | } |
| 204 | |
| 205 | try { |
| 206 | const response: GetLeaderboardResponse = await request('/api/system/activity/leaderboard', { |
| 207 | method: 'GET', |
| 208 | params: { |
| 209 | pageNum: params?.pageNum, |
| 210 | pageSize: params?.pageSize, |
| 211 | }, |
| 212 | }); |
| 213 | |
| 214 | return normalizeLeaderboardResponse(response, params); |
| 215 | } catch (error) { |
| 216 | console.error('获取排行榜失败:', error); |
| 217 | throw error; |
| 218 | } |
| 219 | } |