You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

244 lines
4.8 KiB

  1. <template>
  2. <view class="main">
  3. <view :style="{height:iSMT+'px'}"></view>
  4. <view class="tab">
  5. <view class="tab-item" :class="{active: activeTab === 'email'}" @click="activeTab = 'email'">邮箱</view>
  6. <view class="tab-item" :class="{active: activeTab === 'phone'}" @click="activeTab = 'phone'">手机号</view>
  7. </view>
  8. <view class="switch-tab">
  9. <view class="input-list" v-if="activeTab === 'email'">
  10. <image src="/static/my/changeEmail.png" mode="aspectFit"></image>
  11. <input type="text" placeholder="请输入邮箱" class="input" v-model="userEmail" />
  12. <button class="code-btn" :class="{disabled: gettingCode}" @click="getCode" :disabled="gettingCode">
  13. {{ gettingCode ? `重新发送 ${time}s` : '获取验证码' }}
  14. </button>
  15. </view>
  16. <view class="input-list" v-else>
  17. <image src="/static/my/changeBindPhone.png" mode="aspectFit"></image>
  18. <input type="number" placeholder="请输入手机号" class="input" v-model="userPhone" />
  19. <button class="code-btn" :class="{disabled: gettingCode}" @click="getCode" :disabled="gettingCode">
  20. {{ gettingCode ? `重新发送 ${time}s` : '获取验证码' }}
  21. </button>
  22. </view>
  23. <view class="input-list">
  24. <image src="/static/my/verification.png" mode="aspectFit"></image>
  25. <input type="text" placeholder="请输入验证码" class="input" v-model="verifyCode" />
  26. </view>
  27. </view>
  28. <view class="btn-area">
  29. <button class="next-btn" @click="goToPwdNext">下一步</button>
  30. </view>
  31. </view>
  32. </template>
  33. <script setup>
  34. import {
  35. ref,
  36. onMounted
  37. } from 'vue'
  38. import {
  39. sendEmail,
  40. validateCode,
  41. sendPhone
  42. } from "@/api/setting/password";
  43. const iSMT = ref(0)
  44. const activeTab = ref('email')
  45. const gettingCode = ref(false)
  46. const time = ref(60)
  47. const userEmail = ref('')
  48. const userPhone = ref('')
  49. const verifyCode = ref('')
  50. const getCode = () => {
  51. if (gettingCode.value) return
  52. gettingCode.value = true
  53. time.value = 2
  54. const timer = setInterval(() => {
  55. time.value--
  56. if (time.value <= 0) {
  57. clearInterval(timer)
  58. gettingCode.value = false
  59. time.value = 2
  60. }
  61. }, 1000)
  62. if (activeTab.value === 'email') {
  63. sendEmail({
  64. email: userEmail.value
  65. })
  66. } else {
  67. sendPhone({
  68. phone: userPhone.value
  69. })
  70. }
  71. }
  72. const goToPwdNext = async () => {
  73. if (!userEmail.value) {
  74. uni.showToast({
  75. title: '请输入邮箱',
  76. icon: 'none'
  77. })
  78. return
  79. }
  80. if (!verifyCode.value) {
  81. uni.showToast({
  82. title: '请输入验证码',
  83. icon: 'none'
  84. })
  85. return
  86. }
  87. try {
  88. let param;
  89. if (activeTab.value === 'email') {
  90. param = {
  91. loginType: 'EMAIL',
  92. account: userEmail.value,
  93. verifyCode: verifyCode.value
  94. }
  95. } else {
  96. param = {
  97. loginType: 'PHONE',
  98. account: userPhone.value,
  99. verifyCode: verifyCode.value
  100. }
  101. }
  102. const res = await validateCode(param)
  103. console.log('看看参数', param)
  104. console.log('看看结果', res)
  105. // 如果返回成功
  106. if (res.code === 200) {
  107. uni.showToast({
  108. title: '验证成功',
  109. icon: 'success'
  110. })
  111. uni.navigateTo({
  112. url: '../setting/nextPwd'
  113. })
  114. } else {
  115. uni.showToast({
  116. title: res.msg || '验证失败',
  117. icon: 'none'
  118. })
  119. }
  120. } catch (err) {
  121. console.error(err)
  122. uni.showToast({
  123. title: '请求出错',
  124. icon: 'none'
  125. })
  126. }
  127. }
  128. onMounted(() => {
  129. // 获取状态栏高度
  130. iSMT.value = uni.getSystemInfoSync().statusBarHeight;
  131. })
  132. </script>
  133. <style>
  134. .tab {
  135. display: flex;
  136. height: 8vh;
  137. background-color: #fff;
  138. border-bottom: 1rpx solid #eee;
  139. }
  140. .tab-item {
  141. flex: 1;
  142. display: flex;
  143. justify-content: center;
  144. align-items: center;
  145. font-size: 32rpx;
  146. position: relative;
  147. }
  148. .tab-item.active {
  149. color: #000;
  150. font-weight: bold;
  151. }
  152. .tab-item.active::after {
  153. content: '';
  154. position: absolute;
  155. bottom: 0;
  156. left: 50%;
  157. transform: translateX(-50%);
  158. width: 40rpx;
  159. height: 6rpx;
  160. background-color: #000;
  161. /* ????? */
  162. }
  163. .switch-tab {
  164. background-color: #fff;
  165. padding: 0 60rpx;
  166. }
  167. .input-list {
  168. display: flex;
  169. align-items: center;
  170. justify-content: center;
  171. height: 7vh;
  172. border-bottom: 1rpx solid #eee;
  173. }
  174. .input-list image {
  175. width: 40rpx;
  176. height: 40rpx;
  177. margin-right: 20rpx;
  178. }
  179. .input {
  180. flex: 1;
  181. height: 14vh;
  182. font-size: 28rpx;
  183. }
  184. .code-btn {
  185. width: 200rpx;
  186. height: 60rpx;
  187. font-size: 24rpx;
  188. border-radius: 10rpx;
  189. background-color: #eee;
  190. color: #666;
  191. display: flex;
  192. align-items: center;
  193. justify-content: center;
  194. }
  195. .code-btn.disabled {
  196. background-color: #ccc;
  197. color: #999;
  198. }
  199. .btn-area {
  200. height: 8vh;
  201. background-color: white;
  202. padding-top: 120rpx;
  203. }
  204. .next-btn {
  205. width: 610rpx;
  206. height: 85rpx;
  207. background-color: #000;
  208. color: #fff;
  209. font-size: 30rpx;
  210. border-radius: 40rpx;
  211. display: flex;
  212. align-items: center;
  213. justify-content: center;
  214. }
  215. </style>