Files

101 lines
3.8 KiB
Python

import json
from django.contrib import messages
from django.contrib.auth.decorators import login_required
from django.db import transaction
from django.db.models import Count
from django.shortcuts import get_object_or_404, redirect, render
from requirements.llm import analyze_requirements, _default_spec
from requirements.models import Requirement, Submission
from requirements.tasks import run_submission
@login_required
def dashboard(request):
requirements = Requirement.objects.annotate(sub_count=Count("submissions")).order_by("-created_at")
recent_submissions = Submission.objects.select_related("requirement").order_by("-created_at")[:15]
return render(request, "web/dashboard.html", {
"requirements": requirements,
"recent_submissions": recent_submissions,
})
@login_required
def requirement_detail(request, pk):
requirement = get_object_or_404(Requirement, pk=pk)
submissions = requirement.submissions.all()
return render(request, "web/requirement.html", {
"requirement": requirement,
"submissions": submissions,
})
@login_required
def submission_detail(request, pk):
submission = get_object_or_404(Submission, pk=pk)
return render(request, "web/submission.html", {
"submission": submission,
"report_json": json.dumps(submission.report or {}, ensure_ascii=False, indent=2),
})
@login_required
def create_requirement(request):
from django.conf import settings
if request.method != "POST":
return render(request, "web/create_requirement.html", {
"llm_base_url": settings.LLM_BASE_URL,
"llm_model": settings.LLM_MODEL,
})
title = (request.POST.get("title") or "").strip()
content = (request.POST.get("content") or "").strip()
if not title or not content:
messages.error(request, "标题和内容不能为空")
return redirect("create-requirement")
llm_mode = request.POST.get("llm_mode", "default")
override = {}
if llm_mode == "custom":
override = {
"mode": "custom",
"base_url": (request.POST.get("llm_base_url") or "").strip(),
"api_key": (request.POST.get("llm_api_key") or "").strip(),
"model": (request.POST.get("llm_model") or "").strip(),
}
if not override["base_url"] or not override["model"]:
messages.error(request, "custom 模式必须填写 LLM 地址和模型名")
return redirect("create-requirement")
try:
spec = analyze_requirements(content, override)
except Exception:
spec = _default_spec()
with transaction.atomic():
requirement = Requirement.objects.create(
title=title, content=content, spec=spec, llm_config=override,
)
messages.success(request, f"已创建作业要求「{title}」,AI 分析完成")
return redirect("requirement-detail", pk=requirement.pk)
@login_required
def upload_submission(request, pk):
requirement = get_object_or_404(Requirement, pk=pk)
if request.method != "POST":
return redirect("requirement-detail", pk=pk)
file = request.FILES.get("file")
if not file:
messages.error(request, "请选择要上传的项目包(tar/tar.gz/zip)")
return redirect("requirement-detail", pk=pk)
name = (request.POST.get("name") or "").strip() or file.name
with transaction.atomic():
submission = Submission.objects.create(
requirement=requirement, name=name, file=file, submitted_by=request.user,
)
try:
run_submission(submission.pk)
except Exception:
submission.status = "failed"
submission.save(update_fields=["status"])
messages.success(request, f"已提交「{name}」,检测完成")
return redirect("submission-detail", pk=submission.pk)