diff --git a/docs/_sidebar.md b/docs/_sidebar.md
index 804bf10a..3ac874f0 100644
--- a/docs/_sidebar.md
+++ b/docs/_sidebar.md
@@ -9,7 +9,8 @@
* 操作手册
* [资产管理](operator/asset.md)
* [主机运维](operator/host-ops.md)
- * [命令执行](operator/exec.md)
* [运维审计](operator/asset-audit.md)
+ * [批量执行](operator/exec.md)
+ * [计划任务](operator/job.md)
* [用户管理](operator/user.md)
* [系统管理](operator/system.md)
diff --git a/docs/operator/exec.md b/docs/operator/exec.md
index 4a474498..189d1a25 100644
--- a/docs/operator/exec.md
+++ b/docs/operator/exec.md
@@ -1,4 +1,4 @@
-### 批量执行
+### 命令执行
批量执行 ssh 主机 shell 脚本。
@@ -22,29 +22,6 @@
* 日志: 查看执行日志, ctrl + 左键点击会用新页面打开
* 下载: 下载执行日志
-### 计划任务
-
-维护计划任务, 定时执行命令。
-
-* 新增: 新增计划任务
-* 详情: 查看计划任务详情
-* 修改: 修改计划任务
-* 状态: 修改计划任务状态
-* 手动触发: 手动触发计划任务
-* 删除: 删除计划任务
-
-### 计划任务日志
-
-查看计划任务执行日志
-
-* 清空: 清空执行日志
-* 删除: 删除执行日志
-* 命令: 查看执行时的命令
-* 参数: 查看执行时的参数
-* 中断: 中断命令执行
-* 日志: 查看执行日志, ctrl + 左键点击会用新页面打开
-* 下载: 下载执行日志
-
### 执行模板
用来维护批量执行的命令模板, 支持动态参数, 使用 `@{{ xxx }}` 来替换命令参数。
@@ -54,7 +31,7 @@
* 修改: 修改执行模板
* 删除: 删除执行模板
-> 日志面板快捷键
+### 日志面板快捷键
* 回车: `Enter`
* 向上滚动一行: `↑`
@@ -66,7 +43,7 @@
* 搜索: `ctrl` `F`
* 清空: `ctrl` `L`
-> 命令内置参数
+### 命令内置参数
⚡ 使用 `@{{ xxx }}` 来替换命令参数
diff --git a/docs/operator/job.md b/docs/operator/job.md
new file mode 100644
index 00000000..f6f1289c
--- /dev/null
+++ b/docs/operator/job.md
@@ -0,0 +1,24 @@
+### 任务列表
+
+⚡ 内置参数同 `批量执行 > 命令执行` [查看](/operator/exec.md?id=命令内置参数)
+
+维护计划任务, 定时执行命令。
+
+* 新增: 新增计划任务
+* 详情: 查看计划任务详情
+* 修改: 修改计划任务
+* 状态: 修改计划任务状态
+* 手动触发: 手动触发计划任务
+* 删除: 删除计划任务
+
+### 任务日志
+
+查看计划任务执行日志
+
+* 清空: 清空执行日志
+* 删除: 删除执行日志
+* 命令: 查看执行时的命令
+* 参数: 查看执行时的参数
+* 中断: 中断命令执行
+* 日志: 查看执行日志, ctrl + 左键点击会用新页面打开
+* 下载: 下载执行日志
diff --git a/orion-ops-framework/orion-ops-spring-boot-starter-mybatis/src/main/java/com/orion/ops/framework/mybatis/core/generator/CodeGenerators.java b/orion-ops-framework/orion-ops-spring-boot-starter-mybatis/src/main/java/com/orion/ops/framework/mybatis/core/generator/CodeGenerators.java
index 7a6eeac4..f6c99b98 100644
--- a/orion-ops-framework/orion-ops-spring-boot-starter-mybatis/src/main/java/com/orion/ops/framework/mybatis/core/generator/CodeGenerators.java
+++ b/orion-ops-framework/orion-ops-spring-boot-starter-mybatis/src/main/java/com/orion/ops/framework/mybatis/core/generator/CodeGenerators.java
@@ -51,7 +51,7 @@ public class CodeGenerators {
// .build(),
Template.create("upload_task", "上传任务", "upload")
.disableUnitTest()
- .vue("exec", "batch-upload")
+ .vue("exec", "upload-task")
.enableRowSelection()
.dict("uploadTaskStatus", "status")
.comment("上传任务状态")
@@ -61,7 +61,7 @@ public class CodeGenerators {
.build(),
Template.create("upload_task_file", "上传任务文件", "upload")
.disableUnitTest()
- .vue("exec", "batch-upload-file")
+ .vue("exec", "upload-task-file")
.enableRowSelection()
.dict("uploadTaskFileStatus", "status")
.comment("上传任务文件状态")
diff --git a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/controller/UploadTaskController.java b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/controller/UploadTaskController.java
index b5ad16a7..c0f1b5e4 100644
--- a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/controller/UploadTaskController.java
+++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/controller/UploadTaskController.java
@@ -43,8 +43,6 @@ public class UploadTaskController {
@Resource
private UploadTaskService uploadTaskService;
- // TODO 字典颜色 菜单 操作日志
-
@OperatorLog(UploadTaskOperatorType.UPLOAD)
@PostMapping("/create")
@Operation(summary = "创建上传任务")
@@ -106,7 +104,7 @@ public class UploadTaskController {
}
@PostMapping("/query-count")
- @Operation(summary = "查询主机连接日志数量")
+ @Operation(summary = "查询上传任务数量")
@PreAuthorize("@ss.hasPermission('asset:upload-task:management:clear')")
public Long getUploadTaskCount(@RequestBody UploadTaskQueryRequest request) {
return uploadTaskService.getUploadTaskCount(request);
@@ -114,7 +112,7 @@ public class UploadTaskController {
@OperatorLog(UploadTaskOperatorType.CLEAR)
@PostMapping("/clear")
- @Operation(summary = "清空主机连接日志")
+ @Operation(summary = "清空上传任务")
@PreAuthorize("@ss.hasPermission('asset:upload-task:management:clear')")
public Integer clearUploadTask(@RequestBody UploadTaskQueryRequest request) {
return uploadTaskService.clearUploadTask(request);
diff --git a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/define/operator/UploadTaskOperatorType.java b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/define/operator/UploadTaskOperatorType.java
index 1b161e73..1ee77105 100644
--- a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/define/operator/UploadTaskOperatorType.java
+++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/define/operator/UploadTaskOperatorType.java
@@ -28,7 +28,7 @@ public class UploadTaskOperatorType extends InitializingOperatorTypes {
@Override
public OperatorType[] types() {
return new OperatorType[]{
- new OperatorType(M, UPLOAD, "批量上传文件 ${count}个 (${name})"),
+ new OperatorType(M, UPLOAD, "批量上传文件 ${count}个 (${name})"),
new OperatorType(M, CANCEL, "取消上传文件 ${name}"),
new OperatorType(H, DELETE, "删除上传记录 ${count}条"),
new OperatorType(H, CLEAR, "清理上传记录 ${count}条"),
diff --git a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/upload/task/FileUploadTask.java b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/upload/task/FileUploadTask.java
index a07149ab..638efc78 100644
--- a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/upload/task/FileUploadTask.java
+++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/upload/task/FileUploadTask.java
@@ -135,6 +135,7 @@ public class FileUploadTask implements IFileUploadTask {
List files = v.stream()
.map(s -> FileUploadFileItemDTO.builder()
.id(s.getId())
+ .fileId(s.getFileId())
.remotePath(record.getRemotePath() + Const.SLASH + s.getFilePath())
.status(UploadTaskFileStatusEnum.WAITING.name())
.current(0L)
diff --git a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/upload/uploader/FileUploader.java b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/upload/uploader/FileUploader.java
index 693b3a86..c118f3c8 100644
--- a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/upload/uploader/FileUploader.java
+++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/upload/uploader/FileUploader.java
@@ -100,7 +100,7 @@ public class FileUploader implements IFileUploader {
private boolean initSession() {
log.info("HostFileUploader.initSession start taskId: {}, hostId: {}", taskId, hostId);
try {
- // TODO 测试 打开 executor 后 是否会connect, 不需要的话就关闭 executor 然后重新打开
+ // TODO 测试看看有没有问题, 则修改为 打开 executor 后 是否会connect, 不需要的话就关闭 executor 然后重新打开
// 打开会话
HostTerminalConnectDTO connectInfo = hostTerminalService.getTerminalConnectInfo(hostId);
this.sessionStore = hostTerminalService.openSessionStore(connectInfo);
diff --git a/orion-ops-ui/src/api/asset/host-terminal.ts b/orion-ops-ui/src/api/asset/host-terminal.ts
index cd12c1f1..3fdde0c0 100644
--- a/orion-ops-ui/src/api/asset/host-terminal.ts
+++ b/orion-ops-ui/src/api/asset/host-terminal.ts
@@ -1,4 +1,5 @@
import axios from 'axios';
+import { createAppWebSocket } from '@/utils/http';
// 终端主题
export interface TerminalTheme {
@@ -49,3 +50,17 @@ export function getTerminalThemes() {
export function getTerminalAccessToken() {
return axios.get('/asset/host-terminal/access');
}
+
+/**
+ * 打开主机终端 websocket
+ */
+export const openHostTerminalChannel = (accessToken: string) => {
+ return createAppWebSocket(`/host/terminal/${accessToken}`);
+};
+
+/**
+ * 打开主机传输 websocket
+ */
+export const openHostTransferChannel = (accessToken: string) => {
+ return createAppWebSocket(`/host/transfer/${accessToken}`);
+};
diff --git a/orion-ops-ui/src/api/exec/exec-log.ts b/orion-ops-ui/src/api/exec/exec-log.ts
index 6dcdd54c..1a3f4245 100644
--- a/orion-ops-ui/src/api/exec/exec-log.ts
+++ b/orion-ops-ui/src/api/exec/exec-log.ts
@@ -1,5 +1,6 @@
import type { Pagination } from '@/types/global';
import type { TableData } from '@arco-design/web-vue/es/table/interface';
+import { createAppWebSocket } from '@/utils/http';
/**
* 执行日志查询请求
@@ -82,3 +83,10 @@ export interface ExecLogInterruptRequest {
logId?: number;
hostLogId?: number;
}
+
+/**
+ * 打开执行日志 websocket
+ */
+export const openExecLogChannel = (token: string) => {
+ return createAppWebSocket(`/exec/log/${token}`);
+};
diff --git a/orion-ops-ui/src/api/exec/upload-task.ts b/orion-ops-ui/src/api/exec/upload-task.ts
new file mode 100644
index 00000000..93c35628
--- /dev/null
+++ b/orion-ops-ui/src/api/exec/upload-task.ts
@@ -0,0 +1,146 @@
+import type { DataGrid, Pagination } from '@/types/global';
+import type { TableData } from '@arco-design/web-vue/es/table/interface';
+import axios from 'axios';
+import qs from 'query-string';
+
+/**
+ * 上传任务创建请求
+ */
+export interface UploadTaskCreateRequest {
+ userId?: number;
+ username?: string;
+ remotePath?: string;
+ description?: string;
+ status?: string;
+ extraInfo?: string;
+ startTime?: string;
+ endTime?: string;
+}
+
+/**
+ * 上传任务创建响应
+ */
+export interface UploadTaskCreateResponse {
+ id: number;
+ token: string;
+}
+
+/**
+ * 上传任务请求
+ */
+export interface UploadTaskRequest {
+ id?: number;
+}
+
+/**
+ * 上传任务查询请求
+ */
+export interface UploadTaskQueryRequest extends Pagination {
+ id?: number;
+ userId?: number;
+ remotePath?: string;
+ description?: string;
+ status?: string;
+ createTimeRange?: string[];
+}
+
+/**
+ * 上传任务查询响应
+ */
+export interface UploadTaskQueryResponse extends TableData {
+ id: number;
+ userId: number;
+ username: string;
+ remotePath: string;
+ description: string;
+ status: string;
+ extraInfo: string;
+ startTime: number;
+ endTime: number;
+ createTime: number;
+ files: Array;
+}
+
+/**
+ * 上传任务文件查询响应
+ */
+export interface UploadTaskFileQueryResponse {
+ id: number;
+ taskId: number;
+ hostId: number;
+ fileId: string;
+ filePath: string;
+ fileSize: number;
+ status: string;
+ startTime: number;
+ endTime: number;
+ current: number;
+}
+
+/**
+ * 创建上传任务
+ */
+export function createUploadTask(request: UploadTaskCreateRequest) {
+ return axios.post('/asset/upload-task/create', request);
+}
+
+/**
+ * 创建上传任务
+ */
+export function startUploadTask(request: UploadTaskRequest) {
+ return axios.post('/asset/upload-task/start', request);
+}
+
+/**
+ * 创建上传任务
+ */
+export function cancelUploadTask(request: UploadTaskRequest) {
+ return axios.post('/asset/upload-task/cancel', request);
+}
+
+/**
+ * 查询上传任务
+ */
+export function getUploadTask(id: number) {
+ return axios.get('/asset/upload-task/get', { params: { id } });
+}
+
+/**
+ * 分页查询上传任务
+ */
+export function getUploadTaskPage(request: UploadTaskQueryRequest) {
+ return axios.post>('/asset/upload-task/query', request);
+}
+
+/**
+ * 删除上传任务
+ */
+export function deleteUploadTask(id: number) {
+ return axios.delete('/asset/upload-task/delete', { params: { id } });
+}
+
+/**
+ * 批量删除上传任务
+ */
+export function batchDeleteUploadTask(idList: Array) {
+ return axios.delete('/asset/upload-task/batch-delete', {
+ params: { idList },
+ paramsSerializer: params => {
+ return qs.stringify(params, { arrayFormat: 'comma' });
+ }
+ });
+}
+
+/**
+ * 查询主机连接日志数量
+ */
+export function getUploadTaskCount(request: UploadTaskQueryRequest) {
+ return axios.post('/asset/upload-task/query-count', request);
+}
+
+/**
+ * 清空主机连接日志
+ */
+export function clearUploadTask(request: UploadTaskQueryRequest) {
+ return axios.post('/asset/upload-task/clear', request);
+}
diff --git a/orion-ops-ui/src/api/exec/exec-job-log.ts b/orion-ops-ui/src/api/job/exec-job-log.ts
similarity index 99%
rename from orion-ops-ui/src/api/exec/exec-job-log.ts
rename to orion-ops-ui/src/api/job/exec-job-log.ts
index d7ed05e1..48b4445e 100644
--- a/orion-ops-ui/src/api/exec/exec-job-log.ts
+++ b/orion-ops-ui/src/api/job/exec-job-log.ts
@@ -6,7 +6,7 @@ import type {
ExecLogStatusResponse,
ExecLogTailRequest,
ExecLogInterruptRequest
-} from './exec-log';
+} from '../exec/exec-log';
import axios from 'axios';
import qs from 'query-string';
diff --git a/orion-ops-ui/src/api/exec/exec-job.ts b/orion-ops-ui/src/api/job/exec-job.ts
similarity index 100%
rename from orion-ops-ui/src/api/exec/exec-job.ts
rename to orion-ops-ui/src/api/job/exec-job.ts
diff --git a/orion-ops-ui/src/api/system/upload.ts b/orion-ops-ui/src/api/system/upload.ts
new file mode 100644
index 00000000..71828659
--- /dev/null
+++ b/orion-ops-ui/src/api/system/upload.ts
@@ -0,0 +1,8 @@
+import { createAppWebSocket } from '@/utils/http';
+
+/**
+ * 打开文件上传 websocket
+ */
+export const openFileUploadChannel = (uploadToken: string) => {
+ return createAppWebSocket(`"/file/upload/${uploadToken}`);
+};
diff --git a/orion-ops-ui/src/components/app/app-footer/index.vue b/orion-ops-ui/src/components/app/app-footer/index.vue
index 1c4d6803..612112a0 100644
--- a/orion-ops-ui/src/components/app/app-footer/index.vue
+++ b/orion-ops-ui/src/components/app/app-footer/index.vue
@@ -11,8 +11,8 @@
v{{ version }} 开源版
- Copyright 2024 Li Jiahang All rights reserved.
-
+ Copyright {{ new Date().getFullYear() }} Li Jiahang All rights reserved.
+
diff --git a/orion-ops-ui/src/components/exec/log/panel-modal/index.vue b/orion-ops-ui/src/components/exec/log/panel-modal/index.vue
index a5879615..9d5e7f1c 100644
--- a/orion-ops-ui/src/components/exec/log/panel-modal/index.vue
+++ b/orion-ops-ui/src/components/exec/log/panel-modal/index.vue
@@ -36,7 +36,7 @@
import useLoading from '@/hooks/loading';
import { nextTick, ref } from 'vue';
import { getExecCommandLog } from '@/api/exec/exec-command-log';
- import { getExecJobLog } from '@/api/exec/exec-job-log';
+ import { getExecJobLog } from '@/api/job/exec-job-log';
import ExecLogPanel from '../panel/index.vue';
const props = defineProps<{
diff --git a/orion-ops-ui/src/components/exec/log/panel/index.vue b/orion-ops-ui/src/components/exec/log/panel/index.vue
index 68d5f844..fffcc9c5 100644
--- a/orion-ops-ui/src/components/exec/log/panel/index.vue
+++ b/orion-ops-ui/src/components/exec/log/panel/index.vue
@@ -29,7 +29,7 @@
import type { ExecType } from '../const';
import { onUnmounted, ref, nextTick, onMounted } from 'vue';
import { getExecCommandLogStatus } from '@/api/exec/exec-command-log';
- import { getExecJobLogStatus } from '@/api/exec/exec-job-log';
+ import { getExecJobLogStatus } from '@/api/job/exec-job-log';
import { dictKeys, execHostStatus, execStatus } from '../const';
import { useDictStore } from '@/store';
import ExecHost from './exec-host.vue';
diff --git a/orion-ops-ui/src/components/exec/log/panel/log-appender.ts b/orion-ops-ui/src/components/exec/log/panel/log-appender.ts
index 4380b027..063b6131 100644
--- a/orion-ops-ui/src/components/exec/log/panel/log-appender.ts
+++ b/orion-ops-ui/src/components/exec/log/panel/log-appender.ts
@@ -2,11 +2,10 @@ import type { ILogAppender, LogAddons, LogAppenderConf, LogDomRef } from './appe
import { LogAppenderOptions } from './appender-const';
import type { ExecType } from '../const';
import type { ExecLogTailRequest } from '@/api/exec/exec-log';
+import { openExecLogChannel } from '@/api/exec/exec-log';
import { getExecCommandLogTailToken } from '@/api/exec/exec-command-log';
-import { getExecJobLogTailToken } from '@/api/exec/exec-job-log';
-import { webSocketBaseUrl } from '@/utils/env';
+import { getExecJobLogTailToken } from '@/api/job/exec-job-log';
import { Message } from '@arco-design/web-vue';
-import { createWebSocket } from '@/utils';
import { useDebounceFn } from '@vueuse/core';
import { addEventListen, removeEventListen } from '@/utils/event';
import { copy as copyText } from '@/hooks/copy';
@@ -158,7 +157,7 @@ export default class LogAppender implements ILogAppender {
const { data } = await tokenMaker;
// 打开会话
try {
- this.client = await createWebSocket(`${webSocketBaseUrl}/exec/log/${data}`);
+ this.client = await openExecLogChannel(data);
} catch (e) {
Message.error('连接失败');
console.error('log error', e);
diff --git a/orion-ops-ui/src/components/exec/log/panel/log-item.vue b/orion-ops-ui/src/components/exec/log/panel/log-item.vue
index 9d424864..2332945b 100644
--- a/orion-ops-ui/src/components/exec/log/panel/log-item.vue
+++ b/orion-ops-ui/src/components/exec/log/panel/log-item.vue
@@ -174,7 +174,7 @@
import { formatDuration } from '@/utils';
import { useDictStore } from '@/store';
import { downloadExecCommandLogFile } from '@/api/exec/exec-command-log';
- import { downloadExecJobLogFile } from '@/api/exec/exec-job-log';
+ import { downloadExecJobLogFile } from '@/api/job/exec-job-log';
import { downloadFile } from '@/utils/file';
import XtermSearchModal from '@/components/xtrem/search-modal/index.vue';
import 'xterm/css/xterm.css';
diff --git a/orion-ops-ui/src/router/routes/modules/exec.ts b/orion-ops-ui/src/router/routes/modules/exec.ts
index 9e4eb3b9..15fdb633 100644
--- a/orion-ops-ui/src/router/routes/modules/exec.ts
+++ b/orion-ops-ui/src/router/routes/modules/exec.ts
@@ -17,6 +17,16 @@ const EXEC: AppRouteRecordRaw[] = [
path: '/exec-log',
component: () => import('@/views/exec/exec-command-log/index.vue'),
},
+ {
+ name: 'batchUpload',
+ path: '/batch-upload',
+ component: () => import('@/views/exec/batch-upload/index.vue'),
+ },
+ {
+ name: 'uploadTaskLog',
+ path: '/upload-log',
+ component: () => import('@/views/exec/upload-task-log/index.vue'),
+ },
{
name: 'execTemplate',
path: '/exec-template',
diff --git a/orion-ops-ui/src/store/modules/cache/index.ts b/orion-ops-ui/src/store/modules/cache/index.ts
index b99d9887..ec1b8bda 100644
--- a/orion-ops-ui/src/store/modules/cache/index.ts
+++ b/orion-ops-ui/src/store/modules/cache/index.ts
@@ -13,7 +13,7 @@ import { getHostGroupTree } from '@/api/asset/host-group';
import { getMenuList } from '@/api/system/menu';
import { getCurrentAuthorizedHostIdentity, getCurrentAuthorizedHostKey } from '@/api/asset/asset-authorized-data';
import { getCommandSnippetGroupList } from '@/api/asset/command-snippet-group';
-import { getExecJobList } from '@/api/exec/exec-job';
+import { getExecJobList } from '@/api/job/exec-job';
import { getPathBookmarkGroupList } from '@/api/asset/path-bookmark-group';
export type CacheType = 'users' | 'menus' | 'roles'
diff --git a/orion-ops-ui/src/types/const.ts b/orion-ops-ui/src/types/const.ts
index 516f7dbb..25d553de 100644
--- a/orion-ops-ui/src/types/const.ts
+++ b/orion-ops-ui/src/types/const.ts
@@ -2,7 +2,7 @@
export const AdminRoleCode = 'admin';
// 表格视图分页数配置
-export const TablePageSizeOptions = [10, 20, 30, 50, 100];
+export const TablePageSizeOptions = [10, 15, 20, 30, 50, 100];
// 卡片视图分页数配置
export const CardPageSizeOptions = [12, 18, 36, 48, 96];
diff --git a/orion-ops-ui/src/utils/http.ts b/orion-ops-ui/src/utils/http.ts
new file mode 100644
index 00000000..790b7458
--- /dev/null
+++ b/orion-ops-ui/src/utils/http.ts
@@ -0,0 +1,25 @@
+import { webSocketBaseUrl } from '@/utils/env';
+
+/**
+ * 创建应用 websocket
+ */
+export const createAppWebSocket = (url: string): Promise => {
+ return createWebSocket(webSocketBaseUrl + url);
+};
+
+/**
+ * 创建 websocket
+ */
+export const createWebSocket = (url: string): Promise => {
+ return new Promise((resolve, reject) => {
+ const socket = new WebSocket(url);
+
+ socket.onopen = () => {
+ resolve(socket);
+ };
+
+ socket.onerror = e => {
+ reject(e);
+ };
+ });
+};
diff --git a/orion-ops-ui/src/utils/index.ts b/orion-ops-ui/src/utils/index.ts
index 077ffaaa..9b2be29c 100644
--- a/orion-ops-ui/src/utils/index.ts
+++ b/orion-ops-ui/src/utils/index.ts
@@ -197,23 +197,6 @@ export const objectTruthKeyCount = (obj: any, ignore: string[] = []) => {
}, 0);
};
-/**
- * 创建 websocket
- */
-export const createWebSocket = async (url: string) => {
- return new Promise((resolve, reject) => {
- const socket = new WebSocket(url);
-
- socket.onopen = () => {
- resolve(socket);
- };
-
- socket.onerror = e => {
- reject(e);
- };
- });
-};
-
/**
* 休眠
*/
diff --git a/orion-ops-ui/src/views/exec/batch-upload/index.vue b/orion-ops-ui/src/views/exec/batch-upload/index.vue
new file mode 100644
index 00000000..c283949b
--- /dev/null
+++ b/orion-ops-ui/src/views/exec/batch-upload/index.vue
@@ -0,0 +1,17 @@
+
+ 批量上传
+
+
+
+
+
+
+
diff --git a/orion-ops-ui/src/views/exec/upload-task-log/index.vue b/orion-ops-ui/src/views/exec/upload-task-log/index.vue
new file mode 100644
index 00000000..23a02e6e
--- /dev/null
+++ b/orion-ops-ui/src/views/exec/upload-task-log/index.vue
@@ -0,0 +1,17 @@
+
+ upload-task-log
+
+
+
+
+
+
+
diff --git a/orion-ops-ui/src/views/host/terminal/handler/sftp-transfer-manager.ts b/orion-ops-ui/src/views/host/terminal/handler/sftp-transfer-manager.ts
index 384095a7..611746e4 100644
--- a/orion-ops-ui/src/views/host/terminal/handler/sftp-transfer-manager.ts
+++ b/orion-ops-ui/src/views/host/terminal/handler/sftp-transfer-manager.ts
@@ -2,9 +2,8 @@ import type { ISftpTransferManager, ISftpTransferUploader, SftpTransferItem } fr
import { ISftpTransferDownloader, SftpFile, TransferOperatorResponse } from '../types/terminal.type';
import { TransferReceiverType, TransferStatus, TransferType } from '../types/terminal.const';
import { Message } from '@arco-design/web-vue';
-import { getTerminalAccessToken } from '@/api/asset/host-terminal';
-import { createWebSocket, nextId } from '@/utils';
-import { webSocketBaseUrl } from '@/utils/env';
+import { getTerminalAccessToken, openHostTransferChannel } from '@/api/asset/host-terminal';
+import { nextId } from '@/utils';
import SftpTransferUploader from './sftp-transfer-uploader';
import SftpTransferDownloader from './sftp-transfer-downloader';
@@ -113,7 +112,7 @@ export default class SftpTransferManager implements ISftpTransferManager {
const { data: accessToken } = await getTerminalAccessToken();
// 打开会话
try {
- this.client = await createWebSocket(`${webSocketBaseUrl}/host/transfer/${accessToken}`);
+ this.client = await openHostTransferChannel(accessToken);
} catch (e) {
// 打开失败将传输列表置为失效
Message.error('会话打开失败');
diff --git a/orion-ops-ui/src/views/host/terminal/handler/terminal-channel.ts b/orion-ops-ui/src/views/host/terminal/handler/terminal-channel.ts
index de2881d5..c589b3c7 100644
--- a/orion-ops-ui/src/views/host/terminal/handler/terminal-channel.ts
+++ b/orion-ops-ui/src/views/host/terminal/handler/terminal-channel.ts
@@ -1,9 +1,7 @@
import type { InputPayload, ITerminalChannel, ITerminalOutputProcessor, ITerminalSessionManager, OutputPayload, Protocol, } from '../types/terminal.type';
import { OutputProtocol } from '../types/terminal.protocol';
-import { getTerminalAccessToken } from '@/api/asset/host-terminal';
+import { getTerminalAccessToken, openHostTerminalChannel } from '@/api/asset/host-terminal';
import { Message } from '@arco-design/web-vue';
-import { createWebSocket } from '@/utils';
-import { webSocketBaseUrl } from '@/utils/env';
import TerminalOutputProcessor from './terminal-output-processor';
// 终端通信处理器 实现
@@ -23,7 +21,7 @@ export default class TerminalChannel implements ITerminalChannel {
const { data: accessToken } = await getTerminalAccessToken();
// 打开会话
try {
- this.client = await createWebSocket(`${webSocketBaseUrl}/host/terminal/${accessToken}`);
+ this.client = await openHostTerminalChannel(accessToken);
} catch (e) {
Message.error('无法连接至服务器');
console.error('terminal error', e);
diff --git a/orion-ops-ui/src/views/job/exec-job-log-view/index.vue b/orion-ops-ui/src/views/job/exec-job-log-view/index.vue
index 7c6a50e1..c9a8d2c1 100644
--- a/orion-ops-ui/src/views/job/exec-job-log-view/index.vue
+++ b/orion-ops-ui/src/views/job/exec-job-log-view/index.vue
@@ -17,7 +17,7 @@