后台管理界面:软件/分类/状态可配,反馈可改挂归属 (#1)
## 新增 lib/admin_taxonomy.php - 软件:增删改、排序、启停;新增时自动预置 Bug/功能建议/其他 三个分类 - 分类:在选定软件下增删改、排序、启停 - 状态:改名、改「给用户看的话」、排序、启停;标识不可改(历史数据靠它对应) - 反馈改挂:th_move,可把反馈移到别的软件/分类,跨软件的非法分类会被拒 ## 安全与边界 - 所有动作走 CSRF 校验(沿用现有机制) - 不能删最后一个软件 / 没有分类的软件至少要留一个启用分类 - 有反馈挂着的软件或分类不能删,提示改为停用(停用后前台消失、数据保留) - th_move 加入 fb_admin_is_taxonomy_act 白名单,否则会被「问题不存在」静默吞掉 ## admin.php 接线 - 引入模块 + 动作分发 + tab 白名单加 taxonomy/statuses + 导航两项 - 前置检查放行不依赖 $t 的动作(否则新增软件报「问题不存在」) - 全部问题列表:加软件筛选、分类跟着软件走;修掉三处仍在用旧 fb_statuses()/fb_categories() 的遍历(那会渲染出错) - 详情页加「归属」表单,软件徽章可显示 ## 其他文件 - api.php:状态/分类改数据库;新增 ?sw= / ?software_id= / ?cid= 过滤, 老的 ?category=<slug> 仍可用(在所属软件内解析) - thread.php:详情页显示软件与分类徽章 - config.example.php:移除 categories / statuses,改由数据库管理 ## 修掉两个真实 bug 1. 移除配置后出厂分类兜底只剩 4 个,漏了「同步问题」—— 建库后核对数量才发现 2. th_move 不在白名单,POST 后返回 200 却静默不生效 验证:后台 e2e 29/29;改挂与联动 13/13;PHP 8.5 全部入口 0 弃用; 19 个 PHP 文件语法全过。
This commit is contained in:
@@ -81,6 +81,43 @@ main.wrap{padding-top:24px; padding-bottom:40px; min-height:60vh}
|
||||
.page-head h1{margin-bottom:4px}
|
||||
.page-head .muted{font-size:14px; margin:0}
|
||||
|
||||
/* ---------- 后台:软件 / 分类 / 状态 ---------- */
|
||||
.card-list{display:flex; flex-direction:column; gap:8px; margin-bottom:16px}
|
||||
.tax-row{
|
||||
display:flex; align-items:flex-start; gap:12px; flex-wrap:wrap;
|
||||
padding:12px 14px; background:var(--card); border:1px solid var(--line);
|
||||
border-radius:11px;
|
||||
}
|
||||
.tax-row.on{border-color:var(--brand); box-shadow:0 0 0 1px var(--brand) inset}
|
||||
.tax-row.off{opacity:.62}
|
||||
.tax-main{flex:1 1 320px; min-width:0}
|
||||
.tax-name{font-weight:600; font-size:15.5px; text-decoration:none; color:var(--fg)}
|
||||
.tax-name:hover{color:var(--brand)}
|
||||
.tax-name.plain{font-weight:600}
|
||||
.tax-slug{
|
||||
display:inline-block; margin-left:8px; font-size:12px; color:var(--muted);
|
||||
font-family:ui-monospace,Consolas,monospace;
|
||||
}
|
||||
.tax-meta{margin-left:10px; font-size:12.5px; color:var(--muted)}
|
||||
.tax-note{margin-top:5px; font-size:13px; color:var(--muted); line-height:1.5}
|
||||
.tax-acts{display:flex; flex-wrap:wrap; gap:6px; align-items:center}
|
||||
.inline-form{display:inline}
|
||||
.btn.sm{padding:5px 11px; font-size:13px; border-radius:8px}
|
||||
.btn.danger{border-color:#e0b4b4; color:#b4242c}
|
||||
.btn.danger:hover{background:#fdf2f2; border-color:#b4242c}
|
||||
.tax-form-box{
|
||||
margin:18px 0 8px; border:1px solid var(--line); border-radius:11px;
|
||||
background:var(--card); overflow:hidden;
|
||||
}
|
||||
.tax-form-box>summary{
|
||||
cursor:pointer; padding:12px 14px; font-weight:600; font-size:14.5px;
|
||||
background:var(--bg-soft, #f7f8fa); user-select:none;
|
||||
}
|
||||
.tax-form-box>summary:hover{color:var(--brand)}
|
||||
.tax-form-box[open]>summary{border-bottom:1px solid var(--line)}
|
||||
.sm-form{padding:14px; margin:0}
|
||||
.sm-form .field{margin-bottom:10px}
|
||||
|
||||
/* ---------- 软件切换(一级) ---------- */
|
||||
.software-bar{
|
||||
display:flex; flex-wrap:wrap; align-items:center; gap:8px;
|
||||
@@ -136,6 +173,9 @@ main.wrap{padding-top:24px; padding-bottom:40px; min-height:60vh}
|
||||
.badge.st-resolved{background:var(--ok-soft); color:var(--ok)}
|
||||
.badge.st-closed{background:#f1f3f5; color:#8a929c}
|
||||
.badge.official{background:var(--brand); color:#fff}
|
||||
/* 软件徽章:比分类更"重",一眼看出属于哪个软件 */
|
||||
.badge.sw{background:#eef2f8; color:#2b4a74; border:1px solid #cfdcee; font-weight:600}
|
||||
.badge.st-wontfix{background:#f6eef0; color:#a13c53}
|
||||
|
||||
/* ---------- 分页 ---------- */
|
||||
.pager{display:flex; align-items:center; gap:12px; margin:22px 0 0; justify-content:center}
|
||||
|
||||
Reference in New Issue
Block a user