- {form.routeParams.map((p, idx) => (
+ {form.routeParams.map((p, idx) => {
+ const themeMap =
+ p.paramType === "theme" ? parseThemeMap(p.themeValue) : {};
+ return (
-
- patchParam(idx, { key: e.target.value })}
- placeholder="参数名 key"
- className="h-8 w-full rounded-[2px] border border-[#DBDBDB] bg-white px-2 font-mono text-[12px] focus:border-[#F5222D] focus:outline-none focus:ring-px focus:ring-[#F5222D]"
- />
-
+
+
+ patchParam(idx, { key: e.target.value })}
+ placeholder="参数名 key"
+ className="h-8 w-full rounded-[2px] border border-[#DBDBDB] bg-white px-2 font-mono text-[12px] focus:border-[#F5222D] focus:outline-none focus:ring-px focus:ring-[#F5222D]"
+ />
+
-
-
-
+
+
+
-
- {p.paramType === "login" ? (
-
+ {p.paramType === "login" && (
+
- ) : (
-
patchParam(idx, { themeValue: e.target.value })}
- placeholder="主题值,如 dark-blue"
- className="h-8 w-full rounded-[2px] border border-[#DBDBDB] bg-white px-2 text-[12px] focus:border-[#F5222D] focus:outline-none focus:ring-px focus:ring-[#F5222D]"
- />
)}
+
+
-
+ {/* 主题参数:逐主题色配置传给目标应用的值(左=系统主题色,右=目标应用值,可改) */}
+ {p.paramType === "theme" && (
+
+
+ 各系统主题色跳转/嵌套时传给该应用的值(默认同名,可按对方命名修改)
+
+ {APP_THEME_COLORS.map((c) => (
+
+
+
+ {c.label}
+
+
+ {c.key} =
+
+
+ patchParam(idx, {
+ themeValue: stringifyThemeMap({
+ ...themeMap,
+ [c.key]: e.target.value,
+ }),
+ })
+ }
+ placeholder={c.key}
+ className="h-7 flex-1 rounded-[2px] border border-[#DBDBDB] bg-white px-2 font-mono text-[12px] focus:border-[#F5222D] focus:outline-none focus:ring-px focus:ring-[#F5222D]"
+ />
+
+ ))}
+
+ )}
- ))}
+ );
+ })}
) : (
@@ -669,6 +707,7 @@ function cleanParams(params: LightAppRouteParam[]): LightAppRouteParam[] {
base.customValue = (p.customValue ?? "").trim();
}
} else {
+ // theme:存映射串(或纯值),运行时按当前主题解析取值
base.themeValue = (p.themeValue ?? "").trim();
}
return base;
diff --git a/frontend-web/src/strategy-components/api/light-apps.ts b/frontend-web/src/strategy-components/api/light-apps.ts
index 4fa88ec9..9f476e7a 100644
--- a/frontend-web/src/strategy-components/api/light-apps.ts
+++ b/frontend-web/src/strategy-components/api/light-apps.ts
@@ -20,7 +20,7 @@ import { getBackendBaseURL } from "@/core/config";
export type LightAppType = "window_open" | "iframe";
export type RouteParamType = "login" | "theme";
-/** 路由参数项。登录参数运行时从 localStorage.userInfo 解析;主题参数用 themeValue。 */
+/** 路由参数项。登录参数运行时从 localStorage.userInfo 解析;主题参数随当前系统主题自动注入。 */
export interface LightAppRouteParam {
key: string;
paramType: RouteParamType;
@@ -28,7 +28,7 @@ export interface LightAppRouteParam {
source?: string | null;
/** 登录参数且 source==="other" 时的字面值。 */
customValue?: string | null;
- /** 主题参数的值(dark-blue / red / blue,可改)。 */
+ /** 主题参数配置:映射串 `light=red;dark=darkBlue`(或纯值);运行时按当前系统主题取对应值(见 resolveThemeParamValue)。 */
themeValue?: string | null;
}
diff --git a/frontend-web/src/strategy-components/lib/light-app.ts b/frontend-web/src/strategy-components/lib/light-app.ts
index b2066f47..5b8e66ac 100644
--- a/frontend-web/src/strategy-components/lib/light-app.ts
+++ b/frontend-web/src/strategy-components/lib/light-app.ts
@@ -27,13 +27,68 @@ export const LOGIN_SOURCE_OPTIONS: { label: string; value: string }[] = [
{ label: "其他(自定义值)", value: "other" },
];
-/** 主题参数示例值(深蓝 / 红 / 蓝),可改。 */
-export const THEME_EXAMPLE_OPTIONS: { label: string; value: string }[] = [
- { label: "深蓝色 dark-blue", value: "dark-blue" },
- { label: "红色 red", value: "red" },
- { label: "蓝色 blue", value: "blue" },
+/**
+ * 我方主题色键。当前启用 red(浅色) / dark-blue(深色);blue 为后续将新增的主题。
+ * 主题参数的映射以这些键为左侧 key(如 `dark-blue=darkBlue`)。
+ */
+export type AppThemeColor = "red" | "blue" | "dark-blue";
+
+/** 我方全部主题色(「应用管理」主题参数逐项配置目标值时遍历;dot 为配色小圆点)。 */
+export const APP_THEME_COLORS: { key: AppThemeColor; label: string; dot: string }[] = [
+ { key: "red", label: "红色", dot: "#F5222D" },
+ { key: "blue", label: "蓝色", dot: "#1677FF" },
+ { key: "dark-blue", label: "深蓝色", dot: "#002B5C" },
];
+/**
+ * 读取我方当前主题色,以 ThemeContext 写在 上的 `dark` class 为准
+ * (含嵌入场景的强制主题)。当前:深色=dark-blue,浅色=red。
+ * TODO: 后续新增 blue 主题后,在此区分 blue 与 dark-blue。
+ */
+export function getCurrentTheme(): AppThemeColor {
+ if (typeof document !== "undefined" && document.documentElement.classList.contains("dark")) {
+ return "dark-blue";
+ }
+ return "red";
+}
+
+/** 解析主题映射串(`red=red;dark-blue=darkBlue`)为 { 主题色键: 目标值 }。值不做 trim,便于表单回显。 */
+export function parseThemeMap(raw: string | null | undefined): Record {
+ const map: Record = {};
+ for (const pair of (raw ?? "").split(/[;,]/)) {
+ const idx = pair.search(/[=:]/);
+ if (idx <= 0) continue;
+ const k = pair.slice(0, idx).trim().toLowerCase();
+ map[k] = pair.slice(idx + 1);
+ }
+ return map;
+}
+
+/** 把主题映射对象序列化为映射串,按 APP_THEME_COLORS 顺序输出,缺省走同名(identity)。 */
+export function stringifyThemeMap(map: Record): string {
+ return APP_THEME_COLORS.map((c) => `${c.key}=${map[c.key] ?? c.key}`).join(";");
+}
+
+/**
+ * 按我方当前主题,从配置中取目标轻应用对应的值(跳转 / iframe 嵌套时注入)。
+ *
+ * 配置支持两种写法(管理员在「应用管理」主题参数里配置):
+ * 1) 映射串:`red=red;blue=blue;dark-blue=darkBlue` —— 按当前主题取对应值;
+ * 缺当前主题映射时回退到 red,再回退到首个值,最后回退到主题色名本身。
+ * 2) 纯值:`red` —— 不区分主题,原样返回。
+ */
+export function resolveThemeParamValue(
+ raw: string | null | undefined,
+ theme: AppThemeColor = getCurrentTheme(),
+): string {
+ const value = (raw ?? "").trim();
+ if (!value) return theme;
+ // 不含键值分隔符 → 纯值,不区分主题原样返回
+ if (!/[=:]/.test(value)) return value;
+ const map = parseThemeMap(value);
+ return (map[theme] ?? map.red ?? Object.values(map)[0] ?? theme).trim();
+}
+
/** 读取并解析 localStorage 中的 userInfo。 */
export function readUserInfo(): Record {
try {
@@ -52,7 +107,8 @@ export function resolveRouteParamValue(
userInfo: Record = readUserInfo(),
): string {
if (param.paramType === "theme") {
- return param.themeValue ?? "";
+ // 主题参数:按我方当前系统主题,从管理员配置的映射中取目标应用对应的值。
+ return resolveThemeParamValue(param.themeValue);
}
// login
if (param.source === "other") {