92 lines
2.7 KiB
JavaScript
92 lines
2.7 KiB
JavaScript
/** 工单附件展示适配;文件名、存储名与可访问 URL 分开,不把存储键直接当链接。 */
|
|
// 允许 HTTP(S) 和显式相对路径,拒绝控制字符、反斜杠及脚本/data 等协议。
|
|
function e(e) {
|
|
if (
|
|
!/^(?:https?:\/\/|\/(?!\/)|\.\.?\/)/i.test(e) ||
|
|
/[\u0000-\u001f\u007f\\]/.test(e)
|
|
)
|
|
return !1;
|
|
try {
|
|
let t = new URL(e, `https://attachment.invalid/`);
|
|
return t.protocol === `http:` || t.protocol === `https:`;
|
|
} catch {
|
|
return !1;
|
|
}
|
|
}
|
|
// 仅在地址合法且文件名为支持的位图扩展名时启用图片预览,SVG 不走内嵌预览。
|
|
function t(t) {
|
|
return (
|
|
!!t.href &&
|
|
e(t.href) &&
|
|
/\.(?:avif|bmp|gif|ico|jpe?g|png|webp)$/i.test(t.name)
|
|
);
|
|
}
|
|
// 历史存储名使用 ^ 分隔前缀,展示时取末段;URI 解码失败仍保留可读的原名。
|
|
function n(e, t) {
|
|
let n =
|
|
e
|
|
.split(`/`)
|
|
.at(-1)
|
|
?.split(/\^|%5e/i)
|
|
.at(-1) || t;
|
|
try {
|
|
n = decodeURIComponent(n);
|
|
} catch {}
|
|
return n.split(`^`).at(-1) || t;
|
|
}
|
|
/** 兼容字符串及对象附件;无地址仍保留名称/存储名和明确占位,不伪造下载链接。 */
|
|
function r(t) {
|
|
return Array.isArray(t)
|
|
? t.map((t, r) => {
|
|
let i = `附件 ${r + 1}`,
|
|
a = t && typeof t == `object` && !Array.isArray(t) ? t : null;
|
|
if (
|
|
typeof t != `string` &&
|
|
(!a ||
|
|
![`url`, `name`, `save_name`].some((e) => typeof a[e] == `string`))
|
|
)
|
|
return {
|
|
name: `${i}(格式暂不支持)`,
|
|
href: null,
|
|
};
|
|
let o = typeof t == `string` ? t : a?.url,
|
|
s = typeof o == `string` ? o.trim() : ``,
|
|
c = typeof a?.name == `string` ? a.name.trim() : ``,
|
|
l = typeof a?.save_name == `string` ? a.save_name.trim() : ``,
|
|
u = c || (l ? n(l, i) : ``),
|
|
d =
|
|
l ||
|
|
(typeof o == `string` && !e(o) && !/[\\/:\u0000-\u001f]/.test(o)
|
|
? o
|
|
: ``),
|
|
f = {
|
|
name: u || (d ? n(d, i) : `${i}(地址不可用)`),
|
|
href: null,
|
|
...(d
|
|
? {
|
|
storageName: d,
|
|
}
|
|
: {}),
|
|
};
|
|
if (!e(s)) return f;
|
|
try {
|
|
let e = new URL(s, `https://attachment.invalid/`);
|
|
return e.protocol !== `http:` && e.protocol !== `https:`
|
|
? f
|
|
: {
|
|
name: u || n(e.pathname, i),
|
|
href: s,
|
|
...(d
|
|
? {
|
|
storageName: d,
|
|
}
|
|
: {}),
|
|
};
|
|
} catch {
|
|
return f;
|
|
}
|
|
})
|
|
: [];
|
|
}
|
|
export { r as n, t };
|