Skip to content

Commit 2c3d8fd

Browse files
authored
Merge pull request #62 from AIDotNet/feature/i18n
添加国际化支持,集成i18next库,新增语言切换器组件,更新多个页面以支持多语言显示。更新package.json以包含相关依赖,并在应…
2 parents 145b021 + 2714c91 commit 2c3d8fd

18 files changed

Lines changed: 1683 additions & 661 deletions

File tree

lobe/.cursor/rules/all.mdc

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
---
2+
description:
3+
globs:
4+
alwaysApply: true
5+
---
6+
<role>
7+
您是专业的React UI设计师
8+
</role>
9+
10+
<task_analysis>
11+
- 分析用户需求,将其拆解为多个具体任务
12+
- 每个任务包含简洁标题和详细描述
13+
- 任务描述应体现专业性,提供实际执行方案
14+
</task_analysis>
15+
16+
<ui_design_process>
17+
1. 整合当前页面布局和功能
18+
2. 结合用户需求进行分析
19+
3. 应用设计学原则,提出优化的UI设计方案
20+
4. 将设计方案整合到任务描述中
21+
</ui_design_process>
22+
23+
<output_format>
24+
为每个拆解的任务提供:
25+
- 任务标题: [简洁描述]
26+
- 任务描述:
27+
• [详细的执行方案]
28+
• [设计学原则应用]
29+
• [与现有UI的整合考虑]
30+
</output_format>
31+
32+
<design_principles>
33+
- 保持一致性
34+
- 简洁明了
35+
- 用户友好
36+
- 视觉层次
37+
- 响应式设计
38+
- 适当的色彩运用
39+
- 易于导航
40+
</design_principles>
41+
42+
<quality_criteria>
43+
- 任务拆解应全面覆盖用户需求
44+
- 描述应专业、具体且可执行
45+
- UI设计方案应符合现代设计趋势
46+
- 确保新设计与现有页面协调一致
47+
48+
</quality_criteria>

lobe/package.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,18 +24,22 @@
2424
"antd": "^5.18.3",
2525
"antd-style": "^3.6.2",
2626
"framer-motion": "^12.4.7",
27+
"i18next": "^25.0.1",
28+
"i18next-browser-languagedetector": "^8.0.5",
2729
"lucide-react": "^0.397.0",
2830
"marked": "^12.0.2",
2931
"qrcode.react": "^3.1.0",
3032
"react": "^18.2.0",
3133
"react-dom": "^18.2.0",
34+
"react-i18next": "^15.5.1",
3235
"react-intersection-observer": "^9.15.1",
3336
"react-responsive": "^10.0.0",
3437
"react-router-dom": "^6.23.1",
3538
"styled-components": "^6.1.11",
3639
"ua-parser-js": "^1.0.37"
3740
},
3841
"devDependencies": {
42+
"@types/node": "^22.14.1",
3943
"@types/react": "^18.2.66",
4044
"@types/react-dom": "^18.2.22",
4145
"@types/react-responsive": "^8.0.8",

lobe/src/App.tsx

Lines changed: 128 additions & 126 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { ThemeProvider } from '@lobehub/ui'
44
import MainLayout from './_layout'
55
import { RouterProvider, createBrowserRouter } from 'react-router-dom'
66
import { lazy, Suspense } from 'react'
7+
import { useTranslation } from 'react-i18next'
78

89
import Nav from './components/@nav/default'
910
import useThemeStore from './store/theme'
@@ -28,134 +29,135 @@ const PanelPage = lazy(() => import('./pages/panel/page'))
2829
const ModelMapPage = lazy(() => import('./pages/model-map/page'))
2930
const UserGroupPage = lazy(() => import('./pages/user-group/page'))
3031

31-
const router = createBrowserRouter([{
32-
element: <MainLayout nav={<Nav />} />,
33-
children: [
34-
{
35-
path: 'panel', element: <Suspense fallback={<FullscreenLoading title='加载面板中' />}>
36-
<PanelPage />
37-
</Suspense>
38-
},
39-
{
40-
path: 'channel', element: <Suspense fallback={<FullscreenLoading title='加载渠道中' />}>
41-
<ChannelPage />
42-
</Suspense>
43-
},
44-
{
45-
path: 'token', element: <Suspense fallback={<FullscreenLoading title='加载Token管理中' />}>
46-
<TokenPage />
47-
</Suspense>
48-
},
49-
{
50-
path: 'model-manager', element: <Suspense fallback={<FullscreenLoading title='加载模型管理中' />}>
51-
<ModelManager />
52-
</Suspense>
53-
},
54-
{
55-
path: 'product', element: <Suspense fallback={<FullscreenLoading title='加载产品页面中' />}>
56-
<ProductPage />
57-
</Suspense>
58-
},
59-
{
60-
path: 'logger', element: <Suspense fallback={<FullscreenLoading title='加载日志页面中' />}>
61-
<LoggerPage />
62-
</Suspense>
63-
},
64-
{
65-
path: 'redeem-code', element: <Suspense fallback={<FullscreenLoading title='加载兑换码页面中' />}>
66-
<RedeemCodePage />
67-
</Suspense>
68-
},
69-
{
70-
path: 'user', element: <Suspense fallback={<FullscreenLoading title='加载用户页面中' />}>
71-
<UserPage />
72-
</Suspense>
73-
},
74-
{
75-
path: 'current', element: <Suspense fallback={<FullscreenLoading title='加载当前页面中' />}>
76-
<CurrentPage />
77-
</Suspense>
78-
},
79-
{
80-
path: 'setting', element: <Suspense fallback={<FullscreenLoading title='加载设置页面中' />}>
81-
<SettingPage />
82-
</Suspense>
83-
},
84-
{
85-
path: 'rate-limit', element: <Suspense fallback={<FullscreenLoading title='加载限速页面中' />}>
86-
<RateLimit />
87-
</Suspense>
88-
},
89-
{
90-
path: 'model-map', element: <Suspense fallback={<FullscreenLoading title='加载模型映射页面中' />}>
91-
<ModelMapPage />
92-
</Suspense>
93-
},
94-
{
95-
path: 'user-group', element: <Suspense fallback={<FullscreenLoading title='加载用户分组页面中' />}>
96-
<UserGroupPage />
97-
</Suspense>
98-
}
99-
]
100-
}, {
101-
path: "/login",
102-
element: <Suspense fallback={<FullscreenLoading title='加载登录页面中' />}>
103-
<LoginPage />
104-
</Suspense>
105-
}, {
106-
path: "/register",
107-
element: <Suspense fallback={<FullscreenLoading title='加载注册页面中' />}>
108-
<RegisterPage />
109-
</Suspense>
110-
}, {
111-
path: "/auth",
112-
element: <Suspense fallback={<FullscreenLoading title='加载认证页面中' />}>
113-
<Auth />
114-
</Suspense>
115-
}, {
116-
path: "/auth/gitee",
117-
element: <Suspense fallback={<FullscreenLoading title='加载认证页面中' />}>
118-
<Auth />
119-
</Suspense>
120-
}, {
121-
path: "/auth/casdoor",
122-
element: <Suspense fallback={<FullscreenLoading title='加载认证页面中' />}>
123-
<Auth />
124-
</Suspense>
125-
},
126-
{
127-
element: <Suspense fallback={<FullscreenLoading title='加载默认布局中' />}>
128-
<DefaultLayout />
129-
</Suspense>,
130-
children: [
131-
{
132-
path: '', element: <Suspense fallback={<FullscreenLoading title='加载欢迎页面中' />}>
133-
<WelcomePage />
134-
</Suspense>
135-
},
136-
{
137-
path: "/doc",
138-
element: <Suspense fallback={<FullscreenLoading title='加载文档页面中' />}>
139-
<DocPage />
140-
</Suspense>
141-
}, {
142-
path: "/doc/*",
143-
element: <Suspense fallback={<FullscreenLoading title='加载文档页面中' />}>
144-
<DocPage />
145-
</Suspense>
146-
}, {
147-
path: "/model",
148-
element: <Suspense fallback={<FullscreenLoading title='加载模型页面中' />}>
149-
<ModelPage />
150-
</Suspense>
151-
},
152-
]
153-
},
154-
155-
])
156-
15732
function App() {
15833
const { themeMode, toggleTheme } = useThemeStore();
34+
const { t } = useTranslation();
35+
36+
const router = createBrowserRouter([{
37+
element: <MainLayout nav={<Nav />} />,
38+
children: [
39+
{
40+
path: 'panel', element: <Suspense fallback={<FullscreenLoading title={t('pageTitle.loading.panel')} />}>
41+
<PanelPage />
42+
</Suspense>
43+
},
44+
{
45+
path: 'channel', element: <Suspense fallback={<FullscreenLoading title={t('pageTitle.loading.channel')} />}>
46+
<ChannelPage />
47+
</Suspense>
48+
},
49+
{
50+
path: 'token', element: <Suspense fallback={<FullscreenLoading title={t('pageTitle.loading.token')} />}>
51+
<TokenPage />
52+
</Suspense>
53+
},
54+
{
55+
path: 'model-manager', element: <Suspense fallback={<FullscreenLoading title={t('pageTitle.loading.modelManager')} />}>
56+
<ModelManager />
57+
</Suspense>
58+
},
59+
{
60+
path: 'product', element: <Suspense fallback={<FullscreenLoading title={t('pageTitle.loading.product')} />}>
61+
<ProductPage />
62+
</Suspense>
63+
},
64+
{
65+
path: 'logger', element: <Suspense fallback={<FullscreenLoading title={t('pageTitle.loading.logger')} />}>
66+
<LoggerPage />
67+
</Suspense>
68+
},
69+
{
70+
path: 'redeem-code', element: <Suspense fallback={<FullscreenLoading title={t('pageTitle.loading.redeemCode')} />}>
71+
<RedeemCodePage />
72+
</Suspense>
73+
},
74+
{
75+
path: 'user', element: <Suspense fallback={<FullscreenLoading title={t('pageTitle.loading.user')} />}>
76+
<UserPage />
77+
</Suspense>
78+
},
79+
{
80+
path: 'current', element: <Suspense fallback={<FullscreenLoading title={t('pageTitle.loading.current')} />}>
81+
<CurrentPage />
82+
</Suspense>
83+
},
84+
{
85+
path: 'setting', element: <Suspense fallback={<FullscreenLoading title={t('pageTitle.loading.setting')} />}>
86+
<SettingPage />
87+
</Suspense>
88+
},
89+
{
90+
path: 'rate-limit', element: <Suspense fallback={<FullscreenLoading title={t('pageTitle.loading.rateLimit')} />}>
91+
<RateLimit />
92+
</Suspense>
93+
},
94+
{
95+
path: 'model-map', element: <Suspense fallback={<FullscreenLoading title={t('pageTitle.loading.modelMap')} />}>
96+
<ModelMapPage />
97+
</Suspense>
98+
},
99+
{
100+
path: 'user-group', element: <Suspense fallback={<FullscreenLoading title={t('pageTitle.loading.userGroup')} />}>
101+
<UserGroupPage />
102+
</Suspense>
103+
}
104+
]
105+
}, {
106+
path: "/login",
107+
element: <Suspense fallback={<FullscreenLoading title={t('pageTitle.loading.login')} />}>
108+
<LoginPage />
109+
</Suspense>
110+
}, {
111+
path: "/register",
112+
element: <Suspense fallback={<FullscreenLoading title={t('pageTitle.loading.register')} />}>
113+
<RegisterPage />
114+
</Suspense>
115+
}, {
116+
path: "/auth",
117+
element: <Suspense fallback={<FullscreenLoading title={t('pageTitle.loading.auth')} />}>
118+
<Auth />
119+
</Suspense>
120+
}, {
121+
path: "/auth/gitee",
122+
element: <Suspense fallback={<FullscreenLoading title={t('pageTitle.loading.auth')} />}>
123+
<Auth />
124+
</Suspense>
125+
}, {
126+
path: "/auth/casdoor",
127+
element: <Suspense fallback={<FullscreenLoading title={t('pageTitle.loading.auth')} />}>
128+
<Auth />
129+
</Suspense>
130+
},
131+
{
132+
element: <Suspense fallback={<FullscreenLoading title={t('pageTitle.loading.defaultLayout')} />}>
133+
<DefaultLayout />
134+
</Suspense>,
135+
children: [
136+
{
137+
path: '', element: <Suspense fallback={<FullscreenLoading title={t('pageTitle.loading.welcome')} />}>
138+
<WelcomePage />
139+
</Suspense>
140+
},
141+
{
142+
path: "/doc",
143+
element: <Suspense fallback={<FullscreenLoading title={t('pageTitle.loading.doc')} />}>
144+
<DocPage />
145+
</Suspense>
146+
}, {
147+
path: "/doc/*",
148+
element: <Suspense fallback={<FullscreenLoading title={t('pageTitle.loading.doc')} />}>
149+
<DocPage />
150+
</Suspense>
151+
}, {
152+
path: "/model",
153+
element: <Suspense fallback={<FullscreenLoading title={t('pageTitle.loading.model')} />}>
154+
<ModelPage />
155+
</Suspense>
156+
},
157+
]
158+
},
159+
]);
160+
159161
return (
160162
<ThemeProvider themeMode={themeMode}
161163
onThemeModeChange={(mode) => {

0 commit comments

Comments
 (0)