dengshaobo 7 месяцев назад
Родитель
Сommit
44ba763a4e

+ 11 - 0
package-lock.json

@@ -27,6 +27,7 @@
         "kde": "^0.0.1",
         "lottie-web": "^5.12.2",
         "nprogress": "^0.2.0",
+        "particles.js": "^2.0.0",
         "plotly.js": "^2.35.3",
         "postcss-pxtorem": "^6.1.0",
         "print-js": "^1.6.0",
@@ -11172,6 +11173,11 @@
         "node": ">= 0.8"
       }
     },
+    "node_modules/particles.js": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmmirror.com/particles.js/-/particles.js-2.0.0.tgz",
+      "integrity": "sha512-8e0JIqkRbMMPlFBnF9f+92hX1s07jdkd3tqB8uHE9L+cwGGjIYjQM7QLgt0FQ5MZp6SFFYYDm/Y48pqK3ZvJOQ=="
+    },
     "node_modules/pascal-case": {
       "version": "3.1.2",
       "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz",
@@ -24860,6 +24866,11 @@
       "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
       "dev": true
     },
+    "particles.js": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmmirror.com/particles.js/-/particles.js-2.0.0.tgz",
+      "integrity": "sha512-8e0JIqkRbMMPlFBnF9f+92hX1s07jdkd3tqB8uHE9L+cwGGjIYjQM7QLgt0FQ5MZp6SFFYYDm/Y48pqK3ZvJOQ=="
+    },
     "pascal-case": {
       "version": "3.1.2",
       "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz",

+ 1 - 0
package.json

@@ -30,6 +30,7 @@
     "kde": "^0.0.1",
     "lottie-web": "^5.12.2",
     "nprogress": "^0.2.0",
+    "particles.js": "^2.0.0",
     "plotly.js": "^2.35.3",
     "postcss-pxtorem": "^6.1.0",
     "print-js": "^1.6.0",

BIN
src/assets/login/login_logo.png


BIN
src/assets/login/login_logo.webp


+ 4 - 8
src/router/index.js

@@ -10,16 +10,12 @@ Router.prototype.push = function push(location) {
 // 其他路由
 let constantRoutes = [
   {
-    path: "/index",
-    component: () => import("@/views/login/login"),
+    path: "/",
+    component: () => import("@/views/login/login_ruoyan.vue"),
     meta: {
-      title: "otherLogin",
+      title: "login",
     },
   },
-  {
-    path: "/",
-    redirect: "/index"//redirect: "/studentAnalysisReport"
-  },
 ];
 // 学生端分析报告
 let studentAnalysisReport = {
@@ -116,7 +112,7 @@ function addAnalyticsScript() {
 let router = createRouter();
 router.beforeEach((to, from, next) => {
   if (to.meta.title) {
-    document.title = "慧教研-" + to.meta.title;
+    document.title = "大数据精准教学诊断平台-" + to.meta.title;
   }
   next();
 });

+ 228 - 3
src/styles/login.scss

@@ -27,11 +27,17 @@
 
       img
       {
-        width: 116px;
-        height: 32px;
+        width: 32px;
+        height: auto;
         margin-left: 40px;
         margin-right: 5px;
       }
+
+      span
+      {
+        font-weight: 700;
+        font-size: 26px;
+      }
     }
 
     .header_right
@@ -74,7 +80,7 @@
     background-repeat: no-repeat;
 
   }
-
+  
   .login_info
   {
     min-width:450px;
@@ -292,4 +298,223 @@
       }
     }
   }
+  //屏幕高度小于600
+  @media screen and (max-height: 600px) 
+  {
+    .login_info
+    {
+      min-width:450px;
+      height: 500px;
+      border-radius: 10px 10px 10px 10px;  
+
+       top:calc(50% - 251px + 32px);
+      right:13.5%;
+      position: absolute;
+      padding: 20px;
+      box-sizing: border-box;
+      .login_info_title
+      {
+        width: 100%;
+        
+        background: #FFFFFF;
+        border-radius: 10px 10px 0px 0px;
+
+        font-weight: 500;
+        font-size: 24px;
+        color: #333333;
+        line-height: 35px;
+        margin-bottom: 10px;
+      }
+
+      .login_info_message
+      {
+        font-weight: 500;
+        font-size: 16px;
+        color: #333333;
+        line-height: 28px;
+        margin-bottom: 10px;
+      }
+
+      .login_info_input
+      {
+
+        width: 100%;
+        height: auto;
+        margin-bottom: 20px;
+        .el-form-item {
+          margin-bottom: 20px;
+        }
+        .el-input__inner
+        {
+          width: 100%;
+          height: 40px;
+          line-height: 40px;
+          padding: 0;
+          text-indent: 43px;
+        }
+
+        .el-input__prefix
+        {
+
+          display: flex;
+          align-items: center;
+          left: 17px;
+          .iconfont {
+            font-size: 18px;
+            line-height: 48px;
+          }
+        }
+
+        .el-input__suffix
+        {
+          right: 17px;
+          display: flex;
+          align-items: center;
+        }
+
+        .icon_xianshimima
+        {
+          font-size: 18px;
+          color:#ccc;
+        }
+
+        .icon_buxianshimima
+        {
+          font-size: 18px;
+          color:#ccc;
+        }
+      }
+
+      .login_info_item
+      {
+        width: 100%;
+        
+        margin-bottom: 20px;
+        display: flex;
+        justify-content: space-between;
+        align-items: center;
+
+        .item_left
+        {
+          width: 50%;
+          text-align: left;
+
+        }
+
+        .item_right
+        {
+          width: 50%;
+          text-align: right;
+
+          font-weight: 400;
+          font-size: 14px;
+          color: rgba(25,31,37,0.72);
+          cursor: pointer;
+        }
+      }
+
+      .login_info_button
+      {
+        width: 100%;
+        height: 40px;
+        background: #0470FF;
+        border-radius: 10px;
+        border: none;
+        font-weight: 600;
+        font-size: 16px;
+        color: #FFFFFF;
+        line-height: 40px;
+        text-align:center;
+        .el-button
+        {
+          background-color: transparent;
+          border:none;
+          color:#fff;
+          height: 40px;
+          font-size: 16px;
+          font-weight: 600;
+        }
+
+      }
+
+      .login_other_type
+      {
+
+        width: 100%;
+        height: auto;
+        margin-top: 10px;
+        .other_login_line
+        {
+          display: flex;
+          justify-content: center;
+          height: 52px;
+          align-items: center;
+          .line 
+          {
+            flex: 1;
+            height: 1px;
+            background-color: #dcdfe6;
+          }
+          
+          .text 
+          {
+            margin: 0 10px;
+
+            font-weight: 400;
+            font-size: 14px;
+            color: #999999;
+            img {
+              width: 32px;
+            }
+          }
+        }
+
+        .other_login_icon
+        {
+          display: flex;
+          justify-content: center;
+          .icon_item
+          {
+            width: auto;
+            height: auto;
+            text-align: center;
+            padding:10px 10px;
+            img
+            {
+              width: 32px;
+              height: 32px;
+              cursor: pointer;
+            }
+
+            p
+            {
+              font-weight: 400;
+              font-size: 12px;
+              color: #909399;
+              line-height: 20px;
+            }
+          }
+        }
+      }
+      .wechat_login {
+        .text {
+          font-size: 16px;
+          font-weight: 500;
+          color: #303133;
+          text-align: center;
+          margin-top: 20px;
+          margin-bottom: 10px;
+        }
+        .wechat_url {
+          margin-left: 50px;
+          width: 220px;
+          height: 220px;
+          img {
+            width: 100%;
+            height: 100%;
+          }
+        }
+      }
+    }
+  }
 }

+ 463 - 0
src/views/login/components/FindPassWord.vue

@@ -0,0 +1,463 @@
+<template>
+    <div class="LoginIDItem">
+      <div class="backIdLogin">
+        <i class="el-icon-arrow-left"  @click="backLogin(1)" style="opacity: 1;"></i>
+        <span>忘记密码</span>
+      </div>
+      <el-steps  :active="active" finish-status="success" style="margin-top: 40px;">
+        <el-step title="验证信息"></el-step>
+        <el-step title="设置密码"></el-step>
+        <el-step title="修改完成"></el-step>
+      </el-steps> 
+      <el-form class="login-form" ref="register" :style="{ marginTop: active == 1 ? '55px' : '68px' }" :rules="rules">
+        <div class="emailNoLogin">
+          <el-form-item v-show="active==0">
+            <el-input v-model="emailNo" placeholder="请输入邮箱" prefix-icon="el-icon-user" :clearable="true" :style="{'--inputColor': emailinfo ? infoRex : infoRexerr}">
+            </el-input>
+            <p class="errorInfo" v-show="isDisplay">{{ errorInfo }}</p>
+          </el-form-item>
+          <el-form-item v-show="active==0">
+            <div class="inputDeep emailCodeWrap">
+              <el-input v-model="emailCode" type="emailCode" placeholder="请输入验证码"
+                @keydown.enter.native="login" prefix-icon="iconfont icon-dunpaibaoxianrenzheng_o" :style="{'--inputColor': !emailinfo ? infoRex : infoRexerr}"></el-input>
+                <p class="errorInfo" v-show="isCodeDisplay">{{ errorCodeInfo }}</p>
+              <div class="getemailCode" @click="timeCount" :class="{'send': !isBegainGetCode, 'reget': isBegainGetCode}">
+                {{ isBegainGetCode ? `${countTime}s后重新获取` : "发送" }}
+              </div>
+  
+            </div>
+          </el-form-item>
+  
+        </div>
+        <el-form-item v-show="active==1" prop="password">
+            <el-input v-model="register.password" :type="showPassword ? 'text' : 'password'" placeholder="请输入新密码" :clearable="true" @keydown.enter.native="login"
+            prefix-icon="el-icon-lock" :style="{'--inputColor': emailNewinfo ? infoRex : infoRexerr}"  @input="validatePassword">
+            <template #suffix>
+              <i
+                :class="showPassword ? 'el-icon-view' : 'iconfont icon-ttubiao_hide'"
+                @click="togglePasswordVisibility"
+              ></i>
+            </template>
+          </el-input>
+        </el-form-item>
+        <el-form-item v-show="active==1" prop="checkPassword">
+          <el-input v-model="register.checkPassword" :type="showCheckPassword ? 'text' : 'password'" placeholder="请再次输入新密码" :clearable="true" @keydown.enter.native="login"
+          prefix-icon="el-icon-lock" :style="{'--inputColor': !emailNewinfo ? infoRex : infoRexerr}">
+            <template #suffix>
+              <i
+                :class="showCheckPassword ? 'el-icon-view' : 'iconfont icon-ttubiao_hide'"
+                @click="togglecheckPasswordVisibility"
+              ></i>
+            </template>
+          </el-input>
+        </el-form-item>
+        <el-form-item v-show="active==1">
+          <div style="text-align: left;color:#606266;font-size:12px;">
+            <p><i :class="['el-icon-success', passwordValidations.lengthValid ? 'valid' : '']"></i>&nbsp;<span>密码由8-16位数字、字母或符号组成</span></p>
+            <p style="margin-top: 5px;"><i :class="['el-icon-success', passwordValidations.complexityValid ? 'valid' : '']"></i>&nbsp;<span>至少包含大写字母、小写字母、数字和特殊符号中的至少三种组合</span></p>
+          </div>
+        </el-form-item>
+        <el-form-item v-show="active==2" style="margin-top: 138px;">
+          <div style="font-size:16px;">恭喜你,密码修改成功!</div>
+        </el-form-item>
+        <el-form-item>
+          <div class="btnWrap" :style="{ marginTop: computedMarginTop }">
+            <el-button type="primary" style="width:100%;" @click="nextInfo">{{ active==2 ? "立即登录":"下一步" }}</el-button>
+          </div>
+        </el-form-item>
+      </el-form>
+    </div>
+  </template>
+  <script>
+  import user from '@/http/api/user'
+  import { setToken } from '@/utils/auth'
+  export default {
+    name: "LoginForID",
+    data(){
+      // 密码验证
+      let validatePass = (rule, value,callback) =>{
+        if(this.register.password == "" || this.register.password == undefined){
+          this.infoRex = "#F56C6C";
+          this.emailNewinfo = true;
+          callback(new Error('请输入密码'));
+          // callback()
+        }else{
+          if(this.register.checkPassword !=""){
+            this.$refs.register.validateField('checkPassword');
+          }
+          callback()
+        }
+      }
+      // 密码再次验证
+      let validateCheckPass = (rule, value,callback) =>{
+        if(this.register.checkPassword == "" || this.register.checkPassword == undefined){
+          this.infoRex = "#F56C6C";
+          this.emailNewinfo = false;
+          callback(new Error('请再次输入密码'));
+          // callback()
+        }else{
+          if(this.register.checkPassword !=this.register.password){
+            this.infoRex = "#F56C6C";
+            this.emailNewinfo = false;
+            callback(new Error('两次输入密码不一致!'));
+            // callback()
+          } else{
+            this.infoRex = "#DCDFE6";
+            callback();
+          }
+        }
+      }
+      return{
+        emailNo:null,
+        emailCode:null,
+        countTime:60,
+        isBegainGetCode:false,
+        errorInfo:"",
+        emailNewinfo:"",
+        errorCodeInfo:"",
+        infoRex:"#DCDFE6",
+        isDisplay:false,
+        isCodeDisplay:false,
+        emailinfo:true,
+        infoRexerr:"#DCDFE6",
+        active:0,
+        showPassword:false,
+        showCheckPassword:false,
+        register:{
+          password:"",
+          checkPassword:""
+        },
+        rules:{
+          password:[{validator: validatePass, trigger: "blur"}],
+          checkPassword:[{validator: validateCheckPass, trigger: "blur"}],
+        },
+        passwordValidations: {
+          lengthValid: false,
+          complexityValid: false,
+        },
+      }
+    },
+    mounted(){
+  
+    },
+    computed: {
+      computedMarginTop() {
+        if(this.active == 1 ){
+          return '16px'
+        }else if(this.active == 2){
+          return '105px'
+        }else{
+          return '70px'
+        }
+      }
+    },
+    methods: {
+      nextInfo(){
+          if(this.active == 0){
+            let data = {
+              email:this.emailNo,
+              code:this.emailCode
+            }
+            user.checkEmailCode(data).then((res)=>{
+              if(res.code!=200){
+                this.errorCodeInfo = res.msg;
+                this.isCodeDisplay = true;
+                this.infoRex = "#F56C6C";
+                this.emailinfo = false;
+                return;
+              } else {
+                this.active=1;
+              }
+            }).catch(()=>{
+              this.$message({
+                  message: "请求超时,请检查网络连接",
+                  type: 'error'
+                });
+            })
+            // this.active++
+          }else if(this.active == 1){
+            if(!this.passwordValidations.complexityValid){
+              this.$message({
+                  message: "密码中至少包含大写字母、小写字母、数字和特殊符号中的至少三种组合",
+                  type: 'warning'
+                });
+                return;
+            }
+            if(!this.passwordValidations.lengthValid){
+              this.$message({
+                  message: "密码由8-16位数字、字母或符号组成",
+                  type: 'warning'
+                });
+                return;
+            }
+            let data = {
+              email:this.emailNo,
+              newPassword:this.register.password,
+              confirmNewPassword:this.register.checkPassword,
+              code:this.emailCode
+            }
+            user.updateEmailCodePassword(data).then((res)=>{
+              if(res.code!=200){
+                this.errorCodeInfo = res.msg;
+                this.isCodeDisplay = true;
+                this.infoRex = "#F56C6C";
+                this.emailinfo = false;
+                return;
+              } else {
+                this.active=2;
+              }
+            }).catch(()=>{
+              this.$message({
+                  message: "请求超时,请检查网络连接",
+                  type: 'error'
+                });
+            })
+          }else if(this.active == 2){
+            this.$emit('update-nav-status', 1);
+          }else{
+            if (this.active++ == 2) return this.active = 2;
+          }
+      },
+      changeRemeberPW(e){
+       
+      },
+      goHome(){
+  
+      },
+      timeCount(){
+        this.isCodeDisplay = false;
+        let reg = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
+        if(!this.emailNo){
+          this.errorInfo = '请输入邮箱号';
+          this.infoRex = "#F56C6C";
+          this.isDisplay = true;
+          this.emailinfo = true;
+          return;
+        }else if(this.emailNo !=="" && !reg.test(this.emailNo)) {
+          this.errorInfo = '该邮箱不存在';
+          this.infoRex = "#F56C6C";
+          this.isDisplay = true;
+          this.emailinfo = true;
+          return; 
+        }else{
+          this.errorInfo = "";
+          this.infoRex = "#DCDFE6";
+          this.isDisplay = false;
+          this.emailinfo = true;
+        }
+          
+        
+        if(this.isBegainGetCode)return;
+        this.countTime = 60;
+        this.isBegainGetCode=true;
+        let that = this;
+        function countdown() {
+          that.countTime = that.countTime -1;
+          if (that.countTime <= 0) {
+            clearTimeout(timeout);
+            that.isBegainGetCode=false;
+          } else {
+            timeout = setTimeout(countdown, 1000);
+          }
+        }
+        let timeout = setTimeout(countdown, 1000);
+        let params = {
+          "email":this.emailNo
+          }
+        user.sendReSetPwdEmailCode(params).then((res)=>{
+          if(res.code!=200){
+            this.$message({
+              message: res.data,
+              type: 'warning'
+            });
+            return;
+          }else{
+            this.$message({
+              message: "已发送验证码",
+              type: 'success'
+            });
+          }
+        
+        }).catch(()=>{
+          this.$message({
+              message: "请求超时,请检查网络连接",
+              type: 'error'
+            });
+        })
+      },
+      backLogin(newStatus){
+        this.$emit('update-nav-status', newStatus);
+      },
+      togglePasswordVisibility(){
+        this.showPassword = !this.showPassword;
+      },
+      togglecheckPasswordVisibility(){
+        this.showCheckPassword = !this.showCheckPassword;
+      },
+      validatePassword() {
+        let lengthRegex = /.{8,16}/;
+        let upperCaseRegex = /[A-Z]/;
+        let lowerCaseRegex = /[a-z]/;
+        let numberRegex = /[0-9]/;
+        let specialCharRegex = /[!@#$%^&*(),.?":{}|<>]/;
+
+        let lengthValid = lengthRegex.test(this.register.password);
+        let upperCaseValid = upperCaseRegex.test(this.register.password);
+        let lowerCaseValid = lowerCaseRegex.test(this.register.password);
+        let numberValid = numberRegex.test(this.register.password);
+        let specialCharValid = specialCharRegex.test(this.register.password);
+
+        this.passwordValidations.lengthValid = lengthValid;
+
+        let validCount = 0;
+        if (upperCaseValid) validCount++;
+        if (lowerCaseValid) validCount++;
+        if (numberValid) validCount++;
+        if (specialCharValid) validCount++;
+
+        this.passwordValidations.complexityValid = validCount >= 3;
+      },
+    }
+  }
+  </script>
+  <style lang="scss" scoped>
+  .LoginIDItem {
+    width: 354px;
+    margin: 0 auto;
+    .inputTab {
+      display: flex;
+      justify-content: space-between;
+      margin-bottom: 20px;
+      div {
+        width: 100%;
+        height: 40px;
+        color: #409EFF;
+        font-size: 16px;
+        text-align: center;
+        line-height: 40px;
+        cursor: pointer;
+        border-bottom: 1px solid #DCDFE6;
+  
+        &.active {
+          color: #409EFF;
+          border-bottom: 1px solid #409EFF;
+        }
+      }
+    }
+  
+    .itmeWrap {
+      display: flex;
+    }
+  
+    .btnWrap {
+      width: 100%;
+    }
+  
+    .emailCodeWrap {
+      position: relative;
+  
+      .getemailCode {
+        position: absolute;
+        right: 10px;
+        top: 15px;
+        font-size: 12px;
+        cursor: pointer;
+        border-left: 0.5px solid #C6C6C6;
+        height: 25px;
+        line-height: 25px;
+        padding-left: 5px;
+      }
+      .send {
+        color: #2E64FA; /* 发送字体颜色为蓝色 */
+      }
+      
+      .reget {
+        color: #606266;; /* 重新获取字体颜色为灰色 */
+      }
+    }
+    .login-form{
+      margin-top: 100px;
+      .el-form-item{
+        margin-top:20px;
+        .errorInfo{
+          color: #F56C6C;
+          font-size: 12px;
+          text-align: left;
+        }
+        :deep()  .el-input__inner{
+          height: 53px;
+          line-height: 53px;
+          border-radius: 10px;
+          border-color: var(--inputColor);
+        }
+        :deep() .el-form-item__content{
+          line-height: 18px;
+        }
+      }
+    }
+    .btnWrap {
+      height: 53px;
+      margin-top: 70px;
+      .el-button{
+        height:53px;
+        border-radius: 10px;
+        font-size:16px;
+      }
+    }
+    :deep() .el-steps .el-step .is-process .el-step__icon  {
+      background-color: #2E64FA; /* 修改图标背景色 */
+      border-color: #2E64FA;     /* 修改图标边框色 */
+      color: #fff;               /* 修改图标文字色 */
+    }
+    :deep() .el-steps .el-step .is-process .el-step__line {
+      background-color: #2E64FA; /* 修改连接线颜色 */
+    }
+    :deep() .el-steps .el-step .el-step__title.is-process {
+      color: #2E64FA; /* 修改标题颜色 */
+    }
+    :deep() .el-steps .el-step .is-success .el-step__icon  {
+      background-color: #15BC83; /* 修改图标背景色 */
+      border-color: #15BC83;     /* 修改图标边框色 */
+      color: #fff;               /* 修改图标文字色 */
+    }
+    :deep() .el-steps .el-step .is-success .el-step__line {
+      background-color: #15BC83; /* 修改连接线颜色 */
+    }
+    :deep() .el-steps .el-step .el-step__title.is-success {
+      color: #15BC83; /* 修改标题颜色 */
+    }
+    /* 确保图标居中 */
+    :deep() .el-steps .el-step .el-step__icon {
+      display: flex;
+      align-items: center;
+      justify-content: center;
+    }
+    :deep()  .el-input__suffix{
+      line-height: 53px;
+    }
+  }
+  .backIdLogin{
+    width: 88.57px;
+    height: 22px;
+    
+    span{
+      font-size: 16px;
+      font-weight: 500;
+      line-height: 22.4px;
+      text-align: left;
+      color: #303133;
+  
+    }
+    i{
+      width: 20.57px;
+      height: 18px;
+      gap: 0px;
+      opacity: 0px;
+      cursor: pointer;
+    }
+  
+  }
+  .valid {
+    color: #15BC83;
+  }
+  </style>

+ 271 - 0
src/views/login/components/ForgetPassWord.vue

@@ -0,0 +1,271 @@
+<template>
+  <div>
+    <!-- <GoBack>忘记密码</GoBack> -->
+    <div class="forget_password_page">
+      <!-- <div class="step_box">
+        <div v-for="step in steps" :key="step.number" class="step_item"
+          :class="{ 'process': step.number == currentStep, 'finish': step.number < currentStep }"
+        >
+          <div class="step_header">
+            <div class="step_number">
+              <i class="iconfont icon_xiala" v-if="step.number < currentStep" />
+              <span v-else>{{ step.number }}</span>
+            </div>
+            <div class="step_line"></div>
+          </div>
+          <div class="step_label">{{ step.label }}</div>
+        </div>
+      </div> -->
+      <div v-show="currentStep == 1" class="login_info_input">
+        <el-form :model="validForm" :rules="validFormrules" ref="validFormRef">
+          <el-form-item prop="cellPhoneNumber">
+            <el-input v-model="validForm.cellPhoneNumber" placeholder="请输入手机号码" clearable prefix-icon="iconfont icon_shoujihao" />
+          </el-form-item>
+          <el-form-item prop="validateCode">
+            <el-input v-model="validForm.validateCode" placeholder="请输入验证码" prefix-icon="iconfont icon_yanzhengma">
+              <template slot="suffix">
+                <span class="get_code" @click="GetCode">{{ codeText }}</span>
+              </template>
+            </el-input>
+          </el-form-item>
+        </el-form>
+      </div>
+      <div v-show="currentStep == 2" class="login_info_input">
+        <el-form :model="setPassWordForm" :rules="setPassWordFormrules" ref="setPassWordFormRef">
+          <el-form-item prop="newPassWord">
+            <el-input v-model="setPassWordForm.newPassWord" type="password" placeholder="请输入新密码" clearable show-password prefix-icon="iconfont icon_mima" />
+          </el-form-item>
+          <el-form-item prop="validateNewPassWord">
+            <el-input v-model="setPassWordForm.validateNewPassWord" type="password" placeholder="再次输入新密码" show-password clearable prefix-icon="iconfont icon_mima" />
+          </el-form-item>
+        </el-form>
+      </div>
+      <div class="login_info_button">
+        <el-button :loading="loading" @click="NextStep()">{{currentStep == 2 ? '确认' : '下一步'}}</el-button>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+// import GoBack from "./GoBack";
+export default {
+  // components: { GoBack },
+  data() {
+    return {
+      steps: [
+        { number: 1, label: '验证信息' },
+        { number: 2, label: '设置密码' },
+        { number: 3, label: '修改完成' }
+      ],
+      currentStep: 1, // 1-验证短信, 2-重置密码
+      validForm: {
+        cellPhoneNumber: '',
+        validateCode: ''
+      },
+      validFormrules: {
+        cellPhoneNumber: [
+          {required: true, message: '请输入手机号码', trigger: ['blur', 'change']}
+        ],
+        validateCode: [
+          {required: true, message: '请输入验证码', trigger: ['blur', 'change']}
+        ]
+      },
+      codeText: '获取验证码',
+      count: 60, // 倒数秒数
+      isCount: false, // 是否倒计时
+      loading: false,
+      setPassWordForm: {
+        newPassWord: '',
+        validateNewPassWord: '',
+      },
+      setPassWordFormrules: {
+        newPassWord: [
+          {required: true, message: '请输入密码', trigger: ['blur', 'change']},
+          {min: 6, message: '长度最少为6位', trigger: 'blur'}
+        ],
+        validateNewPassWord: [
+          {required: true, message: '请输入确认密码', trigger: ['blur', 'change']},
+          {
+            validator: (rule, value, callback) => {
+              if (this.setPassWordForm.newPassWord && value !== this.setPassWordForm.newPassWord) {
+                callback(new Error('两次输入的密码不一致'));
+              } else {
+                callback();
+              }
+            },
+            trigger: 'blur'
+          }
+        ]
+      }
+    }
+  },
+  methods: {
+    // 获取验证码
+    GetCode() {
+      if(!this.validForm.cellPhoneNumber) {
+        this.$refs.validFormRef.validateField('cellPhoneNumber')
+        return
+      }
+      if(this.isCount) return
+      this.$api.user.getPhoneValidCode({
+        phoneNumber: this.validForm.cellPhoneNumber
+      }).then(res => {
+        if(res.code == 200) {
+          this.isCount = true
+          this.codeText = `${this.count} 秒`
+          const timer = setInterval(() => {
+            this.count--;
+            this.codeText = `${this.count} 秒`;
+            if (this.count <= 0) {
+              clearInterval(timer);
+              this.isCount = false;
+              this.count = 60;
+              this.codeText = '重新获取'
+            }
+          }, 1000);
+        }else {
+          this.$message.error(res.msg)
+        }
+      })
+    },
+    NextStep() {
+      if(this.currentStep == 1) {
+        this.$refs.validFormRef.validate((valid) => {
+          if (valid) {
+            try {
+              this.loading = true
+              this.$api.user.validCode({
+                phone: this.validForm.cellPhoneNumber,
+                verificationCode: this.validForm.validateCode,
+              }).then(res => {
+                if(res.code === 200) {
+                  this.currentStep = 2;
+                } else {
+                  this.$message.error(res.msg)
+                }
+              })
+              this.loading = false
+            } catch {
+              this.loading = false
+            }
+          } else {
+            return false;
+          }
+        });
+      } else if(this.currentStep == 2) {
+        this.$refs.setPassWordFormRef.validate(valid => {
+          if(valid) {
+            try {
+              this.loading = true
+              this.$api.user.setPassWord({
+                phone: this.validForm.cellPhoneNumber,
+                password: this.setPassWordForm.newPassWord
+              }).then(res => {
+                if(res.code == 200) {
+                  this.$message.success(res.msg)
+                  this.$emit('GoLogin')
+                } else {
+                  this.$message.error(res.msg)
+                }
+              })
+              this.loading = false
+            } catch {
+              this.loading = false
+            }
+          } else {
+            return false;
+          }
+        });
+      }
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.forget_password_page {
+  display: flex;
+  flex-direction: column;
+  justify-content: space-between;
+  .step_box {
+    display: flex; 
+    width: 90%;
+    margin: 0 auto;
+    .step_item {
+      &:not(:last-child) {
+        flex: 1;
+      }
+      min-width: 0;
+      .step_header {
+        display: flex;
+        align-items: center;
+        margin-bottom: 20px;
+        .step_number {
+          width: 24px;
+          height: 24px;
+          line-height: 24px;
+          margin: 0 10px;
+          border: 2px solid #909399;
+          text-align: center;
+          border-radius: 50%;
+          font-weight: 500;
+          color: #909399;
+        }
+        .step_line {
+          flex: 1;
+          height: 2px;
+          background: #DCDFE6;
+        }
+      }
+      .step_label {
+        color: #909399;
+        font-weight: 500;
+      }
+      &.process {
+        .step_header .step_number {
+          background: #2E64FA;
+          border-color: #2E64FA;
+          color: #fff;
+        }
+        .step_line {
+          background: #2E64FA;
+        }
+        .step_label {
+          color: #2E64FA;
+        }
+      }
+      &.finish {
+        .step_header .step_number {
+          background: #15BC83;
+          border-color: #15BC83;
+          color: #fff;
+        }
+        .step_line {
+          background: #15BC83;
+        }
+        .step_label {
+          color: #15BC83;
+        }
+        
+      }
+    }
+    .step_item:last-of-type {
+      .step_header .step_line {
+        display: none;
+      }
+    }
+  }
+  .get_code {
+    color: #2E64FA;
+    cursor: pointer;
+  }
+  .login_info_button {
+    margin-top: 19px;
+    .el-button {
+      width: 100%;
+    }
+  }
+}
+
+</style>

+ 29 - 0
src/views/login/components/GoBack.vue

@@ -0,0 +1,29 @@
+<template>
+  <div class="back_box">
+    <i class="iconfont icon_return" @click="GoBack" />
+    <slot />
+  </div>
+</template> 
+
+<script>
+export default {
+  name: 'GoBack',
+  inject: ['setTabActive'],
+  methods: {
+    GoBack() {
+      this.setTabActive()
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.back_box {
+  margin-bottom: 40px;
+  font-size: 16px;
+  .icon_return {
+    margin-right: 10px;
+    cursor: pointer;
+  }
+}
+</style>

+ 286 - 0
src/views/login/components/LoginForEmail.vue

@@ -0,0 +1,286 @@
+<template>
+  <div class="LoginIDItem">
+    <div class="backIdLogin">
+      <i class="el-icon-arrow-left"  @click="backLogin(1)" style="opacity: 1;"></i>
+      <span>邮箱登录</span>
+    </div>
+    <el-form class="login-form">
+      <div class="emailNoLogin">
+        <el-form-item>
+          <el-input v-model="emailNo" placeholder="请输入邮箱" prefix-icon="el-icon-user" :clearable="true" :style="{'--inputColor': emailinfo ? infoRex : infoRexerr}">
+          </el-input>
+          <p class="errorInfo" v-show="isDisplay">{{ errorInfo }}</p>
+        </el-form-item>
+        <el-form-item>
+          <div class="inputDeep emailCodeWrap">
+            <el-input v-model="emailCode" type="emailCode" placeholder="请输入验证码"
+              @keydown.enter.native="login" prefix-icon="iconfont icon-dunpaibaoxianrenzheng_o" :style="{'--inputColor': !emailinfo ? infoRex : infoRexerr}"></el-input>
+              <p class="errorInfo" v-show="isCodeDisplay">{{ errorCodeInfo }}</p>
+
+            <div class="getemailCode" @click="timeCount" :class="{'send': !isBegainGetCode, 'reget': isBegainGetCode}">
+              {{ isBegainGetCode ? `${countTime}s后重新获取` : "发送" }}
+            </div>
+
+          </div>
+        </el-form-item>
+
+      </div>
+      <el-form-item>
+        <div class="btnWrap">
+          <el-button type="primary" style="width:100%;" @click="login">登 录</el-button>
+        </div>
+      </el-form-item>
+    </el-form>
+  </div>
+</template>
+<script>
+import user from '@/http/api/user'
+import { setToken } from '@/utils/auth'
+export default {
+  name: "LoginForEmail",
+  data(){
+    return{
+      username:"",
+      password:"",
+      remeberPassWord:false,
+      tabIndex:1,
+      emailNo:null,
+      emailCode:null,
+      countTime:60,
+      isBegainGetCode:false,
+      errorInfo:"",
+      errorCodeInfo:"",
+      infoRex:"#DCDFE6",
+      isDisplay:false,
+      isCodeDisplay:false,
+      emailinfo:true,
+      infoRexerr:"#DCDFE6"
+    }
+  },
+  mounted(){
+  },
+  methods: {
+    login(){
+      let data = {
+        email:this.emailNo,
+        code:this.emailCode
+      }
+      
+      user.emailLogin(data).then((res)=>{
+        if(res.code!=200){
+          this.errorCodeInfo = res.msg;
+          this.isCodeDisplay = true;
+          this.infoRex = "#F56C6C";
+          this.emailinfo = false;
+          return;
+        } else {
+          setToken(res.data.tokenValue)
+          this.$store.dispatch('user/SET_TOKEN', res.data.tokenValue)
+          let directUrl = this.$route.query.redirect;
+          let url = directUrl?directUrl:'/userInfo';
+          this.$router.push({path:url})
+          this.$message({
+            message:'验证通过,登录成功',
+            type: "success"
+          });
+        }
+        console.log(res);
+      }).catch(()=>{
+        this.$message({
+            message: "请求超时,请检查网络连接",
+            type: 'error'
+          });
+      })
+      
+    },
+    changeRemeberPW(e){
+      // console.log(e,"e--=")
+      if(e){
+        localStorage.setItem("userName",this.username);
+        localStorage.setItem("userPassWord",this.password);
+      }else{
+        localStorage.setItem("userName","");
+        localStorage.setItem("userPassWord","");
+      }
+    },
+    goHome(){
+
+    },
+    loginTabChange(index){
+      this.tabIndex = index;
+    },
+    timeCount(){
+      this.isCodeDisplay = false;
+      // let reg = /^[A-Za-z0-9\u4e00-\u9fa5]+@[A-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/;
+      let reg = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
+      if(!this.emailNo){
+        this.errorInfo = '请输入邮箱号';
+        this.infoRex = "#F56C6C";
+        this.isDisplay = true;
+        this.emailinfo = true;
+        return;
+      }else if(this.emailNo !=="" && !reg.test(this.emailNo)) {
+        this.errorInfo = '该邮箱不存在';
+        this.infoRex = "#F56C6C";
+        this.isDisplay = true;
+        this.emailinfo = true;
+        return; 
+      }else{
+        this.errorInfo = "";
+        this.infoRex = "#DCDFE6";
+        this.isDisplay = false;
+        this.emailinfo = true;
+      }
+        
+      
+      if(this.isBegainGetCode)return;
+      this.countTime = 60;
+      this.isBegainGetCode=true;
+      let that = this;
+      function countdown() {
+        that.countTime = that.countTime -1;
+        if (that.countTime <= 0) {
+          clearTimeout(timeout);
+          that.isBegainGetCode=false;
+        } else {
+          timeout = setTimeout(countdown, 1000);
+        }
+      }
+      let timeout = setTimeout(countdown, 1000);
+      let params = {
+        "email":this.emailNo
+      }
+      user.sendLoginEmailCode(params).then((res)=>{
+        if(res.code!=200){
+          this.$message({
+            message: res.data,
+            type: 'warning'
+          });
+          return;
+        }else{
+          this.$message({
+            message: "已发送验证码",
+            type: 'success'
+          });
+        }
+       
+      }).catch(()=>{
+        this.$message({
+            message: "请求超时,请检查网络连接",
+            type: 'error'
+          });
+      })
+    },
+    backLogin(newStatus){
+      this.$emit('update-nav-status', newStatus);
+    }
+  }
+}
+</script>
+<style lang="scss" scoped>
+.LoginIDItem {
+  width: 354px;
+  padding-bottom: 20px;
+  .inputTab {
+    display: flex;
+    justify-content: space-between;
+    margin-bottom: 20px;
+    div {
+      width: 100%;
+      height: 40px;
+      color: #409EFF;
+      font-size: 16px;
+      text-align: center;
+      line-height: 40px;
+      cursor: pointer;
+      border-bottom: 1px solid #DCDFE6;
+
+      &.active {
+        color: #409EFF;
+        border-bottom: 1px solid #409EFF;
+      }
+    }
+  }
+
+  .itmeWrap {
+    display: flex;
+  }
+
+  .btnWrap {
+    width: 100%;
+  }
+
+  .emailCodeWrap {
+    position: relative;
+
+    .getemailCode {
+      position: absolute;
+      right: 10px;
+      top: 15px;
+      font-size: 12px;
+      cursor: pointer;
+      border-left: 0.5px solid #C6C6C6;
+      height: 25px;
+      line-height: 25px;
+      padding-left: 5px;
+    }
+    .send {
+      color: #2E64FA; /* 发送字体颜色为蓝色 */
+    }
+    
+    .reget {
+      color: #606266;; /* 重新获取字体颜色为灰色 */
+    }
+  }
+  .login-form{
+    margin-top: 160px;
+    .el-form-item{
+      margin-top:20px;
+      .errorInfo{
+        color: #F56C6C;
+        font-size: 12px;
+        text-align: left;
+      }
+      :deep()  .el-input__inner{
+        height: 53px;
+        line-height: 53px;
+        border-radius: 10px;
+        border-color: var(--inputColor);
+      }
+      :deep() .el-form-item__content{
+        line-height: 18px;
+      }
+    }
+  }
+  .btnWrap {
+    height: 53px;
+    margin-top: 70px;
+    .el-button{
+      height:53px;
+      border-radius: 10px;
+      font-size:16px;
+    }
+  }
+}
+.backIdLogin{
+  width: 88.57px;
+  height: 22px;
+  
+  span{
+    font-size: 16px;
+    font-weight: 500;
+    line-height: 22.4px;
+    text-align: left;
+    color: #303133;
+
+  }
+  i{
+    width: 20.57px;
+    height: 18px;
+    gap: 0px;
+    opacity: 0px;
+    cursor: pointer;
+  }
+
+}
+</style>

+ 351 - 0
src/views/login/components/LoginForID.vue

@@ -0,0 +1,351 @@
+<template>
+  <div class="LoginIDItem">
+    <div class="LoginName tl">
+      HI~欢迎使用<br />
+      大数据精准教学诊断平台
+    </div>
+    <div class="itemName fs16 lh22 fw tl">账号密码登录</div>
+    <el-form class="login-form">
+      <el-form-item>
+        <el-input size="medium" v-model="username" placeholder="请输入账号">
+          <template #prefix>
+            <span>
+              <img
+                src="@/assets/icon/user_icon.png"
+                alt="User Icon"
+                style="width: 18px; height: 18px"
+              />
+            </span>
+          </template>
+          <template #suffix v-if="username != ''">
+            <span @click="clearInput" style="cursor: pointer">
+              <img
+                src="@/assets/icon/userName_clear.png"
+                alt="Clear Icon"
+                style="width: 18px; height: 18px"
+              />
+            </span>
+          </template>
+        </el-input>
+      </el-form-item>
+      <el-form-item>
+        <div class="inputDeep">
+          <el-input
+            v-model="password"
+            :type="showPassword ? 'text' : 'password'"
+            placeholder="请输入密码"
+            @keydown.enter.native="login"
+          >
+            <template #prefix>
+              <span>
+                <img
+                  src="@/assets/icon/passWord_icon.png"
+                  alt="User Icon"
+                  style="width: 18px; height: 18px"
+                />
+              </span>
+            </template>
+            <template #suffix>
+              <span
+                v-if="showPassword"
+                @click="togglePasswordVisibility"
+                class="display_style"
+              >
+                <img
+                  src="@/assets/icon/passWord_show.png"
+                  alt="User Icon"
+                  style="width: 18px; height: 18px"
+                />
+              </span>
+              <i
+                v-else
+                class="iconfont icon-ttubiao_hide"
+                @click="togglePasswordVisibility"
+              ></i>
+            </template>
+          </el-input>
+        </div>
+      </el-form-item>
+      <el-form-item style="margin-bottom: -10px; margin-top: -10px">
+        <div class="itmeWrap">
+          <el-checkbox
+            v-model="remeberPassWord"
+            @change="changeRemeberPW"
+            style="line-height: 39.6px"
+            >记住密码</el-checkbox
+          >
+          <el-button type="text" class="forgetPassWord" @click="emailLogin(3)"
+            >忘记密码</el-button
+          >
+        </div>
+      </el-form-item>
+      <el-form-item>
+        <div class="btnWrap">
+          <el-button type="primary" style="width: 100%" @click="login"
+            >登 录</el-button
+          >
+        </div>
+      </el-form-item>
+    </el-form>
+    <div class="other-login">
+      <span class="line"></span>
+      <span class="text">其他登录方式</span>
+      <span class="line"></span>
+    </div>
+    <div
+      class="text"
+      style="
+        font-size: 13px;
+        cursor: pointer;
+        display: flex;
+        justify-content: center;
+      "
+    >
+      <div style="padding-right: 42px">
+        <img src="../../../assets/weChat.png" alt="" />
+        <p class="margin_top4">微信</p>
+      </div>
+      <div style="padding-right: 42px">
+        <img src="../../../assets/ding.png" alt="" />
+        <p class="margin_top4">钉钉</p>
+      </div>
+      <div>
+        <img src="../../../assets/email.png" alt="" @click="emailLogin(2)" />
+        <p class="margin_top4">邮箱</p>
+      </div>
+    </div>
+  </div>
+</template>
+<script>
+import user from "@/http/api/user";
+import { setToken } from "@/utils/auth";
+export default {
+  name: "LoginForID",
+  data() {
+    return {
+      username: "",
+      password: "",
+      remeberPassWord: false,
+      tabIndex: 1,
+      phoneNumber: null,
+      phoneCode: null,
+      countTime: 60,
+      isBegainGetCode: false,
+      showPassword: false,
+    };
+  },
+  mounted() {
+    this.loadCredentials();
+    
+  },
+ 
+  methods: {
+    loadCredentials() {
+      const userName = localStorage.getItem("userName");
+      const password = localStorage.getItem("userPassWord");
+      this.username = userName || "";
+      this.password = password || "";
+      if (this.username && this.password) {
+        this.remeberPassWord = true;
+      }
+    },
+    clearInput() {
+      this.username = "";
+    },
+    login() {
+      const params = {
+        username: this.username.trim(),
+        password: this.password,
+      };
+
+      if (!params.username) {
+        this.$message({
+          message: "用户名不能为空!",
+          type: "warning",
+        });
+        return;
+      }
+
+      if (!params.password) {
+        this.$message({
+          message: "密码不能为空!",
+          type: "warning",
+        });
+        return;
+      }
+
+      user
+        .login(params)
+        .then((res) => {
+          if (res.code === 200) {
+            console.log("打印登录结果", res);
+            setToken(res.data.tokenValue);
+            this.$store.dispatch("user/SET_TOKEN", res.data.tokenValue);
+            const menuList = res.data.pcMenuVOS || [];
+            this.$store.commit("user/SET_MENULIST", menuList); //设置菜单
+            this.$store.commit("user/SET_USEAR_INFOLOGIN", res.data);
+            this.$store.dispatch("user/getInfo"); //获取用户登录信息
+            if (this.remeberPassWord) {
+              localStorage.setItem("userName", params.username);
+              localStorage.setItem("userPassWord", params.password);
+            } else {
+              localStorage.removeItem("userName");
+              localStorage.removeItem("userPassWord");
+            }
+
+            const directUrl = this.$route.query.redirect || "/userInfo";
+            this.$router.push({ path: directUrl });
+          }
+        })
+        .catch((err) => {
+          this.$message({
+            message: "登录失败,请稍后再试。",
+            type: "warning",
+          });
+          console.error(err);
+        });
+    },
+    changeRemeberPW(e) {
+      if (e) {
+        localStorage.setItem("userName", this.username);
+        localStorage.setItem("userPassWord", this.password);
+      } else {
+        localStorage.removeItem("userName");
+        localStorage.removeItem("userPassWord");
+        this.username = "";
+        this.password = "";
+      }
+    },
+    goHome() {},
+    loginTabChange(index) {
+      this.tabIndex = index;
+    },
+    emailLogin(newStatus) {
+      this.$emit("update-nav-status", newStatus);
+    },
+    togglePasswordVisibility() {
+      this.showPassword = !this.showPassword;
+    },
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+.LoginIDItem {
+  margin: 0 auto;
+  width: 354px;
+
+  .LoginName {
+    font-size: 32px;
+    text-align: left;
+    color: #333333;
+    line-height: 48px;
+  }
+
+  .itemName {
+    color: #333333;
+    margin-top: 14px;
+  }
+
+  .login-form {
+    .el-form-item {
+      margin-top: 20px;
+
+      :deep() .el-input__inner {
+        height: 53px;
+        line-height: 53px;
+        border-radius: 10px;
+      }
+
+      :deep() .el-form-item__content {
+        line-height: 18px;
+      }
+    }
+
+    .inputDeep {
+      :deep() .el-input__suffix {
+        line-height: 53px;
+      }
+    }
+  }
+
+  .itmeWrap {
+    display: flex;
+    justify-content: space-between;
+  }
+
+  .btnWrap {
+    height: 53px;
+
+    .el-button {
+      height: 53px;
+      border-radius: 10px;
+      font-size: 16px;
+    }
+  }
+
+  .forgetPassWord {
+    color: rgba(25, 31, 37, 0.72);
+  }
+}
+
+.login-container {
+  text-align: center;
+}
+
+.other-login {
+  display: flex;
+  align-items: center;
+  margin: 20px 0;
+}
+
+.line {
+  flex: 1;
+  height: 1px;
+  background-color: #dcdfe6;
+}
+
+.text {
+  margin: 0 10px;
+  color: #909399;
+
+  img {
+    width: 32px;
+  }
+}
+
+:deep() .el-checkbox__input.is-checked + .el-checkbox__label {
+  color: rgba(25, 31, 37, 0.72);
+}
+
+.margin_top4 {
+  margin-top: 4px;
+}
+
+:deep() .el-input__prefix,
+:deep() .el-input__suffix,
+:deep() .el-input__suffix-inner,
+.display_style {
+  display: inline-flex;
+  align-items: center;
+  justify-content: center;
+}
+
+:deep() .el-input__prefix {
+  margin-left: 12px;
+}
+
+:deep() .el-input__suffix {
+  margin-right: 10px;
+}
+
+:deep() .el-input--prefix .el-input__inner {
+  padding-left: 44px;
+  font-size: 14px;
+  padding-right: 35px;
+}
+
+:deep() .iconfont.icon-ttubiao_hide {
+  font-size: 18px;
+}
+</style>

+ 46 - 0
src/views/login/components/LoginItem.vue

@@ -0,0 +1,46 @@
+<template>
+  <div class="LoginItem">
+    <LoginForID v-if="navStatus == 1"  @update-nav-status="handleNavStatusUpdate"/>
+    <LoginForEmail v-else-if="navStatus == 2"  @update-nav-status="handleNavStatusUpdate"/>
+    <FindPassWord v-else  @update-nav-status="handleNavStatusUpdate"/>
+  </div>
+</template>
+<script>
+import LoginForEmail from './LoginForEmail.vue';
+import LoginForID from './LoginForID.vue';
+import FindPassWord from './FindPassWord.vue';
+export default {
+  name: "LoginItem",
+  components: {
+    LoginForEmail,
+    LoginForID,
+    FindPassWord
+  },
+  data(){
+    return{
+      navStatus:1, // 1:账号登录 2:邮箱登录 3:找回密码
+    }
+  },
+  mounted(){
+    
+  },
+  methods: {
+    handleNavStatusUpdate(newStatus) {
+      this.navStatus = newStatus;
+    }
+  }
+}
+</script>
+<style lang="scss" scoped>
+.LoginItem {
+  width: 414px;
+  height: 563px;
+  padding: 29px 29px 0;
+  text-align: center;
+  box-sizing: border-box;
+  background-color: #fff;
+  border-radius: 10px;
+  margin-right: 14.5%;
+  margin-top: -62px;
+}
+</style>

+ 740 - 0
src/views/login/login_ruoyan.vue

@@ -0,0 +1,740 @@
+<template>
+  <div class="login_page" >
+    <div class="login_header">
+      <div class="header_left">
+        <img src="../../assets/login/login_logo.png" alt="">
+        <span style="margin-left: 10px;">    大数据精准教学诊断平台</span>
+      </div>
+      <div class="header_right">
+        <div class="right_button" @click="GoWebsite"  >
+          官方网站
+        </div>
+      </div>
+    </div>
+    <div class="login_content" id="particles">
+      
+      <div class="login_info">
+        <div class="login_info_title">
+          <p>HI~欢迎使用</p>
+          <p>大数据精准教学诊断平台</p>
+        </div>
+        <div :class="['login_info_message',{'module_tab':tabActive == 1}]">
+          <template v-if="tabActive == 1">
+            <div :class="['tab_item',{'tab_active':actived == item.value}]" :key="item.value" v-for="item in tabList" @click="TabChange(item.value)">
+              {{ item.title }}
+            </div>
+          </template>
+          <template v-else>{{ tabActive == 3 ? '忘记密码' : tabActive == 4 ? '绑定账号' : ''}}</template>
+        </div>
+        <!-- 账号密码登录 -->
+        <div v-if="tabActive == 1">
+          <div class="login_info_input">
+            <el-input v-model="userName" placeholder="请输入账号">
+              <template #prefix>
+                <span>
+                  <img src="@/assets/login/input_user.webp" alt="User Icon" style="width: 18px; height: 18px" />
+                </span>
+              </template>
+              <template #suffix v-if="userName != ''">
+                <span @click="ClearInput" style="cursor: pointer">
+                  <img src="@/assets/login/input_clear.webp" alt="Clear Icon" style="width: 18px; height: 18px" />
+                </span>
+              </template>
+            </el-input>
+          </div>
+          <div class="login_info_input">
+            
+            <el-input v-model="passWord" :type="isPasswordVisible ? 'text' : 'password'"  placeholder="请输入密码">
+              <template #prefix>
+                <span>
+                  <img src="@/assets/login/input_pass.webp" alt="User Icon" style="width: 18px; height: 18px" />
+                </span>
+              </template>
+              <template #suffix>
+                
+                  <span @click="TogglePasswordVisibility" style="cursor: pointer">
+                    <i class="iconfont icon_xianshimima" v-if="isPasswordVisible"></i>
+                    <i class="iconfont icon_buxianshimima" v-else></i>
+                  </span>
+              </template>
+            </el-input>
+          </div>
+          <div class="login_info_item">
+            <div class="item_left">
+              <el-checkbox v-model="remeberPassWord">记住密码</el-checkbox>
+            </div>
+            <div class="item_right" @click="LoginMode(3)">忘记密码</div>
+          </div>
+          <div class="login_info_button">
+            <el-button  style="width:100%;" @click="SubmitLogin()" :loading="loadingLogin">登 录</el-button>
+          </div>
+        </div>
+        <!-- 微信登录 -->
+        <div v-if="tabActive == 2" class="wechat_login">
+          <p class="text">微信扫描登录</p>
+          <div class="wechat_url" id="wechat-qr-container"></div>
+        </div>
+        <!-- 忘记密码 -->
+        <div v-if="tabActive == 3">
+          <ForgetPassWord @GoLogin="GoLogin" />
+        </div>
+        <!-- 绑定账号 -->
+        <div v-if="tabActive == 4">
+          <div class="login_info_input">
+            <el-form :model="bindForm" :rules="bindFormrules" ref="bindFormRef">
+              <el-form-item prop="userName">
+                <el-input v-model="bindForm.userName" clearable placeholder="请输入账号" prefix-icon="iconfont icon_zhanghao" />
+              </el-form-item>
+              <el-form-item prop="passWord">
+                <el-input v-model="bindForm.passWord" show-password clearable placeholder="请输入密码"  prefix-icon="iconfont icon_mima" />
+              </el-form-item>
+            </el-form>
+          </div>
+          <div class="login_info_button">
+            <el-button style="width:100%;" @click="BindAccount" :loading="loadingBind">立即绑定</el-button>
+          </div>
+        </div>
+        <!-- 其他登录方式选项 --> 
+        <div class="login_other_type">
+          <div class="other_login_line">
+            <span class="line"></span>
+            <span class="text">其他登录方式</span>
+            <span class="line"></span>
+          </div>
+          <div class="other_login_icon">
+            <div class="icon_item" v-if="tabActive != 1">
+              <img src="@/assets/login/account.webp" alt="" @click="LoginMode(1)" />
+              <p>账号</p>
+            </div>
+            <div class="icon_item" v-if="tabActive != 2">
+              <img src="@/assets/login/login_wechat.webp" alt="" @click="LoginMode(2)" />
+              <p>微信</p>
+            </div>
+            <!-- <div class="icon_item">
+              <img src="@/assets/login/login_feishu.webp" alt=""></img>
+              <p>钉钉</p>
+            </div> -->
+            <!-- <div class="icon_item">
+              <img src="@/assets/login/login_email.webp" alt=""></img>
+              <p>邮箱</p>
+            </div> -->
+          </div>
+        </div>
+      </div>
+    </div>
+    <div class="page_dialog">
+      <el-dialog title="绑定账号" center :visible.sync="showBindDialog" width="400px" top="20vh">
+        <div class="dialog_center padding_20">
+          <div class="bingding_center">
+
+            <el-form :model="bindForm" :rules="bindFormrules" ref="bindFormRef">
+              <div class="bingding_input">
+                <el-input v-model="bindForm.userName" clearable placeholder="请输入账号" prefix-icon="iconfont icon_zhanghao" />
+              </div>
+              <div class="bingding_input">
+                <el-input v-model="bindForm.passWord" clearable placeholder="请输入密码"  prefix-icon="iconfont icon_mima" />
+              </div>
+              <div class="bingding_button" :disabled="!bindForm.userName || !bindForm.passWord" @click="BindAccount" v-loading="loadingBind">立即绑定</div>
+            </el-form>
+          </div>
+        </div>
+      </el-dialog>
+    </div>
+  </div>
+</template>
+<script>
+import particles from "particles.js";//页面例子动画特效
+import user from "@/http/api/user";
+import { setToken } from "@/utils/auth";
+import ForgetPassWord from "./components/ForgetPassWord"
+import { encrypt } from "@/utils/jsencrypt";
+import base from "@/http/common/base";
+export default {
+  components: { ForgetPassWord },
+  provide() {
+    return {
+      setTabActive: () => {
+        this.tabActive = 1
+      }
+    };
+  },
+  data(){
+    return {
+      tabList:[{
+        title:'教师',
+        value:'teacher'
+      },{
+        title:'学生',
+        value:'student'
+      }],
+      actived:'student',
+      userName:'',//登录账号
+      passWord:'',//登录密码
+      isPasswordVisible: false,//密码是否可见
+      remeberPassWord:false,//记住密码
+      loadingLogin:false,//登录按钮加载状态
+      tabActive: 1, // 切换账号登录-1,微信登录-2,忘记密码-3,绑定账号-4
+      wechatUrl: '', // 微信二维码地址
+      code: '', // 回调地址返回登录需要的code
+      wxOpenId: '', // 绑定账号需要的openid
+      loadingBind: false, // 绑定账号按钮loading
+      showBindDialog: false, // 绑定账号弹窗
+      bindForm: {
+        userName: '', // 用户账号
+        passWord: '' // 用户密码
+      }, // 绑定用户
+      bindFormrules: {
+        userName: [
+          {required: true, message: '请输入账号', trigger: ['blur', 'change']}
+        ],
+        passWord: [
+          {required: true, message: '请输入密码', trigger: ['blur', 'change']}
+        ]
+      }, // 绑定用户表单校验
+
+      apiUrl:process.env.VUE_APP_BASE || 'https://www.k12100.com',
+    }
+  },
+  mounted(){
+    // 加载微信sdk
+    this.LoadSdk()
+    //加载粒子动画特效
+    this.InitParticles();
+    // 监听键盘按下事件
+    window.addEventListener('keydown', this.handleKeyDown);
+    // 监听微信中间页面传递参数
+    window.addEventListener('message', this.WechatLogin);
+
+    // 恢复记住的用户名和密码
+    this.RestoreRememberedCredentials();
+  },
+  beforeDestroy() {
+    window.removeEventListener('keydown', this.handleKeyDown);
+    window.removeEventListener('message', this.WechatLogin);
+  },
+  methods:{
+    TabChange(value){
+      this.actived = value;
+    },
+    // 恢复记住的用户名和密码
+    RestoreRememberedCredentials() 
+    {
+      try {
+        const savedUserName = localStorage.getItem("userName");
+        const savedUserPassWord = localStorage.getItem("userPassWord");
+        
+        if (savedUserName && savedUserPassWord) {
+          this.userName = savedUserName;
+          this.passWord = savedUserPassWord;
+          this.remeberPassWord = true; // 设置记住密码为选中状态
+        }
+      } catch (error) {
+        console.error("恢复记住的凭证时出错:", error);
+      }
+    },
+
+     handleKeyDown(event) 
+     {
+      if (event.key === 'Enter') {
+        this.SubmitLogin(); // 触发登录方法
+      }
+    },
+
+
+    //添加统计监控代码
+    AddAnalyticsScript() {
+      // 等待DOM加载完成
+      setTimeout(() => {
+        var _s = document.createElement('script');
+        _s.setAttribute('type','text/javascript');
+        _s.setAttribute('id','_bxtj');
+        _s.setAttribute('async',true);
+        
+        // 获取当前用户信息
+        console.log('获取当前用户信息',this.$store.state.user.userInfo);
+        console.log("打印网站siteid",localStorage.getItem("user_schoolWebSiteId"));
+
+
+        // 设置子站点名称
+        const currentUser = this.$store.state.user.userInfo.loginName || ''; // 当前用户名
+        const subSiteName = this.$store.state.user.userInfo.schoolName || '';
+        const mySiteId = localStorage.getItem("user_schoolWebSiteId") || ''; // 你的站点ID
+        // 构建URL(按照原始代码格式)
+        let src = `https://bjedures.bjedu.cn/bjjw_logdb/bxlog.js?user=${currentUser}&id=${mySiteId}`;
+        if (subSiteName) {
+          src += `&subSiteName=${encodeURIComponent(subSiteName)}`;
+        }
+        _s.setAttribute('src', src);
+        var body = document.getElementsByTagName('body');
+        body[0].appendChild(_s);
+      }, 500);
+    },
+
+    
+
+    //密码是否可见
+    TogglePasswordVisibility() 
+    {
+      this.isPasswordVisible = !this.isPasswordVisible;
+      
+    },
+
+    //加载例子动画特效
+    InitParticles()
+    {
+
+      const particlesConfig = {
+        // 粒子配置项
+        particles: {
+          number: {
+            value: 60,//控制例子的数量 默认80
+            density: {
+              enable: true,//是否启用粒子密度检测(默认值:true)
+              value_area: 800//密度检测的区域大小
+            }
+          },
+          color: {
+            // value: ["#ff0000", "#00ff00", "#0000ff"]//定义例子的颜色数组
+            value: "#ffffff"
+          },
+          shape: {
+            type: ["circle"],//粒子的形状  支持  circle圆, edge 正方形, triangle三角形, polygon五边形, image
+            stroke: {
+              width: 0,
+              color: "#000000"
+            },//粒子边框的样式
+            polygon: {
+              nb_sides: 5
+            },//粒子多边形的边数
+            image: {
+              src: "img/github.svg",
+              width: 100,
+              height: 100
+            }//使用图片作为粒子的形状
+          },
+          opacity: {
+            value: 0.5,//粒子的透明度
+            random: false,//是否启用随机透明度(默认值:false)
+            anim: {
+              enable: false,//是否启用透明度动画(默认值:false)
+              speed: 1,//透明度动画速度(默认值:1)
+              opacity_min: 0.1,//随机透明度最小值(默认值:0.1)
+              sync: false//是否启用透明度动画同步(默认值:false)
+            }
+          },
+          size: {
+            value: 3,//粒子的大小
+            random: false,//是否启用随机大小(默认值:false)
+            anim: {
+              enable: true,//是否启用大小动画(默认值:false)
+              speed: 40,//动画速度
+              size_min: 0.1,//随机大小最小值(默认值:0)
+              sync: false//是否同步动画
+            }
+          },
+          line_linked: {
+            enable: true,//是否启用连线
+            distance: 150,//连线最大距离
+            color: "#ffffff",//连线颜色
+            opacity: 0.4,//连线透明度
+            width: 1//连线宽度
+          },//粒子间的连线配置
+          move: {
+            enable: true,//是否启用粒子行动
+            speed: 6,//粒子行动速度
+            direction: "none",//粒子行动方向可选值(none, top, top-right, right, bottom-right, bottom, bottom-left, left, top-left)
+            random: false,//是否启用粒子行动方向随机(默认值:false)
+            straight: false,//是否直线移动
+            out_mode: "out",//粒子离开画布后的行为(out, bounce)
+            bounce: false,//是否启用粒子间反弹
+            attract: {
+              enable: false,//是否启用粒子间吸引
+              rotateX: 600,//粒子间吸引的X轴旋转角度
+              rotateY: 1200//粒子间吸引的Y轴旋转角度
+            }
+          }
+        },//定义粒子的行动
+        interactivity: {
+          detect_on: "canvas",
+          events: {
+            onhover: {
+              enable: true,
+              mode: "grab"
+            },
+            onclick: {
+              enable: true,
+              mode: "push"
+            },
+            resize: true
+          },//粒子与画布的交互
+          modes: {
+            grab: {
+              distance: 140,//抓取距离
+              line_linked: {
+                opacity: 1//连线透明度
+              }
+            },//鼠标悬停时的抓取效果
+            bubble: {
+              distance: 400,//气泡距离
+              size: 40,//气泡大小
+              duration: 2,//气泡持续时间
+              opacity: 8,//气泡透明度
+              speed: 3//气泡速度
+            },//鼠标点击时的气泡效果
+            repulse: {
+              distance: 200,//排斥距离
+              duration: 0.4//排斥持续时间
+            },//鼠标点击时的排斥效果
+            push: {
+              particles_nb: 4//推送的粒子数量
+            },//鼠标推送时的添加效果
+            remove: {
+              particles_nb: 2//移除的粒子数量
+            }//鼠标点击时的移除效果
+          }//定义交互模式
+        },
+        retina_detect: true//是否启用视网膜检测,自动调整粒子大小以适应高分辨率屏幕。
+      };
+      particlesJS("particles", particlesConfig, function() {
+        console.log('粒子动画特效加载成功');
+      });
+    },
+
+    //清空输入框
+    ClearInput() {
+      this.userName = "";
+    },
+
+    //登录提交
+    SubmitLogin() 
+    {
+
+      if (!this.userName) {
+        this.$message({
+          message: "用户名不能为空!",
+          type: "warning",
+        });
+        return;
+      }
+
+      if (!this.passWord) {
+        this.$message({
+          message: "密码不能为空!",
+          type: "warning",
+        });
+        return;
+      }
+      const params = {
+        // "captchaAnswer": "",
+        // "captchaUUID": "",
+        "password": encrypt(this.passWord.trim()),
+        // "password": this.passWord.trim(),
+        // "rememberMe": true,//记住我
+        // "userStatus": 0,//用户状态:用于后台管理直接免登录点击进来校验 默认为0 代表正常登录 1 代表免登录
+        "username": this.userName.trim()
+      };
+      this.loadingLogin=true;
+      if(this.actived == 'student'){//跳转学生端地址
+        user.studentLogin({
+          password:this.passWord.trim(),
+          username:this.userName.trim()
+        }).then((res) => {
+          this.loadingLogin=false;
+          if (res.code === 200) {
+            //跳转到学生端  code:账号 pw:密码 type:1单校 2联校
+            window.location.href = `${base.STUDENT_LOGIN}index?code=${this.userName.trim()}&pw=${encodeURIComponent(this.passWord.trim())}&type=1`;
+          }else{
+            this.$message({
+              message:res.msg,
+              type: "error",
+            });
+          }
+        }).catch((err) => {
+          this.loadingLogin=false;
+          this.$message({
+            message: "服务器维护中,请稍后再试。",
+            type: "warning",
+          });
+          console.error(err);
+        });
+      }else{
+        user.loginEmailPass(params).then((res) => {
+          this.loadingLogin=false;
+          if (res.code === 200) {
+              console.log("打印登录结果",res);
+              this.$store.dispatch("user/CLEAR_LOCAL_STORAGE");//清空本地存储
+              setToken(res.data.tokenValue);
+
+              this.$store.dispatch("user/SET_TOKEN", res.data.tokenValue);
+              this.$store.dispatch("user/SET_SCHOOL_LOGO", res.data.schoolLogoUrl);//设置学校logo
+              this.$store.dispatch("user/SET_SCHOOL_TYPE",res.data.schoolType);//获取用户学校类型
+              this.$store.dispatch("user/SET_SCHOOL_WEB_SITE_ID",res.data.cloudMonitorSiteId || '');//设置学校网站id
+
+              // console.log("打印学校logo",this.$store.state.user.schoolLogo);
+              this.$store.dispatch("user/getUserInfoByToken").then(()=>{
+                console.log('获取用户登录信息成功,添加监控统计代码',this.$store.state.user.userInfo);
+
+                //成功获取用户信息后 添加监控统计代码
+                this.AddAnalyticsScript();
+
+              });//获取用户登录信息
+              this.$store.commit("user/SET_USEAR_INFOLOGIN", res.data);
+              const menuList=res.data.pcMenuVOS || [];
+              const permissions=res.data.permissions || [];
+              this.$store.commit("user/SET_PERMISSIONS",permissions);
+              this.$store.commit("user/SET_MENULIST",menuList);
+              if (this.remeberPassWord) 
+              {
+                localStorage.setItem("userName", this.userName);
+                localStorage.setItem("userPassWord", this.passWord.trim());
+              } else 
+              {
+                localStorage.removeItem("userName");
+                localStorage.removeItem("userPassWord");
+              }
+
+           
+              // const directUrl = this.$route.query.redirect || "/userInfo";
+              if(res.data.userType==1)
+              {
+                //临时用户 跳转到阅卷任务页  bug 4106
+                const directUrl = "/examMarking/markingTasks";//闯哥:默认跳转到分析报告页面
+                //后期需要根据角色 和任务来判断 老师有阅卷任务 默认跳转到阅卷页面  否则跳转到分析报告首页
+                this.$router.push({ path: directUrl });
+              }
+              else
+              {
+                //正式用户 跳转到分析报告首页
+                const directUrl = "/jointExamination/list";//闯哥:默认跳转到分析报告页面
+                //后期需要根据角色 和任务来判断 老师有阅卷任务 默认跳转到阅卷页面  否则跳转到分析报告首页
+                this.$router.push({ path: directUrl });
+              }
+              
+          }
+          else
+          {
+            this.$message({
+              message:res.msg,
+              type: "error",
+            });
+          }
+        })
+        .catch((err) => {
+          this.loadingLogin=false;
+          this.$message({
+            message: "服务器维护中,请稍后再试。",
+            type: "warning",
+          });
+          console.error(err);
+        });
+      }
+    },
+
+    //去往官网
+    GoWebsite()
+    {
+
+      // window.open(this.apiUrl);
+      window.location.href = this.apiUrl+'/website';
+    },
+    GoLogin() {
+      this.tabActive = 1
+    },
+    //登录方式
+    LoginMode(val) {
+      //账号登录
+      if(val == 1) {
+        const container = document.getElementById("wechat-qr-container");
+        if (container) {
+          container.innerHTML = ""; // 清空容器内容
+        }
+      }
+
+      //微信登录
+      if(val == 2) {
+        this.$api.user.getWechatCode().then(res => {
+          if(res.code == 200 && res.data) {
+            this.wechatUrl = res.data
+            if(window.WxLogin) {
+              this.RenderWechatQRCode()
+            }
+          }
+        })
+      }
+      this.tabActive = val
+    },
+    // 动态加载微信SDK
+    LoadSdk() {
+      const script = document.createElement('script');
+      script.src = 'https://res.wx.qq.com/connect/zh_CN/htmledition/js/wxLogin.js';
+      document.body.appendChild(script);
+    },
+    // 微信二维码内置到登录窗口内
+    RenderWechatQRCode() {
+      const container = document.getElementById("wechat-qr-container");
+      if (!container || container.children.length > 0) return; // 防止重复渲染
+
+      const queryString = this.wechatUrl.split('?')[1]?.split('#')[0];
+      const urlParams = new URLSearchParams(queryString)
+      const appid = urlParams.get('appid')
+
+      const redirectUrl=this.apiUrl+"/#/wechatLogin";
+      console.log("打印重新定向的地址",redirectUrl)
+      
+      new window.WxLogin({
+        self_redirect: true,
+        id: "wechat-qr-container",   // 容器 ID
+        appid: appid,           // 替换为你的微信开放平台 AppID
+        scope: "snsapi_login",        // 授权作用域
+        redirect_uri: encodeURIComponent(redirectUrl), // 回调 URL
+        state: "STATE",               // 可选状态值
+        style: "black",               // 样式风格
+        stylelite: 1 ,                // 新版二维码样式
+        onReady: function(isReady){
+            console.log("微信登录组件准备就续",isReady);
+        }
+      });
+    },
+    // 微信二维码扫描登录  event 微信回调地址传递参数
+    WechatLogin(event) {
+      console.log('event 微信二维码中间件传递参数', event)
+      let param = event.data
+      if (param.type === 'wechatLoginSuccess') {
+        // console.log('收到微信登录成功消息:', param.data.code)
+        this.code = param.data.code
+        this.$api.user.getLoginInfo({
+          code: param.data.code
+        }).then(res => {
+          if (res.code == 200) {
+            // 账号已绑定微信
+            setToken(res.data.tokenValue);
+            this.$store.dispatch("user/SET_TOKEN", res.data.tokenValue);
+            this.$store.dispatch("user/SET_SCHOOL_LOGO", res.data.schoolLogoUrl);//设置学校logo
+            this.$store.dispatch("user/SET_SCHOOL_TYPE",res.data.schoolType);//获取用户学校类型
+            this.$store.dispatch("user/SET_SCHOOL_WEB_SITE_ID",res.data.cloudMonitorSiteId || '');//设置学校网站id
+            this.$store.dispatch("user/getUserInfoByToken").then(()=>{
+              console.log('获取用户登录信息成功,添加监控统计代码',this.$store.state.user.userName);
+              //成功获取用户信息后 添加监控统计代码
+              this.AddAnalyticsScript();
+
+            });//获取用户登录信息
+            this.$store.commit("user/SET_USEAR_INFOLOGIN", res.data);
+            const permissions=res.data.permissions || [];
+            this.$store.commit("user/SET_PERMISSIONS",permissions);
+            const menuList = res.data.pcMenuVOS || [];
+            this.$store.commit("user/SET_MENULIST", menuList);
+
+            // const directUrl = this.$route.query.redirect || "/userInfo";
+           
+            const directUrl = "/analysisReportList/list";//闯哥:默认跳转到分析报告页面
+            //后期需要根据角色 和任务来判断 老师有阅卷任务 默认跳转到阅卷页面  否则跳转到分析报告首页
+            this.$router.push({ path: directUrl });
+          } 
+          else if(res.code == 304)
+          {
+            // 账号没有绑定的时候,跳转绑定账号
+            this.wxOpenId = res.data
+            this.$message({
+              message: '该微信未绑定账号,请输入账号、密码进行绑定!',
+              type: "warning"
+            })
+            // this.tabActive = 4
+            this.LoginMode(2);
+            this.showBindDialog = true
+          }
+        })
+      }
+    },
+    // 扫码微信绑定账号
+    BindAccount() {
+
+      if(this.bindForm.userName.trim() == "")
+      {
+        this.$message({
+          message: '请输入账号!',
+          type: "warning"
+        })
+        return;
+      }
+      if(this.bindForm.passWord.trim() == "")
+      {
+        this.$message({
+          message: '请输入密码!',
+          type: "warning"
+        })
+      }
+      this.$refs.bindFormRef.validate(valid => {
+        if(valid) {
+          try {
+            this.loadingBind = true
+            user.loginEmailPass({
+              username: this.bindForm.userName,
+              password: encrypt(this.bindForm.passWord.trim()),
+              wxOpenId: this.wxOpenId
+            }).then(res => {
+              if (res.code === 200) {
+                console.log("打印登录结果",res);
+                setToken(res.data.tokenValue);
+                this.$store.dispatch("user/SET_TOKEN", res.data.tokenValue);
+                this.$store.dispatch("user/SET_SCHOOL_LOGO", res.data.schoolLogoUrl);//设置学校logo
+                this.$store.dispatch("user/SET_SCHOOL_TYPE",res.data.schoolType);//获取用户学校类型
+                this.$store.dispatch("user/SET_SCHOOL_WEB_SITE_ID",res.data.cloudMonitorSiteId || '');//设置学校网站id
+                this.$store.dispatch("user/getUserInfoByToken");//获取用户登录信息
+                this.$store.commit("user/SET_USEAR_INFOLOGIN", res.data);
+                const menuList=res.data.pcMenuVOS || [];
+
+                const permissions=res.data.permissions || [];
+                this.$store.commit("user/SET_PERMISSIONS",permissions);
+                this.$store.commit("user/SET_MENULIST",menuList);
+
+                // const directUrl = this.$route.query.redirect || "/userInfo";
+                const directUrl = "/analysisReportList/list";//闯哥:默认跳转到分析报告页面
+                this.$router.push({ path: directUrl });
+              }
+            })
+            this.loadingBind = false
+          } catch {
+            this.loadingBind = false
+          }
+        } else {
+          return false;
+        }
+      });
+    }
+  }
+  
+}
+</script>
+
+<style lang="scss">
+@use "@/styles/login.scss";
+.login_info{
+  .module_tab{
+    width: 100%;
+    display: flex;
+    gap: 20px;
+    .tab_item{
+      font-weight: 600;
+      font-size: 16px;
+      color: #303133;
+      cursor: pointer;
+      padding-bottom: 4px;
+      &.tab_active{
+        color: #2E64FA;
+        cursor: pointer;
+        position: relative;
+        &::after{
+          position: absolute;
+          content: '';
+          left: 0;
+          right: 0;
+          top: 70%;
+          height: 2px;
+          background-color: #2E64FA;
+        }
+        
+      }
+    }
+  }
+}
+</style>