本文分享在BPM-Table上配置操作日志的经验.最终效果图如下:
需求背景:
系统中已有表RV_XIANGMU(P1项目表),并已有相应视图.
步骤1:新增日志表,表名为LOG_RV_XIANGMU.如下图:
步骤2:新增log_table函数.
//入参0:视图自动KEY(用于查找翻译信息) //入参1:旧VO(无值表示新增) //入参2:新VO(无值表示删除) import com.riversoft.platform.po.VwUrl; import com.riversoft.core.db.SequenceService; import java.util.*; //获取视图 VwUrl url = orm.findByPk(VwUrl.class.getName(),args[0]); if(url==null){ throw new Exception("找不到视图["+args[0]+"],请联系管理员."); } //查找实际视图 Map map = null; if("dyn".equals(url.getViewClass())){ //主表视图 map = orm.findByPk("VwDynTable",args[0]); }else if("sub".equals(url.getViewClass())){ //子表视图 map = orm.findByPk("VwSubTable",args[0]); }else{ //错误视图 throw new Exception("视图配置出错,无法登记日志."); } String targetTable = map.get("name"); String logTable = "LOG_"+targetTable; Integer mode ; if(args[1]==null){ mode = 1;//新增 }else if(args[2]==null){ mode = 3;//删除 }else{ mode = 2;//修改 } //获取业务表主键 List keys = new ArrayList(); for(Map column:map.get("columns")){ if(column.get("updatePri")==null){//主键 keys.add(column.get("name")); } } StringBuffer sql = new StringBuffer(); sql.append("insert into ").append(logTable).append(" ("); //业务主键 if(true){ StringBuffer buff = new StringBuffer(); for(Object field:keys){ buff.append(",").append(field); } sql.append(buff.substring(1)); } sql.append(",OPR_MODE,OPR_USER,OPR_TIME,FIELD_VAL,FIELD_NAME,OLD_VAL,OLD_NAME,NEW_VAL,NEW_NAME,BATCH_ID) values ("); //业务主键 if(true){ StringBuffer buff = new StringBuffer(); for(Object field:keys){ buff.append(",").append("?"); } sql.append(buff.substring(1)); } sql.append(",?,?,?,?,?,?,?,?,?,?)"); Long batchId = SequenceService.getInstance().next("LOG"); Map oldVO = args[1]; Map newVO = args[2]; //循环设值 for(Map column:map.get("columns")){ String name = column.get("name"); if(mode==1&&newVO.get(name)==null){ continue; }else if(mode==3&&oldVO.get(name)==null){ continue; }else if(mode==2){ log.debug("["+name+"]-->"); if(oldVO.get(name)==newVO.get(name)){ continue; } } Map vo = (newVO!=null?newVO:oldVO); List objs = new ArrayList(); for(String field:keys){//设置业务主键 objs.add(vo.get(field)); } //OPR_MODE objs.add(mode); //OPR_USER objs.add(session.get("USER").getUid()); //OPR_TIME objs.add(new Date()); //FIELD_VAL objs.add(name); //FIELD_NAME objs.add(column.get("busiName")); //OLD if(oldVO==null||oldVO.get(name)==null){ objs.add(null); objs.add(null); }else{ objs.add(oldVO.get(name)); objs.add(cm.widget(column.get("widget"),oldVO.get(name))); } //NEW if(newVO==null||newVO.get(name)==null){ objs.add(null); objs.add(null); }else{ objs.add(newVO.get(name)); objs.add(cm.widget(column.get("widget"),newVO.get(name))); } //BATCH_ID objs.add(batchId); db.exec(sql.toString(),objs.toArray()); }
步骤3:编辑P1项目表视图,在触发器中调用log_table函数.如下图:
前置处理器中代码:
if(mode==2){//保存旧VO,方便登记日志 variable.put("old_vo",db.findByPk(vo)); }else if(mode==3){ variable.put("old_vo",vo); }
后置处理器中代码:
if(mode==3){ //删除主表时,联动删除所有子表数据 db.exec("delete from RV_MINGXI where MX_XIANGMU_ID = ?",vo.get("XM_ID")); } Object oldVO = (mode==1?null:variable.get("old_vo"));//新增时旧值为空 Object newVO = (mode==3?null:vo);//删除时新值为空 cm.invoke("log_table","hoHoybJfa2X",oldVO,newVO);
至此日志登记功能已经完成.可以在"动态表管理"菜单里面,选择"预览数据",即可查看每次被登记的日志详细信息.
接下来,将新增一个日志表界面,并作为tab标签关联到P1项目表界面中.
步骤4:新增LOG_RV_XIANGMU表界面.
步骤5:最后,在P1主表的"子表信息"里,将已设置的日志视图关联进来.
最终效果可以查看本文开头的效果图.
(完)
需要获取创河软件或Rivev软件(Platform或SDK)的相关资料,请联系riversoft(at)126.com.