首页接口重构

This commit is contained in:
2026-04-13 12:46:20 +08:00
parent 2a76f48981
commit adff52a3d7
5 changed files with 147 additions and 245 deletions

View File

@@ -0,0 +1,19 @@
package com.jeesite.modules.apps.Module;
import lombok.Data;
import java.io.Serializable;
@Data
public class DockerInfo implements Serializable {
private String username; // 登录账号
private String password; // 登录密码
private String rootPath; // 初始目录
private String authType; // 认证方式
private String privateKey; // 密钥内容
private String hostIp; // 主机域名
private Integer hostPort; // 主机端口
private String containerId;
public DockerInfo(){}
}

View File

@@ -1,9 +1,98 @@
package com.jeesite.modules.apps.web.docker; package com.jeesite.modules.apps.web.docker;
import com.jeesite.modules.apps.Module.ContainerInfo;
import com.jeesite.modules.apps.Module.DockerInfo;
import com.jeesite.modules.apps.Module.DockerResult;
import com.jeesite.modules.biz.dao.MySftpAccountsDao;
import com.jeesite.modules.biz.entity.MySftpAccounts;
import com.jeesite.modules.utils.DockerUtil;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.List;
@Controller @Controller
@RequestMapping(value = "${adminPath}/desktop/analysis") @RequestMapping(value = "${adminPath}/docker/analysis")
public class DockerController { public class DockerController {
@Resource
private MySftpAccountsDao mySftpAccountsDao;
/**
* 启动容器
*/
@RequestMapping(value = "start")
@ResponseBody
public DockerResult start(DockerInfo dockerInfo) {
return DockerUtil.start(dockerInfo);
}
/**
* 停止容器
*/
@RequestMapping(value = "stop")
@ResponseBody
public DockerResult stop(DockerInfo dockerInfo) {
return DockerUtil.stop(dockerInfo);
}
/**
* 重启容器
*/
@RequestMapping(value = "restart")
@ResponseBody
public DockerResult restart(DockerInfo dockerInfo) {
return DockerUtil.restart(dockerInfo);
}
/**
* 获取容器详情
*/
@RequestMapping(value = "inspect")
@ResponseBody
public DockerResult inspect(DockerInfo dockerInfo) {
return DockerUtil.inspect(dockerInfo);
}
/**
* 获取容器日志
*/
@RequestMapping(value = "logs")
@ResponseBody
public DockerResult logs(DockerInfo dockerInfo) {
return DockerUtil.getLogs(dockerInfo, 20000, true);
}
/**
* 获取容器列表
*/
@RequestMapping(value = "listAll")
@ResponseBody
public List<ContainerInfo> listAll(DockerInfo dockerInfo) {
return DockerUtil.listContainers(dockerInfo, true);
}
/**
* 获取服务列表
*/
@RequestMapping(value = "listInfo")
@ResponseBody
public List<DockerInfo> listInfo() {
List<MySftpAccounts> accountsList = mySftpAccountsDao.findList(new MySftpAccounts());
return accountsList.stream()
.map(account -> {
DockerInfo info = new DockerInfo();
info.setHostIp(account.getHostIp());
info.setHostPort(account.getHostPort());
info.setUsername(account.getUsername());
info.setPassword(account.getPassword());
info.setRootPath(account.getRootPath());
info.setAuthType(account.getAuthType());
info.setPrivateKey(account.getPrivateKey());
return info;
})
.toList();
}
} }

View File

@@ -39,6 +39,14 @@ import java.io.Serial;
@Column(name = "account_remark", attrName = "accountRemark", label = "账号备注"), @Column(name = "account_remark", attrName = "accountRemark", label = "账号备注"),
@Column(name = "update_time", attrName = "updateTime", label = "更新时间", isQuery = false, isUpdateForce = true), @Column(name = "update_time", attrName = "updateTime", label = "更新时间", isQuery = false, isUpdateForce = true),
@Column(name = "ustatus", attrName = "ustatus", label = "状态"), @Column(name = "ustatus", attrName = "ustatus", label = "状态"),
}, joinTable = {
@JoinTable(type = Type.LEFT_JOIN, entity = MySftpHosts.class, alias = "b",
on = "a.host_id = b.host_id", attrName = "this",
columns = {
@Column(name = "host_ip", attrName = "hostIp", label = "主机域名"),
@Column(name = "host_port", attrName = "hostPort", label = "主机端口"),
@Column(name = "host_name", attrName = "hostName", label = "主机名称"),
}),
}, orderBy = "a.create_time DESC" }, orderBy = "a.create_time DESC"
) )
@Data @Data
@@ -59,9 +67,9 @@ public class MySftpAccounts extends DataEntity<MySftpAccounts> implements Serial
private Date updateTime; // 更新时间 private Date updateTime; // 更新时间
private String ustatus; // 状态 private String ustatus; // 状态
private String hostIp; // 主机域名 private String hostIp; // 主机域名
private Integer hostPort; // 主机端口 private Integer hostPort; // 主机端口
private String hostName; // 主机名称 private String hostName; // 主机名称
public MySftpAccounts() { public MySftpAccounts() {
this(null); this(null);
@@ -71,116 +79,6 @@ public class MySftpAccounts extends DataEntity<MySftpAccounts> implements Serial
this.hostId = hostId; this.hostId = hostId;
} }
@JsonFormat(pattern = "yyyy-MM-dd HH:mm")
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public String getAccountId() {
return accountId;
}
public void setAccountId(String accountId) {
this.accountId = accountId;
}
public MySftpHosts getHostId() {
return hostId;
}
public void setHostId(MySftpHosts hostId) {
this.hostId = hostId;
}
@NotBlank(message = "登录账号不能为空")
@Size(min = 0, max = 100, message = "登录账号长度不能超过 100 个字符")
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
@NotBlank(message = "登录密码不能为空")
@Size(min = 0, max = 255, message = "登录密码长度不能超过 255 个字符")
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@NotBlank(message = "初始目录不能为空")
@Size(min = 0, max = 255, message = "初始目录长度不能超过 255 个字符")
public String getRootPath() {
return rootPath;
}
public void setRootPath(String rootPath) {
this.rootPath = rootPath;
}
@NotBlank(message = "认证方式不能为空")
@Size(min = 0, max = 12, message = "认证方式长度不能超过 12 个字符")
public String getAuthType() {
return authType;
}
public void setAuthType(String authType) {
this.authType = authType;
}
public String getPrivateKey() {
return privateKey;
}
public void setPrivateKey(String privateKey) {
this.privateKey = privateKey;
}
@JsonFormat(pattern = "yyyy-MM-dd HH:mm")
public Date getExpireTime() {
return expireTime;
}
public void setExpireTime(Date expireTime) {
this.expireTime = expireTime;
}
@Size(min = 0, max = 255, message = "账号备注长度不能超过 255 个字符")
public String getAccountRemark() {
return accountRemark;
}
public void setAccountRemark(String accountRemark) {
this.accountRemark = accountRemark;
}
@JsonFormat(pattern = "yyyy-MM-dd HH:mm")
public Date getUpdateTime() {
return updateTime;
}
public void setUpdateTime(Date updateTime) {
this.updateTime = updateTime;
}
@NotBlank(message = "状态不能为空")
@Size(min = 0, max = 12, message = "状态长度不能超过 12 个字符")
public String getUstatus() {
return ustatus;
}
public void setUstatus(String ustatus) {
this.ustatus = ustatus;
}
public Date getCreateTime_gte() { public Date getCreateTime_gte() {
return sqlMap.getWhere().getValue("create_time", QueryType.GTE); return sqlMap.getWhere().getValue("create_time", QueryType.GTE);
} }

View File

@@ -22,6 +22,7 @@ import com.jeesite.common.utils.excel.annotation.ExcelField.Align;
import com.jeesite.common.utils.excel.annotation.ExcelFields; import com.jeesite.common.utils.excel.annotation.ExcelFields;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import lombok.Setter;
import java.io.Serial; import java.io.Serial;
@@ -75,87 +76,9 @@ public class MySftpHosts extends DataEntity<MySftpHosts> implements Serializabl
super(id); super(id);
} }
@JsonFormat(pattern = "yyyy-MM-dd HH:mm")
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public String getHostId() {
return hostId;
}
public void setHostId(String hostId) {
this.hostId = hostId;
}
@NotBlank(message="主机域名不能为空")
@Size(min=0, max=64, message="主机域名长度不能超过 64 个字符")
public String getHostIp() {
return hostIp;
}
public void setHostIp(String hostIp) {
this.hostIp = hostIp;
}
@NotNull(message="主机端口不能为空")
public Integer getHostPort() {
return hostPort;
}
public void setHostPort(Integer hostPort) {
this.hostPort = hostPort;
}
@NotBlank(message="主机名称不能为空")
@Size(min=0, max=100, message="主机名称长度不能超过 100 个字符")
public String getHostName() {
return hostName;
}
public void setHostName(String hostName) {
this.hostName = hostName;
}
@Size(min=0, max=255, message="备注说明长度不能超过 255 个字符")
public String getHostRemark() {
return hostRemark;
}
public void setHostRemark(String hostRemark) {
this.hostRemark = hostRemark;
}
@JsonFormat(pattern = "yyyy-MM-dd HH:mm")
public Date getUpdateTime() {
return updateTime;
}
public void setUpdateTime(Date updateTime) {
this.updateTime = updateTime;
}
@NotBlank(message="状态不能为空")
@Size(min=0, max=12, message="状态长度不能超过 12 个字符")
public String getUstatus() {
return ustatus;
}
public void setUstatus(String ustatus) {
this.ustatus = ustatus;
}
@Valid @Valid
public List<MySftpAccounts> getMySftpAccountsList() { public List<MySftpAccounts> getMySftpAccountsList() {
return mySftpAccountsList; return mySftpAccountsList;
} }
public void setMySftpAccountsList(List<MySftpAccounts> mySftpAccountsList) {
this.mySftpAccountsList = mySftpAccountsList;
}
} }

View File

@@ -2,8 +2,8 @@ package com.jeesite.modules.utils;
import com.jcraft.jsch.*; import com.jcraft.jsch.*;
import com.jeesite.modules.apps.Module.ContainerInfo; import com.jeesite.modules.apps.Module.ContainerInfo;
import com.jeesite.modules.apps.Module.DockerInfo;
import com.jeesite.modules.apps.Module.DockerResult; import com.jeesite.modules.apps.Module.DockerResult;
import com.jeesite.modules.biz.entity.MySftpAccounts;
import java.io.*; import java.io.*;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
@@ -20,65 +20,38 @@ public class DockerUtil {
private static final int SSH_TIMEOUT = 30000; private static final int SSH_TIMEOUT = 30000;
public static DockerResult start(MySftpAccounts account, String image, String name, public static DockerResult start(DockerInfo dockerInfo) {
String[] ports, String[] envs) { return exec(dockerInfo, "docker start " + dockerInfo.getContainerId());
StringBuilder cmd = new StringBuilder("docker run -d");
if (name != null && !name.isEmpty()) {
cmd.append(" --name ").append(name);
}
if (ports != null) {
for (String p : ports) cmd.append(" -p ").append(p);
}
if (envs != null) {
for (String e : envs) cmd.append(" -e \"").append(e).append("\"");
}
cmd.append(" ").append(image);
return exec(account, cmd.toString());
} }
public static DockerResult stop(MySftpAccounts account, String containerId) { public static DockerResult stop(DockerInfo dockerInfo) {
return exec(account, "docker stop " + containerId); return exec(dockerInfo, "docker stop " + dockerInfo.getContainerId());
} }
public static DockerResult restart(MySftpAccounts account, String containerId) { public static DockerResult restart(DockerInfo dockerInfo) {
return exec(account, "docker restart " + containerId); return exec(dockerInfo, "docker restart " + dockerInfo.getContainerId());
} }
public static DockerResult getLogs(MySftpAccounts account, String containerId, public static DockerResult getLogs(DockerInfo dockerInfo,
int tail, boolean timestamps) { int tail, boolean timestamps) {
String cmd = "docker logs" + (timestamps ? " -t" : "") String cmd = "docker logs" + (timestamps ? " -t" : "")
+ " --tail " + tail + " " + containerId; + " --tail " + tail + " " + dockerInfo.getContainerId();
return exec(account, cmd); return exec(dockerInfo, cmd);
} }
public static DockerResult list(MySftpAccounts account, boolean all) { public static DockerResult list(DockerInfo dockerInfo, boolean all) {
return exec(account, all ? "docker ps -a" : "docker ps"); return exec(dockerInfo, all ? "docker ps -a" : "docker ps");
} }
public static DockerResult remove(MySftpAccounts account, String containerId, boolean force) { public static DockerResult inspect(DockerInfo dockerInfo) {
String cmd = force return exec(dockerInfo, "docker inspect " + dockerInfo.getContainerId());
? "docker stop " + containerId + " && docker rm " + containerId
: "docker rm " + containerId;
return exec(account, cmd);
} }
public static DockerResult inspect(MySftpAccounts account, String containerId) { public static List<ContainerInfo> listContainers(DockerInfo dockerInfo, boolean all) {
return exec(account, "docker inspect " + containerId);
}
public static DockerResult pull(MySftpAccounts account, String image) {
return exec(account, "docker pull " + image);
}
public static DockerResult version(MySftpAccounts account) {
return exec(account, "docker version --format '{{json .}}'");
}
public static List<ContainerInfo> listContainers(MySftpAccounts account, boolean all) {
List<ContainerInfo> list = new ArrayList<>(); List<ContainerInfo> list = new ArrayList<>();
String cmd = (all ? "docker ps -a" : "docker ps") String cmd = (all ? "docker ps -a" : "docker ps")
+ " --format \"{{.ID}}|{{.Image}}|{{.Command}}|{{.CreatedAt}}|{{.Status}}|{{.Ports}}|{{.Names}}\""; + " --format \"{{.ID}}|{{.Image}}|{{.Command}}|{{.CreatedAt}}|{{.Status}}|{{.Ports}}|{{.Names}}\"";
DockerResult r = exec(account, cmd); DockerResult r = exec(dockerInfo, cmd);
if (!r.isSuccess()) { if (!r.isSuccess()) {
return new ArrayList<>(); return new ArrayList<>();
} }
@@ -99,22 +72,22 @@ public class DockerUtil {
return list; return list;
} }
public static DockerResult exec(MySftpAccounts account, String command) { public static DockerResult exec(DockerInfo dockerInfo, String command) {
JSch jsch = new JSch(); JSch jsch = new JSch();
Session session = null; Session session = null;
ChannelExec channel = null; ChannelExec channel = null;
try { try {
int port = account.getHostPort() != null ? account.getHostPort() : 22; int port = dockerInfo.getHostPort() != null ? dockerInfo.getHostPort() : 22;
session = jsch.getSession(account.getUsername(), account.getHostIp(), port); session = jsch.getSession(dockerInfo.getUsername(), dockerInfo.getHostIp(), port);
session.setTimeout(SSH_TIMEOUT); session.setTimeout(SSH_TIMEOUT);
if ("key".equalsIgnoreCase(account.getAuthType()) if ("key".equalsIgnoreCase(dockerInfo.getAuthType())
&& account.getPrivateKey() != null && !account.getPrivateKey().isEmpty()) { && dockerInfo.getPrivateKey() != null && !dockerInfo.getPrivateKey().isEmpty()) {
jsch.addIdentity("temp", jsch.addIdentity("temp",
account.getPrivateKey().getBytes(StandardCharsets.UTF_8), dockerInfo.getPrivateKey().getBytes(StandardCharsets.UTF_8),
null, null); null, null);
} else if (account.getPassword() != null && !account.getPassword().isEmpty()) { } else if (dockerInfo.getPassword() != null && !dockerInfo.getPassword().isEmpty()) {
session.setPassword(account.getPassword()); session.setPassword(dockerInfo.getPassword());
} else { } else {
return DockerResult.fail("SSH 认证信息不完整:缺少密码或私钥"); return DockerResult.fail("SSH 认证信息不完整:缺少密码或私钥");
} }
@@ -125,8 +98,8 @@ public class DockerUtil {
session.connect(SSH_TIMEOUT); session.connect(SSH_TIMEOUT);
channel = (ChannelExec) session.openChannel("exec"); channel = (ChannelExec) session.openChannel("exec");
String finalCmd = (account.getRootPath() != null && !account.getRootPath().isEmpty()) String finalCmd = (dockerInfo.getRootPath() != null && !dockerInfo.getRootPath().isEmpty())
? "cd " + account.getRootPath() + " && " + command ? "cd " + dockerInfo.getRootPath() + " && " + command
: command; : command;
channel.setCommand(finalCmd); channel.setCommand(finalCmd);
channel.setInputStream(null); channel.setInputStream(null);