- 在 backgroundTaskManager 中增加 executeChallengeReminderTask,每日检查已加入且未打卡的挑战并发送鼓励通知 - 扩展 ChallengeNotificationHelpers 提供 sendEncouragementNotification 方法 - 新增 NotificationTypes.CHALLENGE_ENCOURAGEMENT 及对应点击跳转处理 - challengesApi 补充 checkedInToday 字段用于判断今日是否已打卡 - 临时注释掉挑战列表与详情页头部的礼物/分享按钮,避免干扰主流程
78 lines
2.0 KiB
TypeScript
78 lines
2.0 KiB
TypeScript
import { api } from './api';
|
|
|
|
export type ChallengeStatus = 'upcoming' | 'ongoing' | 'expired';
|
|
|
|
export type ChallengeProgressDto = {
|
|
completed: number;
|
|
target: number;
|
|
remaining: number
|
|
checkedInToday: boolean;
|
|
};
|
|
|
|
export type RankingItemDto = {
|
|
id: string;
|
|
name: string;
|
|
avatar: string | null;
|
|
metric: string;
|
|
badge?: string;
|
|
};
|
|
|
|
export enum ChallengeType {
|
|
WATER = 'water',
|
|
EXERCISE = 'exercise',
|
|
DIET = 'diet',
|
|
MOOD = 'mood',
|
|
SLEEP = 'sleep',
|
|
WEIGHT = 'weight',
|
|
}
|
|
|
|
|
|
|
|
export type ChallengeListItemDto = {
|
|
id: string;
|
|
title: string;
|
|
image: string;
|
|
periodLabel?: string;
|
|
durationLabel: string;
|
|
requirementLabel: string;
|
|
status: ChallengeStatus;
|
|
participantsCount: number;
|
|
rankingDescription?: string;
|
|
highlightTitle: string;
|
|
highlightSubtitle: string;
|
|
ctaLabel: string;
|
|
progress?: ChallengeProgressDto;
|
|
isJoined: boolean;
|
|
startAt?: string;
|
|
endAt?: string;
|
|
minimumCheckInDays: number; // 最小打卡天数
|
|
type: ChallengeType;
|
|
};
|
|
|
|
export type ChallengeDetailDto = ChallengeListItemDto & {
|
|
summary?: string;
|
|
rankings: RankingItemDto[];
|
|
userRank?: number;
|
|
};
|
|
|
|
export async function listChallenges(): Promise<ChallengeListItemDto[]> {
|
|
return api.get<ChallengeListItemDto[]>('/challenges');
|
|
}
|
|
|
|
export async function getChallengeDetail(id: string): Promise<ChallengeDetailDto> {
|
|
return api.get<ChallengeDetailDto>(`/challenges/${encodeURIComponent(id)}`);
|
|
}
|
|
|
|
export async function joinChallenge(id: string): Promise<ChallengeProgressDto> {
|
|
return api.post<ChallengeProgressDto>(`/challenges/${encodeURIComponent(id)}/join`);
|
|
}
|
|
|
|
export async function leaveChallenge(id: string): Promise<boolean> {
|
|
return api.post<boolean>(`/challenges/${encodeURIComponent(id)}/leave`);
|
|
}
|
|
|
|
export async function reportChallengeProgress(id: string, value?: number): Promise<ChallengeProgressDto> {
|
|
const body = value != null ? { value } : undefined;
|
|
return api.post<ChallengeProgressDto>(`/challenges/${encodeURIComponent(id)}/progress`, body);
|
|
}
|