PerfEvaObjectUtil.java 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653
  1. package com.kingdee.eas.custom.perfweb.utils;
  2. import com.kingdee.bos.BOSException;
  3. import com.kingdee.bos.Context;
  4. import com.kingdee.bos.metadata.entity.*;
  5. import com.kingdee.bos.metadata.query.util.CompareType;
  6. import com.kingdee.eas.base.message.util.StringUtil;
  7. import com.kingdee.eas.base.permission.IUser;
  8. import com.kingdee.eas.base.permission.UserCollection;
  9. import com.kingdee.eas.base.permission.UserFactory;
  10. import com.kingdee.eas.base.permission.UserInfo;
  11. import com.kingdee.eas.basedata.person.IPerson;
  12. import com.kingdee.eas.basedata.person.PersonCollection;
  13. import com.kingdee.eas.basedata.person.PersonFactory;
  14. import com.kingdee.eas.basedata.person.PersonInfo;
  15. import com.kingdee.shr.perfweb.app.base.evalplan.IPerfEvaObject;
  16. import com.kingdee.shr.perfweb.app.base.evalplan.ITargetNode;
  17. import com.kingdee.shr.perfweb.app.base.evalplan.PerfEvaObjectCollection;
  18. import com.kingdee.shr.perfweb.app.base.evalplan.PerfEvaObjectFactory;
  19. import com.kingdee.shr.perfweb.app.base.evalplan.PerfEvaObjectInfo;
  20. import com.kingdee.shr.perfweb.app.base.evalplan.TargetNodeCollection;
  21. import com.kingdee.shr.perfweb.app.base.evalplan.TargetNodeFactory;
  22. import com.kingdee.shr.perfweb.app.base.evalplan.TargetNodeInfo;
  23. import com.kingdee.shr.perfweb.app.base.evalrule.IWFNodeDef;
  24. import com.kingdee.shr.perfweb.app.base.evalrule.WFNodeDefCollection;
  25. import com.kingdee.shr.perfweb.util.PersonInchargeUtils;
  26. import com.kingdee.shr.perfweb.app.base.evalrule.WFNodeDefFactory;
  27. import com.kingdee.shr.perfweb.app.base.evalrule.WFNodeDefInfo;
  28. import com.kingdee.shr.perfweb.app.workflow.GradeTaskNodeInstCollection;
  29. import com.kingdee.shr.perfweb.app.workflow.GradeTaskNodeInstFactory;
  30. import com.kingdee.shr.perfweb.app.workflow.GradeTaskNodeInstInfo;
  31. import com.kingdee.shr.perfweb.app.workflow.IGradeTaskNodeInst;
  32. import org.apache.commons.lang3.StringUtils;
  33. import org.slf4j.Logger;
  34. import org.slf4j.LoggerFactory;
  35. import org.springframework.util.CollectionUtils;
  36. import java.util.HashMap;
  37. import java.util.HashSet;
  38. import java.util.LinkedHashSet;
  39. import java.util.Map;
  40. import java.util.Set;
  41. /**
  42. * 类名称: PerfPlanExecuteUtils
  43. * 功能描述: 考核对接工具类
  44. * 创建日期: 2026-06-11 10:01
  45. * 作 者: 青梧
  46. * 版 本: 1.0
  47. */
  48. public class PerfEvaObjectUtil {
  49. private static Logger logger = LoggerFactory.getLogger("com.kingdee.eas.custom.perfweb.utils.PerfEvaObjectUtils");
  50. /***
  51. *获取评分任务节点实例
  52. */
  53. public static GradeTaskNodeInstInfo getGradeTaskNodeInst(Context ctx, String evaObjId, String wfLevel) throws BOSException {
  54. FilterInfo filter = new FilterInfo();
  55. filter.getFilterItems().add(new FilterItemInfo("evaObj", evaObjId, CompareType.EQUALS));
  56. filter.getFilterItems().add(new FilterItemInfo("wfLevel", wfLevel, CompareType.EQUALS));
  57. EntityViewInfo evi = new EntityViewInfo();
  58. evi.setFilter(filter);
  59. SelectorItemCollection sic = new SelectorItemCollection();
  60. sic.add(new SelectorItemInfo("id"));
  61. sic.add(new SelectorItemInfo("nodeHandler.number"));
  62. sic.add(new SelectorItemInfo("nodeHandler.id"));
  63. evi.setSelector(sic);
  64. IGradeTaskNodeInst igradeTaskNodeInst = GradeTaskNodeInstFactory.getLocalInstance(ctx);
  65. GradeTaskNodeInstCollection coll = igradeTaskNodeInst.getGradeTaskNodeInstCollection(evi);
  66. if (coll == null || coll.isEmpty()) {
  67. return null;
  68. }
  69. return coll.get(0);
  70. }
  71. /**
  72. * 获取评分任务节点实例主键(flowId)
  73. */
  74. public static String getGradeTaskNodeInstId(Context ctx, String evaObjId, int wfLevel) {
  75. try {
  76. GradeTaskNodeInstInfo info = getGradeTaskNodeInst(ctx, evaObjId, String.valueOf(wfLevel));
  77. if (info != null && info.getId() != null) {
  78. return info.getId().toString();
  79. }
  80. } catch (BOSException e) {
  81. logger.error("getGradeTaskNodeInstId failed, evaObjId=" + evaObjId + ", wfLevel=" + wfLevel, e);
  82. }
  83. return null;
  84. }
  85. /**
  86. * 获取节点处理人工号
  87. */
  88. public static String getNodeHandlerNumber(GradeTaskNodeInstInfo info) {
  89. if (info != null && info.getNodeHandler() != null && StringUtils.isNotBlank(info.getNodeHandler().getNumber())) {
  90. return info.getNodeHandler().getNumber();
  91. }
  92. return null;
  93. }
  94. /**
  95. * 启动考核飞书专用:仅按「设置评分人」T_EVA_TargetNode 取处理人,不读 GradeTaskNodeInst。
  96. */
  97. public static void getBatchTargetNodeHandlersForEvaObj(Context ctx, Set<String> evaObjSet, Map<String, String> resultMap,
  98. Map<String, Set<String>> evaObjHandlerMap, Map<String, String> workFlowNameMap, String wfLevel) {
  99. if (CollectionUtils.isEmpty(evaObjSet)) {
  100. return;
  101. }
  102. try {
  103. int level = Integer.parseInt(wfLevel);
  104. if (level < 1) {
  105. logger.error("TargetNode 查评分人跳过,wfLevel无效: {}", wfLevel);
  106. return;
  107. }
  108. Set<String> allHandlerIdSet = new HashSet();
  109. Map<String, String> evaObjWorkFlowIdMap = loadEvaObjWorkFlowIdMap(ctx, evaObjSet, workFlowNameMap);
  110. for (String evaObjId : evaObjSet) {
  111. if (StringUtils.isBlank(evaObjId)) {
  112. continue;
  113. }
  114. String workFlowId = evaObjWorkFlowIdMap.get(evaObjId);
  115. if (StringUtils.isBlank(workFlowId)) {
  116. logger.error("TargetNode 查评分人跳过,未找到考核对象流程, evaObjId={}", evaObjId);
  117. continue;
  118. }
  119. Set<String> handlerNumbers = new LinkedHashSet<>();
  120. StringBuilder nameBuilder = new StringBuilder();
  121. resolveHandlersFromTargetNode(ctx, evaObjId, workFlowId, level, handlerNumbers, nameBuilder, allHandlerIdSet);
  122. if (handlerNumbers.isEmpty()) {
  123. logger.error("TargetNode 未配置评分人, evaObjId={}", evaObjId);
  124. continue;
  125. }
  126. String key = evaObjId + "$" + workFlowId;
  127. evaObjHandlerMap.put(key, handlerNumbers);
  128. if (nameBuilder.length() > 0) {
  129. resultMap.put(key, nameBuilder.toString());
  130. }
  131. logger.error("TargetNode 查评分人成功, evaObjId={}, handlers={}", evaObjId, handlerNumbers);
  132. }
  133. enrichHandlerDisplayNames(ctx, allHandlerIdSet, evaObjHandlerMap, resultMap);
  134. } catch (Exception e) {
  135. logger.error("getBatchTargetNodeHandlersForEvaObj failed", e);
  136. }
  137. }
  138. private static void enrichHandlerDisplayNames(Context ctx, Set<String> allHandlerIdSet,
  139. Map<String, Set<String>> evaObjHandlerMap, Map<String, String> resultMap) throws BOSException {
  140. if (CollectionUtils.isEmpty(allHandlerIdSet) || CollectionUtils.isEmpty(evaObjHandlerMap)) {
  141. return;
  142. }
  143. FilterInfo userFilterAll = new FilterInfo();
  144. userFilterAll.getFilterItems().add(new FilterItemInfo("person", allHandlerIdSet, CompareType.INCLUDE));
  145. userFilterAll.getFilterItems().add(new FilterItemInfo("isDelete", 0, CompareType.EQUALS));
  146. EntityViewInfo userEvi = new EntityViewInfo();
  147. SelectorItemCollection userSic = new SelectorItemCollection();
  148. userSic.add(new SelectorItemInfo("id"));
  149. userSic.add(new SelectorItemInfo("person.id"));
  150. userSic.add(new SelectorItemInfo("person.number"));
  151. userSic.add(new SelectorItemInfo("person.name"));
  152. userEvi.setSelector(userSic);
  153. userEvi.setFilter(userFilterAll);
  154. IUser iUser = UserFactory.getLocalInstance(ctx);
  155. UserCollection userColl = iUser.getUserCollection(userEvi);
  156. if (userColl == null || userColl.size() <= 0) {
  157. return;
  158. }
  159. Map<String, PersonInfo> umap = new HashMap();
  160. for (int i = 0; i < userColl.size(); ++i) {
  161. UserInfo userInfo = userColl.get(i);
  162. if (userInfo != null && userInfo.getPerson() != null) {
  163. PersonInfo person = userInfo.getPerson();
  164. if (!StringUtil.isEmpty(person.getNumber())) {
  165. umap.put(person.getNumber(), person);
  166. }
  167. }
  168. }
  169. for (Map.Entry<String, Set<String>> entry : evaObjHandlerMap.entrySet()) {
  170. String key = entry.getKey();
  171. Set<String> value = entry.getValue();
  172. if (StringUtils.isBlank(key) || CollectionUtils.isEmpty(value)) {
  173. continue;
  174. }
  175. StringBuilder sb = new StringBuilder();
  176. Set<String> waitDeleteIds = new HashSet();
  177. for (String pid : value) {
  178. PersonInfo personInfo = umap.get(pid);
  179. if (personInfo == null) {
  180. waitDeleteIds.add(pid);
  181. } else if (!StringUtil.isEmpty(personInfo.getName(ctx.getLocale()))) {
  182. sb.append(personInfo.getName()).append(",");
  183. }
  184. }
  185. if (!CollectionUtils.isEmpty(waitDeleteIds)) {
  186. value.removeAll(waitDeleteIds);
  187. }
  188. if (sb.length() > 0) {
  189. resultMap.put(key, sb.toString());
  190. }
  191. }
  192. for (Map.Entry<String, String> entry : resultMap.entrySet()) {
  193. if (!StringUtils.isEmpty(entry.getValue()) && entry.getValue().endsWith(",")) {
  194. entry.setValue(entry.getValue().substring(0, entry.getValue().length() - 1));
  195. }
  196. }
  197. }
  198. public static void getBatchCurrentNodeHandersForEvaObj(Context ctx, Set<String> evaObjSet, Map<String, String> resultMap, Map<String, Set<String>> evaObjHandlerMap, Map<String, Set<String>> workNodeNameMap, Map<String, String> workFlowNameMap, String wfLevel) {
  199. FilterInfo filter = new FilterInfo();
  200. filter.getFilterItems().add(new FilterItemInfo("evaObj.id", evaObjSet, CompareType.INCLUDE));
  201. // filter.getFilterItems().add(new FilterItemInfo("isEffective", "1", CompareType.EQUALS));
  202. // filter.getFilterItems().add(new FilterItemInfo("taskStatus", "2", CompareType.NOTEQUALS));
  203. // filter.getFilterItems().add(new FilterItemInfo("canEdit", "1", CompareType.EQUALS));
  204. // filter.getFilterItems().add(new FilterItemInfo("wfNode.workFlow.id", workFlowSet, CompareType.INCLUDE));
  205. // filter.getFilterItems().add(new FilterItemInfo("isRetain", "0", CompareType.EQUALS));
  206. filter.getFilterItems().add(new FilterItemInfo("wfLevel", wfLevel, CompareType.EQUALS));
  207. EntityViewInfo evi = new EntityViewInfo();
  208. SelectorItemCollection sic = new SelectorItemCollection();
  209. sic.add(new SelectorItemInfo("id"));
  210. sic.add(new SelectorItemInfo("evaObj.id"));
  211. sic.add(new SelectorItemInfo("nodeHandlerName"));
  212. sic.add(new SelectorItemInfo("nodeHandler.id"));
  213. sic.add(new SelectorItemInfo("nodeHandler.number"));
  214. sic.add(new SelectorItemInfo("wfNode.workFlow.*"));
  215. sic.add(new SelectorItemInfo("wfNode.*"));
  216. sic.add("wfNode.*");
  217. evi.setFilter(filter);
  218. evi.setSelector(sic);
  219. Set<String> allHandlerIdSet = new HashSet();
  220. Set<String> allWorkNodeIdSet = new HashSet();
  221. try {
  222. IGradeTaskNodeInst igradeTaskNodeInst = GradeTaskNodeInstFactory.getLocalInstance(ctx);
  223. GradeTaskNodeInstCollection coll = igradeTaskNodeInst.getGradeTaskNodeInstCollection(evi);
  224. if (coll != null && coll.size() > 0) {
  225. Set<String> workNodeIdSet = null;
  226. for (int i = 0; i < coll.size(); ++i) {
  227. GradeTaskNodeInstInfo info = coll.get(i);
  228. if (null != info.getNodeHandler() && null != info.getNodeHandler().getId()) {
  229. allHandlerIdSet.add(info.getNodeHandler().getId().toString());
  230. // 同时取工号用于后续匹配
  231. if (null != info.getNodeHandler().getNumber()) {
  232. allHandlerIdSet.add(info.getNodeHandler().getNumber());
  233. }
  234. }
  235. String evaObj = info.getEvaObj().getId().toString();
  236. String key = evaObj + "$" + info.getWfNode().getWorkflow().getId().toString();
  237. // 填充 workFlowId → workFlowName(wfNode.workFlow.* 已在 selector 中)
  238. if (workFlowNameMap != null && info.getWfNode().getWorkflow() != null) {
  239. String wfId = info.getWfNode().getWorkflow().getId().toString();
  240. if (!workFlowNameMap.containsKey(wfId)) {
  241. String wfName = info.getWfNode().getWorkflow().getName();
  242. if (StringUtils.isNotBlank(wfName)) {
  243. workFlowNameMap.put(wfId, wfName);
  244. }
  245. }
  246. }
  247. if (info.getWfNode() != null && info.getWfNode().getId() != null) {
  248. workNodeIdSet = (Set) workNodeNameMap.get(key);
  249. if (CollectionUtils.isEmpty(workNodeIdSet)) {
  250. workNodeIdSet = new HashSet();
  251. }
  252. workNodeIdSet.add(info.getWfNode().getId().toString());
  253. allWorkNodeIdSet.add(info.getWfNode().getId().toString());
  254. }
  255. String handlers = (String) resultMap.get(key);
  256. Set<String> handlerIdSet = (Set) evaObjHandlerMap.get(key);
  257. if (CollectionUtils.isEmpty(handlerIdSet)) {
  258. handlerIdSet = new HashSet(50);
  259. if (null != info.getNodeHandler() && null != info.getNodeHandler().getNumber()) {
  260. // 存工号而非ID,飞书接口接收人工号
  261. handlerIdSet.add(info.getNodeHandler().getNumber());
  262. }
  263. } else if (null != info.getNodeHandler() && null != info.getNodeHandler().getNumber()) {
  264. handlerIdSet.add(info.getNodeHandler().getNumber());
  265. }
  266. StringBuffer sb = null;
  267. if (handlers == null) {
  268. sb = new StringBuffer();
  269. } else {
  270. sb = new StringBuffer(handlers);
  271. }
  272. if (null != info.getNodeHandler() && !StringUtils.isEmpty(info.getNodeHandler().getName(ctx.getLocale()))) {
  273. sb.append(info.getNodeHandler().getName(ctx.getLocale())).append(",");
  274. }
  275. resultMap.put(key, sb.toString());
  276. evaObjHandlerMap.put(key, handlerIdSet);
  277. workNodeNameMap.put(key, workNodeIdSet);
  278. }
  279. for (Map.Entry<String, String> entry : resultMap.entrySet()) {
  280. if (!StringUtils.isEmpty((CharSequence) entry.getValue()) && ((String) entry.getValue()).lastIndexOf(",") == ((String) entry.getValue()).length() - 1) {
  281. entry.setValue(((String) entry.getValue()).substring(0, ((String) entry.getValue()).length() - 1));
  282. }
  283. }
  284. if (!CollectionUtils.isEmpty(allWorkNodeIdSet)) {
  285. processNodeNameMap(allWorkNodeIdSet, workNodeNameMap, ctx);
  286. }
  287. }
  288. // 1) 节点实例(GradeTaskNodeInst)已有处理人 → 不再查评分人
  289. // 2) 无处理人 → 查 T_EVA_TargetNode(设置评分人)
  290. // 3) 仍无且一级 → 直接上级
  291. Set<String> needFallback = collectEvaObjWithoutHandler(evaObjSet, evaObjHandlerMap);
  292. System.out.println("needFallback---" + needFallback);
  293. if (!needFallback.isEmpty()) {
  294. fillWorkflowHandlerWhenNoNodeHandler(ctx, needFallback, resultMap, evaObjHandlerMap, workFlowNameMap, allHandlerIdSet, wfLevel);
  295. }
  296. enrichHandlerDisplayNames(ctx, allHandlerIdSet, evaObjHandlerMap, resultMap);
  297. } catch (BOSException e) {
  298. e.printStackTrace();
  299. logger.error("BOSException: ", e);
  300. }
  301. }
  302. /**
  303. * 节点实例未查到处理人时的兜底(仅处理 needFallback 中的考核对象)。
  304. * 1) T_EVA_TargetNode(设置评分人,多条取一条)
  305. * 2) 仍无且一级 → 职位直接上级
  306. */
  307. private static void fillWorkflowHandlerWhenNoNodeHandler(Context ctx, Set<String> needFallback, Map<String, String> resultMap, Map<String, Set<String>> evaObjHandlerMap, Map<String, String> workFlowNameMap, Set<String> allHandlerIdSet, String wfLevel) throws BOSException {
  308. if (CollectionUtils.isEmpty(needFallback)) {
  309. return;
  310. }
  311. int level;
  312. try {
  313. level = Integer.parseInt(wfLevel);
  314. } catch (NumberFormatException e) {
  315. logger.error("评分人兜底跳过,wfLevel无效: {}", wfLevel);
  316. return;
  317. }
  318. if (level < 1) {
  319. return;
  320. }
  321. logger.error("节点实例无处理人,查 T_EVA_TargetNode, wfLevel={}, evaObjIds={}", wfLevel, needFallback);
  322. System.out.println("节点实例无处理人,查 T_EVA_TargetNode, wfLevel={" + wfLevel + "}, evaObjIds={" + needFallback + "}");
  323. Map<String, String> evaObjWorkFlowIdMap = loadEvaObjWorkFlowIdMap(ctx, needFallback, workFlowNameMap);
  324. for (String evaObjId : needFallback) {
  325. String workFlowId = evaObjWorkFlowIdMap.get(evaObjId);
  326. if (StringUtils.isBlank(workFlowId)) {
  327. logger.error("TargetNode 兜底跳过,未找到考核对象流程, evaObjId={}", evaObjId);
  328. continue;
  329. }
  330. Set<String> handlerNumbers = new LinkedHashSet<>();
  331. StringBuilder nameBuilder = new StringBuilder();
  332. // 1) 设置评分人:T_EVA_TargetNode WHERE FEvaObjID=? AND FWfNodeID=?
  333. resolveHandlersFromTargetNode(ctx, evaObjId, workFlowId, level, handlerNumbers, nameBuilder, allHandlerIdSet);
  334. // 2) TargetNode 仍无,一级使用直接上级
  335. if (handlerNumbers.isEmpty() && level == 1) {
  336. logger.error("TargetNode 无评分人,使用直接上级兜底, evaObjId={}", evaObjId);
  337. fillDirectSuperiorFromPosition(ctx, evaObjId, handlerNumbers, nameBuilder, allHandlerIdSet);
  338. }
  339. if (handlerNumbers.isEmpty()) {
  340. logger.error("评分人兜底后仍为空, evaObjId={}, workFlowId={}", evaObjId, workFlowId);
  341. continue;
  342. }
  343. String key = evaObjId + "$" + workFlowId;
  344. evaObjHandlerMap.put(key, handlerNumbers);
  345. if (nameBuilder.length() > 0) {
  346. resultMap.put(key, nameBuilder.toString());
  347. }
  348. logger.error("评分人兜底成功, evaObjId={}, handlers={}", evaObjId, handlerNumbers);
  349. }
  350. }
  351. /**
  352. * 按 WFNodeDef 逐级查 T_EVA_TargetNode:evaObj.id + wfNode.id(WFNodeDef 主键)。
  353. * 等价 SQL:WHERE FEvaObjID = ? AND FWfNodeID = ?
  354. */
  355. private static void resolveHandlersFromTargetNode(Context ctx, String evaObjId, String workFlowId, int level, Set<String> handlerNumbers, StringBuilder nameBuilder, Set<String> allHandlerIdSet) {
  356. WFNodeDefCollection nodeDefs = loadWfNodeDefsForLevel(ctx, workFlowId, level);
  357. if (nodeDefs != null && !nodeDefs.isEmpty()) {
  358. for (int i = 0; i < nodeDefs.size(); i++) {
  359. WFNodeDefInfo nodeDef = nodeDefs.get(i);
  360. if (nodeDef == null || nodeDef.getId() == null) {
  361. continue;
  362. }
  363. extractTargetNodeHandlers(ctx, evaObjId, nodeDef.getId().toString(), handlerNumbers, nameBuilder, allHandlerIdSet);
  364. if (!handlerNumbers.isEmpty()) {
  365. return;
  366. }
  367. }
  368. return;
  369. }
  370. // 查不到 WFNodeDef 时,按考核对象查全部 TargetNode 行
  371. logger.error("未查到 WFNodeDef,按 evaObj 查全部 TargetNode, evaObjId={}, workFlowId={}, level={}", evaObjId, workFlowId, level);
  372. System.out.println("未查到 WFNodeDef,按 evaObj 查全部 TargetNode, evaObjId={" + evaObjId + "}, workFlowId={" + workFlowId + "}, level={" + level + "}");
  373. extractAllTargetNodeHandlersByEvaObj(ctx, evaObjId, handlerNumbers, nameBuilder, allHandlerIdSet);
  374. }
  375. /**
  376. * 仅按考核对象查 T_EVA_TargetNode(不限定 wfNode)
  377. */
  378. private static void extractAllTargetNodeHandlersByEvaObj(Context ctx, String evaObjId, Set<String> handlerNumbers, StringBuilder nameBuilder, Set<String> allHandlerIdSet) {
  379. try {
  380. FilterInfo filter = new FilterInfo();
  381. filter.getFilterItems().add(new FilterItemInfo("evaObj.id", evaObjId, CompareType.EQUALS));
  382. EntityViewInfo evi = new EntityViewInfo();
  383. evi.setFilter(filter);
  384. SelectorItemCollection sic = new SelectorItemCollection();
  385. sic.add(new SelectorItemInfo("personNumber"));
  386. sic.add(new SelectorItemInfo("personName"));
  387. evi.setSelector(sic);
  388. ITargetNode iTargetNode = TargetNodeFactory.getLocalInstance(ctx);
  389. TargetNodeCollection coll = iTargetNode.getTargetNodeCollection(evi);
  390. if (coll == null || coll.isEmpty()) {
  391. return;
  392. }
  393. for (int i = 0; i < coll.size(); i++) {
  394. TargetNodeInfo info = coll.get(i);
  395. if (info == null || StringUtils.isBlank(info.getPersonNumber())) {
  396. continue;
  397. }
  398. appendHandler(info.getPersonNumber(), info.getPersonName(), handlerNumbers, nameBuilder, allHandlerIdSet);
  399. return;
  400. }
  401. } catch (BOSException e) {
  402. logger.error("按 evaObj 查 TargetNode 失败, evaObjId={}", evaObjId, e);
  403. }
  404. }
  405. private static WFNodeDefCollection loadWfNodeDefsForLevel(Context ctx, String workFlowId, int level) {
  406. try {
  407. FilterInfo filter = new FilterInfo();
  408. filter.getFilterItems().add(new FilterItemInfo("workflow.id", workFlowId, CompareType.EQUALS));
  409. filter.getFilterItems().add(new FilterItemInfo("level", level, CompareType.EQUALS));
  410. EntityViewInfo evi = new EntityViewInfo();
  411. evi.setFilter(filter);
  412. SelectorItemCollection sic = new SelectorItemCollection();
  413. sic.add(new SelectorItemInfo("id"));
  414. sic.add(new SelectorItemInfo("level"));
  415. sic.add(new SelectorItemInfo("nodeSeq"));
  416. sic.add(new SelectorItemInfo("nodeName"));
  417. sic.add(new SelectorItemInfo("nodeHandler"));
  418. evi.setSelector(sic);
  419. SorterItemCollection sorter = new SorterItemCollection();
  420. sorter.add(new SorterItemInfo("nodeSeq"));
  421. evi.setSorter(sorter);
  422. IWFNodeDef iwfNodeDef = WFNodeDefFactory.getLocalInstance(ctx);
  423. return iwfNodeDef.getWFNodeDefCollection(evi);
  424. } catch (BOSException e) {
  425. logger.error("查询 WFNodeDef 失败, workFlowId={}, level={}", workFlowId, level, e);
  426. return null;
  427. }
  428. }
  429. /**
  430. * T_EVA_TargetNode:evaObj + wfNodeId;同一节点多指标多行时,取第一条有效评分人
  431. */
  432. private static void extractTargetNodeHandlers(Context ctx, String evaObjId, String wfNodeId, Set<String> handlerNumbers, StringBuilder nameBuilder, Set<String> allHandlerIdSet) {
  433. try {
  434. FilterInfo filter = new FilterInfo();
  435. filter.getFilterItems().add(new FilterItemInfo("evaObj.id", evaObjId, CompareType.EQUALS));
  436. filter.getFilterItems().add(new FilterItemInfo("wfNode.id", wfNodeId, CompareType.EQUALS));
  437. EntityViewInfo evi = new EntityViewInfo();
  438. evi.setFilter(filter);
  439. SelectorItemCollection sic = new SelectorItemCollection();
  440. sic.add(new SelectorItemInfo("personNumber"));
  441. sic.add(new SelectorItemInfo("personName"));
  442. evi.setSelector(sic);
  443. ITargetNode iTargetNode = TargetNodeFactory.getLocalInstance(ctx);
  444. TargetNodeCollection coll = iTargetNode.getTargetNodeCollection(evi);
  445. if (coll == null || coll.isEmpty()) {
  446. return;
  447. }
  448. for (int i = 0; i < coll.size(); i++) {
  449. TargetNodeInfo info = coll.get(i);
  450. if (info == null || StringUtils.isBlank(info.getPersonNumber())) {
  451. continue;
  452. }
  453. appendHandler(info.getPersonNumber(), info.getPersonName(), handlerNumbers, nameBuilder, allHandlerIdSet);
  454. return;
  455. }
  456. } catch (BOSException e) {
  457. logger.error("TargetNode 查询失败, evaObjId={}, wfNodeId={}", evaObjId, wfNodeId, e);
  458. }
  459. }
  460. private static void appendHandler(String personNumber, String personName, Set<String> handlerNumbers, StringBuilder nameBuilder, Set<String> allHandlerIdSet) {
  461. if (StringUtils.isNotBlank(personNumber)) {
  462. handlerNumbers.add(personNumber);
  463. allHandlerIdSet.add(personNumber);
  464. }
  465. if (StringUtils.isNotBlank(personName)) {
  466. if (nameBuilder.length() > 0) {
  467. nameBuilder.append(",");
  468. }
  469. nameBuilder.append(personName);
  470. }
  471. }
  472. private static void fillDirectSuperiorFromPosition(Context ctx, String evaObjId, Set<String> handlerNumbers, StringBuilder nameBuilder, Set<String> allHandlerIdSet) throws BOSException {
  473. Set<String> singleEvaObj = new HashSet<>();
  474. singleEvaObj.add(evaObjId);
  475. Map<String, Set<String>> superiorPersonIdMap = PersonInchargeUtils.getRelaPersonInchargeByids(ctx, singleEvaObj);
  476. if (superiorPersonIdMap == null || CollectionUtils.isEmpty(superiorPersonIdMap.get(evaObjId))) {
  477. return;
  478. }
  479. Map<String, PersonInfo> personById = loadPersonByIds(ctx, superiorPersonIdMap.get(evaObjId));
  480. for (String personId : superiorPersonIdMap.get(evaObjId)) {
  481. PersonInfo person = personById.get(personId);
  482. if (person == null || StringUtils.isBlank(person.getNumber())) {
  483. continue;
  484. }
  485. handlerNumbers.add(person.getNumber());
  486. allHandlerIdSet.add(person.getNumber());
  487. allHandlerIdSet.add(personId);
  488. if (!StringUtil.isEmpty(person.getName(ctx.getLocale()))) {
  489. if (nameBuilder.length() > 0) {
  490. nameBuilder.append(",");
  491. }
  492. nameBuilder.append(person.getName(ctx.getLocale()));
  493. }
  494. }
  495. }
  496. private static Set<String> collectEvaObjWithoutHandler(Set<String> evaObjSet, Map<String, Set<String>> evaObjHandlerMap) {
  497. Set<String> needFallback = new HashSet<>();
  498. for (String evaObjId : evaObjSet) {
  499. if (StringUtils.isBlank(evaObjId)) {
  500. continue;
  501. }
  502. String prefix = evaObjId + "$";
  503. boolean hasHandler = false;
  504. if (evaObjHandlerMap != null) {
  505. for (Map.Entry<String, Set<String>> entry : evaObjHandlerMap.entrySet()) {
  506. if (entry.getKey() != null && entry.getKey().startsWith(prefix) && !CollectionUtils.isEmpty(entry.getValue())) {
  507. hasHandler = true;
  508. break;
  509. }
  510. }
  511. }
  512. if (!hasHandler) {
  513. needFallback.add(evaObjId);
  514. }
  515. }
  516. return needFallback;
  517. }
  518. private static Map<String, String> loadEvaObjWorkFlowIdMap(Context ctx, Set<String> evaObjIds, Map<String, String> workFlowNameMap) throws BOSException {
  519. Map<String, String> result = new HashMap<>();
  520. FilterInfo filter = new FilterInfo();
  521. filter.getFilterItems().add(new FilterItemInfo("id", evaObjIds, CompareType.INCLUDE));
  522. EntityViewInfo evi = new EntityViewInfo();
  523. evi.setFilter(filter);
  524. SelectorItemCollection sic = new SelectorItemCollection();
  525. sic.add(new SelectorItemInfo("id"));
  526. sic.add(new SelectorItemInfo("workFlow.id"));
  527. sic.add(new SelectorItemInfo("workFlow.name"));
  528. evi.setSelector(sic);
  529. IPerfEvaObject iPerfEvaObject = PerfEvaObjectFactory.getLocalInstance(ctx);
  530. PerfEvaObjectCollection coll = iPerfEvaObject.getPerfEvaObjectCollection(evi);
  531. if (coll == null || coll.isEmpty()) {
  532. return result;
  533. }
  534. for (int i = 0; i < coll.size(); i++) {
  535. PerfEvaObjectInfo info = coll.get(i);
  536. if (info == null || info.getId() == null || info.getWorkFlow() == null || info.getWorkFlow().getId() == null) {
  537. continue;
  538. }
  539. String evaObjId = info.getId().toString();
  540. String workFlowId = info.getWorkFlow().getId().toString();
  541. result.put(evaObjId, workFlowId);
  542. if (workFlowNameMap != null && !workFlowNameMap.containsKey(workFlowId)) {
  543. String wfName = info.getWorkFlow().getName();
  544. if (StringUtils.isNotBlank(wfName)) {
  545. workFlowNameMap.put(workFlowId, wfName);
  546. }
  547. }
  548. }
  549. return result;
  550. }
  551. private static Map<String, PersonInfo> loadPersonByIds(Context ctx, Set<String> personIds) throws BOSException {
  552. Map<String, PersonInfo> result = new HashMap<>();
  553. if (CollectionUtils.isEmpty(personIds)) {
  554. return result;
  555. }
  556. FilterInfo filter = new FilterInfo();
  557. filter.getFilterItems().add(new FilterItemInfo("id", personIds, CompareType.INCLUDE));
  558. EntityViewInfo evi = new EntityViewInfo();
  559. evi.setFilter(filter);
  560. SelectorItemCollection sic = new SelectorItemCollection();
  561. sic.add(new SelectorItemInfo("id"));
  562. sic.add(new SelectorItemInfo("number"));
  563. sic.add(new SelectorItemInfo("name"));
  564. evi.setSelector(sic);
  565. IPerson iPerson = PersonFactory.getLocalInstance(ctx);
  566. PersonCollection coll = iPerson.getPersonCollection(evi);
  567. if (coll == null || coll.isEmpty()) {
  568. return result;
  569. }
  570. for (int i = 0; i < coll.size(); i++) {
  571. PersonInfo person = coll.get(i);
  572. if (person != null && person.getId() != null) {
  573. result.put(person.getId().toString(), person);
  574. }
  575. }
  576. return result;
  577. }
  578. private static void processNodeNameMap(Set<String> allWorkNodeIdSet, Map<String, Set<String>> workNodeNameMap, Context ctx) throws BOSException {
  579. FilterInfo nodeFilter = new FilterInfo();
  580. nodeFilter.getFilterItems().add(new FilterItemInfo("id", allWorkNodeIdSet, CompareType.INCLUDE));
  581. EntityViewInfo nodeEvi = new EntityViewInfo();
  582. SelectorItemCollection nodeSelector = new SelectorItemCollection();
  583. nodeSelector.add(new SelectorItemInfo("id"));
  584. nodeSelector.add(new SelectorItemInfo("nodeName"));
  585. nodeEvi.setFilter(nodeFilter);
  586. nodeEvi.setSelector(nodeSelector);
  587. WFNodeDefCollection nodeCollection = WFNodeDefFactory.getLocalInstance(ctx).getWFNodeDefCollection(nodeEvi);
  588. Map<String, String> nodeNameMap = new HashMap();
  589. int index = 0;
  590. for (int size = nodeCollection.size(); index < size; ++index) {
  591. WFNodeDefInfo info = nodeCollection.get(index);
  592. nodeNameMap.put(info.getId().toString(), info.getNodeName());
  593. }
  594. for (Map.Entry<String, Set<String>> entry : workNodeNameMap.entrySet()) {
  595. Set<String> nodeIdSet = (Set) entry.getValue();
  596. Set<String> newSet = new HashSet();
  597. for (String nodeId : nodeIdSet) {
  598. if (nodeNameMap.containsKey(nodeId)) {
  599. newSet.add(nodeNameMap.get(nodeId));
  600. }
  601. }
  602. if (!CollectionUtils.isEmpty(newSet)) {
  603. entry.setValue(newSet);
  604. }
  605. }
  606. }
  607. }