├── front-end ├── static │ └── .gitkeep ├── start-server.bat ├── src │ ├── assets │ │ ├── cropper │ │ │ ├── src │ │ │ │ ├── js │ │ │ │ │ ├── outro.js │ │ │ │ │ ├── prototype.js │ │ │ │ │ ├── cropper.js │ │ │ │ │ ├── intro.js │ │ │ │ │ ├── plugin.js │ │ │ │ │ ├── listen.js │ │ │ │ │ ├── variables.js │ │ │ │ │ ├── load.js │ │ │ │ │ ├── template.js │ │ │ │ │ ├── defaults.js │ │ │ │ │ ├── preview.js │ │ │ │ │ ├── build.js │ │ │ │ │ └── utilities.js │ │ │ │ ├── img │ │ │ │ │ └── bg.png │ │ │ │ ├── less │ │ │ │ │ ├── cropper.less │ │ │ │ │ ├── variables.less │ │ │ │ │ ├── utilities.less │ │ │ │ │ └── mixins.less │ │ │ │ ├── .jshintrc │ │ │ │ ├── .csslintrc │ │ │ │ └── .jscsrc │ │ │ ├── related │ │ │ │ ├── 1.jpg │ │ │ │ └── 2.jpg │ │ │ ├── fonts │ │ │ │ ├── icomoon.eot │ │ │ │ ├── icomoon.ttf │ │ │ │ ├── icomoon.woff │ │ │ │ └── icomoon.svg │ │ │ ├── assets │ │ │ │ ├── img │ │ │ │ │ ├── icons.png │ │ │ │ │ ├── picture-2.jpg │ │ │ │ │ └── picture.jpg │ │ │ │ └── fonts │ │ │ │ │ ├── glyphicons-halflings-regular.eot │ │ │ │ │ ├── glyphicons-halflings-regular.ttf │ │ │ │ │ ├── glyphicons-halflings-regular.woff │ │ │ │ │ └── glyphicons-halflings-regular.woff2 │ │ │ ├── examples │ │ │ │ └── crop-avatar │ │ │ │ │ ├── img │ │ │ │ │ ├── loading.gif │ │ │ │ │ └── picture.jpg │ │ │ │ │ ├── README.md │ │ │ │ │ └── css │ │ │ │ │ └── main.css │ │ │ ├── readme.html │ │ │ └── css │ │ │ │ └── normalize.css │ │ ├── logo.png │ │ ├── img │ │ │ └── nopic.jpg │ │ ├── ace-master │ │ │ ├── images │ │ │ │ ├── pattern.jpg │ │ │ │ ├── avatars │ │ │ │ │ ├── user.jpg │ │ │ │ │ ├── avatar.png │ │ │ │ │ ├── avatar1.png │ │ │ │ │ ├── avatar2.png │ │ │ │ │ ├── avatar3.png │ │ │ │ │ ├── avatar4.png │ │ │ │ │ ├── avatar5.png │ │ │ │ │ └── profile-pic.jpg │ │ │ │ ├── email │ │ │ │ │ ├── email1.png │ │ │ │ │ ├── email2.png │ │ │ │ │ ├── email3.png │ │ │ │ │ └── email4.png │ │ │ │ ├── gallery │ │ │ │ │ ├── image-1.jpg │ │ │ │ │ ├── image-2.jpg │ │ │ │ │ ├── image-3.jpg │ │ │ │ │ ├── image-4.jpg │ │ │ │ │ ├── image-5.jpg │ │ │ │ │ ├── image-6.jpg │ │ │ │ │ ├── thumb-1.jpg │ │ │ │ │ ├── thumb-2.jpg │ │ │ │ │ ├── thumb-3.jpg │ │ │ │ │ ├── thumb-4.jpg │ │ │ │ │ ├── thumb-5.jpg │ │ │ │ │ └── thumb-6.jpg │ │ │ │ ├── meteorshower2.jpg │ │ │ │ ├── placeholder │ │ │ │ │ ├── 165x90.png │ │ │ │ │ ├── 255x150.png │ │ │ │ │ ├── 530x270.png │ │ │ │ │ └── 550x280.png │ │ │ │ └── bootstrap-colorpicker │ │ │ │ │ ├── hue.png │ │ │ │ │ ├── alpha.png │ │ │ │ │ ├── saturation.png │ │ │ │ │ ├── hue-horizontal.png │ │ │ │ │ └── alpha-horizontal.png │ │ │ ├── swf │ │ │ │ └── flashExport.swf │ │ │ ├── css │ │ │ │ ├── images │ │ │ │ │ ├── pattern.jpg │ │ │ │ │ └── meteorshower2.jpg │ │ │ │ ├── prettify.min.css │ │ │ │ ├── fonts.googleapis.com.css │ │ │ │ ├── bootstrap-multiselect.min.css │ │ │ │ ├── bootstrap-duallistbox.min.css │ │ │ │ ├── jquery.gritter.min.css │ │ │ │ ├── colorbox.min.css │ │ │ │ ├── jquery-ui.custom.min.css │ │ │ │ ├── bootstrap-timepicker.min.css │ │ │ │ └── bootstrap-colorpicker.min.css │ │ │ ├── fonts │ │ │ │ ├── glyphicons-halflings-regular.eot │ │ │ │ ├── glyphicons-halflings-regular.ttf │ │ │ │ ├── glyphicons-halflings-regular.woff │ │ │ │ └── glyphicons-halflings-regular.woff2 │ │ │ ├── font-awesome │ │ │ │ └── 4.5.0 │ │ │ │ │ └── fonts │ │ │ │ │ ├── fontawesome-webfont.eot │ │ │ │ │ ├── fontawesome-webfont.ttf │ │ │ │ │ ├── fontawesome-webfont.woff │ │ │ │ │ └── fontawesome-webfont.woff2 │ │ │ └── js │ │ │ │ ├── jquery.ui.touch-punch.min.js │ │ │ │ ├── buttons.print.min.js │ │ │ │ ├── jquery.hotkeys.index.min.js │ │ │ │ ├── jquery.flot.resize.min.js │ │ │ │ ├── buttons.colVis.min.js │ │ │ │ ├── html5shiv.min.js │ │ │ │ ├── autosize.min.js │ │ │ │ ├── bootstrap-wysiwyg.min.js │ │ │ │ ├── jquery.dataTables.bootstrap.min.js │ │ │ │ ├── grid.locale-en.js │ │ │ │ └── jquery.easypiechart.min.js │ │ ├── menu-mapping.json │ │ ├── strings.json │ │ ├── menu.json │ │ ├── form.json │ │ └── introduce.md │ ├── config │ │ ├── server.js │ │ ├── cookieOpts.js │ │ └── ajaxSetup.js │ ├── store │ │ └── index.js │ ├── Building.vue │ ├── components │ │ ├── _blank.vue │ │ ├── waiter.vue │ │ ├── main │ │ │ ├── news.vue │ │ │ ├── information-profile.vue │ │ │ ├── person-data.vue │ │ │ └── information-management.vue │ │ ├── back-to-top.vue │ │ ├── widget │ │ │ ├── markdown-preview.vue │ │ │ ├── confirm-dialog-body.vue │ │ │ ├── profile-list.vue │ │ │ ├── confirm-dialog.vue │ │ │ └── btn-multiple.vue │ │ ├── sidebar-item.vue │ │ ├── navbar.vue │ │ ├── main.vue │ │ ├── breadcrumbs.vue │ │ └── theme-setter.vue │ ├── utils │ │ ├── toast.min.js │ │ ├── cryption.js │ │ ├── UserInput.js │ │ └── util.js │ ├── main.js │ └── App.vue ├── .eslintignore ├── config │ ├── prod.env.js │ ├── dev.env.js │ └── index.js ├── .editorconfig ├── .gitignore ├── .postcssrc.js ├── build │ ├── dev-client.js │ ├── vue-loader.conf.js │ ├── build.js │ ├── check-versions.js │ ├── webpack.dev.conf.js │ ├── utils.js │ ├── webpack.base.conf.js │ └── dev-server.js ├── index.html ├── .babelrc ├── README.md ├── .eslintrc.js └── package.json ├── back-end ├── nodemon.cmd ├── config │ ├── client.js │ ├── db.js │ ├── session.js │ └── api.json ├── permission ├── package.json ├── service │ ├── department.js │ ├── permisson.js │ ├── article.js │ └── user.js ├── db │ ├── permDao.js │ ├── deptDao.js │ ├── pool.js │ ├── testDao.js │ └── articleDao.js ├── app.js ├── m.js ├── util │ ├── cryption.js │ └── util.js ├── db.sql └── routes │ └── index.js ├── .gitignore ├── .gitattributes ├── img ├── 001.gif ├── 002.gif ├── 003.gif ├── 004.gif ├── 005.gif └── dir.png └── api.md /front-end/static/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /back-end/nodemon.cmd: -------------------------------------------------------------------------------- 1 | nodemon app.js -------------------------------------------------------------------------------- /front-end/start-server.bat: -------------------------------------------------------------------------------- 1 | npm start -------------------------------------------------------------------------------- /front-end/src/assets/cropper/src/js/outro.js: -------------------------------------------------------------------------------- 1 | }); 2 | -------------------------------------------------------------------------------- /front-end/.eslintignore: -------------------------------------------------------------------------------- 1 | build/*.js 2 | config/*.js 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | dist/ 2 | test/ 3 | node_modules/ 4 | log/ 5 | *.log -------------------------------------------------------------------------------- /back-end/config/client.js: -------------------------------------------------------------------------------- 1 | module.exports = 'http://localhost:8888' -------------------------------------------------------------------------------- /front-end/src/config/server.js: -------------------------------------------------------------------------------- 1 | module.exports = 'http://localhost/api' 2 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto -------------------------------------------------------------------------------- /front-end/config/prod.env.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | NODE_ENV: '"production"' 3 | } 4 | -------------------------------------------------------------------------------- /img/001.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wztscau/StudentManagementSystem/HEAD/img/001.gif -------------------------------------------------------------------------------- /img/002.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wztscau/StudentManagementSystem/HEAD/img/002.gif -------------------------------------------------------------------------------- /img/003.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wztscau/StudentManagementSystem/HEAD/img/003.gif -------------------------------------------------------------------------------- /img/004.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wztscau/StudentManagementSystem/HEAD/img/004.gif -------------------------------------------------------------------------------- /img/005.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wztscau/StudentManagementSystem/HEAD/img/005.gif -------------------------------------------------------------------------------- /img/dir.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wztscau/StudentManagementSystem/HEAD/img/dir.png -------------------------------------------------------------------------------- /front-end/src/assets/cropper/src/js/prototype.js: -------------------------------------------------------------------------------- 1 | $.extend(Cropper.prototype, prototype); 2 | -------------------------------------------------------------------------------- /back-end/permission: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wztscau/StudentManagementSystem/HEAD/back-end/permission -------------------------------------------------------------------------------- /front-end/src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wztscau/StudentManagementSystem/HEAD/front-end/src/assets/logo.png -------------------------------------------------------------------------------- /front-end/src/assets/img/nopic.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wztscau/StudentManagementSystem/HEAD/front-end/src/assets/img/nopic.jpg -------------------------------------------------------------------------------- /front-end/src/config/cookieOpts.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | _name: { 3 | user: 'UserInfo', 4 | remem: 'remem' 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /front-end/src/assets/cropper/related/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wztscau/StudentManagementSystem/HEAD/front-end/src/assets/cropper/related/1.jpg -------------------------------------------------------------------------------- /front-end/src/assets/cropper/related/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wztscau/StudentManagementSystem/HEAD/front-end/src/assets/cropper/related/2.jpg -------------------------------------------------------------------------------- /front-end/src/assets/cropper/src/img/bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wztscau/StudentManagementSystem/HEAD/front-end/src/assets/cropper/src/img/bg.png -------------------------------------------------------------------------------- /front-end/src/assets/cropper/fonts/icomoon.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wztscau/StudentManagementSystem/HEAD/front-end/src/assets/cropper/fonts/icomoon.eot -------------------------------------------------------------------------------- /front-end/src/assets/cropper/fonts/icomoon.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wztscau/StudentManagementSystem/HEAD/front-end/src/assets/cropper/fonts/icomoon.ttf -------------------------------------------------------------------------------- /front-end/src/assets/cropper/fonts/icomoon.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wztscau/StudentManagementSystem/HEAD/front-end/src/assets/cropper/fonts/icomoon.woff -------------------------------------------------------------------------------- /front-end/src/assets/ace-master/images/pattern.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wztscau/StudentManagementSystem/HEAD/front-end/src/assets/ace-master/images/pattern.jpg -------------------------------------------------------------------------------- /front-end/src/assets/cropper/assets/img/icons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wztscau/StudentManagementSystem/HEAD/front-end/src/assets/cropper/assets/img/icons.png -------------------------------------------------------------------------------- /front-end/src/assets/ace-master/swf/flashExport.swf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wztscau/StudentManagementSystem/HEAD/front-end/src/assets/ace-master/swf/flashExport.swf -------------------------------------------------------------------------------- /front-end/src/assets/cropper/assets/img/picture-2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wztscau/StudentManagementSystem/HEAD/front-end/src/assets/cropper/assets/img/picture-2.jpg -------------------------------------------------------------------------------- /front-end/src/assets/cropper/assets/img/picture.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wztscau/StudentManagementSystem/HEAD/front-end/src/assets/cropper/assets/img/picture.jpg -------------------------------------------------------------------------------- /front-end/src/assets/ace-master/css/images/pattern.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wztscau/StudentManagementSystem/HEAD/front-end/src/assets/ace-master/css/images/pattern.jpg -------------------------------------------------------------------------------- /front-end/src/assets/ace-master/images/avatars/user.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wztscau/StudentManagementSystem/HEAD/front-end/src/assets/ace-master/images/avatars/user.jpg -------------------------------------------------------------------------------- /front-end/src/assets/ace-master/images/email/email1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wztscau/StudentManagementSystem/HEAD/front-end/src/assets/ace-master/images/email/email1.png -------------------------------------------------------------------------------- /front-end/src/assets/ace-master/images/email/email2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wztscau/StudentManagementSystem/HEAD/front-end/src/assets/ace-master/images/email/email2.png -------------------------------------------------------------------------------- /front-end/src/assets/ace-master/images/email/email3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wztscau/StudentManagementSystem/HEAD/front-end/src/assets/ace-master/images/email/email3.png -------------------------------------------------------------------------------- /front-end/src/assets/ace-master/images/email/email4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wztscau/StudentManagementSystem/HEAD/front-end/src/assets/ace-master/images/email/email4.png -------------------------------------------------------------------------------- /back-end/config/db.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | host: 'localhost', 3 | port: '3306', 4 | database: 'test', 5 | user: 'root', 6 | password: '123456', 7 | connectTimeout: 10000 8 | } -------------------------------------------------------------------------------- /front-end/src/assets/ace-master/images/avatars/avatar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wztscau/StudentManagementSystem/HEAD/front-end/src/assets/ace-master/images/avatars/avatar.png -------------------------------------------------------------------------------- /front-end/src/assets/ace-master/images/avatars/avatar1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wztscau/StudentManagementSystem/HEAD/front-end/src/assets/ace-master/images/avatars/avatar1.png -------------------------------------------------------------------------------- /front-end/src/assets/ace-master/images/avatars/avatar2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wztscau/StudentManagementSystem/HEAD/front-end/src/assets/ace-master/images/avatars/avatar2.png -------------------------------------------------------------------------------- /front-end/src/assets/ace-master/images/avatars/avatar3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wztscau/StudentManagementSystem/HEAD/front-end/src/assets/ace-master/images/avatars/avatar3.png -------------------------------------------------------------------------------- /front-end/src/assets/ace-master/images/avatars/avatar4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wztscau/StudentManagementSystem/HEAD/front-end/src/assets/ace-master/images/avatars/avatar4.png -------------------------------------------------------------------------------- /front-end/src/assets/ace-master/images/avatars/avatar5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wztscau/StudentManagementSystem/HEAD/front-end/src/assets/ace-master/images/avatars/avatar5.png -------------------------------------------------------------------------------- /front-end/src/assets/ace-master/images/gallery/image-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wztscau/StudentManagementSystem/HEAD/front-end/src/assets/ace-master/images/gallery/image-1.jpg -------------------------------------------------------------------------------- /front-end/src/assets/ace-master/images/gallery/image-2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wztscau/StudentManagementSystem/HEAD/front-end/src/assets/ace-master/images/gallery/image-2.jpg -------------------------------------------------------------------------------- /front-end/src/assets/ace-master/images/gallery/image-3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wztscau/StudentManagementSystem/HEAD/front-end/src/assets/ace-master/images/gallery/image-3.jpg -------------------------------------------------------------------------------- /front-end/src/assets/ace-master/images/gallery/image-4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wztscau/StudentManagementSystem/HEAD/front-end/src/assets/ace-master/images/gallery/image-4.jpg -------------------------------------------------------------------------------- /front-end/src/assets/ace-master/images/gallery/image-5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wztscau/StudentManagementSystem/HEAD/front-end/src/assets/ace-master/images/gallery/image-5.jpg -------------------------------------------------------------------------------- /front-end/src/assets/ace-master/images/gallery/image-6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wztscau/StudentManagementSystem/HEAD/front-end/src/assets/ace-master/images/gallery/image-6.jpg -------------------------------------------------------------------------------- /front-end/src/assets/ace-master/images/gallery/thumb-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wztscau/StudentManagementSystem/HEAD/front-end/src/assets/ace-master/images/gallery/thumb-1.jpg -------------------------------------------------------------------------------- /front-end/src/assets/ace-master/images/gallery/thumb-2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wztscau/StudentManagementSystem/HEAD/front-end/src/assets/ace-master/images/gallery/thumb-2.jpg -------------------------------------------------------------------------------- /front-end/src/assets/ace-master/images/gallery/thumb-3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wztscau/StudentManagementSystem/HEAD/front-end/src/assets/ace-master/images/gallery/thumb-3.jpg -------------------------------------------------------------------------------- /front-end/src/assets/ace-master/images/gallery/thumb-4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wztscau/StudentManagementSystem/HEAD/front-end/src/assets/ace-master/images/gallery/thumb-4.jpg -------------------------------------------------------------------------------- /front-end/src/assets/ace-master/images/gallery/thumb-5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wztscau/StudentManagementSystem/HEAD/front-end/src/assets/ace-master/images/gallery/thumb-5.jpg -------------------------------------------------------------------------------- /front-end/src/assets/ace-master/images/gallery/thumb-6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wztscau/StudentManagementSystem/HEAD/front-end/src/assets/ace-master/images/gallery/thumb-6.jpg -------------------------------------------------------------------------------- /front-end/src/assets/ace-master/images/meteorshower2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wztscau/StudentManagementSystem/HEAD/front-end/src/assets/ace-master/images/meteorshower2.jpg -------------------------------------------------------------------------------- /front-end/src/assets/ace-master/css/images/meteorshower2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wztscau/StudentManagementSystem/HEAD/front-end/src/assets/ace-master/css/images/meteorshower2.jpg -------------------------------------------------------------------------------- /front-end/config/dev.env.js: -------------------------------------------------------------------------------- 1 | var merge = require('webpack-merge') 2 | var prodEnv = require('./prod.env') 3 | 4 | module.exports = merge(prodEnv, { 5 | NODE_ENV: '"development"' 6 | }) 7 | -------------------------------------------------------------------------------- /front-end/src/assets/ace-master/images/avatars/profile-pic.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wztscau/StudentManagementSystem/HEAD/front-end/src/assets/ace-master/images/avatars/profile-pic.jpg -------------------------------------------------------------------------------- /front-end/src/assets/ace-master/images/placeholder/165x90.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wztscau/StudentManagementSystem/HEAD/front-end/src/assets/ace-master/images/placeholder/165x90.png -------------------------------------------------------------------------------- /front-end/src/assets/ace-master/images/placeholder/255x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wztscau/StudentManagementSystem/HEAD/front-end/src/assets/ace-master/images/placeholder/255x150.png -------------------------------------------------------------------------------- /front-end/src/assets/ace-master/images/placeholder/530x270.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wztscau/StudentManagementSystem/HEAD/front-end/src/assets/ace-master/images/placeholder/530x270.png -------------------------------------------------------------------------------- /front-end/src/assets/ace-master/images/placeholder/550x280.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wztscau/StudentManagementSystem/HEAD/front-end/src/assets/ace-master/images/placeholder/550x280.png -------------------------------------------------------------------------------- /front-end/src/assets/cropper/examples/crop-avatar/img/loading.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wztscau/StudentManagementSystem/HEAD/front-end/src/assets/cropper/examples/crop-avatar/img/loading.gif -------------------------------------------------------------------------------- /front-end/src/assets/cropper/examples/crop-avatar/img/picture.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wztscau/StudentManagementSystem/HEAD/front-end/src/assets/cropper/examples/crop-avatar/img/picture.jpg -------------------------------------------------------------------------------- /front-end/src/assets/ace-master/images/bootstrap-colorpicker/hue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wztscau/StudentManagementSystem/HEAD/front-end/src/assets/ace-master/images/bootstrap-colorpicker/hue.png -------------------------------------------------------------------------------- /front-end/src/assets/ace-master/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wztscau/StudentManagementSystem/HEAD/front-end/src/assets/ace-master/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /front-end/src/assets/ace-master/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wztscau/StudentManagementSystem/HEAD/front-end/src/assets/ace-master/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /front-end/src/assets/ace-master/images/bootstrap-colorpicker/alpha.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wztscau/StudentManagementSystem/HEAD/front-end/src/assets/ace-master/images/bootstrap-colorpicker/alpha.png -------------------------------------------------------------------------------- /front-end/src/assets/ace-master/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wztscau/StudentManagementSystem/HEAD/front-end/src/assets/ace-master/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /front-end/src/assets/ace-master/fonts/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wztscau/StudentManagementSystem/HEAD/front-end/src/assets/ace-master/fonts/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /front-end/.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | -------------------------------------------------------------------------------- /front-end/src/assets/ace-master/images/bootstrap-colorpicker/saturation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wztscau/StudentManagementSystem/HEAD/front-end/src/assets/ace-master/images/bootstrap-colorpicker/saturation.png -------------------------------------------------------------------------------- /front-end/src/assets/cropper/assets/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wztscau/StudentManagementSystem/HEAD/front-end/src/assets/cropper/assets/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /front-end/src/assets/cropper/assets/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wztscau/StudentManagementSystem/HEAD/front-end/src/assets/cropper/assets/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /front-end/src/assets/cropper/assets/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wztscau/StudentManagementSystem/HEAD/front-end/src/assets/cropper/assets/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /front-end/src/assets/cropper/assets/fonts/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wztscau/StudentManagementSystem/HEAD/front-end/src/assets/cropper/assets/fonts/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /front-end/src/assets/ace-master/font-awesome/4.5.0/fonts/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wztscau/StudentManagementSystem/HEAD/front-end/src/assets/ace-master/font-awesome/4.5.0/fonts/fontawesome-webfont.eot -------------------------------------------------------------------------------- /front-end/src/assets/ace-master/font-awesome/4.5.0/fonts/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wztscau/StudentManagementSystem/HEAD/front-end/src/assets/ace-master/font-awesome/4.5.0/fonts/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /front-end/src/assets/ace-master/images/bootstrap-colorpicker/hue-horizontal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wztscau/StudentManagementSystem/HEAD/front-end/src/assets/ace-master/images/bootstrap-colorpicker/hue-horizontal.png -------------------------------------------------------------------------------- /front-end/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules/ 3 | dist/ 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Editor directories and files 9 | .idea 10 | *.suo 11 | *.ntvs* 12 | *.njsproj 13 | *.sln 14 | -------------------------------------------------------------------------------- /front-end/src/assets/ace-master/font-awesome/4.5.0/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wztscau/StudentManagementSystem/HEAD/front-end/src/assets/ace-master/font-awesome/4.5.0/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /front-end/src/assets/ace-master/font-awesome/4.5.0/fonts/fontawesome-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wztscau/StudentManagementSystem/HEAD/front-end/src/assets/ace-master/font-awesome/4.5.0/fonts/fontawesome-webfont.woff2 -------------------------------------------------------------------------------- /front-end/src/assets/ace-master/images/bootstrap-colorpicker/alpha-horizontal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wztscau/StudentManagementSystem/HEAD/front-end/src/assets/ace-master/images/bootstrap-colorpicker/alpha-horizontal.png -------------------------------------------------------------------------------- /front-end/.postcssrc.js: -------------------------------------------------------------------------------- 1 | // https://github.com/michael-ciniawsky/postcss-load-config 2 | 3 | module.exports = { 4 | "plugins": { 5 | // to edit target browsers: use "browserslist" field in package.json 6 | "autoprefixer": {} 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /back-end/config/session.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | secret: 'e831b0e9ac1e767a370ec0d115dae4a1084499e9737a93ebb88573ce0f6eccee633b7ef2a78c4722eea5b86668aae9aad64950ed62f9d697dbac482ab1d07721', 3 | cookie: { maxAge: 1000*60*60*24 * 2 }, 4 | resave: false, 5 | saveUninitialized: true 6 | } -------------------------------------------------------------------------------- /back-end/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "bluebird": "^3.5.0", 4 | "body-parser": "^1.17.2", 5 | "cookie-parser": "^1.4.3", 6 | "express": "^4.15.3", 7 | "express-session": "^1.15.5", 8 | "jquery": "^3.2.1", 9 | "mysql": "^2.14.0" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /front-end/build/dev-client.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | require('eventsource-polyfill') 3 | var hotClient = require('webpack-hot-middleware/client?noInfo=true&reload=true') 4 | 5 | hotClient.subscribe(function (event) { 6 | if (event.action === 'reload') { 7 | window.location.reload() 8 | } 9 | }) 10 | -------------------------------------------------------------------------------- /front-end/src/assets/cropper/examples/crop-avatar/README.md: -------------------------------------------------------------------------------- 1 | # Crop Avatar 2 | 3 | A complete example of Cropper. 4 | 5 | 6 | ## Server Dependencies 7 | 8 | - PHP 5.5+ 9 | 10 | 11 | ## Browser Support 12 | 13 | - Chrome 38+ 14 | - Firefox 33+ 15 | - Internet Explorer 8+ 16 | - Opera 25+ 17 | - Safari 5.1+ 18 | -------------------------------------------------------------------------------- /front-end/src/assets/cropper/src/less/cropper.less: -------------------------------------------------------------------------------- 1 | /*! 2 | * Cropper v@VERSION 3 | * https://github.com/fengyuanchen/cropper 4 | * 5 | * Copyright (c) 2014-@YEAR Fengyuan Chen and contributors 6 | * Released under the MIT license 7 | * 8 | * Date: @DATE 9 | */ 10 | 11 | @import "variables.less"; 12 | @import "mixins.less"; 13 | @import "main.less"; 14 | @import "utilities.less"; 15 | -------------------------------------------------------------------------------- /front-end/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 学生管理系统 8 | 9 | 10 |
11 | 12 | 13 | -------------------------------------------------------------------------------- /front-end/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | ["env", { 4 | "modules": false, 5 | "targets": { 6 | "browsers": ["> 1%", "last 2 versions", "not ie <= 8"] 7 | } 8 | }], 9 | "stage-2" 10 | ], 11 | "plugins": ["transform-runtime"], 12 | "env": { 13 | "test": { 14 | "presets": ["env", "stage-2"], 15 | "plugins": ["istanbul"] 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /front-end/src/store/index.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuzitao 3 | * @Date: 2017-08-14 13:25:39 4 | * @Last Modified time: 2017-08-15 22:39:46 5 | */ 6 | import Vue from 'vue' 7 | import Vuex from 'vuex' 8 | import personData from '../components/main/person-data.vue' 9 | import navbar from '../components/navbar.vue' 10 | 11 | Vue.use(Vuex) 12 | export default new Vuex.Store({ 13 | modules: { 14 | navbar 15 | } 16 | }) 17 | -------------------------------------------------------------------------------- /front-end/src/Building.vue: -------------------------------------------------------------------------------- 1 | 6 | 11 | 12 | 22 | 23 | -------------------------------------------------------------------------------- /front-end/src/assets/cropper/src/js/cropper.js: -------------------------------------------------------------------------------- 1 | function Cropper(element, options) { 2 | this.$element = $(element); 3 | this.options = $.extend({}, Cropper.DEFAULTS, $.isPlainObject(options) && options); 4 | 5 | this.ready = false; 6 | this.built = false; 7 | this.rotated = false; 8 | this.cropped = false; 9 | this.disabled = false; 10 | this.canvas = null; 11 | this.cropBox = null; 12 | 13 | this.load(); 14 | } 15 | -------------------------------------------------------------------------------- /front-end/src/config/ajaxSetup.js: -------------------------------------------------------------------------------- 1 | const $ = require('jquery') 2 | const toast = require('../utils/toast.min.js') 3 | module.exports = { 4 | timeout: 10000, 5 | beforeSend () { 6 | $('#waiter').css('display', 'flex') 7 | }, 8 | error (err) { 9 | const errText = err.statusText 10 | switch (errText.toLowerCase()) { 11 | case 'timeout': toast('连接超时,请稍后重试') 12 | break 13 | } 14 | }, 15 | complete () { 16 | $('#waiter').hide() 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /front-end/build/vue-loader.conf.js: -------------------------------------------------------------------------------- 1 | var utils = require('./utils') 2 | var config = require('../config') 3 | var isProduction = process.env.NODE_ENV === 'production' 4 | 5 | module.exports = { 6 | loaders: utils.cssLoaders({ 7 | sourceMap: isProduction 8 | ? config.build.productionSourceMap 9 | : config.dev.cssSourceMap, 10 | extract: isProduction 11 | }), 12 | transformToRequire: { 13 | video: 'src', 14 | source: 'src', 15 | img: 'src', 16 | image: 'xlink:href' 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /front-end/src/assets/menu-mapping.json: -------------------------------------------------------------------------------- 1 | { 2 | "news": "最新动态", 3 | "person": "个人信息管理", 4 | "password": "修改密码", 5 | "headimg": "上传头像", 6 | "account": "账户录入/管理", 7 | "information": "信息录入", 8 | "maccount": "管理账户", 9 | "programmer": "程序员世界", 10 | "publish": "发表新文章", 11 | "article": "文章管理", 12 | "classify": "文章分类", 13 | "achievement": "成绩系统", 14 | "query": "查询成绩", 15 | "inachieve": "录入成绩", 16 | "upload": "提交作业", 17 | "correcting": "评改作业", 18 | "evaluate": "教师评价", 19 | "announce": "公告管理", 20 | "file": "文件管理" 21 | } -------------------------------------------------------------------------------- /back-end/service/department.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuzitao 3 | * @Date: 2017-09-03 13:14:38 4 | * @Last Modified time: 2017-09-03 14:05:23 5 | */ 6 | 7 | 'use strict'; 8 | const query = require('../db/deptDao') 9 | 10 | module.exports = function Department (req, res) { 11 | this.get = pms => { 12 | query(query.fun.get) 13 | .done(result => { 14 | res.send(result) 15 | }) 16 | return this 17 | } 18 | this.add = pms => { 19 | query(query.fun.add, pms) 20 | .done(result => { 21 | res.send({ result }) 22 | }) 23 | } 24 | } -------------------------------------------------------------------------------- /front-end/README.md: -------------------------------------------------------------------------------- 1 | # y 2 | 3 | > y 4 | 5 | ## Build Setup 6 | 7 | ``` bash 8 | # install dependencies 9 | npm install 10 | 11 | # serve with hot reload at localhost:8080 12 | npm run dev 13 | 14 | # build for production with minification 15 | npm run build 16 | 17 | # build for production and view the bundle analyzer report 18 | npm run build --report 19 | ``` 20 | 21 | For detailed explanation on how things work, checkout the [guide](http://vuejs-templates.github.io/webpack/) and [docs for vue-loader](http://vuejs.github.io/vue-loader). 22 | -------------------------------------------------------------------------------- /front-end/src/assets/cropper/src/.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "bitwise": true, 3 | "curly": true, 4 | "eqeqeq": true, 5 | "forin": true, 6 | "freeze": true, 7 | "funcscope": true, 8 | "iterator": true, 9 | "latedef": true, 10 | "noarg": true, 11 | "nocomma": false, 12 | "noempty": true, 13 | "nonbsp": true, 14 | "nonew": true, 15 | "undef": true, 16 | "unused": true, 17 | "strict": false, 18 | "node": true, 19 | "browser": true, 20 | "jquery": true, 21 | "qunit": true, 22 | "globals": { 23 | "define": true 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /front-end/src/assets/ace-master/css/prettify.min.css: -------------------------------------------------------------------------------- 1 | .com{color:#93a1a1}.lit{color:#195f91}.clo,.opn,.pun{color:#93a1a1}.fun{color:#dc322f}.atv,.str{color:#D14}.kwd,.prettyprint .tag{color:#1e347b}.atn,.dec,.typ,.var{color:teal}.pln{color:#48484c}.prettyprint{padding:8px;background-color:#f7f7f9;border:1px solid #e1e1e8}.prettyprint.linenums{-webkit-box-shadow:inset 40px 0 0 #fbfbfc,inset 41px 0 0 #ececf0;box-shadow:inset 40px 0 0 #fbfbfc,inset 41px 0 0 #ececf0}ol.linenums{margin:0 0 0 33px}ol.linenums li{padding-left:12px;color:#bebec5;line-height:20px;text-shadow:0 1px 0 #fff} -------------------------------------------------------------------------------- /front-end/src/assets/ace-master/css/fonts.googleapis.com.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: 'Open Sans'; 3 | font-style: normal; 4 | font-weight: 300; 5 | src: local('Open Sans Light'), local('OpenSans-Light'), url(http://fonts.gstatic.com/s/opensans/v13/DXI1ORHCpsQm3Vp6mXoaTXhCUOGz7vYGh680lGh-uXM.woff) format('woff'); 6 | } 7 | @font-face { 8 | font-family: 'Open Sans'; 9 | font-style: normal; 10 | font-weight: 400; 11 | src: local('Open Sans'), local('OpenSans'), url(http://fonts.gstatic.com/s/opensans/v13/cJZKeOuBrn4kERxqtaUH3T8E0i7KZn-EPnyo3HZu7kw.woff) format('woff'); 12 | } 13 | -------------------------------------------------------------------------------- /front-end/src/assets/cropper/src/.csslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "adjoining-classes": false, 3 | "box-sizing": false, 4 | "box-model": false, 5 | "compatible-vendor-prefixes": false, 6 | "floats": false, 7 | "font-sizes": false, 8 | "gradients": false, 9 | "important": false, 10 | "known-properties": false, 11 | "outline-none": false, 12 | "qualified-headings": false, 13 | "regex-selectors": false, 14 | "shorthand": false, 15 | "text-indent": false, 16 | "zero-units": false, 17 | "unique-headings": false, 18 | "universal-selector": false, 19 | "unqualified-attributes": false 20 | } 21 | -------------------------------------------------------------------------------- /back-end/service/permisson.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuzitao 3 | * @Date: 2017-08-12 23:05:00 4 | * @Last Modified time: 2017-09-05 16:30:32 5 | */ 6 | 7 | 'use strict'; 8 | 9 | module.exports = function Permisson (req, res) { 10 | const query = require('../db/permDao.js') 11 | 12 | this.get = pms => { 13 | query({ uname: pms.uname }) 14 | .done(result => { 15 | if (!result.length) res.send('') 16 | else { 17 | let row = result[0] 18 | req.session.role = row.perm_role 19 | console.log(req.session) 20 | res.send({ name: row.perm_names, role: row.perm_role }) 21 | } 22 | }) 23 | return this 24 | } 25 | } -------------------------------------------------------------------------------- /front-end/src/assets/cropper/src/js/intro.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Cropper v@VERSION 3 | * https://github.com/fengyuanchen/cropper 4 | * 5 | * Copyright (c) 2014-@YEAR Fengyuan Chen and contributors 6 | * Released under the MIT license 7 | * 8 | * Date: @DATE 9 | */ 10 | 11 | (function (factory) { 12 | if (typeof define === 'function' && define.amd) { 13 | // AMD. Register as anonymous module. 14 | define(['jquery'], factory); 15 | } else if (typeof exports === 'object') { 16 | // Node / CommonJS 17 | factory(require('jquery')); 18 | } else { 19 | // Browser globals. 20 | factory(jQuery); 21 | } 22 | })(function ($) { 23 | 24 | 'use strict'; 25 | -------------------------------------------------------------------------------- /front-end/src/assets/cropper/src/less/variables.less: -------------------------------------------------------------------------------- 1 | // Variables 2 | // ============================================================================= 3 | 4 | 5 | // Colors 6 | // ----------------------------------------------------------------------------- 7 | 8 | @color-brand: #69f; 9 | @color-black: #000; 10 | @color-white: #fff; 11 | 12 | 13 | // Media queries breakpoints 14 | // ----------------------------------------------------------------------------- 15 | 16 | @screen-xs: 480px; // Extra small screen / phone 17 | @screen-sm: 768px; // Small screen / tablet 18 | @screen-md: 992px; // Medium screen / desktop 19 | @screen-lg: 1200px; // Large screen / wide desktop 20 | -------------------------------------------------------------------------------- /back-end/db/permDao.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuzitao 3 | * @Date: 2017-08-12 22:59:03 4 | * @Last Modified time: 2017-08-15 19:08:43 5 | */ 6 | 7 | 'use strict' 8 | const BaseDao = require('./baseDao.js') 9 | 10 | module.exports = function (p) { 11 | const query = new BaseDao() 12 | 13 | return query.select({ 14 | $table: 'user', 15 | $column: 'role', 16 | $where: [ 17 | { name: 'uid', value: p.uname } 18 | ] 19 | }) 20 | .then(result => { 21 | if (!result.length) return [] 22 | return query.select({ 23 | $column: ['perm_names', 'perm_role'], 24 | $table: 'permission', 25 | $where: [ 26 | { name: 'perm_role', value: result[0].role } 27 | ] 28 | }) 29 | }) 30 | } -------------------------------------------------------------------------------- /front-end/src/components/_blank.vue: -------------------------------------------------------------------------------- 1 | 6 | 11 | 12 | 29 | 30 | -------------------------------------------------------------------------------- /front-end/src/assets/cropper/readme.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | jQuery之家 6 | 13 | 14 | 15 |

欢迎访问jQuery之家

16 |
17 |

更多精彩内容请访问jQuery之家:http://www.htmleaf.com

18 |

jQuery之家致力于搜集和整理各种jQuery插件,jQuery特效,jquery ui,jQuery 教程,JS特效,网页特效,以及各种html5,css3动画和效果。

19 |

为前端开发者提供最全面的网页开发素材。

20 |
21 | 22 | -------------------------------------------------------------------------------- /back-end/config/api.json: -------------------------------------------------------------------------------- 1 | { 2 | "login": "/api/login", 3 | "session": "/api/session", 4 | "permission": "/api/permission", 5 | "role": "/api/role", 6 | "pwd": "/api/pwd", 7 | "person": "/api/person", 8 | "logout": "/api/logout", 9 | "id": "/api/id", 10 | "addUser": "/api/add-user", 11 | "checkId": "/api/check-id", 12 | "getUser": "/api/get-user-info", 13 | "modUser": "/api/modify-user", 14 | "disable": "/api/disable-user", 15 | "addArticle": "/api/add-article", 16 | "uploadImg": "/api/upload-img", 17 | "getArticle": "/api/get-article", 18 | "getPersonalArticle": "/api/get-personal-article", 19 | "addVisit": "/api/add-visit", 20 | "myArticle": "/api/my-article", 21 | "delArticle": "/api/del-my-article", 22 | "dept": "/api/get-department-info", 23 | "batch": "/api/add-department-batch", 24 | "top": "/api/push-to-top" 25 | } -------------------------------------------------------------------------------- /front-end/src/assets/strings.json: -------------------------------------------------------------------------------- 1 | { 2 | "network-error": "网络异常,请稍后重试", 3 | "wrong-password-disabled": "用户名或密码错误或账号已被禁用", 4 | "wrong-password": "密码错误", 5 | "password-not-the-same": "两次输入密码不一致", 6 | "input-correct-password": "请输入正确的密码", 7 | "success-modify-password": "修改密码成功", 8 | "password-should-different": "原密码和新密码不能相同", 9 | "enter-correct-message": "请输入正确的信息", 10 | "exist-this-user": "该用户已存在", 11 | "commit-first": "请先完成编辑中的内容", 12 | "modify-succeeded": "修改成功", 13 | "input-title-first": "请先输入文章标题", 14 | "input-content-first": "请先输入正文内容", 15 | "sort-first": "请先选择分类", 16 | "invalid-image-type": "不是图片类型的文件", 17 | "img-le-5M": "图片大小不能大于5M", 18 | "upload-img-success": "图片上传成功", 19 | "delete-article-success": "删除文章成功", 20 | "add-batch-success": "新增批次成功", 21 | "top-article-success": "置顶文章成功", 22 | "untop-article-success": "取消置顶文章成功" 23 | } -------------------------------------------------------------------------------- /back-end/app.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuzitao 3 | * @Date: 2017-07-23 23:29:18 4 | * @Last Modified time: 2017-08-30 09:22:40 5 | */ 6 | 'use strict' 7 | const express = require('express') 8 | const path = require('path') 9 | const app = express() 10 | const bodyParser = require('body-parser') 11 | const cookieParser = require('cookie-parser') 12 | const session = require('express-session') 13 | const router = require('./routes') 14 | 15 | require('./m.js')(app) 16 | 17 | app.use(express.static('./public')) 18 | app.use(bodyParser.urlencoded({ 19 | extended: true, // post中要用到true 20 | limit: '5mb' // 设置最大请求体,避免报413错误 21 | })) 22 | app.use(bodyParser.json({ limit: '2048kb' })) 23 | app.use(cookieParser()) 24 | app.use(session(require('./config/session'))) 25 | app.use(router) 26 | 27 | const PORT = process.env.PORT || 9999 28 | app.listen(PORT, function () { 29 | console.log(`DevServer start on port:${ PORT}`) 30 | }) -------------------------------------------------------------------------------- /front-end/.eslintrc.js: -------------------------------------------------------------------------------- 1 | // http://eslint.org/docs/user-guide/configuring 2 | 3 | module.exports = { 4 | root: true, 5 | parser: 'babel-eslint', 6 | parserOptions: { 7 | sourceType: 'module' 8 | }, 9 | env: { 10 | browser: true, 11 | }, 12 | // https://github.com/feross/standard/blob/master/RULES.md#javascript-standard-style 13 | extends: 'standard', 14 | // required to lint *.vue files 15 | plugins: [ 16 | 'html' 17 | ], 18 | // add your custom rules here 19 | 'rules': { 20 | // allow paren-less arrow functions 21 | 'arrow-parens': 0, 22 | // allow async-await 23 | 'generator-star-spacing': 0, 24 | // allow debugger during development 25 | 'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0, 26 | 'no-tabs': 0, 27 | 'indent': 0, 28 | 'no-unused-vars': 0, 29 | 'one-var': 0, 30 | // 'semi': [2, 'always'], // 强制分号结尾 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /front-end/src/components/waiter.vue: -------------------------------------------------------------------------------- 1 | 6 | 11 | 12 | 22 | 23 | -------------------------------------------------------------------------------- /front-end/src/components/main/news.vue: -------------------------------------------------------------------------------- 1 | 6 | 11 | 12 | 28 | 29 | -------------------------------------------------------------------------------- /front-end/src/assets/cropper/src/js/plugin.js: -------------------------------------------------------------------------------- 1 | // Save the other cropper 2 | Cropper.other = $.fn.cropper; 3 | 4 | // Register as jQuery plugin 5 | $.fn.cropper = function (options) { 6 | var args = toArray(arguments, 1), 7 | result; 8 | 9 | this.each(function () { 10 | var $this = $(this), 11 | data = $this.data('cropper'), 12 | fn; 13 | 14 | if (!data) { 15 | $this.data('cropper', (data = new Cropper(this, options))); 16 | } 17 | 18 | if (typeof options === 'string' && $.isFunction((fn = data[options]))) { 19 | result = fn.apply(data, args); 20 | } 21 | }); 22 | 23 | return isUndefined(result) ? this : result; 24 | }; 25 | 26 | $.fn.cropper.Constructor = Cropper; 27 | $.fn.cropper.setDefaults = Cropper.setDefaults; 28 | 29 | // No conflict 30 | $.fn.cropper.noConflict = function () { 31 | $.fn.cropper = Cropper.other; 32 | return this; 33 | }; 34 | -------------------------------------------------------------------------------- /front-end/src/utils/toast.min.js: -------------------------------------------------------------------------------- 1 | function toast(g,a,e){g=g||"";a=a||1000;e=e||500;var d=toast;if(!d.toastValid){d.toastValid=true;var h=document.createElement("div");h.id="jyut_toast";h.style.color="#fff";h.style.background="#676767";h.style.borderRadius="10px";h.style.padding="1em 1em";h.style.textAlign="center";h.style.maxWidth="80%";h.style.minWidth="20px";h.style.position="fixed";h.style.bottom="50px";h.style.fontSize="1em";h.style.opacity=1;h.style.zIndex=1000;h.style.wordWrap="break-word";h.innerHTML=g;document.body.appendChild(h);var c=h.offsetWidth;h.style.left="50%";h.style.marginLeft=(-c/2)+"px";var b=setInterval(function(){var i=parseInt(h.style.bottom.substring(0,h.style.bottom.indexOf("px")));h.style.bottom=(i+=10)+"px";h.style.opacity-=-0.2;if(i>=50){clearInterval(b)}},10);var f=setTimeout(function(){var i=setInterval(function(){h.style.opacity-=0.1;if(h.style.opacity<=0){d.toastValid=false;document.body.removeChild(h);clearInterval(i)}},e/10)},a)}};module.exports=toast; -------------------------------------------------------------------------------- /front-end/src/components/back-to-top.vue: -------------------------------------------------------------------------------- 1 | 6 | 11 | 12 | 36 | 37 | -------------------------------------------------------------------------------- /back-end/m.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuzitao 3 | * @Date: 2017-08-07 09:13:15 4 | * @Last Modified time: 2017-08-11 16:01:40 5 | */ 6 | const path = require('path') 7 | const express = require('express') 8 | const app = express() 9 | const u = require('./util/util') 10 | 11 | module.exports = function (app) { 12 | let dataMaggie = require('../others/Maggie/server') 13 | app.use(express.static(path.resolve('../others/'))) 14 | app.get('/maggie', function (req, res) { 15 | res.sendFile(path.resolve('../others/Maggie/index.html')) 16 | }) 17 | app.get('/maggie/data/:content', function (req, res) { 18 | let content = req.params.content 19 | if (content === 'msg') { 20 | let query = req.query // 如果没有query(?后面的),则是空对象,不是undefined 21 | if (u.isEmptyObject(query)) { 22 | res.json( dataMaggie.getMsg() ) 23 | } else { 24 | res.json( dataMaggie.putMsg(query) ) 25 | } 26 | return 27 | } 28 | if (content === 'img') { 29 | res.json( dataMaggie.getImg() ) 30 | return 31 | } 32 | res.end('404 error') 33 | }) 34 | } -------------------------------------------------------------------------------- /back-end/util/cryption.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuzitao 3 | * @Date: 2017-08-12 14:46:56 4 | * @Last Modified time: 2017-08-12 17:35:58 5 | */ 6 | const crypto = require('crypto') 7 | 8 | function encryptHash (method, text) { 9 | let cry = crypto.createHash(method) 10 | cry.update(text) 11 | return cry.digest('hex') 12 | } 13 | 14 | function encrypt (method, text) { 15 | let cry = crypto.createCipher(method, '9853e61272b549ad1e6371894ade20f2') 16 | let crypted = cry.update(text, 'utf8', 'hex') 17 | return crypted + cry.final('hex') 18 | } 19 | 20 | function decrypt (method, text) { 21 | let decipher = crypto.createDecipher(method, '9853e61272b549ad1e6371894ade20f2') 22 | let dec = decipher.update(text, 'hex', 'utf8') 23 | return dec + decipher.final('utf8') 24 | } 25 | 26 | function md5 (text) { 27 | return encryptHash('md5', text) 28 | } 29 | 30 | function aes (text) { 31 | return encrypt('aes-256-ecb', text) 32 | } 33 | 34 | function deaes (text) { 35 | return decrypt('aes-256-ecb', text) 36 | } 37 | 38 | module.exports = { md5, aes, deaes } -------------------------------------------------------------------------------- /front-end/src/utils/cryption.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuzitao 3 | * @Date: 2017-08-12 14:46:56 4 | * @Last Modified time: 2017-08-31 17:08:10 5 | */ 6 | const crypto = require('crypto') 7 | 8 | function encryptHash (method, text) { 9 | let cry = crypto.createHash(method) 10 | cry.update(text) 11 | return cry.digest('hex') 12 | } 13 | 14 | function encrypt (method, text) { 15 | let cry = crypto.createCipher(method, '9853e61272b549ad1e6371894ade20f2') 16 | let crypted = cry.update(text, 'utf8', 'hex') 17 | return crypted + cry.final('hex') 18 | } 19 | 20 | function decrypt (method, text) { 21 | let decipher = crypto.createDecipher(method, '9853e61272b549ad1e6371894ade20f2') 22 | let dec = decipher.update(text, 'hex', 'utf8') 23 | return dec + decipher.final('utf8') 24 | } 25 | 26 | function md5 (text) { 27 | return encryptHash('md5', text) 28 | } 29 | 30 | function aes (text) { 31 | // return encrypt('aes-256-ecb', text) 32 | return text 33 | } 34 | 35 | function deaes (text) { 36 | // return decrypt('aes-256-ecb', text) 37 | return text 38 | } 39 | 40 | module.exports = { md5, aes, deaes } -------------------------------------------------------------------------------- /front-end/build/build.js: -------------------------------------------------------------------------------- 1 | require('./check-versions')() 2 | 3 | process.env.NODE_ENV = 'production' 4 | 5 | var ora = require('ora') 6 | var rm = require('rimraf') 7 | var path = require('path') 8 | var chalk = require('chalk') 9 | var webpack = require('webpack') 10 | var config = require('../config') 11 | var webpackConfig = require('./webpack.prod.conf') 12 | 13 | var spinner = ora('building for production...') 14 | spinner.start() 15 | 16 | rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => { 17 | if (err) throw err 18 | webpack(webpackConfig, function (err, stats) { 19 | spinner.stop() 20 | if (err) throw err 21 | process.stdout.write(stats.toString({ 22 | colors: true, 23 | modules: false, 24 | children: false, 25 | chunks: false, 26 | chunkModules: false 27 | }) + '\n\n') 28 | 29 | console.log(chalk.cyan(' Build complete.\n')) 30 | console.log(chalk.yellow( 31 | ' Tip: built files are meant to be served over an HTTP server.\n' + 32 | ' Opening index.html over file:// won\'t work.\n' 33 | )) 34 | }) 35 | }) 36 | -------------------------------------------------------------------------------- /front-end/src/assets/ace-master/css/bootstrap-multiselect.min.css: -------------------------------------------------------------------------------- 1 | .multiselect-container{position:absolute;list-style-type:none;margin:0;padding:0}.multiselect-container .input-group{margin:5px}.multiselect-container>li{padding:0}.multiselect-container>li>a.multiselect-all label{font-weight:700}.multiselect-container>li.multiselect-group label{margin:0;padding:3px 20px;height:100%;font-weight:700}.multiselect-container>li.multiselect-group-clickable label{cursor:pointer}.multiselect-container>li>a{padding:0}.multiselect-container>li>a>label{margin:0;height:100%;cursor:pointer;font-weight:400;padding:3px 20px 3px 40px}.multiselect-container>li>a>label.checkbox,.multiselect-container>li>a>label.radio{margin:0}.multiselect-container>li>a>label>input[type=checkbox]{margin-bottom:5px}.btn-group>.btn-group:nth-child(2)>.multiselect.btn{border-top-left-radius:4px;border-bottom-left-radius:4px}.form-inline .multiselect-container label.checkbox,.form-inline .multiselect-container label.radio{padding:3px 20px 3px 40px}.form-inline .multiselect-container li a label.checkbox input[type=checkbox],.form-inline .multiselect-container li a label.radio input[type=radio]{margin-left:-20px;margin-right:0} -------------------------------------------------------------------------------- /back-end/db/deptDao.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuzitao 3 | * @Date: 2017-08-12 22:59:03 4 | * @Last Modified time: 2017-09-03 14:07:18 5 | */ 6 | 7 | 'use strict' 8 | const BaseDao = require('./baseDao.js') 9 | 10 | const fun = { 11 | get: 'get_all_department_info', 12 | add: 'add_department_batch' 13 | } 14 | 15 | exports = module.exports = function (f, p) { 16 | const query = new BaseDao() 17 | 18 | switch (f.toLowerCase()) { 19 | case fun.get: 20 | return query.select({ 21 | $table: 'department', 22 | $column: [ 23 | 'd_name', 24 | 'batch', 25 | 'people_count', 26 | 'reg_time' 27 | ] 28 | }) 29 | 30 | case fun.add: 31 | let map = { 32 | '前端': 22, 33 | 'UI': 12, 34 | 'Java': 88, 35 | '未知': 99 36 | } 37 | return query.select({ 38 | $table: 'department', 39 | $column: 'max(batch) batch', 40 | $where: { d_name: p.name } 41 | }) 42 | .then(result => { 43 | let batch = result[0].batch + 1 44 | return query.insert({ 45 | $table: 'department', 46 | did: map[p.name], 47 | d_name: p.name, 48 | batch, 49 | }) 50 | }) 51 | 52 | default: return null 53 | } 54 | } 55 | 56 | exports.fun = fun 57 | -------------------------------------------------------------------------------- /front-end/src/assets/cropper/src/less/utilities.less: -------------------------------------------------------------------------------- 1 | // Helper classes for JavaScript 2 | // ============================================================================= 3 | 4 | // Visual 5 | // ----------------------------------------------------------------------------- 6 | 7 | .cropper-bg { 8 | background-image: data-uri("../img/bg.png"); 9 | } 10 | 11 | .cropper-invisible { 12 | .opacity(0); 13 | } 14 | 15 | 16 | // Visibility 17 | // ----------------------------------------------------------------------------- 18 | 19 | .cropper-hide { 20 | position: fixed; 21 | top: 0; 22 | left: 0; 23 | z-index: -1; 24 | .square(e("auto!important")); 25 | .min-square(e("0!important")); 26 | .max-square(e("none!important")); 27 | .opacity(0); 28 | } 29 | 30 | .cropper-hidden { 31 | display: none !important; 32 | } 33 | 34 | 35 | 36 | // Cursors 37 | // ----------------------------------------------------------------------------- 38 | 39 | .cropper-move { 40 | cursor: move; 41 | } 42 | 43 | .cropper-crop { 44 | cursor: crosshair; 45 | } 46 | 47 | .cropper-disabled { 48 | .cropper-drag-box, 49 | .cropper-face, 50 | .cropper-line, 51 | .cropper-point { 52 | cursor: not-allowed; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /front-end/src/components/widget/markdown-preview.vue: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | 52 | 53 | -------------------------------------------------------------------------------- /front-end/src/assets/menu.json: -------------------------------------------------------------------------------- 1 | { 2 | "最新动态": { 3 | "router": "/news" 4 | }, 5 | "个人信息管理": { 6 | "ico": "user", 7 | "router": "/person-data", 8 | 9 | "修改密码": { 10 | "router": "/password-modification" 11 | }, 12 | "上传头像": { 13 | "router": "/upload-headimg" 14 | } 15 | }, 16 | "账户录入/管理": { 17 | "ico": "pencil", 18 | "router": "/information-profile", 19 | 20 | "信息录入": { 21 | "router": "/information-input" 22 | }, 23 | "管理账户": { 24 | "router": "/information-management" 25 | } 26 | }, 27 | "程序员世界": { 28 | "ico": "pencil-square-o", 29 | "router": "/programmer", 30 | 31 | "发表新文章": { 32 | "router": "/article-publishment" 33 | }, 34 | "文章管理": { 35 | "router": "/article-management" 36 | }, 37 | "文章分类": { 38 | "router": "/" 39 | } 40 | }, 41 | "成绩系统": { 42 | "ico": "superscript", 43 | "router": "/", 44 | 45 | "成绩查询": { 46 | "router": "/" 47 | }, 48 | "成绩录入": { 49 | "router": "/" 50 | }, 51 | "提交作业": { 52 | "router": "/" 53 | }, 54 | "评改作业": { 55 | "router": "/" 56 | }, 57 | "教师评价": { 58 | "router": "/" 59 | } 60 | }, 61 | "公告管理": { 62 | "ico": "bullhorn", 63 | "router": "/" 64 | }, 65 | "文件管理": { 66 | "ico": "picture-o", 67 | "router": "/" 68 | } 69 | } -------------------------------------------------------------------------------- /front-end/src/assets/ace-master/js/jquery.ui.touch-punch.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * jQuery UI Touch Punch 0.2.3 3 | * 4 | * Copyright 2011–2014, Dave Furfero 5 | * Dual licensed under the MIT or GPL Version 2 licenses. 6 | * 7 | * Depends: 8 | * jquery.ui.widget.js 9 | * jquery.ui.mouse.js 10 | */ 11 | !function(a){function b(a,b){if(!(a.originalEvent.touches.length>1)){a.preventDefault();var c=a.originalEvent.changedTouches[0],d=document.createEvent("MouseEvents");d.initMouseEvent(b,!0,!0,window,1,c.screenX,c.screenY,c.clientX,c.clientY,!1,!1,!1,!1,0,null),a.target.dispatchEvent(d)}}if(a.support.touch="ontouchend"in document,a.support.touch){var c,d=a.ui.mouse.prototype,e=d._mouseInit,f=d._mouseDestroy;d._touchStart=function(a){var d=this;!c&&d._mouseCapture(a.originalEvent.changedTouches[0])&&(c=!0,d._touchMoved=!1,b(a,"mouseover"),b(a,"mousemove"),b(a,"mousedown"))},d._touchMove=function(a){c&&(this._touchMoved=!0,b(a,"mousemove"))},d._touchEnd=function(a){c&&(b(a,"mouseup"),b(a,"mouseout"),this._touchMoved||b(a,"click"),c=!1)},d._mouseInit=function(){var b=this;b.element.bind({touchstart:a.proxy(b,"_touchStart"),touchmove:a.proxy(b,"_touchMove"),touchend:a.proxy(b,"_touchEnd")}),e.call(b)},d._mouseDestroy=function(){var b=this;b.element.unbind({touchstart:a.proxy(b,"_touchStart"),touchmove:a.proxy(b,"_touchMove"),touchend:a.proxy(b,"_touchEnd")}),f.call(b)}}}(jQuery); -------------------------------------------------------------------------------- /back-end/service/article.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuzitao 3 | * @Date: 2017-08-25 16:39:24 4 | * @Last Modified by: wuzitao 5 | * @Last Modified time: 2017-09-05 14:55:54 6 | */ 7 | const query = require('../db/articleDao') 8 | 9 | module.exports = function Article (req, res) { 10 | this.addArticle = pms => { 11 | query(query.fun.add, pms) 12 | .done(result => { 13 | res.send({ result }) 14 | }) 15 | return this 16 | } 17 | this.getArticles = pms => { 18 | query(query.fun.getall, pms) 19 | .done(result => { 20 | res.send(result) 21 | }) 22 | return this 23 | } 24 | this.getPersonalArticle = pms => { 25 | query(query.fun.getperson, pms) 26 | .done(result => { 27 | res.send(result) 28 | }) 29 | return this 30 | } 31 | this.addVisit = pms => { 32 | query(query.fun.visit, pms) 33 | .done(result => { 34 | result && res.send('ok') 35 | }) 36 | return this 37 | } 38 | this.getMyArticles = pms => { 39 | query(query.fun.my, pms) 40 | .done(result => { 41 | res.send(result) 42 | }) 43 | return this 44 | } 45 | this.deleteArticle = pms => { 46 | query(query.fun.del, pms) 47 | .done(result => { 48 | res.send({ result }) 49 | }) 50 | return this 51 | } 52 | this.topArticle = pms => { 53 | query(query.fun.top, pms) 54 | .done(result => { 55 | res.send({ result }) 56 | }) 57 | return this 58 | } 59 | } -------------------------------------------------------------------------------- /front-end/src/main.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuzitao 3 | * @Date: 2017-07-23 22:01:56 4 | * @Last Modified time: 2017-09-09 17:53:50 5 | */ 6 | // The Vue build version to load with the `import` command 7 | // (runtime-only or standalone) has been set in webpack.base.conf with an alias. 8 | import Vue from 'vue' 9 | import $ from 'jquery' 10 | import App from './App' 11 | import router from './router' 12 | import store from './store' 13 | import api from '../../back-end/config/api.json' 14 | import ajaxSetup from './config/ajaxSetup' 15 | 16 | require('./assets/ace-master/css/bootstrap.min.css') 17 | require('./assets/ace-master/font-awesome/4.5.0/css/font-awesome.min.css') 18 | require('./assets/ace-master/css/ace.min.css') 19 | require('./assets/ace-master/css/ace-skins.min.css') 20 | require('./assets/ace-master/js/markdown.min.js') 21 | require('./assets/ace-master/js/bootstrap-markdown.min.js') 22 | 23 | 'use strict' 24 | 25 | Vue.config.productionTip = false 26 | Vue.prototype.api = api // api转发接口 27 | Vue.prototype.__role__ = '' 28 | $.ajaxSetup(ajaxSetup) // $.ajax全局设置 29 | 30 | /* eslint-disable no-new */ 31 | new Vue({ 32 | el: '#app', 33 | router, 34 | store, 35 | template: '', 36 | components: { App } 37 | }) 38 | 39 | $($ => { 40 | $(document).on('click', function (event) { 41 | $('[data-rel=popover]').popover('hide') 42 | $('.dropdown-menu').hide() 43 | }) 44 | }) 45 | -------------------------------------------------------------------------------- /back-end/util/util.js: -------------------------------------------------------------------------------- 1 | function isEmptyObject (obj) { 2 | for (var p in obj) { 3 | return false; 4 | } 5 | return true; 6 | } 7 | function log () { 8 | console.log.apply(console, arguments); 9 | } 10 | function addQuote (val) { 11 | return typeof val === 'string' ? `"${val}"` : val; 12 | } 13 | function fillZero (n) { 14 | return n < 10 ? '0' + n : '' + n 15 | } 16 | function isPlainObject (obj) { 17 | return typeof obj === 'object' 18 | && Object.getPrototypeOf(obj).constructor === Object 19 | } 20 | module.exports = (function () { 21 | Date.prototype.Format = Date.prototype.format = function(fmt) { 22 | var o = { 23 | "M+": this.getMonth() + 1, //月份 24 | "d+": this.getDate(), //日 25 | "h+": this.getHours(), //小时 26 | "m+": this.getMinutes(), //分 27 | "s+": this.getSeconds(), //秒 28 | "q+": Math.floor((this.getMonth() + 3) / 3), //季度 29 | "S": this.getMilliseconds() //毫秒 30 | }; 31 | if (/(y+)/.test(fmt)) 32 | fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length)); 33 | for (var k in o) 34 | if (new RegExp("(" + k + ")").test(fmt)) 35 | fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length))); 36 | return fmt; 37 | } 38 | return { 39 | isEmptyObject, log, addQuote, fillZero, isPlainObject 40 | }; 41 | })(); -------------------------------------------------------------------------------- /front-end/src/assets/cropper/src/less/mixins.less: -------------------------------------------------------------------------------- 1 | // Mixins 2 | // ============================================================================= 3 | 4 | 5 | // Vendor Prefixes 6 | // ----------------------------------------------------------------------------- 7 | 8 | .box-sizing(@boxmodel) { 9 | -webkit-box-sizing: @boxmodel; 10 | -moz-box-sizing: @boxmodel; 11 | box-sizing: @boxmodel; 12 | } 13 | 14 | .user-select(@select) { 15 | -webkit-user-select: @select; 16 | -moz-user-select: @select; 17 | -ms-user-select: @select; // IE10+ 18 | user-select: @select; 19 | } 20 | 21 | 22 | // Opacity 23 | // ----------------------------------------------------------------------------- 24 | 25 | .opacity(@opacity) { 26 | opacity: @opacity; 27 | filter: e(%("alpha(opacity=%s)", @opacity * 100)); // IE8 28 | } 29 | 30 | 31 | // Sizing shortcuts 32 | // ----------------------------------------------------------------------------- 33 | 34 | .size(@width; @height) { 35 | width: @width; 36 | height: @height; 37 | } 38 | 39 | .min-size(@width; @height) { 40 | min-width: @width; 41 | min-height: @height; 42 | } 43 | 44 | .max-size(@width; @height) { 45 | max-width: @width; 46 | max-height: @height; 47 | } 48 | 49 | .square(@size) { 50 | .size(@size; @size); 51 | } 52 | 53 | .min-square(@size) { 54 | .min-size(@size; @size); 55 | } 56 | 57 | .max-square(@size) { 58 | .max-size(@size; @size); 59 | } 60 | -------------------------------------------------------------------------------- /front-end/src/assets/ace-master/css/bootstrap-duallistbox.min.css: -------------------------------------------------------------------------------- 1 | .bootstrap-duallistbox-container .buttons{width:100%;margin-bottom:-1px}.bootstrap-duallistbox-container label{display:block}.bootstrap-duallistbox-container .info{display:inline-block;margin-bottom:5px;font-size:11px}.bootstrap-duallistbox-container .clear1,.bootstrap-duallistbox-container .clear2{display:none;font-size:10px}.bootstrap-duallistbox-container .box1.filtered .clear1,.bootstrap-duallistbox-container .box2.filtered .clear2{display:inline-block}.bootstrap-duallistbox-container .move,.bootstrap-duallistbox-container .remove{width:60%}.bootstrap-duallistbox-container .btn-group .btn{border-bottom-left-radius:0;border-bottom-right-radius:0}.bootstrap-duallistbox-container .moveall,.bootstrap-duallistbox-container .removeall{width:40%}.bootstrap-duallistbox-container.bs2compatible .btn-group>.btn+.btn{margin-left:0}.bootstrap-duallistbox-container select{border-top-left-radius:0;border-top-right-radius:0;width:100%;height:300px;padding:0}.bootstrap-duallistbox-container .filter{display:inline-block;width:100%;height:31px;margin:0 0 5px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.bootstrap-duallistbox-container .filter.placeholder{color:#aaa}.bootstrap-duallistbox-container.moveonselect .move,.bootstrap-duallistbox-container.moveonselect .remove{display:none}.bootstrap-duallistbox-container.moveonselect .moveall,.bootstrap-duallistbox-container.moveonselect .removeall{width:100%} -------------------------------------------------------------------------------- /front-end/build/check-versions.js: -------------------------------------------------------------------------------- 1 | var chalk = require('chalk') 2 | var semver = require('semver') 3 | var packageConfig = require('../package.json') 4 | var shell = require('shelljs') 5 | function exec (cmd) { 6 | return require('child_process').execSync(cmd).toString().trim() 7 | } 8 | 9 | var versionRequirements = [ 10 | { 11 | name: 'node', 12 | currentVersion: semver.clean(process.version), 13 | versionRequirement: packageConfig.engines.node 14 | }, 15 | ] 16 | 17 | if (shell.which('npm')) { 18 | versionRequirements.push({ 19 | name: 'npm', 20 | currentVersion: exec('npm --version'), 21 | versionRequirement: packageConfig.engines.npm 22 | }) 23 | } 24 | 25 | module.exports = function () { 26 | var warnings = [] 27 | for (var i = 0; i < versionRequirements.length; i++) { 28 | var mod = versionRequirements[i] 29 | if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) { 30 | warnings.push(mod.name + ': ' + 31 | chalk.red(mod.currentVersion) + ' should be ' + 32 | chalk.green(mod.versionRequirement) 33 | ) 34 | } 35 | } 36 | 37 | if (warnings.length) { 38 | console.log('') 39 | console.log(chalk.yellow('To use this template, you must update following to modules:')) 40 | console.log() 41 | for (var i = 0; i < warnings.length; i++) { 42 | var warning = warnings[i] 43 | console.log(' ' + warning) 44 | } 45 | console.log() 46 | process.exit(1) 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /front-end/build/webpack.dev.conf.js: -------------------------------------------------------------------------------- 1 | var utils = require('./utils') 2 | var webpack = require('webpack') 3 | var config = require('../config') 4 | var merge = require('webpack-merge') 5 | var baseWebpackConfig = require('./webpack.base.conf') 6 | var HtmlWebpackPlugin = require('html-webpack-plugin') 7 | var FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin') 8 | 9 | // add hot-reload related code to entry chunks 10 | Object.keys(baseWebpackConfig.entry).forEach(function (name) { 11 | baseWebpackConfig.entry[name] = ['./build/dev-client'].concat(baseWebpackConfig.entry[name]) 12 | }) 13 | 14 | module.exports = merge(baseWebpackConfig, { 15 | module: { 16 | rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap }) 17 | }, 18 | // cheap-module-eval-source-map is faster for development 19 | devtool: '#cheap-module-eval-source-map', 20 | plugins: [ 21 | new webpack.DefinePlugin({ 22 | 'process.env': config.dev.env 23 | }), 24 | // https://github.com/glenjamin/webpack-hot-middleware#installation--usage 25 | new webpack.HotModuleReplacementPlugin(), 26 | new webpack.NoEmitOnErrorsPlugin(), 27 | // https://github.com/ampedandwired/html-webpack-plugin 28 | new HtmlWebpackPlugin({ 29 | filename: 'index.html', 30 | template: 'index.html', 31 | inject: true 32 | }), 33 | new FriendlyErrorsPlugin(), 34 | new webpack.ProvidePlugin({ // 解决bootstrap找不到jQuery的问题 35 | jQuery: 'jquery', 36 | $: 'jquery', 37 | jquery: 'jquery', 38 | 'window.jQuery': 'jquery' 39 | }) 40 | ] 41 | }) 42 | -------------------------------------------------------------------------------- /front-end/src/assets/ace-master/css/jquery.gritter.min.css: -------------------------------------------------------------------------------- 1 | #gritter-notice-wrapper{position:fixed;top:20px;right:20px;width:301px;z-index:9999}#gritter-notice-wrapper.top-left{left:20px;right:auto}#gritter-notice-wrapper.bottom-right{top:auto;left:auto;bottom:20px;right:20px}#gritter-notice-wrapper.bottom-left{top:auto;right:auto;bottom:20px;left:20px}.gritter-item-wrapper{position:relative;margin:0 0 10px;background:url(../images/ie-spacer.gif)}.gritter-top{background:url(../images/gritter.png) left -30px no-repeat;height:10px}.hover .gritter-top{background-position:right -30px}.gritter-bottom{background:url(../images/gritter.png) left bottom no-repeat;height:8px;margin:0}.hover .gritter-bottom{background-position:bottom right}.gritter-item{display:block;background:url(../images/gritter.png) left -40px no-repeat;color:#eee;padding:2px 11px 8px;font-size:11px;font-family:verdana}.hover .gritter-item{background-position:right -40px}.gritter-item p{padding:0;margin:0;word-wrap:break-word}.gritter-close{display:none;position:absolute;top:5px;left:3px;background:url(../images/gritter.png) left top no-repeat;cursor:pointer;width:30px;height:30px;text-indent:-9999em}.gritter-title{font-size:14px;font-weight:700;padding:0 0 7px;display:block;text-shadow:1px 1px 0 #000}.gritter-image{width:48px;height:48px;float:left}.gritter-with-image,.gritter-without-image{padding:0}.gritter-with-image{width:220px;float:right}.gritter-light .gritter-bottom,.gritter-light .gritter-close,.gritter-light .gritter-item,.gritter-light .gritter-top{background-image:url(../images/gritter-light.png);color:#222}.gritter-light .gritter-title{text-shadow:none} -------------------------------------------------------------------------------- /front-end/src/assets/cropper/src/js/listen.js: -------------------------------------------------------------------------------- 1 | prototype.addListeners = function () { 2 | var options = this.options; 3 | 4 | this.$element.on(EVENT_DRAG_START, options.dragstart).on(EVENT_DRAG_MOVE, options.dragmove).on(EVENT_DRAG_END, options.dragend).on(EVENT_ZOOM_IN, options.zoomin).on(EVENT_ZOOM_OUT, options.zoomout); 5 | this.$cropper.on(EVENT_MOUSE_DOWN, $.proxy(this.dragstart, this)).on(EVENT_DBLCLICK, $.proxy(this.dblclick, this)); 6 | 7 | if (options.zoomable && options.mouseWheelZoom) { 8 | this.$cropper.on(EVENT_WHEEL, $.proxy(this.wheel, this)); 9 | } 10 | 11 | $document.on(EVENT_MOUSE_MOVE, (this._dragmove = proxy(this.dragmove, this))).on(EVENT_MOUSE_UP, (this._dragend = proxy(this.dragend, this))); 12 | 13 | if (options.responsive) { 14 | $window.on(EVENT_RESIZE, (this._resize = proxy(this.resize, this))); 15 | } 16 | }; 17 | 18 | prototype.removeListeners = function () { 19 | var options = this.options; 20 | 21 | this.$element.off(EVENT_DRAG_START, options.dragstart).off(EVENT_DRAG_MOVE, options.dragmove).off(EVENT_DRAG_END, options.dragend).off(EVENT_ZOOM_IN, options.zoomin).off(EVENT_ZOOM_OUT, options.zoomout); 22 | this.$cropper.off(EVENT_MOUSE_DOWN, this.dragstart).off(EVENT_DBLCLICK, this.dblclick); 23 | 24 | if (options.zoomable && options.mouseWheelZoom) { 25 | this.$cropper.off(EVENT_WHEEL, this.wheel); 26 | } 27 | 28 | $document.off(EVENT_MOUSE_MOVE, this._dragmove).off(EVENT_MOUSE_UP, this._dragend); 29 | 30 | if (options.responsive) { 31 | $window.off(EVENT_RESIZE, this._resize); 32 | } 33 | }; 34 | -------------------------------------------------------------------------------- /front-end/src/utils/UserInput.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuzitao 3 | * @Date: 2017-08-07 23:02:38 4 | * @Last Modified time: 2017-08-13 01:11:09 5 | */ 6 | const distinctObjectArrayBy = require('util.js').distinctObjectArrayBy 7 | 8 | function UserInput () { 9 | this.reflects = [ 10 | { 11 | name: 'tel', 12 | reg: /^(13[0-9]|15[0-9]|18[0-9])\d{8}$/ 13 | }, 14 | { 15 | name: 'qq', 16 | reg: /^[1-9][0-9]{4,15}$/ 17 | } 18 | ]; 19 | addMethod.bind(this)(this.reflects); 20 | } 21 | UserInput.prototype.add = function (obj) { 22 | if (obj instanceof Array) { 23 | for (let o of obj) { 24 | if (!(o.reg instanceof RegExp)) { 25 | throw 'The reg must be a RegExp'; 26 | } 27 | this.reflects.push(o); 28 | } 29 | } else { 30 | this.reflects.push(obj); 31 | if (!(obj.reg instanceof RegExp)) { 32 | throw 'The reg must be a RegExp'; 33 | } 34 | } 35 | this.reflects = distinctObjectArrayBy(this.reflects, 'name'); 36 | addMethod.bind(this)(this.reflects); 37 | return this; 38 | } 39 | function addMethod (refs) { 40 | for (let o of refs) { 41 | this['isIllegal'+upFirstCase(o.name)] = function (str) { 42 | return o.reg.test(str); 43 | }; 44 | } 45 | } 46 | function upFirstCase (str) { 47 | return str.replace(/^(\w)(\w+)/, function (v, v1, v2) { 48 | return v1.toUpperCase() + v2.toLowerCase(); 49 | }); 50 | } 51 | function distinctObjectArrayBy (arr, key) { 52 | let a = []; 53 | let names = []; 54 | for (let i = arr.length - 1; i >= 0; i--) { 55 | let o = arr[i]; 56 | if (names.indexOf(o[key]) === -1) { 57 | a.push(o); 58 | names.push(o[key]); 59 | } 60 | } 61 | return a.reverse(); 62 | } 63 | export default UserInput; -------------------------------------------------------------------------------- /front-end/src/components/widget/confirm-dialog-body.vue: -------------------------------------------------------------------------------- 1 | 6 | 28 | 29 | 64 | 65 | -------------------------------------------------------------------------------- /front-end/src/assets/cropper/css/normalize.css: -------------------------------------------------------------------------------- 1 | article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block;}audio,canvas,video{display:inline-block;}audio:not([controls]){display:none;height:0;}[hidden]{display:none;}html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%;}body{margin:0;}a:focus{outline:thin dotted;}a:active,a:hover{outline:0;}h1{font-size:2em;margin:0.67em 0;}abbr[title]{border-bottom:1px dotted;}b,strong{font-weight:bold;}dfn{font-style:italic;}hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0;}mark{background:#ff0;color:#000;}code,kbd,pre,samp{font-family:monospace,serif;font-size:1em;}pre{white-space:pre-wrap;}q{quotes:"\201C" "\201D" "\2018" "\2019";}small{font-size:80%;}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline;}sup{top:-0.5em;}sub{bottom:-0.25em;}img{border:0;}svg:not(:root){overflow:hidden;}figure{margin:0;}fieldset{border:1px solid #c0c0c0;margin:0 2px;padding:0.35em 0.625em 0.75em;}legend{border:0;padding:0;}button,input,select,textarea{font-family:inherit;font-size:100%;margin:0;}button,input{line-height:normal;}button,select{text-transform:none;}button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer;}button[disabled],html input[disabled]{cursor:default;}input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0;}input[type="search"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box;}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none;}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0;}textarea{overflow:auto;vertical-align:top;}table{border-collapse:collapse;border-spacing:0;} -------------------------------------------------------------------------------- /front-end/src/assets/ace-master/js/buttons.print.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Print button for Buttons and DataTables. 3 | * 2015 SpryMedia Ltd - datatables.net/license 4 | */ 5 | !function(a){"function"==typeof define&&define.amd?define(["jquery","datatables.net","datatables.net-buttons"],function(b){return a(b,window,document)}):"object"==typeof exports?module.exports=function(b,c){return b||(b=window),c&&c.fn.dataTable||(c=require("datatables.net")(b,c).$),c.fn.dataTable.Buttons||require("datatables.net-buttons")(b,c),a(c,b,b.document)}:a(jQuery,window,document)}(function(a,b,c,d){"use strict";var e=a.fn.dataTable,f=c.createElement("a"),g=function(b){var c,d=a(b).clone()[0];return"link"===d.nodeName.toLowerCase()&&(f.href=d.href,c=f.host,-1===c.indexOf("/")&&0!==f.pathname.indexOf("/")&&(c+="/"),d.href=f.protocol+"//"+c+f.pathname+f.search),d.outerHTML};return e.ext.buttons.print={className:"buttons-print",text:function(a){return a.i18n("buttons.print","Print")},action:function(c,d,e,f){var h=d.buttons.exportData(f.exportOptions),i=function(a,b){for(var c="",d=0,e=a.length;e>d;d++)c+="<"+b+">"+a[d]+"";return c+""},j='';f.header&&(j+=""+i(h.header,"th")+""),j+="";for(var k=0,l=h.body.length;l>k;k++)j+=i(h.body[k],"td");j+="",f.footer&&(j+=""+i(h.footer,"th")+"");var m=b.open("",""),n=f.title;"function"==typeof n&&(n=n()),-1!==n.indexOf("*")&&(n=n.replace("*",a("title").text())),m.document.close();var o=""+n+"";a("style, link").each(function(){o+=g(this)}),a(m.document.head).html(o),a(m.document.body).html("

"+n+"

"+f.message+"
"+j),f.customize&&f.customize(m),setTimeout(function(){f.autoPrint&&(m.print(),m.close())},250)},title:"*",message:"",exportOptions:{},header:!0,footer:!1,autoPrint:!0,customize:null},e.Buttons}); -------------------------------------------------------------------------------- /front-end/src/utils/util.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuzitao 3 | * @Date: 2017-08-13 01:05:44 4 | * @Last Modified time: 2017-08-30 19:15:49 5 | */ 6 | 7 | exports.distinctObjectArrayBy = function (arr, key, reverse) { 8 | let a = []; 9 | let names = []; 10 | function inner (i) { 11 | let o = arr[i]; 12 | if (names.indexOf(o[key]) === -1) { 13 | a.push(o); 14 | names.push(o[key]); 15 | } 16 | } 17 | if (reverse === 'reverse') { 18 | for (let i = arr.length - 1; i >= 0; i--) { 19 | inner(i) 20 | } 21 | return a.reverse() 22 | } else { 23 | for (let i = 0; i < arr.length; i++) { 24 | inner(i) 25 | } 26 | return a.reverse(); 27 | } 28 | } 29 | 30 | const regRootPath = /(^\/.*?)(\/|$)/ 31 | 32 | exports.getRootPath = function (vm) { 33 | return vm.$route.path.match(regRootPath)[1] 34 | } 35 | 36 | exports.getId = function (vm) { 37 | return vm.$route.params.id 38 | } 39 | 40 | exports.removeArrayElement = function (arr, elem) { 41 | return arr.splice(arr.indexOf(elem), 1) 42 | } 43 | 44 | exports.getRealTime = function (time) { 45 | return time.replace(/[T]|(\.\d{3}Z)/g, ' ') 46 | } 47 | 48 | exports.formatDate = function(date, fmt) { 49 | var o = { 50 | "M+": date.getMonth() + 1, //月份 51 | "d+": date.getDate(), //日 52 | "h+": date.getHours(), //小时 53 | "m+": date.getMinutes(), //分 54 | "s+": date.getSeconds(), //秒 55 | "q+": Math.floor((date.getMonth() + 3) / 3), //季度 56 | "S": date.getMilliseconds() //毫秒 57 | }; 58 | if (/(y+)/.test(fmt)) 59 | fmt = fmt.replace(RegExp.$1, (date.getFullYear() + "").substr(4 - RegExp.$1.length)); 60 | for (var k in o) 61 | if (new RegExp("(" + k + ")").test(fmt)) 62 | fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length))); 63 | return fmt; 64 | } -------------------------------------------------------------------------------- /front-end/src/assets/form.json: -------------------------------------------------------------------------------- 1 | { 2 | "labels": { 3 | "0": "身份证", 4 | "1": "姓名", 5 | "2": "性别", 6 | "3": "年龄", 7 | "4": "毕业学校", 8 | "5": "籍贯", 9 | "6": "政治面貌", 10 | "7": "部门", 11 | "8": "手机号码", 12 | "9": "QQ", 13 | "10": "邮箱" 14 | }, 15 | "icos": { 16 | "0": "credit-card-alt", 17 | "1": "user", 18 | "2": "", 19 | "3": "transgender-alt", 20 | "4": "graduation-cap", 21 | "5": "map-marker", 22 | "6": "user-secret", 23 | "7": "users", 24 | "8": "phone", 25 | "9": "qq", 26 | "10": "github" 27 | }, 28 | "holders": { 29 | "0": "请输入18位身份证号,最后一位可为X", 30 | "1": "请输入名字", 31 | "2": "", 32 | "3": "请输入年龄", 33 | "4": "请输入毕业学校", 34 | "5": "请输入省份+城市", 35 | "6": "请选择...", 36 | "7": "请选择...", 37 | "8": "请输入手机号码", 38 | "9": "请输入QQ", 39 | "10": "请输入邮箱" 40 | }, 41 | 42 | "sex": ["男", "女"], 43 | "party": ["中共党员", "中共预备党员", "共青团员", "无党派人士", "群众", "未知"], 44 | "department": ["Java", "UI", "前端", "未知"], 45 | 46 | "errors": { 47 | "身份证": ["身份证号不能为空", "身份证号不合法"], 48 | "姓名": ["姓名不能为空", "名字不合法"], 49 | "性别": ["请选择性别", ""], 50 | "年龄": ["年龄不能为空", "年龄需为整数"], 51 | "毕业学校": ["学校名不能为空", ""], 52 | "籍贯": ["籍贯不能为空", "籍贯不合法"], 53 | "政治面貌": ["请选择政治面貌", ""], 54 | "部门": ["请选择部门", ""], 55 | "手机号码": ["手机号码不能为空", "手机号码不合法"], 56 | "QQ": ["", "QQ号码不合法"], 57 | "邮箱": ["", "邮箱格式不合法"] 58 | }, 59 | "errorPatterns": { 60 | "身份证": "^(^[1-9]\\d{7}((0\\d)|(1[0-2]))(([0|1|2]\\d)|3[0-1])\\d{3}$)|(^[1-9]\\d{5}[1-9]\\d{3}((0\\d)|(1[0-2]))(([0|1|2]\\d)|3[0-1])((\\d{4})|\\d{3}[Xx])$)$", 61 | "姓名": "^[\u4e00-\u9fa5]{2,10}$", 62 | "性别": "", 63 | "年龄": "^[^0]\\d$", 64 | "毕业学校": "", 65 | "籍贯": "^[\u4e00-\u9fa5]+$", 66 | "政治面貌": "", 67 | "部门": "", 68 | "手机号码": "^1[3,5,7,8]\\d{9}$", 69 | "QQ": "^[1-9][0-9]{4,15}$", 70 | "邮箱": "^([a-zA-Z0-9]+[_|\\-|\\.]?)*[a-zA-Z0-9]+@([a-zA-Z0-9]+[_|\\-|\\.]?)*[a-zA-Z0-9]+(\\.[a-zA-Z]{2,3})+$" 71 | } 72 | } -------------------------------------------------------------------------------- /front-end/src/components/widget/profile-list.vue: -------------------------------------------------------------------------------- 1 | 6 | 22 | 23 | 49 | 50 | -------------------------------------------------------------------------------- /front-end/src/assets/cropper/src/js/variables.js: -------------------------------------------------------------------------------- 1 | var $window = $(window), 2 | $document = $(document), 3 | location = window.location, 4 | 5 | // Constants 6 | CROPPER_NAMESPACE = '.cropper', 7 | CROPPER_PREVIEW = 'preview' + CROPPER_NAMESPACE, 8 | 9 | // RegExps 10 | REGEXP_DRAG_TYPES = /^(e|n|w|s|ne|nw|sw|se|all|crop|move|zoom)$/, 11 | 12 | // Classes 13 | CLASS_MODAL = 'cropper-modal', 14 | CLASS_HIDE = 'cropper-hide', 15 | CLASS_HIDDEN = 'cropper-hidden', 16 | CLASS_INVISIBLE = 'cropper-invisible', 17 | CLASS_MOVE = 'cropper-move', 18 | CLASS_CROP = 'cropper-crop', 19 | CLASS_DISABLED = 'cropper-disabled', 20 | CLASS_BG = 'cropper-bg', 21 | 22 | // Events 23 | EVENT_MOUSE_DOWN = 'mousedown touchstart', 24 | EVENT_MOUSE_MOVE = 'mousemove touchmove', 25 | EVENT_MOUSE_UP = 'mouseup mouseleave touchend touchleave touchcancel', 26 | EVENT_WHEEL = 'wheel mousewheel DOMMouseScroll', 27 | EVENT_DBLCLICK = 'dblclick', 28 | EVENT_RESIZE = 'resize' + CROPPER_NAMESPACE, // Bind to window with namespace 29 | EVENT_BUILD = 'build' + CROPPER_NAMESPACE, 30 | EVENT_BUILT = 'built' + CROPPER_NAMESPACE, 31 | EVENT_DRAG_START = 'dragstart' + CROPPER_NAMESPACE, 32 | EVENT_DRAG_MOVE = 'dragmove' + CROPPER_NAMESPACE, 33 | EVENT_DRAG_END = 'dragend' + CROPPER_NAMESPACE, 34 | EVENT_ZOOM_IN = 'zoomin' + CROPPER_NAMESPACE, 35 | EVENT_ZOOM_OUT = 'zoomout' + CROPPER_NAMESPACE, 36 | 37 | // Supports 38 | SUPPORT_CANVAS = $.isFunction($('')[0].getContext), 39 | 40 | // Others 41 | sqrt = Math.sqrt, 42 | min = Math.min, 43 | max = Math.max, 44 | abs = Math.abs, 45 | sin = Math.sin, 46 | cos = Math.cos, 47 | num = parseFloat, 48 | 49 | // Prototype 50 | prototype = {}; 51 | -------------------------------------------------------------------------------- /front-end/src/assets/cropper/fonts/icomoon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Generated by IcoMoon 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /front-end/src/assets/cropper/src/.jscsrc: -------------------------------------------------------------------------------- 1 | { 2 | "disallowEmptyBlocks": true, 3 | "disallowKeywords": ["with"], 4 | "disallowMixedSpacesAndTabs": true, 5 | "disallowMultipleLineStrings": true, 6 | "disallowQuotedKeysInObjects": "allButReserved", 7 | "disallowSpaceAfterPrefixUnaryOperators": ["++", "--", "+", "-", "~", "!"], 8 | "disallowSpaceBeforeBinaryOperators": [","], 9 | "disallowSpaceBeforePostfixUnaryOperators": ["++", "--"], 10 | "disallowSpacesInNamedFunctionExpression": { "beforeOpeningRoundBrace": true }, 11 | "disallowSpacesInsideArrayBrackets": true, 12 | "disallowSpacesInsideParentheses": true, 13 | "disallowTrailingComma": true, 14 | "disallowTrailingWhitespace": true, 15 | "requireCamelCaseOrUpperCaseIdentifiers": true, 16 | "requireCapitalizedConstructors": true, 17 | "requireCommaBeforeLineBreak": true, 18 | "requireDotNotation": true, 19 | "requireLineFeedAtFileEnd": true, 20 | "requireSpaceAfterBinaryOperators": ["+", "-", "/", "*", "=", "==", "===", "!=", "!==", ">", "<", ">=", "<="], 21 | "requireSpaceAfterKeywords": ["if", "else", "for", "while", "do", "switch", "return", "try", "catch"], 22 | "requireSpaceAfterLineComment": true, 23 | "requireSpaceBeforeBinaryOperators": ["+", "-", "/", "*", "=", "==", "===", "!=", "!==", ">", "<", ">=", "<="], 24 | "requireSpaceBetweenArguments": true, 25 | "requireSpacesInAnonymousFunctionExpression": { "beforeOpeningCurlyBrace": true, "beforeOpeningRoundBrace": true }, 26 | "requireSpacesInConditionalExpression": true, 27 | "requireSpacesInForStatement": true, 28 | "requireSpacesInFunctionDeclaration": { "beforeOpeningCurlyBrace": true }, 29 | "requireSpacesInFunctionExpression": { "beforeOpeningCurlyBrace": true }, 30 | "requireSpacesInNamedFunctionExpression": { "beforeOpeningCurlyBrace": true }, 31 | "requireSpacesInsideObjectBrackets": "allButNested", 32 | "validateIndentation": 2, 33 | "validateQuoteMarks": "'" 34 | } 35 | -------------------------------------------------------------------------------- /front-end/src/assets/cropper/src/js/load.js: -------------------------------------------------------------------------------- 1 | prototype.load = function (url) { 2 | var options = this.options, 3 | $this = this.$element, 4 | crossOrigin, 5 | bustCacheUrl, 6 | buildEvent, 7 | $clone; 8 | 9 | if (!url) { 10 | if ($this.is('img')) { 11 | if (!$this.attr('src')) { 12 | return; 13 | } 14 | 15 | url = $this.prop('src'); 16 | } else if ($this.is('canvas') && SUPPORT_CANVAS) { 17 | url = $this[0].toDataURL(); 18 | } 19 | } 20 | 21 | if (!url) { 22 | return; 23 | } 24 | 25 | buildEvent = $.Event(EVENT_BUILD); 26 | $this.one(EVENT_BUILD, options.build).trigger(buildEvent); // Only trigger once 27 | 28 | if (buildEvent.isDefaultPrevented()) { 29 | return; 30 | } 31 | 32 | if (options.checkImageOrigin && isCrossOriginURL(url)) { 33 | crossOrigin = 'anonymous'; 34 | 35 | if (!$this.prop('crossOrigin')) { // Only when there was not a "crossOrigin" property 36 | bustCacheUrl = addTimestamp(url); // Bust cache (#148) 37 | } 38 | } 39 | 40 | this.$clone = $clone = $(''); 41 | 42 | $clone.one('load', $.proxy(function () { 43 | var naturalWidth = $clone.prop('naturalWidth') || $clone.width(), 44 | naturalHeight = $clone.prop('naturalHeight') || $clone.height(); 45 | 46 | this.image = { 47 | naturalWidth: naturalWidth, 48 | naturalHeight: naturalHeight, 49 | aspectRatio: naturalWidth / naturalHeight, 50 | rotate: 0 51 | }; 52 | 53 | this.url = url; 54 | this.ready = true; 55 | this.build(); 56 | }, this)).one('error', function () { 57 | $clone.remove(); 58 | }).attr({ 59 | src: bustCacheUrl || url, 60 | crossOrigin: crossOrigin 61 | }); 62 | 63 | // Hide and insert into the document 64 | $clone.addClass(CLASS_HIDE).insertAfter($this); 65 | }; 66 | -------------------------------------------------------------------------------- /front-end/src/components/sidebar-item.vue: -------------------------------------------------------------------------------- 1 | 6 | 28 | 29 | 67 | 68 | -------------------------------------------------------------------------------- /front-end/config/index.js: -------------------------------------------------------------------------------- 1 | // see http://vuejs-templates.github.io/webpack for documentation. 2 | var path = require('path') 3 | 4 | module.exports = { 5 | build: { 6 | env: require('./prod.env'), 7 | index: path.resolve(__dirname, '../dist/index.html'), 8 | assetsRoot: path.resolve(__dirname, '../dist'), 9 | assetsSubDirectory: 'static', 10 | assetsPublicPath: './', 11 | productionSourceMap: true, 12 | // Gzip off by default as many popular static hosts such as 13 | // Surge or Netlify already gzip all static assets for you. 14 | // Before setting to `true`, make sure to: 15 | // npm install --save-dev compression-webpack-plugin 16 | productionGzip: false, 17 | productionGzipExtensions: ['js', 'css'], 18 | // Run the build command with an extra argument to 19 | // View the bundle analyzer report after build finishes: 20 | // `npm run build --report` 21 | // Set to `true` or `false` to always turn it on or off 22 | bundleAnalyzerReport: process.env.npm_config_report 23 | }, 24 | dev: { 25 | env: require('./dev.env'), 26 | port: 8080, 27 | autoOpenBrowser: true, 28 | assetsSubDirectory: 'static', 29 | assetsPublicPath: '/', 30 | proxyTable: { 31 | '/api': { 32 | target: require('../src/config/server'), 33 | secure: false, 34 | changeOrigin: true, 35 | pathRewrite: { 36 | '^/api': '/api' 37 | } 38 | } 39 | }, 40 | // CSS Sourcemaps off by default because relative paths are "buggy" 41 | // with this option, according to the CSS-Loader README 42 | // (https://github.com/webpack/css-loader#sourcemaps) 43 | // In our experience, they generally work as expected, 44 | // just be aware of this issue when enabling this option. 45 | cssSourceMap: false, 46 | 47 | inline: true, // 设置为true,当源文件改变时会自动刷新页面 48 | colors: true, // 设置为true,使终端输出的文件为彩色的 49 | // historyApiFallback: true, // 在开发单页应用时非常有用,它依赖于HTML5 history API,如果设置为true,所有的跳转将指向index.html 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /front-end/src/assets/cropper/src/js/template.js: -------------------------------------------------------------------------------- 1 | // Use the string compressor: Strmin (https://github.com/fengyuanchen/strmin) 2 | Cropper.TEMPLATE = (function (source, words) { 3 | words = words.split(','); 4 | return source.replace(/\d+/g, function (i) { 5 | return words[i]; 6 | }); 7 | })('<0 6="5-container"><0 6="5-canvas"><0 6="5-2-9" 3-2="move"><0 6="5-crop-9"><1 6="5-view-9"><1 6="5-8 8-h"><1 6="5-8 8-v"><1 6="5-face" 3-2="all"><1 6="5-7 7-e" 3-2="e"><1 6="5-7 7-n" 3-2="n"><1 6="5-7 7-w" 3-2="w"><1 6="5-7 7-s" 3-2="s"><1 6="5-4 4-e" 3-2="e"><1 6="5-4 4-n" 3-2="n"><1 6="5-4 4-w" 3-2="w"><1 6="5-4 4-s" 3-2="s"><1 6="5-4 4-ne" 3-2="ne"><1 6="5-4 4-nw" 3-2="nw"><1 6="5-4 4-sw" 3-2="sw"><1 6="5-4 4-se" 3-2="se">', 'div,span,drag,data,point,cropper,class,line,dashed,box'); 8 | 9 | /* Template source: 10 |
11 |
12 |
13 |
14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 |
31 |
32 | */ 33 | -------------------------------------------------------------------------------- /front-end/src/assets/cropper/src/js/defaults.js: -------------------------------------------------------------------------------- 1 | Cropper.DEFAULTS = { 2 | // Defines the aspect ratio of the crop box 3 | // Type: Number 4 | aspectRatio: NaN, 5 | 6 | // Defines the percentage of automatic cropping area when initializes 7 | // Type: Number (Must large than 0 and less than 1) 8 | autoCropArea: 0.8, // 80% 9 | 10 | // Outputs the cropping results. 11 | // Type: Function 12 | crop: null, 13 | 14 | // Add extra containers for previewing 15 | // Type: String (jQuery selector) 16 | preview: '', 17 | 18 | // Toggles 19 | strict: true, // strict mode, the image cannot zoom out less than the container 20 | responsive: true, // Rebuild when resize the window 21 | checkImageOrigin: true, // Check if the target image is cross origin 22 | 23 | modal: true, // Show the black modal 24 | guides: true, // Show the dashed lines for guiding 25 | highlight: true, // Show the white modal to highlight the crop box 26 | background: true, // Show the grid background 27 | 28 | autoCrop: true, // Enable to crop the image automatically when initialize 29 | dragCrop: true, // Enable to create new crop box by dragging over the image 30 | movable: true, // Enable to move the crop box 31 | resizable: true, // Enable to resize the crop box 32 | rotatable: true, // Enable to rotate the image 33 | zoomable: true, // Enable to zoom the image 34 | touchDragZoom: true, // Enable to zoom the image by wheeling mouse 35 | mouseWheelZoom: true, // Enable to zoom the image by dragging touch 36 | 37 | // Dimensions 38 | minCanvasWidth: 0, 39 | minCanvasHeight: 0, 40 | minCropBoxWidth: 0, 41 | minCropBoxHeight: 0, 42 | minContainerWidth: 200, 43 | minContainerHeight: 100, 44 | 45 | // Events 46 | build: null, // Function 47 | built: null, // Function 48 | dragstart: null, // Function 49 | dragmove: null, // Function 50 | dragend: null, // Function 51 | zoomin: null, // Function 52 | zoomout: null // Function 53 | }; 54 | 55 | Cropper.setDefaults = function (options) { 56 | $.extend(Cropper.DEFAULTS, options); 57 | }; 58 | -------------------------------------------------------------------------------- /front-end/src/assets/ace-master/js/jquery.hotkeys.index.min.js: -------------------------------------------------------------------------------- 1 | /*jslint browser: true*/ 2 | /*jslint jquery: true*/ 3 | !function(a){function b(b){if("string"==typeof b.data&&(b.data={keys:b.data}),b.data&&b.data.keys&&"string"==typeof b.data.keys){var c=b.handler,d=b.data.keys.toLowerCase().split(" ");b.handler=function(b){if(this===b.target||!(a.hotkeys.options.filterInputAcceptingElements&&a.hotkeys.textInputTypes.test(b.target.nodeName)||a.hotkeys.options.filterContentEditable&&a(b.target).attr("contenteditable")||a.hotkeys.options.filterTextInputs&&a.inArray(b.target.type,a.hotkeys.textAcceptingInputTypes)>-1)){var e="keypress"!==b.type&&a.hotkeys.specialKeys[b.which],f=String.fromCharCode(b.which).toLowerCase(),g="",h={};a.each(["alt","ctrl","shift"],function(a,c){b[c+"Key"]&&e!==c&&(g+=c+"+")}),b.metaKey&&!b.ctrlKey&&"meta"!==e&&(g+="meta+"),b.metaKey&&"meta"!==e&&g.indexOf("alt+ctrl+shift+")>-1&&(g=g.replace("alt+ctrl+shift+","hyper+")),e?h[g+e]=!0:(h[g+f]=!0,h[g+a.hotkeys.shiftNums[f]]=!0,"shift+"===g&&(h[a.hotkeys.shiftNums[f]]=!0));for(var i=0,j=d.length;j>i;i++)if(h[d[i]])return c.apply(this,arguments)}}}}a.hotkeys={version:"0.2.0",specialKeys:{8:"backspace",9:"tab",10:"return",13:"return",16:"shift",17:"ctrl",18:"alt",19:"pause",20:"capslock",27:"esc",32:"space",33:"pageup",34:"pagedown",35:"end",36:"home",37:"left",38:"up",39:"right",40:"down",45:"insert",46:"del",59:";",61:"=",96:"0",97:"1",98:"2",99:"3",100:"4",101:"5",102:"6",103:"7",104:"8",105:"9",106:"*",107:"+",109:"-",110:".",111:"/",112:"f1",113:"f2",114:"f3",115:"f4",116:"f5",117:"f6",118:"f7",119:"f8",120:"f9",121:"f10",122:"f11",123:"f12",144:"numlock",145:"scroll",173:"-",186:";",187:"=",188:",",189:"-",190:".",191:"/",192:"`",219:"[",220:"\\",221:"]",222:"'"},shiftNums:{"`":"~",1:"!",2:"@",3:"#",4:"$",5:"%",6:"^",7:"&",8:"*",9:"(",0:")","-":"_","=":"+",";":": ","'":'"',",":"<",".":">","/":"?","\\":"|"},textAcceptingInputTypes:["text","password","number","email","url","range","date","month","week","time","datetime","datetime-local","search","color","tel"],textInputTypes:/textarea|input|select/i,options:{filterInputAcceptingElements:!0,filterTextInputs:!0,filterContentEditable:!0}},a.each(["keydown","keyup","keypress"],function(){a.event.special[this]={add:b}})}(jQuery||this.jQuery||window.jQuery); -------------------------------------------------------------------------------- /front-end/build/utils.js: -------------------------------------------------------------------------------- 1 | var path = require('path') 2 | var config = require('../config') 3 | var ExtractTextPlugin = require('extract-text-webpack-plugin') 4 | 5 | exports.assetsPath = function (_path) { 6 | var assetsSubDirectory = process.env.NODE_ENV === 'production' 7 | ? config.build.assetsSubDirectory 8 | : config.dev.assetsSubDirectory 9 | return path.posix.join(assetsSubDirectory, _path) 10 | } 11 | 12 | exports.cssLoaders = function (options) { 13 | options = options || {} 14 | 15 | var cssLoader = { 16 | loader: 'css-loader', 17 | options: { 18 | minimize: process.env.NODE_ENV === 'production', 19 | sourceMap: options.sourceMap 20 | } 21 | } 22 | 23 | // generate loader string to be used with extract text plugin 24 | function generateLoaders (loader, loaderOptions) { 25 | var loaders = [cssLoader] 26 | if (loader) { 27 | loaders.push({ 28 | loader: loader + '-loader', 29 | options: Object.assign({}, loaderOptions, { 30 | sourceMap: options.sourceMap 31 | }) 32 | }) 33 | } 34 | 35 | // Extract CSS when that option is specified 36 | // (which is the case during production build) 37 | if (options.extract) { 38 | return ExtractTextPlugin.extract({ 39 | use: loaders, 40 | fallback: 'vue-style-loader' 41 | }) 42 | } else { 43 | return ['vue-style-loader'].concat(loaders) 44 | } 45 | } 46 | 47 | // https://vue-loader.vuejs.org/en/configurations/extract-css.html 48 | return { 49 | css: generateLoaders(), 50 | postcss: generateLoaders(), 51 | less: generateLoaders('less'), 52 | sass: generateLoaders('sass', { indentedSyntax: true }), 53 | scss: generateLoaders('sass'), 54 | stylus: generateLoaders('stylus'), 55 | styl: generateLoaders('stylus') 56 | } 57 | } 58 | 59 | // Generate loaders for standalone style files (outside of .vue) 60 | exports.styleLoaders = function (options) { 61 | var output = [] 62 | var loaders = exports.cssLoaders(options) 63 | for (var extension in loaders) { 64 | var loader = loaders[extension] 65 | output.push({ 66 | test: new RegExp('\\.' + extension + '$'), 67 | use: loader 68 | }) 69 | } 70 | return output 71 | } 72 | -------------------------------------------------------------------------------- /front-end/build/webpack.base.conf.js: -------------------------------------------------------------------------------- 1 | var path = require('path') 2 | var utils = require('./utils') 3 | var config = require('../config') 4 | var vueLoaderConfig = require('./vue-loader.conf') 5 | 6 | function resolve (dir) { 7 | return path.join(__dirname, '..', dir) 8 | } 9 | 10 | module.exports = { 11 | entry: { 12 | app: './src/main.js' 13 | }, 14 | output: { 15 | path: config.build.assetsRoot, 16 | filename: '[name].js', 17 | publicPath: process.env.NODE_ENV === 'production' 18 | ? config.build.assetsPublicPath 19 | : config.dev.assetsPublicPath 20 | }, 21 | resolve: { 22 | extensions: ['.js', '.vue', '.json'], 23 | alias: { 24 | 'vue$': 'vue/dist/vue.esm.js', 25 | '@': resolve('src') 26 | } 27 | }, 28 | module: { 29 | rules: [ 30 | { 31 | test: /\.(js|vue)$/, 32 | loader: 'eslint-loader', 33 | enforce: 'pre', 34 | include: [resolve('src'), resolve('test')], 35 | exclude: [resolve('src/utils'), resolve('src/assets')], 36 | options: { 37 | formatter: require('eslint-friendly-formatter') 38 | } 39 | }, 40 | { 41 | test: /\.vue$/, 42 | loader: 'vue-loader', 43 | options: vueLoaderConfig 44 | }, 45 | { 46 | test: /\.js$/, 47 | loader: 'babel-loader', 48 | include: [resolve('src'), resolve('test')] 49 | }, 50 | { 51 | test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, 52 | loader: 'url-loader', 53 | options: { 54 | limit: 10000, 55 | name: utils.assetsPath('img/[name].[hash:7].[ext]') 56 | } 57 | }, 58 | { 59 | test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/, 60 | loader: 'url-loader', 61 | options: { 62 | limit: 10000, 63 | name: utils.assetsPath('media/[name].[hash:7].[ext]') 64 | } 65 | }, 66 | { 67 | test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, 68 | // loader: 'url-loader', 69 | loader: 'file-loader', // 打包成fonts文件夹 70 | options: { 71 | limit: 10000, 72 | name: utils.assetsPath('fonts/[name].[hash:7].[ext]') 73 | } 74 | }, 75 | { 76 | test: /\.(txt|md)$/, 77 | loader: 'raw-loader' 78 | } 79 | ] 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /back-end/service/user.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuzitao 3 | * @Date: 2017-08-07 14:49:58 4 | * @Last Modified time: 2017-08-30 16:56:57 5 | */ 6 | 7 | 'use strict' 8 | const query = require('../db/userDao') 9 | 10 | module.exports = function User (req, res) { 11 | this.isPwdCorrect = pms => { 12 | let uname = pms.uname 13 | query(query.fun.pwd, pms) 14 | .done( result => { 15 | if (result[0] && result[0].status) { 16 | // 没有登录过就记录登记时间和次数 17 | if (!req.session[uname]) { 18 | this.record(uname) 19 | } 20 | req.session[uname] = uname; // 有该用户名才算有登录过并且未过期 21 | res.send({ result: true }); 22 | } else { 23 | res.send({ result: false }); 24 | } 25 | }) 26 | return this 27 | } 28 | this.record = uname => { 29 | query(query.fun.record, { uname }) 30 | return this 31 | } 32 | this.isLogin = id => { 33 | if (req.session[id]) 34 | res.send({ isVisit: true }) 35 | else 36 | res.send({ isVisit: false }) 37 | return this 38 | } 39 | this.modifyPwd = pms => { 40 | query(query.fun.mdpwd, pms) 41 | .done( result => { 42 | res.send({ result }) 43 | }) 44 | return this 45 | } 46 | this.getPersonalData = pms => { 47 | query(query.fun.perdata, pms) 48 | .done(result => { 49 | if (!result[0]) 50 | res.send({ info: '' }) 51 | else 52 | res.send({ info: result[0] }) 53 | }) 54 | return this 55 | } 56 | this.checkId = pms => { 57 | query(query.fun.checkid, pms) 58 | .done(result => { 59 | if (result[0]) 60 | res.send({ isExist: true }) 61 | else 62 | res.send({ isExist: false }) 63 | }) 64 | return this 65 | } 66 | this.addUser = pms => { 67 | query(query.fun.adduser, pms) 68 | .done(result => { 69 | res.send({ result }) 70 | }) 71 | return this 72 | } 73 | this.getUserInfo = pms => { 74 | query(query.fun.getuser, pms) 75 | .done(result => { 76 | res.send(result) 77 | }) 78 | return this 79 | } 80 | this.modifyUser = pms => { 81 | query(query.fun.moduser, pms) 82 | .done(result => { 83 | res.send({ result }) 84 | }) 85 | } 86 | this.disableUser = pms => { 87 | query(query.fun.disable, pms) 88 | .done(result => { 89 | res.send({ result }) 90 | }) 91 | return this 92 | } 93 | this.setHeadImage = pms => { 94 | query(query.fun.sethead, pms) 95 | .done(result => { 96 | res.send({ result }) 97 | }) 98 | } 99 | } -------------------------------------------------------------------------------- /front-end/src/components/widget/confirm-dialog.vue: -------------------------------------------------------------------------------- 1 | 6 | 20 | 21 | 76 | 77 | -------------------------------------------------------------------------------- /front-end/src/components/main/information-profile.vue: -------------------------------------------------------------------------------- 1 | 6 | 21 | 22 | 78 | 79 | -------------------------------------------------------------------------------- /front-end/src/assets/ace-master/js/jquery.flot.resize.min.js: -------------------------------------------------------------------------------- 1 | /* Flot plugin for automatically redrawing plots as the placeholder resizes. 2 | 3 | Copyright (c) 2007-2014 IOLA and Ole Laursen. 4 | Licensed under the MIT license. 5 | 6 | It works by listening for changes on the placeholder div (through the jQuery 7 | resize event plugin) - if the size changes, it will redraw the plot. 8 | 9 | There are no options. If you need to disable the plugin for some plots, you 10 | can just fix the size of their placeholders. 11 | 12 | */ 13 | !function(a,b,c){"$:nomunge";function d(c){h===!0&&(h=c||1);for(var i=f.length-1;i>=0;i--){var m=a(f[i]);if(m[0]==b||m.is(":visible")){var n=m.width(),o=m.height(),p=m.data(k);!p||n===p.w&&o===p.h||(m.trigger(j,[p.w=n,p.h=o]),h=c||!0)}else p=m.data(k),p.w=0,p.h=0}null!==e&&(h&&(null==c||1e3>c-h)?e=b.requestAnimationFrame(d):(e=setTimeout(d,g[l]),h=!1))}var e,f=[],g=a.resize=a.extend(a.resize,{}),h=!1,i="setTimeout",j="resize",k=j+"-special-event",l="pendingDelay",m="activeDelay",n="throttleWindow";g[l]=200,g[m]=20,g[n]=!0,a.event.special[j]={setup:function(){if(!g[n]&&this[i])return!1;var b=a(this);f.push(this),b.data(k,{w:b.width(),h:b.height()}),1===f.length&&(e=c,d())},teardown:function(){if(!g[n]&&this[i])return!1;for(var b=a(this),c=f.length-1;c>=0;c--)if(f[c]==this){f.splice(c,1);break}b.removeData(k),f.length||(h?cancelAnimationFrame(e):clearTimeout(e),e=null)},add:function(b){function d(b,d,f){var g=a(this),h=g.data(k)||{};h.w=d!==c?d:g.width(),h.h=f!==c?f:g.height(),e.apply(this,arguments)}if(!g[n]&&this[i])return!1;var e;return a.isFunction(b)?(e=b,d):(e=b.handler,void(b.handler=d))}},b.requestAnimationFrame||(b.requestAnimationFrame=function(){return b.webkitRequestAnimationFrame||b.mozRequestAnimationFrame||b.oRequestAnimationFrame||b.msRequestAnimationFrame||function(a,c){return b.setTimeout(function(){a((new Date).getTime())},g[m])}}()),b.cancelAnimationFrame||(b.cancelAnimationFrame=function(){return b.webkitCancelRequestAnimationFrame||b.mozCancelRequestAnimationFrame||b.oCancelRequestAnimationFrame||b.msCancelRequestAnimationFrame||clearTimeout}())}(jQuery,this),function(a){function b(a){function b(){var b=a.getPlaceholder();0!=b.width()&&0!=b.height()&&(a.resize(),a.setupGrid(),a.draw())}function c(a,c){a.getPlaceholder().resize(b)}function d(a,c){a.getPlaceholder().unbind("resize",b)}a.hooks.bindEvents.push(c),a.hooks.shutdown.push(d)}var c={};a.plot.plugins.push({init:b,options:c,name:"resize",version:"1.0"})}(jQuery); -------------------------------------------------------------------------------- /front-end/src/assets/cropper/src/js/preview.js: -------------------------------------------------------------------------------- 1 | prototype.initPreview = function () { 2 | var url = this.url; 3 | 4 | this.$preview = $(this.options.preview); 5 | this.$viewBox.html(''); 6 | 7 | // Override img element styles 8 | // Add `display:block` to avoid margin top issue (Occur only when margin-top <= -height) 9 | this.$preview.each(function () { 10 | var $this = $(this); 11 | 12 | $this.data(CROPPER_PREVIEW, { 13 | width: $this.width(), 14 | height: $this.height(), 15 | original: $this.html() 16 | }).html(''); 17 | }); 18 | }; 19 | 20 | prototype.resetPreview = function () { 21 | this.$preview.each(function () { 22 | var $this = $(this); 23 | 24 | $this.html($this.data(CROPPER_PREVIEW).original).removeData(CROPPER_PREVIEW); 25 | }); 26 | }; 27 | 28 | prototype.preview = function () { 29 | var image = this.image, 30 | canvas = this.canvas, 31 | cropBox = this.cropBox, 32 | width = image.width, 33 | height = image.height, 34 | left = cropBox.left - canvas.left - image.left, 35 | top = cropBox.top - canvas.top - image.top, 36 | rotate = image.rotate; 37 | 38 | if (!this.cropped || this.disabled) { 39 | return; 40 | } 41 | 42 | this.$viewBox.find('img').css({ 43 | width: width, 44 | height: height, 45 | marginLeft: -left, 46 | marginTop: -top, 47 | transform: getRotateValue(rotate) 48 | }); 49 | 50 | this.$preview.each(function () { 51 | var $this = $(this), 52 | data = $this.data(CROPPER_PREVIEW), 53 | ratio = data.width / cropBox.width, 54 | newWidth = data.width, 55 | newHeight = cropBox.height * ratio; 56 | 57 | if (newHeight > data.height) { 58 | ratio = data.height / cropBox.height; 59 | newWidth = cropBox.width * ratio; 60 | newHeight = data.height; 61 | } 62 | 63 | $this.width(newWidth).height(newHeight).find('img').css({ 64 | width: width * ratio, 65 | height: height * ratio, 66 | marginLeft: -left * ratio, 67 | marginTop: -top * ratio, 68 | transform: getRotateValue(rotate) 69 | }); 70 | }); 71 | }; 72 | -------------------------------------------------------------------------------- /front-end/src/assets/cropper/examples/crop-avatar/css/main.css: -------------------------------------------------------------------------------- 1 | body { 2 | background-color: #fcfcfc; 3 | } 4 | 5 | .avatar-view { 6 | display: block; 7 | margin: 15% auto 5%; 8 | height: 220px; 9 | width: 220px; 10 | border: 3px solid #fff; 11 | border-radius: 5px; 12 | box-shadow: 0 0 5px rgba(0,0,0,.15); 13 | cursor: pointer; 14 | overflow: hidden; 15 | } 16 | 17 | .avatar-view img { 18 | width: 100%; 19 | } 20 | 21 | .avatar-body { 22 | padding-right: 15px; 23 | padding-left: 15px; 24 | } 25 | 26 | .avatar-upload { 27 | overflow: hidden; 28 | } 29 | 30 | .avatar-upload label { 31 | display: block; 32 | float: left; 33 | clear: left; 34 | width: 100px; 35 | } 36 | 37 | .avatar-upload input { 38 | display: block; 39 | margin-left: 110px; 40 | } 41 | 42 | .avater-alert { 43 | margin-top: 10px; 44 | margin-bottom: 10px; 45 | } 46 | 47 | .avatar-wrapper { 48 | height: 364px; 49 | width: 100%; 50 | margin-top: 15px; 51 | box-shadow: inset 0 0 5px rgba(0,0,0,.25); 52 | background-color: #fcfcfc; 53 | overflow: hidden; 54 | } 55 | 56 | .avatar-wrapper img { 57 | display: block; 58 | height: auto; 59 | max-width: 100%; 60 | } 61 | 62 | .avatar-preview { 63 | float: left; 64 | margin-top: 15px; 65 | margin-right: 15px; 66 | border: 1px solid #eee; 67 | border-radius: 4px; 68 | background-color: #fff; 69 | overflow: hidden; 70 | } 71 | 72 | .avatar-preview:hover { 73 | border-color: #ccf; 74 | box-shadow: 0 0 5px rgba(0,0,0,.15); 75 | } 76 | 77 | .avatar-preview img { 78 | width: 100%; 79 | } 80 | 81 | .preview-lg { 82 | height: 184px; 83 | width: 184px; 84 | margin-top: 15px; 85 | } 86 | 87 | .preview-md { 88 | height: 100px; 89 | width: 100px; 90 | } 91 | 92 | .preview-sm { 93 | height: 50px; 94 | width: 50px; 95 | } 96 | 97 | @media (min-width: 992px) { 98 | .avatar-preview { 99 | float: none; 100 | } 101 | } 102 | 103 | .avatar-btns { 104 | margin-top: 30px; 105 | margin-bottom: 15px; 106 | } 107 | 108 | .avatar-btns .btn-group { 109 | margin-right: 5px; 110 | } 111 | 112 | .loading { 113 | display: none; 114 | position: absolute; 115 | top: 0; 116 | right: 0; 117 | bottom: 0; 118 | left: 0; 119 | background: #fff url("../img/loading.gif") no-repeat center center; 120 | opacity: .75; 121 | filter: alpha(opacity=75); 122 | z-index: 20140628; 123 | } 124 | -------------------------------------------------------------------------------- /back-end/db/pool.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuzitao 3 | * @Date: 2017-08-01 20:56:10 4 | * @Last Modified time: 2017-08-13 00:38:23 5 | */ 6 | 'use strict' 7 | const fs = require('fs') 8 | const path = require('path') 9 | const mysql = require('mysql') 10 | const util = require('../util/util') 11 | 12 | const log = path.resolve('./log/') 13 | fs.existsSync(log) || fs.mkdirSync(log) 14 | 15 | const pool = mysql.createPool(require('../config/db')) 16 | 17 | const df = 'yyyy-MM-dd hh:mm:ss' 18 | const date = new Date() 19 | const getSqlType = sql => { 20 | return sql.match(/^(.*?)\s/)[1] 21 | } 22 | 23 | let writeErrorLog = function (err, errType, filePrefix=errType) { 24 | let errText = `[${errType.toUpperCase()} ERROR] - ` + date.format(df) + ` - ${err.message}\n` 25 | fs.open(path.join(log, `${filePrefix.toLowerCase()}-excetion.` + date.format('yyyyMMdd') ), 26 | 'a', function (err, fd) { 27 | if (err) throw err 28 | fs.writeFileSync(fd, errText) 29 | fs.close(fd) 30 | }) 31 | } 32 | 33 | let query = (sql, sqls, conn, succCb, sqlArgs) => { 34 | function queryCb (err, result) { 35 | if (err) { 36 | console.error(err) 37 | conn.rollback() 38 | writeErrorLog(err, getSqlType(sql), 'query') 39 | } else { 40 | // 如果不是最后一条sql就不commit 41 | if (sqls.indexOf(sql) !== sqls.length -1) { 42 | return 43 | } 44 | conn.commit(function (err) { 45 | // commit失败 46 | if (err) { 47 | console.error(err) 48 | conn.rollback() 49 | writeErrorLog(err, 'COMMIT') 50 | } else { 51 | succCb(result) 52 | // succCb.apply(null, result); 53 | conn.release() 54 | } 55 | }) 56 | } 57 | } 58 | sqlArgs ? conn.query(sql, sqlArgs, queryCb) : conn.query(sql, queryCb) 59 | } 60 | 61 | module.exports = { 62 | succConnection(sqls) { 63 | let sqlArgs, succCallback = arguments[1] 64 | if (arguments[2]) { 65 | succCallback = arguments[2] 66 | sqlArgs = arguments[1] 67 | } 68 | pool.getConnection( (err, conn) => { 69 | // 连接失败 70 | if (err) { 71 | console.error(err) 72 | writeErrorLog(err, 'CONNECTION') 73 | } else { 74 | conn.beginTransaction(function (err) { 75 | // transaction问题 76 | if (err) { 77 | console.error(err) 78 | writeErrorLog(err, 'transaction') 79 | } else { 80 | typeof sqls === 'string' && ( sqls = [sqls] ) 81 | for (let i = 0; i < sqls.length; i++) { 82 | query(sqls[i], sqls, conn, succCallback, sqlArgs) 83 | } 84 | } 85 | }) 86 | } 87 | }) 88 | } 89 | } -------------------------------------------------------------------------------- /front-end/src/components/navbar.vue: -------------------------------------------------------------------------------- 1 | 6 | 34 | 35 | 66 | 67 | -------------------------------------------------------------------------------- /front-end/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "student-management-system", 3 | "version": "1.0.0", 4 | "description": "A useful management system", 5 | "author": "Wuzitao", 6 | "private": true, 7 | "scripts": { 8 | "dev": "node build/dev-server.js", 9 | "start": "node build/dev-server.js", 10 | "build": "node build/build.js", 11 | "lint": "eslint --ext .js,.vue src" 12 | }, 13 | "dependencies": { 14 | "axios": "^0.16.2", 15 | "bootstrap": "^3.3.7", 16 | "cropper": "^3.0.0-rc.3", 17 | "crypto": "^0.0.3", 18 | "css-loader": "^0.28.4", 19 | "jquery": "^3.2.1", 20 | "jquery.cookie": "^1.4.1", 21 | "vue": "^2.3.3", 22 | "vue-resource": "^1.3.4", 23 | "vue-router": "^2.6.0", 24 | "vuex": "^2.3.1" 25 | }, 26 | "devDependencies": { 27 | "autoprefixer": "^7.1.2", 28 | "babel-core": "^6.22.1", 29 | "babel-eslint": "^7.1.1", 30 | "babel-loader": "^7.1.1", 31 | "babel-plugin-transform-runtime": "^6.22.0", 32 | "babel-preset-env": "^1.3.2", 33 | "babel-preset-stage-2": "^6.22.0", 34 | "babel-register": "^6.22.0", 35 | "chalk": "^2.0.1", 36 | "connect-history-api-fallback": "^1.3.0", 37 | "copy-webpack-plugin": "^4.0.1", 38 | "css-loader": "^0.28.0", 39 | "cssnano": "^3.10.0", 40 | "eslint": "^3.19.0", 41 | "eslint-config-standard": "^6.2.1", 42 | "eslint-friendly-formatter": "^3.0.0", 43 | "eslint-loader": "^1.7.1", 44 | "eslint-plugin-html": "^3.0.0", 45 | "eslint-plugin-promise": "^3.4.0", 46 | "eslint-plugin-standard": "^2.0.1", 47 | "eventsource-polyfill": "^0.9.6", 48 | "express": "^4.14.1", 49 | "extract-text-webpack-plugin": "^2.0.0", 50 | "file-loader": "^0.11.1", 51 | "friendly-errors-webpack-plugin": "^1.1.3", 52 | "html-webpack-plugin": "^2.28.0", 53 | "http-proxy-middleware": "^0.17.3", 54 | "opn": "^5.1.0", 55 | "optimize-css-assets-webpack-plugin": "^2.0.0", 56 | "ora": "^1.2.0", 57 | "raw-loader": "^0.5.1", 58 | "rimraf": "^2.6.0", 59 | "semver": "^5.3.0", 60 | "shelljs": "^0.7.6", 61 | "url-loader": "^0.5.8", 62 | "vue-loader": "^12.1.0", 63 | "vue-style-loader": "^3.0.1", 64 | "vue-template-compiler": "^2.3.3", 65 | "webpack": "^2.6.1", 66 | "webpack-bundle-analyzer": "^2.2.1", 67 | "webpack-dev-middleware": "^1.10.0", 68 | "webpack-hot-middleware": "^2.18.0", 69 | "webpack-merge": "^4.1.0" 70 | }, 71 | "engines": { 72 | "node": ">= 4.0.0", 73 | "npm": ">= 3.0.0" 74 | }, 75 | "browserslist": [ 76 | "> 1%", 77 | "last 2 versions", 78 | "not ie <= 8" 79 | ] 80 | } 81 | -------------------------------------------------------------------------------- /front-end/src/assets/ace-master/js/buttons.colVis.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Column visibility buttons for Buttons and DataTables. 3 | * 2015 SpryMedia Ltd - datatables.net/license 4 | */ 5 | !function(a){"function"==typeof define&&define.amd?define(["jquery","datatables.net","datatables.net-buttons"],function(b){return a(b,window,document)}):"object"==typeof exports?module.exports=function(b,c){return b||(b=window),c&&c.fn.dataTable||(c=require("datatables.net")(b,c).$),c.fn.dataTable.Buttons||require("datatables.net-buttons")(b,c),a(c,b,b.document)}:a(jQuery,window,document)}(function(a,b,c,d){"use strict";var e=a.fn.dataTable;return a.extend(e.ext.buttons,{colvis:function(a,b){return{extend:"collection",text:function(a){return a.i18n("buttons.colvis","Column visibility")},className:"buttons-colvis",buttons:[{extend:"columnsToggle",columns:b.columns}]}},columnsToggle:function(a,b){var c=a.columns(b.columns).indexes().map(function(a){return{extend:"columnToggle",columns:a}}).toArray();return c},columnToggle:function(a,b){return{extend:"columnVisibility",columns:b.columns}},columnsVisibility:function(a,b){var c=a.columns(b.columns).indexes().map(function(a){return{extend:"columnVisibility",columns:a,visibility:b.visibility}}).toArray();return c},columnVisibility:{columns:d,text:function(a,b,c){return c._columnText(a,c.columns)},className:"buttons-columnVisibility",action:function(a,b,c,e){var f=b.columns(e.columns),g=f.visible();f.visible(e.visibility!==d?e.visibility:!(g.length?g[0]:!1))},init:function(a,b,c){var d=this,e=a.column(c.columns);a.on("column-visibility.dt"+c.namespace,function(a,b,e,f){b.bDestroying||e!==c.columns||d.active(f)}).on("column-reorder.dt"+c.namespace,function(b,e,f){if(1===a.columns(c.columns).count()){"number"==typeof c.columns&&(c.columns=f.mapping[c.columns]);var g=a.column(c.columns);d.text(c._columnText(a,c.columns)),d.active(g.visible())}}),this.active(e.visible())},destroy:function(a,b,c){a.off("column-visibility.dt"+c.namespace).off("column-reorder.dt"+c.namespace)},_columnText:function(a,b){var c=a.column(b).index();return a.settings()[0].aoColumns[c].sTitle.replace(/\n/g," ").replace(/<.*?>/g,"").replace(/^\s+|\s+$/g,"")}},colvisRestore:{className:"buttons-colvisRestore",text:function(a){return a.i18n("buttons.colvisRestore","Restore visibility")},init:function(a,b,c){c._visOriginal=a.columns().indexes().map(function(b){return a.column(b).visible()}).toArray()},action:function(a,b,c,d){b.columns().every(function(a){var c=b.colReorder&&b.colReorder.transpose?b.colReorder.transpose(a,"toOriginal"):a;this.visible(d._visOriginal[c])})}},colvisGroup:{className:"buttons-colvisGroup",action:function(a,b,c,d){b.columns(d.show).visible(!0),b.columns(d.hide).visible(!1)},show:[],hide:[]}}),e.Buttons}); -------------------------------------------------------------------------------- /front-end/src/assets/ace-master/js/html5shiv.min.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @preserve HTML5 Shiv 3.7.3 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed 3 | */ 4 | !function(a,b){function c(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x",d.insertBefore(c.lastChild,d.firstChild)}function d(){var a=t.elements;return"string"==typeof a?a.split(" "):a}function e(a,b){var c=t.elements;"string"!=typeof c&&(c=c.join(" ")),"string"!=typeof a&&(a=a.join(" ")),t.elements=c+" "+a,j(b)}function f(a){var b=s[a[q]];return b||(b={},r++,a[q]=r,s[r]=b),b}function g(a,c,d){if(c||(c=b),l)return c.createElement(a);d||(d=f(c));var e;return e=d.cache[a]?d.cache[a].cloneNode():p.test(a)?(d.cache[a]=d.createElem(a)).cloneNode():d.createElem(a),!e.canHaveChildren||o.test(a)||e.tagUrn?e:d.frag.appendChild(e)}function h(a,c){if(a||(a=b),l)return a.createDocumentFragment();c=c||f(a);for(var e=c.frag.cloneNode(),g=0,h=d(),i=h.length;i>g;g++)e.createElement(h[g]);return e}function i(a,b){b.cache||(b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag()),a.createElement=function(c){return t.shivMethods?g(c,a,b):b.createElem(c)},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+d().join().replace(/[\w\-:]+/g,function(a){return b.createElem(a),b.frag.createElement(a),'c("'+a+'")'})+");return n}")(t,b.frag)}function j(a){a||(a=b);var d=f(a);return!t.shivCSS||k||d.hasCSS||(d.hasCSS=!!c(a,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),l||i(a,d),a}var k,l,m="3.7.3",n=a.html5||{},o=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,p=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,q="_html5shiv",r=0,s={};!function(){try{var a=b.createElement("a");a.innerHTML="",k="hidden"in a,l=1==a.childNodes.length||function(){b.createElement("a");var a=b.createDocumentFragment();return"undefined"==typeof a.cloneNode||"undefined"==typeof a.createDocumentFragment||"undefined"==typeof a.createElement}()}catch(c){k=!0,l=!0}}();var t={elements:n.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:m,shivCSS:n.shivCSS!==!1,supportsUnknownElements:l,shivMethods:n.shivMethods!==!1,type:"default",shivDocument:j,createElement:g,createDocumentFragment:h,addElements:e};a.html5=t,j(b),"object"==typeof module&&module.exports&&(module.exports=t)}("undefined"!=typeof window?window:this,document); -------------------------------------------------------------------------------- /front-end/src/assets/cropper/src/js/build.js: -------------------------------------------------------------------------------- 1 | prototype.build = function () { 2 | var $this = this.$element, 3 | $clone = this.$clone, 4 | options = this.options, 5 | $cropper, 6 | $cropBox; 7 | 8 | if (!this.ready) { 9 | return; 10 | } 11 | 12 | if (this.built) { 13 | this.unbuild(); 14 | } 15 | 16 | // Create cropper elements 17 | this.$cropper = $cropper = $(Cropper.TEMPLATE); 18 | 19 | // Hide the original image 20 | $this.addClass(CLASS_HIDDEN); 21 | 22 | // Show the clone iamge 23 | $clone.removeClass(CLASS_HIDE); 24 | 25 | this.$container = $this.parent().append($cropper); 26 | this.$canvas = $cropper.find('.cropper-canvas').append($clone); 27 | this.$dragBox = $cropper.find('.cropper-drag-box'); 28 | this.$cropBox = $cropBox = $cropper.find('.cropper-crop-box'); 29 | this.$viewBox = $cropper.find('.cropper-view-box'); 30 | 31 | this.addListeners(); 32 | this.initPreview(); 33 | 34 | // Format aspect ratio 35 | options.aspectRatio = num(options.aspectRatio) || NaN; // 0 -> NaN 36 | 37 | if (options.autoCrop) { 38 | this.cropped = true; 39 | 40 | if (options.modal) { 41 | this.$dragBox.addClass(CLASS_MODAL); 42 | } 43 | } else { 44 | $cropBox.addClass(CLASS_HIDDEN); 45 | } 46 | 47 | if (options.background) { 48 | $cropper.addClass(CLASS_BG); 49 | } 50 | 51 | if (!options.highlight) { 52 | $cropBox.find('.cropper-face').addClass(CLASS_INVISIBLE); 53 | } 54 | 55 | if (!options.guides) { 56 | $cropBox.find('.cropper-dashed').addClass(CLASS_HIDDEN); 57 | } 58 | 59 | if (!options.movable) { 60 | $cropBox.find('.cropper-face').data('drag', 'move'); 61 | } 62 | 63 | if (!options.resizable) { 64 | $cropBox.find('.cropper-line, .cropper-point').addClass(CLASS_HIDDEN); 65 | } 66 | 67 | this.setDragMode(options.dragCrop ? 'crop' : 'move'); 68 | 69 | this.built = true; 70 | this.render(); 71 | $this.one(EVENT_BUILT, options.built).trigger(EVENT_BUILT); // Only trigger once 72 | }; 73 | 74 | prototype.unbuild = function () { 75 | if (!this.built) { 76 | return; 77 | } 78 | 79 | this.built = false; 80 | this.container = null; 81 | this.canvas = null; 82 | this.cropBox = null; // This is necessary when replace 83 | this.removeListeners(); 84 | 85 | this.resetPreview(); 86 | this.$preview = null; 87 | 88 | this.$viewBox = null; 89 | this.$cropBox = null; 90 | this.$dragBox = null; 91 | this.$canvas = null; 92 | this.$container = null; 93 | 94 | this.$cropper.remove(); 95 | this.$cropper = null; 96 | }; 97 | -------------------------------------------------------------------------------- /back-end/db/testDao.js: -------------------------------------------------------------------------------- 1 | const query = require('./baseDao'); 2 | 3 | let sql = 'select $column from $table'; 4 | let obj = { 5 | $column: '*', 6 | $table: 'test_user', 7 | $where: [ 8 | { 9 | name: 'uid', 10 | value: 00000000, 11 | }, 12 | // [{ 13 | // name: 'id', 14 | // value: '1', 15 | // relation: 'or' 16 | // }, 17 | // { 18 | // name: 'sex', 19 | // value: '男', 20 | // relation: 'AND' 21 | // }], 22 | ], 23 | // $order_by: [ 24 | // { 25 | // value: 'id' 26 | // } 27 | // ], 28 | } 29 | 30 | let selectobj2 = { 31 | $column: '*', 32 | $table: 'test', 33 | 34 | } 35 | let insertObj = { 36 | $table: 'test', 37 | name: 'yuanmeiqi', 38 | sex: '女' 39 | } 40 | let insertObj2 = { 41 | $table: 'test_user', 42 | uid: '20170525', 43 | pwd: '女' 44 | } 45 | query.begin(); 46 | // query.begin(); 47 | 48 | // query.insert(insertObj, function a1() { 49 | // // console.log(arguments) 50 | // }); 51 | // query.insert(insertObj2, function () { 52 | // console.log(arguments) 53 | // }); 54 | query.select(obj, function a2(argument) { 55 | // console.log('prev') 56 | console.log(arguments) 57 | }); 58 | 59 | // query.select(selectobj2, function (argument) { 60 | // // console.log(arguments) 61 | // }); 62 | 63 | // query.end(); 64 | // query.end(); 65 | 66 | 67 | // query.insert(insertObj, function (argument) { 68 | // console.log(arguments) 69 | // }) 70 | 71 | let updateObj = { 72 | $table: 'test', 73 | $set: { 74 | name: 'wuzitao', 75 | sex: '女', 76 | }, 77 | $where: [ 78 | { 79 | name: 'id', 80 | value: '19' 81 | } 82 | ], 83 | } 84 | 85 | // query.update(updateObj, function a3(argument) { 86 | // console.log(arguments) 87 | // }) 88 | // query.update(updateObj, function (argument) { 89 | // console.log(arguments) 90 | // }) 91 | 92 | let deleteObj = { 93 | $table: 'test', 94 | $where: [ 95 | { 96 | name: 'id', 97 | value: '19', 98 | } 99 | ], 100 | } 101 | 102 | // query.delete(deleteObj, function (argument) { 103 | // console.log(argument) 104 | // }) 105 | query.end(); 106 | 107 | router.get('/test', (req, res) => { 108 | const {tableJoinOn} = require('../db/baseDao.js') 109 | const BaseDao = require('../db/baseDao.js') 110 | const baseDao = new BaseDao() 111 | let args = { 112 | $table: [ 113 | { name: 'baseinfo'}, 114 | { 115 | name: 'user', on: { 116 | table: 'baseinfo', 117 | value: 'uid', 118 | prevValue: 'uid' 119 | } 120 | } 121 | ], 122 | $order_by: 'baseinfo.uid' 123 | } 124 | baseDao.select(args) 125 | .then(result => { 126 | res.send(result) 127 | }) 128 | }) -------------------------------------------------------------------------------- /front-end/src/assets/introduce.md: -------------------------------------------------------------------------------- 1 | # 学生管理系统(Node+Vue前后端分离的spa) 2 | ## 项目介绍 3 |   该管理系统是 4 | 5 | ## 开发环境 6 | Nodejs6.0.1 + Vue-cli2.8.2 + Sublime text3 + Webpack2.6.1 + Nginx1.12.1 + MySQL Server5.7 7 | 8 | ## 框架及插件 9 | #### 前端: 10 | - vue-cli: 搭建vue环境的脚手架工具 11 | - webpack: 模块化项目的打包工具 12 | - jquery: 主要用到其进行DOM操作和ajax 13 | - boostrap: 响应式样式框架 14 | - font-awesome: 一套绝佳的图标字体库和CSS框架 15 | - cropper: 基于jquery的图片裁剪插件 16 | 17 | #### 后端: 18 | - express: 一个简洁而灵活的 node.js Web应用框架 19 | - express-session: 本来是express中的一部分,4.0之后将很多模块独立出去 20 | - bluebird: 便于异步编程的Promise集成工具,可为fs类似的包含大量异步操作的模块提供promise操作 21 | - mysql: 用于node连接mysql数据库的模块 22 | 23 | ## 功能模块 24 | 25 | ## 填过的坑 26 | 1. **前端服务器访问后端服务器的跨域问题** 27 | 28 | 第一种解决方式: 后端服务器上设置`res.setHeader("Access-Control-Allow-Origin", 前端地址)`,获得跨域权限,但是这种方式有个缺陷,req.session在后端拿不到。 29 | 30 | 第二种解决方式: 前端服务器上在config -> index.js上设置dev -> proxyTable: `{ '/api': { target: 后端地址, changeOrigin: true } }`, 提供一个完整的转发接口就可以完成前后端的通信。 31 | 32 | 2. **import boostrap找不到jquery的问题** 33 | 34 | 原因是webpack打包过程中只识别jquery,不识别jQuery或$之类的写法,因此需要在build -> webpack.dev.conf中加入`new webpack.ProvidePlugin({ jQuery: 'jquery', $: 'jquery', 'window.jQuery': 'jquery' })` 35 | 36 | 3. **父组件向子组件传递对象数组且在子组件内修改数据并将结果返回给父组件的问题** 37 | 38 | 众所周知,vue2.0开始规定了子组件不能直接修改从父组件接收的prop,但是同时我们又想在子组件内修改其中的一些属性,以达到更新绑定在子组件上一些数据的目的,这就有点矛盾了。于是我想到一个方法既可以在不改变父组件数据的情况下修改从父组件传下来的数据。这里只对 **对象数组(数组中只存放对象)** 进行分析。 39 | 40 | 1. 子组件修改从父组件传下来的数据而不改变父组件原本的数据 41 | 42 | 首先在子组件中获得父组件传下来的一份克隆数组(一般是直接接收,如果是从网络读数据则需要watch),而且数组中的对象全部需要克隆一份 43 | 44 | 2. 子组件中的对象数组中的元素顺序发生改变,如何在父组件中获得原来那个对象的坐标? 45 | 46 | 在将数组中对象克隆的时候为对象新增一个内置属性_originIndex,这样不管数组顺序如何改变,只要获得该对象就可以获得其原本的坐标,然后就可以将_originIndex,emit给父组件,让父组件获得对应的对象 47 | 48 | 4. **router-view不能响应@click事件,如果想在上面使用click事件,还是要用回\标签,click事件中实现$router的跳转** 49 | 50 | 5. **router-view无法自主刷新,只能折衷于先跳转到一个空白路由_blank,再跳回来当前路由** 51 | 52 | 6. **数据刷新后立刻对DOM进行访问的问题** 53 | 54 | 在数据刷新后,vue会对组件立即进行重新渲染,但是渲染需要一定的时间,如果在渲染完成之后立刻对DOM进行访问(如jQuery的查询),会得不到该DOM,因此需要加上vm.$nextTick(callback),然后对DOM的操作和访问都在callback里面完成 55 | 56 | 7. **vue实例里面的data中的对象通过增加属性不能响应的问题** 57 | 58 | 由于vue的限制,直接通过对数组的下标或增加对象上的方法改变值不能得到预期的效果,view得不到更新。vue1.x可以用vm.$set方法解决该问题,但是自2.0以后便不支持该形式,因此比较好的解决方法是先声明data的对象的所有属性,然后改变值的时候就能够得到响应。 59 | 60 | 8. **post请求的数据接收以及413错误** 61 | 62 | 在node中,在默认设置下,是不能获得post的请求数据的,需要引入body-parser模块以及设置express.use({ bodyParser.urlecoded({ extended: true }) })。而且默认情况下,过大的数据请求会被服务器拒绝,可以有两种方法解决: 63 | 1. 设置bodyParser.urlencoded({ limit: 最大请求体如'5mb' }) 64 | 2. 使用Nginx反向代理服务器设置client_max_body_size最大请求体 65 | 66 | ## 待改进地方 67 | - 需要尽量减少对DOM的操作,尽管有些复杂的DOM需要用到jQuery去完成,不过能用数据驱动的view尽量用vue实现。而且vue中的事件不能被jQuery克隆,应该还是谨慎在vue中使用jQuery 68 | - 组件间的数据和事件传递(父与子、兄弟之间、隔代之间)在一个项目中应该得到很好的控制。如果项目越做越大,组件间的操作会变得越来越难管理。vue在这方面做得有显不足,因此需要用到vuex来对大型应用进行管理,比如侧边栏和各个页面的对应关系等 69 | - 在缓存方面上做得工夫不足,应该增强在服务器上对用户信息的缓存(使用session缓存用户信息),以及在本地对不容易变化的数据进行缓存,减少对网络的请求次数 70 | -------------------------------------------------------------------------------- /front-end/build/dev-server.js: -------------------------------------------------------------------------------- 1 | require('./check-versions')() 2 | 3 | var config = require('../config') 4 | if (!process.env.NODE_ENV) { 5 | process.env.NODE_ENV = JSON.parse(config.dev.env.NODE_ENV) 6 | } 7 | 8 | var opn = require('opn') 9 | var path = require('path') 10 | var express = require('express') 11 | var webpack = require('webpack') 12 | var proxyMiddleware = require('http-proxy-middleware') 13 | var webpackConfig = require('./webpack.dev.conf') 14 | 15 | // default port where dev server listens for incoming traffic 16 | var port = process.env.PORT || config.dev.port 17 | // automatically open browser, if not set will be false 18 | var autoOpenBrowser = !!config.dev.autoOpenBrowser 19 | // Define HTTP proxies to your custom API backend 20 | // https://github.com/chimurai/http-proxy-middleware 21 | var proxyTable = config.dev.proxyTable 22 | 23 | var app = express() 24 | var compiler = webpack(webpackConfig) 25 | 26 | var devMiddleware = require('webpack-dev-middleware')(compiler, { 27 | publicPath: webpackConfig.output.publicPath, 28 | quiet: true 29 | }) 30 | 31 | var hotMiddleware = require('webpack-hot-middleware')(compiler, { 32 | log: () => {}, 33 | heartbeat: 2000 34 | }) 35 | // force page reload when html-webpack-plugin template changes 36 | compiler.plugin('compilation', function (compilation) { 37 | compilation.plugin('html-webpack-plugin-after-emit', function (data, cb) { 38 | hotMiddleware.publish({ action: 'reload' }) 39 | cb() 40 | }) 41 | }) 42 | 43 | // proxy api requests 44 | Object.keys(proxyTable).forEach(function (context) { 45 | var options = proxyTable[context] 46 | if (typeof options === 'string') { 47 | options = { target: options } 48 | } 49 | app.use(proxyMiddleware(options.filter || context, options)) 50 | }) 51 | 52 | // handle fallback for HTML5 history API 53 | app.use(require('connect-history-api-fallback')()) 54 | 55 | // serve webpack bundle output 56 | app.use(devMiddleware) 57 | 58 | // enable hot-reload and state-preserving 59 | // compilation error display 60 | app.use(hotMiddleware) 61 | 62 | // serve pure static assets 63 | var staticPath = path.posix.join(config.dev.assetsPublicPath, config.dev.assetsSubDirectory) 64 | app.use(staticPath, express.static('./static')) 65 | 66 | var uri = 'http://localhost:' + port 67 | 68 | var _resolve 69 | var readyPromise = new Promise(resolve => { 70 | _resolve = resolve 71 | }) 72 | 73 | console.log('> Starting dev server...') 74 | devMiddleware.waitUntilValid(() => { 75 | console.log('> Listening at ' + uri + '\n') 76 | // when env is testing, don't need open it 77 | if (autoOpenBrowser && process.env.NODE_ENV !== 'testing') { 78 | opn(uri) 79 | } 80 | _resolve() 81 | }) 82 | 83 | var server = app.listen(port) 84 | 85 | module.exports = { 86 | ready: readyPromise, 87 | close: () => { 88 | server.close() 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /front-end/src/assets/ace-master/css/colorbox.min.css: -------------------------------------------------------------------------------- 1 | #cboxWrapper,.cboxPhoto{max-width:none}.cboxIframe,.cboxPhoto{display:block;border:0}#cboxCurrent,#cboxTitle{position:absolute;color:#949494;bottom:4px}#cboxClose:active,#cboxNext:active,#cboxPrevious:active,#cboxSlideshow:active,#colorbox{outline:0}#cboxOverlay,#cboxWrapper,#colorbox{position:absolute;top:0;left:0;z-index:9999;overflow:hidden}#cboxOverlay{position:fixed;width:100%;height:100%;background:url(images/overlay.png);opacity:.9;filter:alpha(opacity=90)}#cboxBottomLeft,#cboxMiddleLeft{clear:left}#cboxContent{position:relative;background:#fff;overflow:hidden}#cboxTitle{margin:0;left:0;text-align:center;width:100%}#cboxLoadingGraphic,#cboxLoadingOverlay{position:absolute;top:0;left:0;width:100%;height:100%}.cboxPhoto{float:left;margin:auto;-ms-interpolation-mode:bicubic}.cboxIframe{width:100%;height:100%;padding:0;margin:0}#cboxContent,#cboxLoadedContent,#colorbox{box-sizing:content-box;-moz-box-sizing:content-box;-webkit-box-sizing:content-box}#cboxTopLeft{width:21px;height:21px;background:url(images/controls.png) -101px 0 no-repeat}#cboxTopRight{width:21px;height:21px;background:url(images/controls.png) -130px 0 no-repeat}#cboxBottomLeft{width:21px;height:21px;background:url(images/controls.png) -101px -29px no-repeat}#cboxBottomRight{width:21px;height:21px;background:url(images/controls.png) -130px -29px no-repeat}#cboxMiddleLeft{width:21px;background:url(images/controls.png) left top repeat-y}#cboxMiddleRight{width:21px;background:url(images/controls.png) right top repeat-y}#cboxTopCenter{height:21px;background:url(images/border.png) repeat-x}#cboxBottomCenter{height:21px;background:url(images/border.png) 0 -29px repeat-x}.cboxIframe{background:#fff}#cboxError{padding:50px;border:1px solid #ccc}#cboxLoadedContent{overflow:auto;-webkit-overflow-scrolling:touch;margin-bottom:28px}#cboxCurrent{left:58px}#cboxLoadingOverlay{background:url(images/loading_background.png) center center no-repeat}#cboxLoadingGraphic{background:url(images/loading.gif) center center no-repeat}#cboxClose,#cboxNext,#cboxPrevious,#cboxSlideshow{cursor:pointer;border:0;padding:0;margin:0;overflow:visible;width:auto;background:0 0}#cboxClose,#cboxNext,#cboxPrevious{position:absolute;bottom:0;width:25px;height:25px;text-indent:-9999px}#cboxSlideshow{position:absolute;bottom:4px;right:30px;color:#0092ef}#cboxPrevious{left:0;background:url(images/controls.png) -75px 0 no-repeat}#cboxPrevious:hover{background-position:-75px -25px}#cboxNext{left:27px;background:url(images/controls.png) -50px 0 no-repeat}#cboxNext:hover{background-position:-50px -25px}#cboxClose{right:0;background:url(images/controls.png) -25px 0 no-repeat}#cboxClose:hover{background-position:-25px -25px}.cboxIE #cboxBottomCenter,.cboxIE #cboxBottomLeft,.cboxIE #cboxBottomRight,.cboxIE #cboxMiddleLeft,.cboxIE #cboxMiddleRight,.cboxIE #cboxTopCenter,.cboxIE #cboxTopLeft,.cboxIE #cboxTopRight{filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#00FFFFFF, endColorstr=#00FFFFFF)} -------------------------------------------------------------------------------- /front-end/src/App.vue: -------------------------------------------------------------------------------- 1 | 6 | 15 | 16 | 84 | 85 | 93 | -------------------------------------------------------------------------------- /back-end/db.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE `user` ( 2 | `uid` char(10) NOT NULL COMMENT '用户id=年份(4位)+部门(2位)+批次(2位)+序号(2位)', 3 | `pwd` varchar(50) NOT NULL COMMENT '密码', 4 | `role` enum('超级管理员','管理员','教师','学生','访客') NOT NULL DEFAULT '访客' COMMENT '用户角色', 5 | `status` tinyint(1) NOT NULL DEFAULT '1' COMMENT '状态,true可用、false禁用', 6 | `reg_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '注册时间', 7 | `reg_id` char(10) NOT NULL COMMENT '录入注册信息的人,即管理员id', 8 | `login_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '用户登录时间', 9 | `login_count` smallint(6) NOT NULL DEFAULT '0' COMMENT '登录次数', 10 | PRIMARY KEY (`uid`) 11 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 12 | 13 | CREATE TABLE `permission` ( 14 | `pid` tinyint(4) NOT NULL AUTO_INCREMENT COMMENT '序号', 15 | `perm_role` enum('超级管理员','管理员','教师','学生','访客') NOT NULL COMMENT '权限使用角色', 16 | `perm_names` varchar(1000) NOT NULL COMMENT '权限名称,用&连接,子权限用.表示', 17 | PRIMARY KEY (`pid`) 18 | ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 19 | 20 | CREATE TABLE `department` ( 21 | `did` tinyint(4) NOT NULL, 22 | `d_name` enum('UI','Java','前端','未知') NOT NULL DEFAULT '未知', 23 | `batch` tinyint(4) NOT NULL DEFAULT '0', 24 | `people_count` smallint(6) NOT NULL DEFAULT '0', 25 | `reg_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP 26 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 27 | 28 | CREATE TABLE `baseinfo` ( 29 | `uid` char(10) NOT NULL COMMENT '用户id', 30 | `_id` char(18) NOT NULL COMMENT '身份证', 31 | `realname` varchar(10) NOT NULL COMMENT '真实姓名', 32 | `sex` enum('男','女') NOT NULL COMMENT '性别,‘男’、‘女’', 33 | `age` varchar(3) NOT NULL DEFAULT '未知' COMMENT '年龄', 34 | `school` varchar(255) NOT NULL DEFAULT '未知' COMMENT '毕业学校', 35 | `birthplace` varchar(50) NOT NULL DEFAULT '未知' COMMENT '籍贯', 36 | `party` enum('中共党员','中共预备党员','共青团员','无党派人士','群众','未知') NOT NULL DEFAULT '未知' COMMENT '政治面貌', 37 | `department` enum('前端','Java','UI','未知') NOT NULL DEFAULT '未知' COMMENT '部门', 38 | `phone` char(11) NOT NULL DEFAULT '未知' COMMENT '手机号码', 39 | `qq` varchar(15) NOT NULL DEFAULT '未知' COMMENT 'QQ号码', 40 | `email` varchar(50) NOT NULL DEFAULT '未知' COMMENT '电子邮箱', 41 | `head` longtext COMMENT '头像base64', 42 | PRIMARY KEY (`_id`), 43 | KEY `uid` (`uid`), 44 | CONSTRAINT `uid` FOREIGN KEY (`uid`) REFERENCES `user` (`uid`) 45 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 46 | 47 | CREATE TABLE `article` ( 48 | `aid` smallint(5) NOT NULL AUTO_INCREMENT COMMENT '文章id', 49 | `article_title` varchar(128) NOT NULL COMMENT '文章名称', 50 | `article_content` text NOT NULL COMMENT '文章内容', 51 | `article_summary` varchar(120) NOT NULL DEFAULT '' COMMENT '文章摘要', 52 | `publish_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '发布时间', 53 | `click` int(10) NOT NULL DEFAULT '0' COMMENT '查看人数', 54 | `sort_name` varchar(10) NOT NULL DEFAULT 'unknown' COMMENT '所属分类名称', 55 | `user_id` char(10) NOT NULL COMMENT '所属用户id', 56 | `up` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否置顶', 57 | PRIMARY KEY (`aid`) 58 | ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 -------------------------------------------------------------------------------- /front-end/src/assets/ace-master/css/jquery-ui.custom.min.css: -------------------------------------------------------------------------------- 1 | /*! jQuery UI - v1.11.4 - 2015-09-20 2 | * http://jqueryui.com 3 | * Includes: core.css, draggable.css, resizable.css, selectable.css, sortable.css, slider.css 4 | * Copyright 2015 jQuery Foundation and other contributors; Licensed MIT */.ui-helper-hidden{display:none}.ui-helper-hidden-accessible{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.ui-helper-reset{margin:0;padding:0;border:0;outline:0;line-height:1.3;text-decoration:none;font-size:100%;list-style:none}.ui-helper-clearfix:after,.ui-helper-clearfix:before{content:"";display:table;border-collapse:collapse}.ui-helper-clearfix:after{clear:both}.ui-helper-clearfix{min-height:0}.ui-helper-zfix{width:100%;height:100%;top:0;left:0;position:absolute;opacity:0;filter:Alpha(Opacity=0)}.ui-front{z-index:100}.ui-state-disabled{cursor:default!important}.ui-icon{display:block;text-indent:-99999px;overflow:hidden;background-repeat:no-repeat}.ui-widget-overlay{position:fixed;top:0;left:0;width:100%;height:100%}.ui-draggable-handle{-ms-touch-action:none;touch-action:none}.ui-resizable{position:relative}.ui-resizable-handle{position:absolute;font-size:.1px;display:block;-ms-touch-action:none;touch-action:none}.ui-resizable-autohide .ui-resizable-handle,.ui-resizable-disabled .ui-resizable-handle{display:none}.ui-resizable-n{cursor:n-resize;height:7px;width:100%;top:-5px;left:0}.ui-resizable-s{cursor:s-resize;height:7px;width:100%;bottom:-5px;left:0}.ui-resizable-e{cursor:e-resize;width:7px;right:-5px;top:0;height:100%}.ui-resizable-w{cursor:w-resize;width:7px;left:-5px;top:0;height:100%}.ui-resizable-se{cursor:se-resize;width:12px;height:12px;right:1px;bottom:1px}.ui-resizable-sw{cursor:sw-resize;width:9px;height:9px;left:-5px;bottom:-5px}.ui-resizable-nw{cursor:nw-resize;width:9px;height:9px;left:-5px;top:-5px}.ui-resizable-ne{cursor:ne-resize;width:9px;height:9px;right:-5px;top:-5px}.ui-selectable{-ms-touch-action:none;touch-action:none}.ui-selectable-helper{position:absolute;z-index:100;border:1px dotted #000}.ui-sortable-handle{-ms-touch-action:none;touch-action:none}.ui-slider{position:relative;text-align:left}.ui-slider .ui-slider-handle{position:absolute;z-index:2;width:1.2em;height:1.2em;cursor:default;-ms-touch-action:none;touch-action:none}.ui-slider .ui-slider-range{position:absolute;z-index:1;font-size:.7em;display:block;border:0;background-position:0 0}.ui-slider.ui-state-disabled .ui-slider-handle,.ui-slider.ui-state-disabled .ui-slider-range{filter:inherit}.ui-slider-horizontal{height:.8em}.ui-slider-horizontal .ui-slider-handle{top:-.3em;margin-left:-.6em}.ui-slider-horizontal .ui-slider-range{top:0;height:100%}.ui-slider-horizontal .ui-slider-range-min{left:0}.ui-slider-horizontal .ui-slider-range-max{right:0}.ui-slider-vertical{width:.8em;height:100px}.ui-slider-vertical .ui-slider-handle{left:-.3em;margin-left:0;margin-bottom:-.6em}.ui-slider-vertical .ui-slider-range{left:0;width:100%}.ui-slider-vertical .ui-slider-range-min{bottom:0}.ui-slider-vertical .ui-slider-range-max{top:0} -------------------------------------------------------------------------------- /front-end/src/assets/ace-master/css/bootstrap-timepicker.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Timepicker Component for Twitter Bootstrap 3 | * 4 | * Copyright 2013 Joris de Wit 5 | * 6 | * Contributors https://github.com/jdewit/bootstrap-timepicker/graphs/contributors 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */.bootstrap-timepicker{position:relative}.bootstrap-timepicker.pull-right .bootstrap-timepicker-widget.dropdown-menu{left:auto;right:0}.bootstrap-timepicker.pull-right .bootstrap-timepicker-widget.dropdown-menu:before{left:auto;right:12px}.bootstrap-timepicker.pull-right .bootstrap-timepicker-widget.dropdown-menu:after{left:auto;right:13px}.bootstrap-timepicker .input-group-addon{cursor:pointer}.bootstrap-timepicker .input-group-addon i{display:inline-block;width:16px;height:16px}.bootstrap-timepicker-widget.dropdown-menu{padding:4px}.bootstrap-timepicker-widget.dropdown-menu.open{display:inline-block}.bootstrap-timepicker-widget.dropdown-menu:before{border-bottom:7px solid rgba(0,0,0,.2);border-left:7px solid transparent;border-right:7px solid transparent;content:"";display:inline-block;position:absolute}.bootstrap-timepicker-widget.dropdown-menu:after{border-bottom:6px solid #FFF;border-left:6px solid transparent;border-right:6px solid transparent;content:"";display:inline-block;position:absolute}.bootstrap-timepicker-widget.timepicker-orient-left:before{left:6px}.bootstrap-timepicker-widget.timepicker-orient-left:after{left:7px}.bootstrap-timepicker-widget.timepicker-orient-right:before{right:6px}.bootstrap-timepicker-widget.timepicker-orient-right:after{right:7px}.bootstrap-timepicker-widget.timepicker-orient-top:before{top:-7px}.bootstrap-timepicker-widget.timepicker-orient-top:after{top:-6px}.bootstrap-timepicker-widget.timepicker-orient-bottom:before{bottom:-7px;border-bottom:0;border-top:7px solid #999}.bootstrap-timepicker-widget.timepicker-orient-bottom:after{bottom:-6px;border-bottom:0;border-top:6px solid #fff}.bootstrap-timepicker-widget a.btn,.bootstrap-timepicker-widget input{border-radius:4px}.bootstrap-timepicker-widget table{width:100%;margin:0}.bootstrap-timepicker-widget table td{text-align:center;height:30px;margin:0;padding:2px}.bootstrap-timepicker-widget table td:not(.separator){min-width:30px}.bootstrap-timepicker-widget table td span{width:100%}.bootstrap-timepicker-widget table td a{border:1px solid transparent;width:100%;display:inline-block;margin:0;padding:8px 0;outline:0;color:#333}.bootstrap-timepicker-widget table td a:hover{text-decoration:none;background-color:#eee;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;border-color:#ddd}.bootstrap-timepicker-widget table td a i{margin-top:2px;font-size:18px}.bootstrap-timepicker-widget table td input{width:25px;margin:0;text-align:center}.bootstrap-timepicker-widget .modal-content{padding:4px}@media (min-width:767px){.bootstrap-timepicker-widget.modal{width:200px;margin-left:-100px}}@media (max-width:767px){.bootstrap-timepicker,.bootstrap-timepicker .dropdown-menu{width:100%}} -------------------------------------------------------------------------------- /front-end/src/assets/cropper/src/js/utilities.js: -------------------------------------------------------------------------------- 1 | function isNumber(n) { 2 | return typeof n === 'number'; 3 | } 4 | 5 | function isUndefined(n) { 6 | return typeof n === 'undefined'; 7 | } 8 | 9 | function toArray(obj, offset) { 10 | var args = []; 11 | 12 | if (isNumber(offset)) { // It's necessary for IE8 13 | args.push(offset); 14 | } 15 | 16 | return args.slice.apply(obj, args); 17 | } 18 | 19 | // Custom proxy to avoid jQuery's guid 20 | function proxy(fn, context) { 21 | var args = toArray(arguments, 2); 22 | 23 | return function () { 24 | return fn.apply(context, args.concat(toArray(arguments))); 25 | }; 26 | } 27 | 28 | function isCrossOriginURL(url) { 29 | var parts = url.match(/^(https?:)\/\/([^\:\/\?#]+):?(\d*)/i); 30 | 31 | return parts && (parts[1] !== location.protocol || parts[2] !== location.hostname || parts[3] !== location.port); 32 | } 33 | 34 | function addTimestamp(url) { 35 | var timestamp = 'timestamp=' + (new Date()).getTime(); 36 | 37 | return (url + (url.indexOf('?') === -1 ? '?' : '&') + timestamp); 38 | } 39 | 40 | function inRange(source, target) { 41 | return target.left < 0 && source.width < (target.left + target.width) && target.top < 0 && source.height < (target.top + target.height); 42 | } 43 | 44 | function getRotateValue(degree) { 45 | return degree ? 'rotate(' + degree + 'deg)' : 'none'; 46 | } 47 | 48 | function getRotatedSizes(data, reverse) { 49 | var deg = abs(data.degree) % 180, 50 | arc = (deg > 90 ? (180 - deg) : deg) * Math.PI / 180, 51 | sinArc = sin(arc), 52 | cosArc = cos(arc), 53 | width = data.width, 54 | height = data.height, 55 | aspectRatio = data.aspectRatio, 56 | newWidth, 57 | newHeight; 58 | 59 | if (!reverse) { 60 | newWidth = width * cosArc + height * sinArc; 61 | newHeight = width * sinArc + height * cosArc; 62 | } else { 63 | newWidth = width / (cosArc + sinArc / aspectRatio); 64 | newHeight = newWidth / aspectRatio; 65 | } 66 | 67 | return { 68 | width: newWidth, 69 | height: newHeight 70 | }; 71 | } 72 | 73 | function getSourceCanvas(image, data) { 74 | var canvas = $('')[0], 75 | context = canvas.getContext('2d'), 76 | width = data.naturalWidth, 77 | height = data.naturalHeight, 78 | rotate = data.rotate, 79 | rotated = getRotatedSizes({ 80 | width: width, 81 | height: height, 82 | degree: rotate 83 | }); 84 | 85 | if (rotate) { 86 | canvas.width = rotated.width; 87 | canvas.height = rotated.height; 88 | context.save(); 89 | context.translate(rotated.width / 2, rotated.height / 2); 90 | context.rotate(rotate * Math.PI / 180); 91 | context.drawImage(image, -width / 2, -height / 2, width, height); 92 | context.restore(); 93 | } else { 94 | canvas.width = width; 95 | canvas.height = height; 96 | context.drawImage(image, 0, 0, width, height); 97 | } 98 | 99 | return canvas; 100 | } 101 | -------------------------------------------------------------------------------- /front-end/src/assets/ace-master/js/autosize.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | Autosize 3.0.15 3 | license: MIT 4 | http://www.jacklmoore.com/autosize 5 | */ 6 | !function(a,b){if("function"==typeof define&&define.amd)define(["exports","module"],b);else if("undefined"!=typeof exports&&"undefined"!=typeof module)b(exports,module);else{var c={exports:{}};b(c.exports,c),a.autosize=c.exports}}(this,function(a,b){"use strict";function c(a){function b(){var b=window.getComputedStyle(a,null);n=b.overflowY,"vertical"===b.resize?a.style.resize="none":"both"===b.resize&&(a.style.resize="horizontal"),m="content-box"===b.boxSizing?-(parseFloat(b.paddingTop)+parseFloat(b.paddingBottom)):parseFloat(b.borderTopWidth)+parseFloat(b.borderBottomWidth),isNaN(m)&&(m=0),e()}function c(b){var c=a.style.width;a.style.width="0px",a.offsetWidth,a.style.width=c,n=b,l&&(a.style.overflowY=b),d()}function d(){var b=window.pageYOffset,c=document.body.scrollTop,d=a.style.height;a.style.height="auto";var e=a.scrollHeight+m;return 0===a.scrollHeight?void(a.style.height=d):(a.style.height=e+"px",o=a.clientWidth,document.documentElement.scrollTop=b,void(document.body.scrollTop=c))}function e(){var b=a.style.height;d();var e=window.getComputedStyle(a,null);if(e.height!==a.style.height?"visible"!==n&&c("visible"):"hidden"!==n&&c("hidden"),b!==a.style.height){var f=g("autosize:resized");a.dispatchEvent(f)}}var h=void 0===arguments[1]?{}:arguments[1],i=h.setOverflowX,j=void 0===i?!0:i,k=h.setOverflowY,l=void 0===k?!0:k;if(a&&a.nodeName&&"TEXTAREA"===a.nodeName&&!f.has(a)){var m=null,n=null,o=a.clientWidth,p=function(){a.clientWidth!==o&&e()},q=function(b){window.removeEventListener("resize",p,!1),a.removeEventListener("input",e,!1),a.removeEventListener("keyup",e,!1),a.removeEventListener("autosize:destroy",q,!1),a.removeEventListener("autosize:update",e,!1),f["delete"](a),Object.keys(b).forEach(function(c){a.style[c]=b[c]})}.bind(a,{height:a.style.height,resize:a.style.resize,overflowY:a.style.overflowY,overflowX:a.style.overflowX,wordWrap:a.style.wordWrap});a.addEventListener("autosize:destroy",q,!1),"onpropertychange"in a&&"oninput"in a&&a.addEventListener("keyup",e,!1),window.addEventListener("resize",p,!1),a.addEventListener("input",e,!1),a.addEventListener("autosize:update",e,!1),f.add(a),j&&(a.style.overflowX="hidden",a.style.wordWrap="break-word"),b()}}function d(a){if(a&&a.nodeName&&"TEXTAREA"===a.nodeName){var b=g("autosize:destroy");a.dispatchEvent(b)}}function e(a){if(a&&a.nodeName&&"TEXTAREA"===a.nodeName){var b=g("autosize:update");a.dispatchEvent(b)}}var f="function"==typeof Set?new Set:function(){var a=[];return{has:function(b){return Boolean(a.indexOf(b)>-1)},add:function(b){a.push(b)},"delete":function(b){a.splice(a.indexOf(b),1)}}}(),g=function(a){return new Event(a)};try{new Event("test")}catch(h){g=function(a){var b=document.createEvent("Event");return b.initEvent(a,!0,!1),b}}var i=null;"undefined"==typeof window||"function"!=typeof window.getComputedStyle?(i=function(a){return a},i.destroy=function(a){return a},i.update=function(a){return a}):(i=function(a,b){return a&&Array.prototype.forEach.call(a.length?a:[a],function(a){return c(a,b)}),a},i.destroy=function(a){return a&&Array.prototype.forEach.call(a.length?a:[a],d),a},i.update=function(a){return a&&Array.prototype.forEach.call(a.length?a:[a],e),a}),b.exports=i}); -------------------------------------------------------------------------------- /front-end/src/components/widget/btn-multiple.vue: -------------------------------------------------------------------------------- 1 | 6 | 17 | 18 | 91 | 92 | -------------------------------------------------------------------------------- /front-end/src/components/main/person-data.vue: -------------------------------------------------------------------------------- 1 | 6 | 18 | 19 | 97 | 98 | -------------------------------------------------------------------------------- /back-end/routes/index.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuzitao 3 | * @Date: 2017-08-07 16:11:35 4 | * @Last Modified time: 2017-09-05 16:32:31 5 | */ 6 | 7 | 'use strict' 8 | const express = require('express') 9 | const router = express.Router() 10 | const api = require('../config/api.json') 11 | 12 | const User = require('../service/user') 13 | const Permisson = require('../service/permisson.js') 14 | const Article = require('../service/article.js') 15 | const Department = require('../service/department.js') 16 | 17 | router.use( (req, res, next) => { 18 | // res.setHeader("Access-Control-Allow-Origin", require('../config/client')); 19 | // res.setHeader("Access-Control-Allow-Methods", "GET,POST,OPTIONS"); 20 | // res.setHeader("Access-Control-Allow-Headers", "Authorization,Origin,X-Requested-With,Content-Type,Accept"); 21 | // res.setHeader("Access-Control-Allow-Credentials", "true"); 22 | 23 | next() 24 | }) 25 | 26 | router.post(api.login, (req, res) => { 27 | // 要登录过才可以直接进入主页面,否则需要登录 28 | new User(req, res).isPwdCorrect(req.body) 29 | }) 30 | 31 | router.post(api.logout, (req, res) => { 32 | delete req.session[req.body.uname] 33 | res.end('ok') 34 | }) 35 | 36 | router.post(api.session, (req, res) => { 37 | new User(req, res).isLogin(req.body.id) 38 | }) 39 | 40 | router.get(api.permission, (req, res) => { 41 | new Permisson(req, res).get(req.query) 42 | }) 43 | 44 | router.get(api.role, (req, res) => { 45 | res.send({ role: req.session.role || '' }) 46 | }) 47 | 48 | router.post(api.pwd, (req, res) => { 49 | new User(req, res).modifyPwd(req.body) 50 | }) 51 | 52 | router.get(api.person, (req, res) => { 53 | new User(req, res).getPersonalData(req.query) 54 | }) 55 | 56 | router.get(api.checkId, (req, res) => { 57 | new User(req, res).checkId(req.query) 58 | }) 59 | 60 | router.post(api.addUser, (req, res) => { 61 | new User(req, res).addUser(req.body) 62 | }) 63 | 64 | router.get(api.getUser, (req, res) => { 65 | new User(req, res).getUserInfo(req.query) 66 | }) 67 | 68 | router.post(api.modUser, (req, res) => { 69 | new User(req, res).modifyUser(req.body) 70 | }) 71 | 72 | router.post(api.disable, (req, res) => { 73 | new User(req, res).disableUser(req.body) 74 | }) 75 | 76 | router.post(api.addArticle, (req, res) => { 77 | new Article(req, res).addArticle(req.body) 78 | }) 79 | 80 | router.post(api.uploadImg, (req, res) => { 81 | new User(req, res).setHeadImage(req.body) 82 | }) 83 | 84 | router.get(api.getArticle, (req, res) => { 85 | new Article(req, res).getArticles(req.query) 86 | }) 87 | 88 | router.get(api.getPersonalArticle, (req, res) => { 89 | new Article(req, res).getPersonalArticle(req.query) 90 | }) 91 | 92 | router.post(api.addVisit, (req, res) => { 93 | new Article(req, res).addVisit(req.body) 94 | }) 95 | 96 | router.get(api.myArticle, (req, res) => { 97 | new Article(req, res).getMyArticles(req.query) 98 | }) 99 | 100 | router.post(api.delArticle, (req, res) => { 101 | new Article(req, res).deleteArticle(req.body) 102 | }) 103 | 104 | router.get(api.dept, (req, res) => { 105 | new Department(req, res).get(req.query) 106 | }) 107 | 108 | router.post(api.batch, (req, res) => { 109 | new Department(req, res).add(req.body) 110 | }) 111 | 112 | router.post(api.top, (req, res) => { 113 | new Article(req, res).topArticle(req.body) 114 | }) 115 | 116 | module.exports = router -------------------------------------------------------------------------------- /front-end/src/components/main.vue: -------------------------------------------------------------------------------- 1 | 6 | 30 | 105 | -------------------------------------------------------------------------------- /front-end/src/assets/ace-master/js/bootstrap-wysiwyg.min.js: -------------------------------------------------------------------------------- 1 | /* http://github.com/mindmup/bootstrap-wysiwyg */ 2 | !function(a){"use strict";var b=function(b){var c=a.Deferred(),d=new FileReader;return d.onload=function(a){c.resolve(a.target.result)},d.onerror=c.reject,d.onprogress=c.notify,d.readAsDataURL(b),c.promise()};a.fn.cleanHtml=function(){var b=a(this).html();return b&&b.replace(/(
|\s|

<\/div>| )*$/,"")},a.fn.wysiwyg=function(c){var d,e,f,g=this,h=function(){e.activeToolbarClass&&a(e.toolbarSelector).find(f).each(function(){try{var b=a(this).data(e.commandRole);document.queryCommandState(b)?a(this).addClass(e.activeToolbarClass):a(this).removeClass(e.activeToolbarClass)}catch(c){}})},i=function(a,b){var c=a.split(" "),d=c.shift(),e=c.join(" ")+(b||"");document.execCommand(d,0,e),h()},j=function(b){a.each(b,function(a,b){g.keydown(a,function(a){g.attr("contenteditable")&&g.is(":visible")&&(a.preventDefault(),a.stopPropagation(),i(b))}).keyup(a,function(a){g.attr("contenteditable")&&g.is(":visible")&&(a.preventDefault(),a.stopPropagation())})})},k=function(){try{var a=window.getSelection();if(a.getRangeAt&&a.rangeCount)return a.getRangeAt(0)}catch(b){}},l=function(){d=k()},m=function(){try{var a=window.getSelection();if(d){try{a.removeAllRanges()}catch(b){document.body.createTextRange().select(),document.selection.empty()}a.addRange(d)}}catch(c){}},n=function(c){g.focus(),a.each(c,function(c,d){/^image\//.test(d.type)?a.when(b(d)).done(function(a){i("insertimage",a)}).fail(function(a){e.fileUploadError("file-reader",a)}):e.fileUploadError("unsupported-file-type",d.type)})},o=function(a,b){m(),document.queryCommandSupported("hiliteColor")&&document.execCommand("hiliteColor",0,b||"transparent"),l(),a.data(e.selectionMarker,b)},p=function(b,c){b.find(f).click(function(){m(),g.focus(),i(a(this).data(c.commandRole)),l()}),b.find("[data-toggle=dropdown]").click(m);var d=!!window.navigator.msPointerEnabled||!!document.all&&!!document.addEventListener;b.find("input[type=text][data-"+c.commandRole+"]").on("webkitspeechchange change",function(){var b=this.value;this.value="",m(),b&&(g.focus(),i(a(this).data(c.commandRole),b)),l()}).on("focus",function(){if(!d){var b=a(this);b.data(c.selectionMarker)||(o(b,c.selectionColor),b.focus())}}).on("blur",function(){if(!d){var b=a(this);b.data(c.selectionMarker)&&o(b,!1)}}),b.find("input[type=file][data-"+c.commandRole+"]").change(function(){m(),"file"===this.type&&this.files&&this.files.length>0&&n(this.files),l(),this.value=""})},q=function(){g.on("dragenter dragover",!1).on("drop",function(a){var b=a.originalEvent.dataTransfer;a.stopPropagation(),a.preventDefault(),b&&b.files&&b.files.length>0&&n(b.files)})};return e=a.extend({},a.fn.wysiwyg.defaults,c),f="a[data-"+e.commandRole+"],button[data-"+e.commandRole+"],input[type=button][data-"+e.commandRole+"]",j(e.hotKeys),e.dragAndDropImages&&q(),p(a(e.toolbarSelector),e),g.attr("contenteditable",!0).on("mouseup keyup mouseout",function(){l(),h()}),a(window).bind("touchend",function(a){var b=g.is(a.target)||g.has(a.target).length>0,c=k(),d=c&&c.startContainer===c.endContainer&&c.startOffset===c.endOffset;d&&!b||(l(),h())}),this},a.fn.wysiwyg.defaults={hotKeys:{"ctrl+b meta+b":"bold","ctrl+i meta+i":"italic","ctrl+u meta+u":"underline","ctrl+z meta+z":"undo","ctrl+y meta+y meta+shift+z":"redo","ctrl+l meta+l":"justifyleft","ctrl+r meta+r":"justifyright","ctrl+e meta+e":"justifycenter","ctrl+j meta+j":"justifyfull","shift+tab":"outdent",tab:"indent"},toolbarSelector:"[data-role=editor-toolbar]",commandRole:"edit",activeToolbarClass:"btn-info",selectionMarker:"edit-focus-marker",selectionColor:"darkgrey",dragAndDropImages:!0,fileUploadError:function(a,b){console.log("File upload error",a,b)}}}(window.jQuery); -------------------------------------------------------------------------------- /front-end/src/assets/ace-master/css/bootstrap-colorpicker.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap Colorpicker 3 | * http://mjolnic.github.io/bootstrap-colorpicker/ 4 | * 5 | * Originally written by (c) 2012 Stefan Petre 6 | * Licensed under the Apache License v2.0 7 | * http://www.apache.org/licenses/LICENSE-2.0.txt 8 | * 9 | */.colorpicker-saturation{float:left;width:100px;height:100px;cursor:crosshair;background-image:url(../images/bootstrap-colorpicker/saturation.png)}.colorpicker-saturation i{position:absolute;top:0;left:0;display:block;width:5px;height:5px;margin:-4px 0 0 -4px;border:1px solid #000;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}.colorpicker-saturation i b{display:block;width:5px;height:5px;border:1px solid #fff;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}.colorpicker-alpha,.colorpicker-hue{float:left;width:15px;height:100px;margin-bottom:4px;margin-left:4px;cursor:row-resize}.colorpicker-alpha i,.colorpicker-hue i{position:absolute;top:0;left:0;display:block;width:100%;height:1px;margin-top:-1px;background:#000;border-top:1px solid #fff}.colorpicker-hue{background-image:url(../images/bootstrap-colorpicker/hue.png)}.colorpicker-alpha,.colorpicker-color{background-image:url(../images/bootstrap-colorpicker/alpha.png)}.colorpicker-alpha{display:none}.colorpicker:after,.colorpicker:before{position:absolute;display:inline-block;content:''}.colorpicker-alpha,.colorpicker-hue,.colorpicker-saturation{background-size:contain}.colorpicker{top:0;left:0;z-index:2500;min-width:130px;padding:4px;margin-top:1px;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;*zoom:1}.colorpicker:after,.colorpicker:before{line-height:0}.colorpicker:before{top:-7px;left:6px;border-right:7px solid transparent;border-bottom:7px solid #ccc;border-left:7px solid transparent;border-bottom-color:rgba(0,0,0,.2)}.colorpicker:after{clear:both;top:-6px;left:7px;border-right:6px solid transparent;border-bottom:6px solid #fff;border-left:6px solid transparent}.colorpicker div{position:relative}.colorpicker.colorpicker-with-alpha{min-width:140px}.colorpicker.colorpicker-with-alpha .colorpicker-alpha{display:block}.colorpicker-color{height:10px;margin-top:5px;clear:both;background-position:0 100%}.colorpicker-color div{height:10px}.colorpicker-selectors{display:none;height:10px;margin-top:5px;clear:both}.colorpicker-selectors i{float:left;width:10px;height:10px;cursor:pointer}.colorpicker-selectors i+i{margin-left:3px}.colorpicker-element .add-on i,.colorpicker-element .input-group-addon i{display:inline-block;width:16px;height:16px;vertical-align:text-top;cursor:pointer}.colorpicker.colorpicker-inline{position:relative;z-index:auto;display:inline-block;float:none}.colorpicker.colorpicker-horizontal{width:110px;height:auto;min-width:110px}.colorpicker.colorpicker-horizontal .colorpicker-saturation{margin-bottom:4px}.colorpicker.colorpicker-horizontal .colorpicker-color{width:100px}.colorpicker.colorpicker-horizontal .colorpicker-alpha,.colorpicker.colorpicker-horizontal .colorpicker-hue{float:left;width:100px;height:15px;margin-bottom:4px;margin-left:0;cursor:col-resize}.colorpicker.colorpicker-horizontal .colorpicker-alpha i,.colorpicker.colorpicker-horizontal .colorpicker-hue i{position:absolute;top:0;left:0;display:block;width:1px;height:15px;margin-top:0;background:#fff;border:none}.colorpicker.colorpicker-horizontal .colorpicker-hue{background-image:url(../images/bootstrap-colorpicker/hue-horizontal.png)}.colorpicker.colorpicker-horizontal .colorpicker-alpha{background-image:url(../images/bootstrap-colorpicker/alpha-horizontal.png)}.colorpicker.colorpicker-hidden{display:none}.colorpicker.colorpicker-visible{display:block}.colorpicker-inline.colorpicker-visible{display:inline-block}.colorpicker-right:before{right:6px;left:auto}.colorpicker-right:after{right:7px;left:auto} -------------------------------------------------------------------------------- /front-end/src/assets/ace-master/js/jquery.dataTables.bootstrap.min.js: -------------------------------------------------------------------------------- 1 | /* Set the defaults for DataTables initialisation */ 2 | $.extend(!0,$.fn.dataTable.defaults,{sDom:"<'row'<'col-xs-6'l><'col-xs-6'f>r>t<'row'<'col-xs-6'i><'col-xs-6'p>>",oLanguage:{sLengthMenu:"Display _MENU_ records"}}),$.extend($.fn.dataTableExt.oStdClasses,{sWrapper:"dataTables_wrapper form-inline",sFilterInput:"form-control input-sm",sLengthSelect:"form-control input-sm"}),$.fn.dataTable.Api?($.fn.dataTable.defaults.renderer="bootstrap",$.fn.dataTable.ext.renderer.pageButton.bootstrap=function(a,b,c,d,e,f){var g,h,i=new $.fn.dataTable.Api(a),j=a.oClasses,k=a.oLanguage.oPaginate,l=function(b,d){var m,n,o,p,q=function(a){return a.preventDefault(),$(a.target).parent().hasClass("disabled")?!1:void("ellipsis"!==a.data.action&&i.page(a.data.action).draw(!1))};for(m=0,n=d.length;n>m;m++)if(p=d[m],$.isArray(p))l(b,p);else{switch(g="",h="",p){case"ellipsis":g="…",h="disabled";break;case"first":g=k.sFirst,h=p+(e>0?"":" disabled");break;case"previous":g=k.sPrevious,h=p+(e>0?"":" disabled");break;case"next":g=k.sNext,h=p+(f-1>e?"":" disabled");break;case"last":g=k.sLast,h=p+(f-1>e?"":" disabled");break;default:g=p+1,h=e===p?"active":""}g&&(o=$("
  • ",{"class":j.sPageButton+" "+h,"aria-controls":a.sTableId,tabindex:a.iTabIndex,id:0===c&&"string"==typeof p?a.sTableId+"_"+p:null}).append($("",{href:"#"}).html(g)).appendTo(b),a.oApi._fnBindAction(o,{action:p},q))}};l($(b).empty().html('
      ').children("ul"),d)}):($.fn.dataTable.defaults.sPaginationType="bootstrap",$.fn.dataTableExt.oApi.fnPagingInfo=function(a){return{iStart:a._iDisplayStart,iEnd:a.fnDisplayEnd(),iLength:a._iDisplayLength,iTotal:a.fnRecordsTotal(),iFilteredTotal:a.fnRecordsDisplay(),iPage:-1===a._iDisplayLength?0:Math.ceil(a._iDisplayStart/a._iDisplayLength),iTotalPages:-1===a._iDisplayLength?0:Math.ceil(a.fnRecordsDisplay()/a._iDisplayLength)}},$.extend($.fn.dataTableExt.oPagination,{bootstrap:{fnInit:function(a,b,c){var d=(a.oLanguage.oPaginate,function(b){alert(1),b.preventDefault(),a.oApi._fnPageChange(a,b.data.action)&&c(a)});$(b).append('
      ');var e=$("a",b);$(e[0]).bind("click.DT",{action:"first"},d),$(e[1]).bind("click.DT",{action:"previous"},d),$(e[2]).bind("click.DT",{action:"next"},d),$(e[3]).bind("click.DT",{action:"last"},d)},fnUpdate:function(a,b){var c,d,e,f,g,h,i=5,j=a.oInstance.fnPagingInfo(),k=a.aanFeatures.p,l=Math.floor(i/2);for(j.iTotalPages=j.iTotalPages-l?(g=j.iTotalPages-i+1,h=j.iTotalPages):(g=j.iPage-l+1,h=g+i-1),c=0,d=k.length;d>c;c++){for($("li:gt(0)",k[c]).filter(":not(.next,.prev)").remove(),e=g;h>=e;e++)f=e==j.iPage+1?'class="active"':"",$("
    • '+e+"
    • ").insertBefore($("li.next:eq(0)",k[c])[0]).bind("click",function(c){c.preventDefault(),a._iDisplayStart=(parseInt($("a",this).text(),10)-1)*j.iLength,b(a)});0===j.iPage?$("li.prev",k[c]).addClass("disabled"):$("li.prev",k[c]).removeClass("disabled"),j.iPage===j.iTotalPages-1||0===j.iTotalPages?$("li.next",k[c]).addClass("disabled"):$("li.next",k[c]).removeClass("disabled")}}}})),$.fn.DataTable.TableTools&&($.extend(!0,$.fn.DataTable.TableTools.classes,{container:"DTTT btn-group",buttons:{normal:"btn btn-default",disabled:"disabled"},collection:{container:"DTTT_dropdown dropdown-menu",buttons:{normal:"",disabled:"disabled"}},print:{info:"DTTT_print_info modal"},select:{row:"active"}}),$.extend(!0,$.fn.DataTable.TableTools.DEFAULTS.oTags,{collection:{container:"ul",button:"li",liner:"a"}})); -------------------------------------------------------------------------------- /front-end/src/components/breadcrumbs.vue: -------------------------------------------------------------------------------- 1 | 6 | 45 | 46 | 102 | 103 | -------------------------------------------------------------------------------- /front-end/src/components/theme-setter.vue: -------------------------------------------------------------------------------- 1 | 69 | 70 | 80 | 81 | -------------------------------------------------------------------------------- /front-end/src/assets/ace-master/js/grid.locale-en.js: -------------------------------------------------------------------------------- 1 | !function(a){"use strict";"function"==typeof define&&define.amd?define(["jquery","../grid.base"],a):a(jQuery)}(function(a){a.jgrid=a.jgrid||{},a.jgrid.hasOwnProperty("regional")||(a.jgrid.regional=[]),a.jgrid.regional.en={defaults:{recordtext:"View {0} - {1} of {2}",emptyrecords:"No records to view",loadtext:"Loading...",savetext:"Saving...",pgtext:"Page {0} of {1}",pgfirst:"First Page",pglast:"Last Page",pgnext:"Next Page",pgprev:"Previous Page",pgrecs:"Records per Page",showhide:"Toggle Expand Collapse Grid",pagerCaption:"Grid::Page Settings",pageText:"Page:",recordPage:"Records per Page",nomorerecs:"No more records...",scrollPullup:"Pull up to load more...",scrollPulldown:"Pull down to refresh...",scrollRefresh:"Release to refresh..."},search:{caption:"Search...",Find:"Find",Reset:"Reset",odata:[{oper:"eq",text:"equal"},{oper:"ne",text:"not equal"},{oper:"lt",text:"less"},{oper:"le",text:"less or equal"},{oper:"gt",text:"greater"},{oper:"ge",text:"greater or equal"},{oper:"bw",text:"begins with"},{oper:"bn",text:"does not begin with"},{oper:"in",text:"is in"},{oper:"ni",text:"is not in"},{oper:"ew",text:"ends with"},{oper:"en",text:"does not end with"},{oper:"cn",text:"contains"},{oper:"nc",text:"does not contain"},{oper:"nu",text:"is null"},{oper:"nn",text:"is not null"}],groupOps:[{op:"AND",text:"all"},{op:"OR",text:"any"}],operandTitle:"Click to select search operation.",resetTitle:"Reset Search Value"},edit:{addCaption:"Add Record",editCaption:"Edit Record",bSubmit:"Submit",bCancel:"Cancel",bClose:"Close",saveData:"Data has been changed! Save changes?",bYes:"Yes",bNo:"No",bExit:"Cancel",msg:{required:"Field is required",number:"Please, enter valid number",minValue:"value must be greater than or equal to ",maxValue:"value must be less than or equal to",email:"is not a valid e-mail",integer:"Please, enter valid integer value",date:"Please, enter valid date value",url:"is not a valid URL. Prefix required ('http://' or 'https://')",nodefined:" is not defined!",novalue:" return value is required!",customarray:"Custom function should return array!",customfcheck:"Custom function should be present in case of custom checking!"}},view:{caption:"View Record",bClose:"Close"},del:{caption:"Delete",msg:"Delete selected record(s)?",bSubmit:"Delete",bCancel:"Cancel"},nav:{edittext:"",edittitle:"Edit selected row",addtext:"",addtitle:"Add new row",deltext:"",deltitle:"Delete selected row",searchtext:"",searchtitle:"Find records",refreshtext:"",refreshtitle:"Reload Grid",alertcap:"Warning",alerttext:"Please, select row",viewtext:"",viewtitle:"View selected row",savetext:"",savetitle:"Save row",canceltext:"",canceltitle:"Cancel row editing",selectcaption:"Actions..."},col:{caption:"Select columns",bSubmit:"Ok",bCancel:"Cancel"},errors:{errcap:"Error",nourl:"No url is set",norecords:"No records to process",model:"Length of colNames <> colModel!"},formatter:{integer:{thousandsSeparator:",",defaultValue:"0"},number:{decimalSeparator:".",thousandsSeparator:",",decimalPlaces:2,defaultValue:"0.00"},currency:{decimalSeparator:".",thousandsSeparator:",",decimalPlaces:2,prefix:"",suffix:"",defaultValue:"0.00"},date:{dayNames:["Sun","Mon","Tue","Wed","Thr","Fri","Sat","Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],monthNames:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec","January","February","March","April","May","June","July","August","September","October","November","December"],AmPm:["am","pm","AM","PM"],S:function(a){return 11>a||a>13?["st","nd","rd","th"][Math.min((a-1)%10,3)]:"th"},srcformat:"Y-m-d",newformat:"n/j/Y",parseRe:/[#%\\\/:_;.,\t\s-]/,masks:{ISO8601Long:"Y-m-d H:i:s",ISO8601Short:"Y-m-d",ShortDate:"n/j/Y",LongDate:"l, F d, Y",FullDateTime:"l, F d, Y g:i:s A",MonthDay:"F d",ShortTime:"g:i A",LongTime:"g:i:s A",SortableDateTime:"Y-m-d\\TH:i:s",UniversalSortableDateTime:"Y-m-d H:i:sO",YearMonth:"F, Y"},reformatAfterEdit:!1,userLocalTime:!1},baseLinkUrl:"",showAction:"",target:"",checkbox:{disabled:!0},idName:"id"}}}); -------------------------------------------------------------------------------- /front-end/src/components/main/information-management.vue: -------------------------------------------------------------------------------- 1 | 6 | 30 | 31 | 111 | 112 | -------------------------------------------------------------------------------- /front-end/src/assets/ace-master/js/jquery.easypiechart.min.js: -------------------------------------------------------------------------------- 1 | /**! 2 | * easy-pie-chart 3 | * Lightweight plugin to render simple, animated and retina optimized pie charts 4 | * 5 | * @license 6 | * @author Robert Fleischmann (http://robert-fleischmann.de) 7 | * @version 2.1.7 8 | **/ 9 | !function(a,b){"function"==typeof define&&define.amd?define(["jquery"],function(a){return b(a)}):"object"==typeof exports?module.exports=b(require("jquery")):b(jQuery)}(this,function(a){var b=function(a,b){var c,d=document.createElement("canvas");a.appendChild(d),"object"==typeof G_vmlCanvasManager&&G_vmlCanvasManager.initElement(d);var e=d.getContext("2d");d.width=d.height=b.size;var f=1;window.devicePixelRatio>1&&(f=window.devicePixelRatio,d.style.width=d.style.height=[b.size,"px"].join(""),d.width=d.height=b.size*f,e.scale(f,f)),e.translate(b.size/2,b.size/2),e.rotate((-0.5+b.rotate/180)*Math.PI);var g=(b.size-b.lineWidth)/2;b.scaleColor&&b.scaleLength&&(g-=b.scaleLength+2),Date.now=Date.now||function(){return+new Date};var h=function(a,b,c){c=Math.min(Math.max(-1,c||0),1);var d=0>=c;e.beginPath(),e.arc(0,0,g,0,2*Math.PI*c,d),e.strokeStyle=a,e.lineWidth=b,e.stroke()},i=function(){var a,c;e.lineWidth=1,e.fillStyle=b.scaleColor,e.save();for(var d=24;d>0;--d)d%6===0?(c=b.scaleLength,a=0):(c=.6*b.scaleLength,a=b.scaleLength-c),e.fillRect(-b.size/2+a,0,c,1),e.rotate(Math.PI/12);e.restore()},j=function(){return window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||function(a){window.setTimeout(a,1e3/60)}}(),k=function(){b.scaleColor&&i(),b.trackColor&&h(b.trackColor,b.trackWidth||b.lineWidth,1)};this.getCanvas=function(){return d},this.getCtx=function(){return e},this.clear=function(){e.clearRect(b.size/-2,b.size/-2,b.size,b.size)},this.draw=function(a){b.scaleColor||b.trackColor?e.getImageData&&e.putImageData?c?e.putImageData(c,0,0):(k(),c=e.getImageData(0,0,b.size*f,b.size*f)):(this.clear(),k()):this.clear(),e.lineCap=b.lineCap;var d;d="function"==typeof b.barColor?b.barColor(a):b.barColor,h(d,b.lineWidth,a/100)}.bind(this),this.animate=function(a,c){var d=Date.now();b.onStart(a,c);var e=function(){var f=Math.min(Date.now()-d,b.animate.duration),g=b.easing(this,f,a,c-a,b.animate.duration);this.draw(g),b.onStep(a,c,g),f>=b.animate.duration?b.onStop(a,c):j(e)}.bind(this);j(e)}.bind(this)},c=function(a,c){var d={barColor:"#ef1e25",trackColor:"#f9f9f9",scaleColor:"#dfe0e0",scaleLength:5,lineCap:"round",lineWidth:3,trackWidth:void 0,size:110,rotate:0,animate:{duration:1e3,enabled:!0},easing:function(a,b,c,d,e){return b/=e/2,1>b?d/2*b*b+c:-d/2*(--b*(b-2)-1)+c},onStart:function(a,b){},onStep:function(a,b,c){},onStop:function(a,b){}};if("undefined"!=typeof b)d.renderer=b;else{if("undefined"==typeof SVGRenderer)throw new Error("Please load either the SVG- or the CanvasRenderer");d.renderer=SVGRenderer}var e={},f=0,g=function(){this.el=a,this.options=e;for(var b in d)d.hasOwnProperty(b)&&(e[b]=c&&"undefined"!=typeof c[b]?c[b]:d[b],"function"==typeof e[b]&&(e[b]=e[b].bind(this)));"string"==typeof e.easing&&"undefined"!=typeof jQuery&&jQuery.isFunction(jQuery.easing[e.easing])?e.easing=jQuery.easing[e.easing]:e.easing=d.easing,"number"==typeof e.animate&&(e.animate={duration:e.animate,enabled:!0}),"boolean"!=typeof e.animate||e.animate||(e.animate={duration:1e3,enabled:e.animate}),this.renderer=new e.renderer(a,e),this.renderer.draw(f),a.dataset&&a.dataset.percent?this.update(parseFloat(a.dataset.percent)):a.getAttribute&&a.getAttribute("data-percent")&&this.update(parseFloat(a.getAttribute("data-percent"))),a.style.width=a.style.height=e.size+"px",a.style.lineHeight=e.size-1+"px"}.bind(this);this.update=function(a){return a=parseFloat(a),e.animate.enabled?this.renderer.animate(f,a):this.renderer.draw(a),f=a,this}.bind(this),this.disableAnimation=function(){return e.animate.enabled=!1,this},this.enableAnimation=function(){return e.animate.enabled=!0,this},g()};a.fn.easyPieChart=function(b){return this.each(function(){var d;a.data(this,"easyPieChart")||(d=a.extend({},b,a(this).data()),a.data(this,"easyPieChart",new c(this,d)))})}}); -------------------------------------------------------------------------------- /back-end/db/articleDao.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuzitao 3 | * @Date: 2017-08-25 16:23:38 4 | * @Last Modified by: wuzitao 5 | * @Last Modified time: 2017-09-05 15:51:23 6 | */ 7 | const BaseDao = require('./baseDao') 8 | const Promise = require('bluebird') 9 | const u = require('../util/util') 10 | 11 | const fun = { 12 | add: 'add_article', 13 | getall: 'get_all_articles', 14 | getperson: 'get_personal_artical', 15 | visit: 'add_visitor', 16 | my: 'get_my_articles', 17 | del: 'delete_my_article', 18 | top: 'push_article_to_top' 19 | } 20 | 21 | exports = module.exports = function (f, p) { 22 | const query = new BaseDao() 23 | 24 | let $where = [ 25 | { name: 'article_title', value: p.title }, 26 | { name: 'user_id', value: p.uname, relation: 'and' }, 27 | ] 28 | 29 | switch (f) { 30 | case fun.add: 31 | 32 | return query.select({ 33 | $table: 'article', 34 | $where 35 | }) 36 | .then(result => { 37 | // 更新或新增 38 | if (result.length) { 39 | return query.update({ 40 | $table: 'article', 41 | $set: { article_content: p.content, article_summary: p.summary, 42 | sort_name: p.sort_name, 43 | publish_time: new Date().format('yyyy-MM-dd hh-mm-ss') 44 | }, 45 | $where 46 | }) 47 | } 48 | return query.insert({ 49 | $table: 'article', 50 | article_title: p.title, 51 | article_content: p.content, 52 | article_summary: p.summary, 53 | sort_name: p.sort_name, 54 | user_id: p.uname 55 | }) 56 | }) 57 | 58 | case fun.getall: 59 | return query.select({ 60 | $table: [ 61 | { name: 'article' }, 62 | { name: 'baseinfo', on: { 63 | value: 'uid', 64 | prevValue: 'user_id' 65 | }} 66 | ], 67 | $column: ['article_content', 'article_title', 'article_summary', 'publish_time', 'click', 'sort_name', 'up', 'head', 'realname', 'article.user_id id'], 68 | $order_by: [ 69 | { value: 'up', by: 'desc' }, 70 | { value: 'publish_time', by: 'desc' } 71 | ] 72 | }) 73 | 74 | case fun.getperson: 75 | // 联表查询 76 | const $table = [ 77 | { name: 'article' }, 78 | { name: 'baseinfo', on: { 79 | value: 'uid', 80 | prevValue: 'user_id' 81 | }}, 82 | ] 83 | return query.select({ 84 | $table, 85 | $column: ['article_content', 'head', 'click'], 86 | $where: [ 87 | { name: 'user_id', value: p.uname }, 88 | { name: 'article_title', value: p.title, relation: 'and' } 89 | ] 90 | }) 91 | .then(result1 => { 92 | return new Promise(resolve => { 93 | query.select({ 94 | $table, 95 | $column: ['sum(click) sumClick', 'count(*) countArticle'], 96 | $where: { user_id: p.uname } 97 | }) 98 | .then(result2 => { 99 | resolve([result1, result2]) // 需要将两个结果合并 100 | }) 101 | }) 102 | }) 103 | 104 | case fun.visit: 105 | return query.select({ 106 | $table: 'article', 107 | $column: 'click', 108 | $where 109 | }) 110 | .then(result => { 111 | let click = result[0].click 112 | return query.update({ 113 | $table: 'article', 114 | $set: { click: click + 1 }, 115 | $where 116 | }) 117 | }) 118 | 119 | case fun.my: 120 | return query.select({ 121 | $table: 'article', 122 | $column: ['article_content', 'article_title', 'article_summary', 'publish_time', 'click', 'sort_name', 'up'], 123 | $where: { user_id: p.uname }, 124 | $order_by: { value: 'publish_time', by: 'desc' } 125 | }) 126 | 127 | case fun.del: 128 | return query.delete({ 129 | $table: 'article', 130 | $where: [ 131 | { name: 'user_id', value: p.uname }, 132 | { name: 'article_title', value: p.title, relation: 'and' } 133 | ] 134 | }) 135 | 136 | case fun.top: 137 | return query.update({ 138 | $table: 'article', 139 | $set: { up: Number(p.up) }, 140 | $where: [ 141 | { name: 'user_id', value: p.uname }, 142 | { name: 'article_title', value: p.title, relation: 'and' } 143 | ] 144 | }) 145 | 146 | default: return null 147 | } 148 | } 149 | exports.fun = fun 150 | -------------------------------------------------------------------------------- /api.md: -------------------------------------------------------------------------------- 1 | ## 数据请求API 2 | | num | api | method | params | return type | return content | description | 3 | | :-: | :-: | :----: | :----: | :---------: | :------------: | :---------- | 4 | | 1 | /api/login | POST | uname, pwd | Json | result\ | 检查用户名和密码是否正确,是否为禁用 | 5 | | 2 | /api/session | POST | id | Json | isVisit\ | 询用户是否登录过,如登录过且session为过期,可跳过登录页面 | 6 | | 3 | /api/permission | GET | uname | Json | name\, role\ | 根据用户id查询其角色拥有的权限 | 7 | | 4 | /api/role | GET | \ | Json | role\ | 从session中获取用户权限 | 8 | | 5 | /api/pwd | POST | uname, pwd | Json | result\ | 用户修改密码 | 9 | | 6 | /api/person | GET | uname | Json | info\ | 获取用户个人信息 | 10 | | 7 | /api/logout | POST | uname | String | 'ok' | 用户登出 | 11 | | 8 | /api/add-user | POST | info\ | Json | result\ | 注册新用户信息 | 12 | | 9 | /api/check-id | GET | id | Json | isExist\ | 检查身份证号是否存在,存在则不能新增该用户 | 13 | | 10 | /api/get-user-info | GET | [columns] | Array | result | 得到用户信息,参数用于获取特定的信息,不填则获取所有信息 | 14 | | 11 | /api/modify-user | POST | uname, set\ | Json | result\ | 修改一个用户信息 | 15 | | 12 | /api/disable-user | POST | uname | Json | result\ | 禁用一个用户 | 16 | | 13 | /api/add-article | POST | uname, title, content, summary, sort_name | Json | result\ | 新增或修改一篇文章 | 17 | | 14 | /api/upload-img | POST | uname, base64 | Json | result\ | 上传用户头像 | 18 | | 15 | /api/get-article | GET | \ | Array | result | 得到所有的用户文章 | 19 | | 16 | /api/get-personal-article | GET | uname | Array | [result\, [sumClick\, countArticle\]] | 得到指定用户的所有文章信息和总访问量、总发表文章数 | 20 | | 17 | /api/add-visit | POST | uname, title | String | 'ok' | 为指定的文章新增一个访问记录 | 21 | | 18 | /api/my-article | GET | uname | Array | result | 得到该用户的所有文章 | 22 | | 19 | /api/del-my-article | POST | uname, title | Json | result\ | 删除用户指定的文章 | 23 | | 20 | /api/get-department-info | GET | \ | Array | result | 得到所有的部门信息 | 24 | | 21 | /api/add-department-batch | POST | name | Json | result\ | 增加一个指定部门的批数 | 25 | | 22 | /api/push-to-top | POST | name, title, up | Json | result\ | 将一篇指定的文章置顶 | 26 | ## 数据库CRUD API 27 | ### INSERT 28 | usage: new BaseDao().insert(settings) 29 | 30 | | setting | type | extras | sample | 31 | | :-----: | :--: | :----: | :----: | 32 | | $table | String | \ | $table: 'tableName' | 33 | | [anykey] | String/Number/Boolean | \ | uname: 'zhangsan', age: 12 | 34 | ### SELECT 35 | usage: new BaseDao().select(settings) 36 | 37 | | setting | type | extras | sample | 38 | | :-----: | :--: | :----- | :----- | 39 | | $table | String/Array | name\, join\, on\
      on: {
      table\, value\, prevValue\
      } | $table: 'tableName'
      $table: [{
      name: 'tableName1'
      }, {
      name: 'tableName2',
      on: {
      table: 'otherTableName',
      value: 'id',
      prevValue: 'name'
      }
      }] | 40 | | $where | Object/Array | name\, value\, relation\, compare\, forceText\ | $where: {
      name: 'zhangsan'
      }
      $where: [{
      name: 'name', value: 'zhangsan'}, {
      name: 'id', value: '123', relation: 'and'
      }] | 41 | | $order_by | String/Object/Array | value\, by\ | $order_by: 'id'
      $order_by: {
      value: 'id',by: 'asc'
      }
      $order_by: [{
      value: 'id',by: 'desc'
      },{
      value: 'name', by: 'asc'
      }] | 42 | | $group_by | String/Array | \ | $group_by: 'department'
      $group_by: ['department', 'article'] | 43 | | $limit | Number/Array | \ | $limit: 5
      $limit: [2,5] | 44 | ### UPDATE 45 | usage: new BaseDao().update(settings) 46 | 47 | | setting | type | extras | sample | 48 | | :-----: | :--: | :----: | :----: | 49 | | $table | String | \ | $table: 'tableName' | 50 | | $set | Object | [anykey]: [anyvalue] | $set: {name: 'zhangsan'} | 51 | | $where | !! saw $where in SELECT | !! saw $where in SELECT | !! saw $where in SELECT | 52 | ### DELETE 53 | usage: new BaseDao().delete(settings) 54 | 55 | | setting | type | extras | sample | 56 | | :-----: | :--: | :----: | :----: | 57 | | $table | String | \ | $table: 'tableName' | 58 | | $where | !! saw $where in SELECT | !! saw $where in SELECT | !! saw $where in SELECT | 59 | --------------------------------------------------------------------------------