123 lines
4.2 KiB
Python
123 lines
4.2 KiB
Python
from typing import Optional, List, Tuple
|
|
from sqlalchemy.orm import Session
|
|
from fastapi import HTTPException, status
|
|
|
|
from app.models.project import ClassificationTask, ClassificationProject, ClassificationResult, TaskStatus, ResultStatus
|
|
from app.models.metadata import DataColumn, DataTable, Database as MetaDatabase
|
|
|
|
|
|
def get_task(db: Session, task_id: int) -> Optional[ClassificationTask]:
|
|
return db.query(ClassificationTask).filter(ClassificationTask.id == task_id).first()
|
|
|
|
|
|
def list_tasks(
|
|
db: Session,
|
|
project_id: Optional[int] = None,
|
|
assignee_id: Optional[int] = None,
|
|
status: Optional[str] = None,
|
|
page: int = 1,
|
|
page_size: int = 20,
|
|
) -> Tuple[List[ClassificationTask], int]:
|
|
query = db.query(ClassificationTask)
|
|
if project_id:
|
|
query = query.filter(ClassificationTask.project_id == project_id)
|
|
if assignee_id:
|
|
query = query.filter(ClassificationTask.assignee_id == assignee_id)
|
|
if status:
|
|
query = query.filter(ClassificationTask.status == status)
|
|
total = query.count()
|
|
items = query.order_by(ClassificationTask.created_at.desc()).offset((page - 1) * page_size).limit(page_size).all()
|
|
return items, total
|
|
|
|
|
|
def create_task(
|
|
db: Session,
|
|
project_id: int,
|
|
name: str,
|
|
assigner_id: int,
|
|
assignee_id: int,
|
|
target_type: str = "column",
|
|
target_ids: Optional[str] = None,
|
|
deadline: Optional[str] = None,
|
|
) -> ClassificationTask:
|
|
from datetime import datetime
|
|
db_obj = ClassificationTask(
|
|
project_id=project_id,
|
|
name=name,
|
|
assigner_id=assigner_id,
|
|
assignee_id=assignee_id,
|
|
target_type=target_type,
|
|
target_ids=target_ids,
|
|
status=TaskStatus.PENDING.value,
|
|
deadline=datetime.fromisoformat(deadline) if deadline else None,
|
|
)
|
|
db.add(db_obj)
|
|
db.commit()
|
|
db.refresh(db_obj)
|
|
return db_obj
|
|
|
|
|
|
def update_task_status(db: Session, task: ClassificationTask, status: str) -> ClassificationTask:
|
|
task.status = status
|
|
if status == TaskStatus.COMPLETED.value:
|
|
from datetime import datetime
|
|
task.completed_at = datetime.utcnow()
|
|
db.commit()
|
|
db.refresh(task)
|
|
return task
|
|
|
|
|
|
def assign_columns_to_task(db: Session, project_id: int, task_id: int, column_ids: List[int]) -> None:
|
|
"""Assign columns to a task by creating/updating classification results."""
|
|
from app.services.project_service import list_results
|
|
for col_id in column_ids:
|
|
result = db.query(ClassificationResult).filter(
|
|
ClassificationResult.project_id == project_id,
|
|
ClassificationResult.column_id == col_id,
|
|
).first()
|
|
if not result:
|
|
result = ClassificationResult(
|
|
project_id=project_id,
|
|
column_id=col_id,
|
|
status=ResultStatus.AUTO.value,
|
|
source="auto",
|
|
confidence=0.0,
|
|
)
|
|
db.add(result)
|
|
db.commit()
|
|
|
|
|
|
def get_task_label_items(db: Session, project_id: int, keyword: Optional[str] = None) -> List[dict]:
|
|
"""Get all label items for a project (used in task labeling view)."""
|
|
query = db.query(ClassificationResult).filter(ClassificationResult.project_id == project_id)
|
|
results = query.all()
|
|
|
|
items = []
|
|
for r in results:
|
|
col = r.column
|
|
if not col:
|
|
continue
|
|
table = col.table
|
|
database = table.database if table else None
|
|
source = database.source if database else None
|
|
|
|
items.append({
|
|
"result_id": r.id,
|
|
"column_id": col.id,
|
|
"column_name": col.name,
|
|
"data_type": col.data_type,
|
|
"comment": col.comment,
|
|
"table_name": table.name if table else None,
|
|
"database_name": database.name if database else None,
|
|
"source_name": source.name if source else None,
|
|
"category_id": r.category_id,
|
|
"category_name": r.category.name if r.category else None,
|
|
"level_id": r.level_id,
|
|
"level_name": r.level.name if r.level else None,
|
|
"level_color": r.level.color if r.level else None,
|
|
"source": r.source,
|
|
"confidence": r.confidence,
|
|
"status": r.status,
|
|
})
|
|
return items
|