WODispatchPlanTmDoBizFun.java 61 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012
  1. package com.shkpr.service.aimodelpower.bizmgr;
  2. import com.alibaba.fastjson.JSONArray;
  3. import com.alibaba.fastjson.JSONObject;
  4. import com.global.base.log.LogLevelFlag;
  5. import com.global.base.log.LogPrintMgr;
  6. import com.global.base.tools.FastJsonUtil;
  7. import com.shkpr.service.aimodelpower.commtools.CommTool;
  8. import com.shkpr.service.aimodelpower.commtools.TimeTool;
  9. import com.shkpr.service.aimodelpower.components.locks.CountDownLatchEx;
  10. import com.shkpr.service.aimodelpower.components.locks.WODispatchPlanLockMgr;
  11. import com.shkpr.service.aimodelpower.constants.CommFieldStatus;
  12. import com.shkpr.service.aimodelpower.constants.TaskQueueDataTypeEx;
  13. import com.shkpr.service.aimodelpower.dbdao.DBMgrProxy;
  14. import com.shkpr.service.aimodelpower.dbdao.services.intef.WODispatchCmdBatchItemDBService;
  15. import com.shkpr.service.aimodelpower.dbdao.services.intef.WODispatchCmdInfoDBService;
  16. import com.shkpr.service.aimodelpower.dbdao.services.intef.WODispatchPlanDBService;
  17. import com.shkpr.service.aimodelpower.dbdao.tables.WODispatchDatabaseTable;
  18. import com.shkpr.service.aimodelpower.dbdao.tables.WODispatchPlanInfoTable;
  19. import com.shkpr.service.aimodelpower.dto.*;
  20. import com.shkpr.service.aimodelpower.dto.woDispatchPlanModel.*;
  21. import com.shkpr.service.aimodelpower.globalmgr.AsyncTaskQueueMgr;
  22. import com.shkpr.service.aimodelpower.jsonbean.woDispatchPlan.*;
  23. import com.shkpr.service.aimodelpower.services.ServiceMgrProxy;
  24. import org.springframework.util.CollectionUtils;
  25. import org.springframework.util.StringUtils;
  26. import java.sql.Time;
  27. import java.text.SimpleDateFormat;
  28. import java.time.*;
  29. import java.time.format.DateTimeFormatter;
  30. import java.time.temporal.ChronoUnit;
  31. import java.time.temporal.TemporalAdjusters;
  32. import java.util.*;
  33. import java.util.stream.Collectors;
  34. public class WODispatchPlanTmDoBizFun {
  35. private final static String mStrClassName = "WODispatchPlanTmDoBizFun";
  36. private final static String EMPTY_NULL = "NULL";
  37. private final static String MSG_FAILED = "failed.";
  38. private final static String MSG_SUCCESS = "success.";
  39. private static WODispatchPlanDBService getThisDBService(){ return DBMgrProxy.getInstance().applyWODispatchPlanApi();}
  40. private static WODispatchCmdBatchItemDBService getItemDBService(){ return DBMgrProxy.getInstance().applyWODispatchItemApi();}
  41. private static WODispatchCmdInfoDBService getCmdInfoDBService() {return DBMgrProxy.getInstance().applyWODispatchCmdApi();}
  42. public static ResponseCode produceCmd(String planId, long checkTm){
  43. ResponseCode code = ResponseCode.RESULT_BAD;
  44. if (StringUtils.isEmpty(planId))
  45. return code;
  46. CountDownLatchEx latchEx = null;
  47. int nRetry = 3;
  48. do {
  49. try {
  50. latchEx = WODispatchPlanLockMgr.tryLatchForPlan(planId, 20000);
  51. }catch (Exception e){
  52. latchEx = null;
  53. }
  54. if (latchEx != null){
  55. code = handleProduceCmd(planId, checkTm);
  56. break;
  57. }
  58. }while ((--nRetry) > 0);
  59. if (latchEx != null){
  60. latchEx.countDown();
  61. }else{
  62. code = handleProduceCmd(planId, checkTm);
  63. }
  64. return code;
  65. }
  66. //TODO 判断差值是否小于等于五分钟
  67. private static boolean isWithinFiveMinutes(long timestamp1, long timestamp2) {
  68. return Math.abs(timestamp1 - timestamp2) <= 5 * 60 * 1000;
  69. }
  70. private static ResponseCode handleProduceCmd(String planId, long checkTm){
  71. if(planId.equals("PLP2A012D8D2E815028Y8")){
  72. System.out.println(111);
  73. }
  74. ResponseCode code = ResponseCode.RESULT_BAD;
  75. Long nowLoc = TimeTool.getCurMsUTC();
  76. Map<String,Object> mapSel = getThisDBService().getOne(planId);
  77. if(mapSel!=null&&mapSel.size()>0){
  78. DispatchPlanInfoSSModel model = FastJsonUtil.map2Obj(mapSel,DispatchPlanInfoSSModel.class,true);
  79. String errors = "";
  80. List<String> cmdTaskIds = new ArrayList<>();
  81. long oldNextTakeTime = model.getNextTakeTime();
  82. long oldLimitNextTakeTime = model.getLimitNextTakeTime();
  83. long newNextTakeTime = oldNextTakeTime;
  84. long newLimitNextTakeTime = oldLimitNextTakeTime;
  85. long newLastTakeTime = model.getLastTakeTime();
  86. Map<String, Object> andWheres = new HashMap<>();
  87. andWheres.put(WODispatchPlanInfoTable.R_INFO.PRIMARY_KEY,planId);
  88. Map<String, Object> updates = new HashMap<>();
  89. andWheres.put(WODispatchPlanInfoTable.W_INFO.UNIQUE_ID, planId);
  90. do {
  91. List<DispatchCmdBatchItemModel> itemModels = getItemDBService()
  92. .listAllWithsExByDispoal("", "", andWheres, new HashMap<>(), "handle_start_time", "");
  93. if (checkTm != model.getNextTakeTime()){
  94. errors = "Next take time changed,goto next cycle";
  95. break;
  96. }
  97. if (model.getPlanStatus() != 1){
  98. errors = "Plan status changed,goto next cycle";
  99. break;
  100. }
  101. if (CollectionUtils.isEmpty(itemModels)){
  102. errors = "Plan batch empty,goto next cycle";
  103. break;
  104. }
  105. DispatchPlanInfoNextTimeModel nextTimeModel = new DispatchPlanInfoNextTimeModel();
  106. List<DispatchCmdBatchItemNextTimeModel> itemModelNextTimes = new ArrayList<>();
  107. if (!CollectionUtils.isEmpty(itemModels)) {
  108. for (DispatchCmdBatchItemModel jpItem : itemModels) {
  109. DispatchCmdBatchItemNextTimeModel dispatchCmdBatchItemNextTimeModel = new DispatchCmdBatchItemNextTimeModel();
  110. dispatchCmdBatchItemNextTimeModel.setHandleStartTime(jpItem.getHandleStartTime());
  111. dispatchCmdBatchItemNextTimeModel.setHandleStartTimeLimit(jpItem.getHandleEndTime());
  112. itemModelNextTimes.add(dispatchCmdBatchItemNextTimeModel);
  113. }
  114. }
  115. nextTimeModel.setItemsList(itemModelNextTimes);
  116. nextTimeModel.setPlanType(model.getPlanType());
  117. nextTimeModel.setDispatchLeadTime(model.getDispatchLeadTime());
  118. nextTimeModel.setCycles(model.getCycles());
  119. LocalDateTime newTureNextTakeTimeDateTime = LocalDateTime
  120. .ofInstant(Instant.ofEpochMilli(newNextTakeTime), ZoneId.systemDefault())
  121. .minusMinutes(model.getDispatchLeadTime());
  122. Map<String,Long> nextMap = returnNextTakeTime(nextTimeModel,newTureNextTakeTimeDateTime);
  123. newNextTakeTime = (model.getPlanType()==0)?0L:nextMap.get("nextTakeTime");
  124. newLimitNextTakeTime = (model.getPlanType()==0)?0L:nextMap.get("limitNextTakeTime");//returnNextTakeTime(nextTimeModel);
  125. if (model.getPlanType() != 0 && newNextTakeTime <= oldNextTakeTime){
  126. newNextTakeTime = oldNextTakeTime;
  127. newLimitNextTakeTime = oldLimitNextTakeTime;
  128. errors = "Plan take time produce error,please check take time logic and goto next cycle";
  129. break;
  130. }
  131. if (model.getPlanType() != 0
  132. && !(nowLoc >= oldNextTakeTime && nowLoc <= oldLimitNextTakeTime)){
  133. errors = "Plan will use new take time,goto next cycle";
  134. break;
  135. }
  136. JSONArray jsonArray = new JSONArray();
  137. for (DispatchCmdBatchItemModel item:itemModels) {
  138. JSONObject planCommandParam = new JSONObject();
  139. planCommandParam.put("type", 1);
  140. planCommandParam.put("zoneId", model.getZoneId());
  141. planCommandParam.put("zoneType", model.getZoneType());
  142. planCommandParam.put("zone", model.getZone());
  143. planCommandParam.put("sender", model.getCreatorId());
  144. planCommandParam.put("receiver", item.getHeadUserId());
  145. Long sugBeginTime = 0L;
  146. if(model.getDispatchLeadTime()<0){
  147. sugBeginTime = Instant.ofEpochMilli(model.getNextTakeTime()).atZone(ZoneId.systemDefault())
  148. .minusMinutes(model.getDispatchLeadTime())
  149. .withHour(Integer.valueOf(item.getHandleStartTime().split(":")[0]))
  150. .withMinute(Integer.valueOf(item.getHandleStartTime().split(":")[1]))
  151. .withSecond(Integer.valueOf(item.getHandleStartTime().split(":")[2]))
  152. .toInstant().toEpochMilli();
  153. }else if(model.getDispatchLeadTime()==0){
  154. sugBeginTime = Instant.ofEpochMilli(model.getNextTakeTime()).atZone(ZoneId.systemDefault())
  155. .withHour(Integer.valueOf(item.getHandleStartTime().split(":")[0]))
  156. .withMinute(Integer.valueOf(item.getHandleStartTime().split(":")[1]))
  157. .withSecond(Integer.valueOf(item.getHandleStartTime().split(":")[2]))
  158. .toInstant().toEpochMilli();
  159. }else if(model.getDispatchLeadTime()>0){
  160. sugBeginTime = Instant.ofEpochMilli(model.getNextTakeTime()).atZone(ZoneId.systemDefault())
  161. .minusMinutes(model.getDispatchLeadTime())
  162. .withHour(Integer.valueOf(item.getHandleStartTime().split(":")[0]))
  163. .withMinute(Integer.valueOf(item.getHandleStartTime().split(":")[1]))
  164. .withSecond(Integer.valueOf(item.getHandleStartTime().split(":")[2]))
  165. .toInstant().toEpochMilli();
  166. }
  167. if (sugBeginTime<=0L){
  168. //TODO 说明时间错误,将错误拦截在此处不再进行派单动作
  169. continue;
  170. }
  171. planCommandParam.put("title",String.format("%s--第%s批次任务",model.getTitle(),
  172. TimeTool.convertUTC2DateStr(sugBeginTime, TimeTool.TIMESTAMP_FORMAT_EX3)));
  173. planCommandParam.put("sugBeginTime",sugBeginTime);
  174. String endTimeStr = item.getHandleEndTime();
  175. planCommandParam.put("sugEndTime", Instant.ofEpochMilli(sugBeginTime)
  176. .atZone(ZoneId.systemDefault())
  177. .withHour(Integer.valueOf(endTimeStr.split(":")[0]))
  178. .withMinute(Integer.valueOf(endTimeStr.split(":")[1]))
  179. .withSecond(Integer.valueOf(endTimeStr.split(":")[2]))
  180. .toInstant().toEpochMilli());
  181. List<Map<String,Object>> suggestions = new ArrayList<>();
  182. if(!CollectionUtils.isEmpty(item.getDispoalModels())){
  183. for(DispatchCmdBatchDispoalModel dispoalModel:item.getDispoalModels()) {
  184. Map<String, Object> sug = new HashMap<>();
  185. sug.put("key", dispoalModel.getKey());
  186. sug.put("data", dispoalModel.getData());
  187. sug.put("ordering", dispoalModel.getOrdering());
  188. sug.put("did", dispoalModel.getDid());
  189. sug.put("dname", dispoalModel.getDname());
  190. suggestions.add(sug);
  191. }
  192. }
  193. planCommandParam.put("suggestions",suggestions);
  194. planCommandParam.put("fromSource",planId);
  195. planCommandParam.put("level",model.getUrgentLevel());
  196. planCommandParam.put("sendway",model.getSendway());
  197. planCommandParam.put("remark",model.getDispatchRemark());
  198. planCommandParam.put("gis",item.getGis());
  199. planCommandParam.put("address",item.getHandleAddress());
  200. jsonArray.add(planCommandParam);
  201. }
  202. if(jsonArray.size()>0) {
  203. try {
  204. JSONObject jsonParam = new JSONObject();
  205. jsonParam.put("total",jsonArray.size());
  206. jsonParam.put("data",jsonArray);
  207. ResponseRes<String> res = ServiceMgrProxy.getInstance().applyTaskServiceApi().postPlanCommand(jsonParam);
  208. if (ResponseCode.RESULT_NORMAL.toStrCode().equals(res.getRescode())) {
  209. DispatchCmdTaskRspGroup result = FastJsonUtil.fromJSONByGson(res.getResdata(), DispatchCmdTaskRspGroup.class);
  210. if (CommTool.listSize(result.getData()) > 0){
  211. for (DispatchCmdTaskRsp item:result.getData()){
  212. if ("0".equals(item.getCode())){
  213. cmdTaskIds.add(item.getUid());
  214. newLastTakeTime = item.getOkTime();
  215. code = ResponseCode.RESULT_NORMAL;
  216. }
  217. }
  218. }
  219. }
  220. } catch (Exception ex) {
  221. code = ResponseCode.BUSINESS_BUSY;
  222. LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_INFO, mStrClassName, mStrClassName
  223. , String.format("check planInfo errorMsg:%s end<====",
  224. ex.getLocalizedMessage()));
  225. }
  226. if (code != ResponseCode.RESULT_NORMAL)
  227. errors = "Produce cmd failed by remote api,goto next cycle";
  228. }else
  229. errors = "Produce cmd failed by invalid param,goto next cycle";
  230. if (CommTool.listSize(cmdTaskIds) <= 0 || code != ResponseCode.RESULT_NORMAL){
  231. newNextTakeTime = oldNextTakeTime;
  232. newLimitNextTakeTime = oldLimitNextTakeTime;
  233. break;
  234. }
  235. }while (false);
  236. updates.put(WODispatchPlanInfoTable.W_INFO.ERRORS, errors);
  237. updates.put(WODispatchPlanInfoTable.W_INFO.TAKES, model.getTakes()+1);
  238. updates.put(WODispatchPlanInfoTable.W_INFO.UPDATE_TIME, nowLoc);
  239. updates.put(WODispatchPlanInfoTable.W_INFO.LAST_TAKE_TIME, newLastTakeTime);
  240. updates.put(WODispatchPlanInfoTable.W_INFO.NEXT_TAKE_TIME, newNextTakeTime);
  241. updates.put(WODispatchPlanInfoTable.W_INFO.LIMIT_NEXT_TAKE_TIME, newLimitNextTakeTime);
  242. if (getThisDBService().updateWiths(updates, andWheres) <= 0){
  243. if (CommTool.listSize(cmdTaskIds) > 0){
  244. getCmdInfoDBService().batchDeleteIn(cmdTaskIds, "");
  245. }
  246. code = ResponseCode.BUSINESS_DB_REQ_FAILED;
  247. }else
  248. code = ResponseCode.RESULT_NORMAL;
  249. }
  250. return code;
  251. }
  252. public static void checkPlanForProduce(){
  253. long lCurTime = System.currentTimeMillis();
  254. Map<String, Object> mapSel = getThisDBService().totalWillProduceCounts(null
  255. , null
  256. , ""
  257. , String.format("and %s = %d and next_take_time > 0 and next_take_time <= %d"
  258. , WODispatchPlanInfoTable.R_INFO.STATUS
  259. , CommFieldStatus.ENABLE
  260. , lCurTime));
  261. if (mapSel != null && mapSel.size() > 0){
  262. WODispatchCheckTotal oTotal = FastJsonUtil.map2Obj(mapSel, WODispatchCheckTotal.class, true);
  263. if (oTotal != null && oTotal.getTotal() > 0){
  264. long curIndex = -1L;
  265. int limit = 50, offset = 0, realTotal = 0;
  266. while (curIndex < oTotal.getMaxIndex()){
  267. List<Map<String, Object>> arrDbTmp = getThisDBService().listAllWithsEx(WODispatchPlanInfoTable.R_INFO.TABLE
  268. , WODispatchPlanInfoTable.R_INFO.TOTAL_PRODUCE_FILED
  269. , limit
  270. , offset
  271. ,null
  272. ,null
  273. , WODispatchPlanInfoTable.R_INFO.TOTAL_PRODUCE_ORDER
  274. , String.format("and %s = %d and (id between %d and %d)"
  275. ,WODispatchPlanInfoTable.R_INFO.STATUS
  276. ,CommFieldStatus.ENABLE
  277. ,oTotal.getMinIndex()
  278. ,oTotal.getMaxIndex()));
  279. if (CommTool.listSize(arrDbTmp) <= 0)
  280. break;
  281. realTotal += arrDbTmp.size();
  282. offset = realTotal;
  283. List<WODispatchCheckBean> arrRes = FastJsonUtil.batchMap2Obj(arrDbTmp, WODispatchCheckBean.class, true);
  284. if (CommTool.listSize(arrRes) <= 0)
  285. continue;
  286. for (WODispatchCheckBean oItem:arrRes){
  287. if (oItem.getId() > curIndex)
  288. curIndex = oItem.getId();
  289. if (oItem.getStatus() != CommFieldStatus.ENABLE)
  290. continue;
  291. boolean bProduce = false;
  292. boolean bGenNext = false;
  293. if (oItem.getBatchTotal() <= 0 || oItem.getNextTakeTime() <= 0L){
  294. bGenNext = true;
  295. }else if (oItem.getNextTakeTime() <= lCurTime){
  296. bProduce = true;
  297. }
  298. if (bProduce){
  299. AsyncTaskQueueMgr.getInstance().postTaskData(TaskQueueDataTypeEx.ASYNC_PRODUCE_WO_DISPATCH_CMD, new CommUTMBean(oItem.getUid(), oItem.getNextTakeTime()));
  300. }else if (bGenNext){
  301. //do nothing
  302. }
  303. }
  304. }
  305. }
  306. }
  307. }
  308. //TODO 分页查询计划
  309. //查询·分页
  310. public static PageRecordRes<DispatchPlanInfoSSModel> queryPageList(JPDispatchPlanInfoSS jsonParam){
  311. PageRecordRes<DispatchPlanInfoSSModel> oRes = new PageRecordRes<>();
  312. if (jsonParam == null)
  313. return oRes;
  314. final String lilterExtend = jsonParam.genQueryExtend();
  315. Map<String,Object> andWheres = new HashMap<>();
  316. if(jsonParam.getPlanType()!=null){
  317. andWheres.put("plan_type", jsonParam.getPlanType());
  318. }
  319. if(jsonParam.getPlanStatus()!=null){
  320. andWheres.put("plan_status", jsonParam.getPlanStatus());
  321. }
  322. if(jsonParam.getZoneId()!=null){
  323. andWheres.put("zone_id", jsonParam.getZoneId());
  324. }
  325. String sql = "";
  326. if(jsonParam.getDownFlag()!=null) {
  327. if(jsonParam.getDownFlag()==0) {
  328. sql += " AND " + WODispatchPlanInfoTable.R_INFO.LAST_TAKE_TIME + " > 0 ";
  329. }else{
  330. sql += " AND " + WODispatchPlanInfoTable.R_INFO.LAST_TAKE_TIME + " = 0 ";
  331. }
  332. }
  333. int nTotals = getThisDBService().totalCountsEx("", andWheres, null, lilterExtend+sql);
  334. if (nTotals > 0){
  335. List<Map<String,Object>> dataList = getThisDBService().listAllWithsEx("","",
  336. jsonParam.getLimit(),
  337. jsonParam.getOffset(),
  338. andWheres,
  339. null,
  340. WODispatchPlanInfoTable.R_INFO.CREATE_TIME+" DESC",
  341. lilterExtend+sql);
  342. if(dataList==null){
  343. oRes.setCode(ResponseCode.RESULT_BAD.toInt());
  344. }else{
  345. List<DispatchPlanInfoSSModel> ssInfoModels = dataList.isEmpty()?new ArrayList<>():
  346. FastJsonUtil.batchMap2Obj(dataList,DispatchPlanInfoSSModel.class,true);
  347. oRes.setCode(ResponseCode.RESULT_NORMAL.toInt());
  348. oRes.setTotal(nTotals);
  349. oRes.setData(ssInfoModels);
  350. }
  351. }
  352. return oRes;
  353. }
  354. //TODO 查询详情信息
  355. public static ResponseRes selectPlanInfoView(JPDispatchPlanInfoDetailsSS oJsonParam){
  356. ResponseRes oRes = new ResponseRes();
  357. oRes.setRescode(ResponseCode.RESULT_BAD.toStrCode());
  358. oRes.setResmsg(ResponseCode.RESULT_BAD.toStrMsg());
  359. if(StringUtils.isEmpty(oJsonParam)||StringUtils.isEmpty(oJsonParam.getPlanId())){
  360. oRes.setRescode(ResponseCode.STATUS_ERROR_JSON_FORMAT.toStrCode());
  361. oRes.setResmsg(ResponseCode.STATUS_ERROR_JSON_FORMAT.toStrMsg());
  362. return oRes;
  363. }
  364. try{
  365. Map<String,Object> map = getThisDBService().getOne(oJsonParam.getPlanId());
  366. if(map!=null||map.size()>0){
  367. DispatchPlanInfoDetailsModel model = FastJsonUtil.map2Obj(map,DispatchPlanInfoDetailsModel.class,true);
  368. if (model!=null) {
  369. //TODO 查询相关联规则和标签
  370. Map<String, Object> andWheresRuls = new HashMap<>();
  371. andWheresRuls.put("plan_id", oJsonParam.getPlanId());
  372. List<Map<String,Object>> rulsModels = getThisDBService().selectAllRuls("","",
  373. andWheresRuls,new HashMap<>(),"","");
  374. Map<String, Object> andWheresTags = new HashMap<>();
  375. andWheresTags.put("plan_id", oJsonParam.getPlanId());
  376. List<Map<String,Object>> tagModels = getThisDBService().selectAllPlanTags("","",
  377. andWheresTags,new HashMap<>(),"","");
  378. //TODO 查询相关联的排班项信息
  379. Map<String, Object> andWheres = new HashMap<>();
  380. andWheres.put("plan_id", oJsonParam.getPlanId());
  381. List<DispatchCmdBatchItemModel> itemModels = getItemDBService()
  382. .listAllWithsExByDispoal("", "", andWheres, new HashMap<>(), "handle_start_time", "");
  383. if(!CollectionUtils.isEmpty(rulsModels)){
  384. model.setRulsModels(FastJsonUtil.batchMap2Obj(rulsModels,DispatchPlanInfoRuleModel.class,true));
  385. }
  386. if(!CollectionUtils.isEmpty(tagModels)){
  387. model.setTagsList(FastJsonUtil.batchMap2Obj(tagModels,DispatchPlanInfoTagsModel.class,true));
  388. }
  389. if(!CollectionUtils.isEmpty(itemModels)) {
  390. model.setItemModels(itemModels);
  391. }
  392. oRes.setResdata(FastJsonUtil.toJSON(model));
  393. }
  394. }
  395. oRes.setRescode(ResponseCode.RESULT_NORMAL.toStrCode());
  396. oRes.setResmsg(ResponseCode.RESULT_NORMAL.toStrMsg());
  397. return oRes;
  398. }catch (Exception ex){
  399. return oRes;
  400. }
  401. }
  402. //判断是否在时间区间内并且取出最接近当前时间的大于它的时间
  403. //nextType 0 周 1 月 2 年
  404. public static LocalDateTime findNextTime(List<String> dateTimeStrings,LocalDateTime oldTm){
  405. LocalDateTime now = oldTm==null?LocalDateTime.now():oldTm; // 获取当前日期时间
  406. System.out.println("Current DateTime: " + now);
  407. DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
  408. // 转换为LocalDateTime集合
  409. List<LocalDateTime> dateTimes = new ArrayList<>();
  410. for (String dtStr : dateTimeStrings) {
  411. dateTimes.add(LocalDateTime.parse(dtStr,formatter));
  412. }
  413. // 找到最接近且大于当前时间的日期时间
  414. // 仅考虑大于当前时间的日期时间
  415. LocalDateTime closestFutureDateTime = dateTimes.stream()
  416. .filter(dateTime -> dateTime.isAfter(now))
  417. .min((dateTime1, dateTime2) -> Long.compare(
  418. java.time.temporal.ChronoUnit.MINUTES.between(now, dateTime1),
  419. java.time.temporal.ChronoUnit.MINUTES.between(now, dateTime2)))
  420. .orElse(null); // 如果没有找到,返回null
  421. //TODO 输出结果 ,如果为空说明在集合中没有找到符合条件的时间, 则直接取下一个单位的最小时间即可
  422. return closestFutureDateTime;
  423. }
  424. //LocalDateTime转UTC时间戳
  425. public static Long reloadLocalDateTimeToLong(LocalDateTime localDateTime){
  426. // 转换为毫秒时间戳
  427. long timestampMillis = TimeTool.convertDateStr2UTC(localDateTime.format(DateTimeFormatter.ofPattern(TimeTool.TIMESTAMP_FORMAT)));
  428. return timestampMillis;
  429. }
  430. //TODO 公用计算下次生效时间的方法
  431. //TODO 分是否排班
  432. //TODO oldTm主要为了再派单时比对
  433. public static Map<String,Long> returnNextTakeTime(DispatchPlanInfoNextTimeModel model,LocalDateTime oldTm){
  434. Map<String,Long> map = new HashMap<>();
  435. Long nextTakeTime = 0L;
  436. Long limitNextTakeTime = 0L;
  437. map.put("nextTakeTime",nextTakeTime);
  438. map.put("limitNextTakeTime",limitNextTakeTime);
  439. map.put("ifRestNextTakeTime",0L);//是否将newTextTakeTime更新到 plan中 0否, 1是
  440. if(!CollectionUtils.isEmpty(model.getItemsList())){
  441. List<DispatchCmdBatchItemNextTimeModel> newList = model.getItemsList().stream()
  442. .sorted(Comparator.comparing(DispatchCmdBatchItemNextTimeModel::getHandleStartTime))
  443. .collect(Collectors.toList());
  444. if(model.getPlanType()==0) {
  445. //TODO 临时计划
  446. Instant nowTime = Instant.ofEpochMilli(
  447. TimeTool.convertDateStr2UTC
  448. (
  449. JSONArray.parseArray(model.getCycles()).getString(0)
  450. +" "+
  451. newList.get(0).getHandleStartTime()));
  452. Instant endTime = Instant.ofEpochMilli(
  453. TimeTool.convertDateStr2UTC
  454. (
  455. JSONArray.parseArray(model.getCycles()).getString(0)
  456. +" "+
  457. model.getItemsList().stream().sorted(Comparator.comparing(DispatchCmdBatchItemNextTimeModel::getHandleStartTimeLimit))
  458. .collect(Collectors.toList()).get(0).getHandleStartTimeLimit()));
  459. if(model.getDispatchLeadTime()==0) {
  460. nextTakeTime = nowTime.toEpochMilli();
  461. limitNextTakeTime = endTime.toEpochMilli();
  462. }else if(model.getDispatchLeadTime()>0){
  463. nextTakeTime = nowTime.minus(-model.getDispatchLeadTime(), ChronoUnit.MINUTES).toEpochMilli();
  464. limitNextTakeTime = endTime.toEpochMilli();
  465. }else if(model.getDispatchLeadTime()<0){
  466. nextTakeTime = nowTime.minus(Math.abs(model.getDispatchLeadTime()), ChronoUnit.MINUTES).toEpochMilli();
  467. limitNextTakeTime = endTime.toEpochMilli();
  468. }
  469. //TODO 如果当前时间与下次生效时间是同一天,但是时刻已经是过去时,那么则返回失败信息
  470. Long nowTimeLong = TimeTool.getCurMsUTC();
  471. if(nowTimeLong>nextTakeTime&&nowTimeLong>limitNextTakeTime&&isSameDay(nowTimeLong,nextTakeTime)){
  472. throw new RuntimeException(ResponseCode.STATUS_ERROR_JSON_FORMAT.toStrCode());
  473. }
  474. }else if(model.getPlanType()==1){
  475. //TODO 日计划
  476. boolean isToDay = false;//生效时间是否小于等于当前时刻
  477. for (DispatchCmdBatchItemNextTimeModel item:newList){
  478. Instant nowTime = Instant.ofEpochMilli(
  479. TimeTool.convertDateStr2UTC
  480. (JSONArray.parseArray(model.getCycles()).getString(0)
  481. +" "+item.getHandleStartTime()));
  482. LocalDateTime dateTime = nowTime.atZone(ZoneId.systemDefault()).toLocalDateTime();
  483. Instant endTime = Instant.ofEpochMilli(
  484. TimeTool.convertDateStr2UTC
  485. (
  486. JSONArray.parseArray(model.getCycles()).getString(0)
  487. +" "+
  488. model.getItemsList().stream().sorted(Comparator.comparing(DispatchCmdBatchItemNextTimeModel::getHandleStartTimeLimit))
  489. .collect(Collectors.toList()).get(0).getHandleStartTimeLimit()));
  490. LocalDateTime dateTime1 = endTime.atZone(ZoneId.systemDefault()).toLocalDateTime();
  491. LocalDateTime dateTimeNow = Instant.now().atZone(ZoneId.systemDefault()).toLocalDateTime();
  492. if(Instant.now().isBefore(nowTime)||Instant.now().equals(nowTime)){
  493. isToDay = true;
  494. if(model.getDispatchLeadTime()==0) {
  495. nextTakeTime = nowTime.toEpochMilli();
  496. limitNextTakeTime = endTime.toEpochMilli();
  497. }else if(model.getDispatchLeadTime()>0){
  498. nextTakeTime = nowTime.minus(-model.getDispatchLeadTime(), ChronoUnit.MINUTES).toEpochMilli();
  499. limitNextTakeTime = endTime.toEpochMilli();
  500. }else if(model.getDispatchLeadTime()<0){
  501. nextTakeTime = nowTime.minus(Math.abs(model.getDispatchLeadTime()), ChronoUnit.MINUTES).toEpochMilli();
  502. limitNextTakeTime = endTime.toEpochMilli();
  503. }
  504. break;
  505. }
  506. }
  507. if(!isToDay){
  508. //说明当天并没有满足条件的时刻,那么在日期上加一天,并且用最小时刻
  509. if(model.getDispatchLeadTime()==0) {
  510. nextTakeTime = Instant.ofEpochMilli(
  511. TimeTool.convertDateStr2UTC
  512. (JSONArray.parseArray(model.getCycles()).getString(0)
  513. +" "+newList.get(0).getHandleStartTime())).plus(Duration.ofDays(1)).toEpochMilli();
  514. limitNextTakeTime = Instant.ofEpochMilli(
  515. TimeTool.convertDateStr2UTC
  516. (JSONArray.parseArray(model.getCycles()).getString(0)
  517. +" "+model.getItemsList().stream().sorted(Comparator.comparing(DispatchCmdBatchItemNextTimeModel::getHandleStartTimeLimit))
  518. .collect(Collectors.toList()).get(0).getHandleStartTimeLimit())).plus(Duration.ofDays(1)).toEpochMilli();
  519. }else if(model.getDispatchLeadTime()>0){
  520. nextTakeTime = Instant.ofEpochMilli(
  521. TimeTool.convertDateStr2UTC
  522. (JSONArray.parseArray(model.getCycles()).getString(0)
  523. +" "+newList.get(0).getHandleStartTime())).plus(Duration.ofDays(1)).minus(-model.getDispatchLeadTime(), ChronoUnit.MINUTES).toEpochMilli();
  524. limitNextTakeTime = Instant.ofEpochMilli(
  525. TimeTool.convertDateStr2UTC
  526. (JSONArray.parseArray(model.getCycles()).getString(0)
  527. +" "+model.getItemsList().stream().sorted(Comparator.comparing(DispatchCmdBatchItemNextTimeModel::getHandleStartTimeLimit))
  528. .collect(Collectors.toList()).get(0).getHandleStartTimeLimit())).plus(Duration.ofDays(1)).toEpochMilli();
  529. }else if(model.getDispatchLeadTime()<0){
  530. nextTakeTime = Instant.ofEpochMilli(
  531. TimeTool.convertDateStr2UTC
  532. (JSONArray.parseArray(model.getCycles()).getString(0)
  533. +" "+newList.get(0).getHandleStartTime())).plus(Duration.ofDays(1)).minus(Math.abs(model.getDispatchLeadTime()), ChronoUnit.MINUTES).toEpochMilli();
  534. limitNextTakeTime = Instant.ofEpochMilli(
  535. TimeTool.convertDateStr2UTC
  536. (JSONArray.parseArray(model.getCycles()).getString(0)
  537. +" "+model.getItemsList().stream().sorted(Comparator.comparing(DispatchCmdBatchItemNextTimeModel::getHandleStartTimeLimit))
  538. .collect(Collectors.toList()).get(0).getHandleStartTimeLimit())).plus(Duration.ofDays(1)).toEpochMilli();
  539. }
  540. }
  541. //TODO 如果当前时间大于生效时间,说明生效时间过期,则加一天
  542. LocalDateTime localNext = LocalDateTime.ofInstant(Instant.ofEpochMilli(nextTakeTime), ZoneId.systemDefault())
  543. .minusMinutes(model.getDispatchLeadTime());
  544. if(limitNextTakeTime<TimeTool.getCurMsUTC()){
  545. nextTakeTime = Instant.ofEpochMilli(nextTakeTime)
  546. .plus(1, ChronoUnit.DAYS).toEpochMilli();
  547. limitNextTakeTime = Instant.ofEpochMilli(limitNextTakeTime).toEpochMilli();
  548. }else if(oldTm!=null&&(localNext
  549. .isBefore(oldTm)||localNext.isEqual(oldTm))
  550. ){
  551. //TODO 连续时需考虑
  552. //TODO 如果传递了对比值, 则说明当前计算的时间与old不符合条件,则再加一算一次
  553. nextTakeTime = Instant.ofEpochMilli(nextTakeTime)
  554. .plus(1, ChronoUnit.DAYS).toEpochMilli();
  555. limitNextTakeTime = Instant.ofEpochMilli(limitNextTakeTime).plus(1, ChronoUnit.DAYS).toEpochMilli();
  556. map.put("ifRestNextTakeTime",1L);
  557. }
  558. }else if(model.getPlanType()==2){
  559. //TODO 周计划
  560. //TODO 先取周期值里最小的数,新集合里最小的值就是最早的周几数
  561. JSONArray newJSONArray = JSONArray.parseArray(model.getCycles()).stream().sorted(
  562. // 根据
  563. Comparator.comparingLong(
  564. e -> Long.valueOf(e.toString())
  565. )
  566. // 放开下面的注释,使用reversed()方法,就是降序 大到小
  567. // .reversed()
  568. ).collect(Collectors.toCollection(JSONArray::new));
  569. //TODO 先得到所有集合对应的当前周的所有符合条件的时间
  570. List<String> dateTimeStrings = new ArrayList<>();
  571. List<String> dateLimitTimeStrings = new ArrayList<>();//最小截止值
  572. for (Object obj:newJSONArray){
  573. LocalDateTime nowDate = LocalDateTime.now().with(DayOfWeek.of(Integer.valueOf(obj.toString())));
  574. for (DispatchCmdBatchItemNextTimeModel item : newList){
  575. String[] times = item.getHandleStartTime().split(":");
  576. String[] timeLimits = item.getHandleStartTimeLimit().split(":");
  577. dateTimeStrings.add(nowDate.withHour(Integer.valueOf(times[0]))
  578. .withMinute(Integer.valueOf(times[1])).withSecond(Integer.valueOf(times[2])).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
  579. dateLimitTimeStrings.add(nowDate.withHour(Integer.valueOf(timeLimits[0]))
  580. .withMinute(Integer.valueOf(timeLimits[1])).withSecond(Integer.valueOf(timeLimits[2])).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
  581. }
  582. }
  583. LocalDateTime nextDateTime = findNextTime(dateTimeStrings,oldTm);
  584. LocalDateTime limitNextDateTime = nextDateTime!=null?LocalDateTime.parse(dateLimitTimeStrings.get(dateLimitTimeStrings.indexOf(nextDateTime
  585. .format(DateTimeFormatter.ofPattern(TimeTool.YEAR_MONTH_DAY_FORMAT))
  586. +" "+
  587. model.getItemsList().stream().sorted(Comparator.comparing(DispatchCmdBatchItemNextTimeModel::getHandleStartTimeLimit))
  588. .collect(Collectors.toList()).get(0).getHandleStartTimeLimit())),DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")):null;
  589. if(nextDateTime!=null){
  590. if (model.getDispatchLeadTime() == 0) {
  591. nextTakeTime = reloadLocalDateTimeToLong(nextDateTime);
  592. limitNextTakeTime = reloadLocalDateTimeToLong(limitNextDateTime);
  593. } else if (model.getDispatchLeadTime() > 0) {
  594. nextTakeTime = reloadLocalDateTimeToLong(nextDateTime.minusMinutes(-model.getDispatchLeadTime()));
  595. limitNextTakeTime = reloadLocalDateTimeToLong(limitNextDateTime);
  596. } else if (model.getDispatchLeadTime() < 0) {
  597. nextTakeTime = reloadLocalDateTimeToLong(nextDateTime.minusMinutes(Math.abs(model.getDispatchLeadTime())));
  598. limitNextTakeTime = reloadLocalDateTimeToLong(limitNextDateTime);
  599. }
  600. }else{
  601. LocalTime localTime = LocalTime.parse(newList.get(0).getHandleStartTime(), DateTimeFormatter.ofPattern("HH:mm:ss"));
  602. LocalTime localTimeLimit = LocalTime.parse(model.getItemsList().stream().sorted(Comparator.comparing(DispatchCmdBatchItemNextTimeModel::getHandleStartTimeLimit))
  603. .collect(Collectors.toList()).get(0).getHandleStartTimeLimit(), DateTimeFormatter.ofPattern("HH:mm:ss"));
  604. nextDateTime = LocalDateTime.now()
  605. .with(DayOfWeek.of(Integer.valueOf(newJSONArray.get(0).toString())));
  606. if (model.getDispatchLeadTime() == 0) {
  607. nextTakeTime = reloadLocalDateTimeToLong(nextDateTime.minusWeeks(-1).withHour(localTime.getHour())
  608. .withMinute(localTime.getMinute())
  609. .withSecond(localTime.getSecond()));
  610. limitNextTakeTime = reloadLocalDateTimeToLong(nextDateTime.minusWeeks(-1).withHour(localTimeLimit.getHour())
  611. .withMinute(localTimeLimit.getMinute())
  612. .withSecond(localTimeLimit.getSecond()));
  613. } else if (model.getDispatchLeadTime() > 0) {
  614. nextTakeTime = reloadLocalDateTimeToLong(nextDateTime.minusWeeks(-1).withHour(localTime.getHour())
  615. .withMinute(localTime.getMinute())
  616. .withSecond(localTime.getSecond()));
  617. limitNextTakeTime = reloadLocalDateTimeToLong(nextDateTime.minusWeeks(-1).withHour(localTimeLimit.getHour())
  618. .withMinute(localTimeLimit.getMinute())
  619. .withSecond(localTimeLimit.getSecond()).minusMinutes(-model.getDispatchLeadTime()));
  620. } else if (model.getDispatchLeadTime() < 0) {
  621. nextTakeTime = reloadLocalDateTimeToLong(nextDateTime.minusWeeks(-1).withHour(localTime.getHour())
  622. .withMinute(localTime.getMinute())
  623. .withSecond(localTime.getSecond()).minusMinutes(Math.abs(model.getDispatchLeadTime())));
  624. limitNextTakeTime = reloadLocalDateTimeToLong(nextDateTime.minusWeeks(-1).withHour(localTimeLimit.getHour())
  625. .withMinute(localTimeLimit.getMinute())
  626. .withSecond(localTimeLimit.getSecond()));
  627. }
  628. }
  629. }else if(model.getPlanType()==3){
  630. //TODO 月计划
  631. JSONArray newJSONArray = JSONArray.parseArray(model.getCycles()).stream().sorted(
  632. // 根据
  633. Comparator.comparingLong(
  634. e -> Long.valueOf(e.toString())
  635. )
  636. // 放开下面的注释,使用reversed()方法,就是降序 大到小
  637. // .reversed()
  638. ).collect(Collectors.toCollection(JSONArray::new));
  639. //TODO 先得到所有集合对应的当前月的所有符合条件的时间
  640. List<String> dateTimeStrings = new ArrayList<>();
  641. List<String> dateLimitTimeStrings = new ArrayList<>();//最小截止值
  642. for (Object obj:newJSONArray){
  643. LocalDateTime nowDate = LocalDateTime.now().withDayOfMonth(Integer.valueOf(obj.toString()));
  644. for (DispatchCmdBatchItemNextTimeModel item : newList){
  645. String[] times = item.getHandleStartTime().split(":");
  646. String[] timeLimits = item.getHandleStartTimeLimit().split(":");
  647. dateTimeStrings.add(nowDate.withHour(Integer.valueOf(times[0]))
  648. .withMinute(Integer.valueOf(times[1])).withSecond(Integer.valueOf(times[2])).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
  649. dateLimitTimeStrings.add(nowDate.withHour(Integer.valueOf(timeLimits[0]))
  650. .withMinute(Integer.valueOf(timeLimits[1])).withSecond(Integer.valueOf(timeLimits[2])).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
  651. }
  652. }
  653. LocalDateTime nextDateTime = findNextTime(dateTimeStrings,oldTm);
  654. LocalDateTime limitNextDateTime = nextDateTime!=null?LocalDateTime.parse(dateLimitTimeStrings.get(dateLimitTimeStrings.indexOf(nextDateTime
  655. .format(DateTimeFormatter.ofPattern(TimeTool.YEAR_MONTH_DAY_FORMAT))+" "+model.getItemsList().stream().sorted(Comparator.comparing(DispatchCmdBatchItemNextTimeModel::getHandleStartTimeLimit))
  656. .collect(Collectors.toList()).get(0).getHandleStartTimeLimit())),DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")):null;
  657. if(nextDateTime!=null){
  658. if (model.getDispatchLeadTime() == 0) {
  659. nextTakeTime = reloadLocalDateTimeToLong(nextDateTime);
  660. limitNextTakeTime = reloadLocalDateTimeToLong(limitNextDateTime);
  661. } else if (model.getDispatchLeadTime() > 0) {
  662. nextTakeTime = reloadLocalDateTimeToLong(nextDateTime.minusMinutes(-model.getDispatchLeadTime()));
  663. limitNextTakeTime = reloadLocalDateTimeToLong(limitNextDateTime);
  664. } else if (model.getDispatchLeadTime() < 0) {
  665. nextTakeTime = reloadLocalDateTimeToLong(nextDateTime.minusMinutes(Math.abs(model.getDispatchLeadTime())));
  666. limitNextTakeTime = reloadLocalDateTimeToLong(limitNextDateTime);
  667. }
  668. }else{
  669. LocalTime localTime = LocalTime.parse(newList.get(0).getHandleStartTime(), DateTimeFormatter.ofPattern("HH:mm:ss"));
  670. LocalTime localTimeLimit = LocalTime.parse(model.getItemsList().stream().sorted(Comparator.comparing(DispatchCmdBatchItemNextTimeModel::getHandleStartTimeLimit))
  671. .collect(Collectors.toList()).get(0).getHandleStartTimeLimit(), DateTimeFormatter.ofPattern("HH:mm:ss"));
  672. nextDateTime = LocalDateTime.now()
  673. .withDayOfMonth(newJSONArray.getInteger(0));
  674. if (model.getDispatchLeadTime() == 0) {
  675. nextTakeTime = reloadLocalDateTimeToLong(nextDateTime.minusMonths(-1).withHour(localTime.getHour())
  676. .withMinute(localTime.getMinute())
  677. .withSecond(localTime.getSecond()));
  678. limitNextTakeTime = reloadLocalDateTimeToLong(nextDateTime.minusMonths(-1).withHour(localTimeLimit.getHour())
  679. .withMinute(localTimeLimit.getMinute())
  680. .withSecond(localTimeLimit.getSecond()));
  681. } else if (model.getDispatchLeadTime() > 0) {
  682. nextTakeTime = reloadLocalDateTimeToLong(nextDateTime.minusMonths(-1).withHour(localTime.getHour())
  683. .withMinute(localTime.getMinute())
  684. .withSecond(localTime.getSecond()).minusMinutes(-model.getDispatchLeadTime()));
  685. limitNextTakeTime = reloadLocalDateTimeToLong(nextDateTime.minusMonths(-1).withHour(localTimeLimit.getHour())
  686. .withMinute(localTimeLimit.getMinute())
  687. .withSecond(localTimeLimit.getSecond()));
  688. } else if (model.getDispatchLeadTime() < 0) {
  689. nextTakeTime = reloadLocalDateTimeToLong(nextDateTime.minusMonths(-1).withHour(localTime.getHour())
  690. .withMinute(localTime.getMinute())
  691. .withSecond(localTime.getSecond()).minusMinutes(Math.abs(model.getDispatchLeadTime())));
  692. limitNextTakeTime = reloadLocalDateTimeToLong(nextDateTime.minusMonths(-1).withHour(localTimeLimit.getHour())
  693. .withMinute(localTimeLimit.getMinute())
  694. .withSecond(localTimeLimit.getSecond()));
  695. }
  696. }
  697. }else if(model.getPlanType()==4){
  698. //TODO 年计划
  699. JSONArray newJSONArray = JSONArray.parseArray(model.getCycles()).stream().sorted(
  700. // 根据
  701. Comparator.comparing(
  702. e -> e.toString()
  703. )
  704. // 放开下面的注释,使用reversed()方法,就是降序 大到小
  705. // .reversed()
  706. ).collect(Collectors.toCollection(JSONArray::new));
  707. //TODO 先得到所有集合对应的当前周的所有符合条件的时间
  708. List<String> dateTimeStrings = new ArrayList<>();
  709. List<String> dateLimitTimeStrings = new ArrayList<>();//最小截止值
  710. for (Object obj:newJSONArray){
  711. String[] monthDays = obj.toString().split("-");
  712. LocalDateTime nowDate = LocalDateTime.now().withMonth(Integer.valueOf(monthDays[0]))
  713. .withDayOfMonth(Integer.valueOf(monthDays[1]));
  714. for (DispatchCmdBatchItemNextTimeModel item : newList){
  715. String[] times = item.getHandleStartTime().split(":");
  716. String[] timeLimits = item.getHandleStartTimeLimit().split(":");
  717. dateTimeStrings.add(nowDate.withHour(Integer.valueOf(times[0]))
  718. .withMinute(Integer.valueOf(times[1])).withSecond(Integer.valueOf(times[2])).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
  719. dateLimitTimeStrings.add(nowDate.withHour(Integer.valueOf(timeLimits[0]))
  720. .withMinute(Integer.valueOf(timeLimits[1])).withSecond(Integer.valueOf(timeLimits[2])).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
  721. }
  722. }
  723. LocalDateTime nextDateTime = findNextTime(dateTimeStrings,oldTm);
  724. LocalDateTime limitNextDateTime = nextDateTime!=null?LocalDateTime.parse(dateLimitTimeStrings.get(dateLimitTimeStrings.indexOf(nextDateTime
  725. .format(DateTimeFormatter.ofPattern(TimeTool.YEAR_MONTH_DAY_FORMAT))+" "+model.getItemsList().stream().sorted(Comparator.comparing(DispatchCmdBatchItemNextTimeModel::getHandleStartTimeLimit))
  726. .collect(Collectors.toList()).get(0).getHandleStartTimeLimit())),DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")):null;
  727. if(nextDateTime!=null){
  728. if (model.getDispatchLeadTime() == 0) {
  729. nextTakeTime = reloadLocalDateTimeToLong(nextDateTime);
  730. limitNextTakeTime = reloadLocalDateTimeToLong(limitNextDateTime);
  731. } else if (model.getDispatchLeadTime() > 0) {
  732. nextTakeTime = reloadLocalDateTimeToLong(nextDateTime.minusMinutes(-model.getDispatchLeadTime()));
  733. limitNextTakeTime = reloadLocalDateTimeToLong(limitNextDateTime);
  734. } else if (model.getDispatchLeadTime() < 0) {
  735. nextTakeTime = reloadLocalDateTimeToLong(nextDateTime.minusMinutes(Math.abs(model.getDispatchLeadTime())));
  736. limitNextTakeTime = reloadLocalDateTimeToLong(limitNextDateTime);
  737. }
  738. }else{
  739. LocalTime localTime = LocalTime.parse(newList.get(0).getHandleStartTime(), DateTimeFormatter.ofPattern("HH:mm:ss"));
  740. LocalTime localTimeLimit = LocalTime.parse(model.getItemsList().stream().sorted(Comparator.comparing(DispatchCmdBatchItemNextTimeModel::getHandleStartTimeLimit))
  741. .collect(Collectors.toList()).get(0).getHandleStartTimeLimit(), DateTimeFormatter.ofPattern("HH:mm:ss"));
  742. nextDateTime = LocalDateTime.now()
  743. .withMonth(Integer.valueOf(newJSONArray.get(0).toString().split("-")[0]))
  744. .withDayOfMonth(Integer.valueOf(newJSONArray.get(0).toString().split("-")[1]));
  745. if (model.getDispatchLeadTime() == 0) {
  746. nextTakeTime = reloadLocalDateTimeToLong(nextDateTime.minusYears(-1).withHour(localTime.getHour())
  747. .withMinute(localTime.getMinute())
  748. .withSecond(localTime.getSecond()));
  749. limitNextTakeTime = reloadLocalDateTimeToLong(nextDateTime.minusYears(-1).withHour(localTimeLimit.getHour())
  750. .withMinute(localTimeLimit.getMinute())
  751. .withSecond(localTimeLimit.getSecond()));
  752. } else if (model.getDispatchLeadTime() > 0) {
  753. nextTakeTime = reloadLocalDateTimeToLong(nextDateTime.minusYears(-1).withHour(localTime.getHour())
  754. .withMinute(localTime.getMinute())
  755. .withSecond(localTime.getSecond()).minusMinutes(-model.getDispatchLeadTime()));
  756. limitNextTakeTime = reloadLocalDateTimeToLong(nextDateTime.minusYears(-1).withHour(localTimeLimit.getHour())
  757. .withMinute(localTimeLimit.getMinute())
  758. .withSecond(localTimeLimit.getSecond()));
  759. } else if (model.getDispatchLeadTime() < 0) {
  760. nextTakeTime = reloadLocalDateTimeToLong(nextDateTime.minusYears(-1).withHour(localTime.getHour())
  761. .withMinute(localTime.getMinute())
  762. .withSecond(localTime.getSecond()).minusMinutes(-model.getDispatchLeadTime()));
  763. limitNextTakeTime = reloadLocalDateTimeToLong(nextDateTime.minusYears(-1).withHour(localTimeLimit.getHour())
  764. .withMinute(localTimeLimit.getMinute())
  765. .withSecond(localTimeLimit.getSecond()));
  766. }
  767. }
  768. }
  769. }
  770. map.put("nextTakeTime",nextTakeTime);
  771. map.put("limitNextTakeTime",limitNextTakeTime);
  772. return map;
  773. }
  774. //TODO 新增计划
  775. public static ResponseCode savePlan(JPDispatchPlanInfoSave oJsonParam){
  776. try{
  777. //TODO 根据计划类型计算计划的下次生效时间
  778. DispatchPlanInfoModel model = new DispatchPlanInfoModel();
  779. model.setPlanId(CommTool.genPlanInfoId());
  780. model.setPlanType(oJsonParam.getPlanType());
  781. model.setPlanStatus(oJsonParam.getPlanStatus());
  782. model.setTitle(oJsonParam.getTitle());
  783. model.setUrgentLevel(oJsonParam.getUrgentLevel());
  784. model.setDispatchRemark(oJsonParam.getDispatchRemark());
  785. model.setDispatchLeadTime(oJsonParam.getDispatchLeadTime());
  786. model.setCreatorId(oJsonParam.getCreatorId());
  787. model.setCreateTime(TimeTool.getCurMsUTC());
  788. model.setCycles(oJsonParam.getCycles());
  789. model.setZoneId(oJsonParam.getZoneId());
  790. //TODO 开始计算时间字段并设置
  791. Long lastTakeTime = 0L;
  792. Long nextTakeTime = 0L;//下一次生效时间
  793. Long limitNextTakeTime = 0L;//下一次生效截止时间
  794. DispatchPlanInfoNextTimeModel nextTimeModel = new DispatchPlanInfoNextTimeModel();
  795. nextTimeModel.setPlanType(oJsonParam.getPlanType());
  796. List<DispatchCmdBatchItemNextTimeModel> itemModels = new ArrayList<>();
  797. if(!CollectionUtils.isEmpty(oJsonParam.getItemsList())){
  798. for(JPDispatchCmdBatchItem jpItem:oJsonParam.getItemsList()){
  799. DispatchCmdBatchItemNextTimeModel dispatchCmdBatchItemNextTimeModel =new DispatchCmdBatchItemNextTimeModel();
  800. dispatchCmdBatchItemNextTimeModel.setHandleStartTime(jpItem.getHandleStartTime());
  801. dispatchCmdBatchItemNextTimeModel.setHandleStartTimeLimit(jpItem.getHandleEndTime());
  802. itemModels.add(dispatchCmdBatchItemNextTimeModel);
  803. }
  804. }
  805. nextTimeModel.setItemsList(itemModels);
  806. nextTimeModel.setDispatchLeadTime(oJsonParam.getDispatchLeadTime());
  807. nextTimeModel.setCycles(oJsonParam.getCycles());
  808. Map<String,Long> nextMap = returnNextTakeTime(nextTimeModel,null);
  809. nextTakeTime = nextMap.get("nextTakeTime");
  810. limitNextTakeTime = nextMap.get("limitNextTakeTime");
  811. model.setLastTakeTime(lastTakeTime);
  812. model.setNextTakeTime(nextTakeTime);
  813. model.setLimitNextTakeTime(limitNextTakeTime);
  814. model.setTakes(0);
  815. model.setErrors("");
  816. model.setSendway(oJsonParam.getSendway());
  817. model.setChufaRulsFlag(oJsonParam.getChufaRulsFlag());
  818. ResponseCode insertRes = getThisDBService().insertPlanInfoByCount(model,oJsonParam.getRulesList(),
  819. oJsonParam.getTagsList(),oJsonParam.getItemsList());
  820. return insertRes;
  821. // return null;
  822. }catch(Exception ex){
  823. LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_INFO, mStrClassName, mStrClassName
  824. ,String.format("insert planInfo errorMsg:%s end<====",
  825. ex.getLocalizedMessage()));
  826. return ResponseCode.RESULT_BAD;
  827. }
  828. }
  829. //TODO 修改计划增加线程锁
  830. public static ResponseCode updatePlanClock(JPDispatchPlanInfoUpdate oJsonParam){
  831. ResponseCode code = ResponseCode.RESULT_BAD;
  832. if (oJsonParam==null)
  833. return code;
  834. CountDownLatchEx latchEx = null;
  835. int nRetry = 3;
  836. do {
  837. try {
  838. latchEx = WODispatchPlanLockMgr.tryLatchForPlan(oJsonParam.getPlanId(), 20000);
  839. }catch (Exception e){
  840. latchEx = null;
  841. }
  842. if (latchEx != null){
  843. code = updatePlan(oJsonParam);
  844. break;
  845. }
  846. }while ((--nRetry) > 0);
  847. if (latchEx != null){
  848. latchEx.countDown();
  849. }else{
  850. code = updatePlan(oJsonParam);
  851. }
  852. return code;
  853. }
  854. //TODO 修改计划
  855. private static ResponseCode updatePlan(JPDispatchPlanInfoUpdate oJsonParam){
  856. try {
  857. //TODO 根据计划类型计算计划的下次生效时间
  858. //TODO 查询原计划是否还存在,若存在比对planType是否一致
  859. Map<String,Object> oldPlan = getThisDBService().getOne(oJsonParam.getPlanId());
  860. if(oldPlan==null){
  861. return ResponseCode.RESULT_REFERENCE_NOT_EXIST;
  862. }
  863. if(!oJsonParam.getPlanType().equals(Integer.valueOf(oldPlan.get("plan_type").toString()))){
  864. return ResponseCode.STATUS_ERROR_JSON_FORMAT;
  865. }
  866. //TODO 开始计算时间字段并设置
  867. Long nextTakeTime = 0L;//下一次生效时间
  868. Long limitNextTakeTime = 0L;//下一次生效时间
  869. DispatchPlanInfoNextTimeModel nextTimeModel = new DispatchPlanInfoNextTimeModel();
  870. nextTimeModel.setPlanType(oJsonParam.getPlanType());
  871. List<DispatchCmdBatchItemNextTimeModel> itemModels = new ArrayList<>();
  872. if(!CollectionUtils.isEmpty(oJsonParam.getItemsList())){
  873. for(JPDispatchCmdBatchItem jpItem:oJsonParam.getItemsList()){
  874. DispatchCmdBatchItemNextTimeModel dispatchCmdBatchItemNextTimeModel =new DispatchCmdBatchItemNextTimeModel();
  875. dispatchCmdBatchItemNextTimeModel.setHandleStartTime(jpItem.getHandleStartTime());
  876. dispatchCmdBatchItemNextTimeModel.setHandleStartTimeLimit(jpItem.getHandleEndTime());
  877. itemModels.add(dispatchCmdBatchItemNextTimeModel);
  878. }
  879. }
  880. nextTimeModel.setPlanType(oJsonParam.getPlanType());
  881. nextTimeModel.setItemsList(itemModels);
  882. nextTimeModel.setDispatchLeadTime(oJsonParam.getDispatchLeadTime());
  883. nextTimeModel.setCycles(oJsonParam.getCycles());
  884. Map<String,Long> nextMap = returnNextTakeTime(nextTimeModel,null);
  885. nextTakeTime = nextMap.get("nextTakeTime");
  886. limitNextTakeTime = nextMap.get("limitNextTakeTime");
  887. ResponseCode updateRes = getThisDBService().updatePlanInfoByCount(oJsonParam,nextTakeTime,limitNextTakeTime, oJsonParam.getRulesList(),
  888. oJsonParam.getTagsList(), oJsonParam.getItemsList());
  889. return updateRes;
  890. }catch(Exception ex){
  891. LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_INFO, mStrClassName, mStrClassName
  892. ,String.format("update planInfo errorMsg:%s end<====",
  893. ex.getLocalizedMessage()));
  894. return ResponseCode.RESULT_BAD;
  895. }
  896. }
  897. public static ResponseCode updatePlanStatus(JPDispatchPlanInfoUpdateStatus oJsonParam){
  898. try {
  899. //TODO 根据计划类型计算计划的下次生效时间
  900. //TODO 查询原计划是否还存在,若存在比对planType是否一致
  901. Map<String,Object> oldPlan = getThisDBService().getOne(oJsonParam.getPlanId());
  902. if(oldPlan==null||oldPlan.size()<=0){
  903. return ResponseCode.RESULT_REFERENCE_NOT_EXIST;
  904. }
  905. Map<String,Object> oldPlanUpWhere = new HashMap<>();
  906. oldPlanUpWhere.put("plan_id",oJsonParam.getPlanId());
  907. Map<String,Object> oldPlanUp = new HashMap<>();
  908. oldPlanUp.put("plan_status",oJsonParam.getPlanStatus());
  909. int code = getThisDBService().updateWiths(oldPlanUp,oldPlanUpWhere);
  910. return code>0?ResponseCode.RESULT_NORMAL:ResponseCode.RESULT_BAD;
  911. }catch(Exception ex){
  912. LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_INFO, mStrClassName, mStrClassName
  913. ,String.format("update planInfo errorMsg:%s end<====",
  914. ex.getLocalizedMessage()));
  915. return ResponseCode.RESULT_BAD;
  916. }
  917. }
  918. private static boolean isSameDay(long timestamp1, long timestamp2) {
  919. SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
  920. // 确保时区设置正确,以避免因夏令时导致的问题
  921. sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
  922. return sdf.format(new Date(timestamp1)).equals(sdf.format(new Date(timestamp2)));
  923. }
  924. //TODO 全量查询标签字典信息
  925. public static ResponseRes selectAllTags(){
  926. ResponseRes oRes = new ResponseRes();
  927. oRes.setRescode(ResponseCode.RESULT_BAD.toStrCode());
  928. oRes.setResmsg(ResponseCode.RESULT_BAD.toStrMsg());
  929. try{
  930. List<Map<String,Object>> map = getThisDBService().selectAllTags("","",new HashMap<>(),new HashMap<>()
  931. ,"","");
  932. if(map!=null||map.size()>0){
  933. oRes.setResdata(FastJsonUtil.toJSON(map,true));
  934. }
  935. oRes.setRescode(ResponseCode.RESULT_NORMAL.toStrCode());
  936. oRes.setResmsg(ResponseCode.RESULT_NORMAL.toStrMsg());
  937. return oRes;
  938. }catch (Exception ex){
  939. return oRes;
  940. }
  941. }
  942. }