Commit 2896b157 by chamberone

Merge branch 'develop' of https://zhangguoping@gitlab.dituhui.com/bsh/project/pr…

…oject.git into develop
2 parents 5ae97a31 c679fb62
Showing with 855 additions and 223 deletions
### 批次准备数据、aps引擎处理
* 接口
* ### 重新组织数据并开始计算
GET http://localhost:8011/dispatch/prepare/solveAsync/gsuzhou/2023-07-07
* 查看实时处理状态
GET http://localhost:8011/dispatch/prepare/solveStatus/gsuzhou/2023-07-07
* 停止实时处理状态
GET http://localhost:8011/dispatch/prepare/solveStop/gsuzhou/2023-07-07
...@@ -56,7 +56,7 @@ public class BatchController { ...@@ -56,7 +56,7 @@ public class BatchController {
@JsonDeserialize(using = LocalDateTimeDeserializer.class) @JsonDeserialize(using = LocalDateTimeDeserializer.class)
@JsonSerialize(using = LocalDateTimeSerializer.class) @JsonSerialize(using = LocalDateTimeSerializer.class)
@JsonFormat( pattern = "yyyy-MM-dd HH:mm:ss") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
LocalDateTime endTime; LocalDateTime endTime;
String status; String status;
} }
...@@ -88,29 +88,10 @@ public class BatchController { ...@@ -88,29 +88,10 @@ public class BatchController {
} }
/* @GetMapping("/query/{groupId}/{day}")
* 检查指定日期的小组是否有在运行的批次任务,有则返回,没有则创建后返回批次码 public Result<?> queryBatch(@PathVariable String groupId, @PathVariable String day) {
*/
@GetMapping("/build/{groupId}/{day}")
public Result<?> buildBatch(@PathVariable String groupId, @PathVariable String day) {
log.info("buildBatch, groupId:{}, day:{}", groupId, day); log.info("buildBatch, groupId:{}, day:{}", groupId, day);
try { DispatchBatch batch = batchService.queryBatchInfoByDay(groupId, day);
String batchNo = batchService.buildBatchData(groupId, day);
DispatchBatch batch = batchService.queryBatch(groupId, batchNo);
DispatchBatchDTO batchDTO = new DispatchBatchDTO();
BeanUtil.copyProperties(batch, batchDTO, CopyOptions.create().setIgnoreNullValue(true));
return Result.success(batchDTO);
} catch (SQLException e) {
log.error("buildBatch error", e);
return Result.failed(e.getMessage());
}
}
@GetMapping("/query/{groupId}/{batchNo}")
public Result<?> queryBatch(@PathVariable String groupId, @PathVariable String batchNo) {
log.info("buildBatch, groupId:{}, batchNo:{}", groupId, batchNo);
DispatchBatch batch = batchService.queryBatch(groupId, batchNo);
DispatchBatchDTO batchDTO = new DispatchBatchDTO(); DispatchBatchDTO batchDTO = new DispatchBatchDTO();
BeanUtil.copyProperties(batch, batchDTO, CopyOptions.create().setIgnoreNullValue(true)); BeanUtil.copyProperties(batch, batchDTO, CopyOptions.create().setIgnoreNullValue(true));
......
...@@ -7,9 +7,11 @@ import com.dituhui.pea.dispatch.constraint.DispatchConstraintProvider; ...@@ -7,9 +7,11 @@ import com.dituhui.pea.dispatch.constraint.DispatchConstraintProvider;
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;
import com.dituhui.pea.dispatch.service.BatchService;
import com.dituhui.pea.dispatch.service.ExtractService; import com.dituhui.pea.dispatch.service.ExtractService;
import com.dituhui.pea.dispatch.service.SolveService; import com.dituhui.pea.dispatch.service.SolveService;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.optaplanner.core.api.score.buildin.hardsoftlong.HardSoftLongScore; import org.optaplanner.core.api.score.buildin.hardsoftlong.HardSoftLongScore;
import org.optaplanner.core.api.solver.SolverManager; import org.optaplanner.core.api.solver.SolverManager;
import org.optaplanner.core.api.solver.SolverStatus; import org.optaplanner.core.api.solver.SolverStatus;
...@@ -21,6 +23,7 @@ import org.springframework.web.bind.annotation.PathVariable; ...@@ -21,6 +23,7 @@ import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import java.sql.SQLException;
import java.time.Duration; import java.time.Duration;
import java.util.*; import java.util.*;
...@@ -39,6 +42,9 @@ public class PrepareController { ...@@ -39,6 +42,9 @@ public class PrepareController {
@Autowired @Autowired
SolveService solveService; SolveService solveService;
@Autowired
BatchService batchService;
private SolverManager<DispatchSolution, UUID> solverManager; private SolverManager<DispatchSolution, UUID> solverManager;
...@@ -54,7 +60,7 @@ public class PrepareController { ...@@ -54,7 +60,7 @@ public class PrepareController {
/* /*
* 运行批次任务,直接返回结果 * 运行批次任务,直接返回结果(不重新进行数据准备)
*/ */
@GetMapping("/solveTest/{groupId}/{batchNo}") @GetMapping("/solveTest/{groupId}/{batchNo}")
public Result<?> prepareAndSolve(@PathVariable String groupId, @PathVariable String batchNo) { public Result<?> prepareAndSolve(@PathVariable String groupId, @PathVariable String batchNo) {
...@@ -70,10 +76,12 @@ public class PrepareController { ...@@ -70,10 +76,12 @@ public class PrepareController {
return Result.success(resultMap); return Result.success(resultMap);
} }
// 异步任务运行 todo // 重新进行数据准备、异步任务运行
@GetMapping("/solveAsync/{groupId}/{batchNo}") @GetMapping("/solveAsync/{groupId}/{day}")
public Result<?> solveAsync(@PathVariable String groupId, @PathVariable String batchNo) { public Result<?> solveAsync(@PathVariable String groupId, @PathVariable String day) throws SQLException {
log.info("调用引擎处理-异步处理, groupId:{}, batchNo:{}", groupId, batchNo); log.info("调用引擎处理-异步处理, groupId:{}, day:{}", groupId, day);
String batchNo = batchService.buildBatchData(groupId, day);
log.info("调用引擎处理-异步处理, groupId:{}, day:{}, batchNo:{}", groupId, day, batchNo);
UUID problemId = solveService.generateProblemId(groupId, batchNo); UUID problemId = solveService.generateProblemId(groupId, batchNo);
// 提交问题开始求解 // 提交问题开始求解
DispatchSolution problem = solveService.prepareSolution(groupId, batchNo); DispatchSolution problem = solveService.prepareSolution(groupId, batchNo);
...@@ -86,22 +94,32 @@ public class PrepareController { ...@@ -86,22 +94,32 @@ public class PrepareController {
return Result.success("已触发异步执行"); return Result.success("已触发异步执行");
} }
@GetMapping("/solveStatus/{groupId}/{batchNo}") @GetMapping("/solveStatus/{groupId}/{day}")
public Result<?> solveStatus(@PathVariable String groupId, @PathVariable String batchNo) { public Result<?> solveStatus(@PathVariable String groupId, @PathVariable String day) {
log.info("查询引擎处理状态, groupId:{}, batchNo:{}", groupId, batchNo); log.info("查询引擎处理状态, groupId:{}, day:{}", groupId, day);
String batchNo = batchService.queryBatchNoByDay(groupId, day);
log.info("查询引擎处理状态, groupId:{}, day:{}, batchNo:{}", groupId, day, batchNo);
if (StringUtils.isEmpty(batchNo)) {
return Result.failed("未查询到到批次数据信息");
}
UUID problemId = solveService.generateProblemId(groupId, batchNo); UUID problemId = solveService.generateProblemId(groupId, batchNo);
SolverStatus status = solverManager.getSolverStatus(problemId); SolverStatus status = solverManager.getSolverStatus(problemId);
log.info("查询引擎处理状态, groupId:{}, batchNo:{}, status:{}", groupId, batchNo, status.toString()); log.info("查询引擎处理状态, groupId:{}, day:{}, batchNo:{}, status:{}", groupId, day, batchNo, status.toString());
return Result.success(status); return Result.success(status);
} }
@GetMapping("/solveStop/{groupId}/{batchNo}") @GetMapping("/solveStop/{groupId}/{day}")
public Result<?> solveStop(@PathVariable String groupId, @PathVariable String batchNo) { public Result<?> solveStop(@PathVariable String groupId, @PathVariable String day) {
log.info("停止引擎处理批次, groupId:{}, batchNo:{}", groupId, batchNo); log.info("停止引擎处理批次, groupId:{}, day:{}", groupId, day);
String batchNo = batchService.queryBatchNoByDay(groupId, day);
log.info("查询引擎处理状态, groupId:{}, day:{}, batchNo:{}", groupId, day, batchNo);
if (StringUtils.isEmpty(batchNo)) {
return Result.failed("未查询到到批次数据信息");
}
UUID problemId = solveService.generateProblemId(groupId, batchNo); UUID problemId = solveService.generateProblemId(groupId, batchNo);
solverManager.terminateEarly(problemId); solverManager.terminateEarly(problemId);
SolverStatus status = solverManager.getSolverStatus(problemId); SolverStatus status = solverManager.getSolverStatus(problemId);
log.info("停止引擎处理批次, groupId:{}, batchNo:{}, status:{}", groupId, batchNo, status.toString()); log.info("停止引擎处理批次, groupId:{}, day:{}, batchNo:{}, status:{}", groupId, day, batchNo, status.toString());
return Result.success(status); return Result.success(status);
} }
......
...@@ -4,12 +4,15 @@ package com.dituhui.pea.dispatch.entity; ...@@ -4,12 +4,15 @@ package com.dituhui.pea.dispatch.entity;
import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import lombok.Data; import lombok.Data;
import javax.persistence.*; import javax.persistence.*;
import java.io.Serializable; import java.io.Serializable;
import java.time.LocalDate;
import java.time.LocalDateTime; import java.time.LocalDateTime;
@Data @Data
...@@ -46,6 +49,13 @@ public class OrderAppointment implements Serializable { ...@@ -46,6 +49,13 @@ public class OrderAppointment implements Serializable {
private Integer isWorkshop; private Integer isWorkshop;
@JsonDeserialize(using = LocalDateDeserializer.class)
@JsonSerialize(using = LocalDateSerializer.class)
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
@Column(name = "dt")
private LocalDate dt;
@JsonDeserialize(using = LocalDateTimeDeserializer.class) @JsonDeserialize(using = LocalDateTimeDeserializer.class)
@JsonSerialize(using = LocalDateTimeSerializer.class) @JsonSerialize(using = LocalDateTimeSerializer.class)
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
......
...@@ -4,12 +4,15 @@ package com.dituhui.pea.dispatch.entity; ...@@ -4,12 +4,15 @@ package com.dituhui.pea.dispatch.entity;
import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import lombok.Data; import lombok.Data;
import javax.persistence.*; import javax.persistence.*;
import java.io.Serializable; import java.io.Serializable;
import java.time.LocalDate;
import java.time.LocalDateTime; import java.time.LocalDateTime;
@Data @Data
...@@ -57,6 +60,14 @@ public class OrderRequest implements Serializable { ...@@ -57,6 +60,14 @@ public class OrderRequest implements Serializable {
@Column(name = "fault_describe") @Column(name = "fault_describe")
private String faultDescribe; private String faultDescribe;
@JsonDeserialize(using = LocalDateDeserializer.class)
@JsonSerialize(using = LocalDateSerializer.class)
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
@Column(name = "dt")
private LocalDate dt;
@JsonDeserialize(using = LocalDateTimeDeserializer.class) @JsonDeserialize(using = LocalDateTimeDeserializer.class)
@JsonSerialize(using = LocalDateTimeSerializer.class) @JsonSerialize(using = LocalDateTimeSerializer.class)
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
......
...@@ -19,6 +19,8 @@ public interface BatchService { ...@@ -19,6 +19,8 @@ public interface BatchService {
@Transactional @Transactional
String buildBatchData(String groupId, String day) throws SQLException; String buildBatchData(String groupId, String day) throws SQLException;
DispatchBatch queryBatchInfoByDay(String groupId, String day);
String queryBatchNoByDay(String groupId, String day);
DispatchBatch queryBatch(String groupId, String day);
} }
...@@ -103,7 +103,7 @@ public class BatchServiceImpl implements BatchService { ...@@ -103,7 +103,7 @@ public class BatchServiceImpl implements BatchService {
" and a.dt = ? " + " and a.dt = ? " +
" and appointment_status ='NOT_ASSIGNED' and appointment_method like 'AUTO%' \n" + " and 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" +
...@@ -117,12 +117,14 @@ public class BatchServiceImpl implements BatchService { ...@@ -117,12 +117,14 @@ public class BatchServiceImpl implements BatchService {
" and a.appointment_status = 'ASSIGNED' and appointment_method like 'AUTO%' \n" + " and a.appointment_status = 'ASSIGNED' and appointment_method like 'AUTO%' \n" +
" and o.pre_status ='PRE' \n" + " and o.pre_status ='PRE' \n" +
" 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);
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=?",
engCount, orderCount+orderCountPre, LocalDateTime.now(), groupId, batchNo); engCount, orderCount + orderCountPre, LocalDateTime.now(), groupId, batchNo);
log.info("准备批次数据完成, groupId:{}, day:{}, batchNo:{}", groupId, batchDay, batchNo); log.info("准备批次数据完成, groupId:{}, day:{}, batchNo:{}", groupId, batchDay, batchNo);
...@@ -130,13 +132,20 @@ public class BatchServiceImpl implements BatchService { ...@@ -130,13 +132,20 @@ public class BatchServiceImpl implements BatchService {
} }
public DispatchBatch queryBatch(String groupId, String batchNo) { @Override
List<DispatchBatch> batchList = batchRepository.findLatestGroup(groupId, batchNo); public String queryBatchNoByDay(String groupId, String day) {
if (batchList.size() > 0) { Optional<DispatchBatch> optional = batchRepository.findByGroupIdAndBatchDate(groupId, day);
return batchList.get(0); if (optional.isPresent()) {
return optional.get().getBatchNo();
} else { } else {
return new DispatchBatch(); return "";
}
} }
@Override
public DispatchBatch queryBatchInfoByDay(String groupId, String day) {
Optional<DispatchBatch> optional = batchRepository.findByGroupIdAndBatchDate(groupId, day);
return optional.orElseGet(DispatchBatch::new);
} }
......
...@@ -223,6 +223,7 @@ public class ExtractServiceImpl implements ExtractService { ...@@ -223,6 +223,7 @@ public class ExtractServiceImpl implements ExtractService {
appointment.setEngineerName(engName); appointment.setEngineerName(engName);
appointment.setEngineerPhone(phone); appointment.setEngineerPhone(phone);
appointment.setEngineerAge(age); appointment.setEngineerAge(age);
appointment.setDt(orderRequest.getDt());
appointment.setExpectStartTime(dispatchOrder.getTimeBegin()); appointment.setExpectStartTime(dispatchOrder.getTimeBegin());
appointment.setExpectEndTime(dispatchOrder.getTimeEnd()); appointment.setExpectEndTime(dispatchOrder.getTimeEnd());
appointment.setUpdateTime(LocalDateTime.now()); appointment.setUpdateTime(LocalDateTime.now());
...@@ -240,6 +241,7 @@ public class ExtractServiceImpl implements ExtractService { ...@@ -240,6 +241,7 @@ public class ExtractServiceImpl implements ExtractService {
appointment.setEngineerPhone(phone); appointment.setEngineerPhone(phone);
appointment.setEngineerAge(age); appointment.setEngineerAge(age);
appointment.setIsWorkshop(0); appointment.setIsWorkshop(0);
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("PRE");
......
package com.dituhui.pea.order.common;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.format.TextStyle;
import java.util.Locale;
public class DateUtil {
public static String toWeekChinese(String date) {
LocalDate d = LocalDate.parse(date);
return DateUtil.toWeekChinese(d.getDayOfWeek().getValue());
}
public static String toWeekChinese(int dayOfWeek) {
// TextStyle: SHORT 周一;LONG 星期一;NARROW 一
return DayOfWeek.of(dayOfWeek).getDisplayName(TextStyle.SHORT, Locale.CHINESE);
}
}
package com.dituhui.pea.order.common;
import com.dituhui.pea.order.dao.EngineerInfoDao;
import com.dituhui.pea.order.dao.OrgGroupDao;
import com.dituhui.pea.order.dao.OrgTeamEngineerDao;
import com.dituhui.pea.order.entity.EngineerInfoEntity;
import com.dituhui.pea.order.entity.OrgGroupEntity;
import com.dituhui.pea.order.entity.OrgTeamEngineerEntity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Component;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
@Component
public class EngineerUtil {
@Autowired
private OrgTeamEngineerDao orgTeamEngineerDao;
@Autowired
private EngineerInfoDao engineerInfoDao;
@Autowired
private OrgGroupDao orgGroupDao;
public List<EngineerInfoEntity> getEngineersByLevel(String levelType, String levelValue) {
List<EngineerInfoEntity> engineers = null;
List<String> groupIds = null;
switch (levelType) {
case "team":
List<String> engineerCodes = orgTeamEngineerDao.findAllByTeamId(levelValue).stream()
.map(OrgTeamEngineerEntity::getEngineerCode).collect(Collectors.toList());
engineers = engineerInfoDao.findByEngineerCodeIn(engineerCodes);
break;
case "group":
engineers = engineerInfoDao.findByGroupId(levelValue);
break;
case "branch":
groupIds = orgGroupDao.findAllByBranchId(levelValue).stream()
.map(OrgGroupEntity::getGroupId).collect(Collectors.toList());
engineers = engineerInfoDao.findByGroupIdIn(groupIds);
break;
default:
// "cluster".equals(levelType)
groupIds = orgGroupDao.findAllByClusterId(levelValue).stream()
.map(OrgGroupEntity::getGroupId).collect(Collectors.toList());
engineers = engineerInfoDao.findByGroupIdIn(groupIds);
break;
}
return engineers;
}
public Page<EngineerInfoEntity> filterEngineersByKeyAndPage(List<String> engineerCodes, String key, Integer page, Integer size) {
Pageable pageable = PageRequest.of(page - 1, size);
return engineerInfoDao.findAllByEngineerCodeIn(engineerCodes, buildSpecification(key), pageable);
}
public List<EngineerInfoEntity> filterEngineersByKey(List<String> engineerCodes, String key) {
return engineerInfoDao.findAllByEngineerCodeIn(engineerCodes, buildSpecification(key));
}
private Specification<EngineerInfoEntity> buildSpecification(String keyword) {
return new Specification<EngineerInfoEntity>() {
@Override
public Predicate toPredicate(Root<EngineerInfoEntity> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
List<Predicate> predicates = new ArrayList<>();
// 构建查询条件
Predicate engineerCodePredicate = criteriaBuilder.like(root.get("engineerCode"), "%" + keyword + "%");
Predicate mobilePredicate = criteriaBuilder.like(root.get("phone"), "%" + keyword + "%");
Predicate msgContentPredicate = criteriaBuilder.like(root.get("name"), "%" + keyword + "%");
predicates.add(criteriaBuilder.or(engineerCodePredicate, mobilePredicate, msgContentPredicate));
return criteriaBuilder.and(predicates.toArray(new Predicate[0]));
}
};
}
}
...@@ -9,7 +9,9 @@ import com.dituhui.pea.order.entity.OrderAppointment; ...@@ -9,7 +9,9 @@ import com.dituhui.pea.order.entity.OrderAppointment;
import com.dituhui.pea.order.entity.OrderRequest; import com.dituhui.pea.order.entity.OrderRequest;
import com.dituhui.pea.order.entity.SkillInfo; import com.dituhui.pea.order.entity.SkillInfo;
import lombok.Data; import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.sql.Timestamp; import java.sql.Timestamp;
import java.time.LocalDate; import java.time.LocalDate;
...@@ -21,10 +23,9 @@ import java.util.List; ...@@ -21,10 +23,9 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@Component
@Slf4j
public class OrderAssignCheck { public class OrderAssignCheck {
private String orderId;
private String engineerCode;
@Autowired @Autowired
OrderRequestMPDao orderRequestMPDao; OrderRequestMPDao orderRequestMPDao;
...@@ -37,11 +38,6 @@ public class OrderAssignCheck { ...@@ -37,11 +38,6 @@ public class OrderAssignCheck {
@Autowired @Autowired
EngineerBusinessMPDao engineerBusinessMPDao; EngineerBusinessMPDao engineerBusinessMPDao;
public OrderAssignCheck(String orderId, String engineerCode) {
this.orderId = orderId;
this.engineerCode = engineerCode;
}
@Data @Data
public class Result { public class Result {
private Boolean canAssign; private Boolean canAssign;
...@@ -61,8 +57,10 @@ public class OrderAssignCheck { ...@@ -61,8 +57,10 @@ public class OrderAssignCheck {
} }
} }
public Result orderAssignCheck() { public Result orderAssignCheck(String orderId, String engineerCode) {
OrderRequest order = orderRequestMPDao.getByOrderId(this.orderId); log.info("begin orderAssignCheck:orderId={}, engineerCode={}", orderId, engineerCode);
OrderRequest order = orderRequestMPDao.getByOrderId(orderId);
double curX = Double.parseDouble(order.getX()); double curX = Double.parseDouble(order.getX());
double curY = Double.parseDouble(order.getY()); double curY = Double.parseDouble(order.getY());
...@@ -73,17 +71,21 @@ public class OrderAssignCheck { ...@@ -73,17 +71,21 @@ public class OrderAssignCheck {
// 获取客户期望时间段 // 获取客户期望时间段
int start = this.timestamp2Point(order.getExpectTimeBegin()); int start = this.timestamp2Point(order.getExpectTimeBegin());
int end = this.timestamp2Point(order.getExpectTimeEnd()); int end = this.timestamp2Point(order.getExpectTimeEnd());
log.info("客户期望的时间段:{}-{}, 技能所需时长:{}, 坐标:{},{}", start, end, takeTime, curX, curY);
// 获取技术员的已分配订单的时间段, 根据时间段排序 // 获取技术员的已分配订单的时间段, 根据时间段排序
List<OrderSegment> orderSegments = getEngineerOrderSegments(engineerCode, order.getDt()); List<OrderSegment> orderSegments = getEngineerOrderSegments(engineerCode, order.getDt());
// 转化为SegmentInsertion需要的时间段 // 转化为SegmentInsertion需要的时间段
List<SegmentInsertion.Segment> segments = this.orderSegment2Segment(orderSegments); List<SegmentInsertion.Segment> segments = this.orderSegment2Segment(orderSegments);
log.info("技术员已分配时间段列表:{}", segments);
int index = SegmentInsertion.insertSegment(takeTime, start, end, segments); int index = SegmentInsertion.insertSegment(takeTime, start, end, segments);
if (index == -1) { if (index == -1) {
log.info("没有可连续插入的空间");
return new Result(false, "没有连续可插入空间(没计算时间)", 0, 0, null, null); return new Result(false, "没有连续可插入空间(没计算时间)", 0, 0, null, null);
} }
log.info("插入位置为第{}单", index);
// 计算距离 & 时间 // 计算距离 & 时间
if(index == 0) { if(index == 0) {
// 第一订单为出发地 // 第一订单为出发地
...@@ -97,12 +99,12 @@ public class OrderAssignCheck { ...@@ -97,12 +99,12 @@ public class OrderAssignCheck {
OrderSegment pre = orderSegments.get(index); OrderSegment pre = orderSegments.get(index);
// 为当前订单 // 为当前订单
OrderSegment post = new OrderSegment(start, end, Double.parseDouble(order.getX()), Double.parseDouble(order.getY())); OrderSegment post = new OrderSegment(start, end, Double.parseDouble(order.getX()), Double.parseDouble(order.getY()));
return this.getResult(curX, curY, pre, post, takeTime, order.getDt());
} else { } else {
OrderSegment pre = orderSegments.get(index); OrderSegment pre = orderSegments.get(index);
OrderSegment post = orderSegments.get(index+1); OrderSegment post = orderSegments.get(index+1);
return this.getResult(curX, curY, pre, post, takeTime, order.getDt()); return this.getResult(curX, curY, pre, post, takeTime, order.getDt());
} }
return null;
} }
private List<OrderSegment> getEngineerOrderSegments(String engineerCode, LocalDate dt) { private List<OrderSegment> getEngineerOrderSegments(String engineerCode, LocalDate dt) {
...@@ -117,6 +119,10 @@ public class OrderAssignCheck { ...@@ -117,6 +119,10 @@ public class OrderAssignCheck {
} }
orderIds.add(o.getOrderId()); orderIds.add(o.getOrderId());
} }
if(orderIds.isEmpty()){
return orderSegments;
}
Map<String, List<OrderAppointment>> m = appointments.stream().collect(Collectors.groupingBy(OrderAppointment::getOrderId)); Map<String, List<OrderAppointment>> m = appointments.stream().collect(Collectors.groupingBy(OrderAppointment::getOrderId));
List<OrderRequest> orderRequests = orderRequestMPDao.selectByOrderIds(orderIds); List<OrderRequest> orderRequests = orderRequestMPDao.selectByOrderIds(orderIds);
for(OrderRequest o: orderRequests) { for(OrderRequest o: orderRequests) {
......
...@@ -43,6 +43,10 @@ public class TimeUtils { ...@@ -43,6 +43,10 @@ public class TimeUtils {
return LocalDate.parse(s, DateTimeFormatter.ofPattern(pattern)); return LocalDate.parse(s, DateTimeFormatter.ofPattern(pattern));
} }
public static final String IsoLocalDate2String(LocalDate localDate) {
return localDate.format(DateTimeFormatter.ofPattern(DATE_GAP_FORMAT));
}
public static final LocalDate addDays(LocalDate date, long days) { public static final LocalDate addDays(LocalDate date, long days) {
return date.plusDays(days); return date.plusDays(days);
} }
......
...@@ -3,8 +3,11 @@ package com.dituhui.pea.order.controller; ...@@ -3,8 +3,11 @@ package com.dituhui.pea.order.controller;
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.EngineerBusinessUpdateReqDTO; import com.dituhui.pea.order.dto.EngineerBusinessUpdateReqDTO;
import com.dituhui.pea.order.dto.EngineerCalendarDTO;
import com.dituhui.pea.order.dto.EngineerSkillUpdateReqDTO; import com.dituhui.pea.order.dto.EngineerSkillUpdateReqDTO;
import com.dituhui.pea.order.dto.EngineersGanttReqDTO; import com.dituhui.pea.order.dto.EngineersGanttDTO;
import com.dituhui.pea.order.service.EngineerCalendarService;
import com.dituhui.pea.order.service.EngineerGanttService;
import com.dituhui.pea.order.service.EngineerService; import com.dituhui.pea.order.service.EngineerService;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
...@@ -19,6 +22,12 @@ public class EngineerController { ...@@ -19,6 +22,12 @@ public class EngineerController {
@Autowired @Autowired
private EngineerService engineerService; private EngineerService engineerService;
@Autowired
private EngineerGanttService engineerGanttService;
@Autowired
private EngineerCalendarService engineerCalendarService;
@GetMapping("/engineer/info/list") @GetMapping("/engineer/info/list")
public Result<?> getEngineerInfoList(@RequestParam String levelType, public Result<?> getEngineerInfoList(@RequestParam String levelType,
@RequestParam String levelValue, @RequestParam String levelValue,
...@@ -131,12 +140,23 @@ public class EngineerController { ...@@ -131,12 +140,23 @@ public class EngineerController {
return res; return res;
} }
@PostMapping(value = "/engineer/schedule/gantt") @PostMapping("/engineer/schedule/gantt")
public Result<?> getEngineersGanttList(@Validated @RequestBody EngineersGanttReqDTO reqDTO) { public Result<?> getEngineersGanttList(@Validated @RequestBody EngineersGanttDTO.Request reqDTO) {
log.info("getEngineersGanttList: {}", reqDTO); log.info("getEngineersGanttList: {}", reqDTO);
Result<?> res = null; Result<?> res = null;
try { try {
res = engineerService.getEngineersGanttList(reqDTO); res = engineerGanttService.getEngineersGanttList(reqDTO);
} catch (BusinessException e) {
return Result.failed(e.getMessage());
}
return res;
}
@GetMapping("/engineer/calendar")
public Result<?> getEngineerCalendar(@Validated EngineerCalendarDTO.Request reqDTO) {
Result<?> res = null;
try {
res = engineerCalendarService.getEngineersCalendar(reqDTO);
} catch (BusinessException e) { } catch (BusinessException e) {
return Result.failed(e.getMessage()); return Result.failed(e.getMessage());
} }
......
...@@ -3,6 +3,7 @@ package com.dituhui.pea.order.controller; ...@@ -3,6 +3,7 @@ package com.dituhui.pea.order.controller;
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.OrderAssignReq; import com.dituhui.pea.order.dto.OrderAssignReq;
import com.dituhui.pea.order.dto.OrderRevokeAssign;
import com.dituhui.pea.order.service.OrderAssign; import com.dituhui.pea.order.service.OrderAssign;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
...@@ -40,4 +41,16 @@ public class OrderAssignController { ...@@ -40,4 +41,16 @@ public class OrderAssignController {
} }
return res; return res;
} }
@PostMapping("/order/revoke/assign")
public Result<?> orderRevokeAssign(@RequestBody OrderRevokeAssign req){
// 放回工单池
Result<?> res = null;
try{
res = orderAssign.orderRevokeAssign(req.getOrderId());
} catch (BusinessException e){
return Result.failed(e.getMessage());
}
return res;
}
} }
package com.dituhui.pea.order.dao;
import com.dituhui.pea.order.entity.CapacityEngineerCalendarEntity;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import java.util.List;
public interface CapacityEngineerCalendarDao extends JpaRepository<CapacityEngineerCalendarEntity, Long> {
@Query("select a from CapacityEngineerCalendarEntity a where a.engineerCode=:engineerCode and a.workday between :beginDate and :endDate")
List<CapacityEngineerCalendarEntity> findCalendarByEngineerCodeAndDateBetween(String engineerCode, String beginDate, String endDate);
}
...@@ -2,13 +2,17 @@ package com.dituhui.pea.order.dao; ...@@ -2,13 +2,17 @@ package com.dituhui.pea.order.dao;
import com.dituhui.pea.order.entity.EngineerInfoEntity; import com.dituhui.pea.order.entity.EngineerInfoEntity;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.stereotype.Repository; import org.springframework.stereotype.Repository;
import java.util.List; import java.util.List;
@Repository @Repository
public interface EngineerInfoDao extends JpaRepository<EngineerInfoEntity, Integer> { public interface EngineerInfoDao extends JpaRepository<EngineerInfoEntity, Integer>, JpaSpecificationExecutor<EngineerInfoEntity> {
EngineerInfoEntity getByEngineerCode(String engineerCode); EngineerInfoEntity getByEngineerCode(String engineerCode);
List<EngineerInfoEntity> findByGroupId(String groupId); List<EngineerInfoEntity> findByGroupId(String groupId);
...@@ -16,4 +20,18 @@ public interface EngineerInfoDao extends JpaRepository<EngineerInfoEntity, Integ ...@@ -16,4 +20,18 @@ public interface EngineerInfoDao extends JpaRepository<EngineerInfoEntity, Integ
List<EngineerInfoEntity> findByGroupIdIn(List<String> groupIds); List<EngineerInfoEntity> findByGroupIdIn(List<String> groupIds);
List<EngineerInfoEntity> findByEngineerCodeIn(List<String> engineerCodes); List<EngineerInfoEntity> findByEngineerCodeIn(List<String> engineerCodes);
default List<EngineerInfoEntity> findAllByEngineerCodeIn(List<String> engineerCodes, Specification<EngineerInfoEntity> engineerInfoEntitySpecification) {
Specification<EngineerInfoEntity> spec = Specification.where(engineerCodeIn(engineerCodes)).and(engineerInfoEntitySpecification);
return findAll(spec);
}
default Page<EngineerInfoEntity> findAllByEngineerCodeIn(List<String> engineerCodes, Specification<EngineerInfoEntity> engineerInfoEntitySpecification, Pageable pageable) {
Specification<EngineerInfoEntity> spec = Specification.where(engineerCodeIn(engineerCodes)).and(engineerInfoEntitySpecification);
return findAll(spec, pageable);
}
static Specification<EngineerInfoEntity> engineerCodeIn(List<String> engineerCodes) {
return (root, query, criteriaBuilder) -> root.get("engineerCode").in(engineerCodes);
}
} }
...@@ -17,6 +17,12 @@ public interface OrderAppointmentMPDao extends BaseMapper<OrderAppointment> { ...@@ -17,6 +17,12 @@ public interface OrderAppointmentMPDao extends BaseMapper<OrderAppointment> {
@Select("select * from order_appointment where order_id=#{orderId}") @Select("select * from order_appointment where order_id=#{orderId}")
List<OrderAppointment> selectByOrderId(String orderId); List<OrderAppointment> selectByOrderId(String orderId);
@Select("select * from order_appointment where order_id=#{orderId} and dt=#{dt}")
OrderAppointment getByOrderIdAndDt(String orderId, LocalDate dt);
@Select("select * from order_appointment where order_id=#{orderId} and dt=#{dt}")
List<OrderAppointment> selectByOrderIdAndDt(String orderId, LocalDate dt);
@Select("select * from order_appointment where engineer_code=#{engineerCode} and dt=#{dt}") @Select("select * from order_appointment where engineer_code=#{engineerCode} and dt=#{dt}")
List<OrderAppointment> selectByEngineerCodeAndDt(String engineerCode, LocalDate dt); List<OrderAppointment> selectByEngineerCodeAndDt(String engineerCode, LocalDate dt);
} }
package com.dituhui.pea.order.dao; package com.dituhui.pea.order.dao;
import com.dituhui.pea.order.entity.OrgTeamEntity; import com.dituhui.pea.order.entity.OrgTeamEntity;
import org.hibernate.annotations.Where;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
...@@ -12,14 +13,20 @@ import java.util.List; ...@@ -12,14 +13,20 @@ import java.util.List;
@Repository @Repository
public interface OrgTeamDao extends JpaRepository<OrgTeamEntity, Integer> { public interface OrgTeamDao extends JpaRepository<OrgTeamEntity, Integer> {
@Query("select t from OrgTeamEntity t where t.clusterId = :clusterId and t.status=1")
List<OrgTeamEntity> findAllByClusterId(String clusterId); List<OrgTeamEntity> findAllByClusterId(String clusterId);
@Query("select t from OrgTeamEntity t where t.branchId = :branchId and t.status=1")
List<OrgTeamEntity> findAllByBranchId(String branchId); List<OrgTeamEntity> findAllByBranchId(String branchId);
@Query("select t from OrgTeamEntity t where t.groupId = :groupId and t.status=1")
List<OrgTeamEntity> findAllByGroupId(String groupId); List<OrgTeamEntity> findAllByGroupId(String groupId);
@Query("select t from OrgTeamEntity t where t.groupId = :groupId and t.status=1")
Page<OrgTeamEntity> findAllByGroupId(String groupId, Pageable pageable); Page<OrgTeamEntity> findAllByGroupId(String groupId, Pageable pageable);
@Query("select t from OrgTeamEntity t where t.branchId = :branchId and t.status=1")
Page<OrgTeamEntity> findAllByBranchId(String branchId, Pageable pageable); Page<OrgTeamEntity> findAllByBranchId(String branchId, Pageable pageable);
OrgTeamEntity getByTeamId(String teamId); OrgTeamEntity getByTeamId(String teamId);
......
...@@ -12,14 +12,16 @@ import java.util.List; ...@@ -12,14 +12,16 @@ import java.util.List;
@Repository @Repository
@Where(clause = "status = 1")
public interface OrgTeamEngineerDao extends JpaRepository<OrgTeamEngineerEntity, Integer> { public interface OrgTeamEngineerDao extends JpaRepository<OrgTeamEngineerEntity, Integer> {
@Query("select t from OrgTeamEngineerEntity t where t.teamId = :teamId and t.status=1")
List<OrgTeamEngineerEntity> findAllByTeamId(String teamId); List<OrgTeamEngineerEntity> findAllByTeamId(String teamId);
@Query("select t from OrgTeamEngineerEntity t where t.teamId in :teamIds and t.status=1")
List<OrgTeamEngineerEntity> findAllByTeamIdIn(List<String> teamIds); List<OrgTeamEngineerEntity> findAllByTeamIdIn(List<String> teamIds);
List<OrgTeamEngineerEntity> findByTeamId(String teamId); @Query("select a.teamId from OrgTeamEngineerEntity a where a.engineerCode=:engineerCode")
List<String> getTeamIdsByEngineerCode(String engineerCode);
@Modifying @Modifying
@Query("UPDATE OrgTeamEngineerEntity tt SET tt.status = :status WHERE tt.teamId = :teamId") @Query("UPDATE OrgTeamEngineerEntity tt SET tt.status = :status WHERE tt.teamId = :teamId")
......
...@@ -19,6 +19,8 @@ public class BusinessTeamDetailDTO { ...@@ -19,6 +19,8 @@ public class BusinessTeamDetailDTO {
private ScheduleConfig scheduleConfig; private ScheduleConfig scheduleConfig;
private String teamId; private String teamId;
private String teamName; private String teamName;
private String groupId;
private String groupName;
private String warehouseId; private String warehouseId;
private List<String> workdays; private List<String> workdays;
} }
...@@ -45,7 +47,7 @@ public class BusinessTeamDetailDTO { ...@@ -45,7 +47,7 @@ public class BusinessTeamDetailDTO {
/** /**
* 网点指派策略 * 网点指派策略
*/ */
private String assiginStrategy; private String assignStrategy;
/** /**
* cutoff时间 * cutoff时间
*/ */
......
...@@ -2,6 +2,8 @@ package com.dituhui.pea.order.dto; ...@@ -2,6 +2,8 @@ package com.dituhui.pea.order.dto;
import java.util.List; import java.util.List;
import static com.dituhui.pea.order.config.OrderConfig.DEFAULT_PAGE_SIZE;
public class EngineerCalendarDTO { public class EngineerCalendarDTO {
@lombok.Data @lombok.Data
...@@ -13,11 +15,17 @@ public class EngineerCalendarDTO { ...@@ -13,11 +15,17 @@ public class EngineerCalendarDTO {
private String key; private String key;
private String levelType; private String levelType;
private String levelValue; private String levelValue;
private Integer size = DEFAULT_PAGE_SIZE;
private Integer page = 1;
} }
@lombok.Data @lombok.Data
public static class Result { public static class Result {
private long pageCurrent;
private long pages;
private long pageSize;
private long total;
private List<Engineer> engineers; private List<Engineer> engineers;
} }
......
package com.dituhui.pea.order.dto; package com.dituhui.pea.order.dto;
import com.dituhui.pea.order.config.OrderConfig;
import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
...@@ -11,12 +13,31 @@ import lombok.experimental.Accessors; ...@@ -11,12 +13,31 @@ import lombok.experimental.Accessors;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.List; import java.util.List;
@lombok.Data
@Accessors(chain = true)
public class EngineersGanttRespDTO {
public class EngineersGanttDTO {
@lombok.Data
public static class Request {
// 2种模式:前端可以直接传入精确的engineerCodes,
// 或者是levelType/levelValue/brandIds/branchIds/groupIds/teamIds/key,后端查询匹配
private String levelType;
private String levelValue;
private Integer page = OrderConfig.DEFAULT_PAGE_INDEX;
private Integer size = OrderConfig.DEFAULT_PAGE_SIZE;
private String date;
private List<String> engineerCodes;
private List<String> branchIds;
private List<String> groupIds;
private List<String> teamIds;
private String key;
}
@lombok.Data
@Accessors(chain = true)
public static class Result {
private String date; private String date;
private List<?> engineers; private List<?> engineers;
}
/** /**
* GanttChart * GanttChart
......
package com.dituhui.pea.order.dto;
import com.dituhui.pea.order.config.OrderConfig;
import java.util.List;
@lombok.Data
public class EngineersGanttReqDTO {
private String levelType;
private String levelValue;
private Integer page = OrderConfig.DEFAULT_PAGE_INDEX;
private Integer size = OrderConfig.DEFAULT_PAGE_SIZE;
private String date;
private List<String> engineerCodes;
}
package com.dituhui.pea.order.dto;
import lombok.Data;
@Data
public class OrderRevokeAssign {
private String orderId;
}
package com.dituhui.pea.order.dto; package com.dituhui.pea.order.dto;
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.Data; import lombok.Data;
import javax.validation.constraints.NotNull;
import java.util.List; import java.util.List;
@Data @Data
...@@ -13,5 +15,17 @@ public class OrderServiceDetailResp { ...@@ -13,5 +15,17 @@ public class OrderServiceDetailResp {
private String risk; private String risk;
private String riskDesc; private String riskDesc;
private String location; private String location;
private OrderDetail reschedulingParams;
private List<KV> items; private List<KV> items;
@Data
@JsonInclude(JsonInclude.Include.NON_NULL)
public static class OrderDetail{
private String location;
private String address;
private String brand;
private String date;
private String type;
private String skill;
}
} }
...@@ -30,6 +30,6 @@ public class OrderServiceListReq { ...@@ -30,6 +30,6 @@ public class OrderServiceListReq {
private List<String> serviceCategory; private List<String> serviceCategory;
private String phone; private String phone;
private String orderId; private String orderId;
private String appointmentStatus; private List<String> appointmentStatus;
private String appointmentType; private List<String> appointmentType;
} }
\ No newline at end of file
package com.dituhui.pea.order.entity;
import lombok.Data;
import javax.persistence.*;
import java.sql.Timestamp;
import java.time.LocalDateTime;
@Entity
@Table(name = "capacity_engineer_calendar")
@Data
public class CapacityEngineerCalendarEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column(nullable = false)
private String workday;
@Column(name = "engineer_code", nullable = false, columnDefinition = "varchar(50) default '0'")
private String engineerCode;
@Column(name = "start_time", nullable = false)
private LocalDateTime startTime;
@Column(name = "end_time", nullable = false)
private LocalDateTime endTime;
@Column(nullable = false)
private String type;
@Column(nullable = false)
private String memo;
@Column(name = "create_time", nullable = false, updatable = false, columnDefinition = "timestamp default current_timestamp")
private Timestamp createTime;
@Column(name = "update_time", nullable = false, columnDefinition = "timestamp default current_timestamp on update current_timestamp")
private Timestamp updateTime;
// 其他字段和关联关系的定义
// ...
}
package com.dituhui.pea.order.service;
import com.dituhui.pea.common.Result;
import com.dituhui.pea.order.dto.EngineerCalendarDTO;
public interface EngineerCalendarService {
Result<?> getEngineersCalendar(EngineerCalendarDTO.Request engineerCalendarReq);
}
package com.dituhui.pea.order.service;
import com.dituhui.pea.common.Result;
import com.dituhui.pea.order.dto.EngineersGanttDTO;
public interface EngineerGanttService {
Result<?> getEngineersGanttList(EngineersGanttDTO.Request ganttReqDTO);
}
package com.dituhui.pea.order.service; package com.dituhui.pea.order.service;
import com.dituhui.pea.common.Result; import com.dituhui.pea.common.Result;
import com.dituhui.pea.order.dto.EngineersGanttReqDTO;
import java.util.List; import java.util.List;
...@@ -22,6 +21,4 @@ public interface EngineerService { ...@@ -22,6 +21,4 @@ public interface EngineerService {
// 技术员业务属性配置修改 // 技术员业务属性配置修改
Result<?> engineerBusinessUpdate(String engineerCode, Integer maxNum, Integer maxMutine, String departure, String priority); Result<?> engineerBusinessUpdate(String engineerCode, Integer maxNum, Integer maxMutine, String departure, String priority);
Result<?> getEngineersGanttList(EngineersGanttReqDTO ganttReqDTO);
} }
...@@ -9,4 +9,6 @@ public interface OrderAssign { ...@@ -9,4 +9,6 @@ public interface OrderAssign {
// 服务单指派-指派提交 // 服务单指派-指派提交
Result<?> orderAssign(String orderId, String engineerCode); Result<?> orderAssign(String orderId, String engineerCode);
Result<?> orderRevokeAssign(String orderId);
} }
package com.dituhui.pea.order.service; package com.dituhui.pea.order.service;
import com.dituhui.pea.common.Result; import com.dituhui.pea.common.Result;
import com.dituhui.pea.order.dto.EngineersGanttReqDTO;
import com.dituhui.pea.order.dto.OrderChangeListDTO; import com.dituhui.pea.order.dto.OrderChangeListDTO;
import java.time.LocalDate; import java.time.LocalDate;
......
package com.dituhui.pea.order.service.impl; package com.dituhui.pea.order.service.impl;
import cn.hutool.core.date.Week;
import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.IdUtil;
import com.dituhui.pea.common.Result; import com.dituhui.pea.common.Result;
import com.dituhui.pea.order.common.DateUtil;
import com.dituhui.pea.order.dao.*; import com.dituhui.pea.order.dao.*;
import com.dituhui.pea.order.dto.*; import com.dituhui.pea.order.dto.*;
import com.dituhui.pea.order.entity.OrgGroupEntity; import com.dituhui.pea.order.entity.OrgGroupEntity;
...@@ -89,7 +89,7 @@ public class BusinessTeamServiceImpl implements BusinessTeamService { ...@@ -89,7 +89,7 @@ public class BusinessTeamServiceImpl implements BusinessTeamService {
List<String> days = Arrays.asList(workDays.split(",")); List<String> days = Arrays.asList(workDays.split(","));
Collections.sort(days); Collections.sort(days);
return days.stream().map(e -> { return days.stream().map(e -> {
return Week.of(Integer.valueOf(e)).toChinese("周"); return DateUtil.toWeekChinese(Integer.parseInt(e));
}).collect(Collectors.toList()); }).collect(Collectors.toList());
} }
...@@ -185,7 +185,7 @@ public class BusinessTeamServiceImpl implements BusinessTeamService { ...@@ -185,7 +185,7 @@ public class BusinessTeamServiceImpl implements BusinessTeamService {
public void updateTeamEngineers(String teamId, List<String> engineerCodes) { public void updateTeamEngineers(String teamId, List<String> engineerCodes) {
// 获取现有的工作队和技术员之间的所有关系 // 获取现有的工作队和技术员之间的所有关系
List<OrgTeamEngineerEntity> existingRelations = orgTeamEngineerDao.findByTeamId(teamId); List<OrgTeamEngineerEntity> existingRelations = orgTeamEngineerDao.findAllByTeamId(teamId);
// 构建新的关系映射 // 构建新的关系映射
Map<String, OrgTeamEngineerEntity> newRelationsMap = new HashMap<>(); Map<String, OrgTeamEngineerEntity> newRelationsMap = new HashMap<>();
...@@ -204,9 +204,11 @@ public class BusinessTeamServiceImpl implements BusinessTeamService { ...@@ -204,9 +204,11 @@ public class BusinessTeamServiceImpl implements BusinessTeamService {
String engineerCode = relation.getEngineerCode(); String engineerCode = relation.getEngineerCode();
if (newRelationsMap.containsKey(engineerCode)) { if (newRelationsMap.containsKey(engineerCode)) {
OrgTeamEngineerEntity newRelation = newRelationsMap.get(engineerCode); OrgTeamEngineerEntity newRelation = newRelationsMap.get(engineerCode);
newRelation.setId(relation.getId());
newRelation.setUpdateTime(LocalDateTime.now()); newRelation.setUpdateTime(LocalDateTime.now());
newRelationsMap.put(engineerCode, newRelation); newRelationsMap.put(engineerCode, newRelation);
} else { } else {
// 新的关系不再,设置为0(删除)
relation.setStatus(0); relation.setStatus(0);
orgTeamEngineerDao.save(relation); orgTeamEngineerDao.save(relation);
} }
...@@ -227,8 +229,14 @@ public class BusinessTeamServiceImpl implements BusinessTeamService { ...@@ -227,8 +229,14 @@ public class BusinessTeamServiceImpl implements BusinessTeamService {
Result.failed(String.format("工作队[%s]不存在", req.getTeamId())); Result.failed(String.format("工作队[%s]不存在", req.getTeamId()));
} }
BusinessTeamDetailDTO.Result rs = new BusinessTeamDetailDTO.Result(); BusinessTeamDetailDTO.Result rs = new BusinessTeamDetailDTO.Result();
OrgGroupEntity g = orgGroupDao.getByGroupId(teamEntity.getGroupId());
if (g == null) {
return Result.failed("数据配置错误,工作队没有对应的站点");
}
rs.setTeamId(teamEntity.getTeamId()) rs.setTeamId(teamEntity.getTeamId())
.setTeamName(teamEntity.getTeamName()) .setTeamName(teamEntity.getTeamName())
.setGroupId(g.getGroupId())
.setGroupName(g.getGroupName())
.setWarehouseId(teamEntity.getWarehouseId()) .setWarehouseId(teamEntity.getWarehouseId())
.setWorkdays(Arrays.asList(teamEntity.getWorkdays().split(","))); .setWorkdays(Arrays.asList(teamEntity.getWorkdays().split(",")));
List<String> engineerCodes = orgTeamEngineerDao.findAllByTeamId(teamEntity.getTeamId()).stream() List<String> engineerCodes = orgTeamEngineerDao.findAllByTeamId(teamEntity.getTeamId()).stream()
...@@ -238,7 +246,7 @@ public class BusinessTeamServiceImpl implements BusinessTeamService { ...@@ -238,7 +246,7 @@ public class BusinessTeamServiceImpl implements BusinessTeamService {
}).collect(Collectors.toList()); }).collect(Collectors.toList());
rs.setEngineers(engineers); rs.setEngineers(engineers);
BusinessTeamDetailDTO.ScheduleConfig config = new BusinessTeamDetailDTO.ScheduleConfig(); BusinessTeamDetailDTO.ScheduleConfig config = new BusinessTeamDetailDTO.ScheduleConfig();
config.setAssiginStrategy(teamEntity.getStrategyAppointment()) config.setAssignStrategy(teamEntity.getStrategyAppointment())
.setCutoffTime(teamEntity.getCuteOff()) .setCutoffTime(teamEntity.getCuteOff())
.setTransportMode(teamEntity.getTransportMode()) .setTransportMode(teamEntity.getTransportMode())
.setScheduleStrategy(teamEntity.getStrategySchedule()) .setScheduleStrategy(teamEntity.getStrategySchedule())
......
package com.dituhui.pea.order.service.impl; package com.dituhui.pea.order.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
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.common.TimeUtils; import com.dituhui.pea.order.common.TimeUtils;
...@@ -8,8 +10,6 @@ import com.dituhui.pea.order.dto.DispatchEngineerOrderListResp; ...@@ -8,8 +10,6 @@ import com.dituhui.pea.order.dto.DispatchEngineerOrderListResp;
import com.dituhui.pea.order.dto.DispatchOrderListResp; import com.dituhui.pea.order.dto.DispatchOrderListResp;
import com.dituhui.pea.order.entity.*; import com.dituhui.pea.order.entity.*;
import com.dituhui.pea.order.service.DispatchService; import com.dituhui.pea.order.service.DispatchService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
...@@ -94,7 +94,7 @@ public class DispatchServiceImpl implements DispatchService { ...@@ -94,7 +94,7 @@ public class DispatchServiceImpl implements DispatchService {
@Transactional @Transactional
@Override @Override
public Result<?> getDispatchEngineerOrderList(String levelType, List<String> levelIds, String date) throws BusinessException{ public Result<?> getDispatchEngineerOrderList(String levelType, List<String> levelIds, String date) throws BusinessException {
// 派工台技术员预约单列表 // 派工台技术员预约单列表
// 获取技能耗时 // 获取技能耗时
...@@ -102,13 +102,13 @@ public class DispatchServiceImpl implements DispatchService { ...@@ -102,13 +102,13 @@ public class DispatchServiceImpl implements DispatchService {
// 获取groupIds // 获取groupIds
List<String> groupIds = this.queryOrgGroupIds(levelType, levelIds); List<String> groupIds = this.queryOrgGroupIds(levelType, levelIds);
if (groupIds.isEmpty()){ if (groupIds.isEmpty()) {
throw new BusinessException("大区/分部/小组组织结构配置可能错误或缺失,请联系管理员/研发"); throw new BusinessException("大区/分部/小组组织结构配置可能错误或缺失,请联系管理员/研发");
} }
// 获取engineer列表 // 获取engineer列表
List<EngineerInfo> engineers = this.queryEngineers(groupIds); List<EngineerInfo> engineers = this.queryEngineers(groupIds);
if(engineers.isEmpty()) { if (engineers.isEmpty()) {
// 该group下没有技术员,返回空 // 该group下没有技术员,返回空
DispatchEngineerOrderListResp res = new DispatchEngineerOrderListResp(); DispatchEngineerOrderListResp res = new DispatchEngineerOrderListResp();
List<DispatchEngineerOrderListResp.EngineerInfo> egs = new ArrayList<>(); List<DispatchEngineerOrderListResp.EngineerInfo> egs = new ArrayList<>();
......
package com.dituhui.pea.order.service.impl;
import cn.hutool.core.date.LocalDateTimeUtil;
import com.dituhui.pea.common.Result;
import com.dituhui.pea.order.common.DateUtil;
import com.dituhui.pea.order.common.EngineerUtil;
import com.dituhui.pea.order.dao.CapacityEngineerCalendarDao;
import com.dituhui.pea.order.dao.OrgTeamDao;
import com.dituhui.pea.order.dao.OrgTeamEngineerDao;
import com.dituhui.pea.order.dto.EngineerCalendarDTO;
import com.dituhui.pea.order.entity.CapacityEngineerCalendarEntity;
import com.dituhui.pea.order.entity.EngineerInfoEntity;
import com.dituhui.pea.order.entity.OrgTeamEntity;
import com.dituhui.pea.order.service.EngineerCalendarService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Service;
import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static com.dituhui.pea.order.config.OrderConfig.PATTERN_DATE;
import static com.dituhui.pea.order.config.OrderConfig.PATTERN_DATETIME;
@Slf4j
@Service
public class EngineerCalendarServiceImpl implements EngineerCalendarService {
@Autowired
private EngineerUtil engineerUtil;
@Autowired
private OrgTeamEngineerDao orgTeamEngineerDao;
@Autowired
private CapacityEngineerCalendarDao capacityEngineerCalendarDao;
@Autowired
private OrgTeamDao orgTeamDao;
@Override
public Result<?> getEngineersCalendar(EngineerCalendarDTO.Request req) {
// 技术员日历,查询 capacity_engineer_calendar表,如果当日有各种事项,进行显示;否则显示正常上班;
List<EngineerCalendarDTO.Engineer> engineers = new ArrayList<>();
List<String> allCodes = engineerUtil.getEngineersByLevel(req.getLevelType(), req.getLevelValue()).stream()
.map(EngineerInfoEntity::getEngineerCode).collect(Collectors.toList());
Page<EngineerInfoEntity> page = engineerUtil.filterEngineersByKeyAndPage(allCodes, req.getKey(), req.getPage(), req.getSize());
String edate = LocalDate.parse(req.getDate()).plusDays(14).toString();
for (EngineerInfoEntity e : page.getContent()) {
EngineerCalendarDTO.Engineer engineer = new EngineerCalendarDTO.Engineer();
engineer.setEngineerCode(e.getEngineerCode());
engineer.setName(e.getName());
engineer.setCalendar(getOneEngineerCalendars(e.getEngineerCode(), req.getDate(), edate));
engineers.add(engineer);
}
EngineerCalendarDTO.Result rs = new EngineerCalendarDTO.Result();
rs.setTotal(page.getTotalElements());
rs.setPages(page.getTotalPages());
rs.setPageSize(page.getSize());
rs.setPageCurrent(page.getNumber());
rs.setEngineers(engineers);
return Result.success(rs);
}
private List<EngineerCalendarDTO.Calendar> getOneEngineerCalendars(String engineerCode, String bdate, String edate) {
// 返回某一个技术员,日期范围内的日历列表
List<EngineerCalendarDTO.Calendar> calendars = new ArrayList<>();
List<String> teamIds = orgTeamEngineerDao.getTeamIdsByEngineerCode(engineerCode);
if (teamIds == null || teamIds.size() == 0) {
return new ArrayList<>();
}
LocalDate startDate = LocalDate.parse(bdate);
LocalDate endDate = LocalDate.parse(edate);
List<LocalDate> datesInRange = Stream.iterate(startDate, date -> date.plusDays(1))
.limit(ChronoUnit.DAYS.between(startDate, endDate.plusDays(1)))
.collect(Collectors.toList());
Map<String, List<CapacityEngineerCalendarEntity>> configs = capacityEngineerCalendarDao.findCalendarByEngineerCodeAndDateBetween(engineerCode, bdate, edate).stream()
.collect(Collectors.groupingBy(CapacityEngineerCalendarEntity::getWorkday));
for (LocalDate date : datesInRange) {
String sDate = LocalDateTimeUtil.format(date, PATTERN_DATE);
EngineerCalendarDTO.Calendar calander = null;
calander = getEmptyCalendar(teamIds.get(0), sDate);
if (configs.containsKey(sDate)) {
List<EngineerCalendarDTO.Content> contents = new ArrayList<>();
// 有配置
for (CapacityEngineerCalendarEntity e : configs.get(sDate)) {
EngineerCalendarDTO.Content content = new EngineerCalendarDTO.Content();
content.setType("leave");
content.setTitle(e.getType());
content.setValue(getCalendarDuration(e.getStartTime(), e.getEndTime()));
contents.add(content);
}
List<EngineerCalendarDTO.Content> mergedList = new ArrayList<>();
mergedList.addAll(calander.getContent());
mergedList.addAll(contents);
calander.setContent(mergedList);
}
calendars.add(calander);
}
return calendars;
}
private String getCalendarDuration(LocalDateTime btime, LocalDateTime etime) {
String b2 = LocalDateTimeUtil.format(btime, PATTERN_DATETIME);
String e2 = LocalDateTimeUtil.format(etime, PATTERN_DATETIME);
return getCalendarDuration(b2.substring(11), e2.substring(11));
}
private String getCalendarDuration(String btime, String etime) {
LocalTime t1 = LocalTime.parse(btime);
LocalTime t2 = LocalTime.parse(etime);
Duration duration = Duration.between(t1, t2);
long hours = duration.toHours();
long minutes = duration.toMinutesPart();
if (minutes > 0 && hours == 0) {
return String.format("%d分钟", minutes);
} else if (minutes == 0 && hours > 0) {
return String.format("%d小时", hours);
} else {
return String.format("%d小时%d分钟", hours, minutes);
}
}
private EngineerCalendarDTO.Calendar getEmptyCalendar(String teamId, String date) {
// 初始化一天的日历
OrgTeamEntity e = orgTeamDao.getByTeamId(teamId);
EngineerCalendarDTO.Calendar calendar = new EngineerCalendarDTO.Calendar();
calendar.setDate(date);
int dayOfWeek = LocalDate.parse(date).getDayOfWeek().getValue();
calendar.setWeek(DateUtil.toWeekChinese(dayOfWeek));
EngineerCalendarDTO.Content content = new EngineerCalendarDTO.Content();
List<String> workdays = Arrays.asList(e.getWorkdays().split(","));
if (workdays.contains(String.valueOf(dayOfWeek))) {
content.setType("woring");
content.setTitle(String.format("%s-%s", e.getWorkOn(), e.getWorkOff()));
content.setValue(getCalendarDuration(e.getWorkOn(), e.getWorkOff()));
} else {
content.setType("rest");
content.setTitle("休息");
}
calendar.setContent(Collections.singletonList(content));
return calendar;
}
}
package com.dituhui.pea.order.service.impl;
import com.dituhui.pea.common.Result;
import com.dituhui.pea.order.common.EngineerUtil;
import com.dituhui.pea.order.dao.CapacityEngineerStatDao;
import com.dituhui.pea.order.dao.EngineerInfoDao;
import com.dituhui.pea.order.dao.OrderAppointmentDao;
import com.dituhui.pea.order.dao.OrderRequestDao;
import com.dituhui.pea.order.dto.EngineersGanttDTO;
import com.dituhui.pea.order.dto.LabelValueDTO;
import com.dituhui.pea.order.entity.CapacityEngineerStatEntity;
import com.dituhui.pea.order.entity.EngineerInfoEntity;
import com.dituhui.pea.order.entity.OrderAppointmentEntity;
import com.dituhui.pea.order.entity.OrderRequestEntity;
import com.dituhui.pea.order.service.EngineerGanttService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.*;
import java.util.stream.Collectors;
@Slf4j
@Service
public class EngineerGanttServiceImpl implements EngineerGanttService {
@Autowired
private OrderAppointmentDao orderAppointmentDao;
@Autowired
private CapacityEngineerStatDao capacityEngineerStatDao;
@Autowired
private EngineerInfoDao engineerInfoDao;
@Autowired
private OrderRequestDao orderRequestDao;
@Autowired
private EngineerUtil engineerUtil;
@Override
public Result<?> getEngineersGanttList(EngineersGanttDTO.Request reqDTO) {
// 按日期返回技术员们当天的服务甘特图,不需要翻页
log.info("getEngineersGanttList: {}", reqDTO);
List<String> engineerCodes = reqDTO.getEngineerCodes();
if (engineerCodes == null || engineerCodes.size() == 0) {
// 需要根据levelType/levelValue/brandIds/branchIds/groupIds/teamIds/key,后端查询匹配
engineerCodes = findEngineers(reqDTO.getLevelType(), reqDTO.getLevelValue(), reqDTO.getBranchIds(), reqDTO.getGroupIds(), reqDTO.getTeamIds(), reqDTO.getKey());
log.info("根据多条件,查询返回符合条件的技术员列表:{}", engineerCodes);
}
List<OrderAppointmentEntity> orderAppointments = orderAppointmentDao.findByDateAndEngineerCodeIn(reqDTO.getDate(), engineerCodes);
List<String> orderIds = orderAppointments.stream().map(OrderAppointmentEntity::getOrderId).collect(Collectors.toList());
Map<String, OrderRequestEntity> mapOrderRequest = getOrdersByOrderIds(orderIds);
HashMap<String, List<EngineersGanttDTO.Order>> mapEngineers = new HashMap<>();
for (OrderAppointmentEntity e : orderAppointments) {
log.info("===== order_id: [{}]", e.getOrderId());
EngineersGanttDTO.Order order = new EngineersGanttDTO.Order();
// todo 需要根据订单时间和状态,采用expectXXXX或者actualXXXX
order.setStartTime(e.getExpectStartTime()).setEndTime(e.getExpectEndTime());
order.setOrderId(e.getOrderId()).setPreStatus(e.getPreStatus());
order.setTips(getOrderTips(e.getOrderId()));
order.setAppointmentStatus(mapOrderRequest.get(e.getOrderId()).getAppointmentStatus());
List<EngineersGanttDTO.Order> orders = null;
if (mapEngineers.containsKey(e.getEngineerCode())) {
orders = mapEngineers.get(e.getEngineerCode());
} else {
orders = new ArrayList<>();
}
orders.add(order);
mapEngineers.put(e.getEngineerCode(), orders);
}
List<EngineersGanttDTO.GanttChart> engineers = new ArrayList<>();
for (String engineerCode : engineerCodes) {
EngineerInfoEntity engineerInfo = engineerInfoDao.getByEngineerCode(engineerCode);
EngineersGanttDTO.GanttChart engineer = new EngineersGanttDTO.GanttChart();
engineer.setEngineerCode(engineerCode)
.setStartTime(String.format("%s 08:00", reqDTO.getDate()))
.setEndTime(String.format("%s 18:00", reqDTO.getDate()))
.setHoliday(false) // todo
.setEngineerName(engineerInfo.getName())
.setGrade(engineerInfo.getGrade());
CapacityEngineerStatEntity capacityEngineerStat = capacityEngineerStatDao.getByEngineerCodeAndWorkday(engineerCode, reqDTO.getDate());
if (capacityEngineerStat == null) {
log.warn("技术员当日的容量数据不存在,{}{}", engineerCode, reqDTO.getDate());
} else {
engineer.setCapTotal(capacityEngineerStat.getCapTotal().toString()).setCapUsed(capacityEngineerStat.getCapUsed().toString());
}
if (mapEngineers.containsKey(engineerCode)) {
engineer.setOrders(mapEngineers.get(engineerCode));
}
// engineer.setErrorTip(); todo
engineers.add(engineer);
}
EngineersGanttDTO.Result res = new EngineersGanttDTO.Result();
res.setDate(reqDTO.getDate()).setEngineers(engineers);
return Result.success(res);
}
private List<String> findEngineers(String levelType, String levelValue, List<String> branchIds, List<String> groupIds, List<String> teamIds, String key) {
// brandIds, groupIds, teamIds, 以team -> group -> branch 为顺序判断,前者优先;
List<String> engineerCodes = new ArrayList<>();
if (teamIds != null && teamIds.size() > 0) {
for (String teamId : teamIds) {
engineerCodes.addAll(
engineerUtil.getEngineersByLevel("team", teamId).stream().map(EngineerInfoEntity::getEngineerCode).collect(Collectors.toList()));
}
} else if (groupIds != null && groupIds.size() > 0) {
for (String groupId : groupIds) {
engineerCodes.addAll(
engineerUtil.getEngineersByLevel("group", groupId).stream().map(EngineerInfoEntity::getEngineerCode).collect(Collectors.toList()));
}
} else if (branchIds != null && branchIds.size() > 0) {
for (String branchId : branchIds) {
engineerCodes.addAll(
engineerUtil.getEngineersByLevel("branch", branchId).stream().map(EngineerInfoEntity::getEngineerCode).collect(Collectors.toList()));
}
} else {
engineerCodes.addAll(engineerUtil.getEngineersByLevel(levelType, levelValue).stream().map(EngineerInfoEntity::getEngineerCode).collect(Collectors.toList()));
}
engineerCodes = new ArrayList<>(new HashSet<>(engineerCodes));
if (StringUtils.isBlank(key)) {
return engineerCodes;
} else {
// 最后,还需要根据key进行过滤(需要结合数据库表)
return engineerUtil.filterEngineersByKey(engineerCodes, key).stream().map(EngineerInfoEntity::getEngineerCode).collect(Collectors.toList());
}
}
public Map<String, OrderRequestEntity> getOrdersByOrderIds(List<String> orderIds) {
List<OrderRequestEntity> orders = orderRequestDao.findAllByOrderIdIn(orderIds);
return orders.stream()
.collect(Collectors.toMap(OrderRequestEntity::getOrderId, order -> order));
}
private List<?> getOrderTips(String orderId) {
log.info("==> getOrderTips: orderId[{}]", orderId);
OrderRequestEntity order = orderRequestDao.getByOrderId(orderId);
if (order == null) {
log.error("对应的订单不存在!{}", orderId);
return null;
}
List<LabelValueDTO> tips = new ArrayList<>();
tips.add(new LabelValueDTO().setLabel("工单号码").setValue(orderId));
tips.add(new LabelValueDTO().setLabel("类型/品牌").setValue(String.format("%s %s", order.getBrand(), order.getType())));
tips.add(new LabelValueDTO().setLabel("电话/地址").setValue(String.format("%s %s\n %s", order.getName(), order.getPhone(), order.getAddress())));
if (StringUtils.isNotBlank(order.getApplyNote())) {
tips.add(new LabelValueDTO().setLabel("备注").setValue(order.getApplyNote()));
}
tips.add(new LabelValueDTO().setLabel("标签").setValue(order.getTags()));
return tips;
}
}
...@@ -477,81 +477,4 @@ public class EngineerServiceImpl implements EngineerService { ...@@ -477,81 +477,4 @@ public class EngineerServiceImpl implements EngineerService {
return (age <= 0) ? "" : Integer.toString(age); return (age <= 0) ? "" : Integer.toString(age);
} }
@Override
public Result<?> getEngineersGanttList(EngineersGanttReqDTO reqDTO) {
// 按日期返回技术员们当天的服务甘特图,不需要翻页
log.info("getEngineersGanttList: {}", reqDTO);
List<OrderAppointmentEntity> orderAppointments = orderAppointmentDao.findByDateAndEngineerCodeIn(reqDTO.getDate(), reqDTO.getEngineerCodes());
List<String> orderIds = orderAppointments.stream().map(OrderAppointmentEntity::getOrderId).collect(Collectors.toList());
Map<String, OrderRequestEntity> mapOrderRequest = getOrdersByOrderIds(orderIds);
HashMap<String, List<EngineersGanttRespDTO.Order>> mapEngineers = new HashMap<>();
for (OrderAppointmentEntity e : orderAppointments) {
log.info("===== order_id: [{}]", e.getOrderId());
EngineersGanttRespDTO.Order order = new EngineersGanttRespDTO.Order();
// todo 需要根据订单时间和状态,采用expectXXXX或者actualXXXX
order.setStartTime(e.getExpectStartTime()).setEndTime(e.getExpectEndTime());
order.setOrderId(e.getOrderId()).setPreStatus(e.getPreStatus());
order.setTips(getOrderTips(e.getOrderId()));
order.setAppointmentStatus(mapOrderRequest.get(e.getOrderId()).getAppointmentStatus());
List<EngineersGanttRespDTO.Order> orders = null;
if (mapEngineers.containsKey(e.getEngineerCode())) {
orders = mapEngineers.get(e.getEngineerCode());
} else {
orders = new ArrayList<>();
}
orders.add(order);
mapEngineers.put(e.getEngineerCode(), orders);
}
List<EngineersGanttRespDTO.GanttChart> engineers = new ArrayList<>();
for (String engineerCode : reqDTO.getEngineerCodes()) {
EngineerInfoEntity engineerInfo = engineerInfoDao.getByEngineerCode(engineerCode);
EngineersGanttRespDTO.GanttChart engineer = new EngineersGanttRespDTO.GanttChart();
engineer.setEngineerCode(engineerCode)
.setStartTime(String.format("%s 08:00", reqDTO.getDate()))
.setEndTime(String.format("%s 18:00", reqDTO.getDate()))
.setHoliday(false) // todo
.setEngineerName(engineerInfo.getName())
.setGrade(engineerInfo.getGrade());
CapacityEngineerStatEntity capacityEngineerStat = capacityEngineerStatDao.getByEngineerCodeAndWorkday(engineerCode, reqDTO.getDate());
if (capacityEngineerStat == null) {
log.warn("技术员当日的容量数据不存在,{}{}", engineerCode, reqDTO.getDate());
} else {
engineer.setCapTotal(capacityEngineerStat.getCapTotal().toString()).setCapUsed(capacityEngineerStat.getCapUsed().toString());
}
if (mapEngineers.containsKey(engineerCode)) {
engineer.setOrders(mapEngineers.get(engineerCode));
}
// engineer.setErrorTip(); todo
engineers.add(engineer);
}
EngineersGanttRespDTO data = new EngineersGanttRespDTO().setDate(reqDTO.getDate()).setEngineers(engineers);
return Result.success(data);
}
public Map<String, OrderRequestEntity> getOrdersByOrderIds(List<String> orderIds) {
List<OrderRequestEntity> orders = orderRequestDao.findAllByOrderIdIn(orderIds);
return orders.stream()
.collect(Collectors.toMap(OrderRequestEntity::getOrderId, order -> order));
}
private List<?> getOrderTips(String orderId) {
log.info("==> getOrderTips: orderId[{}]", orderId);
OrderRequestEntity order = orderRequestDao.getByOrderId(orderId);
if (order == null) {
log.error("对应的订单不存在!{}", orderId);
return null;
}
List<LabelValueDTO> tips = new ArrayList<>();
tips.add(new LabelValueDTO().setLabel("工单号码").setValue(orderId));
tips.add(new LabelValueDTO().setLabel("类型/品牌").setValue(String.format("%s %s", order.getBrand(), order.getType())));
tips.add(new LabelValueDTO().setLabel("电话/地址").setValue(String.format("%s %s\n %s", order.getName(), order.getPhone(), order.getAddress())));
if (StringUtils.isNotBlank(order.getApplyNote())) {
tips.add(new LabelValueDTO().setLabel("备注").setValue(order.getApplyNote()));
}
tips.add(new LabelValueDTO().setLabel("标签").setValue(order.getTags()));
return tips;
}
} }
...@@ -4,23 +4,28 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; ...@@ -4,23 +4,28 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
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.common.OrderAssignCheck;
import com.dituhui.pea.order.common.TimeUtils; import com.dituhui.pea.order.common.TimeUtils;
import com.dituhui.pea.order.dao.EngineerInfoMPDao; import com.dituhui.pea.order.dao.EngineerInfoMPDao;
import com.dituhui.pea.order.dao.OrderAppointmentMPDao; import com.dituhui.pea.order.dao.OrderAppointmentMPDao;
import com.dituhui.pea.order.dao.OrderEventMPDao;
import com.dituhui.pea.order.dao.OrderRequestMPDao; import com.dituhui.pea.order.dao.OrderRequestMPDao;
import com.dituhui.pea.order.dto.LabelValueDTO; import com.dituhui.pea.order.dto.LabelValueDTO;
import com.dituhui.pea.order.dto.OrderAssignRecommendResp; import com.dituhui.pea.order.dto.OrderAssignRecommendResp;
import com.dituhui.pea.order.dto.TimeLineDTO; import com.dituhui.pea.order.dto.TimeLineDTO;
import com.dituhui.pea.order.entity.EngineerInfo; import com.dituhui.pea.order.entity.EngineerInfo;
import com.dituhui.pea.order.entity.OrderAppointment; import com.dituhui.pea.order.entity.OrderAppointment;
import com.dituhui.pea.order.entity.OrderEvent;
import com.dituhui.pea.order.entity.OrderRequest; import com.dituhui.pea.order.entity.OrderRequest;
import com.dituhui.pea.order.service.CommonService; import com.dituhui.pea.order.service.CommonService;
import com.dituhui.pea.order.service.OrderAssign; import com.dituhui.pea.order.service.OrderAssign;
import lombok.Data; import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.sql.Timestamp; import java.sql.Timestamp;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.ArrayList; import java.util.ArrayList;
...@@ -30,6 +35,7 @@ import java.util.List; ...@@ -30,6 +35,7 @@ import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@Service @Service
@Slf4j
public class OrderAssignImpl implements OrderAssign { public class OrderAssignImpl implements OrderAssign {
@Autowired @Autowired
...@@ -44,6 +50,12 @@ public class OrderAssignImpl implements OrderAssign { ...@@ -44,6 +50,12 @@ public class OrderAssignImpl implements OrderAssign {
@Autowired @Autowired
private CommonService commonService; private CommonService commonService;
@Autowired
private OrderEventMPDao orderEventMPDao;
@Autowired
private OrderAssignCheck orderAssignCheck;
@Transactional @Transactional
@Override @Override
public Result<?> getOrderAssignRecommendEngineers(String orderId, String key, String distance, String recommend) { public Result<?> getOrderAssignRecommendEngineers(String orderId, String key, String distance, String recommend) {
...@@ -111,26 +123,30 @@ public class OrderAssignImpl implements OrderAssign { ...@@ -111,26 +123,30 @@ public class OrderAssignImpl implements OrderAssign {
throw new BusinessException("订单不存在"); throw new BusinessException("订单不存在");
} }
if (!order.getAppointmentStatus().equals("NOT_ASSIGNED")) {
throw new BusinessException("订单已指派成功,不必重新指派");
}
EngineerInfo engineer = engineerInfoMPDao.getByEngineerCode(engineerCode); EngineerInfo engineer = engineerInfoMPDao.getByEngineerCode(engineerCode);
String date = TimeUtils.timestamp2DateTime(order.getExpectTimeBegin(), TimeUtils.DATE_GAP_FORMAT); boolean record = false;
List<OrderAppointment> orderAppointments = this.queryOrderAppointments(engineerCode, date); OrderAppointment op = orderAppointmentMPDao.getByOrderIdAndDt(orderId, order.getDt());
if(op != null) {
record = true;
}
OrderRecommend recommend = new OrderRecommend(); if(op != null && !order.getAppointmentStatus().equals("NOT_ASSIGNED") && op.getEngineerCode().equals(engineerCode)) {
RecommendResult rr = recommend.recommend(order, orderAppointments); throw new BusinessException(String.format("订单已指派个技术员[%s], 不必重复指派给同一个技术员", engineer.getName()));
if (rr.getIndex() == -1) {
throw new BusinessException("指派失败, 未能找到合适的时间段, 请选择其他技术员");
} }
LineSegment seg = rr.getSeg(); OrderAssignCheck.Result result = orderAssignCheck.orderAssignCheck(orderId, engineerCode);
Timestamp expectStartTime = recommend.linePoint2Timestamp(seg.start, date); log.info("指派检查结果:{}", result);
Timestamp expectEndTime = recommend.linePoint2Timestamp(seg.end, date); if(!result.getCanAssign()){
throw new BusinessException("指派失败, 未能找到合适的时间段, 请选择其他技术员");
}
Timestamp expectStartTime = Timestamp.valueOf(result.getStart());;
Timestamp expectEndTime = Timestamp.valueOf(result.getEnd());
OrderAppointment op = new OrderAppointment(); // 更新或插入指派单
if(!record){
op = new OrderAppointment();
}
op.setOrderId(orderId); op.setOrderId(orderId);
op.setSuborderId(Long.toString(System.currentTimeMillis())); op.setSuborderId(Long.toString(System.currentTimeMillis()));
op.setMainSub(1); op.setMainSub(1);
...@@ -139,12 +155,17 @@ public class OrderAssignImpl implements OrderAssign { ...@@ -139,12 +155,17 @@ public class OrderAssignImpl implements OrderAssign {
op.setEngineerAge(0); op.setEngineerAge(0);
op.setEngineerPhone(engineer.getPhone()); op.setEngineerPhone(engineer.getPhone());
op.setIsWorkshop(0); op.setIsWorkshop(0);
op.setDt(order.getDt());
op.setExpectStartTime(expectStartTime); op.setExpectStartTime(expectStartTime);
op.setExpectEndTime(expectEndTime); op.setExpectEndTime(expectEndTime);
op.setPreStatus("PRE"); op.setPreStatus("CONFIRM");
op.setStatus("ASSIGNED"); op.setStatus("ASSIGNED");
if(!record) {
orderAppointmentMPDao.insert(op); orderAppointmentMPDao.insert(op);
} else {
orderAppointmentMPDao.updateById(op);
}
// 更新order_request表状态 // 更新order_request表状态
LambdaUpdateWrapper<OrderRequest> wrapper = new LambdaUpdateWrapper<>(); LambdaUpdateWrapper<OrderRequest> wrapper = new LambdaUpdateWrapper<>();
...@@ -159,6 +180,40 @@ public class OrderAssignImpl implements OrderAssign { ...@@ -159,6 +180,40 @@ public class OrderAssignImpl implements OrderAssign {
return Result.success(null); return Result.success(null);
} }
@Override
public Result<?> orderRevokeAssign(String orderId) throws BusinessException{
OrderRequest order = orderRequestMPDao.getByOrderId(orderId);
if (order == null){
throw new BusinessException("订单不存在");
}
// 更新order_request表为未指派
order.setAppointmentStatus("NOT_ASSIGNED");
orderRequestMPDao.updateById(order);
// 更新order_appointment表为未指派
LambdaUpdateWrapper<OrderAppointment> appWrapper = new LambdaUpdateWrapper<>();
appWrapper.set(OrderAppointment::getStatus, "NOT_ASSIGNED")
.eq(OrderAppointment::getOrderId, orderId).eq(OrderAppointment::getDt, order.getDt());
orderAppointmentMPDao.update(null, appWrapper);
// 登记事件
OrderEvent oe = new OrderEvent();
oe.setOrderId(orderId);
oe.setSuborderId("");
oe.setHappen(new Timestamp(System.currentTimeMillis()));
oe.setEvent("放回工单池");
oe.setOperator("123"); // 操作员ID TODO-用户系统
oe.setOperatorName("测试用户"); // 操作员姓名 TODO-用户系统
oe.setSource("PEA");
oe.setDescription("返回工单池");
oe.setMemo("");
oe.setCreateTime(new Timestamp(System.currentTimeMillis()));
orderEventMPDao.insert(oe);
return Result.success(null);
}
private List<OrderAppointment> queryOrderAppointments(String engineerCode, String date) { private List<OrderAppointment> queryOrderAppointments(String engineerCode, String date) {
LambdaQueryWrapper<OrderAppointment> lqw = new LambdaQueryWrapper<>(); LambdaQueryWrapper<OrderAppointment> lqw = new LambdaQueryWrapper<>();
lqw.eq(OrderAppointment::getEngineerCode, engineerCode); lqw.eq(OrderAppointment::getEngineerCode, engineerCode);
......
...@@ -51,6 +51,15 @@ public class OrderServiceDetailImpl implements OrderServiceDetail { ...@@ -51,6 +51,15 @@ public class OrderServiceDetailImpl implements OrderServiceDetail {
List<KV> items = this.packOrderDetail(order); List<KV> items = this.packOrderDetail(order);
// 设置订单详情信息
OrderServiceDetailResp.OrderDetail detail = new OrderServiceDetailResp.OrderDetail();
detail.setAddress(String.format("%s%s%s", order.getCity(), order.getCounty(), order.getAddress()));
detail.setLocation(String.format("%s,%s", order.getX(),order.getY()));
detail.setDate(TimeUtils.IsoLocalDate2String(order.getDt()));
detail.setBrand(order.getBrand());
detail.setType(order.getType());
detail.setSkill(order.getSkill());
OrderServiceDetailResp res = new OrderServiceDetailResp(); OrderServiceDetailResp res = new OrderServiceDetailResp();
res.setOrderId(orderId); res.setOrderId(orderId);
res.setRisk(""); res.setRisk("");
...@@ -59,6 +68,7 @@ public class OrderServiceDetailImpl implements OrderServiceDetail { ...@@ -59,6 +68,7 @@ public class OrderServiceDetailImpl implements OrderServiceDetail {
res.setStatus(order.getStatus()); res.setStatus(order.getStatus());
res.setAppointmentStatus(order.getAppointmentStatus()); res.setAppointmentStatus(order.getAppointmentStatus());
res.setLocation(String.format("%s,%s", order.getX(), order.getY())); res.setLocation(String.format("%s,%s", order.getX(), order.getY()));
res.setReschedulingParams(detail);
res.setItems(items); res.setItems(items);
return Result.success(res); return Result.success(res);
...@@ -92,7 +102,7 @@ public class OrderServiceDetailImpl implements OrderServiceDetail { ...@@ -92,7 +102,7 @@ public class OrderServiceDetailImpl implements OrderServiceDetail {
if (appoints.isEmpty()) { if (appoints.isEmpty()) {
// 没有指派单列表,返回 // 没有指派单列表,返回
res.setOrderId(orderId); res.setOrderId(orderId);
res.setOrders(List.of()); res.setOrders(new ArrayList<>());
return Result.success(res); return Result.success(res);
} }
......
...@@ -59,13 +59,8 @@ public class OrderServiceListServiceImpl implements OrderServiceListService { ...@@ -59,13 +59,8 @@ public class OrderServiceListServiceImpl implements OrderServiceListService {
lqw.in(ListUtils.isNotEmpty(reqDTO.getPriorities()), OrderRequest::getPriority, reqDTO.getPriorities()); lqw.in(ListUtils.isNotEmpty(reqDTO.getPriorities()), OrderRequest::getPriority, reqDTO.getPriorities());
lqw.in(ListUtils.isNotEmpty(reqDTO.getProductCategory()), OrderRequest::getType, reqDTO.getProductCategory()); lqw.in(ListUtils.isNotEmpty(reqDTO.getProductCategory()), OrderRequest::getType, reqDTO.getProductCategory());
lqw.in(ListUtils.isNotEmpty(reqDTO.getProductCategory()), OrderRequest::getSkill, reqDTO.getServiceCategory()); lqw.in(ListUtils.isNotEmpty(reqDTO.getProductCategory()), OrderRequest::getSkill, reqDTO.getServiceCategory());
lqw.in(ListUtils.isNotEmpty(reqDTO.getAppointmentType()), OrderRequest::getAppointmentMethod, reqDTO.getAppointmentType());
lqw.eq(StringUtils.isNotEmpty(reqDTO.getAppointmentType()), OrderRequest::getAppointmentMethod, reqDTO.getAppointmentType()); //指派状态 lqw.in(ListUtils.isNotEmpty(reqDTO.getAppointmentStatus()), OrderRequest::getAppointmentStatus, reqDTO.getAppointmentStatus());
if (StringUtils.isNotEmpty(reqDTO.getAppointmentStatus()) && reqDTO.getAppointmentStatus().equals("0")) {
lqw.eq(OrderRequest::getAppointmentStatus, "NOT_ASSIGNED");
} else if (StringUtils.isNotEmpty(reqDTO.getAppointmentStatus()) && reqDTO.getAppointmentStatus().equals("1")) {
lqw.ne(OrderRequest::getAppointmentStatus, "NOT_ASSIGNED");
}
if(ListUtils.isNotEmpty(reqDTO.getEngineerCodes())) { if(ListUtils.isNotEmpty(reqDTO.getEngineerCodes())) {
String engineerCodes = String.join(",", reqDTO.getEngineerCodes()); String engineerCodes = String.join(",", reqDTO.getEngineerCodes());
......
package com.dituhui.pea.order.service.impl; package com.dituhui.pea.order.service.impl;
import com.dituhui.pea.common.Result; import com.dituhui.pea.common.Result;
import com.dituhui.pea.order.common.EngineerUtil;
import com.dituhui.pea.order.dao.*; import com.dituhui.pea.order.dao.*;
import com.dituhui.pea.order.dto.*; import com.dituhui.pea.order.dto.*;
import com.dituhui.pea.order.entity.*; import com.dituhui.pea.order.entity.*;
...@@ -31,6 +32,9 @@ public class OrganizationServiceImpl implements OrganizationService { ...@@ -31,6 +32,9 @@ public class OrganizationServiceImpl implements OrganizationService {
@Autowired @Autowired
private OrgTeamDao orgTeamDao; private OrgTeamDao orgTeamDao;
@Autowired
private EngineerUtil engineerUtil;
@Override @Override
public Result<?> getOrganizationTree(String levelType, String levelValue) { public Result<?> getOrganizationTree(String levelType, String levelValue) {
// 如果传递了精确的id,只返回对应的tree内容;如果没有传递,返回所有tree内容 // 如果传递了精确的id,只返回对应的tree内容;如果没有传递,返回所有tree内容
...@@ -111,30 +115,7 @@ public class OrganizationServiceImpl implements OrganizationService { ...@@ -111,30 +115,7 @@ public class OrganizationServiceImpl implements OrganizationService {
@Override @Override
public Result<?> getEngineersByLevel(String levelType, String levelValue) { public Result<?> getEngineersByLevel(String levelType, String levelValue) {
List<EngineerInfoEntity> engineers = null; List<EngineerInfoEntity> engineers = engineerUtil.getEngineersByLevel(levelType, levelValue);
List<String> groupIds = null;
assert "team".equals(levelType) || "group".equals(levelType) || "branch".equals(levelType) || "cluster".equals(levelType);
switch (levelType) {
case "team":
List<String> engineerCodes = orgTeamEngineerDao.findAllByTeamId(levelValue).stream()
.map(OrgTeamEngineerEntity::getEngineerCode).collect(Collectors.toList());
engineers = engineerInfoDao.findByEngineerCodeIn(engineerCodes);
break;
case "group":
engineers = engineerInfoDao.findByGroupId(levelValue);
break;
case "branch":
groupIds = orgGroupDao.findAllByBranchId(levelValue).stream()
.map(OrgGroupEntity::getGroupId).collect(Collectors.toList());
engineers = engineerInfoDao.findByGroupIdIn(groupIds);
break;
default:
// "cluster".equals(levelType)
groupIds = orgGroupDao.findAllByClusterId(levelValue).stream()
.map(OrgGroupEntity::getGroupId).collect(Collectors.toList());
engineers = engineerInfoDao.findByGroupIdIn(groupIds);
break;
}
List<OrganizationEngineersDTO.Engineer> engineers1 = engineers.stream().map(entity -> { List<OrganizationEngineersDTO.Engineer> engineers1 = engineers.stream().map(entity -> {
return new OrganizationEngineersDTO.Engineer() return new OrganizationEngineersDTO.Engineer()
.setEngineerCode(entity.getEngineerCode()) .setEngineerCode(entity.getEngineerCode())
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!