feat: 新增任务管理功能及相关组件

- 将目标页面改为任务列表,支持任务的创建、完成和跳过功能
- 新增任务卡片和任务进度卡片组件,展示任务状态和进度
- 实现任务数据的获取和管理,集成Redux状态管理
- 更新API服务,支持任务相关的CRUD操作
- 编写任务管理功能实现文档,详细描述功能和组件架构
This commit is contained in:
richarjiang
2025-08-22 17:30:14 +08:00
parent 231620d778
commit 259f10540e
21 changed files with 2756 additions and 608 deletions

83
services/tasksApi.ts Normal file
View File

@@ -0,0 +1,83 @@
import {
ApiResponse,
CompleteTaskRequest,
GetTasksQuery,
PaginatedResponse,
SkipTaskRequest,
Task,
TaskListItem,
TaskStats,
} from '@/types/goals';
import { api } from './api';
// 任务管理API服务
/**
* 获取任务列表
*/
export const getTasks = async (query: GetTasksQuery = {}): Promise<PaginatedResponse<TaskListItem>> => {
const searchParams = new URLSearchParams();
Object.entries(query).forEach(([key, value]) => {
if (value !== undefined && value !== null) {
searchParams.append(key, String(value));
}
});
const queryString = searchParams.toString();
const path = queryString ? `/goals/tasks?${queryString}` : '/goals/tasks';
return api.get<PaginatedResponse<TaskListItem>>(path);
};
/**
* 获取特定目标的任务列表
*/
export const getTasksByGoalId = async (goalId: string, query: GetTasksQuery = {}): Promise<PaginatedResponse<TaskListItem>> => {
const searchParams = new URLSearchParams();
Object.entries(query).forEach(([key, value]) => {
if (value !== undefined && value !== null) {
searchParams.append(key, String(value));
}
});
const queryString = searchParams.toString();
const path = queryString ? `/goals/${goalId}/tasks?${queryString}` : `/goals/${goalId}/tasks`;
return api.get<PaginatedResponse<TaskListItem>>(path);
};
/**
* 完成任务
*/
export const completeTask = async (taskId: string, completionData: CompleteTaskRequest = {}): Promise<Task> => {
return api.post<Task>(`/goals/tasks/${taskId}/complete`, completionData);
};
/**
* 跳过任务
*/
export const skipTask = async (taskId: string, skipData: SkipTaskRequest = {}): Promise<Task> => {
return api.post<Task>(`/goals/tasks/${taskId}/skip`, skipData);
};
/**
* 获取任务统计
*/
export const getTaskStats = async (goalId?: string): Promise<TaskStats> => {
const path = goalId ? `/goals/tasks/stats/overview?goalId=${goalId}` : '/goals/tasks/stats/overview';
const response = await api.get<ApiResponse<TaskStats>>(path);
return response.data;
};
// 导出所有API方法
export const tasksApi = {
getTasks,
getTasksByGoalId,
completeTask,
skipTask,
getTaskStats,
};
export default tasksApi;