campus-errand/miniapp/pages/login/login.vue
18631081161 70c466951b
All checks were successful
continuous-integration/drone/push Build is passing
改bug
2026-03-25 21:54:49 +08:00

240 lines
4.9 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="login-page">
<!-- 自定义导航栏 -->
<view class="custom-navbar" :style="{ paddingTop: statusBarHeight + 'px' }">
<view class="navbar-content">
<view class="nav-back" @click="goBack">
<text class="back-arrow"></text>
</view>
<text class="navbar-title">登录</text>
<view class="nav-placeholder"></view>
</view>
</view>
<view :style="{ height: (statusBarHeight + 44) + 'px' }"></view>
<!-- Logo 和应用名称 -->
<view class="login-header">
<image class="login-logo" src="/static/logo.png" mode="aspectFit"></image>
<text class="login-title">校园跑腿</text>
<text class="login-subtitle">便捷校园生活从这里开始</text>
</view>
<!-- 登录按钮区域 -->
<view class="login-actions">
<button
class="login-btn"
@click="onWxLogin"
:loading="loading"
:disabled="loading"
>
微信一键登录
</button>
<text class="login-tip">{{ tipText }}</text>
</view>
<!-- 底部协议 -->
<view class="login-footer">
<text class="footer-text">登录即表示同意</text>
<text class="footer-link" @click="goAgreement">用户协议</text>
<text class="footer-text"></text>
<text class="footer-link" @click="goPrivacy">隐私政策</text>
</view>
</view>
</template>
<script setup>
import { ref } from 'vue'
import { useUserStore } from '@/stores/user'
import { wxLogin } from '@/utils/api'
const userStore = useUserStore()
const loading = ref(false)
const tipText = ref('使用微信账号快速登录')
const statusBarHeight = ref(0)
// 获取状态栏高度
const sysInfo = uni.getSystemInfoSync()
statusBarHeight.value = sysInfo.statusBarHeight || 0
/** 返回上一页 */
function goBack() {
const pages = getCurrentPages()
if (pages.length > 1) {
uni.navigateBack()
} else {
uni.switchTab({ url: '/pages/index/index' })
}
}
/** 微信一键登录 */
async function onWxLogin() {
loading.value = true
tipText.value = '登录中...'
try {
// 调用 wx.login 获取 code
const loginRes = await new Promise((resolve, reject) => {
uni.login({
provider: 'weixin',
success: resolve,
fail: reject
})
})
if (!loginRes?.code) {
tipText.value = '获取微信授权失败,请重试'
return
}
// 发送 code 到后端换取 token
console.log('[登录] 获取到 code:', loginRes.code)
const res = await wxLogin({ code: loginRes.code })
if (res.token && res.userInfo) {
userStore.setLoginInfo(res.token, res.userInfo)
uni.showToast({ title: '登录成功', icon: 'success' })
// 检查是否有登录前的回跳页面
const redirect = uni.getStorageSync('loginRedirect')
if (redirect) {
uni.removeStorageSync('loginRedirect')
uni.redirectTo({ url: redirect })
} else {
uni.reLaunch({ url: '/pages/index/index' })
}
} else {
tipText.value = '登录失败,请重试'
}
} catch (e) {
console.error('登录失败:', e)
tipText.value = '登录失败,请重试'
} finally {
loading.value = false
}
}
/** 跳转用户协议 */
function goAgreement() {
uni.navigateTo({ url: '/pages/config/agreement' })
}
/** 跳转隐私政策 */
function goPrivacy() {
uni.navigateTo({ url: '/pages/config/privacy' })
}
</script>
<style scoped>
.login-page {
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
background: linear-gradient(180deg, #FFF8E1 0%, #FFFFFF 40%);
padding: 0 60rpx;
}
/* 自定义导航栏 */
.custom-navbar {
position: fixed;
top: 0;
left: 0;
width: 100%;
z-index: 999;
}
.navbar-content {
height: 44px;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 20rpx;
}
.nav-back {
width: 60rpx;
height: 60rpx;
display: flex;
align-items: center;
justify-content: center;
}
.back-arrow {
font-size: 48rpx;
color: #333;
font-weight: bold;
}
.navbar-title {
font-size: 34rpx;
font-weight: bold;
color: #333;
}
.nav-placeholder {
width: 60rpx;
}
.login-header {
display: flex;
flex-direction: column;
align-items: center;
margin-bottom: 120rpx;
}
.login-logo {
width: 160rpx;
height: 160rpx;
margin-bottom: 30rpx;
}
.login-title {
font-size: 44rpx;
font-weight: bold;
color: #333;
margin-bottom: 16rpx;
}
.login-subtitle {
font-size: 28rpx;
color: #999;
}
.login-actions {
width: 100%;
display: flex;
flex-direction: column;
align-items: center;
}
.login-btn {
width: 100%;
height: 96rpx;
line-height: 96rpx;
background: linear-gradient(135deg, #FFB700, #FF9500);
color: #fff;
font-size: 34rpx;
font-weight: bold;
border-radius: 48rpx;
border: none;
letter-spacing: 4rpx;
}
.login-btn::after {
border: none;
}
.login-tip {
font-size: 24rpx;
color: #bbb;
margin-top: 24rpx;
}
.login-footer {
position: fixed;
bottom: 60rpx;
display: flex;
align-items: center;
}
.footer-text {
font-size: 22rpx;
color: #ccc;
}
.footer-link {
font-size: 22rpx;
color: #FFB700;
}
</style>