跳转至

举报中心模块 · Report Center Module (Phase 9)

AstraSentinel · 星穹天巡 — 从静态目录索引升级为完整的举报工作流中枢。


1. 设计目标

把举报中心从「26 条 URL 收藏夹」升级为「证据 → 智能推荐 → 自动生成材料 → 提交跟踪」的端到端工作流。

每条证据应该能够: 1. 一键举报 — 详情页点按钮,自动推荐适用渠道 2. 自动生成材料 — 复用 Phase 9 legaldocs.Generate,匹配渠道模板 3. 半自动提交 — 「复制 + 打开外部页面 + 标记已提交 + 截图凭据」 4. 跟踪状态 — 6 状态机 + 审计完整 + 自动写 custody log 5. 批量操作 — 50 条 evidence 一次性打包 / 一次性入库


2. 数据模型

2.1 新表

用途
portal_report_channels 渠道目录(super_admin 可在线 CRUD)
portal_report_submissions 每租户每次举报一行 + 状态机 + 截图凭据

2.2 portal_report_channels

类型 含义
id varchar(64) 字符串 slug,主键("12377", "douyin_report")
name_zh / name_en varchar(255) 双语名
url varchar(1024) 渠道访问地址
category varchar(128) 分类(电信/短信/网络不良 等)
applicable jsonb 适用类型 array(GIN 索引)
region varchar(32) china / global / us / eu / jp / kr
is_official bool 官方监管 vs 平台举报
required_fields jsonb 客户必填字段结构化定义
template_id varchar(64) 路由到 legaldocs DocType
active / sort_order 软删除 + UI 排序

2.3 portal_report_submissions

类型 含义
id uuid PK
tenant_id / channel_id
evidence_id? / threat_id? / private_server_id? / social_intel_id? uuid 四 source 排他可选
submitted_by_user_id uuid JWT user_id
status enum (CHECK) draft / submitted / in_review / resolved / rejected / withdrawn
submitted_at / closed_at timestamptz 自动管理
reference_no varchar(255) 外部回执号
response_text text 外部回复
screenshot_object_key varchar(512) MinIO 路径(reports/<id>/proof.<ext>
material_markdown text 提交时冻结的材料原文(不可被后续生成器覆盖)
title / notes

3. 14 个新 API

3.1 渠道目录

  • GET /api/v1/report-channels?search=&region=&applicable=&is_official=&active=
  • GET /api/v1/report-channels/:id
  • POST /api/v1/report-channels (super_admin)
  • PATCH /api/v1/report-channels/:id (super_admin)
  • GET /api/v1/reports-center/channels(legacy,兼容旧 UI)

3.2 智能推荐

  • GET /api/v1/report-channels/recommend?evidence_id|threat_id|private_server_id|social_intel_id=...&severity=&region=

3.3 材料生成

  • POST /api/v1/report-channels/:id/generate-material
  • body: { evidence_id, case_label?, rights_holder?, recipient?, lawyer_name?, law_firm?, template_id? }
  • 返回 markdown + missing_required_fields + 实际模板 alias

3.4 提交 CRUD

  • POST /api/v1/report-submissions → 创建 (含 dedup 409 + force=true)
  • GET /api/v1/report-submissions?status=&channel_id=&evidence_id=&search=&page=
  • GET /api/v1/report-submissions/:id
  • PATCH /api/v1/report-submissions/:id → 状态机校验后更新
  • POST /api/v1/report-submissions/:id/screenshot → 截图凭据上传

3.5 批量

  • POST /api/v1/report-channels/:id/batch-package → ZIP 含 N 份材料
  • POST /api/v1/report-submissions/bulk → 一次提交多条 + per-item 结果

4. 状态机

        ┌─→ submitted ─┬─→ in_review ─┬─→ resolved  (终结)
draft ──┤              │              │
        │              ├─→ rejected ──┴─→ submitted  (重投)
        └─→ withdrawn  │              │
                       └──────────────┴─→ withdrawn  (终结)
  • resolved / withdrawn 是终结态 — 不可流出
  • rejected → submitted 是合法的(platform 拒了,补料再投)
  • same → same 是 no-op(PATCH 可盲调不出错)
  • DB CHECK 约束(status 枚举)+ application-layer ValidateStatusTransition 双层校验

5. 智能推荐评分模型(5 因素 / 总分 100)

因素 权重 触发条件
applicable_match 30 渠道 applicable[] 与 signal kinds 有重叠
domain_match 25 source URL 主机匹配渠道平台映射(13 平台预设)
region_match 20 signal.region == channel.region
official_bonus 15 渠道是官方监管 + 高严重度(crime/copyright_criminal/fraud/...)
history_success 10 该租户对此渠道历史提交 ≥2 次且解决率 ≥50%

每个分数对应一条结构化 reason {code, message, delta},UI 渲染 "+30 渠道适用类型命中:copyright"。


6. 模板路由表

Channel template_id → legaldocs DocType 适用渠道
notary_application DocNotaryApplication 12377 / 12321 / MIIT / SAMR / CNCERT
forensic_commission DocForensicCommission NCAC / CNIPA / NPPA / SIPO / MPS110
cease_desist (alias) DocCeaseDesistAttachments DMCA / YouTube / Steam / Alibaba / TG / Discord / CNNIC
cease_desist_attachments DocCeaseDesistAttachments WeChat / QQ / 抖音 / B站 / 小红书 / 快手 / 微博
(NULL) cyber_beian (仅查询)

templateAliasMap 处理 legacy cease_desistcease_desist_attachments — 0 数据迁移。


7. 完整工作流

7.1 单证据流程

1. 客户上传证据 → /evidence/<id>
2. 点「举报」按钮 → ReportRecommendModal
   GET /report-channels/recommend?evidence_id=<uuid>
3. 看到 top 6 渠道 + 推荐理由
4. 点某条「在举报中心打开」→ /reports-center/?channel=X&evidence_id=Y
5. ReportFlowDrawer 自动跳过 channel + evidence 选择
6. 「生成材料」→ POST /report-channels/<id>/generate-material
7. 编辑 markdown → 「复制 + 打开举报页」
8. 在外部渠道粘贴提交 → 拿到回执号
9. 回到 portal → 「标记已提交」+ 截图凭据
   POST /report-submissions
   → 写 REPORT_SUBMITTED custody log(evidence 时间线见到此提交)
10. 后续 PATCH 状态:in_review / resolved / rejected / withdrawn
   → 每次写对应 custody log

7.2 批量流程

1. /reports-center 切到「批量举报」tab
2. 选渠道(支持自动材料的)
3. 搜索 + 多选 N 个 evidence
4. 填批次共同字段(案件标签 / 律师 / 律所)
5. 「📥 下载 ZIP」→ N 份 markdown + README.md
   ZIP 内 errors/ 子目录占位失败项
6. 律师离线审阅 → 提交 → 拿回执号
7. 回到 portal → 「🚀 批量标记已提交」+ 共用回执号
   POST /report-submissions/bulk
   → per-item 结果:✓ created / ⚡ duplicate / ✗ failed
   → 每证据写一条 REPORT_SUBMITTED custody log

8. 前端形态

路由 功能
/reports-center/ 4 tabs: 官方监管 / 平台举报 / 我的记录 / 批量举报
/reports-center/?channel=X&evidence_id=Y Deep-link,自动打开 ReportFlowDrawer
/evidence/[id] 顶部「举报」按钮
/threats Drawer footer「智能举报推荐」
/private-servers Drawer footer「智能举报推荐」
/social-intel Drawer footer「发起举报」(已升级为 ReportRecommendModal)

8.1 组件清单

frontend/src/app/(portal)/reports-center/
├── page.tsx              主页面 + 4 tabs + Hero 4 KPI
├── ChannelCard.tsx       渠道卡(含历史统计 + 自动材料 badge)
├── MySubmissionsList.tsx 我的记录列表 + 状态过滤 + 分页
├── ReportFlowDrawer.tsx  5 步工作流抽屉
├── BatchReportTab.tsx    批量举报 4 步 UI
└── (deep link support via useSearchParams)

frontend/src/components/viz/
└── ReportRecommendModal.tsx  通用智能推荐模态(4 source 复用)

9. 部署 / 运维

9.1 部署形态(ai-astraweb)

  • API: /usr/local/bin/portalportal-api.service (systemd) 管理
  • Frontend: nginx serve /var/www/portal/
  • 不要用 deploy/deploy-aws.sh — 已 stale

9.2 部署命令

# 1. 编译
cd ~/ai/bot/game-guard-portal
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 \
    go build -ldflags="-s -w" -o /tmp/portal-linux ./cmd/portal

# 2. 前端
cd frontend && NEXT_PUBLIC_API_URL=https://portal.astraeye.ai npx next build

# 3. 部 binary
scp /tmp/portal-linux ai-astraweb:/tmp/portal-new
ssh ai-astraweb 'sudo cp /usr/local/bin/portal /usr/local/bin/portal.bak-$(date +%Y%m%d-%H%M%S)
                 sudo install -m 0755 /tmp/portal-new /usr/local/bin/portal
                 sudo systemctl restart portal-api'

# 4. 部前端
rsync -avz --delete ~/ai/bot/game-guard-portal/frontend/out/ ai-astraweb:/tmp/portal-frontend-new/
ssh ai-astraweb 'sudo rsync -a --delete /tmp/portal-frontend-new/ /var/www/portal/'

# 5. 验
curl https://portal.astraeye.ai/health

9.3 数据库迁移

AutoMigrate 自动建表 + BootstrapReportChannels 幂等 seed 27 条渠道:

  • portal_report_channels(含 27 条 seed 行)
  • portal_report_submissions(空表)

OnConflict DoNothing 保证 super_admin 在线编辑过的渠道不会被重启 seed 覆盖。

如需手动 golang-migrate:

migrate -path migrations/ -database $PG_DSN up

10. FAQ

Q: 为什么不自动提交到外部渠道? A: 外部渠道有 captcha / 登录 / 多步表单,自动化脆弱。半自动(复制 + 打开 + 手动粘贴)更鲁棒,律师 / 公证员的真实工作流就是这样。

Q: cease_desist vs cease_desist_attachments 区别? A: 同一个 legaldocs.DocType;seed 数据用了旧字面量 cease_desist,alias map 自动映射。新增渠道用规范名。

Q: 批量大小有上限? A: 100。律所一天产能足够;100+ 案件应分批做。

Q: 我的提交被外部拒了怎么办? A: PATCH status=rejected → 补证据 / 改材料 → PATCH status=submitted(合法状态转移)。系统支持 re-file 工作流。

Q: 怎么向新渠道(新增的法院)举报? A: super_admin POST /report-channels 新建,设置 applicable / template_id。其他 tenant 立即看到。无需发版。


11. 法律合规面

受众 用到本模块
律师 一键生成 N 份材料 + ZIP 打包 + 「批量标记已提交」做案件归档
公证员 客户来公证时附带 portal_report_submissions 历史 + screenshot_object_key 凭据
司法鉴定中心 material_markdown 字段冻结后的原文 = 司法可采
互联网法院 通过 evidence 上的 REPORT_SUBMITTED 等 custody log 完整时间线,证明权利人已主动维权

12. 版本对照

组件 版本
templateAliasMap v1(cease_desist → cease_desist_attachments)
reportrecommend scoring 5 因素 × 100 / reportrecommend/v1
report-center schema migration 000013
Seed 渠道 27 条(14 官方 + 13 平台)

13. Phase 10 候选

  • 真正的自动提交(部分渠道开放 API)
  • 渠道 SLA 跟踪(自动 polling 外部状态查询页)
  • 多 TSA / 多渠道 cross-witness 报告
  • 国际渠道扩展(USPTO / EUIPO / KCOPA / JPO)
  • 渠道 SLA 报表(按 channel 算 resolution 平均时长 + 拒绝原因分布)