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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nsgm-cli",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.6",
|
|
4
4
|
"description": "A CLI tool to run Next/Style-components and Graphql/Mysql fullstack project",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -96,8 +96,8 @@
|
|
|
96
96
|
"mysql2": "3.14.2",
|
|
97
97
|
"next": "15.4.4",
|
|
98
98
|
"rc-util": "5.44.4",
|
|
99
|
-
"react": "
|
|
100
|
-
"react-dom": "
|
|
99
|
+
"react": "18.3.1",
|
|
100
|
+
"react-dom": "18.3.1",
|
|
101
101
|
"react-redux": "9.2.0",
|
|
102
102
|
"redux": "5.0.1",
|
|
103
103
|
"replace": "1.2.2",
|
|
@@ -128,8 +128,8 @@
|
|
|
128
128
|
"@types/mysql": "2.15.27",
|
|
129
129
|
"@types/next": "9.0.0",
|
|
130
130
|
"@types/node": "^24",
|
|
131
|
-
"@types/react": "
|
|
132
|
-
"@types/react-dom": "
|
|
131
|
+
"@types/react": "18.3.23",
|
|
132
|
+
"@types/react-dom": "18.3.7",
|
|
133
133
|
"@types/react-redux": "7.1.34",
|
|
134
134
|
"@types/shelljs": "0.8.17",
|
|
135
135
|
"@types/styled-components": "5.1.34",
|
package/pages/index.tsx
CHANGED
|
@@ -3,6 +3,10 @@ import _ from 'lodash'
|
|
|
3
3
|
import { Container } from '../client/styled/common'
|
|
4
4
|
import getConfig from 'next/config'
|
|
5
5
|
import React from 'react'
|
|
6
|
+
import { Card, Typography, Divider, Row, Col, Tag } from 'antd'
|
|
7
|
+
import { CodeOutlined, BookOutlined, DatabaseOutlined, SettingOutlined } from '@ant-design/icons'
|
|
8
|
+
|
|
9
|
+
const { Title, Paragraph, Text } = Typography
|
|
6
10
|
|
|
7
11
|
const md = new MarkdownIt({
|
|
8
12
|
html: true,
|
|
@@ -14,56 +18,96 @@ const nextConfig = getConfig()
|
|
|
14
18
|
const { publicRuntimeConfig } = nextConfig
|
|
15
19
|
const { env } = publicRuntimeConfig
|
|
16
20
|
|
|
17
|
-
const renderArr: any = []
|
|
18
|
-
|
|
19
|
-
renderArr.push('# NSGM CLI ' + env)
|
|
20
|
-
renderArr.push('- 技术栈: [Next](https://github.com/vercel/next.js), [Styled-components](https://github.com/styled-components/styled-components), [Graphql](https://graphql.org/), [Mysql](https://www.mysql.com/)')
|
|
21
|
-
renderArr.push('- 全栈架构,代码模板生成,快速开发')
|
|
22
|
-
renderArr.push('- 数据库采用 Mysql, 配置见 mysql.config.js')
|
|
23
|
-
renderArr.push('- 项目配置见 project.config.js')
|
|
24
|
-
renderArr.push('- Next 框架配置见 next.config.js')
|
|
25
|
-
|
|
26
|
-
renderArr.push('## 命令')
|
|
27
|
-
renderArr.push('- nsgm init 初始化项目')
|
|
28
|
-
renderArr.push('- nsgm upgrade 升级项目基础文件')
|
|
29
|
-
renderArr.push('- nsgm create 创建模板页面')
|
|
30
|
-
renderArr.push('- nsgm delete 删除模板页面')
|
|
31
|
-
renderArr.push('- nsgm deletedb 删除模板页面及数据库表')
|
|
32
|
-
renderArr.push('- nsgm dev 开发模式')
|
|
33
|
-
renderArr.push('- nsgm start 生产模式')
|
|
34
|
-
renderArr.push('- nsgm build 编译')
|
|
35
|
-
renderArr.push('- nsgm export 导出静态页面')
|
|
36
21
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
22
|
+
const Page = ({ html }) => {
|
|
23
|
+
return (
|
|
24
|
+
<Container>
|
|
25
|
+
<Typography style={{ padding: '24px' }}>
|
|
26
|
+
<Title level={1}>NSGM CLI</Title>
|
|
27
|
+
<Paragraph>
|
|
28
|
+
<Row gutter={[16, 16]}>
|
|
29
|
+
<Col><Tag color="blue">Next</Tag></Col>
|
|
30
|
+
<Col><Tag color="purple">Styled-components</Tag></Col>
|
|
31
|
+
<Col><Tag color="magenta">Graphql</Tag></Col>
|
|
32
|
+
<Col><Tag color="green">Mysql</Tag></Col>
|
|
33
|
+
</Row>
|
|
34
|
+
</Paragraph>
|
|
35
|
+
<Paragraph>
|
|
36
|
+
全栈架构,代码模板生成,快速开发
|
|
37
|
+
</Paragraph>
|
|
41
38
|
|
|
39
|
+
<Card style={{ marginBottom: '24px' }}>
|
|
40
|
+
<Row gutter={[24, 16]}>
|
|
41
|
+
<Col xs={24} md={8}>
|
|
42
|
+
<Card type="inner" title={<><DatabaseOutlined /> 数据库配置</>}>
|
|
43
|
+
数据库采用 Mysql, 配置见 mysql.config.js
|
|
44
|
+
</Card>
|
|
45
|
+
</Col>
|
|
46
|
+
<Col xs={24} md={8}>
|
|
47
|
+
<Card type="inner" title={<><SettingOutlined /> 项目配置</>}>
|
|
48
|
+
项目配置见 project.config.js
|
|
49
|
+
</Card>
|
|
50
|
+
</Col>
|
|
51
|
+
<Col xs={24} md={8}>
|
|
52
|
+
<Card type="inner" title={<><CodeOutlined /> 框架配置</>}>
|
|
53
|
+
Next 框架配置见 next.config.js
|
|
54
|
+
</Card>
|
|
55
|
+
</Col>
|
|
56
|
+
</Row>
|
|
57
|
+
</Card>
|
|
42
58
|
|
|
43
|
-
|
|
59
|
+
<Title level={2}><BookOutlined /> 命令</Title>
|
|
60
|
+
<Divider />
|
|
44
61
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
62
|
+
<Row gutter={[16, 16]}>
|
|
63
|
+
<Col xs={24} md={8}>
|
|
64
|
+
<Card hoverable>
|
|
65
|
+
<Title level={4}>项目管理</Title>
|
|
66
|
+
<ul>
|
|
67
|
+
<li><Text strong>nsgm init</Text> - 初始化项目</li>
|
|
68
|
+
<li><Text strong>nsgm upgrade</Text> - 升级项目基础文件</li>
|
|
69
|
+
</ul>
|
|
70
|
+
</Card>
|
|
71
|
+
</Col>
|
|
72
|
+
<Col xs={24} md={8}>
|
|
73
|
+
<Card hoverable>
|
|
74
|
+
<Title level={4}>模板操作</Title>
|
|
75
|
+
<ul>
|
|
76
|
+
<li><Text strong>nsgm create</Text> - 创建模板页面</li>
|
|
77
|
+
<li><Text strong>nsgm delete</Text> - 删除模板页面</li>
|
|
78
|
+
<li><Text strong>nsgm deletedb</Text> - 删除模板页面及数据库表</li>
|
|
79
|
+
</ul>
|
|
80
|
+
</Card>
|
|
81
|
+
</Col>
|
|
82
|
+
<Col xs={24} md={8}>
|
|
83
|
+
<Card hoverable>
|
|
84
|
+
<Title level={4}>运行与构建</Title>
|
|
85
|
+
<ul>
|
|
86
|
+
<li><Text strong>nsgm dev</Text> - 开发模式</li>
|
|
87
|
+
<li><Text strong>nsgm start</Text> - 生产模式</li>
|
|
88
|
+
<li><Text strong>nsgm build</Text> - 编译</li>
|
|
89
|
+
<li><Text strong>nsgm export</Text> - 导出静态页面</li>
|
|
90
|
+
</ul>
|
|
91
|
+
</Card>
|
|
92
|
+
</Col>
|
|
93
|
+
</Row>
|
|
50
94
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
95
|
+
<Title level={2} style={{ marginTop: '24px' }}>参数</Title>
|
|
96
|
+
<Divider />
|
|
97
|
+
<Card>
|
|
98
|
+
<ul>
|
|
99
|
+
<li><Text strong>dictionary:</Text> 在 export/init 的时候使用, 默认 webapp, 譬如: nsgm export/init dictionary=webapp 或者 nsgm export/init webapp</li>
|
|
100
|
+
<li><Text strong>controller:</Text> 在 create/delete 的时候使用, 必须有。譬如:nsgm create/delete math</li>
|
|
101
|
+
<li><Text strong>action:</Text> 在 create/delete 的时候使用, 默认 manage, 跟在 controller 后面, 譬如 nsgm create/delete math test</li>
|
|
102
|
+
</ul>
|
|
103
|
+
</Card>
|
|
104
|
+
</Typography>
|
|
54
105
|
</Container>
|
|
55
106
|
)
|
|
56
107
|
}
|
|
57
108
|
|
|
58
109
|
Page.getInitialProps = () => {
|
|
59
|
-
|
|
60
|
-
_.each(renderArr, (item, index) => {
|
|
61
|
-
html += md.render(item)
|
|
62
|
-
})
|
|
63
|
-
|
|
64
|
-
return {
|
|
65
|
-
html
|
|
66
|
-
}
|
|
110
|
+
return {}
|
|
67
111
|
}
|
|
68
112
|
|
|
69
113
|
export default Page
|
package/pages/login.tsx
CHANGED
|
@@ -4,6 +4,8 @@ import { LoginContainer } from '../client/styled/common'
|
|
|
4
4
|
// import getConfig from 'next/config'
|
|
5
5
|
import React, { useState } from 'react'
|
|
6
6
|
import { handleXSS } from '../client/utils/common'
|
|
7
|
+
import { Input, Button, Form, Typography, message } from 'antd'
|
|
8
|
+
import { UserOutlined, LockOutlined } from '@ant-design/icons'
|
|
7
9
|
|
|
8
10
|
const md = new MarkdownIt({
|
|
9
11
|
html: true,
|
|
@@ -31,11 +33,18 @@ const Page = ({ html }) => {
|
|
|
31
33
|
|
|
32
34
|
const doLogin = () => {
|
|
33
35
|
if (typeof window !== "undefined") {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
36
|
+
if (userName === '') {
|
|
37
|
+
message.error('请输入用户名');
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
if (userPassword === '') {
|
|
41
|
+
message.error('请输入密码');
|
|
42
|
+
return;
|
|
38
43
|
}
|
|
44
|
+
|
|
45
|
+
let locationHref = window.location.origin + "?ticket=XXX"
|
|
46
|
+
locationHref += "&name=" + btoa(handleXSS(userName + "," + userPassword))
|
|
47
|
+
window.location.href = locationHref
|
|
39
48
|
}
|
|
40
49
|
}
|
|
41
50
|
|
|
@@ -50,17 +59,34 @@ const Page = ({ html }) => {
|
|
|
50
59
|
return (
|
|
51
60
|
<LoginContainer>
|
|
52
61
|
<div dangerouslySetInnerHTML={createMarkup()} />
|
|
53
|
-
<
|
|
54
|
-
<
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
62
|
+
<Typography.Title level={3} style={{ textAlign: 'center', marginBottom: 24 }}>系统登录</Typography.Title>
|
|
63
|
+
<Form layout="vertical" style={{ width: '100%' }}>
|
|
64
|
+
<Form.Item>
|
|
65
|
+
<Input
|
|
66
|
+
prefix={<UserOutlined style={{ color: 'rgba(0,0,0,.25)' }} />}
|
|
67
|
+
placeholder="用户名"
|
|
68
|
+
size="large"
|
|
69
|
+
value={userName}
|
|
70
|
+
onChange={doChangeName}
|
|
71
|
+
autoComplete="off"
|
|
72
|
+
/>
|
|
73
|
+
</Form.Item>
|
|
74
|
+
<Form.Item>
|
|
75
|
+
<Input.Password
|
|
76
|
+
prefix={<LockOutlined style={{ color: 'rgba(0,0,0,.25)' }} />}
|
|
77
|
+
placeholder="密码"
|
|
78
|
+
size="large"
|
|
79
|
+
value={userPassword}
|
|
80
|
+
onChange={doChangePassword}
|
|
81
|
+
autoComplete="off"
|
|
82
|
+
/>
|
|
83
|
+
</Form.Item>
|
|
84
|
+
<Form.Item>
|
|
85
|
+
<Button type="primary" onClick={doLogin} size="large" block>
|
|
86
|
+
登录
|
|
87
|
+
</Button>
|
|
88
|
+
</Form.Item>
|
|
89
|
+
</Form>
|
|
64
90
|
</LoginContainer>
|
|
65
91
|
)
|
|
66
92
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import React, { useEffect, useState } from 'react'
|
|
2
2
|
import { ConfigProvider, Table, Modal, Button, Input, Space, Upload, message } from 'antd'
|
|
3
3
|
import { Container, SearchRow, ModalContainer } from '../../client/styled/template/manage'
|
|
4
|
+
import styled from 'styled-components'
|
|
4
5
|
import { useDispatch, useSelector } from 'react-redux'
|
|
5
6
|
import { getTemplate, addTemplate, modTemplate, delTemplate, updateSSRTemplate, searchTemplate, batchDelTemplate } from '../../client/redux/template/manage/actions'
|
|
6
7
|
import { getTemplateService } from '../../client/service/template/manage'
|
|
@@ -16,12 +17,56 @@ import { saveAs } from 'file-saver'
|
|
|
16
17
|
const pageSize = 100
|
|
17
18
|
const dateFormat = 'YYYY-MM-DD'
|
|
18
19
|
const currentDate = dayjs().format(dateFormat)
|
|
19
|
-
console.log('currentDate', currentDate)
|
|
20
20
|
|
|
21
21
|
const keyTitles = {
|
|
22
22
|
name: '名称'
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
+
// styled-components
|
|
26
|
+
const StyledButton = styled(Button) <{ $primary?: boolean; $export?: boolean; $import?: boolean; $danger?: boolean }>`
|
|
27
|
+
display: flex;
|
|
28
|
+
align-items: center;
|
|
29
|
+
border-radius: 6px;
|
|
30
|
+
box-shadow: 0 2px 0 rgba(0, 0, 0, 0.045);
|
|
31
|
+
${props => props.$export && `
|
|
32
|
+
background-color: #f6ffed;
|
|
33
|
+
color: #52c41a;
|
|
34
|
+
border-color: #b7eb8f;
|
|
35
|
+
box-shadow: 0 2px 0 rgba(0, 0, 0, 0.015);
|
|
36
|
+
transition: all 0.3s ease;
|
|
37
|
+
`}
|
|
38
|
+
${props => props.$import && `
|
|
39
|
+
background-color: #e6f7ff;
|
|
40
|
+
color: #1890ff;
|
|
41
|
+
border-color: #91d5ff;
|
|
42
|
+
box-shadow: 0 2px 0 rgba(0, 0, 0, 0.015);
|
|
43
|
+
transition: all 0.3s ease;
|
|
44
|
+
`}
|
|
45
|
+
${props => props.$danger && `
|
|
46
|
+
background-color: #fff1f0;
|
|
47
|
+
border-color: #ffa39e;
|
|
48
|
+
box-shadow: 0 2px 0 rgba(0, 0, 0, 0.015);
|
|
49
|
+
transition: all 0.3s ease;
|
|
50
|
+
`}
|
|
51
|
+
`
|
|
52
|
+
const StyledInput = styled(Input)`
|
|
53
|
+
width: 200px;
|
|
54
|
+
border-radius: 6px;
|
|
55
|
+
box-shadow: 0 2px 0 rgba(0, 0, 0, 0.015);
|
|
56
|
+
`
|
|
57
|
+
const StyledTable = styled(Table)`
|
|
58
|
+
margin-top: 16px;
|
|
59
|
+
border-radius: 8px;
|
|
60
|
+
overflow: hidden;
|
|
61
|
+
`
|
|
62
|
+
const ModalTitle = styled.div`
|
|
63
|
+
color: #1890ff;
|
|
64
|
+
font-weight: 500;
|
|
65
|
+
`
|
|
66
|
+
const ModalInput = styled(Input)`
|
|
67
|
+
border-radius: 4px;
|
|
68
|
+
`
|
|
69
|
+
|
|
25
70
|
const Page = ({ template }) => {
|
|
26
71
|
const dispatch = useDispatch()
|
|
27
72
|
const [isModalVisiable, setIsModalVisible] = useState(false)
|
|
@@ -36,14 +81,12 @@ const Page = ({ template }) => {
|
|
|
36
81
|
|
|
37
82
|
const state = useSelector((state: RootState) => state)
|
|
38
83
|
const { templateManage }: any = state
|
|
39
|
-
console.log('templateManage', templateManage)
|
|
40
84
|
|
|
41
85
|
if (!templateManage.firstLoadFlag) {
|
|
42
86
|
template = templateManage.template
|
|
43
87
|
}
|
|
44
88
|
|
|
45
89
|
const { totalCounts, items: templateItems } = _.cloneDeep(template)
|
|
46
|
-
console.log('template', template)
|
|
47
90
|
|
|
48
91
|
_.each(templateItems, (item, index) => {
|
|
49
92
|
const { id } = item
|
|
@@ -58,7 +101,9 @@ const Page = ({ template }) => {
|
|
|
58
101
|
key: 'id',
|
|
59
102
|
sorter: (a: any, b: any) => a.id - b.id,
|
|
60
103
|
sortDirections: ['descend', 'ascend'],
|
|
61
|
-
showSorterTooltip: false
|
|
104
|
+
showSorterTooltip: false,
|
|
105
|
+
width: '15%',
|
|
106
|
+
align: 'center'
|
|
62
107
|
},
|
|
63
108
|
{
|
|
64
109
|
title: keyTitles.name,
|
|
@@ -66,23 +111,25 @@ const Page = ({ template }) => {
|
|
|
66
111
|
key: 'name',
|
|
67
112
|
sorter: (a: any, b: any) => a.name.length - b.name.length,
|
|
68
113
|
sortDirections: ['descend', 'ascend'],
|
|
69
|
-
showSorterTooltip: false
|
|
114
|
+
showSorterTooltip: false,
|
|
115
|
+
width: '60%',
|
|
116
|
+
ellipsis: true
|
|
70
117
|
},
|
|
71
118
|
{
|
|
72
119
|
title: '操作',
|
|
73
120
|
dataIndex: '',
|
|
121
|
+
width: '25%',
|
|
122
|
+
align: 'center',
|
|
74
123
|
render: (_: any, record: any) => {
|
|
75
124
|
return (
|
|
76
|
-
<Space>
|
|
77
|
-
<Button onClick={() => {
|
|
78
|
-
console.log('record', record)
|
|
125
|
+
<Space size="small">
|
|
126
|
+
<Button type="primary" size="small" onClick={() => {
|
|
79
127
|
updateTemplate(record)
|
|
80
|
-
}}>修改</Button>
|
|
81
|
-
<Button onClick={() => {
|
|
82
|
-
console.log('record', record)
|
|
128
|
+
}} style={{ borderRadius: '4px' }}>修改</Button>
|
|
129
|
+
<Button danger size="small" onClick={() => {
|
|
83
130
|
const { id } = record
|
|
84
131
|
deleteTemplate(id)
|
|
85
|
-
}}>删除</Button>
|
|
132
|
+
}} style={{ borderRadius: '4px' }}>删除</Button>
|
|
86
133
|
</Space>
|
|
87
134
|
)
|
|
88
135
|
}
|
|
@@ -91,7 +138,7 @@ const Page = ({ template }) => {
|
|
|
91
138
|
|
|
92
139
|
const rowSelection = {
|
|
93
140
|
onChange: (selectedRowKeys: any, selectedRows: any) => {
|
|
94
|
-
|
|
141
|
+
//
|
|
95
142
|
setBatchDelIds(selectedRowKeys)
|
|
96
143
|
}
|
|
97
144
|
}
|
|
@@ -138,7 +185,7 @@ const Page = ({ template }) => {
|
|
|
138
185
|
const modalObj = {
|
|
139
186
|
name: handleXSS(modalName)
|
|
140
187
|
}
|
|
141
|
-
|
|
188
|
+
//
|
|
142
189
|
|
|
143
190
|
const checkResult = checkModalObj(modalObj)
|
|
144
191
|
|
|
@@ -192,8 +239,8 @@ const Page = ({ template }) => {
|
|
|
192
239
|
wb.xlsx.writeBuffer().then((data) => {
|
|
193
240
|
const blob = new Blob([data], { type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" });
|
|
194
241
|
saveAs(blob, "Template.xlsx")
|
|
195
|
-
}).catch((
|
|
196
|
-
|
|
242
|
+
}).catch(() => {
|
|
243
|
+
// 导出失败
|
|
197
244
|
})
|
|
198
245
|
} else {
|
|
199
246
|
message.info("没有数据无需导出")
|
|
@@ -204,9 +251,7 @@ const Page = ({ template }) => {
|
|
|
204
251
|
name: 'file',
|
|
205
252
|
action: '/rest/template/import',
|
|
206
253
|
onChange(info: any) {
|
|
207
|
-
|
|
208
|
-
console.log(info.file, info.fileList)
|
|
209
|
-
}
|
|
254
|
+
//
|
|
210
255
|
|
|
211
256
|
if (info.file.status === 'done') {
|
|
212
257
|
message.success(`${info.file.name} 文件上传成功`)
|
|
@@ -236,43 +281,86 @@ const Page = ({ template }) => {
|
|
|
236
281
|
|
|
237
282
|
return (
|
|
238
283
|
<Container>
|
|
284
|
+
<div className="page-title">模板管理</div>
|
|
239
285
|
<ConfigProvider locale={locale}>
|
|
240
286
|
<SearchRow>
|
|
241
|
-
<Space>
|
|
242
|
-
<
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
287
|
+
<Space size="middle" wrap>
|
|
288
|
+
<Space size="small">
|
|
289
|
+
<StyledButton type="primary" onClick={createTemplate} $primary>
|
|
290
|
+
<i className="fa fa-plus" style={{ marginRight: '5px' }}></i>
|
|
291
|
+
新增
|
|
292
|
+
</StyledButton>
|
|
293
|
+
<StyledInput
|
|
294
|
+
value={searchName}
|
|
295
|
+
placeholder="请输入名称搜索"
|
|
296
|
+
allowClear
|
|
297
|
+
onChange={(e) => setSearchName(e.target.value)}
|
|
298
|
+
onPressEnter={doSearch}
|
|
299
|
+
/>
|
|
300
|
+
<StyledButton type="primary" onClick={doSearch} $primary>
|
|
301
|
+
<i className="fa fa-search" style={{ marginRight: '5px' }}></i>
|
|
302
|
+
搜索
|
|
303
|
+
</StyledButton>
|
|
304
|
+
</Space>
|
|
305
|
+
<Space size="small">
|
|
306
|
+
<StyledButton onClick={exportTemplate} icon={<UploadOutlined rev={undefined} rotate={180} />} $export>
|
|
307
|
+
导出
|
|
308
|
+
</StyledButton>
|
|
309
|
+
<Upload {...uploadProps}>
|
|
310
|
+
<StyledButton icon={<UploadOutlined rev={undefined} />} $import>
|
|
311
|
+
导入
|
|
312
|
+
</StyledButton>
|
|
313
|
+
</Upload>
|
|
314
|
+
<StyledButton danger onClick={batchDeleteTemplate} $danger>
|
|
315
|
+
批量删除
|
|
316
|
+
</StyledButton>
|
|
317
|
+
</Space>
|
|
258
318
|
</Space>
|
|
259
319
|
</SearchRow>
|
|
260
|
-
<
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
320
|
+
<StyledTable
|
|
321
|
+
rowSelection={{
|
|
322
|
+
type: 'checkbox',
|
|
323
|
+
...rowSelection,
|
|
324
|
+
}}
|
|
325
|
+
dataSource={dataSource}
|
|
326
|
+
columns={columns}
|
|
327
|
+
bordered
|
|
328
|
+
rowClassName={(record, index) => index % 2 === 0 ? 'table-row-light' : 'table-row-dark'}
|
|
329
|
+
pagination={{
|
|
330
|
+
total: totalCounts,
|
|
331
|
+
pageSize: pageSize,
|
|
332
|
+
showSizeChanger: false,
|
|
333
|
+
showQuickJumper: true,
|
|
334
|
+
showTotal: (total) => `共 ${total} 条记录`,
|
|
335
|
+
onChange: (page, pageSize) => {
|
|
336
|
+
dispatch(searchTemplate(page - 1, pageSize, { name: handleXSS(searchName) }))
|
|
337
|
+
},
|
|
338
|
+
style: { marginTop: '16px', marginBottom: '16px' }
|
|
339
|
+
}}
|
|
340
|
+
/>
|
|
341
|
+
<Modal
|
|
342
|
+
title={<ModalTitle>{(modalId == 0 ? "新增" : "修改") + " 模板"}</ModalTitle>}
|
|
343
|
+
open={isModalVisiable}
|
|
344
|
+
onOk={handleOk}
|
|
345
|
+
onCancel={handleCancel}
|
|
346
|
+
okText="确认"
|
|
347
|
+
cancelText="取消"
|
|
348
|
+
centered
|
|
349
|
+
maskClosable={false}
|
|
350
|
+
destroyOnClose
|
|
351
|
+
okButtonProps={{ style: { borderRadius: '4px' } }}
|
|
352
|
+
cancelButtonProps={{ style: { borderRadius: '4px' } }}
|
|
353
|
+
>
|
|
272
354
|
<ModalContainer>
|
|
273
355
|
<div className="line">
|
|
274
|
-
<label>{keyTitles.name}
|
|
275
|
-
<
|
|
356
|
+
<label>{keyTitles.name}:</label>
|
|
357
|
+
<ModalInput
|
|
358
|
+
value={modalName}
|
|
359
|
+
placeholder="请输入名称"
|
|
360
|
+
allowClear
|
|
361
|
+
autoFocus
|
|
362
|
+
onChange={(e) => setModalName(e.target.value)}
|
|
363
|
+
/>
|
|
276
364
|
</div>
|
|
277
365
|
</ModalContainer>
|
|
278
366
|
</Modal>
|
|
@@ -285,13 +373,10 @@ Page.getInitialProps = async () => {
|
|
|
285
373
|
let template = null
|
|
286
374
|
|
|
287
375
|
await getTemplateService(0, pageSize).then((res: any) => {
|
|
288
|
-
console.log('res', res)
|
|
289
376
|
const { data } = res
|
|
290
377
|
template = data.template
|
|
291
378
|
})
|
|
292
379
|
|
|
293
|
-
console.log('template-getInitialProps', template)
|
|
294
|
-
|
|
295
380
|
return {
|
|
296
381
|
template
|
|
297
382
|
}
|