fix SSH 终端新增标签页打开方式

This commit is contained in:
bwcx_jzy 2022-06-16 12:35:30 +08:00
parent ecf26c1f2b
commit f9ee62d30e
No known key found for this signature in database
GPG Key ID: 5E48E9372088B9E5
9 changed files with 150 additions and 25 deletions

View File

@ -5,6 +5,8 @@
### 🐣 新增功能
1. 【server】SSH 终端新增标签页打开方式(感谢@hu向...🤡)
### 🐞 解决BUG、优化功能
1. 【server】db 安全检查时机前置(是否开启 web 访问),避免突然关闭数据库(感谢@信徒)
@ -35,6 +37,8 @@
> 此版本为不兼容升级,需要手动升级操作数据相关迁移,操作流程如下:
**(下述流程仅供简单思路参考,不同版本间存在部分差异,详细流程还请差异完整文档:[https://jpom.io/pages/upgrade/2.8.x-to-2.9.x](https://jpom.io/pages/upgrade/2.8.x-to-2.9.x) **
1. 导出低版本数据
1. 启动程序参数里面添加 --backup-h2
2. linux 环境举例:`sh /xxxx/Server.sh restart --backup-h2`

View File

@ -101,6 +101,15 @@ public class SshController extends BaseServerController {
return new JsonMessage<>(200, "", list);
}
@GetMapping(value = "get-item.json", produces = MediaType.APPLICATION_JSON_VALUE)
@Feature(method = MethodFeature.LIST)
public JsonMessage<SshModel> getItem(@ValidatorItem String id) {
SshModel byKey = sshService.getByKey(id, getRequest());
Assert.notNull(byKey, "对应的 ssh 不存在");
return new JsonMessage<>(200, "", byKey);
}
/**
* 编辑
*

View File

@ -9,6 +9,15 @@ export function getSshList(params) {
});
}
// 查询单个 ssh
export function getItem(params) {
return axios({
url: "/node/ssh/get-item.json",
method: "get",
params: params,
});
}
// 检查 ssh 是否安装 插件端
export function getSshCheckAgent(params) {
return axios({

View File

@ -88,6 +88,7 @@
<a-menu-item>
<a-tooltip
placement="leftBottom"
title="清除代码(仓库目录)为删除服务器中存储仓库目录里面的所有东西,删除后下次构建将重新拉起仓库里面的文件,一般用于解决服务器中文件和远程仓库中文件有冲突时候使用。执行时间取决于源码目录大小和文件数量如超时请耐心等待,或稍后重试"
>
<a-button size="small" type="danger" :disabled="!record.sourceDirExist" @click="handleClear(record)">清除代码 </a-button>
@ -735,30 +736,30 @@
<script>
import CustomSelect from "@/components/customSelect";
import BuildLog from "./log";
import { getRepositoryListAll } from "@/api/repository";
import {getRepositoryListAll} from "@/api/repository";
import {
buildModeMap,
clearBuid,
deleteBuild,
editBuild,
getBranchList,
buildModeMap,
getBuildGroupAll,
getBuildList,
getTriggerUrl,
releaseMethodMap,
resetTrigger,
startBuild,
stopBuild,
statusMap,
getBuildGroupAll,
stopBuild,
} from "@/api/build-info";
import { getDishPatchListAll, afterOptList, afterOptListSimple } from "@/api/dispatch";
import { getProjectListAll, getNodeListAll } from "@/api/node";
import { getSshListAll } from "@/api/ssh";
import { itemGroupBy, parseTime } from "@/utils/time";
import {afterOptList, afterOptListSimple, getDishPatchListAll} from "@/api/dispatch";
import {getNodeListAll, getProjectListAll} from "@/api/node";
import {getSshListAll} from "@/api/ssh";
import {itemGroupBy, parseTime} from "@/utils/time";
import codeEditor from "@/components/codeEditor";
import { COMPUTED_PAGINATION, CHANGE_PAGE, PAGE_DEFAULT_LIST_QUERY, CRON_DATA_SOURCE } from "@/utils/const";
import {CHANGE_PAGE, COMPUTED_PAGINATION, CRON_DATA_SOURCE, PAGE_DEFAULT_LIST_QUERY} from "@/utils/const";
import Vue from "vue";
import { dockerSwarmListAll, dockerSwarmServicesList } from "@/api/docker-swarm";
import {dockerSwarmListAll, dockerSwarmServicesList} from "@/api/docker-swarm";
export default {
components: {

View File

@ -0,0 +1,87 @@
<template>
<div>
<a-spin :spinning="spinning">
<a-card
size="small"
:bodyStyle="{
height: `calc(100vh - 45px)`,
}"
>
<template #title>
<template v-if="sshData">
<a-space>
<div>{{ sshData.name }} ({{ sshData.host }})</div>
<a-button size="small" type="primary" :disabled="!sshData.fileDirs" @click="handleFile()">文件</a-button>
</a-space>
</template>
<template v-else>loading</template>
</template>
<a slot="extra" href="#"></a>
<terminal v-if="sshData" :sshId="sshData.id" />
<template v-else>
<a-result status="404" title="404" sub-title="没有对应的SSH">
<template #extra>
<router-link :to="{ path: '/ssh', query: {} }">
<a-button type="primary">返回首页</a-button>
</router-link>
</template>
</a-result>
</template>
</a-card>
</a-spin>
<!-- 文件管理 -->
<a-drawer v-if="sshData" :title="`${sshData.name} (${sshData.host}) 文件管理`" placement="right" width="90vw" :visible="drawerVisible" @close="onClose">
<ssh-file v-if="drawerVisible" :ssh="sshData" />
</a-drawer>
</div>
</template>
<script>
import terminal from "./terminal";
import {getItem} from "@/api/ssh";
import SshFile from "@/pages/ssh/ssh-file";
export default {
components: {
terminal,
SshFile,
},
data() {
return {
sshId: "",
sshData: null,
spinning: true,
drawerVisible: false,
};
},
computed: {},
mounted() {
this.sshId = this.$route.query.id;
if (this.sshId) {
this.loadItemData();
}
},
beforeDestroy() {},
methods: {
loadItemData() {
getItem({
id: this.sshId,
}).then((res) => {
this.spinning = false;
if (res.code === 200) {
this.sshData = res.data;
}
console.log(this.sshData);
});
},
handleFile() {
this.drawerVisible = true;
},
//
onClose() {
this.drawerVisible = false;
},
},
};
</script>

View File

@ -74,6 +74,11 @@
<a-menu-item key="1">
<a-button size="small" type="primary" icon="fullscreen" @click="handleTerminal(record, true)">全屏终端</a-button>
</a-menu-item>
<a-menu-item key="2">
<router-link target="_blank" :to="{ path: '/full-terminal', query: { id: record.id, wid: getWorkspaceId } }">
<a-button size="small" type="primary" icon="fullscreen"> 新标签终端</a-button>
</router-link>
</a-menu-item>
</a-menu>
</a-dropdown>
@ -371,14 +376,14 @@
</div>
</template>
<script>
import { deleteSsh, editSsh, getSshList, getSshCheckAgent, getSshOperationLogList, installAgentNode, getAgent, uploadAgent, syncToWorkspace } from "@/api/ssh";
import {deleteSsh, editSsh, getAgent, getSshCheckAgent, getSshList, getSshOperationLogList, installAgentNode, syncToWorkspace, uploadAgent} from "@/api/ssh";
import SshFile from "@/pages/ssh/ssh-file";
import Terminal from "@/pages/ssh/terminal";
import { parseTime } from "@/utils/time";
import { COMPUTED_PAGINATION, CHANGE_PAGE, PAGE_DEFAULT_LIST_QUERY } from "@/utils/const";
import { getWorkSpaceListAll } from "@/api/workspace";
import {parseTime} from "@/utils/time";
import {CHANGE_PAGE, COMPUTED_PAGINATION, PAGE_DEFAULT_LIST_QUERY} from "@/utils/const";
import {getWorkSpaceListAll} from "@/api/workspace";
import Vue from "vue";
import { mapGetters } from "vuex";
import {mapGetters} from "vuex";
export default {
components: {

View File

@ -2,8 +2,8 @@
<terminal :url="this.socketUrl" />
</template>
<script>
import { mapGetters } from "vuex";
import { getWebSocketUrl } from "@/utils/const";
import {mapGetters} from "vuex";
import {getWebSocketUrl} from "@/utils/const";
import terminal from "@/components/terminal";
// https://blog.csdn.net/qq_41840688/article/details/108636267
@ -16,13 +16,13 @@ export default {
sshId: {
type: String,
},
nodeId: {
type: String,
default: "system",
},
tail: {
type: String,
},
// nodeId: {
// type: String,
// default: "system",
// },
// tail: {
// type: String,
// },
},
data() {
return {};
@ -30,7 +30,7 @@ export default {
computed: {
...mapGetters(["getLongTermToken"]),
socketUrl() {
return getWebSocketUrl("/socket/ssh", `userId=${this.getLongTermToken}&id=${this.sshId}&nodeId=${this.nodeId}&type=ssh&tail=${this.tail}`);
return getWebSocketUrl("/socket/ssh", `userId=${this.getLongTermToken}&id=${this.sshId}&nodeId=system&type=ssh&tail=${this.tail}`);
},
},
mounted() {},

View File

@ -8,6 +8,7 @@ import store from "../store/index";
// 不需要鉴权的名单
const whiteList = ["/login", "/install", "/system/ipAccess"];
const noTabs = ["/full-terminal"];
router.beforeEach((to, from, next) => {
// 检测白名单
@ -27,6 +28,10 @@ router.beforeEach((to, from, next) => {
return;
}
if (noTabs.indexOf(to.path) !== -1) {
next();
return;
}
// 如果存在 token (已经登录)
store.dispatch("loadSystemMenus").then(() => {
// 存储 store

View File

@ -202,6 +202,11 @@ const router = new Router({
name: "install",
component: () => import("../pages/login/install"),
},
{
path: "/full-terminal",
name: "full-terminal",
component: () => import("../pages/ssh/full-terminal"),
},
{
path: "*",
name: "404",