@@ -45,7 +45,7 @@
Loading
45 45
46 46
	final private JSON flowDefinition;
47 47
	
48 -
	private Map<String, FlowNode> nodeMap = new HashMap<>();
48 +
	private final Map<String, FlowNode> nodeMap = new HashMap<>();
49 49
	
50 50
	/**
51 51
	 * @param flowDefinition
@@ -128,7 +128,7 @@
Loading
128 128
		next.sort((o1, o2) -> {
129 129
			int p1 = ((FlowBranch) o1).getPriority();
130 130
			int p2 = ((FlowBranch) o2).getPriority();
131 -
			return p1 > p2 ? 1 : (p1 == p2 ? 0 : -1);
131 +
			return Integer.compare(p1, p2);
132 132
		});
133 133
		return next;
134 134
	}
@@ -143,6 +143,18 @@
Loading
143 143
		}
144 144
		throw new ApprovalException("无效节点 : " + nodeId);
145 145
	}
146 +
147 +
	/**
148 +
	 * 是否有审批人节点,没有审批人节点的无效
149 +
	 *
150 +
	 * @return
151 +
	 */
152 +
	public boolean hasApproverNode() {
153 +
		for (FlowNode node : nodeMap.values()) {
154 +
			if (node.getType().equals(FlowNode.TYPE_APPROVER)) return true;
155 +
		}
156 +
		return false;
157 +
	}
146 158
	
147 159
	/**
148 160
	 * @return

@@ -18,6 +18,7 @@
Loading
18 18
19 19
package com.rebuild.server.configuration;
20 20
21 +
import com.alibaba.fastjson.JSONObject;
21 22
import com.rebuild.server.business.approval.FlowParser;
22 23
23 24
/**
@@ -28,6 +29,8 @@
Loading
28 29
 */
29 30
public class FlowDefinition extends ConfigEntry {
30 31
	private static final long serialVersionUID = 9146239943240893998L;
32 +
33 +
	transient private FlowParser flowParser;
31 34
	
32 35
	/**
33 36
	 * @return
@@ -40,6 +43,17 @@
Loading
40 43
	 * @return
41 44
	 */
42 45
	public FlowParser createFlowParser() {
43 -
		return new FlowParser(getJSON("flowDefinition"));
46 +
		if (flowParser == null) {
47 +
			flowParser = new FlowParser(getJSON("flowDefinition"));
48 +
		}
49 +
		return flowParser;
50 +
	}
51 +
52 +
	/**
53 +
	 * @return
54 +
	 */
55 +
	public boolean isWorkable() {
56 +
		JSONObject def = (JSONObject) getJSON("flowDefinition");
57 +
		return def != null && createFlowParser().hasApproverNode();
44 58
	}
45 59
}

@@ -21,6 +21,7 @@
Loading
21 21
import com.rebuild.server.service.bizz.UserHelper;
22 22
23 23
import java.util.ArrayList;
24 +
import java.util.Date;
24 25
import java.util.List;
25 26
26 27
/**
@@ -33,6 +34,8 @@
Loading
33 34
34 35
	public static final RobotApprovalManager instance = new RobotApprovalManager();
35 36
	private RobotApprovalManager() {}
37 +
38 +
	private static final String CKEY_PREFIX = "RobotApprovalManager2-";
36 39
	
37 40
	/**
38 41
	 * 获取实体/记录流程状态
@@ -95,10 +98,10 @@
Loading
95 98
		// 过滤可用的
96 99
		List<FlowDefinition> workable = new ArrayList<>();
97 100
		for (FlowDefinition def : defs) {
98 -
			if (def.isDisabled() || def.getJSON("flowDefinition") == null) {
101 +
			if (def.isDisabled() || !def.isWorkable()) {
99 102
				continue;
100 103
			}
101 -
			
104 +
102 105
			FlowParser flowParser = def.createFlowParser();
103 106
			FlowNode root = flowParser.getNode("ROOT");  // 发起人节点
104 107
			
@@ -122,24 +125,24 @@
Loading
122 125
	 * @return
123 126
	 */
124 127
	public FlowDefinition[] getFlowDefinitions(Entity entity) {
125 -
		final String cKey = "RobotApprovalManager-" + entity.getName();
128 +
		final String cKey = CKEY_PREFIX + entity.getName();
126 129
		FlowDefinition[] defs = (FlowDefinition[]) Application.getCommonCache().getx(cKey);
127 130
		if (defs != null) {
128 131
			return defs;
129 132
		}
130 133
		
131 134
		Object[][] array = Application.createQueryNoFilter(
132 -
				"select flowDefinition,isDisabled,name,configId from RobotApprovalConfig where belongEntity = ?")
135 +
				"select flowDefinition,isDisabled,name,configId,modifiedOn from RobotApprovalConfig where belongEntity = ?")
133 136
				.setParameter(1, entity.getName())
134 137
				.array();
135 138
		
136 139
		List<FlowDefinition> list = new ArrayList<>();
137 140
		for (Object[] o : array) {
138 -
			FlowDefinition def = new FlowDefinition();
139 -
			def.set("flowDefinition", JSON.parseObject((String) o[0]));
140 -
			def.set("disabled", o[1]);
141 -
			def.set("name", o[2]);
142 -
			def.set("id", o[3]);
141 +
			FlowDefinition def = (FlowDefinition) new FlowDefinition()
142 +
					.set("flowDefinition", JSON.parseObject((String) o[0]))
143 +
					.set("disabled", o[1])
144 +
					.set("name", o[2])
145 +
					.set("id", o[3]);
143 146
			list.add(def);
144 147
		}
145 148
		
@@ -150,7 +153,7 @@
Loading
150 153
	
151 154
	@Override
152 155
	public void clean(Object entity) {
153 -
		final String cKey = "RobotApprovalManager-" + ((Entity) entity).getName();
156 +
		final String cKey = CKEY_PREFIX + ((Entity) entity).getName();
154 157
		Application.getCommonCache().evict(cKey);
155 158
	}
156 159
}

@@ -11,8 +11,10 @@
Loading
11 11
import org.apache.commons.lang.StringEscapeUtils;
12 12
import org.apache.commons.lang.StringUtils;
13 13
14 -
import java.text.SimpleDateFormat;
15 -
import java.util.*;
14 +
import java.util.Collections;
15 +
import java.util.Date;
16 +
import java.util.HashSet;
17 +
import java.util.Set;
16 18
import java.util.regex.Matcher;
17 19
import java.util.regex.Pattern;
18 20
Files Coverage
src/main/java/com/rebuild 57.88%
Project Totals (248 files) 57.88%
624.1
TRAVIS_OS_NAME=linux
oraclejdk8=
1
coverage:
2
  range: "40...90"
3
  round: down
4
  precision: 2
5
  
6
  status:
7
    project: yes
8
    patch: no
9
    changes: no
10

11
ignore:
12
  - ".github/.*"
13
  - ".vscode/.*"
14
  - ".setup/.*"
15
  - ".production/.*"
16
  - "src/test/.*"
17
  - "src/main/webapp/.*"
18
  - "src/main/java/com/rebuild/web/.*"
19
  - ".*/.*Exception.java"
Sunburst
The inner-most circle is the entire project, moving away from the center are folders then, finally, a single file. The size and color of each slice is representing the number of statements and the coverage, respectively.
Icicle
The top section represents the entire project. Proceeding with folders and finally individual files. The size and color of each slice is representing the number of statements and the coverage, respectively.
Grid
Each block represents a single file in the project. The size and color of each block is represented by the number of statements and the coverage, respectively.
Loading