diff --git a/assets/style.css b/assets/style.css index 9da4478..4ae8b52 100644 --- a/assets/style.css +++ b/assets/style.css @@ -149,6 +149,28 @@ main.wrap{padding-top:24px; padding-bottom:40px; min-height:60vh} display:inline-flex; align-items:center; justify-content:center; } .icon-preset:hover{border-color:var(--brand); background:var(--brand-soft)} + +/* ---------- 软件图标(上传图片) ---------- */ +/* 图标图片:外框与字符版完全一致,换图不会让布局跳动 */ +.sw-badge-img{ + display:inline-block; border-radius:7px; object-fit:cover; flex:none; + box-shadow:0 1px 2px rgba(15,25,45,.18); background:var(--card); +} +.chip.on .sw-badge-img{box-shadow:0 0 0 1px rgba(255,255,255,.5)} +/* 后台图标上传行 */ +.icon-up{display:flex; align-items:flex-start; gap:14px; flex-wrap:wrap; margin-top:6px} +.icon-prev{ + width:56px; height:56px; flex:none; border-radius:12px; overflow:hidden; + border:1px solid var(--line); background:var(--card); + display:flex; align-items:center; justify-content:center; +} +.icon-prev img{width:100%; height:100%; object-fit:cover; display:block} +.icon-prev-ph{ + width:100%; height:100%; display:flex; align-items:center; justify-content:center; + color:#fff; font-size:24px; font-weight:600; +} +.icon-up-main{flex:1; min-width:220px; display:flex; flex-direction:column} +.icon-up-main input[type=file]{font-size:13.5px; max-width:100%} /* 选中态的 chip 里,图标底衬白、字符取软件色,避免同色糊在一起 */ .chip.on .sw-badge-ic{background:#fff !important; color:var(--brand) !important; box-shadow:none} .chip.on .sw-badge-nm{color:#fff} diff --git a/lib/admin_taxonomy.php b/lib/admin_taxonomy.php index 24a93c8..8aed2c1 100644 --- a/lib/admin_taxonomy.php +++ b/lib/admin_taxonomy.php @@ -5,6 +5,123 @@ */ if (!defined('FB_ROOT')) { http_response_code(403); exit('forbidden'); } +/* ================================================================== + * 软件图标图片:上传 / 删除 + * ------------------------------------------------------------------ + * 安全边界(三条,缺一不可): + * ① 只有管理员能进(这个函数只从后台登录后的动作分支调用); + * ② 落盘前用 finfo 读真实文件头,必须是图片白名单里的类型 —— + * 与附件上传同一个教训:把 PHP 改名成 .png 就能写进目录, + * .htaccess 是唯一防线,换 nginx 就失守; + * ③ 键空间独立为 icons/,且形状受限(无穿越、无自由路径)。 + * + * 存储方式跟附件完全一致:本机 → uploads/;OSS → 服务器代理 PUT 到私有桶。 + * 对外一律 media.php?k=... 代理,不暴露真实位置。 + * ================================================================== */ + +/** 图标允许的扩展名(比附件白名单窄:图标不需要 gif 动图,也不要 svg) */ +function fb_icon_allowed_ext() { + // ⚠️ 刻意不收 svg:SVG 能内嵌