b1fea23a0c
官网加「定价」菜单与页面。数据来自 GET /api/v1/pricing(**不挂鉴权**): 运营改价、上下架、调发放节奏都在管理端完成,官网跟着变,不用发版; 未登录就能看到价格,这是转化的前提,也是官网存在的意义。 接口只吐在售项与展示字段,成本、权重、租户信息一律不出去。 结账仍在 Web 面完成(那里有登录态、租户上下文与支付轮询),官网只负责 「看价 → 去买」。同一套支付流程不在两处各实现一遍——这也是本次订阅开发 一直遵循的那条线:积分包与订阅共用一个支付弹窗,桌面端不重复购买入口。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
66 lines
2.3 KiB
TypeScript
66 lines
2.3 KiB
TypeScript
import { useEffect, useState } from "react";
|
||
import { BrowserRouter, Routes, Route } from "react-router-dom";
|
||
import { AppShell } from "./shell/AppShell";
|
||
import { Login } from "./Login";
|
||
import { me, clearToken, type AuthUser } from "./api";
|
||
|
||
// 官网落地页(融进本工程,src/site/),挂根 /。
|
||
import { SiteLayout } from "./site/components/layout/site-layout";
|
||
import HomePage from "./site/pages/home";
|
||
import DownloadPage from "./site/pages/download";
|
||
import PricingPage from "./site/pages/pricing";
|
||
import NotFoundPage from "./site/pages/not-found";
|
||
|
||
// 后台鉴权门:只在访问 /admin 时跑 me()(官网公开、不打鉴权)。
|
||
// 未登录 → Login;登录后 → AppShell(其内部再渲染 /admin/* 子路由)。
|
||
function AdminGate() {
|
||
const [user, setUser] = useState<AuthUser | null>(null);
|
||
const [loading, setLoading] = useState(true);
|
||
|
||
useEffect(() => {
|
||
me()
|
||
.then(setUser)
|
||
.catch(() => setUser(null))
|
||
.finally(() => setLoading(false));
|
||
const onLogout = () => setUser(null);
|
||
window.addEventListener("sdx:logout", onLogout);
|
||
return () => window.removeEventListener("sdx:logout", onLogout);
|
||
}, []);
|
||
|
||
if (loading) {
|
||
return <div className="flex h-screen w-screen items-center justify-center text-sm text-gray-400">加载中…</div>;
|
||
}
|
||
if (!user) {
|
||
return <Login onAuthed={setUser} />;
|
||
}
|
||
return (
|
||
<AppShell
|
||
user={user}
|
||
onLogout={() => {
|
||
clearToken();
|
||
setUser(null);
|
||
}}
|
||
/>
|
||
);
|
||
}
|
||
|
||
// 用 BrowserRouter(路径式):/ = 官网、/admin = 运维后台。
|
||
// gateway 的 NoRoute 对非 /api、非文件路径回退 index.html,故深链/刷新都能工作。
|
||
export default function App() {
|
||
return (
|
||
<BrowserRouter>
|
||
<Routes>
|
||
{/* 后台:/admin 前缀,最具体,优先匹配 */}
|
||
<Route path="/admin/*" element={<AdminGate />} />
|
||
{/* 官网:根 / + /download,公开;未知路径落官网 404(保留 header/footer) */}
|
||
<Route element={<SiteLayout />}>
|
||
<Route index element={<HomePage />} />
|
||
<Route path="pricing" element={<PricingPage />} />
|
||
<Route path="download" element={<DownloadPage />} />
|
||
<Route path="*" element={<NotFoundPage />} />
|
||
</Route>
|
||
</Routes>
|
||
</BrowserRouter>
|
||
);
|
||
}
|