diff --git a/package.json b/package.json index 50c38cd..32c6f1a 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "name": "template", + "name": "adminize", "version": "0.1.0", "private": true, "scripts": { @@ -12,6 +12,7 @@ "core-js": "^3.6.4", "normalize.css": "^8.0.1", "tiny-invariant": "^1.1.0", + "v-access": "^2.0.2", "vue": "^2.6.11", "vue-router": "^3.1.5", "vuex": "^3.1.2" @@ -74,4 +75,4 @@ "jest": { "preset": "@vue/cli-plugin-unit-jest/presets/typescript-and-babel" } -} \ No newline at end of file +} diff --git a/src/main.ts b/src/main.ts index 95fdb69..9daca01 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,10 +1,20 @@ import Vue from 'vue' -import App from './App.vue' +import { AuthMethods } from 'v-access' +import 'normalize.css' + import router from './router' import store from './store' -import 'normalize.css' +import './plugins/ability' +import App from './App.vue' + +// https://github.com/vuejs/vetur/issues/159 +declare module 'vue/types/vue' { + interface Vue { + $$auth: AuthMethods + } +} -Vue.config.productionTip = false +Vue.config.productionTip = __DEV__ new Vue({ router, diff --git a/src/plugins/ability.ts b/src/plugins/ability.ts new file mode 100644 index 0000000..f98c673 --- /dev/null +++ b/src/plugins/ability.ts @@ -0,0 +1,35 @@ +import Vue from 'vue' +import VAccess, { init, RouteWithAbility } from 'v-access' +import { Plugin } from 'vuex' +import { RootState } from '@/store' +import VueRouter from 'vue-router' + +Vue.use(VAccess) + +type CreateAbilityPlugin = ( + mutationType: string, + instance: Vue | VueRouter, + redirect: string, + routes: RouteWithAbility[] +) => Plugin + +export const createAbilityPlugin: CreateAbilityPlugin = function( + mutationType, // when should we call init + vm, + redirect, + routes +) { + return store => { + store.subscribe(mutation => { + if (mutation.type === mutationType) { + init({ + vm, + abilities: mutation.payload, + redirect, + routes + }) + return + } + }) + } +} diff --git a/src/shared/constants.ts b/src/shared/constants.ts new file mode 100644 index 0000000..fd0bf70 --- /dev/null +++ b/src/shared/constants.ts @@ -0,0 +1 @@ +export const FORBIDDEN_ROUTE = '/forbidden' diff --git a/src/store/index.ts b/src/store/index.ts index 250f9d9..20d0b48 100644 --- a/src/store/index.ts +++ b/src/store/index.ts @@ -1,9 +1,12 @@ import Vue from 'vue' import Vuex from 'vuex' import createLogger from 'vuex/dist/logger' +import router from '@/router' + import modules from './modules' import { createAbilityPlugin } from '../plugins/ability' -import router from '@/router' +import { types } from './modules/user' +import { FORBIDDEN_ROUTE } from '@/shared/constants' Vue.use(Vuex) @@ -12,9 +15,9 @@ const __DEV__ = process.env.NODE_ENV === 'development' export type RootState = {} const abilityPlugin = createAbilityPlugin( - 'user/setUserAbilities', + types.setUserAbilities, router, - '/forbidden', + FORBIDDEN_ROUTE, [ { path: '/user', diff --git a/src/store/modules/user.ts b/src/store/modules/user.ts new file mode 100644 index 0000000..0d6160a --- /dev/null +++ b/src/store/modules/user.ts @@ -0,0 +1,80 @@ +import { Module } from 'vuex' +import { RootState } from '..' +import { Ability } from 'v-access' +import { errorLog } from '@/shared/utils' + +interface UserState { + token: string + abilities: Ability[] +} + +export const types = { + setToken: 'setToken', + setUserAbilities: 'setUserAbilities' +} + +const user: Module = { + namespaced: true, + + state: { + token: '', + abilities: [] + }, + + getters: { + hasLogin({ token }) { + return Boolean(token) + } + }, + + mutations: { + setToken(state, token) { + state.token = token + }, + setUserAbilities(state, abilities) { + state.abilities = abilities + } + }, + + actions: { + async fetchUserInfo( + { commit }, + { username, password }: Record + ) { + try { + const { token } = await Promise.resolve({ + token: + Math.random() + .toString(16) + .slice(2) + + username + + password + }) + commit('setToken', token) + } catch (error) { + errorLog(error) + } + }, + async fetchUserAbilities({ commit }) { + try { + const { abilities } = await Promise.resolve({ + abilities: Array(20) + .fill(null) + .map((_, index) => ({ + id: `ability.simulator.${index}`, + name: `ability.simulator.${index}`, + createAt: Date.now() + index + })) + }) + commit( + 'setUserAbilities', + abilities.map(ability => ability.id) + ) + } catch (error) { + errorLog(error) + } + } + } +} + +export default user diff --git a/tsconfig.json b/tsconfig.json index 17eb562..7a4746f 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -12,7 +12,10 @@ "baseUrl": ".", "types": [ "webpack-env", - "jest" + "jest", + "vue-router", + "vuex", + "v-access" ], "paths": { "@/*": [ @@ -36,4 +39,4 @@ "exclude": [ "node_modules" ] -} +} \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index 4866d71..c45cd49 100644 --- a/yarn.lock +++ b/yarn.lock @@ -988,9 +988,9 @@ string-width "^2.0.0" "@types/babel__core@^7.1.0": - version "7.1.4" - resolved "https://registry.npm.taobao.org/@types/babel__core/download/@types/babel__core-7.1.4.tgz#5c5569cc40e5f2737dfc00692f5444e871e4a234" - integrity sha1-XFVpzEDl8nN9/ABpL1RE6HHkojQ= + version "7.1.5" + resolved "https://registry.npm.taobao.org/@types/babel__core/download/@types/babel__core-7.1.5.tgz#e4d84704b4df868b3ad538365a13da2fa6dbc023" + integrity sha1-5NhHBLTfhos61Tg2WhPaL6bbwCM= dependencies: "@babel/parser" "^7.1.0" "@babel/types" "^7.0.0" @@ -1014,9 +1014,9 @@ "@babel/types" "^7.0.0" "@types/babel__traverse@*", "@types/babel__traverse@^7.0.6": - version "7.0.8" - resolved "https://registry.npm.taobao.org/@types/babel__traverse/download/@types/babel__traverse-7.0.8.tgz#479a4ee3e291a403a1096106013ec22cf9b64012" - integrity sha1-R5pO4+KRpAOhCWEGAT7CLPm2QBI= + version "7.0.9" + resolved "https://registry.npm.taobao.org/@types/babel__traverse/download/@types/babel__traverse-7.0.9.tgz#be82fab304b141c3eee81a4ce3b034d0eba1590a" + integrity sha1-voL6swSxQcPu6BpM47A00OuhWQo= dependencies: "@babel/types" "^7.3.0" @@ -1130,7 +1130,7 @@ "@typescript-eslint/eslint-plugin@^2.18.0": version "2.20.0" - resolved "https://registry.npm.taobao.org/@typescript-eslint/eslint-plugin/download/@typescript-eslint/eslint-plugin-2.20.0.tgz?cache=0&sync_timestamp=1582134961565&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40typescript-eslint%2Feslint-plugin%2Fdownload%2F%40typescript-eslint%2Feslint-plugin-2.20.0.tgz#a522d0e1e4898f7c9c6a8e1ed3579b60867693fa" + resolved "https://registry.npm.taobao.org/@typescript-eslint/eslint-plugin/download/@typescript-eslint/eslint-plugin-2.20.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40typescript-eslint%2Feslint-plugin%2Fdownload%2F%40typescript-eslint%2Feslint-plugin-2.20.0.tgz#a522d0e1e4898f7c9c6a8e1ed3579b60867693fa" integrity sha1-pSLQ4eSJj3ycao4e01ebYIZ2k/o= dependencies: "@typescript-eslint/experimental-utils" "2.20.0" @@ -1141,7 +1141,7 @@ "@typescript-eslint/experimental-utils@2.20.0": version "2.20.0" - resolved "https://registry.npm.taobao.org/@typescript-eslint/experimental-utils/download/@typescript-eslint/experimental-utils-2.20.0.tgz?cache=0&sync_timestamp=1582134948307&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40typescript-eslint%2Fexperimental-utils%2Fdownload%2F%40typescript-eslint%2Fexperimental-utils-2.20.0.tgz#3b6fa5a6b8885f126d5a4280e0d44f0f41e73e32" + resolved "https://registry.npm.taobao.org/@typescript-eslint/experimental-utils/download/@typescript-eslint/experimental-utils-2.20.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40typescript-eslint%2Fexperimental-utils%2Fdownload%2F%40typescript-eslint%2Fexperimental-utils-2.20.0.tgz#3b6fa5a6b8885f126d5a4280e0d44f0f41e73e32" integrity sha1-O2+lpriIXxJtWkKA4NRPD0HnPjI= dependencies: "@types/json-schema" "^7.0.3" @@ -1150,7 +1150,7 @@ "@typescript-eslint/parser@^2.18.0": version "2.20.0" - resolved "https://registry.npm.taobao.org/@typescript-eslint/parser/download/@typescript-eslint/parser-2.20.0.tgz?cache=0&sync_timestamp=1582134963631&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40typescript-eslint%2Fparser%2Fdownload%2F%40typescript-eslint%2Fparser-2.20.0.tgz#608e5bb06ba98a415b64ace994c79ab20f9772a9" + resolved "https://registry.npm.taobao.org/@typescript-eslint/parser/download/@typescript-eslint/parser-2.20.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40typescript-eslint%2Fparser%2Fdownload%2F%40typescript-eslint%2Fparser-2.20.0.tgz#608e5bb06ba98a415b64ace994c79ab20f9772a9" integrity sha1-YI5bsGupikFbZKzplMeasg+Xcqk= dependencies: "@types/eslint-visitor-keys" "^1.0.0" @@ -1160,7 +1160,7 @@ "@typescript-eslint/typescript-estree@2.20.0": version "2.20.0" - resolved "https://registry.npm.taobao.org/@typescript-eslint/typescript-estree/download/@typescript-eslint/typescript-estree-2.20.0.tgz?cache=0&sync_timestamp=1582134949401&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40typescript-eslint%2Ftypescript-estree%2Fdownload%2F%40typescript-eslint%2Ftypescript-estree-2.20.0.tgz#90a0f5598826b35b966ca83483b1a621b1a4d0c9" + resolved "https://registry.npm.taobao.org/@typescript-eslint/typescript-estree/download/@typescript-eslint/typescript-estree-2.20.0.tgz#90a0f5598826b35b966ca83483b1a621b1a4d0c9" integrity sha1-kKD1WYgms1uWbKg0g7GmIbGk0Mk= dependencies: debug "^4.1.1" @@ -3651,9 +3651,9 @@ ejs@^2.6.1: integrity sha1-SGYSh1c9zFPjZsehrlLDoSDuybo= electron-to-chromium@^1.3.349: - version "1.3.355" - resolved "https://registry.npm.taobao.org/electron-to-chromium/download/electron-to-chromium-1.3.355.tgz#ff805ed8a3d68e550a45955134e4e81adf1122ba" - integrity sha1-/4Be2KPWjlUKRZVRNOToGt8RIro= + version "1.3.358" + resolved "https://registry.npm.taobao.org/electron-to-chromium/download/electron-to-chromium-1.3.358.tgz?cache=0&sync_timestamp=1582333374078&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Felectron-to-chromium%2Fdownload%2Felectron-to-chromium-1.3.358.tgz#1964cab37f57d49a5a421a4de4dba3c6baf14608" + integrity sha1-GWTKs39X1JpaQhpN5NujxrrxRgg= elliptic@^6.0.0: version "6.5.2" @@ -6774,9 +6774,9 @@ node-notifier@^5.4.2: which "^1.3.0" node-releases@^1.1.49: - version "1.1.49" - resolved "https://registry.npm.taobao.org/node-releases/download/node-releases-1.1.49.tgz#67ba5a3fac2319262675ef864ed56798bb33b93e" - integrity sha1-Z7paP6wjGSYmde+GTtVnmLszuT4= + version "1.1.50" + resolved "https://registry.npm.taobao.org/node-releases/download/node-releases-1.1.50.tgz?cache=0&sync_timestamp=1582335507431&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fnode-releases%2Fdownload%2Fnode-releases-1.1.50.tgz#803c40d2c45db172d0410e4efec83aa8c6ad0592" + integrity sha1-gDxA0sRdsXLQQQ5O/sg6qMatBZI= dependencies: semver "^6.3.0" @@ -7412,7 +7412,7 @@ posix-character-classes@^0.1.0: postcss-calc@^7.0.1: version "7.0.2" - resolved "https://registry.npm.taobao.org/postcss-calc/download/postcss-calc-7.0.2.tgz#504efcd008ca0273120568b0792b16cdcde8aac1" + resolved "https://registry.npm.taobao.org/postcss-calc/download/postcss-calc-7.0.2.tgz?cache=0&sync_timestamp=1582014221563&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fpostcss-calc%2Fdownload%2Fpostcss-calc-7.0.2.tgz#504efcd008ca0273120568b0792b16cdcde8aac1" integrity sha1-UE780AjKAnMSBWiweSsWzc3oqsE= dependencies: postcss "^7.0.27" @@ -7977,7 +7977,7 @@ raw-body@2.4.0: react-is@^16.8.4: version "16.12.0" - resolved "https://registry.npm.taobao.org/react-is/download/react-is-16.12.0.tgz#2cc0fe0fba742d97fd527c42a13bec4eeb06241c" + resolved "https://registry.npm.taobao.org/react-is/download/react-is-16.12.0.tgz?cache=0&sync_timestamp=1582245369601&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Freact-is%2Fdownload%2Freact-is-16.12.0.tgz#2cc0fe0fba742d97fd527c42a13bec4eeb06241c" integrity sha1-LMD+D7p0LZf9UnxCoTvsTusGJBw= read-pkg-up@^4.0.0: @@ -9197,7 +9197,7 @@ through@^2.3.6: thunky@^1.0.2: version "1.1.0" - resolved "https://registry.npm.taobao.org/thunky/download/thunky-1.1.0.tgz#5abaf714a9405db0504732bbccd2cedd9ef9537d" + resolved "https://registry.npm.taobao.org/thunky/download/thunky-1.1.0.tgz?cache=0&sync_timestamp=1571043401546&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fthunky%2Fdownload%2Fthunky-1.1.0.tgz#5abaf714a9405db0504732bbccd2cedd9ef9537d" integrity sha1-Wrr3FKlAXbBQRzK7zNLO3Z75U30= timers-browserify@^2.0.4: @@ -9358,9 +9358,9 @@ tsconfig@^7.0.0: strip-json-comments "^2.0.0" tslib@^1.8.0, tslib@^1.8.1, tslib@^1.9.0: - version "1.10.0" - resolved "https://registry.npm.taobao.org/tslib/download/tslib-1.10.0.tgz#c3c19f95973fb0a62973fb09d90d961ee43e5c8a" - integrity sha1-w8GflZc/sKYpc/sJ2Q2WHuQ+XIo= + version "1.11.0" + resolved "https://registry.npm.taobao.org/tslib/download/tslib-1.11.0.tgz#f1f3528301621a53220d58373ae510ff747a66bc" + integrity sha1-8fNSgwFiGlMiDVg3OuUQ/3R6Zrw= tslint@^5.20.1: version "5.20.1" @@ -9444,7 +9444,7 @@ typedarray@^0.0.6: typescript@~3.7.5: version "3.7.5" - resolved "https://registry.npm.taobao.org/typescript/download/typescript-3.7.5.tgz#0692e21f65fd4108b9330238aac11dd2e177a1ae" + resolved "https://registry.npm.taobao.org/typescript/download/typescript-3.7.5.tgz?cache=0&sync_timestamp=1582312132743&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ftypescript%2Fdownload%2Ftypescript-3.7.5.tgz#0692e21f65fd4108b9330238aac11dd2e177a1ae" integrity sha1-BpLiH2X9QQi5MwI4qsEd0uF3oa4= uglify-js@3.4.x: @@ -9639,6 +9639,13 @@ uuid@^3.0.1, uuid@^3.3.2: resolved "https://registry.npm.taobao.org/uuid/download/uuid-3.4.0.tgz?cache=0&sync_timestamp=1581938757764&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fuuid%2Fdownload%2Fuuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" integrity sha1-sj5DWK+oogL+ehAK8fX4g/AgB+4= +v-access@^2.0.2: + version "2.0.2" + resolved "https://registry.npm.taobao.org/v-access/download/v-access-2.0.2.tgz?cache=0&sync_timestamp=1582957079844&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fv-access%2Fdownload%2Fv-access-2.0.2.tgz#911b343d91896733b74742ddca7c71db8700e83a" + integrity sha1-kRs0PZGJZzO3R0Ldynxx24cA6Do= + dependencies: + tiny-invariant "^1.1.0" + v8-compile-cache@^2.0.3: version "2.1.0" resolved "https://registry.npm.taobao.org/v8-compile-cache/download/v8-compile-cache-2.1.0.tgz#e14de37b31a6d194f5690d67efc4e7f6fc6ab30e" @@ -9722,7 +9729,7 @@ vue-loader@^15.8.3: vue-router@^3.1.5: version "3.1.5" - resolved "https://registry.npm.taobao.org/vue-router/download/vue-router-3.1.5.tgz#ff29b8a1e1306c526b52d4dc0532109f16c41231" + resolved "https://registry.npm.taobao.org/vue-router/download/vue-router-3.1.5.tgz?cache=0&sync_timestamp=1582296703890&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fvue-router%2Fdownload%2Fvue-router-3.1.5.tgz#ff29b8a1e1306c526b52d4dc0532109f16c41231" integrity sha1-/ym4oeEwbFJrUtTcBTIQnxbEEjE= vue-style-loader@^4.1.0, vue-style-loader@^4.1.2: