setPhone.vue 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. <template>
  2. <!-- 更换手机号 -->
  3. <view class="content">
  4. <view class="form-container">
  5. <!-- 标题 -->
  6. <view class="title">请输入你要更换的新手机号,并进行验证</view>
  7. <!-- 手机号输入框 -->
  8. <view class="input-wrapper">
  9. <view class="input-left">
  10. <text class="country-code">+86</text>
  11. <text class="icon-envelope">✉</text>
  12. </view>
  13. <input v-model="phone" type="number" class="input-field" placeholder="手机号"
  14. placeholder-style="color: #999;" maxlength="11" />
  15. </view>
  16. <!-- 验证码输入框 -->
  17. <view class="input-wrapper">
  18. <input v-model="code" type="number" class="input-field code-input" placeholder="输入验证码"
  19. placeholder-style="color: #999;" maxlength="6" />
  20. <view class="code-btn" :class="{ disabled: countdown > 0 || !canGetCode }" @click="handleGetCode">
  21. {{ countdown > 0 ? `${countdown}秒` : '获取验证码' }}
  22. </view>
  23. </view>
  24. </view>
  25. <!-- 修改按钮 - 固定在底部 -->
  26. <view class="submit-btn-wrapper">
  27. <view class="submit-btn" @click="handleSubmit" hover-class="hover-active">
  28. 修改
  29. </view>
  30. </view>
  31. </view>
  32. </template>
  33. <script setup>
  34. import { ref, computed, onUnmounted } from 'vue';
  35. import { useUserStore } from '@/store/user.js';
  36. import { LoginSendCode } from '@/api/login.js';
  37. import { isPhone } from '@/utils/is.js';
  38. import { go } from '@/utils/utils.js';
  39. const userStore = useUserStore();
  40. // 表单数据
  41. const phone = ref('');
  42. const code = ref('');
  43. const countdown = ref(0);
  44. let countdownTimer = null;
  45. // 是否可以获取验证码
  46. const canGetCode = computed(() => {
  47. return isPhone(phone.value);
  48. });
  49. // 是否可以提交
  50. const canSubmit = computed(() => {
  51. return isPhone(phone.value) && code.value.length >= 4;
  52. });
  53. // 获取验证码
  54. const handleGetCode = async () => {
  55. if (countdown.value > 0 || !canGetCode.value) {
  56. return;
  57. }
  58. try {
  59. const res = await LoginSendCode({
  60. phone: phone.value
  61. });
  62. uni.showToast({
  63. title: '验证码已发送',
  64. icon: 'success'
  65. });
  66. // 开始倒计时
  67. countdown.value = 60;
  68. countdownTimer = setInterval(() => {
  69. countdown.value--;
  70. if (countdown.value <= 0) {
  71. clearInterval(countdownTimer);
  72. countdownTimer = null;
  73. }
  74. }, 1000);
  75. } catch (error) {
  76. console.error('发送验证码失败:', error);
  77. uni.showToast({
  78. title: error?.msg || '发送验证码失败',
  79. icon: 'none'
  80. });
  81. }
  82. };
  83. // 提交修改
  84. const handleSubmit = async () => {
  85. if (!canSubmit.value) {
  86. return;
  87. }
  88. // TODO: 调用修改手机号接口
  89. // 这里需要根据实际API接口来实现
  90. try {
  91. // const res = await UpdatePhone({
  92. // phone: phone.value,
  93. // code: code.value
  94. // });
  95. uni.showToast({
  96. title: '修改成功',
  97. icon: 'success'
  98. });
  99. // 延迟返回上一页
  100. setTimeout(() => {
  101. go(-1);
  102. }, 1500);
  103. } catch (error) {
  104. console.error('修改手机号失败:', error);
  105. uni.showToast({
  106. title: error?.msg || '修改失败,请重试',
  107. icon: 'none'
  108. });
  109. }
  110. };
  111. // 清理定时器
  112. onUnmounted(() => {
  113. if (countdownTimer) {
  114. clearInterval(countdownTimer);
  115. }
  116. });
  117. </script>
  118. <style scoped lang="scss">
  119. .content {
  120. width: 100%;
  121. min-height: 100vh;
  122. background-color: #F5F5F5;
  123. box-sizing: border-box;
  124. padding: 40rpx 30rpx 160rpx;
  125. /* 底部增加空间,避免被固定按钮遮挡 */
  126. position: relative;
  127. }
  128. .form-container {
  129. width: 100%;
  130. }
  131. .title {
  132. font-size: 27rpx;
  133. color: #151515;
  134. font-weight: 400;
  135. margin-bottom: 60rpx;
  136. line-height: 1.5;
  137. }
  138. .input-wrapper {
  139. width: 100%;
  140. height: 88rpx;
  141. background-color: #fff;
  142. border-radius: 16rpx;
  143. display: flex;
  144. align-items: center;
  145. padding: 0 30rpx;
  146. box-sizing: border-box;
  147. margin-bottom: 30rpx;
  148. .input-left {
  149. display: flex;
  150. align-items: center;
  151. gap: 12rpx;
  152. margin-right: 20rpx;
  153. .country-code {
  154. font-size: 28rpx;
  155. color: #333;
  156. font-weight: 400;
  157. }
  158. .icon-envelope {
  159. font-size: 24rpx;
  160. color: #999;
  161. }
  162. }
  163. .input-field {
  164. flex: 1;
  165. font-size: 28rpx;
  166. color: #333;
  167. height: 100%;
  168. }
  169. .code-input {
  170. flex: 1;
  171. }
  172. .code-btn {
  173. font-size: 28rpx;
  174. color: #F47D1F;
  175. padding: 8rpx 20rpx;
  176. margin-left: 20rpx;
  177. cursor: pointer;
  178. white-space: nowrap;
  179. &.disabled {
  180. color: #999;
  181. cursor: not-allowed;
  182. font-size: 27rpx;
  183. color: #151515;
  184. }
  185. }
  186. }
  187. .submit-btn-wrapper {
  188. position: fixed;
  189. bottom: 0;
  190. left: 0;
  191. right: 0;
  192. background-color: #F5F5F5;
  193. padding: 20rpx 30rpx;
  194. padding-bottom: calc(20rpx + constant(safe-area-inset-bottom));
  195. /* iOS 11.2+ */
  196. padding-bottom: calc(20rpx + env(safe-area-inset-bottom));
  197. /* iOS 11.2+ */
  198. box-sizing: border-box;
  199. z-index: 100;
  200. }
  201. .submit-btn {
  202. width: 100%;
  203. height: 88rpx;
  204. background: linear-gradient(35deg, #FCB73F 0%, #FC733D 100%);
  205. border-radius: 23rpx;
  206. display: flex;
  207. align-items: center;
  208. justify-content: center;
  209. font-weight: bold;
  210. font-size: 31rpx;
  211. color: #FFFFFF;
  212. box-shadow: 0rpx 4rpx 12rpx 0rpx rgba(255, 107, 53, 0.3);
  213. }
  214. </style>