1.0
This commit is contained in:
@@ -0,0 +1,669 @@
|
||||
<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>
|
||||
Reference in New Issue
Block a user