BSTEK Development Framework2(BDF2) : 11.BDF2-PROFILE

       BDF2-PROFILE模块提供了一个允许管理员对系统当中页面组件的显示进行个性化定制的功能。对于这种组件的个性化定制,管理可以将其施加给某个用户、某个部门或某个公司等,一旦对目标群体(用户、部门或者公司)施加了个性化定制功能,那么隶属于这个用户、部门或者公司的人登录系统之后就可以看到这个页面被管理员修改后的效果,接下来们举个例子来说明这个功能的适用场景。

       假如我们需要开发一个系统,这个系统将以SAAS模式给不同的公司去使用,但对于某一些功能页面,不同的公司对页面显示效果要求可能也略有不同,比如某个业务系统维护页面,某些公司可能其中的一个表单中字段A、B、C的显示顺序为A、B、C,但有些公司可能因为某些原因希望将顺序改成B、C、A,对于这样一种需求,因为两家公司习惯不同,对页面的显示要求也不相同,但这么一点不同又不值得我们专门开发一个页面特地给这家公司使用,这个时候就可以利用BDF2-PROFILE模块轻松解决这个问题。当然,BDF2-PROFILE模块能个性化的功能不仅仅是表单元素或表格列的显示顺序,它几乎可以实现所有的支持属性及事件定义的组件个性化定制,比如针对不同的公司为某个Button设置不同的caption,或者针对不同公司为某个UpdataAction设置不同的保存前的确认消息或保存成功之后的提示消息等。

       要使用BDF2-PROFILE模块,首先需要将BDF2-PROFILE模块相关的jar放置到我们的项目当中,具体做法就是可以到nexus.bsdn.org上下载BDF2-PROFILE模块相关jar或到我们提供的在线项目向导当中,创建一个包含BDF2-PROFILE模块的项目,当然如果您采用的是Maven来管理我们的项目,那么只需要在我们项目的 pom.xml当中添加下面的依赖信息即可。

BDF2-PROFILE模块的依赖信息
<dependency>
  <groupId>com.bstek.bdf2</groupId>
  <artifactId>bdf2-profile</artifactId>
  <version>2.0.0</version>
</dependency>

       添加完BDF2-PROFILE模块所需要的jar之后,接下来还需要编写一个IProfileDataService接口实现类,并将其配置到Spring当中,否则启动时会抛出下面的异常:

异常消息
Caused by: java.lang.RuntimeException: The current spring application context without a [com.bstek.bdf2.profile.service.IProfileDataService] interface implementation
	at com.bstek.bdf2.profile.view.component.ComponentMaintain.afterPropertiesSet(ComponentMaintain.java:414)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1545)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1483)
	... 23 more

       我们来看看IProfileDataService接口实现类代码:

IProfileDataService接口源码
package com.bstek.bdf2.profile.service;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import com.bstek.bdf2.profile.model.AssignTarget;
import com.bstek.bdf2.profile.model.UrlDefinition;
import com.bstek.dorado.data.provider.Criteria;
import com.bstek.dorado.data.provider.Page;
/**
 * 使用profile模块必须实现的接口
 * @author Jacky.gao
 * @since 2013-2-26
 */
public interface IProfileDataService {
	/**
	 * 根据给出的父ID,返回其下所有子的URL,实现URL树构建
	 * @param companyId 所在公司(或其它)的ID
	 * @param parentId 父URL ID
	 * @return  返回指定父ID的URL集合
	 */
	List<UrlDefinition> loadUrls(String companyId,String parentId);
	/**
	 * 分页加载分配资源的目标对象
	 * @param page Dorado7分页对象
	 * @param criteria 过滤查询对象
	 */
	void loadAssignTargets(Page<AssignTarget> page,Criteria criteria);
	
	/**
	 * 返回加载个性化信息需要使用的分配资源目标对象的ID,比如username,companyid之
	 * @return 一个字符串
	 */
	String getAssignTargetId(HttpServletRequest request);
}

       接下来我们编写一个IProfileDataService接口实现类,代码如下:

IProfileDataService接口实现类源码
package test;

import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

import com.bstek.bdf2.core.context.ContextHolder;
import com.bstek.bdf2.core.model.Url;
import com.bstek.bdf2.core.view.url.UrlMaintain;
import com.bstek.bdf2.profile.model.AssignTarget;
import com.bstek.bdf2.profile.model.UrlDefinition;
import com.bstek.bdf2.profile.service.IProfileDataService;
import com.bstek.dorado.data.provider.Criteria;
import com.bstek.dorado.data.provider.Page;

@Component
public class TestProfileDataService implements IProfileDataService {
	@Autowired
	@Qualifier("bdf2.urlMaintain")
	private UrlMaintain urlMaintain;
	public List<UrlDefinition> loadUrls(String companyId,String parentId) {
		List<UrlDefinition> list=new ArrayList<UrlDefinition>();
		try {
			for(Url url:urlMaintain.loadUrls(parentId)){
				UrlDefinition def=new UrlDefinition();
				def.setId(url.getId());
				def.setUrl(url.getUrl());
				def.setName(url.getName());
				def.setParentId(parentId);
				list.add(def);
			}
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
		return list;
	}

	public void loadAssignTargets(Page<AssignTarget> page, Criteria criteria) {
		List<AssignTarget> targets=new ArrayList<AssignTarget>();
		AssignTarget t1=new AssignTarget();
		t1.setId("root-bstek");
		t1.setName("上海锐道");
		targets.add(t1);
		
		AssignTarget t2=new AssignTarget();
		t2.setId("root-ibm");
		t2.setName("IBM中国");
		targets.add(t2);
		page.setEntities(targets);
	}

	public String getAssignTargetId(HttpServletRequest request) {
		return ContextHolder.getLoginUser()==null?null:ContextHolder.getLoginUser().getCompanyId();
	}

}

       从实现类当中可以看到,在第一个方法加载菜单时,我们使用时BDF2-CORE模块当中加载菜单的类,实际应用当中,如果您项目当中没有CORE模块,那么,您需要自己编写加载URL菜单的代码;第二个方法加载需要分配个性化信息的目标对象时,我们虚拟了两家公司,实际应用当中,可以是公司,也可以是部门、群组或者直接分给某个用户;最后一个方法是系统在加载个性化信息时使用的,这里与前面对应采用的是公司的ID。

       实现类编写好并配置到Spring当中之后,接下来启动我们的项目,浏览com.bstek.bdf2.profile.view.component.ComponentMaintain.d这个URL,可以看到如下图所示的页面效果:

       可以看到,在选择不同的公司后,对应的URL菜单也会加载进来,在选择不同的URL时,这个URL对应的页面组件会被剖析成一棵树形,在这棵树当中找到我们需要进行个性化调整的组件,设置它的属性、事件或其下子组件的顺序。在做完这些操作之后,别忘记刷新系统缓存,否则将不会生效。

Attachments:

profile.png (image/png)