fix(core): 统一错误处理机制并增强租户管理员角色权限控制
- 移除页面中手动 message.error 调用,统一由拦截器处理 - 在 http 拦截器中实现后端错误消息自动展示 - 添加对业务错误码(code != 0)的处理逻辑 - 完善 HTTP 状态码错误(4xx, 5xx)的处理 - 增强 RoleController 中租户管理员角色的越权保护 - 在角色权限绑定页面添加平台管理员模式检查 - 限制非平台管理员修改 TENANT_ADMIN 角色权限的能力 - 清理调试用的 console.log 输出master
parent
0530605839
commit
bf7439b200
|
|
@ -101,6 +101,18 @@ public class RoleController {
|
||||||
|
|
||||||
// 权限越权校验
|
// 权限越权校验
|
||||||
Long currentTenantId = getCurrentTenantId();
|
Long currentTenantId = getCurrentTenantId();
|
||||||
|
SysRole targetRole = sysRoleService.getById(id);
|
||||||
|
if (targetRole == null) {
|
||||||
|
return ApiResponse.error("角色不存在");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 关键校验:只有平台管理员可以修改 TENANT_ADMIN 角色的权限
|
||||||
|
if ("TENANT_ADMIN".equalsIgnoreCase(targetRole.getRoleCode())) {
|
||||||
|
if (!Long.valueOf(0).equals(currentTenantId)) {
|
||||||
|
return ApiResponse.error("租户管理员角色的权限只能由平台管理员修改");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!Long.valueOf(0).equals(currentTenantId)) {
|
if (!Long.valueOf(0).equals(currentTenantId)) {
|
||||||
List<com.imeeting.entity.SysPermission> myPerms = sysPermissionService.listByUserId(getCurrentUserId(), currentTenantId);
|
List<com.imeeting.entity.SysPermission> myPerms = sysPermissionService.listByUserId(getCurrentUserId(), currentTenantId);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
|
import { message } from "antd";
|
||||||
|
|
||||||
const http = axios.create({
|
const http = axios.create({
|
||||||
baseURL: "",
|
baseURL: "",
|
||||||
|
|
@ -17,8 +18,11 @@ http.interceptors.request.use((config) => {
|
||||||
http.interceptors.response.use(
|
http.interceptors.response.use(
|
||||||
(resp) => {
|
(resp) => {
|
||||||
const body = resp.data;
|
const body = resp.data;
|
||||||
|
// 如果返回的 code 不是 0,表示业务错误
|
||||||
if (body && body.code !== "0") {
|
if (body && body.code !== "0") {
|
||||||
const err = new Error(body.msg || "请求失败");
|
const errorMsg = body.msg || "请求失败";
|
||||||
|
message.error(errorMsg); // 自动展示后端错误消息
|
||||||
|
const err = new Error(errorMsg);
|
||||||
(err as any).code = body.code;
|
(err as any).code = body.code;
|
||||||
(err as any).msg = body.msg;
|
(err as any).msg = body.msg;
|
||||||
return Promise.reject(err);
|
return Promise.reject(err);
|
||||||
|
|
@ -26,17 +30,21 @@ http.interceptors.response.use(
|
||||||
return resp;
|
return resp;
|
||||||
},
|
},
|
||||||
(error) => {
|
(error) => {
|
||||||
|
// 处理 HTTP 状态码错误 (4xx, 5xx)
|
||||||
if (error.response && (error.response.status === 401 || error.response.status === 403)) {
|
if (error.response && (error.response.status === 401 || error.response.status === 403)) {
|
||||||
// Clear session/local storage
|
|
||||||
localStorage.removeItem("accessToken");
|
localStorage.removeItem("accessToken");
|
||||||
localStorage.removeItem("refreshToken");
|
localStorage.removeItem("refreshToken");
|
||||||
sessionStorage.removeItem("userProfile");
|
sessionStorage.removeItem("userProfile");
|
||||||
// Force redirect to login with timeout flag
|
|
||||||
window.location.href = "/login?timeout=1";
|
window.location.href = "/login?timeout=1";
|
||||||
|
return Promise.reject(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process backend error message if available in response body even for non-200 status
|
|
||||||
const body = error.response?.data;
|
const body = error.response?.data;
|
||||||
|
const errorMsg = body?.msg || error.message || "网络异常";
|
||||||
|
|
||||||
|
// 防止重复弹出相同的提示(可选逻辑,根据需要调整)
|
||||||
|
message.error(errorMsg);
|
||||||
|
|
||||||
if (body && body.msg) {
|
if (body && body.msg) {
|
||||||
const err = new Error(body.msg);
|
const err = new Error(body.msg);
|
||||||
(err as any).code = body.code;
|
(err as any).code = body.code;
|
||||||
|
|
|
||||||
|
|
@ -74,7 +74,6 @@ export function usePermission() {
|
||||||
if (isAdmin) return true;
|
if (isAdmin) return true;
|
||||||
|
|
||||||
if (!codes || codes.length === 0) {
|
if (!codes || codes.length === 0) {
|
||||||
console.log(`Permission check for [${perm}]: codes is empty, returning true`);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -87,8 +86,6 @@ export function usePermission() {
|
||||||
} else {
|
} else {
|
||||||
result = !hasButtonCodes || codes.includes(perm);
|
result = !hasButtonCodes || codes.includes(perm);
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(`Permission check for [${perm}]: result=[${result}], hasMenuCodes=[${hasMenuCodes}], hasButtonCodes=[${hasButtonCodes}]`);
|
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@ export default function Devices() {
|
||||||
setData(deviceList || []);
|
setData(deviceList || []);
|
||||||
setUsers(usersList || []);
|
setUsers(usersList || []);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
message.error(t('common.error'));
|
// Handled by interceptor
|
||||||
} finally {
|
} finally {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
}
|
}
|
||||||
|
|
@ -113,7 +113,7 @@ export default function Devices() {
|
||||||
setOpen(false);
|
setOpen(false);
|
||||||
loadData();
|
loadData();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (e instanceof Error && e.message) message.error(e.message);
|
// Handled by interceptor
|
||||||
} finally {
|
} finally {
|
||||||
setSaving(false);
|
setSaving(false);
|
||||||
}
|
}
|
||||||
|
|
@ -125,7 +125,7 @@ export default function Devices() {
|
||||||
message.success(t('common.success'));
|
message.success(t('common.success'));
|
||||||
loadData();
|
loadData();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
message.error(t('common.error'));
|
// Handled by interceptor
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,9 +25,9 @@ export default function Login() {
|
||||||
const data = await fetchCaptcha();
|
const data = await fetchCaptcha();
|
||||||
setCaptcha(data);
|
setCaptcha(data);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
message.error(t('common.error'));
|
// Handled by interceptor
|
||||||
}
|
}
|
||||||
}, [captchaEnabled, t]);
|
}, [captchaEnabled]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const init = async () => {
|
const init = async () => {
|
||||||
|
|
@ -91,7 +91,6 @@ export default function Login() {
|
||||||
message.success(t('common.success'));
|
message.success(t('common.success'));
|
||||||
window.location.href = "/";
|
window.location.href = "/";
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
message.error(e.message || t('common.error'));
|
|
||||||
if (captchaEnabled) {
|
if (captchaEnabled) {
|
||||||
loadCaptcha();
|
loadCaptcha();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -93,7 +93,7 @@ export default function Orgs() {
|
||||||
setSelectedTenantId(list[0].id);
|
setSelectedTenantId(list[0].id);
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
message.error(t('common.error'));
|
// Handled by interceptor
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -104,7 +104,7 @@ export default function Orgs() {
|
||||||
const list = await listOrgs(selectedTenantId);
|
const list = await listOrgs(selectedTenantId);
|
||||||
setData(list || []);
|
setData(list || []);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
message.error(t('common.error'));
|
// Handled by interceptor
|
||||||
} finally {
|
} finally {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
}
|
}
|
||||||
|
|
@ -148,7 +148,7 @@ export default function Orgs() {
|
||||||
message.success(t('common.success'));
|
message.success(t('common.success'));
|
||||||
loadOrgs();
|
loadOrgs();
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
message.error(e.message || t('common.error'));
|
// Handled by interceptor
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -166,7 +166,7 @@ export default function Orgs() {
|
||||||
setDrawerOpen(false);
|
setDrawerOpen(false);
|
||||||
loadOrgs();
|
loadOrgs();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (e instanceof Error && e.message) message.error(e.message);
|
// Handled by interceptor
|
||||||
} finally {
|
} finally {
|
||||||
setSaving(false);
|
setSaving(false);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -161,7 +161,7 @@ export default function Permissions() {
|
||||||
setOpen(false);
|
setOpen(false);
|
||||||
load();
|
load();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (e instanceof Error && e.message) message.error(e.message);
|
// Handled by interceptor
|
||||||
} finally {
|
} finally {
|
||||||
setSaving(false);
|
setSaving(false);
|
||||||
}
|
}
|
||||||
|
|
@ -173,7 +173,7 @@ export default function Permissions() {
|
||||||
message.success(t('common.success'));
|
message.success(t('common.success'));
|
||||||
load();
|
load();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
message.error(t('common.error'));
|
// Handled by interceptor
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@ export default function PlatformSettings() {
|
||||||
const data = await getAdminPlatformConfig();
|
const data = await getAdminPlatformConfig();
|
||||||
form.setFieldsValue(data);
|
form.setFieldsValue(data);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
message.error(t('common.error'));
|
// Handled by interceptor
|
||||||
} finally {
|
} finally {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
}
|
}
|
||||||
|
|
@ -53,7 +53,7 @@ export default function PlatformSettings() {
|
||||||
form.setFieldValue(fieldName, url);
|
form.setFieldValue(fieldName, url);
|
||||||
message.success(t('common.success'));
|
message.success(t('common.success'));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
message.error(t('common.error'));
|
// Handled by interceptor
|
||||||
}
|
}
|
||||||
return false; // 阻止自动上传
|
return false; // 阻止自动上传
|
||||||
};
|
};
|
||||||
|
|
@ -64,7 +64,7 @@ export default function PlatformSettings() {
|
||||||
await updatePlatformConfig(values);
|
await updatePlatformConfig(values);
|
||||||
message.success(t('common.success'));
|
message.success(t('common.success'));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
message.error(t('common.error'));
|
// Handled by interceptor
|
||||||
} finally {
|
} finally {
|
||||||
setSaving(false);
|
setSaving(false);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -74,6 +74,16 @@ export default function RolePermissionBinding() {
|
||||||
const [saving, setSaving] = useState(false);
|
const [saving, setSaving] = useState(false);
|
||||||
const [selectedRoleId, setSelectedRoleId] = useState<number | null>(null);
|
const [selectedRoleId, setSelectedRoleId] = useState<number | null>(null);
|
||||||
|
|
||||||
|
// Platform admin check
|
||||||
|
const isPlatformMode = useMemo(() => {
|
||||||
|
const profileStr = sessionStorage.getItem("userProfile");
|
||||||
|
if (profileStr) {
|
||||||
|
const profile = JSON.parse(profileStr);
|
||||||
|
return profile.isPlatformAdmin && localStorage.getItem("activeTenantId") === "0";
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}, []);
|
||||||
|
|
||||||
// Selection states
|
// Selection states
|
||||||
const [checkedPermIds, setCheckedPermIds] = useState<number[]>([]);
|
const [checkedPermIds, setCheckedPermIds] = useState<number[]>([]);
|
||||||
const [halfCheckedIds, setHalfCheckedIds] = useState<number[]>([]);
|
const [halfCheckedIds, setHalfCheckedIds] = useState<number[]>([]);
|
||||||
|
|
@ -102,7 +112,7 @@ export default function RolePermissionBinding() {
|
||||||
const list = await listPermissions();
|
const list = await listPermissions();
|
||||||
setPermissions(list || []);
|
setPermissions(list || []);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
message.error(t('common.error'));
|
// Handled by interceptor
|
||||||
} finally {
|
} finally {
|
||||||
setLoadingPerms(false);
|
setLoadingPerms(false);
|
||||||
}
|
}
|
||||||
|
|
@ -121,7 +131,6 @@ export default function RolePermissionBinding() {
|
||||||
setHalfCheckedIds([]);
|
setHalfCheckedIds([]);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
setCheckedPermIds([]);
|
setCheckedPermIds([]);
|
||||||
message.error(t('common.error'));
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -161,7 +170,7 @@ export default function RolePermissionBinding() {
|
||||||
await saveRolePermissions(selectedRoleId, allPermIds);
|
await saveRolePermissions(selectedRoleId, allPermIds);
|
||||||
message.success(t('common.success'));
|
message.success(t('common.success'));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
message.error(t('common.error'));
|
// Handled by interceptor
|
||||||
} finally {
|
} finally {
|
||||||
setSaving(false);
|
setSaving(false);
|
||||||
}
|
}
|
||||||
|
|
@ -179,7 +188,7 @@ export default function RolePermissionBinding() {
|
||||||
icon={<SaveOutlined aria-hidden="true" />}
|
icon={<SaveOutlined aria-hidden="true" />}
|
||||||
onClick={handleSave}
|
onClick={handleSave}
|
||||||
loading={saving}
|
loading={saving}
|
||||||
disabled={!selectedRoleId}
|
disabled={!selectedRoleId || (selectedRole?.roleCode === 'TENANT_ADMIN' && !isPlatformMode)}
|
||||||
>
|
>
|
||||||
{saving ? t('common.loading') : t('rolePerm.savePolicy')}
|
{saving ? t('common.loading') : t('rolePerm.savePolicy')}
|
||||||
</Button>
|
</Button>
|
||||||
|
|
@ -261,7 +270,7 @@ export default function RolePermissionBinding() {
|
||||||
onCheck={(keys, info) => {
|
onCheck={(keys, info) => {
|
||||||
const checked = Array.isArray(keys) ? keys : keys.checked;
|
const checked = Array.isArray(keys) ? keys : keys.checked;
|
||||||
const halfChecked = info.halfCheckedKeys || [];
|
const halfChecked = info.halfCheckedKeys || [];
|
||||||
setSelectedPermIds(checked.map(k => Number(k)));
|
setCheckedPermIds(checked.map(k => Number(k)));
|
||||||
setHalfCheckedIds(halfChecked.map(k => Number(k)));
|
setHalfCheckedIds(halfChecked.map(k => Number(k)));
|
||||||
}}
|
}}
|
||||||
defaultExpandAll
|
defaultExpandAll
|
||||||
|
|
|
||||||
|
|
@ -182,7 +182,7 @@ export default function Roles() {
|
||||||
setUserModalOpen(false);
|
setUserModalOpen(false);
|
||||||
selectRole(selectedRole);
|
selectRole(selectedRole);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
message.error(t('common.error'));
|
// Handled by interceptor
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -193,7 +193,7 @@ export default function Roles() {
|
||||||
message.success(t('common.success'));
|
message.success(t('common.success'));
|
||||||
selectRole(selectedRole);
|
selectRole(selectedRole);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
message.error(t('common.error'));
|
// Handled by interceptor
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -259,7 +259,7 @@ export default function Roles() {
|
||||||
const users = await fetchUsersByRoleId(role.roleId);
|
const users = await fetchUsersByRoleId(role.roleId);
|
||||||
setRoleUsers(users || []);
|
setRoleUsers(users || []);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
message.error(t('common.error'));
|
// Handled by interceptor
|
||||||
} finally {
|
} finally {
|
||||||
setLoadingUsers(false);
|
setLoadingUsers(false);
|
||||||
}
|
}
|
||||||
|
|
@ -315,7 +315,7 @@ export default function Roles() {
|
||||||
if (selectedRole?.roleId === id) setSelectedRole(null);
|
if (selectedRole?.roleId === id) setSelectedRole(null);
|
||||||
loadRoles();
|
loadRoles();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
message.error(t('common.error'));
|
// Handled by interceptor
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -342,7 +342,7 @@ export default function Roles() {
|
||||||
setDrawerOpen(false);
|
setDrawerOpen(false);
|
||||||
loadRoles();
|
loadRoles();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (e instanceof Error && e.message) message.error(e.message);
|
// Handled by interceptor
|
||||||
} finally {
|
} finally {
|
||||||
setSaving(false);
|
setSaving(false);
|
||||||
}
|
}
|
||||||
|
|
@ -356,7 +356,7 @@ export default function Roles() {
|
||||||
await saveRolePermissions(selectedRole.roleId, allPermIds);
|
await saveRolePermissions(selectedRole.roleId, allPermIds);
|
||||||
message.success(t('common.success'));
|
message.success(t('common.success'));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
message.error(t('common.error'));
|
// Handled by interceptor
|
||||||
} finally {
|
} finally {
|
||||||
setSaving(false);
|
setSaving(false);
|
||||||
}
|
}
|
||||||
|
|
@ -473,7 +473,7 @@ export default function Roles() {
|
||||||
icon={<SaveOutlined aria-hidden="true" />}
|
icon={<SaveOutlined aria-hidden="true" />}
|
||||||
loading={saving}
|
loading={saving}
|
||||||
onClick={savePermissions}
|
onClick={savePermissions}
|
||||||
disabled={!can("sys:role:permission:save")}
|
disabled={!can("sys:role:permission:save") || (selectedRole.roleCode === 'TENANT_ADMIN' && !isPlatformMode)}
|
||||||
>
|
>
|
||||||
{t('roles.savePerms')}
|
{t('roles.savePerms')}
|
||||||
</Button>
|
</Button>
|
||||||
|
|
|
||||||
|
|
@ -64,12 +64,10 @@ export default function SysParams() {
|
||||||
const res = await pageParams(query);
|
const res = await pageParams(query);
|
||||||
setData(res.records || []);
|
setData(res.records || []);
|
||||||
setTotal(res.total || 0);
|
setTotal(res.total || 0);
|
||||||
} catch (e) {
|
|
||||||
message.error(t('common.error'));
|
|
||||||
} finally {
|
} finally {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
}
|
}
|
||||||
}, [queryParams, t]);
|
}, [queryParams]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
loadData();
|
loadData();
|
||||||
|
|
@ -109,7 +107,7 @@ export default function SysParams() {
|
||||||
message.success(t('common.success'));
|
message.success(t('common.success'));
|
||||||
loadData();
|
loadData();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
message.error(t('common.error'));
|
// Handled by global interceptor
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -59,8 +59,6 @@ export default function Tenants() {
|
||||||
const result = await listTenants(currentParams);
|
const result = await listTenants(currentParams);
|
||||||
setData(result.records || []);
|
setData(result.records || []);
|
||||||
setTotal(result.total || 0);
|
setTotal(result.total || 0);
|
||||||
} catch (e) {
|
|
||||||
message.error(t('common.error'));
|
|
||||||
} finally {
|
} finally {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
}
|
}
|
||||||
|
|
@ -108,7 +106,7 @@ export default function Tenants() {
|
||||||
message.success(t('common.success'));
|
message.success(t('common.success'));
|
||||||
loadData();
|
loadData();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
message.error(t('common.error'));
|
// Handled by interceptor
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -131,7 +129,7 @@ export default function Tenants() {
|
||||||
setDrawerOpen(false);
|
setDrawerOpen(false);
|
||||||
loadData();
|
loadData();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (e instanceof Error && e.message) message.error(e.message);
|
// Handled by interceptor
|
||||||
} finally {
|
} finally {
|
||||||
setSaving(false);
|
setSaving(false);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -64,7 +64,6 @@ export default function UserRoleBinding() {
|
||||||
setCheckedRoleIds(list || []);
|
setCheckedRoleIds(list || []);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
setCheckedRoleIds([]);
|
setCheckedRoleIds([]);
|
||||||
message.error(t('common.error'));
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -100,7 +99,7 @@ export default function UserRoleBinding() {
|
||||||
await saveUserRoles(selectedUserId, checkedRoleIds);
|
await saveUserRoles(selectedUserId, checkedRoleIds);
|
||||||
message.success(t('common.success'));
|
message.success(t('common.success'));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
message.error(t('common.error'));
|
// Handled by global interceptor
|
||||||
} finally {
|
} finally {
|
||||||
setSaving(false);
|
setSaving(false);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -145,7 +145,7 @@ export default function Users() {
|
||||||
setTenants(tenantsResp.records || []);
|
setTenants(tenantsResp.records || []);
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
message.error(t('common.error'));
|
// Handled by interceptor
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -230,7 +230,7 @@ export default function Users() {
|
||||||
});
|
});
|
||||||
setDrawerOpen(true);
|
setDrawerOpen(true);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
message.error(t('common.error'));
|
// Handled by interceptor
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -240,7 +240,7 @@ export default function Users() {
|
||||||
message.success(t('common.success'));
|
message.success(t('common.success'));
|
||||||
loadUsersData();
|
loadUsersData();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
message.error(t('common.error'));
|
// Handled by interceptor
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -287,7 +287,7 @@ export default function Users() {
|
||||||
setDrawerOpen(false);
|
setDrawerOpen(false);
|
||||||
loadUsersData();
|
loadUsersData();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (e instanceof Error && e.message) message.error(e.message);
|
// Handled by interceptor
|
||||||
} finally {
|
} finally {
|
||||||
setSaving(false);
|
setSaving(false);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue