| | |
| | | </template> |
| | | |
| | | <script setup lang="ts"> |
| | | import { ref, onMounted, onUnmounted } from 'vue'; |
| | | import { onLoad } from '@dcloudio/uni-app' |
| | | import { onMounted, onUnmounted, ref } from 'vue' |
| | | import { sendSettingsPhoneCode, updateSettingsPhone } from '../settings/service.js' |
| | | import { cacheSettingsProfile, isSuccessResponse } from '../settings/utils.js' |
| | | |
| | | const statusBarHeight = ref(20); |
| | | const oldPhone = ref(''); |
| | | const newPhone = ref(''); |
| | | const code = ref(''); |
| | | const countdown = ref(0); |
| | | let timer: any = null; |
| | | const statusBarHeight = ref(20) |
| | | const oldPhone = ref('') |
| | | const newPhone = ref('') |
| | | const code = ref('') |
| | | const countdown = ref(0) |
| | | let timer: ReturnType<typeof setInterval> | null = null |
| | | |
| | | onMounted(() => { |
| | | const systemInfo = uni.getSystemInfoSync(); |
| | | statusBarHeight.value = systemInfo.statusBarHeight || 20; |
| | | }); |
| | | /** |
| | | * 页面加载时回显当前手机号。 |
| | | */ |
| | | onLoad((options) => { |
| | | oldPhone.value = typeof options?.phone === 'string' ? decodeURIComponent(options.phone) : '' |
| | | }) |
| | | |
| | | onUnmounted(() => { |
| | | if (timer) { |
| | | clearInterval(timer); |
| | | timer = null; |
| | | } |
| | | }); |
| | | /** |
| | | * 初始化状态栏高度。 |
| | | */ |
| | | onMounted(() => { |
| | | const systemInfo = uni.getSystemInfoSync() |
| | | statusBarHeight.value = systemInfo.statusBarHeight || 20 |
| | | }) |
| | | |
| | | const goBack = () => { |
| | | uni.navigateBack(); |
| | | }; |
| | | /** |
| | | * 页面销毁时清理倒计时。 |
| | | */ |
| | | onUnmounted(() => { |
| | | clearCountdown() |
| | | }) |
| | | |
| | | const getCode = () => { |
| | | if (countdown.value > 0) return; |
| | | |
| | | if (!newPhone.value || newPhone.value.length !== 11) { |
| | | uni.showToast({ |
| | | title: '请输入正确的新手机号', |
| | | icon: 'none' |
| | | }); |
| | | return; |
| | | } |
| | | /** |
| | | * 返回上一页。 |
| | | */ |
| | | function goBack() { |
| | | uni.navigateBack() |
| | | } |
| | | |
| | | /** |
| | | * 发送新手机号验证码。 |
| | | */ |
| | | async function getCode() { |
| | | if (countdown.value > 0) { |
| | | return |
| | | } |
| | | const normalizedNewPhone = normalizePhone(newPhone.value, '请输入正确的新手机号') |
| | | if (!normalizedNewPhone) { |
| | | return |
| | | } |
| | | const response = await sendSettingsPhoneCode({ |
| | | newPhone: normalizedNewPhone, |
| | | }) |
| | | if (!isSuccessResponse(response)) { |
| | | return |
| | | } |
| | | uni.showToast({ |
| | | title: '验证码已发送', |
| | | icon: 'success', |
| | | }) |
| | | startCountdown() |
| | | } |
| | | |
| | | /** |
| | | * 提交修改手机号。 |
| | | */ |
| | | async function handleSubmit() { |
| | | const normalizedOldPhone = normalizePhone(oldPhone.value, '请输入正确的旧手机号') |
| | | if (!normalizedOldPhone) { |
| | | return |
| | | } |
| | | const normalizedNewPhone = normalizePhone(newPhone.value, '请输入正确的新手机号') |
| | | if (!normalizedNewPhone) { |
| | | return |
| | | } |
| | | if (!code.value.trim()) { |
| | | uni.showToast({ |
| | | title: '验证码已发送', |
| | | icon: 'success' |
| | | }); |
| | | |
| | | countdown.value = 60; |
| | | timer = setInterval(() => { |
| | | if (countdown.value > 0) { |
| | | countdown.value--; |
| | | } else { |
| | | clearInterval(timer); |
| | | timer = null; |
| | | } |
| | | }, 1000); |
| | | }; |
| | | |
| | | const handleSubmit = () => { |
| | | if (!oldPhone.value || oldPhone.value.length !== 11) { |
| | | uni.showToast({ |
| | | title: '请输入正确的旧手机号', |
| | | icon: 'none' |
| | | }); |
| | | return; |
| | | title: '请输入验证码', |
| | | icon: 'none', |
| | | }) |
| | | return |
| | | } |
| | | uni.showLoading({ |
| | | title: '修改中...', |
| | | }) |
| | | try { |
| | | const response = await updateSettingsPhone({ |
| | | oldPhone: normalizedOldPhone, |
| | | newPhone: normalizedNewPhone, |
| | | code: code.value.trim(), |
| | | }) |
| | | if (!isSuccessResponse(response)) { |
| | | return |
| | | } |
| | | if (!newPhone.value || newPhone.value.length !== 11) { |
| | | uni.showToast({ |
| | | title: '请输入正确的新手机号', |
| | | icon: 'none' |
| | | }); |
| | | return; |
| | | } |
| | | if (!code.value) { |
| | | uni.showToast({ |
| | | title: '请输入验证码', |
| | | icon: 'none' |
| | | }); |
| | | return; |
| | | } |
| | | |
| | | uni.showLoading({ |
| | | title: '修改中...' |
| | | }); |
| | | |
| | | // 模拟修改接口 |
| | | cacheSettingsProfile(response.data) |
| | | uni.showToast({ |
| | | title: '修改成功', |
| | | icon: 'success', |
| | | }) |
| | | setTimeout(() => { |
| | | uni.hideLoading(); |
| | | uni.showToast({ |
| | | title: '修改成功', |
| | | icon: 'success' |
| | | }); |
| | | setTimeout(() => { |
| | | uni.navigateBack(); |
| | | }, 1500); |
| | | }, 1000); |
| | | }; |
| | | uni.navigateBack() |
| | | }, 400) |
| | | } finally { |
| | | uni.hideLoading() |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 校验手机号格式。 |
| | | */ |
| | | function normalizePhone(value: string, message: string) { |
| | | const normalized = (value || '').trim() |
| | | if (!/^1\d{10}$/.test(normalized)) { |
| | | uni.showToast({ |
| | | title: message, |
| | | icon: 'none', |
| | | }) |
| | | return '' |
| | | } |
| | | return normalized |
| | | } |
| | | |
| | | /** |
| | | * 开始验证码倒计时。 |
| | | */ |
| | | function startCountdown() { |
| | | clearCountdown() |
| | | countdown.value = 60 |
| | | timer = setInterval(() => { |
| | | if (countdown.value <= 1) { |
| | | clearCountdown() |
| | | return |
| | | } |
| | | countdown.value -= 1 |
| | | }, 1000) |
| | | } |
| | | |
| | | /** |
| | | * 清理验证码倒计时。 |
| | | */ |
| | | function clearCountdown() { |
| | | if (!timer) { |
| | | return |
| | | } |
| | | clearInterval(timer) |
| | | timer = null |
| | | countdown.value = 0 |
| | | } |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |