chore: migrate frontend assets to OSS and same-origin APIs

This commit is contained in:
2026-06-04 16:03:49 +08:00
parent 7c6129555b
commit c7c52c1467
55 changed files with 728 additions and 292 deletions
+25 -11
View File
@@ -6,16 +6,15 @@ import {
InfoCircleOutlined,
LoginOutlined,
LogoutOutlined,
PhoneOutlined,
SafetyOutlined,
EnvironmentOutlined,
PlusCircleOutlined,
UserOutlined,
WalletOutlined,
} from "@ant-design/icons";
import { useEffect, useMemo, useRef, useState } from "react";
import type { ReactNode } from "react";
import { publicConfigClient, type WebPublicConfig } from "../api/publicConfigClient";
import type { ServerConnectionHealth } from "../api/serverConnection";
import { ossAssets } from "../data/ossAssets";
import { canManageCommunityCases, canReviewCommunity } from "../features/community-review/communityPermissions";
import type { WebNavItem, WebNotification, WebUsageSummary, WebUserSession, WebViewKey } from "../types";
import NotificationCenter from "./NotificationCenter";
@@ -40,8 +39,7 @@ interface AppShellProps {
children: ReactNode;
}
const BRAND_LOGO_URL = "https://stringtest.oss-cn-hangzhou.aliyuncs.com/logo.png";
const CLIENT_ERROR_MONITOR_ENABLED = import.meta.env.VITE_ENABLE_CLIENT_ERROR_MONITOR === "1";
const BRAND_LOGO_URL = ossAssets.brand.logo;
function formatBalance(cents: number): string {
const value = Math.max(0, cents) / 100;
@@ -71,6 +69,7 @@ function AppShell({
const [infoOpen, setInfoOpen] = useState(false);
const infoRef = useRef<HTMLDivElement>(null);
const [openSubmenuKey, setOpenSubmenuKey] = useState<WebViewKey | null>(null);
const [publicConfig, setPublicConfig] = useState<WebPublicConfig>({});
const prevActiveViewRef = useRef<WebViewKey>(activeView);
const [navJustActivated, setNavJustActivated] = useState<WebViewKey | null>(null);
const isAuthView = activeView === "login";
@@ -136,6 +135,22 @@ function AppShell({
}
}, []);
useEffect(() => {
let cancelled = false;
publicConfigClient
.get()
.then((config) => {
if (!cancelled) setPublicConfig(config);
})
.catch(() => {
if (!cancelled) setPublicConfig({});
});
return () => {
cancelled = true;
};
}, []);
useEffect(() => {
if (!profileOpen) return;
@@ -220,7 +235,6 @@ function AppShell({
? (usage.enterpriseBalanceCents ?? session.user.enterpriseBalanceCents ?? usage.balanceCents)
: usage.balanceCents;
const displayedBalanceLabel = session ? formatBalance(displayedBalanceCents) : "0 积分";
const isPreviewSession = session?.source === "mock-fallback";
const showCommunityReview = canReviewCommunity(session);
const showCommunityCaseAdd = canManageCommunityCases(session);
@@ -339,11 +353,11 @@ function AppShell({
<AnimatedPanel open={infoOpen} className="info-popover panel-surface">
<dl>
<dt></dt>
<dd>ICP备2026021747号-1</dd>
<dd>{publicConfig.icpRecord || "由服务器配置"}</dd>
<dt></dt>
<dd>9A楼501</dd>
<dd>{publicConfig.companyAddress || "由服务器配置"}</dd>
<dt></dt>
<dd>15155073618</dd>
<dd>{publicConfig.contactPhone || "由服务器配置"}</dd>
</dl>
<div className="info-popover__links">
<a href="#/userAgreement" onClick={() => setInfoOpen(false)}></a>
@@ -407,7 +421,7 @@ function AppShell({
<dd>{usage.videoUsed}</dd>
</dl>
<div className="profile-popover__footer">
<span>{import.meta.env.VITE_KEY_SERVER_URL || "使用预览数据"}</span>
<span>{session?.source === "server" ? "服务器会话" : "预览会话"}</span>
<button type="button" onClick={onLogout}>
<LogoutOutlined />
退
@@ -473,7 +487,7 @@ function AppShell({
<div className="web-shell__page">{children}</div>
</main>
</div>
{CLIENT_ERROR_MONITOR_ENABLED && session?.user.role === "admin" ? <AdminMonitor /> : null}
{session?.user.role === "admin" ? <AdminMonitor /> : null}
<RechargeModal open={rechargeOpen} onClose={() => setRechargeOpen(false)} currentBalance={displayedBalanceCents} />
<CookieConsentBanner />
</div>