Commit e239b274 by 张晓

Merge branch 'feature-dispatch-zx' into develop

2 parents 7ade42e9 03eef274
...@@ -8,4 +8,5 @@ ...@@ -8,4 +8,5 @@
/*/.classpath /*/.classpath
/*/.project /*/.project
/*/logs/ /*/logs/
/*/.gitignore /*/.gitignore
\ No newline at end of file dispatchSolution-*.json
\ No newline at end of file
This diff could not be displayed because it is too large.
...@@ -20,7 +20,7 @@ public interface DispatchBatchRepository extends CrudRepository<DispatchBatch, L ...@@ -20,7 +20,7 @@ public interface DispatchBatchRepository extends CrudRepository<DispatchBatch, L
Optional<DispatchBatch> findByGroupIdAndBatchDate(String groupId, String batchDay); Optional<DispatchBatch> findByGroupIdAndBatchDate(String groupId, String batchDay);
@Query(value = "from DispatchBatch where groupId = ?1 and batchNo=?2 ") @Query(value = "from DispatchBatch where groupId = ?1 and batchNo=?2 ")
List<DispatchBatch> findLatestGroup(String groupId, String batchNo); Optional<DispatchBatch> findByGroupIdAndBatchNo(String groupId, String batchNo);
} }
\ No newline at end of file
package com.dituhui.pea.dispatch.dao; package com.dituhui.pea.dispatch.dao;
import com.dituhui.pea.dispatch.entity.OrderAppointment; import com.dituhui.pea.dispatch.entity.OrderAppointment;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.CrudRepository; import org.springframework.data.repository.CrudRepository;
import java.util.Optional; import java.util.Optional;
public interface OrderAppointmentRepository extends CrudRepository<OrderAppointment, Long> { public interface OrderAppointmentRepository extends CrudRepository<OrderAppointment, Long> {
@Query(value = "SELECT * FROM order_appointment WHERE order_id=:orderId ORDER BY id DESC LIMIT 1", nativeQuery = true)
Optional<OrderAppointment> findByOrderId(String orderId); Optional<OrderAppointment> findByOrderId(String orderId);
} }
...@@ -72,6 +72,12 @@ public class DispatchBatch implements Serializable { ...@@ -72,6 +72,12 @@ public class DispatchBatch implements Serializable {
@Column(name = "status") @Column(name = "status")
private String status; private String status;
@JsonDeserialize(using = LocalDateTimeDeserializer.class)
@JsonSerialize(using = LocalDateTimeSerializer.class)
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Column(name = "cutoffed_time")
private LocalDateTime cutoffedTime;
@Column(name = "memo") @Column(name = "memo")
private String memo; private String memo;
......
package com.dituhui.pea.dispatch.scheduler; package com.dituhui.pea.dispatch.scheduler;
import com.dituhui.pea.dispatch.constraint.DispatchConstraintProvider; import com.dituhui.pea.dispatch.constraint.DispatchConstraintProvider;
import com.dituhui.pea.dispatch.entity.DispatchBatch;
import com.dituhui.pea.dispatch.pojo.Customer; import com.dituhui.pea.dispatch.pojo.Customer;
import com.dituhui.pea.dispatch.pojo.DispatchSolution; import com.dituhui.pea.dispatch.pojo.DispatchSolution;
import com.dituhui.pea.dispatch.pojo.Technician; import com.dituhui.pea.dispatch.pojo.Technician;
...@@ -21,6 +22,8 @@ import java.io.File; ...@@ -21,6 +22,8 @@ import java.io.File;
import java.sql.SQLException; import java.sql.SQLException;
import java.time.Duration; import java.time.Duration;
import java.time.LocalDate; import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import java.util.Arrays; import java.util.Arrays;
import java.util.UUID; import java.util.UUID;
...@@ -69,6 +72,32 @@ public class BatchScheduler { ...@@ -69,6 +72,32 @@ public class BatchScheduler {
String currDay = LocalDate.now().plusDays(i).format(DateTimeFormatter.ISO_LOCAL_DATE); String currDay = LocalDate.now().plusDays(i).format(DateTimeFormatter.ISO_LOCAL_DATE);
log.info("dispatchRun begin----- group:{}, day:{}", groupId, currDay); log.info("dispatchRun begin----- group:{}, day:{}", groupId, currDay);
LocalTime currentTime = LocalTime.now();
LocalTime cutoffTime = LocalTime.parse("16:00:00", DateTimeFormatter.ISO_LOCAL_TIME);
if (currentTime.isAfter(cutoffTime)) {
log.info("dispatchRun 已过cutoff时间,更新pre状态为confirm----- group:{}, day:{}", groupId, currDay);
DispatchBatch dispatchBatch = batchService.queryBatchInfoByDay(groupId, currDay);
if (null == dispatchBatch.getBatchNo()) {
log.info("dispatchRun 未查询到批次信息跳过----- group:{}, day:{}", groupId, currDay);
continue;
}
if (null == dispatchBatch.getCutoffedTime()) {
log.info("dispatchRun 已过cutoff时间,更新pre状态为confirm, 执行首次confirm----- group:{}, day:{}", groupId, currDay);
try {
this.extractService.extractDispatchToOrder(groupId, dispatchBatch.getBatchNo(), true);
dispatchBatch.setCutoffedTime(LocalDateTime.now());
batchService.saveDispatchBatch(dispatchBatch);
} catch (SQLException e) {
log.error("dispatchRun 已过cutoff时间,更新pre状态为confirm 异常 %s", e);
throw new RuntimeException(e);
}
} else {
log.info("dispatchRun 已过cutoff时间,更新pre状态为confirm, 已经执行confirm,跳过当次计算 ----- group:{}, day:{}", groupId, currDay);
}
continue;
}
String batchNo = batchService.buildBatchData(groupId, currDay); String batchNo = batchService.buildBatchData(groupId, currDay);
UUID problemId = solveService.generateProblemId(groupId, batchNo); UUID problemId = solveService.generateProblemId(groupId, batchNo);
log.info("dispatchRun group:{}, day:{}, batch:{}, problemId:{}", groupId, currDay, batchNo, problemId); log.info("dispatchRun group:{}, day:{}, batch:{}, problemId:{}", groupId, currDay, batchNo, problemId);
...@@ -81,13 +110,11 @@ public class BatchScheduler { ...@@ -81,13 +110,11 @@ public class BatchScheduler {
} }
log.info("dispatchRun prepare done, group:{}, day:{}, batch:{}, problemId:{}", groupId, currDay, batchNo, problemId); log.info("dispatchRun prepare done, group:{}, day:{}, batch:{}, problemId:{}", groupId, currDay, batchNo, problemId);
DispatchSolution solution = solver.solve(problem); DispatchSolution solution = solver.solve(problem);
log.info("dispatchRun run done, group:{}, day:{}, batch:{}, problemId:{}, score:{}", log.info("dispatchRun run done, group:{}, day:{}, batch:{}, problemId:{}, score:{}", groupId, currDay, batchNo, problemId, solution.getScore().toShortString());
groupId, currDay, batchNo, problemId, solution.getScore().toShortString());
this.extractService.saveAndExtractSolution(solution); this.extractService.saveAndExtractSolution(solution);
log.info("dispatchRun done ------ group:{}, day:{}", groupId, currDay); log.info("dispatchRun done ------ group:{}, day:{}", groupId, currDay);
JacksonSolutionFileIO<DispatchSolution> exporter = new JacksonSolutionFileIO<DispatchSolution>( JacksonSolutionFileIO<DispatchSolution> exporter = new JacksonSolutionFileIO<DispatchSolution>(DispatchSolution.class);
DispatchSolution.class);
// Set the output file. // Set the output file.
...@@ -98,11 +125,10 @@ public class BatchScheduler { ...@@ -98,11 +125,10 @@ public class BatchScheduler {
} }
} catch (InterruptedException e) {
} catch (SQLException e) {
log.info("error %s", e); log.info("error %s", e);
throw new RuntimeException(e); throw new RuntimeException(e);
} catch (InterruptedException e) { } catch (SQLException e) {
log.info("error %s", e); log.info("error %s", e);
throw new RuntimeException(e); throw new RuntimeException(e);
} }
......
...@@ -23,4 +23,6 @@ public interface BatchService { ...@@ -23,4 +23,6 @@ public interface BatchService {
String queryBatchNoByDay(String groupId, String day); String queryBatchNoByDay(String groupId, String day);
void saveDispatchBatch(DispatchBatch batchInfo);
} }
...@@ -2,6 +2,7 @@ package com.dituhui.pea.dispatch.service; ...@@ -2,6 +2,7 @@ package com.dituhui.pea.dispatch.service;
import com.dituhui.pea.dispatch.pojo.DispatchSolution; import com.dituhui.pea.dispatch.pojo.DispatchSolution;
import org.springframework.transaction.annotation.Transactional;
import java.sql.SQLException; import java.sql.SQLException;
...@@ -18,12 +19,14 @@ public interface ExtractService { ...@@ -18,12 +19,14 @@ public interface ExtractService {
* 将计算结果回写到dispatch2个表、以及order两个表 * 将计算结果回写到dispatch2个表、以及order两个表
* 是下面两个方法的包装 * 是下面两个方法的包装
* */ * */
// @Transactional
void saveAndExtractSolution(DispatchSolution solution) throws RuntimeException; void saveAndExtractSolution(DispatchSolution solution) throws RuntimeException;
/* /*
* 将计算结果回写到dispatch_order表(更新补充技术员工号、上门时间) * 将计算结果回写到dispatch_order表(更新补充技术员工号、上门时间)
* */ * */
// @Transactional
void saveSolutionToDispatch(String groupId, String batchNo, DispatchSolution solution) throws RuntimeException; void saveSolutionToDispatch(String groupId, String batchNo, DispatchSolution solution) throws RuntimeException;
/* /*
...@@ -31,7 +34,8 @@ public interface ExtractService { ...@@ -31,7 +34,8 @@ public interface ExtractService {
* order_appointment(新增、更新) * order_appointment(新增、更新)
* order_request(主要更新状态) * order_request(主要更新状态)
* */ * */
void extractDispatchToOrder(String groupId, String batchNo) throws SQLException; // @Transactional
void extractDispatchToOrder(String groupId, String batchNo, boolean isConfirm) throws SQLException;
} }
...@@ -80,6 +80,7 @@ public class BatchServiceImpl implements BatchService { ...@@ -80,6 +80,7 @@ public class BatchServiceImpl implements BatchService {
// int engCount = queryEnginerCount(groupId); // int engCount = queryEnginerCount(groupId);
// int orderCount = queryOrderCount(groupId, batchDay); // int orderCount = queryOrderCount(groupId, batchDay);
log.info("清理原批次数据, groupId:{}, day:{}, batchNo:{}", groupId, batchDay, batchNo); log.info("清理原批次数据, groupId:{}, day:{}, batchNo:{}", groupId, batchDay, batchNo);
jdbcTemplate.update("delete from dispatch_engineer where group_id=? and batch_no=?", groupId, batchNo); jdbcTemplate.update("delete from dispatch_engineer where group_id=? and batch_no=?", groupId, batchNo);
jdbcTemplate.update("delete from dispatch_order where group_id=? and batch_no=?", groupId, batchNo); jdbcTemplate.update("delete from dispatch_order where group_id=? and batch_no=?", groupId, batchNo);
...@@ -94,23 +95,23 @@ public class BatchServiceImpl implements BatchService { ...@@ -94,23 +95,23 @@ public class BatchServiceImpl implements BatchService {
" order by a.engineer_code asc"; " order by a.engineer_code asc";
int engCount = jdbcTemplate.update(sqlEngineer, batchNo, groupId); int engCount = jdbcTemplate.update(sqlEngineer, batchNo, groupId);
// 未派过的工单 // 未派过的工单(虚拟指派不更改order_request.appointment_status,所以也包含在当前条件中)
String sqlOrder = "INSERT INTO dispatch_order (group_id, batch_no, order_id , x, y, expect_time_begin, expect_time_end, tags, priority , skills , take_time )\n" + String sqlOrder = "INSERT INTO dispatch_order (group_id, batch_no, order_id , x, y, expect_time_begin, expect_time_end, tags, priority , skills , take_time )\n" +
" select a.org_group_id, ? , a.order_id, a.x, a.y , \n" + " select a.org_group_id, ? , a.order_id, a.x, a.y , \n" +
" a.expect_time_begin, a.expect_time_end, a.tags, a.priority , concat(a.brand, a.type, a.skill) skills , b.take_time \n" + " a.expect_time_begin, a.expect_time_end, a.tags, a.priority , concat(a.brand, '-', a.type, '-', a.skill) skills , b.take_time \n" +
" from order_request a left join product_category b on (a.brand=b.brand and a.type=b.type and a.skill=b.skill )\n" + " from order_request a left join skill_info b on (a.brand=b.brand and a.type=b.type and a.skill=b.skill )\n" +
" where a.org_group_id=? and a.status='OPEN' " + " where a.org_group_id=? and a.status='OPEN' " +
" and a.dt = ? " + " and a.dt = ? " +
" and appointment_status ='NOT_ASSIGNED' and appointment_method like 'AUTO%' \n" + " and a.appointment_status ='NOT_ASSIGNED' and appointment_method like 'AUTO%' \n" +
" order by a.expect_time_begin asc "; " order by a.expect_time_begin asc ";
int orderCount = jdbcTemplate.update(sqlOrder, batchNo, groupId, batchDay); int orderCount = jdbcTemplate.update(sqlOrder, batchNo, groupId, batchDay);
// 已派过PRE状态还可以再次派 // 已派过PRE状态还可以再次派
String sqlOrderPre = "INSERT INTO dispatch_order (group_id, batch_no, order_id , x, y, expect_time_begin, expect_time_end, tags, priority , skills , take_time )\n" + String sqlOrderPre = "INSERT INTO dispatch_order (group_id, batch_no, order_id , x, y, expect_time_begin, expect_time_end, tags, priority , skills , take_time )\n" +
" select a.org_group_id, ?, a.order_id, a.x, a.y , \n" + " select a.org_group_id, ?, a.order_id, a.x, a.y , \n" +
" a.expect_time_begin, a.expect_time_end, a.tags, a.priority , concat(a.brand, a.type, a.skill) skills , b.take_time \n" + " a.expect_time_begin, a.expect_time_end, a.tags, a.priority , concat(a.brand,'-', a.type, '-', a.skill) skills , b.take_time \n" +
" from order_request a " + " from order_request a " +
" left join product_category b on (a.brand=b.brand and a.type=b.type and a.skill=b.skill )\n" + " left join skill_info b on (a.brand=b.brand and a.type=b.type and a.skill=b.skill )\n" +
" left join order_appointment o on (a.order_id =o.order_id)\n" + " left join order_appointment o on (a.order_id =o.order_id)\n" +
" where a.org_group_id=? and a.status='OPEN' \n" + " where a.org_group_id=? and a.status='OPEN' \n" +
" and a.dt = ? " + " and a.dt = ? " +
...@@ -119,8 +120,9 @@ public class BatchServiceImpl implements BatchService { ...@@ -119,8 +120,9 @@ public class BatchServiceImpl implements BatchService {
" order by a.expect_time_begin asc "; " order by a.expect_time_begin asc ";
int orderCountPre = jdbcTemplate.update(sqlOrderPre, batchNo, groupId, batchDay); int orderCountPre = jdbcTemplate.update(sqlOrderPre, batchNo, groupId, batchDay);
log.info("准备批次数据 order1 :{}", orderCount);
log.info("准备批次数据 order2 :{}", orderCountPre); log.info("准备批次数据 orderCount :{}", orderCount);
log.info("准备批次数据 orderCountPre :{}", orderCountPre);
jdbcTemplate.update("update dispatch_batch set engineer_num=? , order_num=?, start_time=?, end_time=null, status='RUNNING' where group_id=? and batch_no=?", jdbcTemplate.update("update dispatch_batch set engineer_num=? , order_num=?, start_time=?, end_time=null, status='RUNNING' where group_id=? and batch_no=?",
...@@ -148,5 +150,9 @@ public class BatchServiceImpl implements BatchService { ...@@ -148,5 +150,9 @@ public class BatchServiceImpl implements BatchService {
return optional.orElseGet(DispatchBatch::new); return optional.orElseGet(DispatchBatch::new);
} }
@Override
public void saveDispatchBatch(DispatchBatch batchInfo) {
batchRepository.save(batchInfo);
}
} }
...@@ -4,10 +4,7 @@ import cn.hutool.core.date.DateField; ...@@ -4,10 +4,7 @@ import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateTime; import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil; import cn.hutool.core.date.DateUtil;
import com.dituhui.pea.dispatch.dao.*; import com.dituhui.pea.dispatch.dao.*;
import com.dituhui.pea.dispatch.entity.DispatchOrder; import com.dituhui.pea.dispatch.entity.*;
import com.dituhui.pea.dispatch.entity.EngineerInfo;
import com.dituhui.pea.dispatch.entity.OrderAppointment;
import com.dituhui.pea.dispatch.entity.OrderRequest;
import com.dituhui.pea.dispatch.pojo.DispatchSolution; import com.dituhui.pea.dispatch.pojo.DispatchSolution;
import com.dituhui.pea.dispatch.service.ExtractService; import com.dituhui.pea.dispatch.service.ExtractService;
import com.mysql.cj.util.StringUtils; import com.mysql.cj.util.StringUtils;
...@@ -45,6 +42,9 @@ public class ExtractServiceImpl implements ExtractService { ...@@ -45,6 +42,9 @@ public class ExtractServiceImpl implements ExtractService {
@Autowired @Autowired
DispatchBatchRepository batchRepository;
@Autowired
EngineerInfoRepository engineerInfoRepo; EngineerInfoRepository engineerInfoRepo;
...@@ -64,14 +64,31 @@ public class ExtractServiceImpl implements ExtractService { ...@@ -64,14 +64,31 @@ public class ExtractServiceImpl implements ExtractService {
/* /*
* 将计算结果回写到dispatch2个表、以及order两个表 * 将计算结果回写到dispatch2个表、以及order两个表
* */ * */
// @Transactional
@Override @Override
public void saveAndExtractSolution(DispatchSolution solution) throws RuntimeException { public void saveAndExtractSolution(DispatchSolution solution) throws RuntimeException {
String groupId = solution.getGroupId(); String groupId = solution.getGroupId();
String batchNo = solution.getBatchNo(); String batchNo = solution.getBatchNo();
log.info("算法结果回写包装方法, groupId:{}, batchNo:{}", groupId, batchNo); log.info("算法结果回写包装方法, groupId:{}, batchNo:{}", groupId, batchNo);
JacksonSolutionFileIO<DispatchSolution> exporter = new JacksonSolutionFileIO<DispatchSolution>(DispatchSolution.class);
String fileName = String.format("dispatchSolution-%s-%s.json", groupId, batchNo);
File tempFile = new File(fileName);
exporter.write(solution, tempFile);
String dispatchResultJson = "{}";
try {
dispatchResultJson = FileUtil.readAsString(tempFile);
} catch (IOException e) {
log.error("json算法结果回写 error , groupId:{}, batchNo:{} ", groupId, batchNo, e);
}
Object[] paramBatch = {LocalDateTime.now(), dispatchResultJson, groupId, batchNo};
jdbcTemplate.update(" update dispatch_batch set status='DONE', end_time=? , ext=? where group_id=? and batch_no=? ", paramBatch);
this.saveSolutionToDispatch(groupId, batchNo, solution); this.saveSolutionToDispatch(groupId, batchNo, solution);
try { try {
this.extractDispatchToOrder(solution.getGroupId(), solution.getBatchNo()); this.extractDispatchToOrder(solution.getGroupId(), solution.getBatchNo(), false);
} catch (SQLException e) { } catch (SQLException e) {
log.error("算法结果回写包装方法异常, groupId:{}, batchNo:{}", groupId, batchNo, e); log.error("算法结果回写包装方法异常, groupId:{}, batchNo:{}", groupId, batchNo, e);
throw new RuntimeException(e); throw new RuntimeException(e);
...@@ -81,7 +98,7 @@ public class ExtractServiceImpl implements ExtractService { ...@@ -81,7 +98,7 @@ public class ExtractServiceImpl implements ExtractService {
/** /**
* 将计算结果回写到dispatch_order表(更新补充技术员工号、上门时间) * 将计算结果回写到dispatch_order表(更新补充技术员工号、上门时间)
*/ */
@Transactional // @Transactional
@Override @Override
public void saveSolutionToDispatch(String groupId, String batchNo, DispatchSolution solution) throws RuntimeException { public void saveSolutionToDispatch(String groupId, String batchNo, DispatchSolution solution) throws RuntimeException {
log.info("算法结果回写dispatch, groupId:{}, batchNo:{}", groupId, batchNo); log.info("算法结果回写dispatch, groupId:{}, batchNo:{}", groupId, batchNo);
...@@ -92,8 +109,6 @@ public class ExtractServiceImpl implements ExtractService { ...@@ -92,8 +109,6 @@ public class ExtractServiceImpl implements ExtractService {
jdbcTemplate.update(" update dispatch_order set engineer_code='' , seq=0, time_begin=null ,time_end=null where group_id=? and batch_no=? ", paramClear); jdbcTemplate.update(" update dispatch_order set engineer_code='' , seq=0, time_begin=null ,time_end=null where group_id=? and batch_no=? ", paramClear);
String sql = "update dispatch_order set engineer_code=? , seq=?, time_begin=? ,time_end=? where group_id=? and batch_no=? and order_id=? ";
log.info("算法结果回写dispatch, step2-开始回写, groupId:{}, batchNo:{}", groupId, batchNo); log.info("算法结果回写dispatch, step2-开始回写, groupId:{}, batchNo:{}", groupId, batchNo);
// 保存当前批次指派结果 // 保存当前批次指派结果
solution.getTechnicianList().forEach(technician -> { solution.getTechnicianList().forEach(technician -> {
...@@ -122,11 +137,13 @@ public class ExtractServiceImpl implements ExtractService { ...@@ -122,11 +137,13 @@ public class ExtractServiceImpl implements ExtractService {
log.info(customer.toString()); log.info(customer.toString());
Date arriveTime = DateUtil.beginOfDay(dOrder.getExpectTimeBegin()).offset(DateField.MINUTE, customer.getArrivalTime()); Date arriveTime = DateUtil.beginOfDay(dOrder.getExpectTimeBegin()).offset(DateField.MINUTE, customer.getArrivalTime());
Date leaveTime = DateUtil.beginOfDay(arriveTime).offset(DateField.MINUTE, customer.getDepartureTime()); Date leaveTime = DateUtil.beginOfDay(dOrder.getExpectTimeBegin()).offset(DateField.MINUTE, customer.getDepartureTime());
Object[] param = {technician.getCode(), idx, arriveTime, leaveTime, groupId, batchNo, customer.getCode()}; Object[] param = {technician.getCode(), idx, arriveTime, leaveTime, groupId, batchNo, customer.getCode()};
String sql = "update dispatch_order set engineer_code=? , seq=?, time_begin=? ,time_end=? where group_id=? and batch_no=? and order_id=? ";
jdbcTemplate.update(sql, param); int rowUpdated = jdbcTemplate.update(sql, param);
log.info("算法结果回写dispatch, step3-逐个客户处理, order_id:{}, engineer_code:{}, seq: {}, begin:{}, end:{} ,rowUpdated:{}",
customer.getCode(), technician.getCode(), seq, arriveTime, leaveTime, rowUpdated);
} }
...@@ -135,21 +152,6 @@ public class ExtractServiceImpl implements ExtractService { ...@@ -135,21 +152,6 @@ public class ExtractServiceImpl implements ExtractService {
}); });
JacksonSolutionFileIO<DispatchSolution> exporter = new JacksonSolutionFileIO<DispatchSolution>(DispatchSolution.class);
String fileName = String.format("dispatchSolution-%s-%s.json", groupId, batchNo);
File tempFile = new File(fileName);
exporter.write(solution, tempFile);
String dispatchResultJson = "{}";
try {
dispatchResultJson = FileUtil.readAsString(tempFile);
} catch (IOException e) {
log.error("json算法结果回写 error , groupId:{}, batchNo:{} ", groupId, batchNo, e);
}
Object[] paramBatch = {LocalDateTime.now(), dispatchResultJson, groupId, batchNo};
jdbcTemplate.update(" update dispatch_batch set status='DONE', end_time=? , ext=? where group_id=? and batch_no=? ", paramBatch);
log.info("算法结果回写dispatch完成, groupId:{}, batchNo:{}", groupId, batchNo); log.info("算法结果回写dispatch完成, groupId:{}, batchNo:{}", groupId, batchNo);
} }
...@@ -159,9 +161,9 @@ public class ExtractServiceImpl implements ExtractService { ...@@ -159,9 +161,9 @@ public class ExtractServiceImpl implements ExtractService {
* order_appointment(新增、更新) * order_appointment(新增、更新)
* order_request(主要更新状态) * order_request(主要更新状态)
*/ */
@Transactional // @Transactional
@Override @Override
public void extractDispatchToOrder(String groupId, String batchNo) throws SQLException { public void extractDispatchToOrder(String groupId, String batchNo, boolean isConfirm) throws SQLException {
log.info("算法结果更新到工单, groupId:{}, batchNo:{}", groupId, batchNo); log.info("算法结果更新到工单, groupId:{}, batchNo:{}", groupId, batchNo);
Map<String, EngineerInfo> engineerInfoMap = engineerInfoRepo.findByGroupId(groupId).stream().collect(Collectors.toMap(EngineerInfo::getEngineerCode, y -> y)); Map<String, EngineerInfo> engineerInfoMap = engineerInfoRepo.findByGroupId(groupId).stream().collect(Collectors.toMap(EngineerInfo::getEngineerCode, y -> y));
...@@ -186,7 +188,8 @@ public class ExtractServiceImpl implements ExtractService { ...@@ -186,7 +188,8 @@ public class ExtractServiceImpl implements ExtractService {
} }
OrderRequest orderRequest = orderOpt.get(); OrderRequest orderRequest = orderOpt.get();
if (!("OPEN".equals(orderRequest.getStatus()) && ("ASSIGNED".equals(orderRequest.getAppointmentStatus()) || "NOT_ASSIGNED".equals(orderRequest.getAppointmentStatus())))) {
if (!("OPEN".equals(orderRequest.getStatus()) && Set.of("ASSIGNED", "NOT_ASSIGNED").contains(orderRequest.getAppointmentStatus()))) {
log.warn("算法结果更新到工单, step1.1-loop, 工单状态异常, groupId:{}, batchNo:{}, orderId:{}, status:{}, appointment-status:{}", log.warn("算法结果更新到工单, step1.1-loop, 工单状态异常, groupId:{}, batchNo:{}, orderId:{}, status:{}, appointment-status:{}",
groupId, batchNo, orderId, orderRequest.getStatus(), orderRequest.getAppointmentStatus()); groupId, batchNo, orderId, orderRequest.getStatus(), orderRequest.getAppointmentStatus());
return; return;
...@@ -213,24 +216,9 @@ public class ExtractServiceImpl implements ExtractService { ...@@ -213,24 +216,9 @@ public class ExtractServiceImpl implements ExtractService {
// 会有多次上门情况( pre_status='PRE' and status in ('NOT_ASSIGNED', 'ASSIGNED') ,直接更新,其它情况新增) // 会有多次上门情况( pre_status='PRE' and status in ('NOT_ASSIGNED', 'ASSIGNED') ,直接更新,其它情况新增)
Optional<OrderAppointment> appointmentOpt = orderAppointmentRepo.findByOrderId(orderId); Optional<OrderAppointment> appointmentOpt = orderAppointmentRepo.findByOrderId(orderId);
if (appointmentOpt.isPresent() && "PRE".equals(appointmentOpt.get().getPreStatus()) &&
("NOT_ASSIGNED".equals(appointmentOpt.get().getStatus()) || "ASSIGNED".equals(appointmentOpt.get().getStatus()))) {
OrderAppointment appointment = appointmentOpt.get();
appointment.setStatus("ASSIGNED");
appointment.setPreStatus("PRE");
appointment.setEngineerCode(engCode);
appointment.setEngineerName(engName);
appointment.setEngineerPhone(phone);
appointment.setEngineerAge(age);
appointment.setDt(orderRequest.getDt());
appointment.setExpectStartTime(dispatchOrder.getTimeBegin());
appointment.setExpectEndTime(dispatchOrder.getTimeEnd());
appointment.setUpdateTime(LocalDateTime.now());
orderAppointmentRepo.save(appointment);
} else {
if (appointmentOpt.isEmpty()) {
// 没有则插入一条
OrderAppointment appointment = new OrderAppointment(); OrderAppointment appointment = new OrderAppointment();
appointment.setOrderId(dispatchOrder.getOrderId()); appointment.setOrderId(dispatchOrder.getOrderId());
String subId = String.format("%s_%s", dispatchOrder.getOrderId(), DateUtil.format(LocalDateTime.now(), "yyyyMMddHHmmss")); String subId = String.format("%s_%s", dispatchOrder.getOrderId(), DateUtil.format(LocalDateTime.now(), "yyyyMMddHHmmss"));
...@@ -244,12 +232,38 @@ public class ExtractServiceImpl implements ExtractService { ...@@ -244,12 +232,38 @@ public class ExtractServiceImpl implements ExtractService {
appointment.setDt(orderRequest.getDt()); appointment.setDt(orderRequest.getDt());
appointment.setExpectStartTime(dispatchOrder.getTimeBegin()); appointment.setExpectStartTime(dispatchOrder.getTimeBegin());
appointment.setExpectEndTime(dispatchOrder.getTimeEnd()); appointment.setExpectEndTime(dispatchOrder.getTimeEnd());
appointment.setPreStatus("PRE"); appointment.setPreStatus(isConfirm ? "CONFIRM" : "PRE");
appointment.setStatus("ASSIGNED"); appointment.setStatus("ASSIGNED");
appointment.setMemo(""); appointment.setMemo("");
appointment.setCreateTime(LocalDateTime.now()); appointment.setCreateTime(LocalDateTime.now());
appointment.setUpdateTime(LocalDateTime.now()); appointment.setUpdateTime(LocalDateTime.now());
orderAppointmentRepo.save(appointment); orderAppointmentRepo.save(appointment);
} else {
// 如果有记录:1虚拟指派 2排量预派 3
if (Set.of("PRE", "VIRTUAL").contains(appointmentOpt.get().getPreStatus()) &&
Set.of("NOT_ASSIGNED", "ASSIGNED").contains(appointmentOpt.get().getStatus())) {
OrderAppointment appointment = appointmentOpt.get();
appointment.setStatus("ASSIGNED");
appointment.setPreStatus(isConfirm ? "CONFIRM" : "PRE");
appointment.setEngineerCode(engCode);
appointment.setEngineerName(engName);
appointment.setEngineerPhone(phone);
appointment.setEngineerAge(age);
appointment.setDt(orderRequest.getDt());
appointment.setExpectStartTime(dispatchOrder.getTimeBegin());
appointment.setExpectEndTime(dispatchOrder.getTimeEnd());
appointment.setUpdateTime(LocalDateTime.now());
orderAppointmentRepo.save(appointment);
} else {
// 其它情况待补充(改约) todo
if (Set.of("CONFIRM").contains(appointmentOpt.get().getPreStatus()) &&
Set.of("TODO", "???").contains(appointmentOpt.get().getStatus())) {
}
}
} }
}); });
......
...@@ -58,9 +58,9 @@ public class SolveServiceImpl implements SolveService { ...@@ -58,9 +58,9 @@ public class SolveServiceImpl implements SolveService {
// 查询技术员所有技能集 // 查询技术员所有技能集
private List<String> queryEngineerSkills(String engineerCode) { private List<String> queryEngineerSkills(String engineerCode) {
List<String> result = new ArrayList<>(); List<String> result = new ArrayList<>();
String sql = "select concat( b.brand, b.type, b.skill) as skill from engineer_skill a left join product_category b \n" String sql = "select concat( b.brand, '-', b.type, '-', b.skill) as skill from engineer_skill_group a left join skill_info b \n" +
+ "\t on a.category_id= b.product_category_id where a.engineer_code=? and a.status=1 " + " on a.skill_group_code= b.skill_group_code where a.engineer_code=? and a.status=1 \n" +
" and b.brand is not null "; " and b.brand is not null ";
Object[] param = {engineerCode}; Object[] param = {engineerCode};
result = jdbcTemplate.queryForList(sql, param, String.class); result = jdbcTemplate.queryForList(sql, param, String.class);
return result; return result;
...@@ -184,7 +184,7 @@ public class SolveServiceImpl implements SolveService { ...@@ -184,7 +184,7 @@ public class SolveServiceImpl implements SolveService {
SolverConfig solverConfig = new SolverConfig().withSolutionClass(DispatchSolution.class); SolverConfig solverConfig = new SolverConfig().withSolutionClass(DispatchSolution.class);
solverConfig.withEntityClassList(Arrays.asList(Technician.class, Customer.class));// 这里不能漏掉,否则约束不生效 solverConfig.withEntityClassList(Arrays.asList(Technician.class, Customer.class));// 这里不能漏掉,否则约束不生效
solverConfig.withConstraintProviderClass(DispatchConstraintProvider.class); solverConfig.withConstraintProviderClass(DispatchConstraintProvider.class);
solverConfig.withTerminationSpentLimit(Duration.ofSeconds(10)); solverConfig.withTerminationSpentLimit(Duration.ofSeconds(20));
SolverFactory<DispatchSolution> solverFactory = SolverFactory.create(solverConfig); SolverFactory<DispatchSolution> solverFactory = SolverFactory.create(solverConfig);
// Solve the problem // Solve the problem
......
...@@ -3,8 +3,8 @@ server: ...@@ -3,8 +3,8 @@ server:
dispatch: dispatch:
cron: cron:
expr: 0 36 8-18 * * ? expr: 0 43 8-18 * * ?
next-day-limit: 3 next-day-limit: 2
# expr: 0 */10 8-18 * * ? # expr: 0 */10 8-18 * * ?
spring: spring:
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!