手机端参照写法
一、需求:要求在手机端页面新增一个参照:
怎么在手机页面新增一个参照节点?第一步:我们肯定要明白手机端这个页面是怎么展现的?
其实手机端展现的原理很简单,手机端是通过加载在portal界面配置好的手机模板,我们知道,
portal可以配置手机、pc、pad三种终端的界面,这里我们需要配置在手机端的模板,具体看图:
浏览器输入127.0.0.1/portal输入管理员账号即可进入管理员界面,
选择系统管理->表单配置
选择main
然后就会跳转到"个性化设置",里面的说明看清楚。
下面看“增加项”,如果不用这个,请跳过
手动编写一个唯一的"编号"与"名称"即可。这里只做一个内容展现功能,并没有实际的操作。
这里我们重点了解一下“编辑‘
点击”编辑“就会跳转到这个界面
我们注意到左边就是我们的数据集,什么是数据集,(⊙﹏⊙)b这点基础应该有吧?我们点击那个”+“即可展现我们数据集中的属性
这里因为我们是新增一个显示在手机端的参照,所以涉及到数据的操作,我们肯定要选择一个可以关联数据库的字段,这时候预留自
定义属性就起到作用了,因为”vdef1~n“当初设计元数据的时候就是为了将来做功能拓展,这里派上用场了,
友情提示:将左边的属性移动到右边时,要关注这个字段是不是已经被使用,因为不能排除这个应用已经做了别的拓展,对吧?
另外,勾上”是否可见“,让它显示在模板。
我这里选择vdef11,因为前面的被其他使用了,然后选择这个节点,调整属性
因为这里是参照,我们一定要选择到参照,另外引用的参照,就是之前我们在UAP-Studio中模式化生成的参照。
关于怎么模式化生成参照,我这里只做简单的说明,具体请参考相关文档,
1.模式化生成参照,关注有没有生成”xxxModel与xxxControlor“这两个类,
2.查询数据库,关注参照有没有新增到数据库select * from bd_refinfo order by ts desc;
3.具体的逻辑请在xxxControlor中完成,我这里只做了一个简单的查询,大家可以参考其他参照的xxxControlor类怎么写的。
package nc.ref.cacoverplan.control;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import nc.uap.lfw.core.data.Dataset;
import nc.uap.lfw.core.data.PaginationInfo;
import nc.uap.lfw.core.event.DataLoadEvent;
import nc.uap.lfw.core.refnode.IRefNode;
import nc.uap.lfw.core.serializer.impl.List2DatasetSerializer;
import uap.lfw.ref.ctrl.LfwSqlGridReferenceController;
import uap.lfw.ref.sqlvo.ILfwRefSqlVO;
import uap.lfw.ref.sqlvo.LfwReferenceSqlVO;
import uap.lfw.ref.util.LfwReferenceUtil;
public class CacoverplanCAGridRefController extends LfwSqlGridReferenceController {
private String getMultilangTextSql(String fieldCodeInRef, String fieldCodeWithTable) {
StringBuilder sb = new StringBuilder();
sb.append(fieldCodeWithTable).append(' ').append(fieldCodeInRef);
for (int i = 2; i < 7; i++) {
sb.append(',').append(fieldCodeWithTable).append(i).append(' ').append(fieldCodeInRef).append(i);
}
return sb.toString();
}
@Override
public ILfwRefSqlVO getGridSqlVO() {
LfwReferenceSqlVO sqlvo = new LfwReferenceSqlVO();
StringBuilder selSql = new StringBuilder();
selSql.append("select a.pk_group,a.pk_org,a.pk_org_v,a.pk_dept,a.pk_plan,a.pk_salesman, ");
selSql.append(getMultilangTextSql("pk_account_vname", "b.vname")).append(',');
selSql.append(" a.vmemo from cuma_fugaiplan a ");
selSql.append("inner join cuma_account b on a.customer=b.pk_account ");
// String sql = "select b.vname,a.vmemo from cuma_fugaiplan a inner join cuma_account b on a.customer=b.pk_account";
//虚拟表(可以是单个数据库表,也可以是多个表联合查询的虚拟表)
sqlvo.setTableName("(" + selSql + ") cuma_fugaiplan");
//真实数据库表(虚拟表中包含的所有表的集合)
sqlvo.setRealTableNames("cuma_fugaiplan");
//设置虚拟表排序字段
sqlvo.setOrderByPart("");
return sqlvo;
}
@Override
public void onDataLoad(DataLoadEvent e) {
Dataset ds = (Dataset) e.getSource();
ILfwRefSqlVO vo = getMainRefSqlVO();
if (vo == null) {
return;
}
Map values = new HashMap(2);
values.put("KEY_LOCATE_WP", new Object[] { getFilterValue() });
Map sqlMap = vo.getSql(ds.getFieldSet().getFields(), values, null);
String sql = (String) sqlMap.get("KEY_SQL");
String countSql = (String) sqlMap.get("KEY_COUNT_SQL");
List params = (List) sqlMap.get("KEY_SQL_PARAM_VALUES");
sql=sql.replaceAll("realfinishtime", "dplanfinishtime");
countSql=countSql.replaceAll("realfinishtime", "dplanfinishtime");
PaginationInfo pInfo = ds.getCurrentRowSet().getPaginationInfo();
IRefNode refNode = LfwReferenceUtil.getRefNodeFromParentWindow(null);
List vec = getRefResult(refNode, vo, sql, countSql, params, pInfo);
//ds.getFieldSet().addField(new field);
new List2DatasetSerializer().serialize(ds.getCurrentKey(), pInfo, vec,
ds);
}
}
好了,我们的初期设置工作已经做好了,基本上可以在手机上显示那个参照了,如果没有成功,只能说你不够细心了
下面是具体代码的调整,这个根据具体的业务,可以做一个参考。
移动CRM客户端所有关于前端页面交互都会走这个类,我们先找到这个类”MobileAdapterServiceImpl“
怎么找到这个类,试试Ctrl+shift+T,很方便的一个快捷键。
相信聪明的你早就找到了,我们关注getReferToSrvMap()这个方法。
private Map<String, String> getReferToSrvMap() {
Map<String, String> referToMap = new HashMap<String, String>();
referToMap.put(MobileConsts.REFER_TO_ACCOUNT, MobileConsts.ACCOUNT_QRY_SERVICE);
referToMap.put(MobileConsts.REFER_TO_LEAD, MobileConsts.LEAD_QRY_SERVICE);
referToMap.put(MobileConsts.REFER_TO_BO, MobileConsts.BO_QRY_SERVICE);
referToMap.put(MobileConsts.REFER_TO_CONTACT, MobileConsts.CONTACT_QRY_SERVICE);
referToMap.put(MobileConsts.REFER_TO_INVENTORY, MobileConsts.INVENTORY_QRY_SERVICE);
referToMap.put(MobileConsts.REFER_TO_INVENTORY_WEB, MobileConsts.INVENTORY_QRY_SERVICE);
referToMap.put(MobileConsts.REFER_TO_INVENTORYCLASS, MobileConsts.INVENTORYCLASS_QRY_SERVICE);
referToMap.put(MobileConsts.REFER_TO_ACTIVITY, MobileConsts.ACTIVITY_QRY_SERVICE);
referToMap.put(MobileConsts.REFER_TO_COVERPLAN, MobileConsts.ACCOUNT_COVERPLAN_SERVICE);
return referToMap;
}
referToMap.put(MobileConsts.REFER_TO_COVERPLAN, MobileConsts.ACCOUNT_COVERPLAN_SERVICE);这个是我自己手动加的,
目的就是把自己的服务给注册到这个类中,我们看下MobileConsts.REFER_TO_COVERPLAN 指定的 MobileConsts.ACCOUNT_COVERPLAN_SERVICE我们跟进去看下是什么。
/**
* 移动覆盖计划查询服务
*/
public static final String ACCOUNT_COVERPLAN_SERVICE = "nc.pubitf.ca.cuma.account.ma.IMACoverPlanService";
我们看到它实际上就是一个服务类的接口,它会根据这个接口找到相应的实现类。
写完这个之后,我们下一个关注便是
public List<Map> getReferValues(String groupId, String userId, String orgId, String referto, String condition,
String startline, String count, String ispaging)
getReferValues这个方法顾名思义它是得到参照的值的,所以我们要在自己的服务中复写这个方法,写上自己的业务,尽量不要使用这个通用的方法。
package nc.impl.ca.cuma.account.ma;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import nc.bs.ca.capub.mobile.common.MobileCommon;
import nc.bs.ca.capub.mobile.common.MobileConsts;
import nc.bs.ca.capub.mobile.data.handler.MobileReferListHandler;
import nc.bs.ca.capub.mobile.service.MobilePubService;
import nc.bs.ca.capub.mobile.template.MobileTemplateManager;
import nc.bs.ca.capub.service.NCLocatorFactory;
import nc.bs.ca.capub.util.ArrayUtils;
import nc.bs.ca.capub.util.CommonUtils;
import nc.bs.ca.capub.util.QuerySchemeUtils;
import nc.bs.ca.capub.util.QueryUtils;
import nc.bs.ca.capub.vo.CrmLoginContext;
import nc.bs.ca.capub.vo.CrmQueryCondVO;
import nc.bs.framework.common.NCLocator;
import nc.itf.ca.capub.commonfunc.activity.IActivityService;
import nc.itf.ca.cuma.account.IAccountService;
import nc.itf.ca.cuma.account.account.coverplan.ICoverplanService;
import nc.pubitf.ca.cuma.account.ma.IMACoverPlanService;
import nc.uap.cpb.org.vos.CpUserVO;
import nc.uap.ctrl.tpl.qry.FromWhereSQLImpl;
import nc.uap.ctrl.tpl.qry.base.QuerySchemeVO;
import nc.uap.lfw.core.data.PaginationInfo;
import nc.uap.lfw.core.exception.LfwBusinessException;
import nc.vo.ca.capub.commonfunc.activity.ActivityVO;
import nc.vo.ca.cuma.account.AccountVO;
import nc.vo.cuma.fugaiplan.FugaiPlanVO;
import nc.vo.org.DeptVO;
import nc.vo.pub.SuperVO;
import nc.vo.pub.VOStatus;
import nc.vo.pub.lang.UFDate;
import nc.vo.pub.lang.UFDateTime;
import org.apache.commons.lang.StringUtils;
import uap.lfw.imp.query.base.QuerySchemeUtil;
public class MACoverPlanServiceImpl extends MobilePubService implements IMACoverPlanService {
private ICoverplanService service;
private ICoverplanService getService() {
if (null == this.service) {
this.service = NCLocatorFactory.getInstance().getCANCLocator()
.lookup(ICoverplanService.class);
}
return this.service;
}
@Override
public List<Map> getReferValues(String groupId, String userId, String pk_org, String referTo, String condition,
String startline, String count, String ispaging) {
CrmLoginContext crmLoginContext = new CrmLoginContext();
crmLoginContext.setPk_group(groupId);
crmLoginContext.setNodeCode(MobileConsts.FUN_CODE_COVERPLAN);
crmLoginContext.setPk_org(pk_org);
crmLoginContext.setPk_user(userId);
IMACoverPlanService service = NCLocatorFactory.getInstance().getCANCLocator().lookup(IMACoverPlanService.class);
int pageSize = 0;
if (!StringUtils.isEmpty(startline)) {
pageSize = Integer.valueOf(count);
}
PaginationInfo pinfo = new PaginationInfo();
pinfo.setPageSize(pageSize);
SuperVO[] vos = null;
if (StringUtils.isEmpty(startline)) {
pinfo.setPageIndex(0);
} else {
pinfo.setPageIndex(Integer.valueOf(startline) / pageSize);
}
CrmQueryCondVO crmQueryCondVO = new CrmQueryCondVO();
String sql = "";
if (StringUtils.isNotEmpty(condition)) {
sql = ActivityVO.VNAME + " like '%" + condition + "%'";
}
crmQueryCondVO.setWherePart(sql);
crmQueryCondVO.setCrmScope(true);
crmQueryCondVO.setOrderPart(this.getOrderByPart());
//crmQueryCondVO.setExtSql(AccountVO.ENABLESTATE + "=" + EnableStateEnum.ENABLESTATE_ENABLE);
try {
//vos = service.queryVOs(crmLoginContext, new ActivityVO(), pinfo, crmQueryCondVO);
vos = this.getService().queryVOs(pinfo, new FugaiPlanVO(),sql, this.getOrderByPart());
} catch (LfwBusinessException e) {
return MobileCommon.exceptionReturn(e, e.getMessage());
}
List<Map> funInfo = new ArrayList<Map>();
Map funMap = new HashMap();
funInfo.add(funMap);
funMap.put(MobileConsts.ORGID, pk_org);
funMap.put(MobileConsts.BNSTYPE, "");
funMap.put(MobileConsts.WINID, "coverplan_listwin");
funMap.put(MobileConsts.FUNCODE, MobileConsts.FUN_CODE_COVERPLAN);
List<Map<String, Object>> template = null;
try {
template = MobileTemplateManager.getTemplate(groupId, userId, "", "", "", funInfo);
} catch (Exception e) {
return MobileCommon.exceptionReturn(e, e.getMessage());
}
MobileReferListHandler mobileReferListHandler = new MobileReferListHandler(template, vos,
"", FugaiPlanVO.VMEMO);
try {
return mobileReferListHandler.handle();
} catch (Exception e) {
return MobileCommon.exceptionReturn(e, e.getMessage());
}
}
//省略了其他业务代码
}
我们在这个方法里写上自己的逻辑,其他代码可以不用怎么改,大概根据别人写好的,改下就好,但是这个考验你的迁移能力,可能会遇到各种错,慢慢调,这里提醒一下关注vos = this.getService().queryVOs(pinfo, new FugaiPlanVO(),sql, this.getOrderByPart());。因为这个方法是得到你的相应的VO,为什么要得到VO,因为这个VO封装了页面所需要的参数与值,这相当于是一种协议,一种约定。它要什么,你就必须给什么。
这个
MobileReferListHandler mobileReferListHandler = new MobileReferListHandler(template, vos,
"", FugaiPlanVO.VMEMO);
最好也关注一下,至于它是干嘛的,自己可以跟进去看,我这里不做解释,大概就是找到模板,填充数据。
还有一些业务的改动,它显示这个参照的时候,如果我希望用户选择完毕后,做一个数据的回显,那么我们需要关注这个类
ActivityObjectViewData
private List<Map> getHeadData(List<Map> headTplList) throws Exception {
List<Map> headList = new ArrayList<Map>();
Map headMap = new HashMap();
headList.add(headMap);
Map tabContentMap = new HashMap();
headMap.put(TABCONTENT, tabContentMap);
List<Map> groupList = new ArrayList<Map>();
tabContentMap.put(GROUP, groupList);
Map groupMap = new HashMap();
groupList.add(groupMap);
groupMap.put(TABCODE, "");
groupMap.put(TABNAME, "");
groupMap.put("relatedlist",
((Map) ((List) this.template.get(0).get(MobileConsts.HEAD_TEMPLATE_KEY)).get(0)).get("relatedlist"));
Map billItemDataMap = new HashMap();
groupMap.put(TABCONTENT, billItemDataMap);
List<Map> dataList = new ArrayList<Map>();
billItemDataMap.put(BILLITEM_DATA, dataList);
for (Map attrMap : headTplList) {
String type = attrMap.get("type").toString();
String value = null;
if (StringUtils.isNotEmpty(type)) {
if (MobileConsts.REFERTYPE.equalsIgnoreCase(type) || MobileConsts.ADDRESS.equalsIgnoreCase(type)) {
try {
if ("referobj_name".equals(attrMap.get(MobileConsts.KEY).toString())) {
value = this.getRealValue("referobj_name", parentVO);
} else {
value = MobileReferUtil.getReferItemValue(parentVO, attrMap, type,
attrMap.get(MobileConsts.KEY).toString());
}
} catch (Exception e) {
LfwLogger.error(e.getMessage());
}
}
//日期类型去掉时分秒
else if (MobileConsts.DATE.equalsIgnoreCase(type) && null != attrMap.get(MobileConsts.KEY)) {
if (parentVO.getAttributeValue(attrMap.get(MobileConsts.KEY).toString()) != null)
value = parentVO.getAttributeValue(attrMap.get(MobileConsts.KEY).toString()).toString()
.split(" ")[0];
} else if (MobileConsts.COMBO.equalsIgnoreCase(type) && null != attrMap.get(MobileConsts.KEY)) {
List<Map> enumList = (List<Map>) attrMap.get("enumlist");
if (enumList == null || enumList.size() == 0) {
value = this.getRealValue(attrMap.get(MobileConsts.KEY).toString(), parentVO);
} else {
String key = "";
if (parentVO.getAttributeValue(attrMap.get(MobileConsts.KEY).toString()) != null) {
key = parentVO.getAttributeValue(attrMap.get(MobileConsts.KEY).toString()).toString();
}
if (StringUtils.isEmpty(key)) {
value = "";
} else {
for (Map map : enumList) {
if (map.get("realval").equals(key)) {
value = map.get("diplayval").toString();
}
}
}
}
// if (value == null) {
// value = "";
// }
}else if (MobileConsts.MONEY.equalsIgnoreCase(type) && null != attrMap.get(MobileConsts.KEY)) {
value = ActivityUtils.getOrgCurrtypeSign((ActivityVO) parentVO)
+ parentVO.getAttributeValue((String)attrMap.get(MobileConsts.KEY));
}else {
String attrId = attrMap.get(MobileConsts.KEY).toString();
if("action_name".equals(attrId))
value = getShowValue4ItemMap("action", parentVO);
else if("refstage_name".equals(attrId))
value = getShowValue4ItemMap("refstage", parentVO);
else if("vdef11".equals(attrId)){
// ICrmQueryOpt service = NCLocatorFactory.getInstance().getCANCLocator()
// .lookup(ICrmQueryOpt.class);
//
// SuperVO fgvo = (SuperVO) service.queryVOs("select vmemo from fugaiplan where pk_plan= '"+value+"' ");
// if (fgvo != null) {
//TODO 显示覆盖计划的内容
// value = (String) fgvo.getAttributeValue("vmemo");
// }
value = MobileCommon.getString(parentVO.getAttributeValue(attrId));
BaseDAO baseDAO=new BaseDAO();
List<Map> list=(List<Map>) baseDAO.executeQuery("select vmemo from cuma_fugaiplan where pk_plan= '"+value+"' ", new MapListProcessor());
Map map=list.get(0);
value = (String) map.get("vmemo");
}
else
value = MobileCommon.getString(parentVO.getAttributeValue(attrId));
}
}
attrMap.put(MobileConsts.DIGEST, "N");
attrMap.put(MobileConsts.VALUE, value);
attrMap.put(MobileConsts.PARAMLIST, getParamList(attrMap.get(MobileConsts.KEY).toString(), parentVO));
dataList.add(attrMap);
}
addAttachment(dataList);
return headList;
}
这个方法就是塞数据的类了,我们注意到我写的那部分else if("vdef11".equals(attrId)){
value = MobileCommon.getString(parentVO.getAttributeValue(attrId));
BaseDAO baseDAO=new BaseDAO();
List<Map> list=(List<Map>) baseDAO.executeQuery("select vmemo from cuma_fugaiplan where pk_plan= '"+value+"' ", new MapListProcessor());
Map map=list.get(0);
value = (String) map.get("vmemo");
}
这里利用BaseDAO查询数据库,回显数据
这里,手机端参照写法大概就写完了,大家有需要的时候可以实践一下,可能一次不会成功,坚持就是胜利哦,加油!
最后说一句,分享代码,让生活更美好!