Prechádzať zdrojové kódy

feat(frontend): 侧栏菜单提示卡片化并调整分组标题与菜单字号

cc 2 dní pred
rodič
commit
d9e0821504

+ 30 - 19
ai-electron/frontend/src/core/components/SimpleMenu/src/SimpleSubMenu.vue

@@ -1,25 +1,32 @@
 <template>
-  <!-- forceExpanded 由 SimpleMenu 逐级透传到 SubMenu -->
-  <MenuItem
-    :name="item.path"
+  <!-- forceExpanded 由 SimpleMenu 逐级透传 -->
+  <Tooltip
     v-if="!menuHasChildren(item) && getShowMenu"
-    v-bind="$props"
-    :class="getLevelClass"
-    :style="`color: ${getColor}`"
-    :title="getI18nName"
-    :item="getMenuItem"
+    placement="right"
+    :overlayClassName="`${menuPrefixCls}-tooltip-overlay`"
+    :mouseEnterDelay="0.3"
   >
-    <Icon v-if="getIcon" :icon="getIcon" :size="15" />
-    <div v-if="collapsedShowTitle && getIsCollapseParent" class="collapse-title mt-1">
-      {{ getI18nName }}
-    </div>
-    <template #title>
-      <span :class="['ml-2', `${prefixCls}-sub-title`]">
+    <template #title>{{ getI18nName }}</template>
+    <MenuItem
+      :name="item.path"
+      v-bind="$props"
+      :class="getLevelClass"
+      :style="`color: ${getColor}`"
+      :data-menu-title="getI18nName"
+      :item="getMenuItem"
+    >
+      <Icon v-if="getIcon" :icon="getIcon" :size="15" />
+      <div v-if="collapsedShowTitle && getIsCollapseParent" class="collapse-title mt-1">
         {{ getI18nName }}
-      </span>
-      <SimpleMenuTag :item="item" :collapseParent="getIsCollapseParent" />
-    </template>
-  </MenuItem>
+      </div>
+      <template #title>
+        <span :class="['ml-2', `${prefixCls}-sub-title`]">
+          {{ getI18nName }}
+        </span>
+        <SimpleMenuTag :item="item" :collapseParent="getIsCollapseParent" />
+      </template>
+    </MenuItem>
+  </Tooltip>
   <SubMenu
     :name="item.path"
     v-if="menuHasChildren(item) && getShowMenu"
@@ -28,7 +35,7 @@
     :collapse="collapse"
     :forceExpanded="forceExpanded"
     :style="`color: ${getColor}`"
-    :title="getI18nName"
+    :data-menu-title="getI18nName"
   >
     <template #title>
       <Icon v-if="getIcon" :icon="getIcon" :size="15" />
@@ -59,6 +66,7 @@
   import { propTypes } from '@/core/utils/propTypes';
   import { useI18n } from '@/core/hooks/web/useI18n';
   import SimpleMenuTag from './SimpleMenuTag.vue';
+  import { Tooltip } from 'ant-design-vue';
   import { omit } from 'lodash-es';
 
   const props = {
@@ -80,11 +88,13 @@
       MenuItem,
       SimpleMenuTag,
       Icon,
+      Tooltip,
     },
     props,
     setup(props) {
       const { t } = useI18n();
       const { prefixCls } = useDesign('simple-menu');
+      const { prefixCls: menuPrefixCls } = useDesign('menu');
 
       const getShowMenu = computed(() => !props.item?.meta?.hideMenu);
       const getIcon = computed(() => props.item?.icon);
@@ -115,6 +125,7 @@
 
       return {
         prefixCls,
+        menuPrefixCls,
         menuHasChildren,
         getShowMenu,
         getIcon,

+ 1 - 1
ai-electron/frontend/src/core/components/SimpleMenu/src/components/MenuItem.vue

@@ -1,6 +1,6 @@
 <template>
   <li :class="getClass" @click.stop="handleClickItem" :style="getCollapse ? {} : getItemStyle">
-    <Tooltip placement="right" v-if="showTooptip">
+    <Tooltip placement="right" v-if="showTooptip" :overlayClassName="`${prefixCls}-tooltip-overlay`">
       <template #title>
         <slot name="title"></slot>
       </template>

+ 29 - 0
ai-electron/frontend/src/core/components/SimpleMenu/src/components/menu.less

@@ -344,3 +344,32 @@
 }
 
 /* 菜单密度:与 36px 顶栏配套的行高见上方 item/submenu-title padding(44 → 34) */
+
+/* 菜单项提示:白底卡片,和项目浅色主题一致。
+   选择器带 body 前缀,覆盖 antd 运行时注入的同名 Tooltip 样式 */
+body .ant-tooltip.jeesite-menu-tooltip-overlay {
+  --antd-arrow-background-color: #fff;
+
+  .ant-tooltip-inner {
+    min-width: 0;
+    min-height: 0;
+    padding: 5px 10px;
+    color: #1f2a44;
+    font-size: 12px;
+    font-weight: 500;
+    line-height: 18px;
+    background: #fff;
+    border-radius: 8px;
+    box-shadow:
+      0 8px 24px rgba(15, 23, 42, 0.12),
+      0 0 0 1px #e7ebf3;
+  }
+
+  .jeesite-simple-menu-sub-title {
+    margin-left: 0 !important;
+    color: inherit;
+    font-size: inherit;
+    font-weight: inherit;
+    line-height: inherit;
+  }
+}

+ 29 - 29
ai-electron/frontend/src/core/layouts/default/sider/LayoutSider.vue

@@ -172,33 +172,33 @@
       position: relative;
     }
 
-    /* 分组标题:跟随当前菜单结构,菜单标题调整时需同步 */
-    .jeesite-simple-menu > li[title='案件数据'],
-    .jeesite-simple-menu > li[title='通信分析'],
-    .jeesite-simple-menu > li[title='交易分析'],
-    .jeesite-simple-menu > li[title='活动轨迹分析'],
-    .jeesite-simple-menu > li[title='行为时空分析'] {
+    /* 分组标题:跟随当前菜单结构,data-menu-title 调整时需同步 */
+    .jeesite-simple-menu > li[data-menu-title='案件数据'],
+    .jeesite-simple-menu > li[data-menu-title='通信分析'],
+    .jeesite-simple-menu > li[data-menu-title='交易分析'],
+    .jeesite-simple-menu > li[data-menu-title='活动轨迹分析'],
+    .jeesite-simple-menu > li[data-menu-title='行为时空分析'] {
       margin-top: 34px;
     }
 
     /* 叶子项默认 overflow:hidden 会裁掉分组标题 */
-    .jeesite-simple-menu > li[title='案件数据'],
-    .jeesite-simple-menu > li[title='行为时空分析'] {
+    .jeesite-simple-menu > li[data-menu-title='案件数据'],
+    .jeesite-simple-menu > li[data-menu-title='行为时空分析'] {
       overflow: visible;
     }
 
     /* 有子项的分组只保留分组标题,父级行不再显示 */
-    .jeesite-menu-submenu[title='通信分析'] > .jeesite-menu-submenu-title,
-    .jeesite-menu-submenu[title='交易分析'] > .jeesite-menu-submenu-title,
-    .jeesite-menu-submenu[title='活动轨迹分析'] > .jeesite-menu-submenu-title {
+    .jeesite-menu-submenu[data-menu-title='通信分析'] > .jeesite-menu-submenu-title,
+    .jeesite-menu-submenu[data-menu-title='交易分析'] > .jeesite-menu-submenu-title,
+    .jeesite-menu-submenu[data-menu-title='活动轨迹分析'] > .jeesite-menu-submenu-title {
       display: none;
     }
 
-    .jeesite-simple-menu > li[title='案件数据']::after,
-    .jeesite-simple-menu > li[title='通信分析']::after,
-    .jeesite-simple-menu > li[title='交易分析']::after,
-    .jeesite-simple-menu > li[title='活动轨迹分析']::after,
-    .jeesite-simple-menu > li[title='行为时空分析']::after {
+    .jeesite-simple-menu > li[data-menu-title='案件数据']::after,
+    .jeesite-simple-menu > li[data-menu-title='通信分析']::after,
+    .jeesite-simple-menu > li[data-menu-title='交易分析']::after,
+    .jeesite-simple-menu > li[data-menu-title='活动轨迹分析']::after,
+    .jeesite-simple-menu > li[data-menu-title='行为时空分析']::after {
       position: absolute;
       top: -26px;
       left: 14px;
@@ -206,7 +206,7 @@
       height: 16px;
       border-bottom: 1px solid #e7ebf3;
       color: #98a2b3;
-      font-size: 9px;
+      font-size: 12px;
       font-weight: 500;
       letter-spacing: 0.1em;
       line-height: 15px;
@@ -214,27 +214,27 @@
       pointer-events: none;
     }
 
-    .jeesite-simple-menu > li[title='案件数据']::after {
-      content: '01  /  总览';
+    .jeesite-simple-menu > li[data-menu-title='案件数据']::after {
+      content: '总览';
     }
 
-    .jeesite-simple-menu > li[title='通信分析']::after {
-      content: '02  /  通信分析';
+    .jeesite-simple-menu > li[data-menu-title='通信分析']::after {
+      content: '通信分析';
     }
 
-    .jeesite-simple-menu > li[title='交易分析']::after {
-      content: '03  /  交易分析';
+    .jeesite-simple-menu > li[data-menu-title='交易分析']::after {
+      content: '交易分析';
     }
 
-    .jeesite-simple-menu > li[title='活动轨迹分析']::after {
-      content: '04  /  活动轨迹分析';
+    .jeesite-simple-menu > li[data-menu-title='活动轨迹分析']::after {
+      content: '活动轨迹分析';
     }
 
-    .jeesite-simple-menu > li[title='行为时空分析']::after {
-      content: '05  /  关联与工具';
+    .jeesite-simple-menu > li[data-menu-title='行为时空分析']::after {
+      content: '关联与工具';
     }
 
-    /* ---------------- 菜单项 ---------------- */
+    /* ---------------- 菜单项(14px) ---------------- */
     .jeesite-menu-item,
     .jeesite-menu-submenu-title {
       position: relative;
@@ -246,7 +246,7 @@
       border-radius: 0;
       background: transparent;
       color: #1f2937;
-      font-size: 12px;
+      font-size: 14px;
       font-weight: 500;
       line-height: 20px;
       transition: