Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
phsl
/
new-api
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
5aa67994
authored
Mar 07, 2025
by
1808837298@qq.com
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
refactor: Reorganize sidebar navigation and add personal settings route
parent
783c60ee
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
252 additions
and
116 deletions
+252
-116
web/src/App.js
+11
-0
web/src/components/PersonalSetting.js
+1
-1
web/src/components/SiderBar.js
+232
-109
web/src/i18n/locales/en.json
+5
-2
web/src/pages/Setting/Model/SettingClaudeModel.js
+2
-0
web/src/pages/Setting/index.js
+1
-4
No files found.
web/src/App.js
View file @
5aa67994
...
...
@@ -30,6 +30,7 @@ import { useTranslation } from 'react-i18next';
import
{
StatusContext
}
from
'./context/Status'
;
import
{
setStatusData
}
from
'./helpers/data.js'
;
import
{
API
,
showError
}
from
'./helpers'
;
import
PersonalSetting
from
'./components/PersonalSetting.js'
;
const
Home
=
lazy
(()
=>
import
(
'./pages/Home'
));
const
Detail
=
lazy
(()
=>
import
(
'./pages/Detail'
));
...
...
@@ -178,6 +179,16 @@ function App() {
}
/
>
<
Route
path
=
'/personal'
element
=
{
<
PrivateRoute
>
<
Suspense
fallback
=
{
<
Loading
><
/Loading>}
>
<
PersonalSetting
/>
<
/Suspense
>
<
/PrivateRoute
>
}
/
>
<
Route
path
=
'/topup'
element
=
{
<
PrivateRoute
>
...
...
web/src/components/PersonalSetting.js
View file @
5aa67994
...
...
@@ -393,7 +393,7 @@ const PersonalSetting = () => {
<
/div
>
<
/div
>
<
/Modal
>
<
div
style
=
{{
marginTop
:
20
}}
>
<
div
>
<
Card
title
=
{
<
Card
.
Meta
...
...
web/src/components/SiderBar.js
View file @
5aa67994
...
...
@@ -28,7 +28,7 @@ import {
IconSetting
,
IconUser
}
from
'@douyinfe/semi-icons'
;
import
{
Avatar
,
Dropdown
,
Layout
,
Nav
,
Switch
}
from
'@douyinfe/semi-ui'
;
import
{
Avatar
,
Dropdown
,
Layout
,
Nav
,
Switch
,
Divider
}
from
'@douyinfe/semi-ui'
;
import
{
setStatusData
}
from
'../helpers/data.js'
;
import
{
stringToColor
}
from
'../helpers/render.js'
;
import
{
useSetTheme
,
useTheme
}
from
'../context/Theme/index.js'
;
...
...
@@ -65,36 +65,12 @@ const SiderBar = () => {
pricing
:
'/pricing'
,
task
:
'/task'
,
playground
:
'/playground'
,
personal
:
'/personal'
,
};
const
headerButton
s
=
useMemo
(
const
workspaceItem
s
=
useMemo
(
()
=>
[
{
text
:
'Playground'
,
itemKey
:
'playground'
,
to
:
'/playground'
,
icon
:
<
IconCommentStroked
/>
,
},
{
text
:
t
(
'渠道'
),
itemKey
:
'channel'
,
to
:
'/channel'
,
icon
:
<
IconLayers
/>
,
className
:
isAdmin
()
?
''
:
'tableHiddle'
,
},
{
text
:
t
(
'聊天'
),
itemKey
:
'chat'
,
items
:
chatItems
,
icon
:
<
IconComment
/>
,
},
{
text
:
t
(
'令牌'
),
itemKey
:
'token'
,
to
:
'/token'
,
icon
:
<
IconKey
/>
,
},
{
text
:
t
(
'数据看板'
),
itemKey
:
'detail'
,
to
:
'/detail'
,
...
...
@@ -105,33 +81,19 @@ const SiderBar = () => {
:
'tableHiddle'
,
},
{
text
:
t
(
'兑换码'
),
itemKey
:
'redemption'
,
to
:
'/redemption'
,
icon
:
<
IconGift
/>
,
className
:
isAdmin
()
?
''
:
'tableHiddle'
,
},
{
text
:
t
(
'钱包'
),
itemKey
:
'topup'
,
to
:
'/topup'
,
icon
:
<
IconCreditCard
/>
,
},
{
text
:
t
(
'用户管理'
),
itemKey
:
'user'
,
to
:
'/user'
,
icon
:
<
IconUser
/>
,
className
:
isAdmin
()
?
''
:
'tableHiddle'
,
text
:
t
(
'API令牌'
),
itemKey
:
'token'
,
to
:
'/token'
,
icon
:
<
IconKey
/>
,
},
{
text
:
t
(
'日志'
),
text
:
t
(
'
使用
日志'
),
itemKey
:
'log'
,
to
:
'/log'
,
icon
:
<
IconHistogram
/>
,
},
{
text
:
t
(
'绘图'
),
text
:
t
(
'绘图
日志
'
),
itemKey
:
'midjourney'
,
to
:
'/midjourney'
,
icon
:
<
IconImage
/>
,
...
...
@@ -141,31 +103,90 @@ const SiderBar = () => {
:
'tableHiddle'
,
},
{
text
:
t
(
'
异步任务
'
),
text
:
t
(
'
任务日志
'
),
itemKey
:
'task'
,
to
:
'/task'
,
icon
:
<
IconChecklistStroked
/>
,
className
:
localStorage
.
getItem
(
'enable_task'
)
===
'true'
?
''
:
'tableHiddle'
,
localStorage
.
getItem
(
'enable_task'
)
===
'true'
?
''
:
'tableHiddle'
,
}
],
[
localStorage
.
getItem
(
'enable_data_export'
),
localStorage
.
getItem
(
'enable_drawing'
),
localStorage
.
getItem
(
'enable_task'
),
t
,
],
);
const
financeItems
=
useMemo
(
()
=>
[
{
text
:
t
(
'钱包'
),
itemKey
:
'topup'
,
to
:
'/topup'
,
icon
:
<
IconCreditCard
/>
,
},
{
text
:
t
(
'设置'
),
text
:
t
(
'个人设置'
),
itemKey
:
'personal'
,
to
:
'/personal'
,
icon
:
<
IconUser
/>
,
},
],
[
t
],
);
const
adminItems
=
useMemo
(
()
=>
[
{
text
:
t
(
'渠道'
),
itemKey
:
'channel'
,
to
:
'/channel'
,
icon
:
<
IconLayers
/>
,
className
:
isAdmin
()
?
''
:
'tableHiddle'
,
},
{
text
:
t
(
'兑换码'
),
itemKey
:
'redemption'
,
to
:
'/redemption'
,
icon
:
<
IconGift
/>
,
className
:
isAdmin
()
?
''
:
'tableHiddle'
,
},
{
text
:
t
(
'用户管理'
),
itemKey
:
'user'
,
to
:
'/user'
,
icon
:
<
IconUser
/>
,
},
{
text
:
t
(
'系统设置'
),
itemKey
:
'setting'
,
to
:
'/setting'
,
icon
:
<
IconSetting
/>
,
},
],
[
localStorage
.
getItem
(
'enable_data_export'
),
localStorage
.
getItem
(
'enable_drawing'
),
localStorage
.
getItem
(
'enable_task'
),
localStorage
.
getItem
(
'chat_link'
),
chatItems
,
isAdmin
(),
t
,
[
isAdmin
(),
t
],
);
const
chatMenuItems
=
useMemo
(
()
=>
[
{
text
:
'Playground'
,
itemKey
:
'playground'
,
to
:
'/playground'
,
icon
:
<
IconCommentStroked
/>
,
},
{
text
:
t
(
'聊天'
),
itemKey
:
'chat'
,
items
:
chatItems
,
icon
:
<
IconComment
/>
,
},
],
[
chatItems
,
t
],
);
useEffect
(()
=>
{
...
...
@@ -174,42 +195,56 @@ const SiderBar = () => {
localKey
=
'home'
;
}
setSelectedKeys
([
localKey
]);
let
chatLink
=
localStorage
.
getItem
(
'chat_link'
);
if
(
!
chatLink
)
{
let
chats
=
localStorage
.
getItem
(
'chats'
);
if
(
chats
)
{
// console.log(chats);
try
{
chats
=
JSON
.
parse
(
chats
);
if
(
Array
.
isArray
(
chats
))
{
let
chatItems
=
[];
for
(
let
i
=
0
;
i
<
chats
.
length
;
i
++
)
{
let
chat
=
{};
for
(
let
key
in
chats
[
i
])
{
chat
.
text
=
key
;
chat
.
itemKey
=
'chat'
+
i
;
chat
.
to
=
'/chat/'
+
i
;
}
// setRouterMap({ ...routerMap, chat: '/chat/' + i })
chatItems
.
push
(
chat
);
}
setChatItems
(
chatItems
);
}
}
catch
(
e
)
{
console
.
error
(
e
);
showError
(
'聊天数据解析失败'
)
let
chats
=
localStorage
.
getItem
(
'chats'
);
if
(
chats
)
{
// console.log(chats);
try
{
chats
=
JSON
.
parse
(
chats
);
if
(
Array
.
isArray
(
chats
))
{
let
chatItems
=
[];
for
(
let
i
=
0
;
i
<
chats
.
length
;
i
++
)
{
let
chat
=
{};
for
(
let
key
in
chats
[
i
])
{
chat
.
text
=
key
;
chat
.
itemKey
=
'chat'
+
i
;
chat
.
to
=
'/chat/'
+
i
;
}
// setRouterMap({ ...routerMap, chat: '/chat/' + i })
chatItems
.
push
(
chat
);
}
setChatItems
(
chatItems
);
}
}
catch
(
e
)
{
console
.
error
(
e
);
showError
(
'聊天数据解析失败'
)
}
}
}
setIsCollapsed
(
localStorage
.
getItem
(
'default_collapse_sidebar'
)
===
'true'
);
},
[]);
// Custom divider style
const
dividerStyle
=
{
margin
:
'8px 0'
,
opacity
:
0.6
,
};
// Custom group label style
const
groupLabelStyle
=
{
padding
:
'8px 16px'
,
color
:
'var(--semi-color-text-2)'
,
fontSize
:
'12px'
,
fontWeight
:
'normal'
,
};
return
(
<>
<
Nav
style
=
{{
maxWidth
:
2
2
0
,
height
:
'100%'
}}
style
=
{{
maxWidth
:
2
0
0
,
height
:
'100%'
}}
defaultIsCollapsed
=
{
localStorage
.
getItem
(
'default_collapse_sidebar'
)
===
'true'
}
...
...
@@ -219,27 +254,27 @@ const SiderBar = () => {
}}
selectedKeys
=
{
selectedKeys
}
renderWrapper
=
{({
itemElement
,
isSubNav
,
isInSubNav
,
props
})
=>
{
let
chatLink
=
localStorage
.
getItem
(
'chat_link'
);
if
(
!
chatLink
)
{
let
chats
=
localStorage
.
getItem
(
'chats'
);
if
(
chats
)
{
chats
=
JSON
.
parse
(
chats
);
if
(
Array
.
isArray
(
chats
)
&&
chats
.
length
>
0
)
{
for
(
let
i
=
0
;
i
<
chats
.
length
;
i
++
)
{
routerMap
[
'chat'
+
i
]
=
'/chat/'
+
i
;
}
if
(
chats
.
length
>
1
)
{
// delete /chat
if
(
routerMap
[
'chat'
])
{
delete
routerMap
[
'chat'
];
}
}
else
{
// rename /chat to /chat/0
routerMap
[
'chat'
]
=
'/chat/0'
;
}
}
let
chatLink
=
localStorage
.
getItem
(
'chat_link'
);
if
(
!
chatLink
)
{
let
chats
=
localStorage
.
getItem
(
'chats'
);
if
(
chats
)
{
chats
=
JSON
.
parse
(
chats
);
if
(
Array
.
isArray
(
chats
)
&&
chats
.
length
>
0
)
{
for
(
let
i
=
0
;
i
<
chats
.
length
;
i
++
)
{
routerMap
[
'chat'
+
i
]
=
'/chat/'
+
i
;
}
if
(
chats
.
length
>
1
)
{
// delete /chat
if
(
routerMap
[
'chat'
])
{
delete
routerMap
[
'chat'
];
}
}
else
{
// rename /chat to /chat/0
routerMap
[
'chat'
]
=
'/chat/0'
;
}
}
}
}
return
(
<
Link
style
=
{{
textDecoration
:
'none'
}}
...
...
@@ -249,7 +284,6 @@ const SiderBar = () => {
<
/Link
>
);
}}
items
=
{
headerButtons
}
onSelect
=
{(
key
)
=>
{
if
(
key
.
itemKey
.
toString
().
startsWith
(
'chat'
))
{
styleDispatch
({
type
:
'SET_INNER_PADDING'
,
payload
:
false
});
...
...
@@ -258,12 +292,101 @@ const SiderBar = () => {
}
setSelectedKeys
([
key
.
itemKey
]);
}}
footer
=
{
>
{
/* Chat Section - Only show if there are chat items */
}
{
chatItems
.
length
>
0
&&
(
<>
{
chatMenuItems
.
map
((
item
)
=>
{
if
(
item
.
items
&&
item
.
items
.
length
>
0
)
{
return
(
<
Nav
.
Sub
key
=
{
item
.
itemKey
}
itemKey
=
{
item
.
itemKey
}
text
=
{
item
.
text
}
icon
=
{
item
.
icon
}
>
{
item
.
items
.
map
((
subItem
)
=>
(
<
Nav
.
Item
key
=
{
subItem
.
itemKey
}
itemKey
=
{
subItem
.
itemKey
}
text
=
{
subItem
.
text
}
/
>
))}
<
/Nav.Sub
>
);
}
else
{
return
(
<
Nav
.
Item
key
=
{
item
.
itemKey
}
itemKey
=
{
item
.
itemKey
}
text
=
{
item
.
text
}
icon
=
{
item
.
icon
}
/
>
);
}
})}
<
/
>
}
>
<
Nav
.
Footer
collapseButton
=
{
true
}
><
/Nav.Footer
>
)}
{
/* Divider */
}
<
Divider
style
=
{
dividerStyle
}
/
>
{
/* Workspace Section */
}
{
!
isCollapsed
&&
<
div
style
=
{
groupLabelStyle
}
>
{
t
(
'控制台'
)}
<
/div>
}
{
workspaceItems
.
map
((
item
)
=>
(
<
Nav
.
Item
key
=
{
item
.
itemKey
}
itemKey
=
{
item
.
itemKey
}
text
=
{
item
.
text
}
icon
=
{
item
.
icon
}
className
=
{
item
.
className
}
/
>
))}
{
/* Divider */
}
<
Divider
style
=
{
dividerStyle
}
/
>
{
/* Finance Management Section */
}
{
!
isCollapsed
&&
<
div
style
=
{
groupLabelStyle
}
>
{
t
(
'个人中心'
)}
<
/div>
}
{
financeItems
.
map
((
item
)
=>
(
<
Nav
.
Item
key
=
{
item
.
itemKey
}
itemKey
=
{
item
.
itemKey
}
text
=
{
item
.
text
}
icon
=
{
item
.
icon
}
className
=
{
item
.
className
}
/
>
))}
{
isAdmin
()
&&
(
<>
{
/* Divider */
}
<
Divider
style
=
{
dividerStyle
}
/
>
{
/* Admin Section */
}
{
adminItems
.
map
((
item
)
=>
(
<
Nav
.
Item
key
=
{
item
.
itemKey
}
itemKey
=
{
item
.
itemKey
}
text
=
{
item
.
text
}
icon
=
{
item
.
icon
}
className
=
{
item
.
className
}
/
>
))}
<
/
>
)}
<
Nav
.
Footer
collapseButton
=
{
true
}
collapseText
=
{(
collapsed
)
=>
{
if
(
collapsed
){
return
t
(
'展开侧边栏'
)
}
return
t
(
'收起侧边栏'
)
}
}
/
>
<
/Nav
>
<
/
>
);
...
...
web/src/i18n/locales/en.json
View file @
5aa67994
...
...
@@ -621,6 +621,7 @@
"窗口等待"
:
"window wait"
,
"失败"
:
"Failed"
,
"绘图"
:
"Drawing"
,
"绘图日志"
:
"Drawing log"
,
"放大"
:
"Upscalers"
,
"微妙放大"
:
"Upscale (Subtle)"
,
"创造放大"
:
"Upscale (Creative)"
,
...
...
@@ -1120,7 +1121,7 @@
"知识库 ID"
:
"Knowledge Base ID"
,
"请输入知识库 ID,例如:123456"
:
"Please enter knowledge base ID, e.g.: 123456"
,
"可选值"
:
"Optional value"
,
"
异步任务"
:
"Async task
"
,
"
任务日志"
:
"Task log
"
,
"你好"
:
"Hello"
,
"你好,请问有什么可以帮助您的吗?"
:
"Hello, how may I help you?"
,
"用户分组"
:
"Your default group"
,
...
...
@@ -1335,5 +1336,7 @@
"Claude思考适配 BudgetTokens = MaxTokens * BudgetTokens 百分比"
:
"Claude thinking adaptation BudgetTokens = MaxTokens * BudgetTokens percentage"
,
"思考适配 BudgetTokens 百分比"
:
"Thinking adaptation BudgetTokens percentage"
,
"0.1-1之间的小数"
:
"Decimal between 0.1 and 1"
,
"模型相关设置"
:
"Model related settings"
"模型相关设置"
:
"Model related settings"
,
"收起侧边栏"
:
"Collapse sidebar"
,
"展开侧边栏"
:
"Expand sidebar"
}
web/src/pages/Setting/Model/SettingClaudeModel.js
View file @
5aa67994
...
...
@@ -18,6 +18,8 @@ const CLAUDE_HEADER = {
const
CLAUDE_DEFAULT_MAX_TOKENS
=
{
'default'
:
8192
,
"claude-3-haiku-20240307"
:
4096
,
"claude-3-opus-20240229"
:
4096
,
'claude-3-7-sonnet-20250219-thinking'
:
8192
,
}
...
...
web/src/pages/Setting/index.js
View file @
5aa67994
...
...
@@ -18,9 +18,6 @@ const Setting = () => {
const
[
tabActiveKey
,
setTabActiveKey
]
=
useState
(
'1'
);
let
panes
=
[
{
tab
:
t
(
'个人设置'
),
content
:
<
PersonalSetting
/>
,
itemKey
:
'personal'
,
},
];
...
...
@@ -61,7 +58,7 @@ const Setting = () => {
if
(
tab
)
{
setTabActiveKey
(
tab
);
}
else
{
onChangeTab
(
'
personal
'
);
onChangeTab
(
'
operation
'
);
}
},
[
location
.
search
]);
return
(
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment