daShangDao_miniProgram/pages/register/index.vue
2025-11-24 10:25:20 +08:00

463 lines
11 KiB
Vue

<template>
<view class="register-container">
<view class="register-header">
<text class="register-title">用户注册</text>
<text class="register-subtitle">请填写以下信息完成注册</text>
</view>
<!-- 租户选择 -->
<!-- <view class="form-item">
<picker @change="onTenantChange" :value="tenantIndex" :range="tenantList" range-key="companyName">
<view class="picker">
{{ registerForm.tenantId ? selectedTenant.companyName : '请选择租户' }}
</view>
</picker>
</view> -->
<!-- 用户名 -->
<view class="form-item">
<input v-model="registerForm.username" placeholder="请输入用户名" class="input" placeholder-class="placeholder" />
</view>
<!-- 手机号 -->
<view class="form-item">
<input v-model="registerForm.phoneNumber" placeholder="请输入手机号" class="input" placeholder-class="placeholder"
type="number" maxlength="11" />
</view>
<!-- 密码 -->
<view class="form-item">
<input v-model="registerForm.password" password placeholder="请输入密码" class="input"
placeholder-class="placeholder" />
</view>
<!-- 确认密码 -->
<view class="form-item">
<input v-model="confirmPassword" password placeholder="请确认密码" class="input"
placeholder-class="placeholder" />
</view>
<!-- 图形验证码 -->
<view class="form-item code-item">
<input v-model="registerForm.code" placeholder="请输入验证码" class="input code-input"
placeholder-class="placeholder" />
<image :src="codeUrl" class="code-image" mode="aspectFit" @tap="getCode" />
</view>
<!-- 注册按钮 -->
<button :loading="loading" :disabled="loading" class="register-btn" @tap="handleRegister">
{{ loading ? '注册中...' : '立即注册' }}
</button>
<!-- 已有账号,去登录 -->
<view class="login-link" @tap="goToLogin">
<text>已有账号?去登录</text>
</view>
</view>
</template>
<script>
export default {
data() {
return {
registerForm: {
tenantId: '000000',
username: '',
password: '',
phoneNumber: '',
grantType: 'xcx',
userType: 'sys_user',
code: '',
uuid: '',
clientId: '1400a724f627ddc73d8f4dd344f80a5e',
},
confirmPassword: '',
tenantList: [], // 租户列表
tenantIndex: -1,
loading: false, // 加载状态
codeUrl: '', // 验证码图片
loading: false, // 加载状态
captchaEnabled: true, // 是否启用验证码
}
},
computed: {
// 当前选中的租户
selectedTenant() {
return this.tenantList[this.tenantIndex] || {}
}
},
onLoad() {
// this.getTenantList(),
this.getCode()
},
methods: {
// 获取验证码
async getCode() {
try {
console.log('开始获取验证码...');
const res = await uni.request({
url: 'https://api.buzhiyushu.cn/auth/code',
method: 'GET'
})
console.log('验证码响应:', res);
if (res && res[1] && res[1].data) {
const data = res[1].data
if (!data.data.captchaEnabled) {
this.captchaEnabled = false
return
}
if (data.data.img && data.data.uuid) {
this.codeUrl = 'data:image/gif;base64,' + data.data.img
this.registerForm.uuid = data.data.uuid
} else {
uni.showToast({
title: '获取验证码失败',
icon: 'none'
})
}
} else {
uni.showToast({
title: '获取验证码失败',
icon: 'none'
})
}
} catch (error) {
console.error('获取验证码出错:', error)
uni.showToast({
title: '网络错误,请重试',
icon: 'none'
})
}
},
// 获取租户列表
// async getTenantList() {
// try {
// console.log('开始获取租户列表...');
// const res = await uni.request({
// url: 'http://test.api.buzhiyushu.cn/auth/tenant/list',
// method: 'GET'
// })
// console.log('租户列表响应:', res[1]);
// if (res && res[1] && res[1].data && res[1].data.code === 200) {
// const data = res[1].data.data;
// if (!data.tenantEnabled) {
// this.tenantList = [{
// companyName: '系统未启用多租户模式',
// tenantId: ''
// }];
// return;
// }
// // this.tenantList = data.voList || [{
// // companyName: '请选择租户',
// // tenantId: ''
// // }];
// if (this.tenantList.length > 0) {
// this.tenantIndex = 0;
// this.registerForm.tenantId = this.tenantList[0].tenantId;
// }
// } else {
// const msg = res && res[1] && res[1].data ? res[1].data.msg : '获取租户列表失败';
// uni.showToast({
// title: msg,
// icon: 'none'
// });
// this.tenantList = [{
// companyName: '获取租户列表失败',
// tenantId: ''
// }];
// }
// } catch (error) {
// console.error('获取租户列表出错:', error);
// uni.showToast({
// title: '网络错误,请重试',
// icon: 'none'
// });
// this.tenantList = [];
// }
// },
// // 租户选择变化
// onTenantChange(e) {
// this.tenantIndex = e.detail.value
// this.registerForm.tenantId = this.tenantList[this.tenantIndex].tenantId
// },
// 验证用户名是否已存在
async checkUsername() {
try {
const [err, res] = await uni.request({
url: 'https://api.buzhiyushu.cn/auth/getUserName',
method: 'POST'
});
if (err) {
uni.showToast({
title: '验证用户名失败',
icon: 'none'
});
return false;
}
// 确保响应数据存在且格式正确
if (!res || !res.data) {
uni.showToast({
title: '获取用户数据失败',
icon: 'none'
});
return false;
}
// 确保users是数组类型
const users = Array.isArray(res.data) ? res.data : [];
const isExist = users.some(user => user.userName === this.registerForm.username);
if (isExist) {
uni.showToast({
title: '用户名已存在,请更换',
icon: 'none'
});
return false;
}
return true;
} catch (error) {
console.error('验证用户名出错:', error);
uni.showToast({
title: '验证用户名失败',
icon: 'none'
});
return false;
}
},
// 表单验证
async validateForm() {
// if (!this.registerForm.tenantId) {
// uni.showToast({
// title: '请选择租户',
// icon: 'none'
// })
// return false
// }
if (!this.registerForm.username.trim()) {
uni.showToast({
title: '请输入用户名',
icon: 'none'
})
return false
}
// 验证用户名是否已存在
const usernameValid = await this.checkUsername();
if (!usernameValid) {
return false;
}
// if (!this.registerForm.phoneNumber.trim()) {
// uni.showToast({
// title: '请输入手机号',
// icon: 'none'
// })
// return false
// }
// 验证手机号格式
// const phoneRegex = /^1[3-9]\d{9}$/
// if (!phoneRegex.test(this.registerForm.phoneNumber)) {
// uni.showToast({
// title: '手机号格式不正确',
// icon: 'none'
// })
// return false
// }
if (!this.registerForm.password) {
uni.showToast({
title: '请输入密码',
icon: 'none'
})
return false
}
if (this.registerForm.password.length < 6) {
uni.showToast({
title: '密码长度不能少于6位',
icon: 'none'
})
return false
}
if (this.registerForm.password !== this.confirmPassword) {
uni.showToast({
title: '两次输入的密码不一致',
icon: 'none'
})
return false
}
return true
},
// 处理注册
async handleRegister() {
if (!this.validateForm()) return
// 先验证用户名是否存在
const usernameValid = await this.checkUsername()
if (!usernameValid) {
return
}
this.loading = true
try {
console.log('开始注册,提交数据:', this.registerForm);
// 使用数组解构获取响应
const [err, res] = await uni.request({
url: 'https://api.buzhiyushu.cn/auth/wxRegister',
method: 'POST',
data: this.registerForm,
header: {
clientId: '1400a724f627ddc73d8f4dd344f80a5e',
isToken: 'false',
isEncrypt: 'false',
repeatSubmit: 'false'
}
})
console.log('完整注册响应:', res);
// 错误处理
if (err || res.statusCode !== 200) {
throw new Error(err?.errMsg || `请求失败 (${res.statusCode})`)
}
// 安全访问响应数据
const responseData = res.data || {}
console.log('处理后的响应数据111:', responseData)
if (responseData.code === 200) {
console.log('注册成功:')
// 显示模态弹窗
uni.showModal({
title: '注册成功',
content: '请到后台进行申请入驻',
showCancel: false,
success: function(res) {
if (res.confirm) {
// 用户点击确定后跳转到登录页
uni.navigateTo({
url: '/pages/login/index'
})
}
}
})
} else {
// 显示具体错误信息
uni.showToast({
title: responseData.msg || `注册失败 (${responseData.code})`,
icon: 'none'
})
this.getCode() // 刷新验证码
}
} catch (error) {
console.error('注册过程异常:', error)
uni.showToast({
title: error.message || '注册请求异常',
icon: 'none'
})
} finally {
this.loading = false
}
},
// 跳转到登录页
goToLogin() {
uni.navigateTo({
url: '/pages/login/index'
})
}
}
}
</script>
<style lang="scss">
.register-container {
padding: 40rpx;
min-height: 100vh;
background: #f8f8f8;
.register-header {
margin-bottom: 60rpx;
text-align: center;
.register-title {
font-size: 48rpx;
font-weight: bold;
color: #333;
margin-bottom: 20rpx;
display: block;
}
.register-subtitle {
font-size: 28rpx;
color: #666;
}
}
.form-item {
margin-bottom: 30rpx;
background: #fff;
border-radius: 12rpx;
padding: 20rpx;
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.1);
.picker {
height: 80rpx;
line-height: 80rpx;
font-size: 32rpx;
}
.input {
height: 80rpx;
font-size: 32rpx;
}
&.code-item {
display: flex;
align-items: center;
.code-input {
flex: 1;
margin-right: 20rpx;
}
.code-image {
width: 200rpx;
height: 80rpx;
}
}
}
.register-btn {
margin-top: 60rpx;
background: #007aff;
color: #fff;
border-radius: 50rpx;
font-size: 34rpx;
}
.login-link {
margin-top: 40rpx;
text-align: center;
font-size: 28rpx;
color: #007aff;
}
.placeholder {
color: #999;
}
}
view,
text,
image,
input {
box-sizing: border-box;
}
</style>