from rest_framework import serializers from .models import Task, Report, ReportSource, TaskLog class TaskSerializer(serializers.ModelSerializer): """任务序列化器""" report_count = serializers.ReadOnlyField() has_new_report = serializers.ReadOnlyField() class Meta: model = Task fields = [ 'id', 'title', 'description', 'requirement', 'type', 'status', 'schedule_config', 'sources_config', 'web_search_enabled', 'last_report_time', 'next_run_time', 'created_at', 'updated_at', 'report_count', 'has_new_report' ] read_only_fields = ['id', 'created_at', 'updated_at', 'last_report_time'] class CreateTaskSerializer(serializers.Serializer): """创建任务的序列化器""" requirement = serializers.CharField(max_length=5000, help_text='用户需求描述') type = serializers.ChoiceField(choices=['single', 'scheduled'], help_text='任务类型') schedule = serializers.JSONField(required=False, allow_null=True, help_text='周期任务配置') presetSources = serializers.ListField( child=serializers.DictField(), required=False, default=list, help_text='预设信息源' ) customSources = serializers.ListField( child=serializers.DictField(), required=False, default=list, help_text='自定义信息源' ) webSearchEnabled = serializers.BooleanField(default=True, help_text='是否启用联网搜索') def validate_schedule(self, value): """验证周期任务配置""" task_type = self.initial_data.get('type') # 单次任务允许schedule为None或null if task_type == 'single': return None # 周期任务必须有schedule配置 if task_type == 'scheduled': if not value: raise serializers.ValidationError('周期任务必须提供执行周期配置') required_fields = ['frequency', 'time'] for field in required_fields: if field not in value: raise serializers.ValidationError(f'周期任务配置缺少必要字段: {field}') return value class ReportSourceSerializer(serializers.ModelSerializer): """报告来源序列化器""" class Meta: model = ReportSource fields = [ 'id', 'source_type', 'source_name', 'source_url', 'extracted_content', 'collected_at' ] class ReportSerializer(serializers.ModelSerializer): """报告序列化器""" task_title = serializers.CharField(source='task.title', read_only=True) sources = ReportSourceSerializer(many=True, read_only=True) class Meta: model = Report fields = [ 'id', 'task_id', 'task_title', 'title', 'summary', 'content', 'source_tag', 'word_count', 'status', 'generated_at', 'created_at', 'updated_at', 'sources' ] read_only_fields = ['id', 'created_at', 'updated_at', 'word_count'] class ReportListSerializer(serializers.ModelSerializer): """报告列表序列化器(不包含content字段)""" task_title = serializers.CharField(source='task.title', read_only=True) class Meta: model = Report fields = [ 'id', 'task_id', 'task_title', 'title', 'summary', 'source_tag', 'word_count', 'status', 'generated_at' ] class TaskLogSerializer(serializers.ModelSerializer): """任务日志序列化器""" class Meta: model = TaskLog fields = [ 'id', 'action_type', 'message', 'error_details', 'created_at' ] read_only_fields = ['id', 'created_at'] class TaskDetailSerializer(TaskSerializer): """任务详情序列化器""" logs = TaskLogSerializer(many=True, read_only=True) recent_reports = serializers.SerializerMethodField() class Meta(TaskSerializer.Meta): fields = TaskSerializer.Meta.fields + ['logs', 'recent_reports'] def get_recent_reports(self, obj): """获取最近的3个报告""" recent_reports = obj.reports.filter(status='completed')[:3] return ReportListSerializer(recent_reports, many=True).data class UpdateTaskStatusSerializer(serializers.Serializer): """更新任务状态的序列化器""" status = serializers.ChoiceField(choices=['running', 'paused'], help_text='任务状态') class TaskStatisticsSerializer(serializers.Serializer): """任务统计序列化器""" total_tasks = serializers.IntegerField() running_tasks = serializers.IntegerField() paused_tasks = serializers.IntegerField() error_tasks = serializers.IntegerField() completed_tasks = serializers.IntegerField() today_reports = serializers.IntegerField() weekly_reports = serializers.IntegerField() class ReportStatisticsSerializer(serializers.Serializer): """报告统计序列化器""" total_reports = serializers.IntegerField() generated_today = serializers.IntegerField() average_word_count = serializers.FloatField() source_distribution = serializers.DictField() daily_generation = serializers.ListField(child=serializers.DictField())