+
-
-
-
-
-
-
-
#
+
+
+
+
+ ·
+
+ ·
+
+
-
-
-
-
-
-
diff --git a/assets/style.css b/assets/style.css
index efe3a77..b2b0c87 100644
--- a/assets/style.css
+++ b/assets/style.css
@@ -189,10 +189,11 @@ main.wrap{padding-top:24px; padding-bottom:40px; min-height:60vh}
overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}
.sw-badge-sm .sw-badge-nm{font-size:14px}
-.sw-badge-md .sw-badge-nm{font-size:19px}
-.sw-badge-lg .sw-badge-nm{font-size:22px; font-weight:700}
-/* 顶栏主标题:比「选择软件」标签(13.5px)大两号 = 17px。
- * 之前给到 26px 反而比内容区标题还小,主次颠倒;这里保持克制。 */
+.sw-badge-md .sw-badge-nm{font-size:16px; font-weight:600}
+/* 内容区:只是软件标识,字号刻意小于顶栏标题(17px),
+ * 避免「上面的字比下面的小」这种主次颠倒。 */
+.sw-badge-lg .sw-badge-nm{font-size:15px; font-weight:600}
+/* 顶栏主标题:比「选择软件」标签(13.5px)大两号 = 17px,且大于内容区的 15px */
.sw-badge-brand .sw-badge-nm{font-size:17px; font-weight:700; letter-spacing:.2px}
/* 页头副行:图标 + 软件名 */
.page-sw-id{margin:0; display:flex; align-items:center}
@@ -368,6 +369,37 @@ main.wrap{padding-top:24px; padding-bottom:40px; min-height:60vh}
.item-ex{color:var(--muted); font-size:14px; margin:8px 0 8px; word-break:break-word}
.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}
+
+/* ---------- 后台「待审核」列表 ----------
+ * 列表式:一屏能看多条,右侧固定一个「通过并公开」。
+ * 详情/关闭说明留在管理页里填,列表页不塞表单。 */
+.plist{display:flex; flex-direction:column; gap:10px}
+.prow{
+ display:flex; align-items:flex-start; gap:16px;
+ background:var(--card); border:1px solid var(--line);
+ border-radius:12px; padding:13px 16px;
+}
+.prow:hover{border-color:var(--line-strong)}
+.prow-main{flex:1; min-width:0}
+.prow-top{display:flex; align-items:center; flex-wrap:wrap; gap:8px}
+.prow-title{
+ font-weight:600; font-size:15.5px; color:var(--fg);
+ flex:1; min-width:160px; word-break:break-word;
+}
+.prow-title:hover{color:var(--brand); text-decoration:underline}
+.prow-ex{
+ color:var(--muted); font-size:13.5px; margin:6px 0;
+ word-break:break-word; display:-webkit-box; -webkit-line-clamp:2;
+ -webkit-box-orient:vertical; overflow:hidden;
+}
+.prow-meta{display:flex; flex-wrap:wrap; align-items:center; gap:6px; font-size:12.5px; color:var(--muted)}
+.prow-meta .who{color:#3a424d; font-weight:600}
+.prow-act{flex:none; padding-top:2px}
+.prow-act .btn{white-space:nowrap}
+@media (max-width:600px){
+ .prow{flex-direction:column; gap:10px}
+ .prow-act{align-self:flex-start}
+}
/* 问题编号:便于按 id 逐条跟进与引用 */
.item-id{
flex:none; font-size:12.5px; font-weight:600; color:var(--muted);
@@ -383,6 +415,8 @@ main.wrap{padding-top:24px; padding-bottom:40px; min-height:60vh}
}
.badge.st{background:#f1f3f5; color:#5b636e}
.badge.st-open{background:var(--warn-soft); color:var(--warn)}
+/* 「未公开」= 还没审过,用中性灰,不要和「已关闭」混淆 */
+.badge.st-hidden{background:#eef0f3; color:#6b7684}
.badge.st-doing{background:var(--brand-soft); color:var(--brand)}
.badge.st-resolved{background:var(--ok-soft); color:var(--ok)}
.badge.st-closed{background:#f1f3f5; color:#8a929c}
diff --git a/lib/db.php b/lib/db.php
index 7639347..0564418 100644
--- a/lib/db.php
+++ b/lib/db.php
@@ -399,18 +399,36 @@ SQL
}
}
- // 3) 状态:空表时灌 5 个(4 个原有 + 新增「不予考虑」)
+ // 3) 状态:空表时灌全部状态
if ((int)$pdo->query('SELECT COUNT(*) FROM statuses')->fetchColumn() === 0) {
$rows = [
- ['open', '待处理', '您提交的反馈已收到,我们正在处理中。', 0],
- ['doing', '处理中', '我们正在跟进这个问题,有进展会在这里同步。', 1],
- ['resolved', '已解决', '这个问题已经处理好了,欢迎回来验证一下。', 2],
- ['closed', '已关闭', '这个反馈已关闭,如有新情况可以重新提交。', 3],
- ['wontfix', '不予考虑', '经评估这个反馈暂不处理,感谢你的建议。', 4],
+ // key_name 名称 给用户看的说明(进邮件) 排序
+ ['hidden', '未公开', '您的反馈已提交,正在等待管理员查看。', 0],
+ ['open', '待处理', '您的反馈已公开,我们已收到,会尽快安排处理。', 1],
+ ['doing', '处理中', '我们正在跟进这个问题,有进展会在这里同步。', 2],
+ ['resolved', '已解决', '这个问题已经处理好了,欢迎回来验证一下。', 3],
+ ['closed', '已关闭', '这个反馈已关闭,如有新情况可以重新提交。', 4],
+ ['wontfix', '不予考虑', '经评估这个反馈暂不处理,感谢您的建议。', 5],
];
$st = $pdo->prepare('INSERT INTO statuses(key_name, name, user_note, sort_order, enabled)
VALUES(?,?,?,?,1)');
foreach ($rows as $r) { $st->execute($r); }
+ } else {
+ /* 老库补「未公开」状态。
+ * 2026-11-03 新增:用户提交后先落「未公开」,审核通过才转「待处理」——
+ * 「未公开」本身就是一种状态,不该只靠 threads.visible=0 这个附加字段隐式表达。 */
+ $hasHidden = (int)$pdo->query("SELECT COUNT(*) FROM statuses WHERE key_name = 'hidden'")->fetchColumn();
+ if ($hasHidden === 0) {
+ // 先把现有状态整体后移一位,给「未公开」腾出 0 号位
+ $pdo->exec('UPDATE statuses SET sort_order = sort_order + 1');
+ $pdo->prepare('INSERT INTO statuses(key_name, name, user_note, sort_order, enabled)
+ VALUES(?,?,?,?,1)')
+ ->execute(['hidden', '未公开', '您的反馈已提交,正在等待管理员查看。', 0]);
+
+ /* 存量数据:visible=0 且状态还是「待处理」的,语义上就是「没公开」,
+ * 归到「未公开」;visible=1 的保持「待处理」不动。 */
+ $pdo->exec("UPDATE threads SET status = 'hidden' WHERE visible = 0 AND status = 'open'");
+ }
}
// 4) 回填老帖子:software_id / category_id(只填 NULL 的,重复执行无副作用)
diff --git a/lib/mailer.php b/lib/mailer.php
index e27d4fb..7e15142 100644
--- a/lib/mailer.php
+++ b/lib/mailer.php
@@ -786,6 +786,15 @@ if (!function_exists('fb_notify_status_meta')) {
*/
function fb_notify_status_meta($key) {
$map = [
+ /* 「未公开」:用户刚提交时就是这个状态。
+ * 一般不单独发信(提交回执已经说了「等待审核」),
+ * 但万一从别的状态退回来,也要有话可说,不能落到兜底文案。 */
+ 'hidden' => [
+ 'badge' => '未公开', 'color' => '#6b7684', 'tone' => 'muted',
+ 'title' => '您的反馈已提交,正在等待审核',
+ 'intro' => '管理员会尽快查看您的反馈,确认后才会公开显示。',
+ 'tip' => '审核结果我们会通过邮件通知您,无需反复回来查看。',
+ ],
'open' => [
'badge' => '待处理', 'color' => '#5c6572', 'tone' => 'muted',
'title' => '您的反馈已收到,正在等待处理',
diff --git a/new.php b/new.php
index d7c7aa2..1340971 100644
--- a/new.php
+++ b/new.php
@@ -89,8 +89,14 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$atts = $vList;
} else {
$now = time();
- // 审核:开启后新提交默认不公开(visible=0),管理员通过后才会出现在列表
+ /* 审核:开启后新提交默认不公开(visible=0),管理员通过后才出现在列表。
+ *
+ * 🔴 状态与可见性必须同时设,两者是同一件事的两个侧面:
+ * 未公开 → status='hidden'(未公开),公开 → status='open'(待处理)。
+ * 以前一律写 'open',导致后台「待审核」里全是「待处理」,
+ * 状态根本反映不出"还没公开"这个事实。 */
$visible = fb_moderation_on() ? 0 : 1;
+ $initStatus = $visible === 1 ? 'open' : 'hidden';
$ins = $pdo->prepare('INSERT INTO threads(title, body, category, category_id, software_id, author_name, author_email, author_phone, status, visible, reply_count, created_at, updated_at, ip_hash) VALUES(?,?,?,?,?,?,?,?,?,?,0,?,?,?)');
$ins->execute([
$form['title'], $form['body'],
@@ -99,7 +105,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$swId > 0 ? $swId : null,
$form['name'], $form['email'],
$form['phone'] !== '' ? $form['phone'] : null,
- 'open', $visible, $now, $now, fb_ip_hash(),
+ $initStatus, $visible, $now, $now, fb_ip_hash(),
]);
$newId = (int)$pdo->lastInsertId();
fb_attach_save($pdo, $newId, null, $vList);