| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443 |
- <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_input">
- <el-form ref="userInfoForm" @submit.prevent="SubmitLogin"
- :model="loginFormData" :rules="formRules">
- <!-- 账号 -->
- <el-form-item prop="userName">
- <el-input v-model="loginFormData.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="loginFormData.passWord" :type="!showPass ? 'password' : 'text'" placeholder="请输入密码" @keyup.enter="SubmitLogin">
- <template #prefix>
- <img :src="passwordIcon" alt="" style="width: 16px;">
- </template>
- <template #suffix>
- <span style="z-index: 10 !important;" >
- <i @click.down="showPass = !showPass" :class="['iconfont', {'icon_xianshimima':showPass},{'icon_buxianshimima':!showPass}]"></i>
- </span>
- </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>
- <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>
- </div>
-
- </div>
- </template>
- <script setup>
- import { ref, onMounted, computed, watch, reactive } from 'vue'
- // import particles from 'particles.js'
- import { login,getUserInfo,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'
- const router = useRouter() // 获取路由实例
- // 登录信息
- 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 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 ReplaceGraphCode = async ()=>{
- let res = await replaceGraphValidateCodeApi()
- if(res?.code == 200){
- graphCaptchaCode.img = res.data.captchaImage
- graphCaptchaCode.id = res.data.captchaId
- }
- }
- // 清空输入框
- const ClearInput = (event) => {
- loginFormData.value.userName = ''
- }
- // 登录提交
- const SubmitLogin = async () => {
- 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": ""
- }
- loadingLogin.value = true
- let res = undefined
- try{ res = await login(params) }catch(err){
- loadingLogin.value = false
- console.error(err)
- }
- loadingLogin.value = false
- // 登录失败处理
- if(res.code !== 200){
- loginFormData.value.captchaCode = ''
- 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=>{})
- }
- // 去往官网
- 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>
- @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;
- }
- }
- }
- .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;
- }
- }
- }
- }
- }
- //
- .captcha_code{
- width: 100%;
- display: flex;
- justify-content: space-between;
- gap:10px;
- img{
- height: 48px;
- width: calc(50% - 10px);
- }
- }
-
- }
- }
- }
- </style>
|