This commit is contained in:
bwcx_jzy 2021-12-27 14:24:49 +08:00
parent f32f2aae67
commit 006d604202
No known key found for this signature in database
GPG Key ID: 5E48E9372088B9E5
8 changed files with 212 additions and 154 deletions

View File

@ -250,6 +250,7 @@ public class ManageEditProjectController extends BaseAgentController {
exits.setRunMode(projectInfo.getRunMode()); exits.setRunMode(projectInfo.getRunMode());
exits.setWhitelistDirectory(projectInfo.getWhitelistDirectory()); exits.setWhitelistDirectory(projectInfo.getWhitelistDirectory());
exits.setToken(projectInfo.getToken()); exits.setToken(projectInfo.getToken());
exits.setDslContent(projectInfo.getDslContent());
exits.setJdkId(projectInfo.getJdkId()); exits.setJdkId(projectInfo.getJdkId());
// 检查是否非法删除副本集 // 检查是否非法删除副本集
List<NodeProjectInfoModel.JavaCopyItem> javaCopyItemList = exits.getJavaCopyItemList(); List<NodeProjectInfoModel.JavaCopyItem> javaCopyItemList = exits.getJavaCopyItemList();

View File

@ -111,6 +111,18 @@ public class NodeProjectInfoModel extends BaseWorkspaceModel {
* 项目自动启动 * 项目自动启动
*/ */
private Boolean autoStart; private Boolean autoStart;
/**
* dsl yml 内容
*/
private String dslContent;
public String getDslContent() {
return dslContent;
}
public void setDslContent(String dslContent) {
this.dslContent = dslContent;
}
public List<JavaCopyItem> getJavaCopyItemList() { public List<JavaCopyItem> getJavaCopyItemList() {
return javaCopyItemList; return javaCopyItemList;

View File

@ -29,24 +29,28 @@ package io.jpom.model;
* @date 2019/4/22 * @date 2019/4/22
*/ */
public enum RunMode { public enum RunMode {
/** /**
* java -classpath * java -classpath
*/ */
ClassPath, ClassPath,
/** /**
* java -jar * java -jar
*/ */
Jar, Jar,
/** /**
* java -jar Springboot war * java -jar Springboot war
*/ */
JarWar, JarWar,
/** /**
* java -Djava.ext.dirs=lib -cp conf:run.jar $MAIN_CLASS * java -Djava.ext.dirs=lib -cp conf:run.jar $MAIN_CLASS
*/ */
JavaExtDirsCp, JavaExtDirsCp,
/** /**
* 纯文件管理 * 纯文件管理
*/ */
File, File,
/**
* 自定义项目管理
*/
Dsl,
} }

View File

@ -143,6 +143,7 @@ export function editProject(params, replicaParams) {
token: params.token, token: params.token,
logPath: params.logPath, logPath: params.logPath,
autoStart: params.autoStart, autoStart: params.autoStart,
dslContent: params.dslContent,
...replicaParams, ...replicaParams,
}; };
return axios({ return axios({
@ -502,7 +503,7 @@ export function restartProject(params) {
data: params, data: params,
headers: { headers: {
loading: "no", loading: "no",
tip:"no", tip: "no",
}, },
}); });
} }
@ -522,7 +523,7 @@ export function startProject(params) {
data: params, data: params,
headers: { headers: {
loading: "no", loading: "no",
tip:"no", tip: "no",
}, },
}); });
} }
@ -542,9 +543,22 @@ export function stopProject(params) {
data: params, data: params,
headers: { headers: {
loading: "no", loading: "no",
tip:"no", tip: "no",
}, },
}); });
} }
export const runModeList = ["ClassPath", "Jar", "JarWar", "JavaExtDirsCp", "File"]; /**
* 所有的运行模式
*/
export const runModeList = ["ClassPath", "Jar", "JarWar", "JavaExtDirsCp", "File", "Dsl"];
/**
* java 项目的运行模式
*/
export const javaModes = ["ClassPath", "Jar", "JarWar", "JavaExtDirsCp"];
/**
* 有状态管理的运行模式
*/
export const noFileModes = ["ClassPath", "Jar", "JarWar", "JavaExtDirsCp", "Dsl"];

View File

@ -175,8 +175,8 @@
</a-form-model> </a-form-model>
</a-modal> </a-modal>
<!-- 创建/编辑分发项目 --> <!-- 创建/编辑分发项目 -->
<a-modal v-model="editDispatchVisible" width="600px" :title="temp.type === 'edit' ? '编辑分发项目' : '创建分发项目'" @ok="handleEditDispatchOk" :maskClosable="false"> <a-modal v-model="editDispatchVisible" width="60vw" :title="temp.type === 'edit' ? '编辑分发项目' : '创建分发项目'" @ok="handleEditDispatchOk" :maskClosable="false">
<a-form-model ref="editDispatchForm" :rules="rules" :model="temp" :label-col="{ span: 6 }" :wrapper-col="{ span: 18 }"> <a-form-model ref="editDispatchForm" :rules="rules" :model="temp" :label-col="{ span: 4 }" :wrapper-col="{ span: 18 }">
<a-form-model-item prop="id"> <a-form-model-item prop="id">
<template slot="label"> <template slot="label">
分发 ID 分发 ID
@ -220,21 +220,6 @@
<ul> <ul>
<li>白名单路径是指项目文件存放到服务中的文件夹</li> <li>白名单路径是指项目文件存放到服务中的文件夹</li>
<li>可以到节点分发=>分发白名单配置修改</li> <li>可以到节点分发=>分发白名单配置修改</li>
</ul>
</template>
<a-icon type="question-circle" theme="filled" />
</a-tooltip>
</template>
<a-select v-model="temp.whitelistDirectory" 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 prop="lib">
<template slot="label">
项目文件夹
<a-tooltip v-show="temp.type !== 'edit'">
<template slot="title">
<ul>
<li>项目文件夹是项目实际存放的目录名称</li> <li>项目文件夹是项目实际存放的目录名称</li>
<li>项目文件会存放到 <br />&nbsp;&nbsp;<b>项目白名单路径+项目文件夹</b></li> <li>项目文件会存放到 <br />&nbsp;&nbsp;<b>项目白名单路径+项目文件夹</b></li>
</ul> </ul>
@ -242,12 +227,34 @@
<a-icon type="question-circle" theme="filled" /> <a-icon type="question-circle" theme="filled" />
</a-tooltip> </a-tooltip>
</template> </template>
<a-input v-model="temp.lib" placeholder="项目存储的文件夹jar 包存放的文件夹" /> <a-input-group compact>
<a-select style="width: 50%" v-model="temp.whitelistDirectory" placeholder="请选择项目白名单路径">
<a-select-option v-for="access in accessList" :key="access">{{ access }}</a-select-option>
</a-select>
<a-input style="width: 50%" v-model="temp.lib" placeholder="项目存储的文件夹jar 包存放的文件夹" />
</a-input-group>
</a-form-model-item> </a-form-model-item>
<!-- <a-form-model-item prop="lib">
<template slot="label">
项目文件夹
<a-tooltip v-show="temp.type !== 'edit'">
<template slot="title">
<ul></ul>
</template>
<a-icon type="question-circle" theme="filled" />
</a-tooltip>
</template>
</a-form-model-item> -->
<a-form-model-item v-show="filePath !== ''" label="项目完整目录"> <a-form-model-item v-show="filePath !== ''" label="项目完整目录">
<a-alert :message="filePath" type="success" /> <a-alert :message="filePath" type="success" />
</a-form-model-item> </a-form-model-item>
<a-form-model-item v-show="temp.runMode && temp.runMode !== 'File'"> <a-form-model-item v-show="temp.runMode === 'Dsl'" label="DSL 内容" prop="dslContent">
<div style="height: 40vh; overflow-y: scroll">
<code-editor v-model="temp.dslContent" :options="{ mode: 'yaml', tabSize: 2, theme: 'abcdef' }"></code-editor>
</div>
</a-form-model-item>
<a-form-model-item v-show="javaModes.includes(temp.runMode)">
<template slot="label"> <template slot="label">
日志目录 日志目录
<a-tooltip v-show="temp.type !== 'edit'"> <a-tooltip v-show="temp.type !== 'edit'">
@ -265,9 +272,12 @@
<a-select-option v-for="access in accessList" :key="access">{{ access }}</a-select-option> <a-select-option v-for="access in accessList" :key="access">{{ access }}</a-select-option>
</a-select> </a-select>
</a-form-model-item> </a-form-model-item>
<a-form-model-item label="Main Class" prop="mainClass" v-show="temp.runMode && temp.runMode !== 'Jar' && temp.runMode !== 'File'"> <a-form-model-item label="Main Class" prop="mainClass" v-show="javaModes.includes(temp.runMode) && 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>
<a-form-model-item label="JavaExtDirsCp" prop="javaExtDirsCp" v-show="javaModes.includes(temp.runMode) && temp.runMode === 'JavaExtDirsCp'">
<a-input v-model="temp.javaExtDirsCp" placeholder="-Dext.dirs=xxx: -cp xx 填写【xxx:xx】" />
</a-form-model-item>
<a-form-model-item label="分发后操作" prop="afterOpt"> <a-form-model-item label="分发后操作" prop="afterOpt">
<a-select v-model="temp.afterOpt" placeholder="请选择发布后操作"> <a-select v-model="temp.afterOpt" placeholder="请选择发布后操作">
<a-select-option v-for="item in afterOptList" :key="item.value">{{ item.title }}</a-select-option> <a-select-option v-for="item in afterOptList" :key="item.value">{{ item.title }}</a-select-option>
@ -302,15 +312,15 @@
<a-select-option v-for="node in nodeList" :key="node.id">{{ `${node.name}` }}</a-select-option> <a-select-option v-for="node in nodeList" :key="node.id">{{ `${node.name}` }}</a-select-option>
</a-select> </a-select>
</a-form-model-item> </a-form-model-item>
<a-collapse v-show="temp.runMode && temp.runMode !== 'File'"> <a-collapse v-show="noFileModes.includes(temp.runMode)">
<a-collapse-panel v-for="nodeId in temp.nodeIdList" :key="nodeId" :header="nodeNameMap[nodeId] || nodeId"> <a-collapse-panel v-for="nodeId in temp.nodeIdList" :key="nodeId" :header="nodeNameMap[nodeId] || nodeId">
<a-form-model-item label="JVM 参数" prop="jvm"> <a-form-model-item label="JVM 参数" prop="jvm" v-show="javaModes.includes(temp.runMode)">
<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>
<a-form-model-item label="args 参数" prop="args"> <a-form-model-item label="args 参数" prop="args" v-show="javaModes.includes(temp.runMode)">
<a-textarea v-model="temp[`${nodeId}_args`]" :auto-size="{ minRows: 3, maxRows: 3 }" placeholder="Main 函数 args 参数,非必填. 如:--server.port=8080" /> <a-textarea v-model="temp[`${nodeId}_args`]" :auto-size="{ minRows: 3, maxRows: 3 }" placeholder="Main 函数 args 参数,非必填. 如:--server.port=8080" />
</a-form-model-item> </a-form-model-item>
<a-form-model-item prop="autoStart" v-show="temp.runMode && temp.runMode !== 'File'"> <a-form-model-item prop="autoStart" v-show="noFileModes.includes(temp.runMode)">
<template slot="label"> <template slot="label">
自启动 自启动
<a-tooltip v-show="temp.type !== 'edit'"> <a-tooltip v-show="temp.type !== 'edit'">
@ -320,7 +330,7 @@
</template> </template>
<a-switch v-model="temp[`${nodeId}_autoStart`]" checked-children="" un-checked-children="" /> <a-switch v-model="temp[`${nodeId}_autoStart`]" checked-children="" un-checked-children="" />
</a-form-model-item> </a-form-model-item>
<a-form-model-item prop="token"> <a-form-model-item prop="token" v-show="noFileModes.includes(temp.runMode)">
<template slot="label"> <template slot="label">
WebHooks WebHooks
<a-tooltip v-show="temp.type !== 'edit'"> <a-tooltip v-show="temp.type !== 'edit'">
@ -337,33 +347,35 @@
<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>
<!-- 副本信息 --> <div v-if="javaModes.includes(temp.runMode)">
<a-row v-for="replica in temp[`${nodeId}_javaCopyItemList`]" :key="replica.id"> <!-- 副本信息 -->
<a-form-model-item :label="`副本 ${replica.id} JVM 参数`" prop="jvm"> <a-row v-for="replica in temp[`${nodeId}_javaCopyItemList`]" :key="replica.id">
<a-textarea v-model="replica.jvm" :auto-size="{ minRows: 3, maxRows: 3 }" class="replica-area" placeholder="jvm参数,非必填.如:-Xms512m -Xmx512m" /> <a-form-model-item :label="`副本 ${replica.id} JVM 参数`" prop="jvm">
</a-form-model-item> <a-textarea v-model="replica.jvm" :auto-size="{ minRows: 3, maxRows: 3 }" class="replica-area" placeholder="jvm参数,非必填.如:-Xms512m -Xmx512m" />
<a-form-model-item :label="`副本 ${replica.id} args 参数`" prop="args"> </a-form-model-item>
<a-textarea v-model="replica.args" :auto-size="{ minRows: 3, maxRows: 3 }" class="replica-area" placeholder="Main 函数 args 参数,非必填. 如:--server.port=8080" /> <a-form-model-item :label="`副本 ${replica.id} args 参数`" prop="args">
</a-form-model-item> <a-textarea v-model="replica.args" :auto-size="{ minRows: 3, maxRows: 3 }" class="replica-area" placeholder="Main 函数 args 参数,非必填. 如:--server.port=8080" />
<a-tooltip placement="topLeft" title="已经添加成功的副本需要在副本管理页面去删除" class="replica-btn-del"> </a-form-model-item>
<a-button :disabled="!replica.deleteAble" type="danger" @click="handleDeleteReplica(nodeId, replica)">删除</a-button> <a-tooltip placement="topLeft" title="已经添加成功的副本需要在副本管理页面去删除" class="replica-btn-del">
</a-tooltip> <a-button :disabled="!replica.deleteAble" type="danger" @click="handleDeleteReplica(nodeId, replica)">删除</a-button>
</a-row>
<!-- 添加副本 -->
<a-form-model-item>
<template slot="label">
副本操作
<a-tooltip v-show="temp.type !== 'edit'">
<template slot="title">
<ul>
<li>副本是指同一个项目在一个节点服务器中运行多份</li>
</ul>
</template>
<a-icon type="question-circle" theme="filled" />
</a-tooltip> </a-tooltip>
</template> </a-row>
<a-button type="primary" @click="handleAddReplica(nodeId)">添加副本</a-button> <!-- 添加副本 -->
</a-form-model-item> <a-form-model-item>
<template slot="label">
副本操作
<a-tooltip v-show="temp.type !== 'edit'">
<template slot="title">
<ul>
<li>副本是指同一个项目在一个节点服务器中运行多份</li>
</ul>
</template>
<a-icon type="question-circle" theme="filled" />
</a-tooltip>
</template>
<a-button type="primary" @click="handleAddReplica(nodeId)">添加副本</a-button>
</a-form-model-item>
</div>
</a-collapse-panel> </a-collapse-panel>
</a-collapse> </a-collapse>
</a-form-model> </a-form-model>
@ -430,6 +442,7 @@
import { mapGetters } from "vuex"; import { mapGetters } from "vuex";
import File from "../node/node-layout/project/project-file"; import File from "../node/node-layout/project/project-file";
import Console from "../node/node-layout/project/project-console"; import Console from "../node/node-layout/project/project-console";
import codeEditor from "@/components/codeEditor";
import { import {
getDishPatchList, getDishPatchList,
getDispatchProject, getDispatchProject,
@ -444,13 +457,14 @@ import {
statusMap, statusMap,
} from "@/api/dispatch"; } from "@/api/dispatch";
import { getNodeListAll, getProjectListAll } from "@/api/node"; import { getNodeListAll, getProjectListAll } from "@/api/node";
import { getProjectData, runModeList } from "@/api/node-project"; import { getProjectData, runModeList, javaModes, noFileModes } from "@/api/node-project";
import { itemGroupBy, parseTime } from "@/utils/time"; import { itemGroupBy, parseTime } from "@/utils/time";
import { PAGE_DEFAULT_LIMIT, PAGE_DEFAULT_SIZW_OPTIONS, PAGE_DEFAULT_SHOW_TOTAL, PAGE_DEFAULT_LIST_QUERY } from "@/utils/const"; import { PAGE_DEFAULT_LIMIT, PAGE_DEFAULT_SIZW_OPTIONS, PAGE_DEFAULT_SHOW_TOTAL, PAGE_DEFAULT_LIST_QUERY } from "@/utils/const";
export default { export default {
components: { components: {
File, File,
Console, Console,
codeEditor,
}, },
data() { data() {
return { return {
@ -458,6 +472,8 @@ export default {
childLoading: false, childLoading: false,
listQuery: Object.assign({}, PAGE_DEFAULT_LIST_QUERY), listQuery: Object.assign({}, PAGE_DEFAULT_LIST_QUERY),
statusMap: statusMap, statusMap: statusMap,
javaModes: javaModes,
noFileModes: noFileModes,
list: [], list: [],
accessList: [], accessList: [],
nodeList: [], nodeList: [],

View File

@ -5,7 +5,7 @@
<a-layout-sider theme="light" class="sider" width="25%"> <a-layout-sider theme="light" class="sider" width="25%">
<div class="dir-container"> <div class="dir-container">
<a-button type="primary" @click="loadData">刷新目录</a-button> <a-button type="primary" @click="loadData">刷新目录</a-button>
<a-button type="primary" v-if="showConsole" @click="goConsole" v-show="runMode !== 'File'">控制台</a-button> <a-button type="primary" v-if="showConsole" @click="goConsole" v-show="noFileModes.includes(runMode)">控制台</a-button>
</div> </div>
<a-empty v-if="treeList.length === 0" /> <a-empty v-if="treeList.length === 0" />
<el-tree <el-tree
@ -104,7 +104,7 @@
</a-layout> </a-layout>
</template> </template>
<script> <script>
import { getFileList, downloadProjectFile, deleteProjectFile, uploadProjectFile, readFile, updateFile, remoteDownload } from "../../../../api/node-project"; import { getFileList, downloadProjectFile, noFileModes, deleteProjectFile, uploadProjectFile, readFile, updateFile, remoteDownload } from "@/api/node-project";
import { ZIP_ACCEPT } from "@/utils/const"; import { ZIP_ACCEPT } from "@/utils/const";
import codeEditor from "@/components/codeEditor"; import codeEditor from "@/components/codeEditor";
@ -133,6 +133,7 @@ export default {
data() { data() {
return { return {
ZIP_ACCEPT: ZIP_ACCEPT, ZIP_ACCEPT: ZIP_ACCEPT,
noFileModes: noFileModes,
loading: false, loading: false,
treeList: [], treeList: [],
fileList: [], fileList: [],

View File

@ -47,10 +47,10 @@
<span>{{ text }}</span> <span>{{ text }}</span>
</a-tooltip> </a-tooltip>
<template slot="status" slot-scope="text, record"> <template slot="status" slot-scope="text, record">
<a-tooltip v-if="record.runMode !== 'File'" title="状态操作请到控制台中控制"> <a-tooltip v-if="noFileModes.includes(record.runMode)" title="状态操作请到控制台中控制">
<a-switch :checked="text" disabled checked-children="" un-checked-children="" /> <a-switch :checked="text" disabled checked-children="" un-checked-children="" />
</a-tooltip> </a-tooltip>
<span v-if="record.runMode === 'File'">-</span> <span v-else>-</span>
</template> </template>
<a-tooltip slot="port" slot-scope="text, record" placement="topLeft" :title="`进程号:${record.pid}, 端口号:${record.port}`"> <a-tooltip slot="port" slot-scope="text, record" placement="topLeft" :title="`进程号:${record.pid}, 端口号:${record.port}`">
@ -58,8 +58,8 @@
</a-tooltip> </a-tooltip>
<template slot="operation" slot-scope="text, record"> <template slot="operation" slot-scope="text, record">
<a-button type="primary" @click="handleFile(record)">文件</a-button> <a-button type="primary" @click="handleFile(record)">文件</a-button>
<a-tooltip :title="`${record.runMode === 'File' ? 'File 类型项目不能使用控制台功能' : '到控制台去管理项目状态'}`"> <a-tooltip :title="`${noFileModes.includes(record.runMode) ? '到控制台去管理项目状态' : 'File 类型项目不能使用控制台功能'}`">
<a-button type="primary" @click="handleConsole(record)" :disabled="record.runMode === 'File'">控制台</a-button> <a-button type="primary" @click="handleConsole(record)" :disabled="!noFileModes.includes(record.runMode)">控制台</a-button>
</a-tooltip> </a-tooltip>
<a-dropdown> <a-dropdown>
<a class="ant-dropdown-link" @click="(e) => e.preventDefault()"> <a class="ant-dropdown-link" @click="(e) => e.preventDefault()">
@ -71,10 +71,10 @@
<a-button type="primary" @click="handleEdit(record)">编辑</a-button> <a-button type="primary" @click="handleEdit(record)">编辑</a-button>
</a-menu-item> </a-menu-item>
<a-menu-item> <a-menu-item>
<a-button type="primary" @click="handleMonitor(record)" v-show="record.runMode !== 'File'" :disabled="!record.status">监控 </a-button> <a-button type="primary" @click="handleMonitor(record)" v-show="javaModes.includes(record.runMode)" :disabled="!record.status">监控 </a-button>
</a-menu-item> </a-menu-item>
<a-menu-item> <a-menu-item>
<a-button type="primary" @click="handleReplica(record)" v-show="record.runMode !== 'File'" :disabled="!record.javaCopyItemList">副本集 </a-button> <a-button type="primary" @click="handleReplica(record)" v-show="javaModes.includes(record.runMode)" :disabled="!record.javaCopyItemList">副本集 </a-button>
</a-menu-item> </a-menu-item>
<a-menu-item> <a-menu-item>
<a-tooltip v-if="record.outGivingProject" title="节点分发项目需要到节点分发中去删除"> <a-tooltip v-if="record.outGivingProject" title="节点分发项目需要到节点分发中去删除">
@ -87,8 +87,8 @@
</template> </template>
</a-table> </a-table>
<!-- 编辑区 --> <!-- 编辑区 -->
<a-modal v-model="editProjectVisible" width="800px" title="编辑项目" @ok="handleEditProjectOk" :maskClosable="false"> <a-modal v-model="editProjectVisible" width="60vw" title="编辑项目" @ok="handleEditProjectOk" :maskClosable="false">
<a-form-model ref="editProjectForm" :rules="rules" :model="temp" :label-col="{ span: 6 }" :wrapper-col="{ span: 14 }"> <a-form-model ref="editProjectForm" :rules="rules" :model="temp" :label-col="{ span: 4 }" :wrapper-col="{ span: 18 }">
<a-form-model-item label="项目 ID" prop="id"> <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>
@ -117,27 +117,12 @@
</a-form-model-item> </a-form-model-item>
<a-form-model-item prop="whitelistDirectory" class="jpom-node-project-whitelist"> <a-form-model-item prop="whitelistDirectory" class="jpom-node-project-whitelist">
<template slot="label"> <template slot="label">
项目白名单路径 项目路径
<a-tooltip v-show="temp.type !== 'edit'"> <a-tooltip v-show="temp.type !== 'edit'">
<template slot="title"> <template slot="title">
<ul> <ul>
<li>白名单路径是指项目文件存放到服务中的文件夹</li> <li>白名单路径是指项目文件存放到服务中的文件夹</li>
<li>可以到节点管理中的系统管理=>白名单配置修改</li> <li>可以到节点管理中的系统管理=>白名单配置修改</li>
</ul>
</template>
<a-icon type="question-circle" theme="filled" />
</a-tooltip>
</template>
<a-select v-model="temp.whitelistDirectory" 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 prop="lib">
<template slot="label">
项目文件夹
<a-tooltip v-show="temp.type !== 'edit'">
<template slot="title">
<ul>
<li>项目文件夹是项目实际存放的目录名称</li> <li>项目文件夹是项目实际存放的目录名称</li>
<li>项目文件会存放到 <br />&nbsp;&nbsp;<b>项目白名单路径+项目文件夹</b></li> <li>项目文件会存放到 <br />&nbsp;&nbsp;<b>项目白名单路径+项目文件夹</b></li>
</ul> </ul>
@ -145,13 +130,34 @@
<a-icon type="question-circle" theme="filled" /> <a-icon type="question-circle" theme="filled" />
</a-tooltip> </a-tooltip>
</template> </template>
<a-input v-model="temp.lib" placeholder="项目存储的文件夹" @blur.native="checkLibIndexExist" /> <a-input-group compact>
<span class="lib-exist" v-show="temp.libExist">当前文件夹已存在,创建成功后会自动同步文件.</span> <a-select style="width: 50%" v-model="temp.whitelistDirectory" placeholder="请选择项目白名单路径">
<a-select-option v-for="access in accessList" :key="access">{{ access }}</a-select-option>
</a-select>
<a-input style="width: 50%" v-model="temp.lib" placeholder="项目存储的文件夹" @blur.native="checkLibIndexExist" />
<span class="lib-exist" v-show="temp.libExist">{{ temp.libExistMsg }}</span>
</a-input-group>
</a-form-model-item> </a-form-model-item>
<!-- <a-form-model-item prop="lib">
<template slot="label">
项目文件夹
<a-tooltip v-show="temp.type !== 'edit'">
<template slot="title">
<ul></ul>
</template>
<a-icon type="question-circle" theme="filled" />
</a-tooltip>
</template>
</a-form-model-item> -->
<a-form-model-item v-show="filePath !== ''" label="项目完整目录"> <a-form-model-item v-show="filePath !== ''" label="项目完整目录">
<a-alert :message="filePath" type="success" /> <a-alert :message="filePath" type="success" />
</a-form-model-item> </a-form-model-item>
<a-form-model-item v-show="temp.runMode && temp.runMode !== 'File'"> <a-form-model-item v-show="temp.runMode === 'Dsl'" label="DSL 内容" prop="dslContent">
<div style="height: 40vh; overflow-y: scroll">
<code-editor v-model="temp.dslContent" :options="{ mode: 'yaml', tabSize: 2, theme: 'abcdef' }"></code-editor>
</div>
</a-form-model-item>
<a-form-model-item v-show="javaModes.includes(temp.runMode)">
<template slot="label"> <template slot="label">
日志目录 日志目录
<a-tooltip v-show="temp.type !== 'edit'"> <a-tooltip v-show="temp.type !== 'edit'">
@ -170,51 +176,53 @@
</a-select> </a-select>
</a-form-model-item> </a-form-model-item>
<a-form-model-item label="JDK" prop="jdkId" v-show="temp.runMode && temp.runMode !== 'File'" class="jpom-node-project-jdk"> <a-form-model-item label="JDK" prop="jdkId" v-show="javaModes.includes(temp.runMode)" class="jpom-node-project-jdk">
<a-select v-model="temp.jdkId" placeholder="请选择 JDK"> <a-select v-model="temp.jdkId" placeholder="请选择 JDK">
<a-select-option v-for="jdk in jdkList" :key="jdk.id">{{ jdk.name }}</a-select-option> <a-select-option v-for="jdk in jdkList" :key="jdk.id">{{ jdk.name }}</a-select-option>
</a-select> </a-select>
</a-form-model-item> </a-form-model-item>
<a-form-model-item label="Main Class" prop="mainClass" v-show="temp.runMode && temp.runMode !== 'Jar' && temp.runMode !== 'File'"> <a-form-model-item label="Main Class" prop="mainClass" v-show="javaModes.includes(temp.runMode) && 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>
<a-form-model-item label="JavaExtDirsCp" prop="javaExtDirsCp" v-show="temp.runMode === 'JavaExtDirsCp' && temp.runMode !== 'File'"> <a-form-model-item label="JavaExtDirsCp" prop="javaExtDirsCp" v-show="javaModes.includes(temp.runMode) && temp.runMode === 'JavaExtDirsCp'">
<a-input v-model="temp.javaExtDirsCp" placeholder="-Dext.dirs=xxx: -cp xx 填写【xxx:xx】" /> <a-input v-model="temp.javaExtDirsCp" placeholder="-Dext.dirs=xxx: -cp xx 填写【xxx:xx】" />
</a-form-model-item> </a-form-model-item>
<a-form-model-item label="JVM 参数" prop="jvm" v-show="temp.runMode && temp.runMode !== 'File'"> <a-form-model-item label="JVM 参数" prop="jvm" v-show="javaModes.includes(temp.runMode)">
<a-textarea v-model="temp.jvm" :auto-size="{ minRows: 3, maxRows: 3 }" placeholder="jvm参数,非必填.如:-Xms512m -Xmx512m" /> <a-textarea v-model="temp.jvm" :auto-size="{ minRows: 3, maxRows: 3 }" placeholder="jvm参数,非必填.如:-Xms512m -Xmx512m" />
</a-form-model-item> </a-form-model-item>
<a-form-model-item label="args 参数" prop="args" v-show="temp.runMode && temp.runMode !== 'File'"> <a-form-model-item label="args 参数" prop="args" v-show="javaModes.includes(temp.runMode)">
<a-textarea v-model="temp.args" :auto-size="{ minRows: 3, maxRows: 3 }" placeholder="Main 函数 args 参数,非必填. 如:--server.port=8080" /> <a-textarea v-model="temp.args" :auto-size="{ minRows: 3, maxRows: 3 }" placeholder="Main 函数 args 参数,非必填. 如:--server.port=8080" />
</a-form-model-item> </a-form-model-item>
<!-- 副本信息 --> <div v-if="javaModes.includes(temp.runMode)">
<a-row v-for="replica in temp.javaCopyItemList" :key="replica.id"> <!-- 副本信息 -->
<a-form-model-item :label="`副本 ${replica.id} JVM 参数`" prop="jvm"> <a-row v-for="replica in temp.javaCopyItemList" :key="replica.id">
<a-textarea v-model="replica.jvm" :auto-size="{ minRows: 3, maxRows: 3 }" class="replica-area" placeholder="jvm参数,非必填.如:-Xms512m -Xmx512m" /> <a-form-model-item :label="`副本 ${replica.id} JVM 参数`" prop="jvm">
</a-form-model-item> <a-textarea v-model="replica.jvm" :auto-size="{ minRows: 3, maxRows: 3 }" class="replica-area" placeholder="jvm参数,非必填.如:-Xms512m -Xmx512m" />
<a-form-model-item :label="`副本 ${replica.id} args 参数`" prop="args"> </a-form-model-item>
<a-textarea v-model="replica.args" :auto-size="{ minRows: 3, maxRows: 3 }" class="replica-area" placeholder="Main 函数 args 参数,非必填. 如:--server.port=8080" /> <a-form-model-item :label="`副本 ${replica.id} args 参数`" prop="args">
</a-form-model-item> <a-textarea v-model="replica.args" :auto-size="{ minRows: 3, maxRows: 3 }" class="replica-area" placeholder="Main 函数 args 参数,非必填. 如:--server.port=8080" />
<a-tooltip placement="topLeft" title="已经添加成功的副本需要在副本管理页面去删除" class="replica-btn-del"> </a-form-model-item>
<a-button :disabled="!replica.deleteAble" type="danger" @click="handleDeleteReplica(replica)">删除</a-button> <a-tooltip placement="topLeft" title="已经添加成功的副本需要在副本管理页面去删除" class="replica-btn-del">
</a-tooltip> <a-button :disabled="!replica.deleteAble" type="danger" @click="handleDeleteReplica(replica)">删除</a-button>
</a-row>
<!-- 添加副本 -->
<a-form-model-item v-show="temp.runMode && temp.runMode !== 'File'">
<template slot="label">
副本操作
<a-tooltip v-show="temp.type !== 'edit'">
<template slot="title">
<ul>
<li>副本是指同一个项目在一个节点服务器中运行多份</li>
</ul>
</template>
<a-icon type="question-circle" theme="filled" />
</a-tooltip> </a-tooltip>
</template> </a-row>
<a-button type="primary" @click="handleAddReplica">添加副本</a-button> <!-- 添加副本 -->
</a-form-model-item> <a-form-model-item>
<a-form-model-item prop="autoStart" v-show="temp.runMode && temp.runMode !== 'File'"> <template slot="label">
副本操作
<a-tooltip v-show="temp.type !== 'edit'">
<template slot="title">
<ul>
<li>副本是指同一个项目在一个节点服务器中运行多份</li>
</ul>
</template>
<a-icon type="question-circle" theme="filled" />
</a-tooltip>
</template>
<a-button type="primary" @click="handleAddReplica">添加副本</a-button>
</a-form-model-item>
</div>
<a-form-model-item prop="autoStart" v-show="noFileModes.includes(temp.runMode)">
<template slot="label"> <template slot="label">
自启动 自启动
<a-tooltip v-show="temp.type !== 'edit'"> <a-tooltip v-show="temp.type !== 'edit'">
@ -224,7 +232,7 @@
</template> </template>
<a-switch v-model="temp.autoStart" checked-children="" un-checked-children="" /> <a-switch v-model="temp.autoStart" checked-children="" un-checked-children="" />
</a-form-model-item> </a-form-model-item>
<a-form-model-item prop="token" v-show="temp.runMode && temp.runMode !== 'File'" class="jpom-node-project-token"> <a-form-model-item prop="token" v-show="noFileModes.includes(temp.runMode)" class="jpom-node-project-token">
<template slot="label"> <template slot="label">
WebHooks WebHooks
<a-tooltip v-show="temp.type !== 'edit'"> <a-tooltip v-show="temp.type !== 'edit'">
@ -240,10 +248,10 @@
</template> </template>
<a-input v-model="temp.token" placeholder="项目启动,停止,重启都将请求对应的地址,非必填GET请求" /> <a-input v-model="temp.token" placeholder="项目启动,停止,重启都将请求对应的地址,非必填GET请求" />
</a-form-model-item> </a-form-model-item>
<a-form-model-item v-show="temp.type === 'edit' && temp.runMode !== 'File'" label="日志路径" prop="log"> <a-form-model-item v-if="temp.log" v-show="temp.type === 'edit' && javaModes.includes(temp.runMode)" label="日志路径" prop="log">
<a-alert :message="temp.log" type="success" /> <a-alert :message="temp.log" type="success" />
</a-form-model-item> </a-form-model-item>
<a-form-model-item v-show="temp.type === 'edit' && temp.runMode !== 'File'" label="运行命令" prop="runCommand"> <a-form-model-item v-if="temp.runCommand" v-show="temp.type === 'edit' && javaModes.includes(temp.runMode)" label="运行命令" prop="runCommand">
<a-alert :message="temp.runCommand || '无'" type="success" /> <a-alert :message="temp.runCommand || '无'" type="success" />
</a-form-model-item> </a-form-model-item>
</a-form-model> </a-form-model>
@ -284,6 +292,7 @@ import Console from "./project-console";
import Monitor from "./project-monitor"; import Monitor from "./project-monitor";
import Replica from "./project-replica"; import Replica from "./project-replica";
import { parseTime } from "@/utils/time"; import { parseTime } from "@/utils/time";
import codeEditor from "@/components/codeEditor";
import { PAGE_DEFAULT_LIMIT, PAGE_DEFAULT_SIZW_OPTIONS, PAGE_DEFAULT_SHOW_TOTAL, PAGE_DEFAULT_LIST_QUERY } from "@/utils/const"; import { PAGE_DEFAULT_LIMIT, PAGE_DEFAULT_SIZW_OPTIONS, PAGE_DEFAULT_SHOW_TOTAL, PAGE_DEFAULT_LIST_QUERY } from "@/utils/const";
import { import {
@ -298,6 +307,9 @@ import {
restartProject, restartProject,
startProject, startProject,
stopProject, stopProject,
runModeList,
javaModes,
noFileModes,
} from "@/api/node-project"; } from "@/api/node-project";
export default { export default {
@ -311,6 +323,7 @@ export default {
Console, Console,
Monitor, Monitor,
Replica, Replica,
codeEditor,
}, },
data() { data() {
return { return {
@ -318,7 +331,9 @@ export default {
listQuery: Object.assign({}, PAGE_DEFAULT_LIST_QUERY), listQuery: Object.assign({}, PAGE_DEFAULT_LIST_QUERY),
accessList: [], accessList: [],
jdkList: [], jdkList: [],
runModeList: ["ClassPath", "Jar", "JarWar", "JavaExtDirsCp", "File"], runModeList: runModeList,
javaModes: javaModes,
noFileModes: noFileModes,
list: [], list: [],
temp: {}, temp: {},
editProjectVisible: false, editProjectVisible: false,
@ -328,7 +343,7 @@ export default {
drawerMonitorVisible: false, drawerMonitorVisible: false,
drawerReplicaVisible: false, drawerReplicaVisible: false,
// addGroupvisible: false, // addGroupvisible: false,
libExist: false, // libExist: false,
selectedRows: [], selectedRows: [],
selectedRowKeys: [], selectedRowKeys: [],
checkRecord: "", checkRecord: "",
@ -669,11 +684,13 @@ export default {
if (this.temp.lib && this.temp.lib.length !== 0 && this.temp.whitelistDirectory && this.temp.whitelistDirectory.length !== 0) { if (this.temp.lib && this.temp.lib.length !== 0 && this.temp.whitelistDirectory && this.temp.whitelistDirectory.length !== 0) {
const params = { const params = {
nodeId: this.node.id, nodeId: this.node.id,
id: this.temp.id,
newLib: this.temp.whitelistDirectory + this.temp.lib, newLib: this.temp.whitelistDirectory + this.temp.lib,
}; };
nodeJudgeLibExist(params).then((res) => { nodeJudgeLibExist(params).then((res) => {
if (res.code === 401) { if (res.code === 401) {
this.temp.libExist = true; this.temp.libExist = true;
this.temp.libExistMsg = res.msg;
this.temp = { ...this.temp }; this.temp = { ...this.temp };
} }
if (res.code !== 200) { if (res.code !== 200) {
@ -868,15 +885,6 @@ export default {
margin-bottom: 10px; margin-bottom: 10px;
} }
.ant-btn {
margin-right: 10px;
}
.filter-item {
width: 150px;
margin-right: 10px;
}
.btn-add { .btn-add {
margin-left: 10px; margin-left: 10px;
margin-right: 0; margin-right: 0;

View File

@ -52,9 +52,10 @@
</a-tooltip> </a-tooltip>
<template slot="status" slot-scope="text, record"> <template slot="status" slot-scope="text, record">
<a-tooltip v-if="record.runMode !== 'File'" placement="topLeft" title="状态操作请到控制台中控制"> <a-tooltip v-if="noFileModes.includes(record.runMode)" placement="topLeft" title="状态操作请到控制台中控制">
<a-switch :checked="text" disabled checked-children="" un-checked-children="" /> <a-switch :checked="text" disabled checked-children="" un-checked-children="" />
</a-tooltip> </a-tooltip>
<span v-else>-</span>
</template> </template>
<a-tooltip slot="port" slot-scope="text, record" placement="topLeft" :title="`进程号:${record.pid}, 端口号:${record.port}`"> <a-tooltip slot="port" slot-scope="text, record" placement="topLeft" :title="`进程号:${record.pid}, 端口号:${record.port}`">
@ -62,7 +63,7 @@
</a-tooltip> </a-tooltip>
<template slot="operation" slot-scope="text, record"> <template slot="operation" slot-scope="text, record">
<a-button type="primary" @click="handleFile(record)">文件</a-button> <a-button type="primary" @click="handleFile(record)">文件</a-button>
<a-button type="primary" @click="handleConsole(record)" v-show="record.runMode !== 'File'">控制台</a-button> <a-button type="primary" @click="handleConsole(record)" v-show="noFileModes.includes(record.runMode)">控制台</a-button>
</template> </template>
</a-table> </a-table>
<!-- 项目文件组件 --> <!-- 项目文件组件 -->
@ -90,7 +91,7 @@
</template> </template>
<script> <script>
import { getProjectList, delAllProjectCache, getNodeListAll } from "@/api/node"; import { getProjectList, delAllProjectCache, getNodeListAll } from "@/api/node";
import { restartProject, startProject, stopProject, getRuningProjectInfo, runModeList } from "@/api/node-project"; import { restartProject, startProject, stopProject, getRuningProjectInfo, runModeList, noFileModes } from "@/api/node-project";
import { mapGetters } from "vuex"; import { mapGetters } from "vuex";
import File from "../node/node-layout/project/project-file"; import File from "../node/node-layout/project/project-file";
import Console from "../node/node-layout/project/project-console"; import Console from "../node/node-layout/project/project-console";
@ -107,6 +108,7 @@ export default {
runModeList: runModeList, runModeList: runModeList,
selectedRowKeys: [], selectedRowKeys: [],
listQuery: Object.assign({}, PAGE_DEFAULT_LIST_QUERY), listQuery: Object.assign({}, PAGE_DEFAULT_LIST_QUERY),
noFileModes: noFileModes,
nodeMap: {}, nodeMap: {},
drawerTitle: "", drawerTitle: "",
temp: {}, temp: {},