From 40b0e90c0dcf1cf2a783876cc6d05f727b0235ec Mon Sep 17 00:00:00 2001 From: whyour Date: Sat, 20 Nov 2021 00:58:23 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E8=B0=83=E8=AF=95=E5=8A=9F?= =?UTF-8?q?=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- back/api/script.ts | 27 +++++++++++++++++++++ back/data/sock.ts | 3 ++- back/services/script.ts | 43 ++++++++++++++++++++++++++++++++++ src/layouts/index.less | 1 + src/pages/script/editModal.tsx | 39 +++++++++++++++++++++++++++--- src/pages/script/index.tsx | 9 ++++--- 6 files changed, 113 insertions(+), 9 deletions(-) create mode 100644 back/services/script.ts diff --git a/back/api/script.ts b/back/api/script.ts index 930f11a4..75f85f8a 100644 --- a/back/api/script.ts +++ b/back/api/script.ts @@ -10,6 +10,7 @@ import config from '../config'; import * as fs from 'fs'; import { celebrate, Joi } from 'celebrate'; import path from 'path'; +import ScriptService from '../services/script'; const route = Router(); export default (app: Router) => { @@ -237,4 +238,30 @@ export default (app: Router) => { } }, ); + + route.put( + '/scripts/run', + celebrate({ + body: Joi.object({ + filename: Joi.string().required(), + path: Joi.string().optional().allow(''), + }), + }), + async (req: Request, res: Response, next: NextFunction) => { + const logger: Logger = Container.get('logger'); + try { + let { filename, path } = req.body as { + filename: string; + path: string; + }; + const filePath = `${path}/${filename}`; + const scriptService = Container.get(ScriptService); + const result = await scriptService.runScript(filePath); + res.send(result); + } catch (e) { + logger.error('🔥 error: %o', e); + return next(e); + } + }, + ); }; diff --git a/back/data/sock.ts b/back/data/sock.ts index b65c1e31..3132f256 100644 --- a/back/data/sock.ts +++ b/back/data/sock.ts @@ -13,4 +13,5 @@ export class SockMessage { export type SockMessageType = | 'ping' | 'installDependence' - | 'updateSystemVersion'; + | 'updateSystemVersion' + | 'manuallyRunScript'; diff --git a/back/services/script.ts b/back/services/script.ts new file mode 100644 index 00000000..5d1f3cfa --- /dev/null +++ b/back/services/script.ts @@ -0,0 +1,43 @@ +import { Service, Inject } from 'typedi'; +import winston from 'winston'; +import { spawn } from 'child_process'; +import SockService from './sock'; + +@Service() +export default class ScriptService { + constructor( + @Inject('logger') private logger: winston.Logger, + private sockService: SockService, + ) {} + + public async runScript(path: string) { + const cp = spawn(`task -l ${path} now`, { shell: '/bin/bash' }); + + this.sockService.sendMessage({ + type: 'manuallyRunScript', + message: `开始执行脚本`, + }); + cp.stdout.on('data', (data) => { + this.sockService.sendMessage({ + type: 'manuallyRunScript', + message: data.toString(), + }); + }); + + cp.stderr.on('data', (data) => { + this.sockService.sendMessage({ + type: 'manuallyRunScript', + message: data.toString(), + }); + }); + + cp.on('error', (err) => { + this.sockService.sendMessage({ + type: 'manuallyRunScript', + message: JSON.stringify(err), + }); + }); + + return { code: 200 }; + } +} diff --git a/src/layouts/index.less b/src/layouts/index.less index 64d0720f..f7b81e5d 100644 --- a/src/layouts/index.less +++ b/src/layouts/index.less @@ -235,6 +235,7 @@ box-shadow: none; transition: background-color 5000s ease-in-out 0s; -webkit-text-fill-color: @text-color; + caret-color: #e8e6f3 !important; } ::placeholder { diff --git a/src/pages/script/editModal.tsx b/src/pages/script/editModal.tsx index ccec7b8c..1ee1c1d1 100644 --- a/src/pages/script/editModal.tsx +++ b/src/pages/script/editModal.tsx @@ -28,16 +28,19 @@ const EditModal = ({ content, handleCancel, visible, + socketMessage, }: { treeData?: any; currentFile?: string; content?: string; visible: boolean; + socketMessage: any; handleCancel: () => void; }) => { const [value, setValue] = useState(''); const [language, setLanguage] = useState('javascript'); const [fileName, setFileName] = useState(''); + const [selectedKey, setSelectedKey] = useState(''); const [saveModalVisible, setSaveModalVisible] = useState(false); const [settingModalVisible, setSettingModalVisible] = useState(false); @@ -50,10 +53,14 @@ const EditModal = ({ }; const onSelect = (value: any, node: any) => { + if (node.value === fileName || !value) { + return; + } const newMode = LangMap[value.slice(-3)] || ''; setFileName(value); setLanguage(newMode); getDetail(node); + setSelectedKey(node.key); }; const getDetail = (node: any) => { @@ -62,12 +69,39 @@ const EditModal = ({ }); }; - const run = () => {}; + const run = () => { + request + .put(`${config.apiPrefix}scripts/run`, { + data: { + filename: fileName, + path: '', + }, + }) + .then((data) => {}); + }; + + useEffect(() => { + if (!socketMessage) { + return; + } + + let { type, message: _message, references } = socketMessage; + + if (type !== 'manuallyRunScript') { + return; + } + + if (log) { + _message = `\n${_message}`; + } + setLog(`${log}${_message}`); + }, [socketMessage]); useEffect(() => { if (currentFile) { setFileName(currentFile); setValue(content as string); + setSelectedKey(currentFile); } }, [currentFile, content]); @@ -79,12 +113,11 @@ const EditModal = ({ {fileName}