docs: 新增 AI 代理学习偏好与信用盘术语规范
feat: 优化登录与入口页面加载体验 - 为登录页面添加 Suspense 边界,统一 fallback 样式 - 重构入口守卫逻辑,在布局阶段处理未登录重定向,避免闪烁 - 登录页面支持会话过期提示,并自动清理 URL 参数 feat: 信用盘与钱包盘文案差异化展示 - 底部导航「钱包」标签在信用盘模式下显示为「信用」 - 大厅余额条在信用盘模式下使用「可
This commit is contained in:
@@ -24,9 +24,8 @@ export const WALLET_FLOW_FILTERS: { value: string; labelKey: string }[] = [
|
||||
export const CREDIT_FLOW_FILTERS: { value: string; labelKey: string }[] = [
|
||||
{ value: "", labelKey: "wallet.creditFlow.all" },
|
||||
{ value: "bet", labelKey: "wallet.creditFlow.bet" },
|
||||
{ value: "prize", labelKey: "wallet.creditFlow.prize" },
|
||||
{ value: "refund", labelKey: "wallet.creditFlow.refund" },
|
||||
{ value: "reversal", labelKey: "wallet.creditFlow.reversal" },
|
||||
{ value: "credit_release", labelKey: "wallet.creditFlow.credit_release" },
|
||||
{ value: "bill_settlement", labelKey: "wallet.creditFlow.bill_settlement" },
|
||||
];
|
||||
|
||||
const FLOW_LABEL_FALLBACKS: Record<string, string> = {
|
||||
@@ -38,10 +37,12 @@ const FLOW_LABEL_FALLBACKS: Record<string, string> = {
|
||||
"wallet.flow.refund": "退款",
|
||||
"wallet.flow.reversal": "冲正",
|
||||
"wallet.creditFlow.all": "全部",
|
||||
"wallet.creditFlow.bet": "下注占用",
|
||||
"wallet.creditFlow.prize": "派奖释放",
|
||||
"wallet.creditFlow.refund": "退款返还",
|
||||
"wallet.creditFlow.reversal": "冲正回退",
|
||||
"wallet.creditFlow.bet": "占用额度",
|
||||
"wallet.creditFlow.credit_release": "释额",
|
||||
"wallet.creditFlow.bill_settlement": "账期收付",
|
||||
"wallet.creditFlow.win_credit": "中奖释额",
|
||||
"wallet.creditFlow.refund": "账期确认释额",
|
||||
"wallet.creditFlow.reversal": "退本释额",
|
||||
};
|
||||
|
||||
export function logTypeLabel(
|
||||
@@ -97,13 +98,6 @@ export function WalletLogsBlock({
|
||||
?? (creditMode
|
||||
? t("wallet.creditFlowsTitle", { defaultValue: "信用流水" })
|
||||
: t("wallet.flowsTitle", { defaultValue: "钱包流水" }));
|
||||
const channelHint = creditMode
|
||||
? t("wallet.playerChannel.credit", {
|
||||
defaultValue: "信用盘玩家(占用与释放额度流水)",
|
||||
})
|
||||
: t("wallet.playerChannel.wallet", {
|
||||
defaultValue: "主站钱包玩家(划转与钱包余额流水)",
|
||||
});
|
||||
const filters = useMemo(() => {
|
||||
const source = creditMode ? CREDIT_FLOW_FILTERS : WALLET_FLOW_FILTERS;
|
||||
return source.map((f) => ({
|
||||
@@ -118,7 +112,6 @@ export function WalletLogsBlock({
|
||||
<div className="flex flex-col gap-2">
|
||||
<div>
|
||||
<h2 className="text-sm font-black text-[#0b3f96]">{resolvedTitle}</h2>
|
||||
<p className="mt-0.5 text-[11px] font-medium text-slate-500">{channelHint}</p>
|
||||
</div>
|
||||
<div className="flex flex-wrap gap-1.5">
|
||||
{filters.map((f) => (
|
||||
@@ -152,7 +145,9 @@ export function WalletLogsBlock({
|
||||
<ul className="space-y-2">
|
||||
{logs.items.length === 0 ? (
|
||||
<li className="rounded-lg border border-dashed py-8 text-center text-sm text-muted-foreground">
|
||||
{t("wallet.emptyLogs")}
|
||||
{t(creditMode ? "wallet.emptyCreditLogs" : "wallet.emptyLogs", {
|
||||
defaultValue: creditMode ? "暂无信用流水" : "暂无流水",
|
||||
})}
|
||||
</li>
|
||||
) : (
|
||||
logs.items.map((row) => (
|
||||
@@ -219,7 +214,7 @@ export function LogRow({
|
||||
<div className="flex items-start justify-between gap-3">
|
||||
<div className="min-w-0 flex-1">
|
||||
<div className="flex items-center gap-2">
|
||||
<span className={isIn ? "size-2.5 rounded-full bg-emerald-500" : "size-2.5 rounded-full bg-[#0b3f96]"} aria-hidden />
|
||||
<span className={isIn ? "size-2.5 rounded-full bg-emerald-500" : "size-2.5 rounded-full bg-[#e5002c]"} aria-hidden />
|
||||
<p className="truncate text-base font-black leading-tight text-[#101a33]">
|
||||
{logTypeLabel(item.type, t, creditMode)}
|
||||
</p>
|
||||
@@ -235,7 +230,7 @@ export function LogRow({
|
||||
</div>
|
||||
|
||||
<div className="flex shrink-0 flex-col items-end gap-2 text-right">
|
||||
<p className={isIn ? "text-lg font-black tabular-nums text-emerald-600" : "text-lg font-black tabular-nums text-[#0b3f96]"}>
|
||||
<p className={isIn ? "text-lg font-black tabular-nums text-emerald-600" : "text-lg font-black tabular-nums text-[#e5002c]"}>
|
||||
{isIn ? "+" : "−"}
|
||||
{formatMinorAsCurrency(item.amount_abs, ccy)}
|
||||
</p>
|
||||
@@ -246,12 +241,24 @@ export function LogRow({
|
||||
</div>
|
||||
|
||||
<div className="mt-3 flex items-center justify-between rounded-xl bg-[#f8fbff] px-3 py-2 text-xs">
|
||||
<span className="font-semibold text-slate-500">
|
||||
{creditMode ? t("wallet.creditAvailableAfter") : t("wallet.balanceAfter")}
|
||||
</span>
|
||||
<span className="font-mono font-black tabular-nums text-[#32518d]">
|
||||
{formatMinorAsCurrency(item.balance_after, ccy)}
|
||||
</span>
|
||||
{creditMode && item.affects_available_credit === false ? (
|
||||
<span className="font-medium text-slate-500">
|
||||
{t("wallet.creditPaymentRecordOnly", {
|
||||
defaultValue: "账期收付记账,不计入可用信用",
|
||||
})}
|
||||
</span>
|
||||
) : (
|
||||
<>
|
||||
<span className="font-semibold text-slate-500">
|
||||
{creditMode ? t("wallet.creditAvailableAfter") : t("wallet.balanceAfter")}
|
||||
</span>
|
||||
<span className="font-mono font-black tabular-nums text-[#32518d]">
|
||||
{item.balance_after != null
|
||||
? formatMinorAsCurrency(item.balance_after, ccy)
|
||||
: "—"}
|
||||
</span>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</li>
|
||||
);
|
||||
|
||||
@@ -10,6 +10,7 @@ import { WalletLogsBlock } from "@/features/wallet/wallet-logs-block";
|
||||
import { dispatchWalletLogsRefresh } from "@/hooks/use-pending-wallet-reconcile";
|
||||
import { useActivePlayerCurrency } from "@/hooks/use-active-player-currency";
|
||||
import { PLAYER_CURRENCY_CHANGE_EVENT } from "@/lib/player-currency-preference";
|
||||
import { isCreditFundingPlayer } from "@/lib/player-funding-mode";
|
||||
import { formatWalletClientError } from "@/lib/wallet-api-error";
|
||||
import { getWalletLogsLastPage, type WalletLogsData } from "@/types/api/wallet-logs";
|
||||
|
||||
@@ -106,9 +107,17 @@ export function WalletLogsScreen() {
|
||||
|
||||
return (
|
||||
<PlayerPanel
|
||||
title={t("wallet.logsTitle")}
|
||||
title={
|
||||
creditMode
|
||||
? t("wallet.creditLogsTitle", { defaultValue: "信用流水" })
|
||||
: t("wallet.logsTitle")
|
||||
}
|
||||
backHref="/wallet"
|
||||
backLabel={t("wallet.title")}
|
||||
backLabel={
|
||||
creditMode
|
||||
? t("wallet.creditTitle", { defaultValue: "信用" })
|
||||
: t("wallet.title")
|
||||
}
|
||||
>
|
||||
<div className="space-y-3">
|
||||
{error ? (
|
||||
|
||||
@@ -16,6 +16,7 @@ import {
|
||||
import { WalletLogsBlock } from "@/features/wallet/wallet-logs-block";
|
||||
import { dispatchWalletLogsRefresh } from "@/hooks/use-pending-wallet-reconcile";
|
||||
import { useActivePlayerCurrency } from "@/hooks/use-active-player-currency";
|
||||
import { isCreditFundingPlayer } from "@/lib/player-funding-mode";
|
||||
import { formatMinorAsCurrency } from "@/lib/money";
|
||||
import { PLAYER_CURRENCY_CHANGE_EVENT } from "@/lib/player-currency-preference";
|
||||
import { formatWalletClientError } from "@/lib/wallet-api-error";
|
||||
@@ -117,8 +118,7 @@ export function WalletScreen() {
|
||||
|
||||
const hasMore = logs ? logs.page < getWalletLogsLastPage(logs) : false;
|
||||
|
||||
const isCreditPlayer =
|
||||
balance?.credit_line_mode === true || balance?.funding_mode === "credit";
|
||||
const isCreditPlayer = isCreditFundingPlayer(balance);
|
||||
const displayMinor = isCreditPlayer
|
||||
? Number(balance?.available_balance ?? 0)
|
||||
: Number(balance?.balance ?? 0);
|
||||
@@ -155,7 +155,9 @@ export function WalletScreen() {
|
||||
}, [hasMore, loadMore, loading, loadingMore, logsLoading]);
|
||||
|
||||
return (
|
||||
<PlayerPanel title={t("wallet.title")}>
|
||||
<PlayerPanel
|
||||
title={isCreditPlayer ? t("wallet.creditTitle", { defaultValue: "信用" }) : t("wallet.title")}
|
||||
>
|
||||
<div className="space-y-3">
|
||||
{error ? (
|
||||
<div className="rounded-xl border border-red-200 bg-red-50 px-3 py-3 text-sm text-red-700">
|
||||
@@ -213,7 +215,8 @@ export function WalletScreen() {
|
||||
{isCreditPlayer ? (
|
||||
<p className="rounded-xl border border-[#d6e4ff] bg-[#f5f9ff] px-3 py-3 text-sm text-[#0b3f96]/85">
|
||||
{t("wallet.creditNoTransferHint", {
|
||||
defaultValue: "信用盘账号由代理授信,无需主站转入转出;额度调整请联系代理。",
|
||||
defaultValue:
|
||||
"由代理授信,无需主站转入转出;中奖不即时派彩,盈亏在账期统一结算,额度调整请联系代理。",
|
||||
})}
|
||||
</p>
|
||||
) : (
|
||||
|
||||
Reference in New Issue
Block a user