Commit 95e6bb261e35bfae9126b1ca11d8f5cd67b4cafc

Authored by ww
1 parent 7880b723

fix: set product profile button permission

  1 +<svg t="1671442803003" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4002" width="200" height="200"><path d="M0 0m178.086957 0l667.826086 0q178.086957 0 178.086957 178.086957l0 667.826086q0 178.086957-178.086957 178.086957l-667.826086 0q-178.086957 0-178.086957-178.086957l0-667.826086q0-178.086957 178.086957-178.086957Z" fill="#2E7BFC" p-id="4003"></path><path d="M758.717217 394.373565v268.866783l-238.191304 134.455652v-268.911304l124.14887-70.054957v94.497391l51.956869-29.985391V429.412174l62.107826-35.038609z m-493.434434 0l238.191304 134.433392v268.866782l-238.191304-134.433391V394.373565zM512 226.304l246.717217 139.241739L512 504.787478l-246.717217-139.241739L512 226.326261z" fill="#FFFFFF" p-id="4004"></path></svg>
... ...
... ... @@ -9,6 +9,14 @@ export enum Platform {
9 9 PC = 'pc',
10 10 }
11 11
  12 +export enum ConfigurationPermission {
  13 + CREATE = 'api:yt:configuration:center:post',
  14 + UPDATE = 'api:yt:configuration:center:update',
  15 + DELETE = 'api:yt:configuration:center:delete',
  16 + DESIGN = 'api:yt:configuration:center:get_configuration_info:design',
  17 + PREVIEW = 'api:yt:configuration:center:get_configuration_info:preview',
  18 +}
  19 +
12 20 export const PC_DEFAULT_CONTENT =
13 21 '<mxfile><diagram>dZHBDsIgDIafhvuEzOh5Tr142sEzGXWQsHVhmKFP7xbAidMT5fv/UtoSVrTuZHgvLyhAE5oJR9iBUMrybT4dM3l4stnTzJPGKBHYAir1hACj7a4EDInRImqr+hTW2HVQ24RxY3BMbTfUadWeN7ACVc31ml6VsPK7jVk4g2pkLJ3tgtLy6A5gkFzg+IFYSVhhEK2PWleAnscXB+Pzjn/U988MdPZHwhQsb0+XZEesfAE=</diagram></mxfile>';
14 22
... ...
... ... @@ -7,7 +7,7 @@
7 7 EditOutlined,
8 8 EllipsisOutlined,
9 9 } from '@ant-design/icons-vue';
10   - import { onMounted, reactive, ref, unref } from 'vue';
  10 + import { computed, onMounted, reactive, ref, unref } from 'vue';
11 11 import { OrganizationIdTree, useResetOrganizationTree } from '../../common/organizationIdTree';
12 12 import {
13 13 deleteConfigurationCenter,
... ... @@ -17,7 +17,7 @@
17 17 import { PageWrapper } from '/@/components/Page';
18 18 import { Dropdown } from '/@/components/Dropdown';
19 19 import { BasicForm, useForm } from '/@/components/Form';
20   - import { searchFormSchema } from './center.data';
  20 + import { ConfigurationPermission, searchFormSchema } from './center.data';
21 21 import { useMessage } from '/@/hooks/web/useMessage';
22 22 import { Authority } from '/@/components/Authority';
23 23 import { isDevMode } from '/@/utils/env';
... ... @@ -98,6 +98,16 @@
98 98
99 99 const [registerDrawer, { openDrawer }] = useDrawer();
100 100
  101 + const { hasPermission } = usePermission();
  102 +
  103 + const getPreviewFlag = computed(() => {
  104 + return hasPermission(ConfigurationPermission.PREVIEW);
  105 + });
  106 +
  107 + const getDesignFlag = computed(() => {
  108 + return hasPermission(ConfigurationPermission.DESIGN);
  109 + });
  110 +
101 111 const handleCreateOrUpdate = (record?: ConfigurationCenterItemsModal) => {
102 112 if (record) {
103 113 openDrawer(true, {
... ... @@ -114,15 +124,15 @@
114 124 const { configurationPrefix } = useGlobSetting();
115 125 const isDev = isDevMode();
116 126
117   - const { hasPermission } = usePermission();
118 127 const handlePreview = (record: ConfigurationCenterItemsModal) => {
119   - if (!hasPermission('api:yt:configuration:center:get_configuration_info:get')) return;
  128 + if (!unref(getPreviewFlag)) return;
120 129 window.open(
121 130 `${configurationPrefix}/${isDev ? '?dev=1&' : '?'}configurationId=${record!.id}&lightbox=1`
122 131 );
123 132 };
124 133
125 134 const handleDesign = (record: ConfigurationCenterItemsModal) => {
  135 + if (!unref(getDesignFlag)) return;
126 136 window.open(`${configurationPrefix}/${isDev ? '?dev=1&' : '?'}configurationId=${record!.id}`);
127 137 };
128 138
... ... @@ -175,7 +185,9 @@
175 185 >
176 186 <template #header>
177 187 <div class="flex gap-3 justify-end">
178   - <Button type="primary" @click="handleCreateOrUpdate()">新增组态</Button>
  188 + <Authority :value="ConfigurationPermission.CREATE">
  189 + <Button type="primary" @click="handleCreateOrUpdate()">新增组态</Button>
  190 + </Authority>
179 191 <Popover :trigger="['hover']">
180 192 <template #content>
181 193 <div class="w-50">
... ... @@ -214,29 +226,35 @@
214 226 </div>
215 227 </template>
216 228 <template class="ant-card-actions" #actions>
217   - <Authority value="api:yt:configuration:center:get_configuration_info:get">
218   - <Tooltip title="预览">
219   - <EyeOutlined key="setting" @click="handlePreview(item)" />
220   - </Tooltip>
221   - </Authority>
222   - <Authority value="api:yt:configuration:center:get_configuration_info:get">
223   - <Tooltip title="设计">
224   - <EditOutlined key="edit" @click="handleDesign(item)" />
225   - </Tooltip>
226   - </Authority>
  229 + <Tooltip title="预览">
  230 + <EyeOutlined
  231 + :class="getPreviewFlag ? '' : '!cursor-not-allowed !text-gray-200'"
  232 + key="setting"
  233 + @click="handlePreview(item)"
  234 + />
  235 + </Tooltip>
  236 + <Tooltip title="设计">
  237 + <EditOutlined
  238 + :class="getDesignFlag ? '' : '!cursor-not-allowed !text-gray-200'"
  239 + key="edit"
  240 + @click="handleDesign(item)"
  241 + />
  242 + </Tooltip>
227 243 <Dropdown
228 244 :dropMenuList="[
229 245 {
230 246 text: '编辑',
231   - auth: 'api:yt:configuration:center:update',
  247 + auth: ConfigurationPermission.UPDATE,
232 248 icon: 'clarity:note-edit-line',
  249 + event: '',
233 250 onClick: handleCreateOrUpdate.bind(null, item),
234 251 },
235 252 {
236 253 text: '删除',
237   - auth: 'api:yt:configuration:center:delete',
  254 + auth: ConfigurationPermission.DELETE,
238 255 icon: 'ant-design:delete-outlined',
239 256 color: 'error',
  257 + event: '',
240 258 onClick: handleDelete.bind(null, item),
241 259 },
242 260 ]"
... ...
... ... @@ -13,16 +13,23 @@
13 13 } from '/@/api/device/deviceConfigApi';
14 14 import { ProfileRecord } from '/@/api/device/model/deviceConfigModel';
15 15 import { Dropdown } from '/@/components/Dropdown';
16   - import { defaultObj, searchFormSchema, DeviceTypeName } from './device.profile.data';
  16 + import {
  17 + defaultObj,
  18 + searchFormSchema,
  19 + DeviceTypeName,
  20 + ProductPermission,
  21 + } from './device.profile.data';
17 22 import { useMessage } from '/@/hooks/web/useMessage';
18 23 import { useSyncConfirm } from '/@/hooks/component/useSyncConfirm';
19 24 import DeviceProfileModal from './DeviceProfileModal.vue';
20 25 import DeviceProfileDrawer from './DeviceProfileDrawer.vue';
21 26 import { useModal } from '/@/components/Modal';
22 27 import { useDrawer } from '/@/components/Drawer';
  28 + import productDefault from '/@/assets/icons/product-default.svg';
  29 + import { usePermission } from '/@/hooks/web/usePermission';
23 30
24 31 defineProps<{
25   - mode: Mode;
  32 + mode: EnumTableCardMode;
26 33 }>();
27 34
28 35 const emit = defineEmits(['changeMode']);
... ... @@ -31,8 +38,7 @@
31 38 SET_DEFAULT = 'setDefault',
32 39 DELETE = 'delete',
33 40 }
34   - const IMAGE_FALLBACK =
35   - 'data:image/png;base64,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';
  41 + const IMAGE_FALLBACK = productDefault;
36 42
37 43 const { createMessage } = useMessage();
38 44 const { createSyncConfirm } = useSyncConfirm();
... ... @@ -94,6 +100,40 @@
94 100 }
95 101 };
96 102
  103 + const { hasPermission } = usePermission();
  104 +
  105 + const getHasDeleteFlag = computed(() => {
  106 + return hasPermission(ProductPermission.DELETE);
  107 + });
  108 +
  109 + const getHasDetailFlag = computed(() => {
  110 + return hasPermission(ProductPermission.DETAIL);
  111 + });
  112 +
  113 + const getHasUpdateFlag = computed(() => {
  114 + return hasPermission(ProductPermission.UPDATE);
  115 + });
  116 +
  117 + const getDropDownList = (record: ProfileRecord) => {
  118 + const list = [
  119 + {
  120 + text: '默认',
  121 + event: DropMenuEvent.SET_DEFAULT,
  122 + icon: 'ant-design:unordered-list-outlined',
  123 + onClick: handleSetDefault.bind(null, record),
  124 + },
  125 + ];
  126 + if (unref(getHasDeleteFlag)) {
  127 + list.push({
  128 + text: '删除',
  129 + event: DropMenuEvent.DELETE,
  130 + icon: 'ant-design:delete-outlined',
  131 + onClick: handleDelete.bind(null, [record.id]),
  132 + });
  133 + }
  134 + return list;
  135 + };
  136 +
97 137 const handleModeChange = (mode: EnumTableCardMode) => {
98 138 emit('changeMode', mode);
99 139 };
... ... @@ -118,10 +158,12 @@
118 158 };
119 159
120 160 const handleShowDetail = (record: ProfileRecord) => {
  161 + if (!unref(getHasDetailFlag)) return;
121 162 openDrawer(true, { record });
122 163 };
123 164
124 165 const handleUpdate = (record: ProfileRecord) => {
  166 + if (!unref(getHasUpdateFlag)) return;
125 167 openModal(true, {
126 168 record,
127 169 isUpdate: true,
... ... @@ -173,20 +215,27 @@
173 215 >
174 216 <template #header>
175 217 <div class="flex gap-3 justify-end">
176   - <Button type="primary" @click="handleCreate">新增产品</Button>
  218 + <Authority :value="ProductPermission.CREATE">
  219 + <Button type="primary" @click="handleCreate">新增产品</Button>
  220 + </Authority>
  221 +
177 222 <Button type="primary" @click="handleSelectAll">
178 223 {{ getSelectAllFlag ? '反选' : '全选' }}
179 224 </Button>
180   - <Button
181   - type="primary"
182   - danger
183   - :disabled="!getCheckedRecord.length"
184   - @click="handleDelete(getCheckedRecord)"
185   - >
186   - 批量删除
187   - </Button>
  225 + <Authority :value="ProductPermission.DELETE">
  226 + <Button
  227 + type="primary"
  228 + danger
  229 + :disabled="!getCheckedRecord.length"
  230 + @click="handleDelete(getCheckedRecord)"
  231 + >
  232 + 批量删除
  233 + </Button>
  234 + </Authority>
  235 +
188 236 <ModeSwitchButton :value="$props.mode" @change="handleModeChange" />
189 237 <CardLayoutButton v-model:value="colNumber" @change="getDataSource" />
  238 +
190 239 <Tooltip title="刷新">
191 240 <Button type="primary" @click="getDataSource">
192 241 <ReloadOutlined :spin="loading" />
... ... @@ -213,33 +262,21 @@
213 262 </div>
214 263 </template>
215 264 <template class="ant-card-actions" #actions>
216   - <Authority>
217   - <Tooltip title="详情">
218   - <EyeOutlined key="setting" @click.stop="handleShowDetail(item)" />
219   - </Tooltip>
220   - </Authority>
221   - <Authority>
222   - <Tooltip title="编辑">
223   - <FormOutlined key="edit" @click.stop="handleUpdate(item)" />
224   - </Tooltip>
225   - </Authority>
226   - <Dropdown
227   - :trigger="['hover']"
228   - :drop-menu-list="[
229   - {
230   - text: '默认',
231   - event: DropMenuEvent.SET_DEFAULT,
232   - icon: 'ant-design:unordered-list-outlined',
233   - onClick: handleSetDefault.bind(null, item),
234   - },
235   - {
236   - text: '删除',
237   - event: DropMenuEvent.DELETE,
238   - icon: 'ant-design:delete-outlined',
239   - onClick: handleDelete.bind(null, [item.id]),
240   - },
241   - ]"
242   - >
  265 + <Tooltip title="详情">
  266 + <EyeOutlined
  267 + :class="getHasDetailFlag ? '' : '!cursor-not-allowed !text-gray-200'"
  268 + key="setting"
  269 + @click.stop="handleShowDetail(item)"
  270 + />
  271 + </Tooltip>
  272 + <Tooltip title="编辑">
  273 + <FormOutlined
  274 + :class="getHasUpdateFlag ? '' : '!cursor-not-allowed !text-gray-200'"
  275 + key="edit"
  276 + @click.stop="handleUpdate(item)"
  277 + />
  278 + </Tooltip>
  279 + <Dropdown :trigger="['hover']" :drop-menu-list="getDropDownList(item)">
243 280 <MoreOutlined @click.stop class="transform rotate-90" />
244 281 </Dropdown>
245 282 </template>
... ...
... ... @@ -7,15 +7,15 @@
7 7 :clickToRowSelect="false"
8 8 >
9 9 <template #toolbar>
10   - <Authority value="api:yt:deviceProfile:post">
  10 + <Authority :value="ProductPermission.CREATE">
11 11 <a-button type="primary" @click="handleCreate"> 新增产品 </a-button>
12 12 </Authority>
13   - <Authority value="api:yt:deviceProfile:import">
  13 + <Authority :value="ProductPermission.IMPORT">
14 14 <ImpExcel @success="loadDataSuccess" dateFormat="YYYY-MM-DD">
15 15 <a-button @click="handleImport"> 导入产品 </a-button>
16 16 </ImpExcel>
17 17 </Authority>
18   - <Authority value="api:yt:deviceProfile:delete">
  18 + <Authority :value="ProductPermission.DELETE">
19 19 <Popconfirm
20 20 title="您确定要批量删除数据"
21 21 ok-text="确定"
... ... @@ -44,13 +44,13 @@
44 44 :actions="[
45 45 {
46 46 label: '详情',
47   - auth: 'api:yt:deviceProfile:get',
  47 + auth: ProductPermission.DETAIL,
48 48 icon: 'ant-design:eye-outlined',
49 49 onClick: handleDetailView.bind(null, record),
50 50 },
51 51 {
52 52 label: '编辑',
53   - auth: 'api:yt:deviceProfile:update',
  53 + auth: ProductPermission.UPDATE,
54 54 icon: 'clarity:note-edit-line',
55 55 onClick: handleEdit.bind(null, record),
56 56 ifShow: () => {
... ... @@ -69,13 +69,13 @@
69 69 },
70 70 {
71 71 label: '导出',
72   - auth: 'api:yt:deviceProfile:export',
  72 + auth: ProductPermission.EXPORT,
73 73 icon: 'ant-design:login-outlined',
74 74 onClick: handleExport.bind(null, record),
75 75 },
76 76 {
77 77 label: '删除',
78   - auth: 'api:yt:deviceProfile:delete',
  78 + auth: ProductPermission.DELETE,
79 79 icon: 'ant-design:delete-outlined',
80 80 color: 'error',
81 81 popConfirm: {
... ... @@ -102,7 +102,7 @@
102 102 <script lang="ts" setup>
103 103 import { ref, nextTick, onUnmounted } from 'vue';
104 104 import { BasicTable, TableImg, useTable, TableAction, BasicColumn } from '/@/components/Table';
105   - import { columns, searchFormSchema, defaultObj } from './device.profile.data';
  105 + import { columns, searchFormSchema, defaultObj, ProductPermission } from './device.profile.data';
106 106 import { useMessage } from '/@/hooks/web/useMessage';
107 107 import {
108 108 deviceConfigGetQuery,
... ...
... ... @@ -19,6 +19,15 @@ export enum DeviceTypeName {
19 19 GATEWAY = '网关设备',
20 20 SENSOR = '网关子设备',
21 21 }
  22 +export enum ProductPermission {
  23 + DETAIL = 'api:yt:deviceProfile:get',
  24 + CREATE = 'api:yt:deviceProfile:post',
  25 + UPDATE = 'api:yt:deviceProfile:update',
  26 + DELETE = 'api:yt:deviceProfile:delete',
  27 + SET_DEFAULT = '',
  28 + IMPORT = 'api:yt:deviceProfile:import',
  29 + EXPORT = 'api:yt:deviceProfile:export',
  30 +}
22 31
23 32 export enum ModelOfMatterPermission {
24 33 CREATE = 'api:yt:things_model:post',
... ...