⚡ 优化自动聚焦逻辑.
This commit is contained in:
@@ -109,4 +109,6 @@ public interface ErrorMessage {
|
||||
|
||||
String CLIENT_ABORT = "手动中断";
|
||||
|
||||
String UNABLE_DOWNLOAD_FOLDER = "无法下载文件夹";
|
||||
|
||||
}
|
||||
|
||||
@@ -131,9 +131,9 @@ public enum InputTypeEnum {
|
||||
* SFTP 修改文件权限
|
||||
*/
|
||||
SFTP_CHMOD("cm",
|
||||
SftpChangeModHandler.class,
|
||||
SftpChangeModeHandler.class,
|
||||
new String[]{"type", "sessionId", "path", "mod"},
|
||||
SftpChangeModRequest.class,
|
||||
SftpChangeModeRequest.class,
|
||||
true),
|
||||
|
||||
/**
|
||||
|
||||
@@ -5,7 +5,7 @@ import com.orion.visor.framework.biz.operator.log.core.utils.OperatorLogs;
|
||||
import com.orion.visor.framework.common.enums.BooleanBit;
|
||||
import com.orion.visor.module.asset.define.operator.HostTerminalOperatorType;
|
||||
import com.orion.visor.module.asset.handler.host.terminal.enums.OutputTypeEnum;
|
||||
import com.orion.visor.module.asset.handler.host.terminal.model.request.SftpChangeModRequest;
|
||||
import com.orion.visor.module.asset.handler.host.terminal.model.request.SftpChangeModeRequest;
|
||||
import com.orion.visor.module.asset.handler.host.terminal.model.response.SftpBaseResponse;
|
||||
import com.orion.visor.module.asset.handler.host.terminal.session.ISftpSession;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -23,24 +23,24 @@ import java.util.Map;
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class SftpChangeModHandler extends AbstractTerminalHandler<SftpChangeModRequest> {
|
||||
public class SftpChangeModeHandler extends AbstractTerminalHandler<SftpChangeModeRequest> {
|
||||
|
||||
@Override
|
||||
public void handle(WebSocketSession channel, SftpChangeModRequest payload) {
|
||||
public void handle(WebSocketSession channel, SftpChangeModeRequest payload) {
|
||||
long startTime = System.currentTimeMillis();
|
||||
// 获取会话
|
||||
String sessionId = payload.getSessionId();
|
||||
ISftpSession session = hostTerminalManager.getSession(channel.getId(), sessionId);
|
||||
String path = payload.getPath();
|
||||
Integer mod = payload.getMod();
|
||||
log.info("SftpChangeModHandler-handle start sessionId: {}, path: {}, mod: {}", sessionId, path, mod);
|
||||
log.info("SftpChangeModeHandler-handle start sessionId: {}, path: {}, mod: {}", sessionId, path, mod);
|
||||
Exception ex = null;
|
||||
// 修改权限
|
||||
try {
|
||||
session.chmod(path, mod);
|
||||
log.info("SftpChangeModHandler-handle success sessionId: {}, path: {}, mod: {}", sessionId, path, mod);
|
||||
log.info("SftpChangeModeHandler-handle success sessionId: {}, path: {}, mod: {}", sessionId, path, mod);
|
||||
} catch (Exception e) {
|
||||
log.error("SftpChangeModHandler-handle error sessionId: {}", sessionId, e);
|
||||
log.error("SftpChangeModeHandler-handle error sessionId: {}", sessionId, e);
|
||||
ex = e;
|
||||
}
|
||||
// 返回
|
||||
@@ -20,7 +20,7 @@ import lombok.experimental.SuperBuilder;
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class SftpChangeModRequest extends SftpBaseRequest {
|
||||
public class SftpChangeModeRequest extends SftpBaseRequest {
|
||||
|
||||
/**
|
||||
* 10进制的8进制 权限
|
||||
@@ -37,8 +37,11 @@ public class DownloadSession extends TransferSession implements StreamingRespons
|
||||
|
||||
protected InputStream inputStream;
|
||||
|
||||
private Long fileSize;
|
||||
|
||||
public DownloadSession(HostTerminalConnectDTO connectInfo, SessionStore sessionStore, WebSocketSession channel) {
|
||||
super(connectInfo, sessionStore, channel);
|
||||
this.fileSize = 0L;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -53,7 +56,9 @@ public class DownloadSession extends TransferSession implements StreamingRespons
|
||||
// 检查文件是否存在
|
||||
SftpFile file = executor.getFile(path);
|
||||
Valid.notNull(file, ErrorMessage.FILE_ABSENT);
|
||||
if (file.getSize() == 0L) {
|
||||
// 验证非文件夹
|
||||
Valid.isTrue(!file.isDirectory(), ErrorMessage.UNABLE_DOWNLOAD_FOLDER);
|
||||
if ((this.fileSize = file.getSize()) == 0L) {
|
||||
// 文件为空
|
||||
log.info("DownloadSession.startDownload file empty channelId: {}, path: {}", channelId, path);
|
||||
TransferUtils.sendMessage(channel, TransferReceiver.FINISH, null);
|
||||
@@ -101,14 +106,14 @@ public class DownloadSession extends TransferSession implements StreamingRespons
|
||||
// 首次触发
|
||||
if (i == 0) {
|
||||
outputStream.flush();
|
||||
this.sendProgress(size, null);
|
||||
this.sendProgress(size, fileSize);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
// 最后一次也要 flush
|
||||
if (i != 0) {
|
||||
outputStream.flush();
|
||||
this.sendProgress(size, null);
|
||||
this.sendProgress(size, fileSize);
|
||||
}
|
||||
log.info("DownloadSession.download finish channelId: {}, path: {}", channelId, path);
|
||||
} catch (Exception e) {
|
||||
|
||||
@@ -314,6 +314,11 @@ public class TerminalPreferenceModel implements GenericsDataModel {
|
||||
*/
|
||||
private Boolean openSftp;
|
||||
|
||||
/**
|
||||
* 上传文件
|
||||
*/
|
||||
private Boolean uploadFile;
|
||||
|
||||
/**
|
||||
* 清空
|
||||
*/
|
||||
|
||||
@@ -91,6 +91,7 @@ public class TerminalPreferenceStrategy extends AbstractGenericsDataStrategy<Ter
|
||||
new TerminalPreferenceModel.ShortcutKeysModel("toBottom", true, true, false, "ArrowDown", true),
|
||||
new TerminalPreferenceModel.ShortcutKeysModel("selectAll", true, true, false, "KeyA", true),
|
||||
new TerminalPreferenceModel.ShortcutKeysModel("search", true, true, false, "KeyF", true),
|
||||
new TerminalPreferenceModel.ShortcutKeysModel("uploadFile", true, true, false, "KeyU", true),
|
||||
new TerminalPreferenceModel.ShortcutKeysModel("commandEditor", true, false, true, "KeyE", true),
|
||||
new TerminalPreferenceModel.ShortcutKeysModel("fontSizePlus", true, false, true, "Equal", true),
|
||||
new TerminalPreferenceModel.ShortcutKeysModel("fontSizeSubtract", true, false, true, "Minus", true)
|
||||
@@ -112,7 +113,10 @@ public class TerminalPreferenceStrategy extends AbstractGenericsDataStrategy<Ter
|
||||
.fontSizePlus(false)
|
||||
.fontSizeSubtract(false)
|
||||
.commandEditor(true)
|
||||
.fontSizePlus(true)
|
||||
.fontSizeSubtract(true)
|
||||
.openSftp(true)
|
||||
.uploadFile(true)
|
||||
.clear(true)
|
||||
.disconnect(false)
|
||||
.build()
|
||||
@@ -123,7 +127,7 @@ public class TerminalPreferenceStrategy extends AbstractGenericsDataStrategy<Ter
|
||||
.theme(new JSONObject())
|
||||
.displaySetting(JSONObject.parseObject(defaultDisplaySetting))
|
||||
.actionBarSetting(JSONObject.parseObject(actionBarSetting))
|
||||
.rightMenuSetting(Lists.of("selectAll", "copy", "paste", "fontSizePlus", "fontSizeSubtract", "search", "clear"))
|
||||
.rightMenuSetting(Lists.of("selectAll", "copy", "paste", "search", "clear"))
|
||||
.interactSetting(JSONObject.parseObject(defaultInteractSetting))
|
||||
.pluginsSetting(JSONObject.parseObject(defaultPluginsSetting))
|
||||
.sessionSetting(JSONObject.parseObject(defaultSessionSetting))
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<a-drawer v-model:visible="visible"
|
||||
:width="388"
|
||||
:footer="false"
|
||||
@close="onClose">
|
||||
@close="emits('closed')">
|
||||
<!-- 标题 -->
|
||||
<template #title>
|
||||
<span class="snippet-drawer-title usn">
|
||||
@@ -103,7 +103,6 @@
|
||||
</script>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import type { ISshSession } from '../../types/define';
|
||||
import type { CommandSnippetQueryResponse } from '@/api/asset/command-snippet';
|
||||
import type { CommandSnippetGroupQueryResponse } from '@/api/asset/command-snippet-group';
|
||||
import { ref, watch } from 'vue';
|
||||
@@ -111,14 +110,15 @@
|
||||
import useLoading from '@/hooks/loading';
|
||||
import { deleteCommandSnippet } from '@/api/asset/command-snippet';
|
||||
import { useCacheStore, useTerminalStore } from '@/store';
|
||||
import { PanelSessionType } from '../../types/const';
|
||||
import { copy } from '@/hooks/copy';
|
||||
import CommandSnippetItem from './command-snippet-item.vue';
|
||||
import CommandSnippetFormDrawer from './command-snippet-form-drawer.vue';
|
||||
|
||||
const emits = defineEmits(['closed']);
|
||||
|
||||
const { loading, setLoading } = useLoading();
|
||||
const { visible, setVisible } = useVisible();
|
||||
const { getCurrentSession, appendCommandToCurrentSession } = useTerminalStore();
|
||||
const { appendCommandToCurrentSession } = useTerminalStore();
|
||||
|
||||
const cacheStore = useCacheStore();
|
||||
|
||||
@@ -297,12 +297,6 @@
|
||||
filterSnippet();
|
||||
};
|
||||
|
||||
// 关闭回调
|
||||
const onClose = () => {
|
||||
// 关闭时候如果打开的是终端 则聚焦终端
|
||||
getCurrentSession<ISshSession>(PanelSessionType.SSH.type)?.focus();
|
||||
};
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<a-drawer v-model:visible="visible"
|
||||
:width="388"
|
||||
:footer="false"
|
||||
@close="onClose">
|
||||
@close="emits('closed')">
|
||||
<!-- 标题 -->
|
||||
<template #title>
|
||||
<span class="path-drawer-title usn">
|
||||
@@ -105,7 +105,7 @@
|
||||
</script>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import type { ISftpSession, ISshSession } from '../../types/define';
|
||||
import type { ISftpSession } from '../../types/define';
|
||||
import type { PathBookmarkQueryResponse } from '@/api/asset/path-bookmark';
|
||||
import type { PathBookmarkGroupQueryResponse } from '@/api/asset/path-bookmark-group';
|
||||
import { ref, watch } from 'vue';
|
||||
@@ -118,6 +118,8 @@
|
||||
import PathBookmarkItem from './path-bookmark-item.vue';
|
||||
import PathBookmarkFormDrawer from './path-bookmark-form-drawer.vue';
|
||||
|
||||
const emits = defineEmits(['closed']);
|
||||
|
||||
const { loading, setLoading } = useLoading();
|
||||
const { visible, setVisible } = useVisible();
|
||||
const { getCurrentSession, appendCommandToCurrentSession } = useTerminalStore();
|
||||
@@ -302,12 +304,6 @@
|
||||
filterPath();
|
||||
};
|
||||
|
||||
// 关闭回调
|
||||
const onClose = () => {
|
||||
// 关闭时候如果打开的是终端 则聚焦终端
|
||||
getCurrentSession<ISshSession>(PanelSessionType.SSH.type)?.focus();
|
||||
};
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
|
||||
@@ -86,6 +86,8 @@
|
||||
import { getFileSize } from '@/utils/file';
|
||||
import useVisible from '@/hooks/visible';
|
||||
|
||||
const emits = defineEmits(['closed']);
|
||||
|
||||
const { visible, setVisible } = useVisible();
|
||||
const { transferManager } = useTerminalStore();
|
||||
|
||||
@@ -130,6 +132,7 @@
|
||||
// 清空
|
||||
const handlerClear = () => {
|
||||
fileList.value = [];
|
||||
emits('closed');
|
||||
};
|
||||
|
||||
</script>
|
||||
|
||||
@@ -48,6 +48,8 @@
|
||||
class="search-modal"
|
||||
@find="findWords"
|
||||
@close="focus" />
|
||||
<!-- 上传文件模态框 -->
|
||||
<sftp-upload-modal ref="uploadModal" @closed="focus" />
|
||||
</div>
|
||||
</ssh-context-menu>
|
||||
<!-- 命令编辑器 -->
|
||||
@@ -76,6 +78,7 @@
|
||||
import ShellEditorModal from '@/components/view/shell-editor/modal/index.vue';
|
||||
import IconActions from '../layout/icon-actions.vue';
|
||||
import SshContextMenu from './ssh-context-menu.vue';
|
||||
import SftpUploadModal from '../sftp/sftp-upload-modal.vue';
|
||||
import XtermSearchModal from '@/components/xtrem/search-modal/index.vue';
|
||||
|
||||
const props = defineProps<{
|
||||
@@ -87,6 +90,7 @@
|
||||
|
||||
const editorModal = ref();
|
||||
const searchModal = ref();
|
||||
const uploadModal = ref();
|
||||
const commandInput = ref();
|
||||
const terminalRef = ref();
|
||||
const session = ref<ISshSession>();
|
||||
@@ -141,7 +145,8 @@
|
||||
session.value = await sessionManager.openSsh(props.tab, {
|
||||
el: terminalRef.value,
|
||||
editorModal: editorModal.value,
|
||||
searchModal: searchModal.value
|
||||
searchModal: searchModal.value,
|
||||
uploadModal: uploadModal.value,
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
class="transfer-drawer"
|
||||
:width="388"
|
||||
:unmount-on-close="false"
|
||||
:footer="false">
|
||||
:footer="false"
|
||||
@close="emits('closed')">
|
||||
<!-- 标题 -->
|
||||
<template #title>
|
||||
<span class="path-drawer-title usn">
|
||||
@@ -76,6 +77,8 @@
|
||||
import { transferStatusKey } from '../../types/const';
|
||||
import TransferItem from './transfer-item.vue';
|
||||
|
||||
const emits = defineEmits(['closed']);
|
||||
|
||||
const { transferManager } = useTerminalStore();
|
||||
const { toOptions } = useDictStore();
|
||||
const { visible, setVisible } = useVisible();
|
||||
@@ -110,16 +113,6 @@
|
||||
transferManager.cancelAllTransfer();
|
||||
};
|
||||
|
||||
// 关闭
|
||||
const handleClose = () => {
|
||||
handlerClear();
|
||||
};
|
||||
|
||||
// 清空
|
||||
const handlerClear = () => {
|
||||
setLoading(false);
|
||||
};
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
|
||||
@@ -89,6 +89,7 @@ export default class SshSessionHandler implements ISshSessionHandler {
|
||||
case 'enter':
|
||||
case 'commandEditor':
|
||||
case 'openSftp':
|
||||
case 'uploadFile':
|
||||
case 'checkAppendMissing':
|
||||
return this.session.canWrite;
|
||||
case 'disconnect':
|
||||
@@ -217,6 +218,11 @@ export default class SshSessionHandler implements ISshSessionHandler {
|
||||
}
|
||||
}
|
||||
|
||||
// 上传文件
|
||||
uploadFile(): void {
|
||||
this.domRef.uploadModal.open(this.session.hostId, '/');
|
||||
}
|
||||
|
||||
// ctrl + c
|
||||
interrupt() {
|
||||
this.inst.paste(String.fromCharCode(3));
|
||||
|
||||
@@ -30,11 +30,11 @@
|
||||
</div>
|
||||
</main>
|
||||
<!-- 命令片段列表抽屉 -->
|
||||
<command-snippet-drawer ref="snippetRef" />
|
||||
<command-snippet-drawer ref="snippetRef" @closed="autoFocus" />
|
||||
<!-- 路径书签列表抽屉 -->
|
||||
<path-bookmark-drawer ref="pathRef" />
|
||||
<path-bookmark-drawer ref="pathRef" @closed="autoFocus" />
|
||||
<!-- 传输列表 -->
|
||||
<transfer-drawer ref="transferRef" />
|
||||
<transfer-drawer ref="transferRef" @closed="autoFocus" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -88,6 +88,11 @@
|
||||
event.returnValue = confirm('系统可能不会保存您所做的更改');
|
||||
};
|
||||
|
||||
// 自动聚焦
|
||||
const autoFocus = () => {
|
||||
getCurrentSession<ISshSession>(PanelSessionType.SSH.type)?.focus();
|
||||
};
|
||||
|
||||
// 打开默认打开页面
|
||||
onBeforeMount(() => {
|
||||
// 打开默认 tab
|
||||
|
||||
@@ -172,6 +172,10 @@ export const ActionBarItems = [
|
||||
item: 'openSftp',
|
||||
icon: 'icon-folder',
|
||||
content: '打开 SFTP',
|
||||
}, {
|
||||
item: 'uploadFile',
|
||||
icon: 'icon-upload',
|
||||
content: '上传文件',
|
||||
}, {
|
||||
item: 'clear',
|
||||
icon: 'icon-delete',
|
||||
@@ -301,6 +305,10 @@ export const TerminalShortcutItems: Array<ShortcutKeyItem> = [
|
||||
item: 'search',
|
||||
content: '搜索',
|
||||
type: TerminalShortcutType.TERMINAL
|
||||
}, {
|
||||
item: 'uploadFile',
|
||||
content: '上传文件',
|
||||
type: TerminalShortcutType.TERMINAL
|
||||
}, {
|
||||
item: 'fontSizePlus',
|
||||
content: '增大字号',
|
||||
|
||||
@@ -192,6 +192,7 @@ export interface XtermDomRef {
|
||||
el: HTMLElement;
|
||||
searchModal: any;
|
||||
editorModal: any;
|
||||
uploadModal: any;
|
||||
}
|
||||
|
||||
// 终端会话定义
|
||||
@@ -280,6 +281,8 @@ export interface ISshSessionHandler {
|
||||
commandEditor: () => void;
|
||||
// 打开 sftp
|
||||
openSftp: () => void;
|
||||
// 上传文件
|
||||
uploadFile: () => void;
|
||||
// 中断
|
||||
interrupt: () => void;
|
||||
// 回车
|
||||
|
||||
Reference in New Issue
Block a user