双重预防项目-国泰新华二开定制版
SZH
2022-08-20 f9f0687195e0fe349185437d22c495d74c8d4a20
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
package com.ruoyi.framework.web.service;
 
import cn.jiguang.common.ClientConfig;
import cn.jiguang.common.ServiceHelper;
import cn.jiguang.common.connection.NettyHttpClient;
import cn.jiguang.common.resp.APIConnectionException;
import cn.jiguang.common.resp.APIRequestException;
import cn.jiguang.common.resp.ResponseWrapper;
import cn.jpush.api.JPushClient;
import cn.jpush.api.push.PushResult;
import cn.jpush.api.push.model.Message;
import cn.jpush.api.push.model.Platform;
import cn.jpush.api.push.model.PushPayload;
import cn.jpush.api.push.model.audience.Audience;
import cn.jpush.api.push.model.notification.AndroidNotification;
import cn.jpush.api.push.model.notification.IosNotification;
import cn.jpush.api.push.model.notification.Notification;
import cn.jpush.api.report.ReceivedsResult;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.framework.config.JpushConfig;
import com.ruoyi.project.tr.JpushMsg.domain.JpushMsg;
import com.ruoyi.project.tr.JpushMsg.service.IJpushMsgService;
import io.netty.handler.codec.http.HttpMethod;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
 
import javax.annotation.Resource;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.*;
 
/**
 * 极光推送服务
 */
@Service("jpushService")
public class JpushService {
    private static final Logger LOG = LoggerFactory.getLogger(JpushService.class);
    @Resource
    JpushConfig jpushConfig;// 注入配置信息
 
    @Autowired
    private IJpushMsgService jpushMsgService;
 
 
    /**
     * 广播 (所有平台,所有设备, 不支持附加信息)
     *
     * @return
     */
    public PushResult pushAll(String title, String content, Integer style, String bigText, Map<String, String> extrasMap) {
        ClientConfig clientConfig = ClientConfig.getInstance();
        clientConfig.setTimeToLive(Long.valueOf(jpushConfig.getLiveTime()));
        // 使用NativeHttpClient网络客户端,连接网络的方式,不提供回调函数
        JPushClient jpushClient = new JPushClient(jpushConfig.getMasterSecret(), jpushConfig.getAppkey(), null,
                clientConfig);
 
        if (extrasMap == null || extrasMap.isEmpty()) {
            extrasMap = new HashMap<String, String>();
        }
        // 设置推送方式
        PushPayload payload = PushPayload.newBuilder().setPlatform(Platform.android_ios())
                // 别名为空,全员推送;别名不为空,按别名推送
                .setAudience(Audience.all())
                .setNotification(Notification.newBuilder().setAlert(content)
                        .addPlatformNotification(
                                AndroidNotification.newBuilder().setTitle(title).setStyle(style).setBigText(bigText).addExtras(extrasMap).build())
                        .addPlatformNotification(IosNotification.newBuilder().incrBadge(1).addExtras(extrasMap).build())
                        .build())
                .build();
        PushResult result = null;
        try {
            result = jpushClient.sendPush(payload);
 
            //数据库增加极光推送消息
            JpushMsg jpushMsg = new JpushMsg();
            jpushMsg.setTitle(title);
            jpushMsg.setContent(content);
            jpushMsg.setMethodType(extrasMap.get("methodType"));
            jpushMsg.setCreateTime(DateUtils.getNowDate());
            jpushMsgService.insertJpushMsg(jpushMsg);
            LOG.info("极光推送结果 - " + result);
        } catch (APIConnectionException e) {
            LOG.error("极光推送连接错误,请稍后重试 ", e);
            LOG.error("Sendno: " + payload.getSendno());
        } catch (APIRequestException e) {
            LOG.error("极光服务器响应出错,请修复! ", e);
            LOG.info("HTTP Status: " + e.getStatus());
            LOG.info("Error Code: " + e.getErrorCode());
            LOG.info("Error Message: " + e.getErrorMessage());
            LOG.info("Msg ID: " + e.getMsgId());
            LOG.error("Sendno: " + payload.getSendno());
        }
        return result;
    }
 
    /**
     * 大文本通知栏样式
     *
     * @param title     App通知栏标题
     * @param content   App通知栏内容(为了单行显示全,尽量保持在22个汉字以下)
     * @param style     通知栏样式类型(默认为 0,还有 1,2,3 可选,用来指定选择哪种通知栏样式,其他值无效。有三种可选分别为 bigText=1,Inbox=2,bigPicture=3。)
     * @param bigText   大文本通知栏样式(当 style = 1 时可用,内容会被通知栏以大文本的形式展示出来。支持 api 16 以上的 rom。)
     * @param extrasMap 额外推送信息(不会显示在通知栏,传递数据用)
     * @param alias     别名数组,设定哪些用户手机能接收信息(为空则所有用户都推送)
     */
    public PushResult sendPushByAndroidBigText(String title, String content, Integer style, String bigText, Map<String, String> extrasMap, String... alias) {
        ClientConfig clientConfig = ClientConfig.getInstance();
        clientConfig.setTimeToLive(Long.valueOf(jpushConfig.getLiveTime()));
        // 使用NativeHttpClient网络客户端,连接网络的方式,不提供回调函数
        JPushClient jpushClient = new JPushClient(jpushConfig.getMasterSecret(), jpushConfig.getAppkey(), null,
                clientConfig);
 
        if (extrasMap == null || extrasMap.isEmpty()) {
            extrasMap = new HashMap<String, String>();
        }
        // 批量删除数组中空元素
        String[] newAlias = removeArrayEmptyElement(alias);
        // 设置推送方式
        PushPayload payload = PushPayload.newBuilder().setPlatform(Platform.android_ios())
                // 别名为空,全员推送;别名不为空,按别名推送
                .setAudience((null == newAlias || newAlias.length == 0) ? Audience.all() : Audience.alias(alias))
                .setNotification(Notification.newBuilder().setAlert(content)
                        .addPlatformNotification(
                                AndroidNotification.newBuilder().setTitle(title).setStyle(style).setBigText(bigText).addExtras(extrasMap).build())
                        .addPlatformNotification(IosNotification.newBuilder().incrBadge(1).addExtras(extrasMap).build())
                        .build())
                .build();
        PushResult result = null;
        try {
            result = jpushClient.sendPush(payload);
 
            //数据库增加极光推送消息
            JpushMsg jpushMsg = new JpushMsg();
            jpushMsg.setTitle(title);
            jpushMsg.setContent(content);
            jpushMsg.setMethodType(extrasMap.get("methodType"));
            jpushMsg.setUserId((null == newAlias || newAlias.length == 0) ? "" : alias[0]);
            jpushMsg.setCreateTime(DateUtils.getNowDate());
            jpushMsgService.insertJpushMsg(jpushMsg);
            LOG.info("极光推送结果 - " + result);
        } catch (APIConnectionException e) {
            LOG.error("极光推送连接错误,请稍后重试 ", e);
            LOG.error("Sendno: " + payload.getSendno());
        } catch (APIRequestException e) {
            LOG.error("极光服务器响应出错,请修复! ", e);
            LOG.info("HTTP Status: " + e.getStatus());
            LOG.info("Error Code: " + e.getErrorCode());
            LOG.info("Error Message: " + e.getErrorMessage());
            LOG.info("Msg ID: " + e.getMsgId());
            LOG.info("以下存在不能识别别名: " + alias);
            LOG.error("Sendno: " + payload.getSendno());
        }
        return result;
    }
 
 
    /**
     * 发送自定义推送,由APP端拦截信息后再决定是否创建通知(目前APP用此种方式)
     *
     * @param title     App通知栏标题
     * @param content   App通知栏内容(为了单行显示全,尽量保持在22个汉字以下)
     * @param extrasMap 额外推送信息(不会显示在通知栏,传递数据用)
     * @param alias     别名数组,设定哪些用户手机能接收信息(为空则所有用户都推送)
     * @return PushResult
     */
    public PushResult sendCustomPush(String title, String content, Map<String, String> extrasMap, String... alias) {
        ClientConfig clientConfig = ClientConfig.getInstance();
        clientConfig.setTimeToLive(Long.valueOf(jpushConfig.getLiveTime()));
        // 使用NativeHttpClient网络客户端,连接网络的方式,不提供回调函数
        JPushClient jpushClient = new JPushClient(jpushConfig.getMasterSecret(), jpushConfig.getAppkey(), null,
                clientConfig);
        // 设置为消息推送方式为仅推送消息,不创建通知栏提醒
        PushPayload payload = buildCustomPushPayload(title, content, extrasMap, alias);
        PushResult result = null;
        try {
            result = jpushClient.sendPush(payload);
            LOG.info("极光推送结果 - " + result + ",接收推送的别名列表:" + String.join(",", alias));
        } catch (APIConnectionException e) {
            LOG.error("极光推送连接错误,请稍后重试 ", e);
            LOG.error("Sendno: " + payload.getSendno());
        } catch (APIRequestException e) {
            LOG.error("极光服务器响应出错,请修复! ", e);
            LOG.info("HTTP Status: " + e.getStatus());
            LOG.info("Error Code: " + e.getErrorCode());
            LOG.info("Error Message: " + e.getErrorMessage());
            LOG.info("Msg ID: " + e.getMsgId());
            LOG.info("以下存在不能识别的别名: " + String.join(",", alias));
            LOG.error("Sendno: " + payload.getSendno());
        }
        return result;
    }
 
    /**
     * 原生方式推送
     *
     * @param title     App通知栏标题
     * @param content   App通知栏内容(为了单行显示全,尽量保持在22个汉字以下)
     * @param extrasMap 额外推送信息(不会显示在通知栏,传递数据用)
     * @param alias     别名数组,设定哪些用户手机能接收信息(为空则所有用户都推送)
     */
    public PushResult sendPush(String title, String content, Map<String, String> extrasMap, String... alias) {
        ClientConfig clientConfig = ClientConfig.getInstance();
        clientConfig.setTimeToLive(Long.valueOf(jpushConfig.getLiveTime()));
        // 使用NativeHttpClient网络客户端,连接网络的方式,不提供回调函数
        JPushClient jpushClient = new JPushClient(jpushConfig.getMasterSecret(), jpushConfig.getAppkey(), null,
                clientConfig);
        // 设置推送方式
        PushPayload payload = buildPushPayload(title, content, extrasMap, alias);
        PushResult result = null;
        try {
            result = jpushClient.sendPush(payload);
            LOG.info("极光推送结果 - " + result);
        } catch (APIConnectionException e) {
            LOG.error("极光推送连接错误,请稍后重试 ", e);
            LOG.error("Sendno: " + payload.getSendno());
        } catch (APIRequestException e) {
            LOG.error("极光服务器响应出错,请修复! ", e);
            LOG.info("HTTP Status: " + e.getStatus());
            LOG.info("Error Code: " + e.getErrorCode());
            LOG.info("Error Message: " + e.getErrorMessage());
            LOG.info("Msg ID: " + e.getMsgId());
            LOG.info("以下存在不能识别别名: " + alias);
            LOG.error("Sendno: " + payload.getSendno());
        }
        return result;
    }
 
 
    /**
     * 异步请求推送方式
     *
     * @param title     通知栏标题
     * @param content   通知栏内容(为了单行显示全,尽量保持在22个汉字以下)
     * @param extrasMap 额外推送信息(不会显示在通知栏,传递数据用)
     * @param alias     需接收的用户别名数组(为空则所有用户都推送)
     * @see 使用NettyHttpClient,异步接口发送请求,通过回调函数可以获取推送成功与否情况
     */
    public void sendPushWithCallback(String title, String content, Map<String, String> extrasMap, String... alias) {
        ClientConfig clientConfig = ClientConfig.getInstance();
        clientConfig.setTimeToLive(Long.valueOf(jpushConfig.getLiveTime()));
        String host = (String) clientConfig.get(ClientConfig.PUSH_HOST_NAME);
        NettyHttpClient client = new NettyHttpClient(
                ServiceHelper.getBasicAuthorization(jpushConfig.getAppkey(), jpushConfig.getMasterSecret()), null,
                clientConfig);
        try {
            URI uri = new URI(host + clientConfig.get(ClientConfig.PUSH_PATH));
            PushPayload payload = buildPushPayload(title, content, extrasMap, alias);
            client.sendRequest(HttpMethod.POST, payload.toString(), uri, new NettyHttpClient.BaseCallback() {
                @Override
                public void onSucceed(ResponseWrapper responseWrapper) {
                    if (200 == responseWrapper.responseCode) {
                        LOG.info("极光推送成功");
                    } else {
                        LOG.info("极光推送失败,返回结果: " + responseWrapper.responseContent);
                    }
                }
            });
        } catch (URISyntaxException e) {
            e.printStackTrace();
        } finally {
            // 需要手动关闭Netty请求进程,否则会一直保留
            client.close();
        }
 
    }
 
    /**
     * 构建Android和IOS的推送通知对象
     *
     * @return PushPayload
     */
    private PushPayload buildPushPayload(String title, String content, Map<String, String> extrasMap, String... alias) {
        if (extrasMap == null || extrasMap.isEmpty()) {
            extrasMap = new HashMap<String, String>();
        }
        // 批量删除数组中空元素
        String[] newAlias = removeArrayEmptyElement(alias);
        return PushPayload.newBuilder().setPlatform(Platform.android_ios())
                // 别名为空,全员推送;别名不为空,按别名推送
                .setAudience((null == newAlias || newAlias.length == 0) ? Audience.all() : Audience.alias(alias))
                .setNotification(Notification.newBuilder().setAlert(content)
                        .addPlatformNotification(
                                AndroidNotification.newBuilder().setTitle(title).addExtras(extrasMap).build())
                        .addPlatformNotification(IosNotification.newBuilder().incrBadge(1).addExtras(extrasMap).build())
                        .build())
                .build();
    }
 
    /**
     * 构建Android和IOS的自定义消息的推送通知对象
     *
     * @return PushPayload
     */
    private PushPayload buildCustomPushPayload(String title, String content, Map<String, String> extrasMap,
                                               String... alias) {
        // 批量删除数组中空元素
        String[] newAlias = removeArrayEmptyElement(alias);
        return PushPayload.newBuilder().setPlatform(Platform.android_ios())
                .setAudience((null == newAlias || newAlias.length == 0) ? Audience.all() : Audience.alias(alias))
                .setMessage(Message.newBuilder().setTitle(title).setMsgContent(content).addExtras(extrasMap).build())
                .build();
    }
 
    /**
     * 查询记录推送成功条数(暂未使用)
     *
     * @param msg_id 在推送返回结果PushResult中保存
     */
    public void countPush(String msg_id) {
        JPushClient jpushClient = new JPushClient(jpushConfig.getMasterSecret(), jpushConfig.getAppkey());
        try {
            ReceivedsResult result = jpushClient.getReportReceiveds(msg_id);
            ReceivedsResult.Received received = result.received_list.get(0);
            LOG.debug("Android接受信息:" + received.android_received + "\n IOS端接受信息:" + received.ios_apns_sent);
            LOG.debug("极光推送返回结果 - " + result);
        } catch (APIConnectionException e) {
            LOG.error("极光推送连接错误,请稍后重试", e);
        } catch (APIRequestException e) {
            LOG.error("检查错误,并修复推送请求", e);
            LOG.info("HTTP Status: " + e.getStatus());
            LOG.info("Error Code: " + e.getErrorCode());
            LOG.info("Error Message: " + e.getErrorMessage());
        }
    }
 
    /**
     * 删除别名中的空元素(需删除如:null,""," ")
     *
     * @param strArray
     * @return String[]
     */
    private String[] removeArrayEmptyElement(String... strArray) {
        if (null == strArray || strArray.length == 0) {
            return null;
        }
        List<String> tempList = Arrays.asList(strArray);
        List<String> strList = new ArrayList<String>();
        Iterator<String> iterator = tempList.iterator();
        while (iterator.hasNext()) {
            String str = iterator.next();
            // 消除空格后再做比较
            if (null != str && !"".equals(str.trim())) {
                strList.add(str);
            }
        }
        // 若仅输入"",则会将数组长度置为0
        String[] newStrArray = strList.toArray(new String[strList.size()]);
        return newStrArray;
    }
}