Commit 01a22f2e by huangjinxin

Merge remote-tracking branch 'origin/develop' into develop

2 parents a98de2b6 a5572131
...@@ -209,7 +209,6 @@ public class InitEngineerCapacityScheduler { ...@@ -209,7 +209,6 @@ public class InitEngineerCapacityScheduler {
statEntity.setMaxDuration((int) stats.getRemain()); statEntity.setMaxDuration((int) stats.getRemain());
statEntity.setUpdateTime(LocalDateTime.now()); statEntity.setUpdateTime(LocalDateTime.now());
capacityEngineerStatDao.save(statEntity); capacityEngineerStatDao.save(statEntity);
log.info("====== 处理完毕 ======");
} }
public void initOneEngineerByDays(String bdate, String edate, String branchId) { public void initOneEngineerByDays(String bdate, String edate, String branchId) {
......
...@@ -69,7 +69,7 @@ public class BatchScheduler { ...@@ -69,7 +69,7 @@ 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----- teamId:{}, day:{}", teamId, currDay); log.info("dispatchRun begin----- teamId:{}, day:{}", teamId, currDay);
String batchNo = batchService.buildBatchData2(teamId, currDay); String batchNo = batchService.buildBatchData2(teamId, currDay, false);
UUID problemId = solveService.generateProblemId(teamId, batchNo); UUID problemId = solveService.generateProblemId(teamId, batchNo);
log.info("dispatchRun teamId:{}, day:{}, batch:{}, problemId:{}", teamId, currDay, batchNo, problemId); log.info("dispatchRun teamId:{}, day:{}, batch:{}, problemId:{}", teamId, currDay, batchNo, problemId);
......
...@@ -24,7 +24,7 @@ public interface BatchService { ...@@ -24,7 +24,7 @@ public interface BatchService {
void saveDispatchBatch(DispatchBatch batchInfo); void saveDispatchBatch(DispatchBatch batchInfo);
// 小队id // 小队id
public String buildBatchData2(String teamId, String day); public String buildBatchData2(String teamId, String day, boolean cutOff);
public DispatchBatch queryBatchInfoByDay2(String teamId, String day); public DispatchBatch queryBatchInfoByDay2(String teamId, String day);
......
...@@ -192,7 +192,7 @@ public class BatchServiceImpl implements BatchService { ...@@ -192,7 +192,7 @@ public class BatchServiceImpl implements BatchService {
// 检查给定小队、日期是否有在运行的批次任务,没则返回,没有则创建 // 检查给定小队、日期是否有在运行的批次任务,没则返回,没有则创建
@Transactional(isolation = Isolation.READ_COMMITTED, rollbackFor = Exception.class) @Transactional(isolation = Isolation.READ_COMMITTED, rollbackFor = Exception.class)
@Override @Override
public String buildBatchData2(String teamId, String day) { public String buildBatchData2(String teamId, String day, boolean cutOff) {
OrgTeamEntity orgTeamEntity = orgTeamDao.findByTeamId(teamId); OrgTeamEntity orgTeamEntity = orgTeamDao.findByTeamId(teamId);
String groupId = orgTeamEntity.getGroupId(); String groupId = orgTeamEntity.getGroupId();
entityManager.clear(); entityManager.clear();
...@@ -283,11 +283,11 @@ public class BatchServiceImpl implements BatchService { ...@@ -283,11 +283,11 @@ public class BatchServiceImpl implements BatchService {
if (orderCount + orderConfirmCount > 0) { if (orderCount + orderConfirmCount > 0) {
jdbcTemplate.update("update dispatch_batch set engineer_num=? , order_num=?, start_time=?, end_time=null, status='RUNNING' where team_id=? and batch_no=?", jdbcTemplate.update("update dispatch_batch set engineer_num=? , order_num=?, start_time=?, end_time=null, status='RUNNING', cutoffed_time=? where team_id=? and batch_no=?",
engCount, orderCount + orderConfirmCount, LocalDateTime.now(), teamId, batchNo); engCount, orderCount + orderConfirmCount, LocalDateTime.now(), cutOff ? LocalDateTime.now() : null, teamId, batchNo);
} else { } else {
jdbcTemplate.update("update dispatch_batch set engineer_num=? , order_num=?, start_time=?, end_time=?, status='DONE' where team_id=? and batch_no=?", jdbcTemplate.update("update dispatch_batch set engineer_num=? , order_num=?, start_time=?, end_time=?, status='DONE', cutoffed_time=? where team_id=? and batch_no=?",
engCount, 0, LocalDateTime.now(), LocalDateTime.now(), teamId, batchNo); engCount, 0, LocalDateTime.now(), LocalDateTime.now(), cutOff ? LocalDateTime.now() : null, teamId, batchNo);
} }
log.info("准备批次数据完成, teamId:{}, day:{}, batchNo:{}", teamId, batchDay, batchNo); log.info("准备批次数据完成, teamId:{}, day:{}, batchNo:{}", teamId, batchDay, batchNo);
......
package com.dituhui.pea.dispatch.service.impl; package com.dituhui.pea.dispatch.service.impl;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.dituhui.pea.dispatch.dao.DispatchBatchRepository;
import com.dituhui.pea.dispatch.dao.OrgGroupRepository;
import com.dituhui.pea.dispatch.dao.OrgTeamDao; import com.dituhui.pea.dispatch.dao.OrgTeamDao;
import com.dituhui.pea.dispatch.entity.DispatchBatch;
import com.dituhui.pea.dispatch.entity.OrgGroup;
import com.dituhui.pea.dispatch.entity.OrgTeamEntity; import com.dituhui.pea.dispatch.entity.OrgTeamEntity;
import com.dituhui.pea.dispatch.pojo.DispatchSolution; import com.dituhui.pea.dispatch.pojo.DispatchSolution;
import com.dituhui.pea.dispatch.service.BatchService; import com.dituhui.pea.dispatch.service.BatchService;
...@@ -18,10 +25,13 @@ import org.springframework.stereotype.Service; ...@@ -18,10 +25,13 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation; import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.io.File; import java.io.File;
import java.time.LocalDate; import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import java.util.Objects; import java.util.Objects;
import java.util.Optional;
import java.util.UUID; import java.util.UUID;
/** /**
...@@ -34,6 +44,9 @@ import java.util.UUID; ...@@ -34,6 +44,9 @@ import java.util.UUID;
@Slf4j @Slf4j
public class SchedulerServiceImpl implements SchedulerService { public class SchedulerServiceImpl implements SchedulerService {
//默认指派策略
public static final String DEFAULT_STRATEGY_APPOINTMENT = "指派给信息员";
@Value("${dispatch.cron.next-day-limit}") @Value("${dispatch.cron.next-day-limit}")
int nextDaysLimit = 2; int nextDaysLimit = 2;
...@@ -49,7 +62,13 @@ public class SchedulerServiceImpl implements SchedulerService { ...@@ -49,7 +62,13 @@ public class SchedulerServiceImpl implements SchedulerService {
@Autowired @Autowired
OrgTeamDao orgTeamDao; OrgTeamDao orgTeamDao;
@Autowired
OrgGroupRepository orgGroupRepository;
private DefaultSolverFactory<DispatchSolution> solverFactory; private DefaultSolverFactory<DispatchSolution> solverFactory;
@Resource
private DispatchBatchRepository dispatchBatchRepository;
//private Solver<DispatchSolution> solver; //private Solver<DispatchSolution> solver;
public SchedulerServiceImpl() { public SchedulerServiceImpl() {
...@@ -65,14 +84,44 @@ public class SchedulerServiceImpl implements SchedulerService { ...@@ -65,14 +84,44 @@ public class SchedulerServiceImpl implements SchedulerService {
return; return;
} }
OrgGroup orgGroup=orgGroupRepository.findByGroupId(orgTeamEntity.getGroupId()).get();
if (ObjectUtil.equals(2, orgGroup.getCategory())) {
log.error(">>> teamId:{} 来自网点,不自动派工", teamId);
return;
}
String cutOffTime = orgTeamEntity.getCuteOff();
if (StrUtil.isEmpty(cutOffTime)) {
cutOffTime = "18:00";
}
LocalDateTime now = LocalDateTime.now();
String nowTime = DateUtil.format(now, "HH:mm");
String nowTimePlus30 = DateUtil.format(now.plusMinutes(30), "HH:mm");
boolean cutOff = false;
//当前时间大于等于截止时间,或者当前时间+30分钟大于截止时间,运行停止
if (nowTime.compareTo(cutOffTime) >= 0 || nowTimePlus30.compareTo(cutOffTime) > 0) {
cutOff = true;
}
String groupId = orgTeamEntity.getGroupId(); String groupId = orgTeamEntity.getGroupId();
log.info("dispatchRun group:{}, team:{} done", groupId, teamId); log.info("dispatchRun group:{}, team:{} done", groupId, teamId);
for (int i = 1; i <= nextDaysLimit; i++) { for (int i = 1; i <= nextDaysLimit; i++) {
String currDay = LocalDate.now().plusDays(i).format(DateTimeFormatter.ISO_LOCAL_DATE); String currDay = LocalDate.now().plusDays(i).format(DateTimeFormatter.ISO_LOCAL_DATE);
Optional<DispatchBatch> optional = dispatchBatchRepository.findByTeamIdAndBatchDate(teamId, currDay);
if (optional.isPresent() && Objects.nonNull(optional.get().getCutoffedTime())) {
//自动任务截止
log.error(">>> teamId:{}, day:{} 自动任务已截止", teamId, currDay);
continue;
}
try { try {
log.info("dispatchRun begin----- teamId:{}, day:{}", teamId, currDay); log.info("dispatchRun begin----- teamId:{}, day:{}", teamId, currDay);
String batchNo = batchService.buildBatchData2(teamId, currDay); String batchNo = batchService.buildBatchData2(teamId, currDay, cutOff);
UUID problemId = solveService.generateProblemId(teamId, batchNo); UUID problemId = solveService.generateProblemId(teamId, batchNo);
log.info("dispatchRun teamId:{}, day:{}, batch:{}, problemId:{}", teamId, currDay, batchNo, problemId); log.info("dispatchRun teamId:{}, day:{}, batch:{}, problemId:{}", teamId, currDay, batchNo, problemId);
...@@ -88,7 +137,7 @@ public class SchedulerServiceImpl implements SchedulerService { ...@@ -88,7 +137,7 @@ public class SchedulerServiceImpl implements SchedulerService {
DispatchSolutionUtils.removeHardConstraintCustomer(solution, solverFactory); DispatchSolutionUtils.removeHardConstraintCustomer(solution, solverFactory);
log.info("dispatchRun solve done, teamId:{}, day:{}, batch:{}, problemId:{}, score:{}", teamId, currDay, batchNo, problemId, solution.getScore().toShortString()); log.info("dispatchRun solve done, teamId:{}, day:{}, batch:{}, problemId:{}, score:{}", teamId, currDay, batchNo, problemId, solution.getScore().toShortString());
this.solveService.saveSolutionWrp2(solution); this.solveService.saveSolutionWrp2(solution);
this.extractService.extractDispatchToOrder2(teamId, batchNo, false); this.extractService.extractDispatchToOrder2(teamId, batchNo, cutOff);
log.info("dispatchRun done ------ teamId:{}, day:{}", teamId, currDay); log.info("dispatchRun done ------ teamId:{}, day:{}", teamId, currDay);
JacksonSolutionFileIO<DispatchSolution> exporter = new JacksonSolutionFileIO<DispatchSolution>(DispatchSolution.class); JacksonSolutionFileIO<DispatchSolution> exporter = new JacksonSolutionFileIO<DispatchSolution>(DispatchSolution.class);
......
...@@ -3,7 +3,7 @@ server: ...@@ -3,7 +3,7 @@ server:
dispatch: dispatch:
cron: cron:
expr: 0 47 8-22 * * ? expr: 0 14 8-22 * * ?
next-day-limit: 2 next-day-limit: 2
# expr: 0 */10 8-18 * * ? # expr: 0 */10 8-18 * * ?
...@@ -49,12 +49,12 @@ spring: ...@@ -49,12 +49,12 @@ spring:
enabled: false enabled: false
datasource: datasource:
driver-class-name: com.mysql.cj.jdbc.Driver driver-class-name: com.mysql.cj.jdbc.Driver
# url: jdbc:mysql://127.0.0.1:3306/saas_aftersale_test?serverTimezone=Asia/Shanghai url: jdbc:mysql://127.0.0.1:3306/saas_aftersale_test?serverTimezone=Asia/Shanghai
# username: root username: root
# password: 123456 password: 123456
url: jdbc:mysql://localhost:32306/saas_aftersale_test?serverTimezone=Asia/Shanghai # url: jdbc:mysql://localhost:32306/saas_aftersale_test?serverTimezone=Asia/Shanghai
username: boxi # username: boxi
password: boxi_dev_0725 # password: boxi_dev_0725
type: com.alibaba.druid.pool.DruidDataSource type: com.alibaba.druid.pool.DruidDataSource
jpa: jpa:
......
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
<!-- 控制台输出 --> <!-- 控制台输出 -->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender"> <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<filter class="ch.qos.logback.classic.filter.ThresholdFilter"> <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>INFO</level> <level>DEBUG</level>
</filter> </filter>
<!-- 日志输出编码 --> <!-- 日志输出编码 -->
<encoder> <encoder>
...@@ -111,9 +111,10 @@ ...@@ -111,9 +111,10 @@
</appender> </appender>
<logger name="org.optaplanner" level="info"/> <logger name="org.optaplanner" level="info"/>
<logger name="org.springframework.jdbc.core.JdbcTemplate" level="debug" />
<!-- 日志输出级别 --> <!-- 日志输出级别 -->
<root level="debug"> <root level="info">
<appender-ref ref="console"/> <appender-ref ref="console"/>
<appender-ref ref="FileAppender"/> <appender-ref ref="FileAppender"/>
<appender-ref ref="FILE_ERROR"/> <appender-ref ref="FILE_ERROR"/>
......
...@@ -4,7 +4,6 @@ import com.dituhui.pea.common.BusinessException; ...@@ -4,7 +4,6 @@ import com.dituhui.pea.common.BusinessException;
import com.dituhui.pea.common.Result; import com.dituhui.pea.common.Result;
import com.dituhui.pea.enums.StatusCodeEnum; import com.dituhui.pea.enums.StatusCodeEnum;
import com.dituhui.pea.order.common.jackson.DateUtil; import com.dituhui.pea.order.common.jackson.DateUtil;
import com.dituhui.pea.order.common.jackson.JsonUtil;
import com.dituhui.pea.order.dao.TableCodeCheckDao; import com.dituhui.pea.order.dao.TableCodeCheckDao;
import com.dituhui.pea.order.dto.param.BaseDistance; import com.dituhui.pea.order.dto.param.BaseDistance;
import com.dituhui.pea.order.dto.param.BaseDistanceParam; import com.dituhui.pea.order.dto.param.BaseDistanceParam;
...@@ -37,13 +36,10 @@ import org.springframework.web.bind.annotation.RestController; ...@@ -37,13 +36,10 @@ import org.springframework.web.bind.annotation.RestController;
import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull; import javax.validation.constraints.NotNull;
import java.io.IOException;
import java.time.LocalDate; import java.time.LocalDate;
import java.time.ZoneId; import java.time.ZoneId;
import java.util.Date; import java.util.Date;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.stream.Collectors; import java.util.stream.Collectors;
...@@ -66,22 +62,6 @@ public class PeaApiController { ...@@ -66,22 +62,6 @@ public class PeaApiController {
private final TableCodeCheckDao tableCodeCheckDao; private final TableCodeCheckDao tableCodeCheckDao;
private static final String capacity = "{\"groupId\": \"G100038\", \"params\": {\"beginDate\": \"2023-07-21\", \"endDate\": \"2023-07-27\", \"services\": [{\"brand\": \"博世\", \"productType\": \"多门冰箱\", \"serviceType\": \"商场样机安装\"}], \"location\": {\"addressId\":\"21231231\", \"latitude\": 120.608463, \"longitude\": 31.318442, \"name\": \"江苏省苏州市姑苏区蒋庙前\", \"address\": \"江苏省苏州市姑苏区解放大街123号\"}}, \"takeTime\": 720, \"datas\": [{\"date\": \"2023-07-21\", \"segments\": [{\"maxDuration\": 90, \"name\": \"全天\", \"beginTime\": \"2023-07-21 08:00:00\", \"endTime\": \"2023-07-21 17:59:59\", \"status\": 1, \"remain\": 3500}, {\"maxDuration\": 45, \"name\": \"上午\", \"beginTime\": \"2023-07-21 08:00:00\", \"endTime\": \"2023-07-21 11:59:59\", \"status\": 1, \"remain\": 2500}, {\"maxDuration\": 60, \"name\": \"下午\", \"beginTime\": \"2023-07-21 13:00:00\", \"endTime\": \"2023-07-21 17:59:59\", \"status\": 0, \"remain\": 1000}, {\"maxDuration\": 60, \"name\": \"时间段\", \"beginTime\": \"2023-07-21 13:00:00\", \"endTime\": \"2023-07-21 15:00:00\", \"status\": 1, \"remain\": 480}]}]}";
private static final String day_capacity = "{\"groupId\": \"G100038\", \"params\": {\"beginDate\": \"2023-07-21\", \"endDate\": \"2023-07-27\", \"services\": [{\"brand\": \"博世\", \"productType\": \"多门冰箱\", \"serviceType\": \"商场样机安装\"}], \"location\": {\"addressId\": \"21231231\", \"latitude\": 120.608463, \"longitude\": 31.318442, \"name\": \"江苏省苏州市姑苏区蒋庙前\", \"address\": \"江苏省苏州市姑苏区解放大街123号\"}}, \"takeTime\": 720, \"datas\": [{\"date\": \"2023-07-21\", \"segments\": [{\"maxDuration\": 90, \"name\": \"全天\", \"beginTime\": \"2023-07-21 08:00:00\", \"endTime\": \"2023-07-21 17:59:59\", \"status\": 1, \"remain\": 3500}]}]}";
private static final String half_capacity = "{\"groupId\": \"G100038\", \"params\": {\"beginDate\": \"2023-07-21\", \"endDate\": \"2023-07-27\", \"services\": [{\"brand\": \"博世\", \"productType\": \"多门冰箱\", \"serviceType\": \"商场样机安装\"}], \"location\": {\"addressId\": \"21231231\", \"latitude\": 120.608463, \"longitude\": 31.318442, \"name\": \"江苏省苏州市姑苏区蒋庙前\", \"address\": \"江苏省苏州市姑苏区解放大街123号\"}}, \"takeTime\": 720, \"datas\": [{\"date\": \"2023-07-22\", \"segments\": [{\"maxDuration\": 90, \"name\": \"全天\", \"beginTime\": \"2023-07-22 08:00:00\", \"endTime\": \"2023-07-22 17:59:59\", \"status\": 1, \"remain\": 3500}, {\"maxDuration\": 45, \"name\": \"上午\", \"beginTime\": \"2023-07-22 08:00:00\", \"endTime\": \"2023-07-22 11:59:59\", \"status\": 1, \"remain\": 2500}, {\"maxDuration\": 60, \"name\": \"下午\", \"beginTime\": \"2023-07-22 13:00:00\", \"endTime\": \"2023-07-22 17:59:59\", \"status\": 0, \"remain\": 1000}]}]}";
private static final String half_capacity2 = "{\"groupId\": \"G100038\", \"params\": {\"beginDate\": \"2023-07-21\", \"endDate\": \"2023-07-27\", \"services\": [{\"brand\": \"博世\", \"productType\": \"多门冰箱\", \"serviceType\": \"商场样机安装\"}], \"location\": {\"addressId\": \"21231231\", \"latitude\": 120.608463, \"longitude\": 31.318442, \"name\": \"江苏省苏州市姑苏区蒋庙前\", \"address\": \"江苏省苏州市姑苏区解放大街123号\"}}, \"takeTime\": 720, \"datas\": [{\"date\": \"2023-07-21\", \"segments\": [{\"maxDuration\": 90, \"name\": \"全天\", \"beginTime\": \"2023-07-21 08:00:00\", \"endTime\": \"2023-07-21 17:59:59\", \"status\": 1, \"remain\": 1000}, {\"maxDuration\": 60, \"name\": \"下午\", \"beginTime\": \"2023-07-21 13:00:00\", \"endTime\": \"2023-07-21 17:59:59\", \"status\": 0, \"remain\": 1000}]}]}";
private static final String date_capacity = "{\"groupId\": \"G100038\", \"params\": {\"beginDate\": \"2023-07-21\", \"endDate\": \"2023-07-27\", \"services\": [{\"brand\": \"博世\", \"productType\": \"多门冰箱\", \"serviceType\": \"商场样机安装\"}], \"location\": {\"addressId\": \"21231231\", \"latitude\": 120.608463, \"longitude\": 31.318442, \"name\": \"江苏省苏州市姑苏区蒋庙前\", \"address\": \"江苏省苏州市姑苏区解放大街123号\"}}, \"takeTime\": 720, \"datas\": [{\"date\": \"2023-07-23\", \"segments\": [{\"maxDuration\": 90, \"name\": \"全天\", \"beginTime\": \"2023-07-23 08:00:00\", \"endTime\": \"2023-07-23 17:59:59\", \"status\": 1, \"remain\": 480}, {\"maxDuration\": 60, \"name\": \"时间段\", \"beginTime\": \"2023-07-23 13:00:00\", \"endTime\": \"2023-07-23 15:00:00\", \"status\": 1, \"remain\": 480}]}]}";
private static final String stage = "{\"orderId\": \"X10001\", \"engineerCode\": \"E12005\", \"engineerName\": \"祝枝山\", \"engineerCodeAssist\": \"E12446\", \"engineerNameAssist\": \"李晓阳\", \"planVisitTime\": \"2023-07-27 12:00:00\", \"realtimeInfo\": {\"engineerLocation\": {\"latitude\": 31.349701, \"longitude\": 120.675945, \"address\": \"江苏省苏州市苏州工业园区和顺路\", \"name\": \"和顺大酒店\"}, \"estimate\": {\"distance\": 2300, \"arriveTime\": \"2023-07-27 12:12:00\"}}}";
private static Map<String, String> makeMap = new HashMap<>() {
{
put("120.056196,28.910257", day_capacity);
put("120.675945,31.349701", half_capacity);
put("120.721813,31.303003", half_capacity2);
put("120.763953,31.318573", date_capacity);
}
};
/** /**
* 3.1GET 查询技术员日历 * 3.1GET 查询技术员日历
* *
...@@ -215,13 +195,8 @@ public class PeaApiController { ...@@ -215,13 +195,8 @@ public class PeaApiController {
* @apiNote 查询预约单状态,返回指定技术员(主,副)信息、推荐上门时间。如果查询为服务当日,增加对应技术员准实时位置,距离公里数,预计到达时间等 * @apiNote 查询预约单状态,返回指定技术员(主,副)信息、推荐上门时间。如果查询为服务当日,增加对应技术员准实时位置,距离公里数,预计到达时间等
*/ */
@GetMapping("/order/stage/query") @GetMapping("/order/stage/query")
public Result<OrderDTO.StageResult> orderStage(@NotBlank @RequestParam("orderId") String orderId) throws IOException { public Result<OrderDTO.StageResult> orderStage(@NotBlank @RequestParam("orderId") String orderId) {
return Result.success(orderCreateService.orderStage(orderId));
OrderDTO.StageResult stageResult = JsonUtil.parse(stage, OrderDTO.StageResult.class).get();
stageResult.setOrderId(orderId);
return Result.success(stageResult);
} }
/** /**
......
...@@ -40,4 +40,14 @@ public interface OrderInfoDao extends JpaRepository<OrderInfoEntity, Long>, JpaS ...@@ -40,4 +40,14 @@ public interface OrderInfoDao extends JpaRepository<OrderInfoEntity, Long>, JpaS
List<OrderInfoEntity> findByMultipleOrdersAndOrderIdNot(String multipleOrders, String orderId); List<OrderInfoEntity> findByMultipleOrdersAndOrderIdNot(String multipleOrders, String orderId);
List<OrderInfoEntity> findByMultipleOrders(String multipleOrders); List<OrderInfoEntity> findByMultipleOrders(String multipleOrders);
/**
* 获取工程师指定日期内的所有工单
*
* @param engineerCode 工程师编码
* @param targetDate 指定日期
* @return 指定工程师在指定日期内的所有工单
*/
@Query(value = "SELECT * FROM order_info oi WHERE (engineer_code = :engineerCode OR engineer_code_sub =:engineerCode) AND dt = :targetDate", nativeQuery = true)
List<OrderInfoEntity> getEngineerDateOrder(String engineerCode, String targetDate);
} }
...@@ -98,7 +98,7 @@ public class BeanUserDetail { ...@@ -98,7 +98,7 @@ public class BeanUserDetail {
/** /**
* 常用出发地址,常驻的工作地址 * 常用出发地址,常驻的工作地址
*/ */
private String address; private Address address;
/** /**
* 等级=大修、零售、项目、鉴定、寄修 * 等级=大修、零售、项目、鉴定、寄修
*/ */
......
...@@ -18,7 +18,6 @@ package com.dituhui.pea.order.service; ...@@ -18,7 +18,6 @@ package com.dituhui.pea.order.service;
import com.dituhui.pea.common.BusinessException; import com.dituhui.pea.common.BusinessException;
import com.dituhui.pea.common.Result; import com.dituhui.pea.common.Result;
import com.dituhui.pea.order.dto.OrderCreateReqDTO;
import com.dituhui.pea.order.dto.param.OrderDTO; import com.dituhui.pea.order.dto.param.OrderDTO;
public interface OrderCreateService { public interface OrderCreateService {
...@@ -28,4 +27,12 @@ public interface OrderCreateService { ...@@ -28,4 +27,12 @@ public interface OrderCreateService {
Result<?> createOrder(OrderDTO.OrderCreateRequest orderCreateReqDTO) Result<?> createOrder(OrderDTO.OrderCreateRequest orderCreateReqDTO)
throws BusinessException; throws BusinessException;
/**
* 预约单服务进度查询
*
* @param orderId 工单号码
* @return 工单进度信息
* @apiNote 查询预约单状态,返回指定技术员(主,副)信息、推荐上门时间。如果查询为服务当日,增加对应技术员准实时位置,距离公里数,预计到达时间等
*/
OrderDTO.StageResult orderStage(String orderId);
} }
...@@ -18,26 +18,53 @@ package com.dituhui.pea.order.service.impl; ...@@ -18,26 +18,53 @@ package com.dituhui.pea.order.service.impl;
import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.dituhui.pea.common.BusinessException;
import com.dituhui.pea.common.Result; import com.dituhui.pea.common.Result;
import com.dituhui.pea.common.ResultEnum; import com.dituhui.pea.common.ResultEnum;
import com.dituhui.pea.enums.StatusCodeEnum; import com.dituhui.pea.enums.StatusCodeEnum;
import com.dituhui.pea.order.common.*; import com.dituhui.pea.order.common.CapacityUtils;
import com.dituhui.pea.order.dao.*; import com.dituhui.pea.order.common.DateUtils;
import com.dituhui.pea.order.dto.*; import com.dituhui.pea.order.common.Distance;
import com.dituhui.pea.order.common.EngineerUtils;
import com.dituhui.pea.order.common.OrderAssignCheck;
import com.dituhui.pea.order.common.SaasUtils;
import com.dituhui.pea.order.dao.EngineerBusinessDao;
import com.dituhui.pea.order.dao.EngineerInfoDao;
import com.dituhui.pea.order.dao.EngineerSkillDao;
import com.dituhui.pea.order.dao.OrderInfoDao;
import com.dituhui.pea.order.dao.OrgBranchDao;
import com.dituhui.pea.order.dao.OrgGroupDao;
import com.dituhui.pea.order.dao.OrgTeamDao;
import com.dituhui.pea.order.dao.OrgTeamEngineerDao;
import com.dituhui.pea.order.dao.SkillInfoDao;
import com.dituhui.pea.order.dto.LabelValueDTO;
import com.dituhui.pea.order.dto.MsgDTO;
import com.dituhui.pea.order.dto.ParameterRespDTO;
import com.dituhui.pea.order.dto.param.Location; import com.dituhui.pea.order.dto.param.Location;
import com.dituhui.pea.order.dto.param.OrderDTO; import com.dituhui.pea.order.dto.param.OrderDTO;
import com.dituhui.pea.order.dto.param.OrgTeamInfo; import com.dituhui.pea.order.dto.param.OrgTeamInfo;
import com.dituhui.pea.order.entity.*; import com.dituhui.pea.order.entity.EngineerBusinessEntity;
import com.dituhui.pea.order.entity.EngineerInfoEntity;
import com.dituhui.pea.order.entity.EngineerSkillEntity;
import com.dituhui.pea.order.entity.OrderInfoEntity;
import com.dituhui.pea.order.entity.OrgBranchEntity;
import com.dituhui.pea.order.entity.OrgTeamEngineerEntity;
import com.dituhui.pea.order.entity.OrgTeamEntity;
import com.dituhui.pea.order.entity.SkillInfoEntity;
import com.dituhui.pea.order.enums.AppointmentMethodEnum; import com.dituhui.pea.order.enums.AppointmentMethodEnum;
import com.dituhui.pea.order.enums.OrderEventEnum; import com.dituhui.pea.order.enums.OrderEventEnum;
import com.dituhui.pea.order.enums.OrderFlowEnum; import com.dituhui.pea.order.enums.OrderFlowEnum;
import com.dituhui.pea.order.enums.OrderStatusEnum; import com.dituhui.pea.order.enums.OrderStatusEnum;
import com.dituhui.pea.order.service.*; import com.dituhui.pea.order.service.CommonService;
import com.dituhui.pea.order.service.FendanService;
import com.dituhui.pea.order.service.MsgService;
import com.dituhui.pea.order.service.OrderCreateService;
import com.dituhui.pea.order.service.OrderInfoService;
import com.dituhui.pea.order.utils.CommonUtil; import com.dituhui.pea.order.utils.CommonUtil;
import com.dituhui.pea.pojo.saas.req.AdministrativeDistrictReq; import com.dituhui.pea.pojo.saas.req.AdministrativeDistrictReq;
import com.dituhui.pea.pojo.saas.resp.AdministrativeDistrictResp; import com.dituhui.pea.pojo.saas.resp.AdministrativeDistrictResp;
import com.dituhui.pea.util.DateUtil; import com.dituhui.pea.util.DateUtil;
import io.seata.core.context.RootContext; import lombok.Data;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
...@@ -48,7 +75,12 @@ import org.springframework.transaction.annotation.Transactional; ...@@ -48,7 +75,12 @@ import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDate; import java.time.LocalDate;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.UUID; import java.util.UUID;
import java.util.stream.Collectors; import java.util.stream.Collectors;
...@@ -79,6 +111,8 @@ public class OrderCreateServiceImpl implements OrderCreateService { ...@@ -79,6 +111,8 @@ public class OrderCreateServiceImpl implements OrderCreateService {
@Autowired @Autowired
private EngineerInfoDao engineerInfoDao; private EngineerInfoDao engineerInfoDao;
@Autowired
private EngineerBusinessDao engineerBusinessDao;
@Autowired @Autowired
private OrgTeamEngineerDao orgTeamEngineerDao; private OrgTeamEngineerDao orgTeamEngineerDao;
...@@ -131,6 +165,115 @@ public class OrderCreateServiceImpl implements OrderCreateService { ...@@ -131,6 +165,115 @@ public class OrderCreateServiceImpl implements OrderCreateService {
} }
@Override @Override
public OrderDTO.StageResult orderStage(String orderId) {
//获取工单信息
OrderInfoEntity orderInfo = orderInfoDao.getByOrderId(orderId);
if (Objects.isNull(orderInfo)) {
throw new BusinessException("没有找到" + orderId + "相关的工单信息");
}
OrderDTO.StageResult stageResult = new OrderDTO.StageResult();
stageResult.setOrderId(orderInfo.getOrderId());
final String engineerCode = orderInfo.getEngineerCode();
stageResult.setEngineerCode(engineerCode);
stageResult.setEngineerName(orderInfo.getEngineerName());
final String engineerCodeSub = orderInfo.getEngineerCodeSub();
if (StringUtils.isNotBlank(engineerCodeSub)) {
stageResult.setEngineerCodeAssist(engineerCodeSub);
//查询辅助工程师信息
EngineerInfoEntity subEngineerInfo = engineerInfoDao.getByEngineerCode(engineerCodeSub);
stageResult.setEngineerNameAssist(subEngineerInfo.getName());
}
//获取计划上门时间
final LocalDateTime planStartTime = orderInfo.getPlanStartTime();
Date palnDate = com.dituhui.pea.order.common.jackson.DateUtil.toDate(planStartTime);
stageResult.setPlanVisitTime(palnDate);
if (Objects.isNull(planStartTime) || !LocalDate.now().equals(planStartTime.toLocalDate())) {
return stageResult;
}
//如果计划时间为今天 则返回工程师位置信息
Location location = engineerDateLocation(engineerCode);
OrderDTO.RealtimeInfo realtimeInfo = new OrderDTO.RealtimeInfo();
realtimeInfo.setEngineerLocation(location);
OrderDTO.Estimate estimate = new OrderDTO.Estimate();
// 计算两点间距离
Pair distanceAndDuration = getDistanceAndDuration(location.getLatitude(), location.getLongitude(),
Double.parseDouble(orderInfo.getX()), Double.parseDouble(orderInfo.getY()));
estimate.setDistance((double) distanceAndDuration.getDistance());
estimate.setArriveTime(palnDate);
realtimeInfo.setEstimate(estimate);
stageResult.setRealtimeInfo(realtimeInfo);
return stageResult;
}
private Pair getDistanceAndDuration(double x1, double y1, double x2, double y2) {
Distance cal = new Distance();
long distance = Math.round(cal.calculateDistance(x1, y1, x2, y2) * 1.4); // 单位为米
long duration = distance / (19 * 1000 / 60); // 时间为分钟,假设电动车速度为19km/h
return new Pair((int) distance, (int) duration);
}
@Data
class Pair {
private int distance;
private int duration;
public Pair(int distance, int duration) {
this.distance = distance;
this.duration = duration;
}
}
private Location engineerDateLocation(String engineerCode) {
final LocalDate currentDate = LocalDate.now();
List<OrderInfoEntity> engineerDateOrderList = orderInfoDao.getEngineerDateOrder(engineerCode, DateUtils.formatDate(currentDate));
Set<String> ss = Set.of("CANCELED", "RESCHEDULED");
engineerDateOrderList = engineerDateOrderList.stream()
.filter(e -> !ss.contains(e.getOrderStatus()))
.collect(Collectors.toList());
Location location = new Location();
//查询工程师已开始的工单
Optional<OrderInfoEntity> startedOrder = engineerDateOrderList.stream()
.filter(e -> Objects.equals("STARTED", e.getServiceStatus()))
.max(Comparator.comparing(OrderInfoEntity::getPlanStartTime));
if (startedOrder.isPresent()) {
OrderInfoEntity startedOrderInfo = startedOrder.get();
location.setAddress(startedOrderInfo.getAddress());
location.setLongitude(Double.parseDouble(startedOrderInfo.getX()));
location.setLatitude(Double.parseDouble(startedOrderInfo.getY()));
return location;
}
//如果没有已开始的工单 查询 最后一个已完成工单
Optional<OrderInfoEntity> finishedOrder = engineerDateOrderList.stream()
.filter(e -> Objects.equals("FINISHED", e.getServiceStatus()))
.max(Comparator.comparing(OrderInfoEntity::getActualEndTime));
if (finishedOrder.isPresent()) {
OrderInfoEntity finishedOrderInfo = finishedOrder.get();
location.setAddress(finishedOrderInfo.getAddress());
location.setLongitude(Double.parseDouble(finishedOrderInfo.getX()));
location.setLatitude(Double.parseDouble(finishedOrderInfo.getY()));
} else {
// 如果都没有, 则获取工程师出发地址
EngineerBusinessEntity byEngineerCode = engineerBusinessDao.getByEngineerCode(engineerCode);
location.setAddress(byEngineerCode.getAddress());
location.setLongitude(Double.parseDouble(byEngineerCode.getX()));
location.setLatitude(Double.parseDouble(byEngineerCode.getY()));
}
return location;
}
@Override
@Transactional @Transactional
public Result<?> createOrder(OrderDTO.OrderCreateRequest req) { public Result<?> createOrder(OrderDTO.OrderCreateRequest req) {
log.info("[createOrder] req: {}", JSONObject.toJSONString(req)); log.info("[createOrder] req: {}", JSONObject.toJSONString(req));
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!