Commit c75f284d778809e1fafa9b5fae23b869c087433b

Authored by 徐烜
1 parent e53f80dc

添加新的排班验证规则,如果当天的时刻表有的路牌在排班数据中没有,提示错误

src/main/java/com/bsth/service/schedule/plan/DroolsSchedulePlan.java
@@ -475,6 +475,9 @@ public class DroolsSchedulePlan { @@ -475,6 +475,9 @@ public class DroolsSchedulePlan {
475 * @param schedulePlan 475 * @param schedulePlan
476 */ 476 */
477 public void validPlanResult(PlanResult planResult) { 477 public void validPlanResult(PlanResult planResult) {
  478 + // 1-0、获取路牌信息
  479 + LpInfoResults_output lpInfoResults_output = (LpInfoResults_output) this.ttInfoOutput(this.mainLine)[1];
  480 +
478 // 1-1、构造drools规则输入数据,输出数据 481 // 1-1、构造drools规则输入数据,输出数据
479 ValidateParam validateParam = new ValidateParam( 482 ValidateParam validateParam = new ValidateParam(
480 new DateTime(this.from), new DateTime(this.to)); 483 new DateTime(this.from), new DateTime(this.to));
@@ -494,6 +497,9 @@ public class DroolsSchedulePlan { @@ -494,6 +497,9 @@ public class DroolsSchedulePlan {
494 for (SchedulePlanInfo schedulePlanInfo: planResult.getSchedulePlanInfos()) { 497 for (SchedulePlanInfo schedulePlanInfo: planResult.getSchedulePlanInfos()) {
495 session.insert(schedulePlanInfo); 498 session.insert(schedulePlanInfo);
496 } 499 }
  500 + for (LpInfoResult_output lpInfoResult_output: lpInfoResults_output.getLpInfoResult_outputs()) {
  501 + session.insert(lpInfoResult_output);
  502 + }
497 503
498 // 执行rule 504 // 执行rule
499 session.fireAllRules(); 505 session.fireAllRules();
src/main/java/com/bsth/service/schedule/rules/ttinfo/LpInfoResult_output.java
@@ -10,6 +10,8 @@ public class LpInfoResult_output { @@ -10,6 +10,8 @@ public class LpInfoResult_output {
10 private DateTime dateTime; 10 private DateTime dateTime;
11 /** 路牌Id */ 11 /** 路牌Id */
12 private String lpId; 12 private String lpId;
  13 + /** 路牌名字 */
  14 + private String lpName;
13 /** 线路Id */ 15 /** 线路Id */
14 private String xlId; 16 private String xlId;
15 /** 时刻表Id */ 17 /** 时刻表Id */
@@ -56,4 +58,12 @@ public class LpInfoResult_output { @@ -56,4 +58,12 @@ public class LpInfoResult_output {
56 public void setTtInfoName(String ttInfoName) { 58 public void setTtInfoName(String ttInfoName) {
57 this.ttInfoName = ttInfoName; 59 this.ttInfoName = ttInfoName;
58 } 60 }
  61 +
  62 + public String getLpName() {
  63 + return lpName;
  64 + }
  65 +
  66 + public void setLpName(String lpName) {
  67 + this.lpName = lpName;
  68 + }
59 } 69 }
src/main/java/com/bsth/service/schedule/rules/ttinfo/LpInfoResultsFunction.java
@@ -64,6 +64,7 @@ public class LpInfoResultsFunction implements AccumulateFunction { @@ -64,6 +64,7 @@ public class LpInfoResultsFunction implements AccumulateFunction {
64 if (lpInfoResultsData.lpInfoResult_outputMap.get(ttInfoDetail.getLp().getId()) == null) { 64 if (lpInfoResultsData.lpInfoResult_outputMap.get(ttInfoDetail.getLp().getId()) == null) {
65 LpInfoResult_output lpInfoResult_output = new LpInfoResult_output(); 65 LpInfoResult_output lpInfoResult_output = new LpInfoResult_output();
66 lpInfoResult_output.setLpId(String.valueOf(ttInfoDetail.getLp().getId())); 66 lpInfoResult_output.setLpId(String.valueOf(ttInfoDetail.getLp().getId()));
  67 + lpInfoResult_output.setLpName(ttInfoDetail.getLp().getLpName());
67 lpInfoResult_output.setXlId(String.valueOf(ttInfoDetail.getXl().getId())); 68 lpInfoResult_output.setXlId(String.valueOf(ttInfoDetail.getXl().getId()));
68 lpInfoResult_output.setTtInfoId(String.valueOf(ttInfoDetail.getTtinfo().getId())); 69 lpInfoResult_output.setTtInfoId(String.valueOf(ttInfoDetail.getTtinfo().getId()));
69 lpInfoResult_output.setTtInfoName(ttInfoDetail.getTtinfo().getName()); 70 lpInfoResult_output.setTtInfoName(ttInfoDetail.getTtinfo().getName());
src/main/java/com/bsth/service/schedule/rules/validate/ValidWantLpFunction.java 0 → 100644
  1 +package com.bsth.service.schedule.rules.validate;
  2 +
  3 +import com.bsth.entity.schedule.SchedulePlanInfo;
  4 +import com.bsth.service.schedule.rules.ttinfo.LpInfoResult_output;
  5 +import org.kie.api.runtime.rule.AccumulateFunction;
  6 +
  7 +import java.io.*;
  8 +import java.text.SimpleDateFormat;
  9 +import java.util.*;
  10 +
  11 +/**
  12 + * 计算缺少路牌错误。
  13 + * 同一天,如果有时刻表路牌没有执行到,统计。
  14 + * 注意:使用这个函数时,要一天计算一次,多天计算无意义。
  15 + */
  16 +public class ValidWantLpFunction implements AccumulateFunction {
  17 + @Override
  18 + public void writeExternal(ObjectOutput out) throws IOException {
  19 + }
  20 +
  21 + @Override
  22 + public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
  23 +
  24 + }
  25 +
  26 + protected static class WantLpInfo implements Externalizable {
  27 + /** 错误描述 */
  28 + public List<ValidateResults_output.ValidInfo> validInfoList = new ArrayList<>();
  29 + /** 每天的路牌班次数量 */
  30 + public Map<String, Integer> lpBcCount = new HashMap<>();
  31 + /** 每天的路牌名字对应 */
  32 + public Map<String, String> lpNamesMap = new HashMap<>();
  33 + /** 排班日期 */
  34 + public Date scheduleDate;
  35 +
  36 + public WantLpInfo() {
  37 +
  38 + }
  39 +
  40 + @Override
  41 + public void writeExternal(ObjectOutput out) throws IOException {
  42 + out.writeObject(validInfoList);
  43 + }
  44 +
  45 + @Override
  46 + public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
  47 + validInfoList = (List<ValidateResults_output.ValidInfo>) in.readObject();
  48 + }
  49 + }
  50 +
  51 + @Override
  52 + public Serializable createContext() {
  53 + return new WantLpInfo();
  54 + }
  55 +
  56 + @Override
  57 + public void init(Serializable serializable) throws Exception {
  58 + // TODO:
  59 +// System.out.println("init");
  60 + }
  61 +
  62 + @Override
  63 + public void accumulate(Serializable context, Object o) {
  64 + WantLpInfo wantLpInfo = (WantLpInfo) context;
  65 + ValidateResource validateResource = (ValidateResource) o;
  66 +
  67 + SchedulePlanInfo spi = validateResource.getSpi();
  68 + List<LpInfoResult_output> lpiList = validateResource.getLpiList();
  69 +
  70 + // 获取当天所有路牌信息,每个验证对象都带当天所有路牌信息,只需判定一次
  71 + if (wantLpInfo.lpNamesMap.isEmpty()) {
  72 + for (LpInfoResult_output lpInfoResult_output: lpiList) {
  73 + wantLpInfo.lpNamesMap.put(lpInfoResult_output.getLpId(), lpInfoResult_output.getLpName());
  74 + wantLpInfo.lpBcCount.put(lpInfoResult_output.getLpId(), 0);
  75 + }
  76 + }
  77 + if (wantLpInfo.scheduleDate == null) {
  78 + wantLpInfo.scheduleDate = spi.getScheduleDate();
  79 + }
  80 +
  81 + // 累计记录每个排班班次出现次数
  82 + String lpId_spi = spi.getLp().toString();
  83 + wantLpInfo.lpBcCount.put(lpId_spi, wantLpInfo.lpBcCount.get(lpId_spi) + 1);
  84 +
  85 + }
  86 +
  87 + @Override
  88 + public boolean supportsReverse() {
  89 + return true;
  90 + }
  91 +
  92 + @Override
  93 + public void reverse(Serializable context, Object o) throws Exception {
  94 + WantLpInfo wantLpInfo = (WantLpInfo) context;
  95 +
  96 + // 清空数据,下一天继续迭代
  97 + wantLpInfo.lpBcCount.clear();
  98 + wantLpInfo.lpNamesMap.clear();
  99 + wantLpInfo.scheduleDate = null;
  100 + wantLpInfo.validInfoList.clear();
  101 +
  102 +// System.out.println("reverse");
  103 +
  104 + }
  105 +
  106 + @Override
  107 + public Class<?> getResultType() {
  108 + return List.class;
  109 + }
  110 +
  111 + @Override
  112 + public Object getResult(Serializable context) throws Exception {
  113 + WantLpInfo wantLpInfo = (WantLpInfo) context;
  114 +
  115 + SimpleDateFormat sf = new SimpleDateFormat("yyyy年MM月dd日");
  116 + String infoFormat = "日期(%s),路牌(%s),没有排班班次";
  117 +
  118 + for (String lpId : wantLpInfo.lpBcCount.keySet()) {
  119 + if (wantLpInfo.lpBcCount.get(lpId) == 0) {
  120 + // 排班没有班次
  121 + ValidateResults_output.ValidInfo validInfo = new ValidateResults_output.ValidInfo();
  122 + validInfo.setSd(wantLpInfo.scheduleDate);
  123 + validInfo.setDesc(String.format(
  124 + infoFormat,
  125 + sf.format(wantLpInfo.scheduleDate),
  126 + wantLpInfo.lpNamesMap.get(lpId))
  127 + );
  128 + wantLpInfo.validInfoList.add(validInfo);
  129 + }
  130 + }
  131 +
  132 + System.out.println("ValidWantLpFunction==>" + wantLpInfo.lpBcCount);
  133 +
  134 + return wantLpInfo.validInfoList;
  135 + }
  136 +
  137 +}
  138 +
  139 +
  140 +
  141 +
  142 +
  143 +
  144 +
  145 +
src/main/java/com/bsth/service/schedule/rules/validate/ValidateResource.java 0 → 100644
  1 +package com.bsth.service.schedule.rules.validate;
  2 +
  3 +import com.bsth.entity.schedule.SchedulePlanInfo;
  4 +import com.bsth.service.schedule.rules.ttinfo.LpInfoResult_output;
  5 +
  6 +import java.util.Date;
  7 +import java.util.List;
  8 +
  9 +/**
  10 + * 验证操作dsl类。
  11 + */
  12 +public class ValidateResource {
  13 + /** 具体日期 */
  14 + private Date sd;
  15 + /** 当天排班计划 */
  16 + private SchedulePlanInfo spi;
  17 + /** 当天所有路牌信息 */
  18 + private List<LpInfoResult_output> lpiList;
  19 +
  20 + public Date getSd() {
  21 + return sd;
  22 + }
  23 +
  24 + public void setSd(Date sd) {
  25 + this.sd = sd;
  26 + }
  27 +
  28 + public SchedulePlanInfo getSpi() {
  29 + return spi;
  30 + }
  31 +
  32 + public void setSpi(SchedulePlanInfo spi) {
  33 + this.spi = spi;
  34 + }
  35 +
  36 + public List<LpInfoResult_output> getLpiList() {
  37 + return lpiList;
  38 + }
  39 +
  40 + public void setLpiList(List<LpInfoResult_output> lpiList) {
  41 + this.lpiList = lpiList;
  42 + }
  43 +}
src/main/resources/rules/functions.drl
@@ -8,3 +8,4 @@ import accumulate com.bsth.service.schedule.rules.ttinfo.LpInfoResultsFunction l @@ -8,3 +8,4 @@ import accumulate com.bsth.service.schedule.rules.ttinfo.LpInfoResultsFunction l
8 import accumulate com.bsth.service.schedule.rules.ttinfo.MinRuleQyrqFunction minruleqyrq; 8 import accumulate com.bsth.service.schedule.rules.ttinfo.MinRuleQyrqFunction minruleqyrq;
9 import accumulate com.bsth.service.schedule.rules.validate.ValidRepeatBcFunction vrb; 9 import accumulate com.bsth.service.schedule.rules.validate.ValidRepeatBcFunction vrb;
10 import accumulate com.bsth.service.schedule.rules.validate.ValidWholeRerunBcFunction vwrb; 10 import accumulate com.bsth.service.schedule.rules.validate.ValidWholeRerunBcFunction vwrb;
  11 +import accumulate com.bsth.service.schedule.rules.validate.ValidWantLpFunction vwlp;
src/main/resources/rules/validplan.drl
@@ -2,6 +2,7 @@ package com.bsth.service.schedule.rules.validate; @@ -2,6 +2,7 @@ package com.bsth.service.schedule.rules.validate;
2 2
3 import com.bsth.entity.schedule.SchedulePlanInfo; 3 import com.bsth.entity.schedule.SchedulePlanInfo;
4 import com.bsth.service.schedule.rules.ttinfo.LpInfoResult_output; 4 import com.bsth.service.schedule.rules.ttinfo.LpInfoResult_output;
  5 +import com.bsth.service.schedule.rules.validate.ValidateResource;
5 6
6 import org.joda.time.*; 7 import org.joda.time.*;
7 import java.util.*; 8 import java.util.*;
@@ -14,7 +15,22 @@ global Logger log; @@ -14,7 +15,22 @@ global Logger log;
14 // 输出 15 // 输出
15 global ValidateResults_output validResult; 16 global ValidateResults_output validResult;
16 17
17 -//------------------------- 第一阶段、构造循环体 ----------------------------// 18 +//------------------------- 第一阶段、构造验证源 ----------------------------//
  19 +rule "Calcu_validate_resource"
  20 + salience 2000
  21 + when
  22 + $spi: SchedulePlanInfo($sd: scheduleDate)
  23 + $lpiList: ArrayList() from collect (LpInfoResult_output(dateTime.getMillis() == $sd.getTime()))
  24 + then
  25 + ValidateResource resource = new ValidateResource();
  26 + resource.setSd($sd);
  27 + resource.setSpi($spi);
  28 + resource.setLpiList($lpiList);
  29 +
  30 + insert(resource);
  31 +end
  32 +
  33 +//------------------------- 第二阶段、构造循环体 ----------------------------//
18 34
19 declare Loop_param 35 declare Loop_param
20 start_date: DateTime // 开始日期(这个要不停的更新迭代) 36 start_date: DateTime // 开始日期(这个要不停的更新迭代)
@@ -39,23 +55,27 @@ rule &quot;Calcu_Loop_param&quot; @@ -39,23 +55,27 @@ rule &quot;Calcu_Loop_param&quot;
39 insert(p); 55 insert(p);
40 end 56 end
41 57
42 -//------------------------- 第阶段、验证计算 ----------------------------// 58 +//------------------------- 第阶段、验证计算 ----------------------------//
43 59
44 60
45 -rule "Valid_repeat_bc" // 验证是否存在重复班次 61 +rule "Valid_repeat_bc" // 验证是否存在重复班次,未套跑班次,未执行路牌
46 salience 600 62 salience 600
47 when 63 when
48 $lp: Loop_param($sd: start_date, $ed: end_date) 64 $lp: Loop_param($sd: start_date, $ed: end_date)
49 eval($sd.isBefore($ed) || $sd.isEqual($ed)) 65 eval($sd.isBefore($ed) || $sd.isEqual($ed))
50 - $spiList: ArrayList() from collect (SchedulePlanInfo(scheduleDate.getTime() == $sd.getMillis()))  
51 - $infos: ArrayList() from accumulate ($spi: SchedulePlanInfo() from $spiList, vrb($spi))  
52 - $infos2: ArrayList() from accumulate ($spi: SchedulePlanInfo() from $spiList, vwrb($spi)) 66 + $vrList: ArrayList() from collect (ValidateResource(sd.getTime() == $sd.getMillis()))
  67 + $infos: ArrayList() from accumulate ($vr: ValidateResource() from $vrList, vrb($vr.getSpi()))
  68 + $infos2: ArrayList() from accumulate ($vr: ValidateResource() from $vrList, vwrb($vr.getSpi()))
  69 + $infos3: ArrayList() from accumulate ($vr: ValidateResource() from $vrList, vwlp($vr))
53 then 70 then
54 // TODO: 71 // TODO:
55 // log.info("日期={},班次重复错误数={}", $sd, $infos.size()); 72 // log.info("日期={},班次重复错误数={}", $sd, $infos.size());
56 73
  74 +// log.info("班次数={}", $vrList.size());
  75 +
57 validResult.getInfos().addAll($infos); 76 validResult.getInfos().addAll($infos);
58 validResult.getInfos().addAll($infos2); 77 validResult.getInfos().addAll($infos2);
  78 + validResult.getInfos().addAll($infos3);
59 79
60 // 迭代 80 // 迭代
61 $lp.setStart_date($sd.plusDays(1)); 81 $lp.setStart_date($sd.plusDays(1));