E4 RCP 用户权限--控制菜单(1)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zhanwentao2/article/details/7629950

项目需要做用户权限管理,管理的粒度只到菜单,这样就比较简单了。

数据库表设计:

用户------角色------权限

很通用的表设计。

因为菜单有父子的一个关系,所以在设计表的时候,也将父子关系设置其中。

表中的func_id代表的是菜单ID,parent代表的是上级ID.


接下来谈谈如何控制菜单,有两种情况:

第一种:配置文件中,已经配置好所有的菜单项,那么就只需要控制这些菜单项的Visible属性即可。

第二种:配置文件中,未配置菜单项,那么就根据用户权限中的数据,硬编码手动创建这些菜单项。


我的项目中,用到的是第一种方法。

好了,废话不多说,切入正题。

首先,要在登陆后,跳转到一个地方,让我来处理权限功能,(也可以写在登陆代码后面),创建一个model,供我使用。


在plugin.xml 中添加一个节点:org.eclipse.e4.workbench.model,再添加一个处理程序,这个程序就是权限控制的处理类。


选择你处理的类。


在处理类中,需要获得Main Menu,所以,需要添加一个参数,参数的ID就是Application.e4xmi中Main Menu中的ID。


这样配置好了的话,在程序启动时,就会触发这个处理器,在处理器中进行权限的控制。


@SuppressWarnings("all")
public class MenuFilterHandler {
	
	@Inject
	@Named("menu:omse4client.main.menu")
	private MMenu mMenu;  //获得Main Menu
	
	private Users users;  //登陆用户信息
	
	@Inject
	private UserClientDao clientDao;
	@Inject
	private FuncClientDao funcClientDao;
	
	private Map<String,Func> funcMaps,addFuncMaps;
	
	@Execute
	/**
	 * 获得用户权限,将所有权限保存在funcMaps中,循环迭代系统中已配置好的菜单,如果菜单ID在funcMaps中不存在,那么就将该菜单的visible属性设置为false,
	 * 如果遇到下级菜单,就将下级菜单继续迭代.
	 */
	private void filter(){
		
		funcMaps = new HashMap<String, Func>();
		addFuncMaps = new HashMap<String, Func>();
		//获得登陆用户的权限
		Object object = clientDao.queryCurrentUser();
		if(null == object){
			MessageDialog.openInformation(Display.getCurrent().getActiveShell(), "提示", "当前用户不存在或未分配角色权限,请与系统管理员联系");
			System.exit(0);
			return;
		}
		users = (Users) object;
		List<Role> roles = users.getRoles();
		//一个用户可能拥有多个角色
		for (Iterator<Role> iterator2 = roles.iterator(); iterator2.hasNext();) {
			Role role = (Role) iterator2.next();
			List<Func> funcs = role.getFuncs();
			//角色对应多个权限
			for (Iterator<Func> iterator3 = funcs.iterator(); iterator3.hasNext();) {
				Func func = (Func) iterator3.next();
				//如果用户角色权限有重复的地方,用HashMap保存的话,可以起到去重的一个效果
				funcMaps.put(func.getFuncId(), func);
			}
		}
		
		/**
		 * mMenu.getChildren()返回的是一个List<MMenuElement>
		 * MMenuElement无法获取到下一级,在DEBUG时,发现可以看到它的下一级数据,然而它的数据类型是:EObjectContainmentWithInverseEList
		 * 所以,进行了一下强制类型转换
		 */
		EObjectContainmentWithInverseEList<?> elements = (EObjectContainmentWithInverseEList<?>) mMenu.getChildren();
		for (Iterator<?> iterator = elements.iterator(); iterator.hasNext();) {
			Object object1 = (Object) iterator.next();
			MMenuElement element = (MMenuElement) object1;
			/**
			 * addFuncMaps 中保存的是配置文件中可视的所有的菜单项
			 * 初始化数据库中权限的数据
			 */
			if(element.isVisible()){
				Func func = getFunc(element.getElementId(),element.getLabel(),element.getElementId());
				addFuncMaps.put(element.getElementId(),func);
				iteratorMenu(object1);
			}
		}
		funcClientDao.insertFunc(addFuncMaps);
	}
	
	private Func getFunc(String funcId,String name,String parentId){
		Func func = new Func();
		func.setFuncId(funcId);
		func.setName(name);
		func.setParent(parentId);
		return func;
	}
	
	/**
	 * 迭代菜单项
	 * @param object
	 */
	private void iteratorMenu(Object object){
		if(null!=object){
			/**
			 * 菜单下可能会出现下级菜单,也有可能出现处理菜单项
			 * 所有这个地方做了一个判断,如何使下级菜单,那么就对下级菜单进行迭代
			 */
			if(object instanceof MenuImpl){
				MenuImpl element = (MenuImpl) object;
				if(element.isVisible()){
					Func func = getFunc(element.getElementId(),element.getLabel(),element.getParent().getElementId());
					addFuncMaps.put(element.getElementId(),func);
					//判断用户权限中是否包含此菜单项,将未包含的菜单项的visible属性设置为:false
					if(!funcMaps.containsKey(element.getElementId())){
						element.setVisible(false);
					}
					EObjectContainmentWithInverseEList<?> elements = (EObjectContainmentWithInverseEList<?>) element.getChildren();
					for (Iterator<?> iterator = elements.iterator(); iterator.hasNext();) {
						Object object2 = (Object) iterator.next();
						iteratorMenu(object2);
					}
				}
			}else if(object instanceof HandledMenuItemImpl){
				HandledMenuItemImpl element = (HandledMenuItemImpl) object;
				if(element.isVisible()){
					Func func = getFunc(element.getElementId(),element.getLabel(),element.getParent().getElementId());
					addFuncMaps.put(element.getElementId(),func);
					if(!funcMaps.containsKey(element.getElementId())){
						element.setVisible(false);
					}
				}
			}
		}
	}
}



上面提到,有两种情况,我这是第一种情况下的处理方式。

如果大家遇到第二种情况,且不知如何处理的话,可以留言。

猜你喜欢

转载自blog.csdn.net/zhanwentao2/article/details/7629950