feat: 添加切换租户功能,支持平台用户获取新 token,并优化租户选择逻辑
This commit is contained in:
@@ -25,6 +25,15 @@ const AuthAPI = {
|
||||
});
|
||||
},
|
||||
|
||||
/** 切换租户(平台用户) - 返回新的 token */
|
||||
switchTenant(tenantId: number) {
|
||||
return request<any, LoginResponse>({
|
||||
url: `${AUTH_BASE_URL}/switch-tenant`,
|
||||
method: "post",
|
||||
params: { tenantId },
|
||||
});
|
||||
},
|
||||
|
||||
/** 刷新 token 接口*/
|
||||
refreshToken(refreshToken: string) {
|
||||
return request<any, LoginResponse>({
|
||||
|
||||
@@ -2,6 +2,8 @@ import { store } from "@/store";
|
||||
import TenantAPI from "@/api/system/tenant";
|
||||
import type { TenantInfo } from "@/types/api";
|
||||
import { STORAGE_KEYS } from "@/constants";
|
||||
import AuthAPI from "@/api/auth";
|
||||
import { AuthStorage } from "@/utils/auth";
|
||||
|
||||
/**
|
||||
* 租户 Store
|
||||
@@ -71,7 +73,7 @@ export const useTenantStore = defineStore("tenant", () => {
|
||||
|
||||
// 2. 校验本地恢复的租户是否仍然可用(避免 tenantId 不在列表导致无默认选中)
|
||||
if (
|
||||
currentTenantId.value &&
|
||||
currentTenantId.value != null &&
|
||||
tenantList.value.length > 0 &&
|
||||
!tenantList.value.some((t) => t.id === currentTenantId.value)
|
||||
) {
|
||||
@@ -85,7 +87,7 @@ export const useTenantStore = defineStore("tenant", () => {
|
||||
// 3. 如果已有租户列表,则保证一定有一个默认租户被选中
|
||||
if (tenantList.value.length > 0) {
|
||||
// 3.1 优先后端当前租户
|
||||
if (!currentTenantId.value) {
|
||||
if (currentTenantId.value == null) {
|
||||
try {
|
||||
const currentTenantInfo = await TenantAPI.getCurrentTenant();
|
||||
if (currentTenantInfo) {
|
||||
@@ -98,7 +100,7 @@ export const useTenantStore = defineStore("tenant", () => {
|
||||
}
|
||||
|
||||
// 3.2 本地已有 tenantId,但 currentTenant 为空时,从列表补全 tenantInfo(保持展示名称一致)
|
||||
if (currentTenantId.value && !currentTenant.value) {
|
||||
if (currentTenantId.value != null && !currentTenant.value) {
|
||||
const matched = tenantList.value.find((t) => t.id === currentTenantId.value);
|
||||
if (matched) {
|
||||
setCurrentTenant(matched);
|
||||
@@ -107,7 +109,7 @@ export const useTenantStore = defineStore("tenant", () => {
|
||||
}
|
||||
|
||||
// 3.3 兜底:默认选中第一个(即使有多个租户,也保证 TenantSwitcher 有默认选中)
|
||||
if (!currentTenantId.value) {
|
||||
if (currentTenantId.value == null) {
|
||||
setCurrentTenant(tenantList.value[0]);
|
||||
console.debug("[Tenant] 默认选中第一个租户:", tenantList.value[0].name);
|
||||
}
|
||||
@@ -135,7 +137,17 @@ export const useTenantStore = defineStore("tenant", () => {
|
||||
*/
|
||||
async function switchTenant(tenantId: number): Promise<void> {
|
||||
try {
|
||||
// 调用后端切换接口
|
||||
// 优先使用“切换租户并返回新 token”的接口(平台管理员跨租户切换需要更新 token 的 tenantId)
|
||||
try {
|
||||
const token = await AuthAPI.switchTenant(tenantId);
|
||||
if (token?.accessToken && token?.refreshToken) {
|
||||
AuthStorage.setTokens(token.accessToken, token.refreshToken, AuthStorage.getRememberMe());
|
||||
}
|
||||
} catch {
|
||||
// 忽略:非平台用户或后端未启用该接口时,回退到旧接口
|
||||
}
|
||||
|
||||
// 调用后端切换接口(用于获取当前租户信息/兼容旧逻辑)
|
||||
const tenantInfo = await TenantAPI.switchTenant(tenantId);
|
||||
|
||||
// 后端返回切换后的租户信息
|
||||
|
||||
@@ -109,7 +109,11 @@
|
||||
</div>
|
||||
<template #footer>
|
||||
<el-button @click="tenantDialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" :disabled="!selectedTenantId" @click="handleTenantSelected">
|
||||
<el-button
|
||||
type="primary"
|
||||
:disabled="selectedTenantId == null"
|
||||
@click="handleTenantSelected"
|
||||
>
|
||||
继续
|
||||
</el-button>
|
||||
</template>
|
||||
@@ -268,7 +272,7 @@ async function handleLoginSubmit() {
|
||||
// 需要选择租户
|
||||
tenantStore.setTenantList(error.data);
|
||||
selectedTenantId.value = error.data[0]?.id || null;
|
||||
if (selectedTenantId.value) {
|
||||
if (selectedTenantId.value != null) {
|
||||
tenantStore.currentTenantId = selectedTenantId.value;
|
||||
tenantStore.currentTenant =
|
||||
error.data.find((t: any) => t.id === selectedTenantId.value) || null;
|
||||
@@ -292,7 +296,7 @@ async function handleLoginSubmit() {
|
||||
* 租户选择确认后的处理
|
||||
*/
|
||||
async function handleTenantSelected() {
|
||||
if (!selectedTenantId.value) {
|
||||
if (selectedTenantId.value == null) {
|
||||
ElMessage.warning("请选择租户");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@
|
||||
{{ `v${appConfig.version}` }}
|
||||
</el-tag>
|
||||
<el-tag v-if="tenantEnabled" type="success" size="small" effect="light" round>
|
||||
多租<EFBFBD>?
|
||||
多租户
|
||||
</el-tag>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -137,7 +137,7 @@
|
||||
<el-input
|
||||
v-model="formData.code"
|
||||
placeholder="请输入租户编码"
|
||||
:disabled="!!formData.id"
|
||||
:disabled="formData.id != null && String(formData.id) !== ''"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
@@ -167,11 +167,19 @@
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item v-if="!formData.id" label="管理员账号" prop="adminUsername">
|
||||
<el-form-item
|
||||
v-if="formData.id == null || String(formData.id) === ''"
|
||||
label="管理员账号"
|
||||
prop="adminUsername"
|
||||
>
|
||||
<el-input v-model="formData.adminUsername" placeholder="为空则系统生成" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item v-if="formData.id" label="状态" prop="status">
|
||||
<el-form-item
|
||||
v-if="formData.id != null && String(formData.id) !== ''"
|
||||
label="状态"
|
||||
prop="status"
|
||||
>
|
||||
<el-radio-group v-model="formData.status">
|
||||
<el-radio :value="1">正常</el-radio>
|
||||
<el-radio :value="0">禁用</el-radio>
|
||||
@@ -276,7 +284,7 @@ function handleSelectionChange(selection: any) {
|
||||
|
||||
async function handleOpenDialog(tenantId?: string) {
|
||||
dialog.visible = true;
|
||||
if (tenantId) {
|
||||
if (tenantId != null && tenantId !== "") {
|
||||
dialog.title = "修改租户";
|
||||
const data = await TenantAPI.getFormData(tenantId);
|
||||
Object.assign(formData, data);
|
||||
@@ -325,7 +333,7 @@ const handleSubmit = useDebounceFn(async () => {
|
||||
loading.value = true;
|
||||
try {
|
||||
const tenantId = formData.id;
|
||||
if (tenantId) {
|
||||
if (tenantId != null && String(tenantId) !== "") {
|
||||
const payload: TenantForm = {
|
||||
id: formData.id,
|
||||
name: formData.name,
|
||||
@@ -359,14 +367,14 @@ const handleSubmit = useDebounceFn(async () => {
|
||||
handleCloseDialog();
|
||||
handleResetQuery();
|
||||
} catch {
|
||||
ElMessage.error(formData.id ? "修改失败" : "新增失败");
|
||||
ElMessage.error(formData.id != null && String(formData.id) !== "" ? "修改失败" : "新增失败");
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
}, 300);
|
||||
|
||||
function handleDelete(tenantId?: string) {
|
||||
const tenantIds = tenantId ? tenantId : ids.value.join(",");
|
||||
const tenantIds = tenantId != null && tenantId !== "" ? tenantId : ids.value.join(",");
|
||||
if (!tenantIds) {
|
||||
ElMessage.warning("请勾选删除项");
|
||||
return;
|
||||
@@ -393,7 +401,7 @@ function handleDelete(tenantId?: string) {
|
||||
}
|
||||
|
||||
async function handleChangeStatus(id: string | undefined, status: number) {
|
||||
if (!id) return;
|
||||
if (id == null || id === "") return;
|
||||
try {
|
||||
await TenantAPI.updateStatus(String(id), status);
|
||||
ElMessage.success("状态更新成功");
|
||||
|
||||
Reference in New Issue
Block a user