@@ -15,9 +15,8 @@
< p > 欢迎登录 SmartAdmin V2 < / p >
< p class = "desc" >
SmartAdmin 是由 河南 · 洛阳
< a target = "_blank" href = "https://www.1024lab.net" style = "color: white; weight: bolder; font-size: 15px; text-decoration: underline"
> 1024 创新实验室 ( 1024 Lab ) < / a
>
< a target = "_blank" href = "https://www.1024lab.net"
style = "color: white; weight: bolder; font-size: 15px; text-decoration: underline" > 1024 创新实验室 ( 1024 Lab ) < / a>
使用SpringBoot2 . x 和 Vue3 .2 Setup语法糖 、 Composition Api ( 同时支持JavaScript和TypeScript双版本 ) , 开发出的一套简洁 、 易用的中后台解决方案 !
< br / >
< br / >
@@ -29,8 +28,9 @@
保持谦逊 , 保持学习 , 热爱代码 , 更热爱生活 ! < br / >
永远年轻 , 永远前行 ! < br / >
< span class = "author" >
< a target = "_blank" href = "https://zhuoda.vip" style = "color: white; font-size: 13px; text-decoration: underline" >
1024 创新实验室 - 主任 : 卓大 ( 2022 年 · 洛阳 )
< a target = "_blank" href = "https://zhuoda.vip"
style = "color: white; font-size: 13px; text-decoration: underline" >
1024 创新实验室 - 主任 : 卓大
< / a >
< / span >
< / span >
@@ -43,7 +43,7 @@
< / div >
< div class = "app-qr" >
< img :src = "xiaozhen" / >
< marquee class = "qr-desc" scrolldelay = "130" > 关注 : 小镇程序员 , 了解二三线城市程序员的代码与 “ 钱途 ” , 技术与生活 , 城市可能无法选择 , 但未来可以拼搏 。 < / marquee >
< div class = "qr-desc-marquee" > < div class = "marquee" > < span > 关注 : 小镇程序员 , 了解二三线城市程序员的代码与 “ 钱途 ” , 技术与生活 , 城市可能无法选择 , 但未来可以拼搏 。 < / span > < / div > < / div >
< / div >
< / div >
< / div >
@@ -55,12 +55,8 @@
< a-input v -model :value.trim = "loginForm.loginName" placeholder = "请输入用户名" / >
< / a-form-item >
< a-form-item name = "password" >
< a-input-password
v -model :value = "loginForm. password"
autocomplete = "on"
: type = "showPassword ? 'text' : 'password'"
placeholder = "请输入密码"
/ >
< a-input-password v -model :value = "loginForm.password" autocomplete = "on"
: type = "showPassword ? 'text' : ' password' " placeholder = "请输入密码" / >
< / a-form-item >
< a-form-item name = "captchaCode" >
< a-input class = "captcha-input" v -model :value.trim = "loginForm.captchaCode" placeholder = "请输入验证码" / >
@@ -88,119 +84,117 @@
< / div >
< / div >
< / div >
< / div >
< / div >
< / template >
< script setup >
import { message } from 'ant-design-vue' ;
import { onMounted , onUnmounted , reactive , ref } from 'vue' ;
import { useRouter } from 'vue-router' ;
import { loginApi } from '/@/api/system/login/login-api' ;
import { SmartLoading } from '/@/components/framework/smart-loading' ;
import { LOGIN _DEVICE _ENUM } from '/@/constants/system/login-device-const' ;
import { useUserStore } from '/@/store/modules/system/user' ;
import { saveTokenToCookie } from '/@/utils/cookie-util' ;
import { message } from 'ant-design-vue' ;
import { onMounted , onUnmounted , reactive , ref } from 'vue' ;
import { useRouter } from 'vue-router' ;
import { loginApi } from '/@/api/system/login/login-api' ;
import { SmartLoading } from '/@/components/framework/smart-loading' ;
import { LOGIN _DEVICE _ENUM } from '/@/constants/system/login-device-const' ;
import { useUserStore } from '/@/store/modules/system/user' ;
import { saveTokenToCookie } from '/@/utils/cookie-util' ;
import gongzhonghao from '/@/assets/images/1024lab/1024lab-gzh.jpg' ;
import zhuoda from '/@/assets/images/1024lab/zhuoda-wechat.jpg' ;
import loginQR from '/@/assets/images/login/login-qr.png' ;
import xiaozhen from '/@/assets/images/1024lab/xiaozhen-gzh.jpg' ;
import gongzhonghao from '/@/assets/images/1024lab/1024lab-gzh.jpg' ;
import zhuoda from '/@/assets/images/1024lab/zhuoda-wechat.jpg' ;
import loginQR from '/@/assets/images/login/login-qr.png' ;
import xiaozhen from '/@/assets/images/1024lab/xiaozhen-gzh.jpg' ;
import aliLogin from '/@/assets/images/login/ali-icon.png' ;
import googleLogin from '/@/assets/images/login/google-icon.png' ;
import qqLogin from '/@/assets/images/login/qq-icon.png' ;
import weiboLogin from '/@/assets/images/login/weibo-icon.png' ;
import aliLogin from '/@/assets/images/login/ali-icon.png' ;
import googleLogin from '/@/assets/images/login/google-icon.png' ;
import qqLogin from '/@/assets/images/login/qq-icon.png' ;
import weiboLogin from '/@/assets/images/login/weibo-icon.png' ;
import { buildRoutes } from '/@/router/index' ;
import { smartSentry } from '/@/lib/smart-sentry' ;
import { buildRoutes } from '/@/router/index' ;
import { smartSentry } from '/@/lib/smart-sentry' ;
//--------------------- 登录表单 ---------------------------------
//--------------------- 登录表单 ---------------------------------
const loginForm = reactive ( {
loginName : 'admin' ,
password : '' ,
captchaCode : '' ,
captchaUuid : '' ,
loginDevice : LOGIN _DEVICE _ENUM . PC . value ,
} ) ;
const rules = {
loginName : [ { required : true , message : '用户名不能为空' } ] ,
password : [ { required : true , message : '密码不能为空' } ] ,
captchaCode : [ { required : true , message : '验证码不能为空' } ] ,
const loginForm = reactive ( {
loginName : 'admin' ,
password : '' ,
captchaCode : '' ,
captchaUuid : '' ,
loginDevice : LOGIN _DEVICE _ENUM . PC . value ,
} ) ;
const rules = {
loginName : [ { required : true , message : '用户名不能为空' } ] ,
password : [ { required : true , message : '密码不能为空' } ] ,
captchaCode : [ { required : true , message : '验证码不能为空' } ] ,
} ;
const showPassword = ref ( false ) ;
const router = useRouter ( ) ;
const formRef = ref ( ) ;
const rememberPwd = ref ( false ) ;
onMounted ( ( ) => {
document . onkeyup = ( e ) => {
if ( e . keyCode == 13 ) {
onLogin ( ) ;
}
} ;
} ) ;
const showPassword = ref ( false ) ;
const router = useRouter ( ) ;
const formRef = ref ( ) ;
const rememberPwd = ref ( false ) ;
onUnmounted ( ( ) => {
document . onkeyup = null ;
} ) ;
onMounted ( ( ) => {
document . onkeyup = ( e ) => {
if ( e . keyCode == 13 ) {
onLogin ( ) ;
}
} ;
} ) ;
onUnmounted ( ( ) => {
document . onkeyup = null ;
} ) ;
//登录
async function onLogin ( ) {
formRef . value . validate ( ) . then ( async ( ) => {
try {
SmartLoading . show ( ) ;
const res = await loginApi . login ( loginForm ) ;
stopRefrestCaptchaInterval ( ) ;
saveTokenToCookie ( res . data . token ? res . data . token : '' ) ;
message . success ( '登录成功' ) ;
//更新用户信息到pinia
useUserStore ( ) . setUserLoginInfo ( res . data ) ;
//构建系统的路由
buildRoutes ( ) ;
router . push ( '/home' ) ;
} catch ( e ) {
if ( e . data && e . data . code === 30001 ) {
loginForm . captchaCode = '' ;
getCaptcha ( ) ;
}
smartSentry . captureError ( e ) ;
} finally {
SmartLoading . hide ( ) ;
}
} ) ;
}
//--------------------- 验证码 ---------------------------------
const captchaBase64Image = ref ( '' ) ;
async function getCaptcha ( ) {
//登录
async function onLogin ( ) {
formRef . value . validate ( ) . then ( async ( ) => {
try {
let captchaResult = await loginApi . getCaptcha ( ) ;
captchaBase64Image . value = captchaResult . data . captchaBase64Image ;
loginForm . captchaUuid = captchaResult . data . captchaUuid ;
beginRefrestCaptchaInterval ( captchaResult . data . expireSeconds ) ;
SmartLoading . show ( ) ;
const res = await loginApi . login ( loginForm ) ;
stopRefrestCaptchaInterval ( ) ;
saveTokenToCookie ( res . data . token ? res . data . token : '' ) ;
message . success ( '登录成功' ) ;
//更新用户信息到pinia
useUserStore ( ) . setUserLoginInfo ( res . data ) ;
//构建系统的路由
buildRoutes ( ) ;
router . push ( '/home' ) ;
} catch ( e ) {
consol e. log ( e ) ;
if ( e . data && e . data . code === 30001 ) {
loginForm . captchaCode = '' ;
getCaptcha ( ) ;
}
smartSentry . captureError ( e ) ;
} finally {
SmartLoading . hide ( ) ;
}
}
} ) ;
}
let refrestCaptchaInterval = null ;
function beginRefrestCaptchaInterval ( expireSeconds ) {
if ( refrestCaptchaInterval === null ) {
refrestCaptchaInterval = setInterval ( getCaptcha , ( expireSeconds - 5 ) * 1000 ) ;
}
}
//--------------------- 验证码 ---------------------------------
function stopRefrestCaptchaInterval ( ) {
if ( refrestCaptchaInterval != null ) {
clearInterval ( refrestCaptchaInterval ) ;
refrestCaptchaInterval = null ;
}
const captchaBase64Image = ref ( '' ) ;
async function getCaptcha ( ) {
try {
let captchaResult = await loginApi . getCaptcha ( ) ;
captchaBase64Image . value = captchaResult . data . captchaBase64Image ;
loginForm . captchaUuid = captchaResult . data . captchaUuid ;
beginRefrestCaptchaInterval ( captchaResult . data . expireSeconds ) ;
} catch ( e ) {
console . log ( e ) ;
}
}
onMounted ( getCaptcha ) ;
let refrestCaptchaInterval = null ;
function beginRefrestCaptchaInterval ( expireSeconds ) {
if ( refrestCaptchaInterval === null ) {
refrestCaptchaInterval = setInterval ( getCaptcha , ( expireSeconds - 5 ) * 1000 ) ;
}
}
function stopRefrestCaptchaInterval ( ) {
if ( refrestCaptchaInterval != null ) {
clearInterval ( refrestCaptchaInterval ) ;
refrestCaptchaInterval = null ;
}
}
onMounted ( getCaptcha ) ;
< / script >
< style lang = "less" scoped >
@ import './login.less' ;
< / style >
< style lang = "less" scoped > @ import './login.less' ; < / style >