# 万象口袋 — 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 服务。 --- ## Docker 生产部署(预编译二进制) 1. **本机(Windows)**:在 `infogenie-backend-go` 目录运行 `build-linux-amd64.bat`,生成 `dist/server`(Linux amd64)。 2. **构建镜像**:`docker compose up -d --build`(默认使用 `Dockerfile.prebuilt`,不在服务器执行 `go build`)。 3. **若要在镜像内编译**:`docker compose -f docker-compose.yml -f docker-compose.sourcebuild.yml up -d --build`(使用原 `Dockerfile` 多阶段构建)。 4. **端口**:`docker-compose.yml` 映射 `12364:5002`;浏览器访问的 API 基址须与前端 `VITE_API_URL` 一致(HTTPS 反代或公网可达地址)。 5. **`.env.production`**:容器内 `DB_HOST=127.0.0.1` 指向容器自身,**不能**访问宿主机 MySQL。MySQL/Redis 在宿主机时见仓库内 `.env.production.example` 注释(如 `172.17.0.1`、`host.docker.internal`)。`REDIS_ENABLED=true` 时 Redis 必须可达,否则进程启动即失败。 --- ## 运行与配置 - 环境由 `**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**`。