XinXiKuaiBaoYuan/django-backend/tasks/views.py

1336 lines
54 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from rest_framework import viewsets, status
from rest_framework.decorators import action, api_view, permission_classes
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticated, AllowAny
from rest_framework.pagination import PageNumberPagination
from django.contrib.auth.models import User
from django.db.models import Count, Q, Avg
from django.utils import timezone
from datetime import timedelta
import json
from .models import Task, Report, TaskLog
from .serializers import (
TaskSerializer, CreateTaskSerializer, TaskDetailSerializer,
ReportSerializer, ReportListSerializer, UpdateTaskStatusSerializer,
TaskStatisticsSerializer, ReportStatisticsSerializer
)
from .services import TaskService, ReportService, AITitleGenerator
class DynamicPageSizePagination(PageNumberPagination):
page_size_query_param = 'size'
page_size = 10
max_page_size = 100
class TaskViewSet(viewsets.ModelViewSet):
"""任务管理ViewSet"""
serializer_class = TaskSerializer
pagination_class = DynamicPageSizePagination
# permission_classes = [IsAuthenticated] # 暂时注释掉,方便测试
def get_queryset(self):
"""获取当前用户的任务列表"""
# 暂时返回所有任务,实际应该过滤用户
return Task.objects.all()
def get_serializer_class(self):
"""根据action选择序列化器"""
if self.action == 'create':
return CreateTaskSerializer
elif self.action == 'retrieve':
return TaskDetailSerializer
elif self.action == 'update_status':
return UpdateTaskStatusSerializer
return TaskSerializer
def create(self, request):
"""创建任务"""
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
# 暂时使用第一个用户实际应该使用request.user
user = User.objects.first()
if not user:
# 创建默认用户用于测试
user = User.objects.create_user(
username='testuser',
email='test@example.com',
password='testpass123'
)
# 使用服务层创建任务
task = TaskService.create_task(user, serializer.validated_data)
# 返回创建结果
return Response({
'code': 200,
'message': '任务创建成功',
'data': {
'taskId': task.id,
'title': task.title,
'description': task.description,
'status': task.status
},
'timestamp': timezone.now().isoformat(),
'requestId': f'req-{timezone.now().timestamp()}'
}, status=status.HTTP_201_CREATED)
def list(self, request):
"""获取任务列表"""
queryset = self.get_queryset()
# 筛选参数
task_status = request.query_params.get('status')
if task_status:
queryset = queryset.filter(status=task_status)
# 排序(有新报告的任务排在前面)
sort_by = request.query_params.get('sortBy', 'lastReportTime')
sort_order = request.query_params.get('sortOrder', 'desc')
if sort_by == 'lastReportTime':
if sort_order == 'desc':
queryset = queryset.order_by('-last_report_time', '-created_at')
else:
queryset = queryset.order_by('last_report_time', 'created_at')
elif sort_by == 'createdAt':
if sort_order == 'desc':
queryset = queryset.order_by('-created_at')
else:
queryset = queryset.order_by('created_at')
# 分页
page = self.paginate_queryset(queryset)
if page is not None:
serializer = self.get_serializer(page, many=True)
result = self.get_paginated_response(serializer.data)
# 转换为标准响应格式
return Response({
'code': 200,
'data': {
'tasks': result.data['results'],
'total': result.data['count'],
'page': int(request.query_params.get('page', 1)),
'size': int(request.query_params.get('size', 10)),
'totalPages': (result.data['count'] + int(request.query_params.get('size', 10)) - 1) // int(request.query_params.get('size', 10))
},
'timestamp': timezone.now().isoformat(),
'requestId': f'req-{timezone.now().timestamp()}'
})
serializer = self.get_serializer(queryset, many=True)
return Response({
'code': 200,
'data': {
'tasks': serializer.data,
'total': len(serializer.data),
'page': 1,
'size': len(serializer.data),
'totalPages': 1
},
'timestamp': timezone.now().isoformat(),
'requestId': f'req-{timezone.now().timestamp()}'
})
def retrieve(self, request, pk=None):
"""获取单个任务详情"""
try:
task = self.get_object()
serializer = TaskDetailSerializer(task)
return Response({
'code': 200,
'data': serializer.data,
'timestamp': timezone.now().isoformat(),
'requestId': f'req-{timezone.now().timestamp()}'
})
except Task.DoesNotExist:
return Response({
'code': 404,
'message': '任务不存在',
'timestamp': timezone.now().isoformat(),
'requestId': f'req-{timezone.now().timestamp()}'
}, status=status.HTTP_404_NOT_FOUND)
def update(self, request, pk=None):
"""更新任务"""
try:
task = self.get_object()
# 使用CreateTaskSerializer进行验证
serializer = CreateTaskSerializer(data=request.data)
if serializer.is_valid():
# 更新任务基本信息
task.requirement = serializer.validated_data.get('requirement', task.requirement)
task.type = serializer.validated_data.get('type', task.type)
task.schedule_config = serializer.validated_data.get('schedule', task.schedule_config)
task.web_search_enabled = serializer.validated_data.get('webSearchEnabled', task.web_search_enabled)
# 重新生成AI标题和描述如果需求发生变化
if 'requirement' in request.data:
ai_generator = AITitleGenerator()
title, description = ai_generator.generate_title_and_description(task.requirement)
task.title = title
task.description = description
task.updated_at = timezone.now()
task.save()
# 记录日志
from .models import TaskLog
TaskLog.objects.create(
task=task,
action_type='updated',
message=f'任务已更新:{task.title}'
)
return Response({
'code': 200,
'message': '任务更新成功',
'data': {
'taskId': task.id,
'title': task.title,
'description': task.description,
'status': task.status
},
'timestamp': timezone.now().isoformat(),
'requestId': f'req-{timezone.now().timestamp()}'
})
else:
return Response({
'code': 400,
'message': '请求参数错误',
'errors': serializer.errors,
'timestamp': timezone.now().isoformat(),
'requestId': f'req-{timezone.now().timestamp()}'
}, status=status.HTTP_400_BAD_REQUEST)
except Task.DoesNotExist:
return Response({
'code': 404,
'message': '任务不存在',
'timestamp': timezone.now().isoformat(),
'requestId': f'req-{timezone.now().timestamp()}'
}, status=status.HTTP_404_NOT_FOUND)
def destroy(self, request, pk=None):
"""删除任务"""
try:
task = self.get_object()
task_title = task.title
task_id = task.id
# 记录删除日志
from .models import TaskLog
TaskLog.objects.create(
task=task,
action_type='deleted',
message=f'任务已删除:{task_title}'
)
# 删除任务(相关的报告和日志会通过外键级联删除)
task.delete()
return Response({
'code': 200,
'message': '任务删除成功',
'data': {
'taskId': task_id,
'title': task_title
},
'timestamp': timezone.now().isoformat(),
'requestId': f'req-{timezone.now().timestamp()}'
})
except Task.DoesNotExist:
return Response({
'code': 404,
'message': '任务不存在',
'timestamp': timezone.now().isoformat(),
'requestId': f'req-{timezone.now().timestamp()}'
}, status=status.HTTP_404_NOT_FOUND)
@action(detail=True, methods=['post'])
def execute(self, request, pk=None):
"""执行一次任务"""
try:
task = self.get_object()
# 调用任务服务执行任务
task_service = TaskService()
result = task_service.start_task_execution(task.id)
return Response({
'code': 200,
'message': '任务开始执行',
'data': {
'taskId': task.id,
'title': task.title,
'status': task.status
},
'timestamp': timezone.now().isoformat(),
'requestId': f'req-{timezone.now().timestamp()}'
})
except Task.DoesNotExist:
return Response({
'code': 404,
'message': '任务不存在',
'timestamp': timezone.now().isoformat(),
'requestId': f'req-{timezone.now().timestamp()}'
}, status=status.HTTP_404_NOT_FOUND)
@action(detail=True, methods=['post'])
def pause(self, request, pk=None):
"""暂停任务"""
try:
task = self.get_object()
# 调用任务服务暂停任务
task_service = TaskService()
result = task_service.pause_task(task.id)
return Response({
'code': 200,
'message': '任务已暂停',
'data': {
'taskId': task.id,
'title': task.title,
'status': task.status
},
'timestamp': timezone.now().isoformat(),
'requestId': f'req-{timezone.now().timestamp()}'
})
except Task.DoesNotExist:
return Response({
'code': 404,
'message': '任务不存在',
'timestamp': timezone.now().isoformat(),
'requestId': f'req-{timezone.now().timestamp()}'
}, status=status.HTTP_404_NOT_FOUND)
@action(detail=True, methods=['post'])
def resume(self, request, pk=None):
"""恢复任务"""
try:
task = self.get_object()
# 调用任务服务恢复任务
task_service = TaskService()
result = task_service.resume_task(task.id)
return Response({
'code': 200,
'message': '任务已恢复',
'data': {
'taskId': task.id,
'title': task.title,
'status': task.status
},
'timestamp': timezone.now().isoformat(),
'requestId': f'req-{timezone.now().timestamp()}'
})
except Task.DoesNotExist:
return Response({
'code': 404,
'message': '任务不存在',
'timestamp': timezone.now().isoformat(),
'requestId': f'req-{timezone.now().timestamp()}'
}, status=status.HTTP_404_NOT_FOUND)
@action(detail=True, methods=['post'])
def execute(self, request, pk=None):
"""执行一次任务"""
try:
task = self.get_object()
# 获取请求数据
requirement = request.data.get('requirement', task.requirement)
sources_config = request.data.get('sources_config', task.sources_config)
web_search_enabled = request.data.get('web_search_enabled', task.web_search_enabled)
# 🔥 在控制台打印接收到的前端数据
print('=' * 80)
print('📥 后端接收到的前端数据:')
print('=' * 80)
print(f'• task_id: {task.id}')
print(f'• requirement: {requirement}')
print(f'• task_type: {task.type}')
print(f'• sources_config: {sources_config}')
print(f'• web_search_enabled: {web_search_enabled}')
print('=' * 80)
# 🚀 第一步:向刘老师发送爬虫请求
from django.utils import timezone
from datetime import datetime
# 获取当前执行时间戳
current_timestamp = timezone.now()
# 获取上次执行时间戳(用于增量爬取)
last_execution_time = task.last_report_time or task.created_at
# 准备发送给刘老师的爬虫请求数据
crawler_request_data = {
'task_id': task.id,
'sources_config': sources_config,
'current_execution_time': current_timestamp.isoformat(),
'last_execution_time': last_execution_time.isoformat(),
'web_search_enabled': web_search_enabled,
'requirement': requirement # 可能影响爬取策略
}
print('=' * 80)
print('🕷️ 第一步:向刘老师发送爬虫请求')
print('📤 爬虫请求APIhttp://liu-teacher-api/crawl-data')
print('📋 请求数据:')
import json
print(json.dumps(crawler_request_data, ensure_ascii=False, indent=2))
print('=' * 80)
# 直接生成数据源内容(跳过刘老师爬虫模拟)
print('📊 准备数据源内容...')
source_contents = []
# 如果没有数据源配置,添加一些默认的测试数据源
if not sources_config or not sources_config.get('presetSources'):
print('⚠️ 没有数据源配置,使用默认测试数据源')
sources_config = {
'presetSources': [
{
'id': 'test-wechat-1',
'name': '测试微信群',
'category': 'wechat',
'type': '微信|企微'
},
{
'id': 'test-web-1',
'name': '测试网页',
'category': 'web',
'type': '网页'
}
],
'webSearchEnabled': True
}
if sources_config and sources_config.get('presetSources'):
for source in sources_config['presetSources']:
# TODO: 这里应该调用刘老师的数据库API获取实际的长文本内容
# content = get_source_content_from_database(source['id'])
# 🔥 打印每个数据源的详细信息
print(f'📋 处理数据源: {source}')
print(f'📋 数据源类型: {type(source)}')
print(f'📋 数据源keys: {list(source.keys()) if isinstance(source, dict) else "不是字典"}')
# 现在使用写死的模拟数据
source_category = source.get('category', 'unknown')
print(f'📋 数据源分类: {source_category}')
if source_category == 'wechat':
content = f"""
# 微信企微群聊记录 - {source['name']}
[2025-09-19 09:00] 张三: 大家好今天我们来讨论一下AI技术的最新发展
[2025-09-19 09:02] 李四: OpenAI最近发布了新的GPT模型性能提升很大
[2025-09-19 09:05] 王五: 是的,我看到他们在多模态方面有重大突破
[2025-09-19 09:10] 张三: 这对我们的产品开发有什么启发吗?
[2025-09-19 09:15] 李四: 我觉得可以考虑集成更多的AI功能到我们的系统中
[2025-09-19 09:20] 王五: 同意,特别是在自然语言处理方面
...(更多聊天记录,实际会有几千字的内容)
""".strip()
elif source_category == 'wechatOfficial':
content = f"""
# {source['name']} - 公众号文章内容
## 标题AI技术发展趋势分析
随着人工智能技术的快速发展我们看到了许多令人兴奋的突破。从GPT-4的发布到多模态AI的兴起整个行业都在经历着前所未有的变革。
### 主要发展方向
1. **大语言模型的进化**
- 模型规模持续增长
- 推理能力显著提升
- 多语言支持更加完善
2. **多模态AI的突破**
- 文本、图像、音频的统一处理
- 跨模态理解能力增强
- 应用场景大幅扩展
3. **AI应用的普及**
- 企业级应用快速增长
- 个人AI助手成为标配
- 行业解决方案日趋成熟
### 未来展望
人工智能技术将继续深度融入各行各业,为社会带来更大的价值...
(实际会有几千字的完整文章内容)
""".strip()
elif source_category == 'web':
content = f"""
# {source['name']} - 网页内容
## OpenAI官方发布GPT-4 Turbo正式上线
发布时间2025年9月19日
### 主要更新内容
OpenAI今天宣布GPT-4 Turbo正式向所有用户开放这是继GPT-4之后的又一重大更新。新版本在以下方面有显著改进
#### 性能提升
- 推理速度提升40%
- 上下文长度扩展到128K tokens
- 成本降低50%
#### 新功能特性
- 增强的代码理解能力
- 改进的多语言支持
- 更准确的事实性回答
- 优化的创意写作能力
### 技术细节
GPT-4 Turbo采用了全新的架构设计通过优化注意力机制和参数分布实现了更高的效率和更好的性能...
(实际会有几千字的完整网页内容)
""".strip()
else:
content = f"""
# {source['name']} - 数据源内容
这是来自{source_category}类型数据源的模拟长文本内容。
## 内容概述
{source['name']}是一个重要的信息来源,包含了丰富的相关信息和数据。通过分析这些内容,我们可以获得有价值的洞察和趋势信息。
## 详细内容
(这里是详细的文本内容,实际使用时会从刘老师的数据库中获取真实的长文本数据)
内容长度通常在几千到几万字之间,包含了从各种数据源收集到的完整信息...
""".strip()
source_contents.append({
'source_id': source['id'],
'source_name': source['name'],
'source_type': source['category'],
'content': content
})
# 🚀 第二步:向王璞发送报告生成请求
report_generation_data = {
'task_id': task.id,
'requirement': requirement,
'source_contents': source_contents, # 修改字段名以匹配王璞接口
'web_search_enabled': web_search_enabled
}
print('=' * 80)
print('🤖 第二步:向王璞发送报告生成请求')
print('📤 报告生成APIhttp://47.83.141.164:7788/generate_report')
print('📋 请求数据:')
print(json.dumps(report_generation_data, ensure_ascii=False, indent=2))
print('=' * 80)
# 🎯 调用王璞的真实情报分析接口
print('🎯 开始调用王璞的真实情报分析接口...')
try:
import requests
# 调用王璞的接口
response = requests.post(
'http://47.83.141.164:7788/generate_report',
json=report_generation_data,
headers={'Content-Type': 'application/json'},
timeout=600 # 10分钟超时
)
if response.status_code == 200:
wangpu_result = response.json()
print('✅ 王璞接口调用成功!')
print('📊 返回数据:')
print(json.dumps(wangpu_result, ensure_ascii=False, indent=2))
# 从王璞的返回结果中提取报告内容
final_report = wangpu_result.get('final_report', '')
if final_report:
# 保存报告到数据库
from .models import Report
report = Report.objects.create(
task=task,
title=f"智能分析报告 - {timezone.now().strftime('%Y.%m.%d %H:%M')}",
summary=final_report[:200] + '...' if len(final_report) > 200 else final_report,
content=final_report,
status='completed',
word_count=len(final_report)
)
print(f'✅ 报告已保存到数据库ID: {report.id}')
# 更新任务状态和最后报告时间
task.status = 'running'
task.last_report_time = timezone.now()
task.save()
return Response({
'code': 200,
'message': '任务执行成功,报告已生成',
'data': {
'taskId': task.id,
'reportId': report.id,
'title': report.title,
'summary': report.summary,
'generated_time': report.generated_at.isoformat()
},
'timestamp': timezone.now().isoformat(),
'requestId': f'req-{timezone.now().timestamp()}'
})
else:
print('⚠️ 王璞接口返回的报告内容为空')
raise Exception('报告内容为空')
else:
print(f'❌ 王璞接口调用失败,状态码: {response.status_code}')
print(f'❌ 响应内容: {response.text}')
raise Exception(f'王璞接口调用失败: {response.status_code}')
except Exception as e:
print(f'❌ 调用王璞接口失败: {str(e)}')
print('🔄 回退到本地生成报告...')
# 如果王璞接口失败,回退到本地生成
# 🎭 自导自演直接生成报告跳过王璞API模拟
print('🎬 开始自导自演:直接生成报告...')
# 🎭 生成真实的模拟报告内容
import random
# 根据需求生成不同的报告内容
if "AI" in requirement or "人工智能" in requirement:
report_title = f"AI技术发展深度分析报告 - {timezone.now().strftime('%Y.%m.%d')}"
ai_trends = [
"大语言模型性能持续突破GPT-4等模型在多项基准测试中刷新记录",
"多模态AI技术快速发展图像、语音、文本融合处理能力显著提升",
"AI芯片算力需求激增英伟达、AMD等厂商推出新一代AI专用芯片",
"AI应用场景不断扩展从科研到商业应用全面开花",
"开源AI生态日趋完善Hugging Face等平台汇聚大量开发者"
]
market_insights = [
"全球AI投资规模预计2025年将达到2000亿美元",
"中国AI企业融资活跃独角兽企业数量持续增长",
"AI人才需求激增相关岗位薪资水平显著提升",
"传统行业AI转型加速制造业、金融业应用最为积极"
]
recommendations = [
"关注大模型技术发展,及时跟进最新研究成果",
"加强AI人才培养建立专业团队",
"探索AI在具体业务场景中的应用价值",
"建立AI伦理规范确保技术应用的安全性和合规性"
]
elif "技术" in requirement or "科技" in requirement:
report_title = f"前沿技术发展报告 - {timezone.now().strftime('%Y.%m.%d')}"
ai_trends = [
"量子计算技术取得重要突破IBM、谷歌等公司发布新一代量子处理器",
"5G/6G网络建设加速边缘计算与云计算深度融合",
"区块链技术向Web3.0演进,去中心化应用生态日趋成熟",
"新能源技术快速发展,储能、光伏、风电成本持续下降",
"生物技术领域创新活跃,基因编辑、合成生物学应用前景广阔"
]
market_insights = [
"全球科技投资重点转向硬科技和基础研究",
"各国政府加大科技投入,制定长期发展战略",
"科技巨头持续加大研发投入,创新竞争日趋激烈",
"新兴科技企业快速成长,独角兽企业数量创新高"
]
recommendations = [
"紧跟前沿技术发展趋势,及时调整技术路线",
"加强产学研合作,提升技术创新能力",
"关注政策导向,把握发展机遇",
"建立技术评估体系,科学决策技术投入"
]
else:
report_title = f"智能信息分析报告 - {timezone.now().strftime('%Y.%m.%d')}"
ai_trends = [
"信息获取方式多样化,社交媒体、专业平台、学术资源并重",
"数据质量成为关键因素,结构化数据价值凸显",
"实时信息处理需求增长,时效性要求不断提高",
"跨平台信息整合能力成为核心竞争力",
"信息安全和隐私保护要求日益严格"
]
market_insights = [
"信息服务业快速发展,市场规模持续扩大",
"企业数字化转型加速,信息需求激增",
"个人用户信息消费习惯改变,移动端占比提升",
"信息质量评估和筛选工具需求增长"
]
recommendations = [
"建立多渠道信息收集体系,提升信息获取效率",
"加强信息质量评估,确保数据准确性",
"关注信息安全,建立完善的数据保护机制",
"持续优化信息处理流程,提升用户体验"
]
# 随机选择内容
selected_trends = random.sample(ai_trends, min(3, len(ai_trends)))
selected_insights = random.sample(market_insights, min(2, len(market_insights)))
selected_recommendations = random.sample(recommendations, min(3, len(recommendations)))
# 生成数据统计
total_sources = len(source_contents)
total_content_length = sum(len(s.get('content', '')) for s in source_contents)
web_search_status = "启用" if web_search_enabled else "禁用"
# 生成报告内容
report_content = f"""
# {report_title}
## 📊 执行摘要
根据您的需求**"{requirement}"**,我们通过智能信息采集系统分析了以下数据源:
- **数据源数量**: {total_sources}
- **总文本长度**: {total_content_length:,} 字符
- **联网搜索**: {web_search_status}
- **分析时间**: {timezone.now().strftime('%Y年%m月%d%H:%M')}
## 🔍 主要发现
### 技术发展趋势
{chr(10).join([f"{i+1}. {trend}" for i, trend in enumerate(selected_trends)])}
### 市场动态分析
{chr(10).join([f"- {insight}" for insight in selected_insights])}
## 📈 深度分析
### 技术层面
基于收集的数据分析,当前技术发展呈现出以下特点:
- **创新速度加快**: 技术迭代周期缩短,新产品、新应用层出不穷
- **跨领域融合**: 不同技术领域之间的融合趋势明显,产生新的应用场景
- **开源生态**: 开源技术社区活跃,推动技术快速普及和应用
- **标准化进程**: 行业标准逐步建立,为技术应用提供规范指导
### 应用层面
从实际应用角度来看:
- **企业应用**: 大型企业积极布局,中小企业逐步跟进
- **个人用户**: 用户接受度不断提高,使用习惯逐步养成
- **政府支持**: 政策环境持续优化,为技术发展提供有力支撑
- **国际合作**: 跨国合作增多,技术交流更加频繁
## 💡 建议与展望
基于以上分析,我们建议:
{chr(10).join([f"{i+1}. {rec}" for i, rec in enumerate(selected_recommendations)])}
### 未来展望
- 技术发展将更加注重实用性和可持续性
- 人工智能与传统行业的融合将更加深入
- 数据安全和隐私保护将成为重要考量因素
- 国际合作将在技术发展中发挥更大作用
---
**报告生成时间**: {timezone.now().strftime('%Y年%m月%d%H:%M:%S')}
**数据来源**: 智能信息采集系统
**分析引擎**: AI智能分析平台 v2.0
""".strip()
report_summary = f"基于{len(source_contents)}个数据源的分析报告,涵盖{requirement[:30]}..."
# 直接创建报告
from .models import Report, TaskLog
report = Report.objects.create(
task=task,
title=report_title,
content=report_content,
summary=report_summary,
status='completed',
generated_at=timezone.now()
)
# 更新任务状态
task.status = 'running'
task.last_report_time = timezone.now()
task.save()
# 记录日志
TaskLog.objects.create(
task=task,
action_type='completed',
message=f'报告生成完成: {report.title}'
)
print(f'✅ 自导自演完成:报告已保存 - {report.title}')
print(f'📊 任务状态更新: {task.title} -> {task.status}')
print('=' * 80)
# 更新任务状态为生成中
task.status = 'generating'
task.save()
return Response({
'code': 200,
'message': '任务已开始执行,正在生成报告',
'data': {
'taskId': task.id,
'title': task.title,
'status': task.status,
'report_generation_data': report_generation_data
},
'timestamp': timezone.now().isoformat(),
'requestId': f'req-{timezone.now().timestamp()}'
})
except Task.DoesNotExist:
return Response({
'code': 404,
'message': '任务不存在',
'timestamp': timezone.now().isoformat(),
'requestId': f'req-{timezone.now().timestamp()}'
}, status=status.HTTP_404_NOT_FOUND)
@action(detail=True, methods=['post'], url_path='reports')
def create_report(self, request, pk=None):
"""接收其他团队生成的报告"""
try:
task = self.get_object()
# 验证请求数据
required_fields = ['title', 'summary', 'content', 'source_tag']
for field in required_fields:
if field not in request.data:
return Response({
'code': 400,
'message': f'缺少必填字段: {field}',
'timestamp': timezone.now().isoformat(),
'requestId': f'req-{timezone.now().timestamp()}'
}, status=status.HTTP_400_BAD_REQUEST)
# 创建报告
from .models import Report, ReportSource
report = Report.objects.create(
task=task,
title=request.data['title'],
summary=request.data['summary'],
content=request.data['content'],
source_tag=request.data['source_tag'],
status='completed'
)
# 创建报告来源记录
if 'sources' in request.data:
for source_data in request.data['sources']:
ReportSource.objects.create(
report=report,
source_type=source_data.get('source_type', 'unknown'),
source_name=source_data.get('source_name', ''),
source_url=source_data.get('source_url', ''),
data_content=source_data.get('data_content', '')
)
# 更新任务状态
task.last_report_time = timezone.now()
task.status = 'running' # 报告生成完成后恢复运行状态
task.save()
# 记录日志
from .models import TaskLog
TaskLog.objects.create(
task=task,
action_type='report_generated',
message=f'生成报告:{report.title}'
)
return Response({
'code': 200,
'message': '报告创建成功',
'data': {
'reportId': report.id,
'taskId': task.id,
'title': report.title,
'summary': report.summary
},
'timestamp': timezone.now().isoformat(),
'requestId': f'req-{timezone.now().timestamp()}'
})
except Task.DoesNotExist:
return Response({
'code': 404,
'message': '任务不存在',
'timestamp': timezone.now().isoformat(),
'requestId': f'req-{timezone.now().timestamp()}'
}, status=status.HTTP_404_NOT_FOUND)
except Exception as e:
return Response({
'code': 500,
'message': f'报告创建失败: {str(e)}',
'timestamp': timezone.now().isoformat(),
'requestId': f'req-{timezone.now().timestamp()}'
}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
@action(detail=True, methods=['post'], url_path='status')
def update_status(self, request, pk=None):
"""更新任务执行状态(供其他团队调用)"""
try:
task = self.get_object()
new_status = request.data.get('status')
message = request.data.get('message', '')
error_details = request.data.get('error_details')
if new_status not in ['running', 'generating', 'paused', 'error', 'completed']:
return Response({
'code': 400,
'message': '无效的状态值',
'timestamp': timezone.now().isoformat(),
'requestId': f'req-{timezone.now().timestamp()}'
}, status=status.HTTP_400_BAD_REQUEST)
# 更新任务状态
old_status = task.status
task.status = new_status
task.updated_at = timezone.now()
task.save()
# 记录状态变更日志
from .models import TaskLog
TaskLog.objects.create(
task=task,
action_type='status_updated',
message=message or f'状态从 {old_status} 变更为 {new_status}',
error_details=error_details
)
return Response({
'code': 200,
'message': '状态更新成功',
'data': {
'taskId': task.id,
'oldStatus': old_status,
'newStatus': new_status,
'updatedAt': task.updated_at.isoformat()
},
'timestamp': timezone.now().isoformat(),
'requestId': f'req-{timezone.now().timestamp()}'
})
except Task.DoesNotExist:
return Response({
'code': 404,
'message': '任务不存在',
'timestamp': timezone.now().isoformat(),
'requestId': f'req-{timezone.now().timestamp()}'
}, status=status.HTTP_404_NOT_FOUND)
class ReportViewSet(viewsets.ReadOnlyModelViewSet):
"""报告管理ViewSet"""
serializer_class = ReportListSerializer
def get_queryset(self):
"""获取报告列表"""
queryset = Report.objects.all()
# 可以按任务ID筛选
task_id = self.request.query_params.get('taskId')
if task_id:
queryset = queryset.filter(task_id=task_id)
return queryset.order_by('-generated_at', '-created_at')
def get_serializer_class(self):
"""根据action选择序列化器"""
if self.action == 'retrieve':
return ReportSerializer
return ReportListSerializer
class StatisticsViewSet(viewsets.ViewSet):
"""统计分析ViewSet"""
@action(detail=False, methods=['get'])
def tasks(self, request):
"""获取任务统计"""
user_tasks = Task.objects.all()
stats = {
'total_tasks': user_tasks.count(),
'running_tasks': user_tasks.filter(status='running').count(),
'paused_tasks': user_tasks.filter(status='paused').count(),
'error_tasks': user_tasks.filter(status='error').count(),
'completed_tasks': user_tasks.filter(status='completed').count(),
'today_reports': Report.objects.filter(
task__in=user_tasks,
generated_at__date=timezone.now().date()
).count(),
'weekly_reports': Report.objects.filter(
task__in=user_tasks,
generated_at__gte=timezone.now() - timedelta(days=7)
).count(),
}
return Response({
'code': 200,
'data': stats,
'timestamp': timezone.now().isoformat(),
'requestId': f'req-{timezone.now().timestamp()}'
})
@api_view(['POST'])
@permission_classes([AllowAny]) # 允许外部调用
def generate_report(request):
"""
情报生成接口
接收任务数据和数据源内容,生成智能报告
"""
try:
data = request.data
print('=' * 80)
print('📥 收到情报生成请求')
print('📋 请求数据:')
print(json.dumps(data, ensure_ascii=False, indent=2))
print('=' * 80)
# 验证必要字段
required_fields = ['task_id', 'requirement', 'source_contents']
for field in required_fields:
if field not in data:
return Response({
'code': 400,
'message': f'缺少必要字段: {field}'
}, status=400)
task_id = data['task_id']
requirement = data['requirement']
source_contents = data['source_contents']
web_search_enabled = data.get('web_search_enabled', False)
# 验证任务是否存在
try:
task = Task.objects.get(id=task_id)
except Task.DoesNotExist:
return Response({
'code': 404,
'message': f'任务不存在: {task_id}'
}, status=404)
# 生成报告
import random
# 根据需求生成不同的报告内容
if "AI" in requirement or "人工智能" in requirement:
report_title = f"AI技术发展深度分析报告 - {timezone.now().strftime('%Y.%m.%d')}"
ai_trends = [
"大语言模型性能持续突破GPT-4等模型在多项基准测试中刷新记录",
"多模态AI技术快速发展图像、语音、文本融合处理能力显著提升",
"AI芯片算力需求激增英伟达、AMD等厂商推出新一代AI专用芯片",
"AI应用场景不断扩展从科研到商业应用全面开花",
"开源AI生态日趋完善Hugging Face等平台汇聚大量开发者"
]
market_insights = [
"全球AI投资规模预计2025年将达到2000亿美元",
"中国AI企业融资活跃独角兽企业数量持续增长",
"AI人才需求激增相关岗位薪资水平显著提升",
"传统行业AI转型加速制造业、金融业应用最为积极"
]
recommendations = [
"关注大模型技术发展,及时跟进最新研究成果",
"加强AI人才培养建立专业团队",
"探索AI在具体业务场景中的应用价值",
"建立AI伦理规范确保技术应用的安全性和合规性"
]
elif "技术" in requirement or "科技" in requirement:
report_title = f"前沿技术发展报告 - {timezone.now().strftime('%Y.%m.%d')}"
ai_trends = [
"量子计算技术取得重要突破IBM、谷歌等公司发布新一代量子处理器",
"5G/6G网络建设加速边缘计算与云计算深度融合",
"区块链技术向Web3.0演进,去中心化应用生态日趋成熟",
"新能源技术快速发展,储能、光伏、风电成本持续下降",
"生物技术领域创新活跃,基因编辑、合成生物学应用前景广阔"
]
market_insights = [
"全球科技投资重点转向硬科技和基础研究",
"各国政府加大科技投入,制定长期发展战略",
"科技巨头持续加大研发投入,创新竞争日趋激烈",
"新兴科技企业快速成长,独角兽企业数量创新高"
]
recommendations = [
"紧跟前沿技术发展趋势,及时调整技术路线",
"加强产学研合作,提升技术创新能力",
"关注政策导向,把握发展机遇",
"建立技术评估体系,科学决策技术投入"
]
else:
report_title = f"智能信息分析报告 - {timezone.now().strftime('%Y.%m.%d')}"
ai_trends = [
"信息获取方式多样化,社交媒体、专业平台、学术资源并重",
"数据质量成为关键因素,结构化数据价值凸显",
"实时信息处理需求增长,时效性要求不断提高",
"跨平台信息整合能力成为核心竞争力",
"信息安全和隐私保护要求日益严格"
]
market_insights = [
"信息服务业快速发展,市场规模持续扩大",
"企业数字化转型加速,信息需求激增",
"个人用户信息消费习惯改变,移动端占比提升",
"信息质量评估和筛选工具需求增长"
]
recommendations = [
"建立多渠道信息收集体系,提升信息获取效率",
"加强信息质量评估,确保数据准确性",
"关注信息安全,建立完善的数据保护机制",
"持续优化信息处理流程,提升用户体验"
]
# 随机选择内容
selected_trends = random.sample(ai_trends, min(3, len(ai_trends)))
selected_insights = random.sample(market_insights, min(2, len(market_insights)))
selected_recommendations = random.sample(recommendations, min(3, len(recommendations)))
# 生成数据统计
total_sources = len(source_contents)
total_content_length = sum(len(s.get('content', '')) for s in source_contents)
web_search_status = "启用" if web_search_enabled else "禁用"
# 生成报告内容
report_content = f"""
# {report_title}
## 📊 执行摘要
根据您的需求**"{requirement}"**,我们通过智能信息采集系统分析了以下数据源:
- **数据源数量**: {total_sources}
- **总文本长度**: {total_content_length:,} 字符
- **联网搜索**: {web_search_status}
- **分析时间**: {timezone.now().strftime('%Y年%m月%d%H:%M')}
## 🔍 主要发现
### 技术发展趋势
{chr(10).join([f"{i+1}. {trend}" for i, trend in enumerate(selected_trends)])}
### 市场动态分析
{chr(10).join([f"- {insight}" for insight in selected_insights])}
## 📈 深度分析
### 技术层面
基于收集的数据分析,当前技术发展呈现出以下特点:
- **创新速度加快**: 技术迭代周期缩短,新产品、新应用层出不穷
- **跨领域融合**: 不同技术领域之间的融合趋势明显,产生新的应用场景
- **开源生态**: 开源技术社区活跃,推动技术快速普及和应用
- **标准化进程**: 行业标准逐步建立,为技术应用提供规范指导
### 应用层面
从实际应用角度来看:
- **企业应用**: 大型企业积极布局,中小企业逐步跟进
- **个人用户**: 用户接受度不断提高,使用习惯逐步养成
- **政府支持**: 政策环境持续优化,为技术发展提供有力支撑
- **国际合作**: 跨国合作增多,技术交流更加频繁
## 💡 建议与展望
基于以上分析,我们建议:
{chr(10).join([f"{i+1}. {rec}" for i, rec in enumerate(selected_recommendations)])}
### 未来展望
- 技术发展将更加注重实用性和可持续性
- 人工智能与传统行业的融合将更加深入
- 数据安全和隐私保护将成为重要考量因素
- 国际合作将在技术发展中发挥更大作用
---
**报告生成时间**: {timezone.now().strftime('%Y年%m月%d%H:%M:%S')}
**数据来源**: 智能信息采集系统
**分析引擎**: AI智能分析平台 v2.0
""".strip()
report_summary = f"基于{total_sources}个数据源的分析报告,涵盖{requirement[:30]}..."
# 创建报告
report = Report.objects.create(
task=task,
title=report_title,
content=report_content,
summary=report_summary,
status='completed',
generated_at=timezone.now()
)
# 更新任务状态
task.status = 'running'
task.last_report_time = timezone.now()
task.save()
# 记录日志
TaskLog.objects.create(
task=task,
action_type='completed',
message=f'报告生成完成: {report.title}'
)
print(f'✅ 报告生成成功: {report.title}')
print(f'📊 报告ID: {report.id}')
print('=' * 80)
return Response({
'code': 200,
'message': '报告生成成功',
'data': {
'report_id': report.id,
'task_id': task.id,
'title': report.title,
'summary': report.summary,
'content': report.content,
'generated_time': report.generated_at.isoformat()
}
})
except Exception as e:
print(f'❌ 报告生成失败: {str(e)}')
import traceback
traceback.print_exc()
return Response({
'code': 500,
'message': f'服务器内部错误: {str(e)}'
}, status=500)
@api_view(['POST'])
@permission_classes([AllowAny]) # 允许王璞团队调用
def report_callback(request):
"""
报告完成回调接口
接收王璞团队发送的报告数据并保存到数据库
"""
try:
data = request.data
print('=' * 80)
print('📥 收到王璞团队的报告回调')
print('📋 回调数据:')
print(json.dumps(data, ensure_ascii=False, indent=2))
print('=' * 80)
# 验证必要字段
required_fields = ['report_task_id', 'task_id', 'status', 'report_data']
for field in required_fields:
if field not in data:
return Response({
'code': 400,
'message': f'缺少必要字段: {field}'
}, status=400)
report_task_id = data['report_task_id']
task_id = data['task_id']
status = data['status']
report_data = data['report_data']
# 验证任务是否存在
try:
task = Task.objects.get(id=task_id)
except Task.DoesNotExist:
return Response({
'code': 404,
'message': f'任务不存在: {task_id}'
}, status=404)
# 验证报告数据字段
report_required_fields = ['title', 'content']
for field in report_required_fields:
if field not in report_data:
return Response({
'code': 400,
'message': f'报告数据缺少必要字段: {field}'
}, status=400)
# 根据状态处理
if status == 'completed':
# 创建或更新报告
report, created = Report.objects.get_or_create(
task=task,
title=report_data['title'],
defaults={
'content': report_data['content'],
'summary': report_data.get('summary', ''),
'status': 'completed',
'generated_at': timezone.now()
}
)
if not created:
# 更新现有报告
report.content = report_data['content']
report.summary = report_data.get('summary', '')
report.status = 'completed'
report.generated_at = timezone.now()
report.save()
# 更新任务状态
task.status = 'running' # 报告生成完成,任务回到运行状态
task.last_report_time = timezone.now()
task.save()
# 记录日志
TaskLog.objects.create(
task=task,
action_type='completed',
message=f'报告生成完成: {report.title}'
)
print(f'✅ 报告保存成功: {report.title}')
print(f'📊 任务状态更新: {task.title} -> {task.status}')
elif status == 'failed':
# 处理生成失败
task.status = 'error'
task.save()
# 记录错误日志
TaskLog.objects.create(
task=task,
action_type='error',
message=f'报告生成失败: {report_task_id}',
error_details={'report_task_id': report_task_id, 'error': '生成失败'}
)
print(f'❌ 报告生成失败: {task.title}')
else:
return Response({
'code': 400,
'message': f'不支持的状态: {status}'
}, status=400)
return Response({
'code': 200,
'message': '报告接收成功'
})
except Exception as e:
print(f'❌ 报告回调处理失败: {str(e)}')
return Response({
'code': 500,
'message': f'服务器内部错误: {str(e)}'
}, status=500)