├── static
├── .gitkeep
├── favicon.ico
└── tinymce
│ ├── skins
│ └── lightgray
│ │ ├── img
│ │ ├── trans.gif
│ │ ├── anchor.gif
│ │ ├── loader.gif
│ │ └── object.gif
│ │ ├── fonts
│ │ ├── tinymce.eot
│ │ ├── tinymce.ttf
│ │ ├── tinymce.woff
│ │ ├── tinymce-small.eot
│ │ ├── tinymce-small.ttf
│ │ ├── tinymce-mobile.woff
│ │ └── tinymce-small.woff
│ │ ├── content.mobile.min.css
│ │ ├── content.inline.min.css
│ │ └── content.min.css
│ └── zh_CN.js
├── .eslintignore
├── favicon.ico
├── src
├── styles
│ ├── variables.scss
│ ├── mixin.scss
│ ├── element-ui.scss
│ ├── transition.scss
│ ├── index.scss
│ └── sidebar.scss
├── assets
│ └── 404_images
│ │ ├── 404.png
│ │ └── 404_cloud.png
├── views
│ ├── layout
│ │ ├── components
│ │ │ ├── index.js
│ │ │ ├── Sidebar
│ │ │ │ ├── Item.vue
│ │ │ │ ├── Link.vue
│ │ │ │ ├── index.vue
│ │ │ │ └── SidebarItem.vue
│ │ │ ├── AppMain.vue
│ │ │ ├── Navbar.vue
│ │ │ └── TagsView.vue
│ │ ├── mixin
│ │ │ └── ResizeHandler.js
│ │ └── Layout.vue
│ ├── redirect.vue
│ ├── dashboard
│ │ └── index.vue
│ ├── myviews
│ │ ├── tinymce_demo.vue
│ │ ├── printdemo.vue
│ │ └── demoadmin.vue
│ ├── 404.vue
│ ├── userinfo
│ │ └── index.vue
│ ├── login
│ │ └── index.vue
│ └── system
│ │ └── user.vue
├── icons
│ ├── svg
│ │ ├── link.svg
│ │ ├── user.svg
│ │ ├── example.svg
│ │ ├── table.svg
│ │ ├── password.svg
│ │ ├── nested.svg
│ │ ├── eye.svg
│ │ ├── eye_show.svg
│ │ ├── code.svg
│ │ ├── tree.svg
│ │ ├── dashboard.svg
│ │ └── form.svg
│ ├── index.js
│ └── svgo.yml
├── utils
│ ├── auth.js
│ ├── routerStr.js
│ ├── validate.js
│ ├── index.js
│ ├── directives.js
│ ├── generateCode.js
│ └── request.js
├── store
│ ├── index.js
│ ├── getters.js
│ └── modules
│ │ ├── app.js
│ │ ├── user.js
│ │ └── tagsView.js
├── api
│ ├── login.js
│ ├── export.js
│ └── myapi.js
├── main.js
├── components
│ ├── SvgIcon
│ │ └── index.vue
│ ├── SearchField
│ │ ├── index.vue
│ │ └── index2.vue
│ ├── ScrollPane
│ │ └── index.vue
│ ├── Breadcrumb
│ │ └── index.vue
│ ├── Hamburger
│ │ └── index.vue
│ ├── Pagination
│ │ └── index.vue
│ ├── Upload
│ │ ├── singleImage.vue
│ │ ├── singleFile.vue
│ │ ├── multiImage.vue
│ │ ├── cropperImage.vue
│ │ └── mulImage.vue
│ ├── MiniPagination
│ │ └── index.vue
│ ├── Tinymce
│ │ └── index.vue
│ ├── IdentifyCode
│ │ └── index.vue
│ └── DataSelect
│ │ └── index.vue
├── App.vue
├── permission.js
└── router
│ └── index.js
├── .travis.yml
├── config
├── prod.env.js
├── dev.env.js
├── export.js
└── index.js
├── .gitignore
├── .babelrc
├── .postcssrc.js
├── push.sh
├── .editorconfig
├── index.html
├── README.md
├── LICENSE
├── package.json
└── .eslintrc.js
/static/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | build/*.js
2 | config/*.js
3 | src/assets
4 |
--------------------------------------------------------------------------------
/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aeasringnar/vue-element-admin/HEAD/favicon.ico
--------------------------------------------------------------------------------
/static/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aeasringnar/vue-element-admin/HEAD/static/favicon.ico
--------------------------------------------------------------------------------
/src/styles/variables.scss:
--------------------------------------------------------------------------------
1 | //sidebar
2 | $menuBg:#304156;
3 | $subMenuBg:#1f2d3d;
4 | $menuHover:#001528;
5 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js: stable
3 | script: npm run test
4 | notifications:
5 | email: false
6 |
--------------------------------------------------------------------------------
/src/assets/404_images/404.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aeasringnar/vue-element-admin/HEAD/src/assets/404_images/404.png
--------------------------------------------------------------------------------
/config/prod.env.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | module.exports = {
3 | NODE_ENV: '"production"',
4 | BASE_API: '"https://api.line.com"',
5 | }
6 |
--------------------------------------------------------------------------------
/src/assets/404_images/404_cloud.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aeasringnar/vue-element-admin/HEAD/src/assets/404_images/404_cloud.png
--------------------------------------------------------------------------------
/static/tinymce/skins/lightgray/img/trans.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aeasringnar/vue-element-admin/HEAD/static/tinymce/skins/lightgray/img/trans.gif
--------------------------------------------------------------------------------
/static/tinymce/skins/lightgray/img/anchor.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aeasringnar/vue-element-admin/HEAD/static/tinymce/skins/lightgray/img/anchor.gif
--------------------------------------------------------------------------------
/static/tinymce/skins/lightgray/img/loader.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aeasringnar/vue-element-admin/HEAD/static/tinymce/skins/lightgray/img/loader.gif
--------------------------------------------------------------------------------
/static/tinymce/skins/lightgray/img/object.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aeasringnar/vue-element-admin/HEAD/static/tinymce/skins/lightgray/img/object.gif
--------------------------------------------------------------------------------
/static/tinymce/skins/lightgray/fonts/tinymce.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aeasringnar/vue-element-admin/HEAD/static/tinymce/skins/lightgray/fonts/tinymce.eot
--------------------------------------------------------------------------------
/static/tinymce/skins/lightgray/fonts/tinymce.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aeasringnar/vue-element-admin/HEAD/static/tinymce/skins/lightgray/fonts/tinymce.ttf
--------------------------------------------------------------------------------
/static/tinymce/skins/lightgray/fonts/tinymce.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aeasringnar/vue-element-admin/HEAD/static/tinymce/skins/lightgray/fonts/tinymce.woff
--------------------------------------------------------------------------------
/static/tinymce/skins/lightgray/fonts/tinymce-small.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aeasringnar/vue-element-admin/HEAD/static/tinymce/skins/lightgray/fonts/tinymce-small.eot
--------------------------------------------------------------------------------
/static/tinymce/skins/lightgray/fonts/tinymce-small.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aeasringnar/vue-element-admin/HEAD/static/tinymce/skins/lightgray/fonts/tinymce-small.ttf
--------------------------------------------------------------------------------
/static/tinymce/skins/lightgray/fonts/tinymce-mobile.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aeasringnar/vue-element-admin/HEAD/static/tinymce/skins/lightgray/fonts/tinymce-mobile.woff
--------------------------------------------------------------------------------
/static/tinymce/skins/lightgray/fonts/tinymce-small.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aeasringnar/vue-element-admin/HEAD/static/tinymce/skins/lightgray/fonts/tinymce-small.woff
--------------------------------------------------------------------------------
/src/views/layout/components/index.js:
--------------------------------------------------------------------------------
1 | export { default as Navbar } from './Navbar'
2 | export { default as Sidebar } from './Sidebar'
3 | export { default as AppMain } from './AppMain'
4 | export { default as TagsView } from './TagsView'
5 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules/
3 | dist/
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | package-lock.json
8 |
9 | # Editor directories and files
10 | .idea
11 | .vscode
12 | *.suo
13 | *.ntvs*
14 | *.njsproj
15 | *.sln
16 |
--------------------------------------------------------------------------------
/static/tinymce/skins/lightgray/content.mobile.min.css:
--------------------------------------------------------------------------------
1 | .tinymce-mobile-unfocused-selections .tinymce-mobile-unfocused-selection{position:absolute;display:inline-block;background-color:green;opacity:.5}body{-webkit-text-size-adjust:none}body img{max-width:96vw}body table img{max-width:95%}
--------------------------------------------------------------------------------
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [
3 | ["env", {
4 | "modules": false,
5 | "targets": {
6 | "browsers": ["> 1%", "last 2 versions", "not ie <= 8"]
7 | }
8 | }],
9 | "stage-2"
10 | ],
11 | "plugins":["transform-vue-jsx", "transform-runtime"]
12 | }
13 |
--------------------------------------------------------------------------------
/config/dev.env.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | const merge = require('webpack-merge')
3 | const prodEnv = require('./prod.env')
4 |
5 | module.exports = merge(prodEnv, {
6 | NODE_ENV: '"development"',
7 | BASE_API: '"http://127.0.0.1:9000"',
8 | // BASE_API: '"https://btapi.ibeatop.com"',
9 | })
10 |
--------------------------------------------------------------------------------
/.postcssrc.js:
--------------------------------------------------------------------------------
1 | // https://github.com/michael-ciniawsky/postcss-load-config
2 |
3 | module.exports = {
4 | "plugins": {
5 | "postcss-import": {},
6 | "postcss-url": {},
7 | // to edit target browsers: use "browserslist" field in package.json
8 | "autoprefixer": {}
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/push.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash
2 | proj_dir="demo"
3 | server="127.0.0.1"
4 | npm run build
5 | ssh root@${server} "[[ ! -d /var/www/${proj_dir}/ ]] && mkdir -p /var/www/${proj_dir}/"
6 | ssh root@${server} "[[ -d /var/www/${proj_dir}/ ]] && rm -rf /var/www/${proj_dir}/*"
7 | scp -r dist/* root@${server}:/var/www/${proj_dir}/
--------------------------------------------------------------------------------
/src/icons/svg/link.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # http://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 |
--------------------------------------------------------------------------------
/src/views/redirect.vue:
--------------------------------------------------------------------------------
1 |
13 |
--------------------------------------------------------------------------------
/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 requireAll = requireContext => requireContext.keys().map(requireContext)
8 | const req = require.context('./svg', false, /\.svg$/)
9 | requireAll(req)
10 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/src/utils/auth.js:
--------------------------------------------------------------------------------
1 | import Cookies from 'js-cookie'
2 |
3 | const TokenKey = 'Aeas-Manage-Token'
4 |
5 | export function getToken() {
6 | return localStorage.getItem(TokenKey)
7 | }
8 |
9 | export function setToken(token) {
10 | return localStorage.setItem(TokenKey, token)
11 | }
12 |
13 | export function removeToken() {
14 | return localStorage.removeItem(TokenKey)
15 | }
16 |
--------------------------------------------------------------------------------
/src/store/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import Vuex from 'vuex'
3 | import app from './modules/app'
4 | import user from './modules/user'
5 | import getters from './getters'
6 | import tagsView from './modules/tagsView'
7 |
8 | Vue.use(Vuex)
9 |
10 | const store = new Vuex.Store({
11 | modules: {
12 | app,
13 | user,
14 | tagsView
15 | },
16 | getters
17 | })
18 |
19 | export default store
20 |
--------------------------------------------------------------------------------
/src/icons/svg/user.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/api/login.js:
--------------------------------------------------------------------------------
1 | import request from '@/utils/request'
2 |
3 | export function login(data) {
4 | return request({
5 | url: '/adminlogin/',
6 | method: 'post',
7 | data: data
8 | })
9 | }
10 |
11 | export function getInfo() {
12 | return request({
13 | url: '/userinfo/',
14 | method: 'get'
15 | })
16 | }
17 |
18 | export function logout() {
19 | return request({
20 | url: '/logout/',
21 | method: 'post'
22 | })
23 | }
24 |
--------------------------------------------------------------------------------
/src/store/getters.js:
--------------------------------------------------------------------------------
1 | const getters = {
2 | sidebar: state => state.app.sidebar,
3 | device: state => state.app.device,
4 | token: state => state.user.token,
5 | avatar: state => state.user.avatar,
6 | name: state => state.user.name,
7 | roles: state => state.user.roles,
8 | auth_json: state => state.user.auth_json,
9 | user_obj: state => state.user.user_obj,
10 | visitedViews: state => state.tagsView.visitedViews
11 | }
12 | export default getters
13 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | AEAS'S Admin
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/src/icons/svg/example.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # vue-element-admin
2 |
3 | 这是一个 基于 Vue 2.X + element-UI的后台管理项目模板,用于快速构建企业级高性能的后台管理系统。
4 |
5 | ## 技术栈
6 |
7 | - **框架选择**:基于 Vue2.X + element-UI
8 | - **框架特色**:Vue全家桶 vue + vue-cli + vue-router + vuex + axios
9 | - **授权验证**:基于 JWT
10 | - **内置功能**:通用组件、文件下载、动态权限、代码生成、Demo实例等
11 |
12 | ## 快速入门
13 |
14 | 如需进一步了解,参见 [Vue 文档](https://cn.vuejs.org)。
15 |
16 | ### 本地开发
17 |
18 | ```bash
19 | $ npm install
20 | $ npm run dev
21 | ```
22 |
23 | ### 部署
24 |
25 | ```bash
26 | $ npm run build
27 | ```
28 |
29 |
--------------------------------------------------------------------------------
/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 | &::-webkit-scrollbar {
14 | width: 6px;
15 | }
16 | &::-webkit-scrollbar-thumb {
17 | background: #99a9bf;
18 | border-radius: 20px;
19 | }
20 | }
21 |
22 | @mixin relative {
23 | position: relative;
24 | width: 100%;
25 | height: 100%;
26 | }
27 |
28 |
--------------------------------------------------------------------------------
/src/styles/element-ui.scss:
--------------------------------------------------------------------------------
1 | //to reset element-ui default css
2 | .el-upload {
3 | input[type="file"] {
4 | display: none !important;
5 | }
6 | }
7 |
8 | .el-upload__input {
9 | display: none;
10 | }
11 |
12 | //暂时性解决diolag 问题 https://github.com/ElemeFE/element/issues/2461
13 | .el-dialog {
14 | transform: none;
15 | left: 0;
16 | position: relative;
17 | margin: 0 auto;
18 | }
19 |
20 | //element ui upload
21 | .upload-container {
22 | .el-upload {
23 | width: 100%;
24 | .el-upload-dragger {
25 | width: 100%;
26 | height: 200px;
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/icons/svg/table.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/icons/svg/password.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/views/layout/components/Sidebar/Item.vue:
--------------------------------------------------------------------------------
1 |
30 |
--------------------------------------------------------------------------------
/config/export.js:
--------------------------------------------------------------------------------
1 | import axios from 'axios'
2 | import store from '@/store'
3 | export function exportXls(params, url, file_name) {
4 | const new_headers = { 'Authorization': 'bearer ' + store.getters.token }
5 | axios({ url: url,
6 | method: 'get',
7 | headers: new_headers,
8 | params: params,
9 | responseType: 'blob' })
10 | .then(res => {
11 | console.log(res)
12 | const url = window.URL.createObjectURL(new Blob([res.data]))
13 | const link = document.createElement('a')
14 | link.href = url
15 | link.setAttribute('download', file_name)
16 | document.body.appendChild(link)
17 | link.click()
18 | }).catch(res => {
19 | alert(res)
20 | })
21 | }
22 |
--------------------------------------------------------------------------------
/src/api/export.js:
--------------------------------------------------------------------------------
1 | import axios from 'axios'
2 | import store from '@/store'
3 | export function exportXls(params, url, file_name) {
4 | const new_headers = { 'Authorization': 'bearer ' + store.getters.token }
5 | axios({ url: url,
6 | method: 'get',
7 | headers: new_headers,
8 | params: params,
9 | responseType: 'blob' })
10 | .then(res => {
11 | console.log(res)
12 | const url = window.URL.createObjectURL(new Blob([res.data]))
13 | const link = document.createElement('a')
14 | link.href = url
15 | link.setAttribute('download', file_name)
16 | document.body.appendChild(link)
17 | link.click()
18 | }).catch(res => {
19 | alert(res)
20 | })
21 | }
22 |
--------------------------------------------------------------------------------
/src/views/dashboard/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
name:{{ name }}
4 |
roles:{{ role }}
5 |
6 |
7 |
8 |
21 |
22 |
33 |
--------------------------------------------------------------------------------
/src/views/layout/components/AppMain.vue:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
11 |
21 |
22 |
30 |
--------------------------------------------------------------------------------
/src/main.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 |
3 | import 'normalize.css/normalize.css' // A modern alternative to CSS resets
4 |
5 | import ElementUI from 'element-ui'
6 | import 'element-ui/lib/theme-chalk/index.css'
7 | import locale from 'element-ui/lib/locale/lang/zh-CN' // lang i18n
8 |
9 | import '@/styles/index.scss' // global css
10 |
11 | import App from './App'
12 | import router from './router'
13 | import store from './store'
14 |
15 | import '@/icons' // icon
16 | import '@/permission' // permission control
17 | import 'babel-polyfill'
18 | import './utils/directives.js'
19 |
20 | Vue.use(ElementUI, { locale })
21 |
22 | Vue.config.productionTip = false
23 |
24 | new Vue({
25 | el: '#app',
26 | router,
27 | store,
28 | render: h => h(App)
29 | })
30 |
--------------------------------------------------------------------------------
/src/icons/svg/nested.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/views/layout/components/Sidebar/Link.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
40 |
--------------------------------------------------------------------------------
/src/components/SvgIcon/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
34 |
35 |
44 |
--------------------------------------------------------------------------------
/src/utils/routerStr.js:
--------------------------------------------------------------------------------
1 | function creatRouter(obj_list) {
2 | var str = `[`
3 | for(let i in obj_list){
4 | var childPath = ``
5 | for (let j in obj_list[i].childs) {
6 | childPath += `
7 | {
8 | path: '${obj_list[i].childs[j].object_name}',
9 | name: '${obj_list[i].dir_name}_${obj_list[i].childs[j].object_name}',
10 | component: () => import('@/views/${obj_list[i].dir_name}/${obj_list[i].childs[j].object_name}'),
11 | meta: { title: '${obj_list[i].childs[j].object_name_cn}', icon: 'form' }
12 | },`
13 | }
14 | str += `
15 | {
16 | path: '/${obj_list[i].dir_name}',
17 | meta: { title: '${obj_list[i].dir_name_cn}', icon: 'form' },
18 | component: Layout,
19 | children: [
20 | ${childPath}
21 | ]
22 | },`
23 | }
24 | str += `\n]`
25 | return str
26 | }
27 |
28 | module.exports.creatRouter = creatRouter
--------------------------------------------------------------------------------
/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
35 |
--------------------------------------------------------------------------------
/src/styles/transition.scss:
--------------------------------------------------------------------------------
1 | //globl 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 | .fade-transform-enter {
20 | opacity: 0;
21 | transform: translateX(-30px);
22 | }
23 | .fade-transform-leave-to {
24 | opacity: 0;
25 | transform: translateX(30px);
26 | }
27 |
28 | /*fade*/
29 | .breadcrumb-enter-active,
30 | .breadcrumb-leave-active {
31 | transition: all .5s;
32 | }
33 |
34 | .breadcrumb-enter,
35 | .breadcrumb-leave-active {
36 | opacity: 0;
37 | transform: translateX(20px);
38 | }
39 |
40 | .breadcrumb-move {
41 | transition: all .5s;
42 | }
43 |
44 | .breadcrumb-leave-active {
45 | position: absolute;
46 | }
47 |
--------------------------------------------------------------------------------
/src/icons/svg/eye.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/views/layout/components/Sidebar/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
12 |
13 |
14 |
15 |
16 |
17 |
36 |
--------------------------------------------------------------------------------
/src/utils/validate.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by jiachenpan on 16/11/18.
3 | */
4 |
5 | export function isvalidUsername(str) {
6 | const valid_map = ['admin', 'editor']
7 | return valid_map.indexOf(str.trim()) >= 0
8 | }
9 |
10 | /* 合法uri*/
11 | export function validateURL(textval) {
12 | const urlregex = /^(https?|ftp):\/\/([a-zA-Z0-9.-]+(:[a-zA-Z0-9.&%$-]+)*@)*((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(:[0-9]+)*(\/($|[a-zA-Z0-9.,?'\\+&%$#=~_-]+))*$/
13 | return urlregex.test(textval)
14 | }
15 |
16 | /* 小写字母*/
17 | export function validateLowerCase(str) {
18 | const reg = /^[a-z]+$/
19 | return reg.test(str)
20 | }
21 |
22 | /* 大写字母*/
23 | export function validateUpperCase(str) {
24 | const reg = /^[A-Z]+$/
25 | return reg.test(str)
26 | }
27 |
28 | /* 大小写字母*/
29 | export function validatAlphabets(str) {
30 | const reg = /^[A-Za-z]+$/
31 | return reg.test(str)
32 | }
33 |
--------------------------------------------------------------------------------
/src/components/SearchField/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
10 | {{ buttonName }}
11 |
12 |
13 |
14 |
15 |
45 |
46 |
48 |
--------------------------------------------------------------------------------
/src/icons/svg/eye_show.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/api/myapi.js:
--------------------------------------------------------------------------------
1 | import request from '@/utils/request'
2 |
3 | // 上传文件
4 | export function uploadfile(data) {
5 | return request({
6 | url: '/website/uploadfile',
7 | method: 'post',
8 | data: data
9 | })
10 | }
11 |
12 | // 第二版本的异步请求
13 | // get 请求数据
14 | export function GetAjax(url, params) {
15 | return request({
16 | url: url,
17 | method: 'get',
18 | params: params
19 | })
20 | }
21 | // post 提交数据
22 | export function PostAjax(url, data) {
23 | return request({
24 | url: url,
25 | method: 'post',
26 | data: data
27 | })
28 | }
29 | // patch 修改数据
30 | export function PatchAjax(url, data) {
31 | return request({
32 | url: url,
33 | method: 'patch',
34 | data: data
35 | })
36 | }
37 | // put 修改数据
38 | export function PutAjax(url, data) {
39 | return request({
40 | url: url,
41 | method: 'put',
42 | data: data
43 | })
44 | }
45 | // delete 删除数据
46 | export function DeleteAjax(url, data) {
47 | return request({
48 | url: url,
49 | method: 'delete',
50 | data: data
51 | })
52 | }
53 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/src/views/layout/mixin/ResizeHandler.js:
--------------------------------------------------------------------------------
1 | import store from '@/store'
2 |
3 | const { body } = document
4 | const WIDTH = 1024
5 | const RATIO = 3
6 |
7 | export default {
8 | watch: {
9 | $route(route) {
10 | if (this.device === 'mobile' && this.sidebar.opened) {
11 | store.dispatch('CloseSideBar', { withoutAnimation: false })
12 | }
13 | }
14 | },
15 | beforeMount() {
16 | window.addEventListener('resize', this.resizeHandler)
17 | },
18 | mounted() {
19 | const isMobile = this.isMobile()
20 | if (isMobile) {
21 | store.dispatch('ToggleDevice', 'mobile')
22 | store.dispatch('CloseSideBar', { withoutAnimation: true })
23 | }
24 | },
25 | methods: {
26 | isMobile() {
27 | const rect = body.getBoundingClientRect()
28 | return rect.width - RATIO < WIDTH
29 | },
30 | resizeHandler() {
31 | if (!document.hidden) {
32 | const isMobile = this.isMobile()
33 | store.dispatch('ToggleDevice', isMobile ? 'mobile' : 'desktop')
34 |
35 | if (isMobile) {
36 | store.dispatch('CloseSideBar', { withoutAnimation: true })
37 | }
38 | }
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/icons/svg/code.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/store/modules/app.js:
--------------------------------------------------------------------------------
1 | import Cookies from 'js-cookie'
2 |
3 | const app = {
4 | state: {
5 | sidebar: {
6 | opened: !+Cookies.get('sidebarStatus'),
7 | withoutAnimation: false
8 | },
9 | device: 'desktop'
10 | },
11 | mutations: {
12 | TOGGLE_SIDEBAR: state => {
13 | if (state.sidebar.opened) {
14 | Cookies.set('sidebarStatus', 1)
15 | } else {
16 | Cookies.set('sidebarStatus', 0)
17 | }
18 | state.sidebar.opened = !state.sidebar.opened
19 | state.sidebar.withoutAnimation = false
20 | },
21 | CLOSE_SIDEBAR: (state, withoutAnimation) => {
22 | Cookies.set('sidebarStatus', 1)
23 | state.sidebar.opened = false
24 | state.sidebar.withoutAnimation = withoutAnimation
25 | },
26 | TOGGLE_DEVICE: (state, device) => {
27 | state.device = device
28 | }
29 | },
30 | actions: {
31 | ToggleSideBar: ({ commit }) => {
32 | commit('TOGGLE_SIDEBAR')
33 | },
34 | CloseSideBar({ commit }, { withoutAnimation }) {
35 | commit('CLOSE_SIDEBAR', withoutAnimation)
36 | },
37 | ToggleDevice({ commit }, device) {
38 | commit('TOGGLE_DEVICE', device)
39 | }
40 | }
41 | }
42 |
43 | export default app
44 |
--------------------------------------------------------------------------------
/src/components/SearchField/index2.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
11 | {{ buttonName }}
12 |
13 |
14 |
15 |
16 |
53 |
54 |
56 |
--------------------------------------------------------------------------------
/src/permission.js:
--------------------------------------------------------------------------------
1 | import router from './router'
2 | import store from './store'
3 | import NProgress from 'nprogress' // Progress 进度条
4 | import 'nprogress/nprogress.css'// Progress 进度条样式
5 | import { Message } from 'element-ui'
6 | import { getToken } from '@/utils/auth' // 验权
7 |
8 | const whiteList = ['/login'] // 不重定向白名单
9 | router.beforeEach((to, from, next) => {
10 | NProgress.start()
11 | if (getToken()) {
12 | if (to.path === '/login') {
13 | next({ path: '/' })
14 | NProgress.done() // if current page is dashboard will not trigger afterEach hook, so manually handle it
15 | } else {
16 | if (store.getters.name == '') {
17 | store.dispatch('GetInfo').then(res => { // 拉取用户信息
18 | next()
19 | }).catch((err) => {
20 | store.dispatch('FedLogOut').then(() => {
21 | Message.error(err || 'Verification failed, please login again')
22 | next({ path: '/' })
23 | })
24 | })
25 | } else {
26 | next()
27 | }
28 | }
29 | } else {
30 | if (whiteList.indexOf(to.path) !== -1) {
31 | next()
32 | } else {
33 | next(`/login?redirect=${to.path}`) // 否则全部重定向到登录页
34 | NProgress.done()
35 | }
36 | }
37 | })
38 |
39 | router.afterEach(() => {
40 | NProgress.done() // 结束Progress
41 | })
42 |
--------------------------------------------------------------------------------
/src/styles/index.scss:
--------------------------------------------------------------------------------
1 | @import './variables.scss';
2 | @import './mixin.scss';
3 | @import './transition.scss';
4 | @import './element-ui.scss';
5 | @import './sidebar.scss';
6 |
7 | body {
8 | height: 100%;
9 | -moz-osx-font-smoothing: grayscale;
10 | -webkit-font-smoothing: antialiased;
11 | text-rendering: optimizeLegibility;
12 | font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, Arial, sans-serif;
13 | }
14 |
15 | label {
16 | font-weight: 700;
17 | }
18 |
19 | html {
20 | height: 100%;
21 | box-sizing: border-box;
22 | }
23 |
24 | #app{
25 | height: 100%;
26 | }
27 |
28 | *,
29 | *:before,
30 | *:after {
31 | box-sizing: inherit;
32 | }
33 |
34 | a,
35 | a:focus,
36 | a:hover {
37 | cursor: pointer;
38 | color: inherit;
39 | outline: none;
40 | text-decoration: none;
41 | }
42 |
43 | div:focus{
44 | outline: none;
45 | }
46 |
47 | a:focus,
48 | a:active {
49 | outline: none;
50 | }
51 |
52 | a,
53 | a:focus,
54 | a:hover {
55 | cursor: pointer;
56 | color: inherit;
57 | text-decoration: none;
58 | }
59 |
60 | .clearfix {
61 | &:after {
62 | visibility: hidden;
63 | display: block;
64 | font-size: 0;
65 | content: " ";
66 | clear: both;
67 | height: 0;
68 | }
69 | }
70 |
71 | //main-container全局样式
72 | .app-main{
73 | min-height: 100%
74 | }
75 |
76 | .app-container {
77 | padding: 20px;
78 | }
79 |
--------------------------------------------------------------------------------
/src/components/ScrollPane/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
40 |
41 |
57 |
--------------------------------------------------------------------------------
/src/icons/svg/tree.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/views/layout/Layout.vue:
--------------------------------------------------------------------------------
1 |
2 |
11 |
12 |
13 |
49 |
50 |
72 |
--------------------------------------------------------------------------------
/src/utils/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by jiachenpan on 16/11/18.
3 | */
4 |
5 | export function parseTime(time, cFormat) {
6 | if (arguments.length === 0) {
7 | return null
8 | }
9 | const format = cFormat || '{y}-{m}-{d} {h}:{i}:{s}'
10 | let date
11 | if (typeof time === 'object') {
12 | date = time
13 | } else {
14 | if (('' + time).length === 10) time = parseInt(time) * 1000
15 | date = new Date(time)
16 | }
17 | const formatObj = {
18 | y: date.getFullYear(),
19 | m: date.getMonth() + 1,
20 | d: date.getDate(),
21 | h: date.getHours(),
22 | i: date.getMinutes(),
23 | s: date.getSeconds(),
24 | a: date.getDay()
25 | }
26 | const time_str = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => {
27 | let value = formatObj[key]
28 | // Note: getDay() returns 0 on Sunday
29 | if (key === 'a') { return ['日', '一', '二', '三', '四', '五', '六'][value ] }
30 | if (result.length > 0 && value < 10) {
31 | value = '0' + value
32 | }
33 | return value || 0
34 | })
35 | return time_str
36 | }
37 |
38 | export function formatTime(time, option) {
39 | time = +time * 1000
40 | const d = new Date(time)
41 | const now = Date.now()
42 |
43 | const diff = (now - d) / 1000
44 |
45 | if (diff < 30) {
46 | return '刚刚'
47 | } else if (diff < 3600) {
48 | // less 1 hour
49 | return Math.ceil(diff / 60) + '分钟前'
50 | } else if (diff < 3600 * 24) {
51 | return Math.ceil(diff / 3600) + '小时前'
52 | } else if (diff < 3600 * 24 * 2) {
53 | return '1天前'
54 | }
55 | if (option) {
56 | return parseTime(time, option)
57 | } else {
58 | return (
59 | d.getMonth() +
60 | 1 +
61 | '月' +
62 | d.getDate() +
63 | '日' +
64 | d.getHours() +
65 | '时' +
66 | d.getMinutes() +
67 | '分'
68 | )
69 | }
70 | }
71 |
72 | export function isExternal(path) {
73 | return /^(https?:|mailto:|tel:)/.test(path)
74 | }
75 |
--------------------------------------------------------------------------------
/src/components/Breadcrumb/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {{ item.meta.title }}
6 | {{ item.meta.title }}
7 |
8 |
9 |
10 |
11 |
12 |
58 |
59 |
71 |
--------------------------------------------------------------------------------
/src/components/Hamburger/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
26 |
27 |
28 |
29 |
44 |
45 |
59 |
--------------------------------------------------------------------------------
/src/components/Pagination/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
14 |
15 |
16 |
17 |
85 |
86 |
95 |
--------------------------------------------------------------------------------
/src/icons/svg/dashboard.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/components/Upload/singleImage.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
62 |
63 |
92 |
--------------------------------------------------------------------------------
/src/utils/directives.js:
--------------------------------------------------------------------------------
1 |
2 | import Vue from 'vue'
3 |
4 | // v-dialogDrag: 弹窗拖拽
5 | Vue.directive('dialogDrag', {
6 | bind(el, binding, vnode, oldVnode) {
7 | const dialogHeaderEl = el.querySelector('.el-dialog__header')
8 | const dragDom = el.querySelector('.el-dialog')
9 | dialogHeaderEl.style.cursor = 'move'
10 |
11 | // 获取原有属性 ie dom元素.currentStyle 火狐谷歌 window.getComputedStyle(dom元素, null);
12 | const sty = dragDom.currentStyle || window.getComputedStyle(dragDom, null)
13 |
14 | dialogHeaderEl.onmousedown = (e) => {
15 | // 鼠标按下,计算当前元素距离可视区的距离
16 | const disX = e.clientX - dialogHeaderEl.offsetLeft
17 | const disY = e.clientY - dialogHeaderEl.offsetTop
18 |
19 | // 获取到的值带px 正则匹配替换
20 | let styL, styT
21 |
22 | // 注意在ie中 第一次获取到的值为组件自带50% 移动之后赋值为px
23 | if (sty.left.includes('%')) {
24 | styL = +document.body.clientWidth * (+sty.left.replace(/\%/g, '') / 100)
25 | styT = +document.body.clientHeight * (+sty.top.replace(/\%/g, '') / 100)
26 | } else {
27 | styL = +sty.left.replace(/\px/g, '')
28 | styT = +sty.top.replace(/\px/g, '')
29 | }
30 |
31 | document.onmousemove = function(e) {
32 | // 通过事件委托,计算移动的距离
33 | const l = e.clientX - disX
34 | const t = e.clientY - disY
35 |
36 | // 移动当前元素
37 | dragDom.style.left = `${l + styL}px`
38 | dragDom.style.top = `${t + styT}px`
39 |
40 | // 将此时的位置传出去
41 | // binding.value({x:e.pageX,y:e.pageY})
42 | }
43 |
44 | document.onmouseup = function(e) {
45 | document.onmousemove = null
46 | document.onmouseup = null
47 | }
48 | }
49 | }
50 | })
51 |
52 | // v-dialogDragWidth: 弹窗宽度拖大 拖小
53 | Vue.directive('dialogDragWidth', {
54 | bind(el, binding, vnode, oldVnode) {
55 | const dragDom = binding.value.$el.querySelector('.el-dialog')
56 |
57 | el.onmousedown = (e) => {
58 | // 鼠标按下,计算当前元素距离可视区的距离
59 | const disX = e.clientX - el.offsetLeft
60 |
61 | document.onmousemove = function(e) {
62 | e.preventDefault() // 移动时禁用默认事件
63 |
64 | // 通过事件委托,计算移动的距离
65 | const l = e.clientX - disX
66 | dragDom.style.width = `${l}px`
67 | }
68 |
69 | document.onmouseup = function(e) {
70 | document.onmousemove = null
71 | document.onmouseup = null
72 | }
73 | }
74 | }
75 | })
76 |
77 |
--------------------------------------------------------------------------------
/src/icons/svg/form.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/router/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import Router from 'vue-router'
3 | Vue.use(Router)
4 |
5 | /* Layout */
6 | import Layout from '../views/layout/Layout'
7 | export const constantRouterMap = [
8 | { path: '/login', component: () => import('@/views/login/index'), hidden: true },
9 | { path: '/404', component: () => import('@/views/404'), hidden: true },
10 | {
11 | path: '/',
12 | component: Layout,
13 | redirect: '/dashboard',
14 | children: [{
15 | path: 'dashboard',
16 | name: 'Dashboard',
17 | component: () => import('@/views/userinfo/index'),
18 | meta: { title: '个人信息', icon: 'dashboard', noCache: true }
19 | }]
20 | },
21 | {
22 | path: '/demoadmin',
23 | component: Layout,
24 | hidden: true,
25 | children: [
26 | {
27 | path: 'demo',
28 | name: 'demo',
29 | component: () => import('@/views/myviews/demoadmin'),
30 | meta: { title: 'demo admin', icon: 'form' }
31 | }
32 | ]
33 | },
34 | {
35 | path: '/print',
36 | component: Layout,
37 | hidden: true,
38 | children: [
39 | {
40 | path: 'pdemo',
41 | name: 'pdemo',
42 | component: () => import('@/views/myviews/printdemo'),
43 | meta: { title: 'demo print', icon: 'form' }
44 | }
45 | ]
46 | },
47 | {
48 | path: '/tinymceDemo',
49 | component: Layout,
50 | hidden: true,
51 | children: [
52 | {
53 | path: 'tinymce',
54 | name: 'tinymce',
55 | component: () => import('@/views/myviews/tinymce_demo'),
56 | meta: { title: 'Tinymce Demo', icon: 'form' }
57 | }
58 | ]
59 | },
60 | {
61 | path: '/system',
62 | meta: { title: '系统管理', icon: 'form' },
63 | component: Layout,
64 | children: [
65 | {
66 | path: 'user',
67 | name: 'user',
68 | component: () => import('@/views/system/user'),
69 | meta: { title: '用户管理', icon: 'form' }
70 | },
71 | {
72 | path: 'auth',
73 | name: 'auth',
74 | component: () => import('@/views/system/auth'),
75 | meta: { title: '权限管理', icon: 'form' }
76 | },
77 | ]
78 | },
79 | {
80 | path: '/redirect/:path*',
81 | component: () => import('@/views/redirect')
82 | },
83 | { path: '*', redirect: '/404', hidden: true }
84 | ]
85 |
86 | export default new Router({
87 | // mode: 'history', //后端支持可开
88 | scrollBehavior: () => ({ y: 0 }),
89 | routes: constantRouterMap
90 | })
91 |
--------------------------------------------------------------------------------
/src/utils/generateCode.js:
--------------------------------------------------------------------------------
1 | const path = require('path');
2 | const fs = require('fs');
3 | const vueCode = require('./codeStr');
4 | const router = require('./routerStr');
5 | // console.log(__dirname); // 当前文件所在的绝对路径。
6 | // console.log(__filename); // 当前文件的文件名,包括全路径。 __dirname和__filename都是全局对象。
7 |
8 |
9 | // 写入主体
10 | var obj_list = [
11 | {
12 | dir_name:'system',
13 | dir_name_cn:'系统管理',
14 | childs: [
15 | {
16 | object_name:'group',
17 | object_name_cn:'用户组管理',
18 | fields:[
19 | {prop:'id',label:'ID'},
20 | {prop:'group_type',label:'角色类型'},
21 | ]
22 | },
23 | {
24 | object_name:'user',
25 | object_name_cn:'用户管理',
26 | fields:[
27 | {prop:'id',label:'ID'},
28 | {prop:'username',label:'用户名'}
29 | ]
30 | }
31 | ]
32 | },
33 | {
34 | dir_name:'info',
35 | dir_name_cn:'信息管理',
36 | childs: [
37 | {
38 | object_name:'company',
39 | object_name_cn:'公司管理',
40 | fields:[
41 | {prop:'id',label:'ID'},
42 | {prop:'name',label:'公司名称'}
43 | ]
44 | },
45 | {
46 | object_name:'employ',
47 | object_name_cn:'员工管理',
48 | fields:[
49 | {prop:'id',label:'ID'},
50 | {prop:'real_name',label:'员工名称'}
51 | ]
52 | }
53 | ]
54 | }
55 | ]
56 |
57 |
58 | // 写入vue文件的函数
59 | function writeCode(dir_path, data, dir_name) {
60 | const file_path = dir_path + '/' + data.object_name + '.vue'
61 | fs.writeFile(file_path, vueCode.creatCode(data, dir_name), (err) => {
62 | if (err) throw err
63 | console.log('文件:' + String(file_path) + '已被保存...')
64 | })
65 | }
66 |
67 | // 写入路由文件的函数
68 | function writeRouter(file_path, data) {
69 | fs.writeFile(file_path, data, (err) => {
70 | if (err) throw err
71 | console.log('文件:' + String(file_path) + '已被保存...')
72 | })
73 | }
74 |
75 | // 主体函数
76 | function creatCode(obj_list) {
77 | for (let i in obj_list) {
78 | // 创建目录
79 | const base_path = __dirname + '/my_view'
80 | const dir_path = base_path + '/' + obj_list[i].dir_name
81 | const router_path = base_path + '/router.js'
82 | fs.mkdir(dir_path, { recursive: true }, (err) => {
83 | if (err) throw err
84 | for (let j in obj_list[i].childs) {
85 | writeCode(dir_path, obj_list[i].childs[j], obj_list[i].dir_name)
86 | }
87 | writeRouter(router_path, router.creatRouter(obj_list))
88 | })
89 | }
90 | }
91 |
92 | // 运行主体函数
93 | creatCode(obj_list)
94 |
--------------------------------------------------------------------------------
/src/views/layout/components/Navbar.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | {{name}}
8 |
9 |
10 |
11 |
16 |
17 | 登出
18 |
19 |
20 |
21 |
22 |
23 |
24 |
53 |
54 |
96 |
97 |
--------------------------------------------------------------------------------
/src/components/MiniPagination/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
14 |
21 |
22 |
23 |
24 |
96 |
97 |
106 |
--------------------------------------------------------------------------------
/src/utils/request.js:
--------------------------------------------------------------------------------
1 | import axios from 'axios'
2 | import { Message, MessageBox } from 'element-ui'
3 | import store from '../store'
4 | import { getToken } from '@/utils/auth'
5 |
6 | // 创建axios实例
7 | const service = axios.create({
8 | baseURL: process.env.BASE_API, // api 的 base_url
9 | timeout: 30 * 1000 // 请求超时时间
10 | })
11 |
12 | // request拦截器
13 | service.interceptors.request.use(
14 | config => {
15 | if (store.getters.token) {
16 | config.headers['Authorization'] = 'bearer ' + getToken() // 让每个请求携带自定义token 请根据实际情况自行修改
17 | }
18 | return config
19 | },
20 | error => {
21 | // Do something with request error
22 | console.log(error) // for debug
23 | Promise.reject(error)
24 | }
25 | )
26 |
27 | // response 拦截器
28 | service.interceptors.response.use(
29 | response => {
30 | /**
31 | * code为非20000是抛错 可结合自己业务进行修改
32 | */
33 | console.log('response拦截器开始拦截')
34 | console.log(response.data)
35 | console.log('response拦截器结束拦截(会拦截所有response)')
36 | const res = response.data
37 |
38 | if (response.status === 201) {
39 | Message({ showClose: true, message: '创建成功', type: 'success' })
40 | } else if (response.status === 204) {
41 | Message({ showClose: true, message: '删除成功', type: 'success' })
42 | } else if (response.status === 401) {
43 | return Promise.reject('请登陆')
44 | } else if (response.status === 403) {
45 | MessageBox({ showClose: true, message: '您没有权限', type: 'error' })
46 | } else if (response.status === 404) {
47 | MessageBox({ showClose: true, message: '资源不存在', type: 'error' })
48 | } else if (response.status >= 300 && response.status < 400) {
49 | MessageBox({ showClose: true, message: '服务器已迁移', type: 'error' })
50 | } else if (response.status >= 400 && response.status < 500) {
51 | MessageBox({ showClose: true, message: '请求错误', type: 'error' })
52 | } else if (response.status >= 500 && response.status < 600) {
53 | MessageBox({ showClose: true, message: '服务器错误', type: 'error' })
54 | } else if (response.status === 200) {
55 | if (res.errorCode !== 0) {
56 | // MessageBox({ showClose: true, message: res.message, type: 'error' })
57 | Message({
58 | showClose: true,
59 | message: res.message,
60 | type: 'error'
61 | });
62 | } else {
63 | return response.data
64 | }
65 | } else {
66 | // MessageBox({ showClose: true, message: '访问错误', type: 'error' })
67 | Message({
68 | showClose: true,
69 | message: '访问错误',
70 | type: 'error'
71 | });
72 | }
73 | },
74 | error => {
75 | console.log('error:' + error) // for debug
76 | // localStorage.removeItem('Website-Manage-Token')
77 | // return Promise.reject(error)
78 | alert(error)
79 | }
80 | )
81 |
82 | export default service
83 |
--------------------------------------------------------------------------------
/src/components/Tinymce/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "mymanage",
3 | "version": "3.8.0",
4 | "license": "MIT",
5 | "description": "A vue admin template with Element UI & axios & iconfont & permission control & lint",
6 | "author": "Pan ",
7 | "scripts": {
8 | "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
9 | "start": "npm run dev",
10 | "code": "node ./src/utils/generateCode.js",
11 | "build": "node build/build.js",
12 | "build:report": "npm_config_report=true npm run build",
13 | "lint": "eslint --ext .js,.vue src",
14 | "test": "npm run lint",
15 | "svgo": "svgo -f src/icons/svg --config=src/icons/svgo.yml"
16 | },
17 | "dependencies": {
18 | "@tinymce/tinymce-vue": "^1.1.0",
19 | "axios": "0.18.0",
20 | "babel-polyfill": "^6.26.0",
21 | "date-and-time": "^0.6.3",
22 | "element-ui": "2.12.0",
23 | "js-cookie": "2.2.0",
24 | "normalize.css": "7.0.0",
25 | "nprogress": "0.2.0",
26 | "tinymce": "^4.9.5",
27 | "vue": "2.5.17",
28 | "vue-cropper": "^0.4.9",
29 | "vue-router": "3.0.1",
30 | "vuex": "3.0.1"
31 | },
32 | "devDependencies": {
33 | "autoprefixer": "8.5.0",
34 | "babel-core": "6.26.0",
35 | "babel-eslint": "8.2.6",
36 | "babel-helper-vue-jsx-merge-props": "2.0.3",
37 | "babel-loader": "7.1.5",
38 | "babel-plugin-syntax-jsx": "6.18.0",
39 | "babel-plugin-transform-runtime": "6.23.0",
40 | "babel-plugin-transform-vue-jsx": "3.7.0",
41 | "babel-preset-env": "1.7.0",
42 | "babel-preset-stage-2": "6.24.1",
43 | "chalk": "2.4.1",
44 | "copy-webpack-plugin": "4.5.2",
45 | "css-loader": "^1.0.1",
46 | "eslint": "4.19.1",
47 | "eslint-friendly-formatter": "4.0.1",
48 | "eslint-loader": "2.0.0",
49 | "eslint-plugin-vue": "4.7.1",
50 | "eventsource-polyfill": "0.9.6",
51 | "file-loader": "1.1.11",
52 | "friendly-errors-webpack-plugin": "1.7.0",
53 | "html-webpack-plugin": "4.0.0-alpha",
54 | "mini-css-extract-plugin": "0.4.1",
55 | "node-notifier": "5.2.1",
56 | "node-sass": "^4.7.2",
57 | "optimize-css-assets-webpack-plugin": "5.0.0",
58 | "ora": "3.0.0",
59 | "path-to-regexp": "2.4.0",
60 | "portfinder": "1.0.16",
61 | "postcss-import": "12.0.0",
62 | "postcss-loader": "2.1.6",
63 | "postcss-url": "7.3.2",
64 | "rimraf": "2.6.2",
65 | "sass-loader": "7.0.3",
66 | "script-ext-html-webpack-plugin": "2.0.1",
67 | "semver": "5.5.0",
68 | "shelljs": "0.8.2",
69 | "style-loader": "^0.23.1",
70 | "stylus-loader": "^3.0.2",
71 | "svg-sprite-loader": "3.8.0",
72 | "svgo": "1.0.5",
73 | "uglifyjs-webpack-plugin": "1.2.7",
74 | "url-loader": "1.0.1",
75 | "vue-loader": "15.3.0",
76 | "vue-style-loader": "4.1.2",
77 | "vue-template-compiler": "2.5.17",
78 | "webpack": "4.16.5",
79 | "webpack-bundle-analyzer": "2.13.1",
80 | "webpack-cli": "3.1.0",
81 | "webpack-dev-server": "3.1.5",
82 | "webpack-merge": "4.1.4"
83 | },
84 | "engines": {
85 | "node": ">= 6.0.0",
86 | "npm": ">= 3.0.0"
87 | },
88 | "browserslist": [
89 | "> 1%",
90 | "last 2 versions",
91 | "not ie <= 8"
92 | ]
93 | }
94 |
--------------------------------------------------------------------------------
/config/index.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | // Template version: 1.2.6
3 | // see http://vuejs-templates.github.io/webpack for documentation.
4 |
5 | const path = require('path')
6 |
7 | module.exports = {
8 | dev: {
9 | // Paths
10 | assetsSubDirectory: 'static',
11 | assetsPublicPath: '/',
12 | proxyTable: {},
13 |
14 | // Various Dev Server settings
15 | host: '0.0.0.0', // can be overwritten by process.env.HOST
16 | port: 8099, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined
17 | autoOpenBrowser: false,
18 | errorOverlay: true,
19 | notifyOnErrors: false,
20 | poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions-
21 |
22 | // Use Eslint Loader?
23 | // If true, your code will be linted during bundling and
24 | // linting errors and warnings will be shown in the console.
25 | useEslint: true,
26 | // If true, eslint errors and warnings will also be shown in the error overlay
27 | // in the browser.
28 | showEslintErrorsInOverlay: false,
29 |
30 | /**
31 | * Source Maps
32 | */
33 |
34 | // https://webpack.js.org/configuration/devtool/#development
35 | devtool: 'cheap-source-map',
36 |
37 | // CSS Sourcemaps off by default because relative paths are "buggy"
38 | // with this option, according to the CSS-Loader README
39 | // (https://github.com/webpack/css-loader#sourcemaps)
40 | // In our experience, they generally work as expected,
41 | // just be aware of this issue when enabling this option.
42 | cssSourceMap: false
43 | },
44 |
45 | build: {
46 | // Template for index.html
47 | index: path.resolve(__dirname, '../dist/index.html'),
48 |
49 | // Paths
50 | assetsRoot: path.resolve(__dirname, '../dist'),
51 | assetsSubDirectory: 'static',
52 |
53 | /**
54 | * You can set by youself according to actual condition
55 | * You will need to set this if you plan to deploy your site under a sub path,
56 | * for example GitHub pages. If you plan to deploy your site to https://foo.github.io/bar/,
57 | * then assetsPublicPath should be set to "/bar/".
58 | * In most cases please use '/' !!!
59 | */
60 | assetsPublicPath: './',
61 |
62 | /**
63 | * Source Maps
64 | */
65 |
66 | productionSourceMap: false,
67 | // https://webpack.js.org/configuration/devtool/#production
68 | devtool: 'source-map',
69 |
70 | // Gzip off by default as many popular static hosts such as
71 | // Surge or Netlify already gzip all static assets for you.
72 | // Before setting to `true`, make sure to:
73 | // npm install --save-dev compression-webpack-plugin
74 | productionGzip: false,
75 | productionGzipExtensions: ['js', 'css'],
76 |
77 | // Run the build command with an extra argument to
78 | // View the bundle analyzer report after build finishes:
79 | // `npm run build --report`
80 | // Set to `true` or `false` to always turn it on or off
81 | bundleAnalyzerReport: process.env.npm_config_report || false,
82 |
83 | // `npm run build:prod --generate_report`
84 | generateAnalyzerReport: process.env.npm_config_generate_report || false
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/src/components/Upload/singleFile.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
14 | 点击上传
15 | 文件最大不超过64MB
16 |
17 |
18 |
19 |
20 |
107 |
108 |
111 |
--------------------------------------------------------------------------------
/src/views/layout/components/Sidebar/SidebarItem.vue:
--------------------------------------------------------------------------------
1 |
2 |
34 |
35 |
36 |
102 |
--------------------------------------------------------------------------------
/src/styles/sidebar.scss:
--------------------------------------------------------------------------------
1 | #app {
2 | // 主体区域
3 | .main-container {
4 | min-height: 100%;
5 | transition: margin-left .28s;
6 | margin-left: 180px;
7 | position: relative;
8 | }
9 | // 侧边栏
10 | .sidebar-container {
11 | transition: width 0.28s;
12 | width: 180px !important;
13 | height: 100%;
14 | position: fixed;
15 | font-size: 0px;
16 | top: 0;
17 | bottom: 0;
18 | left: 0;
19 | z-index: 1001;
20 | overflow: hidden;
21 | //reset element-ui css
22 | .horizontal-collapse-transition {
23 | transition: 0s width ease-in-out, 0s padding-left ease-in-out, 0s padding-right ease-in-out;
24 | }
25 | .el-scrollbar__bar.is-vertical{
26 | right: 0px;
27 | }
28 | .scrollbar-wrapper {
29 | overflow-x: hidden!important;
30 | .el-scrollbar__view {
31 | height: 100%;
32 | }
33 | }
34 | .is-horizontal {
35 | display: none;
36 | }
37 | a {
38 | display: inline-block;
39 | width: 100%;
40 | overflow: hidden;
41 | }
42 | .svg-icon {
43 | margin-right: 16px;
44 | }
45 | .el-menu {
46 | border: none;
47 | height: 100%;
48 | width: 100% !important;
49 | }
50 | .is-active > .el-submenu__title{
51 | color: #f4f4f5!important;
52 | }
53 | }
54 | .hideSidebar {
55 | .sidebar-container {
56 | width: 36px !important;
57 | }
58 | .main-container {
59 | margin-left: 36px;
60 | }
61 | .submenu-title-noDropdown {
62 | padding-left: 10px !important;
63 | position: relative;
64 | .el-tooltip {
65 | padding: 0 10px !important;
66 | }
67 | }
68 | .el-submenu {
69 | overflow: hidden;
70 | &>.el-submenu__title {
71 | padding-left: 10px !important;
72 | .el-submenu__icon-arrow {
73 | display: none;
74 | }
75 | }
76 | }
77 | .el-menu--collapse {
78 | .el-submenu {
79 | &>.el-submenu__title {
80 | &>span {
81 | height: 0;
82 | width: 0;
83 | overflow: hidden;
84 | visibility: hidden;
85 | display: inline-block;
86 | }
87 | }
88 | }
89 | }
90 | }
91 | .sidebar-container .nest-menu .el-submenu>.el-submenu__title,
92 | .sidebar-container .el-submenu .el-menu-item {
93 | min-width: 180px !important;
94 | background-color: $subMenuBg !important;
95 | &:hover {
96 | background-color: $menuHover !important;
97 | }
98 | }
99 | .el-menu--collapse .el-menu .el-submenu {
100 | min-width: 180px !important;
101 | }
102 |
103 | //适配移动端
104 | .mobile {
105 | .main-container {
106 | margin-left: 0px;
107 | }
108 | .sidebar-container {
109 | transition: transform .28s;
110 | width: 180px !important;
111 | }
112 | &.hideSidebar {
113 | .sidebar-container {
114 | transition-duration: 0.3s;
115 | transform: translate3d(-180px, 0, 0);
116 | }
117 | }
118 | }
119 | .withoutAnimation {
120 | .main-container,
121 | .sidebar-container {
122 | transition: none;
123 | }
124 | }
125 | }
126 |
127 | .el-menu--vertical{
128 | & >.el-menu{
129 | .svg-icon{
130 | margin-right: 16px;
131 | }
132 | }
133 | }
134 |
--------------------------------------------------------------------------------
/static/tinymce/skins/lightgray/content.inline.min.css:
--------------------------------------------------------------------------------
1 | .word-wrap{word-wrap:break-word;-ms-word-break:break-all;word-break:break-all;word-break:break-word;-ms-hyphens:auto;-moz-hyphens:auto;-webkit-hyphens:auto;hyphens:auto}.mce-content-body .mce-reset{margin:0;padding:0;border:0;outline:0;vertical-align:top;background:transparent;text-decoration:none;color:black;font-family:Arial;font-size:11px;text-shadow:none;float:none;position:static;width:auto;height:auto;white-space:nowrap;cursor:inherit;line-height:normal;font-weight:normal;text-align:left;-webkit-tap-highlight-color:transparent;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box;direction:ltr;max-width:none}.mce-object{border:1px dotted #3A3A3A;background:#D5D5D5 url(img/object.gif) no-repeat center}.mce-preview-object{display:inline-block;position:relative;margin:0 2px 0 2px;line-height:0;border:1px solid gray}.mce-preview-object[data-mce-selected="2"] .mce-shim{display:none}.mce-preview-object .mce-shim{position:absolute;top:0;left:0;width:100%;height:100%;background:url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)}figure.align-left{float:left}figure.align-right{float:right}figure.image.align-center{display:table;margin-left:auto;margin-right:auto}figure.image{display:inline-block;border:1px solid gray;margin:0 2px 0 1px;background:#f5f2f0}figure.image img{margin:8px 8px 0 8px}figure.image figcaption{margin:6px 8px 6px 8px;text-align:center}.mce-toc{border:1px solid gray}.mce-toc h2{margin:4px}.mce-toc li{list-style-type:none}.mce-pagebreak{cursor:default;display:block;border:0;width:100%;height:5px;border:1px dashed #666;margin-top:15px;page-break-before:always}@media print{.mce-pagebreak{border:0}}.mce-item-anchor{cursor:default;display:inline-block;-webkit-user-select:all;-webkit-user-modify:read-only;-moz-user-select:all;-moz-user-modify:read-only;user-select:all;user-modify:read-only;width:9px !important;height:9px !important;border:1px dotted #3A3A3A;background:#D5D5D5 url(img/anchor.gif) no-repeat center}.mce-nbsp,.mce-shy{background:#AAA}.mce-shy::after{content:'-'}.mce-match-marker{background:#AAA;color:#fff}.mce-match-marker-selected{background:#3399ff;color:#fff}.mce-spellchecker-word{border-bottom:2px solid rgba(208,2,27,0.5);cursor:default}.mce-spellchecker-grammar{border-bottom:2px solid #008000;cursor:default}.mce-item-table,.mce-item-table td,.mce-item-table th,.mce-item-table caption{border:1px dashed #BBB}td[data-mce-selected],th[data-mce-selected]{background-color:#2276d2 !important}.mce-edit-focus{outline:1px dotted #333}.mce-content-body *[contentEditable=false] *[contentEditable=true]:focus{outline:2px solid #2276d2}.mce-content-body *[contentEditable=false] *[contentEditable=true]:hover{outline:2px solid #2276d2}.mce-content-body *[contentEditable=false][data-mce-selected]{outline:2px solid #2276d2}.mce-content-body.mce-content-readonly *[contentEditable=true]:focus,.mce-content-body.mce-content-readonly *[contentEditable=true]:hover{outline:none}.mce-content-body *[data-mce-selected="inline-boundary"]{background:#bfe6ff}.mce-content-body .mce-item-anchor[data-mce-selected]{background:#D5D5D5 url(img/anchor.gif) no-repeat center}.mce-content-body hr{cursor:default}.mce-content-body table{-webkit-nbsp-mode:normal}.ephox-snooker-resizer-bar{background-color:#2276d2;opacity:0}.ephox-snooker-resizer-cols{cursor:col-resize}.ephox-snooker-resizer-rows{cursor:row-resize}.ephox-snooker-resizer-bar.ephox-snooker-resizer-bar-dragging{opacity:.2}.mce-content-body{line-height:1.3}
--------------------------------------------------------------------------------
/src/components/Upload/multiImage.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
117 |
118 |
121 |
--------------------------------------------------------------------------------
/static/tinymce/skins/lightgray/content.min.css:
--------------------------------------------------------------------------------
1 | body{background-color:#FFFFFF;color:#000000;font-family:Verdana,Arial,Helvetica,sans-serif;font-size:14px;line-height:1.3;scrollbar-3dlight-color:#F0F0EE;scrollbar-arrow-color:#676662;scrollbar-base-color:#F0F0EE;scrollbar-darkshadow-color:#DDDDDD;scrollbar-face-color:#E0E0DD;scrollbar-highlight-color:#F0F0EE;scrollbar-shadow-color:#F0F0EE;scrollbar-track-color:#F5F5F5}td,th{font-family:Verdana,Arial,Helvetica,sans-serif;font-size:14px}.word-wrap{word-wrap:break-word;-ms-word-break:break-all;word-break:break-all;word-break:break-word;-ms-hyphens:auto;-moz-hyphens:auto;-webkit-hyphens:auto;hyphens:auto}.mce-content-body .mce-reset{margin:0;padding:0;border:0;outline:0;vertical-align:top;background:transparent;text-decoration:none;color:black;font-family:Arial;font-size:11px;text-shadow:none;float:none;position:static;width:auto;height:auto;white-space:nowrap;cursor:inherit;line-height:normal;font-weight:normal;text-align:left;-webkit-tap-highlight-color:transparent;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box;direction:ltr;max-width:none}.mce-object{border:1px dotted #3A3A3A;background:#D5D5D5 url(img/object.gif) no-repeat center}.mce-preview-object{display:inline-block;position:relative;margin:0 2px 0 2px;line-height:0;border:1px solid gray}.mce-preview-object[data-mce-selected="2"] .mce-shim{display:none}.mce-preview-object .mce-shim{position:absolute;top:0;left:0;width:100%;height:100%;background:url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)}figure.align-left{float:left}figure.align-right{float:right}figure.image.align-center{display:table;margin-left:auto;margin-right:auto}figure.image{display:inline-block;border:1px solid gray;margin:0 2px 0 1px;background:#f5f2f0}figure.image img{margin:8px 8px 0 8px}figure.image figcaption{margin:6px 8px 6px 8px;text-align:center}.mce-toc{border:1px solid gray}.mce-toc h2{margin:4px}.mce-toc li{list-style-type:none}.mce-pagebreak{cursor:default;display:block;border:0;width:100%;height:5px;border:1px dashed #666;margin-top:15px;page-break-before:always}@media print{.mce-pagebreak{border:0}}.mce-item-anchor{cursor:default;display:inline-block;-webkit-user-select:all;-webkit-user-modify:read-only;-moz-user-select:all;-moz-user-modify:read-only;user-select:all;user-modify:read-only;width:9px !important;height:9px !important;border:1px dotted #3A3A3A;background:#D5D5D5 url(img/anchor.gif) no-repeat center}.mce-nbsp,.mce-shy{background:#AAA}.mce-shy::after{content:'-'}.mce-match-marker{background:#AAA;color:#fff}.mce-match-marker-selected{background:#3399ff;color:#fff}.mce-spellchecker-word{border-bottom:2px solid rgba(208,2,27,0.5);cursor:default}.mce-spellchecker-grammar{border-bottom:2px solid #008000;cursor:default}.mce-item-table,.mce-item-table td,.mce-item-table th,.mce-item-table caption{border:1px dashed #BBB}td[data-mce-selected],th[data-mce-selected]{background-color:#2276d2 !important}.mce-edit-focus{outline:1px dotted #333}.mce-content-body *[contentEditable=false] *[contentEditable=true]:focus{outline:2px solid #2276d2}.mce-content-body *[contentEditable=false] *[contentEditable=true]:hover{outline:2px solid #2276d2}.mce-content-body *[contentEditable=false][data-mce-selected]{outline:2px solid #2276d2}.mce-content-body.mce-content-readonly *[contentEditable=true]:focus,.mce-content-body.mce-content-readonly *[contentEditable=true]:hover{outline:none}.mce-content-body *[data-mce-selected="inline-boundary"]{background:#bfe6ff}.mce-content-body .mce-item-anchor[data-mce-selected]{background:#D5D5D5 url(img/anchor.gif) no-repeat center}.mce-content-body hr{cursor:default}.mce-content-body table{-webkit-nbsp-mode:normal}.ephox-snooker-resizer-bar{background-color:#2276d2;opacity:0}.ephox-snooker-resizer-cols{cursor:col-resize}.ephox-snooker-resizer-rows{cursor:row-resize}.ephox-snooker-resizer-bar.ephox-snooker-resizer-bar-dragging{opacity:.2}
--------------------------------------------------------------------------------
/src/components/IdentifyCode/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/src/views/myviews/tinymce_demo.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
tinymce 富文本编辑器
4 |
5 |
6 |
7 |
8 | 确定
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/src/views/myviews/printdemo.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 打印
6 |
7 |
8 |
9 |
14 |
15 |
小票测试
16 |
电话:17312345601
17 |
* * * * * * * * * * * * * * * * * * * *
18 |
19 |
名称
20 |
数量
21 |
单价
22 |
23 |
24 |
test01
25 |
1
26 |
55
27 |
28 |
29 |
test02
30 |
2
31 |
128
32 |
33 |
- - - - - - - - - - - - - - - - - - - - - -
34 |
35 | 总金额:311
36 |
37 |
38 | 日期:2019-02-28
39 |
40 |
* * * * * * * * * * * * * * * * * * * *
41 |
请妥善保管好购物凭证
42 |
多谢惠顾
43 |
44 |
48 |
49 |
50 |
51 |
52 |
85 |
86 |
--------------------------------------------------------------------------------
/src/components/DataSelect/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
8 |
9 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/src/store/modules/user.js:
--------------------------------------------------------------------------------
1 | import { login, logout, getInfo } from '@/api/login'
2 | import { getToken, setToken, removeToken } from '@/utils/auth'
3 | import router from '../../router'
4 |
5 | function handleRouters(routers, auth_json) {
6 | const whiteList = ['/login', '/404', '/', '*', 'dashboard']
7 | const auth = auth_json
8 | function handleOneRouter(router) {
9 | if (!router.children) {
10 | if (whiteList.indexOf(router.path) === -1) {
11 | if (auth[router.name]) {
12 | if (auth[router.name].auth_list) {
13 | router.hidden = false
14 | } else {
15 | router.hidden = true
16 | }
17 | } else {
18 | router.hidden = true
19 | }
20 | }
21 | return 1
22 | } else {
23 | var count = 1
24 | for (var i in router.children) {
25 | count += handleOneRouter(router.children[i])
26 | if (router.children[i].children) {
27 | var len = router.children[i].children.length
28 | var false_len = 0
29 | for (let j in router.children[i].children) {
30 | if (router.children[i].children[j].hidden) {
31 | false_len++
32 | }
33 | }
34 | if (len === false_len) {
35 | router.children[i].hidden = true
36 | } else {
37 | router.children[i].hidden = false
38 | }
39 | }
40 | }
41 | return count
42 | }
43 | }
44 | var need_handle_routers = { children: routers }
45 | handleOneRouter(need_handle_routers)
46 | return need_handle_routers.children
47 | }
48 |
49 | const user = {
50 | state: {
51 | token: getToken(),
52 | name: '',
53 | avatar: '',
54 | roles: '',
55 | auth_json: {},
56 | routers: router,
57 | user_obj: {}
58 | },
59 |
60 | mutations: {
61 | SET_TOKEN: (state, token) => {
62 | state.token = token
63 | },
64 | SET_USER_OBJ: (state, user_obj) => {
65 | state.user_obj = user_obj
66 | },
67 | SET_NAME: (state, name) => {
68 | state.name = name
69 | },
70 | SET_AVATAR: (state, avatar) => {
71 | state.avatar = avatar
72 | },
73 | SET_ROLES: (state, roles) => {
74 | state.roles = roles
75 | },
76 | SET_AUTHS: (state, auths) => {
77 | var auth_obj = {}
78 | for (let i in auths) {
79 | auth_obj[auths[i].object_name] = {
80 | auth_create: auths[i].auth_create,
81 | auth_list: auths[i].auth_list,
82 | auth_update: auths[i].auth_update,
83 | auth_destroy: auths[i].auth_destroy
84 | }
85 | }
86 | state.auth_json = auth_obj
87 | },
88 | SET_ROUTE: (state, routers) => {
89 | state.routers = routers
90 | }
91 | },
92 |
93 | actions: {
94 | // 登录
95 | Login({ commit }, userInfo) {
96 | return new Promise((resolve, reject) => {
97 | login(userInfo).then(response => {
98 | const data = response.data
99 | setToken(data.token)
100 | commit('SET_TOKEN', data.token)
101 | resolve()
102 | }).catch(error => {
103 | reject(error)
104 | // alert(error)
105 | })
106 | })
107 | },
108 |
109 | // 获取用户信息
110 | GetInfo({ commit, state }) {
111 | return new Promise((resolve, reject) => {
112 | getInfo().then(response => {
113 | const data = response.data
114 | console.log(data)
115 | commit('SET_USER_OBJ', data)
116 | commit('SET_NAME', data.username)
117 | commit('SET_ROLES', data.group.group_type)
118 | commit('SET_AVATAR', data.img_url)
119 | if (data.group.group_type !== 'SuperAdmin') {
120 | commit('SET_AUTHS', data.auth.auth_permissions)
121 | console.log('查看auths:', state.auth_json)
122 | console.log(router.options.routes)
123 | var my_router = handleRouters(router.options.routes, state.auth_json)
124 | console.log(my_router)
125 | router.options.routes = my_router
126 | commit('SET_ROUTE', router)
127 | }
128 | resolve(response)
129 | }).catch(error => {
130 | reject(error)
131 | })
132 | })
133 | },
134 |
135 | // 登出
136 | LogOut({ commit, state }) {
137 | return new Promise((resolve, reject) => {
138 | logout(state.token).then(() => {
139 | commit('SET_TOKEN', '')
140 | commit('SET_ROLES', [])
141 | removeToken()
142 | resolve()
143 | }).catch(error => {
144 | reject(error)
145 | })
146 | })
147 | },
148 |
149 | // 前端 登出
150 | FedLogOut({ commit }) {
151 | return new Promise(resolve => {
152 | commit('SET_TOKEN', '')
153 | router.push({path: '/login'})
154 | removeToken()
155 | resolve()
156 | })
157 | }
158 | }
159 | }
160 |
161 | export default user
162 |
--------------------------------------------------------------------------------
/src/store/modules/tagsView.js:
--------------------------------------------------------------------------------
1 | const tagsView = {
2 | state: {
3 | visitedViews: [],
4 | cachedViews: []
5 | },
6 | mutations: {
7 | ADD_VISITED_VIEW: (state, view) => {
8 | if (state.visitedViews.some(v => v.path === view.path)) return
9 | state.visitedViews.push(
10 | Object.assign({}, view, {
11 | title: view.meta.title || 'no-name'
12 | })
13 | )
14 | },
15 | ADD_CACHED_VIEW: (state, view) => {
16 | if (state.cachedViews.includes(view.name)) return
17 | if (!view.meta.noCache) {
18 | state.cachedViews.push(view.name)
19 | }
20 | },
21 |
22 | DEL_VISITED_VIEW: (state, view) => {
23 | for (const [i, v] of state.visitedViews.entries()) {
24 | if (v.path === view.path) {
25 | state.visitedViews.splice(i, 1)
26 | break
27 | }
28 | }
29 | },
30 | DEL_CACHED_VIEW: (state, view) => {
31 | for (const i of state.cachedViews) {
32 | if (i === view.name) {
33 | const index = state.cachedViews.indexOf(i)
34 | state.cachedViews.splice(index, 1)
35 | break
36 | }
37 | }
38 | },
39 |
40 | DEL_OTHERS_VISITED_VIEWS: (state, view) => {
41 | for (const [i, v] of state.visitedViews.entries()) {
42 | if (v.path === view.path) {
43 | state.visitedViews = state.visitedViews.slice(i, i + 1)
44 | break
45 | }
46 | }
47 | },
48 | DEL_OTHERS_CACHED_VIEWS: (state, view) => {
49 | for (const i of state.cachedViews) {
50 | if (i === view.name) {
51 | const index = state.cachedViews.indexOf(i)
52 | state.cachedViews = state.cachedViews.slice(index, index + 1)
53 | break
54 | }
55 | }
56 | },
57 |
58 | DEL_ALL_VISITED_VIEWS: state => {
59 | state.visitedViews = []
60 | },
61 | DEL_ALL_CACHED_VIEWS: state => {
62 | state.cachedViews = []
63 | },
64 |
65 | UPDATE_VISITED_VIEW: (state, view) => {
66 | for (let v of state.visitedViews) {
67 | if (v.path === view.path) {
68 | v = Object.assign(v, view)
69 | break
70 | }
71 | }
72 | }
73 |
74 | },
75 | actions: {
76 | addView({ dispatch }, view) {
77 | dispatch('addVisitedView', view)
78 | dispatch('addCachedView', view)
79 | },
80 | addVisitedView({ commit }, view) {
81 | commit('ADD_VISITED_VIEW', view)
82 | },
83 | addCachedView({ commit }, view) {
84 | commit('ADD_CACHED_VIEW', view)
85 | },
86 |
87 | delView({ dispatch, state }, view) {
88 | return new Promise(resolve => {
89 | dispatch('delVisitedView', view)
90 | dispatch('delCachedView', view)
91 | resolve({
92 | visitedViews: [...state.visitedViews],
93 | cachedViews: [...state.cachedViews]
94 | })
95 | })
96 | },
97 | delVisitedView({ commit, state }, view) {
98 | return new Promise(resolve => {
99 | commit('DEL_VISITED_VIEW', view)
100 | resolve([...state.visitedViews])
101 | })
102 | },
103 | delCachedView({ commit, state }, view) {
104 | return new Promise(resolve => {
105 | commit('DEL_CACHED_VIEW', view)
106 | resolve([...state.cachedViews])
107 | })
108 | },
109 |
110 | delOthersViews({ dispatch, state }, view) {
111 | return new Promise(resolve => {
112 | dispatch('delOthersVisitedViews', view)
113 | dispatch('delOthersCachedViews', view)
114 | resolve({
115 | visitedViews: [...state.visitedViews],
116 | cachedViews: [...state.cachedViews]
117 | })
118 | })
119 | },
120 | delOthersVisitedViews({ commit, state }, view) {
121 | return new Promise(resolve => {
122 | commit('DEL_OTHERS_VISITED_VIEWS', view)
123 | resolve([...state.visitedViews])
124 | })
125 | },
126 | delOthersCachedViews({ commit, state }, view) {
127 | return new Promise(resolve => {
128 | commit('DEL_OTHERS_CACHED_VIEWS', view)
129 | resolve([...state.cachedViews])
130 | })
131 | },
132 |
133 | delAllViews({ dispatch, state }, view) {
134 | return new Promise(resolve => {
135 | dispatch('delAllVisitedViews', view)
136 | dispatch('delAllCachedViews', view)
137 | resolve({
138 | visitedViews: [...state.visitedViews],
139 | cachedViews: [...state.cachedViews]
140 | })
141 | })
142 | },
143 | delAllVisitedViews({ commit, state }) {
144 | return new Promise(resolve => {
145 | commit('DEL_ALL_VISITED_VIEWS')
146 | resolve([...state.visitedViews])
147 | })
148 | },
149 | delAllCachedViews({ commit, state }) {
150 | return new Promise(resolve => {
151 | commit('DEL_ALL_CACHED_VIEWS')
152 | resolve([...state.cachedViews])
153 | })
154 | },
155 |
156 | updateVisitedView({ commit }, view) {
157 | commit('UPDATE_VISITED_VIEW', view)
158 | }
159 | }
160 | }
161 |
162 | export default tagsView
163 |
--------------------------------------------------------------------------------
/src/components/Upload/cropperImage.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
10 |
11 |
12 |
13 |
14 |
35 |
39 |
40 |
41 |
42 |
43 |
141 |
142 |
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | root: true,
3 | parserOptions: {
4 | parser: 'babel-eslint',
5 | sourceType: 'module'
6 | },
7 | env: {
8 | browser: true,
9 | node: true,
10 | es6: true,
11 | },
12 | extends: ['plugin:vue/recommended', 'eslint:recommended'],
13 |
14 | // add your custom rules here
15 | //it is base on https://github.com/vuejs/eslint-config-vue
16 | rules: {
17 | "vue/max-attributes-per-line": [2, {
18 | "singleline": 10,
19 | "multiline": {
20 | "max": 1,
21 | "allowFirstLine": false
22 | }
23 | }],
24 | "vue/name-property-casing": ["error", "PascalCase"],
25 | 'accessor-pairs': 2,
26 | 'arrow-spacing': [2, {
27 | 'before': true,
28 | 'after': true
29 | }],
30 | 'block-spacing': [2, 'always'],
31 | 'brace-style': [2, '1tbs', {
32 | 'allowSingleLine': true
33 | }],
34 | 'camelcase': [0, {
35 | 'properties': 'always'
36 | }],
37 | 'comma-dangle': [2, 'never'],
38 | 'comma-spacing': [2, {
39 | 'before': false,
40 | 'after': true
41 | }],
42 | 'comma-style': [2, 'last'],
43 | 'constructor-super': 2,
44 | 'curly': [2, 'multi-line'],
45 | 'dot-location': [2, 'property'],
46 | 'eol-last': 2,
47 | 'eqeqeq': [2, 'allow-null'],
48 | 'generator-star-spacing': [2, {
49 | 'before': true,
50 | 'after': true
51 | }],
52 | 'handle-callback-err': [2, '^(err|error)$'],
53 | 'indent': [2, 2, {
54 | 'SwitchCase': 1
55 | }],
56 | 'jsx-quotes': [2, 'prefer-single'],
57 | 'key-spacing': [2, {
58 | 'beforeColon': false,
59 | 'afterColon': true
60 | }],
61 | 'keyword-spacing': [2, {
62 | 'before': true,
63 | 'after': true
64 | }],
65 | 'new-cap': [2, {
66 | 'newIsCap': true,
67 | 'capIsNew': false
68 | }],
69 | 'new-parens': 2,
70 | 'no-array-constructor': 2,
71 | 'no-caller': 2,
72 | 'no-console': 'off',
73 | 'no-class-assign': 2,
74 | 'no-cond-assign': 2,
75 | 'no-const-assign': 2,
76 | 'no-control-regex': 2,
77 | 'no-delete-var': 2,
78 | 'no-dupe-args': 2,
79 | 'no-dupe-class-members': 2,
80 | 'no-dupe-keys': 2,
81 | 'no-duplicate-case': 2,
82 | 'no-empty-character-class': 2,
83 | 'no-empty-pattern': 2,
84 | 'no-eval': 2,
85 | 'no-ex-assign': 2,
86 | 'no-extend-native': 2,
87 | 'no-extra-bind': 2,
88 | 'no-extra-boolean-cast': 2,
89 | 'no-extra-parens': [2, 'functions'],
90 | 'no-fallthrough': 2,
91 | 'no-floating-decimal': 2,
92 | 'no-func-assign': 2,
93 | 'no-implied-eval': 2,
94 | 'no-inner-declarations': [2, 'functions'],
95 | 'no-invalid-regexp': 2,
96 | 'no-irregular-whitespace': 2,
97 | 'no-iterator': 2,
98 | 'no-label-var': 2,
99 | 'no-labels': [2, {
100 | 'allowLoop': false,
101 | 'allowSwitch': false
102 | }],
103 | 'no-lone-blocks': 2,
104 | 'no-mixed-spaces-and-tabs': 2,
105 | 'no-multi-spaces': 2,
106 | 'no-multi-str': 2,
107 | 'no-multiple-empty-lines': [2, {
108 | 'max': 1
109 | }],
110 | 'no-native-reassign': 2,
111 | 'no-negated-in-lhs': 2,
112 | 'no-new-object': 2,
113 | 'no-new-require': 2,
114 | 'no-new-symbol': 2,
115 | 'no-new-wrappers': 2,
116 | 'no-obj-calls': 2,
117 | 'no-octal': 2,
118 | 'no-octal-escape': 2,
119 | 'no-path-concat': 2,
120 | 'no-proto': 2,
121 | 'no-redeclare': 2,
122 | 'no-regex-spaces': 2,
123 | 'no-return-assign': [2, 'except-parens'],
124 | 'no-self-assign': 2,
125 | 'no-self-compare': 2,
126 | 'no-sequences': 2,
127 | 'no-shadow-restricted-names': 2,
128 | 'no-spaced-func': 2,
129 | 'no-sparse-arrays': 2,
130 | 'no-this-before-super': 2,
131 | 'no-throw-literal': 2,
132 | 'no-trailing-spaces': 2,
133 | 'no-undef': 2,
134 | 'no-undef-init': 2,
135 | 'no-unexpected-multiline': 2,
136 | 'no-unmodified-loop-condition': 2,
137 | 'no-unneeded-ternary': [2, {
138 | 'defaultAssignment': false
139 | }],
140 | 'no-unreachable': 2,
141 | 'no-unsafe-finally': 2,
142 | 'no-unused-vars': [2, {
143 | 'vars': 'all',
144 | 'args': 'none'
145 | }],
146 | 'no-useless-call': 2,
147 | 'no-useless-computed-key': 2,
148 | 'no-useless-constructor': 2,
149 | 'no-useless-escape': 0,
150 | 'no-whitespace-before-property': 2,
151 | 'no-with': 2,
152 | 'one-var': [2, {
153 | 'initialized': 'never'
154 | }],
155 | 'operator-linebreak': [2, 'after', {
156 | 'overrides': {
157 | '?': 'before',
158 | ':': 'before'
159 | }
160 | }],
161 | 'padded-blocks': [2, 'never'],
162 | 'quotes': [2, 'single', {
163 | 'avoidEscape': true,
164 | 'allowTemplateLiterals': true
165 | }],
166 | 'semi': [2, 'never'],
167 | 'semi-spacing': [2, {
168 | 'before': false,
169 | 'after': true
170 | }],
171 | 'space-before-blocks': [2, 'always'],
172 | 'space-before-function-paren': [2, 'never'],
173 | 'space-in-parens': [2, 'never'],
174 | 'space-infix-ops': 2,
175 | 'space-unary-ops': [2, {
176 | 'words': true,
177 | 'nonwords': false
178 | }],
179 | 'spaced-comment': [2, 'always', {
180 | 'markers': ['global', 'globals', 'eslint', 'eslint-disable', '*package', '!', ',']
181 | }],
182 | 'template-curly-spacing': [2, 'never'],
183 | 'use-isnan': 2,
184 | 'valid-typeof': 2,
185 | 'wrap-iife': [2, 'any'],
186 | 'yield-star-spacing': [2, 'both'],
187 | 'yoda': [2, 'never'],
188 | 'prefer-const': 2,
189 | 'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0,
190 | 'object-curly-spacing': [2, 'always', {
191 | objectsInObjects: false
192 | }],
193 | 'array-bracket-spacing': [2, 'never']
194 | }
195 | }
196 |
197 |
--------------------------------------------------------------------------------
/src/views/404.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
(⊙o⊙)哦!
12 |
15 |
{{ message }}
16 |
请检查您输入的网址是否正确,请点击以下按钮返回主页或者发送错误报告
17 |
继续探索
18 |
19 |
20 |
21 |
22 |
23 |
34 |
35 |
229 |
--------------------------------------------------------------------------------
/src/views/layout/components/TagsView.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
13 | {{ tag.title }}
14 |
15 |
16 |
17 |
23 |
24 |
25 |
26 |
139 |
140 |
206 |
207 |
232 |
--------------------------------------------------------------------------------
/src/views/userinfo/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
10 |
11 |
12 | {{ scope.row.group.group_type }}
13 |
14 |
15 | 无
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 | 编辑
26 |
27 |
28 |
29 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
69 |
70 |
71 |
72 |
73 |
173 |
174 |
--------------------------------------------------------------------------------
/src/views/login/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | AEAS'S Admin
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 | 登 录
38 |
39 |
40 |
41 |
如果您没有登录账号,请联系人事。
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
148 |
149 |
182 |
183 |
236 |
--------------------------------------------------------------------------------
/src/components/Upload/mulImage.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
42 |
46 |
47 |
48 |
49 |
50 |
208 |
209 |
215 |
--------------------------------------------------------------------------------
/static/tinymce/zh_CN.js:
--------------------------------------------------------------------------------
1 | tinymce.addI18n('zh_CN',{
2 | "Redo": "\u91cd\u590d",
3 | "Undo": "\u64a4\u6d88",
4 | "Cut": "\u526a\u5207",
5 | "Copy": "\u590d\u5236",
6 | "Paste": "\u7c98\u8d34",
7 | "Select all": "\u5168\u9009",
8 | "New document": "\u65b0\u6587\u6863",
9 | "Ok": "\u786e\u5b9a",
10 | "Cancel": "\u53d6\u6d88",
11 | "Visual aids": "\u7f51\u683c\u7ebf",
12 | "Bold": "\u7c97\u4f53",
13 | "Italic": "\u659c\u4f53",
14 | "Underline": "\u4e0b\u5212\u7ebf",
15 | "Strikethrough": "\u5220\u9664\u7ebf",
16 | "Superscript": "\u4e0a\u6807",
17 | "Subscript": "\u4e0b\u6807",
18 | "Clear formatting": "\u6e05\u9664\u683c\u5f0f",
19 | "Align left": "\u5de6\u5bf9\u9f50",
20 | "Align center": "\u5c45\u4e2d",
21 | "Align right": "\u53f3\u5bf9\u9f50",
22 | "Justify": "\u4e24\u7aef\u5bf9\u9f50",
23 | "Bullet list": "\u9879\u76ee\u7b26\u53f7",
24 | "Numbered list": "\u7f16\u53f7\u5217\u8868",
25 | "Decrease indent": "\u51cf\u5c11\u7f29\u8fdb",
26 | "Increase indent": "\u589e\u52a0\u7f29\u8fdb",
27 | "Close": "\u5173\u95ed",
28 | "Formats": "\u683c\u5f0f",
29 | "Your browser doesn't support direct access to the clipboard. Please use the Ctrl+X\/C\/V keyboard shortcuts instead.": "\u4f60\u7684\u6d4f\u89c8\u5668\u4e0d\u652f\u6301\u5bf9\u526a\u8d34\u677f\u7684\u8bbf\u95ee\uff0c\u8bf7\u4f7f\u7528Ctrl+X\/C\/V\u952e\u8fdb\u884c\u590d\u5236\u7c98\u8d34\u3002",
30 | "Headers": "\u6807\u9898",
31 | "Header 1": "\u6807\u98981",
32 | "Header 2": "\u6807\u98982",
33 | "Header 3": "\u6807\u98983",
34 | "Header 4": "\u6807\u98984",
35 | "Header 5": "\u6807\u98985",
36 | "Header 6": "\u6807\u98986",
37 | "Headings": "\u6807\u9898",
38 | "Heading 1": "\u6807\u98981",
39 | "Heading 2": "\u6807\u98982",
40 | "Heading 3": "\u6807\u98983",
41 | "Heading 4": "\u6807\u98984",
42 | "Heading 5": "\u6807\u98985",
43 | "Heading 6": "\u6807\u98986",
44 | "Preformatted": "\u9884\u683c\u5f0f\u5316",
45 | "Div": "Div\u533a\u5757",
46 | "Pre": "\u9884\u683c\u5f0f\u6587\u672c",
47 | "Code": "\u4ee3\u7801",
48 | "Paragraph": "\u6bb5\u843d",
49 | "Blockquote": "\u5f15\u7528",
50 | "Inline": "\u6587\u672c",
51 | "Blocks": "\u533a\u5757",
52 | "Paste is now in plain text mode. Contents will now be pasted as plain text until you toggle this option off.": "\u5f53\u524d\u4e3a\u7eaf\u6587\u672c\u7c98\u8d34\u6a21\u5f0f\uff0c\u518d\u6b21\u70b9\u51fb\u53ef\u4ee5\u56de\u5230\u666e\u901a\u7c98\u8d34\u6a21\u5f0f\u3002",
53 | "Font Family": "\u5b57\u4f53",
54 | "Font Sizes": "\u5b57\u53f7",
55 | "Class": "Class",
56 | "Browse for an image": "\u6d4f\u89c8\u56fe\u50cf",
57 | "OR": "\u6216",
58 | "Drop an image here": "\u62d6\u653e\u4e00\u5f20\u56fe\u50cf\u81f3\u6b64",
59 | "Upload": "\u4e0a\u4f20",
60 | "Block": "\u5757",
61 | "Align": "\u5bf9\u9f50",
62 | "Default": "\u9ed8\u8ba4",
63 | "Circle": "\u7a7a\u5fc3\u5706",
64 | "Disc": "\u5b9e\u5fc3\u5706",
65 | "Square": "\u65b9\u5757",
66 | "Lower Alpha": "\u5c0f\u5199\u82f1\u6587\u5b57\u6bcd",
67 | "Lower Greek": "\u5c0f\u5199\u5e0c\u814a\u5b57\u6bcd",
68 | "Lower Roman": "\u5c0f\u5199\u7f57\u9a6c\u5b57\u6bcd",
69 | "Upper Alpha": "\u5927\u5199\u82f1\u6587\u5b57\u6bcd",
70 | "Upper Roman": "\u5927\u5199\u7f57\u9a6c\u5b57\u6bcd",
71 | "Anchor": "\u951a\u70b9",
72 | "Name": "\u540d\u79f0",
73 | "Id": "\u6807\u8bc6\u7b26",
74 | "Id should start with a letter, followed only by letters, numbers, dashes, dots, colons or underscores.": "\u6807\u8bc6\u7b26\u5e94\u8be5\u4ee5\u5b57\u6bcd\u5f00\u5934\uff0c\u540e\u8ddf\u5b57\u6bcd\u3001\u6570\u5b57\u3001\u7834\u6298\u53f7\u3001\u70b9\u3001\u5192\u53f7\u6216\u4e0b\u5212\u7ebf\u3002",
75 | "You have unsaved changes are you sure you want to navigate away?": "\u4f60\u8fd8\u6709\u6587\u6863\u5c1a\u672a\u4fdd\u5b58\uff0c\u786e\u5b9a\u8981\u79bb\u5f00\uff1f",
76 | "Restore last draft": "\u6062\u590d\u4e0a\u6b21\u7684\u8349\u7a3f",
77 | "Special character": "\u7279\u6b8a\u7b26\u53f7",
78 | "Source code": "\u6e90\u4ee3\u7801",
79 | "Insert\/Edit code sample": "\u63d2\u5165\/\u7f16\u8f91\u4ee3\u7801\u793a\u4f8b",
80 | "Language": "\u8bed\u8a00",
81 | "Code sample": "\u4ee3\u7801\u793a\u4f8b",
82 | "Color": "\u989c\u8272",
83 | "R": "R",
84 | "G": "G",
85 | "B": "B",
86 | "Left to right": "\u4ece\u5de6\u5230\u53f3",
87 | "Right to left": "\u4ece\u53f3\u5230\u5de6",
88 | "Emoticons": "\u8868\u60c5",
89 | "Document properties": "\u6587\u6863\u5c5e\u6027",
90 | "Title": "\u6807\u9898",
91 | "Keywords": "\u5173\u952e\u8bcd",
92 | "Description": "\u63cf\u8ff0",
93 | "Robots": "\u673a\u5668\u4eba",
94 | "Author": "\u4f5c\u8005",
95 | "Encoding": "\u7f16\u7801",
96 | "Fullscreen": "\u5168\u5c4f",
97 | "Action": "\u64cd\u4f5c",
98 | "Shortcut": "\u5feb\u6377\u952e",
99 | "Help": "\u5e2e\u52a9",
100 | "Address": "\u5730\u5740",
101 | "Focus to menubar": "\u79fb\u52a8\u7126\u70b9\u5230\u83dc\u5355\u680f",
102 | "Focus to toolbar": "\u79fb\u52a8\u7126\u70b9\u5230\u5de5\u5177\u680f",
103 | "Focus to element path": "\u79fb\u52a8\u7126\u70b9\u5230\u5143\u7d20\u8def\u5f84",
104 | "Focus to contextual toolbar": "\u79fb\u52a8\u7126\u70b9\u5230\u4e0a\u4e0b\u6587\u83dc\u5355",
105 | "Insert link (if link plugin activated)": "\u63d2\u5165\u94fe\u63a5 (\u5982\u679c\u94fe\u63a5\u63d2\u4ef6\u5df2\u6fc0\u6d3b)",
106 | "Save (if save plugin activated)": "\u4fdd\u5b58(\u5982\u679c\u4fdd\u5b58\u63d2\u4ef6\u5df2\u6fc0\u6d3b)",
107 | "Find (if searchreplace plugin activated)": "\u67e5\u627e(\u5982\u679c\u67e5\u627e\u66ff\u6362\u63d2\u4ef6\u5df2\u6fc0\u6d3b)",
108 | "Plugins installed ({0}):": "\u5df2\u5b89\u88c5\u63d2\u4ef6 ({0}):",
109 | "Premium plugins:": "\u4f18\u79c0\u63d2\u4ef6\uff1a",
110 | "Learn more...": "\u4e86\u89e3\u66f4\u591a...",
111 | "You are using {0}": "\u4f60\u6b63\u5728\u4f7f\u7528 {0}",
112 | "Plugins": "\u63d2\u4ef6",
113 | "Handy Shortcuts": "\u5feb\u6377\u952e",
114 | "Horizontal line": "\u6c34\u5e73\u5206\u5272\u7ebf",
115 | "Insert\/edit image": "\u63d2\u5165\/\u7f16\u8f91\u56fe\u7247",
116 | "Image description": "\u56fe\u7247\u63cf\u8ff0",
117 | "Source": "\u5730\u5740",
118 | "Dimensions": "\u5927\u5c0f",
119 | "Constrain proportions": "\u4fdd\u6301\u7eb5\u6a2a\u6bd4",
120 | "General": "\u666e\u901a",
121 | "Advanced": "\u9ad8\u7ea7",
122 | "Style": "\u6837\u5f0f",
123 | "Vertical space": "\u5782\u76f4\u8fb9\u8ddd",
124 | "Horizontal space": "\u6c34\u5e73\u8fb9\u8ddd",
125 | "Border": "\u8fb9\u6846",
126 | "Insert image": "\u63d2\u5165\u56fe\u7247",
127 | "Image": "\u56fe\u7247",
128 | "Image list": "\u56fe\u7247\u5217\u8868",
129 | "Rotate counterclockwise": "\u9006\u65f6\u9488\u65cb\u8f6c",
130 | "Rotate clockwise": "\u987a\u65f6\u9488\u65cb\u8f6c",
131 | "Flip vertically": "\u5782\u76f4\u7ffb\u8f6c",
132 | "Flip horizontally": "\u6c34\u5e73\u7ffb\u8f6c",
133 | "Edit image": "\u7f16\u8f91\u56fe\u7247",
134 | "Image options": "\u56fe\u7247\u9009\u9879",
135 | "Zoom in": "\u653e\u5927",
136 | "Zoom out": "\u7f29\u5c0f",
137 | "Crop": "\u88c1\u526a",
138 | "Resize": "\u8c03\u6574\u5927\u5c0f",
139 | "Orientation": "\u65b9\u5411",
140 | "Brightness": "\u4eae\u5ea6",
141 | "Sharpen": "\u9510\u5316",
142 | "Contrast": "\u5bf9\u6bd4\u5ea6",
143 | "Color levels": "\u989c\u8272\u5c42\u6b21",
144 | "Gamma": "\u4f3d\u9a6c\u503c",
145 | "Invert": "\u53cd\u8f6c",
146 | "Apply": "\u5e94\u7528",
147 | "Back": "\u540e\u9000",
148 | "Insert date\/time": "\u63d2\u5165\u65e5\u671f\/\u65f6\u95f4",
149 | "Date\/time": "\u65e5\u671f\/\u65f6\u95f4",
150 | "Insert link": "\u63d2\u5165\u94fe\u63a5",
151 | "Insert\/edit link": "\u63d2\u5165\/\u7f16\u8f91\u94fe\u63a5",
152 | "Text to display": "\u663e\u793a\u6587\u5b57",
153 | "Url": "\u5730\u5740",
154 | "Target": "\u6253\u5f00\u65b9\u5f0f",
155 | "None": "\u65e0",
156 | "New window": "\u5728\u65b0\u7a97\u53e3\u6253\u5f00",
157 | "Remove link": "\u5220\u9664\u94fe\u63a5",
158 | "Anchors": "\u951a\u70b9",
159 | "Link": "\u94fe\u63a5",
160 | "Paste or type a link": "\u7c98\u8d34\u6216\u8f93\u5165\u94fe\u63a5",
161 | "The URL you entered seems to be an email address. Do you want to add the required mailto: prefix?": "\u4f60\u6240\u586b\u5199\u7684URL\u5730\u5740\u4e3a\u90ae\u4ef6\u5730\u5740\uff0c\u9700\u8981\u52a0\u4e0amailto:\u524d\u7f00\u5417\uff1f",
162 | "The URL you entered seems to be an external link. Do you want to add the required http:\/\/ prefix?": "\u4f60\u6240\u586b\u5199\u7684URL\u5730\u5740\u5c5e\u4e8e\u5916\u90e8\u94fe\u63a5\uff0c\u9700\u8981\u52a0\u4e0ahttp:\/\/:\u524d\u7f00\u5417\uff1f",
163 | "Link list": "\u94fe\u63a5\u5217\u8868",
164 | "Insert video": "\u63d2\u5165\u89c6\u9891",
165 | "Insert\/edit video": "\u63d2\u5165\/\u7f16\u8f91\u89c6\u9891",
166 | "Insert\/edit media": "\u63d2\u5165\/\u7f16\u8f91\u5a92\u4f53",
167 | "Alternative source": "\u955c\u50cf",
168 | "Poster": "\u5c01\u9762",
169 | "Paste your embed code below:": "\u5c06\u5185\u5d4c\u4ee3\u7801\u7c98\u8d34\u5728\u4e0b\u9762:",
170 | "Embed": "\u5185\u5d4c",
171 | "Media": "\u5a92\u4f53",
172 | "Nonbreaking space": "\u4e0d\u95f4\u65ad\u7a7a\u683c",
173 | "Page break": "\u5206\u9875\u7b26",
174 | "Paste as text": "\u7c98\u8d34\u4e3a\u6587\u672c",
175 | "Preview": "\u9884\u89c8",
176 | "Print": "\u6253\u5370",
177 | "Save": "\u4fdd\u5b58",
178 | "Find": "\u67e5\u627e",
179 | "Replace with": "\u66ff\u6362\u4e3a",
180 | "Replace": "\u66ff\u6362",
181 | "Replace all": "\u5168\u90e8\u66ff\u6362",
182 | "Prev": "\u4e0a\u4e00\u4e2a",
183 | "Next": "\u4e0b\u4e00\u4e2a",
184 | "Find and replace": "\u67e5\u627e\u548c\u66ff\u6362",
185 | "Could not find the specified string.": "\u672a\u627e\u5230\u641c\u7d22\u5185\u5bb9.",
186 | "Match case": "\u533a\u5206\u5927\u5c0f\u5199",
187 | "Whole words": "\u5168\u5b57\u5339\u914d",
188 | "Spellcheck": "\u62fc\u5199\u68c0\u67e5",
189 | "Ignore": "\u5ffd\u7565",
190 | "Ignore all": "\u5168\u90e8\u5ffd\u7565",
191 | "Finish": "\u5b8c\u6210",
192 | "Add to Dictionary": "\u6dfb\u52a0\u5230\u5b57\u5178",
193 | "Insert table": "\u63d2\u5165\u8868\u683c",
194 | "Table properties": "\u8868\u683c\u5c5e\u6027",
195 | "Delete table": "\u5220\u9664\u8868\u683c",
196 | "Cell": "\u5355\u5143\u683c",
197 | "Row": "\u884c",
198 | "Column": "\u5217",
199 | "Cell properties": "\u5355\u5143\u683c\u5c5e\u6027",
200 | "Merge cells": "\u5408\u5e76\u5355\u5143\u683c",
201 | "Split cell": "\u62c6\u5206\u5355\u5143\u683c",
202 | "Insert row before": "\u5728\u4e0a\u65b9\u63d2\u5165",
203 | "Insert row after": "\u5728\u4e0b\u65b9\u63d2\u5165",
204 | "Delete row": "\u5220\u9664\u884c",
205 | "Row properties": "\u884c\u5c5e\u6027",
206 | "Cut row": "\u526a\u5207\u884c",
207 | "Copy row": "\u590d\u5236\u884c",
208 | "Paste row before": "\u7c98\u8d34\u5230\u4e0a\u65b9",
209 | "Paste row after": "\u7c98\u8d34\u5230\u4e0b\u65b9",
210 | "Insert column before": "\u5728\u5de6\u4fa7\u63d2\u5165",
211 | "Insert column after": "\u5728\u53f3\u4fa7\u63d2\u5165",
212 | "Delete column": "\u5220\u9664\u5217",
213 | "Cols": "\u5217",
214 | "Rows": "\u884c",
215 | "Width": "\u5bbd",
216 | "Height": "\u9ad8",
217 | "Cell spacing": "\u5355\u5143\u683c\u5916\u95f4\u8ddd",
218 | "Cell padding": "\u5355\u5143\u683c\u5185\u8fb9\u8ddd",
219 | "Caption": "\u6807\u9898",
220 | "Left": "\u5de6\u5bf9\u9f50",
221 | "Center": "\u5c45\u4e2d",
222 | "Right": "\u53f3\u5bf9\u9f50",
223 | "Cell type": "\u5355\u5143\u683c\u7c7b\u578b",
224 | "Scope": "\u8303\u56f4",
225 | "Alignment": "\u5bf9\u9f50\u65b9\u5f0f",
226 | "H Align": "\u6c34\u5e73\u5bf9\u9f50",
227 | "V Align": "\u5782\u76f4\u5bf9\u9f50",
228 | "Top": "\u9876\u90e8\u5bf9\u9f50",
229 | "Middle": "\u5782\u76f4\u5c45\u4e2d",
230 | "Bottom": "\u5e95\u90e8\u5bf9\u9f50",
231 | "Header cell": "\u8868\u5934\u5355\u5143\u683c",
232 | "Row group": "\u884c\u7ec4",
233 | "Column group": "\u5217\u7ec4",
234 | "Row type": "\u884c\u7c7b\u578b",
235 | "Header": "\u8868\u5934",
236 | "Body": "\u8868\u4f53",
237 | "Footer": "\u8868\u5c3e",
238 | "Border color": "\u8fb9\u6846\u989c\u8272",
239 | "Insert template": "\u63d2\u5165\u6a21\u677f",
240 | "Templates": "\u6a21\u677f",
241 | "Template": "\u6a21\u677f",
242 | "Text color": "\u6587\u5b57\u989c\u8272",
243 | "Background color": "\u80cc\u666f\u8272",
244 | "Custom...": "\u81ea\u5b9a\u4e49...",
245 | "Custom color": "\u81ea\u5b9a\u4e49\u989c\u8272",
246 | "No color": "\u65e0",
247 | "Table of Contents": "\u5185\u5bb9\u5217\u8868",
248 | "Show blocks": "\u663e\u793a\u533a\u5757\u8fb9\u6846",
249 | "Show invisible characters": "\u663e\u793a\u4e0d\u53ef\u89c1\u5b57\u7b26",
250 | "Words: {0}": "\u5b57\u6570\uff1a{0}",
251 | "{0} words": "{0} \u5b57",
252 | "File": "\u6587\u4ef6",
253 | "Edit": "\u7f16\u8f91",
254 | "Insert": "\u63d2\u5165",
255 | "View": "\u89c6\u56fe",
256 | "Format": "\u683c\u5f0f",
257 | "Table": "\u8868\u683c",
258 | "Tools": "\u5de5\u5177",
259 | "Powered by {0}": "\u7531{0}\u9a71\u52a8",
260 | "Rich Text Area. Press ALT-F9 for menu. Press ALT-F10 for toolbar. Press ALT-0 for help": "\u5728\u7f16\u8f91\u533a\u6309ALT-F9\u6253\u5f00\u83dc\u5355\uff0c\u6309ALT-F10\u6253\u5f00\u5de5\u5177\u680f\uff0c\u6309ALT-0\u67e5\u770b\u5e2e\u52a9"
261 | });
--------------------------------------------------------------------------------
/src/views/myviews/demoadmin.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 新增
6 | 编辑
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
43 |
44 |
45 |
46 |
47 |
48 | 编辑
49 |
50 |
51 | 删除
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 | 类型01
94 | 类型02
95 | 类型03
96 | 类型04
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
117 |
118 |
119 |
125 | 是否确认删除,删除后不可恢复?
126 |
130 |
131 |
132 |
137 |
138 |
139 |
140 |
141 |
142 |
146 |
147 |
148 |
149 |
154 |
356 |
357 |
386 |
--------------------------------------------------------------------------------
/src/views/system/user.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | 新增
8 | 刷新
9 |
10 |
11 |
12 |
14 |
15 |
16 |
23 |
24 |
25 |
26 |
27 |
28 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 | 编辑
45 |
46 |
47 | 删除
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
106 |
107 |
108 |
114 | 是否确认删除,删除后不可恢复?
115 |
119 |
120 |
121 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
172 |
173 |
174 |
175 |
180 |
395 |
396 |
398 |
--------------------------------------------------------------------------------