From 465ea34dcd3d668558ff5cd2451b9fa9dc819669 Mon Sep 17 00:00:00 2001 From: jeremygan2021 Date: Tue, 17 Mar 2026 23:48:08 +0800 Subject: [PATCH] audo url --- backend/competition/judge_urls.py | 1 + backend/competition/judge_views.py | 87 +++++++++++++++ .../templates/judge/dashboard.html | 103 +++++++++++++++++- 3 files changed, 188 insertions(+), 3 deletions(-) diff --git a/backend/competition/judge_urls.py b/backend/competition/judge_urls.py index 243bc31..efe8719 100644 --- a/backend/competition/judge_urls.py +++ b/backend/competition/judge_urls.py @@ -16,5 +16,6 @@ urlpatterns = [ path('api/projects//', judge_views.project_detail_api, name='judge_project_detail_api'), path('api/score/submit/', judge_views.submit_score, name='judge_submit_score'), path('api/upload/', judge_views.upload_audio, name='judge_api_upload'), + path('api/upload/url/', judge_views.upload_audio_url, name='judge_api_upload_url'), path('api/ai//delete/', judge_views.delete_ai_task, name='judge_delete_ai_task'), ] diff --git a/backend/competition/judge_views.py b/backend/competition/judge_views.py index 898f2a0..6bf03f6 100644 --- a/backend/competition/judge_views.py +++ b/backend/competition/judge_views.py @@ -509,6 +509,93 @@ def upload_audio(request): logger.error(f"Upload error: {e}") return JsonResponse({'success': False, 'message': str(e)}) +@judge_required +@csrf_exempt +def upload_audio_url(request): + """ + 处理 URL 上传音频的 API + 通过给定的音频 URL 直接进行处理,无需上传文件 + """ + role = request.session.get('judge_role') + if role not in ['judge', 'guest']: + return JsonResponse({'success': False, 'message': 'Permission denied'}) + + if request.method != 'POST': + return JsonResponse({'success': False, 'message': 'Method not allowed'}) + + import json + try: + data = json.loads(request.body) + except json.JSONDecodeError: + return JsonResponse({'success': False, 'message': 'Invalid JSON'}) + + audio_url = data.get('url') + project_id = data.get('project_id') + + if not audio_url or not project_id: + return JsonResponse({'success': False, 'message': 'Missing url or project_id'}) + + # 验证 URL 格式 + if not audio_url.startswith(('http://', 'https://')): + return JsonResponse({'success': False, 'message': 'Invalid URL format'}) + + judge_id = request.session['judge_id'] + + try: + # 验证权限 + user = WeChatUser.objects.get(id=judge_id) + project = Project.objects.get(id=project_id) + + enrollment = CompetitionEnrollment.objects.filter( + user=user, + role=role, + competition=project.competition + ).first() + + if not enrollment: + return JsonResponse({'success': False, 'message': 'No permission for this project'}) + + # 创建任务记录,使用 URL 作为 file_url + service = AliyunTingwuService() + + task = TranscriptionTask.objects.create( + project=project, + file_url=audio_url, + status=TranscriptionTask.Status.PENDING + ) + + # 调用 Tingwu 服务 + try: + tingwu_response = service.create_transcription_task(audio_url) + + if 'Data' in tingwu_response and isinstance(tingwu_response['Data'], dict): + task_id = tingwu_response['Data'].get('TaskId') + else: + task_id = tingwu_response.get('TaskId') + + if task_id: + task.task_id = task_id + task.status = TranscriptionTask.Status.PROCESSING + task.save() + + log_audit(request, 'UPLOAD_AUDIO_URL', f"Task {task.id}", 'SUCCESS') + return JsonResponse({'success': True, 'task_id': task.id, 'file_url': audio_url}) + else: + task.status = TranscriptionTask.Status.FAILED + task.error_message = "No TaskId returned" + task.save() + return JsonResponse({'success': False, 'message': 'Failed to create Tingwu task'}) + + except Exception as e: + task.status = TranscriptionTask.Status.FAILED + task.error_message = str(e) + task.save() + return JsonResponse({'success': False, 'message': f'Tingwu Error: {e}'}) + + except Exception as e: + logger.error(f"Upload URL error: {e}") + return JsonResponse({'success': False, 'message': str(e)}) + @judge_required def ai_manage(request): # Contestants cannot access AI manage diff --git a/backend/competition/templates/judge/dashboard.html b/backend/competition/templates/judge/dashboard.html index 2d3f668..5021850 100644 --- a/backend/competition/templates/judge/dashboard.html +++ b/backend/competition/templates/judge/dashboard.html @@ -204,6 +204,21 @@
+ +
+ + +
+
+ + +
@@ -211,7 +226,7 @@

或拖拽文件到这里

@@ -221,6 +236,13 @@
+ + +