# 考陪练系统 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已开发完成并测试通过*

