index.vue 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. <script setup lang="tsx">
  2. import { onMounted, ref } from 'vue';
  3. import { NButton, NCard, NInput, NSpin, NTag } from 'naive-ui';
  4. import {
  5. fetchClearSwitchTenant,
  6. fetchGetActiveTenants,
  7. fetchGetCurrentSwitchTenant,
  8. fetchSwitchTenant
  9. } from '@/service/api/tenant';
  10. import { useTable } from '@/components/zt/Table/hooks/useTable';
  11. import { $t } from '@/locales';
  12. interface TenantData {
  13. tenantId: number;
  14. tenantCode: string;
  15. tenantDomain: string;
  16. tenantName: string;
  17. packageId: number;
  18. status: number;
  19. expireTime: string;
  20. }
  21. const columns: NaiveUI.TableColumn<any>[] = [
  22. {
  23. key: 'index',
  24. title: $t('common.index'),
  25. align: 'center',
  26. width: 64,
  27. render: (_, index) => index + 1
  28. },
  29. {
  30. key: 'tenantCode',
  31. title: '租户编号',
  32. align: 'center',
  33. minWidth: 120
  34. },
  35. {
  36. key: 'tenantName',
  37. title: '企业名称',
  38. align: 'center',
  39. minWidth: 150
  40. },
  41. {
  42. key: 'tenantDomain',
  43. title: '绑定域名',
  44. align: 'center',
  45. minWidth: 150
  46. },
  47. {
  48. key: 'expireTime',
  49. title: '过期时间',
  50. align: 'center',
  51. minWidth: 170
  52. },
  53. {
  54. key: 'status',
  55. title: '租户状态',
  56. align: 'center',
  57. width: 100,
  58. render: row => {
  59. if (row.status === null || row.status === undefined) {
  60. return null;
  61. }
  62. const tagMap: Record<number, NaiveUI.ThemeColor> = {
  63. 1: 'success',
  64. 0: 'error'
  65. };
  66. const labelMap: Record<number, string> = {
  67. 1: '正常',
  68. 0: '停用'
  69. };
  70. return <NTag type={tagMap[row.status]}>{labelMap[row.status]}</NTag>;
  71. }
  72. }
  73. ];
  74. const [registerTable, { setTableLoading }] = useTable({
  75. searchFormConfig: {
  76. schemas: [],
  77. inline: false,
  78. size: 'small',
  79. labelPlacement: 'left',
  80. isFull: false
  81. },
  82. tableConfig: {
  83. keyField: 'tenantId',
  84. title: '租户列表',
  85. showAddButton: false,
  86. scrollX: 800,
  87. showSearch: false
  88. }
  89. });
  90. // 当前选中的租户
  91. const currentTenant = ref<TenantData | null>(null);
  92. const currentTenantDisplay = ref('');
  93. const loadingCurrentTenant = ref(false);
  94. // 获取当前切换的租户
  95. async function loadCurrentTenant() {
  96. loadingCurrentTenant.value = true;
  97. try {
  98. const { data, error } = await fetchGetCurrentSwitchTenant();
  99. if (!error && data) {
  100. currentTenant.value = data;
  101. currentTenantDisplay.value = data.tenantName || '';
  102. } else {
  103. currentTenant.value = null;
  104. currentTenantDisplay.value = '';
  105. }
  106. } catch (err) {
  107. console.error(err);
  108. currentTenant.value = null;
  109. currentTenantDisplay.value = '';
  110. } finally {
  111. loadingCurrentTenant.value = false;
  112. }
  113. }
  114. // 清除租户切换
  115. async function handleClearTenant() {
  116. try {
  117. const { error } = await fetchClearSwitchTenant();
  118. if (!error) {
  119. currentTenant.value = null;
  120. currentTenantDisplay.value = '';
  121. window.$message?.success('已清除');
  122. }
  123. } catch (err) {
  124. console.error(err);
  125. window.$message?.error('清除失败');
  126. }
  127. }
  128. // 切换租户
  129. async function handleSwitch(row: TenantData) {
  130. setTableLoading(true);
  131. try {
  132. const { error } = await fetchSwitchTenant(row.tenantCode);
  133. if (!error) {
  134. window.$message?.success('切换成功');
  135. await loadCurrentTenant();
  136. }
  137. } catch (err) {
  138. console.error(err);
  139. window.$message?.error('切换失败');
  140. } finally {
  141. setTableLoading(false);
  142. }
  143. }
  144. onMounted(() => {
  145. loadCurrentTenant();
  146. });
  147. </script>
  148. <template>
  149. <LayoutTable>
  150. <NCard size="small" class="mb-16px">
  151. <div class="flex items-center gap-12px">
  152. <span class="whitespace-nowrap text-14px">当前租户:</span>
  153. <NSpin :show="loadingCurrentTenant" size="small" class="w-300px">
  154. <NInput
  155. :value="currentTenantDisplay"
  156. placeholder="暂未选择租户"
  157. readonly
  158. clearable
  159. @clear="handleClearTenant"
  160. />
  161. </NSpin>
  162. </div>
  163. </NCard>
  164. <ZTable :columns="columns as any" :api="fetchGetActiveTenants" @register="registerTable">
  165. <template #op="{ row }">
  166. <NButton size="small" ghost type="primary" @click="handleSwitch(row)">切换</NButton>
  167. </template>
  168. </ZTable>
  169. </LayoutTable>
  170. </template>
  171. <style scoped></style>