WODispatchPlanTmDoBizFun.java 61 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022
  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("PLP29FC0FC6BFC01462QO")){
  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. LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_INFO
  251. , mStrClassName
  252. , mStrClassName
  253. , String.format("cmdCode {%s}"
  254. , code));
  255. return code;
  256. }
  257. public static void checkPlanForProduce(){
  258. long lCurTime = System.currentTimeMillis();
  259. Map<String, Object> mapSel = getThisDBService().totalWillProduceCounts(null
  260. , null
  261. , ""
  262. , String.format("and %s = %d and next_take_time > 0 and next_take_time <= %d"
  263. , WODispatchPlanInfoTable.R_INFO.STATUS
  264. , CommFieldStatus.ENABLE
  265. , lCurTime));
  266. if (mapSel != null && mapSel.size() > 0){
  267. WODispatchCheckTotal oTotal = FastJsonUtil.map2Obj(mapSel, WODispatchCheckTotal.class, true);
  268. if (oTotal != null && oTotal.getTotal() > 0){
  269. long curIndex = -1L;
  270. int limit = 50, offset = 0, realTotal = 0;
  271. while (curIndex < oTotal.getMaxIndex()){
  272. List<Map<String, Object>> arrDbTmp = getThisDBService().listAllWithsEx(WODispatchPlanInfoTable.R_INFO.TABLE
  273. , WODispatchPlanInfoTable.R_INFO.TOTAL_PRODUCE_FILED
  274. , limit
  275. , offset
  276. ,null
  277. ,null
  278. , WODispatchPlanInfoTable.R_INFO.TOTAL_PRODUCE_ORDER
  279. , String.format("and %s = %d and (id between %d and %d)"
  280. ,WODispatchPlanInfoTable.R_INFO.STATUS
  281. ,CommFieldStatus.ENABLE
  282. ,oTotal.getMinIndex()
  283. ,oTotal.getMaxIndex()));
  284. if (CommTool.listSize(arrDbTmp) <= 0)
  285. break;
  286. realTotal += arrDbTmp.size();
  287. offset = realTotal;
  288. List<WODispatchCheckBean> arrRes = FastJsonUtil.batchMap2Obj(arrDbTmp, WODispatchCheckBean.class, true);
  289. if (CommTool.listSize(arrRes) <= 0)
  290. continue;
  291. for (WODispatchCheckBean oItem:arrRes){
  292. if (oItem.getId() > curIndex)
  293. curIndex = oItem.getId();
  294. if (oItem.getStatus() != CommFieldStatus.ENABLE)
  295. continue;
  296. boolean bProduce = false;
  297. boolean bGenNext = false;
  298. if (oItem.getBatchTotal() <= 0 || oItem.getNextTakeTime() <= 0L){
  299. bGenNext = true;
  300. }else if (oItem.getNextTakeTime() <= lCurTime){
  301. bProduce = true;
  302. }
  303. if (bProduce){
  304. AsyncTaskQueueMgr.getInstance().postTaskData(TaskQueueDataTypeEx.ASYNC_PRODUCE_WO_DISPATCH_CMD, new CommUTMBean(oItem.getUid(), oItem.getNextTakeTime()));
  305. }else if (bGenNext){
  306. //do nothing
  307. }
  308. }
  309. }
  310. }
  311. }
  312. }
  313. //TODO 分页查询计划
  314. //查询·分页
  315. public static PageRecordRes<DispatchPlanInfoSSModel> queryPageList(JPDispatchPlanInfoSS jsonParam){
  316. PageRecordRes<DispatchPlanInfoSSModel> oRes = new PageRecordRes<>();
  317. if (jsonParam == null)
  318. return oRes;
  319. final String lilterExtend = jsonParam.genQueryExtend();
  320. Map<String,Object> andWheres = new HashMap<>();
  321. if(jsonParam.getPlanType()!=null){
  322. andWheres.put("plan_type", jsonParam.getPlanType());
  323. }
  324. if(jsonParam.getPlanStatus()!=null){
  325. andWheres.put("plan_status", jsonParam.getPlanStatus());
  326. }
  327. if(jsonParam.getZoneId()!=null){
  328. andWheres.put("zone_id", jsonParam.getZoneId());
  329. }
  330. String sql = "";
  331. if(jsonParam.getDownFlag()!=null) {
  332. if(jsonParam.getDownFlag()==0) {
  333. sql += " AND " + WODispatchPlanInfoTable.R_INFO.LAST_TAKE_TIME + " > 0 ";
  334. }else{
  335. sql += " AND " + WODispatchPlanInfoTable.R_INFO.LAST_TAKE_TIME + " = 0 ";
  336. }
  337. }
  338. int nTotals = getThisDBService().totalCountsEx("", andWheres, null, lilterExtend+sql);
  339. if (nTotals > 0){
  340. List<Map<String,Object>> dataList = getThisDBService().listAllWithsEx("","",
  341. jsonParam.getLimit(),
  342. jsonParam.getOffset(),
  343. andWheres,
  344. null,
  345. WODispatchPlanInfoTable.R_INFO.CREATE_TIME+" DESC",
  346. lilterExtend+sql);
  347. if(dataList==null){
  348. oRes.setCode(ResponseCode.RESULT_BAD.toInt());
  349. }else{
  350. List<DispatchPlanInfoSSModel> ssInfoModels = dataList.isEmpty()?new ArrayList<>():
  351. FastJsonUtil.batchMap2Obj(dataList,DispatchPlanInfoSSModel.class,true);
  352. oRes.setCode(ResponseCode.RESULT_NORMAL.toInt());
  353. oRes.setTotal(nTotals);
  354. oRes.setData(ssInfoModels);
  355. }
  356. }
  357. return oRes;
  358. }
  359. //TODO 查询详情信息
  360. public static ResponseRes selectPlanInfoView(JPDispatchPlanInfoDetailsSS oJsonParam){
  361. ResponseRes oRes = new ResponseRes();
  362. oRes.setRescode(ResponseCode.RESULT_BAD.toStrCode());
  363. oRes.setResmsg(ResponseCode.RESULT_BAD.toStrMsg());
  364. if(StringUtils.isEmpty(oJsonParam)||StringUtils.isEmpty(oJsonParam.getPlanId())){
  365. oRes.setRescode(ResponseCode.STATUS_ERROR_JSON_FORMAT.toStrCode());
  366. oRes.setResmsg(ResponseCode.STATUS_ERROR_JSON_FORMAT.toStrMsg());
  367. return oRes;
  368. }
  369. try{
  370. Map<String,Object> map = getThisDBService().getOne(oJsonParam.getPlanId());
  371. if(map!=null||map.size()>0){
  372. DispatchPlanInfoDetailsModel model = FastJsonUtil.map2Obj(map,DispatchPlanInfoDetailsModel.class,true);
  373. if (model!=null) {
  374. //TODO 查询相关联规则和标签
  375. Map<String, Object> andWheresRuls = new HashMap<>();
  376. andWheresRuls.put("plan_id", oJsonParam.getPlanId());
  377. List<Map<String,Object>> rulsModels = getThisDBService().selectAllRuls("","",
  378. andWheresRuls,new HashMap<>(),"","");
  379. Map<String, Object> andWheresTags = new HashMap<>();
  380. andWheresTags.put("plan_id", oJsonParam.getPlanId());
  381. List<Map<String,Object>> tagModels = getThisDBService().selectAllPlanTags("","",
  382. andWheresTags,new HashMap<>(),"","");
  383. //TODO 查询相关联的排班项信息
  384. Map<String, Object> andWheres = new HashMap<>();
  385. andWheres.put("plan_id", oJsonParam.getPlanId());
  386. List<DispatchCmdBatchItemModel> itemModels = getItemDBService()
  387. .listAllWithsExByDispoal("", "", andWheres, new HashMap<>(), "handle_start_time", "");
  388. if(!CollectionUtils.isEmpty(rulsModels)){
  389. model.setRulsModels(FastJsonUtil.batchMap2Obj(rulsModels,DispatchPlanInfoRuleModel.class,true));
  390. }
  391. if(!CollectionUtils.isEmpty(tagModels)){
  392. model.setTagsList(FastJsonUtil.batchMap2Obj(tagModels,DispatchPlanInfoTagsModel.class,true));
  393. }
  394. if(!CollectionUtils.isEmpty(itemModels)) {
  395. model.setItemModels(itemModels);
  396. }
  397. oRes.setResdata(FastJsonUtil.toJSON(model));
  398. }
  399. }
  400. oRes.setRescode(ResponseCode.RESULT_NORMAL.toStrCode());
  401. oRes.setResmsg(ResponseCode.RESULT_NORMAL.toStrMsg());
  402. return oRes;
  403. }catch (Exception ex){
  404. return oRes;
  405. }
  406. }
  407. //判断是否在时间区间内并且取出最接近当前时间的大于它的时间
  408. //nextType 0 周 1 月 2 年
  409. public static LocalDateTime findNextTime(List<String> dateTimeStrings,LocalDateTime oldTm){
  410. LocalDateTime now = oldTm==null?LocalDateTime.now():oldTm; // 获取当前日期时间
  411. System.out.println("Current DateTime: " + now);
  412. DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
  413. // 转换为LocalDateTime集合
  414. List<LocalDateTime> dateTimes = new ArrayList<>();
  415. for (String dtStr : dateTimeStrings) {
  416. dateTimes.add(LocalDateTime.parse(dtStr,formatter));
  417. }
  418. // 找到最接近且大于当前时间的日期时间
  419. // 仅考虑大于当前时间的日期时间
  420. LocalDateTime closestFutureDateTime = dateTimes.stream()
  421. .filter(dateTime -> dateTime.isAfter(now))
  422. .min((dateTime1, dateTime2) -> Long.compare(
  423. java.time.temporal.ChronoUnit.MINUTES.between(now, dateTime1),
  424. java.time.temporal.ChronoUnit.MINUTES.between(now, dateTime2)))
  425. .orElse(null); // 如果没有找到,返回null
  426. //TODO 输出结果 ,如果为空说明在集合中没有找到符合条件的时间, 则直接取下一个单位的最小时间即可
  427. return closestFutureDateTime;
  428. }
  429. //LocalDateTime转UTC时间戳
  430. public static Long reloadLocalDateTimeToLong(LocalDateTime localDateTime){
  431. // 转换为毫秒时间戳
  432. long timestampMillis = TimeTool.convertDateStr2UTC(localDateTime.format(DateTimeFormatter.ofPattern(TimeTool.TIMESTAMP_FORMAT)));
  433. return timestampMillis;
  434. }
  435. //TODO 公用计算下次生效时间的方法
  436. //TODO 分是否排班
  437. //TODO oldTm主要为了再派单时比对
  438. public static Map<String,Long> returnNextTakeTime(DispatchPlanInfoNextTimeModel model,LocalDateTime oldTm){
  439. Map<String,Long> map = new HashMap<>();
  440. Long nextTakeTime = 0L;
  441. Long limitNextTakeTime = 0L;
  442. map.put("nextTakeTime",nextTakeTime);
  443. map.put("limitNextTakeTime",limitNextTakeTime);
  444. map.put("ifRestNextTakeTime",0L);//是否将newTextTakeTime更新到 plan中 0否, 1是
  445. if(!CollectionUtils.isEmpty(model.getItemsList())){
  446. List<DispatchCmdBatchItemNextTimeModel> newList = model.getItemsList().stream()
  447. .sorted(Comparator.comparing(DispatchCmdBatchItemNextTimeModel::getHandleStartTime))
  448. .collect(Collectors.toList());
  449. if(model.getPlanType()==0) {
  450. //TODO 临时计划
  451. Instant nowTime = Instant.ofEpochMilli(
  452. TimeTool.convertDateStr2UTC
  453. (
  454. JSONArray.parseArray(model.getCycles()).getString(0)
  455. +" "+
  456. newList.get(0).getHandleStartTime()));
  457. Instant endTime = Instant.ofEpochMilli(
  458. TimeTool.convertDateStr2UTC
  459. (
  460. JSONArray.parseArray(model.getCycles()).getString(0)
  461. +" "+
  462. model.getItemsList().stream().sorted(Comparator.comparing(DispatchCmdBatchItemNextTimeModel::getHandleStartTimeLimit))
  463. .collect(Collectors.toList()).get(0).getHandleStartTimeLimit()));
  464. if(model.getDispatchLeadTime()==0) {
  465. nextTakeTime = nowTime.toEpochMilli();
  466. limitNextTakeTime = endTime.toEpochMilli();
  467. }else if(model.getDispatchLeadTime()>0){
  468. nextTakeTime = nowTime.minus(-model.getDispatchLeadTime(), ChronoUnit.MINUTES).toEpochMilli();
  469. limitNextTakeTime = endTime.toEpochMilli();
  470. }else if(model.getDispatchLeadTime()<0){
  471. nextTakeTime = nowTime.minus(Math.abs(model.getDispatchLeadTime()), ChronoUnit.MINUTES).toEpochMilli();
  472. limitNextTakeTime = endTime.toEpochMilli();
  473. }
  474. //TODO 如果当前时间与下次生效时间是同一天,但是时刻已经是过去时,那么则返回失败信息
  475. Long nowTimeLong = TimeTool.getCurMsUTC();
  476. if(nowTimeLong>nextTakeTime&&nowTimeLong>limitNextTakeTime&&isSameDay(nowTimeLong,nextTakeTime)){
  477. throw new RuntimeException(ResponseCode.STATUS_ERROR_JSON_FORMAT.toStrCode());
  478. }
  479. }else if(model.getPlanType()==1){
  480. //TODO 日计划
  481. //TODO 日计划时,如果oTm不等于空,那么说明不能再用添加或修改时的cylse
  482. model.setCycles("[\"" + TimeTool.convertUTC2DateStr(TimeTool.getCurMsUTC(), "yyyy-MM-dd") + "\"]");
  483. boolean isToDay = false;//生效时间是否小于等于当前时刻
  484. for (DispatchCmdBatchItemNextTimeModel item:newList){
  485. Instant nowTime = Instant.ofEpochMilli(
  486. TimeTool.convertDateStr2UTC
  487. (JSONArray.parseArray(model.getCycles()).getString(0)
  488. +" "+item.getHandleStartTime()));
  489. LocalDateTime dateTime = nowTime.atZone(ZoneId.systemDefault()).toLocalDateTime();
  490. Instant endTime = Instant.ofEpochMilli(
  491. TimeTool.convertDateStr2UTC
  492. (
  493. JSONArray.parseArray(model.getCycles()).getString(0)
  494. +" "+
  495. model.getItemsList().stream().sorted(Comparator.comparing(DispatchCmdBatchItemNextTimeModel::getHandleStartTimeLimit))
  496. .collect(Collectors.toList()).get(0).getHandleStartTimeLimit()));
  497. LocalDateTime dateTime1 = endTime.atZone(ZoneId.systemDefault()).toLocalDateTime();
  498. LocalDateTime dateTimeNow = Instant.now().atZone(ZoneId.systemDefault()).toLocalDateTime();
  499. if(Instant.now().isBefore(nowTime)||Instant.now().equals(nowTime)){
  500. isToDay = true;
  501. if(model.getDispatchLeadTime()==0) {
  502. nextTakeTime = nowTime.toEpochMilli();
  503. limitNextTakeTime = endTime.toEpochMilli();
  504. }else if(model.getDispatchLeadTime()>0){
  505. nextTakeTime = nowTime.minus(-model.getDispatchLeadTime(), ChronoUnit.MINUTES).toEpochMilli();
  506. limitNextTakeTime = endTime.toEpochMilli();
  507. }else if(model.getDispatchLeadTime()<0){
  508. nextTakeTime = nowTime.minus(Math.abs(model.getDispatchLeadTime()), ChronoUnit.MINUTES).toEpochMilli();
  509. limitNextTakeTime = endTime.toEpochMilli();
  510. }
  511. break;
  512. }
  513. }
  514. if(!isToDay){
  515. //说明当天并没有满足条件的时刻,那么在日期上加一天,并且用最小时刻
  516. if(model.getDispatchLeadTime()==0) {
  517. nextTakeTime = Instant.ofEpochMilli(
  518. TimeTool.convertDateStr2UTC
  519. (JSONArray.parseArray(model.getCycles()).getString(0)
  520. +" "+newList.get(0).getHandleStartTime())).plus(Duration.ofDays(1)).toEpochMilli();
  521. limitNextTakeTime = Instant.ofEpochMilli(
  522. TimeTool.convertDateStr2UTC
  523. (JSONArray.parseArray(model.getCycles()).getString(0)
  524. +" "+model.getItemsList().stream().sorted(Comparator.comparing(DispatchCmdBatchItemNextTimeModel::getHandleStartTimeLimit))
  525. .collect(Collectors.toList()).get(0).getHandleStartTimeLimit())).plus(Duration.ofDays(1)).toEpochMilli();
  526. }else if(model.getDispatchLeadTime()>0){
  527. nextTakeTime = Instant.ofEpochMilli(
  528. TimeTool.convertDateStr2UTC
  529. (JSONArray.parseArray(model.getCycles()).getString(0)
  530. +" "+newList.get(0).getHandleStartTime())).plus(Duration.ofDays(1)).minus(-model.getDispatchLeadTime(), ChronoUnit.MINUTES).toEpochMilli();
  531. limitNextTakeTime = Instant.ofEpochMilli(
  532. TimeTool.convertDateStr2UTC
  533. (JSONArray.parseArray(model.getCycles()).getString(0)
  534. +" "+model.getItemsList().stream().sorted(Comparator.comparing(DispatchCmdBatchItemNextTimeModel::getHandleStartTimeLimit))
  535. .collect(Collectors.toList()).get(0).getHandleStartTimeLimit())).plus(Duration.ofDays(1)).toEpochMilli();
  536. }else if(model.getDispatchLeadTime()<0){
  537. nextTakeTime = Instant.ofEpochMilli(
  538. TimeTool.convertDateStr2UTC
  539. (JSONArray.parseArray(model.getCycles()).getString(0)
  540. +" "+newList.get(0).getHandleStartTime())).plus(Duration.ofDays(1)).minus(Math.abs(model.getDispatchLeadTime()), ChronoUnit.MINUTES).toEpochMilli();
  541. limitNextTakeTime = Instant.ofEpochMilli(
  542. TimeTool.convertDateStr2UTC
  543. (JSONArray.parseArray(model.getCycles()).getString(0)
  544. +" "+model.getItemsList().stream().sorted(Comparator.comparing(DispatchCmdBatchItemNextTimeModel::getHandleStartTimeLimit))
  545. .collect(Collectors.toList()).get(0).getHandleStartTimeLimit())).plus(Duration.ofDays(1)).toEpochMilli();
  546. }
  547. }
  548. //TODO 如果当前时间大于生效时间,说明生效时间过期,则加一天
  549. LocalDateTime localNext = LocalDateTime.ofInstant(Instant.ofEpochMilli(nextTakeTime), ZoneId.systemDefault())
  550. .minusMinutes(model.getDispatchLeadTime());
  551. if(limitNextTakeTime<TimeTool.getCurMsUTC()
  552. ||(nextTakeTime<=TimeTool.getCurMsUTC()&&limitNextTakeTime<TimeTool.getCurMsUTC())){
  553. nextTakeTime = Instant.ofEpochMilli(nextTakeTime)
  554. .plus(1, ChronoUnit.DAYS).toEpochMilli();
  555. limitNextTakeTime = Instant.ofEpochMilli(limitNextTakeTime).toEpochMilli();
  556. }else if(oldTm!=null&&(localNext
  557. .isBefore(oldTm)||localNext.isEqual(oldTm))
  558. ){
  559. //TODO 连续时需考虑
  560. //TODO 如果传递了对比值, 则说明当前计算的时间与old不符合条件,则再加一算一次
  561. nextTakeTime = oldTm.minusDays(-1).minusMinutes(-model.getDispatchLeadTime())
  562. .atZone(ZoneId.systemDefault())
  563. .toInstant()
  564. .toEpochMilli();
  565. limitNextTakeTime = Instant.ofEpochMilli(limitNextTakeTime).plus(1, ChronoUnit.DAYS).toEpochMilli();
  566. map.put("ifRestNextTakeTime",1L);
  567. }
  568. }else if(model.getPlanType()==2){
  569. //TODO 周计划
  570. //TODO 先取周期值里最小的数,新集合里最小的值就是最早的周几数
  571. JSONArray newJSONArray = JSONArray.parseArray(model.getCycles()).stream().sorted(
  572. // 根据
  573. Comparator.comparingLong(
  574. e -> Long.valueOf(e.toString())
  575. )
  576. // 放开下面的注释,使用reversed()方法,就是降序 大到小
  577. // .reversed()
  578. ).collect(Collectors.toCollection(JSONArray::new));
  579. //TODO 先得到所有集合对应的当前周的所有符合条件的时间
  580. List<String> dateTimeStrings = new ArrayList<>();
  581. List<String> dateLimitTimeStrings = new ArrayList<>();//最小截止值
  582. for (Object obj:newJSONArray){
  583. LocalDateTime nowDate = LocalDateTime.now().with(DayOfWeek.of(Integer.valueOf(obj.toString())));
  584. for (DispatchCmdBatchItemNextTimeModel item : newList){
  585. String[] times = item.getHandleStartTime().split(":");
  586. String[] timeLimits = item.getHandleStartTimeLimit().split(":");
  587. dateTimeStrings.add(nowDate.withHour(Integer.valueOf(times[0]))
  588. .withMinute(Integer.valueOf(times[1])).withSecond(Integer.valueOf(times[2])).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
  589. dateLimitTimeStrings.add(nowDate.withHour(Integer.valueOf(timeLimits[0]))
  590. .withMinute(Integer.valueOf(timeLimits[1])).withSecond(Integer.valueOf(timeLimits[2])).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
  591. }
  592. }
  593. LocalDateTime nextDateTime = findNextTime(dateTimeStrings,oldTm);
  594. LocalDateTime limitNextDateTime = nextDateTime!=null?LocalDateTime.parse(dateLimitTimeStrings.get(dateLimitTimeStrings.indexOf(nextDateTime
  595. .format(DateTimeFormatter.ofPattern(TimeTool.YEAR_MONTH_DAY_FORMAT))
  596. +" "+
  597. model.getItemsList().stream().sorted(Comparator.comparing(DispatchCmdBatchItemNextTimeModel::getHandleStartTimeLimit))
  598. .collect(Collectors.toList()).get(0).getHandleStartTimeLimit())),DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")):null;
  599. if(nextDateTime!=null){
  600. if (model.getDispatchLeadTime() == 0) {
  601. nextTakeTime = reloadLocalDateTimeToLong(nextDateTime);
  602. limitNextTakeTime = reloadLocalDateTimeToLong(limitNextDateTime);
  603. } else if (model.getDispatchLeadTime() > 0) {
  604. nextTakeTime = reloadLocalDateTimeToLong(nextDateTime.minusMinutes(-model.getDispatchLeadTime()));
  605. limitNextTakeTime = reloadLocalDateTimeToLong(limitNextDateTime);
  606. } else if (model.getDispatchLeadTime() < 0) {
  607. nextTakeTime = reloadLocalDateTimeToLong(nextDateTime.minusMinutes(Math.abs(model.getDispatchLeadTime())));
  608. limitNextTakeTime = reloadLocalDateTimeToLong(limitNextDateTime);
  609. }
  610. }else{
  611. LocalTime localTime = LocalTime.parse(newList.get(0).getHandleStartTime(), DateTimeFormatter.ofPattern("HH:mm:ss"));
  612. LocalTime localTimeLimit = LocalTime.parse(model.getItemsList().stream().sorted(Comparator.comparing(DispatchCmdBatchItemNextTimeModel::getHandleStartTimeLimit))
  613. .collect(Collectors.toList()).get(0).getHandleStartTimeLimit(), DateTimeFormatter.ofPattern("HH:mm:ss"));
  614. nextDateTime = LocalDateTime.now()
  615. .with(DayOfWeek.of(Integer.valueOf(newJSONArray.get(0).toString())));
  616. if (model.getDispatchLeadTime() == 0) {
  617. nextTakeTime = reloadLocalDateTimeToLong(nextDateTime.minusWeeks(-1).withHour(localTime.getHour())
  618. .withMinute(localTime.getMinute())
  619. .withSecond(localTime.getSecond()));
  620. limitNextTakeTime = reloadLocalDateTimeToLong(nextDateTime.minusWeeks(-1).withHour(localTimeLimit.getHour())
  621. .withMinute(localTimeLimit.getMinute())
  622. .withSecond(localTimeLimit.getSecond()));
  623. } else if (model.getDispatchLeadTime() > 0) {
  624. nextTakeTime = reloadLocalDateTimeToLong(nextDateTime.minusWeeks(-1).withHour(localTime.getHour())
  625. .withMinute(localTime.getMinute())
  626. .withSecond(localTime.getSecond()));
  627. limitNextTakeTime = reloadLocalDateTimeToLong(nextDateTime.minusWeeks(-1).withHour(localTimeLimit.getHour())
  628. .withMinute(localTimeLimit.getMinute())
  629. .withSecond(localTimeLimit.getSecond()).minusMinutes(-model.getDispatchLeadTime()));
  630. } else if (model.getDispatchLeadTime() < 0) {
  631. nextTakeTime = reloadLocalDateTimeToLong(nextDateTime.minusWeeks(-1).withHour(localTime.getHour())
  632. .withMinute(localTime.getMinute())
  633. .withSecond(localTime.getSecond()).minusMinutes(Math.abs(model.getDispatchLeadTime())));
  634. limitNextTakeTime = reloadLocalDateTimeToLong(nextDateTime.minusWeeks(-1).withHour(localTimeLimit.getHour())
  635. .withMinute(localTimeLimit.getMinute())
  636. .withSecond(localTimeLimit.getSecond()));
  637. }
  638. }
  639. }else if(model.getPlanType()==3){
  640. //TODO 月计划
  641. JSONArray newJSONArray = JSONArray.parseArray(model.getCycles()).stream().sorted(
  642. // 根据
  643. Comparator.comparingLong(
  644. e -> Long.valueOf(e.toString())
  645. )
  646. // 放开下面的注释,使用reversed()方法,就是降序 大到小
  647. // .reversed()
  648. ).collect(Collectors.toCollection(JSONArray::new));
  649. //TODO 先得到所有集合对应的当前月的所有符合条件的时间
  650. List<String> dateTimeStrings = new ArrayList<>();
  651. List<String> dateLimitTimeStrings = new ArrayList<>();//最小截止值
  652. for (Object obj:newJSONArray){
  653. LocalDateTime nowDate = LocalDateTime.now().withDayOfMonth(Integer.valueOf(obj.toString()));
  654. for (DispatchCmdBatchItemNextTimeModel item : newList){
  655. String[] times = item.getHandleStartTime().split(":");
  656. String[] timeLimits = item.getHandleStartTimeLimit().split(":");
  657. dateTimeStrings.add(nowDate.withHour(Integer.valueOf(times[0]))
  658. .withMinute(Integer.valueOf(times[1])).withSecond(Integer.valueOf(times[2])).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
  659. dateLimitTimeStrings.add(nowDate.withHour(Integer.valueOf(timeLimits[0]))
  660. .withMinute(Integer.valueOf(timeLimits[1])).withSecond(Integer.valueOf(timeLimits[2])).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
  661. }
  662. }
  663. LocalDateTime nextDateTime = findNextTime(dateTimeStrings,oldTm);
  664. LocalDateTime limitNextDateTime = nextDateTime!=null?LocalDateTime.parse(dateLimitTimeStrings.get(dateLimitTimeStrings.indexOf(nextDateTime
  665. .format(DateTimeFormatter.ofPattern(TimeTool.YEAR_MONTH_DAY_FORMAT))+" "+model.getItemsList().stream().sorted(Comparator.comparing(DispatchCmdBatchItemNextTimeModel::getHandleStartTimeLimit))
  666. .collect(Collectors.toList()).get(0).getHandleStartTimeLimit())),DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")):null;
  667. if(nextDateTime!=null){
  668. if (model.getDispatchLeadTime() == 0) {
  669. nextTakeTime = reloadLocalDateTimeToLong(nextDateTime);
  670. limitNextTakeTime = reloadLocalDateTimeToLong(limitNextDateTime);
  671. } else if (model.getDispatchLeadTime() > 0) {
  672. nextTakeTime = reloadLocalDateTimeToLong(nextDateTime.minusMinutes(-model.getDispatchLeadTime()));
  673. limitNextTakeTime = reloadLocalDateTimeToLong(limitNextDateTime);
  674. } else if (model.getDispatchLeadTime() < 0) {
  675. nextTakeTime = reloadLocalDateTimeToLong(nextDateTime.minusMinutes(Math.abs(model.getDispatchLeadTime())));
  676. limitNextTakeTime = reloadLocalDateTimeToLong(limitNextDateTime);
  677. }
  678. }else{
  679. LocalTime localTime = LocalTime.parse(newList.get(0).getHandleStartTime(), DateTimeFormatter.ofPattern("HH:mm:ss"));
  680. LocalTime localTimeLimit = LocalTime.parse(model.getItemsList().stream().sorted(Comparator.comparing(DispatchCmdBatchItemNextTimeModel::getHandleStartTimeLimit))
  681. .collect(Collectors.toList()).get(0).getHandleStartTimeLimit(), DateTimeFormatter.ofPattern("HH:mm:ss"));
  682. nextDateTime = LocalDateTime.now()
  683. .withDayOfMonth(newJSONArray.getInteger(0));
  684. if (model.getDispatchLeadTime() == 0) {
  685. nextTakeTime = reloadLocalDateTimeToLong(nextDateTime.minusMonths(-1).withHour(localTime.getHour())
  686. .withMinute(localTime.getMinute())
  687. .withSecond(localTime.getSecond()));
  688. limitNextTakeTime = reloadLocalDateTimeToLong(nextDateTime.minusMonths(-1).withHour(localTimeLimit.getHour())
  689. .withMinute(localTimeLimit.getMinute())
  690. .withSecond(localTimeLimit.getSecond()));
  691. } else if (model.getDispatchLeadTime() > 0) {
  692. nextTakeTime = reloadLocalDateTimeToLong(nextDateTime.minusMonths(-1).withHour(localTime.getHour())
  693. .withMinute(localTime.getMinute())
  694. .withSecond(localTime.getSecond()).minusMinutes(-model.getDispatchLeadTime()));
  695. limitNextTakeTime = reloadLocalDateTimeToLong(nextDateTime.minusMonths(-1).withHour(localTimeLimit.getHour())
  696. .withMinute(localTimeLimit.getMinute())
  697. .withSecond(localTimeLimit.getSecond()));
  698. } else if (model.getDispatchLeadTime() < 0) {
  699. nextTakeTime = reloadLocalDateTimeToLong(nextDateTime.minusMonths(-1).withHour(localTime.getHour())
  700. .withMinute(localTime.getMinute())
  701. .withSecond(localTime.getSecond()).minusMinutes(Math.abs(model.getDispatchLeadTime())));
  702. limitNextTakeTime = reloadLocalDateTimeToLong(nextDateTime.minusMonths(-1).withHour(localTimeLimit.getHour())
  703. .withMinute(localTimeLimit.getMinute())
  704. .withSecond(localTimeLimit.getSecond()));
  705. }
  706. }
  707. }else if(model.getPlanType()==4){
  708. //TODO 年计划
  709. JSONArray newJSONArray = JSONArray.parseArray(model.getCycles()).stream().sorted(
  710. // 根据
  711. Comparator.comparing(
  712. e -> e.toString()
  713. )
  714. // 放开下面的注释,使用reversed()方法,就是降序 大到小
  715. // .reversed()
  716. ).collect(Collectors.toCollection(JSONArray::new));
  717. //TODO 先得到所有集合对应的当前周的所有符合条件的时间
  718. List<String> dateTimeStrings = new ArrayList<>();
  719. List<String> dateLimitTimeStrings = new ArrayList<>();//最小截止值
  720. for (Object obj:newJSONArray){
  721. String[] monthDays = obj.toString().split("-");
  722. LocalDateTime nowDate = LocalDateTime.now().withMonth(Integer.valueOf(monthDays[0]))
  723. .withDayOfMonth(Integer.valueOf(monthDays[1]));
  724. for (DispatchCmdBatchItemNextTimeModel item : newList){
  725. String[] times = item.getHandleStartTime().split(":");
  726. String[] timeLimits = item.getHandleStartTimeLimit().split(":");
  727. dateTimeStrings.add(nowDate.withHour(Integer.valueOf(times[0]))
  728. .withMinute(Integer.valueOf(times[1])).withSecond(Integer.valueOf(times[2])).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
  729. dateLimitTimeStrings.add(nowDate.withHour(Integer.valueOf(timeLimits[0]))
  730. .withMinute(Integer.valueOf(timeLimits[1])).withSecond(Integer.valueOf(timeLimits[2])).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
  731. }
  732. }
  733. LocalDateTime nextDateTime = findNextTime(dateTimeStrings,oldTm);
  734. LocalDateTime limitNextDateTime = nextDateTime!=null?LocalDateTime.parse(dateLimitTimeStrings.get(dateLimitTimeStrings.indexOf(nextDateTime
  735. .format(DateTimeFormatter.ofPattern(TimeTool.YEAR_MONTH_DAY_FORMAT))+" "+model.getItemsList().stream().sorted(Comparator.comparing(DispatchCmdBatchItemNextTimeModel::getHandleStartTimeLimit))
  736. .collect(Collectors.toList()).get(0).getHandleStartTimeLimit())),DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")):null;
  737. if(nextDateTime!=null){
  738. if (model.getDispatchLeadTime() == 0) {
  739. nextTakeTime = reloadLocalDateTimeToLong(nextDateTime);
  740. limitNextTakeTime = reloadLocalDateTimeToLong(limitNextDateTime);
  741. } else if (model.getDispatchLeadTime() > 0) {
  742. nextTakeTime = reloadLocalDateTimeToLong(nextDateTime.minusMinutes(-model.getDispatchLeadTime()));
  743. limitNextTakeTime = reloadLocalDateTimeToLong(limitNextDateTime);
  744. } else if (model.getDispatchLeadTime() < 0) {
  745. nextTakeTime = reloadLocalDateTimeToLong(nextDateTime.minusMinutes(Math.abs(model.getDispatchLeadTime())));
  746. limitNextTakeTime = reloadLocalDateTimeToLong(limitNextDateTime);
  747. }
  748. }else{
  749. LocalTime localTime = LocalTime.parse(newList.get(0).getHandleStartTime(), DateTimeFormatter.ofPattern("HH:mm:ss"));
  750. LocalTime localTimeLimit = LocalTime.parse(model.getItemsList().stream().sorted(Comparator.comparing(DispatchCmdBatchItemNextTimeModel::getHandleStartTimeLimit))
  751. .collect(Collectors.toList()).get(0).getHandleStartTimeLimit(), DateTimeFormatter.ofPattern("HH:mm:ss"));
  752. nextDateTime = LocalDateTime.now()
  753. .withMonth(Integer.valueOf(newJSONArray.get(0).toString().split("-")[0]))
  754. .withDayOfMonth(Integer.valueOf(newJSONArray.get(0).toString().split("-")[1]));
  755. if (model.getDispatchLeadTime() == 0) {
  756. nextTakeTime = reloadLocalDateTimeToLong(nextDateTime.minusYears(-1).withHour(localTime.getHour())
  757. .withMinute(localTime.getMinute())
  758. .withSecond(localTime.getSecond()));
  759. limitNextTakeTime = reloadLocalDateTimeToLong(nextDateTime.minusYears(-1).withHour(localTimeLimit.getHour())
  760. .withMinute(localTimeLimit.getMinute())
  761. .withSecond(localTimeLimit.getSecond()));
  762. } else if (model.getDispatchLeadTime() > 0) {
  763. nextTakeTime = reloadLocalDateTimeToLong(nextDateTime.minusYears(-1).withHour(localTime.getHour())
  764. .withMinute(localTime.getMinute())
  765. .withSecond(localTime.getSecond()).minusMinutes(-model.getDispatchLeadTime()));
  766. limitNextTakeTime = reloadLocalDateTimeToLong(nextDateTime.minusYears(-1).withHour(localTimeLimit.getHour())
  767. .withMinute(localTimeLimit.getMinute())
  768. .withSecond(localTimeLimit.getSecond()));
  769. } else if (model.getDispatchLeadTime() < 0) {
  770. nextTakeTime = reloadLocalDateTimeToLong(nextDateTime.minusYears(-1).withHour(localTime.getHour())
  771. .withMinute(localTime.getMinute())
  772. .withSecond(localTime.getSecond()).minusMinutes(-model.getDispatchLeadTime()));
  773. limitNextTakeTime = reloadLocalDateTimeToLong(nextDateTime.minusYears(-1).withHour(localTimeLimit.getHour())
  774. .withMinute(localTimeLimit.getMinute())
  775. .withSecond(localTimeLimit.getSecond()));
  776. }
  777. }
  778. }
  779. }
  780. map.put("nextTakeTime",nextTakeTime);
  781. map.put("limitNextTakeTime",limitNextTakeTime);
  782. return map;
  783. }
  784. //TODO 新增计划
  785. public static ResponseCode savePlan(JPDispatchPlanInfoSave oJsonParam){
  786. try{
  787. //TODO 根据计划类型计算计划的下次生效时间
  788. DispatchPlanInfoModel model = new DispatchPlanInfoModel();
  789. model.setPlanId(CommTool.genPlanInfoId());
  790. model.setPlanType(oJsonParam.getPlanType());
  791. model.setPlanStatus(oJsonParam.getPlanStatus());
  792. model.setTitle(oJsonParam.getTitle());
  793. model.setUrgentLevel(oJsonParam.getUrgentLevel());
  794. model.setDispatchRemark(oJsonParam.getDispatchRemark());
  795. model.setDispatchLeadTime(oJsonParam.getDispatchLeadTime());
  796. model.setCreatorId(oJsonParam.getCreatorId());
  797. model.setCreateTime(TimeTool.getCurMsUTC());
  798. model.setCycles(oJsonParam.getCycles());
  799. model.setZoneId(oJsonParam.getZoneId());
  800. //TODO 开始计算时间字段并设置
  801. Long lastTakeTime = 0L;
  802. Long nextTakeTime = 0L;//下一次生效时间
  803. Long limitNextTakeTime = 0L;//下一次生效截止时间
  804. DispatchPlanInfoNextTimeModel nextTimeModel = new DispatchPlanInfoNextTimeModel();
  805. nextTimeModel.setPlanType(oJsonParam.getPlanType());
  806. List<DispatchCmdBatchItemNextTimeModel> itemModels = new ArrayList<>();
  807. if(!CollectionUtils.isEmpty(oJsonParam.getItemsList())){
  808. for(JPDispatchCmdBatchItem jpItem:oJsonParam.getItemsList()){
  809. DispatchCmdBatchItemNextTimeModel dispatchCmdBatchItemNextTimeModel =new DispatchCmdBatchItemNextTimeModel();
  810. dispatchCmdBatchItemNextTimeModel.setHandleStartTime(jpItem.getHandleStartTime());
  811. dispatchCmdBatchItemNextTimeModel.setHandleStartTimeLimit(jpItem.getHandleEndTime());
  812. itemModels.add(dispatchCmdBatchItemNextTimeModel);
  813. }
  814. }
  815. nextTimeModel.setItemsList(itemModels);
  816. nextTimeModel.setDispatchLeadTime(oJsonParam.getDispatchLeadTime());
  817. nextTimeModel.setCycles(oJsonParam.getCycles());
  818. Map<String,Long> nextMap = returnNextTakeTime(nextTimeModel,null);
  819. nextTakeTime = nextMap.get("nextTakeTime");
  820. limitNextTakeTime = nextMap.get("limitNextTakeTime");
  821. model.setLastTakeTime(lastTakeTime);
  822. model.setNextTakeTime(nextTakeTime);
  823. model.setLimitNextTakeTime(limitNextTakeTime);
  824. model.setTakes(0);
  825. model.setErrors("");
  826. model.setSendway(oJsonParam.getSendway());
  827. model.setChufaRulsFlag(oJsonParam.getChufaRulsFlag());
  828. ResponseCode insertRes = getThisDBService().insertPlanInfoByCount(model,oJsonParam.getRulesList(),
  829. oJsonParam.getTagsList(),oJsonParam.getItemsList());
  830. return insertRes;
  831. // return null;
  832. }catch(Exception ex){
  833. LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_INFO, mStrClassName, mStrClassName
  834. ,String.format("insert planInfo errorMsg:%s end<====",
  835. ex.getLocalizedMessage()));
  836. return ResponseCode.RESULT_BAD;
  837. }
  838. }
  839. //TODO 修改计划增加线程锁
  840. public static ResponseCode updatePlanClock(JPDispatchPlanInfoUpdate oJsonParam){
  841. ResponseCode code = ResponseCode.RESULT_BAD;
  842. if (oJsonParam==null)
  843. return code;
  844. CountDownLatchEx latchEx = null;
  845. int nRetry = 3;
  846. do {
  847. try {
  848. latchEx = WODispatchPlanLockMgr.tryLatchForPlan(oJsonParam.getPlanId(), 20000);
  849. }catch (Exception e){
  850. latchEx = null;
  851. }
  852. if (latchEx != null){
  853. code = updatePlan(oJsonParam);
  854. break;
  855. }
  856. }while ((--nRetry) > 0);
  857. if (latchEx != null){
  858. latchEx.countDown();
  859. }else{
  860. code = updatePlan(oJsonParam);
  861. }
  862. return code;
  863. }
  864. //TODO 修改计划
  865. private static ResponseCode updatePlan(JPDispatchPlanInfoUpdate oJsonParam){
  866. try {
  867. //TODO 根据计划类型计算计划的下次生效时间
  868. //TODO 查询原计划是否还存在,若存在比对planType是否一致
  869. Map<String,Object> oldPlan = getThisDBService().getOne(oJsonParam.getPlanId());
  870. if(oldPlan==null){
  871. return ResponseCode.RESULT_REFERENCE_NOT_EXIST;
  872. }
  873. if(!oJsonParam.getPlanType().equals(Integer.valueOf(oldPlan.get("plan_type").toString()))){
  874. return ResponseCode.STATUS_ERROR_JSON_FORMAT;
  875. }
  876. //TODO 开始计算时间字段并设置
  877. Long nextTakeTime = 0L;//下一次生效时间
  878. Long limitNextTakeTime = 0L;//下一次生效时间
  879. DispatchPlanInfoNextTimeModel nextTimeModel = new DispatchPlanInfoNextTimeModel();
  880. nextTimeModel.setPlanType(oJsonParam.getPlanType());
  881. List<DispatchCmdBatchItemNextTimeModel> itemModels = new ArrayList<>();
  882. if(!CollectionUtils.isEmpty(oJsonParam.getItemsList())){
  883. for(JPDispatchCmdBatchItem jpItem:oJsonParam.getItemsList()){
  884. DispatchCmdBatchItemNextTimeModel dispatchCmdBatchItemNextTimeModel =new DispatchCmdBatchItemNextTimeModel();
  885. dispatchCmdBatchItemNextTimeModel.setHandleStartTime(jpItem.getHandleStartTime());
  886. dispatchCmdBatchItemNextTimeModel.setHandleStartTimeLimit(jpItem.getHandleEndTime());
  887. itemModels.add(dispatchCmdBatchItemNextTimeModel);
  888. }
  889. }
  890. nextTimeModel.setPlanType(oJsonParam.getPlanType());
  891. nextTimeModel.setItemsList(itemModels);
  892. nextTimeModel.setDispatchLeadTime(oJsonParam.getDispatchLeadTime());
  893. nextTimeModel.setCycles(oJsonParam.getCycles());
  894. Map<String,Long> nextMap = returnNextTakeTime(nextTimeModel,null);
  895. nextTakeTime = nextMap.get("nextTakeTime");
  896. limitNextTakeTime = nextMap.get("limitNextTakeTime");
  897. ResponseCode updateRes = getThisDBService().updatePlanInfoByCount(oJsonParam,nextTakeTime,limitNextTakeTime, oJsonParam.getRulesList(),
  898. oJsonParam.getTagsList(), oJsonParam.getItemsList());
  899. return updateRes;
  900. }catch(Exception ex){
  901. LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_INFO, mStrClassName, mStrClassName
  902. ,String.format("update planInfo errorMsg:%s end<====",
  903. ex.getLocalizedMessage()));
  904. return ResponseCode.RESULT_BAD;
  905. }
  906. }
  907. public static ResponseCode updatePlanStatus(JPDispatchPlanInfoUpdateStatus oJsonParam){
  908. try {
  909. //TODO 根据计划类型计算计划的下次生效时间
  910. //TODO 查询原计划是否还存在,若存在比对planType是否一致
  911. Map<String,Object> oldPlan = getThisDBService().getOne(oJsonParam.getPlanId());
  912. if(oldPlan==null||oldPlan.size()<=0){
  913. return ResponseCode.RESULT_REFERENCE_NOT_EXIST;
  914. }
  915. Map<String,Object> oldPlanUpWhere = new HashMap<>();
  916. oldPlanUpWhere.put("plan_id",oJsonParam.getPlanId());
  917. Map<String,Object> oldPlanUp = new HashMap<>();
  918. oldPlanUp.put("plan_status",oJsonParam.getPlanStatus());
  919. int code = getThisDBService().updateWiths(oldPlanUp,oldPlanUpWhere);
  920. return code>0?ResponseCode.RESULT_NORMAL:ResponseCode.RESULT_BAD;
  921. }catch(Exception ex){
  922. LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_INFO, mStrClassName, mStrClassName
  923. ,String.format("update planInfo errorMsg:%s end<====",
  924. ex.getLocalizedMessage()));
  925. return ResponseCode.RESULT_BAD;
  926. }
  927. }
  928. private static boolean isSameDay(long timestamp1, long timestamp2) {
  929. SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
  930. // 确保时区设置正确,以避免因夏令时导致的问题
  931. sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
  932. return sdf.format(new Date(timestamp1)).equals(sdf.format(new Date(timestamp2)));
  933. }
  934. //TODO 全量查询标签字典信息
  935. public static ResponseRes selectAllTags(){
  936. ResponseRes oRes = new ResponseRes();
  937. oRes.setRescode(ResponseCode.RESULT_BAD.toStrCode());
  938. oRes.setResmsg(ResponseCode.RESULT_BAD.toStrMsg());
  939. try{
  940. List<Map<String,Object>> map = getThisDBService().selectAllTags("","",new HashMap<>(),new HashMap<>()
  941. ,"","");
  942. if(map!=null||map.size()>0){
  943. oRes.setResdata(FastJsonUtil.toJSON(map,true));
  944. }
  945. oRes.setRescode(ResponseCode.RESULT_NORMAL.toStrCode());
  946. oRes.setResmsg(ResponseCode.RESULT_NORMAL.toStrMsg());
  947. return oRes;
  948. }catch (Exception ex){
  949. return oRes;
  950. }
  951. }
  952. }