nsgm-cli 1.0.26 → 2.0.0

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.
Files changed (70) hide show
  1. package/.babelrc +13 -0
  2. package/LICENSE +201 -201
  3. package/README.md +161 -162
  4. package/client/layout/index.tsx +245 -0
  5. package/client/redux/reducers.ts +5 -0
  6. package/{generation/client → client}/redux/store.ts +50 -44
  7. package/{generation/client → client}/redux/template/manage/actions.ts +190 -190
  8. package/{generation/client → client}/redux/template/manage/reducers.ts +118 -118
  9. package/{generation/client → client}/redux/template/manage/types.ts +24 -24
  10. package/client/service/template/manage.ts +97 -0
  11. package/{generation/client → client}/styled/common.ts +27 -28
  12. package/client/styled/layout/index.ts +26 -0
  13. package/{generation/client → client}/styled/template/manage.ts +51 -51
  14. package/client/utils/common.ts +86 -0
  15. package/client/utils/cookie.ts +52 -0
  16. package/{generation/client → client}/utils/fetch.ts +25 -25
  17. package/client/utils/menu.tsx +27 -0
  18. package/generation/.DS_Store +0 -0
  19. package/generation/.babelrc +3 -2
  20. package/generation/README.md +19 -18
  21. package/generation/app.js +2 -2
  22. package/generation/client/redux/reducers.ts +5 -5
  23. package/generation/client/utils/menu.tsx +27 -26
  24. package/generation/gitignore +5 -4
  25. package/generation/mysql.config.js +13 -12
  26. package/generation/next.config.js +6 -6
  27. package/generation/package.json +25 -20
  28. package/generation/project.config.js +12 -12
  29. package/generation/server/rest.js +20 -20
  30. package/generation/server/utils/common.js +7 -0
  31. package/generation/tsconfig.json +30 -29
  32. package/index.js +10 -10
  33. package/lib/args.d.ts +6 -6
  34. package/lib/args.js +47 -47
  35. package/lib/generate.d.ts +3 -3
  36. package/lib/generate.js +735 -590
  37. package/lib/index.d.ts +2 -2
  38. package/lib/index.js +259 -182
  39. package/lib/server/db.d.ts +5 -5
  40. package/lib/server/db.js +110 -47
  41. package/lib/server/graphql.d.ts +7 -7
  42. package/lib/server/graphql.js +119 -119
  43. package/lib/server/plugins/date.d.ts +5 -5
  44. package/lib/server/plugins/date.js +16 -16
  45. package/lib/tsconfig.build.tsbuildinfo +1 -0
  46. package/mysql.config.js +14 -14
  47. package/next-env.d.ts +6 -0
  48. package/next.config.js +194 -174
  49. package/package.json +125 -113
  50. package/{generation/pages → pages}/_app.tsx +44 -44
  51. package/{generation/pages → pages}/_document.tsx +4 -2
  52. package/pages/index.tsx +68 -0
  53. package/{generation/pages → pages}/template/manage.tsx +278 -280
  54. package/project.config.js +14 -14
  55. package/public/slbhealthcheck.html +10 -0
  56. package/scripts/shutdown.sh +10 -0
  57. package/scripts/startup.sh +35 -0
  58. package/{generation/server → server}/apis/template.js +17 -18
  59. package/{generation/server → server}/modules/template/resolver.js +29 -35
  60. package/{generation/server → server}/modules/template/schema.js +33 -33
  61. package/server/rest.js +20 -0
  62. package/{generation/server → server}/sql/template.sql +8 -8
  63. package/server/utils/common.js +7 -0
  64. package/generation/client/layout/index.tsx +0 -223
  65. package/generation/client/service/template/manage.ts +0 -74
  66. package/generation/client/styled/layout/index.ts +0 -14
  67. package/generation/client/utils/common.ts +0 -45
  68. package/generation/next-env.d.ts +0 -2
  69. package/generation/pages/index.tsx +0 -55
  70. /package/{generation/public → public}/images/zhizuotu_1.png +0 -0
@@ -1,281 +1,279 @@
1
- import React, { useEffect, useState } from 'react'
2
- import { ConfigProvider, Table, Modal, Button, Input, Space, Upload, message } from 'antd'
3
- import { Container, SearchRow, ModalContainer } from '../../client/styled/template/manage'
4
- import { useDispatch, useSelector } from 'react-redux'
5
- import { getTemplate, addTemplate, modTemplate, delTemplate, updateSSRTemplate, searchTemplate, batchDelTemplate } from '../../client/redux/template/manage/actions'
6
- import { getTemplateService } from '../../client/service/template/manage'
7
- import { RootState } from '../../client/redux/store'
8
- import _ from 'lodash'
9
- import moment from 'moment'
10
- import locale from 'antd/lib/locale/zh_CN'
11
- import { handleXSS, checkModalObj } from '../../client/utils/common'
12
- import XLSX from 'xlsx'
13
- import { UploadOutlined } from '@ant-design/icons'
14
-
15
- const pageSize = 100
16
- const dateFormat = 'YYYY-MM-DD'
17
- const currentDate = moment().format(dateFormat)
18
- // console.log('currentDate', currentDate)
19
-
20
- const keyTitles = {
21
- name: '名称'
22
- }
23
-
24
- const Page = ({ template }) => {
25
- const dispatch = useDispatch()
26
- const [isModalVisiable, setIsModalVisible] = useState(false)
27
- const [modalId, setModalId] = useState(0)
28
- const [modalName, setModalName] = useState('')
29
- const [searchName, setSearchName] = useState('')
30
- const [batchDelIds, setBatchDelIds] = useState([])
31
-
32
- useEffect(() => {
33
- dispatch(updateSSRTemplate(template))
34
- }, [dispatch])
35
-
36
- const state = useSelector((rootState: RootState) => rootState)
37
- const { templateManage }:any = state
38
- // console.log('templateManage', templateManage)
39
-
40
- if (!templateManage.firstLoadFlag) {
41
- template = templateManage.template
42
- }
43
-
44
- const { totalCounts, items:templateItems } = template
45
- // console.log('template', template)
46
-
47
- _.each(templateItems, (item:any, index:any) => {
48
- const { id } = item
49
- item.key = id
50
- })
51
-
52
- const dataSource = templateItems
53
- const columns:any = [
54
- {
55
- title: 'ID',
56
- dataIndex: 'id',
57
- key: 'id',
58
- sorter: (a: any, b: any) => a.id - b.id,
59
- sortDirections: ['descend', 'ascend'],
60
- showSorterTooltip: false
61
- },
62
- {
63
- title: keyTitles.name,
64
- dataIndex: 'name',
65
- key: 'name',
66
- sorter: (a: any, b: any) => a.name.length - b.name.length,
67
- sortDirections: ['descend', 'ascend'],
68
- showSorterTooltip: false
69
- },
70
- {
71
- title: '操作',
72
- dataIndex: '',
73
- render: (__:any, record:any) => {
74
- return (
75
- <Space>
76
- <Button onClick={() => {
77
- // console.log('record', record)
78
- updateTemplate(record)
79
- }}>修改</Button>
80
- <Button onClick={() => {
81
- // console.log('record', record)
82
- const { id } = record
83
- deleteTemplate(id)
84
- }}>删除</Button>
85
- </Space>
86
- )
87
- }
88
- }
89
- ]
90
-
91
- const rowSelection = {
92
- onChange: (selectedRowKeys: React.Key[], selectedRows: any) => {
93
- // console.log(`selectedRowKeys: ${selectedRowKeys}`, 'selectedRows: ', selectedRows)
94
- setBatchDelIds(selectedRowKeys)
95
- }
96
- }
97
-
98
- const createTemplate = () => {
99
- setModalId(0)
100
- setModalName('')
101
- showModal()
102
- }
103
-
104
- const updateTemplate = (record:any) => {
105
- const { id, name } = record
106
-
107
- setModalId(id)
108
- setModalName(name)
109
- showModal()
110
- }
111
-
112
- const deleteTemplate = (id:number) => {
113
- Modal.confirm({
114
- title: '提示',
115
- content: '确认删除吗',
116
- okText: '确认',
117
- cancelText: '取消',
118
- onOk : (e) => {
119
- dispatch(delTemplate(id))
120
- Modal.destroyAll()
121
- }
122
- })
123
- }
124
-
125
- const showModal = () => {
126
- setIsModalVisible(true)
127
- }
128
-
129
- const getMessageTitle = (key: string) => {
130
- let result = keyTitles[key]
131
- if (result === undefined)
132
- result = key
133
- return result
134
- }
135
-
136
- const handleOk = () => {
137
- const modalObj = {
138
- name: handleXSS(modalName)
139
- }
140
- // console.log('handleOk', modalObj)
141
-
142
- const checkResult = checkModalObj(modalObj)
143
-
144
- if (!checkResult) {
145
- if (modalId === 0) { // 新增
146
- dispatch(addTemplate(modalObj))
147
- } else {
148
- dispatch(modTemplate(modalId, modalObj))
149
- }
150
-
151
- setIsModalVisible(false)
152
- } else {
153
- message.info(getMessageTitle(checkResult.key) + checkResult.reason)
154
- }
155
- }
156
-
157
- const handleCancel = () => {
158
- setIsModalVisible(false)
159
- }
160
-
161
- const doSearch = () => {
162
- dispatch(searchTemplate(0, pageSize, { name: handleXSS(searchName) }))
163
- }
164
-
165
- const exportTemplate = () => {
166
- if (templateItems.length > 0) {
167
- const wb = XLSX.utils.book_new()
168
- const jsonData = _.map(templateItems, (item) => _.omit(item, ['key']))
169
- // console.log('jsonData', jsonData)
170
- const ws = XLSX.utils.json_to_sheet(jsonData)
171
-
172
- /* add worksheet to workbook */
173
- XLSX.utils.book_append_sheet(wb, ws, "Template")
174
-
175
- /* write workbook */
176
- XLSX.writeFile(wb, "Template.xlsx")
177
- } else {
178
- message.info("没有数据无需导出")
179
- }
180
- }
181
-
182
- const uploadProps = {
183
- name: 'file',
184
- action: '/rest/template/import',
185
- onChange(info: any) {
186
- /*
187
- if (info.file.status !== 'uploading') {
188
- console.log(info.file, info.fileList)
189
- }
190
- */
191
-
192
- if (info.file.status === 'done') {
193
- message.success(`${info.file.name} 文件上传成功`)
194
- window.location.reload()
195
- } else if (info.file.status === 'error') {
196
- message.error(`${info.file.name} 文件上传失败`)
197
- }
198
- }
199
- }
200
-
201
- const batchDeleteTemplate = () => {
202
- if (batchDelIds.length > 0) {
203
- Modal.confirm({
204
- title: '提示',
205
- content: '确认批量删除吗',
206
- okText: '确认',
207
- cancelText: '取消',
208
- onOk : (e) => {
209
- dispatch(batchDelTemplate(batchDelIds))
210
- Modal.destroyAll()
211
- }
212
- })
213
- } else {
214
- message.info("没有数据不能批量删除")
215
- }
216
- }
217
-
218
- return (
219
- <Container>
220
- <ConfigProvider locale={locale}>
221
- <SearchRow>
222
- <Space>
223
- <Button type="primary" onClick={createTemplate}>
224
- 新增
225
- </Button>
226
- <Input value={searchName} placeholder="" onChange={(e) => setSearchName(e.target.value)} />
227
- <Button type="primary" onClick={doSearch}>
228
- 搜索
229
- </Button>
230
- <Button type="primary" onClick={exportTemplate}>
231
- 导出
232
- </Button>
233
- <Upload {...uploadProps}>
234
- <Button icon={<UploadOutlined />}>导入</Button>
235
- </Upload>
236
- <Button type="primary" onClick={batchDeleteTemplate}>
237
- 批量删除
238
- </Button>
239
- </Space>
240
- </SearchRow>
241
- <Table rowSelection={{
242
- type: 'checkbox',
243
- ...rowSelection,
244
- }} dataSource={dataSource} columns={columns} pagination={{
245
- total: totalCounts,
246
- pageSize,
247
- onChange: (page:any, newPageSize:any) => {
248
- // console.log('onChange', page, newPageSize)
249
- dispatch(searchTemplate(page - 1, pageSize, { name: handleXSS(searchName) }))
250
- }
251
- }} />
252
- <Modal title={(modalId === 0 ? "新增" : "修改") + " template"} visible={isModalVisiable} onOk={handleOk} onCancel={handleCancel} okText="确认" cancelText="取消">
253
- <ModalContainer>
254
- <div className="line">
255
- <label>{keyTitles.name}</label>
256
- <Input value={modalName} placeholder="" onChange={(e) => setModalName(e.target.value)} />
257
- </div>
258
- </ModalContainer>
259
- </Modal>
260
- </ConfigProvider>
261
- </Container>
262
- )
263
- }
264
-
265
- Page.getInitialProps = async () => {
266
- let template = null
267
-
268
- await getTemplateService(0, pageSize).then((res: any) => {
269
- // console.log('res', res)
270
- const { data } = res
271
- template = data.template
272
- })
273
-
274
- // console.log('template-getInitialProps', template)
275
-
276
- return {
277
- template
278
- }
279
- }
280
-
1
+ import React, { useEffect, useState } from 'react'
2
+ import { ConfigProvider, Table, Modal, Button, Input, Space, Upload, message } from 'antd'
3
+ import { Container, SearchRow, ModalContainer } from '../../client/styled/template/manage'
4
+ import { useDispatch, useSelector } from 'react-redux'
5
+ import { getTemplate, addTemplate, modTemplate, delTemplate, updateSSRTemplate, searchTemplate, batchDelTemplate } from '../../client/redux/template/manage/actions'
6
+ import { getTemplateService } from '../../client/service/template/manage'
7
+ import { RootState } from '../../client/redux/store'
8
+ import _ from 'lodash'
9
+ import moment from 'moment'
10
+ import locale from 'antd/lib/locale/zh_CN'
11
+ import { handleXSS, checkModalObj } from '../../client/utils/common'
12
+ import XLSX from 'xlsx'
13
+ import { UploadOutlined } from '@ant-design/icons'
14
+
15
+ const pageSize = 100
16
+ const dateFormat = 'YYYY-MM-DD'
17
+ const currentDate = moment().format(dateFormat)
18
+ console.log('currentDate', currentDate)
19
+
20
+ const keyTitles = {
21
+ name: '名称'
22
+ }
23
+
24
+ const Page = ({ template }) => {
25
+ const dispatch = useDispatch()
26
+ const [isModalVisiable, setIsModalVisible] = useState(false)
27
+ const [modalId, setModalId] = useState(0)
28
+ const [modalName, setModalName] = useState('')
29
+ const [searchName, setSearchName] = useState('')
30
+ const [batchDelIds, setBatchDelIds] = useState([])
31
+
32
+ useEffect(() => {
33
+ dispatch(updateSSRTemplate(template))
34
+ }, [dispatch])
35
+
36
+ const state = useSelector((state: RootState) => state)
37
+ const { templateManage }:any = state
38
+ console.log('templateManage', templateManage)
39
+
40
+ if (!templateManage.firstLoadFlag) {
41
+ template = templateManage.template
42
+ }
43
+
44
+ const { totalCounts, items:templateItems } = template
45
+ console.log('template', template)
46
+
47
+ _.each(templateItems, (item, index) => {
48
+ const { id } = item
49
+ item.key = id
50
+ })
51
+
52
+ const dataSource = templateItems
53
+ const columns:any = [
54
+ {
55
+ title: 'ID',
56
+ dataIndex: 'id',
57
+ key: 'id',
58
+ sorter: (a: any, b: any) => a.id - b.id,
59
+ sortDirections: ['descend', 'ascend'],
60
+ showSorterTooltip: false
61
+ },
62
+ {
63
+ title: keyTitles.name,
64
+ dataIndex: 'name',
65
+ key: 'name',
66
+ sorter: (a: any, b: any) => a.name.length - b.name.length,
67
+ sortDirections: ['descend', 'ascend'],
68
+ showSorterTooltip: false
69
+ },
70
+ {
71
+ title: '操作',
72
+ dataIndex: '',
73
+ render: (_:any, record:any) => {
74
+ return (
75
+ <Space>
76
+ <Button onClick={() => {
77
+ console.log('record', record)
78
+ updateTemplate(record)
79
+ }}>修改</Button>
80
+ <Button onClick={() => {
81
+ console.log('record', record)
82
+ const { id } = record
83
+ deleteTemplate(id)
84
+ }}>删除</Button>
85
+ </Space>
86
+ )
87
+ }
88
+ }
89
+ ]
90
+
91
+ const rowSelection = {
92
+ onChange: (selectedRowKeys: any, selectedRows: any) => {
93
+ console.log(`selectedRowKeys: ${selectedRowKeys}`, 'selectedRows: ', selectedRows)
94
+ setBatchDelIds(selectedRowKeys)
95
+ }
96
+ }
97
+
98
+ const createTemplate = () => {
99
+ setModalId(0)
100
+ setModalName('')
101
+ showModal()
102
+ }
103
+
104
+ const updateTemplate = (record:any) => {
105
+ let { id, name } = record
106
+
107
+ setModalId(id)
108
+ setModalName(name)
109
+ showModal()
110
+ }
111
+
112
+ const deleteTemplate = (id:number) => {
113
+ Modal.confirm({
114
+ title: '提示',
115
+ content: '确认删除吗',
116
+ okText: '确认',
117
+ cancelText: '取消',
118
+ onOk : (e) => {
119
+ dispatch(delTemplate(id))
120
+ Modal.destroyAll()
121
+ }
122
+ })
123
+ }
124
+
125
+ const showModal = () => {
126
+ setIsModalVisible(true)
127
+ }
128
+
129
+ const getMessageTitle = (key: string) => {
130
+ let result = keyTitles[key]
131
+ if (result == undefined)
132
+ result = key
133
+ return result
134
+ }
135
+
136
+ const handleOk = () => {
137
+ const modalObj = {
138
+ name: handleXSS(modalName)
139
+ }
140
+ console.log('handleOk', modalObj)
141
+
142
+ const checkResult = checkModalObj(modalObj)
143
+
144
+ if (!checkResult) {
145
+ if (modalId == 0) { // 新增
146
+ dispatch(addTemplate(modalObj))
147
+ } else {
148
+ dispatch(modTemplate(modalId, modalObj))
149
+ }
150
+
151
+ setIsModalVisible(false)
152
+ } else {
153
+ message.info(getMessageTitle(checkResult.key) + checkResult.reason)
154
+ }
155
+ }
156
+
157
+ const handleCancel = () => {
158
+ setIsModalVisible(false)
159
+ }
160
+
161
+ const doSearch = () => {
162
+ dispatch(searchTemplate(0, pageSize, { name: handleXSS(searchName) }))
163
+ }
164
+
165
+ const exportTemplate = () => {
166
+ if (templateItems.length > 0) {
167
+ const wb = XLSX.utils.book_new()
168
+ const jsonData = _.map(templateItems, (item) => _.omit(item, ['key']))
169
+ //console.log('jsonData', jsonData)
170
+ const ws = XLSX.utils.json_to_sheet(jsonData)
171
+
172
+ /* add worksheet to workbook */
173
+ XLSX.utils.book_append_sheet(wb, ws, "Template")
174
+
175
+ /* write workbook */
176
+ XLSX.writeFile(wb, "Template.xlsx")
177
+ } else {
178
+ message.info("没有数据无需导出")
179
+ }
180
+ }
181
+
182
+ const uploadProps = {
183
+ name: 'file',
184
+ action: '/rest/template/import',
185
+ onChange(info:any) {
186
+ if (info.file.status !== 'uploading') {
187
+ console.log(info.file, info.fileList)
188
+ }
189
+
190
+ if (info.file.status === 'done') {
191
+ message.success(`${info.file.name} 文件上传成功`)
192
+ window.location.reload()
193
+ } else if (info.file.status === 'error') {
194
+ message.error(`${info.file.name} 文件上传失败`)
195
+ }
196
+ }
197
+ }
198
+
199
+ const batchDeleteTemplate = () => {
200
+ if (batchDelIds.length > 0) {
201
+ Modal.confirm({
202
+ title: '提示',
203
+ content: '确认批量删除吗',
204
+ okText: '确认',
205
+ cancelText: '取消',
206
+ onOk : (e) => {
207
+ dispatch(batchDelTemplate(batchDelIds))
208
+ Modal.destroyAll()
209
+ }
210
+ })
211
+ } else {
212
+ message.info("没有数据不能批量删除")
213
+ }
214
+ }
215
+
216
+ return (
217
+ <Container>
218
+ <ConfigProvider locale={locale}>
219
+ <SearchRow>
220
+ <Space>
221
+ <Button type="primary" onClick={createTemplate}>
222
+ 新增
223
+ </Button>
224
+ <Input value={searchName} placeholder="" onChange={(e) => setSearchName(e.target.value)} />
225
+ <Button type="primary" onClick={doSearch}>
226
+ 搜索
227
+ </Button>
228
+ <Button type="primary" onClick={exportTemplate}>
229
+ 导出
230
+ </Button>
231
+ <Upload {...uploadProps}>
232
+ <Button icon={<UploadOutlined />}>导入</Button>
233
+ </Upload>
234
+ <Button type="primary" onClick={batchDeleteTemplate}>
235
+ 批量删除
236
+ </Button>
237
+ </Space>
238
+ </SearchRow>
239
+ <Table rowSelection={{
240
+ type: 'checkbox',
241
+ ...rowSelection,
242
+ }} dataSource={dataSource} columns={columns} pagination={{
243
+ total: totalCounts,
244
+ pageSize: pageSize,
245
+ onChange: (page, pageSize) => {
246
+ console.log('onChange', page, pageSize)
247
+ dispatch(searchTemplate(page - 1, pageSize, { name: handleXSS(searchName) }))
248
+ }
249
+ }} />
250
+ <Modal title={(modalId == 0 ? "新增" : "修改") + " template"} open={isModalVisiable} onOk={handleOk} onCancel={handleCancel} okText="确认" cancelText="取消">
251
+ <ModalContainer>
252
+ <div className="line">
253
+ <label>{keyTitles.name}</label>
254
+ <Input value={modalName} placeholder="" onChange={(e) => setModalName(e.target.value)} />
255
+ </div>
256
+ </ModalContainer>
257
+ </Modal>
258
+ </ConfigProvider>
259
+ </Container>
260
+ )
261
+ }
262
+
263
+ Page.getInitialProps = async () => {
264
+ let template = null
265
+
266
+ await getTemplateService(0, pageSize).then((res: any) => {
267
+ console.log('res', res)
268
+ const { data } = res
269
+ template = data.template
270
+ })
271
+
272
+ console.log('template-getInitialProps', template)
273
+
274
+ return {
275
+ template
276
+ }
277
+ }
278
+
281
279
  export default Page
package/project.config.js CHANGED
@@ -1,15 +1,15 @@
1
- const pkg = require('./package.json')
2
-
3
- const { version } = pkg
4
- const prefix = ''
5
- const protocol = 'http'
6
- const host = '127.0.0.1'
7
- const port = 8080
8
-
9
- module.exports = {
10
- version,
11
- prefix,
12
- protocol,
13
- host,
14
- port
1
+ const pkg = require('./package.json')
2
+
3
+ const { version } = pkg
4
+ const protocol = 'http'
5
+ const prefix = ''
6
+ const host = '127.0.0.1'
7
+ const port = 8080
8
+
9
+ module.exports = {
10
+ version,
11
+ prefix,
12
+ protocol,
13
+ host,
14
+ port
15
15
  }
@@ -0,0 +1,10 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <title>nsgm-cli</title>
6
+ </head>
7
+ <body>
8
+ SLBHEALTHCHECK
9
+ </body>
10
+ </html>
@@ -0,0 +1,10 @@
1
+ #!/bin/sh
2
+
3
+ cd $(dirname $BASH_SOURCE)
4
+ cd ..
5
+ appid=$(basename $(pwd))
6
+ cd current
7
+ appname=node-app-$appid
8
+
9
+ pm2 delete $appname
10
+ pm2 dump
@@ -0,0 +1,35 @@
1
+ #!/bin/sh
2
+
3
+ cpu=1
4
+
5
+ if [ -n "$CDOS_CPUS" ]; then
6
+ cpu=$(printf "%.0f" $CDOS_CPUS)
7
+ else
8
+ cpu=$(cat /proc/cpuinfo | grep "processor" | wc -l)
9
+ fi
10
+
11
+ if [ $cpu -lt 1 ]; then
12
+ cpu=1
13
+ fi
14
+
15
+ if [ $cpu -gt 8 ]; then
16
+ cpu=8
17
+ fi
18
+
19
+ cd $(dirname $BASH_SOURCE)
20
+ cd ..
21
+ appid=$(basename $(pwd))
22
+ cd current
23
+ appname=node-app-$appid
24
+
25
+ pm2 delete $appname
26
+ pm2 web
27
+ pm2 start app.js\
28
+ -i $cpu\
29
+ --name $appname\
30
+ --merge-logs\
31
+ --log-date-format="YYYY-MM-DD HH:mm:ss"\
32
+ --log /opt/logs/$appid/outerr.log\
33
+ --output /opt/logs/$appid/out.log\
34
+ --error /opt/logs/$appid/err.log
35
+ pm2 dump