feat: web UI - dashboard, requirement/submission pages, create & upload forms
This commit is contained in:
+100
@@ -0,0 +1,100 @@
|
||||
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)
|
||||
Reference in New Issue
Block a user