WODispatchPlanTmDoBizFun.java 57 KB

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