├── vue-element-admin
├── .eslintignore
├── babel.config.js
├── tests
│ └── unit
│ │ ├── .eslintrc.js
│ │ ├── components
│ │ ├── SvgIcon.spec.js
│ │ └── Hamburger.spec.js
│ │ └── utils
│ │ ├── parseTime.spec.js
│ │ ├── formatTime.spec.js
│ │ └── validate.spec.js
├── public
│ ├── favicon.ico
│ ├── static
│ │ └── tinymce4.7.5
│ │ │ ├── skins
│ │ │ └── lightgray
│ │ │ │ ├── img
│ │ │ │ ├── anchor.gif
│ │ │ │ ├── loader.gif
│ │ │ │ ├── object.gif
│ │ │ │ └── trans.gif
│ │ │ │ └── fonts
│ │ │ │ ├── tinymce.eot
│ │ │ │ ├── tinymce.ttf
│ │ │ │ ├── tinymce.woff
│ │ │ │ ├── tinymce-mobile.woff
│ │ │ │ ├── tinymce-small.eot
│ │ │ │ ├── tinymce-small.ttf
│ │ │ │ └── tinymce-small.woff
│ │ │ └── plugins
│ │ │ └── emoticons
│ │ │ └── img
│ │ │ ├── smiley-cry.gif
│ │ │ ├── smiley-cool.gif
│ │ │ ├── smiley-frown.gif
│ │ │ ├── smiley-kiss.gif
│ │ │ ├── smiley-smile.gif
│ │ │ ├── smiley-wink.gif
│ │ │ ├── smiley-yell.gif
│ │ │ ├── smiley-innocent.gif
│ │ │ ├── smiley-laughing.gif
│ │ │ ├── smiley-sealed.gif
│ │ │ ├── smiley-embarassed.gif
│ │ │ ├── smiley-surprised.gif
│ │ │ ├── smiley-tongue-out.gif
│ │ │ ├── smiley-undecided.gif
│ │ │ ├── smiley-foot-in-mouth.gif
│ │ │ └── smiley-money-mouth.gif
│ └── index.html
├── .env.production
├── .travis.yml
├── src
│ ├── assets
│ │ ├── 401_images
│ │ │ └── 401.gif
│ │ ├── 404_images
│ │ │ ├── 404.png
│ │ │ └── 404_cloud.png
│ │ ├── login_wraper.8ab0d297.jpg
│ │ └── custom-theme
│ │ │ └── fonts
│ │ │ ├── element-icons.ttf
│ │ │ └── element-icons.woff
│ ├── views
│ │ ├── nested
│ │ │ ├── menu2
│ │ │ │ └── index.vue
│ │ │ └── menu1
│ │ │ │ ├── menu1-3
│ │ │ │ └── index.vue
│ │ │ │ ├── index.vue
│ │ │ │ ├── menu1-2
│ │ │ │ ├── menu1-2-1
│ │ │ │ │ └── index.vue
│ │ │ │ ├── menu1-2-2
│ │ │ │ │ └── index.vue
│ │ │ │ └── index.vue
│ │ │ │ └── menu1-1
│ │ │ │ └── index.vue
│ │ ├── errorLog
│ │ │ ├── errorTestB.vue
│ │ │ ├── errorTestA.vue
│ │ │ └── index.vue
│ │ ├── example
│ │ │ ├── components
│ │ │ │ ├── Dropdown
│ │ │ │ │ ├── index.js
│ │ │ │ │ ├── SourceUrl.vue
│ │ │ │ │ ├── Comment.vue
│ │ │ │ │ └── Platform.vue
│ │ │ │ └── Warning.vue
│ │ │ ├── edit.vue
│ │ │ └── create.vue
│ │ ├── svg-icons
│ │ │ ├── requireIcons.js
│ │ │ └── element-icon.json
│ │ ├── redirect
│ │ │ └── index.vue
│ │ ├── pdf
│ │ │ └── index.vue
│ │ ├── login
│ │ │ └── authRedirect.vue
│ │ ├── charts
│ │ │ ├── line.vue
│ │ │ ├── mixChart.vue
│ │ │ └── keyboard.vue
│ │ ├── permission
│ │ │ ├── page.vue
│ │ │ └── components
│ │ │ │ └── SwitchRoles.vue
│ │ ├── table
│ │ │ └── dynamicTable
│ │ │ │ ├── index.vue
│ │ │ │ ├── unfixedThead.vue
│ │ │ │ └── fixedThead.vue
│ │ ├── excel
│ │ │ ├── components
│ │ │ │ ├── FilenameOption.vue
│ │ │ │ ├── AutoWidthOption.vue
│ │ │ │ └── BookTypeOption.vue
│ │ │ └── uploadExcel.vue
│ │ ├── dashboard
│ │ │ ├── index.vue
│ │ │ └── admin
│ │ │ │ └── components
│ │ │ │ ├── TransactionTable.vue
│ │ │ │ └── TodoList
│ │ │ │ └── Todo.vue
│ │ ├── guide
│ │ │ ├── index.vue
│ │ │ └── defineSteps.js
│ │ ├── components-demo
│ │ │ ├── dropzone.vue
│ │ │ ├── dndList.vue
│ │ │ ├── dragSelect.vue
│ │ │ ├── tinymce.vue
│ │ │ ├── jsonEditor.vue
│ │ │ ├── dragKanban.vue
│ │ │ ├── avatarUpload.vue
│ │ │ └── splitpane.vue
│ │ ├── qiniu
│ │ │ └── upload.vue
│ │ ├── tab
│ │ │ └── index.vue
│ │ ├── clipboard
│ │ │ └── index.vue
│ │ ├── headImage
│ │ │ └── index.vue
│ │ ├── i18n-demo
│ │ │ └── local.js
│ │ └── documentation
│ │ │ └── index.vue
│ ├── App.vue
│ ├── api
│ │ ├── qiniu.js
│ │ ├── showUser.js
│ │ ├── remoteSearch.js
│ │ ├── user.js
│ │ ├── readPapers.js
│ │ ├── role.js
│ │ ├── article.js
│ │ ├── examination.js
│ │ ├── classes.js
│ │ └── addQuestion.js
│ ├── icons
│ │ ├── svg
│ │ │ ├── chart.svg
│ │ │ ├── size.svg
│ │ │ ├── link.svg
│ │ │ ├── guide.svg
│ │ │ ├── component.svg
│ │ │ ├── money.svg
│ │ │ ├── email.svg
│ │ │ ├── drag.svg
│ │ │ ├── guide 2.svg
│ │ │ ├── documentation.svg
│ │ │ ├── fullscreen.svg
│ │ │ ├── user.svg
│ │ │ ├── lock.svg
│ │ │ ├── excel.svg
│ │ │ ├── example.svg
│ │ │ ├── star.svg
│ │ │ ├── table.svg
│ │ │ ├── search.svg
│ │ │ ├── password.svg
│ │ │ ├── tab.svg
│ │ │ ├── message.svg
│ │ │ ├── theme.svg
│ │ │ ├── peoples.svg
│ │ │ ├── edit.svg
│ │ │ ├── nested.svg
│ │ │ ├── project.svg
│ │ │ ├── tree-table.svg
│ │ │ ├── eye.svg
│ │ │ ├── clipboard.svg
│ │ │ ├── list.svg
│ │ │ ├── icon.svg
│ │ │ ├── sliders.svg
│ │ │ ├── international.svg
│ │ │ ├── wechat.svg
│ │ │ ├── people.svg
│ │ │ ├── language.svg
│ │ │ ├── eye-open.svg
│ │ │ ├── 404.svg
│ │ │ ├── zip.svg
│ │ │ ├── bug.svg
│ │ │ ├── pdf.svg
│ │ │ ├── exit-fullscreen.svg
│ │ │ └── tree.svg
│ │ ├── index.js
│ │ └── svgo.yml
│ ├── components
│ │ ├── ImageCropper
│ │ │ └── utils
│ │ │ │ ├── mimes.js
│ │ │ │ ├── data2blob.js
│ │ │ │ └── effectRipple.js
│ │ ├── Tinymce
│ │ │ ├── toolbar.js
│ │ │ └── plugins.js
│ │ ├── MarkdownEditor
│ │ │ └── defaultOptions.js
│ │ ├── SvgIcon
│ │ │ └── index.vue
│ │ ├── Charts
│ │ │ └── mixins
│ │ │ │ └── resize.js
│ │ ├── LangSelect
│ │ │ └── index.vue
│ │ ├── Screenfull
│ │ │ └── index.vue
│ │ ├── Hamburger
│ │ │ └── index.vue
│ │ ├── SizeSelect
│ │ │ └── index.vue
│ │ ├── DragSelect
│ │ │ └── index.vue
│ │ ├── JsonEditor
│ │ │ └── index.vue
│ │ └── GithubCorner
│ │ │ └── index.vue
│ ├── layout
│ │ ├── components
│ │ │ ├── index.js
│ │ │ ├── Sidebar
│ │ │ │ ├── Item.vue
│ │ │ │ ├── Link.vue
│ │ │ │ ├── FixiOSBug.js
│ │ │ │ └── index.vue
│ │ │ └── AppMain.vue
│ │ └── mixin
│ │ │ └── ResizeHandler.js
│ ├── directive
│ │ ├── waves
│ │ │ ├── index.js
│ │ │ └── waves.css
│ │ ├── el-dragDialog
│ │ │ └── index.js
│ │ ├── clipboard
│ │ │ ├── index.js
│ │ │ └── clipboard.js
│ │ ├── permission
│ │ │ ├── index.js
│ │ │ └── permission.js
│ │ └── el-table
│ │ │ ├── index.js
│ │ │ └── adaptive.js
│ ├── utils
│ │ ├── auth.js
│ │ ├── i18n.js
│ │ ├── permission.js
│ │ ├── clipboard.js
│ │ ├── errorLog.js
│ │ ├── openWindow.js
│ │ └── scrollTo.js
│ ├── store
│ │ ├── modules
│ │ │ ├── errorLog.js
│ │ │ ├── settings.js
│ │ │ ├── readPapers.js
│ │ │ ├── permission.js
│ │ │ ├── classes.js
│ │ │ ├── app.js
│ │ │ └── examination.js
│ │ ├── getters.js
│ │ └── index.js
│ ├── router
│ │ └── modules
│ │ │ ├── headImage.js
│ │ │ ├── charts.js
│ │ │ ├── user.js
│ │ │ ├── classes.js
│ │ │ ├── table.js
│ │ │ ├── readPapers.js
│ │ │ ├── examination.js
│ │ │ ├── exam.js
│ │ │ └── nested.js
│ ├── vendor
│ │ └── Export2Zip.js
│ ├── styles
│ │ ├── variables.scss
│ │ ├── transition.scss
│ │ ├── element-variables.scss
│ │ ├── element-ui.scss
│ │ ├── mixin.scss
│ │ └── btn.scss
│ ├── settings.js
│ ├── lang
│ │ └── index.js
│ ├── filters
│ │ └── index.js
│ └── main.js
├── .env.staging
├── .github
│ └── ISSUE_TEMPLATE
│ │ ├── feature_request.md
│ │ ├── question.md
│ │ └── bug_report.md
├── plop-templates
│ ├── utils.js
│ ├── view
│ │ ├── index.hbs
│ │ └── prompt.js
│ └── component
│ │ ├── index.hbs
│ │ └── prompt.js
├── .postcssrc.js
├── plopfile.js
├── .editorconfig
├── .gitignore
├── .env.development
├── jest.config.js
├── build
│ └── index.js
├── LICENSE
└── mock
│ ├── remoteSearch.js
│ ├── user.js
│ └── mock-server.js
├── README.md
└── .gitignore
/vue-element-admin/.eslintignore:
--------------------------------------------------------------------------------
1 | build/*.js
2 | src/assets
3 | public
4 | dist
5 |
--------------------------------------------------------------------------------
/vue-element-admin/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [
3 | '@vue/app'
4 | ]
5 | }
6 |
--------------------------------------------------------------------------------
/vue-element-admin/tests/unit/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | env: {
3 | jest: true
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/vue-element-admin/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/raneenana/tasksystem/HEAD/vue-element-admin/public/favicon.ico
--------------------------------------------------------------------------------
/vue-element-admin/.env.production:
--------------------------------------------------------------------------------
1 | # just a flag
2 | ENV = 'production'
3 |
4 | # base api
5 | VUE_APP_BASE_API = '/prod-api'
6 |
7 |
--------------------------------------------------------------------------------
/vue-element-admin/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js: stable
3 | script: npm run test
4 | notifications:
5 | email: false
6 |
--------------------------------------------------------------------------------
/vue-element-admin/src/assets/401_images/401.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/raneenana/tasksystem/HEAD/vue-element-admin/src/assets/401_images/401.gif
--------------------------------------------------------------------------------
/vue-element-admin/src/assets/404_images/404.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/raneenana/tasksystem/HEAD/vue-element-admin/src/assets/404_images/404.png
--------------------------------------------------------------------------------
/vue-element-admin/.env.staging:
--------------------------------------------------------------------------------
1 | NODE_ENV = production
2 |
3 | # just a flag
4 | ENV = 'staging'
5 |
6 | # base api
7 | VUE_APP_BASE_API = '/stage-api'
8 |
9 |
--------------------------------------------------------------------------------
/vue-element-admin/src/assets/404_images/404_cloud.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/raneenana/tasksystem/HEAD/vue-element-admin/src/assets/404_images/404_cloud.png
--------------------------------------------------------------------------------
/vue-element-admin/src/assets/login_wraper.8ab0d297.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/raneenana/tasksystem/HEAD/vue-element-admin/src/assets/login_wraper.8ab0d297.jpg
--------------------------------------------------------------------------------
/vue-element-admin/src/views/nested/menu2/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/vue-element-admin/src/assets/custom-theme/fonts/element-icons.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/raneenana/tasksystem/HEAD/vue-element-admin/src/assets/custom-theme/fonts/element-icons.ttf
--------------------------------------------------------------------------------
/vue-element-admin/src/assets/custom-theme/fonts/element-icons.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/raneenana/tasksystem/HEAD/vue-element-admin/src/assets/custom-theme/fonts/element-icons.woff
--------------------------------------------------------------------------------
/vue-element-admin/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature Request(新功能建议)
3 | about: Suggest an idea for this project
4 | ---
5 |
6 | ## Feature request(新功能建议)
7 |
8 |
--------------------------------------------------------------------------------
/vue-element-admin/public/static/tinymce4.7.5/skins/lightgray/img/anchor.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/raneenana/tasksystem/HEAD/vue-element-admin/public/static/tinymce4.7.5/skins/lightgray/img/anchor.gif
--------------------------------------------------------------------------------
/vue-element-admin/public/static/tinymce4.7.5/skins/lightgray/img/loader.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/raneenana/tasksystem/HEAD/vue-element-admin/public/static/tinymce4.7.5/skins/lightgray/img/loader.gif
--------------------------------------------------------------------------------
/vue-element-admin/public/static/tinymce4.7.5/skins/lightgray/img/object.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/raneenana/tasksystem/HEAD/vue-element-admin/public/static/tinymce4.7.5/skins/lightgray/img/object.gif
--------------------------------------------------------------------------------
/vue-element-admin/public/static/tinymce4.7.5/skins/lightgray/img/trans.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/raneenana/tasksystem/HEAD/vue-element-admin/public/static/tinymce4.7.5/skins/lightgray/img/trans.gif
--------------------------------------------------------------------------------
/vue-element-admin/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
--------------------------------------------------------------------------------
/vue-element-admin/public/static/tinymce4.7.5/skins/lightgray/fonts/tinymce.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/raneenana/tasksystem/HEAD/vue-element-admin/public/static/tinymce4.7.5/skins/lightgray/fonts/tinymce.eot
--------------------------------------------------------------------------------
/vue-element-admin/public/static/tinymce4.7.5/skins/lightgray/fonts/tinymce.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/raneenana/tasksystem/HEAD/vue-element-admin/public/static/tinymce4.7.5/skins/lightgray/fonts/tinymce.ttf
--------------------------------------------------------------------------------
/vue-element-admin/public/static/tinymce4.7.5/plugins/emoticons/img/smiley-cry.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/raneenana/tasksystem/HEAD/vue-element-admin/public/static/tinymce4.7.5/plugins/emoticons/img/smiley-cry.gif
--------------------------------------------------------------------------------
/vue-element-admin/public/static/tinymce4.7.5/skins/lightgray/fonts/tinymce.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/raneenana/tasksystem/HEAD/vue-element-admin/public/static/tinymce4.7.5/skins/lightgray/fonts/tinymce.woff
--------------------------------------------------------------------------------
/vue-element-admin/src/views/nested/menu1/menu1-3/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/vue-element-admin/public/static/tinymce4.7.5/plugins/emoticons/img/smiley-cool.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/raneenana/tasksystem/HEAD/vue-element-admin/public/static/tinymce4.7.5/plugins/emoticons/img/smiley-cool.gif
--------------------------------------------------------------------------------
/vue-element-admin/public/static/tinymce4.7.5/plugins/emoticons/img/smiley-frown.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/raneenana/tasksystem/HEAD/vue-element-admin/public/static/tinymce4.7.5/plugins/emoticons/img/smiley-frown.gif
--------------------------------------------------------------------------------
/vue-element-admin/public/static/tinymce4.7.5/plugins/emoticons/img/smiley-kiss.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/raneenana/tasksystem/HEAD/vue-element-admin/public/static/tinymce4.7.5/plugins/emoticons/img/smiley-kiss.gif
--------------------------------------------------------------------------------
/vue-element-admin/public/static/tinymce4.7.5/plugins/emoticons/img/smiley-smile.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/raneenana/tasksystem/HEAD/vue-element-admin/public/static/tinymce4.7.5/plugins/emoticons/img/smiley-smile.gif
--------------------------------------------------------------------------------
/vue-element-admin/public/static/tinymce4.7.5/plugins/emoticons/img/smiley-wink.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/raneenana/tasksystem/HEAD/vue-element-admin/public/static/tinymce4.7.5/plugins/emoticons/img/smiley-wink.gif
--------------------------------------------------------------------------------
/vue-element-admin/public/static/tinymce4.7.5/plugins/emoticons/img/smiley-yell.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/raneenana/tasksystem/HEAD/vue-element-admin/public/static/tinymce4.7.5/plugins/emoticons/img/smiley-yell.gif
--------------------------------------------------------------------------------
/vue-element-admin/src/api/qiniu.js:
--------------------------------------------------------------------------------
1 | import request from '@/utils/request'
2 |
3 | export function getToken() {
4 | return request({
5 | url: '/qiniu/upload/token', // 假地址 自行替换
6 | method: 'get'
7 | })
8 | }
9 |
--------------------------------------------------------------------------------
/vue-element-admin/src/icons/svg/chart.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/vue-element-admin/public/static/tinymce4.7.5/plugins/emoticons/img/smiley-innocent.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/raneenana/tasksystem/HEAD/vue-element-admin/public/static/tinymce4.7.5/plugins/emoticons/img/smiley-innocent.gif
--------------------------------------------------------------------------------
/vue-element-admin/public/static/tinymce4.7.5/plugins/emoticons/img/smiley-laughing.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/raneenana/tasksystem/HEAD/vue-element-admin/public/static/tinymce4.7.5/plugins/emoticons/img/smiley-laughing.gif
--------------------------------------------------------------------------------
/vue-element-admin/public/static/tinymce4.7.5/plugins/emoticons/img/smiley-sealed.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/raneenana/tasksystem/HEAD/vue-element-admin/public/static/tinymce4.7.5/plugins/emoticons/img/smiley-sealed.gif
--------------------------------------------------------------------------------
/vue-element-admin/public/static/tinymce4.7.5/skins/lightgray/fonts/tinymce-mobile.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/raneenana/tasksystem/HEAD/vue-element-admin/public/static/tinymce4.7.5/skins/lightgray/fonts/tinymce-mobile.woff
--------------------------------------------------------------------------------
/vue-element-admin/public/static/tinymce4.7.5/skins/lightgray/fonts/tinymce-small.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/raneenana/tasksystem/HEAD/vue-element-admin/public/static/tinymce4.7.5/skins/lightgray/fonts/tinymce-small.eot
--------------------------------------------------------------------------------
/vue-element-admin/public/static/tinymce4.7.5/skins/lightgray/fonts/tinymce-small.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/raneenana/tasksystem/HEAD/vue-element-admin/public/static/tinymce4.7.5/skins/lightgray/fonts/tinymce-small.ttf
--------------------------------------------------------------------------------
/vue-element-admin/public/static/tinymce4.7.5/skins/lightgray/fonts/tinymce-small.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/raneenana/tasksystem/HEAD/vue-element-admin/public/static/tinymce4.7.5/skins/lightgray/fonts/tinymce-small.woff
--------------------------------------------------------------------------------
/vue-element-admin/src/components/ImageCropper/utils/mimes.js:
--------------------------------------------------------------------------------
1 | export default {
2 | 'jpg': 'image/jpeg',
3 | 'png': 'image/png',
4 | 'gif': 'image/gif',
5 | 'svg': 'image/svg+xml',
6 | 'psd': 'image/photoshop'
7 | }
8 |
--------------------------------------------------------------------------------
/vue-element-admin/src/views/nested/menu1/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/vue-element-admin/public/static/tinymce4.7.5/plugins/emoticons/img/smiley-embarassed.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/raneenana/tasksystem/HEAD/vue-element-admin/public/static/tinymce4.7.5/plugins/emoticons/img/smiley-embarassed.gif
--------------------------------------------------------------------------------
/vue-element-admin/public/static/tinymce4.7.5/plugins/emoticons/img/smiley-surprised.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/raneenana/tasksystem/HEAD/vue-element-admin/public/static/tinymce4.7.5/plugins/emoticons/img/smiley-surprised.gif
--------------------------------------------------------------------------------
/vue-element-admin/public/static/tinymce4.7.5/plugins/emoticons/img/smiley-tongue-out.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/raneenana/tasksystem/HEAD/vue-element-admin/public/static/tinymce4.7.5/plugins/emoticons/img/smiley-tongue-out.gif
--------------------------------------------------------------------------------
/vue-element-admin/public/static/tinymce4.7.5/plugins/emoticons/img/smiley-undecided.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/raneenana/tasksystem/HEAD/vue-element-admin/public/static/tinymce4.7.5/plugins/emoticons/img/smiley-undecided.gif
--------------------------------------------------------------------------------
/vue-element-admin/src/views/nested/menu1/menu1-2/menu1-2-1/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/vue-element-admin/src/views/nested/menu1/menu1-2/menu1-2-2/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/vue-element-admin/public/static/tinymce4.7.5/plugins/emoticons/img/smiley-foot-in-mouth.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/raneenana/tasksystem/HEAD/vue-element-admin/public/static/tinymce4.7.5/plugins/emoticons/img/smiley-foot-in-mouth.gif
--------------------------------------------------------------------------------
/vue-element-admin/public/static/tinymce4.7.5/plugins/emoticons/img/smiley-money-mouth.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/raneenana/tasksystem/HEAD/vue-element-admin/public/static/tinymce4.7.5/plugins/emoticons/img/smiley-money-mouth.gif
--------------------------------------------------------------------------------
/vue-element-admin/src/views/errorLog/errorTestB.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
12 |
--------------------------------------------------------------------------------
/vue-element-admin/plop-templates/utils.js:
--------------------------------------------------------------------------------
1 | exports.notEmpty = name => {
2 | return v => {
3 | if (!v || v.trim === '') {
4 | return `${name} is required`
5 | } else {
6 | return true
7 | }
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/vue-element-admin/src/views/example/components/Dropdown/index.js:
--------------------------------------------------------------------------------
1 | export { default as CommentDropdown } from './Comment'
2 | export { default as PlatformDropdown } from './Platform'
3 | export { default as SourceUrlDropdown } from './SourceUrl'
4 |
--------------------------------------------------------------------------------
/vue-element-admin/src/icons/svg/size.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/vue-element-admin/src/views/nested/menu1/menu1-1/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/vue-element-admin/src/views/nested/menu1/menu1-2/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/vue-element-admin/.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 |
--------------------------------------------------------------------------------
/vue-element-admin/src/views/errorLog/errorTestA.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {{ a.a }}
5 |
6 |
7 |
8 |
9 |
14 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # tasksystem
2 | 后台管理:根据登陆者的权限id不同进行判断用户可以查看的页面
3 |
4 | #### 1,下载安装依赖
5 | ```
6 | npm install
7 | cnpm install
8 | ```
9 | #### 2,运行项目
10 | ```
11 | npm run dev
12 | ```
13 | #### 3,打包项目,上线运行
14 | ```
15 | npm run build:prod
16 | ```
17 | #### 4,运用框架
18 | vue框架与element-ui
--------------------------------------------------------------------------------
/vue-element-admin/src/views/example/edit.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
13 |
14 |
--------------------------------------------------------------------------------
/vue-element-admin/src/views/example/create.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
13 |
14 |
--------------------------------------------------------------------------------
/vue-element-admin/plopfile.js:
--------------------------------------------------------------------------------
1 | const viewGenerator = require('./plop-templates/view/prompt')
2 | const componentGenerator = require('./plop-templates/component/prompt')
3 |
4 | module.exports = function(plop) {
5 | plop.setGenerator('view', viewGenerator)
6 | plop.setGenerator('component', componentGenerator)
7 | }
8 |
--------------------------------------------------------------------------------
/vue-element-admin/src/icons/svg/link.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/vue-element-admin/src/layout/components/index.js:
--------------------------------------------------------------------------------
1 | export { default as AppMain } from './AppMain'
2 | export { default as Navbar } from './Navbar'
3 | export { default as Settings } from './Settings'
4 | export { default as Sidebar } from './Sidebar/index.vue'
5 | export { default as TagsView } from './TagsView/index.vue'
6 |
--------------------------------------------------------------------------------
/vue-element-admin/src/api/showUser.js:
--------------------------------------------------------------------------------
1 | import request from '@/utils/request'
2 |
3 | export function showUser() {
4 | return request({
5 | url: '/user/user',
6 | method: 'get'
7 | })
8 | }
9 | export function identity() {
10 | return request({
11 | url: '/user/identity',
12 | method: 'get'
13 | })
14 | }
15 |
--------------------------------------------------------------------------------
/vue-element-admin/src/directive/waves/index.js:
--------------------------------------------------------------------------------
1 | import waves from './waves'
2 |
3 | const install = function(Vue) {
4 | Vue.directive('waves', waves)
5 | }
6 |
7 | if (window.Vue) {
8 | window.waves = waves
9 | Vue.use(install); // eslint-disable-line
10 | }
11 |
12 | waves.install = install
13 | export default waves
14 |
--------------------------------------------------------------------------------
/vue-element-admin/.editorconfig:
--------------------------------------------------------------------------------
1 | # https://editorconfig.org
2 | root = true
3 |
4 | [*]
5 | charset = utf-8
6 | indent_style = space
7 | indent_size = 2
8 | end_of_line = lf
9 | insert_final_newline = true
10 | trim_trailing_whitespace = true
11 |
12 | [*.md]
13 | insert_final_newline = false
14 | trim_trailing_whitespace = false
15 |
--------------------------------------------------------------------------------
/vue-element-admin/src/views/svg-icons/requireIcons.js:
--------------------------------------------------------------------------------
1 | const req = require.context('../../icons/svg', false, /\.svg$/)
2 | const requireAll = requireContext => requireContext.keys()
3 |
4 | const re = /\.\/(.*)\.svg/
5 |
6 | const icons = requireAll(req).map(i => {
7 | return i.match(re)[1]
8 | })
9 |
10 | export default icons
11 |
--------------------------------------------------------------------------------
/vue-element-admin/src/directive/el-dragDialog/index.js:
--------------------------------------------------------------------------------
1 | import drag from './drag'
2 |
3 | const install = function(Vue) {
4 | Vue.directive('el-drag-dialog', drag)
5 | }
6 |
7 | if (window.Vue) {
8 | window['el-drag-dialog'] = drag
9 | Vue.use(install); // eslint-disable-line
10 | }
11 |
12 | drag.install = install
13 | export default drag
14 |
--------------------------------------------------------------------------------
/vue-element-admin/src/icons/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import SvgIcon from '@/components/SvgIcon'// svg组件
3 |
4 | // register globally
5 | Vue.component('svg-icon', SvgIcon)
6 |
7 | const req = require.context('./svg', false, /\.svg$/)
8 | const requireAll = requireContext => requireContext.keys().map(requireContext)
9 | requireAll(req)
10 |
--------------------------------------------------------------------------------
/vue-element-admin/src/icons/svg/guide.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/vue-element-admin/src/views/redirect/index.vue:
--------------------------------------------------------------------------------
1 |
13 |
--------------------------------------------------------------------------------
/vue-element-admin/src/icons/svg/component.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/vue-element-admin/src/directive/clipboard/index.js:
--------------------------------------------------------------------------------
1 | import Clipboard from './clipboard'
2 |
3 | const install = function(Vue) {
4 | Vue.directive('Clipboard', Clipboard)
5 | }
6 |
7 | if (window.Vue) {
8 | window.clipboard = Clipboard
9 | Vue.use(install); // eslint-disable-line
10 | }
11 |
12 | Clipboard.install = install
13 | export default Clipboard
14 |
--------------------------------------------------------------------------------
/vue-element-admin/src/icons/svg/money.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/vue-element-admin/src/views/pdf/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | {{ $t('pdf.tips') }}
4 |
5 |
6 | Click to download PDF
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/vue-element-admin/src/directive/permission/index.js:
--------------------------------------------------------------------------------
1 | import permission from './permission'
2 |
3 | const install = function(Vue) {
4 | Vue.directive('permission', permission)
5 | }
6 |
7 | if (window.Vue) {
8 | window['permission'] = permission
9 | Vue.use(install); // eslint-disable-line
10 | }
11 |
12 | permission.install = install
13 | export default permission
14 |
--------------------------------------------------------------------------------
/vue-element-admin/src/icons/svg/email.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/vue-element-admin/src/icons/svg/drag.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/vue-element-admin/src/icons/svgo.yml:
--------------------------------------------------------------------------------
1 | # replace default config
2 |
3 | # multipass: true
4 | # full: true
5 |
6 | plugins:
7 |
8 | # - name
9 | #
10 | # or:
11 | # - name: false
12 | # - name: true
13 | #
14 | # or:
15 | # - name:
16 | # param1: 1
17 | # param2: 2
18 |
19 | - removeAttrs:
20 | attrs:
21 | - 'fill'
22 | - 'fill-rule'
23 |
--------------------------------------------------------------------------------
/vue-element-admin/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules/
3 | dist/
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | **/*.log
8 |
9 | tests/**/coverage/
10 | tests/e2e/reports
11 | selenium-debug.log
12 |
13 | # Editor directories and files
14 | .idea
15 | .vscode
16 | *.suo
17 | *.ntvs*
18 | *.njsproj
19 | *.sln
20 | *.local
21 |
22 | package-lock.json
23 | yarn.lock
24 |
--------------------------------------------------------------------------------
/vue-element-admin/src/utils/auth.js:
--------------------------------------------------------------------------------
1 | import Cookies from 'js-cookie'
2 |
3 | const TokenKey = 'authorization'
4 |
5 | export function getToken() {
6 | return Cookies.get(TokenKey)
7 | }
8 |
9 | export function setToken(token) {
10 | return Cookies.set(TokenKey, token, { expires: 7 })
11 | }
12 |
13 | export function removeToken() {
14 | return Cookies.remove(TokenKey)
15 | }
16 |
--------------------------------------------------------------------------------
/vue-element-admin/src/directive/el-table/index.js:
--------------------------------------------------------------------------------
1 |
2 | import adaptive from './adaptive'
3 |
4 | const install = function(Vue) {
5 | Vue.directive('el-height-adaptive-table', adaptive)
6 | }
7 |
8 | if (window.Vue) {
9 | window['el-height-adaptive-table'] = adaptive
10 | Vue.use(install); // eslint-disable-line
11 | }
12 |
13 | adaptive.install = install
14 | export default adaptive
15 |
--------------------------------------------------------------------------------
/vue-element-admin/src/icons/svg/guide 2.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/vue-element-admin/src/api/remoteSearch.js:
--------------------------------------------------------------------------------
1 | import request from '@/utils/request'
2 |
3 | export function searchUser(name) {
4 | return request({
5 | url: '/search/user',
6 | method: 'get',
7 | params: { name }
8 | })
9 | }
10 |
11 | export function transactionList(query) {
12 | return request({
13 | url: '/transaction/list',
14 | method: 'get',
15 | params: query
16 | })
17 | }
18 |
--------------------------------------------------------------------------------
/vue-element-admin/src/store/modules/errorLog.js:
--------------------------------------------------------------------------------
1 | const state = {
2 | logs: []
3 | }
4 |
5 | const mutations = {
6 | ADD_ERROR_LOG: (state, log) => {
7 | state.logs.push(log)
8 | }
9 | }
10 |
11 | const actions = {
12 | addErrorLog({ commit }, log) {
13 | commit('ADD_ERROR_LOG', log)
14 | }
15 | }
16 |
17 | export default {
18 | namespaced: true,
19 | state,
20 | mutations,
21 | actions
22 | }
23 |
--------------------------------------------------------------------------------
/vue-element-admin/src/utils/i18n.js:
--------------------------------------------------------------------------------
1 | // translate router.meta.title, be used in breadcrumb sidebar tagsview
2 | export function generateTitle(title) {
3 | const hasKey = this.$te('route.' + title)
4 |
5 | if (hasKey) {
6 | // $t :this method from vue-i18n, inject in @/lang/index.js
7 | const translatedTitle = this.$t('route.' + title)
8 |
9 | return translatedTitle
10 | }
11 | return title
12 | }
13 |
--------------------------------------------------------------------------------
/vue-element-admin/src/views/login/authRedirect.vue:
--------------------------------------------------------------------------------
1 |
16 |
--------------------------------------------------------------------------------
/vue-element-admin/src/icons/svg/documentation.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/vue-element-admin/src/icons/svg/fullscreen.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/vue-element-admin/plop-templates/view/index.hbs:
--------------------------------------------------------------------------------
1 | {{#if template}}
2 |
3 |
4 |
5 | {{/if}}
6 |
7 | {{#if script}}
8 |
20 | {{/if}}
21 |
22 | {{#if style}}
23 |
26 | {{/if}}
27 |
--------------------------------------------------------------------------------
/vue-element-admin/src/icons/svg/user.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/vue-element-admin/plop-templates/component/index.hbs:
--------------------------------------------------------------------------------
1 | {{#if template}}
2 |
3 |
4 |
5 | {{/if}}
6 |
7 | {{#if script}}
8 |
20 | {{/if}}
21 |
22 | {{#if style}}
23 |
26 | {{/if}}
27 |
--------------------------------------------------------------------------------
/vue-element-admin/src/icons/svg/lock.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/vue-element-admin/src/views/example/components/Warning.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | 创建和编辑页面是不能被keep-alive 缓存的,因为keep-alive 的include 目前不支持根据路由来缓存,所以目前都是基于component name 来缓存的,如果你想要实现缓存的效果,可以使用localstorage 等浏览器缓存方案。或者不要使用keep-alive
4 | 的include,直接缓存所有页面。详情见
5 | 文档
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/vue-element-admin/src/icons/svg/excel.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/vue-element-admin/src/views/charts/line.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
15 |
16 |
23 |
24 |
--------------------------------------------------------------------------------
/vue-element-admin/.github/ISSUE_TEMPLATE/question.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Question(提问)
3 | about: Asking questions about use
4 | ---
5 |
6 | ## Question(提问)
7 |
8 |
15 |
--------------------------------------------------------------------------------
/vue-element-admin/src/views/charts/mixChart.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
15 |
16 |
23 |
24 |
--------------------------------------------------------------------------------
/vue-element-admin/src/views/charts/keyboard.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
15 |
16 |
23 |
24 |
--------------------------------------------------------------------------------
/vue-element-admin/src/views/permission/page.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
20 |
--------------------------------------------------------------------------------
/vue-element-admin/src/icons/svg/example.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/vue-element-admin/src/components/Tinymce/toolbar.js:
--------------------------------------------------------------------------------
1 | // Here is a list of the toolbar
2 | // Detail list see https://www.tinymce.com/docs/advanced/editor-control-identifiers/#toolbarcontrols
3 |
4 | const toolbar = ['searchreplace bold italic underline strikethrough alignleft aligncenter alignright outdent indent blockquote undo redo removeformat subscript superscript code codesample', 'hr bullist numlist link image charmap preview anchor pagebreak insertdatetime media table emoticons forecolor backcolor fullscreen']
5 |
6 | export default toolbar
7 |
--------------------------------------------------------------------------------
/vue-element-admin/src/icons/svg/star.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/vue-element-admin/src/icons/svg/table.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/vue-element-admin/src/icons/svg/search.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/vue-element-admin/.env.development:
--------------------------------------------------------------------------------
1 | # just a flag
2 | ENV = 'development'
3 |
4 | # base api
5 | VUE_APP_BASE_API = '/dev-api'
6 |
7 | # vue-cli uses the VUE_CLI_BABEL_TRANSPILE_MODULES environment variable,
8 | # to control whether the babel-plugin-dynamic-import-node plugin is enabled.
9 | # It only does one thing by converting all import() to require().
10 | # This configuration can significantly increase the speed of hot updates,
11 | # when you have a large number of pages.
12 | # Detail: https://github.com/vuejs/vue-cli/blob/dev/packages/@vue/babel-preset-app/index.js
13 |
14 | VUE_CLI_BABEL_TRANSPILE_MODULES = true
15 |
--------------------------------------------------------------------------------
/vue-element-admin/src/components/Tinymce/plugins.js:
--------------------------------------------------------------------------------
1 | // Any plugins you want to use has to be imported
2 | // Detail plugins list see https://www.tinymce.com/docs/plugins/
3 | // Custom builds see https://www.tinymce.com/download/custom-builds/
4 |
5 | const plugins = ['advlist anchor autolink autosave code codesample colorpicker colorpicker contextmenu directionality emoticons fullscreen hr image imagetools insertdatetime link lists media nonbreaking noneditable pagebreak paste preview print save searchreplace spellchecker tabfocus table template textcolor textpattern visualblocks visualchars wordcount']
6 |
7 | export default plugins
8 |
--------------------------------------------------------------------------------
/vue-element-admin/src/views/table/dynamicTable/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {{ $t('table.dynamicTips1') }}
5 |
6 |
7 |
8 |
9 | {{ $t('table.dynamicTips2') }}
10 |
11 |
12 |
13 |
14 |
15 |
24 |
25 |
--------------------------------------------------------------------------------
/vue-element-admin/src/icons/svg/password.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/vue-element-admin/src/components/ImageCropper/utils/data2blob.js:
--------------------------------------------------------------------------------
1 | /**
2 | * database64文件格式转换为2进制
3 | *
4 | * @param {[String]} data dataURL 的格式为 “data:image/png;base64,****”,逗号之前都是一些说明性的文字,我们只需要逗号之后的就行了
5 | * @param {[String]} mime [description]
6 | * @return {[blob]} [description]
7 | */
8 | export default function(data, mime) {
9 | data = data.split(',')[1]
10 | data = window.atob(data)
11 | var ia = new Uint8Array(data.length)
12 | for (var i = 0; i < data.length; i++) {
13 | ia[i] = data.charCodeAt(i)
14 | }
15 | // canvas.toDataURL 返回的默认格式就是 image/png
16 | return new Blob([ia], {
17 | type: mime
18 | })
19 | }
20 |
--------------------------------------------------------------------------------
/vue-element-admin/src/layout/components/Sidebar/Item.vue:
--------------------------------------------------------------------------------
1 |
30 |
--------------------------------------------------------------------------------
/vue-element-admin/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | <%= webpackConfig.name %>
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/vue-element-admin/src/router/modules/headImage.js:
--------------------------------------------------------------------------------
1 | /** When your routing table is too long, you can split it into small modules**/
2 |
3 | import Layout from '@/layout'
4 |
5 | const headImageRouter = {
6 | path: '/headImage',
7 | component: Layout,
8 | redirect: 'noredirect',
9 | name: 'headImage',
10 | hidden: true,
11 | meta: {
12 | title: 'headImage',
13 | icon: 'table'
14 | },
15 | children: [
16 | {
17 | path: 'index',
18 | component: () => import('@/views/headImage'),
19 | name: 'headImages',
20 | meta: { title: 'headImage', noCache: true }
21 | }
22 | ]
23 | }
24 |
25 | export default headImageRouter
26 |
--------------------------------------------------------------------------------
/vue-element-admin/src/icons/svg/tab.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/vue-element-admin/src/icons/svg/message.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/vue-element-admin/src/icons/svg/theme.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/vue-element-admin/src/directive/permission/permission.js:
--------------------------------------------------------------------------------
1 |
2 | import store from '@/store'
3 |
4 | export default {
5 | inserted(el, binding, vnode) {
6 | const { value } = binding
7 | const roles = store.getters && store.getters.roles
8 |
9 | if (value && value instanceof Array && value.length > 0) {
10 | const permissionRoles = value
11 |
12 | const hasPermission = roles.some(role => {
13 | return permissionRoles.includes(role)
14 | })
15 |
16 | if (!hasPermission) {
17 | el.parentNode && el.parentNode.removeChild(el)
18 | }
19 | } else {
20 | throw new Error(`need roles! Like v-permission="['admin','editor']"`)
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/vue-element-admin/src/api/user.js:
--------------------------------------------------------------------------------
1 | import request from '@/utils/request'
2 |
3 | export function login(data) {
4 | return request({
5 | url: '/user/login',
6 | method: 'post',
7 | data
8 | })
9 | }
10 |
11 | export function getInfo() {
12 | return request({
13 | url: '/user/userInfo',
14 | method: 'get'
15 | })
16 | }
17 |
18 | export function getViewAuthority(data) {
19 | return request.get('/user/new', { params: { user_id: data }})
20 | }
21 | export function newitem(data) {
22 | return request.get('/user/new', { params: { user_id: data.user_id }})
23 | }
24 |
25 | export function logout() {
26 | return request({
27 | url: '/user/logout',
28 | method: 'post'
29 | })
30 | }
31 |
--------------------------------------------------------------------------------
/vue-element-admin/src/api/readPapers.js:
--------------------------------------------------------------------------------
1 | import request from '@/utils/request'
2 |
3 | // 获取已经分配教室的班级,得到待批班级的信息
4 | export function classInfo() {
5 | return request({
6 | url: '/manger/grade',
7 | method: 'get'
8 | })
9 | }
10 | // 获取学生试卷列表
11 | export function getStudent(params) {
12 | return request({
13 | url: '/exam/student',
14 | method: 'get',
15 | params
16 | })
17 | }
18 | // 获取学生试卷
19 | export function getExam(data) {
20 | return request({
21 | url: '/exam/student/' + data.id,
22 | method: 'get'
23 | })
24 | }
25 | // 批阅试卷
26 | export function getScroll(data) {
27 | return request({
28 | url: '/exam/student/' + data.id,
29 | method: 'put',
30 | data: data
31 | })
32 | }
33 |
--------------------------------------------------------------------------------
/vue-element-admin/src/vendor/Export2Zip.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable */
2 | require('script-loader!file-saver');
3 | import JSZip from 'jszip'
4 |
5 | export function export_txt_to_zip(th, jsonData, txtName, zipName) {
6 | const zip = new JSZip()
7 | const txt_name = txtName || 'file'
8 | const zip_name = zipName || 'file'
9 | const data = jsonData
10 | let txtData = `${th}\r\n`
11 | data.forEach((row) => {
12 | let tempStr = ''
13 | tempStr = row.toString()
14 | txtData += `${tempStr}\r\n`
15 | })
16 | zip.file(`${txt_name}.txt`, txtData)
17 | zip.generateAsync({
18 | type: "blob"
19 | }).then((blob) => {
20 | saveAs(blob, `${zip_name}.zip`)
21 | }, (err) => {
22 | alert('导出失败')
23 | })
24 | }
25 |
--------------------------------------------------------------------------------
/vue-element-admin/src/utils/permission.js:
--------------------------------------------------------------------------------
1 | import store from '@/store'
2 |
3 | /**
4 | * @param {Array} value
5 | * @returns {Boolean}
6 | * @example see @/views/permission/directive.vue
7 | */
8 | export default function checkPermission(value) {
9 | if (value && value instanceof Array && value.length > 0) {
10 | const roles = store.getters && store.getters.roles
11 | const permissionRoles = value
12 |
13 | const hasPermission = roles.some(role => {
14 | return permissionRoles.includes(role)
15 | })
16 | if (!hasPermission) {
17 | return false
18 | }
19 | return true
20 | } else {
21 | console.error(`need roles! Like v-permission="['admin','editor']"`)
22 | return false
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/vue-element-admin/src/components/MarkdownEditor/defaultOptions.js:
--------------------------------------------------------------------------------
1 | // doc: https://nhnent.github.io/tui.editor/api/latest/ToastUIEditor.html#ToastUIEditor
2 | export default {
3 | minHeight: '200px',
4 | previewStyle: 'vertical',
5 | useCommandShortcut: true,
6 | useDefaultHTMLSanitizer: true,
7 | usageStatistics: false,
8 | hideModeSwitch: false,
9 | toolbarItems: [
10 | 'heading',
11 | 'bold',
12 | 'italic',
13 | 'strike',
14 | 'divider',
15 | 'hr',
16 | 'quote',
17 | 'divider',
18 | 'ul',
19 | 'ol',
20 | 'task',
21 | 'indent',
22 | 'outdent',
23 | 'divider',
24 | 'table',
25 | 'image',
26 | 'link',
27 | 'divider',
28 | 'code',
29 | 'codeblock'
30 | ]
31 | }
32 |
--------------------------------------------------------------------------------
/vue-element-admin/src/icons/svg/peoples.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/vue-element-admin/src/api/role.js:
--------------------------------------------------------------------------------
1 | import request from '@/utils/request'
2 |
3 | export function getRoutes() {
4 | return request({
5 | url: '/routes',
6 | method: 'get'
7 | })
8 | }
9 |
10 | export function getRoles() {
11 | return request({
12 | url: '/roles',
13 | method: 'get'
14 | })
15 | }
16 |
17 | export function addRole(data) {
18 | return request({
19 | url: '/role',
20 | method: 'post',
21 | data
22 | })
23 | }
24 |
25 | export function updateRole(id, data) {
26 | return request({
27 | url: `/role/${id}`,
28 | method: 'put',
29 | data
30 | })
31 | }
32 |
33 | export function deleteRole(id) {
34 | return request({
35 | url: `/role/${id}`,
36 | method: 'delete'
37 | })
38 | }
39 |
--------------------------------------------------------------------------------
/vue-element-admin/src/store/modules/settings.js:
--------------------------------------------------------------------------------
1 | import defaultSettings from '@/settings'
2 | const { showSettings, tagsView, fixedHeader, sidebarLogo, theme } = defaultSettings
3 |
4 | const state = {
5 | theme: theme,
6 | showSettings: showSettings,
7 | tagsView: tagsView,
8 | fixedHeader: fixedHeader,
9 | sidebarLogo: sidebarLogo
10 | }
11 |
12 | const mutations = {
13 | CHANGE_SETTING: (state, { key, value }) => {
14 | if (state.hasOwnProperty(key)) {
15 | state[key] = value
16 | }
17 | }
18 | }
19 |
20 | const actions = {
21 | changeSetting({ commit }, data) {
22 | commit('CHANGE_SETTING', data)
23 | }
24 | }
25 |
26 | export default {
27 | namespaced: true,
28 | state,
29 | mutations,
30 | actions
31 | }
32 |
33 |
--------------------------------------------------------------------------------
/vue-element-admin/tests/unit/components/SvgIcon.spec.js:
--------------------------------------------------------------------------------
1 | import { shallowMount } from '@vue/test-utils'
2 | import SvgIcon from '@/components/SvgIcon/index.vue'
3 | describe('SvgIcon.vue', () => {
4 | it('iconClass', () => {
5 | const wrapper = shallowMount(SvgIcon, {
6 | propsData: {
7 | iconClass: 'test'
8 | }
9 | })
10 | expect(wrapper.find('use').attributes().href).toBe('#icon-test')
11 | })
12 | it('className', () => {
13 | const wrapper = shallowMount(SvgIcon, {
14 | propsData: {
15 | iconClass: 'test'
16 | }
17 | })
18 | expect(wrapper.classes().length).toBe(1)
19 | wrapper.setProps({ className: 'test' })
20 | expect(wrapper.classes().includes('test')).toBe(true)
21 | })
22 | })
23 |
--------------------------------------------------------------------------------
/vue-element-admin/tests/unit/components/Hamburger.spec.js:
--------------------------------------------------------------------------------
1 | import { shallowMount } from '@vue/test-utils'
2 | import Hamburger from '@/components/Hamburger/index.vue'
3 | describe('Hamburger.vue', () => {
4 | it('toggle click', () => {
5 | const wrapper = shallowMount(Hamburger)
6 | const mockFn = jest.fn()
7 | wrapper.vm.$on('toggleClick', mockFn)
8 | wrapper.find('.hamburger').trigger('click')
9 | expect(mockFn).toBeCalled()
10 | })
11 | it('prop isActive', () => {
12 | const wrapper = shallowMount(Hamburger)
13 | wrapper.setProps({ isActive: true })
14 | expect(wrapper.contains('.is-active')).toBe(true)
15 | wrapper.setProps({ isActive: false })
16 | expect(wrapper.contains('.is-active')).toBe(false)
17 | })
18 | })
19 |
--------------------------------------------------------------------------------
/vue-element-admin/src/views/excel/components/FilenameOption.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
29 |
--------------------------------------------------------------------------------
/vue-element-admin/src/layout/components/Sidebar/Link.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
37 |
--------------------------------------------------------------------------------
/vue-element-admin/src/store/getters.js:
--------------------------------------------------------------------------------
1 | const getters = {
2 | sidebar: state => state.app.sidebar,
3 | language: state => state.app.language,
4 | size: state => state.app.size,
5 | device: state => state.app.device,
6 | visitedViews: state => state.tagsView.visitedViews,
7 | cachedViews: state => state.tagsView.cachedViews,
8 | token: state => state.user.token,
9 | avatar: state => state.user.avatar,
10 | name: state => state.user.name,
11 | introduction: state => state.user.introduction,
12 | roles: state => state.user.roles,
13 | permission_routes: state => state.permission.routes,
14 | addRoutes: state => state.permission.addRoutes,
15 | errorLogs: state => state.errorLog.logs,
16 | userInfo: state => state.user.userInfo
17 | }
18 | export default getters
19 |
--------------------------------------------------------------------------------
/vue-element-admin/src/views/dashboard/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
32 |
--------------------------------------------------------------------------------
/vue-element-admin/src/layout/components/Sidebar/FixiOSBug.js:
--------------------------------------------------------------------------------
1 | export default {
2 | computed: {
3 | device() {
4 | return this.$store.state.app.device
5 | }
6 | },
7 | mounted() {
8 | // In order to fix the click on menu on the ios device will trigger the mouseleave bug
9 | // https://github.com/PanJiaChen/vue-element-admin/issues/1135
10 | this.fixBugIniOS()
11 | },
12 | methods: {
13 | fixBugIniOS() {
14 | const $subMenu = this.$refs.subMenu
15 | if ($subMenu) {
16 | const handleMouseleave = $subMenu.handleMouseleave
17 | $subMenu.handleMouseleave = (e) => {
18 | if (this.device === 'mobile') {
19 | return
20 | }
21 | handleMouseleave(e)
22 | }
23 | }
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/vue-element-admin/src/views/excel/components/AutoWidthOption.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | True
7 |
8 |
9 | False
10 |
11 |
12 |
13 |
14 |
15 |
35 |
--------------------------------------------------------------------------------
/vue-element-admin/src/router/modules/charts.js:
--------------------------------------------------------------------------------
1 | /** When your routing table is too long, you can split it into small modules**/
2 |
3 | import Layout from '@/layout'
4 |
5 | const chartsRouter = {
6 | path: '/charts',
7 | component: Layout,
8 | redirect: 'noredirect',
9 | name: 'Charts',
10 | meta: {
11 | title: 'charts',
12 | icon: 'chart'
13 | },
14 | children: [
15 | {
16 | path: 'line',
17 | component: () => import('@/views/charts/line'),
18 | name: 'LineChart',
19 | meta: { title: 'lineChart', noCache: true }
20 | },
21 | {
22 | path: 'mixchart',
23 | component: () => import('@/views/charts/mixChart'),
24 | name: 'MixChart',
25 | meta: { title: 'mixChart', noCache: true }
26 | }
27 | ]
28 | }
29 |
30 | export default chartsRouter
31 |
--------------------------------------------------------------------------------
/vue-element-admin/src/views/svg-icons/element-icon.json:
--------------------------------------------------------------------------------
1 | ["info","error","success","warning","question","back","arrow-left","arrow-down","arrow-right","arrow-up","caret-left","caret-bottom","caret-top","caret-right","d-arrow-left","d-arrow-right","minus","plus","remove","circle-plus","remove-outline","circle-plus-outline","close","check","circle-close","circle-check","circle-close-outline","circle-check-outline","zoom-out","zoom-in","d-caret","sort","sort-down","sort-up","tickets","document","goods","sold-out","news","message","date","printer","time","bell","mobile-phone","service","view","menu","more","more-outline","star-on","star-off","location","location-outline","phone","phone-outline","picture","picture-outline","delete","search","edit","edit-outline","rank","refresh","share","setting","upload","upload2","download","loading"]
2 |
--------------------------------------------------------------------------------
/vue-element-admin/src/icons/svg/edit.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/vue-element-admin/src/icons/svg/nested.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/vue-element-admin/src/views/permission/components/SwitchRoles.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {{ $t('permission.roles') }}: {{ roles }}
5 |
6 | {{ $t('permission.switchRoles') }}:
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
33 |
--------------------------------------------------------------------------------
/vue-element-admin/src/api/article.js:
--------------------------------------------------------------------------------
1 | import request from '@/utils/request'
2 |
3 | export function fetchList(query) {
4 | return request({
5 | url: '/article/list',
6 | method: 'get',
7 | params: query
8 | })
9 | }
10 |
11 | export function fetchArticle(id) {
12 | return request({
13 | url: '/article/detail',
14 | method: 'get',
15 | params: { id }
16 | })
17 | }
18 |
19 | export function fetchPv(pv) {
20 | return request({
21 | url: '/article/pv',
22 | method: 'get',
23 | params: { pv }
24 | })
25 | }
26 |
27 | export function createArticle(data) {
28 | return request({
29 | url: '/article/create',
30 | method: 'post',
31 | data
32 | })
33 | }
34 |
35 | export function updateArticle(data) {
36 | return request({
37 | url: '/article/update',
38 | method: 'post',
39 | data
40 | })
41 | }
42 |
--------------------------------------------------------------------------------
/vue-element-admin/src/store/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import Vuex from 'vuex'
3 | import getters from './getters'
4 | // import createLogger from 'vuex/dist/logger'
5 | Vue.use(Vuex)
6 |
7 | // https://webpack.js.org/guides/dependency-management/#requirecontext
8 | const modulesFiles = require.context('./modules', false, /\.js$/)
9 |
10 | // you do not need `import app from './modules/app'`
11 | // it will auto require all vuex module from modules file
12 | const modules = modulesFiles.keys().reduce((modules, modulePath) => {
13 | // set './app.js' => 'app'
14 | const moduleName = modulePath.replace(/^\.\/(.*)\.\w+$/, '$1')
15 | const value = modulesFiles(modulePath)
16 | modules[moduleName] = value.default
17 | return modules
18 | }, {})
19 |
20 | const store = new Vuex.Store({
21 | modules,
22 | getters
23 | })
24 |
25 | export default store
26 |
--------------------------------------------------------------------------------
/vue-element-admin/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report(报告问题)
3 | about: Create a report to help us improve
4 | ---
5 |
10 |
11 |
12 | ## Bug report(问题描述)
13 |
14 | #### Steps to reproduce(问题复现步骤)
15 |
20 |
21 | #### Screenshot or Gif(截图或动态图)
22 |
23 |
24 | #### Link to minimal reproduction(最小可在线还原demo)
25 |
26 |
29 |
30 | #### Other relevant information(格外信息)
31 | - Your OS:
32 | - Node.js version:
33 | - vue-element-admin version:
34 |
--------------------------------------------------------------------------------
/vue-element-admin/src/router/modules/user.js:
--------------------------------------------------------------------------------
1 | /** When your routing table is too long, you can split it into small modules**/
2 |
3 | import Layout from '@/layout'
4 |
5 | const userRouter = {
6 | path: '/user',
7 | component: Layout,
8 | redirect: 'noredirect',
9 | name: 'User',
10 | alwaysShow: true,
11 | meta: {
12 | title: 'user',
13 | icon: 'user'
14 | },
15 | children: [
16 | {
17 | path: 'addUser',
18 | component: () => import('@/views/users/addUser'),
19 | name: 'addUser',
20 | meta: { title: 'addUser', noCache: true, view_id: 'main-addUser' }
21 | },
22 | {
23 | path: 'showUser',
24 | component: () => import('@/views/users/showUser'),
25 | name: 'showUser',
26 | meta: { title: 'showUser', noCache: true, view_id: 'main-showUser' }
27 | }
28 | ]
29 | }
30 |
31 | export default userRouter
32 |
--------------------------------------------------------------------------------
/vue-element-admin/src/views/excel/components/BookTypeOption.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
11 |
12 |
13 |
14 |
15 |
40 |
--------------------------------------------------------------------------------
/vue-element-admin/src/icons/svg/project.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/vue-element-admin/src/icons/svg/tree-table.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/vue-element-admin/src/components/SvgIcon/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
34 |
35 |
44 |
--------------------------------------------------------------------------------
/vue-element-admin/src/utils/clipboard.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import Clipboard from 'clipboard'
3 |
4 | function clipboardSuccess() {
5 | Vue.prototype.$message({
6 | message: 'Copy successfully',
7 | type: 'success',
8 | duration: 1500
9 | })
10 | }
11 |
12 | function clipboardError() {
13 | Vue.prototype.$message({
14 | message: 'Copy failed',
15 | type: 'error'
16 | })
17 | }
18 |
19 | export default function handleClipboard(text, event) {
20 | const clipboard = new Clipboard(event.target, {
21 | text: () => text
22 | })
23 | clipboard.on('success', () => {
24 | clipboardSuccess()
25 | clipboard.off('error')
26 | clipboard.off('success')
27 | clipboard.destroy()
28 | })
29 | clipboard.on('error', () => {
30 | clipboardError()
31 | clipboard.off('error')
32 | clipboard.off('success')
33 | clipboard.destroy()
34 | })
35 | clipboard.onClick(event)
36 | }
37 |
--------------------------------------------------------------------------------
/vue-element-admin/src/icons/svg/eye.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/vue-element-admin/src/styles/variables.scss:
--------------------------------------------------------------------------------
1 | // base color
2 | $blue:#324157;
3 | $light-blue:#3A71A8;
4 | $red:#C03639;
5 | $pink: #E65D6E;
6 | $green: #30B08F;
7 | $tiffany: #4AB7BD;
8 | $yellow:#FEC171;
9 | $panGreen: #30B08F;
10 |
11 | //sidebar
12 | $menuText:#bfcbd9;
13 | $menuActiveText:#409EFF;
14 | $subMenuActiveText:#f4f4f5; //https://github.com/ElemeFE/element/issues/12951
15 |
16 | $menuBg:#304156;
17 | $menuHover:#263445;
18 |
19 | $subMenuBg:#1f2d3d;
20 | $subMenuHover:#001528;
21 |
22 | $sideBarWidth: 12%;
23 |
24 | // the :export directive is the magic sauce for webpack
25 | // https://www.bluematador.com/blog/how-to-share-variables-between-js-and-sass
26 | :export {
27 | menuText: $menuText;
28 | menuActiveText: $menuActiveText;
29 | subMenuActiveText: $subMenuActiveText;
30 | menuBg: $menuBg;
31 | menuHover: $menuHover;
32 | subMenuBg: $subMenuBg;
33 | subMenuHover: $subMenuHover;
34 | sideBarWidth: $sideBarWidth;
35 | }
36 |
--------------------------------------------------------------------------------
/vue-element-admin/src/styles/transition.scss:
--------------------------------------------------------------------------------
1 | //global transition css
2 |
3 | /*fade*/
4 | .fade-enter-active,
5 | .fade-leave-active {
6 | transition: opacity 0.28s;
7 | }
8 |
9 | .fade-enter,
10 | .fade-leave-active {
11 | opacity: 0;
12 | }
13 |
14 | /*fade-transform*/
15 | .fade-transform-leave-active,
16 | .fade-transform-enter-active {
17 | transition: all .5s;
18 | }
19 |
20 | .fade-transform-enter {
21 | opacity: 0;
22 | transform: translateX(-30px);
23 | }
24 |
25 | .fade-transform-leave-to {
26 | opacity: 0;
27 | transform: translateX(30px);
28 | }
29 |
30 | /*breadcrumb transition*/
31 | .breadcrumb-enter-active,
32 | .breadcrumb-leave-active {
33 | transition: all .5s;
34 | }
35 |
36 | .breadcrumb-enter,
37 | .breadcrumb-leave-active {
38 | opacity: 0;
39 | transform: translateX(20px);
40 | }
41 |
42 | .breadcrumb-move {
43 | transition: all .5s;
44 | }
45 |
46 | .breadcrumb-leave-active {
47 | position: absolute;
48 | }
49 |
--------------------------------------------------------------------------------
/vue-element-admin/src/directive/waves/waves.css:
--------------------------------------------------------------------------------
1 | .waves-ripple {
2 | position: absolute;
3 | border-radius: 100%;
4 | background-color: rgba(0, 0, 0, 0.15);
5 | background-clip: padding-box;
6 | pointer-events: none;
7 | -webkit-user-select: none;
8 | -moz-user-select: none;
9 | -ms-user-select: none;
10 | user-select: none;
11 | -webkit-transform: scale(0);
12 | -ms-transform: scale(0);
13 | transform: scale(0);
14 | opacity: 1;
15 | }
16 |
17 | .waves-ripple.z-active {
18 | opacity: 0;
19 | -webkit-transform: scale(2);
20 | -ms-transform: scale(2);
21 | transform: scale(2);
22 | -webkit-transition: opacity 1.2s ease-out, -webkit-transform 0.6s ease-out;
23 | transition: opacity 1.2s ease-out, -webkit-transform 0.6s ease-out;
24 | transition: opacity 1.2s ease-out, transform 0.6s ease-out;
25 | transition: opacity 1.2s ease-out, transform 0.6s ease-out, -webkit-transform 0.6s ease-out;
26 | }
--------------------------------------------------------------------------------
/vue-element-admin/src/styles/element-variables.scss:
--------------------------------------------------------------------------------
1 | /**
2 | * I think element-ui's default theme color is too light for long-term use.
3 | * So I modified the default color and you can modify it to your liking.
4 | **/
5 |
6 | /* theme color */
7 | $--color-primary: #1890ff;
8 | $--color-success: #13ce66;
9 | $--color-warning: #FFBA00;
10 | $--color-danger: #ff4949;
11 | // $--color-info: #1E1E1E;
12 |
13 | $--button-font-weight: 400;
14 |
15 | // $--color-text-regular: #1f2d3d;
16 |
17 | $--border-color-light: #dfe4ed;
18 | $--border-color-lighter: #e6ebf5;
19 |
20 | $--table-border:1px solid#dfe6ec;
21 |
22 | /* icon font path, required */
23 | $--font-path: '~element-ui/lib/theme-chalk/fonts';
24 |
25 | @import "~element-ui/packages/theme-chalk/src/index";
26 |
27 | // the :export directive is the magic sauce for webpack
28 | // https://www.bluematador.com/blog/how-to-share-variables-between-js-and-sass
29 | :export {
30 | theme: $--color-primary;
31 | }
32 |
--------------------------------------------------------------------------------
/vue-element-admin/src/views/errorLog/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
{{ $t('errorLog.tips') }}
7 |
8 | {{ $t('errorLog.description') }}
9 |
10 | {{ $t('errorLog.documentation') }}
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
28 |
29 |
34 |
--------------------------------------------------------------------------------
/vue-element-admin/src/views/guide/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {{ $t('guide.description') }}
5 | driver.js.
6 |
7 |
8 |
9 | {{ $t('guide.button') }}
10 |
11 |
12 |
13 |
14 |
37 |
--------------------------------------------------------------------------------
/vue-element-admin/src/icons/svg/clipboard.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/vue-element-admin/src/views/components-demo/dropzone.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Based on dropzone .
5 | {{ $t('components.dropzoneTips') }}
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
31 |
32 |
--------------------------------------------------------------------------------
/vue-element-admin/jest.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | verbose: true,
3 | moduleFileExtensions: ['js', 'jsx', 'json', 'vue'],
4 | transformIgnorePatterns: [
5 | 'node_modules/(?!(babel-jest|jest-vue-preprocessor)/)'
6 | ],
7 | transform: {
8 | '^.+\\.vue$': 'vue-jest',
9 | '.+\\.(css|styl|less|sass|scss|svg|png|jpg|ttf|woff|woff2)$': 'jest-transform-stub',
10 | '^.+\\.jsx?$': 'babel-jest'
11 | },
12 | moduleNameMapper: {
13 | '^@/(.*)$': '/src/$1'
14 | },
15 | snapshotSerializers: ['jest-serializer-vue'],
16 | testMatch: [
17 | '**/tests/unit/**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)'
18 | ],
19 | collectCoverageFrom: ['src/utils/**/*.{js,vue}', '!src/utils/auth.js', '!src/utils/request.js', 'src/components/**/*.{js,vue}'],
20 | coverageDirectory: '/tests/unit/coverage',
21 | // 'collectCoverage': true,
22 | 'coverageReporters': [
23 | 'lcov',
24 | 'text-summary'
25 | ],
26 | testURL: 'http://localhost/'
27 | }
28 |
--------------------------------------------------------------------------------
/vue-element-admin/src/icons/svg/list.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/vue-element-admin/src/settings.js:
--------------------------------------------------------------------------------
1 | import variables from '@/styles/element-variables.scss'
2 |
3 | export default {
4 | theme: variables.theme,
5 |
6 | /**
7 | * @type {boolean} true | false
8 | * @description Whether show the settings right-panel
9 | */
10 | showSettings: true,
11 |
12 | /**
13 | * @type {boolean} true | false
14 | * @description Whether need tagsView
15 | */
16 | tagsView: true,
17 |
18 | /**
19 | * @type {boolean} true | false
20 | * @description Whether fix the header
21 | */
22 | fixedHeader: false,
23 |
24 | /**
25 | * @type {boolean} true | false
26 | * @description Whether show the logo in sidebar
27 | */
28 | sidebarLogo: false,
29 |
30 | /**
31 | * @type {string | array} 'production' | ['production', 'development']
32 | * @description Need show err logs component.
33 | * The default is only used in the production env
34 | * If you want to also use it in dev, you can pass ['production', 'development']
35 | */
36 | errorLog: 'production'
37 | }
38 |
--------------------------------------------------------------------------------
/vue-element-admin/src/views/components-demo/dndList.vue:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
12 |
39 |
40 |
--------------------------------------------------------------------------------
/vue-element-admin/src/views/example/components/Dropdown/SourceUrl.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 外链
5 |
6 |
7 |
8 |
9 |
10 |
11 | 填写url
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
39 |
--------------------------------------------------------------------------------
/vue-element-admin/src/icons/svg/icon.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/vue-element-admin/src/layout/components/AppMain.vue:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
11 |
24 |
25 |
49 |
50 |
--------------------------------------------------------------------------------
/vue-element-admin/src/router/modules/classes.js:
--------------------------------------------------------------------------------
1 | /** When your routing table is too long, you can split it into small modules**/
2 |
3 | import Layout from '@/layout'
4 |
5 | const examRouter = {
6 | path: '/classes',
7 | component: Layout,
8 | redirect: 'noredirect',
9 | name: 'Classes',
10 | alwaysShow: true,
11 | meta: {
12 | title: 'classes',
13 | icon: 'table'
14 | },
15 | children: [
16 | {
17 | path: 'class',
18 | component: () => import('@/views/classes/class'),
19 | name: 'class',
20 | meta: { title: 'class', noCache: true, view_id: 'main-grade' }
21 | },
22 | {
23 | path: 'classroom',
24 | component: () => import('@/views/classes/classroom'),
25 | name: 'classroom',
26 | meta: { title: 'classroom', noCache: true, view_id: 'main-student' }
27 | },
28 | {
29 | path: 'student',
30 | component: () => import('@/views/classes/student'),
31 | name: 'student',
32 | meta: { title: 'student', noCache: true, view_id: 'main-room' }
33 | }
34 | ]
35 | }
36 |
37 | export default examRouter
38 |
--------------------------------------------------------------------------------
/vue-element-admin/src/utils/errorLog.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import store from '@/store'
3 | import { isString, isArray } from '@/utils/validate'
4 | import settings from '@/settings'
5 |
6 | // you can set in settings.js
7 | // errorLog:'production' | ['production','development']
8 | const { errorLog: needErrorLog } = settings
9 |
10 | function checkNeed(arg) {
11 | const env = process.env.NODE_ENV
12 | if (isString(needErrorLog)) {
13 | return env === needErrorLog
14 | }
15 | if (isArray(needErrorLog)) {
16 | return needErrorLog.includes(env)
17 | }
18 | return false
19 | }
20 |
21 | if (checkNeed()) {
22 | Vue.config.errorHandler = function(err, vm, info, a) {
23 | // Don't ask me why I use Vue.nextTick, it just a hack.
24 | // detail see https://forum.vuejs.org/t/dispatch-in-vue-config-errorhandler-has-some-problem/23500
25 | Vue.nextTick(() => {
26 | store.dispatch('errorLog/addErrorLog', {
27 | err,
28 | vm,
29 | info,
30 | url: window.location.href
31 | })
32 | console.error(err, info)
33 | })
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/vue-element-admin/build/index.js:
--------------------------------------------------------------------------------
1 | const { run } = require('runjs')
2 | const chalk = require('chalk')
3 | const config = require('../vue.config.js')
4 | const rawArgv = process.argv.slice(2)
5 | const args = rawArgv.join(' ')
6 |
7 | if (process.env.npm_config_preview || rawArgv.includes('--preview')) {
8 | const report = rawArgv.includes('--report')
9 |
10 | run(`vue-cli-service build ${args}`)
11 |
12 | const port = 9526
13 | const publicPath = config.publicPath
14 |
15 | var connect = require('connect')
16 | var serveStatic = require('serve-static')
17 | const app = connect()
18 |
19 | app.use(
20 | publicPath,
21 | serveStatic('./dist', {
22 | index: ['index.html', '/']
23 | })
24 | )
25 |
26 | app.listen(port, function() {
27 | console.log(chalk.green(`> Preview at http://localhost:${port}${publicPath}`))
28 | if (report) {
29 | console.log(chalk.green(`> Report at http://localhost:${port}${publicPath}report.html`))
30 | }
31 |
32 | })
33 | } else {
34 | run(`vue-cli-service build ${args}`)
35 | }
--------------------------------------------------------------------------------
/vue-element-admin/tests/unit/utils/parseTime.spec.js:
--------------------------------------------------------------------------------
1 | import { parseTime } from '@/utils/index.js'
2 | describe('Utils:parseTime', () => {
3 | const d = new Date('2018-07-13 17:54:01') // "2018-07-13 17:54:01"
4 | it('timestamp', () => {
5 | expect(parseTime(d)).toBe('2018-07-13 17:54:01')
6 | })
7 | it('ten digits timestamp', () => {
8 | expect(parseTime((d / 1000).toFixed(0))).toBe('2018-07-13 17:54:01')
9 | })
10 | it('new Date', () => {
11 | expect(parseTime(new Date(d))).toBe('2018-07-13 17:54:01')
12 | })
13 | it('format', () => {
14 | expect(parseTime(d, '{y}-{m}-{d} {h}:{i}')).toBe('2018-07-13 17:54')
15 | expect(parseTime(d, '{y}-{m}-{d}')).toBe('2018-07-13')
16 | expect(parseTime(d, '{y}/{m}/{d} {h}-{i}')).toBe('2018/07/13 17-54')
17 | })
18 | it('get the day of the week', () => {
19 | expect(parseTime(d, '{a}')).toBe('五') // 星期五
20 | })
21 | it('get the day of the week', () => {
22 | expect(parseTime(+d + 1000 * 60 * 60 * 24 * 2, '{a}')).toBe('日') // 星期日
23 | })
24 | it('empty argument', () => {
25 | expect(parseTime()).toBeNull()
26 | })
27 | })
28 |
--------------------------------------------------------------------------------
/vue-element-admin/src/icons/svg/sliders.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/vue-element-admin/src/views/example/components/Dropdown/Comment.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {{ !comment_disabled?'评论已打开':'评论已关闭' }}
5 |
6 |
7 |
8 |
9 |
10 |
11 | 关闭评论
12 |
13 |
14 | 打开评论
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
42 |
--------------------------------------------------------------------------------
/vue-element-admin/src/icons/svg/international.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/vue-element-admin/src/api/examination.js:
--------------------------------------------------------------------------------
1 | import request from '@/utils/request'
2 |
3 | // 考试类型
4 | export function typeExam() {
5 | return request({
6 | url: '/exam/examType',
7 | method: 'get'
8 | })
9 | }
10 | // 课程
11 | export function getCurriculum() {
12 | return request({
13 | url: '/exam/subject',
14 | method: 'get'
15 | })
16 | }
17 | // 创建试卷
18 | export function CreateExam(params) {
19 | return request({
20 | url: '/exam/exam',
21 | method: 'post',
22 | data: params
23 | })
24 | }
25 | // 获取试卷列表
26 | export function getExamList() {
27 | return request({
28 | url: '/exam/exam',
29 | method: 'get'
30 | })
31 | }
32 | // 获取试卷列表详情
33 | export function getExamDetail(data) {
34 | return request({
35 | url: '/exam/exam/' + data,
36 | method: 'get'
37 | })
38 | }
39 | // 获取所有的试题
40 | export function getTest() {
41 | return request({
42 | url: '/exam/questions/new',
43 | method: 'get'
44 | })
45 | }
46 | // 更新试卷
47 | export function renewal(str, data) {
48 | return request({
49 | url: '/exam/exam/' + str,
50 | method: 'put',
51 | data
52 | })
53 | }
54 |
--------------------------------------------------------------------------------
/vue-element-admin/src/components/Charts/mixins/resize.js:
--------------------------------------------------------------------------------
1 | import { debounce } from '@/utils'
2 |
3 | export default {
4 | data() {
5 | return {
6 | $_sidebarElm: null
7 | }
8 | },
9 | mounted() {
10 | this.__resizeHandler = debounce(() => {
11 | if (this.chart) {
12 | this.chart.resize()
13 | }
14 | }, 100)
15 | window.addEventListener('resize', this.__resizeHandler)
16 |
17 | this.$_sidebarElm = document.getElementsByClassName('sidebar-container')[0]
18 | this.$_sidebarElm && this.$_sidebarElm.addEventListener('transitionend', this.$_sidebarResizeHandler)
19 | },
20 | beforeDestroy() {
21 | window.removeEventListener('resize', this.__resizeHandler)
22 |
23 | this.$_sidebarElm && this.$_sidebarElm.removeEventListener('transitionend', this.$_sidebarResizeHandler)
24 | },
25 | methods: {
26 | // use $_ for mixins properties
27 | // https://vuejs.org/v2/style-guide/index.html#Private-property-names-essential
28 | $_sidebarResizeHandler(e) {
29 | if (e.propertyName === 'width') {
30 | this.__resizeHandler()
31 | }
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/vue-element-admin/src/components/LangSelect/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | 中文
9 |
10 |
11 | English
12 |
13 |
14 | Español
15 |
16 |
17 |
18 |
19 |
20 |
39 |
--------------------------------------------------------------------------------
/vue-element-admin/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017-present PanJiaChen
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/vue-element-admin/src/icons/svg/wechat.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 |
8 | # Runtime data
9 | pids
10 | *.pid
11 | *.seed
12 | *.pid.lock
13 |
14 | # Directory for instrumented libs generated by jscoverage/JSCover
15 | lib-cov
16 |
17 | # Coverage directory used by tools like istanbul
18 | coverage
19 |
20 | # nyc test coverage
21 | .nyc_output
22 |
23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
24 | .grunt
25 |
26 | # Bower dependency directory (https://bower.io/)
27 | bower_components
28 |
29 | # node-waf configuration
30 | .lock-wscript
31 |
32 | # Compiled binary addons (https://nodejs.org/api/addons.html)
33 | build/Release
34 |
35 | # Dependency directories
36 | node_modules/
37 | jspm_packages/
38 |
39 | # TypeScript v1 declaration files
40 | typings/
41 |
42 | # Optional npm cache directory
43 | .npm
44 |
45 | # Optional eslint cache
46 | .eslintcache
47 |
48 | # Optional REPL history
49 | .node_repl_history
50 |
51 | # Output of 'npm pack'
52 | *.tgz
53 |
54 | # Yarn Integrity file
55 | .yarn-integrity
56 |
57 | # dotenv environment variables file
58 | .env
59 |
60 | # next.js build output
61 | .next
62 |
--------------------------------------------------------------------------------
/vue-element-admin/tests/unit/utils/formatTime.spec.js:
--------------------------------------------------------------------------------
1 | import { formatTime } from '@/utils/index.js'
2 | describe('Utils:formatTime', () => {
3 | const d = new Date('2018-07-13 17:54:01') // "2018-07-13 17:54:01"
4 | const retrofit = 5 * 1000
5 |
6 | it('ten digits timestamp', () => {
7 | expect(formatTime((d / 1000).toFixed(0))).toBe('7月13日17时54分')
8 | })
9 | it('test now', () => {
10 | expect(formatTime(+new Date() - 1)).toBe('刚刚')
11 | })
12 | it('less two minute', () => {
13 | expect(formatTime(+new Date() - 60 * 2 * 1000 + retrofit)).toBe('2分钟前')
14 | })
15 | it('less two hour', () => {
16 | expect(formatTime(+new Date() - 60 * 60 * 2 * 1000 + retrofit)).toBe('2小时前')
17 | })
18 | it('less one day', () => {
19 | expect(formatTime(+new Date() - 60 * 60 * 24 * 1 * 1000)).toBe('1天前')
20 | })
21 | it('more than one day', () => {
22 | expect(formatTime(d)).toBe('7月13日17时54分')
23 | })
24 | it('format', () => {
25 | expect(formatTime(d, '{y}-{m}-{d} {h}:{i}')).toBe('2018-07-13 17:54')
26 | expect(formatTime(d, '{y}-{m}-{d}')).toBe('2018-07-13')
27 | expect(formatTime(d, '{y}/{m}/{d} {h}-{i}')).toBe('2018/07/13 17-54')
28 | })
29 | })
30 |
--------------------------------------------------------------------------------
/vue-element-admin/src/icons/svg/people.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/vue-element-admin/src/router/modules/table.js:
--------------------------------------------------------------------------------
1 | /** When your routing table is too long, you can split it into small modules**/
2 |
3 | import Layout from '@/layout'
4 |
5 | const tableRouter = {
6 | path: '/table',
7 | component: Layout,
8 | redirect: '/table/complex-table',
9 | name: 'Table',
10 | meta: {
11 | title: 'Table',
12 | icon: 'table'
13 | },
14 | children: [
15 | {
16 | path: 'dynamic-table',
17 | component: () => import('@/views/table/dynamicTable/index'),
18 | name: 'DynamicTable',
19 | meta: { title: 'dynamicTable' }
20 | },
21 | {
22 | path: 'drag-table',
23 | component: () => import('@/views/table/dragTable'),
24 | name: 'DragTable',
25 | meta: { title: 'dragTable' }
26 | },
27 | {
28 | path: 'inline-edit-table',
29 | component: () => import('@/views/table/inlineEditTable'),
30 | name: 'InlineEditTable',
31 | meta: { title: 'inlineEditTable' }
32 | },
33 | {
34 | path: 'complex-table',
35 | component: () => import('@/views/table/complexTable'),
36 | name: 'ComplexTable',
37 | meta: { title: 'complexTable' }
38 | }
39 | ]
40 | }
41 | export default tableRouter
42 |
--------------------------------------------------------------------------------
/vue-element-admin/src/views/qiniu/upload.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 将文件拖到此处,或点击上传
6 |
7 |
8 |
9 |
10 |
42 |
--------------------------------------------------------------------------------
/vue-element-admin/src/views/excel/uploadExcel.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
43 |
--------------------------------------------------------------------------------
/vue-element-admin/src/views/components-demo/dragSelect.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | {{ item }}
10 |
11 |
12 |
13 |
14 |
15 |
44 |
--------------------------------------------------------------------------------
/vue-element-admin/src/router/modules/readPapers.js:
--------------------------------------------------------------------------------
1 | import Layout from '@/layout'
2 | const readRouter = {
3 | path: '/readPapers',
4 | component: Layout,
5 | redirect: 'noredirect',
6 | name: 'readPapers',
7 | alwaysShow: true,
8 | meta: {
9 | title: 'readPapers',
10 | icon: 'project'
11 | // view_id: 'main-main-examPaperClassList,main-examPaperClassnate'
12 | },
13 | children: [{
14 | path: 'waitClass', // 待批班级
15 | component: () => import('@/views/readPapers/waitClass'),
16 | name: 'waitClass',
17 | meta: {
18 | title: 'waitClass',
19 | noCache: true,
20 | view_id: 'main-examinationPapers'
21 | }
22 | },
23 | {
24 | path: 'classmate', // 待批学生
25 | component: () => import('@/views/readPapers/classmate'), // Parent router-view
26 | name: 'classmate',
27 | hidden: true,
28 | meta: { title: 'classmate', noCache: true, view_id: 'main-examPaperClassmate' }
29 | },
30 | {
31 | path: 'getscore', // 提交批卷分数
32 | component: () => import('@/views/readPapers/getscore'), // Parent router-view
33 | name: 'getscore',
34 | hidden: true,
35 | meta: { title: 'getscore', noCache: true, view_id: 'main-examDetail' }
36 | }]
37 | }
38 | export default readRouter
39 |
--------------------------------------------------------------------------------
/vue-element-admin/src/icons/svg/language.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/vue-element-admin/tests/unit/utils/validate.spec.js:
--------------------------------------------------------------------------------
1 | import { validUsername, validURL, validLowerCase, validUpperCase, validAlphabets } from '@/utils/validate.js'
2 | describe('Utils:validate', () => {
3 | it('validUsername', () => {
4 | expect(validUsername('admin')).toBe(true)
5 | expect(validUsername('editor')).toBe(true)
6 | expect(validUsername('xxxx')).toBe(false)
7 | })
8 | it('validURL', () => {
9 | expect(validURL('https://github.com/PanJiaChen/vue-element-admin')).toBe(true)
10 | expect(validURL('http://github.com/PanJiaChen/vue-element-admin')).toBe(true)
11 | expect(validURL('github.com/PanJiaChen/vue-element-admin')).toBe(false)
12 | })
13 | it('validLowerCase', () => {
14 | expect(validLowerCase('abc')).toBe(true)
15 | expect(validLowerCase('Abc')).toBe(false)
16 | expect(validLowerCase('123abc')).toBe(false)
17 | })
18 | it('validUpperCase', () => {
19 | expect(validUpperCase('ABC')).toBe(true)
20 | expect(validUpperCase('Abc')).toBe(false)
21 | expect(validUpperCase('123ABC')).toBe(false)
22 | })
23 | it('validAlphabets', () => {
24 | expect(validAlphabets('ABC')).toBe(true)
25 | expect(validAlphabets('Abc')).toBe(true)
26 | expect(validAlphabets('123aBC')).toBe(false)
27 | })
28 | })
29 |
--------------------------------------------------------------------------------
/vue-element-admin/src/icons/svg/eye-open.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/vue-element-admin/src/utils/openWindow.js:
--------------------------------------------------------------------------------
1 | /**
2 | *Created by jiachenpan on 16/11/29.
3 | * @param {Sting} url
4 | * @param {Sting} title
5 | * @param {Number} w
6 | * @param {Number} h
7 | */
8 | export default function openWindow(url, title, w, h) {
9 | // Fixes dual-screen position Most browsers Firefox
10 | const dualScreenLeft = window.screenLeft !== undefined ? window.screenLeft : screen.left
11 | const dualScreenTop = window.screenTop !== undefined ? window.screenTop : screen.top
12 |
13 | const width = window.innerWidth ? window.innerWidth : document.documentElement.clientWidth ? document.documentElement.clientWidth : screen.width
14 | const height = window.innerHeight ? window.innerHeight : document.documentElement.clientHeight ? document.documentElement.clientHeight : screen.height
15 |
16 | const left = ((width / 2) - (w / 2)) + dualScreenLeft
17 | const top = ((height / 2) - (h / 2)) + dualScreenTop
18 | const newWindow = window.open(url, title, 'toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=no, resizable=yes, copyhistory=no, width=' + w + ', height=' + h + ', top=' + top + ', left=' + left)
19 |
20 | // Puts focus on the newWindow
21 | if (window.focus) {
22 | newWindow.focus()
23 | }
24 | }
25 |
26 |
--------------------------------------------------------------------------------
/vue-element-admin/src/directive/el-table/adaptive.js:
--------------------------------------------------------------------------------
1 |
2 | import { addResizeListener, removeResizeListener } from 'element-ui/src/utils/resize-event'
3 |
4 | /**
5 | * How to use
6 | * ...
7 | * el-table height is must be set
8 | * bottomOffset: 30(default) // The height of the table from the bottom of the page.
9 | */
10 |
11 | const doResize = (el, binding, vnode) => {
12 | const { componentInstance: $table } = vnode
13 |
14 | const { value } = binding
15 |
16 | if (!$table.height) {
17 | throw new Error(`el-$table must set the height. Such as height='100px'`)
18 | }
19 | const bottomOffset = (value && value.bottomOffset) || 30
20 |
21 | if (!$table) return
22 |
23 | const height = window.innerHeight - el.getBoundingClientRect().top - bottomOffset
24 | $table.layout.setHeight(height)
25 | $table.doLayout()
26 | }
27 |
28 | export default {
29 | bind(el, binding, vnode) {
30 | el.resizeListener = () => {
31 | doResize(el, binding, vnode)
32 | }
33 |
34 | addResizeListener(el, el.resizeListener)
35 | },
36 | inserted(el, binding, vnode) {
37 | doResize(el, binding, vnode)
38 | },
39 | unbind(el) {
40 | removeResizeListener(el, el.resizeListener)
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/vue-element-admin/mock/remoteSearch.js:
--------------------------------------------------------------------------------
1 | import Mock from 'mockjs'
2 |
3 | const NameList = []
4 | const count = 100
5 |
6 | for (let i = 0; i < count; i++) {
7 | NameList.push(Mock.mock({
8 | name: '@first'
9 | }))
10 | }
11 | NameList.push({ name: 'mock-Pan' })
12 |
13 | export default [
14 | // username search
15 | {
16 | url: '/search/user',
17 | type: 'get',
18 | response: config => {
19 | const { name } = config.query
20 | const mockNameList = NameList.filter(item => {
21 | const lowerCaseName = item.name.toLowerCase()
22 | return !(name && lowerCaseName.indexOf(name.toLowerCase()) < 0)
23 | })
24 | return {
25 | code: 20000,
26 | data: { items: mockNameList }
27 | }
28 | }
29 | },
30 |
31 | // transaction list
32 | {
33 | url: '/transaction/list',
34 | type: 'get',
35 | response: _ => {
36 | return {
37 | code: 20000,
38 | data: {
39 | total: 20,
40 | 'items|20': [{
41 | order_no: '@guid()',
42 | timestamp: +Mock.Random.date('T'),
43 | username: '@name()',
44 | price: '@float(1000, 15000, 0, 2)',
45 | 'status|1': ['success', 'pending']
46 | }]
47 | }
48 | }
49 | }
50 | }
51 | ]
52 |
--------------------------------------------------------------------------------
/vue-element-admin/src/views/guide/defineSteps.js:
--------------------------------------------------------------------------------
1 | const steps = [
2 | {
3 | element: '#hamburger-container',
4 | popover: {
5 | title: 'Hamburger',
6 | description: 'Open && Close sidebar',
7 | position: 'bottom'
8 | }
9 | },
10 | {
11 | element: '#breadcrumb-container',
12 | popover: {
13 | title: 'Breadcrumb',
14 | description: 'Indicate the current page location',
15 | position: 'bottom'
16 | }
17 | },
18 | {
19 | element: '#header-search',
20 | popover: {
21 | title: 'Page Search',
22 | description: 'Page search, quick navigation',
23 | position: 'left'
24 | }
25 | },
26 | {
27 | element: '#screenfull',
28 | popover: {
29 | title: 'Screenfull',
30 | description: 'Set the page into fullscreen',
31 | position: 'left'
32 | }
33 | },
34 | {
35 | element: '#size-select',
36 | popover: {
37 | title: 'Switch Size',
38 | description: 'Switch the system size',
39 | position: 'left'
40 | }
41 | },
42 | {
43 | element: '#tags-view-container',
44 | popover: {
45 | title: 'Tags view',
46 | description: 'The history of the page you visited',
47 | position: 'bottom'
48 | },
49 | padding: 0
50 | }
51 | ]
52 |
53 | export default steps
54 |
--------------------------------------------------------------------------------
/vue-element-admin/src/views/example/components/Dropdown/Platform.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 平台({{ platforms.length }})
5 |
6 |
7 |
8 |
9 |
10 | {{ item.name }}
11 |
12 |
13 |
14 |
15 |
16 |
17 |
47 |
--------------------------------------------------------------------------------
/vue-element-admin/src/components/Screenfull/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
50 |
51 |
61 |
--------------------------------------------------------------------------------
/vue-element-admin/src/components/Hamburger/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
14 |
15 |
16 |
32 |
33 |
45 |
--------------------------------------------------------------------------------
/vue-element-admin/src/lang/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import VueI18n from 'vue-i18n'
3 | import Cookies from 'js-cookie'
4 | import elementEnLocale from 'element-ui/lib/locale/lang/en' // element-ui lang
5 | import elementZhLocale from 'element-ui/lib/locale/lang/zh-CN'// element-ui lang
6 | import elementEsLocale from 'element-ui/lib/locale/lang/es'// element-ui lang
7 | import enLocale from './en'
8 | import zhLocale from './zh'
9 | import esLocale from './es'
10 |
11 | Vue.use(VueI18n)
12 |
13 | const messages = {
14 | en: {
15 | ...enLocale,
16 | ...elementEnLocale
17 | },
18 | zh: {
19 | ...zhLocale,
20 | ...elementZhLocale
21 | },
22 | es: {
23 | ...esLocale,
24 | ...elementEsLocale
25 | }
26 | }
27 | export function getLanguage() {
28 | const chooseLanguage = Cookies.get('language')
29 | if (chooseLanguage) return chooseLanguage
30 |
31 | // if has not choose language
32 | const language = (navigator.language || navigator.browserLanguage).toLowerCase()
33 | const locales = Object.keys(messages)
34 | for (const locale of locales) {
35 | if (language.indexOf(locale) > -1) {
36 | return locale
37 | }
38 | }
39 | return 'en'
40 | }
41 | const i18n = new VueI18n({
42 | // set locale
43 | // options: en | zh | es
44 | locale: getLanguage(),
45 | // set locale messages
46 | messages
47 | })
48 |
49 | export default i18n
50 |
--------------------------------------------------------------------------------
/vue-element-admin/src/views/tab/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | mounted times :{{ createdTimes }}
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
40 |
41 |
46 |
--------------------------------------------------------------------------------
/vue-element-admin/src/icons/svg/404.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/vue-element-admin/src/router/modules/examination.js:
--------------------------------------------------------------------------------
1 | /** When your routing table is too long, you can split it into small modules**/
2 |
3 | import Layout from '@/layout'
4 |
5 | const examination = {
6 | path: '/examination',
7 | component: Layout,
8 | redirect: 'noredirect',
9 | name: 'examination',
10 | alwaysShow: true,
11 | meta: {
12 | title: 'examination',
13 | icon: 'documentation'
14 | },
15 | children: [{
16 | path: 'addexamination',
17 | component: () =>
18 | import('@/views/examination/addexamination'),
19 | name: 'Addexamination',
20 | meta: { title: 'Addexamination', noCache: true, view_id: 'main-addExam' }
21 | },
22 | {
23 | path: 'listexamination',
24 | component: () =>
25 | import('@/views/examination/listexamination'),
26 | name: 'Listexamination',
27 | meta: { title: 'Listexamination', noCache: true, view_id: 'main-examList' }
28 | },
29 | {
30 | path: 'add',
31 | hidden: true,
32 | component: () =>
33 | import('@/views/examination/add'),
34 | name: 'add',
35 | meta: { title: 'add', noCache: true, view_id: 'main-examEdit' }
36 | },
37 | {
38 | path: 'detail',
39 | hidden: true,
40 | component: () =>
41 | import('@/views/examination/detail'),
42 | name: 'detail',
43 | meta: { title: 'detail', noCache: true, view_id: 'main-examDetail' }
44 | }]
45 | }
46 |
47 | export default examination
48 |
--------------------------------------------------------------------------------
/vue-element-admin/plop-templates/view/prompt.js:
--------------------------------------------------------------------------------
1 | const { notEmpty } = require('../utils.js')
2 |
3 | module.exports = {
4 | description: 'generate a view',
5 | prompts: [{
6 | type: 'input',
7 | name: 'name',
8 | message: 'view name please',
9 | validate: notEmpty('name')
10 | },
11 | {
12 | type: 'checkbox',
13 | name: 'blocks',
14 | message: 'Blocks:',
15 | choices: [{
16 | name: '',
17 | value: 'template',
18 | checked: true
19 | },
20 | {
21 | name: '
51 |
--------------------------------------------------------------------------------
/vue-element-admin/src/layout/mixin/ResizeHandler.js:
--------------------------------------------------------------------------------
1 | import store from '@/store'
2 |
3 | const { body } = document
4 | const WIDTH = 992 // refer to Bootstrap's responsive design
5 |
6 | export default {
7 | watch: {
8 | $route(route) {
9 | if (this.device === 'mobile' && this.sidebar.opened) {
10 | store.dispatch('app/closeSideBar', { withoutAnimation: false })
11 | }
12 | }
13 | },
14 | beforeMount() {
15 | window.addEventListener('resize', this.$_resizeHandler)
16 | },
17 | beforeDestroy() {
18 | window.removeEventListener('resize', this.$_resizeHandler)
19 | },
20 | mounted() {
21 | const isMobile = this.$_isMobile()
22 | if (isMobile) {
23 | store.dispatch('app/toggleDevice', 'mobile')
24 | store.dispatch('app/closeSideBar', { withoutAnimation: true })
25 | }
26 | },
27 | methods: {
28 | // use $_ for mixins properties
29 | // https://vuejs.org/v2/style-guide/index.html#Private-property-names-essential
30 | $_isMobile() {
31 | const rect = body.getBoundingClientRect()
32 | return rect.width - 1 < WIDTH
33 | },
34 | $_resizeHandler() {
35 | if (!document.hidden) {
36 | const isMobile = this.$_isMobile()
37 | store.dispatch('app/toggleDevice', isMobile ? 'mobile' : 'desktop')
38 |
39 | if (isMobile) {
40 | store.dispatch('app/closeSideBar', { withoutAnimation: true })
41 | }
42 | }
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/vue-element-admin/plop-templates/component/prompt.js:
--------------------------------------------------------------------------------
1 | const { notEmpty } = require('../utils.js')
2 |
3 | module.exports = {
4 | description: 'generate vue component',
5 | prompts: [{
6 | type: 'input',
7 | name: 'name',
8 | message: 'component name please',
9 | validate: notEmpty('name')
10 | },
11 | {
12 | type: 'checkbox',
13 | name: 'blocks',
14 | message: 'Blocks:',
15 | choices: [{
16 | name: '',
17 | value: 'template',
18 | checked: true
19 | },
20 | {
21 | name: '
30 |
31 |
36 |
37 |
--------------------------------------------------------------------------------
/vue-element-admin/src/styles/element-ui.scss:
--------------------------------------------------------------------------------
1 | //覆盖一些element-ui样式
2 |
3 | .el-breadcrumb__inner,
4 | .el-breadcrumb__inner a {
5 | font-weight: 400 !important;
6 | }
7 |
8 | .el-upload {
9 | input[type="file"] {
10 | display: none !important;
11 | }
12 | }
13 |
14 | .el-upload__input {
15 | display: none;
16 | }
17 |
18 | .cell {
19 | .el-tag {
20 | margin-right: 0px;
21 | }
22 | }
23 |
24 | .small-padding {
25 | .cell {
26 | padding-left: 5px;
27 | padding-right: 5px;
28 | }
29 | }
30 |
31 | .fixed-width {
32 | .el-button--mini {
33 | padding: 7px 10px;
34 | width: 60px;
35 | }
36 | }
37 |
38 | .status-col {
39 | .cell {
40 | padding: 0 10px;
41 | text-align: center;
42 |
43 | .el-tag {
44 | margin-right: 0px;
45 | }
46 | }
47 | }
48 |
49 | //暂时性解决dialog 问题 https://github.com/ElemeFE/element/issues/2461
50 | .el-dialog {
51 | transform: none;
52 | left: 0;
53 | position: relative;
54 | margin: 0 auto;
55 | }
56 |
57 | //文章页textarea修改样式
58 | .article-textarea {
59 | textarea {
60 | padding-right: 40px;
61 | resize: none;
62 | border: none;
63 | border-radius: 0px;
64 | border-bottom: 1px solid #bfcbd9;
65 | }
66 | }
67 |
68 | //element ui upload
69 | .upload-container {
70 | .el-upload {
71 | width: 100%;
72 |
73 | .el-upload-dragger {
74 | width: 100%;
75 | height: 200px;
76 | }
77 | }
78 | }
79 |
80 | //dropdown
81 | .el-dropdown-menu {
82 | a {
83 | display: block
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/vue-element-admin/src/components/ImageCropper/utils/effectRipple.js:
--------------------------------------------------------------------------------
1 | /**
2 | * 点击波纹效果
3 | *
4 | * @param {[event]} e [description]
5 | * @param {[Object]} arg_opts [description]
6 | * @return {[bollean]} [description]
7 | */
8 | export default function(e, arg_opts) {
9 | var opts = Object.assign({
10 | ele: e.target, // 波纹作用元素
11 | type: 'hit', // hit点击位置扩散center中心点扩展
12 | bgc: 'rgba(0, 0, 0, 0.15)' // 波纹颜色
13 | }, arg_opts)
14 | var target = opts.ele
15 | if (target) {
16 | var rect = target.getBoundingClientRect()
17 | var ripple = target.querySelector('.e-ripple')
18 | if (!ripple) {
19 | ripple = document.createElement('span')
20 | ripple.className = 'e-ripple'
21 | ripple.style.height = ripple.style.width = Math.max(rect.width, rect.height) + 'px'
22 | target.appendChild(ripple)
23 | } else {
24 | ripple.className = 'e-ripple'
25 | }
26 | switch (opts.type) {
27 | case 'center':
28 | ripple.style.top = (rect.height / 2 - ripple.offsetHeight / 2) + 'px'
29 | ripple.style.left = (rect.width / 2 - ripple.offsetWidth / 2) + 'px'
30 | break
31 | default:
32 | ripple.style.top = (e.pageY - rect.top - ripple.offsetHeight / 2 - document.body.scrollTop) + 'px'
33 | ripple.style.left = (e.pageX - rect.left - ripple.offsetWidth / 2 - document.body.scrollLeft) + 'px'
34 | }
35 | ripple.style.backgroundColor = opts.bgc
36 | ripple.className = 'e-ripple z-active'
37 | return false
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/vue-element-admin/src/icons/svg/bug.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/vue-element-admin/src/store/modules/readPapers.js:
--------------------------------------------------------------------------------
1 | import {
2 | classInfo,
3 | getStudent,
4 | getExam,
5 | getScroll
6 | } from '@/api/readPapers'
7 |
8 | const state = {
9 | classArr: [],
10 | studentData: [],
11 | message: {}
12 | }
13 | const mutations = {
14 | CHANGE_CLASS(state, payload) {
15 | state.classArr = payload.data
16 | },
17 | CHANGE_DATA(state, payload) {
18 | if (!payload) {
19 | state.studentData = []
20 | } else {
21 | if (payload.code === 1) {
22 | state.studentData = payload.exam
23 | }
24 | }
25 | },
26 | CHNAGE_MES(state, payload) {
27 | if (!payload) {
28 | state.message = {}
29 | } else {
30 | if (payload.code === 1) {
31 | state.message = payload.data
32 | }
33 | }
34 | }
35 | }
36 | const actions = {
37 | // 获取已经分配教室的班级,得到待批班级的信息
38 | async getExamType({ commit }) {
39 | const getClassInfo = await classInfo()
40 | commit('CHANGE_CLASS', getClassInfo)
41 | },
42 | // 获取学生试卷列表
43 | async getStudentList({ commit }, payload) {
44 | const studentData = await getStudent(payload)
45 | commit('CHANGE_DATA', studentData)
46 | },
47 | // 获取学生试卷信息
48 | async getExamMsg({ commit }, payload) {
49 | const message = await getExam(payload)
50 | commit('CHNAGE_MES', message)
51 | },
52 | // 提交分数
53 | async subScroll({ commit }, payload) {
54 | var res = await getScroll(payload)
55 | return res
56 | }
57 | }
58 |
59 | export default {
60 | namespaced: true,
61 | state,
62 | mutations,
63 | actions
64 | }
65 |
--------------------------------------------------------------------------------
/vue-element-admin/src/api/classes.js:
--------------------------------------------------------------------------------
1 | import request from '@/utils/request'
2 |
3 | // 获取所有班级
4 | export function getAllClass() {
5 | return request({
6 | url: '/manger/grade',
7 | method: 'get'
8 | })
9 | }
10 | // 获取所有教室
11 | export function getAllRoom() {
12 | return request({
13 | url: '/manger/room',
14 | method: 'get'
15 | })
16 | }
17 |
18 | // 获取所有学生
19 | export function getAllStudent() {
20 | return request({
21 | url: '/manger/student',
22 | method: 'get'
23 | })
24 | }
25 |
26 | // 添加教室
27 | export function addRoom(params) {
28 | return request({
29 | url: '/manger/room',
30 | method: 'post',
31 | data: params
32 | })
33 | }
34 |
35 | // 删除教室
36 | export function deleteRoom(params) {
37 | return request({
38 | url: '/manger/room/delete',
39 | method: 'delete',
40 | data: params
41 | })
42 | }
43 |
44 | // 添加班级
45 | export function addGrade(params) {
46 | return request({
47 | url: '/manger/grade',
48 | method: 'post',
49 | data: params
50 | })
51 | }
52 |
53 | // 删除班级
54 | export function deleteGrade(params) {
55 | return request({
56 | url: '/manger/grade/delete',
57 | method: 'delete',
58 | data: params
59 | })
60 | }
61 |
62 | // 更新班级
63 | export function updateGrade(params) {
64 | return request({
65 | url: '/manger/grade/update',
66 | method: 'put',
67 | data: params
68 | })
69 | }
70 |
71 | // 删除学生
72 | export function deleteStudent(params) {
73 | return request({
74 | url: '/manger/student/' + params,
75 | method: 'delete'
76 | })
77 | }
78 |
--------------------------------------------------------------------------------
/vue-element-admin/src/views/dashboard/admin/components/TransactionTable.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {{ scope.row.order_no | orderNoFilter }}
6 |
7 |
8 |
9 |
10 | ¥{{ scope.row.price | toThousandFilter }}
11 |
12 |
13 |
14 |
15 |
16 | {{ row.status }}
17 |
18 |
19 |
20 |
21 |
22 |
23 |
56 |
--------------------------------------------------------------------------------
/vue-element-admin/src/components/SizeSelect/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | {{
9 | item.label }}
10 |
11 |
12 |
13 |
14 |
15 |
58 |
--------------------------------------------------------------------------------
/vue-element-admin/src/layout/components/Sidebar/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
54 |
--------------------------------------------------------------------------------
/vue-element-admin/src/styles/mixin.scss:
--------------------------------------------------------------------------------
1 | @mixin clearfix {
2 | &:after {
3 | content: "";
4 | display: table;
5 | clear: both;
6 | }
7 | }
8 |
9 | @mixin scrollBar {
10 | &::-webkit-scrollbar-track-piece {
11 | background: #d3dce6;
12 | }
13 |
14 | &::-webkit-scrollbar {
15 | width: 6px;
16 | }
17 |
18 | &::-webkit-scrollbar-thumb {
19 | background: #99a9bf;
20 | border-radius: 20px;
21 | }
22 | }
23 |
24 | @mixin relative {
25 | position: relative;
26 | width: 100%;
27 | height: 100%;
28 | }
29 |
30 | @mixin pct($pct) {
31 | width: #{$pct};
32 | position: relative;
33 | margin: 0 auto;
34 | }
35 |
36 | @mixin triangle($width, $height, $color, $direction) {
37 | $width: $width/2;
38 | $color-border-style: $height solid $color;
39 | $transparent-border-style: $width solid transparent;
40 | height: 0;
41 | width: 0;
42 |
43 | @if $direction==up {
44 | border-bottom: $color-border-style;
45 | border-left: $transparent-border-style;
46 | border-right: $transparent-border-style;
47 | }
48 |
49 | @else if $direction==right {
50 | border-left: $color-border-style;
51 | border-top: $transparent-border-style;
52 | border-bottom: $transparent-border-style;
53 | }
54 |
55 | @else if $direction==down {
56 | border-top: $color-border-style;
57 | border-left: $transparent-border-style;
58 | border-right: $transparent-border-style;
59 | }
60 |
61 | @else if $direction==left {
62 | border-right: $color-border-style;
63 | border-top: $transparent-border-style;
64 | border-bottom: $transparent-border-style;
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/vue-element-admin/src/views/clipboard/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | copy
8 |
9 |
10 |
11 |
12 |
13 | copy
14 |
15 |
16 |
17 |
18 |
19 |
20 |
49 |
50 |
--------------------------------------------------------------------------------
/vue-element-admin/src/components/DragSelect/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
50 |
51 |
62 |
--------------------------------------------------------------------------------
/vue-element-admin/src/store/modules/permission.js:
--------------------------------------------------------------------------------
1 | import { asyncRoutes, constantRoutes } from '@/router'
2 |
3 | /**
4 | * 通过meta.role判断是否与当前用户权限匹配
5 | * @param roles
6 | * @param route
7 | */
8 | function hasPermission(view_ids, route) {
9 | if (route.meta && route.meta.view_id) {
10 | return view_ids.some(item => item === route.meta.view_id)
11 | } else {
12 | return true
13 | }
14 | }
15 |
16 | /**
17 | * 递归过滤异步路由表,返回符合用户角色权限的路由表
18 | * @param routes asyncRoutes
19 | * @param roles
20 | */
21 | export function filterAsyncRoutes(routes, view_ids) {
22 | const res = []
23 |
24 | routes.forEach(route => {
25 | const tmp = { ...route }
26 | if (hasPermission(view_ids, tmp)) {
27 | if (tmp.children) {
28 | tmp.children = filterAsyncRoutes(tmp.children, view_ids)
29 | }
30 | res.push(tmp)
31 | }
32 | })
33 | return res
34 | }
35 |
36 | const state = {
37 | routes: [],
38 | addRoutes: []
39 | }
40 |
41 | const mutations = {
42 | SET_ROUTES: (state, routes) => {
43 | state.addRoutes = routes
44 | state.routes = constantRoutes.concat(routes)
45 | }
46 | }
47 |
48 | const actions = {
49 | async generateRoutes({ commit }, view_authority) {
50 | // 获取用户所拥有的view_ids
51 | const view_ids = view_authority.map(item => item.view_id)
52 | // 在动态路由里过滤一遍,得到用户能访问的路由
53 | const accessedRoutes = filterAsyncRoutes(asyncRoutes, view_ids)
54 | console.log('可访问的路由', accessedRoutes)
55 | // 更新路由
56 | commit('SET_ROUTES', accessedRoutes)
57 | return accessedRoutes
58 | }
59 | }
60 |
61 | export default {
62 | namespaced: true,
63 | state,
64 | mutations,
65 | actions
66 | }
67 |
--------------------------------------------------------------------------------
/vue-element-admin/src/views/headImage/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 修改头像
6 |
7 |
18 |
19 |
20 |
59 |
--------------------------------------------------------------------------------
/vue-element-admin/src/views/components-demo/jsonEditor.vue:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
14 |
29 |
30 |
36 |
37 |
--------------------------------------------------------------------------------
/vue-element-admin/src/icons/svg/pdf.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/vue-element-admin/src/api/addQuestion.js:
--------------------------------------------------------------------------------
1 | import request from '@/utils/request'
2 | // 获取当前用户信息
3 | export function getUserInfo() {
4 | return request({
5 | url: '/user/userInfo',
6 | method: 'get'
7 | })
8 | }
9 | // 获取考试类型
10 | export function getType() {
11 | return request({
12 | url: '/exam/examType',
13 | method: 'get'
14 | })
15 | }
16 | // 获取所有的课程
17 | export function getSubject() {
18 | return request({
19 | url: '/exam/subject',
20 | method: 'get'
21 | })
22 | }
23 | // 获取所有的试题类型
24 | export function getQuestionsType() {
25 | return request({
26 | url: '/exam/getQuestionsType',
27 | method: 'get'
28 | })
29 | }
30 | // 添加试题类型
31 | export function getAddType(params) {
32 | return request({
33 | url: '/exam/insertQuestionsType',
34 | method: 'get',
35 | params
36 | })
37 | }
38 | // 删除指定试题类型
39 | export function delAddType(params) {
40 | return request({
41 | url: '/exam/delQuestionsType',
42 | method: 'post',
43 | data: params
44 | })
45 | }
46 | // 添加试题
47 | export function addQuestion(data) {
48 | return request({
49 | url: '/exam/questions',
50 | method: 'post',
51 | data
52 | })
53 | }
54 | // 更新试题
55 | export function updataQuestion(data) {
56 | return request({
57 | url: '/exam/questions/update',
58 | method: 'put',
59 | data
60 | })
61 | }
62 | // 获取所有的试题
63 | export function allExam(params) {
64 | return request({
65 | url: '/exam/questions/new',
66 | method: 'get',
67 | params
68 | })
69 | }
70 |
71 | // 获取所有的试题
72 | export function searchExam(params) {
73 | return request({
74 | url: '/exam/questions/condition',
75 | method: 'get',
76 | params
77 | })
78 | }
79 |
--------------------------------------------------------------------------------
/vue-element-admin/src/filters/index.js:
--------------------------------------------------------------------------------
1 | // set function parseTime,formatTime to filter
2 | export { parseTime, formatTime } from '@/utils'
3 |
4 | /**
5 | * Show plural label if time is plural number
6 | * @param {number} time
7 | * @param {string} label
8 | * @return {string}
9 | */
10 | function pluralize(time, label) {
11 | if (time === 1) {
12 | return time + label
13 | }
14 | return time + label + 's'
15 | }
16 |
17 | /**
18 | * @param {number} time
19 | */
20 | export function timeAgo(time) {
21 | const between = Date.now() / 1000 - Number(time)
22 | if (between < 3600) {
23 | return pluralize(~~(between / 60), ' minute')
24 | } else if (between < 86400) {
25 | return pluralize(~~(between / 3600), ' hour')
26 | } else {
27 | return pluralize(~~(between / 86400), ' day')
28 | }
29 | }
30 |
31 | /**
32 | * Number formatting
33 | * like 10000 => 10k
34 | * @param {number} num
35 | * @param {number} digits
36 | */
37 | export function numberFormatter(num, digits) {
38 | const si = [
39 | { value: 1E18, symbol: 'E' },
40 | { value: 1E15, symbol: 'P' },
41 | { value: 1E12, symbol: 'T' },
42 | { value: 1E9, symbol: 'G' },
43 | { value: 1E6, symbol: 'M' },
44 | { value: 1E3, symbol: 'k' }
45 | ]
46 | for (let i = 0; i < si.length; i++) {
47 | if (num >= si[i].value) {
48 | return (num / si[i].value + 0.1).toFixed(digits).replace(/\.0+$|(\.[0-9]*[1-9])0+$/, '$1') + si[i].symbol
49 | }
50 | }
51 | return num.toString()
52 | }
53 |
54 | /**
55 | * 10000 => "10,000"
56 | * @param {number} num
57 | */
58 | export function toThousandFilter(num) {
59 | return (+num || 0).toString().replace(/^-?\d+/g, m => m.replace(/(?=(?!\b)(\d{3})+$)/g, ','))
60 | }
61 |
--------------------------------------------------------------------------------
/vue-element-admin/src/views/components-demo/dragKanban.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
39 |
66 |
67 |
--------------------------------------------------------------------------------
/vue-element-admin/src/views/i18n-demo/local.js:
--------------------------------------------------------------------------------
1 |
2 | export default {
3 | zh: {
4 | i18nView: {
5 | title: '切换语言',
6 | note: '本项目国际化基于 vue-i18n',
7 | datePlaceholder: '请选择日期',
8 | selectPlaceholder: '请选择',
9 | tableDate: '日期',
10 | tableName: '姓名',
11 | tableAddress: '地址',
12 | default: '默认按钮',
13 | primary: '主要按钮',
14 | success: '成功按钮',
15 | info: '信息按钮',
16 | warning: '警告按钮',
17 | danger: '危险按钮',
18 | one: '一',
19 | two: '二',
20 | three: '三'
21 | }
22 | },
23 | en: {
24 | i18nView: {
25 | title: 'Switch Language',
26 | note: 'The internationalization of this project is based on vue-i18n',
27 | datePlaceholder: 'Pick a day',
28 | selectPlaceholder: 'Select',
29 | tableDate: 'tableDate',
30 | tableName: 'tableName',
31 | tableAddress: 'tableAddress',
32 | default: 'default:',
33 | primary: 'primary',
34 | success: 'success',
35 | info: 'info',
36 | warning: 'warning',
37 | danger: 'danger',
38 | one: 'One',
39 | two: 'Two',
40 | three: 'Three'
41 | }
42 | },
43 | es: {
44 | i18nView: {
45 | title: 'Switch Language',
46 | note: 'The internationalization of this project is based on vue-i18n',
47 | datePlaceholder: 'Pick a day',
48 | selectPlaceholder: 'Select',
49 | tableDate: 'tableDate',
50 | tableName: 'tableName',
51 | tableAddress: 'tableAddress',
52 | default: 'default:',
53 | primary: 'primary',
54 | success: 'success',
55 | info: 'info',
56 | warning: 'warning',
57 | danger: 'danger',
58 | one: 'One',
59 | two: 'Two',
60 | three: 'Three'
61 | }
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/vue-element-admin/src/main.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | // 方便以对象方式操作cookie
3 | import Cookies from 'js-cookie'
4 | // 消除浏览器差异
5 | import 'normalize.css/normalize.css' // A modern alternative to CSS resets
6 | // 引入elemnt-ui
7 | import Element from 'element-ui'
8 | import './styles/element-variables.scss'
9 |
10 | // 引入全局样式
11 | import '@/styles/index.scss' // global css
12 |
13 | // 引入根路由
14 | import App from './App'
15 | // 引入数据管理vuex
16 | import store from './store'
17 | // 引入路由
18 | import router from './router'
19 | // 引入国际化配置
20 | import i18n from './lang' // Internationalization
21 |
22 | import './icons' // icon
23 | // 引入导航守卫
24 | import './permission' // permission control
25 | // 错误处理
26 | import './utils/errorLog' // error log
27 |
28 | // 挂载只定义过滤器
29 | import * as filters from './filters' // global filters
30 | // 挂载mock,拦截请求
31 | // import { mockXHR } from '../mock' // simulation data
32 |
33 | // mock api in github pages site build
34 | // if (process.env.NODE_ENV === 'production') { mockXHR() }
35 |
36 | // if (process.env.NODE_ENV === 'production') { mockXHR() }
37 |
38 | // import { mockXHR } from '../mock' // simulation data
39 |
40 | // mock api in github pages site build
41 | // if (process.env.NODE_ENV === 'production') { mockXHR() }
42 | // 挂载Element
43 | Vue.use(Element, {
44 | size: Cookies.get('size') || 'medium', // set element-ui default size
45 | i18n: (key, value) => i18n.t(key, value)
46 | })
47 |
48 | // 注册全局过滤器
49 | // register global utility filters.
50 | Object.keys(filters).forEach(key => {
51 | Vue.filter(key, filters[key])
52 | })
53 |
54 | // 使用生成环境提示
55 | Vue.config.productionTip = false
56 |
57 | new Vue({
58 | el: '#app',
59 | router,
60 | store,
61 | i18n,
62 | // template: ''
63 | render: h => h(App)
64 | })
65 |
--------------------------------------------------------------------------------
/vue-element-admin/src/views/components-demo/avatarUpload.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
This is based on
4 | vue-image-crop-upload.
5 | {{ $t('components.imageUploadTips') }}
6 |
7 |
8 |
9 |
10 |
11 | Change Avatar
12 |
13 |
14 |
24 |
25 |
26 |
27 |
54 |
55 |
62 |
63 |
--------------------------------------------------------------------------------
/vue-element-admin/src/directive/clipboard/clipboard.js:
--------------------------------------------------------------------------------
1 | // Inspired by https://github.com/Inndy/vue-clipboard2
2 | const Clipboard = require('clipboard')
3 | if (!Clipboard) {
4 | throw new Error('you should npm install `clipboard` --save at first ')
5 | }
6 |
7 | export default {
8 | bind(el, binding) {
9 | if (binding.arg === 'success') {
10 | el._v_clipboard_success = binding.value
11 | } else if (binding.arg === 'error') {
12 | el._v_clipboard_error = binding.value
13 | } else {
14 | const clipboard = new Clipboard(el, {
15 | text() { return binding.value },
16 | action() { return binding.arg === 'cut' ? 'cut' : 'copy' }
17 | })
18 | clipboard.on('success', e => {
19 | const callback = el._v_clipboard_success
20 | callback && callback(e) // eslint-disable-line
21 | })
22 | clipboard.on('error', e => {
23 | const callback = el._v_clipboard_error
24 | callback && callback(e) // eslint-disable-line
25 | })
26 | el._v_clipboard = clipboard
27 | }
28 | },
29 | update(el, binding) {
30 | if (binding.arg === 'success') {
31 | el._v_clipboard_success = binding.value
32 | } else if (binding.arg === 'error') {
33 | el._v_clipboard_error = binding.value
34 | } else {
35 | el._v_clipboard.text = function() { return binding.value }
36 | el._v_clipboard.action = function() { return binding.arg === 'cut' ? 'cut' : 'copy' }
37 | }
38 | },
39 | unbind(el, binding) {
40 | if (binding.arg === 'success') {
41 | delete el._v_clipboard_success
42 | } else if (binding.arg === 'error') {
43 | delete el._v_clipboard_error
44 | } else {
45 | el._v_clipboard.destroy()
46 | delete el._v_clipboard
47 | }
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/vue-element-admin/src/store/modules/classes.js:
--------------------------------------------------------------------------------
1 | import { getAllClass, getAllRoom, getAllStudent, addRoom, deleteRoom, addGrade, deleteGrade, deleteStudent, updateGrade } from '@/api/classes'
2 | const state = {
3 | arr: [],
4 | roomarr: [],
5 | studentarr: [],
6 | roomId: '',
7 | gradeId: ''
8 | }
9 | const mutations = {
10 | updata(state, payload) {
11 | for (var i in payload) {
12 | state[i] = payload[i]
13 | }
14 | }
15 | }
16 | const actions = {
17 | async allClass({ commit }) { // 获取所有班级
18 | const all = await getAllClass()
19 | commit('updata', { arr: all.data })
20 | },
21 | async allRoom({ commit }) { // 获取所有教室
22 | const room = await getAllRoom()
23 | commit('updata', { roomarr: room.data })
24 | },
25 | async allStudent({ commit }) { // 获取所有学生
26 | const obj = await getAllStudent()
27 | commit('updata', { studentarr: obj.data })
28 | },
29 | async allAddroom({ commit }, payload) { // 添加教室
30 | const obj = await addRoom(payload)
31 | commit('updata', { roomId: obj.room_id })
32 | },
33 | async deleteroom({ commit }, payload) { // 删除教室
34 | await deleteRoom(payload)
35 | },
36 | async addgrade({ commit }, payload) { // 添加班级
37 | const obj = await addGrade(payload)
38 | return obj
39 | },
40 | async deletegrade({ commit }, payload) { // 删除班级
41 | const obj = await deleteGrade(payload)
42 | return obj
43 | },
44 | async updategrade({ commit }, payload) { // 更新班级
45 | const obj = await updateGrade(payload)
46 | return obj
47 | },
48 | async deletestudent({ commit }, payload) { // 删除学生
49 | const obj = await deleteStudent(payload)
50 | return obj
51 | }
52 |
53 | }
54 |
55 | export default {
56 | namespaced: true,
57 | state,
58 | mutations,
59 | actions
60 | }
61 |
--------------------------------------------------------------------------------
/vue-element-admin/src/icons/svg/exit-fullscreen.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/vue-element-admin/src/icons/svg/tree.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/vue-element-admin/src/store/modules/app.js:
--------------------------------------------------------------------------------
1 | import Cookies from 'js-cookie'
2 | import { getLanguage } from '@/lang/index'
3 |
4 | const state = {
5 | sidebar: {
6 | opened: Cookies.get('sidebarStatus') ? !!+Cookies.get('sidebarStatus') : true,
7 | withoutAnimation: false
8 | },
9 | device: 'desktop',
10 | language: getLanguage(),
11 | size: Cookies.get('size') || 'medium'
12 | }
13 |
14 | const mutations = {
15 | TOGGLE_SIDEBAR: state => {
16 | state.sidebar.opened = !state.sidebar.opened
17 | state.sidebar.withoutAnimation = false
18 | if (state.sidebar.opened) {
19 | Cookies.set('sidebarStatus', 1)
20 | } else {
21 | Cookies.set('sidebarStatus', 0)
22 | }
23 | },
24 | CLOSE_SIDEBAR: (state, withoutAnimation) => {
25 | Cookies.set('sidebarStatus', 0)
26 | state.sidebar.opened = false
27 | state.sidebar.withoutAnimation = withoutAnimation
28 | },
29 | TOGGLE_DEVICE: (state, device) => {
30 | state.device = device
31 | },
32 | SET_LANGUAGE: (state, language) => {
33 | state.language = language
34 | Cookies.set('language', language)
35 | },
36 | SET_SIZE: (state, size) => {
37 | state.size = size
38 | Cookies.set('size', size)
39 | }
40 | }
41 |
42 | const actions = {
43 | toggleSideBar({ commit }) {
44 | commit('TOGGLE_SIDEBAR')
45 | },
46 | closeSideBar({ commit }, { withoutAnimation }) {
47 | commit('CLOSE_SIDEBAR', withoutAnimation)
48 | },
49 | toggleDevice({ commit }, device) {
50 | commit('TOGGLE_DEVICE', device)
51 | },
52 | setLanguage({ commit }, language) {
53 | commit('SET_LANGUAGE', language)
54 | },
55 | setSize({ commit }, size) {
56 | commit('SET_SIZE', size)
57 | }
58 | }
59 |
60 | export default {
61 | namespaced: true,
62 | state,
63 | mutations,
64 | actions
65 | }
66 |
--------------------------------------------------------------------------------
/vue-element-admin/src/views/components-demo/splitpane.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
SplitPane If you've used
4 | codepen,
5 | jsfiddle will not be unfamiliar.
6 | Github repository
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
39 |
40 |
68 |
--------------------------------------------------------------------------------
/vue-element-admin/mock/user.js:
--------------------------------------------------------------------------------
1 |
2 | const tokens = {
3 | admin: {
4 | token: 'admin-token'
5 | },
6 | editor: {
7 | token: 'editor-token'
8 | }
9 | }
10 |
11 | const users = {
12 | 'admin-token': {
13 | roles: ['admin'],
14 | introduction: 'I am a super administrator',
15 | avatar: 'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif',
16 | name: 'Super Admin'
17 | },
18 | 'editor-token': {
19 | roles: ['editor'],
20 | introduction: 'I am an editor',
21 | avatar: 'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif',
22 | name: 'Normal Editor'
23 | }
24 | }
25 |
26 | export default [
27 | // user login
28 | {
29 | url: '/user/login',
30 | type: 'post',
31 | response: config => {
32 | const { username } = config.body
33 | const token = tokens[username]
34 |
35 | // mock error
36 | if (!token) {
37 | return {
38 | code: 60204,
39 | message: 'Account and password are incorrect.'
40 | }
41 | }
42 |
43 | return {
44 | code: 20000,
45 | data: token
46 | }
47 | }
48 | },
49 |
50 | // get user info
51 | {
52 | url: '/user/info\.*',
53 | type: 'get',
54 | response: config => {
55 | const { token } = config.query
56 | const info = users[token]
57 |
58 | // mock error
59 | if (!info) {
60 | return {
61 | code: 50008,
62 | message: 'Login failed, unable to get user details.'
63 | }
64 | }
65 |
66 | return {
67 | code: 20000,
68 | data: info
69 | }
70 | }
71 | },
72 |
73 | // user logout
74 | {
75 | url: '/user/logout',
76 | type: 'post',
77 | response: _ => {
78 | return {
79 | code: 20000,
80 | data: 'success'
81 | }
82 | }
83 | }
84 | ]
85 |
--------------------------------------------------------------------------------
/vue-element-admin/src/store/modules/examination.js:
--------------------------------------------------------------------------------
1 | import {
2 | typeExam,
3 | getCurriculum,
4 | CreateExam,
5 | getExamList,
6 | getExamDetail,
7 | getTest,
8 | renewal
9 | } from '@/api/examination'
10 |
11 | const state = {
12 | // 获取考试类型.
13 | examType: [],
14 | // 获取课程
15 | curriculum: [],
16 | // 获取试卷列表
17 | paperList: []
18 | }
19 | const mutations = {
20 | // 考试类型
21 | updateTypeExam(state, payload) {
22 | state.examType = payload
23 | },
24 | // 课程
25 | updateCurriculum(state, payload) {
26 | state.curriculum = payload
27 | },
28 | // 试卷列表
29 | updatePaperList(state, payload) {
30 | state.paperList = payload
31 | }
32 | }
33 | const actions = {
34 | // 考试类型
35 | async getExamType({ commit }) {
36 | const getType = await typeExam()
37 | commit('updateTypeExam', getType.data)
38 | },
39 | // 获取所有课程
40 | async getCurriculums({ commit }) {
41 | const curriculums = await getCurriculum()
42 | commit('updateCurriculum', curriculums.data)
43 | },
44 | // 创建试卷
45 | async createTestPaper({ commit }, payload) {
46 | const create = await CreateExam(payload)
47 | return create.data
48 | },
49 | // 获取试卷列表
50 | async getPaperList({ commit }) {
51 | const paper = await getExamList()
52 | commit('updatePaperList', paper.exam)
53 | },
54 | // 获取试卷详情
55 | async getPaperDetail({ commit }, payload) {
56 | const detail = await getExamDetail(payload)
57 | return detail.data.questions
58 | },
59 | // 获取所有的试题
60 | async getTestList({ commit }) {
61 | const alltest = await getTest()
62 | return alltest.data
63 | },
64 | // 更新试卷
65 | async getRenewal({ commit }, payload) {
66 | const res = await renewal(payload.header, payload.data)
67 | return res
68 | }
69 | }
70 |
71 | export default {
72 | namespaced: true,
73 | state,
74 | mutations,
75 | actions
76 | }
77 |
--------------------------------------------------------------------------------
/vue-element-admin/src/styles/btn.scss:
--------------------------------------------------------------------------------
1 | @import './variables.scss';
2 |
3 | @mixin colorBtn($color) {
4 | background: $color;
5 |
6 | &:hover {
7 | color: $color;
8 |
9 | &:before,
10 | &:after {
11 | background: $color;
12 | }
13 | }
14 | }
15 |
16 | .blue-btn {
17 | @include colorBtn($blue)
18 | }
19 |
20 | .light-blue-btn {
21 | @include colorBtn($light-blue)
22 | }
23 |
24 | .red-btn {
25 | @include colorBtn($red)
26 | }
27 |
28 | .pink-btn {
29 | @include colorBtn($pink)
30 | }
31 |
32 | .green-btn {
33 | @include colorBtn($green)
34 | }
35 |
36 | .tiffany-btn {
37 | @include colorBtn($tiffany)
38 | }
39 |
40 | .yellow-btn {
41 | @include colorBtn($yellow)
42 | }
43 |
44 | .pan-btn {
45 | font-size: 14px;
46 | color: #fff;
47 | padding: 14px 36px;
48 | border-radius: 8px;
49 | border: none;
50 | outline: none;
51 | transition: 600ms ease all;
52 | position: relative;
53 | display: inline-block;
54 |
55 | &:hover {
56 | background: #fff;
57 |
58 | &:before,
59 | &:after {
60 | width: 100%;
61 | transition: 600ms ease all;
62 | }
63 | }
64 |
65 | &:before,
66 | &:after {
67 | content: '';
68 | position: absolute;
69 | top: 0;
70 | right: 0;
71 | height: 2px;
72 | width: 0;
73 | transition: 400ms ease all;
74 | }
75 |
76 | &::after {
77 | right: inherit;
78 | top: inherit;
79 | left: 0;
80 | bottom: 0;
81 | }
82 | }
83 |
84 | .custom-button {
85 | display: inline-block;
86 | line-height: 1;
87 | white-space: nowrap;
88 | cursor: pointer;
89 | background: #fff;
90 | color: #fff;
91 | -webkit-appearance: none;
92 | text-align: center;
93 | box-sizing: border-box;
94 | outline: 0;
95 | margin: 0;
96 | padding: 10px 15px;
97 | font-size: 14px;
98 | border-radius: 4px;
99 | }
100 |
--------------------------------------------------------------------------------
/vue-element-admin/src/components/JsonEditor/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
56 |
57 |
73 |
--------------------------------------------------------------------------------
/vue-element-admin/src/views/table/dynamicTable/fixedThead.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | apple
7 |
8 |
9 | banana
10 |
11 |
12 | orange
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | {{ scope.row[fruit] }}
22 |
23 |
24 |
25 |
26 |
27 |
28 |
62 |
63 |
--------------------------------------------------------------------------------
/vue-element-admin/mock/mock-server.js:
--------------------------------------------------------------------------------
1 | const chokidar = require('chokidar')
2 | const bodyParser = require('body-parser')
3 | const chalk = require('chalk')
4 |
5 | function registerRoutes(app) {
6 | let mockLastIndex
7 | const { default: mocks } = require('./index.js')
8 | for (const mock of mocks) {
9 | app[mock.type](mock.url, mock.response)
10 | mockLastIndex = app._router.stack.length
11 | }
12 | const mockRoutesLength = Object.keys(mocks).length
13 | return {
14 | mockRoutesLength: mockRoutesLength,
15 | mockStartIndex: mockLastIndex - mockRoutesLength
16 | }
17 | }
18 |
19 | function unregisterRoutes() {
20 | Object.keys(require.cache).forEach(i => {
21 | if (i.includes('/mock')) {
22 | delete require.cache[require.resolve(i)]
23 | }
24 | })
25 | }
26 |
27 | module.exports = app => {
28 | // es6 polyfill
29 | require('@babel/register')
30 |
31 | // parse app.body
32 | // https://expressjs.com/en/4x/api.html#req.body
33 | app.use(bodyParser.json())
34 | app.use(bodyParser.urlencoded({
35 | extended: true
36 | }))
37 |
38 | const mockRoutes = registerRoutes(app)
39 | var mockRoutesLength = mockRoutes.mockRoutesLength
40 | var mockStartIndex = mockRoutes.mockStartIndex
41 |
42 | // watch files, hot reload mock server
43 | chokidar.watch(('./mock'), {
44 | ignored: 'mock/mock-server.js',
45 | persistent: true,
46 | ignoreInitial: true
47 | }).on('all', (event, path) => {
48 | if (event === 'change' || event === 'add') {
49 | // remove mock routes stack
50 | app._router.stack.splice(mockStartIndex, mockRoutesLength)
51 |
52 | // clear routes cache
53 | unregisterRoutes()
54 |
55 | const mockRoutes = registerRoutes(app)
56 | mockRoutesLength = mockRoutes.mockRoutesLength
57 | mockStartIndex = mockRoutes.mockStartIndex
58 |
59 | console.log(chalk.magentaBright(`\n > Mock Server hot reload success! changed ${path}`))
60 | }
61 | })
62 | }
63 |
--------------------------------------------------------------------------------
/vue-element-admin/src/utils/scrollTo.js:
--------------------------------------------------------------------------------
1 | Math.easeInOutQuad = function(t, b, c, d) {
2 | t /= d / 2
3 | if (t < 1) {
4 | return c / 2 * t * t + b
5 | }
6 | t--
7 | return -c / 2 * (t * (t - 2) - 1) + b
8 | }
9 |
10 | // requestAnimationFrame for Smart Animating http://goo.gl/sx5sts
11 | var requestAnimFrame = (function() {
12 | return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || function(callback) { window.setTimeout(callback, 1000 / 60) }
13 | })()
14 |
15 | /**
16 | * Because it's so fucking difficult to detect the scrolling element, just move them all
17 | * @param {number} amount
18 | */
19 | function move(amount) {
20 | document.documentElement.scrollTop = amount
21 | document.body.parentNode.scrollTop = amount
22 | document.body.scrollTop = amount
23 | }
24 |
25 | function position() {
26 | return document.documentElement.scrollTop || document.body.parentNode.scrollTop || document.body.scrollTop
27 | }
28 |
29 | /**
30 | * @param {number} to
31 | * @param {number} duration
32 | * @param {Function} callback
33 | */
34 | export function scrollTo(to, duration, callback) {
35 | const start = position()
36 | const change = to - start
37 | const increment = 20
38 | let currentTime = 0
39 | duration = (typeof (duration) === 'undefined') ? 500 : duration
40 | var animateScroll = function() {
41 | // increment the time
42 | currentTime += increment
43 | // find the value with the quadratic in-out easing function
44 | var val = Math.easeInOutQuad(currentTime, start, change, duration)
45 | // move the document.body
46 | move(val)
47 | // do the animation unless its over
48 | if (currentTime < duration) {
49 | requestAnimFrame(animateScroll)
50 | } else {
51 | if (callback && typeof (callback) === 'function') {
52 | // the animation is done so lets callback
53 | callback()
54 | }
55 | }
56 | }
57 | animateScroll()
58 | }
59 |
--------------------------------------------------------------------------------
/vue-element-admin/src/views/dashboard/admin/components/TodoList/Todo.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
13 |
22 |
23 |
24 |
25 |
82 |
--------------------------------------------------------------------------------
/vue-element-admin/src/components/GithubCorner/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
23 |
24 |
25 |
26 |
55 |
--------------------------------------------------------------------------------
/vue-element-admin/src/views/documentation/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
31 |
32 |
50 |
--------------------------------------------------------------------------------
/vue-element-admin/src/router/modules/nested.js:
--------------------------------------------------------------------------------
1 | /** When your routing table is too long, you can split it into small modules**/
2 |
3 | import Layout from '@/layout'
4 |
5 | const nestedRouter = {
6 | path: '/nested',
7 | component: Layout,
8 | redirect: '/nested/menu1/menu1-1',
9 | name: 'Nested',
10 | meta: {
11 | title: 'nested',
12 | icon: 'nested'
13 | },
14 | children: [
15 | {
16 | path: 'menu1',
17 | component: () => import('@/views/nested/menu1/index'), // Parent router-view
18 | name: 'Menu1',
19 | meta: { title: 'menu1' },
20 | redirect: '/nested/menu1/menu1-1',
21 | children: [
22 | {
23 | path: 'menu1-1',
24 | component: () => import('@/views/nested/menu1/menu1-1'),
25 | name: 'Menu1-1',
26 | meta: { title: 'menu1-1' }
27 | },
28 | {
29 | path: 'menu1-2',
30 | component: () => import('@/views/nested/menu1/menu1-2'),
31 | name: 'Menu1-2',
32 | redirect: '/nested/menu1/menu1-2/menu1-2-1',
33 | meta: { title: 'menu1-2' },
34 | children: [
35 | {
36 | path: 'menu1-2-1',
37 | component: () => import('@/views/nested/menu1/menu1-2/menu1-2-1'),
38 | name: 'Menu1-2-1',
39 | meta: { title: 'menu1-2-1' }
40 | },
41 | {
42 | path: 'menu1-2-2',
43 | component: () => import('@/views/nested/menu1/menu1-2/menu1-2-2'),
44 | name: 'Menu1-2-2',
45 | meta: { title: 'menu1-2-2' }
46 | }
47 | ]
48 | },
49 | {
50 | path: 'menu1-3',
51 | component: () => import('@/views/nested/menu1/menu1-3'),
52 | name: 'Menu1-3',
53 | meta: { title: 'menu1-3' }
54 | }
55 | ]
56 | },
57 | {
58 | path: 'menu2',
59 | name: 'Menu2',
60 | component: () => import('@/views/nested/menu2/index'),
61 | meta: { title: 'menu2' }
62 | }
63 | ]
64 | }
65 |
66 | export default nestedRouter
67 |
--------------------------------------------------------------------------------