From f910fb0a4560f379c99aebdff05b609ea4529c03 Mon Sep 17 00:00:00 2001 From: bwcx_jzy Date: Mon, 13 Mar 2023 18:21:38 +0800 Subject: [PATCH] =?UTF-8?q?fix=20SSH=20=E5=91=BD=E4=BB=A4=E8=84=9A?= =?UTF-8?q?=E6=9C=AC=E3=80=81=E6=9C=8D=E5=8A=A1=E7=AB=AF=E8=84=9A=E6=9C=AC?= =?UTF-8?q?=E3=80=81=E6=8F=92=E4=BB=B6=E7=AB=AF=E8=84=9A=E6=9C=AC=E6=89=A7?= =?UTF-8?q?=E8=A1=8C=E5=8F=82=E6=95=B0=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 10 ++ .../io/jpom/model/data/NodeScriptModel.java | 5 + .../jpom/script/NodeScriptProcessBuilder.java | 2 +- .../java/io/jpom/script/CommandParam.java | 125 ++++++++++++++++++ .../controller/script/ScriptController.java | 5 +- .../controller/ssh/CommandInfoController.java | 17 +-- .../java/io/jpom/model/data/CommandModel.java | 25 ---- .../io/jpom/model/node/ScriptCacheModel.java | 5 + .../io/jpom/model/script/ScriptModel.java | 4 + .../service/node/command/CommandService.java | 17 +-- .../socket/ServerScriptProcessBuilder.java | 3 +- .../socket/handler/ServerScriptHandler.java | 6 +- .../resources/sql-view/alter.all.v1.3.csv | 1 + .../resources/sql-view/table.all.v1.0.csv | 1 - .../node/node-layout/other/script-console.vue | 38 +++++- .../node/node-layout/other/script-list.vue | 42 +++++- web-vue/src/pages/node/script-list.vue | 41 +++++- web-vue/src/pages/script/script-console.vue | 39 +++++- web-vue/src/pages/script/script-list.vue | 43 +++++- web-vue/src/pages/ssh/command.vue | 95 +++++++------ web-vue/src/pages/system/workspace.vue | 7 +- 21 files changed, 395 insertions(+), 136 deletions(-) create mode 100644 modules/common/src/main/java/io/jpom/script/CommandParam.java diff --git a/CHANGELOG.md b/CHANGELOG.md index 79d53583a..277576004 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,16 @@ 3. 【server】修复 节点分发 webhook 输入框的错别字(感谢 @大灰灰 ) 4. 【server】修复 工作空间环境变量操作日志记录错误问题 5. 【all】更新 fastjson2 版本 +6. 【all】优化 SSH 命令脚本、服务端脚本、插件端脚本执行参数优化 + (感谢 [@大灰灰大](https://gitee.com/linjianhui) [Gitee issues I6IPDY](https://gitee.com/dromara/Jpom/issues/I6IPDY) ) + +### ❌ 不兼容功能 + +1. 【server】删除 COMMAND_INFO 表 type 字段 + +### ⚠️ 注意 + +SSH 命令脚本、服务端脚本、插件端脚本默认参数规则变化:参数描述将必填,默认参数在手动执行时无法删除并且可以查看对应参数描述 ------ diff --git a/modules/agent/src/main/java/io/jpom/model/data/NodeScriptModel.java b/modules/agent/src/main/java/io/jpom/model/data/NodeScriptModel.java index b8ada0852..30f691d71 100644 --- a/modules/agent/src/main/java/io/jpom/model/data/NodeScriptModel.java +++ b/modules/agent/src/main/java/io/jpom/model/data/NodeScriptModel.java @@ -25,6 +25,7 @@ package io.jpom.model.data; import cn.hutool.core.io.FileUtil; import cn.hutool.core.util.StrUtil; import io.jpom.JpomApplication; +import io.jpom.script.CommandParam; import lombok.Data; import lombok.EqualsAndHashCode; @@ -69,6 +70,10 @@ public class NodeScriptModel extends BaseWorkspaceModel { return StrUtil.emptyToDefault(lastRunUser, StrUtil.DASHED); } + public void setDefArgs(String defArgs) { + this.defArgs = CommandParam.convertToParam(defArgs); + } + public File scriptPath() { return scriptPath(getId()); } diff --git a/modules/agent/src/main/java/io/jpom/script/NodeScriptProcessBuilder.java b/modules/agent/src/main/java/io/jpom/script/NodeScriptProcessBuilder.java index 0adfbae6f..d60319f36 100644 --- a/modules/agent/src/main/java/io/jpom/script/NodeScriptProcessBuilder.java +++ b/modules/agent/src/main/java/io/jpom/script/NodeScriptProcessBuilder.java @@ -81,7 +81,7 @@ public class NodeScriptProcessBuilder extends BaseRunScript implements Runnable // String script = FileUtil.getAbsolutePath(scriptFile); processBuilder = new ProcessBuilder(); - List command = StrUtil.splitTrim(args, StrUtil.SPACE); + List command = CommandParam.toCommandList(args); command.add(0, script); CommandUtil.paddingPrefix(command); log.debug(CollUtil.join(command, StrUtil.SPACE)); diff --git a/modules/common/src/main/java/io/jpom/script/CommandParam.java b/modules/common/src/main/java/io/jpom/script/CommandParam.java new file mode 100644 index 000000000..3f0aff4cd --- /dev/null +++ b/modules/common/src/main/java/io/jpom/script/CommandParam.java @@ -0,0 +1,125 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Code Technology Studio + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package io.jpom.script; + +import cn.hutool.core.lang.Opt; +import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson2.JSONObject; +import com.alibaba.fastjson2.JSONValidator; +import io.jpom.model.BaseJsonModel; +import io.jpom.util.StringUtil; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * 脚本参数 + * + * @author bwcx_jzy + * @since 2023/3/13 + */ +@Data +@EqualsAndHashCode(callSuper = true) +public class CommandParam extends BaseJsonModel { + /** + * 参数值 + */ + private String value; + /** + * 描述 + */ + private String desc; + + public static String convertToParam(String defArgs) { + JSONValidator.Type type = StringUtil.validatorJson(defArgs); + if (type == null || type == JSONValidator.Type.Value) { + // 旧版本的数据 + List commandParams = CommandParam.convertLineStr(defArgs); + return commandParams == null ? null : JSONObject.toJSONString(commandParams); + } else if (type == JSONValidator.Type.Object) { + return defArgs; + } else { + return defArgs; + } + } + + public static String toCommandLine(String params) { + JSONValidator.Type type = StringUtil.validatorJson(params); + if (type == null || type == JSONValidator.Type.Value) { + // 兼容旧数据 + return params; + } + List paramList = params(params); + return Optional.ofNullable(paramList) + .map(commandParams -> commandParams.stream() + .map(CommandParam::getValue) + .collect(Collectors.joining(StrUtil.SPACE))) + .orElse(StrUtil.EMPTY); + } + + public static List toCommandList(String params) { + JSONValidator.Type type = StringUtil.validatorJson(params); + if (type == null || type == JSONValidator.Type.Value) { + // 兼容旧数据 + return StrUtil.splitTrim(params, StrUtil.SPACE); + } + List paramList = params(params); + return Optional.ofNullable(paramList) + .map(commandParams -> commandParams.stream() + .map(CommandParam::getValue) + .filter(Objects::nonNull) + .collect(Collectors.toList())) + .orElse(Collections.emptyList()); + } + + public static List params(String defParams) { + return StringUtil.jsonConvertArray(defParams, CommandParam.class); + } + + public static String checkStr(String str) { + return Opt.ofBlankAble(str) + .map(s -> { + List params = params(s); + return JSONObject.toJSONString(params); + }).orElse(StrUtil.EMPTY); + } + + public static List convertLineStr(String defArgs) { + List list = StrUtil.splitTrim(defArgs, StrUtil.SPACE); + return Optional.ofNullable(list) + .map(strings -> { + List commandParams1 = new ArrayList<>(strings.size()); + for (int i = 0; i < strings.size(); i++) { + CommandParam commandParam = new CommandParam(); + commandParam.setValue(strings.get(i)); + commandParam.setDesc("参数" + (i + 1)); + commandParams1.add(commandParam); + } + return commandParams1; + }) + .orElse(null); + } + +} diff --git a/modules/server/src/main/java/io/jpom/controller/script/ScriptController.java b/modules/server/src/main/java/io/jpom/controller/script/ScriptController.java index c864de551..748b85fce 100644 --- a/modules/server/src/main/java/io/jpom/controller/script/ScriptController.java +++ b/modules/server/src/main/java/io/jpom/controller/script/ScriptController.java @@ -30,7 +30,6 @@ import io.jpom.common.*; import io.jpom.common.forward.NodeForward; import io.jpom.common.forward.NodeUrl; import io.jpom.common.validator.ValidatorItem; -import top.jpom.model.PageResultDto; import io.jpom.model.data.NodeModel; import io.jpom.model.script.ScriptModel; import io.jpom.model.user.UserModel; @@ -38,6 +37,7 @@ import io.jpom.permission.ClassFeature; import io.jpom.permission.Feature; import io.jpom.permission.MethodFeature; import io.jpom.permission.SystemPermission; +import io.jpom.script.CommandParam; import io.jpom.service.node.script.NodeScriptServer; import io.jpom.service.script.ScriptExecuteLogServer; import io.jpom.service.script.ScriptServer; @@ -48,6 +48,7 @@ import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; +import top.jpom.model.PageResultDto; import javax.servlet.http.HttpServletRequest; import java.io.File; @@ -118,7 +119,7 @@ public class ScriptController extends BaseServerController { scriptModel.setName(name); scriptModel.setNodeIds(nodeIds); scriptModel.setDescription(description); - scriptModel.setDefArgs(defArgs); + scriptModel.setDefArgs(CommandParam.checkStr(defArgs)); Assert.hasText(scriptModel.getContext(), "内容为空"); // diff --git a/modules/server/src/main/java/io/jpom/controller/ssh/CommandInfoController.java b/modules/server/src/main/java/io/jpom/controller/ssh/CommandInfoController.java index 84b5f1085..0a65099a8 100644 --- a/modules/server/src/main/java/io/jpom/controller/ssh/CommandInfoController.java +++ b/modules/server/src/main/java/io/jpom/controller/ssh/CommandInfoController.java @@ -35,6 +35,7 @@ import io.jpom.permission.ClassFeature; import io.jpom.permission.Feature; import io.jpom.permission.MethodFeature; import io.jpom.permission.SystemPermission; +import io.jpom.script.CommandParam; import io.jpom.service.node.command.CommandExecLogService; import io.jpom.service.node.command.CommandService; import io.jpom.service.user.TriggerTokenLogServer; @@ -48,7 +49,6 @@ import javax.servlet.http.HttpServletRequest; import java.io.File; import java.io.IOException; import java.util.HashMap; -import java.util.List; import java.util.Map; /** @@ -104,7 +104,7 @@ public class CommandInfoController extends BaseServerController { */ @RequestMapping(value = "edit", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE) @Feature(method = MethodFeature.EDIT) - public JsonMessage edit(@RequestBody JSONObject data) { + public JsonMessage edit(@RequestBody JSONObject data, HttpServletRequest request) { String name = data.getString("name"); String command = data.getString("command"); String desc = data.getString("desc"); @@ -121,22 +121,13 @@ public class CommandInfoController extends BaseServerController { commandModel.setSshIds(data.getString("sshIds")); commandModel.setAutoExecCron(autoExecCron); // - if (StrUtil.isNotEmpty(defParams)) { - List params = CommandModel.params(defParams); - if (params == null) { - commandModel.setDefParams(StrUtil.EMPTY); - } else { - commandModel.setDefParams(JSONObject.toJSONString(params)); - } - } else { - commandModel.setDefParams(StrUtil.EMPTY); - } + commandModel.setDefParams(CommandParam.checkStr(defParams)); if (StrUtil.isEmpty(id)) { commandService.insert(commandModel); } else { commandModel.setId(id); - commandService.updateById(commandModel, getRequest()); + commandService.updateById(commandModel, request); } return JsonMessage.success("操作成功"); } diff --git a/modules/server/src/main/java/io/jpom/model/data/CommandModel.java b/modules/server/src/main/java/io/jpom/model/data/CommandModel.java index 4679371a4..f9ef63164 100644 --- a/modules/server/src/main/java/io/jpom/model/data/CommandModel.java +++ b/modules/server/src/main/java/io/jpom/model/data/CommandModel.java @@ -22,15 +22,11 @@ */ package io.jpom.model.data; -import io.jpom.model.BaseJsonModel; import io.jpom.model.BaseWorkspaceModel; -import io.jpom.util.StringUtil; import lombok.Data; import lombok.EqualsAndHashCode; import top.jpom.h2db.TableName; -import java.util.List; - /** * 指令信息 * @@ -53,10 +49,6 @@ public class CommandModel extends BaseWorkspaceModel { * 指令内容 */ private String command; - /** - * 命令类型,0-shell,1-powershell - */ - private Integer type; /** * 命令默认参数 */ @@ -73,21 +65,4 @@ public class CommandModel extends BaseWorkspaceModel { * 触发器 token */ private String triggerToken; - - public List params() { - return params(getDefParams()); - } - - public static List params(String defParams) { - return StringUtil.jsonConvertArray(defParams, CommandParam.class); - } - - @Data - @EqualsAndHashCode(callSuper = true) - public static class CommandParam extends BaseJsonModel { - /** - * 参数值 - */ - private String value; - } } diff --git a/modules/server/src/main/java/io/jpom/model/node/ScriptCacheModel.java b/modules/server/src/main/java/io/jpom/model/node/ScriptCacheModel.java index 2aa56739e..6151b75f9 100644 --- a/modules/server/src/main/java/io/jpom/model/node/ScriptCacheModel.java +++ b/modules/server/src/main/java/io/jpom/model/node/ScriptCacheModel.java @@ -23,6 +23,7 @@ package io.jpom.model.node; import io.jpom.model.BaseNodeModel; +import io.jpom.script.CommandParam; import lombok.Data; import lombok.EqualsAndHashCode; import top.jpom.h2db.TableName; @@ -79,4 +80,8 @@ public class ScriptCacheModel extends BaseNodeModel { public void dataId(String id) { setScriptId(id); } + + public void setDefArgs(String defArgs) { + this.defArgs = CommandParam.convertToParam(defArgs); + } } diff --git a/modules/server/src/main/java/io/jpom/model/script/ScriptModel.java b/modules/server/src/main/java/io/jpom/model/script/ScriptModel.java index f9fa4d3b9..bbbc16267 100644 --- a/modules/server/src/main/java/io/jpom/model/script/ScriptModel.java +++ b/modules/server/src/main/java/io/jpom/model/script/ScriptModel.java @@ -28,6 +28,7 @@ import cn.hutool.core.util.StrUtil; import io.jpom.JpomApplication; import io.jpom.common.Const; import io.jpom.model.BaseWorkspaceModel; +import io.jpom.script.CommandParam; import io.jpom.system.ExtConfigBean; import io.jpom.util.CommandUtil; import io.jpom.util.FileUtils; @@ -76,6 +77,9 @@ public class ScriptModel extends BaseWorkspaceModel { */ private String triggerToken; + public void setDefArgs(String defArgs) { + this.defArgs = CommandParam.convertToParam(defArgs); + } public File scriptPath() { return scriptPath(getId()); diff --git a/modules/server/src/main/java/io/jpom/service/node/command/CommandService.java b/modules/server/src/main/java/io/jpom/service/node/command/CommandService.java index 796b52542..fc7c027b1 100644 --- a/modules/server/src/main/java/io/jpom/service/node/command/CommandService.java +++ b/modules/server/src/main/java/io/jpom/service/node/command/CommandService.java @@ -35,7 +35,6 @@ import cn.hutool.db.Entity; import cn.hutool.extra.ssh.ChannelType; import cn.hutool.extra.ssh.JschUtil; import cn.hutool.system.SystemUtil; -import com.alibaba.fastjson2.JSONObject; import com.jcraft.jsch.ChannelExec; import io.jpom.common.BaseServerController; import io.jpom.cron.CronUtils; @@ -46,6 +45,7 @@ import io.jpom.model.data.CommandExecLogModel; import io.jpom.model.data.CommandModel; import io.jpom.model.data.SshModel; import io.jpom.model.user.UserModel; +import io.jpom.script.CommandParam; import io.jpom.service.ITriggerToken; import io.jpom.service.h2db.BaseWorkspaceService; import io.jpom.service.node.ssh.SshService; @@ -63,7 +63,6 @@ import java.io.InputStream; import java.nio.charset.Charset; import java.util.List; import java.util.Map; -import java.util.stream.Collectors; /** * 命令管理 @@ -199,12 +198,11 @@ public class CommandService extends BaseWorkspaceService implement */ public String executeBatch(CommandModel commandModel, String params, String nodes, int triggerExecType) { Assert.notNull(commandModel, "没有对应对命令"); - List commandParams = CommandModel.params(params); List sshIds = StrUtil.split(nodes, StrUtil.COMMA, true, true); Assert.notEmpty(sshIds, "请选择 ssh 节点"); String batchId = IdUtil.fastSimpleUUID(); for (String sshId : sshIds) { - this.executeItem(commandModel, commandParams, sshId, batchId, triggerExecType); + this.executeItem(commandModel, params, sshId, batchId, triggerExecType); } return batchId; } @@ -217,7 +215,7 @@ public class CommandService extends BaseWorkspaceService implement * @param sshId ssh id * @param batchId 批次ID */ - private void executeItem(CommandModel commandModel, List commandParams, String sshId, String batchId, int triggerExecType) { + private void executeItem(CommandModel commandModel, String commandParams, String sshId, String batchId, int triggerExecType) { SshModel sshModel = sshService.getByKey(sshId, false); CommandExecLogModel commandExecLogModel = new CommandExecLogModel(); @@ -232,13 +230,7 @@ public class CommandService extends BaseWorkspaceService implement } commandExecLogModel.setStatus(CommandExecLogModel.Status.ING.getCode()); // 拼接参数 - String commandParamsLine; - if (commandParams != null) { - commandExecLogModel.setParams(JSONObject.toJSONString(commandParams)); - commandParamsLine = commandParams.stream().map(CommandModel.CommandParam::getValue).collect(Collectors.joining(StrUtil.SPACE)); - } else { - commandParamsLine = StrUtil.EMPTY; - } + String commandParamsLine = CommandParam.toCommandLine(commandParams); commandExecLogService.insert(commandExecLogModel); ThreadUtil.execute(() -> { @@ -372,7 +364,6 @@ public class CommandService extends BaseWorkspaceService implement update.setId(exits.getId()); update.setCommand(data.getCommand()); update.setDesc(data.getDesc()); - update.setType(data.getType()); update.setDefParams(data.getDefParams()); update.setAutoExecCron(data.getAutoExecCron()); super.updateById(update); diff --git a/modules/server/src/main/java/io/jpom/socket/ServerScriptProcessBuilder.java b/modules/server/src/main/java/io/jpom/socket/ServerScriptProcessBuilder.java index 6a7f8d3d3..96f97de23 100644 --- a/modules/server/src/main/java/io/jpom/socket/ServerScriptProcessBuilder.java +++ b/modules/server/src/main/java/io/jpom/socket/ServerScriptProcessBuilder.java @@ -36,6 +36,7 @@ import io.jpom.common.JsonMessage; import io.jpom.model.EnvironmentMapBuilder; import io.jpom.model.script.ScriptModel; import io.jpom.script.BaseRunScript; +import io.jpom.script.CommandParam; import io.jpom.service.system.WorkspaceEnvVarService; import io.jpom.system.ExtConfigBean; import io.jpom.util.CommandUtil; @@ -79,7 +80,7 @@ public class ServerScriptProcessBuilder extends BaseRunScript implements Runnabl // String script = FileUtil.getAbsolutePath(scriptFile); processBuilder = new ProcessBuilder(); - List command = StrUtil.splitTrim(args, StrUtil.SPACE); + List command = CommandParam.toCommandList(args); command.add(0, script); CommandUtil.paddingPrefix(command); log.debug(CollUtil.join(command, StrUtil.SPACE)); diff --git a/modules/server/src/main/java/io/jpom/socket/handler/ServerScriptHandler.java b/modules/server/src/main/java/io/jpom/socket/handler/ServerScriptHandler.java index a51392b31..351825c21 100644 --- a/modules/server/src/main/java/io/jpom/socket/handler/ServerScriptHandler.java +++ b/modules/server/src/main/java/io/jpom/socket/handler/ServerScriptHandler.java @@ -27,6 +27,7 @@ import cn.hutool.extra.spring.SpringUtil; import com.alibaba.fastjson2.JSONObject; import io.jpom.common.BaseServerController; import io.jpom.common.Const; +import io.jpom.common.JsonMessage; import io.jpom.model.script.ScriptExecuteLogModel; import io.jpom.model.script.ScriptModel; import io.jpom.model.user.UserModel; @@ -88,7 +89,10 @@ public class ServerScriptHandler extends BaseProxyHandler { json.put(Const.SOCKET_MSG_TAG, Const.SOCKET_MSG_TAG); json.put("executeId", executeId); ServerScriptProcessBuilder.addWatcher(scriptModel, executeId, args, session); - this.sendMsg(session, json.toString()); + JsonMessage jsonMessage = new JsonMessage<>(200, "开始执行"); + JSONObject jsonObject = jsonMessage.toJson(); + jsonObject.putAll(json); + this.sendMsg(session, jsonObject.toString()); break; } case stop: { diff --git a/modules/server/src/main/resources/sql-view/alter.all.v1.3.csv b/modules/server/src/main/resources/sql-view/alter.all.v1.3.csv index c853b0132..1898f9e21 100644 --- a/modules/server/src/main/resources/sql-view/alter.all.v1.3.csv +++ b/modules/server/src/main/resources/sql-view/alter.all.v1.3.csv @@ -15,3 +15,4 @@ DROP,DOCKER_INFO,failureMsg DROP,USEROPERATELOGV1,reqId ADD,USEROPERATELOGV1,workspaceName,String,50,,工作空间名 ADD,USEROPERATELOGV1,username,String,50,,用户名 +DROP,COMMAND_INFO,type, diff --git a/modules/server/src/main/resources/sql-view/table.all.v1.0.csv b/modules/server/src/main/resources/sql-view/table.all.v1.0.csv index dbea27ef7..1d81cca03 100644 --- a/modules/server/src/main/resources/sql-view/table.all.v1.0.csv +++ b/modules/server/src/main/resources/sql-view/table.all.v1.0.csv @@ -287,7 +287,6 @@ COMMAND_INFO,workspaceId,String,50,,true,false,所属工作空间, COMMAND_INFO,name,String,100,,false,false,命令名称, COMMAND_INFO,desc,String,500,,false,false,命令描述, COMMAND_INFO,command,TEXT,,,false,false,指令内容, -COMMAND_INFO,type,Integer,,0,false,false,命令类型,0-shell,1-powershell, COMMAND_INFO,defParams,TEXT,,,false,false,命令参数, COMMAND_INFO,sshIds,TEXT,,,false,false,绑定的ssh id, COMMAND_INFO,autoExecCron,String,100,,false,false,自动执行表达式, diff --git a/web-vue/src/pages/node/node-layout/other/script-console.vue b/web-vue/src/pages/node/node-layout/other/script-console.vue index f57ee256a..71a7852db 100644 --- a/web-vue/src/pages/node/node-layout/other/script-console.vue +++ b/web-vue/src/pages/node/node-layout/other/script-console.vue @@ -16,10 +16,29 @@ - - - - + + + + + + + + + + + + + + + + + + + 添加参数 @@ -52,8 +71,9 @@ export default { scriptStatus: 0, editArgs: false, temp: { - args: "", + // args: "", }, + commandParams: [], // 日志内容 // logContext: "loading ...", btnLoading: true, @@ -67,7 +87,11 @@ export default { }, mounted() { this.initWebSocket(); - this.temp.args = this.defArgs; + if (typeof this.defArgs === "string" && this.defArgs) { + this.commandParams = JSON.parse(this.defArgs); + } else { + this.commandParams = []; + } }, beforeDestroy() { if (this.socket) { @@ -145,7 +169,7 @@ export default { const data = { op: op, scriptId: this.scriptId, - args: this.temp.args, + args: JSON.stringify(this.commandParams), executeId: this.temp.executeId, }; this.socket.send(JSON.stringify(data)); diff --git a/web-vue/src/pages/node/node-layout/other/script-list.vue b/web-vue/src/pages/node/node-layout/other/script-list.vue index 970c0d03f..a4f4e1ecc 100644 --- a/web-vue/src/pages/node/node-layout/other/script-list.vue +++ b/web-vue/src/pages/node/node-layout/other/script-list.vue @@ -53,8 +53,28 @@ - + + +
+ + + + + + + + + + + + + + +
+ + 添加参数
@@ -118,6 +138,7 @@ export default { name: [{ required: true, message: "Please input Script name", trigger: "blur" }], context: [{ required: true, message: "Please input Script context", trigger: "blur" }], }, + commandParams: [], }; }, computed: { @@ -144,14 +165,13 @@ export default { this.loading = false; }); }, - parseTime(v) { - return parseTime(v); - }, + parseTime, // 添加 handleAdd() { this.temp = { type: "add", }; + this.commandParams = []; this.editScriptVisible = true; }, // 修改 @@ -161,6 +181,7 @@ export default { nodeId: this.node.id, }).then((res) => { this.temp = Object.assign({}, res.data); + this.commandParams = this.temp.defArgs ? JSON.parse(this.temp.defArgs) : []; // this.editScriptVisible = true; }); @@ -173,6 +194,19 @@ export default { }); return; } + if (this.commandParams && this.commandParams.length > 0) { + for (let i = 0; i < this.commandParams.length; i++) { + if (!this.commandParams[i].desc) { + this.$notification.error({ + message: "请填写第" + (i + 1) + "个参数的描述", + }); + return false; + } + } + this.temp.defArgs = JSON.stringify(this.commandParams); + } else { + this.temp.defArgs = ""; + } // 检验表单 this.$refs["editScriptForm"].validate((valid) => { if (!valid) { diff --git a/web-vue/src/pages/node/script-list.vue b/web-vue/src/pages/node/script-list.vue index 5b1990a53..ed07faaee 100644 --- a/web-vue/src/pages/node/script-list.vue +++ b/web-vue/src/pages/node/script-list.vue @@ -83,8 +83,28 @@ - + + +
+ + + + + + + + + + + + + + +
+ + 添加参数
@@ -231,6 +251,7 @@ export default { context: [{ required: true, message: "Please input Script context", trigger: "blur" }], }, triggerVisible: false, + commandParams: [], }; }, computed: { @@ -263,9 +284,7 @@ export default { this.loading = false; }); }, - parseTime(v) { - return parseTime(v); - }, + parseTime, // 修改 handleEdit(record) { itemScript({ @@ -275,6 +294,7 @@ export default { if (res.code === 200) { this.temp = Object.assign({}, res.data); this.temp.nodeId = record.nodeId; + this.commandParams = this.temp.defArgs ? JSON.parse(this.temp.defArgs) : []; // this.editScriptVisible = true; } @@ -293,6 +313,19 @@ export default { if (!valid) { return false; } + if (this.commandParams && this.commandParams.length > 0) { + for (let i = 0; i < this.commandParams.length; i++) { + if (!this.commandParams[i].desc) { + this.$notification.error({ + message: "请填写第" + (i + 1) + "个参数的描述", + }); + return false; + } + } + this.temp.defArgs = JSON.stringify(this.commandParams); + } else { + this.temp.defArgs = ""; + } // 提交数据 editScript(this.temp).then((res) => { if (res.code === 200) { diff --git a/web-vue/src/pages/script/script-console.vue b/web-vue/src/pages/script/script-console.vue index ea799414b..b24f2673f 100644 --- a/web-vue/src/pages/script/script-console.vue +++ b/web-vue/src/pages/script/script-console.vue @@ -15,10 +15,32 @@ - - - + + + + + + + + + + + + + + + + + + + + 添加参数 @@ -47,11 +69,12 @@ export default { scriptStatus: 0, editArgs: false, temp: { - args: "", + // args: "", }, // 日志内容 // logContext: "loading ...", btnLoading: true, + commandParams: [], }; }, computed: { @@ -62,7 +85,11 @@ export default { }, mounted() { this.initWebSocket(); - this.temp.args = this.defArgs; + if (typeof this.defArgs === "string" && this.defArgs) { + this.commandParams = JSON.parse(this.defArgs); + } else { + this.commandParams = []; + } }, beforeDestroy() { if (this.socket) { @@ -139,7 +166,7 @@ export default { const data = { op: op, id: this.id, - args: this.temp.args, + args: JSON.stringify(this.commandParams), executeId: this.temp.executeId, }; this.socket.send(JSON.stringify(data)); diff --git a/web-vue/src/pages/script/script-list.vue b/web-vue/src/pages/script/script-list.vue index 78bbb2bef..f5d65ab73 100644 --- a/web-vue/src/pages/script/script-list.vue +++ b/web-vue/src/pages/script/script-list.vue @@ -90,8 +90,28 @@ - + + +
+ + + + + + + + + + + + + + +
+ + 添加参数
@@ -259,6 +279,7 @@ export default { syncToWorkspaceVisible: false, workspaceList: [], triggerVisible: false, + commandParams: [], }; }, computed: { @@ -304,15 +325,16 @@ export default { }, createScript() { this.temp = {}; + this.commandParams = []; this.editScriptVisible = true; this.getAllNodeList(); }, // 修改 handleEdit(record) { this.temp = Object.assign({}, record); - // record; - // - // this.temp.; + + this.commandParams = record.defArgs ? JSON.parse(record.defArgs) : []; + this.temp = { ...this.temp, chooseNode: record.nodeIds ? record.nodeIds.split(",") : [] }; this.editScriptVisible = true; this.getAllNodeList(); @@ -324,6 +346,19 @@ export default { if (!valid) { return false; } + if (this.commandParams && this.commandParams.length > 0) { + for (let i = 0; i < this.commandParams.length; i++) { + if (!this.commandParams[i].desc) { + this.$notification.error({ + message: "请填写第" + (i + 1) + "个参数的描述", + }); + return false; + } + } + this.temp.defArgs = JSON.stringify(this.commandParams); + } else { + this.temp.defArgs = ""; + } // 提交数据 this.temp.nodeIds = this.temp?.chooseNode?.join(","); editScript(this.temp).then((res) => { diff --git a/web-vue/src/pages/ssh/command.vue b/web-vue/src/pages/ssh/command.vue index fa8056681..67c8ffc61 100644 --- a/web-vue/src/pages/ssh/command.vue +++ b/web-vue/src/pages/ssh/command.vue @@ -83,16 +83,24 @@ -
-
- -
-
- -
+
+ + + + + + + + + + + + + +
- 添加参数 + 添加参数 @@ -126,16 +134,27 @@ - -
-
- -
-
- -
-
- 添加参数 + + + + + + + + + + + + + + + + + 添加参数 @@ -327,6 +346,14 @@ export default { } this.formLoading = true; if (this.commandParams && this.commandParams.length > 0) { + for (let i = 0; i < this.commandParams.length; i++) { + if (!this.commandParams[i].desc) { + this.$notification.error({ + message: "请填写第" + (i + 1) + "个参数的描述", + }); + return false; + } + } this.temp.defParams = JSON.stringify(this.commandParams); } else { this.temp.defParams = ""; @@ -423,19 +450,7 @@ export default { this.sshList = res.data || []; }); }, - // 添加命令参数 - handleAddParam() { - this.commandParams.push({}); - }, - // 删除命令参数 - handleDeleteParam(index) { - this.commandParams.splice(index, 1); - }, - handleParamChange(check) { - if (!check) { - this.commandParams = []; - } - }, + handleExecuteCommandOk() { if (!this.chooseSsh || this.chooseSsh.length <= 0) { this.$notification.error({ @@ -542,22 +557,4 @@ export default { overflow-y: scroll; max-height: 300px; } - -.params-item { - display: flex; - align-items: center; - border-bottom: 1px #e2e2e2 solid; - padding-bottom: 5px; -} - -.item-info { - display: inline-block; - width: 90%; -} - -.item-icon { - display: inline-block; - width: 10%; - text-align: center; -} diff --git a/web-vue/src/pages/system/workspace.vue b/web-vue/src/pages/system/workspace.vue index 5c8e22f0d..fcd9862aa 100644 --- a/web-vue/src/pages/system/workspace.vue +++ b/web-vue/src/pages/system/workspace.vue @@ -113,20 +113,17 @@ export default { customRender: (text) => { return parseTime(text); }, - width: 170, + width: "170px", }, { title: "修改时间", dataIndex: "modifyTimeMillis", customRender: (text) => { - if (!text) { - return ""; - } return parseTime(text); }, sorter: true, - width: 180, + width: "170px", }, { title: "操作", dataIndex: "operation", align: "center", scopedSlots: { customRender: "operation" }, width: "220px" }, ],