Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
C
center-book
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
EzijingWeb
center-book
Commits
6d1921de
提交
6d1921de
authored
7月 21, 2026
作者:
王鹏飞
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
chore(admin): 修改页面布局和样式
上级
f0d76e9d
隐藏空白字符变更
内嵌
并排
正在显示
5 个修改的文件
包含
231 行增加
和
224 行删除
+231
-224
AppList.less
apps/admin/src/components/AppList/AppList.less
+19
-3
AppList.tsx
apps/admin/src/components/AppList/AppList.tsx
+22
-19
breadcrumb.jsx
apps/admin/src/layout/components/breadcrumb.jsx
+5
-26
index.jsx
apps/admin/src/layout/index.jsx
+144
-142
index.less
apps/admin/src/layout/index.less
+41
-34
没有找到文件。
apps/admin/src/components/AppList/AppList.less
浏览文件 @
6d1921de
...
@@ -5,34 +5,50 @@
...
@@ -5,34 +5,50 @@
&__filters {
&__filters {
display: flex;
display: flex;
flex-wrap: wrap;
flex-wrap:
no
wrap;
align-items: flex-end;
align-items: flex-end;
justify-content: space-between;
justify-content: space-between;
gap: 16px;
gap: 16px;
}
}
&__filter-main {
display: flex;
flex: 0 1 auto;
align-items: flex-end;
gap: 16px;
min-width: 0;
}
&__filter-items {
&__filter-items {
display: flex;
display: flex;
flex:
1
;
flex:
0 1 auto
;
flex-wrap: wrap;
flex-wrap: wrap;
align-items: flex-end;
align-items: flex-end;
gap: 16px;
gap: 16px;
}
}
&__filter-actions {
flex: 0 0 auto;
}
&__filter-item {
&__filter-item {
display: flex;
display: flex;
flex-direction: column;
flex-direction: row;
align-items: center;
gap: 8px;
gap: 8px;
}
}
&__filter-label {
&__filter-label {
flex: 0 0 auto;
color: rgb(0 0 0 / 88%);
color: rgb(0 0 0 / 88%);
white-space: nowrap;
}
}
&__toolbar {
&__toolbar {
display: flex;
display: flex;
flex-wrap: wrap;
flex-wrap: wrap;
gap: 8px;
gap: 8px;
flex: 0 0 auto;
}
}
&__blocking-error {
&__blocking-error {
...
...
apps/admin/src/components/AppList/AppList.tsx
浏览文件 @
6d1921de
...
@@ -53,29 +53,32 @@ export function AppList<Row extends object, Filters extends object = Record<stri
...
@@ -53,29 +53,32 @@ export function AppList<Row extends object, Filters extends object = Record<stri
<
div
className=
"app-list"
>
<
div
className=
"app-list"
>
{
filters
?
(
{
filters
?
(
<
section
className=
"app-list__filters"
aria
-
label=
"筛选条件"
>
<
section
className=
"app-list__filters"
aria
-
label=
"筛选条件"
>
<
div
className=
"app-list__filter-items"
>
<
div
className=
"app-list__filter-main"
>
{
filters
.
items
.
map
((
item
)
=>
(
<
div
className=
"app-list__filter-items"
>
<
div
className=
"app-list__filter-item"
key=
{
String
(
item
.
name
)
}
>
{
filters
.
items
.
map
((
item
)
=>
(
<
span
className=
"app-list__filter-label"
>
{
item
.
label
}
</
span
>
<
div
className=
"app-list__filter-item"
key=
{
String
(
item
.
name
)
}
>
{
item
.
render
({
<
span
className=
"app-list__filter-label"
>
{
item
.
label
}
</
span
>
value
:
filters
.
value
[
item
.
name
],
{
item
.
render
({
onChange
:
(
value
)
=>
updateFilter
(
item
,
value
),
value
:
filters
.
value
[
item
.
name
],
})
}
onChange
:
(
value
)
=>
updateFilter
(
item
,
value
),
</
div
>
})
}
))
}
</
div
>
))
}
</
div
>
<
Space
wrap
className=
"app-list__filter-actions"
>
<
Button
type=
"primary"
icon=
{
<
SearchOutlined
/>
}
onClick=
{
filters
.
onSearch
}
>
搜索
</
Button
>
<
Button
icon=
{
<
ReloadOutlined
/>
}
onClick=
{
filters
.
onReset
}
>
重置
</
Button
>
</
Space
>
</
div
>
</
div
>
<
Space
wrap
>
{
toolbar
?
<
div
className=
"app-list__toolbar"
>
{
toolbar
}
</
div
>
:
null
}
<
Button
type=
"primary"
icon=
{
<
SearchOutlined
/>
}
onClick=
{
filters
.
onSearch
}
>
搜索
</
Button
>
<
Button
icon=
{
<
ReloadOutlined
/>
}
onClick=
{
filters
.
onReset
}
>
重置
</
Button
>
</
Space
>
</
section
>
</
section
>
)
:
null
}
)
:
null
}
{
toolbar
?
<
div
className=
"app-list__toolbar"
>
{
toolbar
}
</
div
>
:
null
}
{
!
filters
&&
toolbar
?
<
div
className=
"app-list__toolbar"
>
{
toolbar
}
</
div
>
:
null
}
{
hasRefreshError
?
(
{
hasRefreshError
?
(
<
Alert
<
Alert
...
...
apps/admin/src/layout/components/breadcrumb.jsx
浏览文件 @
6d1921de
import
{
Button
}
from
"antd"
;
import
{
Link
}
from
"react-router"
;
import
{
LeftOutlined
}
from
"@ant-design/icons"
;
import
{
useLocation
,
useNavigate
}
from
"react-router"
;
export
default
function
Breadcrumb
()
{
export
default
function
Breadcrumb
({
parent
})
{
const
{
pathname
}
=
useLocation
();
if
(
!
parent
)
return
null
;
const
navigate
=
useNavigate
();
// const hasBack = currentMenusList.find(item => {
// const regExp = new RegExp(`^${item.path}`)
// return regExp.test(pathname) && item.path !== pathname
// })
const
hasBack
=
[
"/books/management/add-edit"
,
"/setting/help/addedit"
,
"/books/management/chapter"
,
"/userinfo"
,
"/books/audit/detail"
,
"/books/sale/discussP"
,
"/books/sale/discuss-detail"
,
"/member/list/detail"
,
"/books/sale/detail"
,
].
includes
(
pathname
);
if
(
!
hasBack
)
return
null
;
return
(
return
(
<
div
className=
"layout-breadcrumb"
>
<
div
className=
"layout-breadcrumb"
>
<
Button
type=
"text"
icon=
{
<
LeftOutlined
/>
}
onClick=
{
()
=>
navigate
(
-
1
)
}
>
<
Link
to=
{
parent
.
parent
}
>
{
parent
.
parentTitle
}
</
Link
>
返回
<
span
aria
-
hidden=
"true"
>
/
</
span
>
</
Button
>
</
div
>
</
div
>
);
);
}
}
apps/admin/src/layout/index.jsx
浏览文件 @
6d1921de
import
{
useState
,
useEffect
,
Suspense
}
from
"react"
;
import
{
useState
,
useEffect
,
Suspense
}
from
'react'
import
{
Button
,
Layout
,
Flex
}
from
"antd"
;
import
{
Button
,
Layout
,
Flex
}
from
'antd'
import
{
Outlet
,
Link
,
useLocation
}
from
"react-router"
;
import
{
Outlet
,
Link
,
useLocation
}
from
'react-router'
import
{
useDispatch
}
from
"react-redux"
;
import
{
useDispatch
}
from
'react-redux'
import
{
import
{
RiAdvertisementLine
,
RiAdvertisementLine
,
RiAppStoreLine
,
RiAppStoreLine
,
...
@@ -38,194 +38,196 @@ import {
...
@@ -38,194 +38,196 @@ import {
RiAdminLine
,
RiAdminLine
,
RiLayoutGridLine
,
RiLayoutGridLine
,
RiPaletteLine
,
RiPaletteLine
,
}
from
"@remixicon/react"
;
}
from
'@remixicon/react'
import
{
setOperationPermissionsList
}
from
"@/store/modules/user"
;
import
{
setOperationPermissionsList
}
from
'@/store/modules/user'
import
Menu
from
"./components/menu"
;
import
Menu
from
'./components/menu'
import
Message
from
"./components/message"
;
import
Message
from
'./components/message'
import
User
from
"./components/user"
;
import
User
from
'./components/user'
import
Logout
from
"./components/logout"
;
import
Logout
from
'./components/logout'
import
Breadcrumb
from
"./components/breadcrumb"
;
import
Breadcrumb
from
'./components/breadcrumb'
import
"./index.less"
;
import
'./index.less'
import
logo
from
"@/assets/images/logo.png"
;
import
logo
from
'@/assets/images/logo.png'
import
{
getMenuList
,
checkSSOLogin
}
from
"./request"
;
import
{
getMenuList
,
checkSSOLogin
}
from
'./request'
const
{
Header
,
Content
,
Sider
}
=
Layout
;
const
{
Header
,
Content
,
Sider
}
=
Layout
function
getMenuIcon
(
item
,
hasChildren
)
{
function
getMenuIcon
(
item
,
hasChildren
)
{
const
name
=
item
.
name
||
""
;
const
name
=
item
.
name
||
''
const
path
=
item
.
front_url
||
""
;
const
path
=
item
.
front_url
||
''
if
(
/
\/
books
\/
management/
.
test
(
path
))
return
RiQuillPenLine
;
if
(
/
\/
books
\/
management/
.
test
(
path
))
return
RiQuillPenLine
if
(
/
\/
books
\/
audit/
.
test
(
path
))
return
RiShieldCheckLine
;
if
(
/
\/
books
\/
audit/
.
test
(
path
))
return
RiShieldCheckLine
if
(
/
\/
books
\/
classify/
.
test
(
path
))
return
RiFolder2Line
;
if
(
/
\/
books
\/
classify/
.
test
(
path
))
return
RiFolder2Line
if
(
/
\/
books
\/
label/
.
test
(
path
))
return
RiPriceTag3Line
;
if
(
/
\/
books
\/
label/
.
test
(
path
))
return
RiPriceTag3Line
if
(
/
\/
books
\/
sale/
.
test
(
path
))
return
RiStore2Line
;
if
(
/
\/
books
\/
sale/
.
test
(
path
))
return
RiStore2Line
if
(
/
\/
books
\/
question-bank/
.
test
(
path
))
return
RiQuestionnaireLine
;
if
(
/
\/
books
\/
question-bank/
.
test
(
path
))
return
RiQuestionnaireLine
if
(
/
\/
books
\/
discussion/
.
test
(
path
))
return
RiDiscussLine
;
if
(
/
\/
books
\/
discussion/
.
test
(
path
))
return
RiDiscussLine
if
(
/
\/
books
\/
order-management/
.
test
(
path
))
return
RiShoppingBag3Line
;
if
(
/
\/
books
\/
order-management/
.
test
(
path
))
return
RiShoppingBag3Line
if
(
/
\/
books
\/
design/
.
test
(
path
))
return
RiPaletteLine
;
if
(
/
\/
books
\/
design/
.
test
(
path
))
return
RiPaletteLine
if
(
/
\/
member
\/
userlevel/
.
test
(
path
))
return
RiMedal2Line
;
if
(
/
\/
member
\/
userlevel/
.
test
(
path
))
return
RiMedal2Line
if
(
/
\/
member
\/
list/
.
test
(
path
))
return
RiUser3Line
;
if
(
/
\/
member
\/
list/
.
test
(
path
))
return
RiUser3Line
if
(
/
\/
advertisement
\/
adsense/
.
test
(
path
))
return
RiLayoutGridLine
;
if
(
/
\/
advertisement
\/
adsense/
.
test
(
path
))
return
RiLayoutGridLine
if
(
/
\/
advertisement
\/
advert/
.
test
(
path
))
return
RiAdvertisementLine
;
if
(
/
\/
advertisement
\/
advert/
.
test
(
path
))
return
RiAdvertisementLine
if
(
/
\/
setting
\/
help/
.
test
(
path
))
return
RiCustomerService2Line
;
if
(
/
\/
setting
\/
help/
.
test
(
path
))
return
RiCustomerService2Line
if
(
/
\/
setting
\/
applied/
.
test
(
path
))
return
RiAppStoreLine
;
if
(
/
\/
setting
\/
applied/
.
test
(
path
))
return
RiAppStoreLine
if
(
/
\/
setting
\/
personalized-setting/
.
test
(
path
))
return
RiPaletteLine
;
if
(
/
\/
setting
\/
personalized-setting/
.
test
(
path
))
return
RiPaletteLine
if
(
/
\/
setting
\/
point-management/
.
test
(
path
))
return
RiCoinsLine
;
if
(
/
\/
setting
\/
point-management/
.
test
(
path
))
return
RiCoinsLine
if
(
/
\/
setting
\/
app-version/
.
test
(
path
))
return
RiSmartphoneLine
;
if
(
/
\/
setting
\/
app-version/
.
test
(
path
))
return
RiSmartphoneLine
if
(
/
\/
setting
\/
coupon/
.
test
(
path
))
return
RiCoupon3Line
;
if
(
/
\/
setting
\/
coupon/
.
test
(
path
))
return
RiCoupon3Line
if
(
/
\/
setting
\/
sensitive/
.
test
(
path
))
return
RiSearchEyeLine
;
if
(
/
\/
setting
\/
sensitive/
.
test
(
path
))
return
RiSearchEyeLine
if
(
/
\/
setting
\/
feedback/
.
test
(
path
))
return
RiFeedbackLine
;
if
(
/
\/
setting
\/
feedback/
.
test
(
path
))
return
RiFeedbackLine
if
(
/
\/
jurisdiction
\/
admin/
.
test
(
path
))
return
RiAdminLine
;
if
(
/
\/
jurisdiction
\/
admin/
.
test
(
path
))
return
RiAdminLine
if
(
/
\/
jurisdiction
\/
role/
.
test
(
path
))
return
RiShieldKeyholeLine
;
if
(
/
\/
jurisdiction
\/
role/
.
test
(
path
))
return
RiShieldKeyholeLine
if
(
/
\/
teacher
\/
list/
.
test
(
path
))
return
RiUserStarLine
;
if
(
/
\/
teacher
\/
list/
.
test
(
path
))
return
RiUserStarLine
if
(
/首页|工作台|概览/
.
test
(
name
))
return
RiHome5Line
;
if
(
/首页|工作台|概览/
.
test
(
name
))
return
RiHome5Line
if
(
/图书|教材|章节|书架/
.
test
(
name
))
return
hasChildren
?
RiBook2Line
:
RiBookOpenLine
;
if
(
/图书|教材|章节|书架/
.
test
(
name
))
return
hasChildren
?
RiBook2Line
:
RiBookOpenLine
if
(
/题库|题目|试题|练习/
.
test
(
name
))
return
RiQuestionnaireLine
;
if
(
/题库|题目|试题|练习/
.
test
(
name
))
return
RiQuestionnaireLine
if
(
/分类|标签/
.
test
(
name
))
return
RiPriceTag3Line
;
if
(
/分类|标签/
.
test
(
name
))
return
RiPriceTag3Line
if
(
/会员|用户/
.
test
(
name
))
return
RiUser3Line
;
if
(
/会员|用户/
.
test
(
name
))
return
RiUser3Line
if
(
/教师|老师/
.
test
(
name
))
return
RiUserStarLine
;
if
(
/教师|老师/
.
test
(
name
))
return
RiUserStarLine
if
(
/班级|组织|团队/
.
test
(
name
))
return
RiGroupLine
;
if
(
/班级|组织|团队/
.
test
(
name
))
return
RiGroupLine
if
(
/订单|销售|支付|结算/
.
test
(
name
))
return
RiShoppingBag3Line
;
if
(
/订单|销售|支付|结算/
.
test
(
name
))
return
RiShoppingBag3Line
if
(
/优惠券|卡券/
.
test
(
name
))
return
RiCoupon3Line
;
if
(
/优惠券|卡券/
.
test
(
name
))
return
RiCoupon3Line
if
(
/积分|账单|余额/
.
test
(
name
))
return
RiCoinsLine
;
if
(
/积分|账单|余额/
.
test
(
name
))
return
RiCoinsLine
if
(
/广告|轮播/
.
test
(
name
))
return
RiAdvertisementLine
;
if
(
/广告|轮播/
.
test
(
name
))
return
RiAdvertisementLine
if
(
/讨论|评论/
.
test
(
name
))
return
RiDiscussLine
;
if
(
/讨论|评论/
.
test
(
name
))
return
RiDiscussLine
if
(
/审核|认证/
.
test
(
name
))
return
RiShieldCheckLine
;
if
(
/审核|认证/
.
test
(
name
))
return
RiShieldCheckLine
if
(
/权限|角色/
.
test
(
name
))
return
RiShieldKeyholeLine
;
if
(
/权限|角色/
.
test
(
name
))
return
RiShieldKeyholeLine
if
(
/帮助|客服/
.
test
(
name
))
return
RiCustomerService2Line
;
if
(
/帮助|客服/
.
test
(
name
))
return
RiCustomerService2Line
if
(
/反馈/
.
test
(
name
))
return
RiFeedbackLine
;
if
(
/反馈/
.
test
(
name
))
return
RiFeedbackLine
if
(
/消息|通知/
.
test
(
name
))
return
RiNotification3Line
;
if
(
/消息|通知/
.
test
(
name
))
return
RiNotification3Line
if
(
/应用/
.
test
(
name
))
return
RiAppStoreLine
;
if
(
/应用/
.
test
(
name
))
return
RiAppStoreLine
if
(
/设置|配置/
.
test
(
name
))
return
RiSettings3Line
;
if
(
/设置|配置/
.
test
(
name
))
return
RiSettings3Line
if
(
/内容|编辑/
.
test
(
name
))
return
RiFileSettingsLine
;
if
(
/内容|编辑/
.
test
(
name
))
return
RiFileSettingsLine
return
hasChildren
?
RiApps2Line
:
RiFileList3Line
;
return
hasChildren
?
RiApps2Line
:
RiFileList3Line
}
}
function
generateMenus
(
items
=
[],
maxLevel
=
2
,
level
=
1
)
{
function
generateMenus
(
items
=
[],
maxLevel
=
2
,
level
=
1
)
{
return
items
.
map
((
item
)
=>
{
return
items
.
map
((
item
)
=>
{
const
children
=
const
children
=
level
<
maxLevel
&&
item
.
childs
?
generateMenus
(
item
.
childs
,
maxLevel
,
level
+
1
)
:
null
level
<
maxLevel
&&
item
.
childs
?
generateMenus
(
item
.
childs
,
maxLevel
,
level
+
1
)
:
null
;
const
Icon
=
getMenuIcon
(
item
,
Boolean
(
children
?.
length
))
const
Icon
=
getMenuIcon
(
item
,
Boolean
(
children
?.
length
));
return
{
return
{
key
:
item
.
id
+
""
,
key
:
item
.
id
+
''
,
path
:
item
.
front_url
,
path
:
item
.
front_url
,
title
:
item
.
name
,
title
:
item
.
name
,
icon
:
<
Icon
className=
"layout-menu__icon"
aria
-
hidden=
"true"
/>,
icon
:
<
Icon
className=
"layout-menu__icon"
aria
-
hidden=
"true"
/>,
label
:
<
Link
to=
{
item
.
front_url
}
>
{
item
.
name
}
</
Link
>,
label
:
<
Link
to=
{
item
.
front_url
}
>
{
item
.
name
}
</
Link
>,
children
,
children
,
}
;
}
})
;
})
}
}
function
getCurrentMenuTitle
(
items
,
pathname
)
{
function
getCurrentMenuTitle
(
items
,
pathname
)
{
let
currentMenu
;
let
currentMenu
const
visit
=
(
menuItems
)
=>
{
const
visit
=
(
menuItems
)
=>
{
menuItems
.
forEach
((
item
)
=>
{
menuItems
.
forEach
((
item
)
=>
{
const
isMatch
=
const
isMatch
=
item
.
path
&&
item
.
path
&&
(
pathname
===
item
.
path
||
(
item
.
path
!==
'/'
&&
pathname
.
startsWith
(
`
${
item
.
path
}
/`
)))
(
pathname
===
item
.
path
||
(
item
.
path
!==
"/"
&&
pathname
.
startsWith
(
`
${
item
.
path
}
/`
)));
if
(
isMatch
&&
(
!
currentMenu
||
item
.
path
.
length
>
currentMenu
.
path
.
length
))
currentMenu
=
item
if
(
isMatch
&&
(
!
currentMenu
||
item
.
path
.
length
>
currentMenu
.
path
.
length
))
if
(
item
.
children
?.
length
)
visit
(
item
.
children
)
currentMenu
=
item
;
})
if
(
item
.
children
?.
length
)
visit
(
item
.
children
);
}
});
};
visit
(
items
)
return
currentMenu
?.
title
||
''
}
visit
(
items
);
const
pageHeaderOverrides
=
{
return
currentMenu
?.
title
||
"工作台"
;
'/books/management/add-edit'
:
{
parent
:
'/books/management'
,
parentTitle
:
'写书管理'
,
title
:
'编辑图书'
},
'/books/management/chapter'
:
{
parent
:
'/books/management'
,
parentTitle
:
'写书管理'
,
title
:
'章节编辑'
},
'/books/audit/detail'
:
{
parent
:
'/books/audit'
,
parentTitle
:
'书籍审核'
,
title
:
'审核详情'
},
'/books/sale/detail'
:
{
parent
:
'/books/sale'
,
parentTitle
:
'在售书籍'
,
title
:
'书籍编辑'
},
'/books/sale/discussP'
:
{
parent
:
'/books/sale'
,
parentTitle
:
'在售书籍'
,
title
:
'书籍讨论'
},
'/books/sale/discuss-detail'
:
{
parent
:
'/books/sale'
,
parentTitle
:
'在售书籍'
,
title
:
'讨论详情'
},
'/member/list/detail'
:
{
parent
:
'/member/list'
,
parentTitle
:
'会员管理'
,
title
:
'会员详情'
},
'/setting/help/addedit'
:
{
parent
:
'/setting/help/list'
,
parentTitle
:
'帮助中心'
,
title
:
'编辑帮助'
},
'/userinfo'
:
{
parent
:
'/'
,
parentTitle
:
'首页'
,
title
:
'个人中心'
},
}
}
export
default
function
AppLayout
()
{
export
default
function
AppLayout
()
{
const
dispatch
=
useDispatch
();
const
dispatch
=
useDispatch
()
const
{
pathname
}
=
useLocation
();
const
{
pathname
}
=
useLocation
()
const
[
menuList
,
setMenuList
]
=
useState
([]);
const
[
menuList
,
setMenuList
]
=
useState
([])
const
[
collapsed
,
setCollapsed
]
=
useState
(
false
);
const
[
collapsed
,
setCollapsed
]
=
useState
(
false
)
const
pageTitle
=
getCurrentMenuTitle
(
menuList
,
pathname
);
const
headerOverride
=
pageHeaderOverrides
[
pathname
]
const
pageTitle
=
headerOverride
?.
title
||
getCurrentMenuTitle
(
menuList
,
pathname
)
const
getSSOToken
=
async
()
=>
{
const
getSSOToken
=
async
()
=>
{
const
data
=
await
checkSSOLogin
()
;
const
data
=
await
checkSSOLogin
()
if
(
data
&&
data
.
token
)
{
if
(
data
&&
data
.
token
)
{
localStorage
.
setItem
(
"kiwi.token"
,
data
.
token
);
localStorage
.
setItem
(
'kiwi.token'
,
data
.
token
)
}
}
}
;
}
// 获取菜单
// 获取菜单
const
getMenu
=
async
()
=>
{
const
getMenu
=
async
()
=>
{
// 获取菜单内容
// 获取菜单内容
const
{
data
,
operation_permissions_list
}
=
await
getMenuList
()
;
const
{
data
,
operation_permissions_list
}
=
await
getMenuList
()
if
(
data
&&
data
.
length
)
{
if
(
data
&&
data
.
length
)
{
setMenuList
(
generateMenus
(
data
))
;
setMenuList
(
generateMenus
(
data
))
}
}
// 获取操作权限内容
// 获取操作权限内容
if
(
operation_permissions_list
&&
operation_permissions_list
.
length
)
{
if
(
operation_permissions_list
&&
operation_permissions_list
.
length
)
{
dispatch
(
setOperationPermissionsList
(
operation_permissions_list
))
;
dispatch
(
setOperationPermissionsList
(
operation_permissions_list
))
}
}
}
;
}
useEffect
(()
=>
{
useEffect
(()
=>
{
(
async
()
=>
{
;
(
async
()
=>
{
await
getSSOToken
()
;
await
getSSOToken
()
await
getMenu
()
;
await
getMenu
()
})()
;
})()
},
[])
;
},
[])
return
(
return
(
<
Layout
className=
"layout-container"
>
<
Layout
className=
"layout-container"
>
<
Header
className=
"layout-header"
>
<
Sider
className=
"layout-sider"
width=
{
240
}
collapsedWidth=
{
64
}
collapsed=
{
collapsed
}
theme=
"light"
trigger=
{
null
}
>
<
div
className=
"layout-brand"
>
<
div
className=
"layout-brand"
>
<
Link
className=
"layout-brand__logo"
to=
"/"
aria
-
label=
"返回工作台首页"
>
<
Link
className=
"layout-brand__logo"
to=
"/"
aria
-
label=
"返回工作台首页"
>
<
img
src=
{
logo
}
alt=
"清控紫荆数智学堂"
/>
<
img
src=
{
logo
}
alt=
"清控紫荆数智学堂"
/>
</
Link
>
</
Link
>
</
div
>
</
div
>
{
menuList
.
length
?
(
<
div
className=
"layout-sider__body"
>
<
Flex
align=
"center"
gap=
"small"
className=
"layout-header__actions"
>
<
Menu
menuList=
{
menuList
}
collapsed=
{
collapsed
}
></
Menu
>
<
Message
></
Message
>
</
div
>
<
User
></
User
>
<
Button
<
Logout
></
Logout
>
className=
"layout-sider-toggle"
</
Flex
>
type=
"text"
)
:
null
}
onClick=
{
()
=>
setCollapsed
((
value
)
=>
!
value
)
}
</
Header
>
aria
-
label=
{
collapsed
?
'展开侧边菜单'
:
'收起侧边菜单'
}
>
<
Layout
className=
{
`layout-body${collapsed ? " layout-body--collapsed" : ""}`
}
>
{
collapsed
?
<
RiMenuUnfoldLine
aria
-
hidden=
"true"
/>
:
<
RiMenuFoldLine
aria
-
hidden=
"true"
/>
}
<
Sider
</
Button
>
className=
"layout-sider"
</
Sider
>
width=
{
200
}
<
Layout
className=
"layout-main"
>
collapsedWidth=
{
56
}
<
Header
className=
"layout-header"
>
collapsed=
{
collapsed
}
<
div
className=
"layout-page-header"
>
theme=
"light"
<
Breadcrumb
parent=
{
headerOverride
}
></
Breadcrumb
>
trigger=
{
null
}
<
div
className=
"layout-page-title"
>
{
pageTitle
}
</
div
>
>
<
div
className=
"layout-sider__body"
>
<
Menu
menuList=
{
menuList
}
collapsed=
{
collapsed
}
></
Menu
>
</
div
>
</
div
>
<
Button
{
menuList
.
length
?
(
className=
"layout-sider-toggle"
<
Flex
align=
"center"
gap=
"small"
className=
"layout-header__actions"
>
type=
"text"
<
Message
></
Message
>
onClick=
{
()
=>
setCollapsed
((
value
)
=>
!
value
)
}
<
User
></
User
>
aria
-
label=
{
collapsed
?
"展开侧边菜单"
:
"收起侧边菜单"
}
<
Logout
></
Logout
>
>
</
Flex
>
{
collapsed
?
(
)
:
null
}
<
RiMenuUnfoldLine
aria
-
hidden=
"true"
/>
</
Header
>
)
:
(
<
Content
className=
"layout-content"
>
<
RiMenuFoldLine
aria
-
hidden=
"true"
/>
<
main
className=
"layout-page-content"
>
)
}
<
Suspense
>
</
Button
>
<
Outlet
/>
</
Sider
>
</
Suspense
>
<
Layout
className=
"layout-main"
>
</
main
>
<
Content
className=
"layout-content"
>
</
Content
>
<
div
className=
"layout-page-header"
>
<
div
className=
"layout-page-title"
>
{
pageTitle
}
</
div
>
<
Breadcrumb
></
Breadcrumb
>
</
div
>
<
main
className=
"layout-page-content"
>
<
Suspense
>
<
Outlet
/>
</
Suspense
>
</
main
>
</
Content
>
</
Layout
>
</
Layout
>
</
Layout
>
</
Layout
>
</
Layout
>
)
;
)
}
}
apps/admin/src/layout/index.less
浏览文件 @
6d1921de
.layout-container {
.layout-container {
min-height: 100vh;
min-height: 100vh;
background: #f
6f7f9
;
background: #f
ff
;
}
}
.layout-sider {
.layout-sider {
position: fixed !important;
position: sticky !important;
top: 84px;
top: 0;
bottom: 0;
height: 100vh;
left: 0;
height: auto;
overflow: hidden;
overflow: hidden;
background: #f
6f7f9
!important;
background: #f
5f6f7
!important;
border-inline-end: 0 !important;
border-inline-end: 0 !important;
box-shadow: none;
box-shadow: none;
z-index: 100;
z-index: 100;
...
@@ -28,20 +26,11 @@
...
@@ -28,20 +26,11 @@
overflow-y: auto;
overflow-y: auto;
}
}
.layout-body {
min-height: calc(100vh - 84px);
padding-left: 200px;
}
.layout-body--collapsed {
padding-left: 56px;
}
.layout-brand {
.layout-brand {
display: flex;
display: flex;
align-items: center;
align-items: center;
height: 84px;
height: 84px;
padding: 0;
padding: 0
20px
;
.layout-brand__logo {
.layout-brand__logo {
display: inline-flex;
display: inline-flex;
...
@@ -68,7 +57,7 @@
...
@@ -68,7 +57,7 @@
margin: 0 10px 10px;
margin: 0 10px 10px;
padding: 0;
padding: 0;
color: #6f7886;
color: #6f7886;
background: #f
6f7f9
;
background: #f
5f6f7
;
border: 0;
border: 0;
border-radius: 8px;
border-radius: 8px;
cursor: pointer;
cursor: pointer;
...
@@ -253,7 +242,7 @@
...
@@ -253,7 +242,7 @@
.layout-main {
.layout-main {
min-width: 0;
min-width: 0;
background: #f
6f7f9
;
background: #f
ff
;
}
}
.layout-header {
.layout-header {
...
@@ -264,16 +253,16 @@
...
@@ -264,16 +253,16 @@
align-items: center;
align-items: center;
justify-content: space-between;
justify-content: space-between;
height: 84px;
height: 84px;
padding: 0 32px
0 20px
;
padding: 0 32px;
line-height: normal;
line-height: normal;
background: #f
6f7f9
;
background: #f
ff
;
border-bottom:
0
;
border-bottom:
1px solid #1f23290a
;
}
}
.layout-page-title {
.layout-page-title {
display: flex;
display: flex;
align-items: center;
align-items: center;
height:
60
px;
height:
56
px;
color: #252b36;
color: #252b36;
font-size: 22px;
font-size: 22px;
font-weight: 600;
font-weight: 600;
...
@@ -281,7 +270,10 @@
...
@@ -281,7 +270,10 @@
}
}
.layout-page-header {
.layout-page-header {
min-height: 60px;
display: flex;
align-items: center;
gap: 8px;
min-width: 0;
}
}
.layout-header__actions {
.layout-header__actions {
...
@@ -307,16 +299,31 @@
...
@@ -307,16 +299,31 @@
.layout-breadcrumb {
.layout-breadcrumb {
display: flex;
display: flex;
align-items: center;
align-items: center;
height:
40
px;
height:
56
px;
margin
-top: -8px
;
margin
: 0
;
padding: 0;
padding: 0;
a {
color: #646a73;
font-size: 14px;
text-decoration: none;
&:hover {
color: #1f2329;
}
}
span {
margin-left: 8px;
color: #b0b5bd;
}
}
}
.layout-content {
.layout-content {
min-height: calc(100vh - 84px);
min-height: calc(100vh - 84px);
margin: 0
32px 40px 20px
;
margin: 0;
padding:
0
;
padding:
24px 32px 40px
;
background:
transparent
;
background:
#fff
;
border-radius: 0;
border-radius: 0;
box-shadow: none;
box-shadow: none;
}
}
...
@@ -355,9 +362,9 @@
...
@@ -355,9 +362,9 @@
margin-top: 16px;
margin-top: 16px;
overflow: hidden;
overflow: hidden;
background: #fff;
background: #fff;
border:
1px solid #e7eaee
;
border:
0
;
border-radius:
12px
;
border-radius:
0
;
box-shadow:
0 1px 2px rgb(31 41 55 / 2%)
;
box-shadow:
none
;
}
}
.ant-table,
.ant-table,
...
@@ -377,13 +384,13 @@
...
@@ -377,13 +384,13 @@
font-size: 13px;
font-size: 13px;
font-weight: 500;
font-weight: 500;
background: #f8f9fb !important;
background: #f8f9fb !important;
border-bottom: 1px solid #
edf0f3
;
border-bottom: 1px solid #
1f232926
;
}
}
.ant-table-tbody > tr > td {
.ant-table-tbody > tr > td {
height: 52px;
height: 52px;
color: #303641;
color: #303641;
border-bottom: 1px solid #
f0f2f4
;
border-bottom: 1px solid #
1f232926
;
}
}
.ant-table-tbody > tr:nth-child(2n) {
.ant-table-tbody > tr:nth-child(2n) {
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论