form-club-register.vue 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. <template>
  2. <div class="club-register">
  3. <el-form :model="formData" :rules="rules" ref="form" label-width="0">
  4. <el-form-item prop="mobile">
  5. <el-input
  6. type="text"
  7. v-model="formData.mobile"
  8. placeholder="手机号"
  9. @blur="onMobileBlur"
  10. maxlength="11"
  11. @input="handleMobileInput"
  12. ></el-input>
  13. </el-form-item>
  14. <el-form-item prop="verifyCode">
  15. <div class="verifyCode flex justify-between">
  16. <el-input
  17. v-model="formData.verifyCode"
  18. placeholder="验证码"
  19. maxlength="6"
  20. @input="handleVerifyCodeInput"
  21. ></el-input>
  22. <div class="send ml-8" @click="onSend">{{ sendCodeBtnText }}</div>
  23. </div>
  24. </el-form-item>
  25. <el-form-item prop="password">
  26. <el-input
  27. type="password"
  28. v-model="formData.password"
  29. placeholder="密码"
  30. maxlength="12"
  31. show-word-limit
  32. show-password
  33. ></el-input>
  34. </el-form-item>
  35. <el-form-item prop="confirmPwd">
  36. <el-input
  37. type="password"
  38. v-model="formData.confirmPwd"
  39. placeholder="再次输入密码"
  40. maxlength="12"
  41. show-word-limit
  42. show-password
  43. ></el-input>
  44. </el-form-item>
  45. </el-form>
  46. <SimpleDialog
  47. v-model="active"
  48. @confirm="onConfirm"
  49. @cancel="onCancel"
  50. confirmText="去登录"
  51. description="抱歉,该手机号已注册,您可以登录后再来进行正品授权申请!"
  52. :center="true"
  53. />
  54. </div>
  55. </template>
  56. <script>
  57. import { mapGetters } from 'vuex'
  58. import { isMobile } from '@/utils/validator'
  59. export default {
  60. data() {
  61. const confirmPwdValide = (rule, value, callback) => {
  62. if (this.formData.password !== value) {
  63. callback(new Error('两次输入的密码不一致'))
  64. } else {
  65. callback()
  66. }
  67. }
  68. const mobileValidate = (rule, value, callback) => {
  69. if (!isMobile(value)) {
  70. callback(new Error('手机号格式不正确'))
  71. } else {
  72. callback()
  73. }
  74. }
  75. return {
  76. formData: {
  77. mobile: '',
  78. verifyCode: '',
  79. password: '',
  80. confirmPwd: '',
  81. },
  82. registerStatus: true, // 能否注册
  83. sendStatus: 0,
  84. active: false,
  85. rules: {
  86. mobile: [
  87. { required: true, message: '手机号不能为空', trigger: ['blur'] },
  88. { validator: mobileValidate, trigger: ['blur'] },
  89. ],
  90. verifyCode: [
  91. { required: true, message: '验证码不能为空', trigger: ['blur'] },
  92. ],
  93. password: [
  94. { required: true, message: '密码不能为空', trigger: ['blur'] },
  95. { min: 8, max: 12, message: '请输入8-12位密码', trigger: ['blur'] },
  96. ],
  97. confirmPwd: [
  98. { required: true, message: '请再次输入密码', trigger: ['blur'] },
  99. { validator: confirmPwdValide, trigger: ['blur'] },
  100. ],
  101. },
  102. }
  103. },
  104. computed: {
  105. ...mapGetters(['authUserId', 'routePrefix', 'accessToken']),
  106. sendCodeBtnText() {
  107. return this.sendStatus === 0
  108. ? '获取验证码'
  109. : `再次发送${this.sendStatus}s`
  110. },
  111. },
  112. methods: {
  113. async onSend() {
  114. if (!this.registerStatus) return (this.active = true)
  115. if (this.sendStatus > 0) return
  116. // 验证手机号是否合法
  117. if (!isMobile(this.formData.mobile)) {
  118. this.$toast('请输入正确的手机号')
  119. return
  120. }
  121. try {
  122. // 发送验证码
  123. await this.$http.api.sendVerifyCode({
  124. mobile: this.formData.mobile,
  125. authUserId: this.authUserId,
  126. type: 1,
  127. })
  128. this.$toast('验证码已发送')
  129. // 开启倒计时
  130. this.countdown()
  131. } catch (error) {
  132. console.log(error)
  133. }
  134. },
  135. // 输入框输入时
  136. handleMobileInput() {
  137. this.formData.mobile = this.formData.mobile.replace(/\D/gi, '')
  138. },
  139. // 输入框输入时
  140. handleVerifyCodeInput() {
  141. this.formData.verifyCode = this.formData.verifyCode.replace(/\D/gi, '')
  142. },
  143. countdown() {
  144. this.sendStatus = 30
  145. this.timer = setInterval(() => {
  146. if (this.sendStatus === 0) {
  147. clearInterval(this.timer)
  148. return
  149. }
  150. this.sendStatus--
  151. }, 1000)
  152. },
  153. onConfirm() {
  154. this.$router.push(`${this.routePrefix}`)
  155. },
  156. onCancel() {
  157. this.active = false
  158. },
  159. onMobileBlur() {
  160. if (isMobile(this.formData.mobile)) {
  161. this.checkouMobileBindClub()
  162. }
  163. },
  164. // 判断用户手机号是否绑定机构
  165. async checkouMobileBindClub() {
  166. try {
  167. const res = await this.$http.api.fetchClubAuthInfo({
  168. authUserId: this.authUserId,
  169. mobile: this.formData.mobile,
  170. })
  171. if (res.data.clubUser) {
  172. this.active = true
  173. this.registerStatus = false
  174. } else {
  175. this.registerStatus = true
  176. }
  177. } catch (error) {
  178. console.log(error)
  179. }
  180. },
  181. genetageFormData() {
  182. return {
  183. mobile: this.formData.mobile,
  184. verifyCode: this.formData.verifyCode,
  185. password: this.formData.password,
  186. }
  187. },
  188. // 表单验证
  189. validate() {
  190. this.$emit('step', this.genetageFormData())
  191. return this.$refs.form.validate()
  192. },
  193. },
  194. }
  195. </script>
  196. <style lang="scss" scoped>
  197. .club-register {
  198. ::v-deep {
  199. .el-input.is-active .el-input__inner,
  200. .el-input__inner:focus {
  201. @include themify($themes) {
  202. border-color: themed('color');
  203. }
  204. }
  205. }
  206. }
  207. .verifyCode {
  208. .send {
  209. cursor: pointer;
  210. white-space: nowrap;
  211. @include themify($themes) {
  212. color: themed('color');
  213. }
  214. }
  215. }
  216. </style>