Commit 605fa942 by hewei

Merge branch '1.3' into 'master'

1.3

See merge request !4
parents 22172dc3 6f7ab054
...@@ -30,6 +30,9 @@ docker run -p 3306:3306 --name mysql57 -v $PWD/dockerData/mysql57/data:/var/lib/ ...@@ -30,6 +30,9 @@ docker run -p 3306:3306 --name mysql57 -v $PWD/dockerData/mysql57/data:/var/lib/
--- ---
tail -f /data0/java_projects_jenkins/logs/spring-boot-plus-error.log
## 开发规范 ## 开发规范
### 关于模块 ### 关于模块
......
...@@ -58,6 +58,19 @@ public class ImClientController extends BaseController { ...@@ -58,6 +58,19 @@ public class ImClientController extends BaseController {
/** /**
* 退出登陆
*
* @return
* @throws Exception
*/
@PostMapping("/logout")
@ApiOperation(value = "退出登陆 清除推送token等")
public ApiResult<Boolean> logout() throws Exception {
boolean flag = imClientService.logout();
return ApiResult.result(flag);
}
/**
* 获取用户在线状态(批量) * 获取用户在线状态(批量)
* *
* @return true:在线, false 不在线 * @return true:在线, false 不在线
......
package com.wecloud.im.controller; package com.wecloud.im.controller;
import com.wecloud.im.param.ImHistoryMessagePageParam; import com.wecloud.im.param.ImHistoryMessagePageParam;
import com.wecloud.im.param.add.ImMsgRecall;
import com.wecloud.im.param.add.ImMsgUpdate; import com.wecloud.im.param.add.ImMsgUpdate;
import com.wecloud.im.service.ImMessageService; import com.wecloud.im.service.ImMessageService;
import com.wecloud.im.vo.ImMessageOfflineListVo; import com.wecloud.im.vo.ImMessageOfflineListVo;
...@@ -18,7 +19,6 @@ import org.springframework.validation.annotation.Validated; ...@@ -18,7 +19,6 @@ import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import java.util.List; import java.util.List;
...@@ -43,8 +43,8 @@ public class ImMessageController extends BaseController { ...@@ -43,8 +43,8 @@ public class ImMessageController extends BaseController {
*/ */
@PostMapping("/withdraw") @PostMapping("/withdraw")
@ApiOperation(value = "消息撤回", notes = "只能撤回客户端自己发送的消息") @ApiOperation(value = "消息撤回", notes = "只能撤回客户端自己发送的消息")
public ApiResult<Boolean> updateMsgWithdrawById(@RequestParam Long msgId) throws Exception { public ApiResult<Boolean> updateMsgWithdrawById(@RequestBody ImMsgRecall imMsgRecall) throws Exception {
return imMessageService.updateMsgWithdrawById(msgId); return imMessageService.updateMsgWithdrawById(imMsgRecall);
} }
/** /**
......
...@@ -37,4 +37,8 @@ public interface ImClientMapper extends BaseMapper<ImClient> { ...@@ -37,4 +37,8 @@ public interface ImClientMapper extends BaseMapper<ImClient> {
*/ */
IPage<ImClientQueryVo> getImClientPageList(@Param("page") Page page, @Param("param") ImClientPageParam imClientPageParam); IPage<ImClientQueryVo> getImClientPageList(@Param("page") Page page, @Param("param") ImClientPageParam imClientPageParam);
int removeOldToken(@Param("appId") Long appId, @Param("deviceToken") String deviceToken);
} }
...@@ -65,6 +65,16 @@ public interface ImConversationMapper extends BaseMapper<ImConversation> { ...@@ -65,6 +65,16 @@ public interface ImConversationMapper extends BaseMapper<ImConversation> {
*/ */
Integer getRepetitionConversation(@Param("clientId1") Long clientId1, @Param("clientId2") Long clientId2); Integer getRepetitionConversation(@Param("clientId1") Long clientId1, @Param("clientId2") Long clientId2);
/**
* 判断重复会话中的Attributes是否一样
*
* @param clientId1
* @param clientId2
* @param attributes
* @return 大于等于1为有重复会话
*/
Long getRepetitionConversationAttributes(@Param("clientId1") Long clientId1, @Param("clientId2") Long clientId2, @Param("attributes") String attributes);
/** /**
* 查询已经存在的会话信息 * 查询已经存在的会话信息
......
...@@ -42,4 +42,12 @@ public interface ImInboxMapper extends BaseMapper<ImInbox> { ...@@ -42,4 +42,12 @@ public interface ImInboxMapper extends BaseMapper<ImInbox> {
Long updateImMsgReceivedByIds(@Param("clientId") Long clientId, @Param("msgIds") List<Long> msgIds); Long updateImMsgReceivedByIds(@Param("clientId") Long clientId, @Param("msgIds") List<Long> msgIds);
Long updateImMsgReadByIds(@Param("clientId") Long clientId, @Param("msgIds") List<Long> msgIds); Long updateImMsgReadByIds(@Param("clientId") Long clientId, @Param("msgIds") List<Long> msgIds);
/**
* 统计未读消息数量
*
* @param clientId
* @return
*/
Integer countMyNotReadCount(@Param("clientId") Long clientId);
} }
package com.wecloud.im.param.add;
import com.wecloud.im.ws.model.request.PushModel;
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;
/**
* 撤回消息
*
* @author wei
*/
@Data
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = true)
@ApiModel(value = "ImMsgRecall")
public class ImMsgRecall extends BaseEntity {
private static final long serialVersionUID = 1L;
@ApiModelProperty("消息id")
private Long msgId;
@ApiModelProperty("自定义推送字段")
private PushModel push;
}
...@@ -32,6 +32,9 @@ public interface ImClientService extends BaseService<ImClient> { ...@@ -32,6 +32,9 @@ public interface ImClientService extends BaseService<ImClient> {
*/ */
boolean updateDeviceInfo(ImClientDeviceInfoAdd imClientDevice); boolean updateDeviceInfo(ImClientDeviceInfoAdd imClientDevice);
boolean logout();
/** /**
* 修改 * 修改
* *
...@@ -60,6 +63,15 @@ public interface ImClientService extends BaseService<ImClient> { ...@@ -60,6 +63,15 @@ public interface ImClientService extends BaseService<ImClient> {
ImClientQueryVo getImClientById(Long id) throws Exception; ImClientQueryVo getImClientById(Long id) throws Exception;
/** /**
* 移除旧的设备token
*
* @param appId
* @param deviceToken
* @return
*/
int removeOldToken(Long appId, String deviceToken);
/**
* 获取分页对象 * 获取分页对象
* *
* @param imClientPageParam * @param imClientPageParam
......
...@@ -102,5 +102,15 @@ public interface ImConversationService extends BaseService<ImConversation> { ...@@ -102,5 +102,15 @@ public interface ImConversationService extends BaseService<ImConversation> {
*/ */
Integer getRepetitionConversation(Long clientId1, Long clientId2); Integer getRepetitionConversation(Long clientId1, Long clientId2);
/**
* 判断重复会话中的Attributes是否一样
*
* @param clientId1
* @param clientId2
* @param attributes
* @return 大于等于1为有重复会话
*/
Long getRepetitionConversationAttributes(Long clientId1, Long clientId2, String attributes);
} }
...@@ -70,6 +70,14 @@ public interface ImInboxService extends BaseService<ImInbox> { ...@@ -70,6 +70,14 @@ public interface ImInboxService extends BaseService<ImInbox> {
ApiResult<Boolean> updateImMsgReceived(ImMsgReceivedStatusUpdate imMsgReceivedUpdate); ApiResult<Boolean> updateImMsgReceived(ImMsgReceivedStatusUpdate imMsgReceivedUpdate);
/** /**
* 统计未读消息数量
*
* @param clientId
* @return
*/
Integer countMyNotReadCount(Long clientId);
/**
* 消息修改为已读状态 * 消息修改为已读状态
* *
* @return * @return
......
...@@ -2,6 +2,7 @@ package com.wecloud.im.service; ...@@ -2,6 +2,7 @@ package com.wecloud.im.service;
import com.wecloud.im.entity.ImMessage; import com.wecloud.im.entity.ImMessage;
import com.wecloud.im.param.ImHistoryMessagePageParam; import com.wecloud.im.param.ImHistoryMessagePageParam;
import com.wecloud.im.param.add.ImMsgRecall;
import com.wecloud.im.param.add.ImMsgUpdate; import com.wecloud.im.param.add.ImMsgUpdate;
import com.wecloud.im.vo.ImMessageOfflineListVo; import com.wecloud.im.vo.ImMessageOfflineListVo;
import com.wecloud.im.vo.OfflineMsgDto; import com.wecloud.im.vo.OfflineMsgDto;
...@@ -23,10 +24,9 @@ public interface ImMessageService extends BaseService<ImMessage> { ...@@ -23,10 +24,9 @@ public interface ImMessageService extends BaseService<ImMessage> {
/** /**
* 消息撤回 只能撤回客户端自己发送的消息 * 消息撤回 只能撤回客户端自己发送的消息
* *
* @param msgId
* @return * @return
*/ */
ApiResult<Boolean> updateMsgWithdrawById(Long msgId); ApiResult<Boolean> updateMsgWithdrawById(ImMsgRecall imMsgRecall);
/** /**
* 修改消息体 * 修改消息体
......
package com.wecloud.im.service.impl; package com.wecloud.im.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.metadata.OrderItem; import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
...@@ -51,18 +52,53 @@ public class ImClientServiceImpl extends BaseServiceImpl<ImClientMapper, ImClien ...@@ -51,18 +52,53 @@ public class ImClientServiceImpl extends BaseServiceImpl<ImClientMapper, ImClien
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public boolean updateDeviceInfo(ImClientDeviceInfoAdd imClientDevice) { public boolean updateDeviceInfo(ImClientDeviceInfoAdd imClientDevice) {
// shiro线程中获取当前token
JwtToken curentJwtToken = JwtUtil.getCurentJwtToken();
// 根据appKey查询appid
ImApplication imApplication = imApplicationService.getOneByAppKey(curentJwtToken.getAppKey());
// 清除旧client的redis缓存
ImClient imClient = this.getOne(new QueryWrapper<ImClient>().lambda()
.eq(ImClient::getFkAppid, imApplication.getId())
.eq(ImClient::getDeviceToken, imClientDevice.getDeviceToken()));
if (imClient != null) {
deleteCacheImClient(imClient.getFkAppid(), imClient.getClientId());
// client登陆的时候 判断数据库内是否已经存在这个设备token,如果存在就清空旧的
this.removeOldToken(imApplication.getId(), curentJwtToken.getToken());
}
ImClient client = getCurentClient(); ImClient client = getCurentClient();
ImClient clientNew = new ImClient(); ImClient clientNew = new ImClient();
BeanUtils.copyProperties(imClientDevice, clientNew); BeanUtils.copyProperties(imClientDevice, clientNew);
clientNew.setId(client.getId()); clientNew.setId(client.getId());
// 清缓存 // 清除新client的redis缓存
deleteCacheImClient(client.getFkAppid(), client.getClientId()); deleteCacheImClient(client.getFkAppid(), client.getClientId());
// 修改 // 修改
return this.updateImClient(clientNew); return this.updateImClient(clientNew);
} }
@Override
public boolean logout() {
ImClient curentClient = getCurentClient();
// 清除设备token
boolean update = this.update(new UpdateWrapper<ImClient>().lambda()
.eq(ImClient::getFkAppid, curentClient.getFkAppid())
.eq(ImClient::getId, curentClient.getId())
.set(ImClient::getDeviceToken, null)
);
if (update) {
// 清除新client的redis缓存
deleteCacheImClient(curentClient.getFkAppid(), curentClient.getClientId());
}
return update;
}
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
@Override @Override
public boolean updateImClient(ImClient imClient) { public boolean updateImClient(ImClient imClient) {
...@@ -75,6 +111,13 @@ public class ImClientServiceImpl extends BaseServiceImpl<ImClientMapper, ImClien ...@@ -75,6 +111,13 @@ public class ImClientServiceImpl extends BaseServiceImpl<ImClientMapper, ImClien
return super.removeById(id); return super.removeById(id);
} }
@Transactional(rollbackFor = Exception.class)
@Override
public int removeOldToken(Long appId, String deviceToken) {
return imClientMapper.removeOldToken(appId, deviceToken);
}
@Override @Override
public ImClientQueryVo getImClientById(Long id) throws Exception { public ImClientQueryVo getImClientById(Long id) throws Exception {
return imClientMapper.getImClientById(id); return imClientMapper.getImClientById(id);
......
...@@ -123,37 +123,30 @@ public class ImConversationServiceImpl extends BaseServiceImpl<ImConversationMap ...@@ -123,37 +123,30 @@ public class ImConversationServiceImpl extends BaseServiceImpl<ImConversationMap
} }
} else { } else {
//创建重复会话时对比扩展字段 0不 1是 //创建重复会话时对比扩展字段 1是
if (imApplication.getContrastExtendedFieldStatus() == 1) { if (imApplication.getContrastExtendedFieldStatus() == 1) {
// 被邀请client // 被邀请client
ImClient inviteClient = imClientService.getOne(new QueryWrapper<ImClient>().lambda() ImClient inviteClient = imClientService.getOne(new QueryWrapper<ImClient>().lambda()
.eq(ImClient::getFkAppid, createClient.getFkAppid()) .eq(ImClient::getFkAppid, createClient.getFkAppid())
.eq(ImClient::getClientId, imConversationCreate.getClientIds().get(0))); .eq(ImClient::getClientId, imConversationCreate.getClientIds().get(0)));
// 是否存在重复会话
Integer repetitionConversation = getRepetitionConversation(createClient.getId(), inviteClient.getId());
if (repetitionConversation != 0) {
ImConversation repetitionConversationInfo = imConversationMapper.getRepetitionConversationInfo(createClient.getId(), inviteClient.getId());
log.info("出现Conversation重复");
JsonMapper jsonMapper = new JsonMapper(); JsonMapper jsonMapper = new JsonMapper();
HashMap dbAttributesMap = jsonMapper.readValue(repetitionConversationInfo.getAttributes(), HashMap.class); String asString = jsonMapper.writeValueAsString(imConversationCreate.getAttributes());
log.info("RequestAttributes:" + asString);
log.info("DBAttributes:" + repetitionConversationInfo.getAttributes());
log.info("RequestAttributes:" + jsonMapper.writeValueAsString(imConversationCreate.getAttributes()));
Long repetitionConversation = getRepetitionConversationAttributes(createClient.getId(), inviteClient.getId(), asString);
if (dbAttributesMap.equals(imConversationCreate.getAttributes())) { // 存在重复会话
if (repetitionConversation != null) {
log.info("出现Attributes重复"); log.info("出现Attributes重复");
ImConversationCreateVo imConversationCreateVo = new ImConversationCreateVo(); ImConversationCreateVo imConversationCreateVo = new ImConversationCreateVo();
imConversationCreateVo.setId(repetitionConversationInfo.getId()); imConversationCreateVo.setId(repetitionConversation);
// 为重复 // 为重复
return ApiResult.ok(imConversationCreateVo); return ApiResult.ok(imConversationCreateVo);
} }
} }
}
} }
// 会话id // 会话id
...@@ -289,4 +282,9 @@ public class ImConversationServiceImpl extends BaseServiceImpl<ImConversationMap ...@@ -289,4 +282,9 @@ public class ImConversationServiceImpl extends BaseServiceImpl<ImConversationMap
return imConversationMapper.getRepetitionConversation(clientId1, clientId2); return imConversationMapper.getRepetitionConversation(clientId1, clientId2);
} }
@Override
public Long getRepetitionConversationAttributes(Long clientId1, Long clientId2, String attributes) {
return imConversationMapper.getRepetitionConversationAttributes(clientId1, clientId2, attributes);
}
} }
...@@ -116,6 +116,19 @@ public class ImInboxServiceImpl extends BaseServiceImpl<ImInboxMapper, ImInbox> ...@@ -116,6 +116,19 @@ public class ImInboxServiceImpl extends BaseServiceImpl<ImInboxMapper, ImInbox>
return ApiResult.ok(); return ApiResult.ok();
} }
/**
* 统计未读消息数量
*
* @param clientId
* @return
*/
@Override
public Integer countMyNotReadCount(Long clientId) {
return imInboxMapper.countMyNotReadCount(clientId);
}
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public ApiResult<Boolean> updateImMsgRead(ImMsgReadStatusUpdate imMsgReadStatusUpdate) { public ApiResult<Boolean> updateImMsgRead(ImMsgReadStatusUpdate imMsgReadStatusUpdate) {
......
package com.wecloud.im.service.impl; package com.wecloud.im.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.metadata.OrderItem; import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.json.JsonMapper; import com.fasterxml.jackson.databind.json.JsonMapper;
import com.wecloud.im.entity.ImApplication;
import com.wecloud.im.entity.ImClient; import com.wecloud.im.entity.ImClient;
import com.wecloud.im.entity.ImConversation; import com.wecloud.im.entity.ImConversation;
import com.wecloud.im.entity.ImConversationMembers;
import com.wecloud.im.entity.ImMessage; import com.wecloud.im.entity.ImMessage;
import com.wecloud.im.entity.ImMessageOnlineSend;
import com.wecloud.im.mapper.ImMessageMapper; import com.wecloud.im.mapper.ImMessageMapper;
import com.wecloud.im.param.ImHistoryMessagePageParam; import com.wecloud.im.param.ImHistoryMessagePageParam;
import com.wecloud.im.param.add.ImMsgRecall;
import com.wecloud.im.param.add.ImMsgUpdate; import com.wecloud.im.param.add.ImMsgUpdate;
import com.wecloud.im.service.ImApplicationService;
import com.wecloud.im.service.ImClientService; import com.wecloud.im.service.ImClientService;
import com.wecloud.im.service.ImConversationMembersService;
import com.wecloud.im.service.ImConversationService; import com.wecloud.im.service.ImConversationService;
import com.wecloud.im.service.ImMessageService; import com.wecloud.im.service.ImMessageService;
import com.wecloud.im.vo.ImMessageOfflineListVo; import com.wecloud.im.vo.ImMessageOfflineListVo;
import com.wecloud.im.vo.OfflineMsgDto; import com.wecloud.im.vo.OfflineMsgDto;
import com.wecloud.im.ws.model.ResponseModel;
import com.wecloud.im.ws.model.request.PushModel;
import com.wecloud.im.ws.sender.PushTask;
import com.wecloud.im.ws.service.WriteDataService;
import io.geekidea.springbootplus.framework.common.api.ApiCode;
import io.geekidea.springbootplus.framework.common.api.ApiResult; import io.geekidea.springbootplus.framework.common.api.ApiResult;
import io.geekidea.springbootplus.framework.common.service.impl.BaseServiceImpl; import io.geekidea.springbootplus.framework.common.service.impl.BaseServiceImpl;
import io.geekidea.springbootplus.framework.core.pagination.PageInfo; import io.geekidea.springbootplus.framework.core.pagination.PageInfo;
import io.geekidea.springbootplus.framework.core.pagination.Paging; import io.geekidea.springbootplus.framework.core.pagination.Paging;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
...@@ -48,14 +61,34 @@ public class ImMessageServiceImpl extends BaseServiceImpl<ImMessageMapper, ImMes ...@@ -48,14 +61,34 @@ public class ImMessageServiceImpl extends BaseServiceImpl<ImMessageMapper, ImMes
@Autowired @Autowired
private ImConversationService imConversationService; private ImConversationService imConversationService;
@Autowired
private PushTask pushTask;
@Autowired
private ImApplicationService imApplicationService;
@Autowired
private ImConversationMembersService imConversationMembersService;
@Autowired
private WriteDataService writeDataService;
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public ApiResult<Boolean> updateMsgWithdrawById(Long msgId) { public ApiResult<Boolean> updateMsgWithdrawById(ImMsgRecall imMsgRecall) {
ImClient client = imClientService.getCurentClient(); ImClient imClientSender = imClientService.getCurentClient();
// 查询imApplication
ImApplication imApplication = imApplicationService.getById(imClientSender.getFkAppid());
if (imApplication == null) {
log.info("imApplication为空");
return ApiResult.fail();
}
// 判断该消息是否是该客户端发送 // 判断该消息是否是该客户端发送
ImMessage messageById = this.getById(msgId); ImMessage messageById = this.getById(imMsgRecall.getMsgId());
if (!messageById.getSender().equals(client.getId())) { if (!messageById.getSender().equals(imClientSender.getId())) {
log.error("判断该消息是否是该客户端发送"); log.error("判断该消息是否是该客户端发送");
return ApiResult.fail(); return ApiResult.fail();
} }
...@@ -63,13 +96,76 @@ public class ImMessageServiceImpl extends BaseServiceImpl<ImMessageMapper, ImMes ...@@ -63,13 +96,76 @@ public class ImMessageServiceImpl extends BaseServiceImpl<ImMessageMapper, ImMes
return ApiResult.ok(); return ApiResult.ok();
} }
// 修改消息体
messageById.setWithdraw(Boolean.TRUE); messageById.setWithdraw(Boolean.TRUE);
messageById.setWithdrawTime(new Date()); messageById.setWithdrawTime(new Date());
messageById.setContent("{}"); messageById.setContent("{}");
boolean saveOk = this.updateById(messageById);
if (saveOk) {
// 查询该会话所有成员
List<ImConversationMembers> membersList = imConversationMembersService.list(
new QueryWrapper<ImConversationMembers>().lambda()
.eq(ImConversationMembers::getFkConversationId, messageById.getFkConversationId())
.notIn(ImConversationMembers::getFkClientId, imClientSender.getId())
);
if (membersList.isEmpty()) {
log.info("membersList为空,toConversationId:" + messageById.getFkConversationId());
return ApiResult.fail();
boolean b = this.updateById(messageById); }
// 遍历发送
for (ImConversationMembers conversationMembers : membersList) {
// // 保存收件箱
// long imInboxId = SnowflakeUtil.getId();
// ImInbox imInbox = new ImInbox();
// imInbox.setId(imInboxId);
// imInbox.setCreateTime(new Date());
// imInbox.setFkAppid(imApplication.getId());
// imInbox.setReceiver(conversationMembers.getFkClientId());
// imInbox.setFkMsgId(messageId);
// imInbox.setReadMsgStatus(0);
// imInbox.setReceiverMsgStatus(0);
// imInbox.setFkConversationId(toConversationId);
// imInboxService.save(imInbox);
// 查询接收方
ImClient imClientReceiver = imClientService.getOne(new QueryWrapper<ImClient>().lambda()
.eq(ImClient::getFkAppid, imApplication.getId())
.eq(ImClient::getId, conversationMembers.getFkClientId()));
if (imClientReceiver == null) {
continue;
}
// 封装响应的实体
ImMessageOnlineSend imMessageOnlineSend = new ImMessageOnlineSend();
BeanUtils.copyProperties(messageById, imMessageOnlineSend);
imMessageOnlineSend.setMsgId(messageById.getId());
imMessageOnlineSend.setSender(imClientSender.getClientId());
imMessageOnlineSend.setContent(null);
imMessageOnlineSend.setConversationId(conversationMembers.getFkConversationId());
imMessageOnlineSend.setWithdraw(Boolean.TRUE);
imMessageOnlineSend.setEvent(Boolean.TRUE);
// 向接收方推送
ResponseModel<ImMessageOnlineSend> responseModel = new ResponseModel<>();
responseModel.setCmd(ResponseModel.ONLINE_EVENT_MSG);
ApiResult<Boolean> result = ApiResult.result(ApiCode.SUCCESS);
responseModel.setCode(result.getCode());
responseModel.setMsg(result.getMessage());
responseModel.setData(imMessageOnlineSend);
responseModel.setReqId(null);
writeDataService.write(responseModel, imApplication.getAppKey(), imClientReceiver.getClientId());
// 获取自定义推送字段
PushModel pushModel = imMsgRecall.getPush();
// 异步推送系统通知消息
pushTask.push(pushModel, imClientReceiver, imApplication);
}
if (b) {
return ApiResult.ok(); return ApiResult.ok();
} else { } else {
......
package com.wecloud.im.ws.model.request; package com.wecloud.im.ws.model.request;
import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable; import java.io.Serializable;
...@@ -12,8 +10,6 @@ import java.io.Serializable; ...@@ -12,8 +10,6 @@ import java.io.Serializable;
* @Date 2019-12-05 * @Date 2019-12-05
*/ */
@Data @Data
@NoArgsConstructor
@AllArgsConstructor
public class PushModel implements Serializable { public class PushModel implements Serializable {
/** /**
......
...@@ -7,6 +7,7 @@ import com.wecloud.im.entity.ImApplication; ...@@ -7,6 +7,7 @@ import com.wecloud.im.entity.ImApplication;
import com.wecloud.im.entity.ImClient; import com.wecloud.im.entity.ImClient;
import com.wecloud.im.entity.ImIosApns; import com.wecloud.im.entity.ImIosApns;
import com.wecloud.im.push.PushUtils; import com.wecloud.im.push.PushUtils;
import com.wecloud.im.service.ImInboxService;
import com.wecloud.im.service.ImIosApnsService; import com.wecloud.im.service.ImIosApnsService;
import com.wecloud.im.ws.model.request.PushModel; import com.wecloud.im.ws.model.request.PushModel;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
...@@ -35,6 +36,10 @@ public class PushTask { ...@@ -35,6 +36,10 @@ public class PushTask {
@Autowired @Autowired
private ImIosApnsService imIosApnsService; private ImIosApnsService imIosApnsService;
@Autowired
private ImInboxService imInboxService;
/** /**
* 谷歌推送地址 * 谷歌推送地址
*/ */
...@@ -50,23 +55,23 @@ public class PushTask { ...@@ -50,23 +55,23 @@ public class PushTask {
*/ */
private static final String PUSH_BODY = "Click to view"; private static final String PUSH_BODY = "Click to view";
private static final String title = "title";
private static final String subTitle = "subTitle";
/** /**
* 异步系统推送 * 异步系统推送
* *
* @param imClientReceiver * @param imClientReceiver
*/ */
@Async @Async
public void push(HashMap<String, String> pushMap, ImClient imClientReceiver, ImApplication imApplication) { public void push(PushModel pushModel, ImClient imClientReceiver, ImApplication imApplication) {
log.info("push:" + imClientReceiver.getClientId()); log.info("push:" + imClientReceiver.getClientId());
PushModel pushModel = new PushModel(); if (pushModel == null) {
pushModel = new PushModel();
if (pushMap.isEmpty()) {
pushModel.setTitle(PUSH_TITLE); pushModel.setTitle(PUSH_TITLE);
pushModel.setSubTitle(PUSH_BODY); pushModel.setSubTitle(PUSH_BODY);
} else {
pushModel.setTitle(pushMap.get("title"));
pushModel.setSubTitle(pushMap.get("subTitle"));
} }
// 校验参数 // 校验参数
...@@ -89,6 +94,30 @@ public class PushTask { ...@@ -89,6 +94,30 @@ public class PushTask {
} }
} }
/**
* 异步系统推送
*
* @param imClientReceiver
*/
@Async
public void push(HashMap<String, String> pushMap, ImClient imClientReceiver, ImApplication imApplication) {
log.info("push:" + imClientReceiver.getClientId());
PushModel pushModel = new PushModel();
if (pushMap == null || pushMap.isEmpty()) {
pushModel.setTitle(PUSH_TITLE);
pushModel.setSubTitle(PUSH_BODY);
} else {
pushModel.setTitle(pushMap.get(title));
pushModel.setSubTitle(pushMap.get(subTitle));
}
this.push(pushModel, imClientReceiver, imApplication);
}
private void android(PushModel pushModel, ImClient imClientReceiver, ImApplication imApplication) { private void android(PushModel pushModel, ImClient imClientReceiver, ImApplication imApplication) {
// 安卓推送通道,友盟:1;firebase:2; 信鸽3 // 安卓推送通道,友盟:1;firebase:2; 信鸽3
if (imApplication.getAndroidPushChannel() == 1) { if (imApplication.getAndroidPushChannel() == 1) {
...@@ -207,7 +236,8 @@ public class PushTask { ...@@ -207,7 +236,8 @@ public class PushTask {
String deviceToken = imClientReceiver.getDeviceToken(); String deviceToken = imClientReceiver.getDeviceToken();
String alertTitle = pushModel.getTitle(); String alertTitle = pushModel.getTitle();
String alertBody = pushModel.getSubTitle(); String alertBody = pushModel.getSubTitle();
int badge = 1; // 统计未读消息数量
int badge = imInboxService.countMyNotReadCount(imClientReceiver.getId());
String topicBundleId = apns.getBundleId(); String topicBundleId = apns.getBundleId();
String certificatePassword = apns.getPwd(); String certificatePassword = apns.getPwd();
boolean contentAvailable = false; boolean contentAvailable = false;
......
...@@ -44,8 +44,8 @@ import java.util.List; ...@@ -44,8 +44,8 @@ import java.util.List;
public class ImConcreteReceiveStrategy extends AbstractReceiveStrategy { public class ImConcreteReceiveStrategy extends AbstractReceiveStrategy {
private static final String TO_CONVERSATION_KEY = "toConversation"; private static final String TO_CONVERSATION_KEY = "toConversation";
private static final String PUSH_KEY = "push"; public static final String PUSH_KEY = "push";
private static final String MSG_ID = "msgId"; public static final String MSG_ID = "msgId";
private static final JsonMapper JSON_MAPPER = new JsonMapper(); private static final JsonMapper JSON_MAPPER = new JsonMapper();
......
...@@ -7,6 +7,12 @@ ...@@ -7,6 +7,12 @@
id id
, create_time, update_time, fk_appid, attributes,device_type,valid , create_time, update_time, fk_appid, attributes,device_type,valid
</sql> </sql>
<update id="removeOldToken">
UPDATE im_client
SET device_token = NULL
WHERE device_token = #{deviceToken}
AND fk_appid = #{appId}
</update>
<select id="getImClientById" resultType="com.wecloud.im.param.ImClientQueryVo"> <select id="getImClientById" resultType="com.wecloud.im.param.ImClientQueryVo">
select select
......
...@@ -72,6 +72,25 @@ ...@@ -72,6 +72,25 @@
) AS r1 ) AS r1
WHERE members_count = 2 WHERE members_count = 2
</select> </select>
<select id="getRepetitionConversationAttributes" resultType="java.lang.Long">
SELECT *
FROM im_conversation
WHERE id IN (
SELECT im_conversation_members.fk_conversation_id
FROM im_conversation_members
INNER JOIN (SELECT *
FROM im_conversation_members
WHERE im_conversation_members.fk_client_id = #{clientId2}) AS im_conversation_members2
ON im_conversation_members.fk_conversation_id =
im_conversation_members2.fk_conversation_id
WHERE im_conversation_members.fk_client_id = #{clientId1}
)
AND attributes = CAST(#{attributes} AS json) LIMIT 1
</select>
<select id="getRepetitionConversationInfo" resultType="com.wecloud.im.entity.ImConversation"> <select id="getRepetitionConversationInfo" resultType="com.wecloud.im.entity.ImConversation">
SELECT im_conversation.* SELECT im_conversation.*
FROM im_conversation_members FROM im_conversation_members
......
...@@ -46,5 +46,11 @@ ...@@ -46,5 +46,11 @@
<include refid="Base_Column_List"/> <include refid="Base_Column_List"/>
from im_Inbox from im_Inbox
</select> </select>
<select id="countMyNotReadCount" resultType="java.lang.Integer">
SELECT COUNT(id)
FROM im_inbox
WHERE receiver = #{clientId}
AND receiver_msg_status = 0
</select>
</mapper> </mapper>
...@@ -15,10 +15,15 @@ spring-boot-plus: ...@@ -15,10 +15,15 @@ spring-boot-plus:
spring: spring:
datasource: datasource:
url: jdbc:mysql://localhost:3306/wecloud_im?serverTimezone=UTC&useUnicode=true&characterEncoding=utf8&useSSL=false&allowPublicKeyRetrieval=true url: jdbc:mysql://localhost:3306/wecloud_im_v1_3?serverTimezone=UTC&useUnicode=true&characterEncoding=utf8&useSSL=false&allowPublicKeyRetrieval=true
username: root username: root
password: 123 password: 123
#//测试外网
# url: jdbc:mysql://18.136.207.16:3306/wecloud_im?serverTimezone=UTC&useUnicode=true&characterEncoding=utf8&useSSL=false&allowPublicKeyRetrieval=true
# username: web
# password: axT8knPN5hAP
# Redis配置 # Redis配置
redis: redis:
database: 0 database: 0
......
...@@ -30,9 +30,20 @@ spring: ...@@ -30,9 +30,20 @@ spring:
# port: 6379 # port: 6379
# 飞蛙 # 飞蛙
# datasource:
# url: jdbc:mysql://127.0.0.1:3306/wecloud_im?serverTimezone=UTC&useUnicode=true&characterEncoding=utf8&useSSL=false&allowPublicKeyRetrieval=true
# username: web
# password: axT8knPN5hAP
# redis:
# database: 0
# host: 127.0.0.1
# password: JH86uc53r8Ca
# port: 6379
# 国内IM集成版
datasource: datasource:
url: jdbc:mysql://127.0.0.1:3306/wecloud_im?serverTimezone=UTC&useUnicode=true&characterEncoding=utf8&useSSL=false&allowPublicKeyRetrieval=true url: jdbc:mysql://127.0.0.1:3306/wecloud_im?serverTimezone=UTC&useUnicode=true&characterEncoding=utf8&useSSL=false&allowPublicKeyRetrieval=true
username: web username: root
password: axT8knPN5hAP password: axT8knPN5hAP
redis: redis:
database: 0 database: 0
......
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 443 ssl;
server_name xxx.com;
ssl_certificate ssl/_.im199.com.crt;
ssl_certificate_key ssl/_.im199.com.key;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
location /api {
proxy_pass http://localhost:8082/api/;
}
location /ws {
proxy_pass http://localhost:8899/ws; # ws结尾不带"/",实际请求服务器时不会去掉"/ws"
proxy_set_header Upgrade $http_upgrade; # 升级协议头
proxy_set_header Connection upgrade; # 升级长连接协议头
}
location / {
root html;
index index.html index.htm;
}
}
\ No newline at end of file
...@@ -76,3 +76,26 @@ Invoke-RestMethod http://169.254.169.254/latest/meta-data/public-ipv4 ...@@ -76,3 +76,26 @@ Invoke-RestMethod http://169.254.169.254/latest/meta-data/public-ipv4
load-blance: load-blance:
服务器配置 Local,AWS,AlibabaCloud,HuaweiCloud 服务器配置 Local,AWS,AlibabaCloud,HuaweiCloud
server-type: Local server-type: Local
2021年09月27日17:00:50部署国内IM集成版
部署1.3 版本
| weikeyun_imapi | 121.37.208.9 | 国内IM集成版
docker run -p 6379:6379 -d --restart=always --name redis6 -v $PWD/dockerData/redis6:/data redis:6 --appendonly yes --requirepass "axT8knPN5hAP"
##mysql5.7(如果本地不开,可以连上测试环境)
### docker 安装mysql
docker run -p 3306:3306 --name mysql57 -v $PWD/dockerData/mysql57/data:/var/lib/mysql --restart always -e MYSQL_ROOT_PASSWORD=JH86uc53r8Ca -d mysql:5.7
mysql
username: root
password: axT8knPN5hAP
redis:
database: 0
host: 127.0.0.1
password: JH86uc53r8Ca
port: 6379
utf8mb4_unicode_ci
建库语句
CREATE DATABASE IF NOT EXISTS wecloud_im DEFAULT CHARSET utf8mb4 COLLATE utf8mb4_general_ci;
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