目录
一、需求说明
在项目落地时,经常会遇到客户对于原生Windhcill工作流页面,面向对象调转后进行操作感到繁琐,想要更简化终端页面的操作。特别是对PBO(即业务主对象),经常会有一些内容的下载,更换,批注等等的需求,想要在工作流任务的页面直接进行处理,而后进行任务的后续进行。
故,此示例将PBO以表格的方式,于流程任务的表单页面单行展现出来,并在末尾列对于主内容提供了操作的能力。
二、代码示例
2.1 表格代码展示
package ext.test.afterSaleTool.builders;
import java.util.ArrayList;
import java.util.List;
import wt.content.ContentHelper;
import wt.content.ContentHolder;
import wt.content.ContentRoleType;
import wt.fc.Persistable;
import wt.fc.QueryResult;
import wt.fc.ReferenceFactory;
import wt.util.WTException;
import wt.workflow.work.WorkItem;
import com.ptc.jca.mvc.components.JcaComponentParams;
import com.ptc.mvc.components.AbstractComponentBuilder;
import com.ptc.mvc.components.ColumnConfig;
import com.ptc.mvc.components.ComponentBuilder;
import com.ptc.mvc.components.ComponentConfig;
import com.ptc.mvc.components.ComponentConfigFactory;
import com.ptc.mvc.components.ComponentParams;
import com.ptc.mvc.components.TableConfig;
import com.ptc.netmarkets.util.beans.NmCommandBean;
@ComponentBuilder("ext.test.afterSaleTool.builders.RelatedAttachmentTableBuilder")
public class RelatedAttachmentTableBuilder extends AbstractComponentBuilder{
public ComponentConfig buildComponentConfig(ComponentParams componentparams) throws WTException{
ComponentConfigFactory factory = getComponentConfigFactory();
TableConfig table = factory.newTableConfig();
table.setLabel("上传附件列表");
table.setSelectable(false);
//流程环节
ColumnConfig col = factory.newColumnConfig("activityName",true);
col.setLabel("流程环节");
col.setDataUtilityId("AfterSaleToolDataUtility");
table.addComponent(col);
//创建者
col = factory.newColumnConfig("creator",true);
col.setLabel("上传人");
col.setDataUtilityId("AfterSaleToolDataUtility");
table.addComponent(col);
//文档名称
col = factory.newColumnConfig("fileName",true);
col.setLabel("文档名称");
col.setDataUtilityId("AfterSaleToolDataUtility");
table.addComponent(col);
//操作
col = factory.newColumnConfig("operation",true);
col.setLabel("操作");
col.setWidth(100);
col.setDataUtilityId("AfterSaleToolDataUtility");
table.addComponent(col);
//操作菜单
table.setActionModel("afterSaleTool_relatedAttachment_toolbar");
return table;
}
public Object buildComponentData(ComponentConfig componentconfig,ComponentParams componentparams) throws Exception{
JcaComponentParams jcacomponentparams = (JcaComponentParams)componentparams;
NmCommandBean nmcommandbean = jcacomponentparams.getHelperBean().getNmCommandBean();
return initData(nmcommandbean);
}
@SuppressWarnings({ "rawtypes", "unchecked" })
private Object initData(NmCommandBean nmcommandbean) throws Exception{
String oid=nmcommandbean.getTextParameter("oid");
WorkItem item=(WorkItem) new ReferenceFactory().getReference(oid).getObject();
Persistable pbo=item.getPrimaryBusinessObject().getObject();
if(!(pbo instanceof ContentHolder))
return null;
List l = new ArrayList();
QueryResult qr = ContentHelper.service.getContentsByRole((ContentHolder) pbo, ContentRoleType.SECONDARY);
while(qr.hasMoreElements()){
Object obj = (Object)qr.nextElement();
l.add(obj);
}
qr = ContentHelper.service.getContentsByRole((ContentHolder) pbo, ContentRoleType.PRIMARY);
while(qr.hasMoreElements()){
Object obj = (Object)qr.nextElement();
l.add(obj);
}
return l;
}
}
2.2 Datautility代码展示
package ext.test.afterSaleTool.datautility;
import wt.content.ApplicationData;
import wt.content.ContentHelper;
import wt.content.ContentHolder;
import wt.fc.Persistable;
import wt.fc.PersistenceHelper;
import wt.fc.ReferenceFactory;
import wt.session.SessionHelper;
import wt.util.WTException;
import wt.workflow.engine.WfActivity;
import wt.workflow.work.WorkItem;
import com.ptc.core.components.descriptor.ModelContext;
import com.ptc.core.components.factory.AbstractDataUtility;
import com.ptc.core.components.rendering.GuiComponent;
import com.ptc.core.components.rendering.guicomponents.Label;
import com.ptc.core.components.rendering.guicomponents.TextDisplayComponent;
import com.ptc.netmarkets.util.misc.NmAction;
import com.ptc.netmarkets.util.misc.NmActionServiceHelper;
public class AfterSaleToolDataUtility extends AbstractDataUtility {
private static final ReferenceFactory RF=new ReferenceFactory();
private static final String BLANK_SPACE = " ";
@Override
public Object getDataValue(String componentId, Object object, ModelContext modelContext)
throws WTException {
if(!(object instanceof ApplicationData))
return null;
ApplicationData data=(ApplicationData)object;
if(componentId.equals("operation")){//操作项
ContentHolder holder=getContentHolder(modelContext);
if(holder!=null)
return getOptionComponent(componentId,data,holder,modelContext);
}else if(componentId.equals("activityName")){
return getLabelComponent(componentId, data.getDescription(), data);
}else if(componentId.equals("creator")){
return getLabelComponent(componentId, data.getModifiedBy().getFullName(), data);
}else if(componentId.equals("fileName")){
return getLabelComponent(componentId, data.getFileName(), data);
}
return null;
}
/**
*展示控件
* */
private GuiComponent getLabelComponent(String key,String value,Persistable persistable){
Label label=new Label("");
label.setValue(value);
label.setId(key+"_"+PersistenceHelper.getObjectIdentifier(persistable).getId());
return label;
}
private Object getOptionComponent(String componentId, ApplicationData data, ContentHolder holder, ModelContext modelContext)throws WTException{
TextDisplayComponent guiComp = null;
String oid=modelContext.getNmCommandBean().getTextParameter("oid");
WorkItem item=(WorkItem) RF.getReference(oid).getObject();
WfActivity activity=(WfActivity)item.getSource().getObject();
Object readOnlyObj=activity.getContext().getValue("readonlyRelatedDoc");
Boolean readOnly=readOnlyObj==null?false:(Boolean)readOnlyObj;
try{
guiComp=new TextDisplayComponent("");
guiComp.setId(componentId+"_"+PersistenceHelper.getObjectIdentifier(data).getId());
guiComp.setRichText(false);
guiComp.setCheckXSS(false);
String downloadUrl=ContentHelper.service.getDownloadURL(holder, data).toString();
StringBuffer buffer=new StringBuffer();
//下载
buffer.append("<a href=\"javascript:void(0);\" onclick=\"window.open('"+downloadUrl+"','_blank')\">");
buffer.append("<img src=\"netmarkets/images/download.gif\" alt=\"下载\" title=\"下载\">");
buffer.append("</a>");
buffer.append(BLANK_SPACE+BLANK_SPACE);
buffer.append(BLANK_SPACE+BLANK_SPACE);
//当前用户
String localUserName=SessionHelper.manager.getPrincipalReference().getFullName();
String creator=data.getCreatedBy().getFullName();
if(!localUserName.equalsIgnoreCase(creator)||item.isComplete()||readOnly){
guiComp.setValue(buffer.toString());
return guiComp;
}
//替换
NmAction nmaction=NmActionServiceHelper.service.getAction("lqPartActions","replaceAttachment");
nmaction.setContextObject(modelContext.getNmCommandBean().getActionOid());
nmaction.setButton(true);
nmaction.addParam("oldDataOid",RF.getReferenceString(data));
nmaction.addParam("holderOid", RF.getReferenceString(holder));
String url=nmaction.getActionUrlExternal();
buffer.append("<a href=\"javascript:void(0);\" onclick=\""+url+"\">");
buffer.append("<img src=\"netmarkets/images/edit.gif\" alt=\"替换\" title=\"替换\">");
buffer.append("</a>");
buffer.append(BLANK_SPACE+BLANK_SPACE);
buffer.append(BLANK_SPACE+BLANK_SPACE);
//移除
nmaction=NmActionServiceHelper.service.getAction("lqPartActions","removeAttachment");
nmaction.setContextObject(modelContext.getNmCommandBean().getActionOid());
nmaction.setButton(true);
nmaction.addParam("dataOid",RF.getReferenceString(data));
nmaction.addParam("holderOid", RF.getReferenceString(holder));
url=nmaction.getActionUrlExternal();
buffer.append("<a href=\"javascript:void(0);\" onclick=\""+url+"\">");
buffer.append("<img src=\"netmarkets/images/delete.gif\" alt=\"删除\" title=\"删除\">");
buffer.append("</a>");
buffer.append(BLANK_SPACE+BLANK_SPACE);
guiComp.setValue(buffer.toString());
}catch(Exception e){
throw new WTException(e);
}
return guiComp;
}
private static ContentHolder getContentHolder(ModelContext modelContext) throws WTException{
String oid=modelContext.getNmCommandBean().getTextParameter("oid");
WorkItem item=(WorkItem) RF.getReference(oid).getObject();
Persistable persistable=item.getPrimaryBusinessObject().getObject();
if(persistable instanceof ContentHolder)
return (ContentHolder)persistable;
return null;
}
}
三、代码说明
在TableBuilder的表格中,最后一列定义为了“操作列”,列的唯一标识为operation。所有的列都绑定了同一个Datautility类来进行显示的处理。
在Datautility加载渲染时,遇到列唯一标识为operation时,调用getOptionComponent方法进行前端需要提供显示内容的html的拼接,并在拼接的html上嵌套标签行内的javascript事件,而后触发javascript对应的动作。以此达到下载、替换、移除主内容的能力。