操作日志设计


本文分享在BPM-Table上配置操作日志的经验.最终效果图如下:
操作日志设计_第1张图片
 

需求背景:

系统中已有表RV_XIANGMU(P1项目表),并已有相应视图.

 

 步骤1:新增日志表,表名为LOG_RV_XIANGMU.如下图:

操作日志设计_第2张图片
 

 

步骤2:新增log_table函数.

 操作日志设计_第3张图片
 函数内容如下:

//入参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函数.如下图:

操作日志设计_第4张图片
 

前置处理器中代码: 

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张图片
  

操作日志设计_第6张图片
 

操作日志设计_第7张图片
 

操作日志设计_第8张图片
 

步骤5:最后,在P1主表的"子表信息"里,将已设置的日志视图关联进来.

操作日志设计_第9张图片
 

最终效果可以查看本文开头的效果图.

 

(完)

 

 需要获取创河软件或Rivev软件(Platform或SDK)的相关资料,请联系riversoft(at)126.com.

 

你可能感兴趣的:(工作流,企业应用,动态表,开发框架,RiverSoft)