1834b97fe2
PR Check / Lint, Check, Test and Build (push) Has been cancelled
Squash merge of fix/134-促销前端展示对齐 (4702dee).
HIF-79/HIF-113 落地后前端有三处对齐缺失:
- promo-info.tsx 仍读 promo.end_time,但后端 SubscribeDiscountPromo
JSON 字段是 expires_at(×2 处)
- billing.tsx 缺 Promo Discount 行,PreOrderResponse 拿到 promo_discount
时无处可渲染
- typings.d.ts: SubscribeDiscountPromo 缺 expires_at/rule_type,
PreOrderResponse 缺 promo_discount
本次仅修字段对齐与展示行,不动业务逻辑、不动 OrderDetail 类型 (后端
当前未透出 promo_discount)。新增 billing.promoDiscount 中英文文案。
115 lines
3.4 KiB
TypeScript
115 lines
3.4 KiB
TypeScript
"use client";
|
|
|
|
import { Separator } from "@workspace/ui/components/separator";
|
|
import { useTranslation } from "react-i18next";
|
|
import { Display } from "@/components/display";
|
|
|
|
interface SubscribeBillingProps {
|
|
order?: Partial<
|
|
API.OrderDetail & {
|
|
unit_price: number;
|
|
unit_time: string;
|
|
subscribe_discount: number;
|
|
promo_discount: number;
|
|
show_original_price?: boolean;
|
|
}
|
|
>;
|
|
}
|
|
|
|
export function SubscribeBilling({ order }: Readonly<SubscribeBillingProps>) {
|
|
const { t } = useTranslation("subscribe");
|
|
|
|
return (
|
|
<>
|
|
<div className="font-semibold">
|
|
{t("billing.billingTitle", "Billing Detail")}
|
|
</div>
|
|
<ul className="grid grid-cols-2 gap-3 *:flex *:items-center *:justify-between lg:grid-cols-1">
|
|
{order?.type && [1, 2].includes(order?.type) && (
|
|
<li>
|
|
<span className="text-muted-foreground">
|
|
{t("billing.duration", "Duration")}
|
|
</span>
|
|
<span>
|
|
{order?.quantity || 1}{" "}
|
|
{t(order?.unit_time || "Month", order?.unit_time || "Month")}
|
|
</span>
|
|
</li>
|
|
)}{" "}
|
|
{order?.show_original_price !== false &&
|
|
order?.type &&
|
|
[1, 2].includes(order?.type) && (
|
|
<li>
|
|
<span className="text-muted-foreground">
|
|
{t("billing.originalPrice", "Original Price (Monthly)")}
|
|
</span>
|
|
<span>
|
|
<Display type="currency" value={order?.unit_price} />
|
|
</span>
|
|
</li>
|
|
)}{" "}
|
|
<li>
|
|
<span className="text-muted-foreground">
|
|
{t("billing.price", "Price")}
|
|
</span>
|
|
<span>
|
|
<Display
|
|
type="currency"
|
|
value={order?.price || order?.unit_price}
|
|
/>
|
|
</span>
|
|
</li>
|
|
<li>
|
|
<span className="text-muted-foreground">
|
|
{t("billing.productDiscount", "Product Discount")}
|
|
</span>
|
|
<span>
|
|
<Display type="currency" value={order?.discount} />
|
|
</span>
|
|
</li>
|
|
<li>
|
|
<span className="text-muted-foreground">
|
|
{t("billing.promoDiscount", "Promo Discount")}
|
|
</span>
|
|
<span>
|
|
<Display type="currency" value={order?.promo_discount} />
|
|
</span>
|
|
</li>
|
|
<li>
|
|
<span className="text-muted-foreground">
|
|
{t("billing.couponDiscount", "Coupon Discount")}
|
|
</span>
|
|
<span>
|
|
<Display type="currency" value={order?.coupon_discount} />
|
|
</span>
|
|
</li>
|
|
<li>
|
|
<span className="text-muted-foreground">
|
|
{t("billing.fee", "Fee")}
|
|
</span>
|
|
<span>
|
|
<Display type="currency" value={order?.fee_amount} />
|
|
</span>
|
|
</li>
|
|
<li>
|
|
<span className="text-muted-foreground">
|
|
{t("billing.gift", "Gift")}
|
|
</span>
|
|
<span>
|
|
<Display type="currency" value={order?.gift_amount} />
|
|
</span>
|
|
</li>
|
|
</ul>
|
|
<Separator />
|
|
<div className="flex items-center justify-between font-semibold">
|
|
<span className="text-muted-foreground">
|
|
{t("billing.total", "Total")}
|
|
</span>
|
|
<span>
|
|
<Display type="currency" value={order?.amount} />
|
|
</span>
|
|
</div>
|
|
</>
|
|
);
|
|
}
|