优化终端代码.

This commit is contained in:
lijiahang
2024-08-05 09:11:54 +08:00
parent 471acfdf00
commit 8cea9dc977
25 changed files with 205 additions and 43 deletions

View File

@@ -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;"

View File

@@ -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;"

View File

@@ -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;

View File

@@ -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>
<!-- 修改 --> <!-- 修改 -->

View File

@@ -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}")

View File

@@ -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();
}
} }

View File

@@ -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();
} }

View File

@@ -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;

View File

@@ -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;
} }
// 设置参数 // 设置参数

View File

@@ -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) {
}
}

View File

@@ -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);
/** /**
* 获取连接信息 * 获取连接信息
* *

View File

@@ -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);

View File

@@ -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>

View File

@@ -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);
} }

View File

@@ -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;

View File

@@ -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);
} }

View File

@@ -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
*/ */

View File

@@ -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;

View File

@@ -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 {

View File

@@ -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,

View File

@@ -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="主机地址">

View File

@@ -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']);

View File

@@ -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' },

View File

@@ -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('会话打开失败');

View File

@@ -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 '修改时间',