# API 接口参考 **本文引用的文件** - [AI_AGENT.md](file://AI_AGENT.md) - [readme.md](file://readme.md) - [ai-gateway/src/main/java/com/zsjz/gateway/config/CorsConfig.java](file://ai-gateway/src/main/java/com/zsjz/gateway/config/CorsConfig.java) - [ai-gateway/src/main/java/com/zsjz/gateway/admin/AdminAuthWebFilter.java](file://ai-gateway/src/main/java/com/zsjz/gateway/admin/AdminAuthWebFilter.java) - [ai-gateway/src/main/java/com/zsjz/gateway/route/LoginRequestFilter.java](file://ai-gateway/src/main/java/com/zsjz/gateway/route/LoginRequestFilter.java) - [ai-gateway/src/main/java/com/zsjz/gateway/route/LoginResponseFilter.java](file://ai-gateway/src/main/java/com/zsjz/gateway/route/LoginResponseFilter.java) - [ai-gateway/src/main/java/com/zsjz/gateway/route/StickyRouteFilter.java](file://ai-gateway/src/main/java/com/zsjz/gateway/route/StickyRouteFilter.java) - [ai-gateway/src/main/java/com/zsjz/gateway/support/GatewayErrorHandler.java](file://ai-gateway/src/main/java/com/zsjz/gateway/support/GatewayErrorHandler.java) - [ai-server/src/main/java/com/zsjz/ai/common/config/CorsConfig.java](file://ai-server/src/main/java/com/zsjz/ai/common/config/CorsConfig.java) - [ai-server/src/main/java/com/zsjz/ai/common/config/SaTokenWebConfig.java](file://ai-server/src/main/java/com/zsjz/ai/common/config/SaTokenWebConfig.java) - [ai-server/src/main/java/com/zsjz/ai/module/plat/controller/AuthController.java](file://ai-server/src/main/java/com/zsjz/ai/module/plat/controller/AuthController.java) ## 目录 1. [引言](#引言) 2. [项目结构与入口](#项目结构与入口) 3. [统一协议与认证](#统一协议与认证) 4. [网关接口](#网关接口) 5. [系统基础 plat](#系统基础-plat) 6. [Agent 对话](#agent-对话) 7. [AI 清洗](#ai-清洗) 8. [知识检索](#知识检索) 9. [图谱、人员、通话、交易、轨迹、治理、外部表、数据建模](#图谱人员通话交易轨迹治理外部表数据建模) 10. [跨域策略](#跨域策略) 11. [分页、上传下载与速率限制](#分页上传下载与速率限制) 12. [错误码与排查](#错误码与排查) 13. [调用示例](#调用示例) 14. [结论](#结论) ## 引言 清鉴 AI 调查工具由 **ai-gateway(Spring Cloud Gateway)** 和 **ai-server(Spring Boot 3 + MyBatis-Plus + AgentScope)** 两个后端服务组成。前端通过 `/js` 前缀访问,实际请求最终落到 ai-server 的 `/js/a` 上下文路径;开发环境前端代理到 `http://127.0.0.1:8980`。本文按业务域整理 REST 接口参考,并重点说明认证方式、SSE 连接、跨域、分页、上传下载及常见错误排查。 **章节来源** - [AI_AGENT.md](file://AI_AGENT.md) - [readme.md](file://readme.md) ## 项目结构与入口 - 父工程聚合 `ai-server` 与 `ai-gateway`。 - ai-server 启动类为 `com.zsjz.ai.App`,默认端口 `8980`。 - 后端模块根包 `com.zsjz.ai`,业务模块固定取值:`agent`、`call`、`dm`、`external`、`govern`、`graph`、`otg`、`person`、`plat`、`track`、`trans`。 - 所有业务 Controller 位于 `module//controller`,统一返回 `Result`。 ```mermaid graph TB Client["浏览器或 Electron 前端"] --> Gateway["Spring Cloud Gateway
粘性路由 + 管理端鉴权"] Gateway --> ServerA["ai-server 节点 A
/js/a 上下文"] Gateway --> ServerB["ai-server 节点 B
/js/a 上下文"] ServerA --> DB["PostgreSQL / DuckDB / Redis / Neo4j"] ServerB --> DB ``` **图示来源** - [AI_AGENT.md](file://AI_AGENT.md) - [ai-gateway/src/main/java/com/zsjz/gateway/route/StickyRouteFilter.java](file://ai-gateway/src/main/java/com/zsjz/gateway/route/StickyRouteFilter.java) **章节来源** - [AI_AGENT.md](file://AI_AGENT.md) ## 统一协议与认证 ### HTTP 基础 | 项目 | 约定 | |---|---| | 网关对外前缀 | `/js` | | 后端上下文路径 | `/js/a` | | 开发环境代理目标 | `http://127.0.0.1:8980` | | 统一响应体 | `Result`,字段包含 `code`、`message`、`data` | | 成功状态码 | HTTP 200,`Result.code=200` | | 登录态令牌 | 请求头 `x-token` | | 会话实现 | Sa-Token,基于 Redis 存储 token 和用户会话 | ### 认证流程 1. 前端调用 `POST /js/a/auth/login`,携带用户名与密码 JSON。 2. 后端返回 `Result`,其中 `data.token` 是 Sa-Token 凭据。 3. 前端将 `token` 存入本地存储,后续请求在请求头中附加 `x-token`。 4. Sa-Token 拦截器对除白名单外的路径执行登录校验;未登录时返回 HTTP 200 但 `body.code=401`。 5. 网关层根据 `x-token` 解析 userId,并把用户绑定到某个 ai-server 节点,实现粘性路由。 ```mermaid sequenceDiagram participant FE as "前端" participant GW as "网关" participant SV as "ai-server" participant ST as "Sa-Token" FE->>GW: POST /js/a/auth/login {username,password} GW->>SV: 转发登录请求 SV->>ST: 校验账号 ST-->>SV: 登录成功 SV-->>GW: Result{code:200,data:{token,userId,username}} GW->>GW: 记录用户与节点绑定 GW-->>FE: 返回登录结果 FE->>GW: 后续请求 + x-token GW->>GW: 解析 userId → 选择绑定节点 GW->>SV: 转发业务请求 SV-->>GW: Result GW-->>FE: 透传响应 ``` **图示来源** - [ai-server/src/main/java/com/zsjz/ai/module/plat/controller/AuthController.java](file://ai-server/src/main/java/com/zsjz/ai/module/plat/controller/AuthController.java) - [ai-server/src/main/java/com/zsjz/ai/common/config/SaTokenWebConfig.java](file://ai-server/src/main/java/com/zsjz/ai/common/config/SaTokenWebConfig.java) - [ai-gateway/src/main/java/com/zsjz/gateway/route/LoginResponseFilter.java](file://ai-gateway/src/main/java/com/zsjz/gateway/route/LoginResponseFilter.java) - [ai-gateway/src/main/java/com/zsjz/gateway/route/StickyRouteFilter.java](file://ai-gateway/src/main/java/com/zsjz/gateway/route/StickyRouteFilter.java) **章节来源** - [AI_AGENT.md](file://AI_AGENT.md) - [ai-server/src/main/java/com/zsjz/ai/module/plat/controller/AuthController.java](file://ai-server/src/main/java/com/zsjz/ai/module/plat/controller/AuthController.java) - [ai-server/src/main/java/com/zsjz/ai/common/config/SaTokenWebConfig.java](file://ai-server/src/main/java/com/zsjz/ai/common/config/SaTokenWebConfig.java) - [ai-gateway/src/main/java/com/zsjz/gateway/route/LoginResponseFilter.java](file://ai-gateway/src/main/java/com/zsjz/gateway/route/LoginResponseFilter.java) - [ai-gateway/src/main/java/com/zsjz/gateway/route/StickyRouteFilter.java](file://ai-gateway/src/main/java/com/zsjz/gateway/route/StickyRouteFilter.java) ## 网关接口 网关暴露的管理接口统一位于 `/gateway/admin/**`,不走普通业务鉴权,而是由网关自身过滤器处理。 ### 管理接口通用规则 | 项目 | 说明 | |---|---| | URL 模式 | `/gateway/admin/**` | | 前置开关 | `gateway.admin.enabled=false` 时直接返回 404,接口“消失” | | IP 白名单 | `gateway.admin.ip-whitelist`,支持单 IP 与 CIDR,空表示不限 | | 认证方式 | 请求头 `x-token`,经 Sa-Token 共享 Redis 解析出 userId | | 权限要求 | 用户需满足 `sys_user.is_admin=1` 且 `status=1` | | 响应格式 | 网关内部 JSON,结构同 `ApiResult` | ```mermaid flowchart TD Start["进入 /gateway/admin/**"] --> Enabled{"管理接口已启用?"} Enabled -->|否| NotFound["返回 404"] Enabled -->|是| IpCheck["校验来源 IP 白名单"] IpCheck -->|不通过| Forbidden["返回 403"] IpCheck -->|通过| TokenCheck["校验 x-token"] TokenCheck -->|无效| Unauthorized["返回 401"] TokenCheck -->|有效| AdminCheck["检查 is_admin=1 且 status=1"] AdminCheck -->|不通过| Forbidden AdminCheck -->|通过| Pass["放行并注入管理员 userId"] ``` **图示来源** - [ai-gateway/src/main/java/com/zsjz/gateway/admin/AdminAuthWebFilter.java](file://ai-gateway/src/main/java/com/zsjz/gateway/admin/AdminAuthWebFilter.java) **章节来源** - [ai-gateway/src/main/java/com/zsjz/gateway/admin/AdminAuthWebFilter.java](file://ai-gateway/src/main/java/com/zsjz/gateway/admin/AdminAuthWebFilter.java) ## 系统基础 plat ### 认证接口 | 方法 | URL | 请求体 | 响应 | 说明 | |---|---|---|---|---| | POST | `/js/a/auth/login` | `LoginDTO`,包含用户名和密码 | `Result` | 登录成功后返回 token、userId、username | | POST | `/js/a/auth/logout` | 无 | `Result` | 注销 token 并释放该用户占用的案件数据源 | | GET | `/js/a/auth/info` | 无 | `Result` | 获取当前登录用户信息 | | POST | `/js/a/auth/changePwd` | `ChangePwdDTO` | `Result` | 自助修改密码 | | POST | `/js/a/auth/verifyPwd` | `VerifyPwdDTO`,可选 password | `Result` | 锁屏解锁等场景校验密码,失败返回 `data=false` | ### 其他基础接口 Sa-Token 白名单中还开放以下路径,用于健康检查、授权校验、地图静态资源等: - `/js/a/sys/health` - `/js/a/sys/checkAuth` - `/js/a/sys/info` - `/js/a/sys/code` - `/js/a/sys/noNet` - `/js/a/sys/map/**` 这些接口无需登录即可访问。 **章节来源** - [ai-server/src/main/java/com/zsjz/ai/module/plat/controller/AuthController.java](file://ai-server/src/main/java/com/zsjz/ai/module/plat/controller/AuthController.java) - [ai-server/src/main/java/com/zsjz/ai/common/config/SaTokenWebConfig.java](file://ai-server/src/main/java/com/zsjz/ai/common/config/SaTokenWebConfig.java) ## Agent 对话 Agent 子系统围绕 `module/agent` 展开,核心能力包括: - REST 对话接口。 - SSE 流式事件推送。 - 模型与厂商配置。 - SQL 工具执行与结果分页。 - Python 沙箱分析。 - RAG 模板与向量索引。 - 意图识别与追问生成。 - 工作空间元数据。 ### Agent REST 接口概览 | 模块 | 典型 URL 模式 | 用途 | |---|---|---| | 对话 | `/js/a/agent/chat/**` | 发起对话、查询会话消息、停止推理等 | | 模型 | `/js/a/agent/model/**` | 模型与 Provider 的 CRUD | | SQL 结果 | `/js/a/agent/result/**` | `execute_sql` 结果集分页查询 | | Python 文件 | `/js/a/agent/py/files/**` | 访问 Python 产出图片等资源 | | 专家/能力/工具包 | `/js/a/agent/expert/**`、`/js/a/agent/capability/**`、`/js/a/agent/tool-pack/**` | Agent 能力配置 | | 洞察 | `/js/a/agent/insight/**` | 洞察分析相关接口 | Agent 对话 Controller 采用 REST + SSE 混合方式:普通问答走 REST,流式输出走 SSE。SQL 结果分页由独立 Controller 提供,避免长连接阻塞。 **章节来源** - [AI_AGENT.md](file://AI_AGENT.md) ### SSE 连接建立 SSE 属于长连接,客户端需要: 1. 使用原生 `fetch` 或 WebSocket/SSE 客户端发起请求。 2. 请求头携带 `x-token`。 3. 设置 `Accept: text/event-stream`。 4. 保持连接不断开,直到服务端关闭或发送结束事件。 若前端使用浏览器 `fetch`,注意: - 不要自动把响应当作 JSON 解析。 - 逐行读取 `text/event-stream`。 - 遇到连接中断要按重连策略重试。 ### SSE 事件类型 Agent SSE 事件一般包含以下几类语义(具体事件名以各 Controller 实现为准): | 事件类型 | 含义 | |---|---| | 开始事件 | 对话任务已创建并开始处理 | | 文本增量 | 大模型返回的文本片段 | | 工具调用 | 正在调用 `execute_sql`、`render_chart`、`execute_python` 等业务工具 | | 工具结果 | 工具执行完成,附带结构化结果 | | 图表配置 | `render_chart` 返回的 ECharts 配置 | | 错误事件 | 业务异常、工具执行失败、模型调用失败 | | 结束事件 | 对话完成,可清理本地状态 | ### SSE 消息格式 SSE 消息通常包含: - `event`:事件类型。 - `data`:JSON 或纯文本消息体。 - `id`:可选消息标识,便于断线续传。 对于 Agent 对话,`data` 常见字段包括: | 字段 | 类型 | 说明 | |---|---|---| | `sessionId` | 字符串 | 会话标识 | | `messageId` | 字符串 | 消息标识 | | `type` | 字符串 | 消息类型,如思考、工具调用、结果、错误 | | `content` | 字符串 | 人类可读内容 | | `toolName` | 字符串 | 工具名称,如 `execute_sql` | | `resultId` | 字符串 | SQL 结果缓存 ID | | `error` | 字符串 | 错误信息 | ### 心跳保活协议 SSE 保活建议遵循以下原则: 1. 客户端侧定期检测连接是否活跃;长时间无事件时应主动重连。 2. 服务端应保证在较长空闲时间内仍维持连接,或在必要时发送心跳事件。 3. 客户端重连时尽量带上最后收到的 `messageId`,以便服务端补齐遗漏消息。 4. 如果连接被顶下线或 token 失效,服务端可能返回错误事件或断开连接,客户端应据此引导重新登录。 ### Agent 会话关键流程 ```mermaid sequenceDiagram participant FE as "前端" participant GW as "网关" participant AC as "AgentChatController" participant SVC as "AgentChatService" participant TOOLS as "工具集" participant STORE as "SQL 结果缓存" FE->>GW: POST /js/a/agent/chat (x-token) GW->>AC: 转发请求 AC->>SVC: 创建或查找会话 SVC->>TOOLS: 调用意图识别 / 工具 TOOLS->>STORE: execute_sql 写入结果 STORE-->>TOOLS: resultId + 列定义 + 分页信息 SVC-->>AC: 流式事件 AC-->>FE: SSE event/text/data FE->>GW: 拉取 SQL 结果分页 GW->>AC: 转发分页请求 AC-->>FE: 返回结果页 ``` **图示来源** - [AI_AGENT.md](file://AI_AGENT.md) - [ai-gateway/src/main/java/com/zsjz/gateway/route/StickyRouteFilter.java](file://ai-gateway/src/main/java/com/zsjz/gateway/route/StickyRouteFilter.java) **章节来源** - [AI_AGENT.md](file://AI_AGENT.md) ## AI 清洗 AI 清洗模块位于 `module/dm` 与 `module/aiclean`,主要职责是把多源异构数据导入后清洗、映射、治理,并沉淀到 DuckDB 案情库。 ### 典型接口方向 | 模块 | URL 模式 | 功能 | |---|---|---| | 数据建模 | `/js/a/dm/**` | 表元数据、字段映射、导入模板、清洗任务 | | AI 清洗 | `/js/a/aiclean/**` | 智能清洗、值转换、字段短名、同义词 | | 清洗错误日志 | `/js/a/dm/clean-error-log/**` | 查看清洗过程中的错误记录 | ### 输入输出要点 - 输入多为表单、JSON 或文件上传,涉及 Excel、CSV 等表格数据。 - 输出多为 `Result`,分页查询返回 MyBatis-Plus `Page`。 - 金额、比率字段使用 `BigDecimal`,避免浮点精度问题。 **章节来源** - [AI_AGENT.md](file://AI_AGENT.md) ## 知识检索 知识检索围绕 RAG 与知识库展开,涉及: - 知识库 CRUD。 - 模板元数据语义检索。 - 向量索引重建。 - Embedding 调试。 ### 典型接口方向 | 模块 | URL 模式 | 功能 | |---|---|---| | 知识库 | `/js/a/knowledge/**` | 知识库列表、新增、更新、删除、检索 | | Embedding 调试 | `/js/a/embedding/**` | 向量模型调试 | | Agent RAG 工具 | 通过 `search_table_schema` 工具间接暴露 | 基于 pgvector 的模板元数据语义检索 | 知识库下载接口返回裸文件流,不带 `Result` 包装,前端需使用带 `x-token` 的 `fetch` 获取 blob 并触发保存。 **章节来源** - [AI_AGENT.md](file://AI_AGENT.md) ## 图谱、人员、通话、交易、轨迹、治理、外部表、数据建模 ### 图谱 graph | 典型 URL 模式 | 功能 | |---|---| | `/js/a/graph/**` | 关系图查询、图谱节点与边数据 | ### 人员 person | 典型 URL 模式 | 功能 | |---|---| | `/js/a/person/person-basic-info/**` | 人员基本信息 | | `/js/a/person/person-group/**` | 人员分组 | | `/js/a/person/resident-population/**` | 常住人口 | | `/js/a/person/intimacy/**` | 亲密度分析 | | `/js/a/person/data-profile/**` | 人物画像 | ### 通话 call | 典型 URL 模式 | 功能 | |---|---| | `/js/a/call/call-record/**` | 通话原始明细 | | `/js/a/call/call-night/**` | 夜间通话统计 | | `/js/a/call/call-continuous/**` | 持续联系统计 | | `/js/a/call/call-sensitive/**` | 敏感日期联系统计 | ### 交易 trans | 典型 URL 模式 | 功能 | |---|---| | `/js/a/trans/trans-record/**` | 交易记录 | | `/js/a/trans/trans-fund-flow/**` | 资金流水、资金流向图、资金流向轨迹 | | `/js/a/trans/trans-frequency/**` | 高频交易统计 | | `/js/a/trans/trans-continuous/**` | 连续交易统计 | | `/js/a/trans/trans-cash-flow/**` | 现金流水 | | `/js/a/trans/trans-card-hold/**` | 共同持卡 | | `/js/a/trans/trans-financial/**` | 金融账户统计 | | `/js/a/trans/trans-fixed-deposit/**` | 定期存款 | | `/js/a/trans/trans-fast-fund-flow/**` | 快进快出 | | `/js/a/trans/trans-big/**` | 大额交易统计 | | `/js/a/trans/trans-sensitive/**` | 敏感交易统计 | | `/js/a/trans/cash-key/**`、`financial-key/**`、`fixed-deposit-key/**` | 交易关键参数配置 | ### 轨迹 track | 典型 URL 模式 | 功能 | |---|---| | `/js/a/track/track-cell-tower/**` | 基站轨迹 | | `/js/a/track/track-en-local/**` | 本地轨迹 | | `/js/a/track/track-meet/**` | 轨迹相遇 | | `/js/a/track/track-together-live/**` | 同住轨迹 | | `/js/a/track/track-together-travel/**` | 同行轨迹 | | `/js/a/track/express-info/**` | 快递信息 | ### 治理 govern | 典型 URL 模式 | 功能 | |---|---| | `/js/a/govern/**` | 治理任务、治理树 | | `/js/a/govern/govern-tree/**` | 治理树与关联人/银行/通话操作人分页 | ### 外部表 external | 典型 URL 模式 | 功能 | |---|---| | `/js/a/external/**` | 外部表元数据、字段元数据 | ### 数据建模 dm | 典型 URL 模式 | 功能 | |---|---| | `/js/a/dm/**` | 数据建模、清洗、模板、错误日志 | 上述接口普遍遵循: - 查询参数放在 URL 查询串或 JSON body。 - 分页使用 MyBatis-Plus `Page`。 - 金额字段使用 `BigDecimal`。 - 多数接口受 Sa-Token 登录态保护。 **章节来源** - [AI_AGENT.md](file://AI_AGENT.md) ## 跨域策略 跨域由网关与后端共同控制: | 层级 | 行为 | |---|---| | 后端 ai-server | 默认开启 CORS,允许任意 Origin,允许所有方法和请求头,开启 `credentials=true`,暴露 `Content-Disposition`,优先级最高 | | 网关 ai-gateway | 默认关闭 CORS;仅在 `gateway.cors.enabled=true` 时启用,允许所有方法、所有请求头,不携带凭据,暴露 `X-Gateway-Node`、`Content-Disposition`、`X-Request-Id` | 关键点: - 因为鉴权靠 `x-token` 请求头,不属于 Cookie,所以不需要 Cookie 凭证。 - 后端 SSE 和文件下载可能使用带 `credentials: 'include'` 的 fetch,因此后端必须允许凭据。 - 若网关也开启 CORS,不应重复暴露多个 `Access-Control-Allow-Origin`,否则浏览器会拒绝响应。 **章节来源** - [ai-server/src/main/java/com/zsjz/ai/common/config/CorsConfig.java](file://ai-server/src/main/java/com/zsjz/ai/common/config/CorsConfig.java) - [ai-gateway/src/main/java/com/zsjz/gateway/config/CorsConfig.java](file://ai-gateway/src/main/java/com/zsjz/gateway/config/CorsConfig.java) ## 分页、上传下载与速率限制 ### 分页 - 后端统一使用 MyBatis-Plus `Page`。 - 分页拦截器已注册,DuckDB 主库使用 `PaginationInnerInterceptor(DbType.DUCKDB)`。 - 常见分页字段包括页号、页大小、排序条件、过滤条件。 - 部分 Agent 工具(如 `execute_sql`)会返回 `resultId`,再由分页接口拉取结果。 ### 上传 - 上传通常走 multipart/form-data,例如清洗模板、数据文件、知识库附件。 - 网关对登录请求体会做最大 64KB 解析,但普通上传不受该限制约束。 - 下载接口返回裸文件流,不经过 `Result` 包装。 ### 下载 - 下载接口依赖响应头 `Content-Disposition` 传递文件名。 - 后端 CORS 显式暴露 `Content-Disposition`,使跨域前端能读取文件名。 - 前端需用 `fetch` 获取 blob,再触发浏览器保存。 ### 速率限制 当前代码证据中未发现统一的限流控制器或全局限流拦截器。生产环境如需限流,应在网关或应用层增加独立限流组件。现有风险点主要体现在: - 长连接 SSE 未明确看到统一心跳或超时策略。 - 登录请求体解析有 64KB 限制。 - 登录响应体绑定解析有 256KB 限制。 **章节来源** - [AI_AGENT.md](file://AI_AGENT.md) - [ai-gateway/src/main/java/com/zsjz/gateway/route/LoginRequestFilter.java](file://ai-gateway/src/main/java/com/zsjz/gateway/route/LoginRequestFilter.java) - [ai-gateway/src/main/java/com/zsjz/gateway/route/LoginResponseFilter.java](file://ai-gateway/src/main/java/com/zsjz/gateway/route/LoginResponseFilter.java) - [ai-server/src/main/java/com/zsjz/ai/common/config/CorsConfig.java](file://ai-server/src/main/java/com/zsjz/ai/common/config/CorsConfig.java) ## 错误码与排查 ### 通用响应结构 后端统一返回 `Result`: | 字段 | 含义 | |---|---| | `code` | 业务状态码,成功通常为 200 | | `message` | 人类可读消息 | | `data` | 业务数据 | ### 网关错误 网关错误处理器会根据异常类型返回明确 HTTP 状态码: | HTTP 状态 | 含义 | |---|---| | 404 | 无匹配路由或资源不存在 | | 401 | 未登录或 token 失效 | | 403 | 非管理员访问管理接口、IP 不在白名单 | | 502 | 后端节点连接失败或超时 | | 503 | 粘性路由不可用、绑定节点不可用、服务暂无可用节点 | | 500 | 网关内部错误 | ### 常见错误排查 #### 401 未登录或登录失效 可能原因: - 未携带 `x-token`。 - token 过期。 - 账号被新登录顶下线。 - 账号被踢下线。 - token 伪造或 Redis 中会话不存在。 排查步骤: 1. 确认请求头是否携带 `x-token`。 2. 确认是否先调用 `/js/a/auth/login` 拿到 token。 3. 检查 Sa-Token 会话是否仍在 Redis。 4. 检查是否出现“被顶下线”,必要时重新登录。 #### 403 权限不足 可能原因: - 访问 `/gateway/admin/**` 但 IP 不在白名单。 - 访问管理接口但用户不是管理员或已停用。 - 业务层判定无权限。 排查步骤: 1. 确认来源 IP 是否在 `gateway.admin.ip-whitelist`。 2. 确认用户 `is_admin=1` 且 `status=1`。 3. 检查业务逻辑中的权限判断。 #### 503 服务不可用 可能原因: - 用户绑定的节点已停用或 DOWN。 - 用户未绑定节点且服务没有默认节点。 - 当前无可用健康节点。 - 粘性路由选择失败。 排查步骤: 1. 检查网关日志中用户绑定节点。 2. 检查对应 ai-server 节点是否存活。 3. 检查 `defaultNodeId` 是否配置。 4. 不要期望 503 时自动切换到其他节点,因为数据可能留在原节点磁盘。 #### SSE 中断 可能原因: - 网络断开。 - token 失效导致后端返回错误或断开。 - 服务端负载过高或连接超时。 - 前端过早关闭 fetch 或页面卸载。 - 中间代理(Nginx、CDN、浏览器)中断长连接。 排查步骤: 1. 检查浏览器 Network 面板中 SSE 请求状态。 2. 检查是否因 token 失效收到错误事件。 3. 增加客户端重连机制。 4. 检查代理层是否设置了过短的超时时间。 5. 关注网关上游连接失败或超时日志。 **章节来源** - [ai-gateway/src/main/java/com/zsjz/gateway/admin/AdminAuthWebFilter.java](file://ai-gateway/src/main/java/com/zsjz/gateway/admin/AdminAuthWebFilter.java) - [ai-gateway/src/main/java/com/zsjz/gateway/route/StickyRouteFilter.java](file://ai-gateway/src/main/java/com/zsjz/gateway/route/StickyRouteFilter.java) - [ai-gateway/src/main/java/com/zsjz/gateway/support/GatewayErrorHandler.java](file://ai-gateway/src/main/java/com/zsjz/gateway/support/GatewayErrorHandler.java) - [ai-server/src/main/java/com/zsjz/ai/common/config/SaTokenWebConfig.java](file://ai-server/src/main/java/com/zsjz/ai/common/config/SaTokenWebConfig.java) ## 调用示例 ### curl 示例 登录: ```bash curl -X POST http://localhost:8980/js/a/auth/login \ -H "Content-Type: application/json" \ -d '{"username":"admin","password":"your-password"}' ``` 携带 token 调用业务接口: ```bash curl http://localhost:8980/js/a/auth/info \ -H "x-token: 从登录响应 data.token 获取" ``` 下载文件(示例): ```bash curl -o file.xlsx http://localhost:8980/js/a/knowledge/download/xxx \ -H "x-token: 从登录响应 data.token 获取" ``` ### 前端调用示例 使用带 `x-token` 的 `fetch`: ```javascript const res = await fetch('/js/a/auth/info', { headers: { 'x-token': localStorage.getItem('token') } }); const json = await res.json(); if (json.code === 401) { // 跳转登录 } else if (json.code === 200) { // 渲染用户信息 } ``` SSE 调用示例: ```javascript const res = await fetch('/js/a/agent/chat/sse', { method: 'POST', headers: { 'x-token': localStorage.getItem('token'), 'Accept': 'text/event-stream' }, body: JSON.stringify({ message: '分析近期夜间通话异常' }) }); const reader = res.body.getReader(); const decoder = new TextDecoder(); while (true) { const { done, value } = await reader.read(); if (done) break; const text = decoder.decode(value); // 按 event/data 解析 SSE 事件 } ``` **章节来源** - [ai-server/src/main/java/com/zsjz/ai/module/plat/controller/AuthController.java](file://ai-server/src/main/java/com/zsjz/ai/module/plat/controller/AuthController.java) - [AI_AGENT.md](file://AI_AGENT.md) ## 结论 清鉴 AI 调查工具的 API 以 `/js/a` 为后端入口,通过网关进行粘性路由与管理端准入控制。认证基于 Sa-Token,token 通过 `x-token` 请求头传递;所有业务接口默认受登录态保护。Agent 对话同时支持 REST 与 SSE,SSE 需要客户端自行处理连接保活与重连。跨域默认在后端开启,网关默认关闭以避免重复跨域头。分页统一使用 MyBatis-Plus `Page`,下载接口返回裸文件流并依赖 `Content-Disposition` 响应头。常见错误 401、403、503 与 SSE 中断应优先从 token、IP 白名单、节点健康状态和连接生命周期排查。