ZZJ
2021-10-09 2e56105da84145350e9b6fe2925cee63d55283f6
zzjv2
6个文件已添加
13个文件已修改
1945 ■■■■■ 已修改文件
public/apps.json 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/fonts/alibaba/demo_index.html 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/fonts/alibaba/iconfont.css 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/fonts/alibaba/iconfont.ttf 补丁 | 查看 | 原始文档 | blame | 历史
public/fonts/alibaba/iconfont.woff 补丁 | 查看 | 原始文档 | blame | 历史
public/fonts/alibaba/iconfont.woff2 补丁 | 查看 | 原始文档 | blame | 历史
public/images/systemMonitor/Group 224.png 补丁 | 查看 | 原始文档 | blame | 历史
public/images/systemMonitor/Group 241.png 补丁 | 查看 | 原始文档 | blame | 历史
public/images/systemMonitor/Group 242.png 补丁 | 查看 | 原始文档 | blame | 历史
public/images/systemMonitor/Group 265.png 补丁 | 查看 | 原始文档 | blame | 历史
public/images/systemMonitor/心电算法备份 2 25.png 补丁 | 查看 | 原始文档 | blame | 历史
public/images/systemMonitor/心电算法备份 2-1 2.png 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/settings/components/IPInput.vue 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/settings/components/switchBar.vue 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/settings/index/index.vue 149 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/settings/views/NetSettings.vue 683 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/settings/views/clusterManagement.vue 332 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/settings/views/generalSettings.vue 47 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/systemMonitor/index/App.vue 633 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/apps.json
@@ -394,6 +394,29 @@
      "progressMsg": ""
    },
    {
      "id": "1e51abbf-a4dd-4cf9-9eee-2149102d6d43",
      "name": "系统监控",
      "package": "systemMonitor",
      "type": "2",
      "url": "/view/systemMonitor/",
      "title": "系统监控",
      "width": 1200,
      "height": 670,
      "iconBlob": "",
      "icon": "../../images/app-mid/library.png",
      "version": "1.0.0",
      "create_time": "2020-10-10 20:39:25",
      "create_by": "basic",
      "update_time": "",
      "update_by": "",
      "isDelete": 0,
      "isDefault": true,
      "remoteVersion": "",
      "installed": true,
      "isUpgrade": false,
      "progressMsg": ""
    },
    {
      "id": "aaf6875a-2e45-414a-affd-ae0a97420920",
      "name": "GB28181配置",
      "package": "gb28181",
public/fonts/alibaba/demo_index.html
@@ -2358,9 +2358,9 @@
<pre><code class="language-css"
>@font-face {
  font-family: 'iconfont';
  src: url('iconfont.woff2?t=1632996238561') format('woff2'),
       url('iconfont.woff?t=1632996238561') format('woff'),
       url('iconfont.ttf?t=1632996238561') format('truetype');
  src: url('iconfont.woff2?t=1633747444881') format('woff2'),
       url('iconfont.woff?t=1633747444881') format('woff'),
       url('iconfont.ttf?t=1633747444881') format('truetype');
}
</code></pre>
          <h3 id="-iconfont-">第二步:定义使用 iconfont çš„æ ·å¼</h3>
public/fonts/alibaba/iconfont.css
@@ -1,8 +1,8 @@
@font-face {
  font-family: "iconfont"; /* Project id 1155353 */
  src: url('iconfont.woff2?t=1632996238561') format('woff2'),
       url('iconfont.woff?t=1632996238561') format('woff'),
       url('iconfont.ttf?t=1632996238561') format('truetype');
  src: url('iconfont.woff2?t=1633747444881') format('woff2'),
       url('iconfont.woff?t=1633747444881') format('woff'),
       url('iconfont.ttf?t=1633747444881') format('truetype');
}
.iconfont {
public/fonts/alibaba/iconfont.ttf
Binary files differ
public/fonts/alibaba/iconfont.woff
Binary files differ
public/fonts/alibaba/iconfont.woff2
Binary files differ
public/images/systemMonitor/Group 224.png
public/images/systemMonitor/Group 241.png
public/images/systemMonitor/Group 242.png
public/images/systemMonitor/Group 265.png
public/images/systemMonitor/ÐĵçËã·¨±¸·Ý 2 25.png
public/images/systemMonitor/ÐĵçËã·¨±¸·Ý 2-1 2.png
src/pages/settings/components/IPInput.vue
@@ -201,7 +201,7 @@
<style lang="scss" scoped>
.ip-input-container {
  display: inline-block;
  width: 100%;
  height: 32px;
  line-height: normal;
@@ -210,11 +210,13 @@
  background-color: #fff;
  text-align: left;
  max-width: 360px;
  display: flex;
}
.ip-segment {
  display: inline-block;
  width: 25%;
  height: 32px;
    display: flex;
    align-items: center;
  line-height: normal;
  input {
    width: 90%;
src/pages/settings/components/switchBar.vue
@@ -1,7 +1,12 @@
<template>
  <div class="switch-bar">
    <div class="name">{{ barName }}</div>
    <el-switch v-model="value" active-color="#4e94ff" @change="switchChange">
    <el-switch
      v-model="value"
      active-color="#4e94ff"
      :width="30"
      @change="switchChange"
    >
    </el-switch>
  </div>
</template>
@@ -23,33 +28,40 @@
  height: 50px;
  padding: 0 25px;
  justify-content: space-between;
  border-radius: 12px;
border-radius: 8px;
  margin-bottom: 10px;
  .el-switch {
    display: inline-flex;
    align-items: center;
  .el-switch.is-checked .el-switch__core::after {
    left: 100%;
    margin-left: -12px;
  }
  .el-switch__core {
    margin: 0;
    position: relative;
    font-size: 14px;
    line-height: 14px;
    width: 40px;
    height: 14px;
    border: 1px solid #dcdfe6;
    outline: 0;
    border-radius: 10px;
    -webkit-box-sizing: border-box;
    box-sizing: border-box;
    background: #dcdfe6;
    -webkit-transition: border-color 0.3s, background-color 0.3s;
    transition: border-color 0.3s, background-color 0.3s;
    vertical-align: middle;
    .el-switch__core {
      width: 30px !important;
      height: 14px;
      border: 1px solid #E0E0E0;
      border-radius: 20px;
      background: #E0E0E0;
    }
    .el-switch__core:after {
      top: 0px;
      left: -1px;
      width: 12px;
      height: 12px;
      background-color: #fff;
    }
    .el-switch.is-checked .el-switch__core::after {
      margin-left: -10px;
    }
  }
  .el-switch__core:after {
    content: "";
    position: absolute;
    top: 0px;
    left: 0px;
    border-radius: 100%;
    -webkit-transition: all 0.3s;
    transition: all 0.3s;
    width: 12px;
    height: 12px;
    background-color: #fff;
  }
  .name {
    font-size: 12px;
src/pages/settings/index/index.vue
@@ -8,7 +8,6 @@
        :key="i"
        @click="openMenu(i)"
      >
        <!-- <span class="icon iconfont">{{ item.icon }}</span> -->
        <img :src="item.blackIcon" class="b" alt="" />
        <img :src="item.whiteIcon" class="w" alt="" />
        <span class="card-text">{{ item.name }}</span>
@@ -40,7 +39,6 @@
          </div>
        </div>
        <div class="add-account" v-if="curUserRole != '普通用户'">
          <!-- <span class="icon iconfont" @click="openAdd">&#xe646;</span> -->
          <i
            class="el-icon-circle-plus"
            style="font-size: 40px"
@@ -74,15 +72,7 @@
                <span class="enable" v-if="!showJPGArr" @click="editHeadPic"
                  >编辑头像</span
                >
                <!-- <span
                  class="enable"
                  v-if="addForm.headpic"
                  @click="confirmChangePic"
                  >确认选择</span
                >
                <span class="enable" v-if="showJPGArr" @click="cacelChoosePic">
                  å–消</span
                > -->
              </div>
            </div>
            <div class="user-desc">
@@ -366,12 +356,6 @@
          </div>
          <div class="adjust-zone">
            <!-- <el-radio-group v-model="ajustType"
            fill="#4E94FF"
            >
                  <el-radio-button label="手动校时"></el-radio-button>
                  <el-radio-button label=""></el-radio-button>
                </el-radio-group> -->
            <div class="two-radio">
              <div
                class="radio"
@@ -624,7 +608,6 @@
      :class="showRecomand ? 'border-change' : ''"
      @click.stop
    >
      <!-- @blur="showRecomand = false" -->
      <el-input
        class="search-input"
        placeholder="查找设置"
@@ -660,7 +643,6 @@
        :key="i"
      >
        <div class="child-info">
          <!-- <span class="icon iconfont welcome-icon">{{ item.icon }}</span> -->
          <img :src="item.imgUrl" alt="" />
          <span class="welcome-title">{{ item.name }}</span>
        </div>
@@ -752,7 +734,6 @@
      browserTimer: null,
      timezone: "",
      showRecomand: false,
      searchArr: [
        { name: "账户", addr: [0] },
        { name: "通用设置", addr: [5] },
@@ -786,7 +767,6 @@
      isSetPermission: false,
      timeInterval: 10,
      ntpServer: "",
      // syncType: "1",
      equipmentTime: "",
      equipmentDate: "",
      roleList: [],
@@ -847,7 +827,6 @@
      ],
      accountArr: [],
      jpgArr: [],
      isManual: true,
      isNtp: false,
      activeIndex: 0,
      clockTimer: null,
@@ -904,9 +883,9 @@
  beforeDestroy() {
    clearTimeout(this.clockTimer);
    clearInterval(this.browserTimer);
    if (this.$refs.curPage) {
      this.$refs.curPage.removeEventListener("click");
    }
    // if (this.$refs.curPage) {
    //   this.$refs.curPage.removeEventListener("click");
    // }
  },
  mounted() {
    const menu = getUrlKey("menu");
@@ -1017,7 +996,6 @@
        case "hrs":
          num = +this.syncHour - 1;
          if (num == -1) {
            æœ‰çº¿ç½‘络有线网络;
            num = 23;
          }
          this.syncHour = pad0(+num);
@@ -1175,18 +1153,18 @@
        }
      );
    },
    flatCheckedArr(arr, res) {
      for (const item of arr) {
        if (item.selected) res.push(item.id);
        if (item.children) this.flatCheckedArr(item.children, res);
      }
    },
    // flatCheckedArr(arr, res) {
    //   for (const item of arr) {
    //     if (item.selected) res.push(item.id);
    //     if (item.children) this.flatCheckedArr(item.children, res);
    //   }
    // },
    saveAuth() {
      let arr = [];
      this.flatCheckedArr(this.sysMenus, arr);
      // let arr = [];
      // this.flatCheckedArr(this.sysMenus, arr);
      updataUser({
        id: this.activeAccountItem.id,
        menuIds: arr,
        menuIds: this.$refs.treeMenus.getCheckedKeys(),
      }).then((res) => {
        if (res.success) {
          this.$message.success(res.msg);
@@ -1218,9 +1196,7 @@
        if (rsp && rsp.success) {
          this.timezone = rsp.data.time_zone;
          if (!ntpTest) {
            // this.syncType = rsp.data.ntp ? "1" : "2";
            this.isNtp = rsp.data.ntp;
            this.isManual = !rsp.data.ntp;
          }
          if (rsp.data.ntp) {
            this.ntpServer = rsp.data.ntp_server;
@@ -1232,7 +1208,7 @@
            "日一二三四五六".charAt(new Date(+this.timestamp * 1000).getDay());
          if (this.clockTimer === null) {
            this.runClock();
            if (this.isManual) this.parseTime();
            if (!this.isNtp) this.parseTime();
          }
        }
      });
@@ -1313,9 +1289,6 @@
        this.openWelcome(addr[0]);
        this.$nextTick(() => {
          if (addr[0] == 1) {
            // addr[1] == 0
            //   ? this.changeSwitch("isNtp")
            //   : this.changeSwitch("isManual");
            return;
          }
          this.$refs[`view_${addr[0]}`].openRight(addr[1]);
@@ -1570,7 +1543,6 @@
  .search-box {
    width: 332px;
    z-index: 999;
    // margin: 55px auto;
    position: fixed;
    left: calc(50% - 166px);
    top: 50px;
@@ -1653,9 +1625,6 @@
        font-weight: bold;
        color: #4e94ff;
      }
      // .res-bar:last-child {
      //   border-radius: 0 0 20px 20px;
      // }
    }
  }
  .nav-items {
@@ -1674,11 +1643,9 @@
      align-items: center;
      cursor: pointer;
      // box-shadow: 2px 2px 4px rgb(226, 226, 226);
      .child-info {
        display: flex;
        flex-direction: column;
        // justify-content: space-around;
        height: 100%;
        .welcome-icon {
          font-size: 72px;
@@ -1697,11 +1664,7 @@
        }
      }
    }
    .nav-child:hover {
      // box-shadow: 4px 4px 12px rgb(218, 218, 218);
      // transform: translate3d(0, -1px, 0);
      // transition: all 0.3s;
    }
  }
}
.container {
@@ -1713,7 +1676,6 @@
  box-sizing: border-box;
  background-color: #fff;
  border-top: 1px solid #e1e0e6;
  .container-left {
    height: 100%;
    width: 244px;
@@ -1721,7 +1683,6 @@
    box-sizing: border-box;
    flex-shrink: 0;
    padding: 10px;
    // border-right: 5px solid rgba(248, 248, 248, 1);
    box-sizing: border-box;
    .left-card {
      height: 56px;
@@ -1731,11 +1692,7 @@
      display: flex;
      align-items: center;
      padding: 0 20px;
      // .iconfont {
      //   margin-left: 25px;
      //   margin-right: 10px;
      //   font-size: 24px;
      // }
      .card-text {
        margin-left: 20px;
        color: #333333;
@@ -1825,7 +1782,6 @@
          color: #333333;
          transform: scale(0.833333);
          line-height: 22.21px;
          // border: 1px solid var(--colorCard) ;
          span {
            font-size: 13px;
          }
@@ -1859,7 +1815,6 @@
          margin: 0 auto;
          display: flex;
          flex-direction: column;
          // margin-bottom: 80px;
          align-items: center;
          .touxiang-big {
            width: 100px;
@@ -2009,22 +1964,23 @@
      .change-pw {
        padding: 40px 10px;
    max-width: 600px;
    margin: 0 auto;
        max-width: 600px;
        margin: 0 auto;
        .title {
          font-weight: bold;
          font-size: 16px;
          line-height: 22px;
          color: #333333;    margin-bottom: 40px;
              height: 28px;
    display: flex;
    align-items: center;
    justify-content: center;
          .icon{
    font-size: 28px;
    font-weight: normal;margin-right: 10px;
          color: #333333;
          margin-bottom: 40px;
          height: 28px;
          display: flex;
          align-items: center;
          justify-content: center;
          .icon {
            font-size: 28px;
            font-weight: normal;
            margin-right: 10px;
          }
        }
        .el-form-item__content {
          line-height: 48px;
@@ -2059,12 +2015,16 @@
        .el-form-item {
          .el-input__inner {
            background-color: #ffffff;
            border: none;
            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;
@@ -2081,11 +2041,11 @@
          }
        }
        .p-title {
           height: 48px;
            text-align: left;
            line-height: 48px;
            width: 90px;
            font-weight: 600;
          height: 48px;
          text-align: left;
          line-height: 48px;
          width: 90px;
          font-weight: 600;
        }
      }
      .el-form-item {
@@ -2132,8 +2092,8 @@
            color: #333;
            height: 100%;
            overflow: auto;
                max-width: 600px;
    margin: 0 auto;
            max-width: 600px;
            margin: 0 auto;
            .el-tree-node {
              background: initial;
              .el-tree-node__content {
@@ -2271,14 +2231,18 @@
          }
          .el-form-item {
            .el-input__inner {
              background-color: #ffffff;
              border: none;
              border-radius: 20px;
              height: 32px;
              padding: 0 15px;
              font-size: 14px;
              font-weight: bold;
            }
            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;
@@ -2534,7 +2498,8 @@
                border-radius: 20px;
                width: 68px;
                color: #333;
                font-weight: bold;padding: 6px 20px;
                font-weight: bold;
                padding: 6px 20px;
              }
            }
          }
@@ -2573,7 +2538,6 @@
      }
      .ip-input-container {
        max-width: none !important;
        display: inline-block;
        width: 336px;
        height: 34px;
        line-height: normal;
@@ -2585,7 +2549,9 @@
        border: 2px solid transparent;
      }
    }
    .btns {
  }
      .btns {
      margin: 0 auto;
      margin-top: 40px;
      width: fit-content;
@@ -2613,7 +2579,6 @@
        font-size: 16px;
      }
    }
  }
  .container-right-for-account {
    background: #fbfaff;
    padding: 0;
src/pages/settings/views/NetSettings.vue
@@ -10,11 +10,11 @@
          @click="openRight(i)"
          ref="leftbar"
        >
          <div>
          <div class="item-left">
            <span class="icon iconfont">{{ item.icon }}</span>
          <span class="text">{{ item.name }}</span>
            <span class="text">{{ item.name }}</span>
          </div>
          <span v-if="showStatus && i==2" class="status">已连接</span>
          <!-- <span v-if="showStatus && i == 2" class="status">已连接</span> -->
        </div>
      </div>
      <div class="net-right">
@@ -25,9 +25,9 @@
            :rules="rules"
            ref="joinForm"
            class="join-form"
            label-width="150px"
          >
            <el-form-item label="设备名称" prop="deviceName">
            <el-form-item prop="deviceName">
              <div class="p-title">设备名称</div>
              <el-input
                v-model="ruleForm.deviceName"
                size="small"
@@ -35,7 +35,8 @@
              ></el-input>
            </el-form-item>
            <el-form-item label="端口" prop="port">
            <el-form-item prop="port">
              <div class="p-title">端口</div>
              <el-input
                v-model="ruleForm.port"
                placeholder="选填,外部访问的端口"
@@ -43,10 +44,15 @@
              ></el-input>
            </el-form-item>
          </el-form>
          <div class="save-btn" @click="saveServerName">保存</div>
          <!-- <div class="save-btn" @click="saveServerName">保存</div> -->
          <div class="btns">
            <div class="ok" @click="saveServerName">保存</div>
          </div>
        </div>
        <div class="wifi" v-if="activePage == 1 && !inWifiDetail">
        <div class="wifi-set" v-if="activePage == 1 && !inWifiDetail">
          <div class="title">无线网络</div>
          <switchBar
            :barName="`无线网卡`"
            @switchChange="wifiControl"
@@ -55,167 +61,190 @@
          <div class="wifi-option" v-for="(item, i) in wifiList" :key="i">
            <div class="name">
              <span class="icon iconfont">&#xe646;</span>
              <span>{{ item.name }}</span>
              <span class="icon iconfont" v-if="item.isConnected"
                >&#xe676;</span
              >
              <span
                :style="!item.isConnected ? { 'margin-left': '24px' } : {}"
                >{{ item.name }}</span
              >
            </div>
            <div class="more-detail">
              <span class="icon iconfont">&#xe676;</span>
              <span
                class="icon iconfont"
                style="margin-left: 10px; cursor: pointer"
                @click="checkWifi(item)"
              <span class="icon iconfont lock">&#xe726;</span>
              <span class="icon iconfont signal">&#xe6e5;</span>
              <span class="icon iconfont more-icon" @click="checkWifi(item)"
                >&#xe640;</span
              >
            </div>
          </div>
        </div>
        <div class="wifi-detail" v-if="activePage == 2 && inWifiDetail">
        <div class="wifi-detail" v-if="activePage == 1 && inWifiDetail">
          <div class="title">无线网络</div>
          <div class="btns">
            <div class="left">删除</div>
            <div class="right">断开连接</div>
            <div class="cancel">删除</div>
            <div class="ok">断开连接</div>
          </div>
          <div class="title">通用</div>
          <div class="general-box">
            <div class="in-title">通用</div>
          <el-form
            :model="wifiForm"
            :rules="wifiFormRules"
            ref="wifiForm"
            class="join-form"
            label-width="150px"
          >
            <el-form-item label="名称" prop="name">
              <div class="wifi-name">{{ 12123 }}</div>
            </el-form-item>
            <el-form
              :model="wifiForm"
              :rules="wifiFormRules"
              ref="wifiForm"
              class="join-form"
            >
              <el-form-item prop="name">
                <div class="p-title">名称</div>
                <!-- <div class="wifi-name">{{ 12123 }}</div> -->
                <el-input
                  v-model="wifiForm.name"
                  placeholder=""
                  size="small"
                ></el-input>
              </el-form-item>
            <el-form-item label="密码" prop="password">
              <el-input
                v-model="wifiForm.password"
                placeholder="请输入密码"
                size="small"
                show-password
              ></el-input>
            </el-form-item>
          </el-form>
              <el-form-item prop="password">
                <div class="p-title">密码</div>
                <el-input
                  v-model="wifiForm.password"
                  placeholder="请输入密码"
                  size="small"
                  show-password
                ></el-input>
              </el-form-item>
            </el-form>
          </div>
          <switchBar
            :barName="`高级设置`"
            @switchChange="highClassSetting"
            :value="isHighClass"
          ></switchBar>
          <div class="title">IPV4</div>
          <el-form
            :model="ipv4Form"
            :rules="ipv4FormRules"
            ref="ipv4Form"
            label-width="150px"
          >
            <el-form-item label="方法">
              <el-select v-model="value" placeholder="请选择" size="small">
                <el-option
                  v-for="item in options"
                  :key="item.value"
                  :label="item.label"
                  :value="item.value"
                ></el-option>
              </el-select>
            </el-form-item>
            <el-form-item label="IP" prop="ip">
              <ip-input
                :ip="ipv4Form.ip"
                @on-blur="ipv4Form.ip = arguments[0]"
              ></ip-input>
            </el-form-item>
            <el-form-item label="子网掩码" prop="subMask">
              <ip-input
                :ip="ipv4Form.subMask"
                @on-blur="ipv4Form.subMask = arguments[0]"
              ></ip-input>
            </el-form-item>
          <div class="general-box">
            <div class="in-title">IPV4</div>
            <el-form-item label="网关" prop="gateway">
              <ip-input
                :ip="ipv4Form.gateway"
                @on-blur="ipv4Form.gateway = arguments[0]"
              ></ip-input>
            </el-form-item>
            <el-form-item label="首选DNS" prop="dns">
              <ip-input
                :ip="ipv4Form.dns1"
                @on-blur="ipv4Form.dns1 = arguments[0]"
              ></ip-input>
            </el-form-item>
            <el-form-item label="备用DNS" prop="dns">
              <ip-input
                :ip="ipv4Form.dns2"
                @on-blur="ipv4Form.dns2 = arguments[0]"
              ></ip-input>
            </el-form-item>
          </el-form>
            <el-form :model="ipv4Form" :rules="ipv4FormRules" ref="ipv4Form">
              <el-form-item>
                <div class="p-title">方法</div>
                <el-select v-model="value" placeholder="请选择" size="small">
                  <el-option
                    v-for="item in options"
                    :key="item.value"
                    :label="item.label"
                    :value="item.value"
                  ></el-option>
                </el-select>
              </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>
              </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>
              </el-form-item>
          <div class="title">IPV6</div>
              <el-form-item prop="gateway">
                <div class="p-title">网关</div>
                <ip-input
                  :ip="ipv4Form.gateway"
                  @on-blur="ipv4Form.gateway = arguments[0]"
                ></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>
              </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>
              </el-form-item>
            </el-form>
          </div>
          <el-form
            :model="ipv6Form"
            :rules="ipv6FormRules"
            ref="ipv4Form"
            label-width="150px"
          >
            <el-form-item label="方法">
              <el-select v-model="value" placeholder="请选择" size="small">
                <el-option
                  v-for="item in options"
                  :key="item.value"
                  :label="item.label"
                  :value="item.value"
                ></el-option>
              </el-select>
            </el-form-item>
            <el-form-item label="IP地址" prop="ip">
              <ip-input
                :ip="ipv6Form.ip"
                @on-blur="ipv6Form.ip = arguments[0]"
              ></ip-input>
            </el-form-item>
            <el-form-item label="前缀" prop="subMask">
              <div style="display: flex">
                <el-input
                  v-model="wifiForm.password"
                  placeholder
                  size="small"
                ></el-input>
          <div class="general-box">
            <div class="in-title">IPV6</div>
                <div class="ad">-</div>
                <div class="ad">+</div>
                <div class="ad">重置</div>
              </div>
            </el-form-item>
            <el-form :model="ipv6Form" :rules="ipv6FormRules" ref="ipv4Form">
              <el-form-item>
                <div class="p-title">方法</div>
                <el-select v-model="value" placeholder="请选择" size="small">
                  <el-option
                    v-for="item in options"
                    :key="item.value"
                    :label="item.label"
                    :value="item.value"
                  ></el-option>
                </el-select>
              </el-form-item>
              <el-form-item prop="ip">
                <div class="p-title">IP</div>
                <ip-input
                  :ip="ipv6Form.ip"
                  @on-blur="ipv6Form.ip = arguments[0]"
                ></ip-input>
              </el-form-item>
              <el-form-item prop="subMask">
                <div class="p-title">前缀</div>
                <div style="display: flex; width: 100%">
                  <el-input
                    v-model="wifiForm.password"
                    placeholder
                    size="small"
                  ></el-input>
            <el-form-item label="网关" prop="gateway">
              <ip-input
                :ip="ipv6Form.gateway"
                @on-blur="ipv6Form.gateway = arguments[0]"
              ></ip-input>
            </el-form-item>
            <el-form-item label="首选DNS" prop="dns">
              <ip-input
                :ip="ipv6Form.dns1"
                @on-blur="ipv6Form.dns1 = arguments[0]"
              ></ip-input>
            </el-form-item>
            <el-form-item label="备用DNS" prop="dns">
              <ip-input
                :ip="ipv6Form.dns2"
                @on-blur="ipv6Form.dns2 = arguments[0]"
              ></ip-input>
            </el-form-item>
          </el-form>
                  <div class="ad">
                    <i class="el-icon-remove-outline"></i>
                  </div>
                  <div class="ad">
                    <i class="el-icon-circle-plus-outline"></i>
                  </div>
                  <div class="ad"><i class="el-icon-refresh-left"></i></div>
                </div>
              </el-form-item>
              <el-form-item prop="gateway">
                <div class="p-title">网关</div>
                <ip-input
                  :ip="ipv6Form.gateway"
                  @on-blur="ipv6Form.gateway = arguments[0]"
                ></ip-input>
              </el-form-item>
              <el-form-item prop="dns">
                <div class="p-title">首选DNS</div>
                <ip-input
                  :ip="ipv6Form.dns1"
                  @on-blur="ipv6Form.dns1 = arguments[0]"
                ></ip-input>
              </el-form-item>
              <el-form-item prop="dns">
                <div class="p-title">备用DNS</div>
                <ip-input
                  :ip="ipv6Form.dns2"
                  @on-blur="ipv6Form.dns2 = arguments[0]"
                ></ip-input>
              </el-form-item>
            </el-form>
          </div>
          <div class="btns">
            <div class="left" @click="inWifiDetail = false">取消</div>
            <div class="right">保存</div>
            <div class="cancel" @click="inWifiDetail = false">取消</div>
            <div class="ok">保存</div>
          </div>
        </div>
@@ -230,53 +259,60 @@
            <div class="name">{{ "网络" + item.index }}</div>
            <div class="right">
              <span class="icon iconfont good" v-if="item.lower_up&&item.active"
              <span
                class="icon iconfont good"
                v-if="item.lower_up && item.active"
                >&#xe6f1;</span
              >
              <span class="icon iconfont bad" v-if="!item.lower_up&&item.active">&#xe6e6;</span>
              <span
                class="icon iconfont bad"
                v-if="!item.lower_up && item.active"
                >&#xe6e6;</span
              >
              <el-switch
                v-model="item.active"
                active-color="rgba(61, 104, 225, 1)"
                active-color="#4E94FF"
                @change="switchNetCard(item)"
                :width="30"
              ></el-switch>
            </div>
          </div>
        </div>
        <div class="wire-detail" v-if="activePage == 2 && inWireDetail">
          <div class="title">网络设置</div>
          <el-form
            :model="wireForm"
            :rules="wireFormRules"
            ref="wireForm"
            label-width="150px"
          >
            <el-form-item label="网络名称" prop="name">
          <el-form :model="wireForm" :rules="wireFormRules" ref="wireForm">
            <el-form-item  prop="name">
                <div class="p-title">网络名称</div>
              <div class="wifi-name">{{ "网络" + activeWireItem.index }}</div>
            </el-form-item>
            <el-form-item label="网卡" prop="ifname">
            <el-form-item  prop="ifname">
                <div class="p-title">网卡</div>
              <div class="wifi-name">{{ activeWireItem.name }}</div>
            </el-form-item>
            <el-form-item label="IP" prop="ip">
            <el-form-item  prop="ip">
                <div class="p-title">IP</div>
              <ip-input
                :ip="wireForm.ip"
                @on-blur="wireForm.ip = arguments[0]"
              ></ip-input>
            </el-form-item>
            <el-form-item label="子网掩码" prop="subMask">
            <el-form-item prop="subMask">
                <div class="p-title">子网掩码</div>
              <ip-input
                :ip="wireForm.subMask"
                @on-blur="wireForm.subMask = arguments[0]"
              ></ip-input>
            </el-form-item>
            <el-form-item label="网关" prop="gateway">
            <el-form-item  prop="gateway">
                <div class="p-title">网关</div>
              <ip-input
                :ip="wireForm.gateway"
                @on-blur="wireForm.gateway = arguments[0]"
              ></ip-input>
            </el-form-item>
            <el-form-item label="DNS" prop="dns">
            <el-form-item  prop="dns">
                <div class="p-title">DNS</div>
              <ip-input
                :ip="wireForm.dns"
                @on-blur="wireForm.dns = arguments[0]"
@@ -305,7 +341,7 @@
  upNetCard,
} from "@/api/system";
import ipInput from "@/components/subComponents/IPInput";
import ipInput from "../components/IPInput";
import switchBar from "../components/switchBar";
export default {
@@ -338,7 +374,10 @@
      },
      wireArr: [],
      inWifiDetail: false,
      wifiList: [{ name: "无线网络1" }, { name: "无线网络2" }],
      wifiList: [
        { name: "无线网络1", isConnected: false },
        { name: "无线网络2", isConnected: true },
      ],
      isOpenWifi: false,
      inWireDetail: false,
      wireForm: {
@@ -359,12 +398,21 @@
      ipv6Form: {},
      ipv4FormRules: {},
      tabList: [
        { name: "网络设置", icon: "\ue6ed" },
        { name: "无线网络", icon: "\ue991" },
        { name: "有线网络", icon: "\ue6dd" },
        { name: "网络设置", icon: "\ue6dd" },
        { name: "无线网络", icon: "\uea13" },
        { name: "有线网络", icon: "\ue73b" },
      ],
      ipv6FormRules: {},
      options: [],
      options: [
        {
          value: "选项1",
          label: "自动",
        },
        {
          value: "选项2",
          label: "手动",
        },
      ],
      value: "",
    };
  },
@@ -503,9 +551,9 @@
    },
  },
  computed: {
    showStatus(){
      return this.wireArr.some((item) => item.lower_up==true)
    }
    showStatus() {
      return this.wireArr.some((item) => item.lower_up == true);
    },
  },
};
</script>
@@ -518,6 +566,17 @@
    font-size: 16px;
    margin-bottom: 10px;
  }
  .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;    display: flex;
        }
  .btns {
    display: flex;
    justify-content: space-between;
@@ -539,8 +598,10 @@
  }
}
.net-set {
  max-width: 600px;
  margin: 0 auto;
  .title {
       font-size: 16px;
    font-size: 16px;
    margin-bottom: 10px;
    height: 30px;
    line-height: 30px;
@@ -562,41 +623,44 @@
  flex: 1;
  flex-basis: auto;
  box-sizing: border-box;
  background-color: #fbfaff;
  .net-center {
    height: 100%;
    width: 280px;
    width: 300px;
    overflow: auto;
    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;
      height: 50px;
      margin-bottom: 10px;
      background: #f2f2f7;
      height: 56px;
      margin-bottom: 4px;
      border-radius: 8px;
      line-height: 50px;
      line-height: 56px;
      box-sizing: border-box;
      font-size: 14px; cursor: pointer;
      font-size: 14px;
      cursor: pointer;
      padding: 0 20px;
      display: flex;
      justify-content: space-between;
      .item-left {
        display: flex;
        align-items: center;
      }
      .icon {
        margin-right: 8px;
        font-size: 18px;
        font-size: 23px;
      }
      .text {
        font-size: 15px;
        font-weight: bold;
        font-size: 16px;
      }
    }
    .menu-item-active {
      background-color: var(--colorCard);
      color: white;
    }
    .menu-item:hover {
      background-color: var(--colorCard);
      color: white;
      color: #ffffff;
    }
  }
  .net-right {
@@ -605,7 +669,14 @@
    overflow: auto;
    box-sizing: border-box;
    position: relative;
    padding: 20px 40px;
    padding: 10px;
    .title {
      height: 48px;
      font-size: 16px;
      line-height: 48px;
      color: #333333;
      font-weight: bold;
    }
    .el-form-item.is-required:not(.is-no-asterisk)
      > .el-form-item__label:before,
    .el-form-item.is-required:not(.is-no-asterisk)
@@ -616,47 +687,172 @@
    .el-select {
      width: 100%;
    }
    .el-form-item__label{
      font-size: 15px;
    }
    .el-form-item {
      margin-bottom: 10px;
      height: 54px;
      padding: 6px 20px;
      background: #f8f8f8;
      box-sizing: border-box;
      border-radius: 10px;
      .el-form-item__label {
        text-align: left;
        line-height: 42px;
      }
      margin-bottom: 16px;
    }
    .el-form-item__content {
      line-height: 40px;
      position: relative;
          .el-input--small {
    font-size: 15px;
}
      line-height: 48px;
      display: flex;
      align-items: center;
      background: #f2f2f7;
      border-radius: 8px;
      padding: 0 15px 0 20px;
      .el-input.is-active .el-input__inner,
      .el-input__inner:focus {
        border: 2px solid #409eff !important;
      }
      .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__error {
      line-height: 0.7;
      left: 20px;
    }
    .p-title {
      height: 48px;
      text-align: left;
      line-height: 48px;
      width: 90px;
      font-weight: 600;
    }
    .el-form-item {
      .el-input__inner {
        background-color: #ffffff;
        border: 2px solid transparent;
        border-radius: 20px;
        height: 32px;
        padding: 0 15px;
        font-size: 14px;
        line-height: 32px;
        font-weight: bold;
      }
      .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;
      }
    }
    .ip-input-container {
      max-width: none !important;
    }
    .wifi {
    .wifi-set {
      max-width: 600px;
      margin: 0 auto;
      .switch-bar {
        background: #f2f2f7;
        padding: 0 20px;
      }
      .switch-bar .name {
        font-size: 14px;
        color: #333;
        font-weight: bold;
      }
      .wifi-option {
        height: 50px;
        background-color: #f8f8f8;
        height: 48px;
        line-height: 48px;
        display: flex;
        justify-content: space-between;
        align-items: center;
        box-sizing: border-box;
        padding: 0 20px;
        margin-bottom: 10px;
        background: #f2f2f7;
        border-radius: 8px;
        .name {
          font-size: 14px;
          color: #333;
          font-weight: bold;
          .icon {
            color: #4e94ff;
            margin-right: 8px;
            font-size: 16px;
          }
        }
        .more-detail {
          display: flex;
          align-items: center;
          .signal {
            margin-right: 10px;
            font-size: 20px;
          }
          .lock {
            font-size: 20px;
            margin-right: 10px;
          }
          .more-icon {
            font-weight: bold;
            cursor: pointer;
          }
        }
      }
    }
    .wifi-detail {
      max-width: 600px;
      margin: 0 auto;
      .general-box {
        background: #f2f2f7;
        border-radius: 8px;
        padding-bottom: 10px;
        margin-bottom: 20px;
        .el-form-item {
          margin-bottom: 0px;
        }
        .in-title {
          text-align: left;
          padding: 14px 20px;
          font-weight: bold;
          font-size: 14px;
          color: #333333;
        }
        .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;
        }
      }
      .switch-bar {
        margin-bottom: 0;
      }
      .switch-bar .name {
        font-size: 14px;
        color: #4f4f4f;
        font-weight: bold;
      }
      .btns {
        margin-top: 0;
        display: flex;
        justify-content: space-between;
        margin-bottom: 20px;
        .left {
          background-color: rgba(240, 240, 240, 1);
          height: 40px;
@@ -674,31 +870,31 @@
        }
      }
      .wifi-name {
        height: 40px;
        height: 48px;
        background-color: #f0f0f0;
        text-align: left;
        box-sizing: border-box;
        padding: 0 20px;
        padding: 0 10px;
        line-height: 48px;
      }
      .ad {
        min-width: 35px;
        background-color: rgba(240, 240, 240, 1);
        height: 35px;
        margin: 4px 0px 4px 5px;
        border-radius: 5px;
        line-height: 35px;
        height: 32px;
        /* margin: 4px 0px 4px 5px; */
        /* border-radius: 5px; */
        line-height: 31px;
        /* width: 27px; */
        text-align: center;
        font-size: 17px;
        /* font-weight: bold; */
        margin-left: 10px;
        cursor: pointer;
      }
    }
    .wire {
      .title {
        line-height: 30px;
        height: 30px;
        font-size: 16px;
        margin-bottom: 10px;
      }
      .wire-bar {
        height: 50px;
        background-color: #f8f8f8;
        height: 48px;
        background-color: #f2f2f7;
        cursor: pointer;
        display: flex;
        justify-content: space-between;
@@ -706,23 +902,46 @@
        box-sizing: border-box;
        padding: 0 20px;
        margin-bottom: 10px;
        border-radius: 10px;
        border-radius: 8px;
        .name {
          font-size: 15px;
          font-weight: bold;
          font-size: 14px;
          color: #333333;
        }
        .right {
          display: flex;
          align-items: center;
          .el-switch__core {
            height: 14px;
          }
          .el-switch.is-checked .el-switch__core::after {
            left: 100%;
            margin-left: -12px;
          }
          .el-switch__core:after {
            content: "";
            position: absolute;
            top: 0px;
            left: 1px;
            border-radius: 100%;
            -webkit-transition: all 0.3s;
            transition: all 0.3s;
            width: 12px;
            height: 12px;
            background-color: #fff;
          }
          .icon {
            margin-right: 15px;
          }
          .good {
            color: #3d68e1;
            font-size: 18px;
            color: #4e94ff;
            font-size: 16px;
          }
          .bad {
            color: rgb(243, 105, 54);
            font-size: 18px;
            color: #f44620;
            font-size: 16px;
          }
        }
      }
@@ -733,18 +952,6 @@
        box-sizing: border-box;
        padding: 0 20px;
      }
    }
    .save-btn {
      background-color: #3d68e1;
      width: 240px;
      height: 40px;
      margin: 0 auto;
      border-radius: 10px;
      color: #fff;
      line-height: 40px;
      cursor: pointer;
      font-size: 14px;
      margin-top: 30px;
    }
  }
}
src/pages/settings/views/clusterManagement.vue
@@ -1,9 +1,12 @@
<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">
@@ -22,32 +25,34 @@
            >&#xe60c;</span
          >
          <span
            class="icon iconfont" style="font-size:21px;"
            class="icon iconfont"
            style="font-size: 18px"
            @click="clearInput(1)"
            v-show="isFillingName"
            >&#xe649;</span
            >&#xe785;</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"
            >&#xe62a;</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>
@@ -65,25 +70,29 @@
            >&#xe60c;</span
          >
          <span
            class="icon iconfont" style="font-size:21px;"
            class="icon iconfont"
            style="font-size: 18px"
            @click="clearInput(2)"
            v-show="isFillingIp"
            >&#xe649;</span
            >&#xe785;</span
          >
          <span
            class="icon iconfont"
            @click="updateCluster(2)" style="font-size:20px;"
            @click="updateCluster(2)"
            style="font-size: 20px; color: #4e94ff"
            v-show="isFillingIp"
            >&#xe62a;</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' : ''"
@@ -91,25 +100,24 @@
          :key="i"
          @click="openRight(i)"
        >
          <span class="icon iconfont" v-if="activePage == 0">&#xe73c;</span>
          <span class="icon iconfont" v-if="activePage == 1">&#xe721;</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="不允许输入,保存后回显"
@@ -117,7 +125,8 @@
                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位密码,或点击生成"
@@ -128,7 +137,8 @@
                >
              </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"
@@ -136,7 +146,9 @@
              ></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">
@@ -145,14 +157,16 @@
            :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地址"
@@ -160,7 +174,8 @@
                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="请输入集群密码"
@@ -186,8 +201,9 @@
              </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>
@@ -207,7 +223,7 @@
  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 {
@@ -224,11 +240,11 @@
        }
      }, 1000);
    };
    const checkID= (rule, value, callback) => {
    const checkID = (rule, value, callback) => {
      if (!value) {
        return callback(new Error("密码不能为空"));
      }
    }
    };
    return {
      innerNodes: [],
      intervalTimer: null,
@@ -338,9 +354,12 @@
      });
    },
    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;
@@ -405,7 +424,7 @@
        this.stopSearch();
      }, 10 * 1000);
    },
    openRight( i) {
    openRight(i) {
      this.activePage = i;
    },
    async stopSearch() {
@@ -457,7 +476,28 @@
      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 ? "成功" : "失败",
@@ -472,14 +512,16 @@
            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) {
@@ -509,7 +551,7 @@
      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 === "") {
@@ -527,6 +569,7 @@
      if (res.success) {
        this.findCluster();
      }
      this.$notify({
        title: res.success ? "成功" : "失败",
        message: res.msg,
@@ -575,32 +618,92 @@
<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;
      }
    }
  }
@@ -624,6 +727,8 @@
  flex: 1;
  flex-basis: auto;
  box-sizing: border-box;
  background: #fbfaff;
  .cluster-center {
    height: 100%;
    width: 280px;
@@ -631,26 +736,29 @@
    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;
@@ -666,26 +774,84 @@
      > .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;
src/pages/settings/views/generalSettings.vue
@@ -139,7 +139,7 @@
          </div>
          <div class="bar-group">
            <div
              class="bar"
              class="general-bar"
              v-for="(item, i) in soundList"
              :key="i"
              @click="clickSound(item, i)"
@@ -148,7 +148,7 @@
              <div class="left-part">
                <span class="name">{{ item.name }}</span>
              </div>
              <div class="btns">
              <div class="sound-btns">
                <span @click="togglePlay(item, i)">
                  <span
                    class="iconfont"
@@ -665,6 +665,7 @@
      }
      .bar-group {
        overflow: auto;
<<<<<<< HEAD
        height: 400px;
      }
      .bar {
@@ -684,10 +685,30 @@
        }
        .btns {
          width: 52px;
=======
        height: 520px;
        .general-bar {
          height: 48px;
          background-color: #f8f8f8;
          border-radius: 10px;
          line-height: 48px;
          box-sizing: border-box;
          padding: 0 20px 0 20px;
          font-weight: 700;
>>>>>>> 0892efe5131551631fe287cfda29e59e4f2f6707
          display: flex;
          justify-content: space-between;
          color: rgba(191, 191, 191, 1);
          /*  .el-icon-video-pause {
          margin-bottom: 2px;
          border: 2px solid #fff;
          .name {
            font-size: 14px;
          }
          .sound-btns {
            width: 52px;
            display: flex;
            justify-content: space-between;
            color: rgba(191, 191, 191, 1);
            /*  .el-icon-video-pause {
            cursor: pointer;
            font-size: 23px;
            vertical-align: middle;
@@ -699,18 +720,20 @@
            vertical-align: middle;
            color: #409eff;
          } */
          span {
            color: #333;
            span {
              color: #333;
            }
            .del:hover {
              color: #fc4958;
            }
          }
          .del:hover {
            color: #fc4958;
          .desc {
            font-size: 14px;
            color: rgba(134, 134, 134, 1);
          }
        }
        .desc {
          font-size: 14px;
          color: rgba(134, 134, 134, 1);
        }
      }
      /* .bar:hover {
        border: 2px solid #4E94FF !important;
      } */
src/pages/systemMonitor/index/App.vue
@@ -1,38 +1,99 @@
<template>
  <div class="s-system-monitor">
    <el-tabs id="systemMonitor" v-model="activeName">
      <el-tab-pane label="单元" name="proc">
        <div class="form-title">
          <b>算法单元</b>
          (正在进行{{algoProcessData.length}}个算法单元)
          <el-table :data="algoProcessData" style="width: 100%">
            <el-table-column prop="desc" label="名称" width="180"></el-table-column>
      <el-tab-pane name="proc">
        <span slot="label">
          <span class="iconfont icon">&#xe742;</span>
          å•å…ƒ</span
        >
        <div class="left-tab">
          <div
            class="tab-item"
            :class="activeTab == 0 ? 'tab-item-active' : ''"
            @click="activeTab = 0"
          >
            <div class="title">算法单元</div>
            <div class="subtitle">
              æ­£åœ¨è¿›è¡Œ{{ algoProcessData.length }}个算法单元
            </div>
            <span class="iconfont icon" :style="activeTab == 0 ? {} :{color:'#fff'} ">&#xe741;</span>
          </div>
          <div
            class="tab-item"
            :class="activeTab == 1 ? 'tab-item-active' : ''"
            @click="activeTab = 1"
          >
            <div class="title">应用单元</div>
            <div class="subtitle">正在进行{{ 1 }}个应用单元</div>
            <span class="iconfont icon" :style="activeTab == 1 ? {} :{color:'#fff'} ">&#xe744;</span>
          </div>
        </div>
        <div class="form-title" v-if="activeTab == 0">
          <div class="desc">
            <b>算法单元</b>
            (正在进行{{ algoProcessData.length }}个算法单元)
          </div>
          <el-table
            :data="algoProcessData"
            style="width: 100%"
            :header-cell-style="'background: #F2F2F7;color: #333333;height: 40px;font-size: 16px;'"
            stripe
            class="tableBox"
          >
            <el-table-column
              prop="desc"
              label="名称"
              width="180"
            ></el-table-column>
            <el-table-column label="CPU" width="180">
              <template slot-scope="scope">
                <span>{{ scope.row.cpu.toFixed(2)}} %</span>
                <span>{{ scope.row.cpu.toFixed(2) }} %</span>
              </template>
            </el-table-column>
            <el-table-column label="内存">
              <template slot-scope="scope">
                <span>{{ scope.row.mem.toFixed(2)}} %</span>
                <span>{{ scope.row.mem.toFixed(2) }} %</span>
              </template>
            </el-table-column>
            <el-table-column prop="disk" label="硬盘"></el-table-column>
            <el-table-column label="算力">
              <template slot-scope="scope">
                <span>{{ scope.row.gpu}} M</span>
                <span>{{ scope.row.gpu }} M</span>
              </template>
            </el-table-column>
            <el-table-column prop="net" label="网络"></el-table-column>
          </el-table>
        </div>
        <div class="form-title" style="margin-top:20px">
          <b>应用单元</b>
          (正在进行{{appProcessData.length}}个应用单元)
          <el-table :data="appProcessData" style="width: 100%">
            <el-table-column prop="desc" label="名称" width="180"></el-table-column>
            <el-table-column prop="cpu" label="CPU" width="180"></el-table-column>
        <div class="form-title" v-if="activeTab == 1">
          <div class="desc">
            <b>应用单元</b>
            (正在进行{{ appProcessData.length }}个算法单元)
          </div>
          <el-table
            :data="appProcessData"
            style="width: 100%"
            :header-cell-style="{
              background: '#F2F2F7',
              color: '#333333',
              height: '40px',
            }"
            stripe
            class="tableBox"
          >
            <el-table-column
              prop="desc"
              label="名称"
              width="180"
            ></el-table-column>
            <el-table-column
              prop="cpu"
              label="CPU"
              width="180"
            ></el-table-column>
            <el-table-column prop="mem" label="内存"></el-table-column>
            <el-table-column prop="disk" label="硬盘"></el-table-column>
            <el-table-column prop="gpu" label="算力"></el-table-column>
@@ -41,54 +102,79 @@
        </div>
      </el-tab-pane>
      <el-tab-pane label="性能" name="top">
      <el-tab-pane  name="top">
        <span slot="label">
          <span class="iconfont icon">&#xe743;</span>
          æ€§èƒ½</span
        >
        <div class="column-left" ref="left">
          <div class="resize-bar">
            <div
              :class="['ax_default', activeChartItem == 'cpu' ?'selected': '']"
              :class="[
                'ax_default',
                activeChartItem == 'cpu' ? 'selected' : '',
              ]"
              @click="setActiveChartItem('cpu')"
            >
              <div class="ax_default_pic color-cpu"></div>
              <div class="ax_default_text">CPU</div>
              <div class="ax_default_subtext">{{cpuUsedPercent}}%</div>
              <div>
                <div class="ax_default_text">CPU</div>
              <div class="ax_default_subtext">{{ cpuUsedPercent }}%</div>
              </div>
            </div>
            <div
              :class="['ax_default', activeChartItem == 'mem' ?'selected': '']"
              :class="[
                'ax_default',
                activeChartItem == 'mem' ? 'selected' : '',
              ]"
              @click="setActiveChartItem('mem')"
            >
              <div class="ax_default_pic color-mem"></div>
              <div class="ax_default_text">内存</div>
              <div class="ax_default_subtext">{{memUsedPercent}}%</div>
              <div><div class="ax_default_text">内存</div>
              <div class="ax_default_subtext">{{ memUsedPercent }}%</div></div>
            </div>
            <div
              :class="['ax_default', activeChartItem == 'gpu' ?'selected': '']"
              :class="[
                'ax_default',
                activeChartItem == 'gpu' ? 'selected' : '',
              ]"
              @click="setActiveChartItem('gpu')"
            >
              <div class="ax_default_pic color-gpu"></div>
              <div class="ax_default_text">算力</div>
              <div class="ax_default_subtext">{{gpuUsedPercent}}%</div>
             <div> <div class="ax_default_text">算力</div>
              <div class="ax_default_subtext">{{ gpuUsedPercent }}%</div></div>
            </div>
            <div
              :class="['ax_default', activeChartItem == 'net' ?'selected': '']"
              :class="[
                'ax_default',
                activeChartItem == 'net' ? 'selected' : '',
              ]"
              @click="setActiveChartItem('net')"
            >
              <div class="ax_default_pic color-net"></div>
              <div class="ax_default_text">网络</div>
              <div class="ax_default_subtext">{{netSend | byteConver}} / {{netRecive | byteConver}}</div>
             <div> <div class="ax_default_text">网络</div>
              <div class="ax_default_subtext">
                {{ netSend | byteConver }} / {{ netRecive | byteConver }}
              </div></div>
            </div>
            <div
              v-for="(v, k) in disks"
              :key="k"
              :class="['ax_default', activeChartItem == ('disk|' + k) ?'selected': '']"
              @click="setActiveChartItem('disk|'+k)"
              :class="[
                'ax_default',
                activeChartItem == 'disk|' + k ? 'selected' : '',
              ]"
              @click="setActiveChartItem('disk|' + k)"
            >
              <div class="ax_default_pic color-disk"></div>
              <div class="ax_default_text">磁盘 {{k}}</div>
              <div class="ax_default_subtext">{{v.info.total | byteConver}}</div>
              <div><div class="ax_default_text">磁盘 {{ k }}</div>
              <div class="ax_default_subtext">
                {{ v.info.total | byteConver }}
              </div></div>
            </div>
          </div>
@@ -96,92 +182,96 @@
        </div>
        <div class="column-right">
          <div class="max-val">{{yAxisMaxVal}}</div>
          <div class="max-val">{{ yAxisMaxVal }}</div>
          <div ref="graphs" class="graphs-chart"></div>
          <div v-show="activeChartItem == 'cpu'">
            <div class="ax_default_label">
              <b>占用率</b>
              <p>{{cpuUsedPercent}}%</p>
              <p>{{ cpuUsedPercent }}%</p>
            </div>
            <div class="ax_default_label">
              <b>主频</b>
              <p>{{cpuMaxRate}}Ghz</p>
              <p>{{ cpuMaxRate }}Ghz</p>
            </div>
            <div class="ax_default_label">
              <b>插槽</b>
              <p>{{cpuCount}}</p>
              <p>{{ cpuCount }}</p>
            </div>
            <div class="ax_default_label">
              <b>内核</b>
              <p>{{cpuCore}}</p>
              <p>{{ cpuCore }}</p>
            </div>
          </div>
          <div v-show="activeChartItem == 'mem'">
            <div class="ax_default_label">
              <b>使用中</b>
              <p>{{memUsed}}G</p>
              <p>{{ memUsed }}G</p>
            </div>
            <div class="ax_default_label">
              <b>已缓存</b>
              <p>{{memCache}}G</p>
              <p>{{ memCache }}G</p>
            </div>
            <div class="ax_default_label">
              <b>可用</b>
              <p>{{memFree}}G</p>
              <p>{{ memFree }}G</p>
            </div>
          </div>
          <div v-show="activeChartItem == 'net'">
            <div class="ax_default_label">
              <b>接收</b>
              <p>{{netRecive |byteConver}}</p>
              <p>{{ netRecive | byteConver }}</p>
            </div>
            <div class="ax_default_label">
              <b>发送</b>
              <p>{{netSend |byteConver}}</p>
              <p>{{ netSend | byteConver }}</p>
            </div>
            <div class="ax_default_label">
              <b>IP地址</b>
              <p>{{ipAddr}}</p>
              <p>{{ ipAddr }}</p>
            </div>
            <div class="ax_default_label" style="margin-left: 19px;">
            <div class="ax_default_label" style="margin-left: 19px">
              <b>MAC地址</b>
              <p>{{macAddr}}</p>
              <p>{{ macAddr }}</p>
            </div>
          </div>
          <div v-show="isDisk">
            <div class="ax_default_label">
              <b>容量</b>
              <p>{{activeDisk.total |byteConver}}</p>
              <p>{{ activeDisk.total | byteConver }}</p>
            </div>
            <div class="ax_default_label">
              <b>已用</b>
              <p>{{activeDisk.used |byteConver}}</p>
              <p>{{ activeDisk.used | byteConver }}</p>
            </div>
            <div class="ax_default_label">
              <b>可用</b>
              <p>{{activeDisk.free |byteConver}}</p>
              <p>{{ activeDisk.free | byteConver }}</p>
            </div>
            <div class="ax_default_label">
              <b>读取速度</b>
              <p>{{ioRead | byteConver}}</p>
              <p>{{ ioRead | byteConver }}</p>
            </div>
            <div class="ax_default_label">
              <b>写入速度</b>
              <p>{{ioWrite | byteConver}}</p>
              <p>{{ ioWrite | byteConver }}</p>
            </div>
          </div>
        </div>
      </el-tab-pane>
      <el-tab-pane label="服务" name="service">
      <el-tab-pane name="service">
        <span slot="label">
          <span class="iconfont icon">&#xe944;</span>
          æœåŠ¡</span
        >
        <el-table :data="vasystemServicesData">
          <el-table-column label="名称" show-overflow-tooltip>
            <template slot-scope="scope">
              <span>{{ scope.row.name}}</span>
              <span>{{ scope.row.name }}</span>
            </template>
          </el-table-column>
          <el-table-column label="状态" prop="status">
@@ -198,52 +288,54 @@
<script>
import echarts from "echarts";
import { showSystemStates, showService, showProcesses } from "../api/api"
import { showSystemStates, showService, showProcesses } from "../api/api";
export default {
  components: {
  },
  components: {},
  computed: {
    isDisk() {
      return this.activeChartItem.indexOf("disk") == 0
      return this.activeChartItem.indexOf("disk") == 0;
    },
    isAdmin() {
      if (
        sessionStorage.getItem('userInfo') &&
        sessionStorage.getItem('userInfo') !== ''
        sessionStorage.getItem("userInfo") &&
        sessionStorage.getItem("userInfo") !== ""
      ) {
        let loginName = JSON.parse(sessionStorage.getItem('userInfo')).username
        return (
          loginName === 'superadmin' || loginName === 'basic'
        )
        let loginName = JSON.parse(sessionStorage.getItem("userInfo")).username;
        return loginName === "superadmin" || loginName === "basic";
      }
      return false;
    }
    },
  },
  filters: {
    byteConver(limit) {
      var size = "";
      if (limit < 1024) { //如果小于0.1KB转化成B
      if (limit < 1024) {
        //如果小于0.1KB转化成B
        size = limit + "B";
      } else if (limit < 1024 * 1024) {//如果小于0.1MB转化成KB
      } else if (limit < 1024 * 1024) {
        //如果小于0.1MB转化成KB
        size = (limit / 1024).toFixed(2) + "KB";
      } else if (limit < 1024 * 1024 * 1024) { //如果小于0.1GB转化成MB
      } else if (limit < 1024 * 1024 * 1024) {
        //如果小于0.1GB转化成MB
        size = (limit / (1024 * 1024)).toFixed(2) + "MB";
      } else if (limit < 1024 * 1024 * 1024 * 1024) { //其他转化成GB
      } else if (limit < 1024 * 1024 * 1024 * 1024) {
        //其他转化成GB
        size = (limit / (1024 * 1024 * 1024)).toFixed(2) + "GB";
      } else {
        size = (limit / (1024 * 1024 * 1024 * 1024)).toFixed(2) + "TB";
      }
      var sizestr = size + "";
      var len = sizestr.indexOf("\.");
      var len = sizestr.indexOf(".");
      var dec = sizestr.substr(len + 1, 2);
      if (dec == "00") {//当小数点后为00时 åŽ»æŽ‰å°æ•°éƒ¨åˆ†
      if (dec == "00") {
        //当小数点后为00时 åŽ»æŽ‰å°æ•°éƒ¨åˆ†
        return sizestr.substring(0, len) + sizestr.substr(len + 3, 2);
      }
      return sizestr;
    }
    },
  },
  data() {
    return {
@@ -254,6 +346,7 @@
      appProcessData: [],
      vasystemServicesData: [],
      eChartsObj: {},
      activeTab: 0,
      eChartsBaseOpt: {
        title: {
          top: 10,
@@ -261,12 +354,12 @@
        animation: false,
        grid: {
          show: true,
          left: '1%',
          right: '4%',
          bottom: '3%',
          left: "1%",
          right: "4%",
          bottom: "3%",
          containLabel: true,
          borderWidth: 2,
          borderColor: '#000'
          borderColor: "#000",
        },
        xAxis: {
          type: "category",
@@ -274,43 +367,43 @@
          data: Array.from({ length: 60 }, () => 0),
          // show: false,
          axisLabel: {
            show: false
            show: false,
          },
          axisTick: {
            show: false
            show: false,
          },
          splitLine: {
            show: true,
            interval: 5,
            lineStyle: {
              width: 1,
              type: 'solid'
            }
          }
              type: "solid",
            },
          },
        },
        yAxis: {
          type: 'value',
          type: "value",
          // show: false,
          axisLine: {
            show: false
            show: false,
          },
          axisLabel: {
            show: false
            show: false,
          },
          axisTick: {
            show: false
          }
            show: false,
          },
        },
        series: [
          {
            type: 'line',
            symbol: 'none',
            type: "line",
            symbol: "none",
            data: Array.from({ length: 60 }, () => 0),
            // smooth: true,
            itemStyle: {},
            areaStyle: {}
          }
        ]
            areaStyle: {},
          },
        ],
      },
      cpuUtilizations: Array.from({ length: 60 }, () => 0),
      memUtilizations: Array.from({ length: 60 }, () => 0),
@@ -337,7 +430,7 @@
      disks: {},
      activeDisk: {},
      ioRead: 0,
      ioWrite: 0
      ioWrite: 0,
    };
  },
  mounted() {
@@ -351,41 +444,42 @@
      this.procCollect();
      setTimeout(() => {
        this.dataCollection();
      }, 5000)
      }, 5000);
    },
    serviceCollect() {
      showService().then(rsp => {
        if (rsp && rsp.success) {
          rsp.data.sort(function (obj1, obj2) {
            var val1 = obj1.name
            var val2 = obj2.name
            if (val1 < val2) {
              return -1
            } else if (val1 > val2) {
              return 1
            } else {
              return 0
            }
          })
          this.vasystemServicesData = rsp.data;
        }
      }).catch(() => { })
      showService()
        .then((rsp) => {
          if (rsp && rsp.success) {
            rsp.data.sort(function (obj1, obj2) {
              var val1 = obj1.name;
              var val2 = obj2.name;
              if (val1 < val2) {
                return -1;
              } else if (val1 > val2) {
                return 1;
              } else {
                return 0;
              }
            });
            this.vasystemServicesData = rsp.data;
          }
        })
        .catch(() => {});
    },
    procCollect() {
      showProcesses().then(rsp => {
        if (rsp && rsp.success) {
          if (rsp.data.algos)
            this.algoProcessData = rsp.data.algos;
      showProcesses()
        .then((rsp) => {
          if (rsp && rsp.success) {
            if (rsp.data.algos)
              this.algoProcessData = [...rsp.data.algos, ...rsp.data.algos];
          if (rsp.data.apps)
            this.appProcessData = rsp.data.apps;
        }
      }).catch(() => { })
            if (rsp.data.apps) this.appProcessData = rsp.data.apps;
          }
        })
        .catch(() => {});
    },
    getSystemState() {
      showSystemStates().then(rsp => {
      showSystemStates().then((rsp) => {
        if (rsp && rsp.success) {
          // å¤„理cpu
          this.cpuUtilizations = this.cpuUtilizations.slice(1);
@@ -394,8 +488,12 @@
          if (rsp.data.cpu_info) {
            this.cpuMaxRate = (rsp.data.cpu_info[0].mhz / 1024).toFixed(2);
            this.cpuModel = rsp.data.cpu_info[0].modelName;
            this.cpuCore = Number(rsp.data.cpu_info[rsp.data.cpu_info.length - 1].coreId) + 1;
            this.cpuCount = (rsp.data.cpu_info.length / this.cpuCore).toFixed(0);
            this.cpuCore =
              Number(rsp.data.cpu_info[rsp.data.cpu_info.length - 1].coreId) +
              1;
            this.cpuCount = (rsp.data.cpu_info.length / this.cpuCore).toFixed(
              0
            );
          }
          // å†…å­˜
@@ -404,7 +502,12 @@
          this.memTotal = (rsp.data.mem.total / 1024 / 1024 / 1000).toFixed(0);
          this.memUsed = (rsp.data.mem.used / 1024 / 1024 / 1000).toFixed(2);
          this.memFree = (rsp.data.mem.free / 1024 / 1024 / 1000).toFixed(2);
          this.memCache = ((rsp.data.mem.cached + rsp.data.mem.buffers) / 1024 / 1024 / 1000).toFixed(2);
          this.memCache = (
            (rsp.data.mem.cached + rsp.data.mem.buffers) /
            1024 /
            1024 /
            1000
          ).toFixed(2);
          this.memUsedPercent = rsp.data.mem.usedPercent.toFixed(2);
          // ç®—力
@@ -436,47 +539,54 @@
            } else {
              return 0;
            }
          })
          });
          rsp.data.disk.forEach(d => {
          rsp.data.disk.forEach((d) => {
            if (d.name in this.disks) {
              this.disks[d.name].readBytes = this.disks[d.name].readBytes.slice(1);
              this.disks[d.name].readBytes = this.disks[d.name].readBytes.slice(
                1
              );
              this.disks[d.name].readBytes.push(d.readBytes);
              this.disks[d.name].writeBytes = this.disks[d.name].writeBytes.slice(1);
              this.disks[d.name].writeBytes = this.disks[
                d.name
              ].writeBytes.slice(1);
              this.disks[d.name].writeBytes.push(d.writeBytes);
            } else {
              this.disks[d.name] = {};
              this.disks[d.name]["info"] = d.info;
              this.disks[d.name]["readBytes"] = Array.from({ length: 60 }, () => 0);
              this.disks[d.name]["writeBytes"] = Array.from({ length: 60 }, () => 0);
              this.disks[d.name]["readBytes"] = Array.from(
                { length: 60 },
                () => 0
              );
              this.disks[d.name]["writeBytes"] = Array.from(
                { length: 60 },
                () => 0
              );
            }
          });
          // this.disks = rsp.data.disk;
        }
        this.setChartData();
        setTimeout(() => {
          this.getSystemState();
        }, 1000)
      })
        }, 1000);
      });
    },
    isShow(authority) {
      if (this.isAdmin) {
        return true
      } else if (
        this.buttonAuthority.indexOf(',' + authority + ',') > -1
      ) {
        return true
        return true;
      } else if (this.buttonAuthority.indexOf("," + authority + ",") > -1) {
        return true;
      } else {
        return false
        return false;
      }
    },
    format(array) {
      return [
        this.$moment(array[0]).format("YYYY-MM-DD"),
        this.$moment(array[1]).format("YYYY-MM-DD")
        this.$moment(array[1]).format("YYYY-MM-DD"),
      ];
    },
    setActiveChartItem(item) {
@@ -491,7 +601,7 @@
    setChartData() {
      let option = JSON.parse(JSON.stringify(this.eChartsBaseOpt));
      switch (this.activeChartItem) {
        case 'cpu':
        case "cpu":
          this.yAxisMaxVal = this.cpuModel;
          option.title.text = "CPU";
          option.title.subtext = "%占用率";
@@ -503,7 +613,7 @@
          option.series[0].data = this.cpuUtilizations;
          break;
        case 'mem':
        case "mem":
          this.yAxisMaxVal = this.memTotal + "G";
          option.title.text = "内存";
          option.title.subtext = "内存使用量";
@@ -514,7 +624,7 @@
          option.series[0].areaStyle.color = "#f7bb88";
          option.series[0].data = this.memUtilizations;
          break;
        case 'gpu':
        case "gpu":
          this.yAxisMaxVal = "100%";
          option.title.text = "算力";
          option.title.subtext = "%使用率";
@@ -525,7 +635,7 @@
          option.series[0].areaStyle.color = "#de9dff";
          option.series[0].data = this.gpuUtilizations;
          break;
        case 'net':
        case "net":
          this.yAxisMaxVal = "";
          option.title.text = "网络";
          option.title.subtext = "网络负载";
@@ -534,17 +644,17 @@
          option.series[0].areaStyle.color = "#d68658";
          option.series[0].data = this.netReciveCount;
          option.series.push({
            type: 'line',
            symbol: 'none',
            type: "line",
            symbol: "none",
            data: this.netSendCount,
            // smooth: true,
            itemStyle: {
              color: "#4696da"
              color: "#4696da",
            },
            areaStyle: {
              color: "#4eacfd"
            }
          })
              color: "#4eacfd",
            },
          });
          break;
        default:
          if (this.activeChartItem.indexOf("disk|") == 0) {
@@ -558,17 +668,17 @@
            option.series[0].areaStyle.color = "#4eacfd";
            option.series[0].data = this.disks[dev].readBytes;
            option.series.push({
              type: 'line',
              symbol: 'none',
              type: "line",
              symbol: "none",
              data: this.disks[dev].writeBytes,
              // smooth: true,
              itemStyle: {
                color: "#33ff66"
                color: "#33ff66",
              },
              areaStyle: {
                color: "#33cc66"
              }
            })
                color: "#33cc66",
              },
            });
            this.activeDisk = this.disks[dev].info;
            this.ioRead = this.disks[dev].readBytes[59];
@@ -578,9 +688,8 @@
      }
      this.eChartsObj.setOption(option);
    }
  }
    },
  },
};
</script>
<style lang="scss">
@@ -588,12 +697,187 @@
  width: 100% !important;
  min-width: 759px;
  box-sizing: border-box;
  padding: 10px;
  // background-color: #e9ebf2;
  background-color: #fff;
  height: 100%;
  .el-table th.el-table__cell.is-leaf,
  .el-table td.el-table__cell {
    border-bottom: none;
  }
  .el-table--enable-row-hover .el-table__body tr:hover > td {
    background-color: #4e94ff !important;
    color: #fff;
  }
  .el-table th.el-table__cell > .cell {
    text-align: center;
  }
  .tableBox {
    .el-table td.el-table__cell {
      border-bottom: none;
    }
    .el-table--striped
      .el-table__body
      tr.el-table__row--striped
      td.el-table__cell {
      background: #f8f8ff;
    }
    th {
      padding: 0 !important;
      height: 40px;
      line-height: 40px;
      border-radius: 4px;
    }
    td {
      padding: 0 !important;
      height: 40px;
      line-height: 40px;
    }
  }
  .el-tabs--top {
    height: 100%;
    background: #f2f2f7;
    padding: 4px;
    box-sizing: border-box;
  }
  #systemMonitor .el-tabs__header {
    background: #fff;
    border-radius: 4px;
    background-image: url("/images/systemMonitor/Group 224.png");
    background-repeat: no-repeat;
    background-size: 116px;
    background-position: top 15px right 18px;
  }
  .el-tabs__nav-wrap {
    padding: 25px 20px;
  }
  #systemMonitor .el-tabs__active-bar {
    /* background-color: #ff7733; */
    visibility: hidden;
  }
  #systemMonitor .el-tabs__content {
    padding: 0px !important;
    height: calc(100% - 97px);
    width: calc(100% - 0px);
    .el-tab-pane {
      width: 100%;
      display: flex;
      height: 100%;
      .form-title {
        text-align: left;
        font-size: 14px;
        width: calc(100% - 200px);
        padding: 10px;
        box-sizing: border-box;
        .desc {
          font-size: 16px;
          line-height: 22px;
          color: #4e94ff;
          margin-left: 10px;
          margin-bottom: 5px;
        }
      }
    }
  }
  .left-tab {
    width: 200px;
    height: 100%;
    border-radius: 4px;
    background: #ffffff;
    padding: 20px;
    border-radius: 4px;
    box-sizing: border-box;
    .tab-item {
      width: 160px;
      height: 85px;
      /* left: 24px; */
      color: #333333;
      /* top: 158px; */
      background: #f8f8ff;
      cursor: pointer;
      border: 2px solid transparent;
      border-radius: 8px;
      margin-bottom: 20px;
      padding: 12px;
      box-sizing: border-box;
      text-align: left;
      position: relative;
      .title {
        font-weight: bold;
        font-size: 16px;
        line-height: 22px;
        margin-bottom: 4px;
      }
      .subtitle {
           font-size: 12px;
    line-height: 17px;
    z-index: 99;
    position: absolute;
      }
      .icon{
    color: #6da3f3;
    font-size: 60px;
    position: absolute;
    bottom: 4px;
    right: 4px;
      }
    }
    .tab-item-active {
      background-color: #4e94ff;
      color: #fff;
    }
    .tab-item:hover {
      border: 2px solid #4e94ff;
    }
  }
  .el-tabs__header {
    margin: 0;
  }
  .el-tabs__nav-wrap::after {
    content: "";
    position: absolute;
    left: 0;
    bottom: 0;
    width: 100%;
    height: 3px;
    background-color: #f2f2f7;
    z-index: 1;
  }
  .form-title {
    text-align: left;
    font-size: 14px;
    margin-left: 4px;
    background: #fff;
  }
  #systemMonitor .el-tabs__header .el-tabs__item:nth-child(2) {
    padding-left: 39px;
  }
  #systemMonitor .el-tabs__header .el-tabs__item {
    padding: 0 39px;
    height: 40px;
    background: #f8f8ff;
    font-family: PingFangSC-Regular;
    font-size: 14px;
    font-weight: bold;
    font-size: 16px;
    color: #222222;
    text-align: center;
    border: 0px solid transparent;
    margin-right: 2px;
  }
  #systemMonitor .el-tabs__header .el-tabs__item:not(.is-disabled):hover {
    color: initial;
  }
  #systemMonitor .el-tabs__header .el-tabs__item.is-active {
    border: none;
    /* font-weight: bold; */
    background: #4e94ff;
    color: #fff !important;
  }
  .graphs-chart {
@@ -622,8 +906,8 @@
  }
  .resize-bar {
    width: 238px;
    height: 610px;
       width: 285px;
height: 600px;
  }
  /* æ‹–拽线 */
@@ -638,28 +922,38 @@
  }
  .ax_default {
    width: 207px;
    height: 45px;
   width: 270px;
    height: 70px;
    padding: 10px;
    font-size: 15px;
    font-size: 14px;
    margin: 5px;
    cursor: pointer;
    border-radius: 4px;
    box-sizing: border-box;
    display: flex;
    justify-content: space-between;
  }
  .selected {
    background: inherit;
    background-color: #cde8ff;
    // background: inherit;
    // background-color: #cde8ff;
    // border: none;
    // border-radius: 8px;
      background: inherit;
    background-color: #4E94FF;
    border: none;
    border-radius: 8px;
    color: #fff;
  }
  .ax_default_pic {
    position: absolute;
    // position: absolute;
    border-width: 0px;
    width: 66px;
    height: 45px;
       height: 50px;
    box-sizing: border-box;
    border: 1px solid rgba(255, 153, 0, 1);
    background-color: #fff;
    background-repeat: no-repeat;
    background-position: bottom;
  }
@@ -692,14 +986,13 @@
  .ax_default_text {
    position: relative;
    text-align: left;
    margin-left: 72px;
  font-size: 16px;
  }
  .ax_default_subtext {
    font-size: 13px;
    margin-left: 72px;
    line-height: 35px;
    color: #4e4d4d;
    text-align: left;
  }