feat: 完成P6-P8前端能力闭环(V3,D2,D3,B3)

这个提交包含在:
2026-02-10 11:28:51 +08:00
父节点 6bc09f557b
当前提交 4e5a7793fe
共修改 14 个文件,包含 1151 行新增和 62 行删除
+83
查看文件
@@ -0,0 +1,83 @@
import { apiRequestData } from "./http";
export type BudgetPool = {
id: string;
code: string;
name: string;
departmentId: string | null;
status: "active" | "archived";
periodStart: string | null;
periodEnd: string | null;
allocatedAmount: string;
usedAmount: string;
remainingAmount: string;
warningThresholdPercent: number;
archivedAt: string | null;
createdAt: string | null;
updatedAt: string | null;
};
export type BudgetListResponse = {
page: number;
pageSize: number;
total: number;
items: BudgetPool[];
};
export type BudgetListQuery = {
status?: "active" | "archived";
departmentId?: string;
page?: number;
pageSize?: number;
};
function toQueryString(query: BudgetListQuery = {}) {
const params = new URLSearchParams();
if (query.status) params.set("status", query.status);
if (query.departmentId) params.set("departmentId", query.departmentId);
if (query.page != null) params.set("page", String(query.page));
if (query.pageSize != null) params.set("pageSize", String(query.pageSize));
const encoded = params.toString();
return encoded ? `?${encoded}` : "";
}
export async function fetchBudgets(query: BudgetListQuery = {}) {
return apiRequestData<BudgetListResponse>(`/api/budgets${toQueryString(query)}`);
}
export async function createBudget(payload: {
code: string;
name: string;
departmentId?: string | null;
periodStart: string;
periodEnd: string;
allocatedAmount: string;
warningThresholdPercent?: number;
}) {
return apiRequestData<BudgetPool>(`/api/budgets`, {
method: "POST",
body: JSON.stringify(payload),
});
}
export async function updateBudget(
budgetId: string,
payload: Partial<{
name: string;
allocatedAmount: string;
warningThresholdPercent: number;
status: "active" | "archived";
}>,
) {
return apiRequestData<BudgetPool>(`/api/budgets/${budgetId}`, {
method: "PATCH",
body: JSON.stringify(payload),
});
}
export async function archiveBudget(budgetId: string) {
return apiRequestData<BudgetPool>(`/api/budgets/${budgetId}/archive`, {
method: "POST",
body: JSON.stringify({}),
});
}