exam-h5/pages/register/register.vue

528 lines
16 KiB
Vue
Raw Normal View History

2025-07-16 10:14:15 +08:00
<template>
<view class="app">
2025-07-16 16:01:40 +08:00
<view class="user">
<view class="title">
个人信息
2025-07-16 10:14:15 +08:00
</view>
2025-07-16 16:01:40 +08:00
<view class="item">
<span>姓名</span>
<span class='addition'>
<u-input type="text" placeholder="请输入姓名" v-model="personInfo.realName" />
</span>
</view>
<view class="item">
<span>手机号</span>
<span class='addition'>
<u-input type="text" placeholder="请输入手机号" v-model="personInfo.phone" />
</span>
</view>
<view class="item">
<span>身份证号</span>
<span class='addition'>
<u-input type="text" placeholder="请输入身份证号" v-model="personInfo.userName" />
</span>
</view>
<view class="item">
<span>电子邮箱(用于接收考试通知)</span>
<span class='addition'>
<u-input type="text" placeholder="请输入电子邮箱" v-model="personInfo.email" />
</span>
</view>
<view class="item">
<span>通讯地址</span>
<span class='addition'>
<u-input type="text" placeholder="请输入通讯地址" v-model="personInfo.address" />
</span>
2025-07-16 10:14:15 +08:00
</view>
</view>
2025-07-16 16:01:40 +08:00
<view class="user">
<view class="title">
教育背景
</view>
<view class="item">
<span>最高学历</span>
<span class='addition'>
<u-radio-group v-model="personInfo.education" @change="">
<u-radio @change="" v-for="(item, index) in educationlist" :key="index" :name="item.label"
style="padding: 0 15rpx;" :disabled="item.checked">
{{item.name}}
</u-radio>
</u-radio-group>
</span>
</view>
<view class="item">
<span>毕业院校</span>
<span class='addition'>
<u-input type="text" placeholder="请输入毕业院校" v-model="personInfo.graduateSchool" />
</span>
</view>
<view class="item">
<span>专业(如适用)</span>
<span class='addition'>
<u-input type="text" placeholder="请输入专业" v-model="personInfo.major" />
</span>
2025-07-16 10:14:15 +08:00
</view>
</view>
2025-07-16 16:01:40 +08:00
<view class="user">
<view class="title">
报考信息
</view>
<view class="item">
<span>报考类别(可选)</span>
<span class='addition'>
<u-radio-group v-model="personInfo.regType" @change="">
<u-radio @change="" v-for="(item, index) in regTypelist" :key="index" :name="item.label"
style="padding: 15rpx;" :disabled="item.checked">
{{item.name}}
</u-radio>
</u-radio-group>
</span>
</view>
<view class="item">
<span>培训经历(如有)</span>
<span class='addition'>
<view class="item" style="padding: 10rpx 0;">
<span>机构名称</span>
<span class='addition'>
<u-input type="text" placeholder="请输入机构名称" v-model="personInfo.trainInstitution" />
</span>
</view>
<view class="item" style="padding: 10rpx 0;">
<span>培训时间</span>
<span class='addition' @click="trainDateshow=true"
style="margin-left:50rpx;display: inline-block;padding: 10rpx;background-color: #4C7BC9;border-radius: 10rpx;color: #fff;">
选择时间区间
</span>
<view class="" v-if="personInfo.trainStartDate" style="padding: 16rpx 0;">
{{personInfo.trainStartDate+'至'}}{{personInfo.trainEndDate}}
</view>
</view>
</span>
2025-07-16 10:14:15 +08:00
</view>
</view>
2025-07-16 16:01:40 +08:00
<view class="user">
<view class="title">
上传材料
</view>
<view class="item">
<span>身份证正面</span>
<span class='addition'>
<u-upload :action="action" :form-data="{
type:'cardFrontUrl'
}" :file-list="fileList" :max-count="1" @on-uploaded="uploadedcardFront"></u-upload>
</span>
</view>
<view class="item">
<span>身份证反面</span>
<span class='addition'>
<u-upload :action="action" :form-data="{
type:'cardBackUrl'
}" :file-list="fileList" :max-count="1" @on-uploaded="uploadedcardBack"></u-upload>
</span>
</view>
<view class="item" style="line-height: 50rpx;">
<span>近期白底免冠证件照(1,JPG格式,&lt;20KB)</span>
<span class='addition'>
<u-upload :action="action" :form-data="{
type:'photoUrl'
}" :file-list="fileList" :max-count="1" @on-uploaded="uploadedphoto"></u-upload>
</span>
</view>
<view class="item" style="line-height: 50rpx;">
<span>学历证明(毕业证或学信网截图)</span>
<span class='addition'>
<u-upload :action="action" :form-data="{
type:'certificateUrl'
}" :file-list="fileList" :max-count="1" @on-uploaded="uploadedcertificate"></u-upload>
</span>
2025-07-16 10:14:15 +08:00
</view>
</view>
2025-07-16 16:01:40 +08:00
<view class="user">
<view class="title">
密码
</view>
<view class="item">
<span>密码</span>
<span class='addition'>
<u-input placeholder="请输入密码" v-model="personInfo.password" type="password" :password-icon="true" />
</span>
2025-07-16 10:14:15 +08:00
</view>
2025-07-16 16:01:40 +08:00
<view class="item">
<span>重复密码</span>
<span class='addition'>
<u-input placeholder="请再次输入密码" v-model="personInfo.newpassword" type="password"
:password-icon="true" />
</span>
2025-07-16 10:14:15 +08:00
</view>
2025-07-16 16:01:40 +08:00
<!-- <view class="item">
<view class="lefttext">
验证码
</view>
<input class="righttext" style='left:23%' type="text" placeholder="" maxlength="6" v-model="verification" />
<view class="obtaincode" :style="{'color':getCodeBtnColor}" @click.stop="getCode()">
{{getCodeText}}
</view>
</view> -->
2025-07-16 10:14:15 +08:00
</view>
2025-07-16 16:01:40 +08:00
<view class="priceback">
<view class="queren" @tap='register'>注册</view>
<view class="switch" @tap='gologin'>
已有账号,去登录
</view>
2025-07-16 10:14:15 +08:00
</view>
<u-toast ref="uToast" />
2025-07-16 16:01:40 +08:00
<u-mask :show="signatureshow" @click="signatureshow = false">
<view style="position:absolute;bottom:0;height:900rpx;width:100%;background-color: #fff;"
v-if='signatureshow'>
<signature @userSignaturePictureUrl='userSignaturePicture' @click.native.stop
style='background-color: #F4F5F7;width: 100%;height: 900rpx;'></signature>
</view>
</u-mask>
<u-calendar v-model="trainDateshow" mode="range" @change="trainDatechange"></u-calendar>
<u-toast ref="uToast" />
2025-07-16 10:14:15 +08:00
</view>
</template>
<script>
import {
reg
} from '@/api/register/index.js'
2025-07-16 16:01:40 +08:00
import {
getExamList,
save
} from '@/api/addexam/index.js'
import baseurl from '@/api/baseurl.js'
import signature from '@/components/signature/signature.vue'
2025-07-16 10:14:15 +08:00
export default {
2025-07-16 16:01:40 +08:00
components: {
signature
},
2025-07-16 10:14:15 +08:00
data() {
return {
2025-07-16 16:01:40 +08:00
trainDateshow: false,
signatureshow: false,
userSignaturePictureUrl: null,
examlist: [],
educationlist: [{
name: '初中',
label: 1,
checked: false,
},
{
name: '高中/中专',
label: 2,
checked: false,
},
{
name: '大专及以上',
label: 3,
checked: false,
}
],
regTypelist: [{
name: '普通医疗护理员',
label: 1,
checked: false,
},
{
name: '老年医疗护理员',
label: 2,
checked: false,
},
{
name: '孕产妇和新生儿医疗护理员',
label: 3,
checked: false,
}
],
action: baseurl + '/exam/api/file/upload',
fileList: [],
personInfo: {
password: undefined,
newpassword: undefined,
"address": "",
"cardBack": "",
"cardCopy": "", // 身份证正反面复印件
"cardFront": "",
"certificate": "",
"education": 0,
"email": "",
"examId": "",
startTime: undefined,
endTime: undefined,
startDate: undefined,
endDate: undefined,
"graduateSchool": "",
"major": "",
"phone": "",
"photo": "",
"physicalReport": "", //健康体检报告
"realName": "",
"regTime": "",
"regType": 0,
"signPicture": "",
"title": "",
"trainEndDate": "",
"trainInstitution": "",
"trainStartDate": "",
"userId": "",
"userName": "",
examFee: undefined,
},
2025-07-16 10:14:15 +08:00
verification: '',
getCodeText: '获取验证码', //获取验证码的文字
getCodeBtnColor: "#4C7BC9", //获取验证码的color
getCodeisWaiting: false, //判断是否在倒计时中
};
},
2025-07-16 16:01:40 +08:00
onLoad() {},
2025-07-16 10:14:15 +08:00
methods: {
2025-07-16 16:01:40 +08:00
uploadedcertificate(res) {
this.personInfo.certificate = res[0].response.data.url
},
uploadedphoto(res) {
this.personInfo.photo = res[0].response.data.url
},
uploadedcardBack(res) {
this.personInfo.cardBack = res[0].response.data.url
},
uploadedcardFront(res) {
this.personInfo.cardFront = res[0].response.data.url
},
trainDatechange(e) {
this.personInfo.trainEndDate = e.endDate
this.personInfo.trainStartDate = e.startDate
},
//签名
userSignaturePicture(data) {
let that = this
this.userSignaturePictureUrl = data
this.signatureshow = false
uni.uploadFile({
url: baseurl + '/exam/api/file/upload',
filePath: this.userSignaturePictureUrl,
name: 'file',
formData: {
type: 'signPictureUrl'
},
timeout: 5000,
success(res) {
that.personInfo.signPicture = JSON.parse(res.data).data.url
}
})
},
2025-07-16 10:14:15 +08:00
//注册功能
register() {
2025-07-16 16:01:40 +08:00
if (this.personInfo.password !== this.personInfo.newpassword) {
2025-07-16 10:14:15 +08:00
this.$refs.uToast.show({
title: '密码输入不一致,请重新输入',
type: 'error',
duration: '1500'
})
2025-07-16 16:01:40 +08:00
} else if (!this.validateIDCard(this.personInfo.userName)) {
this.$refs.uToast.show({
title: '身份证错误,请重新输入',
type: 'error',
duration: '1500'
})
} else if (!this.validatePhone(this.personInfo.phone)) {
this.$refs.uToast.show({
title: '手机号错误,请重新输入',
type: 'error',
duration: '1500'
})
2025-07-16 10:14:15 +08:00
} else {
2025-07-16 16:01:40 +08:00
reg(this.personInfo).then(res => {
2025-07-16 10:14:15 +08:00
if (res.code == 0) {
uni.setStorageSync("examh5token", res.data.token)
uni.setStorageSync("examh5user", {
id: res.data.id,
phone: res.data.phone,
name: res.data.realName,
cardNo: res.data.userName
})
this.$refs.uToast.show({
title: '注册成功,前往登录',
type: 'success',
duration: '1500'
})
setTimeout(e => {
uni.reLaunch({
url: `/pages/login/login?phone=${this.patientName}&password=${this.password}`
})
}, 1500)
} else {
this.$refs.uToast.show({
title: res.msg,
type: 'error'
})
}
})
}
},
2025-07-16 16:01:40 +08:00
// 校验手机号的通用方法
validatePhone(phone) {
// 简单的手机号正则匹配11位数字1开头
const reg = /^1[3-9]\d{9}$/;
return reg.test(phone);
},
// 校验身份证号码的通用方法
validateIDCard(idCard) {
// 15位和18位身份证号码的正则表达式
const reg15 = /^[1-9]\d{7}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}$/;
const reg18 = /^[1-9]\d{5}(18|19|20)\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/;
// 校验长度
if (idCard.length === 15) {
return reg15.test(idCard);
} else if (idCard.length === 18) {
// 18位身份证需要校验最后一位校验码
if (reg18.test(idCard)) {
return this.checkIDCardLastCode(idCard);
}
return false;
}
return false;
},
// 校验18位身份证最后一位校验码
checkIDCardLastCode(idCard) {
if (idCard.length !== 18) return false;
// 加权因子
const weight = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
// 校验码
const checkCode = ['1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'];
let sum = 0;
for (let i = 0; i < 17; i++) {
sum += parseInt(idCard[i]) * weight[i];
}
const mod = sum % 11;
return idCard[17].toUpperCase() === checkCode[mod];
},
2025-07-16 10:14:15 +08:00
//跳转登录页
gologin() {
uni.reLaunch({
url: `/pages/login/login`
})
},
//点击获取验证码
getCode() {
uni.hideKeyboard() //隐藏已经显示的软键盘,如果软键盘没有显示则不做任何操作。
if (this.getCodeisWaiting) { //是否在倒计时中
return;
}
if (!(/^1(3|4|5|6|7|8|9)\d{9}$/.test(this.phone))) { //校验手机号码是否有误
uni.showToast({
title: '请填写正确手机号码',
icon: "none"
});
return false;
}
this.getCodeText = "发送中..." //发送验证码
this.getCodeisWaiting = true;
this.getCodeBtnColor = "rgba(138,139,133,1)" //追加样式,修改颜色
//示例用定时器模拟请求效果
//setTimeout(()用于在指定的毫秒数后调用函数或计算表达式
setTimeout(() => {
uni.showToast({
title: '验证码已发送',
icon: "none"
}); //弹出提示框
// this.code = '1234'; //发送验证码,进行填入 示例默认1234生产中请删除这一句。
this.setTimer(); //调用定时器方法
}, 1000)
},
//获取验证码的倒计时 setTimer 需要每隔一段时间执行一件事的的时候就需要使用SetTimer函数
setTimer() {
let holdTime = 60; //定义变量并赋值
this.getCodeText = "重新获取(60)"
//setInterval是一个实现定时调用的函数可按照指定的周期以毫秒计来调用函数或计算表达式。
//setInterval方法会不停地调用函数直到 clearInterval被调用或窗口被关闭。
this.Timer = setInterval(() => {
if (holdTime <= 0) {
this.getCodeisWaiting = false;
this.getCodeBtnColor = "#4C7BC9";
this.getCodeText = "获取验证码"
clearInterval(this.Timer); //清除该函数
return; //返回前面
}
this.getCodeText = "重新获取(" + holdTime + ")"
holdTime--;
}, 1000)
},
doReg() {
// uni.hideKeyboard() //隐藏已经显示的软键盘,如果软键盘没有显示则不做任何操作。
// //模板示例部分验证规则
// if (!(/^1(3|4|5|6|7|8|9)\d{9}$/.test(this.phoneNumber))) { //校验手机号码
// uni.showToast({
// title: '请填写正确手机号码',
// icon: "none"
// });
// return false;
// }
// //示例验证码,实际使用中应为请求服务器比对验证码是否正确。
// if (this.code != 1234) {
// uni.showToast({
// title: '验证码不正确',
// icon: "none"
// });
// return false;
// }
// uni.showLoading({
// title: '提交中...'
// })
// //模板示例把用户注册信息储存在本地,实际使用中请替换为上传服务器。
// setTimeout(() => {
// uni.getStorage({
// key: 'UserList',
// success: (res) => {
// //增加记录密码md5
// res.data.push({
// username: this.phoneNumber,
// passwd: md5(this.passwd)
// })
// uni.setStorage({
// key: 'UserList',
// data: res.data,
// success: function() {
// uni.hideLoading()
// uni.showToast({
// title: '注册成功',
// icon: "success"
// });
// setTimeout(function() {
// uni.navigateBack();
// }, 1000)
// }
// });
// },
// fail: (e) => {
// uni.hideLoading()
// //新建UserList
// uni.setStorage({
// key: 'UserList',
// data: [{
// username: this.phoneNumber,
// passwd: md5(this.passwd)
// }],
// success: function() {
// uni.hideLoading()
// uni.showToast({
// title: '注册成功',
// icon: "success"
// });
// setTimeout(function() {
// uni.navigateBack();
// }, 1000)
// },
// fail: function(e) {
// }
// });
// }
// });
// }, 1000)
},
},
}
</script>
<style lang="scss">
@import "./register.scss";
</style>