--添加测试模块

This commit is contained in:
2025-10-13 11:53:54 +08:00
parent c3c93fe308
commit e1326c7ce8
146 changed files with 11171 additions and 807 deletions

View File

@ -10,61 +10,117 @@
v-show="showDate"
>
<LockOutlined />
<span>{{ t('sys.lock.unlock') }}</span>
<span>{{ t('解锁') }}</span>
</div>
<div class="flex w-screen h-screen justify-center items-center">
<div :class="`${prefixCls}__hour`" class="relative mr-5 md:mr-20 w-2/5 h-2/5 md:h-4/5">
<span>{{ hour }}</span>
<span class="meridiem absolute left-5 top-5 text-md xl:text-xl" v-show="showDate">
{{ meridiem }}
</span>
<div class="flex flex-col w-screen h-screen justify-center items-center">
<!-- 第一行logo和系统名 -->
<div :class="`${prefixCls}__logo-row`" class="flex items-center justify-center mb-8">
<img :src="logoConfig.menuLogoUrl || logo" width="144" style="height: 144px" />
<div :class="`${prefixCls}__sysname-box`" class="ml-4">
{{ sysName }}
</div>
</div>
<div :class="`${prefixCls}__minute w-2/5 h-2/5 md:h-4/5 `">
<span> {{ minute }}</span>
<!-- 第二行hour和minute并排 -->
<div class="flex items-center justify-center">
<div :class="`${prefixCls}__hour`" class="relative mr-5 md:mr-20">
<span>{{ hour }}</span>
<span class="meridiem absolute left-5 top-5 text-md xl:text-xl" v-show="showDate">
{{ meridiem }}
</span>
</div>
<div :class="`${prefixCls}__minute`">
<span> {{ minute }}</span>
</div>
</div>
<!-- 新增lockErrorMsg 显示 -->
<div v-if="lockErrorMsg" style="margin-top: 16px; color: #ff4d4f; font-size: 1.2rem;">
{{ lockErrorMsg }}
</div>
</div>
<transition name="fade-slide">
<div :class="`${prefixCls}-entry`" v-show="!showDate">
<div :class="`${prefixCls}-entry-content`">
<div :class="`${prefixCls}-entry__header enter-x`">
<img :src="userinfo.avatar || headerImg" :class="`${prefixCls}-entry__header-img`" />
<p :class="`${prefixCls}-entry__header-name`">
{{ userinfo.realName }}
{{ userinfo.name }}
</p>
<p :class="`${prefixCls}-entry__header-name`">
{{ userinfo.mobile.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2') }}
</p>
</div>
<InputPassword
:placeholder="t('sys.lock.placeholder')"
class="enter-x"
v-model:value="password"
/>
<span :class="`${prefixCls}-entry__err-msg enter-x`" v-if="errMsg">
{{ t('sys.lock.alert') }}
</span>
<template v-if="loginType === 'password'">
<InputPassword
:placeholder="t('登录密码')"
class="enter-x"
v-model:value="password"
@pressEnter="handleLogin"
/>
<span :class="`${prefixCls}-entry__err-msg enter-x`" v-if="errMsg">
{{ t('请重新登录') }}
</span>
</template>
<div v-else>
<Input v-model:value="formData.code" :placeholder="t('验证码')" class="enter-x" size="small" style="height: 58px;">
<template #suffix>
<Button type="link" class="f-16" @click="getLoginCode" size="small" :disabled="codeButtonDisabled">
{{ getCodeButtonName }}
</Button>
</template>
</Input>
</div>
<div style="margin-top: 10px">
<a-button :style="{ 'border-radius': '8px' }" block class="sub-button" type="primary" @click="handleLogin">
解锁
</a-button>
</div>
<div :class="`${prefixCls}-entry__footer enter-x`">
<a-button
type="link"
size="small"
class="mt-2 mr-2 enter-x"
:disabled="loading"
style="font-size: 1.2rem;"
@click="handleShowForm(true)"
>
{{ t('common.back') }}
<!-- 返回锁屏界面 -->
{{ t('取消') }}
</a-button>
<a-button
type="link"
size="small"
class="mt-2 mr-2 enter-x"
:disabled="loading"
style="font-size: 1.2rem;"
@click="goLogin"
>
{{ t('sys.lock.backToLogin') }}
{{ t('返回登录界面') }}
</a-button>
<a-button class="mt-2" type="link" size="small" @click="unLock()" :loading="loading">
{{ t('sys.lock.entry') }}
<a-button
class="mt-2"
type="link"
size="small"
style="font-size: 1.2rem;"
@click="changeLoginType"
:loading="loading">
{{ loginType == 'sms' ? t('密码解锁') : t('短信解锁') }}
</a-button>
</div>
</div>
<!-- <div class="back_login">
<a-button
type="link"
size="small"
class="mt-2 mr-2 enter-x"
:disabled="loading"
@click="goLogin"
>
{{ t('返回登录界面') }}
</a-button>
</div> -->
</div>
</transition>
@ -74,6 +130,28 @@
</div>
<div class="text-2xl">{{ year }}/{{ month }}/{{ day }} {{ week }}</div>
</div>
<a-modal
v-model:visible="visible"
@ok="handleOk"
@cancel="handleCancel"
:maskClosable="false"
centered
title="请完成下列验证后继续"
width="20%"
cancelText=""
>
<div class="login-modal-content">
<div class="refresh" @click="refreshTodo">
刷新
<a-icon :spin="refreshLoading" icon="ant-design:redo-outlined" class="redo-outlined" />
</div>
<a-image
:width="200"
:src="imgObj.imgBase64 || ''"
/>
<a-input v-model:value="imgCode" :placeholder="t('验证码')" size="large" />
</div>
</a-modal>
</div>
</template>
<script lang="ts" setup>
@ -86,17 +164,43 @@
import { useDesign } from '/@/hooks/web/useDesign';
import { LockOutlined } from '@ant-design/icons-vue';
import headerImg from '/@/assets/images/header.jpg';
import { useAppStore } from '/@/store/modules/app';
import logo from '/@/assets/images/logo_geg.png';
import { getMobileLoginCode, getMobileLoginImg } from '/@/api/system/login';
const appStore = useAppStore();
const logoConfig = appStore.getLogoConfig;
const sysName = ref(import.meta.env.VITE_SYSTEM_NAME);
const InputPassword = Input.Password;
const password = ref('');
const captchaCode = ref('');
const formData = ref({
code: ''
});
const imgBase64 = ref('');
const loginType = ref('password');
const loading = ref(false);
const errMsg = ref(false);
const showDate = ref(true);
const lockErrorMsg = computed(() => lockStore.getLockInfo?.msg || '');
const { prefixCls } = useDesign('lock-page');
const lockStore = useLockStore();
const userStore = useUserStore();
const getCodeButtonName = ref('获取验证码')
const codeButtonDisabled = ref(false)
const countdown = ref(60)
const visible = ref(false);
const refreshLoading = ref(false);
const imgCode = ref('');
const imgObj = ref({
imgBase64: ''
})
let setCodeInterval = null
const { hour, month, minute, meridiem, year, day, week } = useNow(true);
@ -131,13 +235,88 @@
function handleShowForm(show = false) {
showDate.value = show;
}
const getLoginCode = async () => {
countdown.value = 60
visible.value = true
imgCode.value = ''
await onMobileLoginImg()
}
async function onMobileLoginImg() {
imgObj.value = await getMobileLoginImg({account: userinfo.value.mobile})
}
async function refreshTodo() {
refreshLoading.value = true
await onMobileLoginImg()
refreshLoading.value = false
}
async function handleOk() {
await getMobileLoginCode({captchaCode: imgCode.value ,mobile: userinfo.value.mobile})
setCodeInterval = setInterval(updateCountdown, 1000);
onVisible()
}
function updateCountdown() {
if (countdown.value === 0) {
getCodeButtonName.value = '获取验证码';
codeButtonDisabled.value = false;
clearInterval(setCodeInterval)
} else {
countdown.value--;
getCodeButtonName.value = countdown.value + ' 秒后可重发';
codeButtonDisabled.value = true;
}
}
function onVisible () {
visible.value = false
imgObj.value.imgBase64 = ''
}
function handleCancel() {
onVisible()
}
function changeLoginType () {
loginType.value = loginType.value == 'password' ? 'sms' : 'password'
}
/**
* @description: unLockByPhone
*/
async function unLockByPhone() {
if (!formData.value.code) {
return;
}
let code = formData.value.code;
try {
loading.value = true;
const res = await lockStore.unLockByPhone(code);
errMsg.value = !res;
} finally {
loading.value = false;
}
}
function handleLogin() {
const obj = {
password: unLock,
sms: unLockByPhone,
}
obj[loginType.value]()
}
</script>
<style lang="less" scoped>
@prefix-cls: ~'@{namespace}-lock-page';
.@{prefix-cls} {
z-index: @lock-page-z-index;
z-index: 999;
// 新增或修改背景色
background: linear-gradient(180deg, #00356d 0%, rgb(0 53 109 / 0%) 100%), linear-gradient(180deg, #0074d3 2%, #011853 100%);
&__unlock {
transform: translate(-50%, 0);
}
@ -146,8 +325,8 @@
&__minute {
display: flex;
font-weight: 700;
color: #bababa;
background-color: #141313;
color: #ffffff;
background-color: linear-gradient(180deg, #00356d 0%, rgb(0 53 109 / 0%) 100%), linear-gradient(180deg, #0074d3 2%, #011853 100%);
border-radius: 30px;
justify-content: center;
align-items: center;
@ -187,6 +366,27 @@
}
}
&__logo-row {
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 20px;
img {
width: 144px;
height: 144px;
border-radius: 50%;
}
}
&__sysname-box {
font-size: 6rem;
font-weight: 600;
color: #fff;
display: flex;
align-items: center;
justify-content: center;
}
&-entry {
position: absolute;
top: 0;
@ -200,7 +400,7 @@
align-items: center;
&-content {
width: 260px;
width: 390px;
}
&__header {
@ -231,4 +431,16 @@
}
}
}
.back_login {
position: absolute;
left: 10px;
top: 10px;
}
.login-modal-content {
text-align: center;
.refresh {
text-align: right;
cursor: pointer;
}
}
</style>