|
|
@@ -0,0 +1,251 @@
|
|
|
+package com.ruoyi.common.utils.push;
|
|
|
+
|
|
|
+import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
|
|
|
+import com.getui.push.v2.sdk.ApiHelper;
|
|
|
+import com.getui.push.v2.sdk.api.PushApi;
|
|
|
+import com.getui.push.v2.sdk.api.UserApi;
|
|
|
+import com.getui.push.v2.sdk.common.ApiResult;
|
|
|
+import com.getui.push.v2.sdk.dto.req.Audience;
|
|
|
+import com.getui.push.v2.sdk.dto.req.AudienceDTO;
|
|
|
+import com.getui.push.v2.sdk.dto.req.Settings;
|
|
|
+import com.getui.push.v2.sdk.dto.req.Strategy;
|
|
|
+import com.getui.push.v2.sdk.dto.req.message.PushChannel;
|
|
|
+import com.getui.push.v2.sdk.dto.req.message.PushDTO;
|
|
|
+import com.getui.push.v2.sdk.dto.req.message.PushMessage;
|
|
|
+import com.getui.push.v2.sdk.dto.req.message.android.AndroidDTO;
|
|
|
+import com.getui.push.v2.sdk.dto.req.message.android.ThirdNotification;
|
|
|
+import com.getui.push.v2.sdk.dto.req.message.android.Ups;
|
|
|
+import com.getui.push.v2.sdk.dto.req.message.ios.Alert;
|
|
|
+import com.getui.push.v2.sdk.dto.req.message.ios.Aps;
|
|
|
+import com.getui.push.v2.sdk.dto.req.message.ios.IosDTO;
|
|
|
+import com.getui.push.v2.sdk.dto.res.CidStatusDTO;
|
|
|
+import com.getui.push.v2.sdk.dto.res.TaskIdDTO;
|
|
|
+import com.google.common.collect.Lists;
|
|
|
+import com.google.common.collect.Sets;
|
|
|
+import com.ruoyi.common.utils.ClassConvertUtils;
|
|
|
+import com.ruoyi.common.utils.redis.RedisUtils;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.springframework.stereotype.Component;
|
|
|
+import org.springframework.util.CollectionUtils;
|
|
|
+import org.springframework.util.StringUtils;
|
|
|
+
|
|
|
+import java.util.ArrayList;
|
|
|
+import java.util.HashMap;
|
|
|
+import java.util.List;
|
|
|
+import java.util.Map;
|
|
|
+
|
|
|
+/**
|
|
|
+ * @author wuchao
|
|
|
+ */
|
|
|
+@Slf4j
|
|
|
+@Component
|
|
|
+public class GeTuiUtils {
|
|
|
+
|
|
|
+ private PushApi pushApi;
|
|
|
+ private UserApi userApi;
|
|
|
+
|
|
|
+ public GeTuiUtils(ApiHelper apiHelper) {
|
|
|
+ pushApi = apiHelper.creatApi(PushApi.class);
|
|
|
+ userApi = apiHelper.creatApi(UserApi.class);
|
|
|
+ }
|
|
|
+
|
|
|
+ public boolean pushToSingleByCid(Msg msg) {
|
|
|
+ PushDTO<Audience> pushDTO = this.buildPushDTO(msg);
|
|
|
+ // 设置接收人信息
|
|
|
+ Audience audience = new Audience();
|
|
|
+ pushDTO.setAudience(audience);
|
|
|
+ audience.addCid(msg.getCid());// cid
|
|
|
+ // 进行cid单推
|
|
|
+ ApiResult<Map<String, Map<String, String>>> apiResult = pushApi.pushToSingleByCid(pushDTO);
|
|
|
+ //successed_offline: 离线下发(包含厂商通道下发),successed_online: 在线下发,successed_ignore: 最近90天内不活跃用户不下发
|
|
|
+ log.info(String.format("单推[%s],返回结果:%s", apiResult.getMsg(), apiResult.getData()));
|
|
|
+ return apiResult.isSuccess();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * cid批量推
|
|
|
+ *
|
|
|
+ * @param msg
|
|
|
+ */
|
|
|
+ public boolean pushListByCid(Msg msg) {
|
|
|
+ //批量发送
|
|
|
+ AudienceDTO audienceDTO = new AudienceDTO();
|
|
|
+ PushDTO<Audience> pushDTO = this.buildPushDTO(msg);
|
|
|
+
|
|
|
+ ApiResult<TaskIdDTO> createApiResult = pushApi.createMsg(pushDTO);
|
|
|
+ if (!createApiResult.isSuccess()) {
|
|
|
+ log.error("推送:创建消息失败:" + createApiResult.getMsg());
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ // 设置接收人信息
|
|
|
+ Audience audience = new Audience();
|
|
|
+ pushDTO.setAudience(audience);
|
|
|
+ audience.setCid(msg.getCidList());
|
|
|
+
|
|
|
+ audienceDTO.setAudience(audience);
|
|
|
+ audienceDTO.setTaskid(createApiResult.getData().getTaskId());
|
|
|
+ audienceDTO.setAsync(true);
|
|
|
+
|
|
|
+ ApiResult<Map<String, Map<String, String>>> apiResult = pushApi.pushListByCid(audienceDTO);
|
|
|
+ log.info(String.format("批量推[%s],返回结果:%s", apiResult.getMsg(), apiResult.getData()));
|
|
|
+ return apiResult.isSuccess();
|
|
|
+ }
|
|
|
+
|
|
|
+ private PushDTO<Audience> buildPushDTO(Msg msg) {
|
|
|
+ PushDTO<Audience> pushDTO = new PushDTO<>();
|
|
|
+ //前端接收的消息
|
|
|
+ Map<String, Object> map = new HashMap<>();
|
|
|
+ map.put("title", msg.getTitle());
|
|
|
+ map.put("content", msg.getContent());
|
|
|
+ map.put("payload", msg.getMsg());
|
|
|
+ String payload = ClassConvertUtils.transformJSONToSnake(map);
|
|
|
+
|
|
|
+ // 设置推送参数
|
|
|
+ //requestid需要每次变化唯一
|
|
|
+ pushDTO.setRequestId(System.currentTimeMillis() + "");
|
|
|
+ pushDTO.setGroupName("wxb-group");
|
|
|
+
|
|
|
+ //配置推送条件
|
|
|
+ // 1: 表示该消息在用户在线时推送个推通道,用户离线时推送厂商通道;
|
|
|
+ // 2: 表示该消息只通过厂商通道策略下发,不考虑用户是否在线;
|
|
|
+ // 3: 表示该消息只通过个推通道下发,不考虑用户是否在线;
|
|
|
+ // 4: 表示该消息优先从厂商通道下发,若消息内容在厂商通道代发失败后会从个推通道下发。
|
|
|
+ Strategy strategy = new Strategy();
|
|
|
+ strategy.setDef(1);
|
|
|
+ strategy.setSt(1);
|
|
|
+ Settings settings = new Settings();
|
|
|
+ settings.setStrategy(strategy);
|
|
|
+ pushDTO.setSettings(settings);
|
|
|
+ //消息有效期,走厂商消息需要设置该值
|
|
|
+ settings.setTtl(3600000);
|
|
|
+
|
|
|
+ //推送苹果离线通知标题内容
|
|
|
+ Alert alert = new Alert();
|
|
|
+ //苹果离线通知栏标题
|
|
|
+ alert.setTitle(msg.getTitle());
|
|
|
+ //苹果离线通知栏内容
|
|
|
+ alert.setBody(msg.getContent());
|
|
|
+ Aps aps = new Aps();
|
|
|
+ //1表示静默推送(无通知栏消息),静默推送时不需要填写其他参数。
|
|
|
+ //苹果建议1小时最多推送3条静默消息
|
|
|
+ aps.setContentAvailable(0);
|
|
|
+ aps.setSound("default");
|
|
|
+ aps.setAlert(alert);
|
|
|
+ IosDTO iosDTO = new IosDTO();
|
|
|
+ iosDTO.setAps(aps);
|
|
|
+ iosDTO.setType("notify");
|
|
|
+ iosDTO.setPayload(payload);
|
|
|
+ PushChannel pushChannel = new PushChannel();
|
|
|
+ pushChannel.setIos(iosDTO);
|
|
|
+ //安卓离线厂商通道推送消息体
|
|
|
+ AndroidDTO androidDTO = new AndroidDTO();
|
|
|
+ Ups ups = new Ups();
|
|
|
+ ThirdNotification notification1 = new ThirdNotification();
|
|
|
+ ups.setNotification(notification1);
|
|
|
+ //安卓离线展示的标题
|
|
|
+ notification1.setTitle(msg.getTitle());
|
|
|
+ //安卓离线展示的内容
|
|
|
+ notification1.setBody(msg.getContent());
|
|
|
+ notification1.setClickType("intent");
|
|
|
+ notification1.setIntent("intent:#Intent;action=android.intent.action.oppopush;launchFlags=0x14000000;component=com.weixiaobao/io.dcloud.PandoraEntry;S.UP-OL-SU=true;S.title=" + msg.getTitle() + ";S.content=" + msg.getContent() + ";S.payload=" + msg.getMsg() + ";end");
|
|
|
+ //各厂商自有功能单项设置
|
|
|
+ //ups.addOption("HW", "/message/android/notification/badge/class", "io.dcloud.PandoraEntry ");
|
|
|
+ //ups.addOption("HW", "/message/android/notification/badge/add_num", 1);
|
|
|
+ //ups.addOption("HW", "/message/android/notification/importance", "HIGH");
|
|
|
+ //ups.addOption("VV","classification",1);
|
|
|
+ androidDTO.setUps(ups);
|
|
|
+ pushChannel.setAndroid(androidDTO);
|
|
|
+ pushDTO.setPushChannel(pushChannel);
|
|
|
+
|
|
|
+ // PushMessage在线走个推通道才会起作用的消息体
|
|
|
+ PushMessage pushMessage = new PushMessage();
|
|
|
+ pushDTO.setPushMessage(pushMessage);
|
|
|
+ pushMessage.setTransmission(payload);
|
|
|
+ return pushDTO;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 单推
|
|
|
+ *
|
|
|
+ * @param msg
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public void pushByUserId(Msg msg) {
|
|
|
+ try {
|
|
|
+ if (ObjectUtils.isEmpty(msg.getUid())) {
|
|
|
+ log.error("用户ID不能为空");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ //获取Push客户端ID:6a67d611f29e233492223e2de4d7a0c7
|
|
|
+ String clientId = RedisUtils.getCacheObject(getPushCid(String.valueOf(msg.getUid())));
|
|
|
+ if (StringUtils.isEmpty(clientId)) {
|
|
|
+ log.error("客户端ID没有获取到");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ msg.setCid(clientId);
|
|
|
+ //单推
|
|
|
+ this.pushToSingleByCid(msg);
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("单推异常");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 批量推
|
|
|
+ *
|
|
|
+ * @param msg
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public void pushByUserIds(Msg msg) {
|
|
|
+ try {
|
|
|
+ if (CollectionUtils.isEmpty(msg.getUidList())) {
|
|
|
+ log.error("用户ID不能为空");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ List<String> cidList = new ArrayList<>();
|
|
|
+ msg.getUidList().forEach(u -> {
|
|
|
+ //获取Push客户端ID:6a67d611f29e233492223e2de4d7a0c7
|
|
|
+ String clientId = RedisUtils.getCacheObject(getPushCid(String.valueOf(u)));
|
|
|
+ //去重
|
|
|
+ if (!StringUtils.isEmpty(clientId) && !cidList.contains(clientId)) {
|
|
|
+ cidList.add(clientId);
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ if (CollectionUtils.isEmpty(cidList)) {
|
|
|
+ log.error("客户端ID没有获取到");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (cidList.size() > 0) {
|
|
|
+ //按每200个一组分割
|
|
|
+ List<List<String>> parts = Lists.partition(cidList, 200);
|
|
|
+ parts.forEach(list -> {
|
|
|
+ msg.setCidList(list);
|
|
|
+ //批量推
|
|
|
+ this.pushListByCid(msg);
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("批量推异常");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 查询用户状态
|
|
|
+ *
|
|
|
+ * @param cid 客户端标识
|
|
|
+ */
|
|
|
+ public void queryUserStatus(String cid) {
|
|
|
+ ApiResult<Map<String, CidStatusDTO>> mapApiResult = userApi.queryUserStatus(Sets.newHashSet(cid));
|
|
|
+ log.info(String.format("用户状态:%s", mapApiResult));//online在线 offline离线
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 个推客户端ID
|
|
|
+ **/
|
|
|
+ public static String getPushCid(String key) {
|
|
|
+ return "push:cid:" + key;
|
|
|
+ }
|
|
|
+}
|