显示分发结果,节点编辑 ID 回显,加载默认拦截器配置

This commit is contained in:
bwcx_jzy 2021-08-11 14:57:17 +08:00
parent cfad91c274
commit d607bfdaa3
4 changed files with 759 additions and 791 deletions

View File

@ -13,101 +13,101 @@ import io.jpom.service.node.NodeService;
* @date 2019/4/22
*/
public class OutGivingNodeProject extends BaseJsonModel {
private static NodeService nodeService;
private static NodeService nodeService;
private String nodeId;
private String projectId;
private String lastOutGivingTime;
private int status = Status.No.getCode();
private String result;
private String nodeId;
private String projectId;
private String lastOutGivingTime;
private int status = Status.No.getCode();
private String result;
public String getResult() {
return result;
}
public String getResult() {
return result;
}
public void setResult(String result) {
this.result = result;
}
public void setResult(String result) {
this.result = result;
}
public int getStatus() {
return status;
}
public int getStatus() {
return status;
}
public String getStatusMsg() {
return BaseEnum.getDescByCode(Status.class, getStatus());
}
public String getStatusMsg() {
return BaseEnum.getDescByCode(Status.class, getStatus());
}
public void setStatus(int status) {
this.status = status;
}
public void setStatus(int status) {
this.status = status;
}
public String getLastOutGivingTime() {
return StrUtil.emptyToDefault(lastOutGivingTime, StrUtil.DASHED);
}
public String getLastOutGivingTime() {
return StrUtil.emptyToDefault(lastOutGivingTime, StrUtil.DASHED);
}
public void setLastOutGivingTime(String lastOutGivingTime) {
this.lastOutGivingTime = lastOutGivingTime;
}
public void setLastOutGivingTime(String lastOutGivingTime) {
this.lastOutGivingTime = lastOutGivingTime;
}
public String getNodeId() {
return nodeId;
}
public String getNodeId() {
return nodeId;
}
public void setNodeId(String nodeId) {
this.nodeId = nodeId;
}
public void setNodeId(String nodeId) {
this.nodeId = nodeId;
}
public String getProjectId() {
return projectId;
}
public String getProjectId() {
return projectId;
}
public void setProjectId(String projectId) {
this.projectId = projectId;
}
public void setProjectId(String projectId) {
this.projectId = projectId;
}
/**
* 获取节点的数据
*
* @param get 防止自动读取
* @return 实体
*/
public NodeModel getNodeData(boolean get) {
if (nodeService == null) {
nodeService = SpringUtil.getBean(NodeService.class);
}
return nodeService.getItem(this.nodeId);
}
/**
* 获取节点的数据
*
* @param get 防止自动读取
* @return 实体
*/
public NodeModel getNodeData(boolean get) {
if (nodeService == null) {
nodeService = SpringUtil.getBean(NodeService.class);
}
return nodeService.getItem(this.nodeId);
}
/**
* 状态
*/
public enum Status implements BaseEnum {
/**
*
*/
No(0, "未分发"),
Ing(1, "分发中"),
Ok(2, "分发成功"),
Fail(3, "分发失败"),
Cancel(4, "取消分发"),
;
private int code;
private String desc;
/**
* 状态
*/
public enum Status implements BaseEnum {
/**
*
*/
No(0, "未分发"),
Ing(1, "分发中"),
Ok(2, "分发成功"),
Fail(3, "分发失败"),
Cancel(4, "取消分发"),
;
private final int code;
private final String desc;
Status(int code, String desc) {
this.code = code;
this.desc = desc;
}
Status(int code, String desc) {
this.code = code;
this.desc = desc;
}
@Override
public int getCode() {
return code;
}
@Override
public int getCode() {
return code;
}
@Override
public String getDesc() {
return desc;
}
}
@Override
public String getDesc() {
return desc;
}
}
}

View File

@ -24,6 +24,7 @@ banner:
interceptor:
resourceHandler: /**,/static/**,/favicon.ico
resourceLocation: classpath:/dist/,classpath:/static/,classpath:/static/favicon.ico
initPackageName: io.jpom.common.interceptor
# 启动完成自动初始化指定包
preload:
packageName: io.jpom.system.init

View File

@ -6,8 +6,7 @@
<a-button type="primary" @click="handleFilter">刷新</a-button>
</div>
<!-- 表格 :scroll="{x: 740, y: tableHeight - 60}" scroll expandedRowRender 不兼容没法同时使用不然会多出一行数据-->
<a-table :loading="loading" :columns="columns" :data-source="list" bordered rowKey="id" :style="{'max-height': tableHeight + 'px' }"
@expand="expand" :pagination="false">
<a-table :loading="loading" :columns="columns" :data-source="list" bordered rowKey="id" :style="{ 'max-height': tableHeight + 'px' }" @expand="expand" :pagination="false">
<a-tooltip slot="id" slot-scope="text" placement="topLeft" :title="text">
<span>{{ text }}</span>
</a-tooltip>
@ -26,15 +25,25 @@
<a-button type="danger" @click="handleDelete(record)">删除</a-button>
</template>
<!-- 嵌套表格 -->
<a-table slot="expandedRowRender" slot-scope="text" :loading="childLoading" :columns="childColumns" :data-source="text.children"
:pagination="false" :rowKey="(record, index) => record.nodeId + record.projectId + index">
<a-table
slot="expandedRowRender"
slot-scope="text"
:loading="childLoading"
:columns="childColumns"
:data-source="text.children"
:pagination="false"
:rowKey="(record, index) => record.nodeId + record.projectId + index"
>
<a-tooltip slot="nodeId" slot-scope="text" placement="topLeft" :title="text">
<span>{{ text }}</span>
</a-tooltip>
<a-tooltip slot="projectName" slot-scope="text" placement="topLeft" :title="text">
<span>{{ text }}</span>
</a-tooltip>
<a-switch slot="projectStatus" slot-scope="text" :checked="text" checked-children="运行中" un-checked-children="未运行"/>
<a-tooltip slot="outGivingResult" slot-scope="text" placement="topLeft" :title="text">
<span>{{ text }}</span>
</a-tooltip>
<a-switch slot="projectStatus" slot-scope="text" :checked="text" checked-children="运行中" un-checked-children="未运行" />
<template slot="child-operation" slot-scope="text, record">
<a-button :disabled="!record.projectName" type="primary" @click="handleFile(record)">文件</a-button>
<a-button :disabled="!record.projectName" type="primary" @click="handleConsole(record)">控制台</a-button>
@ -45,10 +54,10 @@
<a-modal v-model="linkDispatchVisible" width="600px" title="编辑关联项目" @ok="handleLinkDispatchOk" :maskClosable="false" @cancel="clearDispatchList">
<a-form-model ref="linkDispatchForm" :rules="rules" :model="temp" :label-col="{ span: 4 }" :wrapper-col="{ span: 18 }">
<a-form-model-item label="分发 ID" prop="id">
<a-input v-model="temp.id" :disabled="temp.type === 'edit'" placeholder="创建之后不能修改"/>
<a-input v-model="temp.id" :disabled="temp.type === 'edit'" placeholder="创建之后不能修改" />
</a-form-model-item>
<a-form-model-item label="分发名称" prop="name">
<a-input v-model="temp.name" placeholder="分发名称"/>
<a-input v-model="temp.name" placeholder="分发名称" />
</a-form-model-item>
<!-- <a-form-model-item label="分发项目" prop="projectId">
<a-select v-model="temp.projectId" placeholder="请选择需要分发的项目" @select="selectProject">
@ -67,39 +76,28 @@
</a-form-model-item> -->
<a-form-model-item label="分发节点" prop="name">
<a-list item-layout="horizontal" :data-source="dispatchList">
<a-list-item slot="renderItem" slot-scope="item, index" v-if="item.status" >
<span>节点: </span>
<a-select
placeholder="请选择节点"
notFoundContent="暂无节点信息"
style="width: 130px"
:defaultValue="item.index"
@change="value => handleNodeListChange(value, index)"
:disabled="item.index===''?false:!nodeNameList[item.index].openStatus"
>
<a-select-option :value="index"
v-for="(nodeList,index) in nodeNameList"
:key="nodeList.id" :disabled="!nodeList.openStatus"
<a-list-item slot="renderItem" slot-scope="item, index" v-if="item.status">
<span>节点: </span>
<a-select
placeholder="请选择节点"
notFoundContent="暂无节点信息"
style="width: 130px"
:defaultValue="item.index"
@change="(value) => handleNodeListChange(value, index)"
:disabled="item.index === '' ? false : !nodeNameList[item.index].openStatus"
>
{{ nodeList.name }}
</a-select-option>
</a-select>
<span>项目: </span>
<a-select style="width: 130px"
placeholder="请选择项目"
:defaultValue="item.projectId"
notFoundContent="暂无项目信息,重新其他项目"
@change="value =>handleProjectChange(value,index)"
>
<a-select-option :value="project.id"
v-for="(project) in item.project"
:key="project.id"
>
{{ project.name }}
</a-select-option>
</a-select>
<a-button type="danger" @click="delDispachList(index)" icon="delete"></a-button>
</a-list-item>
<a-select-option :value="index" v-for="(nodeList, index) in nodeNameList" :key="nodeList.id" :disabled="!nodeList.openStatus">
{{ nodeList.name }}
</a-select-option>
</a-select>
<span>项目: </span>
<a-select style="width: 130px" placeholder="请选择项目" :defaultValue="item.projectId" notFoundContent="暂无项目信息,重新其他项目" @change="(value) => handleProjectChange(value, index)">
<a-select-option :value="project.id" v-for="project in item.project" :key="project.id">
{{ project.name }}
</a-select-option>
</a-select>
<a-button type="danger" @click="delDispachList(index)" icon="delete"></a-button>
</a-list-item>
</a-list>
<a-button type="primary" @click="addDispachList">添加</a-button>
</a-form-model-item>
@ -117,10 +115,10 @@
<a-modal v-model="editDispatchVisible" width="600px" title="创建分发项目" @ok="handleEditDispatchOk" :maskClosable="false">
<a-form-model ref="editDispatchForm" :rules="rules" :model="temp" :label-col="{ span: 6 }" :wrapper-col="{ span: 18 }">
<a-form-model-item label="项目 ID" prop="id">
<a-input v-model="temp.id" :disabled="temp.type === 'edit'" placeholder="创建之后不能修改"/>
<a-input v-model="temp.id" :disabled="temp.type === 'edit'" placeholder="创建之后不能修改" />
</a-form-model-item>
<a-form-model-item label="项目名称" prop="name">
<a-input v-model="temp.name" placeholder="项目名称"/>
<a-input v-model="temp.name" placeholder="项目名称" />
</a-form-model-item>
<a-form-model-item label="运行方式" prop="runMode">
<a-select v-model="temp.runMode" placeholder="请选择运行方式">
@ -128,7 +126,7 @@
</a-select>
</a-form-model-item>
<a-form-model-item label="Main Class" prop="mainClass" v-show="temp.runMode !== 'Jar'">
<a-input v-model="temp.mainClass" placeholder="程序运行的 main 类(jar 模式运行可以不填)"/>
<a-input v-model="temp.mainClass" placeholder="程序运行的 main 类(jar 模式运行可以不填)" />
</a-form-model-item>
<a-form-model-item label="项目白名单路径" prop="whitelistDirectory" class="jpom-project-whitelist">
<a-select v-model="temp.whitelistDirectory" placeholder="请选择项目白名单路径">
@ -136,12 +134,12 @@
</a-select>
</a-form-model-item>
<a-form-model-item label="项目文件夹" prop="lib">
<a-input v-model="temp.lib" placeholder="项目存储的文件夹jar 包存放的文件夹"/>
<a-input v-model="temp.lib" placeholder="项目存储的文件夹jar 包存放的文件夹" />
</a-form-model-item>
<a-form-model-item label="日志目录">
<a-select v-model="temp.logPath" placeholder="请选择项目白名单路径">
<a-select-option v-for="access in accessList" :key="access">{{ access }}</a-select-option>
</a-select>
<a-select v-model="temp.logPath" placeholder="请选择项目白名单路径">
<a-select-option v-for="access in accessList" :key="access">{{ access }}</a-select-option>
</a-select>
</a-form-model-item>
<a-form-model-item label="分发后操作" prop="afterOpt">
<a-select v-model="temp.afterOpt" placeholder="请选择发布后操作">
@ -160,28 +158,28 @@
<a-collapse>
<a-collapse-panel v-for="nodeId in temp.nodeIdList" :key="nodeId" :header="nodeId">
<a-form-model-item label="WebHooks" prop="token">
<a-input v-model="temp[`${nodeId}_token`]" placeholder="关闭程序时自动请求,非必填GET请求"/>
<a-input v-model="temp[`${nodeId}_token`]" placeholder="关闭程序时自动请求,非必填GET请求" />
</a-form-model-item>
<a-form-model-item label="JVM 参数" prop="jvm">
<a-textarea v-model="temp[`${nodeId}_jvm`]" :auto-size="{ minRows: 3, maxRows: 3 }" placeholder="jvm参数,非必填.如:-Xms512m -Xmx512m"/>
<a-textarea v-model="temp[`${nodeId}_jvm`]" :auto-size="{ minRows: 3, maxRows: 3 }" placeholder="jvm参数,非必填.如:-Xms512m -Xmx512m" />
</a-form-model-item>
<a-form-model-item label="args 参数" prop="args">
<a-textarea v-model="temp[`${nodeId}_args`]" :auto-size="{ minRows: 3, maxRows: 3 }" placeholder="Main 函数 args 参数,非必填. 如:--service.port=8080"/>
<a-textarea v-model="temp[`${nodeId}_args`]" :auto-size="{ minRows: 3, maxRows: 3 }" placeholder="Main 函数 args 参数,非必填. 如:--service.port=8080" />
</a-form-model-item>
<!-- 副本信息 -->
<a-row v-for="replica in temp[`${nodeId}_javaCopyItemList`]" :key="replica.id">
<a-form-model-item :label="`副本 ${replica.id} JVM 参数`" prop="jvm">
<a-textarea v-model="replica.jvm" :auto-size="{ minRows: 3, maxRows: 3 }" class="replica-area" placeholder="jvm参数,非必填.如:-Xms512m -Xmx512m"/>
<a-textarea v-model="replica.jvm" :auto-size="{ minRows: 3, maxRows: 3 }" class="replica-area" placeholder="jvm参数,非必填.如:-Xms512m -Xmx512m" />
</a-form-model-item>
<a-form-model-item :label="`副本 ${replica.id} args 参数`" prop="args">
<a-textarea v-model="replica.args" :auto-size="{ minRows: 3, maxRows: 3 }" class="replica-area" placeholder="Main 函数 args 参数,非必填. 如:--service.port=8080"/>
<a-textarea v-model="replica.args" :auto-size="{ minRows: 3, maxRows: 3 }" class="replica-area" placeholder="Main 函数 args 参数,非必填. 如:--service.port=8080" />
</a-form-model-item>
<a-tooltip placement="topLeft" title="已经添加成功的副本需要在副本管理页面去删除" class="replica-btn-del">
<a-button :disabled="!replica.deleteAble" type="danger" @click="handleDeleteReplica(nodeId, replica)">删除</a-button>
</a-tooltip>
</a-row>
<!-- 添加副本 -->
<a-form-model-item label="操作" >
<a-form-model-item label="操作">
<a-button type="primary" @click="handleAddReplica(nodeId)">添加副本</a-button>
</a-form-model-item>
</a-collapse-panel>
@ -189,7 +187,7 @@
</a-form-model>
</a-modal>
<!-- 分发项目 -->
<a-modal v-model="dispatchVisible" width="600px" :title="'分发项目----'+temp.name" @ok="handleDispatchOk" :maskClosable="false" >
<a-modal v-model="dispatchVisible" width="600px" :title="'分发项目----' + temp.name" @ok="handleDispatchOk" :maskClosable="false">
<a-form-model ref="dispatchForm" :rules="rules" :model="temp" :label-col="{ span: 6 }" :wrapper-col="{ span: 18 }">
<a-form-model-item label="选择分发文件" prop="clearOld">
<a-upload :file-list="fileList" :remove="handleRemove" :before-upload="beforeUpload" accept=".zip,.tar,.gz,.bz2">
@ -197,7 +195,7 @@
</a-upload>
</a-form-model-item>
<a-form-model-item label="清空发布" prop="clearOld">
<a-switch v-model="temp.clearOld" checked-children="" un-checked-children=""/>
<a-switch v-model="temp.clearOld" checked-children="" un-checked-children="" />
</a-form-model-item>
<a-form-model-item label="分发后操作" prop="afterOpt">
<a-select v-model="temp.afterOpt" placeholder="请选择发布后操作">
@ -210,104 +208,89 @@
</a-form-model>
</a-modal>
<!-- 项目文件组件 -->
<a-drawer :title="drawerTitle" placement="right" width="85vw"
:visible="drawerFileVisible" @close="onFileClose">
<a-drawer :title="drawerTitle" placement="right" width="85vw" :visible="drawerFileVisible" @close="onFileClose">
<file v-if="drawerFileVisible" :nodeId="temp.nodeId" :projectId="temp.projectId" />
</a-drawer>
<!-- 项目控制台组件 -->
<a-drawer :title="drawerTitle" placement="right" width="85vw"
:visible="drawerConsoleVisible" @close="onConsoleClose">
<a-drawer :title="drawerTitle" placement="right" width="85vw" :visible="drawerConsoleVisible" @close="onConsoleClose">
<console v-if="drawerConsoleVisible" :nodeId="temp.nodeId" :projectId="temp.projectId" />
</a-drawer>
</div>
</template>
<script>
import { mapGetters } from 'vuex';
import File from '../node/node-layout/project/project-file';
import Console from '../node/node-layout/project/project-console';
import { getDishPatchList, getDispatchProject, getReqId, editDispatch, editDispatchProject, uploadDispatchFile, getDispatchWhiteList, deleteDisPatch } from '../../api/dispatch';
import { getNodeProjectList } from '../../api/node';
import { getProjectData } from '../../api/node-project';
import { mapGetters } from "vuex";
import File from "../node/node-layout/project/project-file";
import Console from "../node/node-layout/project/project-console";
import { getDishPatchList, getDispatchProject, getReqId, editDispatch, editDispatchProject, uploadDispatchFile, getDispatchWhiteList, deleteDisPatch } from "../../api/dispatch";
import { getNodeProjectList } from "../../api/node";
import { getProjectData } from "../../api/node-project";
export default {
components: {
File,
Console
Console,
},
data() {
return {
loading: false,
childLoading: false,
tableHeight: '70vh',
tableHeight: "70vh",
list: [],
accessList: [],
nodeList: [],
projectList: [],
nodeProjectMap: {},
targetKeys: [],
reqId: '',
reqId: "",
temp: {},
fileList: [],
runModeList: [
'ClassPath',
'Jar',
'JarWar',
'JavaExtDirsCp',
"ClassPath",
"Jar",
"JarWar",
"JavaExtDirsCp",
// 'File'
],
list_expanded: {},
linkDispatchVisible: false,
editDispatchVisible: false,
dispatchVisible: false,
drawerTitle: '',
drawerTitle: "",
drawerFileVisible: false,
drawerConsoleVisible: false,
nodeNameList:[],
dispatchList:[],
nodeNameList: [],
dispatchList: [],
columns: [
{title: '分发 ID', dataIndex: 'id', width: 100, ellipsis: true, scopedSlots: {customRender: 'id'}},
{title: '分发名称', dataIndex: 'name', width: 150, ellipsis: true, scopedSlots: {customRender: 'name'}},
{title: '类型', dataIndex: 'outGivingProject', width: 100, ellipsis: true, scopedSlots: {customRender: 'outGivingProject'}},
{title: '操作', dataIndex: 'operation', scopedSlots: {customRender: 'operation'}, width: 380, align: 'left'}
{ title: "分发 ID", dataIndex: "id", width: 100, ellipsis: true, scopedSlots: { customRender: "id" } },
{ title: "分发名称", dataIndex: "name", width: 150, ellipsis: true, scopedSlots: { customRender: "name" } },
{ title: "类型", dataIndex: "outGivingProject", width: 100, ellipsis: true, scopedSlots: { customRender: "outGivingProject" } },
{ title: "操作", dataIndex: "operation", scopedSlots: { customRender: "operation" }, width: 380, align: "left" },
],
childColumns: [
{title: '节点名称', dataIndex: 'nodeId', width: 100, ellipsis: true, scopedSlots: {customRender: 'nodeId'}},
{title: '项目名称', dataIndex: 'projectName', width: 120, ellipsis: true, scopedSlots: {customRender: 'projectName'}},
{title: '项目状态', dataIndex: 'projectStatus', width: 150, ellipsis: true, scopedSlots: {customRender: 'projectStatus'}},
{title: '分发状态', dataIndex: 'outGivingStatus', width: 180},
{title: '最后分发时间', dataIndex: 'lastTime', width: 180, ellipsis: true, scopedSlots: {customRender: 'lastTime'}},
{title: '操作', dataIndex: 'child-operation', scopedSlots: {customRender: 'child-operation'}, width: 200, align: 'left'}
{ title: "节点名称", dataIndex: "nodeId", width: 100, ellipsis: true, scopedSlots: { customRender: "nodeId" } },
{ title: "项目名称", dataIndex: "projectName", width: 120, ellipsis: true, scopedSlots: { customRender: "projectName" } },
{ title: "项目状态", dataIndex: "projectStatus", width: 120, ellipsis: true, scopedSlots: { customRender: "projectStatus" } },
{ title: "分发状态", dataIndex: "outGivingStatus", width: 120 },
{ title: "分发结果", dataIndex: "outGivingResult", width: 180, ellipsis: true, scopedSlots: { customRender: "outGivingResult" } },
{ title: "最后分发时间", dataIndex: "lastTime", width: 180, ellipsis: true, scopedSlots: { customRender: "lastTime" } },
{ title: "操作", dataIndex: "child-operation", scopedSlots: { customRender: "child-operation" }, width: 200, align: "left" },
],
rules: {
id: [
{ required: true, message: 'Please input dispatch id', trigger: 'blur' }
],
name: [
{ required: true, message: 'Please input dispatch name', trigger: 'blur' }
],
projectId: [
{ required: true, message: 'Please select project', trigger: 'blur' }
],
runMode: [
{ required: true, message: 'Please select project runMode', trigger: 'blur' }
],
whitelistDirectory: [
{ required: true, message: 'Please select project access path', trigger: 'blur' }
],
lib: [
{ required: true, message: 'Please input project lib', trigger: 'blur' }
]
}
}
id: [{ required: true, message: "Please input dispatch id", trigger: "blur" }],
name: [{ required: true, message: "Please input dispatch name", trigger: "blur" }],
projectId: [{ required: true, message: "Please select project", trigger: "blur" }],
runMode: [{ required: true, message: "Please select project runMode", trigger: "blur" }],
whitelistDirectory: [{ required: true, message: "Please select project access path", trigger: "blur" }],
lib: [{ required: true, message: "Please input project lib", trigger: "blur" }],
},
};
},
computed: {
...mapGetters([
'getGuideFlag'
])
...mapGetters(["getGuideFlag"]),
},
watch: {
getGuideFlag() {
this.introGuide();
}
},
},
created() {
this.calcTableHeight();
@ -317,14 +300,18 @@ export default {
//
introGuide() {
if (this.getGuideFlag) {
this.$introJs().setOptions({
hidePrev: true,
steps: [{
title: 'Jpom 导航助手',
element: document.querySelector('.jpom-project-whitelist'),
intro: '项目白名单需要在侧边栏菜单<b>分发白名单</b>组件里面去设置'
}]
}).start();
this.$introJs()
.setOptions({
hidePrev: true,
steps: [
{
title: "Jpom 导航助手",
element: document.querySelector(".jpom-project-whitelist"),
intro: "项目白名单需要在侧边栏菜单<b>分发白名单</b>组件里面去设置",
},
],
})
.start();
return false;
}
this.$introJs().exit();
@ -332,41 +319,41 @@ export default {
//
calcTableHeight() {
this.$nextTick(() => {
this.tableHeight = window.innerHeight - this.$refs['filter'].clientHeight - 135;
})
this.tableHeight = window.innerHeight - this.$refs["filter"].clientHeight - 135;
});
},
//
loadData() {
this.list = [];
this.loading = true;
this.childLoading = false;
getDishPatchList().then(res => {
getDishPatchList().then((res) => {
if (res.code === 200) {
this.list = res.data;
}
this.loading = false;
})
});
},
// reqId
loadReqId() {
getReqId().then(res => {
getReqId().then((res) => {
if (res.code === 200) {
this.reqId = res.data;
}
})
});
},
//
loadAccesList() {
getDispatchWhiteList().then(res => {
getDispatchWhiteList().then((res) => {
if (res.code === 200) {
this.accessList = res.data;
}
})
});
},
//
expand(expanded, record) {
this.list_expanded[record.id] = expanded;
this.list_expanded= {...this.list_expanded};
this.list_expanded = { ...this.list_expanded };
if (expanded) {
this.handleReload(record);
}
@ -378,62 +365,62 @@ export default {
},
//
handleLink() {
this.$refs['linkDispatchForm'] && this.$refs['linkDispatchForm'].resetFields()
this.$refs["linkDispatchForm"] && this.$refs["linkDispatchForm"].resetFields();
this.temp = {
type: 'add',
id: '',
name: '',
projectId: ''
type: "add",
id: "",
name: "",
projectId: "",
};
this.loadReqId();
this.linkDispatchVisible = true;
},
//
handleEditDispatch(record) {
this.$nextTick(() => {
this.$refs['linkDispatchForm'] && this.$refs['linkDispatchForm'].resetFields();
//
record.outGivingNodeProjectList.forEach(ele => {
let index = '';
let projects = [];
this.nodeNameList.forEach((item,idx) =>{
if (item.id === ele.nodeId){
index = idx;
projects = item.projects;
item.openStatus = false;
}
})
this.temp[`node_${ele.nodeId}`] = ele.projectId;
this.dispatchList.push({
nodeId: ele.nodeId,
projectId: ele.projectId,
index: index,
project: projects,
status: true
});
})
this.temp.type = 'edit';
this.temp.projectId = record.projectId;
this.temp.name = record.name;
this.temp.afterOpt = record.afterOpt;
this.temp.id = record.id;
this.loadReqId();
this.linkDispatchVisible = true;
})
this.$nextTick(() => {
this.$refs["linkDispatchForm"] && this.$refs["linkDispatchForm"].resetFields();
//
record.outGivingNodeProjectList.forEach((ele) => {
let index = "";
let projects = [];
this.nodeNameList.forEach((item, idx) => {
if (item.id === ele.nodeId) {
index = idx;
projects = item.projects;
item.openStatus = false;
}
});
this.temp[`node_${ele.nodeId}`] = ele.projectId;
this.dispatchList.push({
nodeId: ele.nodeId,
projectId: ele.projectId,
index: index,
project: projects,
status: true,
});
});
this.temp.type = "edit";
this.temp.projectId = record.projectId;
this.temp.name = record.name;
this.temp.afterOpt = record.afterOpt;
this.temp.id = record.id;
this.loadReqId();
this.linkDispatchVisible = true;
});
},
//
selectProject(value) {
this.targetKeys = [];
this.nodeList.forEach(node => {
this.nodeList.forEach((node) => {
node.disabled = true;
})
this.nodeProjectMap[value].forEach(nodeId => {
this.nodeList.forEach(node => {
});
this.nodeProjectMap[value].forEach((nodeId) => {
this.nodeList.forEach((node) => {
if (node.key === nodeId) {
node.disabled = false;
}
})
})
});
});
},
// 穿
filterOption(inputValue, option) {
@ -446,124 +433,124 @@ export default {
//
handleLinkDispatchOk() {
//
this.$refs['linkDispatchForm'].validate((valid) => {
this.$refs["linkDispatchForm"].validate((valid) => {
if (!valid) {
return false;
}
// reqId
this.temp.reqId = this.reqId;
//
editDispatch(this.temp).then(res => {
editDispatch(this.temp).then((res) => {
if (res.code === 200) {
//
this.$notification.success({
message: res.msg,
duration: 2
duration: 2,
});
this.targetKeys = [];
this.$refs['linkDispatchForm'].resetFields();
this.$refs["linkDispatchForm"].resetFields();
this.linkDispatchVisible = false;
this.clearDispatchList();
this.handleFilter();
} else {
this.targetKeys = [];
}
})
})
});
});
},
//
handleAdd() {
this.temp = {
type: 'add',
id: '',
name: '',
afterOpt: '',
runMode: '',
mainClass: '',
javaExtDirsCp: '',
whitelistDirectory: '',
lib: '',
nodeIdList: []
type: "add",
id: "",
name: "",
afterOpt: "",
runMode: "",
mainClass: "",
javaExtDirsCp: "",
whitelistDirectory: "",
lib: "",
nodeIdList: [],
};
// javaCopyItemList
this.nodeList.forEach(node => {
this.nodeList.forEach((node) => {
this.temp[`${node.key}_javaCopyItemList`] = [];
})
});
this.loadAccesList();
this.loadReqId();
this.editDispatchVisible = true;
this.$nextTick(() => {
this.$refs['editDispatchForm'].resetFields();
this.$refs["editDispatchForm"].resetFields();
setTimeout(() => {
this.introGuide();
}, 500);
})
});
},
//
handleEditDispatchProject(record) {
this.$nextTick(() => {
this.$refs['editDispatchForm'] && this.$refs['editDispatchForm'].resetFields();
//
this.temp = {};
record.outGivingNodeProjectList.forEach(ele => {
const params = {
id: ele.projectId,
nodeId: ele.nodeId
}
getProjectData(params).then(res => {
if (res.code === 200) {
// temp.id
if (!this.temp.id) {
this.temp = {
id: res.data.id,
name: res.data.name,
type: 'edit',
afterOpt: res.data.afterOpt,
runMode: res.data.runMode,
mainClass: res.data.mainClass,
javaExtDirsCp: res.data.javaExtDirsCp,
whitelistDirectory: res.data.whitelistDirectory,
lib: res.data.lib,
nodeIdList: []
}
}
// nodeIdList
this.temp.nodeIdList.push(ele.nodeId);
// jvm token args
this.temp[`${ele.nodeId}_jvm`] = res.data.jvm || '';
this.temp[`${ele.nodeId}_token`] = res.data.token || '';
this.temp[`${ele.nodeId}_args`] = res.data.args || '';
// javaCopyItemList
this.temp[`${ele.nodeId}_javaCopyItemList`] = res.data.javaCopyItemList || [];
}
})
})
//
this.loadAccesList();
this.loadReqId();
this.editDispatchVisible = true;
})
this.$nextTick(() => {
this.$refs["editDispatchForm"] && this.$refs["editDispatchForm"].resetFields();
//
this.temp = {};
record.outGivingNodeProjectList.forEach((ele) => {
const params = {
id: ele.projectId,
nodeId: ele.nodeId,
};
getProjectData(params).then((res) => {
if (res.code === 200) {
// temp.id
if (!this.temp.id) {
this.temp = {
id: res.data.id,
name: res.data.name,
type: "edit",
afterOpt: res.data.afterOpt,
runMode: res.data.runMode,
mainClass: res.data.mainClass,
javaExtDirsCp: res.data.javaExtDirsCp,
whitelistDirectory: res.data.whitelistDirectory,
lib: res.data.lib,
nodeIdList: [],
};
}
// nodeIdList
this.temp.nodeIdList.push(ele.nodeId);
// jvm token args
this.temp[`${ele.nodeId}_jvm`] = res.data.jvm || "";
this.temp[`${ele.nodeId}_token`] = res.data.token || "";
this.temp[`${ele.nodeId}_args`] = res.data.args || "";
// javaCopyItemList
this.temp[`${ele.nodeId}_javaCopyItemList`] = res.data.javaCopyItemList || [];
}
});
});
//
this.loadAccesList();
this.loadReqId();
this.editDispatchVisible = true;
});
},
//
handleAddReplica(nodeId) {
const $chars = 'ABCDEFGHJKMNPQRSTWXYZ0123456789';
const $chars = "ABCDEFGHJKMNPQRSTWXYZ0123456789";
/****默认去掉了容易混淆的字符oOLl,9gq,Vv,Uu,I1****/
const maxPos = $chars.length;
let repliccaId = '';
let repliccaId = "";
for (let i = 0; i < 2; i++) {
repliccaId += $chars.charAt(Math.floor(Math.random() * maxPos));
}
this.temp[`${nodeId}_javaCopyItemList`].push({
id: repliccaId,
jvm: '',
args: '',
deleteAble: true
})
this.temp = {...this.temp};
jvm: "",
args: "",
deleteAble: true,
});
this.temp = { ...this.temp };
},
//
handleDeleteReplica(nodeId, reeplica) {
const index = this.temp[`${nodeId}_javaCopyItemList`].findIndex(element => element.id === reeplica.id);
const index = this.temp[`${nodeId}_javaCopyItemList`].findIndex((element) => element.id === reeplica.id);
const newList = this.temp[`${nodeId}_javaCopyItemList`].slice();
newList.splice(index, 1);
this.temp[`${nodeId}_javaCopyItemList`] = newList;
@ -571,57 +558,57 @@ export default {
//
handleEditDispatchOk() {
//
this.$refs['editDispatchForm'].validate((valid) => {
this.$refs["editDispatchForm"].validate((valid) => {
if (!valid) {
return false;
}
//
if (this.temp.nodeIdList.length < 2) {
this.$notification.warn({
message: '请至少选择 2 个节点',
duration: 2
message: "请至少选择 2 个节点",
duration: 2,
});
return false;
}
// reqId
this.temp.reqId = this.reqId;
//
this.temp.nodeIdList.forEach(key => {
this.temp.nodeIdList.forEach((key) => {
this.temp[`add_${key}`] = key;
//
this.temp[`${key}_javaCopyIds`] = '';
this.temp[`${key}_javaCopyItemList`].forEach(element => {
this.temp[`${key}_javaCopyIds`] = "";
this.temp[`${key}_javaCopyItemList`].forEach((element) => {
this.temp[`${key}_javaCopyIds`] += `${element.id},`;
this.temp[`${key}_jvm_${element.id}`] = element.jvm;
this.temp[`${key}_args_${element.id}`] = element.args;
})
});
// ,
this.temp[`${key}_javaCopyIds`] = this.temp[`${key}_javaCopyIds`].substring(0, this.temp[`${key}_javaCopyIds`].length-1);
})
this.temp[`${key}_javaCopyIds`] = this.temp[`${key}_javaCopyIds`].substring(0, this.temp[`${key}_javaCopyIds`].length - 1);
});
//
editDispatchProject(this.temp).then(res => {
editDispatchProject(this.temp).then((res) => {
if (res.code === 200) {
//
this.$notification.success({
message: res.msg,
duration: 2
duration: 2,
});
this.$refs['editDispatchForm'].resetFields();
this.$refs["editDispatchForm"].resetFields();
this.editDispatchVisible = false;
this.handleFilter();
}
})
})
});
});
},
//
handleReload(record) {
this.childLoading = true;
getDispatchProject(record.id).then(res => {
getDispatchProject(record.id).then((res) => {
if (res.code === 200) {
record.children = res.data;
}
this.childLoading = false;
})
});
},
//
handleDispatch(record) {
@ -644,66 +631,66 @@ export default {
//
handleDispatchOk() {
//
this.$refs['dispatchForm'].validate((valid) => {
this.$refs["dispatchForm"].validate((valid) => {
if (!valid) {
return false;
}
//
if (this.fileList.length === 0) {
this.$notification.error({
message: '请选择文件',
duration: 2
message: "请选择文件",
duration: 2,
});
return false;
}
//
const key='upload';
const key = "upload";
const formData = new FormData();
this.$message.loading({content:'正在上传文件...',key,duration: 0});
formData.append('file', this.fileList[0]);
formData.append('id', this.temp.id);
formData.append('afterOpt', this.temp.afterOpt);
formData.append('clearOld', this.temp.clearOld);
uploadDispatchFile(formData).then(res => {
this.$message.loading({ content: "正在上传文件...", key, duration: 0 });
formData.append("file", this.fileList[0]);
formData.append("id", this.temp.id);
formData.append("afterOpt", this.temp.afterOpt);
formData.append("clearOld", this.temp.clearOld);
uploadDispatchFile(formData).then((res) => {
if (res.code === 200) {
this.$notification.success({
message: res.msg,
duration: 2
duration: 2,
});
this.$message.success({content:'上传成功,开始分发!',key,duration: 2 });
this.$refs['dispatchForm'].resetFields();
this.$message.success({ content: "上传成功,开始分发!", key, duration: 2 });
this.$refs["dispatchForm"].resetFields();
this.fileList = [];
this.loadData();
this.dispatchVisible = false;
}
})
})
});
});
},
//
handleDelete(record) {
this.$confirm({
title: '系统提示',
content: '真的要删除分发信息么?',
okText: '确认',
cancelText: '取消',
title: "系统提示",
content: "真的要删除分发信息么?",
okText: "确认",
cancelText: "取消",
onOk: () => {
//
deleteDisPatch(record.id).then((res) => {
if (res.code === 200) {
this.$notification.success({
message: res.msg,
duration: 2
duration: 2,
});
this.handleFilter();
}
})
}
});
},
});
},
//
handleFile(record) {
this.temp = Object.assign(record);
this.drawerTitle = `文件管理(${this.temp.projectId})`
this.drawerTitle = `文件管理(${this.temp.projectId})`;
this.drawerFileVisible = true;
},
//
@ -723,46 +710,43 @@ export default {
//
loadNodeList() {
this.nodeList = [];
getNodeProjectList().then(res => {
getNodeProjectList().then((res) => {
if (res.code === 200) {
this.nodeNameList = res.data;
//
res.data.forEach(node => {
res.data.forEach((node) => {
const nodeItem = {
title: node.name,
key: node.id,
disabled: true
}
node.projects.forEach(project => {
disabled: true,
};
node.projects.forEach((project) => {
// ID
const index = this.projectList.findIndex(p => p.id === project.id);
const index = this.projectList.findIndex((p) => p.id === project.id);
if (index === -1) {
const projectItem = {
name: `${project.name} ( ${project.id} )`,
id: project.id
}
id: project.id,
};
this.projectList.push(projectItem);
}
//
if (!this.nodeProjectMap[`${project.id}`]) {
this.nodeProjectMap[`${project.id}`] = [
...this.nodeProjectMap[`${project.id}`] || [],
node.id
];
this.nodeProjectMap[`${project.id}`] = [...(this.nodeProjectMap[`${project.id}`] || []), node.id];
} else {
const tempIndex = this.nodeProjectMap[`${project.id}`].findIndex(nodeId => node.id === nodeId);
const tempIndex = this.nodeProjectMap[`${project.id}`].findIndex((nodeId) => node.id === nodeId);
if (tempIndex === -1) {
this.nodeProjectMap[`${project.id}`].push(node.id);
}
}
})
});
this.nodeList.push(nodeItem);
})
});
}
})
});
},
//
handleNodeListChange(value,index){
handleNodeListChange(value, index) {
//this.projectNameList = this.nodeNameList[value].projects;
this.nodeNameList[value].openStatus = false;
this.dispatchList[index].project = this.nodeNameList[value].projects;
@ -770,17 +754,17 @@ export default {
this.dispatchList[index].index = value;
},
//
handleProjectChange(value,index){
handleProjectChange(value, index) {
this.dispatchList[index].projectId = value;
this.temp["node_"+this.dispatchList[index].nodeId] = value;
this.temp["node_" + this.dispatchList[index].nodeId] = value;
},
//
addDispachList(){
this.dispatchList.push({nodeId: "", projectId: "", index: "", project: [], status: true});
addDispachList() {
this.dispatchList.push({ nodeId: "", projectId: "", index: "", project: [], status: true });
},
//
delDispachList(value){
if (this.dispatchList[value].index !== '') {
delDispachList(value) {
if (this.dispatchList[value].index !== "") {
this.nodeNameList[this.dispatchList[value].index].openStatus = true;
}
//this.dispatchList.splice(value,1);
@ -788,14 +772,14 @@ export default {
this.dispatchList[value].status = false;
},
//
clearDispatchList(){
clearDispatchList() {
this.dispatchList = [];
for (let node in this.nodeNameList) {
this.nodeNameList[node].openStatus = true;
}
}
}
}
},
},
};
</script>
<style scoped>
.filter {

View File

@ -1,434 +1,417 @@
<template>
<div>
<div ref="filter" class="filter">
<a-select v-model="listQuery.group" allowClear placeholder="请选择分组"
class="filter-item" @change="handleFilter">
<a-select-option v-for="group in groupList" :key="group">{{ group }}</a-select-option>
</a-select>
<a-button type="primary" @click="handleFilter">搜索</a-button>
<a-button type="primary" @click="handleAdd">新增</a-button>
<a-button type="primary" @click="loadData">刷新</a-button>
</div>
<!-- 表格 :scroll="{ x: 1070, y: tableHeight -60 }" scroll expandedRowRender 不兼容没法同时使用不然会多出一行数据-->
<a-table :loading="loading" :columns="columns" :data-source="list" :style="{'max-height': tableHeight + 'px' }" bordered rowKey="id" @expand="expand" :pagination="false">
<a-tooltip slot="group" slot-scope="text" placement="topLeft" :title="text">
<span>{{ text }}</span>
</a-tooltip>
<a-tooltip slot="url" slot-scope="text" placement="topLeft" :title="text">
<span>{{ text }}</span>
</a-tooltip>
<template slot="operation" slot-scope="text, record">
<a-button type="primary" @click="handleTerminal(record)" :disabled="!record.sshId">终端</a-button>
<a-button type="primary" @click="handleNode(record)" :disabled="record.openStatus === false">节点管理</a-button>
<a-button type="primary" @click="handleEdit(record)">编辑</a-button>
<a-button type="danger" @click="handleDelete(record)">删除</a-button>
</template>
<!-- 嵌套表格 -->
<a-table slot="expandedRowRender" slot-scope="text" :loading="childLoading" :columns="childColumns" :data-source="text.children" :pagination="false" :rowKey="(record, index) => text.id + index">
<a-tooltip slot="osName" slot-scope="text" placement="topLeft" :title="text">
<span>{{ text }}</span>
</a-tooltip>
<a-tooltip slot="javaVersion" slot-scope="text" placement="topLeft" :title="text">
<span>{{ text }}</span>
</a-tooltip>
<a-tooltip slot="runTime" slot-scope="text" placement="topLeft" :title="text">
<span>{{ text }}</span>
</a-tooltip>
</a-table>
</a-table>
<!-- 编辑区 -->
<a-modal v-model="editNodeVisible" title="编辑节点" @ok="handleEditNodeOk" :maskClosable="false">
<a-form-model ref="editNodeForm" :rules="rules" :model="temp" :label-col="{ span: 6 }" :wrapper-col="{ span: 14 }">
<a-form-model-item label="节点 ID" prop="id">
<a-input v-model="temp.id" :disabled="temp.id" placeholder="创建之后不能修改"/>
</a-form-model-item>
<a-form-model-item label="节点名称" prop="name">
<a-input v-model="temp.name" placeholder="节点名称"/>
</a-form-model-item>
<a-form-model-item label="分组名称" prop="group">
<a-row>
<a-col :span="18">
<a-select v-model="temp.group" placeholder="可手动输入">
<a-select-option v-for="group in groupList" :key="group">{{ group }}</a-select-option>
</a-select>
</a-col>
<a-col :span="6">
<a-popover v-model="addGroupvisible" title="添加分组" trigger="click">
<template slot="content">
<a-row>
<a-col :span="18">
<a-input v-model="temp.tempGroup" placeholder="分组名称"/>
</a-col>
<a-col :span="6">
<a-button type="primary" @click="handleAddGroup">确认</a-button>
</a-col>
</a-row>
</template>
<a-button type="primary" class="btn-add">添加分组</a-button>
</a-popover>
</a-col>
</a-row>
</a-form-model-item>
<a-form-model-item label="绑定 SSH " prop="sshId">
<a-select v-model="temp.sshId" placeholder="节点协议">
<a-select-option v-for="ssh in sshList" :key="ssh.id" :disabled="ssh.disabled">{{ ssh.name }}</a-select-option>
</a-select>
</a-form-model-item>
<a-form-model-item label="监控周期" prop="cycle">
<a-select v-model="temp.cycle" defaultValue="0" placeholder="监控周期">
<a-select-option :key="0">不开启</a-select-option>
<a-select-option :key="-30">30 </a-select-option>
<a-select-option :key="1">1 分钟</a-select-option>
<a-select-option :key="5">5 分钟</a-select-option>
<a-select-option :key="10">10 分钟</a-select-option>
<a-select-option :key="30">30 分钟</a-select-option>
</a-select>
</a-form-model-item>
<div>
<div ref="filter" class="filter">
<a-select v-model="listQuery.group" allowClear placeholder="请选择分组" class="filter-item" @change="handleFilter">
<a-select-option v-for="group in groupList" :key="group">{{ group }}</a-select-option>
</a-select>
<a-button type="primary" @click="handleFilter">搜索</a-button>
<a-button type="primary" @click="handleAdd">新增</a-button>
<a-button type="primary" @click="loadData">刷新</a-button>
</div>
<!-- 表格 :scroll="{ x: 1070, y: tableHeight -60 }" scroll expandedRowRender 不兼容没法同时使用不然会多出一行数据-->
<a-table :loading="loading" :columns="columns" :data-source="list" :style="{ 'max-height': tableHeight + 'px' }" bordered rowKey="id" @expand="expand" :pagination="false">
<a-tooltip slot="group" slot-scope="text" placement="topLeft" :title="text">
<span>{{ text }}</span>
</a-tooltip>
<a-tooltip slot="url" slot-scope="text" placement="topLeft" :title="text">
<span>{{ text }}</span>
</a-tooltip>
<template slot="operation" slot-scope="text, record">
<a-button type="primary" @click="handleTerminal(record)" :disabled="!record.sshId">终端</a-button>
<a-button type="primary" @click="handleNode(record)" :disabled="record.openStatus === false">节点管理</a-button>
<a-button type="primary" @click="handleEdit(record)">编辑</a-button>
<a-button type="danger" @click="handleDelete(record)">删除</a-button>
</template>
<!-- 嵌套表格 -->
<a-table slot="expandedRowRender" slot-scope="text" :loading="childLoading" :columns="childColumns" :data-source="text.children" :pagination="false" :rowKey="(record, index) => text.id + index">
<a-tooltip slot="osName" slot-scope="text" placement="topLeft" :title="text">
<span>{{ text }}</span>
</a-tooltip>
<a-tooltip slot="javaVersion" slot-scope="text" placement="topLeft" :title="text">
<span>{{ text }}</span>
</a-tooltip>
<a-tooltip slot="runTime" slot-scope="text" placement="topLeft" :title="text">
<span>{{ text }}</span>
</a-tooltip>
</a-table>
</a-table>
<!-- 编辑区 -->
<a-modal v-model="editNodeVisible" title="编辑节点" @ok="handleEditNodeOk" :maskClosable="false">
<a-form-model ref="editNodeForm" :rules="rules" :model="temp" :label-col="{ span: 6 }" :wrapper-col="{ span: 14 }">
<a-form-model-item label="节点 ID" prop="id">
<a-input v-model="temp.id" :disabled="temp.type != 'add'" placeholder="创建之后不能修改" />
</a-form-model-item>
<a-form-model-item label="节点名称" prop="name">
<a-input v-model="temp.name" placeholder="节点名称" />
</a-form-model-item>
<a-form-model-item label="分组名称" prop="group">
<a-row>
<a-col :span="18">
<a-select v-model="temp.group" placeholder="可手动输入">
<a-select-option v-for="group in groupList" :key="group">{{ group }}</a-select-option>
</a-select>
</a-col>
<a-col :span="6">
<a-popover v-model="addGroupvisible" title="添加分组" trigger="click">
<template slot="content">
<a-row>
<a-col :span="18">
<a-input v-model="temp.tempGroup" placeholder="分组名称" />
</a-col>
<a-col :span="6">
<a-button type="primary" @click="handleAddGroup">确认</a-button>
</a-col>
</a-row>
</template>
<a-button type="primary" class="btn-add">添加分组</a-button>
</a-popover>
</a-col>
</a-row>
</a-form-model-item>
<a-form-model-item label="绑定 SSH " prop="sshId">
<a-select v-model="temp.sshId" placeholder="节点协议">
<a-select-option v-for="ssh in sshList" :key="ssh.id" :disabled="ssh.disabled">{{ ssh.name }}</a-select-option>
</a-select>
</a-form-model-item>
<a-form-model-item label="监控周期" prop="cycle">
<a-select v-model="temp.cycle" defaultValue="0" placeholder="监控周期">
<a-select-option :key="0">不开启</a-select-option>
<a-select-option :key="-30">30 </a-select-option>
<a-select-option :key="1">1 分钟</a-select-option>
<a-select-option :key="5">5 分钟</a-select-option>
<a-select-option :key="10">10 分钟</a-select-option>
<a-select-option :key="30">30 分钟</a-select-option>
</a-select>
</a-form-model-item>
<a-form-model-item label="节点状态" prop="openStatus">
<a-switch v-model="temp.openStatus" checked-children="启用" un-checked-children="停用" default-checked/>
</a-form-model-item>
<a-form-model-item label="节点地址" prop="url">
<a-form-model-item label="节点状态" prop="openStatus">
<a-switch v-model="temp.openStatus" checked-children="启用" un-checked-children="停用" default-checked />
</a-form-model-item>
<a-form-model-item label="节点地址" prop="url">
<a-input v-model="temp.url" placeholder="节点地址 (127.0.0.1:2123)">
<a-select slot="addonBefore" v-model="temp.protocol" default-value="Http://" style="width: 80px">
<a-select-option value="Http"> Http:// </a-select-option>
<a-select-option value="Https"> Https:// </a-select-option>
</a-select>
</a-input>
<a-input v-model="temp.url" placeholder="节点地址 (127.0.0.1:2123)">
<a-select slot="addonBefore" v-model="temp.protocol" default-value="Http://" style="width: 80px">
<a-select-option value="Http">
Http://
</a-select-option>
<a-select-option value="Https">
Https://
</a-select-option>
</a-select>
</a-input>
<!-- <a-input-group>
<!-- <a-input-group>
</a-input-group> -->
</a-form-model-item>
<div class="node-config">
<a-form-model-item label="节点账号" prop="loginName">
<a-input v-model="temp.loginName" placeholder="节点账号,请查看节点启动输出的信息"/>
</a-form-model-item>
<a-form-model-item label="节点密码" prop="loginPwd">
<a-input-password v-model="temp.loginPwd" placeholder="节点密码,请查看节点启动输出的信息"/>
</a-form-model-item>
</div>
<a-form-model-item label="超时时间(s)" prop="timeOut">
<a-input-number v-model="temp.timeOut" :min="0" placeholder="秒 (值太小可能会取不到节点状态)" style="width: 100%"/>
</a-form-model-item>
</a-form-model>
</a-modal>
<!-- 管理节点 -->
<a-drawer :title="drawerTitle" placement="right" width="calc(100vw - 200px)"
:visible="drawerVisible" @close="onClose">
<!-- 节点管理组件 -->
<node-layout v-if="drawerVisible" :node="temp"/>
</a-drawer>
<!-- Terminal -->
<a-modal v-model="terminalVisible" width="80%" title="Terminal" :footer="null" :maskClosable="false">
<terminal v-if="terminalVisible" :sshId="temp.sshId" :nodeId="temp.id"/>
</a-modal>
</div>
</a-form-model-item>
<div class="node-config">
<a-form-model-item label="节点账号" prop="loginName">
<a-input v-model="temp.loginName" placeholder="节点账号,请查看节点启动输出的信息" />
</a-form-model-item>
<a-form-model-item label="节点密码" prop="loginPwd">
<a-input-password v-model="temp.loginPwd" placeholder="节点密码,请查看节点启动输出的信息" />
</a-form-model-item>
</div>
<a-form-model-item label="超时时间(s)" prop="timeOut">
<a-input-number v-model="temp.timeOut" :min="0" placeholder="秒 (值太小可能会取不到节点状态)" style="width: 100%" />
</a-form-model-item>
</a-form-model>
</a-modal>
<!-- 管理节点 -->
<a-drawer :title="drawerTitle" placement="right" width="calc(100vw - 200px)" :visible="drawerVisible" @close="onClose">
<!-- 节点管理组件 -->
<node-layout v-if="drawerVisible" :node="temp" />
</a-drawer>
<!-- Terminal -->
<a-modal v-model="terminalVisible" width="80%" title="Terminal" :footer="null" :maskClosable="false">
<terminal v-if="terminalVisible" :sshId="temp.sshId" :nodeId="temp.id" />
</a-modal>
</div>
</template>
<script>
import {mapGetters} from 'vuex';
import {getNodeGroupList, getNodeList, getNodeStatus, editNode, deleteNode} from '../../api/node';
import {getSshListByNodeId} from '../../api/ssh';
import NodeLayout from './node-layout';
import Terminal from './terminal';
import { mapGetters } from "vuex";
import { getNodeGroupList, getNodeList, getNodeStatus, editNode, deleteNode } from "../../api/node";
import { getSshListByNodeId } from "../../api/ssh";
import NodeLayout from "./node-layout";
import Terminal from "./terminal";
export default {
components: {
NodeLayout,
Terminal
},
data() {
return {
loading: false,
childLoading: false,
listQuery: {},
tableHeight: '70vh',
groupList: [],
sshList: [],
list: [],
temp: {
timeOut: 0
},
editNodeVisible: false,
drawerVisible: false,
terminalVisible: false,
addGroupvisible: false,
drawerTitle: '',
columns: [
{title: '节点 ID', dataIndex: 'id', key: 'id', width: 100, ellipsis: true, scopedSlots: {customRender: 'id'}},
{title: '节点名称', dataIndex: 'name', key: 'name', width: 150, ellipsis: true, scopedSlots: {customRender: 'name'}},
{title: '分组', dataIndex: 'group', key: 'group', width: 100, ellipsis: true, scopedSlots: {customRender: 'group'}},
{title: '节点协议', dataIndex: 'protocol', key: 'protocol', width: 100, ellipsis: true, scopedSlots: {customRender: 'protocol'}},
{title: '节点地址', dataIndex: 'url', key: 'url', width: 150, ellipsis: true, scopedSlots: {customRender: 'url'}},
{title: '超时时间', dataIndex: 'timeOut', key: 'timeOut', width: 100, ellipsis: true},
{title: '操作', dataIndex: 'operation', key: 'operation', scopedSlots: {customRender: 'operation'}, width: '360px', align: 'left'}
],
childColumns: [
{title: '系统名', dataIndex: 'osName', key: 'osName', width: 100, ellipsis: true, scopedSlots: {customRender: 'osName'}},
{title: 'JDK 版本', dataIndex: 'javaVersion', key: 'javaVersion', width: 120, ellipsis: true, scopedSlots: {customRender: 'javaVersion'}},
{title: 'JVM 总内存', dataIndex: 'totalMemory', key: 'totalMemory', width: 150},
{title: 'JVM 剩余内存', dataIndex: 'freeMemory', key: 'freeMemory', width: 180},
{title: 'Jpom 版本', dataIndex: 'jpomVersion', key: 'jpomVersion', width: 140},
{title: 'Java 程序数', dataIndex: 'javaVirtualCount', key: 'javaVirtualCount', width: 150},
{title: '项目数', dataIndex: 'count', key: 'count', width: 100},
{title: '响应时间', dataIndex: 'timeOut', key: 'timeOut', width: 120},
{title: '已运行时间', dataIndex: 'runTime', key: 'runTime', width: 150, ellipsis: true, scopedSlots: {customRender: 'runTime'}}
],
rules: {
id: [
{required: true, message: 'Please input node id', trigger: 'blur'}
],
name: [
{required: true, message: 'Please input node name', trigger: 'blur'}
],
url: [
{required: true, message: 'Please input url', trigger: 'blur'}
],
loginName: [
{required: true, message: 'Please input login name', trigger: 'blur'}
],
loginPwd: [
{required: true, message: 'Please input login password', trigger: 'blur'}
],
timeOut: [
{required: true, message: 'Please input timeout', trigger: 'blur'}
],
}
}
},
computed: {
...mapGetters([
'getGuideFlag'
])
},
watch: {
getGuideFlag() {
this.introGuide();
}
},
created() {
this.calcTableHeight();
this.loadGroupList();
this.handleFilter();
},
methods: {
//
introGuide() {
if (this.getGuideFlag) {
this.$introJs().setOptions({
hidePrev: true,
steps: [{
title: 'Jpom 导航助手',
element: document.querySelector('.node-config'),
intro: '节点的账号密码可以通过 agent_authorize.json 文件查看'
}]
}).start();
return false;
}
this.$introJs().exit();
},
//
calcTableHeight() {
this.$nextTick(() => {
this.tableHeight = window.innerHeight - this.$refs['filter'].clientHeight - 135;
})
},
//
loadGroupList() {
getNodeGroupList().then(res => {
if (res.code === 200) {
this.groupList = res.data;
}
})
},
// SSH
loadSshList() {
getSshListByNodeId(this.temp.id).then(res => {
if (res.code === 200) {
this.sshList = res.data;
}
})
},
//
loadData() {
this.list = [];
this.loading = true;
getNodeList(this.listQuery).then(res => {
if (res.code === 200) {
this.list = res.data;
let nodeId = this.$route.query.nodeId;
this.list.map((item) => {
if (nodeId === item.id) {
this.handleNode(item);
}
})
}
this.loading = false;
})
},
//
expand(expanded, record) {
if (expanded) {
if (!record.openStatus) {
this.$notification.error({
message: '节点未启用',
duration: 2
});
return false;
}
//
this.childLoading = true;
getNodeStatus(record.id).then(res => {
if (res.code === 200) {
// const index = this.list.findIndex(ele => ele.id === record.id);
// this.list[index].children = res.data;
record.children = res.data;
}
this.childLoading = false;
})
}
},
//
handleFilter() {
this.loadData();
},
//
handleAdd() {
this.temp = {
type: 'add',
cycle: 0,
protocol: 'http',
openStatus: true,
timeOut: 0,
loginName: 'jpomAgent'
};
this.editNodeVisible = true;
components: {
NodeLayout,
Terminal,
},
data() {
return {
loading: false,
childLoading: false,
listQuery: {},
tableHeight: "70vh",
groupList: [],
sshList: [],
list: [],
temp: {
timeOut: 0,
},
editNodeVisible: false,
drawerVisible: false,
terminalVisible: false,
addGroupvisible: false,
drawerTitle: "",
columns: [
{ title: "节点 ID", dataIndex: "id", key: "id", width: 100, ellipsis: true, scopedSlots: { customRender: "id" } },
{ title: "节点名称", dataIndex: "name", key: "name", width: 150, ellipsis: true, scopedSlots: { customRender: "name" } },
{ title: "分组", dataIndex: "group", key: "group", width: 100, ellipsis: true, scopedSlots: { customRender: "group" } },
{ title: "节点协议", dataIndex: "protocol", key: "protocol", width: 100, ellipsis: true, scopedSlots: { customRender: "protocol" } },
{ title: "节点地址", dataIndex: "url", key: "url", width: 150, ellipsis: true, scopedSlots: { customRender: "url" } },
{ title: "超时时间", dataIndex: "timeOut", key: "timeOut", width: 100, ellipsis: true },
{ title: "操作", dataIndex: "operation", key: "operation", scopedSlots: { customRender: "operation" }, width: "360px", align: "left" },
],
childColumns: [
{ title: "系统名", dataIndex: "osName", key: "osName", width: 100, ellipsis: true, scopedSlots: { customRender: "osName" } },
{ title: "JDK 版本", dataIndex: "javaVersion", key: "javaVersion", width: 120, ellipsis: true, scopedSlots: { customRender: "javaVersion" } },
{ title: "JVM 总内存", dataIndex: "totalMemory", key: "totalMemory", width: 150 },
{ title: "JVM 剩余内存", dataIndex: "freeMemory", key: "freeMemory", width: 180 },
{ title: "Jpom 版本", dataIndex: "jpomVersion", key: "jpomVersion", width: 140 },
{ title: "Java 程序数", dataIndex: "javaVirtualCount", key: "javaVirtualCount", width: 150 },
{ title: "项目数", dataIndex: "count", key: "count", width: 100 },
{ title: "响应时间", dataIndex: "timeOut", key: "timeOut", width: 120 },
{ title: "已运行时间", dataIndex: "runTime", key: "runTime", width: 150, ellipsis: true, scopedSlots: { customRender: "runTime" } },
],
rules: {
id: [{ required: true, message: "Please input node id", trigger: "blur" }],
name: [{ required: true, message: "Please input node name", trigger: "blur" }],
url: [{ required: true, message: "Please input url", trigger: "blur" }],
loginName: [{ required: true, message: "Please input login name", trigger: "blur" }],
loginPwd: [{ required: true, message: "Please input login password", trigger: "blur" }],
timeOut: [{ required: true, message: "Please input timeout", trigger: "blur" }],
},
};
},
computed: {
...mapGetters(["getGuideFlag"]),
},
watch: {
getGuideFlag() {
this.introGuide();
},
},
created() {
this.calcTableHeight();
this.loadGroupList();
this.handleFilter();
},
methods: {
//
introGuide() {
if (this.getGuideFlag) {
this.$introJs()
.setOptions({
hidePrev: true,
steps: [
{
title: "Jpom 导航助手",
element: document.querySelector(".node-config"),
intro: "节点的账号密码可以通过 agent_authorize.json 文件查看",
},
],
})
.start();
return false;
}
this.$introJs().exit();
},
//
calcTableHeight() {
this.$nextTick(() => {
this.tableHeight = window.innerHeight - this.$refs["filter"].clientHeight - 135;
});
},
//
loadGroupList() {
getNodeGroupList().then((res) => {
if (res.code === 200) {
this.groupList = res.data;
}
});
},
// SSH
loadSshList() {
getSshListByNodeId(this.temp.id).then((res) => {
if (res.code === 200) {
this.sshList = res.data;
}
});
},
//
loadData() {
this.list = [];
this.loading = true;
getNodeList(this.listQuery).then((res) => {
if (res.code === 200) {
this.list = res.data;
let nodeId = this.$route.query.nodeId;
this.list.map((item) => {
if (nodeId === item.id) {
this.handleNode(item);
}
});
}
this.loading = false;
});
},
//
expand(expanded, record) {
if (expanded) {
if (!record.openStatus) {
this.$notification.error({
message: "节点未启用",
duration: 2,
});
return false;
}
//
this.childLoading = true;
getNodeStatus(record.id).then((res) => {
if (res.code === 200) {
// const index = this.list.findIndex(ele => ele.id === record.id);
// this.list[index].children = res.data;
record.children = res.data;
}
this.childLoading = false;
});
}
},
//
handleFilter() {
this.loadData();
},
//
handleAdd() {
this.temp = {
type: "add",
cycle: 0,
protocol: "http",
openStatus: true,
timeOut: 0,
loginName: "jpomAgent",
};
this.editNodeVisible = true;
// @author jzy 08-04
this.$refs['editNodeForm'] && this.$refs['editNodeForm'].resetFields();
this.$nextTick(() => {
setTimeout(() => {
this.introGuide();
}, 500);
})
},
//
handleTerminal(record) {
this.temp = Object.assign(record);
this.terminalVisible = true;
},
//
handleEdit(record) {
this.temp = Object.assign(record);
this.loadSshList();
this.temp.tempGroup = '';
this.editNodeVisible = true;
this.$refs["editNodeForm"] && this.$refs["editNodeForm"].resetFields();
this.$nextTick(() => {
setTimeout(() => {
this.introGuide();
}, 500);
});
},
//
handleTerminal(record) {
this.temp = Object.assign(record);
this.terminalVisible = true;
},
//
handleEdit(record) {
this.temp = Object.assign(record);
this.loadSshList();
this.temp.tempGroup = "";
this.editNodeVisible = true;
// @author jzy 08-04
this.$refs['editNodeForm'] && this.$refs['editNodeForm'].resetFields();
},
//
handleEditNodeOk() {
//
this.$refs['editNodeForm'].validate((valid) => {
if (!valid) {
return false;
}
//
editNode(this.temp).then(res => {
if (res.code === 200) {
//
this.$notification.success({
message: res.msg,
duration: 2
});
this.editNodeVisible = false;
this.loadData();
this.loadGroupList();
}
})
})
},
handleDelete(record) {
this.$confirm({
title: '系统提示',
content: '真的要删除节点么?',
okText: '确认',
cancelText: '取消',
onOk: () => {
//
deleteNode(record.id).then((res) => {
if (res.code === 200) {
this.$notification.success({
message: res.msg,
duration: 2
});
this.loadData();
}
})
}
});
},
//
handleNode(record) {
this.temp = Object.assign(record);
this.drawerTitle = `${this.temp.id} (${this.temp.url})`;
this.drawerVisible = true;
let nodeId = this.$route.query.nodeId;
if (nodeId !== record.id) {
this.$router.push({
query: {nodeId: record.id}
})
}
},
//
onClose() {
this.drawerVisible = false;
this.$router.push({
query: {nodeId: null}
})
},
//
handleAddGroup() {
if (!this.temp.tempGroup || this.temp.tempGroup.length === 0) {
this.$notification.warning({
message: '分组名称不能为空',
duration: 2
});
return false;
}
//
if (this.groupList.indexOf(this.temp.tempGroup) === -1) {
this.groupList.push(this.temp.tempGroup);
}
this.temp.tempGroup = '';
this.$notification.success({
message: '添加成功',
duration: 2
});
this.addGroupvisible = false;
}
}
}
this.$refs["editNodeForm"] && this.$refs["editNodeForm"].resetFields();
},
//
handleEditNodeOk() {
//
this.$refs["editNodeForm"].validate((valid) => {
if (!valid) {
return false;
}
//
editNode(this.temp).then((res) => {
if (res.code === 200) {
//
this.$notification.success({
message: res.msg,
duration: 2,
});
this.editNodeVisible = false;
this.loadData();
this.loadGroupList();
}
});
});
},
handleDelete(record) {
this.$confirm({
title: "系统提示",
content: "真的要删除节点么?",
okText: "确认",
cancelText: "取消",
onOk: () => {
//
deleteNode(record.id).then((res) => {
if (res.code === 200) {
this.$notification.success({
message: res.msg,
duration: 2,
});
this.loadData();
}
});
},
});
},
//
handleNode(record) {
this.temp = Object.assign(record);
this.drawerTitle = `${this.temp.id} (${this.temp.url})`;
this.drawerVisible = true;
let nodeId = this.$route.query.nodeId;
if (nodeId !== record.id) {
this.$router.push({
query: { nodeId: record.id },
});
}
},
//
onClose() {
this.drawerVisible = false;
this.$router.push({
query: { nodeId: null },
});
},
//
handleAddGroup() {
if (!this.temp.tempGroup || this.temp.tempGroup.length === 0) {
this.$notification.warning({
message: "分组名称不能为空",
duration: 2,
});
return false;
}
//
if (this.groupList.indexOf(this.temp.tempGroup) === -1) {
this.groupList.push(this.temp.tempGroup);
}
this.temp.tempGroup = "";
this.$notification.success({
message: "添加成功",
duration: 2,
});
this.addGroupvisible = false;
},
},
};
</script>
<style scoped>
.filter {
margin-bottom: 10px;
margin-bottom: 10px;
}
.ant-btn {
margin-right: 10px;
margin-right: 10px;
}
.filter-item {
width: 150px;
margin-right: 10px;
width: 150px;
margin-right: 10px;
}
.btn-add {
margin-left: 10px;
margin-right: 0;
margin-left: 10px;
margin-right: 0;
}
</style>