|
|
@@ -0,0 +1,181 @@
|
|
|
+<script setup lang="tsx">
|
|
|
+import { onMounted, ref } from 'vue';
|
|
|
+import { NButton, NCard, NInput, NSpin, NTag } from 'naive-ui';
|
|
|
+import {
|
|
|
+ fetchClearSwitchTenant,
|
|
|
+ fetchGetActiveTenants,
|
|
|
+ fetchGetCurrentSwitchTenant,
|
|
|
+ fetchSwitchTenant
|
|
|
+} from '@/service/api/tenant';
|
|
|
+import { useTable } from '@/components/zt/Table/hooks/useTable';
|
|
|
+import { $t } from '@/locales';
|
|
|
+
|
|
|
+interface TenantData {
|
|
|
+ tenantId: number;
|
|
|
+ tenantCode: string;
|
|
|
+ tenantDomain: string;
|
|
|
+ tenantName: string;
|
|
|
+ packageId: number;
|
|
|
+ status: number;
|
|
|
+ expireTime: string;
|
|
|
+}
|
|
|
+
|
|
|
+const columns: NaiveUI.TableColumn<any>[] = [
|
|
|
+ {
|
|
|
+ key: 'index',
|
|
|
+ title: $t('common.index'),
|
|
|
+ align: 'center',
|
|
|
+ width: 64,
|
|
|
+ render: (_, index) => index + 1
|
|
|
+ },
|
|
|
+ {
|
|
|
+ key: 'tenantCode',
|
|
|
+ title: '租户编号',
|
|
|
+ align: 'center',
|
|
|
+ minWidth: 120
|
|
|
+ },
|
|
|
+ {
|
|
|
+ key: 'tenantName',
|
|
|
+ title: '企业名称',
|
|
|
+ align: 'center',
|
|
|
+ minWidth: 150
|
|
|
+ },
|
|
|
+ {
|
|
|
+ key: 'tenantDomain',
|
|
|
+ title: '绑定域名',
|
|
|
+ align: 'center',
|
|
|
+ minWidth: 150
|
|
|
+ },
|
|
|
+ {
|
|
|
+ key: 'expireTime',
|
|
|
+ title: '过期时间',
|
|
|
+ align: 'center',
|
|
|
+ minWidth: 170
|
|
|
+ },
|
|
|
+ {
|
|
|
+ key: 'status',
|
|
|
+ title: '租户状态',
|
|
|
+ align: 'center',
|
|
|
+ width: 100,
|
|
|
+ render: row => {
|
|
|
+ if (row.status === null || row.status === undefined) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ const tagMap: Record<number, NaiveUI.ThemeColor> = {
|
|
|
+ 1: 'success',
|
|
|
+ 0: 'error'
|
|
|
+ };
|
|
|
+ const labelMap: Record<number, string> = {
|
|
|
+ 1: '正常',
|
|
|
+ 0: '停用'
|
|
|
+ };
|
|
|
+ return <NTag type={tagMap[row.status]}>{labelMap[row.status]}</NTag>;
|
|
|
+ }
|
|
|
+ }
|
|
|
+];
|
|
|
+
|
|
|
+const [registerTable, { setTableLoading }] = useTable({
|
|
|
+ searchFormConfig: {
|
|
|
+ schemas: [],
|
|
|
+ inline: false,
|
|
|
+ size: 'small',
|
|
|
+ labelPlacement: 'left',
|
|
|
+ isFull: false
|
|
|
+ },
|
|
|
+ tableConfig: {
|
|
|
+ keyField: 'tenantId',
|
|
|
+ title: '租户列表',
|
|
|
+ showAddButton: false,
|
|
|
+ scrollX: 800,
|
|
|
+ showSearch: false
|
|
|
+ }
|
|
|
+});
|
|
|
+
|
|
|
+// 当前选中的租户
|
|
|
+const currentTenant = ref<TenantData | null>(null);
|
|
|
+const currentTenantDisplay = ref('');
|
|
|
+const loadingCurrentTenant = ref(false);
|
|
|
+
|
|
|
+// 获取当前切换的租户
|
|
|
+async function loadCurrentTenant() {
|
|
|
+ loadingCurrentTenant.value = true;
|
|
|
+ try {
|
|
|
+ const { data, error } = await fetchGetCurrentSwitchTenant();
|
|
|
+ if (!error && data) {
|
|
|
+ currentTenant.value = data;
|
|
|
+ currentTenantDisplay.value = data.tenantName || '';
|
|
|
+ } else {
|
|
|
+ currentTenant.value = null;
|
|
|
+ currentTenantDisplay.value = '';
|
|
|
+ }
|
|
|
+ } catch (err) {
|
|
|
+ console.error(err);
|
|
|
+ currentTenant.value = null;
|
|
|
+ currentTenantDisplay.value = '';
|
|
|
+ } finally {
|
|
|
+ loadingCurrentTenant.value = false;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// 清除租户切换
|
|
|
+async function handleClearTenant() {
|
|
|
+ try {
|
|
|
+ const { error } = await fetchClearSwitchTenant();
|
|
|
+ if (!error) {
|
|
|
+ currentTenant.value = null;
|
|
|
+ currentTenantDisplay.value = '';
|
|
|
+ window.$message?.success('已清除');
|
|
|
+ }
|
|
|
+ } catch (err) {
|
|
|
+ console.error(err);
|
|
|
+ window.$message?.error('清除失败');
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// 切换租户
|
|
|
+async function handleSwitch(row: TenantData) {
|
|
|
+ setTableLoading(true);
|
|
|
+ try {
|
|
|
+ const { error } = await fetchSwitchTenant(row.tenantCode);
|
|
|
+ if (!error) {
|
|
|
+ window.$message?.success('切换成功');
|
|
|
+ await loadCurrentTenant();
|
|
|
+ }
|
|
|
+ } catch (err) {
|
|
|
+ console.error(err);
|
|
|
+ window.$message?.error('切换失败');
|
|
|
+ } finally {
|
|
|
+ setTableLoading(false);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+onMounted(() => {
|
|
|
+ loadCurrentTenant();
|
|
|
+});
|
|
|
+</script>
|
|
|
+
|
|
|
+<template>
|
|
|
+ <LayoutTable>
|
|
|
+ <NCard size="small" class="mb-16px">
|
|
|
+ <div class="flex items-center gap-12px">
|
|
|
+ <span class="whitespace-nowrap text-14px">当前租户:</span>
|
|
|
+ <NSpin :show="loadingCurrentTenant" size="small" class="w-300px">
|
|
|
+ <NInput
|
|
|
+ :value="currentTenantDisplay"
|
|
|
+ placeholder="暂未选择租户"
|
|
|
+ readonly
|
|
|
+ clearable
|
|
|
+ @clear="handleClearTenant"
|
|
|
+ />
|
|
|
+ </NSpin>
|
|
|
+ </div>
|
|
|
+ </NCard>
|
|
|
+ <ZTable :columns="columns as any" :api="fetchGetActiveTenants" @register="registerTable">
|
|
|
+ <template #op="{ row }">
|
|
|
+ <NButton size="small" ghost type="primary" @click="handleSwitch(row)">切换</NButton>
|
|
|
+ </template>
|
|
|
+ </ZTable>
|
|
|
+ </LayoutTable>
|
|
|
+</template>
|
|
|
+
|
|
|
+<style scoped></style>
|