fix(reports): separate readable categories from report content

Store readable category snapshots separately from details and evidence, validate report categories, and preserve context in admin displays and moderation actions. Widen report categories to TEXT and bump the schema to 3.2.0 without legacy data conversion.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
kate522andClaude Fable 5 committed 2026-10-31 00:57:13 +08:00
1 parent b2811cc248
commit b45fd161f0
16 files changed
+797 -75

No files matched your search

+22 -10
View File
@@ -46,7 +46,7 @@ trait UserControllerReportOperations {
$page = max(1, (int) ($request->get_param('page') ?: 1));
$per_page = max(1, min(100, (int) ($request->get_param('per_page') ?: $request->get_param('limit') ?: 20)));
$status = sanitize_key((string) $request->get_param('status'));
$category = sanitize_key((string) $request->get_param('category'));
$category = sanitize_text_field((string) $request->get_param('category'));
$target_type = sanitize_key((string) $request->get_param('target_type'));
$keyword = trim(sanitize_text_field((string) $request->get_param('keyword')));
$date_from = sanitize_text_field((string) $request->get_param('date_from'));
@@ -95,7 +95,7 @@ trait UserControllerReportOperations {
$counts = \AKSRT\Messages\ReportCenter::get_instance()->get_status_counts();
$categories = [];
foreach ((array) $rows as $row) {
$cat = sanitize_key((string) ($row['category'] ?? ''));
$cat = sanitize_text_field((string) ($row['category'] ?? ''));
if ($cat !== '') {
$categories[$cat] = $cat;
}
@@ -190,11 +190,14 @@ trait UserControllerReportOperations {
return $this->error(__('举报工单不存在', 'aksrt'), 404);
}
$action_reason = (string) ($row['category'] ?? '');
$details = (string) ($row['reason'] ?? '');
if ($details !== '') $action_reason .= "\n\n" . $details;
$effect = $this->apply_report_action(
sanitize_key((string) $row['target_type']),
(int) $row['target_id'],
$action_taken,
(string) ($row['reason'] ?? '')
$action_reason
);
$notes = json_decode((string) ($row['notes_json'] ?? '[]'), true);
@@ -260,7 +263,7 @@ trait UserControllerReportOperations {
'target_type' => sanitize_key((string) ($row['target_type'] ?? '')),
'target_id' => (int) ($row['target_id'] ?? 0),
'reason' => (string) ($row['reason'] ?? ''),
'category' => sanitize_key((string) ($row['category'] ?? '')),
'category' => (string) ($row['category'] ?? ''),
'status' => sanitize_key((string) ($row['status'] ?? 'pending')),
'created_at' => (string) ($row['created_at'] ?? ''),
'updated_at' => (string) ($row['updated_at'] ?? ''),
@@ -408,16 +411,25 @@ trait UserControllerReportOperations {
return $this->error('举报系统未启用', 500);
}
$params = $this->get_json_params($request);
$target_type = sanitize_key((string) ($params['target_type'] ?? ''));
$target_id = (int) ($params['target_id'] ?? 0);
$reason = sanitize_textarea_field((string) ($params['reason'] ?? ''));
$category = sanitize_key((string) ($params['category'] ?? ''));
$target_type = sanitize_key((string) $request->get_param('target_type'));
$target_id = (int) $request->get_param('target_id');
$reason = sanitize_textarea_field((string) $request->get_param('reason'));
$category = sanitize_text_field((string) $request->get_param('category'));
if ($target_type === '' || $target_id <= 0 || $reason === '') {
if ($target_type === '' || $target_id <= 0 || $category === '') {
return $this->error('请填写完整的举报信息');
}
$other_category = '其他原因';
$categories = array_column(\AKSRT\Settings\UserRuntime::ban_settings()['reasons'], 'name');
$categories[] = $other_category;
if (!in_array($category, $categories, true)) {
return $this->error(__('举报原因无效或已更新,请刷新页面后重新选择', 'aksrt'));
}
if ($category === $other_category && $reason === '') {
return $this->error(__('请填写举报原因的具体说明', 'aksrt'));
}
$valid_types = ['post', 'comment', 'user'];
if (!in_array($target_type, $valid_types, true)) {
return $this->error('无效的举报类型');