feat(web): 透析 API + 积分账户组件 + 工作台 store + 统计页修复

- dialysis.ts: 新增透析管理 API 模块
- PointsAccountTab.tsx: 积分账户标签页组件
- workbenchStore.ts: 工作台状态管理
- StatisticsDashboard.tsx: 统计页空列表修复
- auth.test.ts: 修复权限码拼写 health.alert → health.alerts
- api.test.ts: API 契约测试
This commit is contained in:
iven
2026-05-03 19:32:00 +08:00
parent 70322e4132
commit 3e4baa38a6
6 changed files with 485 additions and 5 deletions

View File

@@ -0,0 +1,58 @@
import { create } from 'zustand';
import { actionInboxApi, type ActionItem, type WorkbenchStats } from '../api/health/actionInbox';
interface WorkbenchState {
tasks: ActionItem[];
selectedTaskId: string | null;
tab: 'pending' | 'completed';
loading: boolean;
stats: WorkbenchStats | null;
selectTask: (id: string | null) => void;
setTab: (tab: 'pending' | 'completed') => void;
refreshTasks: () => Promise<void>;
refreshStats: () => Promise<void>;
completeTask: (id: string) => void;
}
export const useWorkbenchStore = create<WorkbenchState>((set, get) => ({
tasks: [],
selectedTaskId: null,
tab: 'pending',
loading: false,
stats: null,
selectTask: (id) => set({ selectedTaskId: id }),
setTab: (tab) => {
set({ tab, selectedTaskId: null });
get().refreshTasks();
},
refreshTasks: async () => {
set({ loading: true });
try {
const status = get().tab === 'pending' ? 'pending' : 'completed';
const resp = await actionInboxApi.list({ status, page: 1, page_size: 50 });
const tasks = Array.isArray(resp?.data) ? resp.data : [];
set({ tasks, loading: false });
} catch {
set({ loading: false });
}
},
refreshStats: async () => {
try {
const stats = await actionInboxApi.stats();
set({ stats: stats ?? null });
} catch { /* ignore */ }
},
completeTask: (id) => {
const { tasks } = get();
const remaining = tasks.filter(t => t.id !== id);
const nextId = remaining.length > 0 ? remaining[0].id : null;
set({ tasks: remaining, selectedTaskId: nextId });
get().refreshStats();
},
}));