feat(P25-2/P25-3/P26-2/P28-1/P24-2/P29-3): 落地内部OA够用版前端入口与运营页面

关联 Issue: P25-2, P25-3, P25-4, P26-2, P26-4, P28-1, P28-2, P28-3, P28-4, P24-2, P29-3
这个提交包含在:
2026-03-21 18:03:48 +08:00
父节点 e39e41287e
当前提交 9905c1c79d
共修改 44 个文件,包含 2029 行新增和 169 行删除
+109
查看文件
@@ -0,0 +1,109 @@
import { apiRequestData } from "./http";
import type { RiskFlag } from "./feeControl";
export type PaymentBatchEntityType = "reimbursement" | "travel_order";
export type PaymentBatchStatus = "draft" | "reviewed" | "executed" | "failed" | "cancelled";
export type PaymentChannel = "bank" | "alipay" | "wechat" | "cash" | "other";
export type PaymentBatchItem = {
id: string;
entityId: string;
entityCode: string;
entityTitle: string;
amount: string;
currencyCode: string;
paymentVoucherNoOverride: string | null;
paymentDateOverride: string | null;
paymentChannelOverride: PaymentChannel | null;
status: string;
failureCode: string | null;
failureMessage: string | null;
snapshotJson: Record<string, unknown>;
createdAt: string | null;
openRiskFlags: RiskFlag[];
};
export type PaymentBatch = {
id: string;
batchNo: string;
entityType: PaymentBatchEntityType;
name: string;
status: PaymentBatchStatus;
defaultPaymentDate: string | null;
defaultPaymentChannel: PaymentChannel | null;
voucherPrefix: string | null;
reviewComment: string | null;
executionSummaryJson: Record<string, unknown> | null;
createdAt: string | null;
createdBy: string | null;
reviewedAt: string | null;
reviewedBy: string | null;
executedAt: string | null;
executedBy: string | null;
cancelledAt: string | null;
cancelledBy: string | null;
items: PaymentBatchItem[];
};
export type PaymentBatchListResponse = { items: PaymentBatch[] };
export async function fetchPaymentBatches(query: { entityType?: PaymentBatchEntityType; status?: PaymentBatchStatus } = {}) {
const params = new URLSearchParams();
if (query.entityType) params.set("entityType", query.entityType);
if (query.status) params.set("status", query.status);
const suffix = params.toString() ? `?${params.toString()}` : "";
return apiRequestData<PaymentBatchListResponse>(`/api/payment-batches${suffix}`);
}
export async function fetchPaymentBatchDetail(batchId: string) {
return apiRequestData<{ item: PaymentBatch }>(`/api/payment-batches/${batchId}`);
}
export async function createPaymentBatch(payload: {
entityType: PaymentBatchEntityType;
name: string;
entityIds: string[];
defaultPaymentDate?: string;
defaultPaymentChannel?: PaymentChannel;
voucherPrefix?: string;
}) {
return apiRequestData<{ item: PaymentBatch }>("/api/payment-batches", {
method: "POST",
body: JSON.stringify(payload),
});
}
export async function updatePaymentBatchItem(batchId: string, itemId: string, payload: {
paymentVoucherNoOverride?: string | null;
paymentDateOverride?: string | null;
paymentChannelOverride?: PaymentChannel | null;
}) {
return apiRequestData<{ item: Pick<PaymentBatchItem, "id" | "paymentVoucherNoOverride" | "paymentDateOverride" | "paymentChannelOverride"> }>(
`/api/payment-batches/${batchId}/items/${itemId}`,
{
method: "PATCH",
body: JSON.stringify(payload),
},
);
}
export async function reviewPaymentBatch(batchId: string, payload: { comment?: string; resolveRiskFlagIds?: string[] } = {}) {
return apiRequestData<{ item: PaymentBatch }>(`/api/payment-batches/${batchId}/review`, {
method: "POST",
body: JSON.stringify(payload),
});
}
export async function executePaymentBatch(batchId: string) {
return apiRequestData<{ item: PaymentBatch }>(`/api/payment-batches/${batchId}/execute`, {
method: "POST",
body: JSON.stringify({}),
});
}
export async function cancelPaymentBatch(batchId: string) {
return apiRequestData<{ item: PaymentBatch }>(`/api/payment-batches/${batchId}/cancel`, {
method: "POST",
body: JSON.stringify({}),
});
}