88 lines
2.3 KiB
JavaScript
88 lines
2.3 KiB
JavaScript
/** 邮件/手机验证码发送:复用人机验证,成功后倒计时,组件销毁清理定时器。 */
|
|
import { onScopeDispose } from "vue";
|
|
import { ref } from "vue";
|
|
import { useApi } from "~/lib/auth.js";
|
|
import { t as interval_t } from "~/lib/interval.js";
|
|
function i(i) {
|
|
let a = useApi(),
|
|
o = ref(!1),
|
|
s = ref(0),
|
|
c = null,
|
|
l = !1;
|
|
function u() {
|
|
c &&= (clearInterval(c), null);
|
|
}
|
|
// 默认为 60 秒;重复启动先清旧定时器,防止多次递减造成提前结束。
|
|
function d() {
|
|
l ||
|
|
(u(),
|
|
(s.value = i.seconds ?? 60),
|
|
(c = interval_t(() => {
|
|
(--s.value, s.value <= 0 && u());
|
|
}, 1e3)));
|
|
}
|
|
onScopeDispose(() => {
|
|
((l = !0), u());
|
|
});
|
|
/** e 为 email 或手机场景,t 为收件账号,n 为账号缺失提示;发送中/倒计时中直接忽略。 */
|
|
async function f(e, t, n) {
|
|
if (l || o.value || s.value > 0) return;
|
|
if (((i.error.value = ``), !t)) {
|
|
i.error.value = n;
|
|
return;
|
|
}
|
|
let r = i.captcha.validationError();
|
|
if (r) {
|
|
i.error.value = r;
|
|
return;
|
|
}
|
|
o.value = !0;
|
|
try {
|
|
let n = {
|
|
action: i.action,
|
|
captcha: i.captcha.value.value.trim(),
|
|
token: i.captcha.token.value,
|
|
};
|
|
if (e === `email`)
|
|
await a.post(`/email/code`, {
|
|
...n,
|
|
email: t,
|
|
});
|
|
else {
|
|
let e = String(
|
|
typeof i.phoneCode == `function`
|
|
? i.phoneCode()
|
|
: (i.phoneCode ?? 86),
|
|
).trim();
|
|
if (!/^[1-9]\d{0,3}$/.test(e)) throw Error(`请输入有效的国际电话区号`);
|
|
await a.post(`/phone/code`, {
|
|
...n,
|
|
phone_code: Number(e),
|
|
phone: t,
|
|
});
|
|
}
|
|
// 发送成功才开始倒计时;已消费的人机验证失效/刷新,不能在下一次发送时复用。
|
|
(d(),
|
|
!l &&
|
|
i.captcha.needed.value &&
|
|
(i.captcha.provider.value === `geetest`
|
|
? i.captcha.invalidate()
|
|
: i.captcha.load()));
|
|
} catch (e) {
|
|
if (l) return;
|
|
((i.error.value = e instanceof Error ? e.message : `验证码发送失败`),
|
|
await i.captcha.handleError(e));
|
|
} finally {
|
|
o.value = !1;
|
|
}
|
|
}
|
|
return {
|
|
sending: o,
|
|
countdown: s,
|
|
send: f,
|
|
start: d,
|
|
stop: u,
|
|
};
|
|
}
|
|
export { i as t };
|