nsgm-cli 2.1.5 → 2.1.6
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/README.md +0 -2
- package/client/layout/index.tsx +107 -33
- package/client/styled/common.ts +18 -22
- package/client/styled/layout/index.ts +131 -9
- package/client/styled/template/manage.ts +86 -2
- package/lib/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +5 -5
- package/pages/index.tsx +84 -40
- package/pages/login.tsx +41 -15
- package/pages/template/manage.tsx +138 -53
package/README.md
CHANGED
package/client/layout/index.tsx
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import React, { useEffect, useState } from 'react'
|
|
2
|
-
import { Layout, Menu, Breadcrumb, Image, Select } from 'antd'
|
|
2
|
+
import { Layout, Menu, Breadcrumb, Image, Select, Avatar, Dropdown, Space, Tooltip } from 'antd'
|
|
3
3
|
import { Container } from '../styled/layout'
|
|
4
|
+
import styled from 'styled-components'
|
|
4
5
|
import { useRouter } from 'next/router'
|
|
5
6
|
import _ from 'lodash'
|
|
6
7
|
import menuConfig from '../utils/menu'
|
|
7
8
|
import { logout } from '../utils/sso'
|
|
8
9
|
import getConfig from 'next/config'
|
|
10
|
+
import { UserOutlined, LogoutOutlined, SettingOutlined, BellOutlined } from '@ant-design/icons'
|
|
9
11
|
|
|
10
12
|
const { Option } = Select
|
|
11
13
|
const { SubMenu } = Menu
|
|
@@ -15,6 +17,34 @@ const nextConfig = getConfig()
|
|
|
15
17
|
const { publicRuntimeConfig } = nextConfig
|
|
16
18
|
const { prefix } = publicRuntimeConfig
|
|
17
19
|
|
|
20
|
+
// styled-components
|
|
21
|
+
const FlexLayout = styled(Layout)`
|
|
22
|
+
display: flex;
|
|
23
|
+
flex: 1;
|
|
24
|
+
`
|
|
25
|
+
const StyledSider = styled(Sider)`
|
|
26
|
+
display: flex;
|
|
27
|
+
flex-direction: column;
|
|
28
|
+
justify-content: space-between;
|
|
29
|
+
`
|
|
30
|
+
const SiderFooter = styled.div<{ collapsed: boolean }>`
|
|
31
|
+
padding: ${props => props.collapsed ? '8px 0' : '8px 16px'};
|
|
32
|
+
text-align: center;
|
|
33
|
+
color: rgba(0,0,0,0.45);
|
|
34
|
+
font-size: 12px;
|
|
35
|
+
border-top: 1px solid #ebeef5;
|
|
36
|
+
background: #f5f7fa;
|
|
37
|
+
`
|
|
38
|
+
const SideMenu = styled(Menu)`
|
|
39
|
+
height: 100%;
|
|
40
|
+
border-right: 0;
|
|
41
|
+
`
|
|
42
|
+
const ContentLayout = styled(Layout)`
|
|
43
|
+
display: flex;
|
|
44
|
+
flex-direction: column;
|
|
45
|
+
flex: 1;
|
|
46
|
+
`
|
|
47
|
+
|
|
18
48
|
const getLocationKey = () => {
|
|
19
49
|
let result = {
|
|
20
50
|
topMenu: '1',
|
|
@@ -85,6 +115,7 @@ const LayoutComponent = ({ user, children }) => {
|
|
|
85
115
|
const router = useRouter()
|
|
86
116
|
const [topMenuKey, setTopMenuKey] = useState('1')
|
|
87
117
|
const [sliderMenuKey, setSliderMenuKey] = useState('1')
|
|
118
|
+
const [collapsed, setCollapsed] = useState(false)
|
|
88
119
|
|
|
89
120
|
// console.log('topMenuKey: ' + topMenuKey, ', sliderMenuKey: ' + sliderMenuKey, user)
|
|
90
121
|
|
|
@@ -175,44 +206,92 @@ const LayoutComponent = ({ user, children }) => {
|
|
|
175
206
|
})
|
|
176
207
|
|
|
177
208
|
return (
|
|
178
|
-
<Layout>
|
|
209
|
+
<Layout className="main-layout">
|
|
179
210
|
<Container>
|
|
180
211
|
<Header className="header">
|
|
181
212
|
<div className="logo">
|
|
182
213
|
<Image width={100} src={prefix + "/images/zhizuotu_1.png"} preview={false} />
|
|
183
214
|
</div>
|
|
184
|
-
<Menu
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
215
|
+
<Menu
|
|
216
|
+
theme="dark"
|
|
217
|
+
mode="horizontal"
|
|
218
|
+
defaultSelectedKeys={['1']}
|
|
219
|
+
selectedKeys={[topMenuKey]}
|
|
220
|
+
items={menuItems}
|
|
221
|
+
className="main-menu"
|
|
222
|
+
/>
|
|
223
|
+
<div className="user-actions">
|
|
224
|
+
<Space size={16} align="center">
|
|
225
|
+
<Tooltip title="通知">
|
|
226
|
+
<BellOutlined className="action-icon" />
|
|
227
|
+
</Tooltip>
|
|
228
|
+
<Tooltip title="设置">
|
|
229
|
+
<SettingOutlined className="action-icon" />
|
|
230
|
+
</Tooltip>
|
|
231
|
+
<Dropdown
|
|
232
|
+
menu={{
|
|
233
|
+
items: [
|
|
234
|
+
{
|
|
235
|
+
key: '1',
|
|
236
|
+
icon: <UserOutlined />,
|
|
237
|
+
label: '个人中心',
|
|
238
|
+
},
|
|
239
|
+
{
|
|
240
|
+
key: '2',
|
|
241
|
+
icon: <SettingOutlined />,
|
|
242
|
+
label: '账户设置',
|
|
243
|
+
},
|
|
244
|
+
{
|
|
245
|
+
type: 'divider',
|
|
246
|
+
},
|
|
247
|
+
{
|
|
248
|
+
key: '3',
|
|
249
|
+
icon: <LogoutOutlined />,
|
|
250
|
+
label: '退出登录',
|
|
251
|
+
onClick: () => logout(),
|
|
252
|
+
},
|
|
253
|
+
],
|
|
254
|
+
}}
|
|
255
|
+
>
|
|
256
|
+
<Space className="user-dropdown">
|
|
257
|
+
<span className="username">{user?.displayName || '用户'}</span>
|
|
258
|
+
</Space>
|
|
259
|
+
</Dropdown>
|
|
260
|
+
</Space>
|
|
189
261
|
</div>
|
|
190
262
|
</Header>
|
|
191
|
-
<
|
|
192
|
-
<
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
263
|
+
<FlexLayout>
|
|
264
|
+
<StyledSider
|
|
265
|
+
width={200}
|
|
266
|
+
className="site-layout-background sidebar"
|
|
267
|
+
collapsible
|
|
268
|
+
collapsed={collapsed}
|
|
269
|
+
onCollapse={(value) => setCollapsed(value)}
|
|
270
|
+
>
|
|
271
|
+
<div>
|
|
272
|
+
<SideMenu
|
|
273
|
+
mode="inline"
|
|
274
|
+
defaultSelectedKeys={['slider_1_0']}
|
|
275
|
+
defaultOpenKeys={['slider_1']}
|
|
276
|
+
selectedKeys={['slider_' + topMenuKey + '_' + sliderMenuKey]}
|
|
277
|
+
openKeys={['slider_' + topMenuKey]}
|
|
278
|
+
items={menuItemsVertical}
|
|
279
|
+
className="side-menu"
|
|
280
|
+
/>
|
|
281
|
+
</div>
|
|
282
|
+
<SiderFooter collapsed={collapsed}>
|
|
283
|
+
{collapsed ? '©' : '© 2025 NSGM'}
|
|
284
|
+
</SiderFooter>
|
|
285
|
+
</StyledSider>
|
|
286
|
+
<ContentLayout className="content-layout">
|
|
287
|
+
<Breadcrumb className="breadcrumb-container">
|
|
205
288
|
{_.map(menuConfig, (item, index) => {
|
|
206
289
|
const { key, text, subMenus } = item
|
|
207
290
|
|
|
208
291
|
if (subMenus) {
|
|
209
|
-
// console.log('subMenus', subMenus)
|
|
210
|
-
|
|
211
292
|
let subContent: any = []
|
|
212
293
|
_.each(subMenus, (subItem, subIndex) => {
|
|
213
294
|
const { key: subKey, text: subText } = subItem
|
|
214
|
-
// console.log('subKey', subKey, key, topMenuKey, sliderMenuKey)
|
|
215
|
-
|
|
216
295
|
if (subKey === topMenuKey + '_' + sliderMenuKey) {
|
|
217
296
|
subContent.push(<Breadcrumb.Item key={'breadcrumb' + subIndex}>{text}</Breadcrumb.Item>)
|
|
218
297
|
subContent.push(<Breadcrumb.Item key={'breadcrumb' + subIndex}>{subText}</Breadcrumb.Item>)
|
|
@@ -228,17 +307,12 @@ const LayoutComponent = ({ user, children }) => {
|
|
|
228
307
|
})}
|
|
229
308
|
</Breadcrumb>
|
|
230
309
|
<Content
|
|
231
|
-
className="site-layout-background"
|
|
232
|
-
style={{
|
|
233
|
-
padding: 24,
|
|
234
|
-
margin: 0,
|
|
235
|
-
minHeight: 280
|
|
236
|
-
}}
|
|
310
|
+
className="site-layout-background content-container"
|
|
237
311
|
>
|
|
238
312
|
{children}
|
|
239
313
|
</Content>
|
|
240
|
-
</
|
|
241
|
-
</
|
|
314
|
+
</ContentLayout>
|
|
315
|
+
</FlexLayout>
|
|
242
316
|
</Container>
|
|
243
317
|
</Layout>
|
|
244
318
|
)
|
package/client/styled/common.ts
CHANGED
|
@@ -19,33 +19,29 @@ export const Container = styled.div`
|
|
|
19
19
|
|
|
20
20
|
export const LoginContainer = styled.div`
|
|
21
21
|
margin: auto;
|
|
22
|
-
margin-top:
|
|
23
|
-
width:
|
|
22
|
+
margin-top: 100px;
|
|
23
|
+
width: 350px;
|
|
24
24
|
display: flex;
|
|
25
25
|
flex-direction: column;
|
|
26
26
|
justify-content: center;
|
|
27
|
-
align-items:
|
|
28
|
-
border: 1px solid
|
|
29
|
-
border-radius:
|
|
30
|
-
padding:
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
flex-direction: row;
|
|
37
|
-
justify-content: flex-start;
|
|
38
|
-
align-items: center;
|
|
39
|
-
|
|
40
|
-
.user-input {
|
|
41
|
-
width: 210px;
|
|
42
|
-
margin-bottom: 5px;
|
|
43
|
-
}
|
|
27
|
+
align-items: center;
|
|
28
|
+
border: 1px solid #e8e8e8;
|
|
29
|
+
border-radius: 8px;
|
|
30
|
+
padding: 30px;
|
|
31
|
+
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
|
32
|
+
background-color: #fff;
|
|
33
|
+
|
|
34
|
+
.ant-form-item {
|
|
35
|
+
margin-bottom: 20px;
|
|
44
36
|
}
|
|
45
37
|
|
|
46
|
-
.
|
|
47
|
-
|
|
48
|
-
|
|
38
|
+
.ant-input-affix-wrapper {
|
|
39
|
+
border-radius: 4px;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.ant-btn {
|
|
43
|
+
height: 40px;
|
|
44
|
+
border-radius: 4px;
|
|
49
45
|
}
|
|
50
46
|
`
|
|
51
47
|
|
|
@@ -1,26 +1,148 @@
|
|
|
1
1
|
import styled from 'styled-components'
|
|
2
2
|
|
|
3
3
|
export const Container = styled.div`
|
|
4
|
+
.main-layout {
|
|
5
|
+
min-height: 100vh;
|
|
6
|
+
display: flex;
|
|
7
|
+
flex-direction: column;
|
|
8
|
+
}
|
|
9
|
+
|
|
4
10
|
.header {
|
|
5
11
|
position: relative;
|
|
12
|
+
display: flex;
|
|
13
|
+
align-items: center;
|
|
14
|
+
padding: 0 20px;
|
|
15
|
+
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.1);
|
|
16
|
+
z-index: 10;
|
|
6
17
|
|
|
7
18
|
.logo {
|
|
8
|
-
float: left;
|
|
9
19
|
width: 120px;
|
|
10
20
|
height: 31px;
|
|
11
|
-
|
|
21
|
+
margin-right: 24px;
|
|
22
|
+
display: flex;
|
|
23
|
+
align-items: center;
|
|
12
24
|
}
|
|
13
25
|
|
|
14
|
-
.
|
|
15
|
-
|
|
26
|
+
.main-menu {
|
|
27
|
+
flex: 1;
|
|
16
28
|
}
|
|
17
29
|
|
|
18
|
-
.user {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
30
|
+
.user-actions {
|
|
31
|
+
display: flex;
|
|
32
|
+
align-items: center;
|
|
33
|
+
margin-left: auto;
|
|
34
|
+
height: 100%;
|
|
35
|
+
|
|
36
|
+
.ant-space {
|
|
37
|
+
display: flex;
|
|
38
|
+
align-items: center;
|
|
39
|
+
height: 100%;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.action-icon {
|
|
43
|
+
color: rgba(255, 255, 255, 0.85);
|
|
44
|
+
font-size: 20px;
|
|
45
|
+
cursor: pointer;
|
|
46
|
+
transition: color 0.3s;
|
|
47
|
+
display: flex;
|
|
48
|
+
align-items: center;
|
|
49
|
+
justify-content: center;
|
|
50
|
+
height: 32px;
|
|
51
|
+
width: 32px;
|
|
52
|
+
|
|
53
|
+
&:hover {
|
|
54
|
+
color: #fff;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
.user-dropdown {
|
|
59
|
+
cursor: pointer;
|
|
60
|
+
padding: 0 8px;
|
|
61
|
+
display: flex;
|
|
62
|
+
align-items: center;
|
|
63
|
+
|
|
64
|
+
.username {
|
|
65
|
+
color: rgba(255, 255, 255, 0.85);
|
|
66
|
+
margin-left: 8px;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
.sidebar {
|
|
73
|
+
box-shadow: 2px 0 8px 0 rgba(29, 35, 41, 0.05);
|
|
74
|
+
background: #f5f7fa;
|
|
75
|
+
border-right: 1px solid #ebeef5;
|
|
76
|
+
|
|
77
|
+
.side-menu {
|
|
78
|
+
border-right: none;
|
|
79
|
+
background: #f5f7fa;
|
|
80
|
+
|
|
81
|
+
.ant-menu-item {
|
|
82
|
+
margin: 0;
|
|
83
|
+
border-radius: 0;
|
|
84
|
+
|
|
85
|
+
&:hover {
|
|
86
|
+
background-color: #e6f7ff;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
&.ant-menu-item-selected {
|
|
90
|
+
background-color: #e6f7ff;
|
|
91
|
+
border-right: 3px solid #1890ff;
|
|
92
|
+
font-weight: 500;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
.ant-menu-submenu-title {
|
|
97
|
+
&:hover {
|
|
98
|
+
background-color: #e6f7ff;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
.ant-menu-submenu-selected > .ant-menu-submenu-title {
|
|
103
|
+
color: #1890ff;
|
|
104
|
+
font-weight: 500;
|
|
105
|
+
}
|
|
23
106
|
}
|
|
24
107
|
}
|
|
25
108
|
|
|
109
|
+
.content-layout {
|
|
110
|
+
padding: 0 24px 24px;
|
|
111
|
+
display: flex;
|
|
112
|
+
flex-direction: column;
|
|
113
|
+
flex: 1;
|
|
114
|
+
height: 100%;
|
|
115
|
+
|
|
116
|
+
.breadcrumb-container {
|
|
117
|
+
margin: 16px 0;
|
|
118
|
+
font-size: 14px;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
.content-container {
|
|
122
|
+
padding: 24px;
|
|
123
|
+
margin: 0;
|
|
124
|
+
flex: 1;
|
|
125
|
+
min-height: 280px;
|
|
126
|
+
background: #fff;
|
|
127
|
+
border-radius: 4px;
|
|
128
|
+
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.05);
|
|
129
|
+
display: flex;
|
|
130
|
+
flex-direction: column;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
.site-layout-background {
|
|
135
|
+
background: #fff;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
.ant-layout-sider-trigger {
|
|
139
|
+
background: #e6f7ff;
|
|
140
|
+
color: #1890ff;
|
|
141
|
+
border-top: 1px solid #ebeef5;
|
|
142
|
+
border-right: 1px solid #ebeef5;
|
|
143
|
+
|
|
144
|
+
&:hover {
|
|
145
|
+
background: #bae7ff;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
26
148
|
`
|
|
@@ -2,15 +2,76 @@ import styled from 'styled-components'
|
|
|
2
2
|
|
|
3
3
|
export const Container = styled.div`
|
|
4
4
|
margin: 20px;
|
|
5
|
+
|
|
6
|
+
.ant-table {
|
|
7
|
+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
|
|
8
|
+
border-radius: 8px;
|
|
9
|
+
overflow: hidden;
|
|
10
|
+
transition: all 0.3s ease;
|
|
11
|
+
|
|
12
|
+
&:hover {
|
|
13
|
+
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.12);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.table-row-light {
|
|
18
|
+
background-color: #ffffff;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.table-row-dark {
|
|
22
|
+
background-color: #f9f9f9;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.ant-table-thead > tr > th {
|
|
26
|
+
background-color: #f0f5ff;
|
|
27
|
+
color: #1890ff;
|
|
28
|
+
font-weight: 500;
|
|
29
|
+
padding: 12px 16px;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.ant-table-tbody > tr > td {
|
|
33
|
+
padding: 12px 16px;
|
|
34
|
+
transition: background-color 0.3s;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.page-title {
|
|
38
|
+
font-size: 24px;
|
|
39
|
+
font-weight: 500;
|
|
40
|
+
color: #1890ff;
|
|
41
|
+
margin-bottom: 20px;
|
|
42
|
+
padding-bottom: 10px;
|
|
43
|
+
border-bottom: 1px solid #f0f0f0;
|
|
44
|
+
position: relative;
|
|
45
|
+
|
|
46
|
+
&:after {
|
|
47
|
+
content: '';
|
|
48
|
+
position: absolute;
|
|
49
|
+
bottom: -1px;
|
|
50
|
+
left: 0;
|
|
51
|
+
width: 100px;
|
|
52
|
+
height: 3px;
|
|
53
|
+
background: linear-gradient(90deg, #1890ff, #69c0ff);
|
|
54
|
+
border-radius: 3px;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
5
57
|
`
|
|
6
58
|
|
|
7
59
|
export const SearchRow = styled.div`
|
|
8
|
-
margin: 10px;
|
|
60
|
+
margin: 10px 0 20px 0;
|
|
61
|
+
padding: 16px 20px;
|
|
9
62
|
display: flex;
|
|
10
63
|
flex: 1;
|
|
11
64
|
flex-direction: row;
|
|
12
65
|
justify-content: space-between;
|
|
13
66
|
align-items: center;
|
|
67
|
+
background-color: #fff;
|
|
68
|
+
border-radius: 8px;
|
|
69
|
+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
|
|
70
|
+
transition: all 0.3s ease;
|
|
71
|
+
|
|
72
|
+
&:hover {
|
|
73
|
+
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.12);
|
|
74
|
+
}
|
|
14
75
|
`
|
|
15
76
|
|
|
16
77
|
export const ModalContainer = styled.div`
|
|
@@ -21,6 +82,7 @@ export const ModalContainer = styled.div`
|
|
|
21
82
|
justify-content: flex-start;
|
|
22
83
|
align-items: flex-start;
|
|
23
84
|
height: 50px;
|
|
85
|
+
margin-bottom: 16px;
|
|
24
86
|
|
|
25
87
|
label {
|
|
26
88
|
display: flex;
|
|
@@ -29,11 +91,33 @@ export const ModalContainer = styled.div`
|
|
|
29
91
|
align-items: flex-start;
|
|
30
92
|
width: 80px;
|
|
31
93
|
height: 32px;
|
|
32
|
-
margin-right:
|
|
94
|
+
margin-right: 16px;
|
|
95
|
+
font-weight: 500;
|
|
96
|
+
color: #333;
|
|
97
|
+
position: relative;
|
|
98
|
+
|
|
99
|
+
&:after {
|
|
100
|
+
content: '';
|
|
101
|
+
position: absolute;
|
|
102
|
+
left: -8px;
|
|
103
|
+
top: 50%;
|
|
104
|
+
transform: translateY(-50%);
|
|
105
|
+
width: 3px;
|
|
106
|
+
height: 16px;
|
|
107
|
+
background: #1890ff;
|
|
108
|
+
border-radius: 3px;
|
|
109
|
+
}
|
|
33
110
|
}
|
|
34
111
|
|
|
35
112
|
input {
|
|
36
113
|
flex: 1;
|
|
114
|
+
border-radius: 6px;
|
|
115
|
+
transition: all 0.3s ease;
|
|
116
|
+
|
|
117
|
+
&:hover, &:focus {
|
|
118
|
+
border-color: #40a9ff;
|
|
119
|
+
box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2);
|
|
120
|
+
}
|
|
37
121
|
}
|
|
38
122
|
|
|
39
123
|
.row {
|