|
@@ -0,0 +1,258 @@
|
|
|
|
|
+package work.baiyun.chronicdiseaseapp.service.impl;
|
|
|
|
|
+
|
|
|
|
|
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
|
|
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|
|
|
|
+import org.slf4j.Logger;
|
|
|
|
|
+import org.slf4j.LoggerFactory;
|
|
|
|
|
+import org.springframework.beans.BeanUtils;
|
|
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
|
|
+import work.baiyun.chronicdiseaseapp.enums.ErrorCode;
|
|
|
|
|
+import work.baiyun.chronicdiseaseapp.exception.CustomException;
|
|
|
|
|
+import work.baiyun.chronicdiseaseapp.mapper.MessageMapper;
|
|
|
|
|
+import work.baiyun.chronicdiseaseapp.mapper.UserInfoMapper;
|
|
|
|
|
+import work.baiyun.chronicdiseaseapp.model.po.MessagePO;
|
|
|
|
|
+import work.baiyun.chronicdiseaseapp.model.po.UserInfo;
|
|
|
|
|
+import work.baiyun.chronicdiseaseapp.model.vo.DoctorPatientMessagesVO;
|
|
|
|
|
+import work.baiyun.chronicdiseaseapp.model.vo.MessageVO;
|
|
|
|
|
+import work.baiyun.chronicdiseaseapp.model.vo.SendMessageRequest;
|
|
|
|
|
+import work.baiyun.chronicdiseaseapp.model.vo.SystemAnomalySendRequest;
|
|
|
|
|
+import work.baiyun.chronicdiseaseapp.model.vo.SystemDailySendRequest;
|
|
|
|
|
+import work.baiyun.chronicdiseaseapp.service.MessageService;
|
|
|
|
|
+import work.baiyun.chronicdiseaseapp.service.UserBindingService;
|
|
|
|
|
+import work.baiyun.chronicdiseaseapp.enums.MessageType;
|
|
|
|
|
+import work.baiyun.chronicdiseaseapp.util.SecurityUtils;
|
|
|
|
|
+
|
|
|
|
|
+import java.time.LocalDateTime;
|
|
|
|
|
+import java.util.List;
|
|
|
|
|
+
|
|
|
|
|
+@Service
|
|
|
|
|
+public class MessageServiceImpl implements MessageService {
|
|
|
|
|
+
|
|
|
|
|
+ private static final Logger logger = LoggerFactory.getLogger(MessageServiceImpl.class);
|
|
|
|
|
+
|
|
|
|
|
+ @Autowired
|
|
|
|
|
+ private MessageMapper messageMapper;
|
|
|
|
|
+
|
|
|
|
|
+ @Autowired
|
|
|
|
|
+ private UserInfoMapper userInfoMapper;
|
|
|
|
|
+
|
|
|
|
|
+ @Autowired
|
|
|
|
|
+ private UserBindingService userBindingService;
|
|
|
|
|
+
|
|
|
|
|
+ // TODO: 注入推送服务,如果有的话
|
|
|
|
|
+ // @Autowired
|
|
|
|
|
+ // private PushService pushService;
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public String sendMessage(SendMessageRequest request) {
|
|
|
|
|
+ Long currentUserId = SecurityUtils.getCurrentUserId();
|
|
|
|
|
+ // 校验权限:医生
|
|
|
|
|
+ // TODO: 添加权限校验
|
|
|
|
|
+
|
|
|
|
|
+ // 首先处理直接接收者
|
|
|
|
|
+ for (Long receiverId : request.getReceiverIds()) {
|
|
|
|
|
+ MessagePO message = new MessagePO();
|
|
|
|
|
+ BeanUtils.copyProperties(request, message);
|
|
|
|
|
+ message.setSenderId(currentUserId);
|
|
|
|
|
+ message.setReceiverId(receiverId);
|
|
|
|
|
+ message.setContentFormat(request.getContentFormat() != null ? request.getContentFormat() : "PLAIN");
|
|
|
|
|
+ message.setNotifyPopup(request.getNotifyPopup() != null ? (byte) (request.getNotifyPopup() ? 1 : 0) : 0);
|
|
|
|
|
+ message.setNotifySubscribe(request.getNotifySubscribe() != null ? (byte) (request.getNotifySubscribe() ? 1 : 0) : 0);
|
|
|
|
|
+ message.setStatus((byte) 0); // 未读
|
|
|
|
|
+ messageMapper.insert(message);
|
|
|
|
|
+
|
|
|
|
|
+ // 推送通知
|
|
|
|
|
+ if (message.getNotifySubscribe() == 1) {
|
|
|
|
|
+ // TODO: 调用推送服务
|
|
|
|
|
+ // pushService.sendSubscribeMessage(receiverId, message);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ logger.info("[MessageOperation] userId={}, action=send, messageId={}", currentUserId, message.getId());
|
|
|
|
|
+
|
|
|
|
|
+ // 如果勾选了通知家属,则为该病人的家属也发送消息
|
|
|
|
|
+ if (request.getNotifyFamily() != null && request.getNotifyFamily()) {
|
|
|
|
|
+ List<Long> familyIds = userBindingService.getBoundFamilyIds(receiverId);
|
|
|
|
|
+ for (Long familyId : familyIds) {
|
|
|
|
|
+ MessagePO familyMessage = new MessagePO();
|
|
|
|
|
+ BeanUtils.copyProperties(request, familyMessage);
|
|
|
|
|
+ familyMessage.setSenderId(currentUserId);
|
|
|
|
|
+ familyMessage.setReceiverId(familyId);
|
|
|
|
|
+ familyMessage.setContentFormat(request.getContentFormat() != null ? request.getContentFormat() : "PLAIN");
|
|
|
|
|
+ familyMessage.setNotifyPopup(request.getNotifyPopup() != null ? (byte) (request.getNotifyPopup() ? 1 : 0) : 0);
|
|
|
|
|
+ familyMessage.setNotifySubscribe(request.getNotifySubscribe() != null ? (byte) (request.getNotifySubscribe() ? 1 : 0) : 0);
|
|
|
|
|
+ familyMessage.setStatus((byte) 0); // 未读
|
|
|
|
|
+ messageMapper.insert(familyMessage);
|
|
|
|
|
+
|
|
|
|
|
+ // 推送通知给家属
|
|
|
|
|
+ if (familyMessage.getNotifySubscribe() == 1) {
|
|
|
|
|
+ // TODO: 调用推送服务
|
|
|
|
|
+ // pushService.sendSubscribeMessage(familyId, familyMessage);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ logger.info("[MessageOperation] userId={}, action=send_to_family, patientId={}, familyId={}, messageId={}",
|
|
|
|
|
+ currentUserId, receiverId, familyId, familyMessage.getId());
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 返回最后一个消息ID
|
|
|
|
|
+ return "消息发送成功"; // 或返回ID列表
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public String sendSystemDailyMessage(SystemDailySendRequest request) {
|
|
|
|
|
+ // 系统发送,senderId=0
|
|
|
|
|
+ for (Long receiverId : request.getReceiverIds()) {
|
|
|
|
|
+ MessagePO message = new MessagePO();
|
|
|
|
|
+ message.setSenderId(0L);
|
|
|
|
|
+ message.setReceiverId(receiverId);
|
|
|
|
|
+ message.setContent(request.getContent());
|
|
|
|
|
+ message.setContentFormat("PLAIN");
|
|
|
|
|
+ message.setType(request.getType());
|
|
|
|
|
+ message.setNotifyPopup((byte) 0);
|
|
|
|
|
+ message.setNotifySubscribe((byte) 0);
|
|
|
|
|
+ message.setStatus((byte) 0);
|
|
|
|
|
+ messageMapper.insert(message);
|
|
|
|
|
+
|
|
|
|
|
+ logger.info("[MessageOperation] action=system_daily_send, messageId={}", message.getId());
|
|
|
|
|
+ }
|
|
|
|
|
+ return "系统日常消息发送成功";
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public String sendSystemAnomalyMessage(SystemAnomalySendRequest request) {
|
|
|
|
|
+ MessagePO message = new MessagePO();
|
|
|
|
|
+ message.setSenderId(0L);
|
|
|
|
|
+ message.setReceiverId(request.getPatientId());
|
|
|
|
|
+ message.setContent("检测到异常数据: " + request.getAnomalyData().toString()); // 简化
|
|
|
|
|
+ message.setContentFormat("PLAIN");
|
|
|
|
|
+ message.setType(request.getType());
|
|
|
|
|
+ message.setNotifyPopup((byte) 1); // 弹窗
|
|
|
|
|
+ message.setNotifySubscribe((byte) 1); // 推送
|
|
|
|
|
+ message.setStatus((byte) 0);
|
|
|
|
|
+ messageMapper.insert(message);
|
|
|
|
|
+
|
|
|
|
|
+ // 推送
|
|
|
|
|
+ // TODO: pushService.sendSubscribeMessage(request.getPatientId(), message);
|
|
|
|
|
+
|
|
|
|
|
+ logger.info("[MessageOperation] action=system_anomaly_send, messageId={}", message.getId());
|
|
|
|
|
+ return message.getId().toString();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public Page<MessageVO> listMessages(int page, int size, Byte status) {
|
|
|
|
|
+ Long currentUserId = SecurityUtils.getCurrentUserId();
|
|
|
|
|
+ LambdaQueryWrapper<MessagePO> wrapper = new LambdaQueryWrapper<>();
|
|
|
|
|
+ wrapper.eq(MessagePO::getReceiverId, currentUserId);
|
|
|
|
|
+ if (status != null) {
|
|
|
|
|
+ wrapper.eq(MessagePO::getStatus, status);
|
|
|
|
|
+ }
|
|
|
|
|
+ wrapper.orderByDesc(MessagePO::getCreateTime);
|
|
|
|
|
+
|
|
|
|
|
+ Page<MessagePO> poPage = messageMapper.selectPage(new Page<>(page, size), wrapper);
|
|
|
|
|
+ Page<MessageVO> voPage = new Page<>(page, size, poPage.getTotal());
|
|
|
|
|
+
|
|
|
|
|
+ List<MessageVO> voList = poPage.getRecords().stream().map(this::convertToVO).collect(java.util.stream.Collectors.toList());
|
|
|
|
|
+ voPage.setRecords(voList);
|
|
|
|
|
+
|
|
|
|
|
+ return voPage;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public MessageVO getMessageById(Long id) {
|
|
|
|
|
+ Long currentUserId = SecurityUtils.getCurrentUserId();
|
|
|
|
|
+ MessagePO message = messageMapper.selectById(id);
|
|
|
|
|
+ if (message == null || !message.getReceiverId().equals(currentUserId)) {
|
|
|
|
|
+ throw new CustomException(ErrorCode.PARAMETER_ERROR.getCode(), "消息不存在或无权限");
|
|
|
|
|
+ }
|
|
|
|
|
+ return convertToVO(message);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public void markAsRead(Long id) {
|
|
|
|
|
+ Long currentUserId = SecurityUtils.getCurrentUserId();
|
|
|
|
|
+ MessagePO message = messageMapper.selectById(id);
|
|
|
|
|
+ if (message == null || !message.getReceiverId().equals(currentUserId)) {
|
|
|
|
|
+ throw new CustomException(ErrorCode.PARAMETER_ERROR.getCode(), "消息不存在或无权限");
|
|
|
|
|
+ }
|
|
|
|
|
+ message.setStatus((byte) 1);
|
|
|
|
|
+ message.setReadTime(LocalDateTime.now());
|
|
|
|
|
+ messageMapper.updateById(message);
|
|
|
|
|
+ logger.info("[MessageOperation] userId={}, action=read, messageId={}", currentUserId, id);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public void deleteMessage(Long id) {
|
|
|
|
|
+ Long currentUserId = SecurityUtils.getCurrentUserId();
|
|
|
|
|
+ MessagePO message = messageMapper.selectById(id);
|
|
|
|
|
+ if (message == null || !message.getReceiverId().equals(currentUserId)) {
|
|
|
|
|
+ throw new CustomException(ErrorCode.PARAMETER_ERROR.getCode(), "消息不存在或无权限");
|
|
|
|
|
+ }
|
|
|
|
|
+ messageMapper.deleteById(id);
|
|
|
|
|
+ logger.info("[MessageOperation] userId={}, action=delete, messageId={}", currentUserId, id);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public Integer getUnreadCount() {
|
|
|
|
|
+ Long currentUserId = SecurityUtils.getCurrentUserId();
|
|
|
|
|
+ LambdaQueryWrapper<MessagePO> wrapper = new LambdaQueryWrapper<>();
|
|
|
|
|
+ wrapper.eq(MessagePO::getReceiverId, currentUserId);
|
|
|
|
|
+ wrapper.eq(MessagePO::getStatus, (byte) 0);
|
|
|
|
|
+ return Math.toIntExact(messageMapper.selectCount(wrapper));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private MessageVO convertToVO(MessagePO po) {
|
|
|
|
|
+ MessageVO vo = new MessageVO();
|
|
|
|
|
+ BeanUtils.copyProperties(po, vo);
|
|
|
|
|
+ vo.setId(po.getId().toString());
|
|
|
|
|
+ vo.setSenderId(po.getSenderId().toString());
|
|
|
|
|
+ vo.setReceiverId(po.getReceiverId().toString());
|
|
|
|
|
+ vo.setNotifyPopup(po.getNotifyPopup() != 0);
|
|
|
|
|
+ vo.setNotifySubscribe(po.getNotifySubscribe() != 0);
|
|
|
|
|
+
|
|
|
|
|
+ // 获取发送者姓名
|
|
|
|
|
+ if (po.getSenderId() != 0) {
|
|
|
|
|
+ UserInfo user = userInfoMapper.selectById(po.getSenderId());
|
|
|
|
|
+ if (user != null) {
|
|
|
|
|
+ vo.setSenderName(user.getNickname());
|
|
|
|
|
+ }
|
|
|
|
|
+ } else {
|
|
|
|
|
+ vo.setSenderName("系统");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return vo;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public DoctorPatientMessagesVO getPatientAndFamilyMessages(Long patientId) {
|
|
|
|
|
+ DoctorPatientMessagesVO result = new DoctorPatientMessagesVO();
|
|
|
|
|
+
|
|
|
|
|
+ // 获取患者的消息
|
|
|
|
|
+ LambdaQueryWrapper<MessagePO> patientWrapper = new LambdaQueryWrapper<>();
|
|
|
|
|
+ patientWrapper.eq(MessagePO::getReceiverId, patientId);
|
|
|
|
|
+ patientWrapper.orderByDesc(MessagePO::getCreateTime);
|
|
|
|
|
+ List<MessagePO> patientMessagePOs = messageMapper.selectList(patientWrapper);
|
|
|
|
|
+ List<MessageVO> patientMessages = patientMessagePOs.stream()
|
|
|
|
|
+ .map(this::convertToVO)
|
|
|
|
|
+ .collect(java.util.stream.Collectors.toList());
|
|
|
|
|
+ result.setPatientMessages(patientMessages);
|
|
|
|
|
+
|
|
|
|
|
+ // 获取家属的消息
|
|
|
|
|
+ List<Long> familyIds = userBindingService.getBoundFamilyIds(patientId);
|
|
|
|
|
+ if (!familyIds.isEmpty()) {
|
|
|
|
|
+ LambdaQueryWrapper<MessagePO> familyWrapper = new LambdaQueryWrapper<>();
|
|
|
|
|
+ familyWrapper.in(MessagePO::getReceiverId, familyIds);
|
|
|
|
|
+ familyWrapper.orderByDesc(MessagePO::getCreateTime);
|
|
|
|
|
+ List<MessagePO> familyMessagePOs = messageMapper.selectList(familyWrapper);
|
|
|
|
|
+ List<MessageVO> familyMessages = familyMessagePOs.stream()
|
|
|
|
|
+ .map(this::convertToVO)
|
|
|
|
|
+ .collect(java.util.stream.Collectors.toList());
|
|
|
|
|
+ result.setFamilyMessages(familyMessages);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ result.setFamilyMessages(java.util.Collections.emptyList());
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return result;
|
|
|
|
|
+ }
|
|
|
|
|
+}
|