# -*- coding: utf-8 -*- # @Time : 2024/11/19 下午8:05 # @FileName: manage_project.py # @Software: PyCharm from datetime import datetime from typing import re from fastapi import APIRouter from sqlalchemy import delete from dependencies import * from models import Project, ProjectUserLink router = APIRouter() TenantRole = 1 # 列举所有项目 @router.get("/api/s1/project") async def get_project(response: Response, session: SessionDep, current_user: User = Depends(get_current_user)): # 只有角色为 0、1、2 或 3 的用户才可以访问 if current_user.role == 0: # 角色为0,显示所有项目 projects = session.query(Project).all() elif current_user.role == 1: # 角色为1,显示tenant_id匹配的项目(即属于当前租户的项目) projects = session.query(Project).filter(Project.owner_id == current_user.tenant_id).all() elif current_user.role in [2, 3]: # 角色为2或3,显示与当前用户相关联的项目 projects = ( session.query(Project) .join(ProjectUserLink) .filter(ProjectUserLink.user_id == current_user.id) .all() ) else: raise HTTPException(status_code=403, detail="You do not have permission to view projects.") if not projects: raise HTTPException(status_code=404, detail="Project not found or you have no projects.") # 返回项目的基本信息 return { "projects": [ { "name": project.name, "requirement": project.requirement, "start_time": project.start_time, "deadline": project.deadline } for project in projects ] } # 新增与修改项目 @router.post("/api/s1/project") async def create_project(data: dict, session: SessionDep, current_user: User = Depends(get_current_user)): if current_user.role != 1: raise HTTPException(status_code=403, detail="Only Tenant admin users can add or update projects.") project_id = data.get("project_id") name = data.get("name") requirement = data.get("requirement") start_time_str = data.get("start_time") deadline_str = data.get("deadline") estimators = data.get("estimator") auditors = data.get("auditor") # 验证是否缺少必要参数 if not name or not requirement or not start_time_str or not deadline_str: raise HTTPException(status_code=400, detail="Need more details") # 验证开始时间是否早于结束时间 # 去掉 'Z' 和毫秒部分 start_time_str = start_time_str.split('.')[0].rstrip('Z') deadline_str = deadline_str.split('.')[0].rstrip('Z') start_time = datetime.strptime(start_time_str, "%Y-%m-%dT%H:%M:%S") deadline = datetime.strptime(deadline_str, "%Y-%m-%dT%H:%M:%S") if start_time > deadline: raise HTTPException(status_code=400, detail="Start time must be before deadline") # 验证是否有传入评估/审核员 if not estimators or not auditors: raise HTTPException(status_code=400, detail="Need more estimators or auditors") # 验证评估审核员是否存在 query_estimators = select(User).where(User.username.in_(estimators)) users_estimators = session.exec(query_estimators).all() query_auditors = select(User).where(User.username.in_(auditors)) users_auditors = session.exec(query_auditors).all() # 提取出所有查询到的 existing_estimators = {user.username for user in users_estimators} existing_auditors = {user.username for user in users_auditors} # 验证是否所有的username都存在于数据库中 missing_usernames = (set(auditors) | set(estimators)) - existing_estimators - existing_auditors if missing_usernames: raise HTTPException(status_code=404, detail=f"Missing usernames:{missing_usernames}") # 更新项目还是新增项目 if project_id: # 查找现有项目 project = session.get(Project, project_id) if not project: raise HTTPException(status_code=404, detail="Project not found") # 更新项目内容 project.name = name project.requirement = requirement project.start_time = start_time project.deadline = deadline else: # 新增项目 exist_project = session.exec(select(Project).where(Project.name == name)).first() if exist_project: raise HTTPException(status_code=404, detail="Project already exists") project = Project( name=name, requirement=requirement, start_time=start_time, deadline=deadline, owner_id=current_user.tenant_id, ) session.add(project) # 处理项目和用户的关联 # 先清除现有的关联 # 生成删除语句并执行 stmt = delete(ProjectUserLink).where(ProjectUserLink.project_id == project.id) session.execute(stmt) session.commit() # 提交事务 # 重新建立与评估员和审核员的关系 for username in estimators: user = next((user for user in users_estimators if user.username == username), None) if user: project_user_link = ProjectUserLink(project_id=project.id, user_id=user.id) session.add(project_user_link) for username in auditors: user = next((user for user in users_auditors if user.username == username), None) if user: project_user_link = ProjectUserLink(project_id=project.id, user_id=user.id) session.add(project_user_link) # 提交事务 session.commit() session.refresh(project) return {"message": "Added or updated successfully", "information": project, } # 删除项目 @router.delete("/api/s1/project") async def delete_project(data: dict, session: SessionDep, current_user: User = Depends(get_current_user)): if current_user.role != 1: raise HTTPException(status_code=403, detail="Only Tenant admin users can delete projects.") project_name = data.get("name") if not project_name: raise HTTPException(status_code=400, detail="Project name is required") # 查找项目 project = session.exec( select(Project).where(Project.name == project_name)).first() if not project: raise HTTPException(status_code=404, detail="Project not found") # 删除与项目相关的用户链接 # 先清除现有的关联 stmt = delete(ProjectUserLink).where(ProjectUserLink.project_id == project.id) session.execute(stmt) # 删除项目 session.delete(project) session.commit() return {"detail": "Project deleted successfully"}