# osAdmin后台管理系统 **Repository Path**: lc1001/osadmin ## Basic Information - **Project Name**: osAdmin后台管理系统 - **Description**: osAdmin 是一款基于原生Layui,开箱即用的Layui-Admin 后台管理系统前端模板,简洁易用,规范标准,专为开发者打造,能够快速二次部署与开发。 - **Primary Language**: Unknown - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 2 - **Forks**: 2 - **Created**: 2026-03-29 - **Last Updated**: 2026-06-27 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # OSADMIN 后台管理系统开发文档 ## 📋 项目概述 **项目名称**: OSADMIN\ **版本**: 1.9.4\ **描述**: 基于 LayUI 的轻量化原生管理后台系统\ **技术栈**: LayUI + jQuery + 原生 JavaScript\ **架构模式**: 模块化架构 + 配置驱动\ **开源协议**: Apache 2.0 ### 核心特性 - ✅ **模块化架构**: 基于 LayUI 模块系统,按需加载 - ✅ **配置驱动**: JSON 配置文件驱动,灵活可扩展 - ✅ **权限管理**: 完善的权限控制系统 - ✅ **角色主题系统**: 基于角色的主题权限配置,支持精细化主题管理 - ✅ **主题系统**: 支持多主题切换和自定义,暗主题全面适配 18+ LayUI 组件,WCAG 对比度 90%+ 合规 - ✅ **间距系统**: 7级 CSS 变量间距系统,支持紧凑模式全局缩放 - ✅ **路由管理**: Hash 路由,支持 ID 和 Code 混合路由,完整查询参数支持 - ✅ **资源按需加载**: 页面级 CSS/JS 按需加载,支持动态 meta 信息 - ✅ **智能组件渲染**: 自动检测并渲染 LayUI 组件,支持按需加载模块 - ✅ **水印系统**: Canvas 水印,支持防删除保护和动态文本 - ✅ **性能优化**: 骨架屏、资源预加载、并行配置加载、Service Worker 缓存 - ✅ **Toast 组件**: 支持堆叠/替换模式、消散动画、数量限制 - ✅ **组件丰富**: 封装多种常用组件 - ✅ **响应式设计**: 适配多种屏幕尺寸 *** ## 📁 项目结构 ```HTML osadmin/ ├── admin/ # 管理后台核心目录 │ ├── css/ # 样式文件 │ │ ├── admin.css # 主样式文件 │ │ ├── theme.css # 主题样式 │ │ ├── index.css # 首页样式 │ │ ├── layui-override/ # LayUI 样式覆盖 │ │ │ ├── button.css # 按钮样式覆盖 │ │ │ ├── form.css # 表单样式覆盖 │ │ │ ├── table.css # 表格样式覆盖 │ │ │ ├── nav.css # 导航样式覆盖 │ │ │ ├── panel.css # 面板样式覆盖 │ │ │ ├── tabs.css # 标签页样式覆盖 │ │ │ ├── layer.css # 弹层样式覆盖 │ │ │ ├── laydate.css # 日期选择器样式覆盖 │ │ │ ├── laypage.css # 分页样式覆盖 │ │ │ ├── menu.css # 菜单样式覆盖 │ │ │ ├── layout.css # 布局样式覆盖 │ │ │ ├── carousel.css # 轮播样式覆盖 │ │ │ ├── rate.css # 评分样式覆盖 │ │ │ ├── slider.css # 滑块样式覆盖 │ │ │ ├── colorpicker.css # 颜色选择器样式覆盖 │ │ │ ├── transfer.css # 穿梭框样式覆盖 │ │ │ ├── tree.css # 树形样式覆盖 │ │ │ ├── upload.css # 上传样式覆盖 │ │ │ ├── progress.css # 进度条样式覆盖 │ │ │ ├── timeline.css # 时间线样式覆盖 │ │ │ ├── badge.css # 徽章样式覆盖 │ │ │ ├── code.css # 代码块样式覆盖 │ │ │ ├── flow.css # 流加载样式覆盖 │ │ │ ├── auxiliary.css # 辅助元素样式覆盖 │ │ │ ├── text.css # 文本样式覆盖 │ │ │ ├── util.css # 工具样式覆盖 │ │ │ └── xm-select.css # 多选下拉样式覆盖 │ │ ├── extends/ # 扩展样式 │ │ │ ├── toast.css # 提示框样式 │ │ │ └── resetForm.css # 表单重置样式 │ │ └── view/ # 页面样式 │ │ └── dashboard.css # 仪表盘样式 │ └── js/ # JavaScript 文件 │ ├── index.js # 全局入口文件 │ ├── init.js # 初始化脚本 │ ├── layui-init.js # LayUI初始化 │ ├── service-worker.js # Service Worker 缓存 │ └── extends/ # 扩展脚本 │ └── searchForm.js # 表单搜索扩展 │ ├── config/ # 配置文件目录 │ ├── app.json # 应用配置文件 │ └── menu.json # 菜单配置文件 │ ├── docs/ # 文档目录 │ ├── permission-guide.md # 权限模块使用指南 │ └── README.md # 开发文档(本文件) │ ├── lib/ # 第三方库目录 │ ├── layui/ # LayUI 框架 │ │ ├── layui.js # LayUI 核心 │ │ ├── css/ # LayUI 样式 │ │ └── font/ # LayUI 字体图标 │ ├── echarts/ # ECharts 图表库 │ │ └── echarts.min.js │ ├── xm-select/ # XM-Select 下拉选择 │ │ └── xm-select.js │ └── tinymce/ # TinyMCE 富文本编辑器 │ ├── tinymce.min.js # TinyMCE 核心 │ ├── skins/ # 皮肤文件 │ ├── plugins/ # 插件文件 │ ├── themes/ # 主题文件 │ ├── icons/ # 图标文件 │ └── langs/ # 语言包 │ ├── modules/ # 模块目录 │ ├── app.js # 主应用模块 │ ├── common/ # 公共模块 │ │ ├── router.js # 路由模块 │ │ ├── theme.js # 主题模块 │ │ ├── permission.js # 权限模块 │ │ └── component-renderer.js # 组件渲染模块 │ ├── components/ # 组件模块 │ │ ├── sidebar.js # 侧边栏组件 │ │ └── tabs.js # 标签页组件 │ └── extends/ # 扩展模块 │ ├── common.js # 公共扩展 │ ├── count.js # 计数器 │ ├── echarts.js # 图表扩展 │ ├── xm-select.js # 下拉选择扩展 │ ├── tinymce.js # 富文本编辑器扩展 │ ├── toast.js # 提示框 │ ├── drawer.js # 抽屉组件 │ └── laydrawer.js # LayUI 抽屉 │ ├── view/ # 页面视图目录 │ ├── dashboard.html # 仪表盘页面 │ ├── settings.html # 设置页面 │ ├── permission-demo.html # 权限示例页面 │ ├── components/ # 组件示例页面 │ │ ├── form-demo.html # 表单示例 │ │ ├── button-demo.html # 按钮示例 │ │ ├── table-demo.html # 表格示例 │ │ ├── layer-demo.html # 弹层示例 │ │ ├── laydate-demo.html # 日期示例 │ │ ├── dropdown-demo.html # 下拉菜单示例 │ │ ├── drawer-demo.html # 抽屉示例 │ │ ├── echarts-demo.html # 图表示例 │ │ ├── xm-select-demo.html # 下拉选择示例 │ │ ├── tinymce-demo.html # 富文本编辑器示例 │ │ ├── toast-demo.html # 提示框示例 │ │ ├── form-comprehensive.html # 综合表单 │ │ ├── tabs-demo.html # 标签页示例 │ │ ├── carousel-demo.html # 轮播示例 │ │ ├── rate-demo.html # 评分示例 │ │ ├── slider-demo.html # 滑块示例 │ │ ├── transfer-demo.html # 穿梭框示例 │ │ ├── tree-demo.html # 树形示例 │ │ ├── colorpicker-demo.html # 颜色选择器示例 │ │ ├── laypage-demo.html # 分页示例 │ │ ├── progress-demo.html # 进度条示例 │ │ ├── util-demo.html # 工具示例 │ │ ├── flow-demo.html # 流加载示例 │ │ ├── code-demo.html # 代码块示例 │ │ ├── laytpl-demo.html # 模板示例 │ │ ├── nav-demo.html # 导航示例 │ │ ├── breadcrumb-demo.html # 面包屑示例 │ │ ├── collapse-demo.html # 折叠面板示例 │ │ ├── treeTable-demo.html # 树表示例 │ │ ├── upload-demo.html # 上传示例 │ │ ├── watermark-demo.html # 水印示例 │ │ ├── iconPicker-demo.html # 图标选择器示例 │ │ ├── icon-demo.html # 图标示例 │ │ ├── badge-demo.html # 徽章示例 │ │ ├── timeline-demo.html # 时间线示例 │ │ ├── anim-demo.html # 动画示例 │ │ └── laydrawer-demo.html # 抽屉组件示例 │ ├── theme-preview.html # 主题预览页面 │ └── data/ # 示例数据 │ ├── notifications.json # 通知数据 │ ├── permission.json # 权限数据 │ ├── permission-super.json # 超级管理员权限 │ ├── permission-operator.json # 运营人员权限 │ ├── permission-manager.json # 业务经理权限 │ └── permission-readme.md # 权限数据说明 │ ├── index.html # 入口页面 └── favicon.ico # 网站图标 ``` *** ## 🚀 快速开始 ### 环境要求 - Node.js >= 12.0.0 (可选,用于本地开发服务器) - 现代浏览器 (Chrome, Firefox, Safari, Edge) - Web 服务器 (Nginx, Apache, 或本地开发服务器) ### 安装步骤 1. **克隆项目** ```bash git clone cd osadmin ``` 1. **启动本地服务器** 方式1: 使用 Python ```bash # Python 3 python -m http.server 8080 # Python 2 python -m SimpleHTTPServer 8080 ``` 方式2: 使用 Node.js ```bash npx http-server -p 8080 ``` 方式3: 使用 VS Code Live Server 插件 1. **访问系统** ``` http://localhost:8080 ``` ### 目录权限 确保以下目录有写入权限: - `config/` - 配置文件目录 - `view/data/` - 数据文件目录 *** ## ⚙️ 配置说明 ### 1. 应用配置 (config/app.json) 应用配置文件包含系统的所有配置项。 #### 基础配置 ```json { "name": "OSADMIN", "version": "1.0.0", "description": "基于layui原生管理后台系统" } ``` ### 水印系统 系统内置了强大的水印功能,支持动态文本、防删除保护和性能优化。 #### 基本配置 ```json { "watermark": { "enabled": true, "text": "OSADMIN", "dynamicTextKey": "username", "fontSize": 14, "color": "rgba(0, 0, 0, 0.08)", "rotate": -22, "gapX": 100, "gapY": 100 } } ``` #### 水印特性 ##### 1. 动态文本支持 支持从 sessionStorage 中读取动态文本作为水印内容: ```javascript // 简单键名 sessionStorage.setItem('username', '张三'); // 嵌套键名(支持多层级) sessionStorage.setItem('userInfo', JSON.stringify({ admin: { info: { userName: '张三' } } })); // 配置中使用嵌套路径 { "watermark": { "dynamicTextKey": "userInfo.admin.info.userName" } } ``` ##### 2. 防删除保护 使用 MutationObserver 监听水印节点,自动恢复被删除或修改的水印: - **节点删除保护**: 检测到水印节点被删除时自动恢复 - **样式修改保护**: 检测到 `display`、`visibility`、`opacity` 等样式被修改时自动恢复 - **控制台警告**: 删除或修改水印时在控制台输出警告信息 ##### 3. Canvas 缓存机制 使用 Canvas 生成水印图片并缓存,提升性能: - **缓存策略**: 根据水印参数(文本、字体、颜色、旋转角度、间距)生成缓存键 - **性能提升**: 相同参数的水印只生成一次,后续直接使用缓存 - **精确测量**: 使用 `ctx.measureText()` 精确测量文本宽度,优化水印间距 ##### 4. 主题自动适配 水印颜色会根据主题模式自动调整: - **亮色主题**: 使用配置的颜色(默认 `rgba(0, 0, 0, 0.08)`) - **暗色主题**: 自动切换为 `rgba(255, 255, 255, 0.06)` #### 使用方法 ##### 启用/禁用水印 ```javascript var theme = OSLAY.modules.theme; // 启用水印 theme.setState({ watermarkEnabled: true }); // 禁用水印 theme.setState({ watermarkEnabled: false }); // 设置水印文本 theme.setState({ watermarkText: '机密文件' }); ``` ##### 动态设置水印 ```javascript // 用户登录后设置水印 sessionStorage.setItem('username', '张三'); theme.applyWatermark(true, '张三'); // 使用嵌套数据 var userData = { admin: { name: '张三', department: '技术部' } }; sessionStorage.setItem('userData', JSON.stringify(userData)); // 配置文件中 { "watermark": { "dynamicTextKey": "userData.admin.name" } } ``` #### 水印优先级 水印文本的获取优先级: 1. **sessionStorage 动态文本** (最高优先级) - 从 `dynamicTextKey` 配置的键名读取 2. **state.watermarkText** - 通过 `theme.setState({ watermarkText: 'xxx' })` 设置的文本 3. **配置文件中的 text** - `app.json` 中 `watermark.text` 的值 #### API 接口 ```javascript var theme = OSLAY.modules.theme; // 应用水印 theme.applyWatermark(enabled, text); // 获取水印文本 var watermarkText = theme.getWatermarkText(); // 获取嵌套对象值 var value = theme.getNestedValue(obj, 'path.to.value'); // 启动水印监听 theme.startWatermarkObserver(); // 停止水印监听 theme.stopWatermarkObserver(); ``` #### 注意事项 1. **性能考虑**: 水印使用 Canvas 生成,大量不同参数的水印会占用内存 2. **安全提示**: 前端水印可被技术手段绕过,重要场景需配合后端水印 3. **浏览器兼容**: 需要浏览器支持 Canvas API 和 MutationObserver 4. **sessionStorage 限制**: sessionStorage 大小限制约 5MB,避免存储过大数据 #### 站点配置 ```json { "site": { "name": "OSADMIN", "title": "OSADMIN", "logo": "favicon.ico", "keywords": "OSADMIN", "description": "OSADMIN 轻量化原生管理后台" } } ``` #### 路由配置 ```json { "router": { "mode": "hash", // 路由模式: hash | history "base": "/" // 路由基础路径 } } ``` #### 主题配置 ```json { "theme": { "defaultMode": "light", // 默认主题: light | dark "defaultColor": "#16baaa", // 默认主题色 "defaultLayout": "double", // 默认布局: single | double "tabsVisible": true, // 是否显示标签页 "rememberTabs": true, // 是否记住标签页 "accordion": false, // 菜单是否手风琴模式 "pageAnimation": "fadeIn" // 页面动画: fadeIn | slideIn | none } } ``` #### 水印配置 ```json { "watermark": { "enabled": true, // 是否启用水印 "text": "OSADMIN", // 水印默认文字 "dynamicTextKey": "username", // 动态文本键名,支持嵌套路径如 "userInfo.admin.userName" "fontSize": 14, // 字体大小 "color": "rgba(0, 0, 0, 0.08)", // 水印颜色 "rotate": -22, // 旋转角度 "gapX": 100, // X轴间距 "gapY": 100 // Y轴间距 } } ``` #### 资源配置 ```json { "resources": { "url": "config/resources.json" // 资源配置文件路径 } } ``` #### TinyMCE 配置 ```json { "tinymce": { "uploadUrl": "" // 图片上传地址(空表示关闭上传功能) } } ``` **水印特性说明**: - **动态文本**: 支持从 sessionStorage 中读取动态文本,如用户名 - **嵌套键名**: 支持使用点号分隔的嵌套路径,如 `"userInfo.admin.userName"` - **防删除保护**: 使用 MutationObserver 监听水印节点,自动恢复被删除的水印 - **Canvas 缓存**: 使用缓存机制提升水印生成性能 - **主题适配**: 自动适配亮色/暗色主题,调整水印颜色 #### 多语言配置 ```json { "lang": { "default": "zh-CN", // 默认语言 "list": [ // 支持的语言列表 { "code": "zh-CN", "name": "简体中文" }, { "code": "zh-TW", "name": "繁體中文" }, { "code": "en", "name": "English" } ] } } ``` #### 主题色配置 ```JSON { "colors": { "#16baaa": { "hover": "#14a090", // 悬停色 "rgb": "22, 186, 170" // RGB 值 }, "#16b777": { "hover": "#12a066", "rgb": "22, 183, 119" }, "#1e9fff": { "hover": "#1a8fe6", "rgb": "30, 159, 255" }, "#ff5722": { "hover": "#e64a19", "rgb": "255, 87, 34" }, "#ffb800": { "hover": "#e6a600", "rgb": "255, 184, 0" }, "#a233c6": { "hover": "#8e2db0", "rgb": "162, 51, 198" } } } ``` #### 布局配置 ```json { "sidebar": { "width": 220, // 侧边栏宽度 "collapsedWidth": 64, // 折叠后宽度 "submenuWidth": 180 // 子菜单宽度 }, "topbar": { "height": 50 // 顶部栏高度 }, "tabs": { "height": 40, // 标签页高度 "maxTabs": 20 // 最大标签页数量 } } ``` #### 存储配置 ```json { "storage": { "themeKey": "themeConfig", // 主题存储键 "tabsKey": "tabsState", // 标签页存储键 "langKey": "langConfig" // 语言存储键 } } ``` #### 菜单配置 ```json { "menu": { "selectId": 0, // 默认选中菜单ID "url": "config/menu.json", // 菜单配置文件路径 "method": "GET", // 请求方法 "async": true, // 是否异步加载 "cache": true, // 是否缓存菜单数据(默认 true) "data": [] // 内联菜单数组(优先于 url,可选) } } ``` #### 权限配置 ```json { "permission": { "enabled": true, // 是否启用权限 "url": "view/data/permission.json", // 权限接口地址 "method": "GET", // 请求方法 "cache": true // 是否缓存权限(默认 true) } } ``` ### 2. 菜单配置 (config/menu.json) 菜单配置文件定义系统的导航菜单结构。 #### 菜单项结构 ```json { "id": 1, // 菜单ID (唯一) "type": 1, // 类型: 0=目录, 1=菜单 "code": "view/dashboard", // 菜单代码 (唯一) "title": "控制台", // 菜单标题 "icon": "layui-icon-console", // 菜单图标 "href": "view/dashboard.html", // 页面路径 "openType": "_blank", // 打开方式 (可选,仅菜单类型有效) "closable": true, // 是否可关闭 "children": [] // 子菜单 } ``` #### type 类型定义 | type | 含义 | 特征 | |------|------|------| | `0` | 目录 | 有 `children` 且非空 | | `1` | 菜单 | 有 `href`,无 `children` 或 `children` 为空 | #### openType 打开方式 (仅菜单类型有效) | openType | 含义 | 行为 | |----------|------|------| | `_blank` | 新标签页 | `window.open(href, '_blank')` | | `_iframe` | 内嵌 iframe | 主页面显示 iframe | | `_dialog` | 弹窗 | `layer.open({ type: 2, content: href })` | | 无 | 默认 | 内部页面 AJAX 加载 | #### 菜单示例 ```json [ { "id": 0, "type": 1, "code": "view/dashboard", "title": "控制台", "icon": "layui-icon-console", "href": "view/dashboard.html", "closable": false }, { "id": 1, "type": 0, "code": "system", "title": "系统管理", "icon": "layui-icon-set", "children": [ { "id": 10, "type": 1, "code": "view/user", "title": "用户管理", "icon": "layui-icon-user", "href": "view/user.html" }, { "id": 11, "type": 1, "code": "view/role", "title": "角色管理", "icon": "layui-icon-group", "href": "view/role.html" } ] }, { "id": 100, "type": 0, "code": "external-links", "title": "外部链接", "icon": "layui-icon-link", "children": [ { "id": 101, "type": 1, "code": "external/baidu", "title": "百度搜索", "icon": "layui-icon-search", "href": "https://www.baidu.com", "openType": "_blank" }, { "id": 102, "type": 1, "code": "external/monitor", "title": "监控大屏", "icon": "layui-icon-chart-screen", "href": "https://monitor.example.com", "openType": "_iframe" } ] } ] ``` #### 菜单属性说明 | 属性 | 类型 | 必填 | 说明 | | -------- | ------- | -- | ---------------- | | id | Number | 是 | 菜单唯一标识 | | type | Number | 否 | 类型: 0=目录, 1=菜单 (默认根据 children 自动判断) | | code | String | 是 | 菜单代码,用于路由 | | title | String | 是 | 菜单显示标题 | | icon | String | 否 | LayUI 图标类名 | | href | String | 否 | 页面路径 (支持外链) | | openType | String | 否 | 打开方式: `_blank`/`_iframe`/`_dialog` (仅菜单类型有效) | | closable | Boolean | 否 | 标签页是否可关闭,默认 true | | children | Array | 否 | 子菜单数组 | *** ## 📦 资源按需加载 ### 功能概述 系统支持页面级资源按需加载,可以在页面加载时动态注入 CSS、JS 资源,并支持动态更新页面的 title、keywords、description 等 meta 信息。 ### 配置文件 资源配置文件位于 `config/resources.json`。 #### 配置结构 ```json { "pages": { "view/dashboard.html": { "title": "控制台", "keywords": "控制台,仪表盘,数据概览", "description": "系统控制台,展示关键业务数据指标", "css": ["admin/css/view/dashboard.css"], "js": ["admin/js/view/dashboard.js"], "dependencies": ["echarts"] } }, "global": { "css": ["lib/layui/css/layui.css", "admin/css/index.css"], "js": ["lib/layui/layui.js", "admin/js/index.js"] }, "externals": { "echarts": { "js": "lib/echarts/echarts.min.js", "css": null, "global": "echarts" }, "xmSelect": { "js": "lib/xm-select/xm-select.js", "css": "lib/xm-select/xm-select.css", "global": "xmSelect" } } } ``` #### 配置项说明 | 配置项 | 类型 | 说明 | | --------- | ------ | ------- | | pages | Object | 页面级资源配置 | | global | Object | 全局资源配置 | | externals | Object | 外部依赖配置 | #### 页面配置属性 | 属性 | 类型 | 必填 | 说明 | | ------------ | ------ | -- | -------------- | | title | String | 否 | 页面标题,会自动拼接站点名称 | | keywords | String | 否 | 页面关键词,用于 SEO | | description | String | 否 | 页面描述,用于 SEO | | css | Array | 否 | 页面专属 CSS 文件列表 | | js | Array | 否 | 页面专属 JS 文件列表 | | dependencies | Array | 否 | 依赖的外部模块列表 | ### Meta 信息优先级 系统支持三种方式配置页面 meta 信息,优先级从高到低: ``` 页面 HTML meta > resources.json 配置 > 菜单 title ``` #### 方式一:页面 HTML(最高优先级) 在页面 HTML 的 `` 中定义: ```html 商品列表 - 库存管理系统
``` #### 方式二:resources.json 配置 在资源配置文件中定义: ```json { "pages": { "view/product-list.html": { "title": "商品列表", "keywords": "商品,列表,库存", "description": "商品列表管理页面", "css": ["view/css/product-list.css"], "js": ["view/js/product-list.js"] } } } ``` #### 方式三:菜单 title(兜底) 使用菜单配置中的 title 作为页面标题: ```json { "id": 10, "title": "商品列表", "href": "view/product-list.html" } ``` ### 外部依赖管理 系统支持定义外部依赖模块,可在多个页面间复用: ```json { "externals": { "echarts": { "js": "lib/echarts/echarts.min.js", "css": null, "global": "echarts" } } } ``` 在页面中引用: ```json { "pages": { "view/components/echarts-demo.html": { "dependencies": ["echarts"] } } } ``` ### API 接口 #### resourceLoader 模块 ```javascript // 获取页面配置 var pageConfig = resourceLoader.getPageConfig('view/dashboard.html'); // 加载页面资源 resourceLoader.loadPageResources('view/dashboard.html').done(function() { console.log('资源加载完成'); }); // 加载单个 CSS resourceLoader.loadCSS('admin/css/custom.css'); // 加载单个 JS resourceLoader.loadJS('admin/js/custom.js'); // 加载依赖模块 resourceLoader.loadDependency('echarts'); // 检查资源是否已加载 var loaded = resourceLoader.isLoaded('css', 'admin/css/custom.css'); // 清除缓存 resourceLoader.clearCache(); ``` ### 最佳实践 1. **资源分离**: 将页面专属的 CSS/JS 放在独立的目录中 2. **依赖复用**: 使用 externals 定义公共依赖 3. **按需配置**: 只配置页面真正需要的资源 4. **SEO 优化**: 为重要页面配置完整的 meta 信息 *** ## 🏗️ 架构设计 ### 模块化架构 系统采用 LayUI 的模块化架构,所有功能模块化开发。 #### 模块分类 ``` 模块类型 ├── 核心模块 (Core Modules) │ ├── app.js # 主应用模块 │ ├── router.js # 路由模块 │ ├── theme.js # 主题模块 │ ├── permission.js # 权限模块 │ └── component-renderer.js # 组件渲染模块 │ ├── 组件模块 (Component Modules) │ ├── sidebar.js # 侧边栏组件 │ └── tabs.js # 标签页组件 │ └── 扩展模块 (Extension Modules) ├── common.js # 公共扩展 ├── echarts.js # 图表扩展 ├── xm-select.js # 下拉选择扩展 ├── toast.js # 提示框扩展 ├── drawer.js # 抽屉组件 └── laydrawer.js # LayUI 抽屉 ``` #### 模块定义规范 ```javascript layui.define(['jquery', '依赖模块'], function(exports) { 'use strict'; var $ = layui.jquery; var Module = { // 模块属性 property: null, // 初始化方法 init: function(options) { // 初始化逻辑 return this; }, // 公共方法 method: function() { // 方法逻辑 } }; exports('moduleName', Module); }); ``` #### 模块使用方式 ```javascript // 方式1: 通过 OSLAY 全局对象 OSLAY.ready(function(modules) { var module = modules.moduleName; module.method(); }); // 方式2: 通过 LayUI use layui.use(['moduleName'], function() { var module = layui.moduleName; module.method(); }); ``` ### 初始化流程 ``` 页面加载 ↓ 加载 index.js ↓ 加载 LayUI 框架 ↓ 加载 app.json 配置 ↓ 加载 menu.json 配置 ↓ 注册所有模块 ↓ 初始化权限模块 ↓ 初始化主应用模块 ↓ 系统就绪 ↓ 触发 ready 回调 ``` ### 路由系统 系统支持 Hash 路由模式,支持 ID 和 Code 混合路由。 #### 路由格式 ``` Hash 路由格式: http://example.com/#/view/dashboard http://example.com/#/view/user http://example.com/#/view/dashboard?id=123&keyword=test ``` #### 路由跳转 ```javascript // 方式1: 通过路由模块 var router = OSLAY.modules.router; router.go('view/dashboard'); // 方式2: 通过标签页模块 var tabs = OSLAY.modules.tabs; tabs.add({ id: 'dashboard', title: '控制台', href: 'view/dashboard.html' }); // 方式3: 直接修改 hash window.location.hash = '#/view/dashboard'; ``` #### 路由监听 ```javascript var router = OSLAY.modules.router; // 监听路由变化 router.on('change', function(route) { console.log('路由变化:', route); }); ``` #### 查询参数支持 路由系统完整支持查询参数,可通过以下方式获取: ```javascript // 获取所有查询参数(对象形式) var params = layui.routerModule.getQueryParams(); // 输出: { id: "123", keyword: "test" } // 获取单个参数 var keyword = layui.routerModule.getQueryParam('keyword'); // 输出: "test" // 获取原始查询字符串 var queryString = layui.routerModule.getQueryString(); // 输出: "id=123&keyword=test" ``` *** ## 🎨 主题系统 ### 角色主题权限配置 基于角色的主题权限控制系统,不同角色拥有不同的主题配置权限,实现精细化的主题管理。 #### 角色权限示例 | 权限项 | admin (超级管理员) | employee (员工) | vip (会员) | |--------|:-----------------:|:---------------:|:----------:| | 完整配置面板 | ✅ | ✅ | ❌ 切换按钮 | | 明暗模式切换 | ✅ | ✅ | ✅ | | 配色方案选择 | ✅ 6种 | ✅ 6种 | 🔒 仅白名单3种 | | 自定义颜色 | ✅ | ❌ | ❌ | | 布局模式 | ✅ 3种 | ✅ 3种 | 🔒 仅下拉菜单 | | 紧凑模式 | ✅ | ✅ | ❌ | | 侧边栏宽度 | ✅ | ✅ | ❌ | | 子菜单宽度 | ✅ | ✅ | ❌ | #### 核心特性 - **localStorage 隔离**: 不同角色使用独立的存储键(`osadmin_{role}_themeConfig`) - **运行时切换**: 支持通过 `theme.setRole('admin')` 动态切换角色 - **白名单机制**: 支持方案/配色/布局的白名单限制 - **默认配置锁定**: 特定角色可强制使用指定配置 ### 间距系统与紧凑模式 系统实现了 7 级 CSS 变量间距系统,并支持紧凑模式全局缩放。 #### 间距变量定义 ```css :root { --space-xs: 4px; /* 微间距 - 图标与文字间距 */ --space-sm: 8px; /* 小间距 - 紧凑元素间距 */ --space-md: 12px; /* 中间距 - 默认紧凑模式基准 */ --space-base: 16px; /* 基准间距 - 内容区间距、卡片间距 */ --space-lg: 20px; /* 大间距 - 卡片内边距、表单项间距 */ --space-xl: 24px; /* 超大间距 - 区块间距 */ --space-2xl: 32px; /* 2倍大间距 - 页面级间距 */ } ``` #### 紧凑模式 通过 `[data-density="compact"]` 属性实现全局紧凑缩放,同时支持导航高度变量化: - `--nav-item-height`: 52px → 44px - `--nav-sub-item-height`: 46px → 38px ### 侧边栏与子菜单宽度配置 支持在主题配置面板中调整侧边栏和子菜单宽度: | 配置项 | 可调范围 | 默认值 | |--------|----------|--------| | 侧边栏宽度 | 160-320px | 210px | | 子菜单宽度(弹性双列) | 140-240px | 180px | | 子菜单宽度(固定双列) | 140-240px | 180px | > **注意**: 弹性双列和固定双列的子面板宽度是**独立配置**的,使用不同的 CSS 变量。 ### 主题切换 系统支持亮色/暗色主题切换。 #### 切换主题 ```javascript var theme = OSLAY.modules.theme; // 切换到亮色主题 theme.setMode('light'); // 切换到暗色主题 theme.setMode('dark'); // 切换主题色 theme.setColor('#16baaa'); ``` #### 主题配置 ```json { "theme": { "defaultMode": "light", "defaultScheme": "indigo", "defaultColor": "#16baaa", "defaultLayout": "double", "tabsVisible": true, "accordion": false, "pageAnimation": "fadeIn" }, "sidebar": { "width": 210, "collapsedWidth": 64, "submenuWidth": 180 } } ``` ### CSS 变量系统 系统使用 CSS 变量实现主题定制和间距管理。 ```css :root { /* 主题色 */ --accent: #6366f1; --accent-hover: #4f46e5; --accent-light: rgba(99,102,241,0.1); --accent-rgb: 99,102,241; /* 背景色 */ --bg: #f8f8f8; --bg-sidebar: #ffffff; --bg-topbar: #ffffff; --bg-tabs: #ffffff; --bg-content: #f8fafc; --card-bg: #ffffff; /* 文字色 */ --text-primary: rgba(0, 0, 0, 0.85); --text-secondary: #333; --text-muted: #999; /* 边框色 */ --border: #e2e8f0; --sidebar-text: #374151; --sidebar-text-muted: #9ca3af; /* 尺寸变量 */ --sidebar-width: 210px; --sidebar-collapsed: 64px; --submenu-width: 180px; --submenu-fixed-width: 180px; --topbar-height: 50px; --tabs-height: 41px; --nav-item-height: 52px; --nav-sub-item-height: 46px; /* 间距系统 (Spacing Scale) */ --space-xs: 4px; /* 微间距 - 图标与文字间距 */ --space-sm: 8px; /* 小间距 - 紧凑元素间距 */ --space-md: 12px; /* 中间距 - 默认紧凑模式基准 */ --space-base: 16px; /* 基准间距 - 内容区间距、卡片间距 */ --space-lg: 20px; /* 大间距 - 卡片内边距、表单项间距 */ --space-xl: 24px; /* 超大间距 - 区块间距 */ --space-2xl: 32px; /* 2倍大间距 - 页面级间距 */ } /* 紧凑模式 */ [data-density="compact"] { --space-xs: 2px; --space-sm: 6px; --space-md: 8px; --space-base: 10px; --space-lg: 14px; --space-xl: 18px; --space-2xl: 24px; --nav-item-height: 44px; --nav-sub-item-height: 38px; } ``` ### 自定义主题 1. **修改 CSS 变量** ```css /* admin/css/theme.css */ :root { --accent: #1e9fff; --accent-hover: #1a8fe6; } ``` 1. **添加主题色** ```json // config/app.json { "colors": { "#1e9fff": { "hover": "#1a8fe6", "rgb": "30, 159, 255" } } } ``` ### 角色主题权限配置 基于角色的主题权限控制系统,不同角色拥有不同的主题配置权限,实现精细化的主题管理。 #### 1. 接口返回格式 后端接口需返回以下 JSON 格式: ```json { "_currentRole": "admin", "roles": { "admin": { "label": "超级管理员", "showPanel": true, "canChangeMode": true, "canChangeScheme": true, "canChangeColor": true, "canChangeLayout": true, "canChangeDensity": true, "canChangeSidebarWidth": true, "allowedSchemes": ["*"], "allowedColors": ["*"], "allowedLayouts": ["*"] }, "employee": { "label": "员工", "showPanel": true, "canChangeMode": true, "canChangeScheme": true, "canChangeColor": false, "canChangeLayout": true, "canChangeDensity": true, "canChangeSidebarWidth": true, "allowedSchemes": ["*"], "allowedColors": [], "allowedLayouts": ["*"] }, "vip": { "label": "会员", "showPanel": false, "canChangeMode": true, "canChangeScheme": false, "canChangeColor": false, "canChangeLayout": false, "canChangeDensity": false, "canChangeSidebarWidth": false, "allowedSchemes": ["indigo", "ocean", "emerald"], "allowedColors": [], "allowedLayouts": ["dropdown"], "defaultConfig": { "scheme": "indigo", "mode": "light" } } } } ``` > **重要**: 必须同时返回 `_currentRole` 和 `roles` 两个字段,否则系统会降级为**全权限默认配置**。 #### 2. 配置说明 | 字段 | 类型 | 说明 | |------|------|------| | `_currentRole` | string | 当前用户角色标识 | | `roles` | object | 角色权限配置对象 | | `roles[role].label` | string | 角色显示名称 | | `roles[role].showPanel` | boolean | 是否显示完整配置面板 | | `roles[role].canChangeMode` | boolean | 是否允许切换明暗模式 | | `roles[role].canChangeScheme` | boolean | 是否允许切换配色方案 | | `roles[role].canChangeColor` | boolean | 是否允许使用自定义颜色 | | `roles[role].canChangeLayout` | boolean | 是否允许切换布局模式 | | `roles[role].canChangeDensity` | boolean | 是否允许切换紧凑模式 | | `roles[role].canChangeSidebarWidth` | boolean | 是否允许调整侧边栏宽度 | | `roles[role].allowedSchemes` | array | 允许的配色方案白名单,`["*"]` 表示全部 | | `roles[role].allowedColors` | array | 允许的自定义颜色白名单 | | `roles[role].allowedLayouts` | array | 允许的布局模式白名单 | | `roles[role].defaultConfig` | object | 强制使用的默认配置 | #### 3. 本地开发配置 本地开发时,可使用 `config/rolesTheme.json` 文件,系统会自动加载。 #### 4. localStorage 隔离 不同角色使用独立的存储键,避免配置冲突: - `osadmin_admin_themeConfig` - `osadmin_employee_themeConfig` - `osadmin_vip_themeConfig` #### 5. 运行时切换角色 ```javascript var theme = OSLAY.modules.theme; // 切换到员工角色 theme.setRole('employee'); // 获取当前角色 var role = theme.getRole(); // 获取当前角色配置 var profile = theme.getProfile(); ``` ### 间距系统与紧凑模式 #### 1. 框架级组件规范 **职责边界**: 框架只管容器级间距,不侵入组件内部。 | 选择器 | 间距规则 | 用途 | |--------|---------|------| | `.page-content > .layui-card + .layui-card` | `margin-top: var(--space-base)` | 卡片间间距 | | `.layui-card-body`, `.layui-panel-body` | `padding: var(--space-lg)` | 卡片内边距 | | `.layui-card-header` | `padding: var(--space-base) var(--space-lg)` | 卡片头部 | | `.layui-table td, .layui-table th` | `padding: var(--space-sm) var(--space-base)` | 表格单元格 | | `.layui-nav-bar .layui-nav-item a` | `height: var(--nav-item-height)` | 导航项高度 | #### 2. 紧凑模式切换 ```javascript var theme = OSLAY.modules.theme; // 切换到紧凑模式 theme.setState({ density: 'compact' }); // 切换到舒适模式 theme.setState({ density: 'comfortable' }); // 切换(布尔值) theme.previewDensity('compact'); ``` #### 3. 侧边栏宽度调整 ```javascript // 调整侧边栏宽度(160-320px) theme.setState({ sidebarWidth: 240 }); // 调整子菜单宽度(140-240px) theme.setState({ submenuWidth: 200 }); // 实时预览 theme.previewSidebarWidth(240); theme.previewSubmenuWidth(200); ``` *** ## 🤖 智能组件渲染 ### 功能概述 在 SPA (单页应用) 模式下,动态加载的 HTML 内容中的 LayUI 组件不会自动渲染。`componentRenderer` 模块通过智能扫描 DOM,自动检测并渲染所需的 LayUI 组件,实现按需加载和性能优化。 ### 核心特性 - ✅ **自动扫描**: 自动检测页面中的 LayUI 组件 - ✅ **按需加载**: 只加载检测到的组件所需的模块 - ✅ **智能缓存**: 避免重复渲染同一组件 - ✅ **优先级控制**: 支持组件渲染优先级配置 - ✅ **调试模式**: 提供详细的渲染日志 ### 支持的组件 | 组件名 | 选择器 | LayUI 模块 | 优先级 | |--------|--------|-----------|--------| | tabs | `.layui-tabs` | tabs | 1 | | form | `.layui-form`, 表单元素 | form | 2 | | element | `.layui-nav`, `.layui-collapse` 等 | element | 3 | | carousel | `.layui-carousel` | carousel | 4 | | rate | `.layui-rate` | rate | 5 | | slider | `.layui-slider` | slider | 6 | | transfer | `.layui-transfer` | transfer | 7 | | tree | `.layui-tree` | tree | 8 | | colorpicker | `.layui-colorpicker` | colorpicker | 9 | | laypage | `.layui-laypage` | laypage | 10 | | code | `pre.layui-code` | code | 11 | ### 使用方法 #### 1. 基本使用 ```javascript // 在页面加载完成后自动渲染所有组件 OSLAY.ready(function(modules) { var renderer = layui.componentRenderer; // 渲染整个页面 renderer.render(); }); ``` #### 2. 渲染指定容器 ```javascript // 只渲染特定容器内的组件 renderer.render('#myContainer'); ``` #### 3. 渲染指定组件 ```javascript // 只渲染指定的组件类型 renderer.render('#container', 'tabs,form,element'); ``` #### 4. 开启调试模式 ```javascript // 初始化时开启调试 renderer.init({ debug: true }); // 渲染时会输出详细日志 renderer.render(); // 输出示例: // [ComponentRenderer] Detected: tabs Count: 2 // [ComponentRenderer] Modules to load: ["tabs", "form"] // [ComponentRenderer] Rendered: tabs ``` #### 5. 清除缓存 ```javascript // 清除渲染缓存,允许重新渲染 renderer.clearCache('#container'); ``` ### API 文档 #### 初始化 ```javascript renderer.init(options); ``` | 参数 | 类型 | 默认值 | 说明 | |------|------|--------|------| | debug | Boolean | false | 是否开启调试模式 | #### 渲染方法 ```javascript renderer.render(container, componentNames); ``` | 参数 | 类型 | 必填 | 说明 | |------|------|------|------| | container | String/Element | 否 | 容器选择器或元素,默认为整个文档 | | componentNames | String | 否 | 组件名称列表,用逗号分隔 | #### 其他方法 ```javascript // 扫描组件 var components = renderer.scanComponents($('#container')); // 获取所需模块 var modules = renderer.getRequiredModules(components); // 清除缓存 renderer.clearCache('#container'); // 渲染所有组件 renderer.renderAll('#container'); ``` ### 工作原理 1. **DOM 扫描**: 遍历容器,查找匹配的组件选择器 2. **模块收集**: 收集所有检测到的组件所需的 LayUI 模块 3. **按需加载**: 使用 `layui.use()` 动态加载所需模块 4. **组件渲染**: 调用各组件的 `render()` 方法进行渲染 5. **状态标记**: 为已渲染的组件添加标记,避免重复渲染 ### 性能优化 - **减少模块加载**: 只加载页面实际使用的组件模块,减少 80% 的不必要加载 - **Canvas 缓存**: 水印等组件使用 Canvas 缓存机制 - **智能检测**: 通过选择器快速定位,避免全局遍历 - **渲染标记**: 使用 `data-layui-rendered` 标记避免重复渲染 ### 最佳实践 #### 1. 在 SPA 中使用 ```javascript // 在 app.js 的 showContent 方法中 showContent: function(content) { $wrapper.html(content); // 自动渲染新内容中的组件 if (window.layui && layui.componentRenderer) { layui.componentRenderer.render($wrapper); } } ``` #### 2. 动态内容渲染 ```javascript // 加载动态内容后渲染 $('#container').load('page.html', function() { layui.componentRenderer.render('#container'); }); ``` #### 3. 表单动态添加 ```javascript // 添加新表单元素后渲染 $('#formContainer').append(newFormHtml); layui.componentRenderer.render('#formContainer', 'form'); ``` ### 注意事项 1. **避免重复渲染**: 组件渲染后会添加标记,重复调用 `render()` 不会重复渲染 2. **容器选择**: 建议指定具体的容器,避免全局扫描影响性能 3. **模块依赖**: 确保所需的 LayUI 模块已正确配置 4. **调试模式**: 生产环境建议关闭调试模式 *** ## 🔐 权限系统 ### 权限配置 权限配置详见 [权限模块使用指南](permission-guide.md)。 ### 快速使用 #### 1. 配置权限接口 ```json { "permission": { "enabled": true, "url": "/api/admin/permission" } } ``` #### 2. HTML 权限控制 ```html ``` #### 3. JavaScript 权限检查 ```javascript OSLAY.ready(function(modules) { var permission = modules.permission; if (permission.hasPermission('user-delete')) { // 显示删除按钮 } }); ``` ### 权限示例数据 项目提供了多种角色的权限示例数据: - `view/data/permission.json` - 标准权限 - `view/data/permission-super.json` - 超级管理员 - `view/data/permission-operator.json` - 运营人员 - `view/data/permission-manager.json` - 业务经理 *** ## 🧩 组件开发 ### 开发规范 #### 1. 模块定义 ```javascript /** * 组件名称 * 组件描述 */ layui.define(['jquery', '依赖模块'], function(exports) { 'use strict'; var $ = layui.jquery; var Component = { // 默认配置 config: { property: 'value' }, // 初始化 init: function(options) { var self = this; var config = $.extend({}, this.config, options); // 初始化逻辑 return this; }, // 公共方法 method: function() { // 方法逻辑 }, // 私有方法 _privateMethod: function() { // 私有逻辑 } }; exports('componentName', Component); }); ``` #### 2. 注册模块 ```javascript // admin/js/index.js layui.config({ base: baseUrl }).extend({ componentName: 'modules/path/to/component' }); ``` #### 3. 使用组件 ```javascript // 方式1: 通过 OSLAY OSLAY.ready(function(modules) { var component = modules.componentName; component.init({ /* 配置 */ }); }); // 方式2: 通过 LayUI layui.use(['componentName'], function() { var component = layui.componentName; component.init({ /* 配置 */ }); }); ``` ### 组件示例 #### Toast 提示框组件 ```javascript // 使用 Toast var toast = OSLAY.modules.toast; // 基础用法 toast.success('操作成功'); toast.error('操作失败'); toast.warning('警告信息'); toast.info('提示信息'); // 堆叠模式(默认,最多显示5条) toast.success('消息1', { mode: 'stack', maxCount: 5 }); // 替换模式(只显示最新一条) toast.info('消息', { mode: 'replace' }); // 消散动画关闭 var id = toast.loading('加载中...'); toast.dismiss(id); // 带消散动画 // 关闭所有 toast.dismissAll(); // 带消散动画 toast.clear(); // 立即关闭 ``` #### Drawer 抽屉组件 ```javascript // 使用 Drawer var drawer = OSLAY.modules.drawer; drawer.open({ title: '抽屉标题', content: '抽屉内容', width: 400, onConfirm: function() { // 确认回调 }, onCancel: function() { // 取消回调 } }); ``` #### ECharts 图表组件 ```javascript // 使用 ECharts var echarts = OSLAY.modules.echarts; echarts.render('chart-container', { title: { text: '图表标题' }, xAxis: { data: ['A', 'B', 'C'] }, yAxis: {}, series: [{ type: 'bar', data: [10, 20, 30] }] }); ``` *** ## 📦 扩展开发 ### 添加新页面 #### 1. 创建页面文件 ```html 我的页面
``` #### 2. 添加菜单项 ```json // config/menu.json { "id": 100, "code": "view/mypage", "title": "我的页面", "icon": "layui-icon-component", "href": "view/mypage.html" } ``` ### 添加新模块 #### 1. 创建模块文件 ```javascript // modules/myModule.js layui.define(['jquery'], function(exports) { 'use strict'; var $ = layui.jquery; var MyModule = { init: function() { console.log('MyModule initialized'); return this; } }; exports('myModule', MyModule); }); ``` #### 2. 注册模块 ```javascript // admin/js/index.js layui.config({ base: baseUrl }).extend({ myModule: 'modules/myModule' }); ``` #### 3. 加载模块 ```javascript // admin/js/index.js layui.use(['appMain', 'myModule'], function() { var myModule = layui.myModule; myModule.init(); }); ``` ### 添加新组件 #### 1. 创建组件文件 ```javascript // modules/components/myComponent.js layui.define(['jquery'], function(exports) { 'use strict'; var $ = layui.jquery; var MyComponent = { render: function(container, options) { var html = '
组件内容
'; $(container).html(html); return this; } }; exports('myComponent', MyComponent); }); ``` #### 2. 创建样式文件 ```css /* admin/css/components/myComponent.css */ .my-component { padding: 20px; background: #fff; border-radius: 4px; } ``` #### 3. 注册和使用 ```javascript // 注册 layui.extend({ myComponent: 'modules/components/myComponent' }); // 使用 OSLAY.ready(function(modules) { var myComponent = layui.myComponent; myComponent.render('#container', { /* 配置 */ }); }); ``` *** ## 🎯 最佳实践 ### 代码规范 #### 1. 命名规范 ```javascript // 模块名: 小驼峰 var myModule = {}; // 组件名: 小驼峰 var myComponent = {}; // 方法名: 小驼峰 function getData() {} // 私有方法: 下划线前缀 function _privateMethod() {} // 常量: 大写下划线 var MAX_COUNT = 100; ``` #### 2. 注释规范 ```javascript /** * 方法描述 * @param {String} param1 - 参数1说明 * @param {Object} param2 - 参数2说明 * @returns {Boolean} 返回值说明 */ function methodName(param1, param2) { // 单行注释 /* * 多行注释 * 第二行 */ } ``` #### 3. 错误处理 ```javascript // 推荐的错误处理方式 function loadData() { return new Promise(function(resolve, reject) { $.ajax({ url: '/api/data', success: function(res) { if (res.code === 0) { resolve(res.data); } else { reject(new Error(res.msg)); } }, error: function(err) { reject(err); } }); }); } // 使用 loadData() .then(function(data) { console.log('数据加载成功:', data); }) .catch(function(err) { console.error('数据加载失败:', err); layer.msg('数据加载失败'); }); ``` ### 性能优化 #### 1. 按需加载 ```javascript // 推荐: 按需加载模块 layui.use(['需要的模块'], function() { // 只加载需要的模块 }); // 不推荐: 加载所有模块 layui.use(['所有模块'], function() { // 加载不必要的模块 }); ``` #### 2. 事件委托 ```javascript // 推荐: 使用事件委托 $(document).on('click', '.btn', function() { // 事件处理 }); // 不推荐: 为每个元素绑定事件 $('.btn').each(function() { $(this).on('click', function() { // 事件处理 }); }); ``` #### 3. 缓存 DOM ```javascript // 推荐: 缓存 DOM 元素 var $container = $('#container'); $container.find('.item').each(function() { // 处理逻辑 }); // 不推荐: 重复查询 DOM $('#container').find('.item').each(function() { // 处理逻辑 }); $('#container').find('.other').each(function() { // 处理逻辑 }); ``` ### 安全建议 #### 1. XSS 防护 ```javascript // 推荐: 使用 text() 而不是 html() $('#content').text(userInput); // 不推荐: 直接使用 html() $('#content').html(userInput); ``` #### 2. 权限验证 ```javascript // 前端权限检查 if (permission.hasPermission('user-delete')) { // 显示删除按钮 } // 后端权限验证 (必须) // 所有敏感操作必须在服务端验证权限 ``` #### 3. 数据验证 ```javascript // 前端数据验证 function validateForm(data) { if (!data.name) { layer.msg('请输入名称'); return false; } if (!data.email) { layer.msg('请输入邮箱'); return false; } return true; } // 后端数据验证 (必须) // 所有数据必须在服务端验证 ``` *** ## 🐛 调试技巧 ### 开启调试模式 ```javascript // 在浏览器控制台执行 OSLAY.debug = true; // 查看模块列表 console.log(OSLAY.modules); // 查看配置 console.log(OSLAY.appConfig); console.log(OSLAY.menuConfig); ``` ### 常用调试命令 ```javascript // 查看权限状态 var permission = OSLAY.modules.permission; console.log('权限列表:', permission.getPermissions()); console.log('是否超管:', permission.isSuper()); // 查看当前路由 var router = OSLAY.modules.router; console.log('当前路由:', router.getCurrent()); // 查看主题配置 var theme = OSLAY.modules.theme; console.log('当前主题:', theme.getMode()); console.log('当前颜色:', theme.getColor()); ``` ### 控制台日志 ```javascript // 在模块中添加日志 var Module = { init: function() { if (OSLAY.debug) { console.log('[Module] 初始化'); } } }; ``` *** ## 📚 API 文档 ### OSLAY 全局对象 #### 属性 | 属性 | 类型 | 说明 | | ---------- | ------- | ---- | | version | String | 版本号 | | name | String | 应用名称 | | debug | Boolean | 调试模式 | | baseUrl | String | 基础路径 | | modules | Object | 模块集合 | | appConfig | Object | 应用配置 | | menuConfig | Object | 菜单配置 | #### 方法 | 方法 | 参数 | 返回值 | 说明 | | ---------------------- | --------------- | ------ | ------ | | ready(callback) | Function | void | 系统就绪回调 | | use(modules, callback) | Array, Function | void | 加载模块 | | getModule(name) | String | Object | 获取模块 | | getConfig() | - | Object | 获取配置 | | getMenuConfig() | - | Object | 获取菜单配置 | | log(...args) | ...Any | void | 调试日志 | ### 权限模块 API 详见 [权限模块使用指南](permission-guide.md)。 ### 路由模块 API | 方法 | 参数 | 返回值 | 说明 | | ------------------- | ---------------- | ------ | ------- | | go(path) | String | void | 跳转到指定路由 | | getCurrent() | - | String | 获取当前路由 | | getQueryParams() | - | Object | 获取查询参数对象 | | getQueryParam(name) | String | String | 获取单个查询参数 | | getQueryString() | - | String | 获取原始查询字符串 | | on(event, callback) | String, Function | void | 监听路由事件 | ### 主题模块 API | 方法 | 参数 | 返回值 | 说明 | | --------------- | ------ | ------ | ------ | | setMode(mode) | String | void | 设置主题模式 | | getMode() | - | String | 获取主题模式 | | setColor(color) | String | void | 设置主题色 | | getColor() | - | String | 获取主题色 | *** ## 🔄 更新日志 完整的更新日志请查看 [CHANGELOG.md](CHANGELOG.md)。 *** ## 🤝 贡献指南 ### 开发流程 1. Fork 项目 2. 创建特性分支 (`git checkout -b feature/AmazingFeature`) 3. 提交更改 (`git commit -m 'Add some AmazingFeature'`) 4. 推送到分支 (`git push origin feature/AmazingFeature`) 5. 提交 Pull Request ### 代码规范 - 遵循 JavaScript 编码规范 - 添加必要的注释 - 编写单元测试 - 更新相关文档 ### 提交规范 ``` feat: 新功能 fix: 修复 bug docs: 文档更新 style: 代码格式调整 refactor: 代码重构 test: 测试相关 chore: 构建/工具相关 ``` *** ## 📄 许可证 本项目采用 Apache License 2.0 开源协议。详见 [LICENSE](LICENSE) 文件。 *** ## 📞 联系方式 - 项目主页: \[GitHub Repository URL] - 问题反馈: \[GitHub Issues URL] - 文档地址: \[Documentation URL] *** ## 🙏 致谢 感谢以下开源项目: - [LayUI](https://layui.com/) - 经典模块化前端框架 - [jQuery](https://jquery.com/) - JavaScript 库 - [ECharts](https://echarts.apache.org/) - 数据可视化图表库 - [XM-Select](https://gitee.com/maplemei/xm-select) - 多选解决方案 *** **最后更新时间**: 2026-05-26\ **文档版本**: 1.9.4