若依线程池多线程并发 ruoyi-vue SpringBoot 实战批量发送微信小程序订阅消息

业务代码

java 复制代码
    private final ThreadPoolTaskExecutor executorService = SpringUtils.getBean("threadPoolTaskExecutor");


     @Override
    public void batchSendWxMsgByDiy(sendDiyWxMsgVo entity) {
        if (CollectionUtils.isEmpty(entity.getAcceptIds())) {
            throw new TipUserException("接收人不能为空");
        }
        if (StringUtils.isBlank(entity.getDataType())) {
            throw new TipUserException("类型不能为空");
        }
        List<TrainSignupMan> signupManList = signupManMapper.selectByIds(entity.getAcceptIds());
        if (CollectionUtils.isEmpty(signupManList)) {
            throw new TipUserException("人员删除或不可见");
        }
        Map<String, SysDictData> templateConfig = dictTypeService.selectDictDataByType("train_wx_learn_notice")
                .stream().collect(Collectors.toMap(SysDictData::getDictLabel, o -> o));
        if (MapUtils.isEmpty(templateConfig)) {
            throw new TipUserException("请联系管理员配置微信消息模板-培训学习通知");
        }
        List<Long> lyUserIdIds = signupManList.stream().map(TrainSignupMan::getLyUserId).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(lyUserIdIds)) {
            return;
        }
        Map<Long, TzLyUser> tzLyUserMap = tzLyUserService.selectOpenIdListByUserIds(lyUserIdIds)
                .stream().collect(Collectors.toMap(TzLyUser::getId, o -> o));
        if (MapUtils.isEmpty(tzLyUserMap)) {
            return;
        }
        String className = entity.getClassName();
        String dataTip = null;
        Date dataTime = null;
        if (StringUtils.equals(entity.getDataType(), "diy")) {
            dataTip = entity.getDataTip();
            dataTime = entity.getDataTime();
            if (StringUtils.isBlank(dataTip)) {
                throw new TipUserException("温馨提示不能为空");
            }
            if (ObjectUtils.isEmpty(dataTime)) {
                throw new TipUserException("时间不能为空");
            }
        } else if (StringUtils.equals(entity.getDataType(), "dict")) {
            dataTime = DateUtils.getNowDate();
            SysDictData defaultSysDictData = templateConfig.get("default");
            SysDictData trainSysDictData = templateConfig.get(entity.getTrainingCourseId());
            if (ObjectUtils.isEmpty(defaultSysDictData)) {
                throw new TipUserException("请配置该培训班-培训学习通知默认模板");
            }
            dataTip = defaultSysDictData.getDictValue();
            if (ObjectUtils.isNotEmpty(trainSysDictData)) {
                dataTip = trainSysDictData.getDictValue();
            }
        } else {
            throw new TipUserException("请携带类型参数");
        }
        // 创建 final 变量副本用于 lambda 表达式
        final String finalDataTip = dataTip;
        final Date finalDataTime = dataTime;
        ConcurrentLinkedQueue<SmsPreventBody> smsPreventBodyQueue = new ConcurrentLinkedQueue<>();
        CountDownLatch latch = new CountDownLatch(signupManList.size());
        for (TrainSignupMan signupMan : signupManList) {
            TzLyUser tzLyUser = tzLyUserMap.get(signupMan.getLyUserId());
            if (ObjectUtils.isEmpty(tzLyUser)) {
                latch.countDown();
            } else {
                try {
                    executorService.execute(()->{
                        SmsPreventBody smsPreventBody = sendNoticeWxMsg(signupMan, templateConfig, tzLyUser.getOpenId(), className, finalDataTip, finalDataTime);
                        smsPreventBodyQueue.add(smsPreventBody);
                        latch.countDown();
                    });
                } catch (Exception e) {
                    latch.countDown();
                }
            }
        }
        executorService.shutdown();
        List<SmsPreventBody> smsPreventBodyList = new ArrayList<>(smsPreventBodyQueue);
        smsPreventService.saveBatch(smsPreventBodyList);
    }

微信发送消息工具类

java 复制代码
   private SmsPreventBody sendNoticeWxMsg(TrainSignupMan signupMan, Map<String, SysDictData> templateConfig, String openId, String className, String dataTip, Date dataTime) {
        String env_version = ConfigUtils.getString("wx.mp.is.env.version", "release");
        SendMessageTemplateVo messageTemplateVo = new SendMessageTemplateVo();
        messageTemplateVo.setMiniprogram_state(env_version);
        messageTemplateVo.setTemplate_id(templateConfig.get("template_id").getDictValue());
        messageTemplateVo.setPage(templateConfig.get("page").getDictValue());
        messageTemplateVo.setTouser(openId);
        // 培训班
        messageTemplateVo.putParam("thing1", className);
        // 时间
        String dateFormat = DateUtil.format(dataTime, "yyyy年MM月dd日");
        messageTemplateVo.putParam("time2", dateFormat);
        // 温馨提示
        messageTemplateVo.putParam("thing3", dataTip);
        // 消息发送成功
        SmsPreventBody smsPreventBody = new SmsPreventBody();
        smsPreventBody.setMobile(signupMan.getTel());
        smsPreventBody.setType("train-notice");
        smsPreventBody.setTipStr("微信订阅消息-培训学习通知");
        com.alibaba.fastjson.JSONObject jsonObject = WeChatUtils.sendWxMessage(messageTemplateVo);
        String errcode = jsonObject.getString("errcode");
        String errmsg = jsonObject.getString("errmsg");
        if (StringUtils.equals(errcode, "0")) {
            smsPreventBody.setState("success");
            smsPreventBody.setContent(errmsg);
        } else {
            smsPreventBody.setState("error");
            smsPreventBody.setContent(errcode + ":" + errmsg);
        }
        return smsPreventBody;
    }

消息实体

java 复制代码
package com.huida.tzly.domain.vo;

import com.alibaba.fastjson.JSONObject;
import lombok.Data;

import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;

/**
 * 微信发送订阅消息
 *
 */
@Data
public class SendMessageTemplateVo implements Serializable {

    //接收者(用户)的 openid
    private String touser;

    //所需下发的订阅模板id
    private String template_id;

    //点击模板卡片后的跳转页面,仅限本小程序内的页面。支持带参数,(示例index?foo=bar)。该字段不填则模板无跳转
    private String page;

    //模板内容,格式形如 { "key1": { "value": any }, "key2": { "value": any } }的object
    private JSONObject data = new JSONObject();

    // 跳转小程序类型:developer为开发版;trial为体验版;formal为正式版;默认为正式版
    private String miniprogram_state;

    //进入小程序查看"的语言类型,支持zh_CN(简体中文)、en_US(英文)、zh_HK(繁体中文)、zh_TW(繁体中文),默认为zh_CN
//    private String lang;

    public void putParam(String key, String value) {
        Map<String, Object> temp = new HashMap<>();
        temp.put("value", value);
        this.data.put(key, temp);
    }


}
相关推荐
chusheng18406 分钟前
Java 基于SpringBoot +Vue的4S 店车辆管理系统(附源码,说明文档,部署)
java·vue.js·spring boot·汽车管理系统·4s店汽车管理系统·4s 店汽车管理
wcy011215 分钟前
微信小程序+Vant-自定义选择器组件(单选带筛选
微信小程序·小程序
尘浮生1 小时前
Java项目实战II基于Java+Spring Boot+MySQL的智慧养老中心管理系统(开发文档+数据库+源码)
java·开发语言·数据库·spring boot·mysql·微信小程序·maven
哎呦没1 小时前
英语知识网站开发:Spring Boot框架技巧
spring boot·后端·性能优化
ZmyCoder1 小时前
springboot项目使用maven打包,第三方jar问题
spring boot·maven
世间万物皆对象1 小时前
Spring Boot Web应用开发:数据访问
java·数据库·spring boot
冰冻果冻2 小时前
vue--制作购物车
前端·javascript·vue.js
顽疲2 小时前
springboot vue 开源 会员收银系统 (9) 库存管理 结算时扣库存
vue.js·spring boot·后端
2401_857600952 小时前
英语知识在线教学:Spring Boot网站构建
spring boot·后端·mfc
paterWang2 小时前
小程序-基于java+SpringBoot+Vue的铁路订票平台小程序设计与实现
java·spring boot·小程序