完善skills;测试用例生成页面功能初步实现

This commit is contained in:
2026-05-05 19:45:33 +08:00
parent 0c2ed67e2a
commit 69b49d28b2
35 changed files with 4396 additions and 658 deletions

View File

@@ -1,26 +1,46 @@
from pathlib import Path
from typing import Any, List
import shutil
from fastapi import APIRouter, BackgroundTasks, Depends, File, HTTPException, UploadFile
from sqlalchemy.orm import Session
from app.core.security import get_current_user
from app.db.session import get_db
from app.models.tooling import SRSExtraction, ToolJob
from app.models.knowledge import KnowledgeBase
from app.models.tooling import SRSExtraction, TestingGeneration, ToolJob
from app.models.user import User
from app.schemas.tooling import (
SRSToolCreateJobResponse,
SRSToolHistoryItem,
SRSToolJobStatusResponse,
SRSToolRequirementsSaveRequest,
SRSToolResultResponse,
TestingGenerationCreateRequest,
TestingGenerationCreateResponse,
TestingGenerationHistoryItem,
TestingGenerationJobStatusResponse,
TestingGenerationResultResponse,
TestingGenerationSaveRequest,
ToolDefinitionResponse,
)
from app.services.srs_job_service import (
build_srs_upload_path,
build_result_response,
delete_srs_job,
ensure_upload_path,
list_srs_history,
replace_requirements,
run_srs_job,
)
from app.services.testing_generation_service import (
build_testing_generation_response,
create_testing_generation,
delete_testing_generation,
list_testing_history,
)
from app.services.testing_generation_job_service import run_testing_generation_job
from app.tools.registry import ToolRegistry
from app.tools.srs_reqs_qwen import get_srs_tool
@@ -173,3 +193,223 @@ async def save_srs_requirements(
db.refresh(extraction)
return build_result_response(job, extraction)
@router.get("/srs/history", response_model=List[SRSToolHistoryItem])
async def get_srs_history(
db: Session = Depends(get_db),
current_user: User = Depends(get_current_user),
) -> Any:
return list_srs_history(db, current_user.id)
@router.delete("/srs/jobs/{job_id}")
async def delete_srs_job_api(
job_id: int,
db: Session = Depends(get_db),
current_user: User = Depends(get_current_user),
) -> Any:
job = (
db.query(ToolJob)
.filter(ToolJob.id == job_id, ToolJob.user_id == current_user.id)
.first()
)
if not job:
raise HTTPException(status_code=404, detail="任务不存在")
upload_path = build_srs_upload_path(job_id)
delete_srs_job(db, job)
if upload_path.exists():
shutil.rmtree(upload_path, ignore_errors=True)
return {"message": "删除成功"}
@router.post("/testing/generations", response_model=TestingGenerationResultResponse)
async def save_testing_generation(
payload: TestingGenerationSaveRequest,
db: Session = Depends(get_db),
current_user: User = Depends(get_current_user),
) -> Any:
if payload.source_job_id is not None:
source_job = (
db.query(ToolJob)
.filter(
ToolJob.id == payload.source_job_id,
ToolJob.user_id == current_user.id,
)
.first()
)
if not source_job:
raise HTTPException(status_code=404, detail="来源文件不存在")
if payload.knowledge_base_id is not None:
knowledge_base = (
db.query(KnowledgeBase)
.filter(
KnowledgeBase.id == payload.knowledge_base_id,
KnowledgeBase.user_id == current_user.id,
)
.first()
)
if not knowledge_base:
raise HTTPException(status_code=404, detail="知识库不存在")
return create_testing_generation(db, current_user.id, payload)
@router.post("/testing/jobs", response_model=TestingGenerationCreateResponse)
async def create_testing_generation_job(
background_tasks: BackgroundTasks,
payload: TestingGenerationCreateRequest,
db: Session = Depends(get_db),
current_user: User = Depends(get_current_user),
) -> Any:
if payload.source_job_id is not None:
source_job = (
db.query(ToolJob)
.filter(
ToolJob.id == payload.source_job_id,
ToolJob.user_id == current_user.id,
)
.first()
)
if not source_job:
raise HTTPException(status_code=404, detail="来源文件不存在")
if payload.knowledge_base_id is not None:
knowledge_base = (
db.query(KnowledgeBase)
.filter(
KnowledgeBase.id == payload.knowledge_base_id,
KnowledgeBase.user_id == current_user.id,
)
.first()
)
if not knowledge_base:
raise HTTPException(status_code=404, detail="知识库不存在")
job = ToolJob(
user_id=current_user.id,
tool_name="testing.case_generator",
status="pending",
input_file_name=payload.source_document_name,
input_file_path="",
output_summary={
"source_document_name": payload.source_document_name,
"current_step": 0,
"total_steps": len(payload.requirements),
},
)
db.add(job)
db.commit()
db.refresh(job)
background_tasks.add_task(
run_testing_generation_job,
job.id,
payload.dict(),
)
return {
"job_id": job.id,
"status": job.status,
}
@router.get("/testing/jobs/{job_id}", response_model=TestingGenerationJobStatusResponse)
async def get_testing_generation_job_status(
job_id: int,
db: Session = Depends(get_db),
current_user: User = Depends(get_current_user),
) -> Any:
job = (
db.query(ToolJob)
.filter(
ToolJob.id == job_id,
ToolJob.user_id == current_user.id,
)
.first()
)
if not job:
raise HTTPException(status_code=404, detail="任务不存在")
summary = job.output_summary or {}
return {
"job_id": job.id,
"tool_name": job.tool_name,
"status": job.status,
"error_message": job.error_message,
"started_at": job.started_at,
"completed_at": job.completed_at,
"source_document_name": summary.get("source_document_name"),
"current_step": summary.get("current_step"),
"total_steps": summary.get("total_steps"),
"current_requirement_id": summary.get("current_requirement_id"),
}
@router.get("/testing/history", response_model=List[TestingGenerationHistoryItem])
async def get_testing_history(
db: Session = Depends(get_db),
current_user: User = Depends(get_current_user),
) -> Any:
return list_testing_history(db, current_user.id)
@router.get("/testing/jobs/{job_id}/result", response_model=TestingGenerationResultResponse)
async def get_testing_generation_result(
job_id: int,
db: Session = Depends(get_db),
current_user: User = Depends(get_current_user),
) -> Any:
job = (
db.query(ToolJob)
.filter(
ToolJob.id == job_id,
ToolJob.user_id == current_user.id,
)
.first()
)
if not job:
raise HTTPException(status_code=404, detail="任务不存在")
generation = (
db.query(TestingGeneration)
.filter(TestingGeneration.job_id == job.id)
.first()
)
if not generation:
raise HTTPException(status_code=404, detail="任务结果不存在")
return build_testing_generation_response(job, generation)
@router.delete("/testing/jobs/{job_id}")
async def delete_testing_generation_api(
job_id: int,
db: Session = Depends(get_db),
current_user: User = Depends(get_current_user),
) -> Any:
job = (
db.query(ToolJob)
.filter(
ToolJob.id == job_id,
ToolJob.user_id == current_user.id,
)
.first()
)
if not job:
raise HTTPException(status_code=404, detail="任务不存在")
generation = (
db.query(TestingGeneration)
.filter(TestingGeneration.job_id == job.id)
.first()
)
if not generation:
raise HTTPException(status_code=404, detail="任务结果不存在")
delete_testing_generation(db, job)
return {"message": "删除成功"}