Files
shangbangbang/uniapp/pages/register/register.vue
T
solosw 99b11b04e4 1.0
2026-01-05 14:11:34 +08:00

669 lines
15 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="container">
<view class="register-header">
<text class="page-title">用户注册</text>
</view>
<view class="register-form">
<!-- 基本信息 -->
<view class="section-title">基本信息</view>
<view class="form-item">
<text class="form-label">手机号 *</text>
<input class="form-input"
v-model="registerForm.phone"
type="number"
placeholder="请输入手机号"
maxlength="11" />
</view>
<view class="form-item">
<text class="form-label">密码 *</text>
<input class="form-input"
v-model="registerForm.password"
type="password"
placeholder="请输入密码(6-20位)" />
</view>
<view class="form-item">
<text class="form-label">确认密码 *</text>
<input class="form-input"
v-model="registerForm.confirmPassword"
type="password"
placeholder="请再次输入密码" />
</view>
<view class="form-item">
<text class="form-label">店铺名称 *</text>
<input class="form-input"
v-model="registerForm.customer_name"
placeholder="请输入店铺名称" />
</view>
<view class="form-item">
<text class="form-label">法人名称 *</text>
<input class="form-input"
v-model="registerForm.real_name"
placeholder="请输入法人名称" />
</view>
<view class="form-item">
<text class="form-label">公司名称 *</text>
<input class="form-input"
v-model="registerForm.company_name"
placeholder="请输入公司名称" />
</view>
<!-- 证件上传 -->
<view class="section-title">证件信息</view>
<view class="upload-section">
<text class="upload-label">身份证正面 *</text>
<view class="upload-area" @click="chooseIdCardFront">
<image v-if="registerForm.id_card_front"
:src="getFullImageUrl(registerForm.id_card_front)"
mode="aspectFill"
class="upload-image"></image>
<view v-else class="upload-placeholder">
<uni-icons type="camera" size="30" color="#999"></uni-icons>
<text class="upload-text">点击上传身份证正面</text>
</view>
</view>
</view>
<view class="upload-section">
<text class="upload-label">身份证反面 *</text>
<view class="upload-area" @click="chooseIdCardBack">
<image v-if="registerForm.id_card_back"
:src="getFullImageUrl(registerForm.id_card_back)"
mode="aspectFill"
class="upload-image"></image>
<view v-else class="upload-placeholder">
<uni-icons type="camera" size="30" color="#999"></uni-icons>
<text class="upload-text">点击上传身份证反面</text>
</view>
</view>
</view>
<view class="upload-section">
<text class="upload-label">营业执照 *</text>
<view class="upload-area" @click="chooseBusinessLicense">
<image v-if="registerForm.business_license"
:src="getFullImageUrl(registerForm.business_license)"
mode="aspectFill"
class="upload-image"></image>
<view v-else class="upload-placeholder">
<uni-icons type="camera" size="30" color="#999"></uni-icons>
<text class="upload-text">点击上传营业执照</text>
</view>
</view>
</view>
<!-- 验证方式 -->
<view class="section-title">验证信息</view>
<!-- 短信验证码必填 -->
<view class="verify-section">
<view class="form-item">
<text class="form-label">短信验证码 *</text>
<view class="verify-input-group">
<input class="form-input verify-input"
v-model="registerForm.sms_code"
type="number"
placeholder="请输入验证码"
maxlength="6" />
<button class="verify-btn"
@click="sendSmsCode"
:disabled="smsLoading || countdown > 0">
{{ smsLoading ? '发送中...' : countdown > 0 ? `${countdown}s` : '获取验证码' }}
</button>
</view>
</view>
</view>
<!-- 推荐人身份码选填 -->
<view class="form-item">
<text class="form-label">推荐人身份码</text>
<input class="form-input"
v-model="registerForm.referrer_identity_code"
placeholder="请输入推荐人身份码(选填)" />
</view>
<!-- 用户协议 -->
<view class="agreement-section">
<view class="agreement-item" @click="toggleAgreement">
<uni-icons :type="agreed ? 'checkbox-filled' : 'circle'" size="16" :color="agreed ? '#FF4444' : '#999'"></uni-icons>
<text class="agreement-text">我已阅读并同意</text>
<text class="agreement-link">用户协议</text>
<text class="agreement-text"></text>
<text class="agreement-link">隐私政策</text>
</view>
</view>
<!-- 注册按钮 -->
<button class="register-btn" @click="handleRegister" :disabled="registerLoading">
{{ registerLoading ? '注册中...' : '立即注册' }}
</button>
<view class="login-link">
<text class="link-text">已有账号</text>
<text class="link-action" @click="goToLogin">立即登录</text>
</view>
</view>
</view>
</template>
<script>
import request from '@/utils/request.js'
export default {
data() {
return {
token:'',
registerForm: {
phone: '',
password: '',
confirmPassword: '',
customer_name: '',
real_name: '',
company_name: '',
id_card_front: '',
id_card_back: '',
business_license: '',
referrer_identity_code: '',
sms_code: ''
},
agreed: false,
registerLoading: false,
smsLoading: false,
countdown: 0
}
},
onLoad() {
this.token=uni.getStorageSync('token')
},
methods: {
// 获取完整的图片URL
getFullImageUrl(url) {
return request.getImageUrl(url)
},
// 选择身份证正面
chooseIdCardFront() {
this.chooseImage('id_card_front')
},
// 选择身份证反面
chooseIdCardBack() {
this.chooseImage('id_card_back')
},
// 选择营业执照
chooseBusinessLicense() {
this.chooseImage('business_license')
},
// 选择图片并上传
chooseImage(field) {
uni.chooseImage({
count: 1,
sizeType: ['compressed'],
sourceType: ['camera', 'album'],
success: (res) => {
const tempFilePath = res.tempFilePaths[0]
this.uploadImage(tempFilePath, field)
}
})
},
// 上传图片
async uploadImage(filePath, field) {
uni.showLoading({
title: '上传中...'
})
try {
const res = await request.upload("/back/upload", filePath, {
token: this.token
})
if (res.success) {
this.registerForm[field] = res.data.url
uni.showToast({
title: '上传成功',
icon: 'success'
})
} else {
uni.showToast({
title: res.message || '上传失败',
icon: 'none'
})
}
// uni.uploadFile({
// url: request.config.baseURL + '/back/upload',
// filePath: filePath,
// name: 'file',
// header: {
// 'token': token
// },
// success: (uploadRes) => {
// try {
// const result = JSON.parse(uploadRes.data)
// if (result.success) {
// this.registerForm[field] = result.data.url
// uni.showToast({
// title: '上传成功',
// icon: 'success'
// })
// } else {
// uni.showToast({
// title: result.message || '上传失败',
// icon: 'none'
// })
// }
// } catch (e) {
// uni.showToast({
// title: '上传失败',
// icon: 'none'
// })
// }
// },
// fail: (err) => {
// console.log(err)
// uni.showToast({
// title: '上传失败',
// icon: 'none'
// })
// },
// complete: () => {
// uni.hideLoading()
// }
// })
} catch (error) {
uni.hideLoading()
uni.showToast({
title: '上传失败',
icon: 'none'
})
console.log(error)
}
},
// 发送短信验证码
async sendSmsCode() {
if (!this.registerForm.phone) {
uni.showToast({
title: '请先输入手机号',
icon: 'none'
})
return
}
if (!/^1[3-9]\d{9}$/.test(this.registerForm.phone)) {
uni.showToast({
title: '手机号格式不正确',
icon: 'none'
})
return
}
this.smsLoading = true
try {
const res = await request.post('/back/auth/send-sms', {
phone: this.registerForm.phone
})
if (res.success) {
uni.showToast({
title: '验证码发送成功',
icon: 'success'
})
// 开始倒计时
this.startCountdown()
} else {
uni.showToast({
title: res.message || '发送失败',
icon: 'none'
})
}
} catch (error) {
uni.showToast({
title: '发送失败',
icon: 'none'
})
} finally {
this.smsLoading = false
}
},
// 开始倒计时
startCountdown() {
this.countdown = 60
const timer = setInterval(() => {
this.countdown--
if (this.countdown <= 0) {
clearInterval(timer)
}
}, 1000)
},
// 切换协议同意状态
toggleAgreement() {
this.agreed = !this.agreed
},
// 表单验证
validateForm() {
if (!this.registerForm.phone) {
uni.showToast({ title: '请输入手机号', icon: 'none' })
return false
}
if (!/^1[3-9]\d{9}$/.test(this.registerForm.phone)) {
uni.showToast({ title: '手机号格式不正确', icon: 'none' })
return false
}
if (!this.registerForm.password) {
uni.showToast({ title: '请输入密码', icon: 'none' })
return false
}
if (this.registerForm.password.length < 6 || this.registerForm.password.length > 20) {
uni.showToast({ title: '密码长度为6-20位', icon: 'none' })
return false
}
if (this.registerForm.password !== this.registerForm.confirmPassword) {
uni.showToast({ title: '两次密码输入不一致', icon: 'none' })
return false
}
if (!this.registerForm.customer_name) {
uni.showToast({ title: '请输入店铺名称', icon: 'none' })
return false
}
if (!this.registerForm.real_name) {
uni.showToast({ title: '请输入法人名称', icon: 'none' })
return false
}
if (!this.registerForm.company_name) {
uni.showToast({ title: '请输入公司名称', icon: 'none' })
return false
}
if (!this.registerForm.id_card_front) {
uni.showToast({ title: '请上传身份证正面', icon: 'none' })
return false
}
if (!this.registerForm.id_card_back) {
uni.showToast({ title: '请上传身份证反面', icon: 'none' })
return false
}
if (!this.registerForm.business_license) {
uni.showToast({ title: '请上传营业执照', icon: 'none' })
return false
}
if (!this.registerForm.sms_code) {
uni.showToast({ title: '请输入短信验证码', icon: 'none' })
return false
}
if (!this.agreed) {
uni.showToast({ title: '请先同意用户协议', icon: 'none' })
return false
}
return true
},
// 处理注册
async handleRegister() {
if (!this.validateForm()) {
return
}
this.registerLoading = true
try {
// 准备注册数据
const registerData = {
phone: this.registerForm.phone,
password: this.registerForm.password,
customer_name: this.registerForm.customer_name,
real_name: this.registerForm.real_name,
company_name: this.registerForm.company_name,
business_license_image: this.registerForm.business_license,
id_card_front_image: this.registerForm.id_card_front,
id_card_back_image: this.registerForm.id_card_back
}
// 添加验证信息(验证码必填,身份码选填)
registerData.sms_code = this.registerForm.sms_code
if (this.registerForm.referrer_identity_code) {
registerData.referrer_identity_code = this.registerForm.referrer_identity_code
}
const res = await request.post('/back/auth/register', registerData)
if (res.success) {
uni.showToast({
title: '注册成功',
icon: 'success'
})
setTimeout(() => {
uni.navigateBack()
}, 1500)
} else {
uni.showToast({
title: res.message || '注册失败',
icon: 'none'
})
}
} catch (error) {
console.error('注册失败:', error)
uni.showToast({
title: '网络错误,请稍后重试',
icon: 'none'
})
} finally {
this.registerLoading = false
}
},
// 跳转到登录页面
goToLogin() {
uni.navigateBack()
}
}
}
</script>
<style scoped>
.container {
background-color: #f5f5f5;
min-height: 100vh;
}
.register-header {
background: linear-gradient(135deg, #FF4444 0%, #FF6666 100%);
padding: 40rpx 30rpx;
text-align: center;
color: #fff;
}
.page-title {
font-size: 36rpx;
font-weight: bold;
}
.register-form {
padding: 40rpx 30rpx;
}
.section-title {
font-size: 32rpx;
font-weight: bold;
color: #333;
margin: 40rpx 0 30rpx 0;
}
.form-item {
background-color: #fff;
border-radius: 16rpx;
padding: 30rpx;
margin-bottom: 20rpx;
}
.form-label {
display: block;
font-size: 28rpx;
color: #333;
margin-bottom: 20rpx;
}
.form-input {
width: 100%;
font-size: 28rpx;
color: #333;
}
/* 上传区域 */
.upload-section {
margin-bottom: 30rpx;
}
.upload-label {
display: block;
font-size: 28rpx;
color: #333;
margin-bottom: 20rpx;
}
.upload-area {
background-color: #fff;
border-radius: 16rpx;
height: 200rpx;
display: flex;
align-items: center;
justify-content: center;
border: 2rpx dashed #ddd;
}
.upload-image {
width: 100%;
height: 100%;
border-radius: 16rpx;
}
.upload-placeholder {
display: flex;
flex-direction: column;
align-items: center;
color: #999;
}
.upload-placeholder uni-icons {
margin-bottom: 15rpx;
}
.upload-text {
font-size: 24rpx;
}
/* 验证码输入组 */
.verify-section {
margin-bottom: 20rpx;
}
.verify-input-group {
display: flex;
align-items: center;
gap: 20rpx;
}
.verify-input {
flex: 1;
}
.verify-btn {
background-color: #FF4444;
color: #fff;
border: none;
border-radius: 8rpx;
padding: 20rpx 30rpx;
font-size: 24rpx;
white-space: nowrap;
}
.verify-btn:disabled {
background-color: #ccc;
}
/* 用户协议 */
.agreement-section {
margin: 40rpx 0;
}
.agreement-item {
display: flex;
align-items: center;
padding: 20rpx;
}
.agreement-item uni-icons {
margin-right: 15rpx;
}
.agreement-text {
font-size: 24rpx;
color: #666;
}
.agreement-link {
font-size: 24rpx;
color: #FF4444;
text-decoration: underline;
}
/* 注册按钮 */
.register-btn {
background-color: #FF4444;
color: #fff;
border-radius: 50rpx;
height: 100rpx;
font-size: 32rpx;
font-weight: bold;
margin: 40rpx 0;
border: none;
}
.register-btn:disabled {
background-color: #ccc;
}
/* 登录链接 */
.login-link {
text-align: center;
margin-top: 40rpx;
}
.link-text {
font-size: 28rpx;
color: #666;
}
.link-action {
font-size: 28rpx;
color: #FF4444;
text-decoration: underline;
}
</style>