albertshaw лет назад: 8
Родитель
Сommit
8a69f2ce37

+ 4 - 0
src/main/java/com/goafanti/common/enums/UserType.java

@@ -21,6 +21,10 @@ public enum UserType {
 		}
 	}
 
+	public static boolean isPersonal(Integer code) {
+		return PERSONAL == getStatus(code);
+	}
+
 	public static UserType getStatus(Integer code) {
 		if (containsType(code)) {
 			return status.get(code);

+ 1 - 0
src/main/java/com/goafanti/core/cache/serializer/FastJsonRedisSerializer.java

@@ -23,6 +23,7 @@ public class FastJsonRedisSerializer implements RedisSerializer<Object> {
 		pc.addAccept("com.goafanti.news.bo.NewsPortalList");
 		pc.addAccept("com.goafanti.common.model.Activity");
 		pc.addAccept("com.goafanti.portal.bo.InternationalListBo");
+		pc.addAccept("com.goafanti.easemob.bo.EasemobInfo");
 	}
 
 	@Override

+ 182 - 0
src/main/java/com/goafanti/easemob/EasemobUtils.java

@@ -0,0 +1,182 @@
+package com.goafanti.easemob;
+
+import java.io.IOException;
+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.HttpGet;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.client.methods.HttpUriRequest;
+import org.apache.http.client.methods.HttpRequestBase;
+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 org.springframework.http.HttpMethod;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.goafanti.easemob.bo.EasemobInfo;
+import com.goafanti.easemob.queue.EasemobRedisQueue;
+
+public class EasemobUtils implements InitializingBean, DisposableBean {
+	private static final String				UTF_8	= "UTF-8";
+	private static final Logger				logger	= LoggerFactory.getLogger(EasemobUtils.class);
+	private static final Optional<Integer>	UN_AUTH	= Optional.of(401);
+
+	@Value(value = "${easemob.client.url}")
+	private String							clientUrl;
+	@Value(value = "${easemob.client.id}")
+	private String							clientId;
+	@Value(value = "${easemob.client.secret}")
+	private String							clientSecret;
+
+	private String							token;
+
+	@Autowired
+	private EasemobRedisQueue				jedisQueue;
+
+	private void auth() {
+		JSONObject jo = new JSONObject();
+		jo.put("grant_type", "client_credentials");
+		jo.put("client_id", clientId);
+		jo.put("client_secret", clientSecret);
+		JSONObject res = send(
+				new EasemobInfo().uri("/token").data(jo.toJSONString()).method(HttpMethod.POST).withAuth(false));
+		if (res != null) {
+			token = res.getString("access_token");
+		}
+	}
+
+	private HttpUriRequest buildRequest(EasemobInfo info) {
+		HttpUriRequest req = null;
+		switch (info.getMethod()) {
+		case POST:
+			req = new HttpPost(clientUrl + info.getUri());
+			((HttpPost) req).setEntity(new StringEntity(info.getData(), UTF_8));
+			break;
+		default:
+			req = new HttpGet(clientUrl + info.getUri());
+			break;
+		}
+		if (info.isWithAuth()) {
+			req.addHeader("Authorization", "Bearer " + token);
+		}
+		((HttpRequestBase) req).setConfig(RequestConfig.custom().setConnectTimeout(10000)
+				.setConnectionRequestTimeout(10000).setSocketTimeout(10000).build());
+		req.addHeader("Content-Type", "application/json");
+		return req;
+	}
+
+	public JSONObject send(EasemobInfo info) {
+		HttpUriRequest req = buildRequest(info);
+		CloseableHttpAsyncClient httpclient = HttpAsyncClients.createDefault();
+		httpclient.start();
+		logger.debug(req.toString());
+		Future<HttpResponse> future = httpclient.execute(req, null);
+		try {
+			HttpResponse response = future.get();
+			if (info.isWithAuth() && isUnauth(response)) {
+				auth();
+			} else {
+				HttpEntity entity = response.getEntity();
+				if (entity != null) {
+					try {
+						String resStr = EntityUtils.toString(entity, UTF_8);
+						logger.debug(resStr);
+						return (JSONObject) JSON.parse(resStr);
+					} catch (Exception e) {
+						logger.error(e.getMessage(), e);
+					}
+				}
+			}
+		} catch (InterruptedException | ExecutionException e) {
+			logger.error(e.getMessage(), e);
+		} finally {
+			try {
+				httpclient.close();
+			} catch (IOException e) {
+			}
+		}
+		return info.getTryCount() > 1 ? null : send(info.tryCount(info.getTryCount() + 1));
+	}
+
+	public void sendLater(EasemobInfo info) {
+		jedisQueue.pushFromTail(info);
+	}
+
+	public void sendAsync(EasemobInfo info) {
+		HttpUriRequest req = buildRequest(info);
+		CloseableHttpAsyncClient httpclient = HttpAsyncClients.createDefault();
+		httpclient.start();
+		logger.debug(req.toString());
+		httpclient.execute(req, new FutureCallback<HttpResponse>() {
+			@Override
+			public void failed(Exception ex) {
+				sendLater(info.tryCount(info.getTryCount() + 1));
+				close();
+			}
+
+			@Override
+			public void completed(HttpResponse result) {
+				if (info.isWithAuth() && isUnauth(result)) {
+					auth();
+				} else {
+					HttpEntity entity = result.getEntity();
+					if (entity != null) {
+						try {
+							logger.debug(EntityUtils.toString(entity, UTF_8));
+						} catch (Exception e) {
+							logger.error(e.getMessage(), e);
+						}
+					}
+				}
+				try {
+					httpclient.close();
+				} catch (IOException e) {
+				}
+				close();
+			}
+
+			@Override
+			public void cancelled() {
+				close();
+				logger.debug(req.toString() + "cancelled!");
+			}
+
+			private void close() {
+				try {
+					httpclient.close();
+				} catch (IOException e) {
+				}
+			}
+		});
+	}
+
+	private boolean isUnauth(HttpResponse response) {
+		return UN_AUTH
+				.equals(Optional.ofNullable(response).map(res -> res.getStatusLine()).map(sl -> sl.getStatusCode()));
+	}
+
+	@Override
+	public void destroy() throws Exception {
+		logger.debug("消息系统关闭");
+	}
+
+	@Override
+	public void afterPropertiesSet() throws Exception {
+		auth();
+	}
+
+}

+ 81 - 0
src/main/java/com/goafanti/easemob/bo/EasemobInfo.java

@@ -0,0 +1,81 @@
+package com.goafanti.easemob.bo;
+
+import org.springframework.http.HttpMethod;
+
+public class EasemobInfo {
+	private String		uri;
+
+	private String		data;
+
+	private HttpMethod	method;
+
+	private int			tryCount	= 0;
+
+	private boolean		withAuth	= true;
+
+	public String getUri() {
+		return uri;
+	}
+
+	public void setUri(String uri) {
+		this.uri = uri;
+	}
+
+	public String getData() {
+		return data;
+	}
+
+	public void setData(String data) {
+		this.data = data;
+	}
+
+	public int getTryCount() {
+		return tryCount;
+	}
+
+	public void setTryCount(int tryCount) {
+		this.tryCount = tryCount;
+	}
+
+	public HttpMethod getMethod() {
+		return method;
+	}
+
+	public void setMethod(HttpMethod method) {
+		this.method = method;
+	}
+
+	public boolean isWithAuth() {
+		return withAuth;
+	}
+
+	public void setWithAuth(boolean withAuth) {
+		this.withAuth = withAuth;
+	}
+
+	public EasemobInfo uri(String uri) {
+		this.uri = uri;
+		return this;
+	}
+
+	public EasemobInfo method(HttpMethod method) {
+		this.method = method;
+		return this;
+	}
+
+	public EasemobInfo tryCount(int tryCount) {
+		this.tryCount = tryCount;
+		return this;
+	}
+
+	public EasemobInfo data(String data) {
+		this.data = data;
+		return this;
+	}
+
+	public EasemobInfo withAuth(boolean withAuth) {
+		this.withAuth = withAuth;
+		return this;
+	}
+
+}

+ 151 - 0
src/main/java/com/goafanti/easemob/queue/EasemobRedisQueue.java

@@ -0,0 +1,151 @@
+package com.goafanti.easemob.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.easemob.bo.EasemobInfo;
+
+public class EasemobRedisQueue 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<EasemobInfo>	listener;
+	private Thread								listenerThread;
+
+	private boolean								isClosed;
+
+	public void setRedisTemplate(RedisTemplate<String, Object> redisTemplate) {
+		this.redisTemplate = redisTemplate;
+	}
+
+	public void setListener(RedisQueueListener<EasemobInfo> 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((EasemobInfo) value);
+						} catch (Exception e) {
+						}
+					}
+				}
+			} catch (InterruptedException e) {
+			}
+		}
+	}
+
+}

+ 19 - 0
src/main/java/com/goafanti/easemob/queue/EasemobRedisQueueListener.java

@@ -0,0 +1,19 @@
+package com.goafanti.easemob.queue;
+
+import org.springframework.beans.factory.annotation.Autowired;
+
+import com.goafanti.easemob.EasemobUtils;
+import com.goafanti.easemob.bo.EasemobInfo;
+
+public class EasemobRedisQueueListener implements RedisQueueListener<EasemobInfo> {
+	@Autowired
+	EasemobUtils easemobUtils;
+
+	@Override
+	public void onMessage(EasemobInfo value) {
+		if (value.getTryCount() < 3) {
+			easemobUtils.sendAsync(value);
+		}
+	}
+
+}

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

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

+ 32 - 3
src/main/java/com/goafanti/user/controller/UserApiController.java

@@ -10,7 +10,10 @@ import javax.servlet.http.HttpServletRequest;
 import javax.validation.Valid;
 
 import org.apache.commons.lang3.StringUtils;
+import org.apache.shiro.crypto.hash.SimpleHash;
 import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpMethod;
 import org.springframework.validation.BindingResult;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestMethod;
@@ -18,6 +21,7 @@ import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.ResponseBody;
 import org.springframework.web.bind.annotation.RestController;
 
+import com.alibaba.fastjson.JSONObject;
 import com.goafanti.cognizance.bo.InputOrgHumanResource;
 import com.goafanti.cognizance.service.OrgRatepayService;
 import com.goafanti.common.bo.Result;
@@ -53,6 +57,8 @@ import com.goafanti.common.utils.PasswordUtil;
 import com.goafanti.common.utils.TimeUtils;
 import com.goafanti.common.utils.VerifyCodeUtils;
 import com.goafanti.core.shiro.token.TokenManager;
+import com.goafanti.easemob.EasemobUtils;
+import com.goafanti.easemob.bo.EasemobInfo;
 import com.goafanti.techproject.service.TechWebsiteService;
 import com.goafanti.user.bo.InputOrgPro;
 import com.goafanti.user.bo.InputOrganizationTech;
@@ -109,6 +115,9 @@ public class UserApiController extends BaseApiController {
 	@Resource
 	private OrgRatepayService				orgRatepayService;
 
+	@Autowired
+	private EasemobUtils					easemobUtils;
+
 	private static final Integer			STEP_ONE			= 1;
 
 	// private static final Integer STEP_TWO = 2;
@@ -425,9 +434,8 @@ public class UserApiController extends BaseApiController {
 					OrgProFields.getFieldDesc(bindingResult.getFieldError().getField())));
 			return res;
 		}
-		
-		
-		if (StringUtils.isBlank(pro.getCompanyName())){
+
+		if (StringUtils.isBlank(pro.getCompanyName())) {
 			res.getError().add(buildError(ErrorConstants.PARAM_EMPTY_ERROR, "找不到单位名称", "单位名称"));
 			return res;
 		}
@@ -877,4 +885,25 @@ public class UserApiController extends BaseApiController {
 		return res;
 	}
 
+	/**
+	 * 获取环信登录账号,如果未注册则先注册
+	 */
+	@RequestMapping(value = "/easemob", method = RequestMethod.GET)
+	public Result getEasemob() {
+		User u = TokenManager.getUserToken();
+		if (u != null) {
+			JSONObject res = easemobUtils.send(new EasemobInfo().uri("/users/" + u.getNumber()).method(HttpMethod.GET));
+			JSONObject resultObj = new JSONObject();
+			resultObj.put("password", new SimpleHash("md5", u.getId(), null, 1).toHex());
+			resultObj.put("username", String.valueOf(u.getNumber()));
+			resultObj.put("nickname", StringUtils.isBlank(u.getNickname()) ? "技淘用户" + u.getNumber() : u.getNickname());
+			if (res == null || StringUtils.equals("service_resource_not_found", (CharSequence) res.get("error"))) {
+				easemobUtils.sendLater(
+						new EasemobInfo().uri("/users/").data(resultObj.toJSONString()).method(HttpMethod.POST));
+			}
+			return res().data(resultObj);
+		} else {
+			return res().error(buildError("user only", "必须是登录会员才能访问。"));
+		}
+	}
 }

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

@@ -71,4 +71,8 @@ portal.host=//afts.hnzhiming.com/portal/1.0.11
 
 patentTemplate=SMS_72005286
 
-avatar.upload.host=//afts.hnzhiming.com/upload
+avatar.upload.host=//afts.hnzhiming.com/upload
+
+easemob.client.url=https://a1.easemob.com/1117170814115609/jitao
+easemob.client.id=YXA6RUDGkIDSEeemq9_4PWzcNA
+easemob.client.secret=YXA61NHE0renI5N8gEgizoI5ivM9SYE

+ 29 - 25
src/main/resources/props/config_local.properties

@@ -1,41 +1,41 @@
 #Driver
 jdbc.driverClassName=com.mysql.jdbc.Driver
-#\u6570\u636e\u5e93\u94fe\u63a5\uff0c
-jdbc.url=jdbc:mysql://127.0.0.1:3306/aft?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=false
-#\u5e10\u53f7
+#\u6570\u636E\u5E93\u94FE\u63A5\uFF0C
+jdbc.url=jdbc:mysql://127.0.0.1:3306/aft_dev?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=false
+#\u5E10\u53F7
 jdbc.username=root
-#\u5bc6\u7801
+#\u5BC6\u7801
 jdbc.password=123456
-#\u68c0\u6d4b\u6570\u636e\u5e93\u94fe\u63a5\u662f\u5426\u6709\u6548\uff0c\u5fc5\u987b\u914d\u7f6e
+#\u68C0\u6D4B\u6570\u636E\u5E93\u94FE\u63A5\u662F\u5426\u6709\u6548\uFF0C\u5FC5\u987B\u914D\u7F6E
 jdbc.validationQuery=SELECT 'x'
-#\u521d\u59cb\u8fde\u63a5\u6570
+#\u521D\u59CB\u8FDE\u63A5\u6570
 jdbc.initialSize=3
-#\u6700\u5927\u8fde\u63a5\u6c60\u6570\u91cf
+#\u6700\u5927\u8FDE\u63A5\u6C60\u6570\u91CF
 jdbc.maxActive=20
-#\u53bb\u6389\uff0c\u914d\u7f6e\u6587\u4ef6\u5bf9\u5e94\u53bb\u6389
+#\u53BB\u6389\uFF0C\u914D\u7F6E\u6587\u4EF6\u5BF9\u5E94\u53BB\u6389
 #jdbc.maxIdle=20
-#\u914d\u7f6e0,\u5f53\u7ebf\u7a0b\u6c60\u6570\u91cf\u4e0d\u8db3\uff0c\u81ea\u52a8\u8865\u5145\u3002
+#\u914D\u7F6E0,\u5F53\u7EBF\u7A0B\u6C60\u6570\u91CF\u4E0D\u8DB3\uFF0C\u81EA\u52A8\u8865\u5145\u3002
 jdbc.minIdle=0
-#\u83b7\u53d6\u94fe\u63a5\u8d85\u65f6\u65f6\u95f4\u4e3a1\u5206\u949f\uff0c\u5355\u4f4d\u4e3a\u6beb\u79d2\u3002
+#\u83B7\u53D6\u94FE\u63A5\u8D85\u65F6\u65F6\u95F4\u4E3A1\u5206\u949F\uFF0C\u5355\u4F4D\u4E3A\u6BEB\u79D2\u3002
 jdbc.maxWait=120000
-#\u83b7\u53d6\u94fe\u63a5\u7684\u65f6\u5019\uff0c\u4e0d\u6821\u9a8c\u662f\u5426\u53ef\u7528\uff0c\u5f00\u542f\u4f1a\u6709\u635f\u6027\u80fd\u3002
+#\u83B7\u53D6\u94FE\u63A5\u7684\u65F6\u5019\uFF0C\u4E0D\u6821\u9A8C\u662F\u5426\u53EF\u7528\uFF0C\u5F00\u542F\u4F1A\u6709\u635F\u6027\u80FD\u3002
 jdbc.testOnBorrow=false
-#\u5f52\u8fd8\u94fe\u63a5\u5230\u8fde\u63a5\u6c60\u7684\u65f6\u5019\u6821\u9a8c\u94fe\u63a5\u662f\u5426\u53ef\u7528\u3002
+#\u5F52\u8FD8\u94FE\u63A5\u5230\u8FDE\u63A5\u6C60\u7684\u65F6\u5019\u6821\u9A8C\u94FE\u63A5\u662F\u5426\u53EF\u7528\u3002
 jdbc.testOnReturn=false
-#\u6b64\u9879\u914d\u7f6e\u4e3atrue\u5373\u53ef\uff0c\u4e0d\u5f71\u54cd\u6027\u80fd\uff0c\u5e76\u4e14\u4fdd\u8bc1\u5b89\u5168\u6027\u3002\u610f\u4e49\u4e3a\uff1a\u7533\u8bf7\u8fde\u63a5\u7684\u65f6\u5019\u68c0\u6d4b\uff0c\u5982\u679c\u7a7a\u95f2\u65f6\u95f4\u5927\u4e8etimeBetweenEvictionRunsMillis\uff0c\u6267\u884cvalidationQuery\u68c0\u6d4b\u8fde\u63a5\u662f\u5426\u6709\u6548\u3002
+#\u6B64\u9879\u914D\u7F6E\u4E3Atrue\u5373\u53EF\uFF0C\u4E0D\u5F71\u54CD\u6027\u80FD\uFF0C\u5E76\u4E14\u4FDD\u8BC1\u5B89\u5168\u6027\u3002\u610F\u4E49\u4E3A\uFF1A\u7533\u8BF7\u8FDE\u63A5\u7684\u65F6\u5019\u68C0\u6D4B\uFF0C\u5982\u679C\u7A7A\u95F2\u65F6\u95F4\u5927\u4E8EtimeBetweenEvictionRunsMillis\uFF0C\u6267\u884CvalidationQuery\u68C0\u6D4B\u8FDE\u63A5\u662F\u5426\u6709\u6548\u3002
 jdbc.testWhileIdle=true
-#1.Destroy\u7ebf\u7a0b\u4f1a\u68c0\u6d4b\u8fde\u63a5\u7684\u95f4\u9694\u65f6\u95f4
-#2.testWhileIdle\u7684\u5224\u65ad\u4f9d\u636e
+#1.Destroy\u7EBF\u7A0B\u4F1A\u68C0\u6D4B\u8FDE\u63A5\u7684\u95F4\u9694\u65F6\u95F4
+#2.testWhileIdle\u7684\u5224\u65AD\u4F9D\u636E
 jdbc.timeBetweenEvictionRunsMillis=60000
-#\u4e00\u4e2a\u94fe\u63a5\u751f\u5b58\u7684\u65f6\u95f4\uff08\u4e4b\u524d\u7684\u503c\uff1a25200000\uff0c\u8fd9\u4e2a\u65f6\u95f4\u6709\u70b9BT\uff0c\u8fd9\u4e2a\u7ed3\u679c\u4e0d\u77e5\u9053\u662f\u600e\u4e48\u6765\u7684\uff0c\u6362\u7b97\u540e\u7684\u7ed3\u679c\u662f\uff1a25200000/1000/60/60 = 7\u4e2a\u5c0f\u65f6\uff09
+#\u4E00\u4E2A\u94FE\u63A5\u751F\u5B58\u7684\u65F6\u95F4\uFF08\u4E4B\u524D\u7684\u503C\uFF1A25200000\uFF0C\u8FD9\u4E2A\u65F6\u95F4\u6709\u70B9BT\uFF0C\u8FD9\u4E2A\u7ED3\u679C\u4E0D\u77E5\u9053\u662F\u600E\u4E48\u6765\u7684\uFF0C\u6362\u7B97\u540E\u7684\u7ED3\u679C\u662F\uFF1A25200000/1000/60/60 = 7\u4E2A\u5C0F\u65F6\uFF09
 jdbc.minEvictableIdleTimeMillis=300000
-#\u94fe\u63a5\u4f7f\u7528\u8d85\u8fc7\u65f6\u95f4\u9650\u5236\u662f\u5426\u56de\u6536
+#\u94FE\u63A5\u4F7F\u7528\u8D85\u8FC7\u65F6\u95F4\u9650\u5236\u662F\u5426\u56DE\u6536
 jdbc.removeAbandoned=true
-#\u8d85\u8fc7\u65f6\u95f4\u9650\u5236\u65f6\u95f4\uff08\u5355\u4f4d\u79d2\uff09\uff0c\u76ee\u524d\u4e3a5\u5206\u949f\uff0c\u5982\u679c\u6709\u4e1a\u52a1\u5904\u7406\u65f6\u95f4\u8d85\u8fc75\u5206\u949f\uff0c\u53ef\u4ee5\u9002\u5f53\u8c03\u6574\u3002
+#\u8D85\u8FC7\u65F6\u95F4\u9650\u5236\u65F6\u95F4\uFF08\u5355\u4F4D\u79D2\uFF09\uFF0C\u76EE\u524D\u4E3A5\u5206\u949F\uFF0C\u5982\u679C\u6709\u4E1A\u52A1\u5904\u7406\u65F6\u95F4\u8D85\u8FC75\u5206\u949F\uFF0C\u53EF\u4EE5\u9002\u5F53\u8C03\u6574\u3002
 jdbc.removeAbandonedTimeout=300
-#\u94fe\u63a5\u56de\u6536\u7684\u65f6\u5019\u63a7\u5236\u53f0\u6253\u5370\u4fe1\u606f\uff0c\u6d4b\u8bd5\u73af\u5883\u53ef\u4ee5\u52a0\u4e0atrue\uff0c\u7ebf\u4e0a\u73af\u5883false\u3002\u4f1a\u5f71\u54cd\u6027\u80fd\u3002
+#\u94FE\u63A5\u56DE\u6536\u7684\u65F6\u5019\u63A7\u5236\u53F0\u6253\u5370\u4FE1\u606F\uFF0C\u6D4B\u8BD5\u73AF\u5883\u53EF\u4EE5\u52A0\u4E0Atrue\uFF0C\u7EBF\u4E0A\u73AF\u5883false\u3002\u4F1A\u5F71\u54CD\u6027\u80FD\u3002
 jdbc.logAbandoned=true
-#\u7edf\u8ba1\u76d1\u63a7
+#\u7EDF\u8BA1\u76D1\u63A7
 jdbc.filters=stat
 
 logging.level.com.goafanti=DEBUG
@@ -43,7 +43,7 @@ logging.level.com.goafanti=DEBUG
 jedis.host=127.0.0.1
 jedis.port=6379
 jedis.timeout=5000
-jedis.password=aft123456
+jedis.password=123456
 
 pwd.hash_algorithm_name=md5
 pwd.hash_iterations=2
@@ -53,7 +53,7 @@ session.validate.timespan=18000000
 
 app.name=AFT
 
-static.host=//sb.jishutao.com/1.0.40
+static.host=//afts.hnzhiming.com/1.0.41
 
 upload.path=/Users/xiaolong/Sites/upload
 upload.private.path=/Users/xiaolong/Sites/doc
@@ -61,7 +61,7 @@ upload.private.path=/Users/xiaolong/Sites/doc
 accessKey=LTAIqTgQLLwz252Z
 accessSecret=ICGuiUnqzaar7urw4zecVcJrJ1MHg9
 
-avatar.host=//sf.jishutao.com
+avatar.host=//afts.hnzhiming.com
 
 aesSecretKey=aft1234567890123
 
@@ -69,8 +69,12 @@ template.cacheable=false
 
 mobileCodeTemplate=SMS_37845022
 
-portal.host=//sf.jishutao.com/portal/1.0.9
+portal.host=//afts.hnzhiming.com/portal/1.0.11
 
 patentTemplate=SMS_72005286
 
-avatar.upload.host=//sf.jishutao.com/upload
+avatar.upload.host=//afts.hnzhiming.com/upload
+
+easemob.client.url=https://a1.easemob.com/1117170814115609/jitao
+easemob.client.id=YXA6RUDGkIDSEeemq9_4PWzcNA
+easemob.client.secret=YXA61NHE0renI5N8gEgizoI5ivM9SYE

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

@@ -73,4 +73,8 @@ portal.host=//aftts.hnzhiming.com/portal/1.0.8
 
 patentTemplate=SMS_72005286
 
-avatar.upload.host=//aftts.hnzhiming.com/upload
+avatar.upload.host=//aftts.hnzhiming.com/upload
+
+easemob.client.url=https://a1.easemob.com/1117170814115609/jitao
+easemob.client.id=YXA6RUDGkIDSEeemq9_4PWzcNA
+easemob.client.secret=YXA61NHE0renI5N8gEgizoI5ivM9SYE

+ 14 - 3
src/main/resources/spring/spring-shiro.xml

@@ -29,9 +29,20 @@
 	<bean id="redisTemplate" class="com.goafanti.core.cache.template.FastJsonRedisTemplate">
 		<constructor-arg index="0" ref="redisConnectionFactory" />
 	</bean>
-
-	<bean id="sessionRedisTemplate"
-		class="com.goafanti.core.shiro.cache.template.SessionRedisTemplate">
+	
+    <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>