This commit is contained in:
chc
2022-11-23 18:44:54 +08:00
parent fc71d2d1ca
commit 49b517f1ab
58 changed files with 1775 additions and 148 deletions

View File

@@ -0,0 +1,31 @@
package cn.lili;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
/**
* @author liushuai
*/
@SpringBootApplication
public class ImApiApplication {
public static void main(String[] args) {
SpringApplication.run(ImApiApplication.class, args);
}
/**
* 如果使用独立的servlet容器
* 而不是直接使用springboot的内置容器
* 就不要注入ServerEndpointExporter
* 因为它将由容器自己提供和管理
*
* @return
*/
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
}

View File

@@ -0,0 +1,175 @@
package cn.lili.controller.im;
import cn.lili.common.enums.ResultCode;
import cn.lili.common.enums.ResultUtil;
import cn.lili.common.exception.ServiceException;
import cn.lili.common.security.AuthUser;
import cn.lili.common.security.context.UserContext;
import cn.lili.common.security.enums.UserEnums;
import cn.lili.common.security.token.Token;
import cn.lili.common.utils.StringUtils;
import cn.lili.common.vo.PageVO;
import cn.lili.common.vo.ResultMessage;
import cn.lili.common.vo.SearchVO;
import cn.lili.modules.permission.entity.dos.AdminUser;
import cn.lili.modules.permission.entity.dto.AdminUserDTO;
import cn.lili.modules.permission.entity.vo.AdminUserVO;
import cn.lili.modules.permission.service.AdminUserService;
import cn.lili.modules.permission.service.DepartmentService;
import cn.lili.mybatis.util.PageUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import java.util.List;
@Slf4j
@RestController
@Api(tags = "管理员")
@RequestMapping("/manager/im/passport/user")
@Validated
public class ImManagerController {
@Autowired
private AdminUserService adminUserService;
@Autowired
private DepartmentService departmentService;
@PostMapping(value = "/login")
@ApiOperation(value = "登录管理员")
public ResultMessage<Token> login(@NotNull(message = "用户名不能为空") String username,
@NotNull(message = "密码不能为空") String password) {
return ResultUtil.data(adminUserService.login(username, password));
}
@ApiOperation(value = "注销接口")
@PostMapping("/logout")
public ResultMessage<Object> logout() {
this.adminUserService.logout(UserEnums.MANAGER);
return ResultUtil.success();
}
@ApiOperation(value = "刷新token")
@GetMapping("/refresh/{refreshToken}")
public ResultMessage<Object> refreshToken(@NotNull(message = "刷新token不能为空") @PathVariable String refreshToken) {
return ResultUtil.data(this.adminUserService.refreshToken(refreshToken));
}
@GetMapping(value = "/info")
@ApiOperation(value = "获取当前登录用户接口")
public ResultMessage<AdminUserVO> getUserInfo() {
AuthUser tokenUser = UserContext.getCurrentUser();
if (tokenUser != null) {
AdminUserVO adminUser = new AdminUserVO(adminUserService.findByUsername(tokenUser.getUsername()));
if (StringUtils.isNotEmpty(adminUser.getDepartmentId())) {
adminUser.setDepartmentTitle(departmentService.getById(adminUser.getDepartmentId()).getTitle());
}
adminUser.setPassword(null);
return ResultUtil.data(adminUser);
}
throw new ServiceException(ResultCode.USER_NOT_LOGIN);
}
@PutMapping(value = "/edit")
@ApiOperation(value = "修改用户自己资料", notes = "用户名密码不会修改")
public ResultMessage<Object> editOwner(AdminUser adminUser) {
AuthUser tokenUser = UserContext.getCurrentUser();
if (tokenUser != null) {
//查询当前管理员
AdminUser oldAdminUser = adminUserService.findByUsername(tokenUser.getUsername());
oldAdminUser.setAvatar(adminUser.getAvatar());
oldAdminUser.setNickName(adminUser.getNickName());
if (!adminUserService.updateById(oldAdminUser)) {
throw new ServiceException(ResultCode.USER_EDIT_ERROR);
}
return ResultUtil.success(ResultCode.USER_EDIT_SUCCESS);
}
throw new ServiceException(ResultCode.USER_NOT_LOGIN);
}
@PutMapping(value = "/admin/edit")
@ApiOperation(value = "超级管理员修改其他管理员资料")
public ResultMessage<Object> edit(@Valid AdminUser adminUser,
@RequestParam(required = false) List<String> roles) {
if (!adminUserService.updateAdminUser(adminUser, roles)) {
throw new ServiceException(ResultCode.USER_EDIT_ERROR);
}
return ResultUtil.success(ResultCode.USER_EDIT_SUCCESS);
}
/**
* 修改密码
*
* @param password
* @param newPassword
* @return
*/
@PutMapping(value = "/editPassword")
@ApiOperation(value = "修改密码")
public ResultMessage<Object> editPassword(String password, String newPassword) {
adminUserService.editPassword(password, newPassword);
return ResultUtil.success(ResultCode.USER_EDIT_SUCCESS);
}
@PostMapping(value = "/resetPassword/{ids}")
@ApiOperation(value = "重置密码")
public ResultMessage<Object> resetPassword(@PathVariable List ids) {
adminUserService.resetPassword(ids);
return ResultUtil.success(ResultCode.USER_EDIT_SUCCESS);
}
@GetMapping
@ApiOperation(value = "多条件分页获取用户列表")
public ResultMessage<IPage<AdminUserVO>> getByCondition(AdminUserDTO user,
SearchVO searchVo,
PageVO pageVo) {
IPage<AdminUserVO> page = adminUserService.adminUserPage(PageUtil.initPage(pageVo), PageUtil.initWrapper(user, searchVo));
return ResultUtil.data(page);
}
@PostMapping
@ApiOperation(value = "添加用户")
public ResultMessage<Object> register(@Valid AdminUserDTO adminUser,
@RequestParam(required = false) List<String> roles) {
int rolesMaxSize = 10;
try {
if (roles != null && roles.size() >= rolesMaxSize) {
throw new ServiceException(ResultCode.PERMISSION_BEYOND_TEN);
}
adminUserService.saveAdminUser(adminUser, roles);
} catch (Exception e) {
log.error("添加用户错误", e);
}
return ResultUtil.success();
}
@PutMapping(value = "/enable/{userId}")
@ApiOperation(value = "禁/启 用 用户")
public ResultMessage<Object> disable(@ApiParam("用户唯一id标识") @PathVariable String userId, Boolean status) {
AdminUser user = adminUserService.getById(userId);
if (user == null) {
throw new ServiceException(ResultCode.USER_NOT_EXIST);
}
user.setStatus(status);
adminUserService.updateById(user);
return ResultUtil.success();
}
@DeleteMapping(value = "/{ids}")
@ApiOperation(value = "批量通过ids删除")
public ResultMessage<Object> delAllByIds(@PathVariable List<String> ids) {
adminUserService.deleteCompletely(ids);
return ResultUtil.success();
}
}

View File

@@ -0,0 +1,82 @@
package cn.lili.controller.im;
import cn.lili.common.enums.ResultCode;
import cn.lili.common.enums.ResultUtil;
import cn.lili.common.vo.ResultMessage;
import cn.lili.modules.im.entity.dos.ImMessage;
import cn.lili.modules.im.entity.dto.MessageQueryParams;
import cn.lili.modules.im.service.ImMessageService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* @author Chopper
*/
@RestController
@Api(tags = "Im消息接口")
@RequestMapping("/lili/imMessage")
@Transactional(rollbackFor = Exception.class)
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class ImMessageController {
private final ImMessageService imMessageService;
@GetMapping(value = "/{id}")
@ApiOperation(value = "查看Im消息详情")
public ResultMessage<ImMessage> get(@PathVariable String id) {
ImMessage imMessage = imMessageService.getById(id);
return new ResultUtil<ImMessage>().setData(imMessage);
}
@GetMapping
@ApiOperation(value = "分页获取Im消息")
public ResultMessage<List<ImMessage>> historyMessage(MessageQueryParams messageQueryParams) {
List<ImMessage> data = imMessageService.list(messageQueryParams.initQueryWrapper());
return new ResultUtil<List<ImMessage>>().setData(data);
}
@PostMapping
@ApiOperation(value = "新增Im消息")
public ResultMessage<ImMessage> save(ImMessage imMessage) {
if (imMessageService.save(imMessage)) {
return new ResultUtil<ImMessage>().setData(imMessage);
}
return new ResultUtil<ImMessage>().setErrorMsg(ResultCode.ERROR);
}
@PutMapping("/{id}")
@ApiOperation(value = "更新Im消息")
public ResultMessage<ImMessage> update(@PathVariable String id, ImMessage imMessage) {
if (imMessageService.updateById(imMessage)) {
return new ResultUtil<ImMessage>().setData(imMessage);
}
return new ResultUtil<ImMessage>().setErrorMsg(ResultCode.ERROR);
}
@DeleteMapping(value = "/{ids}")
@ApiOperation(value = "删除Im消息")
public ResultMessage<Object> delAllByIds(@PathVariable List ids) {
imMessageService.removeByIds(ids);
return ResultUtil.success(ResultCode.SUCCESS);
}
@GetMapping(value = "/newMessage")
@ApiOperation(value = "删除Im消息")
public ResultMessage<Boolean> hasNewMessage(String accessToken) {
return ResultUtil.data(imMessageService.hasNewMessage(accessToken));
}
}

View File

@@ -0,0 +1,93 @@
package cn.lili.controller.im;
import cn.lili.common.enums.ResultCode;
import cn.lili.common.enums.ResultUtil;
import cn.lili.common.security.AuthUser;
import cn.lili.common.security.context.UserContext;
import cn.lili.common.vo.ResultMessage;
import cn.lili.modules.im.entity.dos.ImTalk;
import cn.lili.modules.im.entity.vo.ImTalkVO;
import cn.lili.modules.im.service.ImTalkService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.stream.Collectors;
/**
* @author Chopper
*/
@RestController
@Api(tags = "聊天接口")
@RequestMapping("/lili/imTalk")
@Transactional(rollbackFor = Exception.class)
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class ImTalkController {
private final ImTalkService imTalkService;
@GetMapping(value = "/{id}")
@ApiOperation(value = "查看聊天详情")
public ResultMessage<ImTalk> get(@PathVariable String id) {
ImTalk imTalk = imTalkService.getById(id);
return new ResultUtil<ImTalk>().setData(imTalk);
}
@GetMapping(value = "/user/{uid}")
@ApiOperation(value = "查看与某人聊天详情")
public ResultMessage<ImTalk> getUser(@PathVariable String uid) {
AuthUser authUser = UserContext.getCurrentUser();
return ResultUtil.data(imTalkService.getTalkByUser(authUser.getId(), uid));
}
@GetMapping(value = "/top")
@ApiOperation(value = "查看与某人聊天详情")
public ResultMessage top(String id, Boolean top) {
imTalkService.top(id, top);
return ResultUtil.success();
}
@GetMapping("/list")
@ApiOperation(value = "分页获取聊天")
public ResultMessage<List<ImTalkVO>> getByPage() {
AuthUser authUser = UserContext.getCurrentUser();
LambdaQueryWrapper<ImTalk> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(ImTalk::getUserId1, authUser.getId()).or().eq(ImTalk::getUserId2, authUser.getId());
List<ImTalk> imTalks = imTalkService.list(queryWrapper);
List<ImTalkVO> results = imTalks.stream().map(imTalk -> {
return new ImTalkVO(imTalk, authUser.getId());
}).collect(Collectors.toList());
return ResultUtil.data(results);
}
@GetMapping("/store/list")
@ApiOperation(value = "分页获取商家聊天")
public ResultMessage<List<ImTalkVO>> getStoreTalkList() {
AuthUser authUser = UserContext.getCurrentUser();
LambdaQueryWrapper<ImTalk> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(ImTalk::getUserId1, authUser.getStoreId()).or().eq(ImTalk::getUserId2, authUser.getStoreId());
List<ImTalk> imTalks = imTalkService.list(queryWrapper);
List<ImTalkVO> results = imTalks.stream().map(imTalk -> {
return new ImTalkVO(imTalk, authUser.getStoreId());
}).collect(Collectors.toList());
return ResultUtil.data(results);
}
@DeleteMapping(value = "/{id}")
@ApiOperation(value = "删除聊天")
public ResultMessage<Object> disable(@PathVariable String id) {
imTalkService.disable(id);
return ResultUtil.success(ResultCode.SUCCESS);
}
}

View File

@@ -0,0 +1,51 @@
package cn.lili.controller.im;
import cn.lili.common.enums.ResultUtil;
import cn.lili.common.security.AuthUser;
import cn.lili.common.security.context.UserContext;
import cn.lili.common.vo.ResultMessage;
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 io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author Chopper
*/
@RestController
@Api(tags = "Im消息接口")
@RequestMapping("/lili/imUser")
@Transactional(rollbackFor = Exception.class)
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class ImUserController {
private final MemberService memberService;
@Autowired
private StoreService storeService;
@GetMapping
@ApiOperation(value = "获取用户信息")
public ResultMessage<Member> getImUser() {
AuthUser authUser = UserContext.getCurrentUser();
return ResultUtil.data(memberService.getById(authUser.getId()));
}
@GetMapping("/store")
@ApiOperation(value = "获取用户信息")
public ResultMessage<Store> getStoreUser() {
AuthUser authUser = UserContext.getCurrentUser();
return ResultUtil.data(storeService.getById(authUser.getStoreId()));
}
}

View File

@@ -0,0 +1,62 @@
package cn.lili.controller.im;
import cn.lili.common.enums.ResultUtil;
import cn.lili.common.vo.PageVO;
import cn.lili.common.vo.ResultMessage;
import cn.lili.modules.im.entity.dos.QA;
import cn.lili.modules.im.service.QAService;
import com.baomidou.mybatisplus.core.metadata.IPage;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
/**
* 管理端,自定义分词接口
*
* @author paulG
* @since 2020/10/16
**/
@Slf4j
@RestController
@Api(tags = "管理端,自定义分词接口")
@RequestMapping("/store/qa")
public class QAStoreController {
@Autowired
private QAService qaService;
@ApiOperation(value = "添加问答")
@PostMapping
public ResultMessage<QA> addCustomWords(@Valid QA qa) {
qaService.save(qa);
return ResultUtil.data(qa);
}
@ApiOperation(value = "修改自定义问答")
@PutMapping
public ResultMessage<QA> updateCustomWords(@Valid QA qa) {
qaService.updateById(qa);
return ResultUtil.data(qa);
}
@ApiOperation(value = "删除自定义分词")
@DeleteMapping("/{id}")
public ResultMessage<String> deleteCustomWords(@NotNull @PathVariable String id) {
qaService.removeById(id);
return ResultUtil.success();
}
@ApiOperation(value = "分页获取自定义分词")
@ApiImplicitParam(name = "word", value = "问题", required = true, dataType = "String", paramType = "query")
@GetMapping("/page")
public ResultMessage<IPage<QA>> getCustomWords(@RequestParam String word, PageVO pageVo) {
return ResultUtil.data(qaService.getStoreQA(word, pageVo));
}
}

View File

@@ -0,0 +1,59 @@
package cn.lili.controller.im;
import cn.lili.common.enums.ResultUtil;
import cn.lili.common.vo.ResultMessage;
import cn.lili.modules.im.service.SeatService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 坐席登录接口
*
* @author Chopper
* @version v1.0
* 2022-02-10 16:40
*/
@Slf4j
@RestController
@Api(tags = "坐席端")
@RequestMapping("/seat/login")
public class SeatLogin {
@Autowired
private SeatService seatService;
@ApiOperation(value = "登录接口")
@ApiImplicitParams({
@ApiImplicitParam(name = "username", value = "用户名", required = true, paramType = "query"),
@ApiImplicitParam(name = "password", value = "密码", required = true, paramType = "query")
})
@PostMapping("/userLogin")
public ResultMessage<Object> userLogin(String username, String password) {
return ResultUtil.data(this.seatService.usernameLogin(username, password));
}
@ApiOperation(value = "商家快捷登录客服")
@PostMapping("/quicklogin")
public ResultMessage<Object> quickLogin(String code) {
return ResultUtil.data(this.seatService.quickLogin(code));
}
@ApiOperation(value = "登出")
@PostMapping("/logout")
public ResultMessage<Object> logout() {
//todo
// UserContext.getCurrentUser().getId()
// verificationServiceClient.check(uuid);
return ResultUtil.success();
}
}

View File

@@ -0,0 +1,44 @@
package cn.lili.controller.im;
import cn.lili.common.enums.ResultUtil;
import cn.lili.common.security.context.UserContext;
import cn.lili.common.vo.ResultMessage;
import cn.lili.modules.im.entity.dos.SeatSetting;
import cn.lili.modules.im.service.SeatSettingService;;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 店铺端,分类绑定参数组管理接口
*
* @author pikachu
* @since 2020-02-18 15:18:56
*/
@RestController
@Api(tags = "店铺端,坐席设置")
@RequestMapping("/store/seat/setting")
@Transactional(rollbackFor = Exception.class)
public class SeatSettingStoreController {
@Autowired
private SeatSettingService seatSettingService;
@ApiOperation(value = "查询坐席设置")
@GetMapping
public ResultMessage<SeatSetting> getSetting() {
return ResultUtil.data(seatSettingService.getSetting(UserContext.getCurrentUser().getTenantId()));
}
@ApiOperation(value = "更新坐席设置")
@PutMapping
public void update(SeatSetting seatSetting) {
seatSetting.setTenantId(UserContext.getCurrentUser().getTenantId());
seatSettingService.updateByStore(seatSetting);
}
}

View File

@@ -0,0 +1,42 @@
package cn.lili.controller.im;
import cn.lili.common.enums.ResultUtil;
import cn.lili.common.security.context.UserContext;
import cn.lili.common.vo.ResultMessage;
import cn.lili.modules.im.entity.vo.SeatVO;
import cn.lili.modules.im.service.SeatService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* SeatController
*
* @author Chopper
* @version v1.0
* 2022-02-10 11:50
*/
@RestController
@Api(tags = "店铺端,坐席管理")
@RequestMapping("/store/seat/setting")
@Transactional(rollbackFor = Exception.class)
public class SeatStoreController {
@Autowired
private SeatService seatService;
@ApiOperation(value = "分页获取坐席")
@GetMapping("/list")
public ResultMessage<List<SeatVO>> getSeats() {
return ResultUtil.data(seatService.seatVoList(UserContext.getCurrentUser().getTenantId()));
}
}

View File

@@ -0,0 +1,39 @@
package cn.lili.controller.im;
import cn.lili.common.enums.ResultUtil;
import cn.lili.common.vo.ResultMessage;
import cn.lili.modules.im.entity.vo.SeatVO;
import cn.lili.modules.im.service.SeatService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* SeatController
*
* @author Chopper
* @version v1.0
* 2022-02-10 11:50
*/
@RestController
@Api(tags = "店铺端,坐席管理")
@RequestMapping("/manager/seat/setting")
@Transactional(rollbackFor = Exception.class)
public class SeatStoreManagerController {
@Autowired
private SeatService seatService;
@ApiOperation(value = "查看店铺坐席列表")
@GetMapping("/list")
public ResultMessage<List<SeatVO>> getSeats(String storeId) {
return ResultUtil.data(seatService.seatVoList(storeId));
}
}

View File

@@ -0,0 +1,172 @@
package cn.lili.controller.im;
import cn.lili.cache.Cache;
import cn.lili.common.security.AuthUser;
import cn.lili.common.security.context.UserContext;
import cn.lili.common.utils.SnowFlake;
import cn.lili.modules.im.config.CustomSpringConfigurator;
import cn.lili.modules.im.entity.dos.ImMessage;
import cn.lili.modules.im.entity.enums.MessageResultType;
import cn.lili.modules.im.entity.vo.MessageOperation;
import cn.lili.modules.im.entity.vo.MessageVO;
import cn.lili.modules.im.service.ImMessageService;
import cn.lili.modules.member.entity.dos.Member;
import cn.lili.modules.member.service.MemberService;
import com.alibaba.druid.util.StringUtils;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.Date;
import java.util.concurrent.ConcurrentHashMap;
/**
* @author liushuai
*/
@Component
@ServerEndpoint(value = "/lili/webSocket/{accessToken}", configurator = CustomSpringConfigurator.class)
@Slf4j
public class WebSocketServer {
/**
* 消息服务
*/
@Autowired
private ImMessageService imMessageService;
/**
* im用户服务
*/
@Autowired
private MemberService memberService;
@Autowired
private Cache cache;
/**
* 在线人数
* PS 注意,只能单节点,如果多节点部署需要自行寻找方案
*/
private static ConcurrentHashMap<String, Session> sessionPools = new ConcurrentHashMap<>();
/**
* 建立连接
*
* @param session
*/
@OnOpen
public void onOpen(@PathParam("accessToken") String accessToken, Session session) throws IOException {
AuthUser authUser = UserContext.getAuthUser(accessToken);
Member member = memberService.getById(authUser.getId());
sessionPools.put(authUser.getId(), session);
MessageVO messageVO = new MessageVO(MessageResultType.FRIENDS, member);
sendMessage(authUser.getId(), messageVO);
}
/**
* 关闭连接
*/
@OnClose
public void onClose(@PathParam("accessToken") String accessToken) {
log.info("断开连接:{}", accessToken);
sessionPools.remove(UserContext.getAuthUser(accessToken).getId());
}
/**
* 发送消息
*
* @param msg
* @throws IOException
*/
@OnMessage
public void onMessage(@PathParam("accessToken") String accessToken, String msg) {
log.error(msg);
MessageOperation messageOperation = JSON.parseObject(msg, MessageOperation.class);
operation(accessToken, messageOperation);
}
/**
* IM操作
*
* @param accessToken
* @param messageOperation
*/
private void operation(String accessToken, MessageOperation messageOperation) {
AuthUser authUser = UserContext.getAuthUser(accessToken);
switch (messageOperation.getOperationType()) {
case PING:
break;
case MESSAGE:
//保存消息
ImMessage imMessage = new ImMessage();
imMessage.setFromUser(messageOperation.getFrom());
imMessage.setMessageType(messageOperation.getMessageType());
imMessage.setIsRead(false);
imMessage.setText(messageOperation.getContext());
imMessage.setTalkId(messageOperation.getTalkId());
imMessage.setCreateTime(new Date());
imMessage.setToUser(messageOperation.getTo());
imMessage.setId(SnowFlake.getIdStr());
imMessageService.save(imMessage);
//发送消息
sendMessage(messageOperation.getTo(), new MessageVO(MessageResultType.MESSAGE, imMessage));
break;
case READ:
if (!StringUtils.isEmpty(messageOperation.getContext())) {
imMessageService.read(messageOperation.getTalkId(), accessToken);
}
break;
case UNREAD:
sendMessage(authUser.getId(), new MessageVO(MessageResultType.UN_READ, imMessageService.unReadMessages(accessToken)));
break;
case HISTORY:
sendMessage(authUser.getId(), new MessageVO(MessageResultType.HISTORY, imMessageService.historyMessage(accessToken, messageOperation.getTo())));
break;
default:
break;
}
}
/**
* 发送消息
*
* @param key 密钥
* @param message 消息对象
*/
private void sendMessage(String key, MessageVO message) {
Session session = sessionPools.get(key);
if (session != null) {
try {
session.getBasicRemote().sendText(JSON.toJSONString(message, true));
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* socket exception
*
* @param session
* @param throwable
*/
@OnError
public void onError(Session session, Throwable throwable) {
throwable.printStackTrace();
}
/**
* 获取店铺id
*
* @return
*/
private String storeKey(String storeId) {
return "STORE_" + storeId;
}
}

View File

@@ -0,0 +1,53 @@
package cn.lili.controller.security;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
import org.springframework.web.cors.CorsConfigurationSource;
/**
* spring Security 核心配置类 通用安全
*
* @author Chopper
* @version v4.0
* @since 2020/11/14 16:20
*/
@Slf4j
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class ImSecurityConfig extends WebSecurityConfigurerAdapter {
/**
* spring security -》 权限不足处理
*/
@Autowired
private CorsConfigurationSource corsConfigurationSource;
@Override
protected void configure(HttpSecurity http) throws Exception {
ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry registry = http
.authorizeRequests();
registry
.and()
//禁止网页iframe
.headers().frameOptions().disable()
.and()
.authorizeRequests()
//任何请求
.anyRequest()
//需要身份认证
.permitAll()
.and()
//允许跨域
.cors().configurationSource(corsConfigurationSource).and()
//关闭跨站请求防护
.csrf().disable();
}
}