Merge remote-tracking branch 'refs/remotes/origin/dev/pjq'

This commit is contained in:
高子兴 2024-11-20 22:11:13 +08:00
commit 924b2864d3
5 changed files with 341 additions and 2 deletions

View File

@ -2,7 +2,7 @@
<module type="PYTHON_MODULE" version="4"> <module type="PYTHON_MODULE" version="4">
<component name="NewModuleRootManager"> <component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" /> <content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" /> <orderEntry type="jdk" jdkName="Python 3.11" jdkType="Python SDK" />
<orderEntry type="sourceFolder" forTests="false" /> <orderEntry type="sourceFolder" forTests="false" />
</component> </component>
</module> </module>

View File

@ -38,5 +38,26 @@
</library> </library>
</libraries> </libraries>
</data-source> </data-source>
<data-source source="LOCAL" name="test [2]" uuid="13832c0f-6caa-4909-a819-f7b92b095c8f">
<driver-ref>sqlite.xerial</driver-ref>
<synchronize>true</synchronize>
<jdbc-driver>org.sqlite.JDBC</jdbc-driver>
<jdbc-url>jdbc:sqlite:C:\Users\15089\PycharmProjects\CostEvalPlatform\test.db</jdbc-url>
<working-dir>$ProjectFileDir$</working-dir>
<libraries>
<library>
<url>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</url>
</library>
<library>
<url>file://$APPLICATION_CONFIG_DIR$/jdbc-drivers/Xerial SQLiteJDBC/3.45.1/org/slf4j/slf4j-api/1.7.36/slf4j-api-1.7.36.jar</url>
</library>
<library>
<url>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</url>
</library>
<library>
<url>file://$APPLICATION_CONFIG_DIR$/jdbc-drivers/Xerial SQLiteJDBC/3.45.1/org/slf4j/slf4j-api/1.7.36/slf4j-api-1.7.36.jar</url>
</library>
</libraries>
</data-source>
</component> </component>
</project> </project>

View File

@ -28,5 +28,5 @@
</profile-state> </profile-state>
</entry> </entry>
</component> </component>
<component name="ProjectRootManager" version="2" project-jdk-name="demo1" project-jdk-type="Python SDK" /> <component name="ProjectRootManager" version="2" project-jdk-name="Python 3.11" project-jdk-type="Python SDK" />
</project> </project>

View File

@ -2,9 +2,188 @@
# @Time : 2024/11/19 下午8:05 # @Time : 2024/11/19 下午8:05
# @FileName: manage_project.py # @FileName: manage_project.py
# @Software: PyCharm # @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 fastapi import APIRouter
from typing import List
router = APIRouter() 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"}

View File

@ -3,6 +3,145 @@
# @FileName: manage_tanant.py # @FileName: manage_tanant.py
# @Software: PyCharm # @Software: PyCharm
from fastapi import APIRouter 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() 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"}