package com.qxueyou.scc.msg.service.impl; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.TimeUnit; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.context.properties.DeprecatedConfigurationProperty; import org.springframework.stereotype.Service; import com.qxueyou.scc.base.model.Result; import com.qxueyou.scc.base.service.ICacheService; import com.qxueyou.scc.msg.model.MsgChatroomMsg; import com.qxueyou.scc.msg.service.IChatroomMsgService; @Service public class ChatroomMessageBean implements IChatroomMsgService { @Autowired ICacheService redis; private static final int PAGE_SIZE = 20; private static final String CACHEKEY_MSG_QUEUE = "msg_chatroom_msg_"; // ʵʱÏûÏ¢¶ÓÁÐ private static final String CACHEKEY_MESSAGE_A_COUNT = "msg_chatroom_message_count_"; // AÀàÏûÏ¢×ÜÊý private static final String CACHEKEY_MESSAGE_HISTORY = "msg_chatroom_msg_history_"; //ÀúÊ·ÏûÏ¢ private static final String CACHEKEY_ONLINE_COUNT = "msg_chatroom_online_count_"; // ÔÚÏßÈËÊý private static final String CACHEKEY_PRAISE_COUNT = "msg_chatroom_praise_count_"; // µãÔÞÊý private static final String CACHEKEY_LOTTERY_COUNT = "msg_chatroom_lottery_count_"; // Ç©µ½Êý private static final String CACHEKEY_VIEW_COUNT = "msg_chatroom_view_count_"; // ä¯ÀÀÊý private static final String CACHEKEY_LOTTERY_RESULT_COUNT = "msg_chatroom_lottery_result_count_"; //Öн±½á¹û private static final String CACHEKEY_REWARD_COUNT = "msg_chatroom_reward_count_"; //´òÉÍ´ÎÊý private static final String CACHEKEY_CONSULT_COUNT = "msg_chatroom_consult_count_"; //×Éѯ´ÎÊý private static final String CACHEKEY_REWARD_AMOUNT = "msg_chatroom_reward_amount_"; //´òÉͽð¶î /** * ·¢ËÍÏûÏ¢ */ @Override public Result doSendMessage(String chatroomId, String senderId, String imgPath, String alias, String content, Integer type, String userType) { MsgChatroomMsg mes = new MsgChatroomMsg(); mes.setMsgId(redis.incr("ChatroomMsgId")); mes.setChatroomId(chatroomId); mes.setSenderId(senderId); mes.setContent(content); mes.setType(type); mes.setAlias(alias); mes.setUserType(userType); mes.setImgPath(imgPath); mes.setCreateTime(new Date()); //»º´æÏûÏ¢ this.msgCache(chatroomId, mes); this.msgTypeCountCache(chatroomId, type); return new Result(true, null, mes); } /** * ÁÄÌìÏûÏ¢¼ôÇУ¬ * * @param chatroomId */ @Deprecated private void msgListTrim(String key, String chatroomId){ List mesList = redis.lstRange(key, 0l, -1l); if(mesList != null && !mesList.isEmpty()){ if(mesList.size() <= PAGE_SIZE){ return; } long index = 0; long time = System.currentTimeMillis(); for(MsgChatroomMsg msg : mesList){ if(time - msg.getCreateTime().getTime()<= 10000){ break; } index ++; } //±£Áô20Ìõ redis.lstTrim(key, mesList.size() - index <= 20?mesList.size()-20:index, -1l); } } /** * »º´æÏûÏ¢ * * @param chatroomId * @param mes */ private void msgCache(String chatroomId, MsgChatroomMsg mes){ String key = CACHEKEY_MSG_QUEUE + chatroomId; //ÏÈ»ñÈ¡10ÃëÄÚµÄÊý¾Ý // this.msgListTrim(key, chatroomId); // List mesList = redis.lstRange(key, 0l, -1l); //»ñÈ¡PAGE_SIZEÌõÒÔÄÚµÄÏûÏ¢ List mesList= redis.lstRange(key, 0l, PAGE_SIZE); //×î½ü20ÏûÏ¢¹ýÂËÖØ¸´µÄµãÔÞ£¬½øÈ룬Í˳ö if((MsgChatroomMsg.TYPE_PRAISE == mes.getType() || MsgChatroomMsg.TYPE_ENTER == mes.getType() || MsgChatroomMsg.TYPE_EXIT == mes.getType()) && mesList.contains(mes)){ return; } redis.lstRightPush(key, mes); redis.expire(key, 360, TimeUnit.DAYS); } /** * ¼ÆÊýÆ÷ * * @param chatroomId * @param type */ private void msgTypeCountCache(String chatroomId, Integer type){ if(type == MsgChatroomMsg.TYPE_ENTER){//ÔÚÏßÈËÊý¼ÓÒ» redis.incr(CACHEKEY_ONLINE_COUNT + chatroomId); redis.expire(CACHEKEY_ONLINE_COUNT + chatroomId, 360, TimeUnit.DAYS); } if(type == MsgChatroomMsg.TYPE_ENTER || type == MsgChatroomMsg.TYPE_PRAISE || type == MsgChatroomMsg.TYPE_LOTTERY || type == MsgChatroomMsg.TYPE_REWARD || type == MsgChatroomMsg.TYPE_CONSULT || type == MsgChatroomMsg.TYPE_LOTTERY_RESULT){ redis.incr(this.getKey(chatroomId, type)); redis.expire(this.getKey(chatroomId, type), 360, TimeUnit.DAYS); }else if(type == MsgChatroomMsg.TYPE_EXIT){//ÔÚÏßÈËÊý¼õÒ» String key = CACHEKEY_ONLINE_COUNT + chatroomId; Long value = redis.getIncrValue(key); if(value.compareTo(0l)>0){ redis.decr(key); } redis.expire(key, 360, TimeUnit.DAYS); }else if(type == MsgChatroomMsg.TYPE_NORMAL || type == MsgChatroomMsg.TYPE_LOTTERY_RESULT){//AÀàÏûÏ¢¼ÆÊýÆ÷ redis.incr(CACHEKEY_MESSAGE_A_COUNT + chatroomId); redis.expire(CACHEKEY_MESSAGE_A_COUNT + chatroomId, 360, TimeUnit.DAYS); } } //»ñÈ¡»º´ækeyÖµ private String getKey(String chatroomId, Integer type){ String key = ""; switch(type){ case MsgChatroomMsg.TYPE_PRAISE: key = CACHEKEY_PRAISE_COUNT + chatroomId; break; case MsgChatroomMsg.TYPE_LOTTERY: key = CACHEKEY_LOTTERY_COUNT + chatroomId; break; case MsgChatroomMsg.TYPE_ENTER: key = CACHEKEY_VIEW_COUNT + chatroomId; break; case MsgChatroomMsg.TYPE_REWARD: key = CACHEKEY_REWARD_COUNT + chatroomId; break; case MsgChatroomMsg.TYPE_CONSULT: key = CACHEKEY_CONSULT_COUNT + chatroomId; break; case MsgChatroomMsg.TYPE_LOTTERY_RESULT: key = CACHEKEY_LOTTERY_RESULT_COUNT + chatroomId; break; default: key = ""; } return key; } /** * ÂÖѯ * * @param chatroomId * @throws Exception */ @Override public Result latestMsg(String chatroomId) { List mesList = redis.lstRange(CACHEKEY_MSG_QUEUE + chatroomId, 0l, -1l); //½±½ð×ÜÊý Long rewardAmount = redis.getIncrValue(CACHEKEY_REWARD_AMOUNT + chatroomId); Map data = new HashMap(); //ͳ¼ÆÊý¾Ý Map statistics = this.reStatistics(chatroomId); Integer maxPage = this.getMaxPage(chatroomId, String.valueOf(statistics.get("historyMsgCount"))); data.put("maxPage", maxPage); data.put("currentPage", maxPage); data.put("onlineCount", statistics.get("onlineCount")); data.put("praiseCount", statistics.get("praiseCount")); data.put("viewCount", statistics.get("viewCount")); data.put("lotteryCount", statistics.get("lotteryCount")); data.put("rewardCount", statistics.get("rewardCount")); data.put("consultCount", statistics.get("consultCount")); data.put("rewardAmount", rewardAmount); data.put("dataList", mesList); data.put("serverTime", new Date()); return new Result(true, null, data); } /** * »ñÈ¡ä¯ÀÀÈË´Î * @param chatroomId * @throws Exception */ @Override public Long getViewCount(String chatroomId){ return redis.getIncrValue(CACHEKEY_VIEW_COUNT + chatroomId); } /** * ÖØÐÂͳ¼ÆÊý¾Ý£¬¶ÁÈ¡Êý¾Ý¿â * * @param type * @param statistics * @return */ private Map reStatistics(String chatroomId){ Long msgCount = nul2Zero(redis.getIncrValue(CACHEKEY_MESSAGE_A_COUNT + chatroomId)); Long onlineCount = nul2Zero(redis.getIncrValue(CACHEKEY_ONLINE_COUNT + chatroomId)); Long praiseCount = nul2Zero(redis.getIncrValue(CACHEKEY_PRAISE_COUNT + chatroomId)); Long lotteryCount = nul2Zero(redis.getIncrValue(CACHEKEY_LOTTERY_COUNT + chatroomId)); Long viewCount = nul2Zero(redis.getIncrValue(CACHEKEY_VIEW_COUNT + chatroomId)); Long rewardCount = nul2Zero(redis.getIncrValue(CACHEKEY_REWARD_COUNT + chatroomId)); Long lotteryResultCount = nul2Zero(redis.getIncrValue(CACHEKEY_LOTTERY_RESULT_COUNT + chatroomId)); Long consultCount = nul2Zero(redis.getIncrValue(CACHEKEY_CONSULT_COUNT + chatroomId)); Map result = new HashMap<>(); result.put("msgCount", msgCount); //ÀúÊ·ÏûÏ¢ÊýÁ¿£¬Õý³£ÏûÏ¢¡¢Öн±ÏûÏ¢£¬´òÉÍÏûÏ¢ result.put("historyMsgCount", msgCount+lotteryResultCount+rewardCount); result.put("onlineCount", onlineCount); result.put("praiseCount", praiseCount); result.put("lotteryCount", lotteryCount); result.put("viewCount", viewCount); result.put("rewardCount", rewardCount); result.put("consultCount", consultCount); return result; } private Long nul2Zero(Long value) { if(value==null) { return 0l; } return value; } /** * °´Ò³»ñÈ¡ÀúÊ·ÏûÏ¢ */ @Override public Result getHistoryMes(String chatroomId, Integer pageNo) { //ͳ¼ÆÊý¾Ý List mesList = redis.lstRange(CACHEKEY_MSG_QUEUE + chatroomId, 0l, -1l); Map statistics = this.reStatistics(chatroomId); Integer maxPage = getMaxPage(chatroomId, String.valueOf(statistics.get("historyMsgCount")+mesList.size())); String key = CACHEKEY_MESSAGE_HISTORY + chatroomId+ "_" + pageNo; if (StringUtils.isEmpty(chatroomId) || pageNo == null || pageNo > maxPage) { return new Result(false, "²ÎÊý´íÎó"); } List msgList = redis.lstAll(key); msgList = this.distinct(msgList, chatroomId); Map data = new HashMap<>(); data.put("currentPage", pageNo); data.put("maxPage", maxPage); data.put("dataList", msgList); return new Result(true, null, data); } /** * È¥³ýÖØ¸´ÏûÏ¢ * * @return */ private List distinct(List historyMsgList, String chatroomId){ List lastMsgList = redis.lstRange(CACHEKEY_MSG_QUEUE + chatroomId, 0l, -1l); if(historyMsgList != null && !historyMsgList.isEmpty() && lastMsgList != null && !lastMsgList.isEmpty()){ for(int i=historyMsgList.size()-1;i>= 0;i--){ MsgChatroomMsg historyMsgChatroomMsg = historyMsgList.get(i); for(MsgChatroomMsg lastMsgChatroomMsg : lastMsgList){ if(historyMsgChatroomMsg.getMsgId().equals(lastMsgChatroomMsg.getMsgId())){ historyMsgList.remove(i); break; } } } } return historyMsgList; } /** * »ñÈ¡AÀàÏûÏ¢×î´óÒ³Âë * * @param chatroomId * @return */ public Integer getMaxPage(String chatroomId, String msgCount) { Integer count = Integer.valueOf(msgCount); int maxPage = count % PAGE_SIZE == 0 ? count / PAGE_SIZE : count / PAGE_SIZE + 1; return maxPage; } }