🔨 优化代码逻辑.

This commit is contained in:
lijiahangmax
2025-06-28 16:38:15 +08:00
parent f1771ce676
commit eb81a030e3
25 changed files with 125 additions and 139 deletions

View File

@@ -13,7 +13,7 @@
ref="formRef" ref="formRef"
label-align="right" label-align="right"
:auto-label-width="true" :auto-label-width="true"
:rules="formRules"> :rules="commandSnippetFormRules">
<!-- 名称 --> <!-- 名称 -->
<a-form-item field="name" label="名称"> <a-form-item field="name" label="名称">
<a-input v-model="formModel.name" <a-input v-model="formModel.name"
@@ -52,8 +52,8 @@
import { createCommandSnippet, updateCommandSnippet } from '@/api/terminal/command-snippet'; import { createCommandSnippet, updateCommandSnippet } from '@/api/terminal/command-snippet';
import useLoading from '@/hooks/loading'; import useLoading from '@/hooks/loading';
import useVisible from '@/hooks/visible'; import useVisible from '@/hooks/visible';
import formRules from './types/form.rules';
import { Message } from '@arco-design/web-vue'; import { Message } from '@arco-design/web-vue';
import { commandSnippetFormRules } from '../../types/form.rules';
import CommandSnippetGroupSelector from '@/components/terminal/command-snippet/gruop/selector/index.vue'; import CommandSnippetGroupSelector from '@/components/terminal/command-snippet/gruop/selector/index.vue';
const { visible, setVisible } = useVisible(); const { visible, setVisible } = useVisible();

View File

@@ -1,24 +0,0 @@
import type { FieldRule } from '@arco-design/web-vue';
export const groupId = [{
message: '请选择分组'
}] as FieldRule[];
export const name = [{
required: true,
message: '请输入名称'
}, {
maxLength: 64,
message: '名称长度不能大于64位'
}] as FieldRule[];
export const command = [{
required: true,
message: '请输入代码片段'
}] as FieldRule[];
export default {
groupId,
name,
command,
} as Record<string, FieldRule | FieldRule[]>;

View File

@@ -13,7 +13,7 @@
ref="formRef" ref="formRef"
label-align="right" label-align="right"
:auto-label-width="true" :auto-label-width="true"
:rules="formRules"> :rules="bookmarkFormRules">
<!-- 名称 --> <!-- 名称 -->
<a-form-item field="name" label="名称"> <a-form-item field="name" label="名称">
<a-input v-model="formModel.name" <a-input v-model="formModel.name"
@@ -54,12 +54,11 @@
import { ref } from 'vue'; import { ref } from 'vue';
import useLoading from '@/hooks/loading'; import useLoading from '@/hooks/loading';
import useVisible from '@/hooks/visible'; import useVisible from '@/hooks/visible';
import formRules from './types/form.rules';
import { createPathBookmark, updatePathBookmark } from '@/api/terminal/path-bookmark'; import { createPathBookmark, updatePathBookmark } from '@/api/terminal/path-bookmark';
import { PathBookmarkType } from './types/const'; import { bookmarkFormRules } from '../../types/form.rules';
import { pathBookmarkTypeKey, PathBookmarkType } from '../../types/const';
import { useDictStore } from '@/store'; import { useDictStore } from '@/store';
import { Message } from '@arco-design/web-vue'; import { Message } from '@arco-design/web-vue';
import { pathBookmarkTypeKey } from '../../types/const';
import PathBookmarkGroupSelector from '@/components/terminal/bookmark-path/group/selector/index.vue'; import PathBookmarkGroupSelector from '@/components/terminal/bookmark-path/group/selector/index.vue';
const { visible, setVisible } = useVisible(); const { visible, setVisible } = useVisible();

View File

@@ -117,8 +117,7 @@
import { useTerminalStore } from '@/store'; import { useTerminalStore } from '@/store';
import { useDebounceFn } from '@vueuse/core'; import { useDebounceFn } from '@vueuse/core';
import { getParentPath } from '@/utils/file'; import { getParentPath } from '@/utils/file';
import { PathBookmarkType } from './types/const'; import { TerminalSessionTypes, PathBookmarkType } from '../../types/const';
import { TerminalSessionTypes } from '../../types/const';
const props = defineProps<{ const props = defineProps<{
item: PathBookmarkQueryResponse; item: PathBookmarkQueryResponse;

View File

@@ -1,5 +0,0 @@
// 路径书签类型
export const PathBookmarkType = {
FILE: 'FILE',
DIR: 'DIR',
};

View File

@@ -1,33 +0,0 @@
import type { FieldRule } from '@arco-design/web-vue';
export const groupId = [{
message: '请选择分组'
}] as FieldRule[];
export const name = [{
required: true,
message: '请输入名称'
}, {
maxLength: 64,
message: '名称长度不能大于64位'
}] as FieldRule[];
export const type = [{
required: true,
message: '请选择类型'
}] as FieldRule[];
export const path = [{
required: true,
message: '请输入路径'
}, {
maxLength: 1000,
message: '名称长度不能大于1000位'
}] as FieldRule[];
export default {
groupId,
name,
type,
path,
} as Record<string, FieldRule | FieldRule[]>;

View File

@@ -1,5 +1,5 @@
<template> <template>
<div v-if="session.status.connectStatus === TerminalStatus.CONNECTED"> <div v-if="session.state.connectStatus === TerminalStatus.CONNECTED">
<!-- 工具栏 --> <!-- 工具栏 -->
<a-popover v-model:popup-visible="visible" <a-popover v-model:popup-visible="visible"
:title="undefined" :title="undefined"

View File

@@ -1,11 +1,11 @@
<template> <template>
<div v-if="session.status.connectStatus !== TerminalStatus.CONNECTED && visible"> <div v-if="session.state.connectStatus !== TerminalStatus.CONNECTED && visible">
<!-- 连接中 --> <!-- 连接中 -->
<a-spin v-if="session.status.connectStatus === TerminalStatus.CONNECTING" <a-spin v-if="session.state.connectStatus === TerminalStatus.CONNECTING"
tip="正在连接会话..." tip="正在连接会话..."
dot /> dot />
<!-- 会话关闭 --> <!-- 会话关闭 -->
<a-card v-if="session.status.connectStatus === TerminalStatus.CLOSED" <a-card v-if="session.state.connectStatus === TerminalStatus.CLOSED"
class="rdp-status-wrapper" class="rdp-status-wrapper"
title="会话已关闭"> title="会话已关闭">
<!-- 错误信息 --> <!-- 错误信息 -->
@@ -20,18 +20,18 @@
</a-descriptions-item> </a-descriptions-item>
<!-- 错误码 --> <!-- 错误码 -->
<a-descriptions-item label="错误码"> <a-descriptions-item label="错误码">
{{ session.status.closeCode }} {{ session.state.closeCode }}
</a-descriptions-item> </a-descriptions-item>
<!-- 错误信息 --> <!-- 错误信息 -->
<a-descriptions-item label="错误信息"> <a-descriptions-item label="错误信息">
<span class="span-red"> <span class="span-red">
<!-- 异地登录 --> <!-- 异地登录 -->
<template v-if="session.status.closeCode === TerminalCloseCode.LOGGED_ELSEWHERE"> <template v-if="session.state.closeCode === TerminalCloseCode.LOGGED_ELSEWHERE">
{{ TerminalMessages.loggedElsewhere }} ({{ dateFormat() }}) {{ TerminalMessages.loggedElsewhere }} ({{ dateFormat() }})
</template> </template>
<!-- 其他错误 --> <!-- 其他错误 -->
<template v-else> <template v-else>
{{ session.status.closeMessage ?? '-' }} {{ session.state.closeMessage ?? '-' }}
</template> </template>
</span> </span>
</a-descriptions-item> </a-descriptions-item>
@@ -39,7 +39,7 @@
<!-- 按钮 --> <!-- 按钮 -->
<a-space class="status-button"> <a-space class="status-button">
<a-button @click="setVisible(false)">关闭</a-button> <a-button @click="setVisible(false)">关闭</a-button>
<a-button v-if="session.status.closeCode !== TerminalCloseCode.FORCE && session.status.canReconnect" <a-button v-if="session.state.closeCode !== TerminalCloseCode.FORCE && session.state.canReconnect"
type="primary" type="primary"
@click="reOpenSession(session.sessionKey)"> @click="reOpenSession(session.sessionKey)">
重连 重连

View File

@@ -45,7 +45,7 @@
</div> </div>
</div> </div>
<!-- 已关闭-右侧操作 --> <!-- 已关闭-右侧操作 -->
<div v-if="session?.status.connected === false && closeMessage !== undefined" <div v-if="session?.state.connected === false && closeMessage !== undefined"
class="sftp-table-header-right"> class="sftp-table-header-right">
<!-- 错误信息 --> <!-- 错误信息 -->
<a-tag class="close-message" <a-tag class="close-message"
@@ -54,7 +54,7 @@
已断开: {{ closeMessage }} 已断开: {{ closeMessage }}
</a-tag> </a-tag>
<!-- 重连 --> <!-- 重连 -->
<a-tooltip v-if="session?.status.connected === false && session?.status.canReconnect" <a-tooltip v-if="session?.state.connected === false && session?.state.canReconnect"
position="top" position="top"
:mini="true" :mini="true"
:overlay-inverse="true" :overlay-inverse="true"
@@ -245,7 +245,7 @@
// 设置命令编辑模式 // 设置命令编辑模式
const setPathEditable = (editable: boolean) => { const setPathEditable = (editable: boolean) => {
// 检查是否断开 // 检查是否断开
if (editable && !props.session?.status.connected) { if (editable && !props.session?.state.connected) {
return; return;
} }
pathEditable.value = editable; pathEditable.value = editable;
@@ -267,7 +267,7 @@
// 加载文件列表 // 加载文件列表
const loadFileList = (path: string = props.currentPath) => { const loadFileList = (path: string = props.currentPath) => {
// 检查是否断开 // 检查是否断开
if (!props.session?.status.connected) { if (!props.session?.state.connected) {
return; return;
} }
emits('loadFile', path); emits('loadFile', path);

View File

@@ -3,7 +3,7 @@
row-key="path" row-key="path"
ref="tableRef" ref="tableRef"
class="sftp-table" class="sftp-table"
:columns="columns" :columns="sftpColumns"
:row-selection="rowSelection" :row-selection="rowSelection"
:sticky-header="true" :sticky-header="true"
:data="list" :data="list"
@@ -149,7 +149,7 @@
import { dateFormat } from '@/utils'; import { dateFormat } from '@/utils';
import { setAutoFocus } from '@/utils/dom'; import { setAutoFocus } from '@/utils/dom';
import { copy } from '@/hooks/copy'; import { copy } from '@/hooks/copy';
import columns from './types/table.columns'; import { sftpColumns } from '@/views/terminal/types/table.columns';
import { FILE_TYPE, openSftpChmodModalKey, openSftpMoveModalKey } from '@/views/terminal/types/const'; import { FILE_TYPE, openSftpChmodModalKey, openSftpMoveModalKey } from '@/views/terminal/types/const';
const props = defineProps<{ const props = defineProps<{
@@ -205,7 +205,7 @@
const clickFilename = (record: TableData) => { const clickFilename = (record: TableData) => {
if (record.isDir) { if (record.isDir) {
// 检查是否断开 // 检查是否断开
if (!props.session?.status.connected) { if (!props.session?.state.connected) {
return; return;
} }
// 进入文件夹 // 进入文件夹
@@ -218,7 +218,7 @@
// 编辑文件 // 编辑文件
const editFile = (record: TableData) => { const editFile = (record: TableData) => {
// 检查是否断开 // 检查是否断开
if (!props.session?.status.connected) { if (!props.session?.state.connected) {
return; return;
} }
emits('editFile', record.name, record.path); emits('editFile', record.name, record.path);
@@ -228,7 +228,7 @@
// 删除文件 // 删除文件
const deleteFile = (path: string) => { const deleteFile = (path: string) => {
// 检查是否断开 // 检查是否断开
if (!props.session?.status.connected) { if (!props.session?.state.connected) {
return; return;
} }
emits('deleteFile', [path]); emits('deleteFile', [path]);
@@ -237,7 +237,7 @@
// 下载文件 // 下载文件
const downloadFile = (path: string) => { const downloadFile = (path: string) => {
// 检查是否断开 // 检查是否断开
if (!props.session?.status.connected) { if (!props.session?.state.connected) {
return; return;
} }
emits('download', [path], false); emits('download', [path], false);
@@ -246,7 +246,7 @@
// 移动文件 // 移动文件
const moveFile = (path: string) => { const moveFile = (path: string) => {
// 检查是否断开 // 检查是否断开
if (!props.session?.status.connected) { if (!props.session?.state.connected) {
return; return;
} }
openSftpMoveModal(props.session?.sessionKey as string, path); openSftpMoveModal(props.session?.sessionKey as string, path);
@@ -255,7 +255,7 @@
// 文件提权 // 文件提权
const chmodFile = (path: string, permission: number) => { const chmodFile = (path: string, permission: number) => {
// 检查是否断开 // 检查是否断开
if (!props.session?.status.connected) { if (!props.session?.state.connected) {
return; return;
} }
openSftpChmodModal(props.session?.sessionKey as string, path, permission); openSftpChmodModal(props.session?.sessionKey as string, path, permission);

View File

@@ -23,8 +23,8 @@
<!-- 连接状态 --> <!-- 连接状态 -->
<a-badge v-if="preference.sshActionBarSetting.connectStatus !== false" <a-badge v-if="preference.sshActionBarSetting.connectStatus !== false"
class="status-bridge" class="status-bridge"
:status="getDictValue(connectStatusKey, session ? session.status.connectStatus : TerminalStatus.CONNECTING, 'status')" :status="getDictValue(connectStatusKey, session ? session.state.connectStatus : TerminalStatus.CONNECTING, 'status')"
:text="getDictValue(connectStatusKey, session ? session.status.connectStatus : TerminalStatus.CONNECTING)" /> :text="getDictValue(connectStatusKey, session ? session.state.connectStatus : TerminalStatus.CONNECTING)" />
</div> </div>
</div> </div>
</template> </template>

View File

@@ -42,7 +42,7 @@ export interface SessionHostInfo {
} }
// 会话状态 // 会话状态
export interface ReactiveSessionStatus { export interface ReactiveSessionState {
// 连接状态 // 连接状态
connectStatus: number; connectStatus: number;
// 是否已连接 // 是否已连接
@@ -54,7 +54,7 @@ export interface ReactiveSessionStatus {
} }
// guacd 会话状态 // guacd 会话状态
export interface GuacdReactiveSessionStatus extends ReactiveSessionStatus { export interface GuacdReactiveSessionStatus extends ReactiveSessionState {
// 关闭码 // 关闭码
closeCode: number; closeCode: number;
// 关闭信息 // 关闭信息
@@ -76,7 +76,7 @@ export interface IDomViewportHandler {
} }
// 终端会话定义 // 终端会话定义
export interface ITerminalSession<Status extends ReactiveSessionStatus = ReactiveSessionStatus> { export interface ITerminalSession<State extends ReactiveSessionState = ReactiveSessionState> {
readonly type: string; readonly type: string;
// 会话主机信息 // 会话主机信息
@@ -88,7 +88,7 @@ export interface ITerminalSession<Status extends ReactiveSessionStatus = Reactiv
// 后端交互的唯一值 后端的 sessionId // 后端交互的唯一值 后端的 sessionId
sessionId: string; sessionId: string;
// 会话状态 // 会话状态
readonly status: Reactive<Status>; readonly state: Reactive<State>;
// 重新初始化 // 重新初始化
reInit: () => Promise<void>; reInit: () => Promise<void>;

View File

@@ -131,10 +131,10 @@ export default abstract class BaseGuacdChannel<T extends ITerminalSession<GuacdR
this.onerror(new Guacamole.Status(closeCode as any, msg)); this.onerror(new Guacamole.Status(closeCode as any, msg));
} }
// 设置关闭原因 // 设置关闭原因
this.session.status.closeCode = closeCode; this.session.state.closeCode = closeCode;
this.session.status.closeMessage = msg || TerminalMessages.sessionClosed; this.session.state.closeMessage = msg || TerminalMessages.sessionClosed;
// 设置重连状态 // 设置重连状态
this.session.status.canReconnect = TerminalCloseCode.FORCE !== closeCode; this.session.state.canReconnect = TerminalCloseCode.FORCE !== closeCode;
// 设置已关闭 // 设置已关闭
this.setState(Guacamole.Tunnel.State.CLOSED); this.setState(Guacamole.Tunnel.State.CLOSED);
this.session.setClosed(); this.session.setClosed();

View File

@@ -32,7 +32,7 @@ export default class SftpChannel extends BaseTerminalChannel<ISftpSession> imple
} }
const codeNumber = Number.parseInt(code); const codeNumber = Number.parseInt(code);
this.triggerClosed = true; this.triggerClosed = true;
this.session.status.canReconnect = TerminalCloseCode.FORCE !== codeNumber; this.session.state.canReconnect = TerminalCloseCode.FORCE !== codeNumber;
// 设置已关闭 // 设置已关闭
this.session.setClosed(); this.session.setClosed();
// sftp 设置状态 // sftp 设置状态

View File

@@ -36,13 +36,13 @@ export default class SshChannel extends BaseTerminalChannel<ISshSession> impleme
if (this.triggerClosed) { if (this.triggerClosed) {
return; return;
} }
const beforeConnected = this.session.status.connected; const beforeConnected = this.session.state.connected;
this.triggerClosed = true; this.triggerClosed = true;
// 设置重连状态 // 设置重连状态
this.session.status.canReconnect = TerminalCloseCode.FORCE !== Number.parseInt(code); this.session.state.canReconnect = TerminalCloseCode.FORCE !== Number.parseInt(code);
// 拼接关闭消息 // 拼接关闭消息
this.session.write((beforeConnected ? '\r\n\r\n' : '') + ansi(91, msg || '')); this.session.write((beforeConnected ? '\r\n\r\n' : '') + ansi(91, msg || ''));
if (this.session.status.canReconnect) { if (this.session.state.canReconnect) {
this.session.write('\r\n' + ansi(91, TerminalMessages.waitingReconnect) + '\r\n'); this.session.write('\r\n' + ansi(91, TerminalMessages.waitingReconnect) + '\r\n');
} }
// 设置已关闭 // 设置已关闭

View File

@@ -82,9 +82,9 @@ export default class SshSessionHandler implements ISshSessionHandler {
case 'openSftp': case 'openSftp':
case 'uploadFile': case 'uploadFile':
case 'checkAppendMissing': case 'checkAppendMissing':
return this.session.status.canWrite; return this.session.state.canWrite;
case 'disconnect': case 'disconnect':
return this.session.status.connected; return this.session.state.connected;
default: default:
return true; return true;
} }
@@ -193,7 +193,7 @@ export default class SshSessionHandler implements ISshSessionHandler {
// 字号增加 // 字号增加
private fontSizeAdd(addSize: number) { private fontSizeAdd(addSize: number) {
this.inst.options['fontSize'] = this.inst.options['fontSize'] as number + addSize; this.inst.options['fontSize'] = this.inst.options['fontSize'] as number + addSize;
if (this.session.status.connected) { if (this.session.state.connected) {
this.session.fit(); this.session.fit();
this.inst.focus(); this.inst.focus();
} }

View File

@@ -1,21 +1,21 @@
import type { Reactive } from 'vue'; import type { Reactive } from 'vue';
import { reactive } from 'vue'; import { reactive } from 'vue';
import type { ITerminalChannel, ITerminalSession, ReactiveSessionStatus, SessionHostInfo, TerminalSessionTabItem } from '@/views/terminal/interfaces'; import type { ITerminalChannel, ITerminalSession, ReactiveSessionState, SessionHostInfo, TerminalSessionTabItem } from '@/views/terminal/interfaces';
import { TerminalStatus } from '@/views/terminal/types/const'; import { TerminalStatus } from '@/views/terminal/types/const';
// 会话基类 // 会话基类
export default abstract class BaseSession<Status extends ReactiveSessionStatus, Channel extends ITerminalChannel> export default abstract class BaseSession<State extends ReactiveSessionState, Channel extends ITerminalChannel>
implements ITerminalSession<Status> { implements ITerminalSession<State> {
public readonly type: string; public readonly type: string;
public readonly info: SessionHostInfo; public readonly info: SessionHostInfo;
public readonly panelIndex: number; public readonly panelIndex: number;
public readonly status: Reactive<Status>; public readonly state: Reactive<State>;
public readonly sessionKey: string; public readonly sessionKey: string;
public sessionId: string; public sessionId: string;
protected channel: Channel; protected channel: Channel;
protected constructor(item: TerminalSessionTabItem, reactiveStatus: Partial<Status>) { protected constructor(item: TerminalSessionTabItem, state: Partial<State>) {
this.type = item.type; this.type = item.type;
this.info = { this.info = {
hostId: item.hostId, hostId: item.hostId,
@@ -26,13 +26,13 @@ export default abstract class BaseSession<Status extends ReactiveSessionStatus,
this.panelIndex = item.panelIndex; this.panelIndex = item.panelIndex;
this.sessionKey = item.key; this.sessionKey = item.key;
this.sessionId = item.key; this.sessionId = item.key;
this.status = reactive({ this.state = reactive({
connectStatus: TerminalStatus.CONNECTING, connectStatus: TerminalStatus.CONNECTING,
connected: false, connected: false,
canWrite: false, canWrite: false,
canReconnect: false, canReconnect: false,
...reactiveStatus, ...state,
} as Status); } as State);
this.channel = undefined as unknown as Channel; this.channel = undefined as unknown as Channel;
} }
@@ -62,28 +62,28 @@ export default abstract class BaseSession<Status extends ReactiveSessionStatus,
// 设置是否可写 // 设置是否可写
setCanWrite(canWrite: boolean): void { setCanWrite(canWrite: boolean): void {
this.status.canWrite = canWrite; this.state.canWrite = canWrite;
} }
// 设置连接中 // 设置连接中
setConnecting(): void { setConnecting(): void {
this.status.connected = false; this.state.connected = false;
this.status.canWrite = false; this.state.canWrite = false;
this.status.connectStatus = TerminalStatus.CONNECTING; this.state.connectStatus = TerminalStatus.CONNECTING;
} }
// 设置已连接 // 设置已连接
setConnected(): void { setConnected(): void {
// 设置状态 // 设置状态
this.status.connected = true; this.state.connected = true;
this.status.connectStatus = TerminalStatus.CONNECTED; this.state.connectStatus = TerminalStatus.CONNECTED;
} }
// 设置已关闭 // 设置已关闭
setClosed(): void { setClosed(): void {
this.status.connected = false; this.state.connected = false;
this.status.canWrite = false; this.state.canWrite = false;
this.status.connectStatus = TerminalStatus.CLOSED; this.state.connectStatus = TerminalStatus.CLOSED;
} }
} }

View File

@@ -128,7 +128,7 @@ export default class RdpSession extends BaseSession<GuacdReactiveSessionStatus,
// 定时检查是否连接成功 // 定时检查是否连接成功
this.connectTimeoutId = window.setTimeout(() => { this.connectTimeoutId = window.setTimeout(() => {
// 未连接上证明连接超时 // 未连接上证明连接超时
if (!this.status.connected) { if (!this.state.connected) {
this.channel.closeTunnel(TerminalCloseCode.CONNECT_TIMEOUT, TerminalMessages.rdpConnectTimeout); this.channel.closeTunnel(TerminalCloseCode.CONNECT_TIMEOUT, TerminalMessages.rdpConnectTimeout);
} }
}, CONNECT_TIMEOUT); }, CONNECT_TIMEOUT);
@@ -217,7 +217,7 @@ export default class RdpSession extends BaseSession<GuacdReactiveSessionStatus,
// 是否可写 // 是否可写
isWriteable(): boolean { isWriteable(): boolean {
return this.status.connected && this.status.canWrite; return this.state.connected && this.state.canWrite;
} }
// 设置为已关闭 // 设置为已关闭

View File

@@ -1,4 +1,4 @@
import type { ISftpChannel, ISftpSession, ISftpSessionHandler, ReactiveSessionStatus, TerminalSessionTabItem } from '@/views/terminal/interfaces'; import type { ISftpChannel, ISftpSession, ISftpSessionHandler, ReactiveSessionState, TerminalSessionTabItem } from '@/views/terminal/interfaces';
import { h } from 'vue'; import { h } from 'vue';
import { InputProtocol } from '@/views/terminal/types/protocol'; import { InputProtocol } from '@/views/terminal/types/protocol';
import { Modal } from '@arco-design/web-vue'; import { Modal } from '@arco-design/web-vue';
@@ -6,7 +6,7 @@ import BaseSession from './base-session';
import SftpChannel from '../channel/sftp-channel'; import SftpChannel from '../channel/sftp-channel';
// SFTP 会话实现 // SFTP 会话实现
export default class SftpSession extends BaseSession<ReactiveSessionStatus, ISftpChannel> implements ISftpSession { export default class SftpSession extends BaseSession<ReactiveSessionState, ISftpChannel> implements ISftpSession {
public handler: ISftpSessionHandler; public handler: ISftpSessionHandler;

View File

@@ -1,4 +1,4 @@
import type { ISshChannel, ISshSession, ISshSessionHandler, ReactiveSessionStatus, SshInitConfig, TerminalSessionTabItem } from '@/views/terminal/interfaces'; import type { ISshChannel, ISshSession, ISshSessionHandler, ReactiveSessionState, SshInitConfig, TerminalSessionTabItem } from '@/views/terminal/interfaces';
import type { UnwrapRef } from 'vue'; import type { UnwrapRef } from 'vue';
import type { ISearchOptions } from '@xterm/addon-search'; import type { ISearchOptions } from '@xterm/addon-search';
import { SearchAddon } from '@xterm/addon-search'; import { SearchAddon } from '@xterm/addon-search';
@@ -23,7 +23,7 @@ import SshChannel from '../channel/ssh-channel';
import SshSessionHandler from '../handler/ssh-session-handler'; import SshSessionHandler from '../handler/ssh-session-handler';
// SSH 会话实现 // SSH 会话实现
export default class SshSession extends BaseSession<ReactiveSessionStatus, ISshChannel> implements ISshSession { export default class SshSession extends BaseSession<ReactiveSessionState, ISshChannel> implements ISshSession {
public inst: Terminal; public inst: Terminal;
@@ -102,9 +102,9 @@ export default class SshSession extends BaseSession<ReactiveSessionStatus, ISshC
e.preventDefault(); e.preventDefault();
} }
// 检查重新连接 // 检查重新连接
if (!this.status.connected && this.status.canReconnect && e.key === 'Enter') { if (!this.state.connected && this.state.canReconnect && e.key === 'Enter') {
// 防止重复回车 // 防止重复回车
this.status.canReconnect = false; this.state.canReconnect = false;
// 异步作用域重新连接 // 异步作用域重新连接
setTimeout(async () => { setTimeout(async () => {
await useTerminalStore().reOpenSession(this.sessionKey); await useTerminalStore().reOpenSession(this.sessionKey);
@@ -129,7 +129,7 @@ export default class SshSession extends BaseSession<ReactiveSessionStatus, ISshC
private registerEvent(dom: HTMLElement, preference: UnwrapRef<TerminalPreference>) { private registerEvent(dom: HTMLElement, preference: UnwrapRef<TerminalPreference>) {
// 注册输入事件 // 注册输入事件
this.inst.onData(s => { this.inst.onData(s => {
if (!this.status.canWrite || !this.status.connected) { if (!this.state.canWrite || !this.state.connected) {
return; return;
} }
// 输入 // 输入
@@ -153,7 +153,7 @@ export default class SshSession extends BaseSession<ReactiveSessionStatus, ISshC
} }
// 注册 resize 事件 // 注册 resize 事件
this.inst.onResize(({ cols, rows }) => { this.inst.onResize(({ cols, rows }) => {
if (!this.status.connected) { if (!this.state.connected) {
return; return;
} }
this.channel.send(InputProtocol.RESIZE, { this.channel.send(InputProtocol.RESIZE, {
@@ -165,7 +165,7 @@ export default class SshSession extends BaseSession<ReactiveSessionStatus, ISshC
addEventListen(dom, 'contextmenu', async () => { addEventListen(dom, 'contextmenu', async () => {
// 右键粘贴逻辑 // 右键粘贴逻辑
if (preference.interactSetting.rightClickPaste) { if (preference.interactSetting.rightClickPaste) {
if (!this.status.canWrite || !this.status.connected) { if (!this.state.canWrite || !this.state.connected) {
return; return;
} }
// 未开启右键选中 || 开启并无选中的内容则粘贴 // 未开启右键选中 || 开启并无选中的内容则粘贴

View File

@@ -89,7 +89,7 @@ export default class RdpFileDownloadTask extends BaseFileTransferTask implements
} }
this.state.aborted = true; this.state.aborted = true;
try { try {
if (this.session.status.connected) { if (this.session.state.connected) {
if (this.stream) { if (this.stream) {
// 发送 ACK // 发送 ACK
this.stream.sendAck('Aborted', Guacamole.Status.Code.RESOURCE_CLOSED); this.stream.sendAck('Aborted', Guacamole.Status.Code.RESOURCE_CLOSED);

View File

@@ -117,7 +117,7 @@ export default class RdpFileUploadTask extends BaseFileTransferTask implements I
} }
this.state.aborted = true; this.state.aborted = true;
try { try {
if (this.session.status.connected) { if (this.session.state.connected) {
// 关闭流 // 关闭流
if (this.stream) { if (this.stream) {
this.stream.sendEnd(); this.stream.sendEnd();

View File

@@ -485,6 +485,12 @@ export const TransferReceiver = {
ABORT: 'abort', ABORT: 'abort',
}; };
// 路径书签类型
export const PathBookmarkType = {
FILE: 'FILE',
DIR: 'DIR',
};
// 打开 extraModal key // 打开 extraModal key
export const openExtraModalKey = Symbol(); export const openExtraModalKey = Symbol();

View File

@@ -0,0 +1,44 @@
import type { FieldRule } from '@arco-design/web-vue';
// 代码片段规则
export const commandSnippetFormRules = {
groupId: [{
message: '请选择分组'
}],
name: [{
required: true,
message: '请输入名称'
}, {
maxLength: 64,
message: '名称长度不能大于64位'
}],
command: [{
required: true,
message: '请输入代码片段'
}],
} as Record<string, FieldRule | FieldRule[]>;
// 书签路径规则
export const bookmarkFormRules = {
groupId: [{
message: '请选择分组'
}],
name: [{
required: true,
message: '请输入名称'
}, {
maxLength: 64,
message: '名称长度不能大于64位'
}],
type: [{
required: true,
message: '请选择类型'
}],
path: [{
required: true,
message: '请输入路径'
}, {
maxLength: 1000,
message: '路径长度不能大于1000位'
}],
} as Record<string, FieldRule | FieldRule[]>;

View File

@@ -1,8 +1,8 @@
import type { TableColumnData } from '@arco-design/web-vue'; import type { TableColumnData } from '@arco-design/web-vue';
import { getFileSize } from '@/utils/file'; import { getFileSize } from '@/utils/file';
// 表格列 // SFTP 表格列
const columns = [ export const sftpColumns = [
{ {
title: '名称', title: '名称',
dataIndex: 'name', dataIndex: 'name',
@@ -45,4 +45,4 @@ const columns = [
}, },
] as TableColumnData[]; ] as TableColumnData[];
export default columns; export default sftpColumns;