├── .gitignore ├── LICENSE ├── README.md ├── app.js ├── assets ├── css │ └── framework-ui.css ├── images │ ├── 404.png │ ├── default_photo.png │ ├── loading.gif │ ├── login_info.png │ ├── shards-logo.ico │ └── shards-logo.svg ├── js │ └── framework-ui.js └── libs │ ├── animate │ └── animate.css │ ├── bootstrap-table │ ├── bootstrap-table.css │ ├── bootstrap-table.js │ ├── extensions │ │ ├── accent-neutralise │ │ │ ├── bootstrap-table-accent-neutralise.js │ │ │ └── bootstrap-table-accent-neutralise.min.js │ │ ├── addrbar │ │ │ ├── bootstrap-table-addrbar.js │ │ │ └── bootstrap-table-addrbar.min.js │ │ ├── auto-refresh │ │ │ ├── bootstrap-table-auto-refresh.js │ │ │ └── bootstrap-table-auto-refresh.min.js │ │ ├── cell-input │ │ │ ├── bootstrap-table-cell-input.css │ │ │ ├── bootstrap-table-cell-input.js │ │ │ ├── bootstrap-table-cell-input.min.css │ │ │ └── bootstrap-table-cell-input.min.js │ │ ├── cookie │ │ │ ├── bootstrap-table-cookie.js │ │ │ └── bootstrap-table-cookie.min.js │ │ ├── copy-rows │ │ │ ├── bootstrap-table-copy-rows.js │ │ │ └── bootstrap-table-copy-rows.min.js │ │ ├── defer-url │ │ │ ├── bootstrap-table-defer-url.js │ │ │ └── bootstrap-table-defer-url.min.js │ │ ├── editable │ │ │ ├── bootstrap-table-editable.js │ │ │ └── bootstrap-table-editable.min.js │ │ ├── export │ │ │ ├── bootstrap-table-export.js │ │ │ └── bootstrap-table-export.min.js │ │ ├── filter-control │ │ │ ├── bootstrap-table-filter-control.css │ │ │ ├── bootstrap-table-filter-control.js │ │ │ ├── bootstrap-table-filter-control.min.css │ │ │ └── bootstrap-table-filter-control.min.js │ │ ├── fixed-columns │ │ │ ├── bootstrap-table-fixed-columns.css │ │ │ ├── bootstrap-table-fixed-columns.js │ │ │ ├── bootstrap-table-fixed-columns.min.css │ │ │ └── bootstrap-table-fixed-columns.min.js │ │ ├── group-by-v2 │ │ │ ├── bootstrap-table-group-by.css │ │ │ ├── bootstrap-table-group-by.js │ │ │ ├── bootstrap-table-group-by.min.css │ │ │ └── bootstrap-table-group-by.min.js │ │ ├── i18n-enhance │ │ │ ├── bootstrap-table-i18n-enhance.js │ │ │ └── bootstrap-table-i18n-enhance.min.js │ │ ├── key-events │ │ │ ├── bootstrap-table-key-events.js │ │ │ └── bootstrap-table-key-events.min.js │ │ ├── mobile │ │ │ ├── bootstrap-table-mobile.js │ │ │ └── bootstrap-table-mobile.min.js │ │ ├── multiple-sort │ │ │ ├── bootstrap-table-multiple-sort.js │ │ │ └── bootstrap-table-multiple-sort.min.js │ │ ├── natural-sorting │ │ │ ├── bootstrap-table-natural-sorting.js │ │ │ └── bootstrap-table-natural-sorting.min.js │ │ ├── page-jump-to │ │ │ ├── bootstrap-table-page-jump-to.css │ │ │ ├── bootstrap-table-page-jump-to.js │ │ │ ├── bootstrap-table-page-jump-to.min.css │ │ │ └── bootstrap-table-page-jump-to.min.js │ │ ├── pipeline │ │ │ ├── bootstrap-table-pipeline.js │ │ │ └── bootstrap-table-pipeline.min.js │ │ ├── print │ │ │ ├── bootstrap-table-print.js │ │ │ └── bootstrap-table-print.min.js │ │ ├── reorder-columns │ │ │ ├── bootstrap-table-reorder-columns.js │ │ │ └── bootstrap-table-reorder-columns.min.js │ │ ├── reorder-rows │ │ │ ├── bootstrap-table-reorder-rows.css │ │ │ ├── bootstrap-table-reorder-rows.js │ │ │ ├── bootstrap-table-reorder-rows.min.css │ │ │ └── bootstrap-table-reorder-rows.min.js │ │ ├── resizable │ │ │ ├── bootstrap-table-resizable.js │ │ │ └── bootstrap-table-resizable.min.js │ │ ├── sticky-header │ │ │ ├── bootstrap-table-sticky-header.css │ │ │ ├── bootstrap-table-sticky-header.js │ │ │ ├── bootstrap-table-sticky-header.min.css │ │ │ └── bootstrap-table-sticky-header.min.js │ │ ├── toolbar │ │ │ ├── bootstrap-table-toolbar.js │ │ │ └── bootstrap-table-toolbar.min.js │ │ └── treegrid │ │ │ ├── bootstrap-table-treegrid.js │ │ │ └── bootstrap-table-treegrid.min.js │ ├── locale │ │ └── bootstrap-table-zh-CN.js │ └── themes │ │ ├── bulma │ │ ├── bootstrap-table-bulma.css │ │ └── bootstrap-table-bulma.js │ │ └── materialize │ │ ├── bootstrap-table-materialize.css │ │ └── bootstrap-table-materialize.js │ ├── bootstrap │ ├── css │ │ └── bootstrap.css │ └── js │ │ └── bootstrap.js │ ├── fSelect │ ├── README.md │ ├── fSelect.css │ ├── fSelect.js │ └── test.html │ ├── font-awesome │ ├── css │ │ ├── fontawesome-all.css │ │ ├── fontawesome-all.min.css │ │ ├── fontawesome.css │ │ └── fontawesome.min.css │ └── webfonts │ │ ├── fa-brands-400.eot │ │ ├── fa-brands-400.svg │ │ ├── fa-brands-400.ttf │ │ ├── fa-brands-400.woff │ │ ├── fa-brands-400.woff2 │ │ ├── fa-regular-400.eot │ │ ├── fa-regular-400.svg │ │ ├── fa-regular-400.ttf │ │ ├── fa-regular-400.woff │ │ ├── fa-regular-400.woff2 │ │ ├── fa-solid-900.eot │ │ ├── fa-solid-900.svg │ │ ├── fa-solid-900.ttf │ │ ├── fa-solid-900.woff │ │ └── fa-solid-900.woff2 │ ├── jquery-slimScroll │ └── jquery.slimscroll.js │ ├── jquery-treegrid │ ├── css │ │ └── jquery.treegrid.css │ ├── img │ │ ├── collapse.png │ │ ├── expand.png │ │ ├── file.png │ │ └── folder.png │ └── js │ │ └── jquery.treegrid.js │ ├── jquery-validate │ └── jquery.validate.js │ ├── jquery │ └── jquery.js │ ├── layer │ ├── images │ │ ├── icon-ext.png │ │ ├── icon.png │ │ ├── loading-0.gif │ │ ├── loading-1.gif │ │ ├── loading-2.gif │ │ └── loading-3.gif │ ├── layer.css │ └── layer.js │ ├── metisMenu │ └── jquery.metisMenu.js │ ├── moment │ ├── moment.js │ └── zh-cn.js │ ├── pace │ └── pace.js │ ├── popper │ └── popper.js │ ├── select2 │ ├── select2.css │ ├── select2.js │ └── zh-CN.js │ └── zTree │ ├── css │ └── zTreeStyle │ │ ├── img │ │ ├── diy │ │ │ ├── 1_close.png │ │ │ ├── 1_open.png │ │ │ ├── 2.png │ │ │ ├── 3.png │ │ │ ├── 4.png │ │ │ ├── 5.png │ │ │ ├── 6.png │ │ │ ├── 7.png │ │ │ ├── 8.png │ │ │ └── 9.png │ │ ├── line_conn.gif │ │ ├── loading.gif │ │ ├── zTreeStandard.gif │ │ └── zTreeStandard.png │ │ └── zTreeStyle.css │ └── js │ ├── jquery.ztree.all.js │ ├── jquery.ztree.core.js │ ├── jquery.ztree.excheck.js │ ├── jquery.ztree.exedit.js │ └── jquery.ztree.exhide.js ├── common ├── logger.js └── tool.js ├── config.default.js ├── controller ├── login.js ├── main.js └── system.js ├── dbsync.js ├── middleware ├── auth.js └── requestLog.js ├── models ├── branch.js ├── index.js ├── menu.js ├── position.js ├── sql │ └── express_admin_init.sql └── user.js ├── package.json ├── router.js └── views ├── 404.ejs ├── _partial ├── header.ejs └── sidebar.ejs ├── layout-form.ejs ├── layout-main.ejs ├── layout-nologin.ejs ├── login.ejs ├── main └── index.ejs └── system ├── branch-edit.ejs ├── branch-list.ejs ├── menu-edit.ejs ├── menu-list.ejs ├── position-edit.ejs ├── position-list.ejs ├── user-edit.ejs └── user-list.ejs /.gitignore: -------------------------------------------------------------------------------- 1 | logs/ 2 | *.log 3 | *.log* 4 | 5 | *.lock 6 | *.lock.json 7 | *.lock.* 8 | *-lock.* 9 | 10 | node_modules 11 | 12 | .DS_Store 13 | .idea 14 | .classpath 15 | .project 16 | .settings 17 | Thumbs.db 18 | .ntvs_analysis.dat 19 | dist 20 | build 21 | .sass-cache/ 22 | 23 | nginx/ 24 | upload/* 25 | tmp/* 26 | config.js 27 | !.gitkeep 28 | .vscode/launch.json 29 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 ciey 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | Node.js 7 |

8 | 9 | [![node version](https://img.shields.io/badge/node.js-%3E=_8.0.0-green.svg)](http://nodejs.org/download/) 10 | [![express](https://img.shields.io/badge/express-%5E4.17.1-green.svg)](https://expressjs.com) 11 | [![mysql](https://img.shields.io/badge/mysql-%5E2.17.1-green.svg)](https://github.com/mysqljs/mysql) 12 | 13 | ### 介绍 14 | NodeExpressAdmin为后台权限管理系统 15 | 16 | [node后台权限管理系统(1)—权限设计](https://github.com/ciey/NodeExpressAdmin/issues/1) 17 | 18 | [node后台权限管理(2)—界面设计及实现](https://github.com/ciey/NodeExpressAdmin/issues/2) 19 | 20 | [node后台权限管理(3)—异常处理](https://github.com/ciey/NodeExpressAdmin/issues/3) 21 | 22 | ### 技术栈 23 | Framework: Express 24 | 25 | db: mysql 26 | 27 | ORM: sequelize 28 | 29 | Cache: redis 30 | 31 | ECMAScript: ES6 32 | 33 | ### 项目运行 34 | 35 | 环境: 36 | - node >=8, 推荐LTS 10+ 37 | - mysql >= 5.6 38 | - redis 39 | 40 | ``` 41 | //copy config.js,config.js为本地配置文件,加入了gitignore 42 | $ cp config.default.js config.js 43 | 44 | $ npm install 45 | 46 | //mysql中手动建数据库,执行以下命令同步表 47 | $ node dbsync 48 | 49 | // models/sql/express_admin_init.sql 执行并初始化数据 50 | // 默认初设账户admin/admin, test/test 51 | $ npm start 52 | 53 | ``` 54 | 55 | ### 项目布局 56 | 57 | ``` 58 | . 59 | ├── assets 静态资源目录 60 | │ ├── css 自定义css 61 | │ ├── images 自定义图片 62 | │ ├── js 自定义js 63 | │ └── libs 第三方资源库 64 | ├── common 公共组件 65 | │ ├── logger.js 日志 66 | │ └── xxx.js 其他(后续增加) 67 | ├── controller 控制器 68 | │ ├── login.js 登录控制器 69 | │ ├── system.js 系统控制器 70 | │ ├── xxxx.js 其他(后续增加) 71 | ├── logs 日志文件 72 | ├── middleware 中间件 73 | │ ├── auth.js 权限验证 74 | │ └── xxxx.js 其他(后续增加) 75 | ├── models 模型(数据库) 76 | │ ├── index.js db配置及加载模型 77 | │ └── user.js 用户模型 78 | ├── upload 上传文件夹 79 | │ └── xxxx.png 80 | ├── views 视图 81 | ├── app.js 启动文件 82 | ├── config.default.js 默认配置 83 | ├── config.js 加载实际配置(本地) 84 | ├── dbsync.js 数据同步 85 | ├── package.json 配置文件 86 | ├── README.md 项目说明 87 | └── router.js 路由表 88 | 89 | ``` 90 | -------------------------------------------------------------------------------- /app.js: -------------------------------------------------------------------------------- 1 | /**************************************************************************************** 2 | * app.js 3 | * Node.js >= 8.0.0 4 | * database : mysql, redis 5 | * server : ubuntu 16.04 / nginx 6 | ***************************************************************************************/ 7 | 'use strict'; 8 | const _ = require('lodash'); 9 | const path = require('path'); 10 | const config = require('./config'); 11 | const express = require('express'); 12 | require('express-async-errors'); 13 | const session = require('express-session'); 14 | const redisStore = require('connect-redis')(session); 15 | const cookieParser = require('cookie-parser'); 16 | const compression = require('compression'); 17 | const bodyParser = require('body-parser'); 18 | const moment = require('moment'); 19 | const logger = require('./common/logger'); 20 | const requestLog = require('./middleware/requestLog'); 21 | const router = require('./router'); 22 | 23 | const app = express(); 24 | // view engine setup 25 | app.engine('ejs', require('ejs-mate')); 26 | app.set('views', path.join(__dirname, 'views')); 27 | app.set('view engine', 'ejs'); 28 | 29 | // server static files 30 | app.use('/assets', express.static(path.join(__dirname, 'assets'))); 31 | app.use('/upload/public', express.static(path.join(__dirname, 'upload/public'))); 32 | // log4js 33 | app.use(require('log4js').connectLogger(logger, { level: config.debug ? 'DEBUG' : 'ERROR' })); 34 | 35 | // Request logger 36 | app.use(requestLog); 37 | 38 | // parser 39 | app.use(bodyParser.json()); 40 | app.use(bodyParser.urlencoded({ extended: false })); 41 | app.use(cookieParser()); 42 | 43 | app.use(compression()); 44 | 45 | // session support redis store 46 | app.use(session({ 47 | store: new redisStore(config.redis), 48 | resave: true, 49 | saveUninitialized: false, 50 | secret: config.session_secret 51 | })); 52 | 53 | // locals 54 | app.use((req, res, next) => { 55 | res.locals.user = req.session.user; 56 | res.locals.moment = moment; 57 | res.locals.site = config.site; 58 | next(); 59 | }); 60 | 61 | // routes 62 | app.use('/', router); 63 | 64 | // error handle 65 | app.use((err, req, res, next) => { 66 | logger.error(err.message, err); 67 | if (req.xhr) { 68 | return res.json({ 69 | state: false, 70 | msg: err.message 71 | }); 72 | } 73 | //return res.send(err.message); 74 | next(err); 75 | }); 76 | 77 | app.listen(config.port,() => { 78 | logger.info('server listening on port:' + config.port); 79 | }) -------------------------------------------------------------------------------- /assets/images/404.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciey/NodeExpressAdmin/58bcc1941e803675e5b0a576a615b9f68d5586b7/assets/images/404.png -------------------------------------------------------------------------------- /assets/images/default_photo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciey/NodeExpressAdmin/58bcc1941e803675e5b0a576a615b9f68d5586b7/assets/images/default_photo.png -------------------------------------------------------------------------------- /assets/images/loading.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciey/NodeExpressAdmin/58bcc1941e803675e5b0a576a615b9f68d5586b7/assets/images/loading.gif -------------------------------------------------------------------------------- /assets/images/login_info.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciey/NodeExpressAdmin/58bcc1941e803675e5b0a576a615b9f68d5586b7/assets/images/login_info.png -------------------------------------------------------------------------------- /assets/images/shards-logo.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciey/NodeExpressAdmin/58bcc1941e803675e5b0a576a615b9f68d5586b7/assets/images/shards-logo.ico -------------------------------------------------------------------------------- /assets/images/shards-logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Logo Icon 5 | Created with Sketch. 6 | 7 | 8 | 9 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /assets/libs/bootstrap-table/bootstrap-table.css: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | /** 3 | * @author zhixin wen 4 | * version: 1.15.3 5 | * https://github.com/wenzhixin/bootstrap-table/ 6 | */ 7 | .bootstrap-table .fixed-table-toolbar::after { 8 | content: ""; 9 | display: block; 10 | clear: both; 11 | } 12 | .bootstrap-table .fixed-table-toolbar .bs-bars, 13 | .bootstrap-table .fixed-table-toolbar .search, 14 | .bootstrap-table .fixed-table-toolbar .columns { 15 | position: relative; 16 | margin-top: 10px; 17 | margin-bottom: 10px; 18 | } 19 | .bootstrap-table .fixed-table-toolbar .columns .btn-group > .btn-group { 20 | display: inline-block; 21 | margin-left: -1px !important; 22 | } 23 | .bootstrap-table .fixed-table-toolbar .columns .btn-group > .btn-group > .btn { 24 | border-radius: 0; 25 | } 26 | .bootstrap-table .fixed-table-toolbar .columns .btn-group > .btn-group:first-child > .btn { 27 | border-top-left-radius: 4px; 28 | border-bottom-left-radius: 4px; 29 | } 30 | .bootstrap-table .fixed-table-toolbar .columns .btn-group > .btn-group:last-child > .btn { 31 | border-top-right-radius: 4px; 32 | border-bottom-right-radius: 4px; 33 | } 34 | .bootstrap-table .fixed-table-toolbar .columns .dropdown-menu { 35 | text-align: left; 36 | max-height: 300px; 37 | overflow: auto; 38 | -ms-overflow-style: scrollbar; 39 | z-index: 1001; 40 | } 41 | .bootstrap-table .fixed-table-toolbar .columns label { 42 | display: block; 43 | padding: 3px 20px; 44 | clear: both; 45 | font-weight: normal; 46 | line-height: 1.428571429; 47 | } 48 | .bootstrap-table .fixed-table-toolbar .columns-left { 49 | margin-right: 5px; 50 | } 51 | .bootstrap-table .fixed-table-toolbar .columns-right { 52 | margin-left: 5px; 53 | } 54 | .bootstrap-table .fixed-table-toolbar .pull-right .dropdown-menu { 55 | right: 0; 56 | left: auto; 57 | } 58 | .bootstrap-table .fixed-table-container { 59 | position: relative; 60 | clear: both; 61 | } 62 | .bootstrap-table .fixed-table-container .table { 63 | width: 100%; 64 | margin-bottom: 0 !important; 65 | } 66 | .bootstrap-table .fixed-table-container .table th, 67 | .bootstrap-table .fixed-table-container .table td { 68 | vertical-align: middle; 69 | box-sizing: border-box; 70 | } 71 | .bootstrap-table .fixed-table-container .table thead th { 72 | vertical-align: bottom; 73 | padding: 0; 74 | margin: 0; 75 | } 76 | .bootstrap-table .fixed-table-container .table thead th:focus { 77 | outline: 0 solid transparent; 78 | } 79 | .bootstrap-table .fixed-table-container .table thead th.detail { 80 | width: 30px; 81 | } 82 | .bootstrap-table .fixed-table-container .table thead th .th-inner { 83 | padding: 0.75rem; 84 | vertical-align: bottom; 85 | overflow: hidden; 86 | text-overflow: ellipsis; 87 | white-space: nowrap; 88 | } 89 | .bootstrap-table .fixed-table-container .table thead th .sortable { 90 | cursor: pointer; 91 | background-position: right; 92 | background-repeat: no-repeat; 93 | padding-right: 30px; 94 | } 95 | .bootstrap-table .fixed-table-container .table thead th .both { 96 | background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAQAAADYWf5HAAAAkElEQVQoz7X QMQ5AQBCF4dWQSJxC5wwax1Cq1e7BAdxD5SL+Tq/QCM1oNiJidwox0355mXnG/DrEtIQ6azioNZQxI0ykPhTQIwhCR+BmBYtlK7kLJYwWCcJA9M4qdrZrd8pPjZWPtOqdRQy320YSV17OatFC4euts6z39GYMKRPCTKY9UnPQ6P+GtMRfGtPnBCiqhAeJPmkqAAAAAElFTkSuQmCC"); 97 | } 98 | .bootstrap-table .fixed-table-container .table thead th .asc { 99 | background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAYAAAByUDbMAAAAZ0lEQVQ4y2NgGLKgquEuFxBPAGI2ahhWCsS/gDibUoO0gPgxEP8H4ttArEyuQYxAPBdqEAxPBImTY5gjEL9DM+wTENuQahAvEO9DMwiGdwAxOymGJQLxTyD+jgWDxCMZRsEoGAVoAADeemwtPcZI2wAAAABJRU5ErkJggg=="); 100 | } 101 | .bootstrap-table .fixed-table-container .table thead th .desc { 102 | background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAYAAAByUDbMAAAAZUlEQVQ4y2NgGAWjYBSggaqGu5FA/BOIv2PBIPFEUgxjB+IdQPwfC94HxLykus4GiD+hGfQOiB3J8SojEE9EM2wuSJzcsFMG4ttQgx4DsRalkZENxL+AuJQaMcsGxBOAmGvopk8AVz1sLZgg0bsAAAAASUVORK5CYII= "); 103 | } 104 | .bootstrap-table .fixed-table-container .table tbody tr.selected td { 105 | background-color: rgba(0, 0, 0, 0.075); 106 | } 107 | .bootstrap-table .fixed-table-container .table tbody tr.no-records-found { 108 | text-align: center; 109 | } 110 | .bootstrap-table .fixed-table-container .table tbody tr .card-view { 111 | display: flex; 112 | } 113 | .bootstrap-table .fixed-table-container .table tbody tr .card-view .card-view-title { 114 | font-weight: bold; 115 | display: inline-block; 116 | min-width: 30%; 117 | text-align: left !important; 118 | } 119 | .bootstrap-table .fixed-table-container .table .bs-checkbox { 120 | text-align: center; 121 | } 122 | .bootstrap-table .fixed-table-container .table input[type=radio], 123 | .bootstrap-table .fixed-table-container .table input[type=checkbox] { 124 | margin: 0 auto !important; 125 | } 126 | .bootstrap-table .fixed-table-container .table.table-sm .th-inner { 127 | padding: 0.3rem; 128 | } 129 | .bootstrap-table .fixed-table-container.fixed-height:not(.has-footer) { 130 | border-bottom: 1px solid #dee2e6; 131 | } 132 | .bootstrap-table .fixed-table-container.fixed-height.has-card-view { 133 | border-top: 1px solid #dee2e6; 134 | border-bottom: 1px solid #dee2e6; 135 | } 136 | .bootstrap-table .fixed-table-container.fixed-height .fixed-table-border { 137 | border-left: 1px solid #dee2e6; 138 | border-right: 1px solid #dee2e6; 139 | } 140 | .bootstrap-table .fixed-table-container.fixed-height .table thead th { 141 | border-bottom: 1px solid #dee2e6; 142 | } 143 | .bootstrap-table .fixed-table-container.fixed-height .table-dark thead th { 144 | border-bottom: 1px solid #32383e; 145 | } 146 | .bootstrap-table .fixed-table-container .fixed-table-header { 147 | overflow: hidden; 148 | } 149 | .bootstrap-table .fixed-table-container .fixed-table-body { 150 | overflow-x: auto; 151 | overflow-y: auto; 152 | height: 100%; 153 | } 154 | .bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading { 155 | align-items: center; 156 | background: #fff; 157 | display: none; 158 | justify-content: center; 159 | position: absolute; 160 | bottom: 0; 161 | width: 100%; 162 | z-index: 1000; 163 | } 164 | .bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading .loading-wrap { 165 | align-items: baseline; 166 | display: flex; 167 | justify-content: center; 168 | } 169 | .bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading .loading-wrap .loading-text { 170 | font-size: 2rem; 171 | margin-right: 6px; 172 | } 173 | .bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading .loading-wrap .animation-wrap { 174 | align-items: center; 175 | display: flex; 176 | justify-content: center; 177 | } 178 | .bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading .loading-wrap .animation-dot, 179 | .bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading .loading-wrap .animation-wrap::after, 180 | .bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading .loading-wrap .animation-wrap::before { 181 | content: ""; 182 | animation-duration: 1.5s; 183 | animation-iteration-count: infinite; 184 | animation-name: LOADING; 185 | background: #212529; 186 | border-radius: 50%; 187 | display: block; 188 | height: 5px; 189 | margin: 0 4px; 190 | opacity: 0; 191 | width: 5px; 192 | } 193 | .bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading .loading-wrap .animation-dot { 194 | animation-delay: 0.3s; 195 | } 196 | .bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading .loading-wrap .animation-wrap::after { 197 | animation-delay: 0.6s; 198 | } 199 | .bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading.table-dark { 200 | background: #212529; 201 | } 202 | .bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading.table-dark .animation-dot, 203 | .bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading.table-dark .animation-wrap::after, 204 | .bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading.table-dark .animation-wrap::before { 205 | background: #fff; 206 | } 207 | .bootstrap-table .fixed-table-container .fixed-table-footer { 208 | overflow: hidden; 209 | } 210 | .bootstrap-table .fixed-table-pagination::after { 211 | content: ""; 212 | display: block; 213 | clear: both; 214 | } 215 | .bootstrap-table .fixed-table-pagination > .pagination-detail, 216 | .bootstrap-table .fixed-table-pagination > .pagination { 217 | margin-top: 10px; 218 | margin-bottom: 10px; 219 | } 220 | .bootstrap-table .fixed-table-pagination > .pagination-detail .pagination-info { 221 | line-height: 34px; 222 | margin-right: 5px; 223 | } 224 | .bootstrap-table .fixed-table-pagination > .pagination-detail .page-list { 225 | display: inline-block; 226 | } 227 | .bootstrap-table .fixed-table-pagination > .pagination-detail .page-list .btn-group { 228 | position: relative; 229 | display: inline-block; 230 | vertical-align: middle; 231 | } 232 | .bootstrap-table .fixed-table-pagination > .pagination-detail .page-list .btn-group .dropdown-menu { 233 | margin-bottom: 0; 234 | } 235 | .bootstrap-table .fixed-table-pagination > .pagination ul.pagination { 236 | margin: 0; 237 | } 238 | .bootstrap-table .fixed-table-pagination > .pagination ul.pagination a { 239 | padding: 6px 12px; 240 | line-height: 1.428571429; 241 | } 242 | .bootstrap-table .fixed-table-pagination > .pagination ul.pagination li.page-intermediate a { 243 | color: #c8c8c8; 244 | } 245 | .bootstrap-table .fixed-table-pagination > .pagination ul.pagination li.page-intermediate a::before { 246 | content: "⬅"; 247 | } 248 | .bootstrap-table .fixed-table-pagination > .pagination ul.pagination li.page-intermediate a::after { 249 | content: "➡"; 250 | } 251 | .bootstrap-table .fixed-table-pagination > .pagination ul.pagination li.disabled a { 252 | pointer-events: none; 253 | cursor: default; 254 | } 255 | .bootstrap-table.fullscreen { 256 | position: fixed; 257 | top: 0; 258 | left: 0; 259 | z-index: 1050; 260 | width: 100% !important; 261 | background: #fff; 262 | height: calc(100vh); 263 | overflow-y: scroll; 264 | } 265 | 266 | /* calculate scrollbar width */ 267 | div.fixed-table-scroll-inner { 268 | width: 100%; 269 | height: 200px; 270 | } 271 | 272 | div.fixed-table-scroll-outer { 273 | top: 0; 274 | left: 0; 275 | visibility: hidden; 276 | width: 200px; 277 | height: 150px; 278 | overflow: hidden; 279 | } 280 | 281 | @keyframes LOADING { 282 | 0% { 283 | opacity: 0; 284 | } 285 | 50% { 286 | opacity: 1; 287 | } 288 | to { 289 | opacity: 0; 290 | } 291 | } 292 | 293 | 294 | -------------------------------------------------------------------------------- /assets/libs/bootstrap-table/extensions/cell-input/bootstrap-table-cell-input.css: -------------------------------------------------------------------------------- 1 | .table-cell-input { 2 | display: block !important; 3 | padding: 5px !important; 4 | margin: 0 !important; 5 | border: 0 !important; 6 | width: 100% !important; 7 | box-sizing: border-box !important; 8 | -moz-box-sizing: border-box !important; 9 | border-radius: 0 !important; 10 | line-height: 1 !important; 11 | white-space: nowrap; 12 | } 13 | -------------------------------------------------------------------------------- /assets/libs/bootstrap-table/extensions/cell-input/bootstrap-table-cell-input.min.css: -------------------------------------------------------------------------------- 1 | /** 2 | * bootstrap-table - An extended table to integration with some of the most widely used CSS frameworks. (Supports Bootstrap, Semantic UI, Bulma, Material Design, Foundation) 3 | * 4 | * @version v1.15.3 5 | * @homepage https://bootstrap-table.com 6 | * @author wenzhixin (http://wenzhixin.net.cn/) 7 | * @license MIT 8 | */ 9 | 10 | .table-cell-input{display:block!important;padding:5px!important;margin:0!important;border:0!important;width:100%!important;box-sizing:border-box!important;-moz-box-sizing:border-box!important;border-radius:0!important;line-height:1!important;white-space:nowrap} -------------------------------------------------------------------------------- /assets/libs/bootstrap-table/extensions/defer-url/bootstrap-table-defer-url.min.js: -------------------------------------------------------------------------------- 1 | /** 2 | * bootstrap-table - An extended table to integration with some of the most widely used CSS frameworks. (Supports Bootstrap, Semantic UI, Bulma, Material Design, Foundation) 3 | * 4 | * @version v1.15.3 5 | * @homepage https://bootstrap-table.com 6 | * @author wenzhixin (http://wenzhixin.net.cn/) 7 | * @license MIT 8 | */ 9 | 10 | (function(a,b){"object"==typeof exports&&"undefined"!=typeof module?b(require("jquery")):"function"==typeof define&&define.amd?define(["jquery"],b):(a=a||self,b(a.jQuery))})(this,function(a){'use strict';var n=Math.min;function b(a,b){return b={exports:{}},a(b,b.exports),b.exports}function c(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}function d(a,b){for(var c,d=0;dc?xa(c+b,0):n(c,b)},za=function(a){return function(b,c,d){var e,f=H(b),g=wa(f.length),h=ya(d,g);if(a&&c!=c){for(;g>h;)if(e=f[h++],e!=e)return!0;}else for(;g>h;h++)if((a||h in f)&&f[h]===c)return a||h||0;return!a&&-1}},Aa={includes:za(!0),indexOf:za(!1)},Ba=Aa.indexOf,Ca=function(a,b){var c,d=H(a),e=0,f=[];for(c in d)!L(ha,c)&&L(d,c)&&f.push(c);for(;b.length>e;)L(d,c=b[e++])&&(~Ba(f,c)||f.push(c));return f},Da=["constructor","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","toLocaleString","toString","valueOf"].concat("length","prototype"),Ea=Object.getOwnPropertyNames||function(a){return Ca(a,Da)},Fa={f:Ea},Ga=Object.getOwnPropertySymbols,Ha={f:Ga},Ia=function(a,b){return 2>arguments.length?sa(ra[a])||sa(u[a]):ra[a]&&ra[a][b]||u[a]&&u[a][b]}("Reflect","ownKeys")||function(a){var b=Fa.f(U(a)),c=Ha.f;return c?b.concat(c(a)):b},Ja=function(a,b){for(var c,d=Ia(b),e=X.f,f=T.f,g=0;gab)throw TypeError(bb);for(b=0;b=ab)throw TypeError(bb);Ta(g,h++,e)}return g.length=h,g}}),a.extend(a.fn.bootstrapTable.defaults,{deferUrl:void 0}),a.BootstrapTable=function(a){function b(){return c(this,b),k(this,h(b).apply(this,arguments))}return g(b,a),e(b,[{key:"init",value:function(){for(var a,c=arguments.length,d=Array(c),e=0;e (http://wenzhixin.net.cn/) 7 | * @license MIT 8 | */ 9 | 10 | .no-filter-control{height:34px}.filter-control{margin:0 2px 2px 2px} -------------------------------------------------------------------------------- /assets/libs/bootstrap-table/extensions/fixed-columns/bootstrap-table-fixed-columns.css: -------------------------------------------------------------------------------- 1 | .fixed-table-header-columns, 2 | .fixed-table-body-columns { 3 | position: absolute; 4 | background-color: #fff; 5 | box-sizing: border-box; 6 | overflow: hidden; 7 | z-index: 1; 8 | } 9 | 10 | .fixed-table-header-columns { 11 | z-index: 2; 12 | } 13 | 14 | .fixed-table-header-columns .table, 15 | .fixed-table-body-columns .table { 16 | border-right: 1px solid #ddd; 17 | } 18 | 19 | .fixed-table-header-columns .table.table-no-bordered, 20 | .fixed-table-body-columns .table.table-no-bordered { 21 | border-right: 1px solid transparent; 22 | } 23 | 24 | .fixed-table-body-columns table { 25 | position: absolute; 26 | animation: none; 27 | } 28 | -------------------------------------------------------------------------------- /assets/libs/bootstrap-table/extensions/fixed-columns/bootstrap-table-fixed-columns.min.css: -------------------------------------------------------------------------------- 1 | /** 2 | * bootstrap-table - An extended table to integration with some of the most widely used CSS frameworks. (Supports Bootstrap, Semantic UI, Bulma, Material Design, Foundation) 3 | * 4 | * @version v1.15.3 5 | * @homepage https://bootstrap-table.com 6 | * @author wenzhixin (http://wenzhixin.net.cn/) 7 | * @license MIT 8 | */ 9 | 10 | .fixed-table-header-columns,.fixed-table-body-columns{position:absolute;background-color:#fff;box-sizing:border-box;overflow:hidden;z-index:1}.fixed-table-header-columns{z-index:2}.fixed-table-header-columns .table,.fixed-table-body-columns .table{border-right:1px solid #ddd}.fixed-table-header-columns .table.table-no-bordered,.fixed-table-body-columns .table.table-no-bordered{border-right:1px solid transparent}.fixed-table-body-columns table{position:absolute;animation:none} -------------------------------------------------------------------------------- /assets/libs/bootstrap-table/extensions/group-by-v2/bootstrap-table-group-by.css: -------------------------------------------------------------------------------- 1 | .bootstrap-table .table > tbody > tr.groupBy { 2 | cursor: pointer; 3 | } 4 | 5 | .bootstrap-table .table > tbody > tr.hidden + tr.detail-view { 6 | display: none; 7 | } 8 | -------------------------------------------------------------------------------- /assets/libs/bootstrap-table/extensions/group-by-v2/bootstrap-table-group-by.min.css: -------------------------------------------------------------------------------- 1 | /** 2 | * bootstrap-table - An extended table to integration with some of the most widely used CSS frameworks. (Supports Bootstrap, Semantic UI, Bulma, Material Design, Foundation) 3 | * 4 | * @version v1.15.3 5 | * @homepage https://bootstrap-table.com 6 | * @author wenzhixin (http://wenzhixin.net.cn/) 7 | * @license MIT 8 | */ 9 | 10 | .bootstrap-table .table>tbody>tr.groupBy{cursor:pointer}.bootstrap-table .table>tbody>tr.hidden+tr.detail-view{display:none} -------------------------------------------------------------------------------- /assets/libs/bootstrap-table/extensions/i18n-enhance/bootstrap-table-i18n-enhance.js: -------------------------------------------------------------------------------- 1 | (function (global, factory) { 2 | typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('jquery')) : 3 | typeof define === 'function' && define.amd ? define(['jquery'], factory) : 4 | (global = global || self, factory(global.jQuery)); 5 | }(this, function ($) { 'use strict'; 6 | 7 | $ = $ && $.hasOwnProperty('default') ? $['default'] : $; 8 | 9 | function _classCallCheck(instance, Constructor) { 10 | if (!(instance instanceof Constructor)) { 11 | throw new TypeError("Cannot call a class as a function"); 12 | } 13 | } 14 | 15 | function _defineProperties(target, props) { 16 | for (var i = 0; i < props.length; i++) { 17 | var descriptor = props[i]; 18 | descriptor.enumerable = descriptor.enumerable || false; 19 | descriptor.configurable = true; 20 | if ("value" in descriptor) descriptor.writable = true; 21 | Object.defineProperty(target, descriptor.key, descriptor); 22 | } 23 | } 24 | 25 | function _createClass(Constructor, protoProps, staticProps) { 26 | if (protoProps) _defineProperties(Constructor.prototype, protoProps); 27 | if (staticProps) _defineProperties(Constructor, staticProps); 28 | return Constructor; 29 | } 30 | 31 | function _inherits(subClass, superClass) { 32 | if (typeof superClass !== "function" && superClass !== null) { 33 | throw new TypeError("Super expression must either be null or a function"); 34 | } 35 | 36 | subClass.prototype = Object.create(superClass && superClass.prototype, { 37 | constructor: { 38 | value: subClass, 39 | writable: true, 40 | configurable: true 41 | } 42 | }); 43 | if (superClass) _setPrototypeOf(subClass, superClass); 44 | } 45 | 46 | function _getPrototypeOf(o) { 47 | _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { 48 | return o.__proto__ || Object.getPrototypeOf(o); 49 | }; 50 | return _getPrototypeOf(o); 51 | } 52 | 53 | function _setPrototypeOf(o, p) { 54 | _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { 55 | o.__proto__ = p; 56 | return o; 57 | }; 58 | 59 | return _setPrototypeOf(o, p); 60 | } 61 | 62 | function _assertThisInitialized(self) { 63 | if (self === void 0) { 64 | throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); 65 | } 66 | 67 | return self; 68 | } 69 | 70 | function _possibleConstructorReturn(self, call) { 71 | if (call && (typeof call === "object" || typeof call === "function")) { 72 | return call; 73 | } 74 | 75 | return _assertThisInitialized(self); 76 | } 77 | 78 | /** 79 | * @author: Jewway 80 | * @update zhixin wen 81 | */ 82 | 83 | $.fn.bootstrapTable.methods.push('changeTitle'); 84 | $.fn.bootstrapTable.methods.push('changeLocale'); 85 | 86 | $.BootstrapTable = 87 | /*#__PURE__*/ 88 | function (_$$BootstrapTable) { 89 | _inherits(_class, _$$BootstrapTable); 90 | 91 | function _class() { 92 | _classCallCheck(this, _class); 93 | 94 | return _possibleConstructorReturn(this, _getPrototypeOf(_class).apply(this, arguments)); 95 | } 96 | 97 | _createClass(_class, [{ 98 | key: "changeTitle", 99 | value: function changeTitle(locale) { 100 | $.each(this.options.columns, function (idx, columnList) { 101 | $.each(columnList, function (idx, column) { 102 | if (column.field) { 103 | column.title = locale[column.field]; 104 | } 105 | }); 106 | }); 107 | this.initHeader(); 108 | this.initBody(); 109 | this.initToolbar(); 110 | } 111 | }, { 112 | key: "changeLocale", 113 | value: function changeLocale(localeId) { 114 | this.options.locale = localeId; 115 | this.initLocale(); 116 | this.initPagination(); 117 | this.initBody(); 118 | this.initToolbar(); 119 | } 120 | }]); 121 | 122 | return _class; 123 | }($.BootstrapTable); 124 | 125 | })); 126 | -------------------------------------------------------------------------------- /assets/libs/bootstrap-table/extensions/i18n-enhance/bootstrap-table-i18n-enhance.min.js: -------------------------------------------------------------------------------- 1 | /** 2 | * bootstrap-table - An extended table to integration with some of the most widely used CSS frameworks. (Supports Bootstrap, Semantic UI, Bulma, Material Design, Foundation) 3 | * 4 | * @version v1.15.3 5 | * @homepage https://bootstrap-table.com 6 | * @author wenzhixin (http://wenzhixin.net.cn/) 7 | * @license MIT 8 | */ 9 | 10 | (function(a,b){"object"==typeof exports&&"undefined"!=typeof module?b(require("jquery")):"function"==typeof define&&define.amd?define(["jquery"],b):(a=a||self,b(a.jQuery))})(this,function(a){'use strict';function b(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}function c(a,b){for(var c,d=0;d .pagination ul.pagination, 2 | .bootstrap-table.bootstrap3 .fixed-table-pagination > .pagination .page-jump-to { 3 | display: inline; 4 | } 5 | 6 | .bootstrap-table .fixed-table-pagination > .pagination .page-jump-to input { 7 | width: 70px; 8 | margin-left: 5px; 9 | text-align: center; 10 | float: left; 11 | } 12 | -------------------------------------------------------------------------------- /assets/libs/bootstrap-table/extensions/page-jump-to/bootstrap-table-page-jump-to.min.css: -------------------------------------------------------------------------------- 1 | /** 2 | * bootstrap-table - An extended table to integration with some of the most widely used CSS frameworks. (Supports Bootstrap, Semantic UI, Bulma, Material Design, Foundation) 3 | * 4 | * @version v1.15.3 5 | * @homepage https://bootstrap-table.com 6 | * @author wenzhixin (http://wenzhixin.net.cn/) 7 | * @license MIT 8 | */ 9 | 10 | .bootstrap-table.bootstrap3 .fixed-table-pagination>.pagination ul.pagination,.bootstrap-table.bootstrap3 .fixed-table-pagination>.pagination .page-jump-to{display:inline}.bootstrap-table .fixed-table-pagination>.pagination .page-jump-to input{width:70px;margin-left:5px;text-align:center;float:left} -------------------------------------------------------------------------------- /assets/libs/bootstrap-table/extensions/page-jump-to/bootstrap-table-page-jump-to.min.js: -------------------------------------------------------------------------------- 1 | /** 2 | * bootstrap-table - An extended table to integration with some of the most widely used CSS frameworks. (Supports Bootstrap, Semantic UI, Bulma, Material Design, Foundation) 3 | * 4 | * @version v1.15.3 5 | * @homepage https://bootstrap-table.com 6 | * @author wenzhixin (http://wenzhixin.net.cn/) 7 | * @license MIT 8 | */ 9 | 10 | (function(a,b){"object"==typeof exports&&"undefined"!=typeof module?b(require("jquery")):"function"==typeof define&&define.amd?define(["jquery"],b):(a=a||self,b(a.jQuery))})(this,function(a){'use strict';var n=Math.min;function b(a,b){return b={exports:{}},a(b,b.exports),b.exports}function c(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}function d(a,b){for(var c,d=0;darguments.length?sa(ra[a])||sa(u[a]):ra[a]&&ra[a][b]||u[a]&&u[a][b]},ua=Math.ceil,va=Math.floor,wa=function(a){return isNaN(a=+a)?0:(0c?ya(c+b,0):n(c,b)},Aa=function(a){return function(b,c,d){var e,f=H(b),g=xa(f.length),h=za(d,g);if(a&&c!=c){for(;g>h;)if(e=f[h++],e!=e)return!0;}else for(;g>h;h++)if((a||h in f)&&f[h]===c)return a||h||0;return!a&&-1}},Ba={includes:Aa(!0),indexOf:Aa(!1)},Ca=Ba.indexOf,Da=function(a,b){var c,d=H(a),e=0,f=[];for(c in d)!L(ha,c)&&L(d,c)&&f.push(c);for(;b.length>e;)L(d,c=b[e++])&&(~Ca(f,c)||f.push(c));return f},Ea=["constructor","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","toLocaleString","toString","valueOf"],Fa=Ea.concat("length","prototype"),Ga=Object.getOwnPropertyNames||function(a){return Da(a,Fa)},Ha={f:Ga},Ia=Object.getOwnPropertySymbols,Ja={f:Ia},Ka=ta("Reflect","ownKeys")||function(a){var b=Ha.f(U(a)),c=Ja.f;return c?b.concat(c(a)):b},La=function(a,b){for(var c,d=Ka(b),e=X.f,f=T.f,g=0;gdb)throw TypeError(eb);for(b=0;b=db)throw TypeError(eb);Wa(g,h++,e)}return g.length=h,g}});var ib=function(a){if("function"!=typeof a)throw TypeError(a+" is not a function");return a},jb=function(d,e,f){return(ib(d),void 0===e)?d:0===f?function(){return d.call(e)}:1===f?function(b){return d.call(e,b)}:2===f?function(c,a){return d.call(e,c,a)}:3===f?function(f,a,b){return d.call(e,f,a,b)}:function(){return d.apply(e,arguments)}},kb=[].push,lb=function(a){var b=1==a,c=4==a,d=6==a;return function(e,f,g,h){for(var i,j,k=Va(e),l=F(k),m=jb(f,g,3),n=xa(l.length),o=0,p=h||ab,q=b?p(e,n):2==a?p(e,0):void 0;n>o;o++)if((5==a||d||o in l)&&(i=l[o],j=m(i,o,k),a))if(b)q[o]=j;else if(j)switch(a){case 3:return!0;case 5:return i;case 6:return o;case 2:kb.call(q,i);}else if(c)return!1;return d?-1:3==a||c?c:q}},mb={forEach:lb(0),map:lb(1),filter:lb(2),some:lb(3),every:lb(4),find:lb(5),findIndex:lb(6)},nb=Object.keys||function(a){return Da(a,Ea)},ob=w?Object.defineProperties:function(a,b){U(a);for(var c,d=nb(b),e=d.length,f=0;e>f;)X.f(a,c=d[f++],b[c]);return a},pb=ta("document","documentElement"),qb=ga("IE_PROTO"),rb="prototype",sb=function(){},tb=function(){var a,b=O("iframe"),c=Ea.length,d="<",e="script",f=">";for(b.style.display="none",pb.appendChild(b),b.src="java"+e+":"+"",a=b.contentWindow.document,a.open(),a.write(d+e+f+"document.F=Object"+d+"/"+e+f),a.close(),tb=a.F;c--;)delete tb[rb][Ea[c]];return tb()},ub=Object.create||function(a,b){var c;return null===a?c=tb():(sb[rb]=U(a),c=new sb,sb[rb]=null,c[qb]=a),void 0===b?c:ob(c,b)};ha[qb]=!0;var vb=$a("unscopables"),wb=Array.prototype;wb[vb]==null&&Y(wb,vb,ub(null));var xb=mb.find,yb="find",zb=!0;yb in[]&&[,][yb](function(){zb=!1}),Ta({target:"Array",proto:!0,forced:zb},{find:function(a){return xb(this,a,1 .pagination"),j=i.find(".page-jump-to");j.length||(j=a("\n
\n \n \n
\n ")).appendTo(i),j.on("click","button",function(b){c.selectPage(+a(b.target).parent(".page-jump-to").find("input").val())}))}}}]),d}(a.BootstrapTable)}); 11 | -------------------------------------------------------------------------------- /assets/libs/bootstrap-table/extensions/reorder-columns/bootstrap-table-reorder-columns.min.js: -------------------------------------------------------------------------------- 1 | /** 2 | * bootstrap-table - An extended table to integration with some of the most widely used CSS frameworks. (Supports Bootstrap, Semantic UI, Bulma, Material Design, Foundation) 3 | * 4 | * @version v1.15.3 5 | * @homepage https://bootstrap-table.com 6 | * @author wenzhixin (http://wenzhixin.net.cn/) 7 | * @license MIT 8 | */ 9 | 10 | (function(a,b){"object"==typeof exports&&"undefined"!=typeof module?b(require("jquery")):"function"==typeof define&&define.amd?define(["jquery"],b):(a=a||self,b(a.jQuery))})(this,function(a){'use strict';var c=Math.max,d=Math.min;function b(a,b){return b={exports:{}},a(b,b.exports),b.exports}a=a&&a.hasOwnProperty("default")?a["default"]:a;var e,g,h,i="undefined"==typeof globalThis?"undefined"==typeof window?"undefined"==typeof global?"undefined"==typeof self?{}:self:global:window:globalThis,j="object",k=function(a){return a&&a.Math==Math&&a},l=k(typeof globalThis==j&&globalThis)||k(typeof window==j&&window)||k(typeof self==j&&self)||k(typeof i==j&&i)||Function("return this")(),m=function(a){try{return!!a()}catch(a){return!0}},n=!m(function(){return 7!=Object.defineProperty({},"a",{get:function(){return 7}}).a}),o={}.propertyIsEnumerable,p=Object.getOwnPropertyDescriptor,q=p&&!o.call({1:2},1),r=q?function(a){var b=p(this,a);return!!b&&b.enumerable}:o,f={f:r},s=function(a,b){return{enumerable:!(1&a),configurable:!(2&a),writable:!(4&a),value:b}},t={}.toString,u=function(a){return t.call(a).slice(8,-1)},v="".split,w=m(function(){return!Object("z").propertyIsEnumerable(0)})?function(a){return"String"==u(a)?v.call(a,""):Object(a)}:Object,x=function(a){if(a==null)throw TypeError("Can't call method on "+a);return a},y=function(a){return w(x(a))},z=function(a){return"object"==typeof a?null!==a:"function"==typeof a},A=function(a,b){if(!z(a))return a;var c,d;if(b&&"function"==typeof(c=a.toString)&&!z(d=c.call(a)))return d;if("function"==typeof(c=a.valueOf)&&!z(d=c.call(a)))return d;if(!b&&"function"==typeof(c=a.toString)&&!z(d=c.call(a)))return d;throw TypeError("Can't convert object to primitive value")},B={}.hasOwnProperty,C=function(a,b){return B.call(a,b)},D=l.document,E=z(D)&&z(D.createElement),F=function(a){return E?D.createElement(a):{}},G=!n&&!m(function(){return 7!=Object.defineProperty(F("div"),"a",{get:function(){return 7}}).a}),H=Object.getOwnPropertyDescriptor,I=n?H:function(a,b){if(a=y(a),b=A(b,!0),G)try{return H(a,b)}catch(a){}return C(a,b)?s(!f.f.call(a,b),a[b]):void 0},J={f:I},K=function(a){if(!z(a))throw TypeError(a+" is not an object");return a},L=Object.defineProperty,M=n?L:function(a,b,c){if(K(a),b=A(b,!0),K(c),G)try{return L(a,b,c)}catch(a){}if("get"in c||"set"in c)throw TypeError("Accessors not supported");return"value"in c&&(a[b]=c.value),a},N={f:M},P=n?function(a,b,c){return N.f(a,b,s(1,c))}:function(a,b,c){return a[b]=c,a},Q=function(a,b){try{P(l,a,b)}catch(c){l[a]=b}return b},R=b(function(a){var b=l["__core-js_shared__"]||Q("__core-js_shared__",{});(a.exports=function(a,c){return b[a]||(b[a]=c===void 0?{}:c)})("versions",[]).push({version:"3.1.3",mode:"global",copyright:"\xA9 2019 Denis Pushkarev (zloirock.ru)"})}),S=R("native-function-to-string",Function.toString),T=l.WeakMap,U="function"==typeof T&&/native code/.test(S.call(T)),V=0,O=Math.random(),W=function(a){return"Symbol("+((a===void 0?"":a)+"")+")_"+(++V+O).toString(36)},X=R("keys"),Y=function(a){return X[a]||(X[a]=W(a))},Z={},_=l.WeakMap,aa=function(a){return h(a)?g(a):e(a,{})};if(U){var ba=new _,ca=ba.get,da=ba.has,ea=ba.set;e=function(a,b){return ea.call(ba,a,b),b},g=function(a){return ca.call(ba,a)||{}},h=function(a){return da.call(ba,a)}}else{var fa=Y("state");Z[fa]=!0,e=function(a,b){return P(a,fa,b),b},g=function(a){return C(a,fa)?a[fa]:{}},h=function(a){return C(a,fa)}}var ga={set:e,get:g,has:h,enforce:aa,getterFor:function(a){return function(b){var c;if(!z(b)||(c=g(b)).type!==a)throw TypeError("Incompatible receiver, "+a+" required");return c}}},ha=b(function(a){var b=ga.get,c=ga.enforce,d=(S+"").split("toString");R("inspectSource",function(a){return S.call(a)}),(a.exports=function(a,b,e,f){var g=!!f&&!!f.unsafe,h=!!f&&!!f.enumerable,i=!!f&&!!f.noTargetGet;return("function"==typeof e&&("string"==typeof b&&!C(e,"name")&&P(e,"name",b),c(e).source=d.join("string"==typeof b?b:"")),a===l)?void(h?a[b]=e:Q(b,e)):void(g?!i&&a[b]&&(h=!0):delete a[b],h?a[b]=e:P(a,b,e))})(Function.prototype,"toString",function(){return"function"==typeof this&&b(this).source||S.call(this)})}),ia=l,ja=function(a){return"function"==typeof a?a:void 0},ka=function(a,b){return 2>arguments.length?ja(ia[a])||ja(l[a]):ia[a]&&ia[a][b]||l[a]&&l[a][b]},la=Math.ceil,ma=Math.floor,na=function(a){return isNaN(a=+a)?0:(0e?c(e+b,0):d(e,b)},qa=function(a){return function(b,c,d){var e,f=y(b),g=oa(f.length),h=pa(d,g);if(a&&c!=c){for(;g>h;)if(e=f[h++],e!=e)return!0;}else for(;g>h;h++)if((a||h in f)&&f[h]===c)return a||h||0;return!a&&-1}},ra={includes:qa(!0),indexOf:qa(!1)},sa=ra.indexOf,ta=function(a,b){var c,d=y(a),e=0,f=[];for(c in d)!C(Z,c)&&C(d,c)&&f.push(c);for(;b.length>e;)C(d,c=b[e++])&&(~sa(f,c)||f.push(c));return f},ua=["constructor","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","toLocaleString","toString","valueOf"],va=ua.concat("length","prototype"),wa=Object.getOwnPropertyNames||function(a){return ta(a,va)},xa={f:wa},ya=Object.getOwnPropertySymbols,za={f:ya},Aa=ka("Reflect","ownKeys")||function(a){var b=xa.f(K(a)),c=za.f;return c?b.concat(c(a)):b},Ba=function(a,b){for(var c,d=Aa(b),e=N.f,f=J.f,g=0;go;o++)if((5==a||d||o in l)&&(i=l[o],j=m(i,o,k),a))if(b)q[o]=j;else if(j)switch(a){case 3:return!0;case 5:return i;case 6:return o;case 2:Ua.call(q,i);}else if(c)return!1;return d?-1:3==a||c?c:q}},Wa={forEach:Va(0),map:Va(1),filter:Va(2),some:Va(3),every:Va(4),find:Va(5),findIndex:Va(6)},Xa=Ra("species"),Ya=function(a){return!m(function(){var b=[],c=b.constructor={};return c[Xa]=function(){return{foo:1}},1!==b[a](Boolean).foo})},Za=Wa.filter;Ja({target:"Array",proto:!0,forced:!Ya("filter")},{filter:function(a){return Za(this,a,1f;)N.f(a,c=d[f++],b[c]);return a},ab=ka("document","documentElement"),bb=Y("IE_PROTO"),cb="prototype",db=function(){},eb=function(){var a,b=F("iframe"),c=ua.length,d="<",e="script",f=">";for(b.style.display="none",ab.appendChild(b),b.src="java"+e+":"+"",a=b.contentWindow.document,a.open(),a.write(d+e+f+"document.F=Object"+d+"/"+e+f),a.close(),eb=a.F;c--;)delete eb[cb][ua[c]];return eb()},fb=Object.create||function(a,b){var c;return null===a?c=eb():(db[cb]=K(a),c=new db,db[cb]=null,c[bb]=a),void 0===b?c:_a(c,b)};Z[bb]=!0;var gb=Ra("unscopables"),hb=Array.prototype;hb[gb]==null&&P(hb,gb,fb(null));var ib=Wa.find,jb="find",kb=!0;jb in[]&&[,][jb](function(){kb=!1}),Ja({target:"Array",proto:!0,forced:kb},{find:function(a){return ib(this,a,1>>0;if("function"!=typeof a)throw new TypeError;for(var d=[],e=2<=arguments.length?arguments[1]:void 0,f=0;f (http://wenzhixin.net.cn/) 7 | * @license MIT 8 | */ 9 | 10 | .reorder_rows_onDragClass td{background-color:#eee;-webkit-box-shadow:11px 5px 12px 2px #333,0 1px 0 #ccc inset,0 -1px 0 #ccc inset;-webkit-box-shadow:6px 3px 5px #555,0 1px 0 #ccc inset,0 -1px 0 #ccc inset;-moz-box-shadow:6px 4px 5px 1px #555,0 1px 0 #ccc inset,0 -1px 0 #ccc inset;-box-shadow:6px 4px 5px 1px #555,0 1px 0 #ccc inset,0 -1px 0 #ccc inset}.reorder_rows_onDragClass td:last-child{-webkit-box-shadow:8px 7px 12px 0 #333,0 1px 0 #ccc inset,0 -1px 0 #ccc inset;-webkit-box-shadow:1px 8px 6px -4px #555,0 1px 0 #ccc inset,0 -1px 0 #ccc inset;-moz-box-shadow:0 9px 4px -4px #555,0 1px 0 #ccc inset,0 -1px 0 #ccc inset,-1px 0 0 #ccc inset;-box-shadow:0 9px 4px -4px #555,0 1px 0 #ccc inset,0 -1px 0 #ccc inset,-1px 0 0 #ccc inset} -------------------------------------------------------------------------------- /assets/libs/bootstrap-table/extensions/reorder-rows/bootstrap-table-reorder-rows.min.js: -------------------------------------------------------------------------------- 1 | /** 2 | * bootstrap-table - An extended table to integration with some of the most widely used CSS frameworks. (Supports Bootstrap, Semantic UI, Bulma, Material Design, Foundation) 3 | * 4 | * @version v1.15.3 5 | * @homepage https://bootstrap-table.com 6 | * @author wenzhixin (http://wenzhixin.net.cn/) 7 | * @license MIT 8 | */ 9 | 10 | (function(a,b){"object"==typeof exports&&"undefined"!=typeof module?b(require("jquery")):"function"==typeof define&&define.amd?define(["jquery"],b):(a=a||self,b(a.jQuery))})(this,function(a){'use strict';var c=Math.max,d=Math.min;function b(a,b){return b={exports:{}},a(b,b.exports),b.exports}a=a&&a.hasOwnProperty("default")?a["default"]:a;var e,g,h,i="undefined"==typeof globalThis?"undefined"==typeof window?"undefined"==typeof global?"undefined"==typeof self?{}:self:global:window:globalThis,j="object",k=function(a){return a&&a.Math==Math&&a},l=k(typeof globalThis==j&&globalThis)||k(typeof window==j&&window)||k(typeof self==j&&self)||k(typeof i==j&&i)||Function("return this")(),m=function(a){try{return!!a()}catch(a){return!0}},n=!m(function(){return 7!=Object.defineProperty({},"a",{get:function(){return 7}}).a}),o={}.propertyIsEnumerable,p=Object.getOwnPropertyDescriptor,q=p&&!o.call({1:2},1),r=q?function(a){var b=p(this,a);return!!b&&b.enumerable}:o,f={f:r},s=function(a,b){return{enumerable:!(1&a),configurable:!(2&a),writable:!(4&a),value:b}},t={}.toString,u=function(a){return t.call(a).slice(8,-1)},v="".split,w=m(function(){return!Object("z").propertyIsEnumerable(0)})?function(a){return"String"==u(a)?v.call(a,""):Object(a)}:Object,x=function(a){if(a==null)throw TypeError("Can't call method on "+a);return a},y=function(a){return w(x(a))},z=function(a){return"object"==typeof a?null!==a:"function"==typeof a},A=function(a,b){if(!z(a))return a;var c,d;if(b&&"function"==typeof(c=a.toString)&&!z(d=c.call(a)))return d;if("function"==typeof(c=a.valueOf)&&!z(d=c.call(a)))return d;if(!b&&"function"==typeof(c=a.toString)&&!z(d=c.call(a)))return d;throw TypeError("Can't convert object to primitive value")},B={}.hasOwnProperty,C=function(a,b){return B.call(a,b)},D=l.document,E=z(D)&&z(D.createElement),F=function(a){return E?D.createElement(a):{}},G=!n&&!m(function(){return 7!=Object.defineProperty(F("div"),"a",{get:function(){return 7}}).a}),H=Object.getOwnPropertyDescriptor,I=n?H:function(a,b){if(a=y(a),b=A(b,!0),G)try{return H(a,b)}catch(a){}return C(a,b)?s(!f.f.call(a,b),a[b]):void 0},J={f:I},K=function(a){if(!z(a))throw TypeError(a+" is not an object");return a},L=Object.defineProperty,M=n?L:function(a,b,c){if(K(a),b=A(b,!0),K(c),G)try{return L(a,b,c)}catch(a){}if("get"in c||"set"in c)throw TypeError("Accessors not supported");return"value"in c&&(a[b]=c.value),a},N={f:M},P=n?function(a,b,c){return N.f(a,b,s(1,c))}:function(a,b,c){return a[b]=c,a},Q=function(a,b){try{P(l,a,b)}catch(c){l[a]=b}return b},R=b(function(a){var b=l["__core-js_shared__"]||Q("__core-js_shared__",{});(a.exports=function(a,c){return b[a]||(b[a]=c===void 0?{}:c)})("versions",[]).push({version:"3.1.3",mode:"global",copyright:"\xA9 2019 Denis Pushkarev (zloirock.ru)"})}),S=R("native-function-to-string",Function.toString),T=l.WeakMap,U="function"==typeof T&&/native code/.test(S.call(T)),V=0,O=Math.random(),W=function(a){return"Symbol("+((a===void 0?"":a)+"")+")_"+(++V+O).toString(36)},X=R("keys"),Y=function(a){return X[a]||(X[a]=W(a))},Z={},_=l.WeakMap,aa=function(a){return h(a)?g(a):e(a,{})};if(U){var ba=new _,ca=ba.get,da=ba.has,ea=ba.set;e=function(a,b){return ea.call(ba,a,b),b},g=function(a){return ca.call(ba,a)||{}},h=function(a){return da.call(ba,a)}}else{var fa=Y("state");Z[fa]=!0,e=function(a,b){return P(a,fa,b),b},g=function(a){return C(a,fa)?a[fa]:{}},h=function(a){return C(a,fa)}}var ga={set:e,get:g,has:h,enforce:aa,getterFor:function(a){return function(b){var c;if(!z(b)||(c=g(b)).type!==a)throw TypeError("Incompatible receiver, "+a+" required");return c}}},ha=b(function(a){var b=ga.get,c=ga.enforce,d=(S+"").split("toString");R("inspectSource",function(a){return S.call(a)}),(a.exports=function(a,b,e,f){var g=!!f&&!!f.unsafe,h=!!f&&!!f.enumerable,i=!!f&&!!f.noTargetGet;return("function"==typeof e&&("string"==typeof b&&!C(e,"name")&&P(e,"name",b),c(e).source=d.join("string"==typeof b?b:"")),a===l)?void(h?a[b]=e:Q(b,e)):void(g?!i&&a[b]&&(h=!0):delete a[b],h?a[b]=e:P(a,b,e))})(Function.prototype,"toString",function(){return"function"==typeof this&&b(this).source||S.call(this)})}),ia=l,ja=function(a){return"function"==typeof a?a:void 0},ka=Math.ceil,la=Math.floor,ma=function(a){return isNaN(a=+a)?0:(0e?c(e+b,0):d(e,b)},pa=function(a){return function(b,c,d){var e,f=y(b),g=na(f.length),h=oa(d,g);if(a&&c!=c){for(;g>h;)if(e=f[h++],e!=e)return!0;}else for(;g>h;h++)if((a||h in f)&&f[h]===c)return a||h||0;return!a&&-1}},qa={includes:pa(!0),indexOf:pa(!1)},ra=qa.indexOf,sa=function(a,b){var c,d=y(a),e=0,f=[];for(c in d)!C(Z,c)&&C(d,c)&&f.push(c);for(;b.length>e;)C(d,c=b[e++])&&(~ra(f,c)||f.push(c));return f},ta=["constructor","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","toLocaleString","toString","valueOf"].concat("length","prototype"),ua=Object.getOwnPropertyNames||function(a){return sa(a,ta)},va={f:ua},wa=Object.getOwnPropertySymbols,xa={f:wa},ya=function(a,b){return 2>arguments.length?ja(ia[a])||ja(l[a]):ia[a]&&ia[a][b]||l[a]&&l[a][b]}("Reflect","ownKeys")||function(a){var b=va.f(K(a)),c=xa.f;return c?b.concat(c(a)):b},za=function(a,b){for(var c,d=ya(b),e=N.f,f=J.f,g=0;gUa)throw TypeError(Va);for(b=0;b=Ua)throw TypeError(Va);Ka(g,h++,e)}return g.length=h,g}});var Za=Oa("species"),$a=[].slice;Ha({target:"Array",proto:!0,forced:!Sa("slice")},{slice:function(a,b){var d,e,f,g=y(this),h=na(g.length),i=oa(a,h),j=oa(void 0===b?h:b,h);if(Ia(g)&&(d=g.constructor,"function"==typeof d&&(d===Array||Ia(d.prototype))?d=void 0:z(d)&&(d=d[Za],null===d&&(d=void 0)),d===Array||void 0===d))return $a.call(g,i,j);for(e=new(void 0===d?Array:d)(c(j-i,0)),f=0;i (http://wenzhixin.net.cn/) 7 | * @license MIT 8 | */ 9 | 10 | (function(a,b){"object"==typeof exports&&"undefined"!=typeof module?b(require("jquery")):"function"==typeof define&&define.amd?define(["jquery"],b):(a=a||self,b(a.jQuery))})(this,function(a){'use strict';var c=Math.max,d=Math.min;function b(a,b){return b={exports:{}},a(b,b.exports),b.exports}a=a&&a.hasOwnProperty("default")?a["default"]:a;var e,g,h,i="undefined"==typeof globalThis?"undefined"==typeof window?"undefined"==typeof global?"undefined"==typeof self?{}:self:global:window:globalThis,j="object",k=function(a){return a&&a.Math==Math&&a},l=k(typeof globalThis==j&&globalThis)||k(typeof window==j&&window)||k(typeof self==j&&self)||k(typeof i==j&&i)||Function("return this")(),m=function(a){try{return!!a()}catch(a){return!0}},n=!m(function(){return 7!=Object.defineProperty({},"a",{get:function(){return 7}}).a}),o={}.propertyIsEnumerable,p=Object.getOwnPropertyDescriptor,q=p&&!o.call({1:2},1),r=q?function(a){var b=p(this,a);return!!b&&b.enumerable}:o,f={f:r},s=function(a,b){return{enumerable:!(1&a),configurable:!(2&a),writable:!(4&a),value:b}},t={}.toString,u=function(a){return t.call(a).slice(8,-1)},v="".split,w=m(function(){return!Object("z").propertyIsEnumerable(0)})?function(a){return"String"==u(a)?v.call(a,""):Object(a)}:Object,x=function(a){if(a==null)throw TypeError("Can't call method on "+a);return a},y=function(a){return w(x(a))},z=function(a){return"object"==typeof a?null!==a:"function"==typeof a},A=function(a,b){if(!z(a))return a;var c,d;if(b&&"function"==typeof(c=a.toString)&&!z(d=c.call(a)))return d;if("function"==typeof(c=a.valueOf)&&!z(d=c.call(a)))return d;if(!b&&"function"==typeof(c=a.toString)&&!z(d=c.call(a)))return d;throw TypeError("Can't convert object to primitive value")},B={}.hasOwnProperty,C=function(a,b){return B.call(a,b)},D=l.document,E=z(D)&&z(D.createElement),F=function(a){return E?D.createElement(a):{}},G=!n&&!m(function(){return 7!=Object.defineProperty(F("div"),"a",{get:function(){return 7}}).a}),H=Object.getOwnPropertyDescriptor,I=n?H:function(a,b){if(a=y(a),b=A(b,!0),G)try{return H(a,b)}catch(a){}return C(a,b)?s(!f.f.call(a,b),a[b]):void 0},J={f:I},K=function(a){if(!z(a))throw TypeError(a+" is not an object");return a},L=Object.defineProperty,M=n?L:function(a,b,c){if(K(a),b=A(b,!0),K(c),G)try{return L(a,b,c)}catch(a){}if("get"in c||"set"in c)throw TypeError("Accessors not supported");return"value"in c&&(a[b]=c.value),a},N={f:M},P=n?function(a,b,c){return N.f(a,b,s(1,c))}:function(a,b,c){return a[b]=c,a},Q=function(a,b){try{P(l,a,b)}catch(c){l[a]=b}return b},R=b(function(a){var b=l["__core-js_shared__"]||Q("__core-js_shared__",{});(a.exports=function(a,c){return b[a]||(b[a]=c===void 0?{}:c)})("versions",[]).push({version:"3.1.3",mode:"global",copyright:"\xA9 2019 Denis Pushkarev (zloirock.ru)"})}),S=R("native-function-to-string",Function.toString),T=l.WeakMap,U="function"==typeof T&&/native code/.test(S.call(T)),V=0,O=Math.random(),W=function(a){return"Symbol("+((a===void 0?"":a)+"")+")_"+(++V+O).toString(36)},X=R("keys"),Y=function(a){return X[a]||(X[a]=W(a))},Z={},_=l.WeakMap,aa=function(a){return h(a)?g(a):e(a,{})};if(U){var ba=new _,ca=ba.get,da=ba.has,ea=ba.set;e=function(a,b){return ea.call(ba,a,b),b},g=function(a){return ca.call(ba,a)||{}},h=function(a){return da.call(ba,a)}}else{var fa=Y("state");Z[fa]=!0,e=function(a,b){return P(a,fa,b),b},g=function(a){return C(a,fa)?a[fa]:{}},h=function(a){return C(a,fa)}}var ga={set:e,get:g,has:h,enforce:aa,getterFor:function(a){return function(b){var c;if(!z(b)||(c=g(b)).type!==a)throw TypeError("Incompatible receiver, "+a+" required");return c}}},ha=b(function(a){var b=ga.get,c=ga.enforce,d=(S+"").split("toString");R("inspectSource",function(a){return S.call(a)}),(a.exports=function(a,b,e,f){var g=!!f&&!!f.unsafe,h=!!f&&!!f.enumerable,i=!!f&&!!f.noTargetGet;return("function"==typeof e&&("string"==typeof b&&!C(e,"name")&&P(e,"name",b),c(e).source=d.join("string"==typeof b?b:"")),a===l)?void(h?a[b]=e:Q(b,e)):void(g?!i&&a[b]&&(h=!0):delete a[b],h?a[b]=e:P(a,b,e))})(Function.prototype,"toString",function(){return"function"==typeof this&&b(this).source||S.call(this)})}),ia=l,ja=function(a){return"function"==typeof a?a:void 0},ka=Math.ceil,la=Math.floor,ma=function(a){return isNaN(a=+a)?0:(0e?c(e+b,0):d(e,b)},pa=function(a){return function(b,c,d){var e,f=y(b),g=na(f.length),h=oa(d,g);if(a&&c!=c){for(;g>h;)if(e=f[h++],e!=e)return!0;}else for(;g>h;h++)if((a||h in f)&&f[h]===c)return a||h||0;return!a&&-1}},qa={includes:pa(!0),indexOf:pa(!1)},ra=qa.indexOf,sa=function(a,b){var c,d=y(a),e=0,f=[];for(c in d)!C(Z,c)&&C(d,c)&&f.push(c);for(;b.length>e;)C(d,c=b[e++])&&(~ra(f,c)||f.push(c));return f},ta=["constructor","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","toLocaleString","toString","valueOf"].concat("length","prototype"),ua=Object.getOwnPropertyNames||function(a){return sa(a,ta)},va={f:ua},wa=Object.getOwnPropertySymbols,xa={f:wa},ya=function(a,b){return 2>arguments.length?ja(ia[a])||ja(l[a]):ia[a]&&ia[a][b]||l[a]&&l[a][b]}("Reflect","ownKeys")||function(a){var b=va.f(K(a)),c=xa.f;return c?b.concat(c(a)):b},za=function(a,b){for(var c,d=ya(b),e=N.f,f=J.f,g=0;g 3 | * @update zhixin wen 4 | */ 5 | 6 | .fix-sticky { 7 | position: fixed !important; 8 | overflow: hidden; 9 | z-index: 100; 10 | } 11 | 12 | .fix-sticky table thead { 13 | background: #fff; 14 | } 15 | 16 | .fix-sticky table thead.thead-light { 17 | background: #e9ecef; 18 | } 19 | 20 | .fix-sticky table thead.thead-dark { 21 | background: #212529; 22 | } 23 | -------------------------------------------------------------------------------- /assets/libs/bootstrap-table/extensions/sticky-header/bootstrap-table-sticky-header.min.css: -------------------------------------------------------------------------------- 1 | /** 2 | * bootstrap-table - An extended table to integration with some of the most widely used CSS frameworks. (Supports Bootstrap, Semantic UI, Bulma, Material Design, Foundation) 3 | * 4 | * @version v1.15.3 5 | * @homepage https://bootstrap-table.com 6 | * @author wenzhixin (http://wenzhixin.net.cn/) 7 | * @license MIT 8 | */ 9 | 10 | .fix-sticky{position:fixed!important;overflow:hidden;z-index:100}.fix-sticky table thead{background:#fff}.fix-sticky table thead.thead-light{background:#e9ecef}.fix-sticky table thead.thead-dark{background:#212529} -------------------------------------------------------------------------------- /assets/libs/bootstrap-table/themes/materialize/bootstrap-table-materialize.css: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | /** 3 | * @author zhixin wen 4 | * https://github.com/wenzhixin/bootstrap-table/ 5 | * theme: https://github.com/jgthms/bulma/ 6 | */ 7 | .bootstrap-table .fixed-table-toolbar::after { 8 | content: ""; 9 | display: block; 10 | clear: both; 11 | } 12 | .bootstrap-table .fixed-table-toolbar .bs-bars, 13 | .bootstrap-table .fixed-table-toolbar .search, 14 | .bootstrap-table .fixed-table-toolbar .columns { 15 | position: relative; 16 | margin-top: 10px; 17 | margin-bottom: 10px; 18 | } 19 | .bootstrap-table .fixed-table-toolbar .columns .btn-group > .btn-group { 20 | display: inline-block; 21 | margin-left: -1px !important; 22 | } 23 | .bootstrap-table .fixed-table-toolbar .columns .btn-group > .btn-group > .btn { 24 | border-radius: 0; 25 | } 26 | .bootstrap-table .fixed-table-toolbar .columns .btn-group > .btn-group:first-child > .btn { 27 | border-top-left-radius: 4px; 28 | border-bottom-left-radius: 4px; 29 | } 30 | .bootstrap-table .fixed-table-toolbar .columns .btn-group > .btn-group:last-child > .btn { 31 | border-top-right-radius: 4px; 32 | border-bottom-right-radius: 4px; 33 | } 34 | .bootstrap-table .fixed-table-toolbar .columns .dropdown-menu { 35 | text-align: left; 36 | max-height: 300px; 37 | overflow: auto; 38 | -ms-overflow-style: scrollbar; 39 | z-index: 1001; 40 | } 41 | .bootstrap-table .fixed-table-toolbar .columns label { 42 | display: block; 43 | padding: 3px 20px; 44 | clear: both; 45 | font-weight: normal; 46 | line-height: 1.428571429; 47 | } 48 | .bootstrap-table .fixed-table-toolbar .columns-left { 49 | margin-right: 5px; 50 | } 51 | .bootstrap-table .fixed-table-toolbar .columns-right { 52 | margin-left: 5px; 53 | } 54 | .bootstrap-table .fixed-table-toolbar .pull-right .dropdown-menu { 55 | right: 0; 56 | left: auto; 57 | } 58 | .bootstrap-table .fixed-table-container { 59 | position: relative; 60 | clear: both; 61 | } 62 | .bootstrap-table .fixed-table-container .table { 63 | width: 100%; 64 | margin-bottom: 0 !important; 65 | } 66 | .bootstrap-table .fixed-table-container .table th, 67 | .bootstrap-table .fixed-table-container .table td { 68 | vertical-align: middle; 69 | box-sizing: border-box; 70 | } 71 | .bootstrap-table .fixed-table-container .table thead th { 72 | vertical-align: bottom; 73 | padding: 0; 74 | margin: 0; 75 | } 76 | .bootstrap-table .fixed-table-container .table thead th:focus { 77 | outline: 0 solid transparent; 78 | } 79 | .bootstrap-table .fixed-table-container .table thead th.detail { 80 | width: 30px; 81 | } 82 | .bootstrap-table .fixed-table-container .table thead th .th-inner { 83 | padding: 0.75rem; 84 | vertical-align: bottom; 85 | overflow: hidden; 86 | text-overflow: ellipsis; 87 | white-space: nowrap; 88 | } 89 | .bootstrap-table .fixed-table-container .table thead th .sortable { 90 | cursor: pointer; 91 | background-position: right; 92 | background-repeat: no-repeat; 93 | padding-right: 30px; 94 | } 95 | .bootstrap-table .fixed-table-container .table thead th .both { 96 | background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAQAAADYWf5HAAAAkElEQVQoz7X QMQ5AQBCF4dWQSJxC5wwax1Cq1e7BAdxD5SL+Tq/QCM1oNiJidwox0355mXnG/DrEtIQ6azioNZQxI0ykPhTQIwhCR+BmBYtlK7kLJYwWCcJA9M4qdrZrd8pPjZWPtOqdRQy320YSV17OatFC4euts6z39GYMKRPCTKY9UnPQ6P+GtMRfGtPnBCiqhAeJPmkqAAAAAElFTkSuQmCC"); 97 | } 98 | .bootstrap-table .fixed-table-container .table thead th .asc { 99 | background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAYAAAByUDbMAAAAZ0lEQVQ4y2NgGLKgquEuFxBPAGI2ahhWCsS/gDibUoO0gPgxEP8H4ttArEyuQYxAPBdqEAxPBImTY5gjEL9DM+wTENuQahAvEO9DMwiGdwAxOymGJQLxTyD+jgWDxCMZRsEoGAVoAADeemwtPcZI2wAAAABJRU5ErkJggg=="); 100 | } 101 | .bootstrap-table .fixed-table-container .table thead th .desc { 102 | background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAYAAAByUDbMAAAAZUlEQVQ4y2NgGAWjYBSggaqGu5FA/BOIv2PBIPFEUgxjB+IdQPwfC94HxLykus4GiD+hGfQOiB3J8SojEE9EM2wuSJzcsFMG4ttQgx4DsRalkZENxL+AuJQaMcsGxBOAmGvopk8AVz1sLZgg0bsAAAAASUVORK5CYII= "); 103 | } 104 | .bootstrap-table .fixed-table-container .table tbody tr.selected td { 105 | background-color: rgba(242, 242, 242, 0.5); 106 | } 107 | .bootstrap-table .fixed-table-container .table tbody tr.no-records-found { 108 | text-align: center; 109 | } 110 | .bootstrap-table .fixed-table-container .table tbody tr .card-view { 111 | display: flex; 112 | } 113 | .bootstrap-table .fixed-table-container .table tbody tr .card-view .card-view-title { 114 | font-weight: bold; 115 | display: inline-block; 116 | min-width: 30%; 117 | text-align: left !important; 118 | } 119 | .bootstrap-table .fixed-table-container .table .bs-checkbox { 120 | text-align: center; 121 | } 122 | .bootstrap-table .fixed-table-container .table input[type=radio], 123 | .bootstrap-table .fixed-table-container .table input[type=checkbox] { 124 | margin: 0 auto !important; 125 | } 126 | .bootstrap-table .fixed-table-container .table.table-sm .th-inner { 127 | padding: 0.3rem; 128 | } 129 | .bootstrap-table .fixed-table-container.fixed-height:not(.has-footer) { 130 | border-bottom: 1px solid rgba(0, 0, 0, 0.12); 131 | } 132 | .bootstrap-table .fixed-table-container.fixed-height.has-card-view { 133 | border-top: 1px solid rgba(0, 0, 0, 0.12); 134 | border-bottom: 1px solid rgba(0, 0, 0, 0.12); 135 | } 136 | .bootstrap-table .fixed-table-container.fixed-height .fixed-table-border { 137 | border-left: 1px solid rgba(0, 0, 0, 0.12); 138 | border-right: 1px solid rgba(0, 0, 0, 0.12); 139 | } 140 | .bootstrap-table .fixed-table-container.fixed-height .table thead th { 141 | border-bottom: 1px solid rgba(0, 0, 0, 0.12); 142 | } 143 | .bootstrap-table .fixed-table-container.fixed-height .table-dark thead th { 144 | border-bottom: 1px solid #32383e; 145 | } 146 | .bootstrap-table .fixed-table-container .fixed-table-header { 147 | overflow: hidden; 148 | } 149 | .bootstrap-table .fixed-table-container .fixed-table-body { 150 | overflow-x: auto; 151 | overflow-y: auto; 152 | height: 100%; 153 | } 154 | .bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading { 155 | align-items: center; 156 | background: #fefefe; 157 | display: none; 158 | justify-content: center; 159 | position: absolute; 160 | bottom: 0; 161 | width: 100%; 162 | z-index: 1000; 163 | } 164 | .bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading .loading-wrap { 165 | align-items: baseline; 166 | display: flex; 167 | justify-content: center; 168 | } 169 | .bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading .loading-wrap .loading-text { 170 | font-size: 2rem; 171 | margin-right: 6px; 172 | } 173 | .bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading .loading-wrap .animation-wrap { 174 | align-items: center; 175 | display: flex; 176 | justify-content: center; 177 | } 178 | .bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading .loading-wrap .animation-dot, 179 | .bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading .loading-wrap .animation-wrap::after, 180 | .bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading .loading-wrap .animation-wrap::before { 181 | content: ""; 182 | animation-duration: 1.5s; 183 | animation-iteration-count: infinite; 184 | animation-name: LOADING; 185 | background: #0a0a0a; 186 | border-radius: 50%; 187 | display: block; 188 | height: 5px; 189 | margin: 0 4px; 190 | opacity: 0; 191 | width: 5px; 192 | } 193 | .bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading .loading-wrap .animation-dot { 194 | animation-delay: 0.3s; 195 | } 196 | .bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading .loading-wrap .animation-wrap::after { 197 | animation-delay: 0.6s; 198 | } 199 | .bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading.table-dark { 200 | background: #0a0a0a; 201 | } 202 | .bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading.table-dark .animation-dot, 203 | .bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading.table-dark .animation-wrap::after, 204 | .bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading.table-dark .animation-wrap::before { 205 | background: #fefefe; 206 | } 207 | .bootstrap-table .fixed-table-container .fixed-table-footer { 208 | overflow: hidden; 209 | } 210 | .bootstrap-table .fixed-table-pagination::after { 211 | content: ""; 212 | display: block; 213 | clear: both; 214 | } 215 | .bootstrap-table .fixed-table-pagination > .pagination-detail, 216 | .bootstrap-table .fixed-table-pagination > .pagination { 217 | margin-top: 10px; 218 | margin-bottom: 10px; 219 | } 220 | .bootstrap-table .fixed-table-pagination > .pagination-detail .pagination-info { 221 | line-height: 34px; 222 | margin-right: 5px; 223 | } 224 | .bootstrap-table .fixed-table-pagination > .pagination-detail .page-list { 225 | display: inline-block; 226 | } 227 | .bootstrap-table .fixed-table-pagination > .pagination-detail .page-list .btn-group { 228 | position: relative; 229 | display: inline-block; 230 | vertical-align: middle; 231 | } 232 | .bootstrap-table .fixed-table-pagination > .pagination-detail .page-list .btn-group .dropdown-menu { 233 | margin-bottom: 0; 234 | } 235 | .bootstrap-table .fixed-table-pagination > .pagination ul.pagination { 236 | margin: 0; 237 | } 238 | .bootstrap-table .fixed-table-pagination > .pagination ul.pagination a { 239 | padding: 6px 12px; 240 | line-height: 1.428571429; 241 | } 242 | .bootstrap-table .fixed-table-pagination > .pagination ul.pagination li.page-intermediate a { 243 | color: #c8c8c8; 244 | } 245 | .bootstrap-table .fixed-table-pagination > .pagination ul.pagination li.page-intermediate a::before { 246 | content: "⬅"; 247 | } 248 | .bootstrap-table .fixed-table-pagination > .pagination ul.pagination li.page-intermediate a::after { 249 | content: "➡"; 250 | } 251 | .bootstrap-table .fixed-table-pagination > .pagination ul.pagination li.disabled a { 252 | pointer-events: none; 253 | cursor: default; 254 | } 255 | .bootstrap-table.fullscreen { 256 | position: fixed; 257 | top: 0; 258 | left: 0; 259 | z-index: 1050; 260 | width: 100% !important; 261 | background: #fff; 262 | height: calc(100vh); 263 | overflow-y: scroll; 264 | } 265 | 266 | /* calculate scrollbar width */ 267 | div.fixed-table-scroll-inner { 268 | width: 100%; 269 | height: 200px; 270 | } 271 | 272 | div.fixed-table-scroll-outer { 273 | top: 0; 274 | left: 0; 275 | visibility: hidden; 276 | width: 200px; 277 | height: 150px; 278 | overflow: hidden; 279 | } 280 | 281 | @keyframes LOADING { 282 | 0% { 283 | opacity: 0; 284 | } 285 | 50% { 286 | opacity: 1; 287 | } 288 | to { 289 | opacity: 0; 290 | } 291 | } 292 | .bootstrap-table .float-left { 293 | float: left; 294 | } 295 | .bootstrap-table .float-right { 296 | float: right; 297 | } 298 | .bootstrap-table .fixed-table-toolbar .columns > .btn { 299 | margin-left: 3px; 300 | } 301 | .bootstrap-table .fixed-table-toolbar .columns > div { 302 | display: inline; 303 | } 304 | .bootstrap-table .fixed-table-toolbar .keep-open li label { 305 | padding-top: 13px; 306 | } 307 | .bootstrap-table .fixed-table-footer { 308 | border-top: 1px solid rgba(0, 0, 0, 0.12); 309 | } 310 | .bootstrap-table .fixed-table-pagination .page-list i { 311 | vertical-align: middle; 312 | } 313 | .bootstrap-table .fixed-table-pagination .pagination li { 314 | height: 36px; 315 | } 316 | 317 | /*# sourceMappingURL=bootstrap-table-materialize.css.map */ 318 | -------------------------------------------------------------------------------- /assets/libs/fSelect/README.md: -------------------------------------------------------------------------------- 1 | # fSelect 2 | A jQuery select box replacement library ([live demo](https://facetwp.com/wp-content/plugins/facetwp/assets/vendor/fSelect/test.html)) 3 | 4 | 5 | 6 | ### Usage 7 | 8 | ```javascript 9 | $('.your-select').fSelect(); 10 | ``` 11 | 12 | ### Available options 13 | 14 | ```js 15 | $('.your-select').fSelect({ 16 | placeholder: 'Select some options', 17 | numDisplayed: 3, 18 | overflowText: '{n} selected', 19 | noResultsText: 'No results found', 20 | searchText: 'Search', 21 | showSearch: true 22 | }); 23 | ``` 24 | 25 | * **placeholder** (str) - the default placeholder text 26 | * **numDisplayed** (int) - the number of values to show before switching to the `overflowText` 27 | * **overflowText** (str) - the text to show after exceeding the `numDisplayed` limit 28 | * **noResultsText** (str) - the text to show if no choices exist (or an empty string) 29 | * **searchText** (str) - the search box placeholder text 30 | * **showSearch** (bool) - show the search box? 31 | 32 | ### Methods 33 | 34 | ```js 35 | $('.your-select').fSelect('reload'); 36 | $('.your-select').fSelect('destroy'); 37 | ``` 38 | 39 | ### Single vs. multi-select 40 | 41 | Add the `multiple` attribute to your ` 45 | ``` 46 | -------------------------------------------------------------------------------- /assets/libs/fSelect/fSelect.css: -------------------------------------------------------------------------------- 1 | .fs-wrap { 2 | display: inline-block; 3 | cursor: pointer; 4 | line-height: 1; 5 | width: 200px; 6 | } 7 | 8 | .fs-label-wrap { 9 | position: relative; 10 | background-color: #fff; 11 | border: 1px solid #ddd; 12 | cursor: default; 13 | } 14 | 15 | .fs-label-wrap, 16 | .fs-dropdown { 17 | -webkit-user-select: none; 18 | -moz-user-select: none; 19 | -ms-user-select: none; 20 | user-select: none; 21 | } 22 | 23 | .fs-label-wrap .fs-label { 24 | padding: 6px 22px 6px 8px; 25 | text-overflow: ellipsis; 26 | white-space: nowrap; 27 | overflow: hidden; 28 | } 29 | 30 | .fs-arrow { 31 | width: 0; 32 | height: 0; 33 | border-left: 5px solid transparent; 34 | border-right: 5px solid transparent; 35 | border-top: 5px solid #333; 36 | position: absolute; 37 | top: 0; 38 | right: 5px; 39 | bottom: 0; 40 | margin: auto; 41 | transition: ease-in 0.15s; 42 | } 43 | 44 | .fs-open .fs-arrow { 45 | transform: rotate(-180deg); 46 | } 47 | 48 | .fs-dropdown { 49 | position: absolute; 50 | background-color: #fff; 51 | border: 1px solid #ddd; 52 | width: 200px; 53 | margin-top: 5px; 54 | z-index: 1000; 55 | } 56 | 57 | .fs-dropdown .fs-options { 58 | max-height: 200px; 59 | overflow: auto; 60 | } 61 | 62 | .fs-search input { 63 | border: none !important; 64 | box-shadow: none !important; 65 | outline: none; 66 | padding: 6px 0; 67 | width: 100%; 68 | } 69 | 70 | .fs-option, 71 | .fs-search, 72 | .fs-optgroup-label { 73 | padding: 6px 8px; 74 | border-bottom: 1px solid #eee; 75 | cursor: default; 76 | } 77 | 78 | .fs-option:last-child { 79 | border-bottom: none; 80 | } 81 | 82 | .fs-search { 83 | padding: 0 8px; 84 | } 85 | 86 | .fs-no-results { 87 | padding: 6px 8px; 88 | } 89 | 90 | .fs-option { 91 | cursor: pointer; 92 | word-break: break-all; 93 | } 94 | 95 | .fs-option.disabled { 96 | opacity: 0.4; 97 | cursor: default; 98 | } 99 | 100 | .fs-option.hl { 101 | background-color: #f5f5f5; 102 | } 103 | 104 | .fs-wrap.multiple .fs-option { 105 | position: relative; 106 | padding-left: 30px; 107 | } 108 | 109 | .fs-wrap.multiple .fs-checkbox { 110 | position: absolute; 111 | display: block; 112 | width: 30px; 113 | top: 0; 114 | left: 0; 115 | bottom: 0; 116 | } 117 | 118 | .fs-wrap.multiple .fs-option .fs-checkbox i { 119 | position: absolute; 120 | margin: auto; 121 | left: 0; 122 | right: 0; 123 | top: 0; 124 | bottom: 0; 125 | width: 14px; 126 | height: 14px; 127 | border: 1px solid #aeaeae; 128 | border-radius: 2px; 129 | background-color: #fff; 130 | } 131 | 132 | .fs-wrap.multiple .fs-option.selected .fs-checkbox i { 133 | background-color: rgb(17, 169, 17); 134 | border-color: transparent; 135 | background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAGCAYAAAD+Bd/7AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAABx0RVh0U29mdHdhcmUAQWRvYmUgRmlyZXdvcmtzIENTNXG14zYAAABMSURBVAiZfc0xDkAAFIPhd2Kr1WRjcAExuIgzGUTIZ/AkImjSofnbNBAfHvzAHjOKNzhiQ42IDFXCDivaaxAJd0xYshT3QqBxqnxeHvhunpu23xnmAAAAAElFTkSuQmCC'); 136 | background-repeat: no-repeat; 137 | background-position: center; 138 | } 139 | 140 | .fs-optgroup-label { 141 | font-weight: bold; 142 | text-align: center; 143 | } 144 | 145 | .hidden { 146 | display: none; 147 | } 148 | -------------------------------------------------------------------------------- /assets/libs/fSelect/test.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | fSelect Test 4 | 5 | 6 | 7 | 14 | 15 | 16 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /assets/libs/font-awesome/webfonts/fa-brands-400.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciey/NodeExpressAdmin/58bcc1941e803675e5b0a576a615b9f68d5586b7/assets/libs/font-awesome/webfonts/fa-brands-400.eot -------------------------------------------------------------------------------- /assets/libs/font-awesome/webfonts/fa-brands-400.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciey/NodeExpressAdmin/58bcc1941e803675e5b0a576a615b9f68d5586b7/assets/libs/font-awesome/webfonts/fa-brands-400.ttf -------------------------------------------------------------------------------- /assets/libs/font-awesome/webfonts/fa-brands-400.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciey/NodeExpressAdmin/58bcc1941e803675e5b0a576a615b9f68d5586b7/assets/libs/font-awesome/webfonts/fa-brands-400.woff -------------------------------------------------------------------------------- /assets/libs/font-awesome/webfonts/fa-brands-400.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciey/NodeExpressAdmin/58bcc1941e803675e5b0a576a615b9f68d5586b7/assets/libs/font-awesome/webfonts/fa-brands-400.woff2 -------------------------------------------------------------------------------- /assets/libs/font-awesome/webfonts/fa-regular-400.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciey/NodeExpressAdmin/58bcc1941e803675e5b0a576a615b9f68d5586b7/assets/libs/font-awesome/webfonts/fa-regular-400.eot -------------------------------------------------------------------------------- /assets/libs/font-awesome/webfonts/fa-regular-400.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciey/NodeExpressAdmin/58bcc1941e803675e5b0a576a615b9f68d5586b7/assets/libs/font-awesome/webfonts/fa-regular-400.ttf -------------------------------------------------------------------------------- /assets/libs/font-awesome/webfonts/fa-regular-400.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciey/NodeExpressAdmin/58bcc1941e803675e5b0a576a615b9f68d5586b7/assets/libs/font-awesome/webfonts/fa-regular-400.woff -------------------------------------------------------------------------------- /assets/libs/font-awesome/webfonts/fa-regular-400.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciey/NodeExpressAdmin/58bcc1941e803675e5b0a576a615b9f68d5586b7/assets/libs/font-awesome/webfonts/fa-regular-400.woff2 -------------------------------------------------------------------------------- /assets/libs/font-awesome/webfonts/fa-solid-900.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciey/NodeExpressAdmin/58bcc1941e803675e5b0a576a615b9f68d5586b7/assets/libs/font-awesome/webfonts/fa-solid-900.eot -------------------------------------------------------------------------------- /assets/libs/font-awesome/webfonts/fa-solid-900.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciey/NodeExpressAdmin/58bcc1941e803675e5b0a576a615b9f68d5586b7/assets/libs/font-awesome/webfonts/fa-solid-900.ttf -------------------------------------------------------------------------------- /assets/libs/font-awesome/webfonts/fa-solid-900.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciey/NodeExpressAdmin/58bcc1941e803675e5b0a576a615b9f68d5586b7/assets/libs/font-awesome/webfonts/fa-solid-900.woff -------------------------------------------------------------------------------- /assets/libs/font-awesome/webfonts/fa-solid-900.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciey/NodeExpressAdmin/58bcc1941e803675e5b0a576a615b9f68d5586b7/assets/libs/font-awesome/webfonts/fa-solid-900.woff2 -------------------------------------------------------------------------------- /assets/libs/jquery-treegrid/css/jquery.treegrid.css: -------------------------------------------------------------------------------- 1 | .treegrid-indent {width:16px; height: 16px; display: inline-block; position: relative;} 2 | 3 | .treegrid-expander {width:16px; height: 16px; display: inline-block; position: relative; cursor: pointer;} 4 | 5 | .treegrid-expander-expanded{background-image: url(../img/collapse.png); } 6 | .treegrid-expander-collapsed{background-image: url(../img/expand.png);} 7 | -------------------------------------------------------------------------------- /assets/libs/jquery-treegrid/img/collapse.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciey/NodeExpressAdmin/58bcc1941e803675e5b0a576a615b9f68d5586b7/assets/libs/jquery-treegrid/img/collapse.png -------------------------------------------------------------------------------- /assets/libs/jquery-treegrid/img/expand.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciey/NodeExpressAdmin/58bcc1941e803675e5b0a576a615b9f68d5586b7/assets/libs/jquery-treegrid/img/expand.png -------------------------------------------------------------------------------- /assets/libs/jquery-treegrid/img/file.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciey/NodeExpressAdmin/58bcc1941e803675e5b0a576a615b9f68d5586b7/assets/libs/jquery-treegrid/img/file.png -------------------------------------------------------------------------------- /assets/libs/jquery-treegrid/img/folder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciey/NodeExpressAdmin/58bcc1941e803675e5b0a576a615b9f68d5586b7/assets/libs/jquery-treegrid/img/folder.png -------------------------------------------------------------------------------- /assets/libs/layer/images/icon-ext.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciey/NodeExpressAdmin/58bcc1941e803675e5b0a576a615b9f68d5586b7/assets/libs/layer/images/icon-ext.png -------------------------------------------------------------------------------- /assets/libs/layer/images/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciey/NodeExpressAdmin/58bcc1941e803675e5b0a576a615b9f68d5586b7/assets/libs/layer/images/icon.png -------------------------------------------------------------------------------- /assets/libs/layer/images/loading-0.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciey/NodeExpressAdmin/58bcc1941e803675e5b0a576a615b9f68d5586b7/assets/libs/layer/images/loading-0.gif -------------------------------------------------------------------------------- /assets/libs/layer/images/loading-1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciey/NodeExpressAdmin/58bcc1941e803675e5b0a576a615b9f68d5586b7/assets/libs/layer/images/loading-1.gif -------------------------------------------------------------------------------- /assets/libs/layer/images/loading-2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciey/NodeExpressAdmin/58bcc1941e803675e5b0a576a615b9f68d5586b7/assets/libs/layer/images/loading-2.gif -------------------------------------------------------------------------------- /assets/libs/layer/images/loading-3.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciey/NodeExpressAdmin/58bcc1941e803675e5b0a576a615b9f68d5586b7/assets/libs/layer/images/loading-3.gif -------------------------------------------------------------------------------- /assets/libs/moment/zh-cn.js: -------------------------------------------------------------------------------- 1 | //! moment.js locale configuration 2 | 3 | ;(function (global, factory) { 4 | typeof exports === 'object' && typeof module !== 'undefined' 5 | && typeof require === 'function' ? factory(require('../moment')) : 6 | typeof define === 'function' && define.amd ? define(['../moment'], factory) : 7 | factory(global.moment) 8 | }(this, (function (moment) { 'use strict'; 9 | 10 | 11 | var zhCn = moment.defineLocale('zh-cn', { 12 | months : '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split('_'), 13 | monthsShort : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'), 14 | weekdays : '星期日_星期一_星期二_星期三_星期四_星期五_星期六'.split('_'), 15 | weekdaysShort : '周日_周一_周二_周三_周四_周五_周六'.split('_'), 16 | weekdaysMin : '日_一_二_三_四_五_六'.split('_'), 17 | longDateFormat : { 18 | LT : 'HH:mm', 19 | LTS : 'HH:mm:ss', 20 | L : 'YYYY/MM/DD', 21 | LL : 'YYYY年M月D日', 22 | LLL : 'YYYY年M月D日Ah点mm分', 23 | LLLL : 'YYYY年M月D日ddddAh点mm分', 24 | l : 'YYYY/M/D', 25 | ll : 'YYYY年M月D日', 26 | lll : 'YYYY年M月D日 HH:mm', 27 | llll : 'YYYY年M月D日dddd HH:mm' 28 | }, 29 | meridiemParse: /凌晨|早上|上午|中午|下午|晚上/, 30 | meridiemHour: function (hour, meridiem) { 31 | if (hour === 12) { 32 | hour = 0; 33 | } 34 | if (meridiem === '凌晨' || meridiem === '早上' || 35 | meridiem === '上午') { 36 | return hour; 37 | } else if (meridiem === '下午' || meridiem === '晚上') { 38 | return hour + 12; 39 | } else { 40 | // '中午' 41 | return hour >= 11 ? hour : hour + 12; 42 | } 43 | }, 44 | meridiem : function (hour, minute, isLower) { 45 | var hm = hour * 100 + minute; 46 | if (hm < 600) { 47 | return '凌晨'; 48 | } else if (hm < 900) { 49 | return '早上'; 50 | } else if (hm < 1130) { 51 | return '上午'; 52 | } else if (hm < 1230) { 53 | return '中午'; 54 | } else if (hm < 1800) { 55 | return '下午'; 56 | } else { 57 | return '晚上'; 58 | } 59 | }, 60 | calendar : { 61 | sameDay : '[今天]LT', 62 | nextDay : '[明天]LT', 63 | nextWeek : '[下]ddddLT', 64 | lastDay : '[昨天]LT', 65 | lastWeek : '[上]ddddLT', 66 | sameElse : 'L' 67 | }, 68 | dayOfMonthOrdinalParse: /\d{1,2}(日|月|周)/, 69 | ordinal : function (number, period) { 70 | switch (period) { 71 | case 'd': 72 | case 'D': 73 | case 'DDD': 74 | return number + '日'; 75 | case 'M': 76 | return number + '月'; 77 | case 'w': 78 | case 'W': 79 | return number + '周'; 80 | default: 81 | return number; 82 | } 83 | }, 84 | relativeTime : { 85 | future : '%s内', 86 | past : '%s前', 87 | s : '几秒', 88 | ss : '%d 秒', 89 | m : '1 分钟', 90 | mm : '%d 分钟', 91 | h : '1 小时', 92 | hh : '%d 小时', 93 | d : '1 天', 94 | dd : '%d 天', 95 | M : '1 个月', 96 | MM : '%d 个月', 97 | y : '1 年', 98 | yy : '%d 年' 99 | }, 100 | week : { 101 | // GB/T 7408-1994《数据元和交换格式·信息交换·日期和时间表示法》与ISO 8601:1988等效 102 | dow : 1, // Monday is the first day of the week. 103 | doy : 4 // The week that contains Jan 4th is the first week of the year. 104 | } 105 | }); 106 | 107 | return zhCn; 108 | 109 | }))); 110 | -------------------------------------------------------------------------------- /assets/libs/select2/zh-CN.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.5 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/zh-CN",[],function(){return{errorLoading:function(){return"无法载入结果。"},inputTooLong:function(e){var t=e.input.length-e.maximum,n="请删除"+t+"个字符";return n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="请再输入至少"+t+"个字符";return n},loadingMore:function(){return"载入更多结果…"},maximumSelected:function(e){var t="最多只能选择"+e.maximum+"个项目";return t},noResults:function(){return"未找到结果"},searching:function(){return"搜索中…"}}}),{define:e.define,require:e.require}})(); 4 | -------------------------------------------------------------------------------- /assets/libs/zTree/css/zTreeStyle/img/diy/1_close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciey/NodeExpressAdmin/58bcc1941e803675e5b0a576a615b9f68d5586b7/assets/libs/zTree/css/zTreeStyle/img/diy/1_close.png -------------------------------------------------------------------------------- /assets/libs/zTree/css/zTreeStyle/img/diy/1_open.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciey/NodeExpressAdmin/58bcc1941e803675e5b0a576a615b9f68d5586b7/assets/libs/zTree/css/zTreeStyle/img/diy/1_open.png -------------------------------------------------------------------------------- /assets/libs/zTree/css/zTreeStyle/img/diy/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciey/NodeExpressAdmin/58bcc1941e803675e5b0a576a615b9f68d5586b7/assets/libs/zTree/css/zTreeStyle/img/diy/2.png -------------------------------------------------------------------------------- /assets/libs/zTree/css/zTreeStyle/img/diy/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciey/NodeExpressAdmin/58bcc1941e803675e5b0a576a615b9f68d5586b7/assets/libs/zTree/css/zTreeStyle/img/diy/3.png -------------------------------------------------------------------------------- /assets/libs/zTree/css/zTreeStyle/img/diy/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciey/NodeExpressAdmin/58bcc1941e803675e5b0a576a615b9f68d5586b7/assets/libs/zTree/css/zTreeStyle/img/diy/4.png -------------------------------------------------------------------------------- /assets/libs/zTree/css/zTreeStyle/img/diy/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciey/NodeExpressAdmin/58bcc1941e803675e5b0a576a615b9f68d5586b7/assets/libs/zTree/css/zTreeStyle/img/diy/5.png -------------------------------------------------------------------------------- /assets/libs/zTree/css/zTreeStyle/img/diy/6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciey/NodeExpressAdmin/58bcc1941e803675e5b0a576a615b9f68d5586b7/assets/libs/zTree/css/zTreeStyle/img/diy/6.png -------------------------------------------------------------------------------- /assets/libs/zTree/css/zTreeStyle/img/diy/7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciey/NodeExpressAdmin/58bcc1941e803675e5b0a576a615b9f68d5586b7/assets/libs/zTree/css/zTreeStyle/img/diy/7.png -------------------------------------------------------------------------------- /assets/libs/zTree/css/zTreeStyle/img/diy/8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciey/NodeExpressAdmin/58bcc1941e803675e5b0a576a615b9f68d5586b7/assets/libs/zTree/css/zTreeStyle/img/diy/8.png -------------------------------------------------------------------------------- /assets/libs/zTree/css/zTreeStyle/img/diy/9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciey/NodeExpressAdmin/58bcc1941e803675e5b0a576a615b9f68d5586b7/assets/libs/zTree/css/zTreeStyle/img/diy/9.png -------------------------------------------------------------------------------- /assets/libs/zTree/css/zTreeStyle/img/line_conn.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciey/NodeExpressAdmin/58bcc1941e803675e5b0a576a615b9f68d5586b7/assets/libs/zTree/css/zTreeStyle/img/line_conn.gif -------------------------------------------------------------------------------- /assets/libs/zTree/css/zTreeStyle/img/loading.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciey/NodeExpressAdmin/58bcc1941e803675e5b0a576a615b9f68d5586b7/assets/libs/zTree/css/zTreeStyle/img/loading.gif -------------------------------------------------------------------------------- /assets/libs/zTree/css/zTreeStyle/img/zTreeStandard.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciey/NodeExpressAdmin/58bcc1941e803675e5b0a576a615b9f68d5586b7/assets/libs/zTree/css/zTreeStyle/img/zTreeStandard.gif -------------------------------------------------------------------------------- /assets/libs/zTree/css/zTreeStyle/img/zTreeStandard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciey/NodeExpressAdmin/58bcc1941e803675e5b0a576a615b9f68d5586b7/assets/libs/zTree/css/zTreeStyle/img/zTreeStandard.png -------------------------------------------------------------------------------- /assets/libs/zTree/css/zTreeStyle/zTreeStyle.css: -------------------------------------------------------------------------------- 1 | /*------------------------------------- 2 | zTree Style 3 | 4 | version: 3.5.19 5 | author: Hunter.z 6 | email: hunter.z@263.net 7 | website: http://code.google.com/p/jquerytree/ 8 | 9 | -------------------------------------*/ 10 | 11 | .ztree * {padding:0; margin:0; font-size:12px; font-family: Verdana, Arial, Helvetica, AppleGothic, sans-serif} 12 | .ztree {margin:0; padding:5px; color:#333} 13 | .ztree li{padding:0; margin:0; list-style:none; line-height:14px; text-align:left; white-space:nowrap; outline:0} 14 | .ztree li ul{ margin:0; padding:0 0 0 18px} 15 | .ztree li ul.line{ background:url(./img/line_conn.gif) 0 0 repeat-y;} 16 | 17 | .ztree li a {padding:1px 3px 0 0; margin:0; cursor:pointer; height:17px; color:#333; background-color: transparent; 18 | text-decoration:none; vertical-align:top; display: inline-block} 19 | .ztree li a:hover {text-decoration:underline} 20 | .ztree li a.curSelectedNode {padding-top:0px; background-color:#FFE6B0; color:black; height:16px; border:1px #FFB951 solid; opacity:0.8;} 21 | .ztree li a.curSelectedNode_Edit {padding-top:0px; background-color:#FFE6B0; color:black; height:16px; border:1px #FFB951 solid; opacity:0.8;} 22 | .ztree li a.tmpTargetNode_inner {padding-top:0px; background-color:#316AC5; color:white; height:16px; border:1px #316AC5 solid; 23 | opacity:0.8; filter:alpha(opacity=80)} 24 | .ztree li a.tmpTargetNode_prev {} 25 | .ztree li a.tmpTargetNode_next {} 26 | .ztree li a input.rename {height:14px; width:80px; padding:0; margin:0; 27 | font-size:12px; border:1px #7EC4CC solid; *border:0px} 28 | .ztree li span {line-height:16px; margin-right:2px} 29 | .ztree li span.button {line-height:0; margin:0; width:16px; height:16px; display: inline-block; vertical-align:middle; 30 | border:0 none; cursor: pointer;outline:none; 31 | background-color:transparent; background-repeat:no-repeat; background-attachment: scroll; 32 | background-image:url("./img/zTreeStandard.png"); *background-image:url("./img/zTreeStandard.gif")} 33 | 34 | .ztree li span.button.chk {width:13px; height:13px; margin:0 3px 0 0; cursor: auto} 35 | .ztree li span.button.chk.checkbox_false_full {background-position:0 0} 36 | .ztree li span.button.chk.checkbox_false_full_focus {background-position:0 -14px} 37 | .ztree li span.button.chk.checkbox_false_part {background-position:0 -28px} 38 | .ztree li span.button.chk.checkbox_false_part_focus {background-position:0 -42px} 39 | .ztree li span.button.chk.checkbox_false_disable {background-position:0 -56px} 40 | .ztree li span.button.chk.checkbox_true_full {background-position:-14px 0} 41 | .ztree li span.button.chk.checkbox_true_full_focus {background-position:-14px -14px} 42 | .ztree li span.button.chk.checkbox_true_part {background-position:-14px -28px} 43 | .ztree li span.button.chk.checkbox_true_part_focus {background-position:-14px -42px} 44 | .ztree li span.button.chk.checkbox_true_disable {background-position:-14px -56px} 45 | .ztree li span.button.chk.radio_false_full {background-position:-28px 0} 46 | .ztree li span.button.chk.radio_false_full_focus {background-position:-28px -14px} 47 | .ztree li span.button.chk.radio_false_part {background-position:-28px -28px} 48 | .ztree li span.button.chk.radio_false_part_focus {background-position:-28px -42px} 49 | .ztree li span.button.chk.radio_false_disable {background-position:-28px -56px} 50 | .ztree li span.button.chk.radio_true_full {background-position:-42px 0} 51 | .ztree li span.button.chk.radio_true_full_focus {background-position:-42px -14px} 52 | .ztree li span.button.chk.radio_true_part {background-position:-42px -28px} 53 | .ztree li span.button.chk.radio_true_part_focus {background-position:-42px -42px} 54 | .ztree li span.button.chk.radio_true_disable {background-position:-42px -56px} 55 | 56 | .ztree li span.button.switch {width:18px; height:18px} 57 | .ztree li span.button.root_open{background-position:-92px -54px} 58 | .ztree li span.button.root_close{background-position:-74px -54px} 59 | .ztree li span.button.roots_open{background-position:-92px 0} 60 | .ztree li span.button.roots_close{background-position:-74px 0} 61 | .ztree li span.button.center_open{background-position:-92px -18px} 62 | .ztree li span.button.center_close{background-position:-74px -18px} 63 | .ztree li span.button.bottom_open{background-position:-92px -36px} 64 | .ztree li span.button.bottom_close{background-position:-74px -36px} 65 | .ztree li span.button.noline_open{background-position:-92px -72px} 66 | .ztree li span.button.noline_close{background-position:-74px -72px} 67 | .ztree li span.button.root_docu{ background:none;} 68 | .ztree li span.button.roots_docu{background-position:-56px 0} 69 | .ztree li span.button.center_docu{background-position:-56px -18px} 70 | .ztree li span.button.bottom_docu{background-position:-56px -36px} 71 | .ztree li span.button.noline_docu{ background:none;} 72 | 73 | .ztree li span.button.ico_open{margin-right:2px; background-position:-110px -16px; vertical-align:top; *vertical-align:middle} 74 | .ztree li span.button.ico_close{margin-right:2px; background-position:-110px 0; vertical-align:top; *vertical-align:middle} 75 | .ztree li span.button.ico_docu{margin-right:2px; background-position:-110px -32px; vertical-align:top; *vertical-align:middle} 76 | .ztree li span.button.edit {margin-right:2px; background-position:-110px -48px; vertical-align:top; *vertical-align:middle} 77 | .ztree li span.button.remove {margin-right:2px; background-position:-110px -64px; vertical-align:top; *vertical-align:middle} 78 | 79 | .ztree li span.button.ico_loading{margin-right:2px; background:url(./img/loading.gif) no-repeat scroll 0 0 transparent; vertical-align:top; *vertical-align:middle} 80 | 81 | ul.tmpTargetzTree {background-color:#FFE6B0; opacity:0.8; filter:alpha(opacity=80)} 82 | 83 | span.tmpzTreeMove_arrow {width:16px; height:16px; display: inline-block; padding:0; margin:2px 0 0 1px; border:0 none; position:absolute; 84 | background-color:transparent; background-repeat:no-repeat; background-attachment: scroll; 85 | background-position:-110px -80px; background-image:url("./img/zTreeStandard.png"); *background-image:url("./img/zTreeStandard.gif")} 86 | 87 | ul.ztree.zTreeDragUL {margin:0; padding:0; position:absolute; width:auto; height:auto;overflow:hidden; background-color:#cfcfcf; border:1px #00B83F dotted; opacity:0.8; filter:alpha(opacity=80)} 88 | .zTreeMask {z-index:10000; background-color:#cfcfcf; opacity:0.0; filter:alpha(opacity=0); position:absolute} 89 | 90 | /* level style*/ 91 | /*.ztree li span.button.level0 { 92 | display:none; 93 | } 94 | .ztree li ul.level0 { 95 | padding:0; 96 | background:none; 97 | }*/ -------------------------------------------------------------------------------- /common/logger.js: -------------------------------------------------------------------------------- 1 | const log4js = require('log4js'); 2 | 3 | log4js.configure({ 4 | appenders: { 5 | logfile: { 6 | type: 'dateFile', 7 | filename: 'logs/app.log', 8 | pattern: "yyyy-MM-dd", 9 | alwaysIncludePattern: true, 10 | keepFileExt: true 11 | }, 12 | display: { 13 | type: 'console' 14 | } 15 | }, 16 | categories: { 17 | default: { 18 | appenders: ['logfile', 'display'], 19 | level: 'DEBUG' 20 | } 21 | }, 22 | "pm2": true 23 | }); 24 | 25 | const logger = log4js.getLogger(); 26 | 27 | module.exports = logger; -------------------------------------------------------------------------------- /common/tool.js: -------------------------------------------------------------------------------- 1 | function resolvSelectJson(result, node) { 2 | const data = []; 3 | node.forEach(item => { 4 | let prefix = ""; 5 | for (let i = 0; i < item.level; i++) { 6 | prefix += "  "; 7 | } 8 | data.push({ 9 | id: item.id, 10 | name: prefix + item.name 11 | }) 12 | if (result[item.id]) { 13 | let ret = resolvSelectJson(result, result[item.id]); 14 | ret.forEach(item => { 15 | let prefix = ""; 16 | for (let i = 0; i < item.level; i++) { 17 | prefix += "  "; 18 | } 19 | data.push({ 20 | id: item.id, 21 | name: prefix + item.name 22 | }); 23 | }) 24 | } 25 | }); 26 | return data; 27 | } 28 | 29 | exports.resolvSelectJson = resolvSelectJson; -------------------------------------------------------------------------------- /config.default.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = { 4 | debug: true, 5 | host: 'localhost', 6 | port: 9000, 7 | session_secret: 'node_express_admin', 8 | site: { 9 | name: '后台权限管理系统', // 名称 10 | description: '后台权限管理系统', // 描述 11 | keywords: 'Node.js, Express', 12 | }, 13 | // sqldb 14 | sqldb: { 15 | db: 'mysql', 16 | host: '127.0.0.1', 17 | database: 'express_admin', 18 | username: 'root', 19 | password: '123456', 20 | timezone: '+08:00' //for writing to database 21 | }, 22 | // redis 23 | redis: { 24 | host: '127.0.0.1', 25 | port: 6379, 26 | db: 0, 27 | pass: '', 28 | } 29 | }; -------------------------------------------------------------------------------- /controller/login.js: -------------------------------------------------------------------------------- 1 | const _ = require('lodash'), 2 | crypto = require('crypto'), 3 | logger = require('../common/logger'), 4 | models = require('../models'), 5 | Op = models.Sequelize.Op; 6 | 7 | /** 登录注册相关 */ 8 | class loginController { 9 | 10 | /**登录页面 */ 11 | async showLogin(req, res, next) { 12 | res.render("login", {}); 13 | } 14 | 15 | /** 执行登录 */ 16 | async login(req, res, next) { 17 | let loginname = req.body.loginname; 18 | let password = req.body.password; 19 | const user = await models.user.findOne({ 20 | where: { 21 | login_name: loginname 22 | } 23 | }); 24 | if (user === null) { 25 | return res.send({ 26 | state: false, 27 | msg: "用户名或密码错误!" 28 | }) 29 | } 30 | if (user.is_enabled == 0) { 31 | return res.send({ 32 | state: false, 33 | msg: "禁止登录,请联系管理员!" 34 | }) 35 | } 36 | if (crypto.createHash('md5').update(password).digest('hex') === user.login_password) { 37 | req.session.user = user; 38 | 39 | const userPosition = await models.position.findAll({ 40 | where: { 41 | id: { 42 | [Op.in]: user.position_id.split(',') 43 | } 44 | }, 45 | }); 46 | let menuId = []; 47 | if (userPosition.length > 0) { 48 | userPosition.forEach(element => { 49 | menuId = _.union(menuId, element.menu_id.split(',')); 50 | }); 51 | } 52 | 53 | const userMenu = await models.menu.findAll({ 54 | where: { 55 | id: { 56 | [Op.in]: menuId 57 | 58 | }, 59 | is_enabled: 1, 60 | }, 61 | }); 62 | req.session.menu = userMenu; 63 | 64 | logger.info("用户:" + loginname + "登录成功!"); 65 | return res.send({ 66 | state: true, 67 | msg: "登录成功!" 68 | }) 69 | } else { 70 | return res.send({ 71 | state: false, 72 | msg: "用户名或密码错误!" 73 | }) 74 | } 75 | } 76 | 77 | /** 退出登录 */ 78 | async logout(req, res, next) { 79 | req.session.destroy(function() { 80 | res.redirect('/login'); 81 | }); 82 | } 83 | 84 | } 85 | 86 | module.exports = new loginController(); -------------------------------------------------------------------------------- /controller/main.js: -------------------------------------------------------------------------------- 1 | class mainController { 2 | async showMain(req, res, next) { 3 | res.render("main/index", { 4 | pageTitle: "主页" 5 | }); 6 | } 7 | } 8 | 9 | module.exports = new mainController(); -------------------------------------------------------------------------------- /dbsync.js: -------------------------------------------------------------------------------- 1 | const models = require('./models'); 2 | 3 | models.sequelize.sync({alter:true}).then(function(){ 4 | process.exit(); 5 | }); 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /middleware/auth.js: -------------------------------------------------------------------------------- 1 | class authMiddleware { 2 | /** 需要用户登录*/ 3 | async loginRequired(req, res, next) { 4 | if (!req.session || !req.session.user || !req.session.user.id) { 5 | return res.redirect('/login'); 6 | } 7 | await next(); 8 | } 9 | 10 | /** 用户鉴权*/ 11 | async authUserPermission(req, res, next) { 12 | if (!req.session || !req.session.user || !req.session.user.id) { 13 | return res.redirect('/login'); 14 | } 15 | if (!req.session || !req.session.menu || req.session.menu.length == 0) { 16 | return res.send('抱歉,您无此权限!请联系管理员'); 17 | } 18 | let targetUrl = req.route.path; 19 | let hasPower = false; 20 | req.session.menu.forEach(el => { 21 | if (el.page_url == targetUrl || el.control_url == targetUrl) { 22 | hasPower = true; 23 | } 24 | 25 | }); 26 | if (!hasPower) { 27 | if (req.xhr) { 28 | return res.json({ 29 | state: false, 30 | msg: "抱歉,您无此权限!请联系管理员" 31 | }); 32 | } 33 | 34 | return res.send('抱歉,您无此权限!请联系管理员'); 35 | } 36 | next(); 37 | } 38 | 39 | } 40 | 41 | module.exports = new authMiddleware(); -------------------------------------------------------------------------------- /middleware/requestLog.js: -------------------------------------------------------------------------------- 1 | const logger = require('../common/logger'); 2 | const ignore = /^\/(assets|agent)/; 3 | 4 | exports = module.exports = async (req, res, next) => { 5 | // Assets do not out log. 6 | if (ignore.test(req.url)) { 7 | await next(); 8 | return; 9 | } 10 | 11 | let t = new Date(); 12 | logger.info(req.method, req.url, req.ip); 13 | res.on('finish', () => { 14 | let duration = ((new Date()) - t); 15 | 16 | logger.info('Completed', res.statusCode, `(${duration} ms)`); 17 | }); 18 | 19 | await next(); 20 | }; 21 | 22 | -------------------------------------------------------------------------------- /models/branch.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | const moment = require('moment'); 3 | 4 | module.exports = (sequelize, DataTypes) => { 5 | let Branch = sequelize.define('branch', { 6 | id: { 7 | type: DataTypes.INTEGER, 8 | primaryKey: true, 9 | unique: true, 10 | autoIncrement: true 11 | }, 12 | /**部门名称 */ 13 | name: { 14 | type: DataTypes.STRING, 15 | allowNull: false, 16 | defaultValue: '' 17 | }, 18 | /**部门编码(第一级01,第二级0101,依次类推) */ 19 | code: { 20 | type: DataTypes.STRING, 21 | allowNull: false, 22 | defaultValue: 0 23 | }, 24 | /**上一级部门id */ 25 | parent_id: { 26 | type: DataTypes.INTEGER, 27 | allowNull: false, 28 | defaultValue: 0 29 | }, 30 | /**层级 */ 31 | level: { 32 | type: DataTypes.INTEGER, 33 | allowNull: false, 34 | defaultValue: 0 35 | }, 36 | /**排序 */ 37 | sort: { 38 | type: DataTypes.INTEGER, 39 | allowNull: false, 40 | defaultValue: 0 41 | }, 42 | createdAt: { 43 | type: DataTypes.DATE, 44 | get() { 45 | return moment(this.getDataValue('createdAt')).format('YYYY-MM-DD HH:mm:ss'); 46 | } 47 | }, 48 | updatedAt: { 49 | type: DataTypes.DATE, 50 | get() { 51 | return moment(this.getDataValue('updatedAt')).format('YYYY-MM-DD HH:mm:ss'); 52 | } 53 | } 54 | }, { 55 | freezeTableName: true, 56 | }); 57 | 58 | return Branch; 59 | }; -------------------------------------------------------------------------------- /models/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const _ = require('lodash'); 4 | const fs = require('fs'); 5 | const path = require('path'); 6 | const Sequelize = require('sequelize'); 7 | const basename = path.basename(__filename); 8 | const sqldb = require('../config').sqldb; 9 | const db = {}; 10 | 11 | // connect mysql on Sequelize 12 | var options = { 13 | host: sqldb.host, 14 | dialect: sqldb.db, 15 | port: _.isNil(sqldb.port) ? '3306' : sqldb.port, 16 | pool: { 17 | max: 5, 18 | min: 1, 19 | idle: 10000, 20 | } 21 | }; 22 | 23 | if(!_.isNil(sqldb.dialectOptions)){ 24 | options.dialectOptions = sqldb.dialectOptions; 25 | } 26 | if(!_.isNil(sqldb.timezone)){ 27 | options.timezone = sqldb.timezone; 28 | } 29 | 30 | const sequelize = new Sequelize(sqldb.database, sqldb.username, sqldb.password, options); 31 | 32 | fs 33 | .readdirSync(__dirname) 34 | .filter(file => { 35 | return (file.indexOf('.') !== 0) && (file !== basename) && (file.slice(-3) === '.js'); 36 | }) 37 | .forEach(file => { 38 | var model = sequelize['import'](path.join(__dirname, file)); 39 | db[model.name] = model; 40 | }); 41 | 42 | Object.keys(db).forEach(modelName => { 43 | if (db[modelName].associate) { 44 | db[modelName].associate(db); 45 | } 46 | }); 47 | 48 | db.sequelize = sequelize; 49 | db.Sequelize = Sequelize; 50 | 51 | module.exports = db; 52 | -------------------------------------------------------------------------------- /models/menu.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | const moment = require('moment'); 3 | 4 | module.exports = (sequelize, DataTypes) => { 5 | let Menu = sequelize.define('menu', { 6 | id: { 7 | type: DataTypes.INTEGER, 8 | primaryKey: true, 9 | unique: true, 10 | autoIncrement: true 11 | }, 12 | /**菜单名称 */ 13 | name: { 14 | type: DataTypes.STRING, 15 | allowNull: false, 16 | defaultValue: '' 17 | }, 18 | /**页面地址 */ 19 | page_url: { 20 | type: DataTypes.STRING, 21 | allowNull: false, 22 | defaultValue: '' 23 | }, 24 | /**控件地址 */ 25 | control_url: { 26 | type: DataTypes.STRING, 27 | allowNull: false, 28 | defaultValue: '' 29 | }, 30 | /**上一级菜单id */ 31 | parent_id: { 32 | type: DataTypes.INTEGER, 33 | allowNull: false, 34 | defaultValue: 0 35 | }, 36 | /**层级 */ 37 | level: { 38 | type: DataTypes.INTEGER, 39 | allowNull: false, 40 | defaultValue: 0 41 | }, 42 | /**排序 */ 43 | sort: { 44 | type: DataTypes.INTEGER, 45 | allowNull: false, 46 | defaultValue: 0 47 | }, 48 | /**图标 */ 49 | icon: { 50 | type: DataTypes.STRING, 51 | allowNull: false, 52 | defaultValue: '' 53 | }, 54 | /**是否显示:0否 1是*/ 55 | is_show: { 56 | type: DataTypes.TINYINT, 57 | allowNull: false, 58 | defaultValue: 1 59 | }, 60 | /**是否启用:0禁用 1正常*/ 61 | is_enabled: { 62 | type: DataTypes.TINYINT, 63 | allowNull: false, 64 | defaultValue: 1 65 | }, 66 | createdAt: { 67 | type: DataTypes.DATE, 68 | get() { 69 | return moment(this.getDataValue('createdAt')).format('YYYY-MM-DD HH:mm:ss'); 70 | } 71 | }, 72 | updatedAt: { 73 | type: DataTypes.DATE, 74 | get() { 75 | return moment(this.getDataValue('updatedAt')).format('YYYY-MM-DD HH:mm:ss'); 76 | } 77 | } 78 | }, { 79 | freezeTableName: true, 80 | }); 81 | 82 | return Menu; 83 | }; -------------------------------------------------------------------------------- /models/position.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | const moment = require('moment'); 3 | 4 | module.exports = (sequelize, DataTypes) => { 5 | let Position = sequelize.define('position', { 6 | id: { 7 | type: DataTypes.INTEGER, 8 | primaryKey: true, 9 | unique: true, 10 | autoIncrement: true 11 | }, 12 | /**职位名称 */ 13 | name: { 14 | type: DataTypes.STRING, 15 | allowNull: false, 16 | defaultValue: '' 17 | }, 18 | /**部门id(单个) */ 19 | branch_id: { 20 | type: DataTypes.STRING, 21 | allowNull: false, 22 | defaultValue: 0 23 | }, 24 | /**部门名称 */ 25 | branch_name: { 26 | type: DataTypes.STRING, 27 | allowNull: false, 28 | defaultValue: '' 29 | }, 30 | /**菜单权限集合(1,2,3,4) */ 31 | menu_id: { 32 | type: DataTypes.STRING, 33 | allowNull: false, 34 | defaultValue: '' 35 | }, 36 | createdAt: { 37 | type: DataTypes.DATE, 38 | get() { 39 | return moment(this.getDataValue('createdAt')).format('YYYY-MM-DD HH:mm:ss'); 40 | } 41 | }, 42 | updatedAt: { 43 | type: DataTypes.DATE, 44 | get() { 45 | return moment(this.getDataValue('updatedAt')).format('YYYY-MM-DD HH:mm:ss'); 46 | } 47 | } 48 | }, { 49 | freezeTableName: true, 50 | }); 51 | 52 | return Position; 53 | }; -------------------------------------------------------------------------------- /models/sql/express_admin_init.sql: -------------------------------------------------------------------------------- 1 | /* 2 | Navicat Premium Data Transfer 3 | 4 | Source Server : MySQL 5 | Source Server Type : MySQL 6 | Source Server Version : 50642 7 | Source Host : localhost:3306 8 | Source Schema : express_admin 9 | 10 | Target Server Type : MySQL 11 | Target Server Version : 50642 12 | File Encoding : 65001 13 | 14 | Date: 27/08/2019 13:41:22 15 | */ 16 | 17 | SET NAMES utf8mb4; 18 | SET FOREIGN_KEY_CHECKS = 0; 19 | 20 | -- ---------------------------- 21 | -- Table structure for branch 22 | -- ---------------------------- 23 | DROP TABLE IF EXISTS `branch`; 24 | CREATE TABLE `branch` ( 25 | `id` int(11) NOT NULL AUTO_INCREMENT, 26 | `name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '', 27 | `code` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '0', 28 | `parent_id` int(11) NOT NULL DEFAULT 0, 29 | `level` int(11) NOT NULL DEFAULT 0, 30 | `sort` int(11) NOT NULL DEFAULT 0, 31 | `createdAt` datetime(0) NULL DEFAULT NULL, 32 | `updatedAt` datetime(0) NULL DEFAULT NULL, 33 | PRIMARY KEY (`id`) USING BTREE, 34 | UNIQUE INDEX `id`(`id`) USING BTREE 35 | ) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact; 36 | 37 | -- ---------------------------- 38 | -- Records of branch 39 | -- ---------------------------- 40 | INSERT INTO `branch` VALUES (1, '科学研究有限公司', '01', 0, 0, 0, '2019-08-20 09:40:09', '2019-08-20 09:40:11'); 41 | INSERT INTO `branch` VALUES (2, '信息部', '0101', 1, 1, 0, '2019-08-20 09:40:13', '2019-08-20 09:40:15'); 42 | 43 | -- ---------------------------- 44 | -- Table structure for menu 45 | -- ---------------------------- 46 | DROP TABLE IF EXISTS `menu`; 47 | CREATE TABLE `menu` ( 48 | `id` int(11) NOT NULL AUTO_INCREMENT, 49 | `name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '', 50 | `page_url` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '', 51 | `control_url` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '', 52 | `parent_id` int(11) NOT NULL DEFAULT 0, 53 | `level` int(11) NOT NULL DEFAULT 0, 54 | `sort` int(11) NOT NULL DEFAULT 0, 55 | `icon` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '', 56 | `is_show` tinyint(4) NOT NULL DEFAULT 1, 57 | `is_enabled` tinyint(4) NOT NULL DEFAULT 1, 58 | `createdAt` datetime(0) NULL DEFAULT NULL, 59 | `updatedAt` datetime(0) NULL DEFAULT NULL, 60 | PRIMARY KEY (`id`) USING BTREE, 61 | UNIQUE INDEX `id`(`id`) USING BTREE 62 | ) ENGINE = InnoDB AUTO_INCREMENT = 15 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact; 63 | 64 | -- ---------------------------- 65 | -- Records of menu 66 | -- ---------------------------- 67 | INSERT INTO `menu` VALUES (1, '主页', '/main', '', 0, 0, 0, 'fa fa-desktop', 1, 1, '2019-08-20 09:39:10', '2019-08-20 09:39:13'); 68 | INSERT INTO `menu` VALUES (2, '系统管理', '', '', 0, 0, 0, 'fa fa-cog', 1, 1, '2019-08-20 09:39:15', '2019-08-20 09:39:17'); 69 | INSERT INTO `menu` VALUES (3, '用户管理', '/system/userList', '/system/getUserPage', 2, 1, 0, '', 1, 1, '2019-08-20 09:39:19', '2019-08-20 09:39:22'); 70 | INSERT INTO `menu` VALUES (4, '菜单管理', '/system/menuList', '/system/getMenuPage', 2, 1, 1, '', 1, 1, '2019-08-20 09:39:24', '2019-08-20 09:39:26'); 71 | INSERT INTO `menu` VALUES (5, '部门管理', '/system/branchList', '/system/getBranchPage', 2, 1, 2, '', 1, 1, '2019-08-20 09:39:29', '2019-08-20 09:39:31'); 72 | INSERT INTO `menu` VALUES (6, '职位管理', '/system/positionList', '/system/getPositionPage', 2, 1, 3, '', 1, 1, '2019-08-20 09:39:34', '2019-08-20 09:39:36'); 73 | INSERT INTO `menu` VALUES (7, '用户编辑', '', '/system/userEdit/:id', 3, 2, 0, '', 0, 1, '2019-08-20 09:39:38', '2019-08-20 09:39:40'); 74 | INSERT INTO `menu` VALUES (8, '用户删除', '', '/system/deleteUser/:id', 3, 2, 1, '', 0, 1, '2019-08-20 09:39:43', '2019-08-20 09:39:45'); 75 | INSERT INTO `menu` VALUES (9, '菜单编辑', '', '/system/menuEdit/:id', 4, 2, 0, '', 0, 1, '2019-08-20 09:39:48', '2019-08-20 09:39:50'); 76 | INSERT INTO `menu` VALUES (10, '菜单删除', '', '/system/deleteMenu/:id', 4, 2, 1, '', 0, 1, '2019-08-20 09:39:52', '2019-08-20 09:39:55'); 77 | INSERT INTO `menu` VALUES (11, '部门编辑', '', '/system/branchEdit/:id', 5, 2, 0, '', 0, 1, '2019-08-20 09:18:27', '2019-08-20 09:18:27'); 78 | INSERT INTO `menu` VALUES (12, '部门删除', '', '/system/deleteBranch/:id', 5, 2, 1, '', 0, 1, '2019-08-20 09:19:29', '2019-08-20 09:19:29'); 79 | INSERT INTO `menu` VALUES (13, '职位编辑', '', '/system/positionEdit/:id', 6, 2, 0, '', 0, 1, '2019-08-20 09:20:23', '2019-08-20 09:20:23'); 80 | INSERT INTO `menu` VALUES (14, '职位删除', '', '/system/deletePosition/:id', 6, 2, 1, '', 0, 1, '2019-08-20 09:20:50', '2019-08-20 09:20:50'); 81 | 82 | -- ---------------------------- 83 | -- Table structure for position 84 | -- ---------------------------- 85 | DROP TABLE IF EXISTS `position`; 86 | CREATE TABLE `position` ( 87 | `id` int(11) NOT NULL AUTO_INCREMENT, 88 | `name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '', 89 | `branch_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '0', 90 | `branch_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '', 91 | `menu_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '', 92 | `createdAt` datetime(0) NULL DEFAULT NULL, 93 | `updatedAt` datetime(0) NULL DEFAULT NULL, 94 | PRIMARY KEY (`id`) USING BTREE, 95 | UNIQUE INDEX `id`(`id`) USING BTREE 96 | ) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact; 97 | 98 | -- ---------------------------- 99 | -- Records of position 100 | -- ---------------------------- 101 | INSERT INTO `position` VALUES (1, '软件开发', '2', '信息部', '1,2,3,4,5,6,7,8,9,10,11,12,13,14', '2019-08-20 09:39:02', '2019-08-20 09:39:04'); 102 | INSERT INTO `position` VALUES (2, '软件测试', '2', '信息部', '1,2,3', '2019-08-20 09:42:24', '2019-08-20 09:44:09'); 103 | 104 | -- ---------------------------- 105 | -- Table structure for user 106 | -- ---------------------------- 107 | DROP TABLE IF EXISTS `user`; 108 | CREATE TABLE `user` ( 109 | `id` int(11) NOT NULL AUTO_INCREMENT, 110 | `login_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '', 111 | `login_password` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '', 112 | `real_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '', 113 | `position_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '0', 114 | `position_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '', 115 | `branch_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '0', 116 | `branch_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '', 117 | `mobile` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '', 118 | `is_enabled` tinyint(4) NOT NULL DEFAULT 1, 119 | `createdAt` datetime(0) NULL DEFAULT NULL, 120 | `updatedAt` datetime(0) NULL DEFAULT NULL, 121 | PRIMARY KEY (`id`) USING BTREE, 122 | UNIQUE INDEX `id`(`id`) USING BTREE 123 | ) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact; 124 | 125 | -- ---------------------------- 126 | -- Records of user 127 | -- ---------------------------- 128 | INSERT INTO `user` VALUES (1, 'admin', '21232f297a57a5a743894a0e4a801fc3', '管理员', '1', '软件开发', '2', '信息部', '15757288533', 1, '2019-08-20 09:38:53', '2019-08-20 09:38:56'); 129 | INSERT INTO `user` VALUES (2, 'test', '098f6bcd4621d373cade4e832627b4f6', '测试1', '2', '软件测试', '2', '信息部', '', 1, '2019-08-20 09:43:05', '2019-08-20 09:43:05'); 130 | 131 | SET FOREIGN_KEY_CHECKS = 1; 132 | -------------------------------------------------------------------------------- /models/user.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | const moment = require('moment'); 3 | 4 | module.exports = (sequelize, DataTypes) => { 5 | let User = sequelize.define('user', { 6 | id: { 7 | type: DataTypes.INTEGER, 8 | primaryKey: true, 9 | unique: true, 10 | autoIncrement: true 11 | }, 12 | /**登录用户名 */ 13 | login_name: { 14 | type: DataTypes.STRING, 15 | allowNull: false, 16 | defaultValue: '' 17 | }, 18 | /**登录密码 */ 19 | login_password: { 20 | type: DataTypes.STRING, 21 | allowNull: false, 22 | defaultValue: '' 23 | }, 24 | /**用户真实名称 */ 25 | real_name: { 26 | type: DataTypes.STRING, 27 | allowNull: false, 28 | defaultValue: '' 29 | }, 30 | /**职位id列表(1,2,3) */ 31 | position_id: { 32 | type: DataTypes.STRING, 33 | allowNull: false, 34 | defaultValue: 0 35 | }, 36 | /**职位名称列表(开发,总经理) */ 37 | position_name: { 38 | type: DataTypes.STRING, 39 | allowNull: false, 40 | defaultValue: '' 41 | }, 42 | /**部门id(单个) */ 43 | branch_id: { 44 | type: DataTypes.STRING, 45 | allowNull: false, 46 | defaultValue: 0 47 | }, 48 | /**部门名称 */ 49 | branch_name: { 50 | type: DataTypes.STRING, 51 | allowNull: false, 52 | defaultValue: '' 53 | }, 54 | /**手机号码 */ 55 | mobile: { 56 | type: DataTypes.STRING, 57 | allowNull: false, 58 | defaultValue: '' 59 | }, 60 | /**是否启用:0禁止访问 1正常*/ 61 | is_enabled: { 62 | type: DataTypes.TINYINT, 63 | allowNull: false, 64 | defaultValue: 1 65 | }, 66 | createdAt: { 67 | type: DataTypes.DATE, 68 | get() { 69 | return moment(this.getDataValue('createdAt')).format('YYYY-MM-DD HH:mm:ss'); 70 | } 71 | }, 72 | updatedAt: { 73 | type: DataTypes.DATE, 74 | get() { 75 | return moment(this.getDataValue('updatedAt')).format('YYYY-MM-DD HH:mm:ss'); 76 | } 77 | } 78 | }, { 79 | freezeTableName: true, 80 | }); 81 | 82 | return User; 83 | }; -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "seari-admin", 3 | "version": "1.0.0", 4 | "description": "后台权限管理系统", 5 | "private": true, 6 | "scripts": { 7 | "start": "node app.js" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git@github.com:ciey/NodeExpressAdmin.git" 12 | }, 13 | "keywords": [ 14 | "node.js", 15 | "express" 16 | ], 17 | "author": "ciey", 18 | "dependencies": { 19 | "body-parser": "^1.19.0", 20 | "compression": "^1.7.4", 21 | "connect-redis": "^3.4.2", 22 | "cookie-parser": "^1.4.4", 23 | "ejs-mate": "^3.0.0", 24 | "express": "^4.17.1", 25 | "express-async-errors": "^3.1.1", 26 | "express-session": "^1.16.2", 27 | "lodash": "^4.17.11", 28 | "log4js": "^5.0.0", 29 | "moment": "^2.24.0", 30 | "mysql": "^2.17.1", 31 | "mysql2": "^1.6.5", 32 | "sequelize": "^5.16.0" 33 | }, 34 | "devDependencies": {}, 35 | "engines": { 36 | "node": ">=8.0.0" 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /router.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | /** 3 | * router 主要用来描述请求 URL 和具体承担执行动作的 Controller 的对应关系, 4 | * 框架约定 router.js 文件用于统一所有路由规则。 5 | * 通过统一的配置,我们可以避免路由规则逻辑散落在多个地方,从而出现未知的冲突,集中在一起可以更方便的来查看全局的路由规则。 6 | */ 7 | const router = require('express').Router(), 8 | auth = require('./middleware/auth'), 9 | login = require('./controller/login'), 10 | system = require('./controller/system'), 11 | main = require('./controller/main'); 12 | 13 | //登录 14 | router.get('/login', login.showLogin); 15 | router.post('/login', login.login); 16 | router.get('/logout', login.logout); 17 | 18 | router.get('/main', auth.loginRequired, main.showMain); 19 | 20 | //用户管理 21 | router.get('/system/userList', auth.authUserPermission, system.showUserList); 22 | router.get('/system/getUserPage', auth.authUserPermission, system.getUserPage); 23 | router.get('/system/userEdit/:id', auth.authUserPermission, system.showUserEdit); 24 | router.post('/system/userEdit/:id', auth.authUserPermission, system.saveUserEdit); 25 | router.post('/system/deleteUser/:id', auth.authUserPermission, system.deleteUser); 26 | 27 | //菜单管理 28 | router.get('/system/menuList', auth.authUserPermission, system.showMenuList); 29 | router.get('/system/getMenuPage', auth.authUserPermission, system.getMenuPage); 30 | router.get('/system/menuEdit/:id', auth.authUserPermission, system.showMenuEdit); 31 | router.post('/system/menuEdit/:id', auth.authUserPermission, system.saveMenuEdit); 32 | router.post('/system/deleteMenu/:id', auth.authUserPermission, system.deleteMenu); 33 | router.get('/system/getMenuSelectJson', auth.loginRequired, system.getMenuSelectJson); 34 | router.get('/system/getMenuTreeJson', auth.loginRequired, system.getMenuTreeJson); 35 | router.get('/system/getMenuTreeJsonByUser', auth.loginRequired, system.getMenuTreeJsonByUser); 36 | 37 | //部门管理 38 | router.get('/system/branchList', auth.authUserPermission, system.showBranchList); 39 | router.get('/system/getBranchPage', auth.authUserPermission, system.getBranchPage); 40 | router.get('/system/branchEdit/:id', auth.authUserPermission, system.showBranchEdit); 41 | router.post('/system/branchEdit/:id', auth.authUserPermission, system.saveBranchEdit); 42 | router.post('/system/deleteBranch/:id', auth.authUserPermission, system.deleteBranch); 43 | router.get('/system/getBranchSelectJson', auth.loginRequired, system.getBranchSelectJson); 44 | router.get('/system/getBranchTreeJson', auth.loginRequired, system.getBranchTreeJson); 45 | 46 | //职位管理 47 | router.get('/system/positionList', auth.authUserPermission, system.showPositionList); 48 | router.get('/system/getPositionPage', auth.authUserPermission, system.getPositionPage); 49 | router.get('/system/positionEdit/:id', auth.authUserPermission, system.showPositionEdit); 50 | router.post('/system/positionEdit/:id', auth.authUserPermission, system.savePositionEdit); 51 | router.post('/system/deletePosition/:id', auth.authUserPermission, system.deletePosition); 52 | router.get('/system/getPositionTreeJson', auth.loginRequired, system.getPositionTreeJson); 53 | 54 | // 未找到路由 55 | router.use((req, res) => { 56 | res.render('404'); 57 | }); 58 | module.exports = router; //导出 -------------------------------------------------------------------------------- /views/404.ejs: -------------------------------------------------------------------------------- 1 | <% layout('layout-nologin') -%> 2 |
3 | Image 4 |

抱歉,您访问的页面不存在

5 | 6 |
7 | -------------------------------------------------------------------------------- /views/_partial/header.ejs: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /views/_partial/sidebar.ejs: -------------------------------------------------------------------------------- 1 | 22 | -------------------------------------------------------------------------------- /views/layout-form.ejs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | <%- body -%> 24 | 25 | -------------------------------------------------------------------------------- /views/layout-main.ejs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | <% if (site.keywords) { %> 10 | 11 | <% } %> 12 | <% if (site.description) { %> 13 | 14 | <% } %> 15 | 16 | 17 | 18 | <% if(typeof(pageTitle) !== 'undefined') { %> 19 | <%= pageTitle %> 20 | <% } else { %> 21 | <%= site.name %> 22 | <% } %> 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 50 | 51 | 52 | 53 |
54 | 55 | <%- partial('_partial/sidebar') %> 56 |
57 | 58 | <%- partial('_partial/header') %> 59 | 60 | <%- body -%> 61 | 65 |
66 |
67 | 68 | 69 | -------------------------------------------------------------------------------- /views/layout-nologin.ejs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | <% if(typeof(pageTitle) !== 'undefined') { %> 7 | <%= pageTitle %> 8 | <% } else { %> 9 | <%= site.name %> 10 | <% } %> 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | <%- body -%> 25 | 26 | -------------------------------------------------------------------------------- /views/login.ejs: -------------------------------------------------------------------------------- 1 | <% layout('layout-nologin') -%> 2 | 70 | 84 |
85 |
86 |
87 |
88 | 89 |
90 |
91 | 122 |
123 |
124 | 125 |
126 |
127 |
128 |

Copyright © ciey All Rights Reserved.

129 |
130 | -------------------------------------------------------------------------------- /views/main/index.ejs: -------------------------------------------------------------------------------- 1 | <% layout('layout-main') -%> 2 |
3 |
4 |

This is page content

5 |
6 | You can create here any grid layout you want. And any variation layout you imagine:) Check out main dashboard and other site. 7 | It use many different layout. 8 |
9 | Dashboard 10 |
11 |
12 |
-------------------------------------------------------------------------------- /views/system/branch-edit.ejs: -------------------------------------------------------------------------------- 1 | <% layout('layout-form') -%> 2 |
3 |
4 | <% if(typeof(action) !== 'undefined' && action == 'edit'){ %> 5 | 6 | <% }else{ %> 7 | 8 | <% } %> 9 | 10 | 11 | 12 | 16 | 17 | 18 | 19 | 26 | 27 | 28 | 29 | 33 | 34 | 35 | 36 | 40 | 41 | 42 |
* 部门名称 13 | 15 |
* 上级节点 20 | 22 | 25 |
部门编码 30 | 32 |
排序 37 | 39 |
43 | 44 | 45 |
46 |
47 | 48 | -------------------------------------------------------------------------------- /views/system/branch-list.ejs: -------------------------------------------------------------------------------- 1 | <% layout('layout-main') -%> 2 | 3 | 4 | 5 |
6 |
7 |
8 |
9 |
10 |
<%= typeof(pageTitle) !== 'undefined' && pageTitle || '部门管理' %>
11 |
12 |
13 |
14 | 15 |
16 |
17 |
18 |
19 | 20 |
21 |
22 |
23 | -------------------------------------------------------------------------------- /views/system/menu-edit.ejs: -------------------------------------------------------------------------------- 1 | <% layout('layout-form') -%> 2 |
3 |
4 | <% if(typeof(action) !== 'undefined' && action == 'edit'){ %> 5 | 6 | <% }else{ %> 7 | 8 | <% } %> 9 | 10 | 11 | 12 | 16 | 17 | 18 | 19 | 25 | 26 | 27 | 28 | 32 | 33 | 34 | 35 | 39 | 40 | 41 | 42 | 43 | 47 | 48 | 49 | 50 | 56 | 57 | 58 | 59 | 65 | 66 |
* 菜单名称 13 | 15 |
* 上级节点 20 | 21 | 24 |
菜单地址 29 | 31 |
控件地址 36 | 38 |
排序 44 | 46 |
是否显示 51 | 55 |
是否启用 60 | 64 |
67 | 68 | 69 |
70 |
71 | 72 | -------------------------------------------------------------------------------- /views/system/menu-list.ejs: -------------------------------------------------------------------------------- 1 | <% layout('layout-main') -%> 2 | 3 | 4 | 5 |
6 |
7 |
8 |
9 |
10 |
<%= typeof(pageTitle) !== 'undefined' && pageTitle || '菜单管理' %>
11 |
12 |
13 |
14 | 15 |
16 |
17 |
18 |
19 | 20 |
21 |
22 |
23 | -------------------------------------------------------------------------------- /views/system/position-edit.ejs: -------------------------------------------------------------------------------- 1 | <% layout('layout-form') -%> 2 | 3 | 4 |
5 |
6 | <% if(typeof(action) !== 'undefined' && action == 'edit'){ %> 7 | 8 | <% }else{ %> 9 | 10 | <% } %> 11 | 12 | 13 | 14 | 18 | 19 | 20 | 21 | 27 | 28 | 29 | 30 | 34 | 35 |
* 职位名称 15 | 17 |
* 所属部门 22 | 24 | 26 |
* 职位权限 31 | 32 |
    33 |
    36 | 37 | 38 |
    39 |
    40 | 41 | -------------------------------------------------------------------------------- /views/system/position-list.ejs: -------------------------------------------------------------------------------- 1 | <% layout('layout-main') -%> 2 | 3 | 4 |
    5 |
    6 |
    7 |
    8 |
    9 |
    部门列表
    10 |
    11 |
    12 |
    13 |
      14 |
      15 |
      16 |
      17 | 18 |
      19 |
      20 |
      21 |
      22 |
      <%= typeof(pageTitle) !== 'undefined' && pageTitle || '职位管理' %>
      23 |
      24 |
      25 |
      26 | 27 |
      28 |
      29 |
      30 |
      31 |
      32 |
      33 |
      34 | -------------------------------------------------------------------------------- /views/system/user-edit.ejs: -------------------------------------------------------------------------------- 1 | <% layout('layout-form') -%> 2 | 3 | 4 | 13 |
      14 |
      15 | <% if(typeof(action) !== 'undefined' && action == 'edit'){ %> 16 | 17 | <% }else{ %> 18 | 19 | <% } %> 20 | 21 | 22 | 23 | 27 | 28 | 29 | 30 | 37 | 38 | 39 | 40 | 46 | 47 | 48 | 49 | 56 | 57 | 58 | 59 | 60 | 64 | 65 | 66 | 67 | 71 | 72 | 73 | 74 | 84 | 85 |
      * 用户名 24 | 26 |
      * 登录密码 31 | <% if(typeof(action) !== 'undefined' && action == 'add'){ %> 32 | 33 | <% }else{ %> 34 | 35 | <% } %> 36 |
      所属部门 41 | 43 | 45 |
      职位 50 | 52 | 55 |
      真实名称 61 | 63 |
      手机号码 68 | 70 |
      是否启用 75 | 83 |
      86 |
      87 | 88 | 89 | 92 |
      93 | 94 | 95 | -------------------------------------------------------------------------------- /views/system/user-list.ejs: -------------------------------------------------------------------------------- 1 | <% layout('layout-main') -%> 2 |
      3 |
      4 |
      5 |
      6 |
      7 |
      <%= typeof(pageTitle) !== 'undefined' && pageTitle || '用户管理' %>
      8 |
      9 |
      10 |
      11 | 12 |
      13 |
      14 |
      15 |
      16 | 17 |
      18 |
      19 |
      20 | --------------------------------------------------------------------------------