首页改介绍页;列表只服务当前软件;新增UUID追踪让提交人看得到未审核反馈
用户提的两个核心问题:
一、首页不该列全部问题
场景:这套系统是给某个软件配反馈入口、把地址贴进那软件的「意见反馈」里。
访客总是从某个软件过来的,看别的软件的问题对他没意义。
⇒ / 不带 sw 时渲染介绍页(特点介绍 + 「点右上角设置按钮选软件」+ 软件卡片)
带 sw 才是该软件的问题列表,检索/筛选/分类全在本软件范围内
二、提交后未审核,用户点不进去(真实缺陷)
邮件里给了「点击查看您刚才提交的反馈」,但 thread.php 只在 visible=1 时
才给看,未审核的一律 404 / 只看到「等待审核」静态页 —— 链接等于白给。
⇒ threads 加 track_token(32位hex = 128位熵),提交时生成:
- 邮件里所有链接一律带 ?t=<token>(不再是裸 id)
- 带对 token:可看完整详情、可回复,哪怕未公开/已关闭
- 没 token 或 token 错:对外一律 404,不泄露存在性
- 公开列表仍用 id 链接(公开内容谁都能看,用于避免重复提交)
实现细节:
- threads.track_token + 唯一索引;幂等迁移,存量数据自动回填
- fb_track_new_token / fb_track_token_ok(hash_equals 防时序探测)
/ fb_thread_viewable / fb_thread_link(thread, personal)
- thread.php 权限从 fb_thread_public 改为 fb_thread_viewable
- 带 token 看自己未公开的反馈时,顶部给「私人跟踪链接」提示条
- 回复表单与回复后跳转都保留 token,否则回复完就失去访问权
- 提交完成后直接带 token 跳详情页,不再只给静态等待页
- close 类邮件补上「查看这条反馈」按钮(原来完全没链接)
- 顶栏「全部问题」改为「问题列表」且只在选中软件后显示
- 详情/提交页「返回问题列表」按所属软件返回,不再回介绍页
- new.php 无 sw 时不再默认落到第一个软件,改为让用户先选
(默默替选会让反馈进错软件、通知发错人)
验证:首页 0 条问题卡片且未泄露任何标题、三个软件入口齐全;
未公开#4 无 token 404 / 错 token 404 / 正确 token 200 且显示完整详情
(不再卡在「等待审核」)、提示条与表单 token 都在;
已公开#2 无 token 可看;5 类邮件(回执/通过/回复/状态/关闭)链接全带 token;
两套回归各 30+ 项断言全过。
This commit is contained in:
@@ -150,6 +150,75 @@ main.wrap{padding-top:24px; padding-bottom:40px; min-height:60vh}
|
||||
/* ---------- 页头 ---------- */
|
||||
.page-head{display:flex; align-items:flex-start; gap:16px; margin:6px 0 18px}
|
||||
.page-head .btn{margin-left:auto; flex:none; margin-top:4px}
|
||||
|
||||
/* ---------- 首页:轻反馈介绍页 ----------
|
||||
* 用户 2026-11-03:首页不列问题,只做介绍 + 指路。
|
||||
* 因为访客总是从某个软件过来的,他要的是「怎么进自己那个软件的反馈」,
|
||||
* 而不是看别人的问题列表。 */
|
||||
.home{max-width:820px; margin:0 auto; padding:8px 0 40px}
|
||||
.home-hero{text-align:center; padding:26px 0 30px}
|
||||
.home-hero h1{
|
||||
font-size:30px; line-height:1.3; margin:0 0 12px;
|
||||
letter-spacing:-.4px;
|
||||
}
|
||||
.home-lead{
|
||||
font-size:15.5px; line-height:1.75; color:var(--muted);
|
||||
margin:0 auto; max-width:600px;
|
||||
}
|
||||
|
||||
.home-feats{
|
||||
display:grid; grid-template-columns:repeat(2, minmax(0,1fr));
|
||||
gap:12px; margin:0 0 34px;
|
||||
}
|
||||
@media (max-width:600px){ .home-feats{grid-template-columns:1fr} }
|
||||
.home-feat{
|
||||
background:var(--card); border:1px solid var(--line);
|
||||
border-radius:12px; padding:16px 18px;
|
||||
}
|
||||
.home-feat-ic{font-size:20px; line-height:1; margin-bottom:8px}
|
||||
.home-feat h3{margin:0 0 6px; font-size:15px; font-weight:700}
|
||||
.home-feat p{margin:0; font-size:13.5px; line-height:1.7; color:var(--muted)}
|
||||
|
||||
.home-enter{
|
||||
background:var(--card); border:1px solid var(--line);
|
||||
border-radius:14px; padding:22px 24px;
|
||||
}
|
||||
.home-enter h2{margin:0 0 10px; font-size:17px}
|
||||
.home-enter-tip{
|
||||
font-size:14px; color:var(--muted); line-height:1.8; margin:0 0 16px;
|
||||
display:flex; align-items:center; flex-wrap:wrap; gap:6px;
|
||||
}
|
||||
.home-enter-tip b{color:var(--fg); font-weight:600}
|
||||
/* 小号三横线示意,让「右上角那个设置按钮」有具体形象可对照 */
|
||||
.home-menu-demo{
|
||||
display:inline-flex; flex-direction:column; justify-content:center; gap:2.5px;
|
||||
width:22px; height:22px; padding:4px; box-sizing:border-box;
|
||||
border:1px solid var(--line-strong); border-radius:6px;
|
||||
background:var(--bg, #f6f8fb);
|
||||
}
|
||||
.home-menu-demo i{display:block; width:100%; height:1.5px; background:var(--fg); border-radius:2px}
|
||||
|
||||
.home-sw-list{display:flex; flex-direction:column; gap:8px}
|
||||
.home-sw{
|
||||
display:flex; align-items:center; gap:12px;
|
||||
padding:11px 14px; border-radius:11px;
|
||||
border:1px solid var(--line); background:var(--card);
|
||||
color:var(--fg);
|
||||
}
|
||||
.home-sw:hover{
|
||||
text-decoration:none; color:var(--fg);
|
||||
border-color:var(--swc); background:var(--bg, #f6f8fb);
|
||||
}
|
||||
.home-sw-ic{
|
||||
width:36px; height:36px; flex:none; border-radius:9px;
|
||||
display:flex; align-items:center; justify-content:center;
|
||||
font-size:22px; line-height:1;
|
||||
}
|
||||
.home-sw-ic img{width:36px; height:36px; object-fit:contain; display:block}
|
||||
.home-sw-nm{font-size:15px; font-weight:600; color:var(--swc)}
|
||||
.home-sw-go{margin-left:auto; font-size:13px; color:var(--muted); flex:none}
|
||||
.home-sw:hover .home-sw-go{color:var(--swc)}
|
||||
.home-enter-alt{margin:12px 0 0}
|
||||
.page-head h1{margin-bottom:4px}
|
||||
.page-head .muted{font-size:14px; margin:0}
|
||||
|
||||
@@ -386,6 +455,17 @@ main.wrap{padding-top:24px; padding-bottom:40px; min-height:60vh}
|
||||
.item-meta{display:flex; flex-wrap:wrap; align-items:center; gap:6px; font-size:13px; color:var(--muted)}
|
||||
.item-meta .who{color:#3a424d; font-weight:600}
|
||||
|
||||
/* 提交人凭 token 看自己未公开反馈时的提示条 */
|
||||
.owner-note{
|
||||
display:flex; flex-direction:column; gap:4px;
|
||||
margin:0 0 16px; padding:12px 14px;
|
||||
background:var(--warn-soft, #fff8e6);
|
||||
border:1px solid #f0d9a8; border-left:3px solid #d99b1f;
|
||||
border-radius:10px; font-size:13.5px; line-height:1.65;
|
||||
color:#6b5313;
|
||||
}
|
||||
.owner-note b{font-size:14px; color:#5a4610}
|
||||
|
||||
/* ---------- 后台「待审核」列表 ----------
|
||||
* 列表式:一屏能看多条,右侧固定一个「通过并公开」。
|
||||
* 详情/关闭说明留在管理页里填,列表页不塞表单。 */
|
||||
|
||||
Reference in New Issue
Block a user