272 lines
5.3 KiB
Vue
272 lines
5.3 KiB
Vue
<template>
|
||
<view class="login-container">
|
||
<view class="login-box">
|
||
<view class="logo-section">
|
||
<image class="logo" src="/static/logo.png" mode="aspectFit"></image>
|
||
<view class="app-name">趣味答题</view>
|
||
<view class="app-desc">海量题库,轻松学习</view>
|
||
</view>
|
||
|
||
<button
|
||
class="wx-login-btn"
|
||
:class="{ 'disabled': isLoading }"
|
||
:disabled="isLoading"
|
||
open-type="getUserInfo"
|
||
@getuserinfo="handleWxLogin"
|
||
>
|
||
<text class="wx-icon">👤</text>
|
||
<text>{{ isLoading ? '登录中...' : '微信一键登录' }}</text>
|
||
</button>
|
||
|
||
<view class="skip-btn" @click="handleSkip">
|
||
<text>暂不登录</text>
|
||
</view>
|
||
|
||
<view class="tips">
|
||
登录即表示同意《用户协议》和《隐私政策》
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<script>
|
||
import api from '../../utils/api.js'
|
||
import storage from '../../utils/storage.js'
|
||
|
||
export default {
|
||
data() {
|
||
return {
|
||
isLoading: false,
|
||
redirectUrl: ''
|
||
}
|
||
},
|
||
|
||
onLoad(options) {
|
||
if (options.redirect) {
|
||
this.redirectUrl = decodeURIComponent(options.redirect)
|
||
}
|
||
},
|
||
|
||
methods: {
|
||
async handleWxLogin(e) {
|
||
if (this.isLoading) {
|
||
return
|
||
}
|
||
|
||
this.isLoading = true
|
||
|
||
try {
|
||
uni.showLoading({
|
||
title: '登录中...',
|
||
mask: true
|
||
})
|
||
|
||
uni.login({
|
||
provider: 'weixin',
|
||
success: async (loginRes) => {
|
||
console.log('uni.login 成功:', loginRes)
|
||
|
||
if (!loginRes.code) {
|
||
throw new Error('获取微信登录凭证失败')
|
||
}
|
||
|
||
try {
|
||
const res = await api.wxLogin(loginRes.code)
|
||
console.log('后端登录返回:', res)
|
||
|
||
if (res.data && res.data.accessToken) {
|
||
storage.setToken(res.data.accessToken)
|
||
storage.setRefreshToken(res.data.refreshToken)
|
||
|
||
const userInfo = {
|
||
...res.data,
|
||
nickName: res.data.name || '微信用户',
|
||
avatarUrl: res.data.avatarUrl || ''
|
||
}
|
||
storage.setUserInfo(userInfo)
|
||
|
||
try {
|
||
const questionRes = await api.getQuestion()
|
||
if (questionRes.data) {
|
||
storage.setQuestion(questionRes.data)
|
||
}
|
||
} catch (questionError) {
|
||
console.error('获取题目失败:', questionError)
|
||
}
|
||
|
||
uni.hideLoading()
|
||
uni.showToast({
|
||
title: '登录成功',
|
||
icon: 'success'
|
||
})
|
||
|
||
setTimeout(() => {
|
||
this.navigateAfterLogin()
|
||
}, 1500)
|
||
} else {
|
||
throw new Error(res.message || '登录失败')
|
||
}
|
||
} catch (apiError) {
|
||
console.error('登录接口调用失败:', apiError)
|
||
uni.hideLoading()
|
||
uni.showToast({
|
||
title: apiError.message || '登录失败,请重试',
|
||
icon: 'none',
|
||
duration: 2000
|
||
})
|
||
}
|
||
},
|
||
fail: (err) => {
|
||
console.error('uni.login 失败:', err)
|
||
uni.hideLoading()
|
||
uni.showToast({
|
||
title: '微信登录失败',
|
||
icon: 'none'
|
||
})
|
||
}
|
||
})
|
||
} catch (error) {
|
||
console.error('登录异常:', error)
|
||
uni.hideLoading()
|
||
uni.showToast({
|
||
title: '登录失败,请重试',
|
||
icon: 'none'
|
||
})
|
||
} finally {
|
||
this.isLoading = false
|
||
}
|
||
},
|
||
|
||
handleSkip() {
|
||
if (this.redirectUrl) {
|
||
if (this.isTabBarPage(this.redirectUrl)) {
|
||
uni.switchTab({
|
||
url: this.redirectUrl
|
||
})
|
||
} else {
|
||
uni.redirectTo({
|
||
url: this.redirectUrl
|
||
})
|
||
}
|
||
} else {
|
||
uni.switchTab({
|
||
url: '/pages/index/index'
|
||
})
|
||
}
|
||
},
|
||
|
||
navigateAfterLogin() {
|
||
if (this.redirectUrl) {
|
||
if (this.isTabBarPage(this.redirectUrl)) {
|
||
uni.switchTab({
|
||
url: this.redirectUrl
|
||
})
|
||
} else {
|
||
uni.redirectTo({
|
||
url: this.redirectUrl
|
||
})
|
||
}
|
||
} else {
|
||
uni.switchTab({
|
||
url: '/pages/index/index'
|
||
})
|
||
}
|
||
},
|
||
|
||
isTabBarPage(url) {
|
||
const tabBarPages = [
|
||
'/pages/index/index',
|
||
'/pages/gameplay/gameplay',
|
||
'/pages/mine/mine'
|
||
]
|
||
return tabBarPages.some(page => url.includes(page))
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style scoped>
|
||
.login-container {
|
||
min-height: 100vh;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||
padding: 40rpx;
|
||
}
|
||
|
||
.login-box {
|
||
width: 100%;
|
||
max-width: 600rpx;
|
||
background: #ffffff;
|
||
border-radius: 20rpx;
|
||
padding: 80rpx 40rpx;
|
||
box-shadow: 0 10rpx 40rpx rgba(0, 0, 0, 0.1);
|
||
}
|
||
|
||
.logo-section {
|
||
text-align: center;
|
||
margin-bottom: 80rpx;
|
||
}
|
||
|
||
.logo {
|
||
width: 160rpx;
|
||
height: 160rpx;
|
||
margin-bottom: 30rpx;
|
||
}
|
||
|
||
.app-name {
|
||
font-size: 48rpx;
|
||
font-weight: bold;
|
||
color: #333;
|
||
margin-bottom: 16rpx;
|
||
}
|
||
|
||
.app-desc {
|
||
font-size: 28rpx;
|
||
color: #999;
|
||
}
|
||
|
||
.wx-login-btn {
|
||
width: 100%;
|
||
height: 96rpx;
|
||
background: linear-gradient(135deg, #07c160 0%, #06ae56 100%);
|
||
color: #ffffff;
|
||
font-size: 32rpx;
|
||
border-radius: 48rpx;
|
||
border: none;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
margin-bottom: 30rpx;
|
||
box-shadow: 0 8rpx 24rpx rgba(7, 193, 96, 0.3);
|
||
}
|
||
|
||
.wx-login-btn.disabled {
|
||
opacity: 0.6;
|
||
}
|
||
|
||
.wx-icon {
|
||
font-size: 36rpx;
|
||
margin-right: 12rpx;
|
||
}
|
||
|
||
.skip-btn {
|
||
text-align: center;
|
||
padding: 20rpx 0;
|
||
margin-bottom: 40rpx;
|
||
}
|
||
|
||
.skip-btn text {
|
||
font-size: 28rpx;
|
||
color: #999;
|
||
}
|
||
|
||
.tips {
|
||
font-size: 24rpx;
|
||
color: #999;
|
||
text-align: center;
|
||
line-height: 1.6;
|
||
}
|
||
</style>
|