Skip to content

Commit 499a939

Browse files
perf: Workspace api
1 parent 89171a9 commit 499a939

File tree

6 files changed

+102
-14
lines changed

6 files changed

+102
-14
lines changed

backend/apps/system/api/workspace.py

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
from typing import Optional
22
from fastapi import APIRouter, HTTPException, Query
3-
from sqlmodel import exists, or_, select
3+
from sqlmodel import exists, or_, select, delete as sqlmodel_delete
4+
from apps.system.crud.user import clean_user_cache
5+
from apps.system.crud.workspace import reset_single_user_oid, reset_user_oid
46
from apps.system.models.system_model import UserWsModel, WorkspaceBase, WorkspaceEditor, WorkspaceModel
57
from apps.system.models.user import UserModel
68
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
118120
})
119121
for uid in creator.uid_list
120122
]
123+
for uid in creator.uid_list:
124+
await reset_single_user_oid(session, uid, oid)
125+
await clean_user_cache(uid)
126+
121127
session.add_all(db_model_list)
122128
session.commit()
123129

124130
@router.put("/uws")
125131
async def edit(session: SessionDep, editor: UserWsEditor):
126132
if not editor.oid or not editor.uid:
127-
raise RuntimeError("param [oid, uid] miss")
133+
raise HTTPException("param [oid, uid] miss")
128134
db_model = session.exec(select(UserWsModel).where(UserWsModel.uid == editor.uid, UserWsModel.oid == editor.oid)).first()
129135
if not db_model:
130-
raise RuntimeError("uws not exist")
136+
raise HTTPException("uws not exist")
131137
if editor.weight == db_model.weight:
132138
return
133139

134140
db_model.weight = editor.weight
135141
session.add(db_model)
142+
143+
await clean_user_cache(editor.uid)
136144
session.commit()
137145

138146
@router.delete("/uws")
@@ -145,6 +153,11 @@ async def delete(session: SessionDep, current_user: CurrentUser, dto: UserWsBase
145153
raise HTTPException(f"UserWsModel not found")
146154
for db_model in db_model_list:
147155
session.delete(db_model)
156+
157+
for uid in dto.uid_list:
158+
await reset_single_user_oid(session, uid, oid, False)
159+
await clean_user_cache(uid)
160+
148161
session.commit()
149162

150163
@router.get("", response_model=list[WorkspaceModel])
@@ -167,7 +180,7 @@ async def update(session: SessionDep, editor: WorkspaceEditor):
167180
id = editor.id
168181
db_model = session.get(WorkspaceModel, id)
169182
if not db_model:
170-
raise ValueError(f"WorkspaceModel with id {id} not found")
183+
raise HTTPException(f"WorkspaceModel with id {id} not found")
171184
update_data = WorkspaceModel.model_validate(editor)
172185
db_model.sqlmodel_update(update_data)
173186
session.add(db_model)
@@ -177,16 +190,27 @@ async def update(session: SessionDep, editor: WorkspaceEditor):
177190
async def get_one(session: SessionDep, trans: Trans, id: int):
178191
db_model = session.get(WorkspaceModel, id)
179192
if not db_model:
180-
raise ValueError(f"WorkspaceModel with id {id} not found")
193+
raise HTTPException(f"WorkspaceModel with id {id} not found")
181194
if db_model.name.startswith('i18n'):
182195
db_model.name = trans(db_model.name)
183196
return db_model
184197

185198
@router.delete("/{id}")
186-
async def delete(session: SessionDep, id: int):
199+
async def single_delete(session: SessionDep, id: int):
187200
db_model = session.get(WorkspaceModel, id)
188201
if not db_model:
189-
raise ValueError(f"WorkspaceModel with id {id} not found")
202+
raise HTTPException(f"WorkspaceModel with id {id} not found")
203+
204+
user_ws_list = session.exec(select(UserWsModel).where(UserWsModel.oid == id)).all()
205+
if user_ws_list:
206+
# clean user cache
207+
for user_ws in user_ws_list:
208+
await clean_user_cache(user_ws.uid)
209+
# reset user default oid
210+
await reset_user_oid(session, id)
211+
# delete user_ws
212+
session.exec(sqlmodel_delete(UserWsModel).where(UserWsModel.oid == id))
213+
190214
session.delete(db_model)
191215
session.commit()
192216

backend/apps/system/crud/user.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11

22
from typing import Optional
33
from sqlmodel import Session, select, delete as sqlmodel_delete
4-
4+
import logging
55
from apps.system.models.system_model import UserWsModel, WorkspaceModel
66
from apps.system.schemas.auth import CacheName, CacheNamespace
77
from apps.system.schemas.system_schema import BaseUserDTO, UserInfoDTO, UserWs
@@ -64,4 +64,8 @@ async def single_delete(session: SessionDep, id: int):
6464
del_stmt = sqlmodel_delete(UserWsModel).where(UserWsModel.uid == id)
6565
session.exec(del_stmt)
6666
session.delete(user_model)
67-
session.commit()
67+
session.commit()
68+
69+
@clear_cache(namespace=CacheNamespace.AUTH_INFO, cacheName=CacheName.USER_INFO, keyExpression="id")
70+
async def clean_user_cache(id: int):
71+
logging.info(f"User cache for [{id}] has been cleaned")
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
2+
from typing import Optional
3+
from sqlmodel import Session, func, select, update
4+
5+
from apps.system.models.system_model import UserWsModel
6+
from apps.system.models.user import UserModel
7+
8+
async def reset_single_user_oid(session: Session, uid: int, oid: int, add: Optional[bool] = True):
9+
user_model = session.get(UserModel, uid)
10+
if not user_model:
11+
return
12+
origin_oid = user_model.oid
13+
if add and (not origin_oid or origin_oid == 0):
14+
user_model.oid = oid
15+
session.add(user_model)
16+
if not add and origin_oid and origin_oid == oid:
17+
user_model.oid = 0
18+
user_ws = session.exec(select(UserWsModel).where(UserWsModel.uid == uid, UserWsModel.oid != oid)).first()
19+
if user_ws:
20+
user_model.oid = user_ws.oid
21+
session.add(user_model)
22+
23+
async def reset_user_oid(session: Session, oid: int):
24+
stmt = (
25+
select(
26+
UserModel.id,
27+
UserModel.oid,
28+
func.coalesce(
29+
func.array_remove(
30+
func.array_agg(UserWsModel.oid),
31+
None
32+
),
33+
[]
34+
).label("oid_list")
35+
)
36+
.join(UserWsModel, UserModel.id == UserWsModel.uid, isouter=True)
37+
.where(UserModel.id != 1)
38+
.group_by(UserModel.id)
39+
)
40+
41+
user_filter = (
42+
select(UserModel.id)
43+
.join(UserWsModel, UserModel.id == UserWsModel.uid)
44+
.where(UserWsModel.oid == oid)
45+
.distinct()
46+
)
47+
stmt = stmt.where(UserModel.id.in_(user_filter))
48+
49+
result_user_list = session.exec(stmt)
50+
for row in result_user_list:
51+
result_dict = {}
52+
for item, key in zip(row, row._fields):
53+
result_dict[key] = item
54+
55+
origin_oid = result_dict['oid']
56+
oid_list: list = list(filter(lambda x: x != oid, result_dict['oid_list']))
57+
if origin_oid not in oid_list:
58+
result_dict['oid'] = oid_list[0] if oid_list else 0
59+
if result_dict['oid'] != origin_oid:
60+
result_dict.pop("oid_list", None)
61+
update_stmt = update(UserModel).where(UserModel.id == result_dict['id']).values(oid=result_dict['oid'])
62+
session.exec(update_stmt)

backend/common/core/pagination.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ def _process_result_row(self, row: Row) -> Dict[str, Any]:
1414
result_dict = {}
1515
for item, key in zip(row, row._fields):
1616
if isinstance(item, SQLModel):
17-
result_dict.update(item.dict())
17+
result_dict.update(item.model_dump())
1818
else:
1919
result_dict[key] = item
2020

frontend/src/api/workspace.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,6 @@ export const workspaceUwsUpdate = (data: any) => request.put('/system/workspace/
1111
export const workspaceCreate = (data: any) => request.post('/system/workspace', data)
1212
export const workspaceUpdate = (data: any) => request.put('/system/workspace', data)
1313
export const workspaceUwsDelete = (data: any) => request.delete('/system/workspace/uws', { data })
14-
export const workspaceDelete = (data: any) => request.delete('/system/workspace', { data })
14+
export const workspaceDelete = (id: any) => request.delete(`/system/workspace/${id}`)
1515
export const workspaceList = () => request.get('/system/workspace')
1616
export const workspaceDetail = (id: any) => request.get(`/system/workspace/${id}`)

frontend/src/views/system/workspace/index.vue

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -236,9 +236,7 @@ const delWorkspace = (row: any) => {
236236
customClass: 'confirm-no_icon',
237237
autofocus: false,
238238
}).then(() => {
239-
workspaceDelete({
240-
id: row.id,
241-
}).then(() => {
239+
workspaceDelete(row.id).then(() => {
242240
ElMessage({
243241
type: 'success',
244242
message: t('dashboard.delete_success'),

0 commit comments

Comments
 (0)