feat: 初始化考培练系统项目

- 从服务器拉取完整代码
- 按框架规范整理项目结构
- 配置 Drone CI 测试环境部署
- 包含后端(FastAPI)、前端(Vue3)、管理端

技术栈: Vue3 + TypeScript + FastAPI + MySQL
This commit is contained in:
111
2026-01-24 19:33:28 +08:00
commit 998211c483
1197 changed files with 228429 additions and 0 deletions

View 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已开发完成并测试通过*