From d66b25deb318eeeef1b52b5b1b657a6736749874 Mon Sep 17 00:00:00 2001 From: fit2cloud-chenyw Date: Fri, 17 Oct 2025 14:45:50 +0800 Subject: [PATCH] fix: Unable to switch workspaces after deleting a workspace --- backend/apps/system/api/workspace.py | 12 ++++++++++-- frontend/src/components/layout/Workspace.vue | 8 ++++---- frontend/src/views/system/workspace/index.vue | 10 +++++++++- 3 files changed, 23 insertions(+), 7 deletions(-) diff --git a/backend/apps/system/api/workspace.py b/backend/apps/system/api/workspace.py index 8cd05ac8..8868d456 100644 --- a/backend/apps/system/api/workspace.py +++ b/backend/apps/system/api/workspace.py @@ -1,6 +1,6 @@ from typing import Optional from fastapi import APIRouter, HTTPException, Query -from sqlmodel import exists, or_, select, delete as sqlmodel_delete +from sqlmodel import exists, or_, select, delete as sqlmodel_delete, update as sqlmodel_update 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 @@ -204,13 +204,21 @@ async def get_one(session: SessionDep, trans: Trans, id: int): return db_model @router.delete("/{id}") -async def single_delete(session: SessionDep, id: int): +async def single_delete(session: SessionDep, current_user: CurrentUser, id: int): + if not current_user.isAdmin: + raise HTTPException("only admin can delete workspace") if id == 1: raise HTTPException(f"Can not delete default workspace") db_model = session.get(WorkspaceModel, id) if not db_model: raise HTTPException(f"WorkspaceModel with id {id} not found") + if current_user.oid == id: + current_user.oid = 1 # reset to default workspace + update_stmt = sqlmodel_update(UserModel).where(UserModel.id == current_user.id).values(oid=1) + session.exec(update_stmt) + await clean_user_cache(current_user.id) + user_ws_list = session.exec(select(UserWsModel).where(UserWsModel.oid == id)).all() if user_ws_list: # clean user cache diff --git a/frontend/src/components/layout/Workspace.vue b/frontend/src/components/layout/Workspace.vue index d1a31c6e..861c1aa1 100644 --- a/frontend/src/components/layout/Workspace.vue +++ b/frontend/src/components/layout/Workspace.vue @@ -40,7 +40,7 @@ const formatKeywords = (item: string) => { const emit = defineEmits(['selectWorkspace']) const handleDefaultWorkspaceChange = (item: any) => { - if (item.id.toString() === currentWorkspace.value.id.toString()) { + if (currentWorkspace.value?.id && item.id.toString() === currentWorkspace.value.id.toString()) { return } currentWorkspace.value = { id: item.id, name: item.name } @@ -81,8 +81,8 @@ onMounted(async () => { - {{ - currentWorkspace.name + {{ + currentWorkspace?.name || '' }} @@ -107,7 +107,7 @@ onMounted(async () => { v-for="ele in defaultWorkspaceListWithSearch" :key="ele.name" class="popover-item" - :class="currentWorkspace.id === ele.id && 'isActive'" + :class="currentWorkspace?.id === ele.id && 'isActive'" @click="handleDefaultWorkspaceChange(ele)" > diff --git a/frontend/src/views/system/workspace/index.vue b/frontend/src/views/system/workspace/index.vue index 74884b83..05fcdf92 100644 --- a/frontend/src/views/system/workspace/index.vue +++ b/frontend/src/views/system/workspace/index.vue @@ -25,6 +25,10 @@ import delIcon from '@/assets/svg/icon_delete.svg' import icon_more_outlined from '@/assets/svg/icon_more_outlined.svg' import icon_done_outlined from '@/assets/svg/icon_done_outlined.svg' +import { useUserStore } from '@/stores/user' + +const userStore = useUserStore() + const { t } = useI18n() const multipleSelectionAll = ref([]) const tableList = ref([] as any[]) @@ -259,12 +263,16 @@ const delWorkspace = (row: any) => { customClass: 'confirm-no_icon', autofocus: false, }).then(() => { - workspaceDelete(row.id).then(() => { + workspaceDelete(row.id).then(async () => { ElMessage({ type: 'success', message: t('dashboard.delete_success'), }) init() + if (row.id === userStore.getOid) { + userStore.setOid('1') + await userStore.info() + } }) }) }