Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
S
SiEn
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
hewei
SiEn
Commits
6cab69bf
Commit
6cab69bf
authored
Oct 22, 2020
by
zhangjw
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
1:完善ws鉴权逻辑
2:会话列表接口新增 latestRecord recordId字段逻辑 3:全局status修改为code
parent
448d645d
Hide whitespace changes
Inline
Side-by-side
Showing
29 changed files
with
244 additions
and
211 deletions
+244
-211
customer-service/pom.xml
+0
-7
customer-service/src/main/java/com/ym/im/config/ExceptionConfig.java
+4
-4
customer-service/src/main/java/com/ym/im/config/RedisConfig.java
+1
-20
customer-service/src/main/java/com/ym/im/controller/SessionController.java
+8
-8
customer-service/src/main/java/com/ym/im/core/MessageDecoder.java
+2
-2
customer-service/src/main/java/com/ym/im/entity/JwtTokenRedisVo.java
+80
-0
customer-service/src/main/java/com/ym/im/entity/MsgBody.java
+1
-1
customer-service/src/main/java/com/ym/im/entity/Session.java
+2
-2
customer-service/src/main/java/com/ym/im/entity/model/SessionInfo.java
+18
-0
customer-service/src/main/java/com/ym/im/exception/IMessageException.java
+1
-1
customer-service/src/main/java/com/ym/im/factory/SingleChatFactory.java
+0
-1
customer-service/src/main/java/com/ym/im/handler/IndexHandler.java
+0
-120
customer-service/src/main/java/com/ym/im/handler/SingleChatHandler.java
+2
-2
customer-service/src/main/java/com/ym/im/handler/WebSocketHandshakerHandler.java
+34
-9
customer-service/src/main/java/com/ym/im/mapper/ChatRecordMapper.java
+6
-1
customer-service/src/main/java/com/ym/im/mq/Receiver.java
+4
-4
customer-service/src/main/java/com/ym/im/service/ChatRecordService.java
+3
-2
customer-service/src/main/java/com/ym/im/service/SessionListService.java
+11
-1
customer-service/src/main/java/com/ym/im/service/impl/ChatRecordServiceImpl.java
+10
-4
customer-service/src/main/java/com/ym/im/service/impl/MsgBodyServiceImpl.java
+5
-5
customer-service/src/main/java/com/ym/im/service/impl/SessionListServiceImpl.java
+24
-0
customer-service/src/main/java/com/ym/im/service/impl/StaffServiceImpl.java
+4
-4
customer-service/src/main/java/com/ym/im/service/impl/StaffSingleChatServiceImpl.java
+2
-2
customer-service/src/main/java/com/ym/im/service/impl/UserServiceImpl.java
+5
-5
customer-service/src/main/java/com/ym/im/service/impl/UserSingleChatServiceImpl.java
+1
-1
customer-service/src/main/java/com/ym/im/util/MybatisGenerator.java
+2
-1
customer-service/src/main/resources/application-dev.yml
+3
-3
customer-service/src/main/resources/com/ym/im/mapper/ChatRecordMapper.xml
+11
-0
pom.xml
+0
-1
No files found.
customer-service/pom.xml
View file @
6cab69bf
...
@@ -41,13 +41,6 @@
...
@@ -41,13 +41,6 @@
<dependencies>
<dependencies>
<!-- <dependency>-->
<!-- <groupId>com.ym</groupId>-->
<!-- <artifactId>pathfinder_common</artifactId>-->
<!-- <version>1.0-SNAPSHOT</version>-->
<!-- <scope>compile</scope>-->
<!-- </dependency>-->
<dependency>
<dependency>
<groupId>
org.springframework.boot
</groupId>
<groupId>
org.springframework.boot
</groupId>
<artifactId>
spring-boot-starter-web
</artifactId>
<artifactId>
spring-boot-starter-web
</artifactId>
...
...
customer-service/src/main/java/com/ym/im/config/ExceptionConfig.java
View file @
6cab69bf
...
@@ -48,7 +48,7 @@ public class ExceptionConfig {
...
@@ -48,7 +48,7 @@ public class ExceptionConfig {
final
String
errornum
=
UUID
.
randomUUID
().
toString
();
final
String
errornum
=
UUID
.
randomUUID
().
toString
();
log
.
error
(
"Error number: "
+
errornum
,
e
);
log
.
error
(
"Error number: "
+
errornum
,
e
);
final
MsgBody
msgBody
=
new
MsgBody
<>()
final
MsgBody
msgBody
=
new
MsgBody
<>()
.
set
Status
(
HttpStatus
.
INTERNAL_SERVER_ERROR
.
value
())
.
set
Code
(
HttpStatus
.
INTERNAL_SERVER_ERROR
.
value
())
.
setMessage
(
MessageUtils
.
getMsg
(
"error.system"
,
request
.
getLocale
(),
errornum
));
.
setMessage
(
MessageUtils
.
getMsg
(
"error.system"
,
request
.
getLocale
(),
errornum
));
return
new
ResponseEntity
<>(
msgBody
,
HttpStatus
.
INTERNAL_SERVER_ERROR
);
return
new
ResponseEntity
<>(
msgBody
,
HttpStatus
.
INTERNAL_SERVER_ERROR
);
}
}
...
@@ -61,7 +61,7 @@ public class ExceptionConfig {
...
@@ -61,7 +61,7 @@ public class ExceptionConfig {
@ExceptionHandler
(
value
=
HttpMessageNotReadableException
.
class
)
@ExceptionHandler
(
value
=
HttpMessageNotReadableException
.
class
)
protected
ResponseEntity
<
MsgBody
>
httpMessageNotReadableExceptionHandle
(
HttpServletRequest
request
)
{
protected
ResponseEntity
<
MsgBody
>
httpMessageNotReadableExceptionHandle
(
HttpServletRequest
request
)
{
final
MsgBody
msgBody
=
new
MsgBody
<>()
final
MsgBody
msgBody
=
new
MsgBody
<>()
.
set
Status
(
HttpStatus
.
BAD_REQUEST
.
value
())
.
set
Code
(
HttpStatus
.
BAD_REQUEST
.
value
())
.
setMessage
(
MessageUtils
.
getMsg
(
"error.missing_body"
,
request
.
getLocale
()));
.
setMessage
(
MessageUtils
.
getMsg
(
"error.missing_body"
,
request
.
getLocale
()));
return
new
ResponseEntity
<>(
msgBody
,
HttpStatus
.
BAD_REQUEST
);
return
new
ResponseEntity
<>(
msgBody
,
HttpStatus
.
BAD_REQUEST
);
}
}
...
@@ -74,7 +74,7 @@ public class ExceptionConfig {
...
@@ -74,7 +74,7 @@ public class ExceptionConfig {
*/
*/
@ExceptionHandler
(
value
=
IMessageException
.
class
)
@ExceptionHandler
(
value
=
IMessageException
.
class
)
protected
ResponseEntity
<
MsgBody
>
iMessageExceptionHandle
(
IMessageException
e
)
{
protected
ResponseEntity
<
MsgBody
>
iMessageExceptionHandle
(
IMessageException
e
)
{
final
MsgBody
msgBody
=
new
MsgBody
<>().
set
Status
(
HttpStatus
.
INTERNAL_SERVER_ERROR
.
value
()).
setMessage
(
"error.top_level_error"
);
final
MsgBody
msgBody
=
new
MsgBody
<>().
set
Code
(
HttpStatus
.
INTERNAL_SERVER_ERROR
.
value
()).
setMessage
(
"error.top_level_error"
);
return
new
ResponseEntity
<>(
msgBody
,
HttpStatus
.
INTERNAL_SERVER_ERROR
);
return
new
ResponseEntity
<>(
msgBody
,
HttpStatus
.
INTERNAL_SERVER_ERROR
);
}
}
...
@@ -101,7 +101,7 @@ public class ExceptionConfig {
...
@@ -101,7 +101,7 @@ public class ExceptionConfig {
}
}
}
}
final
MsgBody
<
List
<
String
>>
msgBody
=
new
MsgBody
<>();
final
MsgBody
<
List
<
String
>>
msgBody
=
new
MsgBody
<>();
msgBody
.
set
Status
(
HttpStatus
.
BAD_REQUEST
.
value
());
msgBody
.
set
Code
(
HttpStatus
.
BAD_REQUEST
.
value
());
msgBody
.
setMessage
(
MessageUtils
.
getMsg
(
"error.bad_parameter"
,
request
.
getLocale
())
+
errorMsg
.
toString
());
msgBody
.
setMessage
(
MessageUtils
.
getMsg
(
"error.bad_parameter"
,
request
.
getLocale
())
+
errorMsg
.
toString
());
return
new
ResponseEntity
<>(
msgBody
,
HttpStatus
.
BAD_REQUEST
);
return
new
ResponseEntity
<>(
msgBody
,
HttpStatus
.
BAD_REQUEST
);
}
}
...
...
customer-service/src/main/java/com/ym/im/config/RedisConfig.java
View file @
6cab69bf
...
@@ -17,26 +17,6 @@ import org.springframework.data.redis.serializer.StringRedisSerializer;
...
@@ -17,26 +17,6 @@ import org.springframework.data.redis.serializer.StringRedisSerializer;
**/
**/
@Configuration
@Configuration
public
class
RedisConfig
{
public
class
RedisConfig
{
/**
* 序列化、反序列化为Json的RedisTemplate
*
* @param redisConnectionFactory 连接工厂
* @param objectMapper Jackson.ObjectMapper
* @return redisTemplate
*/
@Bean
public
RedisTemplate
<
Object
,
Object
>
redisTemplate
(
RedisConnectionFactory
redisConnectionFactory
,
ObjectMapper
objectMapper
)
{
final
RedisSerializer
<
String
>
stringSerializer
=
new
StringRedisSerializer
();
final
GenericJackson2JsonRedisSerializer
jsonRedisSerializer
=
new
GenericJackson2JsonRedisSerializer
(
objectMapper
);
final
RedisTemplate
<
Object
,
Object
>
template
=
new
RedisTemplate
<>();
template
.
setKeySerializer
(
stringSerializer
);
template
.
setValueSerializer
(
jsonRedisSerializer
);
template
.
setHashKeySerializer
(
stringSerializer
);
template
.
setHashValueSerializer
(
jsonRedisSerializer
);
template
.
setDefaultSerializer
(
jsonRedisSerializer
);
template
.
setConnectionFactory
(
redisConnectionFactory
);
return
template
;
}
@Bean
@Bean
public
RedisTemplate
<
Object
,
Object
>
myRedisTemplate
(
RedisConnectionFactory
redisConnectionFactory
)
{
public
RedisTemplate
<
Object
,
Object
>
myRedisTemplate
(
RedisConnectionFactory
redisConnectionFactory
)
{
...
@@ -53,4 +33,5 @@ public class RedisConfig {
...
@@ -53,4 +33,5 @@ public class RedisConfig {
return
template
;
return
template
;
}
}
}
}
customer-service/src/main/java/com/ym/im/controller/SessionController.java
View file @
6cab69bf
...
@@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
...
@@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import
com.ym.im.entity.MsgBody
;
import
com.ym.im.entity.MsgBody
;
import
com.ym.im.entity.Session
;
import
com.ym.im.entity.Session
;
import
com.ym.im.entity.enums.ResultStatus
;
import
com.ym.im.entity.enums.ResultStatus
;
import
com.ym.im.entity.model.SessionInfo
;
import
com.ym.im.service.SessionListService
;
import
com.ym.im.service.SessionListService
;
import
io.swagger.annotations.Api
;
import
io.swagger.annotations.Api
;
import
io.swagger.annotations.ApiOperation
;
import
io.swagger.annotations.ApiOperation
;
...
@@ -27,20 +28,19 @@ public class SessionController {
...
@@ -27,20 +28,19 @@ public class SessionController {
@Autowired
@Autowired
private
SessionListService
sessionListService
;
private
SessionListService
sessionListService
;
@GetMapping
(
"/list"
)
@GetMapping
(
"/list"
)
@ApiOperation
(
value
=
"获取用户会话列表"
)
@ApiOperation
(
value
=
"获取用户会话列表"
)
public
MsgBody
<
List
<
Session
>>
getSessionList
(
Long
userId
)
{
public
MsgBody
<
List
<
SessionInfo
>>
getSessionList
(
Long
userId
)
{
return
new
MsgBody
<
List
<
Session
>>()
return
sessionListService
.
getSessionList
(
userId
);
.
setStatus
(
ResultStatus
.
SUCCESS
.
getCode
())
.
setData
(
sessionListService
.
list
(
new
QueryWrapper
<
Session
>().
lambda
().
eq
(
Session:
:
getUserId
,
userId
)));
}
}
@DeleteMapping
(
"/list"
)
@DeleteMapping
(
"/list"
)
@ApiOperation
(
value
=
"删除商户会话"
)
@ApiOperation
(
value
=
"删除商户会话"
)
public
MsgBody
deleteSessionList
(
Long
merchantId
)
{
public
MsgBody
deleteSessionList
(
Long
userId
,
Long
merchantId
)
{
sessionListService
.
remove
(
new
QueryWrapper
<
Session
>().
lambda
().
eq
(
Session:
:
getMerchantId
,
merchantId
));
sessionListService
.
remove
(
new
QueryWrapper
<
Session
>().
lambda
().
eq
(
Session:
:
get
UserId
,
userId
).
eq
(
Session:
:
get
MerchantId
,
merchantId
));
return
new
MsgBody
<>().
set
Status
(
ResultStatus
.
SUCCESS
.
getCode
());
return
new
MsgBody
<>().
set
Code
(
ResultStatus
.
SUCCESS
.
getCode
());
}
}
}
}
customer-service/src/main/java/com/ym/im/core/MessageDecoder.java
View file @
6cab69bf
...
@@ -34,12 +34,12 @@ public class MessageDecoder extends MessageToMessageDecoder<TextWebSocketFrame>
...
@@ -34,12 +34,12 @@ public class MessageDecoder extends MessageToMessageDecoder<TextWebSocketFrame>
protected
void
decode
(
ChannelHandlerContext
ctx
,
TextWebSocketFrame
textWebSocketFrame
,
List
out
)
throws
Exception
{
protected
void
decode
(
ChannelHandlerContext
ctx
,
TextWebSocketFrame
textWebSocketFrame
,
List
out
)
throws
Exception
{
final
String
jsonStr
=
textWebSocketFrame
.
text
();
final
String
jsonStr
=
textWebSocketFrame
.
text
();
MsgBody
<
ChatRecord
>
msgBody
=
new
MsgBody
<
ChatRecord
>().
set
Status
(
MsgBody
.
ERROR
);
MsgBody
<
ChatRecord
>
msgBody
=
new
MsgBody
<
ChatRecord
>().
set
Code
(
MsgBody
.
ERROR
);
try
{
try
{
msgBody
=
JsonUtils
.
json2Obj
(
jsonStr
,
MsgBody
.
class
,
ChatRecord
.
class
);
msgBody
=
JsonUtils
.
json2Obj
(
jsonStr
,
MsgBody
.
class
,
ChatRecord
.
class
);
}
catch
(
IOException
e
)
{
}
catch
(
IOException
e
)
{
log
.
error
(
"Json转{}异常:\r\n"
+
"Json原串:{}\r\n"
+
"===异常栈信息==="
,
"MsgBody.class"
,
jsonStr
,
e
);
log
.
error
(
"Json转{}异常:\r\n"
+
"Json原串:{}\r\n"
+
"===异常栈信息==="
,
"MsgBody.class"
,
jsonStr
,
e
);
msgBody
.
set
Status
(
MsgBody
.
ERROR
);
msgBody
.
set
Code
(
MsgBody
.
ERROR
);
msgBody
.
setMessage
(
"错误的Json格式:"
+
jsonStr
);
msgBody
.
setMessage
(
"错误的Json格式:"
+
jsonStr
);
ctx
.
channel
().
writeAndFlush
(
msgBody
);
ctx
.
channel
().
writeAndFlush
(
msgBody
);
return
;
return
;
...
...
customer-service/src/main/java/com/ym/im/entity/JwtTokenRedisVo.java
0 → 100755
View file @
6cab69bf
/*
* Copyright 2019-2029 geekidea(https://github.com/geekidea)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
com
.
ym
.
im
.
entity
;
import
lombok.Data
;
import
lombok.experimental.Accessors
;
import
java.io.Serializable
;
import
java.util.Date
;
/**
* JwtToken Redis缓存对象
*
* @author geekidea
* @date 2019-09-30
**/
@Data
@Accessors
(
chain
=
true
)
public
class
JwtTokenRedisVo
implements
Serializable
{
private
static
final
long
serialVersionUID
=
1831633309466775223L
;
/**
* 客户端类型
*/
private
String
type
;
/**
* mcId
*/
private
Long
mcId
;
/**
* 登录ip
*/
private
String
host
;
/**
* 登录用户ID
*/
private
Long
userId
;
/**
* 登录用户名称
*/
private
String
username
;
/**
* 登录盐值
*/
private
String
salt
;
/**
* 登录token
*/
private
String
token
;
/**
* 创建时间
*/
private
Date
createDate
;
/**
* 多长时间过期,默认一小时
*/
private
long
expireSecond
;
/**
* 过期日期
*/
private
Date
expireDate
;
}
customer-service/src/main/java/com/ym/im/entity/MsgBody.java
View file @
6cab69bf
...
@@ -43,7 +43,7 @@ public class MsgBody<T> implements Serializable {
...
@@ -43,7 +43,7 @@ public class MsgBody<T> implements Serializable {
" * 6、分配客服"
+
" * 6、分配客服"
+
" * 7、绑定失败"
" * 7、绑定失败"
)
)
private
Integer
status
;
private
Integer
code
;
@Valid
@Valid
@NotNull
(
message
=
"{error.msg_body_data_empty}"
,
groups
=
MsgBodyGroup
.
class
)
@NotNull
(
message
=
"{error.msg_body_data_empty}"
,
groups
=
MsgBodyGroup
.
class
)
...
...
customer-service/src/main/java/com/ym/im/entity/Session.java
View file @
6cab69bf
...
@@ -39,10 +39,10 @@ public class Session implements Serializable {
...
@@ -39,10 +39,10 @@ public class Session implements Serializable {
private
Long
merchantId
;
private
Long
merchantId
;
@NotNull
(
message
=
"{error.chat_create_time_empty}"
,
groups
=
{
Default
.
class
,
ChatRecordSaveGroup
.
class
})
@NotNull
(
message
=
"{error.chat_create_time_empty}"
,
groups
=
{
Default
.
class
,
ChatRecordSaveGroup
.
class
})
@ApiModelProperty
(
value
=
"创建时间
(服务端设置)
"
)
@ApiModelProperty
(
value
=
"创建时间"
)
private
Date
createTime
;
private
Date
createTime
;
@NotNull
(
message
=
"{error.chat_modify_time_empty}"
,
groups
=
{
Default
.
class
})
@NotNull
(
message
=
"{error.chat_modify_time_empty}"
,
groups
=
{
Default
.
class
})
@ApiModelProperty
(
value
=
"修改时间
(服务端设置
)"
)
@ApiModelProperty
(
value
=
"修改时间)"
)
private
Date
modifyTime
;
private
Date
modifyTime
;
}
}
customer-service/src/main/java/com/ym/im/entity/model/SessionInfo.java
0 → 100644
View file @
6cab69bf
package
com
.
ym
.
im
.
entity
.
model
;
import
com.ym.im.entity.Session
;
import
lombok.Data
;
import
lombok.experimental.Accessors
;
/**
* @author: JJww
* @Date:2020/10/22
*/
@Data
@Accessors
(
chain
=
true
)
public
class
SessionInfo
extends
Session
{
private
Long
recordId
;
private
String
latestRecord
;
}
customer-service/src/main/java/com/ym/im/exception/IMessageException.java
View file @
6cab69bf
...
@@ -26,7 +26,7 @@ public class IMessageException extends RuntimeException {
...
@@ -26,7 +26,7 @@ public class IMessageException extends RuntimeException {
super
(
MessageUtils
.
getMsg
(
i18nError
,
Locale
.
CHINA
));
super
(
MessageUtils
.
getMsg
(
i18nError
,
Locale
.
CHINA
));
this
.
i18nError
=
i18nError
;
this
.
i18nError
=
i18nError
;
this
.
msgBody
=
new
MsgBody
()
this
.
msgBody
=
new
MsgBody
()
.
set
Status
(
MsgBody
.
ERROR
)
.
set
Code
(
MsgBody
.
ERROR
)
.
setMessage
(
MessageUtils
.
getMsg
(
i18nError
));
.
setMessage
(
MessageUtils
.
getMsg
(
i18nError
));
}
}
}
}
customer-service/src/main/java/com/ym/im/factory/SingleChatFactory.java
View file @
6cab69bf
...
@@ -25,7 +25,6 @@ public class SingleChatFactory {
...
@@ -25,7 +25,6 @@ public class SingleChatFactory {
* @return
* @return
*/
*/
public
ChatService
getService
(
String
type
)
{
public
ChatService
getService
(
String
type
)
{
switch
(
RoleEnum
.
get
(
type
))
{
switch
(
RoleEnum
.
get
(
type
))
{
case
APP:
case
APP:
return
userSingleChatServiceImpl
;
return
userSingleChatServiceImpl
;
...
...
customer-service/src/main/java/com/ym/im/handler/IndexHandler.java
deleted
100644 → 0
View file @
448d645d
//package com.ym.im.handler;
//
//
//import com.ym.im.entity.BaseSocketInfo;
//import com.ym.im.entity.LanguageEnum;
//import com.ym.im.entity.MsgBody;
//import com.ym.im.entity.NettyConstant;
//import com.ym.im.entity.enums.PlatformEnum;
//import com.ym.im.factory.SingleChatFactory;
//import com.ym.im.service.ChannelGroupService;
//import io.netty.buffer.ByteBuf;
//import io.netty.buffer.Unpooled;
//import io.netty.channel.ChannelFuture;
//import io.netty.channel.ChannelFutureListener;
//import io.netty.channel.ChannelHandler;
//import io.netty.channel.ChannelHandlerContext;
//import io.netty.handler.codec.http.*;
//import io.netty.util.CharsetUtil;
//import lombok.extern.slf4j.Slf4j;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.data.redis.core.RedisTemplate;
//import org.springframework.stereotype.Component;
//
//import javax.annotation.Resource;
//import java.util.List;
//import java.util.Map;
//
//import static io.netty.handler.codec.http.HttpResponseStatus.UNAUTHORIZED;
//import static io.netty.handler.codec.http.HttpVersion.HTTP_1_1;
//
///**
// * @author: JJww
// * ws 校验/初始化相关处理
// * @Date:2019-05-17
// */
//@Slf4j
//@Component
//@ChannelHandler.Sharable
//public class IndexHandler extends BaseHandler<FullHttpRequest> {
//
// @Resource(name = "myRedisTemplate")
// private RedisTemplate redisTemplate;
//
// @Autowired
// private SingleChatFactory singleChatFactory;
//
// @Override
// protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest request) throws Exception {
//
// // 获取uri参数信息
// final Map<String, List<String>> parameters = new QueryStringDecoder(request.uri()).parameters();
// // 获取token信息
// final List<String> tokenStr = parameters.get(NettyConstant.TOKEN);
// if (tokenStr == null) {
// log.error("token值为空!");
// sendHttpResponse(ctx, request, new DefaultFullHttpResponse(HTTP_1_1, UNAUTHORIZED));
// return;
// }
// // 解析token
//// final String[] tokenInfo = String.valueOf(JwtUtil.checkToken(tokenStr.get(0)).get("user_id")).split("_");
// final String[] tokenInfo = null;
// if (tokenInfo.length < 2) {
// log.error("userId格式不正确:" + tokenInfo[1]);
// sendHttpResponse(ctx, request, new DefaultFullHttpResponse(HTTP_1_1, UNAUTHORIZED));
// return;
// }
// final Integer type = NettyConstant.CONNECT_TYPE.get(tokenInfo[0]);
// final Long userId = Long.valueOf(tokenInfo[1]);
// if (type == null) {
// log.error("用户类型值不正确:" + tokenInfo[0]);
// sendHttpResponse(ctx, request, new DefaultFullHttpResponse(HTTP_1_1, UNAUTHORIZED));
// return;
// }
//// if (NettyConstant.CONNECT_TYPE_USER == type.intValue() && Constants.FORBIDDEN.equals(redisTemplate.opsForHash().get(Constants.USER, userId))) {
//// log.info("用户被禁用:" + userId);
//// sendHttpResponse(ctx, request, new DefaultFullHttpResponse(HTTP_1_1, PROXY_AUTHENTICATION_REQUIRED));
//// return;
//// }
// //保存当前token
// String token = "Bearer " + tokenStr.get(0);
// ctx.channel().attr(NettyConstant.TOKEN_INFO).set(token);
// ctx.channel().attr(NettyConstant.ID).set(userId);
// ctx.channel().attr(NettyConstant.COL_INFO).set(parameters.get(NettyConstant.COL) == null ? LanguageEnum.zh.getKey() : parameters.get(NettyConstant.COL).get(0));
// this.close(token, userId, tokenInfo[0]);
// singleChatFactory.getService(type).init(ctx);
// request.setUri(NettyConstant.WS);
// ctx.fireChannelRead(request.retain());
// }
//
//
// private void close(String token, Long userId, String type) {
// final BaseSocketInfo baseSocketInfo = PlatformEnum.app.getKey().equals(type) ? ChannelGroupService.USER_GROUP.get(userId) : ChannelGroupService.STAFF_GROUP.get(userId);
// if (baseSocketInfo != null && !token.equals(baseSocketInfo.getToken())) {
// baseSocketInfo.getChannel().write(new MsgBody(MsgBody.FORCEDOFFLINE));
// baseSocketInfo.getChannel().close();
// ChannelGroupService.USER_GROUP.remove(userId);
// log.info("用户: " + userId + " 被迫下线");
// }
// }
//
//
// private static void sendHttpResponse(ChannelHandlerContext ctx, FullHttpRequest request, FullHttpResponse response) {
//
// if (response.status().code() != HttpResponseStatus.OK.code()) {
// ByteBuf buf = Unpooled.copiedBuffer(response.status().toString(), CharsetUtil.UTF_8);
// response.content().writeBytes(buf);
// buf.release();
// response.headers();
// HttpUtil.setContentLength(response, response.content().readableBytes());
// }
//
// ChannelFuture f = ctx.channel().writeAndFlush(response);
// if (!HttpUtil.isKeepAlive(request) || response.status().code() != HttpResponseStatus.OK.code()) {
// f.addListener(ChannelFutureListener.CLOSE);
// }
// }
//
//
//}
\ No newline at end of file
customer-service/src/main/java/com/ym/im/handler/SingleChatHandler.java
View file @
6cab69bf
...
@@ -42,11 +42,11 @@ public class SingleChatHandler extends BaseHandler<MsgBody<ChatRecord>> {
...
@@ -42,11 +42,11 @@ public class SingleChatHandler extends BaseHandler<MsgBody<ChatRecord>> {
next
=
constraintViolation
;
next
=
constraintViolation
;
errorMsg
.
add
(
next
.
getMessage
()
+
" "
+
((
PathImpl
)
next
.
getPropertyPath
()).
getLeafNode
().
asString
()
+
" = "
+
next
.
getInvalidValue
());
errorMsg
.
add
(
next
.
getMessage
()
+
" "
+
((
PathImpl
)
next
.
getPropertyPath
()).
getLeafNode
().
asString
()
+
" = "
+
next
.
getInvalidValue
());
}
}
msgBody
.
set
Status
(
MsgBody
.
ERROR
);
msgBody
.
set
Code
(
MsgBody
.
ERROR
);
msgBody
.
setMessage
(
errorMsg
.
toString
());
msgBody
.
setMessage
(
errorMsg
.
toString
());
ctx
.
channel
().
writeAndFlush
(
msgBody
);
ctx
.
channel
().
writeAndFlush
(
msgBody
);
}
catch
(
IMessageException
e
)
{
}
catch
(
IMessageException
e
)
{
msgBody
.
set
Status
(
MsgBody
.
ERROR
);
msgBody
.
set
Code
(
MsgBody
.
ERROR
);
msgBody
.
setMessage
(
MessageUtils
.
getMsg
(
e
.
getI18nError
()));
msgBody
.
setMessage
(
MessageUtils
.
getMsg
(
e
.
getI18nError
()));
ctx
.
channel
().
writeAndFlush
(
msgBody
);
ctx
.
channel
().
writeAndFlush
(
msgBody
);
}
catch
(
Exception
e
)
{
}
catch
(
Exception
e
)
{
...
...
customer-service/src/main/java/com/ym/im/handler/WebSocketHandshakerHandler.java
View file @
6cab69bf
package
com
.
ym
.
im
.
handler
;
package
com
.
ym
.
im
.
handler
;
import
com.ym.im.entity.JwtTokenRedisVo
;
import
com.ym.im.entity.MsgBody
;
import
com.ym.im.entity.MsgBody
;
import
com.ym.im.entity.base.BaseSocketInfo
;
import
com.ym.im.entity.base.BaseSocketInfo
;
import
com.ym.im.entity.base.ChannelAttributeKey
;
import
com.ym.im.entity.base.ChannelAttributeKey
;
...
@@ -12,9 +13,13 @@ import io.netty.channel.ChannelHandlerContext;
...
@@ -12,9 +13,13 @@ import io.netty.channel.ChannelHandlerContext;
import
io.netty.handler.codec.http.DefaultFullHttpResponse
;
import
io.netty.handler.codec.http.DefaultFullHttpResponse
;
import
io.netty.handler.codec.http.FullHttpRequest
;
import
io.netty.handler.codec.http.FullHttpRequest
;
import
lombok.extern.slf4j.Slf4j
;
import
lombok.extern.slf4j.Slf4j
;
import
org.apache.commons.codec.digest.DigestUtils
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.data.redis.core.RedisTemplate
;
import
org.springframework.stereotype.Component
;
import
org.springframework.stereotype.Component
;
import
javax.annotation.Resource
;
import
java.util.LinkedHashMap
;
import
java.util.Optional
;
import
java.util.Optional
;
import
static
io
.
netty
.
handler
.
codec
.
http
.
HttpResponseStatus
.
BAD_REQUEST
;
import
static
io
.
netty
.
handler
.
codec
.
http
.
HttpResponseStatus
.
BAD_REQUEST
;
...
@@ -37,25 +42,31 @@ public class WebSocketHandshakerHandler extends BaseHandler<FullHttpRequest> {
...
@@ -37,25 +42,31 @@ public class WebSocketHandshakerHandler extends BaseHandler<FullHttpRequest> {
@Autowired
@Autowired
private
SingleChatFactory
singleChatFactory
;
private
SingleChatFactory
singleChatFactory
;
public
static
final
String
ROLE_TYPE
=
"RoleType"
;
@Resource
(
name
=
"myRedisTemplate"
)
private
RedisTemplate
redisTemplate
;
public
static
final
String
MERCHANT_ID
=
"MerchantId"
;
public
static
final
String
AUTHORIZATION
=
"Authorization"
;
public
static
final
String
AUTHORIZATION
=
"Authorization"
;
/**
* 登录用户token信息key
* login:token:tokenMd5
*/
public
static
final
String
LOGIN_TOKEN
=
"login:token:%s"
;
@Override
@Override
protected
void
channelRead0
(
ChannelHandlerContext
ctx
,
FullHttpRequest
fullHttpRequest
)
throws
Exception
{
protected
void
channelRead0
(
ChannelHandlerContext
ctx
,
FullHttpRequest
fullHttpRequest
)
throws
Exception
{
final
String
token
=
fullHttpRequest
.
headers
().
get
(
AUTHORIZATION
);
final
String
token
=
fullHttpRequest
.
headers
().
get
(
AUTHORIZATION
);
Optional
.
ofNullable
(
token
).
orElseThrow
(()
->
new
HttpException
(
ctx
,
fullHttpRequest
,
new
DefaultFullHttpResponse
(
HTTP_1_1
,
UNAUTHORIZED
)));
Optional
.
ofNullable
(
token
).
orElseThrow
(()
->
new
HttpException
(
ctx
,
fullHttpRequest
,
new
DefaultFullHttpResponse
(
HTTP_1_1
,
UNAUTHORIZED
)));
final
String
roleType
=
fullHttpRequest
.
headers
().
get
(
ROLE_TYPE
,
null
);
final
JwtTokenRedisVo
tokenInfoForRedis
=
this
.
getTokenInfoForRedis
(
token
);
Optional
.
ofNullable
(
roleType
).
orElseThrow
(()
->
new
HttpException
(
ctx
,
fullHttpRequest
,
new
DefaultFullHttpResponse
(
HTTP_1_1
,
BAD_REQUEST
)));
Optional
.
ofNullable
(
tokenInfoForRedis
).
orElseThrow
(()
->
new
HttpException
(
ctx
,
fullHttpRequest
,
new
DefaultFullHttpResponse
(
HTTP_1_1
,
UNAUTHORIZED
)));
final
String
roleType
=
tokenInfoForRedis
.
getType
();
if
(
RoleEnum
.
merchant
.
getType
().
equals
(
roleType
))
{
if
(
RoleEnum
.
merchant
.
getType
().
equals
(
roleType
))
{
final
Object
merchantId
=
fullHttpRequest
.
headers
().
get
(
MERCHANT_ID
);
final
Long
merchantId
=
tokenInfoForRedis
.
getMcId
(
);
Optional
.
ofNullable
(
merchantId
).
orElseThrow
(()
->
new
HttpException
(
ctx
,
fullHttpRequest
,
new
DefaultFullHttpResponse
(
HTTP_1_1
,
BAD_REQUEST
)));
Optional
.
ofNullable
(
merchantId
).
orElseThrow
(()
->
new
HttpException
(
ctx
,
fullHttpRequest
,
new
DefaultFullHttpResponse
(
HTTP_1_1
,
BAD_REQUEST
)));
ctx
.
channel
().
attr
(
ChannelAttributeKey
.
MERCHANT_ID
).
set
(
Long
.
valueOf
(
merchantId
.
toString
())
);
ctx
.
channel
().
attr
(
ChannelAttributeKey
.
MERCHANT_ID
).
set
(
merchantId
);
}
}
final
Long
userId
=
Long
.
valueOf
(
fullHttpRequest
.
headers
().
get
(
MERCHANT_ID
));
//待完善鉴权逻辑
final
Long
userId
=
tokenInfoForRedis
.
getUserId
();
ctx
.
channel
().
attr
(
ChannelAttributeKey
.
ROLE_ID
).
set
(
userId
);
ctx
.
channel
().
attr
(
ChannelAttributeKey
.
ROLE_ID
).
set
(
userId
);
ctx
.
channel
().
attr
(
ChannelAttributeKey
.
TOKEN_INFO
).
set
(
token
);
ctx
.
channel
().
attr
(
ChannelAttributeKey
.
TOKEN_INFO
).
set
(
token
);
ctx
.
channel
().
attr
(
ChannelAttributeKey
.
ROLE_TYPE
).
set
(
roleType
);
ctx
.
channel
().
attr
(
ChannelAttributeKey
.
ROLE_TYPE
).
set
(
roleType
);
...
@@ -80,9 +91,23 @@ public class WebSocketHandshakerHandler extends BaseHandler<FullHttpRequest> {
...
@@ -80,9 +91,23 @@ public class WebSocketHandshakerHandler extends BaseHandler<FullHttpRequest> {
default
:
default
:
}
}
if
(
baseSocketInfo
!=
null
&&
!
token
.
equals
(
baseSocketInfo
.
getToken
()))
{
if
(
baseSocketInfo
!=
null
&&
!
token
.
equals
(
baseSocketInfo
.
getToken
()))
{
baseSocketInfo
.
writeAndFlush
(
new
MsgBody
<>().
set
Status
(
MsgBody
.
FORCEDOFFLINE
));
baseSocketInfo
.
writeAndFlush
(
new
MsgBody
<>().
set
Code
(
MsgBody
.
FORCEDOFFLINE
));
baseSocketInfo
.
close
();
baseSocketInfo
.
close
();
log
.
info
(
"用户: "
+
roleId
+
" 被迫下线"
);
log
.
info
(
"用户: "
+
roleId
+
" 被迫下线"
);
}
}
}
}
public
JwtTokenRedisVo
getTokenInfoForRedis
(
String
token
)
{
final
LinkedHashMap
jwtTokenInfo
=
(
LinkedHashMap
)
redisTemplate
.
opsForValue
().
get
(
String
.
format
(
LOGIN_TOKEN
,
DigestUtils
.
md5Hex
(
token
)));
if
(
jwtTokenInfo
==
null
)
{
return
null
;
}
//@class 对象路径不一致 重新set
final
String
type
=
jwtTokenInfo
.
get
(
"type"
).
toString
();
return
new
JwtTokenRedisVo
()
.
setUserId
(
Long
.
valueOf
(
jwtTokenInfo
.
get
(
"userId"
).
toString
()))
.
setType
(
type
).
setMcId
(
RoleEnum
.
merchant
.
getType
().
equals
(
type
)
?
Long
.
valueOf
(
jwtTokenInfo
.
get
(
"mcId"
).
toString
())
:
null
);
}
}
}
customer-service/src/main/java/com/ym/im/mapper/ChatRecordMapper.java
View file @
6cab69bf
package
com
.
ym
.
im
.
mapper
;
package
com
.
ym
.
im
.
mapper
;
import
com.baomidou.mybatisplus.core.mapper.BaseMapper
;
import
com.ym.im.entity.ChatRecord
;
import
com.ym.im.entity.ChatRecord
;
import
com.ym.im.entity.PullChatRecord
;
import
com.ym.im.entity.PullChatRecord
;
import
com.ym.im.entity.Session
;
import
org.apache.ibatis.annotations.Param
;
import
org.apache.ibatis.annotations.Param
;
import
java.util.List
;
import
java.util.List
;
...
@@ -14,7 +16,7 @@ import java.util.List;
...
@@ -14,7 +16,7 @@ import java.util.List;
* @author 陈俊雄
* @author 陈俊雄
* @since 2019-05-28
* @since 2019-05-28
*/
*/
public
interface
ChatRecordMapper
{
public
interface
ChatRecordMapper
extends
BaseMapper
<
ChatRecord
>
{
int
insert
(
@Param
(
"chat"
)
ChatRecord
chatRecord
,
@Param
(
"index"
)
int
index
);
int
insert
(
@Param
(
"chat"
)
ChatRecord
chatRecord
,
@Param
(
"index"
)
int
index
);
int
insertSelective
(
@Param
(
"chat"
)
ChatRecord
chatRecord
,
@Param
(
"index"
)
int
index
);
int
insertSelective
(
@Param
(
"chat"
)
ChatRecord
chatRecord
,
@Param
(
"index"
)
int
index
);
...
@@ -30,4 +32,7 @@ public interface ChatRecordMapper {
...
@@ -30,4 +32,7 @@ public interface ChatRecordMapper {
ChatRecord
selectById
(
@Param
(
"id"
)
Long
id
,
@Param
(
"index"
)
int
index
);
ChatRecord
selectById
(
@Param
(
"id"
)
Long
id
,
@Param
(
"index"
)
int
index
);
List
<
ChatRecord
>
getChatRecord
(
@Param
(
"pull"
)
PullChatRecord
pull
,
@Param
(
"index"
)
int
index
);
List
<
ChatRecord
>
getChatRecord
(
@Param
(
"pull"
)
PullChatRecord
pull
,
@Param
(
"index"
)
int
index
);
ChatRecord
getLatestRecord
(
@Param
(
"userId"
)
Long
userId
,
@Param
(
"merchantId"
)
Long
merchantId
,
@Param
(
"index"
)
int
index
);
}
}
customer-service/src/main/java/com/ym/im/mq/Receiver.java
View file @
6cab69bf
...
@@ -75,7 +75,7 @@ public class Receiver {
...
@@ -75,7 +75,7 @@ public class Receiver {
if
(
channelGroup
.
USER_GROUP
.
get
(
userId
)
!=
null
)
{
if
(
channelGroup
.
USER_GROUP
.
get
(
userId
)
!=
null
)
{
final
StaffSocketInfo
idleStaff
=
staffService
.
getIdleStaff
(
staffSocketInfo
.
getMerchantId
(),
userId
);
final
StaffSocketInfo
idleStaff
=
staffService
.
getIdleStaff
(
staffSocketInfo
.
getMerchantId
(),
userId
);
if
(
idleStaff
!=
null
)
{
if
(
idleStaff
!=
null
)
{
idleStaff
.
writeAndFlush
(
new
MsgBody
<>().
set
Status
(
MsgBody
.
DISTRIBUTION_STAFF
).
setData
(
new
IdModel
().
setStaffId
(
staffId
).
setUserId
(
userId
)));
idleStaff
.
writeAndFlush
(
new
MsgBody
<>().
set
Code
(
MsgBody
.
DISTRIBUTION_STAFF
).
setData
(
new
IdModel
().
setStaffId
(
staffId
).
setUserId
(
userId
)));
}
}
}
}
});
});
...
@@ -94,7 +94,7 @@ public class Receiver {
...
@@ -94,7 +94,7 @@ public class Receiver {
final
UserSocketInfo
userSocketInfo
=
channelGroup
.
USER_GROUP
.
get
(
Long
.
valueOf
(
userId
));
final
UserSocketInfo
userSocketInfo
=
channelGroup
.
USER_GROUP
.
get
(
Long
.
valueOf
(
userId
));
if
(
userSocketInfo
!=
null
)
{
if
(
userSocketInfo
!=
null
)
{
userSocketInfo
.
writeAndFlush
(
new
MsgBody
<>().
set
Status
(
MsgBody
.
LOGOUT
));
userSocketInfo
.
writeAndFlush
(
new
MsgBody
<>().
set
Code
(
MsgBody
.
LOGOUT
));
userSocketInfo
.
close
();
userSocketInfo
.
close
();
log
.
info
(
"用户: "
+
userId
+
"被禁用"
);
log
.
info
(
"用户: "
+
userId
+
"被禁用"
);
}
}
...
@@ -115,7 +115,7 @@ public class Receiver {
...
@@ -115,7 +115,7 @@ public class Receiver {
return
;
return
;
}
}
StaffSocketInfo
staffSocketInfo
=
channelGroup
.
getMerchantStaff
(
userSocketInfo
.
getStaffId
(
orderModel
.
getMerchantId
()));
StaffSocketInfo
staffSocketInfo
=
channelGroup
.
getMerchantStaff
(
userSocketInfo
.
getStaffId
(
orderModel
.
getMerchantId
()));
final
MsgBody
<
OrderModel
>
orderInfo
=
new
MsgBody
<
OrderModel
>().
set
Status
(
MsgBody
.
ORDER
).
setData
(
orderModel
);
final
MsgBody
<
OrderModel
>
orderInfo
=
new
MsgBody
<
OrderModel
>().
set
Code
(
MsgBody
.
ORDER
).
setData
(
orderModel
);
/**
/**
* 绑定客服在线,发送订单信息
* 绑定客服在线,发送订单信息
*/
*/
...
@@ -159,7 +159,7 @@ public class Receiver {
...
@@ -159,7 +159,7 @@ public class Receiver {
}
}
MsgBody
<
ChatRecord
>
msg
=
JsonUtils
.
json2Obj
(
String
.
valueOf
(
redisTemplate
.
opsForHash
().
get
(
NettyConstant
.
MSG_KEY
+
userId
,
recordId
)),
JsonUtils
.
getJavaType
(
MsgBody
.
class
,
ChatRecord
.
class
));
MsgBody
<
ChatRecord
>
msg
=
JsonUtils
.
json2Obj
(
String
.
valueOf
(
redisTemplate
.
opsForHash
().
get
(
NettyConstant
.
MSG_KEY
+
userId
,
recordId
)),
JsonUtils
.
getJavaType
(
MsgBody
.
class
,
ChatRecord
.
class
));
if
(
msg
!=
null
&&
msg
.
get
Status
().
equals
(
MsgBody
.
HAVE_READ
))
{
if
(
msg
!=
null
&&
msg
.
get
Code
().
equals
(
MsgBody
.
HAVE_READ
))
{
redisTemplate
.
opsForHash
().
delete
(
NettyConstant
.
MSG_KEY
+
userId
,
recordId
);
redisTemplate
.
opsForHash
().
delete
(
NettyConstant
.
MSG_KEY
+
userId
,
recordId
);
return
;
return
;
}
}
...
...
customer-service/src/main/java/com/ym/im/service/ChatRecordService.java
View file @
6cab69bf
...
@@ -30,7 +30,7 @@ public interface ChatRecordService {
...
@@ -30,7 +30,7 @@ public interface ChatRecordService {
@Validated
({
ChatRecordSaveGroup
.
class
})
@Validated
({
ChatRecordSaveGroup
.
class
})
int
insertSelective
(
@Valid
ChatRecord
chatRecord
);
int
insertSelective
(
@Valid
ChatRecord
chatRecord
);
int
updateById
(
ChatRecord
chatRecord
);
int
updateBy
Record
Id
(
ChatRecord
chatRecord
);
int
updateByIdSelective
(
ChatRecord
chatRecord
);
int
updateByIdSelective
(
ChatRecord
chatRecord
);
...
@@ -42,5 +42,6 @@ public interface ChatRecordService {
...
@@ -42,5 +42,6 @@ public interface ChatRecordService {
MsgBody
<
List
<
ChatRecord
>>
updateReceiveTime
(
List
<
ChatRecord
>
chats
);
MsgBody
<
List
<
ChatRecord
>>
updateReceiveTime
(
List
<
ChatRecord
>
chats
);
// MsgBody
ChatRecord
getLatestMsg
(
Long
userId
,
Long
merchantId
);
}
}
customer-service/src/main/java/com/ym/im/service/SessionListService.java
View file @
6cab69bf
package
com
.
ym
.
im
.
service
;
package
com
.
ym
.
im
.
service
;
import
com.baomidou.mybatisplus.extension.service.IService
;
import
com.baomidou.mybatisplus.extension.service.IService
;
import
com.ym.im.entity.MsgBody
;
import
com.ym.im.entity.Session
;
import
com.ym.im.entity.Session
;
import
com.ym.im.entity.model.SessionInfo
;
import
java.util.List
;
/**
/**
* @author: JJww
* @author: JJww
...
@@ -10,6 +14,12 @@ import com.ym.im.entity.Session;
...
@@ -10,6 +14,12 @@ import com.ym.im.entity.Session;
public
interface
SessionListService
extends
IService
<
Session
>
{
public
interface
SessionListService
extends
IService
<
Session
>
{
/**
* 获取会话信息列表
*
* @param userId
* @return
*/
MsgBody
<
List
<
SessionInfo
>>
getSessionList
(
Long
userId
);
}
}
customer-service/src/main/java/com/ym/im/service/impl/ChatRecordServiceImpl.java
View file @
6cab69bf
package
com
.
ym
.
im
.
service
.
impl
;
package
com
.
ym
.
im
.
service
.
impl
;
import
com.baomidou.mybatisplus.extension.service.impl.ServiceImpl
;
import
com.github.pagehelper.PageHelper
;
import
com.github.pagehelper.PageHelper
;
import
com.github.pagehelper.PageInfo
;
import
com.github.pagehelper.PageInfo
;
import
com.ym.im.entity.ChatRecord
;
import
com.ym.im.entity.ChatRecord
;
...
@@ -22,7 +23,7 @@ import java.util.List;
...
@@ -22,7 +23,7 @@ import java.util.List;
* @since 2019-05-28
* @since 2019-05-28
*/
*/
@Service
@Service
public
class
ChatRecordServiceImpl
implements
ChatRecordService
{
public
class
ChatRecordServiceImpl
extends
ServiceImpl
<
ChatRecordMapper
,
ChatRecord
>
implements
ChatRecordService
{
@Autowired
@Autowired
private
ChatRecordMapper
chatRecordMapper
;
private
ChatRecordMapper
chatRecordMapper
;
...
@@ -38,7 +39,7 @@ public class ChatRecordServiceImpl implements ChatRecordService {
...
@@ -38,7 +39,7 @@ public class ChatRecordServiceImpl implements ChatRecordService {
}
}
@Override
@Override
public
int
updateById
(
ChatRecord
chatRecord
)
{
public
int
updateBy
Record
Id
(
ChatRecord
chatRecord
)
{
return
chatRecordMapper
.
updateById
(
chatRecord
,
remainder
(
chatRecord
.
getUserId
()));
return
chatRecordMapper
.
updateById
(
chatRecord
,
remainder
(
chatRecord
.
getUserId
()));
}
}
...
@@ -65,16 +66,21 @@ public class ChatRecordServiceImpl implements ChatRecordService {
...
@@ -65,16 +66,21 @@ public class ChatRecordServiceImpl implements ChatRecordService {
pull
.
setChatRecords
(
chatRecords
);
pull
.
setChatRecords
(
chatRecords
);
pull
.
setPages
(
pageInfo
.
getPages
());
pull
.
setPages
(
pageInfo
.
getPages
());
pull
.
setTotal
(
pageInfo
.
getTotal
());
pull
.
setTotal
(
pageInfo
.
getTotal
());
return
new
MsgBody
<
PullChatRecord
>().
set
Status
(
ResultStatus
.
SUCCESS
.
getCode
()).
setData
(
pull
);
return
new
MsgBody
<
PullChatRecord
>().
set
Code
(
ResultStatus
.
SUCCESS
.
getCode
()).
setData
(
pull
);
}
}
@Override
@Override
public
MsgBody
<
List
<
ChatRecord
>>
updateReceiveTime
(
List
<
ChatRecord
>
chats
)
{
public
MsgBody
<
List
<
ChatRecord
>>
updateReceiveTime
(
List
<
ChatRecord
>
chats
)
{
chatRecordMapper
.
updateBatchReceiveTimeById
(
chats
,
remainder
(
chats
.
get
(
0
).
getUserId
()));
chatRecordMapper
.
updateBatchReceiveTimeById
(
chats
,
remainder
(
chats
.
get
(
0
).
getUserId
()));
return
new
MsgBody
<
List
<
ChatRecord
>>().
set
Status
(
ResultStatus
.
SUCCESS
.
getCode
()).
setData
(
chats
);
return
new
MsgBody
<
List
<
ChatRecord
>>().
set
Code
(
ResultStatus
.
SUCCESS
.
getCode
()).
setData
(
chats
);
}
}
@Override
public
ChatRecord
getLatestMsg
(
Long
userId
,
Long
merchantId
)
{
return
chatRecordMapper
.
getLatestRecord
(
userId
,
merchantId
,
remainder
(
userId
));
}
/**
/**
* 使用userId取聊天记录表数量余数
* 使用userId取聊天记录表数量余数
*
*
...
...
customer-service/src/main/java/com/ym/im/service/impl/MsgBodyServiceImpl.java
View file @
6cab69bf
...
@@ -51,7 +51,7 @@ public class MsgBodyServiceImpl implements MsgBodyService {
...
@@ -51,7 +51,7 @@ public class MsgBodyServiceImpl implements MsgBodyService {
final
ChatService
chatService
=
singleChatFactory
.
getService
(
ctx
.
channel
().
attr
(
ChannelAttributeKey
.
ROLE_TYPE
).
get
());
final
ChatService
chatService
=
singleChatFactory
.
getService
(
ctx
.
channel
().
attr
(
ChannelAttributeKey
.
ROLE_TYPE
).
get
());
switch
(
msgBody
.
get
Status
())
{
switch
(
msgBody
.
get
Code
())
{
case
SEND_MSG:
case
SEND_MSG:
// 获取用户、客服Id
// 获取用户、客服Id
...
@@ -59,18 +59,18 @@ public class MsgBodyServiceImpl implements MsgBodyService {
...
@@ -59,18 +59,18 @@ public class MsgBodyServiceImpl implements MsgBodyService {
// 先保存聊天消息
// 先保存聊天消息
chatService
.
save
(
id
,
msgBody
);
chatService
.
save
(
id
,
msgBody
);
// 再发送回执
// 再发送回执
ctx
.
channel
().
writeAndFlush
(
msgBody
.
set
Status
(
CHECK_MSG
)).
addListener
((
ChannelFutureListener
)
future
->
{
ctx
.
channel
().
writeAndFlush
(
msgBody
.
set
Code
(
CHECK_MSG
)).
addListener
((
ChannelFutureListener
)
future
->
{
// 获取对应的channel
// 获取对应的channel
final
NioSocketChannel
channel
=
chatService
.
distribution
(
id
,
msgBody
);
final
NioSocketChannel
channel
=
chatService
.
distribution
(
id
,
msgBody
);
if
(
channel
!=
null
)
{
if
(
channel
!=
null
)
{
// 最后发送聊天消息
// 最后发送聊天消息
chatService
.
send
(
channel
,
msgBody
.
set
Status
(
SEND_MSG
));
chatService
.
send
(
channel
,
msgBody
.
set
Code
(
SEND_MSG
));
}
}
});
});
break
;
break
;
case
CHECK_MSG:
case
CHECK_MSG:
msgBody
.
set
Status
(
MsgBody
.
HAVE_READ
);
//回执
msgBody
.
set
Code
(
MsgBody
.
HAVE_READ
);
//回执
chatService
.
ack
(
msgBody
);
chatService
.
ack
(
msgBody
);
break
;
break
;
...
@@ -82,7 +82,7 @@ public class MsgBodyServiceImpl implements MsgBodyService {
...
@@ -82,7 +82,7 @@ public class MsgBodyServiceImpl implements MsgBodyService {
@Override
@Override
public
void
sendAndAck
(
NioSocketChannel
channel
,
MsgBody
<
ChatRecord
>
msgBody
)
throws
JsonProcessingException
{
public
void
sendAndAck
(
NioSocketChannel
channel
,
MsgBody
<
ChatRecord
>
msgBody
)
throws
JsonProcessingException
{
msgBody
.
set
Status
(
SEND_MSG
);
msgBody
.
set
Code
(
SEND_MSG
);
// 先保存消息至Redis
// 先保存消息至Redis
redisTemplate
.
opsForHash
().
put
(
NettyConstant
.
MSG_KEY
+
msgBody
.
getData
().
getUserId
(),
msgBody
.
getData
().
getId
(),
JsonUtils
.
obj2Json
(
msgBody
));
redisTemplate
.
opsForHash
().
put
(
NettyConstant
.
MSG_KEY
+
msgBody
.
getData
().
getUserId
(),
msgBody
.
getData
().
getId
(),
JsonUtils
.
obj2Json
(
msgBody
));
// 再默认以用户没有收到消息为前提,做循环、延迟通知
// 再默认以用户没有收到消息为前提,做循环、延迟通知
...
...
customer-service/src/main/java/com/ym/im/service/impl/SessionListServiceImpl.java
View file @
6cab69bf
package
com
.
ym
.
im
.
service
.
impl
;
package
com
.
ym
.
im
.
service
.
impl
;
import
com.baomidou.mybatisplus.core.conditions.query.QueryWrapper
;
import
com.baomidou.mybatisplus.extension.service.impl.ServiceImpl
;
import
com.baomidou.mybatisplus.extension.service.impl.ServiceImpl
;
import
com.ym.im.entity.ChatRecord
;
import
com.ym.im.entity.MsgBody
;
import
com.ym.im.entity.Session
;
import
com.ym.im.entity.Session
;
import
com.ym.im.entity.enums.ResultStatus
;
import
com.ym.im.entity.model.SessionInfo
;
import
com.ym.im.mapper.SessionListMapper
;
import
com.ym.im.mapper.SessionListMapper
;
import
com.ym.im.service.ChatRecordService
;
import
com.ym.im.service.SessionListService
;
import
com.ym.im.service.SessionListService
;
import
lombok.extern.slf4j.Slf4j
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.beans.BeanUtils
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.stereotype.Service
;
import
org.springframework.stereotype.Service
;
import
java.util.ArrayList
;
import
java.util.List
;
/**
/**
* @author: JJww
* @author: JJww
* @Date:2020/10/21
* @Date:2020/10/21
...
@@ -15,5 +26,18 @@ import org.springframework.stereotype.Service;
...
@@ -15,5 +26,18 @@ import org.springframework.stereotype.Service;
@Service
@Service
public
class
SessionListServiceImpl
extends
ServiceImpl
<
SessionListMapper
,
Session
>
implements
SessionListService
{
public
class
SessionListServiceImpl
extends
ServiceImpl
<
SessionListMapper
,
Session
>
implements
SessionListService
{
@Autowired
private
ChatRecordService
chatRecordService
;
@Override
public
MsgBody
<
List
<
SessionInfo
>>
getSessionList
(
Long
userId
)
{
final
List
<
SessionInfo
>
sessions
=
new
ArrayList
<>();
baseMapper
.
selectList
(
new
QueryWrapper
<
Session
>().
lambda
().
eq
(
Session:
:
getUserId
,
userId
)).
forEach
(
session
->
{
final
ChatRecord
latestMsg
=
chatRecordService
.
getLatestMsg
(
userId
,
session
.
getMerchantId
());
final
SessionInfo
sessionModel
=
new
SessionInfo
().
setLatestRecord
(
latestMsg
.
getMsgInfo
()).
setRecordId
(
latestMsg
.
getId
());
BeanUtils
.
copyProperties
(
session
,
sessionModel
);
sessions
.
add
(
sessionModel
);
});
return
new
MsgBody
<
List
<
SessionInfo
>>().
setCode
(
ResultStatus
.
SUCCESS
.
getCode
()).
setData
(
sessions
);
}
}
}
customer-service/src/main/java/com/ym/im/service/impl/StaffServiceImpl.java
View file @
6cab69bf
...
@@ -54,7 +54,7 @@ public class StaffServiceImpl implements StaffService {
...
@@ -54,7 +54,7 @@ public class StaffServiceImpl implements StaffService {
final
Long
staffId
=
staffSocketInfo
.
getStaffId
();
final
Long
staffId
=
staffSocketInfo
.
getStaffId
();
userSocketInfo
.
setStaff
(
merchantId
,
staffId
);
userSocketInfo
.
setStaff
(
merchantId
,
staffId
);
//通知用户 新的客服
//通知用户 新的客服
userSocketInfo
.
writeAndFlush
(
new
MsgBody
<>().
set
Status
(
MsgBody
.
DISTRIBUTION_STAFF
).
setData
(
new
IdModel
().
setStaffId
(
staffId
).
setUserId
(
userId
)));
userSocketInfo
.
writeAndFlush
(
new
MsgBody
<>().
set
Code
(
MsgBody
.
DISTRIBUTION_STAFF
).
setData
(
new
IdModel
().
setStaffId
(
staffId
).
setUserId
(
userId
)));
}
}
return
staffSocketInfo
;
return
staffSocketInfo
;
}
}
...
@@ -69,14 +69,14 @@ public class StaffServiceImpl implements StaffService {
...
@@ -69,14 +69,14 @@ public class StaffServiceImpl implements StaffService {
final
UserSocketInfo
userSocketInfo
=
channelGroup
.
USER_GROUP
.
get
(
userId
);
final
UserSocketInfo
userSocketInfo
=
channelGroup
.
USER_GROUP
.
get
(
userId
);
final
StaffSocketInfo
staffSocketInfo
=
channelGroup
.
getMerchantStaff
(
staffId
);
final
StaffSocketInfo
staffSocketInfo
=
channelGroup
.
getMerchantStaff
(
staffId
);
if
(
staffSocketInfo
==
null
||
userSocketInfo
==
null
)
{
if
(
staffSocketInfo
==
null
||
userSocketInfo
==
null
)
{
return
new
MsgBody
<>().
set
Status
(
MsgBody
.
BINDINGFAILURE
).
setMessage
(
ResultStatus
.
FORWARD_FAILURE
.
getMessage
());
return
new
MsgBody
<>().
set
Code
(
MsgBody
.
BINDINGFAILURE
).
setMessage
(
ResultStatus
.
FORWARD_FAILURE
.
getMessage
());
}
}
//移除原客服绑定
//移除原客服绑定
channelGroup
.
getMerchantStaff
(
userSocketInfo
.
getStaffId
(
merchantId
)).
getUserIds
().
remove
(
userId
);
channelGroup
.
getMerchantStaff
(
userSocketInfo
.
getStaffId
(
merchantId
)).
getUserIds
().
remove
(
userId
);
//设置新的客服
//设置新的客服
staffSocketInfo
.
getUserIds
().
add
(
userId
);
staffSocketInfo
.
getUserIds
().
add
(
userId
);
userSocketInfo
.
setStaff
(
merchantId
,
staffId
);
userSocketInfo
.
setStaff
(
merchantId
,
staffId
);
final
MsgBody
<
IdModel
>
msgBody
=
new
MsgBody
<
IdModel
>().
set
Status
(
MsgBody
.
DISTRIBUTION_STAFF
).
setData
(
idModel
);
final
MsgBody
<
IdModel
>
msgBody
=
new
MsgBody
<
IdModel
>().
set
Code
(
MsgBody
.
DISTRIBUTION_STAFF
).
setData
(
idModel
);
//通知用户 新客服ID
//通知用户 新客服ID
userSocketInfo
.
writeAndFlush
(
msgBody
);
userSocketInfo
.
writeAndFlush
(
msgBody
);
//通知新客服
//通知新客服
...
@@ -91,7 +91,7 @@ public class StaffServiceImpl implements StaffService {
...
@@ -91,7 +91,7 @@ public class StaffServiceImpl implements StaffService {
channelGroup
.
STAFF_GROUP
.
get
(
merchantId
).
forEach
((
k
,
v
)
->
{
channelGroup
.
STAFF_GROUP
.
get
(
merchantId
).
forEach
((
k
,
v
)
->
{
staffs
.
add
(
v
);
staffs
.
add
(
v
);
});
});
return
new
MsgBody
<>().
set
Status
(
ResultStatus
.
SUCCESS
.
getCode
()).
setData
(
staffs
);
return
new
MsgBody
<>().
set
Code
(
ResultStatus
.
SUCCESS
.
getCode
()).
setData
(
staffs
);
}
}
...
...
customer-service/src/main/java/com/ym/im/service/impl/StaffSingleChatServiceImpl.java
View file @
6cab69bf
...
@@ -113,12 +113,12 @@ public class StaffSingleChatServiceImpl implements ChatService {
...
@@ -113,12 +113,12 @@ public class StaffSingleChatServiceImpl implements ChatService {
if
(
currentStaffId
==
null
)
{
if
(
currentStaffId
==
null
)
{
//通知用户 新的客服
//通知用户 新的客服
userSocketInfo
.
setStaff
(
merchantId
,
id
);
userSocketInfo
.
setStaff
(
merchantId
,
id
);
userSocketInfo
.
writeAndFlush
(
new
MsgBody
<>().
set
Status
(
MsgBody
.
DISTRIBUTION_STAFF
).
setData
(
new
IdModel
().
setStaffId
(
id
).
setUserId
(
userId
)));
userSocketInfo
.
writeAndFlush
(
new
MsgBody
<>().
set
Code
(
MsgBody
.
DISTRIBUTION_STAFF
).
setData
(
new
IdModel
().
setStaffId
(
id
).
setUserId
(
userId
)));
channelGroup
.
getMerchantStaff
(
id
).
getUserIds
().
add
(
userId
);
channelGroup
.
getMerchantStaff
(
id
).
getUserIds
().
add
(
userId
);
}
}
if
(
currentStaffId
!=
null
&&
!
currentStaffId
.
equals
(
id
))
{
if
(
currentStaffId
!=
null
&&
!
currentStaffId
.
equals
(
id
))
{
//通知客服 绑定失败 当前用户已绑定客服
//通知客服 绑定失败 当前用户已绑定客服
channelGroup
.
getMerchantStaff
(
id
).
writeAndFlush
(
new
MsgBody
<>().
set
Status
(
MsgBody
.
BINDINGFAILURE
).
setData
(
new
IdModel
().
setStaffId
(
currentStaffId
).
setUserId
(
userId
).
setMerchantId
(
merchantId
)));
channelGroup
.
getMerchantStaff
(
id
).
writeAndFlush
(
new
MsgBody
<>().
set
Code
(
MsgBody
.
BINDINGFAILURE
).
setData
(
new
IdModel
().
setStaffId
(
currentStaffId
).
setUserId
(
userId
).
setMerchantId
(
merchantId
)));
return
null
;
return
null
;
}
}
return
userSocketInfo
.
getChannel
();
return
userSocketInfo
.
getChannel
();
...
...
customer-service/src/main/java/com/ym/im/service/impl/UserServiceImpl.java
View file @
6cab69bf
...
@@ -37,7 +37,7 @@ public class UserServiceImpl implements UserService {
...
@@ -37,7 +37,7 @@ public class UserServiceImpl implements UserService {
if
(
usersId
.
size
()
>
0
)
{
if
(
usersId
.
size
()
>
0
)
{
redisTemplate
.
delete
(
NettyConstant
.
STAFF_USERIDS_KEY
+
staffId
);
redisTemplate
.
delete
(
NettyConstant
.
STAFF_USERIDS_KEY
+
staffId
);
}
}
return
new
MsgBody
<>().
set
Status
(
ResultStatus
.
SUCCESS
.
getCode
()).
setData
(
usersId
);
return
new
MsgBody
<>().
set
Code
(
ResultStatus
.
SUCCESS
.
getCode
()).
setData
(
usersId
);
}
}
@Override
@Override
...
@@ -45,14 +45,14 @@ public class UserServiceImpl implements UserService {
...
@@ -45,14 +45,14 @@ public class UserServiceImpl implements UserService {
final
StaffSocketInfo
staffSocketInfo
=
channelGroup
.
getMerchantStaff
(
idModel
.
getStaffId
());
final
StaffSocketInfo
staffSocketInfo
=
channelGroup
.
getMerchantStaff
(
idModel
.
getStaffId
());
if
(
staffSocketInfo
==
null
)
{
if
(
staffSocketInfo
==
null
)
{
return
new
MsgBody
<>().
set
Status
(
ResultStatus
.
REQUEST_ERROR
.
getCode
()).
setMessage
(
ResultStatus
.
REQUEST_ERROR
.
getMessage
());
return
new
MsgBody
<>().
set
Code
(
ResultStatus
.
REQUEST_ERROR
.
getCode
()).
setMessage
(
ResultStatus
.
REQUEST_ERROR
.
getMessage
());
}
}
staffSocketInfo
.
getUserIds
().
remove
(
idModel
.
getUserId
());
staffSocketInfo
.
getUserIds
().
remove
(
idModel
.
getUserId
());
final
UserSocketInfo
userSocketInfo
=
channelGroup
.
USER_GROUP
.
get
(
idModel
.
getUserId
());
final
UserSocketInfo
userSocketInfo
=
channelGroup
.
USER_GROUP
.
get
(
idModel
.
getUserId
());
if
(
userSocketInfo
!=
null
&&
idModel
.
getStaffId
().
equals
(
userSocketInfo
.
getStaffId
(
idModel
.
getMerchantId
())))
{
if
(
userSocketInfo
!=
null
&&
idModel
.
getStaffId
().
equals
(
userSocketInfo
.
getStaffId
(
idModel
.
getMerchantId
())))
{
userSocketInfo
.
getStaffIds
().
remove
(
idModel
.
getMerchantId
());
userSocketInfo
.
getStaffIds
().
remove
(
idModel
.
getMerchantId
());
}
}
return
new
MsgBody
<>().
set
Status
(
ResultStatus
.
SUCCESS
.
getCode
());
return
new
MsgBody
<>().
set
Code
(
ResultStatus
.
SUCCESS
.
getCode
());
}
}
@Override
@Override
...
@@ -65,9 +65,9 @@ public class UserServiceImpl implements UserService {
...
@@ -65,9 +65,9 @@ public class UserServiceImpl implements UserService {
* 用户在线未绑定客服
* 用户在线未绑定客服
*/
*/
if
(
userSocketInfo
==
null
||
(
userSocketInfo
!=
null
&&
idModel
.
getStaffId
().
equals
(
userSocketInfo
.
getStaffId
(
merchantId
))
||
userSocketInfo
.
getStaffId
(
merchantId
)
==
null
))
{
if
(
userSocketInfo
==
null
||
(
userSocketInfo
!=
null
&&
idModel
.
getStaffId
().
equals
(
userSocketInfo
.
getStaffId
(
merchantId
))
||
userSocketInfo
.
getStaffId
(
merchantId
)
==
null
))
{
return
new
MsgBody
<>().
set
Status
(
ResultStatus
.
SUCCESS
.
getCode
());
return
new
MsgBody
<>().
set
Code
(
ResultStatus
.
SUCCESS
.
getCode
());
}
}
return
new
MsgBody
<>().
set
Status
(
ResultStatus
.
CHECK_FAILURE
.
getCode
()).
setData
(
userSocketInfo
.
getStaffId
(
merchantId
));
return
new
MsgBody
<>().
set
Code
(
ResultStatus
.
CHECK_FAILURE
.
getCode
()).
setData
(
userSocketInfo
.
getStaffId
(
merchantId
));
}
}
...
...
customer-service/src/main/java/com/ym/im/service/impl/UserSingleChatServiceImpl.java
View file @
6cab69bf
...
@@ -217,7 +217,7 @@ public class UserSingleChatServiceImpl implements ChatService {
...
@@ -217,7 +217,7 @@ public class UserSingleChatServiceImpl implements ChatService {
channelGroup
.
USER_GROUP
.
get
(
userId
).
getStaffIds
().
forEach
((
merchantId
,
staffId
)
->
{
channelGroup
.
USER_GROUP
.
get
(
userId
).
getStaffIds
().
forEach
((
merchantId
,
staffId
)
->
{
channelGroup
.
STAFF_GROUP
.
get
(
merchantId
).
values
().
forEach
(
staffSocketInfo
->
{
channelGroup
.
STAFF_GROUP
.
get
(
merchantId
).
values
().
forEach
(
staffSocketInfo
->
{
staffSocketInfo
.
getUserIds
().
remove
(
userId
);
staffSocketInfo
.
getUserIds
().
remove
(
userId
);
staffSocketInfo
.
writeAndFlush
(
new
MsgBody
<>().
set
Status
(
MsgBody
.
USERS_ONLINE
).
setData
(
new
IdModel
().
setStaffId
(
staffId
).
setUserId
(
userId
)));
staffSocketInfo
.
writeAndFlush
(
new
MsgBody
<>().
set
Code
(
MsgBody
.
USERS_ONLINE
).
setData
(
new
IdModel
().
setStaffId
(
staffId
).
setUserId
(
userId
)));
});
});
});
});
}
}
...
...
customer-service/src/main/java/com/ym/im/util/MybatisGenerator.java
View file @
6cab69bf
//package com.ym.im.util;
//package com.ym.im.util;
//
//
//import cn.hutool.extra.template.TemplateConfig;
//import com.baomidou.mybatisplus.core.config.GlobalConfig;
//import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException;
//import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException;
//import com.baomidou.mybatisplus.core.toolkit.StringPool;
//import com.baomidou.mybatisplus.core.toolkit.StringPool;
//import com.baomidou.mybatisplus.generator.AutoGenerator;
//import com.baomidou.mybatisplus.generator.AutoGenerator;
//import com.baomidou.mybatisplus.generator.InjectionConfig;
//import com.baomidou.mybatisplus.generator.InjectionConfig;
//import com.baomidou.mybatisplus.generator.config.*;
//import com.baomidou.mybatisplus.generator.config.po.TableInfo;
//import com.baomidou.mybatisplus.generator.config.po.TableInfo;
//import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
//import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
//import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
//import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
...
...
customer-service/src/main/resources/application-dev.yml
View file @
6cab69bf
...
@@ -34,9 +34,9 @@ spring:
...
@@ -34,9 +34,9 @@ spring:
simple
:
simple
:
default-requeue-rejected
:
false
default-requeue-rejected
:
false
redis
:
redis
:
database
:
5
database
:
0
host
:
127.0.0.1
host
:
47.99.47.225
password
:
password
:
temple123456
port
:
6379
port
:
6379
# (重要!)设置mvc默认语言为zh_CN,默认语言必须为static.i18n目录下有的语言配置文件,否则跟随服务器语言
# (重要!)设置mvc默认语言为zh_CN,默认语言必须为static.i18n目录下有的语言配置文件,否则跟随服务器语言
mvc
:
mvc
:
...
...
customer-service/src/main/resources/com/ym/im/mapper/ChatRecordMapper.xml
View file @
6cab69bf
...
@@ -200,5 +200,16 @@
...
@@ -200,5 +200,16 @@
</trim>
</trim>
</select>
</select>
<select
id=
"getLatestRecord"
resultType=
"com.ym.im.entity.ChatRecord"
>
SELECT
<include
refid=
"Base_Column_List"
/>
FROM chat_record_${index}
where
user_id = #{userId}
and merchant_id = #{merchantId}
order by send_time desc
limit 1
</select>
</mapper>
</mapper>
pom.xml
View file @
6cab69bf
...
@@ -72,7 +72,6 @@
...
@@ -72,7 +72,6 @@
<module>
api-system
</module>
<module>
api-system
</module>
<module>
api-app
</module>
<module>
api-app
</module>
<module>
api-merchant
</module>
<module>
api-merchant
</module>
<module>
customer-service
</module>
</modules>
</modules>
<dependencyManagement>
<dependencyManagement>
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment