260720
This commit is contained in:
298
pages/login/index.vue
Normal file
298
pages/login/index.vue
Normal file
@@ -0,0 +1,298 @@
|
||||
<template>
|
||||
<view class="page">
|
||||
<view class="hero-card">
|
||||
<view class="hero-title">进入智慧团委小程序</view>
|
||||
<view class="hero-desc">支持手机号密码登录,也支持微信手机号授权登录。</view>
|
||||
</view>
|
||||
|
||||
<view class="login-card">
|
||||
<view class="tab-row">
|
||||
<view
|
||||
class="tab-item"
|
||||
:class="{ 'tab-item--active': loginMode === 'password' }"
|
||||
@tap="loginMode = 'password'"
|
||||
>
|
||||
手机号密码登录
|
||||
</view>
|
||||
<view
|
||||
class="tab-item"
|
||||
:class="{ 'tab-item--active': loginMode === 'wechat' }"
|
||||
@tap="loginMode = 'wechat'"
|
||||
>
|
||||
微信授权登录
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view v-if="loginMode === 'password'" class="form-section">
|
||||
<uv-input
|
||||
v-model.trim="form.username"
|
||||
class="field-input"
|
||||
type="text"
|
||||
placeholder="请输入手机号或账号"
|
||||
:maxlength="-1"
|
||||
border="none"
|
||||
/>
|
||||
<uv-input
|
||||
v-model="form.password"
|
||||
class="field-input"
|
||||
type="password"
|
||||
placeholder="请输入密码"
|
||||
:maxlength="-1"
|
||||
border="none"
|
||||
password
|
||||
/>
|
||||
<view class="submit-btn" :class="{ 'submit-btn--loading': loading }" @tap="submitPasswordLogin">
|
||||
{{ loading ? '登录中...' : '立即登录' }}
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view v-else class="form-section">
|
||||
<view class="wechat-intro">授权后将使用微信手机号完成登录。</view>
|
||||
<button
|
||||
class="submit-btn submit-btn--wechat"
|
||||
:disabled="loading"
|
||||
open-type="getPhoneNumber"
|
||||
@getphonenumber="handleWxPhoneLogin"
|
||||
>
|
||||
{{ loading ? '登录中...' : '微信授权登录' }}
|
||||
</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { loginByMpWxPhone, loginByPassword } from './service'
|
||||
import { hasToken, setAuthInfo } from '../../utils/request'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
loginMode: 'password',
|
||||
loading: false,
|
||||
redirect: '',
|
||||
wxCode: '',
|
||||
form: {
|
||||
username: '',
|
||||
password: ''
|
||||
}
|
||||
}
|
||||
},
|
||||
onLoad(options) {
|
||||
this.redirect = decodeURIComponent((options && options.redirect) || '')
|
||||
},
|
||||
onShow() {
|
||||
if (hasToken()) {
|
||||
this.navigateAfterLogin()
|
||||
return
|
||||
}
|
||||
this.refreshWxCode()
|
||||
},
|
||||
methods: {
|
||||
showToast(title) {
|
||||
uni.showToast({
|
||||
title,
|
||||
icon: 'none'
|
||||
})
|
||||
},
|
||||
refreshWxCode() {
|
||||
uni.login({
|
||||
success: (res) => {
|
||||
this.wxCode = (res && res.code) || ''
|
||||
}
|
||||
})
|
||||
},
|
||||
navigateAfterLogin() {
|
||||
const url = this.redirect || '/pages/index/index'
|
||||
uni.reLaunch({
|
||||
url
|
||||
})
|
||||
},
|
||||
async submitPasswordLogin() {
|
||||
if (this.loading) {
|
||||
return
|
||||
}
|
||||
if (!this.form.username) {
|
||||
this.showToast('请输入手机号或账号')
|
||||
return
|
||||
}
|
||||
if (!this.form.password) {
|
||||
this.showToast('请输入密码')
|
||||
return
|
||||
}
|
||||
this.loading = true
|
||||
try {
|
||||
const result = await loginByPassword({
|
||||
username: this.form.username,
|
||||
password: this.form.password
|
||||
})
|
||||
setAuthInfo(result)
|
||||
this.showToast('登录成功')
|
||||
setTimeout(() => {
|
||||
this.navigateAfterLogin()
|
||||
}, 300)
|
||||
} catch (error) {
|
||||
this.showToast((error && error.message) || '登录失败')
|
||||
} finally {
|
||||
this.loading = false
|
||||
}
|
||||
},
|
||||
async handleWxPhoneLogin(event) {
|
||||
if (this.loading) {
|
||||
return
|
||||
}
|
||||
const detail = (event && event.detail) || {}
|
||||
if (!detail.code) {
|
||||
this.showToast(detail.errMsg || '未获取到微信手机号凭证')
|
||||
return
|
||||
}
|
||||
this.loading = true
|
||||
try {
|
||||
if (!this.wxCode) {
|
||||
await new Promise((resolve) => {
|
||||
uni.login({
|
||||
success: (res) => {
|
||||
this.wxCode = (res && res.code) || ''
|
||||
resolve()
|
||||
},
|
||||
fail: () => resolve()
|
||||
})
|
||||
})
|
||||
}
|
||||
const result = await loginByMpWxPhone({
|
||||
phoneCode: detail.code,
|
||||
code: this.wxCode || undefined
|
||||
})
|
||||
setAuthInfo(result)
|
||||
this.showToast('登录成功')
|
||||
setTimeout(() => {
|
||||
this.navigateAfterLogin()
|
||||
}, 300)
|
||||
} catch (error) {
|
||||
this.showToast((error && error.message) || '微信登录失败')
|
||||
this.refreshWxCode()
|
||||
} finally {
|
||||
this.loading = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.page {
|
||||
min-height: 100vh;
|
||||
padding: 28rpx 24rpx 40rpx;
|
||||
background:
|
||||
radial-gradient(circle at top left, rgba(20, 150, 242, 0.14), transparent 30%),
|
||||
linear-gradient(180deg, #f5fbff 0%, #eef7ff 100%);
|
||||
}
|
||||
|
||||
.hero-card,
|
||||
.login-card {
|
||||
border-radius: 32rpx;
|
||||
box-shadow: 0 18rpx 40rpx rgba(20, 118, 194, 0.12);
|
||||
}
|
||||
|
||||
.hero-card {
|
||||
padding: 34rpx 30rpx;
|
||||
background: linear-gradient(145deg, #0d6fba 0%, #1496f2 58%, #5bc2ff 100%);
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.hero-badge {
|
||||
display: inline-flex;
|
||||
padding: 10rpx 18rpx;
|
||||
border-radius: 999rpx;
|
||||
background: rgba(255, 255, 255, 0.16);
|
||||
font-size: 22rpx;
|
||||
}
|
||||
|
||||
.hero-title {
|
||||
margin-top: 22rpx;
|
||||
font-size: 42rpx;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.hero-desc {
|
||||
margin-top: 14rpx;
|
||||
font-size: 24rpx;
|
||||
line-height: 1.7;
|
||||
color: rgba(255, 255, 255, 0.86);
|
||||
}
|
||||
|
||||
.login-card {
|
||||
margin-top: 24rpx;
|
||||
padding: 28rpx 24rpx;
|
||||
background: rgba(255, 255, 255, 0.94);
|
||||
}
|
||||
|
||||
.tab-row {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
gap: 14rpx;
|
||||
}
|
||||
|
||||
.tab-item {
|
||||
height: 82rpx;
|
||||
border-radius: 22rpx;
|
||||
background: #edf5ff;
|
||||
color: #1496f2;
|
||||
font-size: 24rpx;
|
||||
font-weight: 600;
|
||||
line-height: 82rpx;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.tab-item--active {
|
||||
background: linear-gradient(135deg, #1496f2, #0d6fba);
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.form-section {
|
||||
margin-top: 22rpx;
|
||||
}
|
||||
|
||||
:deep(.field-input.uv-input) {
|
||||
width: 100%;
|
||||
height: 88rpx;
|
||||
margin-top: 16rpx;
|
||||
padding: 0 24rpx !important;
|
||||
border-radius: 24rpx;
|
||||
background: #f8fbff !important;
|
||||
border: 1rpx solid rgba(20, 150, 242, 0.12) !important;
|
||||
}
|
||||
|
||||
:deep(.field-input.uv-input .uv-input__content__field-wrapper__field) {
|
||||
font-size: 24rpx;
|
||||
color: #1f2329;
|
||||
}
|
||||
|
||||
.wechat-intro {
|
||||
font-size: 24rpx;
|
||||
line-height: 1.7;
|
||||
color: #667085;
|
||||
}
|
||||
|
||||
.submit-btn {
|
||||
width: 100%;
|
||||
height: 88rpx;
|
||||
margin-top: 22rpx;
|
||||
border: none;
|
||||
border-radius: 24rpx;
|
||||
background: linear-gradient(135deg, #1496f2, #0d6fba);
|
||||
color: #fff;
|
||||
font-size: 26rpx;
|
||||
font-weight: 700;
|
||||
line-height: 88rpx;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.submit-btn--wechat {
|
||||
background: linear-gradient(135deg, #1dbf73, #12a150);
|
||||
}
|
||||
|
||||
.submit-btn--loading {
|
||||
opacity: 0.72;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user