文件
hyb-oa/client/src/api/expenseStandards.ts
T
wangsli 14c2cbd6da fix(R56): 修复费用标准编辑时 expenseTypeId 校验失败
前端编辑提交时携带了只读字段 expenseTypeId,后端 strict schema 拒绝。
剔除只读字段后 PATCH 正常工作。
2026-04-08 18:53:39 +08:00

119 行
3.3 KiB
TypeScript

import { apiRequestData } from "./http";
export type ExpenseStandardPerUnit = "item" | "day" | "trip";
export type ExpenseStandardControlMode = "warn" | "block";
export type ExpenseStandardScopeType = "global" | "department";
export type ExpenseStandard = {
id: string;
expenseTypeId: string;
expenseTypeName: string | null;
name: string;
maxAmount: string;
perUnit: ExpenseStandardPerUnit;
controlMode: ExpenseStandardControlMode;
scopeType: ExpenseStandardScopeType;
scopeKey: string | null;
scopeLabel: string;
enabled: boolean;
note: string | null;
createdAt: string | null;
updatedAt: string | null;
};
export type ExpenseStandardListResponse = {
expenseTypeId: string | null;
scopeType: ExpenseStandardScopeType | null;
enabled: boolean | null;
items: ExpenseStandard[];
};
export type ExpenseStandardListQuery = {
expenseTypeId?: string;
scopeType?: ExpenseStandardScopeType;
enabled?: boolean;
};
export type CreateExpenseStandardPayload = {
expenseTypeId: string;
name: string;
maxAmount: string;
perUnit?: ExpenseStandardPerUnit;
controlMode?: ExpenseStandardControlMode;
scopeType?: ExpenseStandardScopeType;
scopeKey?: string | null;
enabled?: boolean;
note?: string | null;
};
export type UpdateExpenseStandardPayload = {
name?: string;
maxAmount?: string;
perUnit?: ExpenseStandardPerUnit;
controlMode?: ExpenseStandardControlMode;
scopeType?: ExpenseStandardScopeType;
scopeKey?: string | null;
enabled?: boolean;
note?: string | null;
};
function toQueryString(query: Record<string, string | number | boolean | undefined>) {
const params = new URLSearchParams();
for (const [key, value] of Object.entries(query)) {
if (value == null || value === "") {
continue;
}
params.set(key, String(value));
}
const encoded = params.toString();
return encoded ? `?${encoded}` : "";
}
export async function fetchExpenseStandards(query: ExpenseStandardListQuery = {}) {
return apiRequestData<ExpenseStandardListResponse>(
`/api/expense-standards${toQueryString(query as Record<string, string | number | boolean | undefined>)}`,
);
}
export async function createExpenseStandard(payload: CreateExpenseStandardPayload) {
return apiRequestData<ExpenseStandard>("/api/expense-standards", {
method: "POST",
body: JSON.stringify(payload),
});
}
export async function updateExpenseStandard(standardId: string, payload: UpdateExpenseStandardPayload) {
const {
name,
maxAmount,
perUnit,
controlMode,
scopeType,
scopeKey,
enabled,
note,
} = payload;
return apiRequestData<ExpenseStandard>(`/api/expense-standards/${standardId}`, {
method: "PATCH",
body: JSON.stringify({
...(name === undefined ? {} : { name }),
...(maxAmount === undefined ? {} : { maxAmount }),
...(perUnit === undefined ? {} : { perUnit }),
...(controlMode === undefined ? {} : { controlMode }),
...(scopeType === undefined ? {} : { scopeType }),
...(scopeKey === undefined ? {} : { scopeKey }),
...(enabled === undefined ? {} : { enabled }),
...(note === undefined ? {} : { note }),
}),
});
}
export async function deleteExpenseStandard(standardId: string) {
return apiRequestData<ExpenseStandard>(`/api/expense-standards/${standardId}`, {
method: "DELETE",
body: JSON.stringify({}),
});
}