141 lines
3.9 KiB
Vue
141 lines
3.9 KiB
Vue
|
|
<script setup lang="ts">
|
|||
|
|
import type { LoginRequest } from '@/service/types'
|
|||
|
|
import { ref } from 'vue'
|
|||
|
|
import AuthForm from '@/components/auth/AuthForm.vue'
|
|||
|
|
import { sysUsersResetPasswordUsingPost } from '@/service/xitongyonghu'
|
|||
|
|
import { useUserStore } from '@/store/user'
|
|||
|
|
|
|||
|
|
const userStore = useUserStore()
|
|||
|
|
|
|||
|
|
// 当前模式:登录或重置密码
|
|||
|
|
const currentMode = ref<'login' | 'reset'>('login')
|
|||
|
|
const loading = ref(false)
|
|||
|
|
|
|||
|
|
// 处理登录
|
|||
|
|
async function handleLogin(data: LoginRequest) {
|
|||
|
|
try {
|
|||
|
|
loading.value = true
|
|||
|
|
await userStore.login(data)
|
|||
|
|
|
|||
|
|
uni.showToast({
|
|||
|
|
title: '登录成功',
|
|||
|
|
icon: 'success',
|
|||
|
|
})
|
|||
|
|
|
|||
|
|
// 登录成功,跳转到首页
|
|||
|
|
setTimeout(() => {
|
|||
|
|
uni.reLaunch({
|
|||
|
|
url: '/pages/index/index',
|
|||
|
|
})
|
|||
|
|
}, 1500)
|
|||
|
|
}
|
|||
|
|
catch (error) {
|
|||
|
|
console.error('登录失败:', error)
|
|||
|
|
}
|
|||
|
|
finally {
|
|||
|
|
loading.value = false
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 处理重置密码
|
|||
|
|
async function handleReset(data: { phone: string, code: string, password: string }) {
|
|||
|
|
try {
|
|||
|
|
loading.value = true
|
|||
|
|
|
|||
|
|
// 调用重置密码API
|
|||
|
|
await sysUsersResetPasswordUsingPost({
|
|||
|
|
body: {
|
|||
|
|
phone: data.phone,
|
|||
|
|
verify_code: data.code,
|
|||
|
|
new_password: data.password,
|
|||
|
|
confirm_password: data.password,
|
|||
|
|
username: data.phone, // 使用手机号作为用户名
|
|||
|
|
},
|
|||
|
|
})
|
|||
|
|
|
|||
|
|
uni.showToast({
|
|||
|
|
title: '密码重置成功',
|
|||
|
|
icon: 'success',
|
|||
|
|
})
|
|||
|
|
|
|||
|
|
// 延迟切换到登录模式
|
|||
|
|
setTimeout(() => {
|
|||
|
|
currentMode.value = 'login'
|
|||
|
|
}, 1500)
|
|||
|
|
}
|
|||
|
|
catch (error) {
|
|||
|
|
console.error('重置密码失败:', error)
|
|||
|
|
uni.showToast({
|
|||
|
|
title: '重置失败,请重试',
|
|||
|
|
icon: 'none',
|
|||
|
|
})
|
|||
|
|
}
|
|||
|
|
finally {
|
|||
|
|
loading.value = false
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 切换模式
|
|||
|
|
function handleSwitchMode(mode: 'login' | 'reset') {
|
|||
|
|
currentMode.value = mode
|
|||
|
|
}
|
|||
|
|
</script>
|
|||
|
|
|
|||
|
|
<template>
|
|||
|
|
<view class="relative h-screen w-full overflow-hidden from-blue-500 via-purple-500 to-blue-600 bg-gradient-to-br">
|
|||
|
|
<!-- 背景图片 -->
|
|||
|
|
<image
|
|||
|
|
class="absolute inset-0 z-0 h-full w-full opacity-80"
|
|||
|
|
src="https://images.unsplash.com/photo-1557804506-669a67965ba0?ixlib=rb-4.0.3&auto=format&fit=crop&w=1974&q=80"
|
|||
|
|
mode="aspectFill"
|
|||
|
|
/>
|
|||
|
|
|
|||
|
|
<!-- 渐变蒙版 -->
|
|||
|
|
<view class="absolute inset-0 z-1 from-blue-500/90 via-purple-500/80 to-blue-600/90 bg-gradient-to-br" />
|
|||
|
|
|
|||
|
|
<!-- 主要内容 -->
|
|||
|
|
<view class="relative z-2 h-full flex flex-col">
|
|||
|
|
<!-- Logo 区域 -->
|
|||
|
|
<view class="flex flex-1 flex-col items-center justify-center px-8">
|
|||
|
|
<view class="relative mb-4">
|
|||
|
|
<view class="h-12 w-12 flex items-center justify-center rounded-3xl from-red-500 to-red-600 bg-gradient-to-br shadow-xl">
|
|||
|
|
<text class="text-3xl text-white font-bold">享</text>
|
|||
|
|
</view>
|
|||
|
|
</view>
|
|||
|
|
|
|||
|
|
<view class="text-center">
|
|||
|
|
<text class="mb-2 block text-4xl text-white font-bold drop-shadow-lg">象乐学</text>
|
|||
|
|
<text class="mb-4 block text-base text-white/90 drop-shadow">【教师版】</text>
|
|||
|
|
<text class="block text-sm text-white/80 drop-shadow">乐学未来,向学而行</text>
|
|||
|
|
</view>
|
|||
|
|
</view>
|
|||
|
|
|
|||
|
|
<!-- 认证表单区域 - 全宽底部 -->
|
|||
|
|
<view class="w-full rounded-t-2xl bg-white shadow-2xl">
|
|||
|
|
<auth-form
|
|||
|
|
:mode="currentMode"
|
|||
|
|
@login="handleLogin"
|
|||
|
|
@reset="handleReset"
|
|||
|
|
@switch-mode="handleSwitchMode"
|
|||
|
|
/>
|
|||
|
|
</view>
|
|||
|
|
</view>
|
|||
|
|
|
|||
|
|
<!-- 装饰元素 -->
|
|||
|
|
<view class="pointer-events-none absolute inset-0 z-1">
|
|||
|
|
<view class="absolute left-1/10 top-1/5 h-20 w-20 animate-pulse rounded-full bg-white/10" />
|
|||
|
|
<view class="animation-delay-2s absolute right-1/6 top-3/5 h-12 w-12 animate-pulse rounded-full bg-white/10" />
|
|||
|
|
<view class="animation-delay-4s absolute left-1/12 top-3/4 h-28 w-28 animate-pulse rounded-full bg-white/10" />
|
|||
|
|
</view>
|
|||
|
|
</view>
|
|||
|
|
</template>
|
|||
|
|
|
|||
|
|
<route lang="json5">
|
|||
|
|
{
|
|||
|
|
"name": "auth",
|
|||
|
|
"style": {
|
|||
|
|
"navigationStyle": "custom",
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
</route>
|