首页改介绍页;列表只服务当前软件;新增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:
+24
-2
@@ -94,17 +94,39 @@ CREATE TABLE IF NOT EXISTS threads (
|
||||
author_name TEXT NOT NULL,
|
||||
author_email TEXT NOT NULL,
|
||||
author_phone TEXT,
|
||||
status TEXT NOT NULL DEFAULT 'open',
|
||||
status TEXT NOT NULL DEFAULT 'hidden',
|
||||
reply_count INTEGER NOT NULL DEFAULT 0,
|
||||
created_at INTEGER NOT NULL,
|
||||
updated_at INTEGER NOT NULL,
|
||||
ip_hash TEXT
|
||||
ip_hash TEXT,
|
||||
track_token TEXT NOT NULL DEFAULT ''
|
||||
);
|
||||
SQL
|
||||
);
|
||||
$pdo->exec('CREATE INDEX IF NOT EXISTS idx_threads_updated ON threads(updated_at DESC)');
|
||||
$pdo->exec('CREATE INDEX IF NOT EXISTS idx_threads_cat ON threads(category)');
|
||||
|
||||
/* ---- threads.track_token:提交人的「私人追踪钥匙」 ----
|
||||
* 因为本站不做用户登录,没办法认人;但每个人都必须能跟踪自己提交的反馈,
|
||||
* 哪怕是还没审核通过的。做法:提交时生成一串随机 token 只发到他的邮箱,
|
||||
* 链接带 ?t=<token> 就能看 / 能回复,别人不知道这串东西就看不到。
|
||||
*
|
||||
* 🔴 不要用 id 代替:id 是自增的,任何人改个数字就能翻别人的私有反馈。
|
||||
* token 必须是不可猜的随机值(这里用 32 位 hex = 128 位熵)。 */
|
||||
$thCols = $pdo->query('PRAGMA table_info(threads)')->fetchAll();
|
||||
$thNames = [];
|
||||
foreach ($thCols as $c4) { if (isset($c4['name'])) { $thNames[(string)$c4['name']] = true; } }
|
||||
if (!isset($thNames['track_token'])) {
|
||||
$pdo->exec("ALTER TABLE threads ADD COLUMN track_token TEXT NOT NULL DEFAULT ''");
|
||||
}
|
||||
// 存量回填:给还没有 token 的帖子补一个,保证老数据的邮件链接也能用
|
||||
$need = $pdo->query("SELECT id FROM threads WHERE track_token IS NULL OR track_token = ''")->fetchAll();
|
||||
if ($need) {
|
||||
$upd = $pdo->prepare('UPDATE threads SET track_token = ? WHERE id = ?');
|
||||
foreach ($need as $r) { $upd->execute([bin2hex(random_bytes(16)), (int)$r['id']]); }
|
||||
}
|
||||
$pdo->exec('CREATE UNIQUE INDEX IF NOT EXISTS idx_threads_token ON threads(track_token)');
|
||||
|
||||
$pdo->exec(<<<'SQL'
|
||||
CREATE TABLE IF NOT EXISTS replies (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
|
||||
Reference in New Issue
Block a user