Skip to content

Commit f882ad0

Browse files
committed
增加运行命令
1 parent d387795 commit f882ad0

File tree

4 files changed

+117
-7
lines changed

4 files changed

+117
-7
lines changed

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "command-manager",
3-
"version": "0.2.1",
3+
"version": "0.2.2",
44
"private": true,
55
"scripts": {
66
"start": "vue-cli-service serve --port 27000",

server/router/index.js

+86-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ const path = require('path')
22
const fs = require('fs-extra')
33
const router = require('koa-router')()
44
const { useResponse } = require('../utils')
5-
const { exec } = require('child_process')
5+
const { exec, spawn } = require('child_process')
6+
const commandList = {}
67

78
router.get('/', async (ctx) => {
89
await ctx.render('index', {})
@@ -48,4 +49,88 @@ router.post('/open', async (ctx) => {
4849
useResponse(ctx, {}, 500, '文件目录不存在')
4950
})
5051

52+
router.post('/stop', async (ctx) => {
53+
data = ctx.request.body
54+
console.log(commandList[data.uuid])
55+
if (data.uuid && Array.isArray(commandList[data.uuid])) {
56+
commandList[data.uuid].forEach(list => {
57+
list.forEach(item => {
58+
if (!item.close) {
59+
item.child.kill('SIGKILL')
60+
}
61+
})
62+
})
63+
delete commandList[data.uuid]
64+
return useResponse(ctx, 1)
65+
}
66+
useResponse(ctx, 0)
67+
})
68+
69+
router.post('/exec', async (ctx) => {
70+
const current = []
71+
const commands = []
72+
const data = ctx.request.body
73+
if (data.uuid) {
74+
commandList[data.uuid] = commandList[data.uuid] || []
75+
commandList[data.uuid].push(current)
76+
}
77+
if (data.nodeVersion) {
78+
commands.push('nvm use ' + data.nodeVersion)
79+
}
80+
if (typeof data.commandLines === 'string' || Array.isArray(data.commandLines)) {
81+
const commandLines = (Array.isArray(data.commandLines) ? data.commandLines : data.commandLines.split('\n'))
82+
commandLines.map(command => {
83+
commands.push(command.replace(/(^\s+|\s+$)/g, ''))
84+
})
85+
const result = []
86+
const promises = commands.map((command, index) => {
87+
return new Promise((resolve, reject) => {
88+
if (!command) resolve()
89+
const child = spawn('cmd.exe', ['/c', command], {
90+
cwd: data.path
91+
})
92+
const item = {
93+
command,
94+
child
95+
}
96+
current.push(item)
97+
child.stdout.on('data', data => {
98+
console.log(`${command} 输出:\n${data}\n`)
99+
})
100+
child.stderr.on('data', data => {
101+
console.error(`${command} 错误:\n${data}\n`)
102+
})
103+
child.on('close', code => {
104+
Object.assign(item, {
105+
close: true,
106+
code
107+
})
108+
result[index] = {
109+
command,
110+
code
111+
}
112+
if (code === 0) resolve()
113+
else reject(code)
114+
})
115+
})
116+
})
117+
console.log(commands)
118+
const execPromise = () => Promise.all(promises).then(() => {
119+
useResponse(ctx, result.slice(data.nodeVersion ? 3 : 2))
120+
}).catch(error => {
121+
useResponse(ctx, {}, 500, error.toString())
122+
}).finally(() => {
123+
if (data.uuid) {
124+
commandList[data.uuid] = commandList[data.uuid].filter(item => item !== current)
125+
}
126+
})
127+
if (data.await) {
128+
return execPromise()
129+
} else {
130+
execPromise()
131+
}
132+
}
133+
useResponse(ctx, {})
134+
})
135+
51136
module.exports = router

src/api/index.js

+6
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,11 @@ export default {
55
},
66
open (data) {
77
return fetchApi('open', 'post', data)
8+
},
9+
exec (data) {
10+
return fetchApi('exec', 'post', data)
11+
},
12+
stop (data) {
13+
return fetchApi('stop', 'post', data)
814
}
915
}

src/views/manager/list.vue

+24-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<template>
2-
<el-table :data="tableData" @dblclick="row => handleRow('managerEdit', row)">
2+
<el-table :data="tableData" @row-dblclick="row => handleRow('managerEdit', row)">
33
<el-table-column type="index" label="序号" width="60" />
44
<el-table-column prop="name" label="名称" width="120" />
55
<el-table-column prop="port" label="端口" width="120" />
@@ -8,11 +8,14 @@
88
<el-table-column prop="path" label="脚本路径" />
99
<el-table-column prop="keywords" label="关键词" />
1010
<el-table-column prop="desc" label="备注" />
11-
<el-table-column prop="handle" label="操作" width="240">
12-
<template #default="{ row }">
13-
<el-button type="info" size="small" @click="handleOpen(row)">打开路径</el-button>
14-
<el-button type="warning" size="small" @click="handleRow('managerEdit', row)">修改</el-button>
11+
<el-table-column prop="handle" label="操作" width="400">
12+
<template #default="{ row, $index }">
13+
<el-button size="small" @click="handleOpen(row)">打开路径</el-button>
14+
<el-button type="danger" size="small" @click="handleExec(row)">执行</el-button>
15+
<el-button type="info" size="small" @click="handleStop(row)">停止</el-button>
16+
<el-button type="success" size="small" @click="handleRow('managerEdit', row)">修改</el-button>
1517
<el-button type="primary" size="small" @click="handleRow('managerCopy', row)">复制</el-button>
18+
<el-button type="warning" size="small" @click="handleDelete(row, $index)">删除</el-button>
1619
</template>
1720
</el-table-column>
1821
</el-table>
@@ -23,7 +26,9 @@ import { ref } from 'vue'
2326
import api from '@/api'
2427
import { manifest } from './common'
2528
import router from '@/router'
29+
import { ElMessageBox } from 'element-plus'
2630
const handleRow = (type, row) => {
31+
console.log(row)
2732
router.push({
2833
name: type,
2934
query: {
@@ -34,6 +39,20 @@ const handleRow = (type, row) => {
3439
const handleOpen = (row) => {
3540
api.open(row)
3641
}
42+
const handleExec = (row) => {
43+
api.exec(row)
44+
}
45+
const handleStop = (row) => {
46+
api.stop(row)
47+
}
48+
const handleDelete = (row, $index) => {
49+
ElMessageBox.confirm(`是否删除 ${row.name} 命令?`, {
50+
title: '删除确认',
51+
type: 'warning'
52+
}).then(() => {
53+
tableData.value.splice($index)
54+
}).catch(console.log)
55+
}
3756
const tableData = ref(manifest.value.commands)
3857
</script>
3958
<style scoped>

0 commit comments

Comments
 (0)