package com.uas.ps.message.service.impl; import com.alibaba.fastjson.JSONObject; import com.uas.account.entity.User; import com.uas.account.entity.UserView; import com.uas.account.util.AccountUtils; import com.uas.account.util.FlexJsonUtil; import com.uas.ps.core.page.PageInfo; import com.uas.ps.core.page.PageParams; import com.uas.ps.core.page.criteria.LogicalExpression; import com.uas.ps.core.page.criteria.PredicateUtils; import com.uas.ps.core.page.criteria.SimpleExpression; import com.uas.ps.core.util.ArrayUtils; import com.uas.ps.message.dao.AppDao; import com.uas.ps.message.dao.MessageDao; import com.uas.ps.message.domain.App; import com.uas.ps.message.domain.Message; import com.uas.ps.message.domain.SmsMessage; import com.uas.ps.message.exception.IllegalOperatorException; import com.uas.ps.message.exception.ParameterMissingException; import com.uas.ps.message.service.MessageService; import com.uas.ps.message.util.Constant; import com.uas.ps.message.util.ConsumeType; import com.uas.ps.message.util.FastjsonUtils; import com.uas.ps.message.util.SMSType; import com.uas.ps.message.util.SplitChar; import com.uas.ps.message.util.account.HttpUtil; import com.uas.ps.message.util.account.HttpUtil.ResponseWrap; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import javax.persistence.criteria.CriteriaBuilder; import javax.persistence.criteria.CriteriaQuery; import javax.persistence.criteria.Predicate; import javax.persistence.criteria.Root; import org.apache.log4j.Logger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.data.jpa.domain.Specification; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.stereotype.Service; import org.springframework.ui.ModelMap; import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; /** * Created by wangyc on 2018/1/13. * * @version 2018/1/13 15:44 wangyc */ @Service public class MessageServiceImpl implements MessageService { private final MessageDao messageDao; private final AppDao appDao; private static final Logger logger = Logger.getLogger(Logger.class); // private RestTemplate restTemplate; // private static final String EMAIL_REGEX = "\\w[-\\w.+]*@([A-Za-z0-9][-A-Za-z0-9]+\\.)+[A-Za-z]{2,14}"; // private static final String TEL_REGEXP = "^((\\(\\d{3}\\))|(\\d{3}\\-))?(13|15|18|17)\\d{9}$"; private static final String PROD_URL = "https://mobile.ubtob.com/tigase/baiduPush"; private static final String PUBLIC_INQUIRY_IM_URL= "https://mobile.ubtob.com:8443/openapp/?pagekind=B&id=%s&uu=%s&telephone=%s"; /** * 邮件服务主机地址 */ private static final String MAIL_CONSOLE_HOST = "http://10.10.100.136:8080"; /** * 发送邮件给单个人url */ private static final String MAIL_SEND_URL = "mail/send"; /** * 发送邮件给多个人 url */ private static final String MAIL_SEND_MANY_URL = "mail/send/o2m"; /** * 短信接口 */ private final String messageUrl = "http://10.10.100.136:8080/sms/send"; @Autowired public MessageServiceImpl(MessageDao messageDao, AppDao appDao) { this.messageDao = messageDao; this.appDao = appDao; } @Override public Page getMessages(String receiverUu, String receiverEnuu, String consumerApp, String isRead, String keyword, PageParams pageParams) { if (StringUtils.isEmpty(receiverUu) || StringUtils.isEmpty(receiverEnuu)) { throw new ParameterMissingException("接收人信息为空"); } if (StringUtils.isEmpty(consumerApp)) { throw new ParameterMissingException("接收应用信息为空"); } App consumerAppExists = appDao.findByName(consumerApp); if (consumerApp == null) { throw new IllegalOperatorException("接收应用不存在"); } final Long consumerAppId = consumerAppExists.getId(); // 消息接收人过滤 SimpleExpression receiverUuExp = PredicateUtils.eq("receiverUu", Long.valueOf(receiverUu), true); // 消息接收企业过滤 SimpleExpression receiverEnuuExp = PredicateUtils.eq("receiverEnuu", Long.valueOf(receiverEnuu), true); SimpleExpression[] simpleExpressions = new SimpleExpression[] {receiverUuExp, receiverEnuuExp}; // 读取状态 if (!StringUtils.isEmpty(isRead)) { SimpleExpression isReadExp = PredicateUtils.eq("isRead", Short.valueOf(isRead), true); simpleExpressions = ArrayUtils.concat(simpleExpressions, new SimpleExpression[] {isReadExp}); } // 关键词搜索 if (!StringUtils.isEmpty(keyword)) { SimpleExpression contentExp = PredicateUtils.like("content", keyword, true); simpleExpressions = ArrayUtils.concat(simpleExpressions, new SimpleExpression[] {contentExp}); } final LogicalExpression logicalExpression = PredicateUtils.and(simpleExpressions); final PageInfo pageInfo = new PageInfo(pageParams); return messageDao.findAll(new Specification() { @Override public Predicate toPredicate(Root root, CriteriaQuery criteriaQuery, CriteriaBuilder criteriaBuilder) { Predicate messagePredicate = criteriaBuilder.and(logicalExpression.toPredicate(root, criteriaQuery, criteriaBuilder)); // 消费应用过滤 Predicate consumerAppPredicate = criteriaBuilder.equal(root.join("consumerApp").get("id"), consumerAppId); Predicate all = criteriaBuilder.and(messagePredicate, consumerAppPredicate); criteriaQuery.where(all); return null; } }, pageInfo); } @Override public Map getUnReadMessageCount(String receiverUu, String receiverEnuu, String consumerApp) { if (StringUtils.isEmpty(receiverUu) || StringUtils.isEmpty(receiverEnuu)) { throw new ParameterMissingException("接收人信息为空"); } if (StringUtils.isEmpty(consumerApp)) { throw new ParameterMissingException("接收应用信息为空"); } App consumerAppExists = appDao.findByName(consumerApp); if (consumerApp == null) { throw new IllegalOperatorException("接收应用不存在"); } Integer messagesCount = messageDao.findCountByReceiverUuAndReceiverEnuuAndIsReadAndConsumerAppId(Long.valueOf(receiverUu), Long.valueOf(receiverEnuu), Constant.NO, consumerAppExists.getId()); Map resultMap = new HashMap<>(); resultMap.put("success", "success"); resultMap.put("count", messagesCount); return resultMap; } @Override public Map getMessageCount(String receiverUu, String receiverEnuu, String consumerApp, String isRead) { if (StringUtils.isEmpty(receiverUu) || StringUtils.isEmpty(receiverEnuu)) { throw new ParameterMissingException("接收人信息为空"); } if (StringUtils.isEmpty(consumerApp)) { throw new ParameterMissingException("接收应用信息为空"); } App consumerAppExists = appDao.findByName(consumerApp); if (consumerApp == null) { throw new IllegalOperatorException("接收应用不存在"); } Integer messagesCount = 0; if (StringUtils.isEmpty(isRead) || (!isRead.equals(Constant.NO.toString()) && !isRead.equals(Constant.YES.toString()))) { messagesCount = messageDao.findCountByReceiverUuAndReceiverEnuuAndConsumerAppId(Long.valueOf(receiverUu), Long.valueOf(receiverEnuu), consumerAppExists.getId()); } else { messagesCount = messageDao.findCountByReceiverUuAndReceiverEnuuAndIsReadAndConsumerAppId(Long.valueOf(receiverUu), Long.valueOf(receiverEnuu), Short.valueOf(isRead), consumerAppExists.getId()); } Map resultMap = new HashMap<>(); resultMap.put("success", "success"); resultMap.put("count", messagesCount); return resultMap; } @Override public List saveMessages(String messages) { List jsonObjects = FastjsonUtils.fromJsonArray(messages, JSONObject.class); List messageList = convertFromJsonObj(jsonObjects); return messageDao.save(messageList); } @Override public Map sendMessage(String consumerApp) { JSONObject consumer = FastjsonUtils.parseObject(consumerApp); Object consumerAppObj = consumer.get("consumerApp"); if (consumerAppObj != null && !StringUtils.isEmpty(String.valueOf(consumerAppObj))) { App consumerAppExists = appDao.findByName(String.valueOf(consumerAppObj)); if (consumerAppExists == null) { throw new IllegalOperatorException("接收应用不存在"); } // 获取改应用应接收的未读、未发送的需要推送的消息(取前500条) List messages = messageDao.findByConsumerAppIdAndIsReadAndIsSentNeedToSend( consumerAppExists.getId(), Constant.NO, Constant.NO); logger.info("信息数量:" + messages.size()); Map resultMap = sendMessageByAPI(messages, consumerApp); resultMap.put("success", "success"); return resultMap; } else { throw new ParameterMissingException("接收应用信息为空"); } } @Override public ModelMap readMessage(String consumer) { ModelMap map = new ModelMap(); map.put("success", "false"); if (StringUtils.isEmpty(consumer)) { throw new ParameterMissingException("接收人信息为空,无法阅读消息"); } JSONObject jsonObject = FastjsonUtils.parseObject(consumer); // 消息id Object messageId = jsonObject.get("messageId"); Object receiverUu = jsonObject.get("receiverUu"); Object receiverEnuu = jsonObject.get("receiverEnuu"); Object consumerApp = jsonObject.get("consumerApp"); if (StringUtils.isEmpty(messageId)) { map.put("data", "消息id为空,请重新确认消息信息"); return map; } else { String[] messageIds = String.valueOf(messageId).split(SplitChar.COMMA); List messages = new ArrayList<>(); for (String id : messageIds) { Message message = messageDao.findOne(Long.valueOf(String.valueOf(id))); if (message == null) { map.put("data", "消息不存在,请重新确认消息信息"); return map; } if (receiverUu == null || StringUtils.isEmpty(String.valueOf(receiverEnuu)) || receiverEnuu == null || StringUtils.isEmpty(String.valueOf(receiverUu)) || StringUtils.isEmpty(String.valueOf(consumerApp))) { map.put("data", "用户信息为空,无法读取消息"); return map; } if (!Long.valueOf(String.valueOf(receiverEnuu)).equals(message.getReceiverEnuu()) || !Long.valueOf(String.valueOf(receiverUu)).equals(message.getReceiverUu())) { map.put("data", "此消息不属于当前用户,请重新确认后读取"); return map; } if (Constant.YES.equals(message.getIsRead())) { map.put("data", "消息已阅读"); return map; } App app = appDao.findByName(String.valueOf(consumerApp)); if (app == null) { map.put("data", "消费应用不存在,请重新确认用户信息"); return map; } if (!message.getConsumerApp().contains(app)) { map.put("data", "消息不属于当前应用"); return map; } message.setIsRead(Constant.YES); messages.add(message); } messages = messageDao.save(messages); map.put("success", "success"); map.put("data", FastjsonUtils.toJson(messages)); return map; } } /** * jsonObject转换为Message * @param jsonObjects jsonObjects * @return messages */ private List convertFromJsonObj(List jsonObjects) { List messages = new ArrayList<>(); for (JSONObject jsonObject : jsonObjects) { Message message = new Message(); // 消息内容 Object content = jsonObject.get("content"); if (StringUtils.isEmpty(content)) { throw new ParameterMissingException("消息内容为空"); } else { message.setContent(String.valueOf(content)); } // 发送人 Object senderUu = jsonObject.get("senderUu"); Object senderEnuu = jsonObject.get("senderEnuu"); if (StringUtils.isEmpty(senderUu) || StringUtils.isEmpty(senderEnuu)) { throw new ParameterMissingException("发送人信息为空"); } else { message.setSenderUu(Long.valueOf(String.valueOf(senderUu))); message.setSenderEnuu(Long.valueOf(String.valueOf(senderEnuu))); } // 接收人 Object receiverUu = jsonObject.get("receiverUu"); Object receiverEnuu = jsonObject.get("receiverEnuu"); if (StringUtils.isEmpty(receiverUu) || StringUtils.isEmpty(receiverEnuu)) { throw new ParameterMissingException("接收人信息为空"); } else { message.setReceiverUu(Long.valueOf(String.valueOf(receiverUu))); message.setReceiverEnuu(Long.valueOf(String.valueOf(receiverEnuu))); } // 发送应用 Object producerApp = jsonObject.get("producerApp"); if (StringUtils.isEmpty(producerApp)) { throw new ParameterMissingException("发送应用为空"); } else { App app = appDao.findByName(String.valueOf(producerApp)); if (app == null) { throw new IllegalOperatorException("发送应用不存在"); } message.setProducerApp(app.getId()); } // 接收应用 Object consumerType = jsonObject.get("consumerType"); if (StringUtils.isEmpty(consumerType)) { throw new ParameterMissingException("接收应用类型为空"); } else { String type = String.valueOf(consumerType); // 消息接收类型为公共,即所有子应用共享 if (ConsumeType.PUBLIC.equals(type)) { List apps = appDao.findAll(); message.setConsumerApp(new HashSet<>(apps)); message.setConsumeType(type); } else { Object consumerApp = jsonObject.get("consumerApp"); if (consumerApp == null) { throw new ParameterMissingException("接收应用为空"); } else { // 取出通过逗号拼接的接收应用 String[] consumers = String.valueOf(consumerApp).split(SplitChar.COMMA); if (consumers.length < 1) { throw new ParameterMissingException("接收应用为空"); } Set consumerApps = new HashSet<>(); for (String consumer : consumers) { App app = appDao.findByName(consumer); if (app == null) { throw new IllegalOperatorException("接收应用不存在"); } consumerApps.add(app); } message.setConsumerApp(consumerApps); message.setConsumeType(consumers.length > 1 ? ConsumeType.MULTI : ConsumeType.SINGLE); } } } // 消息类型(暂时未定) Object type = jsonObject.get("type"); if (!StringUtils.isEmpty(type)) { message.setType(String.valueOf(type)); } // 推送类型 Object smsType = jsonObject.get("smsType"); if (StringUtils.isEmpty(smsType)) { message.setSmsType(SMSType.DONT_SEND); } else { message.setSmsType(String.valueOf(smsType)); } // 备注 Object remark = jsonObject.get("remark"); if (!StringUtils.isEmpty(remark)) { message.setRemark(String.valueOf(remark)); } // 来源id Object sourceId = jsonObject.get("sourceId"); if (!StringUtils.isEmpty(sourceId)) { message.setSourceId(Long.valueOf(String.valueOf(sourceId))); } // 邮件模板 Object mailTemplate = jsonObject.get("mailTemplate"); if (!StringUtils.isEmpty(mailTemplate)) { message.setMailTemplate(String.valueOf(mailTemplate)); } // 短信模板 Object smTemplate = jsonObject.get("smTemplate"); if (!StringUtils.isEmpty(smTemplate)) { message.setSmTemplate(String.valueOf(smTemplate)); } message.setIsRead(Constant.NO); message.setCreateTime(new Date()); message.setIsSent(Constant.NO); messages.add(message); } return messages; } /** * 推送消息(调用邮件、短信、IM接口) * @param messages 消息 * @param consumerApp 消费app * @return resultMap */ private Map sendMessageByAPI(List messages, String consumerApp) { Map resultMap = new HashMap<>(); if (!CollectionUtils.isEmpty(messages)) { for (Message message : messages) { try { UserView receiver = AccountUtils.getImUserByUserUU(message.getReceiverUu(), message.getReceiverEnuu()); if (receiver.getName() != null) { logger.info("接收人:" + receiver.getName()); UserView sender = AccountUtils.getImUserByUserUU(message.getSenderUu(), message.getSenderEnuu()); if (sender != null && sender.getName() != null && sender.getSpaceName() != null) { logger.info("发送人:" + sender.getName()); boolean sendSuccess = false; // 发送邮件 // if (message.getSmsType().contains(SMSType.MAIL)) { // sendMail(message, receiver); // } // 发送短息 if (message.getSmsType().contains(SMSType.SM)) { logger.info("开始推送短信"); sendSuccess = sendSM(message, receiver, sender); } // 发送IM if (message.getSmsType().contains(SMSType.IM)) { logger.info("开始推送IM"); sendSuccess = sendIM(message, receiver, consumerApp); } // 推送成功 if (sendSuccess) { pushSuccess(message, receiver, sender); } } else { logger.info("发送人信息为空,uu:" + message.getSenderUu() + ",enuu:" + message.getSenderEnuu()); } } else { logger.info("接收人姓名为空,uu:" + message.getReceiverUu() + ",enuu:" + message.getReceiverEnuu()); } } catch (Exception e) { message.setIsSent(Constant.ERROR); logger.info(e.getMessage()); } } messageDao.save(messages); } return resultMap; } /** * 发送邮件 * @param message 消息 * @param receiver 接收人 */ private void sendMail(Message message, User receiver) { if (message.getMailTemplate() != null && receiver.getSecondUID() != null) { HttpHeaders headers = new HttpHeaders(); MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8"); headers.setContentType(type); headers.add("Accept", MediaType.APPLICATION_JSON.toString()); JSONObject object = new JSONObject(); object.put("templateId", message.getMailTemplate()); object.put("receiver", receiver.getSecondUID()); object.put("params", message.getContent()); // HttpEntity formEntity = new HttpEntity(, headers); try { ResponseWrap responseWrap = HttpUtil.doPost(MAIL_CONSOLE_HOST + MAIL_SEND_URL, FlexJsonUtil.toJson(object)); } catch (Exception e) { e.printStackTrace(); } } } /** * 发送短信 * @param message 消息 * @param receiver 接收人 * @param sender 发送人 * @return 推送成功状态 */ private boolean sendSM(Message message, UserView receiver, UserView sender) { if (!StringUtils.isEmpty(message.getSmTemplate()) && !StringUtils.isEmpty(receiver.getUid())) { try { SmsMessage sms = new SmsMessage(); List obj = new ArrayList(); switch (message.getSmTemplate()) { // 公共询价单,普通短信 case "e14d502a-25b8-40a0-8acf-5c61ae38d763" : obj.add(receiver.getName()); obj.add(sender.getSpaceName()); obj.add(message.getRemark()); pushSm(sms, message, obj, receiver, sender); break; // 公共询价单,UU互联 case "6e094dcf-f2c7-462a-9686-b2d32d684a78" : obj.add(message.getSourceId()); obj.add(message.getReceiverEnuu()); obj.add(receiver.getUid()); pushSm(sms, message, obj, receiver, sender); break; // 公共询价统计 case "e6320a3c-89ac-4c77-a75f-62a727bce654" : obj.add(message.getRemark()); pushSm(sms, message, obj, receiver, sender); default: break; } return true; } catch (Exception e) { logger.info("短信推送异常:" + e.getMessage()); e.printStackTrace(); return false; } } return false; } /** * 调用短信接口 * @param sms 短信model * @param message 消息 * @param param 短信参数 * @param receiver 接收人 * @param sender 发送人 */ private void pushSm(SmsMessage sms, Message message, List param, UserView receiver, UserView sender) { sms.setParams(param); sms.setReceiver(receiver.getUid()); sms.setTemplateId(message.getSmTemplate()); String response = com.uas.ps.message.util.HttpUtil .sendPost(messageUrl, FastjsonUtils.toJson(sms)); logger.info("短信推送成功:" + response); } public static void main(String[] args) { SmsMessage smsMessage = new SmsMessage(); List param = new ArrayList<>(); param.add("测试公司"); param.add("测试型号"); smsMessage.setParams(param); smsMessage.setReceiver("13632823241"); smsMessage.setTemplateId("7879bfda-f871-4a95-9430-54d1ea00b198"); String response = com.uas.ps.message.util.HttpUtil .sendPost("http://10.10.100.136:8080/sms/send", FastjsonUtils.toJson(smsMessage)); System.out.println(response); } /** * 设置推送送成功 * @param message 消息 * @param receiver 接收人 * @param sender 发送人 */ private void pushSuccess(Message message, UserView receiver, UserView sender) { message.setIsSent(Constant.YES); message.setReceiver(FastjsonUtils.toJson(receiver)); message.setSender(FastjsonUtils.toJson(sender)); } /** * 发送IM * @param message 消息 * @param receiver 接收人 * @param consumerApp 消费app * @return 推送成功状态 */ private boolean sendIM(Message message, UserView receiver, String consumerApp) { Map params = new HashMap<>(); if (!StringUtils.isEmpty(receiver.getDialectUID())) { params.put("master", receiver.getSpaceName()); // 账套 公司名称 params.put("userid", receiver.getDialectUID()); // 推送目标用户 params.put("title", message.getType() == null ? "" : message.getType()); // 推送标题 params.put("content", message.getContent()); // 正文 params.put("enUU", message.getReceiverEnuu()); // UU号 params.put("masterId", null); params.put("url", String.format(PUBLIC_INQUIRY_IM_URL, message.getSourceId(), message.getReceiverEnuu(), receiver.getUid())); // 跳转链接地址 params.put("pageTitle", message.getType() == null ? "" : message.getType()); params.put("platform", "B2B"); // 系统名称,ERP或B2B try { ResponseWrap res = HttpUtil.doPost(PROD_URL, params); if (res.isSuccess()) { logger.info("IM推送成功"); return true; } else { logger.info("IM推送失败:" + res.getContent()); } } catch (Exception e) { e.printStackTrace(); return false; } } return false; } }