Преглед изворни кода

添加用户登录接口调用

lm пре 1 месец
родитељ
комит
de03bb2c86
4 измењених фајлова са 372 додато и 265 уклоњено
  1. 35 4
      src/api/login.ts
  2. 3 2
      src/utils/request.ts
  3. 145 119
      src/views/login/login.vue
  4. 189 140
      src/views/login/phoneLogin.vue

+ 35 - 4
src/api/login.ts

@@ -1,28 +1,59 @@
 // src/api/login.ts
 import request from '../utils/request.ts'
 
-let studentPrefix = import.meta.env.VITE_API_STUDENT_PRE
+let adminPrefix = import.meta.env.VITE_API_ADMIN_PRE
 
 
 // 登录接口
 export const login = (data:any) => {
   return request({
-    url: `${studentPrefix}/api/v1/student/login`,
+    url: `${adminPrefix}/api/v1/auth/accountlogin`,
     method: 'post',
     data
   })
 }
+
+// 重新生成图形验证码 接口
+export const replaceGraphValidateCodeApi = () => {
+  return request({
+    url: `${adminPrefix}/api/v1/auth/captcha`,
+    method: 'get',
+  })
+}
+
+
+// 发送短信验证码接口
+export const sendSMSVerificationLogin = (data:any) => {
+  return request({
+    url: `${adminPrefix}/api/v1/auth/sms/smsCode`,
+    method: 'post',
+    data
+  })
+}
+
+// 验证码登录
+export const smsCodeLoginApi = (data:any) => {
+  return request({
+    url: `${adminPrefix}/api/v1/auth/smsCodeLogin`,
+    method: 'post',
+    data
+  })
+}
+
+
+
+
 // 获取用户信息
 export const getUserInfo = () => {
   return request({
-    url: `${studentPrefix}/api/v1/student_user/find_user_info`,
+    url: `${adminPrefix}/api/v1/student_user/find_user_info`,
     method: 'get'
   })
 }
 //退出登录
 export const loginOut = (data: any) => {
   return request({
-    url: `${studentPrefix}/api/v1/student/logout`,
+    url: `${adminPrefix}/api/v1/student/logout`,
     method: 'post',
     data
   })

+ 3 - 2
src/utils/request.ts

@@ -31,7 +31,7 @@ service.interceptors.request.use(
 service.interceptors.response.use(
   (response: AxiosResponse) => {
     const res = response.data
-
+    /*
     if (res.code !== 200) {
       ElMessage({
         message: res.msg || '请求失败',
@@ -41,11 +41,12 @@ service.interceptors.response.use(
       // 特殊状态码处理,如 token 失效等
       if (res.code === 401) {
         // 跳转登录页
-        window.location.href = '/'
+        // window.location.href = '/'
       }
 
       return Promise.reject(res.msg || '请求失败')
     }
+    */
 
     return res
   },

+ 145 - 119
src/views/login/login.vue

@@ -18,17 +18,12 @@
 
         <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 ref="userInfoForm" @submit.prevent="SubmitLogin" 
+            :model="loginFormData" :rules="formRules">
+            <!-- 账号 -->
             <el-form-item prop="userName">
-              <el-input v-model="userName" placeholder="请输入账号"  @keyup.enter="SubmitLogin">
+              <el-input v-model="loginFormData.userName" placeholder="请输入账号"  @keyup.enter="SubmitLogin">
                 <template #prefix>
                   <i class="iconfont icon_zhanghao" />
                 </template>
@@ -37,8 +32,9 @@
                 </template>
               </el-input>
             </el-form-item>
+            <!-- 密码 -->
             <el-form-item prop="passWord">
-              <el-input v-model="passWord"  :type="!showPass ? 'password' : 'text'"   placeholder="请输入密码" @keyup.enter="SubmitLogin">
+              <el-input v-model="loginFormData.passWord"  :type="!showPass ? 'password' : 'text'"   placeholder="请输入密码" @keyup.enter="SubmitLogin">
                 <template #prefix>
                   <img :src="passwordIcon" alt="" style="width: 16px;">
                 </template>
@@ -48,11 +44,14 @@
                   </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-item v-if="showCaptchaCode" prop="captchaCode">
+              <div class="captcha_code">
+                <el-input  v-model="loginFormData.captchaCode" placeholder="请输入验证码" @keyup.enter="SubmitLogin">
+                </el-input>
+                <img  :src="graphCaptchaCode.img" alt="验证码图片" @click="ReplaceGraphCode">
+              </div>
             </el-form-item>
           </el-form>
         </div>
@@ -66,40 +65,15 @@
         <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 { ref, onMounted, computed, watch, reactive } from 'vue'
 // import particles from 'particles.js'
-import { login,getUserInfo} from '@/api/login.ts'
+import { login,getUserInfo,replaceGraphValidateCodeApi} from '@/api/login.ts'
 
 import { ElMessage } from 'element-plus' // 
 import { useRouter } from 'vue-router'
@@ -107,19 +81,33 @@ import { encrypt } from "@/utils/jsencrypt";
 import passwordIcon from '@/assets/icon/password.svg'
 import lineCloseIcon from '@/assets/icon/line_close_icon.webp'
 
-
 const router = useRouter() // 获取路由实例
-// 响应式数据
-const userName = ref('')
-const passWord = ref('')
+
+// 登录信息 
+const userInfoForm = ref()
+const loginFormData = ref({})
+const formRules = ref({
+  userName: [
+    { required:true,trigger:'blur',message:'请输入账号'},
+  ],
+  passWord:[
+    { required:true,trigger:'blur',message:'请输入密码'},
+  ],
+  captchaCode:[
+    { required:true,trigger:'blur',message:'请输入图形验证码'},
+  ]
+})
+
+const showCaptchaCode = ref(false)  //是否展示验证码
+const graphCaptchaCode = reactive({  //图形验证码信息
+  img:'',  //验证码图片
+  id:''   //图形验证码id
+})
+
 const remeberPassWord = ref(false)
 const loadingLogin = ref(false)
 const showPass = ref(false)
 
-const isStudentLogin = ref(true)
-
-
-const userInfoForm = ref()
 
 // 粒子动画初始化
 const InitParticles = () => {
@@ -239,96 +227,121 @@ const InitParticles = () => {
   })
 }
 
-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 ReplaceGraphCode = async ()=>{
+  let res = await replaceGraphValidateCodeApi()
+  if(res?.code == 200){
+    graphCaptchaCode.img = res.data.captchaImage
+    graphCaptchaCode.id = res.data.captchaId
+  }else{
+    ElMessage.warning(res?.msg)
   }
-})
-
-const HandleLoginChange = (val)=>{
-  isStudentLogin.value = val
 }
 
+
 // 清空输入框
 const ClearInput = (event) => {
-  userName.value = ''
+  loginFormData.value.userName = ''
 }
- 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 formEl = userInfoForm.value
+  if (!formEl) return
+
+  await formEl.validate(async(valid) => {
+    if(!valid) return
+
+    const params = {
+      username: loginFormData.value.userName.trim(),
+      // password: encrypt(passWord.value.trim()),
+      password: loginFormData.value.passWord.trim(),
+      rememberMe: remeberPassWord.value,
+      captchaId: graphCaptchaCode.id,
+      captchaAnswer: loginFormData.value.captchaCode,
+      "userType": ""
+    }
 
-  router.push('/phoneLogin')
+    loadingLogin.value = true
+    let res = undefined
+    try{ res = await login(params) }catch(err){
+      loadingLogin.value = false
+      console.error(err)
+    }
+    loadingLogin.value = false
 
-/*
-  let res = undefined
+    // 登录失败处理
+    if(res.code !== 200){
+      loginFormData.value.captchaCode = ''
 
+      if(res.code == 406 && res.data.message){
+          ElMessage.warning(res.data.message)
+      }else{
+        ElMessage.warning(res.msg)
+      }
 
-  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')
-        }
+      const {
+        captchaVO,  //图形验证码数据
+        showPicCode,  //是否需要图形验证码
+        commitCount,  //当前提交次数
+        commitTopCount //最多提交次数 
+      } = res?.data
+      showCaptchaCode.value = showPicCode
+      if(showPicCode){
+        // 需要显示 图形验证码数据
+        graphCaptchaCode.img = captchaVO.captchaImage
+        graphCaptchaCode.id = captchaVO.captchaId
+      }else{
+        graphCaptchaCode.img = ''
+        graphCaptchaCode.id = ''
+        loginFormData.value.captchaCode = ''
       }
+    // 登录成功处理
+    }else{
+      let sendMsgInfo = {
+        userName:loginFormData.value.userName,
+        passWord:loginFormData.value.passWord,
+        phone:res.data.mobile
+      }
+      sessionStorage.setItem('sendMsgInfo', JSON.stringify(sendMsgInfo))
+        
+      if (remeberPassWord.value) {
+        localStorage.setItem('userName', loginFormData.value.userName)
+        localStorage.setItem('passWord', loginFormData.value.passWord)
+        localStorage.setItem('rememberMe', 'true')
+      } else {
+        localStorage.removeItem('userName')
+        localStorage.removeItem('passWord')
+        localStorage.setItem('rememberMe', 'false')
+      }
+      
+      router.push('/phoneLogin')
     }
-  }catch(err){
-     loadingLogin.value = false
-      console.error(err)
-  }
-
-  */
+  }).catch(err=>{})
 }
 
 // 去往官网
 const GoWebsite = () => {
   window.open('https://www.k12100.com/website')
 }
+
+
+
+onMounted(() => {
+  //   InitParticles()
+  const storedUsername = localStorage.getItem('userName')
+  const storedPassword = localStorage.getItem('passWord')
+  const storedRememberMe = localStorage.getItem('rememberMe')
+
+  if (storedRememberMe === 'true') {
+    loginFormData.value.userName = storedUsername
+    loginFormData.value.passWord = storedPassword
+    remeberPassWord.value = true
+  }
+})
+
 </script>
 
 <style lang="scss" scoped>
@@ -417,6 +430,19 @@ const GoWebsite = () => {
           }
         }
       }
+
+// 
+      .captcha_code{
+        width: 100%;
+        display: flex;
+        justify-content: space-between;
+        gap:10px;
+        img{
+          height: 48px;
+          width: calc(50% - 10px);
+        }
+      }
+      
     }
   }
 }

+ 189 - 140
src/views/login/phoneLogin.vue

@@ -18,43 +18,42 @@
 
         <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">
+          <el-form :rules="formRules" 
+            ref="userInfoForm" 
+            :model="formData"  >
+            <!-- :rules="phoneRules" -->
+            <el-form-item  prop="phone">
+              <el-input :disabled="true" v-model="formData.phone" 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">
+            <el-form-item prop="phoneVerificationCode">
+              <el-input v-model="formData.phoneVerificationCode"    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" >
+                  <span v-if="timeCountDown<=0" style="z-index: 10 !important;" 
+                    class="valid_code" @click="sendVerificationCode" >
                     获取验证码
-                    <!-- <i  @click.down="showPass = !showPass" :class="['iconfont', {'icon_xianshimima':showPass},{'icon_buxianshimima':!showPass}]"></i> -->
                   </span>
+                  <span v-else>重新发送 {{ timeCountDown }}s</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-item v-if="showCaptchaCode" prop="captchaCode">
+              <div class="captcha_code">
+                <el-input  v-model="formData.captchaCode" placeholder="请输入验证码" @keyup.enter="SubmitLogin">
+                </el-input>
+                <img class="captcha_code" :src="graphCaptchaCode.img" alt="验证码图片" @click="ReplaceGraphCode">
+              </div>
+            </el-form-item>
+
           </el-form>
         </div>
 
@@ -67,60 +66,60 @@
         <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 { ref, reactive, onMounted, computed, watch, onUnmounted } from 'vue'
 // import particles from 'particles.js'
-import { login,getUserInfo} from '@/api/login.ts'
+import { 
+  login,getUserInfo,sendSMSVerificationLogin,
+  smsCodeLoginApi, replaceGraphValidateCodeApi
+} 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 userInfoForm = ref()
+const formData = ref({
+  phone:'',  //手机号
+  phoneVerificationCode:'',  //手机验证码
+  captchaCode:'',  // 图形验证码
+})
+const formRules = ref({
+  phone: [
+    { required:true,trigger:'blur',message:'请输入手机号'},
+  ],
+  phoneVerificationCode:[
+    { required:true,trigger:'blur',message:'请输入验证码'},
+  ],
+  captchaCode:[
+    { required:true,trigger:'blur',message:'请输入图形验证码'},
+  ]
+})
+
+const sendMsgInfo = ref({})  //上一步传过来的用户名/密码/账号绑定的手机号
+
+const showCaptchaCode = ref(false)  //是否展示图形验证码
+const graphCaptchaCode = reactive({
+  img:'',  //验证码图片
+  id:''   //图形验证码id
+})
+
 const remeberPassWord = ref(false)
 const loadingLogin = ref(false)
-const showPass = ref(false)
-
-const isStudentLogin = ref(true)
 
+// 验证码发送倒计时数据
+const timeCountDown = ref(0)
+const timeoutFlag = ref()
 
-const userInfoForm = ref()
 
 // 粒子动画初始化
 const InitParticles = () => {
@@ -240,104 +239,140 @@ const InitParticles = () => {
   })
 }
 
-const phoneValidatePass = (rule,value, callback) => {
-  if (value === '') {
-    callback(new Error('Please input the password again'))
-  } else {
-    callback()
+
+// 发送验证码
+const sendVerificationCode = async ()=>{
+  let params = {
+    username: sendMsgInfo.value.userName,
+    password: sendMsgInfo.value.passWord,
+    mobile: formData.value.phone,
+    captchaId: graphCaptchaCode.id,       
+    captchaAnswer: formData.value.captchaCode,   
+    "userType": ""
+  }
+  let res = await sendSMSVerificationLogin(params)
+  if(res?.code == 200){
+    ElMessage.success(res.msg)
+    timeCountDown.value = 60
+    // 开始验证码倒计时
+    timeoutFlag.value = setInterval(()=>{
+      if(timeCountDown.value > 0){
+        console.log('倒计时进行中')
+        timeCountDown.value -= 1
+      }else{
+        console.log('倒计时结束')
+        clearInterval(timeoutFlag.value)
+        timeoutFlag.value = null
+        timeCountDown.value = 0
+      }
+    },1000)
+  }else{
+    ElMessage.warning(res.msg)
   }
 }
-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 ReplaceGraphCode = async ()=>{
+  let res = await replaceGraphValidateCodeApi()
+  if(res?.code == 200){
+    graphCaptchaCode.img = res.data.captchaImage
+    graphCaptchaCode.id = res.data.captchaId
+  }else{
+    ElMessage.warning(res.msg)
+  }
 }
 
-// 清空输入框
-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')
-        }
-      }
+  let formEl = userInfoForm.value
+  if (!formEl) return
+
+  await formEl.validate(async(valid) => {
+    if(!valid) return
+
+    let params = {
+      username: sendMsgInfo.value.userName,
+      password: sendMsgInfo.value.passWord,
+      mobile: formData.value.phone,
+      rememberMe: remeberPassWord.value,
+      smsCode: formData.value.phoneVerificationCode,
+      captchaId: graphCaptchaCode.id,     
+      captchaAnswer: formData.value.captchaCode, 
+      "userType": ""
     }
-  }catch(err){
-     loadingLogin.value = false
-      console.error(err)
-  }
-  */
+    let res = await smsCodeLoginApi(params)
+
+    // 登录失败处理
+    if(res?.code !== 200){
+      ElMessage.warning(res.msg)
+      formData.value.captchaCode = ''
 
-  router.push('/main')
+      const {
+        captchaVO,  //图形验证码数据
+        showPicCode,  //是否需要图形验证码
+        commitCount,  //当前提交次数
+        commitTopCount //最多提交次数 
+      } = res?.data
+
+      showCaptchaCode.value = showPicCode
+      if(showPicCode){
+        // 需要显示 图形验证码数据
+        graphCaptchaCode.img = captchaVO.captchaImage
+        graphCaptchaCode.id = captchaVO.captchaId
+      }else{
+        graphCaptchaCode.img = ''
+        graphCaptchaCode.id = ''
+        formData.value.captchaCode = ''
+      }
+    
+    // 登录成功处理
+    }else{
+      let token = res.data.tokenInfo.tokenValue
+      localStorage.setItem('token',token)
+      sessionStorage.removeItem('sendMsgInfo')
+
+      if (!(remeberPassWord.value)) {
+        localStorage.removeItem('userName')
+        localStorage.removeItem('passWord')
+        localStorage.setItem('rememberMe', 'false')
+      }
+      router.push('/main')
+    }
+  }).catch(err=>{
+    console.log('报错信息',err)
+  })
 }
 
 // 去往官网
 const GoWebsite = () => {
   window.open('https://www.k12100.com/website')
 }
+
+onMounted(() => {
+  //   InitParticles()
+  let sendMsgInfoStorage = sessionStorage.getItem('sendMsgInfo')
+  if(!sendMsgInfoStorage){
+    router.replace('/phone')
+    return
+  } 
+  sendMsgInfo.value = JSON.parse(sendMsgInfoStorage || '{}')
+  formData.value.phone = sendMsgInfo.value.phone
+
+  const storedRememberMe = localStorage.getItem('rememberMe')
+  if (storedRememberMe === 'true') {
+    remeberPassWord.value = true
+  }
+})
+
+onUnmounted(()=>{
+  console.log('清除倒计时')
+  clearInterval(timeoutFlag.value)
+  sessionStorage.removeItem('sendMsgInfo')
+  timeoutFlag.value = null
+})
+
 </script>
 
 <style lang="scss" scoped>
@@ -372,6 +407,7 @@ const GoWebsite = () => {
 }
 
 .valid_code{
+  cursor: pointer;
   font-size: 12px;
   color: #2E64FA;
 }
@@ -431,6 +467,19 @@ const GoWebsite = () => {
           }
         }
       }
+
+      .captcha_code{
+        width: 100%;
+        display: flex;
+        justify-content: space-between;
+        gap:10px;
+        img{
+          height: 48px;
+          width: calc(50% - 10px);
+        }
+      }
+
+
     }
   }
 }