blob: 25c1d9a909df86c026192c3925976aabf16e6721 [file] [log] [blame]
BirdNETM8bcf85f2025-06-09 16:07:21 +08001// service.ts - 活动系统服务层文件
2
3import { request } from '@umijs/max';
4import type {
5 GetActivityListResponse,
6 GetLeaderboardResponse,
7 ParticipateActivityResponse,
8 ActivityListParams,
9 LeaderboardParams,
10 SysActivity,
11 LeaderboardEntry,
12 StandardizedActivityListResponse,
13 StandardizedLeaderboardResponse
14} from './data';
15
16// 开发环境模拟数据开关
17const USE_MOCK = process.env.NODE_ENV === 'development' && false;
18
19// 模拟活动数据 - 适配后端格式
20const 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// 模拟排行榜数据
54const 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 */
64export 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 */
80function 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
96function 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 */
115export 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 */
171export 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 */
193export 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}