实现 B-2b 统一报销工作台迁移(reimbursement-form-shared-component-migration)
这个提交包含在:
@@ -0,0 +1,96 @@
|
||||
import type { ReactNode } from "react";
|
||||
import type { ReimbursementDetail } from "../api/reimbursements";
|
||||
import type { ReimbursementApprovalEvidenceProjection } from "./reimbursementApprovalProjection";
|
||||
import { resolveReimbursementDisplayCode } from "./reimbursementDisplay";
|
||||
|
||||
export type ReimbursementWorkspaceHeaderModel = {
|
||||
displayCode: string;
|
||||
ownerName: string;
|
||||
reimbursementDate: string | null;
|
||||
totalAmount: string | null;
|
||||
description: string | null;
|
||||
};
|
||||
|
||||
export type ReimbursementWorkspaceIssueAnchor = {
|
||||
id: string;
|
||||
label: string;
|
||||
severity: "blocking" | "review" | "info";
|
||||
};
|
||||
|
||||
export type ReimbursementWorkspaceModel = {
|
||||
header: ReimbursementWorkspaceHeaderModel;
|
||||
evidence: ReimbursementApprovalEvidenceProjection;
|
||||
issueAnchors: ReimbursementWorkspaceIssueAnchor[];
|
||||
};
|
||||
|
||||
export type ReimbursementWorkspaceSlots = {
|
||||
status: ReactNode;
|
||||
backAction?: ReactNode;
|
||||
headerDetails?: ReactNode;
|
||||
beforeEvidence?: ReactNode;
|
||||
afterEvidence?: ReactNode;
|
||||
timeline?: ReactNode;
|
||||
actionPanel?: ReactNode;
|
||||
mobileActions?: ReactNode;
|
||||
transientFeedback?: ReactNode;
|
||||
};
|
||||
|
||||
export function buildReimbursementWorkspaceHeader(
|
||||
detail: Pick<ReimbursementDetail, "formNumber" | "owner" | "reimbursementDate" | "totalAmount" | "description" | "id">,
|
||||
): ReimbursementWorkspaceHeaderModel {
|
||||
return {
|
||||
displayCode: resolveReimbursementDisplayCode(detail),
|
||||
ownerName: detail.owner?.name ?? "-",
|
||||
reimbursementDate: detail.reimbursementDate,
|
||||
totalAmount: detail.totalAmount,
|
||||
description: detail.description,
|
||||
};
|
||||
}
|
||||
|
||||
export function buildReimbursementWorkspaceIssueAnchors(
|
||||
evidence: ReimbursementApprovalEvidenceProjection,
|
||||
options: { snapshotMissing?: boolean; snapshotInvalid?: boolean } = {},
|
||||
): ReimbursementWorkspaceIssueAnchor[] {
|
||||
const anchors: ReimbursementWorkspaceIssueAnchor[] = [];
|
||||
if (options.snapshotInvalid) {
|
||||
anchors.push({ id: "reimbursement-workspace-snapshot", label: "提交记录无法读取", severity: "blocking" });
|
||||
} else if (options.snapshotMissing) {
|
||||
anchors.push({ id: "reimbursement-workspace-snapshot", label: "未留存预算快照", severity: "info" });
|
||||
}
|
||||
if (evidence.currentCheck.unlinkedInvoiceCount) {
|
||||
anchors.push({
|
||||
id: "reimbursement-workspace-unlinked",
|
||||
label: `${evidence.currentCheck.unlinkedInvoiceCount} 张票据尚未选择明细`,
|
||||
severity: "blocking",
|
||||
});
|
||||
}
|
||||
if (evidence.currentCheck.missingInvoiceItemCount) {
|
||||
anchors.push({
|
||||
id: "reimbursement-workspace-evidence",
|
||||
label: `${evidence.currentCheck.missingInvoiceItemCount} 条明细缺少票据`,
|
||||
severity: "review",
|
||||
});
|
||||
}
|
||||
if (evidence.currentCheck.amountUnavailableItemCount) {
|
||||
anchors.push({
|
||||
id: "reimbursement-workspace-evidence",
|
||||
label: `${evidence.currentCheck.amountUnavailableItemCount} 条明细的票面金额未能读取`,
|
||||
severity: "blocking",
|
||||
});
|
||||
}
|
||||
if (evidence.currentCheck.manualReviewItemCount) {
|
||||
anchors.push({
|
||||
id: "reimbursement-workspace-evidence",
|
||||
label: `${evidence.currentCheck.manualReviewItemCount} 条明细需查看原件核对金额`,
|
||||
severity: "review",
|
||||
});
|
||||
}
|
||||
if (evidence.currentCheck.amountExceededItemCount) {
|
||||
anchors.push({
|
||||
id: "reimbursement-workspace-evidence",
|
||||
label: `${evidence.currentCheck.amountExceededItemCount} 条明细申报额高于票面金额`,
|
||||
severity: "blocking",
|
||||
});
|
||||
}
|
||||
return anchors;
|
||||
}
|
||||
在新工单中引用
屏蔽一个用户