# 🤖 TG 群管机器人 v2 — 重构规划

## 📌 项目信息

| 项 | 值 |
|----|-----|
| 项目路径 | `/vol3/1000/Code/tg-spam-guard/` |
| Git 仓库 | GitHub `ngfchl/tg-spam-guard` |
| 运行环境 | Python 3.12 + Docker |
| Web 框架 | FastAPI + uvicorn |
| ORM | Tortoise ORM + aerich |
| 数据库 | PostgreSQL (`192.168.123.5:15432`) |
| Bot | python-telegram-bot ≥ 22 |
| AI | Ollama (`qwen3:8b`) |
| 知识库 | sentence-transformers + BGE-zh + numpy |
| 前端 | Element UI 单页 |

---

## 🏗️ 项目结构

```
tg-spam-guard/
├── main.py                    # 入口：启动 FastAPI + Bot
├── config.py                  # 全局配置（从环境变量/配置文件读取）
│
├── db/                        # 数据库层
│   ├── __init__.py            # Tortoise 初始化
│   ├── models.py              # 所有 ORM 模型
│   └── migrate.py             # aerich 迁移配置
│
├── handlers/                  # Telegram 消息处理器
│   ├── __init__.py
│   ├── welcome.py             # 入群欢迎/退群告别
│   ├── verify.py              # 入群验证
│   ├── spam.py                # 垃圾检测+封禁
│   ├── night_mode.py          # 夜间模式
│   ├── knowledge.py           # /ask 知识库问答
│   ├── fun.py                 # 气氛组 + 小游戏
│   ├── bind.py                # 账号绑定
│   └── admin.py               # /ban /unban /warn /mute /kick /stats /purge
│
├── services/                  # 业务逻辑层
│   ├── __init__.py
│   ├── spam_detector.py       # 多层垃圾检测引擎
│   ├── knowledge_base.py      # RAG 检索（当前 knowledge/ 模块）
│   ├── verify_service.py      # 验证逻辑
│   ├── night_scheduler.py     # APScheduler 定时任务
│   ├── game_service.py        # 小游戏逻辑
│   └── bind_service.py        # go-harvest-server verify 对接
│
├── web/                       # Web 管理面板
│   ├── api.py                 # FastAPI 路由
│   └── static/
│       └── index.html         # Element UI 前端
│
├── knowledge/                 # 知识库（保持现有）
│   ├── __init__.py
│   ├── __main__.py
│   ├── index/
│   └── models/
│
├── templates/                 # 消息模板
│   ├── welcome.md
│   ├── verify.md
│   └── night_mode.md
│
├── wheels/                    # 本地 wheel 缓存（torch 等）
├── logs/                      # 日志目录（运行时生成）
│
├── docker-compose.yaml
├── Dockerfile
├── requirements.txt
├── pyproject.toml
├── aerich.toml                # aerich 迁移配置
├── .env.example               # 环境变量示例
└── .gitignore
```

---

## 📦 数据库设计（PostgreSQL）

### 核心表

```sql
-- 消息记录
CREATE TABLE messages (
    id BIGSERIAL PRIMARY KEY,
    msg_id BIGINT,
    chat_id BIGINT NOT NULL,
    user_id BIGINT NOT NULL,
    username VARCHAR(255),
    first_name VARCHAR(255),
    text TEXT,
    is_spam BOOLEAN DEFAULT FALSE,
    spam_reason VARCHAR(255),
    created_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE INDEX idx_messages_user_id ON messages(user_id);
CREATE INDEX idx_messages_created_at ON messages(created_at);
CREATE INDEX idx_messages_is_spam ON messages(is_spam);

-- 封禁记录
CREATE TABLE bans (
    id BIGSERIAL PRIMARY KEY,
    user_id BIGINT NOT NULL,
    username VARCHAR(255),
    first_name VARCHAR(255),
    reason VARCHAR(500),
    method VARCHAR(50),         -- 'auto' / 'command' / 'verify_fail'
    duration_minutes INTEGER,
    auto_unban BOOLEAN DEFAULT TRUE,
    unban_at TIMESTAMPTZ,
    created_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE INDEX idx_bans_user_id ON bans(user_id);

-- 操作日志（入群/退群/删除/解封/警告等）
CREATE TABLE actions (
    id BIGSERIAL PRIMARY KEY,
    action VARCHAR(50) NOT NULL,  -- JOIN/LEAVE/DELETE/UNBAN/WARN/MUTE/KICK
    user_id BIGINT,
    username VARCHAR(255),
    operator_id BIGINT,          -- 执行操作的管理员
    details JSONB,               -- 扩展字段
    created_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE INDEX idx_actions_action ON actions(action);
CREATE INDEX idx_actions_created_at ON actions(created_at);

-- 入队验证
CREATE TABLE verify_queue (
    id BIGSERIAL PRIMARY KEY,
    user_id BIGINT NOT NULL,
    username VARCHAR(255),
    question VARCHAR(500),
    answer VARCHAR(500),
    attempts INTEGER DEFAULT 0,
    status VARCHAR(20) DEFAULT 'pending', -- pending/verified/failed/expired
    created_at TIMESTAMPTZ DEFAULT NOW(),
    verified_at TIMESTAMPTZ
);
CREATE INDEX idx_verify_user_id ON verify_queue(user_id);

-- 账号绑定（TG ↔ Harvest）
CREATE TABLE user_bindings (
    id BIGSERIAL PRIMARY KEY,
    tg_user_id BIGINT UNIQUE NOT NULL,
    tg_username VARCHAR(255),
    harvest_uid VARCHAR(255),
    harvest_token VARCHAR(500),
    bound_at TIMESTAMPTZ DEFAULT NOW()
);

-- 警告记录
CREATE TABLE warnings (
    id BIGSERIAL PRIMARY KEY,
    user_id BIGINT NOT NULL,
    username VARCHAR(255),
    reason VARCHAR(500),
    issued_by BIGINT,
    active BOOLEAN DEFAULT TRUE,
    created_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE INDEX idx_warnings_user_id ON warnings(user_id);
CREATE INDEX idx_warnings_active ON warnings(active);

-- 游戏积分
CREATE TABLE game_scores (
    id BIGSERIAL PRIMARY KEY,
    user_id BIGINT NOT NULL,
    username VARCHAR(255),
    game_type VARCHAR(50),
    score INTEGER DEFAULT 0,
    wins INTEGER DEFAULT 0,
    total INTEGER DEFAULT 0,
    streak INTEGER DEFAULT 0,
    last_played TIMESTAMPTZ,
    UNIQUE(user_id, game_type)
);

-- 群组配置
CREATE TABLE group_config (
    key VARCHAR(100) PRIMARY KEY,
    value JSONB,
    updated_at TIMESTAMPTZ DEFAULT NOW()
);
```

---

## 📋 功能清单（去掉 PT 专属）

| # | 模块 | 优先级 | 说明 |
|---|------|--------|------|
| 1 | 🛡️ 垃圾信息阻挡 | ✅ 已有 | 三级检测：缓存→正则→AI，保留优化 |
| 2 | ⚡ 防刷屏 | 🔴 P0 | 令牌桶限速，超阈值删除多余消息 |
| 3 | 🔒 新人限制 | 🔴 P0 | 入群 N 分钟内禁止发链接/图片/文件/贴纸 |
| 4 | 👋 入群欢迎 | 🔴 P0 | 自定义欢迎卡片 + 群规 + 60s 自动删 |
| 5 | ✅ 入群验证 | 🔴 P0 | 新人答题/点按钮，超时踢出 |
| 6 | 🔗 账号绑定 | 🔴 P0 | TG ↔ Harvest 授权绑定 |
| 7 | 🌙 夜间模式 | 🟡 P1 | 定时全员禁言，管理员不受影响 |
| 8 | 🔨 管理工具 | 🟡 P1 | /warn /mute /kick /purge /slowmode /stats |
| 9 | 📊 操作审计 | 🟡 P1 | 所有管理员操作记录到 DB |
| 10 | 👥 退群告别 | 🟡 P1 | 可选，默认关闭 |
| 11 | 📚 知识库问答 | ✅ 已有 | /ask + RAG，保持 |
| 12 | 🎉 气氛组 | 🟢 P2 | 关键词触发表情、连击、撒花、里程碑 |
| 13 | 🎮 小游戏 | 🟢 P2 | 答题/签到/积分排行/抽奖 |
| 14 | 🎂 生日祝福 | 🟢 P3 | 记录生日，当天自动祝福 |

---

## 🔄 开发阶段

### Phase 1：基建（SQLite→PG + 重构 + Git）
- 初始化 Git 仓库
- 项目目录结构搭建
- config.py（环境变量管理）
- db/（Tortoise ORM 模型 + aerich 初始化）
- docker-compose.yaml（接入 PostgreSQL 网络）
- requirements.txt / pyproject.toml 更新
- main.py 瘦身：只保留启动逻辑

### Phase 2：核心安全（P0）
- handlers/spam.py + services/spam_detector.py（从旧 main.py 提取）
- handlers/admin.py（/ban /unban /warn /mute /kick /stats /purge）
- 防刷屏中间件
- 新人限制（禁止链接/图片/文件）

### Phase 3：入群流程（P0）
- handlers/welcome.py（入群欢迎/退群告别）
- handlers/verify.py + services/verify_service.py（入群验证）
- templates/（消息模板）

### Phase 4：账号绑定（P0）
- handlers/bind.py + services/bind_service.py
- 对接 go-harvest-server verify 接口
- /bind /unbind 命令

### Phase 5：夜间模式 + 管理增强（P1）
- handlers/night_mode.py + services/night_scheduler.py
- APScheduler 集成
- 操作审计

### Phase 6：社交 + 游戏（P2-P3）
- handlers/fun.py + services/game_service.py
- 气氛组（关键词触发、连击、撒花）
- 小游戏（答题、签到、积分）
- 生日祝福

### Phase 7：Web 面板升级
- web/api.py（所有 API 路由）
- web/static/index.html（适配新数据结构）
- SSE 实时推送适配

---

## ⚙️ 环境变量（.env）

```env
# Telegram
TG_BOT_TOKEN=your_telegram_bot_token
TG_CHAT_ID=-1001515287526

# PostgreSQL
DATABASE_URL=postgresql://user:password@192.168.123.5:15432/tg_spam_guard

# Ollama
OLLAMA_URL=http://127.0.0.1:11434
OLLAMA_MODEL=qwen3:8b

# Proxy
PROXY_URL=http://192.168.123.10:11055

# Web
WEB_PORT=8766
SITE_URL=https://ptools.fun

# Harvest
HARVEST_SERVER_URL=https://ptools.fun
```

---

## 📝 备忘

- 旧数据迁移：JSON → PostgreSQL（一次性脚本，放在 scripts/migrate_json_to_pg.py）
- docker-compose 需要加入 `1panel-network` 网络
- aerich 配置写在 aerich.toml，用 `aerich init` / `aerich migrate` 管理
- wheels/ 目录保留（torch 等大包不走网络）
- 知识库模块（knowledge/）保持独立，不改动
- 旧 main.py 备份为 main.py.bak
