feat: 书库导入导出/图片变体/书籍搜索/小组件运行时等

新增:
- 书库导入导出(library_import/library_export)及测试
- 图片变体生成(image_variants)与响应式图片(responsiveImage)
- 书籍搜索(bookSearch)+ BookSearch/LibrarySearchGrid 组件
- 小组件运行时(widgetRuntime)与静态检查(widgetLint)
- 上传缓存中间件(upload_cache)与字体 CSS 提取脚本

其它:
- 后端 handlers/services 全量调整
- 前端页面、组件、库函数与配置更新
This commit is contained in:
2026-10-01 03:06:05 +08:00
parent 7fbd6ba699
commit ff2ab286fb
141 changed files with 7527 additions and 1407 deletions

View File

@@ -1,4 +1,5 @@
import { brandLogoBox, type BrandLogoFit, type BrandLogoSize, type BrandMark } from "@/lib/brand";
import { densitySrcSet, isOwnImage, pickVariantWidth, variantURL } from "@/lib/responsiveImage";
/** 页眉品牌锁:图加文字 / 纯图 / 纯文字。图槽按画幅占位,铺法决定图怎么填进框。 */
export default function BrandLockup({
@@ -45,11 +46,11 @@ export default function BrandLockup({
{src ? (
both ? (
<>
<Logo src={logoLight} fit={fit} alt={label} decorative={showText} extra="j13-brand-logo-light" />
<Logo src={logoDark} fit={fit} alt={label} decorative={showText} extra="j13-brand-logo-dark" />
<Logo src={logoLight} fit={fit} alt={label} decorative={showText} extra="j13-brand-logo-light" cssPx={Math.max(box.w, box.h)} />
<Logo src={logoDark} fit={fit} alt={label} decorative={showText} extra="j13-brand-logo-dark" cssPx={Math.max(box.w, box.h)} />
</>
) : (
<Logo src={src} fit={fit} alt={label} decorative={showText} />
<Logo src={src} fit={fit} alt={label} decorative={showText} cssPx={Math.max(box.w, box.h)} />
)
) : (
<Bubble h={box.h} label={showText ? undefined : label} />
@@ -81,6 +82,7 @@ function Logo({
alt,
decorative = false,
extra = "",
cssPx,
}: {
src: string;
fit: BrandLogoFit;
@@ -88,6 +90,8 @@ function Logo({
/** 旁边已有站名时,读屏跳过,HTML 仍保留 alt 供检索 */
decorative?: boolean;
extra?: string;
/** 图槽最大边 CSS px,用于密度变体 */
cssPx: number;
}) {
if (fit === "repeat") {
return (
@@ -100,9 +104,17 @@ function Logo({
/>
);
}
// 本站光栅图走 1x/2x 变体(SVG/ICO 后端透传);外链图保持原地址
const own = isOwnImage(src);
return (
/* eslint-disable-next-line @next/next/no-img-element */
<img src={src} alt={alt} aria-hidden={decorative || undefined} className={`j13-brand-logo ${extra}`} />
<img
src={own ? variantURL(src, pickVariantWidth(cssPx)) : src}
srcSet={own ? densitySrcSet(src, cssPx) : undefined}
alt={alt}
aria-hidden={decorative || undefined}
className={`j13-brand-logo ${extra}`}
/>
);
}