diff --git a/.idea/CostEvalPlatform.iml b/.idea/CostEvalPlatform.iml
index d0876a7..909438d 100644
--- a/.idea/CostEvalPlatform.iml
+++ b/.idea/CostEvalPlatform.iml
@@ -2,7 +2,7 @@
-
+
\ No newline at end of file
diff --git a/.idea/dataSources.xml b/.idea/dataSources.xml
index 11cdf89..1de88be 100644
--- a/.idea/dataSources.xml
+++ b/.idea/dataSources.xml
@@ -38,5 +38,26 @@
+
+ sqlite.xerial
+ true
+ org.sqlite.JDBC
+ jdbc:sqlite:C:\Users\15089\PycharmProjects\CostEvalPlatform\test.db
+ $ProjectFileDir$
+
+
+ file://$APPLICATION_CONFIG_DIR$/jdbc-drivers/Xerial SQLiteJDBC/3.45.1/org/xerial/sqlite-jdbc/3.45.1.0/sqlite-jdbc-3.45.1.0.jar
+
+
+ file://$APPLICATION_CONFIG_DIR$/jdbc-drivers/Xerial SQLiteJDBC/3.45.1/org/slf4j/slf4j-api/1.7.36/slf4j-api-1.7.36.jar
+
+
+ file://$APPLICATION_CONFIG_DIR$/jdbc-drivers/Xerial SQLiteJDBC/3.45.1/org/xerial/sqlite-jdbc/3.45.1.0/sqlite-jdbc-3.45.1.0.jar
+
+
+ file://$APPLICATION_CONFIG_DIR$/jdbc-drivers/Xerial SQLiteJDBC/3.45.1/org/slf4j/slf4j-api/1.7.36/slf4j-api-1.7.36.jar
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
index 63337c1..2f33712 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -28,5 +28,5 @@
-
+
\ No newline at end of file
diff --git a/api/manage_project.py b/api/manage_project.py
index c6426f6..804faa4 100644
--- a/api/manage_project.py
+++ b/api/manage_project.py
@@ -2,9 +2,188 @@
# @Time : 2024/11/19 下午8:05
# @FileName: manage_project.py
# @Software: PyCharm
+from fastapi import HTTPException, Response, Depends, APIRouter
+from typing import Optional, Annotated
+from datetime import datetime, timedelta
+from jose import JWTError, jwt
+from sqlalchemy import delete
+
+from sqlmodel import select
+
+from models import Tenant, User, Project, ProjectUserLink
+from dependencies import *
from fastapi import APIRouter
+from typing import List
+
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["name"]
+ requirement = data["requirement"]
+ start_time_str = data["start_time"]
+ deadline_str = data["deadline"]
+ estimators = data["estimators"]
+ auditors = data["auditors"]
+
+ # 验证是否缺少必要参数
+ if not name or not requirement or not start_time_str or not deadline_str:
+ raise HTTPException(status_code=400, detail="Need more name/requirement/start_time/deadline")
+
+ # 验证开始时间是否早于结束时间
+ 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")
+
+ # 验证评估审核员是否存在
+ 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()
+ print(exist_project) # 测试用
+ 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=1 # 假设owner_id是1,之后应该是通过token获取owner_id吧
+ )
+ session.add(project)
+
+ # 处理项目和用户的关联
+ # 先清除现有的关联
+ # 生成删除语句并执行
+ print(project_id) # 测试用
+ 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 current_user.role != 1:
+ # raise HTTPException(status_code=403, detail="Only admin users can delete projects")
+
+ 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"}
diff --git a/api/manage_tanant.py b/api/manage_tanant.py
index 04404e9..ad4240b 100644
--- a/api/manage_tanant.py
+++ b/api/manage_tanant.py
@@ -3,6 +3,145 @@
# @FileName: manage_tanant.py
# @Software: PyCharm
from fastapi import APIRouter
+from fastapi import HTTPException, Response, Depends, APIRouter
+from typing import Optional, Annotated
+from datetime import datetime, timedelta
+from jose import JWTError, jwt
+from sqlalchemy import delete
+
+from sqlmodel import select
+
+from models import Tenant, User, Project
+from dependencies import *
router = APIRouter()
+from fastapi import HTTPException, Response
+from sqlalchemy.orm import Session
+from models import Tenant, User # 假设你已导入 Tenant 和 User 模型
+from dependencies import SessionDep # 假设 SessionDep 是数据库会话的依赖
+
+#列举所有租户
+@router.get("/api/s1/tenant")
+async def get_tenant(response: Response, session: SessionDep, current_user: User = Depends(get_current_user)):
+
+ if current_user.role != 0:
+ raise HTTPException(status_code=403, detail="Only Superadmin can list all tenants.")
+
+ tenants = session.query(Tenant).all() # 获取所有租户
+ if not tenants:
+ raise HTTPException(status_code=404, detail="No tenants found")
+
+ tenant_data = []
+ for tenant in tenants:
+ # 获取该租户中 role=1 的第一个用户(如果存在)
+ tenant_user = next((user for user in tenant.users if user.role == 1), None)
+
+ # 获取该租户中除了 role=1 以外的用户数量
+ user_num = len([user for user in tenant.users if user.role != 1])
+
+ # 构建租户信息
+ tenant_info = {
+ "name": tenant.name,
+ "username": tenant_user.username if tenant_user else None, # 如果找到 role=1 的用户,返回其 username
+ "user_num": user_num # 除去 role=1 的用户数量
+ }
+
+ tenant_data.append(tenant_info)
+
+ return {"tenants": tenant_data}
+
+# 新增和修改租户
+@router.post("/api/s1/tenant")
+async def create_or_update_tenant(data: dict, session: SessionDep, current_user: User = Depends(get_current_user)):
+ if current_user.role != 0:
+ raise HTTPException(status_code=403, detail="Only Superadmin can add or update tenants.")
+
+ name = data.get("name")
+ username = data.get("username")
+ password = data.get("password")
+
+ # 验证是否缺少必要参数
+ if not name:
+ raise HTTPException(status_code=400, detail="Need more name")
+
+ if username:
+ # 如果 username 不为空,判断为新建租户
+ # 检查租户名是否已存在
+ tenant_query = select(Tenant).where(Tenant.name == name)
+ existing_tenant = session.exec(tenant_query).first()
+
+ if existing_tenant:
+ raise HTTPException(status_code=409, detail="Tenant name already exists")
+
+ # 创建新租户
+ tenant = Tenant(name=name)
+ session.add(tenant)
+ session.commit()
+ session.refresh(tenant)
+
+ # 创建新用户
+ user = User(
+ username=username,
+ password=password, # 记得加密密码
+ role=1, # 默认role为1
+ tenant_id=tenant.id,
+ )
+ session.add(user)
+
+ # 提交事务
+ session.commit()
+
+ return {"message": "Tenant and User added successfully"}
+
+ else:
+ # 如果 username 为空,执行更新操作
+ # 根据租户名称查找 Tenant
+ tenant_query = select(Tenant).where(Tenant.name == name)
+ tenant = session.exec(tenant_query).first()
+
+ # 如果找不到对应的租户,抛出错误
+ if not tenant:
+ raise HTTPException(status_code=404, detail="Tenant not found")
+
+ # 找到租户后,根据 tenant_id 查找该租户下的所有用户
+ user_query = select(User).where(User.tenant_id == tenant.id)
+
+ user = session.exec(user_query).first()
+
+ #如果找不到对应的用户,抛出错误
+ if not user:
+ raise HTTPException(status_code=404, detail="User not found")
+ user.password = password
+ session.add(user)
+ session.commit()
+ print(user) #测试用
+ return {"message": "Tenant and User update successfully"}
+
+#删除租户
+@router.delete("/api/s1/tenant")
+async def delete_tenant(data: dict, session: SessionDep, current_user: User = Depends(get_current_user)):
+
+ if current_user.role != 0:
+ raise HTTPException(status_code=403, detail="Only Superadmin can delete tenants.")
+
+ tenant_name = data.get("name")
+
+ if not tenant_name:
+ raise HTTPException(status_code=400, detail="Tenant name is required")
+
+ # 查找租户
+ tenant = session.exec(
+ select(Tenant).where(Tenant.name == tenant_name)).first()
+ if not tenant:
+ raise HTTPException(status_code=404, detail="Tenant not found")
+
+ # 删除与租户相关的用户
+ stmt = delete(User).where(User.tenant_id == tenant.id)
+ session.execute(stmt)
+
+ # 删除租户
+ session.delete(tenant)
+ session.commit()
+
+ return {"detail": "Tenant deleted successfully"}
\ No newline at end of file