Commit c4adf19c by 刘鑫

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

2 parents 9e4da8a7 1de26b2e
package com.dituhui.pea.order.dao;
import com.dituhui.pea.order.entity.MapBlockInfoEntity;
import org.apache.ibatis.annotations.Param;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;
import java.util.List;
......@@ -10,15 +12,20 @@ import java.util.List;
@Repository
public interface MapBlockInfoDao extends JpaRepository<MapBlockInfoEntity, Integer>, JpaSpecificationExecutor<MapBlockInfoEntity> {
List<MapBlockInfoEntity> findByBlockIdInAndLayerIdIn(List<String> blockIds, List<String> layerIds);
List<MapBlockInfoEntity> findByBlockIdInAndLayerIdIn(List<String> blockIds, List<String> layerIds);
MapBlockInfoEntity findByBlockId(String blockId);
MapBlockInfoEntity findByBlockId(String blockId);
List<MapBlockInfoEntity> findByGroupId(String groupId);
List<MapBlockInfoEntity> findByGroupId(String groupId);
List<MapBlockInfoEntity> findByLayerId(String layerId);
List<MapBlockInfoEntity> findByLayerId(String layerId);
MapBlockInfoEntity findByTeamIdAndLayerId(String teamId, String layerId);
MapBlockInfoEntity findByTeamIdAndLayerId(String teamId, String layerId);
List<MapBlockInfoEntity> findByBlockIdIn(List<String> blockIds);
List<MapBlockInfoEntity> findByBlockIdIn(List<String> blockIds);
@Query(value = "select mbi.* from map_block_info mbi left join skill_info si on mbi.layer_id = si.layer_id left join map_layer_customize mlc on mlc.layer_id = mbi.layer_id " +
"where si.brand = :brand and si.`type` = :productType and si.skill = :skill and mbi.block_id in ( :blockIds ) order by mlc.priority ", nativeQuery = true)
List<MapBlockInfoEntity> listTeamIdByBrandAndSkillAndBlockIds(@Param("brand") String brand, @Param("productType") String productType,
@Param("skill") String skill, @Param("blockIds") List<String> blockIds);
}
......@@ -25,6 +25,12 @@ public class ScheduleOverviewResp {
private String distanceDesc;
private OrderSum order;
private List<Item> children;
private String clusterId;
private String branchId;
private String groupId;
}
@Data
......
......@@ -49,8 +49,8 @@ public class EngineerBusinessEntity implements Serializable {
@Column(name = "y", nullable = false, length = 20)
private String Y;
@Column(name = "vehicle", nullable = false, length = 10, columnDefinition = "varchar(10) default 'electric'")
private String vehicle;
@Column(name = "vehicle", nullable = false, length = 10, columnDefinition = "varchar(10) default '1'")
private String vehicle = "1";
@Column(name = "vehicle_no", nullable = false, length = 10, columnDefinition = "varchar(10) default ''")
private String vehicleNo;
......
......@@ -58,8 +58,8 @@ public class OrgTeamEntity {
@Column(name = "work_duration", nullable = false, columnDefinition = "int default 600")
private Integer workDuration = 600;
@Column(name = "transport_mode", columnDefinition = "varchar(10) default '电动车'")
private String transportMode = "电动车";
@Column(name = "transport_mode", columnDefinition = "varchar(10) default '1'")
private String transportMode = "1";
@Column(name = "strategy_schedule", columnDefinition = "varchar(10) default '营销优先'")
private String strategySchedule = "营销优先";
......
......@@ -36,6 +36,8 @@ public class FendanServiceImpl implements FendanService {
@Autowired
private OrgTeamEngineerDao orgTeamEngineerDao;
private static String allLayerId = "ALL";
@Override
public Result<List<OrgTeamInfo>> fendan(OrderDTO.OrderCreateRequest request) {
List<OrgTeamInfo> orgTeamInfos = new ArrayList<>();
......@@ -129,6 +131,12 @@ public class FendanServiceImpl implements FendanService {
return Result.success(orgTeamInfos);
}
/**
* 派工到工作队
*
* @param request
* @return
*/
@Override
public Result<List<OrgGroupInfo>> fendanToGroup(OrderDTO.OrderCreateRequest request) {
List<OrgGroupInfo> orgGroupTeamInfos = new ArrayList<>();
......@@ -140,21 +148,53 @@ public class FendanServiceImpl implements FendanService {
return Result.failed(StatusCodeEnum.FENDAN_AREA_UNMATCHED);
}
//2:匹配工作队
//2:根据服务范围匹配工作队
String peaBrand = fixBrand(request.getBrand());
List<String> blockIds = blockInfos.stream().map(SaasUtils.BlockInfo::getBlockId).distinct().collect(Collectors.toList());
List<MapBlockInfoEntity> mapBlockInfoEntities = mapBlockInfoDao.findByBlockIdIn(blockIds);
if (CollectionUtils.isEmpty(mapBlockInfoEntities)) {
//区划所在范围并分配到具体技能的工作队
List<MapBlockInfoEntity> mapBlockInfoList = mapBlockInfoDao.listTeamIdByBrandAndSkillAndBlockIds(peaBrand, request.getProductType(), request.getServiceType(), blockIds);
//区划所在范围所有工作队
List<MapBlockInfoEntity> mapBlockInBlockIdsList = mapBlockInfoDao.findByBlockIdIn(blockIds);
if (CollectionUtils.isEmpty(mapBlockInfoList) && CollectionUtils.isEmpty(mapBlockInBlockIdsList)) {
return Result.failed(StatusCodeEnum.FENDAN_TEAM_UNMATCHED);
}
//3:匹配分部
List<String> teamIdList = mapBlockInfoEntities.stream().map(MapBlockInfoEntity::getTeamId).distinct().collect(Collectors.toList());
List<Integer> mapBlockIdList = mapBlockInfoList.stream().map(MapBlockInfoEntity::getId).distinct().collect(Collectors.toList());
//筛选漏选工作队(处理全技能图层)
for (MapBlockInfoEntity mapBlockInfoEntity : mapBlockInBlockIdsList) {
if (mapBlockIdList.contains(mapBlockInfoEntity.getId())) {
continue;
}
if (mapBlockInfoEntity.getLayerId().equals(allLayerId)) {
mapBlockInfoList.add(mapBlockInfoEntity);
}
}
//3:按照派工顺序组装工作队数据
List<String> teamIdList = mapBlockInfoList.stream().map(MapBlockInfoEntity::getTeamId).distinct().collect(Collectors.toList());
List<OrgTeamEntity> teamList = orgTeamDao.findByTeamIdIn(teamIdList);
Map<String, OrgTeamEntity> teamMap = teamList.stream().collect(Collectors.toMap(OrgTeamEntity::getTeamId, e -> e));
List<OrgGroupEntity> orgGroupList = orgGroupDao.findByTeamIdIn(teamIdList);
for (OrgGroupEntity orgGroupEntity : orgGroupList) {
OrgGroupInfo orgGroup = BeanUtil.copyProperties(orgGroupEntity, OrgGroupInfo.class);
List<OrgTeamInfo> orgTeamInfoList = teamList.stream().filter(e -> e.getGroupId().equals(orgGroup.getGroupId())).map(e -> BeanUtil.copyProperties(e, OrgTeamInfo.class)).collect(Collectors.toList());
orgGroup.setTeamInfos(orgTeamInfoList);
MapBlockInfoEntity allLayer = null;
for (int i = 0; i < mapBlockInfoList.size(); i++) {
if (!mapBlockInfoList.get(i).getGroupId().equals(orgGroupEntity.getGroupId())) {
continue;
}
OrgTeamEntity orgTeamEntity = teamMap.get(mapBlockInfoList.get(i).getTeamId());
//全技能数据放在最后
if (mapBlockInfoList.get(i).getLayerId().equals(allLayerId)) {
allLayer = mapBlockInfoList.get(i);
} else {
OrgTeamInfo orgTeamInfo = BeanUtil.copyProperties(orgTeamEntity, OrgTeamInfo.class);
orgGroup.setTeamInfos(Arrays.asList(orgTeamInfo));
}
//最后处理全技能数据
if (i == mapBlockInfoList.size() - 1 && null != allLayer) {
OrgTeamInfo orgTeamInfoAll = BeanUtil.copyProperties(orgTeamEntity, OrgTeamInfo.class);
orgGroup.setTeamInfos(Arrays.asList(orgTeamInfoAll));
allLayer = null;
}
}
orgGroupTeamInfos.add(orgGroup);
}
return Result.success(orgGroupTeamInfos);
......
......@@ -25,434 +25,437 @@ import java.util.stream.Collectors;
@Service
public class ScheduleServiceImpl implements ScheduleService {
@Autowired
private OrderInfoMPDao orderInfoMPDao;
@Autowired
private OrderInfoDao orderInfoDao;
@Autowired
private OrgTeamDao orgTeamDao;
@Autowired
private OrgTeamEngineerDao orgTeamEngineerDao;
@Autowired
private OrgGroupDao orgGroupDao;
@Autowired
private EngineerInfoDao engineerInfoDao;
@Autowired
private SkillInfoDao skillInfoDao;
@Override
public Result<?> getScheduleSummary(LocalDate date, String levelType, List<String> levelValue) {
List<ScheduleSummaryResp.ItemDTO> items = new ArrayList<>();
ScheduleSummaryResp.ItemDTO skillItem = new ScheduleSummaryResp.ItemDTO();
skillItem.setType("order");
skillItem.setRows(this.packSkillSummary(this.queryCountBySkill(date, levelType, levelValue)));
items.add(skillItem);
ScheduleSummaryResp.ItemDTO groupItem = new ScheduleSummaryResp.ItemDTO();
groupItem.setType("order");
groupItem.setRows(this.packGroupCategorySummary(this.queryCountByGroupId(date, levelType, levelValue)));
items.add(groupItem);
ScheduleSummaryResp.ItemDTO appointmentItem = new ScheduleSummaryResp.ItemDTO();
appointmentItem.setType("order");
appointmentItem.setRows(this.packAppointmentSummary(this.queryCountByAppointment(date, levelType, levelValue)));
items.add(appointmentItem);
ScheduleSummaryResp res = new ScheduleSummaryResp();
res.setSummary(items);
return Result.success(res);
}
@Override
public Result<?> getScheduleOverview(long page, long size, LocalDate date, String levelType, List<String> levelIds) {
// 排班结果
// 获取team列表, 以team排序分页
Page<OrgTeamEntity> pg = this.queryOrgTeams(page, size, levelType, levelIds);
List<OrgTeamEntity> orgTeams = pg.getContent();
List<ScheduleOverviewResp.Team> teams = new ArrayList<>();
// 获取skill与skill_category的映射
HashMap<String, String> skillMapping = this.getSkillMapping();
// 获取工单列表
for (OrgTeamEntity t : orgTeams) {
ScheduleOverviewResp.Team team = new ScheduleOverviewResp.Team();
team.setName(t.getTeamName());
team.setValue(t.getTeamId());
team.setLevel("team");
// 获取改team订单列表
List<OrderInfoEntity> orders = orderInfoDao.findByDtAndOrgTeamIdAndAppointmentStatusIn(date, t.getTeamId(), List.of("PRE", "CONFIRM"));
team.setOrder(this.getTeamOrderSum(orders, skillMapping));
// 技术员指派单列表
Map<String, List<OrderInfoEntity>> engineerOrders = new HashMap<>();
if (ListUtils.isNotEmpty(orders)) {
orders.sort(Comparator.comparing(OrderInfoEntity::getEngineerCode));
engineerOrders = orders.stream().collect(Collectors.groupingBy(OrderInfoEntity::getEngineerCode));
}
// 获取team技术员列表
List<OrgTeamEngineerEntity> teamEngineers = orgTeamEngineerDao.findAllByTeamId(t.getTeamId());
List<String> engineerCodes = teamEngineers.stream().map(OrgTeamEngineerEntity::getEngineerCode).collect(Collectors.toList());
List<EngineerInfoEntity> engineerInfoList = engineerInfoDao.findByEngineerCodeIn(engineerCodes);
Map<String, List<EngineerInfoEntity>> engineers = engineerInfoList.stream().collect(
Collectors.groupingBy(EngineerInfoEntity::getEngineerCode));
List<ScheduleOverviewResp.Item> children = new ArrayList<>();
for (Map.Entry<String, List<EngineerInfoEntity>> entry : engineers.entrySet()) {
ScheduleOverviewResp.Item child = new ScheduleOverviewResp.Item();
//技术员信息
String engineerCode = entry.getKey();
EngineerInfoEntity engineerInfo = entry.getValue().get(0);
// 获取技术员已经指派的订单列表
List<OrderInfoEntity> orders2 = engineerOrders.getOrDefault(engineerCode, new ArrayList<>());
child.setName(engineerInfo.getName());
child.setValue(engineerCode);
child.setLevel("engineer");
child.setOrder(this.getTeamOrderSum(orders2, skillMapping));
child.setOrderDesc(Integer.toString(orders2.size()));
child.setDistanceDesc("");
children.add(child);
}
team.setChildren(children);
team.setOrderDesc(String.format("人均:%d", teamEngineers.size() > 0 ? (orders.size() / teamEngineers.size()) : 0));
team.setDistanceDesc("");
teams.add(team);
}
ScheduleOverviewResp res = new ScheduleOverviewResp();
res.setTotal(pg.getTotalElements());
res.setPages(pg.getTotalPages());
res.setPageSize(pg.getSize());
res.setPageCurrent(pg.getNumber() + 1);
res.setContent(teams);
return Result.success(res);
}
@Override
public Result<?> getScheduleEngineerOverview(LocalDate date, String engineerCode) throws BusinessException {
// 获取技术员已排班概况
EngineerInfoEntity engineer = engineerInfoDao.getByEngineerCode(engineerCode);
if (engineer == null) {
throw new BusinessException("分销员不存在");
}
List<LabelValueDTO> emptyTips = new ArrayList<>();
List<OrderInfoEntity> orderAppointments = orderInfoDao.findByEngineerCodeAndDtAndAppointmentStatusIn(
engineerCode, date, List.of("PRE", "CONFIRM"));
List<TimeLineDTO> timelines = new ArrayList<>();
for (OrderInfoEntity o : orderAppointments) {
TimeLineDTO item = new TimeLineDTO();
item.setOrderId(o.getOrderId());
item.setAppointmentStatus(o.getAppointmentStatus());
item.setStartTime(TimeUtils.IsoLocalDateTime2String(o.getPlanStartTime()));
item.setEndTime(TimeUtils.IsoLocalDateTime2String(o.getPlanEndTime()));
item.setTips(emptyTips);
timelines.add(item);
}
Map<String, List<OrderInfoEntity>> statusGroup = orderAppointments.stream().collect(Collectors.groupingBy(OrderInfoEntity::getServiceStatus));
List<OrderInfoEntity> empty = new ArrayList<>();
Integer countPending = statusGroup.getOrDefault("INIT", empty).size() + statusGroup.getOrDefault("CONTACTED", empty).size() + statusGroup.getOrDefault("PENDING", empty).size();
List<LabelValueDTO> dynamics = new ArrayList<>();
dynamics.add(new LabelValueDTO("姓名", engineer.getName()));
dynamics.add(new LabelValueDTO("日期", TimeUtils.IsoLocalDate2String(date)));
dynamics.add(new LabelValueDTO("状态", "上班"));
dynamics.add(new LabelValueDTO("待服务", Integer.toString(countPending)));
dynamics.add(new LabelValueDTO("服务中", Integer.toString(statusGroup.getOrDefault("STARTED", empty).size())));
dynamics.add(new LabelValueDTO("已完成", Integer.toString(statusGroup.getOrDefault("FINISHED", empty).size())));
dynamics.add(new LabelValueDTO("已取消", Integer.toString(statusGroup.getOrDefault("CANCELED", empty).size())));
dynamics.add(new LabelValueDTO("已改约", Integer.toString(statusGroup.getOrDefault("RESCHEDULED", empty).size())));
dynamics.add(new LabelValueDTO("预计总耗时", "6小时"));
dynamics.add(new LabelValueDTO("公里数", "42公里"));
dynamics.add(new LabelValueDTO("工作时间", "08:00-18:00"));
dynamics.add(new LabelValueDTO("交通工具", "电动车"));
List<String> orderIds = orderAppointments.stream().map(OrderInfoEntity::getOrderId).collect(Collectors.toList());
List<OrderInfoEntity> orderRequests = new ArrayList<>();
if (orderIds != null && !orderIds.isEmpty()) {
orderRequests = orderInfoDao.findAllByDtAndOrderIdIn(date, orderIds);
}
List<ScheduleEngineerOverviewResp.Order> orders = new ArrayList<>();
for (OrderInfoEntity o : orderRequests) {
ScheduleEngineerOverviewResp.Order item = new ScheduleEngineerOverviewResp.Order();
item.setOrderId(o.getOrderId());
item.setLocation(String.format("%s,%s", o.getX(), o.getY()));
item.setType(o.getType());
item.setSkill(o.getSkill());
item.setOrderStatus(o.getAppointmentStatus());
item.setOrderStatusName("");
item.setDistance(3000);
item.setTimeType("auto");
item.setExpectArriveDuration("10分钟");
item.setArriveTime("10分钟");
item.setExpectWorkDuration("30分钟");
item.setWorkDuration("30分钟");
orders.add(item);
}
String groupName = "";
OrgGroupEntity group = orgGroupDao.getByGroupId(engineer.getGroupId());
if (group != null) {
groupName = group.getGroupName();
}
ScheduleEngineerOverviewResp res = new ScheduleEngineerOverviewResp();
res.setTitle(String.format("%s_%s", groupName, engineer.getName()));
res.setEngineerCode(engineerCode);
res.setStartTime(String.format("%s 08:00:00", date)); // TODO
res.setEndTime(String.format("%s 18:00:00", date));
res.setDynamics(dynamics);
res.setOrders(timelines);
res.setOrderDetails(orders);
return Result.success(res);
}
public Page<OrgTeamEntity> queryOrgTeams(long page, long size, String levelType, List<String> levelIds) {
Pageable pageable = PageRequest.of((int) page, (int) size);
Specification<OrgTeamEntity> spec = (root, query, cb) -> {
Predicate statusPredicate = cb.equal(root.get("status"), 1);
Predicate levelPredicate = null;
if ("cluster".equals(levelType)) {
levelPredicate = root.get("clusterId").in(levelIds);
} else if ("branch".equals(levelType)) {
levelPredicate = root.get("branchId").in(levelIds);
} else if ("group".equals(levelType)) {
levelPredicate = root.get("groupId").in(levelIds);
}
return cb.and(statusPredicate, levelPredicate);
};
return orgTeamDao.findAll(spec, pageable);
}
private ScheduleOverviewResp.OrderSum getTeamOrderSum(List<OrderInfoEntity> orders, HashMap<String, String> skillMapping) {
ScheduleOverviewResp.OrderSum s = new ScheduleOverviewResp.OrderSum();
List<OrderInfo> emtpy = new ArrayList<>();
HashMap<String, Integer> skillCounter = new HashMap<>();
Map<String, List<OrderInfoEntity>> cc = orders.stream().collect(Collectors.groupingBy(OrderInfoEntity::getSkill));
for (Map.Entry<String, List<OrderInfoEntity>> entry : cc.entrySet()) {
String skill = entry.getKey();
Integer count = entry.getValue().size();
String skillCategory = skillMapping.get(skill);
Integer v = skillCounter.getOrDefault(skillCategory, 0);
v += count;
skillCounter.put(skillCategory, v);
}
s.setTotal(orders.size());
s.setInstallNum(skillCounter.getOrDefault("安装", 0));
s.setFixNum(skillCounter.getOrDefault("维修", 0));
s.setDesignNum(0); // 前端接口已废弃
s.setCleanNum(skillCounter.getOrDefault("清洁保养", 0));
s.setReformNum(skillCounter.getOrDefault("整改", 0));
return s;
}
private HashMap<String, String> getSkillMapping() {
List<SkillInfoEntity> skills = skillInfoDao.findAll();
return skills.stream().collect(Collectors.toMap(
SkillInfoEntity::getSkill, SkillInfoEntity::getSkillCategory, (oldValue, newValue) -> newValue, HashMap::new));
}
private HashMap<String, Integer> queryCountBySkill(LocalDate date, String levelType, List<String> levelValue) {
HashMap<String, Integer> map = new HashMap<>();
// 获取skill映射
HashMap<String, String> skillMap = this.getSkillCategoryMapping();
QueryWrapper<OrderInfo> wrapper = new QueryWrapper<>();
wrapper.select("skill, COUNT(*) as count")
.lambda()
.eq(OrderInfo::getDt, date)
.in(levelType.equals("cluster"), OrderInfo::getOrgClusterId, levelValue)
.in(levelType.equals("branch"), OrderInfo::getOrgBranchId, levelValue)
.in(levelType.equals("group"), OrderInfo::getOrgGroupId, levelValue)
.groupBy(OrderInfo::getSkill);
List<Map<String, Object>> results = orderInfoMPDao.selectMaps(wrapper);
for (Map<String, Object> result : results) {
String skill = (String) result.get("skill");
Long countValue = (Long) result.get("count");
Integer count = countValue.intValue();
String skillCategory = skillMap.get(skill);
Integer value = map.getOrDefault(skillCategory, 0);
value = value + count;
map.put(skillCategory, value);
}
return map;
}
private HashMap<Integer, Integer> queryCountByGroupId(LocalDate date, String levelType, List<String> levelValue) {
HashMap<Integer, Integer> map = new HashMap<>();
HashMap<String, Integer> groupCategoryMapping = this.getGroupCategoryMapping(levelType, levelValue);
QueryWrapper<OrderInfo> wrapper = new QueryWrapper<>();
wrapper.select("org_group_id, COUNT(*) as count")
.lambda()
.eq(OrderInfo::getDt, date)
.in(levelType.equals("cluster"), OrderInfo::getOrgClusterId, levelValue)
.in(levelType.equals("branch"), OrderInfo::getOrgBranchId, levelValue)
.in(levelType.equals("group"), OrderInfo::getOrgGroupId, levelValue)
.groupBy(OrderInfo::getOrgGroupId);
List<Map<String, Object>> results = orderInfoMPDao.selectMaps(wrapper);
for (Map<String, Object> result : results) {
String groupId = (String) result.get("org_group_id");
Long countValue = (Long) result.get("count");
Integer count = countValue.intValue();
Integer groupCategory = groupCategoryMapping.get(groupId);
Integer value = map.getOrDefault(groupCategory, 0);
value = value + count;
map.put(groupCategory, value);
}
return map;
}
private HashMap<String, Integer> queryCountByAppointment(LocalDate date, String levelType, List<String> levelValue) {
HashMap<String, Integer> map = new HashMap<>();
QueryWrapper<OrderInfo> wrapper = new QueryWrapper<>();
wrapper.select("appointment_method, appointment_status, COUNT(*) as count")
.lambda()
.eq(OrderInfo::getDt, date)
.in(levelType.equals("cluster"), OrderInfo::getOrgClusterId, levelValue)
.in(levelType.equals("branch"), OrderInfo::getOrgBranchId, levelValue)
.in(levelType.equals("group"), OrderInfo::getOrgGroupId, levelValue)
.groupBy(OrderInfo::getAppointmentMethod, OrderInfo::getAppointmentStatus);
List<Map<String, Object>> results = orderInfoMPDao.selectMaps(wrapper);
Integer autoTotal = 0;
Integer manualTotal = 0;
Integer notAssignTotal = 0;
for (Map<String, Object> result : results) {
String method = (String) result.get("appointment_method");
String status = (String) result.get("appointment_status");
Long countValue = (Long) result.get("count");
int count = countValue.intValue();
if (status.equals("NOT_ASSIGNED")) {
notAssignTotal += count;
continue;
}
if (method.equals("MANUAL")) {
manualTotal += count;
} else {
autoTotal += count;
}
}
map.put("autoTotal", autoTotal);
map.put("manualTotal", manualTotal);
map.put("notAssignTotal", notAssignTotal);
return map;
}
private HashMap<String, String> getSkillCategoryMapping() {
// 获取skill与skillCategory(面向前端)的映射
List<SkillInfoEntity> skillList = skillInfoDao.findAll();
return skillList.stream()
.collect(Collectors.toMap(
SkillInfoEntity::getSkill, SkillInfoEntity::getSkillCategory, (oldValue, newValue) -> newValue, HashMap::new));
}
private HashMap<String, Integer> getGroupCategoryMapping(String levelType, List<String> levelValue) {
HashMap<String, Integer> map = new HashMap<>();
List<OrgGroupEntity> groups = new ArrayList<>();
if(levelType.equals("cluster")){
groups = orgGroupDao.findAllByClusterIdIn(levelValue);
} else if (levelType.equals("branch")){
groups = orgGroupDao.findAllByBranchIdIn(levelValue);
} else if (levelType.equals("group")){
groups = orgGroupDao.findAllByGroupIdIn(levelValue);
}
for (OrgGroupEntity g : groups) {
map.put(g.getGroupId(), g.getCategory());
}
return map;
}
private List<ScheduleSummaryResp.ValueDTO> packSkillSummary(HashMap<String, Integer> map) {
Integer sum = 0;
for (Map.Entry<String, Integer> entry : map.entrySet()) {
sum += entry.getValue();
}
String urlName = "DispatchBenchManage";
List<ScheduleSummaryResp.ValueDTO> items = new ArrayList<>();
items.add(new ScheduleSummaryResp.ValueDTO("总单量", sum, "#469967", urlName, new HashMap<>()));
HashMap<String, List<String>> p1 = this.packParams("skillCategory", "安装");
items.add(new ScheduleSummaryResp.ValueDTO("安装", map.getOrDefault("安装", 0), null, urlName, p1));
HashMap<String, List<String>> p2 = this.packParams("skillCategory", "维修");
items.add(new ScheduleSummaryResp.ValueDTO("维修", map.getOrDefault("维修", 0), null, urlName, p2));
HashMap<String, List<String>> p3 = this.packParams("skillCategory", "清洁保养");
items.add(new ScheduleSummaryResp.ValueDTO("清洁保养", map.getOrDefault("清洁保养", 0), null, urlName, p3));
HashMap<String, List<String>> p4 = this.packParams("skillCategory", "整改");
items.add(new ScheduleSummaryResp.ValueDTO("整改", map.getOrDefault("整改", 0), null, urlName, p4));
return items;
}
private List<ScheduleSummaryResp.ValueDTO> packGroupCategorySummary(HashMap<Integer, Integer> map) {
String urlName = "DispatchBenchManage";
List<ScheduleSummaryResp.ValueDTO> items = new ArrayList<>();
HashMap<String, List<Integer>> p1 = this.packParams("groupCategory", 1);
items.add(new ScheduleSummaryResp.ValueDTO("自有", map.getOrDefault(1, 0), null, urlName, p1));
HashMap<String, List<Integer>> p2 = this.packParams("groupCategory", 2);
items.add(new ScheduleSummaryResp.ValueDTO("网点", map.getOrDefault(2, 0), null, urlName, p2));
return items;
}
private List<ScheduleSummaryResp.ValueDTO> packAppointmentSummary(HashMap<String, Integer> map) {
String urlName = "DispatchBenchManage";
List<ScheduleSummaryResp.ValueDTO> items = new ArrayList<>();
HashMap<String, List<String>> p1 = this.packParams("appointmentType", "AUTO_NOW", "AUTO_BATCH");
items.add(new ScheduleSummaryResp.ValueDTO("自动指派", map.getOrDefault("autoTotal", 0), null, urlName, p1));
HashMap<String, List<String>> p2 = this.packParams("appointmentType", "MANUAL");
items.add(new ScheduleSummaryResp.ValueDTO("人工指派", map.getOrDefault("manualTotal", 0), null, urlName, p2));
HashMap<String, List<String>> p3 = this.packParams("appointmentStatus", "NOT_ASSIGNED");
items.add(new ScheduleSummaryResp.ValueDTO("未指派", map.getOrDefault("notAssignTotal", 0), null, urlName, p3));
return items;
}
private <T> HashMap<String, List<T>> packParams(String key, T... values) {
HashMap<String, List<T>> map = new HashMap<>();
List<T> value = new ArrayList<>();
Collections.addAll(value, values);
map.put(key, value);
return map;
}
@Autowired
private OrderInfoMPDao orderInfoMPDao;
@Autowired
private OrderInfoDao orderInfoDao;
@Autowired
private OrgTeamDao orgTeamDao;
@Autowired
private OrgTeamEngineerDao orgTeamEngineerDao;
@Autowired
private OrgGroupDao orgGroupDao;
@Autowired
private EngineerInfoDao engineerInfoDao;
@Autowired
private SkillInfoDao skillInfoDao;
@Override
public Result<?> getScheduleSummary(LocalDate date, String levelType, List<String> levelValue) {
List<ScheduleSummaryResp.ItemDTO> items = new ArrayList<>();
ScheduleSummaryResp.ItemDTO skillItem = new ScheduleSummaryResp.ItemDTO();
skillItem.setType("order");
skillItem.setRows(this.packSkillSummary(this.queryCountBySkill(date, levelType, levelValue)));
items.add(skillItem);
ScheduleSummaryResp.ItemDTO groupItem = new ScheduleSummaryResp.ItemDTO();
groupItem.setType("order");
groupItem.setRows(this.packGroupCategorySummary(this.queryCountByGroupId(date, levelType, levelValue)));
items.add(groupItem);
ScheduleSummaryResp.ItemDTO appointmentItem = new ScheduleSummaryResp.ItemDTO();
appointmentItem.setType("order");
appointmentItem.setRows(this.packAppointmentSummary(this.queryCountByAppointment(date, levelType, levelValue)));
items.add(appointmentItem);
ScheduleSummaryResp res = new ScheduleSummaryResp();
res.setSummary(items);
return Result.success(res);
}
@Override
public Result<?> getScheduleOverview(long page, long size, LocalDate date, String levelType, List<String> levelIds) {
// 排班结果
// 获取team列表, 以team排序分页
Page<OrgTeamEntity> pg = this.queryOrgTeams(page, size, levelType, levelIds);
List<OrgTeamEntity> orgTeams = pg.getContent();
List<ScheduleOverviewResp.Team> teams = new ArrayList<>();
// 获取skill与skill_category的映射
HashMap<String, String> skillMapping = this.getSkillMapping();
// 获取工单列表
for (OrgTeamEntity t : orgTeams) {
ScheduleOverviewResp.Team team = new ScheduleOverviewResp.Team();
team.setName(t.getTeamName());
team.setValue(t.getTeamId());
team.setGroupId(t.getGroupId());
team.setBranchId(t.getBranchId());
team.setClusterId(t.getClusterId());
team.setLevel("team");
// 获取改team订单列表
List<OrderInfoEntity> orders = orderInfoDao.findByDtAndOrgTeamIdAndAppointmentStatusIn(date, t.getTeamId(), List.of("PRE", "CONFIRM"));
team.setOrder(this.getTeamOrderSum(orders, skillMapping));
// 技术员指派单列表
Map<String, List<OrderInfoEntity>> engineerOrders = new HashMap<>();
if (ListUtils.isNotEmpty(orders)) {
orders.sort(Comparator.comparing(OrderInfoEntity::getEngineerCode));
engineerOrders = orders.stream().collect(Collectors.groupingBy(OrderInfoEntity::getEngineerCode));
}
// 获取team技术员列表
List<OrgTeamEngineerEntity> teamEngineers = orgTeamEngineerDao.findAllByTeamId(t.getTeamId());
List<String> engineerCodes = teamEngineers.stream().map(OrgTeamEngineerEntity::getEngineerCode).collect(Collectors.toList());
List<EngineerInfoEntity> engineerInfoList = engineerInfoDao.findByEngineerCodeIn(engineerCodes);
Map<String, List<EngineerInfoEntity>> engineers = engineerInfoList.stream().collect(
Collectors.groupingBy(EngineerInfoEntity::getEngineerCode));
List<ScheduleOverviewResp.Item> children = new ArrayList<>();
for (Map.Entry<String, List<EngineerInfoEntity>> entry : engineers.entrySet()) {
ScheduleOverviewResp.Item child = new ScheduleOverviewResp.Item();
//技术员信息
String engineerCode = entry.getKey();
EngineerInfoEntity engineerInfo = entry.getValue().get(0);
// 获取技术员已经指派的订单列表
List<OrderInfoEntity> orders2 = engineerOrders.getOrDefault(engineerCode, new ArrayList<>());
child.setName(engineerInfo.getName());
child.setValue(engineerCode);
child.setLevel("engineer");
child.setOrder(this.getTeamOrderSum(orders2, skillMapping));
child.setOrderDesc(Integer.toString(orders2.size()));
child.setDistanceDesc("");
children.add(child);
}
team.setChildren(children);
team.setOrderDesc(String.format("人均:%d", teamEngineers.size() > 0 ? (orders.size() / teamEngineers.size()) : 0));
team.setDistanceDesc("");
teams.add(team);
}
ScheduleOverviewResp res = new ScheduleOverviewResp();
res.setTotal(pg.getTotalElements());
res.setPages(pg.getTotalPages());
res.setPageSize(pg.getSize());
res.setPageCurrent(pg.getNumber() + 1);
res.setContent(teams);
return Result.success(res);
}
@Override
public Result<?> getScheduleEngineerOverview(LocalDate date, String engineerCode) throws BusinessException {
// 获取技术员已排班概况
EngineerInfoEntity engineer = engineerInfoDao.getByEngineerCode(engineerCode);
if (engineer == null) {
throw new BusinessException("分销员不存在");
}
List<LabelValueDTO> emptyTips = new ArrayList<>();
List<OrderInfoEntity> orderAppointments = orderInfoDao.findByEngineerCodeAndDtAndAppointmentStatusIn(
engineerCode, date, List.of("PRE", "CONFIRM"));
List<TimeLineDTO> timelines = new ArrayList<>();
for (OrderInfoEntity o : orderAppointments) {
TimeLineDTO item = new TimeLineDTO();
item.setOrderId(o.getOrderId());
item.setAppointmentStatus(o.getAppointmentStatus());
item.setStartTime(TimeUtils.IsoLocalDateTime2String(o.getPlanStartTime()));
item.setEndTime(TimeUtils.IsoLocalDateTime2String(o.getPlanEndTime()));
item.setTips(emptyTips);
timelines.add(item);
}
Map<String, List<OrderInfoEntity>> statusGroup = orderAppointments.stream().collect(Collectors.groupingBy(OrderInfoEntity::getServiceStatus));
List<OrderInfoEntity> empty = new ArrayList<>();
Integer countPending = statusGroup.getOrDefault("INIT", empty).size() + statusGroup.getOrDefault("CONTACTED", empty).size() + statusGroup.getOrDefault("PENDING", empty).size();
List<LabelValueDTO> dynamics = new ArrayList<>();
dynamics.add(new LabelValueDTO("姓名", engineer.getName()));
dynamics.add(new LabelValueDTO("日期", TimeUtils.IsoLocalDate2String(date)));
dynamics.add(new LabelValueDTO("状态", "上班"));
dynamics.add(new LabelValueDTO("待服务", Integer.toString(countPending)));
dynamics.add(new LabelValueDTO("服务中", Integer.toString(statusGroup.getOrDefault("STARTED", empty).size())));
dynamics.add(new LabelValueDTO("已完成", Integer.toString(statusGroup.getOrDefault("FINISHED", empty).size())));
dynamics.add(new LabelValueDTO("已取消", Integer.toString(statusGroup.getOrDefault("CANCELED", empty).size())));
dynamics.add(new LabelValueDTO("已改约", Integer.toString(statusGroup.getOrDefault("RESCHEDULED", empty).size())));
dynamics.add(new LabelValueDTO("预计总耗时", "6小时"));
dynamics.add(new LabelValueDTO("公里数", "42公里"));
dynamics.add(new LabelValueDTO("工作时间", "08:00-18:00"));
dynamics.add(new LabelValueDTO("交通工具", "电动车"));
List<String> orderIds = orderAppointments.stream().map(OrderInfoEntity::getOrderId).collect(Collectors.toList());
List<OrderInfoEntity> orderRequests = new ArrayList<>();
if (orderIds != null && !orderIds.isEmpty()) {
orderRequests = orderInfoDao.findAllByDtAndOrderIdIn(date, orderIds);
}
List<ScheduleEngineerOverviewResp.Order> orders = new ArrayList<>();
for (OrderInfoEntity o : orderRequests) {
ScheduleEngineerOverviewResp.Order item = new ScheduleEngineerOverviewResp.Order();
item.setOrderId(o.getOrderId());
item.setLocation(String.format("%s,%s", o.getX(), o.getY()));
item.setType(o.getType());
item.setSkill(o.getSkill());
item.setOrderStatus(o.getAppointmentStatus());
item.setOrderStatusName("");
item.setDistance(3000);
item.setTimeType("auto");
item.setExpectArriveDuration("10分钟");
item.setArriveTime("10分钟");
item.setExpectWorkDuration("30分钟");
item.setWorkDuration("30分钟");
orders.add(item);
}
String groupName = "";
OrgGroupEntity group = orgGroupDao.getByGroupId(engineer.getGroupId());
if (group != null) {
groupName = group.getGroupName();
}
ScheduleEngineerOverviewResp res = new ScheduleEngineerOverviewResp();
res.setTitle(String.format("%s_%s", groupName, engineer.getName()));
res.setEngineerCode(engineerCode);
res.setStartTime(String.format("%s 08:00:00", date)); // TODO
res.setEndTime(String.format("%s 18:00:00", date));
res.setDynamics(dynamics);
res.setOrders(timelines);
res.setOrderDetails(orders);
return Result.success(res);
}
public Page<OrgTeamEntity> queryOrgTeams(long page, long size, String levelType, List<String> levelIds) {
Pageable pageable = PageRequest.of((int) page, (int) size);
Specification<OrgTeamEntity> spec = (root, query, cb) -> {
Predicate statusPredicate = cb.equal(root.get("status"), 1);
Predicate levelPredicate = null;
if ("cluster".equals(levelType)) {
levelPredicate = root.get("clusterId").in(levelIds);
} else if ("branch".equals(levelType)) {
levelPredicate = root.get("branchId").in(levelIds);
} else if ("group".equals(levelType)) {
levelPredicate = root.get("groupId").in(levelIds);
}
return cb.and(statusPredicate, levelPredicate);
};
return orgTeamDao.findAll(spec, pageable);
}
private ScheduleOverviewResp.OrderSum getTeamOrderSum(List<OrderInfoEntity> orders, HashMap<String, String> skillMapping) {
ScheduleOverviewResp.OrderSum s = new ScheduleOverviewResp.OrderSum();
List<OrderInfo> emtpy = new ArrayList<>();
HashMap<String, Integer> skillCounter = new HashMap<>();
Map<String, List<OrderInfoEntity>> cc = orders.stream().collect(Collectors.groupingBy(OrderInfoEntity::getSkill));
for (Map.Entry<String, List<OrderInfoEntity>> entry : cc.entrySet()) {
String skill = entry.getKey();
Integer count = entry.getValue().size();
String skillCategory = skillMapping.get(skill);
Integer v = skillCounter.getOrDefault(skillCategory, 0);
v += count;
skillCounter.put(skillCategory, v);
}
s.setTotal(orders.size());
s.setInstallNum(skillCounter.getOrDefault("安装", 0));
s.setFixNum(skillCounter.getOrDefault("维修", 0));
s.setDesignNum(0); // 前端接口已废弃
s.setCleanNum(skillCounter.getOrDefault("清洁保养", 0));
s.setReformNum(skillCounter.getOrDefault("整改", 0));
return s;
}
private HashMap<String, String> getSkillMapping() {
List<SkillInfoEntity> skills = skillInfoDao.findAll();
return skills.stream().collect(Collectors.toMap(
SkillInfoEntity::getSkill, SkillInfoEntity::getSkillCategory, (oldValue, newValue) -> newValue, HashMap::new));
}
private HashMap<String, Integer> queryCountBySkill(LocalDate date, String levelType, List<String> levelValue) {
HashMap<String, Integer> map = new HashMap<>();
// 获取skill映射
HashMap<String, String> skillMap = this.getSkillCategoryMapping();
QueryWrapper<OrderInfo> wrapper = new QueryWrapper<>();
wrapper.select("skill, COUNT(*) as count")
.lambda()
.eq(OrderInfo::getDt, date)
.in(levelType.equals("cluster"), OrderInfo::getOrgClusterId, levelValue)
.in(levelType.equals("branch"), OrderInfo::getOrgBranchId, levelValue)
.in(levelType.equals("group"), OrderInfo::getOrgGroupId, levelValue)
.groupBy(OrderInfo::getSkill);
List<Map<String, Object>> results = orderInfoMPDao.selectMaps(wrapper);
for (Map<String, Object> result : results) {
String skill = (String) result.get("skill");
Long countValue = (Long) result.get("count");
Integer count = countValue.intValue();
String skillCategory = skillMap.get(skill);
Integer value = map.getOrDefault(skillCategory, 0);
value = value + count;
map.put(skillCategory, value);
}
return map;
}
private HashMap<Integer, Integer> queryCountByGroupId(LocalDate date, String levelType, List<String> levelValue) {
HashMap<Integer, Integer> map = new HashMap<>();
HashMap<String, Integer> groupCategoryMapping = this.getGroupCategoryMapping(levelType, levelValue);
QueryWrapper<OrderInfo> wrapper = new QueryWrapper<>();
wrapper.select("org_group_id, COUNT(*) as count")
.lambda()
.eq(OrderInfo::getDt, date)
.in(levelType.equals("cluster"), OrderInfo::getOrgClusterId, levelValue)
.in(levelType.equals("branch"), OrderInfo::getOrgBranchId, levelValue)
.in(levelType.equals("group"), OrderInfo::getOrgGroupId, levelValue)
.groupBy(OrderInfo::getOrgGroupId);
List<Map<String, Object>> results = orderInfoMPDao.selectMaps(wrapper);
for (Map<String, Object> result : results) {
String groupId = (String) result.get("org_group_id");
Long countValue = (Long) result.get("count");
Integer count = countValue.intValue();
Integer groupCategory = groupCategoryMapping.get(groupId);
Integer value = map.getOrDefault(groupCategory, 0);
value = value + count;
map.put(groupCategory, value);
}
return map;
}
private HashMap<String, Integer> queryCountByAppointment(LocalDate date, String levelType, List<String> levelValue) {
HashMap<String, Integer> map = new HashMap<>();
QueryWrapper<OrderInfo> wrapper = new QueryWrapper<>();
wrapper.select("appointment_method, appointment_status, COUNT(*) as count")
.lambda()
.eq(OrderInfo::getDt, date)
.in(levelType.equals("cluster"), OrderInfo::getOrgClusterId, levelValue)
.in(levelType.equals("branch"), OrderInfo::getOrgBranchId, levelValue)
.in(levelType.equals("group"), OrderInfo::getOrgGroupId, levelValue)
.groupBy(OrderInfo::getAppointmentMethod, OrderInfo::getAppointmentStatus);
List<Map<String, Object>> results = orderInfoMPDao.selectMaps(wrapper);
Integer autoTotal = 0;
Integer manualTotal = 0;
Integer notAssignTotal = 0;
for (Map<String, Object> result : results) {
String method = (String) result.get("appointment_method");
String status = (String) result.get("appointment_status");
Long countValue = (Long) result.get("count");
int count = countValue.intValue();
if (status.equals("NOT_ASSIGNED")) {
notAssignTotal += count;
continue;
}
if (method.equals("MANUAL")) {
manualTotal += count;
} else {
autoTotal += count;
}
}
map.put("autoTotal", autoTotal);
map.put("manualTotal", manualTotal);
map.put("notAssignTotal", notAssignTotal);
return map;
}
private HashMap<String, String> getSkillCategoryMapping() {
// 获取skill与skillCategory(面向前端)的映射
List<SkillInfoEntity> skillList = skillInfoDao.findAll();
return skillList.stream()
.collect(Collectors.toMap(
SkillInfoEntity::getSkill, SkillInfoEntity::getSkillCategory, (oldValue, newValue) -> newValue, HashMap::new));
}
private HashMap<String, Integer> getGroupCategoryMapping(String levelType, List<String> levelValue) {
HashMap<String, Integer> map = new HashMap<>();
List<OrgGroupEntity> groups = new ArrayList<>();
if (levelType.equals("cluster")) {
groups = orgGroupDao.findAllByClusterIdIn(levelValue);
} else if (levelType.equals("branch")) {
groups = orgGroupDao.findAllByBranchIdIn(levelValue);
} else if (levelType.equals("group")) {
groups = orgGroupDao.findAllByGroupIdIn(levelValue);
}
for (OrgGroupEntity g : groups) {
map.put(g.getGroupId(), g.getCategory());
}
return map;
}
private List<ScheduleSummaryResp.ValueDTO> packSkillSummary(HashMap<String, Integer> map) {
Integer sum = 0;
for (Map.Entry<String, Integer> entry : map.entrySet()) {
sum += entry.getValue();
}
String urlName = "DispatchBenchManage";
List<ScheduleSummaryResp.ValueDTO> items = new ArrayList<>();
items.add(new ScheduleSummaryResp.ValueDTO("总单量", sum, "#469967", urlName, new HashMap<>()));
HashMap<String, List<String>> p1 = this.packParams("skillCategory", "安装");
items.add(new ScheduleSummaryResp.ValueDTO("安装", map.getOrDefault("安装", 0), null, urlName, p1));
HashMap<String, List<String>> p2 = this.packParams("skillCategory", "维修");
items.add(new ScheduleSummaryResp.ValueDTO("维修", map.getOrDefault("维修", 0), null, urlName, p2));
HashMap<String, List<String>> p3 = this.packParams("skillCategory", "清洁保养");
items.add(new ScheduleSummaryResp.ValueDTO("清洁保养", map.getOrDefault("清洁保养", 0), null, urlName, p3));
HashMap<String, List<String>> p4 = this.packParams("skillCategory", "整改");
items.add(new ScheduleSummaryResp.ValueDTO("整改", map.getOrDefault("整改", 0), null, urlName, p4));
return items;
}
private List<ScheduleSummaryResp.ValueDTO> packGroupCategorySummary(HashMap<Integer, Integer> map) {
String urlName = "DispatchBenchManage";
List<ScheduleSummaryResp.ValueDTO> items = new ArrayList<>();
HashMap<String, List<Integer>> p1 = this.packParams("groupCategory", 1);
items.add(new ScheduleSummaryResp.ValueDTO("自有", map.getOrDefault(1, 0), null, urlName, p1));
HashMap<String, List<Integer>> p2 = this.packParams("groupCategory", 2);
items.add(new ScheduleSummaryResp.ValueDTO("网点", map.getOrDefault(2, 0), null, urlName, p2));
return items;
}
private List<ScheduleSummaryResp.ValueDTO> packAppointmentSummary(HashMap<String, Integer> map) {
String urlName = "DispatchBenchManage";
List<ScheduleSummaryResp.ValueDTO> items = new ArrayList<>();
HashMap<String, List<String>> p1 = this.packParams("appointmentType", "AUTO_NOW", "AUTO_BATCH");
items.add(new ScheduleSummaryResp.ValueDTO("自动指派", map.getOrDefault("autoTotal", 0), null, urlName, p1));
HashMap<String, List<String>> p2 = this.packParams("appointmentType", "MANUAL");
items.add(new ScheduleSummaryResp.ValueDTO("人工指派", map.getOrDefault("manualTotal", 0), null, urlName, p2));
HashMap<String, List<String>> p3 = this.packParams("appointmentStatus", "NOT_ASSIGNED");
items.add(new ScheduleSummaryResp.ValueDTO("未指派", map.getOrDefault("notAssignTotal", 0), null, urlName, p3));
return items;
}
private <T> HashMap<String, List<T>> packParams(String key, T... values) {
HashMap<String, List<T>> map = new HashMap<>();
List<T> value = new ArrayList<>();
Collections.addAll(value, values);
map.put(key, value);
return map;
}
}
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!