feat: 接入玩家入口与API代理

- 新增 /api 重写代理,支持 LOTTERY_API_PROXY_TARGET 配置
- 玩家首页切换为 EntryGate,并移除 layout 对 PlayerAppShell 的包裹
- 请求层拆分语言头与玩家鉴权注入逻辑,引入 zustand 依赖
- 允许提交 .env.example 供本地配置参考
This commit is contained in:
2026-05-09 10:17:39 +08:00
parent 7bed43ac96
commit 14c297fe1a
16 changed files with 750 additions and 81 deletions

View File

@@ -0,0 +1,24 @@
import {
Card,
CardContent,
CardDescription,
CardHeader,
CardTitle,
} from "@/components/ui/card";
/** 下注大厅占位§4.2 再接表格与期号) */
export default function LotteryHallPlaceholderPage() {
return (
<Card>
<CardHeader>
<CardTitle></CardTitle>
<CardDescription>
</CardDescription>
</CardHeader>
<CardContent className="text-sm text-muted-foreground">
</CardContent>
</Card>
);
}

View File

@@ -0,0 +1,15 @@
import { PlayerAppShell } from "@/components/layout/player-app-shell";
import { HydratePlayerAuth } from "@/features/player/hydrate-player-auth";
export default function PlayerMainLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<>
<HydratePlayerAuth />
<PlayerAppShell>{children}</PlayerAppShell>
</>
);
}

View File

@@ -1,9 +1,7 @@
import { PlayerAppShell } from "@/components/layout/player-app-shell";
export default function PlayerLayout({
export default function PlayerRootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return <PlayerAppShell>{children}</PlayerAppShell>;
return children;
}

View File

@@ -1,23 +1,20 @@
import {
Card,
CardContent,
CardDescription,
CardHeader,
CardTitle,
} from "@/components/ui/card";
import type { ReactNode } from "react";
import { Suspense } from "react";
export default function PlayerHomePage() {
import { EntryGate } from "@/features/player/entry-gate";
function EntryFallback(): ReactNode {
return (
<Card>
<CardHeader>
<CardTitle></CardTitle>
<CardDescription>
layout
</CardDescription>
</CardHeader>
<CardContent className="text-sm text-muted-foreground">
PlayerAppShell
</CardContent>
</Card>
<div className="flex min-h-dvh flex-col items-center justify-center bg-gradient-to-b from-red-800 to-red-950 px-4 text-sm text-white/90">
<p></p>
</div>
);
}
export default function EntryPage() {
return (
<Suspense fallback={<EntryFallback />}>
<EntryGate />
</Suspense>
);
}