chore: 【ops】保洁员业务领域调整
This commit is contained in:
@@ -0,0 +1,370 @@
|
||||
package com.viewsh.module.ops.environment.domain.cleaner;
|
||||
|
||||
import com.viewsh.module.ops.core.dispatch.model.AssigneeStatus;
|
||||
import com.viewsh.module.ops.environment.integration.adapter.CleanerAssigneeStatusAdapter;
|
||||
import com.viewsh.module.ops.enums.PriorityEnum;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 保洁员领域服务接口
|
||||
* <p>
|
||||
* 职责:
|
||||
* 1. 保洁员状态管理
|
||||
* 2. 保洁员可用性查询
|
||||
* 3. 保洁员工作量统计
|
||||
* <p>
|
||||
* 设计说明:
|
||||
* - 业务层领域服务,处理保洁业务特定逻辑
|
||||
* - 通过 {@link AssigneeStatus} 接口与通用调度引擎解耦
|
||||
*
|
||||
* @author lzh
|
||||
*/
|
||||
public interface CleanerDomainService {
|
||||
|
||||
// ==================== 状态查询 ====================
|
||||
|
||||
/**
|
||||
* 获取保洁员状态(通用接口)
|
||||
*
|
||||
* @param userId 保洁员ID
|
||||
* @return 通用执行人状态接口
|
||||
*/
|
||||
AssigneeStatus getAssigneeStatus(Long userId);
|
||||
|
||||
/**
|
||||
* 获取保洁员当前工作量
|
||||
*
|
||||
* @param userId 保洁员ID
|
||||
* @return 工作量信息
|
||||
*/
|
||||
CleanerWorkload getWorkload(Long userId);
|
||||
|
||||
/**
|
||||
* 检查保洁员是否可用(可接新单)
|
||||
*
|
||||
* @param userId 保洁员ID
|
||||
* @return 是否可用
|
||||
*/
|
||||
boolean isAvailable(Long userId);
|
||||
|
||||
/**
|
||||
* 检查保洁员是否在线
|
||||
*
|
||||
* @param userId 保洁员ID
|
||||
* @return 是否在线
|
||||
*/
|
||||
boolean isOnline(Long userId);
|
||||
|
||||
// ==================== 保洁员查询 ====================
|
||||
|
||||
/**
|
||||
* 查询指定区域的保洁员列表
|
||||
*
|
||||
* @param areaId 区域ID
|
||||
* @return 保洁员列表(通用状态接口)
|
||||
*/
|
||||
List<AssigneeStatus> listByArea(Long areaId);
|
||||
|
||||
/**
|
||||
* 查询指定区域的可用保洁员
|
||||
*
|
||||
* @param areaId 区域ID
|
||||
* @return 可用保洁员列表
|
||||
*/
|
||||
List<AssigneeStatus> listAvailableByArea(Long areaId);
|
||||
|
||||
/**
|
||||
* 查询附近的保洁员
|
||||
*
|
||||
* @param areaId 中心区域ID
|
||||
* @param radius 搜索半径
|
||||
* @return 附近保洁员列表
|
||||
*/
|
||||
List<AssigneeStatus> listNearby(Long areaId, Integer radius);
|
||||
|
||||
/**
|
||||
* 根据条件推荐保洁员
|
||||
*
|
||||
* @param areaId 区域ID
|
||||
* @param priority 工单优先级
|
||||
* @param limit 最多返回数量
|
||||
* @return 推荐的保洁员列表
|
||||
*/
|
||||
List<CleanerRecommendation> recommend(Long areaId, PriorityEnum priority, int limit);
|
||||
|
||||
/**
|
||||
* 获取最佳保洁员
|
||||
*
|
||||
* @param areaId 区域ID
|
||||
* @param priority 工单优先级
|
||||
* @return 推荐结果,无合适保洁员返回null
|
||||
*/
|
||||
CleanerRecommendation getBestCleaner(Long areaId, PriorityEnum priority);
|
||||
|
||||
// ==================== 工作量统计 ====================
|
||||
|
||||
/**
|
||||
* 统计保洁员今日完成任务数
|
||||
*
|
||||
* @param userId 保洁员ID
|
||||
* @return 完成任务数
|
||||
*/
|
||||
int countCompletedToday(Long userId);
|
||||
|
||||
/**
|
||||
* 统计保洁员今日工作时长(分钟)
|
||||
*
|
||||
* @param userId 保洁员ID
|
||||
* @return 工作时长
|
||||
*/
|
||||
int getWorkMinutesToday(Long userId);
|
||||
|
||||
/**
|
||||
* 获取保洁员当前等待任务数
|
||||
*
|
||||
* @param userId 保洁员ID
|
||||
* @return 等待任务数
|
||||
*/
|
||||
int getWaitingTaskCount(Long userId);
|
||||
|
||||
// ==================== 状态更新(仅业务层调用)====================
|
||||
|
||||
/**
|
||||
* 设置保洁员当前工单
|
||||
*
|
||||
* @param userId 保洁员ID
|
||||
* @param orderId 工单ID
|
||||
* @param orderCode 工单编号
|
||||
*/
|
||||
void setCurrentWorkOrder(Long userId, Long orderId, String orderCode);
|
||||
|
||||
/**
|
||||
* 清理保洁员当前工单
|
||||
*
|
||||
* @param userId 保洁员ID
|
||||
*/
|
||||
void clearCurrentWorkOrder(Long userId);
|
||||
|
||||
/**
|
||||
* 更新保洁员当前位置
|
||||
*
|
||||
* @param userId 保洁员ID
|
||||
* @param areaId 区域ID
|
||||
* @param areaName 区域名称
|
||||
*/
|
||||
void updateCurrentArea(Long userId, Long areaId, String areaName);
|
||||
|
||||
// ==================== 内部类 ====================
|
||||
|
||||
/**
|
||||
* 保洁员工作量信息
|
||||
*/
|
||||
class CleanerWorkload {
|
||||
/**
|
||||
* 保洁员ID
|
||||
*/
|
||||
private Long userId;
|
||||
|
||||
/**
|
||||
* 保洁员姓名
|
||||
*/
|
||||
private String userName;
|
||||
|
||||
/**
|
||||
* 当前任务数
|
||||
*/
|
||||
private int currentTaskCount;
|
||||
|
||||
/**
|
||||
* 等待任务数
|
||||
*/
|
||||
private int waitingTaskCount;
|
||||
|
||||
/**
|
||||
* 今日完成任务数
|
||||
*/
|
||||
private int completedToday;
|
||||
|
||||
/**
|
||||
* 今日工作时长(分钟)
|
||||
*/
|
||||
private int workMinutesToday;
|
||||
|
||||
public CleanerWorkload() {
|
||||
}
|
||||
|
||||
public CleanerWorkload(Long userId, String userName, int currentTaskCount,
|
||||
int waitingTaskCount, int completedToday, int workMinutesToday) {
|
||||
this.userId = userId;
|
||||
this.userName = userName;
|
||||
this.currentTaskCount = currentTaskCount;
|
||||
this.waitingTaskCount = waitingTaskCount;
|
||||
this.completedToday = completedToday;
|
||||
this.workMinutesToday = workMinutesToday;
|
||||
}
|
||||
|
||||
public Long getUserId() {
|
||||
return userId;
|
||||
}
|
||||
|
||||
public void setUserId(Long userId) {
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
public String getUserName() {
|
||||
return userName;
|
||||
}
|
||||
|
||||
public void setUserName(String userName) {
|
||||
this.userName = userName;
|
||||
}
|
||||
|
||||
public int getCurrentTaskCount() {
|
||||
return currentTaskCount;
|
||||
}
|
||||
|
||||
public void setCurrentTaskCount(int currentTaskCount) {
|
||||
this.currentTaskCount = currentTaskCount;
|
||||
}
|
||||
|
||||
public int getWaitingTaskCount() {
|
||||
return waitingTaskCount;
|
||||
}
|
||||
|
||||
public void setWaitingTaskCount(int waitingTaskCount) {
|
||||
this.waitingTaskCount = waitingTaskCount;
|
||||
}
|
||||
|
||||
public int getCompletedToday() {
|
||||
return completedToday;
|
||||
}
|
||||
|
||||
public void setCompletedToday(int completedToday) {
|
||||
this.completedToday = completedToday;
|
||||
}
|
||||
|
||||
public int getWorkMinutesToday() {
|
||||
return workMinutesToday;
|
||||
}
|
||||
|
||||
public void setWorkMinutesToday(int workMinutesToday) {
|
||||
this.workMinutesToday = workMinutesToday;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取总任务数(当前+等待)
|
||||
*/
|
||||
public int getTotalTaskCount() {
|
||||
return currentTaskCount + waitingTaskCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否忙碌
|
||||
*/
|
||||
public boolean isBusy() {
|
||||
return currentTaskCount > 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 保洁员推荐结果
|
||||
*/
|
||||
class CleanerRecommendation {
|
||||
/**
|
||||
* 保洁员ID
|
||||
*/
|
||||
private Long userId;
|
||||
|
||||
/**
|
||||
* 保洁员姓名
|
||||
*/
|
||||
private String userName;
|
||||
|
||||
/**
|
||||
* 推荐分数(0-100)
|
||||
*/
|
||||
private int score;
|
||||
|
||||
/**
|
||||
* 推荐理由
|
||||
*/
|
||||
private String reason;
|
||||
|
||||
/**
|
||||
* 电量
|
||||
*/
|
||||
private Integer batteryLevel;
|
||||
|
||||
/**
|
||||
* 状态
|
||||
*/
|
||||
private String status;
|
||||
|
||||
public CleanerRecommendation() {
|
||||
}
|
||||
|
||||
public CleanerRecommendation(Long userId, String userName, int score, String reason) {
|
||||
this.userId = userId;
|
||||
this.userName = userName;
|
||||
this.score = score;
|
||||
this.reason = reason;
|
||||
}
|
||||
|
||||
public static CleanerRecommendation of(Long userId, String userName, int score, String reason) {
|
||||
return new CleanerRecommendation(userId, userName, score, reason);
|
||||
}
|
||||
|
||||
public static CleanerRecommendation none() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Long getUserId() {
|
||||
return userId;
|
||||
}
|
||||
|
||||
public void setUserId(Long userId) {
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
public String getUserName() {
|
||||
return userName;
|
||||
}
|
||||
|
||||
public void setUserName(String userName) {
|
||||
this.userName = userName;
|
||||
}
|
||||
|
||||
public int getScore() {
|
||||
return score;
|
||||
}
|
||||
|
||||
public void setScore(int score) {
|
||||
this.score = score;
|
||||
}
|
||||
|
||||
public String getReason() {
|
||||
return reason;
|
||||
}
|
||||
|
||||
public void setReason(String reason) {
|
||||
this.reason = reason;
|
||||
}
|
||||
|
||||
public Integer getBatteryLevel() {
|
||||
return batteryLevel;
|
||||
}
|
||||
|
||||
public void setBatteryLevel(Integer batteryLevel) {
|
||||
this.batteryLevel = batteryLevel;
|
||||
}
|
||||
|
||||
public String getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(String status) {
|
||||
this.status = status;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,325 @@
|
||||
package com.viewsh.module.ops.environment.domain.cleaner;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.viewsh.module.ops.api.queue.OrderQueueDTO;
|
||||
import com.viewsh.module.ops.api.queue.OrderQueueService;
|
||||
import com.viewsh.module.ops.core.dispatch.model.AssigneeStatus;
|
||||
import com.viewsh.module.ops.environment.dal.dataobject.cleaner.OpsCleanerStatusDO;
|
||||
import com.viewsh.module.ops.dal.dataobject.workorder.OpsOrderDO;
|
||||
import com.viewsh.module.ops.dal.mysql.workorder.OpsOrderMapper;
|
||||
import com.viewsh.module.ops.enums.CleanerStatusEnum;
|
||||
import com.viewsh.module.ops.enums.PriorityEnum;
|
||||
import com.viewsh.module.ops.enums.WorkOrderStatusEnum;
|
||||
import com.viewsh.module.ops.environment.integration.adapter.CleanerAssigneeStatusAdapter;
|
||||
import com.viewsh.module.ops.environment.service.cleaner.CleanerStatusService;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 保洁员领域服务实现
|
||||
* <p>
|
||||
* 职责:
|
||||
* 1. 保洁员状态管理
|
||||
* 2. 保洁员可用性查询
|
||||
* 3. 保洁员工作量统计
|
||||
* <p>
|
||||
* 设计说明:
|
||||
* - 业务层领域服务,处理保洁业务特定逻辑
|
||||
* - 通过 {@link AssigneeStatus} 接口与通用调度引擎解耦
|
||||
* - 使用 {@link CleanerAssigneeStatusAdapter} 适配保洁员状态到通用接口
|
||||
*
|
||||
* @author lzh
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
public class CleanerDomainServiceImpl implements CleanerDomainService {
|
||||
|
||||
@Resource
|
||||
private CleanerStatusService cleanerStatusService;
|
||||
|
||||
@Resource
|
||||
private OrderQueueService orderQueueService;
|
||||
|
||||
@Resource
|
||||
private OpsOrderMapper orderMapper;
|
||||
|
||||
// ==================== 状态查询 ====================
|
||||
|
||||
@Override
|
||||
public AssigneeStatus getAssigneeStatus(Long userId) {
|
||||
OpsCleanerStatusDO cleanerStatus = cleanerStatusService.getStatus(userId);
|
||||
if (cleanerStatus == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// 获取等待任务数
|
||||
int waitingCount = getWaitingTaskCount(userId);
|
||||
|
||||
return new CleanerAssigneeStatusAdapter(cleanerStatus, (long) waitingCount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CleanerWorkload getWorkload(Long userId) {
|
||||
OpsCleanerStatusDO cleanerStatus = cleanerStatusService.getStatus(userId);
|
||||
if (cleanerStatus == null) {
|
||||
return new CleanerWorkload();
|
||||
}
|
||||
|
||||
// 获取等待任务数
|
||||
int waitingCount = getWaitingTaskCount(userId);
|
||||
|
||||
// 统计今日完成任务数
|
||||
int completedToday = countCompletedToday(userId);
|
||||
|
||||
// 统计今日工作时长
|
||||
int workMinutes = getWorkMinutesToday(userId);
|
||||
|
||||
return new CleanerWorkload(
|
||||
userId,
|
||||
cleanerStatus.getUserName(),
|
||||
cleanerStatus.getCurrentOpsOrderId() != null ? 1 : 0,
|
||||
waitingCount,
|
||||
completedToday,
|
||||
workMinutes
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable(Long userId) {
|
||||
OpsCleanerStatusDO cleanerStatus = cleanerStatusService.getStatus(userId);
|
||||
if (cleanerStatus == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
CleanerStatusEnum statusEnum = cleanerStatus.getStatusEnum();
|
||||
return statusEnum != null && statusEnum.isCanAcceptNewOrder();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOnline(Long userId) {
|
||||
return cleanerStatusService.isOnline(userId);
|
||||
}
|
||||
|
||||
// ==================== 保洁员查询 ====================
|
||||
|
||||
@Override
|
||||
public List<AssigneeStatus> listByArea(Long areaId) {
|
||||
List<OpsCleanerStatusDO> cleaners = cleanerStatusService.listCleanersByArea(areaId);
|
||||
|
||||
return cleaners.stream()
|
||||
.map(cleaner -> {
|
||||
int waitingCount = getWaitingTaskCount(cleaner.getUserId());
|
||||
return new CleanerAssigneeStatusAdapter(cleaner, (long) waitingCount);
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<AssigneeStatus> listAvailableByArea(Long areaId) {
|
||||
List<OpsCleanerStatusDO> cleaners = cleanerStatusService.listAvailableCleaners(areaId);
|
||||
|
||||
return cleaners.stream()
|
||||
.map(cleaner -> {
|
||||
int waitingCount = getWaitingTaskCount(cleaner.getUserId());
|
||||
return new CleanerAssigneeStatusAdapter(cleaner, (long) waitingCount);
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<AssigneeStatus> listNearby(Long areaId, Integer radius) {
|
||||
// TODO: 实现基于地理位置的附近查询
|
||||
// 目前简化为按区域查询
|
||||
return listByArea(areaId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CleanerRecommendation> recommend(Long areaId, PriorityEnum priority, int limit) {
|
||||
List<OpsCleanerStatusDO> cleaners = cleanerStatusService.listCleanersByArea(areaId);
|
||||
if (cleaners.isEmpty()) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
// 过滤在线的保洁员
|
||||
List<OpsCleanerStatusDO> onlineCleaners = cleaners.stream()
|
||||
.filter(c -> CleanerStatusEnum.OFFLINE != c.getStatusEnum())
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// 按分数排序
|
||||
return onlineCleaners.stream()
|
||||
.limit(limit)
|
||||
.map(cleaner -> {
|
||||
int score = calculateScore(cleaner);
|
||||
String reason = buildRecommendationReason(cleaner);
|
||||
return CleanerRecommendation.of(
|
||||
cleaner.getUserId(),
|
||||
cleaner.getUserName(),
|
||||
score,
|
||||
reason
|
||||
);
|
||||
})
|
||||
.sorted((a, b) -> Integer.compare(b.getScore(), a.getScore()))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CleanerRecommendation getBestCleaner(Long areaId, PriorityEnum priority) {
|
||||
List<CleanerRecommendation> recommendations = recommend(areaId, priority, 1);
|
||||
return recommendations.isEmpty() ? null : recommendations.get(0);
|
||||
}
|
||||
|
||||
// ==================== 工作量统计 ====================
|
||||
|
||||
@Override
|
||||
public int countCompletedToday(Long userId) {
|
||||
LocalDate today = LocalDate.now();
|
||||
LocalDateTime startOfDay = today.atStartOfDay();
|
||||
LocalDateTime endOfDay = today.plusDays(1).atStartOfDay();
|
||||
|
||||
// 查询今日完成的保洁工单
|
||||
// LambdaQueryWrapper<OpsOrderDO> queryWrapper = new LambdaQueryWrapper<>();
|
||||
// queryWrapper.eq(OpsOrderDO::getAssigneeId, userId)
|
||||
// .eq(OpsOrderDO::getOrderType, "CLEAN")
|
||||
// .eq(OpsOrderDO::getStatus, WorkOrderStatusEnum.COMPLETED.getStatus())
|
||||
// .ge(OpsOrderDO::getCompletionTime, startOfDay)
|
||||
// .lt(OpsOrderDO::getCompletionTime, endOfDay);
|
||||
|
||||
// return orderMapper.selectCount(queryWrapper);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getWorkMinutesToday(Long userId) {
|
||||
LocalDate today = LocalDate.now();
|
||||
LocalDateTime startOfDay = today.atStartOfDay();
|
||||
LocalDateTime endOfDay = today.plusDays(1).atStartOfDay();
|
||||
|
||||
// 查询今日完成的保洁工单
|
||||
// LambdaQueryWrapper<OpsOrderDO> queryWrapper = new LambdaQueryWrapper<>();
|
||||
// queryWrapper.eq(OpsOrderDO::getAssigneeId, userId)
|
||||
// .eq(OpsOrderDO::getOrderType, "CLEAN")
|
||||
// .eq(OpsOrderDO::getStatus, WorkOrderStatusEnum.COMPLETED.getStatus())
|
||||
// .ge(OpsOrderDO::getCompletionTime, startOfDay)
|
||||
// .lt(OpsOrderDO::getCompletionTime, endOfDay)
|
||||
// .isNotNull(OpsOrderDO::getCompletionTime)
|
||||
// .isNotNull(OpsOrderDO::getDispatchTime);
|
||||
|
||||
// List<OpsOrderDO> orders = orderMapper.selectList(queryWrapper);
|
||||
|
||||
// 计算总工作时长(分钟)
|
||||
int totalMinutes = 0;
|
||||
// for (OpsOrderDO order : orders) {
|
||||
// if (order.getDispatchTime() != null && order.getCompletionTime() != null) {
|
||||
// long minutes = Duration.between(order.getDispatchTime(), order.getCompletionTime()).toMinutes();
|
||||
// totalMinutes += minutes;
|
||||
// }
|
||||
// }
|
||||
|
||||
return totalMinutes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getWaitingTaskCount(Long userId) {
|
||||
try {
|
||||
List<OrderQueueDTO> waitingTasks = orderQueueService.getWaitingTasksByUserId(userId);
|
||||
return waitingTasks != null ? waitingTasks.size() : 0;
|
||||
} catch (Exception e) {
|
||||
log.warn("查询等待任务数量失败: userId={}", userId, e);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// ==================== 状态更新 ====================
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void setCurrentWorkOrder(Long userId, Long orderId, String orderCode) {
|
||||
cleanerStatusService.setCurrentWorkOrder(userId, orderId, orderCode);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void clearCurrentWorkOrder(Long userId) {
|
||||
cleanerStatusService.clearCurrentWorkOrder(userId);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void updateCurrentArea(Long userId, Long areaId, String areaName) {
|
||||
cleanerStatusService.updateCurrentArea(userId, areaId, areaName);
|
||||
}
|
||||
|
||||
// ==================== 私有方法 ====================
|
||||
|
||||
/**
|
||||
* 计算推荐分数(0-100)
|
||||
*/
|
||||
private int calculateScore(OpsCleanerStatusDO cleaner) {
|
||||
int score = 50; // 基础分
|
||||
|
||||
CleanerStatusEnum statusEnum = cleaner.getStatusEnum();
|
||||
|
||||
// 状态分数
|
||||
if (statusEnum == CleanerStatusEnum.IDLE) {
|
||||
score += 30;
|
||||
} else if (statusEnum == CleanerStatusEnum.BUSY) {
|
||||
score += 10;
|
||||
}
|
||||
|
||||
// 电量分数
|
||||
if (cleaner.getBatteryLevel() != null) {
|
||||
if (cleaner.getBatteryLevel() > 80) {
|
||||
score += 15;
|
||||
} else if (cleaner.getBatteryLevel() > 50) {
|
||||
score += 10;
|
||||
} else if (cleaner.getBatteryLevel() > 20) {
|
||||
score += 5;
|
||||
}
|
||||
}
|
||||
|
||||
// 心跳分数
|
||||
if (cleaner.getLastHeartbeatTime() != null) {
|
||||
long minutesSinceHeartbeat = Duration.between(
|
||||
cleaner.getLastHeartbeatTime(),
|
||||
LocalDateTime.now()
|
||||
).toMinutes();
|
||||
if (minutesSinceHeartbeat < 5) {
|
||||
score += 5;
|
||||
}
|
||||
}
|
||||
|
||||
return Math.min(score, 100);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建推荐理由
|
||||
*/
|
||||
private String buildRecommendationReason(OpsCleanerStatusDO cleaner) {
|
||||
StringBuilder reason = new StringBuilder();
|
||||
|
||||
CleanerStatusEnum statusEnum = cleaner.getStatusEnum();
|
||||
if (statusEnum != null) {
|
||||
reason.append("状态=").append(statusEnum.getDescription());
|
||||
}
|
||||
|
||||
if (cleaner.getBatteryLevel() != null) {
|
||||
reason.append("、电量").append(cleaner.getBatteryLevel()).append("%");
|
||||
}
|
||||
|
||||
if (cleaner.getCurrentAreaName() != null) {
|
||||
reason.append("、位置=").append(cleaner.getCurrentAreaName());
|
||||
}
|
||||
|
||||
return reason.toString();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user