# 万象口袋 — Go 后端文档

**技术栈**：Go 1.25+ · Gin · GORM · MySQL ·（可选）Redis（go-redis v9）

**模块路径**：`infogenie-backend`（见 `go.mod`）

**入口**：`cmd/server/main.go` — 加载配置、连接 MySQL、`cache.Init`（若启用 Redis）、`AutoMigrate`、启动 HTTP 服务。

---

## 运行与配置

- 环境由 `**APP_ENV`** 决定：`development` 或 `production`（见 `config.Load()`）。
- 若存在 `**.env.development**` / `**.env.production**`，会通过 `godotenv` 加载对应文件。
- `**APP_PORT**` 默认 **5002**（与前端 `VITE_API_URL` 开发默认一致）。
- 数据库、邮件、认证中心、`INFOGENIE_SITE_ADMIN_TOKEN`、可选 Redis 等从环境变量读取，详见 `config/config.go`。

### Redis（可选）


| 变量                 | 说明                                                        |
| ------------------ | --------------------------------------------------------- |
| `REDIS_ENABLED`    | `true` / `1` / `yes` / `on` 时启用；未启用则不连 Redis，站点接口直连 MySQL |
| `REDIS_ADDR`       | `host:port`；生产环境必填；开发未设时默认 `10.1.1.100:6379`              |
| `REDIS_PASSWORD`   | 可选                                                        |
| `REDIS_DB`         | 逻辑库编号，默认 **10**（与 `db0` 等业务隔离）                            |
| `REDIS_KEY_PREFIX` | Key 前缀，默认 `infogenie:go:v1:`（可自动补 `:`）                    |
| `REDIS_SITE_TTL`   | 站点类 JSON 缓存 TTL（秒），默认 **60**                              |


启用时启动阶段会 **Ping**；失败则进程退出。站点只读接口对 `60s-disabled`、`60s-source`、`ai-model-disabled`、`feature-card-clicks` 等做 cache-aside，管理端写入成功后删对应 Key（见 `internal/cache/redis.go` 与 `internal/handler/siteconfig.go`、`feature_card_clicks.go`）。

---

## 健康与诊断

### `GET /api/health`（公开）

- `**status`**：`running` 或 `degraded`（MySQL 未连通 **或** 60s 上游探测失败时为 degraded；**不**因 Redis 失败而 degraded）。
- `**mysql`**：`ok`、`status`（`connected` / `disconnected` / `not_initialized`）。
- `**sixty_api**`：当前生效的上游 `source_id`、`base_url`、`label`，以及对 `…/v2/ip` 的探测结果（`probe_url`、`http_status`、`latency_ms`、`error`）。
- `**redis**`：未启用时 `{ "enabled": false }`；启用时 `{ "enabled": true, "ok": bool, "error"?: string }`。

### `GET /api/admin/site/diagnostics`（需管理员）

请求头 `**X-Site-Admin-Token**` 须与 `**INFOGENIE_SITE_ADMIN_TOKEN**` 一致。

返回**不含密码明文**，仅连接与进程摘要，供运维/后台展示：


| 字段               | 内容                                                                                          |
| ---------------- | ------------------------------------------------------------------------------------------- |
| `app`            | `env`、`listen_addr`（`0.0.0.0:端口`）、`listen_port`                                             |
| `mysql`          | `host`、`port`、`database`、`user`、`password_configured`                                       |
| `redis`          | `enabled`；若启用则含 `addr`、`logical_db`、`key_prefix`、`site_cache_ttl_sec`、`password_configured` |
| `sixty_upstream` | 库内当前 60s 节点 `source_id` / `base_url` / `label`                                              |
| `auth_center`    | `api_url`                                                                                   |
| `mail`           | SMTP `host`、`port`、`username`、`password_configured`                                         |


---

**根路径**：`GET /` — 返回服务说明与主要 endpoint 分组（`version` 当前为 **3.3.0-go**）。

---

## 数据库（GORM AutoMigrate）

启动时会迁移以下模型（见 `internal/database/mysql.go`）：


| 模型                     | 用途                                                |
| ---------------------- | ------------------------------------------------- |
| `AIConfig`             | 多厂商 AI Key / Base / 模型列表（如 deepseek、kimi）         |
| `Site60sDisabled`      | 60s 功能在前端隐藏的 `feature_id`                         |
| `SiteAIRuntime`        | DeepSeek 兼容网关（Base + Key + 默认模型），优先级高于部分 AIConfig |
| `Site60sUpstream`      | 60s 上游节点（单例 id=1）                                 |
| `SiteAIModelDisabled`  | AI 应用在前端隐藏的 `app_id`                              |
| `SiteFeatureCardClick` | 四大板块功能卡片点击统计（`section` + `item_id` 联合主键）          |


---

## 路由概览（`internal/router/router.go`）

### CORS

全局 `middleware.CORS()`，放行常用 Method/Header（含 `Authorization`、`X-Site-Admin-Token`）。

### 认证与用户


| 方法  | 路径                  | 说明             |
| --- | ------------------- | -------------- |
| GET | `/api/auth/check`   | 可选 JWT：校验登录态   |
| GET | `/api/user/profile` | **需 JWT**：用户资料 |


实际登录、发 token 由 **萌芽账户认证中心** 完成；后端校验 JWT。

### 站点公开配置（无需登录）


| 方法   | 路径                                        | 说明                              |
| ---- | ----------------------------------------- | ------------------------------- |
| GET  | `/api/site/60s-disabled`                  | 被隐藏的 60s `feature_id` 列表        |
| GET  | `/api/site/60s-source`                    | 60s 上游 `source_id` / `base_url` |
| GET  | `/api/site/ai-model-disabled`             | 被隐藏的 AI 应用 id 列表                |
| GET  | `/api/site/feature-card-clicks?section=`  | 功能卡片点击次数（见下）                    |
| POST | `/api/site/feature-card-clicks/increment` | 上报一次点击，返回最新 count               |


`**section` 合法值**：`60sapi` · `smallgame` · `toolbox` · `aimodel`

**increment 请求体**：`{ "section": "...", "item_id": "..." }`

### 站点管理（需 `X-Site-Admin-Token`，与环境变量 `INFOGENIE_SITE_ADMIN_TOKEN` 一致）


| 方法      | 路径                                  | 说明                     |
| ------- | ----------------------------------- | ---------------------- |
| PUT     | `/api/admin/site/60s-disabled`      | 更新 60s 隐藏列表            |
| PUT     | `/api/admin/site/60s-source`        | 切换 60s 上游              |
| PUT     | `/api/admin/site/ai-model-disabled` | 更新 AI 应用隐藏列表           |
| GET/PUT | `/api/admin/site/ai-runtime`        | 读取/更新 DeepSeek 兼容运行时配置 |
| GET     | `/api/admin/site/diagnostics`       | 连接与进程配置快照（不含密钥明文）      |


### AI 应用（`/api/aimodelapp`，默认 **需 JWT**）


| 方法   | 路径                 | 说明                                              |
| ---- | ------------------ | ----------------------------------------------- |
| POST | `/chat`            | 非流式对话，JSON 返回全文                                 |
| POST | `/chat/stream`     | **SSE 流式**：透传上游 OpenAI 兼容流（`text/event-stream`） |
| POST | `/name-analysis` 等 | 各垂直能力（姓名、变量命名、写诗、翻译等）                           |
| GET  | `/models`          | 模型列表                                            |


**流式说明**（`internal/handler/aimodel.go` + `internal/service/ai.go`）：

- 上游请求带 `stream: true`，成功后将上游 body **分块写入并 Flush** 到客户端。
- 支持 **deepseek**（运行时或 `AIConfig`）与 **kimi**（`AIConfig`）。
- 与 `/chat` 共用同一套 `bindAIModelChat` 校验（消息条数、长度、模型白名单等）。

**模型白名单**：见 `internal/handler/aimodel.go` 中 `allowedModels`（如 deepseek-chat、deepseek-reasoner、部分 kimi 模型）。

---

## 核心源码目录

```
cmd/server/          # main
config/              # 配置加载（含 Redis）
internal/
  cache/             # Redis 可选封装（Get/Set JSON、Delete、Ping）
  database/          # MySQL 初始化、AutoMigrate
  handler/           # HTTP 处理器（auth、user、aimodel、siteconfig、ai_runtime、feature_card_clicks）
  middleware/        # CORS、JWT
  model/             # GORM 模型
  router/            # 路由注册（含 /api/health、diagnostics）
  service/           # AI 调用（含 OpenAI 兼容非流式与流式）
scripts/redis_keyspace/   # 可选：本地查看各逻辑库 keyspace（go run，需 REDIS_PASSWORD）
```

---

## 与其他工程的关系

- **前端 SPA** 通过 `VITE_API_URL` 指向本服务（开发默认 `http://127.0.0.1:5002`）。
- `**public/aimodelapp/*/shared/ai-chat.js`** 优先调用 `/api/aimodelapp/chat/stream`，失败时回退 `/chat`。

更完整的前端集成说明见 `**infogenie-frontend/前端文档.md**`。