Prechádzať zdrojové kódy

添加手机登录页和密码登录页

lm 1 týždeň pred
rodič
commit
d451b88fde

BIN
src/assets/login/validate_code.png


+ 7 - 0
src/router/index.ts

@@ -16,6 +16,13 @@ const routes: Array<RouteRecordRaw> = [
     name: 'Login',
     component: () => import('../views/login/login.vue')
   },
+  {
+    path: '/phoneLogin',
+    name: 'phoneLogin',
+    component: () => import('../views/login/phoneLogin.vue')
+  },
+
+  
   {
     path: '/main',
     name: 'main',

+ 6 - 0
src/views/login/login.vue

@@ -282,6 +282,10 @@ const SubmitLogin = async () => {
   }
   loadingLogin.value = true
 
+
+  router.push('/phoneLogin')
+
+/*
   let res = undefined
 
 
@@ -317,6 +321,8 @@ const SubmitLogin = async () => {
      loadingLogin.value = false
       console.error(err)
   }
+
+  */
 }
 
 // 去往官网

+ 439 - 0
src/views/login/phoneLogin.vue

@@ -0,0 +1,439 @@
+<template>
+  <div class="login_page" >
+    <div class="login_header">
+      <div class="header_left">
+        <img src="../../assets/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="input_tips">请输入验证码</div>
+
+        <!-- <div class="login_info_message">校本选课系统登录</div> -->
+<!-- 
+        <div class="tab">
+          <span :class="!isStudentLogin ? 'selected': 'un_selected' " @click="HandleLoginChange(false)">教师</span>
+          <span :class="isStudentLogin ? 'selected': 'un_selected' " @click="HandleLoginChange(true)">学生</span>
+        </div> -->
+
+        <div class="login_info_input">
+          <el-form ref="userInfoForm" @submit.prevent="SubmitLogin">
+            <el-form-item :rules="phoneRules" prop="userName">
+              <el-input v-model="userName" placeholder="请输入手机号"  @keyup.enter="SubmitLogin">
+                <template #prefix>
+                  <i class="iconfont icon_zhanghao" />
+                </template>
+                <template #suffix>
+                  <img @click.stop="ClearInput"  :src="lineCloseIcon" alt="Clear Icon" style="width: 18px;height: 18px;cursor: pointer;">
+                </template>
+              </el-input>
+            </el-form-item>
+            <el-form-item prop="passWord">
+              <el-input v-model="passWord"  :type="'text'"   placeholder="请输入验证码" @keyup.enter="SubmitLogin">
+                <template #prefix>
+                  <img :src="validateCodeIcon" alt="" style="width: 18px;height: 18px;">
+                </template>
+                <template #suffix>
+                  <span style="z-index: 10 !important;" class="valid_code" >
+                    获取验证码
+                    <!-- <i  @click.down="showPass = !showPass" :class="['iconfont', {'icon_xianshimima':showPass},{'icon_buxianshimima':!showPass}]"></i> -->
+                  </span>
+                </template>
+              </el-input>
+              <!-- <el-input v-model="passWord" placeholder="请输入密码" :type="!showPass ? 'password' : 'text'">
+                <template #prefix>
+                  <i class="iconfont icon_mima" />
+                </template>
+              </el-input> -->
+            </el-form-item>
+          </el-form>
+        </div>
+
+        <div class="login_info_item">
+          <div class="item_left">
+            <el-checkbox v-model="remeberPassWord">记住密码</el-checkbox>
+          </div>
+          <div class="item_right">忘记密码</div>
+        </div>
+        <div class="login_info_button">
+          <el-button  style="width:100%;" @click="SubmitLogin()" :loading="loadingLogin">登 录</el-button>
+        </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">
+              <img src="../../assets/login/login_wechat.webp" alt=""></img>
+              <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>
+</template>
+<script setup>
+import { ref, onMounted, computed, watch } from 'vue'
+// import particles from 'particles.js'
+import { login,getUserInfo} from '@/api/login.ts'
+
+import { ElMessage } from 'element-plus' // 
+import { useRouter } from 'vue-router'
+import { encrypt } from "@/utils/jsencrypt";
+import passwordIcon from '@/assets/icon/password.svg'
+import lineCloseIcon from '@/assets/icon/line_close_icon.webp'
+import validateCodeIcon from '@/assets/login/validate_code.png'
+
+const router = useRouter() // 获取路由实例
+// 响应式数据
+const userName = ref('')
+const passWord = ref('')
+const remeberPassWord = ref(false)
+const loadingLogin = ref(false)
+const showPass = ref(false)
+
+const isStudentLogin = ref(true)
+
+
+const userInfoForm = ref()
+
+// 粒子动画初始化
+const InitParticles = () => {
+  const particlesConfig = {
+    particles: {
+      number: {
+        value: 60,
+        density: {
+          enable: true,
+          value_area: 800
+        }
+      },
+      color: {
+        value: '#ffffff'
+      },
+      shape: {
+        type: ['circle'],
+        stroke: {
+          width: 0,
+          color: '#000000'
+        },
+        polygon: {
+          nb_sides: 5
+        },
+        image: {
+          src: 'img/github.svg',
+          width: 100,
+          height: 100
+        }
+      },
+      opacity: {
+        value: 0.5,
+        random: false,
+        anim: {
+          enable: false,
+          speed: 1,
+          opacity_min: 0.1,
+          sync: false
+        }
+      },
+      size: {
+        value: 3,
+        random: false,
+        anim: {
+          enable: true,
+          speed: 40,
+          size_min: 0.1,
+          sync: false
+        }
+      },
+      line_linked: {
+        enable: true,
+        distance: 150,
+        color: '#ffffff',
+        opacity: 0.4,
+        width: 1
+      },
+      move: {
+        enable: true,
+        speed: 6,
+        direction: 'none',
+        random: false,
+        straight: false,
+        out_mode: 'out',
+        bounce: false,
+        attract: {
+          enable: false,
+          rotateX: 600,
+          rotateY: 1200
+        }
+      }
+    },
+    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, () => {
+    console.log('粒子动画特效加载成功')
+  })
+}
+
+const phoneValidatePass = (rule,value, callback) => {
+  if (value === '') {
+    callback(new Error('Please input the password again'))
+  } else {
+    callback()
+  }
+}
+const phoneRules = [
+  { required:true,trigger:'blur',message:'请输入手机号'},
+  // 动态提示
+  { validator: phoneValidatePass, trigger: 'blur' }
+]
+onMounted(() => {
+//   InitParticles()
+  const storedUsername = localStorage.getItem('userName')
+  const storedPassword = localStorage.getItem('passWord')
+  const storedRememberMe = localStorage.getItem('rememberMe')
+
+  if (storedRememberMe === 'true') {
+    userName.value = storedUsername
+    passWord.value = storedPassword
+    remeberPassWord.value = true
+  }
+})
+
+const HandleLoginChange = (val)=>{
+  isStudentLogin.value = val
+}
+
+// 清空输入框
+const ClearInput = (event) => {
+  userName.value = ''
+}
+ const menuList = ref([])
+// 登录提交
+const SubmitLogin = async () => {
+  if(!userName.value || !passWord.value) {
+    return
+  }
+  if (remeberPassWord.value) {
+    localStorage.setItem('userName', userName.value)
+    localStorage.setItem('passWord', passWord.value)
+    localStorage.setItem('rememberMe', 'true')
+  } else {
+    localStorage.removeItem('userName')
+    localStorage.removeItem('passWord')
+    localStorage.setItem('rememberMe', 'false')
+  }
+ 
+  /*
+  const params = {
+    username: userName.value.trim(),
+    password: encrypt(passWord.value.trim()),
+    deviceType:'PC',
+  }
+  loadingLogin.value = true
+  let res = undefined
+  try{
+    res  = await login(params)
+    loadingLogin.value = false
+    if (res.code === 200) {
+      console.log("登录成功返回",res)
+      localStorage.setItem('token', res.data.tokenValue)
+      menuList.value = res.data.pcMenuVOS
+      localStorage.setItem('menuList', JSON.stringify(res.data.pcMenuVOS))
+      localStorage.setItem('permissions', JSON.stringify(res.data.permissions))
+      
+      // 登录成功后调用获取用户信息接口  
+      let userInfoRes = undefined
+      userInfoRes = await getUserInfo(res.data.token)
+      console.log("获取用户信息返回",userInfoRes)
+      if (userInfoRes?.code === 200) {
+        // 存储用户信息到 localStorage 或 Pinia
+        localStorage.setItem('userInfo', JSON.stringify(userInfoRes.data))
+        ElMessage.success('登录成功');
+
+        //根据不同的角色跳转不同的页面
+        // 管理员跳转
+        if(userInfoRes.data?.roleCodes?.includes('SCHOOL_MANAGER')){
+          router.push('/main')
+        }else{
+          router.push('/main/personalCenter')
+        }
+      }
+    }
+  }catch(err){
+     loadingLogin.value = false
+      console.error(err)
+  }
+  */
+
+  router.push('/main')
+}
+
+// 去往官网
+const GoWebsite = () => {
+  window.open('https://www.k12100.com/website')
+}
+</script>
+
+<style lang="scss" scoped>
+@use "../../styles/login.scss" as *;
+
+.tab  {
+  display: flex;
+  flex-direction: row;
+  margin:0 0 10px;
+  gap: 20px;
+  font-weight: bold;
+  line-height: 48px;
+  span{
+    padding:0 0 4px;
+    &:hover{
+      cursor: pointer;
+    }
+  }
+  .selected{
+    position: relative;
+    color: #2e64fa;
+    &::after{
+      position: absolute;
+      content: "";
+      left: 0;
+      right: 0;
+      top: 70%;
+      height: 2px;
+      background-color: #2e64fa;
+    }
+  }
+}
+
+.valid_code{
+  font-size: 12px;
+  color: #2E64FA;
+}
+
+.login_info{
+  .login_info_title{
+      margin-bottom: 32px !important;
+  }
+  .input_tips{
+    font-weight: 600;
+    font-size: 14px;
+    color: #333;
+    margin-bottom: 26px;
+  }
+}
+
+.login_info_input{
+  // border:solid red 1px;
+  .iconfont{
+    color:#c0c4cc;
+  }
+  .el-form{
+    .el-form-item{
+      // border:solid red 1px !important;
+      :deep(.el-form-item__content){
+        .el-input{
+          .el-input__wrapper{
+            border: none;
+            box-shadow: none;
+            padding: 0;
+            &::hover{
+              border:none;
+              box-shadow: none;
+            }
+
+            .el-input__prefix{
+              position: absolute;
+              left: 17px;
+            }
+            .el-input__suffix{
+              position: absolute;
+              right: 17px;
+            }
+
+            .el-input__inner{
+              text-indent: 43px;
+              border:solid #dcdfe6 1px;
+              height: 100%;
+              border-radius: 4px;
+              &:hover{
+                border-color: #c0c4cc;
+              }
+              &:focus{
+                border-color: #2e64fa;
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+}
+
+
+</style>