194 lines
7.3 KiB
Python
194 lines
7.3 KiB
Python
"""内容提交路由"""
|
|
from fastapi import APIRouter, Depends, HTTPException, Query
|
|
from sqlalchemy.orm import Session
|
|
from typing import List, Optional
|
|
from datetime import date
|
|
from database import get_db
|
|
from models import (
|
|
User, Submission, SubmissionHistory, Project, UserRole,
|
|
PhaseGroup, WorkType, ContentType, SubmitTo
|
|
)
|
|
from schemas import SubmissionCreate, SubmissionUpdate, SubmissionOut
|
|
from auth import get_current_user, require_role
|
|
|
|
router = APIRouter(prefix="/api/submissions", tags=["内容提交"])
|
|
|
|
|
|
def submission_to_out(s: Submission) -> SubmissionOut:
|
|
return SubmissionOut(
|
|
id=s.id, user_id=s.user_id,
|
|
user_name=s.user.name if s.user else None,
|
|
project_id=s.project_id,
|
|
project_name=s.project.name if s.project else None,
|
|
project_phase=s.project_phase.value if hasattr(s.project_phase, 'value') else s.project_phase,
|
|
work_type=s.work_type.value if hasattr(s.work_type, 'value') else s.work_type,
|
|
content_type=s.content_type.value if hasattr(s.content_type, 'value') else s.content_type,
|
|
duration_minutes=s.duration_minutes,
|
|
duration_seconds=s.duration_seconds,
|
|
total_seconds=s.total_seconds,
|
|
hours_spent=s.hours_spent,
|
|
submit_to=s.submit_to.value if hasattr(s.submit_to, 'value') else s.submit_to,
|
|
description=s.description,
|
|
submit_date=s.submit_date,
|
|
created_at=s.created_at,
|
|
)
|
|
|
|
|
|
@router.get("/", response_model=List[SubmissionOut])
|
|
def list_submissions(
|
|
project_id: Optional[int] = Query(None),
|
|
user_id: Optional[int] = Query(None),
|
|
start_date: Optional[date] = Query(None),
|
|
end_date: Optional[date] = Query(None),
|
|
db: Session = Depends(get_db),
|
|
current_user: User = Depends(get_current_user)
|
|
):
|
|
q = db.query(Submission)
|
|
# 成员只能看自己的
|
|
if current_user.role == UserRole.MEMBER:
|
|
q = q.filter(Submission.user_id == current_user.id)
|
|
elif user_id:
|
|
q = q.filter(Submission.user_id == user_id)
|
|
if project_id:
|
|
q = q.filter(Submission.project_id == project_id)
|
|
if start_date:
|
|
q = q.filter(Submission.submit_date >= start_date)
|
|
if end_date:
|
|
q = q.filter(Submission.submit_date <= end_date)
|
|
subs = q.order_by(Submission.submit_date.desc(), Submission.created_at.desc()).all()
|
|
return [submission_to_out(s) for s in subs]
|
|
|
|
|
|
@router.post("/", response_model=SubmissionOut)
|
|
def create_submission(
|
|
req: SubmissionCreate,
|
|
db: Session = Depends(get_db),
|
|
current_user: User = Depends(get_current_user)
|
|
):
|
|
# 校验项目存在
|
|
project = db.query(Project).filter(Project.id == req.project_id).first()
|
|
if not project:
|
|
raise HTTPException(status_code=404, detail="项目不存在")
|
|
|
|
# 自动计算总秒数
|
|
total_seconds = (req.duration_minutes or 0) * 60 + (req.duration_seconds or 0)
|
|
|
|
sub = Submission(
|
|
user_id=current_user.id,
|
|
project_id=req.project_id,
|
|
project_phase=PhaseGroup(req.project_phase),
|
|
work_type=WorkType(req.work_type),
|
|
content_type=ContentType(req.content_type),
|
|
duration_minutes=req.duration_minutes or 0,
|
|
duration_seconds=req.duration_seconds or 0,
|
|
total_seconds=total_seconds,
|
|
hours_spent=req.hours_spent,
|
|
submit_to=SubmitTo(req.submit_to),
|
|
description=req.description,
|
|
submit_date=req.submit_date,
|
|
)
|
|
db.add(sub)
|
|
db.commit()
|
|
db.refresh(sub)
|
|
return submission_to_out(sub)
|
|
|
|
|
|
@router.put("/{submission_id}", response_model=SubmissionOut)
|
|
def update_submission(
|
|
submission_id: int,
|
|
req: SubmissionUpdate,
|
|
db: Session = Depends(get_db),
|
|
current_user: User = Depends(require_role(UserRole.OWNER, UserRole.SUPERVISOR, UserRole.LEADER))
|
|
):
|
|
"""高权限修改提交记录(需填写原因)"""
|
|
sub = db.query(Submission).filter(Submission.id == submission_id).first()
|
|
if not sub:
|
|
raise HTTPException(status_code=404, detail="提交记录不存在")
|
|
|
|
# 保存旧数据用于历史记录
|
|
old_data = {
|
|
"project_phase": sub.project_phase.value if hasattr(sub.project_phase, 'value') else sub.project_phase,
|
|
"work_type": sub.work_type.value if hasattr(sub.work_type, 'value') else sub.work_type,
|
|
"content_type": sub.content_type.value if hasattr(sub.content_type, 'value') else sub.content_type,
|
|
"duration_minutes": sub.duration_minutes,
|
|
"duration_seconds": sub.duration_seconds,
|
|
"total_seconds": sub.total_seconds,
|
|
"hours_spent": sub.hours_spent,
|
|
"submit_to": sub.submit_to.value if hasattr(sub.submit_to, 'value') else sub.submit_to,
|
|
"description": sub.description,
|
|
"submit_date": str(sub.submit_date),
|
|
}
|
|
|
|
# 更新字段
|
|
if req.project_phase is not None:
|
|
sub.project_phase = PhaseGroup(req.project_phase)
|
|
if req.work_type is not None:
|
|
sub.work_type = WorkType(req.work_type)
|
|
if req.content_type is not None:
|
|
sub.content_type = ContentType(req.content_type)
|
|
if req.duration_minutes is not None:
|
|
sub.duration_minutes = req.duration_minutes
|
|
if req.duration_seconds is not None:
|
|
sub.duration_seconds = req.duration_seconds
|
|
if req.hours_spent is not None:
|
|
sub.hours_spent = req.hours_spent
|
|
if req.submit_to is not None:
|
|
sub.submit_to = SubmitTo(req.submit_to)
|
|
if req.description is not None:
|
|
sub.description = req.description
|
|
if req.submit_date is not None:
|
|
sub.submit_date = req.submit_date
|
|
|
|
# 重算总秒数
|
|
sub.total_seconds = (sub.duration_minutes or 0) * 60 + (sub.duration_seconds or 0)
|
|
|
|
# 保存新数据
|
|
new_data = {
|
|
"project_phase": sub.project_phase.value if hasattr(sub.project_phase, 'value') else sub.project_phase,
|
|
"work_type": sub.work_type.value if hasattr(sub.work_type, 'value') else sub.work_type,
|
|
"content_type": sub.content_type.value if hasattr(sub.content_type, 'value') else sub.content_type,
|
|
"duration_minutes": sub.duration_minutes,
|
|
"duration_seconds": sub.duration_seconds,
|
|
"total_seconds": sub.total_seconds,
|
|
"hours_spent": sub.hours_spent,
|
|
"submit_to": sub.submit_to.value if hasattr(sub.submit_to, 'value') else sub.submit_to,
|
|
"description": sub.description,
|
|
"submit_date": str(sub.submit_date),
|
|
}
|
|
|
|
# 写入修改历史
|
|
history = SubmissionHistory(
|
|
submission_id=sub.id,
|
|
changed_by=current_user.id,
|
|
change_reason=req.change_reason,
|
|
old_data=old_data,
|
|
new_data=new_data,
|
|
)
|
|
db.add(history)
|
|
db.commit()
|
|
db.refresh(sub)
|
|
return submission_to_out(sub)
|
|
|
|
|
|
@router.get("/{submission_id}/history")
|
|
def get_submission_history(
|
|
submission_id: int,
|
|
db: Session = Depends(get_db),
|
|
current_user: User = Depends(require_role(UserRole.OWNER, UserRole.SUPERVISOR, UserRole.LEADER))
|
|
):
|
|
"""查看提交的修改历史"""
|
|
records = db.query(SubmissionHistory).filter(
|
|
SubmissionHistory.submission_id == submission_id
|
|
).order_by(SubmissionHistory.created_at.desc()).all()
|
|
return [
|
|
{
|
|
"id": r.id,
|
|
"changed_by": r.changed_by,
|
|
"change_reason": r.change_reason,
|
|
"old_data": r.old_data,
|
|
"new_data": r.new_data,
|
|
"created_at": r.created_at,
|
|
}
|
|
for r in records
|
|
]
|