165 lines
6.6 KiB
Vue
165 lines
6.6 KiB
Vue
<template>
|
|
<view class="login-page" :style="{ paddingTop: statusBarHeight + 'px', backgroundColor: brandConfig.secondaryColor }">
|
|
<view class="brand-area">
|
|
<view class="logo-wrap" :style="{ backgroundColor: brandConfig.logoUrl ? 'transparent' : 'rgba(' + brandConfig.primaryColorRgb + ',0.15)' }">
|
|
<image v-if="brandConfig.logoUrl" class="logo-img" :src="brandConfig.logoUrl" mode="aspectFit" />
|
|
<text v-else class="logo-symbol" :style="{ color: brandConfig.primaryColor }">✦</text>
|
|
</view>
|
|
<text class="app-name">{{ brandConfig.brandName }}</text>
|
|
<text class="app-slogan" v-if="brandConfig.slogan">{{ brandConfig.slogan }}</text>
|
|
</view>
|
|
|
|
<view class="login-btn-area">
|
|
<button class="wechat-login-btn" @click="handleLogin"
|
|
:style="{ background: brandConfig.primaryColor }">
|
|
<text class="wechat-symbol" :style="{ color: brandConfig.secondaryColor }">微</text>
|
|
<text class="btn-text" :style="{ color: brandConfig.secondaryColor }">微信一键登录</text>
|
|
</button>
|
|
|
|
<view class="agreement-row">
|
|
<view class="checkbox-wrapper" @click="toggleAgree">
|
|
<view class="checkbox" :class="{ checked: agreed }" :style="agreed ? agreedStyle : ''">
|
|
<text v-if="agreed" class="check-mark" :style="{ color: brandConfig.secondaryColor }">✓</text>
|
|
</view>
|
|
</view>
|
|
<text class="agreement-text">
|
|
已阅读并同意
|
|
<text class="link" :style="{ color: brandConfig.primaryColor }">《用户协议》</text>
|
|
和
|
|
<text class="link" :style="{ color: brandConfig.primaryColor }">《隐私政策》</text>
|
|
</text>
|
|
</view>
|
|
</view>
|
|
|
|
<view class="other-login">
|
|
<text class="divider-text">其他登录方式</text>
|
|
<view class="other-icons">
|
|
<view class="other-item">
|
|
<view class="other-icon-circle">
|
|
<text class="other-symbol">☏</text>
|
|
</view>
|
|
<text class="other-label">手机号</text>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
<view class="footer-tip">
|
|
<text>首次登录将自动注册账号</text>
|
|
</view>
|
|
</view>
|
|
</template>
|
|
|
|
<script>
|
|
const authApi = require('../../api/auth')
|
|
const store = require('../../store/index')
|
|
const brandStore = require('../../store/brand')
|
|
|
|
export default {
|
|
data() {
|
|
return {
|
|
statusBarHeight: 0,
|
|
agreed: false,
|
|
loading: false,
|
|
brandConfig: brandStore.config
|
|
}
|
|
},
|
|
onLoad() {
|
|
const systemInfo = uni.getSystemInfoSync()
|
|
this.statusBarHeight = systemInfo.statusBarHeight || 20
|
|
// 已登录则直接跳转首页
|
|
if (store.isLoggedIn) {
|
|
uni.switchTab({ url: '/pages/index/index' })
|
|
}
|
|
uni.$on('brand:updated', (config) => { this.brandConfig = config })
|
|
},
|
|
onUnload() {
|
|
uni.$off('brand:updated')
|
|
},
|
|
computed: {
|
|
agreedStyle() {
|
|
return 'background:' + this.brandConfig.primaryColor + ';border-color:' + this.brandConfig.secondaryColor
|
|
}
|
|
},
|
|
methods: {
|
|
toggleAgree() { this.agreed = !this.agreed },
|
|
handleLogin() {
|
|
if (!this.agreed) {
|
|
uni.showToast({ title: '请先同意用户协议', icon: 'none' })
|
|
return
|
|
}
|
|
if (this.loading) return
|
|
this.loading = true
|
|
|
|
// 微信小程序登录
|
|
// #ifdef MP-WEIXIN
|
|
uni.login({
|
|
provider: 'weixin',
|
|
success: (loginRes) => {
|
|
authApi.miniappLogin(loginRes.code)
|
|
.then((res) => {
|
|
store.setLogin(res.accessToken, { memberId: res.memberId, isNewUser: res.isNewUser })
|
|
uni.switchTab({ url: '/pages/index/index' })
|
|
})
|
|
.catch((err) => {
|
|
console.error('登录失败:', err)
|
|
uni.showToast({ title: '登录失败,请重试', icon: 'none' })
|
|
})
|
|
.finally(() => { this.loading = false })
|
|
},
|
|
fail: (err) => {
|
|
console.error('wx.login 失败:', err)
|
|
uni.showToast({ title: '获取微信授权失败', icon: 'none' })
|
|
this.loading = false
|
|
}
|
|
})
|
|
// #endif
|
|
|
|
// #ifndef MP-WEIXIN
|
|
// H5 / App 环境:使用模拟登录(开发调试)
|
|
uni.showToast({ title: '非小程序环境,使用模拟登录', icon: 'none' })
|
|
setTimeout(() => {
|
|
store.setLogin('dev-token-' + Date.now(), { memberId: 1, isNewUser: false })
|
|
uni.switchTab({ url: '/pages/index/index' })
|
|
this.loading = false
|
|
}, 500)
|
|
// #endif
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style scoped>
|
|
.login-page { min-height: 100vh; background: #F5F7FA; display: flex; flex-direction: column; align-items: center; padding: 0 32px; overflow-x: hidden; }
|
|
|
|
.brand-area { display: flex; flex-direction: column; align-items: center; margin-top: 60px; margin-bottom: 80px; }
|
|
.logo-wrap { width: 120px; height: 120px; background: rgba(0,230,118,0.15); border-radius: 50%; display: flex; align-items: center; justify-content: center; margin-bottom: 24px; overflow: hidden; }
|
|
.logo-img { width: 100%; height: 100%; }
|
|
.logo-symbol { font-size: 52px; color: #00C853; }
|
|
.app-name { font-size: 28px; font-weight: 700; color: #FFFFFF; letter-spacing: 1px; }
|
|
.app-slogan { font-size: 14px; color: rgba(255,255,255,0.6); margin-top: 8px; letter-spacing: 2px; }
|
|
|
|
.login-btn-area { width: 100%; display: flex; flex-direction: column; align-items: center; }
|
|
.wechat-login-btn { width: 100%; height: 52px; background: #00E676; border-radius: 40px; display: flex; align-items: center; justify-content: center; border: none; padding: 0; box-shadow: 0 4px 16px rgba(0,230,118,0.35); }
|
|
.wechat-login-btn::after { border: none; }
|
|
.wechat-symbol { font-size: 18px; font-weight: 700; color: #1A1A1A; margin-right: 8px; }
|
|
.btn-text { font-size: 17px; font-weight: 700; color: #1A1A1A; }
|
|
|
|
.agreement-row { display: flex; align-items: center; margin-top: 16px; }
|
|
.checkbox-wrapper { margin-right: 6px; }
|
|
.checkbox { width: 18px; height: 18px; border-radius: 50%; border: 2px solid rgba(255,255,255,0.3); display: flex; align-items: center; justify-content: center; }
|
|
.checkbox.checked { background: #00E676; border-color: #00E676; }
|
|
.check-mark { font-size: 12px; color: #1A1A1A; font-weight: 700; }
|
|
.agreement-text { font-size: 12px; color: rgba(255,255,255,0.5); }
|
|
.link { color: #00E676; }
|
|
|
|
.other-login { margin-top: 60px; width: 100%; display: flex; flex-direction: column; align-items: center; }
|
|
.divider-text { font-size: 13px; color: rgba(255,255,255,0.3); margin-bottom: 20px; }
|
|
.other-icons { display: flex; }
|
|
.other-item { display: flex; flex-direction: column; align-items: center; }
|
|
.other-icon-circle { width: 48px; height: 48px; background: rgba(255,255,255,0.1); border-radius: 50%; display: flex; align-items: center; justify-content: center; box-shadow: 0 4px 12px rgba(0,0,0,0.2); }
|
|
.other-symbol { font-size: 22px; color: rgba(255,255,255,0.6); }
|
|
.other-label { font-size: 12px; color: rgba(255,255,255,0.4); }
|
|
|
|
.footer-tip { position: absolute; bottom: 60px; font-size: 12px; color: rgba(255,255,255,0.25); }
|
|
</style>
|