Repository: shengzhang666/sa-admin Branch: master Commit: 218e4f0b61c2 Files: 77 Total size: 1.1 MB Directory structure: gitextract_n2f8j4kf/ ├── LICENSE ├── README.md ├── index.html ├── login.html ├── main.html ├── sa-frame/ │ ├── com/ │ │ ├── sa-info.vue │ │ ├── sa-item.vue │ │ └── sa-td.vue │ ├── index/ │ │ ├── admin-util.js │ │ ├── index.css │ │ ├── index.js │ │ └── theme.css │ ├── login/ │ │ ├── app.js │ │ ├── reset.css │ │ └── style.css │ ├── menu-list.js │ ├── nav/ │ │ ├── com-add-tab.vue │ │ ├── com-right-menu.vue │ │ ├── nav-logo.vue │ │ ├── nav-menu-bar.vue │ │ ├── nav-tab-bar.vue │ │ ├── nav-tool-bar.vue │ │ └── nav-view-vessel.vue │ └── sa-code.js ├── sa-view/ │ ├── article/ │ │ ├── art-add.html │ │ ├── art-list.html │ │ └── data-list.js │ ├── case/ │ │ ├── mock-data-list.js │ │ ├── mock-joptions.js │ │ ├── query-p-case.html │ │ ├── query-table-case-add.html │ │ ├── query-table-case.html │ │ └── submit-form.html │ ├── cfg/ │ │ ├── system-cfg.html │ │ └── xxx.vue │ ├── console/ │ │ ├── com-chart-1.vue │ │ ├── com-chart-2.vue │ │ ├── com-chart-3.vue │ │ ├── com-intro.vue │ │ ├── com-origin.vue │ │ ├── com-sta-data.vue │ │ ├── com-stack.vue │ │ ├── com-update-log.vue │ │ └── console-main.html │ ├── error-page/ │ │ ├── 403.html │ │ ├── 404.html │ │ └── 500.html │ ├── home/ │ │ ├── mock-data-list.js │ │ ├── swiper-add.html │ │ └── swiper-list.html │ ├── role/ │ │ ├── menu-list.html │ │ ├── menu-setup.html │ │ ├── mock-data.js │ │ ├── role-add.html │ │ └── role-list.html │ ├── sa-doc/ │ │ ├── check-per.md │ │ ├── sa-doc.html │ │ └── start-up.md │ ├── ser-goods/ │ │ └── ser-goods-add.html │ ├── sys-type/ │ │ ├── moke-data.js │ │ ├── sys-type-add.html │ │ ├── sys-type-info.html │ │ └── sys-type-list.html │ └── user/ │ ├── data-list.js │ ├── user-add.html │ ├── user-chart.html │ └── user-list.html └── static/ ├── kj/ │ ├── element-ui/ │ │ ├── index.js │ │ └── theme-chalk/ │ │ └── index.css │ ├── httpVueLoader.js │ ├── layer/ │ │ ├── layer.js │ │ ├── mobile/ │ │ │ ├── layer.js │ │ │ └── need/ │ │ │ └── layer.css │ │ └── theme/ │ │ └── default/ │ │ └── layer.css │ └── upload-util.js ├── sa.css └── sa.js ================================================ FILE CONTENTS ================================================ ================================================ FILE: LICENSE ================================================ MIT License Copyright (c) 2020 省长 Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: README.md ================================================

logo

Sa-Admin v1.41.0

一个多窗口后台模板,流畅、易上手、提高生产力

## ⚡ 介绍 Sa-Admin 是一个多窗口后台模板,纯 html 无后端代码,无需脚手架即可直接运行,流畅、易上手、提高生产力。核心技术栈:Vue + Element-UI + jquery + layer。 废话不多说,具体效果可参见在线预览:[http://sa-admin.dev33.cn/](http://sa-admin.dev33.cn/) ## ⭐ 特点 Sa-Admin 最大的特点是无需搭建 vue-cli 脚手架,随便一个 html 预览工具(比如 [HBuilderX](https://www.dcloud.io/hbuilderx.html))即可直接运行(采用 http-vue-loader 技术实现)。 目前最新版包括以下功能: - 视图:支持 iframe 和 .vue 两种视图方式,支持一、二、三、四级菜单。 - 操作:工具栏提供常见操作按钮:折叠、搜索、刷新、账号、便签、主题切换、全屏切换。 - 主题:内置十种主题,也可方便的扩展主题。 - 切换:支持拖拽排序、切换视图自动记录hash,刷新页面自动打开上次的视图。 - 右键:tabbar栏支持右键菜单:悬浮打开、新窗口打开、视图复制、快捷关闭等操作。 - 接口:开放一系列api,可方便的用js新建、打开、切换视图等动作。 - 示例:提供大量常见示例,以及各种表单组件的封装,助你快速CRUD。 ## 🖥 截图
## 🔍 开始使用 ### 1、下载项目 直接在 Gitee 或 GitHub 下载代码 ### 2、初始化模板 在使用时不建议你直接魔改模板的代码,以免在运行时出现意外bug。在文件夹 `\sa-frame` 下有个 `sa-code.js` 文件, 这是为了方便你对接后端专门预留的文件,你可以在此文件中调用 Sa-Admin 提供的 API 来操作模板。 ``` js // 设置基本信息 sa_admin.title="xxx"; // 设置模板标题 sa_admin.logo='xxx.png'; // 设置 logo 图标地址 sa_admin.icon = 'xxx.ico'; // 设置 icon 图标地址 // 初始化菜单 var myMenuList = window.menuList; // window.menuList 在 menu-list.js 中定义(内有格式详细说明) sa_admin.setMenuList(myMenuList); // 方式一:写入菜单,这些菜单会全部显示 sa_admin.setMenuList(myMenuList, ['1', '1-1', '1-2']); // 方式二:写入菜单,并在第二个参数决定哪些菜单会显示出来 sa_admin.initMenu(['1', '1-1', '1-2']); // 方式三:相当于方式二省略了第一个参数(框架会自动寻找 window.menuList) /* * MenuList 菜单的格式在 menu-list.js 文件中有详细的示例和格式说明 * 一般情况下我们的菜单最终都是一个 Tree 形格式,但我们从数据库查询出来时都是平面一维数组, * 这时候你不需要手动做格式转换,调用 sa_admin.setMenuList 模板会自动为你进行格式转换, * (前提是你的数组里每个 menu 对象指定了 parentId 属性) */ // 设置右上角的 user 信息 sa_admin.user = { username: 'root', // 昵称 avatar: 'sa-frame/admin-logo.png' // 头像地址 } // 设置头像点击处可操作的选项 sa_admin.dropList = [ { name: '我的资料', click: function() { /* balabala... */ } }, { name: '退出登录', click: function() { /* balabala... */ } } ] // 初始化模板(必须调用) sa_admin.init(); ``` ### 3、js操作模板 你可以使用以下 API 来操作模板 ``` js sa_admin.showHome(); // 显示主页选项卡 sa_admin.showTabById('1-1'); // 显示一个选项卡, 根据id sa_admin.closeTabById('1-1'); // 关闭一个选项卡,根据 id ( 第二个参数可填关闭后的回调函数 ) sa_admin.showMenuById('1-1'); // 打开一个 菜单,根据 id // 新增一个选项卡 sa_admin.addTab({name: '新页面', url: 'http://sa-token.dev33.cn/'}); // id不要和已有的菜单id冲突,其它属性均可参照菜单项 // 新增一个选项卡、并立即显示 sa_admin.showTab({name: '新页面', url: 'http://sa-plus.dev33.cn/'}); // 参数同上 ``` ### 4、多视图通信 怎么在一个选项卡页面调用另一个页面的代码 ``` js // 根据id获取其页面的window对象 (如果此页面未打开,则返回空)(跨域模式下无法获取其window对象) var win = sa_admin.getTabWindow('2-1'); if(win) { win.app.f5(); // 然后调用这个对象上的方法 } // 根据iframe的子父通信原则,在子页面中调用父页面的方法,需要加上parent前缀,例如: parent.sa_admin.msg('啦啦啦'); // 调用父页面的弹窗方法 ``` ### 5、鉴权相关 ``` js // 首先在登录时,写入当前会话所具有的权限码集合 var arr = ['1', '2', '3', 'a', 'b', 'c']; // 一般由后端提供接口返回当前会话所具有的权限码集合 sa.setAuth(arr); // 写入本地缓存中 // 然后:我们就可以愉快的使用鉴权了 // 如果一个页面需要某个权限码才能打开,在这个页面的 ================================================ FILE: login.html ================================================ 登录
================================================ FILE: main.html ================================================

欢迎使用 SA-后台管理

================================================ FILE: sa-frame/com/sa-info.vue ================================================ ================================================ FILE: sa-frame/com/sa-item.vue ================================================ ================================================ FILE: sa-frame/com/sa-td.vue ================================================ ================================================ FILE: sa-frame/index/admin-util.js ================================================ // ======================== 一些工具方法 ======================== var sa_admin_code_util = { // 删除数组某个元素 arrayDelete: function(arr, item){ var index = arr.indexOf(item); if (index > -1) { arr.splice(index, 1); } }, //执行一个函数, 解决layer拉伸或者最大化的时候,iframe高度不能自适应的问题 solveLayerBug: function(index) { var selected = '#layui-layer' + index; var height = $(selected).height(); var title_height = $(selected).find('.layui-layer-title').height(); $(selected).find('iframe').css('height', (height - title_height) + 'px'); // var selected = '#layui-layer' + index; // var height = $(selected).height(); // var title_height = $(selected).find('.layui-layer-title').height(); // $(selected).find('iframe').css('height', (height - title_height) + 'px'); }, // ======================== 菜单集合相关 ======================== // 将一维平面数组转换为 Tree 菜单 (根据其指定的parentId添加到其父菜单的childList) arrayToTree: function(menu_list) { for (var i = 0; i < menu_list.length; i++) { var menu = menu_list[i]; // 添加到其指定的父菜单的childList if(menu.parentId) { var parent_menu = this.findMenuById(menu_list, menu.parentId); if(parent_menu) { parent_menu.childList = parent_menu.childList || []; parent_menu.childList.push(menu); menu_list.splice(i, 1); // 从一维中删除 i--; } } } return menu_list; }, // 将 menu_list 处理一下 refMenuList: function(menu_list) { for (var i = 0; i < menu_list.length; i++) { var menu = menu_list[i]; // 有子项的递归处理 if(menu.childList){ menu.children = menu.childList; this.refMenuList(menu.childList); } } return menu_list; }, // 返回指定 index 的menu getMenuById: function(menuList, id) { for (var i = 0; i < menuList.length; i++) { var menu = menuList[i]; if(menu.id + '' == id + '') { return menu; } // 如果是二级或多级 if(menu.childList) { var menu2 = this.getMenuById(menu.childList, id); if(menu2 != null) { return menu2; } } } return null; }, // 将 Tree 菜单 转换为 一维平面数组 treeToArray: function(menu_list) { var arr = []; function _dg(menu_list) { menu_list = menu_list || []; for (var i = 0; i < menu_list.length; i++) { var menu = menu_list[i]; arr.push(menu); // 如果有子菜单 if(menu.childList) { _dg(menu.childList); } } } _dg(menu_list); return arr; }, } ================================================ FILE: sa-frame/index/index.css ================================================ *{margin: 0; padding: 0; } html,body{height: 100%; background-color: #EEE;} body{height: 100vh;background-color: #EEE;background-image: url(admin-loading.gif); background-repeat: no-repeat;background-position: 50% 50%;} .app{height: 100%; font-size: 16px; font-family: "Helvetica Neue",Helvetica,"PingFang SC","Hiragino Sans GB","Microsoft YaHei","微软雅黑",Arial,sans-serif;} .app{background-color: #EEE;} /* 变量 */ body{ --nav-left-width: 200px; --nav-left-width-fold: 64px; --nav-right-1-height: 50px; --nav-right-2-height: 35px; } .nav-left, .nav-right {position: fixed; top: 0; height: 100%;} /* 左边 */ .nav-left{width: var(--nav-left-width); left: 0px; z-index: 200; overflow: hidden;} .nav-left-top{width: 100%; box-sizing: border-box; height: 85px; line-height: 85px;/* z-index: 100; */ overflow: hidden;} .nav-left-bottom{width: 100%; box-sizing: border-box; height: calc(100% - 85px); overflow: hidden;} /* 右边 */ .nav-right{width: calc(100% - var(--nav-left-width)); right: 0px; z-index: 100; } .nav-right-1{height: var(--nav-right-1-height); line-height: var(--nav-right-1-height); z-index: 200; position: relative; border-bottom: 1px #F1F1F1 solid; box-sizing: border-box; overflow: hidden;} .nav-right-2{height: var(--nav-right-2-height); line-height: var(--nav-right-2-height); z-index: 200; position: relative; box-shadow: 0 2px 2px rgba(0,0,0,0.1);} .nav-right-3{width: 100%; height: calc(100vh - var(--nav-right-1-height) - var(--nav-right-2-height)); position: relative; overflow: hidden;} /* .fas{transition: all 0s;} */ /* 所有带动画的元素 */ .admin-logo,.nav-left,.nav-left-top,.nav-left-bottom, .nav-right/* , .nav-right-2 * */{transition: all 0.2s; } /* 菜单折叠 */ .app-fold{ --nav-left-width: 64px; } /* 菜单折叠时 部分元素隐藏 */ .app-fold .admin-title, .app-fold .menu-name, .app-fold-right .el-submenu__icon-arrow{display: none;} .app-fold .admin-logo{margin-left: 12px !important;} /* .nav-right-3 包裹了太多 View,不能让它参与动画,因为实在太TM卡了 */ .nav-right-3{width: calc(100% - var(--nav-left-width)); position: fixed; transition: none;} .app-fold-right .nav-right-3{width: calc(100% - 64px); left: 64px;} /* -------------- 其它 --------------- */ /* 折叠时悬浮菜单样式,防止透明 */ .el-menu--vertical .el-menu--popup{background-color: #FFF !important; color: red !important;} /* 最高层级 */ .z-index-max{z-index: 2147483647;} /* 遮罩样式 */ .shade-fox{position: absolute; z-index: 1000000; width: 100%; height: 100%; background-color: rgba(0,0,0,0.5); color: #FFF; top: 0px;} .shade-fox{display: flex; justify-content: center; align-items: center} .shade-text{} /* 去除掉便签的大边框 */ .layer-note-class .layui-layer-input{outline: 0; box-shadow: none !important; padding: 0.8em !important; font-family: 'Times New Roman', Times, serif;} .layer-note-class .layui-layer-input{border: 0px #ddd solid; border-bottom: 1px #ddd solid;} ================================================ FILE: sa-frame/index/index.js ================================================ // 首页 var homeTab = { id: 'home', // 唯一标识 name: '首页', url: 'main.html', // 页面地址 isNeedLoad: false, // 标注:是否需要此刻加载 hideClose: true // 隐藏关闭键 } // sa_admin对象 var sa_admin = new Vue({ components: { "nav-logo": httpVueLoader('sa-frame/nav/nav-logo.vue'), // logo "nav-menu-bar": httpVueLoader('sa-frame/nav/nav-menu-bar.vue'), // 菜单栏 "nav-tool-bar": httpVueLoader('sa-frame/nav/nav-tool-bar.vue'), // 工具栏 "nav-tab-bar": httpVueLoader('sa-frame/nav/nav-tab-bar.vue'), // tab栏 "nav-view-vessel": httpVueLoader('sa-frame/nav/nav-view-vessel.vue'), // 视图容器 "com-right-menu": httpVueLoader('sa-frame/nav/com-right-menu.vue'), // 右键菜单 "com-add-tab": httpVueLoader('sa-frame/nav/com-add-tab.vue'), // 双击添加 tab 的弹窗 }, el: '.app', data: { // ------------------------------- 配置 ------------------------------- title: '', // 页面标题 -- Sa-Admin logo: '', // logo地址 -- sa-frame/admin-logo.png icon: '', // icon地址 -- sa-frame/admin-logo.png version: 'v1.41.0', // 当前版本号 updateTime: '2021-10-24', // 更新日期 githubUrl: 'https://github.com/click33/sa-admin', // github地址 isRemeOpen: true, // 是否记住上一次最后打开的窗口 printInfo: true, // 是否在控制台打印信息 homeTab: homeTab, // 主页首屏 Tab menuList: [], // 全部菜单集合 showList: [], // 显示的菜单集合(id集合) // ------------------------------- 状态 ------------------------------- themeV: localStorage.getItem('themeV') || '1', // 当前 / 默认的主题 isOpen: true, // 当前是否展开菜单 (整体框架) isOpenRight: true, // 当前是否展开 (右边) (将右边盒子折叠与菜单折叠分开,这样可以减少动画的卡顿现象) activeMenuId: '0', // 正在高亮的菜单id isDrag: false, // 当前是否正在拖拽 tab dragTab: null, // 当前正在拖拽的 tab tabList: [homeTab], // 当前 Tab 集合 viewList: [homeTab], // 当前 View 集合 nativeTab: homeTab, // 当前正显示的Tab user: null ,// user信息 dropList: [], // 头像处下拉列表菜单 }, watch: { // 监听title改变时, 页面title也跟着切换 title: function(newValue, oldValue) { document.querySelector('title').innerHTML = newValue; }, // 监听 icon_url 网页图标 icon: function(newValue, oldValue) { var icon = newValue; var iconTarget = document.querySelector('.admin-icon'); if(iconTarget) { iconTarget.setAttribute('href', icon); } } }, methods: { // ------------------- 初始化相关 -------------------- // 初始化模板, 此方法必须且只能调用一次 init: function(option) { // 打开上次最后的一个窗口 this.showTabByHash(); if(this.nativeTab.id == this.homeTab.id) { this.showHome(); } // 打印版本等信息 if(this.printInfo) { this.printVesion(); } // 手动触发一下窗口变动监听 window.onresize(); }, // 初始化菜单: // showList = 显示菜单id数组 —— (注意是id的数组),你填哪些id哪些菜单才会显示 ,为空时代表显示所有 initMenu: function(showList) { this.setMenuList(window.menuList, showList); }, // 写入菜单: // menuList = 全部菜单 —— 可以是已经渲染好的 tree 数组,也可以是一个尚未渲染的一维数组(你只要指定好 parentId,Sa-Admin内部会自动渲染) // showList = 显示菜单id数组 —— (注意是id的数组),你填哪些id哪些菜单才会显示 ,为空时代表显示所有 setMenuList: function(menuList, showList) { // 设置 全部菜单 this.menuList = this.arrayToTree(menuList); // 设置 显示的菜单id showList = showList || this.getAllId(this.menuList); for (var i = 0; i < showList.length; i++) { showList[i] = showList[i] + ''; } this.showList = showList; }, // ------------------- Menu 相关操作 -------------------- // 根据 id 查找 Menu getMenuById: function(id) { return this.findMenuById(this.menuList, id); }, // 显示某个菜单,根据id showMenuById: function(id) { var menu = this.getMenuById(id); if(menu) { this.showTab(menu); } }, // 显示homeTab showHome: function() { this.showTab(this.homeTab); }, // 返回当前所有菜单的 一维数组 形式 (将树形菜单转化为一维数组并返回) 方便遍历 getYwList: function() { var arr = []; function _dg(menuList) { menuList = menuList || []; for (var i = 0; i < menuList.length; i++) { var menu = menuList[i]; arr.push(menu); // 如果有子菜单 if(menu.childList) { _dg(menu.childList); } } } _dg(this.menuList); return arr; }, // 获取菜单所有id getAllId: function() { var arr = []; this.getYwList().forEach(function(item) { arr.push(item.id); }); return arr; }, // ------------------- Tab 相关操作 -------------------- // 刷新Tab f5Tab: function(tab) { var cs = '#iframe-' + tab.id; var iframe = document.querySelector(cs); if(iframe) { iframe.setAttribute('src', this.getTabUrl(tab)); } else { tab.isNeedLoad = false; this.$nextTick(function() { tab.isNeedLoad = true; }) } }, // 获取 Tab,根据 id getTabById: function(id) { for (var i = 0; i < this.tabList.length; i++) { if(this.tabList[i].id + '' == id + '') { return this.tabList[i]; } } return null; }, // 添加一个Tab {id,name,url} addTab: function(tab) { // 如果没有提供id,则随机一个 if(!tab.id) { tab.id = new Date().getTime() + '' + this.randomNum(); } // 如果没有指定类型 if(tab.view === undefined) { if(this.getUrlExt(tab.url).toLowerCase() == 'vue') { tab.view = httpVueLoader(tab.url); } } if(tab.isNeedLoad === undefined) { // tab.isNeedLoad = true; Vue.set(tab, 'isNeedLoad', true); } // console.log('添加之前:' + JSON.stringify(tab)); this.tabList.push(tab); this.viewList.push(tab); // tab 超过 20 个,提示过多,如果用户无视继续添加则超过 30 个后不再提示 if(this.tabList.length > 20 && this.tabList.length < 30) { sa_admin.$message({message: '选项卡过多会造成窗口卡顿,建议您关闭不使用的窗口', type: 'warning'}); } }, // 显示某个页面 (如果不存在, 则先添加) showTab: function(tab) { // 标注:需要此刻加载 // tab.isNeedLoad = false; Vue.set(tab, 'isNeedLoad', true); // 如果是外部链接 if(tab.isBlank) { return open(tab.url); } // 如果是当前正在显示的tab , 则直接返回,无需继续操作 if(tab == this.nativeTab) { return; } // 如果是click函数 if(tab.click) { if(tab.click() !== true) { return; } } // 如果这个 tab 还没有添加到 tabList 上 if(this.getTabById(tab.id) == null){ this.addTab(tab); } // 然后开始显示这个 tab this.nativeTab = tab; // this.nativeTab.is_load = true; // 标注:已经加载过了 this.activeMenuId = tab.id + ''; // 左边自动关联, 如果左边没有,则无效果 // 刷新一下url中的锚链 this.$nextTick(function() { this.f5HashByNativeTab(); }) // 调整一下滚动条 this.$nextTick(function() { try{ this.$refs['nav-tab-bar'].scrollToAuto(); }catch(e){} }) }, // 显示一个选项卡, 根据 id , 不存在则不显示 showTabById: function(id) { var tab = this.getTabById(id); if(tab) { this.showTab(tab); } }, // 关闭 tab (带动画) closeTab: function(tab, callFn) { // homeTab不能关闭 if(tab == this.homeTab || tab.hideClose){ return; } // 执行关闭动画 var div = document.querySelector('#tab-' + tab.id); div.style.width = div.offsetWidth + 'px'; setTimeout(function() { div.style.width = '0px'; }, 0); // 等待动画结束 setTimeout(function() { // 如果 tab 为当前正在显示的 tab, 则切换为前一个 tab if(tab == this.nativeTab) { var index = this.tabList.indexOf(tab); var preTab = this.tabList[index - 1]; if(preTab) { this.showTab(preTab); } else { var nextTab = this.tabList[index + 1]; this.showTab(nextTab); } } // 从 tabList 中移除这个 tab sa_admin_code_util.arrayDelete(this.tabList, tab); sa_admin_code_util.arrayDelete(this.viewList, tab); // 如果有回调 if(callFn) { this.$nextTick(function() { callFn(); }) } }.bind(this), 150); }, // 关闭 tab, 根据 id closeTabById: function(id, callFn) { var tab = this.getTabById(id); if(tab) { this.closeTab(tab, callFn); } }, // 悬浮打开 tab xfTab: function(tab) { console.log('悬浮'); // layer打开 var index = layer.open({ type: 2, title: tab.name, moveOut: true, // 是否可拖动到外面 maxmin: true, // 显示最大化按钮 shadeClose: false, shade: 0, area: ['80%', '80%'], zIndex: layer.zIndex, content: this.getTabUrl(tab), // 解决拉伸或者最大化的时候,iframe高度不能自适应的问题 resizing: function (layero) { sa_admin_code_util.solveLayerBug(index); }, // 操作这个layer的时候置顶它 success: function(layero){ layer.setTop(layero); } }); // 解决拉伸或者最大化的时候,iframe高度不能自适应的问题 document.querySelector('#layui-layer' + index + ' .layui-layer-max').onclick = function() { setTimeout(function() { sa_admin_code_util.solveLayerBug(index); }, 200) } }, // 新窗口打开 tab newWinTab: function(tab) { open(this.getTabUrl(tab)); // this.closeTab(tab); }, // 获取指定 tab 所代表 iframe 的 url 地址 (同域下可获取最新地址, 跨域时只能获取初始化时的地址) getTabUrl: function(tab) { var cs = '#iframe-' + tab.id; var iframe = document.querySelector(cs); if(!iframe) { return tab.url; } try{ return iframe.contentWindow.location.href; }catch(e){ return iframe.getAttribute('src'); } }, // ------------------- 框架整体相关操作 -------------------- // 展开菜单 startOpen: function() { this.isOpen = true; setTimeout(function() { this.isOpenRight = true; }.bind(this), 200); }, // 折叠菜单 endOpen: function() { this.isOpen = false; this.isOpenRight = false; }, // ------------------- 锚链接路由相关 -------------------- // 根据锚链接, 打开窗口 showTabByHash: function() { // 如果非记住模式 if(this.isRemeOpen == false) { return; } // 获取锚链接中的id var hash = location.hash; var id = hash.replace('#', ''); if(id == '') { return; } // 如果已经存在与tabbar中 var tab = this.getTabById(id); if(tab) { return this.showTab(tab); } // 否则从菜单中打开 this.showMenuById(id); // 此时, 仍有一种tab打不开, 那就是自定义tab然后还已经关闭的, // 预设 解决方案: 在localStor里存储所有打开过的tab, // 以后如果有强需求这个功能时, 再实现 }, // 根据当前tab刷新一下锚链接 f5HashByNativeTab: function() { // 如果非记住模式 if(this.isRemeOpen == false) { return; } location.hash = this.nativeTab.id; }, // ------------------- 工具方法 -------------------- // 弹窗提示 msg: function(msg) { layer.msg(msg) }, // 返回随机数 randomNum: function(min, max) { min = min || 1; max = max || 1000000000; return parseInt(Math.random() * (max - min + 1) + min, 10); }, // 从 menuList 里查找指定 id 的 menu,支持多级递归 findMenuById: function(menuList, id) { for (var i = 0; i < menuList.length; i++) { var menu = menuList[i]; if(menu.id + '' == id + '') { return menu; } // 如果是二级或多级 if(menu.childList) { var menu2 = this.findMenuById(menu.childList, id); if(menu2 != null) { return menu2; } } } return null; }, // 获取文件后缀 getUrlExt: function(url) { if(!url) { return ""; } if(url.indexOf('?') > -1) { url = url.split('?')[0]; } if(url.indexOf('#') > -1) { url = url.split('#')[0]; } var index= url.lastIndexOf("."); if(index == -1) { return ""; } var ext = url.substr(index + 1); return ext; }, // 将一维平面数组转换为 Tree 菜单 (根据其指定的 parentId 添加到其父菜单的childList) arrayToTree: function(menuList) { for (var i = 0; i < menuList.length; i++) { var menu = menuList[i]; // 如果这个 Menu 指定了 parentId 属性,则将其转移到其指定的父 Menu 的 childList 属性上 if(menu.parentId) { var parent_menu = this.findMenuById(menuList, menu.parentId); if(parent_menu) { menu.parent_menu = parent_menu; parent_menu.childList = parent_menu.childList || []; parent_menu.childList.push(menu); menuList.splice(i, 1); // 从一维中删除 i--; } } } return menuList; }, // ------------------- 其它 -------------------- // 获取指定 tab 栏的 window 对象, 用于多窗口通信 getTabWindow: function(tabId) { var iframe = document.querySelector('#iframe-' + tabId); if(iframe != null) { return iframe.contentWindow; } return null; }, // 打印版本 printVesion: function() { console.log('欢迎使用Sa-Admin,当前版本:' + this.version + ",更新于:" + this.updateTime + ",GitHub地址:" + this.githubUrl); console.log('如在使用中发现任何bug或者疑问,请加入QQ群交流:782974737,点击加入:' + 'https://jq.qq.com/?_wv=1027&k=5DHN5Ib'); }, }, created:function(){ } }); var saAdmin = sa_admin; Vue.prototype.sa_admin = sa_admin; Vue.prototype.saAdmin = saAdmin; // 监听窗口大小变动 window.onresize = function() { if(document.body.clientWidth < 800) { sa_admin.endOpen(); } else { sa_admin.startOpen(); } } // 监听锚链接变动 window.onhashchange = function() { sa_admin.showTabByHash(); } ================================================ FILE: sa-frame/index/theme.css ================================================ /* 样式调整为继承父级 */ .nav-left .el-submenu__title i, .nav-left .el-menu-item i, .nav-right-1 .el-dropdown, .tab-title:hover .el-icon-caret-right, .tab-title.tab-native .el-icon-caret-right { color: inherit; } .el-menu, .el-submenu, .nav-left .el-submenu__title, .nav-left .el-submenu .el-submenu .el-submenu__title, .nav-left .el-menu-item { color: inherit; background-color: inherit; } .theme-0 .menu-name,.theme-0 .tab-title-2>span{transition: none !important;} /* 声明变量 */ body{ --menu-bg-color: #222; /* 菜单 - 背景色 */ --menu-color: #FFF; /* 菜单 - 文字色 */ --menu-bg-color-2: #000; /* 二级菜单 - 背景色 */ --menu-hover-bg-color: #4E5465; /* 菜单悬浮 - 背景色 */ --menu-active-bg-color: #2D8CF0; /* 菜单选中 - 背景色 */ --menu-active-color: #FFF; /* 菜单选中 - 文字色 */ --tool-bg-color: #FFF; /* 工具栏 - 背景色 */ --tool-color: #333; /* 工具栏 - 文字色 */ --tool-hover-bg-color: #EEE; /* 工具栏悬浮 - 背景色 */ /* --tab-hover-bg-color: var(--menu-active-bg-color); */ /* Tab栏悬浮和选中 - 文字色 */ /* --tab-hover-color: var(--menu-active-color); */ /* Tab栏悬浮和选中 - 文字色 */ --nav-left-top-border-color: 1px #222 solid; /* 左上 - 右边框颜色 */ --nav-left-bottom-border-color: 1px #222 solid; /* 左下 - 右边框颜色 */ } /* ========================== 主题 - 0 默认样式 蓝色 ========================== */ .theme-0 {} /* 左上 - 右边框颜色 */ .theme-0 .nav-left-top{ border-right: var(--nav-left-top-border-color); } /* 左下 - 右边框颜色 */ .theme-0 .nav-left-bottom{ border-right: var(--nav-left-bottom-border-color); } /* 左边栏背景色,前景色 */ .theme-0 .nav-left { background-color: var(--menu-bg-color); color: var(--menu-color); } /* 二级菜单背景色 */ .theme-0 .el-submenu .el-menu-item, .theme-0 .nav-left .el-submenu .el-submenu .el-submenu__title{ background: var(--menu-bg-color-2); } /* 所有菜单悬浮样式*/ .theme-0 .nav-left .el-submenu__title:hover, .theme-0 .nav-left .el-submenu .el-submenu .el-submenu__title:hover, .theme-0 .nav-left .el-menu-item:hover{ background-color: var(--menu-hover-bg-color); } /* 所有菜单选中时 */ .theme-0 .nav-left .el-menu-item.is-active { /* background-color: var(--menu-active-bg-color); */ background: var(--menu-active-bg-color); color: var(--menu-active-color); } /* 工具栏背景色颜色, 前景色 */ .theme-0 .nav-right-1 { color: var(--tool-color); background-color: var(--tool-bg-color); } /* 工具栏悬浮颜色 */ .theme-0 .tool-fox:hover { background-color: var(--tool-hover-bg-color); } /* tab卡片栏 - 悬浮颜色 */ .theme-0 .tab-title:hover{ color: var(--menu-active-bg-color); border: 1px var(--menu-active-bg-color) solid; } /* tab卡片栏 - 选中颜色 */ .theme-0 .tab-native.tab-title { background-color: var(--menu-active-bg-color); color: var(--menu-active-color); border: 1px var(--menu-active-bg-color) solid; } /* 以下的主题 logo栏变小 */ .theme-3 .nav-left-top, .theme-4 .nav-left-top, .theme-10 .nav-left-top{height: 50px; line-height: 50px; text-indent: 0.3em;} .theme-3 .nav-left-top .admin-logo, .theme-4 .nav-left-top .admin-logo, .theme-10 .nav-left-top .admin-logo{width: 28px; height: 28px; position: relative; top: -2px;} .theme-3 .nav-left-bottom, .theme-4 .nav-left-bottom, .theme-10 .nav-left-bottom{height: calc(100% - 85px + 36px);} /* ========================== 主题-1 什么也不覆盖 即:全部取默认样式 ========================== */ .theme-1 {} /* ========================== 主题-2 绿色 ========================== */ .theme-2 { --menu-active-bg-color: #009688; /* 菜单选中 - 背景色 */ } /* ========================== 主题-3 白色 清爽 ========================== */ .theme-3 { --menu-bg-color: #FFF; /* 菜单 - 背景色 */ --menu-color: #333; /* 菜单 - 文字色 */ --menu-bg-color-2: #fafafa; /* 二级菜单 - 背景色 */ --menu-hover-bg-color: #ECF5FF; /* 菜单悬浮 - 背景色 */ --menu-active-bg-color: #ECF5FF; /* 菜单选中 - 背景色 */ --menu-active-color: #409EFF; /* 菜单选中 - 文字色 */ --nav-left-top-border-color: 1px #ddd solid; /* 左上 - 右边框颜色 */ --nav-left-bottom-border-color: 1px #ddd solid; /* 左下 - 右边框颜色 */ } /* ----- 附加样式 ----- */ /* logo下面的边框 */ .theme-3 .nav-left-top{border-bottom: 1px #eee solid;} /* tab卡片栏 - 悬浮颜色 */ .theme-3 .tab-title:hover{ color: var(--menu-active-color); border: 1px var(--menu-active-color) solid; } /* tab卡片栏 - 选中颜色 */ .theme-3 .tab-native.tab-title { background-color: var(--menu-active-bg-color); color: var(--menu-active-color); border: 1px var(--menu-active-color) solid; } /* ========================== 主题-4 灰绿色 ========================== */ .theme-4 { --menu-bg-color: #EEE; /* 菜单 - 背景色 */ --menu-color: #333; /* 菜单 - 文字色 */ --menu-bg-color-2: #DDD; /* 二级菜单 - 背景色 */ --menu-hover-bg-color: #ECF5FF; /* 菜单悬浮 - 背景色 */ --menu-active-bg-color: #009688; /* 菜单选中 - 背景色 */ --menu-active-color: #FFF; /* 菜单选中 - 文字色 */ --tool-bg-color: #222; /* 工具栏 - 背景色 */ --tool-color: #EEE; /* 工具栏 - 文字色 */ --tool-hover-bg-color: #444; /* 工具栏悬浮 - 背景色 */ --nav-left-bottom-border-color: 1px #ddd solid; /* 左下 - 右边框颜色 */ } .theme-4 .nav-left-top{height: 49px; line-height: 49px; text-indent: 0.3em; background-color: #222; color: #FFF;} /* ========================== 主题-5 红色 ========================== */ .theme-5 { --menu-active-bg-color: #dd4949; /* 菜单选中 - 背景色 */ } /* ========================== 主题-6 钛合金 ========================== */ .theme-6 { --menu-active-bg-color: #805322; /* 菜单选中 - 背景色 */ --tool-bg-color: #222; /* 工具栏 - 背景色 */ --tool-color: #EEE; /* 工具栏 - 文字色 */ --tool-hover-bg-color: #444; /* 工具栏悬浮 - 背景色 */ } /* ========================== 主题-7 沉淀式黑蓝 ========================== */ .theme-7 { --tool-bg-color: #222; /* 工具栏 - 背景色 */ --tool-color: #EEE; /* 工具栏 - 文字色 */ --tool-hover-bg-color: #444; /* 工具栏悬浮 - 背景色 */ } /* ========================== 主题-8 简约式灰蓝 ========================== */ .theme-8 { --menu-active-bg-color: #4E5465; /* 菜单选中 - 背景色 */ } /* ========================== 主题-9 紫色 ========================== */ .theme-9 { --menu-active-bg-color: #A906B3; /* 菜单选中 - 背景色 */ } /* ========================== 主题-10 简约草绿 ========================== */ .theme-10 { --menu-bg-color: #FFF; /* 菜单 - 背景色 */ --menu-color: #333; /* 菜单 - 文字色 */ --menu-bg-color-2: #fff; /* 二级菜单 - 背景色 */ --menu-hover-bg-color: #ECF5FF; /* 菜单悬浮 - 背景色 */ --menu-active-bg-color: #73D13D; /* 菜单选中 - 背景色 */ --nav-left-top-border-color: 1px #fff solid; /* 左下 - 右边框颜色 */ --nav-left-bottom-border-color: 1px #ddd solid; /* 左下 - 右边框颜色 */ } /* logo下面的边框 */ .theme-10 .nav-left-top{border-bottom: 1px #eee solid;} /* tab卡片栏 - 悬浮颜色 */ .theme-10 .tab-title:hover{ color: var(--menu-active-bg-color); border: 1px var(--menu-active-bg-color) solid; } /* tab卡片栏 - 选中颜色 */ .theme-10 .tab-native.tab-title { background-color: var(--menu-active-bg-color); color: var(--menu-active-color); border: 1px var(--menu-active-bg-color) solid; } ================================================ FILE: sa-frame/login/app.js ================================================ /* ----------------------------------------------- /* How to use? : Check the GitHub README /* ----------------------------------------------- */ /* To load a config file (particles.json) you need to host this demo (MAMP/WAMP/local)... */ /* particlesJS.load('particles-js', 'particles.json', function() { console.log('particles.js loaded - callback'); }); */ /* Otherwise just put the config content (json): */ particlesJS('particles-js', { "particles": { "number": { "value": 40, "density": { "enable": true, "value_area": 800 } }, "color": { "value": "#ffffff" }, "shape": { "type": "circle", "stroke": { "width": 0, "color": "#000000" }, "polygon": { "nb_sides": 5 }, "image": { "src": "img/github.svg", "width": 100, "height": 100 } }, "opacity": { "value": 0.7, "random": false, "anim": { "enable": false, "speed": 1, "opacity_min": 0.1, "sync": false } }, "size": { "value": 3, "random": true, "anim": { "enable": false, "speed": 40, "size_min": 0.1, "sync": false } }, "line_linked": { "enable": true, "distance": 150, "color": "#ffffff", "opacity": 0.6, "width": 1 }, "move": { "enable": true, "speed": 6, "direction": "none", "random": false, "straight": false, "out_mode": "out", "bounce": false, "attract": { "enable": false, "rotateX": 600, "rotateY": 1200 } } }, "interactivity": { "detect_on": "canvas", "events": { "onhover": { "enable": true, "mode": "grab" }, "onclick": { "enable": true, "mode": "push" }, "resize": true }, "modes": { "grab": { "distance": 200, "line_linked": { "opacity": 1 } }, "bubble": { "distance": 400, "size": 40, "duration": 2, "opacity": 8, "speed": 3 }, "repulse": { "distance": 200, "duration": 0.4 }, "push": { "particles_nb": 4 }, "remove": { "particles_nb": 2 } } }, "retina_detect": false } ); ================================================ FILE: sa-frame/login/reset.css ================================================ @charset "utf-8"; /* CSS Document */ /*Reset*/ *{box-sizing:content-box;} a:hover, a:focus{text-decoration:none;} body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,form,fieldset,input,textarea,p,blockquote,th,td{margin:0;padding:0;} table{border-collapse:collapse;border-spacing:0;} body{-webkit-text-size-adjust:none;} fieldset,img{border:0;} img{ vertical-align: top; max-width: 100%; } address,caption,cite,code,dfn,em,th,var{font-style:normal;font-weight:normal;} ol,ul{list-style:none;} caption,th{text-align:left;} h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:normal;} q:before,q:after{content:'';} abbr,acronym {border:0;} .clearfix:after{visibility:hidden;display: block;font-size:0;content:" ";clear:both;height:0;} * html .clearfix{ zoom: 1; } /* IE6 */ *:first-child+html .clearfix { zoom: 1; } /* IE7 */ .cli{ clear:both; font-size:0; height:0; overflow:hidden;display:block;} .lclear{clear:left;font-size:0;height:0;overflow:hidden;} .fl{float:left;} .fr{float:right;} /* ֹ iframe{nifm2:expression(this.src='about:blank',this.outerHTML='');} script{no2js:expression((this.src.toLowerCase().indexOf('http')==0)?document.close():'');} */ /* ıԼ˶ div{word-wrap: break-word;word-break: normal;} p{text-align:justify; text-justify:inter-ideograph;} */ /*general*/ body{font-size:12px;font-family:'微软雅黑',"宋体","Arial Narrow",Helvetica,sans-serif;color:#000;line-height:1.2;text-align:left;} a{color:#333;text-decoration:none;} ================================================ FILE: sa-frame/login/style.css ================================================ @charset "utf-8"; /* CSS Document */ /*Reset*/ *{box-sizing:content-box;} a:hover, a:focus{text-decoration:none;} body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,form,fieldset,input,textarea,p,blockquote,th,td{margin:0;padding:0;} table{border-collapse:collapse;border-spacing:0;} body{-webkit-text-size-adjust:none;} fieldset,img{border:0;} img{ vertical-align: top; max-width: 100%; } address,caption,cite,code,dfn,em,th,var{font-style:normal;font-weight:normal;} ol,ul{list-style:none;} caption,th{text-align:left;} h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:normal;} q:before,q:after{content:'';} abbr,acronym {border:0;} .clearfix:after{visibility:hidden;display: block;font-size:0;content:" ";clear:both;height:0;} * html .clearfix{ zoom: 1; } /* IE6 */ *:first-child+html .clearfix { zoom: 1; } /* IE7 */ .cli{ clear:both; font-size:0; height:0; overflow:hidden;display:block;} .lclear{clear:left;font-size:0;height:0;overflow:hidden;} .fl{float:left;} .fr{float:right;} /* ֹ iframe{nifm2:expression(this.src='about:blank',this.outerHTML='');} script{no2js:expression((this.src.toLowerCase().indexOf('http')==0)?document.close():'');} */ /* ıԼ˶ div{word-wrap: break-word;word-break: normal;} p{text-align:justify; text-justify:inter-ideograph;} */ /*general*/ body{font-size:12px;font-family:'微软雅黑',"宋体","Arial Narrow",Helvetica,sans-serif;color:#000;line-height:1.2;text-align:left;} a{color:#333;text-decoration:none;} /* 以下为手写代码 */ html,body{ width:100%; height:100%; } canvas{ display:block; vertical-align:bottom; } .count-particles{ background: #000022; position: absolute; top: 48px; left: 0; width: 80px; color: #13E8E9; font-size: .8em; text-align: left; text-indent: 4px; line-height: 14px; padding-bottom: 2px; font-family: Helvetica, Arial, sans-serif; font-weight: bold; } .js-count-particles{ font-size: 1.1em; } #stats, .count-particles{ -webkit-user-select: none; margin-top: 5px; margin-left: 5px; } #stats{ border-radius: 3px 3px 0 0; overflow: hidden; } .count-particles{ border-radius: 0 0 3px 3px; } #particles-js{ width: 100%; height: 100%; position: relative; /* background-image: url(sa-frame/login/bg.jpg); */ background-position: 50% 50%; background-size: cover; background-repeat: no-repeat; margin-left: auto; margin-right: auto; } .sk-rotating-plane { display: none; width: 80px; height: 80px; margin: auto; background-color: white; -webkit-animation: sk-rotating-plane 1.2s infinite ease-in-out; animation: sk-rotating-plane 1.2s infinite ease-in-out; z-index: 1; position: absolute; top: 50%; left: 50%; margin-left: -40px; margin-top: -80px; } .sk-rotating-plane.active{display: block;} @keyframes sk-rotating-plane{ 0% { -webkit-transform: perspective(120px) rotateX(0deg) rotateY(0deg); transform: perspective(120px) rotateX(0deg) rotateY(0deg); } 50% { -webkit-transform: perspective(120px) rotateX(-180.1deg) rotateY(0deg); transform: perspective(120px) rotateX(-180.1deg) rotateY(0deg); } 100% { -webkit-transform: perspective(120px) rotateX(-180deg) rotateY(-179.9deg); transform: perspective(120px) rotateX(-180deg) rotateY(-179.9deg); } } @keyframes login-small{ 0%{ transform: scale(1);-moz-transform: scale(1); /* Firefox 4 */-webkit-transform: scale(1); /* Safari 和 Chrome */-o-transform: scale(1); /* Opera */-ms-transform:scale(1); /* IE 9 */ } 100%{ transform: scale(0.2);-moz-transform: scale(0.1); /* Firefox 4 */-webkit-transform: scale(0.2); /* Safari 和 Chrome */-o-transform: scale(0.1); /* Opera */-ms-transform:scale(0.1); /* IE 9 */ } } .login{z-index: 2;position:absolute;width: 350px;border-radius: 2px;height: 500px;background: white;box-shadow: 0px 0px 5px #333333;top: 50%;left: 50%;margin-top: -250px;margin-left: -175px;transition: all 1s;-moz-transition: all 1s; /* Firefox 4 */-webkit-transition: all 1s; /* Safari 和 Chrome */-o-transition: all 1s; /* Opera */} .login-top{font-size: 24px;margin-top: 100px;padding-left: 40px;box-sizing: border-box;color: #333333;margin-bottom: 50px;} .login-center{width: 100%;box-sizing: border-box;padding: 0 40px;margin-bottom: 30px;} .login-center-img{width: 20px;height: 20px;float: left;margin-top: 5px;} .login-center-img>img{width: 100%;} .login-center-input{float: left;width: 230px;margin-left: 15px;height: 30px;position: relative;} .login-center-input input{z-index: 2;transition: all 0.5s;padding-left: 10px;color: #333333;width: 100%;height: 30px;border: 0;border-bottom: 1px solid #cccccc;border-top: 1px solid #ffffff;border-left: 1px solid #ffffff;border-right: 1px solid #ffffff;box-sizing: border-box;outline: none;position: relative;} .login-center-input input:focus{border: 1px solid dodgerblue;} .login-center-input-text{background: white;padding: 0 5px;position: absolute;z-index: 0;opacity: 0;height: 20px;top: 50%;margin-top: -10px;font-size: 14px;left: 5px;color: dodgerblue;line-height: 20px;transition: all 0.5s;-moz-transition: all 0.5s; /* Firefox 4 */-webkit-transition: all 0.5s; /* Safari 和 Chrome */-o-transition: all 0.5s; /* Opera */} .login-center-input input:focus~.login-center-input-text{top: 0;z-index: 3;opacity: 1;margin-top: -15px;} .login.active{-webkit-animation: login-small 0.8s ; animation: login-small 0.8s ;animation-fill-mode:forwards;-webkit-animation-fill-mode:forwards} .login-button{cursor: pointer;width: 250px;text-align: center;height: 40px;line-height: 40px;background-color: dodgerblue;border-radius: 5px;margin: 0 auto;margin-top: 50px;color: white;} ================================================ FILE: sa-frame/menu-list.js ================================================ // 一个菜单可以包括的所有属性 // { // id: '12345', // 菜单id, 必须唯一 // name: '用户中心', // 菜单名称, 同时也是tab选项卡上显示的名称 // icon: 'el-icon-user', // 菜单图标, 参考地址: https://element.eleme.cn/#/zh-CN/component/icon // info: '管理所有用户', // 菜单介绍, 在菜单预览和分配权限时会有显示 // url: 'sa-view/user/user-list.html', // 菜单指向地址 // parentId: 1, // 所属父菜单id, 如果指定了一个值, sa-admin在初始化时会将此菜单转移到指定菜单上 // isShow: true, // 是否显示, 默认true // isBlank: false, // 是否属于外部链接, 如果为true, 则点击菜单时从新窗口打开 // childList: [ // 指定这个菜单所有的子菜单, 子菜单可以继续指定子菜单, 至多支持四级菜单 // // .... // ], // click: function(){} // 点击菜单执行一个函数 // } // 定义菜单列表 var menuList = [ { id: '2', name: '各种示例', icon: 'el-icon-document-remove', info: '增删改查各种常用组件示例', childList: [ {id: '2-1', name: '查询参数示例', url: 'sa-view/case/query-p-case.html'}, {id: '2-2', name: '表格显示示例', url: 'sa-view/case/query-table-case.html'}, {id: '2-3', name: '表单提交示例', url: 'sa-view/case/submit-form.html'}, {id: '2-11', name: '在线表单构建', url: 'https://mrhj.gitee.io/form-generator/#/'}, ] }, { id: '3', name: '首页设置', icon: 'el-icon-search', info: '首页的一些设置', childList: [ {id: '3-1-1', name: '分类列表', icon: 'el-icon-eleme', url: 'sa-view/sys-type/sys-type-list.html'}, {id: '3-1-2', name: '分类添加', icon: 'el-icon-plus', url: 'sa-view/sys-type/sys-type-add.html'}, {id: '3-2-1', name: '轮播图列表', icon: 'el-icon-collection-tag', url: 'sa-view/home/swiper-list.html'}, {id: '3-2-2', name: '轮播图添加', icon: 'el-icon-plus', url: 'sa-view/home/swiper-add.html'}, {id: '3-3-1', name: '商品规格示例', icon: 'el-icon-plus', url: 'sa-view/ser-goods/ser-goods-add.html'}, ] }, { id: '4', name: '权限控制', icon: 'el-icon-unlock', info: '对系统角色权限的分配等设计,敏感度较高,请谨慎授权', childList: [ {id: '4-1', name: '角色列表', icon: 'el-icon-key', url: 'sa-view/role/role-list.html'}, {id: '4-2', name: '菜单列表', icon: 'el-icon-magic-stick', url: 'sa-view/role/menu-list.html'} ] }, { id: '5', name: '用户管理', icon: 'el-icon-user', info: '对用户列表、添加、统计等等...', childList: [ {id: '5-1', name: '用户列表', icon: 'el-icon-document-remove', url: 'sa-view/user/user-list.html'}, {id: '5-2', name: '用户添加', icon: 'el-icon-plus', url: 'sa-view/user/user-add.html'}, { id: '5-3', name: '用户统计', icon: 'el-icon-data-line', childList: [ {id: '1-3-1', name: '注册量统计', icon: 'el-icon-pie-chart', url: 'sa-view/user/user-chart.html'}, ] }, ] }, { id: '6', name: '文章管理', icon: 'el-icon-document-copy', info: '对文章的增删改查、维护', childList: [ {id: '6-1', name: '文章列表', url: 'sa-view/article/art-list.html'}, {id: '6-2', name: '文章发布', url: 'sa-view/article/art-add.html'}, ] }, { id: '7', name: '系统设置', icon: 'el-icon-setting', info: '有关系统的一些设置', childList: [ {id: '7-1', name: '登录页', url: 'login.html'}, {id: '7-8', name: '403无权限', url: 'sa-view/error-page/403.html'}, {id: '7-9', name: '404未找到', url: 'sa-view/error-page/404.html'}, {id: '7-10', name: '500有错误', url: 'sa-view/error-page/500.html'}, {id: '7-11', name: '服务器设置', url: 'sa-view/cfg/system-cfg.html', info: '对服务器参数的设置'}, {id: '7-12', name: '函数菜单', click: function(){sa.alert('点击菜单执行一个函数,你可以自定义任意代码')}}, {id: '6-3', name: 'vue组件', url: 'sa-view/cfg/xxx.vue'} ] }, // ========= 示例 外部链接 点击从新窗口打开 ================ { id: '8', name: '友情链接', icon: 'el-icon-link', info: '示例:外部链接', childList: [ {id: '8-21', name: '极品蓝图', url: 'http://un.jipinlantu.com/', isBlank: true}, {id: '8-11', name: '河浪前端笔记', url: 'https://mydarling.gitee.io/resource/', isBlank: true}, // {id: '8-1', name: '百度一下', url: 'https://www.baidu.com/', isBlank: true}, {id: '8-41', name: 'sa-admin单页版', url: 'http://sa-vue-admin.dev33.cn/', isBlank: true}, {id: '8-3', name: 'sa-token', url: 'http://sa-token.dev33.cn/', isBlank: true}, {id: '8-12', name: 'sa-doc', url: 'http://sa-doc.dev33.cn/', isBlank: true}, {id: '8-13', name: 'sa-plus', url: 'http://sa-plus.dev33.cn/', isBlank: true}, {id: '8-4', name: 'SqlFly', url: 'https://sqlfly.dev33.cn/', isBlank: true}, {id: '8-6', name: '颜值排行榜', url: 'http://yanzhi21.com/', isBlank: true}, {id: '8-7', name: 'jq22插件库', url: 'http://www.jq22.com/', isBlank: true}, {id: '8-2', name: 'uni-app', url: 'https://uniapp.dcloud.io/', isBlank: true}, {id: '8-31', name: '秀恩爱专用', url: 'http://click33.gitee.io/xixi/'}, ] }, // ========= 示例 隐藏的菜单,最终将不会显示在菜单栏里 ================ { id: '9', name: '一个隐藏菜单', url: 'https://www.baidu.com/', isBlank: true, isShow: false// 隐藏 }, // ========= jq22搜集 ================ { id: '111', name: 'jq22搜集', icon: 'el-icon-link', info: '示例:外部链接', childList: [ { id: '110', name: '大屏展示', icon: 'el-icon-link', info: '大屏展示页', childList: [ {id: '110-1', name: '大屏1', url: 'http://www.jq22.com/demo/estszjcmoban202008030007/'}, // 原作者:http://www.jq22.com/jquery-info23260 {id: '110-2', name: '大屏2', url: 'http://www.jq22.com/demo/estjkdsj202007301414/'}, // 原作者:http://www.jq22.com/jquery-info23247 {id: '110-3', name: '大屏3', url: 'http://www.jq22.com/demo/jquerygndsjmoban202007212350/'}, // 原作者:http://www.jq22.com/jquery-info23239 {id: '110-4', name: '大屏4', url: 'http://www.jq22.com/demo/jqueryEchartsny202006151033/'}, // 原作者:http://www.jq22.com/jquery-info23114 {id: '110-5', name: '大屏5', url: 'http://www.jq22.com/demo/echartsdindanmoban202007302202/'}, // 原作者:http://www.jq22.com/jquery-info23202 {id: '110-6', name: '大屏6', url: 'http://www.jq22.com/demo/echartssjmoban202005210009/'}, // 原作者:http://www.jq22.com/jquery-info23047 {id: '110-7', name: '大屏7', url: 'http://www.jq22.com/demo/echartsdsj202002251026/'}, // 原作者:http://www.jq22.com/jquery-info22826 {id: '110-8', name: '大屏8', url: 'http://www.jq22.com/demo/echartswldsj201912112223/'}, // 原作者:http://www.jq22.com/jquery-info22636 ], }, {id: '111-1', name: '图片切换', url: 'http://www.jq22.com/demo/jQueryTpqh201804012309/'}, // 原作者:https://www.jq22.com/jquery-info18534 {id: '111-2', name: '3D旋转特效', url: 'http://www.jq22.com/demo/jQueryCss3D201710241004/'}, // 原作者:https://www.jq22.com/jquery-info16495 {id: '111-3', name: 'canvas炫酷星空', url: 'http://www.jq22.com/demo/warpDrive201712211120/index.html'}, // 原作者:https://www.jq22.com/jquery-info17456 {id: '111-4', name: 'H5碰撞小球', url: 'http://www.jq22.com/demo/html5Pzxq201712242209/'}, // 原作者:https://www.jq22.com/jquery-info17482 {id: '111-5', name: '网页画板', url: 'http://www.jq22.com/demo/Mapping201802252341/'}, // 原作者:https://www.jq22.com/jquery-info18172 {id: '111-6', name: '简约富文本编辑器', url: 'http://www.jq22.com/demo/jquery-notebook-master/'}, // 原作者:https://www.jq22.com/jquery-info345 {id: '111-7', name: '水滴特效', url: 'http://www.jq22.com/demo/jquery-shuidi20151123/'}, // 原作者:https://www.jq22.com/jquery-info4835 {id: '111-8', name: '图片放大', url: 'http://www.jq22.com/demo/jQueryJpg201708110048/'}, // 原作者:http://www.jq22.com/jquery-info15264 {id: '111-9', name: '3D云', url: 'http://www.jq22.com/demo/jquery-cloud-141217202931/'}, // 原作者:http://www.jq22.com/jquery-info1325 {id: '111-10', name: '3D选择图片', url: 'http://www.jq22.com/demo/jquery-3d20150831/'}, // 原作者:http://www.jq22.com/jquery-info4000 {id: '111-11', name: '蜘蛛纸牌', url: 'http://www.jq22.com/demo/jqueryspider201809140137/'}, // 原作者:http://www.jq22.com/jquery-info20047 {id: '111-12', name: '大转盘', url: 'http://www.jq22.com/demo/jquerylocal201912122316/'}, // 原作者:http://www.jq22.com/jquery-info22646 {id: '111-13', name: '旋转地球', url: 'http://www.jq22.com/demo/earth201810300101/'}, // 原作者:http://www.jq22.com/jquery-info20328 {id: '111-14', name: '下雨动画', url: 'http://www.jq22.com/demo/html5-canvas-rain201710252014/'}, // 原作者:http://www.jq22.com/jquery-info16518 {id: '111-15', name: '绚丽星空', url: 'http://www.jq22.com/demo/jQuery3dxk201710142249/'}, // 原作者:http://www.jq22.com/jquery-info16294 {id: '111-16', name: '3d波浪墙', url: 'http://www.jq22.com/demo/voxels-liquid201704112355/'}, // 原作者:http://www.jq22.com/jquery-info13400 {id: '111-17', name: '元素周期表', url: 'http://www.jq22.com/demo/jquery-3D20151113/'}, // 原作者:http://www.jq22.com/jquery-info4710 {id: '111-18', name: '旋转相册', url: 'http://www.jq22.com/demo/tikm202006072243/'}, // 原作者:http://www.jq22.com/jquery-info23116 {id: '111-19', name: '装逼专用', url: 'http://www.jq22.com/demo/canvaslxy202003192234/'}, // 原作者:http://www.jq22.com/jquery-info22793 {id: '111-20', name: '3D粒子文字', url: 'http://www.jq22.com/demo/3dwz201912102124/'}, // 原作者:http://www.jq22.com/jquery-info22631 {id: '111-21', name: '多面立方体', url: 'http://www.jq22.com/demo/threelft201905080117/'}, // 原作者:http://www.jq22.com/demo/threelft201905080117/ {id: '111-22', name: '常见配色', url: 'http://www.jq22.com/demo/jQueryColour202008050020/'}, // 原作者:http://www.jq22.com/jquery-info23262 {id: '111-23', name: '音量调节', url: 'http://www.jq22.com/demo/AdjustVolume202005122241/'}, // 原作者:http://www.jq22.com/jquery-info23045 {id: '111-24', name: '重力下落', url: 'http://www.jq22.com/demo/gamecaisse202005220040/'}, // 原作者:http://www.jq22.com/jquery-info23074 {id: '111-25', name: '表情匹配', url: 'http://www.jq22.com/demo/emojimatchgame201907170050/dist/'}, // 原作者:http://www.jq22.com/jquery-info21952 ] }, ] ================================================ FILE: sa-frame/nav/com-add-tab.vue ================================================ ================================================ FILE: sa-frame/nav/com-right-menu.vue ================================================ ================================================ FILE: sa-frame/nav/nav-logo.vue ================================================ ================================================ FILE: sa-frame/nav/nav-menu-bar.vue ================================================ ================================================ FILE: sa-frame/nav/nav-tab-bar.vue ================================================ ================================================ FILE: sa-frame/nav/nav-tool-bar.vue ================================================ ================================================ FILE: sa-frame/nav/nav-view-vessel.vue ================================================ ================================================ FILE: sa-frame/sa-code.js ================================================ // 在使用时,不建议你直接魔改模板的代码,以免在运行时出现意外bug,而是在本文件中根据模板的提供的API,来适应你的业务逻辑 // .... // ================================= 示例:一些基本信息 ================================= // 设置模板标题 sa_admin.title = "Sa-Admin"; sa_admin.logo = 'sa-frame/admin-logo.png'; // 设置logo图标地址 sa_admin.icon = 'sa-frame/admin-logo.png'; // 设置icon图标地址 // ================================= 示例:自定义菜单 ================================= var myMenuList = window.menuList; // window.menuList 在 menu-list.js 中定义 sa_admin.setMenuList(myMenuList); // 写入菜单 // sa_admin.setMenuList(myMenuList, [11, 1, '1-1']); // 写入菜单,并设置应该显示哪些id的菜单(第二个参数为空时,代表默认显示所有) // sa_admin.initMenu(); // 更简单的写法,相当于setMenuList省略第一个参数 // 如果需要获得更多操作能力,如:动态添加菜单、删除菜单等 // 可直接 sa_admin.menuList 获得菜单引用,直接操作对象 // ================================= 示例:js控制打开某个菜单 ================================= // 显示主页选项卡 // sa_admin.showHome(); // 显示一个选项卡, 根据id // sa_admin.showTabById('1-1'); // 关闭一个选项卡,根据 id // sa_admin.closeTabById('1-1'); // 新增一个选项卡 // sa_admin.addTab({id: 12345, name: '新页面', url: 'http://web.yanzhi21.com'}); // id不要和已有的菜单id冲突,其它属性均可参照菜单项 // 新增一个选项卡、并立即显示 // sa_admin.showTab({id: 12345, name: '新页面', url: 'http://web.yanzhi21.com'}); // 参数同上 // 打开一个 菜单,根据 id // sa_admin.showMenuById('1-1'); // ================================= 示例:设置user信息 ================================= // 用户登录后,右上角可直接显示用户的头像和昵称 sa_admin.user = { username: 'root', // 昵称 avatar: 'sa-frame/admin-logo.png' // 头像地址 } // ================================= 示例:设置登录后的头像处,下拉可以出现的选项 ================================= sa_admin.dropList = [ // 头像点击处可操作的选项 { name: '我的资料', click: function() { sa_admin.$message('点击了我的资料,你可以参照文档重写此函数'); } }, { name: '切换账号', click: function() { sa.$page.openLogin('login.html'); // layer.open({ // type: 2, // title: false, // closeBtn: false, // shadeClose: true, // shade: 0.8, // area: ['70%', '80%'], // resize: false, // content: 'login.html' // }); } }, { name: '退出登录', click: function() { // sa_admin.$message('点击了退出登录,你可以参照文档重写此函数'); // location="login.html"; sa.confirm('退出登录?', function(res) { sa.ajax2('/acc/exit', function(res) { sa.alert('注销成功', function() { location.href = "login.html"; }) }, {msg: '正在注销'}) }); } } ] // ================================= 示例:调用另一个页面的代码 ================================= // var win = sa_admin.getTabWindow('2-1'); // 根据id获取其页面的window对象 (如果此页面未打开,则返回空)(跨域模式下无法获取其window对象) // win.app.f5(); // 注意: // 根据`iframe`的子父通信原则,在子页面中调用父页面的方法,需要加上parent前缀,例如: // parent.sa_admin.msg('啦啦啦'); // 调用父页面的弹窗方法 // ================================= 示例:初始化模板(必须调用) ================================= // 初始化模板 sa_admin.init(); ================================================ FILE: sa-view/article/art-add.html ================================================ 文章-添加/修改 ================================================ FILE: sa-view/article/art-list.html ================================================ 帖子列表 ================================================ FILE: sa-view/article/data-list.js ================================================ var mockData = { code: 200, msg: 'ok', data: [{ "id": 20, "title": "那个清晨", "content": "那个清晨一大早,便被母亲叫起。我有些不满,平常我是总要在床上多赖一会儿的。可当我迷迷糊糊的看到母亲紧绷的脸庞时...", "see_count": 356, "like_count": 55, "share_count": 13, "create_username": '省长', "is_public": 1, "create_time": "2019-05-12" }, { "id": 17, "title": "人生,就是一场抵达", "content": "庄子说,人生天地之间,若白驹过隙,忽然而已。人生就是一场抵达,我们总以为来日方长...", "see_count": 200, "like_count": 12, "share_count": 6, "create_username": '小言', "is_public": 1, "create_time": "2019-05-12" }, { "id": 11, "title": "气质女生与世界先生", "content": "我把衣柜翻了个底朝天,花花绿绿地堆了满床。谢雨帆盘腿坐在电脑前打游戏,嗑着瓜子眼皮也不抬一下,半晌才悠悠地吐出一句...", "see_count": 240, "like_count": 22, "share_count": 15, "create_username": 'fan哈', "is_public": 2, "create_time": "2019-05-10" }, { "id": 9, "title": "善待朋友,珍惜拥有", "content": "不要弄丢,一个对你好的人;不要漠视,一份待你深的情。不是谁都能包容你的臭脾气,更不是谁都能一直等下去...", "see_count": 2420, "like_count": 122, "share_count": 95, "create_username": '小丸子', "is_public": 2, "create_time": "2019-05-5" }, { "id": 7, "title": "爱是淡淡的忧伤", "content": "回味初识的那一段深情爱恋,清晰的面容,熟悉的身影,悦耳的声音,在某个深夜恍然想起。那是一个深秋的夜晚,我们相拥而坐...", "see_count": 320, "like_count": 12, "share_count": 5, "create_username": '不值一提', "is_public": 1, "create_time": "2019-05-1" }, { "id": 6, "title": "男人看了沉默,女人看了流泪", "content": "男人看了沉默,女人看了流泪男人看了沉默,女人看了流泪男人看了沉默,女人看了流泪男人看了沉默,女人看了流泪...", "see_count": 3220, "like_count": 11, "share_count": 1, "create_username": 'UC震惊部', "is_public": 1, "create_time": "2019-05-1" }, { "id": 5, "title": "爱是淡淡的忧伤", "content": "回味初识的那一段深情爱恋,清晰的面容,熟悉的身影,悦耳的声音,在某个深夜恍然想起。那是一个深秋的夜晚,我们相拥而坐...", "see_count": 320, "like_count": 12, "share_count": 5, "create_username": '不值一提', "is_public": 1, "create_time": "2019-05-1" } ], dataCount: 6379 } ================================================ FILE: sa-view/case/mock-data-list.js ================================================ var mockDataList = { code: 200, msg: 'ok', data: [ { id: 101, name: '苹果', icon: 'el-icon-apple', avatar: 'http://color-test.oss-cn-qingdao.aliyuncs.com/dyc/img/2020/01/19/15794196587511189314194.png', money: 1999, status: 1, day: '135', create_time: new Date() }, { id: 102, name: '香蕉', icon: 'el-icon-apple', avatar: 'http://color-test.oss-cn-qingdao.aliyuncs.com/dyc/img/2020/01/19/15794196587511189314194.png', money: 2555, status: 1, day: '135', create_time: new Date() }, { id: 103, name: '茄子', icon: 'el-icon-cherry', avatar: 'http://color-test.oss-cn-qingdao.aliyuncs.com/dyc/img/2020/01/19/15794196587511189314194.png', money: 4999, status: 1, day: '135', create_time: new Date() }, { id: 104, name: '芸豆', icon: 'el-icon-cherry', avatar: 'http://color-test.oss-cn-qingdao.aliyuncs.com/dyc/img/2020/01/19/15794196587511189314194.png', money: 5555, status: 1, day: '135', create_time: new Date() }, { id: 105, name: '木须肉', icon: 'el-icon-umbrella', avatar: 'http://color-test.oss-cn-qingdao.aliyuncs.com/dyc/img/2020/01/19/15794196587511189314194.png', money: 10000, status: 1, day: '246', create_time: new Date() }, { id: 106, name: '回锅肉', icon: 'el-icon-umbrella', avatar: 'http://color-test.oss-cn-qingdao.aliyuncs.com/dyc/img/2020/01/19/15794196587511189314194.png', money: 10000, status: 1, day: '246', create_time: new Date() }, { id: 107, name: '辣子鸡', icon: 'el-icon-user', avatar: 'http://color-test.oss-cn-qingdao.aliyuncs.com/dyc/img/2020/01/19/15794196587511189314194.png', money: 99999, status: 2, day: '246', create_time: new Date() }, { id: 108, name: '大萝贝', icon: 'el-icon-user', avatar: 'http://color-test.oss-cn-qingdao.aliyuncs.com/dyc/img/2020/01/19/15794196587511189314194.png', money: 23333, status: 2, day: '567', create_time: new Date() }, ], dataCount: 1244 } ================================================ FILE: sa-view/case/mock-joptions.js ================================================ var mockJoptions = [ // 级联选项 { value: 'v1', label: '选项1', children: [ { value: 'v1-1', label: '选项1-1', children: [ {value: 'v1-1-1', label: '选项1-1-1'}, {value: 'v1-1-2', label: '选项1-1-2'}, {value: 'v1-1-3', label: '选项1-1-3'}, ] }, {value: 'v1-2', label: '选项1-2'}, {value: 'v1-3', label: '选项1-3'}, ] }, { value: 'v2', label: '选项2', children: [ {value: 'v2-1', label: '选项2-1'}, {value: 'v2-2', label: '选项2-2'} ] }, { value: 'v3', label: '选项3', children: [ {value: 'v3-1', label: '选项3-1'}, {value: 'v3-2', label: '选项3-2'} ] } ]; ================================================ FILE: sa-view/case/query-p-case.html ================================================ 各种查询参数示例 ================================================ FILE: sa-view/case/query-table-case-add.html ================================================ 表格显示示例-修改 ================================================ FILE: sa-view/case/query-table-case.html ================================================ 各种表格显示示例 ================================================ FILE: sa-view/case/submit-form.html ================================================ 表单提交示例 ================================================ FILE: sa-view/cfg/system-cfg.html ================================================ 角色列表 ================================================ FILE: sa-view/cfg/xxx.vue ================================================ ================================================ FILE: sa-view/console/com-chart-1.vue ================================================ ================================================ FILE: sa-view/console/com-chart-2.vue ================================================ ================================================ FILE: sa-view/console/com-chart-3.vue ================================================ ================================================ FILE: sa-view/console/com-intro.vue ================================================ ================================================ FILE: sa-view/console/com-origin.vue ================================================ ================================================ FILE: sa-view/console/com-sta-data.vue ================================================ ================================================ FILE: sa-view/console/com-stack.vue ================================================ ================================================ FILE: sa-view/console/com-update-log.vue ================================================ ================================================ FILE: sa-view/console/console-main.html ================================================ Sa-Admin 控制台
================================================ FILE: sa-view/error-page/403.html ================================================ 403

403 - 你还没有权限进行当前操作哦 , 你可以:回到首页

================================================ FILE: sa-view/error-page/404.html ================================================ 404

404 - 没有找到你想要的页面 , 你可以:回到首页

================================================ FILE: sa-view/error-page/500.html ================================================ 500

500 - 服务器好像出了点问题 , 你可以:回到首页

================================================ FILE: sa-view/home/mock-data-list.js ================================================ // 数据 var mockDataList = { code: 200, msg: 'ok', data: [{ "id": 1, "title": "壁纸1", "img_src": "https://color-test.oss-cn-qingdao.aliyuncs.com/sa-admin/32.jpg", "type": 1, "link": "", "click_count": 21, "create_time": "2019-05-23T03:41:48.000+0000", "status": 1, "sort": 1, "is_update": false }, { "id": 2, "title": "壁纸2", "img_src": "https://color-test.oss-cn-qingdao.aliyuncs.com/sa-admin/46.png", "type": 1, "link": "", "click_count": 54, "create_time": "2019-05-23T03:43:15.000+0000", "status": 1, "sort": 2, "is_update": false }, { "id": 3, "title": "壁纸3", "img_src": "http://color-test.oss-cn-qingdao.aliyuncs.com/dyc/img/2020/01/20/15795058964941214251195.jpg", "type": 1, "link": "", "click_count": 16, "create_time": "2019-05-23T03:11:16.000+0000", "status": 1, "sort": 3, "is_update": false }, { "id": 4, "title": "壁纸4", "img_src": "http://color-test.oss-cn-qingdao.aliyuncs.com/dyc/img/2020/01/20/1579506018108368398487.png", "type": 1, "link": "", "click_count": 91, "create_time": "2019-05-23T03:11:16.000+0000", "status": 1, "sort": 4, "is_update": false }], dataCount: 1433 } ================================================ FILE: sa-view/home/swiper-add.html ================================================ 商品分类表-添加/修改 ================================================ FILE: sa-view/home/swiper-list.html ================================================ 各种查询参数示例 ================================================ FILE: sa-view/role/menu-list.html ================================================ 菜单预览 ================================================ FILE: sa-view/role/menu-setup.html ================================================ 权限分配 ================================================ FILE: sa-view/role/mock-data.js ================================================ // 模拟数据 var mockData = { code: 200, msg: 'ok', data: [{ "id": 1, "role_name": "普通用户", "role_info": "普通用户", "is_lock": 1, "create_time": "2018-08-17T02:33:14.000+0000" }, { "id": 11, "role_name": "顶级管理员", "role_info": "最高权限", "is_lock": 1, "create_time": "2018-08-17T02:33:14.000+0000" }, { "id": 101, "role_name": "超级管理员", "role_info": "最高权限", "is_lock": 2, "create_time": "2018-08-17T03:24:01.000+0000" }] } ================================================ FILE: sa-view/role/role-add.html ================================================ 商品分类表-添加/修改 ================================================ FILE: sa-view/role/role-list.html ================================================ 角色列表 ================================================ FILE: sa-view/sa-doc/check-per.md ================================================ # sa-admin 集成鉴权功能 #### 1、首先在登录时,写入当前会话所具有的权限码集合 ``` var arr = ['1', '2', '3', 'a', 'b', 'c']; // 一般由后端提供接口返回当前会话所具有的权限码集合 sa.setAuth(arr); // 写入本地缓存中 ``` 测试: #### 2、然后:如果一个页面需要某个权限码才能打开 ``` // 在这个页面的 ================================================ FILE: sa-view/sa-doc/start-up.md ================================================ # sa-admin 使用步骤 五分钟快速上手 #### 1、获取 源码 > - 你有两种方式获取源码 > - 通过gitee、或github获取源码 > - [点我直接下载](http://sa-admin.dev33.cn/sa-admin-dev.rar) #### 2、使用说明 > - 在使用时,不建议你直接魔改模板的代码,以免在运行时出现意外bug,而是用扩展的方法,来适应你的业务逻辑 > - 如何扩展?在 `sa-resourecs` 文件下,有个 `sa-code.js` ,这是专门为了方便你接入你的业务逻辑而预留的一个文件 你可以在此文件中根据模板提供的API来操作模板 > - 具体可以操作哪些接口?接着往下看 #### 3、设置模板标题 ``` js sa_admin.title = "SA-后台模板"; // sa_admin.logo='url'; // 设置logo图标地址 默认值:sa-frame/admin-logo.png // sa_admin.icon = 'sa-frame/admin-logo.png'; // 设置icon图标地址 默认值:sa-frame/admin-logo.png ``` 测试: #### 4、自定义菜单树 ``` js var myMenuList = window.menuList; // window.menuList 在 menu-list.js 中定义 sa_admin.setMenuList(myMenuList); // 写入菜单 // sa_admin.setMenuList(myMenuList, [11, 1, '1-1']); // 写入菜单,并设置应该显示哪些id的菜单(第二个参数为空时,代表默认显示所有) ``` #### 5、js控制打开某个菜单 ```js sa_admin.showHome(); // 显示主页选项卡 sa_admin.showTabById('1-1'); // 显示一个选项卡, 根据id sa_admin.closeTabById('1-1'); // 关闭一个选项卡,根据 id ( 第二个参数可填关闭后的回调函数 ) sa_admin.showMenuById('1-1'); // 打开一个 菜单,根据 id // 新增一个选项卡 // sa_admin.addTab({id: 12345, name: '新页面', url: 'http://sa-token.dev33.cn/'}); // id不要和已有的菜单id冲突,其它属性均可参照菜单项 // 新增一个选项卡、并立即显示 // sa_admin.showTab({id: 12345, name: '新页面', url: 'http://web.yanzhi21.com'}); // 参数同上 ``` 测试: #### 6、如何设置登录后右上角显示的user信息 ``` js sa_admin.user = { username: 'root', // 昵称 avatar: 'sa-frame/admin-logo.png' // 头像地址 } ``` #### 7、重写按钮事件 你可以轻松自定义登录后的头像处,下拉可以出现的选项 ``` js sa_admin.dropList = [ // 头像点击处可操作的选项 { name: '我的资料', click: function() { /* balabala... */ } }, { name: '退出登录', click: function() { /* balabala... */ } } ] ``` #### 8、怎么在一个选项卡页面调用另一个页面的代码 ``` js var win = sa_admin.getTabWindow('2-1'); // 根据id获取其页面的window对象 (如果此页面未打开,则返回空)(跨域模式下无法获取其window对象) win.app.f5(); // 然后调用这个对象上的方法 ``` #### 9、子父窗口通信操作注意点 根据`iframe`的子父通信原则,在子页面中调用父页面的方法,需要加上parent前缀,例如: ``` parent.sa_admin.msg('啦啦啦'); // 调用父页面的弹窗方法 ``` #### 10、初始化模板(必须调用) ``` js sa_admin.init(); // 初始化模板 // 或者以下方式,增加配置项 sa_admin.init({ themeDefault: '1', // 默认的主题,可选值:1、2、3、4、5、6、7 switchDefault: 'fade', // 默认的切换动画,可选值:fade、slide、cube、coverflow、flip is_reme_open: true, // 是否记住上一次最后打开的窗口, 默认为true, 配置为false后, 每次刷新不再自动打开上一次最后打开的窗口(也不再有锚链接智能tab调准) }); ``` 想获得更多操作能力?其实在`sa_admin`对象上的所有属性和函数都可以直接调用 #### 11、以上示例在 sa-code.js中 都有相应的注释说明,如何还有不懂的地方,可以加群问我(群链接在首页) ================================================ FILE: sa-view/ser-goods/ser-goods-add.html ================================================ 商品表-添加/修改 ================================================ FILE: sa-view/sys-type/moke-data.js ================================================ var getMockData = function(name) { name = name || ""; var dataList = [ { "id": 101, "name": "虚拟物品", "icon": "http://oss.dev33.cn/sa-admin/pic_yhk1.png", "sort": 3, "create_time": "2020-08-04 00:19:35" }, { "id": 102, "name": "休闲零食", "icon": "http://oss.dev33.cn/sa-admin/pic_gtgsh1.png", "sort": 2, "create_time": "2020-08-04 00:19:35" }, { "id": 103, "name": "服饰箱包", "icon": "http://oss.dev33.cn/sa-admin/pic_car1.png", "sort": 4, "create_time": "2020-08-04 00:19:35" }, { "id": 104, "name": "宠物生活", "icon": "http://oss.dev33.cn/sa-admin/pic_cxtj1.png", "sort": 1, "create_time": "2020-08-04 00:19:35" }, { "id": 105, "name": "图书文娱", "icon": "http://oss.dev33.cn/sa-admin/pic_yhk1.png", "sort": 8, "create_time": "2020-08-04 00:19:35" }, { "id": 106, "name": "电脑办公", "icon": "http://oss.dev33.cn/sa-admin/pic_gtgsh1.png", "sort": 6, "create_time": "2020-08-04 00:19:35" }, { "id": 107, "name": "汽车生活", "icon": "http://oss.dev33.cn/sa-admin/pic_car1.png", "sort": 5, "create_time": "2020-08-04 00:19:35" }, { "id": 108, "name": "玩具乐器", "icon": "http://oss.dev33.cn/sa-admin/pic_cxtj1.png", "sort": 7, "create_time": "2020-08-04 00:19:35" } ]; var mockData = { "code": 200, "msg": "ok", "data": [], "dataCount": 100 } // 根据名称筛选 for (var i = 0; i < dataList.length; i++) { if(dataList[i].name.indexOf(name) > -1) { mockData.data.push(dataList[i]); } } // 返回 return mockData; } ================================================ FILE: sa-view/sys-type/sys-type-add.html ================================================ 商品分类表-添加/修改 ================================================ FILE: sa-view/sys-type/sys-type-info.html ================================================ 商品分类-详情 ================================================ FILE: sa-view/sys-type/sys-type-list.html ================================================ 商品分类-列表 ================================================ FILE: sa-view/user/data-list.js ================================================ // 模拟数据 var mockData = { code: 200, msg: 'ok', data: [{ "id": 12001, "username": "省长", "avatar": "https://color-test.oss-cn-qingdao.aliyuncs.com/dyc/img/default_head/2.png?x-oss-process=style/yasuo", "tell": '这人懒,啥也没有留下', "sex": "男", "photo_list": [ "http://color-test.oss-cn-qingdao.aliyuncs.com/dyc/img/2019/02/02/1549112799839261454077.jpeg?x-oss-process=style/yasuo", "http://color-test.oss-cn-qingdao.aliyuncs.com/dyc/img/2019/02/02/15491128027001242326540.jpeg?x-oss-process=style/yasuo", "http://color-test.oss-cn-qingdao.aliyuncs.com/dyc/img/2019/02/02/1549112804446367923451.jpeg?x-oss-process=style/yasuo", "http://color-test.oss-cn-qingdao.aliyuncs.com/dyc/img/2019/02/02/1549112806223866151639.jpeg?x-oss-process=style/yasuo", "http://color-test.oss-cn-qingdao.aliyuncs.com/dyc/img/2019/02/02/15491128087691462190017.jpeg?x-oss-process=style/yasuo" ], "create_type": "账号注册", "create_time": "2019-02-09 20:22:00", "status": 1 }, { "id": 12002, "username": "小言", "avatar": "https://color-test.oss-cn-qingdao.aliyuncs.com/dyc/img/default_head/3.png?x-oss-process=style/yasuo", "tell": '人懒,啥也没留', "sex": "女", "photo_list": [ "http://color-test.oss-cn-qingdao.aliyuncs.com/dyc/img/2019/01/28/15486414241411760471758.jpg?x-oss-process=style/yasuo", "http://color-test.oss-cn-qingdao.aliyuncs.com/dyc/img/2019/01/28/1548641424112923395306.jpg?x-oss-process=style/yasuo", "http://color-test.oss-cn-qingdao.aliyuncs.com/dyc/img/2019/01/28/1548641424124307645243.jpg?x-oss-process=style/yasuo", "http://color-test.oss-cn-qingdao.aliyuncs.com/dyc/img/2019/01/28/15486414241301079583057.jpg?x-oss-process=style/yasuo", "http://color-test.oss-cn-qingdao.aliyuncs.com/dyc/img/2019/01/28/15486414241351214293219.jpg?x-oss-process=style/yasuo", "http://color-test.oss-cn-qingdao.aliyuncs.com/dyc/img/2019/01/28/1548641424156586322884.jpg?x-oss-process=style/yasuo" ], "create_type": "账号注册", "create_time": "2019-02-11 13:22:41", "status": 1 }, { "id": 12003, "username": "旧城人凉", "avatar": "https://color-test.oss-cn-qingdao.aliyuncs.com/dyc/img/default_head/4.png?x-oss-process=style/yasuo", "tell": '人懒,啥也没留', "sex": "女", "photo_list": [ "http://color-test.oss-cn-qingdao.aliyuncs.com/dyc/img/2019/01/29/15487010332581464190738.jpg?x-oss-process=style/yasuo", "http://color-test.oss-cn-qingdao.aliyuncs.com/dyc/img/2019/01/29/15487010332521119691172.jpg?x-oss-process=style/yasuo", "http://color-test.oss-cn-qingdao.aliyuncs.com/dyc/img/2019/01/29/15487010332621622298950.jpg?x-oss-process=style/yasuo", "http://color-test.oss-cn-qingdao.aliyuncs.com/dyc/img/2019/01/29/15487010332711954721691.jpg?x-oss-process=style/yasuo", "http://color-test.oss-cn-qingdao.aliyuncs.com/dyc/img/2019/01/29/1548701033275197287565.jpg?x-oss-process=style/yasuo", "http://color-test.oss-cn-qingdao.aliyuncs.com/dyc/img/2019/01/29/1548701033277157114772.jpg?x-oss-process=style/yasuo", "http://color-test.oss-cn-qingdao.aliyuncs.com/dyc/img/2019/01/29/15487010332801673263633.jpg?x-oss-process=style/yasuo" ], "create_type": "账号注册", "create_time": "2019-02-11 8:22:56", "status": 1 }, { "id": 12004, "username": "苦巷深桥", "avatar": "https://color-test.oss-cn-qingdao.aliyuncs.com/dyc/img/default_head/5.png?x-oss-process=style/yasuo", "tell": '人懒,啥也没留', "sex": "女", "photo_list": [ "http://color-test.oss-cn-qingdao.aliyuncs.com/dyc/img/2019/01/28/1548641148401699190597.jpg?x-oss-process=style/yasuo", "http://color-test.oss-cn-qingdao.aliyuncs.com/dyc/img/2019/01/28/1548641148403368860642.jpg?x-oss-process=style/yasuo", "http://color-test.oss-cn-qingdao.aliyuncs.com/dyc/img/2019/01/28/1548641148447490522299.jpg?x-oss-process=style/yasuo", "http://color-test.oss-cn-qingdao.aliyuncs.com/dyc/img/2019/01/28/15486411484491404458881.jpg?x-oss-process=style/yasuo", "http://color-test.oss-cn-qingdao.aliyuncs.com/dyc/img/2019/01/28/15486411484521613746711.jpg?x-oss-process=style/yasuo", "http://color-test.oss-cn-qingdao.aliyuncs.com/dyc/img/2019/01/28/1548641148452436812749.jpg?x-oss-process=style/yasuo" ], "create_type": "账号注册", "create_time": "2019-02-13 12:22:12", "status": 1 }, { "id": 12005, "username": "三重门", "avatar": "https://color-test.oss-cn-qingdao.aliyuncs.com/dyc/img/default_head/6.png?x-oss-process=style/yasuo", "tell": '人懒,啥也没留', "sex": "女", "photo_list": [ "http://color-test.oss-cn-qingdao.aliyuncs.com/dyc/img/2019/01/28/1548639217745410394722.jpg?x-oss-process=style/yasuo", "http://color-test.oss-cn-qingdao.aliyuncs.com/dyc/img/2019/01/28/15486392177481726898108.jpg?x-oss-process=style/yasuo", "http://color-test.oss-cn-qingdao.aliyuncs.com/dyc/img/2019/01/28/15486392177473938812.jpg?x-oss-process=style/yasuo", "http://color-test.oss-cn-qingdao.aliyuncs.com/dyc/img/2019/01/28/15486392177582114379277.jpg?x-oss-process=style/yasuo", "http://color-test.oss-cn-qingdao.aliyuncs.com/dyc/img/2019/01/28/15486392177631301168776.jpg?x-oss-process=style/yasuo" ], "create_type": "邮箱注册", "create_time": "2019-02-13 9:52:00", "status": 1 }, { "id": 12006, "username": "红尘几度欢颜笑", "avatar": "https://color-test.oss-cn-qingdao.aliyuncs.com/dyc/img/default_head/7.png?x-oss-process=style/yasuo", "tell": '人懒,啥也没留', "sex": "女", "photo_list": [ "http://color-test.oss-cn-qingdao.aliyuncs.com/dyc/img/2019/01/28/15486396582311677880214.jpg?x-oss-process=style/yasuo", "http://color-test.oss-cn-qingdao.aliyuncs.com/dyc/img/2019/01/28/15486396582112088482959.jpg?x-oss-process=style/yasuo", "http://color-test.oss-cn-qingdao.aliyuncs.com/dyc/img/2019/01/28/15486396582201751882045.jpg?x-oss-process=style/yasuo", "http://color-test.oss-cn-qingdao.aliyuncs.com/dyc/img/2019/01/28/1548639658226225134395.jpg?x-oss-process=style/yasuo", "http://color-test.oss-cn-qingdao.aliyuncs.com/dyc/img/2019/01/28/15486396582351948796029.jpg?x-oss-process=style/yasuo", "http://color-test.oss-cn-qingdao.aliyuncs.com/dyc/img/2019/01/28/1548639658257423792653.jpg?x-oss-process=style/yasuo", "http://color-test.oss-cn-qingdao.aliyuncs.com/dyc/img/2019/01/28/1548639658260413362409.jpg?x-oss-process=style/yasuo", "http://color-test.oss-cn-qingdao.aliyuncs.com/dyc/img/2019/01/28/15486396582701933849474.jpg?x-oss-process=style/yasuo" ], "create_type": "邮箱注册", "create_time": "2019-03-13 20:12:54", "status": 1 }, { "id": 12007, "username": "许你春秋", "avatar": "https://color-test.oss-cn-qingdao.aliyuncs.com/dyc/img/default_head/8.png?x-oss-process=style/yasuo", "tell": '人懒,啥也没留', "sex": "女", "photo_list": [ "http://color-test.oss-cn-qingdao.aliyuncs.com/dyc/img/2019/01/28/1548638841214290095149.jpg?x-oss-process=style/yasuo", "http://color-test.oss-cn-qingdao.aliyuncs.com/dyc/img/2019/01/28/1548638841227809145772.jpg?x-oss-process=style/yasuo", "http://color-test.oss-cn-qingdao.aliyuncs.com/dyc/img/2019/01/28/1548638841240270928767.jpg?x-oss-process=style/yasuo", "http://color-test.oss-cn-qingdao.aliyuncs.com/dyc/img/2019/01/28/1548638841244906005971.jpg?x-oss-process=style/yasuo", "http://color-test.oss-cn-qingdao.aliyuncs.com/dyc/img/2019/01/28/154863884124713283459.jpg?x-oss-process=style/yasuo" ], "create_type": "邮箱注册", "create_time": "2019-03-16 20:22:00", "status": 1 }, { "id": 12008, "username": "李灵涵", "avatar": "https://color-test.oss-cn-qingdao.aliyuncs.com/dyc/img/default_head/9.png?x-oss-process=style/yasuo", "tell": '人懒,啥也没留', "sex": "女", "photo_list": [ "http://color-test.oss-cn-qingdao.aliyuncs.com/dyc/img/2019/01/28/15486374854182024752471.jpg?x-oss-process=style/yasuo", "http://color-test.oss-cn-qingdao.aliyuncs.com/dyc/img/2019/01/28/1548637485458718538949.jpg?x-oss-process=style/yasuo", "http://color-test.oss-cn-qingdao.aliyuncs.com/dyc/img/2019/01/28/1548637485455211731533.jpg?x-oss-process=style/yasuo", "http://color-test.oss-cn-qingdao.aliyuncs.com/dyc/img/2019/01/28/1548637485460724239093.jpg?x-oss-process=style/yasuo", "http://color-test.oss-cn-qingdao.aliyuncs.com/dyc/img/2019/01/28/15486374854672002390350.jpg?x-oss-process=style/yasuo", "http://color-test.oss-cn-qingdao.aliyuncs.com/dyc/img/2019/01/28/1548637485473210846647.jpg?x-oss-process=style/yasuo", "http://color-test.oss-cn-qingdao.aliyuncs.com/dyc/img/2019/01/28/1548637485471190844084.jpg?x-oss-process=style/yasuo" ], "create_type": "邮箱注册", "create_time": "2019-03-18 20:22:00", "status": 1 }, { "id": 12009, "username": "樱桃", "avatar": "https://color-test.oss-cn-qingdao.aliyuncs.com/dyc/img/default_head/10.png?x-oss-process=style/yasuo", "tell": '人懒,啥也没留', "sex": "女", "photo_list": [ "http://color-test.oss-cn-qingdao.aliyuncs.com/dyc/img/2019/01/28/1548637231837487154029.jpg?x-oss-process=style/yasuo", "http://color-test.oss-cn-qingdao.aliyuncs.com/dyc/img/2019/01/28/15486372318271509628451.jpg?x-oss-process=style/yasuo", "http://color-test.oss-cn-qingdao.aliyuncs.com/dyc/img/2019/01/28/1548637231848392706841.jpg?x-oss-process=style/yasuo", "http://color-test.oss-cn-qingdao.aliyuncs.com/dyc/img/2019/01/28/1548637231857929283080.jpg?x-oss-process=style/yasuo", "http://color-test.oss-cn-qingdao.aliyuncs.com/dyc/img/2019/01/28/1548637231873648635582.jpg?x-oss-process=style/yasuo" ], "create_type": "邮箱注册", "create_time": "2019-03-22 20:22:00", "status": 2 }, { "id": 12010, "username": "碘盐", "avatar": "https://color-test.oss-cn-qingdao.aliyuncs.com/dyc/img/default_head/1.png?x-oss-process=style/yasuo", "tell": '人懒,啥也没留', "sex": "女", "photo_list": [ "http://color-test.oss-cn-qingdao.aliyuncs.com/dyc/img/2019/01/28/1548635034223276859883.jpg?x-oss-process=style/yasuo" ], "create_type": "手机号呢注册", "create_time": "2019-03-22 20:33:00", "status": 2 }, ], dataCount: 3306 } ================================================ FILE: sa-view/user/user-add.html ================================================ 用户添加 ================================================ FILE: sa-view/user/user-chart.html ================================================ 用户注册统计 ================================================ FILE: sa-view/user/user-list.html ================================================ 用户列表 ================================================ FILE: static/kj/element-ui/index.js ================================================ !function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t(require("vue")):"function"==typeof define&&define.amd?define("ELEMENT",["vue"],t):"object"==typeof exports?exports.ELEMENT=t(require("vue")):e.ELEMENT=t(e.Vue)}("undefined"!=typeof self?self:this,function(e){return function(e){var t={};function i(n){if(t[n])return t[n].exports;var r=t[n]={i:n,l:!1,exports:{}};return e[n].call(r.exports,r,r.exports,i),r.l=!0,r.exports}return i.m=e,i.c=t,i.d=function(e,t,n){i.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},i.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},i.t=function(e,t){if(1&t&&(e=i(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(i.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var r in e)i.d(n,r,function(t){return e[t]}.bind(null,r));return n},i.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return i.d(t,"a",t),t},i.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},i.p="/dist/",i(i.s=49)}([function(t,i){t.exports=e},function(e,t,i){var n=i(4);e.exports=function(e,t,i){return void 0===i?n(e,t,!1):n(e,i,!1!==t)}},function(e,t,i){var n;!function(r){"use strict";var s={},a=/d{1,4}|M{1,4}|yy(?:yy)?|S{1,3}|Do|ZZ|([HhMsDm])\1?|[aA]|"[^"]*"|'[^']*'/g,o="[^\\s]+",l=/\[([^]*?)\]/gm,u=function(){};function c(e,t){for(var i=[],n=0,r=e.length;n3?0:(e-e%10!=10)*e%10]}};var g={D:function(e){return e.getDay()},DD:function(e){return d(e.getDay())},Do:function(e,t){return t.DoFn(e.getDate())},d:function(e){return e.getDate()},dd:function(e){return d(e.getDate())},ddd:function(e,t){return t.dayNamesShort[e.getDay()]},dddd:function(e,t){return t.dayNames[e.getDay()]},M:function(e){return e.getMonth()+1},MM:function(e){return d(e.getMonth()+1)},MMM:function(e,t){return t.monthNamesShort[e.getMonth()]},MMMM:function(e,t){return t.monthNames[e.getMonth()]},yy:function(e){return d(String(e.getFullYear()),4).substr(2)},yyyy:function(e){return d(e.getFullYear(),4)},h:function(e){return e.getHours()%12||12},hh:function(e){return d(e.getHours()%12||12)},H:function(e){return e.getHours()},HH:function(e){return d(e.getHours())},m:function(e){return e.getMinutes()},mm:function(e){return d(e.getMinutes())},s:function(e){return e.getSeconds()},ss:function(e){return d(e.getSeconds())},S:function(e){return Math.round(e.getMilliseconds()/100)},SS:function(e){return d(Math.round(e.getMilliseconds()/10),2)},SSS:function(e){return d(e.getMilliseconds(),3)},a:function(e,t){return e.getHours()<12?t.amPm[0]:t.amPm[1]},A:function(e,t){return e.getHours()<12?t.amPm[0].toUpperCase():t.amPm[1].toUpperCase()},ZZ:function(e){var t=e.getTimezoneOffset();return(t>0?"-":"+")+d(100*Math.floor(Math.abs(t)/60)+Math.abs(t)%60,4)}},b={d:["\\d\\d?",function(e,t){e.day=t}],Do:["\\d\\d?"+o,function(e,t){e.day=parseInt(t,10)}],M:["\\d\\d?",function(e,t){e.month=t-1}],yy:["\\d\\d?",function(e,t){var i=+(""+(new Date).getFullYear()).substr(0,2);e.year=""+(t>68?i-1:i)+t}],h:["\\d\\d?",function(e,t){e.hour=t}],m:["\\d\\d?",function(e,t){e.minute=t}],s:["\\d\\d?",function(e,t){e.second=t}],yyyy:["\\d{4}",function(e,t){e.year=t}],S:["\\d",function(e,t){e.millisecond=100*t}],SS:["\\d{2}",function(e,t){e.millisecond=10*t}],SSS:["\\d{3}",function(e,t){e.millisecond=t}],D:["\\d\\d?",u],ddd:[o,u],MMM:[o,h("monthNamesShort")],MMMM:[o,h("monthNames")],a:[o,function(e,t,i){var n=t.toLowerCase();n===i.amPm[0]?e.isPm=!1:n===i.amPm[1]&&(e.isPm=!0)}],ZZ:["[^\\s]*?[\\+\\-]\\d\\d:?\\d\\d|[^\\s]*?Z",function(e,t){var i,n=(t+"").match(/([+-]|\d\d)/gi);n&&(i=60*n[1]+parseInt(n[2],10),e.timezoneOffset="+"===n[0]?i:-i)}]};b.dd=b.d,b.dddd=b.ddd,b.DD=b.D,b.mm=b.m,b.hh=b.H=b.HH=b.h,b.MM=b.M,b.ss=b.s,b.A=b.a,s.masks={default:"ddd MMM dd yyyy HH:mm:ss",shortDate:"M/D/yy",mediumDate:"MMM d, yyyy",longDate:"MMMM d, yyyy",fullDate:"dddd, MMMM d, yyyy",shortTime:"HH:mm",mediumTime:"HH:mm:ss",longTime:"HH:mm:ss.SSS"},s.format=function(e,t,i){var n=i||s.i18n;if("number"==typeof e&&(e=new Date(e)),"[object Date]"!==Object.prototype.toString.call(e)||isNaN(e.getTime()))throw new Error("Invalid Date in fecha.format");t=s.masks[t]||t||s.masks.default;var r=[];return(t=(t=t.replace(l,function(e,t){return r.push(t),"@@@"})).replace(a,function(t){return t in g?g[t](e,n):t.slice(1,t.length-1)})).replace(/@@@/g,function(){return r.shift()})},s.parse=function(e,t,i){var n=i||s.i18n;if("string"!=typeof t)throw new Error("Invalid format in fecha.parse");if(t=s.masks[t]||t,e.length>1e3)return null;var r={},o=[],u=[];t=t.replace(l,function(e,t){return u.push(t),"@@@"});var c,h=(c=t,c.replace(/[|\\{()[^$+*?.-]/g,"\\$&")).replace(a,function(e){if(b[e]){var t=b[e];return o.push(t[1]),"("+t[0]+")"}return e});h=h.replace(/@@@/g,function(){return u.shift()});var d=e.match(new RegExp(h,"i"));if(!d)return null;for(var p=1;pe?u():!0!==t&&(r=setTimeout(n?function(){r=void 0}:u,void 0===n?e-o:e))}}},function(e,t){var i=e.exports="undefined"!=typeof window&&window.Math==Math?window:"undefined"!=typeof self&&self.Math==Math?self:Function("return this")();"number"==typeof __g&&(__g=i)},function(e,t){var i=/^(attrs|props|on|nativeOn|class|style|hook)$/;function n(e,t){return function(){e&&e.apply(this,arguments),t&&t.apply(this,arguments)}}e.exports=function(e){return e.reduce(function(e,t){var r,s,a,o,l;for(a in t)if(r=e[a],s=t[a],r&&i.test(a))if("class"===a&&("string"==typeof r&&(l=r,e[a]=r={},r[l]=!0),"string"==typeof s&&(l=s,t[a]=s={},s[l]=!0)),"on"===a||"nativeOn"===a||"hook"===a)for(o in s)r[o]=n(r[o],s[o]);else if(Array.isArray(r))e[a]=r.concat(s);else if(Array.isArray(s))e[a]=[r].concat(s);else for(o in s)r[o]=s[o];else e[a]=t[a];return e},{})}},function(e,t){var i={}.hasOwnProperty;e.exports=function(e,t){return i.call(e,t)}},function(e,t,i){"use strict";t.__esModule=!0;var n,r=i(56),s=(n=r)&&n.__esModule?n:{default:n};t.default=s.default||function(e){for(var t=1;t0?n:i)(e)}},function(e,t,i){var n=i(28)("keys"),r=i(21);e.exports=function(e){return n[e]||(n[e]=r(e))}},function(e,t,i){var n=i(14),r=i(5),s=r["__core-js_shared__"]||(r["__core-js_shared__"]={});(e.exports=function(e,t){return s[e]||(s[e]=void 0!==t?t:{})})("versions",[]).push({version:n.version,mode:i(20)?"pure":"global",copyright:"© 2019 Denis Pushkarev (zloirock.ru)"})},function(e,t){e.exports="constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf".split(",")},function(e,t){t.f=Object.getOwnPropertySymbols},function(e,t){e.exports={}},function(e,t,i){var n=i(10).f,r=i(7),s=i(13)("toStringTag");e.exports=function(e,t,i){e&&!r(e=i?e:e.prototype,s)&&n(e,s,{configurable:!0,value:t})}},function(e,t,i){t.f=i(13)},function(e,t,i){var n=i(5),r=i(14),s=i(20),a=i(33),o=i(10).f;e.exports=function(e){var t=r.Symbol||(r.Symbol=s?{}:n.Symbol||{});"_"==e.charAt(0)||e in t||o(t,e,{value:a.f(e)})}},function(e,t,i){var n=i(4),r=i(1);e.exports={throttle:n,debounce:r}},function(e,t,i){e.exports=!i(11)&&!i(16)(function(){return 7!=Object.defineProperty(i(37)("div"),"a",{get:function(){return 7}}).a})},function(e,t,i){var n=i(15),r=i(5).document,s=n(r)&&n(r.createElement);e.exports=function(e){return s?r.createElement(e):{}}},function(e,t,i){var n=i(7),r=i(12),s=i(62)(!1),a=i(27)("IE_PROTO");e.exports=function(e,t){var i,o=r(e),l=0,u=[];for(i in o)i!=a&&n(o,i)&&u.push(i);for(;t.length>l;)n(o,i=t[l++])&&(~s(u,i)||u.push(i));return u}},function(e,t,i){var n=i(40);e.exports=Object("z").propertyIsEnumerable(0)?Object:function(e){return"String"==n(e)?e.split(""):Object(e)}},function(e,t){var i={}.toString;e.exports=function(e){return i.call(e).slice(8,-1)}},function(e,t,i){var n=i(25);e.exports=function(e){return Object(n(e))}},function(e,t,i){"use strict";var n=i(20),r=i(23),s=i(43),a=i(9),o=i(31),l=i(69),u=i(32),c=i(72),h=i(13)("iterator"),d=!([].keys&&"next"in[].keys()),p=function(){return this};e.exports=function(e,t,i,f,m,v,g){l(i,t,f);var b,y,w,_=function(e){if(!d&&e in S)return S[e];switch(e){case"keys":case"values":return function(){return new i(this,e)}}return function(){return new i(this,e)}},x=t+" Iterator",C="values"==m,k=!1,S=e.prototype,D=S[h]||S["@@iterator"]||m&&S[m],$=D||_(m),E=m?C?_("entries"):$:void 0,T="Array"==t&&S.entries||D;if(T&&(w=c(T.call(new e)))!==Object.prototype&&w.next&&(u(w,x,!0),n||"function"==typeof w[h]||a(w,h,p)),C&&D&&"values"!==D.name&&(k=!0,$=function(){return D.call(this)}),n&&!g||!d&&!k&&S[h]||a(S,h,$),o[t]=$,o[x]=p,m)if(b={values:C?$:_("values"),keys:v?$:_("keys"),entries:E},g)for(y in b)y in S||s(S,y,b[y]);else r(r.P+r.F*(d||k),t,b);return b}},function(e,t,i){e.exports=i(9)},function(e,t,i){var n=i(17),r=i(70),s=i(29),a=i(27)("IE_PROTO"),o=function(){},l=function(){var e,t=i(37)("iframe"),n=s.length;for(t.style.display="none",i(71).appendChild(t),t.src="javascript:",(e=t.contentWindow.document).open(),e.write("