Files
console-dev/app/pages/forgot-password.vue
cneicy 42dfead9cd
前端验证 / verify (push) Failing after 15m3s
feat(ui): 优化控制台响应式布局与视觉体验
- 统一页面标题、圆角、字体和响应式断点,调整暗色主题及图表配色
- 新增表格列标签插件,在窄屏下将表格转换为卡片布局,优化实例、订单、工单等列表展示
- 支持移动端点击订单行进入详情,并完善订单凭据的打印布局
- 在财务中心展示本月及累计消费,补充充值关闭时的提示
- 优化工单详情布局,将附件上传入口整合至富文本编辑器工具栏
- 调整实例操作按钮、SSH 密钥操作及安全菜单图标
- 为多个页面显式导入 definePageMeta,完善页面元数据声明
2026-11-07 00:09:57 +08:00

511 lines
16 KiB
Vue

<script>
/**
* 密码找回:手机或邮箱验证码配合验证码挑战提交重置请求,成功后返回登录并保留经处理的站内跳转参数。
*/
import { definePageMeta } from "#imports";
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 "~/components/PasswordField.vue";
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: ``,
}),
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,
});
// 复用 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 (!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: `86`,
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 }))
: 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>