Parcourir la source

1.添加角色列表和搜索功能

1 il y a 1 mois
Parent
commit
9163959d34

+ 9 - 5
imwork-windows/imwork-silos/src/main/java/top/imwork/window/silos/convert/SysRoleConvert.java

@@ -142,10 +142,12 @@ public class SysRoleConvert {
 
     public static SysRoleListDTO sysRoleListParamVoToDTO(SysRoleListParamVO sysRoleListParamVO) {
         if (sysRoleListParamVO == null) {
-            return new SysRoleListDTO();
+            return null;
         }
         SysRoleListDTO sysRoleListDTO = new SysRoleListDTO();
-        sysRoleListDTO.setSysRoleName(sysRoleListParamVO.getSysRoleName());
+        sysRoleListDTO.setRoleName(sysRoleListParamVO.getRoleName());
+        sysRoleListDTO.setRoleType(sysRoleListParamVO.getRoleType());
+        sysRoleListDTO.setEnabled(sysRoleListParamVO.getEnabled());
         sysRoleListDTO.setPageNo(sysRoleListParamVO.getPageNo());
         sysRoleListDTO.setPageRows(sysRoleListParamVO.getPageRows());
         sysRoleListDTO.setDelFlag(sysRoleListParamVO.getDelFlag());
@@ -158,13 +160,15 @@ public class SysRoleConvert {
         sysRoleListDTO.setRemark(sysRoleListParamVO.getRemark());
         return sysRoleListDTO;
     }
-        
+
     public static SysRoleListParamVO sysRoleListParamDtoToVo(SysRoleListDTO sysRoleListDTO) {
         if (sysRoleListDTO == null) {
-            return new SysRoleListParamVO();
+            return null;
         }
         SysRoleListParamVO sysRoleListParamVO = new SysRoleListParamVO();
-        sysRoleListParamVO.setSysRoleName(sysRoleListDTO.getSysRoleName());
+        sysRoleListParamVO.setRoleName(sysRoleListDTO.getRoleName());
+        sysRoleListParamVO.setRoleType(sysRoleListDTO.getRoleType());
+        sysRoleListParamVO.setEnabled(sysRoleListDTO.getEnabled());
         sysRoleListParamVO.setPageNo(sysRoleListDTO.getPageNo());
         sysRoleListParamVO.setPageRows(sysRoleListDTO.getPageRows());
         sysRoleListParamVO.setDelFlag(sysRoleListDTO.getDelFlag());

+ 5 - 7
imwork-windows/imwork-silos/src/main/java/top/imwork/window/silos/pojo/dto/SysRoleListDTO.java

@@ -1,6 +1,7 @@
 package top.imwork.window.silos.pojo.dto;
 
 
+import lombok.Data;
 import top.imwork.commons.core.pojo.BaseParams;
 
 /**
@@ -10,14 +11,11 @@ import top.imwork.commons.core.pojo.BaseParams;
  * email: e-jiangxiaowei@outlook.com
  * date: 2025-12-09 16:29:22
  */
+@Data
 public class SysRoleListDTO extends BaseParams {
-    private String sysRoleName;
+    private String roleName;
 
-    public String getSysRoleName() {
-        return sysRoleName;
-    }
+    private String roleType;
 
-    public void setSysRoleName(String sysRoleName) {
-        this.sysRoleName = sysRoleName;
-    }
+    private Integer enabled;
 }

+ 6 - 7
imwork-windows/imwork-silos/src/main/java/top/imwork/window/silos/pojo/po/SysRoleListParamVO.java

@@ -1,6 +1,7 @@
 package top.imwork.window.silos.pojo.po;
 
 
+import lombok.Data;
 import top.imwork.commons.core.pojo.BaseParams;
 
 /**
@@ -10,14 +11,12 @@ import top.imwork.commons.core.pojo.BaseParams;
  * email: e-jiangxiaowei@outlook.com
  * date: 2025-12-09 16:29:22
  */
+@Data
 public class SysRoleListParamVO extends BaseParams {
-    private String SysRoleName;
+    private String roleName;
 
-    public String getSysRoleName() {
-        return SysRoleName;
-    }
+    private String roleType;
+
+    private Integer enabled;
 
-    public void setSysRoleName(String sysRoleName) {
-        SysRoleName = sysRoleName;
-    }
 }

+ 24 - 11
imwork-windows/imwork-silos/src/main/java/top/imwork/window/silos/service/impl/SysRoleServiceImpl.java

@@ -1,12 +1,12 @@
 package top.imwork.window.silos.service.impl;
 
+import com.github.pagehelper.PageHelper;
+import com.github.pagehelper.PageInfo;
 import org.springframework.stereotype.Service;
 import org.springframework.util.ObjectUtils;
 import jakarta.annotation.Resource;
 
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
-import com.baomidou.mybatisplus.core.metadata.IPage;
-import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 
 import top.imwork.commons.core.utils.StringUtils;
@@ -19,13 +19,16 @@ import top.imwork.window.silos.pojo.dto.SysRoleListDTO;
 import top.imwork.window.silos.service.ISysRoleService;
 import top.imwork.window.silos.convert.SysRoleConvert;
 
+import java.util.List;
+
 @Service("sysRoleService")
-public class SysRoleServiceImpl extends ServiceImpl<SysRoleDao,SysRole> implements ISysRoleService {
+public class SysRoleServiceImpl extends ServiceImpl<SysRoleDao, SysRole> implements ISysRoleService {
     @Resource
     private SysRoleDao sysRoleDao;
 
     /**
      * 根据id获取信息
+     *
      * @param id 用户id
      * @return SysRoleBO 响应信息
      */
@@ -37,6 +40,7 @@ public class SysRoleServiceImpl extends ServiceImpl<SysRoleDao,SysRole> implemen
 
     /**
      * 新增/更新信息
+     *
      * @param sysRoleDTO 信息
      * @return sysRoleBO 更新后信息
      */
@@ -53,6 +57,7 @@ public class SysRoleServiceImpl extends ServiceImpl<SysRoleDao,SysRole> implemen
 
     /**
      * 根据id删除信息
+     *
      * @param id id
      * @return true/false 是否删除成功
      */
@@ -70,8 +75,16 @@ public class SysRoleServiceImpl extends ServiceImpl<SysRoleDao,SysRole> implemen
     public SysRoleResultBO queryPage(SysRoleListDTO sysRoleListDTO) {
         QueryWrapper<SysRole> queryWrapper = new QueryWrapper<>();
 
-        if (!StringUtils.isEmpty(sysRoleListDTO.getSysRoleName())) {
-            queryWrapper.like("sysRole_name", sysRoleListDTO.getSysRoleName());
+        if (!StringUtils.isEmpty(sysRoleListDTO.getRoleName())) {
+            queryWrapper.like("role_name", sysRoleListDTO.getRoleName());
+        }
+
+        if (!StringUtils.isEmpty(sysRoleListDTO.getRoleType())) {
+            queryWrapper.like("role_type", sysRoleListDTO.getRoleType());
+        }
+
+        if (!StringUtils.isEmpty(sysRoleListDTO.getEnabled())) {
+            queryWrapper.like("enabled", sysRoleListDTO.getEnabled());
         }
 
         if (!StringUtils.isEmpty(sysRoleListDTO.getCreateBeginTime())) {
@@ -89,16 +102,16 @@ public class SysRoleServiceImpl extends ServiceImpl<SysRoleDao,SysRole> implemen
         if (!StringUtils.isEmpty(sysRoleListDTO.getUpdateEndTime())) {
             queryWrapper.apply("update_time <= '" + sysRoleListDTO.getUpdateEndTime() + "'");
         }
-
-        Page<SysRole> page = new Page<>(sysRoleListDTO.getPageNo(), sysRoleListDTO.getPageRows());
-        IPage<SysRole> iPage = sysRoleDao.queryPage(page, queryWrapper);
+        PageHelper.startPage(sysRoleListDTO.getPageNo(), sysRoleListDTO.getPageRows());
+        List<SysRole> list = sysRoleDao.selectList(queryWrapper);
+        PageInfo<SysRole> pageInfo = new PageInfo<>(list);
 
         SysRoleResultBO resultBO = new SysRoleResultBO();
         resultBO.setPageNo(sysRoleListDTO.getPageNo());
         resultBO.setPageRows(sysRoleListDTO.getPageRows());
-        resultBO.setPageCount((int) iPage.getPages());
-        resultBO.setTotalRows((int) iPage.getTotal());
-        resultBO.setDataList(SysRoleConvert.sysRoleListToSysRoleBOList(iPage.getRecords()));
+        resultBO.setPageCount(pageInfo.getPages());
+        resultBO.setTotalRows((int) pageInfo.getTotal());
+        resultBO.setDataList(SysRoleConvert.sysRoleListToSysRoleBOList(list));
         resultBO.setParams(sysRoleListDTO);
 
         return resultBO;

+ 559 - 0
imwork-windows/imwork-silos/src/main/resources/static/business/upms/role/css/list.css

@@ -0,0 +1,559 @@
+:root {
+    --primary: #4361ee;
+    --secondary: #3f37c9;
+    --success: #4cc9f0;
+    --warning: #f72585;
+    --light: #f8f9fa;
+    --dark: #212529;
+    --gray: #6c757d;
+    --light-gray: #e9ecef;
+    --border-radius: 8px;
+    --box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
+    --transition: all 0.3s ease;
+}
+
+* {
+    margin: 0;
+    padding: 0;
+    box-sizing: border-box;
+    font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
+}
+
+body {
+    background-color: #f5f7fb;
+    color: var(--dark);
+    line-height: 1.6;
+}
+
+.container {
+    max-width: 1400px;
+    margin: 0 auto;
+    padding: 20px;
+}
+
+header {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    margin-bottom: 30px;
+    padding-bottom: 15px;
+    border-bottom: 1px solid var(--light-gray);
+}
+
+.header-title h1 {
+    font-size: 28px;
+    color: var(--primary);
+    display: flex;
+    align-items: center;
+    gap: 10px;
+}
+
+.header-title p {
+    color: var(--gray);
+    font-size: 14px;
+}
+
+.user-info {
+    display: flex;
+    align-items: center;
+    gap: 15px;
+}
+
+.user-avatar {
+    width: 40px;
+    height: 40px;
+    border-radius: 50%;
+    background-color: var(--primary);
+    color: white;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    font-weight: bold;
+}
+
+.dashboard-cards {
+    display: grid;
+    grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
+    gap: 20px;
+    margin-bottom: 30px;
+}
+
+.card {
+    background: white;
+    border-radius: var(--border-radius);
+    box-shadow: var(--box-shadow);
+    padding: 20px;
+    transition: var(--transition);
+}
+
+.card:hover {
+    transform: translateY(-5px);
+    box-shadow: 0 6px 12px rgba(0, 0, 0, 0.15);
+}
+
+.card-icon {
+    width: 50px;
+    height: 50px;
+    border-radius: 50%;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    margin-bottom: 15px;
+    font-size: 20px;
+}
+
+.card-title {
+    font-size: 14px;
+    color: var(--gray);
+    margin-bottom: 5px;
+}
+
+.card-value {
+    font-size: 24px;
+    font-weight: bold;
+    margin-bottom: 10px;
+}
+
+.card-trend {
+    font-size: 12px;
+    display: flex;
+    align-items: center;
+    gap: 5px;
+}
+
+.trend-up {
+    color: #28a745;
+}
+
+.trend-down {
+    color: #dc3545;
+}
+
+.card-total {
+    background: linear-gradient(135deg, #4361ee, #3a0ca3);
+    color: white;
+}
+
+.card-active {
+    background: linear-gradient(135deg, #4cc9f0, #4895ef);
+    color: white;
+}
+
+.card-admin {
+    background: linear-gradient(135deg, #7209b7, #560bad);
+    color: white;
+}
+
+.card-system {
+    background: linear-gradient(135deg, #f72585, #b5179e);
+    color: white;
+}
+
+.search-section {
+    background: white;
+    border-radius: var(--border-radius);
+    box-shadow: var(--box-shadow);
+    padding: 20px;
+    margin-bottom: 30px;
+}
+
+.search-row {
+    display: grid;
+    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
+    gap: 15px;
+    margin-bottom: 15px;
+}
+
+.form-group {
+    margin-bottom: 15px;
+}
+
+.form-group label {
+    display: block;
+    margin-bottom: 5px;
+    font-size: 14px;
+    font-weight: 500;
+}
+
+.form-control {
+    width: 100%;
+    padding: 10px 15px;
+    border: 1px solid var(--light-gray);
+    border-radius: var(--border-radius);
+    font-size: 14px;
+    transition: var(--transition);
+}
+
+.form-control:focus {
+    outline: none;
+    border-color: var(--primary);
+    box-shadow: 0 0 0 3px rgba(67, 97, 238, 0.2);
+}
+
+.btn {
+    padding: 10px 20px;
+    border: none;
+    border-radius: var(--border-radius);
+    cursor: pointer;
+    font-size: 14px;
+    font-weight: 500;
+    transition: var(--transition);
+    display: inline-flex;
+    align-items: center;
+    gap: 8px;
+}
+
+.btn-primary {
+    background-color: var(--primary);
+    color: white;
+}
+
+.btn-primary:hover {
+    background-color: var(--secondary);
+}
+
+.btn-success {
+    background-color: #28a745;
+    color: white;
+}
+
+.btn-success:hover {
+    background-color: #218838;
+}
+
+.btn-warning {
+    background-color: #ffc107;
+    color: var(--dark);
+}
+
+.btn-warning:hover {
+    background-color: #e0a800;
+}
+
+.btn-danger {
+    background-color: #dc3545;
+    color: white;
+}
+
+.btn-danger:hover {
+    background-color: #c82333;
+}
+
+.btn-light {
+    background-color: var(--light-gray);
+    color: var(--dark);
+}
+
+.btn-light:hover {
+    background-color: #dae0e5;
+}
+
+.search-actions {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    margin-top: 20px;
+}
+
+.table-container {
+    background: white;
+    border-radius: var(--border-radius);
+    box-shadow: var(--box-shadow);
+    overflow: hidden;
+    margin-bottom: 30px;
+}
+
+.table-header {
+    padding: 20px;
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    border-bottom: 1px solid var(--light-gray);
+}
+
+.table-title {
+    font-size: 18px;
+    font-weight: 600;
+}
+
+table {
+    width: 100%;
+    border-collapse: collapse;
+}
+
+thead {
+    background-color: #f8f9fa;
+}
+
+th, td {
+    padding: 15px;
+    text-align: left;
+    border-bottom: 1px solid var(--light-gray);
+}
+
+th {
+    font-weight: 600;
+    color: var(--gray);
+    font-size: 14px;
+}
+
+tbody tr:hover {
+    background-color: #f8f9fa;
+}
+
+.status-badge {
+    padding: 5px 10px;
+    border-radius: 20px;
+    font-size: 12px;
+    font-weight: 500;
+}
+
+.status-active {
+    background-color: #d4edda;
+    color: #155724;
+}
+
+.status-inactive {
+    background-color: #f8d7da;
+    color: #721c24;
+}
+
+.role-level-1 { color: #4361ee; }
+.role-level-2 { color: #3a0ca3; }
+.role-level-3 { color: #7209b7; }
+.role-level-4 { color: #f72585; }
+.role-level-5 { color: #4cc9f0; }
+
+.role-tree {
+    display: flex;
+    align-items: center;
+    gap: 5px;
+}
+
+.tree-indent {
+    width: 20px;
+    display: inline-block;
+}
+
+.tree-toggle {
+    cursor: pointer;
+    color: var(--gray);
+    width: 16px;
+    text-align: center;
+}
+
+.actions {
+    display: flex;
+    gap: 10px;
+}
+
+.action-btn {
+    width: 32px;
+    height: 32px;
+    border-radius: 50%;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    cursor: pointer;
+    transition: var(--transition);
+}
+
+.edit-btn {
+    background-color: rgba(255, 193, 7, 0.2);
+    color: #ffc107;
+}
+
+.edit-btn:hover {
+    background-color: #ffc107;
+    color: white;
+}
+
+.delete-btn {
+    background-color: rgba(220, 53, 69, 0.2);
+    color: #dc3545;
+}
+
+.delete-btn:hover {
+    background-color: #dc3545;
+    color: white;
+}
+
+.permission-btn {
+    background-color: rgba(67, 97, 238, 0.2);
+    color: #4361ee;
+}
+
+.permission-btn:hover {
+    background-color: #4361ee;
+    color: white;
+}
+
+.pagination {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    padding: 20px;
+    border-top: 1px solid var(--light-gray);
+}
+
+.pagination-info {
+    font-size: 14px;
+    color: var(--gray);
+}
+
+.pagination-controls {
+    display: flex;
+    gap: 10px;
+}
+
+.page-btn {
+    width: 36px;
+    height: 36px;
+    border-radius: 50%;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    background-color: white;
+    border: 1px solid var(--light-gray);
+    cursor: pointer;
+    transition: var(--transition);
+}
+
+.page-btn.active {
+    background-color: var(--primary);
+    color: white;
+    border-color: var(--primary);
+}
+
+.page-btn:hover:not(.active) {
+    background-color: var(--light-gray);
+}
+
+.modal {
+    display: none;
+    position: fixed;
+    top: 0;
+    left: 0;
+    width: 100%;
+    height: 100%;
+    background-color: rgba(0, 0, 0, 0.5);
+    z-index: 1000;
+    align-items: center;
+    justify-content: center;
+}
+
+.modal-content {
+    background-color: white;
+    border-radius: var(--border-radius);
+    width: 90%;
+    max-width: 700px;
+    max-height: 90vh;
+    overflow-y: auto;
+    box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);
+}
+
+.modal-header {
+    padding: 20px;
+    border-bottom: 1px solid var(--light-gray);
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+}
+
+.modal-title {
+    font-size: 20px;
+    font-weight: 600;
+}
+
+.close-btn {
+    background: none;
+    border: none;
+    font-size: 24px;
+    cursor: pointer;
+    color: var(--gray);
+}
+
+.modal-body {
+    padding: 20px;
+}
+
+.modal-footer {
+    padding: 20px;
+    border-top: 1px solid var(--light-gray);
+    display: flex;
+    justify-content: flex-end;
+    gap: 10px;
+}
+
+.form-row {
+    display: grid;
+    grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
+    gap: 15px;
+    margin-bottom: 15px;
+}
+
+.required::after {
+    content: " *";
+    color: #dc3545;
+}
+
+.permission-section {
+    margin-top: 30px;
+    border-top: 1px solid var(--light-gray);
+    padding-top: 20px;
+}
+
+.permission-grid {
+    display: grid;
+    grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
+    gap: 15px;
+    margin-top: 15px;
+}
+
+.permission-item {
+    display: flex;
+    align-items: center;
+    gap: 10px;
+    padding: 10px;
+    border: 1px solid var(--light-gray);
+    border-radius: var(--border-radius);
+    transition: var(--transition);
+}
+
+.permission-item:hover {
+    background-color: #f8f9fa;
+}
+
+.permission-item input[type="checkbox"] {
+    width: 18px;
+    height: 18px;
+}
+
+@media (max-width: 768px) {
+    .search-row {
+        grid-template-columns: 1fr;
+    }
+
+    .table-header {
+        flex-direction: column;
+        align-items: flex-start;
+        gap: 15px;
+    }
+
+    .table-container {
+        overflow-x: auto;
+    }
+
+    table {
+        min-width: 800px;
+    }
+
+    .pagination {
+        flex-direction: column;
+        gap: 15px;
+    }
+
+    .permission-grid {
+        grid-template-columns: 1fr;
+    }
+}

+ 356 - 0
imwork-windows/imwork-silos/src/main/resources/static/business/upms/role/js/list.js

@@ -0,0 +1,356 @@
+layui.use(['form', 'layer', 'table', 'laytpl', 'jquery'], function () {
+    var form = layui.form,
+        layer = parent.layer === undefined ? layui.layer : top.layer,
+        $ = layui.$,
+        laytpl = layui.laytpl,
+        table = layui.table;
+
+    // 缓存常用DOM元素
+    var $searchBtn = $(".search_btn"),
+        $roleName = $("#roleName"),
+        $roleType = $("#roleType"),
+        $enabled = $("#enabled"),
+        $addBtn = $(".add_btn"),
+        $delAllBtn = $(".delAll_btn"),
+        $allotBtn = $(".allot_btn"),
+        $resetBtn = $(".reset_btn");
+
+    // 配置常量
+    var TABLE_CONFIG = {
+        elem: '#list',
+        url: '/upms/sysrole/queryPage',
+        method: 'POST',
+        dataType: 'json',
+        contentType: 'application/json;charset=utf-8',
+        headers: { token: '' },
+        cellMinWidth: 95,
+        page: true,
+        height: "full-125",
+        limits: [10, 15, 20, 25],
+        limit: 15,
+        id: "listTable",
+        request: {
+            pageName: "pageNo",
+            limitName: "pageRows"
+        },
+        response: {
+            statusName: 'code',
+            statusCode: 200,
+            msgName: 'msg',
+            countName: 'totalRows',
+            dataName: 'data'
+        },
+        parseData: function (res) {
+            return {
+                "code": res.code,
+                "msg": res.msg,
+                "totalRows": res.data.totalRows,
+                "data": res.data.dataList
+            };
+        }
+    };
+
+    // 表格列配置
+    var TABLE_COLS = [[
+        { type: "checkbox", fixed: "left", width: 50 },
+        { field: 'roleName', title: '角色名称', minWidth: 100, align: "center" },
+        { field: 'roleDesc', title: '角色详情', minWidth: 100, align: "center" },
+        {
+            field: 'roleType', title: '角色类型', align: 'center', templet: function (d) {
+                var roleTypeMap = {
+                    "0": "默认角色",
+                    "1": "普通管理员",
+                    "2": "系统管理员",
+                    "3": "区域管理员",
+                    "9": "超级管理员"
+                };
+                return roleTypeMap[d.roleType] || "异常角色";
+            }
+        },
+        {
+            field: 'createTime', title: '创建时间', minWidth: 100, align: "center",
+            templet: function (d) { return formatDateTime(d.createTime); }
+        },
+        {
+            field: 'updateTime', title: '更新时间', align: 'center', minWidth: 150,
+            templet: function (d) { return formatDateTime(d.updateTime); }
+        },
+        { title: '操作', minWidth: 175, templet: '#listBar', fixed: "right", align: "center" }
+    ]];
+
+    // 初始化表格
+    var tableIns = table.render(Object.assign({}, TABLE_CONFIG, {
+        cols: TABLE_COLS
+    }));
+    // 刷新
+    $('.refresh').click(() => location.reload());
+    // 事件绑定
+    function bindEvents() {
+        // 搜索功能
+        $searchBtn.on("click", handleSearch);
+
+        // 重置功能
+        if ($resetBtn.length > 0) {
+            $resetBtn.on("click", handleReset);
+        }
+
+        // 添加角色
+        $addBtn.click(function () {
+            openDialog("添加角色", "/upms/sysrole/update");
+        });
+
+        // 批量删除
+        $delAllBtn.click(handleBatchDelete);
+
+        // 分配权限
+        $allotBtn.click(handleAllotPermission);
+
+        // 表格行操作
+        table.on('tool(list)', handleTableRowAction);
+    }
+
+    // 搜索处理
+    function handleSearch() {
+        const keyword = $roleName.val().trim();
+        const roleType = $roleType.val();
+        const enabled = $enabled.val();
+
+        table.reload("listTable", {
+            page: { curr: 1 },
+            where: { roleName: keyword,
+                roleType: roleType,
+                enabled: enabled
+            }
+        });
+    }
+
+    // 重置处理
+    function handleReset() {
+        // 1. 清空搜索框
+        $roleName.val('');
+
+        // 2. 重置表单元素(如果有其他表单元素)
+        resetFormElements();
+
+        // 3. 可选:显示重置成功提示
+        //layui.layer.msg("搜索条件已重置", { icon: 1, time: 1000 });
+    }
+
+    // 重置表单元素
+    function resetFormElements() {
+        // 重置下拉框
+        $("select").each(function() {
+            var $select = $(this);
+            var defaultValue = $select.data('default-value') || $select.find("option:first").val();
+            $select.val(defaultValue);
+        });
+
+        // 重置单选/复选框
+        $("input[type='radio'], input[type='checkbox']").each(function() {
+            var $input = $(this);
+            if ($input.prop('defaultChecked')) {
+                $input.prop('checked', true);
+            } else {
+                $input.prop('checked', false);
+            }
+        });
+
+        // 重置其他输入框
+        $("input[type='text'], input[type='number'], textarea").not(".searchVal").each(function() {
+            var $input = $(this);
+            var defaultValue = $input.data('default-value') || '';
+            $input.val(defaultValue);
+        });
+
+        // 重新渲染表单
+        form.render();
+    }
+
+    // 批量删除处理
+    function handleBatchDelete() {
+        var checkStatus = table.checkStatus('listTable');
+        var data = checkStatus.data;
+
+        if (data.length === 0) {
+            layer.msg("请选择需要删除的条目!");
+            return;
+        }
+
+        var ids = data.map(function (item) {
+            return item.id;
+        });
+
+        layer.confirm('确定删除选中的' + data.length + '个条目?', {
+            icon: 3,
+            title: '提示信息'
+        }, function (index) {
+            deleteRoles(ids, index);
+        });
+    }
+
+    // 分配权限处理
+    function handleAllotPermission() {
+        var checkStatus = table.checkStatus('listTable');
+        var data = checkStatus.data;
+
+        if (data.length === 0) {
+            layer.msg("请选择需要分配权限的角色");
+            return;
+        }
+
+        var ids = data.map(function (item) {
+            return item.id;
+        });
+
+        openDialog('分配权限', "/upms/sysrole/allot?ids=" + ids.join(','));
+    }
+
+    // 表格行操作处理
+    function handleTableRowAction(obj) {
+        var layEvent = obj.event,
+            data = obj.data;
+
+        switch (layEvent) {
+            case 'edit':
+                openDialog("编辑角色", "/upms/sysrole/update", data);
+                break;
+            case 'del':
+                confirmDelete(data.id);
+                break;
+            case 'usable':
+                toggleUserStatus($(this), data.id);
+                break;
+        }
+    }
+
+    // 通用弹窗函数
+    function openDialog(title, url, data) {
+        var index = layui.layer.open({
+            title: title,
+            type: 2,
+            content: url,
+            area: ['95%', '95%'],
+            maxmin: true,
+            success: function (layero, index) {
+                // 如果有数据,传递给子窗口
+                if (data) {
+                    var body = layui.layer.getChildFrame('body', index);
+                    // 这里可以根据实际需要传递数据给子页面
+                    // body.find(...).val(...);
+                }
+
+                // 添加关闭提示
+                setTimeout(function () {
+                    layer.tips('点击此处返回角色列表', '.layui-layer-setwin .layui-layer-close', {
+                        tips: 3
+                    });
+                }, 500);
+            },
+            end: function () {
+                // 对话框关闭后刷新表格
+                tableIns.reload();
+            }
+        });
+    }
+
+    // 删除角色(支持批量)
+    function deleteRoles(ids, layerIndex) {
+        $.ajax({
+            url: "/upms/sysrole/deleteInfoByIds/" + (Array.isArray(ids) ? ids.join(',') : ids),
+            type: "POST",
+            dataType: "json",
+            contentType: 'application/json;charset=UTF-8'
+        })
+            .done(function (res) {
+                if (res.code === 200) {
+                    layer.msg(res.msg || "删除成功", { icon: 1 });
+                    tableIns.reload();
+                } else {
+                    layer.msg(res.msg || "删除失败", { icon: 2 });
+                }
+            })
+            .fail(function (xhr, status, error) {
+                layer.msg("请求失败: " + error, { icon: 2 });
+            })
+            .always(function () {
+                if (layerIndex) layer.close(layerIndex);
+            });
+    }
+
+    // 确认删除单个
+    function confirmDelete(id) {
+        layer.confirm('确定删除此角色?', {
+            icon: 3,
+            title: '提示信息'
+        }, function (index) {
+            deleteRoles(id, index);
+        });
+    }
+
+    // 切换用户状态
+    function toggleUserStatus($element, userId) {
+        var currentText = $element.text();
+        var confirmText = currentText === "已禁用" ?
+            "是否确定启用此用户?" : "是否确定禁用此用户?";
+
+        layer.confirm(confirmText, {
+            icon: 3,
+            title: '系统提示'
+        }, function (index) {
+            // 这里应该发送AJAX请求更新状态
+            // $.post('/upms/user/toggleStatus', {id: userId}, function(res) {...});
+
+            $element.text(currentText === "已禁用" ? "已启用" : "已禁用");
+            layer.close(index);
+        });
+    }
+
+    // 格式化时间
+    function formatDateTime(timestamp) {
+        if (!timestamp) return '';
+
+        var date = new Date(timestamp);
+
+        // 检查日期是否有效
+        if (isNaN(date.getTime())) return '';
+
+        var pad = function (num) {
+            return num < 10 ? '0' + num : num;
+        };
+
+        return date.getFullYear() + '-' +
+            pad(date.getMonth() + 1) + '-' +
+            pad(date.getDate()) + ' ' +
+            pad(date.getHours()) + ':' +
+            pad(date.getMinutes()) + ':' +
+            pad(date.getSeconds());
+    }
+
+    // 防抖函数(用于搜索优化)
+    function debounce(func, wait) {
+        var timeout;
+        return function () {
+            var context = this,
+                args = arguments;
+            clearTimeout(timeout);
+            timeout = setTimeout(function () {
+                func.apply(context, args);
+            }, wait);
+        };
+    }
+
+    // 初始化
+    $(function () {
+        bindEvents();
+
+        // 添加搜索框回车事件
+        $searchVal.on('keypress', function (e) {
+            if (e.which === 13) {
+                handleSearch();
+            }
+        });
+
+        // 可选:添加搜索防抖(500ms)
+        // $searchVal.on('input', debounce(handleSearch, 500));
+    });
+});

+ 129 - 52
imwork-windows/imwork-silos/src/main/resources/templates/upms/role/list.html

@@ -1,61 +1,138 @@
 <!DOCTYPE html>
-<html lang="en" xmlns:th="http://www.thymeleaf.org">
+<html lang="zh-CN" xmlns:th="http://www.thymeleaf.org">
 <head>
-    <meta charset="utf-8">
-    <title>角色管理</title>
+    <meta charset="UTF-8">
+    <meta http-equiv="X-UA-Compatible" content="IE=edge,Chrome=1">
+    <!-- Google Chrome Frame也可以让IE用上Chrome的引擎: -->
     <meta name="renderer" content="webkit">
-    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
-    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
-    <meta name="apple-mobile-web-app-status-bar-style" content="black">
-    <meta name="apple-mobile-web-app-capable" content="yes">
-    <meta name="format-detection" content="telephone=no">
-
-    <link rel="shortcut icon" href="../../../assets/images/logo/logo.png" th:href="@{/assets/images/logo/logo.png}"/>
-    <link rel="bookmark" href="../../../assets/images/logo/logo.png" th:href="@{/assets/images/logo/logo.png}"/>
-    <link rel="stylesheet" href="../../../assets/lib/layui/css/layui.css" th:href="@{/assets/lib/layui/css/layui.css}"/>
-    <link rel="stylesheet" href="../../../assets/lib/font/css/font-awesome.css" th:href="@{/assets/lib/font/css/font-awesome.css}"/>
-    <link rel="stylesheet" href="../../../assets/css/admin.css" th:href="@{/assets/css/admin.css}"/>
+    <!--国产浏览器高速模式-->
+    <meta name="viewport" content="width=device-width, initial-scale=1">
+    <!-- 作者 -->
+    <meta name="author" content="silos"/>
+    <meta name="revised" content="Silos-Admin-v-2.0.0"/>
+    <!-- 定义页面的最新版本 -->
+    <meta name="description" content="网站简介"/>
+    <!-- 网站简介 -->
+    <meta name="keywords" content="搜索关键字,以半角英文逗号隔开"/>
+    <title>Index</title>
+    <!-- 公共样式 开始 -->
+    <link rel="shortcut icon" href="../../../static/assets/silos/img/favicon.png"
+          th:href="@{/assets/silos/img/favicon.png}"/>
+    <link rel="bookmark" href="../../../static/assets/silos/img/favicon.png"
+          th:href="@{/assets/silos/img/favicon.png}"/>
+    <link rel="stylesheet" href="../../../static/assets/lib/layui/css/layui.css"
+          th:href="@{/assets/lib/layui/css/layui.css}"/>
+    <link rel="stylesheet" href="../../../static/assets/lib/fonts/fontawesome6/css/all.css"
+          th:href="@{/assets/lib/fonts/fontawesome6/css/all.css}"/>
+    <link rel="stylesheet" href="../../../static/business/upms/role/css/list.css" th:href="@{/business/upms/role/css/list.css}"/>
 </head>
-<body class="childrenBody">
-<div class="layui-card">
-    <div class="layui-card-body">
-        <form class="layui-form">
-            <blockquote class="layui-elem-quote quoteBox">
-                <form class="layui-form">
-                    <div class="layui-inline">
-                        <div class="layui-input-inline">
-                            <input type="text" class="layui-input searchVal" placeholder="请输入搜索的内容"/>
-                        </div>
-                        <a class="layui-btn search_btn" data-type="reload">搜索</a>
-                    </div>
-                    <div class="layui-inline"><a class="layui-btn layui-btn-primary allot_btn">分配</a></div>
-                    <div class="layui-inline">
-                        <a class="layui-btn layui-btn-normal add_btn">添加</a>
-                    </div>
-                    <div class="layui-inline">
-                        <a class="layui-btn layui-btn-warm add_btn">编辑</a>
-                    </div>
-                    <div class="layui-inline">
-                        <a class="layui-btn layui-btn-danger layui-btn-normal delAll_btn">删除</a>
-                    </div>
-                    <div class="layui-inline"><a class="layui-btn layui-btn-normal refresh"><i
-                            class="layui-icon layui-icon-refresh-3"></i>刷新</a></div>
-                </form>
-            </blockquote>
-            <table id="list" lay-filter="list"></table>
+<body>
+<div class="container">
+    <div class="dashboard-cards">
+        <div class="card card-total">
+            <div class="card-icon">
+                <i class="fas fa-tags"></i>
+            </div>
+            <div class="card-title">总角色数</div>
+            <div class="card-value">48</div>
+            <div class="card-trend trend-up">
+                <i class="fas fa-arrow-up"></i> 3.2% 较上月
+            </div>
+        </div>
+        <div class="card card-active">
+            <div class="card-icon">
+                <i class="fas fa-toggle-on"></i>
+            </div>
+            <div class="card-title">启用角色</div>
+            <div class="card-value">42</div>
+            <div class="card-trend trend-up">
+                <i class="fas fa-arrow-up"></i> 1.8% 较上月
+            </div>
+        </div>
+        <div class="card card-admin">
+            <div class="card-icon">
+                <i class="fas fa-user-shield"></i>
+            </div>
+            <div class="card-title">管理员角色</div>
+            <div class="card-value">12</div>
+            <div class="card-trend trend-up">
+                <i class="fas fa-arrow-up"></i> 0.5% 较上月
+            </div>
+        </div>
+        <div class="card card-system">
+            <div class="card-icon">
+                <i class="fas fa-cogs"></i>
+            </div>
+            <div class="card-title">系统角色</div>
+            <div class="card-value">6</div>
+            <div class="card-trend trend-down">
+                <i class="fas fa-arrow-down"></i> 0.2% 较上月
+            </div>
+        </div>
+    </div>
 
-            <!--操作-->
-            <script type="text/html" id="listBar">
-                <a class="layui-btn layui-btn-xs layui-btn-warm" lay-event="edit">编辑</a>
-                <a class="layui-btn layui-btn-xs layui-btn-danger" lay-event="del">删除</a>
-            </script>
-        </form>
+    <div class="search-section">
+        <div class="search-row">
+            <div class="form-group">
+                <label for="roleName">角色名称</label>
+                <input type="text" id="roleName" class="form-control" placeholder="输入角色名称">
+            </div>
+            <div class="form-group">
+                <label for="roleType">角色类型</label>
+                <select id="roleType" class="form-control">
+                    <option value="">全部</option>
+                    <option value="0">普通角色</option>
+                    <option value="1">普通管理员</option>
+                    <option value="2">区域管理员</option>
+                    <option value="3">平台管理员</option>
+                    <option value="5">系统管理员</option>
+                    <option value="9">超级管理员</option>
+                </select>
+            </div>
+            <div class="form-group">
+                <label for="enabled">启用状态</label>
+                <select id="enabled" class="form-control">
+                    <option value="">全部</option>
+                    <option value="1">启用</option>
+                    <option value="0">禁用</option>
+                </select>
+            </div>
+        </div>
+        <div class="search-actions">
+            <div>
+                <button class="btn btn-light reset_btn">
+                    <i class="fas fa-redo"></i> 重置
+                </button>
+                <button class="btn btn-info refresh">
+                    <i class="fas fa-redo"></i> 刷新
+                </button>
+                <button class="btn btn-success add_btn">
+                    <i class="fa-solid fa-person-circle-plus"></i> 添加角色
+                </button>
+                <button class="btn btn-warning allot_btn">
+                    <i class="fa-solid fa-person-circle-plus"></i> 分配权限
+                </button>
+                <button class="btn btn-danger delAll_btn">
+                    <i class="fa-regular fa-trash-can"></i> 批量删除
+                </button>
+            </div>
+            <div>
+                <button class="btn btn-primary search_btn">
+                    <i class="fas fa-search"></i> 搜索
+                </button>
+            </div>
+        </div>
     </div>
+    <table id="list" lay-filter="list"></table>
+    <!--操作-->
+    <script type="text/html" id="listBar">
+        <a class="layui-btn layui-btn-xs" lay-event="edit">编辑</a>
+        <a class="layui-btn layui-btn-xs layui-btn-warm" lay-event="usable">已启用</a>
+        <a class="layui-btn layui-btn-xs layui-btn-danger" lay-event="del">删除</a>
+    </script>
 </div>
-
-<script src="../../../assets/lib/jquery/jquery.min.js" th:src="@{/assets/lib/jquery/jquery.min.js}"></script>
-<script src="../../../assets/lib/layui/layui.js" th:src="@{/assets/lib/layui/layui.js}"></script>
-<script src="../../../assets/js/admin.js" th:src="@{/assets/js/admin.js}"></script>
-<script type="text/javascript" src="../../../static/business/upms/role/list.js" th:src="@{/business/upms/role/list.js}"></script>
+<script src="../../../static/assets/lib/jquery/jquery.js" th:src="@{/assets/lib/jquery/jquery.js}"></script>
+<script src="../../../static/assets/lib/layui/layui.js" th:src="@{/assets/lib/layui/layui.js}"></script>
+<script src="../../../static/business/upms/role/js/list.js" th:src="@{/business/upms/role/js/list.js}"></script>
 </body>
 </html>

+ 61 - 0
配套资料/模块/upms/role/list.html

@@ -0,0 +1,61 @@
+<!DOCTYPE html>
+<html lang="en" xmlns:th="http://www.thymeleaf.org">
+<head>
+    <meta charset="utf-8">
+    <title>角色管理</title>
+    <meta name="renderer" content="webkit">
+    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
+    <meta name="apple-mobile-web-app-status-bar-style" content="black">
+    <meta name="apple-mobile-web-app-capable" content="yes">
+    <meta name="format-detection" content="telephone=no">
+
+    <link rel="shortcut icon" href="../../../assets/images/logo/logo.png" th:href="@{/assets/images/logo/logo.png}"/>
+    <link rel="bookmark" href="../../../assets/images/logo/logo.png" th:href="@{/assets/images/logo/logo.png}"/>
+    <link rel="stylesheet" href="../../../assets/lib/layui/css/layui.css" th:href="@{/assets/lib/layui/css/layui.css}"/>
+    <link rel="stylesheet" href="../../../assets/lib/font/css/font-awesome.css" th:href="@{/assets/lib/font/css/font-awesome.css}"/>
+    <link rel="stylesheet" href="../../../assets/css/admin.css" th:href="@{/assets/css/admin.css}"/>
+</head>
+<body class="childrenBody">
+<div class="layui-card">
+    <div class="layui-card-body">
+        <form class="layui-form">
+            <blockquote class="layui-elem-quote quoteBox">
+                <form class="layui-form">
+                    <div class="layui-inline">
+                        <div class="layui-input-inline">
+                            <input type="text" class="layui-input searchVal" placeholder="请输入搜索的内容"/>
+                        </div>
+                        <a class="layui-btn search_btn" data-type="reload">搜索</a>
+                    </div>
+                    <div class="layui-inline"><a class="layui-btn layui-btn-primary allot_btn">分配</a></div>
+                    <div class="layui-inline">
+                        <a class="layui-btn layui-btn-normal add_btn">添加</a>
+                    </div>
+                    <div class="layui-inline">
+                        <a class="layui-btn layui-btn-warm add_btn">编辑</a>
+                    </div>
+                    <div class="layui-inline">
+                        <a class="layui-btn layui-btn-danger layui-btn-normal delAll_btn">删除</a>
+                    </div>
+                    <div class="layui-inline"><a class="layui-btn layui-btn-normal refresh"><i
+                            class="layui-icon layui-icon-refresh-3"></i>刷新</a></div>
+                </form>
+            </blockquote>
+            <table id="list" lay-filter="list"></table>
+
+            <!--操作-->
+            <script type="text/html" id="listBar">
+                <a class="layui-btn layui-btn-xs layui-btn-warm" lay-event="edit">编辑</a>
+                <a class="layui-btn layui-btn-xs layui-btn-danger" lay-event="del">删除</a>
+            </script>
+        </form>
+    </div>
+</div>
+
+<script src="../../../assets/lib/jquery/jquery.min.js" th:src="@{/assets/lib/jquery/jquery.min.js}"></script>
+<script src="../../../assets/lib/layui/layui.js" th:src="@{/assets/lib/layui/layui.js}"></script>
+<script src="../../../assets/js/admin.js" th:src="@{/assets/js/admin.js}"></script>
+<script type="text/javascript" src="../../../static/business/upms/role/list.js" th:src="@{/business/upms/role/list.js}"></script>
+</body>
+</html>