删除无用代码并且新增流程图相关内容
This commit is contained in:
0
flowchart/__init__.py
Normal file
0
flowchart/__init__.py
Normal file
0
flowchart/admin.py
Normal file
0
flowchart/admin.py
Normal file
7
flowchart/apps.py
Normal file
7
flowchart/apps.py
Normal file
@@ -0,0 +1,7 @@
|
||||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class FlowchartConfig(AppConfig):
|
||||
default_auto_field = 'django.db.models.BigAutoField'
|
||||
name = 'flowchart'
|
||||
verbose_name = '流程图管理'
|
||||
83
flowchart/consumers.py
Normal file
83
flowchart/consumers.py
Normal file
@@ -0,0 +1,83 @@
|
||||
"""
|
||||
WebSocket consumers for flowchart evaluation updates
|
||||
"""
|
||||
import json
|
||||
import logging
|
||||
from channels.generic.websocket import AsyncWebsocketConsumer
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class FlowchartConsumer(AsyncWebsocketConsumer):
|
||||
"""
|
||||
WebSocket consumer for real-time flowchart evaluation updates
|
||||
当用户提交流程图后,通过 WebSocket 实时接收AI评分状态更新
|
||||
"""
|
||||
|
||||
async def connect(self):
|
||||
"""处理 WebSocket 连接"""
|
||||
self.user = self.scope["user"]
|
||||
|
||||
# 只允许认证用户连接
|
||||
if not self.user.is_authenticated:
|
||||
await self.close()
|
||||
return
|
||||
|
||||
# 使用用户 ID 作为组名,这样可以向特定用户推送消息
|
||||
self.group_name = f"flowchart_user_{self.user.id}"
|
||||
|
||||
# 加入用户专属的组
|
||||
await self.channel_layer.group_add(
|
||||
self.group_name,
|
||||
self.channel_name
|
||||
)
|
||||
|
||||
await self.accept()
|
||||
logger.info(f"Flowchart WebSocket connected: user_id={self.user.id}, channel={self.channel_name}")
|
||||
|
||||
async def disconnect(self, close_code):
|
||||
"""处理 WebSocket 断开连接"""
|
||||
if hasattr(self, 'group_name'):
|
||||
await self.channel_layer.group_discard(
|
||||
self.group_name,
|
||||
self.channel_name
|
||||
)
|
||||
logger.info(f"Flowchart WebSocket disconnected: user_id={self.user.id}, close_code={close_code}")
|
||||
|
||||
async def receive(self, text_data):
|
||||
"""
|
||||
接收客户端消息
|
||||
客户端可以发送心跳包或订阅特定流程图提交
|
||||
"""
|
||||
try:
|
||||
data = json.loads(text_data)
|
||||
message_type = data.get("type")
|
||||
|
||||
if message_type == "ping":
|
||||
# 响应心跳包
|
||||
await self.send(text_data=json.dumps({
|
||||
"type": "pong",
|
||||
"timestamp": data.get("timestamp")
|
||||
}))
|
||||
elif message_type == "subscribe":
|
||||
# 订阅特定流程图提交的更新
|
||||
submission_id = data.get("submission_id")
|
||||
if submission_id:
|
||||
logger.info(f"User {self.user.id} subscribed to flowchart submission {submission_id}")
|
||||
# 可以在这里做额外的订阅逻辑
|
||||
except json.JSONDecodeError:
|
||||
logger.error(f"Invalid JSON received from user {self.user.id}")
|
||||
except Exception as e:
|
||||
logger.error(f"Error handling message from user {self.user.id}: {str(e)}")
|
||||
|
||||
async def flowchart_evaluation_update(self, event):
|
||||
"""
|
||||
接收来自 channel layer 的流程图评分更新消息并发送给客户端
|
||||
这个方法名对应 push_flowchart_evaluation_update 中的 type 字段
|
||||
"""
|
||||
try:
|
||||
# 从 event 中提取数据并发送给客户端
|
||||
await self.send(text_data=json.dumps(event["data"]))
|
||||
logger.debug(f"Sent flowchart evaluation update to user {self.user.id}: {event['data']}")
|
||||
except Exception as e:
|
||||
logger.error(f"Error sending flowchart evaluation update to user {self.user.id}: {str(e)}")
|
||||
45
flowchart/migrations/0001_initial.py
Normal file
45
flowchart/migrations/0001_initial.py
Normal file
@@ -0,0 +1,45 @@
|
||||
# Generated by Django 5.2.3 on 2025-10-11 14:57
|
||||
|
||||
import django.db.models.deletion
|
||||
import utils.shortcuts
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
('problem', '0004_problem_allow_flowchart_problem_flowchart_data_and_more'),
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='FlowchartSubmission',
|
||||
fields=[
|
||||
('id', models.TextField(db_index=True, default=utils.shortcuts.rand_str, primary_key=True, serialize=False)),
|
||||
('mermaid_code', models.TextField()),
|
||||
('flowchart_data', models.JSONField(default=dict)),
|
||||
('status', models.IntegerField(default=0)),
|
||||
('create_time', models.DateTimeField(auto_now_add=True)),
|
||||
('ai_score', models.FloatField(blank=True, null=True)),
|
||||
('ai_grade', models.CharField(blank=True, max_length=10, null=True)),
|
||||
('ai_feedback', models.TextField(blank=True, null=True)),
|
||||
('ai_suggestions', models.TextField(blank=True, null=True)),
|
||||
('ai_criteria_details', models.JSONField(default=dict)),
|
||||
('ai_provider', models.CharField(default='deepseek', max_length=50)),
|
||||
('ai_model', models.CharField(default='deepseek-chat', max_length=50)),
|
||||
('processing_time', models.FloatField(blank=True, null=True)),
|
||||
('evaluation_time', models.DateTimeField(blank=True, null=True)),
|
||||
('problem', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='flowchart_submissions', to='problem.problem')),
|
||||
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='flowchart_submissions', to=settings.AUTH_USER_MODEL)),
|
||||
],
|
||||
options={
|
||||
'db_table': 'flowchart_submission',
|
||||
'ordering': ['-create_time'],
|
||||
'indexes': [models.Index(fields=['user', 'create_time'], name='flowchart_user_time_idx'), models.Index(fields=['problem', 'create_time'], name='flowchart_problem_time_idx'), models.Index(fields=['status'], name='flowchart_status_idx')],
|
||||
},
|
||||
),
|
||||
]
|
||||
0
flowchart/migrations/__init__.py
Normal file
0
flowchart/migrations/__init__.py
Normal file
65
flowchart/models.py
Normal file
65
flowchart/models.py
Normal file
@@ -0,0 +1,65 @@
|
||||
from django.db import models
|
||||
from django.contrib.auth import get_user_model
|
||||
from utils.shortcuts import rand_str
|
||||
from problem.models import Problem
|
||||
|
||||
User = get_user_model()
|
||||
|
||||
class FlowchartSubmissionStatus:
|
||||
PENDING = 0 # 等待AI评分
|
||||
PROCESSING = 1 # AI评分中
|
||||
COMPLETED = 2 # 评分完成
|
||||
FAILED = 3 # 评分失败
|
||||
|
||||
class FlowchartSubmission(models.Model):
|
||||
"""流程图提交模型"""
|
||||
id = models.TextField(default=rand_str, primary_key=True, db_index=True)
|
||||
|
||||
# 基础信息
|
||||
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='flowchart_submissions')
|
||||
problem = models.ForeignKey(Problem, on_delete=models.CASCADE, related_name='flowchart_submissions')
|
||||
|
||||
# 提交内容
|
||||
mermaid_code = models.TextField() # Mermaid代码
|
||||
flowchart_data = models.JSONField(default=dict) # 流程图元数据
|
||||
|
||||
# 状态信息
|
||||
status = models.IntegerField(default=FlowchartSubmissionStatus.PENDING)
|
||||
create_time = models.DateTimeField(auto_now_add=True)
|
||||
|
||||
# AI评分结果
|
||||
ai_score = models.FloatField(null=True, blank=True) # AI评分 (0-100)
|
||||
ai_grade = models.CharField(max_length=10, null=True, blank=True) # 等级 (S/A/B/C)
|
||||
ai_feedback = models.TextField(null=True, blank=True) # AI反馈
|
||||
ai_suggestions = models.TextField(null=True, blank=True) # AI建议
|
||||
ai_criteria_details = models.JSONField(default=dict) # 详细评分标准
|
||||
|
||||
# 处理信息
|
||||
ai_provider = models.CharField(max_length=50, default='deepseek')
|
||||
ai_model = models.CharField(max_length=50, default='deepseek-chat')
|
||||
processing_time = models.FloatField(null=True, blank=True) # AI处理耗时(秒)
|
||||
evaluation_time = models.DateTimeField(null=True, blank=True) # 评分完成时间
|
||||
|
||||
|
||||
class Meta:
|
||||
db_table = 'flowchart_submission'
|
||||
ordering = ['-create_time']
|
||||
indexes = [
|
||||
models.Index(fields=['user', 'create_time'], name='flowchart_user_time_idx'),
|
||||
models.Index(fields=['problem', 'create_time'], name='flowchart_problem_time_idx'),
|
||||
models.Index(fields=['status'], name='flowchart_status_idx'),
|
||||
]
|
||||
|
||||
def __str__(self):
|
||||
return f"FlowchartSubmission {self.id}"
|
||||
|
||||
def check_user_permission(self, user, check_share=True):
|
||||
"""检查用户权限"""
|
||||
if (
|
||||
self.user_id == user.id
|
||||
or not user.is_regular_user()
|
||||
or self.problem.created_by_id == user.id
|
||||
):
|
||||
return True
|
||||
|
||||
return False
|
||||
60
flowchart/serializers.py
Normal file
60
flowchart/serializers.py
Normal file
@@ -0,0 +1,60 @@
|
||||
from rest_framework import serializers
|
||||
from .models import FlowchartSubmission
|
||||
|
||||
|
||||
class CreateFlowchartSubmissionSerializer(serializers.Serializer):
|
||||
problem_id = serializers.IntegerField()
|
||||
mermaid_code = serializers.CharField()
|
||||
flowchart_data = serializers.JSONField(required=False, default=dict)
|
||||
|
||||
def validate_mermaid_code(self, value):
|
||||
if not value.strip():
|
||||
raise serializers.ValidationError("Mermaid代码不能为空")
|
||||
return value
|
||||
|
||||
|
||||
class FlowchartSubmissionSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = FlowchartSubmission
|
||||
fields = [
|
||||
"id",
|
||||
"user",
|
||||
"problem",
|
||||
"mermaid_code",
|
||||
"flowchart_data",
|
||||
"status",
|
||||
"create_time",
|
||||
"ai_score",
|
||||
"ai_grade",
|
||||
"ai_feedback",
|
||||
"ai_suggestions",
|
||||
"ai_criteria_details",
|
||||
"ai_provider",
|
||||
"ai_model",
|
||||
"processing_time",
|
||||
"evaluation_time",
|
||||
]
|
||||
read_only_fields = ["id", "create_time", "evaluation_time"]
|
||||
|
||||
|
||||
class FlowchartSubmissionListSerializer(serializers.ModelSerializer):
|
||||
"""用于列表显示的简化序列化器"""
|
||||
|
||||
username = serializers.CharField(source="user.username")
|
||||
problem_title = serializers.CharField(source="problem.title")
|
||||
|
||||
class Meta:
|
||||
model = FlowchartSubmission
|
||||
fields = [
|
||||
"id",
|
||||
"username",
|
||||
"problem_title",
|
||||
"status",
|
||||
"create_time",
|
||||
"ai_score",
|
||||
"ai_grade",
|
||||
"ai_provider",
|
||||
"ai_model",
|
||||
"processing_time",
|
||||
"evaluation_time",
|
||||
]
|
||||
186
flowchart/tasks.py
Normal file
186
flowchart/tasks.py
Normal file
@@ -0,0 +1,186 @@
|
||||
import dramatiq
|
||||
import json
|
||||
import time
|
||||
from openai import OpenAI
|
||||
from django.db import transaction
|
||||
from django.utils import timezone
|
||||
from utils.shortcuts import get_env, DRAMATIQ_WORKER_ARGS
|
||||
from .models import FlowchartSubmission, FlowchartSubmissionStatus
|
||||
|
||||
@dramatiq.actor(**DRAMATIQ_WORKER_ARGS(max_retries=3))
|
||||
def evaluate_flowchart_task(submission_id):
|
||||
"""异步AI评分任务"""
|
||||
try:
|
||||
submission = FlowchartSubmission.objects.get(id=submission_id)
|
||||
|
||||
# 更新状态为处理中
|
||||
submission.status = FlowchartSubmissionStatus.PROCESSING
|
||||
submission.save()
|
||||
|
||||
start_time = time.time()
|
||||
|
||||
# 使用固定评分标准
|
||||
system_prompt = build_evaluation_prompt(submission.problem)
|
||||
|
||||
# 构建用户提示词,包含标准答案对比
|
||||
user_prompt = f"""
|
||||
请对以下Mermaid流程图进行评分:
|
||||
|
||||
学生提交的流程图:
|
||||
```mermaid
|
||||
{submission.mermaid_code}
|
||||
```
|
||||
|
||||
标准答案参考:
|
||||
```mermaid
|
||||
{submission.problem.mermaid_code}
|
||||
```
|
||||
"""
|
||||
# 如果有流程图提示,添加到提示词中
|
||||
if submission.problem.flowchart_hint:
|
||||
user_prompt += f"""
|
||||
|
||||
设计提示:{submission.problem.flowchart_hint}
|
||||
"""
|
||||
|
||||
user_prompt += """
|
||||
|
||||
请按照评分标准进行详细评估,并给出0-100的分数。
|
||||
"""
|
||||
|
||||
# 调用AI进行评分
|
||||
api_key = get_env("AI_KEY")
|
||||
if not api_key:
|
||||
raise Exception("AI_KEY is not set")
|
||||
|
||||
client = OpenAI(api_key=api_key, base_url="https://api.deepseek.com")
|
||||
|
||||
response = client.chat.completions.create(
|
||||
model="deepseek-chat",
|
||||
messages=[
|
||||
{"role": "system", "content": system_prompt},
|
||||
{"role": "user", "content": user_prompt}
|
||||
],
|
||||
temperature=0.3,
|
||||
)
|
||||
|
||||
ai_response = response.choices[0].message.content
|
||||
score_data = parse_ai_evaluation_response(ai_response)
|
||||
|
||||
processing_time = time.time() - start_time
|
||||
|
||||
# 保存评分结果
|
||||
with transaction.atomic():
|
||||
submission.ai_score = score_data['score']
|
||||
submission.ai_grade = score_data['grade']
|
||||
submission.ai_feedback = score_data['feedback']
|
||||
submission.ai_suggestions = score_data.get('suggestions', '')
|
||||
submission.ai_criteria_details = score_data.get('criteria_details', {})
|
||||
submission.ai_provider = 'deepseek'
|
||||
submission.ai_model = 'deepseek-chat'
|
||||
submission.processing_time = processing_time
|
||||
submission.status = FlowchartSubmissionStatus.COMPLETED
|
||||
submission.evaluation_time = timezone.now()
|
||||
submission.save()
|
||||
|
||||
# 推送评分完成通知
|
||||
from utils.websocket import push_flowchart_evaluation_update
|
||||
push_flowchart_evaluation_update(
|
||||
submission_id=str(submission.id),
|
||||
user_id=submission.user_id,
|
||||
data={
|
||||
"type": "flowchart_evaluation_completed",
|
||||
"submission_id": str(submission.id),
|
||||
"score": score_data['score'],
|
||||
"grade": score_data['grade'],
|
||||
"feedback": score_data['feedback']
|
||||
}
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
# 处理失败
|
||||
submission.status = FlowchartSubmissionStatus.FAILED
|
||||
submission.save()
|
||||
|
||||
# 推送错误通知
|
||||
from utils.websocket import push_flowchart_evaluation_update
|
||||
push_flowchart_evaluation_update(
|
||||
submission_id=str(submission.id),
|
||||
user_id=submission.user_id,
|
||||
data={
|
||||
"type": "flowchart_evaluation_failed",
|
||||
"submission_id": str(submission.id),
|
||||
"error": str(e)
|
||||
}
|
||||
)
|
||||
raise e
|
||||
|
||||
def build_evaluation_prompt(problem):
|
||||
"""构建AI评分提示词 - 使用固定标准"""
|
||||
|
||||
# 使用固定的评分标准
|
||||
criteria_text = """
|
||||
- 逻辑正确性 (权重: 1.0, 最高分: 40): 检查流程图的逻辑是否正确,包括条件判断、循环结构等
|
||||
- 完整性 (权重: 0.8, 最高分: 30): 检查流程图是否包含所有必要的步骤和分支
|
||||
- 规范性 (权重: 0.6, 最高分: 20): 检查流程图符号使用是否规范,是否符合标准
|
||||
- 清晰度 (权重: 0.4, 最高分: 10): 评估流程图的整体布局和可读性
|
||||
"""
|
||||
|
||||
return f"""
|
||||
你是一个专业的编程教学助手,负责评估学生提交的Mermaid流程图。
|
||||
|
||||
评分标准:
|
||||
{criteria_text}
|
||||
|
||||
评分要求:
|
||||
1. 仔细分析流程图的逻辑正确性、完整性和清晰度
|
||||
2. 检查是否涵盖了题目的所有要求
|
||||
3. 评估流程图的规范性和可读性
|
||||
4. 给出0-100的分数
|
||||
5. 提供详细的反馈和改进建议
|
||||
|
||||
评分等级:
|
||||
- S级 (90-100分): 优秀,逻辑清晰,完全符合要求
|
||||
- A级 (80-89分): 良好,基本符合要求,有少量改进空间
|
||||
- B级 (70-79分): 及格,基本正确但存在一些问题
|
||||
- C级 (0-69分): 需要改进,存在明显问题
|
||||
|
||||
请以JSON格式返回评分结果:
|
||||
{{
|
||||
"score": 85,
|
||||
"grade": "A",
|
||||
"feedback": "详细的反馈内容",
|
||||
"suggestions": "改进建议",
|
||||
"criteria_details": {{
|
||||
"逻辑正确性": {{"score": 35, "max": 40, "comment": "逻辑基本正确"}},
|
||||
"完整性": {{"score": 25, "max": 30, "comment": "缺少部分步骤"}},
|
||||
"规范性": {{"score": 18, "max": 20, "comment": "符号使用规范"}},
|
||||
"清晰度": {{"score": 8, "max": 10, "comment": "布局清晰"}}
|
||||
}}
|
||||
}}
|
||||
"""
|
||||
|
||||
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": {}
|
||||
}
|
||||
1
flowchart/urls/__init__.py
Normal file
1
flowchart/urls/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
# URLs package
|
||||
12
flowchart/urls/oj.py
Normal file
12
flowchart/urls/oj.py
Normal file
@@ -0,0 +1,12 @@
|
||||
from django.urls import path
|
||||
from ..views.oj import (
|
||||
FlowchartSubmissionAPI,
|
||||
FlowchartSubmissionListAPI,
|
||||
FlowchartSubmissionRetryAPI
|
||||
)
|
||||
|
||||
urlpatterns = [
|
||||
path('flowchart/submission', FlowchartSubmissionAPI.as_view()),
|
||||
path('flowchart/submissions', FlowchartSubmissionListAPI.as_view()),
|
||||
path('flowchart/submission/retry', FlowchartSubmissionRetryAPI.as_view()),
|
||||
]
|
||||
3
flowchart/views.py
Normal file
3
flowchart/views.py
Normal file
@@ -0,0 +1,3 @@
|
||||
from django.shortcuts import render
|
||||
|
||||
# Create your views here.
|
||||
1
flowchart/views/__init__.py
Normal file
1
flowchart/views/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
# Views package
|
||||
138
flowchart/views/oj.py
Normal file
138
flowchart/views/oj.py
Normal file
@@ -0,0 +1,138 @@
|
||||
from utils.api import APIView
|
||||
from account.decorators import login_required
|
||||
from flowchart.models import FlowchartSubmission, FlowchartSubmissionStatus
|
||||
from flowchart.serializers import (
|
||||
CreateFlowchartSubmissionSerializer,
|
||||
FlowchartSubmissionSerializer,
|
||||
FlowchartSubmissionListSerializer
|
||||
)
|
||||
from flowchart.tasks import evaluate_flowchart_task
|
||||
|
||||
class FlowchartSubmissionAPI(APIView):
|
||||
@login_required
|
||||
def post(self, request):
|
||||
"""创建流程图提交"""
|
||||
serializer = CreateFlowchartSubmissionSerializer(data=request.data)
|
||||
if not serializer.is_valid():
|
||||
return self.error(serializer.errors)
|
||||
|
||||
data = serializer.validated_data
|
||||
|
||||
# 验证题目存在
|
||||
try:
|
||||
from problem.models import Problem
|
||||
problem = Problem.objects.get(_id=data['problem_id'])
|
||||
except Problem.DoesNotExist:
|
||||
return self.error("Problem doesn't exist")
|
||||
|
||||
# 验证题目是否允许流程图提交
|
||||
if not problem.allow_flowchart:
|
||||
return self.error("This problem does not allow flowchart submission")
|
||||
|
||||
# 创建提交记录
|
||||
submission = FlowchartSubmission.objects.create(
|
||||
user=request.user,
|
||||
problem=problem,
|
||||
mermaid_code=data['mermaid_code'],
|
||||
flowchart_data=data.get('flowchart_data', {})
|
||||
)
|
||||
|
||||
# 启动AI评分任务
|
||||
evaluate_flowchart_task.send(submission.id)
|
||||
|
||||
return self.success({
|
||||
'submission_id': submission.id,
|
||||
'status': 'pending'
|
||||
})
|
||||
|
||||
@login_required
|
||||
def get(self, request):
|
||||
"""获取流程图提交详情"""
|
||||
submission_id = request.GET.get('id')
|
||||
if not submission_id:
|
||||
return self.error("submission_id is required")
|
||||
|
||||
try:
|
||||
submission = FlowchartSubmission.objects.get(id=submission_id)
|
||||
except FlowchartSubmission.DoesNotExist:
|
||||
return self.error("Submission doesn't exist")
|
||||
|
||||
if not submission.check_user_permission(request.user):
|
||||
return self.error("No permission for this submission")
|
||||
|
||||
serializer = FlowchartSubmissionSerializer(submission)
|
||||
return self.success(serializer.data)
|
||||
|
||||
class FlowchartSubmissionListAPI(APIView):
|
||||
@login_required
|
||||
def get(self, request):
|
||||
"""获取流程图提交列表"""
|
||||
user_id = request.GET.get('user_id')
|
||||
problem_id = request.GET.get('problem_id')
|
||||
offset = int(request.GET.get('offset', 0))
|
||||
limit = int(request.GET.get('limit', 20))
|
||||
|
||||
queryset = FlowchartSubmission.objects.select_related('user', 'problem')
|
||||
|
||||
# 权限过滤
|
||||
if not request.user.is_admin_role():
|
||||
queryset = queryset.filter(user=request.user)
|
||||
|
||||
# 其他过滤条件
|
||||
if user_id:
|
||||
queryset = queryset.filter(user_id=user_id)
|
||||
if problem_id:
|
||||
queryset = queryset.filter(problem_id=problem_id)
|
||||
|
||||
total = queryset.count()
|
||||
submissions = queryset[offset:offset + limit]
|
||||
|
||||
serializer = FlowchartSubmissionListSerializer(submissions, many=True)
|
||||
|
||||
return self.success({
|
||||
'results': serializer.data,
|
||||
'total': total
|
||||
})
|
||||
|
||||
|
||||
class FlowchartSubmissionRetryAPI(APIView):
|
||||
@login_required
|
||||
def post(self, request):
|
||||
"""重新触发AI评分"""
|
||||
submission_id = request.data.get('submission_id')
|
||||
if not submission_id:
|
||||
return self.error("submission_id is required")
|
||||
|
||||
try:
|
||||
submission = FlowchartSubmission.objects.get(id=submission_id)
|
||||
except FlowchartSubmission.DoesNotExist:
|
||||
return self.error("Submission doesn't exist")
|
||||
|
||||
# 检查权限
|
||||
if not submission.check_user_permission(request.user):
|
||||
return self.error("No permission for this submission")
|
||||
|
||||
# 检查是否可以重新评分
|
||||
if submission.status not in [FlowchartSubmissionStatus.FAILED, FlowchartSubmissionStatus.COMPLETED]:
|
||||
return self.error("Submission is not in a state that allows retry")
|
||||
|
||||
# 重置状态并重新启动AI评分
|
||||
submission.status = FlowchartSubmissionStatus.PENDING
|
||||
submission.ai_score = None
|
||||
submission.ai_grade = None
|
||||
submission.ai_feedback = None
|
||||
submission.ai_suggestions = None
|
||||
submission.ai_criteria_details = {}
|
||||
submission.processing_time = None
|
||||
submission.evaluation_time = None
|
||||
submission.save()
|
||||
|
||||
# 重新启动AI评分任务
|
||||
evaluate_flowchart_task.send(submission.id)
|
||||
|
||||
return self.success({
|
||||
'submission_id': submission.id,
|
||||
'status': 'pending',
|
||||
'message': 'AI evaluation restarted'
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user