69 lines
1.5 KiB
TypeScript
69 lines
1.5 KiB
TypeScript
import { onUnmounted, ref } from 'vue'
|
|
import { showToast } from 'vant'
|
|
import { sendSmsCode } from '@/features/auth/api/auth'
|
|
|
|
export function useSmsCountdown() {
|
|
const countDown = ref(0)
|
|
const sending = ref(false)
|
|
let timer: ReturnType<typeof setInterval> | null = null
|
|
|
|
function startCountDown() {
|
|
countDown.value = 60
|
|
timer = setInterval(() => {
|
|
countDown.value--
|
|
if (countDown.value <= 0) {
|
|
clearInterval(timer!)
|
|
timer = null
|
|
}
|
|
}, 1000)
|
|
}
|
|
|
|
onUnmounted(() => {
|
|
if (timer) {
|
|
clearInterval(timer)
|
|
timer = null
|
|
}
|
|
})
|
|
|
|
async function handleSendCode(phone: string) {
|
|
if (!phone.trim()) {
|
|
showToast({ message: '请输入手机号', icon: 'warning-o' })
|
|
return false
|
|
}
|
|
|
|
sending.value = true
|
|
try {
|
|
await sendSmsCode(phone)
|
|
showToast({
|
|
message: '验证码已发送,请注意查收',
|
|
icon: 'passed',
|
|
})
|
|
startCountDown()
|
|
return true
|
|
} catch (error) {
|
|
showToast({
|
|
message: readError(error, '验证码发送失败,请稍后重试'),
|
|
icon: 'cross',
|
|
})
|
|
return false
|
|
} finally {
|
|
sending.value = false
|
|
}
|
|
}
|
|
|
|
function readError(error: unknown, fallback: string) {
|
|
if (typeof error === 'object' && error && 'response' in error) {
|
|
const response = (error as { response?: { data?: { message?: string } } }).response
|
|
return response?.data?.message || fallback
|
|
}
|
|
return fallback
|
|
}
|
|
|
|
return {
|
|
countDown,
|
|
sending,
|
|
handleSendCode,
|
|
readError,
|
|
}
|
|
}
|