Files
console-dev/app/lib/navigation-state.js
T

80 lines
2.1 KiB
JavaScript

/** 按 auth store 实例共享导航加载状态,切换身份立即丢弃旧菜单及旧请求结果。 */
import { watch } from "vue";
import { ref } from "vue";
import { effectScope } from "vue";
import { i as backend_menu_i } from "~/lib/backend-menu.js";
import { l as backend_menu_l } from "~/lib/backend-menu.js";
function a(a, o) {
let s = ref([]),
c = ref(!1),
l = ref(!1),
u = ref(!1),
d = ref(``),
f = 0,
p = null;
effectScope(!0).run(() =>
watch(
() => a.token,
() => {
(f++,
(p = null),
(s.value = []),
(c.value = !1),
(l.value = !1),
(u.value = !1),
(d.value = ``));
},
{
flush: `sync`,
},
),
);
// e 为强制刷新;并发请求复用 p,已加载的菜单默认不重复请求。
function m(e = !1) {
if (!a.isLoggedIn) return Promise.resolve();
if (p) return p;
if (l.value && !e) return Promise.resolve();
let t = f,
n = a.token;
((u.value = !0), (d.value = ``));
let m = o
.get(`/menu`, void 0, !1, {
timeoutMs: 8e3,
})
.then((e) => {
if (t === f && n === a.token) {
if (!Array.isArray(e?.menu)) throw Error(`站点导航响应异常`);
((s.value = backend_menu_l(backend_menu_i(e.menu))),
(c.value =
e.menu.length === 0 ||
e.menu.some((e) => e && typeof e == `object` && `id` in e)),
(l.value = !0));
}
})
.catch((e) => {
t === f &&
n === a.token &&
(d.value = e instanceof Error ? e.message : `站点导航加载失败`);
})
.finally(() => {
p === m && ((p = null), (u.value = !1));
});
return ((p = m), m);
}
return {
entries: s,
authoritative: c,
loaded: l,
loading: u,
error: d,
load: m,
};
}
// WeakMap 不延长 store 生命周期;同一应用内多个导航消费者共享同一份响应式状态。
var o = new WeakMap();
function s(e, t) {
let n = o.get(e);
return (n || ((n = a(e, t)), o.set(e, n)), n);
}
export { s as t };