WODispatchPlanTmDoBizFun.java 58 KB

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