apple 1 өдөр өмнө
parent
commit
a2b6ae5fa4

+ 0 - 494
SsSubTab组件改造方案.md

@@ -1,494 +0,0 @@
-# SsSubTab 组件改造方案
-
-## 文件位置
-`/js/vue/ss-components.js` 第 5715-5895 行
-
-## 改造目标
-
-### 1. UI 模式改造
-- **去掉**:顶部图片 `headerImage`
-- **新增两种模式**:
-  - `collapse`(默认):只显示图标,鼠标悬停时浮动显示文字
-  - `fixed`:只显示图标,不展开浮动
-
-### 2. 性能优化
-- **现状**:iframe 用 `v-show`,页面打开时全部加载
-- **改为**:懒加载,点击哪个才加载哪个
-
----
-
-## 具体修改方案
-
-### 一、Props 修改
-
-```js
-// 删除
-headerImage: { type: String, default: "" },
-
-// 新增
-initialMode: {
-  type: String,
-  default: 'collapse',  // 'collapse' | 'fixed'
-  validator: (v) => ['collapse', 'fixed'].includes(v)
-},
-```
-
-### 二、Setup 新增逻辑
-
-```js
-setup(props, { emit }) {
-  // ... 原有逻辑保留 ...
-
-  // ===== 新增:菜单模式管理 =====
-  const menuMode = ref(props.initialMode); // 'collapse' | 'fixed'
-  const isHovering = ref(false);  // 鼠标是否在菜单区域
-
-  // 切换模式
-  const toggleMenuMode = () => {
-    menuMode.value = menuMode.value === 'collapse' ? 'fixed' : 'collapse';
-  };
-
-  // 鼠标进入/离开
-  const onMouseEnter = () => {
-    if (menuMode.value === 'collapse') {
-      isHovering.value = true;
-    }
-  };
-  const onMouseLeave = () => {
-    isHovering.value = false;
-  };
-
-  // 是否显示文字(展开状态)
-  const isExpanded = computed(() => {
-    return menuMode.value === 'collapse' && isHovering.value;
-  });
-
-  // ===== 新增:iframe 懒加载 =====
-  const loadedMenus = ref(new Set());  // 已加载过的菜单 name
-
-  // 修改 selectItem
-  const selectItem = (item) => {
-    currentMenu.value = item;
-    // 标记为已加载
-    if (item.name) {
-      loadedMenus.value.add(item.name);
-    }
-    emit("menu-change", item);
-  };
-
-  // 初始化:默认选中项需要加入已加载集合
-  watch(currentMenu, (menu) => {
-    if (menu?.name) {
-      loadedMenus.value.add(menu.name);
-    }
-  }, { immediate: true });
-
-  // 判断菜单是否已加载
-  const isMenuLoaded = (menuName) => {
-    return loadedMenus.value.has(menuName);
-  };
-
-  return {
-    // 原有
-    currentMenu,
-    selectItem,
-    handleFooterClick,
-    // 新增
-    menuMode,
-    isHovering,
-    isExpanded,
-    toggleMenuMode,
-    onMouseEnter,
-    onMouseLeave,
-    isMenuLoaded,
-  };
-}
-```
-
-### 三、Template 修改
-
-```html
-<div class="project-edit-container">
-    <!-- 左侧菜单 -->
-    <div class="left-side"
-         v-if="leftDisplay"
-         :data-mode="menuMode"
-         :class="{ 'is-expanded': isExpanded }"
-         @mouseenter="onMouseEnter"
-         @mouseleave="onMouseLeave">
-
-        <!-- 删除:头部图片 -->
-
-        <!-- 菜单内容 -->
-        <div class="menu-content">
-            <div class="scroll-view">
-                <template v-for="(menuItem, i) in menuList" :key="i">
-
-                    <!-- 分组菜单 -->
-                    <div v-if="menuItem.children?.length > 0" class="group">
-                        <div class="menu-item" @click="menuItem.open = !menuItem.open">
-                            <ss-icon :name="menuItem.icon || 'folder'" class="menu-icon" size="20px" />
-                            <span class="menu-label" v-show="isExpanded">{{ menuItem.title }}</span>
-                            <span class="arrow" v-show="isExpanded">
-                                <ss-icon :name="menuItem.open ? 'arrow-up' : 'arrow-down'" size="16px" />
-                            </span>
-                            <!-- 收起时的悬浮提示 -->
-                            <div class="menu-tooltip" v-show="!isExpanded">{{ menuItem.title }}</div>
-                        </div>
-                        <div v-show="menuItem.open && isExpanded" class="group-detail">
-                            <div v-for="(item, j) in menuItem.children"
-                                :key="j"
-                                class="menu-item"
-                                :class="{ active: item.name === currentMenu?.name }"
-                                @click="selectItem(item)">
-                                <ss-icon :name="item.icon || 'file'" class="menu-icon" size="18px" />
-                                <span class="menu-label">{{ item.title }}</span>
-                                <span class="menu-item-point" v-if="item.cgxList || item.objectList"></span>
-                            </div>
-                        </div>
-                    </div>
-
-                    <!-- 普通菜单项 -->
-                    <div v-else
-                        class="menu-item"
-                        :class="{ active: menuItem.name === currentMenu?.name }"
-                        @click="selectItem(menuItem)">
-                        <ss-icon :name="menuItem.icon || 'file'" class="menu-icon" size="20px" />
-                        <span class="menu-label" v-show="isExpanded">{{ menuItem.title }}</span>
-                        <span class="menu-item-point" v-if="menuItem.cgxList || menuItem.objectList"></span>
-                        <!-- 收起时的悬浮提示 -->
-                        <div class="menu-tooltip" v-show="!isExpanded">{{ menuItem.title }}</div>
-                    </div>
-
-                </template>
-            </div>
-        </div>
-
-        <!-- 底部:模式切换按钮 -->
-        <div class="menu-mode-toggle" @click="toggleMenuMode">
-            <ss-icon :name="menuMode === 'collapse' ? 'pin' : 'pin-fill'" size="20px" />
-            <span class="menu-label" v-show="isExpanded">
-                {{ menuMode === 'collapse' ? '固定菜单' : '取消固定' }}
-            </span>
-        </div>
-
-        <!-- 底部按钮(保留原有) -->
-        <div v-if="footerButtons.length > 0" class="sub-tab-menu-footer" @click="footerButtons[0].onclick">
-            <!-- ... 保持原有 ... -->
-        </div>
-
-    </div>
-
-    <!-- 右侧内容区域 - 懒加载 iframe -->
-    <div class="content-area fit-height-content"
-         style="overflow: hidden;"
-         :style="!leftDisplay ? { width: '100%' } : {}">
-
-        <template v-for="(menuItem, i) in menuList" :key="i">
-            <!-- 只有加载过的才渲染 iframe -->
-            <iframe
-                v-if="isMenuLoaded(menuItem.name)"
-                :src="menuItem.url"
-                style="height: 100%;width: 100%;"
-                frameborder="0"
-                class="sub-tab-iframe"
-                :id="i === 0 ? 'sub-tab-iframe' : ''"
-                v-show="currentMenu?.name === menuItem.name"
-            />
-        </template>
-
-    </div>
-</div>
-```
-
----
-
-## CSS 样式修改(base.css:4784-4968)
-
-### 现有样式分析
-```css
-/* 现有:固定 180px 宽度 */
-.project-edit-container .left-side {
-  width: 180px !important;  /* 需要改为动态 */
-}
-.project-edit-container>div.content-area {
-  width: calc(100% - 180px);  /* 需要改为动态 */
-}
-```
-
-### 需要修改的样式
-
-#### 1. 左侧容器宽度(行 4798-4802)
-```css
-/* 原来 */
-.project-edit-container .left-side {
-  width: 180px !important;
-  border-right: 1px solid #e2e4ec;
-  background-color: #edf1f5;
-}
-
-/* 改为 */
-.project-edit-container .left-side {
-  width: 60px;  /* 默认收起宽度 */
-  border-right: 1px solid #e2e4ec;
-  background-color: #edf1f5;
-  transition: width 0.2s ease;
-  display: flex;
-  flex-direction: column;
-  overflow: hidden;
-}
-
-/* 展开状态 */
-.project-edit-container .left-side.is-expanded {
-  width: 200px;
-}
-
-/* 固定模式:始终收起,不响应悬浮 */
-.project-edit-container .left-side[data-mode="fixed"] {
-  width: 60px !important;
-}
-```
-
-#### 2. 右侧内容区宽度(行 4964-4967)
-```css
-/* 原来 */
-.project-edit-container>div.content-area {
-  width: calc(100% - 180px);
-  overflow-y: auto;
-}
-
-/* 改为 */
-.project-edit-container>div.content-area {
-  flex: 1;  /* 自动填充剩余空间 */
-  overflow-y: auto;
-}
-```
-
-#### 3. 菜单项样式(行 4824-4832)
-```css
-/* 原来 */
-.project-edit-container .menu-item,
-.project-edit-container .group .menu-item {
-  padding: 20px 12px 20px 30px;
-  cursor: pointer;
-  position: relative;
-  color: #333333;
-  display: flex;
-  align-items: center;
-}
-
-/* 改为 */
-.project-edit-container .menu-item,
-.project-edit-container .group .menu-item {
-  padding: 15px;
-  cursor: pointer;
-  position: relative;
-  color: #333333;
-  display: flex;
-  align-items: center;
-  justify-content: center;  /* 收起时图标居中 */
-  gap: 10px;
-}
-
-/* 展开时左对齐 */
-.project-edit-container .left-side.is-expanded .menu-item {
-  justify-content: flex-start;
-  padding: 15px 20px;
-}
-```
-
-#### 4. 删除头部图片相关样式(行 4808-4815)
-```css
-/* 删除或注释掉 */
-/* .project-edit-container .menu-header {
-  height: 120px;
-  border-bottom: 1px solid #d8dae3;
-} */
-
-/* 修改 menu-content 高度 */
-.project-edit-container .menu-content {
-  height: calc(100% - 50px);  /* 原来是 calc(100% - 60px),去掉图片后调整 */
-  flex: 1;
-  overflow: hidden;
-}
-```
-
-#### 5. 箭头位置(行 4834-4837)
-```css
-/* 原来:固定位置 */
-.project-edit-container .menu-item .arrow {
-  position: absolute;
-  left: 180px;
-}
-
-/* 改为:相对定位,放在右侧 */
-.project-edit-container .menu-item .arrow {
-  margin-left: auto;
-}
-```
-
-### 需要新增的样式
-
-```css
-/* ===== 新增:图标样式 ===== */
-.project-edit-container .menu-icon {
-  flex-shrink: 0;
-  width: 24px;
-  height: 24px;
-  display: flex;
-  align-items: center;
-  justify-content: center;
-}
-
-/* ===== 新增:文字标签 ===== */
-.project-edit-container .menu-label {
-  white-space: nowrap;
-  overflow: hidden;
-  text-overflow: ellipsis;
-}
-
-/* 收起时隐藏文字 */
-.project-edit-container .left-side:not(.is-expanded) .menu-label {
-  display: none;
-}
-
-/* ===== 新增:悬浮提示(收起时显示) ===== */
-.project-edit-container .menu-tooltip {
-  position: absolute;
-  left: calc(100% + 10px);
-  top: 50%;
-  transform: translateY(-50%);
-  background: #393d51;
-  color: #fff;
-  padding: 8px 16px;
-  border-radius: 4px;
-  white-space: nowrap;
-  z-index: 1000;
-  opacity: 0;
-  pointer-events: none;
-  transition: opacity 0.15s ease;
-  font-size: 14px;
-}
-
-/* 小三角 */
-.project-edit-container .menu-tooltip::before {
-  content: "";
-  position: absolute;
-  left: -6px;
-  top: 50%;
-  transform: translateY(-50%);
-  border: 6px solid transparent;
-  border-right-color: #393d51;
-  border-left: none;
-}
-
-/* 悬浮显示 tooltip */
-.project-edit-container .left-side:not(.is-expanded) .menu-item:hover .menu-tooltip {
-  opacity: 1;
-}
-
-/* 展开时隐藏 tooltip */
-.project-edit-container .left-side.is-expanded .menu-tooltip {
-  display: none;
-}
-
-/* ===== 新增:模式切换按钮 ===== */
-.project-edit-container .menu-mode-toggle {
-  height: 50px;
-  display: flex;
-  align-items: center;
-  justify-content: center;
-  padding: 15px;
-  cursor: pointer;
-  border-top: 1px solid #d8dae3;
-  color: #666;
-  gap: 10px;
-  flex-shrink: 0;
-}
-
-.project-edit-container .menu-mode-toggle:hover {
-  background: #e0e4ea;
-  color: #333;
-}
-
-/* 展开时左对齐 */
-.project-edit-container .left-side.is-expanded .menu-mode-toggle {
-  justify-content: flex-start;
-  padding: 15px 20px;
-}
-
-/* ===== 新增:子菜单样式调整 ===== */
-.project-edit-container .group-detail {
-  background: rgba(0, 0, 0, 0.03);
-}
-
-.project-edit-container .group-detail .menu-item {
-  padding-left: 25px;
-}
-
-.project-edit-container .left-side.is-expanded .group-detail .menu-item {
-  padding-left: 50px;
-}
-
-/* 收起时隐藏子菜单 */
-.project-edit-container .left-side:not(.is-expanded) .group-detail {
-  display: none;
-}
-```
-
-### CSS 修改汇总表
-
-| 行号 | 原值 | 新值 | 说明 |
-|-----|------|------|-----|
-| 4799 | `width: 180px !important` | `width: 60px` | 默认收起宽度 |
-| 4808-4811 | `.menu-header {...}` | 删除或注释 | 去掉头部图片 |
-| 4814 | `height: calc(100% - 60px)` | `flex: 1` | 菜单内容自适应 |
-| 4826 | `padding: 20px 12px 20px 30px` | `padding: 15px` | 菜单项内边距 |
-| 4836 | `left: 180px` | `margin-left: auto` | 箭头位置 |
-| 4965 | `width: calc(100% - 180px)` | `flex: 1` | 右侧内容区自适应 |
-
----
-
-## 数据结构要求
-
-菜单项需要增加 `icon` 字段:
-
-```js
-menuList: [
-  {
-    name: 'basic',
-    title: '基本信息',
-    icon: 'info',      // 新增:图标名称
-    url: '/page/xxx.jsp'
-  },
-  {
-    title: '项目设置',
-    icon: 'setting',   // 新增
-    children: [
-      { name: 'config1', title: '配置1', icon: 'config', url: '...' },
-      { name: 'config2', title: '配置2', icon: 'config', url: '...' }
-    ]
-  }
-]
-```
-
----
-
-## 改造要点总结
-
-| 项目 | 原实现 | 新实现 |
-|-----|-------|-------|
-| 头部图片 | 有 headerImage | 删除 |
-| 菜单宽度 | 固定宽度 | 60px / 200px 切换 |
-| 文字显示 | 始终显示 | 收起时隐藏,悬浮/展开时显示 |
-| 模式切换 | 无 | collapse(悬浮展开) / fixed(始终收起) |
-| iframe 加载 | v-show 全部加载 | v-if 懒加载(点击才加载) |
-| 图标 | 无 | 每个菜单项需要 icon 字段 |
-
----
-
-## 兼容性注意
-
-1. 需要确保 `menuList` 数据有 `icon` 字段,否则使用默认图标
-2. 懒加载后,切换回已加载的菜单不会重新加载(保持 iframe 状态)
-3. 底部按钮功能保持不变