<template>
<div class="register-box">
<!-- 用于医生、护士注册 -->
<div class="main">
<div class="cont">
<div class="header">
<p class="header-title">请填写以下注册信息</p>
<p class="header-descripte">以下信息为必填项</p>
</div>
<div class="info">
<ul class="info-list">
<li @click="handleInputFocus('userName')" class="info-item">
<input ref="userName" v-model="userInfo.userName" @blur="handleBlur()" placeholder="请输入姓名" type="text">
</li>
<li @click="handleInputFocus('phone')" class="info-item">
<input ref="phone" v-model.trim="userInfo.phone" @blur="handleBlur()" oninput="this.value=this.value.replace(/\D/g,'')" maxlength="11" placeholder="请输入手机号">
</li>
<li @click="handleInputFocus('captcha')" class="info-item verificate-code">
<input ref="captcha" v-model="userInfo.captcha" @blur="handleBlur()" placeholder="请输入验证码" type="number">
<span v-show="!isShowCount" @click.stop="getCode()" :class="{android: !isIOS(), prohibit: !userInfo.phone || !checkTel(userInfo.phone), disabled: !userInfo.phone || !checkTel(userInfo.phone)}" class="code">{{isFirst ? '获取验证码' : '重新获取'}}</span>
<span v-show="isShowCount" :class="{android: !isIOS()}" class="code disabled">{{this.count}}s</span>
</li>
<li @click="showPicker('area')" v-if="mode === 'doctor' || mode === 'nurse' || mode === 'agency'" class="info-item choose">
<span v-if="!areaText" class="text default">请选择城市</span>
<span v-else class="text">{{areaText}}</span>
</li>
<li @click="handleShowSelectComp()" v-if="mode === 'doctor' || mode === 'nurse'" class="info-item">
<span v-if="!userInfo.hospital" class="text default">请输入医院名称</span>
<span v-else class="text">{{userInfo.hospital}}</span>
</li>
<li @click="showPicker('department')" v-if="mode === 'doctor' || mode === 'nurse'" class="info-item choose">
<span v-if="!userInfo.deptName" class="text default">请选择科室</span>
<span v-else class="text">{{userInfo.deptName}}</span>
</li>
<li @click="showPicker('jobTitle')" v-if="mode === 'doctor' || mode === 'nurse'" class="info-item choose">
<span v-if="!userInfo.jobTitle" class="text default">请选择职称</span>
<span v-else class="text">{{userInfo.jobTitle}}</span>
</li>
<li @click="handleShowSelectComp()" v-if="mode === 'agency'" class="info-item">
<span v-if="!userInfo.organ" class="text default">请输入机构名称</span>
<span v-else class="text">{{userInfo.organ}}</span>
</li>
<li @click="handleInputFocus('jobTitle')" v-if="mode === 'agency'" class="info-item">
<input ref="jobTitle" v-model="userInfo.jobTitle" @blur="handleBlur()" placeholder="请输入职位" type="text">
</li>
<li @click="showPicker('date')" v-if="mode === 'mother'" class="info-item choose">
<span v-if="!userInfo.babyBirthday" class="text default">宝宝出生日期(预产期)</span><span class="text default tip" v-if="!userInfo.babyBirthday">非必填</span>
<span v-if="userInfo.babyBirthday" class="text">{{userInfo.babyBirthday}}</span>
</li>
</ul>
<div class="terms">
<p @click="handleChoose()" :class="{active: isChoose}" class="choose "></p>
<p @click="handleChoose()" class="text">我已阅读并同意<span @click.stop="showTerms()">《注册条款协议》</span></p>
</div>
<div :class="{active: !handleClassName}" @click="submit()" class="btn">注册</div>
</div>
</div>
<div class="bg"></div>
</div>
<van-popup v-model="isShowPicker"
position="bottom">
<!-- 省市区选择 -->
<van-picker
class="picker-wrapper"
:class="{android: !isIOS()}"
v-if="currentPicker === 'area'"
show-toolbar
ref="areaPicker"
:columns="areaOps"
@cancel="cancelSelect"
@confirm="confirmArea" />
<!-- 科室 -->
<van-picker v-if='currentPicker === "department"'
class="picker-wrapper"
:class="{android: !isIOS()}"
show-toolbar
ref="depPicker"
value-key='value'
:columns="depOps"
@cancel="cancelSelect"
@confirm="confirmDep" />
<!-- 职称 -->
<van-picker v-if='currentPicker === "jobTitle"'
class="picker-wrapper"
:class="{android: !isIOS()}"
show-toolbar
ref="jobTitlePicker"
:columns="jobTitleOps"
@cancel="cancelSelect"
@confirm="confirmJobTitle" />
<!-- 时间选择 -->
<van-datetime-picker
v-if="currentPicker === 'date'"
class="date"
v-model="currentDate"
type="date"
:formatter="formatter"
@confirm="confirmDate"
@cancel="cancelSelect"
/>
</van-popup>
<!-- 选择医院/机构组件 -->
<org-select v-if='showSelectComp'
:name="userInfo.hospital || userInfo.organ"
:type='selectType'
@confirm='selectOrg'
@cancel='cancelSelectOrg'>
</org-select>
<!-- 条款 -->
<div v-show="isShowTerms" class="mask terms-mask">
<div class="terms-wrapper">
<div class="header">使用条款</div>
<div class="cont">
<div class="text" v-html='agreeMent'> 1、勾选本协议前选项框并点击“注册”,将视为您签署了本协议,表明您自愿接受本协议全部条款的约束,本协议将构成您与上海佰集科技有限公司及其经营的“简书”平台(以下统称“简书”,包括相关关联方)之间具有约束力的法律文件。无论您是进入简书浏览网页,还是在简书上发布任何内容,或者是直接或通过各类方式(如站外API引用等)间接使用简书网服务和数据的行为,都将被视作已无条件接受本声明所涉全部内容。 2、简书有权利对本协议进行修改,协议修改后,简书将通过在相关页面公告或发送通知等方式公布修改的内容,修改后的协议一经公布即有效的代替原协议。如果您不同意本协议的修改,请立即停止访问或使用本网站或取消已经获得的服务;如果您选择继续访问或使用本网站,则视为您已接受本协议的修改。 作者:简书 链接:https://www.jianshu.com/p/c44d171298ce 来源:简书 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。</div>
</div>
<div @click="isShowTerms = false" class="icon-close"></div>
</div>
</div>
</div>
</template>
<script>
import areaOps from '@/components/picker/area_new2.js'
import { Popup, Picker, DatetimePicker } from 'vant'
import orgSelect from './components/org-select'
export default {
name: 'registerIndex',
components: {
[Popup.name]: Popup,
[Picker.name]: Picker,
[DatetimePicker.name]: DatetimePicker,
orgSelect
},
data () {
return {
isLoading: false, // 提交防抖
/**
* 注册类型
* doctor: 医生
* nurse: 护士
* agency: 母婴服务机构人员
* mother: 妈妈级家庭
* employee: 美德乐员工
* other: 其他
*/
mode: this.$route.query.type,
// 表单信息
userInfo: {
userName: '', // 姓名
phone: '', // 手机号
captcha: '', // 验证码
province: '', // 省
city: '', // 市
hospital: '', // 医院名称
deptName: '', // 科室名称
organ: '', // 机构
jobTitle: '', // 职称
babyBirthday: '' // 宝宝出生日期
},
agreeMent: ``,
// 获取验证码相关
count: 60,
isFirst: true, // 是否是首次获取验证码
isShowCount: false,
timer: null,
start: 0, // 锁频开始的时间
end: 0, // 锁屏结束的时间
vibS: 0, // 用于记录锁屏时间间隔
newS: 0, // 锁屏前倒计时显示的秒数-锁屏时间间隔
// 显示蒙层
isShowPicker: false,
currentPicker: '',
// 省市选择相关
areaText: '',
areaOps: areaOps,
// 医院列表、机构列表相关
selectType: '',
showSelectComp: false,
// 医生科室相关
depOps: ['新生儿科/儿科', '产科', '乳腺科', '儿保科', '产后康复科', '其他科室'],
// 医生职称
jobTitleOps: ['主任医师', '副主任医师', '主治医师', '住院医师', '医师/医士', '主任护师', '副主任护师', '主管护师', '护师/护士', '研究生', '其他'],
// 时间选择相关
currentDate: new Date(), // 日历的当前时间
// 条款相关
isChoose: false,
isShowTerms: false,
scrollY: 0
}
},
computed: {
// 按钮动添高亮
handleClassName () {
let count = 0
if (!this.userInfo.userName) {
count += 1
} else if (!this.userInfo.phone) {
count += 1
} else if (!this.checkTel(this.userInfo.phone)) {
count += 1
} else if (!this.userInfo.captcha) {
count += 1
}
switch (this.mode) {
case 'doctor': // 医生、护士
case 'nurse':
if (!this.userInfo.province || !this.userInfo.city) {
count += 1
} else if (!this.userInfo.hospital) {
count += 1
} else if (!this.userInfo.deptName) {
count += 1
} else if (!this.userInfo.jobTitle) {
count += 1
}
break
case 'agency': // 母婴服务机构人员
if (!this.userInfo.province || !this.userInfo.city) {
count += 1
} else if (!this.userInfo.organ) {
count += 1
}
break
}
return count
}
},
methods: {
submit () {
this.check(() => {
let params = {
userName: this.userInfo.userName,
phone: this.userInfo.phone,
captcha: this.userInfo.captcha
}
switch (this.mode) {
case 'doctor': // 医生
case 'nurse': // 护士
params.province = this.userInfo.province
params.city = this.userInfo.city
params.hospital = this.userInfo.hospital
params.deptName = this.userInfo.deptName
params.jobTitle = this.userInfo.jobTitle
params.userType = 4
if (this.mode === 'doctor') {
params.userType = 4
} else if (this.mode === 'nurse') {
params.userType = 5
}
break
case 'agency': // 母婴服务机构
params.province = this.userInfo.province
params.city = this.userInfo.city
params.organ = this.userInfo.organ
params.jobTitle = this.userInfo.jobTitle || null
params.userType = 6
break
case 'mother': // 妈妈级家庭
params.babyBirthday = this.userInfo.babyBirthday || null
params.userType = 8
break
case 'employee': // 美德乐员工
params.userType = 7
break
case 'other': // 其他
params.userType = 9
break
}
if (this.isLoading) {
return
}
this.isLoading = true
let url = `${this.SERVICE_PORTAL}/${localStorage.getItem('appid')}/user/${localStorage.getItem('openid')}/certification`
this.$posts(url, params).then(res => {
this.isLoading = false
if (res.code === 200) {
this.$toast(res.message)
// 提交成功重新获取粉丝信息
this.getFansInfo()
} else {
this.$toast(res.message)
}
}).catch(() => {
this.isLoading = false
})
})
},
// 获取粉丝信息
getFansInfo () {
let url = `${this.SERVICE_PORTAL}/${localStorage.getItem('appid')}/fans/${localStorage.getItem('openid')}/basice`
let param = {}
this.$get(url, param).then(rsp => {
if (rsp.code === 200) {
if (rsp.data) {
localStorage.setItem('isSubscribe', rsp.data.isSubscribe ? rsp.data.isSubscribe : 0)
localStorage.setItem('fansAvatar', rsp.data.avatar ? rsp.data.avatar : '')
localStorage.setItem('fansNickName', rsp.data.nickName ? rsp.data.nickName : '')
localStorage.setItem('userName', rsp.data.realName ? rsp.data.realName : '')
localStorage.setItem('userType', rsp.data.userType ? rsp.data.userType : -1)
} else {
localStorage.setItem('isSubscribe', 0)
localStorage.setItem('fansAvatar', '')
localStorage.setItem('fansNickName', '')
localStorage.setItem('userName', '')
localStorage.setItem('userType', -1)
}
// 提交成功返回上一页
window.history.go(-1)
}
})
},
// 触发获取验证码
getCode () {
let phone = this.userInfo.phone
if (phone.length === 0 || !this.checkTel(this.userInfo.phone)) {
return this.$toast('请输入正确的手机号')
}
this.isShowCount = true
this.noteVerifyCode()
this.countdown()
},
// 倒计时秒
countdown () {
if (this.count >= 0) {
this.timer = setTimeout(() => {
this.count -= 1
this.countdown()
}, 1000)
} else {
this.isFirst = false
this.isShowCount = false
clearTimeout(this.timer)
this.timer = null
this.count = 60
}
},
// 获取验证码
noteVerifyCode () {
let url = `${this.SERVICE_PORTAL}/${localStorage.getItem('appid')}/user/${this.userInfo.phone}/sendCode`
this.$get(url).then(res => {
if (res.code === 200) {}
})
},
// 选中条款
handleChoose () {
this.isChoose = !this.isChoose
},
// 查看条款
showTerms () {
this.isShowTerms = true
},
// 显示择选择组件
showPicker (type) {
this.currentPicker = type
this.isShowPicker = true
},
// 隐藏选择
cancelSelect () {
this.isShowPicker = false
},
// 确定选择省市
confirmArea (data) {
this.areaText = data.join('-')
this.userInfo.province = data[0] ? data[0] : ''
this.userInfo.city = data[1] ? data[1] : ''
this.isShowPicker = false
},
// 输入医院名称或机构名称
selectOrg (name) {
switch (this.mode) {
case 'doctor':
case 'nurse':
this.userInfo.hospital = name
break
case 'agency':
this.userInfo.organ = name
break
}
this.showSelectComp = false
this.allowScroll()
},
// 取消选择医院 / 机构
cancelSelectOrg () {
this.showSelectComp = false
this.allowScroll()
},
// 确定选择科室
confirmDep (data) {
this.userInfo.deptName = data
this.isShowPicker = false
},
// 确定选择职称
confirmJobTitle (data) {
this.userInfo.jobTitle = data
this.isShowPicker = false
},
// 确定日期选择
confirmDate (val) {
this.userInfo.babyBirthday = this.$options.filters['dateConversion'](val)
this.isShowPicker = false
},
// 校验
check (cb) {
if (!this.userInfo.userName) {
return this.$toast('请输入姓名')
} else if (!this.userInfo.phone) {
return this.$toast('请输入手机号')
} else if (!this.checkTel(this.userInfo.phone)) {
return this.$toast('请输入正确的手机号')
} else if (!this.userInfo.captcha) {
return this.$toast('请输入验证码')
}
switch (this.mode) {
case 'doctor': // 医生
case 'nurse': // 护士
if (!this.userInfo.province || !this.userInfo.city) {
return this.$toast('请选择城市')
} else if (!this.userInfo.hospital) {
return this.$toast('请输入医院名称')
} else if (!this.userInfo.deptName) {
return this.$toast('请选择科室')
} else if (!this.userInfo.jobTitle) {
return this.$toast('请选择职称')
} if (!this.isChoose) {
return this.$toast('请勾选并同意注册协议')
} else {
return cb()
}
case 'agency': // 母婴服务机构人员
if (!this.userInfo.province || !this.userInfo.city) {
return this.$toast('请选择城市')
} else if (!this.userInfo.organ) {
return this.$toast('请输入机构名称')
} else if (!this.isChoose) {
return this.$toast('请勾选并同意注册协议')
} else {
return cb()
}
case 'mother': // 妈妈级家庭
if (!this.isChoose) {
return this.$toast('请勾选并同意注册协议')
} else {
return cb()
}
case 'employee':
case 'other':
if (!this.isChoose) {
return this.$toast('请勾选并同意注册协议')
} else {
return cb()
}
}
},
// 处理时间格式
formatter (type, value) {
switch (type) {
case 'year':
return `${value}年`
case 'month':
return `${value}月`
case 'day':
return `${value}日`
// case 'hour':
// return `${value}时`
// case 'minute':
// return `${value}分`
}
},
handleShowSelectComp () {
this.showSelectComp = true
this.prohibitScroll()
},
// ios 输入框聚焦不灵敏
handleInputFocus (type) {
this.$refs[type].focus()
this.scrollY = window.scrollY
},
// 失焦
handleBlur () {
window.scrollTo(0, this.scrollY)
},
// 禁止滚动
prohibitScroll () {
this.scrollY = window.scrollY
document.body.setAttribute('style', `position:fixed;top:0;height: 100%;width:100%;overflow: hidden;`)
},
// 开启滚动
allowScroll () {
document.body.setAttribute('style', '')
window.scrollTo(0, this.scrollY)
},
// 监听页面隐藏(锁屏)或后台执行时,解决定时器不执行的问题
addVisibilitychange () {
// hidden 为锁屏隐藏状态,visible为重新显示状态
if (document.visibilityState === 'hidden') {
this.start = new Date().getTime()
} else if (document.visibilityState === 'visible') {
this.end = new Date().getTime()
// vibS为锁屏间隔的时间(秒),count为定时器锁屏前显示的秒数
this.vibS = Math.floor((parseInt(this.end) - parseInt(this.start)) / 1000)
this.newS = parseInt(this.count) - this.vibS
if (this.newS > 0) {
// 重新赋值,间隔后的新的定时器时间
this.count = this.newS
} else {
// 已经超出范围,则默认秒数已经读完,恢复原来时间、定时器,显示重发验证码文案
this.isFirst = false
this.isShowCount = false
clearTimeout(this.timer)
this.timer = null
this.count = 60
}
}
}
},
filters: {
dateConversion (val) {
let date = new Date(val)
let year = date.getFullYear()
let month = (date.getMonth() + 1) < 10 ? `0${(date.getMonth() + 1)}` : date.getMonth() + 1
let day = date.getDate() < 10 ? `0${date.getDate()}` : date.getDate()
// let hour = date.getHours() < 10 ? `0${date.getHours()}` : date.getHours()
// let minute = date.getMinutes() < 10 ? `0${date.getMinutes()}` : date.getMinutes()
return `${year}-${month}-${day}`
}
},
mounted () {
document.addEventListener('visibilitychange', this.addVisibilitychange, false)
},
beforeDestroy () {
document.removeEventListener('visibilitychange', this.addVisibilitychange, false)
},
created () {
switch (this.mode) {
case 'doctor':
case 'nurse':
this.selectType = 'hospital'
break
case 'agency':
this.selectType = 'org'
break
}
}
}
</script>
<style lang="stylus" scoped>
::-webkit-input-placeholder /* WebKit browsers */
color #878B8D !important
font-family: 'PingFangSC-Regular', 'PingFang SC';
font-size 16px
:-moz-placeholder /* Mozilla Firefox 4 to 18 */
color #878B8D !important
font-family: 'PingFangSC-Regular', 'PingFang SC';
font-size 16px
::-moz-placeholder /* Mozilla Firefox 19+ */
color #878B8D !important
font-family: 'PingFangSC-Regular', 'PingFang SC';
font-size 16px
:-ms-input-placeholder /* Internet Explorer 10+ */
color #878B8D !important
font-family: 'PingFangSC-Regular', 'PingFang SC';
font-size 16px
.register-box
position relative
width 100vw
height 100vh
.main
width 100%
max-width 750Px
height 100vh
margin 0 auto
background: #F6F6F6;
overflow-y auto
-webkit-overflow-scrolling touch
display flex
flex-direction column
justify-content space-between
.cont
width 100%
.bg
flex none
width 100%
height 74px
background #F6F6F6 url('~assets/img/home_ic_logo1@3x.png') no-repeat center bottom 18px / 93px 18px
.header
width 100%
padded_box(border-box, 30px 30px 25px)
background #F6F6F6
.header-title
height: 28px;
font-size: 20px;
font-family: 'PingFangSC-Medium', 'PingFang SC';
color: #000000;
line-height: 28px;
.header-descripte
height 17px
font-size: 12px;
font-family: 'PingFangSC-Regular', 'PingFang SC';
color: #878B8D;
line-height: 17px;
margin-top 3px
.info
width 100%
background #F6F6F6
.info-list
width 100%
padded_box(border-box, 0 30px)
.info-item
width 100%
padded_box(border-box, 25px 0 10px)
border-bottom 1px solid #EDEDED
font-size 0
&.choose
padded_box(border-box, 25px 34px 10px 0)
background url('~assets/img/login_ic_xiala@3x.png') no-repeat right top 23px / 24px
&.verificate-code
padded_box(border-box, 22px 0 7px)
display flex
align-items center
input
width calc(100% - 96px)
.code
width: 86px;
height: 28px;
line-height 15px
text-align center
background: rgba(255, 199, 0, 0.7);
padded_box(border-box, 6px 0)
border-radius: 4px;
font-size: 13px;
font-family: 'PingFangSC-Regular', 'PingFang SC';
color: #333333;
&.android
padding-top 7px
&.disabled
background:rgba(137,141,141, 0.8);
color #fff
// 禁止点击
&.prohibit
pointer-events: none;
input
width 100%
height 22px
line-height 22px
font-size: 16px;
font-family: 'PingFangSC-Regular', 'PingFang SC';
color: #333333;
.text
font-size: 16px;
font-family: 'PingFangSC-Regular', 'PingFang SC';
color: #333333;
line-height: 22px;
&.default
color: #878B8D;
&.tip
margin-left 24px
.terms
width 100%
padding 0 27px
box-sizing border-box
display flex
align-items center
margin-top 20px
.choose
width: 15px;
height: 15px;
border: 1px solid #898D8D;
border-radius 50%
&.active
position relative
&::after
content ''
display block
width 7px
height 7px
background #898D8D
border-radius 50%
position absolute
top 3px
left 3px
.text
margin-left 4px
line-height: 18px;
font-size: 12px;
font-family: 'PingFangSC-Regular', 'PingFang SC';
color: #666666;
span
color #FFC500
.btn
width: 300px;
height: 45px;
line-height 45px
text-align center
background: #B8B9BB;
border-radius: 4px;
font-size: 16px;
font-family: 'PingFangSC-Medium', 'PingFang SC';
color: #FFFFFF;
margin 60px auto 0
&.active
background #FFC700
color #000
/* 蒙层 */
.mask
width 750px
height 100vh
background rgba(0, 0,0, 0.5)
position fixed
top 0
left 50%
transform translate(-50%, 0)
z-index 1000
// 条款
&.terms-mask
padding-top 156px
box-sizing border-box
.terms-wrapper
width 310px
background #fff
margin 0 auto
border-radius 6px
position relative
padded_box(border-box, 30px 0 0)
.header
width 100%
height 22px
line-height 22px
text-align center
background #fff
border-radius 6px 6px 0px 0px
font-size 18px
font-family 'PingFangSC-Medium', 'PingFang SC'
color #000
.cont
width 100%
height 260px
background #FEFEFE
border-radius 0 0 6px 6px
padded_box(border-box, 18px 15px 16px)
.text
width 100%
height 100%
font-size: 14px;
font-family: 'PingFangSC-Regular', 'PingFang SC';
color: #646363;
line-height: 28px;
overflow-y auto
.icon-close
width 60px
height 60px
background url('~assets/img/popup_bt_delete@3x.png') no-repeat center / 100%
position absolute
left 50%
bottom -82px
transform translate(-50%, 0)
// 地区科室等
.picker-wrapper
&.android
>>> .van-picker-column__item .van-ellipsis
line-height 18px
padding-top 4px
// 日期组件样式
>>> .van-popup--bottom, >>> .van-picker
border-radius 10px 10px 0 0
>>> .van-picker__toolbar button
font-size 16px
>>> .van-picker__confirm
color #FFC700
</style>
获取验证码,倒计时,解决ios手机锁屏后倒计时暂停问题
最后编辑于 :
©著作权归作者所有,转载或内容合作请联系作者
- 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
- 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
- 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
推荐阅读更多精彩内容
- 大家在做验证码的时候一般都会用到倒计时,基本上大家实现的方式都差不多,先贴出一些代码来.. -(void)star...
- 做一朵白莲花吧,在物欲横流的社会底层静静发育,不沾染一点灰尘,慢慢伸出理想的枝干,穿越尔虞我诈的茂密荷叶,...
- 前言: 点击获取验证码倒计时,在项目中很多都会用到,尤其是现在应用App当中手机验证登录,都会用到。本着封装一个倒...
- 缘由 对于做这个封装的目的就是想制造一个简单易用无风险的验证码倒计时控件吧 便于在多个项目使用,网络上也有很多类似...