提交 0259b09d authored 作者: matian's avatar matian

增加权限

上级 df2c6b5d
......@@ -32,15 +32,20 @@ const defaultActive = computed(() => {
<nav class="nav">
<el-menu :default-active="defaultActive" :router="true">
<template v-for="item in menus" :key="item.path">
<el-sub-menu :index="item.path" v-if="item.children">
<el-sub-menu :index="item.path" v-permission="item.tag" v-if="item.children">
<template #title>
<el-icon><component :is="item.icon"></component></el-icon>{{ 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-permission="subitem.tag"
>
{{ subitem.name }}
</el-menu-item>
</el-sub-menu>
<el-menu-item :index="item.path" v-else>
<el-menu-item :index="item.path" v-permission="item.tag" v-else>
<el-icon><component :is="item.icon"></component></el-icon>{{ item.name }}
</el-menu-item>
</template>
......
......@@ -3,15 +3,15 @@ export default { name: 'AppHeader' }
</script>
<script setup lang="ts">
import { useUserStore } from '@/stores/user'
import { useInfoStore } from '@/stores/index'
withDefaults(defineProps<{ hasTitle?: boolean }>(), {
hasTitle: true
})
const userStore = useUserStore()
const userStore = useInfoStore()
const userInfo = userStore.user
const userInfo = userStore.info
const logout = async () => {
await userStore.logout()
......@@ -39,7 +39,7 @@ const logout = async () => {
<img :src="userInfo.avatar || 'https://webapp-pub.ezijing.com/website/base/images/avatar.svg'" />
</div>
<div class="app-header-user-main">
<h3>{{ userStore.userName }}</h3>
<h3>{{ userStore.name }}</h3>
<p>{{ userInfo.email || userInfo.mobile }}</p>
</div>
<div class="app-header-user-buttons">
......
......@@ -7,7 +7,7 @@ export const routes: Array<RouteRecordRaw> = [
component: AppLayout,
children: [
{ path: '', component: () => import('./views/List.vue') },
{ path: '/channel/bp/detail/:id', component: () => import('./views/View.vue'), props: true }
{ path: '/channel/bp/detail', component: () => import('./views/View.vue') }
]
}
]
<script setup lang="ts">
import shortcuts from '@/utils/shortcut'
import { getConditionList, getChannelList } from '../api'
const router = useRouter()
const tagsList = ref([])
getConditionList({ channel: true }).then(res => {
tagsList.value = res.data.channel.tags.reduce((t: any, cur: any) => {
t.push({ id: res.data.channel.tags.indexOf(cur), name: cur })
......@@ -10,101 +9,7 @@ getConditionList({ channel: true }).then(res => {
}, [])
console.log(tagsList.value)
})
const shortcuts = [
{
text: '今日',
value: () => {
const end = new Date()
const start = new Date()
start.setTime(new Date(new Date().toLocaleDateString()).getTime())
return [start, end.setHours(23, 59, 59, 999)]
}
},
{
text: '昨日',
value: () => {
// const end = new Date()
const start = new Date()
start.setTime(start.getTime() - 3600 * 1000 * 24)
return [start.setHours(0, 0, 0, 0), start.setHours(23, 59, 59, 999)]
}
},
{
text: '本周',
value: () => {
// let weeks = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六']
const end = new Date()
const start = new Date()
console.log(start.getDay())
start.setTime(start.getTime() - 3600 * 1000 * 24 * (start.getDay() - 1))
return [start.setHours(0, 0, 0, 0), end]
}
},
{
text: '上周',
value: () => {
const end = new Date()
const start = new Date()
start.setTime(start.getTime() - 3600 * 1000 * 24 * (start.getDay() + 6))
end.setTime(end.getTime() - 3600 * 1000 * 24 * end.getDay())
return [start.setHours(0, 0, 0, 0), end.setHours(23, 59, 59, 999)]
}
},
{
text: '过去7天',
value: () => {
const end = new Date()
const start = new Date()
start.setTime(start.getTime() - 3600 * 1000 * 24 * 7)
return [start.setHours(0, 0, 0, 0), end.setHours(23, 59, 59, 999)]
}
},
{
text: '过去14天',
value: () => {
const end = new Date()
const start = new Date()
start.setTime(start.getTime() - 3600 * 1000 * 24 * 14)
return [start.setHours(0, 0, 0, 0), end.setHours(23, 59, 59, 999)]
}
},
{
text: '过去30天',
value: () => {
const end = new Date()
const start = new Date()
start.setTime(start.getTime() - 3600 * 1000 * 24 * 30)
return [start.setHours(0, 0, 0, 0), end.setHours(23, 59, 59, 999)]
}
},
{
text: '过去60天',
value: () => {
const end = new Date()
const start = new Date()
start.setTime(start.getTime() - 3600 * 1000 * 24 * 60)
return [start.setHours(0, 0, 0, 0), end.setHours(23, 59, 59, 999)]
}
},
{
text: '过去90天',
value: () => {
const end = new Date()
const start = new Date()
start.setTime(start.getTime() - 3600 * 1000 * 24 * 90)
return [start.setHours(0, 0, 0, 0), end.setHours(23, 59, 59, 999)]
}
},
{
text: '过去180天',
value: () => {
const end = new Date()
const start = new Date()
start.setTime(start.getTime() - 3600 * 1000 * 24 * 180)
return [start.setHours(0, 0, 0, 0), end.setHours(23, 59, 59, 999)]
}
}
]
// 列表配置
const listOptions = $computed(() => {
return {
......@@ -188,9 +93,9 @@ const listOptions = $computed(() => {
</template>
<template #table-x="{ row }">
<router-link :to="`/channel/bp/detail/?id=${row.id}`" target="_blank">
<el-link type="primary" plain>查看</el-link>
</router-link>
<el-button type="primary" link v-permission="'channel-index-view'">
<router-link :to="`/channel/bp/detail/?id=${row.id}`" target="_blank">查看</router-link>
</el-button>
</template>
</AppList>
</AppCard>
......
......@@ -44,7 +44,7 @@ const listOptions1 = $computed(() => {
<template>
<AppCard title="基本信息">
<el-descriptions :column="4">
<el-descriptions :column="4" border>
<el-descriptions-item label="渠道编号">{{ channelInfo.channel_id || '-' }}</el-descriptions-item>
<el-descriptions-item label="渠道名称">{{ channelInfo.title || '-' }}</el-descriptions-item>
<el-descriptions-item label="状态">{{ channelInfo.channel_status_name || '-' }}</el-descriptions-item>
......
......@@ -30,22 +30,14 @@ const init = () => {
x: 'center',
left: '20%',
orient: 'vertical',
data: [
{ value: 1048, name: 'ZWS客户' },
{ value: 735, name: '院校客户' },
{ value: 580, name: '渠道客户' }
] //水平排列。(vertical为垂直排列}}
data: [{ name: 'ZWS客户' }, { name: '院校客户' }, { name: '渠道客户' }] //水平排列。(vertical为垂直排列}}
},
{
x: 'center',
top: 'bottom',
orient: 'vertical',
left: '60%',
data: [
{ value: 484, name: '尘峰客户' },
{ value: 300, name: '企微客户' },
{ value: 300, name: '小鹅通客户' }
] //水平排列。(vertical为垂直排列}}
data: [{ name: '尘峰客户' }, { name: '企微客户' }, { name: '小鹅通客户' }] //水平排列。(vertical为垂直排列}}
}
],
series: [
......
......@@ -44,10 +44,16 @@ const handleRefetch = () => {
<template>
<AppCard title="联系人信息">
<AppList v-bind="listOptions" ref="appList">
<el-button type="primary" style="margin-bottom: 20px" @click="handleBatchImport">批量导入</el-button>
<el-button
type="primary"
style="margin-bottom: 20px"
@click="handleBatchImport"
v-permission="'school-user-import'"
>批量导入</el-button
>
<template #table-x="{ row }">
<el-button type="primary" link>
<el-button type="primary" link v-permission="'school-user-view'">
<router-link :to="`/school/contact/detail/${row.id}`" target="_blank">查看</router-link>
</el-button>
</template>
......
......@@ -44,10 +44,16 @@ const handleRefetch = () => {
<template>
<AppCard title="项目信息">
<AppList v-bind="listOptions" ref="appList">
<el-button type="primary" style="margin-bottom: 20px" @click="handleBatchImport">批量导入</el-button>
<el-button
type="primary"
style="margin-bottom: 20px"
@click="handleBatchImport"
v-permission="'school-project-import'"
>批量导入</el-button
>
<template #table-x="{ row }">
<el-button type="primary" link>
<el-button type="primary" link v-permission="'school-project-view'">
<router-link :to="`/school/project/detail/${row.id}`" target="_blank">查看</router-link>
</el-button>
</template>
......
......@@ -42,9 +42,15 @@ const handleRefetch = () => {
<template>
<AppCard title="学校信息">
<AppList v-bind="listOptions" ref="appList">
<el-button type="primary" style="margin-bottom: 20px" @click="handleBatchImport">批量导入</el-button>
<el-button
type="primary"
style="margin-bottom: 20px"
@click="handleBatchImport"
v-permission="'school-school-import'"
>批量导入</el-button
>
<template #table-x="{ row }">
<el-button type="primary" link>
<el-button type="primary" link v-permission="'school-school-view'">
<router-link :to="`/school/school/${row.id}`" target="_blank">查看</router-link>
</el-button>
</template>
......
......@@ -102,13 +102,13 @@ const listOptions = $computed(() => {
const handleDetail = (row: any) => {
if (row.system_id === 'zws') {
router.push(`/user/zws/detail/${row.id}`)
router.push(`/user/zws/detail/?id=${row.id}`)
} else if (row.system_id === 'wechat') {
router.push(`/user/weixin/detail/${row.id}`)
router.push(`/user/weixin/detail/?id=${row.id}`)
} else if (row.system_id === 'dustess') {
router.push(`/user/chenfeng/detail/${row.id}`)
router.push(`/user/chenfeng/detail/?id=${row.id}`)
} else if (row.system_id === 'xiaoe') {
router.push(`/user/xiaoetong/detail/${row.id}`)
router.push(`/user/xiaoetong/detail/?id=${row.id}`)
}
}
</script>
......
......@@ -133,9 +133,9 @@ const listOptions = $computed(() => {
</template>
<template #table-x="{ row }">
<router-link :to="`/user/xiaoetong/detail/?id=${row.id}`" target="_blank">
<el-link type="primary" plain>查看</el-link>
</router-link>
<el-button type="primary" link v-permission="'customer-xiaoe-view'">
<router-link :to="`/user/xiaoetong/detail/?id=${row.id}`" target="_blank">查看</router-link>
</el-button>
</template>
</AppList>
</AppCard>
......
......@@ -112,9 +112,9 @@ const listOptions = $computed(() => {
</template>
<template #table-x="{ row }">
<router-link :to="`/user/chenfeng/detail/?id=${row.id}`" target="_blank">
<el-link type="primary" plain>查看</el-link>
</router-link>
<el-button type="primary" link v-permission="'customer-dustess-view'">
<router-link :to="`/user/chenfeng/detail/?id=${row.id}`" target="_blank">查看</router-link>
</el-button>
</template>
</AppList>
</AppCard>
......
......@@ -12,7 +12,6 @@ getPeakUserDetail(params).then(res => {
res.data.custom_fields = JSON.parse(res.data.custom_fields)
infoList.value = res.data
})
console.log(route.query.id, '0000')
</script>
<template>
......
......@@ -148,9 +148,9 @@ const listOptions = $computed(() => {
<div v-for="(item, index) in row.follow" :key="index">{{ item.createtime }}</div>
</template>
<template #table-x="{ row }">
<router-link :to="`/user/weixin/detail/?id=${row.external_userid}`" target="_blank">
<el-link type="primary" plain>查看</el-link>
</router-link>
<el-button type="primary" link v-permission="'customer-wechat-view'">
<router-link :to="`/user/weixin/detail/?id=${row.external_userid}`" target="_blank">查看</router-link>
</el-button>
</template>
</AppList>
</AppCard>
......
......@@ -7,7 +7,7 @@ export const routes: Array<RouteRecordRaw> = [
component: AppLayout,
children: [
{ path: '', component: () => import('./views/List.vue') },
{ path: '/user/zws/detail/:id', component: () => import('./views/View.vue'), props: true }
{ path: '/user/zws/detail', component: () => import('./views/View.vue') }
]
}
]
......@@ -139,9 +139,9 @@ const listOptions = $computed(() => {
/>
</template>
<template #table-x="{ row }">
<router-link :to="`/user/zws/detail/?id=${row.id}`" target="_blank">
<el-link type="primary" plain>查看</el-link>
</router-link>
<el-button type="primary" link v-permission="'customer-zws-view'">
<router-link :to="`/user/zws/detail/?id=${row.id}`" target="_blank">查看</router-link>
</el-button>
</template>
</AppList>
</AppCard>
......
import { createRouter, createWebHistory } from 'vue-router'
import { useUserStore } from '@/stores/user'
import { useInfoStore } from '@/stores/index'
const router = createRouter({
history: createWebHistory(),
......@@ -8,10 +8,10 @@ const router = createRouter({
router.beforeEach(async (to, from, next) => {
const whiteList = ['/401']
const user = useUserStore()
const user = useInfoStore()
if (!user.isLogin && !whiteList.includes(to.path)) {
try {
await user.getUser()
await user.getUserInfo()
} catch (e) {
console.error(e)
}
......
import { defineStore } from 'pinia'
import { getUserInfo } from '@/api/base'
export interface IUserType {
info: IInfo[]
import { getUserInfo, logout } from '@/api/base'
import type { IInfo, IPermissions } from '@/types'
interface IUserType {
info: IInfo | null
permissions: IPermissions[]
roles: []
}
export interface IInfo {
id: string
mobile: string
name: string
email: string
username: string
avatar: string
auth_key: null
}
export interface IPermissions {
id: string
name: string
tag: string
parent_id: string
type: number
desc: string
effect_uris: string
}
export const useInfoStore = defineStore({
id: 'map',
state: (): IUserType => {
return {
info: [],
info: null,
permissions: [],
roles: []
}
},
getters: {
isLogin: state => !!state.info,
userName: ({ info }) => {
if (!info) return ''
return info.name || info.username || ''
}
},
actions: {
async getUserInfo() {
const res = await getUserInfo()
this.info = res.data.info || []
this.info = res.data.info
this.permissions = res.data.permissions || []
this.roles = res.data.roles || []
},
async logout() {
await logout()
this.info = null
}
}
})
useInfoStore().getUserInfo()
......@@ -9,38 +9,46 @@ interface State {
// 学生菜单
const menus: IMenuItem[] = [
{
tag: 'index',
name: '主页',
path: '/',
icon: markRaw(House)
},
{
tag: 'customer',
name: '学员信息',
path: '/user',
icon: markRaw(User),
children: [
{
tag: 'customer-all',
name: '全部学员信息',
path: '/user/all'
},
{
tag: 'customer-zws',
name: 'ZWS学员信息',
path: '/user/zws'
},
{
tag: 'customer-wechat',
name: '企微客户',
path: '/user/weixin'
},
{
tag: 'customer-xiaoe',
name: '小鹅通客户',
path: '/user/xiaoetong'
},
{
tag: 'customer-dustess',
name: '尘峰客户',
path: '/user/chenfeng'
}
]
},
{
tag: 'channel',
name: '渠道信息',
path: '/channel',
icon: markRaw(Monitor),
......@@ -52,19 +60,23 @@ const menus: IMenuItem[] = [
]
},
{
tag: 'school',
name: '学校信息',
path: '/school',
icon: markRaw(School),
children: [
{
tag: 'school-school',
name: '学校信息',
path: '/school/school'
},
{
tag: 'school-project',
name: '项目信息',
path: '/school/project'
},
{
tag: 'school-user',
name: '联系人信息',
path: '/school/contact'
}
......
import { defineStore } from 'pinia'
import { getUser, logout } from '@/api/base'
import type { UserType, PermissionType } from '@/types'
interface State {
user: UserType | null
permissions: PermissionType[]
}
export const useUserStore = defineStore({
id: 'user',
state: (): State => ({
user: null,
permissions: []
}),
getters: {
isLogin: state => !!state.user,
userName: ({ user }) => {
if (!user) return ''
return user.realname || user.nickname || user.username || ''
}
},
actions: {
async getUser() {
const res = await getUser()
this.user = res.data
},
async logout() {
await logout()
this.user = null
}
}
})
......@@ -9,26 +9,22 @@ export interface IMenuItem {
}
// 用户信息
export interface UserType {
export interface IInfo {
id: string
mobile: string
name: string
email: string
realname: string
username: string
nickname: string
avatar: string
auth_key: null
}
// 权限信息
export interface PermissionType {
desc: string
effect_uris: string
export interface IPermissions {
id: string
name: string
tag: string
parent_id: string
system_tag: number
type: number
tag: string
desc: string
effect_uris: string
}
import { useUserStore } from '@/stores/user'
import { useInfoStore } from '@/stores/index'
import type { DirectiveBinding } from 'vue'
// 判断是否有权限
export function checkPermission(value: string | string[]): boolean {
const userStore = useUserStore()
const userStore = useInfoStore()
const permissions = userStore.permissions
if (Array.isArray(value)) {
return permissions.some(item => value.includes(item.tag))
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论