mirror of
https://gitee.com/dromara/Jpom.git
synced 2024-12-03 12:29:14 +08:00
add project console page feature
This commit is contained in:
parent
582be4a257
commit
703289f12e
@ -250,4 +250,38 @@ export function getRecoverData(params) {
|
||||
method: 'post',
|
||||
data: params
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取项目日志文件大小
|
||||
* @param {
|
||||
* nodeId: 节点 ID
|
||||
* id: 项目 ID
|
||||
* copyId: copyId
|
||||
* } params
|
||||
*/
|
||||
export function getProjectLogSize(params) {
|
||||
return axios({
|
||||
url: '/node/manage/log/logSize',
|
||||
method: 'post',
|
||||
data: params
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载项目日志文件
|
||||
* @param {
|
||||
* nodeId: 节点 ID
|
||||
* id: 项目 ID
|
||||
* copyId: copyId
|
||||
* } params
|
||||
*/
|
||||
export function downloadProjectLogFile(params) {
|
||||
return axios({
|
||||
url: '/node/manage/log/export.html',
|
||||
method: 'get',
|
||||
responseType: 'blob',
|
||||
timeout: 0,
|
||||
params
|
||||
})
|
||||
}
|
185
web-vue/src/pages/node/node-layout/project/project-console.vue
Normal file
185
web-vue/src/pages/node/node-layout/project/project-console.vue
Normal file
@ -0,0 +1,185 @@
|
||||
<template>
|
||||
<div>
|
||||
<div ref="filter" class="filter">
|
||||
<a-button :disabled="project.status" type="primary" @click="start">启动</a-button>
|
||||
<a-button :disabled="!project.status" type="danger" @click="restart">重启</a-button>
|
||||
<a-button :disabled="!project.status" type="danger" @click="stop">停止</a-button>
|
||||
<a-button type="primary" @click="handleDownload">导出日志</a-button>
|
||||
<a-button type="primary" >备份列表</a-button>
|
||||
<a-tag color="#87d068">文件大小: {{project.logSize}}</a-tag>
|
||||
</div>
|
||||
<div>
|
||||
<a-input class="console" v-model="logContext" readOnly type="textarea" style="resize: none;"/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { getProjectLogSize, downloadProjectLogFile } from '../../../../api/node-project';
|
||||
import { mapGetters } from 'vuex';
|
||||
export default {
|
||||
props: {
|
||||
node: {
|
||||
type: Object
|
||||
},
|
||||
project: {
|
||||
type: Object
|
||||
},
|
||||
copyId: {
|
||||
type: String
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
socket: null,
|
||||
// 日志内容
|
||||
logContext: '',
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters([
|
||||
'getToken'
|
||||
]),
|
||||
socketUrl() {
|
||||
const protocol = location.protocol === 'https' ? 'wss://' : 'ws://';
|
||||
return `${protocol}${location.host}/console?userId=${this.getToken}&projectId=${this.project.id}&nodeId=${this.node.id}&type=console©Id=${this.copyId}`;
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.initWebSocket();
|
||||
this.loadFileSize();
|
||||
},
|
||||
beforeDestroy() {
|
||||
this.socket.close();
|
||||
},
|
||||
methods: {
|
||||
// 初始化
|
||||
initWebSocket() {
|
||||
this.logContext = '';
|
||||
if (!this.socket || this.socket.readyState !== this.socket.OPEN || this.socket.readyState !== this.socket.CONNECTING) {
|
||||
this.socket = new WebSocket(this.socketUrl);
|
||||
}
|
||||
// 连接成功后
|
||||
this.socket.onopen = () => {
|
||||
this.sendMsg('status');
|
||||
this.sendMsg('showlog');
|
||||
}
|
||||
this.socket.onmessage = (msg) => {
|
||||
if (msg.data.indexOf('code') > -1 && msg.data.indexOf('msg') > -1) {
|
||||
const res = JSON.parse(msg.data);
|
||||
if (res.code === 200) {
|
||||
this.$notification.success({
|
||||
message: res.msg,
|
||||
duration: 3
|
||||
});
|
||||
// 如果操作是启动或者停止
|
||||
if (res.op === 'stop') {
|
||||
this.project.status = false;
|
||||
}
|
||||
if (res.op === 'start') {
|
||||
this.project.status = true;
|
||||
}
|
||||
} else {
|
||||
this.$notification.error({
|
||||
message: res.msg,
|
||||
duration: 5
|
||||
});
|
||||
}
|
||||
}
|
||||
this.logContext += `${msg.data}\r\n`;
|
||||
}
|
||||
},
|
||||
// 发送消息
|
||||
sendMsg(op) {
|
||||
const data = {
|
||||
op: op,
|
||||
projectId: this.project.id,
|
||||
copyId: this.copyId
|
||||
}
|
||||
this.socket.send(JSON.stringify(data));
|
||||
},
|
||||
// 加载日志文件大小
|
||||
loadFileSize() {
|
||||
const params = {
|
||||
nodeId: this.node.id,
|
||||
id: this.project.id,
|
||||
copyId: this.copyId
|
||||
}
|
||||
getProjectLogSize(params).then(res => {
|
||||
if (res.code === 200) {
|
||||
this.project.logSize = res.data.logSize;
|
||||
}
|
||||
})
|
||||
},
|
||||
// 启动
|
||||
start() {
|
||||
this.sendMsg('start');
|
||||
},
|
||||
// 重启
|
||||
restart() {
|
||||
this.$confirm({
|
||||
title: '系统提示',
|
||||
content: '真的要重启项目么?',
|
||||
okText: '确认',
|
||||
cancelText: '取消',
|
||||
onOk: () => {
|
||||
this.sendMsg('restart');
|
||||
}
|
||||
});
|
||||
},
|
||||
// 停止
|
||||
stop() {
|
||||
this.$confirm({
|
||||
title: '系统提示',
|
||||
content: '真的要重启项目么?',
|
||||
okText: '确认',
|
||||
cancelText: '取消',
|
||||
onOk: () => {
|
||||
this.sendMsg('stop');
|
||||
}
|
||||
});
|
||||
},
|
||||
// 下载日志文件
|
||||
handleDownload() {
|
||||
this.$notification.info({
|
||||
message: '正在下载,请稍等...',
|
||||
duration: 5
|
||||
});
|
||||
// 请求参数
|
||||
const params = {
|
||||
nodeId: this.node.id,
|
||||
id: this.project.id,
|
||||
copyId: this.copyId
|
||||
}
|
||||
// 请求接口拿到 blob
|
||||
downloadProjectLogFile(params).then(blob => {
|
||||
const url = window.URL.createObjectURL(blob);
|
||||
let link = document.createElement('a');
|
||||
link.style.display = 'none';
|
||||
link.href = url;
|
||||
link.setAttribute('download', this.project.log);
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style scoped>
|
||||
.filter {
|
||||
margin: 0 0 10px;
|
||||
}
|
||||
.ant-btn {
|
||||
margin-right: 10px;
|
||||
}
|
||||
.console {
|
||||
padding: 5px;
|
||||
color: #fff;
|
||||
font-size: 14px;
|
||||
background-color: black;
|
||||
width: 100%;
|
||||
height: calc(100vh - 120px);
|
||||
overflow-y: auto;
|
||||
border: 1px solid #e2e2e2;
|
||||
border-radius: 5px 5px;
|
||||
}
|
||||
</style>
|
@ -17,7 +17,7 @@
|
||||
<template slot="operation" slot-scope="text, record">
|
||||
<a-button type="primary" @click="handleEdit(record)">编辑</a-button>
|
||||
<a-button type="primary" @click="handleFile(record)">文件</a-button>
|
||||
<a-button type="primary" @click="handleEdit(record)">控制台</a-button>
|
||||
<a-button type="primary" @click="handleConsole(record)">控制台</a-button>
|
||||
<a-button type="primary" @click="handleEdit(record)">监控</a-button>
|
||||
<a-button type="danger" @click="handleDelete(record)">删除</a-button>
|
||||
</template>
|
||||
@ -74,16 +74,21 @@
|
||||
</a-form-model-item>
|
||||
</a-form-model>
|
||||
</a-modal>
|
||||
<!-- 项目文件 -->
|
||||
<!-- 项目文件组件 -->
|
||||
<a-drawer :title="drawerTitle" placement="right" width="85vw"
|
||||
:visible="drawerFileVisible" @close="onFileClose">
|
||||
<!-- 项目文件组件 -->
|
||||
<file v-if="drawerFileVisible" :node="node" :project="temp" />
|
||||
</a-drawer>
|
||||
<!-- 项目控制台组件 -->
|
||||
<a-drawer :title="drawerTitle" placement="right" width="85vw"
|
||||
:visible="drawerConsoleVisible" @close="onConsoleClose">
|
||||
<console v-if="drawerConsoleVisible" :node="node" :project="temp" />
|
||||
</a-drawer>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import File from './project-file';
|
||||
import Console from './project-console';
|
||||
import { getJdkList, getRuningProjectInfo, getProjectById, deleteProject, getProjectList, getPorjectGroupList, getProjectAccessList, editProject } from '../../../../api/node-project';
|
||||
export default {
|
||||
props: {
|
||||
@ -92,7 +97,8 @@ export default {
|
||||
}
|
||||
},
|
||||
components: {
|
||||
File
|
||||
File,
|
||||
Console
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
@ -113,6 +119,7 @@ export default {
|
||||
editProjectVisible: false,
|
||||
drawerTitle: '',
|
||||
drawerFileVisible: false,
|
||||
drawerConsoleVisible: false,
|
||||
columns: [
|
||||
{title: '项目名称', dataIndex: 'name', width: 150, ellipsis: true, scopedSlots: {customRender: 'name'}},
|
||||
{title: '创建时间', dataIndex: 'createTime', width: 170, ellipsis: true, scopedSlots: {customRender: 'createTime'}},
|
||||
@ -272,6 +279,17 @@ export default {
|
||||
onFileClose() {
|
||||
this.drawerFileVisible = false;
|
||||
},
|
||||
// 控制台
|
||||
handleConsole(record) {
|
||||
this.temp = Object.assign(record);
|
||||
this.drawerTitle = `控制台(${this.temp.name})`;
|
||||
this.drawerConsoleVisible = true;
|
||||
},
|
||||
// 关闭控制台
|
||||
onConsoleClose() {
|
||||
this.drawerConsoleVisible = false;
|
||||
this.handleFilter();
|
||||
},
|
||||
// 删除
|
||||
handleDelete(record) {
|
||||
this.$confirm({
|
||||
|
@ -13,7 +13,7 @@
|
||||
<a-button type="primary" @click="loadData">刷新</a-button>
|
||||
</div>
|
||||
<div>
|
||||
<a-input v-model="logContext" readOnly type="textarea" style="resize: none;height: calc(100vh - 185px);"/>
|
||||
<a-input class="console" v-model="logContext" readOnly type="textarea" style="resize: none;"/>
|
||||
</div>
|
||||
</a-layout-content>
|
||||
<!-- 对话框 -->
|
||||
@ -191,4 +191,15 @@ export default {
|
||||
.ant-btn {
|
||||
margin: 10px;
|
||||
}
|
||||
.console {
|
||||
padding: 5px;
|
||||
color: #fff;
|
||||
font-size: 14px;
|
||||
background-color: black;
|
||||
width: 100%;
|
||||
height: calc(100vh - 185px);
|
||||
overflow-y: auto;
|
||||
border: 1px solid #e2e2e2;
|
||||
border-radius: 5px 5px;
|
||||
}
|
||||
</style>
|
@ -13,7 +13,7 @@
|
||||
<a-button type="primary" @click="loadData">刷新</a-button>
|
||||
</div>
|
||||
<div>
|
||||
<a-input v-model="logContext" readOnly type="textarea" style="resize: none;height: calc(100vh - 165px);"/>
|
||||
<a-input class="console" v-model="logContext" readOnly type="textarea" style="resize: none;"/>
|
||||
</div>
|
||||
</a-layout-content>
|
||||
<!-- 对话框 -->
|
||||
@ -190,4 +190,15 @@ export default {
|
||||
.ant-btn {
|
||||
margin: 10px;
|
||||
}
|
||||
.console {
|
||||
padding: 5px;
|
||||
color: #fff;
|
||||
font-size: 14px;
|
||||
background-color: black;
|
||||
width: 100%;
|
||||
height: calc(100vh - 165px);
|
||||
overflow-y: auto;
|
||||
border: 1px solid #e2e2e2;
|
||||
border-radius: 5px 5px;
|
||||
}
|
||||
</style>
|
@ -18,6 +18,12 @@ module.exports = {
|
||||
ws: false,
|
||||
logLevel: 'debug'
|
||||
},
|
||||
'/console': {
|
||||
target: 'ws://localhost:2122',
|
||||
// true/false: if you want to proxy websockets
|
||||
ws: false,
|
||||
logLevel: 'debug'
|
||||
},
|
||||
// http
|
||||
'/*': {
|
||||
target: 'http://localhost:2122'
|
||||
|
Loading…
Reference in New Issue
Block a user