|
|
@@ -1,1238 +1,60 @@
|
|
|
- // 模拟数据
|
|
|
- const mockData = [
|
|
|
- {
|
|
|
- id: 1,
|
|
|
- menu_name: "系统管理",
|
|
|
- parent_id: null,
|
|
|
- parent_ids: "",
|
|
|
- parent_auth_name: "",
|
|
|
- icons: "fas fa-cog",
|
|
|
- open_blank: null,
|
|
|
- target: null,
|
|
|
- link_url: "/system",
|
|
|
- sort: 1,
|
|
|
- state: 0,
|
|
|
- status: "0",
|
|
|
- del_flag: "N",
|
|
|
- creator: "admin",
|
|
|
- create_time: "2023-01-15 10:30:00",
|
|
|
- modifier: "admin",
|
|
|
- update_time: "2023-01-15 10:30:00",
|
|
|
- remark: "系统管理模块"
|
|
|
- },
|
|
|
- {
|
|
|
- id: 2,
|
|
|
- menu_name: "用户管理",
|
|
|
- parent_id: 1,
|
|
|
- parent_ids: "1",
|
|
|
- parent_auth_name: "system:user",
|
|
|
- icons: "fas fa-users",
|
|
|
- open_blank: null,
|
|
|
- target: null,
|
|
|
- link_url: "/system/user",
|
|
|
- sort: 1,
|
|
|
- state: 0,
|
|
|
- status: "0",
|
|
|
- del_flag: "N",
|
|
|
- creator: "admin",
|
|
|
- create_time: "2023-01-15 10:32:00",
|
|
|
- modifier: "admin",
|
|
|
- update_time: "2023-03-20 14:25:00",
|
|
|
- remark: "用户管理功能"
|
|
|
- },
|
|
|
- {
|
|
|
- id: 3,
|
|
|
- menu_name: "角色管理",
|
|
|
- parent_id: 1,
|
|
|
- parent_ids: "1",
|
|
|
- parent_auth_name: "system:role",
|
|
|
- icons: "fas fa-user-tag",
|
|
|
- open_blank: null,
|
|
|
- target: null,
|
|
|
- link_url: "/system/role",
|
|
|
- sort: 2,
|
|
|
- state: 0,
|
|
|
- status: "0",
|
|
|
- del_flag: "N",
|
|
|
- creator: "admin",
|
|
|
- create_time: "2023-01-15 10:35:00",
|
|
|
- modifier: "admin",
|
|
|
- update_time: "2023-02-10 09:15:00",
|
|
|
- remark: "角色管理功能"
|
|
|
- },
|
|
|
- {
|
|
|
- id: 4,
|
|
|
- menu_name: "菜单管理",
|
|
|
- parent_id: 1,
|
|
|
- parent_ids: "1",
|
|
|
- parent_auth_name: "system:menu",
|
|
|
- icons: "fas fa-bars",
|
|
|
- open_blank: null,
|
|
|
- target: null,
|
|
|
- link_url: "/system/menu",
|
|
|
- sort: 3,
|
|
|
- state: 0,
|
|
|
- status: "0",
|
|
|
- del_flag: "N",
|
|
|
- creator: "admin",
|
|
|
- create_time: "2023-01-15 10:38:00",
|
|
|
- modifier: "admin",
|
|
|
- update_time: "2023-01-15 10:38:00",
|
|
|
- remark: "菜单管理功能"
|
|
|
- },
|
|
|
- {
|
|
|
- id: 5,
|
|
|
- menu_name: "日志管理",
|
|
|
- parent_id: 1,
|
|
|
- parent_ids: "1",
|
|
|
- parent_auth_name: "system:log",
|
|
|
- icons: "fas fa-clipboard-list",
|
|
|
- open_blank: null,
|
|
|
- target: null,
|
|
|
- link_url: "/system/log",
|
|
|
- sort: 4,
|
|
|
- state: 1,
|
|
|
- status: "1",
|
|
|
- del_flag: "N",
|
|
|
- creator: "admin",
|
|
|
- create_time: "2023-01-20 11:20:00",
|
|
|
- modifier: "admin",
|
|
|
- update_time: "2023-05-05 16:40:00",
|
|
|
- remark: "系统日志查看"
|
|
|
- },
|
|
|
- {
|
|
|
- id: 6,
|
|
|
- menu_name: "业务管理",
|
|
|
- parent_id: null,
|
|
|
- parent_ids: "",
|
|
|
- parent_auth_name: "",
|
|
|
- icons: "fas fa-briefcase",
|
|
|
- open_blank: null,
|
|
|
- target: null,
|
|
|
- link_url: "/business",
|
|
|
- sort: 2,
|
|
|
- state: 0,
|
|
|
- status: "0",
|
|
|
- del_flag: "N",
|
|
|
- creator: "admin",
|
|
|
- create_time: "2023-02-01 09:00:00",
|
|
|
- modifier: "admin",
|
|
|
- update_time: "2023-02-01 09:00:00",
|
|
|
- remark: "业务管理模块"
|
|
|
- },
|
|
|
- {
|
|
|
- id: 7,
|
|
|
- menu_name: "订单管理",
|
|
|
- parent_id: 6,
|
|
|
- parent_ids: "6",
|
|
|
- parent_auth_name: "business:order",
|
|
|
- icons: "fas fa-shopping-cart",
|
|
|
- open_blank: null,
|
|
|
- target: null,
|
|
|
- link_url: "/business/order",
|
|
|
- sort: 1,
|
|
|
- state: 0,
|
|
|
- status: "0",
|
|
|
- del_flag: "N",
|
|
|
- creator: "admin",
|
|
|
- create_time: "2023-02-01 09:05:00",
|
|
|
- modifier: "admin",
|
|
|
- update_time: "2023-04-12 13:30:00",
|
|
|
- remark: "订单管理功能"
|
|
|
- },
|
|
|
- {
|
|
|
- id: 8,
|
|
|
- menu_name: "订单列表",
|
|
|
- parent_id: 7,
|
|
|
- parent_ids: "6,7",
|
|
|
- parent_auth_name: "business:order:list",
|
|
|
- icons: "fas fa-list",
|
|
|
- open_blank: null,
|
|
|
- target: null,
|
|
|
- link_url: "/business/order/list",
|
|
|
- sort: 1,
|
|
|
- state: 0,
|
|
|
- status: "0",
|
|
|
- del_flag: "N",
|
|
|
- creator: "admin",
|
|
|
- create_time: "2023-02-01 09:10:00",
|
|
|
- modifier: "admin",
|
|
|
- update_time: "2023-02-01 09:10:00",
|
|
|
- remark: "订单列表页面"
|
|
|
- },
|
|
|
- {
|
|
|
- id: 9,
|
|
|
- menu_name: "订单统计",
|
|
|
- parent_id: 7,
|
|
|
- parent_ids: "6,7",
|
|
|
- parent_auth_name: "business:order:stat",
|
|
|
- icons: "fas fa-chart-bar",
|
|
|
- open_blank: null,
|
|
|
- target: null,
|
|
|
- link_url: "/business/order/statistics",
|
|
|
- sort: 2,
|
|
|
- state: 0,
|
|
|
- status: "0",
|
|
|
- del_flag: "N",
|
|
|
- creator: "admin",
|
|
|
- create_time: "2023-02-05 14:20:00",
|
|
|
- modifier: "admin",
|
|
|
- update_time: "2023-02-05 14:20:00",
|
|
|
- remark: "订单统计页面"
|
|
|
- },
|
|
|
- {
|
|
|
- id: 10,
|
|
|
- menu_name: "商品管理",
|
|
|
- parent_id: 6,
|
|
|
- parent_ids: "6",
|
|
|
- parent_auth_name: "business:product",
|
|
|
- icons: "fas fa-box",
|
|
|
- open_blank: "_blank",
|
|
|
- target: "_blank",
|
|
|
- link_url: "/business/product",
|
|
|
- sort: 2,
|
|
|
- state: 0,
|
|
|
- status: "0",
|
|
|
- del_flag: "N",
|
|
|
- creator: "admin",
|
|
|
- create_time: "2023-02-10 10:15:00",
|
|
|
- modifier: "admin",
|
|
|
- update_time: "2023-03-25 11:45:00",
|
|
|
- remark: "商品管理功能"
|
|
|
- },
|
|
|
- {
|
|
|
- id: 11,
|
|
|
- menu_name: "客户管理",
|
|
|
- parent_id: 6,
|
|
|
- parent_ids: "6",
|
|
|
- parent_auth_name: "business:customer",
|
|
|
- icons: "fas fa-user-friends",
|
|
|
- open_blank: null,
|
|
|
- target: null,
|
|
|
- link_url: "/business/customer",
|
|
|
- sort: 3,
|
|
|
- state: 0,
|
|
|
- status: "0",
|
|
|
- del_flag: "N",
|
|
|
- creator: "manager",
|
|
|
- create_time: "2023-02-15 14:30:00",
|
|
|
- modifier: "admin",
|
|
|
- update_time: "2023-04-01 10:20:00",
|
|
|
- remark: "客户管理功能"
|
|
|
- },
|
|
|
- {
|
|
|
- id: 12,
|
|
|
- menu_name: "财务管理",
|
|
|
- parent_id: null,
|
|
|
- parent_ids: "",
|
|
|
- parent_auth_name: "",
|
|
|
- icons: "fas fa-money-bill-wave",
|
|
|
- open_blank: null,
|
|
|
- target: null,
|
|
|
- link_url: "/finance",
|
|
|
- sort: 3,
|
|
|
- state: 0,
|
|
|
- status: "0",
|
|
|
- del_flag: "N",
|
|
|
- creator: "admin",
|
|
|
- create_time: "2023-03-01 09:00:00",
|
|
|
- modifier: "admin",
|
|
|
- update_time: "2023-03-01 09:00:00",
|
|
|
- remark: "财务管理模块"
|
|
|
- },
|
|
|
- {
|
|
|
- id: 13,
|
|
|
- menu_name: "报表管理",
|
|
|
- parent_id: null,
|
|
|
- parent_ids: "",
|
|
|
- parent_auth_name: "",
|
|
|
- icons: "fas fa-chart-pie",
|
|
|
- open_blank: null,
|
|
|
- target: null,
|
|
|
- link_url: "/report",
|
|
|
- sort: 4,
|
|
|
- state: 0,
|
|
|
- status: "0",
|
|
|
- del_flag: "N",
|
|
|
- creator: "admin",
|
|
|
- create_time: "2023-03-10 11:00:00",
|
|
|
- modifier: "admin",
|
|
|
- update_time: "2023-03-10 11:00:00",
|
|
|
- remark: "报表管理模块"
|
|
|
- },
|
|
|
- {
|
|
|
- id: 14,
|
|
|
- menu_name: "旧版菜单",
|
|
|
- parent_id: null,
|
|
|
- parent_ids: "",
|
|
|
- parent_auth_name: "",
|
|
|
- icons: "fas fa-archive",
|
|
|
- open_blank: null,
|
|
|
- target: null,
|
|
|
- link_url: "/old",
|
|
|
- sort: 5,
|
|
|
- state: 0,
|
|
|
- status: "0",
|
|
|
- del_flag: "Y",
|
|
|
- creator: "admin",
|
|
|
- create_time: "2022-12-01 08:30:00",
|
|
|
- modifier: "admin",
|
|
|
- update_time: "2023-06-01 15:20:00",
|
|
|
- remark: "已废弃的旧版菜单"
|
|
|
+layui.config({
|
|
|
+ base: '/assets/library/jplus/treeTable/'
|
|
|
+}).use(['form', 'layer', 'table', 'laytpl', 'treeTable'], function () {
|
|
|
+ const form = layui.form,
|
|
|
+ layer = parent.layer === undefined ? layui.layer : top.layer,
|
|
|
+ $ = layui.jquery,
|
|
|
+ laytpl = layui.laytpl,
|
|
|
+ table = layui.table,
|
|
|
+ treeTable = layui.treeTable;
|
|
|
+
|
|
|
+ // 添加用户
|
|
|
+ $('#addMenuBtn').click(() => openEditDialog());
|
|
|
+
|
|
|
+ // 添加用户
|
|
|
+ $('#toggleSearchForm').click(() => toggleSearchForm());
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 打开编辑弹窗
|
|
|
+ * @param {Object} editData - 编辑的数据,为空时表示新增
|
|
|
+ */
|
|
|
+ function openEditDialog(editData = null) {
|
|
|
+ const title = editData ? '修改用户' : '添加用户';
|
|
|
+ const index = layui.layer.open({
|
|
|
+ title,
|
|
|
+ type: 2,
|
|
|
+ content: '/upms/menu/edit.html',
|
|
|
+ area: ['100%', '100%'],
|
|
|
+ success: function (layero, index) {
|
|
|
+ setTimeout(() => {
|
|
|
+ layui.layer.tips('点击此处返回用户列表', '.layui-layer-setwin .layui-layer-close', {
|
|
|
+ tips: 3
|
|
|
+ });
|
|
|
+ }, 500);
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ // 存储弹窗索引用于响应式调整
|
|
|
+ window.sessionStorage.setItem('dialogIndex', index);
|
|
|
+
|
|
|
+ // 响应窗口大小变化
|
|
|
+ $(window).off('resize.dialogResize').on('resize.dialogResize', () => {
|
|
|
+ layer.full(window.sessionStorage.getItem('dialogIndex'));
|
|
|
+ });
|
|
|
}
|
|
|
- ];
|
|
|
|
|
|
- // 全局变量
|
|
|
- let currentData = [...mockData];
|
|
|
- let filteredData = [...mockData];
|
|
|
- let currentPage = 1;
|
|
|
- const itemsPerPage = 10;
|
|
|
- let editingId = null;
|
|
|
- let deletingId = null;
|
|
|
- let selectedMenuId = null;
|
|
|
- let showDeleted = false;
|
|
|
- let expandedMenuIds = new Set([1, 6]); // 默认展开一些菜单
|
|
|
let searchFormExpanded = true; // 搜索表单默认展开
|
|
|
-
|
|
|
- // DOM元素
|
|
|
- const menuTree = document.getElementById('menuTree');
|
|
|
- const menuTableBody = document.getElementById('menuTableBody');
|
|
|
- const emptyState = document.getElementById('emptyState');
|
|
|
- const quickSearchInput = document.getElementById('quickSearchInput');
|
|
|
- const toggleDeletedBtn = document.getElementById('toggleDeletedBtn');
|
|
|
- const exportBtn = document.getElementById('exportBtn');
|
|
|
- const addMenuBtn = document.getElementById('addMenuBtn');
|
|
|
- const refreshBtn = document.getElementById('refreshBtn');
|
|
|
- const searchForm = document.getElementById('searchForm');
|
|
|
- const toggleSearchFormBtn = document.getElementById('toggleSearchForm');
|
|
|
- const resetSearchBtn = document.getElementById('resetSearchBtn');
|
|
|
- const applySearchBtn = document.getElementById('applySearchBtn');
|
|
|
- const menuModal = document.getElementById('menuModal');
|
|
|
- const deleteModal = document.getElementById('deleteModal');
|
|
|
- const modalTitle = document.getElementById('modalTitle');
|
|
|
- const menuForm = document.getElementById('menuForm');
|
|
|
- const parentMenuSelect = document.getElementById('parentMenu');
|
|
|
- const searchParentMenuSelect = document.getElementById('searchParentMenu');
|
|
|
- const closeModalBtn = document.getElementById('closeModalBtn');
|
|
|
- const cancelBtn = document.getElementById('cancelBtn');
|
|
|
- const saveBtn = document.getElementById('saveBtn');
|
|
|
- const closeDeleteModalBtn = document.getElementById('closeDeleteModalBtn');
|
|
|
- const cancelDeleteBtn = document.getElementById('cancelDeleteBtn');
|
|
|
- const confirmDeleteBtn = document.getElementById('confirmDeleteBtn');
|
|
|
- const deleteMenuName = document.getElementById('deleteMenuName');
|
|
|
- const prevPageBtn = document.getElementById('prevPage');
|
|
|
- const nextPageBtn = document.getElementById('nextPage');
|
|
|
- const pageNumbersContainer = document.getElementById('pageNumbers');
|
|
|
- const paginationInfo = document.getElementById('paginationInfo');
|
|
|
- const tableInfo = document.getElementById('tableInfo');
|
|
|
-
|
|
|
- // 初始化
|
|
|
- document.addEventListener('DOMContentLoaded', function() {
|
|
|
- renderMenuTree();
|
|
|
- renderTable();
|
|
|
- setupEventListeners();
|
|
|
- populateParentMenuOptions();
|
|
|
- populateSearchParentMenuOptions();
|
|
|
- setupSearchForm();
|
|
|
-
|
|
|
- // 默认选中第一个菜单
|
|
|
- if (mockData.length > 0) {
|
|
|
- selectedMenuId = 1;
|
|
|
- updateMenuTreeSelection();
|
|
|
-}
|
|
|
-});
|
|
|
-
|
|
|
- // 设置事件监听器
|
|
|
- function setupEventListeners() {
|
|
|
- // 搜索表单切换
|
|
|
- toggleSearchFormBtn.addEventListener('click', toggleSearchForm);
|
|
|
-
|
|
|
- // 快速搜索
|
|
|
- quickSearchInput.addEventListener('input', handleQuickSearch);
|
|
|
-
|
|
|
- // 搜索条件
|
|
|
- resetSearchBtn.addEventListener('click', resetSearchForm);
|
|
|
- applySearchBtn.addEventListener('click', applySearch);
|
|
|
-
|
|
|
- // 按钮点击事件
|
|
|
- addMenuBtn.addEventListener('click', openAddModal);
|
|
|
- refreshBtn.addEventListener('click', refreshData);
|
|
|
- exportBtn.addEventListener('click', exportData);
|
|
|
- toggleDeletedBtn.addEventListener('click', toggleDeleted);
|
|
|
-
|
|
|
- // 模态框事件
|
|
|
- closeModalBtn.addEventListener('click', closeModal);
|
|
|
- cancelBtn.addEventListener('click', closeModal);
|
|
|
- saveBtn.addEventListener('click', saveMenu);
|
|
|
-
|
|
|
- closeDeleteModalBtn.addEventListener('click', closeDeleteModal);
|
|
|
- cancelDeleteBtn.addEventListener('click', closeDeleteModal);
|
|
|
- confirmDeleteBtn.addEventListener('click', confirmDelete);
|
|
|
-
|
|
|
- // 分页事件
|
|
|
- prevPageBtn.addEventListener('click', goToPrevPage);
|
|
|
- nextPageBtn.addEventListener('click', goToNextPage);
|
|
|
-
|
|
|
- // 点击模态框外部关闭
|
|
|
- menuModal.addEventListener('click', function(e) {
|
|
|
- if (e.target === menuModal) closeModal();
|
|
|
-});
|
|
|
-
|
|
|
- deleteModal.addEventListener('click', function(e) {
|
|
|
- if (e.target === deleteModal) closeDeleteModal();
|
|
|
-});
|
|
|
-}
|
|
|
-
|
|
|
- // 设置搜索表单
|
|
|
- function setupSearchForm() {
|
|
|
- // 设置日期输入框的默认值(最近一个月)
|
|
|
- const today = new Date();
|
|
|
- const oneMonthAgo = new Date();
|
|
|
- oneMonthAgo.setMonth(today.getMonth() - 1);
|
|
|
-
|
|
|
- document.getElementById('searchCreateTimeStart').valueAsDate = oneMonthAgo;
|
|
|
- document.getElementById('searchCreateTimeEnd').valueAsDate = today;
|
|
|
- document.getElementById('searchUpdateTimeStart').valueAsDate = oneMonthAgo;
|
|
|
- document.getElementById('searchUpdateTimeEnd').valueAsDate = today;
|
|
|
-}
|
|
|
-
|
|
|
// 切换搜索表单
|
|
|
function toggleSearchForm() {
|
|
|
- searchFormExpanded = !searchFormExpanded;
|
|
|
- if (searchFormExpanded) {
|
|
|
- searchForm.classList.remove('collapsed');
|
|
|
- toggleSearchFormBtn.innerHTML = '<i class="fas fa-chevron-up"></i><span>收起</span>';
|
|
|
-} else {
|
|
|
- searchForm.classList.add('collapsed');
|
|
|
- toggleSearchFormBtn.innerHTML = '<i class="fas fa-chevron-down"></i><span>展开</span>';
|
|
|
-}
|
|
|
-}
|
|
|
-
|
|
|
- // 渲染菜单树
|
|
|
- function renderMenuTree() {
|
|
|
- menuTree.innerHTML = '';
|
|
|
-
|
|
|
- // 获取未删除的顶级菜单
|
|
|
- const topLevelMenus = currentData.filter(menu =>
|
|
|
- menu.parent_id === null && menu.del_flag === 'N'
|
|
|
- ).sort((a, b) => a.sort - b.sort);
|
|
|
-
|
|
|
- topLevelMenus.forEach(menu => {
|
|
|
- const menuItem = createMenuItem(menu);
|
|
|
- menuTree.appendChild(menuItem);
|
|
|
-});
|
|
|
-}
|
|
|
-
|
|
|
- // 创建菜单项
|
|
|
- function createMenuItem(menu) {
|
|
|
- const li = document.createElement('li');
|
|
|
- li.className = 'menu-tree-item';
|
|
|
- li.setAttribute('data-id', menu.id);
|
|
|
-
|
|
|
- // 获取子菜单
|
|
|
- const children = currentData.filter(item =>
|
|
|
- item.parent_id === menu.id && item.del_flag === 'N'
|
|
|
- ).sort((a, b) => a.sort - b.sort);
|
|
|
-
|
|
|
- const hasChildren = children.length > 0;
|
|
|
- const isExpanded = expandedMenuIds.has(menu.id);
|
|
|
-
|
|
|
- li.innerHTML = `
|
|
|
- <div class="menu-tree-node ${selectedMenuId === menu.id ? 'active' : ''}" data-id="${menu.id}">
|
|
|
- <div class="menu-tree-icon">
|
|
|
- <i class="${menu.icons || 'fas fa-folder'}"></i>
|
|
|
- </div>
|
|
|
- <div class="menu-tree-text">${menu.menu_name}</div>
|
|
|
- ${hasChildren ?
|
|
|
- `<div class="menu-tree-toggle ${isExpanded ? 'expanded' : ''}">
|
|
|
- <i class="fas fa-chevron-right"></i>
|
|
|
- </div>` :
|
|
|
- '<div class="menu-tree-toggle" style="visibility: hidden;"></div>'
|
|
|
-}
|
|
|
- </div>
|
|
|
- `;
|
|
|
-
|
|
|
- // 添加子菜单
|
|
|
- if (hasChildren) {
|
|
|
- const childrenUl = document.createElement('ul');
|
|
|
- childrenUl.className = `menu-tree-children ${isExpanded ? 'expanded' : ''}`;
|
|
|
-
|
|
|
- children.forEach(child => {
|
|
|
- const childItem = createMenuItem(child);
|
|
|
- childrenUl.appendChild(childItem);
|
|
|
-});
|
|
|
-
|
|
|
- li.appendChild(childrenUl);
|
|
|
-
|
|
|
- // 添加展开/折叠事件
|
|
|
- const toggleBtn = li.querySelector('.menu-tree-toggle');
|
|
|
- toggleBtn.addEventListener('click', function(e) {
|
|
|
- e.stopPropagation();
|
|
|
- toggleMenuTree(menu.id, childrenUl, toggleBtn);
|
|
|
-});
|
|
|
-}
|
|
|
-
|
|
|
- // 添加点击事件
|
|
|
- const menuNode = li.querySelector('.menu-tree-node');
|
|
|
- menuNode.addEventListener('click', function() {
|
|
|
- selectMenu(menu.id);
|
|
|
-});
|
|
|
-
|
|
|
- return li;
|
|
|
-}
|
|
|
-
|
|
|
- // 切换菜单展开/折叠
|
|
|
- function toggleMenuTree(menuId, childrenUl, toggleBtn) {
|
|
|
- if (expandedMenuIds.has(menuId)) {
|
|
|
- expandedMenuIds.delete(menuId);
|
|
|
- childrenUl.classList.remove('expanded');
|
|
|
- toggleBtn.classList.remove('expanded');
|
|
|
-} else {
|
|
|
- expandedMenuIds.add(menuId);
|
|
|
- childrenUl.classList.add('expanded');
|
|
|
- toggleBtn.classList.add('expanded');
|
|
|
-}
|
|
|
-}
|
|
|
-
|
|
|
- // 选择菜单
|
|
|
- function selectMenu(menuId) {
|
|
|
- selectedMenuId = menuId;
|
|
|
- updateMenuTreeSelection();
|
|
|
-
|
|
|
- // 根据选择的菜单筛选表格数据
|
|
|
- currentPage = 1;
|
|
|
- renderTable();
|
|
|
-}
|
|
|
-
|
|
|
- // 更新菜单树选中状态
|
|
|
- function updateMenuTreeSelection() {
|
|
|
- // 移除所有active类
|
|
|
- document.querySelectorAll('.menu-tree-node').forEach(node => {
|
|
|
- node.classList.remove('active');
|
|
|
- });
|
|
|
-
|
|
|
- // 添加当前选中项的active类
|
|
|
- const selectedNode = document.querySelector(`.menu-tree-node[data-id="${selectedMenuId}"]`);
|
|
|
- if (selectedNode) {
|
|
|
- selectedNode.classList.add('active');
|
|
|
-
|
|
|
- // 滚动到选中项
|
|
|
- selectedNode.scrollIntoView({
|
|
|
- behavior: 'smooth',
|
|
|
- block: 'center'
|
|
|
-});
|
|
|
-}
|
|
|
-}
|
|
|
-
|
|
|
- // 渲染表格
|
|
|
- function renderTable() {
|
|
|
- // 清空表格
|
|
|
- menuTableBody.innerHTML = '';
|
|
|
-
|
|
|
- // 筛选数据
|
|
|
- filteredData = filterData(currentData);
|
|
|
- const totalItems = filteredData.length;
|
|
|
- const totalPages = Math.ceil(totalItems / itemsPerPage);
|
|
|
-
|
|
|
- // 确保当前页码有效
|
|
|
- if (currentPage > totalPages && totalPages > 0) {
|
|
|
- currentPage = totalPages;
|
|
|
-} else if (totalPages === 0) {
|
|
|
- currentPage = 1;
|
|
|
-}
|
|
|
-
|
|
|
- // 获取当前页数据
|
|
|
- const startIndex = (currentPage - 1) * itemsPerPage;
|
|
|
- const endIndex = Math.min(startIndex + itemsPerPage, totalItems);
|
|
|
- const pageData = filteredData.slice(startIndex, endIndex);
|
|
|
-
|
|
|
- // 显示/隐藏空状态
|
|
|
- if (pageData.length === 0) {
|
|
|
- emptyState.style.display = 'block';
|
|
|
-} else {
|
|
|
- emptyState.style.display = 'none';
|
|
|
-}
|
|
|
-
|
|
|
- // 更新表格信息
|
|
|
- tableInfo.textContent = `共 ${totalItems} 条记录`;
|
|
|
-
|
|
|
- // 渲染表格行
|
|
|
- pageData.forEach(item => {
|
|
|
- const row = document.createElement('tr');
|
|
|
-
|
|
|
- // 状态标签
|
|
|
- let statusBadge = '';
|
|
|
- if (item.status === '0') {
|
|
|
- statusBadge = '<span class="status-badge status-active"><i class="fas fa-check-circle"></i> 启用</span>';
|
|
|
-} else {
|
|
|
- statusBadge = '<span class="status-badge status-inactive"><i class="fas fa-pause-circle"></i> 停用</span>';
|
|
|
-}
|
|
|
-
|
|
|
- // 删除状态
|
|
|
- let delFlagBadge = '';
|
|
|
- if (item.del_flag === 'Y') {
|
|
|
- delFlagBadge = '<span class="status-badge status-deleted"><i class="fas fa-trash"></i> 已删除</span>';
|
|
|
-} else {
|
|
|
- delFlagBadge = '<span class="status-badge status-active"><i class="fas fa-check"></i> 正常</span>';
|
|
|
-}
|
|
|
-
|
|
|
- // 查找父级菜单名称
|
|
|
- const parentMenu = item.parent_id ?
|
|
|
- currentData.find(menu => menu.id === item.parent_id)?.menu_name || '未知' :
|
|
|
- '顶级菜单';
|
|
|
-
|
|
|
- // 图标显示
|
|
|
- const iconDisplay = item.icons ?
|
|
|
- `<i class="${item.icons}" style="color: var(--warning-color);"></i>` :
|
|
|
- '<i class="fas fa-folder" style="color: var(--text-secondary);"></i>';
|
|
|
-
|
|
|
- // 格式化日期
|
|
|
- const createDate = formatDateShort(item.create_time);
|
|
|
- const updateDate = formatDateShort(item.update_time);
|
|
|
-
|
|
|
- row.innerHTML = `
|
|
|
- <td>
|
|
|
- <div style="display: flex; align-items: center; gap: 5px;">
|
|
|
- ${iconDisplay}
|
|
|
- <span>${item.menu_name}</span>
|
|
|
- </div>
|
|
|
- </td>
|
|
|
- <td>${parentMenu}</td>
|
|
|
- <td>${item.parent_auth_name || '-'}</td>
|
|
|
- <td>${item.link_url || '-'}</td>
|
|
|
- <td>${iconDisplay}</td>
|
|
|
- <td>${item.open_blank || '默认'}</td>
|
|
|
- <td>${item.target || '-'}</td>
|
|
|
- <td>${item.sort}</td>
|
|
|
- <td>${statusBadge}</td>
|
|
|
- <td>${delFlagBadge}</td>
|
|
|
- <td>
|
|
|
- <div>${item.creator}</div>
|
|
|
- <div style="font-size: 12px; color: var(--text-secondary);">${createDate}</div>
|
|
|
- </td>
|
|
|
- <td>
|
|
|
- <div>${item.modifier}</div>
|
|
|
- <div style="font-size: 12px; color: var(--text-secondary);">${updateDate}</div>
|
|
|
- </td>
|
|
|
- <td>
|
|
|
- <div class="action-buttons">
|
|
|
- <button class="action-btn" title="编辑" onclick="editMenu(${item.id})">
|
|
|
- <i class="fas fa-edit"></i>
|
|
|
- </button>
|
|
|
- <button class="action-btn" title="查看" onclick="viewMenu(${item.id})">
|
|
|
- <i class="fas fa-eye"></i>
|
|
|
- </button>
|
|
|
- ${item.del_flag === 'Y' ?
|
|
|
- `<button class="action-btn" title="恢复" onclick="restoreMenu(${item.id})">
|
|
|
- <i class="fas fa-redo"></i>
|
|
|
- </button>` :
|
|
|
- `<button class="action-btn delete" title="删除" onclick="deleteMenu(${item.id}, '${item.menu_name}')">
|
|
|
- <i class="fas fa-trash"></i>
|
|
|
- </button>`
|
|
|
-}
|
|
|
- </div>
|
|
|
- </td>
|
|
|
- `;
|
|
|
-
|
|
|
- menuTableBody.appendChild(row);
|
|
|
-});
|
|
|
-
|
|
|
- // 更新分页信息
|
|
|
- updatePagination(totalItems, totalPages);
|
|
|
-}
|
|
|
-
|
|
|
- // 过滤数据
|
|
|
- function filterData(data) {
|
|
|
- let filtered = [...data];
|
|
|
-
|
|
|
- // 根据左侧菜单树选择筛选
|
|
|
- if (selectedMenuId) {
|
|
|
- // 获取选中菜单及其所有子菜单
|
|
|
- const selectedMenuIds = getMenuAndChildrenIds(selectedMenuId);
|
|
|
- filtered = filtered.filter(item => selectedMenuIds.includes(item.id));
|
|
|
-}
|
|
|
-
|
|
|
- // 快速搜索过滤
|
|
|
- const quickSearchTerm = quickSearchInput.value.toLowerCase().trim();
|
|
|
- if (quickSearchTerm) {
|
|
|
- filtered = filtered.filter(item =>
|
|
|
- item.menu_name.toLowerCase().includes(quickSearchTerm) ||
|
|
|
- (item.parent_auth_name && item.parent_auth_name.toLowerCase().includes(quickSearchTerm)) ||
|
|
|
- (item.link_url && item.link_url.toLowerCase().includes(quickSearchTerm))
|
|
|
- );
|
|
|
-}
|
|
|
-
|
|
|
- // 高级搜索过滤
|
|
|
- const menuName = document.getElementById('searchMenuName').value.toLowerCase().trim();
|
|
|
- if (menuName) {
|
|
|
- filtered = filtered.filter(item => item.menu_name.toLowerCase().includes(menuName));
|
|
|
-}
|
|
|
-
|
|
|
- const parentMenu = document.getElementById('searchParentMenu').value;
|
|
|
- if (parentMenu === 'null') {
|
|
|
- filtered = filtered.filter(item => item.parent_id === null);
|
|
|
-} else if (parentMenu) {
|
|
|
- filtered = filtered.filter(item => item.parent_id === parseInt(parentMenu));
|
|
|
-}
|
|
|
-
|
|
|
- const parentAuthName = document.getElementById('searchParentAuthName').value.toLowerCase().trim();
|
|
|
- if (parentAuthName) {
|
|
|
- filtered = filtered.filter(item =>
|
|
|
- item.parent_auth_name && item.parent_auth_name.toLowerCase().includes(parentAuthName)
|
|
|
- );
|
|
|
-}
|
|
|
-
|
|
|
- const linkUrl = document.getElementById('searchLinkUrl').value.toLowerCase().trim();
|
|
|
- if (linkUrl) {
|
|
|
- filtered = filtered.filter(item => item.link_url && item.link_url.toLowerCase().includes(linkUrl));
|
|
|
-}
|
|
|
-
|
|
|
- const status = document.getElementById('searchStatus').value;
|
|
|
- if (status !== '') {
|
|
|
- filtered = filtered.filter(item => item.status === status);
|
|
|
-}
|
|
|
-
|
|
|
- const delFlag = document.getElementById('searchDelFlag').value;
|
|
|
- if (delFlag !== '') {
|
|
|
- filtered = filtered.filter(item => item.del_flag === delFlag);
|
|
|
-} else {
|
|
|
- // 默认不显示已删除的菜单
|
|
|
- filtered = filtered.filter(item => item.del_flag === 'N');
|
|
|
-}
|
|
|
-
|
|
|
- const creator = document.getElementById('searchCreator').value.toLowerCase().trim();
|
|
|
- if (creator) {
|
|
|
- filtered = filtered.filter(item => item.creator.toLowerCase().includes(creator));
|
|
|
-}
|
|
|
-
|
|
|
- const sortMin = document.getElementById('searchSortMin').value;
|
|
|
- const sortMax = document.getElementById('searchSortMax').value;
|
|
|
- if (sortMin) {
|
|
|
- filtered = filtered.filter(item => item.sort >= parseInt(sortMin));
|
|
|
-}
|
|
|
- if (sortMax) {
|
|
|
- filtered = filtered.filter(item => item.sort <= parseInt(sortMax));
|
|
|
-}
|
|
|
-
|
|
|
- const openBlank = document.getElementById('searchOpenBlank').value;
|
|
|
- if (openBlank) {
|
|
|
- filtered = filtered.filter(item => item.open_blank === openBlank);
|
|
|
-}
|
|
|
-
|
|
|
- const target = document.getElementById('searchTarget').value.toLowerCase().trim();
|
|
|
- if (target) {
|
|
|
- filtered = filtered.filter(item => item.target && item.target.toLowerCase().includes(target));
|
|
|
-}
|
|
|
-
|
|
|
- const createTimeStart = document.getElementById('searchCreateTimeStart').value;
|
|
|
- const createTimeEnd = document.getElementById('searchCreateTimeEnd').value;
|
|
|
- if (createTimeStart) {
|
|
|
- const startDate = new Date(createTimeStart);
|
|
|
- filtered = filtered.filter(item => new Date(item.create_time) >= startDate);
|
|
|
-}
|
|
|
- if (createTimeEnd) {
|
|
|
- const endDate = new Date(createTimeEnd);
|
|
|
- endDate.setHours(23, 59, 59, 999); // 设置为当天的最后一刻
|
|
|
- filtered = filtered.filter(item => new Date(item.create_time) <= endDate);
|
|
|
-}
|
|
|
-
|
|
|
- const updateTimeStart = document.getElementById('searchUpdateTimeStart').value;
|
|
|
- const updateTimeEnd = document.getElementById('searchUpdateTimeEnd').value;
|
|
|
- if (updateTimeStart) {
|
|
|
- const startDate = new Date(updateTimeStart);
|
|
|
- filtered = filtered.filter(item => new Date(item.update_time) >= startDate);
|
|
|
-}
|
|
|
- if (updateTimeEnd) {
|
|
|
- const endDate = new Date(updateTimeEnd);
|
|
|
- endDate.setHours(23, 59, 59, 999); // 设置为当天的最后一刻
|
|
|
- filtered = filtered.filter(item => new Date(item.update_time) <= endDate);
|
|
|
-}
|
|
|
-
|
|
|
- return filtered;
|
|
|
-}
|
|
|
-
|
|
|
- // 获取菜单及其所有子菜单的ID
|
|
|
- function getMenuAndChildrenIds(menuId) {
|
|
|
- const ids = [menuId];
|
|
|
-
|
|
|
- // 递归获取子菜单ID
|
|
|
- function getChildrenIds(parentId) {
|
|
|
- const children = currentData.filter(item => item.parent_id === parentId);
|
|
|
- children.forEach(child => {
|
|
|
- ids.push(child.id);
|
|
|
- getChildrenIds(child.id);
|
|
|
-});
|
|
|
-}
|
|
|
-
|
|
|
- getChildrenIds(menuId);
|
|
|
- return ids;
|
|
|
-}
|
|
|
-
|
|
|
- // 更新分页
|
|
|
- function updatePagination(totalItems, totalPages) {
|
|
|
- // 更新分页信息文本
|
|
|
- const startItem = totalItems > 0 ? (currentPage - 1) * itemsPerPage + 1 : 0;
|
|
|
- const endItem = Math.min(currentPage * itemsPerPage, totalItems);
|
|
|
- paginationInfo.textContent = `显示第 ${startItem} 到 ${endItem} 条,共 ${totalItems} 条`;
|
|
|
-
|
|
|
- // 更新上一页/下一页按钮状态
|
|
|
- prevPageBtn.disabled = currentPage === 1;
|
|
|
- nextPageBtn.disabled = currentPage === totalPages || totalPages === 0;
|
|
|
-
|
|
|
- // 生成页码按钮
|
|
|
- pageNumbersContainer.innerHTML = '';
|
|
|
-
|
|
|
- // 最多显示5个页码
|
|
|
- let startPage = Math.max(1, currentPage - 2);
|
|
|
- let endPage = Math.min(totalPages, startPage + 4);
|
|
|
-
|
|
|
- // 调整起始页码以确保显示5个页码(如果可能)
|
|
|
- if (endPage - startPage < 4 && startPage > 1) {
|
|
|
- startPage = Math.max(1, endPage - 4);
|
|
|
-}
|
|
|
-
|
|
|
- // 生成页码按钮
|
|
|
- for (let i = startPage; i <= endPage; i++) {
|
|
|
- const pageBtn = document.createElement('div');
|
|
|
- pageBtn.className = `pagination-number ${i === currentPage ? 'active' : ''}`;
|
|
|
- pageBtn.textContent = i;
|
|
|
- pageBtn.addEventListener('click', () => goToPage(i));
|
|
|
- pageNumbersContainer.appendChild(pageBtn);
|
|
|
-}
|
|
|
-}
|
|
|
-
|
|
|
- // 快速搜索处理
|
|
|
- function handleQuickSearch() {
|
|
|
- currentPage = 1;
|
|
|
- renderTable();
|
|
|
-}
|
|
|
-
|
|
|
- // 重置搜索表单
|
|
|
- function resetSearchForm() {
|
|
|
- document.getElementById('searchMenuName').value = '';
|
|
|
- document.getElementById('searchParentMenu').value = '';
|
|
|
- document.getElementById('searchParentAuthName').value = '';
|
|
|
- document.getElementById('searchLinkUrl').value = '';
|
|
|
- document.getElementById('searchStatus').value = '';
|
|
|
- document.getElementById('searchDelFlag').value = 'N';
|
|
|
- document.getElementById('searchCreator').value = '';
|
|
|
- document.getElementById('searchSortMin').value = '';
|
|
|
- document.getElementById('searchSortMax').value = '';
|
|
|
- document.getElementById('searchOpenBlank').value = '';
|
|
|
- document.getElementById('searchTarget').value = '';
|
|
|
-
|
|
|
- // 重置日期为最近一个月
|
|
|
- const today = new Date();
|
|
|
- const oneMonthAgo = new Date();
|
|
|
- oneMonthAgo.setMonth(today.getMonth() - 1);
|
|
|
-
|
|
|
- document.getElementById('searchCreateTimeStart').valueAsDate = oneMonthAgo;
|
|
|
- document.getElementById('searchCreateTimeEnd').valueAsDate = today;
|
|
|
- document.getElementById('searchUpdateTimeStart').valueAsDate = oneMonthAgo;
|
|
|
- document.getElementById('searchUpdateTimeEnd').valueAsDate = today;
|
|
|
-
|
|
|
- // 重新渲染表格
|
|
|
- currentPage = 1;
|
|
|
- renderTable();
|
|
|
-
|
|
|
- showMessage('搜索条件已重置', 'success');
|
|
|
-}
|
|
|
-
|
|
|
- // 应用搜索
|
|
|
- function applySearch() {
|
|
|
- currentPage = 1;
|
|
|
- renderTable();
|
|
|
- showMessage('搜索条件已应用', 'success');
|
|
|
-}
|
|
|
-
|
|
|
- // 切换显示已删除
|
|
|
- function toggleDeleted() {
|
|
|
- showDeleted = !showDeleted;
|
|
|
- toggleDeletedBtn.innerHTML = showDeleted ?
|
|
|
- '<i class="fas fa-eye-slash"></i> 隐藏已删除' :
|
|
|
- '<i class="fas fa-eye"></i> 显示已删除';
|
|
|
- document.getElementById('searchDelFlag').value = showDeleted ? '' : 'N';
|
|
|
- currentPage = 1;
|
|
|
- renderTable();
|
|
|
-}
|
|
|
-
|
|
|
- // 刷新数据
|
|
|
- function refreshData() {
|
|
|
- // 在实际应用中,这里会从服务器重新获取数据
|
|
|
- currentData = [...mockData];
|
|
|
- selectedMenuId = 1;
|
|
|
- currentPage = 1;
|
|
|
- renderMenuTree();
|
|
|
- renderTable();
|
|
|
- updateMenuTreeSelection();
|
|
|
- showMessage('数据已刷新', 'success');
|
|
|
-}
|
|
|
-
|
|
|
- // 导出数据
|
|
|
- function exportData() {
|
|
|
- if (filteredData.length === 0) {
|
|
|
- showMessage('没有可导出的数据', 'warning');
|
|
|
- return;
|
|
|
-}
|
|
|
-
|
|
|
- // 在实际应用中,这里会调用后端导出接口
|
|
|
- showMessage(`正在导出 ${filteredData.length} 条数据...`, 'success');
|
|
|
-
|
|
|
- // 模拟下载
|
|
|
- setTimeout(() => {
|
|
|
- showMessage('数据导出成功,开始下载文件', 'success');
|
|
|
-}, 1000);
|
|
|
-}
|
|
|
-
|
|
|
- // 打开新增菜单模态框
|
|
|
- function openAddModal() {
|
|
|
- modalTitle.textContent = '新增菜单';
|
|
|
- menuForm.reset();
|
|
|
- editingId = null;
|
|
|
-
|
|
|
- // 设置默认值
|
|
|
- document.getElementById('sort').value = 0;
|
|
|
- document.getElementById('status').value = '0';
|
|
|
-
|
|
|
- // 重新填充父级菜单选项
|
|
|
- populateParentMenuOptions();
|
|
|
-
|
|
|
- // 如果左侧有选中的菜单,默认设为父级菜单
|
|
|
- if (selectedMenuId) {
|
|
|
- document.getElementById('parentMenu').value = selectedMenuId;
|
|
|
-}
|
|
|
-
|
|
|
- menuModal.classList.add('active');
|
|
|
-}
|
|
|
-
|
|
|
- // 编辑菜单
|
|
|
- function editMenu(id) {
|
|
|
- const menu = currentData.find(item => item.id === id);
|
|
|
- if (!menu) return;
|
|
|
-
|
|
|
- modalTitle.textContent = '编辑菜单';
|
|
|
- editingId = id;
|
|
|
-
|
|
|
- // 填充表单数据
|
|
|
- document.getElementById('menuName').value = menu.menu_name;
|
|
|
- document.getElementById('parentMenu').value = menu.parent_id || '';
|
|
|
- document.getElementById('parentAuthName').value = menu.parent_auth_name || '';
|
|
|
- document.getElementById('icons').value = menu.icons || '';
|
|
|
- document.getElementById('openBlank').value = menu.open_blank || '';
|
|
|
- document.getElementById('target').value = menu.target || '';
|
|
|
- document.getElementById('linkUrl').value = menu.link_url || '';
|
|
|
- document.getElementById('sort').value = menu.sort;
|
|
|
- document.getElementById('status').value = menu.status;
|
|
|
- document.getElementById('remark').value = menu.remark || '';
|
|
|
-
|
|
|
- // 重新填充父级菜单选项(排除当前菜单及其子菜单)
|
|
|
- populateParentMenuOptions(id);
|
|
|
-
|
|
|
- menuModal.classList.add('active');
|
|
|
-}
|
|
|
-
|
|
|
- // 查看菜单
|
|
|
- function viewMenu(id) {
|
|
|
- const menu = currentData.find(item => item.id === id);
|
|
|
- if (!menu) return;
|
|
|
-
|
|
|
- alert(`菜单详情:\n\n` +
|
|
|
- `菜单名称:${menu.menu_name}\n` +
|
|
|
- `父级菜单ID:${menu.parent_id || '无'}\n` +
|
|
|
- `父级权限名称:${menu.parent_auth_name || '无'}\n` +
|
|
|
- `链接URL:${menu.link_url || '无'}\n` +
|
|
|
- `排序:${menu.sort}\n` +
|
|
|
- `状态:${menu.status === '0' ? '启用' : '停用'}\n` +
|
|
|
- `是否删除:${menu.del_flag === 'Y' ? '是' : '否'}\n` +
|
|
|
- `创建时间:${formatDate(menu.create_time)}\n` +
|
|
|
- `创建人:${menu.creator}\n` +
|
|
|
- `更新时间:${formatDate(menu.update_time)}\n` +
|
|
|
- `更新人:${menu.modifier}\n` +
|
|
|
- `备注:${menu.remark || '无'}`);
|
|
|
-}
|
|
|
-
|
|
|
- // 删除菜单
|
|
|
- function deleteMenu(id, name) {
|
|
|
- deletingId = id;
|
|
|
- deleteMenuName.textContent = name;
|
|
|
- deleteModal.classList.add('active');
|
|
|
-}
|
|
|
-
|
|
|
- // 恢复菜单
|
|
|
- function restoreMenu(id) {
|
|
|
- const index = currentData.findIndex(item => item.id === id);
|
|
|
- if (index !== -1) {
|
|
|
- currentData[index].del_flag = 'N';
|
|
|
- currentData[index].status = '0';
|
|
|
- renderMenuTree();
|
|
|
- renderTable();
|
|
|
- showMessage('菜单已恢复', 'success');
|
|
|
-}
|
|
|
-}
|
|
|
-
|
|
|
- // 确认删除
|
|
|
- function confirmDelete() {
|
|
|
- if (deletingId) {
|
|
|
- const index = currentData.findIndex(item => item.id === deletingId);
|
|
|
- if (index !== -1) {
|
|
|
- currentData[index].del_flag = 'Y';
|
|
|
- currentData[index].status = '1';
|
|
|
- currentData[index].update_time = new Date().toISOString().replace('T', ' ').substr(0, 19);
|
|
|
-
|
|
|
- // 如果删除的是当前选中的菜单,重置选中状态
|
|
|
- if (deletingId === selectedMenuId) {
|
|
|
- selectedMenuId = null;
|
|
|
-}
|
|
|
-
|
|
|
- renderMenuTree();
|
|
|
- renderTable();
|
|
|
- updateMenuTreeSelection();
|
|
|
- showMessage('菜单已删除', 'success');
|
|
|
-}
|
|
|
- closeDeleteModal();
|
|
|
-}
|
|
|
-}
|
|
|
-
|
|
|
- // 保存菜单
|
|
|
- function saveMenu() {
|
|
|
- // 简单的表单验证
|
|
|
- const menuName = document.getElementById('menuName').value.trim();
|
|
|
- if (!menuName) {
|
|
|
- showMessage('菜单名称不能为空', 'error');
|
|
|
- return;
|
|
|
-}
|
|
|
-
|
|
|
- const now = new Date();
|
|
|
- const formattedTime = now.toISOString().replace('T', ' ').substr(0, 19);
|
|
|
-
|
|
|
- if (editingId) {
|
|
|
- // 编辑现有菜单
|
|
|
- const index = currentData.findIndex(item => item.id === editingId);
|
|
|
- if (index !== -1) {
|
|
|
- currentData[index].menu_name = menuName;
|
|
|
- currentData[index].parent_id = document.getElementById('parentMenu').value || null;
|
|
|
- currentData[index].parent_auth_name = document.getElementById('parentAuthName').value || '';
|
|
|
- currentData[index].icons = document.getElementById('icons').value || null;
|
|
|
- currentData[index].open_blank = document.getElementById('openBlank').value || null;
|
|
|
- currentData[index].target = document.getElementById('target').value || null;
|
|
|
- currentData[index].link_url = document.getElementById('linkUrl').value || '';
|
|
|
- currentData[index].sort = parseInt(document.getElementById('sort').value) || 0;
|
|
|
- currentData[index].status = document.getElementById('status').value;
|
|
|
- currentData[index].remark = document.getElementById('remark').value || '';
|
|
|
- currentData[index].update_time = formattedTime;
|
|
|
- currentData[index].modifier = 'admin';
|
|
|
-
|
|
|
- // 更新parent_ids(简化处理,实际应用需要递归计算)
|
|
|
- const parentId = currentData[index].parent_id;
|
|
|
- if (parentId) {
|
|
|
- const parent = currentData.find(item => item.id === parseInt(parentId));
|
|
|
- if (parent) {
|
|
|
- currentData[index].parent_ids = parent.parent_ids ?
|
|
|
- `${parent.parent_ids},${parentId}` :
|
|
|
- `${parentId}`;
|
|
|
-}
|
|
|
-} else {
|
|
|
- currentData[index].parent_ids = '';
|
|
|
-}
|
|
|
-
|
|
|
- showMessage('菜单更新成功', 'success');
|
|
|
-}
|
|
|
-} else {
|
|
|
- // 新增菜单
|
|
|
- const newId = Math.max(...currentData.map(item => item.id)) + 1;
|
|
|
- const parentId = document.getElementById('parentMenu').value || null;
|
|
|
-
|
|
|
- // 计算parent_ids
|
|
|
- let parentIds = '';
|
|
|
- if (parentId) {
|
|
|
- const parent = currentData.find(item => item.id === parseInt(parentId));
|
|
|
- if (parent) {
|
|
|
- parentIds = parent.parent_ids ?
|
|
|
- `${parent.parent_ids},${parentId}` :
|
|
|
- `${parentId}`;
|
|
|
-}
|
|
|
-}
|
|
|
-
|
|
|
- const newMenu = {
|
|
|
- id: newId,
|
|
|
- menu_name: menuName,
|
|
|
- parent_id: parentId,
|
|
|
- parent_ids: parentIds,
|
|
|
- parent_auth_name: document.getElementById('parentAuthName').value || '',
|
|
|
- icons: document.getElementById('icons').value || null,
|
|
|
- open_blank: document.getElementById('openBlank').value || null,
|
|
|
- target: document.getElementById('target').value || null,
|
|
|
- link_url: document.getElementById('linkUrl').value || '',
|
|
|
- sort: parseInt(document.getElementById('sort').value) || 0,
|
|
|
- state: 0,
|
|
|
- status: document.getElementById('status').value,
|
|
|
- del_flag: 'N',
|
|
|
- creator: 'admin',
|
|
|
- create_time: formattedTime,
|
|
|
- modifier: 'admin',
|
|
|
- update_time: formattedTime,
|
|
|
- remark: document.getElementById('remark').value || ''
|
|
|
-};
|
|
|
-
|
|
|
- currentData.push(newMenu);
|
|
|
- showMessage('菜单新增成功', 'success');
|
|
|
-}
|
|
|
-
|
|
|
- // 刷新菜单树和表格
|
|
|
- renderMenuTree();
|
|
|
- renderTable();
|
|
|
- updateMenuTreeSelection();
|
|
|
- closeModal();
|
|
|
-}
|
|
|
-
|
|
|
- // 填充父级菜单选项(用于模态框)
|
|
|
- function populateParentMenuOptions(excludeId = null) {
|
|
|
- parentMenuSelect.innerHTML = '<option value="">无 (顶级菜单)</option>';
|
|
|
-
|
|
|
- // 获取未删除的菜单
|
|
|
- const availableMenus = currentData.filter(item =>
|
|
|
- item.del_flag === 'N' &&
|
|
|
- item.id !== excludeId &&
|
|
|
- // 排除当前菜单的子菜单(简化处理,实际应用需要递归检查)
|
|
|
- !(excludeId && item.parent_ids && item.parent_ids.includes(excludeId.toString()))
|
|
|
- );
|
|
|
-
|
|
|
- // 按层级添加缩进
|
|
|
- availableMenus.forEach(menu => {
|
|
|
- const indentLevel = menu.parent_ids ? menu.parent_ids.split(',').length : 0;
|
|
|
- const indent = ' '.repeat(indentLevel * 2);
|
|
|
- const option = document.createElement('option');
|
|
|
- option.value = menu.id;
|
|
|
- option.innerHTML = `${indent}${menu.menu_name}`;
|
|
|
- parentMenuSelect.appendChild(option);
|
|
|
-});
|
|
|
-}
|
|
|
-
|
|
|
- // 填充父级菜单选项(用于搜索)
|
|
|
- function populateSearchParentMenuOptions() {
|
|
|
- searchParentMenuSelect.innerHTML = '<option value="">全部</option><option value="null">顶级菜单</option>';
|
|
|
-
|
|
|
- // 获取未删除的菜单
|
|
|
- const availableMenus = currentData.filter(item =>
|
|
|
- item.del_flag === 'N'
|
|
|
- );
|
|
|
-
|
|
|
- // 按层级添加缩进
|
|
|
- availableMenus.forEach(menu => {
|
|
|
- const indentLevel = menu.parent_ids ? menu.parent_ids.split(',').length : 0;
|
|
|
- const indent = ' '.repeat(indentLevel * 2);
|
|
|
- const option = document.createElement('option');
|
|
|
- option.value = menu.id;
|
|
|
- option.innerHTML = `${indent}${menu.menu_name}`;
|
|
|
- searchParentMenuSelect.appendChild(option);
|
|
|
-});
|
|
|
-}
|
|
|
-
|
|
|
- // 分页导航
|
|
|
- function goToPage(page) {
|
|
|
- currentPage = page;
|
|
|
- renderTable();
|
|
|
-}
|
|
|
-
|
|
|
- function goToPrevPage() {
|
|
|
- if (currentPage > 1) {
|
|
|
- currentPage--;
|
|
|
- renderTable();
|
|
|
-}
|
|
|
-}
|
|
|
-
|
|
|
- function goToNextPage() {
|
|
|
- const totalPages = Math.ceil(filteredData.length / itemsPerPage);
|
|
|
-
|
|
|
- if (currentPage < totalPages) {
|
|
|
- currentPage++;
|
|
|
- renderTable();
|
|
|
-}
|
|
|
-}
|
|
|
-
|
|
|
- // 关闭模态框
|
|
|
- function closeModal() {
|
|
|
- menuModal.classList.remove('active');
|
|
|
-}
|
|
|
-
|
|
|
- function closeDeleteModal() {
|
|
|
- deleteModal.classList.remove('active');
|
|
|
- deletingId = null;
|
|
|
-}
|
|
|
-
|
|
|
- // 格式化日期
|
|
|
- function formatDate(dateString) {
|
|
|
- const date = new Date(dateString);
|
|
|
- return date.toLocaleDateString('zh-CN') + ' ' + date.toLocaleTimeString('zh-CN', {hour12: false});
|
|
|
-}
|
|
|
-
|
|
|
- // 格式化短日期
|
|
|
- function formatDateShort(dateString) {
|
|
|
- const date = new Date(dateString);
|
|
|
- return date.toLocaleDateString('zh-CN');
|
|
|
-}
|
|
|
-
|
|
|
- // 显示消息提示
|
|
|
- function showMessage(message, type) {
|
|
|
- // 创建消息元素
|
|
|
- const messageEl = document.createElement('div');
|
|
|
- messageEl.textContent = message;
|
|
|
- messageEl.style.cssText = `
|
|
|
- position: fixed;
|
|
|
- top: 20px;
|
|
|
- right: 20px;
|
|
|
- padding: 12px 20px;
|
|
|
- border-radius: 4px;
|
|
|
- color: white;
|
|
|
- font-size: 14px;
|
|
|
- font-weight: 500;
|
|
|
- z-index: 9999;
|
|
|
- box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
|
|
|
- animation: slideIn 0.3s, fadeOut 0.3s 2.7s;
|
|
|
- `;
|
|
|
-
|
|
|
- // 根据类型设置背景色
|
|
|
- if (type === 'success') {
|
|
|
- messageEl.style.backgroundColor = 'var(--success-color)';
|
|
|
-} else if (type === 'error') {
|
|
|
- messageEl.style.backgroundColor = 'var(--danger-color)';
|
|
|
-} else if (type === 'warning') {
|
|
|
- messageEl.style.backgroundColor = 'var(--warning-color)';
|
|
|
-} else {
|
|
|
- messageEl.style.backgroundColor = 'var(--info-color)';
|
|
|
-}
|
|
|
-
|
|
|
- document.body.appendChild(messageEl);
|
|
|
-
|
|
|
- // 3秒后移除消息
|
|
|
- setTimeout(() => {
|
|
|
- if (messageEl.parentNode) {
|
|
|
- messageEl.parentNode.removeChild(messageEl);
|
|
|
-}
|
|
|
-}, 3000);
|
|
|
-}
|
|
|
-
|
|
|
- // 添加CSS动画
|
|
|
- const style = document.createElement('style');
|
|
|
- style.textContent = `
|
|
|
- @keyframes slideIn {
|
|
|
- from {
|
|
|
- transform: translateX(100%);
|
|
|
- opacity: 0;
|
|
|
-}
|
|
|
- to {
|
|
|
- transform: translateX(0);
|
|
|
- opacity: 1;
|
|
|
-}
|
|
|
-}
|
|
|
-
|
|
|
- @keyframes fadeOut {
|
|
|
- from {
|
|
|
- opacity: 1;
|
|
|
-}
|
|
|
- to {
|
|
|
- opacity: 0;
|
|
|
-}
|
|
|
-}
|
|
|
- `;
|
|
|
- document.head.appendChild(style);
|
|
|
+ const toggleSearchFormBtn = document.getElementById('toggleSearchForm');
|
|
|
+ const searchForm = document.getElementById('searchForm');
|
|
|
+ searchFormExpanded = !searchFormExpanded;
|
|
|
+ if (searchFormExpanded) {
|
|
|
+ searchForm.classList.remove('collapsed');
|
|
|
+ toggleSearchFormBtn.innerHTML = '<i class="fas fa-chevron-up"></i><span>收起</span>';
|
|
|
+ } else {
|
|
|
+ searchForm.classList.add('collapsed');
|
|
|
+ toggleSearchFormBtn.innerHTML = '<i class="fas fa-chevron-down"></i><span>展开</span>';
|
|
|
+ }
|
|
|
+ }
|
|
|
+});
|