refactor: update agent API schemas, standardize UI text styling, and enhance settlement credit ledger components
This commit is contained in:
@@ -262,7 +262,7 @@ export function AgentBillDetail({
|
||||
return (
|
||||
<>
|
||||
<ConfirmDialog />
|
||||
<div className="grid gap-6 xl:grid-cols-[minmax(0,1.35fr)_minmax(340px,0.95fr)]">
|
||||
<div className="grid gap-6 md:grid-cols-[minmax(0,1.35fr)_minmax(340px,0.95fr)]">
|
||||
<div className="space-y-5 text-sm">
|
||||
<SettlementBillSummaryHeader bill={bill} currencyCode={currencyCode} />
|
||||
<SettlementBillPartiesRow bill={bill} />
|
||||
@@ -294,22 +294,22 @@ export function AgentBillDetail({
|
||||
|
||||
<div className="space-y-5 text-sm">
|
||||
{rebateAllocations.length > 0 ? (
|
||||
<div className="space-y-2 rounded-xl border border-border/70 p-4">
|
||||
<p className="font-medium">
|
||||
<div className="space-y-2 rounded-xl border border-border/70 bg-card p-5 shadow-sm">
|
||||
<p className="font-semibold tracking-tight">
|
||||
{t("settlementBills.rebateAllocations", { defaultValue: "回水分摊" })}
|
||||
</p>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
<p className="text-xs text-muted-foreground/80">
|
||||
{t("settlementCenter:billDisplay.rebateAllocationsHint", {
|
||||
defaultValue: "各层级代理对回水的承担明细。",
|
||||
})}
|
||||
</p>
|
||||
<div className="space-y-3">
|
||||
<div className="mt-3 space-y-3">
|
||||
<ul className="space-y-1.5 text-muted-foreground">
|
||||
{rebateAllocationSummary.map((row) => (
|
||||
<li key={row.key} className="flex justify-between gap-2">
|
||||
<span className="min-w-0">
|
||||
{row.label}
|
||||
<span className="ml-2 text-xs text-muted-foreground/75">
|
||||
<span className="ml-2 text-xs text-muted-foreground/60">
|
||||
{t("common:count", { defaultValue: "{{count}} 条", count: row.rows })}
|
||||
</span>
|
||||
</span>
|
||||
@@ -354,12 +354,12 @@ export function AgentBillDetail({
|
||||
) : null}
|
||||
|
||||
{canManage && bill.status === "pending_confirm" ? (
|
||||
<div className="space-y-3 rounded-xl border border-border/70 bg-muted/15 p-4">
|
||||
<div className="space-y-4 rounded-xl border border-border/70 bg-primary/5 p-5 shadow-sm">
|
||||
<div className="space-y-1">
|
||||
<p className="font-medium">
|
||||
<p className="font-semibold tracking-tight text-primary">
|
||||
{t("settlementBills.confirm", { defaultValue: "确认账单" })}
|
||||
</p>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
<p className="text-xs text-muted-foreground/80">
|
||||
{t("settlementCenter:billDisplay.confirmHint", {
|
||||
defaultValue: "确认后才可以登记收款或付款。",
|
||||
})}
|
||||
@@ -377,54 +377,57 @@ export function AgentBillDetail({
|
||||
) : null}
|
||||
|
||||
{canManage && ["confirmed", "partial_paid", "overdue"].includes(bill.status) && bill.unpaid_amount > 0 ? (
|
||||
<div className="space-y-3 rounded-xl border border-border/70 p-4">
|
||||
<div className="space-y-1">
|
||||
<div className="space-y-4 rounded-xl border border-border/70 bg-card p-5 shadow-sm">
|
||||
<div className="space-y-2">
|
||||
<div className="flex flex-wrap items-center justify-between gap-2">
|
||||
<p className="font-medium">{paymentTitle}</p>
|
||||
<span className="rounded-full bg-amber-50 px-2.5 py-1 text-xs font-medium text-amber-700 dark:bg-amber-950/30 dark:text-amber-300">
|
||||
<p className="font-semibold tracking-tight">{paymentTitle}</p>
|
||||
<span className="rounded-full bg-amber-500/10 px-2.5 py-0.5 text-xs font-medium text-amber-600 dark:bg-amber-500/20 dark:text-amber-400">
|
||||
{t("settlementCenter:columns.unpaid", { defaultValue: "未结" })}{" "}
|
||||
{formatDashboardMoneyMinor(bill.unpaid_amount, currencyCode)}
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex flex-wrap items-center gap-1 text-xs text-muted-foreground">
|
||||
<span>{direction.payer}</span>
|
||||
<div className="flex flex-wrap items-center gap-1 text-[13px] text-muted-foreground">
|
||||
<span className="font-medium text-foreground/80">{direction.payer}</span>
|
||||
<ArrowRight className="size-3.5 shrink-0" aria-hidden />
|
||||
<span>{direction.payee}</span>
|
||||
<span className="font-medium text-foreground/80">{direction.payee}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="grid gap-2">
|
||||
<div className="space-y-1">
|
||||
<Label>{t("settlementBills.paymentAmount", { defaultValue: "收付金额" })}</Label>
|
||||
<div className="grid gap-4 mt-2">
|
||||
<div className="space-y-1.5">
|
||||
<Label className="text-muted-foreground">{t("settlementBills.paymentAmount", { defaultValue: "收付金额" })}</Label>
|
||||
<Input
|
||||
value={payAmount}
|
||||
onChange={(e) => setPayAmount(e.target.value)}
|
||||
placeholder={String(bill.unpaid_amount)}
|
||||
className="bg-background/50 transition-colors focus:bg-background"
|
||||
/>
|
||||
</div>
|
||||
<div className="space-y-1">
|
||||
<Label>{t("settlementBills.paymentMethod", { defaultValue: "收付方式" })}</Label>
|
||||
<div className="space-y-1.5">
|
||||
<Label className="text-muted-foreground">{t("settlementBills.paymentMethod", { defaultValue: "收付方式" })}</Label>
|
||||
<Input
|
||||
value={payMethod}
|
||||
onChange={(e) => setPayMethod(e.target.value)}
|
||||
placeholder={t("settlementBills.paymentMethodPlaceholder", {
|
||||
defaultValue: "例如:现金 / 银行转账",
|
||||
})}
|
||||
className="bg-background/50 transition-colors focus:bg-background"
|
||||
/>
|
||||
</div>
|
||||
<div className="space-y-1">
|
||||
<Label>{t("settlementBills.paymentProof", { defaultValue: "凭证/备注" })}</Label>
|
||||
<div className="space-y-1.5">
|
||||
<Label className="text-muted-foreground">{t("settlementBills.paymentProof", { defaultValue: "凭证/备注" })}</Label>
|
||||
<Input
|
||||
value={payProof}
|
||||
onChange={(e) => setPayProof(e.target.value)}
|
||||
placeholder={t("settlementBills.paymentProofPlaceholder", {
|
||||
defaultValue: "可填写流水号、截图说明或备注",
|
||||
})}
|
||||
className="bg-background/50 transition-colors focus:bg-background"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<Button
|
||||
type="button"
|
||||
className="w-full"
|
||||
className="w-full mt-2"
|
||||
disabled={confirmBusy}
|
||||
onClick={requestPayment}
|
||||
>
|
||||
@@ -434,31 +437,32 @@ export function AgentBillDetail({
|
||||
) : null}
|
||||
|
||||
{canWriteOff ? (
|
||||
<div className="space-y-3 rounded-xl border border-border/70 p-4">
|
||||
<div className="space-y-4 rounded-xl border border-destructive/20 bg-destructive/5 p-5 shadow-sm">
|
||||
<div className="space-y-1">
|
||||
<p className="font-medium">
|
||||
<p className="font-semibold tracking-tight text-destructive">
|
||||
{t("settlementBills.badDebtWriteOff", { defaultValue: "坏账核销" })}
|
||||
</p>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
<p className="text-xs text-destructive/80">
|
||||
{t("settlementBills.badDebtHint", {
|
||||
defaultValue: "仅在确认无法收回时使用,核销后会生成坏账记录。",
|
||||
})}
|
||||
</p>
|
||||
</div>
|
||||
<div className="space-y-1">
|
||||
<Label>{t("settlementBills.badDebtReason", { defaultValue: "核销原因" })}</Label>
|
||||
<div className="space-y-1.5 mt-2">
|
||||
<Label className="text-destructive/90">{t("settlementBills.badDebtReason", { defaultValue: "核销原因" })}</Label>
|
||||
<Input
|
||||
value={badDebtReason}
|
||||
onChange={(e) => setBadDebtReason(e.target.value)}
|
||||
placeholder={t("settlementBills.badDebtReasonPlaceholder", {
|
||||
defaultValue: "例如:客户失联、确认坏账",
|
||||
})}
|
||||
className="bg-background/50 transition-colors focus:bg-background border-destructive/30"
|
||||
/>
|
||||
</div>
|
||||
<Button
|
||||
type="button"
|
||||
variant="destructive"
|
||||
className="w-full"
|
||||
className="w-full mt-2"
|
||||
disabled={confirmBusy}
|
||||
onClick={requestBadDebtWriteOff}
|
||||
>
|
||||
@@ -468,19 +472,19 @@ export function AgentBillDetail({
|
||||
) : null}
|
||||
|
||||
{canManage && locked ? (
|
||||
<div className="space-y-3 rounded-xl border border-dashed border-border/70 p-4">
|
||||
<div className="space-y-4 rounded-xl border border-dashed border-border/70 bg-card p-5 shadow-sm">
|
||||
<div className="space-y-1">
|
||||
<p className="font-medium">
|
||||
<p className="font-semibold tracking-tight">
|
||||
{t("settlementBills.adjustment", { defaultValue: "补差/冲正单" })}
|
||||
</p>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
<p className="text-xs text-muted-foreground/80">
|
||||
{t("settlementBills.adjustmentHint", {
|
||||
defaultValue: "正数表示补收,负数表示冲减;提交后会生成一张独立调账单。",
|
||||
})}
|
||||
</p>
|
||||
</div>
|
||||
<div className="space-y-1">
|
||||
<Label>{t("settlementBills.adjustmentAmount", { defaultValue: "调整金额(可负)" })}</Label>
|
||||
<div className="space-y-1.5 mt-2">
|
||||
<Label className="text-muted-foreground">{t("settlementBills.adjustmentAmount", { defaultValue: "调整金额(可负)" })}</Label>
|
||||
<Input
|
||||
value={adjustAmount}
|
||||
onChange={(e) => setAdjustAmount(e.target.value)}
|
||||
@@ -488,22 +492,24 @@ export function AgentBillDetail({
|
||||
placeholder={t("settlementBills.adjustmentAmountPlaceholder", {
|
||||
defaultValue: "输入正数或负数",
|
||||
})}
|
||||
className="bg-background/50 transition-colors focus:bg-background"
|
||||
/>
|
||||
</div>
|
||||
<div className="space-y-1">
|
||||
<Label>{t("settlementBills.adjustmentReason", { defaultValue: "调整原因" })}</Label>
|
||||
<div className="space-y-1.5">
|
||||
<Label className="text-muted-foreground">{t("settlementBills.adjustmentReason", { defaultValue: "调整原因" })}</Label>
|
||||
<Input
|
||||
value={adjustReason}
|
||||
onChange={(e) => setAdjustReason(e.target.value)}
|
||||
placeholder={t("settlementBills.adjustmentReasonPlaceholder", {
|
||||
defaultValue: "例如:人工复核补差、冲正错账",
|
||||
})}
|
||||
className="bg-background/50 transition-colors focus:bg-background"
|
||||
/>
|
||||
</div>
|
||||
<Button
|
||||
type="button"
|
||||
variant="outline"
|
||||
className="w-full"
|
||||
className="w-full mt-2"
|
||||
disabled={confirmBusy}
|
||||
onClick={requestAdjustment}
|
||||
>
|
||||
|
||||
Reference in New Issue
Block a user