⚡ 优化终端代码.
This commit is contained in:
@@ -19,12 +19,12 @@
|
|||||||
<a target="_blank"
|
<a target="_blank"
|
||||||
style="text-decoration: none !important;"
|
style="text-decoration: none !important;"
|
||||||
href="https://gitee.com/dromara/orion-visor/stargazers">
|
href="https://gitee.com/dromara/orion-visor/stargazers">
|
||||||
<img src="https://gitee.com/dromara/orion-visor/badge/star.svg?theme=dark" alt="star" />
|
<img src="https://gitee.com/dromara/orion-visor/badge/star.svg?theme=gvp" alt="star" />
|
||||||
</a>
|
</a>
|
||||||
<a target="_blank"
|
<a target="_blank"
|
||||||
style="text-decoration: none !important;"
|
style="text-decoration: none !important;"
|
||||||
href="https://gitee.com/dromara/orion-visor/members">
|
href="https://gitee.com/dromara/orion-visor/members">
|
||||||
<img src="https://gitee.com/dromara/orion-visor/badge/fork.svg?theme=dark" alt="fork" />
|
<img src="https://gitee.com/dromara/orion-visor/badge/fork.svg?theme=gvp" alt="fork" />
|
||||||
</a>
|
</a>
|
||||||
<a target="_blank"
|
<a target="_blank"
|
||||||
style="text-decoration: none !important;"
|
style="text-decoration: none !important;"
|
||||||
|
|||||||
@@ -19,12 +19,12 @@
|
|||||||
<a target="_blank"
|
<a target="_blank"
|
||||||
style="text-decoration: none !important;"
|
style="text-decoration: none !important;"
|
||||||
href="https://gitee.com/lijiahangmax/orion-visor/stargazers">
|
href="https://gitee.com/lijiahangmax/orion-visor/stargazers">
|
||||||
<img src="https://gitee.com/lijiahangmax/orion-visor/badge/star.svg?theme=dark" alt="star" />
|
<img src="https://gitee.com/lijiahangmax/orion-visor/badge/star.svg?theme=gvp" alt="star" />
|
||||||
</a>
|
</a>
|
||||||
<a target="_blank"
|
<a target="_blank"
|
||||||
style="text-decoration: none !important;"
|
style="text-decoration: none !important;"
|
||||||
href="https://gitee.com/lijiahangmax/orion-visor/members">
|
href="https://gitee.com/lijiahangmax/orion-visor/members">
|
||||||
<img src="https://gitee.com/lijiahangmax/orion-visor/badge/fork.svg?theme=dark" alt="fork" />
|
<img src="https://gitee.com/lijiahangmax/orion-visor/badge/fork.svg?theme=gvp" alt="fork" />
|
||||||
</a>
|
</a>
|
||||||
<a target="_blank"
|
<a target="_blank"
|
||||||
style="text-decoration: none !important;"
|
style="text-decoration: none !important;"
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ public class PageRequest implements IPageRequest {
|
|||||||
@Schema(description = "页码")
|
@Schema(description = "页码")
|
||||||
private int page;
|
private int page;
|
||||||
|
|
||||||
@Range(min = 1, max = 100, groups = Page.class)
|
@Range(min = 1, max = 200, groups = Page.class)
|
||||||
@Schema(description = "大小")
|
@Schema(description = "大小")
|
||||||
private int limit;
|
private int limit;
|
||||||
|
|
||||||
|
|||||||
@@ -68,7 +68,7 @@
|
|||||||
<template #extra="{ record }">
|
<template #extra="{ record }">
|
||||||
<a-space>
|
<a-space>
|
||||||
<!-- 更多操作 -->
|
<!-- 更多操作 -->
|
||||||
<a-dropdown trigger="hover">
|
<a-dropdown trigger="hover" :popup-max-height="false">
|
||||||
<icon-more class="card-extra-icon" />
|
<icon-more class="card-extra-icon" />
|
||||||
<template #content>
|
<template #content>
|
||||||
<!-- 修改 -->
|
<!-- 修改 -->
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import com.orion.visor.module.asset.handler.host.terminal.TerminalMessageDispatc
|
|||||||
import com.orion.visor.module.asset.handler.host.transfer.TransferMessageDispatcher;
|
import com.orion.visor.module.asset.handler.host.transfer.TransferMessageDispatcher;
|
||||||
import com.orion.visor.module.asset.interceptor.ExecLogTailInterceptor;
|
import com.orion.visor.module.asset.interceptor.ExecLogTailInterceptor;
|
||||||
import com.orion.visor.module.asset.interceptor.TerminalAccessInterceptor;
|
import com.orion.visor.module.asset.interceptor.TerminalAccessInterceptor;
|
||||||
|
import com.orion.visor.module.asset.interceptor.TerminalTransferInterceptor;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
|
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
|
||||||
@@ -28,6 +29,9 @@ public class AssetWebSocketConfiguration implements WebSocketConfigurer {
|
|||||||
@Resource
|
@Resource
|
||||||
private TerminalAccessInterceptor terminalAccessInterceptor;
|
private TerminalAccessInterceptor terminalAccessInterceptor;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private TerminalTransferInterceptor terminalTransferInterceptor;
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private ExecLogTailInterceptor execLogTailInterceptor;
|
private ExecLogTailInterceptor execLogTailInterceptor;
|
||||||
|
|
||||||
@@ -42,13 +46,13 @@ public class AssetWebSocketConfiguration implements WebSocketConfigurer {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
|
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
|
||||||
// 终端
|
// 终端会话
|
||||||
registry.addHandler(terminalMessageDispatcher, prefix + "/host/terminal/{accessToken}")
|
registry.addHandler(terminalMessageDispatcher, prefix + "/host/terminal/{accessToken}")
|
||||||
.addInterceptors(terminalAccessInterceptor)
|
.addInterceptors(terminalAccessInterceptor)
|
||||||
.setAllowedOrigins("*");
|
.setAllowedOrigins("*");
|
||||||
// 文件传输
|
// 文件传输
|
||||||
registry.addHandler(transferMessageDispatcher, prefix + "/host/transfer/{accessToken}")
|
registry.addHandler(transferMessageDispatcher, prefix + "/host/transfer/{transferToken}")
|
||||||
.addInterceptors(terminalAccessInterceptor)
|
.addInterceptors(terminalTransferInterceptor)
|
||||||
.setAllowedOrigins("*");
|
.setAllowedOrigins("*");
|
||||||
// 执行日志
|
// 执行日志
|
||||||
registry.addHandler(execLogTailHandler, prefix + "/exec/log/{token}")
|
registry.addHandler(execLogTailHandler, prefix + "/exec/log/{token}")
|
||||||
|
|||||||
@@ -49,5 +49,12 @@ public class HostTerminalController {
|
|||||||
return hostTerminalService.getTerminalAccessToken();
|
return hostTerminalService.getTerminalAccessToken();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GetMapping("/transfer")
|
||||||
|
@Operation(summary = "获取主机终端 transferToken")
|
||||||
|
@PreAuthorize("@ss.hasPermission('asset:host-terminal:access')")
|
||||||
|
public String getTerminalTransferToken() {
|
||||||
|
return hostTerminalService.getTerminalTransferToken();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import com.orion.lang.define.cache.key.CacheKeyBuilder;
|
|||||||
import com.orion.lang.define.cache.key.CacheKeyDefine;
|
import com.orion.lang.define.cache.key.CacheKeyDefine;
|
||||||
import com.orion.lang.define.cache.key.struct.RedisCacheStruct;
|
import com.orion.lang.define.cache.key.struct.RedisCacheStruct;
|
||||||
import com.orion.visor.module.asset.entity.dto.HostTerminalAccessDTO;
|
import com.orion.visor.module.asset.entity.dto.HostTerminalAccessDTO;
|
||||||
|
import com.orion.visor.module.asset.entity.dto.HostTerminalTransferDTO;
|
||||||
|
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
@@ -24,4 +25,12 @@ public interface HostTerminalCacheKeyDefine {
|
|||||||
.timeout(3, TimeUnit.MINUTES)
|
.timeout(3, TimeUnit.MINUTES)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
CacheKeyDefine HOST_TERMINAL_TRANSFER = new CacheKeyBuilder()
|
||||||
|
.key("host:terminal:transfer:{}")
|
||||||
|
.desc("主机终端传输token ${token}")
|
||||||
|
.type(HostTerminalTransferDTO.class)
|
||||||
|
.struct(RedisCacheStruct.STRING)
|
||||||
|
.timeout(3, TimeUnit.MINUTES)
|
||||||
|
.build();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,10 +42,6 @@ public class CommandSnippetDO extends BaseDO {
|
|||||||
@TableField("name")
|
@TableField("name")
|
||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
@Schema(description = "触发前缀")
|
|
||||||
@TableField("prefix")
|
|
||||||
private String prefix;
|
|
||||||
|
|
||||||
@Schema(description = "代码片段")
|
@Schema(description = "代码片段")
|
||||||
@TableField("command")
|
@TableField("command")
|
||||||
private String command;
|
private String command;
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ import javax.annotation.Resource;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 终端拦截器
|
* 终端访问拦截器
|
||||||
*
|
*
|
||||||
* @author Jiahang Li
|
* @author Jiahang Li
|
||||||
* @version 1.0.0
|
* @version 1.0.0
|
||||||
@@ -34,11 +34,11 @@ public class TerminalAccessInterceptor implements HandshakeInterceptor {
|
|||||||
public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception {
|
public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception {
|
||||||
// 获取 accessToken
|
// 获取 accessToken
|
||||||
String accessToken = Urls.getUrlSource(request.getURI().getPath());
|
String accessToken = Urls.getUrlSource(request.getURI().getPath());
|
||||||
log.info("TerminalInterceptor-beforeHandshake start accessToken: {}", accessToken);
|
log.info("TerminalAccessInterceptor-beforeHandshake start accessToken: {}", accessToken);
|
||||||
// 获取连接数据
|
// 获取连接数据
|
||||||
HostTerminalAccessDTO access = hostTerminalService.getAccessInfoByToken(accessToken);
|
HostTerminalAccessDTO access = hostTerminalService.getAccessInfoByToken(accessToken);
|
||||||
if (access == null) {
|
if (access == null) {
|
||||||
log.error("TerminalInterceptor-beforeHandshake absent accessToken: {}", accessToken);
|
log.error("TerminalAccessInterceptor-beforeHandshake absent accessToken: {}", accessToken);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// 设置参数
|
// 设置参数
|
||||||
|
|||||||
@@ -0,0 +1,56 @@
|
|||||||
|
package com.orion.visor.module.asset.interceptor;
|
||||||
|
|
||||||
|
import com.orion.lang.utils.Urls;
|
||||||
|
import com.orion.visor.framework.common.constant.ExtraFieldConst;
|
||||||
|
import com.orion.visor.framework.common.meta.TraceIdHolder;
|
||||||
|
import com.orion.visor.framework.common.utils.Requests;
|
||||||
|
import com.orion.visor.module.asset.entity.dto.HostTerminalTransferDTO;
|
||||||
|
import com.orion.visor.module.asset.service.HostTerminalService;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.http.server.ServerHttpRequest;
|
||||||
|
import org.springframework.http.server.ServerHttpResponse;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.web.socket.WebSocketHandler;
|
||||||
|
import org.springframework.web.socket.server.HandshakeInterceptor;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 终端传输拦截器
|
||||||
|
*
|
||||||
|
* @author Jiahang Li
|
||||||
|
* @version 1.0.0
|
||||||
|
* @since 2023/12/27 23:53
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Component
|
||||||
|
public class TerminalTransferInterceptor implements HandshakeInterceptor {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private HostTerminalService hostTerminalService;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception {
|
||||||
|
// 获取 transferToken
|
||||||
|
String transferToken = Urls.getUrlSource(request.getURI().getPath());
|
||||||
|
log.info("TerminalTransferInterceptor-beforeHandshake start transferToken: {}", transferToken);
|
||||||
|
// 获取连接数据
|
||||||
|
HostTerminalTransferDTO transfer = hostTerminalService.getTransferInfoByToken(transferToken);
|
||||||
|
if (transfer == null) {
|
||||||
|
log.error("TerminalTransferInterceptor-beforeHandshake absent transferToken: {}", transferToken);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// 设置参数
|
||||||
|
attributes.put(ExtraFieldConst.USER_ID, transfer.getUserId());
|
||||||
|
attributes.put(ExtraFieldConst.USERNAME, transfer.getUsername());
|
||||||
|
attributes.put(ExtraFieldConst.TRACE_ID, TraceIdHolder.get());
|
||||||
|
attributes.put(ExtraFieldConst.IDENTITY, Requests.getIdentity());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Exception exception) {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -3,6 +3,7 @@ package com.orion.visor.module.asset.service;
|
|||||||
import com.orion.visor.module.asset.entity.domain.HostDO;
|
import com.orion.visor.module.asset.entity.domain.HostDO;
|
||||||
import com.orion.visor.module.asset.entity.dto.HostTerminalAccessDTO;
|
import com.orion.visor.module.asset.entity.dto.HostTerminalAccessDTO;
|
||||||
import com.orion.visor.module.asset.entity.dto.HostTerminalConnectDTO;
|
import com.orion.visor.module.asset.entity.dto.HostTerminalConnectDTO;
|
||||||
|
import com.orion.visor.module.asset.entity.dto.HostTerminalTransferDTO;
|
||||||
import com.orion.visor.module.asset.entity.vo.HostTerminalThemeVO;
|
import com.orion.visor.module.asset.entity.vo.HostTerminalThemeVO;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -30,6 +31,13 @@ public interface HostTerminalService {
|
|||||||
*/
|
*/
|
||||||
String getTerminalAccessToken();
|
String getTerminalAccessToken();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取主机终端传输 transferToken
|
||||||
|
*
|
||||||
|
* @return transferToken
|
||||||
|
*/
|
||||||
|
String getTerminalTransferToken();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 通过 accessToken 获取主机终端访问信息
|
* 通过 accessToken 获取主机终端访问信息
|
||||||
*
|
*
|
||||||
@@ -38,6 +46,14 @@ public interface HostTerminalService {
|
|||||||
*/
|
*/
|
||||||
HostTerminalAccessDTO getAccessInfoByToken(String token);
|
HostTerminalAccessDTO getAccessInfoByToken(String token);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过 transferToken 获取主机终端传输信息
|
||||||
|
*
|
||||||
|
* @param token token
|
||||||
|
* @return config
|
||||||
|
*/
|
||||||
|
HostTerminalTransferDTO getTransferInfoByToken(String token);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取连接信息
|
* 获取连接信息
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import com.orion.visor.module.asset.entity.domain.HostIdentityDO;
|
|||||||
import com.orion.visor.module.asset.entity.domain.HostKeyDO;
|
import com.orion.visor.module.asset.entity.domain.HostKeyDO;
|
||||||
import com.orion.visor.module.asset.entity.dto.HostTerminalAccessDTO;
|
import com.orion.visor.module.asset.entity.dto.HostTerminalAccessDTO;
|
||||||
import com.orion.visor.module.asset.entity.dto.HostTerminalConnectDTO;
|
import com.orion.visor.module.asset.entity.dto.HostTerminalConnectDTO;
|
||||||
|
import com.orion.visor.module.asset.entity.dto.HostTerminalTransferDTO;
|
||||||
import com.orion.visor.module.asset.entity.vo.HostTerminalThemeVO;
|
import com.orion.visor.module.asset.entity.vo.HostTerminalThemeVO;
|
||||||
import com.orion.visor.module.asset.enums.*;
|
import com.orion.visor.module.asset.enums.*;
|
||||||
import com.orion.visor.module.asset.handler.host.config.model.HostSshConfigModel;
|
import com.orion.visor.module.asset.handler.host.config.model.HostSshConfigModel;
|
||||||
@@ -99,6 +100,21 @@ public class HostTerminalServiceImpl implements HostTerminalService {
|
|||||||
return accessToken;
|
return accessToken;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getTerminalTransferToken() {
|
||||||
|
LoginUser user = Valid.notNull(SecurityUtils.getLoginUser());
|
||||||
|
log.info("HostConnectService.getTerminalTransferToken userId: {}", user.getId());
|
||||||
|
String transferToken = UUIds.random19();
|
||||||
|
HostTerminalTransferDTO transfer = HostTerminalTransferDTO.builder()
|
||||||
|
.userId(user.getId())
|
||||||
|
.username(user.getUsername())
|
||||||
|
.build();
|
||||||
|
// 设置 transfer 缓存
|
||||||
|
String key = HostTerminalCacheKeyDefine.HOST_TERMINAL_TRANSFER.format(transferToken);
|
||||||
|
RedisStrings.setJson(key, HostTerminalCacheKeyDefine.HOST_TERMINAL_TRANSFER, transfer);
|
||||||
|
return transferToken;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public HostTerminalAccessDTO getAccessInfoByToken(String token) {
|
public HostTerminalAccessDTO getAccessInfoByToken(String token) {
|
||||||
// 获取缓存
|
// 获取缓存
|
||||||
@@ -111,6 +127,18 @@ public class HostTerminalServiceImpl implements HostTerminalService {
|
|||||||
return access;
|
return access;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public HostTerminalTransferDTO getTransferInfoByToken(String token) {
|
||||||
|
// 获取缓存
|
||||||
|
String key = HostTerminalCacheKeyDefine.HOST_TERMINAL_TRANSFER.format(token);
|
||||||
|
HostTerminalTransferDTO transfer = RedisStrings.getJson(key, HostTerminalCacheKeyDefine.HOST_TERMINAL_TRANSFER);
|
||||||
|
// 删除缓存
|
||||||
|
if (transfer != null) {
|
||||||
|
RedisStrings.delete(key);
|
||||||
|
}
|
||||||
|
return transfer;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public HostTerminalConnectDTO getTerminalConnectInfo(Long hostId) {
|
public HostTerminalConnectDTO getTerminalConnectInfo(Long hostId) {
|
||||||
log.info("HostConnectService.getTerminalConnectInfo-withHost hostId: {}", hostId);
|
log.info("HostConnectService.getTerminalConnectInfo-withHost hostId: {}", hostId);
|
||||||
|
|||||||
@@ -8,7 +8,6 @@
|
|||||||
<result column="user_id" property="userId"/>
|
<result column="user_id" property="userId"/>
|
||||||
<result column="group_id" property="groupId"/>
|
<result column="group_id" property="groupId"/>
|
||||||
<result column="name" property="name"/>
|
<result column="name" property="name"/>
|
||||||
<result column="prefix" property="prefix"/>
|
|
||||||
<result column="command" property="command"/>
|
<result column="command" property="command"/>
|
||||||
<result column="create_time" property="createTime"/>
|
<result column="create_time" property="createTime"/>
|
||||||
<result column="update_time" property="updateTime"/>
|
<result column="update_time" property="updateTime"/>
|
||||||
@@ -19,7 +18,7 @@
|
|||||||
|
|
||||||
<!-- 通用查询结果列 -->
|
<!-- 通用查询结果列 -->
|
||||||
<sql id="Base_Column_List">
|
<sql id="Base_Column_List">
|
||||||
id, user_id, group_id, name, prefix, command, create_time, update_time, creator, updater, deleted
|
id, user_id, group_id, name, command, create_time, update_time, creator, updater, deleted
|
||||||
</sql>
|
</sql>
|
||||||
|
|
||||||
</mapper>
|
</mapper>
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.orion.visor.module.infra.controller;
|
package com.orion.visor.module.infra.controller;
|
||||||
|
|
||||||
|
import com.orion.visor.framework.common.validator.group.Page;
|
||||||
import com.orion.visor.framework.log.core.annotation.IgnoreLog;
|
import com.orion.visor.framework.log.core.annotation.IgnoreLog;
|
||||||
import com.orion.visor.framework.log.core.enums.IgnoreLogMode;
|
import com.orion.visor.framework.log.core.enums.IgnoreLogMode;
|
||||||
import com.orion.visor.framework.web.core.annotation.RestWrapper;
|
import com.orion.visor.framework.web.core.annotation.RestWrapper;
|
||||||
@@ -38,7 +39,7 @@ public class SystemMessageController {
|
|||||||
@IgnoreLog(IgnoreLogMode.ALL)
|
@IgnoreLog(IgnoreLogMode.ALL)
|
||||||
@PostMapping("/list")
|
@PostMapping("/list")
|
||||||
@Operation(summary = "查询系统消息列表")
|
@Operation(summary = "查询系统消息列表")
|
||||||
public List<SystemMessageVO> getSystemMessageList(@RequestBody SystemMessageQueryRequest request) {
|
public List<SystemMessageVO> getSystemMessageList(@Validated(Page.class) @RequestBody SystemMessageQueryRequest request) {
|
||||||
return systemMessageService.getSystemMessageList(request);
|
return systemMessageService.getSystemMessageList(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,8 @@
|
|||||||
package com.orion.visor.module.infra.entity.request.message;
|
package com.orion.visor.module.infra.entity.request.message;
|
||||||
|
|
||||||
|
import com.orion.visor.framework.common.entity.PageRequest;
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.*;
|
||||||
import lombok.Builder;
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.NoArgsConstructor;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 系统消息 查询请求对象
|
* 系统消息 查询请求对象
|
||||||
@@ -17,11 +15,9 @@ import lombok.NoArgsConstructor;
|
|||||||
@Builder
|
@Builder
|
||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
@Schema(name = "SystemMessageQueryRequest", description = "系统消息 查询请求对象")
|
@Schema(name = "SystemMessageQueryRequest", description = "系统消息 查询请求对象")
|
||||||
public class SystemMessageQueryRequest {
|
public class SystemMessageQueryRequest extends PageRequest {
|
||||||
|
|
||||||
@Schema(description = "大小")
|
|
||||||
private Integer limit;
|
|
||||||
|
|
||||||
@Schema(description = "maxId")
|
@Schema(description = "maxId")
|
||||||
private Long maxId;
|
private Long maxId;
|
||||||
|
|||||||
@@ -74,9 +74,9 @@ public class SystemMessageServiceImpl implements SystemMessageService {
|
|||||||
.eq(SystemMessageDO::getClassify, request.getClassify())
|
.eq(SystemMessageDO::getClassify, request.getClassify())
|
||||||
.lt(SystemMessageDO::getId, request.getMaxId())
|
.lt(SystemMessageDO::getId, request.getMaxId())
|
||||||
.eq(SystemMessageDO::getStatus, status)
|
.eq(SystemMessageDO::getStatus, status)
|
||||||
.last(Const.LIMIT + Const.SPACE + request.getLimit())
|
|
||||||
.orderByDesc(SystemMessageDO::getId)
|
.orderByDesc(SystemMessageDO::getId)
|
||||||
.then()
|
.then()
|
||||||
|
.limit(request.getLimit())
|
||||||
.list(SystemMessageConvert.MAPPER::to);
|
.list(SystemMessageConvert.MAPPER::to);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -51,6 +51,13 @@ export function getTerminalAccessToken() {
|
|||||||
return axios.get<string>('/asset/host-terminal/access');
|
return axios.get<string>('/asset/host-terminal/access');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取主机终端 transferToken
|
||||||
|
*/
|
||||||
|
export function getTerminalTransferToken() {
|
||||||
|
return axios.get<string>('/asset/host-terminal/transfer');
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 打开主机终端 websocket
|
* 打开主机终端 websocket
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
|
import type { Pagination } from '@/types/global';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 系统消息查询请求
|
* 系统消息查询请求
|
||||||
*/
|
*/
|
||||||
export interface MessageQueryRequest {
|
export interface MessageQueryRequest extends Pagination {
|
||||||
limit?: number;
|
|
||||||
maxId?: number;
|
maxId?: number;
|
||||||
classify?: string;
|
classify?: string;
|
||||||
queryUnread?: boolean;
|
queryUnread?: boolean;
|
||||||
|
|||||||
@@ -230,6 +230,26 @@ body {
|
|||||||
margin-bottom: 16px;
|
margin-bottom: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.fs12 {
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fs13 {
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fs14 {
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fs15 {
|
||||||
|
font-size: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fs16 {
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
.text-ellipsis {
|
.text-ellipsis {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
@@ -301,13 +321,13 @@ body {
|
|||||||
|
|
||||||
::-webkit-scrollbar-track {
|
::-webkit-scrollbar-track {
|
||||||
background-color: var(--color-fill-1);
|
background-color: var(--color-fill-1);
|
||||||
border-radius: 8px;
|
border-radius: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
::-webkit-scrollbar-thumb {
|
::-webkit-scrollbar-thumb {
|
||||||
border: 1px solid transparent;
|
border: 1px solid transparent;
|
||||||
background-clip: padding-box;
|
background-clip: padding-box;
|
||||||
border-radius: 8px;
|
border-radius: 4px;
|
||||||
background-color: var(--color-fill-4);
|
background-color: var(--color-fill-4);
|
||||||
|
|
||||||
//&:hover {
|
//&:hover {
|
||||||
|
|||||||
@@ -129,6 +129,7 @@
|
|||||||
: undefined;
|
: undefined;
|
||||||
// 查询数据
|
// 查询数据
|
||||||
const { data } = await getSystemMessageList({
|
const { data } = await getSystemMessageList({
|
||||||
|
page: 1,
|
||||||
limit: messageLimit,
|
limit: messageLimit,
|
||||||
classify: currentClassify.value,
|
classify: currentClassify.value,
|
||||||
queryUnread: queryUnread.value,
|
queryUnread: queryUnread.value,
|
||||||
|
|||||||
@@ -33,7 +33,7 @@
|
|||||||
</a-form-item>
|
</a-form-item>
|
||||||
<!-- 主机编码 -->
|
<!-- 主机编码 -->
|
||||||
<a-form-item field="code" label="主机编码">
|
<a-form-item field="code" label="主机编码">
|
||||||
<a-input v-model="formModel.code" placeholder="请输入主机编码" />
|
<a-input v-model="formModel.code" placeholder="请输入主机编码 (定义主机唯一值)" />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<!-- 主机地址 -->
|
<!-- 主机地址 -->
|
||||||
<a-form-item field="address" label="主机地址">
|
<a-form-item field="address" label="主机地址">
|
||||||
|
|||||||
@@ -200,7 +200,7 @@
|
|||||||
</a-button>
|
</a-button>
|
||||||
</a-popconfirm>
|
</a-popconfirm>
|
||||||
<!-- 更多 -->
|
<!-- 更多 -->
|
||||||
<a-dropdown trigger="hover">
|
<a-dropdown trigger="hover" :popup-max-height="false">
|
||||||
<a-button type="text" size="mini">
|
<a-button type="text" size="mini">
|
||||||
更多
|
更多
|
||||||
</a-button>
|
</a-button>
|
||||||
@@ -220,6 +220,22 @@
|
|||||||
复制
|
复制
|
||||||
</span>
|
</span>
|
||||||
</a-doption>
|
</a-doption>
|
||||||
|
<!-- SSH -->
|
||||||
|
<a-doption v-if="record.type === hostType.SSH.type"
|
||||||
|
v-permission="['asset:host-terminal:access']"
|
||||||
|
@click="openNewRoute({ name: 'terminal', query: { connect: record.id, type: 'SSH' } })">
|
||||||
|
<span class="more-doption normal">
|
||||||
|
SSH
|
||||||
|
</span>
|
||||||
|
</a-doption>
|
||||||
|
<!-- SFTP -->
|
||||||
|
<a-doption v-if="record.type === hostType.SSH.type"
|
||||||
|
v-permission="['asset:host-terminal:access']"
|
||||||
|
@click="openNewRoute({ name: 'terminal', query: { connect: record.id, type: 'SFTP' } })">
|
||||||
|
<span class="more-doption normal">
|
||||||
|
SFTP
|
||||||
|
</span>
|
||||||
|
</a-doption>
|
||||||
</template>
|
</template>
|
||||||
</a-dropdown>
|
</a-dropdown>
|
||||||
</div>
|
</div>
|
||||||
@@ -239,7 +255,7 @@
|
|||||||
import { reactive, ref, onMounted } from 'vue';
|
import { reactive, ref, onMounted } from 'vue';
|
||||||
import { deleteHost, batchDeleteHost, getHostPage, updateHostStatus } from '@/api/asset/host';
|
import { deleteHost, batchDeleteHost, getHostPage, updateHostStatus } from '@/api/asset/host';
|
||||||
import { Message, Modal } from '@arco-design/web-vue';
|
import { Message, Modal } from '@arco-design/web-vue';
|
||||||
import { tagColor, hostTypeKey, hostStatusKey } from '../types/const';
|
import { tagColor, hostTypeKey, hostStatusKey, hostType } from '../types/const';
|
||||||
import { useTablePagination, useRowSelection } from '@/hooks/table';
|
import { useTablePagination, useRowSelection } from '@/hooks/table';
|
||||||
import { useDictStore } from '@/store';
|
import { useDictStore } from '@/store';
|
||||||
import { copy } from '@/hooks/copy';
|
import { copy } from '@/hooks/copy';
|
||||||
@@ -247,6 +263,7 @@
|
|||||||
import useLoading from '@/hooks/loading';
|
import useLoading from '@/hooks/loading';
|
||||||
import columns from '../types/table.columns';
|
import columns from '../types/table.columns';
|
||||||
import { GrantKey, GrantRouteName } from '@/views/asset/grant/types/const';
|
import { GrantKey, GrantRouteName } from '@/views/asset/grant/types/const';
|
||||||
|
import { openNewRoute } from '@/router';
|
||||||
import TagMultiSelector from '@/components/meta/tag/multi-selector/index.vue';
|
import TagMultiSelector from '@/components/meta/tag/multi-selector/index.vue';
|
||||||
|
|
||||||
const emits = defineEmits(['openCopy', 'openAdd', 'openUpdate', 'openUpdateConfig', 'openHostGroup']);
|
const emits = defineEmits(['openCopy', 'openAdd', 'openUpdate', 'openUpdateConfig', 'openHostGroup']);
|
||||||
|
|||||||
@@ -85,15 +85,21 @@ export default class SftpSession extends BaseSession implements ISftpSession {
|
|||||||
display: 'flex',
|
display: 'flex',
|
||||||
flexDirection: 'column',
|
flexDirection: 'column',
|
||||||
maxHeight: '40vh',
|
maxHeight: '40vh',
|
||||||
overflowY: 'auto'
|
overflowY: 'auto',
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
paths.map(s => {
|
paths.map(s => {
|
||||||
return h('span', { style: { marginTop: '4px' } }, s);
|
return h('span', {
|
||||||
|
style: {
|
||||||
|
marginTop: '4px',
|
||||||
|
wordBreak: 'break-all',
|
||||||
|
}
|
||||||
|
}, s);
|
||||||
}));
|
}));
|
||||||
// 提示
|
// 提示
|
||||||
Modal.confirm({
|
Modal.confirm({
|
||||||
title: '确定后将立即删除这些文件且无法恢复!',
|
title: `确定后将立即删除这 ${paths.length} 个文件且无法恢复!`,
|
||||||
|
width: 426,
|
||||||
modalStyle: { padding: '24px 32px' },
|
modalStyle: { padding: '24px 32px' },
|
||||||
bodyStyle: { marginTop: '-14px' },
|
bodyStyle: { marginTop: '-14px' },
|
||||||
okButtonProps: { status: 'danger' },
|
okButtonProps: { status: 'danger' },
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import type { ISftpTransferHandler, ISftpTransferManager, SftpFile, SftpTransferItem, TransferOperatorResponse } from '../types/define';
|
import type { ISftpTransferHandler, ISftpTransferManager, SftpFile, SftpTransferItem, TransferOperatorResponse } from '../types/define';
|
||||||
import { sessionCloseMsg, TransferReceiver, TransferStatus, TransferType } from '../types/const';
|
import { sessionCloseMsg, TransferReceiver, TransferStatus, TransferType } from '../types/const';
|
||||||
import { Message } from '@arco-design/web-vue';
|
import { Message } from '@arco-design/web-vue';
|
||||||
import { getTerminalAccessToken, openHostTransferChannel } from '@/api/asset/host-terminal';
|
import { getTerminalTransferToken, openHostTransferChannel } from '@/api/asset/host-terminal';
|
||||||
import { nextId } from '@/utils';
|
import { nextId } from '@/utils';
|
||||||
import SftpTransferUploader from './sftp-transfer-uploader';
|
import SftpTransferUploader from './sftp-transfer-uploader';
|
||||||
import SftpTransferDownloader from './sftp-transfer-downloader';
|
import SftpTransferDownloader from './sftp-transfer-downloader';
|
||||||
@@ -105,11 +105,11 @@ export default class SftpTransferManager implements ISftpTransferManager {
|
|||||||
// 打开会话
|
// 打开会话
|
||||||
private async openClient() {
|
private async openClient() {
|
||||||
this.run = true;
|
this.run = true;
|
||||||
// 获取 access
|
// 获取 transferToken
|
||||||
const { data: accessToken } = await getTerminalAccessToken();
|
const { data: transferToken } = await getTerminalTransferToken();
|
||||||
// 打开会话
|
// 打开会话
|
||||||
try {
|
try {
|
||||||
this.client = await openHostTransferChannel(accessToken);
|
this.client = await openHostTransferChannel(transferToken);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// 打开失败将传输列表置为失效
|
// 打开失败将传输列表置为失效
|
||||||
Message.error('会话打开失败');
|
Message.error('会话打开失败');
|
||||||
|
|||||||
@@ -30,7 +30,6 @@ CREATE TABLE `command_snippet`
|
|||||||
`user_id` bigint(0) NULL DEFAULT NULL COMMENT '用户id',
|
`user_id` bigint(0) NULL DEFAULT NULL COMMENT '用户id',
|
||||||
`group_id` bigint(0) NULL DEFAULT NULL COMMENT '分组id',
|
`group_id` bigint(0) NULL DEFAULT NULL COMMENT '分组id',
|
||||||
`name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '名称',
|
`name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '名称',
|
||||||
`prefix` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '触发前缀',
|
|
||||||
`command` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '代码片段',
|
`command` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '代码片段',
|
||||||
`create_time` datetime(0) NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
`create_time` datetime(0) NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||||
`update_time` datetime(0) NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP(0) COMMENT '修改时间',
|
`update_time` datetime(0) NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP(0) COMMENT '修改时间',
|
||||||
|
|||||||
Reference in New Issue
Block a user