后台小程序批量推送(多线程)

一,创建需要的表

表名:t_push_task(推送任务表)

表格信息
字段类型注释能否为空默认值其他
idint(11) PRINOauto_increment
template_idvarchar(64)小程序模版ID YES 
task_namevarchar(64)模版名称 YES 
task_topicvarchar(64)活动主题 YES 
task_captionvarchar(200)活动说明 YES 
task_tipsvarchar(64)温馨提示 YES 
task_typevarchar(64)任务类型 YES 
statusint(1)任务是否已经发送 1 未发送[默认] 2 已发送 YES 
goods_idint(11)商品ID YES 
goods_namevarchar(64)商品标题 YES 
goods_online_statusint(2)商品前台状态 1 上架 0 下架 YES 
pricedecimal(10,2)商品金额(需要的海贝数) YES 
is_uploadint(1)  YES 
file_namevarchar(64)  YES 
create_timedatetime创建时间 YES 
update_timedatetime更新时间MULNO

 

表名:t_push_task_user(推送流水表)

注释:

返回目录

表格信息
字段类型注释能否为空默认值其他
idint(11) PRINOauto_increment
task_idint(11)推送IDMULYES 
user_idint(11)用户ID YES 
form_idvarchar(50)小程序推送formId YES 
statusint(2)推送状态 1 已推送 2 未推送 YES 
create_timedatetime创建时间 YES 
update_timedatetime更新时间 YES 
notevarchar(255)备注 YES

 

表名:t_push_user_from_id_record(收集formid表)

表格信息
字段类型注释能否为空默认值其他
idbigint(11) PRINOauto_increment
user_idbigint(11)用户idMULYES 
form_idvarchar(100)小程序推送formId YES 
sourcesmallint(2)来源 source 1,步数兑换海贝按钮;2,首页邀请按钮;3,步数拦截弹窗邀请按钮;4,兑换商品按钮;5,海贝不够邀请按钮;6,引导关注蒙层按钮;7,健康体验领取按钮 YES 
statussmallint(2)使用状态 1 未使用[默认] 2 已使用 YES 
create_timedatetime创建时间 YES 
update_timedatetime修改时间 YES 

二.小程序需要推送的必须字段 为 formId和用户的openid

小程序推送任务配置 新建任务

序号任务创建时间模板ID模板名称关联商品编码关联商品标题关联商品前台状态推送用户量任务类型操作
982018-09-20895CZeh4-ISI3cpl1yyS-o_i6EtMfrC8bzgaipHauF0活动加入成功提醒1989健康助利测试商品1上架638指定用户发送查看 发送完成
972018-09-20895CZeh4-ISI3cpl1yyS-o_i6EtMfrC8bzgaipHauF0活动加入成功提醒1989健康助利测试商品1上架638指定用户发送查看 发送完成
962018-09-20895CZeh4-ISI3cpl1yyS-o_i6EtMfrC8bzgaipHauF0活动加入成功提醒1989健康助利测试商品1上架637指定用户发送查看 发送完成
952018-09-20895CZeh4-ISI3cpl1yyS-o_i6EtMfrC8bzgaipHauF0活动加入成功提醒1989健康助利测试商品1上架637指定用户发送查看 发送完成

新增任务(可以配置需要推送的任何商品)

模板ID: 895CZeh4-ISI3cpl1yyS-o_i6EtMfrC8bzgaipHauF0

模板名称: 活动加入成功提醒

活动主题:  限10个字,小程序模板消息的活动主题

活动说明:  限30个字,小程序模板消息的活动说明

温馨提示:  限30个字,小程序模板消息的温馨提示

模板关联前台商品编码:  更新 限1个上架商品编码,小程序模板商品标题及金额

商品标题: 健康助利测试商品1

商品金额: 250

商品前台状态: 上架

然后再列表可以点击 发送按钮;

发送代码

 /**
     * 小程序任务推送
     * @param id
     * @return
     */
    public ResultInfoObject pushMsg(Integer id,String userName) {
        ResultInfoObject resultInfo = new ResultInfoObject();
        //针对于售后服务重复数据进行redis加锁,处理并发问题
        String key = "health_cache_push_" + id;
        if(JedisUtil.keyExists(key)) {
            resultInfo.setRetcode(CommonConstant.PARAM_ERROR_CODE);
            resultInfo.setRetdesc("操作过于频繁,请稍后再试!");
            return resultInfo;
        }

        JedisUtil.setex(key, 300, "1");

        log.info("[pushMsg] add redis lock key : {}", key);

        HealthPushTask healthPushTask = healthPushTaskDao.selectByPrimaryKey(id);

        if (healthPushTask.getStatus()==2){ //已发送
            log.info("此任务已发送id="+healthPushTask.getId());
            resultInfo.setRetcode(CommonConstant.PARAM_ERROR_CODE);
            resultInfo.setObject("此任务已发送id="+healthPushTask.getId());
            return resultInfo ;
        }
        healthPushTask.setStatus(2);
        healthPushTask.setUpdateTime(new Date());
        healthPushTaskDao.updateByPrimaryKeySelective(healthPushTask);
        List<HealthPushTaskUser> healthPushTaskUserList = healthPushTaskUserDao.selectListByTaskId(id);
        if (healthPushTaskUserList== null|| healthPushTaskUserList.size()<1){
            log.info("还没有上传用户ID");
            resultInfo.setRetcode(CommonConstant.PARAM_ERROR_CODE);
            resultInfo.setObject("还没有上传用户ID");
            return resultInfo ;
        }
        List<HealthPushUserFromIdRecord> healthPushUserFromIdRecordList = healthPushUserFromIdRecordDao.selectAvialFormId();
        if (healthPushUserFromIdRecordList== null|| healthPushUserFromIdRecordList.size()<1){
            log.info("没有formid");
            resultInfo.setRetcode(CommonConstant.PARAM_ERROR_CODE);
            resultInfo.setObject("没有formid");
            return resultInfo ;
        }

        Map<String, HealthPushUserFromIdRecord> formIdMap = new HashMap();
        AtomicInteger successCount = new AtomicInteger(0);
        for (HealthPushUserFromIdRecord s : healthPushUserFromIdRecordList) {
            formIdMap.put(s.getUserId() + "", s);
        }
        int totalCount = healthPushTaskUserList.size();
        
        //多线程分发
        final int size = 100;
        int threadCount = (totalCount + size - 1) / size;
		final CountDownLatch countDownLatch = new CountDownLatch(threadCount);
		for(int i=0;i<threadCount;i++) {
			final int beginIndex = i * size;
			final int endIndex = (threadCount - i) ==1 ? totalCount : (beginIndex + size);
			ThreadPoolUtils.addProcess(new Runnable() {
				@Override
				public void run() {
					List<HealthPushTaskUser> subList = new ArrayList<>(healthPushTaskUserList.subList(beginIndex,endIndex));
					log.info("小程序推送子list范围: {}-{}",beginIndex , endIndex);
					
					for (HealthPushTaskUser healthPushTaskUser : subList) {
			            HealthUser healthUser = healthUserDao.selectByPrimaryKey(Long.valueOf(healthPushTaskUser.getUserId()));
			            if (healthUser != null && healthUser.getOpenid() != null) {
			                HealthPushUserFromIdRecord healthPushUserFromIdRecord =formIdMap.get(healthUser.getUserId() + "");

			                try {
			                    if (healthPushUserFromIdRecord== null){
			                        log.info(healthUser.getUserId()+"没有formid");
			                        healthPushTaskUser.setUpdateTime(new Date());
			                        healthPushTaskUser.setStatus(3);
			                        healthPushTaskUser.setNote("没有formid");
			                        healthPushTaskUserDao.updateByPrimaryKeySelective(healthPushTaskUser);
			                        continue;
			                    }
			                    String page ="pages/goods/detail/detail";
			                    String  accessToken = wechatApiService.getAccessToken("health_applet");
			                    String templateId = healthPushTask.getTemplateId();
			                    Map<String, TemplateData> param = new HashMap<String, TemplateData>();
			                    param.put("keyword1", new TemplateData(healthPushTask.getTaskTopic(), "#EE0000"));
			                    param.put("keyword2", new TemplateData(healthPushTask.getTaskCaption(), "#EE0000"));
			                    param.put("keyword3", new TemplateData(healthPushTask.getGoodsName(), "#EE0000"));
			                    param.put("keyword4", new TemplateData( Validator.doubleTrans(Validator.rountTwo(healthPushTask.getPrice().doubleValue()))+"海贝", "#EE0000"));
			                    param.put("keyword5", new TemplateData( healthPushTask.getTaskTips(), "#EE0000"));

			                    com.alibaba.fastjson.JSONObject jsonObject = com.alibaba.fastjson.JSONObject.parseObject(JSON.toJSONString(param));
//			        //调用发送微信消息给用户的接口    ********这里写自己在微信公众平台拿到的模板ID
			                    JSONObject resultJson = WX_TemplateMsgUtil.sendWechatMsgToUser(healthUser.getOpenid(), templateId, page + "?backToHome=1&&goodsId=" + healthPushTask.getGoodsId(),
			                            healthPushUserFromIdRecord.getFormId(), jsonObject, accessToken);
			                    String errmsg = "error";
			                    if (resultJson!=null){
			                        errmsg = (String) resultJson.get("errmsg");
			                    }
			                    if ("ok".equals(errmsg)){
			                        healthPushTaskUser.setStatus(1);
			                        successCount.incrementAndGet();
			                    }else {
			                        healthPushTaskUser.setStatus(3);
			                        // errorCount++;
			                    }
			                    healthPushUserFromIdRecord.setStatus(2);
			                    healthPushUserFromIdRecord.setUpdateTime(new Date());
			                    healthPushUserFromIdRecordDao.updateByPrimaryKeySelective(healthPushUserFromIdRecord);
			                    healthPushTaskUser.setUpdateTime(new Date());
			                    healthPushTaskUser.setNote(errmsg);
			                    healthPushTaskUser.setFormId(healthPushUserFromIdRecord.getFormId());
			                    healthPushTaskUserDao.updateByPrimaryKeySelective(healthPushTaskUser);
			                } catch (Exception e) {
			                    resultInfo.setRetdesc("发送失败");
			                    resultInfo.setRetcode(CommonConstant.PARAM_ERROR_CODE);
			                    log.error("APPPUSH:"+e.getMessage());
			                }
			            } else {
			                healthPushTaskUser.setUpdateTime(new Date());
			                healthPushTaskUser.setStatus(3);
			                healthPushTaskUser.setNote("用户不存在或者openid不存在");
			                healthPushTaskUserDao.updateByPrimaryKeySelective(healthPushTaskUser);
			                log.info("APPPUSH:用户不存在或者openid不存在=" + healthPushTaskUser.getUserId());
			            }
			        }
					
					countDownLatch.countDown();
				}
			});
		}
		try {
			countDownLatch.await();
		} catch (InterruptedException e) {
			log.error("小程序推送线程中断,错误:{}", e.getMessage());
		}
		
		String obj = "总发送数量="+totalCount+",发送成功数量="+successCount.get()+",发送失败数量="+(totalCount-successCount.get());
        log.info(obj);
        resultInfo.setObject(obj);
        resultInfo.setRetcode(CommonConstant.RET_SUCCESS);
        return resultInfo;
    }

首先通过redis 锁 锁住任务,防止任务重复发送,

发送速度通过多线程的方式,每个线程发送100个推送,通过截取list的方式,选择推送范围

qq 群 621692258

git 地址 https://gitee.com/JiaGou-XiaoGe/webappchat/

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zscat-me

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值