feat: 用户订阅流量限速规则编辑器与列表信息增强

- 订阅表单新增卡片式流量限速规则编辑器(TrafficLimitRuleEditor),替换 ArrayInput
- 用户列表与订阅详情展示会员状态(member_status)、最近登录时间(last_login_time)
- ProTable 支持列级 meta.className 自定义样式
- 仪表盘统计与促销规则表单配套调整,用户文案双语同步
This commit is contained in:
2026-07-09 13:34:03 -07:00
parent 511ce4ff65
commit dfe1bafd1c
11 changed files with 367 additions and 158 deletions
@@ -316,19 +316,22 @@ export default function UserSubscription({ userId }: { userId: number }) {
{
accessorKey: "speed_limit",
header: t("speedLimit", "Speed Limit"),
meta: {
className: "min-w-[220px] whitespace-normal",
},
cell: ({ row }) => {
const userSpeed = row.original.speed_limit ?? 0;
const effectiveSpeed = row.original.effective_speed ?? 0;
const planSpeed = resolvePlanSpeed(row.original);
const speed = effectiveSpeed || userSpeed || planSpeed;
const source = row.original.is_throttled
? t("effectiveSpeed", "Effective Speed")
? t("effectiveSpeed")
: userSpeed > 0
? t("userOverride", "User Override")
: t("subscriptionDefault", "Subscription Default");
? t("userOverride")
: t("subscriptionDefault");
return (
<div className="flex flex-col gap-1">
<div className="flex min-w-[200px] flex-col gap-1 whitespace-normal">
<div className="flex items-center gap-2">
<Display type="trafficSpeed" value={speed} />
{row.original.is_throttled && (
@@ -337,19 +340,18 @@ export default function UserSubscription({ userId }: { userId: number }) {
</Badge>
)}
</div>
<span className="text-muted-foreground text-xs">
{source}
</span>
<span className="text-muted-foreground text-xs">
{t("userOverride", "User Override")}:{" "}
<span className="inline-block">
<div className="grid grid-cols-[auto_1fr] gap-x-2 gap-y-0.5 text-muted-foreground text-xs leading-5">
<span>{t("current")}</span>
<span>{source}</span>
<span>{t("userOverride")}</span>
<span>
<Display type="trafficSpeed" value={userSpeed} />
</span>{" "}
/ {t("subscriptionDefault", "Subscription Default")}:{" "}
<span className="inline-block">
</span>
<span>{t("subscriptionDefault")}</span>
<span>
<Display type="trafficSpeed" value={planSpeed} />
</span>
</span>
</div>
</div>
);
},