init: llpreheat 学法送演唱会门票 H5项目
This commit is contained in:
@@ -0,0 +1,340 @@
|
||||
<template>
|
||||
<view class="register-page">
|
||||
<view class="header">
|
||||
<text class="header-title">注册信息</text>
|
||||
<text class="header-desc">填写资料即可参与答题抽奖</text>
|
||||
</view>
|
||||
<view class="form">
|
||||
<view class="field">
|
||||
<text class="label">姓名</text>
|
||||
<view class="input-wrap">
|
||||
<text class="input-icon">👤</text>
|
||||
<input class="input" v-model="userName" placeholder="请输入您的姓名" />
|
||||
</view>
|
||||
<text class="name-tip">本次演唱会门票实行实名制管理,参与抽奖活动须如实填报本人姓名与手机号码;中奖后须在24小时内完成兑奖操作,兑奖时需补充填报本人身份证号码。</text>
|
||||
</view>
|
||||
<view class="field">
|
||||
<text class="label">手机号</text>
|
||||
<view class="input-wrap">
|
||||
<text class="input-icon">📱</text>
|
||||
<input class="input" v-model="phone" placeholder="请输入手机号" type="number" maxlength="11" />
|
||||
</view>
|
||||
</view>
|
||||
<view class="field">
|
||||
<text class="label">验证码</text>
|
||||
<view class="field-row">
|
||||
<view class="input-wrap code-input-wrap">
|
||||
<text class="input-icon">✉️</text>
|
||||
<input class="input" v-model="smsCode" placeholder="请输入验证码" type="number" maxlength="6" />
|
||||
</view>
|
||||
<button class="code-btn" @tap="sendCode" :disabled="sending" :class="{ disabled: sending }">
|
||||
{{ sending ? countdown + 's' : '获取验证码' }}
|
||||
</button>
|
||||
</view>
|
||||
</view>
|
||||
<view class="agree-row" @tap="agreed = !agreed">
|
||||
<view class="agree-checkbox" :class="{ checked: agreed }">
|
||||
<text v-if="agreed" class="agree-check-mark">✓</text>
|
||||
</view>
|
||||
<view class="agree-text">
|
||||
<text>我已阅读并同意</text>
|
||||
<text class="agree-link" @tap.stop="goPrivacy">《用户隐私协议》</text>
|
||||
</view>
|
||||
</view>
|
||||
<button class="submit-btn" @tap="register" :disabled="submitting" :class="{ disabled: submitting }">
|
||||
{{ submitting ? '提交中...' : '立即注册' }}
|
||||
</button>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
userName: '',
|
||||
phone: '',
|
||||
smsCode: '',
|
||||
sending: false,
|
||||
countdown: 60,
|
||||
timer: null,
|
||||
submitting: false,
|
||||
agreed: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
goPrivacy() {
|
||||
uni.navigateTo({ url: '/pages/privacy/privacy' })
|
||||
},
|
||||
sendCode() {
|
||||
if (!/^1\d{10}$/.test(this.phone)) {
|
||||
uni.showToast({ title: '请输入正确手机号', icon: 'none' })
|
||||
return
|
||||
}
|
||||
this.sending = true
|
||||
this.$u.api.sendSms(this.phone).then(res => {
|
||||
if (res.code === 0) {
|
||||
uni.showToast({ title: '验证码已发送', icon: 'none' })
|
||||
this.startCountdown()
|
||||
} else {
|
||||
uni.showToast({ title: res.msg || '发送失败', icon: 'none' })
|
||||
this.sending = false
|
||||
}
|
||||
}).catch(() => {
|
||||
uni.showToast({ title: '网络错误', icon: 'none' })
|
||||
this.sending = false
|
||||
})
|
||||
},
|
||||
startCountdown() {
|
||||
this.countdown = 60
|
||||
this.timer = setInterval(() => {
|
||||
this.countdown--
|
||||
if (this.countdown <= 0) {
|
||||
clearInterval(this.timer)
|
||||
this.timer = null
|
||||
this.sending = false
|
||||
}
|
||||
}, 1000)
|
||||
},
|
||||
register() {
|
||||
if (!this.userName || !this.phone || !this.smsCode) {
|
||||
uni.showToast({ title: '请填写完整信息', icon: 'none' })
|
||||
return
|
||||
}
|
||||
if (!this.agreed) {
|
||||
uni.showToast({ title: '请阅读并同意《用户隐私协议》', icon: 'none' })
|
||||
return
|
||||
}
|
||||
this.submitting = true
|
||||
const openId = uni.getStorageSync('openId')
|
||||
this.$u.api.userRegist({
|
||||
wenjuan_id: 1001,
|
||||
open_id: openId,
|
||||
user_name: this.userName,
|
||||
user_phone: this.phone,
|
||||
sms_code: this.smsCode,
|
||||
channel: 1
|
||||
}).then(res => {
|
||||
if (res.code === 0) {
|
||||
uni.setStorageSync('isRegistered', true)
|
||||
const data = res.Data || {}
|
||||
const userId = data.user_id || data.uesr_id
|
||||
if (userId) uni.setStorageSync('userId', userId)
|
||||
if (data.user_name) uni.setStorageSync('userName', data.user_name)
|
||||
if (data.user_phone) uni.setStorageSync('userPhone', data.user_phone)
|
||||
this.syncUserInfo(openId)
|
||||
uni.showToast({ title: '注册成功' })
|
||||
setTimeout(() => uni.navigateBack(), 1500)
|
||||
} else {
|
||||
uni.showToast({ title: res.msg || '注册失败', icon: 'none' })
|
||||
}
|
||||
}).catch(() => {
|
||||
uni.showToast({ title: '网络错误', icon: 'none' })
|
||||
}).finally(() => {
|
||||
this.submitting = false
|
||||
})
|
||||
},
|
||||
syncUserInfo(openId) {
|
||||
this.$u.api.wxOpenidLogin({ wenjuan_id: 1001, open_id: openId }).then(loginRes => {
|
||||
if (loginRes.code === 0 && loginRes.Data) {
|
||||
const data = loginRes.Data
|
||||
if (data.user_id || data.uesr_id) uni.setStorageSync('userId', data.user_id || data.uesr_id)
|
||||
if (data.user_name) uni.setStorageSync('userName', data.user_name)
|
||||
if (data.user_phone) uni.setStorageSync('userPhone', data.user_phone)
|
||||
}
|
||||
}).catch(err => {
|
||||
console.error('注册后同步用户信息失败', err)
|
||||
})
|
||||
},
|
||||
},
|
||||
beforeDestroy() {
|
||||
if (this.timer) {
|
||||
clearInterval(this.timer)
|
||||
this.timer = null
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
page {
|
||||
background: linear-gradient(135deg, #FFF8ED 0%, #FFE9C4 100%);
|
||||
}
|
||||
|
||||
.register-page {
|
||||
padding: 60rpx 40rpx;
|
||||
min-height: 100vh;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.header {
|
||||
margin-bottom: 50rpx;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.header-title {
|
||||
font-size: 40rpx;
|
||||
font-weight: bold;
|
||||
color: #5D533D;
|
||||
display: block;
|
||||
margin-bottom: 12rpx;
|
||||
}
|
||||
|
||||
.header-desc {
|
||||
font-size: 26rpx;
|
||||
color: #8B7355;
|
||||
}
|
||||
|
||||
.form {
|
||||
background: rgba(255, 255, 255, 0.95);
|
||||
border-radius: 24rpx;
|
||||
padding: 50rpx 40rpx;
|
||||
box-shadow: 0 8rpx 40rpx rgba(0, 0, 0, 0.06);
|
||||
}
|
||||
|
||||
.field {
|
||||
margin-bottom: 36rpx;
|
||||
}
|
||||
|
||||
.label {
|
||||
font-size: 28rpx;
|
||||
font-weight: 500;
|
||||
color: #5D533D;
|
||||
margin-bottom: 16rpx;
|
||||
display: block;
|
||||
padding-left: 8rpx;
|
||||
}
|
||||
|
||||
.input-wrap {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 88rpx;
|
||||
border: 2rpx solid #F0E4D0;
|
||||
border-radius: 12rpx;
|
||||
background: #FEFCF8;
|
||||
padding: 0 24rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.input-wrap:focus-within {
|
||||
border-color: #FD5401;
|
||||
box-shadow: 0 0 0 4rpx rgba(253, 84, 1, 0.08);
|
||||
}
|
||||
|
||||
.input-icon {
|
||||
font-size: 32rpx;
|
||||
margin-right: 16rpx;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.input {
|
||||
height: 100%;
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
flex: 1;
|
||||
border: none;
|
||||
background: transparent;
|
||||
outline: none;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.name-tip {
|
||||
display: block;
|
||||
font-size: 22rpx;
|
||||
color: #E4393C;
|
||||
line-height: 1.5;
|
||||
margin-top: 12rpx;
|
||||
padding: 12rpx 16rpx;
|
||||
background: #FFEFE9;
|
||||
border-radius: 12rpx;
|
||||
}
|
||||
|
||||
.field-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.code-input-wrap {
|
||||
flex: 1;
|
||||
margin-right: 20rpx;
|
||||
}
|
||||
|
||||
.code-btn {
|
||||
flex-shrink: 0;
|
||||
height: 88rpx;
|
||||
line-height: 88rpx;
|
||||
padding: 0 28rpx;
|
||||
font-size: 26rpx;
|
||||
color: #FD5401;
|
||||
background: #FFF0E6;
|
||||
border: none;
|
||||
border-radius: 12rpx;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.code-btn.disabled {
|
||||
color: #B8A898;
|
||||
background: #F0E8E0;
|
||||
}
|
||||
|
||||
.submit-btn {
|
||||
width: 100%;
|
||||
height: 96rpx;
|
||||
line-height: 96rpx;
|
||||
background: linear-gradient(135deg, #FD5401, #FF7A3D);
|
||||
color: #fff;
|
||||
font-size: 34rpx;
|
||||
font-weight: 600;
|
||||
border: none;
|
||||
border-radius: 16rpx;
|
||||
margin-top: 20rpx;
|
||||
box-shadow: 0 6rpx 20rpx rgba(253, 84, 1, 0.3);
|
||||
}
|
||||
|
||||
.submit-btn.disabled {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.agree-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin: -16rpx 8rpx 28rpx;
|
||||
}
|
||||
|
||||
.agree-checkbox {
|
||||
width: 36rpx;
|
||||
height: 36rpx;
|
||||
border: 2rpx solid #CCC;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-shrink: 0;
|
||||
margin-right: 12rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.agree-checkbox.checked {
|
||||
border-color: #FD5401;
|
||||
background: #FD5401;
|
||||
}
|
||||
|
||||
.agree-check-mark {
|
||||
font-size: 22rpx;
|
||||
color: #fff;
|
||||
font-weight: 700;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.agree-text {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 24rpx;
|
||||
color: #8B7355;
|
||||
}
|
||||
|
||||
.agree-link {
|
||||
color: #FD5401;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user