LiJian 1 ay önce
ebeveyn
işleme
0799665ad0
47 değiştirilmiş dosya ile 701 ekleme ve 189 silme
  1. 2 2
      ema-admin/src/main/java/com/ema/admin/codegen/MybatisFlexCodegen.java
  2. 1 0
      ema-admin/src/main/java/com/ema/admin/handler/WebMvcHandler.java
  3. 4 2
      ema-admin/src/main/java/com/ema/admin/modules/system/controller/SysRoleController.java
  4. 7 6
      ema-admin/src/main/java/com/ema/admin/modules/system/controller/SysUserController.java
  5. 1 1
      ema-admin/src/main/java/com/ema/admin/modules/system/vo/SysRoleSaveVo.java
  6. 7 2
      ema-admin/src/main/java/com/ema/admin/modules/system/vo/SysUserInfoVo.java
  7. 1 1
      ema-admin/src/main/resources/application-dev.yml
  8. 0 0
      ema-admin/src/main/resources/web/css/login.css
  9. 0 0
      ema-admin/src/main/resources/web/css/main.css
  10. 0 0
      ema-admin/src/main/resources/web/css/theme-blue.css
  11. 0 0
      ema-admin/src/main/resources/web/images/logo.svg
  12. 0 0
      ema-admin/src/main/resources/web/index.html
  13. 3 3
      ema-admin/src/main/resources/web/js/common.js
  14. 0 0
      ema-admin/src/main/resources/web/js/config.js
  15. 0 0
      ema-admin/src/main/resources/web/js/login.js
  16. 2 2
      ema-admin/src/main/resources/web/js/main.js
  17. 0 0
      ema-admin/src/main/resources/web/lib/jquery.min.js
  18. 0 0
      ema-admin/src/main/resources/web/lib/layui/css/layui.css
  19. 0 0
      ema-admin/src/main/resources/web/lib/layui/font/iconfont.eot
  20. 0 0
      ema-admin/src/main/resources/web/lib/layui/font/iconfont.svg
  21. 0 0
      ema-admin/src/main/resources/web/lib/layui/font/iconfont.ttf
  22. 0 0
      ema-admin/src/main/resources/web/lib/layui/font/iconfont.woff
  23. 0 0
      ema-admin/src/main/resources/web/lib/layui/font/iconfont.woff2
  24. 0 0
      ema-admin/src/main/resources/web/lib/layui/layui.js
  25. 1 0
      ema-admin/src/main/resources/web/pages/department/department_form.html
  26. 1 0
      ema-admin/src/main/resources/web/pages/department/department_list.html
  27. 2 1
      ema-admin/src/main/resources/web/pages/dict/dict_data_form.html
  28. 1 0
      ema-admin/src/main/resources/web/pages/dict/dict_data_list.html
  29. 2 1
      ema-admin/src/main/resources/web/pages/dict/dict_type_form.html
  30. 1 0
      ema-admin/src/main/resources/web/pages/dict/dict_type_list.html
  31. 1 0
      ema-admin/src/main/resources/web/pages/file/file_list.html
  32. 0 0
      ema-admin/src/main/resources/web/pages/home.html
  33. 2 1
      ema-admin/src/main/resources/web/pages/job/job_form.html
  34. 1 0
      ema-admin/src/main/resources/web/pages/job/job_list.html
  35. 1 0
      ema-admin/src/main/resources/web/pages/log/log_detail.html
  36. 1 0
      ema-admin/src/main/resources/web/pages/log/log_list.html
  37. 0 0
      ema-admin/src/main/resources/web/pages/main.html
  38. 6 5
      ema-admin/src/main/resources/web/pages/menu/menu_form.html
  39. 620 0
      ema-admin/src/main/resources/web/pages/menu/menu_list.html
  40. 2 8
      ema-admin/src/main/resources/web/pages/role/role_form.html
  41. 4 4
      ema-admin/src/main/resources/web/pages/role/role_list.html
  42. 1 0
      ema-admin/src/main/resources/web/pages/role/role_menu.html
  43. 1 0
      ema-admin/src/main/resources/web/pages/user/update_pwd.html
  44. 4 3
      ema-admin/src/main/resources/web/pages/user/user_form.html
  45. 1 0
      ema-admin/src/main/resources/web/pages/user/user_info.html
  46. 20 7
      ema-admin/src/main/resources/web/pages/user/user_list.html
  47. 0 140
      ema-web/pages/menu/menu_list.html

+ 2 - 2
ema-admin/src/main/java/com/ema/admin/codegen/MybatisFlexCodegen.java

@@ -20,8 +20,8 @@ public class MybatisFlexCodegen {
             dataSource.setJdbcUrl("jdbc:mysql://172.16.0.212:3306/ema_project?useUnicode=true&characterEncoding=UTF-8&&serverTimezone=GMT%2B8&allowMultiQueries=true&nullCatalogMeansCurrent=true");
             dataSource.setUsername("root");
             dataSource.setPassword("Xcsz@2024");
-            String module = "system";
-            String[] tables = {"sys_department","sys_department_user"};
+            String module = "assets";
+            String[] tables = {"assets_info","asset_status_history"};
 
             //创建全局配置
             GlobalConfig globalConfig = createGlobalConfigUseStyle(module, tables);

+ 1 - 0
ema-admin/src/main/java/com/ema/admin/handler/WebMvcHandler.java

@@ -47,6 +47,7 @@ public class WebMvcHandler implements WebMvcConfigurer {
         configureFileStorageResourceHandlers(registry);
 
         // 配置其他静态资源访问
+        registry.addResourceHandler("/ema/**").addResourceLocations("classpath:/web/");
         registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/");
         registry.addResourceHandler("/queue.html", "/redismq/**").addResourceLocations("classpath:/redismq/");
     }

+ 4 - 2
ema-admin/src/main/java/com/ema/admin/modules/system/controller/SysRoleController.java

@@ -40,7 +40,7 @@ public class SysRoleController {
     /**
      * 添加系统角色信息表。
      *
-     * @param sysRole 系统角色信息表
+     * @param saveVo 系统角色信息表
      * @return {@code true} 添加成功,{@code false} 添加失败
      */
     @PostMapping("save")
@@ -75,7 +75,9 @@ public class SysRoleController {
     @PutMapping("update")
     @ApiOperation("根据主键更新系统角色信息表")
     public boolean update(@RequestBody @ApiParam("系统角色信息表主键") SysRoleSaveVo sysRole) {
-        sysRoleService.assignMenusToRole(sysRole.getId(),sysRole.getMenuIds());
+        if(CollUtil.isNotEmpty(sysRole.getMenuIds())){
+            sysRoleService.assignMenusToRole(sysRole.getId(),sysRole.getMenuIds());
+        }
         return sysRoleService.updateById(sysRoleConverter.toSysRole(sysRole));
     }
 

+ 7 - 6
ema-admin/src/main/java/com/ema/admin/modules/system/controller/SysUserController.java

@@ -44,16 +44,17 @@ public class SysUserController {
     /**
      * 添加系统用户信息表。
      *
-     * @param sysUser 系统用户信息表
+     * @param saveVo 系统用户信息表
      * @return {@code true} 添加成功,{@code false} 添加失败
      */
     @PostMapping("save")
     @ApiOperation("保存系统用户信息表")
-    public boolean save(@RequestBody @ApiParam("系统用户信息表") SysUserSaveVo sysUser) {
-        sysUser.setPassword(SaSecureUtil.md5(sysUser.getPassword()));
-        boolean save = sysUserService.save(sysUserConverter.toSysUser(sysUser));
-        if(CollUtil.isNotEmpty(sysUser.getRoleIds())){
-            sysUserService.assignRolesToUser(sysUser.getId(),sysUser.getRoleIds());
+    public boolean save(@RequestBody @ApiParam("系统用户信息表") SysUserSaveVo saveVo) {
+        saveVo.setPassword(SaSecureUtil.md5(saveVo.getPassword()));
+        SysUser sysUser = sysUserConverter.toSysUser(saveVo);
+        boolean save = sysUserService.save(sysUser);
+        if(CollUtil.isNotEmpty(saveVo.getRoleIds())){
+            sysUserService.assignRolesToUser(sysUser.getId(),saveVo.getRoleIds());
         }
         return save;
     }

+ 1 - 1
ema-admin/src/main/java/com/ema/admin/modules/system/vo/SysRoleSaveVo.java

@@ -56,7 +56,7 @@ public class SysRoleSaveVo implements Serializable {
     @ApiModelProperty("备注")
     private String remark;
 
-    @ApiModelProperty(value = "菜单ID列表", required = true)
+    @ApiModelProperty(value = "菜单ID列表")
     @NotEmpty(message = "菜单ID列表不能为空")
     private List<String> menuIds;
 }

+ 7 - 2
ema-admin/src/main/java/com/ema/admin/modules/system/vo/SysUserInfoVo.java

@@ -1,5 +1,6 @@
 package com.ema.admin.modules.system.vo;
 
+import com.fasterxml.jackson.annotation.JsonFormat;
 import com.mybatisflex.annotation.Id;
 import com.mybatisflex.annotation.KeyType;
 import com.ema.admin.modules.system.entity.SysRole;
@@ -9,8 +10,10 @@ import lombok.AllArgsConstructor;
 import lombok.Builder;
 import lombok.Data;
 import lombok.NoArgsConstructor;
+import org.springframework.format.annotation.DateTimeFormat;
 
 import java.io.Serializable;
+import java.util.Date;
 import java.util.List;
 
 /**
@@ -77,8 +80,10 @@ public class SysUserInfoVo implements Serializable {
     @ApiModelProperty("备注")
     private String remark;
 
-    @ApiModelProperty(value = "数据版本")
-    private Integer version;
+    @ApiModelProperty(value = "创建时间")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", locale = "zh", timezone = "GMT+8")
+    private Date createTime;
 
     @ApiModelProperty(value = "角色列表")
     private List<SysRole> roleList;

+ 1 - 1
ema-admin/src/main/resources/application-dev.yml

@@ -3,7 +3,7 @@ mybatis-flex:
   datasource:
     mysqlMaster:
       type: hikaricp
-      url: jdbc:mysql://172.16.0.212:3306/hn-starcdata?useUnicode=true&characterEncoding=UTF-8&&serverTimezone=GMT%2B8&allowMultiQueries=true&nullCatalogMeansCurrent=true
+      url: jdbc:mysql://172.16.0.212:3306/ema_projet?useUnicode=true&characterEncoding=UTF-8&&serverTimezone=GMT%2B8&allowMultiQueries=true&nullCatalogMeansCurrent=true
       username: root
       password: Xcsz@2024
       driver-class-name: com.mysql.cj.jdbc.Driver

+ 0 - 0
ema-web/css/login.css → ema-admin/src/main/resources/web/css/login.css


+ 0 - 0
ema-web/css/main.css → ema-admin/src/main/resources/web/css/main.css


+ 0 - 0
ema-web/css/theme-blue.css → ema-admin/src/main/resources/web/css/theme-blue.css


+ 0 - 0
ema-web/images/logo.svg → ema-admin/src/main/resources/web/images/logo.svg


+ 0 - 0
ema-web/index.html → ema-admin/src/main/resources/web/index.html


+ 3 - 3
ema-web/js/common.js → ema-admin/src/main/resources/web/js/common.js

@@ -273,7 +273,7 @@ var TableRender = {
         var token = localStorage.getItem('token');
         var headers = {};
         if (token) {
-            headers['Authorization'] = 'Bearer ' + token;
+            headers['token'] = token;
         }
         return headers;
     },
@@ -303,7 +303,7 @@ var TableRender = {
                     code: res.code,
                     msg: res.msg,
                     count: res.data ? res.data.totalRow : 0,
-                    data: res.data ? res.data.list : []
+                    data: res.data ? res.data.records : []
                 };
             },
             before: function(req) {
@@ -311,7 +311,7 @@ var TableRender = {
                 var token = localStorage.getItem('token');
                 if (token) {
                     req.headers = req.headers || {};
-                    req.headers['Authorization'] = 'Bearer ' + token;
+                    req.headers['token'] = token;
                 }
             }
         };

+ 0 - 0
ema-web/js/config.js → ema-admin/src/main/resources/web/js/config.js


+ 0 - 0
ema-web/js/login.js → ema-admin/src/main/resources/web/js/login.js


+ 2 - 2
ema-web/js/main.js → ema-admin/src/main/resources/web/js/main.js

@@ -54,7 +54,7 @@ layui.use(['element', 'layer'], function () {
                     html += ' layui-nav-itemed';
                 }
                 html += '">';
-                html += '<a href="javascript:;" ' + (hasChildren ? '' : 'class="open-tab"') + ' data-url="' + (menu.component || '') + '" data-title="' + menu.menuName + '" data-id="' + menu.id + '">';
+                html += '<a href="javascript:;" ' + (hasChildren ? '' : 'class="open-tab"') + ' data-url="' + (menu.path || '') + '" data-title="' + menu.menuName + '" data-id="' + menu.id + '">';
                 if (menu.icon) {
                     html += '<i class="layui-icon ' + menu.icon + '"></i>';
                 }
@@ -64,7 +64,7 @@ layui.use(['element', 'layer'], function () {
                     html += '<dl class="layui-nav-child">';
                     menu.children.forEach(function (child) {
                         html += '<dd>';
-                        html += '<a href="javascript:;" class="open-tab" data-url="' + (child.component || '') + '" data-title="' + child.menuName + '" data-id="' + child.id + '">';
+                        html += '<a href="javascript:;" class="open-tab" data-url="' + (child.path || '') + '" data-title="' + child.menuName + '" data-id="' + child.id + '">';
                         if (child.icon) {
                             html += '<i class="layui-icon ' + child.icon + '"></i>';
                         }

+ 0 - 0
ema-web/lib/jquery.min.js → ema-admin/src/main/resources/web/lib/jquery.min.js


+ 0 - 0
ema-web/lib/layui/css/layui.css → ema-admin/src/main/resources/web/lib/layui/css/layui.css


+ 0 - 0
ema-web/lib/layui/font/iconfont.eot → ema-admin/src/main/resources/web/lib/layui/font/iconfont.eot


+ 0 - 0
ema-web/lib/layui/font/iconfont.svg → ema-admin/src/main/resources/web/lib/layui/font/iconfont.svg


+ 0 - 0
ema-web/lib/layui/font/iconfont.ttf → ema-admin/src/main/resources/web/lib/layui/font/iconfont.ttf


+ 0 - 0
ema-web/lib/layui/font/iconfont.woff → ema-admin/src/main/resources/web/lib/layui/font/iconfont.woff


+ 0 - 0
ema-web/lib/layui/font/iconfont.woff2 → ema-admin/src/main/resources/web/lib/layui/font/iconfont.woff2


+ 0 - 0
ema-web/lib/layui/layui.js → ema-admin/src/main/resources/web/lib/layui/layui.js


+ 1 - 0
ema-web/pages/department/department_form.html → ema-admin/src/main/resources/web/pages/department/department_form.html

@@ -81,6 +81,7 @@
         </div>
     </form>
     
+    <script src="../../lib/jquery.min.js"></script>
     <script src="../../lib/layui/layui.js"></script>
     <script src="../../js/config.js"></script>
     <script src="../../js/common.js"></script>

+ 1 - 0
ema-web/pages/department/department_list.html → ema-admin/src/main/resources/web/pages/department/department_list.html

@@ -31,6 +31,7 @@
         {{# } }}
     </script>
     
+    <script src="../../lib/jquery.min.js"></script>
     <script src="../../lib/layui/layui.js"></script>
     <script src="../../js/config.js"></script>
     <script src="../../js/common.js"></script>

+ 2 - 1
ema-web/pages/dict/dict_data_form.html → ema-admin/src/main/resources/web/pages/dict/dict_data_form.html

@@ -65,6 +65,7 @@
         </div>
     </form>
     
+    <script src="../../lib/jquery.min.js"></script>
     <script src="../../lib/layui/layui.js"></script>
     <script src="../../js/config.js"></script>
     <script src="../../js/common.js"></script>
@@ -95,7 +96,7 @@
                         Common.success(isEdit ? '修改成功' : '添加成功', function() {
                             var index = parent.layer.getFrameIndex(window.name);
                             parent.layer.close(index);
-                            parent.table.reload('tableList');
+                            parent.layui.table.reload('tableList');
                         });
                     }
                 });

+ 1 - 0
ema-web/pages/dict/dict_data_list.html → ema-admin/src/main/resources/web/pages/dict/dict_data_list.html

@@ -53,6 +53,7 @@
         {{# } }}
     </script>
     
+    <script src="../../lib/jquery.min.js"></script>
     <script src="../../lib/layui/layui.js"></script>
     <script src="../../js/config.js"></script>
     <script src="../../js/common.js"></script>

+ 2 - 1
ema-web/pages/dict/dict_type_form.html → ema-admin/src/main/resources/web/pages/dict/dict_type_form.html

@@ -50,6 +50,7 @@
         </div>
     </form>
     
+    <script src="../../lib/jquery.min.js"></script>
     <script src="../../lib/layui/layui.js"></script>
     <script src="../../js/config.js"></script>
     <script src="../../js/common.js"></script>
@@ -77,7 +78,7 @@
                         Common.success(isEdit ? '修改成功' : '添加成功', function() {
                             var index = parent.layer.getFrameIndex(window.name);
                             parent.layer.close(index);
-                            parent.table.reload('tableList');
+                            parent.layui.table.reload('tableList');
                         });
                     }
                 });

+ 1 - 0
ema-web/pages/dict/dict_type_list.html → ema-admin/src/main/resources/web/pages/dict/dict_type_list.html

@@ -54,6 +54,7 @@
         {{# } }}
     </script>
     
+    <script src="../../lib/jquery.min.js"></script>
     <script src="../../lib/layui/layui.js"></script>
     <script src="../../js/config.js"></script>
     <script src="../../js/common.js"></script>

+ 1 - 0
ema-web/pages/file/file_list.html → ema-admin/src/main/resources/web/pages/file/file_list.html

@@ -40,6 +40,7 @@
     
     <div id="pagination" style="text-align: center; margin-top: 20px;"></div>
     
+    <script src="../../lib/jquery.min.js"></script>
     <script src="../../lib/layui/layui.js"></script>
     <script src="../../js/config.js"></script>
     <script src="../../js/common.js"></script>

+ 0 - 0
ema-web/pages/home.html → ema-admin/src/main/resources/web/pages/home.html


+ 2 - 1
ema-web/pages/job/job_form.html → ema-admin/src/main/resources/web/pages/job/job_form.html

@@ -71,6 +71,7 @@
         </div>
     </form>
     
+    <script src="../../lib/jquery.min.js"></script>
     <script src="../../lib/layui/layui.js"></script>
     <script src="../../js/config.js"></script>
     <script src="../../js/common.js"></script>
@@ -98,7 +99,7 @@
                         Common.success(isEdit ? '修改成功' : '添加成功', function() {
                             var index = parent.layer.getFrameIndex(window.name);
                             parent.layer.close(index);
-                            parent.table.reload('tableList');
+                            parent.layui.table.reload('tableList');
                         });
                     }
                 });

+ 1 - 0
ema-web/pages/job/job_list.html → ema-admin/src/main/resources/web/pages/job/job_list.html

@@ -62,6 +62,7 @@
         {{# } }}
     </script>
     
+    <script src="../../lib/jquery.min.js"></script>
     <script src="../../lib/layui/layui.js"></script>
     <script src="../../js/config.js"></script>
     <script src="../../js/common.js"></script>

+ 1 - 0
ema-web/pages/log/log_detail.html → ema-admin/src/main/resources/web/pages/log/log_detail.html

@@ -29,6 +29,7 @@
         <tr><td>返回结果</td><td id="result"></td></tr>
     </table>
     
+    <script src="../../lib/jquery.min.js"></script>
     <script src="../../lib/layui/layui.js"></script>
     <script src="../../js/config.js"></script>
     <script src="../../js/common.js"></script>

+ 1 - 0
ema-web/pages/log/log_list.html → ema-admin/src/main/resources/web/pages/log/log_list.html

@@ -67,6 +67,7 @@
         {{# } }}
     </script>
     
+    <script src="../../lib/jquery.min.js"></script>
     <script src="../../lib/layui/layui.js"></script>
     <script src="../../js/config.js"></script>
     <script src="../../js/common.js"></script>

+ 0 - 0
ema-web/pages/main.html → ema-admin/src/main/resources/web/pages/main.html


+ 6 - 5
ema-web/pages/menu/menu_form.html → ema-admin/src/main/resources/web/pages/menu/menu_form.html

@@ -46,16 +46,16 @@
         <div class="layui-form-item">
             <label class="layui-form-label">路由地址</label>
             <div class="layui-input-block">
-                <input type="text" name="path" placeholder="请输入路由地址" class="layui-input" style="width: 300px;">
+                <input type="text" name="path" placeholder="如: user/user_list.html" class="layui-input" style="width: 300px;">
             </div>
         </div>
         
-        <div class="layui-form-item">
+<!--        <div class="layui-form-item">
             <label class="layui-form-label">组件路径</label>
             <div class="layui-input-block">
-                <input type="text" name="component" placeholder="如: user/user_list.html" class="layui-input" style="width: 300px;">
+                <input type="text" name="component" placeholder="" class="layui-input" style="width: 300px;">
             </div>
-        </div>
+        </div>-->
         
         <div class="layui-form-item">
             <label class="layui-form-label">权限标识</label>
@@ -103,6 +103,7 @@
         </div>
     </form>
     
+    <script src="../../lib/jquery.min.js"></script>
     <script src="../../lib/layui/layui.js"></script>
     <script src="../../js/config.js"></script>
     <script src="../../js/common.js"></script>
@@ -189,7 +190,7 @@
                         Common.success(isEdit ? '修改成功' : '添加成功', function() {
                             var index = parent.layer.getFrameIndex(window.name);
                             parent.layer.close(index);
-                            parent.table.reload('tableList');
+                            parent.layui.table.reload('tableList');
                         });
                     }
                 });

+ 620 - 0
ema-admin/src/main/resources/web/pages/menu/menu_list.html

@@ -0,0 +1,620 @@
+<!DOCTYPE html>
+<html lang="zh-CN">
+<head>
+    <meta charset="UTF-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <title>菜单管理</title>
+    <link rel="stylesheet" href="../../lib/layui/css/layui.css">
+    <style>
+        body { padding: 15px; background: #f5f7fa; }
+        
+        .menu-container {
+            display: flex;
+            gap: 20px;
+            height: calc(100vh - 90px);
+        }
+        
+        /* 左侧树形区域 */
+        .menu-tree-panel {
+            width: 380px;
+            background: #fff;
+            border-radius: 8px;
+            box-shadow: 0 2px 12px rgba(0,0,0,0.08);
+            display: flex;
+            flex-direction: column;
+            overflow: hidden;
+        }
+        
+        .panel-header {
+            padding: 16px 20px;
+            border-bottom: 1px solid #ebeef5;
+            display: flex;
+            justify-content: space-between;
+            align-items: center;
+        }
+        
+        .panel-header h3 {
+            margin: 0;
+            font-size: 16px;
+            font-weight: 600;
+            color: #303133;
+        }
+        
+        .search-box {
+            padding: 12px 20px;
+            border-bottom: 1px solid #f0f2f5;
+        }
+        
+        .search-box input {
+            width: 100%;
+            padding: 8px 12px;
+            border: 1px solid #dcdfe6;
+            border-radius: 4px;
+            font-size: 14px;
+            transition: all 0.3s;
+        }
+        
+        .search-box input:focus {
+            border-color: #409eff;
+            outline: none;
+        }
+        
+        .tree-content {
+            flex: 1;
+            overflow-y: auto;
+            padding: 12px;
+        }
+        
+        /* 树形节点样式 */
+        .custom-tree-node {
+            display: flex;
+            align-items: center;
+            padding: 8px 12px;
+            border-radius: 6px;
+            transition: all 0.2s;
+            cursor: pointer;
+            margin-bottom: 4px;
+            position: relative;
+        }
+        
+        .custom-tree-node:hover {
+            background: #f5f7fa;
+        }
+        
+        .custom-tree-node.active {
+            background: #ecf5ff;
+        }
+        
+        .node-icon {
+            width: 28px;
+            height: 28px;
+            border-radius: 6px;
+            display: flex;
+            align-items: center;
+            justify-content: center;
+            margin-right: 10px;
+            font-size: 14px;
+        }
+        
+        .node-icon.directory { background: #e1f3f8; color: #009688; }
+        .node-icon.menu { background: #ecf5ff; color: #409eff; }
+        .node-icon.button { background: #fef0f0; color: #f56c6c; }
+        
+        .node-info {
+            flex: 1;
+            min-width: 0;
+        }
+        
+        .node-name {
+            font-size: 14px;
+            color: #303133;
+            font-weight: 500;
+            white-space: nowrap;
+            overflow: hidden;
+            text-overflow: ellipsis;
+        }
+        
+        .node-path {
+            font-size: 12px;
+            color: #909399;
+            margin-top: 2px;
+            white-space: nowrap;
+            overflow: hidden;
+            text-overflow: ellipsis;
+        }
+        
+        .node-actions {
+            display: none;
+            gap: 6px;
+            margin-left: 10px;
+        }
+        
+        .custom-tree-node:hover .node-actions {
+            display: flex;
+        }
+        
+        .node-actions button {
+            width: 28px;
+            height: 28px;
+            border: none;
+            border-radius: 4px;
+            cursor: pointer;
+            display: flex;
+            align-items: center;
+            justify-content: center;
+            transition: all 0.2s;
+        }
+        
+        .node-actions .btn-edit { background: #ecf5ff; color: #409eff; }
+        .node-actions .btn-edit:hover { background: #409eff; color: #fff; }
+        .node-actions .btn-add { background: #f0f9eb; color: #67c23a; }
+        .node-actions .btn-add:hover { background: #67c23a; color: #fff; }
+        .node-actions .btn-del { background: #fef0f0; color: #f56c6c; }
+        .node-actions .btn-del:hover { background: #f56c6c; color: #fff; }
+        
+        .node-expand {
+            width: 20px;
+            height: 20px;
+            display: flex;
+            align-items: center;
+            justify-content: center;
+            cursor: pointer;
+            color: #909399;
+            margin-right: 5px;
+            transition: transform 0.3s;
+        }
+        
+        .node-expand.expanded { transform: rotate(90deg); }
+        .node-expand.empty { visibility: hidden; }
+        
+        .children-nodes {
+            padding-left: 20px;
+        }
+        
+        /* 右侧详情区域 */
+        .menu-detail-panel {
+            flex: 1;
+            background: #fff;
+            border-radius: 8px;
+            box-shadow: 0 2px 12px rgba(0,0,0,0.08);
+            overflow: hidden;
+        }
+        
+        .detail-header {
+            padding: 16px 20px;
+            border-bottom: 1px solid #ebeef5;
+            display: flex;
+            justify-content: space-between;
+            align-items: center;
+        }
+        
+        .detail-header h3 {
+            margin: 0;
+            font-size: 16px;
+            font-weight: 600;
+            color: #303133;
+        }
+        
+        .detail-content {
+            padding: 24px;
+        }
+        
+        .detail-empty {
+            text-align: center;
+            padding: 80px 0;
+            color: #909399;
+        }
+        
+        .detail-empty i {
+            font-size: 60px;
+            margin-bottom: 16px;
+            color: #dcdfe6;
+        }
+        
+        .info-grid {
+            display: grid;
+            grid-template-columns: repeat(2, 1fr);
+            gap: 20px;
+        }
+        
+        .info-item {
+            padding: 16px;
+            background: #fafafa;
+            border-radius: 6px;
+        }
+        
+        .info-item.full-width {
+            grid-column: span 2;
+        }
+        
+        .info-label {
+            font-size: 12px;
+            color: #909399;
+            margin-bottom: 6px;
+        }
+        
+        .info-value {
+            font-size: 14px;
+            color: #303133;
+        }
+        
+        .menu-type-tag {
+            display: inline-block;
+            padding: 2px 10px;
+            border-radius: 4px;
+            font-size: 12px;
+        }
+        
+        .menu-type-tag.M { background: #e1f3f8; color: #009688; }
+        .menu-type-tag.C { background: #ecf5ff; color: #409eff; }
+        .menu-type-tag.F { background: #fef0f0; color: #f56c6c; }
+        
+        .menu-status {
+            display: inline-block;
+            padding: 2px 10px;
+            border-radius: 4px;
+            font-size: 12px;
+        }
+        
+        .menu-status.normal { background: #f0f9eb; color: #67c23a; }
+        .menu-status.disabled { background: #f4f4f5; color: #909399; }
+        
+        /* 按钮样式 */
+        .btn-primary {
+            background: #409eff;
+            color: #fff;
+            border: none;
+            padding: 8px 16px;
+            border-radius: 4px;
+            cursor: pointer;
+            font-size: 14px;
+            display: inline-flex;
+            align-items: center;
+            gap: 6px;
+        }
+        
+        .btn-primary:hover {
+            background: #66b1ff;
+        }
+        
+        .btn-default {
+            background: #fff;
+            color: #606266;
+            border: 1px solid #dcdfe6;
+            padding: 8px 16px;
+            border-radius: 4px;
+            cursor: pointer;
+            font-size: 14px;
+        }
+        
+        .btn-default:hover {
+            color: #409eff;
+            border-color: #c6e2ff;
+            background: #ecf5ff;
+        }
+        
+        /* 滚动条样式 */
+        .tree-content::-webkit-scrollbar,
+        .detail-content::-webkit-scrollbar {
+            width: 6px;
+        }
+        
+        .tree-content::-webkit-scrollbar-thumb,
+        .detail-content::-webkit-scrollbar-thumb {
+            background: #dcdfe6;
+            border-radius: 3px;
+        }
+        
+        .tree-content::-webkit-scrollbar-track,
+        .detail-content::-webkit-scrollbar-track {
+            background: #f5f7fa;
+        }
+        
+        /* 动画 */
+        @keyframes fadeIn {
+            from { opacity: 0; transform: translateY(10px); }
+            to { opacity: 1; transform: translateY(0); }
+        }
+        
+        .detail-content {
+            animation: fadeIn 0.3s ease;
+        }
+    </style>
+</head>
+<body>
+    <div class="menu-container">
+        <!-- 左侧树形区域 -->
+        <div class="menu-tree-panel">
+            <div class="panel-header">
+                <h3><i class="layui-icon layui-icon-app"></i> 菜单列表</h3>
+                <button class="btn-primary" onclick="addMenu(0)">
+                    <i class="layui-icon layui-icon-add-1"></i> 添加
+                </button>
+            </div>
+            <div class="search-box">
+                <input type="text" id="searchInput" placeholder="搜索菜单名称..." oninput="filterMenu(this.value)">
+            </div>
+            <div class="tree-content" id="menuTree"></div>
+        </div>
+        
+        <!-- 右侧详情区域 -->
+        <div class="menu-detail-panel">
+            <div class="detail-header">
+                <h3><i class="layui-icon layui-icon-survey"></i> 菜单详情</h3>
+                <div id="detailActions" style="display: none;">
+                    <button class="btn-default" onclick="editCurrentMenu()">
+                        <i class="layui-icon layui-icon-edit"></i> 编辑
+                    </button>
+                    <button class="btn-default" onclick="addChildMenu()">
+                        <i class="layui-icon layui-icon-add-1"></i> 添加下级
+                    </button>
+                    <button class="btn-default" style="color: #f56c6c;" onclick="delCurrentMenu()">
+                        <i class="layui-icon layui-icon-delete"></i> 删除
+                    </button>
+                </div>
+            </div>
+            <div class="detail-content" id="detailContent">
+                <div class="detail-empty">
+                    <i class="layui-icon layui-icon-survey"></i>
+                    <p>请选择一个菜单查看详情</p>
+                </div>
+            </div>
+        </div>
+    </div>
+    
+    <script src="../../lib/jquery.min.js"></script>
+    <script src="../../lib/layui/layui.js"></script>
+    <script src="../../js/config.js"></script>
+    <script src="../../js/common.js"></script>
+    <script>
+        var currentMenu = null;
+        var menuData = [];
+        
+        // 加载菜单数据
+        function loadMenuTree() {
+            Common.get(Config.api.menu.tree, function(res) {
+                if (res.code === 200) {
+                    menuData = res.data || [];
+                    renderTree(menuData);
+                }
+            });
+        }
+        
+        // 渲染树形结构
+        function renderTree(data, container) {
+            container = container || $('#menuTree');
+            container.empty();
+            
+            data.forEach(function(item) {
+                var hasChildren = item.children && item.children.length > 0;
+                var iconClass = getMenuTypeClass(item.menuType);
+                var iconText = getMenuTypeText(item.menuType);
+                
+                var node = $('<div class="custom-tree-node" data-id="' + item.id + '">' +
+                    '<span class="node-expand ' + (hasChildren ? 'expanded' : 'empty') + '" onclick="toggleNode(this, event)">' +
+                    '<i class="layui-icon layui-icon-right"></i></span>' +
+                    '<span class="node-icon ' + iconClass + '"><i class="layui-icon ' + (item.icon || 'layui-icon-file') + '"></i></span>' +
+                    '<div class="node-info">' +
+                    '<div class="node-name">' + item.menuName + '</div>' +
+                    '<div class="node-path">' + (item.menuUrl || '无 URL') + '</div>' +
+                    '</div>' +
+                    '<div class="node-actions">' +
+                    '<button class="btn-edit" onclick="event.stopPropagation(); editMenu(' + item.id + ')" title="编辑"><i class="layui-icon layui-icon-edit"></i></button>' +
+                    '<button class="btn-add" onclick="event.stopPropagation(); addMenu(' + item.id + ')" title="添加下级"><i class="layui-icon layui-icon-add-1"></i></button>' +
+                    '<button class="btn-del" onclick="event.stopPropagation(); delMenu(' + item.id + ')" title="删除"><i class="layui-icon layui-icon-delete"></i></button>' +
+                    '</div>' +
+                    '</div>');
+                
+                container.append(node);
+                
+                // 存储完整数据
+                node.data('menuData', item);
+                
+                // 点击选中
+                node.on('click', function(e) {
+                    if (!$(e.target).closest('.node-actions').length) {
+                        selectNode($(this));
+                    }
+                });
+                
+                // 子节点
+                if (hasChildren) {
+                    var childrenContainer = $('<div class="children-nodes"></div>');
+                    container.append(childrenContainer);
+                    renderTree(item.children, childrenContainer);
+                }
+            });
+        }
+        
+        // 获取菜单类型样式
+        function getMenuTypeClass(type) {
+            switch(type) {
+                case 'M': return 'directory';
+                case 'C': return 'menu';
+                case 'F': return 'button';
+                default: return 'menu';
+            }
+        }
+        
+        // 获取菜单类型文本
+        function getMenuTypeText(type) {
+            switch(type) {
+                case 'M': return '目录';
+                case 'C': return '菜单';
+                case 'F': return '按钮';
+                default: return '未知';
+            }
+        }
+        
+        // 展开/折叠节点
+        function toggleNode(element, event) {
+            event.stopPropagation();
+            var $this = $(element);
+            var $children = $this.closest('.custom-tree-node').siblings('.children-nodes');
+            
+            if ($children.length > 0) {
+                $this.toggleClass('expanded');
+                $children.slideToggle(200);
+            }
+        }
+        
+        // 选中节点
+        function selectNode($node) {
+            $('.custom-tree-node').removeClass('active');
+            $node.addClass('active');
+            
+            currentMenu = $node.data('menuData');
+            showDetail(currentMenu);
+        }
+        
+        // 显示详情
+        function showDetail(menu) {
+            $('#detailActions').show();
+            
+            var statusClass = menu.status === '1' ? 'normal' : 'disabled';
+            var statusText = menu.status === '1' ? '正常' : '禁用';
+            
+            var typeClass = menu.menuType;
+            var typeText = getMenuTypeText(menu.menuType);
+            
+            var html = '<div class="info-grid">' +
+                '<div class="info-item">' +
+                '<div class="info-label">菜单名称</div>' +
+                '<div class="info-value">' + menu.menuName + '</div>' +
+                '</div>' +
+                '<div class="info-item">' +
+                '<div class="info-label">菜单类型</div>' +
+                '<div class="info-value"><span class="menu-type-tag ' + typeClass + '">' + typeText + '</span></div>' +
+                '</div>' +
+                '<div class="info-item">' +
+                '<div class="info-label">菜单编码</div>' +
+                '<div class="info-value">' + (menu.menuCode || '无') + '</div>' +
+                '</div>' +
+                '<div class="info-item">' +
+                '<div class="info-label">菜单状态</div>' +
+                '<div class="info-value"><span class="menu-status ' + statusClass + '">' + statusText + '</span></div>' +
+                '</div>' +
+                '<div class="info-item">' +
+                '<div class="info-label">菜单图标</div>' +
+                '<div class="info-value"><i class="layui-icon ' + (menu.icon || 'layui-icon-file') + '"></i> ' + (menu.icon || '无') + '</div>' +
+                '</div>' +
+                '<div class="info-item">' +
+                '<div class="info-label">排序号</div>' +
+                '<div class="info-value">' + (menu.orderNum || 0) + '</div>' +
+                '</div>' +
+                '<div class="info-item full-width">' +
+                '<div class="info-label">菜单路径</div>' +
+                '<div class="info-value">' + (menu.menuUrl || '无') + '</div>' +
+                '</div>' +
+                '<div class="info-item full-width">' +
+                '<div class="info-label">组件路径</div>' +
+                '<div class="info-value">' + (menu.component || '无') + '</div>' +
+                '</div>' +
+                '</div>';
+            
+            $('#detailContent').html(html);
+        }
+        
+        // 搜索菜单
+        function filterMenu(keyword) {
+            if (!keyword) {
+                renderTree(menuData);
+                return;
+            }
+            
+            var filtered = filterTreeData(menuData, keyword);
+            renderTree(filtered);
+        }
+        
+        // 过滤树形数据
+        function filterTreeData(data, keyword) {
+            var result = [];
+            
+            data.forEach(function(item) {
+                if (item.menuName.toLowerCase().indexOf(keyword.toLowerCase()) >= 0) {
+                    result.push(item);
+                } else if (item.children && item.children.length > 0) {
+                    var filteredChildren = filterTreeData(item.children, keyword);
+                    if (filteredChildren.length > 0) {
+                        var newItem = $.extend({}, item);
+                        newItem.children = filteredChildren;
+                        result.push(newItem);
+                    }
+                }
+            });
+            
+            return result;
+        }
+        
+        // 添加菜单
+        function addMenu(parentId) {
+            var url = parentId === 0 ? 'menu_form.html?id=' : 'menu_form.html?parentId=' + parentId;
+            Common.open({
+                title: parentId === 0 ? '添加顶级菜单' : '添加下级菜单',
+                area: ['600px', '550px'],
+                content: url,
+                end: function() {
+                    loadMenuTree();
+                }
+            });
+        }
+        
+        // 编辑菜单
+        function editMenu(id) {
+            Common.open({
+                title: '编辑菜单',
+                area: ['600px', '550px'],
+                content: 'menu_form.html?id=' + id,
+                end: function() {
+                    loadMenuTree();
+                }
+            });
+        }
+        
+        // 编辑当前菜单
+        function editCurrentMenu() {
+            if (currentMenu) {
+                editMenu(currentMenu.id);
+            }
+        }
+        
+        // 添加下级(当前选中)
+        function addChildMenu() {
+            if (currentMenu) {
+                addMenu(currentMenu.id);
+            }
+        }
+        
+        // 删除菜单
+        function delMenu(id) {
+            var node = $('.custom-tree-node[data-id="' + id + '"]');
+            var menu = node.data('menuData');
+            
+            Common.confirm('确定要删除菜单 【' + menu.menuName + '】 吗?<br><span style="color: #f56c6c; font-size: 12px;">删除后将无法恢复,请谨慎操作!</span>', function() {
+                Common.del(Config.api.menu.remove + '/' + id, function(res) {
+                    Common.success('删除成功', function() {
+                        loadMenuTree();
+                        if (currentMenu && currentMenu.id === id) {
+                            currentMenu = null;
+                            $('#detailActions').hide();
+                            $('#detailContent').html('<div class="detail-empty"><i class="layui-icon layui-icon-survey"></i><p>请选择一个菜单查看详情</p></div>');
+                        }
+                    });
+                });
+            });
+        }
+        
+        // 删除当前菜单
+        function delCurrentMenu() {
+            if (currentMenu) {
+                delMenu(currentMenu.id);
+            }
+        }
+        
+        // 初始化
+        $(function() {
+            loadMenuTree();
+        });
+    </script>
+</body>
+</html>

+ 2 - 8
ema-web/pages/role/role_form.html → ema-admin/src/main/resources/web/pages/role/role_form.html

@@ -28,13 +28,6 @@
             </div>
         </div>
         
-        <div class="layui-form-item">
-            <label class="layui-form-label"><span class="required">*</span>排序</label>
-            <div class="layui-input-block">
-                <input type="number" name="sort" lay-verify="required|number" value="0" class="layui-input" style="width: 150px;">
-            </div>
-        </div>
-        
         <div class="layui-form-item">
             <label class="layui-form-label"><span class="required">*</span>状态</label>
             <div class="layui-input-block">
@@ -58,6 +51,7 @@
         </div>
     </form>
     
+    <script src="../../lib/jquery.min.js"></script>
     <script src="../../lib/layui/layui.js"></script>
     <script src="../../js/config.js"></script>
     <script src="../../js/common.js"></script>
@@ -93,7 +87,7 @@
                         Common.success(isEdit ? '修改成功' : '添加成功', function() {
                             var index = parent.layer.getFrameIndex(window.name);
                             parent.layer.close(index);
-                            parent.table.reload('tableList');
+                            parent.layui.table.reload('tableList');
                         });
                     }
                 });

+ 4 - 4
ema-web/pages/role/role_list.html → ema-admin/src/main/resources/web/pages/role/role_list.html

@@ -61,6 +61,7 @@
         {{# } }}
     </script>
     
+    <script src="../../lib/jquery.min.js"></script>
     <script src="../../lib/layui/layui.js"></script>
     <script src="../../js/config.js"></script>
     <script src="../../js/common.js"></script>
@@ -77,11 +78,10 @@
                     { type: 'checkbox', fixed: 'left' },
                     { field: 'roleName', title: '角色名称', width: 150 },
                     { field: 'roleKey', title: '权限标识', width: 200 },
-                    { field: 'sort', title: '排序', width: 80 },
                     { field: 'status', title: '状态', width: 100, templet: '#statusTpl' },
-                    { field: 'createTime', title: '创建时间', width: 170, templet: function(d) { return Common.formatDate(d.createTime); } },
-                    { field: 'remark', title: '备注' },
-                    { fixed: 'right', title: '操作', width: 220, align: 'center', toolbar: '#toolbar' }
+                    { field: 'createTime', title: '创建时间', width: 150, templet: function(d) { return Common.formatDate(d.createTime); } },
+                    { field: 'remark', title: '备注',  width: 170,},
+                    { fixed: 'right', title: '操作',  align: 'center', toolbar: '#toolbar' }
                 ]]
             });
             

+ 1 - 0
ema-web/pages/role/role_menu.html → ema-admin/src/main/resources/web/pages/role/role_menu.html

@@ -25,6 +25,7 @@
         </div>
     </div>
     
+    <script src="../../lib/jquery.min.js"></script>
     <script src="../../lib/layui/layui.js"></script>
     <script src="../../js/config.js"></script>
     <script src="../../js/common.js"></script>

+ 1 - 0
ema-web/pages/user/update_pwd.html → ema-admin/src/main/resources/web/pages/user/update_pwd.html

@@ -40,6 +40,7 @@
         </div>
     </form>
     
+    <script src="../../lib/jquery.min.js"></script>
     <script src="../../lib/layui/layui.js"></script>
     <script src="../../js/config.js"></script>
     <script src="../../js/common.js"></script>

+ 4 - 3
ema-web/pages/user/user_form.html → ema-admin/src/main/resources/web/pages/user/user_form.html

@@ -49,12 +49,12 @@
             </div>
         </div>
         
-        <div class="layui-form-item">
+    <!--    <div class="layui-form-item">
             <label class="layui-form-label">头像</label>
             <div class="layui-input-block">
                 <input type="text" name="avatar" placeholder="请输入头像URL" class="layui-input" style="width: 300px;">
             </div>
-        </div>
+        </div>-->
         
         <div class="layui-form-item">
             <label class="layui-form-label"><span class="required">*</span>状态</label>
@@ -86,6 +86,7 @@
         </div>
     </form>
     
+    <script src="../../lib/jquery.min.js"></script>
     <script src="../../lib/layui/layui.js"></script>
     <script src="../../js/config.js"></script>
     <script src="../../js/common.js"></script>
@@ -178,7 +179,7 @@
                         Common.success(isEdit ? '修改成功' : '添加成功', function() {
                             var index = parent.layer.getFrameIndex(window.name);
                             parent.layer.close(index);
-                            parent.table.reload('tableList');
+                            parent.layui.table.reload('tableList');
                         });
                     }
                 });

+ 1 - 0
ema-web/pages/user/user_info.html → ema-admin/src/main/resources/web/pages/user/user_info.html

@@ -55,6 +55,7 @@
         </form>
     </div>
     
+    <script src="../../lib/jquery.min.js"></script>
     <script src="../../lib/layui/layui.js"></script>
     <script src="../../js/config.js"></script>
     <script src="../../js/common.js"></script>

+ 20 - 7
ema-web/pages/user/user_list.html → ema-admin/src/main/resources/web/pages/user/user_list.html

@@ -75,7 +75,18 @@
             <span class="status-red"><i class="layui-icon layui-icon-close-fill"></i> 停用</span>
         {{# } }}
     </script>
+
+    <!-- 角色名称模板 -->
+    <script type="text/html" id="roleNamesTpl">
+        {{# var roles = d.roleList || []; }}
+        {{# if(roles.length > 0) { }}
+            {{ roles.map(function(r) { return r.roleName; }).join('、') }}
+        {{# } else { }}
+            -
+        {{# } }}
+    </script>
     
+    <script src="../../lib/jquery.min.js"></script>
     <script src="../../lib/layui/layui.js"></script>
     <script src="../../js/config.js"></script>
     <script src="../../js/common.js"></script>
@@ -91,13 +102,15 @@
                 url: Config.api.user.page,
                 cols: [[
                     { type: 'checkbox', fixed: 'left' },
-                    { field: 'account', title: '账号', width: 120 },
-                    { field: 'name', title: '姓名', width: 120 },
-                    { field: 'phone', title: '手机号', width: 130 },
-                    { field: 'email', title: '邮箱', width: 180 },
-                    { field: 'status', title: '状态', width: 100, templet: '#statusTpl' },
-                    { field: 'createTime', title: '创建时间', width: 170, templet: function(d) { return Common.formatDate(d.createTime); } },
-                    { fixed: 'right', title: '操作', width: 150, align: 'center', toolbar: '#toolbar' }
+                    { field: 'account', title: '账号', width: 80 },
+                    { field: 'name', title: '姓名', width: 80 },
+                    { field: 'phone', title: '手机号', width: 100 },
+                    { field: 'email', title: '邮箱', width: 100 },
+                    { field: 'status', title: '状态', width: 80, templet: '#statusTpl' },
+                    { field: 'roles', title: '角色', width: 200, templet: '#roleNamesTpl' },
+                    { field: 'createTime', title: '创建时间', width: 100 },
+                    { field: 'remark', title: '备注', width: 150 },
+                    { fixed: 'right', title: '操作',  align: 'center', toolbar: '#toolbar' }
                 ]]
             });
             

+ 0 - 140
ema-web/pages/menu/menu_list.html

@@ -1,140 +0,0 @@
-<!DOCTYPE html>
-<html lang="zh-CN">
-<head>
-    <meta charset="UTF-8">
-    <meta name="viewport" content="width=device-width, initial-scale=1.0">
-    <title>菜单管理</title>
-    <link rel="stylesheet" href="../../lib/layui/css/layui.css">
-    <style>
-        body { padding: 15px; }
-        .search-form { margin-bottom: 15px; padding: 15px; background: #fff; border-radius: 4px; }
-        .status-green { color: #5fb878; }
-        .status-red { color: #ff5722; }
-        .menu-type { padding: 2px 8px; border-radius: 3px; font-size: 12px; }
-        .menu-type-M { background: #009688; color: #fff; }
-        .menu-type-C { background: #1E9FFF; color: #fff; }
-        .menu-type-F { background: #FFB800; color: #fff; }
-    </style>
-</head>
-<body>
-    <div class="search-form">
-        <form class="layui-form layui-form-pane" lay-filter="searchForm">
-            <div class="layui-form-item">
-                <div class="layui-inline">
-                    <label class="layui-form-label">菜单名称</label>
-                    <div class="layui-input-inline">
-                        <input type="text" name="menuName" placeholder="请输入菜单名称" class="layui-input" autocomplete="off">
-                    </div>
-                </div>
-                <div class="layui-inline">
-                    <label class="layui-form-label">状态</label>
-                    <div class="layui-input-inline">
-                        <select name="status" class="layui-select">
-                            <option value="">全部</option>
-                            <option value="1">正常</option>
-                            <option value="0">停用</option>
-                        </select>
-                    </div>
-                </div>
-                <div class="layui-inline">
-                    <button type="button" class="layui-btn" id="btnSearch"><i class="layui-icon layui-icon-search"></i> 搜索</button>
-                    <button type="reset" class="layui-btn layui-btn-primary">重置</button>
-                </div>
-            </div>
-        </form>
-    </div>
-    
-    <div class="table-toolbar">
-        <button class="layui-btn layui-btn-sm" id="btnAdd"><i class="layui-icon layui-icon-add-1"></i> 添加</button>
-    </div>
-    
-    <table id="tableList" lay-filter="tableList"></table>
-    
-    <script type="text/html" id="toolbar">
-        <a class="layui-btn layui-btn-xs" lay-event="edit"><i class="layui-icon layui-icon-edit"></i> 编辑</a>
-        <a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="del"><i class="layui-icon layui-icon-delete"></i> 删除</a>
-    </script>
-    
-    <script type="text/html" id="menuTypeTpl">
-        {{# if(d.menuType === 'M') { }}
-            <span class="menu-type menu-type-M">目录</span>
-        {{# } else if(d.menuType === 'C') { }}
-            <span class="menu-type menu-type-C">菜单</span>
-        {{# } else if(d.menuType === 'F') { }}
-            <span class="menu-type menu-type-F">按钮</span>
-        {{# } }}
-    </script>
-    
-    <script type="text/html" id="statusTpl">
-        {{# if(d.status === '1') { }}
-            <span class="status-green"><i class="layui-icon layui-icon-ok-circle"></i> 正常</span>
-        {{# } else { }}
-            <span class="status-red"><i class="layui-icon layui-icon-close-fill"></i> 停用</span>
-        {{# } }}
-    </script>
-    
-    <script src="../../lib/layui/layui.js"></script>
-    <script src="../../js/config.js"></script>
-    <script src="../../js/common.js"></script>
-    <script>
-        layui.use(['table', 'layer', 'form'], function() {
-            var table = layui.table;
-            var layer = layui.layer;
-            var form = layui.form;
-            
-            var tableIns = TableRender.init({
-                elem: '#tableList',
-                url: Config.api.menu.page,
-                cols: [[
-                    { field: 'menuName', title: '菜单名称', width: 180 },
-                    { field: 'icon', title: '图标', width: 100, templet: function(d) { return d.icon ? '<i class="layui-icon ' + d.icon + '"></i>' : '-'; } },
-                    { field: 'menuType', title: '类型', width: 80, templet: '#menuTypeTpl' },
-                    { field: 'path', title: '路由地址', width: 180 },
-                    { field: 'component', title: '组件路径', width: 200 },
-                    { field: 'perms', title: '权限标识', width: 180 },
-                    { field: 'sort', title: '排序', width: 60 },
-                    { field: 'status', title: '状态', width: 100, templet: '#statusTpl' },
-                    { fixed: 'right', title: '操作', width: 150, align: 'center', toolbar: '#toolbar' }
-                ]]
-            });
-            
-            $('#btnSearch').click(function() {
-                var data = form.val('searchForm');
-                table.reload('tableList', {
-                    where: data,
-                    page: { curr: 1 }
-                });
-            });
-            
-            $('#btnAdd').click(function() {
-                Common.open({
-                    title: '添加菜单',
-                    area: ['600px', '500px'],
-                    content: 'menu_form.html?id='
-                });
-            });
-            
-            table.on('tool(tableList)', function(obj) {
-                var data = obj.data;
-                var event = obj.event;
-                
-                if (event === 'edit') {
-                    Common.open({
-                        title: '编辑菜单',
-                        area: ['600px', '500px'],
-                        content: 'menu_form.html?id=' + data.id
-                    });
-                } else if (event === 'del') {
-                    Common.confirm('确定要删除菜单 【' + data.menuName + '】 吗?', function() {
-                        Common.del(Config.api.menu.remove + '/' + data.id, function(res) {
-                            Common.success('删除成功', function() {
-                                obj.del();
-                            });
-                        });
-                    });
-                }
-            });
-        });
-    </script>
-</body>
-</html>