# 万象口袋 — Java(Spring Boot)后端文档 **技术栈**:Java 17 · Spring Boot 3.5 · Spring Web · Spring Data JPA · Hibernate · MySQL · Spring Data Redis(Lettuce) **模块路径**:Maven 工程 `infogenie-backend-java`(坐标 `com.smyhub.infogenie:infogenie-backend-java`) **入口**:`com.smyhub.infogenie.infogeniebackendjava.InfogenieBackendJavaApplication` — 载入 `application.yaml`、连接 MySQL、按需使用 Redis、启动内嵌 Tomcat。 **与 Go 后端关系**:路由与 JSON 契约与 `infogenie-backend-go` 对齐,便于前端同一份 `REACT_APP_API_URL` 切换端口联调;生产环境当前以 Go 部署为主时,可将前端仍指向 Go 服务。 --- ## 运行与配置 - 配置主文件:[`src/main/resources/application.yaml`](src/main/resources/application.yaml)(占位符 `${VAR:default}` 可被系统环境变量或 IDE Run Configuration 覆盖)。 - Spring Boot **不会自动读取** 仓库内 `.env.development`;该文件仅作文向 `application.yaml` 变量说明(也可自行在 IDE 中一条条导入为环境变量)。 - `**APP_PORT**`:默认 **5002**(与 Go 开发端口一致时需注意二选一占用;亦可改为 5003 等与 Go 错峰)。 - 数据库:通过 `DB_HOST`、`DB_PORT`、`DB_NAME`、`DB_USER`、`DB_PASSWORD` 注入 JDBC URL(yaml 内已给开发用默认值,与 Go `.env.development` 常见配置一致)。 - 认证中心:`AUTH_CENTER_API_URL` → `app.auth-center-url`。 - 站点管理:`INFOGENIE_SITE_ADMIN_TOKEN` → `app.site-admin-token`(请求头 `X-Site-Admin-Token`)。 ### Redis(可选) 业务是否走缓存由 **`app.redis-enabled`**(环境变量 `REDIS_ENABLED`)决定;关闭时服务逻辑直连 MySQL,不在启动阶段强制 Ping Redis。 | 变量 | 说明 | | --- | --- | | `REDIS_ENABLED` | `true` / `false`;映射 `app.redis-enabled` | | `REDIS_HOST` / `REDIS_PORT` | `spring.data.redis.host` / `port` | | `REDIS_PASSWORD` | 可选 | | `REDIS_DB` | 逻辑库编号,默认与 yaml 中示例一致 | | `REDIS_KEY_PREFIX` | `app.redis-key-prefix`,建议与 Go 前缀区分(如 `infogenie:java:`) | | `REDIS_SITE_TTL` | 站点类缓存 TTL(秒)→ `app.redis-site-ttl` | 站点只读接口对 `60s-disabled`、`60s-source`、`ai-model-disabled`、`feature-clicks:{section}` 等做 cache-aside;管理端写入后删除对应 Key(见 `SiteConfigService`、`FeatureClickService`)。 ### 邮件(诊断展示) 管理页 diagnostics 中的 `mail` 块来自环境变量 `MAIL_HOST`、`MAIL_PORT`、`MAIL_USERNAME`、`MAIL_PASSWORD`(仅展示是否配置密码,不落明文)。 --- ## 健康与诊断 ### `GET /api/health`(公开) 响应形状与 Go 一致,供 `AdminPage.js` 中 `normalizeHealthPayload` 解析: - **`status`**:`running` 或 `degraded`(MySQL 未连通或 60s 上游探测失败;**不**因 Redis 将整体标为 degraded,与 Go 一致)。 - **`database`**:`connected` / `disconnected`。 - **`mysql`**:`{ ok, status }`。 - **`redis`**:未启用 `{ enabled: false }`;启用 `{ enabled: true, ok, error? }`。 - **`backend_api`**:`{ ok: true }`。 - **`sixty_api`**:`ok`、`source_id`、`base_url`、`label`、`probe_url`、`http_status`、`latency_ms`、`error`。 **HTTP 状态**:始终 **200**(退化只体现在 JSON `status`),避免前端将健康拉取判为失败。 ### `GET /api/admin/site/diagnostics`(需管理员) 请求头 `X-Site-Admin-Token` 与 `INFOGENIE_SITE_ADMIN_TOKEN` 一致。返回字段与 Go 对齐:`app`(`env`、`listen_addr`、`listen_port`)、`mysql`、`redis`、`sixty_upstream`、`auth_center.api_url`、`mail` 等(不含密钥明文)。 --- **根路径**:`GET /` — 服务说明与主要 endpoint 列表(`version` 为 **3.3.0-java**)。 --- ## 数据库(JPA) `spring.jpa.hibernate.ddl-auto: update` 启动时按实体同步表结构,与 Go `AutoMigrate` 使用同一组业务表: | 实体 | 用途 | | --- | --- | | `AIConfig` | 多厂商 AI Key / Base / 模型 | | `Site60sDisabled` | 60s 前台隐藏 `feature_id` | | `SiteAIRuntime` | DeepSeek 兼容网关(Base + Key + 默认模型),优先级高于部分 `AIConfig` | | `Site60sUpstream` | 60s 上游(单例 `id=1`) | | `SiteAIModelDisabled` | AI 应用前台隐藏 `app_id` | | `SiteFeatureCardClick` | 功能卡片点击(`section` + `item_id` 联合主键);增量 SQL 为 MySQL `INSERT … ON DUPLICATE KEY UPDATE`,对应 Repository 使用 `nativeQuery = true` | --- ## 路由与包结构概览 包根:`com.smyhub.infogenie.infogeniebackendjava` | 包 | 说明 | | --- | --- | | `config` | `WebConfig`(CORS)、`RedisConfig`、`RestTemplateConfig`、`AppProperties` | | `controller` | `Health`、`Auth`、`User`、`SiteConfig`、`Admin`、`AIModel` | | `service` | 站点配置、点击统计、AI 调用、AI 工具提示词、运行时配置、健康探测 | | `repository` | Spring Data JPA | | `entity` | JPA 实体 | | `dto.request` / `dto.response` | 入参与出参;**管理端、`item_id` 等入参使用 snake_case**(`@JsonProperty`),与前端、Go 一致 | | `filter` | `JwtAuthFilter`:将 `Authorization: Bearer` 转发认证中心 `POST …/api/auth/verify`,结果放入 request attribute | | `util` | 管理员令牌校验、AI 辅助方法 | ### CORS `WebConfig` 放宽常用 Method/Header(含 `Authorization`、`X-Site-Admin-Token`)。 ### 认证与用户 | 方法 | 路径 | 说明 | | --- | --- | --- | | GET | `/api/auth/check` | 可选 Bearer:已登录则返回简要 user | | GET | `/api/user/profile` | **需**有效 Bearer | ### 站点公开配置 | 方法 | 路径 | 说明 | | --- | --- | --- | | GET | `/api/site/60s-disabled` | 隐藏 60s id 列表 | | GET | `/api/site/60s-source` | 当前 60s 节点 | | GET | `/api/site/ai-model-disabled` | 隐藏 AI 应用 id | | GET | `/api/site/feature-card-clicks?section=` | 点击统计 | | POST | `/api/site/feature-card-clicks/increment` | body:`section`、`item_id` | ### 站点管理(`X-Site-Admin-Token`) | 方法 | 路径 | 说明 | | --- | --- | --- | | PUT | `/api/admin/site/60s-disabled` | body:`disabled` | | PUT | `/api/admin/site/60s-source` | body:`source_id` | | PUT | `/api/admin/site/ai-model-disabled` | body:`disabled` | | GET/PUT | `/api/admin/site/ai-runtime` | GET 脱敏;PUT body:`api_base`、`api_key`、`default_model`、`default_provider` | | GET | `/api/admin/site/diagnostics` | 配置快照 | ### AI(`/api/aimodelapp`,需 Bearer) | 方法 | 路径 | 说明 | | --- | --- | --- | | POST | `/chat`、`/chat/stream` | 非流式 / SSE 透传 | | POST | `/name-analysis` 等 | 垂直场景 | | GET | `/models` | 白名单模型列表 | 上游解析与 Go 一致:`SiteAIRuntime` 在 base+key 齐全时优先;否则读 `AIConfig`(deepseek/kimi)。 --- ## 常用命令 ```bash cd infogenie-backend-java ./mvnw test ./mvnw spring-boot:run ``` --- ## 与其他工程的关系 - 前端 SPA 通过 `REACT_APP_API_URL` 指向本服务或 Go 服务(路径相同,端口按实际进程调整)。 - 更完整的前端对接说明见 **`infogenie-frontend/前端文档.md`**;Go 行为对照见 **`infogenie-backend-go/后端文档.md`**。