diff --git a/flowchart/serializers.py b/flowchart/serializers.py index ad5cc22..e240d75 100644 --- a/flowchart/serializers.py +++ b/flowchart/serializers.py @@ -4,7 +4,7 @@ from .models import FlowchartSubmission class CreateFlowchartSubmissionSerializer(serializers.Serializer): problem_id = serializers.IntegerField() - mermaid_code = serializers.CharField() + mermaid_code = serializers.CharField(max_length=50000) flowchart_data = serializers.JSONField(required=False, default=dict) def validate_mermaid_code(self, value): @@ -12,6 +12,12 @@ class CreateFlowchartSubmissionSerializer(serializers.Serializer): raise serializers.ValidationError("Mermaid代码不能为空") return value + def validate_flowchart_data(self, value): + import json + if len(json.dumps(value)) > 500 * 1024: + raise serializers.ValidationError("流程图数据过大") + return value + class FlowchartSubmissionSerializer(serializers.ModelSerializer): class Meta: diff --git a/flowchart/tasks.py b/flowchart/tasks.py index 4f0b7c4..8a3939e 100644 --- a/flowchart/tasks.py +++ b/flowchart/tasks.py @@ -24,29 +24,27 @@ def evaluate_flowchart_task(submission_id): # 构建用户提示词,包含标准答案对比 user_prompt = f""" - 请对以下Mermaid流程图进行评分: - - 学生提交的流程图: - ```mermaid - {submission.mermaid_code} - ``` +请对以下Mermaid流程图进行评分: - 标准答案参考: - ```mermaid - {submission.problem.mermaid_code} - ``` - """ - # 如果有流程图提示,添加到提示词中 - if submission.problem.flowchart_hint: +学生提交的流程图: +```mermaid +{submission.mermaid_code} +``` +""" + if submission.problem.mermaid_code: user_prompt += f""" - - 设计提示:{submission.problem.flowchart_hint} - """ - - user_prompt += """ - - 请按照评分标准进行详细评估,并给出0-100的分数。 - """ +标准答案参考: +```mermaid +{submission.problem.mermaid_code} +``` +""" + else: + user_prompt += "\n注意:此题没有标准答案,请根据题目描述和流程图的逻辑合理性进行评分。\n" + + if submission.problem.flowchart_hint: + user_prompt += f"\n设计提示:{submission.problem.flowchart_hint}\n" + + user_prompt += "\n请按照评分标准进行详细评估,并给出0-100的分数。\n" # 调用AI进行评分 client = get_ai_client() @@ -155,26 +153,15 @@ def build_evaluation_prompt(problem): """ def parse_ai_evaluation_response(ai_response): - """解析AI评分响应""" - try: - import re - json_match = re.search(r'\{.*\}', ai_response, re.DOTALL) - if json_match: - data = json.loads(json_match.group()) - else: - data = { - "score": 60, - "grade": "C", - "feedback": "AI评分解析失败,请重新提交", - "suggestions": "", - "criteria_details": {} - } - return data - except Exception: - return { - "score": 60, - "grade": "C", - "feedback": "AI评分解析失败,请重新提交", - "suggestions": "", - "criteria_details": {} - } + """解析AI评分响应,解析失败时抛出异常由调用方处理""" + import re + json_match = re.search(r'\{.*\}', ai_response, re.DOTALL) + if not json_match: + raise ValueError("AI响应中未找到JSON数据") + + data = json.loads(json_match.group()) + + if "score" not in data or "grade" not in data: + raise ValueError("AI响应缺少必要字段: score 或 grade") + + return data diff --git a/flowchart/views/oj.py b/flowchart/views/oj.py index 4e43e19..9100c3c 100644 --- a/flowchart/views/oj.py +++ b/flowchart/views/oj.py @@ -22,8 +22,6 @@ class FlowchartSubmissionAPI(APIView): # 验证题目存在 try: - from problem.models import Problem - problem = Problem.objects.get(id=data["problem_id"]) except Problem.DoesNotExist: return self.error("Problem doesn't exist") @@ -65,6 +63,7 @@ class FlowchartSubmissionAPI(APIView): class FlowchartSubmissionListAPI(APIView): + @login_required def get(self, request): """获取流程图提交列表""" username = request.GET.get("username") @@ -158,12 +157,18 @@ class FlowchartSubmissionDetailAPI(APIView): problem=problem, status=FlowchartSubmissionStatus.COMPLETED, ).order_by("create_time") + count = submissions.count() + if count == 0: + return self.success({"submission": None, "count": 0}) + # page=0 means latest; page=N means the Nth submission (1-indexed, chronological) if page == 0: submission = submissions.last() else: + if page < 0 or page > count: + return self.error("Page out of range") submission = submissions[page - 1] serializer = FlowchartSubmissionSerializer(submission) - return self.success({"submission": serializer.data}) + return self.success({"submission": serializer.data, "count": count}) class FlowchartSubmissionCurrentAPI(APIView):