docs: explain navigation, search and content components

This commit is contained in:
cieanyau committed 2026-11-06 00:37:46 +08:00
1 parent 2ff311005e
commit 179c6febf0
10 files changed
+34

No files matched your search

+3
View File
@@ -1,4 +1,5 @@
<script>
// 渲染后台配置的单个导航项:递归匹配子路由,并区分直接跳转与需要确认的外链。
import "~/assets/styles/BackendNavEntry.Bx6IPica.css";
import { toDisplayString } from "vue";
import { renderList } from "vue";
@@ -68,6 +69,7 @@ var T = {
R = useRoute(),
z = `configured-nav-${useId()}`,
B = ref(null);
// 按同级路径规则查找活动后代,使当前路由所在的分组默认展开。
function V(e) {
let t = e
.filter((e) => e.to)
@@ -97,6 +99,7 @@ var T = {
),
G = ref(!1),
K;
// 有确认标记的入口先保存跳转回调,用户确认后才执行导航或打开新窗口。
function q(e, t) {
if (!w.entry.confirm) {
t && (e.preventDefault(), t());
+2
View File
@@ -1,4 +1,5 @@
<script>
// 加载共享导航状态并渲染菜单;仅在组件仍挂载且已加载完成时向布局通知结果。
import "~/assets/styles/BackendNavEntry.Bx6IPica.css";
import "~/assets/styles/BackendNavigation.CEj4LnzI.css";
import { renderList } from "vue";
@@ -45,6 +46,7 @@ var y = {
onBeforeUnmount(() => {
O = !1;
});
// 已有错误时允许重新加载;把是否为后台权威配置一并交给父级判断。
async function k() {
(await C.load(!!E.value),
O && D.value && x(`loaded`, w.value, C.authoritative.value));
+4
View File
@@ -1,4 +1,5 @@
<script>
// 全局搜索同时展示实例与商品结果,负责输入防抖、过期请求失效和结果跳转。
import "~/assets/styles/GlobalSearch.BQqObidy.css";
import { toDisplayString } from "vue";
import { renderList } from "vue";
@@ -84,6 +85,7 @@ var w = {
W = null,
G = 0,
K = !1;
// 取消待执行的防抖任务并递增代次,已发出的旧请求也不能更新当前结果。
function q() {
(W !== null && clearTimeout(W),
(W = null),
@@ -93,6 +95,7 @@ var w = {
function J(e = !1) {
(q(), e && H.value?.focus(), (L.value = !1));
}
// 搜索使用去空白关键词;只有当前代次且组件未卸载时才写入结果或错误。
async function Y() {
if ((q(), K)) return;
let e = G,
@@ -117,6 +120,7 @@ var w = {
e === G && !K && (R.value = !1);
}
}
// 每次输入先关闭旧结果,停顿 300ms 后再查询,避免逐字符请求。
function X() {
(J(),
(B.value = null),
+3
View File
@@ -1,4 +1,5 @@
<script>
// 操作系统图标依次尝试显式地址、图标地址和内置映射,加载失败后切换下一候选。
import "~/assets/styles/OsIcon.CAi4Iz2S.css";
import { watch } from "vue";
import { createBlock } from "vue";
@@ -37,6 +38,7 @@ var f = [`src`, `width`, `height`],
flush: `sync`,
},
);
// 仅接收站内绝对路径或无认证信息的 HTTP(S) 地址,拒绝控制字符和反斜杠。
function m(e) {
let t = String(e ?? ``).trim();
if (!t || /[\u0000-\u0020\u007f\\]/.test(t)) return ``;
@@ -68,6 +70,7 @@ var f = [`src`, `width`, `height`],
? `lucide:hard-drive`
: `lucide:terminal`,
);
// 只记录当前候选的失败事件,避免前一张图片的迟到事件污染新图标。
function v(e) {
let t = e.target?.getAttribute(`src`);
t && t === g.value && p.value.push(t);
@@ -1,4 +1,5 @@
<script>
// 商品卡片配置摘要:从各模块的默认可售配置中提取 CPU、内存、磁盘和网络信息。
import "~/assets/styles/ProductConfigurationSummary.BqZns1LB.css";
import { toDisplayString } from "vue";
import { renderList } from "vue";
@@ -32,6 +33,7 @@ function S(e) {
let n = Number(t);
return Number.isFinite(n) && n > 0 ? n : void 0;
}
// 将不同后台使用的资源标签归类;未识别的营销文字不参与硬件摘要推断。
function C(e) {
let t = e.trim().replace(/\s+/g, ``).toLowerCase();
if (/^(cpu|处理器|cpu核心|cpu核数|核心数)$/.test(t)) return `cpu`;
@@ -79,6 +81,7 @@ function E(e, t) {
o = /^g/i.test(n[3]) ? `Gbps` : /^k/i.test(n[3]) ? `Kbps` : `Mbps`;
return `${i}${a}${Number(n[2])}${o}`;
}
// 按资源类型格式化并去重,方向不同且数值不同的带宽保留上/下行标记。
function D(e) {
let t = ``,
n = ``,
@@ -153,6 +156,7 @@ function A(e, t, n = ``) {
value: S(t) === void 0 ? `` : `${Number(t)}${n}`,
};
}
// 按真实订单模块读取配置;含级联或高级限制且无法安全推导默认值时不生成摘要。
async function j(e, t) {
if (!product_name_t(t.name)) return [];
let n = (t, n) => e.get(t, n, !1, y);
@@ -354,6 +358,7 @@ var M = {
}),
y = 0;
return (
// 外部 summary 优先;商品变化时清空旧摘要,用序号隔离异步返回结果。
watch(
() => [
m.product.id,
+6
View File
@@ -1,4 +1,5 @@
<script>
// 安全展示商品介绍:简单的“标签:内容”转为信息块,复杂排版保留清洗后的富文本。
import "~/assets/styles/ProductDescription.Ctb7jDuO.css";
import { toDisplayString } from "vue";
import { renderList } from "vue";
@@ -100,6 +101,7 @@ var v = {
function S(e) {
return /<\/?[a-z][^>]*>|<!doctype\b[^>]*>|<!--/i.test(e);
}
// 处理历史数据中的实体编码,最多解码两轮,遇到实际 HTML 后停止继续解码。
function C(e) {
let t = e;
for (
@@ -117,6 +119,7 @@ function C(e) {
}
return t;
}
// 按块级元素、换行和表格单元格边界提取文本,避免直接 textContent 丢失段落结构。
function w(e, t, n = ``) {
let r = ``;
function i() {
@@ -166,6 +169,7 @@ function w(e, t, n = ``) {
)
.trim();
}
// 仅允许无属性的简单标签转成字段块;带格式或不符合标签语义的内容保留富文本。
function T(e, t) {
for (let n of Array.from(e.querySelectorAll(`*`))) {
let r = n.localName;
@@ -192,6 +196,7 @@ function T(e, t) {
}
return !0;
}
// 先做 HTML 清洗,再判断空内容与呈现模式;图片即使没有正文也不能被判为空。
function E(e) {
if (typeof e != `string` || !e.trim())
return {
@@ -311,6 +316,7 @@ var D = [`aria-label`],
v.value = !1;
},
);
// 以 Unicode 码点截断紧凑摘要,避免把代理对字符从中间切开。
function b(e, t) {
let n = Array.from(e);
return n.length > t ? `${n.slice(0, t).join(``)}…` : e;
+4
View File
@@ -1,4 +1,5 @@
<script>
// 轻量富文本输入:用浏览器编辑命令维护选区,并在模型输入/输出边界清洗 HTML。
import "~/assets/styles/RichTextEditor.NkmgPT5m.css";
import { renderList } from "vue";
import { onMounted } from "vue";
@@ -100,12 +101,14 @@ var g = [`aria-label`],
icon: `pi pi-align-right`,
},
];
// 仅保存编辑区域内的选区,点击工具栏后可恢复到用户原来的光标位置。
function S() {
let e = window.getSelection();
e?.rangeCount &&
y.value?.contains(e.anchorNode) &&
(b = e.getRangeAt(0).cloneRange());
}
// 空白正文输出空串,其余内容先清洗再同步 v-model,并更新当前选区。
function C() {
y.value &&
((m.value = y.value.innerText.trim()
@@ -125,6 +128,7 @@ var g = [`aria-label`],
(document.execCommand(e, !1), C());
}
}
// 粘贴只接收纯文本,阻止剪贴板 HTML 直接带入额外标签和属性。
function T(e) {
(e.preventDefault(),
!u.disabled &&
+1
View File
@@ -1,4 +1,5 @@
<script>
// 环形进度通过圆周长和描边偏移表达百分比,绘制时把输入限制在 0–100 范围。
import "~/assets/styles/RingProgress.CVwR7il5.css";
import { toDisplayString } from "vue";
import { createCommentVNode } from "vue";
+3
View File
@@ -1,4 +1,5 @@
<script>
// 工单附件列表提供图片预览与下载,受保护附件通过鉴权下载接口获取。
import "~/assets/styles/TicketAttachments.DtbJGLkE.css";
import { toDisplayString } from "vue";
import { renderList } from "vue";
@@ -85,6 +86,7 @@ var S = {
U = null,
W = ref({}),
G = ref(``);
// 已有直接链接的附件不重复请求;按文件名锁定下载状态,防止连续重复点击。
async function K(e) {
if (
!(e.href || !e.storageName || W.value[e.name]) &&
@@ -110,6 +112,7 @@ var S = {
}
}
}
// 只有附件工具判定可预览的项目才打开弹窗,并重置上一张图片的加载状态。
function q(e) {
ticketAttachments_t(e) &&
((y.value = e),
+3
View File
@@ -1,4 +1,5 @@
<script>
// 通用单文件上传字段:模型保存后台 save_name,界面另外保留用户选择的原始文件名。
import "~/assets/styles/UploadField.BbTCTv6C.css";
import { toDisplayString } from "vue";
import { mergeModels } from "vue";
@@ -64,6 +65,7 @@ var m = {
w = ref(!1),
T = ref(``),
E = ref(``);
// 上传结束后清空原生 input,允许再次选择同一文件;完整响应由 uploaded 事件交给调用方。
async function D(e) {
let t = e.target,
n = t.files?.[0];
@@ -79,6 +81,7 @@ var m = {
}
}
}
// 清除只是取消表单引用,不调用服务器删除文件接口。
function O() {
((p.value = ``), (E.value = ``));
}