Commit 9b45a31c authored by liuyiguang's avatar liuyiguang

别名批量推送

parent 8ad52600
......@@ -350,4 +350,19 @@ public class CommonUtil {
return null;
}
}
/**
* 获分组次数
* @param total 总长度
* @param size 每个分组长度
* @return 分组次数
*/
public static Integer getGroupCount(Integer total, Integer size) {
int groupCount = total / size;
if (total % size != 0) {
groupCount = groupCount + 1;
}
return groupCount;
}
}
......@@ -3,14 +3,21 @@ package com.weface.common.validator;
import com.weface.code.CommonResult;
import com.weface.code.ResultCode;
import com.weface.dto.InformForm;
import com.weface.dto.MultiInformForm;
import com.weface.dto.MultiMsgDTO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.CollectionUtils;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
/**
* @author : Administrator
* @date : 2022/4/21 14:28
*/
@Slf4j
public class ValidatorParam {
/**
......@@ -61,4 +68,34 @@ public class ValidatorParam {
return null;
}
/**
* 校验推送参数
*
* @param informForm 推送参数
* @return 核验结果
*/
public static CommonResult validBatchPushParams(MultiInformForm informForm) {
List<MultiMsgDTO> msgList = informForm.getMsgList();
List<MultiMsgDTO> blankTitleList = msgList.stream().filter(x -> StringUtils.isBlank(x.getTitle())).collect(Collectors.toList());
if (!CollectionUtils.isEmpty(blankTitleList)) {
log.error("msgList中含title为空的消息: param=[{}]", informForm);
return CommonResult.validateFailed("msgList中含title为空的消息");
}
List<MultiMsgDTO> blankContentList = msgList.stream().filter(x -> StringUtils.isBlank(x.getContent())).collect(Collectors.toList());
if (!CollectionUtils.isEmpty(blankContentList)) {
log.error("msgList中含content为空的消息: param=[{}]", informForm);
return CommonResult.validateFailed("msgList中含content为空的消息");
}
List<MultiMsgDTO> emptyAliasList = msgList.stream().filter(x -> x.getAlias() == null || x.getAlias().length == 0).collect(Collectors.toList());
if (!CollectionUtils.isEmpty(emptyAliasList)) {
log.error("msgList中含alias为空的消息: param=[{}]", informForm);
return CommonResult.validateFailed("msgList中含alias为空的消息");
}
return null;
}
}
......@@ -10,17 +10,24 @@ import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONObject;
import com.weface.code.CommonResult;
import com.weface.common.utils.CommonUtil;
import com.weface.common.utils.Constant;
import com.weface.common.utils.Model;
import com.weface.dto.InformForm;
import com.weface.dto.MultiInformForm;
import com.weface.dto.MultiMsgDTO;
import com.weface.service.PushLogService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import java.lang.reflect.Type;
import java.util.*;
import java.util.stream.Collectors;
/**
* @author : Administrator
......@@ -42,6 +49,15 @@ public class MobPushService {
@Autowired
private PushLogService pushLogService;
/**
* 批量推送最大消息体数量
*/
private static final int MAX_ITEM_SIZE = 20;
/**
* 批量推送的消息体内最大推送设备数
*/
private static final int MAX_ALIAS = 200;
/**
* mob 推送
*
......@@ -84,7 +100,7 @@ public class MobPushService {
request.put("groupId", target.getValue());
String body = generalPost(request, pushUrl);
if (body != null) {
pushLogService.saveMobLog(JSONObject.parseObject(body), informForm);
pushLogService.saveMobLog(JSONObject.parseObject(body), informForm, false);
return CommonResult.success();
}
return null;
......@@ -107,14 +123,58 @@ public class MobPushService {
}
/**
* mob批量推送
*
* @param informForm 推送内容
* @param target 推送目标
* mob别名批量推送
* 与袤博技术人员确认:建议一个推送任务设置20 items,一个items可以设置200个推送设备
* @param multiInformForm 推送内容
* @return 执行结果
*/
public Model batchMobPush(InformForm informForm, Constant.PushTarget target) {
public CommonResult batchMobPush(MultiInformForm multiInformForm) {
// 消息体数量
List<MultiMsgDTO> itemList = multiInformForm.getMsgList();
List<MultiMsgDTO> splitItemList = new ArrayList<MultiMsgDTO>();
// 判断每个消息体中的推送设备数是否达到最大限制,
// 如果达到最大限制,则从中分割出N个小于最大限制的消息体,并将其添加到原始的消息体数量中
for (MultiMsgDTO msg : itemList) {
if (msg.getAlias().length > MAX_ALIAS) {
// 从当前的消息体中拆分出N个小于最大限制的消息体
List<MultiMsgDTO> subItemList = splitExceedLimitMsg(msg);
// 将新的消息体集合统一放到的新的消息体集合中
splitItemList.addAll(subItemList);
} else {
msg.setItemId(IdUtil.fastUUID());
}
}
if (!CollectionUtils.isEmpty(splitItemList)) {
// 将所有划分后的消息体放到原始的消息体集合中
itemList.addAll(splitItemList);
}
// 删除没有itemId的元素(超过最大限制的元素)
itemList.removeIf(x -> StringUtils.isBlank(x.getItemId()));
// 判断消息体的数量是否达到上限
// 如果达到最大限制,则将其划分成N个小于最大限制的推送任务
if (itemList.size() > MAX_ITEM_SIZE) {
List<MultiInformForm> informForms = splitExceedLimitForm(multiInformForm);
batchMobPushExecute(informForms);
} else {
// 直接执行当前推送任务
batchMobPushExecute(Collections.singletonList(multiInformForm));
}
return CommonResult.success();
}
/**
* 执行批量推送
* @param multiInformFormList 推送任务集合
*/
public void batchMobPushExecute(List<MultiInformForm> multiInformFormList) {
String pushUrl = "http://api.push.mob.com/v3/push/createMulti";
for (MultiInformForm form : multiInformFormList) {
Map<String, Object> request = new HashMap<>(2);
Map<String, Object> pushWork = new HashMap<>();
......@@ -123,34 +183,117 @@ public class MobPushService {
//Mob-appkey
pushWork.put("appkey", APP_KEY);
//推送展示细节配置
InformForm informForm = new InformForm();
BeanUtils.copyProperties(form, informForm);
Map<String, Object> pushNotify = getBatchPushNotify(informForm);
pushWork.put("pushNotify", pushNotify);
//link 相关打开配置
Map<String, Object> pushForward = getPushForward();
pushWork.put("pushForward", pushForward);
//是否重复推送
//pushWork.put("repate", repate);
//repate 重复记录原始ID
//pushWork.put("parentId", parentId);
//groupId: AB分组测试ID
pushWork.put("groupId", target.getValue());
pushWork.put("groupId", Constant.PushTarget.ALIAS.getKey());
request.put("pushWork", pushWork);
//推送目标
String[] split;
String cid = informForm.getCid();
if (cid.contains(",")) {
split = cid.split(",");
} else {
split = new String[]{cid};
}
Map<String, Object> items = getItems(split, informForm.getTitle(), informForm.getBody(), target.getKey());
request.put("items", new Object[]{items});
MultiMsgDTO[] items = form.getMsgList().toArray(new MultiMsgDTO[form.getMsgList().size()]);
request.put("items", items);
String body = generalPost(request, pushUrl);
log.info("批量推送结果:{}", body);
if (body != null) {
return Model.ok();
batchMobPushSaveLog(form, body);
}
}
}
public void batchMobPushSaveLog(MultiInformForm multiInformForm, String resultBody) {
for (MultiMsgDTO msg : multiInformForm.getMsgList()) {
InformForm informForm = new InformForm();
BeanUtils.copyProperties(multiInformForm, informForm);
informForm.setBody(msg.getContent());
String cid = String.join(",", msg.getAlias());
informForm.setCid(cid);
informForm.setMessageTemplate(3);
pushLogService.saveMobLog(JSONObject.parseObject(resultBody), informForm, true);
}
return Model.error();
}
/**
* 将超出 最大推送设备数的消息体进行分割
* @param msg 消息体
* @return 分割后的消息体的集合
*/
private List<MultiMsgDTO> splitExceedLimitMsg(MultiMsgDTO msg) {
// 计算最终从拆分的消息体的数量
Integer itemCount = CommonUtil.getGroupCount(msg.getAlias().length, MAX_ALIAS);
// 定义返回的消息体集合
List<MultiMsgDTO> itemList = new ArrayList<MultiMsgDTO>(itemCount);
// 取出所有原消息体中的推送设备
List<String> alias = new ArrayList<>(Arrays.asList(msg.getAlias()));
// 将推送设备进行拆分
for (int i = 0; i < itemCount; i++) {
// 当前子消息体内的推送设备列表
List<String> subAlias = new ArrayList<>();
if (i == itemCount - 1) {
subAlias = alias.subList(MAX_ALIAS * i, alias.size() - 1);
subAlias.add(alias.get(alias.size() - 1));
} else {
subAlias = alias.subList(MAX_ALIAS * i, (MAX_ALIAS * i) + MAX_ALIAS);
}
MultiMsgDTO item = new MultiMsgDTO();
BeanUtils.copyProperties(msg, item);
item.setAlias(subAlias.toArray(new String[subAlias.size()]));
item.setItemId(IdUtil.fastUUID());
itemList.add(item);
}
return itemList;
}
/**
* 将超出 最大推送消息体数量的任务进行分割
* @param form 推送任务
* @return 分割后的推送任务的集合
*/
private List<MultiInformForm> splitExceedLimitForm(MultiInformForm form) {
// 计算最终从拆分的推送任务的数量
Integer formCount = CommonUtil.getGroupCount(form.getMsgList().size(), MAX_ITEM_SIZE);
// 定义返回的推送任务集合
List<MultiInformForm> subFormList = new ArrayList<MultiInformForm>(formCount);
// 取出所有原推送任务中的消息体
List<MultiMsgDTO> msgList = form.getMsgList();
// 将消息体进行拆分
for (int i = 0; i < formCount; i++) {
MultiInformForm subForm = new MultiInformForm();
BeanUtils.copyProperties(form, subForm);
// 当前子推送任务内的消息体
// List<MultiMsgDTO> subMsgList = new ArrayList<>();
if (i == formCount - 1) {
List<MultiMsgDTO> subMsgList = msgList.subList(MAX_ITEM_SIZE * i, msgList.size() - 1);
// 不再对原集合操作,避免出现java.util.ConcurrentModificationException异常
if (subMsgList.size() == 0) {
subForm.setMsgList(new ArrayList<>(Collections.singletonList(msgList.get(msgList.size() - 1))));
}
} else {
List<MultiMsgDTO> subMsgList = msgList.subList(MAX_ITEM_SIZE * i, (MAX_ITEM_SIZE * i) + MAX_ITEM_SIZE);
subForm.setMsgList(subMsgList);
}
subFormList.add(subForm);
}
return subFormList;
}
/**
......@@ -197,22 +340,6 @@ public class MobPushService {
return false;
}
private Map<String, Object> getItems(String[] target, String title, String content, Integer pushType) {
Map<String, Object> items = new HashMap<>();
items.put("itemId", IdUtil.fastUUID());
//items.put("workNo", workNo);
//items.put("appPackages", new String[]{});
if (pushType.equals(Constant.PushTarget.ALIAS.getKey())) {
items.put("alias", target);
}
if (pushType.equals(Constant.PushTarget.RIDS.getKey())) {
items.put("rids", target);
}
items.put("title", title);
items.put("content", content);
return items;
}
/**
* 批量推送
*
......@@ -489,18 +616,27 @@ public class MobPushService {
} else {
request = JSONObject.toJSONString(map);
}
log.error("mob推送内容:{}", request);
log.info("mob推送内容:{}", request);
HttpRequest post = HttpUtil.createPost(url);
post.header("Content-Type", "application/json");
post.header("key", APP_KEY);
post.header("sign", getSign(request));
String body = post.body(request).execute().body();
log.error("mob推送结果:{}", body);
log.info("mob推送结果:{}", body);
if (JSONUtil.isJson(body)) {
JSONObject json = JSONObject.parseObject(body);
if (json.containsKey("status") && json.getInteger("status").equals(200))
if (json.containsKey("status") && json.getInteger("status").equals(200)) {
JSONObject res = (JSONObject) JSONObject.parseObject(body).get("res");
if (!res.containsKey("errors")) {
return body;
}
Object errors = res.get("errors");
if (ObjectUtils.isEmpty(errors)) {
return body;
}
}
}
return null;
}
......
......@@ -9,11 +9,13 @@ import com.weface.component.GeTuiService;
import com.weface.component.MobPushService;
import com.weface.dto.InformForm;
import com.weface.dto.MsgDTO;
import com.weface.dto.MultiInformForm;
import com.weface.dto.PushDTO;
import com.weface.service.PushService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
......@@ -116,4 +118,18 @@ public class PushController {
return CommonResult.success(result, "推送成功");
}
}
/**
* 别名批量推送
*/
@PostMapping("/batch/alias")
public CommonResult batchMobPush(@RequestBody @Validated MultiInformForm multiInformForm) {
CommonResult result = ValidatorParam.validBatchPushParams(multiInformForm);
if (result != null) {
return result;
}
return mobPushService.batchMobPush(multiInformForm);
}
}
package com.weface.dto;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.List;
/**
* @Author: lyg
* @Description:
* @Date: 2023/5/10 16:03
**/
@Data
public class MultiInformForm {
/**
* 推送的消息体数组
*/
@NotEmpty(message = "消息列表不能为空")
private List<MultiMsgDTO> msgList;
/**
* 跳转url
*/
@NotBlank(message = "url不能为空")
private String url;
/**
* 推送类型 0:h5 1:原生,默认h5
*/
@NotNull(message = "pushType不能为空")
private Integer pushType;
/**
* 推送平台:kksh,kksb,kkwj,kkmz
*/
@NotBlank(message = "equipmentType不能为空")
private String equipmentType;
}
package com.weface.dto;
import lombok.Data;
/**
* @Author: lyg
* @Description:
* @Date: 2023/5/10 16:10
**/
@Data
public class MultiMsgDTO {
/**
* item id(用户自自定义生成且唯一、不能重复)
*/
private String itemId;
/**
* 推送目标, cid的集合,如:[kksh_59354, kksh_59355, kksh_59356]
*/
private String [] alias;
/**
* 消息标题
*/
private String title;
/**
* 消息内容
*/
private String content;
/**
* 推送任务的 workNo 非必填
*/
private String workNo;
/**
* 包名列表 非必填
*/
private String appPackages;
}
......@@ -28,8 +28,9 @@ public interface PushLogService extends IService<PushLogEntity> {
*
* @param data 返回数据
* @param informForm 推送数据
* @param isBatch 是否为批量推送
*/
public void saveMobLog(JSONObject data, InformForm informForm);
public void saveMobLog(JSONObject data, InformForm informForm, boolean isBatch);
/**
* 查询日志
......
......@@ -50,10 +50,17 @@ public class PushLogServiceImpl extends ServiceImpl<PushLogDao, PushLogEntity> i
}
@Override
public void saveMobLog(JSONObject data, InformForm informForm) {
public void saveMobLog(JSONObject data, InformForm informForm, boolean isBatch) {
try {
Long id = SnowIdUtil.nextId();
String batchId = data.getJSONObject("res").getString("batchId");
String batchId;
if (isBatch) {
batchId = "toMultiPush";
} else {
batchId = data.getJSONObject("res").getString("batchId");
}
PushLogEntity pushLog = getPushLog(id, informForm, batchId, data.toString(), 2);
this.save(pushLog);
} catch (Exception e) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment