UNPKG

vue-bag-admin

Version:

Unified entry package for the Vue Bag Admin runtime ecosystem.

1,395 lines 84.1 kB
import { h as k, nextTick as ke, defineComponent as ee, ref as O, watch as Ce, computed as S, openBlock as m, createElementBlock as w, createElementVNode as s, Fragment as Q, renderList as q, unref as h, withModifiers as Re, normalizeClass as V, createCommentVNode as E, toDisplayString as L, createVNode as H, inject as ft, watchEffect as gt, createBlock as U, resolveDynamicComponent as Pe, createStaticVNode as je, withCtx as R, renderSlot as de, resolveComponent as mt, Transition as vt, KeepAlive as yt, isRef as wt, normalizeStyle as ve, createTextVNode as Ke, useSlots as xt, onMounted as kt, onUnmounted as Ct } from "vue"; import { useI18n as Me, createI18n as Pt } from "vue-i18n"; import { defineStore as ue, storeToRefs as Fe } from "pinia"; import { useRoute as Ae, useRouter as $e, createRouter as Tt, createWebHashHistory as _t } from "vue-router"; import { BagUiProvider as Mt } from "../ui/index.js"; import { NDropdown as Te, NPopover as At, NTabs as $t, NTabPane as St, NEmpty as Bt, NMenu as Lt, NDrawer as Vt, NDrawerContent as Et, NSwitch as Ht, NButton as De, createDiscreteApi as Rt } from "naive-ui"; import { useLocalStorage as K, useBreakpoints as jt, breakpointsTailwind as Kt } from "@vueuse/core"; import { http as Ie } from "../request/index.js"; import { setPluginStateProvider as Dt, registerRuntimePlugins as It, isPluginEnabled as Ot } from "../core/index.js"; const Se = ue("menu", { state: () => ({ menus: [], // 使用 vueuse 的 useLocalStorage,自动处理持久化和响应式 collapsed: K("bag.menu.collapsed", !1), expandedKeys: K("bag.menu.expandedKeys", []), // 新增:用于移动端的抽屉菜单状态 mobileDrawerOpen: !1 }), actions: { setMenus(e) { this.menus = e; }, toggleCollapsed() { this.collapsed = !this.collapsed; }, setCollapsed(e) { this.collapsed = e; }, toggleMobileDrawer() { this.mobileDrawerOpen = !this.mobileDrawerOpen; }, setMobileDrawer(e) { this.mobileDrawerOpen = e; }, setExpandedKeys(e) { this.expandedKeys = e; } } }), ye = "bag.auth.token", Oe = (e) => { var o, a, i, c, d; const t = ((i = (a = (o = e == null ? void 0 : e.response) == null ? void 0 : o.data) == null ? void 0 : a.error) == null ? void 0 : i.message) ?? ((d = (c = e == null ? void 0 : e.response) == null ? void 0 : c.data) == null ? void 0 : d.message) ?? (e == null ? void 0 : e.message); return t ? String(t) : "Request failed"; }, zt = (e) => { var o, a; const t = []; return (o = e.role) != null && o.type && t.push(e.role.type), (a = e.role) != null && a.name && e.role.name !== e.role.type && t.push(e.role.name), t.length === 0 && t.push("authenticated"), { username: e.username || "", user: e, roles: t, permissions: Array.isArray(e.permissions) ? e.permissions : [] }; }, Ze = () => ({ async login(e) { const t = await Ie.post("/api/auth/local", { identifier: e.username, password: e.password }); return { token: t.jwt, profile: t.user ? { username: String(t.user.username ?? ""), user: t.user } : void 0 }; }, async fetchProfile() { const e = await Ie.get("/api/users/me", { params: { populate: "role" } }); return zt(e); } }); let Y = Ze(); const ra = (e) => { Y = e; }, na = () => { Y = Ze(); }, ze = (e, t) => { var o; e.username = t.username || "", e.user = t.user ?? null, e.roles = (o = t.roles) != null && o.length ? t.roles : ["authenticated"], e.permissions = t.permissions ?? [], e.profileLoaded = !0; }, he = ue("user", { state: () => ({ token: localStorage.getItem(ye) || "", username: "", user: null, roles: [], permissions: [], profileLoaded: !1 // 标记用户信息是否已经加载完成 }), getters: { // 判断用户是否已登录 isAuthenticated: (e) => !!e.token }, actions: { /** * 登录逻辑 (对接 Strapi 5) */ async login(e) { try { const t = await Y.login(e); this.token = t.token, localStorage.setItem(ye, this.token), t.profile ? ze(this, t.profile) : await this.fetchProfile(); } catch (t) { throw new Error(Oe(t)); } }, /** * 退出登录 */ logout() { var e; (e = Y.logout) == null || e.call(Y), this.token = "", this.username = "", this.user = null, this.roles = [], this.permissions = [], this.profileLoaded = !1, localStorage.removeItem(ye); }, /** * 获取用户信息(包括角色和权限点) */ async fetchProfile() { try { const e = await Y.fetchProfile({ token: this.token }); ze(this, e); } catch (e) { throw new Error(Oe(e)); } }, /** * 判断当前用户是否拥有某些角色 * @param roles 需要判断的角色数组 * @returns 只要满足其中一个角色即返回 true */ hasRole(e, t = "any") { return e != null && e.length ? t === "all" ? e.every((o) => this.roles.includes(o)) : e.some((o) => this.roles.includes(o)) : !0; }, /** * 判断当前用户是否拥有某些权限 * @param perms 需要判断的权限点数组 * @returns 如果拥有 '*' 权限直接返回 true,否则只要满足其中一个权限即返回 true */ hasPermission(e, t = "any") { return !(e != null && e.length) || this.permissions.includes("*") ? !0 : t === "all" ? e.every((o) => this.permissions.includes(o)) : e.some((o) => this.permissions.includes(o)); } } }); function N(e) { return k( "span", { style: { display: "inline-flex", width: "16px", height: "16px", alignItems: "center" } }, [e] ); } function Nt(e) { if (e === "dashboard") return () => N( k("svg", { viewBox: "0 0 24 24", fill: "none", width: "16", height: "16" }, [ k("path", { d: "M3 13h8V3H3v10Zm10 8h8V11h-8v10ZM3 21h8v-6H3v6Zm10-10h8V3h-8v8Z", fill: "currentColor" }) ]) ); if (e === "settings") return () => N( k("svg", { viewBox: "0 0 24 24", fill: "none", width: "16", height: "16" }, [ k("path", { d: "M19.14 12.94c.04-.31.06-.63.06-.94s-.02-.63-.06-.94l2.03-1.58a.5.5 0 0 0 .12-.64l-1.92-3.32a.5.5 0 0 0-.6-.22l-2.39.96a7.1 7.1 0 0 0-1.63-.94l-.36-2.54A.5.5 0 0 0 13.9 1h-3.8a.5.5 0 0 0-.49.42l-.36 2.54c-.58.23-1.12.54-1.63.94l-2.39-.96a.5.5 0 0 0-.6.22L2.71 7.48a.5.5 0 0 0 .12.64l2.03 1.58c-.04.31-.06.63-.06.94s.02.63.06.94L2.83 14.52a.5.5 0 0 0-.12.64l1.92 3.32c.13.23.4.32.64.22l2.39-.96c.5.4 1.05.71 1.63.94l.36 2.54c.04.24.25.42.49.42h3.8c.24 0 .45-.18.49-.42l.36-2.54c.58-.23 1.12-.54 1.63-.94l2.39.96c.24.1.51.01.64-.22l1.92-3.32a.5.5 0 0 0-.12-.64l-2.03-1.58ZM12 15.5A3.5 3.5 0 1 1 12 8a3.5 3.5 0 0 1 0 7.5Z", fill: "currentColor" }) ]) ); if (e === "shop") return () => N( k( "svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round", width: "16", height: "16" }, [ k("path", { d: "M6 2L3 6v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V6l-3-4z" }), k("line", { x1: "3", y1: "6", x2: "21", y2: "6" }), k("path", { d: "M16 10a4 4 0 0 1-8 0" }) ] ) ); if (e === "order") return () => N( k( "svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round", width: "16", height: "16" }, [ k("path", { d: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" }), k("polyline", { points: "14 2 14 8 20 8" }), k("line", { x1: "16", y1: "13", x2: "8", y2: "13" }), k("line", { x1: "16", y1: "17", x2: "8", y2: "17" }), k("polyline", { points: "10 9 9 9 8 9" }) ] ) ); if (e === "user") return () => N( k( "svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round", width: "16", height: "16" }, [ k("path", { d: "M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2" }), k("circle", { cx: "9", cy: "7", r: "4" }), k("path", { d: "M23 21v-2a4 4 0 0 0-3-3.87" }), k("path", { d: "M16 3.13a4 4 0 0 1 0 7.75" }) ] ) ); if (e === "star") return () => N( k( "svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round", width: "16", height: "16" }, [ k("polygon", { points: "12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2" }) ] ) ); if (e === "chat") return () => N( k( "svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round", width: "16", height: "16" }, [k("path", { d: "M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z" })] ) ); if (e === "money") return () => N( k( "svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round", width: "16", height: "16" }, [ k("line", { x1: "12", y1: "1", x2: "12", y2: "23" }), k("path", { d: "M17 5H9.5a3.5 3.5 0 0 0 0 7h5a3.5 3.5 0 0 1 0 7H6" }) ] ) ); if (e === "store") return () => N( k( "svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round", width: "16", height: "16" }, [ k("path", { d: "M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z" }), k("polyline", { points: "9 22 9 12 15 12 15 22" }) ] ) ); } const Xe = { homePath: "/dashboard", loginPath: "/login", profilePath: "/profile", forbiddenPath: "/403", notFoundPath: "/404", redirectName: "Redirect" }; let _e = { ...Xe }; const Ut = (e) => (_e = { ...Xe, ...e }, _e), z = () => _e, Wt = "bag.admin.tabs", Ft = (e) => { var t, o; return ((t = e.meta) == null ? void 0 : t.layout) === "blank" || ((o = e.meta) == null ? void 0 : o.hideInTabBar) === !0; }, ae = ue("tabbar", { state: () => ({ // 标签页列表需要跨刷新和重开浏览器恢复,因此使用 localStorage 持久化。 tabs: K(Wt, []), // 设置项可能由宿主或独立插件页修改,因此统一走 localStorage 做同步。 enableTabCache: K("bag.admin.enableTabCache", !0), enableTabPersist: K("bag.admin.enableTabPersist", !0), // 刷新页面时会临时把目标视图从 KeepAlive include 中移除,确保重新挂载。 refreshingViews: [] }), getters: { cachedViews: (e) => e.enableTabCache ? [ ...new Set( e.tabs.filter((t) => { const o = t.cacheKey || t.name; return !t.noCache && o && !e.refreshingViews.includes(o); }).map((t) => t.cacheKey || t.name) ) ] : [] }, actions: { syncRefreshingViews() { const e = new Set( this.tabs.map((t) => t.cacheKey || t.name).filter(Boolean) ); this.refreshingViews = this.refreshingViews.filter((t) => e.has(t)); }, addTab(e) { var o, a, i; if (Ft(e) || !e.name) return; if (!this.tabs.some((c) => c.fullPath === e.fullPath)) { const c = (o = e.meta) == null ? void 0 : o.title, d = (a = e.meta) == null ? void 0 : a.noCache, u = (i = e.meta) == null ? void 0 : i.cacheKey; this.tabs.push({ fullPath: e.fullPath, path: e.path, name: e.name, cacheKey: u, title: c || e.name, noCache: !!d }); } }, removeTabsByPaths(e) { if (e.length === 0) return; const t = new Set(e); this.tabs = this.tabs.filter((o) => !t.has(o.path)), this.syncRefreshingViews(); }, removeTab(e) { const t = this.tabs.find((i) => i.fullPath === e), o = this.tabs.findIndex((i) => i.fullPath === e); o !== -1 && this.tabs.splice(o, 1); const a = (t == null ? void 0 : t.cacheKey) || (t == null ? void 0 : t.name); a && (this.refreshingViews = this.refreshingViews.filter((i) => i !== a)); }, clearTabs() { this.refreshingViews = []; const { homePath: e } = z(); this.tabs = this.tabs.filter((t) => t.path === e); }, closeOtherTabs(e) { const { homePath: t } = z(); this.tabs = this.tabs.filter((o) => o.fullPath === e || o.path === t), this.syncRefreshingViews(); }, closeLeftTabs(e) { const t = this.tabs.findIndex((o) => o.fullPath === e); if (t !== -1) { const { homePath: o } = z(); this.tabs = this.tabs.filter((a, i) => i >= t || a.path === o), this.syncRefreshingViews(); } }, closeRightTabs(e) { const t = this.tabs.findIndex((o) => o.fullPath === e); if (t !== -1) { const { homePath: o } = z(); this.tabs = this.tabs.filter((a, i) => i <= t || a.path === o), this.syncRefreshingViews(); } }, async evictCache(e) { const t = this.tabs.find((a) => a.fullPath === e), o = (t == null ? void 0 : t.cacheKey) || (t == null ? void 0 : t.name); !o || t.noCache || (this.refreshingViews.includes(o) || this.refreshingViews.push(o), await ke()); }, restoreCache(e) { const t = this.tabs.find((a) => a.fullPath === e), o = (t == null ? void 0 : t.cacheKey) || (t == null ? void 0 : t.name); o && (this.refreshingViews = this.refreshingViews.filter((a) => a !== o)); } } }), Zt = { class: "tabbar-shell" }, Xt = ["onClick", "onContextmenu"], Yt = { key: 0, class: "tabbar-item-dot" }, Gt = { class: "tabbar-item-title" }, Jt = ["onClick"], Qt = /* @__PURE__ */ ee({ __name: "TabBar", setup(e) { const t = ae(), o = Ae(), a = $e(), { locale: i, fallbackLocale: c, messages: d, t: u } = Me(), T = z(), _ = (b) => /^[A-Za-z0-9_-]+(?:\.[A-Za-z0-9_-]+)+$/.test(b), v = () => { const b = [i.value], g = c.value; if (typeof g == "string") b.push(g); else if (Array.isArray(g)) b.push(...g); else if (g && typeof g == "object") { const y = g[i.value]; typeof y == "string" ? b.push(y) : Array.isArray(y) && b.push(...y); const C = g.default; typeof C == "string" ? b.push(C) : Array.isArray(C) && b.push(...C); } return [...new Set(b.filter(Boolean))]; }, M = (b, g) => { var C; let y = (C = d.value) == null ? void 0 : C[b]; for (const X of g.split(".")) { if (!y || typeof y != "object" || !(X in y)) return; y = y[X]; } return typeof y == "string" ? y : void 0; }, A = (b) => { for (const g of v()) { const y = M(g, b); if (y) return y; } return b; }, j = (b) => { const g = b.title || b.name || "Unknown"; return _(g) ? A(g) : g; }, $ = O(null), D = () => { $.value && $.value.scrollBy({ left: -200, behavior: "smooth" }); }, B = () => { $.value && $.value.scrollBy({ left: 200, behavior: "smooth" }); }, Z = () => { ke(() => { if (!$.value) return; const b = $.value.querySelector(".bg-gradient-to-r"); if (b) { const g = $.value.clientWidth, y = b.offsetLeft, C = b.clientWidth, X = $.value.scrollLeft; y < X ? $.value.scrollTo({ left: y - 20, behavior: "smooth" }) : y + C > X + g && $.value.scrollTo({ left: y + C - g + 20, behavior: "smooth" }); } }); }; Ce( () => o.fullPath, () => { Z(); } ); const P = (b) => o.fullPath === b, f = (b) => { o.fullPath !== b && a.push(b); }, p = (b) => { const g = t.tabs, y = g.findIndex((C) => C.fullPath === b); if (y !== -1) { if (P(b)) { const C = g[y - 1] || g[y + 1]; C ? a.push(C.fullPath) : a.push(T.homePath); } t.removeTab(b); } }, I = (b) => { p(b); }, ne = async (b) => { if (b) { if (await t.evictCache(b.fullPath), b.fullPath === o.fullPath) { await a.replace({ name: "Redirect", query: { target: b.fullPath } }); return; } t.restoreCache(b.fullPath), await a.push(b.fullPath); } }, W = O(!1), le = O(0), G = O(0), te = O(""), se = S(() => [ { label: u("tabbar.reload", "重新加载"), key: "reload" }, { label: u("tabbar.close", "关闭标签"), key: "close", disabled: te.value === T.homePath }, { label: u("tabbar.closeOther", "关闭其他"), key: "closeOther" }, { label: u("tabbar.closeLeft", "关闭左侧"), key: "closeLeft" }, { label: u("tabbar.closeRight", "关闭右侧"), key: "closeRight" }, { label: u("tabbar.closeAll", "全部关闭"), key: "closeAll" } ]), oe = (b, g) => { b.preventDefault(), W.value = !1, ke().then(() => { W.value = !0, le.value = b.clientX, G.value = b.clientY, te.value = g.fullPath; }); }, fe = () => { W.value = !1; }, ge = async (b) => { W.value = !1; const g = te.value, y = t.tabs.find((C) => C.fullPath === g); switch (b) { case "reload": await ne(y); break; case "close": p(g); break; case "closeOther": t.closeOtherTabs(g), P(g) || a.push(g); break; case "closeLeft": t.closeLeftTabs(g), t.tabs.findIndex((C) => C.fullPath === o.fullPath) === -1 && a.push(g); break; case "closeRight": t.closeRightTabs(g), t.tabs.findIndex((C) => C.fullPath === o.fullPath) === -1 && a.push(g); break; case "closeAll": t.clearTabs(), a.push(T.homePath); break; } }; return (b, g) => (m(), w("div", Zt, [ s("div", { class: "tabbar-nav-btn", onClick: D }, [...g[0] || (g[0] = [ s("svg", { xmlns: "http://www.w3.org/2000/svg", class: "h-4 w-4", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor" }, [ s("path", { "stroke-linecap": "round", "stroke-linejoin": "round", "stroke-width": "2", d: "M15 19l-7-7 7-7" }) ], -1) ])]), s("div", { ref_key: "scrollContainer", ref: $, class: "tabbar-scroll scrollbar-hide" }, [ (m(!0), w(Q, null, q(h(t).tabs, (y) => (m(), w("div", { key: y.fullPath, class: V(["tabbar-item", [P(y.fullPath) ? "is-active" : "is-inactive"]]), onClick: (C) => f(y.fullPath), onContextmenu: Re((C) => oe(C, y), ["prevent"]) }, [ P(y.fullPath) ? (m(), w("span", Yt)) : E("", !0), s("span", Gt, L(j(y)), 1), y.path !== h(T).homePath ? (m(), w("button", { key: 1, type: "button", class: "tabbar-close-btn", onClick: Re((C) => I(y.fullPath), ["stop"]) }, [...g[1] || (g[1] = [ s("svg", { xmlns: "http://www.w3.org/2000/svg", class: "tabbar-close-icon", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor" }, [ s("path", { "stroke-linecap": "round", "stroke-linejoin": "round", "stroke-width": "2", d: "M6 18L18 6M6 6l12 12" }) ], -1) ])], 8, Jt)) : E("", !0) ], 42, Xt))), 128)) ], 512), s("div", { class: "tabbar-nav-btn", onClick: B }, [...g[2] || (g[2] = [ s("svg", { xmlns: "http://www.w3.org/2000/svg", class: "h-4 w-4", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor" }, [ s("path", { "stroke-linecap": "round", "stroke-linejoin": "round", "stroke-width": "2", d: "M9 5l7 7-7 7" }) ], -1) ])]), H(h(Te), { placement: "bottom-start", trigger: "manual", x: le.value, y: G.value, options: se.value, show: W.value, "on-clickoutside": fe, onSelect: ge }, null, 8, ["x", "y", "options", "show"]) ])); } }), Be = (e, t) => { const o = e.__vccOpts || e; for (const [a, i] of t) o[a] = i; return o; }, qt = /* @__PURE__ */ Be(Qt, [["__scopeId", "data-v-a3eb268d"]]), pe = (e, t = he()) => { var a; const o = { roles: t.roles, permissions: t.permissions, user: t.user ?? void 0 }; return t.hasRole(e.roles, e.roleMode) && t.hasPermission(e.permissions, e.permissionMode) && (((a = e.policy) == null ? void 0 : a.call(e, o)) ?? !0); }, la = (e) => { const t = he(); return S(() => pe(e, t)); }, es = { "#f97316": { hover: "#fb923c", pressed: "#ea580c", accent: "#f43f5e", accentHover: "#fb7185" }, "#3b82f6": { hover: "#60a5fa", pressed: "#2563eb", accent: "#06b6d4", accentHover: "#22d3ee" }, "#10b981": { hover: "#34d399", pressed: "#059669", accent: "#14b8a6", accentHover: "#2dd4bf" }, "#8b5cf6": { hover: "#a78bfa", pressed: "#7c3aed", accent: "#ec4899", accentHover: "#f472b6" }, "#f43f5e": { hover: "#fb7185", pressed: "#e11d48", accent: "#f97316", accentHover: "#fb923c" } }, ts = { headerHeight: "64px", sidebarWidth: "256px", sidebarCollapsedWidth: "72px", contentMaxWidth: "1280px", radiusSm: "8px", radiusMd: "12px", radiusLg: "16px", radiusXl: "24px" }, Ye = (e) => { const t = e.trim().toLowerCase(); return /^#[0-9a-f]{6}$/.test(t) ? t : "#f97316"; }, Ge = (e) => { const t = Ye(e).slice(1); return { r: Number.parseInt(t.slice(0, 2), 16), g: Number.parseInt(t.slice(2, 4), 16), b: Number.parseInt(t.slice(4, 6), 16) }; }, ss = (e) => { const { r: t, g: o, b: a } = Ge(e); return `${t} ${o} ${a}`; }, J = (e, t) => { const { r: o, g: a, b: i } = Ge(e); return `rgba(${o}, ${a}, ${i}, ${t})`; }, we = (e, t) => ({ ...e, ...t ?? {} }), os = (e, t = "#f97316", o = {}) => { const a = Ye(t), i = es[a] ?? { hover: a, pressed: a, accent: a, accentHover: a }, c = { primary: a, primaryHover: i.hover, primaryPressed: i.pressed, primarySuppl: i.hover, primarySoft: J(a, 0.12), primarySofter: J(a, 0.06), accent: i.accent, accentHover: i.accentHover, accentSoft: J(i.accent, 0.12), success: "#10b981", warning: "#f59e0b", danger: "#f43f5e", info: "#3b82f6" }, d = { ...c, bg: "#fff7ed", bgSoft: "#fffdf8", surface: "#ffffff", surfaceMuted: "#f8fafc", surfaceElevated: "rgba(255, 255, 255, 0.9)", surfaceOverlay: "rgba(255, 255, 255, 0.78)", border: "#e5e7eb", borderMuted: "rgba(226, 232, 240, 0.74)", text: "#1e293b", textMuted: "#64748b", textSubtle: "#94a3b8", icon: "#64748b" }, u = { ...c, bg: "#050b14", bgSoft: "#0b1220", surface: "#0a1120", surfaceMuted: "rgba(255, 255, 255, 0.04)", surfaceElevated: "rgba(15, 23, 42, 0.92)", surfaceOverlay: "rgba(255, 255, 255, 0.06)", border: "#1f2937", borderMuted: "rgba(30, 41, 59, 0.78)", text: "#e2e8f0", textMuted: "#94a3b8", textSubtle: "#64748b", icon: "#cbd5e1" }, T = we(e === "dark" ? u : d, o.color), _ = we(ts, o.layout), v = we( { focus: `0 0 0 2px ${J(a, 0.22)}`, header: e === "dark" ? "0 4px 20px rgba(0, 0, 0, 0.2)" : `0 4px 20px ${J(a, 0.06)}`, sidebar: e === "dark" ? "4px 0 24px rgba(0, 0, 0, 0.2)" : "4px 0 24px rgba(15, 23, 42, 0.03)", card: e === "dark" ? "none" : "0 14px 40px rgba(15, 23, 42, 0.06)", menuActive: `0 4px 12px ${J(a, e === "dark" ? 0.16 : 0.25)}` }, o.shadow ); return { mode: e, color: T, layout: _, shadow: v }; }, as = (e) => ({ "--primary-color": e.color.primary, "--primary-color-400": e.color.primaryHover, "--primary-color-600": e.color.primaryPressed, "--bag-color-primary": e.color.primary, "--bag-color-primary-hover": e.color.primaryHover, "--bag-color-primary-pressed": e.color.primaryPressed, "--bag-color-primary-suppl": e.color.primarySuppl, "--bag-color-primary-rgb": ss(e.color.primary), "--bag-color-primary-soft": e.color.primarySoft, "--bag-color-primary-softer": e.color.primarySofter, "--bag-color-accent": e.color.accent, "--bag-color-accent-hover": e.color.accentHover, "--bag-color-accent-soft": e.color.accentSoft, "--bag-color-success": e.color.success, "--bag-color-warning": e.color.warning, "--bag-color-danger": e.color.danger, "--bag-color-info": e.color.info, "--bag-color-bg": e.color.bg, "--bag-color-bg-soft": e.color.bgSoft, "--bag-color-surface": e.color.surface, "--bag-color-surface-muted": e.color.surfaceMuted, "--bag-color-surface-elevated": e.color.surfaceElevated, "--bag-color-surface-overlay": e.color.surfaceOverlay, "--bag-color-border": e.color.border, "--bag-color-border-muted": e.color.borderMuted, "--bag-color-text": e.color.text, "--bag-color-text-muted": e.color.textMuted, "--bag-color-text-subtle": e.color.textSubtle, "--bag-color-icon": e.color.icon, "--bag-layout-header-height": e.layout.headerHeight, "--bag-layout-sidebar-width": e.layout.sidebarWidth, "--bag-layout-sidebar-collapsed-width": e.layout.sidebarCollapsedWidth, "--bag-layout-content-max-width": e.layout.contentMaxWidth, "--bag-radius-sm": e.layout.radiusSm, "--bag-radius-md": e.layout.radiusMd, "--bag-radius-lg": e.layout.radiusLg, "--bag-radius-xl": e.layout.radiusXl, "--bag-shadow-focus": e.shadow.focus, "--bag-shadow-header": e.shadow.header, "--bag-shadow-sidebar": e.shadow.sidebar, "--bag-shadow-card": e.shadow.card, "--bag-shadow-menu-active": e.shadow.menuActive }), rs = (e, t = document.documentElement) => { const o = as(e); Object.entries(o).forEach(([a, i]) => { t.style.setProperty(a, i); }); }, ns = [ { name: "默认橘", value: "#f97316", colorClass: "bg-orange-500" }, { name: "科技蓝", value: "#3b82f6", colorClass: "bg-blue-500" }, { name: "护眼绿", value: "#10b981", colorClass: "bg-emerald-500" }, { name: "浪漫紫", value: "#8b5cf6", colorClass: "bg-violet-500" }, { name: "玫瑰红", value: "#f43f5e", colorClass: "bg-rose-500" } ], ls = "#f97316", ce = [ { key: "default", name: "默认后台", description: "适合日常后台管理,保留完整导航与标签栏。", theme: "light", themeColor: "#f97316", contentWidth: "fluid", showTabBar: !0, showFooter: !0, enablePageTransition: !0, menuCollapsed: !1, enableTabCache: !0, enableTabPersist: !0 }, { key: "compact", name: "紧凑工作台", description: "更聚焦内容区,适合高频操作与数据录入。", theme: "light", themeColor: "#3b82f6", contentWidth: "fluid", showTabBar: !0, showFooter: !1, enablePageTransition: !1, menuCollapsed: !0, enableTabCache: !0, enableTabPersist: !0 } ], is = (e) => ce.find((t) => t.key === e), be = ue("app-config", { state: () => ({ presetKey: K("bag.layout.presetKey", "default"), theme: K("bag.theme", "light"), themeColor: K("bag.themeColor", ls), contentWidth: K("bag.layout.contentWidth", "fluid"), showTabBar: K("bag.layout.showTabBar", !0), showFooter: K("bag.layout.showFooter", !0), enablePageTransition: K("bag.layout.enablePageTransition", !0), settingsDrawerOpen: !1 }), getters: { isDarkTheme: (e) => e.theme === "dark", themeTokens: (e) => os(e.theme, e.themeColor) }, actions: { ensureValidPresetKey() { if (this.presetKey === "custom") return; ce.some((t) => t.key === this.presetKey) || (this.presetKey = "default"); }, syncPresetState() { if (this.ensureValidPresetKey(), this.presetKey === "custom") return; const e = is(this.presetKey); e && (this.theme = e.theme, this.themeColor = e.themeColor, this.contentWidth = e.contentWidth, this.showTabBar = e.showTabBar, this.showFooter = e.showFooter, this.enablePageTransition = e.enablePageTransition); }, markAsCustom() { this.presetKey = "custom"; }, setTheme(e) { this.markAsCustom(), this.theme = e, this.applyThemeClass(), this.applyThemeColorVariables(); }, toggleTheme() { this.setTheme(this.theme === "light" ? "dark" : "light"); }, setThemeColor(e) { this.markAsCustom(), this.themeColor = e, this.applyThemeColorVariables(); }, setContentWidth(e) { this.markAsCustom(), this.contentWidth = e; }, setShowTabBar(e) { this.markAsCustom(), this.showTabBar = e; }, setShowFooter(e) { this.markAsCustom(), this.showFooter = e; }, setEnablePageTransition(e) { this.markAsCustom(), this.enablePageTransition = e; }, setPresetKey(e) { this.presetKey = e; }, openSettingsDrawer() { this.settingsDrawerOpen = !0; }, closeSettingsDrawer() { this.settingsDrawerOpen = !1; }, resetAppearance() { this.presetKey = "default", this.applyAppearance(); }, applyAppearance() { this.syncPresetState(), this.applyThemeClass(), this.applyThemeColorVariables(); }, applyThemeClass() { typeof document > "u" || (this.theme === "dark" ? document.documentElement.classList.add("dark") : document.documentElement.classList.remove("dark")); }, applyThemeColorVariables() { typeof document > "u" || rs(this.themeTokens); } } }), cs = { title: "Vue Bag Admin", compactTitle: "VBA", logoAlt: "Vue Bag Admin", homePath: "/dashboard", showTitle: !0 }, ds = [ { key: "notify", label: "通知", emptyText: "暂无新通知" }, { key: "system", label: "系统", emptyText: "暂无系统消息" }, { key: "todo", label: "待办", emptyText: "暂无待办事项" } ], us = () => ({ notify: [ { id: 1, title: "有一条新的待处理通知", time: "10分钟前", type: "notice", read: !1, icon: "🔔", color: "bg-orange-100 dark:bg-orange-500/20 text-orange-500" }, { id: 2, title: "系统检测到一项配置需要确认", time: "1小时前", type: "warning", read: !1, icon: "⚠️", color: "bg-rose-100 dark:bg-rose-500/20 text-rose-500" }, { id: 3, title: "本周运行摘要已生成", time: "昨天", type: "success", read: !0, icon: "✅", color: "bg-green-100 dark:bg-green-500/20 text-green-500" } ], system: [ { id: 1, title: "系统升级通知:今晚凌晨2点进行停机维护", time: "2天前", type: "system", read: !0, icon: "🔔", color: "bg-blue-100 dark:bg-blue-500/20 text-blue-500" } ], todo: [] }), hs = () => { const e = us(); return { tabs: ds.map((t) => ({ ...t })), getList: (t) => (e[t] ?? []).map((o) => ({ ...o })), getUnreadCount: () => Object.values(e).flat().filter((t) => !t.read).length, markAllRead: (t) => { (e[t] ?? []).forEach((o) => { o.read = !0; }); } }; }, Je = Symbol("bag-host-ui-config"); function Qe(e) { var a; const t = hs(), o = z(); return { branding: { ...cs, homePath: o.homePath, ...e == null ? void 0 : e.branding }, messageCenter: { ...t, ...e == null ? void 0 : e.messageCenter, tabs: (a = e == null ? void 0 : e.messageCenter) != null && a.tabs && e.messageCenter.tabs.length > 0 ? e.messageCenter.tabs : t.tabs }, slots: { ...e == null ? void 0 : e.slots } }; } function ps(e, t) { e.provide(Je, Qe(t)); } function bs() { return ft(Je, Qe()); } const fs = { class: "app-layout min-h-screen relative overflow-hidden font-sans transition-colors duration-300" }, gs = { class: "bag-app-header backdrop-blur-xl border-b flex justify-between items-center shrink-0 relative z-20 px-4 md:px-6 transition-colors duration-300" }, ms = { class: "flex items-center h-full" }, vs = { class: "bag-brand-logo" }, ys = ["src", "alt"], ws = { key: 1, viewBox: "0 0 24 24", class: "h-6 w-6 text-white", fill: "currentColor" }, xs = { key: 0, class: "bag-brand-copy" }, ks = { class: "bag-brand-title" }, Cs = { key: 0, class: "bag-brand-badge" }, Ps = { class: "hidden md:flex items-center text-sm font-bold" }, Ts = { class: "bag-current-menu-pill flex items-center gap-2 px-3 py-1.5 rounded-full border transition-colors duration-300" }, _s = { class: "bag-header-actions text-slate-500 dark:text-slate-400 font-medium" }, Ms = { class: "bg-white dark:bg-[#0A1120] flex flex-col" }, As = { class: "max-h-[300px] overflow-y-auto custom-scrollbar" }, $s = { key: 0, class: "flex items-center justify-center py-10 text-sm text-slate-400 dark:text-slate-500" }, Ss = { key: 1, class: "flex flex-col" }, Bs = ["onClick"], Ls = { key: 0, class: "bag-notice-unread-dot absolute left-2 top-1/2 -translate-y-1/2 w-1.5 h-1.5 rounded-full" }, Vs = { class: "text-lg" }, Es = { class: "flex-1 min-w-0" }, Hs = { class: "bag-notice-title text-sm line-clamp-2 leading-snug transition-colors" }, Rs = { key: 0, class: "text-xs text-slate-400 dark:text-slate-500 mt-1" }, js = { key: 2, class: "py-10" }, Ks = { class: "bag-header-action" }, Ds = { class: "bag-header-action-label hidden md:inline" }, Is = { class: "bag-header-action-icon" }, Os = { key: 0, xmlns: "http://www.w3.org/2000/svg", class: "h-4 w-4", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round" }, zs = { key: 1, xmlns: "http://www.w3.org/2000/svg", class: "h-4 w-4", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round" }, Ns = { class: "bag-user-entry" }, Us = { class: "font-bold text-slate-700 dark:text-slate-200" }, Ws = { class: "flex h-[calc(100vh-64px)] relative z-10" }, Fs = { class: "flex-1 overflow-y-auto custom-scrollbar p-3" }, Zs = { class: "flex-1 flex flex-col min-w-0 overflow-hidden bg-transparent" }, Xs = { class: "flex-1 overflow-auto custom-scrollbar relative flex flex-col" }, Ys = { key: 0, class: "bag-layout-footer py-4 text-center text-sm border-t mt-auto" }, Gs = /* @__PURE__ */ ee({ __name: "DefaultLayout", setup(e) { const { locale: t, fallbackLocale: o, messages: a, t: i } = Me(), c = Se(), d = he(), u = be(), T = bs(), _ = $e(), v = Ae(), M = z(), A = O("notify"), j = O(!1), $ = O(!1), D = O(0), B = O({}), P = jt(Kt).smaller("md"); gt(() => { P.value && c.setCollapsed(!0); }); const f = S(() => c.collapsed), p = S(() => T.branding), I = S(() => T.messageCenter), ne = S(() => I.value.tabs), W = S(() => T.slots.brand), le = S(() => { var r; const n = (r = p.value.compactTitle) == null ? void 0 : r.trim(); return P.value && n ? n : p.value.title; }); Ce( ne, (n) => { var r; n.some((l) => l.key === A.value) || (A.value = ((r = n[0]) == null ? void 0 : r.key) ?? "notify"); }, { immediate: !0 } ), Ce(A, (n) => { j.value && se(n); }); const G = (n) => B.value[n] ?? [], te = (n) => n.key === "notify" && D.value > 0 ? `${n.label} (${D.value})` : n.label, se = async (n) => { var r, l; $.value = !0; try { const x = await Promise.resolve(((l = (r = I.value).getList) == null ? void 0 : l.call(r, n)) ?? []); B.value = { ...B.value, [n]: x ?? [] }; } catch (x) { console.error("[bag-host] failed to load message list:", x), B.value = { ...B.value, [n]: [] }; } finally { $.value = !1; } }, oe = async () => { var n, r; try { D.value = await Promise.resolve( ((r = (n = I.value).getUnreadCount) == null ? void 0 : r.call(n)) ?? Object.values(B.value).flat().filter((l) => !l.read).length ); } catch (l) { console.error("[bag-host] failed to load unread count:", l), D.value = 0; } }, fe = (n) => { j.value = n, n && Promise.all([se(A.value), oe()]); }, ge = (n, r) => { const l = G(r).map( (x) => x.id === n ? { ...x, read: !0 } : x ); B.value = { ...B.value, [r]: l }; }, b = async () => { var r, l; const n = A.value; await Promise.resolve((l = (r = I.value).markAllRead) == null ? void 0 : l.call(r, n)), await se(n), await oe(); }, g = async (n, r) => { var l, x; n.read || (ge(n.id, r), await oe()), await Promise.resolve((x = (l = I.value).onItemClick) == null ? void 0 : x.call(l, n, r)); }, y = async () => { var n, r; await Promise.resolve((r = (n = I.value).onViewAll) == null ? void 0 : r.call(n, A.value)); }, C = S(() => { var r; const n = (r = v.meta) == null ? void 0 : r.activeMenu; return typeof n == "string" ? n : v.path; }), X = (n) => [...n].sort((r, l) => (r.sort ?? 0) - (l.sort ?? 0)), st = (n) => n.hidden ? !1 : pe({ roles: n.roles, permissions: n.permissions }), Le = (n) => X(n).map((r) => { const l = r.children ? Le(r.children) : void 0; return { ...r, children: l }; }).filter((r) => { var l; return st(r) ? ((l = r.children) != null && l.length, !0) : !1; }), Ve = [ { path: M.homePath, title: "menu.dashboard", icon: "dashboard" } ], ot = (n) => !!n && /^[A-Za-z0-9_-]+(?:\.[A-Za-z0-9_-]+)+$/.test(n), at = () => { const n = [t.value], r = o.value; if (typeof r == "string") n.push(r); else if (Array.isArray(r)) n.push(...r); else if (r && typeof r == "object") { const l = r[t.value]; typeof l == "string" ? n.push(l) : Array.isArray(l) && n.push(...l); const x = r.default; typeof x == "string" ? n.push(x) : Array.isArray(x) && n.push(...x); } return [...new Set(n.filter(Boolean))]; }, rt = (n, r) => { var x; let l = (x = a.value) == null ? void 0 : x[n]; for (const F of r.split(".")) { if (!l || typeof l != "object" || !(F in l)) return; l = l[F]; } return typeof l == "string" ? l : void 0; }, me = (n) => { if (!n) return ""; if (!ot(n)) return n; for (const r of at()) { const l = rt(r, n); if (l) return l; } return n; }, nt = S(() => { var x; const n = [...Ve, ...c.menus], r = (F, Ee) => { for (const ie of F) { if (ie.path === Ee) return ie.title; if (ie.children) { const He = r(ie.children, Ee); if (He) return He; } } }, l = r(n, C.value); return l ? me(l) : (x = v.meta) != null && x.title ? me(v.meta.title) : ""; }), lt = S(() => { const n = (l) => { var F; const x = me(l.title); return { key: l.path, label: () => k("div", { class: "bag-menu-option-label" }, [ k("span", { class: "bag-menu-option-text" }, x || l.title), l.badge ? k( "span", { class: "bag-menu-badge" }, l.badge ) : null ]), icon: Nt(l.icon), children: (F = l.children) == null ? void 0 : F.map(n) }; }, r = [...Ve, ...c.menus]; return Le(r).map(n); }), it = [ { label: "中文", key: "zh-CN" }, { label: "English", key: "en" } ], ct = (n) => { t.value = n, localStorage.setItem("lang", n); }, dt = S(() => [ { label: i("sysSetting.profile") || "个人中心", key: "profile" }, { label: i("sysSetting.logout") || "退出登录", key: "logout" } ]), ut = (n) => { n === "profile" ? _.push(M.profilePath) : n === "logout" && bt(); }, ht = (n) => { if (n.startsWith("http://") || n.startsWith("https://")) { window.open(n, "_blank", "noopener,noreferrer"); return; } _.push(n), P.value && c.setMobileDrawer(!1); }, pt = () => { const n = p.value.homePath; !n || v.path === n || _.push(n); }, bt = () => { d.logout(), _.push(M.loginPath); }; return (n, r) => (m(), w("div", fs, [ r[22] || (r[22] = s("div", { class: "bag-workspace-accent bag-workspace-accent--primary absolute top-0 right-0 w-96 h-96 rounded-full blur-[100px] pointer-events-none transition-colors duration-300" }, null, -1)), r[23] || (r[23] = s("div", { class: "bag-workspace-accent bag-workspace-accent--accent absolute bottom-0 left-0 w-96 h-96 rounded-full blur-[100px] pointer-events-none transition-colors duration-300" }, null, -1)), s("header", gs, [ s("div", ms, [ h(P) ? (m(), w("button", { key: 0, onClick: r[0] || (r[0] = (l) => h(c).toggleMobileDrawer()), class: "bag-mobile-menu-btn p-2 -ml-2 mr-2 rounded-xl transition-colors md:hidden" }, [...r[7] || (r[7] = [ s("svg", { xmlns: "http://www.w3.org/2000/svg", class: "h-6 w-6", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor" }, [ s("path", { "stroke-linecap": "round", "stroke-linejoin": "round", "stroke-width": "2", d: "M4 6h16M4 12h16M4 18h16" }) ], -1) ])])) : E("", !0), W.value ? (m(), U(Pe(W.value), { key: 1, class: "bag-brand-slot" })) : (m(), w("button", { key: 2, class: V(["bag-brand group", { "is-static": !p.value.homePath }]), type: "button", onClick: pt }, [ s("span", vs, [ p.value.logo ? (m(), w("img", { key: 0, src: p.value.logo, alt: p.value.logoAlt || p.value.title, class: "bag-brand-logo-image" }, null, 8, ys)) : (m(), w("svg", ws, [...r[8] || (r[8] = [ s("path", { d: "M16 6V4a2 2 0 0 0-2-2h-4a2 2 0 0 0-2 2v2H4a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-4zm-6-2h4v2h-4V4zm10 14H4V8h16v10z" }, null, -1), s("path", { d: "M9 10a1 1 0 0 0-1 1v2a1 1 0 0 0 2 0v-2a1 1 0 0 0-1-1zm6 0a1 1 0 0 0-1 1v2a1 1 0 0 0 2 0v-2a1 1 0 0 0-1-1z" }, null, -1) ])])) ]), p.value.showTitle ? (m(), w("span", xs, [ s("span", ks, L(le.value), 1), p.value.badge ? (m(), w("span", Cs, L(p.value.badge), 1)) : E("", !0) ])) : E("", !0) ], 2)), r[9] || (r[9] = s("div", { class: "hidden md:block w-px h-6 bg-gray-200 dark:bg-gray-700 mx-6 transition-colors duration-300" }, null, -1)), s("div", Ps, [ s("div", Ts, L(nt.value || "工作台"), 1) ]) ]), s("div", _s, [ s("div", { class: "bag-header-action hidden sm:flex", onClick: r[1] || (r[1] = (l) => h(_).push(h(M).homePath)) }, [...r[10] || (r[10] = [ je('<div class="bag-header-action-icon"><svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m3 9 9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"></path><polyline points="9 22 9 12 15 12 15 22"></polyline></svg></div><span class="bag-header-action-label hidden lg:inline">首页</span>', 2) ])]), H(h(At), { trigger: "click", placement: "bottom-end", width: 320, style: { padding: "0", "border-radius": "12px", overflow: "hidden" }, "onUpdate:show": fe }, { trigger: R(() => [...r[11] || (r[11] = [ s("div", { class: "bag-header-action hidden sm:flex relative" }, [ s("div", { class: "bag-header-action-icon" }, [ s("svg", { xmlns: "http://www.w3.org/2000/svg", class: "h-4 w-4", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round" }, [ s("path", { d: "M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9" }), s("path", { d: "M13.73 21a2 2 0 0 1-3.46 0" }) ]) ]), s("span", { class: "bag-header-action-label hidden lg:inline" }, "消息") ], -1) ])]), default: R(() => [ s("div", Ms, [ s("div", { class: "px-4 py-3 flex justify-between items-center border-b border-gray-100 dark:border-gray-800" }, [ r[12] || (r[12] = s("span", { class: "font-bold text-slate-700 dark:text-slate-200" }, "消息通知", -1)), s("button", { type: "button", class: "bag-notice-action", onClick: b }, " 全部已读 ") ]), H(h($t), { value: A.value, "onUpdate:value": r[2] || (r[2] = (l) => A.value = l), type: "line", "justify-content": "space-evenly", class: "mt-1", "pane-style": "padding: 0;" }, { default: R(() => [ (m(!0), w(Q, null, q(ne.value, (l) => (m(), U(h(St), { key: l.key, name: l.key, tab: te(l) }, { default: R(() => [ s("div", As, [ $.value ? (m(), w("div", $s, " 消息加载中... ")) : G(l.key).length > 0 ? (m(), w("div", Ss, [ (m(!0), w(Q, null, q(G(l.key), (x) => (m(), w("div", { key: x.id, class: V(["bag-notice-item px-4 py-3 cursor-pointer transition-colors flex gap-3 group relative", { "opacity-60": x.read }]), onClick: (F) => g(x, l.key) }, [ x.read ? E("", !0) : (m(), w("div", Ls)), s("div", { class: V(["w-10 h-10 rounded-full flex items-center justify-center shrink-0", x.color]) }, [ s("span", Vs, L(x.icon || "🔔"), 1) ], 2), s("div", Es, [ s("p", Hs, L(x.title), 1), x.time ? (m(), w("p", Rs, L(x.time), 1)) : E("", !0) ]) ], 10, Bs))), 128)) ])) : (m(), w("div", js, [ H(h(Bt), { description: l.emptyText || `暂无${l.label}` }, null, 8, ["description"]) ])) ]) ]), _: 2 }, 1032, ["name", "tab"]))), 128)) ]), _: 1 }, 8, ["value"]), s("div", { class: "border-t border-gray-100 dark:border-gray-800 p-2" }, [ s("button", { type: "button", class: "bag-notice-footer-btn", onClick: y }, " 查看全部消息 ") ]) ]) ]), _: 1 }), H(h(Te), { trigger: "click", options: it, onSelect: ct }, { default: R(() => [ s("div", Ks, [ r[13] || (r[13] = s("div", { class: "bag-header-action-icon" }, [ s("svg", { xmlns: "http://www.w3.org/2000/svg", class: "h-4 w-4", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round" }, [ s("circle", { cx: "12", cy: "12", r: "10" }), s("path", { d: "M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z" }), s("path", { d: "M2 12h20" }) ]) ], -1)), s("span", Ds, L(h(t) === "en" ? "EN" : "中"), 1) ]) ]), _: 1 }), s("div", { class: "bag-header-action bag-header-action--icon", onClick: r[3] || (r[3] = (l) => h(u).toggleTheme()) }, [ s("div", Is, [ h(u).theme === "light" ? (m(), w("svg", Os, [...r[14] || (r[14] = [ je('<circle cx="12" cy="12" r="5"></circle><line x1="12" y1="1" x2="12" y2="3"></l