From 856c3d2047705fd4e08d029c39f2f39816c95177 Mon Sep 17 00:00:00 2001
From: heyujie <516346543@qq.com>
Date: 星期三, 21 七月 2021 18:09:01 +0800
Subject: [PATCH] video max len

---
 src/pages/settings/index/App.vue                      | 1918 +--------------
 src/pages/settings/components/LogManagement.vue       |  190 +
 src/pages/settings/components/RadioSet.vue            |  189 +
 src/pages/settings/components/SystemMaintenance.vue   |  514 ++++
 src/pages/systemSettings/index/App.vue                | 1831 ++++++++++++++
 src/pages/systemSettings/views/generalSettings.vue    |    0 
 src/pages/systemSettings/components/switchBar.vue     |    0 
 src/pages/settings/components/AuthorityManagement.vue |  265 ++
 src/pages/settings/components/ClusterManagement.vue   |  885 +++++++
 src/pages/settings/components/CloudNode.vue           |  226 +
 src/pages/settings/components/BasicSetting.vue        | 1147 +++++++++
 src/pages/systemSettings/views/keyboardLanguage.vue   |    0 
 src/pages/systemSettings/index/main.ts                |   12 
 src/pages/systemSettings/components/CloudNode.vue     |  149 +
 src/pages/systemSettings/views/NetSettings.vue        |    0 
 src/pages/systemSettings/views/clusterManagement.vue  |    0 
 16 files changed, 5,488 insertions(+), 1,838 deletions(-)

diff --git a/src/pages/settings/components/AuthorityManagement.vue b/src/pages/settings/components/AuthorityManagement.vue
new file mode 100644
index 0000000..d95a783
--- /dev/null
+++ b/src/pages/settings/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/settings/components/BasicSetting.vue b/src/pages/settings/components/BasicSetting.vue
new file mode 100644
index 0000000..ebb164e
--- /dev/null
+++ b/src/pages/settings/components/BasicSetting.vue
@@ -0,0 +1,1147 @@
+<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="瑙嗛鎴彇鏈�鐭椂闀�" style="width: 724px">
+                  <el-slider
+                    id="cut_min_duration"
+                    @input="min_len = min_video_len"
+                    v-model="fakeObj.min"
+                    :min="5 / 1.2"
+                    :max="100"
+                    :step="5 / 1.2"
+                    show-stops
+                    :show-tooltip="true"
+                    :format-tooltip="formatTooltip"
+                  ></el-slider>
+                  <el-input-number
+                    v-model="min_len"
+                    @change="fakeObj.min = +(min_len / 1.2)"
+                    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="fakeObj.max"
+                    :min="5 / 1.2"
+                    @input="max_len = max_video_len"
+                    :max="100"
+                    :step="5 / 1.2"
+                    show-stops
+                    :format-tooltip="formatTooltip"
+                    :show-tooltip="true"
+                  ></el-slider>
+                  <el-input-number
+                    v-model="max_len"
+                    @change="fakeObj.max = +(max_len / 1.2)"
+                    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: {
+    min_video_len() {
+      // return +(this.fakeObj.min * 1.2).toFixed(0);
+      return Math.round(this.fakeObj.min * 1.2);
+    },
+    max_video_len() {
+      return Math.round(this.fakeObj.max * 1.2);
+      // return +(this.fakeObj.max * 1.2).toFixed(0);
+    },
+    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: {},
+      min_len: 0,
+      max_len: 0,
+      fakeObj: {
+        min: 0,
+        max: 0,
+      },
+      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: {
+    formatTooltip(v){
+      return Math.round(v*1.2)
+    },
+    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;
+            this.fakeObj.min = rsp.data.min_video_len / 1.2
+            this.fakeObj.max = rsp.data.max_video_len / 1.2
+            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({
+        min_video_len: this.min_video_len,
+        max_video_len: this.max_video_len,
+      }).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/settings/components/CloudNode.vue b/src/pages/settings/components/CloudNode.vue
index 800651a..e99063f 100644
--- a/src/pages/settings/components/CloudNode.vue
+++ b/src/pages/settings/components/CloudNode.vue
@@ -1,7 +1,21 @@
 <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"
@@ -24,46 +38,156 @@
         :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",
+  name: 'cloudNode',
   props: {
-    nodes: Array,
+    nodes: Array
   },
   components: {
-    SerfDiagram,
+    SerfDiagram
   },
-  data() {
+  data () {
     return {
-      agentName: "",
+      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);
+  mounted () {
+    console.log(this.nodes)
     //this.getInsideNodes();
   },
   methods: {
-    getRandom(index) {
+    getRandom (index) {
       if (index % 2 == 0) {
-        return Math.random() * 20;
+        return Math.random() * 20
       } else {
-        return Math.random() * 50;
+        return Math.random() * 50
       }
     },
-    getInsideNodes() {
-      let arr = this.nodes.filter(
-        (item) => item.hardwareType == "01" || item.hardwareType == "02"
-      );
+    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 = [];
@@ -75,55 +199,69 @@
           t: 30 * (index + 1),
           nodeName: item.nodeName,
           id: item.id,
-          workType: item.workType,
-        };
+          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);
+      console.log('w,h', this.minWidth, this.minHeight);
     },
   },
   computed: {
-    cloudPic() {
-      return "/images/settings/cloud.png";
+    cloudPic () {
+      return '/images/settings/cloud.png'
     },
-    insideNodes() {
-      return this.nodes.filter(
-        (item) => item.hardwareType == "01" || item.hardwareType == "02"
-      );
+    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;
+    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;
+    insideSizeY () {
+      return 140 + 200 * 0.2 * (this.insideNodes.length) <= 380 ? 140 + 200 * 0.2 * (this.insideNodes.length) : 380;
     },
-    insideStartX() {
-      return this.insideSizeX / 3;
+    insideStartX () {
+      return this.insideSizeX / 3
     },
-    outsideNodes() {
-      return this.nodes.filter((item) => item.hardwareType == "03");
-    },
-  },
-};
+    // 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: url('/images/settings/easy-cloud.png') no-repeat;
     background-size: 100%;
-    margin-top: -55px;
-    margin-left: 55px;
-
+    margin-top: -80px;
     .rect {
+      //background: rgba(176, 203, 253, 0.3);
       position: relative;
-      margin: 130px 100px 70px;
+      margin: 130px 100px 100px;
       .node {
         position: absolute;
         .node-icon {
diff --git a/src/pages/settings/components/ClusterManagement.vue b/src/pages/settings/components/ClusterManagement.vue
new file mode 100644
index 0000000..bedd193
--- /dev/null
+++ b/src/pages/settings/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/settings/components/LogManagement.vue b/src/pages/settings/components/LogManagement.vue
new file mode 100644
index 0000000..2b2d37e
--- /dev/null
+++ b/src/pages/settings/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/settings/components/RadioSet.vue b/src/pages/settings/components/RadioSet.vue
new file mode 100644
index 0000000..1b7fa56
--- /dev/null
+++ b/src/pages/settings/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/settings/components/SystemMaintenance.vue b/src/pages/settings/components/SystemMaintenance.vue
new file mode 100644
index 0000000..bf40d81
--- /dev/null
+++ b/src/pages/settings/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/settings/index/App.vue b/src/pages/settings/index/App.vue
index ef71b7c..8a8d3e9 100644
--- a/src/pages/settings/index/App.vue
+++ b/src/pages/settings/index/App.vue
@@ -1,1831 +1,161 @@
 <template>
-  <div class="container" v-if="!showWelcome">
-    <div class="container-left">
-      <div
-        class="left-card"
-        :class="activeIndex == index ? 'left-card-active' : ''"
-        v-for="(item, index) in menuArr"
-        :key="index"
-        @click="openMenu(item.name, index)"
-      >
-        <span class="icon iconfont">&#xe646;</span>
-        <span class="card-text">{{ item.name }}</span>
-      </div>
-    </div>
-
-    <div
-      class="container-center"
-      v-if="activePage == '璐︽埛' || activePage == '鏃ユ湡鏃堕棿'"
-    >
-      <div class="account-left" v-if="activePage == '璐︽埛'">
-        <div class="account-list">
-          <div
-            class="account-card"
-            :class="activeAccountIndex == index ? 'account-card-active' : ''"
-            v-for="(item, index) in accountArr"
-            :key="index"
-            ref="account-card"
-            @click="openAccount(item, index)"
-          >
-            <div class="touxiang">
-              <img
-                v-if="item.headpic"
-                :src="`data:image/png;base64,${item.headpic}`"
-                alt=""
-              />
-              
-            </div>
-            <span class="user-name">{{ item.username }}</span>
-          </div>
-        </div>
-        <div class="add-account">
-          <span class="icon iconfont" @click="showAddAccount">&#xe646;</span>
-        </div>
-      </div>
-      <div class="datetime-left" v-if="activePage == '鏃ユ湡鏃堕棿'">
-        <div class="time-card">
-          <div class="head">
-            <span class="icon iconfont">&#xe690;</span>
-            <span>璁惧鏃堕棿</span>
-          </div>
-          <div class="time-main">{{ equipmentTime }}</div>
-          <div class="date-bot">
-            <span class="year">{{ equipmentDate }}</span>
-            <span class="week">{{ weekday }}</span>
-          </div>
-        </div>
-        <div class="line">
-          <div class="name">NTP鏍℃椂</div>
-          <el-switch
-            v-model="isNtp"
-            @change="changeSwitch('isNtp')"
-            active-color="rgba(61, 104, 225, 1)"
-          >
-          </el-switch>
-        </div>
-
-        <div class="line">
-          <div class="name">鎵嬪姩鏍″</div>
-          <el-switch
-            v-model="isManual"
-            @change="changeSwitch('isManual')"
-            active-color="rgba(61, 104, 225, 1)"
-          >
-          </el-switch>
-        </div>
-      </div>
-    </div>
-    <div
-      class="container-right"
-      v-if="activePage == '璐︽埛' || activePage == '鏃ユ湡鏃堕棿'"
-    >
-      <div class="account-right" v-if="activePage == '璐︽埛'">
-        <div
-          class="account-content"
-          v-if="inAccountDetail == false && isAddAccount == false"
-        >
-          <div class="content-top">
-            <div class="touxiang-big">
-              <img
-                v-if="activeAccountItem.headpic"
-                :src="`data:image/png;base64,${activeAccountItem.headpic}`"
-                alt=""
-              />
-            </div>
-            <div class="user-desc">
-              <div class="username">
-                <span class="icon iconfont" style="margin-right: 5px"
-                  >&#xe690;</span
-                >
-                <span>{{ activeAccountItem.username }}</span>
-              </div>
-              <div class="nickname">
-                <span>鏄电О锛�</span>
-                <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"
-                />
-                <span class="icon iconfont" @click="editNickName"
-                  >&#xe60c;</span
-                >
-              </div>
-              <div class="user-role">
-                {{
-                  activeAccountItem.sysRoles.length
-                    ? activeAccountItem.sysRoles[0].name
-                    : ""
-                }}
-              </div>
-            </div>
-          </div>
-          <div class="list-btn">
-            <div class="item-btn" @click="showChangePassword">淇敼瀵嗙爜</div>
-            <div class="item-btn" @click="deleteAccount">鍒犻櫎璐︽埛</div>
-            <div class="item-btn" @click="openPermission">鏉冮檺璁剧疆</div>
-          </div>
-        </div>
-
-        <div class="change-pw" v-if="inAccountDetail && isChangePw">
-          <div class="title">淇敼瀵嗙爜</div>
-          <el-form
-            :model="passwordForm"
-            :rules="pwRules"
-            ref="passwordForm"
-            class="password-form"
-          >
-            <el-form-item prop="curPassword">
-              <div class="p-title">褰撳墠瀵嗙爜锛�</div>
-
-              <el-input
-                placeholder="蹇呭~"
-                v-model="passwordForm.curPassword"
-                show-password
-              ></el-input>
-            </el-form-item>
-            <el-form-item prop="newPassword">
-              <div class="p-title">鏂板瘑鐮侊細</div>
-              <el-input
-                placeholder="蹇呭~"
-                v-model="passwordForm.newPassword"
-                show-password
-              ></el-input>
-            </el-form-item>
-            <el-form-item prop="confirmPassword">
-              <div class="p-title">纭瀵嗙爜锛�</div>
-              <el-input
-                placeholder="蹇呭~"
-                v-model="passwordForm.confirmPassword"
-                show-password
-              ></el-input>
-            </el-form-item>
-          </el-form>
-          <div class="btns">
-            <div class="cancel" @click="cancelPassword">鍙栨秷</div>
-            <div class="ok" @click="SaveNewPassword('passwordForm')">淇濆瓨</div>
-          </div>
-        </div>
-
-        <div class="permission" v-if="inAccountDetail && isSetPermission">
-          <div class="title">鏉冮檺绠$悊</div>
-
-          <div class="line-wrap" v-for="item in sysMenus" :key="item.id">
-            <div class="line">
-              <div class="name">{{ item.name }}</div>
-              <el-switch
-                v-model="item.selected"
-                active-color="rgba(61, 104, 225, 1)"
-                @change="fatherChange(item)"
-              >
-              </el-switch>
-            </div>
-            <div v-if="item.children">
-              <div
-                class="line"
-                style="margin-left: 55px"
-                v-for="x in item.children"
-                :key="x.id"
-              >
-                <div class="name">{{ x.name }}</div>
-                <el-switch
-                  v-model="x.selected"
-                  active-color="rgba(61, 104, 225, 1)"
-                  @change="childrenChange(item)"
-                >
-                </el-switch>
-              </div>
-            </div>
-          </div>
-          <div class="btns">
-            <div class="cancel" @click="cancelSet">鍙栨秷</div>
-            <div class="ok" @click="saveAuth">淇濆瓨</div>
-          </div>
-        </div>
-
-        <div class="add-account-page" v-if="isAddAccount">
-          <div class="title">娣诲姞璐︽埛</div>
-          <div class="upload-group">
-            <div
-              class="upload-jpg"
-              :class="
-                selectedPic == index? 'upload-jpg-border' : ''
-              "
-              v-for="(item, index) in jpgArr"
-              :key="index"
-              @click="pickHeadDefPic(item, index)"
-            >
-              <img
-                v-if="item"
-                :src="`data:image/png;base64,${item.path}`"
-                alt=""
-                srcset=""
-              />
-              <div class="img-mask" v-if="selectedPic == index">
-                <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
-              :model="addForm"
-              :rules="rules"
-              ref="addForm"
-              class="add-form"
-            >
-              <el-form-item prop="userName">
-                <div class="p-title">鐢ㄦ埛鍚嶏細</div>
-                <el-input
-                  placeholder="蹇呭~"
-                  v-model="addForm.userName"
-                ></el-input>
-              </el-form-item>
-              <el-form-item prop="roleId">
-                <div class="p-title">瑙掕壊锛�</div>
-                <el-select v-model="addForm.roleId" placeholder="璇烽�夋嫨瑙掕壊">
-                  <el-option
-                    v-for="(item, i) in roleList"
-                    :key="i"
-                    :label="item.name"
-                    :value="item.id"
-                  ></el-option>
-                </el-select>
-              </el-form-item>
-              <el-form-item prop="nickName">
-                <div class="p-title">鏄电О锛�</div>
-                <el-input
-                  placeholder="閫夊~"
-                  v-model="addForm.nickName"
-                ></el-input>
-              </el-form-item>
-              <el-form-item prop="password">
-                <div class="p-title">瀵嗙爜锛�</div>
-                <el-input
-                  placeholder="蹇呭~"
-                  v-model="addForm.password"
-                  show-password
-                ></el-input>
-              </el-form-item>
-              <el-form-item prop="confirmPassword">
-                <div class="p-title">纭瀵嗙爜锛�</div>
-                <el-input
-                  placeholder="蹇呭~"
-                  v-model="addForm.confirmPassword"
-                  show-password
-                ></el-input>
-              </el-form-item>
-            </el-form>
-          </div>
-          <div class="btns">
-            <div class="cancel" @click="cancelAdd">鍙栨秷</div>
-            <div class="ok" @click="saveAddAccount('addForm')">淇濆瓨</div>
-          </div>
-        </div>
-      </div>
-
-      <div class="datetime-right" v-if="activePage == '鏃ユ湡鏃堕棿'">
-        <div class="ntp-time" v-if="isNtp">
-          <el-form label-width="160px">
-            <el-form-item label="鏈嶅姟鍣ㄥ湴鍧�">
-              <!-- :disabled="syncType === '2'" -->
-              <ip-input
-                :ip="ntpServer"
-                @on-blur="ntpServer = arguments[0]"
-              ></ip-input>
-            </el-form-item>
-
-            <el-form-item label="鏍℃椂鏃堕棿闂撮殧锛堝垎閽燂級">
-              <div class="right">
-                <el-input-number
-                  v-model.number="timeInterval"
-                  :min="1"
-                  :max="60"
-                  placeholder="璇疯緭鍏�"
-                  size="small"
-                  :controls="false"
-                ></el-input-number>
-                <el-button
-                  type="text"
-                  @click="testNTP"
-                  :loading="ntpTestLoading"
-                  >娴嬭瘯</el-button
-                >
-              </div>
-            </el-form-item>
-          </el-form>
-        </div>
-
-        <div class="manual-time" v-if="isManual">
-          <switchBar
-            :barName="`鍚屾鏈绠楁満鏃堕棿`"
-            @switchChange="syncBrowser"
-            :value="isSyncBrowser"
-          ></switchBar>
-
-          <div class="clock-wrap">
-            <div class="clock">
-              <div class="hour">
-                <div class="dnum" @click="showInput('Hour')">
-                  <span v-show="!showHourInput">{{ syncHour }}</span>
-                  <input
-                    class="input-box"
-                    v-show="showHourInput"
-                    ref="iptHour"
-                    oninput="value=value.replace(/[^\d]/g,'');if(value.length>2)value=value.slice(0,2);if(+value>23)value='23'"
-                    type="text"
-                    v-model="inputHour"
-                    @blur="hideInput('Hour')"
-                    @keydown.enter="hideInput('Hour')"
-                  />
-                </div>
-                <div class="control">
-                  <span class="icon iconfont" @click="plusOne('hrs')"
-                    >&#xe60e;</span
-                  >
-                  <span class="icon iconfont fanzhuan" @click="minusOne('hrs')"
-                    >&#xe60e;</span
-                  >
-                </div>
-              </div>
-              <div class="sep">:</div>
-              <div class="mins">
-                <div class="dnum" @click="showInput('Min')">
-                  <span v-show="!showMinInput">{{ syncMin }}</span>
-                  <input
-                    class="input-box"
-                    v-show="showMinInput"
-                    ref="iptMin"
-                    oninput="value=value.replace(/[^\d]/g,'');if(value.length>2)value=value.slice(0,2);if(+value>59)value='59'"
-                    type="text"
-                    v-model="inputMin"
-                    @blur="hideInput('Min')"
-                    @keydown.enter="hideInput('Min')"
-                  />
-                </div>
-                <div class="control">
-                  <span class="icon iconfont" @click="plusOne('min')"
-                    >&#xe60e;</span
-                  >
-                  <span class="icon iconfont fanzhuan" @click="minusOne('min')"
-                    >&#xe60e;</span
-                  >
-                </div>
-              </div>
-              <div class="sep">:</div>
-              <div class="mins">
-                <div class="dnum" @click="showInput('Sec')">
-                  <span v-show="!showSecInput">{{ syncSec }}</span>
-                  <input
-                    class="input-box"
-                    v-show="showSecInput"
-                    ref="iptSec"
-                    oninput="value=value.replace(/[^\d]/g,'');if(value.length>2)value=value.slice(0,2);if(+value>59)value='59'"
-                    type="text"
-                    v-model="inputSec"
-                    @blur="hideInput('Sec')"
-                    @keydown.enter="hideInput('Sec')"
-                  />
-                </div>
-                <div class="control">
-                  <span class="icon iconfont" @click="plusOne('sec')"
-                    >&#xe60e;</span
-                  >
-                  <span class="icon iconfont fanzhuan" @click="minusOne('sec')"
-                    >&#xe60e;</span
-                  >
-                </div>
-              </div>
-            </div>
-          </div>
-
-          <div class="adjust-bar">
-            <div class="minus" @click="minusOne('yrs')">-</div>
-            <div class="middle" @click="showInput('Yrs')">
-              <span v-show="!showYrsInput">{{ syncYrs }}</span>
-              <input
-                class="input-box"
-                v-show="showYrsInput"
-                ref="iptYrs"
-                oninput="value=value.replace(/[^\d]/g,'');if(value.length>4)value=value.slice(0,4);"
-                type="text"
-                v-model="inputYrs"
-                @blur="hideInput('Yrs')"
-                @keydown.enter="hideInput('Yrs')"
-              />
-              骞�
-            </div>
-            <div class="plus" @click="plusOne('yrs')">+</div>
-          </div>
-          <div class="adjust-bar">
-            <div class="minus" @click="minusOne('mth')">-</div>
-            <div class="middle" @click="showInput('Month')">
-              <span v-show="!showMonthInput">{{ syncMonth }}</span>
-              <input
-                class="input-box"
-                v-show="showMonthInput"
-                ref="iptMonth"
-                oninput="value=value.replace(/[^\d]/g,'');if(value.length>2)value=value.slice(0,2);if(+value>12)value='12'"
-                type="text"
-                v-model="inputMonth"
-                @blur="hideInput('Month')"
-                @keydown.enter="hideInput('Month')"
-              />
-              鏈�
-            </div>
-
-            <div class="plus" @click="plusOne('mth')">+</div>
-          </div>
-          <div class="adjust-bar">
-            <div class="minus" @click="minusOne('day')">-</div>
-            <div class="middle" @click="showInput('Day')">
-              <span v-show="!showDayInput">{{ syncDay }}</span>
-              <input
-                class="input-box"
-                v-show="showDayInput"
-                ref="iptDay"
-                oninput="value=value.replace(/[^\d]/g,'');if(value.length>2)value=value.slice(0,2);if(+value>31)value='31'"
-                type="text"
-                v-model="inputDay"
-                @blur="hideInput('Day')"
-                @keydown.enter="hideInput('Day')"
-              />
-              鏃�
-            </div>
-            <div class="plus" @click="plusOne('day')">+</div>
-          </div>
-        </div>
-
-        <div class="btns">
-          <div class="cancel" @click="cancelPassword">鍙栨秷</div>
-          <div class="ok" @click="submitClock">淇濆瓨</div>
-        </div>
-      </div>
-    </div>
-
-    <clusterManagement
-      v-if="activePage == '闆嗙兢绠$悊'"
-      style="width: 100%"
-    ></clusterManagement>
-    <netSettings
-      v-if="activePage == '缃戠粶璁剧疆'"
-      style="width: 100%"
-    ></netSettings>
-    <keyboardLanguage
-      v-if="activePage == '閿洏鍜岃瑷�'"
-      style="width: 100%"
-    ></keyboardLanguage>
-    <generalSettings
-      v-if="activePage == '閫氱敤璁剧疆'"
-      style="width: 100%"
-    ></generalSettings>
-  </div>
-  <div class="welcome-page" v-else>
-    <div class="child" @click="openWelcome('璐︽埛',0)">
-      <div class="child-info">
-        <span class="icon iconfont welcome-icon">&#xe6de;</span>
-        <span class="welcome-title">璐︽埛</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 class="s-system-manage">
+    <basic-setting v-show="activeName === 'basic'"></basic-setting>
   </div>
 </template>
 
 <script>
-import { getClockInfo, saveClockInfo, testNTPserver } from "@/api/system";
-import {
-  uploadHeadPic,
-  addUser,
-  getUsers,
-  updateUser,
-  updataUser,
-  updatePassword,
-  deleteUser,
-  getUserMenus,
-  defHeadPics,
-  getRoles,
-} from "@/api/user";
-import switchBar from "../components/switchBar";
-import ipInput from "@/components/subComponents/IPInput";
-import clusterManagement from "../views/clusterManagement";
-import netSettings from "../views/NetSettings";
-import keyboardLanguage from "../views/keyboardLanguage";
-import generalSettings from "../views/generalSettings";
+import BasicSetting from "../components/BasicSetting";
+
 export default {
-  name: "settings",
+  name: 'settings',
   components: {
-    switchBar,
-    ipInput,
-    clusterManagement,
-    netSettings,
-    keyboardLanguage,
-    generalSettings,
+    BasicSetting
   },
   data() {
-    var validatePass2 = (rule, value, callback) => {
-      if (value === "") {
-        callback(new Error("璇峰啀娆¤緭鍏ュ瘑鐮�"));
-      } else if (value !== this.addForm.password) {
-        callback(new Error("涓ゆ杈撳叆瀵嗙爜涓嶄竴鑷�!"));
-      } else {
-        callback();
-      }
-    };
-    var validatePass4 = (rule, value, callback) => {
-      if (value === "") {
-        callback(new Error("璇峰啀娆¤緭鍏ュ瘑鐮�"));
-      } else if (value !== this.passwordForm.newPassword) {
-        callback(new Error("涓ゆ杈撳叆瀵嗙爜涓嶄竴鑷�!"));
-      } else {
-        callback();
-      }
-    };
     return {
-      showAccount: true,
-      syncYrs: "",
-      activeAccountItem: {},
-      syncMonth: "",
-      syncHour: "",
-      showWelcome: true,
-      syncDay: "",
-      syncMin: "",
-      syncSec: "00",
-      isSyncBrowser: false,
-      showDateTime: false,
-      isAddAccount: false,
-      isCount: false,
-      isCalculate: false,
-      browserTimer: null,
-      timezone: "",
-      isRealtime: false,
-      inputNickName: "",
-      showHourInput: false,
-      showMinInput: false,
-      showSecInput: false,
-      showYrsInput: false,
-      showMonthInput: false,
-      selectedPic: null,
-      showDayInput: false,
-      loadedPic: "",
-      cameraInfo: false,
-      dependentScene: false,
-      timestamp: 0,
-      inAccountDetail: false,
-      isChangePw: false,
-      isSetPermission: false,
-      timeInterval: 10,
-      ntpServer: "",
-      syncType: "1",
-      equipmentTime: "",
-      equipmentDate: "",
-      roleList: [],
-      ntpTestLoading: false,
-      settime: "",
-      weekday: "",
-      menuArr: [
-        { name: "璐︽埛" },
-        { name: "鏃ユ湡鏃堕棿" },
-        { name: "闆嗙兢绠$悊" },
-        { name: "缃戠粶璁剧疆" },
-        { name: "閿洏鍜岃瑷�" },
-        { name: "閫氱敤璁剧疆" },
-      ],
-      accountArr: [],
-      jpgArr: [],
-      isManual: false,
-      isNtp: true,
-      activePage: "璐︽埛",
-      activeIndex: 0,
-      clockTimer: null,
-      inputHour: "",
-      inputMin: "",
-      inputSec: "",
-      inputYrs: "",
-      showInputNickName: false,
-      inputMonth: "",
-      inputDay: "",
-      passwordForm: {
-        curPassword: "",
-        newPassword: "",
-        confirmPassword: "",
-      },
-      activeAccountIndex: 0,
-      sysMenus: [],
-      addForm: {
-        userName: "",
-        nickName: "",
-        password: "",
-        headpic: "",
-        confirmPassword: "",
-        roleId: "",
-      },
-      rules: {
-        userName: [
-          { required: true, message: "璇疯緭鍏ョ敤鎴峰悕", trigger: "blur" },
-          {
-            min: 3,
-            max: 10,
-            message: "闀垮害鍦� 3 鍒� 10 涓瓧绗�",
-            trigger: "blur",
-          },
-        ],
-        password: [
-          { required: true, message: "璇疯緭鍏ュ瘑鐮�", trigger: "blur" },
-          { min: 6, message: "闀垮害鑷冲皯涓� 6 浣�", trigger: "blur" },
-        ],
-        confirmPassword: [{ validator: validatePass2, trigger: "blur" }],
-      },
-      pwRules: {
-        // pw: [{ validator: validatePass3, trigger: "blur" }],
-        curPassword: [
-          { required: true, message: "璇疯緭鍏ュ瘑鐮�", trigger: "blur" },
-          { min: 6, message: "闀垮害鑷冲皯涓� 6 浣�", trigger: "blur" },
-        ],
-        newPassword: [
-          { required: true, message: "璇疯緭鍏ュ瘑鐮�", trigger: "blur" },
-          { min: 6, message: "闀垮害鑷冲皯涓� 6 浣�", trigger: "blur" },
-        ],
-        confirmPassword: [{ validator: validatePass4, trigger: "blur" }],
-      },
-    };
-  },
-  beforeDestroy() {
-    clearTimeout(this.clockTimer);
-    clearInterval(this.browserTimer);
-  },
-  mounted() {
-    this.fetchUserList();
-    this.fetchDefHeadPic();
-  },
-  methods: {
-    fetchDefHeadPic() {
-      defHeadPics().then((res) => {
-        this.jpgArr = res.data;
-      });
-    },
-    fetchUserList(showLast = false) {
-      getUsers().then((res) => {
-        this.accountArr = res.data;
-        if (this.accountArr.length) {
-          this.activeAccountItem = this.accountArr[0];
-          this.activeAccountIndex = 0;
-        }
-        if (showLast) {
-          this.cancelAdd();
-          const lastIdx = this.accountArr.length - 1;
-          this.openAccount(this.accountArr[lastIdx], lastIdx);
-        }
-      });
-    },
-    blurInputNick() {
-      this.$refs["input-nick"].blur();
-    },
-    editNickName() {
-      this.showInputNickName = true;
-      this.inputNickName = this.activeAccountItem.nickname;
-      this.$refs["input-nick"].focus();
-    },
-    hideInputNick() {
-      this.showInputNickName = false;
-      updateUser({
-        id: this.activeAccountItem.id,
-        nickname: this.inputNickName,
-      }).then((res) => {
-        this.$message.success(res.msg);
-        this.fetchUserList(true);
-      });
-    },
-    openAccount(item, i) {
-      this.activeAccountItem = item;
-      this.activeAccountIndex = i;
-      this.inAccountDetail = false;
-      this.cancelSet();
-      this.fetchMenu();
-    },
-    minusOne(typ) {
-      this.isSyncBrowser = false;
-      this.syncBrowser(false);
-      let num;
-      switch (typ) {
-        case "hrs":
-          num = +this.syncHour - 1;
-          if (num == -1) {
-            num = 23;
-          }
-          this.syncHour = this.padZero(num);
-          break;
-        case "min":
-          num = +this.syncMin - 1;
-          if (num == -1) {
-            num = 59;
-          }
-          this.syncMin = this.padZero(num);
-          break;
-        case "sec":
-          num = +this.syncSec + 1;
-          if (num == -1) {
-            num = 59;
-          }
-          this.syncSec = this.padZero(num);
-          break;
-        case "yrs":
-          num = +this.syncYrs - 1;
-          this.syncYrs = this.padZero(num);
-          break;
-        case "mth":
-          num = +this.syncMonth - 1;
-          if (num == 0) {
-            num = 12;
-            this.minusOne("yrs");
-          }
-          this.syncMonth = this.padZero(num);
-          break;
-        case "day":
-          num = +this.syncDay - 1;
-          if (num == 0) {
-            this.minusOne("mth");
-            const maxDay = new Date(
-              +this.syncYrs,
-              +this.syncMonth,
-              0
-            ).getDate();
-            num = maxDay;
-          }
-          this.syncDay = this.padZero(num);
-          break;
-        default:
-          break;
-      }
-    },
-    fatherChange(item) {
-      item.children.forEach((x) => {
-        x.selected = item.selected;
-      });
-    },
-    childrenChange(item) {
-      let isAllSelected = item.children.every((x) => x.selected == true);
-      item.selected = isAllSelected;
-    },
-    plusOne(typ) {
-      this.isSyncBrowser = false;
-      this.syncBrowser(false);
-      let num;
-      switch (typ) {
-        case "hrs":
-          num = +this.syncHour + 1;
-          if (num == 24) {
-            num = 0;
-          }
-          this.syncHour = this.padZero(num);
-          break;
-        case "min":
-          num = +this.syncMin + 1;
-          if (num == 60) {
-            num = 0;
-          }
-          this.syncMin = this.padZero(num);
-          break;
-        case "sec":
-          num = +this.syncSec + 1;
-          if (num == 60) {
-            num = 0;
-          }
-          this.syncSec = this.padZero(num);
-          break;
-        case "yrs":
-          num = +this.syncYrs + 1;
-          this.syncYrs = this.padZero(num);
-          break;
-        case "mth":
-          num = +this.syncMonth + 1;
-          if (num == 13) {
-            num = 1;
-          }
-          this.syncMonth = this.padZero(num);
-          break;
-        case "day":
-          num = +this.syncDay + 1;
-          const maxDay = new Date(+this.syncYrs, +this.syncMonth, 0).getDate();
-          if (num > maxDay) {
-            num = 1;
-          }
-          this.syncDay = this.padZero(num);
-          break;
-        default:
-          break;
-      }
-    },
-    submitClock() {
-      if (this.syncType === "1") {
-        if (this.ntpServer === "" || this.ntpServer === "...") {
-          this.$notify({
-            type: "error",
-            message: "NTP 鏈嶅姟鍣ㄥ湴鍧�涓嶈兘涓虹┖",
-          });
-          return false;
-        } else if (this.timeInterval === "") {
-          this.timeInterval = 1;
-        }
-      } else if (this.isSyncBrowser) {
-        if (this.settime === "") {
-          this.$notify({
-            type: "error",
-            message: "璁剧疆鏃堕棿涓嶈兘涓虹┖",
-          });
-          return false;
-        }
-      } else {
-        this.settime = `${this.syncYrs}-${this.syncMonth}-${this.syncDay} ${this.syncHour}:${this.syncMin}:${this.syncSec}`;
-      }
-      saveClockInfo({
-        timeZone: this.timezone,
-        ntp: this.syncType === "1",
-        ntpServer: this.ntpServer,
-        interval: this.timeInterval,
-        newTime: this.settime,
-      }).then((rsp) => {
-        if (rsp && rsp.success) {
-          this.$notify({
-            type: "success",
-            message: "璁剧疆鎴愬姛",
-          });
-        }
-        this.initClockConf();
-      });
-    },
-    flatGetArr(arr, res) {
-      for (const item of arr) {
-        if (item.selected) res.push(item.id);
-        if (item.children) this.flatGetArr(item.children, res);
-      }
-    },
-    saveAuth() {
-      let arr = [];
-      this.flatGetArr(this.sysMenus, arr);
-      updataUser({
-        id: this.activeAccountItem.id,
-        menuIds: arr,
-      }).then((res) => {
-        if (res.success) {
-          this.$message.success(res.msg);
-          this.cancelSet();
-        }
-      });
-    },
-    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()));
-      this.weekday = "鏄熸湡" + "鏃ヤ竴浜屼笁鍥涗簲鍏�".charAt(date.getDay());
-      for (var i in returnArr) {
-        format = format.replace(formateArr[i], returnArr[i]);
-      }
-      return format;
-    },
-    padZero(n) {
-      n = +n;
-      return n < 10 ? "0" + n : "" + n;
-    },
-    formatNumber(n) {
-      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) {
-          this.timezone = rsp.data.time_zone;
-          if (!ntpTest) {
-            this.syncType = rsp.data.ntp ? "1" : "2";
-            this.isNtp = rsp.data.ntp;
-            this.isManual = !rsp.data.ntp;
-          }
-          if (rsp.data.ntp) {
-            this.ntpServer = rsp.data.ntp_server;
-            this.timeInterval = rsp.data.interval;
-          }
-          this.timestamp = rsp.data.local_time;
-          if (this.clockTimer === null) {
-            this.runClock();
-            if (this.isManual) this.parseTime();
-          }
-        }
-      });
-    },
-    openMenu(name, i) {
-      this.activePage = name;
-      this.activeIndex = i;
-      if (this.activePage == "鏃ユ湡鏃堕棿") {
-        this.initClockConf();
-      }
-    },
-    openWelcome(name,i){
-      this.showWelcome = false
-      this.openMenu(name,i)
-    },
-    showInput(typ) {
-      this[`show${typ}Input`] = true;
-      this.$nextTick(() => {
-        this.$refs[`ipt${typ}`].focus();
-      });
-    },
-    hideInput(typ) {
-      if (this[`input${typ}`]) {
-        this[`sync${typ}`] = this.padZero(this[`input${typ}`]);
-      }
-      this[`show${typ}Input`] = false;
-      this[`input${typ}`] = "";
-    },
-    syncBrowser(enable) {
-      this.isSyncBrowser = 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");
-          let [arr1, arr2] = this.settime.split(" ");
-          [this.syncYrs, this.syncMonth, this.syncDay] = arr1.split("-");
-          [this.syncHour, this.syncMin, this.syncSec] = arr2.split(":");
-        }, 1000);
-      }
-    },
-    showAddAccount() {
-      this.inAccountDetail = false;
-      this.isAddAccount = true;
-      getRoles().then((res) => {
-        if (res.success) {
-          this.roleList = res.data;
-        }
-      });
-    },
-    cancelAdd() {
-      this.inAccountDetail = false;
-      this.isAddAccount = false;
-      this.$refs["addForm"].resetFields();
-      this.selectedPic = null;
-    },
-    cancelPassword() {
-      this.isChangePw = false;
-      this.inAccountDetail = false;
-      this.$refs["passwordForm"].resetFields();
-    },
-    SaveNewPassword(formName) {
-      this.$refs[formName].validate((valid) => {
-        if (valid) {
-          updatePassword({
-            oldPwd: this.passwordForm.curPassword,
-            newPwd: this.passwordForm.newPassword,
-          }).then(
-            (res) => {
-              if (res.success) {
-                this.$message.success(res.msg);
-                this.cancelPassword();
-              }
-            },
-            (err) => {
-              this.$message.warning("淇濆瓨澶辫触锛�" + err.msg);
-            }
-          );
-        }
-      });
-    },
-    saveAddAccount(formName) {
-      this.$refs[formName].validate((valid) => {
-        if (valid) {
-          let data = {
-            username: this.addForm.userName,
-            password: this.addForm.password,
-            nickname: this.addForm.nickName,
-            headpic: this.addForm.headpic,
-          };
-          addUser(data).then(
-            (res) => {
-              this.$message.success(res.data);
-              this.fetchUserList(true);
-            },
-            (err) => {
-              this.$message.warning("淇濆瓨澶辫触锛�" + err.msg);
-            }
-          );
-        } else {
-          console.log("error submit!!");
-          return false;
-        }
-      });
-    },
-    pickHeadDefPic(item, i) {
-      this.addForm.headpic = item.path;
-      this.selectedPic = i;
-    },
-    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;
-        });
-    },
-    cancelSet() {
-      this.isSetPermission = false;
-      this.inAccountDetail = false;
-      this.sysMenus = [];
-    },
-    showChangePassword() {
-      this.isChangePw = true;
-      this.inAccountDetail = true;
-    },
-    runClock() {
-      const str = this.formatTime(++this.timestamp, "Y-M-D h:m:s");
-      [this.equipmentDate, this.equipmentTime] = str.split(" ");
-      this.clockTimer = setTimeout(() => {
-        this.runClock();
-      }, 1000);
-    },
-    deleteAccount() {
-      this.$confirm("鎮ㄦ槸鍚︾‘璁ゅ垹闄よ处鎴凤紵", "鍒犻櫎璐︽埛", {
-        confirmButtonText: "纭畾",
-        cancelButtonText: "鍙栨秷",
-      })
-        .then(() => {
-          let obj = {
-            ids: [this.activeAccountItem.id],
-          };
-          deleteUser(obj).then((res) => {
-            if (res.success) {
-              this.fetchUserList();
-              this.$message({
-                type: "success",
-                message: "鍒犻櫎鎴愬姛!",
-              });
-            } else {
-              this.$message.warning("鍒犻櫎澶辫触");
-            }
-          });
-        })
-        .catch(() => {});
-    },
-    fetchMenu() {
-      getUserMenus({
-        userId: this.activeAccountItem.id,
-      }).then((res) => {
-        if (res && res.success) {
-          this.sysMenus = res.data;
-        }
-      });
-    },
-    openPermission() {
-      this.inAccountDetail = true;
-      this.isSetPermission = true;
-      if (this.sysMenus.length == 0) {
-        this.fetchMenu();
-      }
-    },
-    parseTime() {
-      [this.syncYrs, this.syncMonth, this.syncDay] = this.equipmentDate.split(
-        "-"
-      );
-      [this.syncHour, this.syncMin, this.syncSec] = this.equipmentTime.split(
-        ":"
-      );
-    },
-    changeSwitch(str) {
-      if (str == "isNtp") {
-        this.isManual = !this[str];
-      } else {
-        this.isNtp = !this[str];
-      }
-      this.syncType = this.isNtp ? "1" : "2";
-      if (this.isManual) this.parseTime();
-    },
+      activeName: "basic",
+      buttonAuthority: sessionStorage.getItem("buttonAuthoritys") || [],
+      loginName: JSON.parse(sessionStorage.getItem("userInfo")).username || "鐢ㄦ埛鍚�"
+    }
   },
   computed: {
-    isShowAddAccount() {
-      const info = JSON.parse(sessionStorage.getItem("userInfo"));
-      return true;
+    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">
-.welcome-page {
-  width: 100%;
+.s-system-manage {
+  width: 100% !important;
+  min-width: 1067px;
   height: 100%;
-  background-color: #f5f5f5;
-  display: -ms-flexbox;
-  padding: 0 50px;
-  -webkit-box-sizing: border-box;
   box-sizing: border-box;
-  .child {
+  padding: 10px;
+  background-color: #f8f9fb;
+  .s-system-manage-breadcrumb {
+    height: 5%;
     box-sizing: border-box;
-    background-color: white;
-    -webkit-box-flex: 0;
-    -ms-flex: 0 0 33.3%;
-    /* flex: 0 0 16%; */
-    float: left;
-    width: 250px;
-    height: 200px;
-    margin: 50px 57px 30px 57px;
-    border-radius: 20px;
-    display: flex;
-    justify-content: center;
-    align-items: center;
-    cursor: pointer;
-    .child-info {
-      display: flex;
-      flex-direction: column;
-      height: 62%;
-      justify-content: space-around;
-      .welcome-icon {
-        font-size: 72px;
+    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;
       }
-      .welcome-title {
-        font-size: 18px;
+      .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;
       }
     }
   }
-  .child:hover {
-    -moz-box-shadow: 5px 5px 10px #ddd;
-    -webkit-box-shadow: 5px 5px 10px #ddd;
-    box-shadow: 5px 5px 10px #ddd;
-    transform: translate3d(0,-2.5px,0);
-     transition: all 0.3s;
-}
-}
-.container {
-  height: 100%;
-  display: flex;
-  flex-direction: row;
-  flex: 1;
-  flex-basis: auto;
-  box-sizing: border-box;
-  .container-left {
-    height: 100%;
-     width: 230px;
-    overflow: auto;
+  .el-tabs__header {
+    margin-bottom: 0;
+  }
+  .el-tabs__content {
+    height: calc(100% - 64px);
     box-sizing: border-box;
-    flex-shrink: 0;
-    padding: 10px;
-    border-right: 5px solid rgba(248, 248, 248, 1);
-    box-sizing: border-box;
-    .left-card {
-      height: 55px;
-      cursor: pointer;
-      border-radius: 12px;
-      margin-bottom: 10px;
-      display: flex;
-      align-items: center;
-      .iconfont {
-        margin-left: 25px;
-        margin-right: 10px;
-        font-size: 24px;
-      }
-      .card-text {
+    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;
       }
     }
-    .left-card-active {
-      background-color: rgba(61, 104, 225, 1);
-      color: #fff;
-    }
-    .left-card:hover {
-      background-color: rgba(61, 104, 225, 1);
-      color: #fff;
-    }
   }
-  .container-center {
-    height: 100%;
-    width: 280px;
-    overflow: auto;
-    flex-shrink: 0;
-    padding: 10px;
-    border-right: 5px solid rgba(248, 248, 248, 1);
-    box-sizing: border-box;
-    .account-left {
-      .add-account {
-        color: rgba(61, 104, 225, 1);
-        margin-top: 30px;
-        .iconfont {
-          cursor: pointer;
-          font-size: 32px;
-        }
-      }
-      .account-card {
-        height: 50px;
-        background-color: rgba(248, 248, 248, 1);
-        margin-bottom: 10px;
-        display: flex;
-        align-items: center;
-        padding: 0 20px;
-        box-sizing: border-box;
-        border-radius: 10px;
-        cursor: pointer;
-        .touxiang {
-          height: 35px;
-          width: 35px;
-          background-color: bisque;
-          border-radius: 17.5px;
-          img {
-            border: none;
 
-            height: 35px;
-            width: 35px;
-            border-radius: 17.5px;
-          }
-        }
-        .user-name {
-          margin-left: 10px;
-          font-size: 14px;
-        }
-      }
-
-      .account-card-active {
-        background-color: rgba(61, 104, 225, 1);
-        color: #fff;
-      }
-    }
-    .datetime-left {
-      .time-card {
-        height: 105px;
-        background-color: rgba(248, 248, 248, 1);
-        margin-bottom: 30px;
-        border-radius: 10px;
-        .head {
-          height: 30px;
-          line-height: 30px;
-          text-align: left;
-          box-sizing: border-box;
-          padding: 0 10px;
-          font-size: 14px;
-          .icon {
-            margin-right: 5px;
-            color: rgba(61, 104, 225, 1);
-          }
-        }
-        .time-main {
-          height: 42px;
-          line-height: 42px;
-          font-family: Consolas;
-          font-size: 36px;
-        }
-        .date-bot {
-          height: 25px;
-          font-size: 14px;
-          line-height: 25px;
-          color: #868686;
-          display: flex;
-          justify-content: space-evenly;
-        }
-      }
-      .line {
-        display: flex;
-        align-items: center;
-        height: 50px;
-        padding: 0 25px;
-        background-color: rgba(248, 248, 248, 1);
-        justify-content: space-between;
-        border-radius: 12px;
-        margin-bottom: 10px;
-        .name {
-          font-size: 14px;
-        }
-      }
-    }
+  .s-table {
+    border: 1px solid #e8e8e9;
+    margin-top: 40px;
   }
-  .container-right {
-    flex: 1;
-    flex-basis: auto;
-    overflow: auto;
-    box-sizing: border-box;
+
+  .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;
+  }
 
-    padding: 20px 40px;
-    .account-right {
-      .account-content {
-        .content-top {
-          height: 120px;
-          width: 350px;
-          margin: 0 auto;
-          display: flex;
-          align-items: center;
-          justify-content: center;
-          margin-bottom: 20px;
-          .touxiang-big {
-            width: 100px;
-            height: 100px;
-            background-color: bisque;
-            border-radius: 50px;
-            img {
-              border: none;
+  .ui-top-title:before {
+    content: " ";
+    border-left: 4px solid #f53d3d;
+    display: inline-block;
+    height: 16px;
+    position: absolute;
+    top: 50%;
+    left: 0;
+    margin-top: -13px;
+  }
 
-              width: 100px;
-              height: 100px;
-              border-radius: 50px;
-            }
-          }
-          .user-desc {
-            height: 100px;
-            display: flex;
-            flex-direction: column;
-            align-items: baseline;
-            min-width: 200px;
-            .username {
-              margin: 5px 15px;
-              height: 30px;
-              line-height: 30px;
-              // width: 90px;
-              text-align: left;
-              font-size: 15px;
-              display: flex;
-              align-items: center;
-            }
-            .nickname {
-              margin: 5px 15px;
-              font-size: 14px;
-              .input-nick {
-                width: 50px;
-                margin-right: 5px;
-              }
-              .iconfont {
-                font-size: 14px;
-                margin-left: 5px;
-                cursor: pointer;
-              }
-            }
-            .user-role {
-              margin: 5px 0 0 15px;
-              font-size: 14px;
-              color: darkseagreen;
-            }
-          }
-        }
-        .list-btn {
-          display: flex;
-
-          flex-direction: column;
-          align-items: center;
-          .item-btn {
-            width: 500px;
-            height: 45px;
-            background-color: #f0f0f0;
-            margin-bottom: 15px;
-            border-radius: 10px;
-            line-height: 45px;
-            font-size: 15px;
-            cursor: pointer;
-          }
-          .item-btn:hover {
-            color: rgba(255, 153, 102, 1);
-          }
-        }
-      }
-      .title {
-        height: 30px;
-        line-height: 30px;
-        /* background-color: aliceblue; */
-        margin-bottom: 10px;
-        font-size: 16px;
-        font-weight: 600;
-      }
-      .change-pw {
-        .p-title {
-          text-align: left;
-          font-size: 15px;
-          margin-top: 5px;
-        }
-      }
-      .el-form-item {
-        margin-bottom: 0;
-        .el-input__inner {
-          background-color: rgba(240, 240, 240, 1);
-          border: none;
-          border-radius: 12px;
-          height: 45px;
-          padding: 0 20px;
-          font-size: 15px;
-        }
-        .el-input__clear {
-          color: dimgray;
-          font-size: 17px;
-          line-height: 45px;
-        }
-        .el-input__suffix {
-          right: 1px;
-          top: -0.5px;
-          width: 45px;
-          // background-color: rgba(61, 104, 225, 1);
-          /* color: white; */
-          border-radius: 12px;
-        }
-      }
-      .permission {
-        .line {
-          display: flex;
-          align-items: center;
-          height: 50px;
-          padding: 0 25px;
-          background-color: rgba(248, 248, 248, 1);
-          justify-content: space-between;
-          border-radius: 12px;
-          margin-bottom: 10px;
-          .name {
-            font-size: 14px;
-          }
-        }
-      }
-
-      .add-account-page {
-        .upload-group {
-          height: 120px;
-          width: 360px;
-          margin: 0 auto;
-          overflow: hidden;
-          .upload-jpg {
-            position: relative;
-            height: 48px;
-            width: 48px;
-            float: left;
-            margin: 0 10px;
-            margin-bottom: 10px;
-            background-color: rgba(242, 242, 242, 1);
-            border: 2px solid transparent;
-            border-radius: 50%;
-            cursor: pointer;
-            img {
-              height: 48px;
-              width: 48px;
-              border-radius: 50%;
-            }
-            .img-mask {
-              position: absolute;
-              left: 0;
-              top: 0;
-              height: 48px;
-              width: 48px;
-              background-color: rgba(0, 0, 0, 0.3);
-              color: white;
-              border-radius: 50%;
-              display: flex;
-              justify-content: center;
-              align-items: center;
-              .selected {
-                font-size: 22px;
-              }
-            }
-          }
-          .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;
-          }
-        }
-        .fill-group {
-          .p-title {
-            height: 34px;
-            text-align: left;
-          }
-          .el-form-item {
-            .el-select {
-              width: 100%;
-            }
-          }
-        }
-      }
-    }
-    .datetime-right {
-      .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;
-      }
-      .el-form-item {
-        margin-bottom: 10px;
-        height: 50px;
-        background: #f8f8f8;
-        padding: 4px 20px;
-        -webkit-box-sizing: border-box;
-        box-sizing: border-box;
-        border-radius: 10px;
-        .el-form-item__label {
-          text-align: left;
-          line-height: 42px;
-        }
-      }
-      .el-form-item__content {
-        line-height: 40px;
-        position: relative;
-        font-size: 14px;
-        margin-bottom: 10px;
-      }
-      .ip-input-container {
-        max-width: none !important;
-      }
-      .ntp-time {
-        .right {
-          display: flex;
-          align-items: baseline;
-          .el-input-number--small {
-            width: 100%;
-          }
-          .el-button--text {
-            margin-left: 10px;
-            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 {
-          height: 75px;
-
-          background-color: #f8f8f8;
-          display: flex;
-          justify-content: center;
-          align-items: center;
-          margin-bottom: 10px;
-          border-radius: 10px;
-          .clock {
-            display: flex;
-            align-items: center;
-            height: 90px;
-            justify-content: space-evenly;
-            .iconfont {
-              cursor: pointer;
-              color: rgba(134, 134, 134, 1);
-            }
-            .iconfont:hover {
-              background-color: gainsboro;
-            }
-            .hour {
-              background-color: rgba(240, 240, 240, 1);
-              display: flex;
-              align-items: center;
-              width: 100px;
-              height: 50px;
-              justify-content: space-evenly;
-              border-radius: 10px;
-            }
-            .dnum {
-              width: 40px;
-              height: 40px;
-              line-height: 40px;
-              font-size: 34px;
-              font-family: Consolas;
-              display: flex;
-              align-items: center;
-              .input-box {
-                width: inherit;
-                border: none;
-                border-radius: 5px;
-                height: 35px;
-                font-size: 28px;
-                text-align: center;
-              }
-
-              .input-box:focus {
-                outline: none;
-              }
-            }
-            .control {
-              width: 20px;
-              .fanzhuan {
-                display: inline-block;
-                -moz-transform: scaleY(-1);
-                -webkit-transform: scaleY(-1);
-                -o-transform: scaleY(-1);
-                transform: scaleY(-1);
-              }
-            }
-            .sep {
-              font-family: Consolas;
-              width: 40px;
-              font-size: 34px;
-              height: 40px;
-              line-height: 40px;
-            }
-            .mins {
-              background-color: #f0f0f0;
-              display: flex;
-              align-items: center;
-              width: 110px;
-              height: 50px;
-              justify-content: space-evenly;
-              border-radius: 10px;
-            }
-          }
-        }
-        .adjust-bar {
-          display: flex;
-          justify-content: space-between;
-          align-items: center;
-          margin-bottom: 10px;
-          border-radius: 10px;
-          height: 50px;
-          background-color: rgba(248, 248, 248, 1);
-          .middle {
-            font-size: 14px;
-          }
-          .input-box {
-            width: 80px;
-            border: none;
-            border-radius: 5px;
-            height: 25px;
-            font-size: 18px;
-            text-align: center;
-          }
-
-          .input-box:focus {
-            outline: none;
-          }
-          .minus {
-            width: 50px;
-            height: 50px;
-            background-color: #f0f0f0;
-            font-size: 35px;
-            border-radius: 10px;
-            cursor: pointer;
-            line-height: 50px;
-            color: rgba(134, 134, 134, 1);
-          }
-          .plus {
-            width: 50px;
-            height: 50px;
-            cursor: pointer;
-            background-color: #f0f0f0;
-            font-size: 35px;
-            border-radius: 10px;
-            line-height: 50px;
-            color: rgba(134, 134, 134, 1);
-          }
-        }
-      }
-    }
-    .btns {
-      display: flex;
-      justify-content: space-between;
-      margin-top: 20px;
-
-      .cancel {
-        height: 40px;
-        width: 48%;
-        cursor: pointer;
-        border-radius: 8px;
-        background-color: rgba(240, 240, 240, 1);
-        line-height: 40px;
-        font-size: 14px;
-      }
-      .ok {
-        height: 40px;
-        width: 48%;
-        cursor: pointer;
-        border-radius: 8px;
-        background-color: rgba(61, 104, 225, 1);
-        color: #fff;
-        line-height: 40px;
-        font-size: 14px;
-      }
-    }
+  .el-button--text {
+    color: #3d68e1;
+    text-decoration: underline;
   }
 }
 </style>
-
-
diff --git a/src/pages/systemSettings/components/CloudNode.vue b/src/pages/systemSettings/components/CloudNode.vue
new file mode 100644
index 0000000..800651a
--- /dev/null
+++ b/src/pages/systemSettings/components/CloudNode.vue
@@ -0,0 +1,149 @@
+<template>
+  <div class="cloud">
+    <div class="inner">
+      <div class="rect">
+        <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>
+  </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,
+    };
+  },
+  mounted() {
+    console.log(this.nodes);
+    //this.getInsideNodes();
+  },
+  methods: {
+    getRandom(index) {
+      if (index % 2 == 0) {
+        return Math.random() * 20;
+      } else {
+        return Math.random() * 50;
+      }
+    },
+    getInsideNodes() {
+      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;
+    },
+    outsideNodes() {
+      return this.nodes.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: -55px;
+    margin-left: 55px;
+
+    .rect {
+      position: relative;
+      margin: 130px 100px 70px;
+      .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/settings/components/switchBar.vue b/src/pages/systemSettings/components/switchBar.vue
similarity index 100%
rename from src/pages/settings/components/switchBar.vue
rename to src/pages/systemSettings/components/switchBar.vue
diff --git a/src/pages/systemSettings/index/App.vue b/src/pages/systemSettings/index/App.vue
new file mode 100644
index 0000000..ef71b7c
--- /dev/null
+++ b/src/pages/systemSettings/index/App.vue
@@ -0,0 +1,1831 @@
+<template>
+  <div class="container" v-if="!showWelcome">
+    <div class="container-left">
+      <div
+        class="left-card"
+        :class="activeIndex == index ? 'left-card-active' : ''"
+        v-for="(item, index) in menuArr"
+        :key="index"
+        @click="openMenu(item.name, index)"
+      >
+        <span class="icon iconfont">&#xe646;</span>
+        <span class="card-text">{{ item.name }}</span>
+      </div>
+    </div>
+
+    <div
+      class="container-center"
+      v-if="activePage == '璐︽埛' || activePage == '鏃ユ湡鏃堕棿'"
+    >
+      <div class="account-left" v-if="activePage == '璐︽埛'">
+        <div class="account-list">
+          <div
+            class="account-card"
+            :class="activeAccountIndex == index ? 'account-card-active' : ''"
+            v-for="(item, index) in accountArr"
+            :key="index"
+            ref="account-card"
+            @click="openAccount(item, index)"
+          >
+            <div class="touxiang">
+              <img
+                v-if="item.headpic"
+                :src="`data:image/png;base64,${item.headpic}`"
+                alt=""
+              />
+              
+            </div>
+            <span class="user-name">{{ item.username }}</span>
+          </div>
+        </div>
+        <div class="add-account">
+          <span class="icon iconfont" @click="showAddAccount">&#xe646;</span>
+        </div>
+      </div>
+      <div class="datetime-left" v-if="activePage == '鏃ユ湡鏃堕棿'">
+        <div class="time-card">
+          <div class="head">
+            <span class="icon iconfont">&#xe690;</span>
+            <span>璁惧鏃堕棿</span>
+          </div>
+          <div class="time-main">{{ equipmentTime }}</div>
+          <div class="date-bot">
+            <span class="year">{{ equipmentDate }}</span>
+            <span class="week">{{ weekday }}</span>
+          </div>
+        </div>
+        <div class="line">
+          <div class="name">NTP鏍℃椂</div>
+          <el-switch
+            v-model="isNtp"
+            @change="changeSwitch('isNtp')"
+            active-color="rgba(61, 104, 225, 1)"
+          >
+          </el-switch>
+        </div>
+
+        <div class="line">
+          <div class="name">鎵嬪姩鏍″</div>
+          <el-switch
+            v-model="isManual"
+            @change="changeSwitch('isManual')"
+            active-color="rgba(61, 104, 225, 1)"
+          >
+          </el-switch>
+        </div>
+      </div>
+    </div>
+    <div
+      class="container-right"
+      v-if="activePage == '璐︽埛' || activePage == '鏃ユ湡鏃堕棿'"
+    >
+      <div class="account-right" v-if="activePage == '璐︽埛'">
+        <div
+          class="account-content"
+          v-if="inAccountDetail == false && isAddAccount == false"
+        >
+          <div class="content-top">
+            <div class="touxiang-big">
+              <img
+                v-if="activeAccountItem.headpic"
+                :src="`data:image/png;base64,${activeAccountItem.headpic}`"
+                alt=""
+              />
+            </div>
+            <div class="user-desc">
+              <div class="username">
+                <span class="icon iconfont" style="margin-right: 5px"
+                  >&#xe690;</span
+                >
+                <span>{{ activeAccountItem.username }}</span>
+              </div>
+              <div class="nickname">
+                <span>鏄电О锛�</span>
+                <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"
+                />
+                <span class="icon iconfont" @click="editNickName"
+                  >&#xe60c;</span
+                >
+              </div>
+              <div class="user-role">
+                {{
+                  activeAccountItem.sysRoles.length
+                    ? activeAccountItem.sysRoles[0].name
+                    : ""
+                }}
+              </div>
+            </div>
+          </div>
+          <div class="list-btn">
+            <div class="item-btn" @click="showChangePassword">淇敼瀵嗙爜</div>
+            <div class="item-btn" @click="deleteAccount">鍒犻櫎璐︽埛</div>
+            <div class="item-btn" @click="openPermission">鏉冮檺璁剧疆</div>
+          </div>
+        </div>
+
+        <div class="change-pw" v-if="inAccountDetail && isChangePw">
+          <div class="title">淇敼瀵嗙爜</div>
+          <el-form
+            :model="passwordForm"
+            :rules="pwRules"
+            ref="passwordForm"
+            class="password-form"
+          >
+            <el-form-item prop="curPassword">
+              <div class="p-title">褰撳墠瀵嗙爜锛�</div>
+
+              <el-input
+                placeholder="蹇呭~"
+                v-model="passwordForm.curPassword"
+                show-password
+              ></el-input>
+            </el-form-item>
+            <el-form-item prop="newPassword">
+              <div class="p-title">鏂板瘑鐮侊細</div>
+              <el-input
+                placeholder="蹇呭~"
+                v-model="passwordForm.newPassword"
+                show-password
+              ></el-input>
+            </el-form-item>
+            <el-form-item prop="confirmPassword">
+              <div class="p-title">纭瀵嗙爜锛�</div>
+              <el-input
+                placeholder="蹇呭~"
+                v-model="passwordForm.confirmPassword"
+                show-password
+              ></el-input>
+            </el-form-item>
+          </el-form>
+          <div class="btns">
+            <div class="cancel" @click="cancelPassword">鍙栨秷</div>
+            <div class="ok" @click="SaveNewPassword('passwordForm')">淇濆瓨</div>
+          </div>
+        </div>
+
+        <div class="permission" v-if="inAccountDetail && isSetPermission">
+          <div class="title">鏉冮檺绠$悊</div>
+
+          <div class="line-wrap" v-for="item in sysMenus" :key="item.id">
+            <div class="line">
+              <div class="name">{{ item.name }}</div>
+              <el-switch
+                v-model="item.selected"
+                active-color="rgba(61, 104, 225, 1)"
+                @change="fatherChange(item)"
+              >
+              </el-switch>
+            </div>
+            <div v-if="item.children">
+              <div
+                class="line"
+                style="margin-left: 55px"
+                v-for="x in item.children"
+                :key="x.id"
+              >
+                <div class="name">{{ x.name }}</div>
+                <el-switch
+                  v-model="x.selected"
+                  active-color="rgba(61, 104, 225, 1)"
+                  @change="childrenChange(item)"
+                >
+                </el-switch>
+              </div>
+            </div>
+          </div>
+          <div class="btns">
+            <div class="cancel" @click="cancelSet">鍙栨秷</div>
+            <div class="ok" @click="saveAuth">淇濆瓨</div>
+          </div>
+        </div>
+
+        <div class="add-account-page" v-if="isAddAccount">
+          <div class="title">娣诲姞璐︽埛</div>
+          <div class="upload-group">
+            <div
+              class="upload-jpg"
+              :class="
+                selectedPic == index? 'upload-jpg-border' : ''
+              "
+              v-for="(item, index) in jpgArr"
+              :key="index"
+              @click="pickHeadDefPic(item, index)"
+            >
+              <img
+                v-if="item"
+                :src="`data:image/png;base64,${item.path}`"
+                alt=""
+                srcset=""
+              />
+              <div class="img-mask" v-if="selectedPic == index">
+                <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
+              :model="addForm"
+              :rules="rules"
+              ref="addForm"
+              class="add-form"
+            >
+              <el-form-item prop="userName">
+                <div class="p-title">鐢ㄦ埛鍚嶏細</div>
+                <el-input
+                  placeholder="蹇呭~"
+                  v-model="addForm.userName"
+                ></el-input>
+              </el-form-item>
+              <el-form-item prop="roleId">
+                <div class="p-title">瑙掕壊锛�</div>
+                <el-select v-model="addForm.roleId" placeholder="璇烽�夋嫨瑙掕壊">
+                  <el-option
+                    v-for="(item, i) in roleList"
+                    :key="i"
+                    :label="item.name"
+                    :value="item.id"
+                  ></el-option>
+                </el-select>
+              </el-form-item>
+              <el-form-item prop="nickName">
+                <div class="p-title">鏄电О锛�</div>
+                <el-input
+                  placeholder="閫夊~"
+                  v-model="addForm.nickName"
+                ></el-input>
+              </el-form-item>
+              <el-form-item prop="password">
+                <div class="p-title">瀵嗙爜锛�</div>
+                <el-input
+                  placeholder="蹇呭~"
+                  v-model="addForm.password"
+                  show-password
+                ></el-input>
+              </el-form-item>
+              <el-form-item prop="confirmPassword">
+                <div class="p-title">纭瀵嗙爜锛�</div>
+                <el-input
+                  placeholder="蹇呭~"
+                  v-model="addForm.confirmPassword"
+                  show-password
+                ></el-input>
+              </el-form-item>
+            </el-form>
+          </div>
+          <div class="btns">
+            <div class="cancel" @click="cancelAdd">鍙栨秷</div>
+            <div class="ok" @click="saveAddAccount('addForm')">淇濆瓨</div>
+          </div>
+        </div>
+      </div>
+
+      <div class="datetime-right" v-if="activePage == '鏃ユ湡鏃堕棿'">
+        <div class="ntp-time" v-if="isNtp">
+          <el-form label-width="160px">
+            <el-form-item label="鏈嶅姟鍣ㄥ湴鍧�">
+              <!-- :disabled="syncType === '2'" -->
+              <ip-input
+                :ip="ntpServer"
+                @on-blur="ntpServer = arguments[0]"
+              ></ip-input>
+            </el-form-item>
+
+            <el-form-item label="鏍℃椂鏃堕棿闂撮殧锛堝垎閽燂級">
+              <div class="right">
+                <el-input-number
+                  v-model.number="timeInterval"
+                  :min="1"
+                  :max="60"
+                  placeholder="璇疯緭鍏�"
+                  size="small"
+                  :controls="false"
+                ></el-input-number>
+                <el-button
+                  type="text"
+                  @click="testNTP"
+                  :loading="ntpTestLoading"
+                  >娴嬭瘯</el-button
+                >
+              </div>
+            </el-form-item>
+          </el-form>
+        </div>
+
+        <div class="manual-time" v-if="isManual">
+          <switchBar
+            :barName="`鍚屾鏈绠楁満鏃堕棿`"
+            @switchChange="syncBrowser"
+            :value="isSyncBrowser"
+          ></switchBar>
+
+          <div class="clock-wrap">
+            <div class="clock">
+              <div class="hour">
+                <div class="dnum" @click="showInput('Hour')">
+                  <span v-show="!showHourInput">{{ syncHour }}</span>
+                  <input
+                    class="input-box"
+                    v-show="showHourInput"
+                    ref="iptHour"
+                    oninput="value=value.replace(/[^\d]/g,'');if(value.length>2)value=value.slice(0,2);if(+value>23)value='23'"
+                    type="text"
+                    v-model="inputHour"
+                    @blur="hideInput('Hour')"
+                    @keydown.enter="hideInput('Hour')"
+                  />
+                </div>
+                <div class="control">
+                  <span class="icon iconfont" @click="plusOne('hrs')"
+                    >&#xe60e;</span
+                  >
+                  <span class="icon iconfont fanzhuan" @click="minusOne('hrs')"
+                    >&#xe60e;</span
+                  >
+                </div>
+              </div>
+              <div class="sep">:</div>
+              <div class="mins">
+                <div class="dnum" @click="showInput('Min')">
+                  <span v-show="!showMinInput">{{ syncMin }}</span>
+                  <input
+                    class="input-box"
+                    v-show="showMinInput"
+                    ref="iptMin"
+                    oninput="value=value.replace(/[^\d]/g,'');if(value.length>2)value=value.slice(0,2);if(+value>59)value='59'"
+                    type="text"
+                    v-model="inputMin"
+                    @blur="hideInput('Min')"
+                    @keydown.enter="hideInput('Min')"
+                  />
+                </div>
+                <div class="control">
+                  <span class="icon iconfont" @click="plusOne('min')"
+                    >&#xe60e;</span
+                  >
+                  <span class="icon iconfont fanzhuan" @click="minusOne('min')"
+                    >&#xe60e;</span
+                  >
+                </div>
+              </div>
+              <div class="sep">:</div>
+              <div class="mins">
+                <div class="dnum" @click="showInput('Sec')">
+                  <span v-show="!showSecInput">{{ syncSec }}</span>
+                  <input
+                    class="input-box"
+                    v-show="showSecInput"
+                    ref="iptSec"
+                    oninput="value=value.replace(/[^\d]/g,'');if(value.length>2)value=value.slice(0,2);if(+value>59)value='59'"
+                    type="text"
+                    v-model="inputSec"
+                    @blur="hideInput('Sec')"
+                    @keydown.enter="hideInput('Sec')"
+                  />
+                </div>
+                <div class="control">
+                  <span class="icon iconfont" @click="plusOne('sec')"
+                    >&#xe60e;</span
+                  >
+                  <span class="icon iconfont fanzhuan" @click="minusOne('sec')"
+                    >&#xe60e;</span
+                  >
+                </div>
+              </div>
+            </div>
+          </div>
+
+          <div class="adjust-bar">
+            <div class="minus" @click="minusOne('yrs')">-</div>
+            <div class="middle" @click="showInput('Yrs')">
+              <span v-show="!showYrsInput">{{ syncYrs }}</span>
+              <input
+                class="input-box"
+                v-show="showYrsInput"
+                ref="iptYrs"
+                oninput="value=value.replace(/[^\d]/g,'');if(value.length>4)value=value.slice(0,4);"
+                type="text"
+                v-model="inputYrs"
+                @blur="hideInput('Yrs')"
+                @keydown.enter="hideInput('Yrs')"
+              />
+              骞�
+            </div>
+            <div class="plus" @click="plusOne('yrs')">+</div>
+          </div>
+          <div class="adjust-bar">
+            <div class="minus" @click="minusOne('mth')">-</div>
+            <div class="middle" @click="showInput('Month')">
+              <span v-show="!showMonthInput">{{ syncMonth }}</span>
+              <input
+                class="input-box"
+                v-show="showMonthInput"
+                ref="iptMonth"
+                oninput="value=value.replace(/[^\d]/g,'');if(value.length>2)value=value.slice(0,2);if(+value>12)value='12'"
+                type="text"
+                v-model="inputMonth"
+                @blur="hideInput('Month')"
+                @keydown.enter="hideInput('Month')"
+              />
+              鏈�
+            </div>
+
+            <div class="plus" @click="plusOne('mth')">+</div>
+          </div>
+          <div class="adjust-bar">
+            <div class="minus" @click="minusOne('day')">-</div>
+            <div class="middle" @click="showInput('Day')">
+              <span v-show="!showDayInput">{{ syncDay }}</span>
+              <input
+                class="input-box"
+                v-show="showDayInput"
+                ref="iptDay"
+                oninput="value=value.replace(/[^\d]/g,'');if(value.length>2)value=value.slice(0,2);if(+value>31)value='31'"
+                type="text"
+                v-model="inputDay"
+                @blur="hideInput('Day')"
+                @keydown.enter="hideInput('Day')"
+              />
+              鏃�
+            </div>
+            <div class="plus" @click="plusOne('day')">+</div>
+          </div>
+        </div>
+
+        <div class="btns">
+          <div class="cancel" @click="cancelPassword">鍙栨秷</div>
+          <div class="ok" @click="submitClock">淇濆瓨</div>
+        </div>
+      </div>
+    </div>
+
+    <clusterManagement
+      v-if="activePage == '闆嗙兢绠$悊'"
+      style="width: 100%"
+    ></clusterManagement>
+    <netSettings
+      v-if="activePage == '缃戠粶璁剧疆'"
+      style="width: 100%"
+    ></netSettings>
+    <keyboardLanguage
+      v-if="activePage == '閿洏鍜岃瑷�'"
+      style="width: 100%"
+    ></keyboardLanguage>
+    <generalSettings
+      v-if="activePage == '閫氱敤璁剧疆'"
+      style="width: 100%"
+    ></generalSettings>
+  </div>
+  <div class="welcome-page" v-else>
+    <div class="child" @click="openWelcome('璐︽埛',0)">
+      <div class="child-info">
+        <span class="icon iconfont welcome-icon">&#xe6de;</span>
+        <span class="welcome-title">璐︽埛</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>
+
+<script>
+import { getClockInfo, saveClockInfo, testNTPserver } from "@/api/system";
+import {
+  uploadHeadPic,
+  addUser,
+  getUsers,
+  updateUser,
+  updataUser,
+  updatePassword,
+  deleteUser,
+  getUserMenus,
+  defHeadPics,
+  getRoles,
+} from "@/api/user";
+import switchBar from "../components/switchBar";
+import ipInput from "@/components/subComponents/IPInput";
+import clusterManagement from "../views/clusterManagement";
+import netSettings from "../views/NetSettings";
+import keyboardLanguage from "../views/keyboardLanguage";
+import generalSettings from "../views/generalSettings";
+export default {
+  name: "settings",
+  components: {
+    switchBar,
+    ipInput,
+    clusterManagement,
+    netSettings,
+    keyboardLanguage,
+    generalSettings,
+  },
+  data() {
+    var validatePass2 = (rule, value, callback) => {
+      if (value === "") {
+        callback(new Error("璇峰啀娆¤緭鍏ュ瘑鐮�"));
+      } else if (value !== this.addForm.password) {
+        callback(new Error("涓ゆ杈撳叆瀵嗙爜涓嶄竴鑷�!"));
+      } else {
+        callback();
+      }
+    };
+    var validatePass4 = (rule, value, callback) => {
+      if (value === "") {
+        callback(new Error("璇峰啀娆¤緭鍏ュ瘑鐮�"));
+      } else if (value !== this.passwordForm.newPassword) {
+        callback(new Error("涓ゆ杈撳叆瀵嗙爜涓嶄竴鑷�!"));
+      } else {
+        callback();
+      }
+    };
+    return {
+      showAccount: true,
+      syncYrs: "",
+      activeAccountItem: {},
+      syncMonth: "",
+      syncHour: "",
+      showWelcome: true,
+      syncDay: "",
+      syncMin: "",
+      syncSec: "00",
+      isSyncBrowser: false,
+      showDateTime: false,
+      isAddAccount: false,
+      isCount: false,
+      isCalculate: false,
+      browserTimer: null,
+      timezone: "",
+      isRealtime: false,
+      inputNickName: "",
+      showHourInput: false,
+      showMinInput: false,
+      showSecInput: false,
+      showYrsInput: false,
+      showMonthInput: false,
+      selectedPic: null,
+      showDayInput: false,
+      loadedPic: "",
+      cameraInfo: false,
+      dependentScene: false,
+      timestamp: 0,
+      inAccountDetail: false,
+      isChangePw: false,
+      isSetPermission: false,
+      timeInterval: 10,
+      ntpServer: "",
+      syncType: "1",
+      equipmentTime: "",
+      equipmentDate: "",
+      roleList: [],
+      ntpTestLoading: false,
+      settime: "",
+      weekday: "",
+      menuArr: [
+        { name: "璐︽埛" },
+        { name: "鏃ユ湡鏃堕棿" },
+        { name: "闆嗙兢绠$悊" },
+        { name: "缃戠粶璁剧疆" },
+        { name: "閿洏鍜岃瑷�" },
+        { name: "閫氱敤璁剧疆" },
+      ],
+      accountArr: [],
+      jpgArr: [],
+      isManual: false,
+      isNtp: true,
+      activePage: "璐︽埛",
+      activeIndex: 0,
+      clockTimer: null,
+      inputHour: "",
+      inputMin: "",
+      inputSec: "",
+      inputYrs: "",
+      showInputNickName: false,
+      inputMonth: "",
+      inputDay: "",
+      passwordForm: {
+        curPassword: "",
+        newPassword: "",
+        confirmPassword: "",
+      },
+      activeAccountIndex: 0,
+      sysMenus: [],
+      addForm: {
+        userName: "",
+        nickName: "",
+        password: "",
+        headpic: "",
+        confirmPassword: "",
+        roleId: "",
+      },
+      rules: {
+        userName: [
+          { required: true, message: "璇疯緭鍏ョ敤鎴峰悕", trigger: "blur" },
+          {
+            min: 3,
+            max: 10,
+            message: "闀垮害鍦� 3 鍒� 10 涓瓧绗�",
+            trigger: "blur",
+          },
+        ],
+        password: [
+          { required: true, message: "璇疯緭鍏ュ瘑鐮�", trigger: "blur" },
+          { min: 6, message: "闀垮害鑷冲皯涓� 6 浣�", trigger: "blur" },
+        ],
+        confirmPassword: [{ validator: validatePass2, trigger: "blur" }],
+      },
+      pwRules: {
+        // pw: [{ validator: validatePass3, trigger: "blur" }],
+        curPassword: [
+          { required: true, message: "璇疯緭鍏ュ瘑鐮�", trigger: "blur" },
+          { min: 6, message: "闀垮害鑷冲皯涓� 6 浣�", trigger: "blur" },
+        ],
+        newPassword: [
+          { required: true, message: "璇疯緭鍏ュ瘑鐮�", trigger: "blur" },
+          { min: 6, message: "闀垮害鑷冲皯涓� 6 浣�", trigger: "blur" },
+        ],
+        confirmPassword: [{ validator: validatePass4, trigger: "blur" }],
+      },
+    };
+  },
+  beforeDestroy() {
+    clearTimeout(this.clockTimer);
+    clearInterval(this.browserTimer);
+  },
+  mounted() {
+    this.fetchUserList();
+    this.fetchDefHeadPic();
+  },
+  methods: {
+    fetchDefHeadPic() {
+      defHeadPics().then((res) => {
+        this.jpgArr = res.data;
+      });
+    },
+    fetchUserList(showLast = false) {
+      getUsers().then((res) => {
+        this.accountArr = res.data;
+        if (this.accountArr.length) {
+          this.activeAccountItem = this.accountArr[0];
+          this.activeAccountIndex = 0;
+        }
+        if (showLast) {
+          this.cancelAdd();
+          const lastIdx = this.accountArr.length - 1;
+          this.openAccount(this.accountArr[lastIdx], lastIdx);
+        }
+      });
+    },
+    blurInputNick() {
+      this.$refs["input-nick"].blur();
+    },
+    editNickName() {
+      this.showInputNickName = true;
+      this.inputNickName = this.activeAccountItem.nickname;
+      this.$refs["input-nick"].focus();
+    },
+    hideInputNick() {
+      this.showInputNickName = false;
+      updateUser({
+        id: this.activeAccountItem.id,
+        nickname: this.inputNickName,
+      }).then((res) => {
+        this.$message.success(res.msg);
+        this.fetchUserList(true);
+      });
+    },
+    openAccount(item, i) {
+      this.activeAccountItem = item;
+      this.activeAccountIndex = i;
+      this.inAccountDetail = false;
+      this.cancelSet();
+      this.fetchMenu();
+    },
+    minusOne(typ) {
+      this.isSyncBrowser = false;
+      this.syncBrowser(false);
+      let num;
+      switch (typ) {
+        case "hrs":
+          num = +this.syncHour - 1;
+          if (num == -1) {
+            num = 23;
+          }
+          this.syncHour = this.padZero(num);
+          break;
+        case "min":
+          num = +this.syncMin - 1;
+          if (num == -1) {
+            num = 59;
+          }
+          this.syncMin = this.padZero(num);
+          break;
+        case "sec":
+          num = +this.syncSec + 1;
+          if (num == -1) {
+            num = 59;
+          }
+          this.syncSec = this.padZero(num);
+          break;
+        case "yrs":
+          num = +this.syncYrs - 1;
+          this.syncYrs = this.padZero(num);
+          break;
+        case "mth":
+          num = +this.syncMonth - 1;
+          if (num == 0) {
+            num = 12;
+            this.minusOne("yrs");
+          }
+          this.syncMonth = this.padZero(num);
+          break;
+        case "day":
+          num = +this.syncDay - 1;
+          if (num == 0) {
+            this.minusOne("mth");
+            const maxDay = new Date(
+              +this.syncYrs,
+              +this.syncMonth,
+              0
+            ).getDate();
+            num = maxDay;
+          }
+          this.syncDay = this.padZero(num);
+          break;
+        default:
+          break;
+      }
+    },
+    fatherChange(item) {
+      item.children.forEach((x) => {
+        x.selected = item.selected;
+      });
+    },
+    childrenChange(item) {
+      let isAllSelected = item.children.every((x) => x.selected == true);
+      item.selected = isAllSelected;
+    },
+    plusOne(typ) {
+      this.isSyncBrowser = false;
+      this.syncBrowser(false);
+      let num;
+      switch (typ) {
+        case "hrs":
+          num = +this.syncHour + 1;
+          if (num == 24) {
+            num = 0;
+          }
+          this.syncHour = this.padZero(num);
+          break;
+        case "min":
+          num = +this.syncMin + 1;
+          if (num == 60) {
+            num = 0;
+          }
+          this.syncMin = this.padZero(num);
+          break;
+        case "sec":
+          num = +this.syncSec + 1;
+          if (num == 60) {
+            num = 0;
+          }
+          this.syncSec = this.padZero(num);
+          break;
+        case "yrs":
+          num = +this.syncYrs + 1;
+          this.syncYrs = this.padZero(num);
+          break;
+        case "mth":
+          num = +this.syncMonth + 1;
+          if (num == 13) {
+            num = 1;
+          }
+          this.syncMonth = this.padZero(num);
+          break;
+        case "day":
+          num = +this.syncDay + 1;
+          const maxDay = new Date(+this.syncYrs, +this.syncMonth, 0).getDate();
+          if (num > maxDay) {
+            num = 1;
+          }
+          this.syncDay = this.padZero(num);
+          break;
+        default:
+          break;
+      }
+    },
+    submitClock() {
+      if (this.syncType === "1") {
+        if (this.ntpServer === "" || this.ntpServer === "...") {
+          this.$notify({
+            type: "error",
+            message: "NTP 鏈嶅姟鍣ㄥ湴鍧�涓嶈兘涓虹┖",
+          });
+          return false;
+        } else if (this.timeInterval === "") {
+          this.timeInterval = 1;
+        }
+      } else if (this.isSyncBrowser) {
+        if (this.settime === "") {
+          this.$notify({
+            type: "error",
+            message: "璁剧疆鏃堕棿涓嶈兘涓虹┖",
+          });
+          return false;
+        }
+      } else {
+        this.settime = `${this.syncYrs}-${this.syncMonth}-${this.syncDay} ${this.syncHour}:${this.syncMin}:${this.syncSec}`;
+      }
+      saveClockInfo({
+        timeZone: this.timezone,
+        ntp: this.syncType === "1",
+        ntpServer: this.ntpServer,
+        interval: this.timeInterval,
+        newTime: this.settime,
+      }).then((rsp) => {
+        if (rsp && rsp.success) {
+          this.$notify({
+            type: "success",
+            message: "璁剧疆鎴愬姛",
+          });
+        }
+        this.initClockConf();
+      });
+    },
+    flatGetArr(arr, res) {
+      for (const item of arr) {
+        if (item.selected) res.push(item.id);
+        if (item.children) this.flatGetArr(item.children, res);
+      }
+    },
+    saveAuth() {
+      let arr = [];
+      this.flatGetArr(this.sysMenus, arr);
+      updataUser({
+        id: this.activeAccountItem.id,
+        menuIds: arr,
+      }).then((res) => {
+        if (res.success) {
+          this.$message.success(res.msg);
+          this.cancelSet();
+        }
+      });
+    },
+    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()));
+      this.weekday = "鏄熸湡" + "鏃ヤ竴浜屼笁鍥涗簲鍏�".charAt(date.getDay());
+      for (var i in returnArr) {
+        format = format.replace(formateArr[i], returnArr[i]);
+      }
+      return format;
+    },
+    padZero(n) {
+      n = +n;
+      return n < 10 ? "0" + n : "" + n;
+    },
+    formatNumber(n) {
+      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) {
+          this.timezone = rsp.data.time_zone;
+          if (!ntpTest) {
+            this.syncType = rsp.data.ntp ? "1" : "2";
+            this.isNtp = rsp.data.ntp;
+            this.isManual = !rsp.data.ntp;
+          }
+          if (rsp.data.ntp) {
+            this.ntpServer = rsp.data.ntp_server;
+            this.timeInterval = rsp.data.interval;
+          }
+          this.timestamp = rsp.data.local_time;
+          if (this.clockTimer === null) {
+            this.runClock();
+            if (this.isManual) this.parseTime();
+          }
+        }
+      });
+    },
+    openMenu(name, i) {
+      this.activePage = name;
+      this.activeIndex = i;
+      if (this.activePage == "鏃ユ湡鏃堕棿") {
+        this.initClockConf();
+      }
+    },
+    openWelcome(name,i){
+      this.showWelcome = false
+      this.openMenu(name,i)
+    },
+    showInput(typ) {
+      this[`show${typ}Input`] = true;
+      this.$nextTick(() => {
+        this.$refs[`ipt${typ}`].focus();
+      });
+    },
+    hideInput(typ) {
+      if (this[`input${typ}`]) {
+        this[`sync${typ}`] = this.padZero(this[`input${typ}`]);
+      }
+      this[`show${typ}Input`] = false;
+      this[`input${typ}`] = "";
+    },
+    syncBrowser(enable) {
+      this.isSyncBrowser = 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");
+          let [arr1, arr2] = this.settime.split(" ");
+          [this.syncYrs, this.syncMonth, this.syncDay] = arr1.split("-");
+          [this.syncHour, this.syncMin, this.syncSec] = arr2.split(":");
+        }, 1000);
+      }
+    },
+    showAddAccount() {
+      this.inAccountDetail = false;
+      this.isAddAccount = true;
+      getRoles().then((res) => {
+        if (res.success) {
+          this.roleList = res.data;
+        }
+      });
+    },
+    cancelAdd() {
+      this.inAccountDetail = false;
+      this.isAddAccount = false;
+      this.$refs["addForm"].resetFields();
+      this.selectedPic = null;
+    },
+    cancelPassword() {
+      this.isChangePw = false;
+      this.inAccountDetail = false;
+      this.$refs["passwordForm"].resetFields();
+    },
+    SaveNewPassword(formName) {
+      this.$refs[formName].validate((valid) => {
+        if (valid) {
+          updatePassword({
+            oldPwd: this.passwordForm.curPassword,
+            newPwd: this.passwordForm.newPassword,
+          }).then(
+            (res) => {
+              if (res.success) {
+                this.$message.success(res.msg);
+                this.cancelPassword();
+              }
+            },
+            (err) => {
+              this.$message.warning("淇濆瓨澶辫触锛�" + err.msg);
+            }
+          );
+        }
+      });
+    },
+    saveAddAccount(formName) {
+      this.$refs[formName].validate((valid) => {
+        if (valid) {
+          let data = {
+            username: this.addForm.userName,
+            password: this.addForm.password,
+            nickname: this.addForm.nickName,
+            headpic: this.addForm.headpic,
+          };
+          addUser(data).then(
+            (res) => {
+              this.$message.success(res.data);
+              this.fetchUserList(true);
+            },
+            (err) => {
+              this.$message.warning("淇濆瓨澶辫触锛�" + err.msg);
+            }
+          );
+        } else {
+          console.log("error submit!!");
+          return false;
+        }
+      });
+    },
+    pickHeadDefPic(item, i) {
+      this.addForm.headpic = item.path;
+      this.selectedPic = i;
+    },
+    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;
+        });
+    },
+    cancelSet() {
+      this.isSetPermission = false;
+      this.inAccountDetail = false;
+      this.sysMenus = [];
+    },
+    showChangePassword() {
+      this.isChangePw = true;
+      this.inAccountDetail = true;
+    },
+    runClock() {
+      const str = this.formatTime(++this.timestamp, "Y-M-D h:m:s");
+      [this.equipmentDate, this.equipmentTime] = str.split(" ");
+      this.clockTimer = setTimeout(() => {
+        this.runClock();
+      }, 1000);
+    },
+    deleteAccount() {
+      this.$confirm("鎮ㄦ槸鍚︾‘璁ゅ垹闄よ处鎴凤紵", "鍒犻櫎璐︽埛", {
+        confirmButtonText: "纭畾",
+        cancelButtonText: "鍙栨秷",
+      })
+        .then(() => {
+          let obj = {
+            ids: [this.activeAccountItem.id],
+          };
+          deleteUser(obj).then((res) => {
+            if (res.success) {
+              this.fetchUserList();
+              this.$message({
+                type: "success",
+                message: "鍒犻櫎鎴愬姛!",
+              });
+            } else {
+              this.$message.warning("鍒犻櫎澶辫触");
+            }
+          });
+        })
+        .catch(() => {});
+    },
+    fetchMenu() {
+      getUserMenus({
+        userId: this.activeAccountItem.id,
+      }).then((res) => {
+        if (res && res.success) {
+          this.sysMenus = res.data;
+        }
+      });
+    },
+    openPermission() {
+      this.inAccountDetail = true;
+      this.isSetPermission = true;
+      if (this.sysMenus.length == 0) {
+        this.fetchMenu();
+      }
+    },
+    parseTime() {
+      [this.syncYrs, this.syncMonth, this.syncDay] = this.equipmentDate.split(
+        "-"
+      );
+      [this.syncHour, this.syncMin, this.syncSec] = this.equipmentTime.split(
+        ":"
+      );
+    },
+    changeSwitch(str) {
+      if (str == "isNtp") {
+        this.isManual = !this[str];
+      } else {
+        this.isNtp = !this[str];
+      }
+      this.syncType = this.isNtp ? "1" : "2";
+      if (this.isManual) this.parseTime();
+    },
+  },
+  computed: {
+    isShowAddAccount() {
+      const info = JSON.parse(sessionStorage.getItem("userInfo"));
+      return true;
+    },
+  },
+};
+</script>
+<style lang="scss">
+.welcome-page {
+  width: 100%;
+  height: 100%;
+  background-color: #f5f5f5;
+  display: -ms-flexbox;
+  padding: 0 50px;
+  -webkit-box-sizing: border-box;
+  box-sizing: border-box;
+  .child {
+    box-sizing: border-box;
+    background-color: white;
+    -webkit-box-flex: 0;
+    -ms-flex: 0 0 33.3%;
+    /* flex: 0 0 16%; */
+    float: left;
+    width: 250px;
+    height: 200px;
+    margin: 50px 57px 30px 57px;
+    border-radius: 20px;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    cursor: pointer;
+    .child-info {
+      display: flex;
+      flex-direction: column;
+      height: 62%;
+      justify-content: space-around;
+      .welcome-icon {
+        font-size: 72px;
+      }
+      .welcome-title {
+        font-size: 18px;
+      }
+    }
+  }
+  .child:hover {
+    -moz-box-shadow: 5px 5px 10px #ddd;
+    -webkit-box-shadow: 5px 5px 10px #ddd;
+    box-shadow: 5px 5px 10px #ddd;
+    transform: translate3d(0,-2.5px,0);
+     transition: all 0.3s;
+}
+}
+.container {
+  height: 100%;
+  display: flex;
+  flex-direction: row;
+  flex: 1;
+  flex-basis: auto;
+  box-sizing: border-box;
+  .container-left {
+    height: 100%;
+     width: 230px;
+    overflow: auto;
+    box-sizing: border-box;
+    flex-shrink: 0;
+    padding: 10px;
+    border-right: 5px solid rgba(248, 248, 248, 1);
+    box-sizing: border-box;
+    .left-card {
+      height: 55px;
+      cursor: pointer;
+      border-radius: 12px;
+      margin-bottom: 10px;
+      display: flex;
+      align-items: center;
+      .iconfont {
+        margin-left: 25px;
+        margin-right: 10px;
+        font-size: 24px;
+      }
+      .card-text {
+        font-size: 16px;
+      }
+    }
+    .left-card-active {
+      background-color: rgba(61, 104, 225, 1);
+      color: #fff;
+    }
+    .left-card:hover {
+      background-color: rgba(61, 104, 225, 1);
+      color: #fff;
+    }
+  }
+  .container-center {
+    height: 100%;
+    width: 280px;
+    overflow: auto;
+    flex-shrink: 0;
+    padding: 10px;
+    border-right: 5px solid rgba(248, 248, 248, 1);
+    box-sizing: border-box;
+    .account-left {
+      .add-account {
+        color: rgba(61, 104, 225, 1);
+        margin-top: 30px;
+        .iconfont {
+          cursor: pointer;
+          font-size: 32px;
+        }
+      }
+      .account-card {
+        height: 50px;
+        background-color: rgba(248, 248, 248, 1);
+        margin-bottom: 10px;
+        display: flex;
+        align-items: center;
+        padding: 0 20px;
+        box-sizing: border-box;
+        border-radius: 10px;
+        cursor: pointer;
+        .touxiang {
+          height: 35px;
+          width: 35px;
+          background-color: bisque;
+          border-radius: 17.5px;
+          img {
+            border: none;
+
+            height: 35px;
+            width: 35px;
+            border-radius: 17.5px;
+          }
+        }
+        .user-name {
+          margin-left: 10px;
+          font-size: 14px;
+        }
+      }
+
+      .account-card-active {
+        background-color: rgba(61, 104, 225, 1);
+        color: #fff;
+      }
+    }
+    .datetime-left {
+      .time-card {
+        height: 105px;
+        background-color: rgba(248, 248, 248, 1);
+        margin-bottom: 30px;
+        border-radius: 10px;
+        .head {
+          height: 30px;
+          line-height: 30px;
+          text-align: left;
+          box-sizing: border-box;
+          padding: 0 10px;
+          font-size: 14px;
+          .icon {
+            margin-right: 5px;
+            color: rgba(61, 104, 225, 1);
+          }
+        }
+        .time-main {
+          height: 42px;
+          line-height: 42px;
+          font-family: Consolas;
+          font-size: 36px;
+        }
+        .date-bot {
+          height: 25px;
+          font-size: 14px;
+          line-height: 25px;
+          color: #868686;
+          display: flex;
+          justify-content: space-evenly;
+        }
+      }
+      .line {
+        display: flex;
+        align-items: center;
+        height: 50px;
+        padding: 0 25px;
+        background-color: rgba(248, 248, 248, 1);
+        justify-content: space-between;
+        border-radius: 12px;
+        margin-bottom: 10px;
+        .name {
+          font-size: 14px;
+        }
+      }
+    }
+  }
+  .container-right {
+    flex: 1;
+    flex-basis: auto;
+    overflow: auto;
+    box-sizing: border-box;
+    position: relative;
+
+    padding: 20px 40px;
+    .account-right {
+      .account-content {
+        .content-top {
+          height: 120px;
+          width: 350px;
+          margin: 0 auto;
+          display: flex;
+          align-items: center;
+          justify-content: center;
+          margin-bottom: 20px;
+          .touxiang-big {
+            width: 100px;
+            height: 100px;
+            background-color: bisque;
+            border-radius: 50px;
+            img {
+              border: none;
+
+              width: 100px;
+              height: 100px;
+              border-radius: 50px;
+            }
+          }
+          .user-desc {
+            height: 100px;
+            display: flex;
+            flex-direction: column;
+            align-items: baseline;
+            min-width: 200px;
+            .username {
+              margin: 5px 15px;
+              height: 30px;
+              line-height: 30px;
+              // width: 90px;
+              text-align: left;
+              font-size: 15px;
+              display: flex;
+              align-items: center;
+            }
+            .nickname {
+              margin: 5px 15px;
+              font-size: 14px;
+              .input-nick {
+                width: 50px;
+                margin-right: 5px;
+              }
+              .iconfont {
+                font-size: 14px;
+                margin-left: 5px;
+                cursor: pointer;
+              }
+            }
+            .user-role {
+              margin: 5px 0 0 15px;
+              font-size: 14px;
+              color: darkseagreen;
+            }
+          }
+        }
+        .list-btn {
+          display: flex;
+
+          flex-direction: column;
+          align-items: center;
+          .item-btn {
+            width: 500px;
+            height: 45px;
+            background-color: #f0f0f0;
+            margin-bottom: 15px;
+            border-radius: 10px;
+            line-height: 45px;
+            font-size: 15px;
+            cursor: pointer;
+          }
+          .item-btn:hover {
+            color: rgba(255, 153, 102, 1);
+          }
+        }
+      }
+      .title {
+        height: 30px;
+        line-height: 30px;
+        /* background-color: aliceblue; */
+        margin-bottom: 10px;
+        font-size: 16px;
+        font-weight: 600;
+      }
+      .change-pw {
+        .p-title {
+          text-align: left;
+          font-size: 15px;
+          margin-top: 5px;
+        }
+      }
+      .el-form-item {
+        margin-bottom: 0;
+        .el-input__inner {
+          background-color: rgba(240, 240, 240, 1);
+          border: none;
+          border-radius: 12px;
+          height: 45px;
+          padding: 0 20px;
+          font-size: 15px;
+        }
+        .el-input__clear {
+          color: dimgray;
+          font-size: 17px;
+          line-height: 45px;
+        }
+        .el-input__suffix {
+          right: 1px;
+          top: -0.5px;
+          width: 45px;
+          // background-color: rgba(61, 104, 225, 1);
+          /* color: white; */
+          border-radius: 12px;
+        }
+      }
+      .permission {
+        .line {
+          display: flex;
+          align-items: center;
+          height: 50px;
+          padding: 0 25px;
+          background-color: rgba(248, 248, 248, 1);
+          justify-content: space-between;
+          border-radius: 12px;
+          margin-bottom: 10px;
+          .name {
+            font-size: 14px;
+          }
+        }
+      }
+
+      .add-account-page {
+        .upload-group {
+          height: 120px;
+          width: 360px;
+          margin: 0 auto;
+          overflow: hidden;
+          .upload-jpg {
+            position: relative;
+            height: 48px;
+            width: 48px;
+            float: left;
+            margin: 0 10px;
+            margin-bottom: 10px;
+            background-color: rgba(242, 242, 242, 1);
+            border: 2px solid transparent;
+            border-radius: 50%;
+            cursor: pointer;
+            img {
+              height: 48px;
+              width: 48px;
+              border-radius: 50%;
+            }
+            .img-mask {
+              position: absolute;
+              left: 0;
+              top: 0;
+              height: 48px;
+              width: 48px;
+              background-color: rgba(0, 0, 0, 0.3);
+              color: white;
+              border-radius: 50%;
+              display: flex;
+              justify-content: center;
+              align-items: center;
+              .selected {
+                font-size: 22px;
+              }
+            }
+          }
+          .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;
+          }
+        }
+        .fill-group {
+          .p-title {
+            height: 34px;
+            text-align: left;
+          }
+          .el-form-item {
+            .el-select {
+              width: 100%;
+            }
+          }
+        }
+      }
+    }
+    .datetime-right {
+      .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;
+      }
+      .el-form-item {
+        margin-bottom: 10px;
+        height: 50px;
+        background: #f8f8f8;
+        padding: 4px 20px;
+        -webkit-box-sizing: border-box;
+        box-sizing: border-box;
+        border-radius: 10px;
+        .el-form-item__label {
+          text-align: left;
+          line-height: 42px;
+        }
+      }
+      .el-form-item__content {
+        line-height: 40px;
+        position: relative;
+        font-size: 14px;
+        margin-bottom: 10px;
+      }
+      .ip-input-container {
+        max-width: none !important;
+      }
+      .ntp-time {
+        .right {
+          display: flex;
+          align-items: baseline;
+          .el-input-number--small {
+            width: 100%;
+          }
+          .el-button--text {
+            margin-left: 10px;
+            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 {
+          height: 75px;
+
+          background-color: #f8f8f8;
+          display: flex;
+          justify-content: center;
+          align-items: center;
+          margin-bottom: 10px;
+          border-radius: 10px;
+          .clock {
+            display: flex;
+            align-items: center;
+            height: 90px;
+            justify-content: space-evenly;
+            .iconfont {
+              cursor: pointer;
+              color: rgba(134, 134, 134, 1);
+            }
+            .iconfont:hover {
+              background-color: gainsboro;
+            }
+            .hour {
+              background-color: rgba(240, 240, 240, 1);
+              display: flex;
+              align-items: center;
+              width: 100px;
+              height: 50px;
+              justify-content: space-evenly;
+              border-radius: 10px;
+            }
+            .dnum {
+              width: 40px;
+              height: 40px;
+              line-height: 40px;
+              font-size: 34px;
+              font-family: Consolas;
+              display: flex;
+              align-items: center;
+              .input-box {
+                width: inherit;
+                border: none;
+                border-radius: 5px;
+                height: 35px;
+                font-size: 28px;
+                text-align: center;
+              }
+
+              .input-box:focus {
+                outline: none;
+              }
+            }
+            .control {
+              width: 20px;
+              .fanzhuan {
+                display: inline-block;
+                -moz-transform: scaleY(-1);
+                -webkit-transform: scaleY(-1);
+                -o-transform: scaleY(-1);
+                transform: scaleY(-1);
+              }
+            }
+            .sep {
+              font-family: Consolas;
+              width: 40px;
+              font-size: 34px;
+              height: 40px;
+              line-height: 40px;
+            }
+            .mins {
+              background-color: #f0f0f0;
+              display: flex;
+              align-items: center;
+              width: 110px;
+              height: 50px;
+              justify-content: space-evenly;
+              border-radius: 10px;
+            }
+          }
+        }
+        .adjust-bar {
+          display: flex;
+          justify-content: space-between;
+          align-items: center;
+          margin-bottom: 10px;
+          border-radius: 10px;
+          height: 50px;
+          background-color: rgba(248, 248, 248, 1);
+          .middle {
+            font-size: 14px;
+          }
+          .input-box {
+            width: 80px;
+            border: none;
+            border-radius: 5px;
+            height: 25px;
+            font-size: 18px;
+            text-align: center;
+          }
+
+          .input-box:focus {
+            outline: none;
+          }
+          .minus {
+            width: 50px;
+            height: 50px;
+            background-color: #f0f0f0;
+            font-size: 35px;
+            border-radius: 10px;
+            cursor: pointer;
+            line-height: 50px;
+            color: rgba(134, 134, 134, 1);
+          }
+          .plus {
+            width: 50px;
+            height: 50px;
+            cursor: pointer;
+            background-color: #f0f0f0;
+            font-size: 35px;
+            border-radius: 10px;
+            line-height: 50px;
+            color: rgba(134, 134, 134, 1);
+          }
+        }
+      }
+    }
+    .btns {
+      display: flex;
+      justify-content: space-between;
+      margin-top: 20px;
+
+      .cancel {
+        height: 40px;
+        width: 48%;
+        cursor: pointer;
+        border-radius: 8px;
+        background-color: rgba(240, 240, 240, 1);
+        line-height: 40px;
+        font-size: 14px;
+      }
+      .ok {
+        height: 40px;
+        width: 48%;
+        cursor: pointer;
+        border-radius: 8px;
+        background-color: rgba(61, 104, 225, 1);
+        color: #fff;
+        line-height: 40px;
+        font-size: 14px;
+      }
+    }
+  }
+}
+</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)
+})
diff --git a/src/pages/settings/views/NetSettings.vue b/src/pages/systemSettings/views/NetSettings.vue
similarity index 100%
rename from src/pages/settings/views/NetSettings.vue
rename to src/pages/systemSettings/views/NetSettings.vue
diff --git a/src/pages/settings/views/clusterManagement.vue b/src/pages/systemSettings/views/clusterManagement.vue
similarity index 100%
rename from src/pages/settings/views/clusterManagement.vue
rename to src/pages/systemSettings/views/clusterManagement.vue
diff --git a/src/pages/settings/views/generalSettings.vue b/src/pages/systemSettings/views/generalSettings.vue
similarity index 100%
rename from src/pages/settings/views/generalSettings.vue
rename to src/pages/systemSettings/views/generalSettings.vue
diff --git a/src/pages/settings/views/keyboardLanguage.vue b/src/pages/systemSettings/views/keyboardLanguage.vue
similarity index 100%
rename from src/pages/settings/views/keyboardLanguage.vue
rename to src/pages/systemSettings/views/keyboardLanguage.vue

--
Gitblit v1.8.0