提交 ef43b7e3 authored 作者: pengxiaohui's avatar pengxiaohui

feat: 接入权限管控

上级 aa8b5033
VITE_LOGIN_URL=https://login.ezijing.com/auth/login/index VITE_LOGIN_URL=https://login.ezijing.com/auth/login/index
\ No newline at end of file VITE_SECRET_ID=ezijing_97541c7539a341415e5ae23439ad12b8
VITE_SECRET_KEY=dd8cc780c55faf921bad2923811c68d1
VITE_LOGIN_URL=https://login2.ezijing.com/auth/login/index VITE_LOGIN_URL=https://login2.ezijing.com/auth/login/index
\ No newline at end of file VITE_SECRET_ID=ezijing_97541c7539a341415e5ae23439ad12b8
VITE_SECRET_KEY=dd8cc780c55faf921bad2923811c68d1
VITE_LOGIN_URL=https://login2.ezijing.com/auth/login/index VITE_LOGIN_URL=https://login2.ezijing.com/auth/login/index
\ No newline at end of file VITE_SECRET_ID=ezijing_97541c7539a341415e5ae23439ad12b8
VITE_SECRET_KEY=dd8cc780c55faf921bad2923811c68d1
...@@ -31,3 +31,14 @@ export function uploadFile(data) { ...@@ -31,3 +31,14 @@ export function uploadFile(data) {
export function userSearch(params) { export function userSearch(params) {
return httpRequest.get('/api/customer/admin/v1/system/search-sso-users', { params }) return httpRequest.get('/api/customer/admin/v1/system/search-sso-users', { params })
} }
// 搜索紫荆用户
export function getRole() {
return httpRequest.get('/api/customer/api/v1/user/roles')
}
/**
* 获取权限列表
*/
export function getPermissions(params) {
return httpRequest.get('/api/permissions/api/v1/user/permissions', { params })
}
\ No newline at end of file
...@@ -3,13 +3,18 @@ ...@@ -3,13 +3,18 @@
<nav class="nav"> <nav class="nav">
<el-menu :default-active="defaultActive" :router="true"> <el-menu :default-active="defaultActive" :router="true">
<template v-for="item in menuList"> <template v-for="item in menuList">
<el-submenu :index="item.path" :key="item.path" v-if="item.children"> <el-submenu :index="item.path" :key="item.path" v-if="item.children" v-show="menuVisible(item.tag)">
<template #title><i :class="item.icon"></i>{{ item.name }}</template> <template #title><i :class="item.icon"></i>{{ item.name }}</template>
<el-menu-item :index="subitem.path" v-for="subitem in item.children" :key="subitem.path"> <el-menu-item
:index="subitem.path"
v-for="subitem in item.children"
:key="subitem.path"
v-show="menuVisible(item.tag)"
>
{{ subitem.name }} {{ subitem.name }}
</el-menu-item> </el-menu-item>
</el-submenu> </el-submenu>
<el-menu-item :index="item.path" :key="item.path" v-else> <el-menu-item :index="item.path" :key="item.path" v-else v-show="menuVisible(item.tag)">
<i :class="item.icon"></i>{{ item.name }} <i :class="item.icon"></i>{{ item.name }}
</el-menu-item> </el-menu-item>
</template> </template>
...@@ -25,15 +30,17 @@ export default { ...@@ -25,15 +30,17 @@ export default {
return { return {
menuList: [ menuList: [
{ {
tag: 'menu_customer_manage',
name: '大客户管理', name: '大客户管理',
path: '/customer-manage', path: '/customer-manage',
icon: 'el-icon-user' icon: 'el-icon-user'
}, },
{ {
tag: 'menu_system_manage',
name: '系统管理', name: '系统管理',
path: '/system/customergroup', path: '/system/customergroup',
icon: 'el-icon-setting', icon: 'el-icon-setting',
children: [{ name: '客户组管理', path: '/system/customergroup' }] children: [{ tag: 'menu_customer_group_manage', name: '客户组管理', path: '/system/customergroup' }]
} }
] ]
} }
...@@ -41,6 +48,18 @@ export default { ...@@ -41,6 +48,18 @@ export default {
computed: { computed: {
defaultActive() { defaultActive() {
return this.$route.path return this.$route.path
},
// 菜单权限
menuPermissions() {
return this.$store.state.permissions.filter(item => item.type === 2)
}
},
methods: {
menuVisible(tag) {
if (!tag) {
return true
}
return !!this.menuPermissions.find(item => item.tag === tag)
} }
} }
} }
...@@ -54,7 +73,7 @@ export default { ...@@ -54,7 +73,7 @@ export default {
width: 240px; width: 240px;
z-index: 100; z-index: 100;
background: #fff; background: #fff;
height:100%; height: 100%;
border-right: 1px solid rgba(0, 0, 0, 0.12); border-right: 1px solid rgba(0, 0, 0, 0.12);
overflow-x: hidden; overflow-x: hidden;
overflow-y: auto; overflow-y: auto;
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
<app-card class="customer"> <app-card class="customer">
<app-list v-bind="tableOptions" ref="list" searchResetSeparateLine> <app-list v-bind="tableOptions" ref="list" searchResetSeparateLine>
<template #filter-bar-right> <template #filter-bar-right>
<el-button type="primary" size="small" @click="dialogVisible = true">创建客户</el-button> <el-button v-if="btnCreate" type="primary" size="small" @click="dialogVisible = true">创建客户</el-button>
</template> </template>
<!-- 筛选 --> <!-- 筛选 -->
<template v-slot:filter-date="{ params }"> <template v-slot:filter-date="{ params }">
...@@ -39,8 +39,8 @@ ...@@ -39,8 +39,8 @@
<!-- 操作 --> <!-- 操作 -->
<template v-slot:table-operate="{ row }"> <template v-slot:table-operate="{ row }">
<template> <template>
<el-button type="text" @click="handleDetails(row)" size="mini">查看</el-button> <el-button v-if="btnDetails" type="text" @click="handleDetails(row)" size="mini">查看</el-button>
<el-button type="text" @click="handleRemove(row)" size="mini">删除</el-button> <el-button v-if="btnDelete" type="text" @click="handleRemove(row)" size="mini">删除</el-button>
</template> </template>
</template> </template>
</app-list> </app-list>
...@@ -97,6 +97,18 @@ export default { ...@@ -97,6 +97,18 @@ export default {
} }
}, },
computed: { computed: {
btnPermissions() {
return this.$store.state.permissions.filter(item => item.type === 4)
},
btnCreate() {
return !!this.btnPermissions.find(item => item.tag === 'btn_customer_create')
},
btnDelete() {
return !!this.btnPermissions.find(item => item.tag === 'btn_customer_delete')
},
btnDetails() {
return !!this.btnPermissions.find(item => item.tag === 'btn_customer_details')
},
// 列表配置 // 列表配置
tableOptions() { tableOptions() {
return { return {
...@@ -125,16 +137,6 @@ export default { ...@@ -125,16 +137,6 @@ export default {
{ prop: 'create_date', slots: 'filter-date', label: '创建时间:', class: 'filter-form-item' }, { prop: 'create_date', slots: 'filter-date', label: '创建时间:', class: 'filter-form-item' },
{ prop: 'follow_date', slots: 'filter-follow-date', label: '最近跟进时间:' }, { prop: 'follow_date', slots: 'filter-follow-date', label: '最近跟进时间:' },
{ prop: 'created_by', slots: 'filter-create-by', label: '创建员工:' }, { prop: 'created_by', slots: 'filter-create-by', label: '创建员工:' },
// {
// type: 'select',
// placeholder: '请选择创建员工',
// prop: 'creator',
// options: this.staffList,
// labelKey: 'name',
// valueKey: 'id',
// size: 'small',
// label: '创建员工:'
// },
{ {
type: 'input', type: 'input',
prop: 'name', prop: 'name',
...@@ -232,6 +234,12 @@ export default { ...@@ -232,6 +234,12 @@ export default {
} }
}, },
methods: { methods: {
btnVisible(tag) {
if (!tag) {
return true
}
return !!this.btnPermissions.find(item => item.tag === tag)
},
beforeRequest(params) { beforeRequest(params) {
const _params = Object.assign({}, params) const _params = Object.assign({}, params)
for (const key in _params) { for (const key in _params) {
......
...@@ -37,6 +37,9 @@ export default { ...@@ -37,6 +37,9 @@ export default {
} }
}, },
computed: { computed: {
btnPermissions() {
return this.$store.state.permissions.filter(item => item.type === 4)
},
// 列表配置 // 列表配置
tableOptions() { tableOptions() {
return { return {
......
import Vue from 'vue' import Vue from 'vue'
import Vuex from 'vuex' import Vuex from 'vuex'
import { getUser, logout } from '@/api/base' import { getUser, logout, getPermissions } from '@/api/base'
Vue.use(Vuex) Vue.use(Vuex)
export default new Vuex.Store({ const store = new Vuex.Store({
state: { state: {
user: {} user: {},
permissions: [] // 权限列表
}, },
mutations: { mutations: {
setUser(state, user) { setUser(state, user) {
state.user = user state.user = user
},
setPermissions(state, permissions) {
state.permissions = permissions
} }
}, },
actions: { actions: {
getPermissions({ commit }) {
getPermissions().then(res => {
if (res.data && res.data.items) {
commit('setPermissions', res.data.items)
}
})
},
// 获取用户信息 // 获取用户信息
getUser({ commit }) { getUser({ commit }) {
getUser().then(response => { getUser().then(response => {
...@@ -46,3 +57,7 @@ export default new Vuex.Store({ ...@@ -46,3 +57,7 @@ export default new Vuex.Store({
} }
} }
}) })
// 获取权限列表
store.dispatch('getPermissions')
export default store
import axios from 'axios' import axios from 'axios'
import queryString from 'query-string' import queryString from 'query-string'
import { Message } from 'element-ui' import { Message } from 'element-ui'
import router from '../router'
const httpRequest = axios.create({ const httpRequest = axios.create({
timeout: 60000, timeout: 60000,
withCredentials: true withCredentials: true
// headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
}) })
// 请求拦截 // 请求拦截
httpRequest.interceptors.request.use( httpRequest.interceptors.request.use(
function (config) { function (config) {
// 权限接口单独签名
// https://gitlab.ezijing.com/root/api-documents/-/blob/master/ezijing_permissions/%E7%AD%BE%E5%90%8D%E9%AA%8C%E8%AF%81.md
if (/^\/api\/permissions/.test(config.url)) {
// 默认参数
const defaultHeaders = {
timestamp: parseInt(Date.now() / 1000),
nonce: Math.random().toString(36).slice(-8),
'secret-id': import.meta.env.VITE_SECRET_ID,
'secret-key': import.meta.env.VITE_SECRET_KEY,
signature: 'UG7wBenexQhiuD2wpCwuxkU0jqcj006d'
}
config.headers = Object.assign(config.headers, defaultHeaders)
}
if (config.headers['Content-Type'] === 'application/x-www-form-urlencoded') { if (config.headers['Content-Type'] === 'application/x-www-form-urlencoded') {
config.data = queryString.stringify(config.data) config.data = queryString.stringify(config.data)
} }
...@@ -31,10 +47,20 @@ httpRequest.interceptors.request.use( ...@@ -31,10 +47,20 @@ httpRequest.interceptors.request.use(
httpRequest.interceptors.response.use( httpRequest.interceptors.response.use(
function (response) { function (response) {
const { data } = response const { data } = response
if (data.code) { // 正常返回
return Promise.reject(data) if (data.code === 0) {
return data
}
// 未登录
if (data.code === 4001) {
window.location.href = `${import.meta.env.VITE_LOGIN_URL}?rd=${encodeURIComponent(window.location.href)}`
}
// 没有权限
if (data.code === 4008) {
router.push('/401')
} }
return data Message({ message: data.message, type: 'error' })
return Promise.reject(data)
}, },
function (error) { function (error) {
if (error.response) { if (error.response) {
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论