From af030fcce7f397eed1ec263139a5f7c03a8cf142 Mon Sep 17 00:00:00 2001
From: heyujie <516346543@qq.com>
Date: 星期四, 31 三月 2022 10:33:44 +0800
Subject: [PATCH] 修改登陆url

---
 src/api/login.js                                       |   26 
 src/views/personalCenter/components/Content.vue        |   94 +
 src/views/personalCenter/components/BasicInfo.vue      |  490 ++++++++
 src/components/IndexHeader.vue                         |    5 
 src/views/personalCenter/components/AddBox.vue         |  598 +++++++++
 src/router/index.js                                    |    8 
 src/views/personalCenter/components/Steps.vue          |  109 +
 src/views/personalCenter/index.vue                     |   49 
 src/views/personalCenter/components/SubAccount.vue     |  887 ++++++++++++++
 src/views/personalCenter/components/TreeBox.vue        |   49 
 src/views/personalCenter/components/LeftMenu.vue       |   94 +
 src/api/index.js                                       |    3 
 src/views/personalCenter/components/StepCard.vue       |  339 +++++
 src/views/personalCenter/components/InfoCard.vue       |  311 +++++
 src/views/personalCenter/components/QuitClusterBox.vue |  145 ++
 src/views/personalCenter/components/JoinClusterBox.vue |  367 ++++++
 16 files changed, 3,557 insertions(+), 17 deletions(-)

diff --git a/src/api/index.js b/src/api/index.js
index 4624103..6d59988 100644
--- a/src/api/index.js
+++ b/src/api/index.js
@@ -185,9 +185,6 @@
         message: "杩炴帴鏈嶅姟鍣ㄥけ璐�!",
         type: "error",
       });
-      // router.push({
-      //   path: '/login'
-      // });
     }
     // 杩斿洖 response 閲岀殑閿欒淇℃伅
     return Promise.reject(errJson);
diff --git a/src/api/login.js b/src/api/login.js
index 25eeec6..819ac5a 100644
--- a/src/api/login.js
+++ b/src/api/login.js
@@ -5,7 +5,7 @@
 export const tologin = (query) => {
   // let query = 'username=' + user.loginName + '&password=' + user.password
   return request({
-    url: "/data/api-u/user/login",
+    url: "/saas/api-u/user/login",
     method: "post",
     data: qs.stringify(query),
   });
@@ -15,7 +15,7 @@
 export const logout = () => {
   // let token = sessionStorage.getItem('loginedInfo') && JSON.parse(sessionStorage.getItem('loginedInfo')).access_token
   return request({
-    url: "/data/api-u/user/logout",
+    url: "/saas/api-u/user/logout",
     method: "post",
   });
 };
@@ -23,7 +23,7 @@
 // 鑾峰彇楠岃瘉鐮�
 export const getVerifyCode = (query) => {
   return request({
-    url: "/data/api-u/user/makeVerifyCode",
+    url: "/saas/api-u/user/makeVerifyCode",
     method: "get",
     params: query,
   });
@@ -35,7 +35,7 @@
     sessionStorage.getItem("loginedInfo") &&
     JSON.parse(sessionStorage.getItem("loginedInfo")).access_token;
   return request({
-    url: "/data/api-u/users/current",
+    url: "/saas/api-u/users/current",
     method: "get",
     headers: {
       "Content-Type": "application/x-www-form-urlencoded",
@@ -47,7 +47,7 @@
 //淇敼瀵嗙爜
 export const updatePwd = (query) => {
   return request({
-    url: "/data/api-u/user/updatePwd",
+    url: "/saas/api-u/user/updatePwd",
     method: "post",
     data: qs.stringify(query),
   });
@@ -56,7 +56,7 @@
 // 閲嶇疆瀵嗙爜
 export const forgetPwd = (query) => {
   return request({
-    url: "/data/api-u/user/forgetPwd",
+    url: "/saas/api-u/user/forgetPwd",
     method: "post",
     data: qs.stringify(query),
   });
@@ -65,7 +65,7 @@
 // 娉ㄥ唽
 export const register = (query) => {
   return request({
-    url: "/data/api-u/user/register",
+    url: "/saas/api-u/user/register",
     method: "post",
     data: query,
   });
@@ -74,7 +74,7 @@
 // 楠岃瘉鎵嬫満楠岃瘉鐮�
 export const verifyPh = (query) => {
   return request({
-    url: "/data/api-u/user/verifyCode",
+    url: "/saas/api-u/user/verifyCode",
     method: "post",
     data: qs.stringify(query),
   });
@@ -83,7 +83,7 @@
 // 鑾峰彇瀛楀吀
 export const getDic = (query) => {
   return request({
-    url: "/data/api-u/dic/findDicByType",
+    url: "/saas/api-u/dic/findDicByType",
     method: "get",
     params: query,
   });
@@ -92,7 +92,7 @@
 // 鑾峰彇琛屾斂鍖哄煙
 export const getAreas = (query) => {
   return request({
-    url: "/data/api-u/area/findAreaByParentId",
+    url: "/saas/api-u/area/findAreaByParentId",
     method: "get",
     params: query,
   });
@@ -101,7 +101,7 @@
 // 瀹屽杽鐢ㄦ埛淇℃伅
 export const entireUserInfo = (query) => {
   return request({
-    url: "/data/api-u/user/entireUserInfo",
+    url: "/saas/api-u/user/entireUserInfo",
     method: "post",
     data: query,
   });
@@ -110,7 +110,7 @@
 // 鑾峰彇鐢ㄦ埛淇℃伅
 export const getUserInfo = () => {
   return request({
-    url: "/data/api-u/user/getUserInfo",
+    url: "/saas/api-u/user/getUserInfo",
     method: "get",
   });
 };
@@ -120,7 +120,7 @@
 // verifyCode   string
 export const updatePhoneNum = (query) => {
   return request({
-    url: "/data/api-u/user/updatePhoneNum",
+    url: "/saas/api-u/user/updatePhoneNum",
     method: "post",
     data: qs.stringify(query),
   });
diff --git a/src/components/IndexHeader.vue b/src/components/IndexHeader.vue
index 8abf868..60089bc 100644
--- a/src/components/IndexHeader.vue
+++ b/src/components/IndexHeader.vue
@@ -67,7 +67,10 @@
         </li>
 
         <li class="personal">
-          <div class="label">涓汉涓績</div>
+          <div class="label">
+            <router-link to="/personalCenter">涓汉涓績</router-link>
+          </div>
+
           <div class="content">
             <span class="iconfont">&#xe605;</span> 宸插疄鍚嶈璇�
           </div>
diff --git a/src/router/index.js b/src/router/index.js
index bd5654f..0e9c6a3 100644
--- a/src/router/index.js
+++ b/src/router/index.js
@@ -42,6 +42,14 @@
       ),
   },
   {
+    path: "/personalCenter",
+    name: "personalCenter",
+    component: () =>
+      import(
+        /* webpackChunkName: "about" */ "../views/personalCenter"
+      ),
+  },
+  {
     path: "/equipmentDetail",
     name: "equipmentDetail",
     component: () =>
diff --git a/src/views/personalCenter/components/AddBox.vue b/src/views/personalCenter/components/AddBox.vue
new file mode 100644
index 0000000..86a3bdb
--- /dev/null
+++ b/src/views/personalCenter/components/AddBox.vue
@@ -0,0 +1,598 @@
+<template>
+  <div class="addBox">
+    <div class="title">鍔犲叆闆嗙兢</div>
+
+    <div class="close iconfont" @click="close()">&#xe60f;</div>
+
+    <div class="search">
+      <el-input
+        v-model="searchContent"
+        placeholder="璇疯緭鍏ラ泦缇P/闆嗙兢鍚嶇О/璁惧IP/璁惧鍚嶇О"
+      ></el-input>
+      <div class="button" @click="listType = 'cluster'">鎼滅储闆嗙兢</div>
+      <div class="button" @click="listType = 'equipment'">鎼滅储璁惧</div>
+    </div>
+
+    <div class="clusterList">
+      <div class="tableList" v-if="listType == 'cluster'">
+        <div class="header">
+          <div
+            class="label"
+            v-for="(item, index) in clusterHeader"
+            :key="index"
+          >
+            {{ item }}
+          </div>
+        </div>
+        <div class="body" v-if="listType == 'cluster'">
+          <div class="row" v-for="(item, index) in clusterList" :key="index">
+            <div class="content">
+              <div class="rowItem index">{{ index + 1 }}</div>
+              <div class="rowItem name">{{ item.name }}</div>
+              <div class="rowItem ip">{{ item.ip }}</div>
+              <div class="rowItem status">
+                <div v-if="item.status == 1" class="status green">宸叉坊鍔�</div>
+                <div v-else class="status">鏈坊鍔�</div>
+              </div>
+              <div class="rowItem options">
+                <!-- 娣诲姞 -->
+                <span class="iconfont option" @click="showPasswordBox = true"
+                  >&#xe63f;</span
+                >
+                <!-- 闆嗙兢璇︽儏  -->
+                <span class="iconfont option" @click="showChildrenLIst(index)"
+                  >&#xe63e;</span
+                >
+              </div>
+            </div>
+
+            <div
+              class="overList"
+              :class="{ isShow: showClusterChild == index }"
+            >
+              <el-table
+                :data="overList"
+                :fit="true"
+                header-row-class-name="overList-head"
+              >
+                <el-table-column
+                  label="搴忓彿"
+                  type="index"
+                  width="146"
+                  class-name="index "
+                >
+                </el-table-column>
+                <el-table-column
+                  prop="id"
+                  label="璁惧ID"
+                  width="146"
+                ></el-table-column>
+
+                <el-table-column
+                  prop="ip"
+                  label="璁惧IP"
+                  width="146"
+                ></el-table-column>
+
+                <el-table-column
+                  prop="name"
+                  label="璁惧鍚嶇О"
+                  width="240"
+                ></el-table-column>
+              </el-table>
+
+              <div class="iconfont" @click="showClusterChild = null">
+                &#xe63d;
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+
+      <el-table
+        :data="equipmentList"
+        :fit="true"
+        v-if="listType == 'equipment'"
+      >
+        <el-table-column
+          label="搴忓彿"
+          type="index"
+          width="72"
+          class-name="index"
+        >
+        </el-table-column>
+        <el-table-column prop="id" label="璁惧ID" width="107"></el-table-column>
+        <el-table-column
+          prop="name"
+          label="璁惧鍚嶇О"
+          width="107"
+        ></el-table-column>
+        <el-table-column prop="ip" label="璁惧IP" width="107"></el-table-column>
+        <el-table-column
+          prop="cluster"
+          label="鎵�灞為泦缇�"
+          width="107"
+        ></el-table-column>
+        <el-table-column label="鐘舵��" width="107">
+          <template slot-scope="scope">
+            <div v-if="scope.row.status == 1" class="status green">宸叉坊鍔�</div>
+            <div v-else class="status">鏈坊鍔�</div>
+          </template>
+        </el-table-column>
+
+        <el-table-column label="鎿嶄綔" width="72">
+          <template slot-scope="scope">
+            <div class="options" v-if="scope">
+              <!-- 娣诲姞 -->
+              <span class="iconfont option" @click="showPasswordBox = true"
+                >&#xe63f;</span
+              >
+            </div>
+          </template>
+        </el-table-column>
+      </el-table>
+    </div>
+
+    <div class="passwordBox" v-if="showPasswordBox">
+      <div class="title">鐢宠娣诲姞璁惧</div>
+      <div class="des">
+        <span class="iconfont">&#xe601;</span>
+        濡傝澶囧凡鍔犲叆闆嗙兢锛屾坊鍔犵鐞嗗悗闆嗙兢涓嬫墍鏈夎澶囧皢鍦ㄨ澶囩鐞�
+        椤甸潰鏄剧ず锛屽苟鏀寔淇℃伅鏌ョ湅鍙婄鐞嗐��
+      </div>
+      <div class="ask">瀵嗛挜淇℃伅璇疯闂澶囩鐞嗕汉鍛�</div>
+      <el-input v-model="auth_password"></el-input>
+      <div class="btns">
+        <div class="cancel button" @click="showPasswordBox = false">鍙栨秷</div>
+        <div class="submit button" @click="showPasswordBox = false">鎻愪氦</div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      listType: null, //灞曠ず鐨勫垪琛ㄧ被鍨�
+      searchContent: "", //鎼滅储鍐呭
+      showClusterChild: null, //灞曠ず闆嗙兢鍒楄〃涓嬫媺鍒楄〃
+      clusterHeader: ["搴忓彿", "闆嗙兢鍚嶇О", "IP鍦板潃", "鐘舵��", "鎿嶄綔"], //闆嗙兢鍒楄〃琛ㄥご
+      showPasswordBox: false,
+      clusterList: [
+        {
+          name: "闆嗙兢1",
+          ip: "192.168.7.45",
+          status: "1",
+        },
+        {
+          name: "闆嗙兢1",
+          ip: "192.168.7.45",
+          status: "1",
+        },
+        {
+          name: "闆嗙兢1",
+          ip: "192.168.7.45",
+          status: "0",
+        },
+        {
+          name: "闆嗙兢1",
+          ip: "192.168.7.45",
+          status: "0",
+        },
+      ],
+      equipmentList: [
+        {
+          id: "BJS23123132",
+          name: "鏈嶅姟鍣�20.10",
+          ip: "192.168.7.45",
+          cluster: "闆嗙兢1",
+          status: "1",
+        },
+        {
+          id: "BJS23123132",
+          name: "鏈嶅姟鍣�20.10",
+          ip: "192.168.7.45",
+          cluster: "闆嗙兢1",
+          status: "1",
+        },
+        {
+          id: "BJS23123132",
+          name: "鏈嶅姟鍣�20.10",
+          ip: "192.168.7.45",
+          cluster: "闆嗙兢1",
+          status: "1",
+        },
+        {
+          id: "BJS23123132",
+          name: "鏈嶅姟鍣�20.10",
+          ip: "192.168.7.45",
+          cluster: "闆嗙兢1",
+          status: "1",
+        },
+        {
+          id: "BJS23123132",
+          name: "鏈嶅姟鍣�20.10",
+          ip: "192.168.7.45",
+          cluster: "闆嗙兢1",
+          status: "1",
+        },
+        {
+          id: "BJS23123132",
+          name: "鏈嶅姟鍣�20.10",
+          ip: "192.168.7.45",
+          cluster: "闆嗙兢1",
+          status: "1",
+        },
+        {
+          id: "BJS23123132",
+          name: "鏈嶅姟鍣�20.10",
+          ip: "192.168.7.45",
+          cluster: "闆嗙兢1",
+          status: "1",
+        },
+        {
+          id: "BJS23123132",
+          name: "鏈嶅姟鍣�20.10",
+          ip: "192.168.7.45",
+          cluster: "闆嗙兢1",
+          status: "1",
+        },
+        {
+          id: "BJS23123132",
+          name: "鏈嶅姟鍣�20.10",
+          ip: "192.168.7.45",
+          cluster: "闆嗙兢1",
+          status: "1",
+        },
+      ],
+      overList: [
+        {
+          id: "BJS23123132",
+          name: "鏈嶅姟鍣�20.10",
+          ip: "192.168.7.45",
+          cluster: "闆嗙兢1",
+          status: "1",
+        },
+        {
+          id: "BJS23123132",
+          name: "鏈嶅姟鍣�20.10",
+          ip: "192.168.7.45",
+          cluster: "闆嗙兢1",
+          status: "1",
+        },
+        {
+          id: "BJS23123132",
+          name: "鏈嶅姟鍣�20.10",
+          ip: "192.168.7.45",
+          cluster: "闆嗙兢1",
+          status: "1",
+        },
+        {
+          id: "BJS23123132",
+          name: "鏈嶅姟鍣�20.10",
+          ip: "192.168.7.45",
+          cluster: "闆嗙兢1",
+          status: "1",
+        },
+      ],
+      auth_password: "", //鎺堟潈绉橀挜
+    };
+  },
+  methods: {
+    close() {
+      this.$emit("close");
+    },
+    showChildrenLIst(index) {
+      if (this.showClusterChild === index) {
+        this.showClusterChild = null;
+        return;
+      } else if (!index) {
+        this.showClusterChild = index;
+      }
+      this.showClusterChild = null;
+      setTimeout(() => {
+        this.showClusterChild = index;
+      }, 400);
+    },
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+.addBox {
+  position: relative;
+  box-sizing: border-box;
+  padding: 20px;
+  position: fixed;
+  width: 720px;
+  top: 50%;
+  left: 50%;
+  margin-top: -317px;
+  margin-left: -360px;
+  filter: drop-shadow(0px 2px 16px rgba(0, 43, 106, 0.25));
+  z-index: 999;
+  background-color: #fff;
+
+  .title {
+    padding-bottom: 20px;
+    font-size: 18px;
+    font-weight: 700;
+    border-bottom: 1px solid #e9ebee;
+  }
+
+  .search {
+    display: flex;
+    margin: 20px 0;
+
+    .el-input ::v-deep {
+      width: 324px;
+      height: 32px;
+      .el-input__inner {
+        padding: 0 10px;
+        width: 324px;
+        height: 32px;
+        color: #3d3d3d;
+        border-radius: 0;
+        border-color: #c0c5cc;
+        &::-webkit-input-placeholder {
+          color: #999999;
+        }
+
+        &:focus {
+          border-color: #0065ff;
+        }
+      }
+    }
+
+    .button {
+      margin-left: 10px;
+      width: 88px;
+      height: 32px;
+      line-height: 32px;
+      background-color: #0065ff;
+      text-align: center;
+      color: #fff;
+      font-size: 14px;
+    }
+  }
+
+  .clusterList {
+    max-height: 507px;
+    overflow-y: overlay;
+  }
+
+  .tableList {
+    overflow-y: overlay;
+    max-height: 507px;
+    box-sizing: border-box;
+    border: 1px solid rgb(233, 235, 238);
+    border-bottom: none;
+
+    .header {
+      display: flex;
+      background: #f0f3f5;
+      font-size: 16px;
+      font-weight: 700;
+
+      .label {
+        padding-left: 10px;
+        width: 146px;
+        height: 50px;
+        line-height: 50px;
+
+        &:first-child {
+          padding-left: 20px;
+          width: 96px;
+        }
+      }
+    }
+
+    .content {
+      display: flex;
+      border-bottom: 1px solid #e9ebee;
+      font-size: 14px;
+
+      .rowItem {
+        padding-left: 10px;
+        width: 146px;
+        height: 48px;
+        line-height: 48px;
+      }
+
+      .index {
+        padding-left: 20px;
+        width: 96px;
+      }
+
+      .status {
+        color: #ff6a00;
+
+        &.green {
+          color: #36b24a;
+        }
+      }
+
+      .option {
+        margin-right: 10px;
+        font-size: 24px;
+        color: rgb(0, 101, 255);
+        cursor: pointer;
+      }
+
+      .options {
+        position: relative;
+        .childForm {
+          top: 0;
+          left: 0;
+          position: absolute;
+        }
+      }
+    }
+
+    .overList {
+      overflow: hidden;
+      max-height: 0;
+      position: relative;
+      transition: 0.4s all linear;
+
+      .iconfont {
+        position: absolute;
+        right: 52px;
+        top: 13px;
+        font-size: 24px;
+        color: rgb(0, 101, 255);
+        cursor: pointer;
+      }
+
+      &.isShow {
+        max-height: 500px;
+      }
+    }
+  }
+
+  .el-table ::v-deep {
+    background-color: rgb(233, 235, 238);
+    padding: 1px;
+
+    &::after {
+      display: none;
+    }
+
+    td.index .cell {
+      padding-left: 16px;
+      padding-right: 4px;
+    }
+
+    .has-gutter tr th {
+      background: #f0f3f5;
+      font-size: 16px;
+      color: #3d3d3d;
+      font-weight: 700;
+    }
+
+    td .cell {
+      color: #3d3d3d;
+    }
+
+    tr:hover > td.el-table__cell {
+      background-color: #fff;
+    }
+
+    .el-table__row--striped .el-table__cell {
+      background-color: #f0f5fa !important;
+    }
+    tr:hover > td.el-table__cell {
+      background-color: #fff;
+    }
+
+    .el-table__row--striped .el-table__cell {
+      background-color: #f0f5fa !important;
+    }
+
+    .status {
+      color: #ff6a00;
+
+      &.green {
+        color: #36b24a;
+      }
+    }
+
+    .option {
+      margin-right: 10px;
+      font-size: 24px;
+      color: rgb(0, 101, 255);
+      cursor: pointer;
+    }
+
+    .options {
+      position: relative;
+      .childForm {
+        top: 0;
+        left: 0;
+        position: absolute;
+      }
+    }
+  }
+
+  .close {
+    position: absolute;
+    top: 20px;
+    right: 20px;
+    font-size: 12px;
+    color: #666;
+    cursor: pointer;
+  }
+
+  .passwordBox {
+    box-sizing: border-box;
+    position: absolute;
+    padding: 20px;
+    top: 40px;
+    left: 50%;
+    margin-left: -220px;
+    width: 440px;
+    height: 302px;
+    filter: drop-shadow(0px 2px 16px rgba(0, 43, 106, 0.25));
+    background-color: #fff;
+    font-size: 14px;
+
+    .des {
+      margin: 20px 0;
+      display: flex;
+      color: #0065ff;
+      span {
+        margin-top: 3px;
+        margin-right: 10px;
+        font-size: 16px;
+      }
+    }
+
+    .ask {
+      margin-bottom: 10px;
+    }
+
+    .el-input ::v-deep {
+      .el-input__inner {
+        padding: 0 10px;
+        color: #3d3d3d;
+        border-radius: 0;
+        border-color: #c0c5cc;
+        &::-webkit-input-placeholder {
+          color: #999999;
+        }
+
+        &:focus {
+          border-color: #0065ff;
+        }
+      }
+    }
+
+    .btns {
+      margin-top: 40px;
+      display: flex;
+      justify-content: end;
+      text-align: center;
+      line-height: 32px;
+      font-size: 14px;
+
+      .cancel {
+        margin-right: 10px;
+        width: 60px;
+        height: 32px;
+        border: 1px solid #0065ff;
+        color: #0065ff;
+      }
+
+      .submit {
+        width: 60px;
+
+        height: 32px;
+        color: #fff;
+        background-color: #0065ff;
+        border: 1px solid #0065ff;
+      }
+    }
+  }
+}
+</style>
\ No newline at end of file
diff --git a/src/views/personalCenter/components/BasicInfo.vue b/src/views/personalCenter/components/BasicInfo.vue
new file mode 100644
index 0000000..93abbae
--- /dev/null
+++ b/src/views/personalCenter/components/BasicInfo.vue
@@ -0,0 +1,490 @@
+<template>
+  <div class="basic-info">
+    <div class="head-name">瀛愯处鎴风鐞�</div>
+
+    <el-form
+      :model="ruleForm"
+      :rules="rules"
+      :label-position="'left'"
+      ref="ruleForm"
+      label-width="90px"
+      class="add-ruleForm"
+    >
+      <div class="area-title">鍩烘湰淇℃伅</div>
+      <el-form-item label="鐢ㄦ埛鍚�" prop="name">
+        <el-input v-model="ruleForm.name" style="width: 200px"></el-input>
+      </el-form-item>
+      <el-form-item label="娉ㄥ唽绫诲瀷" prop="type">
+        <el-radio v-model="ruleForm.type" label="1">涓汉</el-radio>
+        <el-radio v-model="ruleForm.type" label="2">鍏徃</el-radio>
+      </el-form-item>
+
+      <el-form-item label="濮撳悕" prop="name">
+        <el-input v-model="ruleForm.name" style="width: 200px"></el-input>
+      </el-form-item>
+
+      <div class="area-title" style="margin-top: 60px">涓氬姟淇℃伅</div>
+
+      <el-form-item label="琛屼笟搴旂敤" prop="region">
+        <el-select
+          v-model="ruleForm.region"
+          placeholder="璇烽�夋嫨琛屼笟搴旂敤"
+          style="width: 410px"
+        >
+          <el-option label="鍖哄煙涓�" value="shanghai"></el-option>
+          <el-option label="鍖哄煙浜�" value="beijing"></el-option>
+        </el-select>
+      </el-form-item>
+      <el-form-item label="鍏徃鍚嶇О" prop="region">
+        <el-input v-model="ruleForm.name" style="width: 410px"></el-input>
+      </el-form-item>
+
+      <div class="area-title" style="margin-top: 60px">鑱旂郴淇℃伅</div>
+
+      <el-form-item label="鎵�鍦ㄥ湴鍖�" prop="region">
+        <el-select
+          v-model="ruleForm.region"
+          placeholder="璇烽�夋嫨鍩庡競"
+          style="width: 200px; margin-right: 10px"
+        >
+          <el-option label="鍖哄煙涓�" value="shanghai"></el-option>
+          <el-option label="鍖哄煙浜�" value="beijing"></el-option>
+        </el-select>
+        <el-select
+          v-model="ruleForm.region"
+          placeholder="璇烽�夋嫨鍖�"
+          style="width: 200px"
+        >
+          <el-option label="鍖哄煙涓�" value="shanghai"></el-option>
+          <el-option label="鍖哄煙浜�" value="beijing"></el-option>
+        </el-select>
+      </el-form-item>
+      <el-form-item label="鎵嬫満鍙�" prop="name">
+        <el-input v-model="ruleForm.name" style="width: 200px"></el-input>
+      </el-form-item>
+
+      <el-form-item label="閭" prop="name">
+        <el-input v-model="ruleForm.password" style="width: 410px"></el-input>
+      </el-form-item>
+    </el-form>
+    <div class="btns">
+      <div class="searchBtn" @click="searchingBtn">淇濆瓨</div>
+    </div>
+  </div>
+</template>
+
+<script>
+export default {
+  components: {},
+  data() {
+    return {
+      searchTime: [
+        this.$moment().format("YYYY-MM-DD 00:00:00"),
+        this.$moment().format("YYYY-MM-DD HH:mm:ss"),
+      ], //鎼滅储鏃堕棿
+      page: 1,
+      size: 10, //鍒嗛〉鐩稿叧
+      inputText: "", //杈撳叆妗嗗唴瀹�
+      activeStep: 0,
+      activeIndex: 0,
+      total: 0, //鎬绘暟
+      dataList: [
+        {
+          name: "basic",
+          phone: "1121313232",
+          userType: "涓汉",
+          duration: "姘镐箙",
+          authList: "闆嗙兢1锛岄泦缇�2",
+          isBind: 1,
+        },
+      ],
+      isShowAdd: false, //鏄惁灞曠ず鏂板寮圭獥
+      isShowUnbind: false, //鏄惁灞曠ず瑙g粦寮圭獥
+      isShowRelate: false,
+      unbindId: "",
+      durationArr: [
+        {
+          value: 0,
+          label: "涓�骞�",
+        },
+        {
+          value: 1,
+          label: "涓ゅ勾",
+        },
+      ], //鎵�灞為泦缇や笅鎷夋
+      cluster: null, //閫変腑鐨勯泦缇ょ被鍨�
+      showQuit: false, //灞曠ず閫�鍑洪泦缇ょ殑寮圭獥
+      showJoin: false, //灞曠ず鍔犲叆闆嗙兢鐨勫脊绐�
+      activeEquipment: null, //澶勭悊涓殑璁惧
+      ruleForm: {
+        name: "",
+        region: "",
+        password: "",
+        date1: "",
+        date2: "",
+        delivery: false,
+        type: [],
+        resource: "",
+        desc: "",
+        authList: {
+          menuAuth: [],
+          dataAuth: [],
+        },
+      },
+      rules: {
+        name: [
+          { required: true, message: "璇疯緭鍏ユ椿鍔ㄥ悕绉�", trigger: "blur" },
+          { min: 3, max: 5, message: "闀垮害鍦� 3 鍒� 5 涓瓧绗�", trigger: "blur" },
+        ],
+        region: [
+          { required: true, message: "璇烽�夋嫨娲诲姩鍖哄煙", trigger: "change" },
+        ],
+        date1: [
+          {
+            type: "date",
+            required: true,
+            message: "璇烽�夋嫨鏃ユ湡",
+            trigger: "change",
+          },
+        ],
+        date2: [
+          {
+            type: "date",
+            required: true,
+            message: "璇烽�夋嫨鏃堕棿",
+            trigger: "change",
+          },
+        ],
+        type: [
+          {
+            type: "array",
+            required: true,
+            message: "璇疯嚦灏戦�夋嫨涓�涓椿鍔ㄦ�ц川",
+            trigger: "change",
+          },
+        ],
+        resource: [
+          { required: true, message: "璇烽�夋嫨娲诲姩璧勬簮", trigger: "change" },
+        ],
+        desc: [{ required: true, message: "璇峰~鍐欐椿鍔ㄥ舰寮�", trigger: "blur" }],
+      },
+      data1: [
+        {
+          id: 1,
+          label: "涓�绾� 1",
+          children: [
+            {
+              id: 4,
+              label: "浜岀骇 1-1",
+              children: [
+                {
+                  id: 9,
+                  label: "涓夌骇 1-1-1",
+                },
+                {
+                  id: 10,
+                  label: "涓夌骇 1-1-2",
+                },
+              ],
+            },
+          ],
+        },
+        {
+          id: 2,
+          label: "涓�绾� 2",
+          children: [
+            {
+              id: 5,
+              label: "浜岀骇 2-1",
+            },
+            {
+              id: 6,
+              label: "浜岀骇 2-2",
+            },
+          ],
+        },
+        {
+          id: 3,
+          label: "涓�绾� 3",
+          children: [
+            {
+              id: 7,
+              label: "浜岀骇 3-1",
+            },
+            {
+              id: 8,
+              label: "浜岀骇 3-2",
+            },
+          ],
+        },
+      ],
+      defaultProps1: {
+        children: "children",
+        label: "label",
+      },
+      data2: [
+        {
+          id: 1,
+          label: "涓�绾� 1",
+          children: [
+            {
+              id: 4,
+              label: "浜岀骇 1-1",
+              children: [
+                {
+                  id: 9,
+                  label: "涓夌骇 1-1-1",
+                },
+                {
+                  id: 10,
+                  label: "涓夌骇 1-1-2",
+                },
+              ],
+            },
+          ],
+        },
+        {
+          id: 2,
+          label: "涓�绾� 2",
+          children: [
+            {
+              id: 5,
+              label: "浜岀骇 2-1",
+            },
+            {
+              id: 6,
+              label: "浜岀骇 2-2",
+            },
+          ],
+        },
+        {
+          id: 3,
+          label: "涓�绾� 3",
+          children: [
+            {
+              id: 7,
+              label: "浜岀骇 3-1",
+            },
+            {
+              id: 8,
+              label: "浜岀骇 3-2",
+            },
+          ],
+        },
+      ],
+      defaultProps2: {
+        children: "children",
+        label: "label",
+      },
+    };
+  },
+  methods: {
+    goback() {
+      this.isShowRelate = false;
+      this.activeIndex = 0;
+    },
+    goto(i) {
+      this.activeIndex = i;
+    },
+    // 璺冲埌璁惧璇︽儏
+    checkDetail(row) {
+      this.$router.push({
+        path: "/equipmentDetail",
+        query: {
+          id: row.devId,
+          ip: row.devIp,
+          port: row.serverPort,
+          ndid: row.id,
+        },
+      });
+    },
+
+    // 璺冲埌绠楁硶璇︽儏
+    algorithmDetail(row) {
+      this.$router.push({
+        path: "/algorithmDetail",
+        query: {
+          id: row.devId,
+          ip: row.devIp,
+          port: row.serverPort,
+        },
+      });
+    },
+
+    // 鏌ヨ鍒楄〃
+    searchingBtn() {
+      let param = {
+        page: this.page,
+        size: this.size,
+        // startTime: this.searchTime[0],
+        // endTime: this.searchTime[1],
+        inputText: this.inputText,
+      };
+      findDevList(param)
+        .then((res) => {
+          this.dataList = res.data.list;
+          //鏃堕棿鍒嗚鏄剧ず
+
+          this.dataList.forEach((item) => {
+            item.installTime = item.installTime.split(" ");
+            item.firstUseTime = item.firstUseTime.split(" ");
+          });
+          this.total = res.data.total;
+          if (res.data.total <= this.size) {
+            this.page = 1;
+          }
+        })
+        .catch((err) => {
+          console.log(err);
+        });
+    },
+
+    //鍒嗛〉鍔熻兘
+    handleSizeChange(size) {
+      this.size = size;
+      this.searchingBtn();
+    },
+    //鍒嗛〉鍔熻兘
+    refrash(page) {
+      this.page = page;
+      this.searchingBtn();
+    },
+
+    //瑙g粦鎸夐挳
+    Untying(row) {
+      console.log(row);
+      this.unbindId = row.id;
+      this.isShowUnbind = true;
+    },
+
+    //鑾峰緱榛樿鏃堕棿
+    getDateInit() {
+      // 瑕佹眰 榛樿涓�涓湀
+      const end = new Date();
+      const start = new Date();
+      const nowDate = new Date();
+      nowDate.setHours(0);
+      nowDate.setMinutes(0);
+      nowDate.setSeconds(0);
+      nowDate.setMilliseconds(0);
+      start.setTime(nowDate.getTime() - 3600 * 1000 * 24 * 30);
+      end.setTime(nowDate.getTime() + 3600 * 1000 * 24 - 1);
+      return [
+        this.$moment(start).format("YYYY-MM-DD HH:mm:ss"),
+        this.$moment(end).format("YYYY-MM-DD HH:mm:ss"),
+      ];
+    },
+
+    //鍏抽棴鏂板寮圭獥
+    closeAddBox() {
+      this.isShowAdd = false;
+    },
+    // 鍏抽棴瑙g粦寮圭獥
+    closeUnbindBox() {
+      this.isShowUnbind = false;
+    },
+
+    //瑙g粦鎴愬姛鍥炶皟
+    reflash() {
+      this.isShowUnbind = false;
+      this.searchingBtn();
+    },
+
+    clearSearch() {
+      this.searchTime = this.getDateInit();
+      this.inputText = "";
+      this.searchingBtn();
+    },
+
+    //閫�鍑洪泦缇�
+    quitCluster(equipment) {
+      this.activeEquipment = equipment;
+      this.showQuit = true;
+    },
+
+    //鍔犲叆闆嗙兢
+    joinCluster(equipment) {
+      this.activeEquipment = equipment;
+      this.showJoin = true;
+    },
+  },
+  mounted() {},
+};
+</script>
+
+<style scoped lang="scss">
+.basic-info {
+  padding: 20px;
+  .head-name {
+    font-weight: 700;
+    font-size: 16px;
+    line-height: 22px;
+    color: #3d3d3d;
+    border-left: 4px solid #0065ff;
+    padding-left: 10px;
+    margin-bottom: 30px;
+  }
+  .add-ruleForm::v-deep {
+    .area-title {
+      font-weight: 700;
+      color: #666666;
+      font-size: 14px;
+      line-height: 20px;
+      margin-bottom: 20px;
+    }
+    .el-input__inner {
+      // width: 200px;
+      color: #3d3d3d;
+      border-radius: 3px;
+      border-color: #c0c5cc;
+      height: 32px;
+      line-height: 32px;
+    }
+    .user-tree {
+      .el-form-item__content {
+        display: flex;
+        .tree-box {
+          .t {
+            height: 32px;
+            background: #f0f5fa;
+            border-radius: 3px 3px 0px 0px;
+            line-height: 32px;
+            text-align: center;
+            border-bottom: 1px solid #c0c5cc;
+          }
+          width: 336px;
+          height: 480px;
+          border: 1px solid #c0c5cc;
+          margin-right: 20px;
+          box-sizing: border-box;
+        }
+      }
+    }
+  }
+  .searchBtn {
+    width: 80px;margin-top: 38px;
+    height: 40px;
+    line-height: 40px;
+    text-align: center;
+    color: #fff;
+    background: #0065ff;
+  }
+}
+</style>
+
+<style >
+.el-date-table td.start-date span,
+.el-date-table td.end-date span {
+  background-color: #0065ff;
+}
+
+.el-button--text span {
+  color: #0065ff;
+}
+
+.el-button.is-plain:hover,
+.el-button.is-plain:focus {
+  color: #0065ff;
+  border-color: #0065ff;
+}
+</style>
\ No newline at end of file
diff --git a/src/views/personalCenter/components/Content.vue b/src/views/personalCenter/components/Content.vue
new file mode 100644
index 0000000..b725687
--- /dev/null
+++ b/src/views/personalCenter/components/Content.vue
@@ -0,0 +1,94 @@
+<template>
+  <div class="whiteContent Content">
+    <LeftMenu @mChange="mChange"> </LeftMenu>
+    <div class="right-content">
+      <SubAccount v-if="activeIndex == 4"></SubAccount>
+      <BasicInfo v-if="activeIndex == 3"></BasicInfo>
+    </div>
+  </div>
+</template>
+
+<script>
+import { findDevList } from "@/api/device";
+import SubAccount from "./SubAccount";
+import LeftMenu from "./LeftMenu";
+import BasicInfo from "./BasicInfo";
+export default {
+  created() {
+    window._AMapSecurityConfig = {
+      securityJsCode: "768ab79bdc4075aa082bc070c53bb3c4",
+    };
+  },
+  mounted() {
+    this.searchingBtn();
+  },
+  components: {
+    SubAccount, //琛ㄦ牸
+    LeftMenu,
+    BasicInfo,
+  },
+  data() {
+    return {
+      map: null,
+      AMap: null,
+      activeIndex: 0,
+      nodes: [],
+      isShowCard: false,
+      isFull: false, //鏄惁鍏ㄥ睆
+      zoom: 4, //鍦板浘绾у埆
+      center: [116.06157, 39.66157], //鍦板浘涓績
+      activeNode: null, //閫変腑鐨勫湴鍥捐妭鐐�
+      geocoder: {},
+    };
+  },
+
+  methods: {
+    //鍏抽棴璁惧璇︽儏寮瑰眰
+    closeCard() {
+      this.isShowCard = false;
+    },
+    mChange(i) {
+      this.activeIndex = i;
+    },
+    // 鏌ヨ鍒楄〃
+    searchingBtn() {
+      let param = {
+        page: 1,
+        size: 999,
+        inputText: "",
+      };
+      findDevList(param)
+        .then((res) => {
+          this.nodes = res.data.list;
+        })
+        .catch((err) => {
+          console.log(err);
+        });
+    },
+  },
+};
+</script>
+
+<style scoped lang="scss">
+.whiteContent {
+  position: relative;
+  box-sizing: border-box;
+  margin: 30px auto;
+  display: flex;
+  justify-content: center;
+  .left-menu {
+    margin-right: 24px;
+  }
+  .sub-account {
+    height: 100%;
+    box-sizing: border-box;
+    background-color: #fff;
+  }
+  .right-content {
+    min-height: 856px;
+    box-sizing: border-box;
+    background-color: #fff;
+    width: 1196px;
+  }
+}
+</style>
\ No newline at end of file
diff --git a/src/views/personalCenter/components/InfoCard.vue b/src/views/personalCenter/components/InfoCard.vue
new file mode 100644
index 0000000..6098ced
--- /dev/null
+++ b/src/views/personalCenter/components/InfoCard.vue
@@ -0,0 +1,311 @@
+<template>
+  <div class="InfoCard">
+    <span class="close iconfont" @click="close">&#xe60f;</span>
+
+    <div class="name">{{ node.devName }}</div>
+    <div class="info">
+      <div class="head">
+        <div class="title">璁惧淇℃伅</div>
+        <div class="link" @click="checkDetail('equipmentDetail')">
+          鏌ョ湅璇︽儏 >
+        </div>
+      </div>
+      <div class="item">
+        <div class="label">璁惧鍨嬪彿:</div>
+        <div class="data">{{ node.devMode }}</div>
+      </div>
+
+      <div class="item">
+        <div class="label">璁惧绫诲瀷:</div>
+        <div class="data">{{ node.devType }}</div>
+      </div>
+
+      <div class="item">
+        <div class="label">閫氶亾涓暟:</div>
+        <div class="data">{{ node.channelCount }}</div>
+      </div>
+
+      <div class="item">
+        <div class="label">鍐呭瓨:</div>
+        <div class="data">{{ node.mem }}</div>
+      </div>
+    </div>
+
+    <div class="info propertyInfo">
+      <div class="head">
+        <div class="title">绯荤粺鎬ц兘</div>
+      </div>
+      <div class="propertyList" v-if="devicePerformance.length > 0">
+        <div class="property">
+          <el-progress
+            type="circle"
+            :percentage="devicePerformance[0].data"
+            :stroke-width="25"
+            color="#0065FF"
+          ></el-progress>
+          <div class="num">{{ devicePerformance[0].data }}%</div>
+          <div class="des">鍐呭瓨</div>
+        </div>
+
+        <div class="property">
+          <el-progress
+            type="circle"
+            :percentage="devicePerformance[1].data"
+            :stroke-width="25"
+            color="rgb(64, 182, 58)"
+          ></el-progress>
+          <div class="num">{{ devicePerformance[1].data }}%</div>
+          <div class="des">绠楀姏</div>
+        </div>
+
+        <div class="property">
+          <el-progress
+            type="circle"
+            :percentage="devicePerformance[2].data"
+            :stroke-width="25"
+            color="rgb(255, 186, 74)"
+          ></el-progress>
+          <div class="num">{{ devicePerformance[2].data }}%</div>
+          <div class="des">CPU</div>
+        </div>
+
+        <div class="property">
+          <el-progress
+            type="circle"
+            :percentage="devicePerformance[3].data"
+            :stroke-width="25"
+            color="rgb(197, 35, 223)"
+          ></el-progress>
+          <div class="num">{{ devicePerformance[3].data }}%</div>
+          <div class="des">纭洏</div>
+        </div>
+      </div>
+    </div>
+
+    <div class="algorithm info">
+      <div class="head">
+        <div class="title">绠楁硶淇℃伅</div>
+        <div class="link" @click="checkDetail('algorithmDetail')">
+          鏌ョ湅璇︽儏 >
+        </div>
+      </div>
+
+      <div class="item">
+        <div class="label">绠楁硶鏁伴噺:</div>
+        <div class="data">{{ algAll }}</div>
+      </div>
+
+      <div class="item">
+        <div class="label">寰呭崌绾х畻娉曟暟閲�:</div>
+        <div class="data">{{ algUpgrade }}</div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import { findAllSdk, showSystemStates } from "@/api/device";
+export default {
+  props: {
+    node: {
+      type: Object,
+    },
+  },
+  created() {
+    this.getAlg();
+    this.getDevicePerformance();
+  },
+  data() {
+    return {
+      algAll: 0, //鎵�鏈夌畻娉�
+      algUpgrade: 0, //寰呭崌绾х殑绠楁硶
+      devicePerformance: [], //绯荤粺鎬ц兘
+    };
+  },
+  methods: {
+    //鑾峰彇绠楁硶淇℃伅
+    async getAlg() {
+      const res = await findAllSdk({
+        ip: this.node.devIp,
+        port: this.node.serverPort,
+      });
+
+      res.data.data.forEach((item) => {
+        //璁$畻绠楁硶鎬绘暟
+        if (item.installed) {
+          this.algAll++;
+        }
+        //璁$畻寰呭崌绾х畻娉�
+        if (item.installed && item.isUpgrade) {
+          this.algUpgrade++;
+        }
+      });
+    },
+    //鑾峰彇璁惧鎬ц兘
+    async getDevicePerformance() {
+      const res = await showSystemStates({
+        ip: this.node.devIp,
+        port: this.node.serverPort,
+      });
+      this.devicePerformance.push({
+        data: +res.data.mem.usedPercent.toString().split(".")[0],
+        name: "鍐呭瓨",
+        type: "mem",
+      });
+      this.devicePerformance.push({
+        data: +res.data.gpu.toString().split(".")[0],
+        name: "绠楀姏",
+        type: "gpu",
+      });
+      this.devicePerformance.push({
+        data: +res.data.cpu.toString().split(".")[0],
+        name: "cpu",
+        type: "cpu",
+      });
+
+      let distData = 0;
+
+      res.data.disk.forEach((item) => {
+        let distItem = +item.info.usedPercent.toString().split(".")[0];
+        distData = distData + distItem;
+      });
+
+      this.devicePerformance.push({
+        data: distData,
+        name: `纭洏`,
+        type: "dist",
+      });
+
+      console.log(this.devicePerformance);
+    },
+    //鍏抽棴
+    close() {
+      this.$emit("close");
+    },
+    // 璺宠浆璇︽儏椤�
+    checkDetail(type) {
+      this.$router.push({
+        path: `/${type}`,
+        query: {
+          id: this.node.devId,
+          ip: this.node.devIp,
+          port: this.node.serverPort,
+          ndid: this.node.id,
+        },
+      });
+    },
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+.InfoCard {
+  box-sizing: border-box;
+  padding: 20px 20px 10px 20px;
+  width: 270px;
+  height: 488px;
+  background-color: #fff;
+  filter: drop-shadow(0px 2px 16px rgba(0, 43, 106, 0.25));
+
+  .name {
+    font-weight: bold;
+    font-size: 18px;
+  }
+
+  .info {
+    position: relative;
+    box-sizing: border-box;
+    padding: 10px;
+    margin-top: 10px;
+    background: rgba(233, 235, 238, 0.4);
+    font-size: 14px;
+
+    .head {
+      display: flex;
+      justify-content: space-between;
+
+      .title {
+        font-weight: bold;
+        color: #666666;
+      }
+
+      .link {
+        color: #0065ff;
+        cursor: pointer;
+
+        &:hover {
+          color: #0033ff;
+        }
+      }
+    }
+
+    .item {
+      display: flex;
+      justify-content: space-between;
+      margin-top: 10px;
+
+      .label {
+        color: #999999;
+      }
+    }
+
+    .propertyList {
+      display: flex;
+      margin-top: 10px;
+      margin-bottom: 4px;
+      width: 100%;
+
+      .property {
+        flex: 1;
+        text-align: center;
+
+        .el-progress ::v-deep {
+          .el-progress-circle,
+          svg {
+            height: 45px !important;
+            width: 45px !important;
+          }
+
+          .el-progress__text {
+            display: none;
+          }
+        }
+
+        .des {
+          color: #666;
+          font-size: 12px;
+        }
+
+        &:nth-child(1) ::v-deep .el-progress-circle__track {
+          stroke: rgb(212, 227, 250);
+        }
+
+        &:nth-child(2) ::v-deep .el-progress-circle__track {
+          stroke: rgb(196, 242, 194);
+        }
+
+        &:nth-child(3) ::v-deep .el-progress-circle__track {
+          stroke: rgb(250, 231, 200);
+        }
+
+        &:nth-child(4) ::v-deep .el-progress-circle__track {
+          stroke: rgb(241, 215, 245);
+        }
+      }
+    }
+
+    &.propertyInfo {
+      height: 137px;
+    }
+  }
+
+  .close {
+    position: absolute;
+    top: 16px;
+    right: 16px;
+    font-size: 12px;
+    color: rgb(187, 187, 187);
+    cursor: pointer;
+  }
+}
+</style>
\ No newline at end of file
diff --git a/src/views/personalCenter/components/JoinClusterBox.vue b/src/views/personalCenter/components/JoinClusterBox.vue
new file mode 100644
index 0000000..2b53c89
--- /dev/null
+++ b/src/views/personalCenter/components/JoinClusterBox.vue
@@ -0,0 +1,367 @@
+<template>
+  <div class="QuitClusterBox" @click="showClusterList = false">
+    <div class="title">鍔犲叆闆嗙兢</div>
+    <!-- 鍒囨崲tab -->
+    <div class="tabs" :class="{ right: activeTab == '鍔犲叆宸叉湁闆嗙兢' }">
+      <div
+        class="tab"
+        v-for="item in tabArr"
+        :key="item"
+        :class="{ active: activeTab == item }"
+        @click="activeTab = item"
+      >
+        {{ item }}
+      </div>
+    </div>
+
+    <!-- 鍒涘缓闆嗙兢琛ㄦ牸 -->
+    <el-form
+      :model="formData"
+      ref="userForm"
+      label-position="left"
+      label-width="76px"
+      v-if="activeTab == '鍒涘缓闆嗙兢'"
+    >
+      <el-form-item prop="name" label="闆嗙兢鍚嶇О">
+        <el-input v-model="formData.name" placeholder="璇疯緭鍏�"></el-input>
+      </el-form-item>
+
+      <el-form-item prop="id" label="闆嗙兢ID">
+        <el-input
+          v-model="formData.id"
+          :disabled="true"
+          placeholder="鍒涘缓闆嗙兢鍚庡洖鏄�"
+        ></el-input>
+      </el-form-item>
+
+      <el-form-item prop="password" label="闆嗙兢瀵嗙爜" class="password">
+        <el-input
+          v-model="formData.password"
+          placeholder="璇疯緭鍏�,鎴栫偣鍑荤敓鎴愬瘑鐮�"
+        ></el-input>
+        <div class="createPassword">鐢熸垚瀵嗙爜</div>
+      </el-form-item>
+
+      <el-form-item prop="ip" label="闆嗙兢IP">
+        <ip-input
+          :ip="formData.ip"
+          :on-blur="onCreateIpBlur"
+          class="ip-input-comp"
+        ></ip-input>
+      </el-form-item>
+    </el-form>
+
+    <!-- 鍔犲叆宸叉湁闆嗙兢琛ㄦ牸 -->
+    <el-form
+      :model="formData2"
+      ref="userForm"
+      label-position="left"
+      label-width="76px"
+      v-if="activeTab == '鍔犲叆宸叉湁闆嗙兢'"
+      autocomplete="off"
+    >
+      <el-form-item prop="id" label="闆嗙兢ID">
+        <el-input v-model="formData2.name" placeholder="璇疯緭鍏�"></el-input>
+      </el-form-item>
+
+      <el-form-item prop="ip" label="IP鍦板潃">
+        <ip-input
+          :ip="formData2.ip"
+          :on-blur="onJoinIpBlur"
+          class="ip-input-comp"
+        ></ip-input>
+      </el-form-item>
+
+      <el-form-item prop="password" label="闆嗙兢瀵嗙爜" class="password">
+        <el-input
+          v-model="formData2.password"
+          placeholder="璇疯緭鍏�,鎴栫偣鍑荤敓鎴愬瘑鐮�"
+          class="passwordInput"
+          :class="{ hiddenPassword: hiddenPassword }"
+        >
+          <div class="control" slot="suffix">
+            <i
+              v-if="hiddenPassword == false"
+              @click="hiddenPassword = true"
+              class="iconfont"
+              >&#xe60a;</i
+            >
+            <i v-else @click="hiddenPassword = false" class="iconfont"
+              >&#xe609;</i
+            >
+          </div>
+        </el-input>
+        <div class="search" @click="searchCluster">鎼滅储闆嗙兢</div>
+      </el-form-item>
+
+      <el-form-item prop="ip" label="闆嗙兢IP">
+        <ip-input
+          :ip="formData2.clusterIp"
+          :on-blur="onClusterIpBlur"
+          class="ip-input-comp"
+        ></ip-input>
+      </el-form-item>
+
+      <div class="clusterList" v-if="showClusterList">
+        <div
+          class="clusterItem"
+          v-for="(item, index) in clusterList"
+          :key="index"
+        >
+          {{ item }}
+        </div>
+      </div>
+    </el-form>
+
+    <!-- 鍙栨秷涓庢彁浜� -->
+    <div class="btns">
+      <div class="cancel button" @click="close()">鍙栨秷</div>
+      <div class="quit button" @click="close()">閫�鍑洪泦缇�</div>
+    </div>
+
+    <div class="close iconfont" @click="close()">&#xe60f;</div>
+  </div>
+</template>
+
+<script>
+import ipInput from "@/components/IPInput";
+
+export default {
+  components: {
+    ipInput,
+  },
+  data() {
+    return {
+      tabArr: ["鍒涘缓闆嗙兢", "鍔犲叆宸叉湁闆嗙兢"], //tab鏍�
+      activeTab: "鍒涘缓闆嗙兢", //閫変腑鐨則ab
+      formData: {
+        name: "189闆嗙兢",
+        id: "5ee1dfa8-e3fb-4d62-8692-388d7632859b",
+        password: "123456",
+        ip: "192.168.20.117",
+      }, //鍒涘缓闆嗙兢琛ㄥ崟鏁版嵁
+      formData2: {
+        id: "",
+        ip: "",
+        password: "",
+        clusterIp: "",
+      }, //鍔犲叆闆嗙兢琛ㄥ崟鏁版嵁
+      hiddenPassword: false, //闅愯棌瀵嗙爜
+      clusterList: ["192.168.20.4", "192.168.20.5", "192.168.20.6"], //闆嗙兢鍒楄〃
+      showClusterList: false, //鏄惁灞曠ず闆嗙兢鍒楄〃
+    };
+  },
+  methods: {
+    close() {
+      this.$emit("close");
+    },
+    //鍒涘缓闆嗙兢ip鍥炶皟
+    onCreateIpBlur(ip) {
+      this.formData.ip = ip;
+    },
+    //鍔犲叆闆嗙兢ip鍦板潃
+    onJoinIpBlur(ip) {
+      this.formData2.ip = ip;
+    },
+    //鍔犲叆闆嗙兢闆嗙兢ip
+    onClusterIpBlur(ip) {
+      this.formData2.clusterIp = ip;
+    },
+    //鎼滅储闆嗙兢鍒楄〃
+    searchCluster(e) {
+      e.stopPropagation();
+      this.showClusterList = true;
+    },
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+.QuitClusterBox {
+  position: relative;
+  box-sizing: border-box;
+  padding: 20px;
+  position: fixed;
+  width: 440px;
+  height: 434px;
+  top: 50%;
+  left: 50%;
+  margin-top: -217px;
+  margin-left: -230px;
+  filter: drop-shadow(0px 2px 16px rgba(0, 43, 106, 0.25));
+  z-index: 3;
+  background-color: #fff;
+
+  .title {
+    padding-bottom: 20px;
+    font-size: 18px;
+    font-weight: 700;
+    border-bottom: 1px solid #e9ebee;
+  }
+
+  .tabs {
+    position: relative;
+    display: flex;
+    justify-content: center;
+    margin: 20px 0;
+    color: #999999;
+    font-size: 16px;
+
+    .tab {
+      cursor: pointer;
+      &:first-child {
+        margin-right: 20px;
+      }
+
+      &.active {
+        color: #0065ff;
+      }
+    }
+
+    &::after {
+      display: block;
+      position: absolute;
+      left: 118px;
+      bottom: -8px;
+      content: "";
+      width: 48px;
+      height: 2px;
+      background-color: #0065ff;
+      transition: all 0.15s linear;
+    }
+
+    &.right::after {
+      left: 217px;
+    }
+  }
+
+  .el-form-item ::v-deep {
+    margin-bottom: 20px;
+
+    label {
+      color: #666;
+    }
+
+    .el-input {
+      .el-input__inner {
+        padding: 0 10px;
+        color: #3d3d3d;
+        border-radius: 0;
+        border-color: #c0c5cc;
+        &::-webkit-input-placeholder {
+          color: #999999;
+        }
+
+        &:focus {
+          border-color: #0065ff;
+        }
+      }
+    }
+  }
+
+  .el-form-item.password ::v-deep {
+    .el-form-item__content {
+      display: flex;
+      justify-content: space-between;
+
+      .el-input {
+        margin-left: -4px;
+        width: 250px;
+      }
+
+      .createPassword {
+        font-size: 14px;
+        color: #0065ff;
+      }
+
+      .search {
+        margin-top: 8px;
+        width: 64px;
+        height: 24px;
+        font-size: 12px;
+        line-height: 24px;
+        text-align: center;
+        background-color: #0065ff;
+        color: #fff;
+        cursor: pointer;
+      }
+    }
+  }
+
+  .ip-input-container ::v-deep {
+    border-color: #c0c5cc;
+    height: 40px;
+
+    .ip-segment,
+    input {
+      height: 40px;
+    }
+  }
+
+  .clusterList {
+    position: absolute;
+    width: 324px;
+    top: 288px;
+    left: 96px;
+    background: #ffffff;
+    box-shadow: 0px 4px 12px rgba(0, 43, 106, 0.12);
+
+    .clusterItem {
+      padding-left: 10px;
+      height: 40px;
+      line-height: 40px;
+      color: #0065ff;
+
+      &:hover {
+        background: #f0f5fa;
+      }
+    }
+  }
+
+  .btns {
+    margin-top: 20px;
+    display: flex;
+    justify-content: end;
+    text-align: center;
+    line-height: 32px;
+    font-size: 14px;
+
+    .cancel {
+      margin-right: 10px;
+      width: 60px;
+      height: 32px;
+      border: 1px solid #0065ff;
+      color: #0065ff;
+    }
+
+    .quit {
+      width: 88px;
+      height: 32px;
+      color: #fff;
+      background-color: #0065ff;
+      border: 1px solid #0065ff;
+    }
+  }
+
+  .close {
+    position: absolute;
+    top: 20px;
+    right: 20px;
+    font-size: 12px;
+    color: #666;
+    cursor: pointer;
+  }
+
+  .passwordInput {
+    .iconfont {
+      font-size: 24px;
+      -webkit-text-security: none;
+      cursor: pointer;
+    }
+
+    &.hiddenPassword {
+      -webkit-text-security: disc;
+    }
+  }
+}
+</style>
\ No newline at end of file
diff --git a/src/views/personalCenter/components/LeftMenu.vue b/src/views/personalCenter/components/LeftMenu.vue
new file mode 100644
index 0000000..905dadd
--- /dev/null
+++ b/src/views/personalCenter/components/LeftMenu.vue
@@ -0,0 +1,94 @@
+<template>
+  <div class="left-menu">
+    <div class="user-img">
+      <img src="/images/hashrate/鐙珛鍦烘櫙绌洪〉闈�.png" alt="" />
+    </div>
+    <div class="user-name">{{ userInfo.username }}</div>
+
+    <div class="menu-list">
+      <div
+        class="item"
+        @click="pickMenu(index)"
+        v-for="(item, index) in menuList"
+        :key="index"
+        :class="index == activeIndex ? 'active-item' : ''"
+      >
+        <span class="iconfont">&#xe614;</span>
+        <span class="item-name"> {{ item.name }}</span>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+export default {
+  created() {
+    this.userInfo = JSON.parse(sessionStorage.getItem("userInfo"));
+  },
+  data() {
+    return {
+      menuList: [
+        { name: "璐︽埛鎬昏" },
+        { name: "璁㈠崟绠$悊" },
+        { name: "娑堟伅涓績" },
+        { name: "鍩烘湰璧勬枡" },
+        { name: "瀛愯处鎴风鐞�" },
+      ],
+      userInfo: null,
+      activeIndex: 0,
+    };
+  },
+  methods: {
+    pickMenu(i) {
+      this.activeIndex = i;
+      this.$emit("mChange", i);
+    },
+  },
+};
+</script>
+
+<style scoped lang="scss">
+.left-menu {
+  background: #fff;
+  width: 220px;
+  min-height: 856px;
+  padding: 30px 10px;
+  box-sizing: border-box;
+  .user-img {
+    display: flex;
+    justify-content: center;
+    margin-bottom: 10px;
+    img {
+      width: 60px;
+      height: 60px;
+    }
+  }
+  .user-name {
+    font-size: 18px;
+    line-height: 25px;
+    color: #3d3d3d;
+    text-align: center;
+  }
+  .menu-list {
+    margin-top: 30px;
+    .item {
+      height: 40px;
+      padding-left: 10px;
+      border-radius: 4px;
+      margin-bottom: 4px;
+      cursor: pointer;
+      line-height: 40px;
+      .iconfont {
+        margin-right: 8px;
+      }
+    }
+    .item:not(.active-item):hover {
+      background: #e9ebee;
+    }
+    .active-item {
+      background: #0065ff;
+      color: #fff;
+    }
+  }
+}
+</style>
\ No newline at end of file
diff --git a/src/views/personalCenter/components/QuitClusterBox.vue b/src/views/personalCenter/components/QuitClusterBox.vue
new file mode 100644
index 0000000..19dd78a
--- /dev/null
+++ b/src/views/personalCenter/components/QuitClusterBox.vue
@@ -0,0 +1,145 @@
+<template>
+  <div class="QuitClusterBox">
+    <div class="title">閫�鍑洪泦缇�</div>
+    <div class="name">189鏈嶅姟鍣�</div>
+
+    <el-form
+      :model="formData"
+      ref="userForm"
+      label-position="left"
+      label-width="76px"
+    >
+      <el-form-item prop="name" label="闆嗙兢鍚嶇О">
+        <el-input v-model="formData.name"></el-input>
+      </el-form-item>
+
+      <el-form-item prop="id" label="闆嗙兢ID">
+        <el-input v-model="formData.id"></el-input>
+      </el-form-item>
+
+      <el-form-item prop="password" label="闆嗙兢瀵嗙爜">
+        <el-input v-model="formData.password"></el-input>
+      </el-form-item>
+
+      <el-form-item prop="ip" label="闆嗙兢IP">
+        <el-input v-model="formData.ip"></el-input>
+      </el-form-item>
+    </el-form>
+
+    <div class="btns">
+      <div class="cancel button" @click="close()">鍙栨秷</div>
+      <div class="submit button" @click="close()">閫�鍑洪泦缇�</div>
+    </div>
+
+    <div class="close iconfont" @click="close()">&#xe60f;</div>
+  </div>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      formData: {
+        name: "189闆嗙兢",
+        id: "5ee1dfa8-e3fb-4d62-8692-388d7632859b",
+        password: "123456",
+        ip: "192.168.20.117",
+      },
+    };
+  },
+  methods: {
+    close() {
+      this.$emit("close");
+    },
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+.QuitClusterBox {
+  box-sizing: border-box;
+  padding: 20px;
+  position: fixed;
+  width: 440px;
+  height: 434px;
+  top: 50%;
+  left: 50%;
+  margin-top: -217px;
+  margin-left: -230px;
+  filter: drop-shadow(0px 2px 16px rgba(0, 43, 106, 0.25));
+  z-index: 3;
+  background-color: #fff;
+
+  .title {
+    padding-bottom: 20px;
+    font-size: 18px;
+    font-weight: 700;
+    border-bottom: 1px solid #e9ebee;
+  }
+
+  .name {
+    margin: 20px 0;
+    color: #666;
+    font-size: 16px;
+    font-weight: 700;
+  }
+
+  .el-form-item ::v-deep {
+    margin-bottom: 20px;
+
+    label {
+      color: #666;
+    }
+
+    .el-input {
+      .el-input__inner {
+        padding: 0 10px;
+        color: #3d3d3d;
+        border-radius: 0;
+        border-color: #c0c5cc;
+        &::-webkit-input-placeholder {
+          color: #999999;
+        }
+
+        &:focus {
+          border-color: #0065ff;
+        }
+      }
+    }
+  }
+
+  .btns {
+    margin-top: 20px;
+    display: flex;
+    justify-content: end;
+    text-align: center;
+    line-height: 32px;
+    font-size: 14px;
+
+    .cancel {
+      margin-right: 10px;
+      width: 60px;
+      height: 32px;
+      border: 1px solid #0065ff;
+      color: #0065ff;
+    }
+
+    .submit {
+      width: 88px;
+      height: 32px;
+      color: #fff;
+      background-color: #0065ff;
+      border: 1px solid #0065ff;
+    }
+  }
+
+  .close {
+    position: absolute;
+    top: 20px;
+    right: 20px;
+    font-size: 12px;
+    color: #666;
+    cursor: pointer;
+  }
+}
+</style>
\ No newline at end of file
diff --git a/src/views/personalCenter/components/StepCard.vue b/src/views/personalCenter/components/StepCard.vue
new file mode 100644
index 0000000..44af2a4
--- /dev/null
+++ b/src/views/personalCenter/components/StepCard.vue
@@ -0,0 +1,339 @@
+<template>
+  <div class="step-card">
+    <div class="step-0" v-if="activeIndex == 0">
+      <el-form
+        :model="ruleForm"
+        :rules="rules"
+        ref="ruleForm"
+        :label-position="'left'"
+        label-width="70px"
+        class="relate-form"
+      >
+        <el-form-item label="鎵嬫満鍙�" prop="phone">
+          <el-input
+            v-model="ruleForm.phone"
+            placeholder="璇疯緭鍏ユ墜鏈哄彿"
+          ></el-input>
+        </el-form-item>
+        <el-form-item label="鐢ㄦ埛鍚�" prop="username">
+          <el-input
+            v-model="ruleForm.username"
+            placeholder="璇疯緭鍏ョ敤鎴峰悕"
+          ></el-input>
+        </el-form-item>
+      </el-form>
+
+      <div class="btns">
+        <div class="cancel" @click="goback">鍙栨秷</div>
+        <div class="ok" @click="gonext">涓嬩竴姝�</div>
+      </div>
+    </div>
+    <div class="step-1" v-if="activeIndex == 1">
+      <div class="user-auth">
+        <div class="name">鐢ㄦ埛鏉冮檺</div>
+        <div class="tree-box">
+          <div class="t">鑿滃崟鏉冮檺</div>
+          <el-tree
+            :data="data1"
+            show-checkbox
+            node-key="id"
+            :default-expanded-keys="[2, 3]"
+            :default-checked-keys="[5]"
+            :props="defaultProps1"
+          >
+          </el-tree>
+        </div>
+        <div class="tree-box">
+          <div class="t">鏁版嵁鏉冮檺</div>
+          <el-tree
+            :data="data2"
+            show-checkbox
+            node-key="id"
+            :default-expanded-keys="[2, 3]"
+            :default-checked-keys="[5]"
+            :props="defaultProps2"
+          >
+          </el-tree>
+        </div>
+      </div>
+
+      <div class="btns">
+        <div class="cancel prev" @click="goprev">涓婁竴姝�</div>
+        <div class="ok" @click="gonext">涓嬩竴姝�</div>
+      </div>
+    </div>
+    <div class="step-2" v-if="activeIndex == 2">
+      <div class="t">
+        <i class="el-icon-circle-check"></i>
+        <span t-h>鍙戦�侀個璇锋垚鍔燂紒绛夊緟鍏宠仈瀛愯处鍙风‘璁わ紒</span>
+      </div>
+      <div class="desc">
+        鎴戜滑浼氶�氳繃绔欏唴淇℃柟寮忛�氱煡鎮ㄩ個绾︾殑鍏宠仈瀛愯处鍙凤紝璇锋帹杩涘叧鑱旇处鍙风殑纭銆�
+      </div>
+      <div class="btns">
+        <div class="ok" @click="goback">瀹屾垚</div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import { validUser, isPhone } from "@/scripts/validate"; // 姝e垯鏂囦欢
+export default {
+  data() {
+    return {
+      ruleForm: {
+        phone: "",
+        username: "",
+      },
+      data1: [
+        {
+          id: 1,
+          label: "涓�绾� 1",
+          children: [
+            {
+              id: 4,
+              label: "浜岀骇 1-1",
+              children: [
+                {
+                  id: 9,
+                  label: "涓夌骇 1-1-1",
+                },
+                {
+                  id: 10,
+                  label: "涓夌骇 1-1-2",
+                },
+              ],
+            },
+          ],
+        },
+        {
+          id: 2,
+          label: "涓�绾� 2",
+          children: [
+            {
+              id: 5,
+              label: "浜岀骇 2-1",
+            },
+            {
+              id: 6,
+              label: "浜岀骇 2-2",
+            },
+          ],
+        },
+        {
+          id: 3,
+          label: "涓�绾� 3",
+          children: [
+            {
+              id: 7,
+              label: "浜岀骇 3-1",
+            },
+            {
+              id: 8,
+              label: "浜岀骇 3-2",
+            },
+          ],
+        },
+      ],
+      data2: [
+        {
+          id: 1,
+          label: "涓�绾� 1",
+          children: [
+            {
+              id: 4,
+              label: "浜岀骇 1-1",
+              children: [
+                {
+                  id: 9,
+                  label: "涓夌骇 1-1-1",
+                },
+                {
+                  id: 10,
+                  label: "涓夌骇 1-1-2",
+                },
+              ],
+            },
+          ],
+        },
+        {
+          id: 2,
+          label: "涓�绾� 2",
+          children: [
+            {
+              id: 5,
+              label: "浜岀骇 2-1",
+            },
+            {
+              id: 6,
+              label: "浜岀骇 2-2",
+            },
+          ],
+        },
+        {
+          id: 3,
+          label: "涓�绾� 3",
+          children: [
+            {
+              id: 7,
+              label: "浜岀骇 3-1",
+            },
+            {
+              id: 8,
+              label: "浜岀骇 3-2",
+            },
+          ],
+        },
+      ],
+      defaultProps2: {
+        children: "children",
+        label: "label",
+      },
+      defaultProps1: {
+        children: "children",
+        label: "label",
+      },
+      rules: {
+        phone: [
+          { required: true, message: "璇疯緭鍏ユ墜鏈哄彿", trigger: "blur" },
+          { validator: isPhone, trigger: "blur" },
+        ],
+        // username: [{ validator: validUser, trigger: "blur" }],
+      },
+    };
+  },
+  props: {
+    titleList: Array,
+    activeIndex: {
+      type: Number,
+      default: 0,
+    },
+  },
+  computed: {},
+  methods: {
+    goback() {
+      this.activeIndex = 0
+      this.$emit("goback");
+    },
+    goprev() {
+      this.activeIndex--;
+      let next = this.activeIndex;
+      this.$emit("goto", next);
+    },
+    gonext() {
+      let next = this.activeIndex;
+      if (this.activeIndex < 2) {
+        next = ++this.activeIndex;
+      }
+      this.$emit("goto", next);
+    },
+    getClass(i) {
+      if (this.activeIndex == i) {
+        return "active-box";
+      } else if (this.activeIndex > i) {
+        return "done-box";
+      } else {
+        return "";
+      }
+    },
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+.step-card {
+  display: flex;
+  justify-content: center;
+  .relate-form::v-deep {
+    .el-input__inner {
+      color: #3d3d3d;
+      border-radius: 3px;
+      height: 32px;
+      width: 350px;
+      border: 1px solid #c0c5cc;
+      line-height: 32px;
+    }
+  }
+  .btns {
+    display: flex;
+    justify-content: center;
+    margin-top: 50px;
+    .cancel {
+      width: 80px;
+      height: 40px;
+      display: flex;
+      justify-content: center;
+      align-items: center;
+      border-radius: 3px;
+      box-sizing: border-box;
+      border: 1px solid #0064ff;
+      color: #0064ff;
+      cursor: pointer;
+      margin-right: 10px;    line-height: 40px;
+
+    }
+    .prev {
+      width: 96px;
+    }
+    .ok {
+      border-radius: 3px;
+      background: #0064ff;
+      width: 96px;
+      height: 40px;
+      display: flex;line-height: 40px;
+      justify-content: center;
+      cursor: pointer;
+      align-items: center;
+      color: #ffffff;
+    }
+  }
+  .user-auth {
+    display: flex;
+    .name {
+      font-size: 14px;
+      color: #3d3d3d;
+      margin-right: 20px;
+    }
+    .tree-box {
+      .t {
+        height: 32px;
+        background: #f0f5fa;
+        border-radius: 3px 3px 0px 0px;
+        line-height: 32px;
+        text-align: center;
+        border-bottom: 1px solid #c0c5cc;
+      }
+      width: 336px;
+      height: 480px;
+      border: 1px solid #c0c5cc;
+      margin-right: 20px;
+      box-sizing: border-box;
+    }
+  }
+  .step-2 {
+    .t {
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      i {
+        font-size: 32px;
+        color: limegreen;
+        margin-right: 10px;
+      }
+      .t-h {
+        font-size: 18px;
+        color: #3d3d3d;
+        line-height: 24px;
+      }
+      
+    }
+    .desc {
+        font-size: 14px;
+        margin-top: 14px;
+        color: #999999;
+        line-height: 20px;
+      }
+  }
+}
+</style>
\ No newline at end of file
diff --git a/src/views/personalCenter/components/Steps.vue b/src/views/personalCenter/components/Steps.vue
new file mode 100644
index 0000000..1f6ed7f
--- /dev/null
+++ b/src/views/personalCenter/components/Steps.vue
@@ -0,0 +1,109 @@
+<template>
+  <div class="steps">
+    <div
+      class="step-box"
+      v-for="(name, i) in titleList"
+      :key="i"
+      :class="getClass(i)"
+    >
+      <div class="head">
+        <div class="num" v-if="activeIndex <= i">{{ i + 1 }}</div>
+        <i v-else class="el-icon-circle-check"></i>
+      </div>
+      <div class="title">
+        {{ name }}
+      </div>
+      <div class="line" v-if="i !== titleList.length - 1"></div>
+    </div>
+  </div>
+</template>
+
+<script>
+export default {
+  data() {
+    return {};
+  },
+  props: {
+    titleList: Array,
+    activeIndex: {
+      type: Number,
+      default: 0,
+    },
+  },
+  computed: {},
+  methods: {
+    getClass(i) {
+      if (this.activeIndex == i) {
+        return "active-box";
+      } else if (this.activeIndex > i) {
+        return "done-box";
+      } else {
+        return "";
+      }
+    },
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+.steps {
+  display: flex;
+  justify-content: center;
+  margin-bottom: 50px;
+  .step-box.done-box {
+    .el-icon-circle-check {
+      font-size: 24px;
+      color: #0064ff;
+    }
+    .title {
+      color: #0064ff;
+    }
+    .line {
+      height: 2px;
+      background: #0064ff;
+    }
+  }
+  .step-box.active-box {
+    .title {
+      color: #0064ff;
+      font-weight: 600;
+    }
+    .head {
+      .num {
+        border: 1px solid #0064ff;
+        color: #ffffff;
+        background: #0064ff;
+      }
+    }
+  }
+  .step-box {
+    display: flex;
+    align-items: center;
+    margin-right: 16px;
+    .head {
+      margin-right: 14px;
+      .num {
+        width: 24px;
+        height: 24px;
+        border: 1px solid #999999;
+        border-radius: 24px;
+        color: #999999;
+        font-size: 16px;
+        text-align: center;
+        line-height: 24px;
+      }
+    }
+    .title {
+      margin-right: 16px;
+      font-size: 16px;
+      line-height: 24px;
+      color: #999999;
+    }
+    .line {
+      height: 1px;
+      width: 148px;
+      background: #e9ebee;
+    }
+  }
+}
+</style>
\ No newline at end of file
diff --git a/src/views/personalCenter/components/SubAccount.vue b/src/views/personalCenter/components/SubAccount.vue
new file mode 100644
index 0000000..380ef3a
--- /dev/null
+++ b/src/views/personalCenter/components/SubAccount.vue
@@ -0,0 +1,887 @@
+<template>
+  <div class="sub-account" v-if="!isShowAdd && !isShowRelate">
+    <div class="head-name">瀛愯处鎴风鐞�</div>
+    <div class="search">
+      <div class="left">
+        <div class="id">
+          濮撳悕/鎵嬫満鍙�
+          <el-input v-model="inputText" placeholder="璇疯緭鍏�"></el-input>
+        </div>
+
+        <div class="cluster">
+          鎺堟潈鏃堕暱
+          <el-select v-model="cluster" placeholder="璇烽�夋嫨">
+            <el-option
+              v-for="item in durationArr"
+              :key="item.value"
+              :label="item.label"
+              :value="item.value"
+            >
+            </el-option>
+          </el-select>
+        </div>
+      </div>
+
+      <div class="right">
+        <div class="button searchBtn" @click="searchingBtn">鎼滅储</div>
+        <div class="button resetBtn" @click="clearSearch">閲嶇疆</div>
+      </div>
+    </div>
+
+    <div class="btns">
+      <div class="button add" @click="isShowAdd = true">
+        <span class="iconfont">&#xe614;</span>
+        <span>娣诲姞瀛愯处鍙�</span>
+      </div>
+      <div class="button export" @click="isShowRelate = true">
+        <span class="iconfont">&#xe614;</span>
+        <span>鍏宠仈瀛愯处鍙�</span>
+      </div>
+    </div>
+
+    <div class="table-area">
+      <el-table
+        id="multipleTable"
+        ref="multipleTable"
+        tooltip-effect="dark"
+        :data="dataList"
+        :fit="true"
+        :default-sort="{ prop: 'createTime', order: 'descending' }"
+        :stripe="true"
+      >
+        <el-table-column label="搴忓彿" width="55" class-name="index">
+          <template slot-scope="scope">{{
+            scope.$index + 1 + (page - 1) * size
+          }}</template>
+        </el-table-column>
+        <el-table-column
+          prop="name"
+          label="濮撳悕"
+          show-overflow-tooltip
+        ></el-table-column>
+        <el-table-column
+          prop="phone"
+          label="鎵嬫満鍙�"
+          show-overflow-tooltip
+        ></el-table-column>
+        <el-table-column prop="userType" label="鐢ㄦ埛绫诲瀷"></el-table-column>
+        <el-table-column prop="duration" label="鎺堟潈鏃堕暱"></el-table-column>
+        <el-table-column prop="authList" label="鏉冮檺"></el-table-column>
+        <!-- <el-table-column label="瀹夎鏃堕棿" >
+          <template slot-scope="scope">
+            <div v-if="scope.row.installTime.length > 1">
+              <div>{{ scope.row.installTime[0] }}</div>
+              <div>{{ scope.row.installTime[1] }}</div>
+            </div>
+            <div v-else>--</div>
+          </template>
+        </el-table-column> -->
+        <!-- <el-table-column label="棣栨浣跨敤鏃堕棿" >
+          <template slot-scope="scope">
+            <div v-if="scope.row.firstUseTime.length > 1">
+              <div>{{ scope.row.firstUseTime[0] }}</div>
+              <div>{{ scope.row.firstUseTime[1] }}</div>
+            </div>
+            <div v-else>--</div>
+          </template>
+        </el-table-column>
+
+        <el-table-column label="鎵�灞為泦缇�" show-overflow-tooltip >
+          <template> -- </template>
+        </el-table-column> -->
+
+        <el-table-column label="鐘舵��">
+          <template slot-scope="scope">
+            <div v-if="scope.row.isBind == 1" class="status green">宸茬粦瀹�</div>
+            <div v-else class="status">鏈粦瀹�</div>
+          </template>
+        </el-table-column>
+
+        <el-table-column label="鎿嶄綔">
+          <template slot-scope="scope">
+            <!-- 缂栬緫 -->
+            <span class="iconfont option" @click="joinCluster(scope.row)"
+              >&#xe640;</span
+            >
+
+            <!-- 瑙g粦 -->
+            <span class="iconfont option" @click="Untying(scope.row)"
+              >&#xe617;</span
+            >
+          </template>
+        </el-table-column>
+      </el-table>
+      <div>
+        <el-pagination
+          @current-change="refrash"
+          @size-change="handleSizeChange"
+          :current-page="page"
+          :page-size="size"
+          layout="total, sizes, prev, pager, next, jumper"
+          :page-sizes="[5, 10, 15, 20, 25]"
+          :total="total"
+          background
+        ></el-pagination>
+      </div>
+    </div>
+
+    <!-- 瑙g粦寮圭獥 -->
+    <UnbindBox
+      @close="closeUnbindBox"
+      v-if="isShowUnbind"
+      :id="unbindId"
+      @reflash="reflash"
+    ></UnbindBox>
+
+    <!-- 娣诲姞璁惧寮圭獥 -->
+    <!-- <AddBox @close="closeAddBox" v-if="isShowAdd"></AddBox> -->
+
+    <!-- 閫�鍑洪泦缇ゅ脊绐� -->
+    <QuitClusterBox
+      :equipment="activeEquipment"
+      v-if="showQuit"
+      @close="showQuit = false"
+    ></QuitClusterBox>
+
+    <!-- 鍔犲叆闆嗙兢寮圭獥 -->
+    <JoinClusterBox
+      :equipment="activeEquipment"
+      v-if="showJoin"
+      @close="showJoin = false"
+    ></JoinClusterBox>
+  </div>
+  <div class="sub-account" v-else-if="isShowAdd">
+    <div class="add-title" @click="isShowAdd = false">
+      <span class="iconfont">&#xe614;</span>
+      <span>娣诲姞瀛愯处鎴�</span>
+    </div>
+    <el-form
+      :model="ruleForm"
+      :rules="rules"
+      :label-position="'left'"
+      ref="ruleForm"
+      label-width="100px"
+      class="add-ruleForm"
+    >
+      <el-form-item label="鐢ㄦ埛鍚�" prop="name">
+        <el-input v-model="ruleForm.name"></el-input>
+      </el-form-item>
+      <el-form-item label="瀵嗙爜" prop="name">
+        <el-input v-model="ruleForm.password"></el-input>
+      </el-form-item>
+      <el-form-item label="閲嶇疆瀵嗙爜" prop="delivery">
+        <el-checkbox v-model="ruleForm.delivery">棣栨鐧婚檰淇敼瀵嗙爜</el-checkbox>
+      </el-form-item>
+      <el-form-item label="鐢ㄦ埛绫诲瀷" prop="type">
+        <el-radio v-model="ruleForm.type" label="1">涓汉</el-radio>
+        <el-radio v-model="ruleForm.type" label="2">鍏徃</el-radio>
+      </el-form-item>
+      <el-form-item label="濮撳悕" prop="name">
+        <el-input v-model="ruleForm.name"></el-input>
+      </el-form-item>
+      <el-form-item label="閭" prop="name">
+        <el-input v-model="ruleForm.password"></el-input>
+      </el-form-item>
+
+      <el-form-item label="琛屼笟" prop="region">
+        <el-select v-model="ruleForm.region" placeholder="璇烽�夋嫨琛屼笟">
+          <el-option label="鍖哄煙涓�" value="shanghai"></el-option>
+          <el-option label="鍖哄煙浜�" value="beijing"></el-option>
+        </el-select>
+      </el-form-item>
+      <el-form-item label="鍦板尯" prop="region">
+        <el-select v-model="ruleForm.region" placeholder="璇烽�夋嫨琛屼笟">
+          <el-option label="鍖哄煙涓�" value="shanghai"></el-option>
+          <el-option label="鍖哄煙浜�" value="beijing"></el-option>
+        </el-select>
+      </el-form-item>
+      <el-form-item label="鎺堟潈鏃堕暱" prop="region">
+        <el-select v-model="ruleForm.region" placeholder="璇烽�夋嫨琛屼笟">
+          <el-option label="鍖哄煙涓�" value="shanghai"></el-option>
+          <el-option label="鍖哄煙浜�" value="beijing"></el-option>
+        </el-select>
+      </el-form-item>
+
+      <el-form-item label="鐢ㄦ埛鏉冮檺" prop="authList" class="user-tree">
+        
+        <TreeBox :defaultProp="defaultProp1" :treeData="data1"></TreeBox>
+
+       
+        <TreeBox :defaultProp="defaultProp2" :treeData="data2"></TreeBox>
+      </el-form-item>
+      
+    </el-form>
+    <div class="right">
+      <div class="button searchBtn" @click="searchingBtn">鎼滅储</div>
+      <div class="button resetBtn" @click="clearSearch">閲嶇疆</div>
+    </div>
+  </div>
+  <div class="sub-account" v-else-if="isShowRelate">
+    <div class="add-title" @click="goback">
+      <span class="iconfont">&#xe614;</span>
+      <span>鍏宠仈瀛愯处鎴�</span>
+    </div>
+    <Steps
+      :titleList="['鍏宠仈瀛愯处鍙蜂俊鎭�', '鏉冮檺璁剧疆', '瀹屾垚']"
+      :activeIndex="activeIndex"
+    ></Steps>
+    <StepsCard @goback="goback" @goto="goto"></StepsCard>
+  </div>
+</template>
+
+<script>
+import { findDevList } from "@/api/device";
+// import AddBox from "@/views/equipmentManagement/equipmentList/components/AddBox";
+import UnbindBox from "@/views/equipmentManagement/equipmentDetail/components/UnbindBox";
+import QuitClusterBox from "@/views/equipmentManagement/equipmentList/components/QuitClusterBox";
+import JoinClusterBox from "@/views/equipmentManagement/equipmentList/components/JoinClusterBox";
+import Steps from "./Steps";
+import StepsCard from "./StepCard";
+import TreeBox from "./TreeBox";
+export default {
+  components: {
+    // AddBox,
+    UnbindBox,
+    QuitClusterBox,
+    JoinClusterBox,
+    Steps,
+    StepsCard,
+    TreeBox,
+  },
+  data() {
+    return {
+      searchTime: [
+        this.$moment().format("YYYY-MM-DD 00:00:00"),
+        this.$moment().format("YYYY-MM-DD HH:mm:ss"),
+      ], //鎼滅储鏃堕棿
+      page: 1,
+      size: 10, //鍒嗛〉鐩稿叧
+      inputText: "", //杈撳叆妗嗗唴瀹�
+      activeStep: 0,
+      activeIndex: 0,
+      total: 0, //鎬绘暟
+      dataList: [
+        {
+          name: "basic",
+          phone: "1121313232",
+          userType: "涓汉",
+          duration: "姘镐箙",
+          authList: "闆嗙兢1锛岄泦缇�2",
+          isBind: 1,
+        },
+      ],
+      isShowAdd: false, //鏄惁灞曠ず鏂板寮圭獥
+      isShowUnbind: false, //鏄惁灞曠ず瑙g粦寮圭獥
+      isShowRelate: false,
+      unbindId: "",
+      durationArr: [
+        {
+          value: 0,
+          label: "涓�骞�",
+        },
+        {
+          value: 1,
+          label: "涓ゅ勾",
+        },
+      ], //鎵�灞為泦缇や笅鎷夋
+      cluster: null, //閫変腑鐨勯泦缇ょ被鍨�
+      showQuit: false, //灞曠ず閫�鍑洪泦缇ょ殑寮圭獥
+      showJoin: false, //灞曠ず鍔犲叆闆嗙兢鐨勫脊绐�
+      activeEquipment: null, //澶勭悊涓殑璁惧
+      ruleForm: {
+        name: "",
+        region: "",
+        password: "",
+        date1: "",
+        date2: "",
+        delivery: false,
+        type: [],
+        resource: "",
+        desc: "",
+        authList: {
+          menuAuth: [],
+          dataAuth: [],
+        },
+      },
+      rules: {
+        name: [
+          { required: true, message: "璇疯緭鍏ユ椿鍔ㄥ悕绉�", trigger: "blur" },
+          { min: 3, max: 5, message: "闀垮害鍦� 3 鍒� 5 涓瓧绗�", trigger: "blur" },
+        ],
+        region: [
+          { required: true, message: "璇烽�夋嫨娲诲姩鍖哄煙", trigger: "change" },
+        ],
+        date1: [
+          {
+            type: "date",
+            required: true,
+            message: "璇烽�夋嫨鏃ユ湡",
+            trigger: "change",
+          },
+        ],
+        date2: [
+          {
+            type: "date",
+            required: true,
+            message: "璇烽�夋嫨鏃堕棿",
+            trigger: "change",
+          },
+        ],
+        type: [
+          {
+            type: "array",
+            required: true,
+            message: "璇疯嚦灏戦�夋嫨涓�涓椿鍔ㄦ�ц川",
+            trigger: "change",
+          },
+        ],
+        resource: [
+          { required: true, message: "璇烽�夋嫨娲诲姩璧勬簮", trigger: "change" },
+        ],
+        desc: [{ required: true, message: "璇峰~鍐欐椿鍔ㄥ舰寮�", trigger: "blur" }],
+      },
+      data1: [
+        {
+          id: 1,
+          label: "涓�绾� 1",
+          children: [
+            {
+              id: 4,
+              label: "浜岀骇 1-1",
+              children: [
+                {
+                  id: 9,
+                  label: "涓夌骇 1-1-1",
+                },
+                {
+                  id: 10,
+                  label: "涓夌骇 1-1-2",
+                },
+              ],
+            },
+          ],
+        },
+        {
+          id: 2,
+          label: "涓�绾� 2",
+          children: [
+            {
+              id: 5,
+              label: "浜岀骇 2-1",
+            },
+            {
+              id: 6,
+              label: "浜岀骇 2-2",
+            },
+          ],
+        },
+        {
+          id: 3,
+          label: "涓�绾� 3",
+          children: [
+            {
+              id: 7,
+              label: "浜岀骇 3-1",
+            },
+            {
+              id: 8,
+              label: "浜岀骇 3-2",
+            },
+          ],
+        },
+      ],
+      defaultProps1: {
+        children: "children",
+        label: "label",
+      },
+      data2: [
+        {
+          id: 1,
+          label: "涓�绾� 1",
+          children: [
+            {
+              id: 4,
+              label: "浜岀骇 1-1",
+              children: [
+                {
+                  id: 9,
+                  label: "涓夌骇 1-1-1",
+                },
+                {
+                  id: 10,
+                  label: "涓夌骇 1-1-2",
+                },
+              ],
+            },
+          ],
+        },
+        {
+          id: 2,
+          label: "涓�绾� 2",
+          children: [
+            {
+              id: 5,
+              label: "浜岀骇 2-1",
+            },
+            {
+              id: 6,
+              label: "浜岀骇 2-2",
+            },
+          ],
+        },
+        {
+          id: 3,
+          label: "涓�绾� 3",
+          children: [
+            {
+              id: 7,
+              label: "浜岀骇 3-1",
+            },
+            {
+              id: 8,
+              label: "浜岀骇 3-2",
+            },
+          ],
+        },
+      ],
+      defaultProps2: {
+        children: "children",
+        label: "label",
+      },
+    };
+  },
+  methods: {
+    goback() {
+      this.isShowRelate = false;
+      this.activeIndex = 0;
+    },
+    goto(i) {
+      this.activeIndex = i;
+    },
+    // 璺冲埌璁惧璇︽儏
+    checkDetail(row) {
+      this.$router.push({
+        path: "/equipmentDetail",
+        query: {
+          id: row.devId,
+          ip: row.devIp,
+          port: row.serverPort,
+          ndid: row.id,
+        },
+      });
+    },
+
+    // 璺冲埌绠楁硶璇︽儏
+    algorithmDetail(row) {
+      this.$router.push({
+        path: "/algorithmDetail",
+        query: {
+          id: row.devId,
+          ip: row.devIp,
+          port: row.serverPort,
+        },
+      });
+    },
+
+    // 鏌ヨ鍒楄〃
+    searchingBtn() {
+      let param = {
+        page: this.page,
+        size: this.size,
+        // startTime: this.searchTime[0],
+        // endTime: this.searchTime[1],
+        inputText: this.inputText,
+      };
+      findDevList(param)
+        .then((res) => {
+          this.dataList = res.data.list;
+          //鏃堕棿鍒嗚鏄剧ず
+
+          this.dataList.forEach((item) => {
+            item.installTime = item.installTime.split(" ");
+            item.firstUseTime = item.firstUseTime.split(" ");
+          });
+          this.total = res.data.total;
+          if (res.data.total <= this.size) {
+            this.page = 1;
+          }
+        })
+        .catch((err) => {
+          console.log(err);
+        });
+    },
+
+    //鍒嗛〉鍔熻兘
+    handleSizeChange(size) {
+      this.size = size;
+      this.searchingBtn();
+    },
+    //鍒嗛〉鍔熻兘
+    refrash(page) {
+      this.page = page;
+      this.searchingBtn();
+    },
+
+    //瑙g粦鎸夐挳
+    Untying(row) {
+      console.log(row);
+      this.unbindId = row.id;
+      this.isShowUnbind = true;
+    },
+
+    //鑾峰緱榛樿鏃堕棿
+    getDateInit() {
+      // 瑕佹眰 榛樿涓�涓湀
+      const end = new Date();
+      const start = new Date();
+      const nowDate = new Date();
+      nowDate.setHours(0);
+      nowDate.setMinutes(0);
+      nowDate.setSeconds(0);
+      nowDate.setMilliseconds(0);
+      start.setTime(nowDate.getTime() - 3600 * 1000 * 24 * 30);
+      end.setTime(nowDate.getTime() + 3600 * 1000 * 24 - 1);
+      return [
+        this.$moment(start).format("YYYY-MM-DD HH:mm:ss"),
+        this.$moment(end).format("YYYY-MM-DD HH:mm:ss"),
+      ];
+    },
+
+    //鍏抽棴鏂板寮圭獥
+    closeAddBox() {
+      this.isShowAdd = false;
+    },
+    // 鍏抽棴瑙g粦寮圭獥
+    closeUnbindBox() {
+      this.isShowUnbind = false;
+    },
+
+    //瑙g粦鎴愬姛鍥炶皟
+    reflash() {
+      this.isShowUnbind = false;
+      this.searchingBtn();
+    },
+
+    clearSearch() {
+      this.searchTime = this.getDateInit();
+      this.inputText = "";
+      this.searchingBtn();
+    },
+
+    //閫�鍑洪泦缇�
+    quitCluster(equipment) {
+      this.activeEquipment = equipment;
+      this.showQuit = true;
+    },
+
+    //鍔犲叆闆嗙兢
+    joinCluster(equipment) {
+      this.activeEquipment = equipment;
+      this.showJoin = true;
+    },
+  },
+  mounted() {
+    this.searchTime = this.getDateInit();
+    this.searchingBtn();
+  },
+};
+</script>
+
+<style scoped lang="scss">
+.sub-account {
+  padding: 20px;
+  .head-name {
+    font-weight: 700;
+    font-size: 16px;
+    line-height: 22px;
+    color: #3d3d3d;
+    border-left: 4px solid #0065ff;
+    padding-left: 10px;
+  }
+  .add-title {
+    font-weight: 700;
+    font-size: 16px;
+    cursor: pointer;
+    line-height: 22px;
+    color: #3d3d3d;
+    margin-bottom: 30px;
+    .iconfont {
+      margin-right: 10px;
+    }
+  }
+  .steps {
+  }
+  .add-ruleForm::v-deep {
+    .el-input__inner {
+      width: 350px;
+      color: #3d3d3d;
+      border-radius: 4px;
+      border-color: #c0c5cc;
+      height: 32px;
+      line-height: 32px;
+      border-color: #c0c5cc;
+    }
+    .user-tree {
+      .el-form-item__content {
+        display: flex;
+        .tree-box {
+          .t {
+            height: 32px;
+            background: #f0f5fa;
+            border-radius: 3px 3px 0px 0px;
+            line-height: 32px;
+            text-align: center;
+            border-bottom: 1px solid #c0c5cc;
+          }
+          width: 336px;
+          height: 480px;
+          border: 1px solid #c0c5cc;
+          margin-right: 20px;
+          box-sizing: border-box;
+        }
+      }
+    }
+  }
+  .searchBtn {
+    width: 60px;
+    height: 32px;
+    line-height: 32px;
+    text-align: center;
+    color: #fff;
+    background: #0065ff;
+    margin-right: 20px;
+  }
+  .right {
+    display: flex;
+  }
+  .resetBtn {
+    width: 60px;
+    height: 32px;
+    line-height: 32px;
+    text-align: center;
+    color: #0065ff;
+    box-sizing: border-box;
+    border: 1px solid #0065ff;
+  }
+  .search {
+    display: flex;
+    font-size: 14px;
+    border-bottom: 1px solid #e9ebee;
+    margin-top: 30px;
+    padding-bottom: 20px;
+    .left,
+    .right,
+    .id,
+    .time,
+    .cluster {
+      display: flex;
+      align-items: center;
+      .el-select {
+        width: auto;
+      }
+    }
+
+    .id .el-input ::v-deep {
+      width: 200px;
+    }
+
+    .cluster::v-deep .el-input {
+      width: 300px;
+
+      margin-left: 10px;
+      margin-right: 20px;
+      .el-input__icon {
+        line-height: 32px;
+      }
+      input {
+        border-radius: 0;
+
+        &::-webkit-input-placeholder {
+          color: #999;
+        }
+
+        &:focus {
+          border-color: #0065ff;
+        }
+      }
+    }
+
+    .el-input ::v-deep {
+      width: 200px;
+      margin-left: 10px;
+      margin-right: 20px;
+      height: 32px;
+      line-height: 32px;
+      input {
+        border-radius: 0;
+        height: 32px;
+        line-height: 32px;
+        &::-webkit-input-placeholder {
+          color: #999;
+        }
+
+        &:focus {
+          border-color: #0065ff;
+        }
+      }
+    }
+
+    .el-date-editor {
+      width: 318px;
+      height: 40px;
+      margin-left: 10px;
+      margin-right: 20px;
+      border-radius: 0;
+
+      &::-webkit-input-placeholder {
+        color: #999;
+      }
+
+      &.is-active {
+        border-color: #0065ff;
+      }
+    }
+  }
+
+  .btns {
+    display: flex;
+    margin: 20px 0;
+    text-align: center;
+    .add {
+      margin-right: 20px;
+      width: 126px;
+      height: 32px;
+      background: #0065ff;
+      color: #fff;
+      span {
+        margin-right: 5px;
+        line-height: 32px;
+        font-size: 14px;
+      }
+    }
+
+    .export {
+      width: 126px;
+      height: 32px;
+      border: 1px solid #0065ff;
+      color: #0065ff;
+      box-sizing: border-box;
+      span {
+        margin-right: 5px;
+        line-height: 32px;
+        font-size: 14px;
+      }
+    }
+  }
+
+  .el-table ::v-deep {
+    background-color: rgb(233, 235, 238);
+    padding: 1px;
+
+    &::after {
+      display: none;
+    }
+
+    td.index .cell {
+      padding-left: 16px;
+      padding-right: 4px;
+    }
+
+    .has-gutter tr th {
+      background: #f0f3f5;
+      font-size: 16px;
+      color: #3d3d3d;
+      font-weight: 700;
+    }
+
+    td .cell {
+      color: #3d3d3d;
+    }
+
+    tr:hover > td.el-table__cell {
+      background-color: #fff;
+    }
+
+    .el-table__row--striped .el-table__cell {
+      background-color: #f0f5fa !important;
+    }
+    tr:hover > td.el-table__cell {
+      background-color: #fff;
+    }
+
+    .el-table__row--striped .el-table__cell {
+      background-color: #f0f5fa !important;
+    }
+
+    .status {
+      color: #ff4b33;
+
+      &.green {
+        color: #36b24a;
+      }
+    }
+
+    .option {
+      margin-right: 10px;
+      font-size: 24px;
+      color: rgb(0, 101, 255);
+      cursor: pointer;
+    }
+  }
+
+  .el-pagination ::v-deep {
+    margin-top: 30px;
+    text-align: center;
+    height: 24px;
+    .el-pagination__sizes {
+      margin-right: 0;
+    }
+
+    button {
+      margin: 0;
+      background-color: #fff;
+      border: 1px solid #c0c5cc;
+      border-radius: 2px;
+    }
+
+    .number {
+      background-color: #fff;
+
+      &:not(.disabled):hover {
+        color: #0065ff;
+      }
+
+      &:not(.disabled).active {
+        background-color: #0065ff;
+        color: #fff;
+      }
+    }
+
+    .el-input .el-input__inner {
+      padding-left: 0;
+
+      &:hover,
+      &:focus {
+        border-color: #0065ff;
+      }
+    }
+  }
+}
+</style>
+
+<style >
+.el-date-table td.start-date span,
+.el-date-table td.end-date span {
+  background-color: #0065ff;
+}
+
+.el-button--text span {
+  color: #0065ff;
+}
+
+.el-button.is-plain:hover,
+.el-button.is-plain:focus {
+  color: #0065ff;
+  border-color: #0065ff;
+}
+</style>
\ No newline at end of file
diff --git a/src/views/personalCenter/components/TreeBox.vue b/src/views/personalCenter/components/TreeBox.vue
new file mode 100644
index 0000000..8ee0c96
--- /dev/null
+++ b/src/views/personalCenter/components/TreeBox.vue
@@ -0,0 +1,49 @@
+<template>
+  <div class="tree-box">
+    <div class="t">鏁版嵁鏉冮檺</div>
+    <el-tree
+      :data="treeData"
+      show-checkbox
+      :default-expand-all="true"
+      node-key="id"
+      :props="defaultProps"
+    >
+    </el-tree>
+      <!-- :default-checked-keys="[5]" -->
+      <!-- :default-expanded-keys="[2, 3]" -->
+  </div>
+</template>
+
+<script>
+export default {
+  created() {},
+  mounted() {},
+  props: {
+    treeData: Array,
+    defaultProps:Object,
+  },
+  data() {
+    return {};
+  },
+
+  methods: {},
+};
+</script>
+
+<style scoped lang="scss">
+.tree-box {
+  .t {
+    height: 32px;
+    background: #f0f5fa;
+    border-radius: 3px 3px 0px 0px;
+    line-height: 32px;
+    text-align: center;
+    border-bottom: 1px solid #c0c5cc;
+  }
+  width: 336px;
+  height: 480px;
+  border: 1px solid #c0c5cc;
+  margin-right: 20px;
+  box-sizing: border-box;
+}
+</style>
\ No newline at end of file
diff --git a/src/views/personalCenter/index.vue b/src/views/personalCenter/index.vue
new file mode 100644
index 0000000..e1f1040
--- /dev/null
+++ b/src/views/personalCenter/index.vue
@@ -0,0 +1,49 @@
+<template>
+  <div class="personalCenter">
+    <!-- 椤靛ご -->
+    <IndexHeader :opacity="false"></IndexHeader>
+    <!-- 闈㈠寘灞� -->
+    <!-- <div class="heart">
+      <el-breadcrumb separator=">">
+        <el-breadcrumb-item>绠$悊涓績</el-breadcrumb-item>
+        <el-breadcrumb-item>璁惧绠$悊</el-breadcrumb-item>
+      </el-breadcrumb>
+    </div> -->
+
+    <!-- 涓昏鍐呭 -->
+    <Content></Content>
+
+    <!-- 椤靛熬 -->
+    <Footer :isBlack="true"></Footer>
+  </div>
+</template>
+
+<script>
+import IndexHeader from "@/components/IndexHeader";
+import Content from "./components/Content";
+import Footer from "@/components/Footer";
+
+export default {
+  components: {
+    IndexHeader,
+    Content,
+    Footer,
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+.personalCenter {
+  background-color: rgb(243, 245, 248);
+  height: 100%;
+
+  .el-breadcrumb {
+    margin-top: 48px;
+    margin-bottom: 24px;
+
+    ::v-deep span {
+      color: #666;
+    }
+  }
+}
+</style>
\ No newline at end of file

--
Gitblit v1.8.0