Commit 90b07d5d by giaogiao

消息在线发送和接收;

消息保存收件箱;
创建聊天会话;
添加会话成员;
parent 4095b386
......@@ -44,6 +44,7 @@ import org.springframework.transaction.annotation.EnableTransactionManagement;
@SpringBootApplication(scanBasePackages = {"io.geekidea.springbootplus", "com.wecloud", "com.wecloud.im", "com.wecloud.im.config"})
public class SpringBootPlusApplication {
public static void main(String[] args) {
// 启动spring-boot-plus
ConfigurableApplicationContext context = SpringApplication.run(SpringBootPlusApplication.class, args);
......
......@@ -3,6 +3,7 @@ package io.geekidea.springbootplus.test;
import cn.hutool.core.lang.Snowflake;
import com.wecloud.im.entity.ImApplication;
import com.wecloud.im.service.ImApplicationService;
import com.wecloud.im.service.ImConversationMembersService;
import com.wecloud.im.tillo.app_ws.utils.RSAGenerator;
import org.junit.Test;
import org.junit.runner.RunWith;
......@@ -17,7 +18,13 @@ import java.util.Date;
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
public class AppKeyTest {
public class ImApplicationTest {
@Autowired
private ImConversationMembersService imConversationMembersService;
@Autowired
private ImApplicationService imApplicationService;
public static void main(String[] args) {
String appKey = RSAGenerator.getAppKey(); //定义变量接收
......@@ -26,15 +33,10 @@ public class AppKeyTest {
int i = 1;
}
@Autowired
private ImApplicationService imApplicationService;
@Test
public void add() {
for (int i = 0; i < 10000; i++) {
for (int i = 0; i < 10; i++) {
addDb(i);
}
}
......@@ -53,5 +55,4 @@ public class AppKeyTest {
imApplicationService.save(imApplication);
}
}
package io.geekidea.springbootplus.test;
import com.wecloud.im.entity.ImConversation;
import com.wecloud.im.entity.ImConversationMembers;
import com.wecloud.im.service.ImConversationMembersService;
import com.wecloud.im.service.ImConversationService;
import io.geekidea.springbootplus.framework.shiro.util.SnowflakeUtil;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import java.util.Date;
/**
* imConversation 单元测试
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
public class ImConversationMembersTest {
@Autowired
private ImConversationMembersService imConversationMembersService;
@Autowired
private ImConversationService imConversationService;
@Test
public void addConversation() {
long creator = 1390920735408656384L;
long user2 = 1390921236443435008L;
long appid = 1387022761016299520L;
Long imConversationId = SnowflakeUtil.getId();
// 创建会话
ImConversation imConversation = new ImConversation();
imConversation.setId(imConversationId);
imConversation.setCreateTime(new Date());
imConversation.setLastMessage(null);
imConversation.setFkAppid(appid);
imConversation.setCreator(creator);
imConversation.setName("");
imConversation.setAttributes("");
imConversation.setSystem(false);
imConversationService.save(imConversation);
// 将自己添加到会话
Long imConversationMembersId = SnowflakeUtil.getId();
ImConversationMembers imConversationMembers = new ImConversationMembers();
imConversationMembers.setId(imConversationMembersId);
imConversationMembers.setCreateTime(new Date());
// imConversationMembers.setUpdateTime(new Date());
imConversationMembers.setFkAppid(appid);
imConversationMembers.setFkConversationId(imConversationId);
imConversationMembers.setFkClientId(creator);
imConversationMembersService.save(imConversationMembers);
// 将他人添加到会话
Long imConversationMembersId2 = SnowflakeUtil.getId();
ImConversationMembers imConversationMembers2 = new ImConversationMembers();
imConversationMembers2.setId(imConversationMembersId2);
imConversationMembers2.setCreateTime(new Date());
imConversationMembers2.setFkAppid(appid);
imConversationMembers2.setFkConversationId(imConversationId);
imConversationMembers2.setFkClientId(user2);
imConversationMembersService.save(imConversationMembers2);
}
}
package io.geekidea.springbootplus.test;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.json.JsonMapper;
import com.wecloud.im.tillo.app_ws.model.request.ReceiveModel;
public class JsonTest {
public static void main(String[] args) throws JsonProcessingException {
// jsonTest();
}
private static void jsonTest() throws JsonProcessingException {
String data = "{\n" +
"\"reqId\":\"123123\",\n" +
"\"cmd\":1,\n" +
"\"data\":{\n" +
" \"type\":-1,\n" +
" \"text\":\"这是一个纯文本消息\",\n" +
" \"attrs\":{\n" +
" \"a\":\"attrs是用来存储用户自定义的一些键值对\"}}\n" +
"}\n";
// json转换成对象
JsonMapper jsonMapper = new JsonMapper();
ReceiveModel receiveModel = jsonMapper.readValue(data, ReceiveModel.class);
// data对象转换成json
ObjectMapper objectMapper = new ObjectMapper();
String s = objectMapper.writeValueAsString(receiveModel.getData());
}
}
......@@ -31,38 +31,48 @@ public class LoginTest {
@Autowired
private StringRedisTemplate redisTemplate;
@Autowired
private ImApplicationService imApplicationService;
@Autowired
private ImClientService imClientService;
/**
* 根据客户方生成签名字符串 验证通过则下发token
*
* @param timestemp
* @param clientId
* @param appKey
* @param sign
* @return
* @throws Exception
*/
private String getToken(String timestemp, String clientId, String appKey, String sign) throws Exception {
String token = null;
// 从数据库查询密钥
// 根据appKey从数据库查询密钥
ImApplication imApplication = imApplicationService.getOne(
new QueryWrapper<ImApplication>().lambda().eq(ImApplication::getAppKey, appKey)
);
// 验证签名
// 生成以数据库为准的签名
String mySign = new MD5().digestHex(timestemp + clientId + imApplication.getAppKey() + imApplication.getAppSecret());
// 验证签名
if (mySign.equals(sign)) {
System.out.println("一致" + mySign);
// return null;
} else {
System.out.println("不一致" + mySign);
return null;
}
// 判断client是否存在
ImClient byid = imClientService.getOne(new QueryWrapper<ImClient>().lambda()
ImClient client = imClientService.getOne(new QueryWrapper<ImClient>().lambda()
.eq(ImClient::getFkAppid, imApplication.getId())
.eq(ImClient::getClientId, clientId));
if (byid == null) {
if (client == null) {
System.out.println("不存在");
ImClient imClient = new ImClient();
......@@ -75,8 +85,10 @@ public class LoginTest {
System.out.println("存在");
}
String generateToken = JwtUtil.generateToken(clientId, imApplication.getAppSecret(), Duration.ofDays(100));
// 生成token
String generateToken = JwtUtil.generateToken(clientId, appKey, imApplication.getAppSecret(), Duration.ofDays(100));
// 保存redis
redisTemplate.opsForValue().set("client:" + imApplication.getAppKey() + ":" + clientId, generateToken);
return generateToken;
}
......@@ -84,10 +96,10 @@ public class LoginTest {
@Test
public void test() throws Exception {
// 时间戳
String timestemp = "1619574452548";
String clientId = "c1";
String timestemp = "1620456403794";
String clientId = "hahah_30";
String appKey = "elLwpel1gWCHDqZy";
String sign = "b240f069db255eaa0ab4677016c86f71";
String sign = "9db5c1383829d346adba48182fd8f503";
String token = getToken(timestemp, clientId, appKey, sign);
System.out.println("token:" + token);
}
......
......@@ -9,7 +9,7 @@ import com.wecloud.im.tillo.app_ws.model.request.ReceiveModel;
import java.util.Date;
/**
* 生成测试appkey与appSecret对,并存入数据库
* 客户方签名字符串生成 单元测试
*/
//@RunWith(SpringJUnit4ClassRunner.class)
//@SpringBootTest
......@@ -21,14 +21,14 @@ public class SignTest {
/**
* 获取sign,客户端sdk得到sign之后就可以进行登录 和开启websocket
* <p>
* sign = MD5{ clientId + AppKey + appSecret}
* sign = MD5{ clientId + appKey + appSecret}
*
* @param AppKey
* @param appKey
* @param appSecret
*/
private static void getSign(String timestemp, String clientId, String AppKey, String appSecret) {
private static void getSign(String timestemp, String clientId, String appKey, String appSecret) {
String sign = new MD5().digestHex(timestemp + clientId + AppKey + appSecret);
String sign = new MD5().digestHex(timestemp + clientId + appKey + appSecret);
System.out.println("timestemp:" + timestemp);
System.out.println("sign:" + sign);
......@@ -36,12 +36,12 @@ public class SignTest {
}
public static void main(String[] args) throws JsonProcessingException {
String clientId = "c1";
String clientId = "hahah_30";
String appKey = "elLwpel1gWCHDqZy";
String appSecret = "68809bb5a9077a83631aeb0b17b5965d6b2302faf2ab3737";
String timestemp = String.valueOf(new Date().getTime());
getSign(timestemp, clientId, appKey, appSecret);
jsonTest();
// jsonTest();
}
private static void jsonTest() throws JsonProcessingException {
......@@ -52,7 +52,7 @@ public class SignTest {
" \"type\":-1,\n" +
" \"text\":\"这是一个纯文本消息\",\n" +
" \"attrs\":{\n" +
" \"a\":\"attrs 是用来存储用户自定义的一些键值对\"}}\n" +
" \"a\":\"attrs是用来存储用户自定义的一些键值对\"}}\n" +
"}\n";
// json转换成对象
......
package com.wecloud.im.controller;
import com.wecloud.im.entity.ImConversation;
import com.wecloud.im.param.ImConversationPageParam;
import com.wecloud.im.param.ImConversationQueryVo;
import com.wecloud.im.service.ImConversationService;
import io.geekidea.springbootplus.framework.common.api.ApiResult;
import io.geekidea.springbootplus.framework.common.controller.BaseController;
import io.geekidea.springbootplus.framework.core.pagination.Paging;
import io.geekidea.springbootplus.framework.core.validator.groups.Add;
import io.geekidea.springbootplus.framework.core.validator.groups.Update;
import io.geekidea.springbootplus.framework.log.annotation.OperationLog;
import io.geekidea.springbootplus.framework.log.enums.OperationLogType;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 会话表 控制器
*
* @author wei
* @since 2021-05-07
*/
@Slf4j
@RestController
@RequestMapping("/imConversation")
@Api(value = "会话表API", tags = {"会话表"})
public class ImConversationController extends BaseController {
@Autowired
private ImConversationService imConversationService;
/**
* 添加会话表
*/
@PostMapping("/add")
@OperationLog(name = "添加会话表", type = OperationLogType.ADD)
@ApiOperation(value = "添加会话表")
public ApiResult<Boolean> addImConversation(@Validated(Add.class) @RequestBody ImConversation imConversation) throws Exception {
boolean flag = imConversationService.saveImConversation(imConversation);
return ApiResult.result(flag);
}
/**
* 修改会话表
*/
@PostMapping("/update")
@OperationLog(name = "修改会话表", type = OperationLogType.UPDATE)
@ApiOperation(value = "修改会话表")
public ApiResult<Boolean> updateImConversation(@Validated(Update.class) @RequestBody ImConversation imConversation) throws Exception {
boolean flag = imConversationService.updateImConversation(imConversation);
return ApiResult.result(flag);
}
/**
* 删除会话表
*/
@PostMapping("/delete/{id}")
@OperationLog(name = "删除会话表", type = OperationLogType.DELETE)
@ApiOperation(value = "删除会话表")
public ApiResult<Boolean> deleteImConversation(@PathVariable("id") Long id) throws Exception {
boolean flag = imConversationService.deleteImConversation(id);
return ApiResult.result(flag);
}
/**
* 获取会话表详情
*/
@GetMapping("/info/{id}")
@OperationLog(name = "会话表详情", type = OperationLogType.INFO)
@ApiOperation(value = "会话表详情")
public ApiResult<ImConversationQueryVo> getImConversation(@PathVariable("id") Long id) throws Exception {
ImConversationQueryVo imConversationQueryVo = imConversationService.getImConversationById(id);
return ApiResult.ok(imConversationQueryVo);
}
/**
* 会话表分页列表
*/
@PostMapping("/getPageList")
@OperationLog(name = "会话表分页列表", type = OperationLogType.PAGE)
@ApiOperation(value = "会话表分页列表")
public ApiResult<Paging<ImConversationQueryVo>> getImConversationPageList(@Validated @RequestBody ImConversationPageParam imConversationPageParam) throws Exception {
Paging<ImConversationQueryVo> paging = imConversationService.getImConversationPageList(imConversationPageParam);
return ApiResult.ok(paging);
}
}
package com.wecloud.im.controller;
import com.wecloud.im.entity.ImConversationMembers;
import com.wecloud.im.param.ImConversationMembersPageParam;
import com.wecloud.im.param.ImConversationMembersQueryVo;
import com.wecloud.im.service.ImConversationMembersService;
import io.geekidea.springbootplus.framework.common.api.ApiResult;
import io.geekidea.springbootplus.framework.common.controller.BaseController;
import io.geekidea.springbootplus.framework.core.pagination.Paging;
import io.geekidea.springbootplus.framework.core.validator.groups.Add;
import io.geekidea.springbootplus.framework.core.validator.groups.Update;
import io.geekidea.springbootplus.framework.log.annotation.OperationLog;
import io.geekidea.springbootplus.framework.log.enums.OperationLogType;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 会话成员表 控制器
*
* @author wei
* @since 2021-05-07
*/
@Slf4j
@RestController
@RequestMapping("/imConversationMembers")
@Api(value = "会话成员表API", tags = {"会话成员表"})
public class ImConversationMembersController extends BaseController {
@Autowired
private ImConversationMembersService imConversationMembersService;
/**
* 添加会话成员表
*/
@PostMapping("/add")
@OperationLog(name = "添加会话成员表", type = OperationLogType.ADD)
@ApiOperation(value = "添加会话成员表")
public ApiResult<Boolean> addImConversationMembers(@Validated(Add.class) @RequestBody ImConversationMembers imConversationMembers) throws Exception {
boolean flag = imConversationMembersService.saveImConversationMembers(imConversationMembers);
return ApiResult.result(flag);
}
/**
* 修改会话成员表
*/
@PostMapping("/update")
@OperationLog(name = "修改会话成员表", type = OperationLogType.UPDATE)
@ApiOperation(value = "修改会话成员表")
public ApiResult<Boolean> updateImConversationMembers(@Validated(Update.class) @RequestBody ImConversationMembers imConversationMembers) throws Exception {
boolean flag = imConversationMembersService.updateImConversationMembers(imConversationMembers);
return ApiResult.result(flag);
}
/**
* 删除会话成员表
*/
@PostMapping("/delete/{id}")
@OperationLog(name = "删除会话成员表", type = OperationLogType.DELETE)
@ApiOperation(value = "删除会话成员表")
public ApiResult<Boolean> deleteImConversationMembers(@PathVariable("id") Long id) throws Exception {
boolean flag = imConversationMembersService.deleteImConversationMembers(id);
return ApiResult.result(flag);
}
/**
* 获取会话成员表详情
*/
@GetMapping("/info/{id}")
@OperationLog(name = "会话成员表详情", type = OperationLogType.INFO)
@ApiOperation(value = "会话成员表详情")
public ApiResult<ImConversationMembersQueryVo> getImConversationMembers(@PathVariable("id") Long id) throws Exception {
ImConversationMembersQueryVo imConversationMembersQueryVo = imConversationMembersService.getImConversationMembersById(id);
return ApiResult.ok(imConversationMembersQueryVo);
}
/**
* 会话成员表分页列表
*/
@PostMapping("/getPageList")
@OperationLog(name = "会话成员表分页列表", type = OperationLogType.PAGE)
@ApiOperation(value = "会话成员表分页列表")
public ApiResult<Paging<ImConversationMembersQueryVo>> getImConversationMembersPageList(@Validated @RequestBody ImConversationMembersPageParam imConversationMembersPageParam) throws Exception {
Paging<ImConversationMembersQueryVo> paging = imConversationMembersService.getImConversationMembersPageList(imConversationMembersPageParam);
return ApiResult.ok(paging);
}
}
package com.wecloud.im.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import io.geekidea.springbootplus.framework.common.entity.BaseEntity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import javax.validation.constraints.NotNull;
import java.util.Date;
/**
* 会话表
*
* @author wei
* @since 2021-05-07
*/
@Data
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = true)
@ApiModel(value = "ImConversation对象")
public class ImConversation extends BaseEntity {
private static final long serialVersionUID = 1L;
@NotNull(message = "会话id不能为空")
@ApiModelProperty("会话id")
@TableId(value = "id", type = IdType.INPUT)
private Long id;
@ApiModelProperty("创建时间")
private Date createTime;
@ApiModelProperty("修改时间")
private Date updateTime;
@ApiModelProperty("对话中最后一条消息的发送或接收时间")
private Date lastMessage;
@NotNull(message = "应用appid不能为空")
@ApiModelProperty("应用appid")
private Long fkAppid;
@NotNull(message = "创建者客户端id不能为空")
@ApiModelProperty("创建者客户端id")
private Long creator;
@ApiModelProperty("可选 对话的名字,可为群组命名。")
private String name;
@ApiModelProperty("可选 自定义属性,供开发者扩展使用。")
private String attributes;
@ApiModelProperty("可选 对话类型标志,是否是系统对话,后面会说明。")
private Boolean system;
}
package com.wecloud.im.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import io.geekidea.springbootplus.framework.common.entity.BaseEntity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import javax.validation.constraints.NotNull;
import java.util.Date;
/**
* 会话成员表
*
* @author wei
* @since 2021-05-07
*/
@Data
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = true)
@ApiModel(value = "ImConversationMembers对象")
public class ImConversationMembers extends BaseEntity {
private static final long serialVersionUID = 1L;
@NotNull(message = "唯一id不能为空")
@ApiModelProperty("唯一id")
@TableId(value = "id", type = IdType.INPUT)
private Long id;
@ApiModelProperty("加入时间")
private Date createTime;
@ApiModelProperty("修改时间")
private Date updateTime;
@NotNull(message = "应用appid不能为空")
@ApiModelProperty("应用appid")
private Long fkAppid;
@NotNull(message = "会话表id不能为空")
@ApiModelProperty("会话表id")
private Long fkConversationId;
@NotNull(message = "客户端id不能为空")
@ApiModelProperty("客户端id")
private Long fkClientId;
}
package com.wecloud.im.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wecloud.im.entity.ImConversation;
import com.wecloud.im.param.ImConversationPageParam;
import com.wecloud.im.param.ImConversationQueryVo;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import java.io.Serializable;
/**
* 会话表 Mapper 接口
*
* @author wei
* @since 2021-05-07
*/
@Repository
public interface ImConversationMapper extends BaseMapper<ImConversation> {
/**
* 根据ID获取查询对象
*
* @param id
* @return
*/
ImConversationQueryVo getImConversationById(Serializable id);
/**
* 获取分页对象
*
* @param page
* @param imConversationPageParam
* @return
*/
IPage<ImConversationQueryVo> getImConversationPageList(@Param("page") Page page, @Param("param") ImConversationPageParam imConversationPageParam);
}
package com.wecloud.im.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wecloud.im.entity.ImConversationMembers;
import com.wecloud.im.param.ImConversationMembersPageParam;
import com.wecloud.im.param.ImConversationMembersQueryVo;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import java.io.Serializable;
/**
* 会话成员表 Mapper 接口
*
* @author wei
* @since 2021-05-07
*/
@Repository
public interface ImConversationMembersMapper extends BaseMapper<ImConversationMembers> {
/**
* 根据ID获取查询对象
*
* @param id
* @return
*/
ImConversationMembersQueryVo getImConversationMembersById(Serializable id);
/**
* 获取分页对象
*
* @param page
* @param imConversationMembersPageParam
* @return
*/
IPage<ImConversationMembersQueryVo> getImConversationMembersPageList(@Param("page") Page page, @Param("param") ImConversationMembersPageParam imConversationMembersPageParam);
}
package com.wecloud.im.param;
import io.geekidea.springbootplus.framework.core.pagination.BasePageOrderParam;
import io.swagger.annotations.ApiModel;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* <pre>
* 会话成员表 分页参数对象
* </pre>
*
* @author wei
* @date 2021-05-07
*/
@Data
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = true)
@ApiModel(value = "会话成员表分页参数")
public class ImConversationMembersPageParam extends BasePageOrderParam {
private static final long serialVersionUID = 1L;
}
package com.wecloud.im.param;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.Date;
/**
* <pre>
* 会话成员表 查询结果对象
* </pre>
*
* @author wei
* @date 2021-05-07
*/
@Data
@Accessors(chain = true)
@ApiModel(value = "ImConversationMembersQueryVo对象")
public class ImConversationMembersQueryVo implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty("唯一id")
private Long id;
@ApiModelProperty("加入时间")
private Date createTime;
@ApiModelProperty("修改时间")
private Date updateTime;
@ApiModelProperty("应用appid")
private Long fkAppid;
@ApiModelProperty("会话表id")
private Long fkConversationId;
@ApiModelProperty("客户端id")
private Long fkClientId;
}
\ No newline at end of file
package com.wecloud.im.param;
import io.geekidea.springbootplus.framework.core.pagination.BasePageOrderParam;
import io.swagger.annotations.ApiModel;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* <pre>
* 会话表 分页参数对象
* </pre>
*
* @author wei
* @date 2021-05-07
*/
@Data
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = true)
@ApiModel(value = "会话表分页参数")
public class ImConversationPageParam extends BasePageOrderParam {
private static final long serialVersionUID = 1L;
}
package com.wecloud.im.param;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.Date;
/**
* <pre>
* 会话表 查询结果对象
* </pre>
*
* @author wei
* @date 2021-05-07
*/
@Data
@Accessors(chain = true)
@ApiModel(value = "ImConversationQueryVo对象")
public class ImConversationQueryVo implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty("会话id")
private Long id;
@ApiModelProperty("创建时间")
private Date createTime;
@ApiModelProperty("修改时间")
private Date updateTime;
@ApiModelProperty("对话中最后一条消息的发送或接收时间")
private Date lastMessage;
@ApiModelProperty("应用appid")
private Long fkAppid;
@ApiModelProperty("创建者客户端id")
private Long creator;
@ApiModelProperty("可选 对话的名字,可为群组命名。")
private String name;
@ApiModelProperty("可选 自定义属性,供开发者扩展使用。")
private String attributes;
@ApiModelProperty("可选 对话类型标志,是否是系统对话,后面会说明。")
private Boolean system;
}
\ No newline at end of file
package com.wecloud.im.service;
import com.wecloud.im.entity.ImConversationMembers;
import com.wecloud.im.param.ImConversationMembersPageParam;
import com.wecloud.im.param.ImConversationMembersQueryVo;
import io.geekidea.springbootplus.framework.common.service.BaseService;
import io.geekidea.springbootplus.framework.core.pagination.Paging;
/**
* 会话成员表 服务类
*
* @author wei
* @since 2021-05-07
*/
public interface ImConversationMembersService extends BaseService<ImConversationMembers> {
/**
* 保存
*
* @param imConversationMembers
* @return
* @throws Exception
*/
boolean saveImConversationMembers(ImConversationMembers imConversationMembers) throws Exception;
/**
* 修改
*
* @param imConversationMembers
* @return
* @throws Exception
*/
boolean updateImConversationMembers(ImConversationMembers imConversationMembers) throws Exception;
/**
* 删除
*
* @param id
* @return
* @throws Exception
*/
boolean deleteImConversationMembers(Long id) throws Exception;
/**
* 根据ID获取查询对象
*
* @param id
* @return
* @throws Exception
*/
ImConversationMembersQueryVo getImConversationMembersById(Long id) throws Exception;
/**
* 获取分页对象
*
* @param imConversationMembersPageParam
* @return
* @throws Exception
*/
Paging<ImConversationMembersQueryVo> getImConversationMembersPageList(ImConversationMembersPageParam imConversationMembersPageParam) throws Exception;
}
package com.wecloud.im.service;
import com.wecloud.im.entity.ImConversation;
import com.wecloud.im.param.ImConversationPageParam;
import com.wecloud.im.param.ImConversationQueryVo;
import io.geekidea.springbootplus.framework.common.service.BaseService;
import io.geekidea.springbootplus.framework.core.pagination.Paging;
/**
* 会话表 服务类
*
* @author wei
* @since 2021-05-07
*/
public interface ImConversationService extends BaseService<ImConversation> {
/**
* 保存
*
* @param imConversation
* @return
* @throws Exception
*/
boolean saveImConversation(ImConversation imConversation) throws Exception;
/**
* 修改
*
* @param imConversation
* @return
* @throws Exception
*/
boolean updateImConversation(ImConversation imConversation) throws Exception;
/**
* 删除
*
* @param id
* @return
* @throws Exception
*/
boolean deleteImConversation(Long id) throws Exception;
/**
* 根据ID获取查询对象
*
* @param id
* @return
* @throws Exception
*/
ImConversationQueryVo getImConversationById(Long id) throws Exception;
/**
* 获取分页对象
*
* @param imConversationPageParam
* @return
* @throws Exception
*/
Paging<ImConversationQueryVo> getImConversationPageList(ImConversationPageParam imConversationPageParam) throws Exception;
}
package com.wecloud.im.service.impl;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wecloud.im.entity.ImConversationMembers;
import com.wecloud.im.mapper.ImConversationMembersMapper;
import com.wecloud.im.param.ImConversationMembersPageParam;
import com.wecloud.im.param.ImConversationMembersQueryVo;
import com.wecloud.im.service.ImConversationMembersService;
import io.geekidea.springbootplus.framework.common.service.impl.BaseServiceImpl;
import io.geekidea.springbootplus.framework.core.pagination.PageInfo;
import io.geekidea.springbootplus.framework.core.pagination.Paging;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
/**
* 会话成员表 服务实现类
*
* @author wei
* @since 2021-05-07
*/
@Slf4j
@Service
public class ImConversationMembersServiceImpl extends BaseServiceImpl<ImConversationMembersMapper, ImConversationMembers> implements ImConversationMembersService {
@Autowired
private ImConversationMembersMapper imConversationMembersMapper;
@Transactional(rollbackFor = Exception.class)
@Override
public boolean saveImConversationMembers(ImConversationMembers imConversationMembers) throws Exception {
return super.save(imConversationMembers);
}
@Transactional(rollbackFor = Exception.class)
@Override
public boolean updateImConversationMembers(ImConversationMembers imConversationMembers) throws Exception {
return super.updateById(imConversationMembers);
}
@Transactional(rollbackFor = Exception.class)
@Override
public boolean deleteImConversationMembers(Long id) throws Exception {
return super.removeById(id);
}
@Override
public ImConversationMembersQueryVo getImConversationMembersById(Long id) throws Exception {
return imConversationMembersMapper.getImConversationMembersById(id);
}
@Override
public Paging<ImConversationMembersQueryVo> getImConversationMembersPageList(ImConversationMembersPageParam imConversationMembersPageParam) throws Exception {
Page<ImConversationMembersQueryVo> page = new PageInfo<>(imConversationMembersPageParam, OrderItem.desc(getLambdaColumn(ImConversationMembers::getCreateTime)));
IPage<ImConversationMembersQueryVo> iPage = imConversationMembersMapper.getImConversationMembersPageList(page, imConversationMembersPageParam);
return new Paging<ImConversationMembersQueryVo>(iPage);
}
}
package com.wecloud.im.service.impl;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wecloud.im.entity.ImConversation;
import com.wecloud.im.mapper.ImConversationMapper;
import com.wecloud.im.param.ImConversationPageParam;
import com.wecloud.im.param.ImConversationQueryVo;
import com.wecloud.im.service.ImConversationService;
import io.geekidea.springbootplus.framework.common.service.impl.BaseServiceImpl;
import io.geekidea.springbootplus.framework.core.pagination.PageInfo;
import io.geekidea.springbootplus.framework.core.pagination.Paging;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
/**
* 会话表 服务实现类
*
* @author wei
* @since 2021-05-07
*/
@Slf4j
@Service
public class ImConversationServiceImpl extends BaseServiceImpl<ImConversationMapper, ImConversation> implements ImConversationService {
@Autowired
private ImConversationMapper imConversationMapper;
@Transactional(rollbackFor = Exception.class)
@Override
public boolean saveImConversation(ImConversation imConversation) throws Exception {
return super.save(imConversation);
}
@Transactional(rollbackFor = Exception.class)
@Override
public boolean updateImConversation(ImConversation imConversation) throws Exception {
return super.updateById(imConversation);
}
@Transactional(rollbackFor = Exception.class)
@Override
public boolean deleteImConversation(Long id) throws Exception {
return super.removeById(id);
}
@Override
public ImConversationQueryVo getImConversationById(Long id) throws Exception {
return imConversationMapper.getImConversationById(id);
}
@Override
public Paging<ImConversationQueryVo> getImConversationPageList(ImConversationPageParam imConversationPageParam) throws Exception {
Page<ImConversationQueryVo> page = new PageInfo<>(imConversationPageParam, OrderItem.desc(getLambdaColumn(ImConversation::getCreateTime)));
IPage<ImConversationQueryVo> iPage = imConversationMapper.getImConversationPageList(page, imConversationPageParam);
return new Paging<ImConversationQueryVo>(iPage);
}
}
......@@ -28,12 +28,11 @@ import java.util.concurrent.TimeUnit;
@Slf4j
public class WsHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> {
@Resource
private ReadWsData readWsData;
@Resource
private MangerChannelService appUserChannelsService;
private MangerChannelService mangerChannelService;
private final static ThreadFactory NAMED_THREAD_FACTORY = new ThreadFactoryBuilder()
.setNamePrefix("business-").build();
......@@ -50,7 +49,6 @@ public class WsHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> {
@Override
protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame msg) {
String data = msg.text();
try {
if (data.isEmpty()) {
return;
......@@ -88,6 +86,7 @@ public class WsHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> {
*/
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
log.debug("检测到异常exceptionCaught", cause);
// //排除当客户端意外关闭的情况,不是发送指定指令通知服务器退出,就会产生此错误。
// if (ctx.channel().isActive()) {
......@@ -98,9 +97,8 @@ public class WsHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> {
@Override
public void handlerAdded(ChannelHandlerContext ctx) {
// Long userIdByChannel = appUserChannelsService.getUserIdByChannel(ctx);
//
// log.debug("uid:" + userIdByChannel + ",app端连接WS成功" + ",channelId:" + ctx.channel().id().asLongText());
String userIdByChannel = mangerChannelService.getUserIdByChannel(ctx);
log.debug("uid:" + userIdByChannel + ",app端连接WS成功" + ",channelId:" + ctx.channel().id().asLongText());
log.debug("连接WS成功handlerAdded");
}
......@@ -113,13 +111,11 @@ public class WsHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> {
*/
@Override
public void channelInactive(ChannelHandlerContext ctx) {
log.debug("连接WS成功channelInactive");
log.debug("客户端不活跃channelInactive");
// Long userIdByChannel = appUserChannelsService.getUserIdByChannel(ctx);
// log.debug("uid:" + userIdByChannel + "," + "不活跃" + ",channelId:" + ctx.channel().id().asLongText());
//
// appUserChannelsService.remove(ctx);
// mangerChannelService.remove(ctx);
}
/**
......
......@@ -43,17 +43,17 @@ public interface MangerChannelService {
/**
* 根据userID获取channel
* @param userId
*
* @return
*/
NioSocketChannel get(String userId);
NioSocketChannel get(String appKey, String clientId);
/**
* userID绑定channel
* @param userId
*
* @param channel
*/
void put(String userId, NioSocketChannel channel);
void put(String appKey, String clientId, NioSocketChannel channel);
/**
* 移除channel
......@@ -67,7 +67,7 @@ public interface MangerChannelService {
* @param channelHandlerContext
* @return
*/
Long getUserIdByChannel(ChannelHandlerContext channelHandlerContext);
String getUserIdByChannel(ChannelHandlerContext channelHandlerContext);
/**
* 下发数据
......
......@@ -27,7 +27,7 @@ import java.util.concurrent.TimeUnit;
*/
@Component
@Slf4j
public class AppUserChannelsServiceImpl implements MangerChannelService {
public class MangerChannelServiceImpl implements MangerChannelService {
private final static ThreadFactory NAMED_THREAD_FACTORY = new ThreadFactoryBuilder()
.setNamePrefix("rpcWrite-").build();
......@@ -59,18 +59,18 @@ public class AppUserChannelsServiceImpl implements MangerChannelService {
@Override
public NioSocketChannel get(String userId) {
public NioSocketChannel get(String appKey, String clientId) {
return MangerChannelService.CHANNEL_MAP.get(userId);
return MangerChannelService.CHANNEL_MAP.get(appKey + clientId);
}
@Override
public void put(String userId, NioSocketChannel channel) {
public void put(String appKey, String clientId, NioSocketChannel channel) {
// AppHashValueModel appHashValueModel = new AppHashValueModel();
// appHashValueModel.setOnlineStatus(UserCache.ONLINE);
userCache.online(userId);
MangerChannelService.CHANNEL_MAP.put(userId, channel);
// userCache.online(userId);
MangerChannelService.CHANNEL_MAP.put(appKey + clientId, channel);
}
......@@ -97,9 +97,9 @@ public class AppUserChannelsServiceImpl implements MangerChannelService {
}
@Override
public Long getUserIdByChannel(ChannelHandlerContext channelHandlerContext) {
// return channelHandlerContext.channel().attr(MangerChannelService.USER_ID).get();
return 1L;
public String getUserIdByChannel(ChannelHandlerContext channelHandlerContext) {
return channelHandlerContext.channel().attr(MangerChannelService.CLIENT_ID).get();
// return 1L;
}
// @Override
......@@ -282,10 +282,9 @@ public class AppUserChannelsServiceImpl implements MangerChannelService {
@Override
public boolean writeData(String msg, String toAppKey, String toClientId) {
NioSocketChannel nioSocketChannel = get(String.valueOf(toAppKey + toClientId));
NioSocketChannel nioSocketChannel = get(toAppKey, toClientId);
if (null == nioSocketChannel) {
userCache.offline(String.valueOf(toAppKey + toClientId));
// userCache.offline(toAppKey + toClientId);
log.debug("writeData连接为空:" + toAppKey + toClientId + "," + msg);
return false;
}
......
......@@ -4,9 +4,7 @@ import com.alibaba.fastjson.JSON;
import com.wecloud.im.tillo.app_ws.model.ResponseModel;
import com.wecloud.im.tillo.app_ws.model.ResultStatus;
import com.wecloud.im.tillo.app_ws.model.request.ReceiveModel;
import com.wecloud.im.tillo.app_ws.service.MangerChannelService;
import com.wecloud.im.tillo.app_ws.service.WriteDataService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.HashMap;
......@@ -19,8 +17,8 @@ import java.util.HashMap;
@Component
public class WriteDataServiceImpl implements WriteDataService {
@Autowired
private MangerChannelService mangerChannelService;
// @Autowired
// private MangerChannelService mangerChannelService;
@Override
public void successAndData(ReceiveModel requestModel, Object data, Long userId, String language) {
......
package com.wecloud.im.tillo.app_ws.strategy.concrete;
import cn.hutool.core.lang.Snowflake;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.json.JsonMapper;
import com.wecloud.im.entity.ImApplication;
import com.wecloud.im.entity.ImClient;
import com.wecloud.im.entity.ImConversationMembers;
import com.wecloud.im.entity.ImInbox;
import com.wecloud.im.entity.ImMessage;
import com.wecloud.im.service.ImApplicationService;
import com.wecloud.im.service.ImClientService;
import com.wecloud.im.service.ImConversationMembersService;
import com.wecloud.im.service.ImInboxService;
import com.wecloud.im.service.ImMessageService;
import com.wecloud.im.tillo.app_ws.annotation.ReceiveTypeAnnotation;
......@@ -15,12 +18,15 @@ import com.wecloud.im.tillo.app_ws.enums.WsRequestCmdEnum;
import com.wecloud.im.tillo.app_ws.model.request.ReceiveModel;
import com.wecloud.im.tillo.app_ws.service.MangerChannelService;
import com.wecloud.im.tillo.app_ws.strategy.AbstractReceiveStrategy;
import io.geekidea.springbootplus.framework.shiro.util.SnowflakeUtil;
import io.netty.channel.ChannelHandlerContext;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
/**
* @Description 处理app单聊消息
......@@ -39,20 +45,36 @@ public class SingleConcreteReceiveStrategy extends AbstractReceiveStrategy {
@Autowired
private ImApplicationService imApplicationService;
@Resource
private MangerChannelService mangerChannelService;
@Autowired
private ImConversationMembersService imConversationMembersService;
@Autowired
private ImClientService imClientService;
@Override
public void process(ReceiveModel requestModel, String language, ChannelHandlerContext ctx, String data) {
String appKey = ctx.channel().attr(MangerChannelService.APP_KEY).get();
String clientId = ctx.channel().attr(MangerChannelService.CLIENT_ID).get();
String clientUniId = ctx.channel().attr(MangerChannelService.CLIENT_ID).get();
// 查询imApplication
ImApplication imApplication = imApplicationService.getOne(new QueryWrapper<ImApplication>().lambda()
.eq(ImApplication::getAppKey, appKey));
// 查询发送者client
ImClient imClientSender = imClientService.getOne(new QueryWrapper<ImClient>().lambda()
.eq(ImClient::getFkAppid, imApplication.getId())
.eq(ImClient::getClientId, clientUniId));
JsonMapper jsonMapper = new JsonMapper();
Long toConversationId = Long.valueOf(requestModel.getData().get("toConversation").toString());
long messageId = SnowflakeUtil.getId();
String content = null;
Long toConversation = Long.valueOf(requestModel.getData().get("toConversation").toString());
long messageId = new Snowflake(1L, 1L).nextId();
long imInboxId = new Snowflake(1L, 1L).nextId();
try {
content = jsonMapper.writeValueAsString(requestModel.getData());
} catch (JsonProcessingException e) {
......@@ -66,29 +88,54 @@ public class SingleConcreteReceiveStrategy extends AbstractReceiveStrategy {
// imMessage.setWithdrawTime(new Date());
// imMessage.setUpdateDate(new Date());
imMessage.setFkAppid(imApplication.getId());
imMessage.setSender(0L);
imMessage.setSender(imClientSender.getId());
imMessage.setContent(content);
imMessage.setWithdraw(false);
imMessage.setEvent(false);
imMessage.setSystem(false);
// imMessage.setAt("");
imMessage.setSendStatus(0);
imMessage.setFkConversationId(toConversation);
imMessage.setFkConversationId(toConversationId);
imMessageService.save(imMessage);
// 向接收方推送
// ChannelFuture channelFuture = ctx.writeAndFlush(new TextWebSocketFrame(data));
// 查询该会话所有成员
List<ImConversationMembers> membersList = imConversationMembersService.list(
new QueryWrapper<ImConversationMembers>().lambda()
.eq(ImConversationMembers::getFkConversationId, toConversationId)
);
if (membersList.isEmpty()) {
log.error("membersList为空");
return;
}
for (ImConversationMembers conversationMembers : membersList) {
// 排除发送者
if (conversationMembers.getFkClientId().equals(imClientSender.getId())) {
continue;
}
// 保存收件箱
long imInboxId = SnowflakeUtil.getId();
ImInbox imInbox = new ImInbox();
imInbox.setId(imInboxId);
imInbox.setCreateTime(new Date());
// imInbox.setUpdateTime(new Date());
// imInbox.setReceiverDate(new Date());
imInbox.setFkAppid(123L);
imInbox.setReceiver(12L);
imInbox.setFkAppid(imApplication.getId());
imInbox.setReceiver(conversationMembers.getId());
imInbox.setFkMsgId(messageId);
imInbox.setReadMsg(0);
imInbox.setFkConversationId(toConversation);
imInbox.setFkConversationId(toConversationId);
imInboxService.save(imInbox);
// 接收方
ImClient imClientReceiver = imClientService.getOne(new QueryWrapper<ImClient>().lambda()
.eq(ImClient::getFkAppid, imApplication.getId())
.eq(ImClient::getId, conversationMembers.getFkClientId()));
// 向接收方推送
String imClientRecerverUniId = imClientReceiver.getClientId();
mangerChannelService.writeData(content, appKey, imClientRecerverUniId);
}
}
}
......@@ -11,6 +11,7 @@ import com.wecloud.im.tillo.app_ws.WsHandler;
import com.wecloud.im.tillo.app_ws.model.WsConstants;
import com.wecloud.im.tillo.app_ws.service.MangerChannelService;
import com.wecloud.im.tillo.app_ws.utils.FullHttpRequestUtils;
import io.geekidea.springbootplus.config.constant.CommonConstant;
import io.geekidea.springbootplus.framework.shiro.util.JwtUtil;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.socket.nio.NioSocketChannel;
......@@ -22,6 +23,7 @@ import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.Map;
......@@ -80,7 +82,6 @@ public class NettyApiRequest {
}
}
/**
* 初始化websocket
*/
......@@ -92,10 +93,10 @@ public class NettyApiRequest {
DecodedJWT jwtInfo = JwtUtil.getJwtInfo(token);
String payload = jwtInfo.getPayload();
Base64.Decoder decoder = Base64.getDecoder();
payload = new String(decoder.decode(payload), "UTF-8");
payload = new String(decoder.decode(payload), StandardCharsets.UTF_8);
JSONObject jsonObject = JSONObject.parseObject(payload);
String appKey = (String) jsonObject.get("appKey");
String clientId = (String) jsonObject.get("username");
String clientId = (String) jsonObject.get(CommonConstant.CLIENT_ID);
// 验签token
ImApplication imApplication = imApplicationService.getOne(new QueryWrapper<ImApplication>().lambda()
......@@ -126,7 +127,7 @@ public class NettyApiRequest {
ctx.pipeline().addLast("appImHandler", appImHandler);
// 保存用户上下文对象
appUserChannelsService.put((appKey + clientId), (NioSocketChannel) ctx.channel());
appUserChannelsService.put(appKey, clientId, (NioSocketChannel) ctx.channel());
//移除当前api处理handler, 不再参与长连接处理
ctx.pipeline().remove("SingleHttpRequestHandler");
......
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.wecloud.im.mapper.ImConversationMapper">
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
id
, create_time, update_time, last_message, fk_appid, creator, name, attributes, system
</sql>
<select id="getImConversationById" resultType="com.wecloud.im.param.ImConversationQueryVo">
select
<include refid="Base_Column_List"/>
from im_conversation where id = #{id}
</select>
<select id="getImConversationPageList" parameterType="com.wecloud.im.param.ImConversationPageParam"
resultType="com.wecloud.im.param.ImConversationQueryVo">
select
<include refid="Base_Column_List"/>
from im_conversation
</select>
</mapper>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.wecloud.im.mapper.ImConversationMembersMapper">
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
id
, create_time, update_time, fk_appid, fk_conversation_id, fk_client_id
</sql>
<select id="getImConversationMembersById" resultType="com.wecloud.im.param.ImConversationMembersQueryVo">
select
<include refid="Base_Column_List"/>
from im_conversation_members where id = #{id}
</select>
<select id="getImConversationMembersPageList" parameterType="com.wecloud.im.param.ImConversationMembersPageParam"
resultType="com.wecloud.im.param.ImConversationMembersQueryVo">
select
<include refid="Base_Column_List"/>
from im_conversation_members
</select>
</mapper>
......@@ -73,7 +73,7 @@ public interface CommonConstant {
/**
* JWT用户名
*/
String JWT_USERNAME = "username";
String CLIENT_ID = "clientId";
/**
* JWT刷新新token响应状态码
......
......@@ -22,7 +22,6 @@ import io.geekidea.springbootplus.config.properties.JwtProperties;
import io.geekidea.springbootplus.framework.shiro.cache.SysLoginRedisService;
import io.geekidea.springbootplus.framework.shiro.jwt.JwtToken;
import io.geekidea.springbootplus.framework.shiro.service.ShiroLoginService;
import io.geekidea.springbootplus.framework.shiro.util.JwtTokenUtil;
import io.geekidea.springbootplus.framework.shiro.util.JwtUtil;
import io.geekidea.springbootplus.framework.shiro.vo.JwtTokenRedisVo;
import lombok.extern.slf4j.Slf4j;
......@@ -36,7 +35,6 @@ import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletResponse;
import java.time.Duration;
import java.util.Date;
/**
......@@ -98,16 +96,16 @@ public class ShiroLoginServiceImpl implements ShiroLoginService {
String salt = jwtToken.getSalt();
Long expireSecond = jwtProperties.getExpireSecond();
// 生成新token字符串
String newToken = JwtUtil.generateToken(username, salt, Duration.ofSeconds(expireSecond));
// String newToken = JwtUtil.generateToken(username, salt, Duration.ofSeconds(expireSecond));
// 生成新JwtToken对象
JwtToken newJwtToken = JwtToken.build(newToken, username, jwtToken.getUserId(), salt, expireSecond, jwtToken.getType(), null);
// 更新redis缓存
sysLoginRedisService.refreshLoginInfo(token, username, newJwtToken);
log.debug("刷新token成功,原token:{},新token:{}", token, newToken);
// 设置响应头
// 刷新token
httpServletResponse.setStatus(CommonConstant.JWT_REFRESH_TOKEN_CODE);
httpServletResponse.setHeader(JwtTokenUtil.getTokenName(), newToken);
// JwtToken newJwtToken = JwtToken.build(newToken, username, jwtToken.getUserId(), salt, expireSecond, jwtToken.getType(), null);
// // 更新redis缓存
// sysLoginRedisService.refreshLoginInfo(token, username, newJwtToken);
// log.debug("刷新token成功,原token:{},新token:{}", token, newToken);
// // 设置响应头
// // 刷新token
// httpServletResponse.setStatus(CommonConstant.JWT_REFRESH_TOKEN_CODE);
// httpServletResponse.setHeader(JwtTokenUtil.getTokenName(), newToken);
}
@Override
......
......@@ -54,23 +54,23 @@ public class JwtUtil {
/**
* 生成JWT Token
*
* @param username 用户名
* @param clientId 用户名
* @param salt 盐值
* @param expireDuration 过期时间和单位
* @return token
*/
public static String generateToken(String username, String salt, Duration expireDuration) {
public static String generateToken(String clientId, String appKey, String salt, Duration expireDuration) {
try {
if (StringUtils.isBlank(username)) {
if (StringUtils.isBlank(clientId)) {
log.error("username不能为空");
return null;
}
log.debug("username:{}", username);
log.debug("clientId:{}", clientId);
// 如果盐值为空,则使用默认值:666666
if (StringUtils.isBlank(salt)) {
salt = jwtProperties.getSecret();
}
// // 如果盐值为空,则使用默认值:666666
// if (StringUtils.isBlank(salt)) {
// salt = jwtProperties.getSecret();
// }
log.debug("salt:{}", salt);
// 过期时间,单位:秒
......@@ -88,7 +88,7 @@ public class JwtUtil {
// 生成token
Algorithm algorithm = Algorithm.HMAC256(salt);
String token = JWT.create()
.withClaim(CommonConstant.JWT_USERNAME, username)
.withClaim(CommonConstant.CLIENT_ID, clientId)
// jwt唯一id
.withJWTId(UUIDUtil.getUuid())
// 签发人
......@@ -97,8 +97,8 @@ public class JwtUtil {
.withSubject(jwtProperties.getSubject())
// 签发的目标
.withAudience(jwtProperties.getAudience())
.withClaim("test1","ddddddd")
.withClaim("appKey","elLwpel1gWCHDqZy")
// .withClaim("test1","ddddddd")
.withClaim("appKey", appKey)
// 签名时间
.withIssuedAt(new Date())
// token过期时间
......@@ -164,7 +164,7 @@ public class JwtUtil {
if (decodedJwt == null) {
return null;
}
String username = decodedJwt.getClaim(CommonConstant.JWT_USERNAME).asString();
String username = decodedJwt.getClaim(CommonConstant.CLIENT_ID).asString();
return username;
}
......
package io.geekidea.springbootplus.framework.shiro.util;
import cn.hutool.core.lang.Snowflake;
public class SnowflakeUtil {
public static Long getId() {
return new Snowflake(1L, 1L).nextId();
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment