Explorar el Código

Merge remote-tracking branch 'origin/dev' into test

wanghui hace 8 años
padre
commit
b42a3bcaa6
Se han modificado 30 ficheros con 826 adiciones y 123 borrados
  1. 81 0
      src/main/java/com/goafanti/admin/controller/AdminMessageController.java
  2. 0 1
      src/main/java/com/goafanti/admin/service/AdminService.java
  3. 30 0
      src/main/java/com/goafanti/admin/service/MessageService.java
  4. 120 0
      src/main/java/com/goafanti/admin/service/impl/MessageServiceImpl.java
  5. 4 2
      src/main/java/com/goafanti/common/bo/Result.java
  6. 7 0
      src/main/java/com/goafanti/common/dao/MessageFromSystemMapper.java
  7. 1 0
      src/main/java/com/goafanti/common/dao/MessageProducerMapper.java
  8. 0 25
      src/main/java/com/goafanti/core/message/BusinessMessageProducerManager.java
  9. 0 5
      src/main/java/com/goafanti/core/message/MessageConsumerManager.java
  10. 0 13
      src/main/java/com/goafanti/core/message/MessageHandler.java
  11. 0 9
      src/main/java/com/goafanti/core/message/MessageProducerManager.java
  12. 0 18
      src/main/java/com/goafanti/core/message/SystemMessageProducerManager.java
  13. 1 0
      src/main/java/com/goafanti/core/shiro/session/CustomSessionManager.java
  14. 5 5
      src/main/java/com/goafanti/easemob/queue/RedisQueueListener.java
  15. 21 0
      src/main/java/com/goafanti/message/BusinessMessageProducerManager.java
  16. 162 0
      src/main/java/com/goafanti/message/JGMessageHelper.java
  17. 10 0
      src/main/java/com/goafanti/message/MessageProducerManager.java
  18. 19 0
      src/main/java/com/goafanti/message/SystemMessageProducerManager.java
  19. 55 0
      src/main/java/com/goafanti/message/bo/Audience.java
  20. 36 0
      src/main/java/com/goafanti/message/bo/JGMessage.java
  21. 17 29
      src/main/java/com/goafanti/message/bo/Message.java
  22. 23 0
      src/main/java/com/goafanti/message/bo/MessageAdapter.java
  23. 25 0
      src/main/java/com/goafanti/message/bo/Options.java
  24. 4 0
      src/main/java/com/goafanti/message/enums/OperatorType.java
  25. 5 0
      src/main/java/com/goafanti/message/enums/SubjectType.java
  26. 150 0
      src/main/java/com/goafanti/message/queue/MessageRedisQueue.java
  27. 21 0
      src/main/java/com/goafanti/message/queue/MessageRedisQueueListener.java
  28. 5 0
      src/main/java/com/goafanti/message/queue/RedisQueueListener.java
  29. 5 1
      src/main/resources/props/config_local.properties
  30. 19 15
      src/main/resources/spring/spring-shiro.xml

+ 81 - 0
src/main/java/com/goafanti/admin/controller/AdminMessageController.java

@@ -0,0 +1,81 @@
+package com.goafanti.admin.controller;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+
+import com.goafanti.admin.service.AdminService;
+import com.goafanti.admin.service.MessageService;
+import com.goafanti.common.bo.Result;
+import com.goafanti.common.constant.AFTConstants;
+import com.goafanti.common.constant.ErrorConstants;
+import com.goafanti.common.controller.CertifyApiController;
+import com.goafanti.user.service.UserService;
+
+/**
+ *  消息推送
+ * @author Administrator
+ *
+ */
+@Controller
+@RequestMapping(value = "/api/admin/message")
+public class AdminMessageController extends CertifyApiController{
+	
+	@Autowired
+	private UserService userServiceImpl;
+	@Autowired
+	private AdminService adminServiceImpl;
+	@Autowired
+	private MessageService messageServiceImpl;
+	/**
+	 * 
+	 * @param companyIds 公司集
+	 * @param userIds 用户集
+	 * @param societyTags 社会属性集
+	 * @param provinceIds 省份集
+	 * @param cityIds 城市集
+	 * @param areas 区域集
+	 * @param roles 角色集
+	 * @param subject  0-运营消息 , 1-客户消息 , 2-技淘推荐
+	 * @throws ParseException 
+	 */
+	@RequestMapping(value = "/createSystemMessage", method = RequestMethod.POST)
+	public Result createSystemMessage(String userIds,String companyIds,String societyTags,String provinceIds,String cityIds,String areaIds,String roles,
+			String title,String body,Integer subject,Integer type,String createTime) throws ParseException{
+		Result res = new Result();
+		if(null == type){
+			res.getError().add(buildError(ErrorConstants.PARAM_EMPTY_ERROR, "必须指定人员类型"));
+			return res;
+		}
+		if(null == subject){
+			res.getError().add(buildError(ErrorConstants.PARAM_EMPTY_ERROR, "必须指定消息类型"));
+			return res;
+		}
+		if(StringUtils.isBlank(title) || StringUtils.isBlank(body)){
+			res.getError().add(buildError(ErrorConstants.PARAM_EMPTY_ERROR, "消息是的标题和内容不能为空"));
+			return res;
+		}
+		Map<Integer,String> selectMap = new HashMap<Integer, String>();
+		if(type == 0) selectMap.put(type, userIds);
+		if(type == 1) selectMap.put(type, societyTags);
+		if(type == 2) selectMap.put(type, provinceIds);
+		if(type == 3) selectMap.put(type, cityIds);
+		if(type == 4) selectMap.put(type, areaIds);
+		if(type == 5) selectMap.put(type, companyIds);
+		if(type == 6) selectMap.put(type, roles);
+		if(StringUtils.isBlank(selectMap.get(type))){
+			res.getError().add(buildError(ErrorConstants.PARAM_EMPTY_ERROR, "指定人员不能为空"));
+			return res;
+		}
+		SimpleDateFormat format = new SimpleDateFormat(AFTConstants.YYYYMMDDHHMMSS);
+		messageServiceImpl.insertSystemMessage(selectMap, title, body, subject,type,format.parse(createTime));
+		return res;
+	}
+}

+ 0 - 1
src/main/java/com/goafanti/admin/service/AdminService.java

@@ -6,7 +6,6 @@ import java.util.Map;
 import com.goafanti.admin.bo.AdminDetail;
 import com.goafanti.admin.bo.AdminListBo;
 import com.goafanti.common.model.Admin;
-import com.goafanti.common.model.AdminLocation;
 import com.goafanti.core.mybatis.page.Pagination;
 
 public interface AdminService {

+ 30 - 0
src/main/java/com/goafanti/admin/service/MessageService.java

@@ -0,0 +1,30 @@
+package com.goafanti.admin.service;
+
+import java.util.Date;
+import java.util.Map;
+
+public interface MessageService {
+	/**
+	 * 查找推送用户
+	 * @param selectMap
+	 * @param subject
+	 * @return
+	 */
+	String selectSendUser(Map<Integer,String> selectMap);
+	/**
+	 * 查询推送运营人员
+	 * @param selectMap
+	 * @param subject
+	 * @return
+	 */
+	String selectSendAdmin(Map<Integer,String> selectMap);
+	/**
+	 * 
+	 * @param selectMap 
+	 * @param title
+	 * @param body
+	 * @param subject
+	 * @return
+	 */
+	int insertSystemMessage(Map<Integer, String> selectMap, String title, String body, Integer subject,Integer type,Date createTime);
+}

+ 120 - 0
src/main/java/com/goafanti/admin/service/impl/MessageServiceImpl.java

@@ -0,0 +1,120 @@
+package com.goafanti.admin.service.impl;
+
+import java.util.Date;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.UUID;
+
+import org.apache.shiro.SecurityUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import com.goafanti.admin.service.MessageService;
+import com.goafanti.common.dao.MessageFromSystemMapper;
+import com.goafanti.common.dao.UserMapper;
+import com.goafanti.common.model.Admin;
+import com.goafanti.common.model.MessageFromSystem;
+
+@Service
+public class MessageServiceImpl implements MessageService{
+	private final Integer DEFAULT_SENDER = 0;//默认发送者ID
+	@Autowired
+	private UserMapper userMapper;
+	@Autowired
+	private MessageFromSystemMapper messageFromSystemMapper;
+	@Override
+	public String selectSendUser(Map<Integer, String> selectMap) {
+		Iterator<Entry<Integer, String>> iterator= selectMap.entrySet().iterator();
+		if(iterator.hasNext()){
+			Entry<Integer, String> entry = iterator.next();
+			Integer key = entry.getKey();
+			String value = entry.getValue();
+			if(0 == key) return value;
+			String sql = "";
+			switch (key) {
+			case 0:
+				break;
+			case 1: //社会属性
+				sql = "select group_concat(id) from user where";
+				StringBuffer tmp = new StringBuffer();
+				String[] societys = value.split(",");
+				for(String s:societys){
+					tmp.append("or society_tag like "+s);
+				}
+				if(tmp.length()>0) sql = sql + "(" +tmp.substring(3) + ")" +"  and status != 2";
+				break;
+			case 2:
+				sql = "select group_concat(a.id) from user a left join user_identity b on a.id = b.uid where b.province in (" + value + ") and a.status != 2";
+				break;
+			case 3:
+				sql = "select group_concat(a.id) from user a left join user_identity b on a.id = b.uid where b.city in (" + value + ") and a.status != 2";
+				break;
+			case 4:
+				sql = "select group_concat(a.id) from user a left join user_identity b on a.id = b.uid where b.area in (" + value + ") and a.status != 2";
+				break;
+			default:
+				break;
+			}
+			if(!sql.equals("")) return messageFromSystemMapper.selectSendTarget(sql);
+		}
+		return "";
+	}
+
+	@Override
+	public String selectSendAdmin(Map<Integer, String> selectMap) {
+		Iterator<Entry<Integer, String>> iterator= selectMap.entrySet().iterator();
+		if(iterator.hasNext()){
+			Entry<Integer, String> entry = iterator.next();
+			Integer key = entry.getKey();
+			String value = entry.getValue();
+			if(0 == key) return value;
+			String sql = "";
+			switch (key) {
+			case 0:
+				break;
+			case 5: //分公司
+				sql = "select group_concat(id) from admin where department_id in ("+ value + ")";
+				break;
+			case 6: // 角色
+				sql = "select group_concat(id) from admin a left join user_role b on a.id = b.uid where b.id in (" + value + ")";
+				break;
+			default:
+				break;
+			}
+			if(!sql.equals("")) return messageFromSystemMapper.selectSendTarget(sql);
+		}
+		return "";
+	}
+
+	@Override
+	public int insertSystemMessage(Map<Integer, String> selectMap, String title, String body, Integer subject,Integer type,Date createTime) {
+		MessageFromSystem mfs = new MessageFromSystem();
+		mfs.setId(UUID.randomUUID().toString());
+		mfs.setTitle(title);
+		mfs.setBody(body);
+		mfs.setCreateTime(createTime);
+		mfs.setSubject(subject);
+		mfs.setConsumerType(type);
+		if(SecurityUtils.getSubject().getPrincipal() instanceof Admin){
+			Admin admin = (Admin)SecurityUtils.getSubject().getPrincipal();
+			mfs.setCreater(admin.getName());
+			mfs.setCreater(admin.getId());
+		}
+		messageFromSystemMapper.insert(mfs);
+		String[] target = null;
+		if(subject == 0){
+			target = selectSendUser(selectMap).split(",");
+			for(String userId : target){
+				
+			}
+		}else if(subject == 1){
+			target = selectSendAdmin(selectMap).split(",");
+			for(String adminId : target){
+				
+			}
+		}
+		return 1;
+	}
+	
+}

+ 4 - 2
src/main/java/com/goafanti/common/bo/Result.java

@@ -3,13 +3,15 @@ package com.goafanti.common.bo;
 import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.List;
+
+import org.apache.shiro.SecurityUtils;
 public class Result {
 	private Object		data;
 	private List<Error>	error	= new ArrayList<Error>();
 	private Serializable token;
 	public Result() {
-		/*if(TokenManager.isLogin())
-		this.token = SecurityUtils.getSubject().getSession().getId();*/
+		this.token = SecurityUtils.getSubject().getSession().getId();
+		System.out.println("返回=============="+token);
 	}
 
 	public Result(Object data) {

+ 7 - 0
src/main/java/com/goafanti/common/dao/MessageFromSystemMapper.java

@@ -93,4 +93,11 @@ public interface MessageFromSystemMapper {
      * @mbg.generated Thu Dec 14 21:04:23 CST 2017
      */
     int updateByPrimaryKey(MessageFromSystem record);
+    
+    /**
+     * 查询发送目标
+     * @param sql
+     * @return
+     */
+    String selectSendTarget(@Param("sql")String sql);
 }

+ 1 - 0
src/main/java/com/goafanti/common/dao/MessageProducerMapper.java

@@ -93,4 +93,5 @@ public interface MessageProducerMapper {
      * @mbg.generated Thu Dec 14 21:04:23 CST 2017
      */
     int updateByPrimaryKey(MessageProducer record);
+
 }

+ 0 - 25
src/main/java/com/goafanti/core/message/BusinessMessageProducerManager.java

@@ -1,25 +0,0 @@
-package com.goafanti.core.message;
-
-import java.util.List;
-import java.util.concurrent.BlockingQueue;
-
-import com.goafanti.message.bo.Message;
-
-public class BusinessMessageProducerManager implements MessageProducerManager,Runnable{
-	BlockingQueue<Message> messageQueue;
-	BusinessMessageProducerManager(BlockingQueue<Message> messageQueue){
-		this.messageQueue = messageQueue;
-	}
-	@Override
-	public List<Message> createMessage() {
-		// TODO Auto-generated method stub
-		return null;
-	}
-
-	@Override
-	public void run() {
-		// TODO Auto-generated method stub
-		
-	}
-	
-}

+ 0 - 5
src/main/java/com/goafanti/core/message/MessageConsumerManager.java

@@ -1,5 +0,0 @@
-package com.goafanti.core.message;
-
-public abstract interface MessageConsumerManager {
-	void consumeMessage();
-}

+ 0 - 13
src/main/java/com/goafanti/core/message/MessageHandler.java

@@ -1,13 +0,0 @@
-package com.goafanti.core.message;
-
-import java.util.concurrent.BlockingQueue;
-import com.goafanti.message.bo.Message;
-
-public class MessageHandler {
-	BlockingQueue<Message> messageQuenue;
-	
- 	void sendMessage(MessageConsumerManager consumerManager){
-		
-	}
- 
-}

+ 0 - 9
src/main/java/com/goafanti/core/message/MessageProducerManager.java

@@ -1,9 +0,0 @@
-package com.goafanti.core.message;
-
-import java.util.List;
-
-import com.goafanti.message.bo.Message;
-
-public  abstract interface MessageProducerManager {
-	List<Message> createMessage();
-}

+ 0 - 18
src/main/java/com/goafanti/core/message/SystemMessageProducerManager.java

@@ -1,18 +0,0 @@
-package com.goafanti.core.message;
-
-import java.util.List;
-import java.util.concurrent.BlockingQueue;
-
-import com.goafanti.message.bo.Message;
-
-public class SystemMessageProducerManager implements MessageProducerManager{
-	private BlockingQueue<Message> messageQueue;
-	public SystemMessageProducerManager(BlockingQueue<Message> messageQueue){
-		this.messageQueue = messageQueue;
-	}
-	@Override
-	public List<Message> createMessage() {
-		// TODO Auto-generated method stub
-		return null;
-	}
-}

+ 1 - 0
src/main/java/com/goafanti/core/shiro/session/CustomSessionManager.java

@@ -31,6 +31,7 @@ public class CustomSessionManager extends DefaultWebSessionManager {
 	@Override
 	protected Serializable getSessionId(ServletRequest request, ServletResponse response) {
 		String sid = request.getParameter("token");
+		System.out.println("请求 token=============="+sid);
 		if (StringUtils.isNotBlank(sid)) {
 			// 是否将sid保存到cookie,浏览器模式下使用此参数。
 			if (WebUtils.isTrue(request, "AFT_SID")) {

+ 5 - 5
src/main/java/com/goafanti/easemob/queue/RedisQueueListener.java

@@ -1,5 +1,5 @@
-package com.goafanti.easemob.queue;
-
-public interface RedisQueueListener<T> {
-	public void onMessage(T value);
-}
+package com.goafanti.easemob.queue;
+
+public interface RedisQueueListener<T> {
+	public void onMessage(T value);
+}

+ 21 - 0
src/main/java/com/goafanti/message/BusinessMessageProducerManager.java

@@ -0,0 +1,21 @@
+package com.goafanti.message;
+
+import java.util.List;
+import java.util.concurrent.BlockingQueue;
+
+import com.goafanti.common.model.MessageFromBusiness;
+import com.goafanti.message.bo.JGMessage;
+
+public class BusinessMessageProducerManager implements MessageProducerManager{
+	private BlockingQueue<JGMessage> messageQueue;
+	private List<MessageFromBusiness> messageList;
+	BusinessMessageProducerManager(BlockingQueue<JGMessage> messageQueue,List<MessageFromBusiness> messageList){
+		this.messageQueue = messageQueue;
+		this.messageList = messageList;
+	}
+	@Override
+	public List<JGMessage> createMessage() {
+		return null;
+	}
+	
+}

+ 162 - 0
src/main/java/com/goafanti/message/JGMessageHelper.java

@@ -0,0 +1,162 @@
+package com.goafanti.message;
+
+import java.io.IOException;
+import java.util.Base64;
+import java.util.Optional;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.config.RequestConfig;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.client.methods.HttpRequestBase;
+import org.apache.http.client.methods.HttpUriRequest;
+import org.apache.http.concurrent.FutureCallback;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
+import org.apache.http.impl.nio.client.HttpAsyncClients;
+import org.apache.http.util.EntityUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.DisposableBean;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.goafanti.common.utils.LoggerUtils;
+import com.goafanti.message.bo.JGMessage;
+import com.goafanti.message.bo.MessageAdapter;
+import com.goafanti.message.queue.MessageRedisQueue;
+
+/**
+ * 极光推送
+ * @author Administrator
+ *
+ */
+public class JGMessageHelper implements InitializingBean, DisposableBean{
+	@Value(value = "${jiguang.appKey}")
+	private String appKey; 
+	@Value(value = "${jiguang.masterSecret}")
+	private String masterSecret;
+	@Value(value = "${jiguang.pushUrl}")
+	private String pushUrl;
+	@Autowired
+	private MessageRedisQueue jedisQueue;
+	private static final Optional<Integer> UN_AUTH	= Optional.of(401);//未验证
+	private static final Optional<Integer> NOT_SUITABLE = Optional.of(405);//不支持该请求方法
+	private static final Optional<Integer> EXCEED_THE_LIMIT = Optional.of(429);//超过频率限制
+	private static final Logger logger = LoggerFactory.getLogger(JGMessage.class);
+	public JSONObject send(MessageAdapter messageAdapter){
+		HttpUriRequest req = buildRequest(messageAdapter.getJgMessage());
+		CloseableHttpAsyncClient httpclient = HttpAsyncClients.createDefault();
+		httpclient.start();
+		LoggerUtils.debug(logger, "SEND TO JGPUSH SERVER: [%s] - [%s]", req.getMethod(), req.getURI());
+		Future<HttpResponse> future = httpclient.execute(req, null);
+		try {
+			HttpResponse response = future.get();
+			Optional<Integer> rescode = getResCode(response);
+			if(rescode.equals(UN_AUTH)){
+				LoggerUtils.debug(logger, "Request Not Authorized");
+			}else if(rescode.equals(NOT_SUITABLE)){
+				LoggerUtils.debug(logger, "Request Not Allow");
+			}else if(rescode.equals(EXCEED_THE_LIMIT)){
+				LoggerUtils.debug(logger, "Request Too Frequent");
+				sendLater(messageAdapter);
+			}else{
+				HttpEntity entity = response.getEntity();
+				if (entity != null) {
+					try {
+						String resStr = EntityUtils.toString(entity, "UTF-8");
+						return (JSONObject) JSON.parse(resStr);
+					} catch (Exception e) {
+						LoggerUtils.debug(logger, e.getMessage(), e);
+					}
+				}
+			}
+			LoggerUtils.debug(logger, response);
+		} catch (InterruptedException | ExecutionException e) {
+			LoggerUtils.debug(logger, e.getMessage(), e);
+		} finally {
+			try {
+				httpclient.close();
+			} catch (IOException e) {
+			}
+		}
+		return messageAdapter.getTryCount()>1?null:send(messageAdapter);
+	}
+
+	public void sendLater(MessageAdapter messageAdapter) {
+		jedisQueue.pushFromTail(messageAdapter);
+	}
+	
+	private HttpUriRequest buildRequest(JGMessage jgMessage){
+		String authorization = Base64.getEncoder().encodeToString((appKey+":"+pushUrl).getBytes());
+		HttpUriRequest req = new HttpPost(pushUrl);
+		req.addHeader("Authorization", "Basic "+authorization);
+		((HttpPost) req).setEntity(new StringEntity(JSONObject.toJSONString(jgMessage), "UTF_8"));
+		((HttpRequestBase) req).setConfig(RequestConfig.custom().setConnectTimeout(10000)
+				.setConnectionRequestTimeout(10000).setSocketTimeout(10000).build());
+		req.addHeader("Content-Type", "application/json");
+		return req;
+	}
+	
+	private Optional<Integer> getResCode(HttpResponse response) {
+		return Optional.ofNullable(response).map(res -> res.getStatusLine()).map(sl -> sl.getStatusCode());
+	}
+	
+	public void sendAsync(MessageAdapter messageAdapter) {
+		HttpUriRequest req = buildRequest(messageAdapter.getJgMessage());
+		CloseableHttpAsyncClient httpclient = HttpAsyncClients.createDefault();
+		httpclient.start();
+		LoggerUtils.debug(logger, "SEND TO JGPUSH SERVER: [%s] - [%s]", req.getMethod(), req.getURI());
+		httpclient.execute(req, new FutureCallback<HttpResponse>() {
+			@Override
+			public void failed(Exception ex) {
+				sendLater(messageAdapter.tryCount((messageAdapter.getTryCount()+1)));
+				close();
+			}
+
+			@Override
+			public void completed(HttpResponse result) {
+				Optional<Integer> rescode = getResCode(result);
+				if(rescode.equals(UN_AUTH)){
+					LoggerUtils.debug(logger, "Request Not Authorized");
+				}else if(rescode.equals(NOT_SUITABLE)){
+					LoggerUtils.debug(logger, "Request Not Allow");
+				}else if(rescode.equals(EXCEED_THE_LIMIT)){
+					LoggerUtils.debug(logger, "Request Too Frequent");
+					sendLater(messageAdapter);
+				}
+				LoggerUtils.debug(logger, result);
+				close();
+			}
+
+			@Override
+			public void cancelled() {
+				close();
+				LoggerUtils.debug(logger, "CANCELLED: [%s] - [%s]", req.getMethod(), req.getURI());
+			}
+
+			private void close() {
+				try {
+					httpclient.close();
+				} catch (IOException e) {
+				}
+			}
+		});
+	}
+
+	@Override
+	public void destroy() throws Exception {
+		LoggerUtils.debug(logger, "消息系统关闭");
+		
+	}
+	@Override
+	public void afterPropertiesSet() throws Exception {
+		
+	}
+
+}

+ 10 - 0
src/main/java/com/goafanti/message/MessageProducerManager.java

@@ -0,0 +1,10 @@
+package com.goafanti.message;
+
+import java.util.List;
+
+import com.goafanti.message.bo.JGMessage;
+
+public  abstract interface MessageProducerManager {
+	List<JGMessage> createMessage();
+	
+}

+ 19 - 0
src/main/java/com/goafanti/message/SystemMessageProducerManager.java

@@ -0,0 +1,19 @@
+package com.goafanti.message;
+
+import java.util.List;
+import java.util.concurrent.BlockingQueue;
+
+import com.goafanti.message.bo.JGMessage;
+
+public class SystemMessageProducerManager implements MessageProducerManager{
+	private BlockingQueue<JGMessage> messageQueue;
+	public SystemMessageProducerManager(BlockingQueue<JGMessage> messageQueue){
+		this.messageQueue = messageQueue;
+	}
+	
+	@Override
+	public List<JGMessage> createMessage() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+}

+ 55 - 0
src/main/java/com/goafanti/message/bo/Audience.java

@@ -0,0 +1,55 @@
+package com.goafanti.message.bo;
+
+import com.alibaba.fastjson.JSONArray;
+
+public class Audience {
+	private JSONArray tag;
+	private JSONArray tag_and;
+	private JSONArray tag_not;
+	private JSONArray alias;
+	private JSONArray registration_id;
+	private JSONArray segment;
+	private JSONArray abtest;
+	public JSONArray getTag() {
+		return tag;
+	}
+	public void setTag(JSONArray tag) {
+		this.tag = tag;
+	}
+	public JSONArray getTag_and() {
+		return tag_and;
+	}
+	public void setTag_and(JSONArray tag_and) {
+		this.tag_and = tag_and;
+	}
+	public JSONArray getTag_not() {
+		return tag_not;
+	}
+	public void setTag_not(JSONArray tag_not) {
+		this.tag_not = tag_not;
+	}
+	public JSONArray getAlias() {
+		return alias;
+	}
+	public void setAlias(JSONArray alias) {
+		this.alias = alias;
+	}
+	public JSONArray getRegistration_id() {
+		return registration_id;
+	}
+	public void setRegistration_id(JSONArray registration_id) {
+		this.registration_id = registration_id;
+	}
+	public JSONArray getSegment() {
+		return segment;
+	}
+	public void setSegment(JSONArray segment) {
+		this.segment = segment;
+	}
+	public JSONArray getAbtest() {
+		return abtest;
+	}
+	public void setAbtest(JSONArray abtest) {
+		this.abtest = abtest;
+	}
+}

+ 36 - 0
src/main/java/com/goafanti/message/bo/JGMessage.java

@@ -0,0 +1,36 @@
+package com.goafanti.message.bo;
+
+public class JGMessage {
+	private final String[] platform = new String[]{"android","ios"}; //推送平台
+	private String cid; //发送消息唯一标示
+	private Audience audience; //推送对象
+	private Message message; //推送内容
+	private Options options; //可选参数
+	public String[] getPlatform() {
+		return platform;
+	}
+	public String getCid() {
+		return cid;
+	}
+	public void setCid(String cid) {
+		this.cid = cid;
+	}
+	public Audience getAudience() {
+		return audience;
+	}
+	public void setAudience(Audience audience) {
+		this.audience = audience;
+	}
+	public Message getMessage() {
+		return message;
+	}
+	public void setMessage(Message message) {
+		this.message = message;
+	}
+	public Options getOptions() {
+		return options;
+	}
+	public void setOptions(Options options) {
+		this.options = options;
+	}
+}

+ 17 - 29
src/main/java/com/goafanti/message/bo/Message.java

@@ -1,17 +1,17 @@
 package com.goafanti.message.bo;
 
+import com.alibaba.fastjson.JSONObject;
+
 public class Message {
-	private String id;
+	private String msg_content;
 	private String title;
-	private String body;
-	private String creater;
-	private String createTime;
-	private String url;
-	public String getId() {
-		return id;
+	private String content_type;
+	private JSONObject extras;
+	public String getMsg_content() {
+		return msg_content;
 	}
-	public void setId(String id) {
-		this.id = id;
+	public void setMsg_content(String msg_content) {
+		this.msg_content = msg_content;
 	}
 	public String getTitle() {
 		return title;
@@ -19,28 +19,16 @@ public class Message {
 	public void setTitle(String title) {
 		this.title = title;
 	}
-	public String getBody() {
-		return body;
-	}
-	public void setBody(String body) {
-		this.body = body;
-	}
-	public String getCreater() {
-		return creater;
-	}
-	public void setCreater(String creater) {
-		this.creater = creater;
-	}
-	public String getCreateTime() {
-		return createTime;
+	public String getContent_type() {
+		return content_type;
 	}
-	public void setCreateTime(String createTime) {
-		this.createTime = createTime;
+	public void setContent_type(String content_type) {
+		this.content_type = content_type;
 	}
-	public String getUrl() {
-		return url;
+	public JSONObject getExtras() {
+		return extras;
 	}
-	public void setUrl(String url) {
-		this.url = url;
+	public void setExtras(JSONObject extras) {
+		this.extras = extras;
 	}
 }

+ 23 - 0
src/main/java/com/goafanti/message/bo/MessageAdapter.java

@@ -0,0 +1,23 @@
+package com.goafanti.message.bo;
+
+public class MessageAdapter extends JGMessage{
+	private int			tryCount = 0;
+	private JGMessage   jgMessage   ;
+	public int getTryCount() {
+		return tryCount;
+	}
+	public void setTryCount(int tryCount) {
+		this.tryCount = tryCount;
+	}
+	public JGMessage getJgMessage() {
+		return jgMessage;
+	}
+	public void setJgMessage(JGMessage jgMessage) {
+		this.jgMessage = jgMessage;
+	}
+	
+	public MessageAdapter tryCount(int tryCount){
+		this.tryCount = tryCount;
+		return this;
+	}
+}

+ 25 - 0
src/main/java/com/goafanti/message/bo/Options.java

@@ -0,0 +1,25 @@
+package com.goafanti.message.bo;
+
+public class Options {
+	private int sendno;//发送序号
+	private int time_to_live;//最长离线时间
+	private int big_push_duration;//定速推送时长
+	public int getSendno() {
+		return sendno;
+	}
+	public void setSendno(int sendno) {
+		this.sendno = sendno;
+	}
+	public int getTime_to_live() {
+		return time_to_live;
+	}
+	public void setTime_to_live(int time_to_live) {
+		this.time_to_live = time_to_live;
+	}
+	public int getBig_push_duration() {
+		return big_push_duration;
+	}
+	public void setBig_push_duration(int big_push_duration) {
+		this.big_push_duration = big_push_duration;
+	}
+}

+ 4 - 0
src/main/java/com/goafanti/message/enums/OperatorType.java

@@ -0,0 +1,4 @@
+package com.goafanti.message.enums;
+
+public class OperatorType {
+}

+ 5 - 0
src/main/java/com/goafanti/message/enums/SubjectType.java

@@ -0,0 +1,5 @@
+package com.goafanti.message.enums;
+
+public abstract class SubjectType {
+	
+}

+ 150 - 0
src/main/java/com/goafanti/message/queue/MessageRedisQueue.java

@@ -0,0 +1,150 @@
+package com.goafanti.message.queue;
+
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
+import org.springframework.beans.factory.DisposableBean;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.data.redis.connection.RedisConnection;
+import org.springframework.data.redis.connection.RedisConnectionFactory;
+import org.springframework.data.redis.core.BoundListOperations;
+import org.springframework.data.redis.core.RedisConnectionUtils;
+import org.springframework.data.redis.core.RedisTemplate;
+
+import com.goafanti.message.bo.JGMessage;
+
+public class MessageRedisQueue implements InitializingBean, DisposableBean {
+	private RedisTemplate<String, Object>		redisTemplate;
+	private String								key;
+	private RedisConnectionFactory				factory;
+	private RedisConnection						connection;
+	private BoundListOperations<String, Object>	listOperations;
+
+	private Lock								lock	= new ReentrantLock();
+
+	private RedisQueueListener<JGMessage>	listener;
+	private Thread								listenerThread;
+
+	private boolean								isClosed;
+
+	public void setRedisTemplate(RedisTemplate<String, Object> redisTemplate) {
+		this.redisTemplate = redisTemplate;
+	}
+
+	public void setListener(RedisQueueListener<JGMessage> listener) {
+		this.listener = listener;
+	}
+
+	public void setKey(String key) {
+		this.key = key;
+	}
+
+	@Override
+	public void afterPropertiesSet() throws Exception {
+		factory = redisTemplate.getConnectionFactory();
+		connection = RedisConnectionUtils.getConnection(factory);
+
+		listOperations = redisTemplate.boundListOps(key);
+		if (listener != null) {
+			listenerThread = new ListenerThread();
+			listenerThread.setDaemon(true);
+			listenerThread.start();
+		}
+	}
+
+	/**
+	 * blocking remove and get last item from queue:BRPOP
+	 * 
+	 * @return
+	 */
+	public Object takeFromTail(int timeout) throws InterruptedException {
+		lock.lockInterruptibly();
+		try {
+			return listOperations.rightPop(timeout, TimeUnit.SECONDS);
+		} finally {
+			lock.unlock();
+		}
+	}
+
+	public Object takeFromTail() throws InterruptedException {
+		return takeFromTail(0);
+	}
+
+	/**
+	 * 从队列的头,插入
+	 */
+	public void pushFromHead(Object value) {
+		listOperations.leftPush(value);
+	}
+
+	public void pushFromTail(Object value) {
+		listOperations.rightPush(value);
+	}
+
+	/**
+	 * noblocking
+	 * 
+	 * @return null if no item in queue
+	 */
+	public Object removeFromHead() {
+		return listOperations.leftPop();
+	}
+
+	public Object removeFromTail() {
+		return listOperations.rightPop();
+	}
+
+	/**
+	 * blocking remove and get first item from queue:BLPOP
+	 * 
+	 * @return
+	 */
+	public Object takeFromHead(int timeout) throws InterruptedException {
+		lock.lockInterruptibly();
+		try {
+			return listOperations.leftPop(timeout, TimeUnit.SECONDS);
+		} finally {
+			lock.unlock();
+		}
+	}
+
+	public Object takeFromHead() throws InterruptedException {
+		return takeFromHead(0);
+	}
+
+	@Override
+	public void destroy() throws Exception {
+		if (isClosed) {
+			return;
+		}
+		shutdown();
+		RedisConnectionUtils.releaseConnection(connection, factory);
+	}
+
+	private void shutdown() {
+		try {
+			listenerThread.interrupt();
+		} catch (Exception e) {
+		}
+	}
+
+	private class ListenerThread extends Thread {
+		@Override
+		public void run() {
+			try {
+				while (true) {
+					Object value = takeFromHead();
+					// 逐个执行
+					if (value != null) {
+						try {
+							listener.onMessage((JGMessage) value);
+						} catch (Exception e) {
+						}
+					}
+				}
+			} catch (InterruptedException e) {
+			}
+		}
+	}
+}

+ 21 - 0
src/main/java/com/goafanti/message/queue/MessageRedisQueueListener.java

@@ -0,0 +1,21 @@
+package com.goafanti.message.queue;
+
+import org.springframework.beans.factory.annotation.Autowired;
+
+import com.goafanti.message.JGMessageHelper;
+import com.goafanti.message.bo.MessageAdapter;
+
+
+public class MessageRedisQueueListener implements RedisQueueListener<MessageAdapter>{
+	@Autowired
+	JGMessageHelper jgMessageHelper;
+
+	@Override
+	public void onMessage(MessageAdapter messageAdapter) {
+		if (messageAdapter.getTryCount() < 3) {
+			jgMessageHelper.sendAsync(messageAdapter);
+		}
+	}
+
+
+}

+ 5 - 0
src/main/java/com/goafanti/message/queue/RedisQueueListener.java

@@ -0,0 +1,5 @@
+package com.goafanti.message.queue;
+
+public interface RedisQueueListener <T>{
+	public void onMessage(T value);
+}

+ 5 - 1
src/main/resources/props/config_local.properties

@@ -71,4 +71,8 @@ patentTemplate=SMS_72005286
 
 easemob.client.url=https://a1.easemob.com/1117170814115609/jitao
 easemob.client.id=YXA6RUDGkIDSEeemq9_4PWzcNA
-easemob.client.secret=YXA61NHE0renI5N8gEgizoI5ivM9SYE
+easemob.client.secret=YXA61NHE0renI5N8gEgizoI5ivM9SYE
+
+jiguang.appKey=36944c5628d34ff997f56dcd
+jiguang.masterSecret=cceff6a22d91c06786bfdcd3
+jiguang.pushUrl=https://api.jpush.cn/v3/push

+ 19 - 15
src/main/resources/spring/spring-shiro.xml

@@ -29,23 +29,10 @@
 	<bean id="redisTemplate" class="com.goafanti.core.cache.template.FastJsonRedisTemplate">
 		<constructor-arg index="0" ref="redisConnectionFactory" />
 	</bean>
-	
-    <bean id="jedisQueueListener" class="com.goafanti.easemob.queue.EasemobRedisQueueListener"/>  
-    
-    
-    <bean id="jedisQueue" class="com.goafanti.easemob.queue.EasemobRedisQueue" destroy-method="destroy">  
-        <property name="redisTemplate" ref="redisTemplate"></property>  
-        <property name="key" value="easemob:queue"></property>  
-        <property name="listener" ref="jedisQueueListener"></property>  
-    </bean> 
-    
-    <bean id="easemobUtils" class="com.goafanti.easemob.EasemobUtils"/>
-      
-
 	<bean id="sessionRedisTemplate" class="com.goafanti.core.shiro.cache.template.SessionRedisTemplate">
 		<constructor-arg index="0" ref="redisConnectionFactory" />
 	</bean>
-
+	
 	<bean id="cacheManager" class="org.springframework.data.redis.cache.RedisCacheManager">
 		<constructor-arg index="0" ref="redisTemplate" />
 		<property name="defaultExpiration" value="86400" />		
@@ -55,11 +42,28 @@
 		<property name="redisTemplate" ref="sessionRedisTemplate" />
 		<property name="expire" value="2592000" />
 	</bean>
+	
+	<!-- 环信 -->
+    <bean id="jedisQueueListener" class="com.goafanti.easemob.queue.EasemobRedisQueueListener"/>  
+    <bean id="jedisQueue" class="com.goafanti.easemob.queue.EasemobRedisQueue" destroy-method="destroy">  
+        <property name="redisTemplate" ref="redisTemplate"></property>  
+        <property name="key" value="easemob:queue"></property>  
+        <property name="listener" ref="jedisQueueListener"></property>  
+    </bean> 
+    <bean id="easemobUtils" class="com.goafanti.easemob.EasemobUtils"/>
+      
+	<!-- 极光 -->
+    <bean id="messageQueueListener" class="com.goafanti.message.queue.MessageRedisQueueListener"/>  
+    <bean id="messageQueue" class="com.goafanti.message.queue.MessageRedisQueue" destroy-method="destroy">  
+        <property name="redisTemplate" ref="redisTemplate"></property>  
+        <property name="key" value="jgpush:queue"></property>  
+        <property name="listener" ref="messageQueueListener"></property>  
+    </bean> 
+    <bean id="jgMessageHelper" class="com.goafanti.message.JGMessageHelper"/>
 
 	<bean id="sessionIdGenerator"
 		class="org.apache.shiro.session.mgt.eis.JavaUuidSessionIdGenerator" />
 
-
 	<bean id="sessionIdCookie" class="org.apache.shiro.web.servlet.SimpleCookie">
 		<constructor-arg value="AFT_SID" />
 		<property name="httpOnly" value="true" />