Java implements a set of process management and flow ideas (pseudo workflow)
A management project is required to implement a set of process management, such as the application approval process for asking for leave. After referring to a lot of information and discussing with colleagues, A self-implemented process management is achieved. The following provides my design ideas. After knowing the ideas, it is much easier to implement them. First, I designed five classes to implement independent process settings, mainly to define the process and process flow. Note: This is a design diagram, not a Dictionary: Data Dictionary. Not to mention, the Flow type exists here: Flow, that is, the definition of the process, including the process name and description, type, enabling time, remarks, etc. Currently, you can determine whether the current process is enabled by determining the activation time of a certain type of process. Only one process is enabled for one category. Therefore, you only need to use the process type to determine the process, and do not specify the Status field. FlowInfoMovingNode: process node. when analyzing the process flow, we find that one flow step is equivalent to jumping from one node to another. Therefore, we design this process node class to represent each step. This includes the process, node name, node description, and listening permission. Explain what the listening permission is. because most of our work is the review process, each node must have a review process before entering the next node, therefore, we need this handlerRole attribute to determine the permissions of the node for review. We also know that the review is generally performed by someone, which we will talk about later. A permission is specified here, that is, the permission of the node can be reviewed. FlowInfoMovingRole: Flow flow rule. In order to solve each branch from the node, we designed this flow rule, which can be put together in FlowInfoMovingNode, however, in terms of data and management, it is better to add flow rules for convenience and clarity. FlowInfoMovingRole is mainly used to determine the flow rules. For example, if a node passes the rule, which node should the node go to and which node should the node fail to pass, in this way, you can set branches, single branches, and loops in the same way. Transition is a conversion rule. Refer to shiro's permission verification method. We also use pure string format to determine the conversion rule. FlowInfoMoving: to which the node belongs (to which the node belongs, the streaming process is also obtained), and the application source (because we do not know what the application source is, we only manage how the process works, the application source has nothing to do with us. we store the unique ID of the application source. If you want to view the application source information during the review process, you can request the Url (handlerUrl) listened to in the Flow for viewing. I will pass the unique identity of the application source to the Url as a parameter ). This is the most frequent operation, so I will explain this class in detail. The following describes the specific implementation of the class design. Attribute fields are annotated for explanation: copy the code/*** flow information ** @ author lichao **/@ Entity @ Table (name = FlowInfoMoving. TABLE_NAME) public class FlowInfoMoving extends BaseAuditEntity {private static final long serialVersionUID = 1L; public static final String TABLE_NAME = "t_flowInfoMoving"; // process node, identifies the node to which the flow information is transferred @ ManyToOne (fetch = FetchType. EAGER) @ JoinColumn (name = "node_id", nullable = true) private FlowInfoM OvingNode node; // application source, which uniquely identifies the application information. @ Column private Long applyId; // applicant. Applicant: @ ManyToOne (fetch = FetchType. EAGER) @ JoinColumn (name = "applyuser_id", nullable = false) private User applyUser; // application information. A brief overview of the application information is provided, provided by the application @ Column (length = 50) @ Size (max = 50) private String discription; // application type, that is, the type of the application process @ ManyToOne (fetch = FetchType. EAGER) @ JoinColumn (name = "flowtype_id", nullable = false) private D Ictionary applyType; // the result of the transformation, that is, the audit fails, and other conditions. This condition is different from the transition of FlowInfoMovingRole, because it has been added for review, other information conditions such as ended @ Column (length = 50) @ Size (max = 50) private String transition; // process information, that is, audit information, added by the reviewer @ Column (length = 100) @ Size (max = 100) private String handlerInfo; // the handler, who applies for the transfer, handlerRole in FlowInfoMovingNode is used for filtering. // the handler of the previous node selects a specific reviewer. @ ManyToOne (fetch = FetchType. EAGER) @ JoinColumn (name = "handleruser_id", nullable = false) private User handlerUser; // status of the flow information, used for query, 0 unreviewed, 1 reviewed, 2 This application has ended @ Column () private int status; // getter... and setter ....} copy the code so that the entire process definition is over. We can set the process rules to set the flow mode. In this way, you can customize any complicated process and modify it at will. The result of this design is that you can customize the process at will first, and the application source does not need to manage the flow of the process. You only need to submit one application, other things are implemented by the process. Let's take a look at how a process works. 1. First, pass specific application information through an interface. 2. Determine the process through getType () in the interface. 3. query the START process node. 4. save the start information to the flow information and wait for processing. handled by the reviewer, specifying the next reviewer 6. obtain the next process node by processing the result. find the next node 8. save the processing information and the information of the next node to the transfer information and wait for processing. it is handled by the reviewer, so that the process is always known to end 10. if the next node found through review information is null, this process has ended, 11. save the ending information to the flow information 12. change the status of the entire flow to "ended. The first is how Applyable is designed: in fact, an interface is used to provide some application information. Copy the code public interface Applyable {// obtain the applied id and perform a joint query with the category, used to determine the specific process Long getId (); // to determine the specific process String getApplyType (); // to obtain the conversion condition, used to determine the first step after the application String getTransition (); // get the description String getDiscription (); // get the approver, that is, the first step is to approve the User getHandlerUser ();} copy the code and then the main control flow and application interface to copy the code/***** @ Description: service * @ Author: lichao * @ Since: Oct 10,201 412: 02: 39 PM */public interface FlowMainService {/***** @ Description: apply for * @ Author: lichao * @ Since: Oct 10,201 43: 19: 07 PM * @ param applyable * @ return * @ throws Exception */public void applyFlow (Applyable applyable) throws Exception;/***** @ Description: Find the current flow information * @ Author: medees * @ Since: Oct 13,201 48: 56: 00 AM * @ param applyid application source * @ param applytype Application category * @ return */public FlowInfoMoving findNowMoving (Long applyid, Dictionary applyType);/***** @ Description: search for all the processes in a process in ascending order of creation time * @ Author: lichao * @ Since: Oct 13,201 41: 46: 54 PM * @ param applyid application source * @ param applytype Application category * @ return */public List <FlowInfoMoving> findAllMoving (Long applyid, Dictionary applyType ); /***** @ Description: Get all transformation conditions * @ Author: lichao * @ Since: Oct 13,201 44: 27: 41 PM * @ param nodeid id * @ return */public List <String> findNextTransition (Long nodeid);/***** @ Description: all users that can be reviewed by this node * @ Author: lichao * @ Since: Oct 14,201 410: 22: 50 AM * @ param nodeid node id * @ param applyid application source * @ param applyUserId applicant id * @ return */public List <User> findNextAppUser (Long nodeid, String transition, long applyUserId);/***** @ Description: query the approval process by page * @ Author: lichao * @ Since: Oct 14,201 41: 39: 50 PM * @ return */public Page <FlowInfoMoving> findMyMoving (Pageable pageRequest);/***** @ Description: Method for review * @ Author: lichao * @ Since: oct 15,201 42: 11: 18 PM * @ param moving * @ throws Exception if an audit error occurs, an Exception is thrown */public boolean approval (FlowInfoMoving moving) throws Exception; /***** @ Description: Find all the flows in a process * @ Author: lichao * @ Since: Oct 16,201 411: 04: 03 AM * @ param applyid * @ param applytype * @ return */public Page <FlowInfoMoving> findAllMoving (Long applyid, Long applytype, Pageable);/*** @ Description: apply again * @ Author: lichao * @ Since: Oct 17,201 41: 43: 03 PM * @ return */public void resetApply (Applyable applyable) throws Exception; /*** @ Description: whether to apply again * @ Author: lichao * @ Since: Oct 17,201 41: 43: 03 PM * @ return */public boolean isNeedReset (Long applyid, Dictionary dic );}