From 5f0ba4bd0c69fd1ebcad122a2dcab8840d929188 Mon Sep 17 00:00:00 2001
From: ZZJ <zzjdsg2300@163.com>
Date: 星期五, 10 十二月 2021 18:24:46 +0800
Subject: [PATCH] 登录前配置页

---
 src/pages/login/api.ts                     |   66 +
 vue.config.js                              |    4 
 src/pages/index/components/formAccount.vue |  134 +++
 src/pages/index/components/formNet.vue     |  141 +++
 src/pages/login/App.vue                    |  564 ++++++++++++
 src/pages/login/main.ts                    |   18 
 /dev/null                                  |    0 
 src/pages/index/components/formInfo.vue    |  259 +++++
 src/pages/index/App.vue                    |  757 +++++-----------
 src/pages/index/api.ts                     |  111 +-
 src/pages/index/components/IPInput.vue     |  238 +++++
 public/images/init/背景图.png                 |    0 
 src/pages/login/ParticleNetwork.vue        |  348 +++++++
 13 files changed, 2,058 insertions(+), 582 deletions(-)

diff --git "a/public/images/init/\350\203\214\346\231\257\345\233\276.png" "b/public/images/init/\350\203\214\346\231\257\345\233\276.png"
new file mode 100644
index 0000000..4ccfa0c
--- /dev/null
+++ "b/public/images/init/\350\203\214\346\231\257\345\233\276.png"
Binary files differ
diff --git a/public/images/login/0.png b/public/images/login/0.png
deleted file mode 100644
index 2a3591c..0000000
--- a/public/images/login/0.png
+++ /dev/null
Binary files differ
diff --git a/public/images/login/1.png b/public/images/login/1.png
deleted file mode 100644
index 1473d0f..0000000
--- a/public/images/login/1.png
+++ /dev/null
Binary files differ
diff --git a/public/images/login/10.png b/public/images/login/10.png
deleted file mode 100644
index 4deae39..0000000
--- a/public/images/login/10.png
+++ /dev/null
Binary files differ
diff --git a/public/images/login/11.png b/public/images/login/11.png
deleted file mode 100644
index 65b81f6..0000000
--- a/public/images/login/11.png
+++ /dev/null
Binary files differ
diff --git a/public/images/login/12.png b/public/images/login/12.png
deleted file mode 100644
index e966939..0000000
--- a/public/images/login/12.png
+++ /dev/null
Binary files differ
diff --git a/public/images/login/13.png b/public/images/login/13.png
deleted file mode 100644
index c4b1707..0000000
--- a/public/images/login/13.png
+++ /dev/null
Binary files differ
diff --git a/public/images/login/14.png b/public/images/login/14.png
deleted file mode 100644
index 81a9916..0000000
--- a/public/images/login/14.png
+++ /dev/null
Binary files differ
diff --git a/public/images/login/15.png b/public/images/login/15.png
deleted file mode 100644
index ff5110c..0000000
--- a/public/images/login/15.png
+++ /dev/null
Binary files differ
diff --git a/public/images/login/2.png b/public/images/login/2.png
deleted file mode 100644
index ef567b2..0000000
--- a/public/images/login/2.png
+++ /dev/null
Binary files differ
diff --git a/public/images/login/3.png b/public/images/login/3.png
deleted file mode 100644
index fea5da6..0000000
--- a/public/images/login/3.png
+++ /dev/null
Binary files differ
diff --git a/public/images/login/4.png b/public/images/login/4.png
deleted file mode 100644
index edcf594..0000000
--- a/public/images/login/4.png
+++ /dev/null
Binary files differ
diff --git a/public/images/login/5.png b/public/images/login/5.png
deleted file mode 100644
index f81bbbc..0000000
--- a/public/images/login/5.png
+++ /dev/null
Binary files differ
diff --git a/public/images/login/6.png b/public/images/login/6.png
deleted file mode 100644
index f8c318a..0000000
--- a/public/images/login/6.png
+++ /dev/null
Binary files differ
diff --git a/public/images/login/7.png b/public/images/login/7.png
deleted file mode 100644
index 3352e3c..0000000
--- a/public/images/login/7.png
+++ /dev/null
Binary files differ
diff --git a/public/images/login/8.png b/public/images/login/8.png
deleted file mode 100644
index bd1ab6d..0000000
--- a/public/images/login/8.png
+++ /dev/null
Binary files differ
diff --git a/public/images/login/9.png b/public/images/login/9.png
deleted file mode 100644
index 04d1128..0000000
--- a/public/images/login/9.png
+++ /dev/null
Binary files differ
diff --git a/src/pages/index/App.vue b/src/pages/index/App.vue
index 6754bff..5fc814d 100644
--- a/src/pages/index/App.vue
+++ b/src/pages/index/App.vue
@@ -1,564 +1,271 @@
 <template>
-  <!-- <div class v-loading="vLoading" :style="`width: ${currentWidth}px;height:${currentHeight}px`">
-    <div class="web-site">
-      <a href="http://www.smartai.com" target="_blank">www.smartai.com</a>
-    </div>
+  <div class="init" v-if="!isWhite">
+    <div class="content">
+      <div class="title">娆㈣繋娉ㄥ唽Smart AI 浜哄伐鏅鸿兘鎿嶄綔绯荤粺</div>
+      <el-steps :active="active" finish-status="success" :align-center="true">
+        <el-step title="鍒涘缓璐﹀彿"></el-step>
+        <el-step title="閰嶇疆缃戠粶"></el-step>
+        <el-step title="娉ㄥ唽淇℃伅"></el-step>
+      </el-steps>
 
-    <lang-select class="lang-select"/>
-    <licence />
-    <div class="right-bg" style>
-      <particle-network />
-    </div>
-    <div class="left-bg">
-      <div class="login-logo">
-        <img src="/images/login-logo.png" alt width="105px" height="105px" />
-      </div>
-      <div class="login-com">
-        <span>{{ $t('login.company') }}</span>
-      </div>
-      <div class="login-form">
-        <el-form
-          :model="user"
-          status-icon
-          :rules="nullRule"
-          :validate-on-rule-change="false"
-          ref="ruleForm"
-          class="demo-ruleForm"
-        >
-          <el-form-item prop="loginName">
-            <el-input v-model="user.loginName" style="width:280px" :placeholder="$t('placeholder.enterUsername')">
-              <i slot="prefix" class="iconfont iconyonghu1"></i>
-            </el-input>
-          </el-form-item>
-          <el-form-item prop="password">
-            <el-input
-              show-password
-              @keyup.enter.native="systemLogin()"
-              v-model="user.password"
-              autocomplete="off"
-              style="width:280px"
-              :placeholder="$t('placeholder.enterPassword')"
-            >
-              <i slot="prefix" class="iconfont iconmima"></i>
-            </el-input>
-          </el-form-item>
-          <el-form-item>
-            <el-button ref="submit" type="warning" @click="systemLogin()" style="width:280px">{{ $t('button.login') }}</el-button>
-          </el-form-item>
-        </el-form>
-      </div>
-      <p class="gradient-text gradient-text-one">
-        鈥斺��
-        <b>SmartAI</b> {{ $t('login.aios') }} 鈥斺��
-      </p>
-      <p
-        class="gradient-text gradient-text-one"
-        style="letter-spacing: 1.8px;font-size:15px;"
-      >V1.0.0</p>
-    </div>
-  </div> -->
-  <div class="login">
-    <div class="title">
-      <div class="en">Smart AI</div>
-      <div class="ch">浜哄伐鏅鸿兘鎿嶄綔绯荤粺</div>
-    </div>
-
-    <div class="left_footer">
-      <img class="logo" src="/images/login/LOGO.png" alt="" />
-      <div class="web">www.smartai.com</div>
-    </div>
-
-    <div
-      class="login-form"
-      :style="{ background: backgroundColor }"
-      :class="{ empty: !user.loginName && !user.password }"
-    >
-      <img class="logo" src="/images/login/OS.png" alt="" />
-
-      <el-form
-        :model="user"
-        status-icon
-        :rules="nullRule"
-        :validate-on-rule-change="false"
-        ref="ruleForm"
-        class="demo-ruleForm"
+      <el-carousel
+        ref="carousel"
+        trigger="click"
+        height="480px"
+        :loop="false"
+        :autoplay="false"
+        :initial-index="active"
       >
-        <el-form-item prop="loginName">
-          <el-input
-            v-model="user.loginName"
-            :placeholder="$t('placeholder.enterUsername')"
-          >
-            <i slot="prefix" class="iconfont icon">&#xe7e5;</i>
-          </el-input>
-        </el-form-item>
-        <el-form-item prop="password">
-          <el-input
-            show-password
-            @keyup.enter.native="systemLogin()"
-            v-model="user.password"
-            autocomplete="off"
-            :placeholder="$t('placeholder.enterPassword')"
-          >
-            <i slot="prefix" class="iconfont icon">&#xe7e4;</i>
-          </el-input>
-        </el-form-item>
-        <el-form-item>
-          <el-button ref="submit" type="warning" @click="systemLogin()">{{
-            $t("button.login")
-          }}</el-button>
-        </el-form-item>
-      </el-form>
+        <el-carousel-item>
+          <formAccount ref="form0"></formAccount>
+        </el-carousel-item>
+        <el-carousel-item>
+          <formNet ref="form1"></formNet>
+        </el-carousel-item>
+        <el-carousel-item>
+          <formInfo ref="form2"></formInfo>
+        </el-carousel-item>
+      </el-carousel>
+
+      <div class="control">
+        <div class="pre" @click="preForm">涓婁竴姝�</div>
+        <div class="next" @click="nextForm" v-if="active == 0">涓嬩竴姝�</div>
+        <div class="next" @click="nextForm" v-if="active == 1">璺宠繃</div>
+        <div class="next" @click="nextForm" v-if="active == 2">瀹屾垚</div>
+      </div>
     </div>
   </div>
+  <div class="white" v-else></div>
 </template>
 
 <script>
-import { tologin, getLoginUserData, getServerName } from "./api.ts";
-import ParticleNetwork from "./ParticleNetwork";
-import Licence from "@/components/licence";
-import LangSelect from "@/components/langSelect";
-import { getMenuListData } from "@/api/utils";
+import formAccount from "@/pages/index/components/formAccount";
+import formNet from "@/pages/index/components/formNet";
+import formInfo from "@/pages/index/components/formInfo";
+import {
+  getInitInfo,
+  savePassword,
+  initNetwork,
+  saveRegInfo,
+  getRegInfo,
+} from "./api";
 
 export default {
-  name: "login-pgae",
-  metaInfo: {
-    title: "鐧诲綍椤�",
+  created() {
+    this.getInitInfo();
+  },
+  data() {
+    return {
+      active: 0,
+      formData: {},
+      isWhite: true,
+    };
   },
   components: {
-    //  ParticleNetwork,
-    // Licence,
-    //  LangSelect
-  },
-  computed: {
-    rules() {
-      return {
-        loginName: [
-          {
-            required: true,
-            message: this.$t("placeholder.enterUsername"),
-            trigger: "change",
-          },
-        ],
-        password: [
-          {
-            required: true,
-            message: this.$t("placeholder.enterPassword"),
-            trigger: "change",
-          },
-        ],
-      };
-    },
-  },
-  data: () => ({
-    serverTitle: "",
-    user: {
-      loginName: "",
-      password: "",
-      rememberMe: false,
-    },
-    nullRule: {},
-
-    loading: "",
-    vLoading: false,
-    currentHeight: 1057,
-    currentWidth: 1920,
-    backgroundColor: "",
-    backgroundList: [
-      "#2A2344",
-      "#342344",
-      "#000000",
-      "#233044",
-      "#0B252E",
-      "#150051",
-      "#110040",
-    ],
-  }),
-  created() {
-    this.getServerName();
-    this.getScreenHeight();
-    this.backgroundColor =
-      this.backgroundList[
-        Math.floor(Math.random() * this.backgroundList.length)
-      ];
-  },
-  mounted() {
-    // 鑷姩鐧诲綍鎺ュ彛
-    this.loginRobot();
-  },
-  watch: {},
-  beforeDestroy() {
-    window.onresize = null;
+    formAccount,
+    formNet,
+    formInfo,
   },
   methods: {
-    loginRobot() {
-      // 瑙f瀽璺敱鍙傛暟锛屽苟缂撳瓨
-      let user = this.getQueryVariable("username");
-      let passwd = this.getQueryVariable("password");
-      if (user.length && passwd.length) {
-        sessionStorage.setItem(
-          "autoLogin",
-          JSON.stringify({ username: user, passwd: passwd })
-        );
-
-        this.user.loginName = user;
-        this.user.password = passwd;
-        this.systemLogin();
+    preForm() {
+      if (this.active == 0) {
+        return;
+      }
+      this.active--;
+      this.$refs["carousel"].prev();
+    },
+    async nextForm() {
+      if (this.active == 2) {
+        const data = this.$refs[`form${this.active}`].getFormData();
+        await saveRegInfo(data);
+        location.assign("/login");
         return;
       }
 
-      // 鐧婚檰瓒呮椂鍚庣殑閲嶆柊鐧婚檰
-      let sessionInfo = sessionStorage.getItem("autoLogin");
-      if (sessionInfo) {
-        let authority = JSON.parse(sessionInfo);
-        this.user.loginName = authority.username;
-        this.user.password = authority.passwd;
-        this.systemLogin();
+      if (this.active == 0) {
+        const data = this.$refs[`form${this.active}`].getFormData();
+        if (!data) {
+          return false;
+        }
+        const res1 = await savePassword(data);
+        console.log(data);
       }
-    },
-    systemLogin() {
-      this.nullRule = this.rules;
-      this.$nextTick(() => {
-        this.$refs["ruleForm"].validate((valid) => {
-          if (valid) {
-            this.loading = this.$loading({
-              lock: true,
-              text: "Loading",
-              spinner: "el-icon-loading",
-              background: "rgba(0, 0, 0, 0.7)",
-            });
-            this.testLogin();
-          } else {
-            this.nullRule = {};
-          }
-        });
-        this.nullRule = {};
-      });
-    },
-    async testLogin() {
-      // location.assign("/view/desktop/")
-      tologin({ username: this.user.loginName, password: this.user.password })
-        .then((json) => {
-          const loginedInfo = {
-            access_token: json.token_type + " " + json.access_token,
-            refresh_token: json.refresh_token,
-          };
-          sessionStorage.setItem("expires_in", json.expires_in);
-          sessionStorage.setItem("loginedInfo", JSON.stringify(loginedInfo));
-          this.loading.close();
-          this.getLoginUserData();
-        })
-        .catch((err) => {
-          this.loading.close();
-          this.$notify({
-            title: "鎻愮ず",
-            type: "error",
-            message: err.msg,
-          });
-          this.$refs.pwd.focus();
-        });
-    },
-    async getLoginUserData() {
-      let res = await getLoginUserData();
-      if (res.success) {
-        sessionStorage.setItem("userInfo", JSON.stringify(res.data));
-        this.$notify.success("鐧诲綍鎴愬姛锛�");
-        // 鑾峰彇鏉冮檺
-        await this.getMenuList();
-        location.assign("/view/desktop/");
-        return res.data;
-      } else {
-        this.$notify.error("鐧诲綍澶辫触锛�");
-      }
-    },
 
-    getScreenHeight() {
-      this.currentHeight = document.documentElement.clientHeight;
-      this.currentWidth = document.documentElement.clientWidth;
-      window.onresize = () => {
-        this.currentHeight = document.documentElement.clientHeight;
-        this.currentWidth = document.documentElement.clientWidth;
-        this.$forceUpdate();
-      };
-    },
-    async getServerName() {
-      let res = await getServerName();
-      if (res && res.success) {
-        this.serverTitle = res.data.serverName;
-        window.document.title = res.data.serverName
-          ? res.data.serverName
-          : "SmartAI";
-        sessionStorage.setItem("title", res.data.serverName);
+      if (this.active == 1) {
+        const data = this.$refs[`form${this.active}`].getFormData();
+        await initNetwork(data);
+        console.log(data);
       }
+
+      this.active++;
+      this.$refs["carousel"].next();
     },
-    async getMenuList() {
-      let results = await getMenuListData({});
-      if (results && results.success) {
-        /* 瀛樺偍鏉冮檺 */
-        let buttonAuthoritys = results.data;
-        if (results && results.length && this.$route.query.is_login) {
-          this.$router.replace(results[0].url);
-        }
-        sessionStorage.setItem(
-          "buttonAuthoritys",
-          "," + buttonAuthoritys + ","
-        );
-        sessionStorage.setItem("menuInfo", JSON.stringify(results));
-      } else {
-        this.$toast({
-          type: "error",
-          message: "鑿滃崟鑾峰彇澶辫触",
-        });
+    async getInitInfo() {
+      const res = await getInitInfo();
+
+      if (res.data.initPwd && !res.data.initRegInfo) {
+        const res1 = await getRegInfo();
+        this.active = 1;
+        this.$refs["carousel"].setActiveItem(1);
       }
-    },
-    getQueryVariable(variable) {
-      var query = window.location.search.substring(1);
-      var vars = query.split("&");
-      for (var i = 0; i < vars.length; i++) {
-        var pair = vars[i].split("=");
-        if (pair[0] == variable) {
-          return pair[1];
-        }
+
+      if (res.data.initPwd && res.data.initRegInfo) {
+        location.assign("/login");
+        return;
       }
-      return false;
+
+      this.isWhite = false;
     },
   },
 };
 </script>
-<style lang="scss">
-.login {
+
+<style lang="scss" scoped>
+.init {
   height: 100%;
-  position: relative;
-  background-image: url("/images/login/鑳屾櫙鍥�.png");
+  background-image: url("/images/init/鑳屾櫙鍥�.png");
+  color: #fff;
+  user-select: none;
 
-  .title {
-    position: absolute;
-    top: 345px;
-    left: 301px;
-    color: #fff;
-    text-align: center;
+  .content {
+    margin: 0 auto;
+    width: 1000px;
+    padding-top: 80px;
 
-    .en {
-      font-size: 120px;
-    }
-
-    .ch {
-      font-size: 48px;
-      letter-spacing: 9px;
-    }
-  }
-
-  .left_footer {
-    position: absolute;
-    display: flex;
-    justify-content: start;
-    align-items: center;
-    left: 358px;
-    bottom: 40px;
-
-    .logo {
-      width: 136px;
-      margin-right: 30px;
-    }
-
-    .web {
-      font-size: 24px;
+    .title {
+      font-size: 28px;
       font-weight: 700;
-      color: rgba(255, 255, 255, 0.7);
+      margin-bottom: 50px;
+      letter-spacing: 5px;
+    }
+
+    .el-steps ::v-deep {
+      margin-left: 22px;
+      text-align: left;
+
+      .el-step__icon {
+        width: 48px;
+        height: 48px;
+      }
+
+      .el-step__line {
+        left: 210px;
+        right: -110px;
+        border: 0.5px solid #fff;
+        border-bottom: none;
+        border-top: none;
+        opacity: 0.1;
+        top: 22px;
+      }
+
+      .is-success .el-step__icon {
+        background: none;
+        border: 2px solid rgba(255, 255, 255, 0.3);
+
+        .el-icon-check::before {
+          color: #fff;
+          font-size: 24px;
+          font-weight: 700;
+        }
+      }
+
+      .is-process .el-step__icon {
+        background-color: rgba(255, 255, 255, 0.3);
+        border: none;
+
+        .el-step__icon-inner {
+          color: #fff;
+          font-size: 24px;
+          font-weight: 700;
+        }
+      }
+
+      .is-wait .el-step__icon {
+        border: 2px solid rgba(255, 255, 255);
+        opacity: 0.5;
+        background: none;
+
+        .el-step__icon-inner {
+          color: #fff;
+          font-size: 24px;
+          font-weight: 700;
+        }
+      }
+
+      .el-step__main {
+        margin-top: 20px;
+        .is-success,
+        .is-process {
+          font-size: 16px;
+          color: #fff;
+          font-weight: normal;
+        }
+
+        .is-wait {
+          font-size: 16px;
+          color: #fff;
+          font-weight: normal;
+          opacity: 0.5;
+        }
+      }
+    }
+
+    .formAccount {
+      margin-top: 157px;
+      margin-left: 200px;
+      width: 550px;
+    }
+
+    .formNet,
+    .formInfo {
+      margin-top: 90px;
+      margin-left: 200px;
+      width: 550px;
+    }
+
+    .control {
+      position: fixed;
+      display: flex;
+      justify-content: center;
+      align-items: center;
+      bottom: 258px;
+      left: 0;
+      right: 0;
+      line-height: 40px;
+      .pre {
+        margin-right: 20px;
+        cursor: pointer;
+        width: 260px;
+        height: 40px;
+        border: 2px solid rgba(255, 255, 255, 0.3);
+        border-radius: 20px;
+        font-weight: bold;
+        color: #ffffff;
+      }
+
+      .next {
+        cursor: pointer;
+        width: 260px;
+        height: 40px;
+        background: rgba(255, 255, 255, 0.3);
+        border-radius: 20px;
+        font-weight: bold;
+        color: #ffffff;
+      }
     }
   }
 
-  .login-form {
-    position: absolute;
-    width: 780px;
-    height: 1000px;
-    right: 40px;
-    top: 40px;
-    padding: 0 90px;
-    box-sizing: border-box;
-
-    background: #2a2344;
-    opacity: 0.95;
-    box-shadow: -4px 0px 10px rgba(0, 0, 0, 0.25);
-    border-radius: 56px;
-
-    .logo {
-      margin-top: 100px;
-      margin-bottom: 16px;
-    }
-
-    .el-form-item {
-      background: rgba(0, 0, 0, 0);
-    }
-
-    .el-form-item:nth-child(2) {
-      margin-top: 60px;
-      margin-bottom: 80px;
-    }
-
-    .el-button {
-      width: 600px;
-      height: 60px;
-      background: #4e94ff;
-      border-radius: 30px;
-      border: none;
-    }
-
-    .el-input {
-      width: 100%;
-      background: rgba(0, 0, 0, 0);
-    }
-
-    input {
-      width: 100%;
-      height: 56px;
-      background: rgba(255, 255, 255, 0.1) !important;
-      border: 1px solid #4e94ff;
-      box-sizing: border-box;
-      border-radius: 28px;
-      color: #fff;
-      caret-color: #fff; //鍏夋爣棰滆壊
-      padding-left: 100px;
-      padding-right: 50px;
-      font-weight: 700;
-    }
-
-    input:-webkit-autofill,
-    textarea:-webkit-autofill,
-    select:-webkit-autofill {
-      -webkit-text-fill-color: #ededed !important;
-      -webkit-box-shadow: 0 0 0px 1000px transparent inset !important;
-      background-color: transparent;
-      background-image: none;
-      transition: background-color 50000s ease-in-out 0s; //鑳屾櫙鑹查�忔槑  鐢熸晥鏃堕暱  杩囨浮鏁堟灉  鍚敤鏃跺欢杩熺殑鏃堕棿
-    }
-
-    .el-form-item__error {
-      top: 110%;
-      left: 80px;
-    }
-
-    .icon {
-      font-size: 32px;
-      color: rgb(80, 151, 255);
-    }
-
-    .el-input__prefix {
-      padding: 0 20px;
-      height: 40px;
-      left: 5px;
-      top: 8px;
-      border-right: 1px solid #4e94ff;
-    }
-
-    .el-input__suffix {
-      right: 20px;
-    }
-
-    .el-icon-circle-close {
-      display: none;
-    }
+  ::v-deep .el-carousel__indicators {
+    display: none;
   }
 
-  .login-form.empty {
-    input {
-      border-color: #999;
-      color: #bbb;
-    }
-
-    .el-button {
-      background-color: #999;
-      color: #fff;
-    }
-
-    .icon {
-      color: #fff;
-    }
-
-    .el-input__prefix {
-      border-color: #d4d6d9;
-    }
+  ::v-deep .el-carousel__container button {
+    display: none;
   }
 }
 
-// .right-bg {
-//   position: fixed;
-//   top: 0;
-//   left: 0;
-//   background-image: url("/images/login-net.png");
-
-//   width: 100%;
-//   height: 100%;
-//   min-width: 1000px;
-//   z-index: -10;
-//   zoom: 1;
-//   background-color: #fff;
-//   background-repeat: no-repeat;
-//   background-size: cover;
-//   -webkit-background-size: cover;
-//   -o-background-size: cover;
-//   background-position: center 0;
-// }
-// .web-site {
-//   position: absolute;
-//   top: 55px;
-//   left: 41px;
-//   font-family: PingFangSC-Medium;
-//   font-size: 20px;
-//   color: #6170e1;
-//   letter-spacing: 6.15px;
-// }
-// .lang-select {
-//   float: right;
-//   color: white !important;
-//   font-size: 14px;
-//   margin: 13px;
-//   cursor: pointer;
-// }
-// .left-bg {
-//   position: absolute;
-//   top: 29%;
-//   right: 18%;
-//   width: 390px;
-//   height: 426px;
-//   background: rgba(146, 208, 255, 0.23);
-//   border-radius: 4px;
-//   text-align: center;
-//   .login-logo {
-//     margin-top: -53px;
-//   }
-
-//   .login-com {
-//     font-family: PingFangSC-Medium;
-//     font-size: 22px;
-//     color: #ffffff;
-//     letter-spacing: 0.44px;
-//     margin: 15px;
-//   }
-//   .login-form {
-//     margin: 40px 10px;
-//   }
-//   .gradient-text {
-//     line-height: 36px;
-//     font-size: 17px;
-//     font-family: -webkit-pictograph;
-//     font-weight: bolder;
-//     position: relative;
-//     b {
-//       font-size: 20px;
-//     }
-//   }
-//   .gradient-text-one {
-//     background-image: linear-gradient(to right, #51feff 5%, #ff8725 100%);
-//     -webkit-background-clip: text;
-//     -webkit-text-fill-color: transparent;
-//   }
-
-//   .el-input__prefix {
-//     left: 8px;
-//   }
-
-//   .el-form-item__error {
-//     left: 54px;
-//   }
-// }
-</style>
+.white {
+  height: 100%;
+  background-color: #fff;
+}
+</style>
\ No newline at end of file
diff --git a/src/pages/index/api.ts b/src/pages/index/api.ts
index 4d4c24f..26369c4 100644
--- a/src/pages/index/api.ts
+++ b/src/pages/index/api.ts
@@ -1,66 +1,67 @@
 import request from '@/scripts/httpRequest'
 import qs from 'qs'
 
-// 鐧诲綍
-export const tologin = (query: any) => {
-  // let query = 'username=' + user.loginName + '&password=' + user.password
+ //鑾峰彇鏄惁淇濆瓨杩囩敤鎴峰悕瀵嗙爜 浠ュ強鏄惁淇濆瓨杩囨敞鍐屼俊鎭�
+export const getInitInfo = (query: any) => {
   return request({
-    url: '/data/api-u/sys/login',
-    method: 'post',
-    data: qs.stringify(query)
-  })
-}
+    url: "/data/api-v/sysinit/getInitInfo",
+    method: "get",
+    params: query
+  });
+};
 
-// 閫�鍑�
-export const logout = () => {
+//鑾峰彇娉ㄥ唽淇℃伅
+export const getRegInfo = (query: any) => {
   return request({
-    url: '/data/api-u/sys/logout',
-    method: 'get'
-  })
-}
+    url: "/data/api-v/sysinit/getRegInfo" ,
+    method: "get",
+    params: query
+  });
+};
 
-// 鑾峰彇鐢ㄦ埛淇℃伅
-// export const getLoginUserData = () => {
-//   let token =
-//     sessionStorage.getItem('loginedInfo') &&
-//     JSON.parse(sessionStorage.getItem('loginedInfo')).access_token
-//   return request({
-//     url: '/data/api-u/users/current',
-//     method: 'get',
-//     headers: {
-//       'Content-Type': 'application/x-www-form-urlencoded',
-//       Authorization: token || ''
-//     }
-//   })
-// }
 
-export const getLoginUserData = () => {
-    let token =
-      sessionStorage.getItem('loginedInfo') &&
-      JSON.parse(sessionStorage.getItem('loginedInfo')).access_token
-    return request({
-      url: '/data/api-u/users/profile',
-      method: 'get',
-      headers: {
-        'Content-Type': 'application/x-www-form-urlencoded',
-        Authorization: token || ''
-      }
-    })
-  }
-
-//淇敼瀵嗙爜
-export const updatePwd = (query: any) => {
+//鑾峰彇缃戝崱鍒楄〃
+export const networkList = (query: any) => {
   return request({
-    url: '/data/api-u/users/updatePwd',
-    method: 'post',
-    data: qs.stringify(query)
-  })
-}
+    url: "/data/api-v/sysinit/networkList",
+    method: "get",
+    params: query
+  });
+};
 
-//鑾峰彇椤圭洰鍚嶇О
-export const getServerName = (query: any) => {
+
+//淇濆瓨鐢ㄦ埛鍚嶅瘑鐮�
+export const savePassword = (data: any) => {
   return request({
-    url: '/data/api-v/info/getServerName',
-    method: 'get'
-  })
-}
+    url: "/data/api-v/sysinit/savePassword",
+    method: "post",
+    data
+  });
+};
+
+
+//鍒濆鍖栫綉缁�
+export const initNetwork = (data: any) => {
+  return request({
+    url: "/data/api-v/sysinit/initNetwork",
+    method: "post",
+    data
+  });
+};
+
+//淇濆瓨娉ㄥ唽淇℃伅
+export const saveRegInfo = (data: any) => {
+  return request({
+    url:  "/data/api-v/sysinit/saveRegInfo" ,
+    method: "post",
+    data
+  });
+};
+
+export const getList = (query: any) => {
+  return request({
+    url: "/data/api-v/gb28181/findAreaByParentId",
+    method: "get",
+    params: query
+  });
+};
\ No newline at end of file
diff --git a/src/pages/index/components/IPInput.vue b/src/pages/index/components/IPInput.vue
new file mode 100644
index 0000000..4636588
--- /dev/null
+++ b/src/pages/index/components/IPInput.vue
@@ -0,0 +1,238 @@
+<template>
+  <div class="ip-input-container" ref="ip-input-container">
+    <div class="ip-segment" v-for="(segment, index) in segments" :key="index">
+      <input
+        type="text"
+        maxlength="3"
+        class="ip-segment-input"
+        :value="segment"
+        :placeholder="placeholder"
+        :disabled="disabled"
+        @focus="showBorder"
+        @keydown="onInputKeydown($event, index)"
+        @input="onInput($event, index)"
+        @blur="onInputBlur"
+        @paste="onPaste($event, index)"
+      />
+      <i v-show="index != segments.length - 1">.</i>
+    </div>
+  </div>
+</template>
+
+<script>
+/* global document*/
+/** 
+ * get the cursor position of the element
+ * @param  {Element} el the element
+ * @return {Integer}    the position fo the cursor
+ */
+function getRange(el) {
+  var cuRange;
+  var tbRange;
+  var headRange;
+  var range;
+  var dupRange;
+  var ret = {};
+  if (el.setSelectionRange) {
+    // standard
+    ret.begin = el.selectionStart;
+    ret.end = el.selectionEnd;
+    ret.result = el.value.substring(ret.begin, ret.end);
+  } else if (document.selection) {
+    // ie
+    if (el.tagName.toLowerCase() === "input") {
+      cuRange = document.selection.createRange();
+      tbRange = el.createTextRange();
+      tbRange.collapse(true);
+      tbRange.select();
+      headRange = document.selection.createRange();
+      headRange.setEndPoint("EndToEnd", cuRange);
+      ret.begin = headRange.text.length - cuRange.text.length;
+      ret.end = headRange.text.length;
+      ret.result = cuRange.text;
+      cuRange.select();
+    } else if (el.tagName.toLowerCase() === "textarea") {
+      range = document.selection.createRange();
+      dupRange = range.duplicate();
+      dupRange.moveToElementText(el);
+      dupRange.setEndPoint("EndToEnd", range);
+      ret.begin = dupRange.text.length - range.text.length;
+      ret.end = dupRange.text.length;
+      ret.result = range.text;
+    }
+  }
+  el.focus();
+  return ret;
+}
+export default {
+  props: {
+    ip: {
+      type: String,
+      defalut: ""
+    },
+    item: {},
+    placeholder: String,
+    onChange: Function,
+    onBlur: Function,
+    onItemChange: Function,
+    disabled: {
+      type: Boolean,
+      default: false
+    }
+  },
+  data() {
+    return {
+      segments: ["", "", "", ""]
+    };
+  },
+  watch: {
+    ip(ip) {
+      this.syncIp(ip);
+    }
+  },
+  methods: {
+    showBorder(){
+      this.$refs['ip-input-container'].style.border = '2px solid var(--colorCard)'
+    },
+    onInputKeydown(event, index) {
+      var keyCode = event.keyCode || event.which;
+      var value = event.target.value;
+      if (keyCode === 8 || keyCode === 37) {
+        // move the cursor to previous input if backspace and left arrow is pressed at the begin of one input
+        if (
+          (value.length === 0 || getRange(event.target).end === 0) &&
+          index > 0
+        ) {
+          this.$el.getElementsByTagName("input")[index - 1].focus();
+          // When jump to pre input(enter "backspace"), thr cursor should in the end.
+          // before fix: 127.|0.0.0  =>   12|7.0.0.1
+          // after fix: 127.|0.0.0 = >   127|.0.0.0
+          // notes: "|" mean the cursor position.
+          event.preventDefault();
+        }
+      } else if (keyCode === 39 && keyCode === 110) {
+        if (getRange(event.target).end === value.length && index < 3) {
+          // move to cursor to the next input if right arrow is pressed at the end of one input
+          this.$el.getElementsByTagName("input")[index + 1].focus();
+        }
+      }
+    },
+    onInput(event, index) {
+      var value = event.target.value;
+      event.target.value = this.segments[index];
+      var segment = Number(value);
+      if (isNaN(segment)) {
+        return;
+      } else if (value === "") {
+        this.segments.splice(index, 1, "");
+      } else if (segment > 255 || segment < 0) {
+        // set the segment to 255 if out of ip range
+        this.segments.splice(index, 1, 255);
+      } else {
+        this.segments.splice(index, 1, segment);
+      }
+      // jump to next input
+      if (
+        (value.length === 3 && index < 3) ||
+        value[value.length - 1] === "."
+      ) {
+        this.$el.getElementsByTagName("input")[index + 1].focus();
+      }
+    },
+    onInputBlur() {
+      this.$refs['ip-input-container'].style.border = '2px solid transparent'
+      setTimeout(() => {
+        this.$emit("on-blur", this.segments.join("."));
+        if (this.onBlur) {
+          this.onBlur(this.segments.join("."));
+        }
+        if (this.onItemChange) {
+          this.onItemChange(this.segments.join("."), this.item)
+        }
+      }, 50);
+    },
+    onPaste(e, index) {
+      var pasteText = e.clipboardData.getData("text/plain");
+      var segments = pasteText.split(".");
+      segments.forEach((segment, i) => {
+        if (
+          index + i < 4 &&
+          !isNaN(segment) &&
+          segment >= 0 &&
+          segment <= 255
+        ) {
+          this.segments.splice(index + i, 1, segment);
+        }
+      });
+      e.preventDefault();
+    },
+    syncIp(ip) {
+      if (ip && ip.indexOf(".") !== -1) {
+        ip.split(".").map((segment, index) => {
+          if (isNaN(segment) || segment < 0 || segment > 255) {
+            segment = 255;
+          }
+          this.segments.splice(index, 1, segment);
+          return segment;
+        });
+      }
+    }
+  },
+  mounted() {
+    this.syncIp(this.ip);
+    this.$watch(
+      () => {
+        return this.segments.join(".");
+      },
+      (val, oldValue) => {
+        if (val !== oldValue) {
+          if (val === "...") {
+            val = "";
+          }
+          if (this.onChange) {
+            this.onChange(val);
+          }
+        }
+      }
+    );
+  }
+};
+</script>
+
+<style lang="scss" scoped>
+.ip-input-container {
+  
+  width: 100%;
+  height: 32px;
+  line-height: normal;
+  border: 1px solid #dcdfe6;
+  box-sizing: border-box;
+  background-color: #fff;
+  text-align: left;
+  max-width: 360px;
+  display: flex;
+}
+.ip-segment {
+  display: inline-block;
+  width: 25%;
+    display: flex;
+    align-items: center;
+  line-height: normal;
+  input {
+    width: 90%;
+    height: 32px;
+    line-height: normal;
+    border: none;
+    outline: none;
+    text-align: center;
+    text-indent: 0px;
+    margin: 0px;
+    padding: 0px;
+    background-color: transparent;
+  }
+  i {
+    display: inline-block;
+    font-size: 18px;
+  }
+}
+</style>
\ No newline at end of file
diff --git a/src/pages/index/components/formAccount.vue b/src/pages/index/components/formAccount.vue
new file mode 100644
index 0000000..0362ab5
--- /dev/null
+++ b/src/pages/index/components/formAccount.vue
@@ -0,0 +1,134 @@
+<template>
+  <div class="formAccount">
+    <el-form ref="form" :model="form" label-width="90px" :rules="rules">
+      <el-form-item label="鐢ㄦ埛鍚�" prop="username">
+        <el-input
+          v-model="form.username"
+          placeholder="2-10浣嶅瓧绗︼紝涓嶈兘浠ユ暟瀛楀紑澶达紝涓嶅彲鍖呭惈姹夊瓧"
+        ></el-input>
+      </el-form-item>
+
+      <el-form-item label="瀵嗙爜" prop="password">
+        <el-input
+          v-model="form.password"
+          placeholder="鑷冲皯涓�6浣嶅瓧绗�"
+          type="password"
+        ></el-input>
+      </el-form-item>
+
+      <el-form-item label="纭瀵嗙爜" prop="repassword">
+        <el-input
+          v-model="form.repassword"
+          placeholder="璇风‘璁ゅ瘑鐮�"
+          type="password"
+        ></el-input>
+      </el-form-item>
+    </el-form>
+  </div>
+</template>
+
+<script>
+import { getRegInfo } from "../api";
+
+export default {
+  data() {
+    const validateName = (rule, value, callback) => {
+      var reg = /^[A-Za-z][A-Za-z0-9]{0,}$/;
+      if (!reg.test(value)) {
+        return callback(new Error("涓嶈兘浠ユ暟瀛楀紑澶达紝涓嶅彲鍖呭惈姹夊瓧"));
+      } else callback();
+    };
+
+    const validateRePass = (rule, value, callback) => {
+      if (this.form.password != value) {
+        return callback(new Error("涓ゆ瀵嗙爜涓嶄竴鑷�"));
+      } else callback();
+    };
+
+    return {
+      form: {
+        username: "",
+        password: "",
+        repassword: "",
+      },
+      rules: {
+        name: [
+          { required: true, message: "璇疯緭鍏ョ敤鎴峰悕", trigger: "blur" },
+          {
+            min: 2,
+            max: 10,
+            message: "闀垮害鍦� 2 鍒� 10 涓瓧绗�",
+            trigger: "blur",
+          },
+          { validator: validateName, trigger: "blur" },
+        ],
+        password: [
+          { required: true, message: "璇疯緭鍏ュ瘑鐮�", trigger: "blur" },
+          {
+            min: 6,
+            max: 24,
+            message: "鑷冲皯涓�6浣嶅瓧绗�",
+            trigger: "blur",
+          },
+        ],
+        repassword: [
+          { required: true, message: "璇风‘璁ゅ瘑鐮�", trigger: "blur" },
+          { validator: validateRePass, trigger: "blur" },
+        ],
+      },
+    };
+  },
+  methods: {
+    getFormData() {
+      const _this = this;
+      let data = null;
+      this.$refs["form"].validate((valid) => {
+        if (valid) {
+          data = _this.form;
+        } else {
+          return false;
+        }
+      });
+      return data;
+    },
+
+    async getRegInfo() {
+      const res = await getRegInfo();
+      console.log(res);
+    },
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+.formAccount {
+  .el-form-item ::v-deep {
+    label {
+      font-size: 14px;
+      color: #fff;
+      text-align: left;
+    }
+
+    .el-form-item__content {
+      margin-left: 110px !important;
+    }
+
+    input {
+      background-color: rgba(0, 0, 0, 0.1);
+      color: #fff;
+      border: none;
+      caret-color: #fff !important;
+    }
+
+    input:-webkit-autofill,
+    textarea:-webkit-autofill,
+    select:-webkit-autofill {
+      -webkit-text-fill-color: #fff !important;
+      -webkit-box-shadow: 0 0 0px 1000px transparent inset !important;
+      background-color: transparent;
+      background-image: none;
+      transition: background-color 50000s ease-in-out 0s; //鑳屾櫙鑹查�忔槑  鐢熸晥鏃堕暱  杩囨浮鏁堟灉  鍚敤鏃跺欢杩熺殑鏃堕棿
+    }
+  }
+}
+</style>
\ No newline at end of file
diff --git a/src/pages/index/components/formInfo.vue b/src/pages/index/components/formInfo.vue
new file mode 100644
index 0000000..4599768
--- /dev/null
+++ b/src/pages/index/components/formInfo.vue
@@ -0,0 +1,259 @@
+<template>
+  <div class="formInfo">
+    <el-form ref="form" :model="form" label-width="90px" :rules="rules">
+      <el-form-item label="绫诲瀷" prop="type">
+        <el-radio v-model="form.userType" label="personal">涓汉</el-radio>
+        <el-radio v-model="form.userType" label="company">鍏徃</el-radio>
+      </el-form-item>
+
+      <el-form-item
+        label="鍏徃鍚嶇О"
+        prop="name1"
+        v-if="form.userType == 'company'"
+      >
+        <el-input v-model="form.name1" placeholder="璇疯緭鍏ュ叕鍙稿悕绉�"></el-input>
+      </el-form-item>
+
+      <el-form-item
+        label="鑱旂郴浜哄鍚�"
+        prop="name2"
+        v-if="form.userType == 'company'"
+      >
+        <el-input
+          v-model="form.name2"
+          placeholder="璇疯緭鍏ヨ仈绯讳汉濮撳悕"
+        ></el-input>
+      </el-form-item>
+
+      <el-form-item label="濮撳悕" prop="name" v-else>
+        <el-input v-model="form.name" placeholder="璇疯緭鍏ュ鍚�"></el-input>
+      </el-form-item>
+
+      <el-form-item label="鎵�鍦ㄥ湴" prop="addr">
+        <el-cascader
+          :props="props"
+          popper-class="location"
+          separator=" "
+          @change="handleChange"
+          v-model="form.addr"
+        ></el-cascader>
+      </el-form-item>
+
+      <el-form-item label="閭" prop="email">
+        <el-input v-model="form.email" placeholder="璇疯緭鍏ラ偖绠�"></el-input>
+      </el-form-item>
+    </el-form>
+  </div>
+</template>
+
+<script>
+import { getList } from "../api";
+export default {
+  created() {},
+  data() {
+    return {
+      form: {
+        userType: "personal",
+        name: "",
+        name1: "",
+        name2: "",
+        email: "",
+        addr: "",
+        provinceId: "",
+        cityId: "",
+        labelList: "",
+      },
+      rules: {
+        name1: [{ required: true, message: "璇疯緭鍏ュ叕鍙稿悕绉�", trigger: "blur" }],
+        name2: [
+          { required: true, message: "璇疯緭鍏ヨ仈绯讳汉濮撳悕", trigger: "blur" },
+        ],
+        name: [{ required: true, message: "璇疯緭鍏ュ鍚�", trigger: "blur" }],
+        addr: [{ required: true, message: "璇烽�夋嫨鎵�鍦ㄥ湴", trigger: "blur" }],
+        email: [{ required: true, message: "璇疯緭鍏ラ偖绠�", trigger: "blur" }],
+      },
+      provinceOptions: [],
+      props: {
+        lazy: true, // 寮�鍚姩鎬佸姞杞�
+        lazyLoad: async (node, resolve) => {
+          // 璁剧疆鍔犺浇鏁版嵁婧愭柟娉� 榛樿鎵ц涓�娆�
+          // node 涓哄綋鍓嶇偣鍑荤殑鑺傜偣
+          // resolve 涓烘暟鎹姞杞藉畬鎴愮殑鍥炶皟(蹇呴』璋冪敤)
+          /* node姝ゆ椂灞炴�т负:
+          		褰撳墠鍙跺瓙  level锛�0
+          		loaded锛歵rue
+          		loading锛歠alse
+          		鏄惁鏄牴  root锛歵ure
+          	*/
+          console.log(node);
+
+          if (node.level == 0) {
+            const res = await getList();
+            this.provinceOptions = res.data.map((item) => {
+              return {
+                value: item.id,
+                label: item.name, // 閫夐」鍚�
+                leaf: false, // 鏄惁涓烘湯灏�
+              };
+            });
+            resolve(this.provinceOptions);
+            console.log(node.level);
+          }
+
+          if (node.level == 1) {
+            console.log("-------------");
+            this.provinceId = node.value;
+            const res2 = await getList({
+              parentId: node.value,
+            });
+
+            const arr = res2.data.map((item) => {
+              return {
+                value: item.id,
+                label: item.name, // 閫夐」鍚�
+                leaf: true, // 鏄惁涓烘湯灏�
+              };
+            });
+            resolve(arr);
+          } else {
+            console.log(node);
+          }
+        },
+      },
+      value: [],
+    };
+  },
+
+  methods: {
+    getFormData() {
+      const _this = this;
+      let data = null;
+      this.$refs["form"].validate((valid) => {
+        if (valid) {
+          console.log(_this.form.userType);
+          if (_this.form.userType == "personal") {
+            data = {
+              userType: _this.form.userType,
+              name: _this.form.name,
+              email: _this.form.email,
+              addr: _this.form.labelList,
+              provinceId: _this.form.provinceId,
+              cityId: _this.form.cityId,
+            };
+          } else {
+            data = {
+              userType: _this.form.userType,
+              name: _this.form.name1 + " " + _this.form.name2,
+              email: _this.form.email,
+              addr: _this.form.labelList,
+              provinceId: _this.form.provinceId,
+              cityId: _this.form.cityId,
+            };
+          }
+        } else {
+          return false;
+        }
+      });
+
+      return data;
+    },
+    handleChange(val) {
+      this.form.provinceId = val[0] + "";
+      this.form.cityId = val[1] + "";
+
+      setTimeout(() => {
+        this.form.labelList =
+          document.querySelectorAll(".el-cascader input")[0].value;
+      }, 200);
+    },
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+.formInfo {
+  .el-form-item ::v-deep {
+    label {
+      font-size: 14px;
+      color: #fff;
+      text-align: left;
+    }
+
+    .el-radio {
+      .el-radio__inner {
+        background: none;
+        border-color: rgba(255, 255, 255, 0.3) !important;
+
+        &::after {
+          width: 6px;
+          height: 6px;
+        }
+      }
+
+      .el-radio__label {
+        color: #fff !important;
+      }
+    }
+
+    .el-form-item__content {
+      margin-left: 110px !important;
+      text-align: left;
+    }
+
+    input {
+      background-color: rgba(0, 0, 0, 0.1);
+      color: #fff;
+      border: none;
+      caret-color: #fff !important;
+    }
+
+    input:-webkit-autofill,
+    textarea:-webkit-autofill,
+    select:-webkit-autofill {
+      -webkit-text-fill-color: #fff !important;
+      -webkit-box-shadow: 0 0 0px 1000px transparent inset !important;
+      background-color: transparent;
+      background-image: none;
+      transition: background-color 50000s ease-in-out 0s; //鑳屾櫙鑹查�忔槑  鐢熸晥鏃堕暱  杩囨浮鏁堟灉  鍚敤鏃跺欢杩熺殑鏃堕棿
+    }
+
+    .el-cascader {
+      width: 100%;
+    }
+  }
+}
+</style>
+
+<style lang="scss">
+.el-popper.el-cascader__dropdown.location {
+  background-color: rgb(77, 72, 111);
+  border: none;
+  margin: 0 0;
+
+  * {
+    color: #fff;
+    border-color: rgba(255, 255, 2555, 0.1);
+  }
+
+  .el-cascader-node:hover,
+  .in-active-path,
+  .is-active,
+  .el-cascader-node {
+    background-color: rgb(101, 93, 126) !important;
+  }
+
+  .popper__arrow::after,
+  .popper__arrow {
+    display: none;
+  }
+
+  .el-cascader-node__label {
+    text-align: left;
+  }
+
+  .el-cascader-menu__wrap {
+    width: 226px;
+    height: 175px;
+  }
+}
+</style>
\ No newline at end of file
diff --git a/src/pages/index/components/formNet.vue b/src/pages/index/components/formNet.vue
new file mode 100644
index 0000000..a151478
--- /dev/null
+++ b/src/pages/index/components/formNet.vue
@@ -0,0 +1,141 @@
+<template>
+  <div class="formNet">
+    <el-form ref="form" :model="form" label-width="80px">
+      <el-form-item label="缃戝崱">
+        <el-select
+          v-model="form.netName"
+          placeholder="璇烽�夋嫨缃戝崱"
+          popper-class="formNet_select"
+        >
+          <el-option
+            v-for="(item, index) in options"
+            :key="index"
+            :label="item.label"
+            :value="item.value"
+          >
+          </el-option>
+        </el-select>
+      </el-form-item>
+
+      <el-form-item label="IP">
+        <ipInput :ip="form.ip" @on-blur="form.ip = arguments[0]"></ipInput>
+      </el-form-item>
+
+      <el-form-item label="瀛愮綉鎺╃爜">
+        <ipInput
+          :ip="form.subMask"
+          @on-blur="form.subMask = arguments[0]"
+        ></ipInput>
+      </el-form-item>
+
+      <el-form-item label="缃戝叧">
+        <ipInput
+          :ip="form.gateway"
+          @on-blur="form.gateway = arguments[0]"
+        ></ipInput>
+      </el-form-item>
+
+      <el-form-item label="DNS">
+        <ipInput :ip="form.dns" @on-blur="form.dns = arguments[0]"></ipInput>
+      </el-form-item>
+    </el-form>
+  </div>
+</template>
+
+<script>
+import ipInput from "../components/IPInput";
+import { networkList } from "../api";
+
+export default {
+  created() {
+    this.networkList();
+  },
+  data() {
+    return {
+      form: { netName: "", ip: "", subMask: "", gateway: "", dns: "" },
+
+      options: [],
+    };
+  },
+  components: {
+    ipInput,
+  },
+  methods: {
+    getFormData() {
+      return this.form;
+    },
+    async networkList() {
+      const res = await networkList();
+      res.data.forEach((item) => {
+        this.options.push({
+          value: item.name,
+          label: item.name,
+        });
+      });
+    },
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+.formNet {
+  .el-form-item ::v-deep {
+    label {
+      font-size: 14px;
+      color: #fff;
+      text-align-last: left;
+    }
+
+    .el-form-item__content {
+      margin-left: 110px !important;
+    }
+  }
+
+  .ip-input-container ::v-deep {
+    background-color: rgba(0, 0, 0, 0.1);
+    border: none !important;
+    height: 40px;
+    max-width: none;
+
+    .ip-segment-input {
+      color: #fff;
+    }
+  }
+
+  .el-select ::v-deep {
+    width: 100%;
+
+    input {
+      background-color: rgba(0, 0, 0, 0.1);
+      border: none !important;
+      color: #fff;
+    }
+  }
+}
+</style>
+
+<style lang="scss">
+.el-select-dropdown.el-popper.formNet_select {
+  background-color: rgb(60, 62, 99);
+
+  border: none;
+  margin: 0 0;
+  z-index: 5;
+
+  * {
+    color: #fff;
+  }
+
+  li {
+    z-index: 4;
+  }
+  .el-select-dropdown__item.hover {
+    background-color: rgba(85, 82, 117) !important;
+  }
+
+  .popper__arrow::after,
+  .popper__arrow {
+    display: none;
+  }
+}
+</style>
\ No newline at end of file
diff --git a/src/pages/login/App.vue b/src/pages/login/App.vue
new file mode 100644
index 0000000..6754bff
--- /dev/null
+++ b/src/pages/login/App.vue
@@ -0,0 +1,564 @@
+<template>
+  <!-- <div class v-loading="vLoading" :style="`width: ${currentWidth}px;height:${currentHeight}px`">
+    <div class="web-site">
+      <a href="http://www.smartai.com" target="_blank">www.smartai.com</a>
+    </div>
+
+    <lang-select class="lang-select"/>
+    <licence />
+    <div class="right-bg" style>
+      <particle-network />
+    </div>
+    <div class="left-bg">
+      <div class="login-logo">
+        <img src="/images/login-logo.png" alt width="105px" height="105px" />
+      </div>
+      <div class="login-com">
+        <span>{{ $t('login.company') }}</span>
+      </div>
+      <div class="login-form">
+        <el-form
+          :model="user"
+          status-icon
+          :rules="nullRule"
+          :validate-on-rule-change="false"
+          ref="ruleForm"
+          class="demo-ruleForm"
+        >
+          <el-form-item prop="loginName">
+            <el-input v-model="user.loginName" style="width:280px" :placeholder="$t('placeholder.enterUsername')">
+              <i slot="prefix" class="iconfont iconyonghu1"></i>
+            </el-input>
+          </el-form-item>
+          <el-form-item prop="password">
+            <el-input
+              show-password
+              @keyup.enter.native="systemLogin()"
+              v-model="user.password"
+              autocomplete="off"
+              style="width:280px"
+              :placeholder="$t('placeholder.enterPassword')"
+            >
+              <i slot="prefix" class="iconfont iconmima"></i>
+            </el-input>
+          </el-form-item>
+          <el-form-item>
+            <el-button ref="submit" type="warning" @click="systemLogin()" style="width:280px">{{ $t('button.login') }}</el-button>
+          </el-form-item>
+        </el-form>
+      </div>
+      <p class="gradient-text gradient-text-one">
+        鈥斺��
+        <b>SmartAI</b> {{ $t('login.aios') }} 鈥斺��
+      </p>
+      <p
+        class="gradient-text gradient-text-one"
+        style="letter-spacing: 1.8px;font-size:15px;"
+      >V1.0.0</p>
+    </div>
+  </div> -->
+  <div class="login">
+    <div class="title">
+      <div class="en">Smart AI</div>
+      <div class="ch">浜哄伐鏅鸿兘鎿嶄綔绯荤粺</div>
+    </div>
+
+    <div class="left_footer">
+      <img class="logo" src="/images/login/LOGO.png" alt="" />
+      <div class="web">www.smartai.com</div>
+    </div>
+
+    <div
+      class="login-form"
+      :style="{ background: backgroundColor }"
+      :class="{ empty: !user.loginName && !user.password }"
+    >
+      <img class="logo" src="/images/login/OS.png" alt="" />
+
+      <el-form
+        :model="user"
+        status-icon
+        :rules="nullRule"
+        :validate-on-rule-change="false"
+        ref="ruleForm"
+        class="demo-ruleForm"
+      >
+        <el-form-item prop="loginName">
+          <el-input
+            v-model="user.loginName"
+            :placeholder="$t('placeholder.enterUsername')"
+          >
+            <i slot="prefix" class="iconfont icon">&#xe7e5;</i>
+          </el-input>
+        </el-form-item>
+        <el-form-item prop="password">
+          <el-input
+            show-password
+            @keyup.enter.native="systemLogin()"
+            v-model="user.password"
+            autocomplete="off"
+            :placeholder="$t('placeholder.enterPassword')"
+          >
+            <i slot="prefix" class="iconfont icon">&#xe7e4;</i>
+          </el-input>
+        </el-form-item>
+        <el-form-item>
+          <el-button ref="submit" type="warning" @click="systemLogin()">{{
+            $t("button.login")
+          }}</el-button>
+        </el-form-item>
+      </el-form>
+    </div>
+  </div>
+</template>
+
+<script>
+import { tologin, getLoginUserData, getServerName } from "./api.ts";
+import ParticleNetwork from "./ParticleNetwork";
+import Licence from "@/components/licence";
+import LangSelect from "@/components/langSelect";
+import { getMenuListData } from "@/api/utils";
+
+export default {
+  name: "login-pgae",
+  metaInfo: {
+    title: "鐧诲綍椤�",
+  },
+  components: {
+    //  ParticleNetwork,
+    // Licence,
+    //  LangSelect
+  },
+  computed: {
+    rules() {
+      return {
+        loginName: [
+          {
+            required: true,
+            message: this.$t("placeholder.enterUsername"),
+            trigger: "change",
+          },
+        ],
+        password: [
+          {
+            required: true,
+            message: this.$t("placeholder.enterPassword"),
+            trigger: "change",
+          },
+        ],
+      };
+    },
+  },
+  data: () => ({
+    serverTitle: "",
+    user: {
+      loginName: "",
+      password: "",
+      rememberMe: false,
+    },
+    nullRule: {},
+
+    loading: "",
+    vLoading: false,
+    currentHeight: 1057,
+    currentWidth: 1920,
+    backgroundColor: "",
+    backgroundList: [
+      "#2A2344",
+      "#342344",
+      "#000000",
+      "#233044",
+      "#0B252E",
+      "#150051",
+      "#110040",
+    ],
+  }),
+  created() {
+    this.getServerName();
+    this.getScreenHeight();
+    this.backgroundColor =
+      this.backgroundList[
+        Math.floor(Math.random() * this.backgroundList.length)
+      ];
+  },
+  mounted() {
+    // 鑷姩鐧诲綍鎺ュ彛
+    this.loginRobot();
+  },
+  watch: {},
+  beforeDestroy() {
+    window.onresize = null;
+  },
+  methods: {
+    loginRobot() {
+      // 瑙f瀽璺敱鍙傛暟锛屽苟缂撳瓨
+      let user = this.getQueryVariable("username");
+      let passwd = this.getQueryVariable("password");
+      if (user.length && passwd.length) {
+        sessionStorage.setItem(
+          "autoLogin",
+          JSON.stringify({ username: user, passwd: passwd })
+        );
+
+        this.user.loginName = user;
+        this.user.password = passwd;
+        this.systemLogin();
+        return;
+      }
+
+      // 鐧婚檰瓒呮椂鍚庣殑閲嶆柊鐧婚檰
+      let sessionInfo = sessionStorage.getItem("autoLogin");
+      if (sessionInfo) {
+        let authority = JSON.parse(sessionInfo);
+        this.user.loginName = authority.username;
+        this.user.password = authority.passwd;
+        this.systemLogin();
+      }
+    },
+    systemLogin() {
+      this.nullRule = this.rules;
+      this.$nextTick(() => {
+        this.$refs["ruleForm"].validate((valid) => {
+          if (valid) {
+            this.loading = this.$loading({
+              lock: true,
+              text: "Loading",
+              spinner: "el-icon-loading",
+              background: "rgba(0, 0, 0, 0.7)",
+            });
+            this.testLogin();
+          } else {
+            this.nullRule = {};
+          }
+        });
+        this.nullRule = {};
+      });
+    },
+    async testLogin() {
+      // location.assign("/view/desktop/")
+      tologin({ username: this.user.loginName, password: this.user.password })
+        .then((json) => {
+          const loginedInfo = {
+            access_token: json.token_type + " " + json.access_token,
+            refresh_token: json.refresh_token,
+          };
+          sessionStorage.setItem("expires_in", json.expires_in);
+          sessionStorage.setItem("loginedInfo", JSON.stringify(loginedInfo));
+          this.loading.close();
+          this.getLoginUserData();
+        })
+        .catch((err) => {
+          this.loading.close();
+          this.$notify({
+            title: "鎻愮ず",
+            type: "error",
+            message: err.msg,
+          });
+          this.$refs.pwd.focus();
+        });
+    },
+    async getLoginUserData() {
+      let res = await getLoginUserData();
+      if (res.success) {
+        sessionStorage.setItem("userInfo", JSON.stringify(res.data));
+        this.$notify.success("鐧诲綍鎴愬姛锛�");
+        // 鑾峰彇鏉冮檺
+        await this.getMenuList();
+        location.assign("/view/desktop/");
+        return res.data;
+      } else {
+        this.$notify.error("鐧诲綍澶辫触锛�");
+      }
+    },
+
+    getScreenHeight() {
+      this.currentHeight = document.documentElement.clientHeight;
+      this.currentWidth = document.documentElement.clientWidth;
+      window.onresize = () => {
+        this.currentHeight = document.documentElement.clientHeight;
+        this.currentWidth = document.documentElement.clientWidth;
+        this.$forceUpdate();
+      };
+    },
+    async getServerName() {
+      let res = await getServerName();
+      if (res && res.success) {
+        this.serverTitle = res.data.serverName;
+        window.document.title = res.data.serverName
+          ? res.data.serverName
+          : "SmartAI";
+        sessionStorage.setItem("title", res.data.serverName);
+      }
+    },
+    async getMenuList() {
+      let results = await getMenuListData({});
+      if (results && results.success) {
+        /* 瀛樺偍鏉冮檺 */
+        let buttonAuthoritys = results.data;
+        if (results && results.length && this.$route.query.is_login) {
+          this.$router.replace(results[0].url);
+        }
+        sessionStorage.setItem(
+          "buttonAuthoritys",
+          "," + buttonAuthoritys + ","
+        );
+        sessionStorage.setItem("menuInfo", JSON.stringify(results));
+      } else {
+        this.$toast({
+          type: "error",
+          message: "鑿滃崟鑾峰彇澶辫触",
+        });
+      }
+    },
+    getQueryVariable(variable) {
+      var query = window.location.search.substring(1);
+      var vars = query.split("&");
+      for (var i = 0; i < vars.length; i++) {
+        var pair = vars[i].split("=");
+        if (pair[0] == variable) {
+          return pair[1];
+        }
+      }
+      return false;
+    },
+  },
+};
+</script>
+<style lang="scss">
+.login {
+  height: 100%;
+  position: relative;
+  background-image: url("/images/login/鑳屾櫙鍥�.png");
+
+  .title {
+    position: absolute;
+    top: 345px;
+    left: 301px;
+    color: #fff;
+    text-align: center;
+
+    .en {
+      font-size: 120px;
+    }
+
+    .ch {
+      font-size: 48px;
+      letter-spacing: 9px;
+    }
+  }
+
+  .left_footer {
+    position: absolute;
+    display: flex;
+    justify-content: start;
+    align-items: center;
+    left: 358px;
+    bottom: 40px;
+
+    .logo {
+      width: 136px;
+      margin-right: 30px;
+    }
+
+    .web {
+      font-size: 24px;
+      font-weight: 700;
+      color: rgba(255, 255, 255, 0.7);
+    }
+  }
+
+  .login-form {
+    position: absolute;
+    width: 780px;
+    height: 1000px;
+    right: 40px;
+    top: 40px;
+    padding: 0 90px;
+    box-sizing: border-box;
+
+    background: #2a2344;
+    opacity: 0.95;
+    box-shadow: -4px 0px 10px rgba(0, 0, 0, 0.25);
+    border-radius: 56px;
+
+    .logo {
+      margin-top: 100px;
+      margin-bottom: 16px;
+    }
+
+    .el-form-item {
+      background: rgba(0, 0, 0, 0);
+    }
+
+    .el-form-item:nth-child(2) {
+      margin-top: 60px;
+      margin-bottom: 80px;
+    }
+
+    .el-button {
+      width: 600px;
+      height: 60px;
+      background: #4e94ff;
+      border-radius: 30px;
+      border: none;
+    }
+
+    .el-input {
+      width: 100%;
+      background: rgba(0, 0, 0, 0);
+    }
+
+    input {
+      width: 100%;
+      height: 56px;
+      background: rgba(255, 255, 255, 0.1) !important;
+      border: 1px solid #4e94ff;
+      box-sizing: border-box;
+      border-radius: 28px;
+      color: #fff;
+      caret-color: #fff; //鍏夋爣棰滆壊
+      padding-left: 100px;
+      padding-right: 50px;
+      font-weight: 700;
+    }
+
+    input:-webkit-autofill,
+    textarea:-webkit-autofill,
+    select:-webkit-autofill {
+      -webkit-text-fill-color: #ededed !important;
+      -webkit-box-shadow: 0 0 0px 1000px transparent inset !important;
+      background-color: transparent;
+      background-image: none;
+      transition: background-color 50000s ease-in-out 0s; //鑳屾櫙鑹查�忔槑  鐢熸晥鏃堕暱  杩囨浮鏁堟灉  鍚敤鏃跺欢杩熺殑鏃堕棿
+    }
+
+    .el-form-item__error {
+      top: 110%;
+      left: 80px;
+    }
+
+    .icon {
+      font-size: 32px;
+      color: rgb(80, 151, 255);
+    }
+
+    .el-input__prefix {
+      padding: 0 20px;
+      height: 40px;
+      left: 5px;
+      top: 8px;
+      border-right: 1px solid #4e94ff;
+    }
+
+    .el-input__suffix {
+      right: 20px;
+    }
+
+    .el-icon-circle-close {
+      display: none;
+    }
+  }
+
+  .login-form.empty {
+    input {
+      border-color: #999;
+      color: #bbb;
+    }
+
+    .el-button {
+      background-color: #999;
+      color: #fff;
+    }
+
+    .icon {
+      color: #fff;
+    }
+
+    .el-input__prefix {
+      border-color: #d4d6d9;
+    }
+  }
+}
+
+// .right-bg {
+//   position: fixed;
+//   top: 0;
+//   left: 0;
+//   background-image: url("/images/login-net.png");
+
+//   width: 100%;
+//   height: 100%;
+//   min-width: 1000px;
+//   z-index: -10;
+//   zoom: 1;
+//   background-color: #fff;
+//   background-repeat: no-repeat;
+//   background-size: cover;
+//   -webkit-background-size: cover;
+//   -o-background-size: cover;
+//   background-position: center 0;
+// }
+// .web-site {
+//   position: absolute;
+//   top: 55px;
+//   left: 41px;
+//   font-family: PingFangSC-Medium;
+//   font-size: 20px;
+//   color: #6170e1;
+//   letter-spacing: 6.15px;
+// }
+// .lang-select {
+//   float: right;
+//   color: white !important;
+//   font-size: 14px;
+//   margin: 13px;
+//   cursor: pointer;
+// }
+// .left-bg {
+//   position: absolute;
+//   top: 29%;
+//   right: 18%;
+//   width: 390px;
+//   height: 426px;
+//   background: rgba(146, 208, 255, 0.23);
+//   border-radius: 4px;
+//   text-align: center;
+//   .login-logo {
+//     margin-top: -53px;
+//   }
+
+//   .login-com {
+//     font-family: PingFangSC-Medium;
+//     font-size: 22px;
+//     color: #ffffff;
+//     letter-spacing: 0.44px;
+//     margin: 15px;
+//   }
+//   .login-form {
+//     margin: 40px 10px;
+//   }
+//   .gradient-text {
+//     line-height: 36px;
+//     font-size: 17px;
+//     font-family: -webkit-pictograph;
+//     font-weight: bolder;
+//     position: relative;
+//     b {
+//       font-size: 20px;
+//     }
+//   }
+//   .gradient-text-one {
+//     background-image: linear-gradient(to right, #51feff 5%, #ff8725 100%);
+//     -webkit-background-clip: text;
+//     -webkit-text-fill-color: transparent;
+//   }
+
+//   .el-input__prefix {
+//     left: 8px;
+//   }
+
+//   .el-form-item__error {
+//     left: 54px;
+//   }
+// }
+</style>
diff --git a/src/pages/login/ParticleNetwork.vue b/src/pages/login/ParticleNetwork.vue
new file mode 100644
index 0000000..53a1e12
--- /dev/null
+++ b/src/pages/login/ParticleNetwork.vue
@@ -0,0 +1,348 @@
+<template>
+  <div class="particle-network-animation" :style="`height:${height}px;width:${width}px`">
+    <div style="display:none">
+      <img ref="conf0" src="/images/login/0.png" />
+      <img ref="conf1" src="/images/login/1.png" />
+      <img ref="conf2" src="/images/login/2.png" />
+      <img ref="conf3" src="/images/login/3.png" />
+      <img ref="conf4" src="/images/login/4.png" />
+      <img ref="conf5" src="/images/login/5.png" />
+      <img ref="conf6" src="/images/login/6.png" />
+      <img ref="conf7" src="/images/login/7.png" />
+      <img ref="conf8" src="/images/login/8.png" />
+      <img ref="conf9" src="/images/login/9.png" />
+      <img ref="conf10" src="/images/login/10.png" />
+      <img ref="conf11" src="/images/login/11.png" />
+      <img ref="conf12" src="/images/login/12.png" />
+      <img ref="conf13" src="/images/login/13.png" />
+      <img ref="conf14" src="/images/login/14.png" />
+      <img ref="conf15" src="/images/login/15.png" />
+    </div>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'particleNetwork',
+  data() {
+    return {
+      imgNumber: 0,
+      destoryed: false
+    }
+  },
+  props: {
+    height: {
+      type: Number,
+      default: 800
+    },
+    width: {
+      type: Number,
+      default: 1000
+    }
+  },
+  mounted() {
+    this.createCavas()
+  },
+  beforeDestroy() {
+    this.destoryed = true
+  },
+  methods: {
+    createCavas() {
+      let that = this
+      var ParticleNetworkAnimation, PNA
+      ParticleNetworkAnimation = PNA = function () { }
+
+      PNA.prototype.init = function (element) {
+        // this.$el = $(element);
+
+        this.container = element
+        this.canvas = document.createElement('canvas')
+        this.sizeCanvas()
+        this.container.appendChild(this.canvas)
+        this.ctx = this.canvas.getContext('2d')
+        this.particleNetwork = new ParticleNetwork(this)
+
+        return this
+      }
+
+      PNA.prototype.sizeCanvas = function () {
+        this.canvas.width = this.container.offsetWidth
+        this.canvas.height = this.container.offsetHeight
+      }
+
+      var Particle = function (parent, x, y) {
+        this.network = parent
+        this.imgNumber = that.imgNumber++
+        this.canvas = parent.canvas
+        this.ctx = parent.ctx
+        this.particleColor = returnRandomArrayitem(
+          this.network.options.particleColors
+        )
+        // 鎺у埗澶у皬
+        this.radius = getLimitedRandom(10, 30)
+        this.opacity = 0
+        // this.x = x || Math.random() * this.canvas.width;
+        // this.y = y || Math.random() * this.canvas.height;
+
+        // 鎺у埗鍒濆鍧愭爣锛屼笉瑕佽秴鍑鸿寖鍥�
+        this.x = x || getLimitedRandom(50, this.canvas.width - 50)
+        this.y = y || getLimitedRandom(50, this.canvas.height - 50)
+
+        this.velocity = {
+          x: (Math.random() - 0.5) * parent.options.velocity,
+          y: (Math.random() - 0.5) * parent.options.velocity
+        }
+      }
+
+      Particle.prototype.update = function () {
+        if (this.opacity < 0.8) {
+          this.opacity += 0.01
+        } else {
+          this.opacity = 0.8
+        }
+        // 绉诲姩鍒拌竟缂樻椂鍙嶅悜
+        if (this.x > this.canvas.width - 50 || this.x < 50) {
+          this.velocity.x = -this.velocity.x
+        }
+        if (this.y > this.canvas.height - 50 || this.y < 50) {
+          this.velocity.y = -this.velocity.y
+        }
+
+        // 鏇存柊鍧愭爣
+        this.x += this.velocity.x
+        this.y += this.velocity.y
+      }
+
+      Particle.prototype.draw = function () {
+        // Draw particle
+        if (that.destoryed) {
+          return
+        }
+        this.ctx.beginPath()
+        this.ctx.fillStyle = this.particleColor
+        this.ctx.globalAlpha = this.opacity
+        this.ctx.arc(this.x, this.y, this.radius, 0, 2 * Math.PI)
+        this.ctx.fill()
+        var prop = this.radius
+        // let imgOdr = parseInt(Math.random() * 16, 10);
+        var img = that.$refs['conf' + this.imgNumber]
+        this.ctx.drawImage(
+          img,
+          this.x - this.radius * 0.8,
+          this.y - this.radius * 0.8,
+          this.radius * 1.6,
+          this.radius * 1.6
+        )
+      }
+
+      var ParticleNetwork = function (parent) {
+        this.options = {
+          velocity: 1, // the higher the faster
+          density: 1500, // the lower the denser
+          netLineDistance: 300,
+          netLineColor: '#477bec',
+          particleColors: ['#7E8BFA'] // ['#6D4E5C', '#aaa', '#FFC458' ]
+        }
+        this.canvas = parent.canvas
+        this.ctx = parent.ctx
+
+        this.init()
+      }
+
+      ParticleNetwork.prototype.init = function () {
+        // Create particle objects
+        this.createParticles(true)
+
+        // Update canvas
+        this.animationFrame = requestAnimationFrame(this.update.bind(this))
+      }
+
+      ParticleNetwork.prototype.createParticles = function (isInitial) {
+        // Initialise / reset particles
+        var me = this
+        this.particles = []
+        // var quantity = this.canvas.width * this.canvas.height / this.options.density;
+        var quantity = 17
+
+        if (isInitial) {
+          var counter = 0
+          clearInterval(this.createIntervalId)
+          this.createIntervalId = setInterval(
+            function () {
+              if (counter < quantity - 1) {
+                // Create particle object
+                this.particles.push(new Particle(this))
+              } else {
+                clearInterval(me.createIntervalId)
+              }
+              counter++
+            }.bind(this),
+            250
+          )
+        } else {
+          // Create particle objects
+          for (var i = 0; i < quantity; i++) {
+            this.particles.push(new Particle(this))
+          }
+        }
+      }
+
+      ParticleNetwork.prototype.destory = function (isInitial) {
+        clearInterval(this.createIntervalId)
+      }
+      ParticleNetwork.prototype.update = function () {
+        if (this.canvas) {
+          this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height)
+          this.ctx.globalAlpha = 1
+
+          // Draw connections
+          for (var i = 0; i < this.particles.length; i++) {
+            for (var j = this.particles.length - 1; j > i; j--) {
+              var distance,
+                p1 = this.particles[i],
+                p2 = this.particles[j]
+
+              // check very simply if the two points are even a candidate for further measurements
+              distance = Math.min(Math.abs(p1.x - p2.x), Math.abs(p1.y - p2.y))
+              if (distance > this.options.netLineDistance) {
+                continue
+              }
+
+              // the two points seem close enough, now let's measure precisely
+              distance = Math.sqrt(
+                Math.pow(p1.x - p2.x, 2) + Math.pow(p1.y - p2.y, 2)
+              )
+              if (distance > this.options.netLineDistance) {
+                continue
+              }
+
+              this.ctx.beginPath()
+              this.ctx.strokeStyle = this.options.netLineColor
+              this.ctx.globalAlpha =
+                ((this.options.netLineDistance - distance) /
+                  this.options.netLineDistance) *
+                p1.opacity *
+                p2.opacity
+              this.ctx.lineWidth = 1.7
+              this.ctx.moveTo(p1.x, p1.y)
+              this.ctx.lineTo(p2.x, p2.y)
+              this.ctx.stroke()
+            }
+          }
+
+          // Draw particles
+          for (var i = 0; i < this.particles.length; i++) {
+            this.particles[i].update()
+            this.particles[i].draw()
+          }
+
+          if (this.options.velocity !== 0) {
+            this.animationFrame = requestAnimationFrame(this.update.bind(this))
+          }
+        } else {
+          cancelAnimationFrame(this.animationFrame)
+        }
+      }
+
+      var getLimitedRandom = function (min, max, roundToInteger) {
+        var number = Math.random() * (max - min) + min
+        if (roundToInteger) {
+          number = Math.round(number)
+        }
+        return number
+      }
+
+      var returnRandomArrayitem = function (array) {
+        return array[Math.floor(Math.random() * array.length)]
+      }
+
+      var elm = document.getElementsByClassName('particle-network-animation')[0]
+
+      this.pna = new ParticleNetworkAnimation()
+      this.pna.init(elm)
+    }
+  }
+}
+</script>
+
+<style lang="scss">
+.particle-network-animation {
+  position: fixed;
+  top: 20%;
+  left: 0;
+  right: 0;
+  // background-color: #171717;
+}
+.particle-network-animation::before {
+  z-index: -3;
+  content: "";
+  position: absolute;
+  top: 0;
+  right: 0;
+  bottom: 0;
+  left: 0;
+  background-size: cover;
+  opacity: 0.2;
+}
+
+.glow {
+  z-index: -2;
+  position: fixed;
+  top: 50%;
+  left: 50%;
+  background-image: radial-gradient(
+    circle closest-side,
+    rgba(255, 255, 255, 0.025),
+    transparent
+  );
+}
+
+.glow-1 {
+  width: 150vw;
+  height: 150vh;
+  margin-top: -75vh;
+  margin-left: -75vw;
+  animation: glow-1-move 25s linear infinite both;
+}
+
+@keyframes glow-1-move {
+  from {
+    transform: translate(-100%, 100%);
+  }
+  to {
+    transform: translate(100%, -100%);
+  }
+}
+.glow-2 {
+  width: 100vw;
+  height: 100vh;
+  margin-top: -50vh;
+  margin-left: -50vw;
+  animation: glow-2-move 25s linear 8.3333333333s infinite both;
+}
+
+@keyframes glow-2-move {
+  from {
+    transform: translate(-100%, 0%);
+  }
+  to {
+    transform: translate(100%, 100%);
+  }
+}
+.glow-3 {
+  width: 120vw;
+  height: 120vh;
+  margin-top: -60vh;
+  margin-left: -60vw;
+  animation: glow-3-move 25s linear 16.6666666667s infinite both;
+}
+
+@keyframes glow-3-move {
+  from {
+    transform: translate(100%, 100%);
+  }
+  to {
+    transform: translate(0%, -100%);
+  }
+}
+</style>
diff --git a/src/pages/login/api.ts b/src/pages/login/api.ts
new file mode 100644
index 0000000..4d4c24f
--- /dev/null
+++ b/src/pages/login/api.ts
@@ -0,0 +1,66 @@
+import request from '@/scripts/httpRequest'
+import qs from 'qs'
+
+// 鐧诲綍
+export const tologin = (query: any) => {
+  // let query = 'username=' + user.loginName + '&password=' + user.password
+  return request({
+    url: '/data/api-u/sys/login',
+    method: 'post',
+    data: qs.stringify(query)
+  })
+}
+
+// 閫�鍑�
+export const logout = () => {
+  return request({
+    url: '/data/api-u/sys/logout',
+    method: 'get'
+  })
+}
+
+// 鑾峰彇鐢ㄦ埛淇℃伅
+// export const getLoginUserData = () => {
+//   let token =
+//     sessionStorage.getItem('loginedInfo') &&
+//     JSON.parse(sessionStorage.getItem('loginedInfo')).access_token
+//   return request({
+//     url: '/data/api-u/users/current',
+//     method: 'get',
+//     headers: {
+//       'Content-Type': 'application/x-www-form-urlencoded',
+//       Authorization: token || ''
+//     }
+//   })
+// }
+
+export const getLoginUserData = () => {
+    let token =
+      sessionStorage.getItem('loginedInfo') &&
+      JSON.parse(sessionStorage.getItem('loginedInfo')).access_token
+    return request({
+      url: '/data/api-u/users/profile',
+      method: 'get',
+      headers: {
+        'Content-Type': 'application/x-www-form-urlencoded',
+        Authorization: token || ''
+      }
+    })
+  }
+
+//淇敼瀵嗙爜
+export const updatePwd = (query: any) => {
+  return request({
+    url: '/data/api-u/users/updatePwd',
+    method: 'post',
+    data: qs.stringify(query)
+  })
+}
+
+//鑾峰彇椤圭洰鍚嶇О
+export const getServerName = (query: any) => {
+  return request({
+    url: '/data/api-v/info/getServerName',
+    method: 'get'
+  })
+}
diff --git a/src/pages/login/main.ts b/src/pages/login/main.ts
new file mode 100644
index 0000000..1a04451
--- /dev/null
+++ b/src/pages/login/main.ts
@@ -0,0 +1,18 @@
+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'
+
+import i18n from '@/lang'
+
+Vue.use(ElementUI, {
+  i18n: (key, value) => i18n.t(key, value),
+})
+
+new Vue({
+  el: '#app',
+  i18n,
+  render: (h) => h(App),
+})
diff --git a/vue.config.js b/vue.config.js
index f4b88d8..9cebf58 100644
--- a/vue.config.js
+++ b/vue.config.js
@@ -40,8 +40,8 @@
   // }
 });
 
-// const serverUrl = "http://192.168.20.189/:7009"; // 缇婁簲
-const serverUrl = "http://192.168.8.10:7009";
+const serverUrl = "http://192.168.20.189:7009"; // 缇婁簲
+//  const serverUrl = "http://192.168.8.10:7009";
 const serverUrl2 = "http://192.168.8.10:9000";
 // const serverUrl = "http://192.168.20.10:7009";
 // const serverUrl2 = "http://192.168.20.10:9000";

--
Gitblit v1.8.0