feat: 初始化考培练系统项目
- 从服务器拉取完整代码 - 按框架规范整理项目结构 - 配置 Drone CI 测试环境部署 - 包含后端(FastAPI)、前端(Vue3)、管理端 技术栈: Vue3 + TypeScript + FastAPI + MySQL
This commit is contained in:
549
docs/规划/考陪练系统API对接规范.md
Normal file
549
docs/规划/考陪练系统API对接规范.md
Normal file
@@ -0,0 +1,549 @@
|
||||
# 考陪练系统 API 对接规范
|
||||
|
||||
> 知识点智能推送功能需要考陪练系统提供的数据查询 API
|
||||
|
||||
---
|
||||
|
||||
## 概述
|
||||
|
||||
SCRM 系统的「知识点智能推送」功能需要调用考陪练系统的 API,**仅用于数据查询**(员工岗位、知识点、课程关系等)。
|
||||
|
||||
**职责划分**:
|
||||
- **考陪练系统**:提供数据查询 API(知识点库、岗位课程关系)
|
||||
- **SCRM AI功能**:负责短板分析、知识点匹配、**动态出题**、效果追踪
|
||||
|
||||
### 对接模式
|
||||
|
||||
```
|
||||
SCRM系统 ────REST API────▶ 考陪练系统
|
||||
│
|
||||
├── 获取员工岗位
|
||||
├── 获取岗位课程
|
||||
├── 搜索知识点
|
||||
└── 获取知识点详情
|
||||
```
|
||||
|
||||
### 认证方式
|
||||
|
||||
**推荐**:内部服务间调用,使用固定 API Key
|
||||
|
||||
```
|
||||
Authorization: Bearer {INTERNAL_API_KEY}
|
||||
```
|
||||
|
||||
或者使用 IP 白名单 + 固定 Token 方式。
|
||||
|
||||
---
|
||||
|
||||
## API 接口列表(共6个)
|
||||
|
||||
> 所有 API 仅用于**数据查询**,不涉及业务逻辑处理
|
||||
|
||||
### 1. 获取员工岗位(通过企微userid)
|
||||
|
||||
根据企微 userid 查询员工在考陪练系统中的岗位信息。
|
||||
|
||||
**请求**
|
||||
|
||||
```
|
||||
GET /api/scrm/employees/{userid}/position
|
||||
```
|
||||
|
||||
| 参数 | 类型 | 必填 | 说明 |
|
||||
|------|------|------|------|
|
||||
| userid | string | 是 | 企微员工userid |
|
||||
|
||||
**响应**
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 0,
|
||||
"message": "success",
|
||||
"data": {
|
||||
"employee_id": 12345,
|
||||
"userid": "zhangxiaomei",
|
||||
"name": "张小美",
|
||||
"positions": [
|
||||
{
|
||||
"position_id": 5,
|
||||
"position_name": "美容顾问",
|
||||
"is_primary": true,
|
||||
"joined_at": "2025-06-01"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**错误码**
|
||||
|
||||
| code | 说明 |
|
||||
|------|------|
|
||||
| 0 | 成功 |
|
||||
| 404 | 员工不存在 |
|
||||
| 40001 | userid 格式错误 |
|
||||
|
||||
---
|
||||
|
||||
### 1.1 获取员工岗位(通过姓名搜索)⭐ 推荐
|
||||
|
||||
根据员工姓名查询岗位信息,支持精确匹配和模糊匹配。**适用于尚未配置企微userid的场景**。
|
||||
|
||||
**请求**
|
||||
|
||||
```
|
||||
GET /api/scrm/employees/search/by-name?name={姓名}
|
||||
```
|
||||
|
||||
| 参数 | 类型 | 必填 | 说明 |
|
||||
|------|------|------|------|
|
||||
| name | string | 是 | 员工姓名(支持精确匹配和模糊匹配) |
|
||||
|
||||
**响应(单个匹配)**
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 0,
|
||||
"message": "success",
|
||||
"data": {
|
||||
"employee_id": 367,
|
||||
"userid": null,
|
||||
"name": "农俊",
|
||||
"positions": [
|
||||
{
|
||||
"position_id": 145,
|
||||
"position_name": "董事长",
|
||||
"is_primary": true,
|
||||
"joined_at": "2025-12-10"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**响应(多个匹配)**
|
||||
|
||||
当有多个同名或姓名相似的员工时,返回候选列表:
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 0,
|
||||
"message": "找到 4 个匹配的员工,请确认后使用 employee_id 精确查询",
|
||||
"data": {
|
||||
"multiple_matches": true,
|
||||
"count": 4,
|
||||
"employees": [
|
||||
{
|
||||
"employee_id": 367,
|
||||
"userid": null,
|
||||
"name": "农俊",
|
||||
"phone": "5653"
|
||||
},
|
||||
{
|
||||
"employee_id": 368,
|
||||
"userid": null,
|
||||
"name": "农美平",
|
||||
"phone": "5078"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 1.2 获取员工岗位(通过员工ID)
|
||||
|
||||
根据员工ID精确查询岗位信息,用于多个同名员工时的精确查询。
|
||||
|
||||
**请求**
|
||||
|
||||
```
|
||||
GET /api/scrm/employees/by-id/{employee_id}/position
|
||||
```
|
||||
|
||||
| 参数 | 类型 | 必填 | 说明 |
|
||||
|------|------|------|------|
|
||||
| employee_id | int | 是 | 员工ID(考陪练系统用户ID) |
|
||||
|
||||
**响应**
|
||||
|
||||
与接口1相同。
|
||||
|
||||
---
|
||||
|
||||
### 2. 获取岗位课程列表
|
||||
|
||||
获取指定岗位的必修/选修课程列表。
|
||||
|
||||
**请求**
|
||||
|
||||
```
|
||||
GET /api/scrm/positions/{position_id}/courses
|
||||
```
|
||||
|
||||
| 参数 | 类型 | 必填 | 说明 |
|
||||
|------|------|------|------|
|
||||
| position_id | int | 是 | 岗位ID |
|
||||
| course_type | string | 否 | 课程类型:required/optional/all,默认all |
|
||||
|
||||
**响应**
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 0,
|
||||
"message": "success",
|
||||
"data": {
|
||||
"position_id": 5,
|
||||
"position_name": "美容顾问",
|
||||
"courses": [
|
||||
{
|
||||
"course_id": 101,
|
||||
"course_name": "医美产品知识",
|
||||
"course_type": "required",
|
||||
"priority": 1,
|
||||
"knowledge_point_count": 25
|
||||
},
|
||||
{
|
||||
"course_id": 102,
|
||||
"course_name": "销售技巧提升",
|
||||
"course_type": "required",
|
||||
"priority": 2,
|
||||
"knowledge_point_count": 18
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 3. 搜索知识点
|
||||
|
||||
根据关键词和岗位搜索匹配的知识点。
|
||||
|
||||
**请求**
|
||||
|
||||
```
|
||||
POST /api/scrm/knowledge-points/search
|
||||
```
|
||||
|
||||
**请求体**
|
||||
|
||||
```json
|
||||
{
|
||||
"keywords": ["玻尿酸", "成分", "功效"],
|
||||
"position_id": 5,
|
||||
"course_ids": [101, 102],
|
||||
"knowledge_type": "产品知识",
|
||||
"limit": 10
|
||||
}
|
||||
```
|
||||
|
||||
| 参数 | 类型 | 必填 | 说明 |
|
||||
|------|------|------|------|
|
||||
| keywords | array | 是 | 搜索关键词列表 |
|
||||
| position_id | int | 否 | 岗位ID(用于优先排序) |
|
||||
| course_ids | array | 否 | 限定课程范围 |
|
||||
| knowledge_type | string | 否 | 知识点类型筛选 |
|
||||
| limit | int | 否 | 返回数量,默认10 |
|
||||
|
||||
**响应**
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 0,
|
||||
"message": "success",
|
||||
"data": {
|
||||
"total": 5,
|
||||
"items": [
|
||||
{
|
||||
"knowledge_point_id": 1001,
|
||||
"name": "玻尿酸分类与特性",
|
||||
"course_id": 101,
|
||||
"course_name": "医美产品知识",
|
||||
"type": "产品知识",
|
||||
"relevance_score": 0.95
|
||||
},
|
||||
{
|
||||
"knowledge_point_id": 1002,
|
||||
"name": "玻尿酸适用人群",
|
||||
"course_id": 101,
|
||||
"course_name": "医美产品知识",
|
||||
"type": "产品知识",
|
||||
"relevance_score": 0.82
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 4. 获取知识点详情
|
||||
|
||||
获取知识点的完整信息。
|
||||
|
||||
**请求**
|
||||
|
||||
```
|
||||
GET /api/scrm/knowledge-points/{knowledge_point_id}
|
||||
```
|
||||
|
||||
| 参数 | 类型 | 必填 | 说明 |
|
||||
|------|------|------|------|
|
||||
| knowledge_point_id | int | 是 | 知识点ID |
|
||||
|
||||
**响应**
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 0,
|
||||
"message": "success",
|
||||
"data": {
|
||||
"knowledge_point_id": 1001,
|
||||
"name": "玻尿酸分类与特性",
|
||||
"course_id": 101,
|
||||
"course_name": "医美产品知识",
|
||||
"type": "产品知识",
|
||||
"content": "玻尿酸(透明质酸,Hyaluronic Acid,简称HA)是一种天然存在于人体内的多糖类物质。按分子量可分为三类:大分子玻尿酸主要用于填充塑形,维持时间较长;中分子玻尿酸用于补水保湿,改善细纹;小分子玻尿酸可深层滋养,促进吸收。在实际应用中,需要根据客户的皮肤状况和需求,推荐合适的类型...",
|
||||
"material_id": 501,
|
||||
"material_type": "pdf",
|
||||
"material_url": "https://xxx/materials/501.pdf",
|
||||
"topic_relation": "医美产品基础知识",
|
||||
"source": 0,
|
||||
"created_at": "2025-06-01 10:00:00"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**字段说明**
|
||||
|
||||
| 字段 | 说明 |
|
||||
|------|------|
|
||||
| content | 知识点完整内容 |
|
||||
| material_id | 关联的课程资料ID(可选) |
|
||||
| material_url | 资料文件URL(可选) |
|
||||
| topic_relation | 与主题的关系描述 |
|
||||
| source | 来源:0=手动创建,1=AI分析生成 |
|
||||
|
||||
> **注意**:30秒精简版内容和测验题由 SCRM AI功能模块生成,考陪练只需提供原始知识点内容。
|
||||
|
||||
---
|
||||
|
||||
## 错误码规范
|
||||
|
||||
| code | HTTP状态码 | 说明 |
|
||||
|------|-----------|------|
|
||||
| 0 | 200 | 成功 |
|
||||
| 400 | 400 | 请求参数错误 |
|
||||
| 401 | 401 | 认证失败 |
|
||||
| 403 | 403 | 无权限 |
|
||||
| 404 | 404 | 资源不存在 |
|
||||
| 500 | 500 | 服务器内部错误 |
|
||||
| 40001 | 400 | userid 格式错误 |
|
||||
| 40002 | 400 | position_id 不存在 |
|
||||
| 40003 | 400 | knowledge_point_id 不存在 |
|
||||
|
||||
---
|
||||
|
||||
## 调用示例
|
||||
|
||||
### Python 示例
|
||||
|
||||
```python
|
||||
import httpx
|
||||
from typing import Optional, List, Dict
|
||||
|
||||
class KaoPeiLianClient:
|
||||
"""考陪练系统API客户端(仅数据查询)"""
|
||||
|
||||
def __init__(self, base_url: str, api_key: str):
|
||||
self.base_url = base_url.rstrip('/')
|
||||
self.api_key = api_key
|
||||
self.headers = {
|
||||
"Authorization": f"Bearer {api_key}",
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
|
||||
async def get_employee_position(self, userid: str) -> Optional[Dict]:
|
||||
"""获取员工岗位"""
|
||||
async with httpx.AsyncClient() as client:
|
||||
response = await client.get(
|
||||
f"{self.base_url}/api/scrm/employees/{userid}/position",
|
||||
headers=self.headers
|
||||
)
|
||||
data = response.json()
|
||||
if data.get("code") == 0:
|
||||
return data.get("data")
|
||||
return None
|
||||
|
||||
async def get_position_courses(self, position_id: int) -> List[Dict]:
|
||||
"""获取岗位课程列表"""
|
||||
async with httpx.AsyncClient() as client:
|
||||
response = await client.get(
|
||||
f"{self.base_url}/api/scrm/positions/{position_id}/courses",
|
||||
headers=self.headers
|
||||
)
|
||||
data = response.json()
|
||||
if data.get("code") == 0:
|
||||
return data.get("data", {}).get("courses", [])
|
||||
return []
|
||||
|
||||
async def search_knowledge_points(
|
||||
self,
|
||||
keywords: List[str],
|
||||
position_id: int = None,
|
||||
limit: int = 10
|
||||
) -> List[Dict]:
|
||||
"""搜索知识点"""
|
||||
payload = {
|
||||
"keywords": keywords,
|
||||
"limit": limit
|
||||
}
|
||||
if position_id:
|
||||
payload["position_id"] = position_id
|
||||
|
||||
async with httpx.AsyncClient() as client:
|
||||
response = await client.post(
|
||||
f"{self.base_url}/api/scrm/knowledge-points/search",
|
||||
headers=self.headers,
|
||||
json=payload
|
||||
)
|
||||
data = response.json()
|
||||
if data.get("code") == 0:
|
||||
return data.get("data", {}).get("items", [])
|
||||
return []
|
||||
|
||||
async def get_knowledge_point_detail(self, kp_id: int) -> Optional[Dict]:
|
||||
"""获取知识点详情"""
|
||||
async with httpx.AsyncClient() as client:
|
||||
response = await client.get(
|
||||
f"{self.base_url}/api/scrm/knowledge-points/{kp_id}",
|
||||
headers=self.headers
|
||||
)
|
||||
data = response.json()
|
||||
if data.get("code") == 0:
|
||||
return data.get("data")
|
||||
return None
|
||||
|
||||
|
||||
# 使用示例
|
||||
async def main():
|
||||
client = KaoPeiLianClient(
|
||||
base_url="https://kaopeilian.example.com",
|
||||
api_key="your_api_key"
|
||||
)
|
||||
|
||||
# 1. 获取员工岗位
|
||||
position = await client.get_employee_position("zhangxiaomei")
|
||||
print(f"岗位: {position['positions'][0]['position_name']}")
|
||||
|
||||
# 2. 获取岗位课程
|
||||
courses = await client.get_position_courses(position['positions'][0]['position_id'])
|
||||
print(f"该岗位有 {len(courses)} 门课程")
|
||||
|
||||
# 3. 搜索知识点
|
||||
knowledge_points = await client.search_knowledge_points(
|
||||
keywords=["玻尿酸", "成分"],
|
||||
position_id=position['positions'][0]['position_id']
|
||||
)
|
||||
print(f"找到 {len(knowledge_points)} 个知识点")
|
||||
|
||||
# 4. 获取知识点详情
|
||||
kp = await client.get_knowledge_point_detail(knowledge_points[0]['knowledge_point_id'])
|
||||
print(f"知识点内容: {kp['content'][:100]}...")
|
||||
|
||||
# 5. 后续由 SCRM AI功能模块处理:
|
||||
# - AI生成30秒精简版
|
||||
# - AI动态生成测验题
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 部署建议
|
||||
|
||||
### 网络连通性
|
||||
|
||||
SCRM 系统与考陪练系统部署在不同服务器,需确保:
|
||||
|
||||
1. **网络互通**:SCRM 服务器可访问考陪练 API 地址
|
||||
2. **防火墙放行**:考陪练 API 端口对 SCRM 服务器 IP 开放
|
||||
3. **超时设置**:建议 API 超时时间设为 10 秒
|
||||
|
||||
### 接口地址配置
|
||||
|
||||
SCRM 系统通过环境变量配置考陪练 API 地址:
|
||||
|
||||
```bash
|
||||
# .env
|
||||
KAOPEILIAN_API_BASE_URL=https://kaopeilian.example.com
|
||||
KAOPEILIAN_API_KEY=your_internal_api_key
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 联调清单
|
||||
|
||||
| 序号 | 接口 | SCRM侧 | 考陪练侧 | 状态 |
|
||||
|------|------|--------|---------|------|
|
||||
| 1 | 获取员工岗位(userid) | 调用方 | 提供方 | ✅ 考陪练侧已完成 |
|
||||
| 1.1 | 获取员工岗位(姓名搜索)⭐ | 调用方 | 提供方 | ✅ 考陪练侧已完成 |
|
||||
| 1.2 | 获取员工岗位(员工ID) | 调用方 | 提供方 | ✅ 考陪练侧已完成 |
|
||||
| 2 | 获取岗位课程 | 调用方 | 提供方 | ✅ 考陪练侧已完成 |
|
||||
| 3 | 搜索知识点 | 调用方 | 提供方 | ✅ 考陪练侧已完成 |
|
||||
| 4 | 获取知识点详情 | 调用方 | 提供方 | ✅ 考陪练侧已完成 |
|
||||
|
||||
## API 接入信息(瑞小美自用)
|
||||
|
||||
| 项目 | 值 |
|
||||
|------|------|
|
||||
| API 基础地址 | `https://aiedu.ireborn.com.cn/api/v1/scrm` |
|
||||
| 认证方式 | Bearer Token |
|
||||
| API Key | `scrm-kpl-api-key-2026-ruixiaomei` |
|
||||
| 请求头格式 | `Authorization: Bearer {API_KEY}` |
|
||||
|
||||
### 快速测试
|
||||
|
||||
```bash
|
||||
# ⭐ 推荐:通过姓名搜索员工岗位(适用于未配置企微userid的场景)
|
||||
curl -X GET "https://aiedu.ireborn.com.cn/api/v1/scrm/employees/search/by-name?name=余丹丹" \
|
||||
-H "Authorization: Bearer scrm-kpl-api-key-2026-ruixiaomei"
|
||||
|
||||
# 通过企微userid获取员工岗位
|
||||
curl -X GET "https://aiedu.ireborn.com.cn/api/v1/scrm/employees/zhangxiaomei_001/position" \
|
||||
-H "Authorization: Bearer scrm-kpl-api-key-2026-ruixiaomei"
|
||||
|
||||
# 通过员工ID精确查询(用于多个同名员工时)
|
||||
curl -X GET "https://aiedu.ireborn.com.cn/api/v1/scrm/employees/by-id/367/position" \
|
||||
-H "Authorization: Bearer scrm-kpl-api-key-2026-ruixiaomei"
|
||||
|
||||
# 搜索知识点
|
||||
curl -X POST "https://aiedu.ireborn.com.cn/api/v1/scrm/knowledge-points/search" \
|
||||
-H "Authorization: Bearer scrm-kpl-api-key-2026-ruixiaomei" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"keywords": ["热玛吉"], "limit": 5}'
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 职责边界说明
|
||||
|
||||
| 功能 | 负责方 | 说明 |
|
||||
|------|--------|------|
|
||||
| 知识点数据存储 | 考陪练 | 知识点、课程、岗位关系 |
|
||||
| 数据查询API | 考陪练 | 本文档定义的4个API |
|
||||
| 短板分析 | SCRM AI功能 | 三维度分析模型 |
|
||||
| 知识点匹配 | SCRM AI功能 | 根据短板匹配知识点 |
|
||||
| 30秒精简版生成 | SCRM AI功能 | AI从原始内容提炼 |
|
||||
| 动态出题 | SCRM AI功能 | AI根据知识点生成测验题 |
|
||||
| 企微推送 | SCRM AI功能 | 发送卡片消息 |
|
||||
| 效果追踪 | SCRM AI功能 | 应用检测、分数对比 |
|
||||
| 管理后台 | SCRM 门户 | 知识点推送模块 |
|
||||
|
||||
---
|
||||
|
||||
*创建于 2026-01-17*
|
||||
*更新于 2026-01-17 - 简化为纯数据查询API,动态出题由SCRM完成*
|
||||
*更新于 2026-01-17 - 考陪练侧4个API已开发完成并测试通过*
|
||||
|
||||
Reference in New Issue
Block a user