AdminMessageServiceImpl.java 6.86 KB
package com.diligrp.rider.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.diligrp.rider.common.exception.BizException;
import com.diligrp.rider.entity.Rider;
import com.diligrp.rider.entity.RiderMessage;
import com.diligrp.rider.entity.RiderMessageTemplate;
import com.diligrp.rider.mapper.RiderMapper;
import com.diligrp.rider.mapper.RiderMessageMapper;
import com.diligrp.rider.mapper.RiderMessageTemplateMapper;
import com.diligrp.rider.service.AdminMessageService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@Service
@RequiredArgsConstructor
public class AdminMessageServiceImpl implements AdminMessageService {

    private final RiderMessageMapper messageMapper;
    private final RiderMessageTemplateMapper templateMapper;
    private final RiderMapper riderMapper;

    private static final int PAGE_SIZE = 20;

    @Override
    @Transactional
    public void sendToRider(Long cityId, Long riderId, Integer type, String title, String content, String bizType, Long bizId) {
        ensureCitySelected(cityId);
        ensureRiderInCity(cityId, riderId);

        RiderMessage message = new RiderMessage();
        message.setCityId(cityId);
        message.setRiderId(riderId);
        message.setType(type);
        message.setTitle(title);
        message.setContent(content);
        message.setBizType(bizType != null ? bizType : "");
        message.setBizId(bizId != null ? bizId : 0L);
        message.setIsRead(0);
        message.setCreateTime(System.currentTimeMillis());
        message.setReadTime(0L);

        messageMapper.insert(message);
        log.info("发送消息成功,riderId={} messageId={}", riderId, message.getId());
    }

    @Override
    @Transactional
    public void broadcastToCity(Long cityId, Integer type, String title, String content) {
        ensureCitySelected(cityId);

        // 查询城市内所有正常状态的骑手
        LambdaQueryWrapper<Rider> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Rider::getCityId, cityId)
                .eq(Rider::getStatus, 1);  // 只发给正常状态的骑手
        List<Rider> riders = riderMapper.selectList(wrapper);

        if (riders.isEmpty()) {
            log.warn("城市内无可用骑手,cityId={}", cityId);
            return;
        }

        // 批量插入消息
        List<RiderMessage> messages = new ArrayList<>();
        long now = System.currentTimeMillis();
        for (Rider rider : riders) {
            RiderMessage message = new RiderMessage();
            message.setCityId(cityId);
            message.setRiderId(rider.getId());
            message.setType(type);
            message.setTitle(title);
            message.setContent(content);
            message.setBizType("broadcast");
            message.setBizId(0L);
            message.setIsRead(0);
            message.setCreateTime(now);
            message.setReadTime(0L);
            messages.add(message);
        }

        // 批量插入(每次最多1000条)
        int batchSize = 1000;
        for (int i = 0; i < messages.size(); i += batchSize) {
            int end = Math.min(i + batchSize, messages.size());
            List<RiderMessage> batch = messages.subList(i, end);
            batch.forEach(messageMapper::insert);
        }

        log.info("群发消息成功,cityId={} 骑手数={}", cityId, riders.size());
    }

    @Override
    public Map<String, Object> listMessages(Long cityId, Long riderId, Integer type, Integer page) {
        ensureCitySelected(cityId);

        Page<RiderMessage> pageObj = new Page<>(page, PAGE_SIZE);
        LambdaQueryWrapper<RiderMessage> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(RiderMessage::getCityId, cityId)
                .eq(riderId != null, RiderMessage::getRiderId, riderId)
                .eq(type != null, RiderMessage::getType, type)
                .orderByDesc(RiderMessage::getCreateTime);

        Page<RiderMessage> result = messageMapper.selectPage(pageObj, wrapper);

        Map<String, Object> data = new HashMap<>();
        data.put("list", result.getRecords());
        data.put("total", result.getTotal());
        data.put("page", page);
        data.put("pageSize", PAGE_SIZE);
        return data;
    }

    private void ensureCitySelected(Long cityId) {
        if (cityId == null || cityId < 1) {
            throw new BizException("请选择租户");
        }
    }

    private void ensureRiderInCity(Long cityId, Long riderId) {
        if (riderId == null) {
            throw new BizException("骑手ID不能为空");
        }
        Rider rider = riderMapper.selectById(riderId);
        if (rider == null) {
            throw new BizException("骑手不存在");
        }
        if (!cityId.equals(rider.getCityId())) {
            throw new BizException("只能给当前租户骑手发送消息");
        }
    }

    @Override
    public List<RiderMessageTemplate> listTemplates() {
        LambdaQueryWrapper<RiderMessageTemplate> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(RiderMessageTemplate::getStatus, 1)
                .orderByAsc(RiderMessageTemplate::getId);
        return templateMapper.selectList(wrapper);
    }

    @Override
    @Transactional
    public void sendByTemplate(Long cityId, Long riderId, String bizType, Map<String, Object> params) {
        // 查询模板
        LambdaQueryWrapper<RiderMessageTemplate> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(RiderMessageTemplate::getBizType, bizType)
                .eq(RiderMessageTemplate::getStatus, 1);
        RiderMessageTemplate template = templateMapper.selectOne(wrapper);

        if (template == null) {
            log.warn("消息模板不存在,bizType={}", bizType);
            return;
        }

        // 替换占位符
        String title = replacePlaceholders(template.getTitleTemplate(), params);
        String content = replacePlaceholders(template.getContentTemplate(), params);

        // 发送消息
        Long bizId = params.get("bizId") != null ? Long.valueOf(params.get("bizId").toString()) : 0L;
        sendToRider(cityId, riderId, template.getType(), title, content, bizType, bizId);
    }

    /**
     * 替换模板占位符
     */
    private String replacePlaceholders(String template, Map<String, Object> params) {
        String result = template;
        for (Map.Entry<String, Object> entry : params.entrySet()) {
            String placeholder = "#{" + entry.getKey() + "}";
            String value = entry.getValue() != null ? entry.getValue().toString() : "";
            result = result.replace(placeholder, value);
        }
        return result;
    }
}