cfel-base-components 2.5.44 → 2.5.46
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/demo/src/index.jsx +1 -0
- package/package.json +1 -1
- package/src/components/base-component/PageContainer/index.module.less +1 -2
- package/src/components/layout/index-console.scss +601 -0
- package/src/components/layout/index.scss +487 -60
- package/src/components/layout/index.tsx +378 -42
- package/src/components/layout-copy/index.scss +169 -0
- package/src/components/layout-copy/index.tsx +218 -0
- package/src/components/layout-copy/user-card/index.scss +180 -0
- package/src/components/layout-copy/user-card/index.tsx +162 -0
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import React, { useEffect, useState } from 'react'
|
|
2
|
-
import { Layout, Menu, MenuProps, Popover } from 'antd'
|
|
2
|
+
import { Layout, List, Menu, MenuProps, Popover } from 'antd'
|
|
3
3
|
import UserCard from './user-card'
|
|
4
|
-
import '
|
|
5
|
-
|
|
4
|
+
import RcMenu, { SubMenu, MenuItem } from 'rc-menu'
|
|
5
|
+
import { CloseCircleOutlined } from '@ant-design/icons'
|
|
6
6
|
const { Sider } = Layout
|
|
7
7
|
|
|
8
8
|
export interface LiosLayoutlProps {
|
|
@@ -10,9 +10,10 @@ export interface LiosLayoutlProps {
|
|
|
10
10
|
productCode: string
|
|
11
11
|
children: any
|
|
12
12
|
menuList: any
|
|
13
|
-
onMenuClick:
|
|
13
|
+
onMenuClick: any
|
|
14
14
|
selectedKeys: string[]
|
|
15
|
-
|
|
15
|
+
setSelectKeys: any
|
|
16
|
+
customAction?: any
|
|
16
17
|
actions?: any[]
|
|
17
18
|
myWalletInfo?: {
|
|
18
19
|
availableCashAmount: string
|
|
@@ -26,23 +27,23 @@ export interface LiosLayoutlProps {
|
|
|
26
27
|
residueNum: string
|
|
27
28
|
currencyCode: string
|
|
28
29
|
}
|
|
29
|
-
myWalletInfoAction?:
|
|
30
|
-
myLoginInfoAction?:
|
|
30
|
+
myWalletInfoAction?: any
|
|
31
|
+
myLoginInfoAction?: any
|
|
31
32
|
logoutUrl?: string
|
|
32
33
|
switchTenantUrl?: string
|
|
33
34
|
defaultOpenKeys?: string[]
|
|
34
35
|
isHideHeader?: boolean //是否隐藏header
|
|
35
36
|
onCollapse?: (value: boolean) => void
|
|
37
|
+
type?: string
|
|
36
38
|
}
|
|
37
39
|
|
|
38
40
|
export default function LiosLayout(props: LiosLayoutlProps) {
|
|
39
41
|
const {
|
|
40
42
|
appName,
|
|
41
|
-
productCode,
|
|
42
43
|
menuList,
|
|
43
44
|
onMenuClick,
|
|
44
|
-
selectedKeys,
|
|
45
|
-
|
|
45
|
+
selectedKeys = [],
|
|
46
|
+
setSelectKeys = () => {},
|
|
46
47
|
customAction,
|
|
47
48
|
actions,
|
|
48
49
|
|
|
@@ -54,9 +55,30 @@ export default function LiosLayout(props: LiosLayoutlProps) {
|
|
|
54
55
|
myLoginInfoAction,
|
|
55
56
|
isHideHeader,
|
|
56
57
|
onCollapse,
|
|
58
|
+
type,
|
|
57
59
|
} = props
|
|
58
60
|
|
|
59
|
-
const
|
|
61
|
+
const [selectKey, setSelectKey] = useState<any>([])
|
|
62
|
+
|
|
63
|
+
useEffect(() => {
|
|
64
|
+
if (type !== 'console') {
|
|
65
|
+
import('./index.scss')
|
|
66
|
+
} else {
|
|
67
|
+
import('./index-console.scss')
|
|
68
|
+
}
|
|
69
|
+
}, [type])
|
|
70
|
+
|
|
71
|
+
const logoUrl =
|
|
72
|
+
type === 'console'
|
|
73
|
+
? 'https://cfel-front.oss-cn-hangzhou.aliyuncs.com/logo/company-logo/cfel-logo-white-compress.png'
|
|
74
|
+
: 'https://cfel-front.oss-cn-hangzhou.aliyuncs.com/logo/company-logo/chengfengerlai.png'
|
|
75
|
+
|
|
76
|
+
const subLogoUrl =
|
|
77
|
+
type === 'console'
|
|
78
|
+
? 'https://cfel-front.oss-cn-hangzhou.aliyuncs.com/logo/company-logo/chengfengerlai-white.png'
|
|
79
|
+
: 'https://cfel-front.oss-cn-hangzhou.aliyuncs.com/logo/company-logo/chengfengerlai.png'
|
|
80
|
+
|
|
81
|
+
const { user, logo, subLogo, productCode } = (window as any)?.g_config
|
|
60
82
|
const { name, avatar } = user || {}
|
|
61
83
|
|
|
62
84
|
const [openKeys, setOpenKeys] = useState<any>(defaultOpenKeys || [])
|
|
@@ -85,6 +107,7 @@ export default function LiosLayout(props: LiosLayoutlProps) {
|
|
|
85
107
|
findNode(menuList, [])
|
|
86
108
|
return result
|
|
87
109
|
}
|
|
110
|
+
|
|
88
111
|
useEffect(() => {
|
|
89
112
|
//在这里找到当前菜单的上层目录
|
|
90
113
|
const paMenu = findParentMenu(menuList, '/' + location.pathname.split('/')[2])
|
|
@@ -115,52 +138,183 @@ export default function LiosLayout(props: LiosLayoutlProps) {
|
|
|
115
138
|
} catch (err) {}
|
|
116
139
|
}
|
|
117
140
|
|
|
141
|
+
const collapseNode = () => {
|
|
142
|
+
return {
|
|
143
|
+
height: 0,
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
const expandNode = (node: any) => {
|
|
147
|
+
return { height: node.scrollHeight }
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
const inlineMotion = {
|
|
151
|
+
motionName: 'rc-menu-collapse',
|
|
152
|
+
onAppearStart: collapseNode,
|
|
153
|
+
onAppearActive: expandNode,
|
|
154
|
+
onEnterStart: collapseNode,
|
|
155
|
+
onEnterActive: expandNode,
|
|
156
|
+
onLeaveStart: expandNode,
|
|
157
|
+
onLeaveActive: collapseNode,
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
const verticalMotion = {
|
|
161
|
+
motionName: 'rc-menu-open-zoom',
|
|
162
|
+
motionAppear: true,
|
|
163
|
+
motionEnter: true,
|
|
164
|
+
motionLeave: true,
|
|
165
|
+
}
|
|
166
|
+
|
|
118
167
|
return (
|
|
119
|
-
<Layout className="layout-
|
|
168
|
+
<Layout className="layout-warps">
|
|
120
169
|
{Array.isArray(menuList) && menuList.length > 0 && (
|
|
121
170
|
<Sider
|
|
122
171
|
className="layout-side"
|
|
123
|
-
style={{
|
|
124
|
-
backgroundSize: collapsed ? '1800%' : '900%',
|
|
125
|
-
}}
|
|
126
172
|
collapsible
|
|
173
|
+
trigger={null}
|
|
127
174
|
collapsed={collapsed}
|
|
128
|
-
width={
|
|
175
|
+
width={260}
|
|
129
176
|
onCollapse={(value) => {
|
|
130
|
-
|
|
177
|
+
if (onCollapse) {
|
|
178
|
+
onCollapse(value)
|
|
179
|
+
}
|
|
131
180
|
localStorage.setItem('layout_collapsed', value.toString())
|
|
132
181
|
setCollapsed(value)
|
|
133
182
|
}}
|
|
134
183
|
>
|
|
135
|
-
<div
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
<img
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
184
|
+
<div className="header-logo" style={{ justifyContent: collapsed ? 'center' : '', paddingLeft: collapsed ? '0' : '' }}>
|
|
185
|
+
<div
|
|
186
|
+
onClick={() => {
|
|
187
|
+
window.open('/home')
|
|
188
|
+
}}
|
|
189
|
+
>
|
|
190
|
+
{!collapsed && <img className={`logo-base current-logo`} src={logo || logoUrl} />}
|
|
191
|
+
|
|
192
|
+
{collapsed && <img className={`logo-base sub-logo`} src={logo || subLogoUrl} />}
|
|
193
|
+
</div>
|
|
194
|
+
|
|
195
|
+
{/* {!collapsed && (
|
|
196
|
+
<div
|
|
197
|
+
className="trigger"
|
|
198
|
+
onClick={() => {
|
|
199
|
+
setCollapsed(true)
|
|
200
|
+
}}
|
|
201
|
+
>
|
|
202
|
+
<Arrow collapsed={true} />
|
|
203
|
+
</div>
|
|
204
|
+
)} */}
|
|
149
205
|
</div>
|
|
150
206
|
|
|
151
|
-
|
|
152
|
-
<
|
|
153
|
-
|
|
207
|
+
{/* {collapsed && (
|
|
208
|
+
<div style={{ width: '100%', display: 'flex', justifyContent: 'center' }}>
|
|
209
|
+
<div
|
|
210
|
+
className="close-trigger"
|
|
211
|
+
onClick={() => {
|
|
212
|
+
setCollapsed(false)
|
|
213
|
+
}}
|
|
214
|
+
>
|
|
215
|
+
<Arrow collapsed={false} />
|
|
216
|
+
</div>
|
|
217
|
+
</div>
|
|
218
|
+
)} */}
|
|
219
|
+
|
|
220
|
+
{!collapsed && <div style={{ height: 24 }}></div>}
|
|
221
|
+
|
|
222
|
+
<div className="layout-menu">
|
|
223
|
+
<RcMenu
|
|
224
|
+
mode={collapsed ? 'vertical' : 'inline'}
|
|
225
|
+
className={`menu${collapsed ? '-collapsed' : ''}`}
|
|
226
|
+
motion={collapsed ? verticalMotion : inlineMotion}
|
|
154
227
|
openKeys={openKeys}
|
|
155
228
|
onOpenChange={onOpenChange}
|
|
156
|
-
|
|
157
|
-
onClick={(item
|
|
158
|
-
|
|
229
|
+
selectedKeys={selectKey}
|
|
230
|
+
onClick={(item: any) => {
|
|
231
|
+
setSelectKey(item.keyPath)
|
|
232
|
+
if (onMenuClick) {
|
|
233
|
+
onMenuClick(item)
|
|
234
|
+
}
|
|
159
235
|
}}
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
236
|
+
triggerSubMenuAction="hover"
|
|
237
|
+
>
|
|
238
|
+
{menuList.map((item: any) => {
|
|
239
|
+
const isSelected = selectKey.includes(item.key)
|
|
240
|
+
if (item.children) {
|
|
241
|
+
let classNames = 'menu-item-label'
|
|
242
|
+
if (isSelected) {
|
|
243
|
+
classNames += ' submenu-selected'
|
|
244
|
+
}
|
|
245
|
+
return (
|
|
246
|
+
<SubMenu
|
|
247
|
+
popupClassName="rc-menu-submenu-popup"
|
|
248
|
+
key={item.key}
|
|
249
|
+
className="menu-item-content"
|
|
250
|
+
title={
|
|
251
|
+
<div className="sub-list">
|
|
252
|
+
<div className="menu-item-inner">
|
|
253
|
+
<span className={`menu-item-icon ${isSelected ? 'submenu-selected' : ''}`}>{item.icon}</span>
|
|
254
|
+
{!collapsed && <span className={classNames}>{item.label}</span>}
|
|
255
|
+
</div>
|
|
256
|
+
</div>
|
|
257
|
+
}
|
|
258
|
+
>
|
|
259
|
+
{item.children.map((child: any) => {
|
|
260
|
+
const isSelected = selectKey.includes(child.key)
|
|
261
|
+
if (item.children) {
|
|
262
|
+
let classNames = 'menu-item-label'
|
|
263
|
+
if (isSelected) {
|
|
264
|
+
classNames += ' submenu-selected'
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
if (child.children) {
|
|
268
|
+
return (
|
|
269
|
+
<SubMenu
|
|
270
|
+
popupClassName="rc-menu-submenu-popup"
|
|
271
|
+
className="menu-item-content sub-li"
|
|
272
|
+
key={child.key}
|
|
273
|
+
title={<div className="sub-list">{!collapsed && <span className={`menu-item-label ${isSelected ? 'submenu-selected' : ''}`}>{child.label}</span>}</div>}
|
|
274
|
+
>
|
|
275
|
+
{child.children.map((grandChild: any) => {
|
|
276
|
+
const isSelected = selectKey.includes(grandChild.key)
|
|
277
|
+
if (item.children) {
|
|
278
|
+
let classNames = 'menu-item-label'
|
|
279
|
+
if (isSelected) {
|
|
280
|
+
classNames += ' submenu-selected'
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
return (
|
|
284
|
+
<MenuItem key={grandChild.key} className="grand-li">
|
|
285
|
+
<div className="menu-item-content">{!collapsed && <span className={`menu-item-label ${isSelected ? 'submenu-selected' : ''}`}>{grandChild.label}</span>}</div>
|
|
286
|
+
</MenuItem>
|
|
287
|
+
)
|
|
288
|
+
})}
|
|
289
|
+
</SubMenu>
|
|
290
|
+
)
|
|
291
|
+
}
|
|
292
|
+
return (
|
|
293
|
+
<MenuItem key={child.key} className="sub-li">
|
|
294
|
+
<div className="menu-item-content">{!collapsed && <span className={`menu-item-label ${isSelected ? 'submenu-selected' : ''}`}>{child.label}</span>}</div>
|
|
295
|
+
</MenuItem>
|
|
296
|
+
)
|
|
297
|
+
})}
|
|
298
|
+
</SubMenu>
|
|
299
|
+
)
|
|
300
|
+
}
|
|
301
|
+
// 没有子菜单的
|
|
302
|
+
else {
|
|
303
|
+
let classNames = 'menu-item-label'
|
|
304
|
+
if (isSelected) {
|
|
305
|
+
classNames += ' submenu-selected'
|
|
306
|
+
}
|
|
307
|
+
return (
|
|
308
|
+
<MenuItem key={item.key} className="menu-item-content">
|
|
309
|
+
<div>
|
|
310
|
+
<span className={`menu-item-icon ${isSelected ? 'submenu-selected' : ''}`}>{item.icon}</span>
|
|
311
|
+
{!collapsed && <span className={classNames}>{item.label}</span>}
|
|
312
|
+
</div>
|
|
313
|
+
</MenuItem>
|
|
314
|
+
)
|
|
315
|
+
}
|
|
316
|
+
})}
|
|
317
|
+
</RcMenu>
|
|
164
318
|
</div>
|
|
165
319
|
</Sider>
|
|
166
320
|
)}
|
|
@@ -201,7 +355,9 @@ export default function LiosLayout(props: LiosLayoutlProps) {
|
|
|
201
355
|
tenantName: false,
|
|
202
356
|
tenantId: false,
|
|
203
357
|
})
|
|
204
|
-
|
|
358
|
+
if (myLoginInfoAction) {
|
|
359
|
+
myLoginInfoAction()
|
|
360
|
+
}
|
|
205
361
|
}}
|
|
206
362
|
>
|
|
207
363
|
<div className="layout-header-user">
|
|
@@ -216,3 +372,183 @@ export default function LiosLayout(props: LiosLayoutlProps) {
|
|
|
216
372
|
</Layout>
|
|
217
373
|
)
|
|
218
374
|
}
|
|
375
|
+
|
|
376
|
+
function Arrow({ collapsed }: { collapsed?: boolean }) {
|
|
377
|
+
return (
|
|
378
|
+
<div>
|
|
379
|
+
<svg style={{ transform: !collapsed ? 'rotate(180deg)' : 'rotate(0deg)' }} viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" width="20" height="20">
|
|
380
|
+
<path
|
|
381
|
+
fill="#7D8295"
|
|
382
|
+
d="M564.6336 775.168a41.5744 41.5744 0 0 0-13.312-28.672l-230.4-234.4448 229.9904-234.1888a42.0864 42.0864 0 0 0-26.3168-73.0112 42.0864 42.0864 0 0 0-30.6176 11.264L231.0656 481.024a41.984 41.984 0 0 0-2.4576 59.5968l1.9968 2.048 263.7824 265.6256a41.984 41.984 0 0 0 70.2464-33.0752z m254.5152 0a41.472 41.472 0 0 0-13.312-28.672L575.488 512l229.9904-234.1376a41.984 41.984 0 1 0-56.9344-61.7984L485.632 480.9728a42.0864 42.0864 0 0 0-2.4064 59.6992l0.8704 0.9216 0.8704 0.8192 0.4096 0.4096 263.5776 265.4208a41.984 41.984 0 0 0 70.1952-33.0752z"
|
|
383
|
+
></path>
|
|
384
|
+
</svg>
|
|
385
|
+
</div>
|
|
386
|
+
)
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
function Search({ menuList, collapsed, type }: { menuList: any; collapsed: boolean; type: string }) {
|
|
390
|
+
useEffect(() => {
|
|
391
|
+
const handleKeyDown = (event: KeyboardEvent) => {
|
|
392
|
+
// Check for Ctrl+K (Windows) or Cmd+K (Mac)
|
|
393
|
+
if ((navigator.platform.toLowerCase().includes('mac') ? event.metaKey : event.ctrlKey) && event.key.toLowerCase() === 'k') {
|
|
394
|
+
event.preventDefault()
|
|
395
|
+
const searchInput = document.querySelector('#menu-input') as HTMLInputElement
|
|
396
|
+
if (searchInput) {
|
|
397
|
+
searchInput.focus()
|
|
398
|
+
setIsHovered(true)
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
document.addEventListener('keydown', handleKeyDown)
|
|
404
|
+
return () => {
|
|
405
|
+
document.removeEventListener('keydown', handleKeyDown)
|
|
406
|
+
}
|
|
407
|
+
}, [])
|
|
408
|
+
type Router = { label: string; icon?: any; key: string; children?: Router[] }
|
|
409
|
+
|
|
410
|
+
const name = (window as any).g_config.productCode
|
|
411
|
+
|
|
412
|
+
const [searchTerm, setSearchTerm] = useState('')
|
|
413
|
+
const [searchHistory, setSearchHistory] = useState<Router[]>([])
|
|
414
|
+
const [searchResult, setSearchResult] = useState<Router[]>([])
|
|
415
|
+
const [isHovered, setIsHovered] = useState(false)
|
|
416
|
+
|
|
417
|
+
useEffect(() => {
|
|
418
|
+
const searchHistory = localStorage.getItem(name + 'searchHistory')
|
|
419
|
+
if (searchHistory) {
|
|
420
|
+
setSearchHistory(JSON.parse(searchHistory))
|
|
421
|
+
} else {
|
|
422
|
+
setSearchHistory([])
|
|
423
|
+
}
|
|
424
|
+
}, [])
|
|
425
|
+
|
|
426
|
+
useEffect(() => {
|
|
427
|
+
if (searchHistory.length > 5) {
|
|
428
|
+
searchHistory.shift()
|
|
429
|
+
}
|
|
430
|
+
localStorage.setItem(name + 'searchHistory', JSON.stringify(searchHistory))
|
|
431
|
+
}, [searchHistory])
|
|
432
|
+
|
|
433
|
+
const handleSearch = (value: string) => {
|
|
434
|
+
setSearchTerm(value)
|
|
435
|
+
//递归menulist判断是否有包含的
|
|
436
|
+
const searchResults: Router[] = []
|
|
437
|
+
search(menuList)
|
|
438
|
+
setSearchResult(searchResults)
|
|
439
|
+
function search(data: Router[]) {
|
|
440
|
+
data.forEach((item) => {
|
|
441
|
+
if (item.label.includes(value.toLocaleUpperCase())) {
|
|
442
|
+
searchResults.push(item)
|
|
443
|
+
}
|
|
444
|
+
if (item.children) {
|
|
445
|
+
search(item.children)
|
|
446
|
+
}
|
|
447
|
+
})
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
const enter = (item: Router) => {
|
|
452
|
+
setIsHovered(false)
|
|
453
|
+
//如果搜索历史里面有这个item,就不再添加
|
|
454
|
+
if (searchHistory.findIndex((i) => i.key === item.key) === -1) {
|
|
455
|
+
setSearchHistory([...searchHistory, item])
|
|
456
|
+
}
|
|
457
|
+
//如果是目录就找到目录下第一个菜单进入
|
|
458
|
+
if (!item.key.includes('/')) {
|
|
459
|
+
//递归找到目录下第一个菜单
|
|
460
|
+
const findFirst = (data: Router[]): Router | undefined => {
|
|
461
|
+
for (let i = 0; i < data.length; i++) {
|
|
462
|
+
if (data[i].key.includes('/')) {
|
|
463
|
+
return data[i]
|
|
464
|
+
} else {
|
|
465
|
+
return findFirst(data[i].children || [])
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
const firstItem = findFirst(item.children || [])
|
|
470
|
+
if (firstItem) {
|
|
471
|
+
//history.push(firstItem.key, '_self')
|
|
472
|
+
}
|
|
473
|
+
} else {
|
|
474
|
+
// history.push(item.key, '_self')
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
const deleteHistory = (item: Router) => {
|
|
479
|
+
setSearchHistory(searchHistory.filter((i) => i.key !== item.key))
|
|
480
|
+
}
|
|
481
|
+
return (
|
|
482
|
+
<>
|
|
483
|
+
{collapsed ? (
|
|
484
|
+
<div className="search-mobile">
|
|
485
|
+
{' '}
|
|
486
|
+
<div className="search-icon">
|
|
487
|
+
<svg viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" width="18" height="18">
|
|
488
|
+
<path
|
|
489
|
+
fill="#B3A6F4"
|
|
490
|
+
d="M962.048 907.776l-229.0176-229.0176a384.3072 384.3072 0 1 0-54.272 54.272l229.0176 229.0176a38.4 38.4 0 0 0 54.272-54.272zM436.1216 743.0656a306.944 306.944 0 1 1 306.944-306.944 307.3024 307.3024 0 0 1-306.944 306.944z"
|
|
491
|
+
></path>
|
|
492
|
+
</svg>
|
|
493
|
+
</div>
|
|
494
|
+
</div>
|
|
495
|
+
) : (
|
|
496
|
+
<div onMouseEnter={() => setIsHovered(true)} onMouseLeave={() => setIsHovered(false)}>
|
|
497
|
+
<div className="search">
|
|
498
|
+
<input id="menu-input" value={searchTerm} onChange={(e) => handleSearch(e.target.value)} className="search-input" placeholder="搜索菜单" />
|
|
499
|
+
<div className="search-icon">
|
|
500
|
+
<svg viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" width="18" height="18">
|
|
501
|
+
<path
|
|
502
|
+
fill={type === 'console' ? '#C2B7F6' : '#817F9B'}
|
|
503
|
+
d="M962.048 907.776l-229.0176-229.0176a384.3072 384.3072 0 1 0-54.272 54.272l229.0176 229.0176a38.4 38.4 0 0 0 54.272-54.272zM436.1216 743.0656a306.944 306.944 0 1 1 306.944-306.944 307.3024 307.3024 0 0 1-306.944 306.944z"
|
|
504
|
+
></path>
|
|
505
|
+
</svg>
|
|
506
|
+
</div>
|
|
507
|
+
<div className="search-command">{navigator.platform.toLowerCase().includes('mac') ? '⌘' : '⊞'}K</div>
|
|
508
|
+
</div>
|
|
509
|
+
<div>
|
|
510
|
+
{isHovered && (
|
|
511
|
+
<>
|
|
512
|
+
{searchTerm ? (
|
|
513
|
+
<List split={false} className="list" size="small" bordered dataSource={searchResult} renderItem={(item) => <List.Item onClick={() => enter(item)}>{item.label}</List.Item>} />
|
|
514
|
+
) : (
|
|
515
|
+
<List
|
|
516
|
+
split={false}
|
|
517
|
+
className="list"
|
|
518
|
+
header={<div>最近访问</div>}
|
|
519
|
+
size="small"
|
|
520
|
+
bordered
|
|
521
|
+
dataSource={searchHistory}
|
|
522
|
+
renderItem={(item) => {
|
|
523
|
+
return (
|
|
524
|
+
<div
|
|
525
|
+
className={'search-item'}
|
|
526
|
+
style={{
|
|
527
|
+
display: 'flex',
|
|
528
|
+
justifyContent: 'space-between',
|
|
529
|
+
alignItems: 'center',
|
|
530
|
+
}}
|
|
531
|
+
onClick={() => enter(item)}
|
|
532
|
+
>
|
|
533
|
+
<List.Item>{item.label}</List.Item>
|
|
534
|
+
<div
|
|
535
|
+
style={{ paddingRight: 10 }}
|
|
536
|
+
onClick={() => {
|
|
537
|
+
deleteHistory(item)
|
|
538
|
+
}}
|
|
539
|
+
>
|
|
540
|
+
<CloseCircleOutlined />
|
|
541
|
+
</div>
|
|
542
|
+
</div>
|
|
543
|
+
)
|
|
544
|
+
}}
|
|
545
|
+
/>
|
|
546
|
+
)}
|
|
547
|
+
</>
|
|
548
|
+
)}
|
|
549
|
+
</div>
|
|
550
|
+
</div>
|
|
551
|
+
)}
|
|
552
|
+
</>
|
|
553
|
+
)
|
|
554
|
+
}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
$header-height: 60px;
|
|
2
|
+
$base-color: #c6538c;
|
|
3
|
+
|
|
4
|
+
body {
|
|
5
|
+
overflow: hidden;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
.layout-warp {
|
|
9
|
+
display: flex;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
.ant-layout .ant-layout-sider {
|
|
13
|
+
background-image: linear-gradient(
|
|
14
|
+
-45deg,
|
|
15
|
+
rgba(103, 200, 21, 0.5),
|
|
16
|
+
rgba(55, 96, 244, 0.5),
|
|
17
|
+
rgba(245, 34, 45, 0.7)
|
|
18
|
+
);
|
|
19
|
+
background-position: center;
|
|
20
|
+
// background-color: #fff;
|
|
21
|
+
// background-color: #13c2c2;
|
|
22
|
+
background-color: #08979c;
|
|
23
|
+
// background-color: #531dab;
|
|
24
|
+
// background-color: #389e0d;
|
|
25
|
+
|
|
26
|
+
.ant-layout-sider-trigger {
|
|
27
|
+
background: transparent;
|
|
28
|
+
&:hover {
|
|
29
|
+
background: rgba(0, 0, 0, 0.12);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.layout-side {
|
|
35
|
+
height: 100vh;
|
|
36
|
+
user-select: none;
|
|
37
|
+
overflow: hidden;
|
|
38
|
+
|
|
39
|
+
.layout-logo {
|
|
40
|
+
cursor: pointer;
|
|
41
|
+
height: 60px;
|
|
42
|
+
margin: 8px auto;
|
|
43
|
+
display: flex;
|
|
44
|
+
justify-content: center;
|
|
45
|
+
align-items: center;
|
|
46
|
+
width: 100%;
|
|
47
|
+
z-index: 1;
|
|
48
|
+
|
|
49
|
+
.logo-img {
|
|
50
|
+
position: absolute;
|
|
51
|
+
height: 60px;
|
|
52
|
+
line-height: 60px;
|
|
53
|
+
object-fit: cover;
|
|
54
|
+
transition: all 0.8s cubic-bezier(0.645, 0.045, 0.355, 1);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.current-logo {
|
|
58
|
+
left: 0;
|
|
59
|
+
right: 0;
|
|
60
|
+
margin: auto;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
.hide-logo {
|
|
64
|
+
left: -500px;
|
|
65
|
+
}
|
|
66
|
+
.hide-sub-logo {
|
|
67
|
+
right: -500px;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
.layout-menu-container {
|
|
72
|
+
height: calc(100vh - 60px - 16px - 48px);
|
|
73
|
+
overflow: auto;
|
|
74
|
+
.ant-menu {
|
|
75
|
+
background: transparent !important;
|
|
76
|
+
}
|
|
77
|
+
.ant-menu-item-selected {
|
|
78
|
+
background: rgba(255, 255, 255, 0.3) !important;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
.layout-header {
|
|
84
|
+
height: $header-height;
|
|
85
|
+
background: white;
|
|
86
|
+
z-index: 1;
|
|
87
|
+
position: relative;
|
|
88
|
+
display: flex;
|
|
89
|
+
justify-content: flex-start;
|
|
90
|
+
align-items: center;
|
|
91
|
+
|
|
92
|
+
.app-name {
|
|
93
|
+
margin-left: 24px;
|
|
94
|
+
font-weight: 500;
|
|
95
|
+
color: rgba(0, 0, 0, 0.65);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
.layout-header-fill {
|
|
99
|
+
flex: 1;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
.layout-header-actions {
|
|
103
|
+
display: flex;
|
|
104
|
+
justify-content: flex-start;
|
|
105
|
+
align-items: center;
|
|
106
|
+
height: 100%;
|
|
107
|
+
max-width: 400px;
|
|
108
|
+
z-index: 2;
|
|
109
|
+
|
|
110
|
+
.actions-item {
|
|
111
|
+
height: 36px;
|
|
112
|
+
border-radius: 6px;
|
|
113
|
+
transition: all 0.3s;
|
|
114
|
+
cursor: pointer;
|
|
115
|
+
margin: 0 4px;
|
|
116
|
+
padding: 0 4px;
|
|
117
|
+
|
|
118
|
+
display: flex;
|
|
119
|
+
justify-content: center;
|
|
120
|
+
align-items: center;
|
|
121
|
+
|
|
122
|
+
&:hover {
|
|
123
|
+
background: rgba(0, 0, 0, 0.06);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
.layout-header-user {
|
|
129
|
+
height: 48px;
|
|
130
|
+
display: flex;
|
|
131
|
+
justify-content: flex-start;
|
|
132
|
+
align-items: center;
|
|
133
|
+
z-index: 2;
|
|
134
|
+
transition: all 0.3s;
|
|
135
|
+
padding: 4px 12px;
|
|
136
|
+
margin: 0 12px;
|
|
137
|
+
border-radius: 6px;
|
|
138
|
+
cursor: pointer;
|
|
139
|
+
|
|
140
|
+
&:hover {
|
|
141
|
+
background: rgba(0, 0, 0, 0.06);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
.avatar {
|
|
145
|
+
width: 40px;
|
|
146
|
+
height: 40px;
|
|
147
|
+
border-radius: 50%;
|
|
148
|
+
margin-right: 12px;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
.layout-main {
|
|
154
|
+
flex: 1;
|
|
155
|
+
height: 100%;
|
|
156
|
+
overflow: auto;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
.layout-content {
|
|
160
|
+
width: 100%;
|
|
161
|
+
height: calc(100vh - #{$header-height});
|
|
162
|
+
overflow: auto;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
.ant-menu-submenu-popup {
|
|
166
|
+
.ant-menu-item-selected {
|
|
167
|
+
background: rgba(255, 255, 255, 0.12) !important;
|
|
168
|
+
}
|
|
169
|
+
}
|