|
@@ -1,34 +1,361 @@
|
|
|
<template>
|
|
<template>
|
|
|
- <div class="login-container">
|
|
|
|
|
- <div class="login-box">
|
|
|
|
|
- <SwitchDark class="login-dark" />
|
|
|
|
|
- <div class="login-left">
|
|
|
|
|
- <img src="@/assets/image/login/side-logo.png" />
|
|
|
|
|
- </div>
|
|
|
|
|
- <div class="login-form">
|
|
|
|
|
- <div class="info-qrcode">{{ accountLogin ? '扫码登录' : '账号登录' }}</div>
|
|
|
|
|
- <img src="@/assets/image/login/qrcode-icon.png" class="qrcode" @click="handleClick" />
|
|
|
|
|
|
|
+ <div id="signin" v-loading="loading">
|
|
|
|
|
+ <div class="title">
|
|
|
|
|
+ <i class="el-icon-unlock"></i>
|
|
|
|
|
+ <span v-t="'signin.title'"></span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <el-form ref="params" :model="params" :rules="rules" label-width="0" class="form">
|
|
|
|
|
+ <el-form-item prop="loginName">
|
|
|
|
|
+ <el-input
|
|
|
|
|
+ v-model.trim="params.loginName"
|
|
|
|
|
+ class="m-input"
|
|
|
|
|
+ prefix-icon="iconfont iconyouxiang1"
|
|
|
|
|
+ :placeholder="$t('signin.form.email')"
|
|
|
|
|
+ @keyup.enter="login"
|
|
|
|
|
+ ></el-input>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item prop="password">
|
|
|
|
|
+ <el-input
|
|
|
|
|
+ v-model.trim="params.password"
|
|
|
|
|
+ class="m-input"
|
|
|
|
|
+ type="password"
|
|
|
|
|
+ autocomplete="off"
|
|
|
|
|
+ show-password
|
|
|
|
|
+ prefix-icon="iconfont iconmima"
|
|
|
|
|
+ :placeholder="$t('signin.form.password')"
|
|
|
|
|
+ @keyup.enter="login"
|
|
|
|
|
+ ></el-input>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <!-- <el-form-item prop="code">
|
|
|
|
|
+ <el-row>
|
|
|
|
|
+ <el-col :span="14">
|
|
|
|
|
+ <el-input
|
|
|
|
|
+ class="code"
|
|
|
|
|
+ v-model.trim="params.emailCode"
|
|
|
|
|
+ prefix-icon="iconfont iconyanzhengma"
|
|
|
|
|
+ :placeholder="$t('signup.form.code')"
|
|
|
|
|
+ ></el-input>
|
|
|
|
|
+ </el-col>
|
|
|
|
|
+ <el-col :span="9" :push="1" style="margin-top: 10px">
|
|
|
|
|
+ <span
|
|
|
|
|
+ @click="getCode(1)"
|
|
|
|
|
+ class="getCode"
|
|
|
|
|
+ v-text="getCodeString"
|
|
|
|
|
+ ></span>
|
|
|
|
|
+ </el-col>
|
|
|
|
|
+ </el-row>
|
|
|
|
|
+ </el-form-item> -->
|
|
|
|
|
+ <el-form-item class="forget">
|
|
|
|
|
+ <div><a v-t="'signin.forget'" href="#/forget"></a></div>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item>
|
|
|
|
|
+ <el-button v-t="'signin.login'" type="danger" class="s-btn" @click="loginValid"></el-button>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ </el-form>
|
|
|
|
|
|
|
|
- <LoginForm v-if="accountLogin" />
|
|
|
|
|
- <LoginQrcode v-else />
|
|
|
|
|
|
|
+ <!--验证码-->
|
|
|
|
|
+ <el-dialog
|
|
|
|
|
+ :title="$t('getCode.item1')"
|
|
|
|
|
+ center
|
|
|
|
|
+ :close-on-click-modal="false"
|
|
|
|
|
+ custom-class="dialog_header_w"
|
|
|
|
|
+ >
|
|
|
|
|
+ <div class="dia-content">
|
|
|
|
|
+ <el-form
|
|
|
|
|
+ ref="dialogCheck_form"
|
|
|
|
|
+ :model="dialogCheck_form"
|
|
|
|
|
+ :rules="rules"
|
|
|
|
|
+ label-width="0"
|
|
|
|
|
+ class="dialogCheck_form"
|
|
|
|
|
+ >
|
|
|
|
|
+ <el-form-item v-if="dialogCheck_type == 0" prop="emailCode">
|
|
|
|
|
+ <el-row>
|
|
|
|
|
+ <el-col :span="14">
|
|
|
|
|
+ <el-input
|
|
|
|
|
+ v-model.trim="dialogCheck_form.emailCode"
|
|
|
|
|
+ class="code"
|
|
|
|
|
+ prefix-icon="iconfont iconyanzhengma"
|
|
|
|
|
+ :placeholder="$t('getCode.item2')"
|
|
|
|
|
+ @blur="selectChange"
|
|
|
|
|
+ ></el-input>
|
|
|
|
|
+ </el-col>
|
|
|
|
|
+ <el-col :span="9" :push="1" style="display: flex; justify-content: center">
|
|
|
|
|
+ <span class="getCode" @click="getCode(1)" v-text="getCodeString"></span>
|
|
|
|
|
+ </el-col>
|
|
|
|
|
+ </el-row>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item v-if="dialogCheck_type == 1" prop="gaCode">
|
|
|
|
|
+ <el-row>
|
|
|
|
|
+ <el-col :span="24">
|
|
|
|
|
+ <el-input
|
|
|
|
|
+ v-model.trim="dialogCheck_form.gaCode"
|
|
|
|
|
+ class="code"
|
|
|
|
|
+ prefix-icon="iconfont iconyanzhengma"
|
|
|
|
|
+ :placeholder="$t('getCode.item3')"
|
|
|
|
|
+ @blur="selectChange"
|
|
|
|
|
+ ></el-input>
|
|
|
|
|
+ </el-col>
|
|
|
|
|
+ </el-row>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ </el-form>
|
|
|
|
|
+ <!-- <div slot="footer" class="dialog-footer">-->
|
|
|
|
|
+ <!-- <el-button v-t="'Btn.Cancel'" @click="dialogCheck = false"></el-button>-->
|
|
|
|
|
+ <!-- <el-button v-t="'Btn.Confirm'" type="danger" @click="login()"></el-button>-->
|
|
|
|
|
+ <!-- </div>-->
|
|
|
</div>
|
|
</div>
|
|
|
- </div>
|
|
|
|
|
|
|
+ </el-dialog>
|
|
|
</div>
|
|
</div>
|
|
|
</template>
|
|
</template>
|
|
|
|
|
|
|
|
<script lang="ts" setup>
|
|
<script lang="ts" setup>
|
|
|
- import { ref } from 'vue'
|
|
|
|
|
- import LoginForm from './components/LoginForm.vue'
|
|
|
|
|
- import SwitchDark from '@/components/SwitchDark/index.vue'
|
|
|
|
|
- import LoginQrcode from './components/LoginQrcode.vue'
|
|
|
|
|
|
|
+ import { ref, reactive, onMounted } from 'vue'
|
|
|
|
|
+ import { useRouter } from 'vue-router'
|
|
|
|
|
+ import { useStore } from 'vuex'
|
|
|
|
|
+ // import Service from '@/service/login'
|
|
|
|
|
+ import Config from '@/config/index'
|
|
|
|
|
+ import axios from 'axios'
|
|
|
|
|
+ import type { FormInstance, FormRules } from 'element-plus'
|
|
|
|
|
+
|
|
|
|
|
+ const { Code } = Config
|
|
|
|
|
+ const router = useRouter()
|
|
|
|
|
+ const store = useStore()
|
|
|
|
|
+
|
|
|
|
|
+ // 类型定义
|
|
|
|
|
+ interface LoginParams {
|
|
|
|
|
+ loginName: string
|
|
|
|
|
+ password: string
|
|
|
|
|
+ emailCode: string
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ interface DialogCheckForm {
|
|
|
|
|
+ emailCode: string
|
|
|
|
|
+ gaCode: string
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 响应式数据
|
|
|
|
|
+ const loading = ref(false)
|
|
|
|
|
+ const params = reactive<LoginParams>({
|
|
|
|
|
+ loginName: '',
|
|
|
|
|
+ password: '',
|
|
|
|
|
+ emailCode: '',
|
|
|
|
|
+ })
|
|
|
|
|
+
|
|
|
|
|
+ const timer = ref(59)
|
|
|
|
|
+ const interval = ref<NodeJS.Timeout | null>(null)
|
|
|
|
|
+ const getCodeString = ref('')
|
|
|
|
|
+
|
|
|
|
|
+ const dialogCheck = ref(false)
|
|
|
|
|
+ const dialogCheck_form = reactive<DialogCheckForm>({
|
|
|
|
|
+ emailCode: '',
|
|
|
|
|
+ gaCode: '',
|
|
|
|
|
+ })
|
|
|
|
|
+ const dialogCheck_type = ref(0)
|
|
|
|
|
+
|
|
|
|
|
+ // 表单引用
|
|
|
|
|
+ const paramsFormRef = ref<FormInstance>()
|
|
|
|
|
+ const dialogCheckFormRef = ref<FormInstance>()
|
|
|
|
|
+
|
|
|
|
|
+ // 验证规则
|
|
|
|
|
+ const rules = reactive<FormRules>({
|
|
|
|
|
+ loginName: [{ required: true, message: '请输入登录名', trigger: 'blur' }],
|
|
|
|
|
+ password: [{ required: true, message: '请输入密码', trigger: 'blur' }],
|
|
|
|
|
+ emailCode: [{ required: true, message: '请输入邮箱验证码', trigger: 'blur' }],
|
|
|
|
|
+ gaCode: [{ required: true, message: '请输入谷歌验证码', trigger: 'blur' }],
|
|
|
|
|
+ })
|
|
|
|
|
+
|
|
|
|
|
+ // 方法
|
|
|
|
|
+ const selectChange = () => {
|
|
|
|
|
+ // 如果需要强制更新
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 登录验证方式
|
|
|
|
|
+ const loginValid = async () => {
|
|
|
|
|
+ if (!paramsFormRef.value) return
|
|
|
|
|
+
|
|
|
|
|
+ const valid = await paramsFormRef.value.validate()
|
|
|
|
|
+ if (!valid) return
|
|
|
|
|
+
|
|
|
|
|
+ loading.value = true
|
|
|
|
|
+ try {
|
|
|
|
|
+ const data = {
|
|
|
|
|
+ loginName: params.loginName,
|
|
|
|
|
+ password: params.password,
|
|
|
|
|
+ }
|
|
|
|
|
+ // const res = await Service.loginValid(data)
|
|
|
|
|
+ //
|
|
|
|
|
+ // if (res.code === Code.StatusOK) {
|
|
|
|
|
+ // const validFlag = res.data
|
|
|
|
|
+ // dialogCheck.value = true
|
|
|
|
|
+ // dialogCheck_type.value = validFlag === 1 ? 1 : 0
|
|
|
|
|
+ //
|
|
|
|
|
+ // if (validFlag !== 1) {
|
|
|
|
|
+ // await getCode(1)
|
|
|
|
|
+ // }
|
|
|
|
|
+ // } else {
|
|
|
|
|
+ // // 使用你的消息提示组件
|
|
|
|
|
+ // console.error(res.msg)
|
|
|
|
|
+ // }
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ console.error('登录验证失败:', error)
|
|
|
|
|
+ } finally {
|
|
|
|
|
+ loading.value = false
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 登录
|
|
|
|
|
+ const login = async () => {
|
|
|
|
|
+ if (!dialogCheckFormRef.value) return
|
|
|
|
|
|
|
|
- const accountLogin = ref<boolean>(true)
|
|
|
|
|
|
|
+ const valid = await dialogCheckFormRef.value.validate()
|
|
|
|
|
+ if (!valid) return
|
|
|
|
|
|
|
|
- const handleClick = () => {
|
|
|
|
|
- console.log('===', accountLogin)
|
|
|
|
|
- accountLogin.value = !accountLogin.value
|
|
|
|
|
|
|
+ loading.value = true
|
|
|
|
|
+ try {
|
|
|
|
|
+ const data =
|
|
|
|
|
+ dialogCheck_type.value === 1
|
|
|
|
|
+ ? {
|
|
|
|
|
+ loginName: params.loginName,
|
|
|
|
|
+ password: params.password,
|
|
|
|
|
+ gaCode: dialogCheck_form.gaCode,
|
|
|
|
|
+ }
|
|
|
|
|
+ : {
|
|
|
|
|
+ loginName: params.loginName,
|
|
|
|
|
+ password: params.password,
|
|
|
|
|
+ emailCode: dialogCheck_form.emailCode,
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // const res = await Service.Login(data)
|
|
|
|
|
+ // if (res.code === Code.StatusOK) {
|
|
|
|
|
+ // dialogCheck.value = false
|
|
|
|
|
+ // sessionStorage.setItem('access_token', res.data)
|
|
|
|
|
+ // axios.defaults.headers.common['Access-Token'] = res.data
|
|
|
|
|
+ // await getLoginInfo()
|
|
|
|
|
+ // } else {
|
|
|
|
|
+ // console.error(res.msg)
|
|
|
|
|
+ // }
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ console.error('登录失败:', error)
|
|
|
|
|
+ } finally {
|
|
|
|
|
+ loading.value = false
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 获取登录信息
|
|
|
|
|
+ const getLoginInfo = async () => {
|
|
|
|
|
+ try {
|
|
|
|
|
+ // const res = await Service.CustomLoginInfo()
|
|
|
|
|
+ // if (res.code === Code.StatusOK) {
|
|
|
|
|
+ // store.commit('InitInfo', res.data)
|
|
|
|
|
+ // store.commit('InfoExpire', false)
|
|
|
|
|
+ // sessionStorage.setItem('info', JSON.stringify(res.data))
|
|
|
|
|
+ // console.log('登录成功')
|
|
|
|
|
+ //
|
|
|
|
|
+ // setTimeout(() => {
|
|
|
|
|
+ // router.push({ path: '/' }).catch((err) => console.log(err))
|
|
|
|
|
+ // }, 1000)
|
|
|
|
|
+ // } else {
|
|
|
|
|
+ // store.commit('InfoExpire', false)
|
|
|
|
|
+ // console.error('系统错误')
|
|
|
|
|
+ // }
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ console.error('获取登录信息失败:', error)
|
|
|
|
|
+ loading.value = false
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 修改语言
|
|
|
|
|
+ const switchLanguage = async () => {
|
|
|
|
|
+ const la = 'cn' // 这里应该从 i18n 获取当前语言
|
|
|
|
|
+ // await Service.switchLanguage({ lang: la })
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 获取验证码
|
|
|
|
|
+ const getCode = async (val: number) => {
|
|
|
|
|
+ if (val && !params.loginName) {
|
|
|
|
|
+ console.warn('请输入邮箱')
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (interval.value) return // 防止重复点击
|
|
|
|
|
+
|
|
|
|
|
+ getCodeString.value = `验证码已发送,${timer.value}秒后重新获取`
|
|
|
|
|
+
|
|
|
|
|
+ await getCode1(val)
|
|
|
|
|
+
|
|
|
|
|
+ interval.value = setInterval(() => {
|
|
|
|
|
+ timer.value--
|
|
|
|
|
+ sessionStorage.setItem('timer', timer.value.toString())
|
|
|
|
|
+
|
|
|
|
|
+ if (timer.value > 0) {
|
|
|
|
|
+ getCodeString.value = `验证码已发送,${timer.value}秒后重新获取`
|
|
|
|
|
+ } else {
|
|
|
|
|
+ getCodeString.value = '获取验证码'
|
|
|
|
|
+ clearInterval(interval.value!)
|
|
|
|
|
+ interval.value = null
|
|
|
|
|
+ timer.value = 59
|
|
|
|
|
+ sessionStorage.setItem('timer', timer.value.toString())
|
|
|
|
|
+ }
|
|
|
|
|
+ }, 1000)
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 发送验证码请求
|
|
|
|
|
+ const getCode1 = async (val: number) => {
|
|
|
|
|
+ if (!val) return
|
|
|
|
|
+
|
|
|
|
|
+ try {
|
|
|
|
|
+ // const res = await Service.sendCode({
|
|
|
|
|
+ // loginName: params.loginName,
|
|
|
|
|
+ // lang: sessionStorage.getItem('lang') || 'en',
|
|
|
|
|
+ // })
|
|
|
|
|
+ //
|
|
|
|
|
+ // if (res.code === Code.StatusOK) {
|
|
|
|
|
+ // console.log('验证码发送成功')
|
|
|
|
|
+ // } else {
|
|
|
|
|
+ // console.error(res.msg)
|
|
|
|
|
+ // }
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ console.error('发送验证码失败:', error)
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ // 初始化定时器
|
|
|
|
|
+ const initTimer = () => {
|
|
|
|
|
+ const storedTimer = sessionStorage.getItem('timer')
|
|
|
|
|
+ const t = storedTimer ? parseInt(storedTimer) : 59
|
|
|
|
|
+
|
|
|
|
|
+ if (t === 59) {
|
|
|
|
|
+ getCodeString.value = '获取验证码'
|
|
|
|
|
+ } else {
|
|
|
|
|
+ timer.value = t
|
|
|
|
|
+ getCode(0)
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ onMounted(() => {
|
|
|
|
|
+ initTimer()
|
|
|
|
|
+ })
|
|
|
</script>
|
|
</script>
|
|
|
<style lang="scss" scoped>
|
|
<style lang="scss" scoped>
|
|
|
@import './index';
|
|
@import './index';
|
|
|
|
|
+ #signin {
|
|
|
|
|
+ .el-input__inner {
|
|
|
|
|
+ border: none;
|
|
|
|
|
+ border-bottom: 1px solid;
|
|
|
|
|
+ border-radius: 0;
|
|
|
|
|
+ @include border_gray_1();
|
|
|
|
|
+ }
|
|
|
|
|
+ .el-form-item {
|
|
|
|
|
+ margin-bottom: 40px;
|
|
|
|
|
+ }
|
|
|
|
|
+ .el-form-item__content {
|
|
|
|
|
+ line-height: initial !important;
|
|
|
|
|
+ }
|
|
|
|
|
+ .el-input__prefix,
|
|
|
|
|
+ .el-input__suffix {
|
|
|
|
|
+ @include font_gray_content_1();
|
|
|
|
|
+ }
|
|
|
|
|
+ .s-btn.el-button--danger {
|
|
|
|
|
+ @include bg_red_1();
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
</style>
|
|
</style>
|