2026-06-02 14:48:26 +08:00

338 lines
7.6 KiB
Vue

<script setup lang="ts">
import type { FormInstance } from 'element-plus'
import { userStore, globalStore } from '@/stores'
import { useRouter, useRoute } from 'vue-router'
import { storeToRefs } from 'pinia'
import { debounce } from 'lodash-es'
import { $XXL, native_api } from '@/utils'
import { isShufaAccount, SHUFA_PATH } from '@/page/app/app.ts'
import hud from '@/utils/hud'
import sass from '@/utils/sass'
const logo = sass.getLogo()
const qr = sass.getQrCode()
const url = window.location.href
const showIcp = url.includes('//www.') || url.split('.').length === 2
const router = useRouter()
const route = useRoute()
const { accountLogin } = userStore()
// const { getInspectorInfo } = urgeStore()
const { system } = storeToRefs(globalStore())
const showBack = computed(() => Boolean(route.query.back))
const formRef = ref<FormInstance>()
const account = ref((route.query.a as string) || '')
const password = ref('')
const hidePassword = ref(true)
// const loading = ref(false)
const onLogin = debounce(
async () => {
// native_api?.startReceiveTeacherScreen(
// JSON.stringify({
// host: '192.168.0.108',
// port: 30443,
// roomId: 'classroom',
// name: '李明杰',
// }),
// )
// return
if (!account.value) {
hud.error('请输入账号')
return
}
if (!password.value) {
hud.error('请输入密码')
return
}
await formRef.value?.validate()
hud.load({
task: async () => {
await accountLogin({
account: account.value,
password: password.value,
})
if (isShufaAccount(account.value)) {
router.replace(SHUFA_PATH)
} else {
router.replace('/')
}
},
option: '登录',
hideSuccess: true,
})
},
1000,
{
leading: true,
trailing: false,
},
)
const enterDebug = ref(0)
// const { initDevTool } = globalStore();
function onEnter() {
if (system.value.debug) return
enterDebug.value++
if (enterDebug.value >= 10) {
debug()
}
}
const debug = debounce(
() => {
enterDebug.value = 0
$XXL.showDebugPanel()
},
10000,
{
leading: true,
trailing: false,
},
)
// 点击二维码会弹出账号密码
function clickQrCode() {
native_api.showDoodle?.()
// hud.success(
// JSON.stringify({
// account: account.value,
// password: password.value,
// }),
// )
}
defineOptions({
name: 'Login',
})
</script>
<template>
<div class="page">
<BackBar v-if="showBack" class="backBar" />
<div class="box">
<img class="logo" :src="logo" @click="onEnter" />
<el-form ref="formRef" class="x-form">
<el-form-item prop="account" label="账号:">
<el-input v-model="account" placeholder="请输入账号" @keyup.enter="onLogin" />
</el-form-item>
<el-form-item prop="password" label="密码:">
<el-input
v-model="password"
:type="hidePassword ? 'password' : ''"
placeholder="请输入密码"
@keyup.enter="onLogin"
>
<template #suffix>
<Icon
:name="hidePassword ? 'eye_close' : 'eye_open'"
size="32"
@click="hidePassword = !hidePassword"
/>
</template>
</el-input>
</el-form-item>
</el-form>
<mj-button type="warn" size="48" height="100" width="100%" @click="onLogin"> </mj-button>
</div>
<div class="qr">
<div class="qr-border" @dblclick="clickQrCode">
<img :src="qr" />
</div>
<div class="qr-info">
<span>更多内容关注</span>
<span>{{ sass.platform.wxName }}公众号</span>
</div>
</div>
<div v-if="showIcp" class="icp-info">
<a href="https://beian.miit.gov.cn/" target="_blank" rel="noopener noreferrer">
蜀ICP备2026014928号-1
</a>
</div>
</div>
</template>
<style lang="scss" scoped>
.page {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
background-color: $theme-color-bg;
.backBar {
position: fixed;
top: 2.67vh;
left: 64px;
}
.box {
width: 696px;
height: 46.17vh;
border-radius: 3.33vh;
border: 0.33vh solid #fff;
background: linear-gradient(
133deg,
rgba(240, 240, 240, 0.9) 2.9%,
rgba(240, 240, 240, 0.65) 49.82%,
#f0f0f0 96.89%
);
backdrop-filter: blur(5px);
position: relative;
padding: 0 56px;
.logo {
width: 17.5vh;
height: 17.5vh;
position: absolute;
top: -8.75vh;
left: 50%;
transform: translateX(-50%);
border-radius: 50%;
border: 0.33vh solid #fff;
box-shadow: 0 0.33vh 0.17vh 0 #00000040;
}
.x-form {
margin-top: 12.33vh;
font-family: $font-special;
font-size: $font-size-7;
:deep(.el-form-item) {
height: 7.33vh;
line-height: 7.33vh;
display: flex;
align-items: center;
padding: 0 $space-4;
border-radius: $radius-6;
background: #fff;
margin-bottom: $space-6_h;
.el-form-item__label {
font-size: $font-size-7;
&::before {
color: $error-color;
}
}
.el-form-item__content {
position: relative;
.el-input {
height: 7.33vh;
font-size: $font-size-7;
.el-input__wrapper {
box-shadow: none;
.el-input__inner {
font-family: $font-special;
height: 100%;
}
input[type='password'] {
-webkit-text-security: disc;
text-security: disc;
}
}
}
.el-form-item__error {
font-size: $font-size-3;
line-height: 1.5em;
position: absolute;
left: -110px;
color: $error-color;
}
}
}
}
}
.qr {
width: 200px;
min-height: 13.33vh;
position: absolute;
top: $space-8_h;
right: $space-8;
display: flex;
flex-direction: column;
align-items: center;
.qr-border {
--w: 160px;
width: var(--w);
height: var(--w);
position: relative;
&::after {
content: '';
display: block;
width: var(--w);
height: var(--w);
border: 0.33vh solid transparent; // 边框设置为透明
border-radius: $radius-5;
@include gradient(
linear-gradient(180deg, #fff, #fff),
linear-gradient(180deg, #fff01f, #4de75c)
);
}
img {
position: absolute;
top: 0.33vh;
left: 4px;
border-radius: $radius-6;
width: var(--w);
overflow: hidden;
background: #fff;
padding: $space-1;
}
}
.qr-info {
width: 100%;
color: #fff;
text-align: center;
text-shadow: 0 0.08vh 0 rgba(0, 0, 0, 0.25);
font-family: 'OPPO Sans';
font-size: 2vh;
line-height: 3vh;
margin-top: $space-2_h;
display: flex;
flex-direction: column;
align-items: center;
}
}
.icp-info {
position: absolute;
bottom: 2.67vh;
left: 50%;
transform: translateX(-50%);
color: #fff;
font-size: 30px;
text-align: center;
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);
opacity: 0.8;
a {
color: inherit;
text-decoration: none;
transition: opacity 0.3s ease;
&:hover {
opacity: 1;
text-decoration: underline;
}
}
}
}
</style>