@4399ywkf/cli 1.0.7 → 1.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/templates/HarmonyOS_Sans_Bold.woff2 +0 -0
- package/dist/templates/HarmonyOS_Sans_Medium.woff2 +0 -0
- package/dist/templates/HarmonyOS_Sans_Regular.woff2 +0 -0
- package/dist/templates/Locale.tsx +14 -18
- package/dist/templates/MainContentWrap.tsx +11 -15
- package/dist/templates/ThemeContext.tsx +27 -24
- package/dist/templates/app/config/env/.env.public.tpl +2 -19
- package/dist/templates/app/config/jwt/index.ts +4 -4
- package/dist/templates/app/config/request/error-handler.ts +67 -0
- package/dist/templates/app/config/request/index.ts +127 -129
- package/dist/templates/app/config/request/interceptors.ts +118 -0
- package/dist/templates/app/config/request/token-manager.ts +23 -0
- package/dist/templates/app/config/request/types.ts +63 -0
- package/dist/templates/app/config/rspack/rspack.config.mjs +62 -61
- package/dist/templates/app/config/rspack/rspack.prod.mjs +41 -62
- package/dist/templates/app/locales/zh-CN/common.json +3 -0
- package/dist/templates/app/package.json.tpl +1 -10
- package/dist/templates/app/public/fonts/HarmonyOS_Sans_Bold.woff2 +0 -0
- package/dist/templates/app/public/fonts/HarmonyOS_Sans_Medium.woff2 +0 -0
- package/dist/templates/app/public/fonts/HarmonyOS_Sans_Regular.woff2 +0 -0
- package/dist/templates/app/react-app-env.d.ts +13 -8
- package/dist/templates/app/src/bootstrap/index.ts +34 -0
- package/dist/templates/app/src/config/env.ts +84 -0
- package/dist/templates/app/src/index.tsx +17 -51
- package/dist/templates/app/src/layout/Locale.tsx +14 -18
- package/dist/templates/app/src/layout/MainContentWrap.tsx +11 -15
- package/dist/templates/app/src/layout/ThemeContext.tsx +27 -24
- package/dist/templates/app/src/locales/default/common.ts +3 -1
- package/dist/templates/app/src/micro/garfish.ts +53 -0
- package/dist/templates/app/src/pages/base/index.tsx +189 -25
- package/dist/templates/app/src/routes.tsx +21 -12
- package/dist/templates/app/src/types/global.d.ts +19 -0
- package/dist/templates/app/src/utils/index.ts +3 -1
- package/dist/templates/app/store/middleware/createDevtools.ts +7 -7
- package/dist/templates/base/index.tsx +189 -25
- package/dist/templates/bootstrap/index.ts +34 -0
- package/dist/templates/common.json +3 -0
- package/dist/templates/common.ts +3 -1
- package/dist/templates/config/env/.env.public.tpl +2 -19
- package/dist/templates/config/env.ts +84 -0
- package/dist/templates/config/jwt/index.ts +4 -4
- package/dist/templates/config/request/error-handler.ts +67 -0
- package/dist/templates/config/request/index.ts +127 -129
- package/dist/templates/config/request/interceptors.ts +118 -0
- package/dist/templates/config/request/token-manager.ts +23 -0
- package/dist/templates/config/request/types.ts +63 -0
- package/dist/templates/config/rspack/rspack.config.mjs +62 -61
- package/dist/templates/config/rspack/rspack.prod.mjs +41 -62
- package/dist/templates/createDevtools.ts +7 -7
- package/dist/templates/default/common.ts +3 -1
- package/dist/templates/env/.env.public.tpl +2 -19
- package/dist/templates/env.ts +83 -2
- package/dist/templates/error-handler.ts +67 -0
- package/dist/templates/fonts/HarmonyOS_Sans_Bold.woff2 +0 -0
- package/dist/templates/fonts/HarmonyOS_Sans_Medium.woff2 +0 -0
- package/dist/templates/fonts/HarmonyOS_Sans_Regular.woff2 +0 -0
- package/dist/templates/garfish.ts +53 -0
- package/dist/templates/global.d.ts +19 -0
- package/dist/templates/index.tsx +189 -25
- package/dist/templates/interceptors.ts +118 -0
- package/dist/templates/jwt/index.ts +4 -4
- package/dist/templates/layout/Locale.tsx +14 -18
- package/dist/templates/layout/MainContentWrap.tsx +11 -15
- package/dist/templates/layout/ThemeContext.tsx +27 -24
- package/dist/templates/locales/default/common.ts +3 -1
- package/dist/templates/locales/zh-CN/common.json +3 -0
- package/dist/templates/micro/garfish.ts +53 -0
- package/dist/templates/middleware/createDevtools.ts +7 -7
- package/dist/templates/package.json.tpl +1 -10
- package/dist/templates/page.tsx +21 -19
- package/dist/templates/pages/base/index.tsx +189 -25
- package/dist/templates/public/fonts/HarmonyOS_Sans_Bold.woff2 +0 -0
- package/dist/templates/public/fonts/HarmonyOS_Sans_Medium.woff2 +0 -0
- package/dist/templates/public/fonts/HarmonyOS_Sans_Regular.woff2 +0 -0
- package/dist/templates/react-app-env.d.ts +13 -8
- package/dist/templates/request/error-handler.ts +67 -0
- package/dist/templates/request/index.ts +127 -129
- package/dist/templates/request/interceptors.ts +118 -0
- package/dist/templates/request/token-manager.ts +23 -0
- package/dist/templates/request/types.ts +63 -0
- package/dist/templates/routes.tsx +21 -12
- package/dist/templates/rspack/rspack.config.mjs +62 -61
- package/dist/templates/rspack/rspack.prod.mjs +41 -62
- package/dist/templates/rspack.config.mjs +62 -61
- package/dist/templates/rspack.prod.mjs +41 -62
- package/dist/templates/src/bootstrap/index.ts +34 -0
- package/dist/templates/src/config/env.ts +84 -0
- package/dist/templates/src/index.tsx +17 -51
- package/dist/templates/src/layout/Locale.tsx +14 -18
- package/dist/templates/src/layout/MainContentWrap.tsx +11 -15
- package/dist/templates/src/layout/ThemeContext.tsx +27 -24
- package/dist/templates/src/locales/default/common.ts +3 -1
- package/dist/templates/src/micro/garfish.ts +53 -0
- package/dist/templates/src/pages/base/index.tsx +189 -25
- package/dist/templates/src/routes.tsx +21 -12
- package/dist/templates/src/types/global.d.ts +19 -0
- package/dist/templates/src/utils/index.ts +3 -1
- package/dist/templates/store/middleware/createDevtools.ts +7 -7
- package/dist/templates/token-manager.ts +23 -0
- package/dist/templates/types/global.d.ts +19 -0
- package/dist/templates/utils/index.ts +3 -1
- package/dist/templates/zh-CN/common.json +3 -0
- package/package.json +1 -1
- package/dist/templates/app/config/sentry/sentry.config.ts +0 -188
- package/dist/templates/app/src/hooks/useRouteTitle.tsx +0 -36
- package/dist/templates/app/src/hooks/useSentry.ts +0 -92
- package/dist/templates/app/src/pages/base/layout.tsx +0 -6
- package/dist/templates/app/src/pages/base/page.tsx +0 -25
- package/dist/templates/app/src/utils/env.ts +0 -3
- package/dist/templates/app/src/utils/format.ts +0 -21
- package/dist/templates/app/src/utils/getMicroApp.ts +0 -39
- package/dist/templates/app/src/utils/sentry.ts +0 -187
- package/dist/templates/app/src/utils/sentryDecorators.ts +0 -34
- package/dist/templates/app/src/utils/updateVersion.ts +0 -186
- package/dist/templates/base/layout.tsx +0 -6
- package/dist/templates/base/page.tsx +0 -25
- package/dist/templates/config/public/404.png +0 -0
- package/dist/templates/config/public/favicon.ico +0 -0
- package/dist/templates/config/public/images/banner_market_modal.webp +0 -0
- package/dist/templates/config/public/images/chatmode_chat_dark.webp +0 -0
- package/dist/templates/config/public/images/chatmode_chat_light.webp +0 -0
- package/dist/templates/config/public/images/chatmode_docs_dark.webp +0 -0
- package/dist/templates/config/public/images/chatmode_docs_light.webp +0 -0
- package/dist/templates/config/public/images/empty_topic_dark.webp +0 -0
- package/dist/templates/config/public/images/empty_topic_light.webp +0 -0
- package/dist/templates/config/public/images/screenshot_background.webp +0 -0
- package/dist/templates/config/public/images/theme_auto.webp +0 -0
- package/dist/templates/config/public/images/theme_dark.webp +0 -0
- package/dist/templates/config/public/images/theme_light.webp +0 -0
- package/dist/templates/config/public/index.html +0 -29
- package/dist/templates/config/sentry/sentry.config.ts +0 -188
- package/dist/templates/format.ts +0 -21
- package/dist/templates/getMicroApp.ts +0 -39
- package/dist/templates/hooks/useRouteTitle.tsx +0 -36
- package/dist/templates/hooks/useSentry.ts +0 -92
- package/dist/templates/layout.tsx +0 -6
- package/dist/templates/pages/base/layout.tsx +0 -6
- package/dist/templates/pages/base/page.tsx +0 -25
- package/dist/templates/sentry/sentry.config.ts +0 -188
- package/dist/templates/sentry.config.ts +0 -188
- package/dist/templates/sentry.ts +0 -187
- package/dist/templates/sentryDecorators.ts +0 -34
- package/dist/templates/src/hooks/useRouteTitle.tsx +0 -36
- package/dist/templates/src/hooks/useSentry.ts +0 -92
- package/dist/templates/src/pages/base/layout.tsx +0 -6
- package/dist/templates/src/pages/base/page.tsx +0 -25
- package/dist/templates/src/utils/env.ts +0 -3
- package/dist/templates/src/utils/format.ts +0 -21
- package/dist/templates/src/utils/getMicroApp.ts +0 -39
- package/dist/templates/src/utils/sentry.ts +0 -187
- package/dist/templates/src/utils/sentryDecorators.ts +0 -34
- package/dist/templates/src/utils/updateVersion.ts +0 -186
- package/dist/templates/updateVersion.ts +0 -186
- package/dist/templates/useRouteTitle.tsx +0 -36
- package/dist/templates/useSentry.ts +0 -92
- package/dist/templates/utils/env.ts +0 -3
- package/dist/templates/utils/format.ts +0 -21
- package/dist/templates/utils/getMicroApp.ts +0 -39
- package/dist/templates/utils/sentry.ts +0 -187
- package/dist/templates/utils/sentryDecorators.ts +0 -34
- package/dist/templates/utils/updateVersion.ts +0 -186
- /package/dist/templates/app/{config/public → public}/404.png +0 -0
- /package/dist/templates/app/{config/public → public}/favicon.ico +0 -0
- /package/dist/templates/app/{config/public → public}/images/banner_market_modal.webp +0 -0
- /package/dist/templates/app/{config/public → public}/images/chatmode_chat_dark.webp +0 -0
- /package/dist/templates/app/{config/public → public}/images/chatmode_chat_light.webp +0 -0
- /package/dist/templates/app/{config/public → public}/images/chatmode_docs_dark.webp +0 -0
- /package/dist/templates/app/{config/public → public}/images/chatmode_docs_light.webp +0 -0
- /package/dist/templates/app/{config/public → public}/images/empty_topic_dark.webp +0 -0
- /package/dist/templates/app/{config/public → public}/images/empty_topic_light.webp +0 -0
- /package/dist/templates/app/{config/public → public}/images/screenshot_background.webp +0 -0
- /package/dist/templates/app/{config/public → public}/images/theme_auto.webp +0 -0
- /package/dist/templates/app/{config/public → public}/images/theme_dark.webp +0 -0
- /package/dist/templates/app/{config/public → public}/images/theme_light.webp +0 -0
- /package/dist/templates/app/{config/public → public}/index.html +0 -0
|
@@ -59,20 +59,11 @@
|
|
|
59
59
|
"universal-cookie": "^8.0.1",
|
|
60
60
|
"url-join": "^5.0.0",
|
|
61
61
|
"uuid": "^11.0.3",
|
|
62
|
+
"zod": "^4.2.1",
|
|
62
63
|
"zustand": "^5.0.5",
|
|
63
64
|
"zustand-utils": "^2.1.1"
|
|
64
65
|
},
|
|
65
66
|
"devDependencies": {
|
|
66
|
-
"@babel/core": "^7.26.0",
|
|
67
|
-
"@babel/plugin-proposal-class-properties": "^7.18.6",
|
|
68
|
-
"@babel/plugin-proposal-decorators": "^7.25.9",
|
|
69
|
-
"@babel/plugin-proposal-optional-chaining": "^7.21.0",
|
|
70
|
-
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
|
|
71
|
-
"@babel/plugin-transform-runtime": "^7.25.9",
|
|
72
|
-
"@babel/preset-env": "^7.26.0",
|
|
73
|
-
"@babel/preset-react": "^7.25.9",
|
|
74
|
-
"@babel/runtime": "^7.26.0",
|
|
75
|
-
"@babel/runtime-corejs3": "^7.26.0",
|
|
76
67
|
"@biomejs/biome": "2.3.2",
|
|
77
68
|
"@pmmmwh/react-refresh-webpack-plugin": "^0.5.15",
|
|
78
69
|
"@rsdoctor/rspack-plugin": "^1.3.8",
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1,13 +1,18 @@
|
|
|
1
1
|
// typings.d.ts
|
|
2
|
-
declare module
|
|
3
|
-
declare module
|
|
4
|
-
declare module
|
|
5
|
-
declare module
|
|
6
|
-
declare module
|
|
7
|
-
declare module
|
|
8
|
-
declare module
|
|
2
|
+
declare module "*.css";
|
|
3
|
+
declare module "*.less";
|
|
4
|
+
declare module "*.png";
|
|
5
|
+
declare module "*.jpeg";
|
|
6
|
+
declare module "*.jpg";
|
|
7
|
+
declare module "*.scss";
|
|
8
|
+
declare module "*.woff";
|
|
9
|
+
declare module "*.woff2";
|
|
10
|
+
declare module "*.ttf";
|
|
11
|
+
declare module "*.eot";
|
|
12
|
+
declare module "*.otf";
|
|
13
|
+
declare module "*.svg" {
|
|
9
14
|
export function ReactComponent(
|
|
10
|
-
props: React.SVGProps<SVGSVGElement
|
|
15
|
+
props: React.SVGProps<SVGSVGElement>
|
|
11
16
|
): React.ReactElement;
|
|
12
17
|
const url: string;
|
|
13
18
|
export default url;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import "dayjs/locale/zh-cn";
|
|
2
|
+
import dayjs from "dayjs";
|
|
3
|
+
import { ConfigProvider } from "antd";
|
|
4
|
+
import { env } from "@/config/env";
|
|
5
|
+
|
|
6
|
+
interface BootstrapConfig {
|
|
7
|
+
appName: string;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* 应用启动前的初始化配置
|
|
12
|
+
*/
|
|
13
|
+
export function bootstrap(config: BootstrapConfig) {
|
|
14
|
+
const { appName } = config;
|
|
15
|
+
|
|
16
|
+
// 配置 dayjs 国际化
|
|
17
|
+
dayjs.locale("zh-cn");
|
|
18
|
+
|
|
19
|
+
// 配置 antd 静态方法的前缀
|
|
20
|
+
ConfigProvider.config({
|
|
21
|
+
prefixCls: appName,
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
console.log(`✅ Application [${appName}] bootstrapped successfully`);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* 使用环境变量初始化应用
|
|
29
|
+
*/
|
|
30
|
+
export function bootstrapWithEnv() {
|
|
31
|
+
bootstrap({
|
|
32
|
+
appName: env.APP_NAME,
|
|
33
|
+
});
|
|
34
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* 环境变量 Schema 定义
|
|
5
|
+
*/
|
|
6
|
+
const envSchema = z.object({
|
|
7
|
+
// Node 环境
|
|
8
|
+
NODE_ENV: z
|
|
9
|
+
.enum(["development", "test", "testDevelopment", "production"])
|
|
10
|
+
.default("development"),
|
|
11
|
+
|
|
12
|
+
// 应用配置
|
|
13
|
+
APP_NAME: z.string().min(1, "应用名称不能为空").default("app"),
|
|
14
|
+
APP_CNAME: z.string().default("应用"),
|
|
15
|
+
BASENAME: z.string().optional(),
|
|
16
|
+
|
|
17
|
+
// API 配置
|
|
18
|
+
API_PREFIX: z.string().default("/api"),
|
|
19
|
+
API_TIMEOUT: z
|
|
20
|
+
.string()
|
|
21
|
+
.transform(Number)
|
|
22
|
+
.pipe(z.number().positive())
|
|
23
|
+
.default(30000),
|
|
24
|
+
|
|
25
|
+
// Cookie 配置
|
|
26
|
+
COOKIE_NAME: z.string().default("access_token"),
|
|
27
|
+
|
|
28
|
+
// 其他配置
|
|
29
|
+
HELP_CENTER_URL: z.string().url().optional(),
|
|
30
|
+
OUTPUT_PATH: z.string().default("dist"),
|
|
31
|
+
PUBLIC_PATH: z.string().default("/"),
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* 安全解析环境变量(开发模式下使用默认值)
|
|
36
|
+
*/
|
|
37
|
+
function safeParseEnv() {
|
|
38
|
+
const result = envSchema.safeParse(process.env);
|
|
39
|
+
|
|
40
|
+
if (!result.success) {
|
|
41
|
+
if (process.env.NODE_ENV === "production") {
|
|
42
|
+
// 生产环境严格校验
|
|
43
|
+
console.error("❌ 环境变量验证失败:");
|
|
44
|
+
result.error.issues.forEach((err) => {
|
|
45
|
+
console.error(` - ${err.path.join(".")}: ${err.message}`);
|
|
46
|
+
});
|
|
47
|
+
throw new Error("环境变量配置错误");
|
|
48
|
+
} else {
|
|
49
|
+
// 开发环境警告但不中断
|
|
50
|
+
console.warn("⚠️ 环境变量验证警告:");
|
|
51
|
+
result.error.issues.forEach((err) => {
|
|
52
|
+
console.warn(` - ${err.path.join(".")}: ${err.message}`);
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return result.success ? result.data : envSchema.parse({});
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* 导出类型安全的环境变量
|
|
62
|
+
*/
|
|
63
|
+
export const env = safeParseEnv();
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* 环境变量类型
|
|
67
|
+
*/
|
|
68
|
+
export type Env = z.infer<typeof envSchema>;
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* 工具函数:判断是否为开发环境
|
|
72
|
+
*/
|
|
73
|
+
export const isDev = env.NODE_ENV === "development";
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* 工具函数:判断是否为生产环境
|
|
77
|
+
*/
|
|
78
|
+
export const isProd = env.NODE_ENV === "production";
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* 工具函数:判断是否为测试环境
|
|
82
|
+
*/
|
|
83
|
+
export const isTest =
|
|
84
|
+
env.NODE_ENV === "test" || env.NODE_ENV === "testDevelopment";
|
|
@@ -1,53 +1,19 @@
|
|
|
1
|
-
import "dayjs/locale/zh-cn";
|
|
2
|
-
|
|
3
|
-
import { renderClient } from "@config/router";
|
|
4
|
-
import { ConfigProvider } from "antd";
|
|
5
|
-
import dayjs from "dayjs";
|
|
6
|
-
import React from "react";
|
|
7
|
-
|
|
8
|
-
import { createRouter } from "@/routes";
|
|
9
|
-
import { openUpdateVersionNotify } from "@/utils/updateVersion";
|
|
10
|
-
|
|
11
|
-
dayjs.locale("zh-cn");
|
|
12
|
-
|
|
13
1
|
import "./index.css";
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
//
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
// 子应用接入
|
|
32
|
-
export const provider = () => {
|
|
33
|
-
let root: any = null;
|
|
34
|
-
return {
|
|
35
|
-
destroy() {
|
|
36
|
-
root?.unmount();
|
|
37
|
-
},
|
|
38
|
-
render({ basename }) {
|
|
39
|
-
// 更改basename的值
|
|
40
|
-
context.basename = basename;
|
|
41
|
-
root = renderClient(context);
|
|
42
|
-
window.Garfish.channel.emit("router", {
|
|
43
|
-
name: AppName,
|
|
44
|
-
routes: createRouter(basename),
|
|
45
|
-
});
|
|
46
|
-
},
|
|
47
|
-
};
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
// 添加单独启动逻辑
|
|
51
|
-
if (!window.__GARFISH__) {
|
|
52
|
-
renderClient(context);
|
|
2
|
+
import { renderClient } from "@config/router";
|
|
3
|
+
import { bootstrapWithEnv } from "@/bootstrap";
|
|
4
|
+
import { createGarfishProvider, isMicroApp } from "@/micro/garfish";
|
|
5
|
+
import { env } from "@/config/env";
|
|
6
|
+
|
|
7
|
+
// 初始化应用
|
|
8
|
+
bootstrapWithEnv();
|
|
9
|
+
|
|
10
|
+
// 微前端模式:导出 Garfish 生命周期
|
|
11
|
+
export const provider = createGarfishProvider(env.APP_NAME);
|
|
12
|
+
|
|
13
|
+
// 独立运行模式:直接渲染
|
|
14
|
+
if (!isMicroApp()) {
|
|
15
|
+
renderClient({
|
|
16
|
+
basename: env.BASENAME,
|
|
17
|
+
rootElement: document.getElementById(env.APP_NAME) ?? document.body,
|
|
18
|
+
});
|
|
53
19
|
}
|
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
import { ConfigProvider } from
|
|
2
|
-
import type { Locale as AntdLocale } from
|
|
3
|
-
import dayjs from
|
|
1
|
+
import { ConfigProvider } from "antd";
|
|
2
|
+
import type { Locale as AntdLocale } from "antd/es/locale";
|
|
3
|
+
import dayjs from "dayjs";
|
|
4
4
|
import React, {
|
|
5
5
|
type PropsWithChildren,
|
|
6
6
|
memo,
|
|
7
7
|
useEffect,
|
|
8
8
|
useState,
|
|
9
|
-
} from
|
|
9
|
+
} from "react";
|
|
10
10
|
|
|
11
|
-
import { isRtlLang } from
|
|
11
|
+
import { isRtlLang } from "rtl-detect";
|
|
12
12
|
|
|
13
|
-
import { createI18nNext } from
|
|
14
|
-
import { getAntdLocale } from
|
|
13
|
+
import { createI18nNext } from "@/locales/create";
|
|
14
|
+
import { getAntdLocale } from "@/utils/locale";
|
|
15
15
|
|
|
16
16
|
const updateDayjs = async (lang: string) => {
|
|
17
17
|
// load default lang
|
|
@@ -19,12 +19,12 @@ const updateDayjs = async (lang: string) => {
|
|
|
19
19
|
try {
|
|
20
20
|
// dayjs locale is using `en` instead of `en-US`
|
|
21
21
|
// refs: https://github.com/lobehub/lobe-chat/issues/3396
|
|
22
|
-
const locale = lang.toLowerCase() ===
|
|
22
|
+
const locale = lang.toLowerCase() === "en-us" ? "en" : lang.toLowerCase();
|
|
23
23
|
|
|
24
24
|
dayJSLocale = await import(`dayjs/locale/${locale}.js`);
|
|
25
25
|
} catch {
|
|
26
26
|
console.warn(`dayjs locale for ${lang} not found, fallback to en`);
|
|
27
|
-
dayJSLocale = await import(
|
|
27
|
+
dayJSLocale = await import("dayjs/locale/en.js");
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
dayjs.locale(dayJSLocale.default);
|
|
@@ -41,8 +41,6 @@ const Locale = memo<LocaleLayoutProps>(
|
|
|
41
41
|
const [lang, setLang] = useState(defaultLang);
|
|
42
42
|
const [locale, setLocale] = useState(antdLocale);
|
|
43
43
|
|
|
44
|
-
console.log(antdLocale, defaultLang);
|
|
45
|
-
|
|
46
44
|
// if on browser side, init i18n instance only once
|
|
47
45
|
if (!i18n.instance.isInitialized)
|
|
48
46
|
// console.debug('locale', lang);
|
|
@@ -65,25 +63,23 @@ const Locale = memo<LocaleLayoutProps>(
|
|
|
65
63
|
await updateDayjs(lng);
|
|
66
64
|
};
|
|
67
65
|
|
|
68
|
-
i18n.instance.on(
|
|
66
|
+
i18n.instance.on("languageChanged", handleLang);
|
|
69
67
|
return () => {
|
|
70
|
-
i18n.instance.off(
|
|
68
|
+
i18n.instance.off("languageChanged", handleLang);
|
|
71
69
|
};
|
|
72
70
|
}, [i18n, lang]);
|
|
73
71
|
|
|
74
72
|
// detect document direction
|
|
75
|
-
const documentDir = isRtlLang(lang) ?
|
|
76
|
-
|
|
77
|
-
console.log(documentDir, locale);
|
|
73
|
+
const documentDir = isRtlLang(lang) ? "rtl" : "ltr";
|
|
78
74
|
|
|
79
75
|
return (
|
|
80
76
|
<ConfigProvider direction={documentDir} locale={locale as AntdLocale}>
|
|
81
77
|
{children}
|
|
82
78
|
</ConfigProvider>
|
|
83
79
|
);
|
|
84
|
-
}
|
|
80
|
+
}
|
|
85
81
|
);
|
|
86
82
|
|
|
87
|
-
Locale.displayName =
|
|
83
|
+
Locale.displayName = "Locale";
|
|
88
84
|
|
|
89
85
|
export default Locale;
|
|
@@ -1,19 +1,15 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import type { Locale as AntdLocale } from 'antd/es/locale';
|
|
3
|
-
import React, { useState, useEffect } from 'react';
|
|
1
|
+
import React, { useState, useEffect } from "react";
|
|
4
2
|
|
|
5
|
-
import { QueryClient, QueryClientProvider } from
|
|
6
|
-
import { Outlet } from
|
|
7
|
-
import
|
|
8
|
-
import { DEFAULT_LANG } from
|
|
9
|
-
import {
|
|
10
|
-
import
|
|
11
|
-
import
|
|
12
|
-
import
|
|
13
|
-
import AppTheme from './ThemeContext';
|
|
3
|
+
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
|
4
|
+
import { Outlet } from "react-router";
|
|
5
|
+
import "../index.css";
|
|
6
|
+
import { DEFAULT_LANG } from "@/const/locale";
|
|
7
|
+
import { getAntdLocale } from "@/utils";
|
|
8
|
+
import queryString from "query-string";
|
|
9
|
+
import Locale from "./Locale";
|
|
10
|
+
import AppTheme from "./ThemeContext";
|
|
14
11
|
|
|
15
12
|
export const MainContentWrap = () => {
|
|
16
|
-
useRouteTitle();
|
|
17
13
|
const [antdLocale, setAntdLocale] = useState<unknown>(null);
|
|
18
14
|
const [isLocaleLoaded, setIsLocaleLoaded] = useState(false);
|
|
19
15
|
|
|
@@ -32,11 +28,11 @@ export const MainContentWrap = () => {
|
|
|
32
28
|
const loadLocale = async () => {
|
|
33
29
|
try {
|
|
34
30
|
const loadedLocale = await getAntdLocale(
|
|
35
|
-
(lang as string) ?? DEFAULT_LANG
|
|
31
|
+
(lang as string) ?? DEFAULT_LANG
|
|
36
32
|
);
|
|
37
33
|
setAntdLocale(loadedLocale);
|
|
38
34
|
} catch (error) {
|
|
39
|
-
console.error(
|
|
35
|
+
console.error("Failed to load locale:", error);
|
|
40
36
|
// 保持默认的中文 locale
|
|
41
37
|
} finally {
|
|
42
38
|
setIsLocaleLoaded(true);
|
|
@@ -1,14 +1,16 @@
|
|
|
1
|
-
import ThemeProvider from
|
|
2
|
-
import { CLOUD_THEME_APPEARANCE } from
|
|
3
|
-
import { setCookie } from
|
|
1
|
+
import ThemeProvider from "@/components/ThemeProvider";
|
|
2
|
+
import { CLOUD_THEME_APPEARANCE } from "@/const/theme";
|
|
3
|
+
import { setCookie } from "@/utils/cookie";
|
|
4
4
|
|
|
5
5
|
// import { useGlobalStore } from "@store/global";
|
|
6
|
-
import React, { memo, useEffect, type ReactNode } from
|
|
6
|
+
import React, { memo, useEffect, type ReactNode } from "react";
|
|
7
|
+
|
|
8
|
+
import { SYSTEM_PREFIX } from "@/const/system";
|
|
9
|
+
import { GlobalStyle } from "@/styles";
|
|
10
|
+
import { useUserStore } from "@store/user";
|
|
11
|
+
import { createStyles } from "antd-style";
|
|
12
|
+
import HarmonyOS_Sans_Regular from "@public/fonts/HarmonyOS_Sans_Regular.woff2";
|
|
7
13
|
|
|
8
|
-
import { SYSTEM_PREFIX } from '@/const/system';
|
|
9
|
-
import { GlobalStyle } from '@/styles';
|
|
10
|
-
import { useUserStore } from '@store/user';
|
|
11
|
-
import { createStyles } from 'antd-style';
|
|
12
14
|
const useStyles = createStyles(({ css, token }) => ({
|
|
13
15
|
app: css`
|
|
14
16
|
position: relative;
|
|
@@ -70,55 +72,56 @@ interface AppThemeProps {
|
|
|
70
72
|
}
|
|
71
73
|
|
|
72
74
|
const AppTheme = memo(({ children }: AppThemeProps) => {
|
|
73
|
-
const themeMode = useUserStore(s => s.themeMode);
|
|
74
|
-
const animationMode = useUserStore(s => s.animationMode);
|
|
75
|
-
const neutralColor = useUserStore(s => s.neutralColor);
|
|
76
|
-
const primaryColor = useUserStore(s => s.primaryColor);
|
|
75
|
+
const themeMode = useUserStore((s) => s.themeMode);
|
|
76
|
+
const animationMode = useUserStore((s) => s.animationMode);
|
|
77
|
+
const neutralColor = useUserStore((s) => s.neutralColor);
|
|
78
|
+
const primaryColor = useUserStore((s) => s.primaryColor);
|
|
77
79
|
const { styles, cx } = useStyles();
|
|
78
80
|
|
|
79
81
|
useEffect(() => {
|
|
80
82
|
// Update data-theme accordingly if user selects light or dark
|
|
81
|
-
if (themeMode !==
|
|
83
|
+
if (themeMode !== "auto") {
|
|
82
84
|
document.documentElement.dataset.theme = themeMode;
|
|
83
85
|
return;
|
|
84
86
|
}
|
|
85
87
|
|
|
86
88
|
// For auto mode, we need to watch system preferences
|
|
87
|
-
const mediaQuery = window.matchMedia(
|
|
89
|
+
const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
|
|
88
90
|
|
|
89
91
|
// Set initial theme based on system preference
|
|
90
92
|
document.documentElement.dataset.theme = mediaQuery.matches
|
|
91
|
-
?
|
|
92
|
-
:
|
|
93
|
+
? "dark"
|
|
94
|
+
: "light";
|
|
93
95
|
|
|
94
96
|
// Update theme when system preference changes
|
|
95
97
|
function handleChange(e) {
|
|
96
|
-
document.documentElement.dataset.theme = e.matches ?
|
|
98
|
+
document.documentElement.dataset.theme = e.matches ? "dark" : "light";
|
|
97
99
|
}
|
|
98
100
|
|
|
99
|
-
mediaQuery.addEventListener(
|
|
100
|
-
return () => mediaQuery.removeEventListener(
|
|
101
|
+
mediaQuery.addEventListener("change", handleChange);
|
|
102
|
+
return () => mediaQuery.removeEventListener("change", handleChange);
|
|
101
103
|
}, [themeMode]);
|
|
102
104
|
|
|
103
105
|
return (
|
|
104
106
|
<ThemeProvider
|
|
105
107
|
prefixCls={SYSTEM_PREFIX}
|
|
106
|
-
appearance={themeMode !==
|
|
108
|
+
appearance={themeMode !== "auto" ? themeMode : undefined}
|
|
107
109
|
className={cx(styles.app, styles.scrollbar, styles.scrollbarPolyfill)}
|
|
108
110
|
customTheme={{
|
|
109
111
|
neutralColor: neutralColor,
|
|
110
112
|
primaryColor: primaryColor,
|
|
111
113
|
}}
|
|
114
|
+
customFonts={[HarmonyOS_Sans_Regular]}
|
|
112
115
|
theme={{
|
|
113
116
|
cssVar: true,
|
|
114
117
|
token: {
|
|
115
|
-
motion: animationMode !==
|
|
116
|
-
motionUnit: animationMode ===
|
|
118
|
+
motion: animationMode !== "disabled",
|
|
119
|
+
motionUnit: animationMode === "agile" ? 0.05 : 0.1,
|
|
117
120
|
},
|
|
118
121
|
}}
|
|
119
122
|
themeMode={themeMode}
|
|
120
|
-
onAppearanceChange={appearance => {
|
|
121
|
-
if (themeMode !==
|
|
123
|
+
onAppearanceChange={(appearance) => {
|
|
124
|
+
if (themeMode !== "auto") return;
|
|
122
125
|
|
|
123
126
|
setCookie(CLOUD_THEME_APPEARANCE, appearance);
|
|
124
127
|
}}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import type { Root } from "react-dom";
|
|
2
|
+
import { renderClient } from "@config/router";
|
|
3
|
+
import { createRouter } from "@/routes";
|
|
4
|
+
|
|
5
|
+
interface GarfishProvider {
|
|
6
|
+
render: (props: { basename: string }) => void;
|
|
7
|
+
destroy: () => void;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
interface RenderContext {
|
|
11
|
+
basename?: string;
|
|
12
|
+
rootElement: HTMLElement | null;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Garfish 微前端生命周期适配器
|
|
17
|
+
*/
|
|
18
|
+
export function createGarfishProvider(appName: string): GarfishProvider {
|
|
19
|
+
let root: Root | null = null;
|
|
20
|
+
|
|
21
|
+
return {
|
|
22
|
+
render({ basename }: { basename: string }) {
|
|
23
|
+
const context: RenderContext = {
|
|
24
|
+
basename,
|
|
25
|
+
rootElement: document.getElementById(appName) ?? document.body,
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
root = renderClient(context);
|
|
29
|
+
|
|
30
|
+
// 向主应用通知路由信息
|
|
31
|
+
if (window.Garfish?.channel) {
|
|
32
|
+
window.Garfish.channel.emit("router", {
|
|
33
|
+
name: appName,
|
|
34
|
+
routes: createRouter(basename),
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
|
|
39
|
+
destroy() {
|
|
40
|
+
if (root) {
|
|
41
|
+
root.unmount();
|
|
42
|
+
root = null;
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* 判断是否在微前端环境中运行
|
|
50
|
+
*/
|
|
51
|
+
export function isMicroApp(): boolean {
|
|
52
|
+
return typeof window !== "undefined" && Boolean(window.__GARFISH__);
|
|
53
|
+
}
|