Commit 50760eab92891e7022d2759fd55c1f173659e9d8

Authored by Adam
1 parent 3d3cdb68fc
Exists in master

auto commit the code by alias command

... ... @@ -27,12 +27,18 @@ for (let i = 0; i < count; i++) {
27 27 }))
28 28 }
29 29  
30   -export default [
31   - {
32   - url: '/vue-element-admin/article/list',
  30 +export default [{
  31 + url: '/yp/article/list',
33 32 type: 'get',
34 33 response: config => {
35   - const { importance, type, title, page = 1, limit = 20, sort } = config.query
  34 + const {
  35 + importance,
  36 + type,
  37 + title,
  38 + page = 1,
  39 + limit = 20,
  40 + sort
  41 + } = config.query
36 42  
37 43 let mockList = List.filter(item => {
38 44 if (importance && item.importance !== +importance) return false
... ... @@ -58,10 +64,12 @@ export default [
58 64 },
59 65  
60 66 {
61   - url: '/vue-element-admin/article/detail',
  67 + url: '/yp/article/detail',
62 68 type: 'get',
63 69 response: config => {
64   - const { id } = config.query
  70 + const {
  71 + id
  72 + } = config.query
65 73 for (const article of List) {
66 74 if (article.id === +id) {
67 75 return {
... ... @@ -74,17 +82,28 @@ export default [
74 82 },
75 83  
76 84 {
77   - url: '/vue-element-admin/article/pv',
  85 + url: '/yp/article/pv',
78 86 type: 'get',
79 87 response: _ => {
80 88 return {
81 89 code: 20000,
82 90 data: {
83   - pvData: [
84   - { key: 'PC', pv: 1024 },
85   - { key: 'mobile', pv: 1024 },
86   - { key: 'ios', pv: 1024 },
87   - { key: 'android', pv: 1024 }
  91 + pvData: [{
  92 + key: 'PC',
  93 + pv: 1024
  94 + },
  95 + {
  96 + key: 'mobile',
  97 + pv: 1024
  98 + },
  99 + {
  100 + key: 'ios',
  101 + pv: 1024
  102 + },
  103 + {
  104 + key: 'android',
  105 + pv: 1024
  106 + }
88 107 ]
89 108 }
90 109 }
... ... @@ -92,7 +111,7 @@ export default [
92 111 },
93 112  
94 113 {
95   - url: '/vue-element-admin/article/create',
  114 + url: '/yp/article/create',
96 115 type: 'post',
97 116 response: _ => {
98 117 return {
... ... @@ -103,7 +122,7 @@ export default [
103 122 },
104 123  
105 124 {
106   - url: '/vue-element-admin/article/update',
  125 + url: '/yp/article/update',
107 126 type: 'post',
108 127 response: _ => {
109 128 return {
... ... @@ -113,4 +132,3 @@ export default [
113 132 }
114 133 }
115 134 ]
116   -
... ...
mock/remote-search.js
... ... @@ -13,7 +13,7 @@ NameList.push({ name: 'mock-Pan' })
13 13 export default [
14 14 // username search
15 15 {
16   - url: '/vue-element-admin/search/user',
  16 + url: '/yp/search/user',
17 17 type: 'get',
18 18 response: config => {
19 19 const { name } = config.query
... ... @@ -30,7 +30,7 @@ export default [
30 30  
31 31 // transaction list
32 32 {
33   - url: '/vue-element-admin/transaction/list',
  33 + url: '/yp/transaction/list',
34 34 type: 'get',
35 35 response: _ => {
36 36 return {
... ...
mock/role/index.js
... ... @@ -50,7 +50,7 @@ const roles = [
50 50 export default [
51 51 // mock get all routes form server
52 52 {
53   - url: '/vue-element-admin/routes',
  53 + url: '/yp/routes',
54 54 type: 'get',
55 55 response: _ => {
56 56 return {
... ... @@ -62,7 +62,7 @@ export default [
62 62  
63 63 // mock get all roles form server
64 64 {
65   - url: '/vue-element-admin/roles',
  65 + url: '/yp/roles',
66 66 type: 'get',
67 67 response: _ => {
68 68 return {
... ... @@ -74,7 +74,7 @@ export default [
74 74  
75 75 // add role
76 76 {
77   - url: '/vue-element-admin/role',
  77 + url: '/yp/role',
78 78 type: 'post',
79 79 response: {
80 80 code: 20000,
... ... @@ -86,7 +86,7 @@ export default [
86 86  
87 87 // update role
88 88 {
89   - url: '/vue-element-admin/role/[A-Za-z0-9]',
  89 + url: '/yp/role/[A-Za-z0-9]',
90 90 type: 'put',
91 91 response: {
92 92 code: 20000,
... ... @@ -98,7 +98,7 @@ export default [
98 98  
99 99 // delete role
100 100 {
101   - url: '/vue-element-admin/role/[A-Za-z0-9]',
  101 + url: '/yp/role/[A-Za-z0-9]',
102 102 type: 'delete',
103 103 response: {
104 104 code: 20000,
... ...
mock/role/routes.js
... ... @@ -23,13 +23,23 @@ export const constantRoutes = [
23 23 hidden: true
24 24 },
25 25 {
  26 + path: '/401',
  27 + component: 'views/error-page/401',
  28 + hidden: true
  29 + },
  30 + {
  31 + path: '/403',
  32 + component: 'views/error-page/403',
  33 + hidden: true
  34 + },
  35 + {
26 36 path: '/404',
27 37 component: 'views/error-page/404',
28 38 hidden: true
29 39 },
30 40 {
31   - path: '/401',
32   - component: 'views/error-page/401',
  41 + path: '/500',
  42 + component: 'views/error-page/500',
33 43 hidden: true
34 44 },
35 45 {
... ... @@ -73,46 +83,46 @@ export const constantRoutes = [
73 83 ]
74 84  
75 85 export const asyncRoutes = [
76   - {
77   - path: '/permission',
78   - component: 'layout/Layout',
79   - redirect: '/permission/index',
80   - alwaysShow: true,
81   - meta: {
82   - title: 'permission',
83   - icon: 'lock',
84   - roles: ['admin', 'assistant', 'runner', 'shoper']
85   - },
86   - children: [
87   - {
88   - path: 'page',
89   - component: 'views/permission/page',
90   - name: 'PagePermission',
91   - meta: {
92   - title: 'pagePermission',
93   - roles: ['admin','assistant']
94   - }
95   - },
96   - {
97   - path: 'directive',
98   - component: 'views/permission/directive',
99   - name: 'DirectivePermission',
100   - meta: {
101   - title: 'directivePermission',
102   - roles:['shoper']
103   - }
104   - },
105   - {
106   - path: 'role',
107   - component: 'views/permission/role',
108   - name: 'RolePermission',
109   - meta: {
110   - title: 'rolePermission',
111   - roles: ['runner']
112   - }
113   - }
114   - ]
115   - },
  86 + // {
  87 + // path: '/permission',
  88 + // component: 'layout/Layout',
  89 + // redirect: '/permission/index',
  90 + // alwaysShow: true,
  91 + // meta: {
  92 + // title: 'permission',
  93 + // icon: 'lock',
  94 + // // roles: ['admin', 'assistant', 'runner', 'shoper']
  95 + // },
  96 + // children: [
  97 + // {
  98 + // path: 'page',
  99 + // component: 'views/permission/page',
  100 + // name: 'PagePermission',
  101 + // meta: {
  102 + // title: 'pagePermission',
  103 + // roles: ['admin','assistant']
  104 + // }
  105 + // },
  106 + // {
  107 + // path: 'directive',
  108 + // component: 'views/permission/directive',
  109 + // name: 'DirectivePermission',
  110 + // meta: {
  111 + // title: 'directivePermission',
  112 + // roles:['shoper']
  113 + // }
  114 + // },
  115 + // {
  116 + // path: 'role',
  117 + // component: 'views/permission/role',
  118 + // name: 'RolePermission',
  119 + // meta: {
  120 + // title: 'rolePermission',
  121 + // roles: ['runner']
  122 + // }
  123 + // }
  124 + // ]
  125 + // },
116 126  
117 127 {
118 128 path: '/icon',
... ... @@ -385,6 +395,12 @@ export const asyncRoutes = [
385 395 component: 'views/error-page/404',
386 396 name: 'Page404',
387 397 meta: { title: 'page404', noCache: true }
  398 + },
  399 + {
  400 + path: '500',
  401 + component: 'views/error-page/500',
  402 + name: 'Page500',
  403 + meta: { title: 'page500', noCache: true }
388 404 }
389 405 ]
390 406 },
... ...
1 1  
  2 +import Mock from 'mockjs'
  3 +
2 4 const tokens = {
3 5 admin: {
4 6 token: 'admin-token'
... ... @@ -41,10 +43,40 @@ const users = {
41 43 }
42 44 }
43 45  
  46 +const List = []
  47 +const count = 100
  48 +
  49 +const baseContent = '<p>I am testing data, I am testing data.</p><p><img src="https://wpimg.wallstcn.com/4c69009c-0fd4-4153-b112-6cb53d1cf943"></p>'
  50 +const image_uri = 'https://wpimg.wallstcn.com/e4558086-631c-425c-9430-56ffb46e70b3'
  51 +
  52 +for (let i = 0; i < count; i++) {
  53 + List.push(Mock.mock({
  54 + uid: '@increment',
  55 + create_time: +Mock.Random.date('T'),
  56 + nickname: '@first',
  57 + reviewer: '@first',
  58 + title: '@title(5, 10)',
  59 + openid:'@sentence(12,12)',
  60 + content_short: 'mock data',
  61 + content: baseContent,
  62 + forecast: '@float(0, 100, 2, 2)',
  63 + importance: '@integer(1, 3)',
  64 + 'type|1': ['CN', 'US', 'JP', 'EU'],
  65 + 'status|1': ['published', 'draft'],
  66 + display_time: '@datetime',
  67 + comment_disabled: true,
  68 + son_of_adv: '@integer(300, 5000)',//下线
  69 + souceof:'@integer(300, 5000)',//源自
  70 + image_uri,
  71 + 'roles|1': ['admin', 'assistant', 'shoper', 'runner'],
  72 + platforms: ['a-platform']//哪个平台
  73 + }))
  74 +}
  75 +
44 76 export default [
45 77 // user login
46 78 {
47   - url: '/vue-element-admin/user/login',
  79 + url: '/yp/user/login',
48 80 type: 'post',
49 81 response: config => {
50 82 const { username } = config.body
... ... @@ -67,7 +99,7 @@ export default [
67 99  
68 100 // get user info
69 101 {
70   - url: '/vue-element-admin/user/info\.*',
  102 + url: '/yp/user/info\.*',
71 103 type: 'get',
72 104 response: config => {
73 105 const { token } = config.query
... ... @@ -90,7 +122,29 @@ export default [
90 122  
91 123 // user logout
92 124 {
93   - url: '/vue-element-admin/user/logout',
  125 + url: '/yp/user/logout',
  126 + type: 'post',
  127 + response: _ => {
  128 + return {
  129 + code: 20000,
  130 + data: 'success'
  131 + }
  132 + }
  133 + },
  134 + // user create
  135 + {
  136 + url: '/yp/user/create',
  137 + type: 'post',
  138 + response: _ => {
  139 + return {
  140 + code: 20000,
  141 + data: 'success'
  142 + }
  143 + }
  144 + },
  145 + // user update
  146 + {
  147 + url: '/yp/user/update',
94 148 type: 'post',
95 149 response: _ => {
96 150 return {
... ... @@ -98,5 +152,52 @@ export default [
98 152 data: 'success'
99 153 }
100 154 }
  155 + },
  156 + // user del
  157 + {
  158 + url: '/yp/user/del',
  159 + type: 'post',
  160 + response: _ => {
  161 + return {
  162 + code: 20000,
  163 + data: 'success'
  164 + }
  165 + }
  166 + },
  167 + // user list
  168 + {
  169 + url: '/yp/user/list',
  170 + type: 'get',
  171 + response: config => {
  172 + const {
  173 + importance,
  174 + type,
  175 + title,
  176 + page = 1,
  177 + limit = 20,
  178 + sort
  179 + } = config.query
  180 +
  181 + let mockList = List.filter(item => {
  182 + if (importance && item.importance !== +importance) return false
  183 + if (type && item.type !== type) return false
  184 + if (title && item.title.indexOf(title) < 0) return false
  185 + return true
  186 + })
  187 +
  188 + if (sort === '-id') {
  189 + mockList = mockList.reverse()
  190 + }
  191 +
  192 + const pageList = mockList.filter((item, index) => index < limit * page && index >= limit * (page - 1))
  193 +
  194 + return {
  195 + code: 20000,
  196 + data: {
  197 + total: mockList.length,
  198 + items: pageList
  199 + }
  200 + }
  201 + }
101 202 }
102 203 ]
... ...
... ... @@ -9,7 +9,7 @@
9 9 "build:prod": "vue-cli-service build",
10 10 "build:stage": "vue-cli-service build --mode staging",
11 11 "preview": "node build/index.js --preview",
12   - "lint": "eslint --ext .js,.vue src",
  12 + "lint": "eslint --fix --ext .js,.vue src",
13 13 "test:unit": "jest --clearCache && vue-cli-service test:unit",
14 14 "test:ci": "npm run lint && npm run test:unit",
15 15 "svgo": "svgo -f src/icons/svg --config=src/icons/svgo.yml",
... ... @@ -43,6 +43,7 @@
43 43 "url": "https://github.com/PanJiaChen/vue-element-admin/issues"
44 44 },
45 45 "dependencies": {
  46 + "ant-design-vue": "^1.5.5",
46 47 "axios": "0.18.1",
47 48 "clipboard": "2.0.4",
48 49 "codemirror": "5.45.0",
... ... @@ -55,14 +56,17 @@
55 56 "js-cookie": "2.2.0",
56 57 "jsonlint": "1.6.3",
57 58 "jszip": "3.2.1",
  59 + "less-loader": "^6.1.0",
58 60 "normalize.css": "7.0.0",
59 61 "nprogress": "0.2.0",
60 62 "path-to-regexp": "2.4.0",
61 63 "pinyin": "2.9.0",
  64 + "qs": "^6.9.4",
62 65 "screenfull": "4.2.0",
63 66 "showdown": "1.9.0",
64 67 "sortablejs": "1.8.4",
65 68 "tui-editor": "1.3.3",
  69 + "vant": "^2.8.0",
66 70 "vue": "2.6.10",
67 71 "vue-count-to": "1.0.13",
68 72 "vue-i18n": "7.3.2",
... ...
src/api/article.js
1 1 import request from '@/utils/request'
2 2  
  3 +// export const getPersonInfo = data => {
  4 +// return service({
  5 +// url: '/person_pay/getpersoninfo',
  6 +// method: 'post',
  7 +// data
  8 +// })
  9 +// }
  10 +
3 11 export function fetchList(query) {
4 12 return request({
5   - url: '/vue-element-admin/article/list',
  13 + url: '/yp/article/list',
6 14 method: 'get',
7 15 params: query
8 16 })
... ... @@ -10,23 +18,27 @@ export function fetchList(query) {
10 18  
11 19 export function fetchArticle(id) {
12 20 return request({
13   - url: '/vue-element-admin/article/detail',
  21 + url: '/yp/article/detail',
14 22 method: 'get',
15   - params: { id }
  23 + params: {
  24 + id
  25 + }
16 26 })
17 27 }
18 28  
19 29 export function fetchPv(pv) {
20 30 return request({
21   - url: '/vue-element-admin/article/pv',
  31 + url: '/yp/article/pv',
22 32 method: 'get',
23   - params: { pv }
  33 + params: {
  34 + pv
  35 + }
24 36 })
25 37 }
26 38  
27 39 export function createArticle(data) {
28 40 return request({
29   - url: '/vue-element-admin/article/create',
  41 + url: '/yp/article/create',
30 42 method: 'post',
31 43 data
32 44 })
... ... @@ -34,7 +46,7 @@ export function createArticle(data) {
34 46  
35 47 export function updateArticle(data) {
36 48 return request({
37   - url: '/vue-element-admin/article/update',
  49 + url: '/yp/article/update',
38 50 method: 'post',
39 51 data
40 52 })
... ...
src/api/remote-search.js
... ... @@ -2,7 +2,7 @@ import request from &#39;@/utils/request&#39;
2 2  
3 3 export function searchUser(name) {
4 4 return request({
5   - url: '/vue-element-admin/search/user',
  5 + url: '/yp/search/user',
6 6 method: 'get',
7 7 params: { name }
8 8 })
... ... @@ -10,7 +10,7 @@ export function searchUser(name) {
10 10  
11 11 export function transactionList(query) {
12 12 return request({
13   - url: '/vue-element-admin/transaction/list',
  13 + url: '/yp/transaction/list',
14 14 method: 'get',
15 15 params: query
16 16 })
... ...
... ... @@ -2,21 +2,21 @@ import request from &#39;@/utils/request&#39;
2 2  
3 3 export function getRoutes() {
4 4 return request({
5   - url: '/vue-element-admin/routes',
  5 + url: '/yp/routes',
6 6 method: 'get'
7 7 })
8 8 }
9 9  
10 10 export function getRoles() {
11 11 return request({
12   - url: '/vue-element-admin/roles',
  12 + url: '/yp/roles',
13 13 method: 'get'
14 14 })
15 15 }
16 16  
17 17 export function addRole(data) {
18 18 return request({
19   - url: '/vue-element-admin/role',
  19 + url: '/yp/role',
20 20 method: 'post',
21 21 data
22 22 })
... ...
... ... @@ -2,7 +2,7 @@ import request from &#39;@/utils/request&#39;
2 2  
3 3 export function login(data) {
4 4 return request({
5   - url: '/vue-element-admin/user/login',
  5 + url: '/yp/user/login',
6 6 method: 'post',
7 7 data
8 8 })
... ... @@ -10,7 +10,7 @@ export function login(data) {
10 10  
11 11 export function getInfo(token) {
12 12 return request({
13   - url: '/vue-element-admin/user/info',
  13 + url: '/yp/user/info',
14 14 method: 'get',
15 15 params: { token }
16 16 })
... ... @@ -18,7 +18,39 @@ export function getInfo(token) {
18 18  
19 19 export function logout() {
20 20 return request({
21   - url: '/vue-element-admin/user/logout',
  21 + url: '/yp/user/logout',
22 22 method: 'post'
23 23 })
24 24 }
  25 +
  26 +export function fetchList(query) {
  27 + return request({
  28 + url: '/yp/user/list',
  29 + method: 'get',
  30 + params: query
  31 + })
  32 +}
  33 +
  34 +export function createUser(query) {
  35 + return request({
  36 + url: '/yp/user/create',
  37 + method: 'post',
  38 + params: query
  39 + })
  40 +}
  41 +
  42 +export function updateUser(query) {
  43 + return request({
  44 + url: '/yp/user/update',
  45 + method: 'post',
  46 + params: query
  47 + })
  48 +}
  49 +
  50 +export function delUser(query) {
  51 + return request({
  52 + url: '/yp/user/del',
  53 + method: 'post',
  54 + params: query
  55 + })
  56 +}
... ...
1 1 export default {
  2 + // 添加的新词条------start
  3 + prod: {
  4 + menu_title: 'products'
  5 + },
  6 + order: {
  7 +
  8 + },
  9 + users: {
  10 +
  11 + },
  12 + site: {
  13 +
  14 + },
  15 + meta: {
  16 +
  17 + },
  18 + system: {
  19 + memu: '系统'
  20 + },
2 21 route: {
  22 + users: 'users',
  23 + usersList: 'user list',
  24 + shopers: 'shoper suply chain',
  25 + prods: 'products',
  26 + orders: 'orders',
  27 + sites: 'sites',
  28 + metas: {
  29 + metas: 'meta',
  30 + list: 'tree'
  31 + },
  32 + systems: {
  33 + systems: 'system',
  34 + sites: 'site seting',
  35 + money: 'money seting',
  36 + industry: 'industry seting',
  37 + template: 'template seting'
  38 + },
  39 + // 添加的新词条------end
3 40 dashboard: 'Dashboard',
4 41 documentation: 'Documentation',
5 42 guide: 'Guide',
... ... @@ -73,7 +110,15 @@ export default {
73 110 size: 'Global Size'
74 111 },
75 112 login: {
76   - title: 'Login Form',
  113 + runner: 'officer Runner',
  114 + shoper: 'shop of Suply Chain',
  115 + assistant: 'worker in system',
  116 + signup: 'sign up',
  117 + forgetpassword: 'forget password',
  118 + rememberpassword: 'remember password',
  119 +
  120 + // title: 'let\'s conquer the world',
  121 + title: 'LET\'S FUCK THE WORLD',
77 122 logIn: 'Login',
78 123 username: 'Username',
79 124 password: 'Password',
... ...
1 1 export default {
  2 + // 添加的新词条------start
  3 + prod: {
  4 + menu_title: 'products'
  5 + },
  6 + order: {
  7 +
  8 + },
  9 + users: {
  10 +
  11 + },
  12 + site: {
  13 +
  14 + },
  15 + meta: {
  16 +
  17 + },
  18 + system: {
  19 + memu: '系统'
  20 + },
2 21 route: {
  22 + users: 'users',
  23 + usersList: 'user list',
  24 + shopers: 'shoper suply chain',
  25 + prods: 'products',
  26 + orders: 'orders',
  27 + sites: 'sites',
  28 + metas: {
  29 + metas: '元',
  30 + list: '树'
  31 + },
  32 + systems: {
  33 + systems: '系统设置',
  34 + sites: '站点设置',
  35 + money: '货币设置',
  36 + industry: '行业设置',
  37 + template: '模版设置'
  38 + },
  39 + // 添加的新词条------end
3 40 dashboard: 'Panel de control',
4 41 documentation: 'Documentación',
5 42 guide: 'Guía',
... ... @@ -73,6 +110,13 @@ export default {
73 110 profile: 'Profile'
74 111 },
75 112 login: {
  113 + runner: 'officer Runner',
  114 + shoper: 'shop of Suply Chain',
  115 + assistant: 'worker in system',
  116 + signup: 'sign up',
  117 + forgetpassword: 'forget password',
  118 + rememberpassword: 'remember password',
  119 +
76 120 title: 'Formulario de acceso',
77 121 logIn: 'Acceso',
78 122 username: 'Usuario',
... ...
1 1 export default {
  2 + // 添加的新词条------start
  3 + prod: {
  4 + menu_title: 'products'
  5 + },
  6 + order: {
  7 +
  8 + },
  9 + users: {
  10 +
  11 + },
  12 + site: {
  13 +
  14 + },
  15 + meta: {
  16 +
  17 + },
  18 + system: {
  19 + memu: '系统'
  20 + },
2 21 route: {
  22 + users: 'users',
  23 + usersList: 'user list',
  24 + shopers: 'shoper suply chain',
  25 + prods: 'products',
  26 + orders: 'orders',
  27 + sites: 'sites',
  28 + metas: {
  29 + metas: '元',
  30 + list: '树'
  31 + },
  32 + systems: {
  33 + systems: '系统设置',
  34 + sites: '站点设置',
  35 + money: '货币设置',
  36 + industry: '行业设置',
  37 + template: '模版设置'
  38 + },
  39 + // 添加的新词条------end
3 40 dashboard: 'トップ',
4 41 documentation: 'ドキュメント',
5 42 guide: 'ガイド',
... ... @@ -73,6 +110,13 @@ export default {
73 110 size: '画面サイズ'
74 111 },
75 112 login: {
  113 + runner: 'officer Runner',
  114 + shoper: 'shop of Suply Chain',
  115 + assistant: 'worker in system',
  116 + signup: 'sign up',
  117 + forgetpassword: 'forget password',
  118 + rememberpassword: 'remember password',
  119 +
76 120 title: 'ユーザログイン',
77 121 logIn: 'ログイン',
78 122 username: 'ユーザ名',
... ...
1 1 export default {
  2 + // 添加的新词条------start
  3 + prod: {
  4 + menu_title: 'products'
  5 + },
  6 + order: {
  7 +
  8 + },
  9 + users: {
  10 +
  11 + },
  12 + site: {
  13 +
  14 + },
  15 + meta: {
  16 +
  17 + },
  18 + system: {
  19 + memu: '系统'
  20 + },
2 21 route: {
  22 + users: '用户',
  23 + usersList: '列表',
  24 + shopers: '厂商',
  25 + prods: '产品',
  26 + orders: '订单',
  27 + sites: '站点',
  28 + metas: {
  29 + metas: '元',
  30 + list: '树'
  31 + },
  32 + systems: {
  33 + systems: '系统设置',
  34 + sites: '站点设置',
  35 + money: '货币设置',
  36 + industry: '行业设置',
  37 + template: '模版设置'
  38 + },
  39 + // 添加的新词条------end
3 40 dashboard: '首页',
4 41 documentation: '文档',
5 42 guide: '引导页',
... ... @@ -73,7 +110,14 @@ export default {
73 110 size: '布局大小'
74 111 },
75 112 login: {
76   - title: '系统登录',
  113 + runner: '运营官',
  114 + shoper: '商家',
  115 + assistant: '操作员',
  116 + signup: '注册',
  117 + forgetpassword: '忘记密码',
  118 + rememberpassword: 'remember password',
  119 +
  120 + title: '鱼皮出海',
77 121 logIn: '登录',
78 122 username: '账号',
79 123 password: '密码',
... ...
src/layout/components/Settings/index.vue
... ... @@ -22,11 +22,12 @@
22 22 <span>{{ $t('settings.sidebarLogo') }}</span>
23 23 <el-switch v-model="sidebarLogo" class="drawer-switch" />
24 24 </div>
25   - <a v-if="isShowJob" href="https://panjiachen.github.io/vue-element-admin-site/zh/job/" target="_blank" class="job-link">
  25 +
  26 + <a v-if="isShowJob" href="https://glass.xiuyetang.com/" target="_blank" class="job-link">
26 27 <el-alert
27   - title="部门目前非常缺人!有兴趣的可以点击了解详情。坐标: 字节跳动"
  28 + title="鱼皮计划极为宏大,而且极为可行,我们要努力写代码,尽快打通任督二脉,要做好很有钱的思想准备"
28 29 type="success"
29   - :closable="false"
  30 + :closable="true"
30 31 />
31 32 </a>
32 33  
... ...
src/router/index.js
... ... @@ -7,11 +7,14 @@ Vue.use(Router)
7 7 import Layout from '@/layout'
8 8  
9 9 /* Router Modules */
10   -import componentsRouter from './modules/components'
11   -import chartsRouter from './modules/charts'
  10 +// import componentsRouter from './modules/components'
  11 +// import chartsRouter from './modules/charts'
12 12 import tableRouter from './modules/table'
13 13 // import nestedRouter from './modules/nested'
14 14 import userRouter from './modules/user'
  15 +import systemRouter from './modules/system'
  16 +import prodRouter from './modules/prod'
  17 +import metaRouter from './modules/meta'
15 18  
16 19 /**
17 20 * Note: sub-menu only appear when route children.length >= 1
... ... @@ -67,6 +70,11 @@ export const constantRoutes = [
67 70 hidden: true
68 71 },
69 72 {
  73 + path: '/500',
  74 + component: () => import('@/views/error-page/500'),
  75 + hidden: true
  76 + },
  77 + {
70 78 path: '/401',
71 79 component: () => import('@/views/error-page/401'),
72 80 hidden: true
... ... @@ -96,33 +104,33 @@ export const constantRoutes = [
96 104 // }
97 105 // ]
98 106 // },
99   - // {
100   - // path: '/guide',
101   - // component: Layout,
102   - // redirect: '/guide/index',
103   - // children: [
104   - // {
105   - // path: 'index',
106   - // component: () => import('@/views/guide/index'),
107   - // name: 'Guide',
108   - // meta: { title: 'guide', icon: 'guide', noCache: true }
109   - // }
110   - // ]
111   - // },
112 107 {
113   - path: '/profile',
  108 + path: '/guide',
114 109 component: Layout,
115   - redirect: '/profile/index',
116   - hidden: true,
  110 + redirect: '/guide/index',
117 111 children: [
118 112 {
119 113 path: 'index',
120   - component: () => import('@/views/profile/index'),
121   - name: 'Profile',
122   - meta: { title: 'profile', icon: 'user', noCache: true }
  114 + component: () => import('@/views/guide/index'),
  115 + name: 'Guide',
  116 + meta: { title: 'guide', icon: 'guide', noCache: true }
123 117 }
124 118 ]
125 119 }
  120 + // {
  121 + // path: '/profile',
  122 + // component: Layout,
  123 + // redirect: '/profile/index',
  124 + // hidden: true,
  125 + // children: [
  126 + // {
  127 + // path: 'index',
  128 + // component: () => import('@/views/profile/index'),
  129 + // name: 'Profile',
  130 + // meta: { title: 'profile', icon: 'user', noCache: true }
  131 + // }
  132 + // ]
  133 + // }
126 134 ]
127 135  
128 136 /**
... ... @@ -172,114 +180,19 @@ export const asyncRoutes = [
172 180 // }
173 181 // ]
174 182 // },
  183 + tableRouter,
  184 + metaRouter,
  185 + userRouter,
  186 + prodRouter,
175 187 {
176   - path: '/meta',
177   - component: Layout,
178   - redirect: '/meta/page',
179   - alwaysShow: true, // will always show the root menu
180   - name: 'Meta',
181   - meta: {
182   - title: 'Meta',
183   - icon: 'lock',
184   - roles: ['admin', 'assistant'] // you can set roles in root nav
185   - },
186   - children: [
187   - {
188   - path: 'page',
189   - component: () => import('@/views/permission/page'),
190   - name: 'MetaList',
191   - meta: {
192   - title: 'MetaList',
193   - roles: ['admin', 'assistant'] // or you can only set roles in sub nav
194   - }
195   - },
196   - {
197   - path: 'defined',
198   - component: () => import('@/views/permission/directive'),
199   - name: 'MetaDefiend',
200   - meta: {
201   - title: 'MetaDefiend',
202   - roles: ['admin', 'assistant']
203   - // if do not set roles, means: this page does not require permission
204   - }
205   - }
206   - ]
207   - },
208   - {
209   - path: '/users',
210   - component: Layout,
211   - redirect: '/users/page',
212   - alwaysShow: true, // will always show the root menu
213   - name: 'Users',
214   - meta: {
215   - title: 'Users',
216   - icon: 'lock',
217   - roles: ['admin', 'assistant'] // you can set roles in root nav
218   - },
219   - children: [
220   - {
221   - path: 'page',
222   - component: () => import('@/views/permission/page'),
223   - name: 'UserList',
224   - meta: {
225   - title: 'UserList',
226   - roles: ['admin', 'assistant'] // or you can only set roles in sub nav
227   - }
228   - },
229   - {
230   - path: 'defined',
231   - component: () => import('@/views/permission/directive'),
232   - name: 'UserDefiend',
233   - meta: {
234   - title: 'UserDefiend',
235   - roles: ['admin', 'assistant']
236   - // if do not set roles, means: this page does not require permission
237   - }
238   - }
239   - ]
240   - },
241   - {
242   - path: '/prod',
243   - component: Layout,
244   - redirect: '/prod/page',
245   - alwaysShow: true, // will always show the root menu
246   - name: 'Prod',
247   - meta: {
248   - title: 'Prod',
249   - icon: 'lock',
250   - roles: ['admin', 'assistant', 'runner', 'shoper'] // you can set roles in root nav
251   - },
252   - children: [
253   - {
254   - path: 'page',
255   - component: () => import('@/views/permission/page'),
256   - name: 'ProdList',
257   - meta: {
258   - title: 'ProdList',
259   - roles: ['admin', 'assistant', 'runner', 'shoper'] // or you can only set roles in sub nav
260   - }
261   - },
262   - {
263   - path: 'defined',
264   - component: () => import('@/views/permission/directive'),
265   - name: 'ProdDefiend',
266   - meta: {
267   - title: 'ProdDefiend',
268   - roles: ['admin', 'assistant', 'shoper']
269   - // if do not set roles, means: this page does not require permission
270   - }
271   - }
272   - ]
273   - },
274   - {
275   - path: '/order',
  188 + path: '/orders',
276 189 component: Layout,
277 190 redirect: '/order/page',
278 191 alwaysShow: true, // will always show the root menu
279 192 name: 'Order',
280 193 meta: {
281   - title: 'Order',
282   - icon: 'lock',
  194 + title: 'orders',
  195 + icon: 'shopping',
283 196 roles: ['admin', 'assistant', 'runner', 'shoper'] // you can set roles in root nav
284 197 },
285 198 children: [
... ... @@ -305,14 +218,14 @@ export const asyncRoutes = [
305 218 ]
306 219 },
307 220 {
308   - path: '/site',
  221 + path: '/sites',
309 222 component: Layout,
310 223 redirect: '/site/page',
311 224 alwaysShow: true, // will always show the root menu
312 225 name: 'Site',
313 226 meta: {
314   - title: 'Site',
315   - icon: 'lock',
  227 + title: 'sites',
  228 + icon: 'people',
316 229 roles: ['admin', 'assistant', 'runner'] // you can set roles in root nav
317 230 },
318 231 children: [
... ... @@ -337,39 +250,7 @@ export const asyncRoutes = [
337 250 }
338 251 ]
339 252 },
340   - {
341   - path: '/system',
342   - component: Layout,
343   - redirect: '/system/page',
344   - alwaysShow: true, // will always show the root menu
345   - name: 'System',
346   - meta: {
347   - title: 'System',
348   - icon: 'lock',
349   - roles: ['admin', 'assistant', 'runner'] // you can set roles in root nav
350   - },
351   - children: [
352   - {
353   - path: 'page',
354   - component: () => import('@/views/permission/page'),
355   - name: 'SystemList',
356   - meta: {
357   - title: 'SystemList',
358   - roles: ['admin', 'assistant', 'runner'] // or you can only set roles in sub nav
359   - }
360   - },
361   - {
362   - path: 'defined',
363   - component: () => import('@/views/permission/directive'),
364   - name: 'SystemDefiend',
365   - meta: {
366   - title: 'SystemDefiend',
367   - roles: ['admin', 'assistant', 'runner']
368   - // if do not set roles, means: this page does not require permission
369   - }
370   - }
371   - ]
372   - },
  253 +
373 254 // {
374 255 // path: '/icon',
375 256 // component: Layout,
... ... @@ -382,13 +263,12 @@ export const asyncRoutes = [
382 263 // }
383 264 // ]
384 265 // },
385   -
  266 + systemRouter,
386 267 /** when your routing map is too long, you can split it into small modules **/
387   - componentsRouter,
388   - chartsRouter,
  268 + // componentsRouter,
  269 + // chartsRouter,
389 270 // nestedRouter,
390   - tableRouter,
391   - userRouter,
  271 + // tableRouter,
392 272  
393 273 // {
394 274 // path: '/example',
... ...
src/router/modules/meta.js
... ... @@ -0,0 +1,25 @@
  1 +import Layout from '@/layout'
  2 +
  3 +const metaRouter = {
  4 + path: '/meta',
  5 + component: Layout,
  6 + redirect: '/meta/page',
  7 + alwaysShow: true, // will always show the root menu
  8 + name: 'Meta',
  9 + meta: {
  10 + title: 'metas.metas',
  11 + icon: 'zip',
  12 + roles: ['admin', 'assistant'] // you can set roles in root nav
  13 + },
  14 + children: [{
  15 + path: 'page',
  16 + component: () => import('@/views/meta/complex-table'),
  17 + name: 'MetaList',
  18 + meta: {
  19 + title: 'MetaList',
  20 + icon: 'zip',
  21 + roles: ['admin', 'assistant'] // or you can only set roles in sub nav
  22 + }
  23 + }]
  24 +}
  25 +export default metaRouter
... ...
src/router/modules/prod.js
... ... @@ -0,0 +1,38 @@
  1 +/** When your routing table is too long, you can split it into small modules**/
  2 +
  3 +import Layout from '@/layout'
  4 +
  5 +const prodRouter = {
  6 + path: '/prods',
  7 + component: Layout,
  8 + redirect: '/prod/page',
  9 + alwaysShow: true, // will always show the root menu
  10 + name: 'Prod',
  11 + meta: {
  12 + title: 'prods', // 会自动被i18n替换
  13 + icon: 'star',
  14 + roles: ['admin', 'assistant', 'runner', 'shoper'] // you can set roles in root nav
  15 + },
  16 + children: [{
  17 + path: 'page',
  18 + component: () => import('@/views/permission/page'),
  19 + name: 'ProdList',
  20 + meta: {
  21 + title: 'ProdList',
  22 + roles: ['admin', 'assistant', 'runner', 'shoper'] // or you can only set roles in sub nav
  23 + }
  24 + },
  25 + {
  26 + path: 'defined',
  27 + component: () => import('@/views/permission/directive'),
  28 + name: 'ProdDefiend',
  29 + meta: {
  30 + title: 'ProdDefiend',
  31 + roles: ['admin', 'assistant', 'shoper']
  32 + // if do not set roles, means: this page does not require permission
  33 + }
  34 + }
  35 + ]
  36 +}
  37 +
  38 +export default prodRouter
... ...
src/router/modules/system.js
... ... @@ -0,0 +1,54 @@
  1 +import Layout from '@/layout'
  2 +
  3 +const systemRouter = {
  4 + path: '/system',
  5 + component: Layout,
  6 + redirect: '/system/page',
  7 + alwaysShow: true, // will always show the root menu
  8 + name: 'System',
  9 + meta: {
  10 + title: 'systems.systems',
  11 + icon: 'component',
  12 + roles: ['admin', 'assistant', 'runner'] // you can set roles in root nav
  13 + },
  14 + children: [{
  15 + path: 'page',
  16 + component: () => import('@/views/example/list'),
  17 + name: 'SystemList',
  18 + meta: {
  19 + title: 'systems.sites',
  20 + roles: ['admin', 'assistant', 'runner'] // or you can only set roles in sub nav
  21 + }
  22 + },
  23 + {
  24 + path: 'page',
  25 + component: () => import('@/views/example/list'),
  26 + name: 'SystemList',
  27 + meta: {
  28 + title: 'systems.money',
  29 + roles: ['admin', 'assistant', 'runner'] // or you can only set roles in sub nav
  30 + }
  31 + },
  32 + {
  33 + path: 'page',
  34 + component: () => import('@/views/example/list'),
  35 + name: 'SystemList',
  36 + meta: {
  37 + title: 'systems.industry',
  38 + roles: ['admin', 'assistant', 'runner'] // or you can only set roles in sub nav
  39 + }
  40 + },
  41 + {
  42 + path: 'page',
  43 + component: () => import('@/views/example/list'),
  44 + name: 'SystemList',
  45 + meta: {
  46 + title: 'systems.template',
  47 + roles: ['admin', 'assistant', 'runner'] // or you can only set roles in sub nav
  48 + }
  49 + }
  50 +
  51 + ]
  52 +}
  53 +
  54 +export default systemRouter
... ...
src/router/modules/user.js
... ... @@ -5,31 +5,32 @@ import Layout from &#39;@/layout&#39;
5 5 const chartsRouter = {
6 6 path: '/users',
7 7 component: Layout,
8   - redirect: 'noRedirect',
  8 + redirect: '/users/page',
  9 + alwaysShow: true, // will always show the root menu
9 10 name: 'Users',
10 11 meta: {
11   - title: '用户管理',
12   - icon: 'peoples'
  12 + title: 'users',
  13 + icon: 'peoples',
  14 + roles: ['admin', 'assistant'] // you can set roles in root nav
13 15 },
14   - children: [
15   - {
16   - path: 'keyboard',
17   - component: () => import('@/views/charts/keyboard'),
18   - name: 'KeyboardChart',
19   - meta: { title: 'keyboardChart', noCache: true }
20   - },
21   - {
22   - path: 'line',
23   - component: () => import('@/views/charts/line'),
24   - name: 'LineChart',
25   - meta: { title: 'lineChart', noCache: true }
26   - },
27   - {
28   - path: 'mix-chart',
29   - component: () => import('@/views/charts/mix-chart'),
30   - name: 'MixChart',
31   - meta: { title: 'mixChart', noCache: true }
  16 + children: [{
  17 + path: 'page',
  18 + component: () => import('@/views/users/list'),
  19 + name: 'UserList',
  20 + meta: {
  21 + title: 'UserList',
  22 + roles: ['admin', 'assistant', 'shoper', 'runner'] // or you can only set roles in sub nav
32 23 }
  24 + }
  25 + // ,{
  26 + // path: '/icons',
  27 + // component: () => import('@/views/icons/index'),
  28 + // name: 'icons',
  29 + // meta: {
  30 + // title: 'icons',
  31 + // roles: ['admin', 'assistant', 'shoper', 'runner'] // or you can only set roles in sub nav
  32 + // }
  33 + // }
33 34 ]
34 35 }
35 36  
... ...
1 1 module.exports = {
2   - title: 'Vue Element Admin',
  2 + title: 'Let\'s fuck this workd',
3 3  
4 4 /**
5 5 * @type {boolean} true | false
... ... @@ -17,13 +17,13 @@ module.exports = {
17 17 * @type {boolean} true | false
18 18 * @description Whether fix the header
19 19 */
20   - fixedHeader: false,
  20 + fixedHeader: true,
21 21  
22 22 /**
23 23 * @type {boolean} true | false
24 24 * @description Whether show the logo in sidebar
25 25 */
26   - sidebarLogo: false,
  26 + sidebarLogo: true,
27 27  
28 28 /**
29 29 * @type {boolean} true | false
... ...
src/utils/request.js
1 1 import axios from 'axios'
2   -import { MessageBox, Message } from 'element-ui'
  2 +import qs from 'qs'
  3 +import {
  4 + MessageBox,
  5 + Message,
  6 + // Loading,
  7 + Notification
  8 +} from 'element-ui'
3 9 import store from '@/store'
4   -import { getToken } from '@/utils/auth'
  10 +import {
  11 + getToken
  12 +} from '@/utils/auth'
5 13  
6 14 // create an axios instance
7 15 const service = axios.create({
8 16 baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url
9   - // withCredentials: true, // send cookies when cross-domain requests
10   - timeout: 5000 // request timeout
  17 + withCredentials: true, // send cookies when cross-domain requests
  18 + timeout: 3000 // request timeout
11 19 })
12   -
  20 +// let loadingInstance
13 21 // request interceptor
14 22 service.interceptors.request.use(
15 23 config => {
16   - // do something before request is sent
17   -
  24 + const token = sessionStorage.getItem('access_token')
  25 + // const csrf = store.getters.csrf
  26 + if (token) {
  27 + config.headers = {
  28 + 'access-token': token,
  29 + 'Content-Type': 'application/x-www-form-urlencoded'
  30 + }
  31 + }
  32 + if (config.url === 'refresh') {
  33 + config.headers = {
  34 + 'refresh-token': sessionStorage.getItem('refresh_token'),
  35 + 'Content-Type': 'application/x-www-form-urlencoded'
  36 + }
  37 + }
  38 + // let options = {
  39 + // lock: true,
  40 + // fullscreen: false,
  41 + // text: '数据加载中……',
  42 + // // background: '#FFCC00',
  43 + // spinner: 'el-icon-loading'
  44 + // };
  45 + const options = {
  46 + type: 'success',
  47 + message: config.url,
  48 + title: 'request axios ',
  49 + showClose: true,
  50 + duration: 3000
  51 + }
  52 + Notification(options)
  53 + // loadingInstance = Loading.service(options);
  54 + config.method === 'post'
  55 + ? config.data = qs.stringify({
  56 + ...config.data
  57 + })
  58 + : config.params = {
  59 + ...config.params
  60 + }
18 61 if (store.getters.token) {
19 62 // let each request carry token
20 63 // ['X-Token'] is a custom headers key
21 64 // please modify it according to the actual situation
22 65 config.headers['X-Token'] = getToken()
23 66 }
  67 + config.headers['Content-Type'] = 'application/x-www-form-urlencoded'
  68 +
24 69 return config
  70 + // do something before request is sent
25 71 },
26 72 error => {
27 73 // do something with request error
  74 + Message({
  75 + message: error || 'Error',
  76 + type: 'error',
  77 + duration: 5 * 1000
  78 + })
28 79 console.log(error) // for debug
29 80 return Promise.reject(error)
30 81 }
... ... @@ -35,7 +86,7 @@ service.interceptors.response.use(
35 86 /**
36 87 * If you want to get http information such as headers or status
37 88 * Please return response => response
38   - */
  89 + */
39 90  
40 91 /**
41 92 * Determine the request status by custom code
... ... @@ -43,6 +94,27 @@ service.interceptors.response.use(
43 94 * You can also judge the status by HTTP Status Code
44 95 */
45 96 response => {
  97 + const options = {
  98 + type: 'error',
  99 + message: response.status,
  100 + title: 'response status value ',
  101 + showClose: true,
  102 + duration: 1000
  103 + }
  104 + Notification(options)
  105 + // Notification.close()
  106 + // 这里根据后端提供的数据进行对应的处理
  107 + console.log('response===>', response)
  108 + // 定时刷新access-token
  109 + // if (!response.data.value && response.data.data.message === 'token invalid') {
  110 + // // 刷新token
  111 + // store.dispatch('refresh').then(response => {
  112 + // sessionStorage.setItem('access_token', response.data)
  113 + // }).catch(error => {
  114 + // throw new Error('token刷新' + error)
  115 + // })
  116 + // }
  117 +
46 118 const res = response.data
47 119  
48 120 // if the custom code is not 20000, it is judged as an error.
... ... @@ -72,14 +144,24 @@ service.interceptors.response.use(
72 144 }
73 145 },
74 146 error => {
75   - console.log('err' + error) // for debug
  147 + console.log('error', error)
  148 + // console.log(JSON.stringify(error));
  149 + // 500的状态也应该处理一下
  150 + // 401-403的状态也应该处理一下
  151 + const text = JSON.parse(JSON.stringify(error)).response.status === 404
  152 + ? '404'
  153 + : '网络异常,请重试'
76 154 Message({
77   - message: error.message,
  155 + message: text || 'Error',
78 156 type: 'error',
79 157 duration: 5 * 1000
80 158 })
  159 +
81 160 return Promise.reject(error)
82 161 }
83 162 )
84 163  
  164 +// 假设你想移除拦截器
  165 +// axios.interceptors.request.eject(service);
  166 +
85 167 export default service
... ...
src/views/dashboard/admin/index.vue
1 1 <template>
2 2 <div class="dashboard-editor-container">
3   - <github-corner class="github-corner" />
  3 + <!-- <github-corner class="github-corner" /> -->
4 4  
5 5 <panel-group @handleSetLineChartData="handleSetLineChartData" />
6 6  
... ... @@ -41,7 +41,7 @@
41 41 </template>
42 42  
43 43 <script>
44   -import GithubCorner from '@/components/GithubCorner'
  44 +// import GithubCorner from '@/components/GithubCorner'
45 45 import PanelGroup from './components/PanelGroup'
46 46 import LineChart from './components/LineChart'
47 47 import RaddarChart from './components/RaddarChart'
... ... @@ -73,7 +73,7 @@ const lineChartData = {
73 73 export default {
74 74 name: 'DashboardAdmin',
75 75 components: {
76   - GithubCorner,
  76 + // GithubCorner,
77 77 PanelGroup,
78 78 LineChart,
79 79 RaddarChart,
... ...
src/views/dashboard/editor/index.vue
1 1 <template>
2 2 <div class="dashboard-editor-container">
3   - <div class=" clearfix">
  3 + <div class="clearfix">
4 4 <pan-thumb :image="avatar" style="float: left">
5 5 Your roles:
6 6 <span v-for="item in roles" :key="item" class="pan-info-roles">{{ item }}</span>
... ... @@ -20,55 +20,53 @@
20 20 <script>
21 21 import { mapGetters } from 'vuex'
22 22 import PanThumb from '@/components/PanThumb'
23   -import GithubCorner from '@/components/GithubCorner'
  23 +// import GithubCorner from '@/components/GithubCorner'
24 24  
25 25 export default {
26 26 name: 'DashboardEditor',
27   - components: { PanThumb, GithubCorner },
  27 + // components: { PanThumb, GithubCorner },
  28 + components: { PanThumb },
28 29 data() {
29 30 return {
30   - emptyGif: 'https://wpimg.wallstcn.com/0e03b7da-db9e-4819-ba10-9016ddfdaed3'
  31 + emptyGif:
  32 + 'https://wpimg.wallstcn.com/0e03b7da-db9e-4819-ba10-9016ddfdaed3'
31 33 }
32 34 },
33 35 computed: {
34   - ...mapGetters([
35   - 'name',
36   - 'avatar',
37   - 'roles'
38   - ])
  36 + ...mapGetters(['name', 'avatar', 'roles'])
39 37 }
40 38 }
41 39 </script>
42 40  
43 41 <style lang="scss" scoped>
44   - .emptyGif {
  42 +.emptyGif {
  43 + display: block;
  44 + width: 45%;
  45 + margin: 0 auto;
  46 +}
  47 +
  48 +.dashboard-editor-container {
  49 + background-color: #e3e3e3;
  50 + min-height: 100vh;
  51 + padding: 50px 60px 0px;
  52 + .pan-info-roles {
  53 + font-size: 12px;
  54 + font-weight: 700;
  55 + color: #333;
45 56 display: block;
46   - width: 45%;
47   - margin: 0 auto;
48 57 }
49   -
50   - .dashboard-editor-container {
51   - background-color: #e3e3e3;
52   - min-height: 100vh;
53   - padding: 50px 60px 0px;
54   - .pan-info-roles {
55   - font-size: 12px;
56   - font-weight: 700;
57   - color: #333;
58   - display: block;
59   - }
60   - .info-container {
61   - position: relative;
62   - margin-left: 190px;
63   - height: 150px;
64   - line-height: 200px;
65   - .display_name {
66   - font-size: 48px;
67   - line-height: 48px;
68   - color: #212121;
69   - position: absolute;
70   - top: 25px;
71   - }
  58 + .info-container {
  59 + position: relative;
  60 + margin-left: 190px;
  61 + height: 150px;
  62 + line-height: 200px;
  63 + .display_name {
  64 + font-size: 48px;
  65 + line-height: 48px;
  66 + color: #212121;
  67 + position: absolute;
  68 + top: 25px;
72 69 }
73 70 }
  71 +}
74 72 </style>
... ...
src/views/error-page/500.vue
... ... @@ -0,0 +1,57 @@
  1 +<template>
  2 + <div class="error-page">
  3 + <div class="error-code">
  4 + 5
  5 + <span>0</span>0
  6 + </div>
  7 + <div class="error-desc">啊哦~ 系统出了故障!</div>
  8 + <div class="error-handle">
  9 + <router-link to="/">
  10 + <el-button type="primary" size="large">返回首页</el-button>
  11 + </router-link>
  12 + <el-button class="error-btn" type="primary" size="large" @click="goBack">返回上一页</el-button>
  13 + </div>
  14 + </div>
  15 +</template>
  16 +
  17 +<script>
  18 +export default {
  19 + methods: {
  20 + goBack() {
  21 + this.$router.go(-1)
  22 + }
  23 + }
  24 +}
  25 +</script>
  26 +<style scoped>
  27 +.error-page {
  28 + display: flex;
  29 + justify-content: center;
  30 + align-items: center;
  31 + flex-direction: column;
  32 + width: 100%;
  33 + height: 100%;
  34 + background: #f3f3f3;
  35 + box-sizing: border-box;
  36 +}
  37 +.error-code {
  38 + line-height: 1;
  39 + font-size: 250px;
  40 + font-weight: bolder;
  41 + color: #f02d2d;
  42 +}
  43 +.error-code span {
  44 + color: #00a854;
  45 +}
  46 +.error-desc {
  47 + font-size: 30px;
  48 + color: #777;
  49 +}
  50 +.error-handle {
  51 + margin-top: 30px;
  52 + padding-bottom: 200px;
  53 +}
  54 +.error-btn {
  55 + margin-left: 100px;
  56 +}
  57 +</style>
... ...
src/views/error-page/502.vue
... ... @@ -1,57 +0,0 @@
1   -<template>
2   - <div class="error-page">
3   - <div class="error-code">
4   - 5
5   - <span>0</span>2
6   - </div>
7   - <div class="error-desc">啊哦~ 系统出了故障!</div>
8   - <div class="error-handle">
9   - <router-link to="/">
10   - <el-button type="primary" size="large">返回首页</el-button>
11   - </router-link>
12   - <el-button class="error-btn" type="primary" size="large" @click="goBack">返回上一页</el-button>
13   - </div>
14   - </div>
15   -</template>
16   -
17   -<script>
18   -export default {
19   - methods: {
20   - goBack() {
21   - this.$router.go(-1)
22   - }
23   - }
24   -}
25   -</script>
26   -<style scoped>
27   -.error-page {
28   - display: flex;
29   - justify-content: center;
30   - align-items: center;
31   - flex-direction: column;
32   - width: 100%;
33   - height: 100%;
34   - background: #f3f3f3;
35   - box-sizing: border-box;
36   -}
37   -.error-code {
38   - line-height: 1;
39   - font-size: 250px;
40   - font-weight: bolder;
41   - color: #f02d2d;
42   -}
43   -.error-code span {
44   - color: #00a854;
45   -}
46   -.error-desc {
47   - font-size: 30px;
48   - color: #777;
49   -}
50   -.error-handle {
51   - margin-top: 30px;
52   - padding-bottom: 200px;
53   -}
54   -.error-btn {
55   - margin-left: 100px;
56   -}
57   -</style>
src/views/login/index.vue
1 1 <template>
2 2 <div class="login-container">
3   - <el-form ref="loginForm" :model="loginForm" :rules="loginRules" class="login-form" autocomplete="on" label-position="left">
4   -
  3 + <el-form
  4 + ref="loginForm"
  5 + :model="loginForm"
  6 + :rules="loginRules"
  7 + class="login-form"
  8 + autocomplete="on"
  9 + label-position="left"
  10 + >
5 11 <div class="title-container">
6   - <h3 class="title">
7   - {{ $t('login.title') }}
8   - </h3>
  12 + <h3 class="title">{{ $t('login.title') }}</h3>
9 13 <lang-select class="set-language" />
10 14 </div>
11 15  
... ... @@ -47,26 +51,47 @@
47 51 </span>
48 52 </el-form-item>
49 53 </el-tooltip>
50   -
51   - <el-button :loading="loading" type="primary" style="width:100%;margin-bottom:30px;" @click.native.prevent="handleLogin">
52   - {{ $t('login.logIn') }}
53   - </el-button>
54   -
  54 + <div
  55 + style="position:relative;text-align:right;height:30px;line-height:30px;border:0px #000 solid;margin-top:-20px;"
  56 + >
  57 + <!-- <el-checkbox v-model="checked">{{$t('rememberpassword')}}</el-checkbox> -->
  58 + <el-link type="primary">{{ $t('login.forgetpassword') }}</el-link>
  59 + </div>
  60 + <el-button
  61 + :loading="loading"
  62 + type="primary"
  63 + style="width:100%;"
  64 + @click.native.prevent="handleLogin"
  65 + >{{ $t('login.logIn') }}</el-button>
  66 + <div
  67 + style="position:relative;text-align:right;height:30px;line-height:30px;border:0px #000 solid;margin-bottom:30px;"
  68 + >
  69 + <div class="tips">
  70 + <el-link type="primary">{{ $t('login.signup') }}</el-link>
  71 + </div>
  72 + </div>
55 73 <div style="position:relative">
56 74 <div class="tips">
57 75 <span>{{ $t('login.username') }} : admin</span>
58 76 <span>{{ $t('login.password') }} : {{ $t('login.any') }}</span>
59 77 </div>
60 78 <div class="tips">
61   - <span style="margin-right:18px;">
62   - {{ $t('login.username') }} : editor
63   - </span>
  79 + <span style="margin-right:18px;">{{ $t('login.username') }} : assistant</span>
64 80 <span>{{ $t('login.password') }} : {{ $t('login.any') }}</span>
65 81 </div>
66   -
67   - <el-button class="thirdparty-button" type="primary" @click="showDialog=true">
68   - {{ $t('login.thirdparty') }}
69   - </el-button>
  82 + <div class="tips">
  83 + <span style="margin-right:18px;">{{ $t('login.username') }} : runner</span>
  84 + <span>{{ $t('login.password') }} : {{ $t('login.any') }}</span>
  85 + </div>
  86 + <div class="tips">
  87 + <span style="margin-right:18px;">{{ $t('login.username') }} : shoper</span>
  88 + <span>{{ $t('login.password') }} : {{ $t('login.any') }}</span>
  89 + </div>
  90 + <el-button
  91 + class="thirdparty-button"
  92 + type="primary"
  93 + @click="showDialog=true"
  94 + >{{ $t('login.thirdparty') }}</el-button>
70 95 </div>
71 96 </el-form>
72 97  
... ... @@ -77,6 +102,7 @@
77 102 <br>
78 103 <social-sign />
79 104 </el-dialog>
  105 + <!-- <vfd></vfd> -->
80 106 </div>
81 107 </template>
82 108  
... ... @@ -84,9 +110,10 @@
84 110 import { validUsername } from '@/utils/validate'
85 111 import LangSelect from '@/components/LangSelect'
86 112 import SocialSign from './components/SocialSignin'
87   -
  113 +// import vfd from "vfd";
88 114 export default {
89 115 name: 'Login',
  116 + // components: { LangSelect, SocialSign, vfd },
90 117 components: { LangSelect, SocialSign },
91 118 data() {
92 119 const validateUsername = (rule, value, callback) => {
... ... @@ -109,8 +136,12 @@ export default {
109 136 password: '111111'
110 137 },
111 138 loginRules: {
112   - username: [{ required: true, trigger: 'blur', validator: validateUsername }],
113   - password: [{ required: true, trigger: 'blur', validator: validatePassword }]
  139 + username: [
  140 + { required: true, trigger: 'blur', validator: validateUsername }
  141 + ],
  142 + password: [
  143 + { required: true, trigger: 'blur', validator: validatePassword }
  144 + ]
114 145 },
115 146 passwordType: 'password',
116 147 capsTooltip: false,
... ... @@ -148,7 +179,7 @@ export default {
148 179 methods: {
149 180 checkCapslock(e) {
150 181 const { key } = e
151   - this.capsTooltip = key && key.length === 1 && (key >= 'A' && key <= 'Z')
  182 + this.capsTooltip = key && key.length === 1 && key >= 'A' && key <= 'Z'
152 183 },
153 184 showPwd() {
154 185 if (this.passwordType === 'password') {
... ... @@ -164,9 +195,13 @@ export default {
164 195 this.$refs.loginForm.validate(valid => {
165 196 if (valid) {
166 197 this.loading = true
167   - this.$store.dispatch('user/login', this.loginForm)
  198 + this.$store
  199 + .dispatch('user/login', this.loginForm)
168 200 .then(() => {
169   - this.$router.push({ path: this.redirect || '/', query: this.otherQuery })
  201 + this.$router.push({
  202 + path: this.redirect || '/',
  203 + query: this.otherQuery
  204 + })
170 205 this.loading = false
171 206 })
172 207 .catch(() => {
... ... @@ -212,8 +247,8 @@ export default {
212 247 /* 修复input 背景不协调 和光标变色 */
213 248 /* Detail see https://github.com/PanJiaChen/vue-element-admin/pull/927 */
214 249  
215   -$bg:#283443;
216   -$light_gray:#fff;
  250 +$bg: #283443;
  251 +$light_gray: #fff;
217 252 $cursor: #fff;
218 253  
219 254 @supports (-webkit-mask: none) and (not (cater-color: $cursor)) {
... ... @@ -256,9 +291,9 @@ $cursor: #fff;
256 291 </style>
257 292  
258 293 <style lang="scss" scoped>
259   -$bg:#2d3a4b;
260   -$dark_gray:#889aa4;
261   -$light_gray:#eee;
  294 +$bg: #2d3a4b;
  295 +$dark_gray: #889aa4;
  296 +$light_gray: #eee;
262 297  
263 298 .login-container {
264 299 min-height: 100%;
... ...
src/views/meta/complex-table.vue
... ... @@ -290,7 +290,7 @@ export default {
290 290 this.$refs['dataForm'].validate((valid) => {
291 291 if (valid) {
292 292 this.temp.id = parseInt(Math.random() * 100) + 1024 // mock a id
293   - this.temp.author = 'vue-element-admin'
  293 + this.temp.author = '秀野堂主'
294 294 createArticle(this.temp).then(() => {
295 295 this.list.unshift(this.temp)
296 296 this.dialogFormVisible = false
... ...
src/views/order/complex-table.vue
... ... @@ -290,7 +290,7 @@ export default {
290 290 this.$refs['dataForm'].validate((valid) => {
291 291 if (valid) {
292 292 this.temp.id = parseInt(Math.random() * 100) + 1024 // mock a id
293   - this.temp.author = 'vue-element-admin'
  293 + this.temp.author = '秀野堂主'
294 294 createArticle(this.temp).then(() => {
295 295 this.list.unshift(this.temp)
296 296 this.dialogFormVisible = false
... ...
src/views/prod/complex-table.vue
... ... @@ -290,7 +290,7 @@ export default {
290 290 this.$refs['dataForm'].validate((valid) => {
291 291 if (valid) {
292 292 this.temp.id = parseInt(Math.random() * 100) + 1024 // mock a id
293   - this.temp.author = 'vue-element-admin'
  293 + this.temp.author = '秀野堂主'
294 294 createArticle(this.temp).then(() => {
295 295 this.list.unshift(this.temp)
296 296 this.dialogFormVisible = false
... ...
src/views/system/complex-table.vue
... ... @@ -290,7 +290,7 @@ export default {
290 290 this.$refs['dataForm'].validate((valid) => {
291 291 if (valid) {
292 292 this.temp.id = parseInt(Math.random() * 100) + 1024 // mock a id
293   - this.temp.author = 'vue-element-admin'
  293 + this.temp.author = '秀野堂主'
294 294 createArticle(this.temp).then(() => {
295 295 this.list.unshift(this.temp)
296 296 this.dialogFormVisible = false
... ...
src/views/table/complex-table.vue
... ... @@ -290,7 +290,7 @@ export default {
290 290 this.$refs['dataForm'].validate((valid) => {
291 291 if (valid) {
292 292 this.temp.id = parseInt(Math.random() * 100) + 1024 // mock a id
293   - this.temp.author = 'vue-element-admin'
  293 + this.temp.author = '秀野堂主'
294 294 createArticle(this.temp).then(() => {
295 295 this.list.unshift(this.temp)
296 296 this.dialogFormVisible = false
... ...
src/views/users/list.vue
... ... @@ -0,0 +1,618 @@
  1 +<template>
  2 + <div class="app-container">
  3 + <div class="filter-container">
  4 + <el-input
  5 + v-model="listQuery.title"
  6 + :placeholder="$t('table.title')"
  7 + style="width: 200px;"
  8 + class="filter-item"
  9 + @keyup.enter.native="handleFilter"
  10 + />
  11 + <el-select
  12 + v-model="listQuery.importance"
  13 + :placeholder="$t('table.importance')"
  14 + clearable
  15 + style="width: 90px"
  16 + class="filter-item"
  17 + >
  18 + <el-option
  19 + v-for="item in importanceOptions"
  20 + :key="item"
  21 + :label="item"
  22 + :value="item"
  23 + />
  24 + </el-select>
  25 + <el-select
  26 + v-model="listQuery.type"
  27 + :placeholder="$t('table.type')"
  28 + clearable
  29 + class="filter-item"
  30 + style="width: 130px"
  31 + >
  32 + <el-option
  33 + v-for="item in calendarTypeOptions"
  34 + :key="item.key"
  35 + :label="item.display_name+'('+item.key+')'"
  36 + :value="item.key"
  37 + />
  38 + </el-select>
  39 + <el-select
  40 + v-model="listQuery.sort"
  41 + style="width: 140px"
  42 + class="filter-item"
  43 + @change="handleFilter"
  44 + >
  45 + <el-option
  46 + v-for="item in sortOptions"
  47 + :key="item.key"
  48 + :label="item.label"
  49 + :value="item.key"
  50 + />
  51 + </el-select>
  52 + <el-button
  53 + v-waves
  54 + class="filter-item"
  55 + type="primary"
  56 + icon="el-icon-search"
  57 + @click="handleFilter"
  58 + >
  59 + {{ $t('table.search') }}
  60 + </el-button>
  61 + <el-button
  62 + class="filter-item"
  63 + style="margin-left: 10px;"
  64 + type="primary"
  65 + icon="el-icon-edit"
  66 + @click="handleCreate"
  67 + >
  68 + {{ $t('table.add') }}
  69 + </el-button>
  70 + <el-button
  71 + v-waves
  72 + :loading="downloadLoading"
  73 + class="filter-item"
  74 + type="primary"
  75 + icon="el-icon-download"
  76 + @click="handleDownload"
  77 + >
  78 + {{ $t('table.export') }}
  79 + </el-button>
  80 + <el-checkbox
  81 + v-model="showReviewer"
  82 + class="filter-item"
  83 + style="margin-left:15px;"
  84 + @change="tableKey=tableKey+1"
  85 + >
  86 + {{ $t('table.reviewer') }}
  87 + </el-checkbox>
  88 + </div>
  89 +
  90 + <el-table
  91 + :key="tableKey"
  92 + v-loading="listLoading"
  93 + :data="list"
  94 + border
  95 + fit
  96 + highlight-current-row
  97 + style="width: 100%;"
  98 + @sort-change="sortChange"
  99 + >
  100 + <el-table-column
  101 + :label="$t('table.uid')"
  102 + prop="id"
  103 + sortable="custom"
  104 + align="center"
  105 + width="80"
  106 + :class-name="getSortClass('id')"
  107 + >
  108 + <template slot-scope="{row}">
  109 + <span>{{ row.uid }}</span>
  110 + </template>
  111 + </el-table-column>
  112 + <el-table-column
  113 + :label="$t('table.create_time')"
  114 + width="150px"
  115 + align="center"
  116 + >
  117 + <template slot-scope="{row}">
  118 + <span>{{ row.create_time | parseTime('{y}-{m}-{d} {h}:{i}') }}</span>
  119 + </template>
  120 + </el-table-column>
  121 + <el-table-column
  122 + :label="$t('table.openid')"
  123 + min-width="150px"
  124 + >
  125 + <template slot-scope="{row}">
  126 + <span
  127 + class="link-type"
  128 + @click="handleUpdate(row)"
  129 + >{{ row.title }}</span>
  130 + </template>
  131 + </el-table-column>
  132 + <el-table-column
  133 + :label="$t('table.nickname')"
  134 + width="110px"
  135 + align="center"
  136 + >
  137 + <template slot-scope="{row}">
  138 + <span>{{ row.nickname }}</span>
  139 + <el-tag>{{ row.type | typeFilter }}</el-tag>
  140 + </template>
  141 + </el-table-column>
  142 + <el-table-column
  143 + v-if="showReviewer"
  144 + :label="$t('table.reviewer')"
  145 + width="110px"
  146 + align="center"
  147 + >
  148 + <template slot-scope="{row}">
  149 + <span style="color:red;">{{ row.reviewer }}</span>
  150 + </template>
  151 + </el-table-column>
  152 + <el-table-column
  153 + :label="$t('table.importance')"
  154 + width="80px"
  155 + >
  156 + <template slot-scope="{row}">
  157 + <svg-icon
  158 + v-for="n in +row.importance"
  159 + :key="n"
  160 + icon-class="star"
  161 + class="meta-item__icon"
  162 + />
  163 + </template>
  164 + </el-table-column>
  165 + <el-table-column
  166 + :label="$t('table.son_of_adv')"
  167 + align="center"
  168 + width="95"
  169 + >
  170 + <template slot-scope="{row}">
  171 + <span
  172 + v-if="row.son_of_adv"
  173 + class="link-type"
  174 + @click="handleFetchPv(row.son_of_adv)"
  175 + >{{ row.son_of_adv }}</span>
  176 + <span v-else>0</span>
  177 + </template>
  178 + </el-table-column>
  179 + <el-table-column
  180 + :label="$t('table.status')"
  181 + class-name="status-col"
  182 + width="100"
  183 + >
  184 + <template slot-scope="{row}">
  185 + <el-tag :type="row.status | statusFilter">{{ row.status }}</el-tag>
  186 + </template>
  187 + </el-table-column>
  188 + <el-table-column
  189 + :label="$t('table.actions')"
  190 + align="center"
  191 + width="230"
  192 + class-name="small-padding fixed-width"
  193 + >
  194 + <template slot-scope="{row,$index}">
  195 + <el-button
  196 + type="primary"
  197 + size="mini"
  198 + @click="handleUpdate(row)"
  199 + >{{ $t('table.edit') }}</el-button>
  200 + <el-button
  201 + v-if="row.status!='deleted'"
  202 + size="mini"
  203 + type="danger"
  204 + @click="handleDelete(row,$index)"
  205 + >{{ $t('table.delete') }}</el-button>
  206 + </template>
  207 + </el-table-column>
  208 + </el-table>
  209 +
  210 + <pagination
  211 + v-show="total>0"
  212 + :total="total"
  213 + :page.sync="listQuery.page"
  214 + :limit.sync="listQuery.limit"
  215 + @pagination="getList"
  216 + />
  217 + <el-dialog
  218 + :title="textMap[dialogStatus]"
  219 + :visible.sync="dialogFormVisible"
  220 + >
  221 + <el-form
  222 + ref="dataForm"
  223 + :rules="rules"
  224 + :model="temp"
  225 + label-position="left"
  226 + label-width="70px"
  227 + style="width: 400px; margin-left:50px;"
  228 + >
  229 + <el-form-item
  230 + :label="$t('table.type')"
  231 + prop="type"
  232 + >
  233 + <el-select
  234 + v-model="temp.type"
  235 + class="filter-item"
  236 + placeholder="Please select"
  237 + >
  238 + <el-option
  239 + v-for="item in calendarTypeOptions"
  240 + :key="item.key"
  241 + :label="item.display_name"
  242 + :value="item.key"
  243 + />
  244 + </el-select>
  245 + </el-form-item>
  246 + <el-form-item
  247 + :label="$t('table.create_time')"
  248 + prop="create_time"
  249 + >
  250 + <el-date-picker
  251 + v-model="temp.create_time"
  252 + type="datetime"
  253 + placeholder="Please pick a date"
  254 + />
  255 + </el-form-item>
  256 + <el-form-item
  257 + :label="$t('table.业务记录')"
  258 + prop="title"
  259 + >
  260 + <el-input v-model="temp.title" />
  261 + </el-form-item>
  262 + <el-form-item :label="$t('table.status')">
  263 + <el-select
  264 + v-model="temp.status"
  265 + class="filter-item"
  266 + placeholder="Please select"
  267 + >
  268 + <el-option
  269 + v-for="item in statusOptions"
  270 + :key="item"
  271 + :label="item"
  272 + :value="item"
  273 + />
  274 + </el-select>
  275 + </el-form-item>
  276 + <el-form-item :label="$t('table.importance')">
  277 + <el-rate
  278 + v-model="temp.importance"
  279 + :colors="['#99A9BF', '#F7BA2A', '#FF9900']"
  280 + :max="3"
  281 + style="margin-top:8px;"
  282 + />
  283 + </el-form-item>
  284 + <el-form-item :label="$t('table.remark')">
  285 + <el-input
  286 + v-model="temp.remark"
  287 + :autosize="{ minRows: 2, maxRows: 4}"
  288 + type="textarea"
  289 + placeholder="Please input"
  290 + />
  291 + </el-form-item>
  292 + </el-form>
  293 + <div
  294 + slot="footer"
  295 + class="dialog-footer"
  296 + >
  297 + <el-button @click="dialogFormVisible = false">{{ $t('table.cancel') }}</el-button>
  298 + <el-button
  299 + type="primary"
  300 + @click="dialogStatus==='create'?createData():updateData()"
  301 + >{{ $t('table.confirm') }}</el-button>
  302 + </div>
  303 + </el-dialog>
  304 +
  305 + <el-dialog
  306 + :visible.sync="dialogPvVisible"
  307 + title="Reading statistics"
  308 + >
  309 + <el-table
  310 + :data="pvData"
  311 + border
  312 + fit
  313 + highlight-current-row
  314 + style="width: 100%"
  315 + >
  316 + <el-table-column
  317 + prop="key"
  318 + label="Channel"
  319 + />
  320 + <el-table-column
  321 + prop="pv"
  322 + label="Pv"
  323 + />
  324 + </el-table>
  325 + <span
  326 + slot="footer"
  327 + class="dialog-footer"
  328 + >
  329 + <el-button
  330 + type="primary"
  331 + @click="dialogPvVisible = false"
  332 + >{{ $t('table.confirm') }}</el-button>
  333 + </span>
  334 + </el-dialog>
  335 + </div>
  336 +</template>
  337 +
  338 +<script>
  339 +import {
  340 + fetchList,
  341 + fetchPv,
  342 + createUser,
  343 + updateUser,
  344 + delUser
  345 +} from '@/api/user'
  346 +import waves from '@/directive/waves' // waves directive
  347 +import { parseTime } from '@/utils'
  348 +import Pagination from '@/components/Pagination' // secondary package based on el-pagination
  349 +
  350 +const calendarTypeOptions = [
  351 + { key: 'CN', display_name: 'China' },
  352 + { key: 'US', display_name: 'USA' },
  353 + { key: 'JP', display_name: 'Japan' },
  354 + { key: 'EU', display_name: 'Eurozone' }
  355 +]
  356 +
  357 +// arr to obj, such as { CN : "China", US : "USA" }
  358 +const calendarTypeKeyValue = calendarTypeOptions.reduce((acc, cur) => {
  359 + acc[cur.key] = cur.display_name
  360 + return acc
  361 +}, {})
  362 +
  363 +export default {
  364 + name: 'ComplexTable',
  365 + components: { Pagination },
  366 + directives: { waves },
  367 + filters: {
  368 + statusFilter(status) {
  369 + const statusMap = {
  370 + published: 'success',
  371 + draft: 'info',
  372 + deleted: 'danger'
  373 + }
  374 + return statusMap[status]
  375 + },
  376 + typeFilter(type) {
  377 + return calendarTypeKeyValue[type]
  378 + }
  379 + },
  380 + data() {
  381 + return {
  382 + tableKey: 0,
  383 + list: null,
  384 + total: 0,
  385 + listLoading: true,
  386 + listQuery: {
  387 + page: 1,
  388 + limit: 20,
  389 + importance: undefined,
  390 + title: undefined,
  391 + type: undefined,
  392 + sort: '+id'
  393 + },
  394 + importanceOptions: [1, 2, 3],
  395 + calendarTypeOptions,
  396 + sortOptions: [
  397 + { label: 'ID Ascending', key: '+id' },
  398 + { label: 'ID Descending', key: '-id' }
  399 + ],
  400 + statusOptions: ['published', 'draft', 'deleted'],
  401 + showReviewer: false,
  402 + temp: {
  403 + id: undefined,
  404 + importance: 1,
  405 + remark: '',
  406 + create_time: new Date(),
  407 + title: '',
  408 + type: '',
  409 + status: 'published'
  410 + },
  411 + dialogFormVisible: false,
  412 + dialogStatus: '',
  413 + textMap: {
  414 + update: 'Edit',
  415 + create: 'Create'
  416 + },
  417 + dialogPvVisible: false,
  418 + pvData: [],
  419 + rules: {
  420 + type: [
  421 + { required: true, message: 'type is required', trigger: 'change' }
  422 + ],
  423 + create_time: [
  424 + {
  425 + type: 'date',
  426 + required: true,
  427 + message: 'create_time is required',
  428 + trigger: 'change'
  429 + }
  430 + ],
  431 + title: [
  432 + { required: true, message: 'title is required', trigger: 'blur' }
  433 + ]
  434 + },
  435 + downloadLoading: false
  436 + }
  437 + },
  438 + created: async function() {
  439 + const params = {
  440 + card_no: '111'
  441 + }
  442 + const res = await this.getList(params)
  443 + console.log('resresresres', res)
  444 + },
  445 + methods: {
  446 + getList() {
  447 + this.listLoading = true
  448 + fetchList(this.listQuery).then(response => {
  449 + this.list = response.data.items
  450 + this.total = response.data.total
  451 +
  452 + // Just to simulate the time of the request
  453 + setTimeout(() => {
  454 + this.listLoading = false
  455 + }, 1.5 * 1000)
  456 + })
  457 + },
  458 + handleFilter() {
  459 + this.listQuery.page = 1
  460 + this.getList()
  461 + },
  462 + handleModifyStatus(row, status) {
  463 + this.$message({
  464 + message: '操作成功',
  465 + type: 'success'
  466 + })
  467 + row.status = status
  468 + },
  469 + sortChange(data) {
  470 + const { prop, order } = data
  471 + if (prop === 'id') {
  472 + this.sortByID(order)
  473 + }
  474 + },
  475 + sortByID(order) {
  476 + if (order === 'ascending') {
  477 + this.listQuery.sort = '+id'
  478 + } else {
  479 + this.listQuery.sort = '-id'
  480 + }
  481 + this.handleFilter()
  482 + },
  483 + resetTemp() {
  484 + this.temp = {
  485 + id: undefined,
  486 + importance: 1,
  487 + remark: '',
  488 + create_time: new Date(),
  489 + title: '',
  490 + status: 'published',
  491 + type: ''
  492 + }
  493 + },
  494 + handleCreate() {
  495 + this.resetTemp()
  496 + this.dialogStatus = 'create'
  497 + this.dialogFormVisible = true
  498 + this.$nextTick(() => {
  499 + this.$refs['dataForm'].clearValidate()
  500 + })
  501 + // const data = []
  502 + // createUser(data).then(() => {
  503 + // this.$notify({
  504 + // title: "成功",
  505 + // message: "添加成功",
  506 + // type: "success",
  507 + // duration: 2000
  508 + // });
  509 + // });
  510 + },
  511 + createData() {
  512 + this.$refs['dataForm'].validate(valid => {
  513 + if (valid) {
  514 + this.temp.id = parseInt(Math.random() * 100) + 1024 // mock a id
  515 + this.temp.author = '秀野堂主'
  516 + createUser(this.temp).then(() => {
  517 + this.list.unshift(this.temp)
  518 + this.dialogFormVisible = false
  519 + this.$notify({
  520 + title: '成功',
  521 + message: '创建成功',
  522 + type: 'success',
  523 + duration: 2000
  524 + })
  525 + })
  526 + }
  527 + })
  528 + },
  529 + handleUpdate(row) {
  530 + this.temp = Object.assign({}, row) // copy obj
  531 + this.temp.create_time = new Date(this.temp.create_time)
  532 + this.dialogStatus = 'update'
  533 + this.dialogFormVisible = true
  534 + this.$nextTick(() => {
  535 + this.$refs['dataForm'].clearValidate()
  536 + })
  537 + },
  538 + updateData() {
  539 + this.$refs['dataForm'].validate(valid => {
  540 + if (valid) {
  541 + const tempData = Object.assign({}, this.temp)
  542 + tempData.create_time = +new Date(tempData.create_time) // change Thu Nov 30 2017 16:41:05 GMT+0800 (CST) to 1512031311464
  543 + updateUser(tempData).then(() => {
  544 + const index = this.list.findIndex(v => v.id === this.temp.id)
  545 + this.list.splice(index, 1, this.temp)
  546 + this.dialogFormVisible = false
  547 + this.$notify({
  548 + title: '成功',
  549 + message: '更新成功',
  550 + type: 'success',
  551 + duration: 2000
  552 + })
  553 + })
  554 + }
  555 + })
  556 + },
  557 + handleDelete(row, index) {
  558 + const data = []
  559 + delUser(data).then(() => {
  560 + this.list.splice(index, 1)
  561 + this.$notify({
  562 + title: '成功',
  563 + message: '删除成功',
  564 + type: 'success',
  565 + duration: 2000
  566 + })
  567 + })
  568 + },
  569 + handleFetchPv(pv) {
  570 + fetchPv(pv).then(response => {
  571 + this.pvData = response.data.pvData
  572 + this.dialogPvVisible = true
  573 + })
  574 + },
  575 + handleDownload() {
  576 + this.downloadLoading = true
  577 + import('@/vendor/Export2Excel').then(excel => {
  578 + const tHeader = [
  579 + 'create_time',
  580 + 'title',
  581 + 'type',
  582 + 'importance',
  583 + 'status'
  584 + ]
  585 + const filterVal = [
  586 + 'create_time',
  587 + 'title',
  588 + 'type',
  589 + 'importance',
  590 + 'status'
  591 + ]
  592 + const data = this.formatJson(filterVal)
  593 + excel.export_json_to_excel({
  594 + header: tHeader,
  595 + data,
  596 + filename: 'table-list'
  597 + })
  598 + this.downloadLoading = false
  599 + })
  600 + },
  601 + formatJson(filterVal) {
  602 + return this.list.map(v =>
  603 + filterVal.map(j => {
  604 + if (j === 'create_time') {
  605 + return parseTime(v[j])
  606 + } else {
  607 + return v[j]
  608 + }
  609 + })
  610 + )
  611 + },
  612 + getSortClass: function(key) {
  613 + const sort = this.listQuery.sort
  614 + return sort === `+${key}` ? 'ascending' : 'descending'
  615 + }
  616 + }
  617 +}
  618 +</script>
... ...
tests/unit/utils/validate.spec.js
... ... @@ -2,7 +2,9 @@ import { validUsername, validURL, validLowerCase, validUpperCase, validAlphabets
2 2 describe('Utils:validate', () => {
3 3 it('validUsername', () => {
4 4 expect(validUsername('admin')).toBe(true)
  5 + expect(validUsername('assistant')).toBe(true)
5 6 expect(validUsername('runner')).toBe(true)
  7 + expect(validUsername('shoper')).toBe(true)
6 8 // expect(validUsername('xxxx')).toBe(false)
7 9 // expect(validUsername('xxxx')).toBe(false)
8 10 // expect(validUsername('xxxx')).toBe(false)
... ...