diff --git a/backend/ai_services/admin.py b/backend/ai_services/admin.py index 02d5b58..3da40ef 100644 --- a/backend/ai_services/admin.py +++ b/backend/ai_services/admin.py @@ -22,7 +22,7 @@ class TranscriptionTaskAdmin(UnfoldModelAdmin): @admin.register(AIEvaluationTemplate) class AIEvaluationTemplateAdmin(UnfoldModelAdmin): - list_display = ['name', 'model_selection', 'is_active', 'created_at'] + list_display = ['name', 'model_selection', 'score_dimension', 'is_active', 'created_at'] list_filter = ['is_active', 'model_selection', 'created_at'] search_fields = ['name', 'prompt'] diff --git a/backend/ai_services/bailian_service.py b/backend/ai_services/bailian_service.py index 2c55725..73a113b 100644 --- a/backend/ai_services/bailian_service.py +++ b/backend/ai_services/bailian_service.py @@ -205,24 +205,34 @@ class BailianService: # 3. 同步评分 (Score) if evaluation.score is not None: # 尝试找到匹配的维度 - # 优先级:完全匹配模板名称 > 包含"AI"的维度 > 第一个维度 dimensions = competition.score_dimensions.all() target_dimension = None - for dim in dimensions: - if dim.name == template_name: - target_dimension = dim - break + # 0. 优先使用模板配置的维度 + if evaluation.template and evaluation.template.score_dimension: + # 检查配置的维度是否属于当前比赛 + if evaluation.template.score_dimension.competition_id == competition.id: + target_dimension = evaluation.template.score_dimension + else: + # 如果不属于当前比赛(跨比赛复用模板),尝试查找同名维度 + target_dimension = dimensions.filter(name=evaluation.template.score_dimension.name).first() + # 1. 如果未配置或未找到,尝试匹配 "AI Rating" (用户指定默认值) + if not target_dimension: + target_dimension = dimensions.filter(name__iexact="AI Rating").first() + + # 2. 尝试匹配包含 "AI" 的维度 if not target_dimension: for dim in dimensions: if "AI" in dim.name.upper(): target_dimension = dim break + + # 3. 尝试匹配模板名称 + if not target_dimension: + target_dimension = dimensions.filter(name=template_name).first() - # 如果还是没找到,尝试创建一个默认的 "AI评分" 维度? - # 或者使用第一个维度。考虑到用户说"对应的AI评分",如果没有对应的,可能需要创建一个? - # 为了安全起见,如果找不到明确的AI维度,且存在维度,就用第一个;否则不评分。 + # 4. 最后兜底:使用第一个维度 if not target_dimension and dimensions.exists(): target_dimension = dimensions.first() diff --git a/backend/ai_services/migrations/0007_aievaluationtemplate_score_dimension.py b/backend/ai_services/migrations/0007_aievaluationtemplate_score_dimension.py new file mode 100644 index 0000000..642319e --- /dev/null +++ b/backend/ai_services/migrations/0007_aievaluationtemplate_score_dimension.py @@ -0,0 +1,20 @@ +# Generated by Django 6.0.1 on 2026-03-11 15:03 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('ai_services', '0006_transcriptiontask_project'), + ('competition', '0003_competition_project_visibility'), + ] + + operations = [ + migrations.AddField( + model_name='aievaluationtemplate', + name='score_dimension', + field=models.ForeignKey(blank=True, help_text='如果同步到比赛评分,优先使用此维度。未填写则默认使用"AI Rating"或包含"AI"的维度', null=True, on_delete=django.db.models.deletion.SET_NULL, to='competition.scoredimension', verbose_name='关联评分维度'), + ), + ] diff --git a/backend/ai_services/models.py b/backend/ai_services/models.py index c2d253b..442d913 100644 --- a/backend/ai_services/models.py +++ b/backend/ai_services/models.py @@ -65,6 +65,14 @@ class AIEvaluationTemplate(models.Model): default='你是一个专业的评分助手。请根据提供的转写内容,对内容质量、逻辑清晰度、语言表达等方面进行综合评分(0-100分),并给出详细的评语。请以JSON格式返回,包含"score"和"evaluation"字段。', help_text=_('用于指导AI评分的提示词') ) + score_dimension = models.ForeignKey( + 'competition.ScoreDimension', + on_delete=models.SET_NULL, + null=True, + blank=True, + verbose_name=_('关联评分维度'), + help_text=_('如果同步到比赛评分,优先使用此维度。未填写则默认使用"AI Rating"或包含"AI"的维度') + ) is_active = models.BooleanField(verbose_name=_('是否启用'), default=True, help_text=_('启用后,新的转写任务完成后将自动使用此模板进行评估')) created_at = models.DateTimeField(verbose_name=_('创建时间'), auto_now_add=True) diff --git a/frontend/src/components/competition/CompetitionDetail.jsx b/frontend/src/components/competition/CompetitionDetail.jsx index acaead8..4e0d442 100644 --- a/frontend/src/components/competition/CompetitionDetail.jsx +++ b/frontend/src/components/competition/CompetitionDetail.jsx @@ -315,7 +315,7 @@ const CompetitionDetail = () => {