code.vue 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. <template>
  2. <view class="container-mine">
  3. <uv-navbar title="" placeholder autoBack bgColor="transparent"></uv-navbar>
  4. <view class="top">
  5. <view class="title">输入验证码</view>
  6. <view>我们已向 {{ mobile }} 发送验证码短信</view>
  7. <view>请查看短信并输入验证码</view>
  8. </view>
  9. <view class="body">
  10. <uv-code-input :class="{active1: captcha.length==0, active2: captcha.length==1, active3: captcha.length==2, active4: captcha.length==3}" size="60" focus v-model="captcha" maxlength="4" @finish="finish"></uv-code-input>
  11. <uv-code :seconds="seconds" start-text="重新获取" @end="end" @start="start" ref="uCode" @change="codeChange"></uv-code>
  12. <view class="reset" @tap="getCode">{{ tips }}</view>
  13. </view>
  14. </view>
  15. </template>
  16. <script setup>
  17. import { smsCode, userCaptcha } from '@/api/login';
  18. import { ref, reactive, onMounted } from 'vue';
  19. import { onLoad } from '@dcloudio/uni-app';
  20. const mobile = ref('');
  21. const tips = ref('');
  22. const seconds = ref(60);
  23. const cid = ref(null);
  24. const uCode = ref(null);
  25. const captcha = ref('');
  26. const codeChange = (text) => {
  27. tips.value = text;
  28. };
  29. onLoad((options) => {
  30. if (options && options.mobile) {
  31. mobile.value = options.mobile;
  32. getCode();
  33. }
  34. // #ifdef APP-PLUS
  35. plus.push.getClientInfoAsync((info) => {
  36. let cids = info['clientid'];
  37. // console.log('cid===>', cids);
  38. uni.setStorageSync('cid', cids);
  39. cid.value = cids;
  40. });
  41. // #endif
  42. });
  43. onMounted(() => {
  44. getCode();
  45. });
  46. const getCode = () => {
  47. if (uCode.value && uCode.value.canGetCode) {
  48. // 模拟向后端请求验证码
  49. uni.showLoading({
  50. title: '正在获取验证码'
  51. });
  52. smsCode({ mobile: mobile.value })
  53. .then((res) => {
  54. uni.$uv.toast('验证码已发送');
  55. })
  56. .finally((e) => {
  57. uni.hideLoading();
  58. // 这里此提示会被this.start()方法中的提示覆盖
  59. uCode.value.start();
  60. });
  61. } else {
  62. uni.$uv.toast('倒计时结束后再发送');
  63. }
  64. };
  65. const end = () => { };
  66. const start = () => {
  67. uni.$uv.toast('请输入验证码');
  68. };
  69. const finish = (e) => {
  70. let nickname = '小彩团' + mobile.value.slice(-4);
  71. userCaptcha({
  72. captcha: e,
  73. mobile: mobile.value,
  74. cid: cid.value,
  75. clientType: 4,
  76. nickname: nickname,
  77. gender: 0
  78. }).then((res) => {
  79. if (res && res.code == 200) {
  80. uni.$uv.toast('登录成功');
  81. uni.setStorageSync('apiToken', res.data.token);
  82. uni.switchTab({
  83. url: '/pages/tabtar/home'
  84. });
  85. } else {
  86. uni.$uv.toast('验证码错误');
  87. }
  88. });
  89. };
  90. </script>
  91. <style scoped>
  92. page {
  93. background-color: #f7f8fa;
  94. }
  95. </style>
  96. <style lang="scss" scoped>
  97. ::v-deep .hx-navbar__icon {
  98. color: #303133 !important;
  99. }
  100. ::v-deep .u-char-item {
  101. width: 120rpx !important;
  102. height: 120rpx !important;
  103. background: #ffffff;
  104. border-radius: 20rpx;
  105. border: none !important;
  106. }
  107. ::v-deep.u-box-active {
  108. border: 2rpx solid #56cbda !important;
  109. }
  110. .lgoin-nav {
  111. width: 100%;
  112. background-color: #fff;
  113. position: fixed;
  114. left: 0;
  115. right: 0;
  116. top: 0;
  117. z-index: 0;
  118. }
  119. .top {
  120. text-align: center;
  121. padding: 80rpx 0 150rpx;
  122. font-size: 30rpx;
  123. color: #343434;
  124. .title {
  125. font-size: 60rpx;
  126. margin-bottom: 20rpx;
  127. font-weight: 700;
  128. color: #303030;
  129. }
  130. }
  131. .body {
  132. padding: 0 30rpx;
  133. margin-bottom: 200rpx;
  134. // .uni-input {
  135. // height: 100rpx;
  136. // margin-bottom: 20rpx;
  137. // border-bottom: 1rpx solid #ccc;
  138. // .uni-input-placeholder {
  139. // color: #bebebe;
  140. // }
  141. // }
  142. // .login-btn {
  143. // background-color: #4095e5;
  144. // color: #fff;
  145. // }
  146. // ::v-deep .u-char-box {
  147. // margin-bottom: 20rpx;
  148. // .u-char-flex {
  149. // // justify-content: space-between;
  150. // }
  151. // }
  152. ::v-deep .uv-code-input__item {
  153. background: #ffffff;
  154. border-radius: 20rpx;
  155. border-color: transparent !important;
  156. }
  157. .active1 {
  158. ::v-deep .uv-code-input__item {
  159. &:first-child {
  160. border-color: #eb5153 !important;
  161. }
  162. }
  163. }
  164. .active2 {
  165. ::v-deep .uv-code-input__item {
  166. &:nth-child(2) {
  167. border-color: #eb5153 !important;
  168. }
  169. }
  170. }
  171. .active3 {
  172. ::v-deep .uv-code-input__item {
  173. &:nth-child(3) {
  174. border-color: #eb5153 !important;
  175. }
  176. }
  177. }
  178. .active4 {
  179. ::v-deep .uv-code-input__item {
  180. &:nth-child(4) {
  181. border-color: #eb5153 !important;
  182. }
  183. }
  184. }
  185. .reset {
  186. // max-width: 300rpx;
  187. padding: 10rpx 80rpx 10rpx;
  188. margin-left: auto;
  189. text-align: right;
  190. color: #56cbd9;
  191. // border: 1rpx solid #3775F6;
  192. border-radius: 8rpx;
  193. cursor: pointer;
  194. text-align: center;
  195. color: #eb5153;
  196. }
  197. .uv-code-input {
  198. justify-content: center;
  199. }
  200. }
  201. </style>