im
This commit is contained in:
@@ -51,7 +51,10 @@
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-websocket</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
|
||||
@@ -68,6 +68,12 @@ public class AuthUser implements Serializable {
|
||||
*/
|
||||
private Boolean isSuper = false;
|
||||
|
||||
/**
|
||||
* 租户id
|
||||
*/
|
||||
private String tenantId;
|
||||
|
||||
|
||||
public AuthUser(String username, String id, String nickName, String face, UserEnums role) {
|
||||
this.username = username;
|
||||
this.face = face;
|
||||
|
||||
@@ -14,7 +14,8 @@ public enum UserEnums {
|
||||
MEMBER("会员"),
|
||||
STORE("商家"),
|
||||
MANAGER("管理员"),
|
||||
SYSTEM("系统");
|
||||
SYSTEM("系统"),
|
||||
SEAT("坐席");
|
||||
private final String role;
|
||||
|
||||
UserEnums(String role) {
|
||||
|
||||
@@ -95,6 +95,19 @@ public class Swagger2Config {
|
||||
.securityContexts(securityContexts());
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Docket imRestApi() {
|
||||
return new Docket(DocumentationType.SWAGGER_2)
|
||||
.groupName("im")
|
||||
.apiInfo(apiInfo()).select()
|
||||
//扫描所有有注解的api,用这种方式更灵活
|
||||
.apis(RequestHandlerSelectors.basePackage("cn.lili.controller.im"))
|
||||
.paths(PathSelectors.any())
|
||||
.build()
|
||||
.securitySchemes(securitySchemes())
|
||||
.securityContexts(securityContexts());
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Docket memberRestApi() {
|
||||
return new Docket(DocumentationType.SWAGGER_2)
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
package cn.lili.im.entity;
|
||||
|
||||
|
||||
import cn.lili.mybatis.BaseTenantEntity;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @author Chopper
|
||||
*/
|
||||
@Data
|
||||
@TableName("li_im_users")
|
||||
@ApiModel(value = "Im消息")
|
||||
public class ImUser extends BaseTenantEntity {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
/**
|
||||
* 头像
|
||||
*/
|
||||
private String face;
|
||||
/**
|
||||
* 昵称
|
||||
*/
|
||||
private String name;
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
package cn.lili.im.mapper;
|
||||
|
||||
import cn.lili.im.entity.ImUser;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
|
||||
/**
|
||||
* Im消息 Dao层
|
||||
*
|
||||
* @author Chopper
|
||||
*/
|
||||
public interface ImUserMapper extends BaseMapper<ImUser> {
|
||||
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
package cn.lili.im.service;
|
||||
|
||||
import cn.lili.im.entity.ImUser;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
/**
|
||||
* Im消息 业务层
|
||||
*
|
||||
* @author Chopper
|
||||
*/
|
||||
public interface ImUserService extends IService<ImUser> {
|
||||
|
||||
/**
|
||||
* 注册用户
|
||||
*
|
||||
* @param accessToken
|
||||
* @return
|
||||
*/
|
||||
ImUser register(String accessToken);
|
||||
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
package cn.lili.im.serviceimpl;
|
||||
|
||||
import cn.lili.common.security.AuthUser;
|
||||
import cn.lili.common.security.context.UserContext;
|
||||
import cn.lili.im.entity.ImUser;
|
||||
import cn.lili.im.mapper.ImUserMapper;
|
||||
import cn.lili.im.service.ImUserService;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
/**
|
||||
* Im消息 业务实现
|
||||
*
|
||||
* @author Chopper
|
||||
*/
|
||||
@Service
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
|
||||
public class ImUserServiceImpl extends ServiceImpl<ImUserMapper, ImUser> implements ImUserService {
|
||||
|
||||
@Override
|
||||
public ImUser register(String accessToken) {
|
||||
AuthUser authUser = UserContext.getAuthUser(accessToken);
|
||||
ImUser imUser;
|
||||
//如果用户存在
|
||||
imUser = this.getById(authUser.getId());
|
||||
if (imUser == null) {
|
||||
imUser = new ImUser();
|
||||
imUser.setId(authUser.getId());
|
||||
imUser.setName(authUser.getNickName());
|
||||
this.save(imUser);
|
||||
}
|
||||
return imUser;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package cn.lili.im.config;
|
||||
package cn.lili.modules.im.config;
|
||||
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
@@ -1,4 +1,4 @@
|
||||
package cn.lili.im.config;
|
||||
package cn.lili.modules.im.config;
|
||||
|
||||
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
|
||||
@@ -1,6 +1,6 @@
|
||||
package cn.lili.im.entity;
|
||||
package cn.lili.modules.im.entity.dos;
|
||||
|
||||
import cn.lili.im.entity.enums.MessageType;
|
||||
import cn.lili.modules.im.entity.enums.MessageTypeEnum;
|
||||
import cn.lili.mybatis.BaseEntity;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
@@ -34,7 +34,7 @@ public class ImMessage extends BaseEntity {
|
||||
/**
|
||||
* 消息类型
|
||||
*/
|
||||
private MessageType messageType;
|
||||
private MessageTypeEnum messageType;
|
||||
|
||||
/**
|
||||
* 聊天id
|
||||
@@ -1,4 +1,4 @@
|
||||
package cn.lili.im.entity;
|
||||
package cn.lili.modules.im.entity.dos;
|
||||
|
||||
|
||||
import cn.lili.common.utils.SnowFlake;
|
||||
@@ -0,0 +1,31 @@
|
||||
package cn.lili.modules.im.entity.dos;
|
||||
|
||||
import cn.lili.mybatis.BaseEntity;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* 问题答案
|
||||
*
|
||||
* @author Chopper
|
||||
* @version v1.0
|
||||
* 2022-02-09 17:59
|
||||
*/
|
||||
@Data
|
||||
@TableName("li_qa")
|
||||
@ApiModel(value = "租户问答")
|
||||
@NoArgsConstructor
|
||||
public class QA extends BaseEntity {
|
||||
|
||||
@ApiModelProperty(value = "租户id")
|
||||
private Integer tenantId;
|
||||
|
||||
@ApiModelProperty(value = "问题")
|
||||
private String question;
|
||||
|
||||
@ApiModelProperty(value = "答案")
|
||||
private String answer;
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package cn.lili.modules.im.entity.dos;
|
||||
|
||||
import cn.lili.mybatis.BaseTenantEntity;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
|
||||
/**
|
||||
* 坐席
|
||||
*
|
||||
* @author Chopper
|
||||
* @version v1.0
|
||||
* 2022-02-09 17:08
|
||||
*/
|
||||
@Data
|
||||
@TableName("li_seat")
|
||||
@ApiModel(value = "坐席")
|
||||
@NoArgsConstructor
|
||||
public class Seat extends BaseTenantEntity {
|
||||
|
||||
@ApiModelProperty(value = "租户id")
|
||||
private String tenantId;
|
||||
|
||||
@ApiModelProperty(value = "坐席用户名")
|
||||
private String username;
|
||||
|
||||
@ApiModelProperty(value = "会员头像")
|
||||
private String face;
|
||||
|
||||
@ApiModelProperty(value = "坐席密码")
|
||||
private String password;
|
||||
|
||||
@ApiModelProperty(value = "昵称")
|
||||
private String nickName;
|
||||
|
||||
@ApiModelProperty(value = "坐席状态")
|
||||
private Boolean disabled;
|
||||
|
||||
@NotEmpty(message = "手机号码不能为空")
|
||||
@ApiModelProperty(value = "手机号码", required = true)
|
||||
private String mobile;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package cn.lili.modules.im.entity.dos;
|
||||
|
||||
import cn.lili.mybatis.BaseTenantEntity;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* 坐席设置
|
||||
*
|
||||
* @author Chopper
|
||||
* @version v1.0
|
||||
* 2022-02-09 17:55
|
||||
*/
|
||||
@Data
|
||||
@TableName("li_seat_setting")
|
||||
@ApiModel(value = "坐席设置")
|
||||
@NoArgsConstructor
|
||||
public class SeatSetting extends BaseTenantEntity {
|
||||
|
||||
@ApiModelProperty(value = "租户idid")
|
||||
private String tenantId;
|
||||
|
||||
@ApiModelProperty(value = "欢迎语")
|
||||
private String welcome;
|
||||
|
||||
@ApiModelProperty(value = "离线自动回复")
|
||||
private String outLineAutoReply;
|
||||
|
||||
@ApiModelProperty(value = "长时间自动回复")
|
||||
private String longTermAutoReply;
|
||||
|
||||
|
||||
}
|
||||
@@ -1,9 +1,9 @@
|
||||
package cn.lili.im.entity.dto;
|
||||
package cn.lili.modules.im.entity.dto;
|
||||
|
||||
import cn.lili.common.enums.ResultCode;
|
||||
import cn.lili.common.exception.ServiceException;
|
||||
import cn.lili.common.utils.StringUtils;
|
||||
import cn.lili.im.entity.ImMessage;
|
||||
import cn.lili.modules.im.entity.dos.ImMessage;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import lombok.Data;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package cn.lili.im.entity.enums;
|
||||
package cn.lili.modules.im.entity.enums;
|
||||
|
||||
/**
|
||||
* 返回消息类型枚举
|
||||
@@ -0,0 +1,31 @@
|
||||
package cn.lili.modules.im.entity.enums;
|
||||
|
||||
/**
|
||||
* 消息的类型
|
||||
*
|
||||
* @author liushuai(liushuai711 @ gmail.com)
|
||||
* @version v4.0
|
||||
* @Description:
|
||||
* @since 2022/2/10 16:36
|
||||
*/
|
||||
public enum MessageStatusEnum {
|
||||
//socket刚打开时发送的消息,这个一般是是刚打开socket链接,进行登录,传入token用
|
||||
CONNECT,
|
||||
//心跳类型的消息,此种类型的消息只有 type 、 text 两种属性
|
||||
HEARTBEAT,
|
||||
//用户打开一个对话框,准备跟某人聊天时
|
||||
OPEN,
|
||||
//客服进行自动回复。客户端发起这种类型请求,则是在拉取对方是否有自动回复,如果有,服务端就会给客户端发送过自动回复的信息
|
||||
AUTO_REPLY,
|
||||
//正常收发消息沟通,文字、表情等沟通
|
||||
MSG,
|
||||
//扩展。比如发送商品、发送订单
|
||||
EXTEND,
|
||||
//系统提示,如提示 对方已离线
|
||||
SYSTEM,
|
||||
//服务端发送到客户端,用于设置客户端的用户信息。会吧 com.xnx3.yunkefu.core.vo.bean.User 传过去
|
||||
SET_USER,
|
||||
//结束服务
|
||||
CLOSE_SERVICE;
|
||||
|
||||
}
|
||||
@@ -1,11 +1,11 @@
|
||||
package cn.lili.im.entity.enums;
|
||||
package cn.lili.modules.im.entity.enums;
|
||||
|
||||
/**
|
||||
* 消息类型
|
||||
*
|
||||
* @author liushuai
|
||||
*/
|
||||
public enum MessageType {
|
||||
public enum MessageTypeEnum {
|
||||
/**
|
||||
* 消息类型枚举
|
||||
* <p>
|
||||
@@ -0,0 +1,14 @@
|
||||
package cn.lili.modules.im.entity.enums;
|
||||
|
||||
/**
|
||||
* 坐席在线状态
|
||||
*
|
||||
* @author Chopper
|
||||
* @version v1.0
|
||||
* 2022-02-10 16:37
|
||||
*/
|
||||
public enum OnlineStatusEnum {
|
||||
// 在线/下线
|
||||
ONLINE,
|
||||
OUTLINE;
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package cn.lili.im.entity.enums;
|
||||
package cn.lili.modules.im.entity.enums;
|
||||
|
||||
/**
|
||||
* 操作类型枚举
|
||||
@@ -1,6 +1,6 @@
|
||||
package cn.lili.im.entity.vo;
|
||||
package cn.lili.modules.im.entity.vo;
|
||||
|
||||
import cn.lili.im.entity.ImTalk;
|
||||
import cn.lili.modules.im.entity.dos.ImTalk;
|
||||
import cn.lili.mybatis.BaseTenantEntity;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
@@ -1,8 +1,8 @@
|
||||
package cn.lili.im.entity.vo;
|
||||
package cn.lili.modules.im.entity.vo;
|
||||
|
||||
import cn.lili.common.utils.StringUtils;
|
||||
import cn.lili.im.entity.enums.MessageType;
|
||||
import cn.lili.im.entity.enums.OperationType;
|
||||
import cn.lili.modules.im.entity.enums.MessageTypeEnum;
|
||||
import cn.lili.modules.im.entity.enums.OperationType;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
@@ -20,6 +20,11 @@ public class MessageOperation {
|
||||
*/
|
||||
private String to;
|
||||
|
||||
/**
|
||||
* 发送者
|
||||
*/
|
||||
private String from;
|
||||
|
||||
/**
|
||||
* 聊天id
|
||||
*/
|
||||
@@ -28,7 +33,7 @@ public class MessageOperation {
|
||||
/**
|
||||
* 消息类型
|
||||
*/
|
||||
private MessageType messageType;
|
||||
private MessageTypeEnum messageType;
|
||||
/**
|
||||
* 消息内容
|
||||
*/
|
||||
@@ -42,7 +47,7 @@ public class MessageOperation {
|
||||
|
||||
public void setMessageType(String messageType) {
|
||||
if (!StringUtils.isEmpty(messageType)) {
|
||||
this.messageType = MessageType.valueOf(messageType);
|
||||
this.messageType = MessageTypeEnum.valueOf(messageType);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
package cn.lili.im.entity.vo;
|
||||
package cn.lili.modules.im.entity.vo;
|
||||
|
||||
import cn.lili.im.entity.enums.MessageResultType;
|
||||
import cn.lili.modules.im.entity.enums.MessageResultType;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package cn.lili.im.entity.vo;
|
||||
package cn.lili.modules.im.entity.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
package cn.lili.modules.im.entity.vo;
|
||||
|
||||
import cn.lili.modules.im.entity.dos.Seat;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 客服VO
|
||||
*
|
||||
* @author Chopper
|
||||
* @version v1.0
|
||||
* 2022-02-10 15:02
|
||||
*/
|
||||
@Data
|
||||
public class SeatVO extends Seat {
|
||||
|
||||
/**
|
||||
* 在线状态
|
||||
*/
|
||||
private String onlineStatus;
|
||||
|
||||
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
package cn.lili.im.mapper;
|
||||
package cn.lili.modules.im.mapper;
|
||||
|
||||
import cn.lili.im.entity.ImMessage;
|
||||
import cn.lili.modules.im.entity.dos.ImMessage;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
|
||||
/**
|
||||
@@ -1,6 +1,6 @@
|
||||
package cn.lili.im.mapper;
|
||||
package cn.lili.modules.im.mapper;
|
||||
|
||||
import cn.lili.im.entity.ImTalk;
|
||||
import cn.lili.modules.im.entity.dos.ImTalk;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
|
||||
/**
|
||||
@@ -0,0 +1,16 @@
|
||||
package cn.lili.modules.im.mapper;
|
||||
|
||||
|
||||
import cn.lili.modules.im.entity.dos.QA;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
|
||||
/**
|
||||
* 问答处理层
|
||||
*
|
||||
* @author pikachu
|
||||
* @since 2020-02-18 15:18:56
|
||||
*/
|
||||
public interface QAMapper extends BaseMapper<QA> {
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package cn.lili.modules.im.mapper;
|
||||
|
||||
|
||||
import cn.lili.modules.im.entity.dos.Seat;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
|
||||
/**
|
||||
* 坐席处理层
|
||||
*
|
||||
* @author pikachu
|
||||
* @since 2020-02-18 15:18:56
|
||||
*/
|
||||
public interface SeatMapper extends BaseMapper<Seat> {
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package cn.lili.modules.im.mapper;
|
||||
|
||||
|
||||
import cn.lili.modules.im.entity.dos.SeatSetting;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
|
||||
/**
|
||||
* 坐席设置处理层
|
||||
*
|
||||
* @author pikachu
|
||||
* @since 2020-02-18 15:18:56
|
||||
*/
|
||||
public interface SeatSettingMapper extends BaseMapper<SeatSetting> {
|
||||
|
||||
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
package cn.lili.im.service;
|
||||
package cn.lili.modules.im.service;
|
||||
|
||||
import cn.lili.im.entity.ImMessage;
|
||||
import cn.lili.modules.im.entity.dos.ImMessage;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
import java.util.List;
|
||||
@@ -1,6 +1,6 @@
|
||||
package cn.lili.im.service;
|
||||
package cn.lili.modules.im.service;
|
||||
|
||||
import cn.lili.im.entity.ImTalk;
|
||||
import cn.lili.modules.im.entity.dos.ImTalk;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
/**
|
||||
@@ -0,0 +1,25 @@
|
||||
package cn.lili.modules.im.service;
|
||||
|
||||
|
||||
import cn.lili.common.vo.PageVO;
|
||||
import cn.lili.modules.im.entity.dos.QA;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
/**
|
||||
* 问答
|
||||
*
|
||||
* @author pikachu
|
||||
* @since 2020-02-18 16:18:56
|
||||
*/
|
||||
public interface QAService extends IService<QA> {
|
||||
|
||||
/**
|
||||
* 查询店铺问题
|
||||
* @param word
|
||||
* @param pageVO
|
||||
* @return
|
||||
*/
|
||||
IPage<QA> getStoreQA(String word, PageVO pageVO);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
package cn.lili.modules.im.service;
|
||||
|
||||
|
||||
import cn.lili.common.security.token.Token;
|
||||
import cn.lili.modules.im.entity.dos.Seat;
|
||||
import cn.lili.modules.im.entity.vo.SeatVO;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 坐席业务
|
||||
*
|
||||
* @author pikachu
|
||||
* @since 2020-02-18 16:18:56
|
||||
*/
|
||||
public interface SeatService extends IService<Seat> {
|
||||
|
||||
|
||||
/**
|
||||
* 获取坐席列表
|
||||
*
|
||||
* @param storeId 店铺id
|
||||
* @return
|
||||
*/
|
||||
List<SeatVO> seatVoList(String storeId);
|
||||
|
||||
/**
|
||||
* 坐席登录
|
||||
*
|
||||
* @param username
|
||||
* @param password
|
||||
* @return
|
||||
*/
|
||||
Token usernameLogin(String username, String password);
|
||||
|
||||
/**
|
||||
* 快捷登录code 生成
|
||||
*
|
||||
* @param username 用户名
|
||||
* @return
|
||||
*/
|
||||
String createQuickLoginCode(String username);
|
||||
|
||||
/**
|
||||
* 快捷登录
|
||||
*
|
||||
* @param code
|
||||
* @return
|
||||
*/
|
||||
Token quickLogin(String code);
|
||||
|
||||
/**
|
||||
* 查询坐席
|
||||
*
|
||||
* @param username
|
||||
* @return
|
||||
*/
|
||||
Seat findByUsername(String username);
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package cn.lili.modules.im.service;
|
||||
|
||||
import cn.lili.modules.im.entity.dos.SeatSetting;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
/**
|
||||
* 坐席设置业务
|
||||
*
|
||||
* @author pikachu
|
||||
* @since 2020-02-18 16:18:56
|
||||
*/
|
||||
public interface SeatSettingService extends IService<SeatSetting> {
|
||||
|
||||
|
||||
/**
|
||||
* 根据店铺id获取坐席配置
|
||||
*
|
||||
* @param storeId
|
||||
* @return
|
||||
*/
|
||||
SeatSetting getSetting(String storeId);
|
||||
|
||||
/**
|
||||
* 根据店铺修改坐席设置
|
||||
*
|
||||
* @param seatSetting 坐席设置
|
||||
* @return
|
||||
*/
|
||||
SeatSetting updateByStore(SeatSetting seatSetting);
|
||||
}
|
||||
@@ -1,10 +1,10 @@
|
||||
package cn.lili.im.serviceimpl;
|
||||
package cn.lili.modules.im.serviceimpl;
|
||||
|
||||
import cn.lili.common.security.context.UserContext;
|
||||
import cn.lili.im.entity.ImMessage;
|
||||
import cn.lili.im.mapper.ImMessageMapper;
|
||||
import cn.lili.im.service.ImMessageService;
|
||||
import cn.lili.im.service.ImTalkService;
|
||||
import cn.lili.modules.im.entity.dos.ImMessage;
|
||||
import cn.lili.modules.im.mapper.ImMessageMapper;
|
||||
import cn.lili.modules.im.service.ImMessageService;
|
||||
import cn.lili.modules.im.service.ImTalkService;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
@@ -1,19 +1,22 @@
|
||||
package cn.lili.im.serviceimpl;
|
||||
package cn.lili.modules.im.serviceimpl;
|
||||
|
||||
import cn.lili.common.enums.ResultCode;
|
||||
import cn.lili.common.exception.ServiceException;
|
||||
import cn.lili.common.security.context.UserContext;
|
||||
import cn.lili.im.entity.ImTalk;
|
||||
import cn.lili.im.entity.ImUser;
|
||||
import cn.lili.im.mapper.ImTalkMapper;
|
||||
import cn.lili.im.service.ImTalkService;
|
||||
import cn.lili.im.service.ImUserService;
|
||||
import cn.lili.modules.im.entity.dos.ImTalk;
|
||||
import cn.lili.modules.im.mapper.ImTalkMapper;
|
||||
import cn.lili.modules.im.service.ImTalkService;
|
||||
import cn.lili.modules.member.entity.dos.Member;
|
||||
import cn.lili.modules.member.service.MemberService;
|
||||
import cn.lili.modules.store.entity.dos.Store;
|
||||
import cn.lili.modules.store.service.StoreService;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.stringtemplate.v4.ST;
|
||||
|
||||
/**
|
||||
* 聊天 业务实现
|
||||
@@ -26,7 +29,10 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
public class ImTalkServiceImpl extends ServiceImpl<ImTalkMapper, ImTalk> implements ImTalkService {
|
||||
|
||||
@Autowired
|
||||
private ImUserService imUserService;
|
||||
private MemberService memberService;
|
||||
|
||||
@Autowired
|
||||
private StoreService storeService;
|
||||
|
||||
@Override
|
||||
public ImTalk getTalkByUser(String userId1, String userId2) {
|
||||
@@ -34,15 +40,34 @@ public class ImTalkServiceImpl extends ServiceImpl<ImTalkMapper, ImTalk> impleme
|
||||
queryWrapper.eq(ImTalk::getUserId2, userId2);
|
||||
queryWrapper.eq(ImTalk::getUserId1, userId1);
|
||||
ImTalk imTalk = this.getOne(queryWrapper);
|
||||
ImUser imUser1 = imUserService.getById(userId1);
|
||||
ImUser imUser2 = imUserService.getById(userId2);
|
||||
Member self = memberService.getById(userId1);
|
||||
Store selfStore = storeService.getById(userId1);
|
||||
|
||||
|
||||
//如果没有聊天,则创建聊天
|
||||
if (imTalk == null) {
|
||||
if (imUser1 == null || imUser2 == null) {
|
||||
// 没有登录的这个账户信息
|
||||
if (self == null && selfStore ==null) {
|
||||
return null;
|
||||
}
|
||||
imTalk = new ImTalk(userId1, userId2, imUser1.getFace(), imUser2.getFace(), imUser1.getName(), imUser2.getName());
|
||||
//当自己为店铺时
|
||||
if(selfStore != null){
|
||||
//没有这个用户信息
|
||||
Member other = memberService.getById(userId2);
|
||||
if(other == null){
|
||||
return null;
|
||||
}
|
||||
//自己为店铺其他人必定为用户
|
||||
imTalk = new ImTalk(userId1, userId2, selfStore.getStoreLogo(), other.getFace(), selfStore.getStoreName(), other.getNickName());
|
||||
}else if(self != null){
|
||||
//没有这个店铺信息
|
||||
Store otherStore = storeService.getById(userId2);
|
||||
if(otherStore == null){
|
||||
return null;
|
||||
}
|
||||
//当自己为用户时 其他人必定为店铺
|
||||
imTalk = new ImTalk(userId1, userId2, self.getFace(), otherStore.getStoreLogo(), self.getNickName(), otherStore.getStoreName());
|
||||
}
|
||||
this.save(imTalk);
|
||||
} else {
|
||||
imTalk = check(imTalk);
|
||||
@@ -0,0 +1,32 @@
|
||||
package cn.lili.modules.im.serviceimpl;
|
||||
|
||||
import cn.lili.common.security.context.UserContext;
|
||||
import cn.lili.common.vo.PageVO;
|
||||
import cn.lili.modules.im.entity.dos.QA;
|
||||
import cn.lili.modules.im.mapper.QAMapper;
|
||||
import cn.lili.modules.im.service.QAService;
|
||||
import cn.lili.mybatis.util.PageUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
/**
|
||||
* 坐席业务层实现
|
||||
*
|
||||
* @author pikachu
|
||||
* @since 2020-02-18 16:18:56
|
||||
*/
|
||||
@Service
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public class QAServiceImpl extends ServiceImpl<QAMapper, QA> implements QAService {
|
||||
|
||||
@Override
|
||||
public IPage<QA> getStoreQA(String word, PageVO pageVo) {
|
||||
LambdaQueryWrapper<QA> qaLambdaQueryWrapper = new LambdaQueryWrapper<>();
|
||||
qaLambdaQueryWrapper.eq(QA::getTenantId, UserContext.getCurrentUser().getTenantId());
|
||||
qaLambdaQueryWrapper.like(QA::getQuestion, word);
|
||||
return this.page(PageUtil.initPage(pageVo), qaLambdaQueryWrapper);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
package cn.lili.modules.im.serviceimpl;
|
||||
|
||||
import cn.lili.cache.Cache;
|
||||
import cn.lili.common.enums.ResultCode;
|
||||
import cn.lili.common.exception.ServiceException;
|
||||
import cn.lili.common.security.token.Token;
|
||||
import cn.lili.common.utils.StringUtils;
|
||||
import cn.lili.modules.im.entity.dos.Seat;
|
||||
import cn.lili.modules.im.entity.enums.OnlineStatusEnum;
|
||||
import cn.lili.modules.im.entity.vo.SeatVO;
|
||||
import cn.lili.modules.im.mapper.SeatMapper;
|
||||
import cn.lili.modules.im.service.SeatService;
|
||||
import cn.lili.modules.im.token.SeatTokenGenerate;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 坐席业务层实现
|
||||
*
|
||||
* @author pikachu
|
||||
* @since 2020-02-18 16:18:56
|
||||
*/
|
||||
@Service
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public class SeatServiceImpl extends ServiceImpl<SeatMapper, Seat> implements SeatService {
|
||||
|
||||
|
||||
@Autowired
|
||||
private SeatTokenGenerate seatTokenGenerate;
|
||||
|
||||
@Autowired
|
||||
private Cache<String> cache;
|
||||
|
||||
/**
|
||||
* 快捷登录缓存前缀
|
||||
*/
|
||||
private static String prefix = "{quick_login}_";
|
||||
|
||||
|
||||
@Override
|
||||
public List<SeatVO> seatVoList(String storeId) {
|
||||
|
||||
LambdaQueryWrapper<Seat> seatLambdaQueryWrapper = new LambdaQueryWrapper<>();
|
||||
seatLambdaQueryWrapper.eq(Seat::getTenantId, storeId);
|
||||
List<Seat> list = this.list(seatLambdaQueryWrapper);
|
||||
|
||||
//转换模型为VO
|
||||
List<SeatVO> results = list.stream().map(item -> (SeatVO) item).collect(Collectors.toList());
|
||||
//填充坐席当前状态
|
||||
//todo
|
||||
results.forEach(item -> {
|
||||
item.setOnlineStatus(OnlineStatusEnum.ONLINE.name());
|
||||
});
|
||||
return results;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Token usernameLogin(String username, String password) {
|
||||
|
||||
Seat seat = this.findByUsername(username);
|
||||
//判断用户是否存在
|
||||
if (seat == null || !seat.getDisabled()) {
|
||||
throw new ServiceException(ResultCode.ERROR);
|
||||
}
|
||||
//判断密码是否输入正确
|
||||
if (!new BCryptPasswordEncoder().matches(password, seat.getPassword())) {
|
||||
throw new ServiceException(ResultCode.ERROR);
|
||||
}
|
||||
return seatTokenGenerate.createToken(seat, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String createQuickLoginCode(String username) {
|
||||
String code = UUID.randomUUID().toString();
|
||||
cache.put(prefix + code, username, 20L);
|
||||
return code;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Token quickLogin(String code) {
|
||||
String username = cache.get(prefix + code);
|
||||
cache.remove(prefix + code);
|
||||
if (StringUtils.isEmpty(username)) {
|
||||
throw new ServiceException(ResultCode.ERROR);
|
||||
}
|
||||
return seatTokenGenerate.createToken(findByUsername(username), true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询坐席
|
||||
*
|
||||
* @param username
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public Seat findByUsername(String username) {
|
||||
LambdaQueryWrapper<Seat> seatLambdaQueryWrapper = new LambdaQueryWrapper<>();
|
||||
seatLambdaQueryWrapper.eq(Seat::getUsername, username);
|
||||
return this.getOne(seatLambdaQueryWrapper);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package cn.lili.modules.im.serviceimpl;
|
||||
|
||||
import cn.lili.common.enums.ResultCode;
|
||||
import cn.lili.common.exception.ServiceException;
|
||||
import cn.lili.modules.im.entity.dos.SeatSetting;
|
||||
import cn.lili.modules.im.mapper.SeatSettingMapper;
|
||||
import cn.lili.modules.im.service.SeatSettingService;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
/**
|
||||
* 坐席设置业务层实现
|
||||
*
|
||||
* @author pikachu
|
||||
* @since 2020-02-18 16:18:56
|
||||
*/
|
||||
@Service
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public class SeatSettingServiceImpl extends ServiceImpl<SeatSettingMapper, SeatSetting> implements SeatSettingService {
|
||||
@Override
|
||||
public SeatSetting getSetting(String storeId) {
|
||||
LambdaQueryWrapper<SeatSetting> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(SeatSetting::getTenantId, storeId);
|
||||
SeatSetting seatSetting = this.baseMapper.selectOne(queryWrapper);
|
||||
if (seatSetting == null) {
|
||||
seatSetting = new SeatSetting();
|
||||
seatSetting.setOutLineAutoReply("您好,我现在不在线,请您留下关键内容和联系方式,我看到后会立马回电。");
|
||||
seatSetting.setLongTermAutoReply("您好,我正在查阅相关资料,请您稍等。");
|
||||
seatSetting.setWelcome("您好,请问有什么可以帮您?");
|
||||
seatSetting.setTenantId(storeId);
|
||||
this.save(seatSetting);
|
||||
}
|
||||
return seatSetting;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SeatSetting updateByStore(SeatSetting seatSetting) {
|
||||
SeatSetting oldSetting = this.baseMapper.selectById(seatSetting.getId());
|
||||
if (oldSetting.getTenantId().equals(seatSetting.getTenantId())) {
|
||||
this.updateById(seatSetting);
|
||||
} else {
|
||||
throw new ServiceException(ResultCode.ERROR);
|
||||
}
|
||||
return seatSetting;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package cn.lili.modules.im.token;
|
||||
|
||||
import cn.lili.common.security.AuthUser;
|
||||
import cn.lili.common.security.enums.UserEnums;
|
||||
import cn.lili.common.security.token.Token;
|
||||
import cn.lili.common.security.token.TokenUtil;
|
||||
import cn.lili.common.security.token.base.AbstractTokenGenerate;
|
||||
import cn.lili.modules.im.entity.dos.Seat;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* 会员token生成
|
||||
*
|
||||
* @author Chopper
|
||||
* @version v4.0
|
||||
* @since 2020/11/16 10:50
|
||||
*/
|
||||
@Component
|
||||
public class SeatTokenGenerate extends AbstractTokenGenerate<Seat> {
|
||||
@Autowired
|
||||
private TokenUtil tokenUtil;
|
||||
|
||||
@Override
|
||||
public Token createToken(Seat seat, Boolean longTerm) {
|
||||
AuthUser authUser = new AuthUser(
|
||||
seat.getUsername(),
|
||||
seat.getId(),
|
||||
seat.getNickName(),
|
||||
seat.getFace(),
|
||||
UserEnums.SEAT);
|
||||
authUser.setTenantId(seat.getTenantId());
|
||||
//登陆成功生成token
|
||||
return tokenUtil.createToken(seat.getUsername(), authUser, longTerm, UserEnums.SEAT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Token refreshToken(String refreshToken) {
|
||||
return tokenUtil.refreshToken(refreshToken, UserEnums.SEAT);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user