Commit 87174379 by 刘鑫

feat(预约单进度查询):

1 parent c10eb803
...@@ -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);
} }
...@@ -18,14 +18,21 @@ package com.dituhui.pea.order.service; ...@@ -18,14 +18,21 @@ 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 {
Result<?> initParameter(); Result<?> initParameter();
Result<?> createOrder(OrderDTO.OrderCreateRequest orderCreateReqDTO) Result<?> createOrder(OrderDTO.OrderCreateRequest orderCreateReqDTO)
throws BusinessException; throws BusinessException;
/**
* 预约单服务进度查询
*
* @param orderId 工单号码
* @return 工单进度信息
* @apiNote 查询预约单状态,返回指定技术员(主,副)信息、推荐上门时间。如果查询为服务当日,增加对应技术员准实时位置,距离公里数,预计到达时间等
*/
OrderDTO.StageResult orderStage(String orderId);
} }
...@@ -18,25 +18,52 @@ package com.dituhui.pea.order.service.impl; ...@@ -18,25 +18,52 @@ 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.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;
...@@ -47,7 +74,12 @@ import org.springframework.transaction.annotation.Transactional; ...@@ -47,7 +74,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;
...@@ -78,6 +110,8 @@ public class OrderCreateServiceImpl implements OrderCreateService { ...@@ -78,6 +110,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;
...@@ -130,6 +164,115 @@ public class OrderCreateServiceImpl implements OrderCreateService { ...@@ -130,6 +164,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));
...@@ -268,7 +411,7 @@ public class OrderCreateServiceImpl implements OrderCreateService { ...@@ -268,7 +411,7 @@ public class OrderCreateServiceImpl implements OrderCreateService {
String joinTags = CollectionUtils.isEmpty(req.getOrderTags()) ? "" : String.join(",", req.getOrderTags()); String joinTags = CollectionUtils.isEmpty(req.getOrderTags()) ? "" : String.join(",", req.getOrderTags());
entity.setBeanTags(joinTags); entity.setBeanTags(joinTags);
entity.setBeanPriority(req.getPriority()); entity.setBeanPriority(req.getPriority());
if (req.getPriority().equals("1")){ if (req.getPriority().equals("1")) {
entity.setAppointmentMethod(AppointmentMethodEnum.AUTO_NOW.name()); entity.setAppointmentMethod(AppointmentMethodEnum.AUTO_NOW.name());
//发送通知分部消息 //发送通知分部消息
sendMsg(entity.getOrgBranchId(), orderId, entity.getExpectTimeBegin().toLocalDate()); sendMsg(entity.getOrgBranchId(), orderId, entity.getExpectTimeBegin().toLocalDate());
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!