/** * Streak Service - API calls for user streak management * 连续记账功能服务 */ import api from './api'; import type { ApiResponse } from '../types'; /** * Streak info returned from backend */ export interface StreakInfo { current_streak: number; // 当前连续天数 longest_streak: number; // 最长连续记录 total_record_days: number; // 累计记账天数 has_record_today: boolean; // 今天是否已记账 message: string; // 提示信息 } /** * Daily contribution data */ export interface DailyContribution { date: string; count: number; } /** * Streak info in camelCase for frontend */ export interface StreakInfoFormatted { currentStreak: number; longestStreak: number; totalRecordDays: number; hasRecordToday: boolean; message: string; } /** * Map streak data from API (snake_case) to frontend (camelCase) */ function mapStreakFromApi(data: StreakInfo): StreakInfoFormatted { return { currentStreak: data.current_streak, longestStreak: data.longest_streak, totalRecordDays: data.total_record_days, hasRecordToday: data.has_record_today, message: data.message, }; } /** * Get current user's streak info * 获取当前用户的连续记账信息 */ export async function getStreakInfo(): Promise { const response = await api.get>('/user/streak'); if (!response.data) { // Return default values if no streak data return { currentStreak: 0, longestStreak: 0, totalRecordDays: 0, hasRecordToday: false, message: '开始记录你的第一笔账吧!', }; } return mapStreakFromApi(response.data); } /** * Recalculate streak from transaction history * 重新计算连续记账天数(基于交易历史) */ export async function recalculateStreak(): Promise { const response = await api.post>('/user/streak/recalculate'); if (!response.data) { throw new Error(response.error || 'Failed to recalculate streak'); } return mapStreakFromApi(response.data); } /** * Get daily contribution data for heatmap * 获取热力图数据 */ export async function getContributionData(): Promise { const response = await api.get>('/user/streak/contribution'); return response.data || []; } export default { getStreakInfo, recalculateStreak, getContributionData, };