update websocket 链接限制变为同ip可以多个用户登录,单用户只能登录一个
This commit is contained in:
parent
c596d9ab30
commit
889189e726
|
@ -78,6 +78,7 @@ public class GlobalExceptionHandler {
|
||||||
@ExceptionHandler(ServiceException.class)
|
@ExceptionHandler(ServiceException.class)
|
||||||
public AjaxResult handleServiceException(ServiceException e, HttpServletRequest request)
|
public AjaxResult handleServiceException(ServiceException e, HttpServletRequest request)
|
||||||
{
|
{
|
||||||
|
|
||||||
log.error(e.getMessage(), e);
|
log.error(e.getMessage(), e);
|
||||||
Integer code = e.getCode();
|
Integer code = e.getCode();
|
||||||
return StringUtils.isNotNull(code) ? AjaxResult.error(code, e.getMessage()) : AjaxResult.error(e.getMessage());
|
return StringUtils.isNotNull(code) ? AjaxResult.error(code, e.getMessage()) : AjaxResult.error(e.getMessage());
|
||||||
|
@ -89,9 +90,10 @@ public class GlobalExceptionHandler {
|
||||||
@ExceptionHandler(RuntimeException.class)
|
@ExceptionHandler(RuntimeException.class)
|
||||||
public AjaxResult handleRuntimeException(RuntimeException e, HttpServletRequest request)
|
public AjaxResult handleRuntimeException(RuntimeException e, HttpServletRequest request)
|
||||||
{
|
{
|
||||||
|
System.out.println("异常抛出时间"+System.currentTimeMillis());
|
||||||
String requestURI = request.getRequestURI();
|
String requestURI = request.getRequestURI();
|
||||||
log.error("请求地址'{}',发生未知异常.", requestURI, e);
|
log.error("请求地址'{}',发生未知异常.", requestURI, e);
|
||||||
return AjaxResult.error(e.getMessage());
|
return AjaxResult.error(HttpStatus.BAD_REQUEST,e.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -54,8 +54,4 @@ public class ChatMessageController {
|
||||||
public AjaxResult readMessage(@RequestBody MessagePageVo pageVo) {
|
public AjaxResult readMessage(@RequestBody MessagePageVo pageVo) {
|
||||||
return chatMessageService.readMessage(pageVo.getRoomId());
|
return chatMessageService.readMessage(pageVo.getRoomId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -2,7 +2,7 @@ package com.m2pool.chat.controller;
|
||||||
|
|
||||||
import com.m2pool.chat.service.ChatRoomService;
|
import com.m2pool.chat.service.ChatRoomService;
|
||||||
import com.m2pool.chat.vo.CharRoomVo;
|
import com.m2pool.chat.vo.CharRoomVo;
|
||||||
import com.m2pool.chat.vo.MessagePageVo;
|
import com.m2pool.chat.vo.RoomPageVo;
|
||||||
import com.m2pool.common.core.web.Result.AjaxResult;
|
import com.m2pool.common.core.web.Result.AjaxResult;
|
||||||
import com.m2pool.common.core.web.page.TableDataInfo;
|
import com.m2pool.common.core.web.page.TableDataInfo;
|
||||||
import com.m2pool.common.security.annotation.RequiresLogin;
|
import com.m2pool.common.security.annotation.RequiresLogin;
|
||||||
|
@ -11,6 +11,8 @@ import io.swagger.annotations.ApiOperation;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
@Api(tags = "聊天室相关接口")
|
@Api(tags = "聊天室相关接口")
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/rooms")
|
@RequestMapping("/rooms")
|
||||||
|
@ -23,8 +25,13 @@ public class ChatRoomController {
|
||||||
@PostMapping("/find/room/list")
|
@PostMapping("/find/room/list")
|
||||||
@ApiOperation(value = "查询客服人员的聊天室列表")
|
@ApiOperation(value = "查询客服人员的聊天室列表")
|
||||||
@RequiresLogin
|
@RequiresLogin
|
||||||
public TableDataInfo findRoomList(@RequestBody MessagePageVo messagePageVo) {
|
public TableDataInfo findRoomList(@RequestBody(required = false) RoomPageVo roomPageVo) {
|
||||||
return chatRoomService.findRoomList(messagePageVo.getSendDateTime());
|
// 如果请求体为空,初始化一个默认的 RoomPageVo 对象
|
||||||
|
if (roomPageVo == null) {
|
||||||
|
roomPageVo = new RoomPageVo();
|
||||||
|
roomPageVo.setSendDateTime(LocalDateTime.now());
|
||||||
|
}
|
||||||
|
return chatRoomService.findRoomList(roomPageVo);
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/find/room/by/userid")
|
@GetMapping("/find/room/by/userid")
|
||||||
|
|
|
@ -17,7 +17,7 @@ public class ChatMessage {
|
||||||
@TableId(value = "id", type = IdType.AUTO)
|
@TableId(value = "id", type = IdType.AUTO)
|
||||||
private Long id;
|
private Long id;
|
||||||
private Integer type;
|
private Integer type;
|
||||||
private Integer read;
|
private Integer isRead;
|
||||||
private String sendEmail;
|
private String sendEmail;
|
||||||
private String content;
|
private String content;
|
||||||
private Long roomId;
|
private Long roomId;
|
||||||
|
|
|
@ -15,6 +15,7 @@ public class ChatMessageHistory {
|
||||||
@TableId(value = "id", type = IdType.AUTO)
|
@TableId(value = "id", type = IdType.AUTO)
|
||||||
private Long id;
|
private Long id;
|
||||||
private Integer type;
|
private Integer type;
|
||||||
|
private Integer isRead;
|
||||||
private String sendEmail;
|
private String sendEmail;
|
||||||
private String content;
|
private String content;
|
||||||
private Long roomId;
|
private Long roomId;
|
||||||
|
|
|
@ -23,7 +23,8 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
import static com.m2pool.chat.constant.CustomHeader.*;
|
import static com.m2pool.chat.constant.CustomHeader.*;
|
||||||
import static com.m2pool.chat.constant.UserType.CUSTOMER;
|
import static com.m2pool.chat.constant.UserType.LOGIN_USER;
|
||||||
|
import static com.m2pool.chat.constant.UserType.TOURIST;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -37,9 +38,9 @@ public class WebsocketChannelInterceptor implements ChannelInterceptor {
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(WebsocketChannelInterceptor.class);
|
private static final Logger LOGGER = LoggerFactory.getLogger(WebsocketChannelInterceptor.class);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 当前加入链接的ip
|
* 当前加入链接的ip ,key 为 ip ,VALUE 为用户邮箱
|
||||||
*/
|
*/
|
||||||
private static final ConcurrentHashMap<String, Boolean> ipConnectionCountMap = new ConcurrentHashMap<>();
|
private static final ConcurrentHashMap<String,String> ipConnectionCountMap = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -78,7 +79,7 @@ public class WebsocketChannelInterceptor implements ChannelInterceptor {
|
||||||
//最大链接数限制
|
//最大链接数限制
|
||||||
maxConnectionsLimit();
|
maxConnectionsLimit();
|
||||||
//根据客服端ip + 用户类型限制连接数
|
//根据客服端ip + 用户类型限制连接数
|
||||||
ipLimit(accessor,type);
|
ipLimit(accessor,type,email);
|
||||||
|
|
||||||
|
|
||||||
//链接请求头中用户信息存入stomp中
|
//链接请求头中用户信息存入stomp中
|
||||||
|
@ -117,14 +118,23 @@ public class WebsocketChannelInterceptor implements ChannelInterceptor {
|
||||||
* ip 链接个数限制
|
* ip 链接个数限制
|
||||||
* @param accessor
|
* @param accessor
|
||||||
*/
|
*/
|
||||||
private void ipLimit(StompHeaderAccessor accessor,int type){
|
private void ipLimit(StompHeaderAccessor accessor,int type,String email){
|
||||||
Map<String, Object> sessionAttributes = accessor.getSessionAttributes();
|
Map<String, Object> sessionAttributes = accessor.getSessionAttributes();
|
||||||
if (sessionAttributes != null) {
|
if (sessionAttributes != null) {
|
||||||
String ipAddr = (String) sessionAttributes.get(IPADDR);
|
String ipAddr = (String) sessionAttributes.get(IPADDR);
|
||||||
if(type != CUSTOMER && ipConnectionCountMap.get(ipAddr) != null){
|
System.out.println(accessor.getSessionId());
|
||||||
|
String hasConnectionEmail = ipConnectionCountMap.get(ipAddr);
|
||||||
|
//两种ip限制情况
|
||||||
|
//本次链接为游客 且ip上已经有人链接直接拒绝本次链接
|
||||||
|
if(type == TOURIST && hasConnectionEmail != null){
|
||||||
throw new MessageDeliveryException(ExceptionEnum.fromCode(ExceptionEnum.IP_LIMIT_CONNECT));
|
throw new MessageDeliveryException(ExceptionEnum.fromCode(ExceptionEnum.IP_LIMIT_CONNECT));
|
||||||
}
|
}
|
||||||
ipConnectionCountMap.put(ipAddr,true);
|
//本次链接为登录用户,并且已经链接.直接拒绝本次链接(多用户登录)
|
||||||
|
if ( type == LOGIN_USER && email.equals(hasConnectionEmail)) {
|
||||||
|
throw new MessageDeliveryException(ExceptionEnum.fromCode(ExceptionEnum.IP_LIMIT_CONNECT));
|
||||||
|
}
|
||||||
|
ipConnectionCountMap.put(ipAddr,email);
|
||||||
|
|
||||||
}else{
|
}else{
|
||||||
throw new MessageDeliveryException(ExceptionEnum.fromCode(ExceptionEnum.GET_PRINCIPAL_FAIL));
|
throw new MessageDeliveryException(ExceptionEnum.fromCode(ExceptionEnum.GET_PRINCIPAL_FAIL));
|
||||||
}
|
}
|
||||||
|
@ -157,15 +167,12 @@ public class WebsocketChannelInterceptor implements ChannelInterceptor {
|
||||||
Map<String, Object> sessionAttributes = accessor.getSessionAttributes();
|
Map<String, Object> sessionAttributes = accessor.getSessionAttributes();
|
||||||
if (sessionAttributes != null) {
|
if (sessionAttributes != null) {
|
||||||
String ipAddr = (String) sessionAttributes.get(IPADDR);
|
String ipAddr = (String) sessionAttributes.get(IPADDR);
|
||||||
if(ipConnectionCountMap.get(ipAddr) != null){
|
|
||||||
ipConnectionCountMap.remove(ipAddr);
|
ipConnectionCountMap.remove(ipAddr);
|
||||||
}
|
|
||||||
}else{
|
}else{
|
||||||
throw new MessageDeliveryException(ExceptionEnum.fromCode(ExceptionEnum.GET_PRINCIPAL_FAIL));
|
throw new MessageDeliveryException(ExceptionEnum.fromCode(ExceptionEnum.GET_PRINCIPAL_FAIL));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void postSend(Message<?> message, MessageChannel channel, boolean sent) {
|
public void postSend(Message<?> message, MessageChannel channel, boolean sent) {
|
||||||
LOGGER.info("------------WebsocketChannelInterceptor-postSend");
|
LOGGER.info("------------WebsocketChannelInterceptor-postSend");
|
||||||
|
|
|
@ -29,6 +29,6 @@ public interface ChatMessageMapper extends BaseMapper<ChatMessage> {
|
||||||
* @return Map<String, Integer>,键为用户邮箱,值为未读消息条数
|
* @return Map<String, Integer>,键为用户邮箱,值为未读消息条数
|
||||||
*/
|
*/
|
||||||
@MapKey("userEmail")
|
@MapKey("userEmail")
|
||||||
Map<String, Integer> findUnReadNums(@Param("userEmails") List<String> userEmails);
|
Map<String, Map<String,Integer>> findUnReadNums(@Param("userEmails") List<String> userEmails);
|
||||||
|
|
||||||
}
|
}
|
|
@ -3,19 +3,18 @@ package com.m2pool.chat.service;
|
||||||
import com.baomidou.mybatisplus.extension.service.IService;
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
import com.m2pool.chat.entity.ChatRoom;
|
import com.m2pool.chat.entity.ChatRoom;
|
||||||
import com.m2pool.chat.vo.CharRoomVo;
|
import com.m2pool.chat.vo.CharRoomVo;
|
||||||
|
import com.m2pool.chat.vo.RoomPageVo;
|
||||||
import com.m2pool.common.core.web.Result.AjaxResult;
|
import com.m2pool.common.core.web.Result.AjaxResult;
|
||||||
import com.m2pool.common.core.web.page.TableDataInfo;
|
import com.m2pool.common.core.web.page.TableDataInfo;
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
|
||||||
|
|
||||||
public interface ChatRoomService extends IService<ChatRoom> {
|
public interface ChatRoomService extends IService<ChatRoom> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询客服的聊天室列表
|
* 查询客服的聊天室列表
|
||||||
* @param sendDateTime 最后一个发送者发送时间
|
* @param roomPageVo
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
TableDataInfo findRoomList(LocalDateTime sendDateTime);
|
TableDataInfo findRoomList(RoomPageVo roomPageVo);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据当前用户邮箱查询聊天室
|
* 根据当前用户邮箱查询聊天室
|
||||||
|
|
|
@ -62,9 +62,11 @@ public class ChatMessageServiceImpl implements ChatMessageService {
|
||||||
}else if (username.equals(chatRoom.getUserTwoEmail())) {
|
}else if (username.equals(chatRoom.getUserTwoEmail())) {
|
||||||
updateUserEmail = chatRoom.getUserOneEmail();
|
updateUserEmail = chatRoom.getUserOneEmail();
|
||||||
}
|
}
|
||||||
int update = chatMessageMapper.update(ChatMessage.builder().read(1).build(),
|
int update = chatMessageMapper.update(ChatMessage.builder().isRead(1).build(),
|
||||||
new LambdaUpdateWrapper<ChatMessage>().eq(ChatMessage::getSendEmail, updateUserEmail).eq(ChatMessage::getRoomId, roomId));
|
new LambdaUpdateWrapper<ChatMessage>()
|
||||||
return update > 0 ? AjaxResult.success("已读") : AjaxResult.error("消息读取失败");
|
.eq(ChatMessage::getSendEmail, updateUserEmail)
|
||||||
|
.eq(ChatMessage::getRoomId, roomId));
|
||||||
|
return update >= 0 ? AjaxResult.success("已读") : AjaxResult.error("消息读取失败");
|
||||||
}
|
}
|
||||||
return AjaxResult.error("聊天室不存在");
|
return AjaxResult.error("聊天室不存在");
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package com.m2pool.chat.service.impl;
|
package com.m2pool.chat.service.impl;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
|
import com.github.pagehelper.PageHelper;
|
||||||
import com.github.pagehelper.PageInfo;
|
import com.github.pagehelper.PageInfo;
|
||||||
import com.m2pool.chat.dto.ChatRoomDto;
|
import com.m2pool.chat.dto.ChatRoomDto;
|
||||||
import com.m2pool.chat.entity.ChatRoom;
|
import com.m2pool.chat.entity.ChatRoom;
|
||||||
|
@ -8,6 +9,7 @@ import com.m2pool.chat.mapper.ChatMessageMapper;
|
||||||
import com.m2pool.chat.mapper.ChatRoomMapper;
|
import com.m2pool.chat.mapper.ChatRoomMapper;
|
||||||
import com.m2pool.chat.service.ChatRoomService;
|
import com.m2pool.chat.service.ChatRoomService;
|
||||||
import com.m2pool.chat.vo.CharRoomVo;
|
import com.m2pool.chat.vo.CharRoomVo;
|
||||||
|
import com.m2pool.chat.vo.RoomPageVo;
|
||||||
import com.m2pool.common.core.constant.HttpStatus;
|
import com.m2pool.common.core.constant.HttpStatus;
|
||||||
import com.m2pool.common.core.utils.PageUtils;
|
import com.m2pool.common.core.utils.PageUtils;
|
||||||
import com.m2pool.common.core.web.Result.AjaxResult;
|
import com.m2pool.common.core.web.Result.AjaxResult;
|
||||||
|
@ -21,7 +23,6 @@ import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import java.time.LocalDateTime;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
@ -40,18 +41,20 @@ public class ChatRoomServiceImpl extends ServiceImpl<ChatRoomMapper, ChatRoom> i
|
||||||
private RemoteUserService remoteUserService;
|
private RemoteUserService remoteUserService;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TableDataInfo findRoomList(LocalDateTime sendDateTime) {
|
public TableDataInfo findRoomList(RoomPageVo roomPageVo) {
|
||||||
String userEmail = SecurityUtils.getUsername();
|
String userEmail = SecurityUtils.getUsername();
|
||||||
PageUtils.startPage();
|
PageHelper.startPage(1, 20);
|
||||||
|
System.out.println("-----时间"+roomPageVo.getSendDateTime()+"-----------用户"+userEmail + "-----当前时间"+ System.currentTimeMillis());
|
||||||
//1.查找当前客服对应的聊天室
|
//1.查找当前客服对应的聊天室
|
||||||
List<ChatRoomDto> roomList = chatRoomMapper.findRoomList(userEmail,sendDateTime);
|
List<ChatRoomDto> roomList = chatRoomMapper.findRoomList(userEmail,roomPageVo.getSendDateTime());
|
||||||
List<String> userEmails = roomList.stream().map(ChatRoomDto::getUserEmail).collect(Collectors.toList());
|
List<String> userEmails = roomList.stream().map(ChatRoomDto::getUserEmail).collect(Collectors.toList());
|
||||||
//2.查询未读数量
|
//2.查询未读数量
|
||||||
if (!userEmails.isEmpty()){
|
if (!userEmails.isEmpty()){
|
||||||
Map<String, Integer> unReadNums = chatMessageMapper.findUnReadNums(userEmails);
|
Map<String, Map<String,Integer>> unReadNums = chatMessageMapper.findUnReadNums(userEmails);
|
||||||
for (ChatRoomDto room : roomList) {
|
for (ChatRoomDto room : roomList) {
|
||||||
Integer i = unReadNums.get(room.getUserEmail());
|
Map<String, Integer> stringIntegerMap = unReadNums.get(room.getUserEmail());
|
||||||
room.setUnReadNumber(i == null ? 0 : i);
|
Integer i = stringIntegerMap != null ? stringIntegerMap.get("unReadNumber") : 0;
|
||||||
|
room.setUnReadNumber(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,7 @@
|
||||||
package com.m2pool.chat.vo;
|
package com.m2pool.chat.vo;
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ClassName MessagePageVo
|
* @ClassName MessagePageVo
|
||||||
* @Description TODO
|
* @Description TODO
|
||||||
|
@ -17,10 +14,6 @@ public class MessagePageVo {
|
||||||
private Long id;
|
private Long id;
|
||||||
private Integer pageNum;
|
private Integer pageNum;
|
||||||
private Long roomId;
|
private Long roomId;
|
||||||
|
|
||||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
|
||||||
private LocalDateTime sendDateTime;
|
|
||||||
|
|
||||||
public MessagePageVo() {
|
public MessagePageVo() {
|
||||||
this.id = 1L;
|
this.id = 1L;
|
||||||
this.pageNum = 20;
|
this.pageNum = 20;
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
package com.m2pool.chat.vo;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import lombok.Data;
|
||||||
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ClassName MessagePageVo
|
||||||
|
* @Description TODO
|
||||||
|
* @Author yyb
|
||||||
|
* @Date 2025/4/22 17:09
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class RoomPageVo {
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
private LocalDateTime sendDateTime;
|
||||||
|
}
|
|
@ -15,14 +15,13 @@
|
||||||
LIMIT #{pageNum}
|
LIMIT #{pageNum}
|
||||||
</select>
|
</select>
|
||||||
<select id="findUnReadNums" resultType="java.util.Map">
|
<select id="findUnReadNums" resultType="java.util.Map">
|
||||||
SELECT send_email as userEmail,
|
SELECT send_email as userEmail,count(*) as unReadNums
|
||||||
count(*) as unReadNums
|
|
||||||
FROM chat_message
|
FROM chat_message
|
||||||
WHERE send_email IN
|
WHERE send_email IN
|
||||||
<foreach collection="userEmails" item="userEmail" open="(" separator="," close=")">
|
<foreach collection="userEmails" item="userEmail" open="(" separator="," close=")">
|
||||||
#{userEmail}
|
#{userEmail}
|
||||||
</foreach>
|
</foreach>
|
||||||
AND `read` = false
|
AND is_read = false
|
||||||
GROUP BY send_email
|
GROUP BY send_email
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
|
|
@ -11,9 +11,17 @@
|
||||||
last_customer_send_time as lastCustomerSendTime
|
last_customer_send_time as lastCustomerSendTime
|
||||||
FROM
|
FROM
|
||||||
chat_room
|
chat_room
|
||||||
WHERE
|
<where>
|
||||||
user_two_email = #{userEmail} AND last_user_send_time <![CDATA[ <= ]]> #{sendDateTime}
|
user_two_email = #{userEmail} AND del = FALSE
|
||||||
AND del = FALSE
|
<choose>
|
||||||
|
<when test="sendDateTime != null">
|
||||||
|
AND last_user_send_time <![CDATA[ <= ]]> #{sendDateTime}
|
||||||
|
</when>
|
||||||
|
<otherwise>
|
||||||
|
AND last_user_send_time <![CDATA[ <= ]]> NOW()
|
||||||
|
</otherwise>
|
||||||
|
</choose>
|
||||||
|
</where>
|
||||||
ORDER BY
|
ORDER BY
|
||||||
flag DESC,
|
flag DESC,
|
||||||
last_user_send_time DESC
|
last_user_send_time DESC
|
||||||
|
|
Loading…
Reference in New Issue