zhangzengfei
2023-10-23 1db7db4bf02259e47d5d906d6b21ecc6451b0a09
添加集群手动选主节点, 无线网络显示ip
5个文件已修改
13790 ■■■■ 已修改文件
src/api/clusterManage.ts 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/settings/components/NetNode.vue 427 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/settings/components/netNodeData.js 13212 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/settings/views/NetSettings.vue 66 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/settings/views/clusterManagement.vue 41 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/clusterManage.ts
@@ -1,5 +1,5 @@
import request from "@/scripts/httpRequest";
import qs from "qs";
import request from "@/scripts/httpRequest"
import qs from "qs"
// 获取随机密码
export const randomPwd = (query: any) => {
@@ -7,8 +7,8 @@
    url: "/data/api-v/cluster/randomPwd",
    method: "get",
    params: query
  });
};
  })
}
// 创建集群
export const createSerfCluster = (query: any) => {
@@ -17,7 +17,7 @@
    method: "post",
    data: query
  })
};
}
// 搜索集群
export const search = (query: any) => {
@@ -26,7 +26,7 @@
    method: "post",
    data: query
  })
};
}
// 调search后,通过此接口获取查到的集群节点信息
export const getSearchNodes = (query: any) => {
@@ -34,8 +34,8 @@
    url: "/data/api-v/cluster/getSearchNodes",
    method: "get",
    params: query
  });
};
  })
}
// 停止搜索
export const stopSearching = (query: any) => {
@@ -44,7 +44,7 @@
    method: "post",
    data: query
  })
};
}
// 查询本地集群
export const findCluster = (query: any) => {
@@ -52,17 +52,17 @@
    url: "/data/api-v/cluster/findCluster",
    method: "get",
    params: query
  });
};
  })
}
// 保存集群名称
export const updateClusterName = (query: any) => {
  return request({
    url: '/data/api-v/cluster/updateClusterName',
    method: 'post',
    url: "/data/api-v/cluster/updateClusterName",
    method: "post",
    data: qs.stringify(query)
  })
};
}
// 加入集群
export const joinCluster = (query: any) => {
@@ -74,7 +74,7 @@
    },
    data: query
  })
};
}
export const leave = (query: any) => {
  return request({
@@ -82,15 +82,23 @@
    method: "post",
    data: query
  })
};
}
// 获取ES集群信息
export const update2Master = (data: any) => {
  return request({
    url: "/data/api-v/cluster/update2Master",
    method: "post",
    data
  })
}
// 获取漂移ip设置
export const getVrrp = () => {
  return request({
    url: "/vrrp",
    method: "get"
  })
};
}
// 设置漂移ip设置
export const setVrrp = (data: any) => {
@@ -126,4 +134,4 @@
    method: "post",
    data
  })
}
}
src/pages/settings/components/NetNode.vue
@@ -1,84 +1,73 @@
<template>
  <div class="net-node">
      <div class="vue-d3-network">
        <D3Network
        ref='net'
        :net-nodes="nodes"
        :net-links="links"
        :options="options"
        />
      </div>
    <div class="vue-d3-network">
      <D3Network ref="net" :net-nodes="nodes" :net-links="links" :options="options" />
    </div>
      <span class="icon iconfont zoom-in"
      @click="changeForce(1)"
      :class="{'zoom-disabled'
      :disabled.zoomIn}">&#xeb89;</span>
    <span class="icon iconfont zoom-in" @click="changeForce(1)" :class="{ 'zoom-disabled': disabled.zoomIn }"
      >&#xeb89;</span
    >
      <span class="icon iconfont zoom-out"
      @click="changeForce(0)"
      :class="{'zoom-disabled'
      :disabled.zoomOut}">&#xe758;</span>
    <span class="icon iconfont zoom-out" @click="changeForce(0)" :class="{ 'zoom-disabled': disabled.zoomOut }"
      >&#xe758;</span
    >
      <div class="illustrate">
        <div>
        <span class="illu-server"></span> 服务器
        </div>
    <div class="illustrate">
      <div><span class="illu-server"></span> APS智能终端</div>
        <div>
      <!-- <div>
        <span class="analysis"></span> 分析盒子
        </div>
      </div>
        </div> -->
    </div>
  </div>
</template>
<script>
import D3Network from 'vue-d3-network'
import {nodes,links} from './netNodeData'
import D3Network from "vue-d3-network"
import { nodes, links } from "./netNodeData"
export default {
created () {
  created() {
    this.reset()
},
  },
props:{
    innerNodes:Array
},
  props: {
    innerNodes: Array
  },
data () {
  return {
    //   settings: {
    //       maxLinks: 2,
    //       maxNodes: 130
    //   },
  data() {
    return {
      settings: {
        maxLinks: 2,
        maxNodes: 15
      },
      nodes,
      links,
      options: {
          size: {
              w: 600,
              h: 240
        size: {
          w: 600,
          h: 240
        },
        offset: {
              x: 0,
              y: 0
          x: 0,
          y: 0
        },
        nodeSize: 18,
        force: 300,
        nodeLabels: true
      },
      disabled:{
          zoomIn:false,
          zoomOut:false
      }
  }
},
      disabled: {
        zoomIn: false,
        zoomOut: false
      }
    }
  },
components: {
  components: {
    D3Network
},
  },
methods: {
  methods: {
    // 初始化
    // reset () {
    //    this.nodes = this.makeRandomNodes(this.settings.maxNodes)
@@ -88,194 +77,224 @@
    // },
    // 随机生成节点
    // makeRandomNodes (maxNodes) {
    //    let nodes = Array.apply(null, { length: maxNodes })
    //    .map((value, index) => { return this.newNode(index) })
    //    return nodes
    // },
    // newNode (nodeId) {
    //   return { id: nodeId, name: this.newNodeName(),_cssClass:"node-default" }
    // },
    // newNodeName () {
    // return Math.random().toString(36).substring(7)
    // },
    makeRandomNodes(maxNodes) {
      let nodes = Array.apply(null, { length: maxNodes }).map((value, index) => {
        return this.newNode(index)
      })
      return nodes
    },
    newNode(nodeId) {
      //   return { id: nodeId, name: this.newNodeName(), _cssClass: "node-default" }
      return {
        id: nodeId,
        name: this.newNodeName(),
        _cssClass: "node-default",
        index: nodeId,
        _labelClass: "label-default"
      }
    },
    newNodeName() {
      return Math.random()
        .toString(36)
        .substring(7)
    },
    // 随机生成连线
    // newLink (id, sid, tid) {
    // return { id, sid, tid,_color:"rgb(90,90,90)" }
    // },
    // makeRandomLinks (nodes, maxLinks) {
    // let links = []
    // let id = 0
    // for (let node of nodes) {
    // let total = Math.floor(Math.random() * maxLinks)
    // for (let i = 0; i <= total; i++) {
    //   let target = Math.floor(Math.random() * nodes.length)
    //   let source = node.id
    //   id++
    //   links.push(this.newLink(id, source, target))
    //  }
    // }
    // return links
    // },
    //随机生成连线
    newLink(id, sid, tid) {
      return { id, sid, tid, _color: "rgb(90,90,90)" }
    },
    makeRandomLinks(nodes, maxLinks) {
      let links = []
      let id = 0
      for (let node of nodes) {
        let total = Math.floor(Math.random() * maxLinks)
        for (let i = 0; i <= total; i++) {
          let target = Math.floor(Math.random() * nodes.length)
          let source = node.id
          id++
          links.push(this.newLink(id, source, target))
        }
      }
      return links
    },
    // 初始化
    reset() {
        let linkId = 200
        this.innerNodes.forEach((item,index) => {
      this.nodes = this.makeRandomNodes(this.settings.maxNodes)
      this.links = this.makeRandomLinks(this.nodes, this.settings.maxLinks)
      let linkId = 200
      let lastId = -1
      this.innerNodes.forEach((item, index) => {
        if (index === 0) {
            this.nodes = this.addNode(item,"server")
            this.links = this.addLink(linkId,6,`${item.node_id}`,"rgba(90,90,90,.6)")
            this.links = this.addLink(linkId+1,8,`${item.node_id}`,"rgba(90,90,90,.6)")
            linkId+=2
          this.nodes = this.addNode(item, item.online ? "server" : "offline")
          this.links = this.addLink(linkId, 6, `${item.node_id}`, "rgba(90,90,90,.6)")
          this.links = this.addLink(linkId + 1, 8, `${item.node_id}`, "rgba(90,90,90,.6)")
          linkId += 2
        } else {
          this.nodes = this.addNode(item, item.online ? "server" : "offline")
          this.links = this.addLink(linkId, item.node_id, this.innerNodes[index - 1].node_id, "#4E94FF")
          this.links = this.addLink(linkId, index, this.innerNodes[index - 1].node_id, "rgba(90,90,90,.6)")
          linkId += 1
        }
        else {
            this.nodes = this.addNode(item,"server")
            this.links = this.addLink(linkId,item.node_id,this.innerNodes[index-1].node_id,"#4E94FF")
            linkId+=1
            }
        })
        lastId = index
      })
      this.links = this.addLink(linkId + 1, 0, this.innerNodes[lastId].node_id, "rgba(90,90,90,.6)")
    },
    // 添加新节点
    addNode(newNode,type) {
        return [...this.nodes,{
                   "id": `${newNode.node_id}`,
                   "name": `${newNode.nodeName}`,
                   "_cssClass": `node-${type}`,
                   "_labelClass": `label-${type}`,
                   "x": 400,
                   "y": 100
                }]
    addNode(newNode, type) {
      return [
        ...this.nodes,
        {
          id: `${newNode.node_id}`,
          name: `${newNode.nodeName}`,
          _cssClass: `node-${type}`,
          _labelClass: `label-${type}`,
          x: 400,
          y: 100
        }
      ]
    },
    // 添加新连线
    addLink(id,sid,tid,color) {
        return [...this.links,{
            "id": id,
            "sid": sid,
            "tid": tid,
            "_color": color,
            "_svgAttrs": {"stroke-width": 2}
            }]
    addLink(id, sid, tid, color) {
      return [
        ...this.links,
        {
          id: id,
          sid: sid,
          tid: tid,
          _color: color,
          _svgAttrs: { "stroke-width": 2 }
        }
      ]
    },
    // 调整作用力
    changeForce(judge) {
    if(judge && this.options.nodeSize >25) {
      if (judge && this.options.nodeSize > 25) {
        this.disabled.zoomIn = true
        return
    }
    if(!judge && this.options.nodeSize <11) {
      }
      if (!judge && this.options.nodeSize < 11) {
        this.disabled.zoomOut = true
        return
    }
    const force =judge? this.options.force + 70 : this.options.force - 70
    let nodeSize = judge? this.options.nodeSize + 2 : this.options.nodeSize - 2
    this.disabled.zoomOut = this.disabled.zoomIn = false
    this.options = {
          size: {
              w: 600,
              h: 240
      }
      const force = judge ? this.options.force + 70 : this.options.force - 70
      let nodeSize = judge ? this.options.nodeSize + 2 : this.options.nodeSize - 2
      this.disabled.zoomOut = this.disabled.zoomIn = false
      this.options = {
        size: {
          w: 600,
          h: 240
        },
        offset: {
              x: 0,
              y: 0
          x: 0,
          y: 0
        },
        nodeSize: nodeSize,
        force
      }
    console.log( this.options);
    },
      console.log(this.options)
    }
  }
}
</script>
<style lang="scss" scoped>
.net-node {
    position: relative;
    overflow: hidden;
    margin-top:10px ;
    margin-bottom:4px ;
    padding-top:10px ;
    height: 240px;
    background-color: rgba(255, 255, 255, 0.719);
  position: relative;
  overflow: hidden;
  margin-top: 10px;
  margin-bottom: 4px;
  padding-top: 10px;
  height: 240px;
  background-color: rgba(255, 255, 255, 0.719);
    ::v-deep .node-default {
        fill: #fff;
        stroke: rgb(90,90,90);
        stroke-width: 1px;
  ::v-deep .node-default {
    fill: #fff;
    stroke: rgb(90, 90, 90);
    stroke-width: 1px;
  }
  ::v-deep .node-server {
    fill: #fff;
    stroke: #4e94ff;
    stroke-width: 2px;
  }
  ::v-deep .node-offline {
    fill: #fff;
    stroke: #b33030;
    stroke-width: 2px;
  }
  ::v-deep .label-default {
    display: none;
  }
  ::v-deep .label-server {
    font-weight: 700;
  }
  .zoom-in,
  .zoom-out {
    position: absolute;
    font-size: 21px;
    cursor: pointer;
    color: #333;
    &:hover {
      color: var(--colorCard);
    }
    ::v-deep .node-server {
        fill: #fff;
        stroke: #4E94FF;
        stroke-width: 2px;
    &.zoom-disabled:hover {
      color: #333;
      cursor: not-allowed;
    }
  }
    ::v-deep .label-default {
        display: none;
  .zoom-in {
    top: 20px;
    right: 20px;
  }
  .zoom-out {
    top: 50px;
    right: 20px;
  }
  .illustrate {
    position: absolute;
    display: flex;
    flex-direction: column;
    justify-content: center;
    padding-left: 8px;
    top: 180px;
    right: 20px;
    height: 40px;
    width: 100px;
    background-color: #fff;
    text-align: left;
    font-weight: bold;
    font-size: 12px;
    .illu-server {
      display: inline-block;
      width: 4px;
      height: 4px;
      border: 2px solid #4e94ff;
      border-radius: 4px;
    }
     ::v-deep .label-server {
        font-weight: 700;
    .analysis {
      display: inline-block;
      width: 4px;
      height: 4px;
      border: 2px solid #4ef4ff;
      border-radius: 4px;
    }
    .zoom-in,.zoom-out {
        position: absolute;
        font-size: 21px;
        cursor: pointer;
        color: #333;
        &:hover {
        color: var(--colorCard);
        }
        &.zoom-disabled:hover {
        color: #333;
        cursor: not-allowed;
        }
    }
    .zoom-in {
        top: 20px;
        right: 20px;
    }
    .zoom-out {
        top: 50px;
        right: 20px;
    }
    .illustrate {
        position: absolute;
        display: flex;
        flex-direction: column;
        justify-content: center;
        padding-left:8px ;
        top: 180px;
        right: 20px;
        height: 40px;
        width: 68px;
        background-color: #fff;
        text-align: left;
        font-weight: bold;
        font-size: 12px;
        .illu-server {
            display: inline-block;
            width: 4px;
            height: 4px;
            border: 2px solid #4E94FF;
            border-radius:4px ;
        }
        .analysis {
            display: inline-block;
            width: 4px;
            height: 4px;
            border: 2px solid #4EF4FF;
            border-radius:4px ;
        }
    }
  }
}
</style>
</style>
src/pages/settings/components/netNodeData.js
Diff too large
src/pages/settings/views/NetSettings.vue
@@ -83,7 +83,7 @@
            </el-form>
          </div>
          <!-- <switchBar :barName="`高级设置`" :value="isHighClass"></switchBar>
          <!-- <switchBar :barName="`高级设置`" :value="isHighClass"></switchBar> -->
          <div class="general-box fold" :class="{ hidden: IPV4_hid }">
            <div class="in-title">
@@ -91,10 +91,16 @@
              <span class="icon iconfont icon-fold" @click="toggleFold('IPV4_hid')">&#xe757;</span>
            </div>
            <el-form :model="ipv4Form" :rules="ipv4FormRules" ref="ipv4Form">
            <el-form :model="wirelessForm" ref="wirelessForm">
              <el-form-item>
                <div class="p-title">方法</div>
                <el-select v-model="value" placeholder="请选择" size="small" :popper-append-to-body="false">
                <el-select
                  v-model="wifiProto"
                  placeholder="请选择"
                  size="small"
                  :popper-append-to-body="false"
                  :disabled="wifiProto == 'dhcp'"
                >
                  <el-option
                    v-for="item in options"
                    :key="item.value"
@@ -105,27 +111,47 @@
              </el-form-item>
              <el-form-item prop="ip">
                <div class="p-title">IP</div>
                <ip-input :ip="ipv4Form.ip" @on-blur="ipv4Form.ip = arguments[0]"></ip-input>
                <ip-input
                  :ip="wirelessForm.ip"
                  @on-blur="wirelessForm.ip = arguments[0]"
                  :disabled="wifiProto == 'dhcp'"
                ></ip-input>
              </el-form-item>
              <el-form-item prop="subMask">
                <div class="p-title">子网掩码</div>
                <ip-input :ip="ipv4Form.subMask" @on-blur="ipv4Form.subMask = arguments[0]"></ip-input>
                <ip-input
                  :ip="wirelessForm.subMask"
                  @on-blur="wirelessForm.subMask = arguments[0]"
                  :disabled="wifiProto == 'dhcp'"
                ></ip-input>
              </el-form-item>
              <el-form-item prop="gateway">
                <div class="p-title">网关</div>
                <ip-input :ip="ipv4Form.gateway" @on-blur="ipv4Form.gateway = arguments[0]"></ip-input>
                <ip-input
                  :ip="wirelessForm.gateway"
                  @on-blur="wirelessForm.gateway = arguments[0]"
                  :disabled="wifiProto == 'dhcp'"
                ></ip-input>
              </el-form-item>
              <el-form-item prop="dns">
                <div class="p-title">首选DNS</div>
                <ip-input :ip="ipv4Form.dns1" @on-blur="ipv4Form.dns1 = arguments[0]"></ip-input>
                <ip-input
                  :ip="wirelessForm.dns1"
                  @on-blur="wirelessForm.dns1 = arguments[0]"
                  :disabled="wifiProto == 'dhcp'"
                ></ip-input>
              </el-form-item>
              <el-form-item prop="dns">
                <div class="p-title">备用DNS</div>
                <ip-input :ip="ipv4Form.dns2" @on-blur="ipv4Form.dns2 = arguments[0]"></ip-input>
                <ip-input
                  :ip="wirelessForm.dns2"
                  @on-blur="wirelessForm.dns2 = arguments[0]"
                  :disabled="wifiProto == 'dhcp'"
                ></ip-input>
              </el-form-item>
            </el-form>
          </div> -->
          </div>
          <div class="btns">
            <div class="cancel" @click="inWifiDetail = false">取消</div>
@@ -248,10 +274,6 @@
        deviceName: "",
        port: ""
      },
      wifiForm: {
        name: "",
        password: ""
      },
      wireArr: [],
      inWifiDetail: false,
      selectedWifi: {},
@@ -308,7 +330,7 @@
      rules: {
        deviceName: [{ required: true, message: "请输入设备名称", trigger: "change" }]
      },
      ipv4Form: {},
      wirelessForm: {},
      ipv6Form: {},
      ipv4FormRules: {},
      tabList: [
@@ -322,15 +344,15 @@
      ipv6FormRules: {},
      options: [
        {
          value: "选项1",
          value: "dhcp",
          label: "自动"
        },
        {
          value: "选项2",
          value: "static",
          label: "手动"
        }
      ],
      value: "",
      wifiProto: "dhcp",
      IPV4_hid: true,
      IPV6_hid: false,
      configLoading: false
@@ -513,6 +535,16 @@
    checkWifi(item) {
      this.inWifiDetail = true
      this.selectedWifi = item
      getNetWorkCardInfo({
        ifname: this.wifiIfname
      }).then((res) => {
        if (res && res.success) {
          this.wirelessForm.ip = res.data.ip
          this.wirelessForm.gateway = res.data.gateway
          this.wirelessForm.dns = res.data.dns
          this.wirelessForm.subMask = res.data.subMask
        }
      })
    },
    openWireDetail(item) {
      this.inWireDetail = true
src/pages/settings/views/clusterManagement.vue
@@ -5,8 +5,16 @@
      <!-- <cloud-node :nodes="innerNodes"></cloud-node> -->
      <net-node :innerNodes="innerNodes"></net-node>
      <div class="cls-bar">视频分析集群管理</div>
      <div class="cls-bar">
        <div class="title">节点状态</div>
        <div class="input-area">
          <div class="text" v-show="!isFillingName">
            {{ ruleForm.state }}
          </div>
          <el-switch v-model="masterNode" :disabled="masterNode" style="margin-top:5px" @change="change2Master">
          </el-switch>
        </div>
      </div>
      <div class="cls-bar">
        <div class="title">集群名称</div>
        <div class="input-area">
@@ -168,7 +176,8 @@
  stopSearching,
  findCluster,
  updateClusterName,
  joinCluster
  joinCluster,
  update2Master
} from "@/api/clusterManage"
// import cloudNode from "../components/CloudNode";
import NetNode from "../components/NetNode"
@@ -195,6 +204,7 @@
      }
    }
    return {
      masterNode: false,
      innerNodes: [],
      intervalTimer: null,
      isFillingName: false,
@@ -210,7 +220,9 @@
      ruleForm: {
        clustername: "",
        clusterpwd: "",
        virtualIp: ""
        virtualIp: "",
        state: "",
        localId: ""
      },
      selfForm: {
        virtualIp: "",
@@ -222,7 +234,7 @@
        clusterpwd: ""
      },
      isSearch: false,
      showCurCluster: true,
      showCurCluster: false,
      loading: false,
      joinLoading: false,
      isHasColony: false,
@@ -349,7 +361,6 @@
      })
    },
    join(formName) {
      console.log("join", formName)
      let _this = this
      _this.joinLoading = true
      let data = {
@@ -357,7 +368,6 @@
        password: _this.joinForm.clusterpwd,
        nodeIps: [_this.joinForm.clusterip]
      }
      console.log("body:", data)
      _this
        .joinCluster(data)
        .then(() => {
@@ -590,6 +600,7 @@
      if (res && res.success) {
        if (res.data && res.data.clusterId) {
          this.isHasColony = true
          this.showCurCluster = true
          this.clusterid = res.data.clusterId
          this.ruleForm.clustername = res.data.clusterName
          this.ruleForm.clusterpwd = "******"
@@ -609,6 +620,13 @@
            obj.nodeName = i.node_name
            obj.Address = i.node_ip
            obj.role = i.drift_state ? i.drift_state : "pc"
            obj.online = i.online
            if (obj.id == res.data.localId) {
              this.ruleForm.state = i.drift_state
              this.ruleForm.localId = res.data.localId
              this.masterNode = i.drift_state === "master"
            }
            return obj
          })
        } else {
@@ -618,6 +636,15 @@
    },
    clearInnerNodes() {
      this.innerNodes = []
    },
    async change2Master() {
      let res = await update2Master({ clusterId: this.clusterid, nodeId: this.ruleForm.localId })
      if (res && res.success) {
        this.$message.success("切换成功")
        this.findCluster()
      } else {
        this.$message.warning("切换失败")
      }
    }
  }
}