PPT 对象选择和绿色选中框。 双击编辑文本框、表格单元格。 文字字体、字号、加粗、颜色、对齐属性。 Ctrl/Cmd+Z、Ctrl/Cmd+Shift+Z 撤销重做。 PPT 缩略图/网格总览切换。 历史版本只读查看。 历史版本“恢复为新版本”,不覆盖旧文件。 海报区块显示/隐藏。 长图区块上移、下移排序。 新背景候选确认,可选择使用新背景或保留原背景。 合规问题“一键采用建议”。 新增 warn 合规级别。 解析失败人工填写入口。 展示解析方法和低质量页诊断。 同步更新了[API 接口文档](/D:/work/code/python/coding/baodanagent/docs/保险智能客服系统_API接口文档.md)。 验证结果: 相关后端测试:28 passed, 1 skipped Python 编译检查:通过 前端生产构建:通过 git diff --check:通过
36 KiB
保险智能客服系统 — API 接口文档
版本:V1.1(与需求文档 V1.0 对齐) 基础路径:
/api认证方式:JWT Bearer Token(Header:Authorization: Bearer <token>) 内容类型:application/json(除文件上传接口外) 接口总数:45 个(含企微/健康检查)
一、全局约定
1.1 统一响应格式
{
"code": 0,
"message": "success",
"data": { ... }
}
code = 0:成功code != 0:失败,message为错误描述,data为 null 或错误详情
1.2 错误码表
| 错误码 | 说明 | 处理建议 |
|---|---|---|
| 0 | 成功 | - |
| 1001 | 参数错误 | 检查请求参数 |
| 1002 | 未授权 | 重新登录 |
| 1003 | Token 已过期 | 调用 refresh-token |
| 1004 | 权限不足 | 联系管理员 |
| 1005 | 资源不存在 | 检查资源 ID |
| 2001 | BaoDan API 调用失败 | 检查 BaoDan 服务 |
| 2002 | BaoDan API 超时 | 重试 |
| 2003 | BaoDan Workflow 失败 | 检查 Workflow 配置 |
| 3001 | 企微 API 调用失败 | 检查企微配置 |
| 4001 | 文件上传失败 | 检查文件格式/大小 |
| 9999 | 服务器内部错误 | 检查日志 |
1.3 分页参数
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| page | int | 1 | 页码 |
| page_size | int | 20 | 每页条数,最大 100 |
1.4 认证方式
所有标注"需要认证"的接口,请求 Header 必须包含:
Authorization: Bearer <JWT_TOKEN>
JWT Token 有效期 2 小时(7200 秒),过期后调用 /api/auth/refresh-token 刷新。
1.5 实现方式标注
| 标注 | 含义 |
|---|---|
| 自研(调 BaoDan) | 自研后端接口,内部调 BaoDan API |
| 自研 | 完全自研 |
| BaoDan 原生 | 直接使用 BaoDan,不需要自研后端 |
| BaoDan + 增强 | BaoDan 有基础,需要少量增强代码 |
二、系统接口
2.1 健康检查
| 项 | 值 |
|---|---|
| URL | GET /api/health |
| 认证 | 不需要 |
| 实现 | 自研 |
响应:
{ "status": "ok" }
2.2 企微机器人回调(URL 验证)
| 项 | 值 |
|---|---|
| URL | GET /api/wecom/callback |
| 认证 | 不需要(企微签名校验) |
| 实现 | 自研 + 企微 API |
参数:msg_signature、timestamp、nonce、echostr
响应:解密后的 echostr(纯文本,非 JSON)
处理逻辑:
- 将 Token、timestamp、nonce、echostr 按字典序排列拼接
- SHA1 哈希,与 msg_signature 比对
- 验证通过则返回解密后的 echostr
2.3 企微机器人消息接收
| 项 | 值 |
|---|---|
| URL | POST /api/wecom/callback |
| 认证 | 不需要(企微签名校验) |
| 实现 | 自研 + 企微 API |
请求体:企微加密的 XML 消息体
响应:success(纯文本,必须在 5 秒内返回)
处理逻辑:
- 验证签名 + 解密 XML
- 判断 MsgType:文本消息继续处理,非文本回复"暂不支持"
- 群聊消息去掉"@机器人"前缀
- 立即返回
success - 异步处理:调 BaoDan Chat API → 通过企微 API 回复用户
2.4 企微 OAuth 登录入口
| 项 | 值 |
|---|---|
| URL | GET /api/wecom/oauth |
| 认证 | 不需要 |
| 实现 | 自研 |
响应:302 重定向到企微授权页面
2.5 企微 OAuth 回调
| 项 | 值 |
|---|---|
| URL | GET /api/wecom/oauth/callback |
| 认证 | 不需要 |
| 实现 | 自研 |
参数:code(企微授权码)、state
处理逻辑:
- 用 code 换取企微 access_token
- 获取用户信息(userid、name、department)
- 查找/创建 wecom_user_mapping 记录
- 生成 JWT Token
- 302 重定向到前端首页
三、认证鉴权(A1)
A1.1.1 企微登录
| 项 | 值 |
|---|---|
| URL | POST /api/auth/wework-login |
| 认证 | 不需要 |
| 实现 | 自研(调 BaoDan) |
请求:
{
"code": "企微授权回调code",
"state": "随机状态值"
}
字段约束:
| 字段 | 类型 | 必填 | 约束 | 错误提示 |
|---|---|---|---|---|
| code | string | 是 | 1-512 字符 | "授权码无效" |
| state | string | 否 | 0-256 字符 | - |
响应:
{
"code": 0,
"data": {
"token": "eyJhbGciOiJIUzI1NiIs...",
"expires_in": 7200,
"user": {
"id": "user-001",
"username": "张三",
"wecom_userid": "zhangsan",
"role": "sales",
"department": "上海团队"
}
}
}
A1.1.2 账密登录
| 项 | 值 |
|---|---|
| URL | POST /api/auth/password-login |
| 认证 | 不需要 |
| 实现 | 自研(调 BaoDan) |
请求:
{
"username": "admin",
"password": "hashed_password"
}
字段约束:
| 字段 | 类型 | 必填 | 约束 | 错误提示 |
|---|---|---|---|---|
| username | string | 是 | 1-64 字符,非空 | "请输入用户名" |
| password | string | 是 | 1-128 字符,非空 | "请输入密码" |
响应:
{
"code": 0,
"data": {
"token": "eyJhbGciOiJIUzI1NiIs...",
"expires_in": 7200
}
}
失败响应:
{ "code": 1002, "message": "用户名或密码错误" }
A1.1.3 刷新 Token
| 项 | 值 |
|---|---|
| URL | POST /api/auth/refresh-token |
| 认证 | 需要(旧 Token) |
| 实现 | 自研(调 BaoDan) |
响应:
{
"code": 0,
"data": { "token": "eyJhbGci...", "expires_in": 7200 }
}
A1.1.4 退出登录
| 项 | 值 |
|---|---|
| URL | POST /api/auth/logout |
| 认证 | 需要 |
| 实现 | 自研 |
处理:将当前 Token 加入黑名单(Redis),后续请求使用该 Token 时返回 1002。
响应:
{ "code": 0, "message": "success" }
四、智能问答(A2)
A2.1.1 发送消息(SSE 流式)
| 项 | 值 |
|---|---|
| URL | POST /api/chat/message |
| 认证 | 需要 |
| 实现 | 自研(调 BaoDan) |
请求:
{
"session_id": "sess-001",
"message": "重疾险的等待期是多少天?",
"filters": { "险种": "重疾险", "保司": null }
}
字段约束:
| 字段 | 类型 | 必填 | 约束 | 枚举 | 错误提示 |
|---|---|---|---|---|---|
| message | string | 是 | 1-10000 字符 | - | "请输入问题内容" |
| session_id | string | 否 | UUID 格式,空串=新对话 | - | "会话ID格式无效" |
| filters | object | 否 | - | - | - |
| filters.险种 | string | 否 | 0-32 字符 | 重疾险/寿险/医疗险/意外险/车险/年金险/储蓄险 | "不支持的险种" |
| filters.保司 | string | 否 | 0-64 字符 | - | - |
响应(SSE 流式,Content-Type: text/event-stream):
data: {"type":"source","data":{"doc_name":"XX重疾险条款.md","chunk":"等待期为合同生效之日起90天..."}}
data: {"type":"delta","data":"根据"}
data: {"type":"delta","data":"XX重疾险条款规定,等待期为90天。"}
data: {"type":"done","data":{"message_id":"msg-001","conversation_id":"conv-001"}}
SSE 事件类型:
| type | 说明 | data 结构 |
|---|---|---|
| source | 来源引用 | {doc_name, chunk, score} |
| delta | 文本增量 | {data: "文本片段"} |
| done | 回答完成 | {message_id, conversation_id} |
| error | 错误 | {message} |
A2.1.2 获取会话列表
| 项 | 值 |
|---|---|
| URL | GET /api/chat/sessions |
| 认证 | 需要 |
| 实现 | 自研(调 BaoDan) |
查询参数:page、page_size
响应:
{
"code": 0,
"data": {
"total": 35,
"items": [
{
"id": "sess-001",
"title": "重疾险等待期问题",
"created_at": "2026-05-31T10:00:00Z",
"updated_at": "2026-05-31T10:05:00Z",
"message_count": 6
}
]
}
}
A2.1.3 创建会话
| 项 | 值 |
|---|---|
| URL | POST /api/chat/sessions |
| 认证 | 需要 |
| 实现 | 自研(调 BaoDan) |
响应:
{ "code": 0, "data": { "session_id": "sess-002" } }
A2.1.4 删除会话
| 项 | 值 |
|---|---|
| URL | DELETE /api/chat/sessions/{id} |
| 认证 | 需要 |
| 实现 | 自研(调 BaoDan) |
路径参数:id(UUID 格式,错误提示:"会话ID格式无效")
响应:
{ "code": 0, "message": "success" }
A2.1.5 获取消息记录
| 项 | 值 |
|---|---|
| URL | GET /api/chat/sessions/{id}/messages |
| 认证 | 需要 |
| 实现 | 自研(调 BaoDan) |
响应:
{
"code": 0,
"data": {
"messages": [
{
"id": "msg-001",
"role": "user",
"content": "重疾险的等待期是多少天?",
"created_at": "2026-05-31T10:00:00Z"
},
{
"id": "msg-002",
"role": "assistant",
"content": "根据 XX 重疾险条款规定,等待期为合同生效之日起90天。",
"sources": [
{"doc_name": "XX重疾险条款.md", "chunk": "等待期为..."}
],
"created_at": "2026-05-31T10:00:05Z"
}
]
}
}
A2.1.6 提交反馈
| 项 | 值 |
|---|---|
| URL | POST /api/chat/messages/{id}/feedback |
| 认证 | 需要 |
| 实现 | 自研(调 BaoDan) |
请求(有用):
{ "rating": "helpful", "comment": null }
请求(纠错):
{ "rating": "not_helpful", "comment": "等待期应该是180天而不是90天" }
字段约束:
| 字段 | 类型 | 必填 | 枚举 | 错误提示 |
|---|---|---|---|---|
| rating | string | 是 | helpful / not_helpful | "评分值无效" |
| comment | string | 否 | 0-2000 字符 | - |
A2.2.1 向量检索
| 项 | 值 |
|---|---|
| URL | POST /api/retrieval/search |
| 认证 | 需要 |
| 实现 | 自研(调 BaoDan) |
请求:
{
"query": "重疾险等待期",
"filters": { "险种": "重疾险", "保司": null },
"top_k": 5
}
字段约束:
| 字段 | 类型 | 必填 | 约束 | 默认值 | 错误提示 |
|---|---|---|---|---|---|
| query | string | 是 | 1-1000 字符 | - | "请输入搜索内容" |
| filters.险种 | string | 否 | 枚举值 | null | "不支持的险种" |
| top_k | int | 否 | 1-20 | 5 | "top_k 应在 1-20 之间" |
响应:
{
"code": 0,
"data": {
"results": [
{
"doc_name": "XX重疾险条款.md",
"chunk": "等待期为合同生效之日起90天...",
"score": 0.92,
"metadata": { "险种": "重疾险", "保司": "XX人寿" }
}
]
}
}
A2.2.2 推荐追问
| 项 | 值 |
|---|---|
| URL | POST /api/chat/suggest |
| 认证 | 需要 |
| 实现 | 自研 |
请求:
{ "message": "根据 XX 重疾险条款规定,等待期为90天。" }
响应:
{
"code": 0,
"data": {
"suggestions": [
"重疾险的免赔额是多少?",
"哪些情况不在理赔范围内?",
"等待期内出险怎么处理?"
]
}
}
五、方案生成(A3)
A3.1.1 生成推荐方案
| 项 | 值 |
|---|---|
| URL | POST /api/recommend/generate |
| 认证 | 需要 |
| 实现 | 自研(调 BaoDan Workflow) |
请求:
{
"customer": {
"name": "李四",
"age": 35,
"gender": "male",
"health_status": "健康",
"occupation": "软件工程师",
"annual_income": 300000,
"monthly_budget": 2000
},
"insurance_types": ["重疾险", "医疗险", "意外险"],
"coverage_amount": 500000,
"coverage_period": "终身",
"existing_policies": []
}
字段约束:
| 字段 | 类型 | 必填 | 约束 | 枚举 | 错误提示 |
|---|---|---|---|---|---|
| customer.age | int | 是 | 0-150 | - | "年龄应在 0-150 之间" |
| customer.gender | string | 是 | - | male/female | "性别值无效" |
| customer.health_status | string | 是 | 1-32 字符 | 健康/有既往病史/慢性病/重大疾病史 | "健康状况值无效" |
| customer.occupation | string | 是 | 1-50 字符 | - | "请输入职业" |
| customer.annual_income | int | 是 | >=0 | - | "年收入不能为负数" |
| customer.monthly_budget | int | 是 | >=1 | - | "月预算必须大于 0" |
| insurance_types | string[] | 是 | 1-10 项 | 寿险/重疾险/医疗险/意外险/年金险/储蓄险 | "请至少选择一个险种" |
| coverage_amount | int | 是 | >=1 | - | "保额必须大于 0" |
| coverage_period | string | 是 | - | 定期10年/20年/30年/保至60岁/70岁/80岁/终身 | "请选择保障期限" |
| existing_policies | object[] | 否 | 0-20 项 | - | - |
响应:
{ "code": 0, "data": { "task_id": "task-001", "status": "processing" } }
A3.1.2 轮询任务状态
| 项 | 值 |
|---|---|
| URL | GET /api/recommend/generate/{task_id} |
| 认证 | 需要 |
| 实现 | 自研 |
字段约束:task_id(UUID 格式,错误提示:"任务ID格式无效")
响应(生成中):
{ "code": 0, "data": { "task_id": "task-001", "status": "processing" } }
响应(完成):
{
"code": 0,
"data": {
"task_id": "task-001",
"status": "done",
"proposal": {
"id": "prop-001",
"plans": [
{
"name": "基础方案",
"total_premium": 4800,
"items": [
{
"product_name": "XX重疾险",
"coverage": 300000,
"premium": 2400,
"reason": "35岁男性投保,性价比高,覆盖120种重疾"
}
],
"summary": "基础保障方案,覆盖重疾、医疗、意外三大类..."
}
]
}
}
}
响应(失败):
{ "code": 0, "data": { "task_id": "task-001", "status": "failed", "error_message": "生成超时" } }
A3.1.3 方案导出
| 项 | 值 |
|---|---|
| URL | POST /api/recommend/{id}/export |
| 认证 | 需要 |
| 实现 | 自研 |
请求:{ "format": "pdf" }
字段约束:
| 字段 | 类型 | 必填 | 枚举 | 错误提示 |
|---|---|---|---|---|
| format | string | 是 | pdf/pptx/docx | "不支持的导出格式" |
响应:
{
"code": 0,
"data": {
"download_url": "https://your-domain.com/api/recommend/{id}/download?token=xxx",
"expire_at": "2026-06-03T10:00:00Z"
}
}
A3.1.4 生成分享链接
| 项 | 值 |
|---|---|
| URL | POST /api/recommend/{id}/share |
| 认证 | 需要 |
| 实现 | 自研 |
请求:{ "expire_hours": 72 }
字段约束:expire_hours(int,1-720,错误提示:"有效期应在 1-720 小时之间")
响应:
{
"code": 0,
"data": {
"share_url": "https://your-domain.com/shared/prop-001?token=xxx",
"expire_at": "2026-06-03T10:00:00Z"
}
}
六、知识库(A4)
A4.1.1 上传文档
| 项 | 值 |
|---|---|
| URL | POST /api/kb/documents/upload |
| Content-Type | multipart/form-data |
| 认证 | 需要 |
| 实现 | 自研(调 BaoDan) |
表单字段:
| 字段 | 类型 | 必填 | 约束 | 错误提示 |
|---|---|---|---|---|
| files | file[] | 是 | 1-50 个文件,每个 <50MB,格式 md/word/txt | "仅支持 MD/Word/TXT 格式" |
| 险种 | string | 是 | 1-32 字符 | "请选择险种" |
| 保司 | string | 是 | 1-64 字符 | "请填写保司名称" |
响应:
{
"code": 0,
"data": {
"upload_id": "upload-001",
"documents": [
{ "doc_id": "doc-001", "filename": "file1.md", "status": "processing" }
]
}
}
A4.1.2 文档列表
| 项 | 值 |
|---|---|
| URL | GET /api/kb/documents |
| 认证 | 需要 |
| 实现 | 自研(调 BaoDan) |
查询参数:
| 参数 | 类型 | 必填 | 约束 | 枚举值 |
|---|---|---|---|---|
| page | int | 否 | >=1,默认 1 | - |
| page_size | int | 否 | 1-100,默认 20 | - |
| 险种 | string | 否 | 0-32 | - |
| 保司 | string | 否 | 0-64 | - |
| status | string | 否 | - | pending/processing/completed/failed |
| keyword | string | 否 | 0-100 | - |
响应:
{
"code": 0,
"data": {
"total": 150,
"items": [
{
"doc_id": "doc-001",
"filename": "XX重疾险条款.md",
"编号": "CJ-XX-001",
"险种": "重疾险",
"保司": "XX人寿",
"tags": ["产品条款", "等待期"],
"status": "completed",
"uploaded_at": "2026-05-15T10:00:00Z",
"processed_at": "2026-05-15T10:05:00Z"
}
]
}
}
A4.1.3 文档处理状态
| 项 | 值 |
|---|---|
| URL | GET /api/kb/documents/{id}/status |
| 认证 | 需要 |
| 实现 | 自研(调 BaoDan) |
响应:
{
"code": 0,
"data": {
"doc_id": "doc-001",
"filename": "XX重疾险条款.md",
"pipeline": [
{ "stage": "upload", "status": "completed", "time": "2026-05-15T10:00:01Z" },
{ "stage": "format_convert", "status": "completed", "time": "2026-05-15T10:00:02Z" },
{ "stage": "chunking", "status": "completed", "time": "2026-05-15T10:00:03Z", "chunk_count": 45 },
{ "stage": "embedding", "status": "completed", "time": "2026-05-15T10:05:00Z" }
]
}
}
A4.1.4 重试失败文档
| 项 | 值 |
|---|---|
| URL | POST /api/kb/documents/{id}/retry |
| 认证 | 需要 |
| 实现 | 自研(调 BaoDan) |
A4.1.5 更新文档元数据
| 项 | 值 |
|---|---|
| URL | PATCH /api/kb/documents/{id} |
| 认证 | 需要 |
| 实现 | 自研(调 BaoDan) |
请求:{ "编号": "CJ-XX-002", "tags": ["产品条款", "核保"] }
字段约束:
| 字段 | 类型 | 必填 | 约束 | 错误提示 |
|---|---|---|---|---|
| 编号 | string | 否 | 0-32 字符 | "编号格式无效" |
| tags | string[] | 否 | 0-20 项,每项 1-32 字符 | - |
A4.1.6 删除文档
| 项 | 值 |
|---|---|
| URL | DELETE /api/kb/documents/{id} |
| 认证 | 需要 |
| 实现 | 自研(调 BaoDan) |
A4.2.1 数据源列表
| 项 | 值 |
|---|---|
| URL | GET /api/kb/datasources |
| 认证 | 需要 |
| 实现 | 自研 |
响应:
{
"code": 0,
"data": [
{
"id": "ds-001",
"name": "XX人寿产品接口",
"api_url": "https://api.xxlife.com/products",
"sync_frequency": "0 2 * * *",
"last_sync": "2026-05-31T02:00:00Z",
"last_sync_status": "success",
"last_sync_count": 156
}
]
}
A4.2.2 新建数据源
| 项 | 值 |
|---|---|
| URL | POST /api/kb/datasources |
| 认证 | 需要(管理员) |
| 实现 | 自研 |
请求:
{
"name": "XX人寿产品接口",
"api_url": "https://api.xxlife.com/products",
"api_key": "encrypted_key_here",
"sync_frequency": "0 2 * * *"
}
A4.2.3 手动同步
| 项 | 值 |
|---|---|
| URL | POST /api/kb/datasources/{id}/sync |
| 认证 | 需要(管理员) |
| 实现 | 自研 |
A4.2.4 同步日志
| 项 | 值 |
|---|---|
| URL | GET /api/kb/datasources/{id}/logs |
| 认证 | 需要(管理员) |
| 实现 | 自研 |
七、用户权限(A5)
A5.1.1 用户管理
| 项 | 值 |
|---|---|
| URL | GET/POST/PUT/DELETE /api/admin/users |
| 认证 | 需要(管理员) |
| 实现 | 自研(调 BaoDan) |
GET 列表请求:GET /api/admin/users?page=1&page_size=20&role=sales&department=上海团队
GET 列表响应:
{
"code": 0,
"data": {
"total": 50,
"items": [
{
"id": "user-001",
"username": "张三",
"wecom_userid": "zhangsan",
"role": "sales",
"department": "上海团队",
"status": "active",
"created_at": "2026-05-01T10:00:00Z",
"last_active_at": "2026-05-31T09:30:00Z"
}
]
}
}
POST 新增请求:
{
"username": "李四",
"wecom_userid": "lisi",
"role": "sales",
"department": "上海团队"
}
字段约束:
| 字段 | 类型 | 必填 | 约束 | 枚举 | 错误提示 |
|---|---|---|---|---|---|
| username | string | 是 | 1-64,不可重复 | - | "用户名已存在" |
| role | string | 是 | - | super_admin/admin/manager/sales | "角色值无效" |
PUT 编辑:PUT /api/admin/users/{id}
DELETE 停用:DELETE /api/admin/users/{id}(停用时吊销所有 Token)
A5.1.2 批量导入用户
| 项 | 值 |
|---|---|
| URL | POST /api/admin/users/batch-import |
| Content-Type | multipart/form-data |
| 认证 | 需要(超级管理员) |
| 实现 | 自研 |
A5.1.3 角色管理
| 项 | 值 |
|---|---|
| URL | GET/POST/PUT/DELETE /api/admin/roles |
| 认证 | 需要(超级管理员) |
| 实现 | 自研 |
GET 响应:
{
"code": 0,
"data": [
{ "id": "role-001", "name": "超级管理员", "permissions": ["*"], "builtin": true },
{ "id": "role-002", "name": "管理员", "permissions": ["kb_manage","log_view","user_manage","config_manage"], "builtin": true },
{ "id": "role-003", "name": "销售主管", "permissions": ["chat","proposal","kb_view","team_stats"], "builtin": true },
{ "id": "role-004", "name": "销售人员", "permissions": ["chat","proposal"], "builtin": true },
{ "id": "role-005", "name": "客户", "permissions": ["chat"], "builtin": true }
]
}
字段约束:
| 字段 | 类型 | 必填 | 约束 | 错误提示 |
|---|---|---|---|---|
| name | string | 是 | 1-32,不可重复 | "角色名已存在" |
| permissions | string[] | 是 | 1-50 项 | "权限标识无效" |
八、系统配置(A6)
A6.1.1 LLM 配置
| 项 | 值 |
|---|---|
| URL | GET/POST/PUT /api/admin/llm-configs |
| 认证 | 需要(超级管理员) |
| 实现 | 自研(调 BaoDan) |
POST 请求:
{
"provider": "deepseek",
"model": "deepseek-chat",
"api_key": "sk-xxxxxxxxxxxx",
"base_url": "https://api.deepseek.com/v1",
"is_default": true,
"params": { "temperature": 0.7, "max_tokens": 4096, "top_p": 0.9 }
}
字段约束:
| 字段 | 类型 | 必填 | 枚举 | 错误提示 |
|---|---|---|---|---|
| provider | string | 是 | deepseek/openai/zhipu/qwen | "不支持的供应商" |
| model | string | 是 | 1-64 字符 | "请输入模型名称" |
| api_key | string | 是 | 1-512 字符 | "请输入 API Key" |
POST 响应:
{
"code": 0,
"data": {
"id": "llm-001",
"provider": "deepseek",
"model": "deepseek-chat",
"api_key_masked": "sk-xxxx****xxxx",
"is_default": true,
"status": "active"
}
}
A6.1.2 连通性测试
| 项 | 值 |
|---|---|
| URL | POST /api/admin/llm-configs/{id}/ping |
| 认证 | 需要(管理员) |
| 实现 | 自研(调 BaoDan) |
响应:
{ "code": 0, "data": { "reachable": true, "latency_ms": 320, "model": "deepseek-chat" } }
A6.1.3 Prompt 管理
| 项 | 值 |
|---|---|
| URL | GET/POST/PUT /api/admin/prompts |
| 认证 | 需要(管理员) |
| 实现 | 自研(调 BaoDan) |
POST 请求:
{
"name": "保险顾问系统提示词",
"type": "system",
"content": "你是一名专业的保险顾问助手...",
"variables": ["险种", "保司"]
}
字段约束:
| 字段 | 类型 | 必填 | 约束 | 错误提示 |
|---|---|---|---|---|
| content | string | 是 | 1-100000 字符 | "Prompt 内容不能为空" |
POST 响应(自动生成版本快照):
{
"code": 0,
"data": {
"id": "prompt-001",
"name": "保险顾问系统提示词",
"version": 3,
"versions": [
{"version": 1, "created_at": "2026-05-01T10:00:00Z"},
{"version": 2, "created_at": "2026-05-15T10:00:00Z"},
{"version": 3, "created_at": "2026-05-31T10:00:00Z"}
]
}
}
A6.1.4 Prompt 测试
| 项 | 值 |
|---|---|
| URL | POST /api/admin/prompts/test |
| 认证 | 需要(管理员) |
| 实现 | 自研(调 BaoDan) |
请求:{ "prompt_id": "prompt-001", "test_query": "重疾险等待期多少天?" }
响应:
{
"code": 0,
"data": {
"response": "根据条款规定,重疾险等待期为90天...",
"latency_ms": 1200,
"token_usage": { "prompt_tokens": 520, "completion_tokens": 180 }
}
}
九、留痕日志(A7)
A7.1.1 问答记录查询
| 项 | 值 |
|---|---|
| URL | GET /api/admin/logs/chat |
| 认证 | 需要(管理员) |
| 实现 | 自研(调 BaoDan) |
查询参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| page | int | 否 | 页码,默认 1 |
| page_size | int | 否 | 每页条数,默认 50 |
| user_id | string | 否 | 按用户筛选 |
| start_date | string | 否 | 开始日期 YYYY-MM-DD |
| end_date | string | 否 | 结束日期 YYYY-MM-DD |
| keyword | string | 否 | 关键词搜索 |
| rating | string | 否 | 评分筛选,枚举 helpful/not_helpful |
| export | string | 否 | 设为 "csv" 时返回 CSV 文件流 |
响应(JSON 模式):
{
"code": 0,
"data": {
"total": 1200,
"items": [
{
"id": "msg-001",
"user_id": "user-001",
"username": "张三",
"question": "重疾险等待期多少天?",
"answer": "等待期为合同生效之日起90天。",
"sources": ["XX重疾险条款.md"],
"rating": "helpful",
"created_at": "2026-05-31T10:00:00Z"
}
]
}
}
响应(CSV 导出):当 export=csv 时返回文件流
Content-Type: text/csv
Content-Disposition: attachment; filename="chat_logs_202605.csv"
A7.1.2 导出对话记录
| 项 | 值 |
|---|---|
| URL | GET /api/admin/logs/chat/export |
| 认证 | 需要(管理员) |
| 实现 | 自研(调 BaoDan) |
查询参数:同 A7.1.1 的筛选参数
响应:返回 CSV 文件流
Content-Type: text/csv
Content-Disposition: attachment; filename="chat_logs_202606.csv"
A7.1.3 系统操作日志
| 项 | 值 |
|---|---|
| URL | GET /api/admin/logs/system |
| 认证 | 需要(超级管理员) |
| 实现 | 自研 |
查询参数:page、page_size、action、user_id
响应:
{
"code": 0,
"data": {
"total": 200,
"items": [
{
"id": "log-001",
"action": "login",
"user_id": "user-001",
"username": "张三",
"ip": "192.168.1.100",
"device": "Chrome/120 Windows",
"detail": "企微 OAuth 登录",
"created_at": "2026-05-31T09:00:00Z"
}
]
}
}
十、统计报表(A8)
A8.1.1 使用概览
| 项 | 值 |
|---|---|
| URL | GET /api/stats/overview |
| 认证 | 需要(管理员) |
| 实现 | 自研 |
响应:
{
"code": 0,
"data": {
"today_chats": 45,
"active_users": 12,
"kb_hit_rate": 0.87,
"total_documents": 1500
}
}
A8.1.2 趋势数据
| 项 | 值 |
|---|---|
| URL | GET /api/stats/trend |
| 认证 | 需要(管理员) |
| 实现 | 自研 |
查询参数:metric(如 chat_count)、start_date、end_date、granularity(day/week/month)
响应:
{
"code": 0,
"data": {
"metric": "chat_count",
"granularity": "day",
"data": [
{ "date": "2026-05-01", "value": 45 },
{ "date": "2026-05-02", "value": 62 }
]
}
}
A8.1.3 知识库健康度
| 项 | 值 |
|---|---|
| URL | GET /api/stats/kb-health |
| 认证 | 需要(管理员) |
| 实现 | 自研 |
查询参数:days
响应:
{
"code": 0,
"data": {
"hot_questions": [{"question": "重疾险等待期多少天", "count": 230}],
"missed_questions": [{"question": "XX新产品费率", "count": 45, "handled": false}],
"coverage": {
"寿险": {"doc_count": 320, "status": "completed"},
"重疾险": {"doc_count": 280, "status": "completed"}
}
}
}
A8.1.4 Token 消耗统计
| 项 | 值 |
|---|---|
| URL | GET /api/stats/token-cost |
| 认证 | 需要(管理员) |
| 实现 | 自研 |
查询参数:start_date、end_date、group_by(model)
响应:
{
"code": 0,
"data": {
"total_tokens": 2500000,
"total_cost_usd": 12.5,
"by_model": [
{"model": "deepseek-chat", "input_tokens": 1500000, "output_tokens": 500000, "cost_usd": 10.0}
],
"daily_trend": [
{"date": "2026-05-01", "tokens": 80000, "cost_usd": 0.4}
]
}
}
十一、接口清单汇总
| # | 方法 | URL | 认证 | 实现 | 对应功能 |
|---|---|---|---|---|---|
| 1 | GET | /api/health | 否 | 自研 | 健康检查 |
| 2 | GET | /api/wecom/callback | 否 | 自研+企微 | 企微回调验证 |
| 3 | POST | /api/wecom/callback | 否 | 自研+企微 | 企微消息接收 |
| 4 | GET | /api/wecom/oauth | 否 | 自研 | OAuth 入口 |
| 5 | GET | /api/wecom/oauth/callback | 否 | 自研 | OAuth 回调 |
| 6 | POST | /api/auth/wework-login | 否 | 自研(调BaoDan) | 企微登录 |
| 7 | POST | /api/auth/password-login | 否 | 自研(调BaoDan) | 账密登录 |
| 8 | POST | /api/auth/refresh-token | 是 | 自研(调BaoDan) | 刷新Token |
| 9 | POST | /api/auth/logout | 是 | 自研 | 退出登录 |
| 10 | POST | /api/chat/message | 是 | 自研(调BaoDan) | 发送消息(SSE) |
| 11 | GET | /api/chat/sessions | 是 | 自研(调BaoDan) | 会话列表 |
| 12 | POST | /api/chat/sessions | 是 | 自研(调BaoDan) | 创建会话 |
| 13 | DELETE | /api/chat/sessions/{id} | 是 | 自研(调BaoDan) | 删除会话 |
| 14 | GET | /api/chat/sessions/{id}/messages | 是 | 自研(调BaoDan) | 消息记录 |
| 15 | POST | /api/chat/messages/{id}/feedback | 是 | 自研(调BaoDan) | 提交反馈 |
| 16 | POST | /api/chat/suggest | 是 | 自研 | 推荐追问 |
| 17 | POST | /api/retrieval/search | 是 | 自研(调BaoDan) | 向量检索 |
| 18 | POST | /api/recommend/generate | 是 | 自研(调BaoDan) | 生成推荐方案 |
| 19 | GET | /api/recommend/generate/{id} | 是 | 自研 | 查询方案状态 |
| 20 | POST | /api/recommend/{id}/export | 是 | 自研 | 方案导出 |
| 21 | POST | /api/recommend/{id}/share | 是 | 自研 | 生成分享链接 |
| 22 | POST | /api/kb/documents/upload | 是 | 自研(调BaoDan) | 上传文档 |
| 23 | GET | /api/kb/documents | 是 | 自研(调BaoDan) | 文档列表 |
| 24 | GET | /api/kb/documents/{id}/status | 是 | 自研(调BaoDan) | 文档处理状态 |
| 25 | POST | /api/kb/documents/{id}/retry | 是 | 自研(调BaoDan) | 重试文档 |
| 26 | PATCH | /api/kb/documents/{id} | 是 | 自研(调BaoDan) | 更新元数据 |
| 27 | DELETE | /api/kb/documents/{id} | 是 | 自研(调BaoDan) | 删除文档 |
| 28 | GET | /api/kb/datasources | 是 | 自研 | 数据源列表 |
| 29 | POST | /api/kb/datasources | 是 | 自研 | 新建数据源 |
| 30 | POST | /api/kb/datasources/{id}/sync | 是 | 自研 | 手动同步 |
| 31 | GET | /api/kb/datasources/{id}/logs | 是 | 自研 | 同步日志 |
| 32 | GET/POST/PUT/DELETE | /api/admin/users | 管理员 | 自研(调BaoDan) | 用户管理 |
| 33 | POST | /api/admin/users/batch-import | 超管 | 自研 | 批量导入 |
| 34 | GET/POST/PUT/DELETE | /api/admin/roles | 超管 | 自研 | 角色管理 |
| 35 | GET/POST/PUT | /api/admin/llm-configs | 超管 | 自研(调BaoDan) | LLM配置 |
| 36 | POST | /api/admin/llm-configs/{id}/ping | 管理员 | 自研(调BaoDan) | 连通性测试 |
| 37 | GET/POST/PUT | /api/admin/prompts | 管理员 | 自研(调BaoDan) | Prompt管理 |
| 38 | POST | /api/admin/prompts/test | 管理员 | 自研(调BaoDan) | Prompt测试 |
| 39 | GET | /api/admin/logs/chat | 管理员 | 自研(调BaoDan) | 问答日志 |
| 40 | GET | /api/admin/logs/chat/export | 管理员 | 自研(调BaoDan) | 导出对话记录 |
| 41 | GET | /api/admin/logs/system | 超管 | 自研 | 系统日志 |
| 42 | GET | /api/stats/overview | 管理员 | 自研 | 使用概览 |
| 43 | GET | /api/stats/trend | 管理员 | 自研 | 趋势数据 |
| 44 | GET | /api/stats/kb-health | 管理员 | 自研 | 知识库健康度 |
| 45 | GET | /api/stats/token-cost | 管理员 | 自研 | Token消耗 |
| 46 | POST | /api/wecom/callback(企微内部) | - | - | 同 #3 |
| 47 | POST | /api/recommend/generate(BaoDan内部) | - | - | 同 #18 |
注:#46 和 #47 是企微/BaoDan 侧视角的接口,实际为同一端点。有效独立接口为 45 个。
11.1 海报用户产品小册子补充接口
以下接口统一要求登录认证,资料详情、预览、修改、删除和生成时都会校验当前用户所有权。
| 方法 | URL | 用途 |
|---|---|---|
| GET | /insurance/poster/product-sources |
查询系统产品、“我的资料”和功能开关状态 |
| GET | /insurance/poster/product-materials |
查询当前用户上传的产品小册子 |
| POST | /insurance/poster/product-materials |
上传 PDF 并异步解析;支持可选 password、companyId、planType |
| GET | /insurance/poster/product-materials/{id} |
查询解析状态和核对数据 |
| PUT | /insurance/poster/product-materials/{id}/confirm |
校验并确认产品规则,确认后可用于生成 |
| POST | /insurance/poster/product-materials/{id}/retry |
解析失败后重新投递任务 |
| GET | /insurance/poster/product-materials/{id}/file |
鉴权预览原 PDF |
| DELETE | /insurance/poster/product-materials/{id} |
软删除本人资料 |
| POST | /insurance/poster/product-materials/{id}/submit-review |
可选:提交公共库审核 |
文案、计划书上传和海报生成接口优先接受:
{
"productSource": {
"type": "user_material",
"id": "123"
}
}
旧请求只传 productId 时仍按系统产品处理。关闭 POSTER_USER_MANUAL_UPLOAD_ENABLED 后,前端隐藏上传入口,后端拒绝私有资料生成请求。
11.2 PPT/海报优化接口(2026-07-31)
生成接口不再接受用户侧脱敏决策;即使旧客户端继续提交 useMaskedData,服务端也会忽略该值,并使用保司/产品配置快照。
| 方法 | URL | 用途 |
|---|---|---|
| GET/POST | /insurance/admin/ppt/scenarios |
查询、新增 PPT 生成场景 |
| PUT/DELETE | /insurance/admin/ppt/scenarios/{code} |
修改、软删除自定义场景;内置场景只能停用 |
| DELETE | /insurance/admin/ppt/companies/{id} |
软删除保司;存在启用产品时拒绝 |
| DELETE | /insurance/admin/ppt/products/{id} |
软删除产品并保留历史快照 |
| DELETE | /insurance/admin/ppt/templates/{id} |
软删除 PPT 模板;内置模板只能停用 |
| DELETE | /insurance/admin/ppt/copy-templates/{id} |
软删除文案模板 |
| POST | /insurance/poster/compliance-check |
返回文案合规状态、哈希、规则编号和字符区间 |
| GET/PUT | /insurance/poster/records/{id}/document |
读取或保存可编辑海报文档 |
| GET | /insurance/poster/records/{id}/background |
读取 AI 背景资产 |
| POST | /insurance/poster/records/{id}/rendered |
上传浏览器合成的最终 PNG 和文档快照 |
| GET | /insurance/ppt/preview/{sessionId}?revision={revision} |
查看当前或指定历史版本预览 |
| POST | /insurance/ppt/preview/{sessionId}/versions/{revision}/restore |
将历史版本复制恢复为新版本 |
保司写接口新增 maskingEnabled、logoEnabled;产品写接口新增 maskingEnabled。开启名称脱敏时 maskedDisplayName 必填。
GET /insurance/ppt/validate/{sessionId} 新增:
{
"canProceed": true,
"blockerCount": 0,
"warningCount": 2,
"infoCount": 0
}
兼容期内继续返回 validated、errorCount、warnCount。利益演示和退保提取问题只进入警告,不影响 canProceed。