Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1b2753a2b7 | ||
|
|
29b44b8b77 | ||
|
|
7290b1364c | ||
|
|
3851ead8bb | ||
|
|
305312cc26 |
@@ -53,7 +53,7 @@
|
|||||||
|
|
||||||
* 🔗 演示地址: http://101.43.254.243:1081/
|
* 🔗 演示地址: http://101.43.254.243:1081/
|
||||||
* 🔏 演示账号: admin/admin
|
* 🔏 演示账号: admin/admin
|
||||||
* ⭐ 体验后可以点一下 `star` 这对我很重要! [github](https://github.com/dromara/orion-visor) [gitee](https://gitee.com/dromara/orion-visor) [gitcode](https://gitcode.com/qq_41011894/orion-visor/overview)
|
* ⭐ 体验后可以点一下 `star` 这对我很重要! [github](https://github.com/dromara/orion-visor) [gitee](https://gitee.com/dromara/orion-visor) [gitcode](https://gitcode.com/dromara/orion-visor/overview)
|
||||||
* 🌈 如果本项目对你有帮助请帮忙推广一下 让更多的人知道此项目!
|
* 🌈 如果本项目对你有帮助请帮忙推广一下 让更多的人知道此项目!
|
||||||
* 🎭 演示环境部分功能不可用, 完整功能请本地部署!
|
* 🎭 演示环境部分功能不可用, 完整功能请本地部署!
|
||||||
* 📛 演示环境请不要随便删除数据!
|
* 📛 演示环境请不要随便删除数据!
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
version: '3.3'
|
version: '3.3'
|
||||||
services:
|
services:
|
||||||
orion-visor-service:
|
orion-visor-service:
|
||||||
image: registry.cn-hangzhou.aliyuncs.com/lijiahangmax/orion-visor-service:2.1.0
|
image: registry.cn-hangzhou.aliyuncs.com/lijiahangmax/orion-visor-service:2.1.1
|
||||||
privileged: true
|
privileged: true
|
||||||
ports:
|
ports:
|
||||||
- 1081:80
|
- 1081:80
|
||||||
@@ -32,7 +32,7 @@ services:
|
|||||||
- orion-visor-mysql
|
- orion-visor-mysql
|
||||||
- orion-visor-redis
|
- orion-visor-redis
|
||||||
orion-visor-mysql:
|
orion-visor-mysql:
|
||||||
image: registry.cn-hangzhou.aliyuncs.com/lijiahangmax/orion-visor-mysql:2.1.0
|
image: registry.cn-hangzhou.aliyuncs.com/lijiahangmax/orion-visor-mysql:2.1.1
|
||||||
privileged: true
|
privileged: true
|
||||||
ports:
|
ports:
|
||||||
- 3307:3306
|
- 3307:3306
|
||||||
@@ -52,7 +52,7 @@ services:
|
|||||||
retries: 10
|
retries: 10
|
||||||
start_period: 3s
|
start_period: 3s
|
||||||
orion-visor-redis:
|
orion-visor-redis:
|
||||||
image: registry.cn-hangzhou.aliyuncs.com/lijiahangmax/orion-visor-redis:2.1.0
|
image: registry.cn-hangzhou.aliyuncs.com/lijiahangmax/orion-visor-redis:2.1.1
|
||||||
privileged: true
|
privileged: true
|
||||||
ports:
|
ports:
|
||||||
- 6380:6379
|
- 6380:6379
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
version: '3.3'
|
version: '3.3'
|
||||||
services:
|
services:
|
||||||
orion-visor-service:
|
orion-visor-service:
|
||||||
image: registry.cn-hangzhou.aliyuncs.com/lijiahangmax/orion-visor-service:2.1.0
|
image: registry.cn-hangzhou.aliyuncs.com/lijiahangmax/orion-visor-service:2.1.1
|
||||||
privileged: true
|
privileged: true
|
||||||
ports:
|
ports:
|
||||||
- 1081:80
|
- 1081:80
|
||||||
@@ -32,7 +32,7 @@ services:
|
|||||||
- orion-visor-mysql
|
- orion-visor-mysql
|
||||||
- orion-visor-redis
|
- orion-visor-redis
|
||||||
orion-visor-mysql:
|
orion-visor-mysql:
|
||||||
image: registry.cn-hangzhou.aliyuncs.com/lijiahangmax/orion-visor-mysql:2.1.0
|
image: registry.cn-hangzhou.aliyuncs.com/lijiahangmax/orion-visor-mysql:2.1.1
|
||||||
privileged: true
|
privileged: true
|
||||||
ports:
|
ports:
|
||||||
- 3307:3306
|
- 3307:3306
|
||||||
@@ -52,7 +52,7 @@ services:
|
|||||||
retries: 10
|
retries: 10
|
||||||
start_period: 3s
|
start_period: 3s
|
||||||
orion-visor-redis:
|
orion-visor-redis:
|
||||||
image: registry.cn-hangzhou.aliyuncs.com/lijiahangmax/orion-visor-redis:2.1.0
|
image: registry.cn-hangzhou.aliyuncs.com/lijiahangmax/orion-visor-redis:2.1.1
|
||||||
privileged: true
|
privileged: true
|
||||||
ports:
|
ports:
|
||||||
- 6380:6379
|
- 6380:6379
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#/bin/bash
|
#/bin/bash
|
||||||
version=2.1.0
|
version=2.1.1
|
||||||
cp -r ../../sql ./sql
|
cp -r ../../sql ./sql
|
||||||
docker build -t orion-visor-mysql:${version} .
|
docker build -t orion-visor-mysql:${version} .
|
||||||
rm -rf ./sql
|
rm -rf ./sql
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#/bin/bash
|
#/bin/bash
|
||||||
version=2.1.0
|
version=2.1.1
|
||||||
docker build -t orion-visor-redis:${version} .
|
docker build -t orion-visor-redis:${version} .
|
||||||
docker tag orion-visor-redis:${version} registry.cn-hangzhou.aliyuncs.com/lijiahangmax/orion-visor-redis:${version}
|
docker tag orion-visor-redis:${version} registry.cn-hangzhou.aliyuncs.com/lijiahangmax/orion-visor-redis:${version}
|
||||||
docker push registry.cn-hangzhou.aliyuncs.com/lijiahangmax/orion-visor-redis:${version}
|
docker push registry.cn-hangzhou.aliyuncs.com/lijiahangmax/orion-visor-redis:${version}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#/bin/bash
|
#/bin/bash
|
||||||
version=2.1.0
|
version=2.1.1
|
||||||
mv ../../orion-visor-launch/target/orion-visor-launch.jar ./orion-visor-launch.jar
|
mv ../../orion-visor-launch/target/orion-visor-launch.jar ./orion-visor-launch.jar
|
||||||
mv ../../orion-visor-ui/dist ./dist
|
mv ../../orion-visor-ui/dist ./dist
|
||||||
docker build -t orion-visor-service:${version} .
|
docker build -t orion-visor-service:${version} .
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
<url>https://github.com/dromara/orion-visor</url>
|
<url>https://github.com/dromara/orion-visor</url>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<revision>2.1.0</revision>
|
<revision>2.1.1</revision>
|
||||||
<spring.boot.version>2.7.17</spring.boot.version>
|
<spring.boot.version>2.7.17</spring.boot.version>
|
||||||
<spring.boot.admin.version>2.7.15</spring.boot.admin.version>
|
<spring.boot.admin.version>2.7.15</spring.boot.admin.version>
|
||||||
<flatten.maven.plugin.version>1.5.0</flatten.maven.plugin.version>
|
<flatten.maven.plugin.version>1.5.0</flatten.maven.plugin.version>
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ public interface AppConst extends OrionConst {
|
|||||||
/**
|
/**
|
||||||
* 同 ${orion.version} 迭代时候需要手动更改
|
* 同 ${orion.version} 迭代时候需要手动更改
|
||||||
*/
|
*/
|
||||||
String VERSION = "2.1.0";
|
String VERSION = "2.1.1";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 同 ${spring.application.name}
|
* 同 ${spring.application.name}
|
||||||
|
|||||||
@@ -94,8 +94,8 @@
|
|||||||
:data="tableRenderData"
|
:data="tableRenderData"
|
||||||
:pagination="pagination"
|
:pagination="pagination"
|
||||||
:bordered="false"
|
:bordered="false"
|
||||||
@page-change="(page) => fetchTableData(page, pagination.pageSize)"
|
@page-change="(page: number) => fetchTableData(page, pagination.pageSize)"
|
||||||
@page-size-change="(size) => fetchTableData(1, size)">
|
@page-size-change="(size: number) => fetchTableData(1, size)">
|
||||||
#foreach($field in ${table.fields})
|
#foreach($field in ${table.fields})
|
||||||
#if(${dictMap.containsKey(${field.propertyName})})
|
#if(${dictMap.containsKey(${field.propertyName})})
|
||||||
<!-- $field.comment -->
|
<!-- $field.comment -->
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
VITE_API_BASE_URL= 'http://127.0.0.1:9200/orion-visor/api'
|
VITE_API_BASE_URL= 'http://127.0.0.1:9200/orion-visor/api'
|
||||||
VITE_WS_BASE_URL= 'ws://127.0.0.1:9200/orion-visor/keep-alive'
|
VITE_WS_BASE_URL= 'ws://127.0.0.1:9200/orion-visor/keep-alive'
|
||||||
VITE_APP_VERSION= '2.1.0'
|
VITE_APP_VERSION= '2.1.1'
|
||||||
VITE_APP_RELEASE= 'community'
|
VITE_APP_RELEASE= 'community'
|
||||||
VITE_SFTP_PREVIEW_MB= 2
|
VITE_SFTP_PREVIEW_MB= 2
|
||||||
VITE_DEMO_MODE= false
|
VITE_DEMO_MODE= false
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
VITE_API_BASE_URL= '/orion-visor/api'
|
VITE_API_BASE_URL= '/orion-visor/api'
|
||||||
VITE_WS_BASE_URL= '/orion-visor/keep-alive'
|
VITE_WS_BASE_URL= '/orion-visor/keep-alive'
|
||||||
VITE_APP_VERSION= '2.1.0'
|
VITE_APP_VERSION= '2.1.1'
|
||||||
VITE_APP_RELEASE= 'community'
|
VITE_APP_RELEASE= 'community'
|
||||||
VITE_SFTP_PREVIEW_MB= 2
|
VITE_SFTP_PREVIEW_MB= 2
|
||||||
VITE_DEMO_MODE= false
|
VITE_DEMO_MODE= false
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "orion-visor-ui",
|
"name": "orion-visor-ui",
|
||||||
"description": "Orion Visor UI",
|
"description": "Orion Visor UI",
|
||||||
"version": "2.1.0",
|
"version": "2.1.1",
|
||||||
"private": true,
|
"private": true,
|
||||||
"author": "Jiahang Li",
|
"author": "Jiahang Li",
|
||||||
"license": "Apache 2.0",
|
"license": "Apache 2.0",
|
||||||
|
|||||||
@@ -50,7 +50,7 @@
|
|||||||
</template>
|
</template>
|
||||||
</a-button>
|
</a-button>
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
<a-dropdown trigger="click" @select="s => changeLocale(s as string)">
|
<a-dropdown trigger="click" @select="(s: string) => changeLocale(s)">
|
||||||
<div ref="localeRef" class="trigger-btn" />
|
<div ref="localeRef" class="trigger-btn" />
|
||||||
<template #content>
|
<template #content>
|
||||||
<a-doption v-for="item in locales"
|
<a-doption v-for="item in locales"
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
:checkable="checkable"
|
:checkable="checkable"
|
||||||
:check-strictly="true"
|
:check-strictly="true"
|
||||||
@drop="moveGroup"
|
@drop="moveGroup"
|
||||||
@select="(s) => emits('onSelected', s)">
|
@select="(s: any) => emits('onSelected', s)">
|
||||||
<!-- 标题 -->
|
<!-- 标题 -->
|
||||||
<template #title="node">
|
<template #title="node">
|
||||||
<!-- 修改名称输入框 -->
|
<!-- 修改名称输入框 -->
|
||||||
|
|||||||
@@ -119,11 +119,6 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.exec-host-items {
|
|
||||||
width: 100%;
|
|
||||||
height: calc(100% - 38px);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
:deep(.log-header) {
|
:deep(.log-header) {
|
||||||
|
|||||||
@@ -13,23 +13,26 @@
|
|||||||
</div>
|
</div>
|
||||||
<!-- 主机列表 -->
|
<!-- 主机列表 -->
|
||||||
<div class="exec-host-items">
|
<div class="exec-host-items">
|
||||||
<div v-for="item in hosts"
|
<a-scrollbar>
|
||||||
:key="item.id"
|
<div v-for="(item, index) in hosts"
|
||||||
class="exec-host-item"
|
:key="item.id"
|
||||||
:class="[ current === item.id ? 'exec-host-item-selected' : '' ]"
|
class="exec-host-item"
|
||||||
@click="emits('selected', item.id)">
|
:class="[ current === item.id ? 'exec-host-item-selected' : '' ]"
|
||||||
<!-- 主机名称 -->
|
:style="{ marginBottom: index === hosts.length -1 ? 0 : '8px' }"
|
||||||
<div class="exec-host-item-name">
|
@click="emits('selected', item.id)">
|
||||||
<span class="host-name">{{ item.hostName }}</span>
|
<!-- 主机名称 -->
|
||||||
<span class="host-address">{{ item.hostAddress }}</span>
|
<div class="exec-host-item-name">
|
||||||
|
<span class="host-name">{{ item.hostName }}</span>
|
||||||
|
<span class="host-address">{{ item.hostAddress }}</span>
|
||||||
|
</div>
|
||||||
|
<!-- 状态 -->
|
||||||
|
<div class="exec-host-item-status">
|
||||||
|
<a-tag :color="getDictValue(execHostStatusKey, item.status, 'execColor')">
|
||||||
|
{{ getDictValue(execHostStatusKey, item.status) }}
|
||||||
|
</a-tag>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- 状态 -->
|
</a-scrollbar>
|
||||||
<div class="exec-host-item-status">
|
|
||||||
<a-tag :color="getDictValue(execHostStatusKey, item.status, 'execColor')">
|
|
||||||
{{ getDictValue(execHostStatusKey, item.status) }}
|
|
||||||
</a-tag>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -78,13 +81,19 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.exec-host-items {
|
.exec-host-items {
|
||||||
position: absolute;
|
position: relative;
|
||||||
width: calc(100% - 32px);
|
width: 100%;
|
||||||
height: calc(100% - 68px);
|
height: calc(100% - 38px);
|
||||||
overflow: auto;
|
|
||||||
|
|
||||||
&::-webkit-scrollbar-track {
|
:deep(.arco-scrollbar) {
|
||||||
display: none;
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
&-container {
|
||||||
|
height: 100%;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -99,7 +108,6 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
margin-bottom: 8px;
|
|
||||||
background: var(--color-fill-2);
|
background: var(--color-fill-2);
|
||||||
transition: all .2s;
|
transition: all .2s;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
|
|||||||
@@ -51,8 +51,8 @@
|
|||||||
:pagination="pagination"
|
:pagination="pagination"
|
||||||
:bordered="false"
|
:bordered="false"
|
||||||
:scroll="{ x: '100%', y: '60vh' }"
|
:scroll="{ x: '100%', y: '60vh' }"
|
||||||
@page-change="(page) => fetchTableData(page, pagination.pageSize)"
|
@page-change="(page: number) => fetchTableData(page, pagination.pageSize)"
|
||||||
@page-size-change="(size) => fetchTableData(1, size)">
|
@page-size-change="(size: number) => fetchTableData(1, size)">
|
||||||
<!-- 模板名称 -->
|
<!-- 模板名称 -->
|
||||||
<template #name="{ record }">
|
<template #name="{ record }">
|
||||||
<span class="span-blue">{{ record.name }}</span>
|
<span class="span-blue">{{ record.name }}</span>
|
||||||
|
|||||||
@@ -34,8 +34,8 @@
|
|||||||
:data="tableRenderData"
|
:data="tableRenderData"
|
||||||
:pagination="pagination"
|
:pagination="pagination"
|
||||||
:bordered="false"
|
:bordered="false"
|
||||||
@page-change="(page) => fetchTableData(page, pagination.pageSize)"
|
@page-change="(page: number) => fetchTableData(page, pagination.pageSize)"
|
||||||
@page-size-change="(size) => fetchTableData(1, size)">
|
@page-size-change="(size: number) => fetchTableData(1, size)">
|
||||||
<!-- 修改前 -->
|
<!-- 修改前 -->
|
||||||
<template #beforeValue="{ record }">
|
<template #beforeValue="{ record }">
|
||||||
<span class="copy-left"
|
<span class="copy-left"
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
<!-- 一级菜单 -->
|
<!-- 一级菜单 -->
|
||||||
<a-menu-item v-if="!menu.children?.length"
|
<a-menu-item v-if="!menu.children?.length"
|
||||||
:key="menu.name"
|
:key="menu.name"
|
||||||
@click="(e) => goto(e, menu)">
|
@click="(e: any) => goto(e, menu)">
|
||||||
<!-- 图标 -->
|
<!-- 图标 -->
|
||||||
<template #icon>
|
<template #icon>
|
||||||
<component v-if="menu.meta?.icon" :is="menu.meta?.icon" />
|
<component v-if="menu.meta?.icon" :is="menu.meta?.icon" />
|
||||||
@@ -34,7 +34,7 @@
|
|||||||
<!-- 子菜单 -->
|
<!-- 子菜单 -->
|
||||||
<a-menu-item v-for="child in menu.children"
|
<a-menu-item v-for="child in menu.children"
|
||||||
:key="child.name"
|
:key="child.name"
|
||||||
@click="(e) => goto(e, child)">
|
@click="(e: any) => goto(e, child)">
|
||||||
<!-- 图标 -->
|
<!-- 图标 -->
|
||||||
<template #icon v-if="child.meta?.icon">
|
<template #icon v-if="child.meta?.icon">
|
||||||
<component :is="child.meta?.icon" />
|
<component :is="child.meta?.icon" />
|
||||||
|
|||||||
@@ -14,8 +14,8 @@
|
|||||||
v-model:page-size="(pagination as any).pageSize"
|
v-model:page-size="(pagination as any).pageSize"
|
||||||
v-bind="pagination as any"
|
v-bind="pagination as any"
|
||||||
:auto-adjust="false"
|
:auto-adjust="false"
|
||||||
@change="page => bubblesEmitter(HeaderEmitter.PAGE_CHANGE, page, (pagination as any).pageSize)"
|
@change="(page: number) => bubblesEmitter(HeaderEmitter.PAGE_CHANGE, page, (pagination as any).pageSize)"
|
||||||
@page-size-change="limit => bubblesEmitter(HeaderEmitter.PAGE_CHANGE, 1, limit)" />
|
@page-size-change="(limit: number) => bubblesEmitter(HeaderEmitter.PAGE_CHANGE, 1, limit)" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- 操作部分 -->
|
<!-- 操作部分 -->
|
||||||
@@ -48,8 +48,8 @@
|
|||||||
:placeholder="searchInputPlaceholder as string"
|
:placeholder="searchInputPlaceholder as string"
|
||||||
size="small"
|
size="small"
|
||||||
allow-clear
|
allow-clear
|
||||||
@input="(e) => bubblesEmitter(HeaderEmitter.UPDATE_SEARCH_VALUE, e)"
|
@input="(e: string) => bubblesEmitter(HeaderEmitter.UPDATE_SEARCH_VALUE, e)"
|
||||||
@change="(e) => bubblesEmitter(HeaderEmitter.UPDATE_SEARCH_VALUE, e)"
|
@change="(e: string) => bubblesEmitter(HeaderEmitter.UPDATE_SEARCH_VALUE, e)"
|
||||||
@keyup.enter="bubblesEmitter(HeaderEmitter.SEARCH)" />
|
@keyup.enter="bubblesEmitter(HeaderEmitter.SEARCH)" />
|
||||||
</div>
|
</div>
|
||||||
<!-- 过滤条件 -->
|
<!-- 过滤条件 -->
|
||||||
|
|||||||
10
orion-visor-ui/src/store/modules/cache/index.ts
vendored
10
orion-visor-ui/src/store/modules/cache/index.ts
vendored
@@ -1,4 +1,4 @@
|
|||||||
import type { CacheState } from './types';
|
import type { CacheState, CacheType } from './types';
|
||||||
import type { AxiosResponse } from 'axios';
|
import type { AxiosResponse } from 'axios';
|
||||||
import type { TagType } from '@/api/meta/tag';
|
import type { TagType } from '@/api/meta/tag';
|
||||||
import { getTagList } from '@/api/meta/tag';
|
import { getTagList } from '@/api/meta/tag';
|
||||||
@@ -19,14 +19,6 @@ import { getCommandSnippetGroupList } from '@/api/asset/command-snippet-group';
|
|||||||
import { getExecJobList } from '@/api/job/exec-job';
|
import { getExecJobList } from '@/api/job/exec-job';
|
||||||
import { getPathBookmarkGroupList } from '@/api/asset/path-bookmark-group';
|
import { getPathBookmarkGroupList } from '@/api/asset/path-bookmark-group';
|
||||||
|
|
||||||
export type CacheType = 'users' | 'menus' | 'roles'
|
|
||||||
| 'hostGroups' | 'hostKeys' | 'hostIdentities'
|
|
||||||
| 'dictKeys'
|
|
||||||
| 'authorizedHostKeys' | 'authorizedHostIdentities'
|
|
||||||
| 'commandSnippetGroups' | 'pathBookmarkGroups'
|
|
||||||
| 'execJob'
|
|
||||||
| string
|
|
||||||
|
|
||||||
export default defineStore('cache', {
|
export default defineStore('cache', {
|
||||||
state: (): CacheState => ({}),
|
state: (): CacheState => ({}),
|
||||||
|
|
||||||
|
|||||||
29
orion-visor-ui/src/store/modules/cache/types.ts
vendored
29
orion-visor-ui/src/store/modules/cache/types.ts
vendored
@@ -1,23 +1,12 @@
|
|||||||
import type { UserQueryResponse } from '@/api/user/user';
|
// 缓存类型
|
||||||
import type { MenuQueryResponse } from '@/api/system/menu';
|
export type CacheType = 'users' | 'menus' | 'roles'
|
||||||
import type { RoleQueryResponse } from '@/api/user/role';
|
| 'hostGroups' | 'hostKeys' | 'hostIdentities'
|
||||||
import type { HostQueryResponse } from '@/api/asset/host';
|
| 'dictKeys'
|
||||||
import type { HostGroupQueryResponse } from '@/api/asset/host-group';
|
| 'authorizedHostKeys' | 'authorizedHostIdentities'
|
||||||
import type { HostKeyQueryResponse } from '@/api/asset/host-key';
|
| 'commandSnippetGroups' | 'pathBookmarkGroups'
|
||||||
import type { HostIdentityQueryResponse } from '@/api/asset/host-identity';
|
| 'execJob'
|
||||||
import type { DictKeyQueryResponse } from '@/api/system/dict-key';
|
| string
|
||||||
|
|
||||||
export interface CacheState {
|
export interface CacheState {
|
||||||
users?: UserQueryResponse[];
|
[key: CacheType]: unknown;
|
||||||
menus?: MenuQueryResponse[];
|
|
||||||
roles?: RoleQueryResponse[];
|
|
||||||
hosts?: HostQueryResponse[];
|
|
||||||
hostGroups?: HostGroupQueryResponse[];
|
|
||||||
hostKeys?: HostKeyQueryResponse[];
|
|
||||||
hostIdentities?: HostIdentityQueryResponse[];
|
|
||||||
dictKeys?: DictKeyQueryResponse[];
|
|
||||||
authorizedHostKeys?: HostKeyQueryResponse[];
|
|
||||||
authorizedHostIdentities?: HostIdentityQueryResponse[];
|
|
||||||
|
|
||||||
[key: string]: unknown;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import type { RouteMeta, RouteRecordNormalized } from 'vue-router';
|
import type { RouteMeta, RouteRecordNormalized } from 'vue-router';
|
||||||
import type { MenuState } from './types';
|
import type { MenuState } from './types';
|
||||||
import type { MenuQueryResponse } from '@/api/system/menu';
|
import type { MenuQueryResponse } from '@/api/system/menu';
|
||||||
|
import router from '@/router';
|
||||||
import { defineStore } from 'pinia';
|
import { defineStore } from 'pinia';
|
||||||
import { Notification } from '@arco-design/web-vue';
|
import { Notification } from '@arco-design/web-vue';
|
||||||
import { getMenuList } from '@/api/user/auth';
|
import { getMenuList } from '@/api/user/auth';
|
||||||
import router from '@/router';
|
|
||||||
import { EnabledStatus } from '@/types/const';
|
import { EnabledStatus } from '@/types/const';
|
||||||
|
|
||||||
export default defineStore('menu', {
|
export default defineStore('menu', {
|
||||||
|
|||||||
@@ -100,8 +100,8 @@
|
|||||||
:data="tableRenderData"
|
:data="tableRenderData"
|
||||||
:pagination="pagination"
|
:pagination="pagination"
|
||||||
:bordered="false"
|
:bordered="false"
|
||||||
@page-change="(page) => fetchTableData(page, pagination.pageSize)"
|
@page-change="(page: number) => fetchTableData(page, pagination.pageSize)"
|
||||||
@page-size-change="(size) => fetchTableData(1, size)">
|
@page-size-change="(size: number) => fetchTableData(1, size)">
|
||||||
<!-- 连接用户 -->
|
<!-- 连接用户 -->
|
||||||
<template #username="{ record }">
|
<template #username="{ record }">
|
||||||
{{ record.username }}
|
{{ record.username }}
|
||||||
|
|||||||
@@ -84,8 +84,8 @@
|
|||||||
:data="tableRenderData"
|
:data="tableRenderData"
|
||||||
:pagination="pagination"
|
:pagination="pagination"
|
||||||
:bordered="false"
|
:bordered="false"
|
||||||
@page-change="(page) => fetchTableData(page, pagination.pageSize)"
|
@page-change="(page: number) => fetchTableData(page, pagination.pageSize)"
|
||||||
@page-size-change="(size) => fetchTableData(1, size)">
|
@page-size-change="(size: number) => fetchTableData(1, size)">
|
||||||
<!-- 操作用户 -->
|
<!-- 操作用户 -->
|
||||||
<template #username="{ record }">
|
<template #username="{ record }">
|
||||||
{{ record.username }}
|
{{ record.username }}
|
||||||
|
|||||||
@@ -102,8 +102,8 @@
|
|||||||
:data="tableRenderData"
|
:data="tableRenderData"
|
||||||
:pagination="pagination"
|
:pagination="pagination"
|
||||||
:bordered="false"
|
:bordered="false"
|
||||||
@page-change="(page) => fetchTableData(page, pagination.pageSize)"
|
@page-change="(page: number) => fetchTableData(page, pagination.pageSize)"
|
||||||
@page-size-change="(size) => fetchTableData(1, size)">
|
@page-size-change="(size: number) => fetchTableData(1, size)">
|
||||||
<!-- 类型 -->
|
<!-- 类型 -->
|
||||||
<template #type="{ record }">
|
<template #type="{ record }">
|
||||||
<a-tag :color="getDictValue(identityTypeKey, record.type, 'color')">
|
<a-tag :color="getDictValue(identityTypeKey, record.type, 'color')">
|
||||||
|
|||||||
@@ -87,8 +87,8 @@
|
|||||||
:data="tableRenderData"
|
:data="tableRenderData"
|
||||||
:pagination="pagination"
|
:pagination="pagination"
|
||||||
:bordered="false"
|
:bordered="false"
|
||||||
@page-change="(page) => fetchTableData(page, pagination.pageSize)"
|
@page-change="(page: number) => fetchTableData(page, pagination.pageSize)"
|
||||||
@page-size-change="(size) => fetchTableData(1, size)">
|
@page-size-change="(size: number) => fetchTableData(1, size)">
|
||||||
<!-- 操作 -->
|
<!-- 操作 -->
|
||||||
<template #handle="{ record }">
|
<template #handle="{ record }">
|
||||||
<div class="table-handle-wrapper">
|
<div class="table-handle-wrapper">
|
||||||
|
|||||||
@@ -127,8 +127,8 @@
|
|||||||
:data="tableRenderData"
|
:data="tableRenderData"
|
||||||
:pagination="pagination"
|
:pagination="pagination"
|
||||||
:bordered="false"
|
:bordered="false"
|
||||||
@page-change="(page) => fetchTableData(page, pagination.pageSize)"
|
@page-change="(page: number) => fetchTableData(page, pagination.pageSize)"
|
||||||
@page-size-change="(size) => fetchTableData(1, size)">
|
@page-size-change="(size: number) => fetchTableData(1, size)">
|
||||||
<!-- 主机类型 -->
|
<!-- 主机类型 -->
|
||||||
<template #type="{ record }">
|
<template #type="{ record }">
|
||||||
<a-tag :color="getDictValue(hostTypeKey, record.type, 'color')">
|
<a-tag :color="getDictValue(hostTypeKey, record.type, 'color')">
|
||||||
|
|||||||
@@ -108,8 +108,8 @@
|
|||||||
:data="tableRenderData"
|
:data="tableRenderData"
|
||||||
:pagination="pagination"
|
:pagination="pagination"
|
||||||
:bordered="false"
|
:bordered="false"
|
||||||
@page-change="(page) => fetchTableData(page, pagination.pageSize)"
|
@page-change="(page: number) => fetchTableData(page, pagination.pageSize)"
|
||||||
@page-size-change="(size) => fetchTableData(1, size)"
|
@page-size-change="(size: number) => fetchTableData(1, size)"
|
||||||
@expand="loadExecHost">
|
@expand="loadExecHost">
|
||||||
<!-- 展开表格 -->
|
<!-- 展开表格 -->
|
||||||
<template #expand-row="{ record }">
|
<template #expand-row="{ record }">
|
||||||
@@ -165,7 +165,7 @@
|
|||||||
type="text"
|
type="text"
|
||||||
size="mini"
|
size="mini"
|
||||||
title="ctrl + 左键新页面打开"
|
title="ctrl + 左键新页面打开"
|
||||||
@click="(e) => emits('viewLog', record.id, e.ctrlKey)">
|
@click="(e: any) => emits('viewLog', record.id, e.ctrlKey)">
|
||||||
日志
|
日志
|
||||||
</a-button>
|
</a-button>
|
||||||
<!-- 中断 -->
|
<!-- 中断 -->
|
||||||
|
|||||||
@@ -18,9 +18,10 @@
|
|||||||
<a-empty description="无执行记录" />
|
<a-empty description="无执行记录" />
|
||||||
</div>
|
</div>
|
||||||
<!-- 批量执行日志 -->
|
<!-- 批量执行日志 -->
|
||||||
<div v-else class="exec-history-rows">
|
<a-scrollbar v-else>
|
||||||
<div v-for="record in historyLogs"
|
<div v-for="(record, index) in historyLogs"
|
||||||
:key="record.id"
|
:key="record.id"
|
||||||
|
:style="{ marginBottom: index === historyLogs.length -1 ? 0 : '8px' }"
|
||||||
class="exec-history"
|
class="exec-history"
|
||||||
@click="emits('selected', record)">
|
@click="emits('selected', record)">
|
||||||
<!-- 机器数量 -->
|
<!-- 机器数量 -->
|
||||||
@@ -32,7 +33,7 @@
|
|||||||
{{ record.description }}
|
{{ record.description }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</a-scrollbar>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -110,14 +111,16 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
.exec-history-rows {
|
.container {
|
||||||
position: absolute;
|
:deep(.arco-scrollbar) {
|
||||||
width: calc(100% - 32px);
|
position: absolute;
|
||||||
height: calc(100% - 64px);
|
width: calc(100% - 32px);
|
||||||
overflow: auto;
|
height: calc(100% - 64px);
|
||||||
|
|
||||||
&::-webkit-scrollbar-track {
|
&-container {
|
||||||
display: none;
|
height: 100%;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -127,7 +130,6 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
margin-bottom: 8px;
|
|
||||||
background: var(--color-fill-2);
|
background: var(--color-fill-2);
|
||||||
transition: all .2s;
|
transition: all .2s;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
|
|||||||
@@ -77,8 +77,8 @@
|
|||||||
:data="tableRenderData"
|
:data="tableRenderData"
|
||||||
:pagination="pagination"
|
:pagination="pagination"
|
||||||
:bordered="false"
|
:bordered="false"
|
||||||
@page-change="(page) => fetchTableData(page, pagination.pageSize)"
|
@page-change="(page: number) => fetchTableData(page, pagination.pageSize)"
|
||||||
@page-size-change="(size) => fetchTableData(1, size)">
|
@page-size-change="(size: number) => fetchTableData(1, size)">
|
||||||
<!-- 模板命令 -->
|
<!-- 模板命令 -->
|
||||||
<template #command="{ record }">
|
<template #command="{ record }">
|
||||||
<span class="copy-left" @click="copy(record.command, '已复制')">
|
<span class="copy-left" @click="copy(record.command, '已复制')">
|
||||||
|
|||||||
@@ -107,8 +107,8 @@
|
|||||||
:data="tableRenderData"
|
:data="tableRenderData"
|
||||||
:pagination="pagination"
|
:pagination="pagination"
|
||||||
:bordered="false"
|
:bordered="false"
|
||||||
@page-change="(page) => fetchTableData(page, pagination.pageSize)"
|
@page-change="(page: number) => fetchTableData(page, pagination.pageSize)"
|
||||||
@page-size-change="(size) => fetchTableData(1, size)">
|
@page-size-change="(size: number) => fetchTableData(1, size)">
|
||||||
<!-- 上传路径 -->
|
<!-- 上传路径 -->
|
||||||
<template #remotePath="{ record }">
|
<template #remotePath="{ record }">
|
||||||
<span class="text-copy span-blue" @click="copy(record.remotePath)">
|
<span class="text-copy span-blue" @click="copy(record.remotePath)">
|
||||||
|
|||||||
@@ -320,6 +320,18 @@
|
|||||||
height: calc(100% - 56px);
|
height: calc(100% - 56px);
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
padding-bottom: 4px;
|
padding-bottom: 4px;
|
||||||
|
|
||||||
|
&::-webkit-scrollbar-track {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&::-webkit-scrollbar-thumb {
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover::-webkit-scrollbar-thumb {
|
||||||
|
background: var(--color-fill-4);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.loading-skeleton {
|
.loading-skeleton {
|
||||||
|
|||||||
@@ -75,9 +75,8 @@
|
|||||||
import type { HostQueryResponse } from '@/api/asset/host';
|
import type { HostQueryResponse } from '@/api/asset/host';
|
||||||
import { onMounted, ref } from 'vue';
|
import { onMounted, ref } from 'vue';
|
||||||
import { useTerminalStore } from '@/store';
|
import { useTerminalStore } from '@/store';
|
||||||
import { PanelSessionType, TerminalTabs } from '../../types/const';
|
import { PanelSessionType, TerminalTabs, emptyRecommendCount } from '../../types/const';
|
||||||
|
|
||||||
const totalCount = 7;
|
|
||||||
const { tabManager, hosts, openSession } = useTerminalStore();
|
const { tabManager, hosts, openSession } = useTerminalStore();
|
||||||
|
|
||||||
const combinedHandlers = ref<Array<CombinedHandlerItem>>([{
|
const combinedHandlers = ref<Array<CombinedHandlerItem>>([{
|
||||||
@@ -103,7 +102,7 @@
|
|||||||
...hosts.hostList.filter(s => s.favorite).map(s => s.id),
|
...hosts.hostList.filter(s => s.favorite).map(s => s.id),
|
||||||
...hosts.hostList.map(s => s.id)
|
...hosts.hostList.map(s => s.id)
|
||||||
])
|
])
|
||||||
].slice(0, totalCount - 1)
|
].slice(0, emptyRecommendCount - 1)
|
||||||
.map(s => hosts.hostList.find(t => t.id === s) as HostQueryResponse)
|
.map(s => hosts.hostList.find(t => t.id === s) as HostQueryResponse)
|
||||||
.filter(Boolean)
|
.filter(Boolean)
|
||||||
.map(s => {
|
.map(s => {
|
||||||
@@ -116,10 +115,10 @@
|
|||||||
// 插入主机列表
|
// 插入主机列表
|
||||||
combinedHandlers.value.push(...combinedHosts);
|
combinedHandlers.value.push(...combinedHosts);
|
||||||
// 不足显示的行数用设置补充
|
// 不足显示的行数用设置补充
|
||||||
if (totalCount - 1 - combinedHosts.length > 0) {
|
if (emptyRecommendCount - 1 - combinedHosts.length > 0) {
|
||||||
const fillTabs = Object.values(TerminalTabs)
|
const fillTabs = Object.values(TerminalTabs)
|
||||||
.filter(s => s.key !== TerminalTabs.NEW_CONNECTION.key)
|
.filter(s => s.key !== TerminalTabs.NEW_CONNECTION.key)
|
||||||
.slice(0, totalCount - 1 - combinedHosts.length)
|
.slice(0, emptyRecommendCount - 1 - combinedHosts.length)
|
||||||
.map(s => {
|
.map(s => {
|
||||||
return {
|
return {
|
||||||
title: s.title,
|
title: s.title,
|
||||||
@@ -147,23 +146,19 @@
|
|||||||
|
|
||||||
.combined-container {
|
.combined-container {
|
||||||
padding: 12px;
|
padding: 12px;
|
||||||
margin: 64px auto 0 auto;
|
margin: 32px auto 0 auto;
|
||||||
width: @container-width;
|
width: @container-width;
|
||||||
height: @container-height;
|
max-height: @container-height;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
box-sizing: content-box;
|
box-sizing: content-box;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
||||||
&:hover {
|
|
||||||
overflow: auto;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.combined-handler {
|
.combined-handler {
|
||||||
width: @container-width - @transform-x;
|
width: @container-width - @transform-x;
|
||||||
height: @handler-height;
|
max-height: @handler-height;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
margin-bottom: 6px;
|
margin-bottom: 6px;
|
||||||
color: var(--color-content-text-1);
|
color: var(--color-content-text-1);
|
||||||
|
|||||||
@@ -14,8 +14,8 @@
|
|||||||
:editable="true"
|
:editable="true"
|
||||||
:hide-content="true"
|
:hide-content="true"
|
||||||
:auto-switch="true"
|
:auto-switch="true"
|
||||||
@tab-click="k => tabManager.clickTab(k as string)"
|
@tab-click="(k: string) => tabManager.clickTab(k)"
|
||||||
@delete="k => tabManager.deleteTab(k as string)">
|
@delete="(k: string) => tabManager.deleteTab(k)">
|
||||||
<a-tab-pane v-for="tab in tabManager.items"
|
<a-tab-pane v-for="tab in tabManager.items"
|
||||||
:key="tab.key">
|
:key="tab.key">
|
||||||
<!-- 标题 -->
|
<!-- 标题 -->
|
||||||
|
|||||||
@@ -6,8 +6,8 @@
|
|||||||
:auto-switch="true"
|
:auto-switch="true"
|
||||||
:show-add-button="true"
|
:show-add-button="true"
|
||||||
@add="openNewConnect"
|
@add="openNewConnect"
|
||||||
@tab-click="k => panel.clickTab(k as string)"
|
@tab-click="(k: string) => panel.clickTab(k)"
|
||||||
@delete="k => panel.deleteTab(k as string)">
|
@delete="(k: string) => panel.deleteTab(k)">
|
||||||
<!-- 右侧按钮 -->
|
<!-- 右侧按钮 -->
|
||||||
<template #extra>
|
<template #extra>
|
||||||
<a-space class="panel-extra">
|
<a-space class="panel-extra">
|
||||||
|
|||||||
@@ -134,10 +134,4 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
.list-view-container {
|
|
||||||
max-height: 100%;
|
|
||||||
width: 100%;
|
|
||||||
overflow: auto;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
type="button"
|
type="button"
|
||||||
class="usn"
|
class="usn"
|
||||||
:options="toRadioOptions(newConnectionTypeKey)"
|
:options="toRadioOptions(newConnectionTypeKey)"
|
||||||
@change="s => updateTerminalPreference(TerminalPreferenceItem.NEW_CONNECTION_TYPE, s as string, true)" />
|
@change="(s: string) => updateTerminalPreference(TerminalPreferenceItem.NEW_CONNECTION_TYPE, s, true)" />
|
||||||
<!-- 过滤 -->
|
<!-- 过滤 -->
|
||||||
<a-auto-complete v-model="filterValue"
|
<a-auto-complete v-model="filterValue"
|
||||||
class="host-filter"
|
class="host-filter"
|
||||||
|
|||||||
@@ -320,6 +320,18 @@
|
|||||||
height: calc(100% - 56px);
|
height: calc(100% - 56px);
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
padding-bottom: 4px;
|
padding-bottom: 4px;
|
||||||
|
|
||||||
|
&::-webkit-scrollbar-track {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&::-webkit-scrollbar-thumb {
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover::-webkit-scrollbar-thumb {
|
||||||
|
background: var(--color-fill-4);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.loading-skeleton {
|
.loading-skeleton {
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
<a-input size="small"
|
<a-input size="small"
|
||||||
:ref="setAutoFocus as unknown as VNodeRef"
|
:ref="setAutoFocus as unknown as VNodeRef"
|
||||||
:model-value="filterValue[0]"
|
:model-value="filterValue[0]"
|
||||||
@input="(value) => setFilterValue([value])"
|
@input="(value: string) => setFilterValue([value])"
|
||||||
@press-enter="handleFilterConfirm" />
|
@press-enter="handleFilterConfirm" />
|
||||||
<!-- 按钮 -->
|
<!-- 按钮 -->
|
||||||
<div class="name-filter-footer">
|
<div class="name-filter-footer">
|
||||||
|
|||||||
@@ -10,13 +10,15 @@
|
|||||||
:unmount-on-close="true"
|
:unmount-on-close="true"
|
||||||
:on-before-ok="handlerOk"
|
:on-before-ok="handlerOk"
|
||||||
@cancel="handleClose">
|
@cancel="handleClose">
|
||||||
<!-- 上传目录 -->
|
<div class="upload-container">
|
||||||
<div class="item-wrapper">
|
<!-- 上传目录 -->
|
||||||
<div class="form-item">
|
<div class="item-wrapper">
|
||||||
<span class="item-label">上传至文件夹</span>
|
<div class="form-item">
|
||||||
<a-input class="item-input"
|
<span class="item-label">上传至文件夹</span>
|
||||||
v-model="parentPath"
|
<a-input class="item-input"
|
||||||
placeholder="上传目录" />
|
v-model="parentPath"
|
||||||
|
placeholder="上传目录" />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<a-space>
|
<a-space>
|
||||||
<!-- 选择文件 -->
|
<!-- 选择文件 -->
|
||||||
@@ -112,7 +114,7 @@
|
|||||||
}
|
}
|
||||||
// 获取上传的文件
|
// 获取上传的文件
|
||||||
const files = fileList.value.map(s => s.file as File);
|
const files = fileList.value.map(s => s.file as File);
|
||||||
// 上传
|
// 普通上传
|
||||||
transferManager.addUpload(hostId.value, parentPath.value, files);
|
transferManager.addUpload(hostId.value, parentPath.value, files);
|
||||||
Message.success('已开始上传, 点击右侧传输列表查看进度');
|
Message.success('已开始上传, 点击右侧传输列表查看进度');
|
||||||
// 清空
|
// 清空
|
||||||
@@ -136,6 +138,11 @@
|
|||||||
@file-size-width: 82px;
|
@file-size-width: 82px;
|
||||||
@item-label: 104px;
|
@item-label: 104px;
|
||||||
|
|
||||||
|
.upload-container {
|
||||||
|
width: 100%;
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
.item-wrapper {
|
.item-wrapper {
|
||||||
margin-bottom: 24px;
|
margin-bottom: 24px;
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -163,6 +170,11 @@
|
|||||||
width: 376px;
|
width: 376px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.form-help {
|
||||||
|
margin: 4px 0 0 @item-label;
|
||||||
|
font-size: 12px;
|
||||||
|
color: var(--color-text-2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.file-list-uploader {
|
.file-list-uploader {
|
||||||
|
|||||||
@@ -242,7 +242,7 @@
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
height: calc(100% - @ssh-header-height);
|
height: calc(100% - @ssh-header-height);
|
||||||
position: relative;
|
position: relative;
|
||||||
padding: 6px 0 0 6px;
|
padding: 8px;
|
||||||
|
|
||||||
.ssh-inst {
|
.ssh-inst {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import type { ISftpSession, ISftpSessionResolver, ITerminalChannel, TerminalPanelTabItem } from '../types/define';
|
import type { ISftpSession, ISftpSessionResolver, ITerminalChannel, TerminalPanelTabItem } from '../types/define';
|
||||||
|
import { h } from 'vue';
|
||||||
import { InputProtocol } from '@/types/protocol/terminal.protocol';
|
import { InputProtocol } from '@/types/protocol/terminal.protocol';
|
||||||
import { PanelSessionType } from '../types/const';
|
import { PanelSessionType } from '../types/const';
|
||||||
import { Modal } from '@arco-design/web-vue';
|
import { Modal } from '@arco-design/web-vue';
|
||||||
@@ -77,15 +78,32 @@ export default class SftpSession extends BaseSession implements ISftpSession {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// 删除文件
|
// 删除文件
|
||||||
remove(path: string[]) {
|
remove(paths: string[]) {
|
||||||
|
// 内容
|
||||||
|
const contentNode = h('div', {
|
||||||
|
style: {
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column',
|
||||||
|
maxHeight: '40vh',
|
||||||
|
overflowY: 'auto'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
paths.map(s => {
|
||||||
|
return h('span', { style: { marginTop: '4px' } }, s);
|
||||||
|
}));
|
||||||
|
// 提示
|
||||||
Modal.confirm({
|
Modal.confirm({
|
||||||
title: '删除确认',
|
title: '确定后将立即删除这些文件且无法恢复!',
|
||||||
content: `确定要删除 ${path.join(',')} 吗? 确定后将立即删除且无法恢复!`,
|
modalStyle: { padding: '24px 32px' },
|
||||||
|
bodyStyle: { marginTop: '-14px' },
|
||||||
|
okButtonProps: { status: 'danger' },
|
||||||
|
okText: '删除',
|
||||||
|
content: () => contentNode,
|
||||||
onOk: () => {
|
onOk: () => {
|
||||||
this.resolver.setLoading(true);
|
this.resolver.setLoading(true);
|
||||||
this.channel.send(InputProtocol.SFTP_REMOVE, {
|
this.channel.send(InputProtocol.SFTP_REMOVE, {
|
||||||
sessionId: this.sessionId,
|
sessionId: this.sessionId,
|
||||||
path: path.join('|')
|
path: paths.join('|')
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -43,7 +43,6 @@ export default class SftpTransferManager implements ISftpTransferManager {
|
|||||||
file: s
|
file: s
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
this.transferList.push(...items);
|
|
||||||
// 开始传输
|
// 开始传输
|
||||||
this.startTransfer(items);
|
this.startTransfer(items);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
import type { ShortcutKeyItem } from './define';
|
import type { ShortcutKeyItem } from './define';
|
||||||
|
|
||||||
|
// 首页推荐数量
|
||||||
|
export const emptyRecommendCount = 7;
|
||||||
|
|
||||||
// 终端 tab
|
// 终端 tab
|
||||||
export const TerminalTabs = {
|
export const TerminalTabs = {
|
||||||
NEW_CONNECTION: {
|
NEW_CONNECTION: {
|
||||||
|
|||||||
@@ -93,8 +93,8 @@
|
|||||||
:data="tableRenderData"
|
:data="tableRenderData"
|
||||||
:pagination="pagination"
|
:pagination="pagination"
|
||||||
:bordered="false"
|
:bordered="false"
|
||||||
@page-change="(page) => fetchTableData(page, pagination.pageSize)"
|
@page-change="(page: number) => fetchTableData(page, pagination.pageSize)"
|
||||||
@page-size-change="(size) => fetchTableData(1, size)"
|
@page-size-change="(size: number) => fetchTableData(1, size)"
|
||||||
@expand="loadExecHost">
|
@expand="loadExecHost">
|
||||||
<!-- 展开表格 -->
|
<!-- 展开表格 -->
|
||||||
<template #expand-row="{ record }">
|
<template #expand-row="{ record }">
|
||||||
@@ -148,7 +148,7 @@
|
|||||||
type="text"
|
type="text"
|
||||||
size="mini"
|
size="mini"
|
||||||
title="ctrl + 左键新页面打开"
|
title="ctrl + 左键新页面打开"
|
||||||
@click="(e) => emits('viewLog', record.id, e.ctrlKey)">
|
@click="(e: any) => emits('viewLog', record.id, e.ctrlKey)">
|
||||||
日志
|
日志
|
||||||
</a-button>
|
</a-button>
|
||||||
<!-- 中断 -->
|
<!-- 中断 -->
|
||||||
|
|||||||
@@ -421,7 +421,7 @@
|
|||||||
|
|
||||||
.command-editor {
|
.command-editor {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: calc(100vh - 318px);
|
height: calc(100vh - 324px);
|
||||||
}
|
}
|
||||||
|
|
||||||
:deep(.arco-input-append) {
|
:deep(.arco-input-append) {
|
||||||
|
|||||||
@@ -84,8 +84,8 @@
|
|||||||
:data="tableRenderData"
|
:data="tableRenderData"
|
||||||
:pagination="pagination"
|
:pagination="pagination"
|
||||||
:bordered="false"
|
:bordered="false"
|
||||||
@page-change="(page) => fetchTableData(page, pagination.pageSize)"
|
@page-change="(page: number) => fetchTableData(page, pagination.pageSize)"
|
||||||
@page-size-change="(size) => fetchTableData(1, size)">
|
@page-size-change="(size: number) => fetchTableData(1, size)">
|
||||||
<!-- cron -->
|
<!-- cron -->
|
||||||
<template #expression="{ record }">
|
<template #expression="{ record }">
|
||||||
<span class="copy-left"
|
<span class="copy-left"
|
||||||
@@ -118,7 +118,7 @@
|
|||||||
:unchecked-text="getDictValue(execJobStatusKey, ExecJobStatus.DISABLED)"
|
:unchecked-text="getDictValue(execJobStatusKey, ExecJobStatus.DISABLED)"
|
||||||
:checked-value="ExecJobStatus.ENABLED"
|
:checked-value="ExecJobStatus.ENABLED"
|
||||||
:unchecked-value="ExecJobStatus.DISABLED"
|
:unchecked-value="ExecJobStatus.DISABLED"
|
||||||
:before-change="s => updateStatus(record.id, s as number)" />
|
:before-change="(s: number) => updateStatus(record.id, s)" />
|
||||||
<!-- 状态 不可编辑 -->
|
<!-- 状态 不可编辑 -->
|
||||||
<a-tag v-else :color="getDictValue(execJobStatusKey, record.status, 'color')">
|
<a-tag v-else :color="getDictValue(execJobStatusKey, record.status, 'color')">
|
||||||
{{ getDictValue(execJobStatusKey, record.status) }}
|
{{ getDictValue(execJobStatusKey, record.status) }}
|
||||||
|
|||||||
@@ -91,8 +91,8 @@
|
|||||||
:data="tableRenderData"
|
:data="tableRenderData"
|
||||||
:pagination="pagination"
|
:pagination="pagination"
|
||||||
:bordered="false"
|
:bordered="false"
|
||||||
@page-change="(page) => fetchTableData(page, pagination.pageSize)"
|
@page-change="(page: number) => fetchTableData(page, pagination.pageSize)"
|
||||||
@page-size-change="(size) => fetchTableData(1, size)">
|
@page-size-change="(size: number) => fetchTableData(1, size)">
|
||||||
<!-- 配置项 -->
|
<!-- 配置项 -->
|
||||||
<template #keyName="{ record }">
|
<template #keyName="{ record }">
|
||||||
<span class="text-copy" @click="copy(record.keyName)">{{ record.keyName }}</span>
|
<span class="text-copy" @click="copy(record.keyName)">{{ record.keyName }}</span>
|
||||||
|
|||||||
@@ -77,8 +77,8 @@
|
|||||||
:data="tableRenderData"
|
:data="tableRenderData"
|
||||||
:pagination="pagination"
|
:pagination="pagination"
|
||||||
:bordered="false"
|
:bordered="false"
|
||||||
@page-change="(page) => fetchTableData(page, pagination.pageSize)"
|
@page-change="(page: number) => fetchTableData(page, pagination.pageSize)"
|
||||||
@page-size-change="(size) => fetchTableData(1, size)">
|
@page-size-change="(size: number) => fetchTableData(1, size)">
|
||||||
<!-- 配置项 -->
|
<!-- 配置项 -->
|
||||||
<template #keyName="{record}">
|
<template #keyName="{record}">
|
||||||
{{ record.keyName }}<span style="margin: 0 4px;">-</span>{{ record.keyDescription }}
|
{{ record.keyName }}<span style="margin: 0 4px;">-</span>{{ record.keyDescription }}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
position="left"
|
position="left"
|
||||||
:lazy-load="true"
|
:lazy-load="true"
|
||||||
:destroy-on-hide="true"
|
:destroy-on-hide="true"
|
||||||
@tab-click="k => clickTab(k as string)">
|
@tab-click="(k: string) => clickTab(k)">
|
||||||
<!-- 个人信息 -->
|
<!-- 个人信息 -->
|
||||||
<a-tab-pane key="mineInfo"
|
<a-tab-pane key="mineInfo"
|
||||||
v-if="!user || hasPermission('infra:system-user:update')"
|
v-if="!user || hasPermission('infra:system-user:update')"
|
||||||
|
|||||||
@@ -7,8 +7,8 @@
|
|||||||
:data="tableRenderData"
|
:data="tableRenderData"
|
||||||
:pagination="pagination"
|
:pagination="pagination"
|
||||||
:bordered="false"
|
:bordered="false"
|
||||||
@page-change="(page) => fetchTableData(page, pagination.pageSize)"
|
@page-change="(page: number) => fetchTableData(page, pagination.pageSize)"
|
||||||
@page-size-change="(size) => fetchTableData(1, size)">
|
@page-size-change="(size: number) => fetchTableData(1, size)">
|
||||||
<!-- 操作模块 -->
|
<!-- 操作模块 -->
|
||||||
<template #module="{ record }">
|
<template #module="{ record }">
|
||||||
<span>{{ getDictValue(operatorLogModuleKey, record.module) }}</span>
|
<span>{{ getDictValue(operatorLogModuleKey, record.module) }}</span>
|
||||||
|
|||||||
@@ -55,8 +55,8 @@
|
|||||||
:data="tableRenderData"
|
:data="tableRenderData"
|
||||||
:pagination="pagination"
|
:pagination="pagination"
|
||||||
:bordered="false"
|
:bordered="false"
|
||||||
@page-change="(page) => fetchTableData(page, pagination.pageSize)"
|
@page-change="(page: number) => fetchTableData(page, pagination.pageSize)"
|
||||||
@page-size-change="(size) => fetchTableData(1, size)">
|
@page-size-change="(size: number) => fetchTableData(1, size)">
|
||||||
<!-- 操作模块 -->
|
<!-- 操作模块 -->
|
||||||
<template #module="{ record }">
|
<template #module="{ record }">
|
||||||
<span>{{ getDictValue(operatorLogModuleKey, record.module) }}</span>
|
<span>{{ getDictValue(operatorLogModuleKey, record.module) }}</span>
|
||||||
|
|||||||
@@ -60,8 +60,8 @@
|
|||||||
:data="tableRenderData"
|
:data="tableRenderData"
|
||||||
:pagination="pagination"
|
:pagination="pagination"
|
||||||
:bordered="false"
|
:bordered="false"
|
||||||
@page-change="(page) => fetchTableData(page, pagination.pageSize)"
|
@page-change="(page: number) => fetchTableData(page, pagination.pageSize)"
|
||||||
@page-size-change="(size) => fetchTableData(1, size)">
|
@page-size-change="(size: number) => fetchTableData(1, size)">
|
||||||
<!-- 编码 -->
|
<!-- 编码 -->
|
||||||
<template #code="{ record }">
|
<template #code="{ record }">
|
||||||
<a-tag>{{ record.code }}</a-tag>
|
<a-tag>{{ record.code }}</a-tag>
|
||||||
@@ -77,7 +77,7 @@
|
|||||||
:unchecked-text="getDictValue(roleStatusKey, RoleStatus.DISABLED)"
|
:unchecked-text="getDictValue(roleStatusKey, RoleStatus.DISABLED)"
|
||||||
:checked-value="RoleStatus.ENABLED"
|
:checked-value="RoleStatus.ENABLED"
|
||||||
:unchecked-value="RoleStatus.DISABLED"
|
:unchecked-value="RoleStatus.DISABLED"
|
||||||
:before-change="(s) => updateStatus(record.id, s as number)" />
|
:before-change="(s: number) => updateStatus(record.id, s)" />
|
||||||
<!-- 无修改权限 -->
|
<!-- 无修改权限 -->
|
||||||
<span v-else>
|
<span v-else>
|
||||||
<span class="circle" :style="{
|
<span class="circle" :style="{
|
||||||
|
|||||||
@@ -88,8 +88,8 @@
|
|||||||
:data="tableRenderData"
|
:data="tableRenderData"
|
||||||
:pagination="pagination"
|
:pagination="pagination"
|
||||||
:bordered="false"
|
:bordered="false"
|
||||||
@page-change="(page) => fetchTableData(page, pagination.pageSize)"
|
@page-change="(page: number) => fetchTableData(page, pagination.pageSize)"
|
||||||
@page-size-change="(size) => fetchTableData(1, size)">
|
@page-size-change="(size: number) => fetchTableData(1, size)">
|
||||||
<!-- 用户名 -->
|
<!-- 用户名 -->
|
||||||
<template #username="{ record }">
|
<template #username="{ record }">
|
||||||
<span class="text-copy" @click="copy(record.username)">
|
<span class="text-copy" @click="copy(record.username)">
|
||||||
@@ -107,7 +107,7 @@
|
|||||||
:unchecked-text="getDictValue(userStatusKey, UserStatus.DISABLED)"
|
:unchecked-text="getDictValue(userStatusKey, UserStatus.DISABLED)"
|
||||||
:checked-value="UserStatus.ENABLED"
|
:checked-value="UserStatus.ENABLED"
|
||||||
:unchecked-value="UserStatus.DISABLED"
|
:unchecked-value="UserStatus.DISABLED"
|
||||||
:before-change="(s) => updateStatus(record.id, s as number)" />
|
:before-change="(s: number) => updateStatus(record.id, s)" />
|
||||||
<!-- 无修改权限 -->
|
<!-- 无修改权限 -->
|
||||||
<span v-else>
|
<span v-else>
|
||||||
<span class="circle" :style="{
|
<span class="circle" :style="{
|
||||||
|
|||||||
2
pom.xml
2
pom.xml
@@ -22,7 +22,7 @@
|
|||||||
</modules>
|
</modules>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<revision>2.1.0</revision>
|
<revision>2.1.1</revision>
|
||||||
<maven.compiler.source>8</maven.compiler.source>
|
<maven.compiler.source>8</maven.compiler.source>
|
||||||
<maven.compiler.target>8</maven.compiler.target>
|
<maven.compiler.target>8</maven.compiler.target>
|
||||||
<maven.surefire.plugin.version>3.0.0-M5</maven.surefire.plugin.version>
|
<maven.surefire.plugin.version>3.0.0-M5</maven.surefire.plugin.version>
|
||||||
|
|||||||
Reference in New Issue
Block a user