Files
console-dev/app/pages/resources.vue
T

271 lines
9.3 KiB
Vue

<script>
/**
* 资源中心:帮助、新闻和公告的可访问标签容器;支持 section 参数和后端 plugin 参数,参数解析完成后再挂载对应内容页。
*/
import "~/assets/styles/notices.BXNGOj-Q.css";
import "~/assets/styles/news.CbIzdrjt.css";
import "~/assets/styles/help.BSOB30LE.css";
import "~/assets/styles/resources._aUrMsvM.css";
import { toDisplayString } from "vue";
import { renderList } from "vue";
import { onMounted } from "vue";
import { normalizeClass } from "vue";
import { onBeforeUnmount } from "vue";
import { watch } from "vue";
import { createBlock } from "vue";
import { ref } from "vue";
import { withCtx } from "vue";
import { createCommentVNode } 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 { useRoute } from "#app";
import { useRouter } from "#app";
import { navigateTo } from "#app";
import { useApi } from "~/lib/auth.js";
import button from "primevue/button";
import { t as _plugin_vue_export_helper_t } from "~/lib/_plugin-vue_export-helper.js";
import message from "primevue/message";
import skeleton from "primevue/skeleton";
import { n as content_route_n } from "~/lib/content-route.js";
import { r as content_route_r } from "~/lib/content-route.js";
import help from "~/pages/help.vue";
import news from "~/pages/news.vue";
import index from "~/pages/notices/index.vue";
var j = {
class: `resources-page`,
},
M = {
class: `page-head`,
},
N = {
class: `resource-tabs`,
role: `tablist`,
"aria-label": `资源分类`,
},
P = [
`id`,
`aria-selected`,
`aria-controls`,
`tabindex`,
`onClick`,
`onKeydown`,
],
F = [`id`, `aria-labelledby`],
I = _plugin_vue_export_helper_t(
defineComponent({
__name: `resources`,
setup(h) {
let C = useRoute(),
I = useRouter(),
L = useApi(),
R = ref(null),
z = ref(``),
B = ref(!1),
V = [
{
value: `help`,
label: `帮助文档`,
},
{
value: `news`,
label: `新闻资讯`,
},
{
value: `notices`,
label: `平台公告`,
},
],
H = 0;
// 优先解析 section;只有 plugin 入口才读取插件清单,并用请求代次隔离连续路由切换。
async function U() {
let e = ++H;
((z.value = ``), (R.value = null), (B.value = !0));
try {
if (C.query.section !== void 0)
R.value = content_route_r(C.query.section);
else if (C.query.plugin !== void 0) {
let t = await L.get(`/plugin`);
if (e !== H) return;
R.value = content_route_n(C.query.plugin, t.list ?? []);
} else R.value = `help`;
R.value || (z.value = `资源入口无效或插件未启用,请重新选择分类`);
} catch (t) {
e === H &&
(z.value = t instanceof Error ? t.message : `资源分类加载失败`);
} finally {
e === H && (B.value = !1);
}
}
// 切换分类同时写入 /resources 的 section 查询参数,保持刷新与分享地址可恢复。
function W(e) {
((R.value = e),
I.push({
path: `/resources`,
query: {
section: e,
},
}));
}
(onMounted(U),
watch(() => [C.query.section, C.query.plugin], U),
onBeforeUnmount(() => {
H++;
}));
// 标签按左右方向键循环切换,Home/End 跳至首尾,并同步焦点到新标签。
function G(e, t) {
let n = t;
if (e.key === `ArrowRight`) n = (t + 1) % V.length;
else if (e.key === `ArrowLeft`) n = (t + V.length - 1) % V.length;
else if (e.key === `Home`) n = 0;
else if (e.key === `End`) n = V.length - 1;
else return;
(e.preventDefault(),
W(V[n].value),
document.getElementById(`resource-tab-${V[n].value}`)?.focus());
}
// 标签使用稳定 ID 关联 tab/panel,解析分类后才挂载对应页面,避免非法参数触发错误内容入口。
return (n, i) => {
let a = button,
s = skeleton,
h = message;
return (
openBlock(),
createElementBlock(`div`, j, [
createElementVNode(`div`, M, [
(i[1] ||= createElementVNode(
`div`,
{
class: `page-heading`,
},
[
createElementVNode(`h2`, null, `资源中心`),
createElementVNode(`p`, null, `查找帮助文档与站点资讯`),
],
-1,
)),
unref(R) === `help`
? (openBlock(),
createBlock(a, {
key: 0,
label: `创建工单`,
icon: `pi pi-plus`,
severity: `secondary`,
outlined: ``,
onClick: (i[0] ||= (e) =>
(`navigateTo` in n ? n.navigateTo : unref(navigateTo))(
`/tickets/create`,
)),
}))
: createCommentVNode(``, !0),
]),
createElementVNode(`div`, N, [
(openBlock(),
createElementBlock(
Fragment,
null,
renderList(V, (t, n) =>
createElementVNode(
`button`,
{
id: `resource-tab-${t.value}`,
key: t.value,
type: `button`,
role: `tab`,
class: normalizeClass([
`resource-tab`,
{
active: unref(R) === t.value,
},
]),
"aria-selected": unref(R) === t.value,
"aria-controls": `resource-panel-${t.value}`,
tabindex: unref(R) === t.value ? 0 : -1,
onClick: (e) => W(t.value),
onKeydown: (e) => G(e, n),
},
toDisplayString(t.label),
43,
P,
),
),
64,
)),
]),
unref(B)
? (openBlock(),
createBlock(s, {
key: 0,
height: `120px`,
}))
: unref(z)
? (openBlock(),
createBlock(
h,
{
key: 1,
severity: `error`,
closable: !1,
},
{
default: withCtx(() => [
createTextVNode(toDisplayString(unref(z)), 1),
createVNode(a, {
label: `重试`,
text: ``,
onClick: U,
}),
]),
_: 1,
},
))
: unref(R)
? (openBlock(),
createElementBlock(
`div`,
{
key: 2,
id: `resource-panel-${unref(R)}`,
role: `tabpanel`,
"aria-labelledby": `resource-tab-${unref(R)}`,
class: `resource-content`,
},
[
unref(R) === `help`
? (openBlock(),
createBlock(help, {
key: 0,
embedded: ``,
}))
: unref(R) === `news`
? (openBlock(),
createBlock(news, {
key: 1,
embedded: ``,
}))
: (openBlock(),
createBlock(index, {
key: 2,
embedded: ``,
})),
],
8,
F,
))
: createCommentVNode(``, !0),
])
);
};
},
}),
[[`__scopeId`, `data-v-7390ef3e`]],
);
export {};
export default I;
</script>