package com.tourguide.modules.system.service; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.tourguide.common.exception.BusinessException; import com.tourguide.modules.system.dto.GuideNotificationResponse; import com.tourguide.modules.system.entity.GuideNoticeRead; import com.tourguide.modules.system.entity.SystemNotice; import com.tourguide.modules.system.mapper.GuideNoticeReadMapper; import com.tourguide.modules.system.mapper.SystemNoticeMapper; import org.springframework.stereotype.Service; import java.time.LocalDateTime; import java.util.Collections; import java.util.List; import java.util.Set; import java.util.stream.Collectors; @Service public class GuideNotificationService { private final SystemNoticeMapper noticeMapper; private final GuideNoticeReadMapper readMapper; public GuideNotificationService(SystemNoticeMapper noticeMapper, GuideNoticeReadMapper readMapper) { this.noticeMapper = noticeMapper; this.readMapper = readMapper; } public long unreadCount(Long guideId) { List notices = publishedNotices(); if (notices.isEmpty()) return 0L; Set readIds = readNoticeIds(guideId, notices); return notices.stream().filter(notice -> !readIds.contains(notice.getId())).count(); } public List list(Long guideId) { List notices = publishedNotices(); Set readIds = readNoticeIds(guideId, notices); return notices.stream() .map(notice -> new GuideNotificationResponse(notice, readIds.contains(notice.getId()))) .collect(Collectors.toList()); } public void markRead(Long guideId, Long noticeId) { SystemNotice notice = noticeMapper.selectOne(new LambdaQueryWrapper() .eq(SystemNotice::getId, noticeId) .eq(SystemNotice::getStatus, 1) .last("LIMIT 1")); if (notice == null) throw new BusinessException(404, "Notification not found"); Long count = readMapper.selectCount(new LambdaQueryWrapper() .eq(GuideNoticeRead::getGuideId, guideId) .eq(GuideNoticeRead::getNoticeId, noticeId)); if (count > 0) return; GuideNoticeRead read = new GuideNoticeRead(); read.setGuideId(guideId); read.setNoticeId(noticeId); read.setReadAt(LocalDateTime.now()); readMapper.insert(read); } private List publishedNotices() { return noticeMapper.selectList(new LambdaQueryWrapper() .eq(SystemNotice::getStatus, 1) .isNotNull(SystemNotice::getPublishTime) .le(SystemNotice::getPublishTime, LocalDateTime.now()) .orderByDesc(SystemNotice::getPublishTime)); } private Set readNoticeIds(Long guideId, List notices) { if (notices.isEmpty()) return Collections.emptySet(); List noticeIds = notices.stream().map(SystemNotice::getId).collect(Collectors.toList()); return readMapper.selectList(new LambdaQueryWrapper() .eq(GuideNoticeRead::getGuideId, guideId) .in(GuideNoticeRead::getNoticeId, noticeIds)) .stream().map(GuideNoticeRead::getNoticeId).collect(Collectors.toSet()); } }