代码提交

This commit is contained in:
fengxiangdebaozi committed 2026-06-02 11:04:25 +08:00
1 parent 6621519f11
commit f0ccd6fb09
3 files changed
+103 -5

No files matched your search

+8 -1
View File
@@ -51,7 +51,14 @@ export function readExternalLoginParams(): Required<ExternalLoginParams> {
}
}
/** 把 ``theme`` query 值映射成 ThemeContext 的 ``'dark' | 'light'`` */
/**
* 把外部(URL query / 无界 props)的 ``theme`` 值映射成 ThemeContext 的
* ``'dark' | 'light'``。已知取值:
* - ``dark-blue`` → 深色
* - ``red`` → 浅色(当前默认红白主题)
* - ``blue`` → 暂无该主题,先用浅色代替(命中 else 分支)
* 其余/缺省同样回退浅色。将来若新增 blue 主题,在此扩展映射即可。
*/
export function resolveThemeFromQuery(themeParam: string | null | undefined): "dark" | "light" {
return themeParam === "dark-blue" ? "dark" : "light";
}
+78
View File
@@ -0,0 +1,78 @@
/**
* 无界(wujie)子应用运行时 props 读取。
*
* 本应用作为子应用被内网门户用无界嵌套时,父级通过
* <WujieVue name="subApp" :url="..." :props="{ ticket, userId, theme, env }" />
* 注入参数,子应用在 `window.$wujie.props` 上拿到**同一个对象**(无界在子应用
* bootstrap 之前就已注入,因此首帧即可读)。
*
* 本期范围:只「读出来 + 存起来 + 打印」,**不接入对方鉴权**。读出的
* ticket/userId/env 复用 external-login 的 localStorage 存储(与 URL 跳转登录
* 同一套 key),theme 交给调用方(LoginPage)映射到 ThemeContext。
*/
import { useEffect, useMemo } from "react";
import { persistExternalLoginParams } from "@/core/auth/external-login";
/** 无界父级注入的 props 形状。除已知字段外允许透传其余未知字段便于排查。 */
export interface WujieProps {
/** 第三方鉴权 ticket(本期仅存储待用,不消费)。 */
ticket?: string;
/** 外部用户 id。 */
userId?: string;
/** 环境标识。 */
env?: string;
/** 主题色标识(映射到深/浅色)。 */
theme?: string;
[key: string]: unknown;
}
interface WujieRuntime {
props?: WujieProps;
[key: string]: unknown;
}
declare global {
interface Window {
/** 无界注入的子应用运行时;非无界环境下为 undefined。 */
$wujie?: WujieRuntime;
/** 无界注入的环境标志(子应用内为 true)。 */
__POWERED_BY_WUJIE__?: boolean;
}
}
/** 当前是否运行在无界子应用环境中。 */
export function isWujieEnv(): boolean {
return typeof window !== "undefined" && !!window.__POWERED_BY_WUJIE__;
}
/** 读取无界父级注入的 props;不在无界环境 / 未注入时返回空对象。 */
export function readWujieProps(): WujieProps {
if (typeof window === "undefined") return {};
return window.$wujie?.props ?? {};
}
/**
* 全局读取无界父级注入的 props 的 hook。
*
* - 首帧从 `window.$wujie.props` 读出(无界已在 bootstrap 前注入,引用稳定);
* - 读到后把 ticket/userId/env 持久化到 localStorage(复用 external-login 存储),
* 供后续任意页面/请求读取 —— 即「存到全局」;
* - 返回 props 供调用方消费(如 LoginPage 取 theme)。
*
* 非无界环境(直接访问)下返回空对象且不做任何持久化,可安全无条件调用。
*/
export function useWujieProps(): WujieProps {
const props = useMemo(() => readWujieProps(), []);
useEffect(() => {
if (!props.ticket && !props.userId && !props.env) return;
persistExternalLoginParams({
ticket: props.ticket,
userId: props.userId,
env: props.env,
});
}, [props.ticket, props.userId, props.env]);
return props;
}
+17 -4
View File
@@ -10,6 +10,7 @@ import {
persistExternalLoginParams,
resolveThemeFromQuery,
} from "@/core/auth/external-login";
import { isWujieEnv, useWujieProps } from "@/core/embed/wujie";
import {
GENERAL_QA_ROUTE,
loginByYUserId,
@@ -49,11 +50,23 @@ export default function LoginPage() {
const [status, setStatus] = useState<LoginStatus>("loading");
const [errorMessage, setErrorMessage] = useState<string>("");
// 主题切换:theme=dark-blue → 深色,其他值或缺省 → 浅色
// 无界(wujie)父级通过 $wujie.props 注入的参数(ticket / userId / theme / env)。
// hook 内部已把 ticket/userId/env 持久化到 localStorage(复用 external-login 存储)。
const wujieProps = useWujieProps();
// 调试:把无界注入的 props 打印出来(仅在无界子应用环境下,避免独立访问时刷日志)。
useEffect(() => {
if (!externalParams.theme) return;
setTheme(resolveThemeFromQuery(externalParams.theme));
}, [externalParams.theme, setTheme]);
if (!isWujieEnv()) return;
console.log("[wujie] sub-app props:", wujieProps);
}, [wujieProps]);
// 主题切换:无界 props.theme 优先,其次 URL query theme。两者取值约定一致
// (dark-blue → 深色;red → 浅色;blue 暂无该主题,先用浅色代替),统一走 resolveThemeFromQuery。
useEffect(() => {
const themeValue = wujieProps.theme || externalParams.theme;
if (!themeValue) return;
setTheme(resolveThemeFromQuery(themeValue));
}, [wujieProps.theme, externalParams.theme, setTheme]);
// ticket / userId / env 持久化(与 login 请求并行做,互不阻塞)
useEffect(() => {