feat(api): 添加汇总记录提交API接口
添加新的API端点/api/v1/summary/submit/用于外部客户端提交汇总记录 自动设置分类为"定期",发言人为"机器人" 包含请求参数验证和错误处理 更新README文档添加API使用说明和示例代码
This commit is contained in:
168
README.md
168
README.md
@@ -1457,6 +1457,174 @@ celery -A diary_family flower --port=5555
|
|||||||
|
|
||||||
访问 http://your-server:5555 查看任务监控界面。
|
访问 http://your-server:5555 查看任务监控界面。
|
||||||
|
|
||||||
|
## API接口文档
|
||||||
|
|
||||||
|
系统提供RESTful API接口,用于外部客户端提交汇总记录。
|
||||||
|
|
||||||
|
### 1. 汇总记录提交API
|
||||||
|
|
||||||
|
用于外部客户端(如监控脚本、自动化任务)向系统提交汇总记录。
|
||||||
|
|
||||||
|
#### 请求信息
|
||||||
|
|
||||||
|
- **URL**: `/api/v1/summary/submit/`
|
||||||
|
- **方法**: `POST`
|
||||||
|
- **Content-Type**: `application/x-www-form-urlencoded` 或 `multipart/form-data`
|
||||||
|
|
||||||
|
#### 请求参数
|
||||||
|
|
||||||
|
| 参数名 | 类型 | 必填 | 说明 |
|
||||||
|
|-------|------|------|------|
|
||||||
|
| content | string | 是 | 汇总记录内容,最大长度不限 |
|
||||||
|
|
||||||
|
#### 响应格式
|
||||||
|
|
||||||
|
**成功响应** (HTTP 200):
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"success": true,
|
||||||
|
"message": "提交成功",
|
||||||
|
"id": 123
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**失败响应** (HTTP 400/500):
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"success": false,
|
||||||
|
"message": "错误信息描述"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 调用示例
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 使用 curl 提交汇总记录
|
||||||
|
curl -X POST http://your-server/api/v1/summary/submit/ \
|
||||||
|
-d "content=这是自动提交的汇总内容"
|
||||||
|
|
||||||
|
# Python requests 调用示例
|
||||||
|
import requests
|
||||||
|
|
||||||
|
url = "http://your-server/api/v1/summary/submit/"
|
||||||
|
data = {
|
||||||
|
"content": "监控报告:系统运行正常,CPU使用率15%,内存使用率42%"
|
||||||
|
}
|
||||||
|
|
||||||
|
response = requests.post(url, data=data)
|
||||||
|
result = response.json()
|
||||||
|
print(result)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 客户端自动提交示例
|
||||||
|
|
||||||
|
创建一个Python脚本用于自动提交系统监控数据:
|
||||||
|
|
||||||
|
```python
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
# submit_summary.py
|
||||||
|
|
||||||
|
import socket
|
||||||
|
import psutil
|
||||||
|
import requests
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
def get_system_info():
|
||||||
|
"""获取系统基本信息"""
|
||||||
|
cpu_percent = psutil.cpu_percent(interval=1)
|
||||||
|
memory = psutil.virtual_memory()
|
||||||
|
disk = psutil.disk_usage('/')
|
||||||
|
return {
|
||||||
|
'cpu': cpu_percent,
|
||||||
|
'memory': memory.percent,
|
||||||
|
'disk': disk.percent
|
||||||
|
}
|
||||||
|
|
||||||
|
def submit_summary(content):
|
||||||
|
"""提交汇总记录到家庭日报系统"""
|
||||||
|
url = "http://your-server/api/v1/summary/submit/"
|
||||||
|
try:
|
||||||
|
response = requests.post(url, data={'content': content}, timeout=10)
|
||||||
|
result = response.json()
|
||||||
|
if result['success']:
|
||||||
|
print(f"提交成功,记录ID: {result['id']}")
|
||||||
|
else:
|
||||||
|
print(f"提交失败: {result['message']}")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"请求异常: {str(e)}")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
info = get_system_info()
|
||||||
|
timestamp = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
|
||||||
|
content = f"[系统监控 {timestamp}] CPU使用率: {info['cpu']}%, 内存使用率: {info['memory']}%, 磁盘使用率: {info['disk']}%"
|
||||||
|
submit_summary(content)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 注意事项
|
||||||
|
|
||||||
|
1. **数据验证**:API仅接受以下条件的记录:
|
||||||
|
- 分类必须为"定期"
|
||||||
|
- 发言人必须为"机器人"
|
||||||
|
- 内容不能为空
|
||||||
|
|
||||||
|
2. **来源自动生成**:系统会自动获取客户端的主机名和IP地址,填充到source字段。
|
||||||
|
|
||||||
|
3. **日期自动设置**:记录日期自动设置为提交时的日期。
|
||||||
|
|
||||||
|
4. **错误处理**:如果分类或发言人不存在,API会返回错误信息。
|
||||||
|
|
||||||
|
### 2. 初始化必需数据
|
||||||
|
|
||||||
|
在使用API提交功能前,需要确保数据库中存在以下数据:
|
||||||
|
|
||||||
|
#### 方法一:Django Shell初始化
|
||||||
|
|
||||||
|
```bash
|
||||||
|
python manage.py shell -c "
|
||||||
|
from core.models import SummaryCategory, FamilyMember
|
||||||
|
|
||||||
|
# 创建'定期'分类(如果不存在)
|
||||||
|
category, created = SummaryCategory.objects.get_or_create(name='定期')
|
||||||
|
if created:
|
||||||
|
print('创建分类: 定期')
|
||||||
|
else:
|
||||||
|
print('分类已存在: 定期')
|
||||||
|
|
||||||
|
# 创建'机器人'发言人(如果不存在)
|
||||||
|
speaker, created = FamilyMember.objects.get_or_create(name='机器人')
|
||||||
|
if created:
|
||||||
|
print('创建发言人: 机器人')
|
||||||
|
else:
|
||||||
|
print('发言人已存在: 机器人')
|
||||||
|
|
||||||
|
print('初始化完成')
|
||||||
|
"
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 方法二:Django Admin后台创建
|
||||||
|
|
||||||
|
1. 登录后台管理:`/houtai`
|
||||||
|
2. 在 **汇总分类** 中添加名为"定期"的分类
|
||||||
|
3. 在 **家庭成员** 中添加名为"机器人"的成员
|
||||||
|
|
||||||
|
### 3. 常见问题排查
|
||||||
|
|
||||||
|
#### 问题1:提交返回"分类 '定期' 不存在"
|
||||||
|
|
||||||
|
**解决方法**:在数据库中创建该分类(见上方初始化方法)
|
||||||
|
|
||||||
|
#### 问题2:提交返回"发言人 '机器人' 不存在"
|
||||||
|
|
||||||
|
**解决方法**:在数据库中创建该发言人(见上方初始化方法)
|
||||||
|
|
||||||
|
#### 问题3:提交返回"内容不能为空"
|
||||||
|
|
||||||
|
**解决方法**:确保请求中包含 `content` 参数且不为空
|
||||||
|
|
||||||
|
#### 问题4:返回HTTP 405错误
|
||||||
|
|
||||||
|
**解决方法**:确认使用的是POST方法,不是GET方法
|
||||||
|
|
||||||
## 注意事项
|
## 注意事项
|
||||||
|
|
||||||
1. 定期备份数据库
|
1. 定期备份数据库
|
||||||
|
|||||||
@@ -29,6 +29,9 @@ urlpatterns = [
|
|||||||
path('summaries/<int:pk>/edit/', views.edit_summary, name='edit_summary'),
|
path('summaries/<int:pk>/edit/', views.edit_summary, name='edit_summary'),
|
||||||
path('summaries/<int:pk>/delete/', views.delete_summary, name='delete_summary'),
|
path('summaries/<int:pk>/delete/', views.delete_summary, name='delete_summary'),
|
||||||
|
|
||||||
|
# API - 汇总记录提交
|
||||||
|
path('api/v1/summary/submit/', views.api_submit_summary, name='api_submit_summary'),
|
||||||
|
|
||||||
# 家庭事项
|
# 家庭事项
|
||||||
path('family-tasks/', views.family_tasks, name='family_tasks'),
|
path('family-tasks/', views.family_tasks, name='family_tasks'),
|
||||||
path('family-tasks/add/', views.add_family_task, name='add_family_task'),
|
path('family-tasks/add/', views.add_family_task, name='add_family_task'),
|
||||||
|
|||||||
@@ -804,3 +804,57 @@ def pdf_list(request):
|
|||||||
}
|
}
|
||||||
|
|
||||||
return render(request, 'core/pdf_list.html', context)
|
return render(request, 'core/pdf_list.html', context)
|
||||||
|
|
||||||
|
def api_submit_summary(request):
|
||||||
|
"""API提交汇总记录 - 仅接受指定分类和发言人的记录"""
|
||||||
|
logger.info("API: 收到汇总记录提交请求")
|
||||||
|
|
||||||
|
if request.method != 'POST':
|
||||||
|
return JsonResponse({'success': False, 'message': '只支持POST请求'}, status=405)
|
||||||
|
|
||||||
|
try:
|
||||||
|
import socket
|
||||||
|
import uuid
|
||||||
|
|
||||||
|
content = request.POST.get('content', '').strip()
|
||||||
|
|
||||||
|
if not content:
|
||||||
|
return JsonResponse({'success': False, 'message': '内容不能为空'}, status=400)
|
||||||
|
|
||||||
|
category_name = "定期"
|
||||||
|
speaker_name = "机器人"
|
||||||
|
|
||||||
|
try:
|
||||||
|
category = SummaryCategory.objects.get(name=category_name)
|
||||||
|
except SummaryCategory.DoesNotExist:
|
||||||
|
logger.error(f"API: 分类 '{category_name}' 不存在")
|
||||||
|
return JsonResponse({'success': False, 'message': f"分类 '{category_name}' 不存在"}, status=400)
|
||||||
|
|
||||||
|
try:
|
||||||
|
speaker = FamilyMember.objects.get(name=speaker_name)
|
||||||
|
except FamilyMember.DoesNotExist:
|
||||||
|
logger.error(f"API: 发言人 '{speaker_name}' 不存在")
|
||||||
|
return JsonResponse({'success': False, 'message': f"发言人 '{speaker_name}' 不存在"}, status=400)
|
||||||
|
|
||||||
|
hostname = socket.gethostname()
|
||||||
|
local_ip = socket.gethostbyname(hostname)
|
||||||
|
source = f"{hostname} ({local_ip})"
|
||||||
|
|
||||||
|
summary = Summary.objects.create(
|
||||||
|
date=timezone.now().date(),
|
||||||
|
category=category,
|
||||||
|
speaker=speaker,
|
||||||
|
content=content,
|
||||||
|
source=source
|
||||||
|
)
|
||||||
|
|
||||||
|
logger.info(f"API: 汇总记录创建成功,ID={summary.id}")
|
||||||
|
return JsonResponse({
|
||||||
|
'success': True,
|
||||||
|
'message': '提交成功',
|
||||||
|
'id': summary.id
|
||||||
|
})
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"API: 提交汇总记录失败: {str(e)}")
|
||||||
|
return JsonResponse({'success': False, 'message': f"提交失败: {str(e)}"}, status=500)
|
||||||
|
|||||||
Reference in New Issue
Block a user