DataSetExecutor.java 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
  1. package jnpf.base.util.dataSet;
  2. import jnpf.base.ActionResult;
  3. import jnpf.base.entity.DictionaryDataEntity;
  4. import jnpf.base.model.dataset.DataSetConfig;
  5. import jnpf.base.model.dataset.DataSetOptions;
  6. import jnpf.base.model.dataset.DataSetSwapModel;
  7. import jnpf.base.service.DataInterfaceService;
  8. import jnpf.base.service.DictionaryDataService;
  9. import jnpf.permission.service.*;
  10. import jnpf.util.*;
  11. import jnpf.util.data.DataSourceContextHolder;
  12. import jnpf.util.visiual.DataTypeConst;
  13. import lombok.Data;
  14. import lombok.extern.slf4j.Slf4j;
  15. import org.apache.commons.collections4.MapUtils;
  16. import org.springframework.beans.factory.annotation.Autowired;
  17. import org.springframework.stereotype.Component;
  18. import java.util.*;
  19. import java.util.concurrent.CountDownLatch;
  20. import java.util.stream.Collectors;
  21. /**
  22. * 数据集数据转换多线程
  23. *
  24. * @author JNPF开发平台组
  25. * @version v5.0.0
  26. * @copyright 引迈信息技术有限公司
  27. * @date 2024/7/15 16:45:09
  28. */
  29. @Slf4j
  30. @Component
  31. public class DataSetExecutor {
  32. @Autowired
  33. private RedisUtil redisUtil;
  34. @Autowired
  35. private UserService userApi;
  36. @Autowired
  37. private OrganizeService organizeApi;
  38. @Autowired
  39. private PositionService positionApi;
  40. @Autowired
  41. private RoleService roleApi;
  42. @Autowired
  43. private GroupService groupApi;
  44. @Autowired
  45. private DictionaryDataService dictionaryDataApi;
  46. @Autowired
  47. private DataInterfaceService dataInterFaceApi;
  48. private String tenantId = "";
  49. private static long DEFAULT_CACHE_TIME = 60 * 5;
  50. /**
  51. * 添加多线程
  52. */
  53. public void executorRedis(Map<String, Object> localCache, String printId, List<DataSetSwapModel> swapList, Map<String, Object> map) {
  54. tenantId = Optional.ofNullable(DataSourceContextHolder.getDatasourceId()).orElse("");
  55. Map<String, OateSetExParam> listExecutor = new HashMap<>();
  56. if (MapUtils.isNotEmpty(map)) {
  57. for (String key : map.keySet()) {
  58. if (Objects.isNull(map.get(key))) continue;
  59. List<Map<String, Object>> list = (List<Map<String, Object>>) map.get(key);
  60. boolean needOrg = false, needDep = false, needPos = false, needUser = false, needRole = false, needGroup = false;
  61. for (Map<String, Object> item : list) {
  62. for (DataSetSwapModel model : swapList) {
  63. String field = model.getField();
  64. String type = model.getType();
  65. if(StringUtil.isEmpty(field) || StringUtil.isEmpty(type)) continue;
  66. String[] fields = field.split("\\.");
  67. DataSetConfig config = model.getConfig();
  68. if (!key.equals(fields[0]) || item.get(fields[1]) == null || "".equals(item.get(fields[1]))) {
  69. continue;
  70. }
  71. String redisKey;
  72. switch (type) {
  73. case DataSetConstant.KEY_ORG:
  74. needOrg = true;
  75. break;
  76. case DataSetConstant.KEY_DEP:
  77. needDep = true;
  78. break;
  79. case DataSetConstant.KEY_POS:
  80. needPos = true;
  81. break;
  82. case DataSetConstant.KEY_USER:
  83. needUser = true;
  84. break;
  85. case DataSetConstant.KEY_ROLE:
  86. needRole = true;
  87. break;
  88. case DataSetConstant.KEY_GROUP:
  89. needGroup = true;
  90. break;
  91. case DataSetConstant.KEY_USERS:
  92. needOrg = true;
  93. needDep = true;
  94. needPos = true;
  95. needUser = true;
  96. needRole = true;
  97. needGroup = true;
  98. break;
  99. case DataSetConstant.KEY_SELECT:
  100. if (DataTypeConst.STATIC.equals(config.getDataType())) {
  101. redisKey = String.format("%s-%s-%s", printId, field, DataTypeConst.STATIC);
  102. if (!localCache.containsKey(redisKey)) {
  103. listExecutor.putIfAbsent(redisKey, new OateSetExParam(redisKey, DataSetConstant.KEY_SELECT, null, config));
  104. }
  105. }
  106. if (DataTypeConst.DICTIONARY.equals(config.getDataType())) {
  107. redisKey = String.format("%s-%s-%s", tenantId, DataTypeConst.DICTIONARY, model.getConfig().getDictionaryType());
  108. if (!localCache.containsKey(redisKey)) {
  109. listExecutor.putIfAbsent(redisKey, new OateSetExParam(redisKey, DataSetConstant.KEY_SELECT, null, config));
  110. }
  111. }
  112. if (DataTypeConst.DYNAMIC.equals(config.getDataType())) {
  113. redisKey = String.format("%s-%s-%s", tenantId, DataTypeConst.DYNAMIC, model.getConfig().getPropsUrl());
  114. if (!localCache.containsKey(redisKey)) {
  115. listExecutor.putIfAbsent(redisKey, new OateSetExParam(redisKey, DataSetConstant.KEY_SELECT, null, config));
  116. }
  117. }
  118. needGroup = true;
  119. break;
  120. default:
  121. break;
  122. }
  123. }
  124. }
  125. //添加系统缓存
  126. Map<String, String> reidsKeyMap = new LinkedHashMap<>();
  127. if (needOrg) reidsKeyMap.put(tenantId + CacheKeyUtil.SYS_ORG_Tree, DataSetConstant.KEY_ORG);
  128. if (needDep) reidsKeyMap.put(tenantId + CacheKeyUtil.SYS_DEP, DataSetConstant.KEY_DEP);
  129. if (needPos) reidsKeyMap.put(tenantId + CacheKeyUtil.SYS_POS, DataSetConstant.KEY_POS);
  130. if (needUser) reidsKeyMap.put(tenantId + CacheKeyUtil.SYS_USER, DataSetConstant.KEY_USER);
  131. if (needRole) reidsKeyMap.put(tenantId + CacheKeyUtil.SYS_ROLE, DataSetConstant.KEY_ROLE);
  132. if (needGroup) reidsKeyMap.put(tenantId + CacheKeyUtil.SYS_GROUP, DataSetConstant.KEY_GROUP);
  133. for (String redisKey : reidsKeyMap.keySet()) {
  134. if (!localCache.containsKey(redisKey)) {
  135. listExecutor.putIfAbsent(redisKey, new OateSetExParam(redisKey, reidsKeyMap.get(redisKey), null, null));
  136. }
  137. }
  138. }
  139. //执行多线程方法
  140. if (!listExecutor.isEmpty()) {
  141. this.execute(localCache, listExecutor);
  142. }
  143. }
  144. }
  145. /**
  146. * 执行多线程
  147. */
  148. private void execute(Map<String, Object> localCache, Map<String, OateSetExParam> listExecutor) {
  149. CountDownLatch countDownLatch = new CountDownLatch(listExecutor.size());
  150. for (String key : listExecutor.keySet()) {
  151. OateSetExParam item = listExecutor.get(key);
  152. String redisKey = item.getRedisKey();
  153. ThreadPoolExecutorUtil.getExecutor().execute(() -> {
  154. try {
  155. switch (item.getType()) {
  156. case DataSetConstant.KEY_USER:
  157. //人员
  158. Map<String, Object> userMap;
  159. if (redisUtil.exists(redisKey)) {
  160. userMap = redisUtil.getMap(redisKey);
  161. userMap = Optional.ofNullable(userMap).orElse(new HashMap<>(20));
  162. } else {
  163. userMap = userApi.getUserMap();
  164. if (DataSetSwapUtil.NEEDCACHE_SYS) {
  165. redisUtil.insert(redisKey, userMap, DEFAULT_CACHE_TIME);
  166. }
  167. }
  168. localCache.put(CacheKeyUtil.SYS_USER, userMap);
  169. break;
  170. case DataSetConstant.KEY_ORG:
  171. Map<String, Object> orgMap;
  172. if (redisUtil.exists(redisKey)) {
  173. orgMap = redisUtil.getMap(redisKey);
  174. orgMap = Optional.ofNullable(orgMap).orElse(new HashMap<>(20));
  175. } else {
  176. orgMap = organizeApi.getAllOrgsTreeName();
  177. if (DataSetSwapUtil.NEEDCACHE_SYS) {
  178. redisUtil.insert(redisKey, orgMap, DEFAULT_CACHE_TIME);
  179. }
  180. }
  181. localCache.put(CacheKeyUtil.SYS_ORG_Tree, orgMap);
  182. break;
  183. case DataSetConstant.KEY_DEP:
  184. Map<String, Object> depMap;
  185. if (redisUtil.exists(redisKey)) {
  186. depMap = redisUtil.getMap(redisKey);
  187. depMap = Optional.ofNullable(depMap).orElse(new HashMap<>(20));
  188. } else {
  189. depMap = organizeApi.getOrgMap();
  190. if (DataSetSwapUtil.NEEDCACHE_SYS) {
  191. redisUtil.insert(redisKey, depMap, DEFAULT_CACHE_TIME);
  192. }
  193. }
  194. localCache.put(CacheKeyUtil.SYS_DEP, depMap);
  195. break;
  196. case DataSetConstant.KEY_POS:
  197. Map<String, String> posMap;
  198. if (redisUtil.exists(redisKey)) {
  199. posMap = redisUtil.getMap(redisKey);
  200. posMap = Optional.ofNullable(posMap).orElse(new HashMap<>(20));
  201. } else {
  202. posMap = positionApi.getPosFullNameMap();
  203. if (DataSetSwapUtil.NEEDCACHE_SYS) {
  204. redisUtil.insert(redisKey, posMap, DEFAULT_CACHE_TIME);
  205. }
  206. }
  207. localCache.put(CacheKeyUtil.SYS_POS, posMap);
  208. break;
  209. case DataSetConstant.KEY_ROLE:
  210. Map<String, Object> roleMap;
  211. if (redisUtil.exists(redisKey)) {
  212. roleMap = redisUtil.getMap(redisKey);
  213. roleMap = Optional.ofNullable(roleMap).orElse(new HashMap<>(20));
  214. } else {
  215. roleMap = roleApi.getRoleMap();
  216. if (DataSetSwapUtil.NEEDCACHE_SYS) {
  217. redisUtil.insert(redisKey, roleMap, DEFAULT_CACHE_TIME);
  218. }
  219. }
  220. localCache.put(CacheKeyUtil.SYS_ROLE, roleMap);
  221. break;
  222. case DataSetConstant.KEY_GROUP:
  223. Map<String, Object> groupMap;
  224. if (redisUtil.exists(redisKey)) {
  225. groupMap = redisUtil.getMap(redisKey);
  226. groupMap = Optional.ofNullable(groupMap).orElse(new HashMap<>(20));
  227. } else {
  228. groupMap = groupApi.getGroupMap();
  229. if (DataSetSwapUtil.NEEDCACHE_SYS) {
  230. redisUtil.insert(redisKey, groupMap, DEFAULT_CACHE_TIME);
  231. }
  232. }
  233. localCache.put(CacheKeyUtil.SYS_GROUP, groupMap);
  234. break;
  235. case DataSetConstant.KEY_SELECT:
  236. DataSetConfig config = (DataSetConfig) item.getParam();
  237. Map<String, String> selectMap = new HashMap<>(16);
  238. List<Map<String, Object>> options = new ArrayList<>();
  239. //静态数据
  240. if (DataTypeConst.STATIC.equals(config.getDataType())) {
  241. if (!localCache.containsKey(redisKey)) {
  242. if (!redisUtil.exists(redisKey)) {
  243. if (config.getOptions() != null) {
  244. List<DataSetOptions> configOptions = config.getOptions();
  245. for (DataSetOptions dso : configOptions) {
  246. selectMap.put(dso.getId(), dso.getFullName());
  247. }
  248. }
  249. redisUtil.insert(redisKey, selectMap, DEFAULT_CACHE_TIME);
  250. localCache.put(redisKey, selectMap);
  251. } else {
  252. localCache.put(redisKey, redisUtil.getMap(redisKey));
  253. }
  254. }
  255. }
  256. //数据字典
  257. if (DataTypeConst.DICTIONARY.equals(config.getDataType())) {
  258. if (!localCache.containsKey(redisKey)) {
  259. if (!redisUtil.exists(redisKey)) {
  260. List<DictionaryDataEntity> list = dictionaryDataApi.getDicList(config.getDictionaryType());
  261. options = list.stream().map(dic -> {
  262. Map<String, Object> dictionaryMap = new HashMap<>(16);
  263. dictionaryMap.put("id", dic.getId());
  264. dictionaryMap.put("enCode", dic.getEnCode());
  265. dictionaryMap.put("fullName", dic.getFullName());
  266. return dictionaryMap;
  267. }).collect(Collectors.toList());
  268. String dictionaryData = JsonUtil.getObjectToString(options);
  269. redisUtil.insert(redisKey, dictionaryData, DEFAULT_CACHE_TIME);
  270. localCache.put(redisKey, options);
  271. } else {
  272. String dictionaryStringData = redisUtil.getString(redisKey).toString();
  273. localCache.put(redisKey, JsonUtil.getJsonToListMap(dictionaryStringData));
  274. }
  275. }
  276. }
  277. //数据接口
  278. if (DataTypeConst.DYNAMIC.equals(config.getDataType())) {
  279. if (!localCache.containsKey(redisKey)) {
  280. if (!redisUtil.exists(redisKey)) {
  281. List<Map<String,Object>> dataList = new ArrayList<>();
  282. ActionResult data = dataInterFaceApi.infoToId(config.getPropsUrl(), null, null);
  283. if (data != null && data.getData() != null) {
  284. if (data.getData() instanceof List) {
  285. dataList = (List<Map<String, Object>>) data.getData();
  286. }
  287. }
  288. String dynamicData = JsonUtil.getObjectToString(dataList);
  289. redisUtil.insert(redisKey, dynamicData, DEFAULT_CACHE_TIME);
  290. localCache.put(redisKey, dataList);
  291. } else {
  292. String dynamicDataStringData = redisUtil.getString(redisKey).toString();
  293. localCache.put(redisKey, JsonUtil.getJsonToListMap(dynamicDataStringData));
  294. }
  295. }
  296. }
  297. break;
  298. default:
  299. break;
  300. }
  301. } catch (Exception e) {
  302. log.error("线程执行错误:" + e.getMessage());
  303. // e.printStackTrace();
  304. } finally {
  305. //每执行一次数值减少一
  306. countDownLatch.countDown();
  307. //也可以给await()设置超时时间,如果超过300s(也可以是时,分)则不再等待,直接执行下面代码。
  308. //countDownLatch.await(300,TimeUnit.SECONDS);
  309. }
  310. });
  311. }
  312. try {
  313. //等待计数器归零
  314. countDownLatch.await();
  315. } catch (InterruptedException e) {
  316. log.error("线程计数错误:" + e.getMessage());
  317. // e.printStackTrace();
  318. }
  319. }
  320. }
  321. @Data
  322. class OateSetExParam {
  323. private String redisKey;
  324. private String type;
  325. private String interfaceId;
  326. private Object param;
  327. public OateSetExParam(String redisKey, String type, String interfaceId, Object param) {
  328. this.redisKey = redisKey;
  329. this.type = type;
  330. this.interfaceId = interfaceId;
  331. this.param = param;
  332. }
  333. }