增加一些directives
This commit is contained in:
parent
50072ace8d
commit
d2982d6428
@ -7,20 +7,13 @@ export const getRoles = (params: any) =>
|
|||||||
params
|
params
|
||||||
})
|
})
|
||||||
|
|
||||||
export const createRole = (data: any) =>
|
export const saveRole = (data: any) =>
|
||||||
request({
|
request({
|
||||||
url: '/roles',
|
url: '/roles',
|
||||||
method: 'post',
|
method: 'post',
|
||||||
data
|
data
|
||||||
})
|
})
|
||||||
|
|
||||||
export const updateRole = (id: number, data: any) =>
|
|
||||||
request({
|
|
||||||
url: `/roles/${id}`,
|
|
||||||
method: 'put',
|
|
||||||
data
|
|
||||||
})
|
|
||||||
|
|
||||||
export const deleteRole = (id: number) =>
|
export const deleteRole = (id: number) =>
|
||||||
request({
|
request({
|
||||||
url: `/roles/${id}`,
|
url: `/roles/${id}`,
|
||||||
|
60
src/directives/clipboard/index.ts
Normal file
60
src/directives/clipboard/index.ts
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
// Inspired by https://github.com/Inndy/vue-clipboard2
|
||||||
|
import Clipboard from 'clipboard'
|
||||||
|
import { DirectiveOptions } from 'vue'
|
||||||
|
|
||||||
|
if (!Clipboard) {
|
||||||
|
throw new Error('you should npm install `clipboard` --save at first ')
|
||||||
|
}
|
||||||
|
|
||||||
|
let successCallback: Function | null
|
||||||
|
let errorCallback: Function | null
|
||||||
|
let clipboardInstance: Clipboard | null
|
||||||
|
|
||||||
|
export const clipboard: DirectiveOptions = {
|
||||||
|
bind(el, binding) {
|
||||||
|
if (binding.arg === 'success') {
|
||||||
|
successCallback = binding.value
|
||||||
|
} else if (binding.arg === 'error') {
|
||||||
|
errorCallback = binding.value
|
||||||
|
} else {
|
||||||
|
clipboardInstance = new Clipboard(el, {
|
||||||
|
text() { return binding.value },
|
||||||
|
action() { return binding.arg === 'cut' ? 'cut' : 'copy' }
|
||||||
|
})
|
||||||
|
clipboardInstance.on('success', e => {
|
||||||
|
const callback = successCallback
|
||||||
|
callback && callback(e)
|
||||||
|
})
|
||||||
|
clipboardInstance.on('error', e => {
|
||||||
|
const callback = errorCallback
|
||||||
|
callback && callback(e)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
update(el, binding) {
|
||||||
|
if (binding.arg === 'success') {
|
||||||
|
successCallback = binding.value
|
||||||
|
} else if (binding.arg === 'error') {
|
||||||
|
errorCallback = binding.value
|
||||||
|
} else {
|
||||||
|
clipboardInstance = new Clipboard(el, {
|
||||||
|
text() { return binding.value },
|
||||||
|
action() { return binding.arg === 'cut' ? 'cut' : 'copy' }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
unbind(_, binding) {
|
||||||
|
if (binding.arg === 'success') {
|
||||||
|
successCallback = null
|
||||||
|
} else if (binding.arg === 'error') {
|
||||||
|
errorCallback = null
|
||||||
|
} else {
|
||||||
|
if (clipboardInstance) {
|
||||||
|
clipboardInstance.destroy()
|
||||||
|
}
|
||||||
|
clipboardInstance = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
75
src/directives/el-draggable-dialog/index.ts
Normal file
75
src/directives/el-draggable-dialog/index.ts
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
import { DirectiveOptions } from 'vue'
|
||||||
|
|
||||||
|
export const elDraggableDialog: DirectiveOptions = {
|
||||||
|
bind(el, _, vnode) {
|
||||||
|
const dragDom = el.querySelector('.el-dialog') as HTMLElement
|
||||||
|
const dialogHeaderEl = el.querySelector('.el-dialog__header') as HTMLElement
|
||||||
|
dragDom.style.cssText += ';top:0px;'
|
||||||
|
dialogHeaderEl.style.cssText += ';cursor:move;'
|
||||||
|
|
||||||
|
dialogHeaderEl.onmousedown = (e) => {
|
||||||
|
const disX = e.clientX - dialogHeaderEl.offsetLeft
|
||||||
|
const disY = e.clientY - dialogHeaderEl.offsetTop
|
||||||
|
|
||||||
|
const dragDomWidth = dragDom.offsetWidth
|
||||||
|
const dragDomHeight = dragDom.offsetHeight
|
||||||
|
|
||||||
|
const screenWidth = document.body.clientWidth
|
||||||
|
const screenHeight = document.body.clientHeight
|
||||||
|
|
||||||
|
const minDragDomLeft = dragDom.offsetLeft
|
||||||
|
const maxDragDomLeft = screenWidth - dragDom.offsetLeft - dragDomWidth
|
||||||
|
|
||||||
|
const minDragDomTop = dragDom.offsetTop
|
||||||
|
const maxDragDomTop = screenHeight - dragDom.offsetTop - dragDomHeight
|
||||||
|
|
||||||
|
const styleLeftStr = getComputedStyle(dragDom).left
|
||||||
|
const styleTopStr = getComputedStyle(dragDom).top
|
||||||
|
if (!styleLeftStr || !styleTopStr) return
|
||||||
|
let styleLeft: number
|
||||||
|
let styleTop: number
|
||||||
|
|
||||||
|
// Format may be "##%" or "##px"
|
||||||
|
if (styleLeftStr.includes('%')) {
|
||||||
|
styleLeft = +document.body.clientWidth * (+styleLeftStr.replace(/%/g, '') / 100)
|
||||||
|
styleTop = +document.body.clientHeight * (+styleTopStr.replace(/%/g, '') / 100)
|
||||||
|
} else {
|
||||||
|
styleLeft = +styleLeftStr.replace(/px/g, '')
|
||||||
|
styleTop = +styleTopStr.replace(/px/g, '')
|
||||||
|
}
|
||||||
|
|
||||||
|
document.onmousemove = (e) => {
|
||||||
|
let left = e.clientX - disX
|
||||||
|
let top = e.clientY - disY
|
||||||
|
|
||||||
|
// Handle edge cases
|
||||||
|
if (-(left) > minDragDomLeft) {
|
||||||
|
left = -minDragDomLeft
|
||||||
|
} else if (left > maxDragDomLeft) {
|
||||||
|
left = maxDragDomLeft
|
||||||
|
}
|
||||||
|
if (-(top) > minDragDomTop) {
|
||||||
|
top = -minDragDomTop
|
||||||
|
} else if (top > maxDragDomTop) {
|
||||||
|
top = maxDragDomTop
|
||||||
|
}
|
||||||
|
|
||||||
|
// Move current element
|
||||||
|
dragDom.style.cssText += `;left:${left + styleLeft}px;top:${top + styleTop}px;`
|
||||||
|
|
||||||
|
// Emit on-dialog-drag event
|
||||||
|
// See https://stackoverflow.com/questions/49264426/vuejs-custom-directive-emit-event
|
||||||
|
if (vnode.componentInstance) {
|
||||||
|
vnode.componentInstance.$emit('on-dialog-drag')
|
||||||
|
} else if (vnode.elm) {
|
||||||
|
vnode.elm.dispatchEvent(new CustomEvent('on-dialog-drag'))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
document.onmouseup = () => {
|
||||||
|
document.onmousemove = null
|
||||||
|
document.onmouseup = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
5
src/directives/index.ts
Normal file
5
src/directives/index.ts
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
export * from './permission'
|
||||||
|
export * from './el-draggable-dialog'
|
||||||
|
export * from './waves'
|
||||||
|
export * from './clipboard'
|
||||||
|
export * from './role'
|
55
src/directives/permission/index.ts
Normal file
55
src/directives/permission/index.ts
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
import { DirectiveOptions } from 'vue'
|
||||||
|
import { UserModule } from '@/store/modules/user'
|
||||||
|
|
||||||
|
export const permission: DirectiveOptions = {
|
||||||
|
inserted(el, binding) {
|
||||||
|
const { value } = binding
|
||||||
|
const permissions = UserModule.permissions
|
||||||
|
let hasPermission = false
|
||||||
|
|
||||||
|
if (value && value instanceof Array && value.length > 0) {
|
||||||
|
for (const sub of value) {
|
||||||
|
if (sub === '*') {
|
||||||
|
hasPermission = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
const subArr = sub.split(':')
|
||||||
|
if (subArr[0] === '*') {
|
||||||
|
for (const p of permissions) {
|
||||||
|
if (p[1] === '*' || p[1] === subArr[1]) {
|
||||||
|
hasPermission = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (subArr[1] === '*') {
|
||||||
|
for (const p of permissions) {
|
||||||
|
if (p[0] === '*' || p[0] === subArr[0]) {
|
||||||
|
hasPermission = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (const p of permissions) {
|
||||||
|
if ((p[0] === '*' && p[1] === '*') ||
|
||||||
|
(p[0] === '*' && p[1] === subArr[1]) ||
|
||||||
|
(p[0] === subArr[0] && p[1] === '*') ||
|
||||||
|
(p[0] === subArr[0] && p[1] === subArr[1])) {
|
||||||
|
hasPermission = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (hasPermission) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hasPermission) {
|
||||||
|
el.style.display = 'none'
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw new Error('need permissions! Like v-permission="[\'role:read\',\'news:read\']"')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
21
src/directives/role/index.ts
Normal file
21
src/directives/role/index.ts
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
import { DirectiveOptions } from 'vue'
|
||||||
|
import { UserModule } from '@/store/modules/user'
|
||||||
|
|
||||||
|
export const role: DirectiveOptions = {
|
||||||
|
inserted(el, binding) {
|
||||||
|
const { value } = binding
|
||||||
|
const roles = UserModule.roles
|
||||||
|
if (value && value instanceof Array && value.length > 0) {
|
||||||
|
const permissionRoles = value
|
||||||
|
const hasRole = roles.some(role => {
|
||||||
|
return permissionRoles.includes(role)
|
||||||
|
})
|
||||||
|
if (!hasRole) {
|
||||||
|
el.style.display = 'none'
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw new Error('need roles! Like v-role="[\'admin\',\'editor\']"')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
46
src/directives/waves/index.ts
Normal file
46
src/directives/waves/index.ts
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
import './waves.css'
|
||||||
|
import { DirectiveOptions } from 'vue'
|
||||||
|
|
||||||
|
export const waves: DirectiveOptions = {
|
||||||
|
bind(el, binding) {
|
||||||
|
el.addEventListener('click', e => {
|
||||||
|
const customOpts = Object.assign({}, binding.value)
|
||||||
|
const opts = Object.assign({
|
||||||
|
ele: el, // 波纹作用元素
|
||||||
|
type: 'hit', // hit 点击位置扩散 center中心点扩展
|
||||||
|
color: 'rgba(0, 0, 0, 0.15)' // 波纹颜色
|
||||||
|
}, customOpts)
|
||||||
|
const target: HTMLElement = opts.ele
|
||||||
|
if (target) {
|
||||||
|
target.style.position = 'relative'
|
||||||
|
target.style.overflow = 'hidden'
|
||||||
|
const rect = target.getBoundingClientRect()
|
||||||
|
let ripple = target.querySelector('.waves-ripple') as HTMLElement
|
||||||
|
if (!ripple) {
|
||||||
|
ripple = document.createElement('span')
|
||||||
|
ripple.className = 'waves-ripple'
|
||||||
|
ripple.style.height = ripple.style.width = Math.max(rect.width, rect.height) + 'px'
|
||||||
|
target.appendChild(ripple)
|
||||||
|
} else {
|
||||||
|
ripple.className = 'waves-ripple'
|
||||||
|
}
|
||||||
|
switch (opts.type) {
|
||||||
|
case 'center':
|
||||||
|
ripple.style.top = rect.height / 2 - ripple.offsetHeight / 2 + 'px'
|
||||||
|
ripple.style.left = rect.width / 2 - ripple.offsetWidth / 2 + 'px'
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
ripple.style.top =
|
||||||
|
(e.pageY - rect.top - ripple.offsetHeight / 2 - document.documentElement.scrollTop ||
|
||||||
|
document.body.scrollTop) + 'px'
|
||||||
|
ripple.style.left =
|
||||||
|
(e.pageX - rect.left - ripple.offsetWidth / 2 - document.documentElement.scrollLeft ||
|
||||||
|
document.body.scrollLeft) + 'px'
|
||||||
|
}
|
||||||
|
ripple.style.backgroundColor = opts.color
|
||||||
|
ripple.className = 'waves-ripple z-active'
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}, false)
|
||||||
|
}
|
||||||
|
}
|
26
src/directives/waves/waves.css
Normal file
26
src/directives/waves/waves.css
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
.waves-ripple {
|
||||||
|
position: absolute;
|
||||||
|
border-radius: 100%;
|
||||||
|
background-color: rgba(0, 0, 0, 0.15);
|
||||||
|
background-clip: padding-box;
|
||||||
|
pointer-events: none;
|
||||||
|
-webkit-user-select: none;
|
||||||
|
-moz-user-select: none;
|
||||||
|
-ms-user-select: none;
|
||||||
|
user-select: none;
|
||||||
|
-webkit-transform: scale(0);
|
||||||
|
-ms-transform: scale(0);
|
||||||
|
transform: scale(0);
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.waves-ripple.z-active {
|
||||||
|
opacity: 0;
|
||||||
|
-webkit-transform: scale(2);
|
||||||
|
-ms-transform: scale(2);
|
||||||
|
transform: scale(2);
|
||||||
|
-webkit-transition: opacity 1.2s ease-out, -webkit-transform 0.6s ease-out;
|
||||||
|
transition: opacity 1.2s ease-out, -webkit-transform 0.6s ease-out;
|
||||||
|
transition: opacity 1.2s ease-out, transform 0.6s ease-out;
|
||||||
|
transition: opacity 1.2s ease-out, transform 0.6s ease-out, -webkit-transform 0.6s ease-out;
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
import Vue from 'vue'
|
import Vue, { DirectiveOptions } from 'vue'
|
||||||
|
|
||||||
import 'normalize.css'
|
import 'normalize.css'
|
||||||
import ElementUI from 'element-ui'
|
import ElementUI from 'element-ui'
|
||||||
@ -13,8 +13,11 @@ import router from '@/router'
|
|||||||
import i18n from '@/lang'
|
import i18n from '@/lang'
|
||||||
import '@/icons/components'
|
import '@/icons/components'
|
||||||
import '@/permission'
|
import '@/permission'
|
||||||
|
import { AppModule } from '@/store/modules/app'
|
||||||
|
import * as directives from '@/directives'
|
||||||
|
|
||||||
Vue.use(ElementUI, {
|
Vue.use(ElementUI, {
|
||||||
|
size: AppModule.size,
|
||||||
i18n: (key: string, value: string) => i18n.t(key, value)
|
i18n: (key: string, value: string) => i18n.t(key, value)
|
||||||
})
|
})
|
||||||
Vue.use(SvgIcon, {
|
Vue.use(SvgIcon, {
|
||||||
@ -23,6 +26,10 @@ Vue.use(SvgIcon, {
|
|||||||
defaultHeight: '1em'
|
defaultHeight: '1em'
|
||||||
})
|
})
|
||||||
|
|
||||||
|
Object.keys(directives).forEach(key => {
|
||||||
|
Vue.directive(key, (directives as { [key: string ]: DirectiveOptions })[key])
|
||||||
|
})
|
||||||
|
// Register global directives
|
||||||
Vue.config.productionTip = false
|
Vue.config.productionTip = false
|
||||||
|
|
||||||
new Vue({
|
new Vue({
|
||||||
|
@ -8,9 +8,9 @@ import {
|
|||||||
import { getUserInfo, login, logout } from '@/api/users'
|
import { getUserInfo, login, logout } from '@/api/users'
|
||||||
import { getToken, removeToken, setToken } from '@/utils/cookies'
|
import { getToken, removeToken, setToken } from '@/utils/cookies'
|
||||||
import store from '@/store'
|
import store from '@/store'
|
||||||
import router, { resetRouter } from "@/router"
|
import router, { resetRouter } from '@/router'
|
||||||
import { PermissionModule } from "@/store/modules/permission"
|
import { PermissionModule } from '@/store/modules/permission'
|
||||||
import { TagsViewModule } from "@/store/modules/tags-view"
|
import { TagsViewModule } from '@/store/modules/tags-view'
|
||||||
|
|
||||||
export interface IUserState {
|
export interface IUserState {
|
||||||
token: string
|
token: string
|
||||||
@ -19,6 +19,7 @@ export interface IUserState {
|
|||||||
introduction: string
|
introduction: string
|
||||||
roles: string[]
|
roles: string[]
|
||||||
email: string
|
email: string
|
||||||
|
permissions: string[][]
|
||||||
}
|
}
|
||||||
|
|
||||||
@Module({ dynamic: true, store, name: 'user' })
|
@Module({ dynamic: true, store, name: 'user' })
|
||||||
@ -28,6 +29,7 @@ class User extends VuexModule implements IUserState {
|
|||||||
public avatar = ''
|
public avatar = ''
|
||||||
public introduction = ''
|
public introduction = ''
|
||||||
public roles: string[] = []
|
public roles: string[] = []
|
||||||
|
public permissions: string[][] = []
|
||||||
public email = ''
|
public email = ''
|
||||||
|
|
||||||
@Action
|
@Action
|
||||||
@ -35,7 +37,6 @@ class User extends VuexModule implements IUserState {
|
|||||||
let { username, password } = userInfo
|
let { username, password } = userInfo
|
||||||
username = username.trim()
|
username = username.trim()
|
||||||
const { data } = await login({ username, password })
|
const { data } = await login({ username, password })
|
||||||
console.log(data);
|
|
||||||
setToken(data.token)
|
setToken(data.token)
|
||||||
this.SET_TOKEN(data.token)
|
this.SET_TOKEN(data.token)
|
||||||
}
|
}
|
||||||
@ -45,6 +46,7 @@ class User extends VuexModule implements IUserState {
|
|||||||
removeToken()
|
removeToken()
|
||||||
this.SET_TOKEN('')
|
this.SET_TOKEN('')
|
||||||
this.SET_ROLES([])
|
this.SET_ROLES([])
|
||||||
|
this.SET_PERMISSIONS([])
|
||||||
}
|
}
|
||||||
|
|
||||||
@Action
|
@Action
|
||||||
@ -53,11 +55,10 @@ class User extends VuexModule implements IUserState {
|
|||||||
throw Error('GetUserInfo: token is undefined!')
|
throw Error('GetUserInfo: token is undefined!')
|
||||||
}
|
}
|
||||||
const { data } = await getUserInfo({ /* Your params here */ })
|
const { data } = await getUserInfo({ /* Your params here */ })
|
||||||
console.log(data);
|
|
||||||
if (!data) {
|
if (!data) {
|
||||||
throw Error('Verification failed, please Login again.')
|
throw Error('Verification failed, please Login again.')
|
||||||
}
|
}
|
||||||
const { roles, showname, avatar, introduction } = data
|
const { roles, showname, avatar, introduction, permissions } = data
|
||||||
// roles must be a non-empty array
|
// roles must be a non-empty array
|
||||||
if (!roles || roles.length <= 0) {
|
if (!roles || roles.length <= 0) {
|
||||||
throw Error('GetUserInfo: roles must be a non-null array!')
|
throw Error('GetUserInfo: roles must be a non-null array!')
|
||||||
@ -66,6 +67,7 @@ class User extends VuexModule implements IUserState {
|
|||||||
this.SET_NAME(showname)
|
this.SET_NAME(showname)
|
||||||
this.SET_AVATAR(avatar)
|
this.SET_AVATAR(avatar)
|
||||||
this.SET_INTRODUCTION(introduction)
|
this.SET_INTRODUCTION(introduction)
|
||||||
|
this.SET_PERMISSIONS(permissions)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Action
|
@Action
|
||||||
@ -93,6 +95,7 @@ class User extends VuexModule implements IUserState {
|
|||||||
removeToken()
|
removeToken()
|
||||||
this.SET_TOKEN('')
|
this.SET_TOKEN('')
|
||||||
this.SET_ROLES([])
|
this.SET_ROLES([])
|
||||||
|
this.SET_PERMISSIONS([])
|
||||||
}
|
}
|
||||||
|
|
||||||
@Mutation
|
@Mutation
|
||||||
@ -119,6 +122,19 @@ class User extends VuexModule implements IUserState {
|
|||||||
private SET_ROLES(roles: string[]) {
|
private SET_ROLES(roles: string[]) {
|
||||||
this.roles = roles
|
this.roles = roles
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Mutation
|
||||||
|
private SET_PERMISSIONS(permissions: string[]) {
|
||||||
|
const results: string[][] = []
|
||||||
|
for (const permission of permissions) {
|
||||||
|
if (permission === '*') {
|
||||||
|
results.push(['*', '*'])
|
||||||
|
} else {
|
||||||
|
results.push(permission.split(':'))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.permissions = results
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const UserModule = getModule(User)
|
export const UserModule = getModule(User)
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { UserModule } from '@/store/modules/user'
|
import { UserModule } from '@/store/modules/user'
|
||||||
|
|
||||||
export const checkPermission = (value: string[]): boolean => {
|
export const checkRole = (value: string[]): boolean => {
|
||||||
if (value && value instanceof Array && value.length > 0) {
|
if (value && value instanceof Array && value.length > 0) {
|
||||||
const roles = UserModule.roles
|
const roles = UserModule.roles
|
||||||
const permissionRoles = value
|
const permissionRoles = value
|
||||||
@ -13,3 +13,49 @@ export const checkPermission = (value: string[]): boolean => {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const checkPermission = (value: string[]): boolean => {
|
||||||
|
if (value && value instanceof Array && value.length > 0) {
|
||||||
|
const permissions = UserModule.permissions
|
||||||
|
let hasPermission = false
|
||||||
|
for (const sub of value) {
|
||||||
|
if (sub === '*') {
|
||||||
|
hasPermission = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
const subArr = sub.split(':')
|
||||||
|
if (subArr[0] === '*') {
|
||||||
|
for (const p of permissions) {
|
||||||
|
if (p[1] === '*' || p[1] === subArr[1]) {
|
||||||
|
hasPermission = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (subArr[1] === '*') {
|
||||||
|
for (const p of permissions) {
|
||||||
|
if (p[0] === '*' || p[0] === subArr[0]) {
|
||||||
|
hasPermission = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (const p of permissions) {
|
||||||
|
if ((p[0] === '*' && p[1] === '*') ||
|
||||||
|
(p[0] === '*' && p[1] === subArr[1]) ||
|
||||||
|
(p[0] === subArr[0] && p[1] === '*') ||
|
||||||
|
(p[0] === subArr[0] && p[1] === subArr[1])) {
|
||||||
|
hasPermission = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (hasPermission) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return hasPermission
|
||||||
|
} else {
|
||||||
|
console.error('need roles! Like v-permission="[\'admin\',\'editor\']"')
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -7,27 +7,27 @@
|
|||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<span
|
<span
|
||||||
v-permission="['admin']"
|
v-permission="['app:read']"
|
||||||
class="permission-alert"
|
class="permission-alert"
|
||||||
>
|
>
|
||||||
Only
|
Only
|
||||||
<el-tag
|
<el-tag
|
||||||
class="permission-tag"
|
class="permission-tag"
|
||||||
size="small"
|
size="small"
|
||||||
>admin</el-tag> can see this
|
>app:read</el-tag> 1 can see this
|
||||||
</span>
|
</span>
|
||||||
<el-tag
|
<el-tag
|
||||||
v-permission="['admin']"
|
v-role="['admin']"
|
||||||
class="permission-sourceCode"
|
class="permission-sourceCode"
|
||||||
type="info"
|
type="info"
|
||||||
>
|
>
|
||||||
v-permission="['admin']"
|
v-role="['admin']"
|
||||||
</el-tag>
|
</el-tag>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<span
|
<span
|
||||||
v-permission="['editor']"
|
v-role="['editor']"
|
||||||
class="permission-alert"
|
class="permission-alert"
|
||||||
>
|
>
|
||||||
Only
|
Only
|
||||||
@ -37,17 +37,17 @@
|
|||||||
>editor</el-tag> can see this
|
>editor</el-tag> can see this
|
||||||
</span>
|
</span>
|
||||||
<el-tag
|
<el-tag
|
||||||
v-permission="['editor']"
|
v-role="['editor']"
|
||||||
class="permission-sourceCode"
|
class="permission-sourceCode"
|
||||||
type="info"
|
type="info"
|
||||||
>
|
>
|
||||||
v-permission="['editor']"
|
v-role="['editor']"
|
||||||
</el-tag>
|
</el-tag>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<span
|
<span
|
||||||
v-permission="['admin','editor']"
|
v-role="['admin','editor']"
|
||||||
class="permission-alert"
|
class="permission-alert"
|
||||||
>
|
>
|
||||||
Both
|
Both
|
||||||
@ -61,17 +61,17 @@
|
|||||||
>editor</el-tag> can see this
|
>editor</el-tag> can see this
|
||||||
</span>
|
</span>
|
||||||
<el-tag
|
<el-tag
|
||||||
v-permission="['admin','editor']"
|
v-role="['admin','editor']"
|
||||||
class="permission-sourceCode"
|
class="permission-sourceCode"
|
||||||
type="info"
|
type="info"
|
||||||
>
|
>
|
||||||
v-permission="['admin','editor']"
|
v-role="['admin','editor']"
|
||||||
</el-tag>
|
</el-tag>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
:key="'checkPermission'+key"
|
:key="'checkRole'+key"
|
||||||
style="margin-top:60px;"
|
style="margin-top:60px;"
|
||||||
>
|
>
|
||||||
<aside>
|
<aside>
|
||||||
@ -84,7 +84,7 @@
|
|||||||
style="width:550px;"
|
style="width:550px;"
|
||||||
>
|
>
|
||||||
<el-tab-pane
|
<el-tab-pane
|
||||||
v-if="checkPermission(['admin'])"
|
v-if="checkRole(['admin'])"
|
||||||
label="Admin"
|
label="Admin"
|
||||||
>
|
>
|
||||||
Admin can see this
|
Admin can see this
|
||||||
@ -92,12 +92,12 @@
|
|||||||
class="permission-sourceCode"
|
class="permission-sourceCode"
|
||||||
type="info"
|
type="info"
|
||||||
>
|
>
|
||||||
v-if="checkPermission(['admin'])"
|
v-if="checkRole(['admin'])"
|
||||||
</el-tag>
|
</el-tag>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
|
|
||||||
<el-tab-pane
|
<el-tab-pane
|
||||||
v-if="checkPermission(['editor'])"
|
v-if="checkRole(['editor'])"
|
||||||
label="Editor"
|
label="Editor"
|
||||||
>
|
>
|
||||||
Editor can see this
|
Editor can see this
|
||||||
@ -105,12 +105,12 @@
|
|||||||
class="permission-sourceCode"
|
class="permission-sourceCode"
|
||||||
type="info"
|
type="info"
|
||||||
>
|
>
|
||||||
v-if="checkPermission(['editor'])"
|
v-if="checkRole(['editor'])"
|
||||||
</el-tag>
|
</el-tag>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
|
|
||||||
<el-tab-pane
|
<el-tab-pane
|
||||||
v-if="checkPermission(['admin','editor'])"
|
v-if="checkRole(['admin','editor'])"
|
||||||
label="Admin-OR-Editor"
|
label="Admin-OR-Editor"
|
||||||
>
|
>
|
||||||
Both admin or editor can see this
|
Both admin or editor can see this
|
||||||
@ -118,7 +118,19 @@
|
|||||||
class="permission-sourceCode"
|
class="permission-sourceCode"
|
||||||
type="info"
|
type="info"
|
||||||
>
|
>
|
||||||
v-if="checkPermission(['admin','editor'])"
|
v-if="checkRole(['admin','editor'])"
|
||||||
|
</el-tag>
|
||||||
|
</el-tab-pane>
|
||||||
|
<el-tab-pane
|
||||||
|
v-if="checkPermission(['app:read'])"
|
||||||
|
label="app_read"
|
||||||
|
>
|
||||||
|
Both admin or editor can see this
|
||||||
|
<el-tag
|
||||||
|
class="permission-sourceCode"
|
||||||
|
type="info"
|
||||||
|
>
|
||||||
|
v-if="checkPermission(['app:read'])"
|
||||||
</el-tag>
|
</el-tag>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
</el-tabs>
|
</el-tabs>
|
||||||
@ -128,7 +140,7 @@
|
|||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Component, Vue } from 'vue-property-decorator'
|
import { Component, Vue } from 'vue-property-decorator'
|
||||||
import { checkPermission } from '@/utils/permission' // Use permission directly
|
import { checkRole, checkPermission } from '@/utils/permission' // Use permission directly
|
||||||
import SwitchRoles from './components/SwitchRoles.vue'
|
import SwitchRoles from './components/SwitchRoles.vue'
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@ -139,6 +151,7 @@ import SwitchRoles from './components/SwitchRoles.vue'
|
|||||||
})
|
})
|
||||||
export default class extends Vue {
|
export default class extends Vue {
|
||||||
private key = 1 // 为了能每次切换权限的时候重新初始化指令
|
private key = 1 // 为了能每次切换权限的时候重新初始化指令
|
||||||
|
private checkRole = checkRole
|
||||||
private checkPermission = checkPermission
|
private checkPermission = checkPermission
|
||||||
|
|
||||||
private handleRolesChange() {
|
private handleRolesChange() {
|
||||||
|
@ -120,7 +120,7 @@ import { cloneDeep } from 'lodash'
|
|||||||
import { Component, Vue } from 'vue-property-decorator'
|
import { Component, Vue } from 'vue-property-decorator'
|
||||||
import { RouteConfig } from 'vue-router'
|
import { RouteConfig } from 'vue-router'
|
||||||
import { Tree } from 'element-ui'
|
import { Tree } from 'element-ui'
|
||||||
import { getRoutes, getRoles, createRole, deleteRole, updateRole } from '@/api/roles'
|
import { getRoutes, getRoles, saveRole, deleteRole } from '@/api/roles'
|
||||||
|
|
||||||
interface IRole {
|
interface IRole {
|
||||||
key: number
|
key: number
|
||||||
@ -302,7 +302,7 @@ export default class extends Vue {
|
|||||||
this.role.routes = this.generateTree(cloneDeep(this.serviceRoutes), '/', checkedKeys)
|
this.role.routes = this.generateTree(cloneDeep(this.serviceRoutes), '/', checkedKeys)
|
||||||
|
|
||||||
if (isEdit) {
|
if (isEdit) {
|
||||||
await updateRole(this.role.key, { role: this.role })
|
await saveRole( { role: this.role })
|
||||||
for (let index = 0; index < this.rolesList.length; index++) {
|
for (let index = 0; index < this.rolesList.length; index++) {
|
||||||
if (this.rolesList[index].key === this.role.key) {
|
if (this.rolesList[index].key === this.role.key) {
|
||||||
this.rolesList.splice(index, 1, Object.assign({}, this.role))
|
this.rolesList.splice(index, 1, Object.assign({}, this.role))
|
||||||
@ -310,7 +310,7 @@ export default class extends Vue {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const { data } = await createRole({ role: this.role })
|
const { data } = await saveRole({ role: this.role })
|
||||||
this.role.key = data.key
|
this.role.key = data.key
|
||||||
this.rolesList.push(this.role)
|
this.rolesList.push(this.role)
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user