field-image-code.vue 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. <template>
  2. <div class="filed">
  3. <van-field
  4. placeholder="请输入短信验证码"
  5. :rules="[{ validator: validatorVerification, message: '请输入6位数验证码' }]"
  6. type="digit"
  7. :left-icon="!leftIcon ? 'https://static.caimei365.com/app/mini-distribution/email.png' : ''"
  8. maxlength="6"
  9. v-model="code"
  10. @input="$emit('handlerCode', code)"
  11. >
  12. <template #button>
  13. <van-button
  14. size="small"
  15. type="primary"
  16. color="#FF5B00"
  17. @click.stop="fetchVerification"
  18. :disabled="showTime"
  19. >{{ showTime ? `${count} S` : '获取验证码' }}</van-button
  20. >
  21. </template>
  22. </van-field>
  23. <van-dialog v-model="showImageCode" title="获取验证码">
  24. <van-form @submit="submitCode">
  25. <van-field
  26. v-model="imgCode"
  27. class="img-code"
  28. placeholder="请输入图片验证码"
  29. :rules="[{ validator: validatorImgCode }]"
  30. maxlength="4"
  31. />
  32. <div class="img-refresh">
  33. <van-image :src="dataImage.baseImage"></van-image>
  34. <div class="refresh" @click="fetchVerification">刷新</div>
  35. </div>
  36. <van-button
  37. class="get-code"
  38. color="#ff5b00"
  39. native-type="submit"
  40. >获取验证码</van-button
  41. >
  42. </van-form>
  43. </van-dialog>
  44. </div>
  45. </template>
  46. <script>
  47. import { Toast } from 'vant'
  48. import {
  49. getCode,
  50. getImageCode,
  51. getSmsCode
  52. } from '@/api/userApi/login.js'
  53. export default {
  54. props: {
  55. mobile: {
  56. type: String,
  57. default: () => ''
  58. },
  59. leftIcon: {
  60. type: Boolean,
  61. default: () => true
  62. },
  63. type: {
  64. type: Number,
  65. default: () => 14
  66. }
  67. },
  68. data () {
  69. return {
  70. code: '',
  71. showImageCode: false,
  72. imgCode: '',
  73. dataImage: {},
  74. showTime: false,
  75. time: null,
  76. count: 60
  77. }
  78. },
  79. methods: {
  80. validatorVerification (val) {
  81. if (this.mobile && this.code) {
  82. return /\d{6}/.test(val)
  83. }
  84. },
  85. fetchVerification () {
  86. getCode({ mobile: this.mobile }).then(() => {
  87. this.showImageCode = true
  88. getImageCode({ platformType: 1 }).then((data) => {
  89. this.dataImage = data
  90. setTimeout(() => {
  91. Toast.clear()
  92. }, 1000)
  93. }).catch(e => {
  94. console.log(e)
  95. })
  96. })
  97. },
  98. validatorImgCode (val) {
  99. if (!val) return false
  100. else if (this.errMsg) return this.errMsg
  101. },
  102. handlerCodeTime () {
  103. this.showTime = true
  104. this.time = setInterval(() => {
  105. this.count--
  106. if (this.count <= 0) {
  107. clearInterval(this.time)
  108. this.showTime = false
  109. this.count = 60
  110. this.imgCode = ''
  111. }
  112. }, 1000)
  113. },
  114. submitCode () {
  115. getSmsCode({
  116. mobile: this.mobile,
  117. token: this.dataImage.token,
  118. imgCode: this.imgCode,
  119. platformType: 1,
  120. isCheckCaptcha: 0,
  121. activateCodeType: this.type
  122. }).then(() => {
  123. this.errMsg = ''
  124. this.showImageCode = false
  125. this.handlerCodeTime()
  126. }).catch(() => {
  127. this.errMsg = '验证码输入错误'
  128. getImageCode({ platformType: 1 }).then((data) => {
  129. this.dataImage = data
  130. setTimeout(() => {
  131. Toast.fail('验证码输入错误')
  132. }, 1000)
  133. })
  134. })
  135. }
  136. }
  137. }
  138. </script>
  139. <style lang="scss" scoped>
  140. ::v-deep .van-dialog__footer {
  141. display: none;
  142. }
  143. ::v-deep .van-dialog__content {
  144. padding: 3.5vw 4vw;
  145. box-sizing: border-box;
  146. }
  147. .filed {
  148. position: relative;
  149. &::after {
  150. position: absolute;
  151. box-sizing: border-box;
  152. content: ' ';
  153. pointer-events: none;
  154. right: 16px;
  155. bottom: 0;
  156. left: 16px;
  157. border-bottom: 1px solid #ebedf0;
  158. -webkit-transform: scaleY(.5);
  159. transform: scaleY(.5);
  160. }
  161. }
  162. .img-refresh {
  163. width: 100%;
  164. margin: 2.7vw 0;
  165. display: flex;
  166. align-items: center;
  167. justify-content: space-between;
  168. .van-image {
  169. height: 12vw;
  170. width: 50vw;
  171. object-fit: cover;
  172. }
  173. .refresh {
  174. width: 20vw;
  175. line-height: 12vw;
  176. text-align: center;
  177. font-size: 3.4vw;
  178. color: #ccc;
  179. }
  180. }
  181. .get-code {
  182. width: 100% !important;
  183. height: 10vw !important;
  184. }
  185. .img-code {
  186. border: 1px solid #ccc;
  187. }
  188. </style>