package com.yami.trading.service.chat.otc; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.yami.trading.bean.c2c.C2cOrder; import com.yami.trading.bean.chat.domain.OtcMessageUser; import com.yami.trading.bean.chat.domain.OtcOnlineChatMessage; import com.yami.trading.bean.model.User; import com.yami.trading.bean.model.UserRecom; import com.yami.trading.common.constants.TipConstants; import com.yami.trading.common.exception.BusinessException; import com.yami.trading.common.util.DateUtils; import com.yami.trading.common.util.StringUtils; import com.yami.trading.common.util.UnicodeUtils; import com.yami.trading.service.c2c.C2cOrderService; import com.yami.trading.service.system.TipService; import com.yami.trading.service.user.UserRecomService; import com.yami.trading.service.user.UserService; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections.CollectionUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.event.ContextRefreshedEvent; import org.springframework.context.event.EventListener; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Service; import java.net.URLDecoder; import java.util.ArrayList; import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; @Slf4j @Service public class OtcOnlineChatMessageServiceImpl implements OtcOnlineChatMessageService { private Logger logger = LoggerFactory.getLogger(OtcOnlineChatMessageServiceImpl.class); @Autowired private OtcDbOnlinechatMessageService dbOnlinechatMessageService; @Autowired private UserService partyService; @Autowired private UserRecomService userRecomService; @Autowired private TipService tipService; @Autowired private C2cOrderService c2cOrderService; @Autowired private OtcMessageUserService otcMessageUserService; @Autowired private JdbcTemplate jdbcTemplate; private Map> cahce_chat = new ConcurrentHashMap>(); private Map cahce_user = new ConcurrentHashMap(); public List cacheGetList(String messageId, int pageSize, String orderNo) { List cache = cahce_chat.get(orderNo); if (cache == null) { return new LinkedList(); } List result = new ArrayList(cache); int start = cacheIndex(messageId, result); // start = start == 0 ? start : start + 1;// 空消息则表示首页,消息索引的后一条为起始 int end = start + pageSize; if (start >= result.size()) {// 起始数据大于总量,返回空 return new LinkedList(); } if (result.size() <= end) { end = cache.size(); } result = result.subList(start, end); if (CollectionUtils.isEmpty(result)) { return result; } result.forEach(msg -> { String content = msg.getContent(); content = UnicodeUtils.decodeUnicode(content); msg.setContent(content); }); return result; } public List cacheGetList(String messageId, int pageSize, String orderNo, String clicentType) { List cache = cahce_chat.get(orderNo); if (cache == null) { return new LinkedList(); } List result = new ArrayList<>(cache); if ("user".equals(clicentType)) { // 过滤掉已撤回的消息 result = cache.stream().filter(chat -> chat.getDeleteStatus() == null || chat.getDeleteStatus() == 0).collect(Collectors.toList()); } int start = cacheIndex(messageId, result); int end = start + pageSize; if (start >= result.size()) {// 起始数据大于总量,返回空 return new LinkedList(); } if (result.size() <= end) { end = result.size(); } result = result.subList(start, end); if (CollectionUtils.isEmpty(result)) { return result; } result.forEach(msg -> { String content = msg.getContent(); content = UnicodeUtils.decodeUnicode(content); msg.setContent(content); }); return result; } /** * 获取消息的索引 * * @param messageId * @param list * @return */ private int cacheIndex(String messageId, List list) { if (StringUtils.isEmptyString(messageId)) return 0; int index = -1; for (int i = 0; i < list.size(); i++) { OtcOnlineChatMessage message = list.get(i); if (messageId.equals(message.getUuid().toString())) { index = i; } } if (index == -1) { throw new BusinessException("参数异常,消息获取失败"); } return index + 1; } @Override public List cacheGetMessageUserPage(int pageNo, int pageSize) { List list = new ArrayList(cahce_user.values()); List result = new ArrayList(); for (OtcMessageUser user : list) { if (user.getDeleteStatus() == -1) continue; result.add(user); } Collections.sort(result); return result; } @Override public void saveSend(String partyId, String type, String content, String username, String orderNo) { OtcOnlineChatMessage onlineChatMessage = new OtcOnlineChatMessage(); onlineChatMessage.setPartyId(partyId); onlineChatMessage.setContentType(type); onlineChatMessage.setSendReceive(""); content = UnicodeUtils.gbEncoding(content); onlineChatMessage.setContent(content); onlineChatMessage.setCreateTime(new Date()); // 后台管理员账户,记录谁回复的消息 onlineChatMessage.setUsername(username); onlineChatMessage.setOrderNo(orderNo); dbOnlinechatMessageService.save(onlineChatMessage); List list = cahce_chat.get(orderNo); if (list == null) { list = new LinkedList(); } list.add(onlineChatMessage); Collections.sort(list); Collections.reverse(list);// 添加完后,时间倒叙排序加回 this.cahce_chat.put(orderNo, list); if (!cahce_user.containsKey(orderNo)) {// 不存在则添加用户 saveCreateByOrderNo(orderNo); } // 用户发送 if (null == username) { updateUnread(partyId, "write", orderNo); if (StringUtils.isNotEmpty(orderNo)) { C2cOrder c2cOrder = c2cOrderService.findOrderNo(orderNo); if (c2cOrder != null) { String diretion = c2cOrder.getDirection(); if (diretion.equals("recharge") || diretion.equals("withdraw")) { tipService.saveTip(onlineChatMessage.getUuid().toString(), TipConstants.BANK_CARD_ORDER_ONLINECHAT); } else { tipService.saveTip(onlineChatMessage.getUuid().toString(), TipConstants.OTCORDER_ONLINECHAT, onlineChatMessage.getPartyId()); } } else { tipService.saveTip(onlineChatMessage.getUuid().toString(), TipConstants.OTCORDER_ONLINECHAT, onlineChatMessage.getPartyId()); } } else { tipService.saveTip(onlineChatMessage.getUuid().toString(), TipConstants.OTCORDER_ONLINECHAT, onlineChatMessage.getPartyId()); } } // 后台客服 else { updateUnreadAdmin(partyId, "write", orderNo); } } /** * 更新未读数 * * @param type read:读,write:写 */ public void updateUnread(String partyId, String type, String orderNo) { OtcMessageUser messageUser = cahce_user.get(orderNo); if (messageUser == null) { saveCreateByOrderNo(orderNo); messageUser = cahce_user.get(orderNo); } C2cOrder c2cOrder = c2cOrderService.get(orderNo); // 承兑商ID String c2cUserId = c2cOrder.getC2cUserPartyId(); // 下单用户ID String orderUserId = c2cOrder.getPartyId(); // 用户承兑商 if (partyId.equals(c2cUserId)) { if ("read".equals(type)) { messageUser.setCustomerUnreadmsg(0); } else if ("write".equals(type)) { messageUser.setUserUnreadmsg(messageUser.getCustomerUnreadmsg() + 1); messageUser.setDeleteStatus(0); } } // 下单用户 else if (partyId.equals(orderUserId)) { if ("read".equals(type)) { messageUser.setUserUnreadmsg(0); } else if ("write".equals(type)) { messageUser.setCustomerUnreadmsg(messageUser.getCustomerUnreadmsg() + 1); messageUser.setDeleteStatus(0); } } updateMessageUser(messageUser); } /** * 更新未读数 * * @param type read:读,write:写 */ public void updateUnreadAdmin(String partyId, String type, String orderNo) { OtcMessageUser messageUser = cahce_user.get(orderNo); if (messageUser == null) { saveCreateByOrderNo(orderNo); messageUser = cahce_user.get(orderNo); } C2cOrder c2cOrder = c2cOrderService.get(orderNo); // 承兑商ID String c2cUserId = c2cOrder.getC2cUserPartyId(); // 下单用户ID String orderUserId = c2cOrder.getPartyId(); // 后台承兑商 发送 if (partyId.equals(c2cUserId)) { if ("read".equals(type)) { int removeTipNum = 0; messageUser.setCustomerUnreadmsg(0); if (removeTipNum > 0) { removeTips(messageUser.getOrderNo(), removeTipNum); } } else if ("write".equals(type)) { messageUser.setUserUnreadmsg(messageUser.getUserUnreadmsg() + 1); messageUser.setDeleteStatus(0); } } // 下单用户发送 else if (partyId.equals(orderUserId)) { if ("read".equals(type)) { messageUser.setUserUnreadmsg(0); } else if ("write".equals(type)) { messageUser.setUserUnreadmsg(messageUser.getUserUnreadmsg() + 1); messageUser.setDeleteStatus(0); } } updateMessageUser(messageUser); } /** * 移除通知 * * @param orderNo * @param removeTipNum */ public void removeTips(String orderNo, int removeTipNum) { List list = this.cacheGetList(null, removeTipNum, orderNo); List ids = new ArrayList(); for (OtcOnlineChatMessage m : list) { ids.add(m.getUuid().toString()); } tipService.deleteTip(ids); } public void updateMessageUser(OtcMessageUser messageUser) { otcMessageUserService.updateById(messageUser); cahce_user.put(messageUser.getOrderNo(), messageUser); } public OtcMessageUser saveCreateByOrderNo(String orderNo) { OtcMessageUser messageUser = cahce_user.get(orderNo); if (messageUser == null) { messageUser = new OtcMessageUser(); messageUser.setOrderNo(orderNo); } messageUser.setUpdatetime(new Date()); otcMessageUserService.saveOrUpdate(messageUser); cahce_user.put(orderNo, messageUser); return messageUser; } @Override public void delete(String orderNo) { OtcMessageUser messageUser = cahce_user.get(orderNo); if (messageUser != null) { messageUser.setCustomerUnreadmsg(0); messageUser.setDeleteStatus(-1); this.updateMessageUser(messageUser); } } /** * 批量获取未读数 * * @param orderNos * @return */ public Map unreadMsgs(List orderNos) { return org.springframework.util.CollectionUtils.isEmpty(orderNos) ? Collections.EMPTY_MAP : orderNos.stream() .collect(Collectors.toMap(orderNo -> orderNo, orderNo -> unreadMsgAdmin(orderNo), (oldValue, newValue) -> newValue)); } /** * 管理后台获取未读消息 */ public int unreadMsgAdmin(String orderNo) { int unreadmsg = 0; if (!StringUtils.isNullOrEmpty(orderNo)) { OtcMessageUser messageUser = cahce_user.get(orderNo); if (messageUser != null) { unreadmsg = messageUser.getCustomerUnreadmsg(); } } else { Iterator> it = cahce_user.entrySet().iterator(); while (it.hasNext()) { Map.Entry entry = it.next(); unreadmsg += entry.getValue().getCustomerUnreadmsg(); } } return unreadmsg; } public Map unreadMsgsApi(List orderNos) { Map result = new HashMap(); for (String orderNo : orderNos) { result.put(orderNo, unreadMsgApi(orderNo)); } return result; } public int unreadMsgApi(String orderNo) { int unreadmsg = 0; if (!StringUtils.isNullOrEmpty(orderNo)) { OtcMessageUser messageUser = cahce_user.get(orderNo); if (messageUser != null) { unreadmsg = messageUser.getUserUnreadmsg(); } } else { Iterator> it = cahce_user.entrySet().iterator(); while (it.hasNext()) { Map.Entry entry = it.next(); unreadmsg += entry.getValue().getUserUnreadmsg(); } } return unreadmsg; } @Override public int unreadMsg(String orderNo, String partyId) { C2cOrder c2cOrder = c2cOrderService.get(orderNo); // 承兑商ID String c2cUserId = c2cOrder.getC2cUserPartyId(); // 下单用户ID String orderUserId = c2cOrder.getPartyId(); int unreadmsg = 0; OtcMessageUser messageUser = cahce_user.get(orderNo); if (messageUser != null) { // 承兑商 if (partyId.equals(c2cUserId)) { unreadmsg = messageUser.getCustomerUnreadmsg(); } // 下单用户 else if (partyId.equals(orderUserId)) { unreadmsg = messageUser.getUserUnreadmsg(); } } return unreadmsg; } /** * 设置备注 * * @param orderNo * @param remarks */ public String resetRemarks(String orderNo, String remarks) throws Exception { if (StringUtils.isEmptyString(remarks) || StringUtils.isEmptyString(remarks.trim())) { return null; } OtcMessageUser messageUser = this.cacheMessageUser(orderNo); if (messageUser == null) { throw new BusinessException("用户不存在"); } messageUser.setRemarks(URLDecoder.decode(remarks, "utf-8")); this.updateMessageUser(messageUser); return remarks; } /** * 获取用户信息 * * @param partyId * @return */ public Map saveGetUserInfo(String orderNo, String partyId) { OtcMessageUser messageUser = this.cacheMessageUser(orderNo); User party = partyService.getById(partyId); if (party == null) { throw new BusinessException("用户不存在"); } if (messageUser == null) { messageUser = this.saveCreateByOrderNo(orderNo); } Map result = new HashMap(); result.put("remarks", messageUser.getRemarks()); result.put("username", party.getUserName()); result.put("usercode", party.getUserCode()); result.put("last_login_time", DateUtils.format(party.getUserLasttime(), DateUtils.DF_yyyyMMddHHmmss)); result.put("create_time", DateUtils.format(party.getCreateTime(), DateUtils.DF_yyyyMMddHHmmss)); result.put("role_name", party.getRoleName()); result.put("login_ip", party.getUserLastip()); List parents = userRecomService.getParents(party.getUserId()); if (!CollectionUtils.isEmpty(parents) && parents.size() >= 2) { User parentParty = partyService.getById(parents.get(1).getUserId()); result.put("recom_parent_name", parentParty == null ? null : parentParty.getUserName()); } else { result.put("recom_parent_name", null); } return result; } public OtcOnlineChatMessage getMessageById(String messageId) { return dbOnlinechatMessageService.getById(messageId); } public void updateMessageDelete(String messageId, String targetUserName) { OtcOnlineChatMessage otcOnlineChatMessage = getMessageById(messageId); if (otcOnlineChatMessage.getDeleteStatus() == -1) { throw new BusinessException("该消息已撤回"); } // 游客或者登录用户 String userKey = StringUtils.isEmptyString(otcOnlineChatMessage.getPartyId()) ? otcOnlineChatMessage.getIp() : otcOnlineChatMessage.getPartyId(); otcOnlineChatMessage.setDeleteStatus(-1); dbOnlinechatMessageService.updateById(otcOnlineChatMessage); List list = cahce_chat.get(otcOnlineChatMessage.getOrderNo()); int indexOf = -1; for (int i = 0; i < list.size(); i++) { if (list.get(i).getUuid().equals(otcOnlineChatMessage.getUuid())) { indexOf = i; break; } } list.remove(indexOf); list.add(indexOf, otcOnlineChatMessage); cahce_chat.put(userKey, list); } @EventListener public void onApplicationEvent(ContextRefreshedEvent event) { init(); } public void init() { List list_user = otcMessageUserService.list(); for (int i = 0; i < list_user.size(); i++) { OtcMessageUser item = list_user.get(i); this.cahce_user.put(item.getOrderNo(), item); } QueryWrapper queryWrapper = new QueryWrapper<>(); queryWrapper.orderByDesc("create_time"); List list_chat = dbOnlinechatMessageService.list(queryWrapper); for (int i = 0; i < list_chat.size(); i++) { OtcOnlineChatMessage item = list_chat.get(i); List list = null; list = cahce_chat.get(item.getOrderNo()); if (list == null) { list = new LinkedList(); } list.add(item); this.cahce_chat.put(item.getOrderNo(), list); } } public Map> cacheMessageAll() { return cahce_chat; } public Map cacheMessageUserAll() { return cahce_user; } public OtcMessageUser cacheMessageUser(String key) { return cahce_user.get(key); } public List cacheMessage(String key) { List otcOnlineChatMessages = cahce_chat.get(key); if (org.springframework.util.CollectionUtils.isEmpty(otcOnlineChatMessages)) { return otcOnlineChatMessages; } otcOnlineChatMessages.forEach(msg -> { String content = msg.getContent(); content = UnicodeUtils.decodeUnicode(content); msg.setContent(content); }); return otcOnlineChatMessages; } public void putMessage(String key, List value) { cahce_chat.put(key, value); } public void putMessageUser(String key, OtcMessageUser value) { cahce_user.put(key, value); } public void updateMessageUserByIp(OtcMessageUser messageUser) { otcMessageUserService.updateById(messageUser); cahce_user.put(messageUser.getIp(), messageUser); } public void deleteByIp(String ip) { OtcMessageUser messageUser = cahce_user.get(ip); if (messageUser != null) { messageUser.setDeleteStatus(-1); this.updateMessageUserByIp(messageUser); } } public void setUserRecomService(UserRecomService userRecomService) { this.userRecomService = userRecomService; } public void setTipService(TipService tipService) { this.tipService = tipService; } public C2cOrderService getC2cOrderService() { return c2cOrderService; } public void setC2cOrderService(C2cOrderService c2cOrderService) { this.c2cOrderService = c2cOrderService; } @Override public void updateMessageRead(String messageId, String orderNo) { OtcOnlineChatMessage otcOnlineChatMessage = getMessageById(messageId); if (null == otcOnlineChatMessage) return; // if(null != otcOnlineChatMessage && 0 == otcOnlineChatMessage.getIsRead()) { // 只更新未读消息 String partyId = otcOnlineChatMessage.getPartyId(); // String userKey = StringUtils.isEmptyString(partyId)?otcOnlineChatMessage.getIp():partyId; // ApplicationUtil.executeUpdate(otcOnlineChatMessage); logger.info("OrderNo 11 -> " + otcOnlineChatMessage.getOrderNo()); logger.info("uuid 11 -> " + otcOnlineChatMessage.getUuid()); logger.info("PartyId 11 -> " + otcOnlineChatMessage.getPartyId()); List list = cahce_chat.get(otcOnlineChatMessage.getOrderNo()); list = list.stream().filter(elem -> null != elem).collect(Collectors.toList()); if (null != list && !list.isEmpty()) { logger.info("OrderNo 22 -> " + otcOnlineChatMessage.getOrderNo()); logger.info("uuid 22 -> " + otcOnlineChatMessage.getUuid()); logger.info("PartyId 22 -> " + otcOnlineChatMessage.getPartyId()); // int indexOf = list.indexOf(otcOnlineChatMessage); int indexOf = findOnlineChatMessage(otcOnlineChatMessage, list); if (indexOf > -1) { logger.info("OrderNo 33 -> " + otcOnlineChatMessage.getOrderNo()); logger.info("uuid 33 -> " + otcOnlineChatMessage.getUuid()); logger.info("PartyId 33 -> " + otcOnlineChatMessage.getPartyId()); otcOnlineChatMessage.setIsRead(1); list.set(indexOf, otcOnlineChatMessage); updateMessageReadData(otcOnlineChatMessage); logger.info("otcOnlineChatMessage 33 -> " + otcOnlineChatMessage); } } cahce_chat.put(orderNo, list); // } } private void updateMessageReadData(OtcOnlineChatMessage otcOnlineChatMessage) { int count = jdbcTemplate.update("UPDATE t_otc_onlinechat_message SET IS_READ=? WHERE UUID=?" , otcOnlineChatMessage.getIsRead() , otcOnlineChatMessage.getUuid()); } private int findOnlineChatMessage(OtcOnlineChatMessage onlineChatMessage, List list) { for (int i = 0; i < list.size(); i++) { if (Objects.equals(list.get(i).getUuid(), onlineChatMessage.getUuid())) { return i; } } return -1; } }