perf: Workspace api

This commit is contained in:
fit2cloud-chenyw
2025-07-17 13:41:33 +08:00
parent 89171a9758
commit 499a939326
6 changed files with 102 additions and 14 deletions
+31 -7
View File
@@ -1,6 +1,8 @@
from typing import Optional
from fastapi import APIRouter, HTTPException, Query
from sqlmodel import exists, or_, select
from sqlmodel import exists, or_, select, delete as sqlmodel_delete
from apps.system.crud.user import clean_user_cache
from apps.system.crud.workspace import reset_single_user_oid, reset_user_oid
from apps.system.models.system_model import UserWsModel, WorkspaceBase, WorkspaceEditor, WorkspaceModel
from apps.system.models.user import UserModel
from apps.system.schemas.system_schema import UserWsBase, UserWsDTO, UserWsEditor, UserWsOption, WorkspaceUser
@@ -118,21 +120,27 @@ async def create(session: SessionDep, current_user: CurrentUser, creator: UserWs
})
for uid in creator.uid_list
]
for uid in creator.uid_list:
await reset_single_user_oid(session, uid, oid)
await clean_user_cache(uid)
session.add_all(db_model_list)
session.commit()
@router.put("/uws")
async def edit(session: SessionDep, editor: UserWsEditor):
if not editor.oid or not editor.uid:
raise RuntimeError("param [oid, uid] miss")
raise HTTPException("param [oid, uid] miss")
db_model = session.exec(select(UserWsModel).where(UserWsModel.uid == editor.uid, UserWsModel.oid == editor.oid)).first()
if not db_model:
raise RuntimeError("uws not exist")
raise HTTPException("uws not exist")
if editor.weight == db_model.weight:
return
db_model.weight = editor.weight
session.add(db_model)
await clean_user_cache(editor.uid)
session.commit()
@router.delete("/uws")
@@ -145,6 +153,11 @@ async def delete(session: SessionDep, current_user: CurrentUser, dto: UserWsBase
raise HTTPException(f"UserWsModel not found")
for db_model in db_model_list:
session.delete(db_model)
for uid in dto.uid_list:
await reset_single_user_oid(session, uid, oid, False)
await clean_user_cache(uid)
session.commit()
@router.get("", response_model=list[WorkspaceModel])
@@ -167,7 +180,7 @@ async def update(session: SessionDep, editor: WorkspaceEditor):
id = editor.id
db_model = session.get(WorkspaceModel, id)
if not db_model:
raise ValueError(f"WorkspaceModel with id {id} not found")
raise HTTPException(f"WorkspaceModel with id {id} not found")
update_data = WorkspaceModel.model_validate(editor)
db_model.sqlmodel_update(update_data)
session.add(db_model)
@@ -177,16 +190,27 @@ async def update(session: SessionDep, editor: WorkspaceEditor):
async def get_one(session: SessionDep, trans: Trans, id: int):
db_model = session.get(WorkspaceModel, id)
if not db_model:
raise ValueError(f"WorkspaceModel with id {id} not found")
raise HTTPException(f"WorkspaceModel with id {id} not found")
if db_model.name.startswith('i18n'):
db_model.name = trans(db_model.name)
return db_model
@router.delete("/{id}")
async def delete(session: SessionDep, id: int):
async def single_delete(session: SessionDep, id: int):
db_model = session.get(WorkspaceModel, id)
if not db_model:
raise ValueError(f"WorkspaceModel with id {id} not found")
raise HTTPException(f"WorkspaceModel with id {id} not found")
user_ws_list = session.exec(select(UserWsModel).where(UserWsModel.oid == id)).all()
if user_ws_list:
# clean user cache
for user_ws in user_ws_list:
await clean_user_cache(user_ws.uid)
# reset user default oid
await reset_user_oid(session, id)
# delete user_ws
session.exec(sqlmodel_delete(UserWsModel).where(UserWsModel.oid == id))
session.delete(db_model)
session.commit()
+6 -2
View File
@@ -1,7 +1,7 @@
from typing import Optional
from sqlmodel import Session, select, delete as sqlmodel_delete
import logging
from apps.system.models.system_model import UserWsModel, WorkspaceModel
from apps.system.schemas.auth import CacheName, CacheNamespace
from apps.system.schemas.system_schema import BaseUserDTO, UserInfoDTO, UserWs
@@ -64,4 +64,8 @@ async def single_delete(session: SessionDep, id: int):
del_stmt = sqlmodel_delete(UserWsModel).where(UserWsModel.uid == id)
session.exec(del_stmt)
session.delete(user_model)
session.commit()
session.commit()
@clear_cache(namespace=CacheNamespace.AUTH_INFO, cacheName=CacheName.USER_INFO, keyExpression="id")
async def clean_user_cache(id: int):
logging.info(f"User cache for [{id}] has been cleaned")
+62
View File
@@ -0,0 +1,62 @@
from typing import Optional
from sqlmodel import Session, func, select, update
from apps.system.models.system_model import UserWsModel
from apps.system.models.user import UserModel
async def reset_single_user_oid(session: Session, uid: int, oid: int, add: Optional[bool] = True):
user_model = session.get(UserModel, uid)
if not user_model:
return
origin_oid = user_model.oid
if add and (not origin_oid or origin_oid == 0):
user_model.oid = oid
session.add(user_model)
if not add and origin_oid and origin_oid == oid:
user_model.oid = 0
user_ws = session.exec(select(UserWsModel).where(UserWsModel.uid == uid, UserWsModel.oid != oid)).first()
if user_ws:
user_model.oid = user_ws.oid
session.add(user_model)
async def reset_user_oid(session: Session, oid: int):
stmt = (
select(
UserModel.id,
UserModel.oid,
func.coalesce(
func.array_remove(
func.array_agg(UserWsModel.oid),
None
),
[]
).label("oid_list")
)
.join(UserWsModel, UserModel.id == UserWsModel.uid, isouter=True)
.where(UserModel.id != 1)
.group_by(UserModel.id)
)
user_filter = (
select(UserModel.id)
.join(UserWsModel, UserModel.id == UserWsModel.uid)
.where(UserWsModel.oid == oid)
.distinct()
)
stmt = stmt.where(UserModel.id.in_(user_filter))
result_user_list = session.exec(stmt)
for row in result_user_list:
result_dict = {}
for item, key in zip(row, row._fields):
result_dict[key] = item
origin_oid = result_dict['oid']
oid_list: list = list(filter(lambda x: x != oid, result_dict['oid_list']))
if origin_oid not in oid_list:
result_dict['oid'] = oid_list[0] if oid_list else 0
if result_dict['oid'] != origin_oid:
result_dict.pop("oid_list", None)
update_stmt = update(UserModel).where(UserModel.id == result_dict['id']).values(oid=result_dict['oid'])
session.exec(update_stmt)
+1 -1
View File
@@ -14,7 +14,7 @@ class Paginator:
result_dict = {}
for item, key in zip(row, row._fields):
if isinstance(item, SQLModel):
result_dict.update(item.dict())
result_dict.update(item.model_dump())
else:
result_dict[key] = item
+1 -1
View File
@@ -11,6 +11,6 @@ export const workspaceUwsUpdate = (data: any) => request.put('/system/workspace/
export const workspaceCreate = (data: any) => request.post('/system/workspace', data)
export const workspaceUpdate = (data: any) => request.put('/system/workspace', data)
export const workspaceUwsDelete = (data: any) => request.delete('/system/workspace/uws', { data })
export const workspaceDelete = (data: any) => request.delete('/system/workspace', { data })
export const workspaceDelete = (id: any) => request.delete(`/system/workspace/${id}`)
export const workspaceList = () => request.get('/system/workspace')
export const workspaceDetail = (id: any) => request.get(`/system/workspace/${id}`)
@@ -236,9 +236,7 @@ const delWorkspace = (row: any) => {
customClass: 'confirm-no_icon',
autofocus: false,
}).then(() => {
workspaceDelete({
id: row.id,
}).then(() => {
workspaceDelete(row.id).then(() => {
ElMessage({
type: 'success',
message: t('dashboard.delete_success'),