Răsfoiți Sursa

1. 取代头像使用用户名显示;2. 完成租户切换功能;3. 调整对话框标题的样式

Shinohara Haruna 6 luni în urmă
părinte
comite
e11b8926e6

+ 5 - 0
smsb-plus-ui/src/assets/styles/element-ui.scss

@@ -85,6 +85,11 @@
         border-bottom: 1px solid var(--brder-color);
         margin-right: 0;
       }
+      .el-dialog__title {
+        display: inline-block;
+        position: relative;
+        top: -8px;
+      }
     }
   }
 }

+ 122 - 16
smsb-plus-ui/src/layout/components/Navbar.vue

@@ -10,13 +10,39 @@
     <div class="navbar-right">
       <div class="right-menu flex align-center">
         <template v-if="appStore.device !== 'mobile'">
-          <el-select v-if="userId === 1 && tenantEnabled" v-model="companyName" class="min-w-244px" clearable filterable
-            reserve-keyword :placeholder="$t('navbar.selectTenant')" @change="dynamicTenantEvent"
-            @clear="dynamicClearEvent">
-            <el-option v-for="item in tenantList" :key="item.tenantId" :label="item.companyName" :value="item.tenantId">
-            </el-option>
-            <template #prefix><svg-icon icon-class="company" class="el-input__icon input-icon" /></template>
-          </el-select>
+          <span v-if="userId === 1 && tenantEnabled && companyName" class="navbar-tenant-name" @click="openTenantDialog"
+            style="cursor: pointer; display: inline-block; margin-right: 12px; color: #fff; font-size: 15px">
+            <svg-icon icon-class="company" style="margin-right: 4px; vertical-align: middle" />
+            <span style="vertical-align: middle">{{
+              tenantList.find((t) => String(t.tenantId) === String(companyName))?.companyName || companyName
+              }}</span>
+            <el-icon style="margin-left: 2px; vertical-align: middle"><caret-bottom /></el-icon>
+          </span>
+          <el-dialog v-model="showTenantDialog" :title="$t('navbar.selectTenant')" width="800px" append-to-body>
+            <el-table :data="tenantList" style="width: 100%; margin-bottom: 12px" height="320"
+              @row-click="handleRadioSelect"
+              :row-class-name="({ row }) => (String(row.tenantId) === String(selectedTenantId) ? 'is-selected' : '')"
+              v-loading="tenantLoading" element-loading-text="加载租户列表中...">
+              <el-table-column label="租户编号" width="120" align="center">
+                <template #default="scope">
+                  <span style="display: flex; align-items: center; gap: 6px">
+                    <el-radio :model-value="selectedTenantId" :label="String(scope.row.tenantId)"
+                      style="margin-left: 4px" :disabled="false" />
+                    <!-- {{ scope.row.tenantId }} -->
+                  </span>
+                </template>
+              </el-table-column>
+              <el-table-column prop="companyName" label="企业名称" min-width="200" />
+              <el-table-column prop="licenseNumber" label="社会信用代码" min-width="180" />
+              <el-table-column prop="contactUserName" label="联系人" min-width="100" />
+              <el-table-column prop="contactPhone" label="联系电话" min-width="120" />
+            </el-table>
+            <div style="text-align: right">
+              <el-button @click="showTenantDialog = false">取消</el-button>
+              <el-button type="primary" :disabled="!selectedTenantId || selectedTenantId === companyName"
+                @click="confirmSelectTenant">确定</el-button>
+            </div>
+          </el-dialog>
 
           <!-- <header-search id="header-search" class="right-menu-item" /> -->
           <search-menu ref="searchMenuRef" />
@@ -34,12 +60,12 @@
                   <svg-icon icon-class="message" />
                 </el-badge>
               </template>
-              <template #default>
+<template #default>
                 <notice></notice>
               </template>
-            </el-popover>
-          </div>
-        </el-tooltip> -->
+</el-popover>
+</div>
+</el-tooltip> -->
           <!--        <el-tooltip content="Github" effect="dark" placement="bottom">
           <ruo-yi-git id="ruoyi-git" class="right-menu-item hover-effect" />
         </el-tooltip>
@@ -62,9 +88,19 @@
         </template>
         <div class="avatar-container">
           <el-dropdown class="right-menu-item hover-effect" trigger="click" @command="handleCommand">
-            <div class="avatar-wrapper">
-              <img :src="userStore.avatar" class="user-avatar" />
-              <el-icon><caret-bottom /></el-icon>
+            <div class="avatar-wrapper" style="margin-top: -20px">
+              <span class="menu-title" style="
+                  max-width: 120px;
+                  display: inline-block;
+                  vertical-align: middle;
+                  overflow: hidden;
+                  text-overflow: ellipsis;
+                  white-space: nowrap;
+                  color: #fff;
+                  font-size: 16px;
+                  margin-left: 1rem;
+                ">{{ userStore.nickname }}</span>
+              <el-icon style="vertical-align: middle"><caret-bottom /></el-icon>
             </div>
             <template #dropdown>
               <el-dropdown-menu>
@@ -87,6 +123,7 @@
 </template>
 
 <script setup lang="ts">
+import { ref } from 'vue';
 import SearchMenu from './TopBar/search.vue';
 import useAppStore from '@/store/modules/app';
 import useUserStore from '@/store/modules/user';
@@ -106,8 +143,76 @@ const newNotice = ref(<number>0);
 const { proxy } = getCurrentInstance() as ComponentInternalInstance;
 
 const userId = ref(userStore.userId);
-const companyName = ref(undefined);
+import { listTenant } from '@/api/system/tenant';
+
+const companyName = ref('');
 const tenantList = ref<TenantVO[]>([]);
+const showTenantDialog = ref(false);
+const selectedTenantId = ref('');
+const tenantLoading = ref(false);
+
+async function openTenantDialog() {
+  tenantLoading.value = true;
+  showTenantDialog.value = true;
+  try {
+    // 尝试用undefined作为参数
+    const resp = await listTenant(undefined);
+    console.log('listTenant full response:', resp);
+    tenantList.value = (resp.rows || []).map((item) => ({
+      ...item,
+      tenantId: String(item.tenantId)
+    }));
+  } catch (e) {
+    console.error('listTenant failed', e);
+    tenantList.value = [];
+  } finally {
+    tenantLoading.value = false;
+  }
+}
+
+watch(companyName, (val) => {
+  console.log('companyName changed:', val);
+});
+watch(tenantList, (val) => {
+  console.log('tenantList changed:', val);
+  console.log('tenantList full:', JSON.stringify(val, null, 2));
+  if (!companyName.value && val.length > 0) {
+    // 优先根据用户的tenantId决定
+    const userTenantId = String(userStore.tenantId);
+    const match = val.find((t) => String(t.tenantId) === userTenantId);
+    if (match) {
+      companyName.value = userTenantId;
+      console.log('companyName set by userStore.tenantId:', companyName.value);
+    } else {
+      companyName.value = String(val[0].tenantId);
+      console.log('companyName fallback to first:', companyName.value);
+    }
+  }
+  // 每次租户列表变化时,默认高亮当前companyName
+  selectedTenantId.value = String(companyName.value);
+});
+
+onMounted(() => {
+  console.log('onMounted companyName:', companyName.value);
+  console.log('onMounted tenantList:', tenantList.value);
+  console.log('onMounted tenantList full:', JSON.stringify(tenantList.value, null, 2));
+});
+
+function handleRadioSelect(row: any) {
+  if (row) {
+    selectedTenantId.value = String(row.tenantId);
+    console.log('selectedTenantId changed:', selectedTenantId.value);
+  }
+}
+
+function confirmSelectTenant() {
+  if (selectedTenantId.value && companyName.value !== selectedTenantId.value) {
+    dynamicTenantEvent(selectedTenantId.value);
+  }
+  showTenantDialog.value = false;
+}
+
+console.log('navbar render', companyName.value, tenantList.value);
 // 是否切换了租户
 const dynamic = ref(false);
 // 租户开关
@@ -123,6 +228,7 @@ const openSearchMenu = () => {
 const dynamicTenantEvent = async (tenantId: string) => {
   if (companyName.value != null && companyName.value !== '') {
     await dynamicTenant(tenantId);
+    companyName.value = tenantId; // 立即同步UI
     dynamic.value = true;
     proxy?.$tab.closeAllPage();
     proxy?.$router.push('/');
@@ -290,7 +396,7 @@ watch(
           cursor: pointer;
           position: absolute;
           right: -20px;
-          top: 25px;
+          top: 4px;
           font-size: 12px;
         }
       }