package com.xiaopeng.maintenance.schedule; import com.alibaba.fastjson2.JSONObject; import com.xiaopeng.api.dto.pushMessage.AliPushMessageDTO; import com.xiaopeng.api.feignClient.account.XpOperationUserClient; import com.xiaopeng.api.feignClient.pushMessage.XpAliPushMessageClient; import com.xiaopeng.api.feignClient.vehicleConvoy.XpVehicleClient; import com.xiaopeng.api.model.account.XpOperationsUser; import com.xiaopeng.api.model.account.XpOperationsUserNotification; import com.xiaopeng.api.model.vehicleConvoy.XpVehicle; import com.xiaopeng.common.core.constant.AliPushTypeConstant; import com.xiaopeng.common.core.domain.R; import com.xiaopeng.common.core.enums.TaskTypeNotificationEnum; import com.xiaopeng.common.core.utils.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Set; import java.util.stream.Collectors; /** * 事故任务通知支撑类 * *

用于事故任务相关定时通知的通用方法抽取。

* * @author mitao * @since 2026-03-14 */ @Component public class AccidentTaskNotificationSupport { private static final Logger log = LoggerFactory.getLogger(AccidentTaskNotificationSupport.class); @Autowired private XpOperationUserClient xpOperationUserClient; @Autowired private XpVehicleClient xpVehicleClient; @Autowired private XpAliPushMessageClient xpAliPushMessageClient; /** * 解析 handleUserId(逗号分隔) */ public Set parseUserIds(String handleUserId) { if (StringUtils.isBlank(handleUserId)) { return Collections.emptySet(); } String[] parts = handleUserId.split(","); Set userIds = new HashSet<>(); for (String part : parts) { if (StringUtils.isBlank(part)) { continue; } try { userIds.add(Long.valueOf(part.trim())); } catch (NumberFormatException e) { log.warn("任务接收人ID非法,handleUserId={}", handleUserId); } } return userIds; } /** * 获取运维人员信息 */ public Map fetchOperationUsers(Set userIds) { if (CollectionUtils.isEmpty(userIds)) { return Collections.emptyMap(); } try { R> result = xpOperationUserClient.listByIds(new ArrayList<>(userIds)); if (result == null || CollectionUtils.isEmpty(result.getData())) { return Collections.emptyMap(); } return result.getData().stream() .filter(Objects::nonNull) .filter(u -> u.getId() != null) .collect(Collectors.toMap(XpOperationsUser::getId, u -> u, (a, b) -> a)); } catch (Exception e) { log.error("获取运维人员信息失败", e); return Collections.emptyMap(); } } /** * 批量获取车辆信息 */ public Map fetchVehicles(Set vehicleIds) { if (CollectionUtils.isEmpty(vehicleIds)) { return Collections.emptyMap(); } try { R> result = xpVehicleClient.listByIds(new ArrayList<>(vehicleIds)); if (result == null || CollectionUtils.isEmpty(result.getData())) { return Collections.emptyMap(); } return result.getData().stream() .filter(Objects::nonNull) .filter(v -> v.getId() != null) .collect(Collectors.toMap(XpVehicle::getId, v -> v, (a, b) -> a)); } catch (Exception e) { log.error("获取车辆信息失败", e); return Collections.emptyMap(); } } /** * 构建推送 body JSON */ public String buildPushBodyJson(String content, Integer strategyCode, Long taskId) { Map param = new HashMap<>(); param.put("content", content); param.put("strategy", strategyCode); param.put("type", TaskTypeNotificationEnum.ACCIDENT_TASK.getCode()); param.put("id", taskId == null ? "0" : taskId.toString()); return JSONObject.toJSONString(param); } /** * 批量构建通知记录(包含 notificationExt) */ public List buildNotifications(List users, Integer notificationType, String content, Long taskId, String bodyJson) { if (CollectionUtils.isEmpty(users)) { return Collections.emptyList(); } List notifications = new ArrayList<>(); for (XpOperationsUser user : users) { if (user == null || user.getId() == null) { continue; } XpOperationsUserNotification notification = new XpOperationsUserNotification(); notification.setNotificationType(notificationType); notification.setNotificationContent(content); notification.setOperationsUserId(user.getId()); notification.setDataId(taskId == null ? 0L : taskId); notification.setReadStatus(0); notification.setNotificationExt(bodyJson); notifications.add(notification); } return notifications; } /** * 推送通知(按 deviceType 分组) */ public int pushToUsersByDeviceType(List users, String title, String bodyJson) { if (CollectionUtils.isEmpty(users)) { return 0; } Map> operationUserMap = users.stream() .filter(u -> u != null && u.getDeviceType() != null && StringUtils.isNotBlank(u.getPhoneNumber())) .collect(Collectors.groupingBy(XpOperationsUser::getDeviceType)); int pushCount = 0; for (Map.Entry> entry : operationUserMap.entrySet()) { List groupUsers = entry.getValue(); if (CollectionUtils.isEmpty(groupUsers)) { continue; } String account = groupUsers.stream() .map(XpOperationsUser::getPhoneNumber) .filter(StringUtils::isNotBlank) .collect(Collectors.joining(",")); if (StringUtils.isBlank(account)) { continue; } try { xpAliPushMessageClient.pushMessage(AliPushMessageDTO.builder() .body(bodyJson) .account(account) .title(title) .pushType(AliPushTypeConstant.NOTICE) .deviceType(entry.getKey()) .build()); pushCount++; } catch (Exception e) { log.error("事故任务推送失败,deviceType={}", entry.getKey(), e); } } return pushCount; } }