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.

256 lines
5.0 KiB

4 weeks ago
4 weeks ago
  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. console.log('发请求之前的activeTab', activeTab.value)
  74. if (activeTab.value === 'email') {
  75. if (!userEmail.value) {
  76. uni.showToast({
  77. title: '请输入邮箱',
  78. icon: 'none'
  79. })
  80. return
  81. }
  82. } else {
  83. if (!userPhone.value) {
  84. uni.showToast({
  85. title: '请输入手机号',
  86. icon: 'none'
  87. })
  88. return
  89. }
  90. }
  91. if (!verifyCode.value) {
  92. uni.showToast({
  93. title: '请输入验证码',
  94. icon: 'none'
  95. })
  96. return
  97. }
  98. try {
  99. let param;
  100. if (activeTab.value === 'email') {
  101. param = {
  102. loginType: 'EMAIL',
  103. account: userEmail.value,
  104. verifyCode: verifyCode.value
  105. }
  106. } else {
  107. param = {
  108. loginType: 'PHONE',
  109. account: userPhone.value,
  110. verifyCode: verifyCode.value
  111. }
  112. }
  113. const res = await validateCode(param)
  114. console.log('看看参数', param)
  115. console.log('看看结果', res)
  116. // 如果返回成功
  117. if (res.code === 200) {
  118. uni.showToast({
  119. title: '验证成功',
  120. icon: 'success'
  121. })
  122. uni.navigateTo({
  123. url: '../setting/nextPwd'
  124. })
  125. } else {
  126. uni.showToast({
  127. title: res.msg || '验证失败',
  128. icon: 'none'
  129. })
  130. }
  131. } catch (err) {
  132. console.error(err)
  133. uni.showToast({
  134. title: '请求出错',
  135. icon: 'none'
  136. })
  137. }
  138. }
  139. onMounted(() => {
  140. // 获取状态栏高度
  141. iSMT.value = uni.getSystemInfoSync().statusBarHeight;
  142. })
  143. </script>
  144. <style>
  145. .tab {
  146. display: flex;
  147. height: 8vh;
  148. background-color: #fff;
  149. border-bottom: 1rpx solid #eee;
  150. }
  151. .tab-item {
  152. flex: 1;
  153. display: flex;
  154. justify-content: center;
  155. align-items: center;
  156. font-size: 32rpx;
  157. position: relative;
  158. }
  159. .tab-item.active {
  160. color: #000;
  161. font-weight: bold;
  162. }
  163. .tab-item.active::after {
  164. content: '';
  165. position: absolute;
  166. bottom: 0;
  167. left: 50%;
  168. transform: translateX(-50%);
  169. width: 40rpx;
  170. height: 6rpx;
  171. background-color: #000;
  172. /* ????? */
  173. }
  174. .switch-tab {
  175. background-color: #fff;
  176. padding: 0 60rpx;
  177. }
  178. .input-list {
  179. display: flex;
  180. align-items: center;
  181. justify-content: center;
  182. height: 7vh;
  183. border-bottom: 1rpx solid #eee;
  184. }
  185. .input-list image {
  186. width: 40rpx;
  187. height: 40rpx;
  188. margin-right: 20rpx;
  189. }
  190. .input {
  191. flex: 1;
  192. height: 14vh;
  193. font-size: 28rpx;
  194. }
  195. .code-btn {
  196. width: 200rpx;
  197. height: 60rpx;
  198. font-size: 24rpx;
  199. border-radius: 10rpx;
  200. background-color: #eee;
  201. color: #666;
  202. display: flex;
  203. align-items: center;
  204. justify-content: center;
  205. }
  206. .code-btn.disabled {
  207. background-color: #ccc;
  208. color: #999;
  209. }
  210. .btn-area {
  211. height: 8vh;
  212. background-color: white;
  213. padding-top: 120rpx;
  214. }
  215. .next-btn {
  216. width: 610rpx;
  217. height: 85rpx;
  218. background-color: #000;
  219. color: #fff;
  220. font-size: 30rpx;
  221. border-radius: 40rpx;
  222. display: flex;
  223. align-items: center;
  224. justify-content: center;
  225. }
  226. </style>