fix 项目列表可以查看项目日志(避免控制台卡顿无法操作下载日志)

This commit is contained in:
bwcx_jzy 2023-06-09 10:35:27 +08:00
parent 11f21ea9e1
commit cb6503511a
No known key found for this signature in database
GPG Key ID: E187D6E9DDDE8C53
4 changed files with 227 additions and 151 deletions

View File

@ -8,6 +8,7 @@
1. 【server】修复 页面关闭 docker 终端未主动关闭后台终端进程问题
2. 【server】优化 docker 终端页面缓冲区大小自动适应
3. 【server】优化 项目列表可以查看项目日志(避免控制台卡顿无法操作下载日志)(感谢@阿超)
------

View File

@ -25,62 +25,50 @@
<a-dropdown>
<!-- <a type="link" class="ant-dropdown-link"> 更多<a-icon type="down" /> </a> -->
<a class="ant-dropdown-link" @click="(e) => e.preventDefault()">
<a
class="ant-dropdown-link"
@click="
(e) => {
e.preventDefault();
handleLogBack();
}
"
>
<a-tag>
文件大小: {{ project.logSize || "-" }}
<!-- 更多 -->
<a-icon type="down" />
<a-icon type="fullscreen" />
</a-tag>
</a>
<a-menu slot="overlay">
<!-- <a-menu slot="overlay">
<a-menu-item>
<a-button type="primary" size="small" :disabled="!project.logSize" @click="handleDownload">导出日志</a-button>
</a-menu-item>
<a-menu-item>
<a-button type="primary" size="small" @click="handleLogBack">备份列表</a-button>
</a-menu-item>
</a-menu>
</a-menu> -->
</a-dropdown>
</a-space>
</template>
</log-view>
<!-- 日志备份 -->
<a-modal destroyOnClose v-model="lobbackVisible" title="日志备份列表" width="850px" :footer="null" :maskClosable="false">
<div ref="model-filter" class="filter">
<a-space direction="vertical">
<a-tag>控制台日志只是启动项目输出的日志信息,并非项目日志可以关闭控制台日志备份功能<b>jpom.project.log.auto-backup-to-file: false</b></a-tag>
<a-tag color="orange">控制台日志路径: {{ project.log }}</a-tag>
<a-tag color="orange">控制台日志备份路径: {{ project.logBack }}</a-tag>
</a-space>
</div>
<!-- 数据表格 -->
<a-table :data-source="logBackList" :loading="loading" :columns="columns" :scroll="{ y: 400 }" :pagination="false" bordered :rowKey="(record, index) => index">
<a-tooltip slot="filename" slot-scope="text" placement="topLeft" :title="text">
<span>{{ text }}</span>
</a-tooltip>
<a-tooltip slot="fileSize" slot-scope="text" placement="topLeft" :title="text">
<span>{{ text }}</span>
</a-tooltip>
<template slot="operation" slot-scope="text, record">
<a-space>
<a-button type="primary" @click="handleDownloadLogback(record)">下载</a-button>
<a-button type="danger" @click="handleDelete(record)">删除</a-button>
</a-space>
</template>
</a-table>
<ProjectLog v-if="lobbackVisible" :nodeId="this.nodeId" :copyId="this.copyId" :projectId="this.projectId"></ProjectLog>
</a-modal>
</div>
</template>
<script>
import { deleteProjectLogBackFile, downloadProjectLogBackFile, downloadProjectLogFile, getLogBackList, getProjectData, getProjectLogSize } from "@/api/node-project";
import { getProjectData, getProjectLogSize } from "@/api/node-project";
import { mapGetters } from "vuex";
import { getWebSocketUrl } from "@/utils/const";
import LogView from "@/components/logView";
import ProjectLog from "./project-log.vue";
export default {
components: {
LogView,
ProjectLog,
},
props: {
nodeId: {
@ -104,13 +92,7 @@ export default {
socket: null,
logExist: false,
lobbackVisible: false,
logBackList: [],
columns: [
{ title: "文件名称", dataIndex: "filename", width: 150, ellipsis: true, scopedSlots: { customRender: "filename" } },
{ title: "修改时间", dataIndex: "modifyTime", width: 150, ellipsis: true, scopedSlots: { customRender: "modifyTime" } },
{ title: "文件大小", dataIndex: "fileSize", width: 100, ellipsis: true, scopedSlots: { customRender: "fileSize" } },
{ title: "操作", dataIndex: "operation", scopedSlots: { customRender: "operation" }, width: 130 },
],
heart: null,
};
},
@ -281,100 +263,17 @@ export default {
},
});
},
//
handleDownload() {
this.$notification.info({
message: "正在下载,请稍等...",
});
//
const params = {
nodeId: this.nodeId,
id: this.projectId,
copyId: this.copyId,
};
// blob
window.open(downloadProjectLogFile(params), "_blank");
},
//
handleLogBack() {
this.loading = true;
//
this.detailData = [];
// this.detailData = [];
this.lobbackVisible = true;
const params = {
nodeId: this.nodeId,
id: this.projectId,
copyId: this.copyId,
};
getLogBackList(params).then((res) => {
if (res.code === 200) {
this.logBackList = res.data.array;
}
this.loading = false;
});
},
//
handleDownloadLogback(record) {
this.$notification.info({
message: "正在下载,请稍等...",
});
//
const params = {
nodeId: this.nodeId,
id: this.projectId,
copyId: this.copyId,
key: record.filename,
};
// blob
window.open(downloadProjectLogBackFile(params), "_blank");
},
//
handleDelete(record) {
this.$confirm({
title: "系统提示",
content: "真的要删除文件么?",
okText: "确认",
cancelText: "取消",
onOk: () => {
//
const params = {
nodeId: this.nodeId,
id: this.projectId,
copyId: this.copyId,
name: record.filename,
};
//
deleteProjectLogBackFile(params).then((res) => {
if (res.code === 200) {
this.$notification.success({
message: res.msg,
});
this.handleLogBack();
}
});
},
});
},
goFile() {
this.$emit("goFile");
},
},
};
</script>
<style scoped>
/* .filter {
margin: 0 0 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>

View File

@ -12,6 +12,7 @@
@change="
(pagination, filters, sorter) => {
this.listQuery = CHANGE_PAGE(this.listQuery, { pagination, sorter });
this.expandedRowKeys = [];
this.loadData();
}
"
@ -119,6 +120,7 @@
<template slot="operation" slot-scope="text, copyRecord">
<a-space>
<a-button size="small" type="primary" @click="handleConsoleCopy(record, copyRecord)">控制台</a-button>
<a-button size="small" type="primary" @click="handleLogBack(record, copyRecord)">日志</a-button>
<a-button size="small" type="danger" @click="handleDeleteCopy(record, copyRecord, 'thorough')">删除</a-button>
</a-space>
</template>
@ -143,13 +145,13 @@
<a-menu-item>
<a-button size="small" type="primary" @click="copyItem(record)">复制</a-button>
</a-menu-item>
<!-- <a-menu-item>
<a-button size="small" type="primary" @click="handleReplica(record)" v-if="javaModes.includes(record.runMode)" :disabled="!record.javaCopyItemList">副本集 </a-button>
</a-menu-item> -->
<a-menu-item v-if="noFileModes.includes(record.runMode)">
<a-button size="small" type="primary" @click="handleLogBack(record)">项目日志 </a-button>
</a-menu-item>
<template v-if="record.outGivingProject">
<a-menu-item>
<a-tooltip title="节点分发项目需要到节点分发中去删除">
<a-button size="small" type="danger" :disabled="true">删除</a-button>
<a-button size="small" type="danger" :disabled="true">逻辑删除</a-button>
</a-tooltip>
</a-menu-item>
<a-menu-item>
@ -163,7 +165,7 @@
</template>
<template v-else>
<a-menu-item>
<a-button size="small" type="danger" @click="handleDelete(record)">删除</a-button>
<a-button size="small" type="danger" @click="handleDelete(record)">逻辑删除</a-button>
</a-menu-item>
<a-menu-item>
<a-button size="small" type="danger" @click="handleDelete(record, 'thorough')">彻底删除</a-button>
@ -441,6 +443,10 @@
</a-list-item>
</a-list>
</a-modal>
<!-- 日志备份 -->
<a-modal destroyOnClose v-model="lobbackVisible" title="日志备份列表" width="850px" :footer="null" :maskClosable="false">
<ProjectLog v-if="lobbackVisible" :nodeId="node.id" :copyId="temp.copyItem && temp.copyItem.id" :projectId="temp.projectId"></ProjectLog>
</a-modal>
</div>
</template>
<script>
@ -449,6 +455,7 @@ import Console from "./project-console";
import FileRead from "./project-file-read";
import CustomSelect from "@/components/customSelect";
// import Replica from "./project-replica";
import ProjectLog from "./project-log.vue";
import codeEditor from "@/components/codeEditor";
import { CHANGE_PAGE, COMPUTED_PAGINATION, PAGE_DEFAULT_LIST_QUERY, PROJECT_DSL_DEFATUL, randomStr, parseTime } from "@/utils/const";
@ -487,6 +494,7 @@ export default {
// Replica,
codeEditor,
FileRead,
ProjectLog,
},
data() {
return {
@ -515,8 +523,31 @@ export default {
checkRecord: "",
batchVisible: false,
batchTitle: "",
columns: [
{ title: "", dataIndex: "javaCopyItemList", align: "center", width: "40px", scopedSlots: { customRender: "copyIcon" } },
copyColumns: [
{ title: "编号", dataIndex: "id", width: "80px", ellipsis: true, scopedSlots: { customRender: "id" } },
{ title: "名称", dataIndex: "name", width: 150, ellipsis: true, scopedSlots: { customRender: "name" } },
{ title: "状态", dataIndex: "status", width: 100, ellipsis: true, scopedSlots: { customRender: "status" } },
{ title: "进程 ID", dataIndex: "pid", width: 100, ellipsis: true, scopedSlots: { customRender: "pid" } },
{ title: "端口号", dataIndex: "port", width: 100, ellipsis: true, scopedSlots: { customRender: "port" } },
{ title: "最后修改时间", dataIndex: "modifyTime", width: "180px", ellipsis: true, scopedSlots: { customRender: "modifyTime" } },
{ title: "操作", dataIndex: "operation", scopedSlots: { customRender: "operation" }, width: "150px" },
],
rules: {
id: [{ required: true, message: "请输入项目ID", trigger: "blur" }],
name: [{ required: true, message: "请输入项目名称", trigger: "blur" }],
runMode: [{ required: true, message: "请选择项目运行方式", trigger: "blur" }],
whitelistDirectory: [{ required: true, message: "请选择项目白名单路径", trigger: "blur" }],
lib: [{ required: true, message: "请输入项目文件夹", trigger: "blur" }],
},
expandedRowKeys: [],
lobbackVisible: false,
showJavaCopyItemList: false,
};
},
computed: {
columns() {
const columns = [
{ title: "项目名称", dataIndex: "name", width: 150, sorter: true, ellipsis: true, scopedSlots: { customRender: "name" } },
{ title: "项目分组", dataIndex: "group", sorter: true, width: "100px", ellipsis: true, scopedSlots: { customRender: "group" } },
{
@ -547,28 +578,12 @@ export default {
width: "170px",
},
{ title: "修改时间", sorter: true, dataIndex: "modifyTimeMillis", width: "170px", ellipsis: true, customRender: (text) => parseTime(text) },
{ title: "操作", dataIndex: "operation", scopedSlots: { customRender: "operation" }, fixed: "right", align: "center", width: "180px" },
],
copyColumns: [
{ title: "编号", dataIndex: "id", width: "80px", ellipsis: true, scopedSlots: { customRender: "id" } },
{ title: "名称", dataIndex: "name", width: 150, ellipsis: true, scopedSlots: { customRender: "name" } },
{ title: "状态", dataIndex: "status", width: 100, ellipsis: true, scopedSlots: { customRender: "status" } },
{ title: "进程 ID", dataIndex: "pid", width: 100, ellipsis: true, scopedSlots: { customRender: "pid" } },
{ title: "端口号", dataIndex: "port", width: 100, ellipsis: true, scopedSlots: { customRender: "port" } },
{ title: "最后修改时间", dataIndex: "modifyTime", width: "180px", ellipsis: true, scopedSlots: { customRender: "modifyTime" } },
{ title: "操作", dataIndex: "operation", scopedSlots: { customRender: "operation" }, width: "120px" },
],
rules: {
id: [{ required: true, message: "请输入项目ID", trigger: "blur" }],
name: [{ required: true, message: "请输入项目名称", trigger: "blur" }],
runMode: [{ required: true, message: "请选择项目运行方式", trigger: "blur" }],
whitelistDirectory: [{ required: true, message: "请选择项目白名单路径", trigger: "blur" }],
lib: [{ required: true, message: "请输入项目文件夹", trigger: "blur" }],
},
expandedRowKeys: [],
};
},
computed: {
];
this.showJavaCopyItemList && columns.unshift({ title: "", dataIndex: "javaCopyItemList", align: "center", width: "40px", scopedSlots: { customRender: "copyIcon" } });
!(this.expandedRowKeys && this.expandedRowKeys.length) &&
columns.push({ title: "操作", dataIndex: "operation", scopedSlots: { customRender: "operation" }, fixed: "right", align: "center", width: "180px" });
return columns;
},
filePath() {
return (this.temp.whitelistDirectory || "") + (this.temp.lib || "");
},
@ -652,6 +667,9 @@ export default {
}
return { ...item, javaCopyItemList: javaCopyItemList };
});
this.showJavaCopyItemList = !!this.list.find((item) => {
return !!item.javaCopyItemList;
});
// // ID
// this.list = this.list.map((element) => {
// //element.dataId = element.id;
@ -837,7 +855,7 @@ export default {
this.drawerTitle = `控制台(${this.temp.name})-${copyItem.id}`;
this.drawerConsoleVisible = true;
this.replicaTemp = copyItem;
console.log(record, copyItem);
// console.log(record, copyItem);
},
//
onConsoleClose() {
@ -1235,6 +1253,11 @@ export default {
}
});
},
//
handleLogBack(record, copyItem) {
this.temp = Object.assign({}, record, { copyItem: copyItem });
this.lobbackVisible = true;
},
},
};
</script>

View File

@ -0,0 +1,153 @@
<template>
<div>
<div ref="model-filter" class="filter">
<a-space direction="vertical">
<a-tag>控制台日志只是启动项目输出的日志信息,并非项目日志可以关闭控制台日志备份功能<b>jpom.project.log.auto-backup-to-file: false</b></a-tag>
<a-tag color="orange" v-if="project.logPath">
控制台日志路径: {{ project.logPath }}
<template v-if="project.logSize">
当前日志文件大小{{ project.logSize }}
<a-button @click="handleDownload" type="link" icon="download" size="small"> 导出 </a-button>
</template>
</a-tag>
<a-tag color="orange" v-if="project.logBackPath">控制台日志备份路径: {{ project.logBackPath }}</a-tag>
</a-space>
</div>
<!-- 数据表格 -->
<a-table :data-source="logBackList" :loading="loading" :columns="columns" :pagination="false" bordered :rowKey="(record, index) => index">
<a-tooltip slot="filename" slot-scope="text" placement="topLeft" :title="text">
<span>{{ text }}</span>
</a-tooltip>
<a-tooltip slot="fileSize" slot-scope="text" placement="topLeft" :title="text">
<span>{{ text }}</span>
</a-tooltip>
<template slot="operation" slot-scope="text, record">
<a-space>
<a-button type="primary" @click="handleDownloadLogback(record)">下载</a-button>
<a-button type="danger" @click="handleDelete(record)">删除</a-button>
</a-space>
</template>
</a-table>
</div>
</template>
<script>
import { getLogBackList, deleteProjectLogBackFile, downloadProjectLogBackFile, getProjectLogSize, downloadProjectLogFile } from "@/api/node-project";
export default {
props: {
nodeId: {
type: String,
},
projectId: {
type: String,
},
copyId: {
type: String,
},
},
data() {
return {
loading: true,
project: {},
logBackList: [],
columns: [
{ title: "文件名称", dataIndex: "filename", width: 150, ellipsis: true, scopedSlots: { customRender: "filename" } },
{ title: "修改时间", dataIndex: "modifyTime", width: 150, ellipsis: true, scopedSlots: { customRender: "modifyTime" } },
{ title: "文件大小", dataIndex: "fileSize", width: 100, ellipsis: true, scopedSlots: { customRender: "fileSize" } },
{ title: "操作", dataIndex: "operation", scopedSlots: { customRender: "operation" }, width: 130 },
],
};
},
mounted() {
this.loadFileSize();
this.loadData();
},
methods: {
//
loadFileSize() {
const params = {
nodeId: this.nodeId,
id: this.projectId,
copyId: this.copyId,
};
getProjectLogSize(params).then((res) => {
if (res.code === 200) {
this.project = { ...this.project, logSize: res.data.logSize };
}
});
},
loadData() {
this.loading = true;
const params = {
nodeId: this.nodeId,
id: this.projectId,
copyId: this.copyId,
};
getLogBackList(params).then((res) => {
if (res.code === 200) {
this.logBackList = res.data.array;
this.project = { ...this.project, logPath: res.data.logPath, logBackPath: res.data.logBackPath };
}
this.loading = false;
});
},
//
handleDownload() {
this.$notification.info({
message: "正在下载,请稍等...",
});
//
const params = {
nodeId: this.nodeId,
id: this.projectId,
copyId: this.copyId,
};
// blob
window.open(downloadProjectLogFile(params), "_blank");
},
//
handleDownloadLogback(record) {
this.$notification.info({
message: "正在下载,请稍等...",
});
//
const params = {
nodeId: this.nodeId,
id: this.projectId,
copyId: this.copyId,
key: record.filename,
};
// blob
window.open(downloadProjectLogBackFile(params), "_blank");
},
//
handleDelete(record) {
this.$confirm({
title: "系统提示",
content: "真的要删除文件么?",
okText: "确认",
cancelText: "取消",
onOk: () => {
//
const params = {
nodeId: this.nodeId,
id: this.projectId,
copyId: this.copyId,
name: record.filename,
};
//
deleteProjectLogBackFile(params).then((res) => {
if (res.code === 200) {
this.$notification.success({
message: res.msg,
});
this.handleLogBack();
}
});
},
});
},
},
};
</script>