package com.yeshi.fanli.service.impl.push; import java.util.ArrayList; import java.util.Calendar; import java.util.Date; import java.util.List; import javax.annotation.Resource; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import com.yeshi.fanli.controller.admin.PushController; import com.yeshi.fanli.dao.mybatis.push.DeviceTokenIOSMapper; import com.yeshi.fanli.dao.mybatis.push.PushQueueRecordMapper; import com.yeshi.fanli.entity.bus.user.AccountMessage; import com.yeshi.fanli.entity.push.DeviceTokenIOS; import com.yeshi.fanli.entity.push.PushQueueRecord; import com.yeshi.fanli.entity.system.SystemZnx; import com.yeshi.fanli.entity.xinge.MessageInfo; import com.yeshi.fanli.entity.xinge.PushRecord; import com.yeshi.fanli.exception.PushException; import com.yeshi.fanli.log.PushLogHelper; import com.yeshi.fanli.service.inter.push.IOSPushService; import com.yeshi.fanli.service.inter.user.UserCustomSettingsService; import com.yeshi.fanli.util.CMQManager; import com.yeshi.fanli.util.Constant; import com.yeshi.fanli.util.StringUtil; import com.yeshi.fanli.util.push.IOSPushUtil; import net.sf.json.JSONObject; @Service public class IOSPushServiceImpl implements IOSPushService { @Resource private DeviceTokenIOSMapper deviceTokenIOSMapper; @Resource private PushQueueRecordMapper pushQueueRecordMapper; @Resource private UserCustomSettingsService userCustomSettingsService; @Override public void pushGoods(Long uid, Long auctionId, String title, String content) throws PushException { String url = "https://item.taobao.com/item.htm?id=" + auctionId; JSONObject json = new JSONObject(); json.put("id", auctionId); json.put("type", "goodsdetail"); json.put("miPushUrl", String.format("%s.ui.recommend.GoodsBrowserActivity", Constant.systemCommonConfig.getAndroidBaseactivityName())); MessageInfo info = new MessageInfo(); info.setTitle(title); info.setContent(content); info.setDescription(content); info.setPackageName(Constant.systemCommonConfig.getAndroidPackageName()); info.setActivty(String.format("%s.ui.recommend.GoodsBrowserActivity", Constant.systemCommonConfig.getAndroidBaseactivityName())); PushRecord pushRecord = new PushRecord(); pushRecord.setState(1); pushRecord.setType(PushController.GOODS); // 都成功 pushRecord.setUrl(url); pushRecord.setTitle(title); pushRecord.setAppName(Constant.systemCommonConfig.getProjectChineseName()); if (uid == null || uid == 0) { addPushIOSQueue(info, url, PushController.GOODS); /* * // 查询IOS所有设备号 // TODO 需要全推 List deviceTokenList = * getDeviceTokenList(1, 20000); // IOS 全推 ThreadUtil.run(new * Runnable() { * * @Override public void run() { try { * IOSPushUtil.allPushIOS(deviceTokenList, info, url, * PushController.GOODS); } catch (Exception e) { * PushLogHelper.iosError(e); * * } } }); */ } else { if (!validateNotDisturbSingle(uid)) { return; //通知免打扰(20:00-24:00 / 00:00 -08:00) } // IOS 单推 List deviceTokenIosList = getDeviceTokenListByUid(uid); List deviceTokenList = new ArrayList<>(); if (deviceTokenIosList != null) for (DeviceTokenIOS ios : deviceTokenIosList) { deviceTokenList.add(ios.getDeviceToken()); } try { IOSPushUtil.allPushIOS(deviceTokenList, info, url, PushController.GOODS); } catch (Exception e) { PushLogHelper.iosError(e); } } } @Override public void pushUrl(Long uid, String url, String title, String content) throws PushException { JSONObject json = new JSONObject(); json.put("url", url); json.put("type", "url"); json.put("webUrl", url); json.put("miPushUrl", String.format("%s.ui.BrowserActivity", Constant.systemCommonConfig.getAndroidBaseactivityName())); MessageInfo info = new MessageInfo(); info.setTitle(title); info.setContent(content); info.setDescription(content); // 小米推送网页 info.setPackageName(Constant.systemCommonConfig.getAndroidPackageName()); info.setActivty( String.format("%s.ui.BrowserActivity", Constant.systemCommonConfig.getAndroidBaseactivityName())); PushRecord pushRecord = new PushRecord(); // IOS 全推 if (uid == null || uid == 0) { // TODO 需要全推 addPushIOSQueue(info, url, PushController.URL); /* * List deviceTokenList = getDeviceTokenList(1, 1000); * ThreadUtil.run(new Runnable() { * * @Override public void run() { try { * * IOSPushUtil.allPushIOS(deviceTokenList, info, url, * PushController.URL); * * } catch (Exception e) { PushLogHelper.iosError(e); } } }); */ } else { if (!validateNotDisturbSingle(uid)) { return; //通知免打扰(20:00-24:00 / 00:00 -08:00) } List deviceTokenIosList = getDeviceTokenListByUid(uid); List deviceTokenList = new ArrayList<>(); if (deviceTokenIosList != null) for (DeviceTokenIOS ios : deviceTokenIosList) { deviceTokenList.add(ios.getDeviceToken()); } try { IOSPushUtil.allPushIOS(deviceTokenList, info, url, PushController.URL); } catch (Exception e) { PushLogHelper.iosError(e); } } } @Override public void pushZNX(Long uId, AccountMessage msg, SystemZnx systemZNX) throws PushException { MessageInfo info = new MessageInfo(); info.setPackageName(Constant.systemCommonConfig.getAndroidPackageName()); JSONObject contentJson = new JSONObject(); contentJson.put("isOpen", 0); contentJson.put("createTime", java.lang.System.currentTimeMillis()); /* 无uid , 广播 数据插入系统表 */ if (systemZNX != null) { info.setTitle(systemZNX.getTitle()); info.setContent(systemZNX.getContent()); contentJson.put("title", systemZNX.getTitle()); contentJson.put("content", systemZNX.getContent()); info.setDescription(systemZNX.getContent()); // 小米开始全推 long id = systemZNX.getId(); contentJson.put("id", id); JSONObject json = new JSONObject(); json.put("type", "ZNX"); json.put("content", contentJson); json.put("miPushUrl", String.format("%s.ui.mine.AppMailDetailActivity", Constant.systemCommonConfig.getAndroidBaseactivityName())); PushRecord pushRecord = new PushRecord(); // TODO 需要全推 addPushIOSQueue(info, id + "", PushController.ZNX); /* * List deviceTokenList = getDeviceTokenList(1, 1000); * * ThreadUtil.run(new Runnable() { * * @Override public void run() { try { * IOSPushUtil.allPushIOS(deviceTokenList, info, id + "", * PushController.ZNX); } catch (Exception e) { * PushLogHelper.iosError(e); } * * } }); */ } else if (msg != null) { if (uId !=null) { if (!validateNotDisturbSingle(uId)) { return; //通知免打扰(20:00-24:00 / 00:00 -08:00) } } // 插入推送记录 PushRecord pushRecord = new PushRecord(); info.setTitle(msg.getTitle()); info.setContent(msg.getContent()); contentJson.put("title", msg.getTitle()); contentJson.put("content", msg.getContent()); info.setDescription(msg.getContent()); info.setAlias(uId + ""); info.setPackageName(Constant.systemCommonConfig.getAndroidPackageName()); info.setActivty( String.format("%s.ui.BrowserActivity", Constant.systemCommonConfig.getAndroidBaseactivityName())); contentJson.put("id", msg.getId() + ""); JSONObject json = new JSONObject(); json.put("type", "ZNX"); json.put("content", contentJson); json.put("miPushUrl", String.format("%s.ui.mine.AppMailDetailActivity", Constant.systemCommonConfig.getAndroidBaseactivityName())); List deviceTokenIosList = getDeviceTokenListByUid(msg.getUserInfo().getId()); List deviceTokenList = new ArrayList<>(); if (deviceTokenIosList != null) for (DeviceTokenIOS ios : deviceTokenIosList) { deviceTokenList.add(ios.getDeviceToken()); } // IOS 单推 try { IOSPushUtil.allPushIOS(deviceTokenList, info, "0", PushController.ZNX); } catch (Exception e) { PushLogHelper.iosError(e); } } } @Transactional @Override public void addDeviceToken(Long uid, int version, String deviceToken, String device) { // 如果device为空就返回 if (StringUtil.isNullOrEmpty(device) || StringUtil.isNullOrEmpty(deviceToken)) return; // 判断device是否存在 DeviceTokenIOS deviceTokenIos = deviceTokenIOSMapper.selectByDevice(device); if (deviceTokenIos == null) { deviceTokenIos = new DeviceTokenIOS(); deviceTokenIos.setCreateTime(new Date()); deviceTokenIos.setUpdateTime(new Date()); deviceTokenIos.setDevice(device); deviceTokenIos.setDeviceToken(deviceToken); deviceTokenIos.setDeviceTokenMd5(StringUtil.Md5(deviceToken)); deviceTokenIos.setUid(uid); deviceTokenIos.setVersion(version); deviceTokenIOSMapper.insertSelective(deviceTokenIos); } else {// 更新devicetoken DeviceTokenIOS updateDeviceTokenIOS = new DeviceTokenIOS(); updateDeviceTokenIOS.setId(deviceTokenIos.getId()); updateDeviceTokenIOS.setDeviceToken(deviceToken); updateDeviceTokenIOS.setDeviceTokenMd5(StringUtil.Md5(deviceToken)); updateDeviceTokenIOS.setUid(uid); updateDeviceTokenIOS.setUpdateTime(new Date()); deviceTokenIOSMapper.updateByPrimaryKeySelective(updateDeviceTokenIOS); } } @Override public List getDeviceTokenListByUid(Long uid) { return deviceTokenIOSMapper.selectByUid(uid); } @Override public List getDeviceTokenList(int page, int size) { List list = deviceTokenIOSMapper.selectList((long) ((page - 1) * size), size); List tokenList = new ArrayList<>(); for (DeviceTokenIOS ios : list) if (!StringUtil.isNullOrEmpty(ios.getDeviceToken())) tokenList.add(ios.getDeviceToken()); return tokenList; } @Override public long getDeviceTokenCount() { return deviceTokenIOSMapper.selectCount(); } @Override public void updateDeviceToken(DeviceTokenIOS deviceTokenIos) { if (deviceTokenIos != null) { deviceTokenIos.setUpdateTime(new Date()); deviceTokenIOSMapper.updateByPrimaryKey(deviceTokenIos); } } @Override public DeviceTokenIOS getDeviceTokenByDeviceToken(String deviceToken) { return deviceTokenIOSMapper.selectByDeviceToken(deviceToken); } /** * 保存推送内容只队列中 * * @param json */ @Transactional public void addPushIOSQueue(MessageInfo info, String url, int type) { try { JSONObject json = IOSPushUtil.getJSONObject(info, url, type); // 总条目 long tokenCount = getDeviceTokenCount(); // 一个队列 1000 条 long totalCount = 1000; // 每次执行条目 int pushNum = 50; for (long i = 0; i < tokenCount + totalCount;) { PushQueueRecord pushQueueRecord = new PushQueueRecord(); // 初始状态 pushQueueRecord.setState(0); // 发送内容 pushQueueRecord.setJsonContent(json.toString()); // 创建时间 pushQueueRecord.setCreatetime(new Date()); // 每次推送数量 pushQueueRecord.setPushNum(pushNum); // 推送端 IOS pushQueueRecord.setType(1); if (tokenCount - i < totalCount) { // 起始游标 pushQueueRecord.setStartCursor(i); // 结束游标 pushQueueRecord.setEndCursor(tokenCount); // 存入数据库 pushQueueRecordMapper.insert(pushQueueRecord); // 加入队列 CMQManager.getInstance().addIOSPushMsg(pushQueueRecord); break; } else { // 起始游标 pushQueueRecord.setStartCursor(i); long endCursor = (i + totalCount) - 1; // 结束游标 pushQueueRecord.setEndCursor(endCursor); // 存入数据库 pushQueueRecordMapper.insert(pushQueueRecord); // 加入队列 CMQManager.getInstance().addIOSPushMsg(pushQueueRecord); } i += totalCount; } } catch (Exception e) { e.printStackTrace(); } } /** * 队列执行推送操作 */ @Override public void readyPushIOS(PushQueueRecord pushQueueRecord) throws Exception { // 起始位置 Long startCursor = pushQueueRecord.getStartCursor(); // 结束位置 Long endCursor = pushQueueRecord.getEndCursor(); if (startCursor == null && endCursor == null) { return; } int total = (int) (endCursor - startCursor); // 每次推送总条数 int moveNum = pushQueueRecord.getPushNum(); int count = total / moveNum; if (total % moveNum > 0) { count += 1; } long recordCursor = startCursor; for (int i = 0; i < count; i++) { // 不足50个数据 if (moveNum > total) { moveNum = (int) (endCursor - startCursor); List list = deviceTokenIOSMapper.selectList(startCursor, moveNum); recordCursor = endCursor; if (list != null) { executePushIOS(list, pushQueueRecord, recordCursor); PushLogHelper.iosInfo("推送游标:" + startCursor + "," + moveNum); } } else { if (recordCursor + moveNum > endCursor) { // System.out.println("recordCursorend:" +recordCursor); moveNum = (int) (endCursor - recordCursor); // System.out.println(moveNum); List list = deviceTokenIOSMapper.selectList(recordCursor, moveNum); if (list != null) { executePushIOS(list, pushQueueRecord, endCursor); PushLogHelper.iosInfo("推送游标:" + recordCursor + "," + moveNum); } recordCursor = endCursor; } else { List list = deviceTokenIOSMapper.selectList(recordCursor, moveNum); recordCursor = recordCursor + 50; if (list != null) { executePushIOS(list, pushQueueRecord, recordCursor - 1); PushLogHelper.iosInfo("推送游标:" + recordCursor + "," + moveNum); } } // System.out.println("recordCursor:" +recordCursor); } } } public void executePushIOS(List list, PushQueueRecord pushQueueRecord, long recordCursor) { String jsonContent = pushQueueRecord.getJsonContent(); JSONObject json = JSONObject.fromObject(jsonContent); List tokenList = new ArrayList<>(); boolean ispush = false; List listNotPushId = null; Calendar now = Calendar.getInstance(); int hour = now.get(Calendar.HOUR_OF_DAY); if (hour >= 8 && hour < 20) { ispush = true; // 可推送 } else { listNotPushId = validateNotDisturb(); } for (DeviceTokenIOS ios : list) { if (!StringUtil.isNullOrEmpty(ios.getDeviceToken())) { if (!ispush && listNotPushId != null && listNotPushId.size() > 0) { Long uid = ios.getUid(); if (uid != null && listNotPushId.contains(uid)) { continue; // 通知免打扰(20:00-24:00 / 00:00 -08:00) } } tokenList.add(ios.getDeviceToken()); } } if (tokenList.size() > 0) { // 执行推送 try { IOSPushUtil.executePushIOS(tokenList, json); } catch (Exception e) { e.printStackTrace(); } } pushQueueRecord.setState(1); pushQueueRecord.setEndtime(new Date()); pushQueueRecord.setRecordCursor(recordCursor); // 更新数据库 pushQueueRecordMapper.updateByPrimaryKeySelective(pushQueueRecord); } @Override public void unBindUidAndDevice(String device) { if (StringUtil.isNullOrEmpty(device)) return; DeviceTokenIOS deviceTokenIOS = deviceTokenIOSMapper.selectByDevice(device); if (device != null) { deviceTokenIOS.setUpdateTime(new Date()); deviceTokenIOS.setUid(null); deviceTokenIOSMapper.updateByPrimaryKey(deviceTokenIOS); } } @Override public void pushWEEX(Long uid, String title, String content, String weexUrl) throws PushException { MessageInfo info = new MessageInfo(); info.setTitle(title); info.setContent(content); info.setDescription(content); // IOS 全推 if (uid == null || uid == 0) { addPushIOSQueue(info, weexUrl, PushController.WEEX); } else { List deviceTokenIosList = getDeviceTokenListByUid(uid); List deviceTokenList = new ArrayList<>(); if (deviceTokenIosList != null) for (DeviceTokenIOS ios : deviceTokenIosList) { deviceTokenList.add(ios.getDeviceToken()); } try { IOSPushUtil.allPushIOS(deviceTokenList, info, weexUrl, PushController.WEEX); } catch (Exception e) { PushLogHelper.iosError(e); } } } @Override public void pushBaiChuanUrl(Long uid, String title, String content, String url) throws PushException { MessageInfo info = new MessageInfo(); info.setTitle(title); info.setContent(content); info.setDescription(content); // IOS 全推 if (uid == null || uid == 0) { addPushIOSQueue(info, url, PushController.BAICHUAN); } else { List deviceTokenIosList = getDeviceTokenListByUid(uid); List deviceTokenList = new ArrayList<>(); if (deviceTokenIosList != null) for (DeviceTokenIOS ios : deviceTokenIosList) { deviceTokenList.add(ios.getDeviceToken()); } try { IOSPushUtil.allPushIOS(deviceTokenList, info, url, PushController.BAICHUAN); } catch (Exception e) { PushLogHelper.iosError(e); } } } /** * 通知免打扰(20:00-8:00) */ public List validateNotDisturb() { return userCustomSettingsService.getCancelNoticeUsers(); } /** * 通知免打扰(20:00-8:00) */ public boolean validateNotDisturbSingle(Long uid) { Calendar now = Calendar.getInstance(); int hour = now.get(Calendar.HOUR_OF_DAY); boolean ispush; if (hour >= 8 && hour < 20) { ispush = true; // 可推送 } else { // 自定义设置 通知免打扰(20:00-24:00 / 00:00 -08:00) ispush = userCustomSettingsService.validateCancelNoticeByUid(uid); } return ispush; } }