R57 A1-A6:报销模板与差旅申请关联

这个提交包含在:
2026-04-08 21:16:30 +08:00
父节点 14c2cbd6da
当前提交 88c987ae8f
共修改 17 个文件,包含 2886 行新增和 76 行删除
+86
查看文件
@@ -0,0 +1,86 @@
import { apiRequestData } from "./http";
export type ReimbursementTemplateItem = {
expenseTypeId: string;
description: string;
defaultAmount?: string;
};
export type ReimbursementTemplate = {
id: string;
name: string;
description: string | null;
items: ReimbursementTemplateItem[];
sortOrder: number;
enabled: boolean;
createdAt: string | null;
updatedAt: string | null;
};
export type ReimbursementTemplateListResponse = {
enabled: boolean | null;
items: ReimbursementTemplate[];
};
export type ReimbursementTemplateListQuery = {
enabled?: boolean;
};
export type CreateReimbursementTemplatePayload = {
name: string;
description?: string | null;
items?: ReimbursementTemplateItem[];
sortOrder?: number;
enabled?: boolean;
};
export type UpdateReimbursementTemplatePayload = {
name?: string;
description?: string | null;
items?: ReimbursementTemplateItem[];
sortOrder?: number;
enabled?: boolean;
};
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 fetchReimbursementTemplates(query: ReimbursementTemplateListQuery = {}) {
return apiRequestData<ReimbursementTemplateListResponse>(
`/api/reimbursement-templates${toQueryString(query as Record<string, string | number | boolean | undefined>)}`,
);
}
export async function createReimbursementTemplate(payload: CreateReimbursementTemplatePayload) {
return apiRequestData<ReimbursementTemplate>("/api/reimbursement-templates", {
method: "POST",
body: JSON.stringify(payload),
});
}
export async function updateReimbursementTemplate(
templateId: string,
payload: UpdateReimbursementTemplatePayload,
) {
return apiRequestData<ReimbursementTemplate>(`/api/reimbursement-templates/${templateId}`, {
method: "PATCH",
body: JSON.stringify(payload),
});
}
export async function deleteReimbursementTemplate(templateId: string) {
return apiRequestData<ReimbursementTemplate>(`/api/reimbursement-templates/${templateId}`, {
method: "DELETE",
});
}
+61 -6
查看文件
@@ -24,6 +24,15 @@ export type ReimbursementItem = {
} | null;
};
export type LinkedTravelRequestSummary = {
id: string;
requestNo: string | null;
purpose: string | null;
startDate: string | null;
endDate: string | null;
estimatedAmount: string;
};
export type ReimbursementListItem = {
id: string;
formNumber: string | null;
@@ -113,6 +122,8 @@ export type ReimbursementDetail = {
totalAmount: string | null;
description: string | null;
projectId: string | null;
linkedTravelRequestId: string | null;
linkedTravelRequest: LinkedTravelRequestSummary | null;
project: {
id: string;
projectNo: string;
@@ -207,6 +218,48 @@ export type ReimbursementPayPayload = {
paymentChannel?: "bank" | "alipay" | "wechat" | "cash" | "other";
};
export type ReimbursementCreatePayload = {
ownerEmployeeId?: string;
reimbursementDate?: string;
description?: string;
templateId?: string;
linkedTravelRequestId?: string;
};
export type ReimbursementCreateResponse = {
id: string;
formNumber: string | null;
submitterId: string;
ownerId: string;
reimbursementDate: string | null;
status: ReimbursementStatus;
description: string | null;
projectId: string | null;
project: {
id: string;
projectNo: string;
name: string;
} | null;
totalAmount: string;
linkedTravelRequestId: string | null;
linkedTravelRequest: LinkedTravelRequestSummary | null;
items: ReimbursementItem[];
};
export type LinkableTravelRequestSummary = {
id: string;
requestNo: string | null;
purpose: string;
startDate: string | null;
endDate: string | null;
estimatedAmount: string;
};
export type LinkableTravelRequestListResponse = {
ownerEmployeeId: string;
items: LinkableTravelRequestSummary[];
};
export type ReimbursementItemPayload = {
expenseTypeId: string;
expenseDate: string;
@@ -301,17 +354,19 @@ export async function fetchReimbursementDetail(reimbursementId: string) {
return apiRequestData<ReimbursementDetail>(`/api/reimbursements/${reimbursementId}`);
}
export async function createReimbursement(payload: {
ownerEmployeeId?: string;
reimbursementDate?: string;
description?: string;
} = {}) {
return apiRequestData<{ id: string }>(`/api/reimbursements`, {
export async function createReimbursement(payload: ReimbursementCreatePayload = {}) {
return apiRequestData<ReimbursementCreateResponse>(`/api/reimbursements`, {
method: "POST",
body: JSON.stringify(payload),
});
}
export async function fetchLinkableTravelRequests(query: { ownerEmployeeId?: string } = {}) {
return apiRequestData<LinkableTravelRequestListResponse>(
`/api/reimbursements/linkable-travel-requests${toQueryString(query as Record<string, string | number | undefined>)}`,
);
}
export async function precheckReimbursement(reimbursementId: string) {
return apiRequestData<PrecheckResponse>(`/api/reimbursements/${reimbursementId}/precheck`, {
method: "POST",