Commit a4ff8a760ff23345d631e25737b0dedcebc8080b

Authored by 徐烜
1 parent 34547da3

嘉定公交调度系统计划调度功能优化5

1、排班优化,重构 排班生成 - 1、计算时刻表相关信息,关联的规则drl,服务service,测试用例
Showing 20 changed files with 1835 additions and 1 deletions
src/main/java/com/bsth/service/schedule/plan/PlanConfig.java
... ... @@ -59,6 +59,19 @@ public class PlanConfig {
59 59 }
60 60  
61 61 /**
  62 + * 排班生成 - 1、计算时刻表相关信息 kieBase。
  63 + * @return
  64 + */
  65 + @Bean(name = "kBaseGenerateCalcuTimeTable_plus")
  66 + public KieBase kBaseGenerateCalcuTimeTable() {
  67 + KieBase kieBase = this.generateKieBase(
  68 + "kBaseGenerateCalcuTimeTable",
  69 + new String[] {this.planConfigProperties.getGenerateCalcuTimetable()});
  70 + LOGGER.info("初始化 KieBase[{}]成功", "排班生成 - 1、计算时刻表相关信息");
  71 + return kieBase;
  72 + }
  73 +
  74 + /**
62 75 * 生成KieBase。
63 76 * @param kBaseName kBase名字
64 77 * @param drlClasspaths 规则类路径
... ...
src/main/java/com/bsth/service/schedule/plan/PlanConfigProperties.java
... ... @@ -22,6 +22,9 @@ public class PlanConfigProperties {
22 22 @NotNull
23 23 private String validateRule;
24 24  
  25 + /** 排班生成 - 1、计算时刻表相关信息 */
  26 + private String generateCalcuTimetable;
  27 +
25 28 public String getValidateTimetable() {
26 29 return validateTimetable;
27 30 }
... ... @@ -37,4 +40,12 @@ public class PlanConfigProperties {
37 40 public void setValidateRule(String validateRule) {
38 41 this.validateRule = validateRule;
39 42 }
  43 +
  44 + public String getGenerateCalcuTimetable() {
  45 + return generateCalcuTimetable;
  46 + }
  47 +
  48 + public void setGenerateCalcuTimetable(String generateCalcuTimetable) {
  49 + this.generateCalcuTimetable = generateCalcuTimetable;
  50 + }
40 51 }
... ...
src/main/java/com/bsth/service/schedule/plan/process/_2_generate/_1_calcu/_2_timetable/PlanProcessGenerateCalcuTimeTableService.java 0 → 100644
  1 +package com.bsth.service.schedule.plan.process._2_generate._1_calcu._2_timetable;
  2 +
  3 +import lombok.AllArgsConstructor;
  4 +import lombok.Builder;
  5 +import lombok.Data;
  6 +import org.joda.time.DateTime;
  7 +
  8 +import java.util.ArrayList;
  9 +import java.util.Date;
  10 +import java.util.List;
  11 +
  12 +/**
  13 + * 计算时刻表信息服务。
  14 + */
  15 +public interface PlanProcessGenerateCalcuTimeTableService {
  16 + /**
  17 + * 计算时刻表信息。
  18 + * @param xlid 线路Id
  19 + * @param from 排班计划开始时间
  20 + * @param to 排班计划结束时间
  21 + * @return 验证输出
  22 + */
  23 + List<TTinfoDetailByLpResult> generateCalcuTTInfos(Integer xlid, Date from, Date to);
  24 +
  25 + /**
  26 + * 时刻表,路牌信息合并。
  27 + * 当前线路,指定排班日期,使用的时刻表,对应的路牌,以及对应路牌的时刻表班次列表。
  28 + */
  29 + @Data
  30 + @Builder
  31 + @AllArgsConstructor
  32 + class TTinfoDetailByLpResult {
  33 + /** 线路 */
  34 + private LineResult lineResult;
  35 +
  36 + /** 排班日期 */
  37 + private DateTime scheduleDate;
  38 +
  39 + /** 当前日期使用的时刻表 */
  40 + private TTinfoResult tTinfoResult;
  41 +
  42 + /** 时刻表对应路牌配置 */
  43 + private LpInfoResult lpInfoResult;
  44 + /** 时刻表路牌对应班次列表 */
  45 + private List<TTinfoDetailResult> tTinfoDetailResultList;
  46 +
  47 + /** 最小班次发车顺序号 */
  48 + private Integer minFcno;
  49 + /** 最大班次发车顺序号 */
  50 + private Integer maxFcno;
  51 + /** 开始分班班次发车顺序号 */
  52 + private Integer startFbFcno;
  53 + }
  54 +
  55 + @Data
  56 + @Builder
  57 + @AllArgsConstructor
  58 + class LineResult {
  59 + /** 主键id */
  60 + private Integer id;
  61 + /** 线路名称 */
  62 + private String name;
  63 + }
  64 +
  65 + @Data
  66 + @Builder
  67 + @AllArgsConstructor
  68 + class TTinfoResult {
  69 + /** 主键Id */
  70 + private Long id;
  71 +
  72 + /** 线路关联 */
  73 + private LineResult xl;
  74 +
  75 + /** 时刻表名称 */
  76 + private String name;
  77 +
  78 + /** 常规有效日(1-7表示星期一到星期日,多个用逗号隔开) */
  79 + private String rule_days;
  80 + /** 特殊有效日期(格式:2001-01-01,多个用逗号隔开) */
  81 + private String special_days;
  82 +
  83 + /** 常规有效日(参照rule_days,1=true表示启用,0=false表示未启用,一个星期7天,保存7个元素) */
  84 + private List<Boolean> weekdayList = new ArrayList<>();
  85 + /** 特殊有效日期(参照special_days,1个日期保存1个元素) */
  86 + private List<DateTime> specialDayList = new ArrayList<>();
  87 +
  88 + /** 线路版本(bsth_c_line_versions表对应字段) */
  89 + private int lineVersion;
  90 + }
  91 +
  92 + @Data
  93 + @Builder
  94 + @AllArgsConstructor
  95 + class LpInfoResult {
  96 + /** 线路信息 */
  97 + private LineResult xl;
  98 + /** 路牌Id */
  99 + private Long id;
  100 + /** 路牌名字 */
  101 + private String name;
  102 + }
  103 +
  104 + @Data
  105 + @Builder
  106 + @AllArgsConstructor
  107 + class TTinfoDetailResult {
  108 + /** 线路 */
  109 + private LineResult xl;
  110 + /** 时刻表 */
  111 + private TTinfoResult ttInfo;
  112 + /** 路牌 */
  113 + private LpInfoResult lp;
  114 +
  115 + /** 主健Id */
  116 + private Long id;
  117 +
  118 + // 站点包括普通站点和停车场(站点编码不同,使用站点编码区分)
  119 + // 以后不需要再区分是站点还是停车场了
  120 + /** 起站点代码(bsth_c_station,bsth_c_car_park 里的编码) */
  121 + private String qdzCode;
  122 + /** 起站点名字(bsth_c_stationroute,bsth_c_car_park里的名字) */
  123 + private String qdzName;
  124 + /** 终点站代码(bsth_c_station,bsth_c_car_park 里的编码) */
  125 + private String zdzCode;
  126 + /** 终点站名字(bsth_c_stationroute,bsth_c_car_park里的名字) */
  127 + private String zdzName;
  128 +
  129 + /** 发车顺序号 */
  130 + private Integer fcno;
  131 + /** 是否分班(表示这个班次是否是晚班班次,就是换另外一个驾驶员开)*/
  132 + private Boolean isFB;
  133 + /** 是否停驶(表示此班次执行完成,停在终点站,不进场) */
  134 + private Boolean isTS;
  135 +
  136 + /** 线路方向(TODO:上下行,上行,下行,这个以后用枚举还是字典再议,现在先用文字) */
  137 + private String xlDir;
  138 + /** 班次类型 字典type=ScheduleType */
  139 + private String bcType;
  140 +
  141 + /** 线路版本(bsth_c_line_versions表对应字段) */
  142 + private int lineVersion;
  143 + /** 发车时间(格式 HH:mm) */
  144 + private String fcsj;
  145 + /** 对应班次数 */
  146 + private Integer bcs;
  147 + /** 计划里程 */
  148 + private Double jhlc;
  149 + /** 班次历时 */
  150 + private Integer bcsj;
  151 +
  152 + /** 备注 */
  153 + private String remark;
  154 + }
  155 +}
... ...
src/main/java/com/bsth/service/schedule/plan/process/_2_generate/_1_calcu/_2_timetable/PlanProcessGenerateCalcuTimeTableServiceDroolsImpl.java 0 → 100644
  1 +package com.bsth.service.schedule.plan.process._2_generate._1_calcu._2_timetable;
  2 +
  3 +import com.bsth.control_v2.plan_module.common.exception.PlanModuleException;
  4 +import com.bsth.service.schedule.plan.process._2_generate._1_calcu._2_timetable.drools.*;
  5 +import org.joda.time.DateTime;
  6 +import org.kie.api.KieBase;
  7 +import org.kie.api.runtime.KieSession;
  8 +import org.slf4j.Logger;
  9 +import org.slf4j.LoggerFactory;
  10 +import org.springframework.jdbc.core.JdbcTemplate;
  11 +import org.springframework.jdbc.core.RowMapper;
  12 +import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
  13 +import org.springframework.util.CollectionUtils;
  14 +
  15 +import java.sql.ResultSet;
  16 +import java.sql.SQLException;
  17 +import java.util.*;
  18 +
  19 +/**
  20 + * 计算时刻表信息服务drools实现。
  21 + */
  22 +public class PlanProcessGenerateCalcuTimeTableServiceDroolsImpl implements PlanProcessGenerateCalcuTimeTableService {
  23 + /** 日志记录器 */
  24 + private static final Logger LOGGER = LoggerFactory.getLogger(PlanProcessGenerateCalcuTimeTableServiceDroolsImpl.class);
  25 +
  26 + /** 计算时刻表信息drools kbase */
  27 + private KieBase kBaseGenerateCalcuTimeTable;
  28 +
  29 + /** 使用的jdbc服务 */
  30 + private JdbcTemplate jdbcTemplate;
  31 +
  32 + /** 线路查询SQL */
  33 + private static final String LINE_QUERY_SQL =
  34 + "select id, name " +
  35 + "from bsth_c_line line " +
  36 + "where line.id = ? and destroy = 0";
  37 + /** 时刻表查询SQL */
  38 + private static final String TTINFO_QUERY_SQL =
  39 + "select id, name, rule_days, special_days, xl " +
  40 + "from bsth_c_s_ttinfo ttinfo " +
  41 + "where ttinfo.is_cancel = 0 and ttinfo.is_enable_dis_template = 1 and ttinfo.xl = ?";
  42 + /** 时刻表明细查询SQL(使用 NamedParameterJdbcTemplate) */
  43 + private static final String TTINFO_DETAIL_QUERY_SQL =
  44 + "select id, qdz_code, qdz_name, zdz_code, zdz_name, " +
  45 + "ttinfo, line_version, lp, fcno, isfb, " +
  46 + "xl, xl_dir, bc_type, ists, " +
  47 + "fcsj, bcs, jhlc, bcsj, remark " +
  48 + "from bsth_c_s_ttinfo_detail td " +
  49 + "where td.ttinfo in (:ttInfoIds)";
  50 + /** 路牌配置信息查询SQL */
  51 + private static final String LP_QUERY_SQL =
  52 + "select id, lp_name, xl " +
  53 + "from bsth_c_s_gbi " +
  54 + "where is_cancel = 0 and xl = ? ";
  55 +
  56 + /** 规则信息查询SQL */
  57 + private static final String FLAT_RULE_QUERY_SQL =
  58 + "select rule.id, cc.xl, rule.qyrq, car_config_info, " +
  59 + "lp_ids, lp_names, lp_start, " +
  60 + "ry_config_ids, ry_dbbms, ry_start, " +
  61 + "car.inside_code " +
  62 + "from bsth_c_s_sr1_flat rule left join bsth_c_s_ccinfo cc on rule.car_config_info = cc.id " +
  63 + "left join bsth_c_cars car on cc.cl = car.id " +
  64 + "where cc.xl = ? ";
  65 +
  66 + @Override
  67 + public List<TTinfoDetailByLpResult> generateCalcuTTInfos(Integer xlid, Date from, Date to) {
  68 + LOGGER.info("KieBase[{}],线路id={},开始日期={},结束日期={} 开始",
  69 + "排班生成 - 1、计算时刻表相关信息", xlid, from, to);
  70 +
  71 + // 构造drools session->载入数据->启动规则->计算->销毁session
  72 + // 创建session,内部配置的是stateful
  73 + KieSession session = kBaseGenerateCalcuTimeTable.newKieSession();
  74 + // 设置gloable对象,在drl中通过别名使用
  75 + session.setGlobal("LOGGER", LOGGER);
  76 +
  77 + // 输出gloable对象
  78 + List<TTinfoDetailByLpResult> rs = new ArrayList<>();
  79 + session.setGlobal("rs", rs);
  80 +
  81 + // 载入数据,参数数据,线路数据,时刻表数据,时刻表明细数据
  82 + // 载入线路fact
  83 + List<KBaseGenerateCalcuTimeTable_Fact_Line> fact_lines = this.jdbcTemplate.query(
  84 + LINE_QUERY_SQL,
  85 + new Object[]{xlid},
  86 + new RowMapper<KBaseGenerateCalcuTimeTable_Fact_Line>() {
  87 + @Override
  88 + public KBaseGenerateCalcuTimeTable_Fact_Line mapRow(ResultSet rs, int rowNum) throws SQLException {
  89 + return KBaseGenerateCalcuTimeTable_Fact_Line.builder()
  90 + .id(rs.getInt("id"))
  91 + .name(rs.getString("name"))
  92 + .build();
  93 + }
  94 + }
  95 + );
  96 + if (CollectionUtils.isEmpty(fact_lines)) {
  97 + throw new PlanModuleException("线路不存在,id=" + xlid);
  98 + } else {
  99 + session.insert(fact_lines.get(0));
  100 + }
  101 +
  102 + // 载入参数fact
  103 + KBaseGenerateCalcuTimeTable_Fact_CalcuParam calcuParam = new KBaseGenerateCalcuTimeTable_Fact_CalcuParam(
  104 + fact_lines.get(0), new DateTime(from), new DateTime(to));
  105 + session.insert(calcuParam);
  106 +
  107 + // 载入规则fact
  108 + List<KBaseGenerateCalcuTimeTable_Fact_Rule> fact_rules = this.jdbcTemplate.query(
  109 + FLAT_RULE_QUERY_SQL,
  110 + new Object[] {xlid},
  111 + new RowMapper<KBaseGenerateCalcuTimeTable_Fact_Rule>() {
  112 + @Override
  113 + public KBaseGenerateCalcuTimeTable_Fact_Rule mapRow(ResultSet rs, int rowNum) throws SQLException {
  114 + return KBaseGenerateCalcuTimeTable_Fact_Rule.builder()
  115 + .id(rs.getLong("id"))
  116 + .qyrq(rs.getDate("qyrq"))
  117 + .lpIds(rs.getString("lp_ids"))
  118 + .lpNames(rs.getString("lp_names"))
  119 + .lpStart(rs.getInt("lp_start"))
  120 + .ryConfigIds(rs.getString("ry_config_ids"))
  121 + .ryDbbms(rs.getString("ry_dbbms"))
  122 + .ryStart(rs.getInt("ry_start"))
  123 + .carConfigInfo(KBaseGenerateCalcuTimeTable_Fact_VehicleConfig.builder()
  124 + .id(rs.getLong("car_config_info"))
  125 + .cl(KBaseGenerateCalcuTimeTable_Fact_Vehicle.builder()
  126 + .insideCode(rs.getString("inside_code"))
  127 + .build())
  128 + .build())
  129 + .xl(KBaseGenerateCalcuTimeTable_Fact_Line.builder()
  130 + .id(rs.getInt("xl"))
  131 + .build())
  132 + .build();
  133 + }
  134 + });
  135 + for (KBaseGenerateCalcuTimeTable_Fact_Rule fact_rule : fact_rules) {
  136 + session.insert(fact_rule);
  137 + }
  138 +
  139 + // 载入时刻表fact
  140 + List<KBaseGenerateCalcuTimeTable_Fact_TTinfo> fact_tTinfos = this.jdbcTemplate.query(
  141 + TTINFO_QUERY_SQL,
  142 + new Object[]{xlid},
  143 + new RowMapper<KBaseGenerateCalcuTimeTable_Fact_TTinfo>() {
  144 + @Override
  145 + public KBaseGenerateCalcuTimeTable_Fact_TTinfo mapRow(ResultSet rs, int rowNum) throws SQLException {
  146 + return KBaseGenerateCalcuTimeTable_Fact_TTinfo.getBuilder()
  147 + .setXl(KBaseGenerateCalcuTimeTable_Fact_Line.builder()
  148 + .id(rs.getInt("xl"))
  149 + .build())
  150 + .setId(rs.getLong("id"))
  151 + .setName(rs.getString("name"))
  152 + .setSpecial_days(rs.getString("special_days"))
  153 + .setSpecialDayList(rs.getString("special_days"))
  154 + .setRule_days(rs.getString("rule_days"))
  155 + .setWeekdayList(rs.getString("rule_days"))
  156 + .build();
  157 + }
  158 + }
  159 + );
  160 + for (KBaseGenerateCalcuTimeTable_Fact_TTinfo fact_tTinfo : fact_tTinfos) {
  161 + session.insert(fact_tTinfo);
  162 + }
  163 +
  164 + // 载入时刻表明细fact
  165 + Map<String, Object> param = new HashMap<>();
  166 + List<Long> ttInfoIds = new ArrayList<>();
  167 + param.put("ttInfoIds", ttInfoIds);
  168 + for (KBaseGenerateCalcuTimeTable_Fact_TTinfo fact_tTinfo : fact_tTinfos) {
  169 + ttInfoIds.add(fact_tTinfo.getId());
  170 + }
  171 + if (!CollectionUtils.isEmpty(ttInfoIds)) {
  172 + NamedParameterJdbcTemplate namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(jdbcTemplate);
  173 + List<KBaseGenerateCalcuTimeTable_Fact_TTInfoDetail> fact_ttInfoDetails = namedParameterJdbcTemplate.query(
  174 + TTINFO_DETAIL_QUERY_SQL,
  175 + param,
  176 + new RowMapper<KBaseGenerateCalcuTimeTable_Fact_TTInfoDetail>() {
  177 + @Override
  178 + public KBaseGenerateCalcuTimeTable_Fact_TTInfoDetail mapRow(ResultSet rs, int rowNum) throws SQLException {
  179 + return KBaseGenerateCalcuTimeTable_Fact_TTInfoDetail.builder()
  180 + .xl(KBaseGenerateCalcuTimeTable_Fact_Line.builder()
  181 + .id(rs.getInt("xl"))
  182 + .build()
  183 + )
  184 + .ttInfo(KBaseGenerateCalcuTimeTable_Fact_TTinfo.getBuilder()
  185 + .setXl(KBaseGenerateCalcuTimeTable_Fact_Line.builder()
  186 + .id(rs.getInt("xl"))
  187 + .build())
  188 + .setId(rs.getLong("ttinfo"))
  189 + .build()
  190 + )
  191 + .lp(KBaseGenerateCalcuTimeTable_Fact_LpInfo.builder()
  192 + .id(rs.getLong("lp"))
  193 + .build()
  194 + )
  195 + .id(rs.getLong("id"))
  196 + .qdzCode(rs.getString("qdz_code"))
  197 + .qdzName(rs.getString("qdz_name"))
  198 + .zdzCode(rs.getString("zdz_code"))
  199 + .zdzName(rs.getString("zdz_name"))
  200 + .fcno(rs.getInt("fcno"))
  201 + .isFB(rs.getBoolean("isfb"))
  202 + .isTS(rs.getBoolean("ists"))
  203 + .xlDir(rs.getString("xl_dir"))
  204 + .bcType(rs.getString("bc_type"))
  205 + .lineVersion(rs.getInt("line_version"))
  206 + .fcsj(rs.getString("fcsj"))
  207 + .bcs(rs.getInt("bcs"))
  208 + .jhlc(rs.getDouble("jhlc"))
  209 + .bcsj(rs.getInt("bcsj"))
  210 + .remark(rs.getString("remark"))
  211 + .build();
  212 +
  213 + }
  214 + }
  215 + );
  216 + for (KBaseGenerateCalcuTimeTable_Fact_TTInfoDetail fact_ttInfoDetail : fact_ttInfoDetails) {
  217 + session.insert(fact_ttInfoDetail);
  218 + }
  219 + }
  220 +
  221 + // 载入路牌fact
  222 + List<KBaseGenerateCalcuTimeTable_Fact_LpInfo> fact_lpInfos = this.jdbcTemplate.query(
  223 + LP_QUERY_SQL,
  224 + new Object[]{xlid},
  225 + new RowMapper<KBaseGenerateCalcuTimeTable_Fact_LpInfo>() {
  226 + @Override
  227 + public KBaseGenerateCalcuTimeTable_Fact_LpInfo mapRow(ResultSet rs, int rowNum) throws SQLException {
  228 + return KBaseGenerateCalcuTimeTable_Fact_LpInfo.builder()
  229 + .xl(KBaseGenerateCalcuTimeTable_Fact_Line.builder().id(rs.getInt("xl")).build())
  230 + .id(rs.getLong("id"))
  231 + .name(rs.getString("lp_name"))
  232 + .build();
  233 + }
  234 + }
  235 + );
  236 + for (KBaseGenerateCalcuTimeTable_Fact_LpInfo fact_lpInfo : fact_lpInfos) {
  237 + session.insert(fact_lpInfo);
  238 + }
  239 +
  240 + // 执行rule
  241 + session.fireAllRules();
  242 +
  243 + // 执行完毕销毁,有日志的也要关闭
  244 + session.dispose();
  245 +
  246 + LOGGER.info("KieBase[{}],线路id={},开始日期={},结束日期={} 完成",
  247 + "排班生成 - 1、计算时刻表相关信息",
  248 + calcuParam.getXl().getId(),
  249 + calcuParam.getFromDate(),
  250 + calcuParam.getToDate());
  251 +
  252 + return rs;
  253 + }
  254 +
  255 + private PlanProcessGenerateCalcuTimeTableServiceDroolsImpl() {}
  256 + private PlanProcessGenerateCalcuTimeTableServiceDroolsImpl(Builder builder) {
  257 + this.kBaseGenerateCalcuTimeTable = builder.kBaseGenerateCalcuTimeTable;
  258 + this.jdbcTemplate = builder.jdbcTemplate;
  259 +
  260 + }
  261 +
  262 + public static Builder getBuilder() {
  263 + return new Builder();
  264 + }
  265 +
  266 + public static class Builder {
  267 + /** 计算时刻表drools kbase */
  268 + private KieBase kBaseGenerateCalcuTimeTable;
  269 +
  270 + /** 使用的jdbc服务 */
  271 + private JdbcTemplate jdbcTemplate;
  272 +
  273 + public Builder setkBaseGenerateCalcuTimeTable(KieBase kBaseGenerateCalcuTimeTable) {
  274 + this.kBaseGenerateCalcuTimeTable = kBaseGenerateCalcuTimeTable;
  275 + return this;
  276 + }
  277 +
  278 + public Builder setJdbcTemplate(JdbcTemplate jdbcTemplate) {
  279 + this.jdbcTemplate = jdbcTemplate;
  280 + return this;
  281 + }
  282 +
  283 + public PlanProcessGenerateCalcuTimeTableServiceDroolsImpl build() {
  284 + return new PlanProcessGenerateCalcuTimeTableServiceDroolsImpl(this);
  285 + }
  286 + }
  287 +}
... ...
src/main/java/com/bsth/service/schedule/plan/process/_2_generate/_1_calcu/_2_timetable/drools/KBaseGenerateCalcuTimeTable_Fact_CalcuParam.java 0 → 100644
  1 +package com.bsth.service.schedule.plan.process._2_generate._1_calcu._2_timetable.drools;
  2 +
  3 +import lombok.AllArgsConstructor;
  4 +import lombok.Builder;
  5 +import lombok.Data;
  6 +import org.joda.time.DateTime;
  7 +
  8 +/**
  9 + * drools规则计算时刻表信息使用的参数fact对象。
  10 + */
  11 +@Data
  12 +@Builder
  13 +@AllArgsConstructor
  14 +public class KBaseGenerateCalcuTimeTable_Fact_CalcuParam {
  15 + /** 线路信息 */
  16 + private KBaseGenerateCalcuTimeTable_Fact_Line xl;
  17 + /** 开始计算时间 */
  18 + private DateTime fromDate;
  19 + /** 结束计算时间 */
  20 + private DateTime toDate;
  21 +}
... ...
src/main/java/com/bsth/service/schedule/plan/process/_2_generate/_1_calcu/_2_timetable/drools/KBaseGenerateCalcuTimeTable_Fact_Line.java 0 → 100644
  1 +package com.bsth.service.schedule.plan.process._2_generate._1_calcu._2_timetable.drools;
  2 +
  3 +import lombok.AllArgsConstructor;
  4 +import lombok.Builder;
  5 +import lombok.Data;
  6 +
  7 +/**
  8 + * drools规则计算时刻表信息使用的线路fact对象。
  9 + */
  10 +@Data
  11 +@Builder
  12 +@AllArgsConstructor
  13 +public class KBaseGenerateCalcuTimeTable_Fact_Line {
  14 + /** 主键id */
  15 + private Integer id;
  16 + /** 线路名称 */
  17 + private String name;
  18 +}
... ...
src/main/java/com/bsth/service/schedule/plan/process/_2_generate/_1_calcu/_2_timetable/drools/KBaseGenerateCalcuTimeTable_Fact_LpInfo.java 0 → 100644
  1 +package com.bsth.service.schedule.plan.process._2_generate._1_calcu._2_timetable.drools;
  2 +
  3 +import lombok.AllArgsConstructor;
  4 +import lombok.Builder;
  5 +import lombok.Data;
  6 +
  7 +/**
  8 + * drools规则计算时刻表信息使用的路牌fact对象。
  9 + */
  10 +@Data
  11 +@Builder
  12 +@AllArgsConstructor
  13 +public class KBaseGenerateCalcuTimeTable_Fact_LpInfo {
  14 + /** 线路信息 */
  15 + private KBaseGenerateCalcuTimeTable_Fact_Line xl;
  16 + /** 路牌Id */
  17 + private Long id;
  18 + /** 路牌名字 */
  19 + private String name;
  20 +}
... ...
src/main/java/com/bsth/service/schedule/plan/process/_2_generate/_1_calcu/_2_timetable/drools/KBaseGenerateCalcuTimeTable_Fact_Rule.java 0 → 100644
  1 +package com.bsth.service.schedule.plan.process._2_generate._1_calcu._2_timetable.drools;
  2 +
  3 +import lombok.AllArgsConstructor;
  4 +import lombok.Builder;
  5 +import lombok.Data;
  6 +
  7 +import java.util.Date;
  8 +
  9 +/**
  10 + * drools规则计算时刻表信息使用的规则fact对象
  11 + */
  12 +@Data
  13 +@Builder
  14 +@AllArgsConstructor
  15 +public class KBaseGenerateCalcuTimeTable_Fact_Rule {
  16 + /** 主键Id */
  17 + private Long id;
  18 + /** 启用日期 */
  19 + private Date qyrq;
  20 + /** 对应的路牌ids(用逗号隔开) */
  21 + private String lpIds;
  22 + /** 路牌名称s(用逗号隔开) */
  23 + private String lpNames;
  24 + /** 起始路牌(从0开始) */
  25 + private Integer lpStart;
  26 + /** 对应的人员配置ids(用逗号隔开,如果分班,就先-隔开再逗号隔开) */
  27 + private String ryConfigIds;
  28 + /** 人员搭班编码s(用逗号隔开,如果分班,就先-隔开再逗号隔开) */
  29 + private String ryDbbms;
  30 + /** 起始人员(从0开始) */
  31 + private Integer ryStart;
  32 +
  33 + /** 关联车辆配置 */
  34 + private KBaseGenerateCalcuTimeTable_Fact_VehicleConfig carConfigInfo;
  35 + /** 关联线路 */
  36 + private KBaseGenerateCalcuTimeTable_Fact_Line xl;
  37 +}
... ...
src/main/java/com/bsth/service/schedule/plan/process/_2_generate/_1_calcu/_2_timetable/drools/KBaseGenerateCalcuTimeTable_Fact_TTInfoDetail.java 0 → 100644
  1 +package com.bsth.service.schedule.plan.process._2_generate._1_calcu._2_timetable.drools;
  2 +
  3 +import lombok.AllArgsConstructor;
  4 +import lombok.Builder;
  5 +import lombok.Data;
  6 +
  7 +/**
  8 + * drools规则计算时刻表信息使用的时刻表明细fact对象。
  9 + */
  10 +@Data
  11 +@Builder
  12 +@AllArgsConstructor
  13 +public class KBaseGenerateCalcuTimeTable_Fact_TTInfoDetail {
  14 + /** 线路 */
  15 + private KBaseGenerateCalcuTimeTable_Fact_Line xl;
  16 + /** 时刻表 */
  17 + private KBaseGenerateCalcuTimeTable_Fact_TTinfo ttInfo;
  18 + /** 路牌 */
  19 + private KBaseGenerateCalcuTimeTable_Fact_LpInfo lp;
  20 +
  21 + /** 主健Id */
  22 + private Long id;
  23 +
  24 + // 站点包括普通站点和停车场(站点编码不同,使用站点编码区分)
  25 + // 以后不需要再区分是站点还是停车场了
  26 + /** 起站点代码(bsth_c_station,bsth_c_car_park 里的编码) */
  27 + private String qdzCode;
  28 + /** 起站点名字(bsth_c_stationroute,bsth_c_car_park里的名字) */
  29 + private String qdzName;
  30 + /** 终点站代码(bsth_c_station,bsth_c_car_park 里的编码) */
  31 + private String zdzCode;
  32 + /** 终点站名字(bsth_c_stationroute,bsth_c_car_park里的名字) */
  33 + private String zdzName;
  34 +
  35 + /** 发车顺序号 */
  36 + private Integer fcno;
  37 + /** 是否分班(表示这个班次是否是晚班班次,就是换另外一个驾驶员开)*/
  38 + private Boolean isFB;
  39 + /** 是否停驶(表示此班次执行完成,停在终点站,不进场) */
  40 + private Boolean isTS;
  41 +
  42 + /** 线路方向(TODO:上下行,上行,下行,这个以后用枚举还是字典再议,现在先用文字) */
  43 + private String xlDir;
  44 + /** 班次类型 字典type=ScheduleType */
  45 + private String bcType;
  46 +
  47 + /** 线路版本(bsth_c_line_versions表对应字段) */
  48 + private int lineVersion;
  49 + /** 发车时间(格式 HH:mm) */
  50 + private String fcsj;
  51 + /** 对应班次数 */
  52 + private Integer bcs;
  53 + /** 计划里程 */
  54 + private Double jhlc;
  55 + /** 班次历时 */
  56 + private Integer bcsj;
  57 +
  58 + /** 备注 */
  59 + private String remark;
  60 +}
... ...
src/main/java/com/bsth/service/schedule/plan/process/_2_generate/_1_calcu/_2_timetable/drools/KBaseGenerateCalcuTimeTable_Fact_TTinfo.java 0 → 100644
  1 +package com.bsth.service.schedule.plan.process._2_generate._1_calcu._2_timetable.drools;
  2 +
  3 +import org.apache.commons.lang3.StringUtils;
  4 +import org.apache.commons.lang3.time.DateFormatUtils;
  5 +import org.joda.time.DateTime;
  6 +
  7 +import java.text.ParseException;
  8 +import java.util.ArrayList;
  9 +import java.util.List;
  10 +
  11 +/**
  12 + * drools规则计算时刻表信息使用的时刻表fact对象。
  13 + */
  14 +public class KBaseGenerateCalcuTimeTable_Fact_TTinfo {
  15 + /** 主键Id */
  16 + private Long id;
  17 +
  18 + /** 线路关联 */
  19 + private KBaseGenerateCalcuTimeTable_Fact_Line xl;
  20 +
  21 + /** 时刻表名称 */
  22 + private String name;
  23 +
  24 + // TODO:原系统里的分别在,圈后圈进场,意思不知道,再议
  25 +
  26 + /** 常规有效日(1-7表示星期一到星期日,多个用逗号隔开) */
  27 + private String rule_days;
  28 + /** 特殊有效日期(格式:2001-01-01,多个用逗号隔开) */
  29 + private String special_days;
  30 +
  31 + /** 常规有效日(参照rule_days,1=true表示启用,0=false表示未启用,一个星期7天,保存7个元素) */
  32 + private List<Boolean> weekdayList = new ArrayList<>();
  33 + /** 特殊有效日期(参照special_days,1个日期保存1个元素) */
  34 + private List<DateTime> specialDayList = new ArrayList<>();
  35 +
  36 + /** 线路版本(bsth_c_line_versions表对应字段) */
  37 + private int lineVersion;
  38 +
  39 + public Long getId() {
  40 + return id;
  41 + }
  42 +
  43 + public void setId(Long id) {
  44 + this.id = id;
  45 + }
  46 +
  47 + public KBaseGenerateCalcuTimeTable_Fact_Line getXl() {
  48 + return xl;
  49 + }
  50 +
  51 + public void setXl(KBaseGenerateCalcuTimeTable_Fact_Line xl) {
  52 + this.xl = xl;
  53 + }
  54 +
  55 + public String getName() {
  56 + return name;
  57 + }
  58 +
  59 + public void setName(String name) {
  60 + this.name = name;
  61 + }
  62 +
  63 + public String getRule_days() {
  64 + return rule_days;
  65 + }
  66 +
  67 + public void setRule_days(String rule_days) {
  68 + this.rule_days = rule_days;
  69 + }
  70 +
  71 + public String getSpecial_days() {
  72 + return special_days;
  73 + }
  74 +
  75 + public void setSpecial_days(String special_days) {
  76 + this.special_days = special_days;
  77 + }
  78 +
  79 + public List<Boolean> getWeekdayList() {
  80 + return weekdayList;
  81 + }
  82 +
  83 + public void setWeekdayList(List<Boolean> weekdayList) {
  84 + this.weekdayList = weekdayList;
  85 + }
  86 +
  87 + public List<DateTime> getSpecialDayList() {
  88 + return specialDayList;
  89 + }
  90 +
  91 + public void setSpecialDayList(List<DateTime> specialDayList) {
  92 + this.specialDayList = specialDayList;
  93 + }
  94 +
  95 + public int getLineVersion() {
  96 + return lineVersion;
  97 + }
  98 +
  99 + public void setLineVersion(int lineVersion) {
  100 + this.lineVersion = lineVersion;
  101 + }
  102 +
  103 + public KBaseGenerateCalcuTimeTable_Fact_TTinfo(Builder builder) {
  104 + this.id = builder.id;
  105 +
  106 + this.xl = builder.xl;
  107 +
  108 + this.name = builder.name;
  109 +
  110 + this.rule_days = builder.rule_days;
  111 + this.special_days = builder.special_days;
  112 + this.weekdayList = builder.weekdayList;
  113 + this.specialDayList = builder.specialDayList;
  114 +
  115 + this.lineVersion = builder.lineVersion;
  116 +
  117 + }
  118 +
  119 + //------------------- builder模式 -----------------//
  120 + public static Builder getBuilder() {
  121 + return new Builder();
  122 + }
  123 + public static class Builder {
  124 + /** 主键Id */
  125 + private Long id;
  126 +
  127 + /** 线路关联 */
  128 + private KBaseGenerateCalcuTimeTable_Fact_Line xl;
  129 +
  130 + /** 时刻表名称 */
  131 + private String name;
  132 +
  133 + // TODO:原系统里的分别在,圈后圈进场,意思不知道,再议
  134 +
  135 + /** 常规有效日(1-7表示星期一到星期日,多个用逗号隔开) */
  136 + private String rule_days;
  137 + /** 特殊有效日期(格式:2001-01-01,多个用逗号隔开) */
  138 + private String special_days;
  139 +
  140 + /** 常规有效日(参照rule_days,1=true表示启用,0=false表示未启用,一个星期7天,保存7个元素) */
  141 + private List<Boolean> weekdayList = new ArrayList<>();
  142 + /** 特殊有效日期(参照special_days,1个日期保存1个元素) */
  143 + private List<DateTime> specialDayList = new ArrayList<>();
  144 +
  145 + /** 线路版本(bsth_c_line_versions表对应字段) */
  146 + private int lineVersion;
  147 +
  148 + public Builder() {
  149 + // 初始化 weekdayList,7个元素为FALSE
  150 + for (int i = 0; i < 7; i++) {
  151 + this.weekdayList.add(Boolean.FALSE);
  152 + }
  153 + }
  154 +
  155 + public Builder setId(Long id) {
  156 + this.id = id;
  157 + return this;
  158 + }
  159 +
  160 + public Builder setXl(KBaseGenerateCalcuTimeTable_Fact_Line xl) {
  161 + this.xl = xl;
  162 + return this;
  163 + }
  164 +
  165 + public Builder setName(String name) {
  166 + this.name = name;
  167 + return this;
  168 + }
  169 +
  170 + public Builder setRule_days(String rule_days) {
  171 + this.rule_days = rule_days;
  172 + return this;
  173 + }
  174 +
  175 + public Builder setSpecial_days(String special_days) {
  176 + this.special_days = special_days;
  177 + return this;
  178 + }
  179 +
  180 + public Builder setWeekdayList(String rule_days) {
  181 + // 初始化weekday,全false
  182 + this.weekdayList = new ArrayList<>(7);
  183 + for (int i = 0; i < 7; i++) {
  184 + this.weekdayList.add(Boolean.FALSE);
  185 + }
  186 + // 1表示工作,其他表示不工作
  187 + if (StringUtils.isNotEmpty(rule_days)) {
  188 + String[] days = rule_days.split(",");
  189 + for (int i = 0; i < 7 && i < days.length; i++) {
  190 + if ("1".equals(days[i])) {
  191 + this.weekdayList.set(i, Boolean.TRUE);
  192 + } else {
  193 + this.weekdayList.set(i, Boolean.FALSE);
  194 + }
  195 + }
  196 + }
  197 + return this;
  198 + }
  199 +
  200 + public Builder setSpecialDayList(String special_days) {
  201 + this.specialDayList = new ArrayList<>();
  202 + if (StringUtils.isNotEmpty(special_days)) {
  203 + String[] days = special_days.split(",");
  204 + for (String day : days) {
  205 + try {
  206 + this.specialDayList.add(new DateTime(DateFormatUtils.ISO_DATE_FORMAT.parse(day)));
  207 + } catch (ParseException exp) {
  208 + throw new RuntimeException(exp);
  209 + }
  210 + }
  211 + }
  212 + return this;
  213 + }
  214 +
  215 + public Builder setLineVersion(int lineVersion) {
  216 + this.lineVersion = lineVersion;
  217 + return this;
  218 + }
  219 +
  220 + public KBaseGenerateCalcuTimeTable_Fact_TTinfo build() {
  221 + return new KBaseGenerateCalcuTimeTable_Fact_TTinfo(this);
  222 + }
  223 + }
  224 +}
... ...
src/main/java/com/bsth/service/schedule/plan/process/_2_generate/_1_calcu/_2_timetable/drools/KBaseGenerateCalcuTimeTable_Fact_Vehicle.java 0 → 100644
  1 +package com.bsth.service.schedule.plan.process._2_generate._1_calcu._2_timetable.drools;
  2 +
  3 +import lombok.AllArgsConstructor;
  4 +import lombok.Builder;
  5 +import lombok.Data;
  6 +
  7 +/**
  8 + * drools规则计算时刻表信息使用的车辆fact对象。
  9 + */
  10 +@Data
  11 +@Builder
  12 +@AllArgsConstructor
  13 +public class KBaseGenerateCalcuTimeTable_Fact_Vehicle {
  14 + /** 主键Id */
  15 + private Integer id;
  16 + /** 自编号/内部编号 */
  17 + private String insideCode;
  18 +}
... ...
src/main/java/com/bsth/service/schedule/plan/process/_2_generate/_1_calcu/_2_timetable/drools/KBaseGenerateCalcuTimeTable_Fact_VehicleConfig.java 0 → 100644
  1 +package com.bsth.service.schedule.plan.process._2_generate._1_calcu._2_timetable.drools;
  2 +
  3 +import lombok.AllArgsConstructor;
  4 +import lombok.Builder;
  5 +import lombok.Data;
  6 +
  7 +/**
  8 + * drools规则计算时刻表信息使用的车辆配置fact对象。
  9 + */
  10 +@Data
  11 +@Builder
  12 +@AllArgsConstructor
  13 +public class KBaseGenerateCalcuTimeTable_Fact_VehicleConfig {
  14 + /** 主健Id */
  15 + private Long id;
  16 + /** 线路 */
  17 + private KBaseGenerateCalcuTimeTable_Fact_Line xl;
  18 + /** 车辆 */
  19 + private KBaseGenerateCalcuTimeTable_Fact_Vehicle cl;
  20 +}
... ...
src/main/java/com/bsth/service/schedule/plan/process/_2_generate/_1_calcu/_2_timetable/drools/KBaseGenerateCalcuTimeTable_Function_MinRuleQyrq.java 0 → 100644
  1 +package com.bsth.service.schedule.plan.process._2_generate._1_calcu._2_timetable.drools;
  2 +
  3 +import org.joda.time.DateTime;
  4 +import org.kie.api.runtime.rule.AccumulateFunction;
  5 +
  6 +import java.io.*;
  7 +
  8 +/**
  9 + * drools规则计算时刻表信息用的函数(计算规则中最早的启用日期)。
  10 + *
  11 + */
  12 +public class KBaseGenerateCalcuTimeTable_Function_MinRuleQyrq implements AccumulateFunction {
  13 + @Override
  14 + public void writeExternal(ObjectOutput out) throws IOException {
  15 + }
  16 +
  17 + @Override
  18 + public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
  19 +
  20 + }
  21 +
  22 + protected static class MinRuleQyrqData implements Externalizable {
  23 + public DateTime min;
  24 + // 最大的最小值,比它小的不计算
  25 + public DateTime maxMin = new DateTime(2014,1,1,0,0);
  26 +
  27 + public MinRuleQyrqData() {}
  28 +
  29 + @Override
  30 + public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
  31 + min = (DateTime) in.readObject();
  32 + }
  33 +
  34 + @Override
  35 + public void writeExternal(ObjectOutput out) throws IOException {
  36 + out.writeObject(min);
  37 + }
  38 + }
  39 +
  40 + @Override
  41 + public Serializable createContext() {
  42 + return new MinRuleQyrqData();
  43 + }
  44 +
  45 + @Override
  46 + public void init(Serializable context) throws Exception { }
  47 +
  48 + @Override
  49 + public void accumulate(Serializable context, Object value) {
  50 + MinRuleQyrqData minRuleQyrqData = (MinRuleQyrqData) context;
  51 + KBaseGenerateCalcuTimeTable_Fact_Rule fact_rule = (KBaseGenerateCalcuTimeTable_Fact_Rule) value;
  52 +
  53 + DateTime qyrq = new DateTime(fact_rule.getQyrq());
  54 + if (qyrq.isAfter(minRuleQyrqData.maxMin)) {
  55 + if (minRuleQyrqData.min == null) {
  56 + minRuleQyrqData.min = qyrq;
  57 + } else if (qyrq.isBefore(minRuleQyrqData.min)) {
  58 + minRuleQyrqData.min = qyrq;
  59 + }
  60 + }
  61 +
  62 + }
  63 +
  64 + @Override
  65 + public boolean supportsReverse() {
  66 + return false;
  67 + }
  68 +
  69 + @Override
  70 + public void reverse(Serializable serializable, Object o) throws Exception {
  71 +
  72 + }
  73 +
  74 + @Override
  75 + public Class<?> getResultType() {
  76 + return DateTime.class;
  77 + }
  78 +
  79 + @Override
  80 + public Object getResult(Serializable context) throws Exception {
  81 + MinRuleQyrqData minRuleQyrqData = (MinRuleQyrqData) context;
  82 + return minRuleQyrqData.min;
  83 + }
  84 +}
... ...
src/main/java/com/bsth/service/schedule/plan/process/_2_generate/_1_calcu/_2_timetable/drools/KBaseGenerateCalcuTimeTable_Function_Result.java 0 → 100644
  1 +package com.bsth.service.schedule.plan.process._2_generate._1_calcu._2_timetable.drools;
  2 +
  3 +import com.bsth.service.schedule.plan.process._2_generate._1_calcu._2_timetable.PlanProcessGenerateCalcuTimeTableService.*;
  4 +import org.kie.api.runtime.rule.AccumulateFunction;
  5 +import org.springframework.util.CollectionUtils;
  6 +
  7 +import java.io.IOException;
  8 +import java.io.ObjectInput;
  9 +import java.io.ObjectOutput;
  10 +import java.io.Serializable;
  11 +import java.util.ArrayList;
  12 +import java.util.HashMap;
  13 +import java.util.List;
  14 +import java.util.Map;
  15 +
  16 +/**
  17 + * drools规则计算时刻表信息用的函数(计算Result 当前线路,指定排班日期,使用的时刻表,对应的路牌,以及对应路牌的时刻表班次列表)
  18 + */
  19 +public class KBaseGenerateCalcuTimeTable_Function_Result implements AccumulateFunction {
  20 + @Override
  21 + public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
  22 +
  23 + }
  24 +
  25 + @Override
  26 + public void writeExternal(ObjectOutput out) throws IOException {
  27 +
  28 + }
  29 +
  30 + protected static class ResultContext implements Serializable {
  31 + private Map<Long, KBaseGenerateCalcuTimeTable_Fact_TTInfoDetail> fact_ttInfoDetailMap;
  32 +
  33 + public ResultContext() {
  34 + this.fact_ttInfoDetailMap = new HashMap<>();
  35 + }
  36 +
  37 + public void add(KBaseGenerateCalcuTimeTable_Fact_TTInfoDetail fact_ttInfoDetail) {
  38 + fact_ttInfoDetailMap.put(fact_ttInfoDetail.getId(), fact_ttInfoDetail);
  39 + }
  40 +
  41 + public void remove(KBaseGenerateCalcuTimeTable_Fact_TTInfoDetail fact_ttInfoDetail) {
  42 + fact_ttInfoDetailMap.remove(fact_ttInfoDetail.getId());
  43 + }
  44 +
  45 + public TTinfoDetailByLpResult result() {
  46 + List<KBaseGenerateCalcuTimeTable_Fact_TTInfoDetail> fact_ttInfoDetails = new ArrayList<>();
  47 + fact_ttInfoDetails.addAll(fact_ttInfoDetailMap.values());
  48 +
  49 + // 输出结果
  50 + TTinfoDetailByLpResult result = TTinfoDetailByLpResult.builder()
  51 + .tTinfoDetailResultList(new ArrayList<TTinfoDetailResult>())
  52 + .build();
  53 +
  54 + // 注意:drl匹配的时候可能没有班次,直接返回result,drl获取result后需要过滤班次列表为空的result
  55 + if (CollectionUtils.isEmpty(fact_ttInfoDetails)) {
  56 + return result;
  57 + }
  58 +
  59 + // 1、线路(相关drl负责添加)
  60 + // 2、路牌(相关drl负责添加)
  61 + // 3、排班日期(相关drl负责添加)
  62 + // 4、对应的时刻表
  63 + KBaseGenerateCalcuTimeTable_Fact_TTinfo fact_tTinfo = fact_ttInfoDetails.get(0).getTtInfo();
  64 + result.setTTinfoResult(TTinfoResult.builder()
  65 + .id(fact_tTinfo.getId())
  66 + .xl(LineResult.builder()
  67 + .id(fact_tTinfo.getXl().getId())
  68 + .build())
  69 + .name(fact_tTinfo.getName())
  70 + .rule_days(fact_tTinfo.getRule_days())
  71 + .special_days(fact_tTinfo.getSpecial_days())
  72 + .weekdayList(fact_tTinfo.getWeekdayList())
  73 + .special_days(fact_tTinfo.getSpecial_days())
  74 + .lineVersion(fact_tTinfo.getLineVersion())
  75 + .build());
  76 + // 5、路牌对应的时刻表时刻表明细列表
  77 + for (KBaseGenerateCalcuTimeTable_Fact_TTInfoDetail fact_ttInfoDetail : fact_ttInfoDetails) {
  78 + TTinfoDetailResult tTinfoDetailResult = TTinfoDetailResult.builder()
  79 + .xl(LineResult.builder()
  80 + .id(fact_ttInfoDetail.getXl().getId())
  81 + .build())
  82 + .ttInfo(TTinfoResult.builder()
  83 + .id(fact_ttInfoDetail.getTtInfo().getId())
  84 + .build())
  85 + .lp(LpInfoResult.builder()
  86 + .id(fact_ttInfoDetail.getLp().getId())
  87 + .build())
  88 + .id(fact_ttInfoDetail.getId())
  89 + .qdzCode(fact_ttInfoDetail.getQdzCode())
  90 + .qdzName(fact_ttInfoDetail.getQdzName())
  91 + .zdzCode(fact_ttInfoDetail.getZdzCode())
  92 + .zdzName(fact_ttInfoDetail.getZdzName())
  93 + .fcno(fact_ttInfoDetail.getFcno())
  94 + .isFB(fact_ttInfoDetail.getIsFB())
  95 + .isTS(fact_ttInfoDetail.getIsTS())
  96 + .xlDir(fact_ttInfoDetail.getXlDir())
  97 + .bcType(fact_ttInfoDetail.getBcType())
  98 + .lineVersion(fact_ttInfoDetail.getLineVersion())
  99 + .fcsj(fact_ttInfoDetail.getFcsj())
  100 + .bcs(fact_ttInfoDetail.getBcs())
  101 + .jhlc(fact_ttInfoDetail.getJhlc())
  102 + .bcsj(fact_ttInfoDetail.getBcsj())
  103 + .remark(fact_ttInfoDetail.getRemark())
  104 + .build();
  105 + result.getTTinfoDetailResultList().add(tTinfoDetailResult);
  106 + }
  107 +
  108 + // 6、计算最小,最大,分班发车顺序号
  109 + Integer minFcno = null;
  110 + Integer maxFcno = null;
  111 + Integer fbFcno = null;
  112 + for (KBaseGenerateCalcuTimeTable_Fact_TTInfoDetail fact_ttInfoDetail : fact_ttInfoDetails) {
  113 + Integer fcno = fact_ttInfoDetail.getFcno();
  114 + if (minFcno == null) { // 最小发车顺序号
  115 + minFcno = fcno;
  116 + } else if (fcno < minFcno) {
  117 + minFcno = fcno;
  118 + }
  119 +
  120 + if (maxFcno == null) { // 最大发车顺序号
  121 + maxFcno = fcno;
  122 + } else if (fcno > maxFcno) {
  123 + maxFcno = fcno;
  124 + }
  125 +
  126 + if (fact_ttInfoDetail.getIsFB() == true) { // 记录分班发车顺序号(注意多个分班可能会乱)
  127 + fbFcno = fcno;
  128 + }
  129 + }
  130 +
  131 + result.setMinFcno(minFcno);
  132 + result.setMaxFcno(maxFcno);
  133 + result.setStartFbFcno(fbFcno);
  134 +
  135 + return result;
  136 + }
  137 +
  138 + }
  139 +
  140 + @Override
  141 + public Serializable createContext() {
  142 + return new ResultContext();
  143 + }
  144 +
  145 + @Override
  146 + public void init(Serializable context) throws Exception {
  147 +
  148 + }
  149 +
  150 + @Override
  151 + public void accumulate(Serializable context, Object value) {
  152 + ResultContext resultContext = (ResultContext) context;
  153 + KBaseGenerateCalcuTimeTable_Fact_TTInfoDetail fact_ttInfoDetail =
  154 + (KBaseGenerateCalcuTimeTable_Fact_TTInfoDetail) value;
  155 + resultContext.add(fact_ttInfoDetail);
  156 + }
  157 +
  158 + @Override
  159 + public void reverse(Serializable context, Object value) throws Exception {
  160 + ResultContext resultContext = (ResultContext) context;
  161 + KBaseGenerateCalcuTimeTable_Fact_TTInfoDetail fact_ttInfoDetail =
  162 + (KBaseGenerateCalcuTimeTable_Fact_TTInfoDetail) value;
  163 + resultContext.remove(fact_ttInfoDetail);
  164 + }
  165 +
  166 + @Override
  167 + public Object getResult(Serializable context) throws Exception {
  168 + ResultContext resultContext = (ResultContext) context;
  169 + return resultContext.result();
  170 + }
  171 +
  172 + @Override
  173 + public boolean supportsReverse() {
  174 + return true;
  175 + }
  176 +
  177 + @Override
  178 + public Class<?> getResultType() {
  179 + return TTinfoDetailByLpResult.class;
  180 + }
  181 +}
... ...
src/main/resources/META-INF/drools.packagebuilder.conf
... ... @@ -18,3 +18,6 @@ drools.accumulate.function.ac = com.bsth.service.schedule.plan.process._1_valida
18 18 drools.accumulate.function.ae = com.bsth.service.schedule.plan.process._1_validate._1_timetable.drools.KBaseValidateTimeTable_Function_AccumulateEmpty
19 19 # kBase_validate_rule.drl使用
20 20 drools.accumulate.function.srif2 = com.bsth.service.schedule.plan.process._1_validate._2_rule.drools.KBaseValidateRule_Function_ErrorInfo
  21 +# KBase_generate_calcu_timetable使用
  22 +drools.accumulate.function.minruleqyrq2 = com.bsth.service.schedule.plan.process._2_generate._1_calcu._2_timetable.drools.KBaseGenerateCalcuTimeTable_Function_MinRuleQyrq
  23 +drools.accumulate.function.tresult = com.bsth.service.schedule.plan.process._2_generate._1_calcu._2_timetable.drools.KBaseGenerateCalcuTimeTable_Function_Result
... ...
src/main/resources/drools/KBase/generate/calcu/timetable/KBase_generate_calcu_timetable.drl 0 → 100644
  1 +package com.bsth.service.schedule.plan.process._2_generate._1_calcu._2_timetable.drools;
  2 +
  3 +import org.joda.time.*;
  4 +import java.util.*;
  5 +
  6 +import com.bsth.service.schedule.plan.process._2_generate._1_calcu._2_timetable.drools.KBaseGenerateCalcuTimeTable_Fact_CalcuParam;
  7 +import com.bsth.service.schedule.plan.process._2_generate._1_calcu._2_timetable.drools.KBaseGenerateCalcuTimeTable_Fact_Rule;
  8 +import com.bsth.service.schedule.plan.process._2_generate._1_calcu._2_timetable.drools.KBaseGenerateCalcuTimeTable_Fact_TTinfo;
  9 +import com.bsth.service.schedule.plan.process._2_generate._1_calcu._2_timetable.drools.KBaseGenerateCalcuTimeTable_Fact_TTInfoDetail;
  10 +import com.bsth.service.schedule.plan.process._2_generate._1_calcu._2_timetable.drools.KBaseGenerateCalcuTimeTable_Fact_Line;
  11 +import com.bsth.service.schedule.plan.process._2_generate._1_calcu._2_timetable.drools.KBaseGenerateCalcuTimeTable_Fact_LpInfo;
  12 +
  13 +import com.bsth.service.schedule.plan.process._2_generate._1_calcu._2_timetable.PlanProcessGenerateCalcuTimeTableService.*;
  14 +
  15 +import org.slf4j.Logger;
  16 +
  17 +// 全局日志类
  18 +global Logger LOGGER;
  19 +
  20 +// 输出
  21 +global List rs;
  22 +
  23 +/*
  24 + 规则说明:
  25 + 1、找出指定线路,指定时间范围的时刻表
  26 + 2、如果一天有多个时刻表全部都要输出(注意:一天多时刻表的情况由前置验证规则处理)
  27 +*/
  28 +
  29 +//----------------- pre 预处理 param对象 -----------------------//
  30 +// 将开始排班时间设定为最小的规则启用日期(因为在时刻表模式下的排班,时刻表和排班规则关联)
  31 +rule "pre_CalcuParam"
  32 + no-loop
  33 + salience 1000
  34 + when
  35 + $cp: KBaseGenerateCalcuTimeTable_Fact_CalcuParam($xlId : xl.id)
  36 + $minqyrq: DateTime() from accumulate ($rule: KBaseGenerateCalcuTimeTable_Fact_Rule(xl.id == $xlId), minruleqyrq2($rule))
  37 + then
  38 + LOGGER.info("修正日期={}", $minqyrq);
  39 + $cp.setFromDate($minqyrq);
  40 + update($cp);
  41 +end
  42 +
  43 +//-------------- 第一阶段、计算规则迭代数据(天数) ------------//
  44 +declare Calcu_iter_days_result
  45 + xlId: Integer // 线路Id
  46 + xlName: String // 线路名字
  47 +
  48 + // 迭代数据
  49 + calcu_day: Integer // 准备计算第几天
  50 + calcu_weekday: Integer // 准备计算星期几(1到7)
  51 + calcu_date: DateTime // 准备计算的具体日期
  52 +
  53 + // 范围数据
  54 + calcu_days: Integer // 总共需要计算的天数
  55 + calcu_start_date: DateTime // 开始计算日期
  56 + calcu_end_date: DateTime // 结束计算日期
  57 +
  58 +end
  59 +
  60 +rule "calcu_iter_days"
  61 + salience 900
  62 + when
  63 + KBaseGenerateCalcuTimeTable_Fact_CalcuParam(
  64 + $xlId: xl.id,
  65 + $fromDate: fromDate,
  66 + $toDate: toDate,
  67 + $fromDate.isBefore($toDate) || $fromDate.isEqual($toDate)
  68 + )
  69 + $line: KBaseGenerateCalcuTimeTable_Fact_Line(id == $xlId)
  70 + then
  71 + // 构造Calcu_iter_days_result对象,进行下一步计算
  72 + Calcu_iter_days_result cidr = new Calcu_iter_days_result();
  73 + Period p = new Period($fromDate, $toDate, PeriodType.days());
  74 +
  75 + cidr.setXlId($xlId);
  76 + cidr.setXlName($line.getName());
  77 +
  78 + cidr.setCalcu_day(new Integer(1));
  79 + cidr.setCalcu_weekday(Integer.valueOf($fromDate.getDayOfWeek()));
  80 + cidr.setCalcu_date($fromDate);
  81 +
  82 + cidr.setCalcu_days(Integer.valueOf(p.getDays() + 1));
  83 + cidr.setCalcu_start_date($fromDate);
  84 + cidr.setCalcu_end_date($toDate);
  85 +
  86 + LOGGER.info(
  87 + "线路={}-id={},开始时间={},结束时间={},总共计算的天数={},将从开始时间迭代",
  88 + cidr.getXlName(),
  89 + cidr.getXlId(),
  90 + cidr.getCalcu_start_date(),
  91 + cidr.getCalcu_end_date(),
  92 + cidr.getCalcu_days()
  93 + );
  94 +
  95 + insert(cidr);
  96 +end
  97 +
  98 +//-------------- 第二阶段、时刻表的日期匹配 ------------//
  99 +// 时刻表内部封装
  100 +declare Internal_WrapTTInfo
  101 + calcuDate: DateTime // 具体的日期
  102 + ttInfoSpecialList: List // 时刻表(可能多张)
  103 + ttInfoNormalList: List // 时刻表明细
  104 +end
  105 +
  106 +
  107 +rule "Calcu_iter_days_special_normal_day" // 日期匹配
  108 + salience 800
  109 + when
  110 + $cid : Calcu_iter_days_result(
  111 + $calcu_date: calcu_date,
  112 + $calcu_weekday: calcu_weekday,
  113 + $calcu_day: calcu_day,
  114 + calcu_day <= calcu_days
  115 + )
  116 +
  117 + $ttInfoSpecialList : ArrayList($ss: size) from collect (
  118 + KBaseGenerateCalcuTimeTable_Fact_TTinfo(
  119 + specialDayList contains $calcu_date
  120 + )
  121 + )
  122 +
  123 + $ttInfoNormalList : ArrayList($sn: size) from collect (
  124 + KBaseGenerateCalcuTimeTable_Fact_TTinfo(
  125 + $ss == 0, // 注意:条件=没有特殊日期被匹配到
  126 + specialDayList not contains $calcu_date,
  127 + weekdayList[$calcu_weekday - 1] == Boolean.TRUE
  128 + )
  129 + )
  130 +
  131 + then
  132 + LOGGER.info("日期={},特殊时刻表个数={},一般时刻表个数={}",
  133 + $calcu_date, $ss, $sn);
  134 + Internal_WrapTTInfo internal_WrapTTInfo = new Internal_WrapTTInfo();
  135 + List ttInfoNormalList = new ArrayList();
  136 + List ttInfoSpecialList = new ArrayList();
  137 + ttInfoNormalList.addAll($ttInfoNormalList);
  138 + ttInfoSpecialList.addAll($ttInfoSpecialList);
  139 + internal_WrapTTInfo.setCalcuDate($calcu_date);
  140 + internal_WrapTTInfo.setTtInfoNormalList(ttInfoNormalList);
  141 + internal_WrapTTInfo.setTtInfoSpecialList(ttInfoSpecialList);
  142 + insert(internal_WrapTTInfo);
  143 +
  144 + // 更新迭代对象
  145 + Integer new_calcu_day = Integer.valueOf($calcu_day + 1);
  146 + $cid.setCalcu_day(new_calcu_day);
  147 + DateTime new_calcu_date = $calcu_date.plusDays(1);
  148 + $cid.setCalcu_date(new_calcu_date);
  149 + $cid.setCalcu_weekday(Integer.valueOf(new_calcu_date.getDayOfWeek()));
  150 +
  151 + update($cid);
  152 +
  153 +end
  154 +
  155 +// 整合时刻表封装类
  156 +declare Internal_WrapTTInfo_merge
  157 + calcuDate: DateTime // 具体的日期
  158 + ttInfo: KBaseGenerateCalcuTimeTable_Fact_TTinfo // 对应的时刻表
  159 + ttInfoDetailList: List // 对应的时刻表列表对应的明细列表
  160 +end
  161 +
  162 +rule "Calcu_Internal_WrapTTInfo_merge_has_special_ttInfo" // 整合时刻表(特殊日期匹配)
  163 + salience 700
  164 + when
  165 + Internal_WrapTTInfo(
  166 + ttInfoSpecialList.size() > 0,
  167 + $calcuDate: calcuDate,
  168 + $ttInfoSpecialList: ttInfoSpecialList
  169 + )
  170 + $ttInfo: KBaseGenerateCalcuTimeTable_Fact_TTinfo($ttInfoId: id) from $ttInfoSpecialList
  171 + $ttInfoDetailList: ArrayList(size > 0) from collect (
  172 + KBaseGenerateCalcuTimeTable_Fact_TTInfoDetail(
  173 + ttInfo.id == $ttInfoId
  174 + )
  175 + )
  176 + then
  177 + LOGGER.info("日期={},时刻表id={}", $calcuDate, $ttInfoId);
  178 +
  179 + // 整合时刻表信息
  180 + Internal_WrapTTInfo_merge internal_WrapTTInfo_merge = new Internal_WrapTTInfo_merge();
  181 + internal_WrapTTInfo_merge.setCalcuDate($calcuDate);
  182 + internal_WrapTTInfo_merge.setTtInfo($ttInfo);
  183 + List ttInfoDetailList = new ArrayList();
  184 + ttInfoDetailList.addAll($ttInfoDetailList);
  185 + internal_WrapTTInfo_merge.setTtInfoDetailList(ttInfoDetailList);
  186 + insert(internal_WrapTTInfo_merge);
  187 +
  188 +end
  189 +
  190 +rule "Calcu_Internal_WrapTTInfo_merge_has_normal_ttInfo" // 整合时刻表(一般日期匹配)
  191 + salience 700
  192 + when
  193 + Internal_WrapTTInfo(
  194 + ttInfoNormalList.size() > 0,
  195 + $calcuDate: calcuDate,
  196 + $ttInfoNormalList: ttInfoNormalList
  197 + )
  198 + $ttInfo: KBaseGenerateCalcuTimeTable_Fact_TTinfo($ttInfoId: id) from $ttInfoNormalList
  199 + $ttInfoDetailList: ArrayList(size > 0) from collect (
  200 + KBaseGenerateCalcuTimeTable_Fact_TTInfoDetail(
  201 + ttInfo.id == $ttInfoId
  202 + )
  203 + )
  204 + then
  205 + LOGGER.info("日期={},时刻表id={}", $calcuDate, $ttInfoId);
  206 +
  207 + // 整合时刻表信息
  208 + Internal_WrapTTInfo_merge internal_WrapTTInfo_merge = new Internal_WrapTTInfo_merge();
  209 + internal_WrapTTInfo_merge.setCalcuDate($calcuDate);
  210 + internal_WrapTTInfo_merge.setTtInfo($ttInfo);
  211 + List ttInfoDetailList = new ArrayList();
  212 + ttInfoDetailList.addAll($ttInfoDetailList);
  213 + internal_WrapTTInfo_merge.setTtInfoDetailList(ttInfoDetailList);
  214 + insert(internal_WrapTTInfo_merge);
  215 +
  216 +end
  217 +
  218 +//-------------- 第三阶段、聚合计算输出结果 ------------//
  219 +rule "output_result"
  220 + salience 600
  221 + when
  222 + $line: KBaseGenerateCalcuTimeTable_Fact_Line($xlId: id, $xlName: name)
  223 + Internal_WrapTTInfo_merge(
  224 + ttInfo.xl.id == $xlId,
  225 + $calcuDate: calcuDate,
  226 + $ttInfo: ttInfo,
  227 + $ttInfoDetailList: ttInfoDetailList
  228 + )
  229 + $lp: KBaseGenerateCalcuTimeTable_Fact_LpInfo(
  230 + $ttInfo.xl.id == xl.id,
  231 + $lpId: id,
  232 + $lpName: name
  233 + )
  234 + $result: TTinfoDetailByLpResult(tTinfoDetailResultList.size > 0) from accumulate (
  235 + $ttInfoDetail: KBaseGenerateCalcuTimeTable_Fact_TTInfoDetail(
  236 + ttInfo.id == $ttInfo.id,
  237 + lp.id == $lpId
  238 + ),
  239 + tresult($ttInfoDetail)
  240 + )
  241 + then
  242 + // 1、线路
  243 + $result.setLineResult(LineResult.builder()
  244 + .id($xlId)
  245 + .name($xlName)
  246 + .build());
  247 +
  248 + // 2、路牌
  249 + $result.setLpInfoResult(LpInfoResult.builder()
  250 + .xl($result.getLineResult())
  251 + .id($lpId)
  252 + .name($lpName)
  253 + .build());
  254 +
  255 + // 3、排班日期(相关drl负责添加)
  256 + $result.setScheduleDate($calcuDate);
  257 +
  258 + LOGGER.debug("数据整合时刻表路牌班次输出:日期={} 时刻表id={} 路牌id={} 班次数={} 最小发车顺序号={} 最大发车顺序号={} 开始分班发车顺序号={} ",
  259 + $calcuDate, $ttInfo.getId(), $lpId, $result.getTTinfoDetailResultList().size(),
  260 + $result.getMinFcno(), $result.getMaxFcno(), $result.getStartFbFcno());
  261 +
  262 + rs.add($result);
  263 +
  264 +end
  265 +
... ...
src/main/resources/drools/config.properties
... ... @@ -23,4 +23,5 @@ drools.KBase.validate_timetable=drools/KBase/validate/timetable/KBase_validate_t
23 23 # 规则验证
24 24 drools.KBase.validate_rule=drools/KBase/validate/rule/KBase_validate_rule.drl
25 25  
26   -
  26 +# 排班生成 - 1、计算时刻表相关信息
  27 +drools.KBase.generate_calcu_timetable=drools/KBase/generate/calcu/timetable/KBase_generate_calcu_timetable.drl
... ...
src/test/java/com/bsth/service/schedule/PlanGenerateTest.java 0 → 100644
  1 +package com.bsth.service.schedule;
  2 +
  3 +import com.bsth.BaseTest_junit4;
  4 +import com.bsth.TestApplication;
  5 +import com.bsth.service.schedule.plan.process._2_generate._1_calcu._2_timetable.PlanProcessGenerateCalcuTimeTableService;
  6 +import com.bsth.service.schedule.plan.process._2_generate._1_calcu._2_timetable.PlanProcessGenerateCalcuTimeTableService.*;
  7 +import com.bsth.service.schedule.plan.process._2_generate._1_calcu._2_timetable.PlanProcessGenerateCalcuTimeTableServiceDroolsImpl;
  8 +import org.joda.time.format.DateTimeFormat;
  9 +import org.junit.Assert;
  10 +import org.junit.Test;
  11 +import org.junit.runner.RunWith;
  12 +import org.kie.api.KieBase;
  13 +import org.springframework.beans.factory.annotation.Autowired;
  14 +import org.springframework.beans.factory.annotation.Qualifier;
  15 +import org.springframework.boot.test.SpringApplicationConfiguration;
  16 +import org.springframework.jdbc.core.JdbcTemplate;
  17 +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
  18 +
  19 +import java.util.*;
  20 +
  21 +/**
  22 + * 排班计划生成测试。
  23 + */
  24 +@RunWith(SpringJUnit4ClassRunner.class)
  25 +@SpringApplicationConfiguration(classes = {TestApplication.class})
  26 +public class PlanGenerateTest extends BaseTest_junit4 {
  27 + @Override
  28 + public Map<String, String> getDbunitTestDbFileClassPathMap() {
  29 + Map<String, String> dbFileMap = new HashMap<>();
  30 + dbFileMap.put("_2_generate_calcu_timetable_test_case1", "testdata/_2_generate_calcu_timetable.xml");
  31 + dbFileMap.put("_2_generate_calcu_timetable_test_case2", "testdata/_2_generate_calcu_timetable.xml");
  32 + return dbFileMap;
  33 + }
  34 +
  35 + @Autowired
  36 + @Qualifier("kBaseGenerateCalcuTimeTable_plus")
  37 + private KieBase kBaseGenerateCalcuTimeTable;
  38 +
  39 + @Autowired
  40 + private JdbcTemplate jdbcTemplate;
  41 +
  42 + /**
  43 + * 正常计算时刻表路牌启用,总班次数验证
  44 + * @throws Exception
  45 + */
  46 + @Test
  47 + public void _2_generate_calcu_timetable_test_case1() {
  48 + LOG.info("--------------- 正常计算时刻表路牌启用,总班次数验证 ------------");
  49 +
  50 + // 使用builder创建服务
  51 + PlanProcessGenerateCalcuTimeTableService planProcessGenerateCalcuTimeTableService =
  52 + PlanProcessGenerateCalcuTimeTableServiceDroolsImpl.getBuilder()
  53 + .setkBaseGenerateCalcuTimeTable(kBaseGenerateCalcuTimeTable)
  54 + .setJdbcTemplate(jdbcTemplate)
  55 + .build();
  56 +
  57 + // 注意:数据有当日重复的时刻表匹配(包括特殊节假日重复和平日重复)
  58 + // 1、当日重复时刻表在业务上一般是错误的(由前置验证规则过滤)
  59 + // 2、到了排班的阶段,计算时刻表重复时是不会过滤的
  60 + List<TTinfoDetailByLpResult> tTinfoDetailByLpResultList = planProcessGenerateCalcuTimeTableService.generateCalcuTTInfos(
  61 + 1,
  62 + DateTimeFormat.forPattern("yyyy-MM-dd").parseDateTime("2019-01-05").toDate(),
  63 + DateTimeFormat.forPattern("yyyy-MM-dd").parseDateTime("2019-01-14").toDate()
  64 + );
  65 + Assert.assertArrayEquals(
  66 + "时刻表路牌班次信息不匹配",
  67 + new Object[] {33},
  68 + new Object[] {tTinfoDetailByLpResultList.size()}
  69 + );
  70 +
  71 + }
  72 +
  73 + /**
  74 + * 单独测试某一天的时刻表路牌班次明细属性是否正常。
  75 + * @throws Exception
  76 + */
  77 + @Test
  78 + public void _2_generate_calcu_timetable_test_case2() {
  79 + LOG.info("--------------- 单独测试某一天的时刻表路牌班次明细属性 ------------");
  80 +
  81 + // 使用builder创建服务
  82 + PlanProcessGenerateCalcuTimeTableService planProcessGenerateCalcuTimeTableService =
  83 + PlanProcessGenerateCalcuTimeTableServiceDroolsImpl.getBuilder()
  84 + .setkBaseGenerateCalcuTimeTable(kBaseGenerateCalcuTimeTable)
  85 + .setJdbcTemplate(jdbcTemplate)
  86 + .build();
  87 +
  88 + // 注意:数据有当日重复的时刻表匹配(包括特殊节假日重复和平日重复)
  89 + // 1、当日重复时刻表在业务上一般是错误的(由前置验证规则过滤)
  90 + // 2、到了排班的阶段,计算时刻表重复时是不会过滤的
  91 + List<TTinfoDetailByLpResult> tTinfoDetailByLpResultList = planProcessGenerateCalcuTimeTableService.generateCalcuTTInfos(
  92 + 1,
  93 + DateTimeFormat.forPattern("yyyy-MM-dd").parseDateTime("2019-01-01").toDate(),
  94 + DateTimeFormat.forPattern("yyyy-MM-dd").parseDateTime("2019-01-01").toDate()
  95 + );
  96 + Assert.assertArrayEquals(
  97 + "时刻表路牌班次信息不匹配",
  98 + new Object[] {5},
  99 + new Object[] {tTinfoDetailByLpResultList.size()}
  100 + );
  101 +
  102 + // 找出时刻表1路牌1数据,路牌2,路牌3的班次数据,时刻表2的路牌1数据,路牌2数据
  103 + TTinfoDetailByLpResult t1_lp1_info = null;
  104 + TTinfoDetailByLpResult t1_lp2_info = null;
  105 + TTinfoDetailByLpResult t1_lp3_info = null;
  106 + TTinfoDetailByLpResult t2_lp1_info = null;
  107 + TTinfoDetailByLpResult t2_lp2_info = null;
  108 + for (TTinfoDetailByLpResult ttInfoLpInfoResult : tTinfoDetailByLpResultList) {
  109 + if (ttInfoLpInfoResult.getTTinfoResult().getId() == 1) {
  110 + if (ttInfoLpInfoResult.getLpInfoResult().getId() == 1L) {
  111 + t1_lp1_info = ttInfoLpInfoResult;
  112 + } else if (ttInfoLpInfoResult.getLpInfoResult().getId() == 2L) {
  113 + t1_lp2_info = ttInfoLpInfoResult;
  114 + } else if (ttInfoLpInfoResult.getLpInfoResult().getId() == 3L) {
  115 + t1_lp3_info = ttInfoLpInfoResult;
  116 + }
  117 + } else if (ttInfoLpInfoResult.getTTinfoResult().getId() == 2) {
  118 + if (ttInfoLpInfoResult.getLpInfoResult().getId() == 1L) {
  119 + t2_lp1_info = ttInfoLpInfoResult;
  120 + } else if (ttInfoLpInfoResult.getLpInfoResult().getId() == 2L) {
  121 + t2_lp2_info = ttInfoLpInfoResult;
  122 + }
  123 + }
  124 + }
  125 +
  126 + Assert.assertArrayEquals(
  127 + "时刻表1 路牌1 最小发车顺序号 最大发车顺序号 开始分班顺序号 不一致",
  128 + new Object[] {1L, 1L, 1, 6, 6},
  129 + new Object[] {t1_lp1_info.getTTinfoResult().getId(), t1_lp1_info.getLpInfoResult().getId(),
  130 + t1_lp1_info.getMinFcno(), t1_lp1_info.getMaxFcno(), t1_lp1_info.getStartFbFcno()});
  131 + Assert.assertArrayEquals(
  132 + "时刻表1 路牌2 最小发车顺序号 最大发车顺序号 开始分班顺序号 不一致",
  133 + new Object[] {1L, 2L, 2, 5, null},
  134 + new Object[] {t1_lp2_info.getTTinfoResult().getId(), t1_lp2_info.getLpInfoResult().getId(),
  135 + t1_lp2_info.getMinFcno(), t1_lp2_info.getMaxFcno(), t1_lp2_info.getStartFbFcno()});
  136 + Assert.assertArrayEquals(
  137 + "时刻表1 路牌3 最小发车顺序号 最大发车顺序号 开始分班顺序号 不一致",
  138 + new Object[] {1L, 3L, 3, 3, null},
  139 + new Object[] {t1_lp3_info.getTTinfoResult().getId(), t1_lp3_info.getLpInfoResult().getId(),
  140 + t1_lp3_info.getMinFcno(), t1_lp3_info.getMaxFcno(), t1_lp3_info.getStartFbFcno()});
  141 +
  142 + Assert.assertArrayEquals(
  143 + "时刻表2 路牌1 最小发车顺序号 最大发车顺序号 开始分班顺序号 不一致",
  144 + new Object[] {2L, 1L, 1, 1, null},
  145 + new Object[] {t2_lp1_info.getTTinfoResult().getId(), t2_lp1_info.getLpInfoResult().getId(),
  146 + t2_lp1_info.getMinFcno(), t2_lp1_info.getMaxFcno(), t2_lp1_info.getStartFbFcno()});
  147 + Assert.assertArrayEquals(
  148 + "时刻表2 路牌2 最小发车顺序号 最大发车顺序号 开始分班顺序号 不一致",
  149 + new Object[] {2L, 2L, 2, 2, null},
  150 + new Object[] {t2_lp2_info.getTTinfoResult().getId(), t2_lp2_info.getLpInfoResult().getId(),
  151 + t2_lp2_info.getMinFcno(), t2_lp2_info.getMaxFcno(), t2_lp2_info.getStartFbFcno()});
  152 +
  153 + // 验证路牌1 ttinfo中的第一个班次的属性
  154 + Collections.sort(t1_lp1_info.getTTinfoDetailResultList(), new Comparator<TTinfoDetailResult>() {
  155 + @Override
  156 + public int compare(TTinfoDetailResult o1, TTinfoDetailResult o2) {
  157 + return o1.getFcno() - o2.getFcno();
  158 + }
  159 + });
  160 + Assert.assertArrayEquals(
  161 + "路牌1的第一个班次 对象属性不能为空",
  162 + new Object[] {
  163 + true,
  164 + true,
  165 + true
  166 + },
  167 + new Object[] {
  168 + t1_lp1_info.getTTinfoDetailResultList().get(0).getXl() != null,
  169 + t1_lp1_info.getTTinfoDetailResultList().get(0).getTtInfo() != null,
  170 + t1_lp1_info.getTTinfoDetailResultList().get(0).getLp() != null
  171 + }
  172 + );
  173 + Assert.assertArrayEquals(
  174 + "路牌1的第一个班次 属性不一致",
  175 + new Object[] {
  176 + 1L,
  177 + 1,
  178 + 1L,
  179 + 1L,
  180 + 1,
  181 + "0",
  182 + "#1",
  183 + "上行起点站",
  184 + "#2",
  185 + "上行终点站",
  186 + "08:30",
  187 + 1,
  188 + 30D,
  189 + 30,
  190 + "normal",
  191 + "mark一下",
  192 + 1,
  193 + false,
  194 + false
  195 + },
  196 + new Object[] {
  197 + t1_lp1_info.getTTinfoDetailResultList().get(0).getId(),
  198 + t1_lp1_info.getTTinfoDetailResultList().get(0).getXl().getId(),
  199 + t1_lp1_info.getTTinfoDetailResultList().get(0).getTtInfo().getId(),
  200 + t1_lp1_info.getTTinfoDetailResultList().get(0).getLp().getId(),
  201 + t1_lp1_info.getTTinfoDetailResultList().get(0).getFcno(),
  202 + t1_lp1_info.getTTinfoDetailResultList().get(0).getXlDir(),
  203 + t1_lp1_info.getTTinfoDetailResultList().get(0).getQdzCode(),
  204 + t1_lp1_info.getTTinfoDetailResultList().get(0).getQdzName(),
  205 + t1_lp1_info.getTTinfoDetailResultList().get(0).getZdzCode(),
  206 + t1_lp1_info.getTTinfoDetailResultList().get(0).getZdzName(),
  207 + t1_lp1_info.getTTinfoDetailResultList().get(0).getFcsj(),
  208 + t1_lp1_info.getTTinfoDetailResultList().get(0).getBcs(),
  209 + t1_lp1_info.getTTinfoDetailResultList().get(0).getJhlc(),
  210 + t1_lp1_info.getTTinfoDetailResultList().get(0).getBcsj(),
  211 + t1_lp1_info.getTTinfoDetailResultList().get(0).getBcType(),
  212 + t1_lp1_info.getTTinfoDetailResultList().get(0).getRemark(),
  213 + t1_lp1_info.getTTinfoDetailResultList().get(0).getLineVersion(),
  214 + t1_lp1_info.getTTinfoDetailResultList().get(0).getIsFB(),
  215 + t1_lp1_info.getTTinfoDetailResultList().get(0).getIsTS()
  216 + }
  217 + );
  218 + }
  219 +}
... ...
src/test/resources/META-INF/drools.packagebuilder.conf
... ... @@ -7,3 +7,6 @@ drools.accumulate.function.ac = com.bsth.service.schedule.plan.process._1_valida
7 7 drools.accumulate.function.ae = com.bsth.service.schedule.plan.process._1_validate._1_timetable.drools.KBaseValidateTimeTable_Function_AccumulateEmpty
8 8 # kBase_validate_rule.drl使用
9 9 drools.accumulate.function.srif2 = com.bsth.service.schedule.plan.process._1_validate._2_rule.drools.KBaseValidateRule_Function_ErrorInfo
  10 +# KBase_generate_calcu_timetable使用
  11 +drools.accumulate.function.minruleqyrq2 = com.bsth.service.schedule.plan.process._2_generate._1_calcu._2_timetable.drools.KBaseGenerateCalcuTimeTable_Function_MinRuleQyrq
  12 +drools.accumulate.function.tresult = com.bsth.service.schedule.plan.process._2_generate._1_calcu._2_timetable.drools.KBaseGenerateCalcuTimeTable_Function_Result
... ...
src/test/resources/testdata/_2_generate_calcu_timetable.xml 0 → 100644
  1 +<?xml version='1.0' encoding='UTF-8'?>
  2 +<dataset>
  3 + <!-- 用户信息 -->
  4 + <bsth_c_sys_user id="1" user_name="管理员1" name="vip" password="vip" enabled="1" />
  5 + <!-- 角色信息 -->
  6 + <bsth_c_sys_role id="1" role_name="管理员组" enable="1" is_super_admin="1" pic="0" />
  7 + <!-- 用户角色关联信息 -->
  8 + <bsth_c_sys_user_roles users="1" roles="1" />
  9 + <!-- 公司信息(关联角色) -->
  10 + <bsth_c_sys_company_auth id="1" company_code="22" company_name="金高公司"
  11 + sub_company_code="01" sub_company_name="一分公司" />
  12 +
  13 + <!-- 车辆基础信息 -->
  14 + <bsth_c_cars id="1" inside_code="SSS-01"
  15 + business_code="22" company="金高公司" branche_company_code="01" branche_company="一分公司"
  16 + car_code="11111" car_plate="沪88881" supplier_name="bsth" equipment_code="123451"
  17 + hvac_car="1" ticket_type="1" led_screen="1" tv_video_type="1" scrap_state="0" />
  18 + <bsth_c_cars id="2" inside_code="SSS-02"
  19 + business_code="22" company="金高公司" branche_company_code="01" branche_company="一分公司"
  20 + car_code="11112" car_plate="沪88882" supplier_name="bsth" equipment_code="123452"
  21 + hvac_car="1" ticket_type="1" led_screen="1" tv_video_type="1" scrap_state="0" />
  22 + <bsth_c_cars id="3" inside_code="SSS-03"
  23 + business_code="55" company="南汇公司" branche_company_code="01" branche_company="一分公司"
  24 + car_code="11113" car_plate="沪88883" supplier_name="bsth" equipment_code="123453"
  25 + hvac_car="1" ticket_type="1" led_screen="1" tv_video_type="1" scrap_state="0" />
  26 + <bsth_c_cars id="4" inside_code="SSS-04"
  27 + business_code="22" company="金高公司" branche_company_code="02" branche_company="二分公司"
  28 + car_code="11114" car_plate="沪88884" supplier_name="bsth" equipment_code="123454"
  29 + hvac_car="1" ticket_type="1" led_screen="1" tv_video_type="1" scrap_state="0" />
  30 + <bsth_c_cars id="5" inside_code="SSS-05"
  31 + business_code="22" company="金高公司" branche_company_code="01" branche_company="一分公司"
  32 + car_code="11115" car_plate="沪88885" supplier_name="bsth" equipment_code="123455"
  33 + hvac_car="1" ticket_type="1" led_screen="1" tv_video_type="1" scrap_state="0" />
  34 +
  35 + <!-- 人员基础信息 -->
  36 + <bsth_c_personnel id="1" company="金高公司" company_code="22" branche_company="一分公司"
  37 + branche_company_code="01" job_code="05-000001" personnel_name="员工1" job_codeori="000001" />
  38 + <bsth_c_personnel id="2" company="金高公司" company_code="22" branche_company="一分公司"
  39 + branche_company_code="01" job_code="05-000002" personnel_name="员工2" job_codeori="000002" />
  40 + <bsth_c_personnel id="3" company="金高公司" company_code="22" branche_company="一分公司"
  41 + branche_company_code="01" job_code="05-000003" personnel_name="员工3" job_codeori="000003" />
  42 + <bsth_c_personnel id="4" company="金高公司" company_code="22" branche_company="一分公司"
  43 + branche_company_code="01" job_code="05-000004" personnel_name="员工4" job_codeori="000004" />
  44 + <bsth_c_personnel id="5" company="金高公司" company_code="22" branche_company="一分公司"
  45 + branche_company_code="01" job_code="05-000005" personnel_name="员工5" job_codeori="000005" />
  46 + <bsth_c_personnel id="6" company="金高公司" company_code="22" branche_company="一分公司"
  47 + branche_company_code="01" job_code="05-000006" personnel_name="员工6" job_codeori="000006" />
  48 + <bsth_c_personnel id="7" company="金高公司" company_code="22" branche_company="一分公司"
  49 + branche_company_code="01" job_code="05-000007" personnel_name="员工7" job_codeori="000007" />
  50 + <bsth_c_personnel id="8" company="金高公司" company_code="22" branche_company="一分公司"
  51 + branche_company_code="01" job_code="05-000008" personnel_name="员工8" job_codeori="000008" />
  52 +
  53 + <!-- 线路基础信息 -->
  54 + <bsth_c_line id="1" name="线路1" company="22" branche_company="01" length="20" destroy="0" />
  55 +
  56 + <!-- 停车场基础信息 -->
  57 + <bsth_c_car_park id="1" park_name="停车场1" company="05" branche_company="01" area="100" />
  58 +
  59 + <!-- 车辆配置信息(线路1,金高公司,一分公司) -->
  60 + <bsth_c_s_ccinfo id="1" xl="1" cl="1" qyrq="2019-01-01" tcd="停车场1" is_switch="0" is_cancel="0" />
  61 + <bsth_c_s_ccinfo id="2" xl="1" cl="2" qyrq="2019-01-01" tcd="停车场1" is_switch="0" is_cancel="0" />
  62 + <bsth_c_s_ccinfo id="3" xl="1" cl="5" qyrq="2019-01-01" tcd="停车场1" is_switch="0" is_cancel="0" />
  63 +
  64 + <!-- 人员配置信息(线路1,金高公司) -->
  65 + <bsth_c_s_ecinfo id="1" xl="1" jsy="1" dbbm="1" is_cancel="0" />
  66 + <bsth_c_s_ecinfo id="2" xl="1" jsy="2" dbbm="2" is_cancel="0" />
  67 + <bsth_c_s_ecinfo id="3" xl="1" jsy="3" dbbm="3" is_cancel="0" />
  68 + <bsth_c_s_ecinfo id="4" xl="1" jsy="4" dbbm="4" is_cancel="0" />
  69 + <bsth_c_s_ecinfo id="5" xl="1" jsy="5" dbbm="5" is_cancel="0" />
  70 + <bsth_c_s_ecinfo id="6" xl="1" jsy="6" dbbm="6" is_cancel="0" />
  71 + <bsth_c_s_ecinfo id="7" xl="1" jsy="7" spy="8" dbbm="78" is_cancel="0" />
  72 +
  73 + <!-- 路牌信息 -->
  74 + <bsth_c_s_gbi id="1" xl="1" lp_no="1" lp_name="路牌1" lp_type="普通路牌" is_cancel="0"
  75 + create_by="1" create_date="2019-02-01" update_by="1" update_date="2019-02-01"
  76 + />
  77 + <bsth_c_s_gbi id="2" xl="1" lp_no="2" lp_name="路牌2" lp_type="普通路牌" is_cancel="0"
  78 + create_by="1" create_date="2019-02-01" update_by="1" update_date="2019-02-01"
  79 + />
  80 + <bsth_c_s_gbi id="3" xl="1" lp_no="3" lp_name="路牌3" lp_type="普通路牌" is_cancel="0"
  81 + create_by="1" create_date="2019-02-01" update_by="1" update_date="2019-02-01"
  82 + />
  83 + <bsth_c_s_gbi id="4" xl="1" lp_no="4" lp_name="特1" lp_type="普通路牌" is_cancel="0"
  84 + create_by="1" create_date="2019-02-01" update_by="1" update_date="2019-02-01"
  85 + />
  86 +
  87 + <!-- 时刻表1信息(平日) -->
  88 + <bsth_c_s_ttinfo id="1" xl="1" name="时刻表1" xl_dir="2" qyrq="2019-01-01" is_enable_dis_template="1"
  89 + is_cancel="0" line_version="1" lp_count = "10" loop_count = "6"
  90 + rule_days="1,1,0,1,1,0,0"
  91 + create_by="1" create_date="2019-02-01" update_by="1" update_date="2019-02-01"
  92 + />
  93 + <!-- 时刻表2信息(节假日) -->
  94 + <bsth_c_s_ttinfo id="2" xl="1" name="时刻表2" xl_dir="2" qyrq="2019-01-01" is_enable_dis_template="1"
  95 + is_cancel="0" line_version="1" lp_count = "10" loop_count = "6"
  96 + rule_days="1,1,0,0,0,1,1"
  97 + create_by="1" create_date="2019-02-01" update_by="1" update_date="2019-02-01"
  98 + />
  99 + <!-- 时刻表3信息(特殊日期) -->
  100 + <bsth_c_s_ttinfo id="3" xl="1" name="时刻表3" xl_dir="2" qyrq="2019-01-01" is_enable_dis_template="1"
  101 + is_cancel="0" line_version="1" lp_count = "10" loop_count = "6"
  102 + special_days="2019-01-05,2019-01-06,2019-01-07"
  103 + create_by="1" create_date="2019-02-01" update_by="1" update_date="2019-02-01"
  104 + />
  105 + <!-- 时刻表4信息(特殊日期) -->
  106 + <bsth_c_s_ttinfo id="4" xl="1" name="时刻表4" xl_dir="2" qyrq="2019-01-01" is_enable_dis_template="1"
  107 + is_cancel="0" line_version="1" lp_count = "10" loop_count = "6"
  108 + special_days="2019-01-06,2019-01-07,2019-01-08,2019-01-09"
  109 + create_by="1" create_date="2019-02-01" update_by="1" update_date="2019-02-01"
  110 + />
  111 +
  112 + <!-- 时刻表1明细信息(3个路牌6个班次 ) -->
  113 + <bsth_c_s_ttinfo_detail id="1" xl="1" ttinfo="1" lp="1" fcno="1" xl_dir="0"
  114 + qdz_code="#1" qdz_name="上行起点站" zdz_code="#2" zdz_name="上行终点站"
  115 + fcsj="08:30" bcs="1" jhlc="30" bcsj="30" bc_type="normal"
  116 + line_version="1" remark="mark一下" isfb="0" ists="0"
  117 + create_by="1" create_date="2019-02-01" update_by="1" update_date="2019-02-01"
  118 + />
  119 + <bsth_c_s_ttinfo_detail id="2" xl="1" ttinfo="1" lp="2" fcno="2" xl_dir="0"
  120 + qdz_code="#1" qdz_name="上行起点站" zdz_code="#2" zdz_name="上行终点站"
  121 + fcsj="08:40" bcs="2" jhlc="30" bcsj="30" bc_type="normal"
  122 + line_version="1"
  123 + create_by="1" create_date="2019-02-01" update_by="1" update_date="2019-02-01"
  124 + />
  125 + <bsth_c_s_ttinfo_detail id="3" xl="1" ttinfo="1" lp="3" fcno="3" xl_dir="0"
  126 + qdz_code="#1" qdz_name="上行起点站" zdz_code="#2" zdz_name="上行终点站"
  127 + fcsj="08:50" bcs="3" jhlc="30" bcsj="30" bc_type="normal"
  128 + line_version="1"
  129 + create_by="1" create_date="2019-02-01" update_by="1" update_date="2019-02-01"
  130 + />
  131 + <bsth_c_s_ttinfo_detail id="4" xl="1" ttinfo="1" lp="1" fcno="4" xl_dir="1"
  132 + qdz_code="#3" qdz_name="下行起点站" zdz_code="#4" zdz_name="下行终点站"
  133 + fcsj="09:10" bcs="4" jhlc="30" bcsj="30" bc_type="normal"
  134 + line_version="1"
  135 + create_by="1" create_date="2019-02-01" update_by="1" update_date="2019-02-01"
  136 + />
  137 + <bsth_c_s_ttinfo_detail id="5" xl="1" ttinfo="1" lp="2" fcno="5" xl_dir="1"
  138 + qdz_code="#3" qdz_name="下行起点站" zdz_code="#4" zdz_name="下行终点站"
  139 + fcsj="09:20" bcs="5" jhlc="30" bcsj="30" bc_type="normal"
  140 + line_version="1"
  141 + create_by="1" create_date="2019-02-01" update_by="1" update_date="2019-02-01"
  142 + />
  143 + <bsth_c_s_ttinfo_detail id="10" xl="1" ttinfo="1" lp="1" fcno="6" xl_dir="0"
  144 + qdz_code="#1" qdz_name="上行起点站" zdz_code="#2" zdz_name="上行终点站"
  145 + fcsj="09:50" bcs="1" jhlc="30" bcsj="30" bc_type="normal" isfb="1"
  146 + line_version="1"
  147 + create_by="1" create_date="2019-02-01" update_by="1" update_date="2019-02-01"
  148 + />
  149 + <!-- 时刻表2明细信息(2个路牌2个班次 ) -->
  150 + <bsth_c_s_ttinfo_detail id="6" xl="1" ttinfo="2" lp="1" fcno="1" xl_dir="0"
  151 + qdz_code="#1" qdz_name="上行起点站" zdz_code="#2" zdz_name="上行终点站"
  152 + fcsj="08:30" bcs="1" jhlc="30" bcsj="30" bc_type="normal"
  153 + line_version="1"
  154 + create_by="1" create_date="2019-02-01" update_by="1" update_date="2019-02-01"
  155 + />
  156 + <bsth_c_s_ttinfo_detail id="7" xl="1" ttinfo="2" lp="2" fcno="2" xl_dir="0"
  157 + qdz_code="#1" qdz_name="上行起点站" zdz_code="#2" zdz_name="上行终点站"
  158 + fcsj="08:40" bcs="2" jhlc="30" bcsj="30" bc_type="normal"
  159 + line_version="1"
  160 + create_by="1" create_date="2019-02-01" update_by="1" update_date="2019-02-01"
  161 + />
  162 + <!-- 时刻表3明细信息(1个路牌1个班次 ) -->
  163 + <bsth_c_s_ttinfo_detail id="8" xl="1" ttinfo="3" lp="1" fcno="1" xl_dir="0"
  164 + qdz_code="#1" qdz_name="上行起点站" zdz_code="#2" zdz_name="上行终点站"
  165 + fcsj="08:30" bcs="1" jhlc="30" bcsj="30" bc_type="normal"
  166 + line_version="1"
  167 + create_by="1" create_date="2019-02-01" update_by="1" update_date="2019-02-01"
  168 + />
  169 + <!-- 时刻表4明细信息(1个路牌1个班次 ) -->
  170 + <bsth_c_s_ttinfo_detail id="9" xl="1" ttinfo="4" lp="1" fcno="1" xl_dir="0"
  171 + qdz_code="#1" qdz_name="上行起点站" zdz_code="#2" zdz_name="上行终点站"
  172 + fcsj="08:30" bcs="1" jhlc="30" bcsj="30" bc_type="normal"
  173 + line_version="1"
  174 + create_by="1" create_date="2019-02-01" update_by="1" update_date="2019-02-01"
  175 + />
  176 +
  177 + <!-- 线路1规则信息 -->
  178 + <bsth_c_s_sr1_flat id="1" xl="1" car_config_info="1" qyrq="2019-01-01"
  179 + lp_names="路牌1" lp_ids="1" lp_start="1"
  180 + ry_dbbms="1,2" ry_config_ids="1,2" ry_start="1"
  181 + fbtype="0"
  182 + />
  183 + <bsth_c_s_sr1_flat id="2" xl="1" car_config_info="2" qyrq="2019-01-01"
  184 + lp_names="路牌2" lp_ids="2" lp_start="1"
  185 + ry_dbbms="3,4" ry_config_ids="3,4" ry_start="1"
  186 + fbtype="0"
  187 + />
  188 + <bsth_c_s_sr1_flat id="3" xl="1" car_config_info="3" qyrq="2019-01-01"
  189 + lp_names="路牌3" lp_ids="3" lp_start="1"
  190 + ry_dbbms="5-78,6" ry_config_ids="5-7,6" ry_start="1"
  191 + fbtype="0"
  192 + />
  193 +
  194 +</dataset>
... ...