Kaynağa Gözat

fix(web): 修复管理端侧边栏菜单滚动问题

Layout.vue: 包裹el-menu于el-scrollbar内,自定义滚动条样式及flex布局
pages.json: 重构小程序页面路由结构
Admin/Product/VendorController: @RequestHeader(X-User-Id)统一为@RequestAttribute(userId)
schema.sql: articles表增加article_type和word_count字段
User 4 ay önce
ebeveyn
işleme
e24e1b328e

+ 7 - 7
cfc-backend/src/main/java/com/etotem/cfc/controller/admin/AdminController.java

@@ -639,7 +639,7 @@ public class AdminController {
      * 获取成长规划师关联的家庭列表
      */
     @PostMapping("/teacher/families")
-    public Result<Object> getTeacherFamilies(@RequestHeader("X-User-Id") Long userId) {
+    public Result<Object> getTeacherFamilies(@RequestAttribute("userId") Long userId) {
         User teacher = userMapper.selectById(userId);
         if (teacher == null || !"teacher".equals(teacher.getRole())) {
             return Result.error("非成长规划师账号");
@@ -673,7 +673,7 @@ public class AdminController {
      * 获取成长规划师发布的任务模板
      */
     @PostMapping("/teacher/task-templates")
-    public Result<Object> getTeacherTaskTemplates(@RequestHeader("X-User-Id") Long userId) {
+    public Result<Object> getTeacherTaskTemplates(@RequestAttribute("userId") Long userId) {
         User teacher = userMapper.selectById(userId);
         if (teacher == null || !"teacher".equals(teacher.getRole())) {
             return Result.error("非成长规划师账号");
@@ -691,7 +691,7 @@ public class AdminController {
      * 成长规划师创建任务模板
      */
     @PostMapping("/teacher/task-templates/create")
-    public Result<Long> createTeacherTaskTemplate(@RequestHeader("X-User-Id") Long userId,
+    public Result<Long> createTeacherTaskTemplate(@RequestAttribute("userId") Long userId,
                                                    @RequestBody TaskTemplate template) {
         User teacher = userMapper.selectById(userId);
         if (teacher == null || !"teacher".equals(teacher.getRole())) {
@@ -711,8 +711,8 @@ public class AdminController {
     /**
      * 成长规划师删除自己的任务模板
      */
-    @DeleteMapping("/teacher/task-templates/{id}")
-    public Result<Boolean> deleteTeacherTaskTemplate(@RequestHeader("X-User-Id") Long userId,
+@PostMapping("/teacher/task-templates/{id}")
+    public Result<Boolean> deleteTeacherTaskTemplate(@RequestAttribute("userId") Long userId,
                                                      @PathVariable Long id) {
         User teacher = userMapper.selectById(userId);
         if (teacher == null || !"teacher".equals(teacher.getRole())) {
@@ -732,7 +732,7 @@ public class AdminController {
      * 获取指定家庭的任务列表
      */
     @PostMapping("/teacher/families/{familyId}/tasks")
-    public Result<Object> getTeacherFamilyTasks(@RequestHeader("X-User-Id") Long userId,
+    public Result<Object> getTeacherFamilyTasks(@RequestAttribute("userId") Long userId,
                                                 @PathVariable Long familyId,
                                                 @RequestBody Map<String, Object> params) {
         User teacher = userMapper.selectById(userId);
@@ -759,7 +759,7 @@ public class AdminController {
      * 获取指定家庭的奖励列表
      */
     @PostMapping("/teacher/families/{familyId}/rewards")
-    public Result<Object> getTeacherFamilyRewards(@RequestHeader("X-User-Id") Long userId,
+    public Result<Object> getTeacherFamilyRewards(@RequestAttribute("userId") Long userId,
                                                   @PathVariable Long familyId,
                                                   @RequestBody Map<String, Object> params) {
         User teacher = userMapper.selectById(userId);

+ 5 - 5
cfc-backend/src/main/java/com/etotem/cfc/controller/product/ProductController.java

@@ -37,24 +37,24 @@ public class ProductController {
 
     @PostMapping("/create")
     public Result<ProductDTO> create(@RequestBody Product product,
-                                    @RequestHeader(value = "X-User-Id", required = false) Long userId) {
+                                    @RequestAttribute(value = "userId", required = false) Long userId) {
         return productService.create(product, userId);
     }
 
     @PostMapping("/update")
     public Result<ProductDTO> update(@RequestBody Product product,
-                                    @RequestHeader(value = "X-User-Id", required = false) Long userId) {
+                                    @RequestAttribute(value = "userId", required = false) Long userId) {
         return productService.update(product, userId);
     }
 
     @PostMapping("/my")
-    public Result<List<ProductDTO>> myProducts(@RequestHeader(value = "X-User-Id", required = false) Long userId) {
+    public Result<List<ProductDTO>> myProducts(@RequestAttribute(value = "userId", required = false) Long userId) {
         return productService.myProducts(userId);
     }
 
     @PostMapping("/shelve")
     public Result<String> shelve(@RequestBody Map<String, Object> params,
-                                @RequestHeader(value = "X-User-Id", required = false) Long userId) {
+                                @RequestAttribute(value = "userId", required = false) Long userId) {
         Long productId = Long.parseLong(params.get("productId").toString());
         String action = (String) params.get("action");
         return productService.shelve(productId, userId, action);
@@ -62,7 +62,7 @@ public class ProductController {
 
     @PostMapping("/images/update")
     public Result<String> updateImages(@RequestBody Map<String, Object> params,
-                                       @RequestHeader(value = "X-User-Id", required = false) Long userId) {
+                                       @RequestAttribute(value = "userId", required = false) Long userId) {
         Long productId = Long.parseLong(params.get("productId").toString());
         @SuppressWarnings("unchecked")
         List<String> images = (List<String>) params.get("images");

+ 4 - 4
cfc-backend/src/main/java/com/etotem/cfc/controller/vendor/VendorController.java

@@ -4,8 +4,8 @@ import com.etotem.cfc.common.Result;
 import com.etotem.cfc.service.VendorService;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestHeader;
 import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestAttribute;
 import org.springframework.web.bind.annotation.RestController;
 
 import javax.annotation.Resource;
@@ -20,19 +20,19 @@ public class VendorController {
 
     @PostMapping("/apply")
     public Result apply(@RequestBody Map<String, Object> params,
-                        @RequestHeader("X-User-Id") Long userId) {
+                        @RequestAttribute("userId") Long userId) {
         String vendorType = (String) params.get("vendorType");
         String vendorInfo = (String) params.getOrDefault("vendorInfo", "");
         return vendorService.apply(userId, vendorType, vendorInfo);
     }
 
     @PostMapping("/status")
-    public Result getStatus(@RequestHeader("X-User-Id") Long userId) {
+    public Result getStatus(@RequestAttribute("userId") Long userId) {
         return vendorService.getStatus(userId);
     }
 
     @PostMapping("/info")
-    public Result getVendorInfo(@RequestHeader("X-User-Id") Long userId) {
+    public Result getVendorInfo(@RequestAttribute("userId") Long userId) {
         return vendorService.getVendorInfo(userId);
     }
 }

+ 2 - 0
cfc-backend/src/main/resources/schema.sql

@@ -1083,6 +1083,8 @@ CREATE TABLE IF NOT EXISTS articles (
     tags VARCHAR(200) DEFAULT '' COMMENT '标签JSON数组',
     author VARCHAR(100) DEFAULT '浠艾福' COMMENT '作者',
     read_time INT DEFAULT 0 COMMENT '预计阅读分钟数',
+    article_type VARCHAR(20) DEFAULT 'normal' COMMENT '文章类型: normal(普通)/premium(优质)/original(原创)',
+    word_count INT DEFAULT 0 COMMENT '文章字数',
     related_dimensions VARCHAR(100) DEFAULT '' COMMENT '关联五维JSON数组',
     visibility VARCHAR(20) DEFAULT 'public' COMMENT '浏览权限: public/login/private',
     visible_to TEXT COMMENT '私密指定人群JSON',

+ 193 - 246
cfc-frontend/pages.json

@@ -1,13 +1,11 @@
 {
   "pages": [
-    // ===== 品牌开屏页(第一项为小程序首页)=====
     {
       "path": "pages/splash/splash",
       "style": {
         "navigationStyle": "custom"
       }
     },
-    // ===== 入口页 + TabBar 页面(必须在主包)=====
     {
       "path": "pages/index/index",
       "style": {
@@ -27,112 +25,6 @@
         "enablePullDownRefresh": true
       }
     },
-    // ===== 主包:其他页面 =====
-    {
-      "path": "pages/discover/index",
-      "style": {
-        "navigationBarTitleText": "发现"
-      }
-    },
-    {
-      "path": "pages/login/login",
-      "style": {
-        "navigationBarTitleText": "登录",
-        "navigationStyle": "custom"
-      }
-    },
-    {
-      "path": "pages/policy/agreement",
-      "style": {
-        "navigationBarTitleText": "用户协议"
-      }
-    },
-    {
-      "path": "pages/policy/privacy",
-      "style": {
-        "navigationBarTitleText": "隐私政策"
-      }
-    },
-    {
-      "path": "pages/user-edit/user-edit",
-      "style": {
-        "navigationBarTitleText": "完善信息"
-      }
-    },
-    {
-      "path": "pages/body/index",
-      "style": {
-        "navigationBarTitleText": "身"
-      }
-    },
-    {
-      "path": "pages/body/health-report",
-      "style": {
-        "navigationBarTitleText": "健康报告详情"
-      }
-    },
-    {
-      "path": "pages/body/health-dimensions",
-      "style": {
-        "navigationBarTitleText": "健康维度全景"
-      }
-    },
-    {
-      "path": "pages/body/checkin",
-      "style": {
-        "navigationBarTitleText": "健康打卡"
-      }
-    },
-    {
-      "path": "pages/body/dimension-questionnaire",
-      "style": {
-        "navigationBarTitleText": "维度问卷"
-      }
-    },
-    {
-      "path": "pages/body/dimension-detail",
-      "style": {
-        "navigationBarTitleText": "维度详情"
-      }
-    },
-    {
-      "path": "pages/body/member-body-detail",
-      "style": {
-        "navigationBarTitleText": "身体能量详情",
-        "navigationStyle": "custom"
-      }
-    },
-    {
-      "path": "pages/health/report-upload",
-      "style": {
-        "navigationBarTitleText": "上传健康报告"
-      }
-    },
-    {
-      "path": "pages/health/report-confirm",
-      "style": {
-        "navigationBarTitleText": "确认健康报告",
-        "navigationStyle": "custom"
-      }
-    },
-    {
-      "path": "pages/health/report-survey",
-      "style": {
-        "navigationBarTitleText": "健康调研问卷"
-      }
-    },
-    {
-      "path": "pages/health/report-list",
-      "style": {
-        "navigationBarTitleText": "健康报告"
-      }
-    },
-    {
-      "path": "pages/health/nutrition-profile",
-      "style": {
-        "navigationBarTitleText": "营养档案"
-      }
-    },
     {
       "path": "pages/mind/index",
       "style": {
@@ -140,58 +32,52 @@
       }
     },
     {
-      "path": "pages/mind/articles",
-      "style": {
-        "navigationBarTitleText": "心智成长"
-      }
-    },
-    {
-      "path": "pages/mind/article-detail",
+      "path": "pages/body/index",
       "style": {
-        "navigationBarTitleText": "文章详情"
+        "navigationBarTitleText": "身"
       }
     },
     {
-      "path": "pages/mind/training",
+      "path": "pages/wisdom/index",
       "style": {
-        "navigationBarTitleText": "能力训练"
+        "navigationBarTitleText": "智"
       }
     },
     {
-      "path": "pages/mind/emotion-report",
+      "path": "pages/profile/profile",
       "style": {
-        "navigationBarTitleText": "心理报告"
+        "navigationBarTitleText": "我的"
       }
     },
     {
-      "path": "pages/mind/member-mind-detail",
+      "path": "pages/login/login",
       "style": {
-        "navigationBarTitleText": "心智能量详情",
+        "navigationBarTitleText": "登录",
         "navigationStyle": "custom"
       }
     },
     {
-      "path": "pages/mind/emotion-checkin",
+      "path": "pages/policy/agreement",
       "style": {
-        "navigationBarTitleText": "情绪打卡"
+        "navigationBarTitleText": "用户协议"
       }
     },
     {
-      "path": "pages/mind/emotion-trend",
+      "path": "pages/policy/privacy",
       "style": {
-        "navigationBarTitleText": "情绪趋势"
+        "navigationBarTitleText": "隐私政策"
       }
     },
     {
-      "path": "pages/mind/traditional-mirror",
+      "path": "pages/user-edit/user-edit",
       "style": {
-        "navigationBarTitleText": "传统文化镜"
+        "navigationBarTitleText": "完善信息"
       }
     },
     {
-      "path": "pages/mind/soothe-toolbox",
+      "path": "pages/discover/index",
       "style": {
-        "navigationBarTitleText": "疏导工具箱"
+        "navigationBarTitleText": "发现"
       }
     },
     {
@@ -200,64 +86,6 @@
         "navigationBarTitleText": "行动"
       }
     },
-    {
-      "path": "pages/action/interaction-log",
-      "style": {
-        "navigationBarTitleText": "记录互动"
-      }
-    },
-    {
-      "path": "pages/action/relationship-questionnaire",
-      "style": {
-        "navigationBarTitleText": "关系问卷"
-      }
-    },
-    // ===== 智慧维度(从分包提级为主包,TabBar 页面)=====
-    {
-      "path": "pages/wisdom/index",
-      "style": {
-        "navigationBarTitleText": "智慧"
-      }
-    },
-    {
-      "path": "pages/wisdom/cognitive-report",
-      "style": {
-        "navigationBarTitleText": "认知测评报告"
-      }
-    },
-    {
-      "path": "pages/wisdom/member-wisdom-detail",
-      "style": {
-        "navigationBarTitleText": "智能量详情",
-        "navigationStyle": "custom"
-      }
-    },
-    {
-      "path": "pages/wisdom/self-quiz",
-      "style": {
-        "navigationBarTitleText": "自己出题自己答"
-      }
-    },
-    {
-      "path": "pages/wisdom/training-hub",
-      "style": {
-        "navigationBarTitleText": "认知训练中心"
-      }
-    },
-    {
-      "path": "pages/action/member-action-detail",
-      "style": {
-        "navigationBarTitleText": "行动能量详情",
-        "navigationStyle": "custom"
-      }
-    },
-    {
-      "path": "pages/action/contact-detail",
-      "style": {
-        "navigationBarTitleText": "联系人详情",
-        "navigationStyle": "custom"
-      }
-    },
     {
       "path": "pages/index/member-home-detail",
       "style": {
@@ -265,12 +93,6 @@
         "navigationStyle": "custom"
       }
     },
-    {
-      "path": "pages/profile/profile",
-      "style": {
-        "navigationBarTitleText": "我的"
-      }
-    },
     {
       "path": "pages/profile/create-child",
       "style": {
@@ -306,44 +128,9 @@
       "style": {
         "navigationBarTitleText": "我的优惠券"
       }
-    },
-    {
-      "path": "pages/family/add-member",
-      "style": {
-        "navigationBarTitleText": "添加家庭成员"
-      }
-    },
-    {
-      "path": "pages/discover/product-detail/product-detail",
-      "style": {
-        "navigationBarTitleText": "商品详情"
-      }
-    },
-    {
-      "path": "pages/discover/activity-detail/activity-detail",
-      "style": {
-        "navigationBarTitleText": "活动详情"
-      }
-    },
-        // ===== AI 聊天 =====
-    {
-      "path": "pages/ai/chat",
-      "style": {
-        "navigationBarTitleText": "AI 家庭助手",
-        "navigationStyle": "custom"
-      }
-    },
-    // ===== 邀请加入 =====
-    {
-      "path": "pages/invite/join",
-      "style": {
-        "navigationBarTitleText": "加入家庭",
-        "navigationStyle": "custom"
-      }
     }
   ],
   "subPackages": [
-    // ===== 成长规划师 =====
     {
       "root": "pages/teacher",
       "pages": [
@@ -377,7 +164,6 @@
         }
       ]
     },
-    // ===== 规划师入驻/套餐 =====
     {
       "root": "pages/guide",
       "pages": [
@@ -415,7 +201,6 @@
         }
       ]
     },
-    // ===== 家长专属 =====
     {
       "root": "pages/parent",
       "pages": [
@@ -449,7 +234,6 @@
         }
       ]
     },
-    // ===== 孩子端 =====
     {
       "root": "pages/child",
       "pages": [
@@ -463,7 +247,6 @@
         }
       ]
     },
-    // ===== 任务管理 =====
     {
       "root": "pages/tasks",
       "pages": [
@@ -485,7 +268,6 @@
         }
       ]
     },
-    // ===== 心愿单 =====
     {
       "root": "pages/wishes",
       "pages": [
@@ -503,7 +285,6 @@
         }
       ]
     },
-    // ===== 奖励/勋章 =====
     {
       "root": "pages/rewards",
       "pages": [
@@ -517,7 +298,6 @@
         }
       ]
     },
-    // ===== 小游戏 =====
     {
       "root": "pages/games",
       "pages": [
@@ -547,7 +327,6 @@
         }
       ]
     },
-    // ===== 测评 =====
     {
       "root": "pages/assessment",
       "pages": [
@@ -565,7 +344,6 @@
         }
       ]
     },
-    // ===== 成长档案 =====
     {
       "root": "pages/growth",
       "pages": [
@@ -595,7 +373,6 @@
         }
       ]
     },
-    // ===== 商城 =====
     {
       "root": "pages/shop",
       "pages": [
@@ -637,7 +414,6 @@
         }
       ]
     },
-    // ===== 服务商入驻 =====
     {
       "root": "pages/vendor",
       "pages": [
@@ -663,7 +439,6 @@
         }
       ]
     },
-    // ===== 数据统计 =====
     {
       "root": "pages/stats",
       "pages": [
@@ -677,7 +452,6 @@
         }
       ]
     },
-    // ===== 推广中心 =====
     {
       "root": "pages/promotion",
       "pages": [
@@ -707,7 +481,6 @@
         }
       ]
     },
-    // ===== 五维能量 =====
     {
       "root": "pages/energy",
       "pages": [
@@ -717,7 +490,6 @@
         }
       ]
     },
-    // ===== 会员服务 =====
     {
       "root": "pages/membership",
       "pages": [
@@ -731,7 +503,6 @@
         }
       ]
     },
-        // ===== 财富维度 =====
     {
       "root": "pages/wealth",
       "pages": [
@@ -753,7 +524,6 @@
         }
       ]
     },
-    // ===== 食谱推荐 =====
     {
       "root": "pages/meal",
       "pages": [
@@ -774,6 +544,183 @@
           "style": { "navigationBarTitleText": "饮食偏好设置" }
         }
       ]
+    },
+    {
+      "root": "pages/health",
+      "pages": [
+        {
+          "path": "report-upload",
+          "style": { "navigationBarTitleText": "上传健康报告" }
+        },
+        {
+          "path": "report-confirm",
+          "style": { "navigationBarTitleText": "确认健康报告", "navigationStyle": "custom" }
+        },
+        {
+          "path": "report-survey",
+          "style": { "navigationBarTitleText": "健康调研问卷" }
+        },
+        {
+          "path": "report-list",
+          "style": { "navigationBarTitleText": "健康报告" }
+        },
+        {
+          "path": "nutrition-profile",
+          "style": { "navigationBarTitleText": "营养档案" }
+        }
+      ]
+    },
+    {
+      "root": "pages/body",
+      "pages": [
+        {
+          "path": "health-report",
+          "style": { "navigationBarTitleText": "健康报告详情" }
+        },
+        {
+          "path": "health-dimensions",
+          "style": { "navigationBarTitleText": "健康维度全景" }
+        },
+        {
+          "path": "checkin",
+          "style": { "navigationBarTitleText": "健康打卡" }
+        },
+        {
+          "path": "dimension-questionnaire",
+          "style": { "navigationBarTitleText": "维度问卷" }
+        },
+        {
+          "path": "dimension-detail",
+          "style": { "navigationBarTitleText": "维度详情" }
+        },
+        {
+          "path": "member-body-detail",
+          "style": { "navigationBarTitleText": "身体能量详情", "navigationStyle": "custom" }
+        }
+      ]
+    },
+    {
+      "root": "pages/mind",
+      "pages": [
+        {
+          "path": "articles",
+          "style": { "navigationBarTitleText": "心智成长" }
+        },
+        {
+          "path": "article-detail",
+          "style": { "navigationBarTitleText": "文章详情" }
+        },
+        {
+          "path": "training",
+          "style": { "navigationBarTitleText": "能力训练" }
+        },
+        {
+          "path": "emotion-report",
+          "style": { "navigationBarTitleText": "心理报告" }
+        },
+        {
+          "path": "member-mind-detail",
+          "style": { "navigationBarTitleText": "心智能量详情", "navigationStyle": "custom" }
+        },
+        {
+          "path": "emotion-checkin",
+          "style": { "navigationBarTitleText": "情绪打卡" }
+        },
+        {
+          "path": "emotion-trend",
+          "style": { "navigationBarTitleText": "情绪趋势" }
+        },
+        {
+          "path": "traditional-mirror",
+          "style": { "navigationBarTitleText": "传统文化镜" }
+        },
+        {
+          "path": "soothe-toolbox",
+          "style": { "navigationBarTitleText": "疏导工具箱" }
+        }
+      ]
+    },
+    {
+      "root": "pages/wisdom",
+      "pages": [
+        {
+          "path": "cognitive-report",
+          "style": { "navigationBarTitleText": "认知测评报告" }
+        },
+        {
+          "path": "member-wisdom-detail",
+          "style": { "navigationBarTitleText": "智能量详情", "navigationStyle": "custom" }
+        },
+        {
+          "path": "self-quiz",
+          "style": { "navigationBarTitleText": "自己出题自己答" }
+        },
+        {
+          "path": "training-hub",
+          "style": { "navigationBarTitleText": "认知训练中心" }
+        }
+      ]
+    },
+    {
+      "root": "pages/action",
+      "pages": [
+        {
+          "path": "interaction-log",
+          "style": { "navigationBarTitleText": "记录互动" }
+        },
+        {
+          "path": "relationship-questionnaire",
+          "style": { "navigationBarTitleText": "关系问卷" }
+        },
+        {
+          "path": "member-action-detail",
+          "style": { "navigationBarTitleText": "行动能量详情", "navigationStyle": "custom" }
+        },
+        {
+          "path": "contact-detail",
+          "style": { "navigationBarTitleText": "联系人详情", "navigationStyle": "custom" }
+        }
+      ]
+    },
+    {
+      "root": "pages/discover",
+      "pages": [
+        {
+          "path": "product-detail/product-detail",
+          "style": { "navigationBarTitleText": "商品详情" }
+        },
+        {
+          "path": "activity-detail/activity-detail",
+          "style": { "navigationBarTitleText": "活动详情" }
+        }
+      ]
+    },
+    {
+      "root": "pages/family",
+      "pages": [
+        {
+          "path": "add-member",
+          "style": { "navigationBarTitleText": "添加家庭成员" }
+        }
+      ]
+    },
+    {
+      "root": "pages/ai",
+      "pages": [
+        {
+          "path": "chat",
+          "style": { "navigationBarTitleText": "AI 家庭助手", "navigationStyle": "custom" }
+        }
+      ]
+    },
+    {
+      "root": "pages/invite",
+      "pages": [
+        {
+          "path": "join",
+          "style": { "navigationBarTitleText": "加入家庭", "navigationStyle": "custom" }
+        }
+      ]
     }
   ],
   "globalStyle": {

+ 62 - 29
cfc-web/src/views/Layout.vue

@@ -2,35 +2,37 @@
   <el-container class="layout-container">
     <el-aside width="200px">
       <div class="logo">浠艾福</div>
-      <el-menu
-        :default-active="activeMenu"
-        class="sidebar-menu"
-        background-color="transparent"
-        text-color="#64748B"
-        active-text-color="#6366F1"
-        @select="handleMenuSelect"
-      >
-        <template v-for="item in menuItems">
-          <el-submenu v-if="item.children && hasPerm(item.perm)" :key="item.title" :index="item.title">
-            <template slot="title">
+      <el-scrollbar wrap-class="sidebar-scrollbar-wrap">
+        <el-menu
+          :default-active="activeMenu"
+          class="sidebar-menu"
+          background-color="transparent"
+          text-color="#64748B"
+          active-text-color="#6366F1"
+          @select="handleMenuSelect"
+        >
+          <template v-for="item in menuItems">
+            <el-submenu v-if="item.children && hasPerm(item.perm)" :key="item.title" :index="item.title">
+              <template slot="title">
+                <i :class="item.icon"></i>
+                <span>{{ item.label || item.title }}</span>
+              </template>
+              <el-menu-item
+                v-for="child in item.children"
+                :key="child.path"
+                :index="child.path"
+              >
+                <i :class="child.icon"></i>
+                <span slot="title">{{ child.label }}</span>
+              </el-menu-item>
+            </el-submenu>
+            <el-menu-item v-else-if="hasPerm(item.perm)" :key="item.path" :index="item.path">
               <i :class="item.icon"></i>
-              <span>{{ item.label || item.title }}</span>
-            </template>
-            <el-menu-item
-              v-for="child in item.children"
-              :key="child.path"
-              :index="child.path"
-            >
-              <i :class="child.icon"></i>
-              <span slot="title">{{ child.label }}</span>
-            </el-menu-item>
-          </el-submenu>
-          <el-menu-item v-else-if="hasPerm(item.perm)" :key="item.path" :index="item.path">
-            <i :class="item.icon"></i>
-            <span slot="title">{{ item.label }}</span>
-      </el-menu-item>
-    </template>
-      </el-menu>
+              <span slot="title">{{ item.label }}</span>
+          </el-menu-item>
+        </template>
+        </el-menu>
+      </el-scrollbar>
     </el-aside>
     <el-container>
       <el-header>
@@ -451,7 +453,9 @@ export default {
 
 .el-aside {
   background-color: #304156;
-  overflow: hidden;
+  overflow: visible;
+  display: flex;
+  flex-direction: column;
 }
 
 .logo {
@@ -462,6 +466,35 @@ export default {
   font-size: 20px;
   font-weight: bold;
   background-color: #2b3a4a;
+  flex-shrink: 0;
+}
+
+/* 侧边栏滚动条样式 */
+.sidebar-scrollbar-wrap {
+  height: calc(100vh - 60px) !important;
+  overflow-x: hidden !important;
+  overflow-y: auto !important;
+}
+
+.sidebar-scrollbar-wrap .el-scrollbar__view {
+  height: 100%;
+}
+
+.sidebar-scrollbar-wrap::-webkit-scrollbar {
+  width: 6px;
+}
+
+.sidebar-scrollbar-wrap::-webkit-scrollbar-track {
+  background: #304156;
+}
+
+.sidebar-scrollbar-wrap::-webkit-scrollbar-thumb {
+  background: #4a5568;
+  border-radius: 3px;
+}
+
+.sidebar-scrollbar-wrap::-webkit-scrollbar-thumb:hover {
+  background: #5a6578;
 }
 
 .el-header {