527 lines
17 KiB
Vue
527 lines
17 KiB
Vue
<script>
|
|
/**
|
|
* 密码找回:手机或邮箱验证码配合验证码挑战提交重置请求,成功后返回登录并保留经处理的站内跳转参数。
|
|
*/
|
|
import "~/assets/styles/PhoneCodeField.CwyHXfML.css";
|
|
import "~/assets/styles/GeetestField.DiieTibK.css";
|
|
import "~/assets/styles/CaptchaField.BSN3ZbsD.css";
|
|
definePageMeta({
|
|
layout: `blank`,
|
|
alias: [`/forgot_password`],
|
|
});
|
|
import { toDisplayString } from "vue";
|
|
import { normalizeClass } from "vue";
|
|
import { createBlock } from "vue";
|
|
import { ref } from "vue";
|
|
import { withCtx } from "vue";
|
|
import { createCommentVNode } from "vue";
|
|
import { reactive } from "vue";
|
|
import { isRef } from "vue";
|
|
import { createElementBlock } from "vue";
|
|
import { createElementVNode } from "vue";
|
|
import { createTextVNode } from "vue";
|
|
import { unref } from "vue";
|
|
import { defineComponent } from "vue";
|
|
import { createVNode } from "vue";
|
|
import { openBlock } from "vue";
|
|
import { withModifiers } from "vue";
|
|
import { useRoute } from "#app";
|
|
import { useRouter } from "#app";
|
|
import { useHead } from "#app";
|
|
import { NuxtLink } from "#components";
|
|
import { useApi } from "~/lib/auth.js";
|
|
import button from "primevue/button";
|
|
import message from "primevue/message";
|
|
import { n as auth_redirect_n } from "~/lib/auth-redirect.js";
|
|
import { t as auth_redirect_t } from "~/lib/auth-redirect.js";
|
|
import inputtext from "primevue/inputtext";
|
|
import CaptchaField from "~/components/CaptchaField.vue";
|
|
import password from "primevue/password";
|
|
import PhoneCodeField from "~/components/PhoneCodeField.vue";
|
|
import { t as useCaptcha_t } from "~/lib/useCaptcha.js";
|
|
import { t as composables_t } from "~/lib/composables-2.js";
|
|
import { t as useVerifyCode_t } from "~/lib/useVerifyCode.js";
|
|
var D = {
|
|
class: `auth-card login-card`,
|
|
},
|
|
O = {
|
|
class: `field`,
|
|
},
|
|
k = {
|
|
class: `seg`,
|
|
role: `group`,
|
|
"aria-labelledby": `recovery-method-label`,
|
|
},
|
|
A = [`aria-pressed`, `disabled`],
|
|
j = [`aria-pressed`, `disabled`],
|
|
M = {
|
|
class: `field`,
|
|
},
|
|
N = {
|
|
for: `account`,
|
|
},
|
|
P = {
|
|
class: `field`,
|
|
},
|
|
F = {
|
|
class: `code-row`,
|
|
},
|
|
I = {
|
|
class: `field`,
|
|
},
|
|
L = {
|
|
class: `field`,
|
|
},
|
|
R = {
|
|
class: `login-links center`,
|
|
},
|
|
z = defineComponent({
|
|
__name: `forgot-password`,
|
|
setup(f) {
|
|
(useHead({
|
|
title: `找回密码 - 破碎工坊网络`,
|
|
}),
|
|
composables_t({
|
|
layout: `blank`,
|
|
alias: `/forgot_password`,
|
|
}));
|
|
let z = useApi(),
|
|
B = useRouter(),
|
|
V = useRoute(),
|
|
H = ref(`phone`),
|
|
U = reactive({
|
|
account: ``,
|
|
code: ``,
|
|
password: ``,
|
|
re_password: ``,
|
|
phone_code: `86`,
|
|
}),
|
|
W = ref(``),
|
|
G = ref(!1),
|
|
K = useCaptcha_t(`password_reset`),
|
|
{
|
|
needed: q,
|
|
provider: J,
|
|
captchaId: Y,
|
|
complete: ae,
|
|
invalidate: oe,
|
|
img: se,
|
|
value: X,
|
|
loading: ce,
|
|
error: Z,
|
|
load: le,
|
|
handleError: ue,
|
|
} = K,
|
|
{
|
|
sending: Q,
|
|
countdown: $,
|
|
send: de,
|
|
} = useVerifyCode_t({
|
|
action: `password_reset`,
|
|
captcha: K,
|
|
error: W,
|
|
phoneCode: () => U.phone_code,
|
|
});
|
|
// 复用 password_reset 场景的验证码发送与倒计时,不在页面另写一套短信请求。
|
|
function fe() {
|
|
if (G.value) return;
|
|
let e = U.account.trim();
|
|
return de(
|
|
H.value,
|
|
e,
|
|
H.value === `email` ? `请输入邮箱` : `请输入手机号`,
|
|
);
|
|
}
|
|
// 校验账号、区号、验证码和两次密码后提交重置;失败交由验证码实例处理挑战刷新。
|
|
async function pe() {
|
|
if (G.value || Q.value) return;
|
|
W.value = ``;
|
|
let e = U.account.trim();
|
|
if (!e)
|
|
return (W.value =
|
|
H.value === `email` ? `请输入邮箱` : `请输入手机号`);
|
|
if (H.value === `phone` && !/^[1-9]\d{0,3}$/.test(U.phone_code))
|
|
return (W.value = `请输入有效的国际电话区号`);
|
|
if (!U.code.trim()) return (W.value = `请输入验证码`);
|
|
if (!U.password) return (W.value = `请输入新密码`);
|
|
if (U.password !== U.re_password)
|
|
return (W.value = `两次输入的密码不一致`);
|
|
G.value = !0;
|
|
try {
|
|
(await z.post(`/account/password_reset`, {
|
|
type: H.value,
|
|
account: e,
|
|
phone_code: U.phone_code,
|
|
code: U.code.trim(),
|
|
password: U.password,
|
|
re_password: U.re_password,
|
|
}),
|
|
await B.push({
|
|
path: `/login`,
|
|
query: {
|
|
reset: `1`,
|
|
...auth_redirect_n(V.query.redirect),
|
|
},
|
|
}));
|
|
} catch (e) {
|
|
((W.value = e instanceof Error ? e.message : `重置失败`),
|
|
await ue(e));
|
|
} finally {
|
|
G.value = !1;
|
|
}
|
|
}
|
|
// 手机号/邮箱输入、验证码和密码表单共享提交锁;成功导航由 pe 负责,渲染层不直接建立会话。
|
|
return (r, o) => {
|
|
let f = PhoneCodeField,
|
|
h = inputtext,
|
|
g = button,
|
|
_ = CaptchaField,
|
|
y = password,
|
|
b = message,
|
|
T = NuxtLink;
|
|
return (
|
|
openBlock(),
|
|
createElementBlock(`div`, D, [
|
|
(o[13] ||= createElementVNode(
|
|
`div`,
|
|
{
|
|
class: `login-brand`,
|
|
},
|
|
[
|
|
createElementVNode(`h1`, null, `找回密码`),
|
|
createElementVNode(
|
|
`p`,
|
|
null,
|
|
`通过注册手机号或邮箱验证身份,设置新密码。`,
|
|
),
|
|
],
|
|
-1,
|
|
)),
|
|
createElementVNode(
|
|
`form`,
|
|
{
|
|
class: `login-form`,
|
|
onSubmit: withModifiers(pe, [`prevent`]),
|
|
},
|
|
[
|
|
unref(H) === `phone`
|
|
? (openBlock(),
|
|
createBlock(
|
|
f,
|
|
{
|
|
key: 0,
|
|
modelValue: unref(U).phone_code,
|
|
"onUpdate:modelValue": (o[0] ||= (e) =>
|
|
(unref(U).phone_code = e)),
|
|
disabled: unref(G) || unref(Q),
|
|
},
|
|
null,
|
|
8,
|
|
[`modelValue`, `disabled`],
|
|
))
|
|
: createCommentVNode(``, !0),
|
|
createElementVNode(`div`, O, [
|
|
(o[8] ||= createElementVNode(
|
|
`span`,
|
|
{
|
|
id: `recovery-method-label`,
|
|
class: `method-label`,
|
|
},
|
|
`找回方式`,
|
|
-1,
|
|
)),
|
|
createElementVNode(`div`, k, [
|
|
createElementVNode(
|
|
`button`,
|
|
{
|
|
type: `button`,
|
|
class: normalizeClass({
|
|
active: unref(H) === `phone`,
|
|
}),
|
|
"aria-pressed": unref(H) === `phone`,
|
|
disabled: unref(G) || unref(Q),
|
|
onClick: (o[1] ||= (e) => (H.value = `phone`)),
|
|
},
|
|
` 手机号 `,
|
|
10,
|
|
A,
|
|
),
|
|
createElementVNode(
|
|
`button`,
|
|
{
|
|
type: `button`,
|
|
class: normalizeClass({
|
|
active: unref(H) === `email`,
|
|
}),
|
|
"aria-pressed": unref(H) === `email`,
|
|
disabled: unref(G) || unref(Q),
|
|
onClick: (o[2] ||= (e) => (H.value = `email`)),
|
|
},
|
|
` 邮箱 `,
|
|
10,
|
|
j,
|
|
),
|
|
]),
|
|
]),
|
|
createElementVNode(`div`, M, [
|
|
createElementVNode(
|
|
`label`,
|
|
N,
|
|
toDisplayString(unref(H) === `email` ? `邮箱` : `手机号`),
|
|
1,
|
|
),
|
|
createVNode(
|
|
h,
|
|
{
|
|
id: `account`,
|
|
modelValue: unref(U).account,
|
|
"onUpdate:modelValue": (o[3] ||= (e) =>
|
|
(unref(U).account = e)),
|
|
placeholder:
|
|
unref(H) === `email`
|
|
? `请输入注册邮箱`
|
|
: `请输入注册手机号`,
|
|
autocomplete: `username`,
|
|
disabled: unref(G) || unref(Q),
|
|
fluid: ``,
|
|
},
|
|
null,
|
|
8,
|
|
[`modelValue`, `placeholder`, `disabled`],
|
|
),
|
|
]),
|
|
createElementVNode(`div`, P, [
|
|
(o[9] ||= createElementVNode(
|
|
`label`,
|
|
{
|
|
for: `code`,
|
|
},
|
|
[
|
|
createTextVNode(`验证码 `),
|
|
createElementVNode(
|
|
`span`,
|
|
{
|
|
class: `req`,
|
|
},
|
|
`*`,
|
|
),
|
|
],
|
|
-1,
|
|
)),
|
|
createElementVNode(`div`, F, [
|
|
createVNode(
|
|
h,
|
|
{
|
|
id: `code`,
|
|
modelValue: unref(U).code,
|
|
"onUpdate:modelValue": (o[4] ||= (e) =>
|
|
(unref(U).code = e)),
|
|
placeholder: `请输入验证码`,
|
|
autocomplete: `one-time-code`,
|
|
},
|
|
null,
|
|
8,
|
|
[`modelValue`],
|
|
),
|
|
createVNode(
|
|
g,
|
|
{
|
|
type: `button`,
|
|
label: unref($) > 0 ? `${unref($)}s` : `获取验证码`,
|
|
severity: `secondary`,
|
|
outlined: ``,
|
|
loading: unref(Q),
|
|
disabled: unref($) > 0 || unref(G),
|
|
onClick: fe,
|
|
},
|
|
null,
|
|
8,
|
|
[`label`, `loading`, `disabled`],
|
|
),
|
|
]),
|
|
]),
|
|
unref(q)
|
|
? (openBlock(),
|
|
createBlock(
|
|
_,
|
|
{
|
|
key: 1,
|
|
modelValue: unref(X),
|
|
"onUpdate:modelValue": (o[5] ||= (e) =>
|
|
isRef(X) ? (X.value = e) : null),
|
|
img: unref(se),
|
|
provider: unref(J),
|
|
"captcha-id": unref(Y),
|
|
disabled: unref(G) || unref(Q),
|
|
onVerified: unref(ae),
|
|
onInvalid: unref(oe),
|
|
loading: unref(ce),
|
|
onRefresh: unref(le),
|
|
},
|
|
null,
|
|
8,
|
|
[
|
|
`modelValue`,
|
|
`img`,
|
|
`provider`,
|
|
`captcha-id`,
|
|
`disabled`,
|
|
`onVerified`,
|
|
`onInvalid`,
|
|
`loading`,
|
|
`onRefresh`,
|
|
],
|
|
))
|
|
: createCommentVNode(``, !0),
|
|
createElementVNode(`div`, I, [
|
|
(o[10] ||= createElementVNode(
|
|
`label`,
|
|
{
|
|
for: `password`,
|
|
},
|
|
[
|
|
createTextVNode(`新密码 `),
|
|
createElementVNode(
|
|
`span`,
|
|
{
|
|
class: `req`,
|
|
},
|
|
`*`,
|
|
),
|
|
],
|
|
-1,
|
|
)),
|
|
createVNode(
|
|
y,
|
|
{
|
|
"input-id": `password`,
|
|
modelValue: unref(U).password,
|
|
"onUpdate:modelValue": (o[6] ||= (e) =>
|
|
(unref(U).password = e)),
|
|
placeholder: `输入新密码`,
|
|
feedback: !1,
|
|
toggleMask: ``,
|
|
autocomplete: `new-password`,
|
|
fluid: ``,
|
|
},
|
|
null,
|
|
8,
|
|
[`modelValue`],
|
|
),
|
|
]),
|
|
createElementVNode(`div`, L, [
|
|
(o[11] ||= createElementVNode(
|
|
`label`,
|
|
{
|
|
for: `re-password`,
|
|
},
|
|
[
|
|
createTextVNode(`确认新密码 `),
|
|
createElementVNode(
|
|
`span`,
|
|
{
|
|
class: `req`,
|
|
},
|
|
`*`,
|
|
),
|
|
],
|
|
-1,
|
|
)),
|
|
createVNode(
|
|
y,
|
|
{
|
|
"input-id": `re-password`,
|
|
modelValue: unref(U).re_password,
|
|
"onUpdate:modelValue": (o[7] ||= (e) =>
|
|
(unref(U).re_password = e)),
|
|
placeholder: `再次输入新密码`,
|
|
feedback: !1,
|
|
toggleMask: ``,
|
|
autocomplete: `new-password`,
|
|
fluid: ``,
|
|
},
|
|
null,
|
|
8,
|
|
[`modelValue`],
|
|
),
|
|
]),
|
|
unref(W)
|
|
? (openBlock(),
|
|
createBlock(
|
|
b,
|
|
{
|
|
key: 2,
|
|
severity: `error`,
|
|
closable: !1,
|
|
},
|
|
{
|
|
default: withCtx(() => [
|
|
createTextVNode(toDisplayString(unref(W)), 1),
|
|
]),
|
|
_: 1,
|
|
},
|
|
))
|
|
: createCommentVNode(``, !0),
|
|
unref(Z)
|
|
? (openBlock(),
|
|
createBlock(
|
|
b,
|
|
{
|
|
key: 3,
|
|
severity: `error`,
|
|
closable: !1,
|
|
},
|
|
{
|
|
default: withCtx(() => [
|
|
createTextVNode(toDisplayString(unref(Z)), 1),
|
|
]),
|
|
_: 1,
|
|
},
|
|
))
|
|
: createCommentVNode(``, !0),
|
|
createVNode(
|
|
g,
|
|
{
|
|
type: `submit`,
|
|
label: `重置密码`,
|
|
loading: unref(G),
|
|
class: `login-btn`,
|
|
fluid: ``,
|
|
},
|
|
null,
|
|
8,
|
|
[`loading`],
|
|
),
|
|
createElementVNode(`div`, R, [
|
|
createVNode(
|
|
T,
|
|
{
|
|
to: unref(auth_redirect_t)(
|
|
`/login`,
|
|
unref(V).query.redirect,
|
|
),
|
|
},
|
|
{
|
|
default: withCtx(() => [
|
|
...(o[12] ||= [
|
|
createTextVNode(`想起密码了?返回登录`, -1),
|
|
]),
|
|
]),
|
|
_: 1,
|
|
},
|
|
8,
|
|
[`to`],
|
|
),
|
|
]),
|
|
],
|
|
32,
|
|
),
|
|
])
|
|
);
|
|
};
|
|
},
|
|
});
|
|
export {};
|
|
export default z;
|
|
</script>
|