查询用户审批信息

        查询用户审批信息本质是查询的act_hi_comment表。act_hi_comment表存储的是“批注”。

        这张表中最重要的两个属性是:“批注人”、“批注”。当然,还存储了任务ID与流程实例ID。

        TASK_ID_  是任务ID。

        PROC_INST_ID 是流程实例ID。

        

           

        通过日志打印出来的SQL语句如下:

        select * from ACT_HI_COMMENT where PROC_INST_ID_ = ? order by TIME_ desc

        SQL语句中的"?"代表的是 流程实例的ID:5016。

        我们知道,一个流程实例包含着一些列任务。所以,为了查询出这些任务和多个上级对不同任务的“批注”,查询条件设置为“流程实例ID”还是很合理的。

        很值得一提的是,这张act_hi_comment表虽然已act_hi开头,但是却不是通过 HistoryService进行查询,而是通过TaskService进行查询。另外,为这张表插入数据的时候,用的Service也是TaskService。

        查询这张表的核心代码如下:

List<Comment> comments = taskService.getProcessInstanceComments(executionId);//executinoId是流程实例ID

        代码虽然简单,但是对于前后端对接起来却不容易。

        Comment是工作流框架提供的一个接口,并不是一个实体对象。

        而前端框架需要上述查询出来的comments集合中数据,并且要求为JSON格式。

        直接使用@ResponseBody返回会报错,我试了很多次。

        原因很简单,comments的泛型是是接口,不是实体。

        Comment接口定义如下:

        

package org.activiti.engine.task;

import java.util.Date;
import org.activiti.engine.history.HistoricData;

public interface Comment extends HistoricData {
    String getId();

    String getUserId();

    Date getTime();

    String getTaskId();

    String getProcessInstanceId();

    String getType();

    String getFullMessage();
}

        Activity工作流提供了Comment接口的实现,就是一些get/set方法,我就省略了。

        

package org.activiti.engine.impl.persistence.entity;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.regex.Pattern;
import org.activiti.engine.impl.db.PersistentObject;
import org.activiti.engine.task.Comment;
import org.activiti.engine.task.Event;

public class CommentEntity implements Comment, Event, PersistentObject, Serializable {
    private static final long serialVersionUID = 1L;
    public static final String TYPE_EVENT = "event";
    public static final String TYPE_COMMENT = "comment";
    protected String id;
    protected String type;
    protected String userId;
    protected Date time;
    protected String taskId;
    protected String processInstanceId;
    protected String action;
    protected String message;
    protected String fullMessage;
    public static String MESSAGE_PARTS_MARKER = "_|_";
    public static Pattern MESSAGE_PARTS_MARKER_REGEX = Pattern.compile("_\\|_");    
.....
}


        为了能够复制CommentEntity的属性,我创建了一个与之相似的类,用于封装数据,准备返回给前端。

        

package com.ssi.domains.workflow.entity;


import lombok.Getter;
import lombok.Setter;

import java.util.Date;

/**
 * Created by jay.zhou on 2018/7/2.
 */
@Getter
@Setter
public class MyCommentEntity {
    private String id;

    private String userId;//用户名,对应的是act_hi_comment表的USER_ID_字段

    private Date date;

    private String taskId;//任务id

    private String processInstanceId;//流程定义id

    private String message;//审批信息

    private String fullMessage;
}

        起初,为了实现属性的复制,我的代码是这样的。看起来又丑又长,那一串长长的set与get方法,着实令我不爽。我寻思着,能不能使用反射进行简化。在别的博主那里,我看到了一种思路。先获取俩个对象的字节码,再获取两个对象的所有Field,对比出相同的Field,然后进行属性复制。这种方法我觉得可行。但是想了一下,通过反射 Class中的getDeclaredFields() 方法获取到的两个数组,还要进行属性逐一比较,然后再进行逐一复制,还是挺麻烦的。


        //从数据库中查询到的审批信息的集合,但是Comment是一个接口,需要我们自己创建一个实现类与之对应
        List<Comment> comments = taskService.getProcessInstanceComments("5016");
        //创建我们自己的list集合
        List<MyCommentEntity> list = Lists.newArrayList();
        //为每一个查询到接口实现类复制属性到我们自己的类中,解析为前端JSON数据
        for(Comment comment :comments){
            //向下转型
            CommentEntity commentEntity = (CommentEntity)comment;
            //创建我们自己的类
            MyCommentEntity myCommentEntity = new MyCommentEntity();
            commentEntity.setId(myCommentEntity.getId());
            commentEntity.setUserId(myCommentEntity.getUserId());
            commentEntity.setMessage(myCommentEntity.getMessage());
            commentEntity.setTaskId(myCommentEntity.getTaskId());
            commentEntity.setProcessInstanceId(myCommentEntity.getProcessInstanceId());
            //添加我们自己的类
            list.add(myCommentEntity);
        }
        return list;

        后来,搜集了其它资料后,发现Spring带的BeanUtils类封装了常用的反射操作。其中就有这个属性复制。因此,代码修改为:

        

TaskService taskService = (TaskService) bf.getBean("taskService");
        //从数据库中查询到的审批信息的集合,但是Comment是一个接口,需要我们自己创建一个实现类与之对应
        List<Comment> comments = taskService.getProcessInstanceComments("5016");
        //创建我们自己的list集合
        List<MyCommentEntity> list = Lists.newArrayList();
        //为每一个查询到接口实现类复制属性到我们自己的类中,解析为前端JSON数据
        for(Comment comment :comments){
            //向下转型
            CommentEntity commentEntity = (CommentEntity)comment;
            //创建我们自己的类
            MyCommentEntity myCommentEntity = new MyCommentEntity();
            //属性复制,源属性为commentEntity, 目标属性为myCommentEntity
            BeanUtils.copyProperties(commentEntity, myCommentEntity);
            //添加我们自己的类
            list.add(myCommentEntity);
        }

        BeanUtils.copyProperties(Source,Target);找到Source与Target相同的属性,把Source的属性值复制到Target中。

        看到这么清爽的代码,心情好多了。反射,你成功引起了我的兴趣。

        最新研究结果显示,Comment接口可以不用向下转型,一样能够进行属性复制。

        上述代码可以改为 BeanUtils.copyProperties(comment,myCommentEntity);

猜你喜欢

转载自blog.csdn.net/yanluandai1985/article/details/80884695
今日推荐