From c83e653ebaef064b0741c1f35cf6576762ccbc68 Mon Sep 17 00:00:00 2001
From: heyujie <516346543@qq.com>
Date: 星期六, 10 七月 2021 16:30:14 +0800
Subject: [PATCH] 系统设置修改

---
 src/pages/systemSettings/components/ClusterManagement.vue              |  885 ++++++++++++
 src/pages/settings/index/App.vue                                       |  261 +--
 public/fonts/alibaba/iconfont.css                                      |    6 
 src/pages/systemSettings/components/AuthorityManagement.vue            |  265 +++
 src/pages/shuohuangMonitorAnalyze/components/searchForVideoAnalyze.vue |    2 
 src/pages/settings/views/NetSettings.vue                               |  241 ++
 src/pages/systemSettings/index/App.vue                                 |  161 ++
 src/pages/cameraAccess/components/SceneRule.vue                        |    1 
 src/pages/systemSettings/components/BasicSetting.vue                   | 1035 ++++++++++++++
 src/api/system.ts                                                      |   17 
 src/pages/systemSettings/components/RadioSet.vue                       |  189 ++
 src/pages/settings/views/generalSettings.vue                           |  251 ++-
 src/pages/systemSettings/components/SystemMaintenance.vue              |  514 +++++++
 src/pages/systemSettings/index/main.ts                                 |   12 
 src/pages/systemSettings/components/CloudNode.vue                      |  287 +++
 src/pages/systemSettings/components/LogManagement.vue                  |  190 ++
 16 files changed, 3,993 insertions(+), 324 deletions(-)

diff --git a/public/fonts/alibaba/iconfont.css b/public/fonts/alibaba/iconfont.css
index 8b90d46..4b9aafc 100644
--- a/public/fonts/alibaba/iconfont.css
+++ b/public/fonts/alibaba/iconfont.css
@@ -4,6 +4,12 @@
        url('iconfont.woff?t=1625566597355') format('woff'),
        url('iconfont.ttf?t=1625566597355') format('truetype');
 }
+@font-face {
+  font-family: 'iconfont';  /* Project id 1155353 */
+  src: url('//at.alicdn.com/t/font_1155353_peuhj1f227s.woff2?t=1625815343825') format('woff2'),
+       url('//at.alicdn.com/t/font_1155353_peuhj1f227s.woff?t=1625815343825') format('woff'),
+       url('//at.alicdn.com/t/font_1155353_peuhj1f227s.ttf?t=1625815343825') format('truetype');
+}
 
 .iconfont {
   font-family: "iconfont" !important;
diff --git a/src/api/system.ts b/src/api/system.ts
index 22c50bc..4683aef 100644
--- a/src/api/system.ts
+++ b/src/api/system.ts
@@ -135,6 +135,21 @@
   });
 };
 
+export const upNetCard = (query: any) => {
+  return request({
+    url: "/data/api-v/sysset/upNetCard",
+    method: "post",
+    data: qs.stringify(query)
+  });
+};
+export const downNetCard = (query: any) => {
+  return request({
+    url: "/data/api-v/sysset/downNetCard",
+    method: "post",
+    data: qs.stringify(query)
+  });
+};
+
 export const setServerName = (query: any) => {
   return request({
     url: "/data/api-v/sysset/setSerName",
@@ -239,4 +254,4 @@
     method: "get",
     params: query
   });
-};
\ No newline at end of file
+};
diff --git a/src/pages/cameraAccess/components/SceneRule.vue b/src/pages/cameraAccess/components/SceneRule.vue
index ba4bc75..e27037b 100644
--- a/src/pages/cameraAccess/components/SceneRule.vue
+++ b/src/pages/cameraAccess/components/SceneRule.vue
@@ -277,6 +277,7 @@
         })
         return false;
       }
+      debugger
       this.eventAudio.src = this.soundPath;
       if (this.togglePlay) {
         this.eventAudio.play();
diff --git a/src/pages/settings/index/App.vue b/src/pages/settings/index/App.vue
index 8d0114c..b935d5f 100644
--- a/src/pages/settings/index/App.vue
+++ b/src/pages/settings/index/App.vue
@@ -8,7 +8,7 @@
         :key="index"
         @click="openMenu(item.name, index)"
       >
-        <span class="icon iconfont">&#xe646;</span>
+        <span class="icon iconfont">{{ item.icon }}</span>
         <span class="card-text">{{ item.name }}</span>
       </div>
     </div>
@@ -35,10 +35,18 @@
               />
             </div>
             <span class="user-name">{{ item.username }}</span>
+            <el-tag
+              style="margin-left: 100px"
+              size="mini"
+              v-if="item.id == curUserID"
+              >鎴戠殑</el-tag
+            >
           </div>
         </div>
         <div class="add-account">
-          <span class="icon iconfont" @click="showAddAccount">&#xe646;</span>
+          <!-- <span class="icon iconfont" @click="openAdd">&#xe646;</span> -->
+          <i class="el-icon-circle-plus" style="font-size: 38px;
+" @click="openAdd"></i>
         </div>
       </div>
       <div class="datetime-left" v-if="activePage == '鏃ユ湡鏃堕棿'">
@@ -114,8 +122,10 @@
             </div>
             <div class="user-desc">
               <div class="username">
-                <span class="icon iconfont" style="margin-right: 5px"
-                  >&#xe690;</span
+                <span
+                  class="icon iconfont"
+                  style="font-size: 18px; margin-right: 3px"
+                  >&#xe6de;</span
                 >
                 <span>{{ activeAccountItem.username }}</span>
               </div>
@@ -124,32 +134,33 @@
                 <span v-show="!showInputNickName">{{
                   activeAccountItem.nickname
                 }}</span>
-                <!-- <input
-                  type="text"
-                  class="input-nick"
-                  ref="input-nick"
-                  v-show="showInputNickName"
-                  v-model="inputNickName"
-                  @blur="hideInputNick"
-                  @keydown.enter="blurInputNick"
-                /> -->
                 <el-input
                   size="mini"
                   v-model="inputNickName"
                   v-if="showInputNickName"
                 ></el-input>
-                <span v-show="!showInputNickName" class="icon iconfont" @click="editNickName"
+                <span
+                  v-show="!showInputNickName"
+                  class="icon iconfont"
+                  @click="editNickName"
                   >&#xe6f0;</span
                 >
-                 <span v-show="showInputNickName" class="icon iconfont" @click="showInputNickName=false"
+                <span
+                  v-show="showInputNickName"
+                  class="icon iconfont"
+                  @click="showInputNickName = false"
                   >&#xe61b;</span
                 >
-                 <span v-show="showInputNickName" class="icon iconfont" style="font-size:21px;font-weight:600;color:green;" @click="hideInputNick"
+                <span
+                  v-show="showInputNickName"
+                  class="icon iconfont"
+                  style="font-size: 21px; font-weight: 600; color: green"
+                  @click="hideInputNick"
                   >&#xe62a;</span
                 >
               </div>
               <div class="user-role">
-                {{ activeUserRole }}
+                <el-tag type="info" size="mini">{{ activeUserRole }}</el-tag>
               </div>
             </div>
           </div>
@@ -198,7 +209,10 @@
             ref="passwordForm"
             class="password-form"
           >
-            <el-form-item prop="curPassword">
+            <el-form-item
+              prop="curPassword"
+              v-if="activeAccountItem.id == curUserID"
+            >
               <div class="p-title">褰撳墠瀵嗙爜锛�</div>
 
               <el-input
@@ -286,14 +300,6 @@
                 <span class="icon iconfont enable">&#xe62a;</span>
               </div>
             </div>
-            <!-- <el-upload
-              class="upload-demo"
-              action="https://jsonplaceholder.typicode.com/posts/"
-              :show-file-list="false"
-              :http-request="uploadUserPic"
-            >
-              <div v-if="loadedPic == ''" class="upload-jpg-up">涓婁紶</div>
-            </el-upload> -->
           </div>
           <div class="fill-group">
             <el-form
@@ -549,42 +555,13 @@
     ></generalSettings>
   </div>
   <div class="welcome-page" v-else>
-    <div class="child" @click="openWelcome('璐︽埛', 0)">
+    <div class="child" @click="openWelcome(item, i)" v-for="(item,i) in menuArr" :key="i">
       <div class="child-info">
-        <span class="icon iconfont welcome-icon">&#xe6de;</span>
-        <span class="welcome-title">璐︽埛</span>
+        <span class="icon iconfont welcome-icon">{{ item.icon }}</span>
+        <span class="welcome-title">{{item.name}}</span>
       </div>
     </div>
-    <div class="child" @click="openWelcome('鏃ユ湡鏃堕棿', 1)">
-      <div class="child-info">
-        <span class="icon iconfont welcome-icon">&#xe6ff;</span>
-        <span class="welcome-title">鏃ユ湡鏃堕棿</span>
-      </div>
-    </div>
-    <div class="child" @click="openWelcome('闆嗙兢绠$悊', 2)">
-      <div class="child-info">
-        <span class="icon iconfont welcome-icon">&#xe6df;</span>
-        <span class="welcome-title">闆嗙兢绠$悊</span>
-      </div>
-    </div>
-    <div class="child" @click="openWelcome('缃戠粶璁剧疆', 3)">
-      <div class="child-info">
-        <span class="icon iconfont welcome-icon">&#xe6dd;</span>
-        <span class="welcome-title">缃戠粶璁剧疆</span>
-      </div>
-    </div>
-    <div class="child" @click="openWelcome('閿洏鍜岃瑷�', 4)">
-      <div class="child-info">
-        <span class="icon iconfont welcome-icon">&#xe6dc;</span>
-        <span class="welcome-title">閿洏鍜岃瑷�</span>
-      </div>
-    </div>
-    <div class="child" @click="openWelcome('閫氱敤璁剧疆', 5)">
-      <div class="child-info">
-        <span class="icon iconfont welcome-icon">&#xe6db;</span>
-        <span class="welcome-title">閫氱敤璁剧疆</span>
-      </div>
-    </div>
+
   </div>
 </template>
 
@@ -608,7 +585,6 @@
 import netSettings from "../views/NetSettings";
 import keyboardLanguage from "../views/keyboardLanguage";
 import generalSettings from "../views/generalSettings";
-import treeVue from "@/components/treeMenu/jsTree/tree.vue";
 export default {
   name: "settings",
   components: {
@@ -683,12 +659,12 @@
       settime: "",
       weekday: "",
       menuArr: [
-        { name: "璐︽埛" },
-        { name: "鏃ユ湡鏃堕棿" },
-        { name: "闆嗙兢绠$悊" },
-        { name: "缃戠粶璁剧疆" },
-        { name: "閿洏鍜岃瑷�" },
-        { name: "閫氱敤璁剧疆" },
+        { name: "璐︽埛", icon: "\ue6de" },
+        { name: "鏃ユ湡鏃堕棿", icon: "\ue6ff" },
+        { name: "闆嗙兢绠$悊", icon: "\ue6df" },
+        { name: "缃戠粶璁剧疆", icon: "\ue6dd" },
+        { name: "閿洏鍜岃瑷�", icon: "\ue6dc" },
+        { name: "閫氱敤璁剧疆", icon: "\ue6db" },
       ],
       accountArr: [],
       jpgArr: [],
@@ -776,9 +752,7 @@
         }
       });
     },
-    blurInputNick() {
-      this.$refs["input-nick"].blur();
-    },
+
     confirmChangePic() {
       updateUser({
         id: this.activeAccountItem.id,
@@ -794,7 +768,6 @@
     editNickName() {
       this.showInputNickName = true;
       this.inputNickName = this.activeAccountItem.nickname;
-      this.$refs["input-nick"].focus();
     },
     hideInputNick() {
       if (this.inputNickName == this.activeAccountItem.nickname) {
@@ -805,7 +778,7 @@
         id: this.activeAccountItem.id,
         nickname: this.inputNickName,
       }).then((res) => {
-        this.activeAccountItem.nickname = this.inputNickName
+        this.activeAccountItem.nickname = this.inputNickName;
         this.$message.success(res.msg);
         this.fetchUserList(true);
         this.showInputNickName = false;
@@ -881,8 +854,8 @@
       });
     },
     childrenChange(item) {
-      let isAllSelected = item.children.every((x) => x.selected == true);
-      item.selected = isAllSelected;
+      let SomeOneSelected = item.children.some((x) => x.selected == true);
+      item.selected = SomeOneSelected;
     },
     plusOne(typ) {
       this.isSyncBrowser = false;
@@ -1014,14 +987,6 @@
       n = n.toString();
       return n[1] ? n : "0" + n;
     },
-    // uploadUserPic(params) {
-    //   let param = new FormData();
-    //   param.append("file", params.file);
-    //   uploadHeadPic(param).then((res) => {
-    //     this.jpgArr.push(res.data);
-    //     this.loadedPic = res.data;
-    //   });
-    // },
     initClockConf(ntpTest = false) {
       getClockInfo().then((rsp) => {
         if (rsp && rsp.success) {
@@ -1050,9 +1015,9 @@
         this.initClockConf();
       }
     },
-    openWelcome(name, i) {
+    openWelcome(item, i) {
       this.showWelcome = false;
-      this.openMenu(name, i);
+      this.openMenu(item.name, i);
     },
     showInput(typ) {
       this[`show${typ}Input`] = true;
@@ -1087,11 +1052,11 @@
         }, 1000);
       }
     },
-    showAddAccount() {
+    openAdd() {
       this.inAccountDetail = false;
       this.isAddAccount = true;
       this.selectedPic = 0;
-      this.addForm.headpic = this.jpgArr[0];
+      this.addForm.headpic = this.jpgArr[0].path;
       getRoles().then((res) => {
         if (res.success) {
           this.roleList = res.data.slice(0, 2);
@@ -1116,12 +1081,21 @@
       this.showJPGArr = false;
     },
     SaveNewPassword(formName) {
+      let data;
       this.$refs[formName].validate((valid) => {
         if (valid) {
-          updatePassword({
-            oldPwd: this.passwordForm.curPassword,
-            newPwd: this.passwordForm.newPassword,
-          }).then(
+          if (this.passwordForm.curPassword == "") {
+            data = {
+              userId: this.activeAccountItem.id,
+              newPwd: this.passwordForm.newPassword,
+            };
+          } else {
+            data = {
+              oldPwd: this.passwordForm.curPassword,
+              newPwd: this.passwordForm.newPassword,
+            };
+          }
+          updatePassword(data).then(
             (res) => {
               if (res.success) {
                 this.$message.success(res.msg);
@@ -1129,7 +1103,7 @@
               }
             },
             (err) => {
-              this.$message.warning("淇濆瓨澶辫触锛�" + err.msg);
+              this.$message.error("淇濆瓨澶辫触锛�" + err.msg);
             }
           );
         }
@@ -1143,6 +1117,7 @@
             password: this.addForm.password,
             nickname: this.addForm.nickName,
             headpic: this.addForm.headpic,
+            roleId: this.addForm.roleId,
           };
           addUser(data).then(
             (res) => {
@@ -1150,7 +1125,7 @@
               this.fetchUserList(true);
             },
             (err) => {
-              this.$message.warning("淇濆瓨澶辫触锛�" + err.msg);
+              this.$message.error("淇濆瓨澶辫触锛�" + err.msg);
             }
           );
         } else {
@@ -1227,7 +1202,7 @@
                 message: "鍒犻櫎鎴愬姛!",
               });
             } else {
-              this.$message.warning("鍒犻櫎澶辫触");
+              this.$message.error("鍒犻櫎澶辫触");
             }
           });
         })
@@ -1275,6 +1250,10 @@
       const info = JSON.parse(sessionStorage.getItem("userInfo"));
       return info.roleName;
     },
+    curUserID() {
+      const info = JSON.parse(sessionStorage.getItem("userInfo"));
+      return info.id;
+    },
   },
 };
 </script>
@@ -1292,7 +1271,6 @@
     background-color: white;
     -webkit-box-flex: 0;
     -ms-flex: 0 0 33.3%;
-    /* flex: 0 0 16%; */
     float: left;
     width: 250px;
     height: 200px;
@@ -1373,12 +1351,16 @@
     border-right: 5px solid rgba(248, 248, 248, 1);
     box-sizing: border-box;
     .account-left {
+      .account-list{
+        height: 530px;
+        overflow: auto;
+      }
       .add-account {
         color: rgba(61, 104, 225, 1);
-        margin-top: 30px;
-        .iconfont {
+        margin-top: 15px;
+        .el-icon-circle-plus {
           cursor: pointer;
-          font-size: 32px;
+          font-size: 38px;
         }
       }
       .account-card {
@@ -1469,7 +1451,6 @@
     overflow: auto;
     box-sizing: border-box;
     position: relative;
-
     padding: 20px 40px;
     .account-right {
       .account-content {
@@ -1533,11 +1514,11 @@
             align-items: baseline;
             min-width: 200px;
             .username {
-                margin: 0 15px;
-    height: 28px;
-    line-height: 28px;
-    text-align: left;
-    font-size: 16px;
+              margin: 0 15px;
+              height: 28px;
+              line-height: 28px;
+              text-align: left;
+              font-size: 16px;
               display: flex;
               align-items: center;
             }
@@ -1551,10 +1532,7 @@
                 width: fit-content;
                 text-align: left;
               }
-              .input-nick {
-                width: 80px;
-                margin-right: 5px;
-              }
+
               .iconfont {
                 font-size: 14px;
                 margin-left: 5px;
@@ -1571,7 +1549,7 @@
             .user-role {
               margin: 5px 0 0 15px;
               font-size: 14px;
-              color: darkseagreen;
+              color: skyblue;
             }
           }
         }
@@ -1598,7 +1576,6 @@
       .title {
         height: 30px;
         line-height: 30px;
-        /* background-color: aliceblue; */
         margin-bottom: 10px;
         font-size: 16px;
         font-weight: 600;
@@ -1629,8 +1606,6 @@
           right: 1px;
           top: -0.5px;
           width: 45px;
-          // background-color: rgba(61, 104, 225, 1);
-          /* color: white; */
           border-radius: 12px;
         }
       }
@@ -1690,20 +1665,6 @@
         }
         .upload-jpg-border {
           border: 2px solid cornflowerblue;
-        }
-        .upload-jpg-up {
-          height: 48px;
-          width: 48px;
-          float: left;
-          display: flex;
-          background-color: rgba(242, 242, 242, 1);
-          border: 2px solid transparent;
-          border-radius: 50%;
-
-          justify-content: center;
-          align-items: center;
-          font-size: 12px;
-          cursor: pointer;
         }
       }
       .add-account-page {
@@ -1770,59 +1731,7 @@
             text-decoration: underline;
           }
         }
-        .ntp-bar {
-          height: 40px;
-          background-color: rgba(248, 248, 248, 1);
-          display: flex;
-          align-items: center;
-          justify-content: space-between;
-          padding: 0 10px;
-          border-radius: 10px;
-          margin-bottom: 10px;
-          .title {
-            min-width: 70px;
-          }
-          .input-area {
-            width: 450px;
-            height: 30px;
-            background-color: rgba(240, 240, 240, 1);
-            border-radius: 10px;
-            line-height: 30px;
-            font-size: 14px;
-          }
-        }
-        .int-bar {
-          height: 40px;
-          background-color: rgba(248, 248, 248, 1);
-          display: flex;
-          align-items: center;
-          justify-content: space-between;
-          padding: 0 10px;
-          border-radius: 10px;
-          margin-bottom: 10px;
-          .title {
-            min-width: 130px;
-          }
-          .right {
-            width: 450px;
-            display: flex;
-            align-items: center;
-            height: 30px;
 
-            .input-area {
-              // width: 410px;
-              background-color: rgba(240, 240, 240, 1);
-              border-radius: 10px;
-              line-height: 30px;
-              width: -webkit-fill-available;
-
-              font-size: 14px;
-            }
-            .test {
-              width: 40px;
-            }
-          }
-        }
       }
       .manual-time {
         .clock-wrap {
diff --git a/src/pages/settings/views/NetSettings.vue b/src/pages/settings/views/NetSettings.vue
index 15737bf..fad8495 100644
--- a/src/pages/settings/views/NetSettings.vue
+++ b/src/pages/settings/views/NetSettings.vue
@@ -27,18 +27,30 @@
             label-width="150px"
           >
             <el-form-item label="璁惧鍚嶇О" prop="deviceName">
-              <el-input v-model="ruleForm.deviceName" size="small" placeholder="蹇呭~"></el-input>
+              <el-input
+                v-model="ruleForm.deviceName"
+                size="small"
+                placeholder="蹇呭~"
+              ></el-input>
             </el-form-item>
 
             <el-form-item label="绔彛" prop="port">
-              <el-input v-model="ruleForm.port" placeholder="閫夊~锛屽閮ㄨ闂殑绔彛" size="small"></el-input>
+              <el-input
+                v-model="ruleForm.port"
+                placeholder="閫夊~锛屽閮ㄨ闂殑绔彛"
+                size="small"
+              ></el-input>
             </el-form-item>
           </el-form>
           <div class="save-btn" @click="saveServerName">淇濆瓨</div>
         </div>
 
         <div class="wifi" v-if="activePage == '鏃犵嚎缃戠粶' && !inWifiDetail">
-          <switchBar :barName="`鏃犵嚎缃戝崱`" @switchChange="wifiControl" :value="isOpenWifi"></switchBar>
+          <switchBar
+            :barName="`鏃犵嚎缃戝崱`"
+            @switchChange="wifiControl"
+            :value="isOpenWifi"
+          ></switchBar>
 
           <div class="wifi-option" v-for="(item, i) in wifiList" :key="i">
             <div class="name">
@@ -52,11 +64,15 @@
                 class="icon iconfont"
                 style="margin-left: 10px; cursor: pointer"
                 @click="checkWifi(item)"
-              >&#xe640;</span>
+                >&#xe640;</span
+              >
             </div>
           </div>
         </div>
-        <div class="wifi-detail" v-if="activePage == '鏃犵嚎缃戠粶' && inWifiDetail">
+        <div
+          class="wifi-detail"
+          v-if="activePage == '鏃犵嚎缃戠粶' && inWifiDetail"
+        >
           <div class="btns">
             <div class="left">鍒犻櫎</div>
             <div class="right">鏂紑杩炴帴</div>
@@ -76,14 +92,28 @@
             </el-form-item>
 
             <el-form-item label="瀵嗙爜" prop="password">
-              <el-input v-model="wifiForm.password" placeholder="璇疯緭鍏ュ瘑鐮�" size="small" show-password></el-input>
+              <el-input
+                v-model="wifiForm.password"
+                placeholder="璇疯緭鍏ュ瘑鐮�"
+                size="small"
+                show-password
+              ></el-input>
             </el-form-item>
           </el-form>
 
-          <switchBar :barName="`楂樼骇璁剧疆`" @switchChange="highClassSetting" :value="isHighClass"></switchBar>
+          <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
+            :model="ipv4Form"
+            :rules="ipv4FormRules"
+            ref="ipv4Form"
+            label-width="150px"
+          >
             <el-form-item label="鏂规硶">
               <el-select v-model="value" placeholder="璇烽�夋嫨" size="small">
                 <el-option
@@ -95,26 +125,46 @@
               </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>
+              <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>
+              <ip-input
+                :ip="ipv4Form.subMask"
+                @on-blur="ipv4Form.subMask = arguments[0]"
+              ></ip-input>
             </el-form-item>
 
             <el-form-item label="缃戝叧" prop="gateway">
-              <ip-input :ip="ipv4Form.gateway" @on-blur="ipv4Form.gateway = arguments[0]"></ip-input>
+              <ip-input
+                :ip="ipv4Form.gateway"
+                @on-blur="ipv4Form.gateway = arguments[0]"
+              ></ip-input>
             </el-form-item>
             <el-form-item label="棣栭�塂NS" prop="dns">
-              <ip-input :ip="ipv4Form.dns1" @on-blur="ipv4Form.dns1 = arguments[0]"></ip-input>
+              <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>
+              <ip-input
+                :ip="ipv4Form.dns2"
+                @on-blur="ipv4Form.dns2 = arguments[0]"
+              ></ip-input>
             </el-form-item>
           </el-form>
 
           <div class="title">IPV6</div>
 
-          <el-form :model="ipv6Form" :rules="ipv6FormRules" ref="ipv4Form" label-width="150px">
+          <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
@@ -126,11 +176,18 @@
               </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>
+              <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>
+                <el-input
+                  v-model="wifiForm.password"
+                  placeholder
+                  size="small"
+                ></el-input>
 
                 <div class="ad">-</div>
                 <div class="ad">+</div>
@@ -139,13 +196,22 @@
             </el-form-item>
 
             <el-form-item label="缃戝叧" prop="gateway">
-              <ip-input :ip="ipv6Form.gateway" @on-blur="ipv6Form.gateway = arguments[0]"></ip-input>
+              <ip-input
+                :ip="ipv6Form.gateway"
+                @on-blur="ipv6Form.gateway = arguments[0]"
+              ></ip-input>
             </el-form-item>
             <el-form-item label="棣栭�塂NS" prop="dns">
-              <ip-input :ip="ipv6Form.dns1" @on-blur="ipv6Form.dns1 = arguments[0]"></ip-input>
+              <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>
+              <ip-input
+                :ip="ipv6Form.dns2"
+                @on-blur="ipv6Form.dns2 = arguments[0]"
+              ></ip-input>
             </el-form-item>
           </el-form>
 
@@ -156,23 +222,37 @@
         </div>
 
         <div class="wire" v-if="activePage == '鏈夌嚎缃戠粶' && !inWireDetail">
-          <div class="wire-bar" v-for="(item, i) in wireArr" :key="i" @click.self="checkWire(item)">
+          <div class="title">鏈夌嚎缃戠粶</div>
+          <div
+            class="wire-bar"
+            v-for="(item, i) in wireArr"
+            :key="i"
+            @click.self="checkWire(item)"
+          >
             <div class="name">{{ "缃戠粶" + item.index }}</div>
 
             <div class="right">
-              <span class="icon iconfont">&#xe676;</span>
-
+              <span class="icon iconfont good" v-if="item.lower_up">&#xe6f1;</span>
+              <span class="icon iconfont bad" v-else>&#xe6e6;</span>
               <el-switch
                 v-model="item.active"
                 active-color="rgba(61, 104, 225, 1)"
-                @change="switchNetCard"
+                @change="switchNetCard(item)"
               ></el-switch>
             </div>
           </div>
         </div>
-        <div class="wire-detail" v-if="activePage == '鏈夌嚎缃戠粶' && inWireDetail">
+        <div
+          class="wire-detail"
+          v-if="activePage == '鏈夌嚎缃戠粶' && inWireDetail"
+        >
           <div class="title">缃戠粶璁剧疆</div>
-          <el-form :model="wireForm" :rules="wireFormRules" ref="wireForm" label-width="150px">
+          <el-form
+            :model="wireForm"
+            :rules="wireFormRules"
+            ref="wireForm"
+            label-width="150px"
+          >
             <el-form-item label="缃戠粶鍚嶇О" prop="name">
               <div class="wifi-name">{{ "缃戠粶" + activeWireItem.index }}</div>
             </el-form-item>
@@ -180,17 +260,29 @@
               <div class="wifi-name">{{ activeWireItem.name }}</div>
             </el-form-item>
             <el-form-item label="IP" prop="ip">
-              <ip-input :ip="wireForm.ip" @on-blur="wireForm.ip = arguments[0]"></ip-input>
+              <ip-input
+                :ip="wireForm.ip"
+                @on-blur="wireForm.ip = arguments[0]"
+              ></ip-input>
             </el-form-item>
             <el-form-item label="瀛愮綉鎺╃爜" prop="subMask">
-              <ip-input :ip="wireForm.subMask" @on-blur="wireForm.subMask = arguments[0]"></ip-input>
+              <ip-input
+                :ip="wireForm.subMask"
+                @on-blur="wireForm.subMask = arguments[0]"
+              ></ip-input>
             </el-form-item>
 
             <el-form-item label="缃戝叧" prop="gateway">
-              <ip-input :ip="wireForm.gateway" @on-blur="wireForm.gateway = arguments[0]"></ip-input>
+              <ip-input
+                :ip="wireForm.gateway"
+                @on-blur="wireForm.gateway = arguments[0]"
+              ></ip-input>
             </el-form-item>
             <el-form-item label="DNS" prop="dns">
-              <ip-input :ip="wireForm.dns" @on-blur="wireForm.dns = arguments[0]"></ip-input>
+              <ip-input
+                :ip="wireForm.dns"
+                @on-blur="wireForm.dns = arguments[0]"
+              ></ip-input>
             </el-form-item>
           </el-form>
 
@@ -226,12 +318,10 @@
   getWireList,
   setNetWorkCard,
   getNetWorkCardInfo,
-  getDevInfo,
+  getDevInfo,downNetCard,upNetCard,
 } from "@/api/system";
 
-import cloudNode from "../components/CloudNode";
 import ipInput from "@/components/subComponents/IPInput";
-import { isIPv4 } from "@/scripts/validate";
 import switchBar from "../components/switchBar";
 
 export default {
@@ -254,7 +344,6 @@
     };
     return {
       isHighClass: false,
-
       ruleForm: {
         deviceName: "",
         port: "",
@@ -306,7 +395,6 @@
     };
   },
   components: {
-    cloudNode,
     ipInput,
     switchBar,
   },
@@ -314,16 +402,29 @@
     this.getCurServer();
     this.fetchWireList();
   },
-  beforeDestroy() { },
+  beforeDestroy() {},
   props: ["barName"],
   methods: {
-    // parseFlags(flags) {
-    //   let arr = flags.split("|");
-    //   if (arr.length) {
-    //     return arr[0] == "up";
-    //   }
-    //   return false;
-    // },
+    switchNetCard(item){
+      if (item.active) {
+        upNetCard({
+          ifname	:item.name
+        }).then((res) => {
+          if (res.success) {
+            this.$message.success(res.data)
+            this.fetchWireList();
+          }
+        })
+      } else {
+        downNetCard({ifname	:item.name}).then((res) => {
+          if (res.success) {
+            this.$message.success(res.data)
+            this.fetchWireList();
+          }
+        })
+      }
+      
+    },
     getCurServer() {
       getDevInfo().then((res) => {
         this.ruleForm.deviceName = res.data.server_name;
@@ -333,23 +434,11 @@
     fetchWireList() {
       getWireList().then((res) => {
         if (res && res.success) {
-          this.wireArr = res.data
-            .filter((x) => x.wireless == false)
-            .map((itm) => {
-              let arr = itm.flags.split("|");
-              let f = false;
-              if (arr.length) {
-                f = arr[0] == "up";
-              }
-              return {
-                flags: itm.flags,
-                index: itm.index,
-                mtu: itm.mtu,
-                name: itm.name,
-                wireless: itm.wireless,
-                active: f
-              }
-            });
+          this.wireArr = res.data;
+          this.wireArr.forEach((x) => {
+            let t = x.flags.split("|")[0] == "up";
+            this.$set(x, "active", t);
+          });
         }
       });
     },
@@ -361,10 +450,12 @@
       this.wireForm.subMask = "";
     },
     saveServerName() {
+      debugger
       setServerName({
         server_name: this.ruleForm.deviceName,
         server_port: this.ruleForm.port,
       }).then((res) => {
+      debugger
         console.log(res);
         if (res && res.success) {
           this.$message.success(res.data);
@@ -402,7 +493,7 @@
         }
       );
     },
-    wifiControl(val) { },
+    wifiControl(val) {},
     checkWifi() {
       this.inWifiDetail = true;
     },
@@ -433,6 +524,10 @@
   width: 100%;
 }
 .wire-detail {
+  .title{
+    font-size: 16px;
+    margin-bottom: 10px;
+  }
   .btns {
     display: flex;
     justify-content: space-between;
@@ -587,6 +682,12 @@
       }
     }
     .wire {
+      .title{
+        line-height: 30px;
+        height: 30px;
+        font-size: 16px;
+        margin-bottom: 10px;
+      }
       .wire-bar {
         height: 50px;
         background-color: #f8f8f8;
@@ -596,6 +697,25 @@
         box-sizing: border-box;
         padding: 0 20px;
         margin-bottom: 10px;
+        border-radius:10px ;
+        .name{
+          font-size: 16px;
+        }
+        .right{
+              display: flex;
+    align-items: center;
+      .icon{
+        margin-right: 15px;
+      }
+          .good{
+            color: #3d68e1;
+            font-size: 18px;
+          }
+          .bad{
+            color: orangered;
+            font-size: 18px;
+          }
+        }
       }
       .wifi-name {
         height: 40px;
@@ -613,6 +733,7 @@
       border-radius: 10px;
       color: #fff;
       line-height: 40px;
+      cursor: pointer;
       font-size: 14px;
       margin-top: 30px;
     }
diff --git a/src/pages/settings/views/generalSettings.vue b/src/pages/settings/views/generalSettings.vue
index 21f11fe..14e5df8 100644
--- a/src/pages/settings/views/generalSettings.vue
+++ b/src/pages/settings/views/generalSettings.vue
@@ -1,22 +1,20 @@
 <template>
   <div class="all">
-    <div class="cluster-content">
-      <div class="cluster-center" ref="left">
-        <div class="menu-item" @click="openRight('basic')">
-          <div>璁惧淇℃伅</div>
-        </div>
-        <div class="menu-item" @click="openRight('video')">
-          <div>浜嬩欢褰曞儚鏃堕暱</div>
-        </div>
-        <div class="menu-item" @click="openRight('sound')">
-          <div>浜嬩欢澹伴煶</div>
-        </div>
-        <div class="menu-item" @click="openRight('personalise')">
-          <div>涓�у寲璁剧疆</div>
+    <div class="general-set">
+      <div class="general-center" ref="left">
+        <div
+          class="menu-item"
+          :class="activePage == i ? 'menu-item-active' : ''"
+          @click="openRight(i)"
+          v-for="(item, i) in menuArr"
+          :key="i"
+        >
+          <span class="iconfont">{{ item.icon }}</span>
+          <span class="title">{{ item.name }}</span>
         </div>
       </div>
       <div class="cluster-right">
-        <div class="lang" v-if="activePage == 'basic'">
+        <div class="lang" v-if="activePage == 0">
           <div class="bar">
             <span class="name">璁惧ID</span>
             <span class="desc">{{ deviceInfo.server_id }}</span>
@@ -58,7 +56,7 @@
             <span class="desc">{{ deviceInfo.runningTime }}</span>
           </div>
         </div>
-        <div class="lang" v-if="activePage == 'video'">
+        <div class="lang" v-if="activePage == 1">
           <div class="min-dur">
             <div class="title">瑙嗛鎴彇鏈�鐭椂闀�</div>
             <div class="entity">
@@ -77,8 +75,9 @@
                 controls-position="right"
                 :min="0"
                 :max="100"
-                size="mini"
-              ></el-input-number>&nbsp;s
+                size="small"
+              ></el-input-number
+              >&nbsp;s
             </div>
           </div>
           <div class="min-dur">
@@ -99,16 +98,18 @@
                 controls-position="right"
                 :min="0"
                 :max="100"
-                size="mini"
-              ></el-input-number>&nbsp;s
+                size="small"
+              ></el-input-number
+              >&nbsp;s
             </div>
           </div>
 
           <div class="save-btn" @click="submitAlarm">淇濆瓨</div>
         </div>
-        <div class="lang" v-if="activePage == 'sound'">
+        <div class="lang" v-if="activePage == 2">
           <div class="title">浜嬩欢澹伴煶</div>
-          <div
+          <div class="bar-group">
+             <div
             class="bar"
             v-for="(item, i) in soundList"
             :key="i"
@@ -116,13 +117,19 @@
             ref="soundBar"
           >
             <div class="left-part">
-              <span class="icon iconfont">&#xe646;</span>
+              <span class="icon iconfont" style="margin-right:12px;">&#xe6f5;</span>
               <span class="name">{{ item.name }}</span>
             </div>
             <div class="btns">
-              <span class="icon iconfont">&#xe646;</span>
-              <span class="icon iconfont" @click="removeSound(item)">&#xe646;</span>
+              <span @click="togglePlay(item, i)">
+                <i v-if="!item.isPlay" class="el-icon-video-play" style=""></i>
+                <i v-else class="el-icon-video-pause"></i>
+              </span>
+              <span class="icon iconfont" style="cursor:pointer;" @click="removeSound(item)"
+                >&#xe6cb;</span
+              >
             </div>
+          </div>
           </div>
           <div class="add-group">
             <el-upload
@@ -140,32 +147,46 @@
                 <br />浠呮敮鎸乵p3/wma绛夋牸寮�
               </div>
             </el-upload>
-            <div v-show="!showUpload"></div>
+            <div v-show="!showUpload" class="upload-demo"></div>
             <div class="add-btn">
-              <span class="icon iconfont" @click="showUpload = !showUpload">&#xe646;</span>
+              <span class="icon iconfont" @click="showUpload = !showUpload"
+                >&#xe646;</span
+              >
             </div>
           </div>
         </div>
 
-        <div class="lang" v-if="activePage == 'personalise'">
+        <div class="lang" v-if="activePage == 3">
           <div class="title">鍥炬爣涓婚</div>
 
-          <div class="min-dur" style="cursor:pointer;" @click="selectIcons(0)">
+          <div class="min-dur" style="cursor: pointer" @click="selectIcons(0)">
             <div class="title">鎵佸钩鍐欏疄鍥炬爣</div>
             <div class="entity">
-              <div class="entity-img" v-for="(item, i) in realIconList" :key="i"></div>
+              <div
+                class="entity-img"
+                v-for="(item, i) in realIconList"
+                :key="i"
+              ></div>
             </div>
           </div>
-          <div class="min-dur" style="cursor:pointer;" @click="selectIcons(1)">
+          <div class="min-dur" style="cursor: pointer" @click="selectIcons(1)">
             <div class="title">鎵佸钩鍖栧浘鏍�</div>
             <div class="entity">
-              <div class="entity-img" v-for="(item, i) in flatIconList" :key="i"></div>
+              <div
+                class="entity-img"
+                v-for="(item, i) in flatIconList"
+                :key="i"
+              ></div>
             </div>
           </div>
           <div class="title">妗岄潰鑳屾櫙涓婚</div>
-          <div class="min-dur" style="padding-top:25px;">
+          <div class="min-dur" style="padding-top: 25px">
             <div class="bg-list">
-              <div class="bg-img" v-for="(item, i) in tableBGList" :key="i"></div>
+              <div
+                class="bg-img"
+                v-for="(item, i) in tableBGList"
+                :key="i"
+              ></div>
             </div>
           </div>
         </div>
@@ -179,21 +200,26 @@
 import { uploadSound, getSoundList, deleteSound } from "@/api/event";
 import config from "../../../../package.json";
 
-import { isIPv4 } from "@/scripts/validate";
-
 export default {
   data() {
     return {
-      isHighClass: false,
       inWifiDetail: false,
+      curPlayingIndex: null,
       inWireDetail: false,
       showUpload: false,
       alarmConf: {
         min_video_len: 10,
         max_video_len: 15,
       },
+      menuArr: [
+        { name: "璁惧淇℃伅", icon: "\ue933" },
+        { name: "浜嬩欢褰曞儚鏃堕暱", icon: "\ue6f3" },
+        { name: "浜嬩欢澹伴煶", icon: "\ue6e1" },
+        { name: "涓�у寲璁剧疆", icon: "\ue756" },
+      ],
       soundList: [],
-      activePage: "basic",
+      activePage: 0,
+      eventAudio: new Audio(),
       deviceInfo: {
         cpu: "",
         runningTime: "",
@@ -206,6 +232,7 @@
         disks: "",
         memory: "",
       },
+      isPlay: false,
       realIconList: [{}, {}, {}],
       flatIconList: [{}, {}, {}],
       tableBGList: [{}, {}, {}],
@@ -214,11 +241,35 @@
   mounted() {
     this.getDeviceInfo();
     this.getSounds();
-
+    let _this = this;
+    this.eventAudio.addEventListener("ended", () => {
+      if (_this.curPlayingIndex !== null && _this.soundList.length) {
+        _this.soundList[_this.curPlayingIndex].isPlay = false;
+        _this.curPlayingIndex = null;
+      }
+    });
   },
-  beforeDestroy() { },
-  props: ["barName"],
+  beforeDestroy() {},
   methods: {
+    togglePlay(item, i) {
+      debugger;
+      if (this.curPlayingIndex !== null) {
+        this.eventAudio.pause();
+        this.soundList[this.curPlayingIndex].isPlay = false;
+        if (this.curPlayingIndex === i) {
+          this.curPlayingIndex = null;
+          return;
+        }
+      }
+      this.curPlayingIndex = i;
+      this.eventAudio.src = "http://" + item.path;
+      if (item.isPlay) {
+        this.eventAudio.pause();
+      } else {
+        this.eventAudio.play();
+      }
+      item.isPlay = !item.isPlay;
+    },
     getDeviceInfo() {
       getDevInfo().then((res) => {
         let info = res.data.deviceInfo;
@@ -234,8 +285,8 @@
         this.deviceInfo.disks = "( " + info.disk + ") ";
         this.deviceInfo.memory =
           (info.mem.total / 1024 / 1024 / 1024).toFixed(2) + "GB";
-        this.alarmConf.min_video_len = basic.min_video_len
-        this.alarmConf.max_video_len = basic.max_video_len
+        this.alarmConf.min_video_len = basic.min_video_len;
+        this.alarmConf.max_video_len = basic.max_video_len;
       });
     },
 
@@ -244,6 +295,9 @@
         .then((res) => {
           if (res.success) {
             this.soundList = res.data;
+            this.soundList.forEach((x) => {
+              this.$set(x, "isPlay", false);
+            });
           }
         })
         .catch((e) => console.log(e));
@@ -263,43 +317,41 @@
         this.getSounds();
       });
     },
-    openRight(typ) {
-      this.activePage = typ;
-      // if (typ == "sound") {
-      //   this.getSounds();
-      // }
+    openRight(i) {
+      this.activePage = i;
     },
-    wifiControl(val) { },
+    wifiControl(val) {},
     checkWifi() {
       this.inWifiDetail = true;
     },
     checkWire(item) {
       this.inWireDetail = true;
     },
-    selectIcons(typ) {
-
-    },
+    selectIcons(typ) {},
     removeSound(item) {
-      this.$confirm('鎮ㄦ槸鍚︾‘璁ゅ垹闄や簨浠跺0闊�', '鍒犻櫎浜嬩欢澹伴煶', {
-        confirmButtonText: '纭畾',
-        cancelButtonText: '鍙栨秷',
-        type: 'warning'
+      this.$confirm("鎮ㄦ槸鍚︾‘璁ゅ垹闄や簨浠跺0闊�", "鍒犻櫎浜嬩欢澹伴煶", {
+        confirmButtonText: "纭畾",
+        cancelButtonText: "鍙栨秷",
+        type: "warning",
       }).then(() => {
         deleteSound({
-          id: item.id
-        }).then((res) => {
-          if (res.success) {
-            this.getSounds()
-            this.$message({
-              type: 'success',
-              message: '鍒犻櫎鎴愬姛!'
-            });
-            this.showUpload = false
+          id: item.id,
+        }).then(
+          (res) => {
+            if (res.success) {
+              this.getSounds();
+              this.$message({
+                type: "success",
+                message: "鍒犻櫎鎴愬姛!",
+              });
+              this.showUpload = false;
+            }
+          },
+          (err) => {
+            this.$message.error(err.msg);
           }
-        }, err => {
-          this.$message.error(err.msg)
-        })
-      })
+        );
+      });
     },
     clickSound(item, i) {
       this.$refs["soundBar"].forEach((x) => {
@@ -326,14 +378,14 @@
   width: 100%;
 }
 
-.cluster-content {
+.general-set {
   height: 100%;
   display: flex;
   flex-direction: row;
   flex: 1;
   flex-basis: auto;
   box-sizing: border-box;
-  .cluster-center {
+  .general-center {
     height: 100%;
     width: 280px;
     overflow: auto;
@@ -342,18 +394,31 @@
     padding: 10px;
     border-right: 5px solid #f8f8f8;
 
-    // background-color: lavender;
     .menu-item {
       background-color: #f8f8f8;
-      height: 40px;
+      height: 50px;
       margin-bottom: 10px;
-      border-radius: 8px;
-      line-height: 40px;
+      border-radius: 10px;
+      line-height: 50px;
       box-sizing: border-box;
       font-size: 14px;
       padding: 0 20px;
+      cursor: pointer;
       display: flex;
-      justify-content: space-between;
+      .iconfont {
+        margin-right: 12px;
+      }
+      .title {
+        font-size: 16px;
+      }
+    }
+    .menu-item-active {
+      background-color: #3d68e1;
+      color: white;
+    }
+    .menu-item:hover {
+      background-color: #3d68e1;
+      color: white;
     }
   }
   .cluster-right {
@@ -404,6 +469,10 @@
         text-align: left;
         margin-bottom: 5px;
       }
+      .bar-group{
+        height: 280px;
+    overflow: auto;
+      }
       .bar {
         height: 50px;
         background-color: rgba(248, 248, 248, 1);
@@ -414,7 +483,6 @@
         display: flex;
         justify-content: space-between;
         margin-bottom: 10px;
-        cursor: pointer;
         .left-part {
           .icon {
             color: rgba(191, 191, 191, 1);
@@ -430,6 +498,18 @@
           display: flex;
           justify-content: space-between;
           color: rgba(191, 191, 191, 1);
+          .el-icon-video-pause {
+            cursor: pointer;
+            font-size: 23px;
+            vertical-align: middle;
+            color: #409eff;
+          }
+          .el-icon-video-play {
+            cursor: pointer;
+            font-size: 23px;
+            vertical-align: middle;
+            color: #409eff;
+          }
         }
         .desc {
           font-size: 14px;
@@ -440,12 +520,14 @@
         background-color: rgba(233, 233, 233, 1);
       }
       .add-group {
-        margin-top: 50px;
+        margin-top: 20px;
         display: flex;
         flex-direction: column;
         justify-content: space-between;
       }
       .upload-demo {
+        height: 180px;
+        transition: all .3s;
         .el-upload-dragger {
           width: 290px;
         }
@@ -454,8 +536,9 @@
         height: 40px;
         line-height: 40px;
         margin-top: 10px;
+        cursor: pointer;
         .icon {
-          font-size: 30px;
+          font-size: 32px;
           color: rgba(61, 104, 225, 1);
         }
       }
@@ -497,16 +580,12 @@
           flex: 1;
           margin: 0 20px 0 6px;
         }
-        .el-input-number--mini {
-          width: 80px;
-        }
-        .el-input-number.is-controls-right[class*="mini"] [class*="increase"],
-        .el-input-number.is-controls-right[class*="mini"] [class*="decrease"] {
-          width: 23px;
+        .el-input-number--small {
+          width: 100px;
         }
         .el-input-number.is-controls-right .el-input__inner {
-          padding-left: 13px;
-          padding-right: 37px;
+          padding-left: 16px;
+          // padding-right: 37px;
         }
         #cut_min_duration {
           .el-slider__bar {
diff --git a/src/pages/shuohuangMonitorAnalyze/components/searchForVideoAnalyze.vue b/src/pages/shuohuangMonitorAnalyze/components/searchForVideoAnalyze.vue
index d6d1a9b..dbf9025 100644
--- a/src/pages/shuohuangMonitorAnalyze/components/searchForVideoAnalyze.vue
+++ b/src/pages/shuohuangMonitorAnalyze/components/searchForVideoAnalyze.vue
@@ -426,7 +426,7 @@
       keyword: "",
       IsFollow: "",
       searchTime: [
-        new Date(2020, 0, 1, 0, 0, 0),
+        new Date(2021, 0, 1, 0, 0, 0),
         new Date(2021, 11, 31, 23, 59, 59),
       ],
       curTabPage: 1,
diff --git a/src/pages/systemSettings/components/AuthorityManagement.vue b/src/pages/systemSettings/components/AuthorityManagement.vue
new file mode 100644
index 0000000..d95a783
--- /dev/null
+++ b/src/pages/systemSettings/components/AuthorityManagement.vue
@@ -0,0 +1,265 @@
+<template>
+  <div class="s-authority-management">
+    <div class="authority-table s-table" v-if="display">
+      <el-table
+        highlight-current-row
+        :data="userList"
+        style="width: 100%"
+        :header-cell-style="{background:'#f8f8f8',color:'#222222'}"
+      >
+        <el-table-column align="center" type="index" label="搴忓彿" width="100"></el-table-column>
+        <el-table-column :align="'center'" prop="username" label="鐢ㄦ埛鍚�"></el-table-column>
+        <el-table-column :align="'center'" prop="role" label="瑙掕壊">
+          <template slot-scope="scope">{{scope.row.sysRoles | roles}}</template>
+        </el-table-column>
+        <el-table-column label="鎿嶄綔" :align="'center'">
+          <template slot-scope="scope">
+            <el-tooltip content="缂栬緫" placement="top" popper-class="atooltip">
+              <i
+                class="el-icon-edit"
+                style="font-size: 18px;"
+                @click="handleEdit(scope.$index, scope.row)"
+              ></i>
+            </el-tooltip>
+            <el-tooltip content="鍒犻櫎" placement="top" popper-class="atooltip" v-show="false">
+              <!-- :disabled="scope.row.sysRoles | roles | isSuper" -->
+              <i
+                class="el-icon-delete"
+                style="font-size: 18px; color:red;"
+                @click="handleDelete(scope.$index, scope.row)"
+              ></i>
+            </el-tooltip>
+          </template>
+        </el-table-column>
+      </el-table>
+    </div>
+    <div class="authority-details" v-if="!display">
+      <el-form label-width="80px" :rules="rules" ref="editForm" :model="editForm">
+        <el-form-item label="鐢ㄦ埛鍚�" style="width:580px" prop="username">
+          <!-- <el-input v-model="editForm.username" placeholder="璇疯緭鍏�" size="small"></el-input> -->
+          <span class="m10" v-if="editForm.username == 'admin' || editForm.username == 'basic'">{{editForm.username}}</span>
+          <el-input v-model="editForm.username" size="small" v-else></el-input>
+        </el-form-item>
+
+        <el-form-item label="鏂板瘑鐮�" style="width:580px" v-show="loginUser != editForm.username">
+          <el-input show-password v-model="editForm.newPwd" placeholder="璇疯緭鍏ュ瘑鐮�" size="small"></el-input>
+        </el-form-item>
+
+        <el-form-item
+          label="纭瀵嗙爜"
+          style="width:580px"
+          prop="checkPass"
+          v-show="loginUser != editForm.username"
+        >
+          <el-input show-password v-model="editForm.checkPass" placeholder="璇疯緭鍏ュ啀娆¤緭鍏ュ瘑鐮�" size="small"></el-input>
+        </el-form-item>
+
+        <el-form-item label="鏉冮檺閰嶇疆" style="width:580px;">
+          <!-- <el-transfer
+            id="e-transfer"
+            :titles="['鍏ㄩ儴瑙掕壊', '褰撳墠瑙掕壊']"
+            v-model="editForm.roleIds"
+            :props="{key: 'id', label: 'name'}"
+            :data="roledata"
+          ></el-transfer>-->
+
+          <el-tree
+            ref="treeMenus"
+            :data="sysMenus"
+            :props="props"
+            node-key="id"
+            :default-checked-keys="userMenus"
+            show-checkbox
+            check-on-click-node
+            default-expand-all
+            style="margin-top: 10px;"
+          ></el-tree>
+        </el-form-item>
+
+        <el-form-item style="width:580px;">
+          <el-button type="primary" style="float: right" @click="save" size="small">淇濆瓨</el-button>
+          <el-button type="info" style="margin-right: 10px;float: right" @click="goback" size="small">杩斿洖</el-button>
+        </el-form-item>
+      </el-form>
+    </div>
+  </div>
+</template>
+
+<script>
+
+import { getUsers, getSysMenus, updataUser, getUserMenus } from "@/api/user"
+
+export default {
+  name: "AuthorityManage",
+  filters: {
+    roles(roles) {
+      return roles.map(r => {
+        return r.name
+      }).join(' ')
+    },
+    isSuper(roles) {
+      return roles.indexOf("瓒呯骇绠$悊鍛�") >= 0
+    }
+  },
+  data() {
+    const generateData = _ => {
+      const data = [];
+      for (let i = 1; i <= 15; i++) {
+        data.push({
+          key: i,
+          label: `澶囬�夐」 ${i}`,
+          disabled: i % 4 === 0
+        });
+      }
+      return data;
+    };
+    const validateCheckPass = (rule, value, callback) => {
+      if (value !== this.editForm.newPwd) {
+        callback(new Error('涓ゆ杈撳叆瀵嗙爜涓嶄竴鑷�!'));
+      } else {
+        callback()
+      }
+    };
+    var checkUserName = (rule, value, callback) => {
+    聽聽if (value && value !== ''){
+    聽聽聽聽let regEn = /^[A-Za-z_@.]{2,10}$/
+        console.log("鐢ㄦ埛鍚嶆牎楠岋紒",value)
+    聽聽聽聽if (!regEn.test(value)) {
+    聽聽聽聽聽聽callback(new Error('璇疯緭鍏�2浣嶅埌10浣嶅瓧姣嶇殑鐢ㄦ埛鍚嶏紝涓嶈兘浠ユ暟瀛楀紑澶达紝涓斾笉鑳藉寘鍚眽瀛�'))
+    聽聽聽聽} else {
+    聽聽聽聽聽聽callback()
+    聽聽聽聽}
+    聽聽} else {
+    聽聽聽聽callback()
+    聽聽}
+    }
+    return {
+      display: true,
+      loginUser: JSON.parse(sessionStorage.getItem('userInfo')).username,
+      acknewpwd: "",
+      sysMenus: [],
+      userMenus: [],
+      rolevalue: [],
+      userList: [],
+      editForm: {},
+      props: {
+        label: 'name'
+      },
+      rules: {
+        username: [
+          { validator: checkUserName, trigger: 'blur' }
+        ],
+        checkPass: [
+          { validator: validateCheckPass, trigger: 'change' }
+        ]
+      }
+    };
+  },
+  mounted() {
+    this.fetchUserList();
+    this.fetchSysMenus();
+    this.initEditForm();
+  },
+  methods: {
+    initEditForm() {
+      this.editForm = {
+        id: "",
+        username: "",
+        newPwd: "",
+        checkPass: "",
+        menuIds: []
+      }
+    },
+    handleEdit(index, row) {
+      this.initEditForm()
+      this.display = !this.display;
+      this.editForm.id = row.id;
+      this.editForm.username = row.username;
+      this.userMenus = []
+      getUserMenus({ userId: row.id }).then(rsp => {
+        if (rsp && rsp.success) {
+          this.userMenus = rsp.data.menus.map(menu => {
+            return menu.id
+          })
+        }
+      })
+
+    },
+    handleDelete(index, row) {
+      this.$notify({
+        type: "warning",
+        message: "鏃犳硶鍒犻櫎璇ョ敤鎴�"
+      })
+    },
+    goback() {
+      this.display = !this.display;
+    },
+    save() {
+      this.$refs.editForm.validate((valid) => {
+        if (valid) {
+          this.editForm.menuIds = this.$refs.treeMenus.getCheckedKeys()
+          updataUser(this.editForm).then(rsp => {
+            if (rsp && rsp.success) {
+              this.$notify({
+                type: "success",
+                message: "淇敼鎴愬姛"
+              })
+            }
+          })
+        }
+      });
+    },
+    fetchUserList() {
+      getUsers().then(rsp => {
+        if (rsp && rsp.success) {
+          this.userList = rsp.data;
+        }
+      })
+    },
+    fetchSysMenus() {
+      getSysMenus().then(rsp => {
+        if (rsp && rsp.success) {
+          this.sysMenus = rsp.data;
+        }
+      })
+    }
+  }
+};
+</script>
+<style lang="scss">
+.s-authority-management {
+  height: 100%;
+  width: 100%;
+  .authority-table,
+  .authority-details {
+    height: 100%;
+    width: 100%;
+    margin-top: 40px;
+  }
+  #e-transfer {
+    .el-button--primary {
+      color: #fff;
+      background-color: #bfbfbf;
+      border-color: #bfbfbf;
+    }
+    .el-button--primary:focus,
+    .el-button--primary:hover {
+      background: #4c4c4c;
+      border-color: #4c4c4c;
+      color: #fff;
+    }
+    .el-transfer-panel
+      .el-transfer-panel__header
+      .el-checkbox
+      .el-checkbox__label {
+      font-size: 14px;
+    }
+  }
+  .el-form-item__content {
+    text-align: left;
+    input {
+      max-width: 498px;
+    }
+  }
+}
+</style>
diff --git a/src/pages/systemSettings/components/BasicSetting.vue b/src/pages/systemSettings/components/BasicSetting.vue
new file mode 100644
index 0000000..7f23ae9
--- /dev/null
+++ b/src/pages/systemSettings/components/BasicSetting.vue
@@ -0,0 +1,1035 @@
+<template>
+  <div class="s-basic-setting">
+    <el-tabs
+      id="e-basic-setting"
+      v-model="activeName"
+      v-loading="loading"
+      :element-loading-text="loadingText"
+      type="border-card"
+    >
+      <!-- 鏈満淇℃伅 -->
+      <el-tab-pane label="鏈満淇℃伅" name="sysInfo" v-if="isShow('settings:sysInfo')">
+        <el-menu
+          :default-openeds="openeds"
+          background-color="#fff"
+          text-color="#303133"
+          active-text-color="#409EFF"
+          style="height: 100%;"
+          class="menu-css"
+          @open="menuOpen"
+          @close="menuClose"
+        >
+          <!-- 鏈満淇℃伅 -->
+          <el-submenu index="0">
+            <template slot="title">
+              <b class="tree-font">鏈満淇℃伅</b>
+            </template>
+            <el-menu-item-group class="item-group">
+              <el-form :model="sysinfo" :rules="rules" ref="sysinfo" label-width="100px">
+                <el-row>
+                  <el-col :span="12">
+                    <el-form-item label="鍚嶇О" prop="server_name">
+                      <el-input v-model="sysinfo.server_name" placeholder="鏈嶅姟鍣ㄥ悕绉�" size="small"></el-input>
+                    </el-form-item>
+                  </el-col>
+                  <el-col :span="12">
+                    <el-form-item label="绔彛" prop="server_port">
+                      <el-input v-model="sysinfo.server_port" placeholder="WEB鏈嶅姟绔彛" size="small"></el-input>
+                    </el-form-item>
+                  </el-col>
+                </el-row>
+
+                <el-row>
+                  <el-col :span="12">
+                    <el-form-item label="IP" prop="ip">
+                      <ip-input :ip="sysinfo.ip" @on-blur="sysinfo.ip = arguments[0]"></ip-input>
+                    </el-form-item>
+                  </el-col>
+                  <el-col :span="12">
+                    <el-form-item label="瀛愮綉鎺╃爜" prop="subMask">
+                      <ip-input :ip="sysinfo.subMask" @on-blur="sysinfo.subMask = arguments[0]"></ip-input>
+                    </el-form-item>
+                  </el-col>
+                </el-row>
+
+                <el-row>
+                  <el-col :span="12">
+                    <el-form-item label="缃戝叧" prop="gateway">
+                      <ip-input :ip="sysinfo.gateway" @on-blur="sysinfo.gateway = arguments[0]"></ip-input>
+                    </el-form-item>
+                  </el-col>
+                  <el-col :span="12">
+                    <el-form-item label="DNS" prop="dns">
+                      <ip-input :ip="sysinfo.dns" @on-blur="sysinfo.dns = arguments[0]"></ip-input>
+                    </el-form-item>
+                  </el-col>
+                </el-row>
+                <div class="mt15 mb10 save-btn">
+                  <el-button type="primary" @click="submitSysinfo" size="small">淇濆瓨</el-button>
+                </div>
+              </el-form>
+            </el-menu-item-group>
+          </el-submenu>
+
+          <el-submenu index="1">
+            <template slot="title">
+              <b class="tree-font">璇︾粏淇℃伅</b>
+            </template>
+            <el-menu-item-group class="item-group desc-info">
+              <el-row :gutter="gutter">
+                <el-col :span="12" class="flex-box">
+                  <div class="xiangqin-label">璁惧ID</div>
+                  <div class="xiangqing-info">{{sysinfo.server_id}}</div>
+                </el-col>
+                <!-- <el-col :span="12" class="flex-box">
+                  <div class="xiangqin-label">璁惧缂栧彿</div>
+                  <div class="xiangqing-info">{{sysinfo.deviceNum}}</div>
+                </el-col>-->
+                <el-col :span="12" class="flex-box">
+                  <div class="xiangqin-label">璁惧鍨嬪彿</div>
+                  <div class="xiangqing-info">{{sysinfo.deviceModel}}</div>
+                </el-col>
+                <el-col :span="12" class="flex-box">
+                  <div class="xiangqin-label">璁惧绫诲瀷</div>
+                  <div class="xiangqing-info">{{sysinfo.deviceDesc}}</div>
+                </el-col>
+                <el-col :span="12" class="flex-box">
+                  <div class="xiangqin-label">閫氶亾涓暟</div>
+                  <div class="xiangqing-info">{{sysinfo.channelCount}}</div>
+                </el-col>
+                <el-col :span="12" class="flex-box">
+                  <div class="xiangqin-label">涓绘帶鐗堟湰</div>
+                  <div class="xiangqing-info">{{sysinfo.masterVersion}}</div>
+                </el-col>
+                <el-col :span="12" class="flex-box">
+                  <div class="xiangqin-label">web鐗堟湰</div>
+                  <div class="xiangqing-info">{{sysinfo.webVersion}}</div>
+                </el-col>
+                <el-col :span="12" class="flex-box">
+                  <div class="xiangqin-label">纭洏淇℃伅</div>
+                  <div class="xiangqing-info">{{sysinfo.disks}}</div>
+                </el-col>
+                <el-col :span="12" class="flex-box">
+                  <div class="xiangqin-label">CPU</div>
+                  <div class="xiangqing-info">{{sysinfo.cpuInfo}}</div>
+                </el-col>
+                <el-col :span="12" class="flex-box">
+                  <div class="xiangqin-label">鍐呭瓨</div>
+                  <div class="xiangqing-info">{{sysinfo.mem}}</div>
+                </el-col>
+                <el-col :span="12" class="flex-box">
+                  <div class="xiangqin-label">杩愯鏃堕棿</div>
+                  <div class="xiangqing-info">{{sysinfo.uptime}}</div>
+                </el-col>
+              </el-row>
+            </el-menu-item-group>
+          </el-submenu>
+          <!-- 浜嬩欢褰曞儚鏃堕暱 -->
+          <el-submenu index="2">
+            <template slot="title">
+              <b class="tree-font">浜嬩欢褰曞儚鏃堕暱</b>
+            </template>
+            <el-menu-item-group class="item-group">
+              <el-form
+                label-width="150px"
+                class="alarmSetting"
+                style="padding-left:5px;padding-right:5px;"
+              >
+                <el-form-item label="瑙嗛鎴彇鏈�鐭椂闀�1" style="width:724px;">
+                  <el-slider
+                    id="cut_min_duration"
+                    v-model="alarmConf.min_video_len"
+                
+                    :step="5" show-stops :show-tooltip="true"
+                  ></el-slider>
+                  <el-input-number
+                    v-model="alarmConf.min_video_len"
+                    controls-position="right"
+                    :min="5"
+                    :max="120"
+                    size="small"
+                  ></el-input-number>&nbsp;s
+                </el-form-item>
+                <el-form-item label="瑙嗛鎴彇鏈�闀挎椂闀�" style="width:724px">
+                  <el-slider
+                    id="cut_max_duration"
+                    v-model="alarmConf.max_video_len"
+                 :step="5" show-stops :show-tooltip="true"
+                  ></el-slider>
+                  <el-input-number
+                    v-model="alarmConf.max_video_len"
+                    controls-position="right"
+                    :min="5"
+                    :max="120"
+                    size="small"
+                  ></el-input-number>&nbsp;s
+                </el-form-item>
+                <div class="mt15 mb10 save-btn">
+                  <el-button type="primary" @click="submitAlarm" size="small">淇濆瓨</el-button>
+                </div>
+              </el-form>
+            </el-menu-item-group>
+          </el-submenu>
+          <!-- 瀵瑰鏈嶅姟IP 鏀瑰悕涓哄閮ㄧ綉缁�(鏂皌ab)-->
+        </el-menu>
+      </el-tab-pane>
+
+      <!-- 鏃堕棿閰嶇疆 -->
+      <el-tab-pane label="鏃堕棿閰嶇疆" name="timeSet" v-if="isShow('settings:timeSet')">
+        <el-form label-width="100px">
+          <el-form-item label="璁惧鏃堕棿">
+            {{ equipmentTime }}
+          </el-form-item>
+          <div style="text-align: left;padding: 10px 0px">
+            <div class="time-type">NTP鏍℃椂</div>
+            <div style="padding: 10px 0px;">
+              <el-radio v-model="syncType" label="1">NTP鏍℃椂</el-radio>
+            </div>
+          </div>
+
+          <el-form-item label="鏈嶅姟鍣ㄥ湴鍧�">
+            <ip-input
+              :ip="ntpServer"
+              @on-blur="ntpServer= arguments[0]"
+              :disabled="syncType === '2'"
+            ></ip-input>
+          </el-form-item>
+
+          <el-form-item label="鏍℃椂鏃堕棿闂撮殧" style="width: 41.3%;">
+            <el-input-number
+              v-model.number="timeInterval"
+              :min="1"
+              :max="60"
+              placeholder="璇疯緭鍏�"
+              size="small"
+              :controls="false"
+              :disabled="syncType === '2'"
+            ></el-input-number>&nbsp;&nbsp;&nbsp;鍒嗛挓
+            <el-button
+              type="text"
+              style="position: absolute; left: 330px;"
+              :disabled="syncType === '2'"
+              @click="testNTP"
+              :loading="ntpTestLoading"
+            >娴嬭瘯</el-button>
+          </el-form-item>
+
+          <div style="text-align: left;padding: 10px 0px">
+            <div class="time-type">鎵嬪姩鏍℃椂</div>
+            <div style="padding: 10px 0px;">
+              <el-radio v-model="syncType" label="2">鎵嬪姩鏍℃椂</el-radio>
+            </div>
+          </div>
+
+          <el-form-item label="璁剧疆鏃堕棿">
+            <el-date-picker
+              v-model="settime"
+              type="datetime"
+              placeholder="閫夋嫨鏃ユ湡鏃堕棿"
+              size="small"
+              value-format="yyyy-MM-dd HH:mm:ss"
+              :disabled="syncType === '1'"
+            ></el-date-picker>
+            <el-checkbox
+              v-model="settimeRadio"
+              style="margin-left: 12px;"
+              @change="syncBrowser"
+              :disabled="syncType === '1'"
+            >鍚屾鏈绠楁満鏃堕棿</el-checkbox>
+          </el-form-item>
+
+          <el-col :span="12" style="padding-right: 40px;">
+            <el-form-item>
+              <el-button type="primary" @click="submitClock" size="small">淇濆瓨</el-button>
+            </el-form-item>
+          </el-col>
+        </el-form>
+      </el-tab-pane>
+
+      <!-- 闆嗙兢绠$悊 -->
+      <el-tab-pane label="闆嗙兢绠$悊" name="cluster" v-if="isShow('settings:cluster')">
+        <cluster-management></cluster-management>
+      </el-tab-pane>
+      <!-- <el-tab-pane label="澶栭儴璁块棶" name="fourth">
+        <el-menu
+          :default-openeds="openeds"
+          background-color="#fff"
+          text-color="#303133"
+          active-text-color="#409EFF"
+          style="height: 100%;"
+          class="menu-css"
+          @open="menuOpen"
+          @close="menuClose"
+        >
+          <el-submenu index="0">
+            <template slot="title">
+              <b class="tree-font">澶栭儴璁块棶璁剧疆</b>
+            </template>
+            <el-menu-item-group class="item-group">
+              <el-form :model="sysinfo" :rules="rules" ref="sysinfo" label-width="100px">
+                <div class="flex-box">
+                  <label>璁剧疆澶栭儴IP</label>
+                  <div style="width:300px;">
+                    <ip-input :ip="ipServer.ip" @on-blur="ipServer.ip = arguments[0]"></ip-input>
+                  </div>
+                  <el-checkbox label="閫夌敤鏈満IP" size="small" style="margin-left: 20px"></el-checkbox>
+                </div>
+                <div class="flex-box">
+                  <label>鍩熷悕</label>
+                  <el-input size="small" v-model="ipServer.localhost"></el-input>
+                </div>
+                <div class="flex-box">
+                  <label>鏈湴鏂囦欢绔彛</label>
+                  <el-input size="small" v-model="ipServer.localFilePort"></el-input>
+                </div>
+                <div class="mt15 mb10 save-btn">
+                  <el-button type="primary" @click="submitSysinfo" size="small">淇濆瓨</el-button>
+                </div>
+              </el-form>
+            </el-menu-item-group>
+          </el-submenu>
+        </el-menu>
+      </el-tab-pane>-->
+      <el-tab-pane label="鏉冮檺绠$悊" name="permission" v-if="isShow('settings:permission')">
+        <authority-management v-if="activeName === 'permission'"></authority-management>
+      </el-tab-pane>
+      <el-tab-pane label="骞挎挱璁剧疆" name="broadcast" v-if="isShow('settings:broadcast')">
+        <radio-set v-if="activeName === 'broadcast'"></radio-set>
+      </el-tab-pane>
+    </el-tabs>
+  </div>
+</template>
+
+<script>
+import {
+  getDevInfo,
+  getAlarmConfig,
+  saveDevInfo,
+  saveAlarmConfig,
+  getClockInfo,
+  saveClockInfo,
+  testNTPserver,
+  getResourceConfig,
+  saveResourceConfig,
+} from "@/api/system";
+
+import { isPort, isIPv4 } from "@/scripts/validate";
+import ipInput from "@/components/subComponents/IPInput";
+import TimeZones from "@/Pool/TimeZones"
+
+import ClusterManagement from "./ClusterManagement";
+import AuthorityManagement from "./AuthorityManagement";
+import RadioSet from "./RadioSet";
+import config from '../../../../package.json'
+
+export default {
+  name: "BasicSettings",
+  components: {
+    ipInput,
+    ClusterManagement,
+    AuthorityManagement,
+    RadioSet
+  },
+  computed: {
+    // timeZoneOption() {
+    //   let options = []
+    //   TimeZones.forEach(zone => {
+    //     options = options.concat(zone.utc.map(v => {
+    //       return { value: v, label: v }
+    //     }))
+    //   })
+    //   return options
+    // },
+    isAdmin() {
+      if (
+        sessionStorage.getItem("userInfo") &&
+        sessionStorage.getItem("userInfo") !== ""
+      ) {
+        let loginName = JSON.parse(sessionStorage.getItem("userInfo")).username;
+        return loginName === "superadmin" || loginName === "basic";
+      }
+
+      return false;
+    },
+  },
+  directives: {
+    focus: {
+      inserted: function (el) {
+        el.querySelector('input').focus()
+      }
+    }
+  },
+  data() {
+    return {
+      loading: true,
+      loadingText: "",
+      gutter: 10,
+      activeName: "sysInfo",
+      timezone: "",
+      syncType: "1",
+      ntpServer: "",
+      equipmentTime: "",
+      NYPport: "",
+      settime: "",
+      timeInterval: 10,
+      settimeRadio: false,
+      clockTimer: null,
+      browserTimer: null,
+      timestamp: 0,
+      sysinfo: {},
+      alarmConf: {},
+      originNetConfig: {
+        ip: "",
+        gw: "",
+        mask: "",
+        dns: ""
+      },
+      rules: {
+        ip: [
+          {
+            required: true,
+            message: "璇疯緭鍏P鍦板潃",
+            trigger: "change"
+          },
+          { validator: isIPv4, trigger: "change" }
+        ],
+        ServerIp: [
+          {
+            required: true,
+            message: "璇疯緭鍏P鍦板潃",
+            trigger: "change"
+          },
+          { validator: isIPv4, trigger: "change" }
+        ],
+        ServerPort: [
+          {
+            required: true,
+            message: "璇疯緭鍏ョ鍙�",
+            trigger: "change"
+          },
+          { validator: isPort, trigger: "change" }
+        ],
+        GbServerPort: [
+          {
+            required: true,
+            message: "璇疯緭鍏ョ鍙�",
+            trigger: "change"
+          },
+          { validator: isPort, trigger: "change" }
+        ],
+        gateway: [
+          {
+            required: true,
+            message: "璇疯緭鍏ョ綉鍏�",
+            trigger: "change"
+          },
+          { validator: isIPv4, trigger: "change" }
+        ],
+        dns: [
+          {
+            required: true,
+            message: "璇疯緭鍏ns鍦板潃",
+            trigger: "change"
+          },
+          { validator: isIPv4, trigger: "change" }
+        ],
+        server_name: [
+          { required: true, message: "璇疯緭鍏ュ悕绉�", trigger: "change" }
+        ],
+        subMask: [
+          {
+            required: true,
+            message: "璇疯緭鍏ュ瓙缃戞帺鐮�",
+            trigger: "change"
+          },
+          { validator: isIPv4, trigger: "change" }
+        ]
+      },
+      openeds: ["0"],
+      ipServer: {
+        diyOrLocalIP: "1",
+        ip: "",
+        localhost: "",
+        localFilePort: "",
+      },
+      locationCity: {
+        province: '',
+        city: '',
+        county: '',
+        provinceOptions: [],
+        cityOptions: [],
+        countyOptions: []
+      },
+      webPort: 0,
+      ntpTestLoading: false,
+      buttonAuthority: sessionStorage.getItem("buttonAuthoritys") || [],
+    };
+  },
+  created() {
+    if (this.isShow("settings:sysInfo")) {
+      this.activeName = "sysInfo";
+    } else if (this.isShow("settings:timeSet")) {
+      this.activeName = "timeSet";
+    } else if (this.isShow("settings:cluster")) {
+      this.activeName = "cluster";
+    } else if (this.isShow("settings:permission")) {
+      this.activeName = "permission";
+    } else if (this.isShow("settings:broadcast")) {
+      this.activeName = "broadcast";
+    }
+  },
+  mounted() {
+    this.$nextTick(() => {
+      this.initSysinfo();
+      // this.initAlarmConf();
+      this.initResourceConfig();
+      this.initClockConf();
+      //this.markStartTime();
+    });
+  },
+  beforeDestroy() {
+    clearTimeout(this.clockTimer);
+    clearInterval(this.browserTimer);
+  },
+  methods: {
+    isShow(authority) {
+      return this.isAdmin || this.buttonAuthority.indexOf("," + authority + ",") > -1
+    },
+    initSysinfo() {
+      this.loadingText = "姝e湪鑾峰彇璁惧淇℃伅...";
+      getDevInfo().then(rsp => {
+        if (rsp && rsp.success) {
+          this.sysinfo = rsp.data;
+          this.sysinfo.gateway = this.sysinfo.gateway.trim();
+          this.originNetConfig.ip = this.sysinfo.ip;
+          this.originNetConfig.mask = this.sysinfo.subMask;
+          this.originNetConfig.gw = this.sysinfo.gateway.trim();
+          this.originNetConfig.dns = this.sysinfo.dns ? this.sysinfo.dns : "";
+          this.alarmConf.min_video_len = rsp.data.min_video_len;
+          this.alarmConf.max_video_len = rsp.data.max_video_len;
+
+          if (this.sysinfo.deviceInfo) {
+            let devInfo = this.sysinfo.deviceInfo;
+
+            this.sysinfo.cpuInfo = devInfo.cpu[0].modelName;
+            this.sysinfo.disks = "( " + devInfo.disk + ") ";
+            this.sysinfo.mem = (devInfo.mem.total / 1024 / 1024 / 1024).toFixed(2) + "GB";
+            // this.sysinfo.arch = devInfo.host.kernelArch;
+            this.sysinfo.uptime = this.secondsFormat(devInfo.host.uptime);
+          }
+
+          if (!this.sysinfo.server_port) {
+            this.sysinfo.server_port = 7003;
+          }
+
+          this.webPort = this.sysinfo.server_port;
+
+          this.sysinfo.webVersion = 'V' + config.version;
+        }
+
+        this.loading = false;
+      }).catch(err => {
+        this.loading = false;
+      });
+    },
+    secondsFormat(s) {
+      var day = Math.floor(s / (24 * 3600)); // Math.floor()鍚戜笅鍙栨暣 
+      var hour = Math.floor((s - day * 24 * 3600) / 3600);
+      var minute = Math.floor((s - day * 24 * 3600 - hour * 3600) / 60);
+      var second = s - day * 24 * 3600 - hour * 3600 - minute * 60;
+      return day + "澶�" + hour + "鏃�" + minute + "鍒�" + second + "绉�";
+    },
+    initClockConf(ntpTest = false) {
+      getClockInfo().then(rsp => {
+        if (rsp && rsp.success) {
+          this.timezone = rsp.data.time_zone;
+          if (!ntpTest) {
+            this.syncType = rsp.data.ntp ? "1" : "2";
+          }
+          if (rsp.data.ntp) {
+            this.ntpServer = rsp.data.ntp_server;
+            this.timeInterval = rsp.data.interval;
+          }
+          this.timestamp = rsp.data.local_time
+          if (this.clockTimer === null) {
+            this.runClock();
+          }
+        }
+      })
+    },
+    runClock() {
+      this.equipmentTime = this.formatTime(++this.timestamp, 'Y-M-D h:m:s');
+      this.clockTimer = setTimeout(() => {
+        this.runClock();
+      }, 1000)
+    },
+    initAlarmConf() {
+      // getAlarmConfig().then(rsp => {
+      //   if (rsp && rsp.success) {
+      //     this.alarmConf = rsp.data;
+      //   }
+      // });
+    },
+    initResourceConfig() {
+      getResourceConfig().then(rsp => {
+        if (rsp && rsp.success) {
+          this.ipServer.diyOrLocalIP = rsp.data.ipType
+          this.ipServer.ip = rsp.data.serviceIp
+          this.ipServer.localhost = rsp.data.domain
+          this.ipServer.localFilePort = rsp.data.filePort
+        }
+      })
+    },
+    syncBrowser(enable) {
+      if (!enable) {
+        clearInterval(this.browserTimer)
+      } else {
+        this.browserTimer = setInterval(() => {
+          let timestamp = new Date().getTime() / 1000;
+          this.settime = this.formatTime(timestamp, 'Y-M-D h:m:s')
+        }, 1000)
+      }
+    },
+    markStartTime() {
+      let timestamp = new Date().getTime() / 1000;
+      this.settime = this.formatTime(timestamp, 'Y-M-D h:m:s')
+    },
+    submitSysinfo() {
+      this.$refs["sysinfo"].validate(valid => {
+        if (valid) {
+          if (this.sysinfo.ip !== this.originNetConfig.ip
+            || this.sysinfo.subMask !== this.originNetConfig.mask
+            || this.sysinfo.dns !== this.originNetConfig.dns
+            || this.sysinfo.gateway !== this.originNetConfig.gw) {
+
+            if (this.sysinfo.ip !== this.originNetConfig.ip) {
+              let newUri = location.protocol + "//" + this.sysinfo.ip + ":" + this.sysinfo.server_port;
+              var changeIPTimer = setTimeout(() => {
+                this.$alert('<strong>鎮ㄥ凡淇敼浜嗘湇鍔″櫒ip, 璇烽噸鏂扮櫥褰�</strong><a target="_parent" href="' + newUri + '"> ' + newUri + '<a/>', '鎻愮ず', {
+                  dangerouslyUseHTMLString: true
+                });
+              }, 10000)
+            }
+
+            this.$confirm("纭闇�瑕佷慨鏀规湇鍔″櫒缃戠粶閰嶇疆鍚楋紵", {
+              center: true,
+              cancelButtonClass: "comfirm-class-cancle",
+              confirmButtonClass: "comfirm-class-sure"
+            }).then(() => {
+              this.loading = true;
+              this.loadingText = "姝e湪澶勭悊..."
+              saveDevInfo(this.sysinfo).then(rsp => {
+                if (rsp && rsp.success) {
+                  this.$notify({
+                    type: "success",
+                    message: "鏈満淇℃伅淇濆瓨鎴愬姛"
+                  });
+                }
+                this.initSysinfo();
+                this.loading = false;
+              }).catch(err => {
+                this.loading = false;
+                clearTimeout(changeIPTimer)
+                this.$notify({
+                  type: "error",
+                  message: "淇濆瓨澶辫触"
+                });
+              });
+            }).catch(err => {
+            });
+          } else {
+            saveDevInfo(this.sysinfo).then(rsp => {
+              if (rsp && rsp.success) {
+                this.$notify({
+                  type: "success",
+                  message: "鏈満淇℃伅淇濆瓨鎴愬姛"
+                });
+                this.initSysinfo();
+              }
+            });
+
+            if (this.sysinfo.server_port !== this.webPort) {
+              let newUri = location.protocol + "//" + this.sysinfo.ip + ":" + this.sysinfo.server_port;
+              var changeIPTimer = setTimeout(() => {
+                this.$alert('<strong>鎮ㄥ凡淇敼浜嗘湇鍔″櫒绔彛, 璇烽噸鏂扮櫥褰�</strong><a target="_parent" href="' + newUri + '"> ' + newUri + '<a/>', '鎻愮ず', {
+                  dangerouslyUseHTMLString: true
+                });
+              }, 5000)
+            }
+          }
+        } else {
+          console.log("error submit!!");
+          return false;
+        }
+      });
+    },
+    checkTimeZone(val) {
+
+    },
+    submitClock() {
+      if (this.syncType === '1') {
+        if (this.ntpServer === "") {
+          this.$notify({
+            type: "error",
+            message: "NTP 鏈嶅姟鍣ㄥ湴鍧�涓嶈兘涓虹┖"
+          });
+          return false
+        } else if (this.timeInterval === "") {
+          this.timeInterval = 1;
+        }
+      } else {
+        if (this.settime === "") {
+          this.$notify({
+            type: "error",
+            message: "璁剧疆鏃堕棿涓嶈兘涓虹┖"
+          });
+          return false
+        }
+      }
+      let requestBody = {
+        timeZone: this.timezone,
+        ntp: this.syncType === '1',
+        ntpServer: this.ntpServer,
+        interval: this.timeInterval,
+        newTime: this.settime
+      }
+      saveClockInfo(requestBody).then(rsp => {
+        if (rsp && rsp.success) {
+          this.$notify({
+            type: "success",
+            message: "璁剧疆鎴愬姛"
+          });
+        }
+        this.initClockConf();
+      })
+    },
+    testNTP() {
+      this.ntpTestLoading = true;
+      testNTPserver({ server: this.ntpServer }).then(rsp => {
+        if (rsp && rsp.success) {
+          this.$notify({
+            type: "success",
+            message: "鏃堕棿鍚屾鎴愬姛"
+          });
+        } else {
+          this.$notify({
+            type: "error",
+            message: "鏃堕棿鍚屾澶辫触"
+          });
+        }
+        this.ntpTestLoading = false;
+        this.initClockConf(true);
+
+      }).catch(err => {
+        this.$notify({
+          type: "error",
+          message: "鏃堕棿鍚屾澶辫触,璇锋鏌ユ湇鍔″櫒ip"
+        });
+        this.ntpTestLoading = false;
+      })
+    },
+    submitAlarm() {
+      saveAlarmConfig(this.alarmConf).then(rsp => {
+        if (rsp && rsp.success) {
+          this.$notify({
+            type: "success",
+            message: "淇濆瓨鎴愬姛"
+          });
+        }
+      });
+    },
+    submitResource() {
+      let regNum = /^[0-9]*$/;
+      if (!this.vaildHost(this.ipServer.localhost)) {
+        this.$notify({
+          type: "warning",
+          message: "璇疯緭鍏ユ纭牸寮忓緱鍩熷悕锛�"
+        })
+        return false;
+      }
+      if (!regNum.test(this.ipServer.localFilePort)) {
+        this.$notify({
+          type: 'warning',
+          message: "璇疯緭鍏ユ纭殑绔彛鍙凤紒"
+        })
+        return false;
+      }
+      saveResourceConfig({
+        domain: this.ipServer.localhost,
+        ipType: this.ipServer.diyOrLocalIP,
+        serviceIp: this.ipServer.ip,
+        filePort: Number(this.ipServer.localFilePort)
+      }).then(res => {
+        if (res && res.success) {
+          this.$notify({
+            type: "success",
+            message: "淇濆瓨鎴愬姛"
+          });
+        } else {
+          this.$notify({
+            type: "error",
+            message: "淇濆瓨澶辫触"
+          });
+        }
+      })
+    },
+    onIpBlur(e, ip) {
+      console.log(e, ip);
+    },
+    formatTime(number, format) {
+      var formateArr = ['Y', 'M', 'D', 'h', 'm', 's'];
+      var returnArr = [];
+
+      var date = new Date(number * 1000);
+      returnArr.push(date.getFullYear());
+      returnArr.push(this.formatNumber(date.getMonth() + 1));
+      returnArr.push(this.formatNumber(date.getDate()));
+
+      returnArr.push(this.formatNumber(date.getHours()));
+      returnArr.push(this.formatNumber(date.getMinutes()));
+      returnArr.push(this.formatNumber(date.getSeconds()));
+
+      for (var i in returnArr) {
+        format = format.replace(formateArr[i], returnArr[i]);
+      }
+      return format;
+    },
+
+    //鏁版嵁杞寲  
+    formatNumber(n) {
+      n = n.toString()
+      return n[1] ? n : '0' + n
+    },
+    menuOpen(event) {
+
+    },
+    menuClose(event) {
+
+    },
+    handleEdit(row) {
+      console.log(row);
+      row.edit = true;
+    },
+    handleCancel(row) {
+      row.edit = false;
+      console.log(row);
+    },
+    handleSave(row) {
+      console.log(row);
+      row.edit = false;
+      this.$notify({
+        message: "淇濆瓨鎴愬姛",
+        type: "success"
+      });
+    },
+    //鏍¢獙鍩熷悕
+    vaildHost(str) {
+      let re = /^(?=^.{3,255}$)(http(s)?:\/\/)?(www\.)?[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(\.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+(:\d+)*(\/\w+\.\w+)*$/
+      return re.test(str)
+    },
+  }
+};
+</script>
+<style lang="scss">
+.s-basic-setting {
+  width: 100%;
+  height: 100%;
+  .el-form {
+    width: 1000px;
+
+    // margin-left: -80px;
+    .el-form-item {
+      text-align: left;
+      &.is-required:not(.is-no-asterisk) > .el-form-item__label:before {
+        margin-left: -8px;
+      }
+      .el-button {
+        float: right;
+      }
+
+      .el-form-item__content {
+        text-align: left;
+        input {
+          max-width: 360px;
+        }
+        .el-date-editor.el-input,
+        .el-date-editor.el-input__inner {
+          width: 216px;
+        }
+        .el-checkbox__label {
+          padding-left: 5px;
+        }
+      }
+
+      .el-form-item__label {
+        text-align: left;
+      }
+    }
+  }
+  .alarmSetting {
+    .el-input {
+      width: 100%;
+      // padding-right: 10px;
+    }
+    .el-select {
+      max-width: 113px;
+    }
+    .el-slider {
+      width: calc(100% - 120px);
+      display: inline-block;
+      padding-right: 30px;
+      box-sizing: border-box;
+      vertical-align: middle;
+    }
+    .el-input-number {
+      width: 100px;
+      display: inline-block;
+      .el-input {
+        width: 100%;
+      }
+    }
+  }
+
+  .time-type {
+    height: 25px;
+    width: 413px;
+    line-height: 28px;
+    padding: 3px 23px;
+    font-size: 14px;
+    font-weight: 600;
+    background-color: #e4e6ed;
+  }
+
+  #cut_min_duration {
+    .el-slider__bar {
+      background-color: #3d68e1;
+    }
+    .el-slider__button {
+      width: 10px;
+      height: 10px;
+      border: 4px solid #3d68e1;
+    }
+  }
+
+  #cut_max_duration {
+    .el-slider__bar {
+      background-color: #ff9e6e;
+    }
+    .el-slider__button {
+      width: 10px;
+      height: 10px;
+      border: 4px solid #ff9e6e;
+    }
+  }
+  .menu-css,
+  .el-menu {
+    border-right: none;
+    list-style: none;
+    position: relative;
+    margin: 0;
+    padding-left: 10px;
+    background-color: #ffffff;
+    .el-submenu__title {
+      height: 35px;
+      line-height: 35px;
+      font-size: 14px;
+      color: #303133;
+      padding: 0 20px;
+      list-style: none;
+      cursor: pointer;
+      position: relative;
+      -webkit-transition: border-color 0.3s, background-color 0.3s, color 0.3s;
+      transition: border-color 0.3s, background-color 0.3s, color 0.3s;
+      -webkit-box-sizing: border-box;
+      box-sizing: border-box;
+      white-space: nowrap;
+    }
+    .tree-font {
+      font-family: PingFangSC-Medium;
+      font-size: 14px;
+      color: #222222;
+      text-align: left;
+    }
+    li {
+      text-align: left;
+      .el-submenu__title {
+        // border-bottom: solid 1px #e6e6e6;
+        padding-left: 10px !important;
+        background-color: #e4e6ed !important;
+        border-radius: 2px;
+        .el-submenu__icon-arrow {
+          position: absolute;
+          top: 50%;
+          right: auto;
+          left: 135px;
+          margin-top: -7px;
+          -webkit-transition: -webkit-transform 0.3s;
+          transition: -webkit-transform 0.3s;
+          transition: transform 0.3s;
+          transition: transform 0.3s, -webkit-transform 0.3s;
+          font-size: 12px;
+        }
+      }
+    }
+  }
+  .save-btn {
+    text-align: right;
+    position: relative;
+    right: 40px;
+  }
+}
+</style>
+<style lang="scss" scoped>
+.flex-box {
+  display: flex;
+  height: 50px;
+  label {
+    width: 120px;
+  }
+  .el-input {
+    width: 300px;
+  }
+}
+.desc-info {
+  margin-bottom: 14px;
+  .flex-box {
+    height: 40px;
+    line-height: 40px;
+    .xiangqin-label {
+      width: 80px;
+    }
+  }
+}
+.menu-css,
+.el-menu {
+  border-right: none;
+  list-style: none;
+  position: relative;
+  margin: 0;
+  padding-left: 0;
+  background-color: #ffffff;
+
+  .tree-font {
+    font-family: PingFangSC-Medium;
+    font-size: 14px;
+    color: #222222;
+    text-align: left;
+  }
+  li {
+    text-align: left;
+    .el-submenu__title {
+      .el-submenu__icon-arrow {
+        position: absolute;
+        top: 50%;
+        right: 0;
+        margin-top: -7px;
+        -webkit-transition: -webkit-transform 0.3s;
+        transition: -webkit-transform 0.3s;
+        transition: transform 0.3s;
+        transition: transform 0.3s, -webkit-transform 0.3s;
+        font-size: 12px;
+      }
+    }
+  }
+}
+</style>
diff --git a/src/pages/systemSettings/components/CloudNode.vue b/src/pages/systemSettings/components/CloudNode.vue
new file mode 100644
index 0000000..e99063f
--- /dev/null
+++ b/src/pages/systemSettings/components/CloudNode.vue
@@ -0,0 +1,287 @@
+<template>
+  <div class="cloud">
+    <div class="inner">
+      <!-- <div
+        class="rect"
+        :style="{width:`${minWidth+BaseWidth}px`,height:`${minHeight+BaseHeight}px`}"
+      >-->
+      <div class="rect">
+        <!-- <div
+          class="node"
+          v-for="item in insideNodes"
+          :key="item.id"
+          :style="{top:item.t+'px',left:item.l+'px'}"
+        >
+          <span class="node-icon">
+          </span>
+          <span class="node-name">{{item.nodeName}}</span>
+        </div>-->
+        <serfDiagram
+          ref="inside-nodes"
+          :members="insideNodes"
+          :agent="agentName"
+          :sizeX="insideSizeX"
+          :sizeY="insideSizeY"
+          :startX="insideStartX"
+          :isShowHover="true"
+          class="inside-nodes"
+        ></serfDiagram>
+      </div>
+    </div>
+    <div class="outer" v-if="outsideNodes.length">
+      <serfDiagram
+        ref="outer-nodes"
+        :members="outsideNodes"
+        :agent="agentName"
+        :sizeX="280"
+        :sizeY="370"
+        :startX="60"
+        class="outer-nodes"
+      ></serfDiagram>
+      <!-- <div
+        class="node"
+        v-for="(item,index) in outsideNodes"
+        :key="item.id"
+        :style="{top:36*(index+1)+'px',left:60*(index+1)+'px'}"
+      >
+        <span class="node-icon"></span>
+        <span class="node-name">{{item.nodeName}}</span>
+      </div>-->
+    </div>
+  </div>
+</template>
+<script>
+import SerfDiagram from "@/components/serfDiagram";
+export default {
+  name: 'cloudNode',
+  props: {
+    nodes: Array
+  },
+  components: {
+    SerfDiagram
+  },
+  data () {
+    return {
+      agentName: '',
+      nodeIcons: [],
+      //insideNodes: [],
+      BaseWidth: 150,
+      BaseHeight: 70,
+      minWidth: 0,
+      minHeight: 0,
+      mockData: [
+        {
+          cluster_id: "b6132bfe-d3af-4710-ba89-436f614c2f46",
+          hardwareType: "01",
+          id: "DSVAD010120190622",
+          node_id: "DSVAD010120190622",
+          node_ip: "192.168.20.10:30190",
+          nodeName: "寮�鍙�20.10-1",
+          role: 'pc'
+        },
+        {
+          cluster_id: "b6132bfe-d3af-4710-ba89-436f614c2f",
+          hardwareType: "02",
+          id: "DSVAD010120190623",
+          node_id: "DSVAD010120190623",
+          node_ip: "192.168.20.10:30190",
+          nodeName: "寮�鍙戞祴璇�20.11-1",
+          role: 'master'
+        },
+        {
+          cluster_id: "b6132bfe-d3af-4710-ba89-436f614c2g",
+          hardwareType: "03",
+          id: "DSVAD010120190624",
+          node_id: "DSVAD010120190624",
+          node_ip: "192.168.20.10:30190",
+          nodeName: "娴嬭瘯20.13-1",
+          role: 'pc'
+        },
+        {
+          cluster_id: "b6132bfe-d3af-4710-ba89-436f614c2h",
+          hardwareType: "03",
+          id: "DSVAD010120190625",
+          node_id: "DSVAD010120190625",
+          node_ip: "192.168.20.10:30190",
+          nodeName: "娴嬭瘯20.101-1",
+          role: 'server'
+        },
+        {
+          cluster_id: "b6132bfe-d3af-4710-ba89-436f614cf",
+          hardwareType: "02",
+          id: "DSVAD01012019063",
+          node_id: "DSVAD01012019063",
+          node_ip: "192.168.20.10:30190",
+          nodeName: "寮�鍙戞祴璇�20.15-1",
+          role: 'master'
+        },
+        {
+          cluster_id: "b6132bfe-d3af-710-ba89-436f614cf",
+          hardwareType: "02",
+          id: "DSVAD0101201906",
+          node_id: "DSVAD0101209063",
+          node_ip: "192.168.20.10:30190",
+          nodeName: "k20.15-128437586",
+          role: 'master'
+        },
+        {
+          cluster_id: "b612bfe-d3af-710-ba89-436f614cf",
+          hardwareType: "02",
+          id: "DSVAD010120906",
+          node_id: "DSVAD010120963",
+          node_ip: "192.168.20.107:30190",
+          nodeName: "kfl20.15-127586",
+          role: 'master'
+        },
+        {
+          cluster_id: "b6132bfe-d3af-710-ba89-436f614cf",
+          hardwareType: "02",
+          id: "DSVAD0101201906",
+          node_id: "DSVAD001209063",
+          node_ip: "192.168.20.10:30190",
+          nodeName: "k20.15-128437586",
+          role: 'master'
+        },
+        {
+          cluster_id: "b612bfe-d3af-710-ba89-436f614cf",
+          hardwareType: "02",
+          id: "DSVAD01010906",
+          node_id: "DSVAD012063",
+          node_ip: "192.168.20.107:30190",
+          nodeName: "kfl20.15-127586",
+          role: 'master'
+        },
+        {
+          cluster_id: "b6132bfe-d3af-710-ba89-436f614cf",
+          hardwareType: "02",
+          id: "DSVAD0101201906",
+          node_id: "DSVAD0012063",
+          node_ip: "192.168.20.10:30190",
+          nodeName: "k20.15-128437586",
+          role: 'master'
+        },
+        {
+          cluster_id: "b612bfe-d3af-710-ba89-436f614cf",
+          hardwareType: "02",
+          id: "DSVAD01010906",
+          node_id: "DSVAD01012063",
+          node_ip: "192.168.20.107:30190",
+          nodeName: "kfl20.15-127586",
+          role: 'master'
+        },
+      ]
+    }
+  },
+  mounted () {
+    console.log(this.nodes)
+    //this.getInsideNodes();
+  },
+  methods: {
+    getRandom (index) {
+      if (index % 2 == 0) {
+        return Math.random() * 20
+      } else {
+        return Math.random() * 50
+      }
+    },
+    getInsideNodes () {
+      //return this.nodes.filter(item=>item.hardwareType=='01'||item.hardwareType=='02');
+      //return this.mockData.filter(item => item.hardwareType == '01' || item.hardwareType == '02');
+      let arr = this.nodes.filter(item => item.hardwareType == '01' || item.hardwareType == '02');
+      let len = arr.length;
+      let lefts = [];
+      let tops = [];
+      this.insideNodes = arr.map((item, index) => {
+        lefts.push((20 - len) * (index + 1) + this.getRandom(index));
+        tops.push(30 * (index + 1));
+        return {
+          l: 10 + this.getRandom(index),
+          t: 30 * (index + 1),
+          nodeName: item.nodeName,
+          id: item.id,
+          workType: item.workType
+        }
+      });
+      this.minWidth = Math.max(...lefts) - Math.min(...lefts);
+      this.minHeight = Math.max(...tops) - Math.min(...tops);
+      console.log('w,h', this.minWidth, this.minHeight);
+    },
+  },
+  computed: {
+    cloudPic () {
+      return '/images/settings/cloud.png'
+    },
+    insideNodes () {
+      return this.nodes.filter(item => item.hardwareType == '01' || item.hardwareType == '02');
+    },
+    insideSizeX () {
+      return 160 + 200 * 0.2 * (this.insideNodes.length) <= 400 ? 160 + 200 * 0.2 * (this.insideNodes.length) : 400;
+    },
+    insideSizeY () {
+      return 140 + 200 * 0.2 * (this.insideNodes.length) <= 380 ? 140 + 200 * 0.2 * (this.insideNodes.length) : 380;
+    },
+    insideStartX () {
+      return this.insideSizeX / 3
+    },
+    // insideNodes () {
+    //   //return this.nodes.filter(item=>item.hardwareType=='01'||item.hardwareType=='02');
+    //   //return this.mockData.filter(item => item.hardwareType == '01' || item.hardwareType == '02');
+    //   let arr = this.mockData.filter(item => item.hardwareType == '01' || item.hardwareType == '02');
+    //   let len = arr.length;
+    //   let lefts = [];
+    //   let tops = [];
+    //   let temp = arr.map((item,index)=>{
+    //     lefts.push((20-len)*(index+1));
+    //     tops.push(30*(index+1));
+    //     return {
+    //       l: (20-len)*(index+1),
+    //       t: 30*(index+1),
+    //       nodeName: item.nodeName,
+    //       id: item.id,
+    //       workType: item.workType
+    //     }
+    //   });
+    //   return temp;
+    // },
+    outsideNodes () {
+      return this.nodes.filter(item=>item.hardwareType=='03');
+      //return this.mockData.filter(item => item.hardwareType == '03');
+    }
+  }
+}
+</script>
+<style lang="scss">
+.cloud {
+  width: 100%;
+  display: flex;
+  .inner {
+    background: url('/images/settings/easy-cloud.png') no-repeat;
+    background-size: 100%;
+    margin-top: -80px;
+    .rect {
+      //background: rgba(176, 203, 253, 0.3);
+      position: relative;
+      margin: 130px 100px 100px;
+      .node {
+        position: absolute;
+        .node-icon {
+          width: 40px;
+          height: 40px;
+        }
+        .node-name {
+          font-size: 14px;
+          color: #333;
+        }
+      }
+    }
+  }
+  .outer {
+    width: 40%;
+    position: relative;
+    text-align: left;
+    .node {
+      position: absolute;
+    }
+  }
+}
+</style>
\ No newline at end of file
diff --git a/src/pages/systemSettings/components/ClusterManagement.vue b/src/pages/systemSettings/components/ClusterManagement.vue
new file mode 100644
index 0000000..bedd193
--- /dev/null
+++ b/src/pages/systemSettings/components/ClusterManagement.vue
@@ -0,0 +1,885 @@
+<template>
+  <div class="s-cluster-management">
+    <div class="ui-top-view">
+      <div class="ui-top-title">瑙嗛鍒嗘瀽闆嗙兢绠$悊</div>
+    </div>
+    <el-row>
+      <el-col :span="12">
+        <el-tabs v-model="activeName" id="e-alaycluster" v-if="!isHasColony">
+          <el-tab-pane label="鍒涘缓闆嗙兢" name="1" :disabled="isHasColony">
+            <el-form :model="ruleForm" :rules="rules" ref="ruleForm" label-width="100px">
+              <el-form-item label="闆嗙兢鍚嶇О" prop="clustername">
+                <el-input v-model="ruleForm.clustername" placeholder="鎵嬪姩杈撳叆, 濡傗�滈泦缇鈥�" size="small"></el-input>
+              </el-form-item>
+              <el-form-item label="闆嗙兢ID">
+                <el-input v-model="clusterid" placeholder="涓嶅厑璁歌緭鍏�,淇濆瓨鍚庡洖鏄�" disabled size="small"></el-input>
+              </el-form-item>
+              <el-form-item label="闆嗙兢瀵嗙爜" prop="clusterpwd">
+                <el-input v-model="ruleForm.clusterpwd" placeholder="璇疯緭鍏�6浣嶅瘑鐮�,鎴栫偣鍑荤敓鎴�" size="small">
+                  <el-button type="text" slot="suffix" @click="generatePassword">鐢熸垚瀵嗙爜</el-button>
+                </el-input>
+              </el-form-item>
+              <el-form-item label="闆嗙兢IP" prop="virtualIp">
+                <ip-input :ip="ruleForm.virtualIp" :on-blur="onIpBlur" class="ip-input-comp"></ip-input>
+              </el-form-item>
+              <el-form-item>
+                <el-button type="primary" size="small" @click="submitForm('ruleForm')">淇濆瓨</el-button>
+              </el-form-item>
+            </el-form>
+          </el-tab-pane>
+
+          <!-- 鍔犲叆宸叉湁闆嗙兢 -->
+          <el-tab-pane label="鍔犲叆宸叉湁闆嗙兢" name="2" :disabled="isHasColony">
+            <el-form
+              label-width="80px"
+              :model="joinForm"
+              :rules="joinRules"
+              ref="joinForm"
+              class="join-form"
+              v-loading="joinLoading"
+            >
+              <el-form-item label="闆嗙兢ID" style="width:440px" prop="clusterid">
+                <el-input v-model="joinForm.clusterid" placeholder size="small"></el-input>
+              </el-form-item>
+              <el-form-item label="IP鍦板潃" style="width:440px" prop="clusterip">
+                <el-input
+                  v-model="joinForm.clusterip"
+                  placeholder="璇疯緭鍏ラ泦缇ゅ唴浠绘剰IP鍦板潃"
+                  size="small"
+                  autocomplete="new-password"
+                ></el-input>
+
+                <!-- <el-button size="mini" :disabled="searchDis" @click="searchColony">鎼滅储闆嗙兢</el-button>
+                <el-button size="mini" @click="stopSearch">鍋滄鎼滅储</el-button>-->
+              </el-form-item>
+              <el-form-item label="闆嗙兢瀵嗙爜" prop="clusterpwd" style="width:440px">
+                <el-input
+                  v-model="joinForm.clusterpwd"
+                  placeholder="璇疯緭鍏ラ泦缇ゅ瘑鐮�"
+                  show-password
+                  size="small"
+                  autocomplete="new-password"
+                >
+                  <el-button
+                    type="text"
+                    slot="suffix"
+                    v-show="!searchDis"
+                    @click="searchColony"
+                  >鎼滅储闆嗙兢</el-button>
+                  <el-button type="text" slot="suffix" v-show="searchDis" @click="stopSearch">
+                    <i class="el-icon-loading"></i>鍋滄鎼滅储
+                  </el-button>
+                </el-input>
+              </el-form-item>
+              <el-form-item style="width:440px">
+                <el-button type="primary" @click="join('joinForm')" size="small">鍔犲叆闆嗙兢</el-button>
+              </el-form-item>
+              <div class="form-tip">璇疯緭鍏ヤ互涓婁俊鎭姞鍏ラ泦缇�,鎴栬�呴�氳繃闆嗙兢瀵嗙爜鎼滅储鍚庤繘琛屽姞鍏�</div>
+            </el-form>
+          </el-tab-pane>
+        </el-tabs>
+        <!-- 鏈夐泦缇ょ殑鎯呭喌 -->
+        <div v-if="isHasColony" id="h-alaycluster">
+          <el-form :model="ruleForm" ref="ruleForm" label-width="100px">
+            <el-form-item label="闆嗙兢鍚嶇О" prop="clustername">
+              <el-input v-model="ruleForm.clustername" placeholder="鎵嬪姩杈撳叆, 濡傗�滈泦缇鈥�" size="small"></el-input>
+            </el-form-item>
+            <el-form-item label="闆嗙兢ID">
+              <el-input v-model="clusterid" placeholder="涓嶅厑璁歌緭鍏�,淇濆瓨鍚庡洖鏄�" disabled size="small"></el-input>
+            </el-form-item>
+            <el-form-item label="闆嗙兢瀵嗙爜" prop="clusterpwd">
+              <el-input
+                v-model="ruleForm.clusterpwd"
+                disabled
+                placeholder="璇疯緭鍏�6浣嶅瘑鐮�,鎴栫偣鍑荤敓鎴�"
+                size="small"
+              ></el-input>
+            </el-form-item>
+
+            <el-form-item label="闆嗙兢IP" prop="virtualIp">
+              <ip-input :ip="ruleForm.virtualIp" :on-blur="onIpBlur" class="ip-input-comp"></ip-input>
+            </el-form-item>
+            <el-form-item style="text-align: right;">
+              <el-button size="small" type="danger" @click="leave">閫�鍑洪泦缇�</el-button>
+              <el-button
+                style="margin-right:10px;"
+                type="primary"
+                size="small"
+                @click="updateCluster('manageForm')"
+              >淇濆瓨</el-button>
+            </el-form-item>
+          </el-form>
+        </div>
+      </el-col>
+      <el-col
+        :span="12"
+        style="height: 100%;"
+        v-if="members.length !== 0 && isSearch"
+        class="node-container"
+      >
+        <serfDiagram
+          ref="diagram"
+          :members="members"
+          :agent="agentName"
+          v-loading="loading"
+          :isShowHover="false"
+          @selected-node="joinNode"
+          class="nodes-svg"
+        ></serfDiagram>
+      </el-col>
+      <el-col
+        :span="12"
+        style="height: 100%;"
+        v-if="innerNodes.length !== 0 && !isSearch"
+        class="node-container"
+      >
+        <cloud-node :nodes="innerNodes"></cloud-node>
+      </el-col>
+    </el-row>
+
+    <!-- <div class="ui-top-view">
+      <div class="ui-top-title">瀛樺偍闆嗙兢绠$悊</div>
+    </div>
+    <el-row>
+      <el-col :span="12">
+        <el-tabs id="e-dbcluster" v-model="sActiveName">
+          <el-tab-pane label="鍒涘缓闆嗙兢" name="s-first" v-if="sActiveName != 's-third1'">
+            <el-button
+              type="primary"
+              style="float: left;margin: 20px 0px;"
+              size="small"
+              @click="createEsCluster()"
+            >鍒涘缓瀛樺偍闆嗙兢</el-button>
+            
+          </el-tab-pane>
+          <el-tab-pane label="鍔犲叆宸叉湁闆嗙兢" name="s-second" v-if="sActiveName != 's-third1'">
+            <el-form label-width="80px">
+              <el-form-item label="IP鍦板潃" style="text-align: left;width: 300px;">
+                <el-input
+                  v-model="esNodeIp"
+                  placeholder="璇疯緭鍏ラ泦缇ゅ唴浠绘剰IP鍦板潃"
+                  size="small"
+                  autocomplete="off"
+                ></el-input>
+                <el-checkbox
+                  label="涓昏妭鐐�"
+                  v-model="esNodeType"
+                  style="margin-left: 20px;position: absolute;"
+                ></el-checkbox>
+              </el-form-item>
+              <el-form-item>
+                <el-button
+                  type="primary"
+                  @click="joinESCluster()"
+                  size="small"
+                  style="float: left;"
+                >鍔犲叆闆嗙兢</el-button>
+              </el-form-item>
+            </el-form>
+          </el-tab-pane>
+          <el-tab-pane label="闆嗙兢淇℃伅" name="s-third">
+            <el-table :data="esNodes" style="width: 100%">
+              <el-table-column prop="nodeType" label="鑺傜偣绫诲瀷"></el-table-column>
+              <el-table-column prop="name" label="鑺傜偣鍚嶇О"></el-table-column>
+              <el-table-column prop="ip" label="鑺傜偣IP鍦板潃" min-width="90px"></el-table-column>
+              <el-table-column prop="buildDate" label="娉ㄥ唽鏃堕棿" min-width="120px"></el-table-column>
+            </el-table>
+          </el-tab-pane>
+        </el-tabs>
+      </el-col>
+    </el-row>-->
+  </div>
+</template>
+
+<script>
+import {
+  createSerfCluster,
+  randomPwd,
+  search,
+  getSearchNodes,
+  stopSearching,
+  findCluster,
+  updateClusterName,
+  joinCluster,
+  leave,
+  getVrrp,
+  setVrrp,
+  createESNode,
+  addESNode,
+  getEsClusterInfo
+} from "@/api/clusterManage";
+
+import {
+  getDevInfo
+} from "@/api/system";
+import cloudNode from "./CloudNode";
+import serfDiagram from "@/components/serfDiagram";
+import ipInput from "@/components/subComponents/IPInput";
+import { isIPv4 } from "@/scripts/validate";
+export default {
+  components: {
+    serfDiagram,
+    ipInput,
+    cloudNode
+  },
+  data() {
+    const checkPwd = (rule, value, callback) => {
+      if (!value) {
+        return callback(new Error("瀵嗙爜涓嶈兘涓虹┖"));
+      }
+      setTimeout(() => {
+        if (value.length != 6) {
+          callback(new Error("瀵嗙爜搴斾负6浣�!"));
+        } else {
+          callback();
+        }
+      }, 1000);
+    };
+
+    return {
+      activeName: "1",
+      sActiveName: "s-first",
+      clusterid: "",
+      esNodeIp: "",
+      esNodeType: "",
+      clusterpwd2: "",
+      sClusterip: "",
+      ruleForm: {
+        clustername: "",
+        clusterpwd: "",
+        virtualIp: ""
+      },
+      vrIpForm: {
+        enable: true,
+        //serve_port: "",
+        serve_port: null,
+        virtual_ip: ""
+      },
+      manageForm: {
+        clustername: "娴嬭瘯闆嗙兢1",
+        clusterpwd: "123456",
+        virtualip: "192.168.1.188"
+      },
+      joinForm: {
+        clusterid: "",
+        clusterip: "",
+        clusterpwd: ""
+      },
+      rules: {
+        clustername: [
+          { required: true, message: "璇疯緭鍏ラ泦缇ゅ悕绉�", trigger: "change" }
+        ],
+        clusterpwd: [{ validator: checkPwd, trigger: "change" }],
+        virtualIp: [
+          { required: true, validator: isIPv4, trigger: "change" }
+        ]
+      },
+      // vrIpRules: {
+      //   virtualIp: [
+      //     { required: true, message: "璇疯緭鍏ヨ櫄鎷烮P", trigger: "change" }
+      //   ]
+      // },
+      joinRules: {
+        clusterid: [
+          { required: true, message: "璇疯緭鍏ラ泦缇D", trigger: "change" },
+        ],
+        clusterip: [
+          { required: true, validator: isIPv4, trigger: "change" }
+        ],
+        clusterpwd: [
+          { validator: checkPwd, trigger: "change" }
+        ]
+      },
+      esNodes: [],
+      scheduleId: "",
+      isHasColony: false,
+      isSearch: false,
+      currentCluster: {},
+      searchNum: "",
+      loading: false,
+      searchDis: false,
+      agentName: "",
+      members: [],
+      innerNodes: [],
+      intervalTimer: null,
+      joinLoading: false,
+      showJoinConfirm: false
+    };
+  },
+  mounted() {
+    this.findCluster();
+    let _this = this;
+    this.intervalTimer = setInterval(() => {
+      _this.findCluster();
+    }, 30000);
+    //this.getEsClusterNodes();
+  },
+  beforeDestroy() {
+    clearInterval(this.intervalTimer);
+  },
+  methods: {
+    checkPsd(psd) {
+      return psd.trim().length === 6
+    },
+    // cleanValue() {
+    //   this.members = [];
+    // },
+    // sHandleClick(tab, event) {
+    //   console.log(tab, event);
+    // },
+    submitForm(formName) {
+      this.$refs[formName].validate(valid => {
+        if (valid) {
+          //alert("submit!");
+          let json = {
+            clusterId: this.clusterid,
+            clusterName: this.ruleForm.clustername,
+            password: this.ruleForm.clusterpwd,
+            virtualIp: this.ruleForm.virtualIp
+          };
+          this.createCluster(json).then(() => {
+            this.findCluster();
+          });
+        } else {
+          console.log("error submit!!");
+          return false;
+        }
+      });
+    },
+
+    // saveForm(formName) {
+    //   this.$refs[formName].validate(valid => {
+    //     if (valid) {
+    //       alert("submit!");
+    //       let json = {
+    //         enable: this.vrIpForm.enable,
+    //         serve_port: this.vrIpForm.serve_port,
+    //         virtual_ip: this.vrIpForm.virtual_ip,
+
+    //       };
+    //       setVrrp(json).then(() => {
+    //         this.getVrrpInfo();
+    //       });
+    //     } else {
+    //       console.log("error submit!!");
+    //       return false;
+    //     }
+    //   });
+    // },
+
+    join(formName) {
+      let _this = this;
+      this.$refs[formName].validate(valid => {
+        if (valid) {
+          _this.joinLoading = true;
+          // if (Object.keys(this.currentCluster).length === 0) {
+          //   this.$notify({
+          //     type: "info",
+          //     duration: 1000,
+          //     message: "璇峰厛閫夋嫨涓�涓泦缇よ妭鐐�"
+          //   });
+          //   _this.joinLoading = false;
+          //   return true;
+          // }
+          let nodeIps = this.members.map(i => {
+            return i.Address;
+          });
+          let json = {
+            //clusterId: this.currentCluster.cluster_id,
+            clusterId: this.joinForm.clusterid,
+            password: this.joinForm.clusterpwd,
+            nodeIps: [this.joinForm.clusterip]
+          };
+          this.joinCluster(json).then(() => {
+            _this.joinLoading = false;
+            this.findCluster();
+          }).catch(e => {
+            console.log(e);
+            _this.joinLoading = false;
+          });
+        } else {
+          console.log("error submit!!");
+          return false;
+        }
+      });
+    },
+    async createCluster(json) {
+      let res = await createSerfCluster(json);
+      console.log(res, "鍒涘缓闆嗙兢");
+      this.$notify({
+        title: res.success ? "鎴愬姛" : "澶辫触",
+        message: res.msg,
+        type: res.success ? "success" : "error"
+      });
+    },
+    async randomPwd() {
+      let res = await randomPwd();
+      if (res && res.success) {
+        this.ruleForm.clusterpwd = res.data;
+      }
+    },
+    async searchColony() {
+      this.isSearch = true;
+      this.$refs["joinForm"].clearValidate();
+      this.$refs["joinForm"].validateField('clusterpwd');
+      if (this.checkPsd(this.joinForm.clusterpwd)) {
+        this.members = [];
+        let json = {
+          password: this.joinForm.clusterpwd,
+          //ip: this.joinForm.clusterip
+        };
+
+        this.search(json)
+          .then(() => {
+            this.setSchedule();
+            // this.searchDis = false;
+            // this.loading = false;
+          })
+          .catch(() => {
+            this.searchDis = false;
+            this.loading = false;
+            this.isSearch = false;
+          });
+      } else {
+        this.searchDis = false;
+        this.loading = false;
+        this.isSearch = false;
+        return false;
+      }
+      //});
+    },
+    async search(json) {
+      let res = await search(json);
+      if (res && res.success) {
+        console.log(res, "鎼滅储闆嗙兢");
+        this.searchNum = res.data;
+      }
+      this.searchDis = true;
+      this.loading = true;
+      window.setTimeout(() => {
+        this.stopSearch();
+      }, 10 * 1000);
+    },
+    //鎼滅储闆嗙兢
+    async getSearchNodes() {
+      let res = await getSearchNodes();
+      if (res && res.success) {
+        let list = res.data.map(i => {
+          let obj = {};
+          obj.cluster_id = i.clusterID ? i.clusterID : "";
+          obj.create_time = i.create_time ? i.create_time : "";
+          obj.id = i.nodeID ? i.nodeID : "";
+          obj.node_id = i.nodeID ? i.nodeID : "";
+          obj.Address = i.nodeAddress ? i.nodeAddress : "";
+          obj.nodeName = i.nodeAddress ? i.nodeAddress : "";
+          obj.role = i.role ? i.role : "pc";
+          return obj;
+        });
+        list.map(i => {
+          let found = this.members.find(element => {
+            return element.node_id === i.node_id;
+          });
+          if (found === undefined) {
+            this.members.push(i);
+          }
+        });
+      }
+    },
+    setSchedule() {
+      this.scheduleId = window.setInterval(() => {
+        this.getSearchNodes();
+      }, 1000);
+    },
+    async stopSearch() {
+      if (!this.loading) {
+        return true;
+      }
+      stopSearching({
+        searchNum: this.searchNum
+      }).then((res) => {
+        console.log(res, '姝e父缁撴潫')
+        this.loading = false;
+        this.searchDis = false;
+        window.clearInterval(this.scheduleId);
+      }).catch((err) => {
+        console.log(err, '鎶ラ敊缁撴潫')
+        this.$notify({
+          type: 'error',
+          duration: 1000,
+          message: '鍋滄鎼滅储鎶ラ敊锛�'
+        })
+        // window.setTimeout(()=>{
+        //   this.loading = false;
+        //   this.searchDis = false;
+        //   window.clearInterval(this.scheduleId);
+        // },2000)
+      })
+    },
+    async findCluster() {
+      let res = await findCluster();
+      if (res && res.success) {
+        if (res.data && res.data.clusterId) {
+          this.isHasColony = true;
+          this.activeName = "3";
+          this.clusterid = res.data.clusterId;
+          this.ruleForm.clustername = res.data.clusterName;
+          this.ruleForm.clusterpwd = '******';
+          this.ruleForm.virtualIp = res.data.virtualIp
+          //let list = res.data.nodes.map(i => {
+          this.isSearch = false;
+          this.innerNodes = res.data.nodes.map(i => {
+            let obj = {};
+            obj.device_type = i.device_type;
+            obj.workType = i.device_type.substr(2, 2);
+            obj.hardwareType = i.device_type.substr(4, 2);
+            obj.cluster_id = i.cluster_id;
+            obj.clusterName = res.data.clusterName;
+            obj.create_time = i.create_time;
+            obj.id = i.id;
+            obj.node_id = i.node_id;
+            obj.node_ip = i.node_ip;
+            obj.nodeName = i.node_name;
+            obj.Address = i.node_ip;
+            obj.role = i.drift_state ? i.drift_state : "pc";
+            return obj;
+          });
+
+          //this.members = this.members.concat(list);
+          console.log(this.members)
+        } else {
+          this.isHasColony = false;
+          // this.activeName = '1'
+        }
+      }
+    },
+    // getVrrpInfo() {
+    //   getVrrp().then(res => {
+    //     if (res.success) {
+    //       this.vrIpForm.virtual_ip = res.data.virtual_ip;
+    //       this.vrIpForm.enable = res.data.enable;
+    //     }
+    //   }).catch(e => {
+    //     console.log(e)
+    //   })
+    // },
+    async updateCluster() {
+      if (this.ruleForm.clustername === "") {
+        this.$message({
+          type: "error",
+          message: "闆嗙兢鍚嶇О涓嶈兘涓虹┖"
+        })
+
+        return
+      }
+
+      let res = await updateClusterName({
+        clusterName: this.ruleForm.clustername,
+        virtualIp: this.ruleForm.virtualIp
+      });
+      this.$notify({
+        title: res.success ? "鎴愬姛" : "澶辫触",
+        message: res.msg,
+        type: res.success ? "success" : "error"
+      });
+    },
+    async joinCluster(json) {
+      let res = await joinCluster(json);
+      if (res.success) {
+        this.members = []
+      }
+      this.$notify({
+        title: res.success ? "鎴愬姛" : "澶辫触",
+        message: res.msg,
+        type: res.success ? "success" : "error"
+      });
+    },
+    leave() {
+      this.$confirm(`纭畾閫�鍑洪泦缇ゅ悧?`, {
+        center: true,
+        cancelButtonClass: "comfirm-class-cancle",
+        confirmButtonClass: "comfirm-class-sure"
+      }).then(async () => {
+        let res = await leave();
+        this.$notify({
+          title: res.success ? "鎴愬姛" : "澶辫触",
+          message: res.msg,
+          type: res.success ? "success" : "error"
+        });
+        if (res && res.success) {
+          this.ruleForm.clustername = "";
+          this.ruleForm.clusterpwd = ""
+          this.clusterid = "";
+          this.isHasColony = false;
+          this.activeName = "1";
+          this.members = [];
+          this.innerNodes = [];
+        }
+      }).catch(() => {
+         this.ruleForm.clustername = "";
+          this.ruleForm.clusterpwd = ""
+          this.clusterid = "";
+          this.isHasColony = false;
+          this.activeName = "1";
+          this.members = [];
+          this.innerNodes = [];
+       });
+
+    },
+    joinNode(event, node) {
+      console.log('join', node)
+      let _this = this;
+      this.currentCluster.cluster_id = node.cluster_id;
+      if (this.activeName === "3") {
+        this.manageForm.clustername = node.clusterName;
+        this.clusterid = node.cluster_id;
+        return;
+      }
+      if (this.activeName === "2") {
+        if (_this.showJoinConfirm) return;
+
+        this.$confirm("鏄惁瑕佸姞鍏ヨ妭鐐� " + node.nodeName + "?", "鍔犲叆闆嗙兢", {
+          confirmButtonText: "纭畾",
+          cancelButtonText: "鍙栨秷",
+          type: "success"
+        })
+          .then(() => {
+            _this.showJoinConfirm = true;
+            let json = {
+              //clusterId: this.currentCluster.cluster_id,
+              clusterId: node.cluster_id,
+              password: this.joinForm.clusterpwd,
+              nodeIps: [node.Address]
+            };
+            this.joinCluster(json).then(() => {
+              _this.showJoinConfirm = false;
+              this.findCluster();
+            }).catch(e => {
+              console.log(e);
+              _this.showJoinConfirm = false;
+            });
+          }).catch(e => {
+            console.log(e)
+          });
+
+        // this.$refs["joinForm"].validate(valid => {
+        //   if (valid) {
+        //     if (_this.showJoinConfirm) return;
+        //     _this.showJoinConfirm = true;
+        //     this.$confirm("鏄惁瑕佸姞鍏ヨ妭鐐� " + node.nodeName + "?", "鍔犲叆闆嗙兢", {
+        //       confirmButtonText: "纭畾",
+        //       cancelButtonText: "鍙栨秷",
+        //       type: "success"
+        //     })
+        //       .then(() => {
+
+        //         console.log(this.currentCluster, '閫夋嫨鐨勯泦缇よ妭鐐�')
+        //         this.join("joinForm");
+        //         _this.showJoinConfirm = false;
+        //       })
+        //       .catch(() => {
+        //         this.$notify({
+        //           type: "info",
+        //           duration: 1000,
+        //           message: "宸插彇娑�"
+        //         });
+        //         _this.showJoinConfirm = false;
+        //       });
+        //   } else {
+        //     console.log("error submit!!");
+        //     return false;
+        //   }
+        // });
+      }
+    },
+    generatePassword() {
+      var chars =
+        "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+      var uuid = [];
+
+      for (let i = 0; i < 6; i++) {
+        uuid[i] = chars[0 | (Math.random() * 50)];
+      }
+
+      this.ruleForm.clusterpwd = uuid.join("");
+    },
+
+    async getEsClusterNodes() {
+      let rsp = await getDevInfo();
+      let hostIpAddr = "";
+      if (rsp && rsp.success) {
+        hostIpAddr = rsp.data.ip;
+      }
+
+      if (hostIpAddr.length) {
+        rsp = await getEsClusterInfo({ ip: hostIpAddr });
+        if (rsp && rsp.success) {
+          this.esNodes = rsp.data.map(el => {
+            return {
+              // buildDate: "2018-06-11T23:38:03.357887Z",
+              buildDate: el.buildDate.split("T")[0] + " " + el.buildDate.split("T")[1].slice(0, 8),
+              ip: el.ip,
+              name: el.name,
+              nodeType: el.nodeType,
+            }
+          })
+
+          if (this.esNodes.length) {
+            this.sActiveName = 's-third';
+          }
+        }
+      }
+    },
+    createEsCluster() {
+      createESNode().then(rsp => {
+        if (rsp && rsp.success) {
+          this.$message({
+            type: "success",
+            duration: 2000,
+            message: "鍒涘缓鎴愬姛"
+          });
+
+          this.getSearchNodes();
+        } else {
+          this.$message({
+            type: "error",
+            duration: 2000,
+            message: rsp.msg
+          });
+        }
+      }).catch(rsp => {
+        this.$message({
+          type: "error",
+          duration: 2000,
+          message: rsp.msg
+        });
+      })
+    },
+    joinESCluster() {
+      if (!this.esNodeIp.length) {
+        this.$message({
+          type: "error",
+          duration: 2000,
+          message: "璇疯緭鍏ユ纭殑ip鍦板潃"
+        });
+        return;
+      }
+
+      addESNode({ ip: this.esNodeIp, option: this.esNodeType ? "1" : "2" }).then(rsp => {
+        if (rsp && rsp.success) {
+          this.$message({
+            type: "success",
+            duration: 2000,
+            message: "鍔犲叆鎴愬姛"
+          });
+
+          this.getSearchNodes();
+        } else {
+          this.$message({
+            type: "error",
+            duration: 2000,
+            message: rsp.msg
+          });
+        }
+      }).catch(rsp => {
+        this.$message({
+          type: "error",
+          duration: 2000,
+          message: rsp.msg
+        });
+      })
+    },
+    onIpBlur(ip) {
+      //this.vrIpForm.virtual_ip = ip;
+      this.ruleForm.virtualIp = ip;
+      console.log(this.ruleForm.virtualIp)
+    }
+
+  },
+
+  created() { }
+
+};
+</script>
+<style lang="scss">
+.s-cluster-management {
+  width: 100%;
+  height: 100%;
+  overflow: auto;
+  .el-form-item {
+    width: 500px;
+  }
+  .el-form-item.is-required:not(.is-no-asterisk) > .el-form-item__label:before,
+  .el-form-item.is-required:not(.is-no-asterisk)
+    .el-form-item__label-wrap
+    > .el-form-item__label:before {
+    display: none;
+  }
+  .ip-input-comp {
+    width: 400px;
+    max-width: 400px;
+  }
+  .el-button {
+    float: right;
+  }
+  .el-form-item__content {
+    text-align: left;
+
+    input {
+      max-width: 400px !important;
+    }
+  }
+
+  #e-alaycluster,
+  #e-dbcluster {
+    .el-tabs__header {
+      border: 0px solid #dcdfe6;
+      .el-tabs__item {
+        padding: 5px 50px;
+        height: 50px;
+        font-family: PingFangSC-Regular;
+        font-size: 14px;
+        color: #222222;
+        text-align: center;
+        border: 0px solid transparent;
+      }
+      .el-tabs__item:nth-child(2) {
+        padding-left: 50px;
+      }
+      .el-tabs__item:last-child {
+        padding-right: 50px;
+      }
+      .el-tabs__item.is-active {
+        color: #ff7733;
+        font-weight: bold;
+        // border-right-color: #fff;
+        // border-left-color: #fff;
+      }
+      .el-tabs__item:not(.is-disabled):hover {
+        color: #ff7733;
+      }
+    }
+    .el-tabs__active-bar {
+      background-color: #ff7733;
+    }
+    .el-form-item__content {
+      text-align: left;
+      input {
+        max-width: 420px;
+      }
+    }
+  }
+
+  #h-alaycluster {
+    .el-form-item__content {
+      text-align: left;
+      // input {
+      //   max-width: 360px;
+      // }
+    }
+  }
+}
+.ui-top-view {
+  height: 30px;
+  line-height: 30px;
+}
+</style>
diff --git a/src/pages/systemSettings/components/LogManagement.vue b/src/pages/systemSettings/components/LogManagement.vue
new file mode 100644
index 0000000..2b2d37e
--- /dev/null
+++ b/src/pages/systemSettings/components/LogManagement.vue
@@ -0,0 +1,190 @@
+<template>
+  <div class="s-log-management">
+    <div class="top">
+      <b>鏃ュ織绫诲瀷:</b>
+      <el-select v-model="logValue" placeholder="璇烽�夋嫨" size="small">
+        <el-option
+          v-for="item in logOptions"
+          :key="item.value"
+          :label="item.label"
+          :value="item.value"
+        ></el-option>
+      </el-select>
+      <b>鏃堕棿:</b>
+      <el-date-picker
+        v-model="timeValue"
+        type="datetimerange"
+        size="small"
+        range-separator="鑷�"
+        start-placeholder="寮�濮嬫棩鏈�"
+        end-placeholder="缁撴潫鏃ユ湡"
+      ></el-date-picker>
+      <el-input
+        v-model="searchValue"
+        placeholder="璇疯緭鍏ュ唴瀹�"
+        clearable
+        style="width: 150px;margin: 0px 10px;"
+        size="small"
+      ></el-input>
+      <el-button type="primary" size="small">鎼滅储</el-button>
+      <el-button type="danger" size="small" @click="delSelected">鎵归噺鍒犻櫎</el-button>
+      <el-button type="text" size="small" style="font-size: 13px;font-weight: 600;">瀵煎嚭</el-button>
+    </div>
+    <div class="foot-table s-table">
+      <el-table
+        ref="multipleTable"
+        highlight-current-row
+        :data="tableData"
+        style="width: 100%"
+        :header-cell-style="{background:'#f8f8f8',color:'#222222'}"
+        @selection-change="handleSelectionChange"
+      >
+        <el-table-column type="selection" width="55"></el-table-column>
+        <el-table-column :align="'center'" sortable prop="index" label="搴忓彿"></el-table-column>
+        <el-table-column :align="'center'" sortable prop="logtype" label="鏃ュ織绫诲瀷"></el-table-column>
+        <el-table-column :align="'center'" sortable prop="username" label="鐢ㄦ埛鍚�"></el-table-column>
+        <el-table-column :align="'center'" sortable prop="ipaddress" label="IP鍦板潃"></el-table-column>
+        <el-table-column :align="'center'" sortable prop="operation" label="鎿嶄綔鍔熻兘"></el-table-column>
+        <el-table-column :align="'center'" sortable prop="operatetime" label="鎿嶄綔鏃堕棿"></el-table-column>
+        <el-table-column :align="'center'" sortable prop="operateinfo" label="鎿嶄綔淇℃伅"></el-table-column>
+        <el-table-column label="鎿嶄綔" :align="'center'">
+          <template slot-scope="scope">
+            <el-button
+              type="text"
+              style="color: red;font-size:16px"
+              @click="handleDelete(scope.$index, scope.row)"
+              icon="el-icon-delete"
+            ></el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+    </div>
+  </div>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      tableData: [
+        {
+          index: "1",
+          logtype: "寮傚父",
+          username: "admin",
+          ipaddress: "192.168.10.110",
+          operation: "娣诲姞鎽勫儚鏈�",
+          operatetime: "2019-5-31 16:38:21",
+          operateinfo: "娣诲姞鎿嶄綔"
+        },
+        {
+          index: "2",
+          logtype: "淇℃伅",
+          username: "admin",
+          ipaddress: "192.168.10.108",
+          operation: "鍒犻櫎鎽勫儚鏈�",
+          operatetime: "2019-5-31 16:38:21",
+          operateinfo: "娣诲姞鎿嶄綔"
+        },
+        {
+          index: "3",
+          logtype: "鎿嶄綔",
+          username: "admin",
+          ipaddress: "192.168.10.110",
+          operation: "娣诲姞鎽勫儚鏈�",
+          operatetime: "2019-5-31 16:38:21",
+          operateinfo: "娣诲姞鎿嶄綔"
+        },
+        {
+          index: "4",
+          logtype: "寮傚父",
+          username: "admin",
+          ipaddress: "192.168.10.110",
+          operation: "娣诲姞鎽勫儚鏈�",
+          operatetime: "2019-5-31 16:38:21",
+          operateinfo: "娣诲姞鎿嶄綔"
+        },
+        {
+          index: "5",
+          logtype: "寮傚父",
+          username: "admin",
+          ipaddress: "192.168.10.110",
+          operation: "鍒犻櫎鎽勫儚鏈�",
+          operatetime: "2019-5-31 16:38:21",
+          operateinfo: "娣诲姞鎿嶄綔"
+        },
+        {
+          index: "6",
+          logtype: "寮傚父",
+          username: "admin",
+          ipaddress: "192.168.10.110",
+          operation: "娣诲姞鎽勫儚鏈�",
+          operatetime: "2019-5-31 16:38:21",
+          operateinfo: "娣诲姞鎿嶄綔"
+        }
+      ],
+      multipleSelection: [],
+      logOptions: [
+        {
+          value: "鍏ㄩ儴绫诲瀷",
+          label: "鍏ㄩ儴绫诲瀷"
+        },
+        {
+          value: "鍏朵粬绫诲瀷",
+          label: "鍏朵粬绫诲瀷"
+        }
+      ],
+      logValue: "鍏ㄩ儴绫诲瀷",
+      timeValue: [
+        new Date(2000, 10, 10, 10, 10),
+        new Date(2000, 10, 11, 10, 10)
+      ],
+      searchValue: ""
+    };
+  },
+  methods: {
+    handleDelete(index, row) {
+      console.log(index, row);
+    },
+    handleSelectionChange(val) {
+      this.multipleSelection = val;
+    },
+    delSelected() {
+      console.log(this.multipleSelection);
+    }
+  }
+};
+</script>
+<style lang="scss">
+.s-log-management {
+  height: 100%;
+  width: 100%;
+  .top {
+    width: 100%;
+    margin-top: 10px;
+    margin-bottom: 20px;
+    overflow-y: auto;
+    min-width: 1156px;
+    height: 40px;
+    text-align: left;
+    b {
+      padding: 0px 10px;
+    }
+  }
+  .export {
+    display: inline-block;
+    padding-right: 10px;
+    box-sizing: border-box;
+    margin-top: 20px;
+    b:hover {
+      color: #2249b4;
+    }
+  }
+  .clear-searching {
+    cursor: pointer;
+    text-decoration: underline;
+    width: 40px;
+    font-size: 13px;
+    color: #3d68e1;
+  }
+}
+</style>
diff --git a/src/pages/systemSettings/components/RadioSet.vue b/src/pages/systemSettings/components/RadioSet.vue
new file mode 100644
index 0000000..1b7fa56
--- /dev/null
+++ b/src/pages/systemSettings/components/RadioSet.vue
@@ -0,0 +1,189 @@
+<template>
+  <div class="s-radio-set">
+    <div class="add-btn">
+      <el-button size="mini" type="primary" @click="handleAdd()">娣诲姞</el-button>
+    </div>
+    <el-table
+      border
+      highlight-current-row
+      :data="tableData"
+      style="width: 100%; margin-top:40px; color:#000"
+      :header-cell-style="{background:'#f8f8f8',color:'#222222'}"
+    >
+      <el-table-column align="center" type="index" label="搴忓彿" width="100px"></el-table-column>
+
+      <el-table-column :align="'center'" label="骞挎挱鍚嶇О">
+        <template slot-scope="{row}">
+          <el-input v-if="row.edit" :autofocus="row.edit" v-model="row.radiosName" size="small" />
+          <span v-else>{{ row.radiosName }}</span>
+        </template>
+      </el-table-column>
+
+      <el-table-column :align="'center'" label="IP鍦板潃">
+        <template slot-scope="{row}">
+          <el-input v-if="row.edit" v-model="row.ipAddress" size="small" />
+          <span v-else>{{ row.ipAddress }}</span>
+        </template>
+      </el-table-column>
+
+      <el-table-column :align="'center'" label="杩炴帴娴嬭瘯">
+        <template slot-scope="{row}">
+          <i v-show="row.isCon" class="el-icon-success" style="color:green; font-size:18px"></i>
+
+          <el-button type="text" @click="handleTest(row)">杩炴帴娴嬭瘯</el-button>
+        </template>
+      </el-table-column>
+
+      <el-table-column label="鎿嶄綔" :align="'center'">
+        <template slot-scope="scope">
+          <template v-if="scope.row.edit">
+            <el-button size="mini" type="info" @click="handleCancel(scope.row)">鍙栨秷</el-button>
+            <el-button size="mini" type="primary" @click="handleSave(scope.row)">淇濆瓨</el-button>
+          </template>
+          <template v-else>
+            <el-button
+              type="text"
+              style="color: black;font-size:18px"
+              @click="handleEdit(scope.row)"
+              icon="el-icon-edit"
+            ></el-button>
+            <el-button
+              type="text"
+              style="color: red;font-size:18px"
+              @click="handleDelete(scope.$index)"
+              icon="el-icon-delete"
+            ></el-button>
+          </template>
+        </template>
+      </el-table-column>
+    </el-table>
+  </div>
+</template>
+
+<script>
+export default {
+  filters: {
+    isCon(r) {
+      return r.isCon ? r.isCon : false
+    }
+  },
+  data() {
+    return {
+      radioName: "",
+      ipAddress: "",
+      tableData: [
+        {
+          index: "1",
+          radiosName: "鎿嶅満",
+          ipAddress: "192.168.1.101",
+          edit: false,
+          isCon: false
+        },
+        {
+          edit: false,
+          index: "2",
+          radiosName: "鏁欏",
+          ipAddress: "192.168.12.61",
+          isCon: false
+        },
+        {
+          edit: false,
+          index: "3",
+          radiosName: "淇濆畨瀹�",
+          ipAddress: "192.168.13.121",
+          isCon: false
+        }
+      ]
+    };
+  },
+  mounted() {
+    this.testAll()
+  },
+  methods: {
+    testAll() {
+      this.tableData.forEach(l => {
+        this.$set(l, "isCon", false)
+      })
+    },
+    handleEdit(row) {
+      console.log(row);
+      row.edit = true;
+    },
+    handleCancel(row) {
+      row.edit = false;
+      console.log(row);
+    },
+    handleDelete(index) {
+      this.$confirm("纭鍒犻櫎璇ュ箍鎾悧?", {
+        center: true,
+        cancelButtonClass: "comfirm-class-cancle",
+        confirmButtonClass: "comfirm-class-sure"
+      })
+        .then(() => {
+          this.tableData.splice(index, 1)
+          this.$notify({
+            type: "success",
+            message: "鍒犻櫎鎴愬姛!"
+          });
+        })
+        .catch(() => { });
+    },
+    handleSave(row) {
+      console.log(row);
+      row.edit = false;
+      this.$notify({
+        message: "淇濆瓨鎴愬姛",
+        type: "success"
+      });
+    },
+    handleTest(row) {
+      this.$set(row, 'isCon', true)
+    },
+    handleAdd() {
+      this.tableData.push({
+        radiosName: "",
+        ipAddress: "",
+        edit: true,
+        isCon: false
+      })
+    }
+  }
+};
+</script>
+<style lang="scss">
+.s-radio-set {
+  width: 100%;
+  height: 100%;
+  .el-dialog {
+    border-radius: 8px;
+    border: 1px solid #ccc;
+    .el-dialog__header {
+      border-bottom: 1px solid #ccc;
+    }
+  }
+
+  .add-btn {
+    float: right;
+    margin-bottom: 7px;
+  }
+}
+.e-message {
+  width: 331px;
+}
+.e-confirm {
+  border-color: #ff0000 !important;
+  background-color: #ff0000 !important;
+}
+.e-confirm:hover {
+  border-color: #f83131d6 !important;
+  background-color: #f83131d6 !important;
+}
+.e-cancel {
+  border-color: #eaeaea !important;
+  background-color: #eaeaea !important;
+}
+.e-cancel:hover {
+  border-color: #e9e9e9 !important;
+  background-color: #e9e9e9 !important;
+}
+</style>
diff --git a/src/pages/systemSettings/components/SystemMaintenance.vue b/src/pages/systemSettings/components/SystemMaintenance.vue
new file mode 100644
index 0000000..bf40d81
--- /dev/null
+++ b/src/pages/systemSettings/components/SystemMaintenance.vue
@@ -0,0 +1,514 @@
+<template>
+    <el-tabs
+      id="systemMaintenance"
+      v-model="activeName"
+      v-loading="loading"
+      :element-loading-text="loadingText"
+    >
+      <el-tab-pane label="璁惧缁存姢" name="first" v-if="isShow('videoSystem:sysManage:sysfix')">
+        <div class="s-system-maintenance">
+        <div class="box-card">
+          <div class="ui-top-view">
+            <div class="ui-top-title">閲嶅惎</div>
+          </div>
+          <el-divider></el-divider>
+
+          <div class="box-card-content">
+            <el-row>
+              <el-col :span="1">
+                <el-button type="primary" size="small" style="width:80px" @click="reboot">閲嶅惎</el-button>
+              </el-col>
+              <el-col :span="23">
+                <b class="card-text">閲嶅惎鑺傜偣</b>
+              </el-col>
+            </el-row>
+            <el-row style="margin-top:20px">
+              <el-col>
+                <vue-cron :expression="rebootCron" @update="setRebootCron" />
+              </el-col>
+            </el-row>
+          </div>
+        </div>
+        <!--
+        <div class="box-card">
+          <div class="ui-top-view">
+            <div class="ui-top-title">鎭㈠榛樿鍊�</div>
+          </div>
+          <el-divider></el-divider>
+
+          <div class="box-card-content">
+            <el-row>
+              <el-col :span="1">
+                <el-button type="primary" size="small">绠�鍗曟仮澶�</el-button>
+              </el-col>
+              <el-col :span="23">
+                <b class="card-text">绠�鍗曟仮澶嶈澶囧弬鏁�</b>
+              </el-col>
+            </el-row>
+            <el-row style="margin-top:20px">
+              <el-col :span="1">
+                <el-button type="primary" size="small">瀹屽叏鎭㈠</el-button>
+              </el-col>
+              <el-col :span="23">
+                <b class="card-text">瀹屽叏鎭㈠璁惧鍙傛暟鍒板嚭鍘傝缃�</b>
+              </el-col>
+            </el-row>
+          </div>
+        </div>
+        
+        <div class="box-card">
+          <div class="ui-top-view">
+            <div class="ui-top-title">鍙傛暟瀵煎叆瀵煎嚭</div>
+          </div>
+          <el-divider></el-divider>
+
+          <div class="box-card-content">
+            <el-row :gutter="4">
+              <el-col :span="1">
+                <el-button type="info" size="small" style="width:80px">瀵煎叆</el-button>
+              </el-col>
+              <el-col :span="3" style="padding-left:30px">
+                <el-input placeholder="涓婁紶鍙傛暟鏂囦欢" size="small" :readonly="true">
+                  <el-upload slot="suffix" action="https://jsonplaceholder.typicode.com/posts/">
+                    <el-button
+                      type="text"
+                      icon="el-icon-upload2"
+                      size="small"
+                      style="font-size:18px; color:#0088ff"
+                    ></el-button>
+                  </el-upload>
+                </el-input>
+              </el-col>
+            </el-row>
+            <el-row style="margin-top:20px">
+              <el-col :span="1">
+                <el-button type="primary" size="small">璁惧鍙傛暟</el-button>
+              </el-col>
+              <el-col :span="23">
+                <b class="card-text">鍙傛暟瀵煎嚭</b>
+              </el-col>
+            </el-row>
+          </div>
+        </div>
+        -->
+        <div class="box-card">
+          <div class="ui-top-view">
+            <div class="ui-top-title">鍗囩骇</div>
+          </div>
+        </div>
+        <el-divider></el-divider>
+        <div class="box-card-content">
+          <el-row :gutter="4">
+            <el-col :span="6">
+              <file-uploader
+                single
+                uploadPlaceholder="涓婁紶鍗囩骇鏂囦欢"
+                url="/data/api-v/sysset/patchUpdate"
+                @complete="onFileUpload"
+                @file-added="onFileAdded"
+              />
+            </el-col>
+            <el-col :span="2">
+              <el-button
+                type="primary"
+                size="small"
+                style="width:80px"
+                @click="upgrade"
+                :disabled="!fileAdded"
+                :loading="upgrading"
+              >鍗囩骇</el-button>
+            </el-col>
+            <el-col :span="16" class="upload-msg">
+              <span v-html="patchUpdateStatus"></span>
+            </el-col>
+          </el-row>
+        </div>
+      </div>
+      </el-tab-pane>
+      <el-tab-pane label="鏁版嵁搴撶淮鎶�" name="second" v-if="isShow('videoSystem:sysManage:dbfix')">
+        <div class="box"> 
+          <p class="title">
+            <label>鏁版嵁娓呯悊</label>
+          </p>  
+          <div class="range">
+            <div class="left">
+              <p>閫夋嫨鏁版嵁鑼冨洿锛�</p>
+            </div>  
+            <div class="middle">
+              <el-date-picker
+                v-model="dataRange"
+                type="daterange"
+                range-separator="鑷�"
+                start-placeholder="寮�濮嬫棩鏈�"
+                end-placeholder="缁撴潫鏃ユ湡"
+                style="height:38px"
+                :picker-options="pickerOptions"
+              ></el-date-picker>
+            </div>
+            <div class="right">
+              <el-button @click="deleteData" style="height:38px;background:#ff0000;color:white">鍒犻櫎鏁版嵁</el-button>
+            </div>  
+          </div>  
+          <div class="tip">
+            <i class="iconfont icontishi-zhuyi"></i>
+            <p class="zhuyi">璇锋敞鎰忥紝鎸変互涓婃棩鏈熻寖鍥村垹闄ょ殑鏁版嵁涓嶅彲鎭㈠锛岀珛鍗崇敓鏁堬紝璇疯皑鎱庢搷浣�</p>
+          </div>  
+        </div>  
+      </el-tab-pane>  
+    </el-tabs>  
+
+</template>
+
+<script>
+import { rebootServer, getDevInfo, getRebootTask, setRebootTask, fileUpload, doUpgrade,deleteDate } from "@/api/system"
+import VueCron from "@/components/subComponents/VueCron"
+import FileUploader from "@/components/subComponents/FileUpload/index"
+
+export default {
+  components: {
+    VueCron,
+    FileUploader
+  },
+  data() {
+    return {
+      timer: null,
+      buttonAuthority: sessionStorage.getItem("buttonAuthoritys") || [],
+      rebootCron: "",
+      activeName: "first",
+      restartValue: "涓嶉噸鍚�",
+      restartTimeValue: new Date(2019, 9, 10, 18, 40),
+      loading: false,
+      loadingText: '',
+      probeSum: 0,
+      patchUpdateStatus: "",
+      dataRange: [
+        this.$moment().format("YYYY-MM-DD HH:mm:ss"),
+        this.$moment().format("YYYY-MM-DD HH:mm:ss")
+      ],
+      fileUploadUrl: fileUpload,
+      patchFile: {},
+      pickerOptions: {
+        disabledDate(time) {
+          var day = new Date()
+          day.setTime(day.getTime() - 24 * 60 * 60 * 1000)
+          return time.getTime() > day;
+        },
+      },
+      upgrading: false,
+      fileAdded: false
+    };
+  },
+  mounted() {
+    this.getRebootCron()
+    if (!this.isShow('videoSystem:sysManage:sysfix')) {
+      console.log("榛樿鏄剧ず鏁版嵁搴撶淮鎶�")
+      this.activeName = "second"
+    }
+  },
+  computed: {
+    isAdmin() {
+      if (
+        sessionStorage.getItem('userInfo') &&
+        sessionStorage.getItem('userInfo') !== ''
+      ) {
+        let loginName = JSON.parse(sessionStorage.getItem('userInfo')).username
+        return (
+          loginName === 'superadmin' || loginName === 'basic'
+        )
+      }
+      return false;
+    }
+  },
+  methods: {
+    isShow (authority) {
+      if (this.isAdmin) {
+        return true
+      } else if (
+        this.buttonAuthority.indexOf(',' + authority + ',') > -1
+      ) {
+        return true
+      } else {
+        return false
+      }
+    },
+    format(array) {
+      return [
+        this.$moment(array[0]).format("YYYY-MM-DD"),
+        this.$moment(array[1]).format("YYYY-MM-DD")
+      ];
+    },
+    getRebootCron() {
+      getRebootTask().then(rsp => {
+        this.rebootCron = rsp.data
+      })
+    },
+    setRebootCron(value) {
+      this.rebootCron = value
+      setRebootTask({ task: value }).then(rsp => {
+        if (rsp && rsp.success) {
+          this.$notify({
+            type: "success",
+            message: "閰嶇疆鎴愬姛"
+          })
+        }
+      }).catch(err => {
+        this.$notify({
+          type: "error",
+          message: "閰嶇疆澶辫触"
+        })
+      })
+    },
+    reboot() {
+      this.$confirm('纭畾瑕侀噸鍚鑺傜偣鍚�?', {
+        center: true,
+        cancelButtonClass: 'comfirm-class-cancle',
+        confirmButtonClass: 'comfirm-class-sure'
+      }).then(() => {
+        this.loading = true;
+        this.loadingText = "鏅鸿兘璁$畻鑺傜偣姝e湪閲嶅惎锛岃鑰愬績绛夊緟..."
+        rebootServer().then(rsp => {
+          this.probeServer(this.reLogin)
+        }).catch(err => {
+          if (err.status == 400) {
+            this.loading = false;
+            this.$notify({
+              type: "error",
+              message: "閲嶅惎璁$畻鑺傜偣澶辫触"
+            })
+          } else {
+            this.probeServer(this.reLogin)
+          }
+        })
+      })
+    },
+    deleteData() {
+      var timeRange = this.format(this.dataRange);
+      var showStartTime = timeRange[0]
+      var showEndTime = timeRange[1]
+      console.log("鏃堕棿锛�",showStartTime,showEndTime)
+      this.$confirm("鎻愮ず锛�"+showStartTime+" 鑷� "+showEndTime+" 浜х敓鐨勫叏閮ㄦ暟鎹皢琚垹闄わ紝姝ゆ搷浣滅珛鍗崇敓鏁堬紝涓嶅彲鎭㈠锛屾槸鍚﹀垹闄わ紵", {
+        center: true,
+        cancelButtonClass: "comfirm-class-cancle",
+        confirmButtonClass: "comfirm-class-sure"
+      }).then(() => {
+        this.loading = true
+        this.loadingText = "姝e湪鍒犻櫎鏁版嵁锛岃绋嶅�欙紒"
+        var param = {
+          startTime: showStartTime,
+          endTime: showEndTime
+        }
+        deleteDate(param).then(resp => {
+          if (resp.success) {
+            this.$message({
+              type: "success",
+              message: "鍒犻櫎鏁版嵁鎴愬姛"
+            })
+            this.loading = false
+          }
+        }).catch(err => {
+          this.$message({
+            type: "error",
+            message: "鍒犻櫎鏁版嵁澶辫触锛�"
+          })
+          this.loading = false
+        })
+
+      }).catch(() => {
+        console.log("鍙栨秷浜嗭紒")
+      })
+    },
+    reLogin() {
+      this.$router.push("/")
+    },
+    probeServer(callback) {
+      this.probeSum++;
+      let _this = this
+      if (this.probeSum > 60) {
+        this.$confirm('杩炴帴鏈嶅姟鍣ㄥけ璐�, 璇峰埛鏂伴〉闈㈡垨鑱旂郴绠$悊鍛�', '澶辫触', {
+          type: 'error',
+          cancelButtonClass: 'comfirm-class-cancle',
+          confirmButtonClass: 'comfirm-class-sure'
+        }).then(() => {
+          // _this.$router.push("/")
+          callback()
+        })
+        return
+      }
+
+      this.timer = setTimeout(() => {
+        getDevInfo().then(() => {
+          // _this.$router.push("/")
+          callback()
+        }).catch(err => {
+          _this.probeServer(callback)
+        })
+      }, 10000)
+    },
+    onFileUpload(file) {
+      this.patchUpdateStatus = `<span style="color:green">涓婁紶鎴愬姛, 鐐瑰嚮鍗囩骇鎸夐挳寮�濮嬪崌绾�</span>`
+      this.patchFile = { ...file }
+      this.fileAdded = true
+    },
+    onFileAdded() {
+      this.patchUpdateStatus = ""
+    },
+    upgrade() {
+      this.upgrading = true
+      this.patchUpdateStatus = `<span style="color:red">姝e湪鍗囩骇...</span>`
+      doUpgrade(this.patchFile).then(rsp => {
+        this.upgrading = false
+
+        if (rsp && rsp.success) {
+          clearTimeout(this.timer)
+          this.doneUpgrade()
+        }
+      }).catch(err => {
+        if (err.code) {
+          this.upgrading = false
+          this.patchUpdateStatus = `<span style="color:red">${err.data}</span>`
+          clearTimeout(this.timer)
+        } else {
+          this.probeServer(this.doneUpgrade)
+        }
+      })
+    },
+    doneUpgrade() {
+      this.upgrading = false
+      this.patchUpdateStatus = `<span style="color:green">鍗囩骇鎴愬姛</span>`
+      let _this = this
+      this.$confirm('鍗囩骇鎴愬姛, 璇烽噸鏂扮櫥褰曠郴缁�', '鎴愬姛', {
+        type: 'success',
+        cancelButtonClass: 'comfirm-class-cancle',
+        confirmButtonClass: 'comfirm-class-sure'
+      }).then(() => {
+        _this.reLogin()
+      })
+    }
+  }
+};
+</script>
+<style lang="scss">
+.s-system-maintenance {
+  width: 100%;
+  height: 100%;
+  .box-card {
+    text-align: left;
+    height: auto;
+    margin: 10px 0px;
+    .box-card-content {
+      padding-bottom: 40px;
+      .card-text {
+        padding: 0 30px;
+        line-height: 32px;
+      }
+    }
+  }
+
+  .upload-icon {
+    font-size: 18px;
+    color: #0088ff;
+  }
+  .upload-msg {
+    padding-left: 10px;
+    text-align: left;
+    span {
+      line-height: 32px;
+      font-size: 13px;
+    }
+  }
+}
+.box{
+  width: 50%;
+  min-width: 700px;
+  height: 270px;
+  border: 1px solid #eee;
+  .title {
+    font-size:20px;
+    font-weight: bold;
+    text-align: left;
+    padding: 20px;
+    border-bottom: 1px solid #eee;
+  }
+  .range {
+    width: 100%;
+    padding-top: 30px;
+    height: 38px;
+    .left {
+      width: 120px;
+      float: left;
+      text-align: right;
+      font-size: 14px;
+      p {
+        height: 38px;
+        line-height: 38px;
+      }
+    }
+    .middle {
+      width: 50%;
+      min-width: 400px;
+      height: 38px;
+      float: left;
+    }
+    .right {
+      width: 20%;
+      height: 38px;
+      float: left;
+    }
+  }
+  .tip {
+    width: 100%;
+    padding: 30px 0px 0px 30px;
+    height: 34px;
+
+    .zhuyi {
+      font-size: 14px;
+      height: 34px;
+      line-height: 34px;
+      margin-left: 20px;
+      float: left;
+    }
+    i {
+      font-size: 32px;
+      color: #e99038;
+      float: left;
+    }
+  }
+}
+#systemMaintenance{
+
+  .el-tabs__header {
+      border: 0px solid #dcdfe6;
+      .el-tabs__item {
+        padding: 5px 50px;
+        height: 50px;
+        font-family: PingFangSC-Regular;
+        font-size: 14px;
+        color: #222222;
+        text-align: center;
+        border: 0px solid transparent;
+      }
+      .el-tabs__item:nth-child(2) {
+        padding-left: 50px;
+      }
+      .el-tabs__item:last-child {
+        padding-right: 50px;
+      }
+      .el-tabs__item.is-active {
+        color: #ff7733;
+        font-weight: bold;
+        // border-right-color: #fff;
+        // border-left-color: #fff;
+      }
+      .el-tabs__item:not(.is-disabled):hover {
+        color: #ff7733;
+      }
+      
+  }
+  .el-tabs__active-bar {
+    background-color: #ff7733;
+  }
+  .el-tabs__content {
+    padding-left: 15px !important;
+  }
+}
+</style>
diff --git a/src/pages/systemSettings/index/App.vue b/src/pages/systemSettings/index/App.vue
new file mode 100644
index 0000000..8a8d3e9
--- /dev/null
+++ b/src/pages/systemSettings/index/App.vue
@@ -0,0 +1,161 @@
+<template>
+  <div class="s-system-manage">
+    <basic-setting v-show="activeName === 'basic'"></basic-setting>
+  </div>
+</template>
+
+<script>
+import BasicSetting from "../components/BasicSetting";
+
+export default {
+  name: 'settings',
+  components: {
+    BasicSetting
+  },
+  data() {
+    return {
+      activeName: "basic",
+      buttonAuthority: sessionStorage.getItem("buttonAuthoritys") || [],
+      loginName: JSON.parse(sessionStorage.getItem("userInfo")).username || "鐢ㄦ埛鍚�"
+    }
+  },
+  computed: {
+    isAdmin() {
+      if (
+        sessionStorage.getItem("userInfo") &&
+        sessionStorage.getItem("userInfo") !== ""
+      ) {
+        let loginName = JSON.parse(sessionStorage.getItem("userInfo")).username;
+        return loginName === "superadmin" || loginName === "basic";
+      }
+      return false;
+    }
+  },
+  methods: {
+    isShow(authority) {
+      if (this.isAdmin) {
+        return true;
+      } else if (this.buttonAuthority.indexOf("," + authority + ",") > -1) {
+        return true;
+      } else {
+        return false;
+      }
+    },
+  },
+  created() {
+    if (this.isShow('videoSystem:base')) {
+      this.activeName = "basic"
+    } else if (this.isShow('videoSystem:permission')) {
+      this.activeName = "user"
+    } else if (this.isShow('videoSystem:broadcast')) {
+      this.activeName = "radio"
+    } else if (this.isShow('videoSystem:eventPush')) {
+      this.activeName = "event"
+    } else if (this.isShow('videoSystem:logManage')) {
+      this.activeName = "log"
+    } else if (this.isShow('videoSystem:sysManage')) {
+      this.activeName = "system"
+    }
+  },
+};
+</script>
+<style lang="scss">
+.s-system-manage {
+  width: 100% !important;
+  min-width: 1067px;
+  height: 100%;
+  box-sizing: border-box;
+  padding: 10px;
+  background-color: #f8f9fb;
+  .s-system-manage-breadcrumb {
+    height: 5%;
+    box-sizing: border-box;
+    border: 1px solid #e4e7ed;
+    box-shadow: #e4e7ed 0px 0px 9px inset;
+    box-shadow: #e4e7ed 0px 0px 9px inset;
+    border-radius: 5px;
+  }
+
+  .el-tabs--border-card {
+    border: 0px solid #dcdfe6;
+    -webkit-box-shadow: none;
+    box-shadow: none;
+    .el-tabs__header {
+      border: 0px solid #dcdfe6;
+      .el-tabs__item {
+        padding: 5px 50px;
+        height: 50px;
+        font-family: PingFangSC-Regular;
+        font-size: 15px;
+        color: #222222;
+        text-align: center;
+        border: 0px solid transparent;
+      }
+      .el-tabs__item:nth-child(2) {
+        padding-left: 50px !important;
+      }
+      .el-tabs__item:last-child {
+        padding-right: 50px !important;
+      }
+      .el-tabs__item.is-active {
+        color: #3d68e1;
+
+        // border-right-color: #fff;
+        // border-left-color: #fff;
+      }
+      .el-tabs__item:not(.is-disabled):hover {
+        color: #3d68e1;
+      }
+    }
+  }
+  .el-tabs__header {
+    margin-bottom: 0;
+  }
+  .el-tabs__content {
+    height: calc(100% - 64px);
+    box-sizing: border-box;
+    overflow-y: auto;
+    padding: 20px 40px !important;
+    background: #fff;
+    .el-tab-pane {
+      width: 100%;
+      .s-title {
+        text-align: left;
+        padding: 15px 0px;
+        font-size: 16px;
+      }
+    }
+  }
+
+  .s-table {
+    border: 1px solid #e8e8e9;
+    margin-top: 40px;
+  }
+
+  .ui-top-title {
+    padding-bottom: 10px;
+    /* border-bottom: 1px solid #ebebeb; */
+    position: relative;
+    text-align: left;
+    padding-left: 15px;
+    font-size: 16px;
+    font-weight: bold;
+  }
+
+  .ui-top-title:before {
+    content: " ";
+    border-left: 4px solid #f53d3d;
+    display: inline-block;
+    height: 16px;
+    position: absolute;
+    top: 50%;
+    left: 0;
+    margin-top: -13px;
+  }
+
+  .el-button--text {
+    color: #3d68e1;
+    text-decoration: underline;
+  }
+}
+</style>
diff --git a/src/pages/systemSettings/index/main.ts b/src/pages/systemSettings/index/main.ts
new file mode 100644
index 0000000..491ea9a
--- /dev/null
+++ b/src/pages/systemSettings/index/main.ts
@@ -0,0 +1,12 @@
+import Vue from 'vue';
+import App from './App.vue';
+
+import ElementUI from 'element-ui';
+import 'element-ui/lib/theme-chalk/index.css';
+import "@/assets/css/element-variables.scss";
+Vue.use(ElementUI)
+
+new Vue({
+  el: '#app',
+  render: h => h(App)
+})

--
Gitblit v1.8.0