feat: 完成P6-P8前端能力闭环(V3,D2,D3,B3)
这个提交包含在:
@@ -211,6 +211,7 @@ export function ReimbursementDetailPage() {
|
||||
}
|
||||
|
||||
const detail = detailQuery.data;
|
||||
const budgetHint = detail.budgetHint;
|
||||
const canPay = hasPermission(permissions, "expense.finance.pay");
|
||||
const canEditItems = ["draft", "rejected"].includes(detail.status);
|
||||
|
||||
@@ -262,6 +263,29 @@ export function ReimbursementDetailPage() {
|
||||
<div>说明:{detail.description || "-"}</div>
|
||||
</Card>
|
||||
|
||||
{budgetHint ? (
|
||||
<Card className="space-y-2 p-6 text-sm" data-testid="reimbursement-budget-hint">
|
||||
<h3 className="text-base font-semibold text-slate-900">预算提示</h3>
|
||||
<div>预算池:{budgetHint.budgetCode} / {budgetHint.budgetName}</div>
|
||||
<div>
|
||||
本次提交后预计占用:{budgetHint.nextUsedAmount} / {budgetHint.allocatedAmount}
|
||||
({budgetHint.nextUsagePercent.toFixed(2)}%)
|
||||
</div>
|
||||
<div>控制模式:{budgetHint.controlMode}</div>
|
||||
{budgetHint.exceedsBudget && budgetHint.controlMode === "block" ? (
|
||||
<p className="rounded-md border border-red-200 bg-red-50 px-2 py-1 text-red-600">
|
||||
当前金额将超出预算上限,提交时会被阻断(block 模式)。
|
||||
</p>
|
||||
) : budgetHint.exceedsThreshold ? (
|
||||
<p className="rounded-md border border-amber-200 bg-amber-50 px-2 py-1 text-amber-700">
|
||||
当前金额已达到预算预警阈值,提交后会记录预算预警审计。
|
||||
</p>
|
||||
) : (
|
||||
<p className="text-slate-500">当前预算充足,可继续提交。</p>
|
||||
)}
|
||||
</Card>
|
||||
) : null}
|
||||
|
||||
<Card className="space-y-4 p-6" data-testid="reimbursement-items">
|
||||
<div className="flex flex-col gap-3 md:flex-row md:items-center md:justify-between">
|
||||
<div className="space-y-1">
|
||||
|
||||
在新工单中引用
屏蔽一个用户