nsgm-cli 2.1.5 → 2.1.7

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 CHANGED
@@ -4,8 +4,6 @@
4
4
  - 数据库采用 Mysql, 配置见 mysql.config.js
5
5
  - 项目配置见 project.config.js
6
6
  - Next 框架配置见 next.config.js
7
- - [ERISHEN](https://www.erishen.cn/)
8
- - [Demo](https://nsgm.erishen.cn:8443/)
9
7
 
10
8
  ## 命令
11
9
  - nsgm init 初始化项目
@@ -1,11 +1,13 @@
1
1
  import React, { useEffect, useState } from 'react'
2
- import { Layout, Menu, Breadcrumb, Image, Select } from 'antd'
3
- import { Container } from '../styled/layout'
2
+ import { Layout, Menu, Breadcrumb, Image, Select, Dropdown, Space, Tooltip } from 'antd'
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
- import menuConfig from '../utils/menu'
7
- import { logout } from '../utils/sso'
7
+ import menuConfig from '@/utils/menu'
8
+ import { logout } from '@/utils/sso'
8
9
  import getConfig from 'next/config'
10
+ import { LogoutOutlined, SettingOutlined, BellOutlined, UserOutlined } from '@ant-design/icons'
9
11
 
10
12
  const { Option } = Select
11
13
  const { SubMenu } = Menu
@@ -15,6 +17,90 @@ 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
+ box-shadow: 2px 0 8px -4px rgba(0, 0, 0, 0.1);
29
+ z-index: 5;
30
+ position: relative;
31
+ `
32
+
33
+ const SideMenu = styled(Menu)`
34
+ height: 100%;
35
+ border-right: 0;
36
+ padding: 8px 0;
37
+ `
38
+
39
+ const ContentLayout = styled(Layout)`
40
+ display: flex;
41
+ flex-direction: column;
42
+ flex: 1;
43
+ background: #f5f7fa;
44
+ position: relative;
45
+ z-index: 1;
46
+ `
47
+ const StyledHeader = styled(Header)`
48
+ display: flex;
49
+ align-items: center;
50
+ padding: 0 24px;
51
+ box-shadow: 0 1px 4px rgba(0, 0, 0, 0.12);
52
+ z-index: 11;
53
+
54
+ .logo {
55
+ margin-right: 24px;
56
+ }
57
+
58
+ .main-menu {
59
+ flex: 1;
60
+ }
61
+
62
+ .user-actions {
63
+ display: flex;
64
+ align-items: center;
65
+
66
+ .action-icon {
67
+ font-size: 18px;
68
+ color: rgba(255, 255, 255, 0.85);
69
+ cursor: pointer;
70
+ padding: 0 8px;
71
+ transition: color 0.3s;
72
+
73
+ &:hover {
74
+ color: #fff;
75
+ }
76
+ }
77
+
78
+ .user-dropdown {
79
+ cursor: pointer;
80
+ padding: 0 8px;
81
+
82
+ .username {
83
+ color: rgba(255, 255, 255, 0.85);
84
+ margin-left: 8px;
85
+ }
86
+ }
87
+ }
88
+ `
89
+ const StyledBreadcrumb = styled(Breadcrumb)`
90
+ margin: 16px 24px;
91
+ font-size: 14px;
92
+ `
93
+ const StyledContent = styled(Content)`
94
+ margin: 0 24px 24px;
95
+ padding: 24px;
96
+ background: #fff;
97
+ border-radius: 4px;
98
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
99
+ min-height: calc(100vh - 180px);
100
+ position: relative;
101
+ z-index: 1;
102
+ `
103
+
18
104
  const getLocationKey = () => {
19
105
  let result = {
20
106
  topMenu: '1',
@@ -85,6 +171,7 @@ const LayoutComponent = ({ user, children }) => {
85
171
  const router = useRouter()
86
172
  const [topMenuKey, setTopMenuKey] = useState('1')
87
173
  const [sliderMenuKey, setSliderMenuKey] = useState('1')
174
+ const [collapsed, setCollapsed] = useState(false)
88
175
 
89
176
  // console.log('topMenuKey: ' + topMenuKey, ', sliderMenuKey: ' + sliderMenuKey, user)
90
177
 
@@ -175,47 +262,92 @@ const LayoutComponent = ({ user, children }) => {
175
262
  })
176
263
 
177
264
  return (
178
- <Layout>
265
+ <Layout className="main-layout">
179
266
  <Container>
180
- <Header className="header">
267
+ <StyledHeader>
181
268
  <div className="logo">
182
- <Image width={100} src={prefix + "/images/zhizuotu_1.png"} preview={false} />
269
+ <Image width={120} src={prefix + "/images/zhizuotu_1.png"} preview={false} />
183
270
  </div>
184
- <Menu theme="dark" mode="horizontal" defaultSelectedKeys={['1']} selectedKeys={[topMenuKey]} items={menuItems} />
185
- <div className="user">
186
- <Select value={user?.displayName} onChange={() => { logout() }}>
187
- <Option value=''>{'退出'}</Option>
188
- </Select>
271
+ <Menu
272
+ theme="dark"
273
+ mode="horizontal"
274
+ defaultSelectedKeys={['1']}
275
+ selectedKeys={[topMenuKey]}
276
+ items={menuItems}
277
+ className="main-menu"
278
+ />
279
+ <div className="user-actions">
280
+ <Space size={20} align="center">
281
+ <Tooltip title="通知">
282
+ <BellOutlined className="action-icon" />
283
+ </Tooltip>
284
+ <Tooltip title="设置">
285
+ <SettingOutlined className="action-icon" />
286
+ </Tooltip>
287
+ <Dropdown
288
+ menu={{
289
+ items: [
290
+ {
291
+ key: '1',
292
+ icon: <UserOutlined />,
293
+ label: '个人中心',
294
+ },
295
+ {
296
+ key: '2',
297
+ icon: <SettingOutlined />,
298
+ label: '账户设置',
299
+ },
300
+ {
301
+ type: 'divider',
302
+ },
303
+ {
304
+ key: '3',
305
+ icon: <LogoutOutlined />,
306
+ label: '退出登录',
307
+ onClick: () => logout(),
308
+ },
309
+ ],
310
+ }}
311
+ >
312
+ <Space className="user-dropdown">
313
+ <span className="username">{user?.displayName || '用户'}</span>
314
+ </Space>
315
+ </Dropdown>
316
+ </Space>
189
317
  </div>
190
- </Header>
191
- <Layout>
192
- <Sider width={200} className="site-layout-background">
193
- <Menu
194
- mode="inline"
195
- defaultSelectedKeys={['slider_1_0']}
196
- defaultOpenKeys={['slider_1']}
197
- selectedKeys={['slider_' + topMenuKey + '_' + sliderMenuKey]}
198
- openKeys={['slider_' + topMenuKey]}
199
- style={{ height: '100%', borderRight: 0 }}
200
- items={menuItemsVertical}
201
- />
202
- </Sider>
203
- <Layout style={{ padding: '0 24px 24px' }}>
204
- <Breadcrumb style={{ margin: '16px 0' }}>
318
+ </StyledHeader>
319
+ <FlexLayout>
320
+ <StyledSider
321
+ width={220}
322
+ className="site-layout-background sidebar"
323
+ collapsible
324
+ collapsed={collapsed}
325
+ onCollapse={(value) => setCollapsed(value)}
326
+ >
327
+ <div>
328
+ <SideMenu
329
+ mode="inline"
330
+ defaultSelectedKeys={['slider_1_0']}
331
+ defaultOpenKeys={['slider_1']}
332
+ selectedKeys={['slider_' + topMenuKey + '_' + sliderMenuKey]}
333
+ openKeys={['slider_' + topMenuKey]}
334
+ items={menuItemsVertical}
335
+ className="side-menu"
336
+ />
337
+ </div>
338
+ </StyledSider>
339
+ <ContentLayout className="content-layout">
340
+ <StyledBreadcrumb>
205
341
  {_.map(menuConfig, (item, index) => {
206
342
  const { key, text, subMenus } = item
207
343
 
208
344
  if (subMenus) {
209
- // console.log('subMenus', subMenus)
210
-
211
345
  let subContent: any = []
212
346
  _.each(subMenus, (subItem, subIndex) => {
213
347
  const { key: subKey, text: subText } = subItem
214
- // console.log('subKey', subKey, key, topMenuKey, sliderMenuKey)
215
-
216
348
  if (subKey === topMenuKey + '_' + sliderMenuKey) {
217
349
  subContent.push(<Breadcrumb.Item key={'breadcrumb' + subIndex}>{text}</Breadcrumb.Item>)
218
- subContent.push(<Breadcrumb.Item key={'breadcrumb' + subIndex}>{subText}</Breadcrumb.Item>)
350
+ subContent.push(<Breadcrumb.Item key={'breadcrumb' + subIndex + '_sub'}>{subText}</Breadcrumb.Item>)
219
351
  return false
220
352
  }
221
353
  })
@@ -226,19 +358,12 @@ const LayoutComponent = ({ user, children }) => {
226
358
  }
227
359
  }
228
360
  })}
229
- </Breadcrumb>
230
- <Content
231
- className="site-layout-background"
232
- style={{
233
- padding: 24,
234
- margin: 0,
235
- minHeight: 280
236
- }}
237
- >
361
+ </StyledBreadcrumb>
362
+ <StyledContent>
238
363
  {children}
239
- </Content>
240
- </Layout>
241
- </Layout>
364
+ </StyledContent>
365
+ </ContentLayout>
366
+ </FlexLayout>
242
367
  </Container>
243
368
  </Layout>
244
369
  )
@@ -1,5 +1,5 @@
1
1
  import * as types from './types'
2
- import { getTemplateService, addTemplateService, updateTemplateService, deleteTemplateService, searchTemplateService, batchDeleteTemplateService } from '../../../service/template/manage'
2
+ import { getTemplateService, addTemplateService, updateTemplateService, deleteTemplateService, searchTemplateService, batchDeleteTemplateService } from '@/service/template/manage'
3
3
 
4
4
  export const getTemplate = (page=0, pageSize=10) => (
5
5
  dispatch: (arg0: {
@@ -1,7 +1,7 @@
1
- import { getLocalGraphql } from '../../utils/fetch'
1
+ import { getLocalGraphql } from '@/utils/fetch'
2
2
  import _ from 'lodash'
3
3
 
4
- export const getTemplateService = (page=0, pageSize=10) => {
4
+ export const getTemplateService = (page = 0, pageSize = 10) => {
5
5
  const getTemplateQuery = `query ($page: Int, $pageSize: Int) { template(page: $page, pageSize: $pageSize) {
6
6
  totalCounts items {
7
7
  id name
@@ -9,10 +9,10 @@ export const getTemplateService = (page=0, pageSize=10) => {
9
9
  }
10
10
  }`
11
11
 
12
- return getLocalGraphql(getTemplateQuery, {
13
- page,
14
- pageSize
15
- })
12
+ return getLocalGraphql(getTemplateQuery, {
13
+ page,
14
+ pageSize
15
+ })
16
16
  }
17
17
 
18
18
  export const searchTemplateByIdService = (id: number) => {
@@ -39,7 +39,7 @@ export const searchTemplateService = (page = 0, pageSize = 10, data: any) => {
39
39
  }`
40
40
 
41
41
  return getLocalGraphql(searchTemplateQuery, {
42
- page,
42
+ page,
43
43
  pageSize,
44
44
  data: {
45
45
  name
@@ -47,7 +47,7 @@ export const searchTemplateService = (page = 0, pageSize = 10, data: any) => {
47
47
  })
48
48
  }
49
49
 
50
- export const addTemplateService = (data: any) => {
50
+ export const addTemplateService = (data: any) => {
51
51
  const { name } = data
52
52
 
53
53
  const addTemplateQuery = `mutation ($data: TemplateAddInput) { templateAdd(data: $data) }`
@@ -59,7 +59,7 @@ export const addTemplateService = (data: any) => {
59
59
  })
60
60
  }
61
61
 
62
- export const updateTemplateService = (id: number, data: any) => {
62
+ export const updateTemplateService = (id: number, data: any) => {
63
63
  const { name } = data
64
64
 
65
65
  const updateTemplateQuery = `mutation ($id: Int, $data: TemplateAddInput) { templateUpdate(id: $id, data: $data) }`
@@ -72,7 +72,7 @@ export const updateTemplateService = (id: number, data: any) => {
72
72
  })
73
73
  }
74
74
 
75
- export const deleteTemplateService = (id: number) => {
75
+ export const deleteTemplateService = (id: number) => {
76
76
  const deleteTemplateQuery = `mutation ($id: Int) { templateDelete(id: $id) }`
77
77
 
78
78
  return getLocalGraphql(deleteTemplateQuery, {
@@ -88,7 +88,7 @@ export const batchAddTemplateService = (datas: any) => {
88
88
  })
89
89
  }
90
90
 
91
- export const batchDeleteTemplateService = (ids: any) => {
91
+ export const batchDeleteTemplateService = (ids: any) => {
92
92
  const batchDeleteTemplateQuery = `mutation ($ids: [Int]) { templateBatchDelete(ids: $ids) }`
93
93
 
94
94
  return getLocalGraphql(batchDeleteTemplateQuery, {
@@ -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: 200px;
23
- width: 250px;
22
+ margin-top: 100px;
23
+ width: 350px;
24
24
  display: flex;
25
25
  flex-direction: column;
26
26
  justify-content: center;
27
- align-items: flex-start;
28
- border: 1px solid gray;
29
- border-radius: 5px;
30
- padding: 20px;
31
-
32
- .row {
33
- width: 100%;
34
- display: flex;
35
- flex: 1;
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
- .right {
47
- margin-top: 10px;
48
- justify-content: flex-end;
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
- // margin: 16px 24px 16px 0;
21
+ margin-right: 24px;
22
+ display: flex;
23
+ align-items: center;
12
24
  }
13
25
 
14
- .site-layout-background {
15
- background: #fff;
26
+ .main-menu {
27
+ flex: 1;
16
28
  }
17
29
 
18
- .user {
19
- position: absolute;
20
- right: 10px;
21
- top: 0;
22
- color: white;
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: 5px;
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 {