| | |
| | | <template>
|
| | | <div class="all">
|
| | | <div class="cluster-guanli" v-if="showCurCluster&& isHasColony">
|
| | | <!-- -->
|
| | | <div class="cluster-guanli" v-if="showCurCluster && isHasColony">
|
| | | <cloud-node :nodes="innerNodes"></cloud-node>
|
| | |
|
| | | <div class="bar">
|
| | | <div class="cls-bar">视频分析集群管理</div>
|
| | |
|
| | | <div class="cls-bar">
|
| | | <div class="title">集群名称</div>
|
| | | <div class="input-area">
|
| | | <div class="text" v-show="!isFillingName">
|
| | |
| | | ></span
|
| | | >
|
| | | <span
|
| | | class="icon iconfont" style="font-size:21px;"
|
| | | class="icon iconfont"
|
| | | style="font-size: 18px"
|
| | | @click="clearInput(1)"
|
| | | v-show="isFillingName"
|
| | | ></span
|
| | | ></span
|
| | | >
|
| | | <span |
| | | class="icon iconfont" style="font-size:20px;"
|
| | | <span
|
| | | class="icon iconfont"
|
| | | style="font-size: 20px; color: #4e94ff"
|
| | | @click="updateCluster(1)"
|
| | | v-show="isFillingName"
|
| | | ></span
|
| | | >
|
| | | </div>
|
| | | </div>
|
| | | <div class="bar">
|
| | | <div class="cls-bar">
|
| | | <div class="title">集群ID</div>
|
| | | <div class="input-area">
|
| | | <div class="text">{{ clusterid }}</div>
|
| | | </div>
|
| | | </div>
|
| | | <div class="bar">
|
| | | <div class="cls-bar">
|
| | | <div class="title">集群密码</div>
|
| | | <div class="input-area">
|
| | | <div class="text">{{ ruleForm.clusterpwd }}</div>
|
| | | </div>
|
| | | </div>
|
| | | <div class="bar">
|
| | | <div class="cls-bar">
|
| | | <div class="title">集群IP</div>
|
| | | <div class="input-area">
|
| | | <div class="text" v-show="!isFillingIp">{{ ruleForm.virtualIp }}</div>
|
| | |
| | | ></span
|
| | | >
|
| | | <span
|
| | | class="icon iconfont" style="font-size:21px;"
|
| | | class="icon iconfont"
|
| | | style="font-size: 18px"
|
| | | @click="clearInput(2)"
|
| | | v-show="isFillingIp"
|
| | | ></span
|
| | | ></span
|
| | | >
|
| | | <span
|
| | | class="icon iconfont"
|
| | | @click="updateCluster(2)" style="font-size:20px;"
|
| | | @click="updateCluster(2)"
|
| | | style="font-size: 20px; color: #4e94ff"
|
| | | v-show="isFillingIp"
|
| | | ></span
|
| | | >
|
| | | </div>
|
| | | </div>
|
| | |
|
| | | <div class="exit" @click="exitCluster">退出集群</div>
|
| | | <div class="btns">
|
| | | <div class="ok" @click="updateCluster">保存</div>
|
| | | <div class="exit" @click="exitCluster">退出集群</div>
|
| | | </div>
|
| | | </div>
|
| | |
|
| | | <div class="cluster-content">
|
| | | <div class="cluster-center" ref="left" v-if="!showCurCluster|| !isHasColony">
|
| | | <!-- !showCurCluster || !isHasColony -->
|
| | | <div class="cluster-content" v-if="!showCurCluster || !isHasColony">
|
| | | <div class="cluster-center" ref="left" v-if="!showCurCluster || !isHasColony">
|
| | | <div
|
| | | class="menu-item"
|
| | | :class="activePage == i ? 'menu-item-active' : ''"
|
| | |
| | | :key="i"
|
| | | @click="openRight(i)"
|
| | | >
|
| | | <span class="icon iconfont" v-if="activePage == 0"></span>
|
| | | <span class="icon iconfont" v-if="activePage == 1"></span>
|
| | | {{ item }}
|
| | | </div>
|
| | | </div>
|
| | | <div class="cluster-right" v-if="!showCurCluster || !isHasColony">
|
| | | <div class="create-new" v-if="activePage == 0">
|
| | | <el-form
|
| | | :model="ruleForm"
|
| | | :rules="rules"
|
| | | ref="ruleForm"
|
| | | label-width="150px"
|
| | | >
|
| | | <el-form-item label="集群名称" prop="clustername">
|
| | | <el-form :model="ruleForm" :rules="rules" ref="ruleForm">
|
| | | <el-form-item prop="clustername">
|
| | | <div class="p-title">集群名称</div>
|
| | | <el-input
|
| | | v-model="ruleForm.clustername"
|
| | | placeholder="手动输入, 如“集群A”"
|
| | | size="small"
|
| | | ></el-input>
|
| | | </el-form-item>
|
| | | <el-form-item label="集群ID">
|
| | | <el-form-item>
|
| | | <div class="p-title">集群ID</div>
|
| | | <el-input
|
| | | v-model="clusterid"
|
| | | placeholder="不允许输入,保存后回显"
|
| | |
| | | size="small"
|
| | | ></el-input>
|
| | | </el-form-item>
|
| | | <el-form-item label="集群密码" prop="clusterpwd">
|
| | | <el-form-item prop="clusterpwd">
|
| | | <div class="p-title">集群密码</div>
|
| | | <el-input
|
| | | v-model="ruleForm.clusterpwd"
|
| | | placeholder="请输入6位密码,或点击生成"
|
| | |
| | | >
|
| | | </el-input>
|
| | | </el-form-item>
|
| | | <el-form-item label="集群IP" prop="virtualIp">
|
| | | <el-form-item prop="virtualIp">
|
| | | <div class="p-title">集群IP</div>
|
| | | <ip-input
|
| | | :ip="ruleForm.virtualIp"
|
| | | :on-blur="onIpBlur"
|
| | |
| | | ></ip-input>
|
| | | </el-form-item>
|
| | | </el-form>
|
| | | <div class="save-btn" @click="saveCluster('ruleForm')">保存</div>
|
| | | <div class="btns">
|
| | | <div class="ok" @click="saveCluster('ruleForm')">保存</div>
|
| | | </div>
|
| | | </div>
|
| | |
|
| | | <div class="join-exist" v-if="activePage == 1">
|
| | |
| | | :rules="joinExistRules"
|
| | | ref="joinForm"
|
| | | class="join-form"
|
| | | label-width="150px"
|
| | | |
| | | v-loading="joinLoading"
|
| | | >
|
| | | <el-form-item label="集群ID" prop="clusterid">
|
| | | <el-form-item prop="clusterid">
|
| | | <div class="p-title">集群ID</div>
|
| | | <el-input v-model="joinForm.clusterid" size="small"></el-input>
|
| | | </el-form-item>
|
| | |
|
| | | <el-form-item label="IP地址" prop="clusterip">
|
| | | <el-form-item prop="clusterip">
|
| | | <div class="p-title">IP地址</div>
|
| | | <el-input
|
| | | v-model="joinForm.clusterip"
|
| | | placeholder="请输入集群内任意IP地址"
|
| | |
| | | autocomplete="new-password"
|
| | | ></el-input>
|
| | | </el-form-item>
|
| | | <el-form-item label="集群密码" prop="clusterpwd">
|
| | | <el-form-item prop="clusterpwd">
|
| | | <div class="p-title">集群密码</div>
|
| | | <el-input
|
| | | v-model="joinForm.clusterpwd"
|
| | | placeholder="请输入集群密码"
|
| | |
| | | </el-input>
|
| | | </el-form-item>
|
| | | </el-form>
|
| | |
|
| | | <div class="save-btn" @click="join('joinForm')">加入集群</div>
|
| | | <div class="btns">
|
| | | <div class="ok" @click="join('joinForm')">加入集群</div>
|
| | | </div>
|
| | | </div>
|
| | | </div>
|
| | | </div>
|
| | |
| | | joinCluster,
|
| | | } from "@/api/clusterManage";
|
| | | import cloudNode from "../components/CloudNode";
|
| | | import ipInput from "@/components/subComponents/IPInput";
|
| | | import ipInput from "../components/IPInput";
|
| | | import { isIPv4 } from "@/scripts/validate";
|
| | |
|
| | | export default {
|
| | |
| | | }
|
| | | }, 1000);
|
| | | };
|
| | | const checkID= (rule, value, callback) => {
|
| | | const checkID = (rule, value, callback) => {
|
| | | if (!value) {
|
| | | return callback(new Error("密码不能为空"));
|
| | | }
|
| | | }
|
| | | };
|
| | | return {
|
| | | innerNodes: [],
|
| | | intervalTimer: null,
|
| | |
| | | });
|
| | | },
|
| | | join(formName) {
|
| | | debugger
|
| | | let _this = this;
|
| | | this.$refs[formName].validate((valid) => {
|
| | | debugger
|
| | | if (valid) {
|
| | | debugger
|
| | | _this.joinLoading = true;
|
| | | let nodeIps = _this.members.map((i) => {
|
| | | return i.Address;
|
| | |
| | | this.stopSearch();
|
| | | }, 10 * 1000);
|
| | | },
|
| | | openRight( i) {
|
| | | openRight(i) {
|
| | | this.activePage = i;
|
| | | },
|
| | | async stopSearch() {
|
| | |
| | | this.ruleForm.clusterpwd = uuid.join("");
|
| | | },
|
| | | exitCluster() {
|
| | | this.$confirm("确定退出集群吗?","提示").then(async () => {
|
| | | const h = this.$createElement;
|
| | | this.$msgbox({
|
| | | title: "",
|
| | | message: h(
|
| | | "div",
|
| | | {
|
| | | style:
|
| | | "display: flex; flex-direction: column; justify-content: center; align-items: center;",
|
| | | },
|
| | | [
|
| | | h("span", { class: "icon iconfont warn-icon" }, "\ue71c"),
|
| | | h("span", { class: "warn-title" }, "退出集群"),
|
| | | h("span", { class: "warn-dec" }, "确定退出集群吗?"),
|
| | | ]
|
| | | ),
|
| | | showCancelButton: true,
|
| | | showClose: true,
|
| | | confirmButtonText: "确定",
|
| | | cancelButtonText: "取消",
|
| | | customClass: "del-account-message-box",
|
| | | }).then(
|
| | | async () => {
|
| | | let res = await leave();
|
| | | this.$notify({
|
| | | title: res.success ? "成功" : "失败",
|
| | |
| | | this.ruleForm.clusterpwd = "";
|
| | | this.clusterid = "";
|
| | | }
|
| | | },(err) => {
|
| | | clearInterval(this.intervalTimer);
|
| | | this.showCurCluster = false;
|
| | | this.ruleForm.virtualIp = "";
|
| | | this.ruleForm.clustername = "";
|
| | | this.ruleForm.clusterpwd = "";
|
| | | this.clusterid = "";
|
| | | })
|
| | | },
|
| | | (err) => {
|
| | | clearInterval(this.intervalTimer);
|
| | | this.showCurCluster = false;
|
| | | this.ruleForm.virtualIp = "";
|
| | | this.ruleForm.clustername = "";
|
| | | this.ruleForm.clusterpwd = "";
|
| | | this.clusterid = "";
|
| | | }
|
| | | );
|
| | | },
|
| | | clearInput(typ) {
|
| | | if (typ == 1) {
|
| | |
| | | this.ruleForm.virtualIp = ip;
|
| | | },
|
| | | async updateCluster(v) {
|
| | | if (v == 1) {
|
| | | if (v == 1 || v == undefined) {
|
| | | this.ruleForm.clustername = this.selfForm.clustername;
|
| | | }
|
| | | if (this.ruleForm.clustername === "") {
|
| | |
| | | if (res.success) {
|
| | | this.findCluster();
|
| | | }
|
| | |
|
| | | this.$notify({
|
| | | title: res.success ? "成功" : "失败",
|
| | | message: res.msg,
|
| | |
| | | <style lang="scss">
|
| | | .all {
|
| | | width: 100%;
|
| | | background: #f2f2f7;
|
| | | }
|
| | | .cluster-guanli {
|
| | | margin: 0 auto;
|
| | | width: 520px;
|
| | | .bar {
|
| | | height: 40px;
|
| | | background-color: rgba(248, 248, 248, 1);
|
| | | margin-bottom: 10px;
|
| | | /* width: 760px; */
|
| | | padding: 0 10px;
|
| | | .btns {
|
| | | margin-top: 30px !important;
|
| | |
|
| | | .exit {
|
| | | width: 188px;
|
| | | height: 40px;
|
| | | cursor: pointer;
|
| | | border-radius: 25px;
|
| | | background-color: #fe6d68;
|
| | | color: #fff;
|
| | | line-height: 40px;
|
| | | font-weight: bold;
|
| | | font-size: 16px;
|
| | | margin-left: 60px;
|
| | | margin-top: 0;
|
| | | }
|
| | | }
|
| | | .cloud {
|
| | | width: 100%;
|
| | | display: flex;
|
| | | height: 255px;
|
| | | border-radius: 8px;
|
| | | background: linear-gradient(
|
| | | 180deg,
|
| | | #ffffff 0%,
|
| | | rgba(255, 255, 255, 0) 100%
|
| | | );
|
| | | .inner {
|
| | | background: url(/images/settings/easy-cloud.png) no-repeat;
|
| | | background-size: contain;
|
| | | margin: 0 auto;
|
| | | width: 240px;
|
| | | .rect {
|
| | | position: relative;
|
| | | margin: 0;
|
| | | height: 100%;
|
| | | }
|
| | | }
|
| | | }
|
| | | .cls-bar {
|
| | | height: 48px;
|
| | | background-color: #ffffff;
|
| | | margin-bottom: 6px;
|
| | | display: flex;
|
| | | box-sizing: border-box;
|
| | | padding: 0 20px;
|
| | | padding: 0 30px;
|
| | | justify-content: space-between;
|
| | | align-items: center;
|
| | | .title{
|
| | | font-size: 14px;
|
| | | border-radius: 8px;
|
| | | font-weight: bold;
|
| | | font-size: 14px;
|
| | | color: #333333;
|
| | | .title {
|
| | | font-size: 14px;
|
| | | }
|
| | | .input-area {
|
| | | display: flex;
|
| | | width: 340px;
|
| | | width: 540px;
|
| | | height: 30px;
|
| | | line-height: 30px;
|
| | | justify-content: inherit;
|
| | | box-sizing: border-box;
|
| | | .icon{
|
| | | background: #f2f2f7;
|
| | | border-radius: 20px;
|
| | | padding: 0 30px;
|
| | | .el-input--mini .el-input__inner {
|
| | | height: 24px;
|
| | | line-height: 24px;
|
| | | /* border: 1px solid transparent; */
|
| | | background: inherit;
|
| | | padding-left: 0;
|
| | | border: none;
|
| | | border-radius: 0px;
|
| | | font-size: 14px;
|
| | | }
|
| | |
|
| | | .icon {
|
| | | cursor: pointer;
|
| | | // font-size: 18px;
|
| | | font-size: 14px;
|
| | | margin-left: 10px;
|
| | | }
|
| | | }
|
| | | }
|
| | |
| | | flex: 1;
|
| | | flex-basis: auto;
|
| | | box-sizing: border-box;
|
| | | background: #fbfaff;
|
| | |
|
| | | .cluster-center {
|
| | | height: 100%;
|
| | | width: 280px;
|
| | |
| | | box-sizing: border-box;
|
| | | flex-shrink: 0;
|
| | | padding: 10px;
|
| | | border-right: 5px solid #f8f8f8;
|
| | | border-right: 4px solid #f2f2f7;
|
| | | border-left: 4px solid #f2f2f7;
|
| | | .menu-item {
|
| | | background-color: #f8f8f8; cursor: pointer;
|
| | | height: 50px;
|
| | | background-color: #f8f8f8;
|
| | | cursor: pointer;
|
| | | height: 56px;
|
| | | margin-bottom: 10px;
|
| | | border-radius: 8px;
|
| | | line-height: 50px;
|
| | | font-size: 15px;
|
| | | line-height: 56px;
|
| | | text-align: left;
|
| | | box-sizing: border-box;
|
| | | padding: 0 20px;
|
| | | font-weight: bold;
|
| | | font-size: 16px;
|
| | | }
|
| | | .menu-item-active {
|
| | | background-color: var(--colorCard);
|
| | | color: white;
|
| | | }
|
| | | .menu-item:hover {
|
| | | background-color: var(--colorCard);
|
| | | color: white;
|
| | | }
|
| | | // .menu-item:hover {
|
| | | // background-color: var(--colorCard);
|
| | | // color: white;
|
| | | // }
|
| | | }
|
| | | .cluster-right {
|
| | | flex: 1;
|
| | |
| | | > .el-form-item__label:before {
|
| | | display: none;
|
| | | }
|
| | | .el-form-item {
|
| | | margin-bottom: 10px;
|
| | | height: 50px;
|
| | | background: #f8f8f8;
|
| | | padding: 4px 20px;
|
| | | -webkit-box-sizing: border-box;
|
| | | box-sizing: border-box;
|
| | | border-radius: 10px;
|
| | | .el-form-item__label {
|
| | | text-align: left;
|
| | | line-height: 42px;
|
| | | .create-new {
|
| | | }
|
| | |
|
| | | .el-form-item__content {
|
| | | line-height: 48px;
|
| | | display: flex;
|
| | | align-items: center;
|
| | | background: #f2f2f7;
|
| | | border-radius: 8px;
|
| | | padding: 0 15px 0 20px;
|
| | | .el-select-dropdown__item {
|
| | | color: #333333;
|
| | | height: 32px;
|
| | | font-size: 12px;
|
| | | line-height: 32px;
|
| | | text-align: center;
|
| | | }
|
| | | .el-popper {
|
| | | margin-top: 0;
|
| | | background: #fbfaff;
|
| | | box-shadow: 0px 2px 6px rgb(0 0 0 / 18%);
|
| | | border-radius: 2px;
|
| | | .el-select-dropdown__item.hover,
|
| | | .el-select-dropdown__item:hover {
|
| | | background-color: #f2f2f7;
|
| | | color: #4e94ff;
|
| | | }
|
| | | }
|
| | | }
|
| | | .el-form-item__content {
|
| | | line-height: 40px;
|
| | | position: relative;
|
| | | font-size: 14px;
|
| | | .el-form-item__error {
|
| | | line-height: 0.7;
|
| | | left: 20px;
|
| | | }
|
| | | .el-form-item {
|
| | | margin-bottom: 10px;
|
| | | .el-input__inner {
|
| | | background-color: #ffffff;
|
| | | border: 2px solid transparent;
|
| | | border-radius: 20px;
|
| | | height: 32px;
|
| | | line-height: 32px;
|
| | | padding: 0 15px;
|
| | | font-size: 14px;
|
| | | font-weight: bold;
|
| | | }
|
| | | .el-input__inner:focus {
|
| | | border: 2px solid #4e94ff;
|
| | | }
|
| | | .el-input__inner::placeholder {
|
| | | color: #c0c4cc;
|
| | | font-size: 12px;
|
| | | font-weight: normal;
|
| | | }
|
| | | .el-select {
|
| | | width: 100%;
|
| | | }
|
| | | .el-select .el-input .el-select__caret {
|
| | | color: #333333;
|
| | | font-size: 14px;
|
| | | font-weight: 600;
|
| | | }
|
| | | }
|
| | | .p-title {
|
| | | height: 48px;
|
| | | text-align: left;
|
| | | line-height: 48px;
|
| | | width: 90px;
|
| | | font-weight: 600;
|
| | | }
|
| | | .ip-input-container {
|
| | | max-width: none !important;
|
| | | height: 32px;
|
| | | line-height: normal;
|
| | | box-sizing: border-box;
|
| | | // background-color: #f2f2f7;
|
| | | text-align: left;
|
| | | border-radius: 20px;
|
| | | border: 2px solid transparent;
|
| | | }
|
| | | .ntp-bar {
|
| | | height: 40px;
|