123 lines
3.3 KiB
JavaScript
123 lines
3.3 KiB
JavaScript
/**
|
|
* Token 使用统计 Store
|
|
*/
|
|
import { create } from 'zustand';
|
|
|
|
const useTokenUsageStore = create((set, get) => ({
|
|
// 状态
|
|
months: [],
|
|
currentMonth: null,
|
|
stats: null,
|
|
roles: [],
|
|
chats: [],
|
|
selectedRole: null,
|
|
selectedChat: null,
|
|
loading: false,
|
|
error: null,
|
|
|
|
// Actions
|
|
fetchMonths: async () => {
|
|
try {
|
|
set({ loading: true, error: null });
|
|
const response = await fetch('/api/token-usage/months');
|
|
if (!response.ok) throw new Error('Failed to fetch months');
|
|
|
|
const months = await response.json();
|
|
set({ months, loading: false });
|
|
|
|
// 默认选择最新的月份
|
|
if (months.length > 0) {
|
|
const latest = months[months.length - 1];
|
|
await get().fetchStats(latest.year, latest.month);
|
|
}
|
|
} catch (error) {
|
|
set({ error: error.message, loading: false });
|
|
}
|
|
},
|
|
|
|
fetchStats: async (year, month, role = null, chat = null) => {
|
|
try {
|
|
set({ loading: true, error: null, currentMonth: { year, month } });
|
|
|
|
let url = `/api/token-usage/stats/${year}/${month}`;
|
|
const params = new URLSearchParams();
|
|
if (role) params.append('role_name', role);
|
|
if (chat) params.append('chat_name', chat);
|
|
|
|
if (params.toString()) {
|
|
url += `?${params.toString()}`;
|
|
}
|
|
|
|
const response = await fetch(url);
|
|
if (!response.ok) throw new Error('Failed to fetch stats');
|
|
|
|
const stats = await response.json();
|
|
set({ stats, loading: false });
|
|
} catch (error) {
|
|
set({ error: error.message, loading: false });
|
|
}
|
|
},
|
|
|
|
fetchRoles: async (year, month) => {
|
|
try {
|
|
const response = await fetch(`/api/token-usage/roles/${year}/${month}`);
|
|
if (!response.ok) throw new Error('Failed to fetch roles');
|
|
|
|
const data = await response.json();
|
|
set({ roles: data.roles });
|
|
} catch (error) {
|
|
console.error('Failed to fetch roles:', error);
|
|
}
|
|
},
|
|
|
|
fetchChats: async (year, month, role = null) => {
|
|
try {
|
|
let url = `/api/token-usage/chats/${year}/${month}`;
|
|
if (role) {
|
|
url += `?role_name=${encodeURIComponent(role)}`;
|
|
}
|
|
|
|
const response = await fetch(url);
|
|
if (!response.ok) throw new Error('Failed to fetch chats');
|
|
|
|
const data = await response.json();
|
|
set({ chats: data.chats });
|
|
} catch (error) {
|
|
console.error('Failed to fetch chats:', error);
|
|
}
|
|
},
|
|
|
|
setSelectedRole: (role) => {
|
|
set({ selectedRole: role });
|
|
const { currentMonth } = get();
|
|
if (currentMonth) {
|
|
get().fetchStats(currentMonth.year, currentMonth.month, role, get().selectedChat);
|
|
}
|
|
},
|
|
|
|
setSelectedChat: (chat) => {
|
|
set({ selectedChat: chat });
|
|
const { currentMonth } = get();
|
|
if (currentMonth) {
|
|
get().fetchStats(currentMonth.year, currentMonth.month, get().selectedRole, chat);
|
|
}
|
|
},
|
|
|
|
setCurrentMonth: (year, month) => {
|
|
set({ currentMonth: { year, month } });
|
|
get().fetchStats(year, month, get().selectedRole, get().selectedChat);
|
|
get().fetchRoles(year, month);
|
|
get().fetchChats(year, month, get().selectedRole);
|
|
},
|
|
|
|
resetFilters: () => {
|
|
set({ selectedRole: null, selectedChat: null });
|
|
const { currentMonth } = get();
|
|
if (currentMonth) {
|
|
get().fetchStats(currentMonth.year, currentMonth.month);
|
|
}
|
|
},
|
|
}));
|
|
|
|
export default useTokenUsageStore;
|