Commit 1eab6b9709cb624c949f945224699107f3fb54a0

Authored by xp.Huang
2 parents 68faed32 2d59d1d6

Merge branch 'f-dev' into 'main'

fix:DEFECT-432 修复超级管理员分配菜单权限和按钮权限问题和修改场景联动

See merge request huang/yun-teng-iot-front!230
... ... @@ -17,9 +17,10 @@ enum ScreenManagerApi {
17 17 SCREEN_UPDATE_URL = '/sceneLinkage/update',
18 18 SCREEN_ORGANIZATION_URL = '/organization/me/list',
19 19 SCREEN_CHANGE_STATUS = '/convert/update/scene',
20   - SCREEN_GET_BY_DEPTID = '/sceneLinkage/device/',
21   - GET_ATTRBUTELIST = '/deviceProfile/devices/keys/timeseries',
  20 + SCREEN_GET_BY_DEPTID = '/sceneLinkage/device',
  21 + GET_ATTRBUTELIST = '/device/keys',
22 22 ALARM_PROFILE = '/alarm/profile/',
  23 + MASTER_GET_DEVICE = '/device/list/master',
23 24 }
24 25
25 26 /**
... ... @@ -55,6 +56,16 @@ export const screenLinkPageAddApi = (params: ScreenAddModel, isUpdate: boolean)
55 56 };
56 57
57 58 /**
  59 + * 获取主设备列表(exclude子设备)
  60 + * @param params organizationId
  61 + */
  62 +export const byOganizationIdGetMasterDevice = (params) => {
  63 + return defHttp.get({
  64 + url: ScreenManagerApi.MASTER_GET_DEVICE + '/' + params,
  65 + });
  66 +};
  67 +
  68 +/**
58 69 * 删除场景联动
59 70 * @param params pageSize page name
60 71 */
... ... @@ -99,13 +110,8 @@ export const getOrganizationAlarmConfig = (params: { organizationId }) => {
99 110 /**
100 111 * 获取设备属性列表
101 112 */
102   -export const getAttribute = () => {
103   - return defHttp.get(
104   - {
105   - url: ScreenManagerApi.GET_ATTRBUTELIST,
106   - },
107   - {
108   - joinPrefix: false,
109   - }
110   - );
  113 +export const getAttribute = (orgId, deviceIds) => {
  114 + return defHttp.get({
  115 + url: ScreenManagerApi.GET_ATTRBUTELIST + '/' + orgId + '?' + deviceIds,
  116 + });
111 117 };
... ...
... ... @@ -11,12 +11,11 @@ import projectSetting from '/@/settings/projectSetting';
11 11 import { PermissionModeEnum } from '/@/enums/appEnum';
12 12 import { asyncRoutes } from '/@/router/routes';
13 13 import { ERROR_LOG_ROUTE, PAGE_NOT_FOUND_ROUTE } from '/@/router/routes/basic';
14   -import { filter } from '/@/utils/helper/treeHelper';
15   -import { getMenuList } from '/@/api/sys/menu';
  14 +import { filter, forEach } from '/@/utils/helper/treeHelper';
  15 +import { getMenuList, getMenusIdsByRoleId } from '/@/api/sys/menu';
16 16 import { getPermCode } from '/@/api/sys/user';
17 17 import { useMessage } from '/@/hooks/web/useMessage';
18 18 import { PageEnum } from '/@/enums/pageEnum';
19   -import { router as navRouter } from '/@/router';
20 19 import { MENU_LIST, USER_INFO_KEY } from '/@/enums/cacheEnum';
21 20 import { getAuthCache, setAuthCache } from '/@/utils/auth';
22 21 import { createStorage } from '/@/utils/cache/index';
... ... @@ -90,8 +89,48 @@ export const usePermissionStore = defineStore({
90 89 this.lastBuildMenuTime = 0;
91 90 },
92 91 async changePermissionCode() {
  92 + const filterMenu = (allMenuList, menuIdsList) => {
  93 + return allMenuList
  94 + .filter((item) => {
  95 + return menuIdsList.indexOf(item.id) > -1;
  96 + })
  97 + .map((subItem) => {
  98 + subItem = Object.assign({}, subItem);
  99 + if (subItem.children) {
  100 + subItem.children = filterMenu(subItem.children, menuIdsList);
  101 + }
  102 + return subItem;
  103 + });
  104 + };
  105 + const userInfo: any = getAuthCache(USER_INFO_KEY);
  106 + const isSysAdmin = 'SYS_ADMIN';
  107 + const routeList = (await getMenuList(2)) as AppRouteRecordRaw[];
  108 + let getSysPermission = [];
  109 + /**
  110 + * 否则不是超级管理员-获取对应角色的权限列表
  111 + */
93 112 const codeList = await getPermCode();
94 113 this.setPermCodeList(codeList);
  114 + /**
  115 + * 如果是超级管理员则获取对应权限列表
  116 + */
  117 + if (userInfo.roles.includes(isSysAdmin) || userInfo.realName == '超级管理员') {
  118 + const getMenuIds = await getMenusIdsByRoleId(userInfo.plainRoles[0].roleId);
  119 + //根据对应的使用者的菜单数组和所有菜单数组对象进行过滤,返回最终需要的菜单
  120 + const newMenu = filterMenu(routeList, getMenuIds);
  121 + /**
  122 + * 递归获取对应所有菜单的权限列表
  123 + */
  124 + function lookForAllId(data = [], arr = []) {
  125 + for (const item of data) {
  126 + arr.push(item.permission);
  127 + if (item.children && item.children.length) lookForAllId(item.children, arr);
  128 + }
  129 + return arr;
  130 + }
  131 + getSysPermission = lookForAllId(newMenu);
  132 + this.setPermCodeList(getSysPermission);
  133 + }
95 134 },
96 135 async buildRoutesAction(): Promise<AppRouteRecordRaw[]> {
97 136 const { t } = useI18n();
... ... @@ -183,70 +222,87 @@ export const usePermissionStore = defineStore({
183 222 // !Simulate to obtain permission codes from the background,
184 223 // this function may only need to be executed once, and the actual project can be put at the right time by itself
185 224 let routeList: AppRouteRecordRaw[] = [];
186   - try {
187   - const userInfo = getAuthCache(USER_INFO_KEY);
188   - if (userInfo?.needSetPwd == true) {
189   - routeList = [
190   - {
191   - name: 'routes.common.system.system',
192   - parentId: '',
193   - children: [
194   - {
195   - id: 'a8ffa8c5-637e-476b-a9e6-b60cebe95718',
196   - createTime: '2021-09-10 20:50:55',
197   - updateTime: '2021-11-16 18:58:24',
198   - name: 'routes.common.system.modifyPassword',
199   - parentId: 'a8ffa8c5-637e-471b-a9e6-b60cebe95713',
200   - children: [],
201   - path: '/system/changePassword',
202   - type: 'SYSADMIN',
203   - permission: 'system:password:view',
204   - sort: 6,
205   - component: '/system/changePassword/index',
206   - meta: {
207   - icon: 'bx:bx-home',
208   - title: 'routes.common.system.modifyPassword',
209   - menuType: '1',
210   - ignoreKeepAlive: true,
211   - hideMenu: false,
212   - status: '0',
213   - },
214   - redirect: '',
  225 + const userInfo: any = getAuthCache(USER_INFO_KEY);
  226 + const filterMenu = (allMenuList, menuIdsList) => {
  227 + return allMenuList
  228 + .filter((item) => {
  229 + return menuIdsList.indexOf(item.id) > -1;
  230 + })
  231 + .map((subItem) => {
  232 + subItem = Object.assign({}, subItem);
  233 + if (subItem.children) {
  234 + subItem.children = filterMenu(subItem.children, menuIdsList);
  235 + }
  236 + return subItem;
  237 + });
  238 + };
  239 + if (userInfo?.needSetPwd == true) {
  240 + routeList = [
  241 + {
  242 + name: 'routes.common.system.system',
  243 + parentId: '',
  244 + children: [
  245 + {
  246 + id: 'a8ffa8c5-637e-476b-a9e6-b60cebe95718',
  247 + createTime: '2021-09-10 20:50:55',
  248 + updateTime: '2021-11-16 18:58:24',
  249 + name: 'routes.common.system.modifyPassword',
  250 + parentId: 'a8ffa8c5-637e-471b-a9e6-b60cebe95713',
  251 + children: [],
  252 + path: '/system/changePassword',
  253 + type: 'SYSADMIN',
  254 + permission: 'system:password:view',
  255 + sort: 6,
  256 + component: '/system/changePassword/index',
  257 + meta: {
  258 + icon: 'bx:bx-home',
  259 + title: 'routes.common.system.modifyPassword',
  260 + menuType: '1',
  261 + ignoreKeepAlive: true,
  262 + hideMenu: false,
  263 + status: '0',
215 264 },
216   - ],
217   - path: '/system',
218   - type: 'SYSADMIN',
219   - permission: '',
220   - sort: 6,
221   - component: 'LAYOUT',
222   - meta: {
223   - icon: 'bx:bx-home',
224   - title: 'routes.common.system.system',
225   - status: '0',
226   - menuType: '0',
  265 + redirect: '',
227 266 },
228   - redirect: '/system/systemManagement',
  267 + ],
  268 + path: '/system',
  269 + type: 'SYSADMIN',
  270 + permission: '',
  271 + sort: 6,
  272 + component: 'LAYOUT',
  273 + meta: {
  274 + icon: 'bx:bx-home',
  275 + title: 'routes.common.system.system',
  276 + status: '0',
  277 + menuType: '0',
229 278 },
230   - ] as AppRouteRecordRaw[];
231   - } else {
232   - this.changePermissionCode();
233   - routeList = (await getMenuList(1)) as AppRouteRecordRaw[];
234   - createStorage('MENU_LIST', JSON.stringify(routeList));
235   - setAuthCache('MENU_LIST', routeList);
  279 + redirect: '/system/systemManagement',
  280 + },
  281 + ] as AppRouteRecordRaw[];
  282 + } else {
  283 + this.changePermissionCode();
  284 + routeList = (await getMenuList(1)) as AppRouteRecordRaw[];
  285 + const isSysAdmin = 'SYS_ADMIN';
  286 + /**
  287 + * 解决超级管理员分配菜单权限问题
  288 + */
  289 + if (userInfo.roles.includes(isSysAdmin) || userInfo.realName == '超级管理员') {
  290 + const getMenuIds = await getMenusIdsByRoleId(userInfo.plainRoles[0].roleId);
  291 + //根据对应的使用者的菜单数组和所有菜单数组对象进行过滤,返回最终需要的菜单
  292 + const newMenu = filterMenu(routeList, getMenuIds);
  293 + routeList = newMenu;
236 294 }
237   - } catch (error) {
238   - console.error(error);
239   - } // Dynamically introduce components
  295 + createStorage('MENU_LIST', JSON.stringify(routeList));
  296 + setAuthCache('MENU_LIST', routeList);
  297 + }
  298 + // Dynamically introduce components
240 299 routeList = transformObjToRoute(routeList);
241   -
242 300 // Background routing to menu structure
243 301 const backMenuList = transformRouteToMenu(routeList);
244 302 this.setBackMenuList(backMenuList);
245   -
246 303 // remove meta.ignoreRoute item
247 304 routeList = filter(routeList, routeRemoveIgnoreFilter);
248 305 routeList = routeList.filter(routeRemoveIgnoreFilter);
249   -
250 306 routeList = flatMultiLevelRoutes(routeList);
251 307 routes = [PAGE_NOT_FOUND_ROUTE, ...routeList];
252 308 break;
... ...
... ... @@ -21,6 +21,7 @@
21 21 class="mt-4"
22 22 title="触发器"
23 23 :index="index"
  24 + :provideOrgid="provideOrgid"
24 25 :ref="skipUnwrap.triggerItemRefs"
25 26 @delete="deleteTriggerOrCondition"
26 27 />
... ... @@ -42,6 +43,7 @@
42 43 class="mt-4"
43 44 title="执行条件"
44 45 :index="index"
  46 + :provideOrgid="provideOrgid"
45 47 :ref="skipUnwrap.conditionItemRefs"
46 48 @delete="deleteTriggerOrCondition"
47 49 />
... ... @@ -94,8 +96,10 @@
94 96 import { useMessage } from '/@/hooks/web/useMessage';
95 97 import {
96 98 screenLinkPageAddApi,
97   - screenLinkPageByDeptIdGetDevice,
  99 + // screenLinkPageByDeptIdGetDevice,
98 100 getOrganizationAlarmConfig,
  101 + byOganizationIdGetMasterDevice,
  102 + getAttribute,
99 103 } from '/@/api/ruleengine/ruleengineApi';
100 104 import TriggerOrCondition from './cpns/Trigger-Condition.vue';
101 105 import Action from './cpns/Action.vue';
... ... @@ -104,6 +108,7 @@
104 108
105 109 const emit = defineEmits(['register', 'success']);
106 110
  111 + const provideOrgid = ref('');
107 112 const { createMessage } = useMessage();
108 113 const triggerData = ref([]);
109 114 const conditionData = ref([]);
... ... @@ -120,6 +125,7 @@
120 125 let getConditionFormValue = ref([]);
121 126 let getActionFormValue = ref([]);
122 127 const editEntryIdData = ref([]);
  128 + let editAttrIdData = [];
123 129 const editAlarmConfigData = ref([]);
124 130 const isUpdate = ref(false);
125 131 const id = ref(undefined);
... ... @@ -151,21 +157,25 @@
151 157 await setFieldsValue(data.record);
152 158 id.value = recordId;
153 159 tenantId.value = recordTenantId;
  160 + provideOrgid.value = organizationId;
154 161 // 获取当前组织下的设备列表
155   - const options = await screenLinkPageByDeptIdGetDevice({
156   - organizationId,
157   - });
  162 + const options = await byOganizationIdGetMasterDevice(organizationId);
158 163 // 获取当前组织下的告警配置
159 164 const alarmConfig = await getOrganizationAlarmConfig({ organizationId });
  165 + // 获取当前组织下的属性列表
  166 + const attrList = await getAttribute(
  167 + organizationId,
  168 + triggers.map((m) => m.entityId).join(',')
  169 + );
160 170
161 171 // 生成回显时对应得组件数量
162 172 triggerData.value = [...new Array(triggers.length).keys()];
163 173 conditionData.value = [...new Array(doConditions.length).keys()];
164 174 actionData.value = [...new Array(doActions.length).keys()];
165 175 // 回显设备列表
166   - editEntryIdData.value = options.items.map((item) => {
  176 + editEntryIdData.value = options.map((item) => {
167 177 return {
168   - value: item.tbDeviceId,
  178 + value: item.id,
169 179 label: item.name,
170 180 };
171 181 });
... ... @@ -176,11 +186,15 @@
176 186 };
177 187 });
178 188 deviceList.value = editEntryIdData.value;
  189 + //回显属性列表
  190 + editAttrIdData = attrList;
179 191 nextTick(() => {
180 192 setEditFields(skipUnwrap.triggerItemRefs, editEntryIdData);
181 193 setEditFields(skipUnwrap.conditionItemRefs, editEntryIdData);
182 194 setEditFields(skipUnwrap.actionItemRefs, editEntryIdData);
183 195 setEditAlarmConfig(skipUnwrap.actionItemRefs, editAlarmConfigData);
  196 + setEditAttr(skipUnwrap.triggerItemRefs, editAttrIdData);
  197 + setEditAttr(skipUnwrap.conditionItemRefs, editAttrIdData);
184 198 });
185 199
186 200 const map = {
... ... @@ -198,12 +212,15 @@
198 212 unref(skipUnwrap.triggerItemRefs)[index].isUpdate = true;
199 213 unref(skipUnwrap.triggerItemRefs)[index].alarmScheduleRef.scheduleData =
200 214 trigger.triggerCondition.schedule;
  215 + const getAttrKeyOption = trigger?.triggerCondition?.condition?.condition.map(
  216 + (m) => m.key.key
  217 + );
201 218 unref(skipUnwrap.triggerItemRefs)[index].setFieldsFormValueFun({
202 219 triggered: trigger?.triggerCondition?.condition?.spec?.type,
203 220 device: trigger?.entityType,
204 221 triggerType: trigger?.triggerType,
205 222 type1: trigger?.triggerCondition?.condition?.condition[0]?.key?.type,
206   - type2: trigger?.triggerCondition?.condition?.condition[0]?.key?.key,
  223 + type2: getAttrKeyOption,
207 224 operationType: trigger?.triggerCondition?.condition?.condition[0]?.valueType,
208 225 detail: trigger?.triggerCondition?.alarmDetails,
209 226 entityId: trigger?.entityId,
... ... @@ -270,12 +287,15 @@
270 287 unref(skipUnwrap.conditionItemRefs)[index].isUpdate = true;
271 288 unref(skipUnwrap.conditionItemRefs)[index].alarmScheduleRef.scheduleData =
272 289 condition.triggerCondition.schedule;
  290 + const getAttrKeyOption = condition?.triggerCondition?.condition?.condition.map(
  291 + (m) => m.key.key
  292 + );
273 293 unref(skipUnwrap.conditionItemRefs)[index].setFieldsFormValueFun({
274 294 triggered: condition?.triggerCondition?.condition?.spec?.type,
275 295 device: condition?.entityType,
276 296 triggerType: condition?.triggerType,
277 297 type1: condition?.triggerCondition?.condition?.condition[0]?.key?.type,
278   - type2: condition?.triggerCondition?.condition?.condition[0]?.key?.key,
  298 + type2: getAttrKeyOption,
279 299 operationType: condition?.triggerCondition?.condition?.condition[0]?.valueType,
280 300 detail: condition?.triggerCondition?.alarmDetails,
281 301 entityId: condition?.entityId,
... ... @@ -471,17 +491,26 @@
471 491 item.updateEditFieldAlarmConfig(alarmConfigList);
472 492 });
473 493 };
  494 + //设置设备属性的options
  495 + const setEditAttr = (linkAge, attrList) => {
  496 + unref(linkAge).map((item) => {
  497 + item.updateFieldAttr(attrList);
  498 + });
  499 + };
  500 +
474 501 // 监听组织变化更新设备列表
475 502 const deviceList = ref([]);
476 503 const alarmConfigList = ref([]);
  504 + let watchAttrList = [];
477 505 watch(organizationId, async (newValue: string) => {
478 506 if (!newValue) return;
479   - const { items } = await screenLinkPageByDeptIdGetDevice({ organizationId: newValue });
480   - deviceList.value = items.map((item) => ({ label: item.name, value: item.tbDeviceId }));
  507 + provideOrgid.value = newValue;
  508 + const items = await byOganizationIdGetMasterDevice(newValue);
  509 + deviceList.value = items.map((item) => ({ label: item.name, value: item.id }));
  510 + watchAttrList = await getAttribute(newValue, null);
481 511 setFields(skipUnwrap.triggerItemRefs, true);
482 512 setFields(skipUnwrap.conditionItemRefs, true);
483 513 setFields(skipUnwrap.actionItemRefs, true);
484   -
485 514 const data = await getOrganizationAlarmConfig({ organizationId: newValue });
486 515 alarmConfigList.value = data.map((item) => ({ label: item.name, value: item.id }));
487 516 setAlarmConfig(skipUnwrap.actionItemRefs, true);
... ... @@ -492,6 +521,7 @@
492 521 unref(linkAge).map((item) => {
493 522 isOrganizationChange && item.resetFieldsValueFunc();
494 523 item.updateFieldDeviceId(deviceList);
  524 + item.updateFieldAttr(watchAttrList);
495 525 });
496 526 }
497 527 function setAlarmConfig(linkAge, isOrganizationChange = false) {
... ... @@ -602,3 +632,10 @@
602 632 });
603 633 };
604 634 </script>
  635 +
  636 +<style lang="less" scoped>
  637 + ///统一下拉选择框宽度,否则超出默认宽度会造成页面样式错乱
  638 + :deep(.ant-select-selector) {
  639 + max-width: 14.2rem;
  640 + }
  641 +</style>
... ...
... ... @@ -257,7 +257,7 @@ export const trigger_condition_schema: FormSchema[] = [
257 257 {
258 258 field: 'type2',
259 259 label: '',
260   - component: 'AutoComplete',
  260 + component: 'Select',
261 261 componentProps: {
262 262 placeholder: '请选择属性',
263 263 },
... ...
... ... @@ -69,7 +69,7 @@
69 69 import AlarmSchedule from './AlarmSchedule.vue';
70 70 import { useModal } from '/@/components/Modal';
71 71
72   - defineProps({
  72 + const props = defineProps({
73 73 title: {
74 74 type: String,
75 75 required: true,
... ... @@ -78,6 +78,10 @@
78 78 type: Number,
79 79 required: true,
80 80 },
  81 + provideOrgid: {
  82 + type: String,
  83 + default: '',
  84 + },
81 85 });
82 86 const emit = defineEmits(['delete']);
83 87 const isUpdate = ref(false);
... ... @@ -101,19 +105,35 @@
101 105 options: deviceList,
102 106 onChange(e) {
103 107 if (e) {
104   - updateFieldAttributeFunc();
  108 + updateFieldAttributeFunc(e);
105 109 }
106 110 },
107 111 },
108 112 });
109 113 };
  114 + const updateFieldAttr = (attrList: any[]) => {
  115 + const attrMapList = attrList?.map((m) => {
  116 + return {
  117 + label: m,
  118 + value: m,
  119 + };
  120 + });
  121 + updateSchema({
  122 + field: 'type2',
  123 + componentProps: {
  124 + placeholder: '请选择属性',
  125 + options: attrMapList,
  126 + },
  127 + });
  128 + };
110 129 const resetFieldsValueFunc = () => resetFields();
111 130 // 回显数据函数
112 131 const setFieldsFormValueFun = (fieldsValue) => {
113 132 setFieldsValue(fieldsValue);
114 133 };
115   - const updateFieldAttributeFunc = async () => {
116   - const data = await getAttribute();
  134 + const updateFieldAttributeFunc = async (e) => {
  135 + const joinDeviceIds = e.join(',');
  136 + const data = await getAttribute(props.provideOrgid, joinDeviceIds);
117 137 const options = data.map((m) => {
118 138 return {
119 139 label: m,
... ... @@ -178,6 +198,7 @@
178 198 defineExpose({
179 199 getFieldsValueFunc,
180 200 updateFieldDeviceId,
  201 + updateFieldAttr,
181 202 resetFieldsValueFunc,
182 203 setFieldsFormValueFun,
183 204 childGetFieldsValue,
... ...