保险智能客服系统 — 后续开发计划
文档版本:V1.0
更新日期:2026-06-25
当前状态:后端框架完成,核心功能完成 64%,产品推荐功能待实现
预计工期:2-3 个工作日
一、当前项目状态
1.1 已完成功能(64%)
| 模块 |
功能 |
状态 |
备注 |
| 认证系统 |
企微 OAuth 登录 |
✅ |
需配置真实企微 |
|
账密登录 |
✅ |
admin/admin123456 |
|
Token 刷新 |
✅ |
|
|
退出登录 |
✅ |
|
| 对话功能 |
iframe 嵌入 BaoDan |
✅ |
|
|
险种筛选 |
✅ |
7 种险种 |
|
会话管理 |
✅ |
|
| 用户管理 |
用户 CRUD |
✅ |
|
|
角色权限 |
✅ |
5 种内置角色 |
|
权限校验中间件 |
✅ |
|
| 知识库 |
文档上传/列表/删除 |
✅ |
调用 BaoDan API |
|
文档状态查询 |
✅ |
|
|
数据源 CRUD |
✅ |
|
| 统计报表 |
使用概览 |
✅ |
占位数据 |
|
趋势数据 |
✅ |
占位数据 |
|
知识库健康度 |
✅ |
占位数据 |
|
Token 消耗 |
✅ |
占位数据 |
| 系统管理 |
方案模板管理 |
✅ |
|
|
通知告警配置 |
✅ |
|
|
分组管理 |
✅ |
|
|
Prompt 管理 |
✅ |
|
|
登录日志 |
✅ |
|
|
对话记录 |
✅ |
|
| 导出功能 |
PDF 导出 |
✅ |
|
|
Word 导出 |
✅ |
|
1.2 未完成功能(36%)
| 模块 |
功能 |
优先级 |
工作量 |
| 产品推荐 |
BaoDan Workflow 配置 |
🔴 高 |
0.5 天 |
|
Workflow 调用封装 |
🔴 高 |
0.5 天 |
|
产品推荐 API 联调 |
🔴 高 |
0.5 天 |
| 用户管理 |
批量导入用户 |
🟡 中 |
0.5 天 |
|
数据权限过滤 |
🟡 中 |
0.5 天 |
| 知识库 |
文档编号自动生成 |
🟢 低 |
0.2 天 |
| 企微集成 |
XML 加解密 |
🟡 中 |
0.5 天 |
| 测试 |
功能测试 |
🔴 高 |
1 天 |
二、后续开发计划
Phase 2.5:BaoDan Workflow 配置(0.5 天)
目标:在 Dify 后台配置产品推荐 Workflow
任务清单
| # |
任务 |
说明 |
验证标准 |
| W.1 |
创建 Workflow 应用 |
在 Dify 后台创建新的 Workflow 应用 |
应用创建成功 |
| W.2 |
配置节点1:参数校验 |
Code Node,校验输入参数 |
传入合法参数通过 |
| W.3 |
配置节点2:检索策略生成 |
Code Node,根据险种生成检索策略 |
输出检索策略 JSON |
| W.4 |
配置节点3:知识库检索 |
Knowledge Retrieval Node |
返回相关文档 |
| W.5 |
配置节点4:LLM 方案生成 |
LLM Node,生成推荐方案 |
输出 Markdown 方案 |
| W.6 |
配置节点5:异常处理 |
Code Node,处理异常情况 |
异常时返回友好提示 |
| W.7 |
配置节点6:格式化输出 |
Code Node,格式化为 JSON |
输出结构化方案 |
| W.8 |
配置条件分支 |
根据险种类型分支处理 |
分支逻辑正确 |
| W.9 |
测试验证 |
端到端测试 |
输入客户信息 → 输出 3 套方案 |
Workflow 节点设计
开始
↓
[节点1] 参数校验 (Code Node)
↓
[节点2] 检索策略生成 (Code Node)
↓
[节点3] 知识库检索 (Knowledge Retrieval Node)
↓
[节点4] LLM 方案生成 (LLM Node)
↓
[节点5] 异常处理 (Code Node)
↓
[节点6] 格式化输出 (Code Node)
↓
结束
输入参数
{
"customer_name": "张三",
"customer_age": 30,
"customer_gender": "male",
"health_status": "健康",
"occupation": "工程师",
"annual_income": 300000,
"monthly_budget": 5000,
"insurance_types": ["重疾险", "医疗险"],
"coverage_amount": 500000,
"coverage_period": "至80岁",
"existing_policies": []
}
输出格式
{
"status": "done",
"proposal": {
"customer_name": "张三",
"plans": [
{
"name": "基础方案",
"total_premium": 12000,
"items": [
{
"product_name": "XX重疾险",
"coverage_amount": 300000,
"annual_premium": 8000,
"recommend_reason": "性价比高,保障全面"
}
],
"summary": "适合预算有限的客户"
},
{
"name": "均衡方案",
"total_premium": 18000,
"items": [...],
"summary": "保障与价格平衡"
},
{
"name": "全面方案",
"total_premium": 25000,
"items": [...],
"summary": "保障最全面"
}
],
"disclaimer": "以上方案仅供参考,具体以保险合同为准"
}
}
Phase 3.1:产品推荐后端 API(0.5 天)
目标:实现产品推荐相关的后端 API
任务清单
| # |
任务 |
API |
说明 |
| 3.1.1 |
数据库扩展 |
- |
添加 share_token 等字段 |
| 3.1.2 |
Workflow 调用封装 |
- |
封装 Dify Workflow API |
| 3.1.3 |
生成方案 API |
POST /recommend/generate |
调用 Workflow |
| 3.1.4 |
查询状态 API |
GET /recommend/generate/{task_id} |
轮询任务状态 |
| 3.1.5 |
导出方案 API |
POST /recommend/{id}/export |
PDF/Word 导出 |
| 3.1.6 |
分享链接 API |
POST /recommend/{id}/share |
生成分享链接 |
3.1.1 数据库扩展
-- 添加分享相关字段
ALTER TABLE recommendation_records
ADD COLUMN IF NOT EXISTS share_token VARCHAR(64),
ADD COLUMN IF NOT EXISTS share_expire_at TIMESTAMP;
3.1.2 Workflow 调用封装
文件:api/insurance/recommend/workflow_helper.py
"""BaoDan Workflow 调用封装。"""
import requests
from flask import current_app
class WorkflowHelper:
"""Workflow API 调用封装。"""
def run_workflow(self, inputs: dict, user_id: str) -> dict:
"""
执行 Workflow 获取推荐方案。
Args:
inputs: 客户信息和保险需求
user_id: 用户 ID
Returns:
Workflow 执行结果
"""
base_url = current_app.config.get("BAODAN_API_URL", "http://localhost:5001")
api_key = current_app.config.get("BAODAN_WORKFLOW_API_KEY", "")
resp = requests.post(
f"{base_url}/v1/workflows/run",
json={
"inputs": inputs,
"response_mode": "blocking",
"user": f"recommend_{user_id}",
},
headers={"Authorization": f"Bearer {api_key}"},
timeout=120,
)
return resp.json()
3.1.3 生成方案 API
文件:api/insurance/recommend/routes.py
@recommend_bp.route("/generate", methods=["POST"])
@jwt_required
def generate():
"""生成推荐方案。"""
data = request.get_json()
if not data:
return jsonify({"code": 1001, "message": "请求体不能为空", "data": None}), 400
user_id = request.user_id
# 参数校验(见需求文档 §13.3)
errors = self._validate_params(data)
if errors:
return jsonify({"code": 1001, "message": "; ".join(errors), "data": None}), 400
# 创建推荐记录
from insurance.recommend.service import RecommendService
service = RecommendService()
result = service.create_proposal(user_id, data)
if result["code"] != 0:
return jsonify(result), 400
task_id = result["data"]["task_id"]
# 异步调用 Workflow
import threading
threading.Thread(
target=self._run_workflow_async,
args=(task_id, data, user_id),
daemon=True,
).start()
return jsonify({"code": 0, "data": {"task_id": task_id, "status": "processing"}})
3.1.4 查询状态 API
@recommend_bp.route("/generate/<task_id>", methods=["GET"])
@jwt_required
def get_status(task_id):
"""查询推荐任务状态。"""
from insurance.recommend.service import RecommendService
service = RecommendService()
result = service.get_proposal_status(task_id)
return jsonify(result)
3.1.5 导出方案 API
@recommend_bp.route("/<proposal_id>/export", methods=["POST"])
@jwt_required
def export_proposal(proposal_id):
"""导出推荐方案。"""
data = request.get_json()
format_type = data.get("format", "pdf") # pdf / docx
from insurance.recommend.service import RecommendService
service = RecommendService()
result = service.export_proposal(proposal_id, format_type)
if result["code"] != 0:
return jsonify(result), 400
return jsonify(result)
3.1.6 分享链接 API
@recommend_bp.route("/<proposal_id>/share", methods=["POST"])
@jwt_required
def share_proposal(proposal_id):
"""生成分享链接。"""
from insurance.recommend.service import RecommendService
service = RecommendService()
result = service.create_share_link(proposal_id)
return jsonify(result)
Phase 3.2:产品推荐前端联调(0.5 天)
目标:联调前端与后端 API
已有前端文件
| 文件 |
说明 |
状态 |
| RecommendPage.vue |
推荐主页面 |
✅ 已存在 |
| RecommendForm.vue |
客户信息表单 |
✅ 已存在 |
| RecommendResult.vue |
方案展示组件 |
✅ 已存在 |
| RecommendHistory.vue |
历史方案列表 |
✅ 已存在 |
| RecommendDetail.vue |
方案详情页 |
✅ 已存在 |
需要修改的文件
| 文件 |
修改内容 |
工作量 |
| RecommendPage.vue |
联调 generate API |
0.2 天 |
| RecommendResult.vue |
适配后端返回格式 |
0.2 天 |
| RecommendHistory.vue |
联调 list API |
0.1 天 |
| RecommendDetail.vue |
联调 export/share API |
0.1 天 |
RecommendPage.vue 联调逻辑
async function onSubmit(formData: RecommendRequest) {
loading.value = true
generating.value = true
result.value = null
try {
// 1. 提交生成请求
const submitRes = await api.post('/recommend/generate', formData)
const taskId = submitRes.data.task_id
// 2. 轮询状态
let retries = 0
const maxRetries = 60
while (retries < maxRetries) {
await new Promise(r => setTimeout(r, 2000))
const pollRes = await api.get(`/recommend/generate/${taskId}`)
const task = pollRes.data
if (task.status === 'done') {
result.value = task
ElMessage.success('方案生成成功')
return
}
if (task.status === 'failed') {
ElMessage.error(task.error_message || '方案生成失败')
return
}
retries++
}
ElMessage.warning('生成超时,请稍后在历史方案中查看')
} catch {
// 错误已由 api 拦截器处理
} finally {
loading.value = false
generating.value = false
}
}
Phase 5.1:批量导入用户(0.5 天)
目标:支持 Excel 批量导入用户
任务清单
| # |
任务 |
说明 |
| 5.1.1 |
后端 API |
POST /admin/users/batch-import |
| 5.1.2 |
Excel 解析 |
使用 openpyxl 解析 Excel |
| 5.1.3 |
批量插入 |
批量插入用户记录 |
| 5.1.4 |
前端上传 |
UsersPage 添加导入按钮 |
后端实现
@bp.route("/users/batch-import", methods=["POST"])
@super_admin_required
def batch_import_users():
"""批量导入用户。"""
file = request.files.get("file")
if not file:
return jsonify({"code": 1001, "message": "请选择文件", "data": None}), 400
# 解析 Excel
import openpyxl
wb = openpyxl.load_workbook(file)
ws = wb.active
users = []
for row in ws.iter_rows(min_row=2, values_only=True):
username, department, role = row[0], row[1], row[2]
if username:
users.append({
"username": username,
"department": department or "",
"role": role or "sales",
})
# 批量插入
from insurance.admin.service import AdminService
service = AdminService()
result = service.batch_create_users(users)
return jsonify(result)
前端实现
<!-- UsersPage.vue -->
<el-upload
:action="'/insurance/admin/users/batch-import'"
:headers="uploadHeaders"
:on-success="onImportSuccess"
:on-error="onImportError"
accept=".xlsx,.xls"
:show-file-list="false"
>
<el-button>批量导入</el-button>
</el-upload>
Phase 5.2:数据权限过滤(0.5 天)
目标:实现销售只看自己的数据,主管看本组数据
任务清单
| # |
任务 |
说明 |
| 5.2.1 |
数据权限中间件 |
get_data_scope() 已实现 |
| 5.2.2 |
推荐记录过滤 |
根据权限过滤推荐记录 |
| 5.2.3 |
对话记录过滤 |
根据权限过滤对话记录 |
实现逻辑
# 在查询接口中注入数据权限
def get_proposals(user_id, params):
"""获取推荐记录列表(带数据权限)。"""
from insurance.middleware.auth_middleware import get_data_scope
scope = get_data_scope()
query = db.session.query(RecommendationRecord)
if scope["scope"] == "self":
# 销售:只看自己的
query = query.filter(RecommendationRecord.user_id == user_id)
elif scope["scope"] == "team":
# 主管:看本部门的
query = query.filter(
RecommendationRecord.user_id.in_(
db.session.query(WeComUserMapping.id).filter(
WeComUserMapping.department == scope["department"]
)
)
)
# admin/super_admin:看全部
return query.all()
Phase 7.1:文档编号自动生成(0.2 天)
目标:文档上传时自动生成编号
编号规则
格式:{险种代码}-{保司代码}-{序号}
示例:CJ-XX-001(重疾险-XX人寿-第1个文档)
险种代码:
- CJ = 重疾险
- RS = 寿险
- YL = 医疗险
- YW = 意外险
- CX = 车险
- NJ = 年金险
- CX = 储蓄险
实现
def generate_doc_number(insurance_type: str, company: str) -> str:
"""生成文档编号。"""
type_codes = {
"重疾险": "CJ", "寿险": "RS", "医疗险": "YL",
"意外险": "YW", "车险": "CX", "年金险": "NJ", "储蓄险": "CX",
}
type_code = type_codes.get(insurance_type, "XX")
company_code = company[:2] if company else "XX"
# 查询当前序号
count = db.session.query(DocumentMetadata).filter(
DocumentMetadata.insurance_type == insurance_type,
DocumentMetadata.company == company,
).count()
return f"{type_code}-{company_code}-{count + 1:03d}"
Phase 8.1:功能测试(1 天)
目标:验证所有功能正常工作
测试清单
| # |
测试项 |
测试用例 |
验证标准 |
| X.1 |
登录 |
账密登录 |
返回 token,可访问受保护页面 |
| X.2 |
登录 |
企微 OAuth |
重定向到企微授权页 |
| X.3 |
对话 |
发送消息 |
返回 AI 回答 |
| X.4 |
对话 |
险种筛选 |
切换险种后对话正常 |
| X.5 |
推荐 |
生成方案 |
返回 3 套方案 |
| X.6 |
推荐 |
导出 PDF |
下载 PDF 文件 |
| X.7 |
用户 |
新增用户 |
用户列表增加 |
| X.8 |
用户 |
角色权限 |
非管理员无法访问 /admin |
| X.9 |
知识库 |
上传文档 |
文档出现在列表 |
| X.10 |
统计 |
查看仪表盘 |
显示数据 |
三、开发时间表
第 1 天:产品推荐核心(1.5 天工作量)
| 时间 |
任务 |
产出 |
| 上午 |
Phase 2.5: Workflow 配置 |
Workflow 应用创建完成 |
| 下午 |
Phase 3.1: 后端 API |
generate/status/export/share API |
| 晚上 |
Phase 3.2: 前端联调 |
推荐页面可正常使用 |
第 2 天:增强功能(1.5 天工作量)
| 时间 |
任务 |
产出 |
| 上午 |
Phase 5.1: 批量导入 |
Excel 导入功能 |
| 下午 |
Phase 5.2: 数据权限 |
销售/主管数据隔离 |
| 晚上 |
Phase 7.1: 文档编号 |
自动编号功能 |
第 3 天:测试 + 部署(1 天工作量)
| 时间 |
任务 |
产出 |
| 上午 |
Phase 8.1: 功能测试 |
测试报告 |
| 下午 |
部署 + 文档 |
生产环境部署 |
四、文件变更清单
后端文件
| 文件 |
操作 |
说明 |
| api/insurance/recommend/workflow_helper.py |
修改 |
封装 Workflow 调用 |
| api/insurance/recommend/routes.py |
修改 |
完善 generate/status/export/share |
| api/insurance/recommend/service.py |
修改 |
实现业务逻辑 |
| api/insurance/admin/routes.py |
修改 |
添加 batch-import |
| api/insurance/admin/service.py |
修改 |
实现批量导入 |
| api/insurance/kb/service.py |
修改 |
添加编号生成 |
前端文件
| 文件 |
操作 |
说明 |
| frontend/src/pages/RecommendPage.vue |
修改 |
联调 generate API |
| frontend/src/pages/RecommendResult.vue |
修改 |
适配返回格式 |
| frontend/src/pages/RecommendHistory.vue |
修改 |
联调 list API |
| frontend/src/pages/admin/UsersPage.vue |
修改 |
添加导入按钮 |
五、配置变更
docker-compose.dify.yml
# 更新 Workflow API Key(从 Dify 后台获取)
BAODAN_WORKFLOW_API_KEY: "app-real-workflow-api-key"
数据库变更
-- 添加分享字段
ALTER TABLE recommendation_records
ADD COLUMN IF NOT EXISTS share_token VARCHAR(64),
ADD COLUMN IF NOT EXISTS share_expire_at TIMESTAMP;
六、验收标准
功能验收
| # |
功能 |
验收标准 |
| 1 |
登录 |
账密/企微登录正常 |
| 2 |
对话 |
iframe 嵌入 BaoDan,可对话 |
| 3 |
推荐 |
填写表单 → 生成 3 套方案 |
| 4 |
导出 |
方案可导出 PDF/Word |
| 5 |
用户管理 |
CRUD + 角色权限正常 |
| 6 |
知识库 |
文档上传/列表正常 |
| 7 |
统计 |
仪表盘显示数据 |
性能验收
| # |
指标 |
标准 |
| 1 |
登录响应 |
< 2 秒 |
| 2 |
对话响应 |
< 5 秒 |
| 3 |
推荐生成 |
< 30 秒 |
| 4 |
页面加载 |
< 3 秒 |
七、风险与应对
| 风险 |
影响 |
应对措施 |
| Workflow 配置复杂 |
推荐功能无法使用 |
参考 Dify 官方文档,逐步配置 |
| Workflow 输出格式不稳定 |
方案解析失败 |
在 workflow_helper.py 中加容错解析 |
| 企微 XML 加解密 |
消息回调不通 |
参考企微官方 Python SDK |
| 测试时间不足 |
部署后出现问题 |
优先测试核心功能 |
八、总结
工作量估算
| 任务 |
工作量 |
优先级 |
| Workflow 配置 |
0.5 天 |
🔴 高 |
| 产品推荐 API |
0.5 天 |
🔴 高 |
| 前端联调 |
0.5 天 |
🔴 高 |
| 批量导入 |
0.5 天 |
🟡 中 |
| 数据权限 |
0.5 天 |
🟡 中 |
| 文档编号 |
0.2 天 |
🟢 低 |
| 功能测试 |
1 天 |
🔴 高 |
| 总计 |
3.2 天 |
|
交付物
- 完整的产品推荐功能(Workflow + API + 前端)
- 批量导入用户功能
- 数据权限过滤
- 文档编号自动生成
- 功能测试报告
- 部署文档