Files
prop-data-guard/backend/app/services/project_service.py
T
2026-04-22 17:07:33 +08:00

121 lines
4.1 KiB
Python

from typing import Optional, List, Tuple
from sqlalchemy.orm import Session
from fastapi import HTTPException, status
from app.models.project import ClassificationProject, ClassificationTask, ClassificationResult
from app.models.classification import Category, DataLevel
from app.models.metadata import DataColumn, DataTable, Database as MetaDatabase
def get_project(db: Session, project_id: int) -> Optional[ClassificationProject]:
return db.query(ClassificationProject).filter(ClassificationProject.id == project_id).first()
def list_projects(
db: Session, keyword: Optional[str] = None, page: int = 1, page_size: int = 20
) -> Tuple[List[ClassificationProject], int]:
query = db.query(ClassificationProject)
if keyword:
query = query.filter(ClassificationProject.name.contains(keyword))
total = query.count()
items = query.order_by(ClassificationProject.created_at.desc()).offset((page - 1) * page_size).limit(page_size).all()
return items, total
def create_project(db: Session, name: str, template_id: int, created_by: int, **kwargs) -> ClassificationProject:
db_obj = ClassificationProject(
name=name,
template_id=template_id,
created_by=created_by,
**kwargs,
)
db.add(db_obj)
db.commit()
db.refresh(db_obj)
return db_obj
def update_project(db: Session, db_obj: ClassificationProject, **kwargs) -> ClassificationProject:
for k, v in kwargs.items():
if v is not None:
setattr(db_obj, k, v)
db.commit()
db.refresh(db_obj)
return db_obj
def delete_project(db: Session, project_id: int) -> None:
db_obj = get_project(db, project_id)
if not db_obj:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="项目不存在")
db.delete(db_obj)
db.commit()
def get_project_stats(db: Session, project_id: int) -> dict:
total = db.query(ClassificationResult).filter(ClassificationResult.project_id == project_id).count()
auto_count = db.query(ClassificationResult).filter(
ClassificationResult.project_id == project_id,
ClassificationResult.source == "auto",
).count()
manual_count = db.query(ClassificationResult).filter(
ClassificationResult.project_id == project_id,
ClassificationResult.source == "manual",
).count()
reviewed_count = db.query(ClassificationResult).filter(
ClassificationResult.project_id == project_id,
ClassificationResult.status == "reviewed",
).count()
return {
"total": total,
"auto": auto_count,
"manual": manual_count,
"reviewed": reviewed_count,
}
def list_results(
db: Session,
project_id: Optional[int] = None,
table_id: Optional[int] = None,
status: Optional[str] = None,
keyword: Optional[str] = None,
page: int = 1,
page_size: int = 50,
) -> Tuple[List[ClassificationResult], int]:
query = db.query(ClassificationResult)
if project_id:
query = query.filter(ClassificationResult.project_id == project_id)
if table_id:
query = query.join(DataColumn).filter(DataColumn.table_id == table_id)
if status:
query = query.filter(ClassificationResult.status == status)
if keyword:
query = query.join(DataColumn).filter(
(DataColumn.name.contains(keyword)) | (DataColumn.comment.contains(keyword))
)
total = query.count()
items = query.offset((page - 1) * page_size).limit(page_size).all()
return items, total
def update_result_label(
db: Session,
result_id: int,
category_id: int,
level_id: int,
labeler_id: int,
) -> ClassificationResult:
result = db.query(ClassificationResult).filter(ClassificationResult.id == result_id).first()
if not result:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="结果不存在")
result.category_id = category_id
result.level_id = level_id
result.labeler_id = labeler_id
result.source = "manual"
result.status = "manual"
result.label_time = __import__('datetime').datetime.utcnow()
db.commit()
db.refresh(result)
return result