├── .babelrc ├── .editorconfig ├── .gitignore ├── .postcssrc.js ├── LICENSE ├── README.md ├── package-lock.json ├── package.json ├── quasar.conf.js ├── screenshot ├── 1.jpg ├── 10.jpg ├── 11.jpg ├── 12.jpg ├── 13.jpg ├── 2.jpg ├── 3.jpg ├── 4.jpg ├── 5.jpg ├── 6.jpg ├── 7.jpg ├── 8.jpg ├── 9.jpg └── flowchart.png ├── src ├── App.vue ├── assets │ ├── 403.gif │ ├── quasar-logo-full.svg │ └── sad.svg ├── components │ ├── .gitkeep │ ├── DemoBlock.vue │ ├── FtyBreadcrumbs.vue │ ├── FtyMenu.vue │ ├── FtyModuleTabs.vue │ └── ScrollPane.vue ├── css │ ├── app.styl │ └── themes │ │ ├── common.variables.styl │ │ ├── variables.ios.styl │ │ └── variables.mat.styl ├── default-access-menu.js ├── i18n │ ├── en-us │ │ └── index.js │ ├── index.js │ ├── pt-br │ │ └── index.js │ └── zh-hans │ │ └── index.js ├── index.template.html ├── layouts │ ├── common.vue │ ├── components │ │ └── TagsView.vue │ └── default.vue ├── libs │ ├── auth.js │ ├── loading.js │ ├── permission.js │ ├── request.js │ ├── three │ │ └── three.js │ └── util.js ├── pages │ ├── 403.vue │ ├── cms │ │ ├── comment.vue │ │ ├── post.vue │ │ └── post_edit.vue │ ├── develop │ │ ├── business │ │ │ └── sku.vue │ │ └── official │ │ │ ├── button-group.md │ │ │ ├── button.md │ │ │ ├── dropdown-button.md │ │ │ └── toolbar.md │ ├── empty.vue │ ├── index.vue │ ├── login.vue │ ├── organization │ │ ├── department.vue │ │ └── position.vue │ ├── other │ │ └── requestlog.vue │ ├── permission │ │ ├── function.vue │ │ ├── role.vue │ │ ├── rolepermission.vue │ │ ├── roleuser.vue │ │ └── userrole.vue │ ├── system │ │ └── menu.vue │ └── user │ │ ├── user.vue │ │ └── userinfo.vue ├── plugins │ ├── .gitkeep │ ├── demo-block.js │ ├── i18n.js │ ├── permission.js │ └── vuelidate.js ├── router │ ├── index.js │ └── routes.js ├── service │ ├── cms │ │ └── post.js │ ├── login.js │ ├── other │ │ ├── requestlog.js │ │ └── resetdb.js │ ├── permission │ │ ├── function.js │ │ └── role.js │ ├── system │ │ └── menu.js │ └── user │ │ └── user.js ├── statics │ ├── icons │ │ ├── apple-icon-152x152.png │ │ ├── favicon-16x16.png │ │ ├── favicon-32x32.png │ │ ├── icon-128x128.png │ │ ├── icon-192x192.png │ │ ├── icon-256x256.png │ │ ├── icon-384x384.png │ │ ├── icon-512x512.png │ │ └── ms-icon-144x144.png │ └── quasar-logo.png └── store │ ├── getters.js │ ├── index.js │ └── modules │ ├── app.js │ └── user.js └── strip-tags.js /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | [ "env", {"modules": false} ], 4 | "stage-2" 5 | ], 6 | "plugins": ["transform-runtime"], 7 | "comments": false 8 | } 9 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .quasar 2 | .DS_Store 3 | .thumbs.db 4 | node_modules 5 | /dist 6 | /src-cordova/platforms 7 | /src-cordova/plugins 8 | /src-cordova/www 9 | npm-debug.log* 10 | yarn-debug.log* 11 | yarn-error.log* 12 | 13 | # Editor directories and files 14 | .idea 15 | .vscode 16 | *.suo 17 | *.ntvs* 18 | *.njsproj 19 | *.sln 20 | -------------------------------------------------------------------------------- /.postcssrc.js: -------------------------------------------------------------------------------- 1 | // https://github.com/michael-ciniawsky/postcss-load-config 2 | 3 | module.exports = { 4 | plugins: [ 5 | // to edit target browsers: use "browserslist" field in package.json 6 | require('autoprefixer') 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 若邪 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |
5 |
', '');
15 | };
16 | };
17 |
18 | function convert(str) {
19 | str = str.replace(/()(\w{4});/gi, function ($0) {
20 | return String.fromCharCode(parseInt(encodeURIComponent($0).replace(/(%26%23x)(\w{4})(%3B)/g, '$2'), 16));
21 | });
22 | return str;
23 | }
24 |
25 | module.exports = function (ctx) {
26 | return {
27 | // app plugins (/src/plugins)
28 | plugins: [
29 | 'i18n',
30 | 'vuelidate',
31 | 'permission',
32 | 'demo-block'
33 | ],
34 | css: [
35 | 'app.styl'
36 | ],
37 | extras: [
38 | ctx.theme.mat ? 'roboto-font' : null,
39 | 'material-icons',
40 | // 'ionicons',
41 | // 'mdi',
42 | 'fontawesome'
43 | ],
44 | supportIE: false,
45 | vendor: {
46 | add: [],
47 | remove: []
48 | },
49 | build: {
50 | env: ctx.dev
51 | ? { // so on dev we'll have
52 | API: JSON.stringify('http://localhost:3000')
53 | }
54 | : { // and on build (production):
55 | API: JSON.stringify('http://69.171.69.13:3000')
56 | },
57 | scopeHoisting: true,
58 | vueRouterMode: 'hash',
59 | // gzip: true,
60 | // analyze: true,
61 | // extractCSS: false,
62 | // useNotifier: false,
63 | extendWebpack(cfg) {
64 | cfg.module.rules.push({
65 | test: /\.md$/,
66 | loader: 'vue-markdown-loader',
67 | options: {
68 | preventExtract: true,
69 | use: [
70 | [require('markdown-it-container'), 'demo', {
71 | validate: function (params) {
72 | return params.trim().match(/^demo\s*(.*)$/);
73 | },
74 |
75 | render: function (tokens, idx) {
76 | var m = tokens[idx].info.trim().match(/^demo\s*(.*)$/);
77 | if (tokens[idx].nesting === 1) {
78 | var description = (m && m.length > 1) ? m[1] : '';
79 | var content = tokens[idx + 1].content;
80 | var html = convert(striptags.strip(content, ['script', 'style'])).replace(/(<[^>]*)=""(?=.*>)/g, '$1');
81 | var script = striptags.fetch(content, 'script');
82 | var style = striptags.fetch(content, 'style');
83 | var jsfiddle = { html: html, script: script, style: style };
84 | jsfiddle = md.utils.escapeHtml(JSON.stringify(jsfiddle));
85 | return `
86 | ${html}
87 |
88 | `;
89 | } else {
90 | return ' \n';
91 | }
92 | }
93 | }],
94 | [require('markdown-it-container'), 'tip'],
95 | [require('markdown-it-container'), 'warning']
96 | ],
97 | preprocess: function (MarkdownIt, source) {
98 | MarkdownIt.renderer.rules.table_open = function () {
99 | return '';
100 | };
101 | MarkdownIt.renderer.rules.fence = wrap(MarkdownIt.renderer.rules.fence);
102 | return source;
103 | }
104 | }
105 | }),
106 | cfg.resolve.alias = {
107 | ...cfg.resolve.alias, // This adds the existing alias
108 |
109 | // Add you own alias like this
110 | '@': resolve('src')
111 | }
112 | }
113 | },
114 | devServer: {
115 | // https: true,
116 | // port: 8080,
117 | open: true // opens browser window automatically
118 | },
119 | framework: 'all', //--- includes everything; for dev only!
120 | // framework: {
121 | // components: [
122 | // 'QLayout',
123 | // 'QLayoutHeader',
124 | // 'QLayoutDrawer',
125 | // 'QPageContainer',
126 | // 'QPage',
127 | // 'QToolbar',
128 | // 'QToolbarTitle',
129 | // 'QBtn',
130 | // 'QIcon',
131 | // 'QList',
132 | // 'QListHeader',
133 | // 'QItem',
134 | // 'QItemMain',
135 | // 'QItemSide',
136 | // 'QCollapsible'
137 | // ],
138 | // directives: [
139 | // 'Ripple'
140 | // ],
141 | // // Quasar plugins
142 | // plugins: [
143 | // 'Notify'
144 | // ]
145 | // },
146 | animations: 'all',// --- includes all animations
147 | // animations: [
148 | // ],
149 | pwa: {
150 | cacheExt: 'js,html,css,ttf,eot,otf,woff,woff2,json,svg,gif,jpg,jpeg,png,wav,ogg,webm,flac,aac,mp4,mp3',
151 | manifest: {
152 | // name: 'Quasar App',
153 | // short_name: 'Quasar-PWA',
154 | // description: 'Best PWA App in town!',
155 | display: 'standalone',
156 | orientation: 'portrait',
157 | background_color: '#ffffff',
158 | theme_color: '#027be3',
159 | icons: [
160 | {
161 | 'src': 'statics/icons/icon-128x128.png',
162 | 'sizes': '128x128',
163 | 'type': 'image/png'
164 | },
165 | {
166 | 'src': 'statics/icons/icon-192x192.png',
167 | 'sizes': '192x192',
168 | 'type': 'image/png'
169 | },
170 | {
171 | 'src': 'statics/icons/icon-256x256.png',
172 | 'sizes': '256x256',
173 | 'type': 'image/png'
174 | },
175 | {
176 | 'src': 'statics/icons/icon-384x384.png',
177 | 'sizes': '384x384',
178 | 'type': 'image/png'
179 | },
180 | {
181 | 'src': 'statics/icons/icon-512x512.png',
182 | 'sizes': '512x512',
183 | 'type': 'image/png'
184 | }
185 | ]
186 | }
187 | },
188 | cordova: {
189 | // id: 'org.cordova.quasar.app'
190 | },
191 | electron: {
192 | extendWebpack(cfg) {
193 | // do something with cfg
194 | },
195 | packager: {
196 | // OS X / Mac App Store
197 | // appBundleId: '',
198 | // appCategoryType: '',
199 | // osxSign: '',
200 | // protocol: 'myapp://path',
201 |
202 | // Window only
203 | // win32metadata: { ... }
204 | }
205 | },
206 |
207 | // leave this here for Quasar CLI
208 | starterKit: '1.0.2'
209 | }
210 | }
211 |
--------------------------------------------------------------------------------
/screenshot/1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wjkang/vue-quasar-admin/9769a6fdd59ec2965797ce5cc0543fb363fb660c/screenshot/1.jpg
--------------------------------------------------------------------------------
/screenshot/10.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wjkang/vue-quasar-admin/9769a6fdd59ec2965797ce5cc0543fb363fb660c/screenshot/10.jpg
--------------------------------------------------------------------------------
/screenshot/11.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wjkang/vue-quasar-admin/9769a6fdd59ec2965797ce5cc0543fb363fb660c/screenshot/11.jpg
--------------------------------------------------------------------------------
/screenshot/12.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wjkang/vue-quasar-admin/9769a6fdd59ec2965797ce5cc0543fb363fb660c/screenshot/12.jpg
--------------------------------------------------------------------------------
/screenshot/13.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wjkang/vue-quasar-admin/9769a6fdd59ec2965797ce5cc0543fb363fb660c/screenshot/13.jpg
--------------------------------------------------------------------------------
/screenshot/2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wjkang/vue-quasar-admin/9769a6fdd59ec2965797ce5cc0543fb363fb660c/screenshot/2.jpg
--------------------------------------------------------------------------------
/screenshot/3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wjkang/vue-quasar-admin/9769a6fdd59ec2965797ce5cc0543fb363fb660c/screenshot/3.jpg
--------------------------------------------------------------------------------
/screenshot/4.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wjkang/vue-quasar-admin/9769a6fdd59ec2965797ce5cc0543fb363fb660c/screenshot/4.jpg
--------------------------------------------------------------------------------
/screenshot/5.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wjkang/vue-quasar-admin/9769a6fdd59ec2965797ce5cc0543fb363fb660c/screenshot/5.jpg
--------------------------------------------------------------------------------
/screenshot/6.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wjkang/vue-quasar-admin/9769a6fdd59ec2965797ce5cc0543fb363fb660c/screenshot/6.jpg
--------------------------------------------------------------------------------
/screenshot/7.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wjkang/vue-quasar-admin/9769a6fdd59ec2965797ce5cc0543fb363fb660c/screenshot/7.jpg
--------------------------------------------------------------------------------
/screenshot/8.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wjkang/vue-quasar-admin/9769a6fdd59ec2965797ce5cc0543fb363fb660c/screenshot/8.jpg
--------------------------------------------------------------------------------
/screenshot/9.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wjkang/vue-quasar-admin/9769a6fdd59ec2965797ce5cc0543fb363fb660c/screenshot/9.jpg
--------------------------------------------------------------------------------
/screenshot/flowchart.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wjkang/vue-quasar-admin/9769a6fdd59ec2965797ce5cc0543fb363fb660c/screenshot/flowchart.png
--------------------------------------------------------------------------------
/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
17 |
18 |
21 |
--------------------------------------------------------------------------------
/src/assets/403.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wjkang/vue-quasar-admin/9769a6fdd59ec2965797ce5cc0543fb363fb660c/src/assets/403.gif
--------------------------------------------------------------------------------
/src/assets/sad.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/components/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wjkang/vue-quasar-admin/9769a6fdd59ec2965797ce5cc0543fb363fb660c/src/components/.gitkeep
--------------------------------------------------------------------------------
/src/components/DemoBlock.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
22 |
23 |
28 |
--------------------------------------------------------------------------------
/src/components/FtyBreadcrumbs.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
21 |
22 |
--------------------------------------------------------------------------------
/src/components/FtyMenu.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 | {{$t(child1.title)}}
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 | {{$t(child.title)}}
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 | {{$t(menu.title)}}
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
98 |
99 |
--------------------------------------------------------------------------------
/src/components/FtyModuleTabs.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
36 |
--------------------------------------------------------------------------------
/src/components/ScrollPane.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
58 |
59 |
--------------------------------------------------------------------------------
/src/css/app.styl:
--------------------------------------------------------------------------------
1 | // app global css
2 |
--------------------------------------------------------------------------------
/src/css/themes/common.variables.styl:
--------------------------------------------------------------------------------
1 | // App Shared Variables
2 | // --------------------------------------------------
3 | // To customize the look and feel of this app, you can override
4 | // the Stylus variables found in Quasar's source Stylus files. Setting
5 | // variables before Quasar's Stylus will use these variables rather than
6 | // Quasar's default Stylus variable values. Stylus variables specific
7 | // to the themes belong in either the variables.ios.styl or variables.mat.styl files.
8 |
9 | // Check documentation for full list of Quasar variables
10 |
11 |
12 | // App Shared Color Variables
13 | // --------------------------------------------------
14 | // It's highly recommended to change the default colors
15 | // to match your app's branding.
16 |
17 | //$primary = #027be3
18 | $primary = #41b883
19 | $secondary = #26A69A
20 | $tertiary = #555
21 |
22 | $neutral = #E0E1E2
23 | $positive = #21BA45
24 | $negative = #DB2828
25 | $info = #31CCEC
26 | $warning = #F2C037
27 |
--------------------------------------------------------------------------------
/src/css/themes/variables.ios.styl:
--------------------------------------------------------------------------------
1 | // App Shared Variables
2 | // --------------------------------------------------
3 | // Shared Stylus variables go in the common.variables.styl file
4 | @import 'common.variables'
5 |
6 | // iOS only Quasar variables overwrites
7 | // -----------------------------------------
8 |
--------------------------------------------------------------------------------
/src/css/themes/variables.mat.styl:
--------------------------------------------------------------------------------
1 | // App Shared Variables
2 | // --------------------------------------------------
3 | // Shared Stylus variables go in the common.variables.styl file
4 | @import 'common.variables'
5 |
6 | // Material only Quasar variables overwrites
7 | // -----------------------------------------
8 |
--------------------------------------------------------------------------------
/src/default-access-menu.js:
--------------------------------------------------------------------------------
1 | export const defaultAccessMenu = [
2 | {
3 | path: "",
4 | icon: "settings",
5 | title: "Website",
6 | name: "website",
7 | leftMemu: true,
8 | children: [
9 | {
10 | path: "/cms",
11 | icon: "settings",
12 | title: "CMS",
13 | name: "CMS",
14 | leftMemu: true,
15 | children: [
16 | {
17 | path: "article",
18 | icon: "settings",
19 | title: "Articles",
20 | name: "article",
21 | leftMemu: true
22 | }
23 | ]
24 | }
25 | ]
26 | },
27 | {
28 | path: "",
29 | icon: "settings",
30 | title: "System",
31 | name: "system",
32 | leftMemu: true,
33 | children: [
34 | {
35 | path: "/system",
36 | icon: "settings",
37 | title: "System settings",
38 | name: "system settings",
39 | leftMemu: true,
40 | children: [
41 | {
42 | path: "menu",
43 | icon: "settings",
44 | title: "Menu management",
45 | name: "menu",
46 | leftMemu: true
47 | }
48 | ]
49 | },
50 | {
51 | path: "/permission",
52 | icon: "settings",
53 | title: "Authority management",
54 | name: "permission",
55 | leftMemu: true,
56 | children: [
57 | {
58 | path: "function",
59 | icon: "settings",
60 | title: "Function management",
61 | name: "function",
62 | leftMemu: true
63 | },
64 | {
65 | path: "role",
66 | icon: "settings",
67 | title: "Role management",
68 | name: "role",
69 | leftMemu: true
70 | },
71 | {
72 | path: "rolepermission",
73 | icon: "settings",
74 | title: "Role rights management",
75 | name: "rolepermission",
76 | leftMemu: true
77 | },
78 | {
79 | path: "roleuser",
80 | icon: "settings",
81 | title: "Role user management",
82 | name: "roleuser",
83 | leftMemu: true
84 | },
85 | {
86 | path: "userrole",
87 | icon: "settings",
88 | title: "Role user management",
89 | name: "userrole",
90 | leftMemu: true
91 | }
92 | ]
93 | },
94 | {
95 | path: "/organization",
96 | icon: "settings",
97 | title: "Organization",
98 | name: "organization",
99 | leftMemu: true,
100 | children: [
101 | {
102 | path: "department",
103 | icon: "settings",
104 | title: "Department",
105 | name: "department",
106 | leftMemu: true
107 | },
108 | {
109 | path: "position",
110 | icon: "settings",
111 | title: "Position management",
112 | name: "position",
113 | leftMemu: true
114 | }
115 | ]
116 | },
117 | {
118 | path: "/user",
119 | icon: "settings",
120 | title: "User Management",
121 | name: "user",
122 | leftMemu: true,
123 | children: [
124 | {
125 | path: "index",
126 | icon: "settings",
127 | title: "User Management",
128 | name: "user_index",
129 | leftMemu: true
130 | }
131 | ]
132 | }
133 | ]
134 | },
135 | {
136 | path: "/",
137 | name: "otherRouter",
138 | leftMemu: false,
139 | children: [
140 | {
141 | path: "home",
142 | title: "Home",
143 | name: "home_index"
144 | },
145 | {
146 | path: "userinfo",
147 | title: "Profile / User info",
148 | name: "userinfo"
149 | }
150 | ]
151 | }
152 | ]
153 |
--------------------------------------------------------------------------------
/src/i18n/en-us/index.js:
--------------------------------------------------------------------------------
1 | export default {
2 | successfulinitdata: "Initialization is successful, please refresh the browser",
3 | loginexpired: "Login information has expired, please login again!",
4 | ID: "Actions",
5 | }
6 |
--------------------------------------------------------------------------------
/src/i18n/index.js:
--------------------------------------------------------------------------------
1 | import enUS from './en-us'
2 | import ptBR from './pt-br'
3 | import zhHans from './zh-hans'
4 |
5 | export default {
6 | 'en-us': enUS,
7 | 'pt-br': ptBR,
8 | 'zh-hans': zhHans
9 | }
10 |
--------------------------------------------------------------------------------
/src/i18n/pt-br/index.js:
--------------------------------------------------------------------------------
1 | export default {
2 | Loading: "Carregando",
3 | successfulinitdata: "Inicialização realizada com sucesso, por favor atualize o navegador",
4 |
5 | // User/Login
6 | Username: "Usuário",
7 | Password: "Senha",
8 | Login: "Entrar",
9 | Reset: "Limpar",
10 | Logout: "Sair",
11 | "Please input Username": "Por favor informe o nome do usuário",
12 | "Account password cannot be empty": "A senha precisa ser informada",
13 | loginexpired: "Login expirou, por favor faça login novamente!",
14 | Email: "Email",
15 | "User Email": "Email do usuário",
16 | "Account name": "Conta de usuário",
17 |
18 | // Menu
19 | "System settings": "Configurações do sistema",
20 | "Article management": "Cadastro de artigos",
21 | "Authorization management": "Cadastro de autorizações",
22 | "Department management": "Cadastro de departamentos",
23 | "Function management": "Cadastro de funções",
24 | "Menu management": "Cadastro de menus",
25 | "Position management": "Cadastro de posições",
26 | "Role management": "Cadastro de grupos",
27 | "Role user management": "Cadastro de usuários dos grupos",
28 | "Role rights management": "Cadastro de permissões de usuários",
29 | "User Management": "Cadastro de usuários",
30 | "User role management": "Cadastro de grupos de usuários",
31 | "Business component": "Componente de negócio",
32 | "Official component": "Componente oficial",
33 | "Personal center": "Centro pessoal",
34 | "Website module administrator": "Administrador do Website",
35 | Organization: "Organização",
36 | Button: "Botão",
37 | Buttons: "Botões",
38 | "Button-Group": "Grupo de botões",
39 | "Dropdown Button": "Botão Dropdown",
40 | Navigation: "Navegação",
41 | Toolbar: "Barra de ferramentas",
42 |
43 | "Add top menu": "Adicionar menu superior",
44 | "Add a submenu": "Adicionar um submenu",
45 | "Add menu": "Adicionar menu",
46 | "Edit menu": "Editar menu",
47 |
48 | "Module name": "Nome do módulo",
49 | "Function name": "Nome da função",
50 | "Function code": "Código da função",
51 | "Function description": "Descrição da função",
52 | "Selection module": "Módulo de seleção",
53 | "Role name": "Nome do grupo",
54 | "Role code": "Código do grupo",
55 | "Role description": "Descrição do grupo",
56 | "Role list": "Lista dos grupos",
57 | "List of roles": "Lista de grupos",
58 | "Editing role": "Edição de grupo",
59 | "Module function": "Função do módulo",
60 | "Edit user": "Editar usuário",
61 | "Authority code": "Código de autorização",
62 | "Display on the left": "Exibir a esquerda",
63 | Lock: "Bloquear",
64 | "User list": "Lista de usuários",
65 | "User under": "Usuários",
66 |
67 | // Outros
68 | Other: "Outro",
69 | System: "Sistema",
70 | Website: "Website",
71 | Development: "Desenvolvimento",
72 | Home: "Início",
73 | "Home notification": "Aviso inicial",
74 | User: "Usuário",
75 | Ok: "Ok",
76 | Cancel: "Cancelar",
77 | Add: "Adicionar",
78 | "Added successfully": "Adicionado com sucesso",
79 | Edit: "Editar",
80 | Editing: "Edição",
81 | Delete: "Excluir",
82 | Deleted: "Excluído",
83 | "Batch deletion": "Exclusão em lote",
84 | "Confirm the deletion?": "Você confirma a exclusão?",
85 | "Confirm the bulk delete operation?": "Você confirma a operação de exclusão em lote?",
86 | "Successfully deleted": "Excluído com sucesso",
87 | "Successfully removed": "Removído com sucesso",
88 | "Batch delete succeeded": "Exclusão em lote realizada com sucesso",
89 | Save: "Gravar",
90 | "Saved successfully": "Gravado com sucesso",
91 | Search: "Pesquisar",
92 | Select: "Selecionar",
93 | "Select icon": "Selecione o ícone",
94 | Permission: "Permissão",
95 | Name: "Nome",
96 | Title: "Título",
97 | Phone: "Telefone",
98 | Draft: "Rascunho",
99 | Published: "Publicado",
100 | Classification: "Classificação",
101 | Tags: "Marcadores",
102 | Status: "Situação",
103 | Sort: "Ordem",
104 | "Published date": "Publicação",
105 | "Created date": "Criação",
106 | "Updated date": "Atualização",
107 | Created: "Criação",
108 | ID: "Ações",
109 | Brief: "Resumo",
110 | "System label": "Label de sistema",
111 | Keywords: "Palavras chave",
112 | Release: "Publicação",
113 | "Release time": "Hora de publicação",
114 | "Front end": "Interface",
115 | "Back end": "Retaguarda",
116 | Life: "Permanente",
117 | Method: "Método",
118 | Request: "Requisição",
119 | "Time (ms)": "Tempo (ms)",
120 | "You don't have permission to go to this page": "Você não tem permissão para acessar esta página",
121 | "Or you can go": "Ou você pode ir",
122 | "Back to home": "De volta para o início",
123 | "This page has nothing": "Esta página está vazia",
124 | "Audit log": "Log de auditoria",
125 | "Zhang San": "Zhang San",
126 |
127 | "System error": "Erro de sistema",
128 | "Network timeout": "Timeout de rede",
129 | "Network error": "Erro de rede",
130 | "No data": "Sem dados",
131 | "Rows per page": "Registros por página",
132 |
133 | "Label option": "Opções",
134 | "Close other": "Fechar outros",
135 | "Close all": "Fechar todos",
136 | "Request log": "Log de requisições",
137 | "Initialization Data": "Inicialização dos Dados",
138 | "User info": "Informações do usuário",
139 | "Layout management": "Cadastro de layout",
140 | "Confirm execution": "Confirma execução",
141 | "No request permission": "Sem permissão para a requisição",
142 | Test: "Teste",
143 |
144 | // CMS
145 | "The title can not be blank": "O título não pode ficar em branco",
146 | "Brief description cannot be empty": "O resumo não pode ficar vazio",
147 | "The content can not be blank": "O conteúdo não pode ficar em branco",
148 | "Classification cannot be empty": "A classificação não pode ficar vazia",
149 |
150 | // SKU
151 | "Place of delivery": "Local de entrega",
152 | "Custom name": "Nome personalizado",
153 | Image: "Imagem",
154 | Color: "Cor",
155 | Material: "Material",
156 | "The retail price in the table below is the price of the product that is ultimately displayed to the buyer":
157 | "O preço de varejo na tabela abaixo é o preço do produto que é exibido ao comprador",
158 | "Set retail price in bulk": "Definir preço de varejo a granel",
159 | Define: "Definir",
160 | "Set inventory in batches": "Definir inventário em lotes",
161 | "Retail price": "Preço no varejo",
162 | "In stock": "Em estoque",
163 | "Commodity code": "Código da mercadoria",
164 | Package: "Pacote",
165 |
166 | "Aluminum": "Alumínio",
167 | "Canvas": "Canvas",
168 | "Cotton": "Algodão",
169 | "Twill fabric": "Tecido de sarja",
170 | "Leather": "Couro",
171 | "Microfiber": "Microfibra",
172 | "Synthetic rubber": "Borracha sintética",
173 | "Nylon": "Nilon",
174 | "Plastic": "Plástico",
175 | "Polyester": "Poliester",
176 | "Silica gel": "Silica gel",
177 | "Vinyl": "Vinil",
178 | "Genuine leather": "Couro legítimo",
179 | "Beige": "Bege",
180 | "Black": "Preto",
181 | "Blue": "Azul",
182 | "Sky blue": "Azul céu",
183 | "Brown": "Marrom",
184 | "Transparent": "Transparente",
185 | "Gold": "Ouro",
186 | "Gray": "Cinza",
187 | "Dark gray": "Cinza escuro",
188 | "Green": "Verde",
189 | "ArmyGreen": "Verde exército",
190 | "Ivory white": "Marfim",
191 | "Khaki": "Caqui",
192 | "Multicolor": "Colorido",
193 | "Orange": "Laranja",
194 | "Pink": "Rosa choque",
195 | "Purple": "Púrpura",
196 | "Violet": "Violeta",
197 | "Red": "Vermelho",
198 | "Silver": "Prata",
199 | "White": "Branco",
200 | "Yellow": "Amarelo",
201 | "Rose": "Rosa",
202 | "Crimson": "Carmesim",
203 | "Dark blue": "Azul escuro",
204 | "Matte Black": "Preto fosco",
205 | "Shell + film": "Shell + filme",
206 | "Shell + lanyard": "Shell + cordão",
207 | }
208 |
--------------------------------------------------------------------------------
/src/i18n/zh-hans/index.js:
--------------------------------------------------------------------------------
1 | export default {
2 | Loading: "Loading",
3 | successfulinitdata: "初始化成功,请刷新浏览器",
4 |
5 | // User/Login
6 | Username: "账号",
7 | Password: "密码",
8 | Login: "Login",
9 | Reset: "Reset",
10 | Logout: "退出",
11 | "Please input Username": "请输入账号",
12 | "Account password cannot be empty": "账号密码不能为空",
13 | loginexpired: "登陆信息已过期,请重新登陆!",
14 | Email: "邮箱",
15 | "User Email": "用户邮箱",
16 | "Account name": "账号名称",
17 |
18 | // Menu
19 | "System settings": "系统设置",
20 | "Article management": "文章管理",
21 | "Authorization management": "权限管理",
22 | "Department management": "部门管理",
23 | "Function management": "功能管理",
24 | "Menu management": "菜单管理",
25 | "Position management": "职位管理",
26 | "Role management": "角色管理",
27 | "Role user management": "角色用户管理",
28 | "Role rights management": "角色权限管理",
29 | "User Management": "用户管理",
30 | "User role management": "用户角色管理",
31 | "Business component": "业务组件",
32 | "Official component": "官方组件",
33 | "Personal center": "个人中心",
34 | "Website module administrator": "网站模块管理员",
35 | Organization: "组织架构",
36 | Button: "Button",
37 | Buttons: "Buttons",
38 | "Button-Group": "Button-Group",
39 | "Dropdown Button": "Dropdown Button",
40 | Navigation: "Navigation",
41 | Toolbar: "Toolbar",
42 |
43 | "Add top menu": "新增顶级菜单",
44 | "Add a submenu": "新增子菜单",
45 | "Add menu": "新增菜单",
46 | "Edit menu": "编辑菜单",
47 |
48 | "Module name": "模块名称",
49 | "Function name": "功能名称",
50 | "Function code": "功能编码",
51 | "Function description": "功能描述",
52 | "Selection module": "选择模块",
53 | "Role name": "角色名称",
54 | "Role code": "角色编码",
55 | "Role description": "角色描述",
56 | "Role list": "角色列表",
57 | "List of roles": "所属角色列表",
58 | "Editing role": "编辑角色",
59 | "Module function": "模块功能",
60 | "Edit user": "编辑用户",
61 | "Authority code": "权限码",
62 | "Display on the left": "是否左侧显示",
63 | Lock: "是否锁定",
64 | "User list": "用户列表",
65 | "User under": "下的用户",
66 |
67 | // Others
68 | Other: "其它",
69 | System: "系统",
70 | Website: "网站",
71 | Development: "开发",
72 | Home: "首页",
73 | "Home notification": "首页通知",
74 | User: "用户",
75 | Ok: "确定",
76 | Cancel: "取消",
77 | Add: "新增",
78 | "Added successfully": "添加成功",
79 | Edit: "编辑",
80 | Editing: "正在编辑",
81 | Delete: "删除",
82 | Deleted: "已删除",
83 | "Batch deletion": "批量删除",
84 | "Confirm the deletion?": "确认执行删除操作?",
85 | "Confirm the bulk delete operation?": "确认执行批量删除操作?",
86 | "Successfully deleted": "删除成功",
87 | "Successfully removed": "移除成功",
88 | "Batch delete succeeded": "批量删除成功",
89 | Save: "保存",
90 | "Saved successfully": "保存成功",
91 | Search: "查询",
92 | Select: "选择",
93 | "Select icon": "选择图标",
94 | Permission: "权限",
95 | Name: "名称",
96 | Title: "标题",
97 | Phone: "Phone",
98 | Draft: "草稿",
99 | Published: "已发布",
100 | Classification: "分类",
101 | Tags: "标签",
102 | Status: "状态",
103 | Sort: "排序",
104 | "Published date": "发布日期",
105 | "Created date": "创建日期",
106 | "Updated date": "更新日期",
107 | Created: "时间",
108 | ID: "操作",
109 | Brief: "简述",
110 | "System label": "系统标签",
111 | Keywords: "关键词",
112 | Release: "发布",
113 | "Release time": "发布时间",
114 | "Front end": "前端",
115 | "Back end": "后端",
116 | Life: "生活",
117 | Method: "方法",
118 | Request: "请求",
119 | "Time (ms)": "耗时(ms)",
120 | "You don't have permission to go to this page": "你没有权限去该页面",
121 | "Or you can go": "或者你可以去",
122 | "Back to home": "回首页",
123 | "This page has nothing": "这个页面什么也没有",
124 | "Audit log": "审计日志",
125 | "Zhang San": "张三",
126 |
127 | "System error": "系统错误",
128 | "Network timeout": "网络超时",
129 | "Network error": "网络错误",
130 | "No data": "没有数据",
131 | "Rows per page": "每页数据",
132 |
133 | "Label option": "标签选项",
134 | "Close other": "关闭其他",
135 | "Close all": "关闭所有",
136 | "Request log": "审计日志",
137 | "Initialization Data": "初始化数据",
138 | "User info": "个人中心",
139 | "Layout management": "布局管理",
140 | "Confirm execution": "确认执行操作",
141 | "No request permission": "没有请求权限",
142 | Test: "测试",
143 |
144 | // CMS
145 | "The title can not be blank": "标题不能为空",
146 | "Brief description cannot be empty": "简述不能为空",
147 | "The content can not be blank": "内容不能为空",
148 | "Classification cannot be empty": "分类不能为空",
149 |
150 | // SKU
151 | "Place of delivery": "发货地",
152 | "Custom name": "自定义名称",
153 | Image: "图片",
154 | Color: "颜色",
155 | Material: "材质",
156 | "The retail price in the table below is the price of the product that is ultimately displayed to the buyer":
157 | "下表的零售价是最终展示给买家的产品价格",
158 | "Set retail price in bulk": "批量设置零售价",
159 | Define: "确定",
160 | "Set inventory in batches": "批量设置库存",
161 | "Retail price": "零售价",
162 | "In stock": "库存",
163 | "Commodity code": "商品编码",
164 | Package: "套餐",
165 |
166 | "Aluminum": "铝",
167 | "Canvas": "帆布",
168 | "Cotton": "棉布",
169 | "Twill fabric": "斜纹布",
170 | "Leather": "皮革",
171 | "Microfiber": "微纤维",
172 | "Synthetic rubber": "合成橡胶",
173 | "Nylon": "尼龙",
174 | "Plastic": "塑料",
175 | "Polyester": "涤纶",
176 | "Silica gel": "硅胶",
177 | "Vinyl": "Vinyl",
178 | "Genuine Leather": "真皮",
179 | "Beige": "米色",
180 | "Black": "黑色",
181 | "Blue": "蓝色",
182 | "Sky blue": "天蓝色",
183 | "Brown": "褐色",
184 | "Transparent": "透明",
185 | "Gold": "金色",
186 | "Gray": "灰色",
187 | "Dark gray": "深灰色",
188 | "Green": "绿色",
189 | "ArmyGreen": "军绿色",
190 | "Ivory white": "象牙白",
191 | "Khaki": "卡其色",
192 | "Multicolor": "多色",
193 | "Orange": "橙色",
194 | "Pink": "粉色",
195 | "Purple": "紫色",
196 | "Violet": "紫罗兰",
197 | "Red": "红色",
198 | "Silver": "银色",
199 | "White": "白色",
200 | "Yellow": "黄色",
201 | "Rose": "玫瑰色",
202 | "Crimson": "深红",
203 | "Dark blue": "深蓝",
204 | "Matte Black": "磨砂黑",
205 | "Shell + film": "壳+贴膜",
206 | "Shell + lanyard": "壳+挂绳",
207 | }
208 |
--------------------------------------------------------------------------------
/src/index.template.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 | <%= htmlWebpackPlugin.options.productName %>
12 |
13 |
14 |
15 |
16 |
17 |
18 | <% if (htmlWebpackPlugin.options.ctx.mode.pwa) { %>
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 | <% } %>
31 |
32 | <%= htmlWebpackPlugin.options.headScripts %>
33 |
34 |
38 | <% if (!['cordova', 'electron'].includes(htmlWebpackPlugin.options.ctx.modeName) && htmlWebpackPlugin.options.ctx.prod) {
39 | for (var chunk of webpack.chunks) {
40 | for (var file of chunk.files) {
41 | if (file.match(/\.(js|css)$/)) { %>
42 |
43 | <% }}}} %>
44 |
100 |
101 |
102 |
103 | <% if (!htmlWebpackPlugin.options.ctx.mode.electron) { %>
104 |
107 | <% } %>
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 | <%= htmlWebpackPlugin.options.bodyScripts %>
120 |
121 |
122 |
123 |
124 |
--------------------------------------------------------------------------------
/src/layouts/components/TagsView.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
12 |
11 |
20 |
21 |
22 |
23 |
114 |
115 |
130 |
--------------------------------------------------------------------------------
/src/layouts/default.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
16 |
17 |
18 |
19 |
20 | Quasar App
21 | Running on Quasar v{{ $q.version }}
22 |
23 |
24 |
25 |
26 |
30 |
35 | Essential Links
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
80 |
81 |
83 |
--------------------------------------------------------------------------------
/src/libs/auth.js:
--------------------------------------------------------------------------------
1 |
2 | const TokenKey = 'fty-admin-token'
3 |
4 | export function getToken() {
5 | return localStorage.getItem(TokenKey)
6 | }
7 |
8 | export function setToken(token) {
9 | localStorage.setItem(TokenKey,token)
10 | }
11 |
12 | export function removeToken() {
13 | localStorage.removeItem(TokenKey)
14 | }
--------------------------------------------------------------------------------
/src/libs/loading.js:
--------------------------------------------------------------------------------
1 | import { Loading, QSpinnerGears,QSpinnerHourglass } from 'quasar'
2 |
3 | let loading = {
4 | }
5 | let lastRequest = new Date('2018');
6 |
7 | loading.show = function (config) {
8 | if (config&&config.loading) {
9 | let now = new Date();
10 | let ms = now - lastRequest;
11 | lastRequest = now;
12 | if (ms > 2000) {//相隔两秒的请求才重新显示loading
13 | if (config.loading == "gears") {
14 | Loading.show({
15 | spinner: QSpinnerGears,
16 | message: '',
17 | messageColor: 'white',
18 | spinnerSize: 100,
19 | spinnerColor: 'white',
20 | customClass : ''
21 | })
22 | }else if(config.loading=="hourglass")
23 | {
24 | Loading.show({
25 | // spinner: QSpinnerHourglass,
26 | message: '',
27 | messageColor: 'white',
28 | spinnerSize: 100,
29 | spinnerColor: 'white',
30 | customClass : ''
31 | })
32 | }
33 | }
34 | }
35 |
36 | }
37 |
38 | loading.hide = function (config) {
39 | if (config&&config.loading) {
40 | setTimeout(() => {
41 | Loading.hide()
42 | }, 1000)
43 | }
44 | }
45 |
46 | export default loading;
47 |
--------------------------------------------------------------------------------
/src/libs/permission.js:
--------------------------------------------------------------------------------
1 | let permission = {
2 |
3 | }
4 |
5 | permission.check = function (config) {
6 | if (config.permission && config.permission.length > 0) {
7 | let needPermissions = config.permission;
8 | let permissions = JSON.parse(localStorage.getItem('permission'));
9 | let isAdmin = localStorage.getItem('isAdmin');
10 | let hasPermission = permissions.some(s => {
11 | return needPermissions.indexOf(s) > -1;
12 | })
13 | if (!hasPermission && isAdmin == 0) {
14 | return false
15 | }
16 | }
17 | return true
18 | }
19 |
20 | export default permission
--------------------------------------------------------------------------------
/src/libs/request.js:
--------------------------------------------------------------------------------
1 | import axios from 'axios'
2 | import Router from '@/router/index';
3 | import { getToken, removeToken } from '@/libs/auth'
4 | import loading from '@/libs/loading'
5 | import permission from '@/libs/permission'
6 | import { Notify } from 'quasar'
7 |
8 | // create an axios instance
9 | const service = axios.create({
10 | baseURL: process.env.API, // api的base_url
11 | timeout: 20000 // request timeout
12 | })
13 |
14 | // request interceptor
15 | service.interceptors.request.use(config => {
16 | // Do something before request is sent
17 | if (!permission.check(config)) {
18 | Notify.create({
19 | message: this.$t("No request permission")
20 | })
21 | throw "403"
22 | }
23 | loading.show(config)
24 | let token = getToken()
25 | if (token) {
26 | config.headers['Authorization'] = 'Bearer ' + token// 让每个请求携带token-- ['X-Token']为自定义key 请根据实际情况自行修改
27 | }
28 | return config
29 | }, error => {
30 | // Do something with request error
31 | //console.log(error) // for debug
32 | Promise.reject(error)
33 | })
34 |
35 | // respone interceptor
36 | service.interceptors.response.use(
37 | response => {
38 | loading.hide(response.config)
39 | const res = response.data;
40 | if (res.statusCode !== 200) {
41 | Notify.create({
42 | message: res.msg
43 | })
44 | return Promise.reject('error');
45 | } else {
46 |
47 | return response;
48 | }
49 | },
50 | error => {
51 | loading.hide(error.config)
52 | if (error.response && error.response.status === 401) {
53 | removeToken();
54 | if (error.config.url.indexOf("logout") === -1) {
55 | Notify.create({
56 | message: this.$t('loginexpired')
57 | })
58 | }
59 | setTimeout(() => {
60 | Router.push({
61 | name: "login"
62 | });
63 | }, 1000)
64 |
65 | } else if (error.response && error.response.status === 500) {
66 | Notify.create({
67 | message: this.$t('System error') + '!',
68 | position: 'bottom-right'
69 | })
70 | } else if (error.message.indexOf("timeout")>-1) {
71 | Notify.create({
72 | message: this.$t('Network timeout') + '!',
73 | position: 'bottom-right'
74 | })
75 | }
76 | else if (error == "403") {
77 |
78 | } else {
79 | Notify.create({
80 | message: this.$t('Network error') + '!',
81 | position: 'bottom-right'
82 | })
83 | }
84 | return Promise.reject(error)
85 |
86 | })
87 |
88 | export default service
89 |
90 |
91 |
92 |
--------------------------------------------------------------------------------
/src/libs/util.js:
--------------------------------------------------------------------------------
1 | let util = {
2 |
3 | };
4 | util.title = function (title) {
5 | title = title || 'vue.quasar.admin';
6 | window.document.title = title;
7 | };
8 |
9 | util.getMenuByName = function (name, menulist) {
10 | let menu = {};
11 | let forFn = function (name, menulist) {
12 | for (var item of menulist) {
13 | if (item.name === name) {
14 | menu = item;
15 | } else {
16 | if (item.children && item.children.length > 0) {
17 | forFn(name, item.children)
18 | }
19 | }
20 | if (menu.name) {
21 | break;
22 | }
23 | }
24 | }
25 | forFn(name, menulist);
26 | return menu;
27 | }
28 |
29 | util.oneOf = function (ele, targetArr) {
30 | if (targetArr.indexOf(ele) >= 0) {
31 | return true;
32 | } else {
33 | return false;
34 | }
35 | };
36 | util.getParentMenusByName = function (openAccesseMenu, name) {
37 | let temp = [];
38 | let forFn = function (openAccesseMenu, name) {
39 | for (var item of openAccesseMenu) {
40 | if (item.name === name && item.path !== "/") {
41 | temp.push(item);
42 | forFn(openAccesseMenu, item.parentName);
43 | }
44 | }
45 | };
46 | forFn(openAccesseMenu, name);
47 | temp.reverse()
48 | return temp;
49 | };
50 |
51 | util.handleTitle = function (vm, item) {
52 | return item.title;
53 | };
54 |
55 | util.setCurrentPath = function (vm, name) {
56 | let openAccesseMenu = vm.$store.state.app.openAccessMenu;
57 | let menulistWithParent = util.getParentMenusByName(openAccesseMenu, name);
58 | let currentPathArr = [];
59 | if (!menulistWithParent.some(item => {
60 | return item.name === "home_index"
61 | })) {
62 | currentPathArr.push({
63 | title: vm.$t("Home"),
64 | path: "/home",
65 | name: 'home_index'
66 | });
67 | }
68 | currentPathArr.push(...menulistWithParent);
69 | vm.$store.commit('setCurrentPath', currentPathArr);
70 | };
71 | util.setCurrentModule = function (vm, name) {
72 | let openAccesseMenu = vm.$store.state.app.openAccessMenu;
73 | let moduleList = vm.$store.state.app.moduleList;
74 | let currentModule = vm.$store.state.app.currentModule;
75 | let menulistWithParent = util.getParentMenusByName(openAccesseMenu, name);
76 | if (menulistWithParent.length > 0) {
77 | let moduleName = menulistWithParent[0].name;
78 | if (moduleList.some(item => {
79 | return item.name === moduleName
80 | }) && currentModule !== moduleName) {
81 | vm.$store.dispatch('changeModule', moduleName);
82 | }
83 | }
84 |
85 | };
86 | util.toDefaultPage = function (menulist, to, routes, next) {
87 | if (to.path == "/") {
88 | next({ name: 'home_index', replace: true })
89 | }
90 | else {
91 | next()
92 | }
93 | };
94 | util.openAccesseMenu = function (accesseMenu) {
95 | let openAccesseMenu = [];
96 | let forFn = function (menulist, parentName) {
97 | for (var item of menulist) {
98 | item.parentName = parentName;
99 | openAccesseMenu.push(item)
100 | if (item.children && item.children.length > 0) {
101 | forFn(item.children, item.name)
102 | }
103 | }
104 | }
105 | forFn(accesseMenu, '');
106 | return openAccesseMenu;
107 | }
108 |
109 | util.openNewPage = function (vm, name, argu, query) {
110 | let pageOpenedList = vm.$store.state.app.pageOpenedList;
111 | let openedPageLen = pageOpenedList.length;
112 | let i = 0;
113 | let tagHasOpened = false;
114 | while (i < openedPageLen) {
115 | if (name === pageOpenedList[i].name) { // 页面已经打开
116 | vm.$store.commit('pageOpenedList', {
117 | index: i,
118 | argu: argu,
119 | query: query
120 | });
121 | tagHasOpened = true;
122 | break;
123 | }
124 | i++;
125 | }
126 | if (!tagHasOpened) {
127 | let tags = vm.$store.state.app.openAccessMenu.filter((item) => {
128 | return name === item.name;
129 | });
130 | if (tags.length > 0) {
131 | let tag = tags[0];
132 | if (argu) {
133 | tag.argu = argu;
134 | }
135 | if (query) {
136 | tag.query = query;
137 | }
138 | vm.$store.commit('increateTag', tag);
139 | }
140 | }
141 | };
142 |
143 | export default util;
144 |
--------------------------------------------------------------------------------
/src/pages/403.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | 返回
4 |
5 |
6 | Oops!
7 | {{$t("You don't have permission to go to this page")}}
8 |
9 | - {{$t('Or you can go')}}:
10 | -
11 |
{{$t('Back to home')}}
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
38 |
39 |
72 |
--------------------------------------------------------------------------------
/src/pages/cms/comment.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/src/pages/cms/post.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
7 |
8 |
9 | {{$t('Search')}}
10 |
11 | {{$t('Add')}}
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 | {{ col.label }}
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 | {{ props.row.title }}
37 |
38 | {{ props.row.catelog }}
39 |
40 | {{tag}}
41 |
42 |
43 | {{$t('Draft')}}
44 | {{$t('Published')}}
45 | {{$t('Deleted')}}
46 |
47 | {{ props.row.sort }}
48 | {{formatDate(props.row.publishedDate)}}
49 | {{formatDate(props.row.createdDate)}}
50 | {{formatDate(props.row.updatedDate)}}
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 | {{ props.row.shortContent }}
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
203 |
--------------------------------------------------------------------------------
/src/pages/cms/post_edit.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | {{$t('Title')}}:
7 |
8 |
9 |
10 |
11 |
12 | {{$t('Brief')}}:
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 | {{$t('Classification')}}:
27 |
28 |
29 |
30 |
31 |
32 | {{$t('System label')}}:
33 |
34 |
35 |
36 |
37 |
38 | {{$t('Keywords')}}:
39 |
40 |
41 |
42 |
43 |
44 | {{$t('Sort')}}:
45 |
46 |
47 |
48 |
49 |
50 | {{$t('Release time')}}:
51 |
52 |
53 |
54 |
55 |
56 | {{$t('Status')}}:
57 |
58 |
63 |
64 |
65 |
66 |
67 |
68 | {{$t('Save')}}
69 |
70 |
71 |
72 |
73 |
74 |
75 |
265 |
272 |
--------------------------------------------------------------------------------
/src/pages/develop/official/button-group.md:
--------------------------------------------------------------------------------
1 | :::demo
2 | ```html
3 | Examples of group buttons. Endless possibilities.
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
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 |
50 |
51 |
52 |
53 |
54 |
55 |
56 | Photos
57 | February 22, 2016
58 |
59 |
60 |
61 |
62 | Files
63 |
64 |
65 |
66 | Vacation
67 | February 22, 2016
68 |
69 |
70 |
71 |
72 |
73 |
74 | ```
75 | :::
76 |
--------------------------------------------------------------------------------
/src/pages/develop/official/dropdown-button.md:
--------------------------------------------------------------------------------
1 | :::demo
2 | ```html
3 | These are just a few examples
4 |
5 |
6 |
7 |
8 |
9 | Photos
10 | February 22, 2016
11 |
12 |
13 |
14 |
15 | Files
16 |
17 |
18 |
19 | Vacation
20 | February 22, 2016
21 |
22 |
23 |
24 |
25 |
26 |
27 | Split with Glossy effect
28 |
29 |
30 |
31 |
32 |
33 | Photos
34 | February 22, 2016
35 |
36 |
37 |
38 |
39 | Files
40 |
41 |
42 |
43 | Vacation
44 | February 22, 2016
45 |
46 |
47 |
48 |
49 |
50 |
51 | Outline
52 |
53 |
54 |
55 |
56 |
57 | Photos
58 | February 22, 2016
59 |
60 |
61 |
62 |
63 | Files
64 |
65 |
66 |
67 | Vacation
68 | February 22, 2016
69 |
70 |
71 |
72 |
73 |
74 |
75 | Push type with icon and v-model
76 |
77 |
78 |
79 |
80 |
81 | Photos
82 | February 22, 2016
83 |
84 |
85 |
86 |
87 | Files
88 |
89 |
90 |
91 | Vacation
92 | February 22, 2016
93 |
94 |
95 |
96 |
97 |
98 |
99 | Push type with icon and v-model
100 |
101 |
102 |
103 |
104 |
105 | Photos
106 | February 22, 2016
107 |
108 |
109 |
110 |
111 | Files
112 |
113 |
114 |
115 | Vacation
116 | February 22, 2016
117 |
118 |
119 |
120 |
121 |
122 | ```
123 | :::
124 |
125 |
126 |
--------------------------------------------------------------------------------
/src/pages/develop/official/toolbar.md:
--------------------------------------------------------------------------------
1 | :::demo
2 | ```html
3 |
4 | Toolbars are mainly used in Layout headers and footers, but they can be used in your Page view too.
5 |
6 |
7 |
8 |
9 |
10 | Toolbar
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 | Toolbar
21 |
22 |
23 |
24 |
25 |
26 | They come in all colors.
27 |
28 |
29 |
30 |
31 |
32 | Toolbar
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 | Toolbar
41 | Subtitle
42 |
43 |
44 |
45 |
46 |
47 |
48 | 2
49 |
50 |
51 | Long title for Toolbar. Very very very very very very long title.
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 | Toolbar
62 |
63 |
64 |
65 |
66 |
67 |
68 | And inverted:
69 |
70 |
71 |
72 |
73 |
74 | Toolbar
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 | Toolbar
83 | Subtitle
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 | Long title for Toolbar. Very very very very very very long title.
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 | Toolbar
102 |
103 |
104 |
105 |
106 | ```
107 | :::
108 |
--------------------------------------------------------------------------------
/src/pages/empty.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Oops!
6 | {{$t('This page has nothing')}}
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
26 |
27 |
60 |
--------------------------------------------------------------------------------
/src/pages/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | {{post.title}}
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 | {{$t('Audit log')}}
21 |
22 |
23 |
24 |
25 |
26 |
27 | {{formatDate(props.value)}}
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
38 |
39 |
128 |
--------------------------------------------------------------------------------
/src/pages/login.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
11 |
12 |
13 |
14 |
15 |
16 |
17 | {{$t('Login')}}
18 |
19 | {{$t('Loading')}}...
20 |
21 |
22 | {{$t('Reset')}}
23 |
24 |
25 |
26 |
27 |
28 |
29 |
170 |
171 |
221 |
--------------------------------------------------------------------------------
/src/pages/organization/department.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/src/pages/organization/position.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/src/pages/other/requestlog.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
7 |
8 |
9 |
10 |
11 | {{formatDate(props.value)}}
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
110 |
--------------------------------------------------------------------------------
/src/pages/permission/function.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
8 |
9 |
11 |
12 |
13 |
14 |
15 | Search
16 | {{$t('Add')}}
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 | {{$t('Edit')}}
37 |
38 |
39 |
40 |
41 |
42 | {{$t('Save')}}
43 | {{$t('Cancel')}}
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 | {{tempFunction.module}}
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 | {{$t('Selection module')}}
67 |
68 |
69 |
70 |
71 |
72 | {{$t('Select')}}
73 | {{$t('Cancel')}}
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
328 |
--------------------------------------------------------------------------------
/src/pages/permission/role.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
8 |
9 |
11 |
12 |
13 |
14 | {{$t('Search')}}
15 | {{$t('Add')}}
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 | {{$t('Edit')}}
36 |
37 |
38 |
39 |
40 |
41 | {{$t('Save')}}
42 | {{$t('Cancel')}}
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
234 |
--------------------------------------------------------------------------------
/src/pages/permission/rolepermission.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
8 |
9 |
11 |
12 |
13 |
14 | {{$t('Search')}}
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 | {{$t('Editing role')}}
31 | {{roleName}} {{$t('Permission')}}
32 |
33 |
34 |
35 |
36 |
37 | {{$t('Save')}}
38 | {{$t('Cancel')}}
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 | {{$t('Module function')}}
52 |
53 |
54 |
55 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
248 |
--------------------------------------------------------------------------------
/src/pages/permission/roleuser.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
8 |
9 |
11 |
12 |
13 |
14 | {{$t('Search')}}
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 | {{$t('Editing role')}}
31 | {{roleName}} {{$t('User under')}}
32 |
33 |
34 |
35 |
37 |
38 |
39 |
40 | {{$t('Search')}}
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
245 |
--------------------------------------------------------------------------------
/src/pages/permission/userrole.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
7 |
8 |
9 |
10 | {{$t('Search')}}
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 | {{$t('Edit user')}}
27 | {{userName}} {{$t('List of roles')}}
28 |
29 |
30 |
31 |
33 |
34 |
35 |
36 | {{$t('Search')}}
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
245 |
--------------------------------------------------------------------------------
/src/pages/user/user.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
7 |
8 |
9 |
10 | {{$t('Search')}}
11 | {{$t('Add')}}
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 | {{$t('Edit')}}
32 |
33 |
34 |
35 |
36 |
37 | {{$t('Save')}}
38 | {{$t('Cancel')}}
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
248 |
--------------------------------------------------------------------------------
/src/pages/user/userinfo.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/src/plugins/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wjkang/vue-quasar-admin/9769a6fdd59ec2965797ce5cc0543fb363fb660c/src/plugins/.gitkeep
--------------------------------------------------------------------------------
/src/plugins/demo-block.js:
--------------------------------------------------------------------------------
1 | import DemoBlock from '@/components/DemoBlock.vue'
2 |
3 | export default ({ Vue }) => {
4 | Vue.component('demo-block', DemoBlock);
5 | }
--------------------------------------------------------------------------------
/src/plugins/i18n.js:
--------------------------------------------------------------------------------
1 | // we import the external package
2 | import VueI18n from 'vue-i18n'
3 |
4 | // let's say we have a file in /src/i18n containing the language pack
5 | import messages from 'src/i18n'
6 |
7 | export default ({ app, router, store, Vue }) => {
8 | // we tell Vue to use our Vue package:
9 | Vue.use(VueI18n)
10 |
11 | // Set i18n instance on app;
12 | // We inject it into root component by doing so;
13 | // new Vue({..., i18n: ... }).$mount(...)
14 |
15 | app.i18n = new VueI18n({
16 | locale: 'zh-hans', // zh-hans, en-us, pt-br
17 | fallbackLocale: 'zh-hans',
18 | messages
19 | })
20 | }
21 |
22 |
--------------------------------------------------------------------------------
/src/plugins/permission.js:
--------------------------------------------------------------------------------
1 | export default ({ app, router, store, Vue }) => {
2 | Vue.directive('permission', {
3 | bind: function (el, binding, vnode) {
4 | let needPermissions = binding.value;
5 | let permissions = JSON.parse(localStorage.getItem('permission'));
6 | let isAdmin=localStorage.getItem('isAdmin');
7 | let hasPermission = permissions.some(s => {
8 | return needPermissions.indexOf(s) > -1;
9 | })
10 | if (!hasPermission&&isAdmin==0) {
11 | el.style.display = "none";
12 | }
13 | }
14 | })
15 | }
--------------------------------------------------------------------------------
/src/plugins/vuelidate.js:
--------------------------------------------------------------------------------
1 | import Vuelidate from 'vuelidate'
2 |
3 | export default ({ Vue }) => {
4 | Vue.use(Vuelidate)
5 | }
--------------------------------------------------------------------------------
/src/router/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import VueRouter from 'vue-router'
3 | import Util from '@/libs/util'
4 | import { routes } from './routes'
5 | import { getToken } from '@/libs/auth'
6 | import store from '@/store'
7 |
8 | Vue.use(VueRouter)
9 |
10 | const Router = new VueRouter({
11 | /*
12 | * NOTE! Change Vue Router mode from quasar.conf.js -> build -> vueRouterMode
13 | *
14 | * If you decide to go with "history" mode, please also set "build.publicPath"
15 | * to something other than an empty string.
16 | * Example: '/' instead of ''
17 | */
18 |
19 | // Leave as is and change from quasar.conf.js instead!
20 | mode: process.env.VUE_ROUTER_MODE,
21 | base: process.env.VUE_ROUTER_BASE,
22 | scrollBehavior: () => ({ y: 0 }),
23 | routes
24 | })
25 |
26 | const whiteList = ['/login', '/403']// 设置白名单,避免死循环
27 |
28 | function hasPermission(router, accessMenu) {
29 | if (whiteList.indexOf(router.path) !== -1) {
30 | return true;
31 | }
32 | let menu = Util.getMenuByName(router.name, accessMenu);
33 | if (menu.name) {
34 | return true;
35 | }
36 | return false;
37 |
38 | }
39 |
40 | //地址栏改变,比$route(to)先触发
41 | Router.beforeEach(async (to, from, next) => {
42 | if (getToken()) {
43 | let userInfo = store.state.user.userInfo;
44 | if (!userInfo.name) {
45 | try {
46 | await store.dispatch("GetUserInfo")
47 | await store.dispatch('updateAccessMenu')
48 | if (to.path === '/login') {
49 | next({ name: 'home_index' })
50 | } else {
51 | //Util.toDefaultPage([...routers], to.name, router, next);
52 | next({ ...to, replace: true })//菜单权限更新完成,重新进一次当前路由
53 | }
54 | }
55 | catch (e) {
56 | if (whiteList.indexOf(to.path) !== -1) { // 在免登录白名单,直接进入
57 | next()
58 | } else {
59 | next('/login')
60 | }
61 | }
62 | } else {
63 | if (to.path === '/login') {
64 | next({ name: 'home_index' })
65 | } else {
66 | if (hasPermission(to, store.getters.accessMenu)) {
67 | Util.toDefaultPage(store.getters.accessMenu,to, routes, next);
68 | } else {
69 | next({ path: '/403',replace:true })
70 | }
71 | }
72 | }
73 | } else {
74 | if (whiteList.indexOf(to.path) !== -1) { // 在免登录白名单,直接进入
75 | next()
76 | } else {
77 | next('/login')
78 | }
79 | }
80 | let menu = Util.getMenuByName(to.name, store.getters.accessMenu);
81 | Util.title(menu.title);
82 | });
83 |
84 | Router.afterEach((to) => {
85 | window.scrollTo(0, 0);
86 | });
87 |
88 | export default Router
89 |
--------------------------------------------------------------------------------
/src/router/routes.js:
--------------------------------------------------------------------------------
1 |
2 | const layout = () => import('layouts/common');
3 |
4 | //不作为Main组件的子页面展示的页面单独写,如下
5 | const loginRouter = {
6 | path: '/login',
7 | name: 'login',
8 | component: () => import('pages/login')
9 | };
10 |
11 |
12 | const page403 = {
13 | path: '/403',
14 | name: '403',
15 | component: () => import('pages/403')
16 | };
17 |
18 | // 作为layout组件的子页面展示但是不在左侧菜单显示的路由写在otherRouter里(children至少包含一个子路由)
19 | const otherRouter = {
20 | path: '/',
21 | name: 'otherRouter',
22 | component: layout,
23 | children: [
24 | {
25 | path: 'home',
26 | name: 'home_index',
27 | component: () => import('pages/index')
28 | },
29 | {
30 | path: 'userinfo',
31 | name: 'userinfo',
32 | component: () => import('pages/user/userinfo')
33 | },
34 | {
35 | path: 'requestlog',
36 | name: 'requestlog',
37 | component: () => import('pages/other/requestlog')
38 | }
39 | ]
40 | };
41 | // 作为layout组件的子页面展示并且在左侧菜单显示的路由写在appRouter里(children至少包含一个子路由)
42 | const appRouter = [
43 | {
44 | path: '/cms',
45 | name: 'CMS',
46 | component: layout,
47 | children: [
48 | {
49 | path: 'article',
50 | name: 'article',
51 | component: () => import('pages/cms/post.vue')
52 | },
53 | {
54 | path: 'article/:id',
55 | name: 'post_edit',
56 | component: () => import('pages/cms/post_edit.vue')
57 | },
58 | {
59 | path: 'comment',
60 | name: 'comment',
61 | component: () => import('pages/cms/comment.vue')
62 | },
63 | ]
64 | },
65 | {
66 | path: '/system',
67 | name: 'system settings',
68 | component: layout,
69 | children: [
70 | {
71 | path: 'menu',
72 | name: 'menu',
73 | component: () => import('pages/system/menu.vue')
74 | }
75 | ]
76 | },
77 | {
78 | path: '/permission',
79 | name: 'permission',
80 | component: layout,
81 | children: [
82 | {
83 | path: 'function',
84 | name: 'function',
85 | component: () => import('pages/permission/function.vue')
86 | },
87 | {
88 | path: 'role',
89 | name: 'role',
90 | component: () => import('pages/permission/role.vue')
91 | },
92 | {
93 | path: 'rolepermission',
94 | name: 'rolepermission',
95 | component: () => import('pages/permission/rolepermission.vue')
96 | },
97 | {
98 | path: 'roleuser',
99 | name: 'roleuser',
100 | component: () => import('pages/permission/roleuser.vue')
101 | },
102 | {
103 | path: 'userrole',
104 | name: 'userrole',
105 | component: () => import('pages/permission/userrole.vue')
106 | }
107 | ]
108 | },
109 | {
110 | path: '/organization',
111 | name: 'organization',
112 | component: layout,
113 | children: [
114 | {
115 | path: 'department',
116 | name: 'department',
117 | component: () => import('pages/organization/department.vue')
118 | },
119 | {
120 | path: 'position',
121 | name: 'position',
122 | component: () => import('pages/organization/position.vue')
123 | }
124 | ]
125 | },
126 | {
127 | path: '/user',
128 | name: 'user',
129 | component: layout,
130 | children: [
131 | {
132 | path: 'index',
133 | name: 'user_index',
134 | component: () => import('pages/user/user.vue')
135 | }
136 | ]
137 | },
138 | {
139 | path: '/business',
140 | name: 'business',
141 | component: layout,
142 | children: [
143 | {
144 | path: 'sku',
145 | name: 'sku',
146 | component: () => import('pages/develop/business/sku.vue')
147 | }
148 | ]
149 | }
150 | ];
151 |
152 | const developRouter = [
153 | {
154 | path: '/official',
155 | name: 'official',
156 | component: layout,
157 | children: [
158 | {
159 | path: 'button',
160 | name: 'button',
161 | component: () => import('pages/develop/official/button.md')
162 | },
163 | {
164 | path: 'button-group',
165 | name: 'button-group',
166 | component: () => import('pages/develop/official/button-group.md')
167 | },
168 | {
169 | path: 'dropdown-button',
170 | name: 'dropdown-button',
171 | component: () => import('pages/develop/official/dropdown-button.md')
172 | },
173 | {
174 | path: 'toolbar',
175 | name: 'toolbar',
176 | component: () => import('pages/develop/official/toolbar.md')
177 | }
178 | ]
179 | }
180 | ]
181 |
182 | // 所有上面定义的路由都要写在下面的routers里
183 | export const routes = [
184 | loginRouter,
185 | page403,
186 | otherRouter,
187 | ...appRouter,
188 | ...developRouter
189 | ];
190 |
191 |
--------------------------------------------------------------------------------
/src/service/cms/post.js:
--------------------------------------------------------------------------------
1 | import request from '@/libs/request'
2 |
3 | export function getPostPagedList(query) {
4 | return request({
5 | url: '/post/pagedlist',
6 | method: 'get',
7 | params: query
8 | })
9 | }
10 |
11 | export function getPost(id) {
12 | return request({
13 | url: '/post/' + id,
14 | method: 'get',
15 | loading: "hourglass"
16 | })
17 | }
18 |
19 | export function savePost(post) {
20 | return request({
21 | url: '/post/save',
22 | method: 'post',
23 | data: post,
24 | loading: "hourglass"
25 | })
26 | }
27 |
28 | export function getTopPostByQuery(query) {
29 | return request({
30 | url: '/post/top',
31 | method: 'get',
32 | params: query,
33 | loading: "gears"
34 | })
35 | }
--------------------------------------------------------------------------------
/src/service/login.js:
--------------------------------------------------------------------------------
1 | import request from '@/libs/request'
2 | import qs from 'qs'
3 |
4 | export function loginByUsername(username, password) {
5 | const data = {
6 | username,
7 | password
8 | }
9 | return request({
10 | url: '/auth/login',
11 | method: 'post',
12 | data: qs.stringify(data)
13 | })
14 | }
15 |
16 | export function logout() {
17 | return request({
18 | url: '/auth/logout',
19 | method: 'post',
20 | loading:"hourglass"
21 | })
22 | }
23 |
24 | export function getUserInfo() {
25 | return request({
26 | url: '/user/info',
27 | method: 'get',
28 | loading:"gears"
29 | })
30 | }
--------------------------------------------------------------------------------
/src/service/other/requestlog.js:
--------------------------------------------------------------------------------
1 | import request from '@/libs/request'
2 |
3 | export function getRequestLogPagedList(query) {
4 | return request({
5 | url: '/requestlog/pagedlist',
6 | method: 'get',
7 | params: query
8 | })
9 | }
--------------------------------------------------------------------------------
/src/service/other/resetdb.js:
--------------------------------------------------------------------------------
1 | import request from '@/libs/request'
2 |
3 | export function resetDb() {
4 | return request({
5 | url: '/resetdb',
6 | method: 'post',
7 | loading:"hourglass"
8 | })
9 | }
--------------------------------------------------------------------------------
/src/service/permission/function.js:
--------------------------------------------------------------------------------
1 | import request from '@/libs/request'
2 | import qs from 'qs'
3 |
4 | export function getMenuListFunctionCode() {
5 | return request({
6 | url: '/function/menulistfunctioncode',
7 | method: 'get',
8 | loading:"gears"
9 | })
10 | }
11 |
12 | export function getFunctionPagedList(query) {
13 | return request({
14 | url: '/function/pagedlist',
15 | method: 'get',
16 | params: query
17 | })
18 | }
19 |
20 | export function delFunction(id) {
21 | return request({
22 | url: '/function/del',
23 | method: 'delete',
24 | params: id,
25 | loading:"hourglass"
26 | })
27 | }
28 |
29 | export function delFunctions(ids) {
30 | return request({
31 | url: '/function/batchdel',
32 | method: 'delete',
33 | params:ids,
34 | loading:"hourglass"
35 | })
36 | }
37 |
38 | export function saveFunction(data) {
39 | return request({
40 | url: '/function/save',
41 | method: 'post',
42 | data: data,
43 | loading:'hourglass'
44 | })
45 | }
--------------------------------------------------------------------------------
/src/service/permission/role.js:
--------------------------------------------------------------------------------
1 | import request from '@/libs/request'
2 |
3 | export function getRolePagedList(query) {
4 | return request({
5 | url: '/role/pagedlist',
6 | method: 'get',
7 | params: query
8 | })
9 | }
10 |
11 | export function delRole(id) {
12 | return request({
13 | url: '/role/del',
14 | method: 'delete',
15 | params: id,
16 | loading:"hourglass"
17 | })
18 | }
19 |
20 | export function delRoles(ids) {
21 | return request({
22 | url: '/role/batchdel',
23 | method: 'delete',
24 | params:ids,
25 | loading:"hourglass"
26 | })
27 | }
28 |
29 | export function saveRole(data) {
30 | return request({
31 | url: '/role/save',
32 | method: 'post',
33 | data: data,
34 | loading:"hourglass"
35 | })
36 | }
37 |
38 | export function savePermission(data){
39 | return request({
40 | url: '/role/savepermission',
41 | method: 'post',
42 | data: data,
43 | loading:"hourglass"
44 | })
45 | }
46 |
--------------------------------------------------------------------------------
/src/service/system/menu.js:
--------------------------------------------------------------------------------
1 | import request from '@/libs/request'
2 | import qs from 'qs'
3 |
4 | export function getAccessMemu() {
5 | return request({
6 | url: '/menu/getaccessmenu',
7 | method: 'get',
8 | loading:"gears"
9 | })
10 | }
11 |
12 | export function getAllMenu(){
13 | return request({
14 | url: '/menu',
15 | method: 'get',
16 | loading:"gears"
17 | })
18 | }
19 |
20 | export function saveMenu(menu){
21 | return request({
22 | url: '/menu/savemenu',
23 | method: 'post',
24 | data:menu,
25 | loading:"hourglass",
26 | permission:["menu_edit"]
27 | })
28 | }
29 |
30 | export function getMenuFunctions(menuId){
31 | return request({
32 | url: '/menu/menufunctions',
33 | method: 'get',
34 | params:menuId,
35 | loading:"gears"
36 | })
37 | }
38 |
39 | export function getIcons(){
40 | return request({
41 | url: '/icons',
42 | method: 'get',
43 | loading:"gears"
44 | })
45 | }
--------------------------------------------------------------------------------
/src/service/user/user.js:
--------------------------------------------------------------------------------
1 | import request from '@/libs/request'
2 |
3 | export function getUserList() {
4 | return request({
5 | url: '/user/userlist',
6 | method: 'get'
7 | })
8 | }
9 | export function getUserPagedList(query) {
10 | return request({
11 | url: '/user/pagedlist',
12 | method: 'get',
13 | params: query
14 | })
15 | }
16 |
17 | export function delUser(id) {
18 | return request({
19 | url: '/user/del',
20 | method: 'delete',
21 | params: id,
22 | loading:"hourglass"
23 | })
24 | }
25 |
26 | export function delUsers(ids) {
27 | return request({
28 | url: '/user/batchdel',
29 | method: 'delete',
30 | params:ids,
31 | loading:"hourglass"
32 | })
33 | }
34 |
35 | export function saveUser(data) {
36 | return request({
37 | url: '/user/save',
38 | method: 'post',
39 | data: data,
40 | loading:"hourglass"
41 | })
42 | }
43 |
44 | export function editRoleUser(data){
45 | return request({
46 | url: '/user/editroleuser',
47 | method: 'post',
48 | data: data,
49 | loading:"hourglass"
50 | })
51 | }
--------------------------------------------------------------------------------
/src/statics/icons/apple-icon-152x152.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wjkang/vue-quasar-admin/9769a6fdd59ec2965797ce5cc0543fb363fb660c/src/statics/icons/apple-icon-152x152.png
--------------------------------------------------------------------------------
/src/statics/icons/favicon-16x16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wjkang/vue-quasar-admin/9769a6fdd59ec2965797ce5cc0543fb363fb660c/src/statics/icons/favicon-16x16.png
--------------------------------------------------------------------------------
/src/statics/icons/favicon-32x32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wjkang/vue-quasar-admin/9769a6fdd59ec2965797ce5cc0543fb363fb660c/src/statics/icons/favicon-32x32.png
--------------------------------------------------------------------------------
/src/statics/icons/icon-128x128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wjkang/vue-quasar-admin/9769a6fdd59ec2965797ce5cc0543fb363fb660c/src/statics/icons/icon-128x128.png
--------------------------------------------------------------------------------
/src/statics/icons/icon-192x192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wjkang/vue-quasar-admin/9769a6fdd59ec2965797ce5cc0543fb363fb660c/src/statics/icons/icon-192x192.png
--------------------------------------------------------------------------------
/src/statics/icons/icon-256x256.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wjkang/vue-quasar-admin/9769a6fdd59ec2965797ce5cc0543fb363fb660c/src/statics/icons/icon-256x256.png
--------------------------------------------------------------------------------
/src/statics/icons/icon-384x384.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wjkang/vue-quasar-admin/9769a6fdd59ec2965797ce5cc0543fb363fb660c/src/statics/icons/icon-384x384.png
--------------------------------------------------------------------------------
/src/statics/icons/icon-512x512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wjkang/vue-quasar-admin/9769a6fdd59ec2965797ce5cc0543fb363fb660c/src/statics/icons/icon-512x512.png
--------------------------------------------------------------------------------
/src/statics/icons/ms-icon-144x144.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wjkang/vue-quasar-admin/9769a6fdd59ec2965797ce5cc0543fb363fb660c/src/statics/icons/ms-icon-144x144.png
--------------------------------------------------------------------------------
/src/statics/quasar-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wjkang/vue-quasar-admin/9769a6fdd59ec2965797ce5cc0543fb363fb660c/src/statics/quasar-logo.png
--------------------------------------------------------------------------------
/src/store/getters.js:
--------------------------------------------------------------------------------
1 | const getters = {
2 | cachePage: state => state.app.cachePage,
3 | pageOpenedList: state => state.app.pageOpenedList,
4 | currentPath:state=>state.app.currentPath,
5 | accessMenu:state=>state.app.accessMenu,
6 | }
7 | export default getters
8 |
--------------------------------------------------------------------------------
/src/store/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue';
2 | import Vuex from 'vuex';
3 |
4 | import app from './modules/app';
5 | import user from './modules/user';
6 | import getters from './getters'
7 |
8 | Vue.use(Vuex);
9 |
10 | const store = new Vuex.Store({
11 | mutations: {
12 | //
13 | },
14 | actions: {
15 |
16 | },
17 | modules: {
18 | app,
19 | user
20 | },
21 | getters
22 | });
23 |
24 | export default store;
25 |
--------------------------------------------------------------------------------
/src/store/modules/app.js:
--------------------------------------------------------------------------------
1 | import Util from '@/libs/util';
2 | import { getAccessMemu } from '@/service/system/menu'
3 | import { defaultAccessMenu } from '@/default-access-menu'
4 |
5 | const app = {
6 | state: {
7 | currentPath: [
8 | {
9 | title: 'Home',
10 | path: '',
11 | name: 'home_index'
12 | }
13 | ], // 面包屑数组
14 | pageOpenedList: [
15 | {
16 | title: 'Home',
17 | path: '',
18 | name: 'home_index'
19 | }
20 | ],//打开的标签
21 | cachePage: [],//缓存的页面
22 | dontCache: ["home_index"], // 在这里定义你不想要缓存的页面的name属性值
23 | currentModule: '',//当前模块
24 | accessMenu: [],//可访问的菜单,
25 | openAccessMenu: [],//展开的可访问的菜单(子级包含父级name)
26 | moduleList: [],//模块列表
27 | moduleMenu: [],//模块菜单
28 | },
29 | mutations: {
30 | setCurrentPath(state, pathArr) {
31 | state.currentPath = pathArr;
32 | },
33 | setCurrentModule(state, module) {
34 | state.currentModule = module;
35 | },
36 | setAccessMenu(state, list) {
37 | state.accessMenu = list;
38 | },
39 | setOpenAccessMenu(state, list) {
40 | state.openAccessMenu = list;
41 | },
42 | setModuleList(state, list) {
43 | state.moduleList = list
44 | },
45 | setModuleMenu(state, list) {
46 | state.moduleMenu = list
47 | },
48 | pageOpenedList(state, get) {
49 | let openedPage = state.pageOpenedList[get.index];
50 | if (get.argu) {
51 | openedPage.argu = get.argu;
52 | }
53 | if (get.query) {
54 | openedPage.query = get.query;
55 | }
56 | //替换新标签
57 | state.pageOpenedList.splice(get.index, 1, openedPage);
58 | localStorage.pageOpenedList = JSON.stringify(state.pageOpenedList);
59 | },
60 | increateTag(state, tagObj) {
61 | if (!Util.oneOf(tagObj.name, state.dontCache)) {
62 | state.cachePage.push(tagObj.name);
63 | localStorage.cachePage = JSON.stringify(state.cachePage);
64 | }
65 | state.pageOpenedList.push(tagObj);
66 | localStorage.pageOpenedList = JSON.stringify(state.pageOpenedList);
67 | },
68 | closePage(state, name) {
69 | for (const [i, v] of state.cachePage.entries()) {
70 | if (v === name) {
71 | state.cachePage.splice(i, 1)
72 | break
73 | }
74 | }
75 | for (const [i, v] of state.pageOpenedList.entries()) {
76 | if (v.name === name) {
77 | state.pageOpenedList.splice(i, 1)
78 | break
79 | }
80 | }
81 | },
82 | closePages(state, data) {
83 | let type = data.type;
84 | let name = data.name;
85 | if (type === "all") {
86 | state.pageOpenedList = [{
87 | title: 'Home',
88 | path: '',
89 | name: 'home_index'
90 | }]
91 | state.cachePage = []
92 | } else {
93 | for (const [i, v] of state.cachePage.entries()) {
94 | if (v === name) {
95 | state.cachePage = state.cachePage.splice(i, 1)
96 | break
97 | }
98 | }
99 | for (const [i, v] of state.pageOpenedList.entries()) {
100 | if (v.name === name) {
101 | state.pageOpenedList = state.pageOpenedList.splice(i, 1, )
102 | if (name !== "home_index") {
103 | state.pageOpenedList.unshift({
104 | title: 'Home',
105 | path: '',
106 | name: 'home_index'
107 | })
108 | }
109 | break
110 | }
111 | }
112 | }
113 | }
114 | },
115 | actions: {
116 | async updateAccessMenu({ commit }) {
117 | let accesseMenu = defaultAccessMenu;
118 | try {
119 | let response = await getAccessMemu();
120 | accesseMenu = response.data.data;
121 | } catch (e) {
122 |
123 | }
124 | let openAccesseMenu = Util.openAccesseMenu(accesseMenu);
125 | let moduleList = accesseMenu.filter(item => {
126 | return item.leftMemu
127 | });
128 | let currentModule = moduleList[0].name;
129 | let moduleMenu = moduleList[0].children;
130 |
131 | commit('setModuleMenu', moduleMenu);
132 | commit('setCurrentModule', currentModule);
133 | commit('setModuleList', moduleList);
134 | commit('setAccessMenu', accesseMenu);
135 | commit('setOpenAccessMenu', openAccesseMenu);
136 | },
137 | changeModule({ commit, state }, module) {
138 | let accesseMenu = state.accessMenu;
139 | let moduleList = accesseMenu.filter(item => {
140 | return item.leftMemu && item.name === module
141 | });
142 | let moduleMenu = moduleList[0].children;
143 | commit('setModuleMenu', moduleMenu);
144 | commit('setCurrentModule', module);
145 | },
146 | closePage({ commit, state }, name) {
147 | return new Promise((resolve) => {
148 | commit('closePage', name)
149 | resolve([...state.pageOpenedList])
150 | })
151 | },
152 | closePages({ commit, state }, data) {
153 | return new Promise((resolve) => {
154 | commit('closePages', data)
155 | resolve([...state.pageOpenedList])
156 | })
157 | }
158 | }
159 | };
160 |
161 | export default app;
162 |
--------------------------------------------------------------------------------
/src/store/modules/user.js:
--------------------------------------------------------------------------------
1 | import * as authService from '@/libs/auth'
2 | import * as loginService from '@/service/login'
3 |
4 | const user = {
5 | state: {
6 | token: authService.getToken(),
7 | userInfo: {
8 | name: '',
9 | avatar: ''
10 | }
11 | },
12 | mutations: {
13 | SET_TOKEN(state, token) {
14 | state.token = token
15 | },
16 | SET_USERINFO(state, userInfo) {
17 | state.userInfo = userInfo
18 | }
19 | },
20 | actions: {
21 | //用户名登录
22 | LoginByUserName({ commit }, userinfo) {
23 | const username = userinfo.username.trim()
24 | return new Promise((resolve, reject) => {
25 | loginService.loginByUsername(username, userinfo.password).then(response => {
26 | const data = response.data.data
27 | commit('SET_TOKEN', data.accessToken)
28 | authService.setToken(data.accessToken)
29 | resolve()
30 | }).catch(error => {
31 | reject(error)
32 | })
33 | })
34 | },
35 | // 登出
36 | LogOut({ commit }, state) {
37 | return new Promise((resolve, reject) => {
38 | loginService.logout().then((response) => {
39 | commit('SET_TOKEN', '')
40 | commit('SET_USERINFO', {
41 | name: '',
42 | avatar: ''
43 | })
44 | authService.removeToken()
45 | resolve()
46 | }).catch(error => {
47 | commit('SET_TOKEN', '')
48 | commit('SET_USERINFO', {
49 | name: '',
50 | avatar: ''
51 | })
52 | authService.removeToken()
53 | reject(error)
54 | })
55 | })
56 | },
57 | GetUserInfo({ commit }, state) {
58 | return new Promise((resolve, reject) => {
59 | loginService.getUserInfo().then((response) => {
60 | const data = response.data.data
61 | const userInfo = {
62 | name: data.userName,
63 | avatar: data.avatarUrl
64 | }
65 | commit('SET_USERINFO', userInfo)
66 | let userRole = data.userRole
67 | let userPermission = data.userPermission
68 | let permission = [...userRole, ...userPermission]
69 | let isAdmin = data.isAdmin
70 | localStorage.setItem("permission", JSON.stringify(permission))
71 | localStorage.setItem("isAdmin", isAdmin)
72 | resolve(data)
73 | }).catch(error => {
74 | reject(error)
75 | })
76 | })
77 | }
78 | }
79 | };
80 |
81 | export default user;
82 |
--------------------------------------------------------------------------------
/strip-tags.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * strip-tags
3 | *
4 | * Copyright (c) 2015 Jon Schlinkert, contributors.
5 | * Licensed under the MIT license.
6 | */
7 |
8 | 'use strict';
9 |
10 | var cheerio = require('cheerio');
11 |
12 | exports.strip = function(str, tags) {
13 | var $ = cheerio.load(str, {decodeEntities: false});
14 |
15 | if (!tags || tags.length === 0) {
16 | return str;
17 | }
18 |
19 | tags = !Array.isArray(tags) ? [tags] : tags;
20 | var len = tags.length;
21 |
22 | while (len--) {
23 | $(tags[len]).remove();
24 | }
25 |
26 | return $("body").html();
27 | };
28 |
29 | exports.fetch = function(str, tag) {
30 | var $ = cheerio.load(str, {decodeEntities: false});
31 | if (!tag) return str;
32 |
33 | return $(tag).html();
34 | };
--------------------------------------------------------------------------------