调整样式

This commit is contained in:
2025-11-17 17:30:29 +08:00
parent 7ee926dc66
commit ab5c01bf5c
9 changed files with 643 additions and 407 deletions

View File

@@ -1,85 +1,209 @@
<template>
<u-popup v-model="show" mode="bottom" border-radius="20">
<view class="p-30">
<view class="login-page">
<!-- 背景视频 -->
<video
class="bg-video"
src="/static/login.mp4"
autoplay
loop
muted
object-fit="cover"
controls="false"
show-center-play-btn="false"
show-play-btn="false"
show-fullscreen-btn="false"
show-mute-btn="false"
show-status-bar="false"
enable-progress-gesture="false"
/>
<view class="text-center u-font-32 u-m-b-20">
<!-- 遮罩层增强可读性 -->
<view class="overlay"></view>
<!-- 背景图 -->
<!-- <image class="bg-img" :src="currentBg" :class="{ fade: isFading }" mode="aspectFill"></image> -->
<!-- 内容层 -->
<view class="login-content">
<view class="title u-font-36 u-m-b-40">
微信授权登录
</view>
<button
class="u-button bg-green text-white"
class="login-btn"
open-type="getPhoneNumber"
@getphonenumber="onGetPhone"
>
使用微信手机号授权登录
</button>
<view class="privacy-tip u-m-t-30 u-text-center">
登录即同意
<text class="link" @click="goPrivacy('user')">用户协议</text>
<text class="link" @click="goPrivacy('privacy')">隐私政策</text>
</view>
</view>
</u-popup>
</view>
</template>
<script>
export default {
data() {
return {
show: false
}
},
data() {
return {
bgImages: [
'/static/loginbg1.jpg',
'/static/loginbg2.jpg'
],
currentIndex: 0,
currentBg: '/static/loginbg1.jpg',
timer: null
}
},
onLoad() {
this.startBgTimer();
},
onUnload() {
clearInterval(this.timer);
},
methods: {
open() {
this.show = true
},
// 微信授权手机号
startBgTimer() {
this.timer = setInterval(() => {
this.currentIndex = (this.currentIndex + 1) % this.bgImages.length;
this.currentBg = this.bgImages[this.currentIndex];
}, 2000); // 每 4 秒切换一次
},
onGetPhone(e) {
const { code } = e.detail
const { code } = e.detail;
if (!code) {
this.$mytip.toast("授权失败")
return
this.$mytip.toast("授权失败");
return;
}
this.doLogin(code)
this.doLogin(code);
},
// 登录逻辑
async doLogin(code) {
uni.showLoading({ title: "登录中...", mask: true })
uni.showLoading({ title: "登录中...", mask: true });
try {
// ① 调后端:通过微信 code => openid + 手机号信息
const authRes = await this.$u.get(`/api/weChatAuth?code=${code}`)
// authRes: { openid, hasPhone: true/false, phoneList: [...] }
const authRes = await this.$u.get(`/api/weChatAuth?code=${code}`);
if (!authRes.hasPhone) {
// ② 未绑定手机号 → 让用户选择手机号
this.showPhoneSelector(authRes.phoneList, authRes.openid)
return
this.showPhoneSelector(authRes.phoneList, authRes.openid);
return;
}
// ③ 已有绑定手机号 → 直接登录
await this.loginWithOpenId(authRes.openid)
await this.loginWithOpenId(authRes.openid);
} catch (err) {
this.$mytip.toast("登录失败")
this.$mytip.toast("登录失败");
uni.switchTab({ url: '/pages/index/index' });
}
},
// 提示选择手机号
showPhoneSelector(phoneList, openid) {
this.show = false
this.$emit("choosePhone", { phoneList, openid })
this.$emit("choosePhone", { phoneList, openid });
},
// 通过 openid 登录
async loginWithOpenId(openid) {
const loginRes = await this.$u.post('/api/weChatLoginByOpenId', { openid })
this.$u.vuex('vuex_token', loginRes.token)
this.$u.vuex('vuex_user', loginRes.loginUser)
uni.hideLoading()
uni.switchTab({ url: '/pages/index/index' })
const loginRes = await this.$u.post('/api/weChatLoginByOpenId', { openid });
this.$u.vuex('vuex_token', loginRes.token);
this.$u.vuex('vuex_user', loginRes.loginUser);
uni.hideLoading();
uni.switchTab({ url: '/pages/index/index' });
},
goPrivacy(type) {
const url = type === 'user'
? '/pages/privacy/userAgreement'
: '/pages/privacy/privacyPolicy';
uni.navigateTo({ url });
}
}
}
</script>
</script>
<style lang="scss" scoped>
.login-page {
position: relative;
width: 100%;
height: 100vh;
overflow: hidden;
.bg-video {
position: absolute;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
z-index: -1;
}
.overlay {
position: absolute;
top:0;
left:0;
width:100%;
height:100%;
background: rgba(0,0,0,0.3);
z-index:0;
}
.bg-img {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: -1;
filter: brightness(0.7) blur(2px);
opacity: 1;
transition: opacity 0.5s ease;
}
.bg-img.fade {
opacity: 0;
}
.login-content {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 80%;
max-width: 400rpx;
display: flex;
flex-direction: column;
align-items: center;
z-index: 1;
animation: floatBtn 2s ease-in-out infinite alternate;
.title {
color: #fff;
font-weight: bold;
text-align: center;
}
.login-btn {
width: 100%;
height: 80rpx;
line-height: 80rpx;
font-size: 28rpx;
color: #fff;
border-radius: 40rpx;
background: linear-gradient(90deg, #4CAF50, #07c160);
box-shadow: 0 6rpx 12rpx rgba(0,0,0,0.25);
text-align: center;
margin-top: 20rpx;
}
.privacy-tip {
font-size: 24rpx;
color: #fff;
margin-top: 20rpx;
text-align: center;
.link {
color: #ffd700;
text-decoration: underline;
margin: 0 4rpx;
}
}
}
}
@keyframes floatBtn {
0% { transform: translate(-50%, -50%) translateY(0); }
100% { transform: translate(-50%, -50%) translateY(-10rpx); }
}
</style>