Files
console-dev/app/pages/account/connections.vue
T

414 lines
14 KiB
Vue

<script>
/**
* 第三方账号关联管理:从账户资料整理 OAuth 绑定状态,通过公共 OAuth 流程发起关联,并确认后解除绑定。
*/
import "~/assets/styles/WechatConnection.DI5ko1xy.css";
import { toDisplayString } from "vue";
import { renderList } from "vue";
import { onMounted } from "vue";
import { onBeforeUnmount } from "vue";
import { createBlock } from "vue";
import { ref } from "vue";
import { withCtx } from "vue";
import { createCommentVNode } from "vue";
import { computed } from "vue";
import { isRef } from "vue";
import { createElementBlock } from "vue";
import { Fragment } 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 { NuxtLink } from "#components";
import { useApi } from "~/lib/auth.js";
import dialog from "primevue/dialog";
import button from "primevue/button";
import message from "primevue/message";
import { t as oauth_t } from "~/lib/oauth.js";
import { t as useOAuth_t } from "~/lib/useOAuth.js";
import skeleton from "primevue/skeleton";
import WechatConnection from "~/components/WechatConnection.vue";
var D = {
class: `account-management-page`,
},
O = {
class: `account-management-head`,
},
k = {
class: `account-management-actions`,
},
A = {
"aria-label": `其他登录方式`,
},
j = {
key: 0,
class: `connection-list`,
},
M = {
key: 1,
class: `account-management-note`,
},
N = {
key: 2,
class: `connection-list`,
},
P = [`src`],
F = {
class: `connection-provider-main`,
},
I = defineComponent({
__name: `connections`,
setup(h) {
let I = useApi(),
L = ref([]),
R = ref(!1),
z = ref(``),
B = ref(``),
V = ref(!1),
H = ref(!1),
U = ref(null),
{ busy: W, error: G, start: K } = useOAuth_t(),
q = computed({
get: () => !!U.value,
set: (e) => {
!e && !H.value && (U.value = null);
},
}),
J = !0;
onBeforeUnmount(() => {
J = !1;
});
// 读取 /account 的 OAuth 关联列表;组件卸载后的响应不再更新界面。
async function Y() {
if (!R.value) {
((R.value = !0), (z.value = ``));
try {
let e = await I.get(`/account`);
if (!J) return;
((L.value = oauth_t(e.account?.oauth)), (V.value = !0));
} catch (e) {
J && (z.value = e instanceof Error ? e.message : `加载失败`);
} finally {
J && (R.value = !1);
}
}
}
// 仅对已关联的提供方执行解绑;请求完成后重新加载列表,以服务端结果为准。
async function X() {
if (U.value?.linked && !H.value && !W.value && J) {
((H.value = !0), (z.value = ``), (B.value = ``));
try {
if (
(await I.post(
`/oauth/unbind/${encodeURIComponent(U.value.name)}`,
),
!J)
)
return;
((U.value = null), (B.value = `已取消关联`), await Y());
} catch (e) {
J && (z.value = e instanceof Error ? e.message : `取消关联失败`);
} finally {
J && (H.value = !1);
}
}
}
return (
onMounted(Y),
// 列表、绑定入口与解绑确认共用上方互斥状态;外部授权流程由公共 OAuth 控制器处理。
(n, r) => {
let a = NuxtLink,
c = button,
h = message,
y = WechatConnection,
C = skeleton,
w = dialog;
return (
openBlock(),
createElementBlock(`div`, D, [
createElementVNode(`header`, O, [
(r[3] ||= createElementVNode(
`div`,
null,
[
createElementVNode(`h2`, null, `关联账号`),
createElementVNode(
`p`,
null,
`管理第三方登录方式与微信通知。`,
),
],
-1,
)),
createElementVNode(`div`, k, [
createVNode(
a,
{
to: `/account`,
class: `account-management-link`,
},
{
default: withCtx(() => [
...(r[2] ||= [
createElementVNode(
`i`,
{
class: `pi pi-angle-left`,
"aria-hidden": `true`,
},
null,
-1,
),
createTextVNode(`账户设置`, -1),
]),
]),
_: 1,
},
),
createVNode(
c,
{
label: `刷新`,
icon: `pi pi-refresh`,
severity: `secondary`,
outlined: ``,
loading: unref(R),
disabled: unref(H) || unref(W),
onClick: Y,
},
null,
8,
[`loading`, `disabled`],
),
]),
]),
unref(z) || unref(G)
? (openBlock(),
createBlock(
h,
{
key: 0,
severity: `error`,
closable: !1,
},
{
default: withCtx(() => [
createTextVNode(
toDisplayString(unref(z) || unref(G)),
1,
),
]),
_: 1,
},
))
: createCommentVNode(``, !0),
unref(B)
? (openBlock(),
createBlock(
h,
{
key: 1,
severity: `success`,
closable: !1,
},
{
default: withCtx(() => [
createTextVNode(toDisplayString(unref(B)), 1),
]),
_: 1,
},
))
: createCommentVNode(``, !0),
createVNode(y),
createElementVNode(`section`, A, [
(r[4] ||= createElementVNode(
`h3`,
{
class: `connection-section-title`,
},
`其他登录方式`,
-1,
)),
unref(R) && !unref(V)
? (openBlock(),
createElementBlock(`div`, j, [
createVNode(C, {
height: `60px`,
}),
]))
: unref(V) && !unref(L).length
? (openBlock(),
createElementBlock(`p`, M, `暂无其他第三方登录方式。`))
: (openBlock(),
createElementBlock(`div`, N, [
(openBlock(!0),
createElementBlock(
Fragment,
null,
renderList(
unref(L),
(t) => (
openBlock(),
createElementBlock(
`div`,
{
key: t.name,
class: `connection-provider`,
},
[
t.image
? (openBlock(),
createElementBlock(
`img`,
{
key: 0,
src: t.image,
alt: ``,
referrerpolicy: `no-referrer`,
},
null,
8,
P,
))
: createCommentVNode(``, !0),
createElementVNode(`div`, F, [
createElementVNode(
`strong`,
null,
toDisplayString(t.title),
1,
),
createElementVNode(
`p`,
null,
toDisplayString(
t.linked ? `已关联` : `未关联`,
),
1,
),
]),
t.linked
? (openBlock(),
createBlock(
c,
{
key: 1,
label: `取消关联`,
severity: `secondary`,
outlined: ``,
disabled:
unref(H) || unref(W) || unref(R),
onClick: (e) => (U.value = t),
},
null,
8,
[`disabled`, `onClick`],
))
: (openBlock(),
createBlock(
c,
{
key: 2,
label: `关联账号`,
disabled:
unref(H) || unref(W) || unref(R),
onClick: (e) => unref(K)(t.name),
},
null,
8,
[`disabled`, `onClick`],
)),
],
)
),
),
128,
)),
])),
]),
createVNode(
w,
{
visible: unref(q),
"onUpdate:visible": (r[1] ||= (e) =>
isRef(q) ? (q.value = e) : null),
header: `取消关联`,
modal: ``,
closable: !unref(H),
draggable: !1,
style: {
width: `450px`,
},
},
{
footer: withCtx(() => [
createVNode(
c,
{
label: `保留关联`,
severity: `secondary`,
outlined: ``,
disabled: unref(H),
onClick: (r[0] ||= (e) => (U.value = null)),
},
null,
8,
[`disabled`],
),
createVNode(
c,
{
label: `确认取消关联`,
severity: `danger`,
loading: unref(H),
onClick: X,
},
null,
8,
[`loading`],
),
]),
default: withCtx(() => [
createElementVNode(
`p`,
null,
`确认取消与 ` +
toDisplayString(unref(U)?.title) +
` 的关联?之后将无法使用该方式登录。请先确认手机号或邮箱登录可用。`,
1,
),
unref(z)
? (openBlock(),
createBlock(
h,
{
key: 0,
severity: `error`,
closable: !1,
},
{
default: withCtx(() => [
createTextVNode(toDisplayString(unref(z)), 1),
]),
_: 1,
},
))
: createCommentVNode(``, !0),
]),
_: 1,
},
8,
[`visible`, `closable`],
),
])
);
}
);
},
});
export {};
export default I;
</script>