Commit 2141ddd645db7cec14005e74e2a6e332ff19e6d7

Authored by ww
1 parent ad8907e8

feat: implement Authorization control

@@ -5,29 +5,39 @@ @@ -5,29 +5,39 @@
5 import { Tooltip } from 'ant-design-vue'; 5 import { Tooltip } from 'ant-design-vue';
6 import SvgIcon from '/@/components/Icon/src/SvgIcon.vue'; 6 import SvgIcon from '/@/components/Icon/src/SvgIcon.vue';
7 import { MoreActionEvent } from '../../config/config'; 7 import { MoreActionEvent } from '../../config/config';
  8 + import { computed } from '@vue/reactivity';
  9 + import { usePermission } from '/@/hooks/web/usePermission';
8 10
9 const emit = defineEmits(['action']); 11 const emit = defineEmits(['action']);
10 const props = defineProps<{ 12 const props = defineProps<{
11 id: string; 13 id: string;
12 }>(); 14 }>();
13 -  
14 - const dropMenuList: DropMenu[] = [  
15 - {  
16 - text: '编辑组件',  
17 - event: MoreActionEvent.EDIT,  
18 - icon: 'ant-design:edit-outlined',  
19 - },  
20 - {  
21 - text: '复制组件',  
22 - event: MoreActionEvent.COPY,  
23 - icon: 'ant-design:copy-outlined',  
24 - },  
25 - {  
26 - text: '删除组件',  
27 - event: MoreActionEvent.DELETE,  
28 - icon: 'ant-design:delete-outlined',  
29 - },  
30 - ]; 15 + const { hasPermission } = usePermission();
  16 + const dropMenuList = computed<DropMenu[]>(() => {
  17 + const basicMenu: DropMenu[] = [];
  18 + const hasUpdatePermission = hasPermission('api:yt:dataBoardDetail:update');
  19 + const hasDeletePermission = hasPermission('api:yt:dataBoardDetail:delete');
  20 + const hasCopyPermission = hasPermission('api:yt:dataBoardDetail:copy');
  21 + if (hasUpdatePermission)
  22 + basicMenu.push({
  23 + text: '编辑组件',
  24 + event: MoreActionEvent.EDIT,
  25 + icon: 'ant-design:edit-outlined',
  26 + });
  27 + if (hasDeletePermission)
  28 + basicMenu.push({
  29 + text: '删除组件',
  30 + event: MoreActionEvent.DELETE,
  31 + icon: 'ant-design:delete-outlined',
  32 + });
  33 + if (hasCopyPermission)
  34 + basicMenu.push({
  35 + text: '复制组件',
  36 + event: MoreActionEvent.COPY,
  37 + icon: 'ant-design:copy-outlined',
  38 + });
  39 + return basicMenu;
  40 + });
31 41
32 const handleMenuEvent = (event: DropMenu) => { 42 const handleMenuEvent = (event: DropMenu) => {
33 emit('action', event, props.id); 43 emit('action', event, props.id);
@@ -50,7 +60,12 @@ @@ -50,7 +60,12 @@
50 <Tooltip title="趋势"> 60 <Tooltip title="趋势">
51 <LineChartOutlined class="cursor-pointer mx-2" /> 61 <LineChartOutlined class="cursor-pointer mx-2" />
52 </Tooltip> 62 </Tooltip>
53 - <Dropdown :drop-menu-list="dropMenuList" :trigger="['click']" @menu-event="handleMenuEvent"> 63 + <Dropdown
  64 + v-if="dropMenuList.length"
  65 + :drop-menu-list="dropMenuList"
  66 + :trigger="['click']"
  67 + @menu-event="handleMenuEvent"
  68 + >
54 <Tooltip title="更多"> 69 <Tooltip title="更多">
55 <MoreOutlined class="transform rotate-90 cursor-pointer" /> 70 <MoreOutlined class="transform rotate-90 cursor-pointer" />
56 </Tooltip> 71 </Tooltip>
@@ -22,6 +22,7 @@ @@ -22,6 +22,7 @@
22 import { useMessage } from '/@/hooks/web/useMessage'; 22 import { useMessage } from '/@/hooks/web/useMessage';
23 import { DataBoardLayoutInfo } from '../types/type'; 23 import { DataBoardLayoutInfo } from '../types/type';
24 import { WidgetComponentType } from './config/visualOptions'; 24 import { WidgetComponentType } from './config/visualOptions';
  25 + import Authority from '/@/components/Authority/src/Authority.vue';
25 26
26 const ROUTE = useRoute(); 27 const ROUTE = useRoute();
27 28
@@ -246,7 +247,9 @@ @@ -246,7 +247,9 @@
246 <section class="bg-light-50 flex flex-col overflow-hidden h-full w-full"> 247 <section class="bg-light-50 flex flex-col overflow-hidden h-full w-full">
247 <PageHeader title="水电表看板" @back="handleBack"> 248 <PageHeader title="水电表看板" @back="handleBack">
248 <template #extra> 249 <template #extra>
249 - <Button type="primary" @click="handleOpenCreatePanel">创建组件</Button> 250 + <Authority value="api:yt:dataBoardDetail:post">
  251 + <Button type="primary" @click="handleOpenCreatePanel">创建组件</Button>
  252 + </Authority>
250 </template> 253 </template>
251 <div> 254 <div>
252 <span class="mr-3 text-gray-400">已创建组件:</span> 255 <span class="mr-3 text-gray-400">已创建组件:</span>
@@ -15,6 +15,9 @@ @@ -15,6 +15,9 @@
15 import { ViewType } from './config/panelDetail'; 15 import { ViewType } from './config/panelDetail';
16 import { useRouter } from 'vue-router'; 16 import { useRouter } from 'vue-router';
17 import { getBoundingClientRect } from '/@/utils/domUtils'; 17 import { getBoundingClientRect } from '/@/utils/domUtils';
  18 + import Authority from '/@/components/Authority/src/Authority.vue';
  19 + import { computed } from '@vue/reactivity';
  20 + import { usePermission } from '/@/hooks/web/usePermission';
18 21
19 const ListItem = List.Item; 22 const ListItem = List.Item;
20 const router = useRouter(); 23 const router = useRouter();
@@ -50,21 +53,28 @@ @@ -50,21 +53,28 @@
50 const { clipboardRef } = useCopyToClipboard(); 53 const { clipboardRef } = useCopyToClipboard();
51 const handleCopyShareUrl = (record: DataBoardRecord) => { 54 const handleCopyShareUrl = (record: DataBoardRecord) => {
52 clipboardRef.value = record.openUrl; 55 clipboardRef.value = record.openUrl;
53 - unref(clipboardRef) && createMessage.success('复制成功'); 56 + unref(clipboardRef) ? createMessage.success('复制成功') : createMessage.error('未找到分享链接');
54 }; 57 };
55 58
56 - const dropMenuList: DropMenu[] = [  
57 - {  
58 - text: '编辑',  
59 - event: MoreActionEvent.EDIT,  
60 - icon: 'ant-design:edit-outlined',  
61 - },  
62 - {  
63 - text: '删除',  
64 - event: MoreActionEvent.DELETE,  
65 - icon: 'ant-design:delete-outlined',  
66 - },  
67 - ]; 59 + const { hasPermission } = usePermission();
  60 + const dropMenuList = computed<DropMenu[]>(() => {
  61 + const hasUpdatePermission = hasPermission('api:yt:dataBoard:update');
  62 + const hasDeletePermission = hasPermission('api:yt:dataBoard:delete');
  63 + const basicMenu: DropMenu[] = [];
  64 + if (hasUpdatePermission)
  65 + basicMenu.push({
  66 + text: '编辑',
  67 + event: MoreActionEvent.EDIT,
  68 + icon: 'ant-design:edit-outlined',
  69 + });
  70 + if (hasDeletePermission)
  71 + basicMenu.push({
  72 + text: '删除',
  73 + event: MoreActionEvent.DELETE,
  74 + icon: 'ant-design:delete-outlined',
  75 + });
  76 + return basicMenu;
  77 + });
68 78
69 const getDatasource = async () => { 79 const getDatasource = async () => {
70 try { 80 try {
@@ -117,7 +127,8 @@ @@ -117,7 +127,8 @@
117 const [registerModal, { openModal }] = useModal(); 127 const [registerModal, { openModal }] = useModal();
118 128
119 const handleViewBoard = (record: DataBoardRecord) => { 129 const handleViewBoard = (record: DataBoardRecord) => {
120 - router.push(`/data/board/detail/${record.id}`); 130 + const hasDetailPermission = hasPermission('api:yt:dataBoard:detail');
  131 + if (hasDetailPermission) router.push(`/data/board/detail/${record.id}`);
121 }; 132 };
122 133
123 const handlePagenationPosition = () => { 134 const handlePagenationPosition = () => {
@@ -143,7 +154,9 @@ @@ -143,7 +154,9 @@
143 <PageWrapper> 154 <PageWrapper>
144 <div class="flex mb-6 items-center"> 155 <div class="flex mb-6 items-center">
145 <div class="text-lg mr-6 font-bold">自定义看板</div> 156 <div class="text-lg mr-6 font-bold">自定义看板</div>
146 - <Button type="primary" @click="handleOpenDetailModal">创建看板</Button> 157 + <Authority value="api:yt:dataBoard:post">
  158 + <Button type="primary" @click="handleOpenDetailModal">创建看板</Button>
  159 + </Authority>
147 </div> 160 </div>
148 <Spin :spinning="loading"> 161 <Spin :spinning="loading">
149 <List 162 <List
@@ -157,6 +170,7 @@ @@ -157,6 +170,7 @@
157 <Card class="data-card cursor-pointer"> 170 <Card class="data-card cursor-pointer">
158 <template #extra> 171 <template #extra>
159 <Dropdown 172 <Dropdown
  173 + v-if="dropMenuList.length"
160 :trigger="['click']" 174 :trigger="['click']"
161 @menu-event="(event) => handleMenuEvent(event, item)" 175 @menu-event="(event) => handleMenuEvent(event, item)"
162 :drop-menu-list="dropMenuList" 176 :drop-menu-list="dropMenuList"