Commit f06103ed authored by chenyongfeng's avatar chenyongfeng

初始化

parent e6c090eb
Pipeline #21464 failed with stages
in 1 minute 11 seconds
......@@ -162,6 +162,11 @@
<artifactId>commons-collections4</artifactId>
<version>4.4</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>transmittable-thread-local</artifactId>
<version>2.2.0</version>
</dependency>
</dependencies>
<build>
......
......@@ -5,9 +5,10 @@ import java.util.concurrent.ThreadLocalRandom;
import javax.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import io.github.doocs.im.config.ImConfig;
import io.github.doocs.im.config.SourceHolder;
import io.github.doocs.im.core.Account;
import io.github.doocs.im.core.Group;
import io.github.doocs.im.core.Member;
......@@ -17,24 +18,21 @@ import io.github.doocs.im.core.Profile;
import io.github.doocs.im.core.RecentContact;
import io.github.doocs.im.core.Sns;
import io.github.doocs.im.util.SigUtil;
import lombok.extern.slf4j.Slf4j;
/**
* @author hyh
* @since 2021/07/29 16:11
*/
@Component
@Slf4j
public class ImClient {
@Value("${sdkAppId}")
private Long sdkAppId;
@Value("${key}")
private String key;
@Value("${userId}")
private String userId;
@Autowired
ImConfig imConfig;
@Autowired
private ClientConfiguration config;
private String userSig;
// private String userSig;
private long userSigExpireTs;
private static final String VERSION = "v4";
......@@ -50,10 +48,10 @@ public class ImClient {
public Operation operation;
public RecentContact recentContact;
// public ImClient(long sdkAppId, String userId, String key) {
//
//
// }
// public ImClient(long sdkAppId, String userId, String key) {
//
//
// }
// private static final ClientConfiguration DEFAULT_CONFIG = new ClientConfiguration();
......@@ -91,7 +89,7 @@ public class ImClient {
@PostConstruct
public void initMethod() {
this.userSig = SigUtil.genUserSig(sdkAppId, key, userId, config.getExpireTime());
// this.userSig = SigUtil.genUserSig(sdkAppId, key, userId, config.getExpireTime());
this.userSigExpireTs = System.currentTimeMillis() / 1000 + config.getExpireTime() - 100;
account = new Account(this);
......@@ -105,18 +103,35 @@ public class ImClient {
}
private String getUserSig() {
ImConfig.Config currentSourceParamMap = getCurrentSourceParamMap();
Long sdkAppId = currentSourceParamMap.getSdkAppId();
String key = currentSourceParamMap.getKey();
String userId = currentSourceParamMap.getUserId();
if (config.isAutoRenewSig()) {
long currentTs = System.currentTimeMillis() / 1000;
if (currentTs >= userSigExpireTs) {
synchronized (this) {
if (currentTs >= userSigExpireTs) {
userSig = SigUtil.genUserSig(sdkAppId, key, userId, config.getExpireTime());
userSigExpireTs = currentTs + config.getExpireTime() - 100;
return SigUtil.genUserSig(sdkAppId, key, userId, config.getExpireTime());
}
}
}
}
return userSig;
return SigUtil.genUserSig(sdkAppId, key, userId, config.getExpireTime());
}
public ImConfig.Config getCurrentSourceParamMap() {
String local = SourceHolder.getLocal();
for (ImConfig.Config imConfigConfig : imConfig.getConfigs()) {
if (imConfigConfig.getSource().equals(local)) {
return imConfigConfig;
}
}
return null;
}
public ClientConfiguration getConfig() {
......@@ -124,9 +139,14 @@ public class ImClient {
}
public String getUrl(String serviceName, String command) {
ImConfig.Config currentSourceParamMap = getCurrentSourceParamMap();
Long sdkAppId = currentSourceParamMap.getSdkAppId();
String userId = currentSourceParamMap.getUserId();
String sig = getUserSig();
long random = ThreadLocalRandom.current().nextLong(0, 0x100000000L);
return String.format(FORMAT_URL, VERSION, serviceName, command, sdkAppId, userId, sig, random);
String format = String.format(FORMAT_URL, VERSION, serviceName, command, sdkAppId, userId, sig, random);
log.info("请求路径:{}", format);
return format;
}
public Account getAccount() {
......
......@@ -47,7 +47,10 @@ public enum ErrorEnum {
BINDTYPE_ERROR("30027","已绑定身份!"),
PAYMENT_ERROR("30028","订单已确认收款,不能重复提交!"),
RESERVE_ERROR("30029","您已在该时段预约,不能重复提交!"),
NULL_TIMEZONE_ERROR("30030","时区不可为空!!");
SOURCE_NAME_NULL_ERROR("30030","平台名称不可为空!"),
SOURCE_NOT_OPEN_ERROR("30031","未对平台开放im!");
private String code;
private String msg;
......
......@@ -12,6 +12,8 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import com.alibaba.ttl.threadpool.TtlExecutors;
@Configuration
public class ExecutorConfig {
......@@ -32,6 +34,8 @@ public class ExecutorConfig {
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
// 执行初始化
executor.initialize();
return executor;
return TtlExecutors.getTtlExecutor(executor);
}
}
package io.github.doocs.im.config;
import java.util.List;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import lombok.Data;
@Configuration
@Data
@ConfigurationProperties(prefix = "param")
public class ImConfig {
private List<Config> configs;
@Data
public static class Config {
private Long sdkAppId;
private String key;
private String userId;
private String source;
}
}
package io.github.doocs.im.config;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import com.alibaba.ttl.TransmittableThreadLocal;
import com.alibaba.ttl.threadpool.TtlExecutors;
public class SourceHolder {
private static final ThreadLocal<String> STRING_THREAD_LOCAL = new TransmittableThreadLocal<>();
public static void setLocal(String source) {
STRING_THREAD_LOCAL.set(source);
}
public static String getLocal() {
return STRING_THREAD_LOCAL.get();
}
public static void removeLocal() {
STRING_THREAD_LOCAL.remove();
}
}
package io.github.doocs.im.config;
import java.util.List;
import java.util.stream.Collectors;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import lombok.extern.slf4j.Slf4j;
/**
* 拦截器
*/
@Slf4j
@Configuration
public class SourceInterceptor implements HandlerInterceptor {
@Autowired
ImConfig imConfig;
/**
* 在请求处理之前进行调用(Controller方法调用之前)
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
String header = request.getHeader("source-im");
if (StringUtils.isBlank(header)) {
throw new BusinessException(ErrorEnum.SOURCE_NAME_NULL_ERROR);
}
List<ImConfig.Config> configs = imConfig.getConfigs();
List<String> sourceList = configs.stream().map(ImConfig.Config::getSource).collect(Collectors.toList());
if (!sourceList.contains(header)) {
throw new BusinessException(ErrorEnum.SOURCE_NOT_OPEN_ERROR);
}
SourceHolder.setLocal(header);
return true;
}
/**
* 请求处理之后进行调用,但是在视图被渲染之前(Controller方法调用之后)
*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) {
// System.out.println("执行了TestInterceptor的postHandle方法");
}
/**
* 在整个请求结束之后被调用,也就是在DispatcherServlet 渲染了对应的视图之后执行(主要是用于进行资源清理工作)
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,
Exception ex) {
SourceHolder.removeLocal();
}
}
\ No newline at end of file
......@@ -3,8 +3,11 @@ package io.github.doocs.im.config;
import java.text.SimpleDateFormat;
import java.util.TimeZone;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import com.fasterxml.jackson.databind.DeserializationFeature;
......@@ -16,8 +19,10 @@ import com.fasterxml.jackson.databind.SerializationFeature;
*
* @author WebJsonConverterConfig
*/
// @Configuration
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Autowired
SourceInterceptor sourceInterceptor;
@Bean
public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() {
MappingJackson2HttpMessageConverter jackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter();
......@@ -30,8 +35,8 @@ public class WebConfig implements WebMvcConfigurer {
return jackson2HttpMessageConverter;
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(sourceInterceptor).addPathPatterns("/**");
}
}
......@@ -9,9 +9,13 @@ import io.github.doocs.im.config.CommonResult;
import io.github.doocs.im.model.request.AddGroupMemberRequest;
import io.github.doocs.im.model.request.CreateGroupRequest;
import io.github.doocs.im.model.request.DeleteGroupMemberRequest;
import io.github.doocs.im.model.request.DeleteGroupMsgBySenderRequest;
import io.github.doocs.im.model.request.DestroyGroupRequest;
import io.github.doocs.im.model.request.GroupMsgGetSimpleRequest;
import io.github.doocs.im.model.request.GroupMsgRecallRequest;
import io.github.doocs.im.model.request.ModifyGroupBaseInfoRequest;
import io.github.doocs.im.model.request.SendGroupMsgRequest;
import io.github.doocs.im.model.request.SendGroupSystemNotificationRequest;
import io.github.doocs.im.model.request.SetUnreadMsgNumRequest;
import io.github.doocs.im.servie.GroupService;
......@@ -103,6 +107,7 @@ public class GroupController {
/**
* 管理员撤回群消息
*
* @param groupMsgRecallRequest
* @return
*/
......@@ -110,4 +115,51 @@ public class GroupController {
public CommonResult groupMsgRecall(@RequestBody GroupMsgRecallRequest groupMsgRecallRequest) {
return groupService.groupMsgRecall(groupMsgRecallRequest);
}
/**
* 管理员撤回指定用户信息
*
* @param deleteGroupMsgBySenderRequest
* @return
*/
@RequestMapping("/deleteGroupMsgBySender")
public CommonResult
deleteGroupMsgBySender(@RequestBody DeleteGroupMsgBySenderRequest deleteGroupMsgBySenderRequest) {
return groupService.deleteGroupMsgBySender(deleteGroupMsgBySenderRequest);
}
/**
* 拉取群历史消息
*
* @param groupMsgGetSimpleRequest
* @return
*/
@RequestMapping("/groupMsgGetSimple")
public CommonResult groupMsgGetSimple(@RequestBody GroupMsgGetSimpleRequest groupMsgGetSimpleRequest) {
return groupService.groupMsgGetSimple(groupMsgGetSimpleRequest);
}
/**
* 发送群系统消息
*
* @param sendGroupSystemNotificationRequest
* @return
*/
@RequestMapping("/sendGroupSystemNotification")
public CommonResult sendGroupSystemNotification(
@RequestBody SendGroupSystemNotificationRequest sendGroupSystemNotificationRequest) {
return groupService.sendGroupSystemNotification(sendGroupSystemNotificationRequest);
}
/**
* 发送基础群消息
* @param sendGroupMsgRequest
* @return
*/
@RequestMapping("/sendGroupMsg")
public CommonResult sendGroupMsg(@RequestBody SendGroupMsgRequest sendGroupMsgRequest) {
return groupService.sendGroupMsg(sendGroupMsgRequest);
}
}
package io.github.doocs.im.controller;
import com.fasterxml.jackson.core.JsonProcessingException;
import io.github.doocs.im.servie.MessageService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
......@@ -9,6 +7,11 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import io.github.doocs.im.config.CommonResult;
import io.github.doocs.im.model.request.AdminGetRoamMsgRequest;
import io.github.doocs.im.model.request.AdminMsgWithdrawRequest;
import io.github.doocs.im.model.request.AdminSetMsgReadRequest;
import io.github.doocs.im.model.request.GetC2cUnreadMsgRequest;
import io.github.doocs.im.servie.MessageService;
import io.github.doocs.im.vo.SimpleMessageVO;
@RestController
......@@ -17,21 +20,78 @@ public class MessageController {
@Autowired
MessageService messageService;
/**
* 发送消息
*
* @param simpleMessageVO
* @return
* @throws Exception
*/
@PostMapping("/sendMessage")
public CommonResult sendMessage(@RequestBody SimpleMessageVO simpleMessageVO) throws JsonProcessingException {
public CommonResult sendMessage(@RequestBody SimpleMessageVO simpleMessageVO) throws Exception {
return messageService.sendMessage(simpleMessageVO);
}
/**
* 以管理员身份获取会话记录 查询消息
*
* @param adminGetRoamMsgRequest
* @return
* @throws Exception
*/
@PostMapping("/getRoamMsg")
public CommonResult getRoamMsg(@RequestBody AdminGetRoamMsgRequest adminGetRoamMsgRequest) throws Exception {
return messageService.getRoamMsg(adminGetRoamMsgRequest);
}
/**
* 撤回单聊消息
*
* @param adminMsgWithdrawRequest
* @return
* @throws Exception
*/
@PostMapping("/msgWithdraw")
public CommonResult msgWithdraw(@RequestBody AdminMsgWithdrawRequest adminMsgWithdrawRequest) throws Exception {
return messageService.msgWithdraw(adminMsgWithdrawRequest);
}
/**
* 设置单聊信息已读
*
* @param adminSetMsgReadRequest
* @return
* @throws Exception
*/
@PostMapping("/setMsgRead")
public CommonResult setMsgRead(@RequestBody AdminSetMsgReadRequest adminSetMsgReadRequest) throws Exception {
return messageService.setMsgRead(adminSetMsgReadRequest);
}
/**
* 查询未读消息数 总数或者各个单聊未读数
*
* @param getC2cUnreadMsgRequest
* @return
* @throws Exception
*/
@PostMapping("/getC2cUnreadMsgNum")
public CommonResult getC2cUnreadMsgNum(@RequestBody GetC2cUnreadMsgRequest getC2cUnreadMsgRequest)
throws Exception {
return messageService.getC2cUnreadMsgNum(getC2cUnreadMsgRequest);
}
// public static void main(String[] args) {
// String a = "https://img14.360buyimg.com/pop/jfs/t1/181251/30/8749/184198/60c32b0bEbe5d7052/dc859b8261fb7c8b.jpg";
// int length = a.length();
// System.out.println(length);
// }
// public static void main(String[] args) {
// String a = "https://img14.360buyimg.com/pop/jfs/t1/181251/30/8749/184198/60c32b0bEbe5d7052/dc859b8261fb7c8b.jpg";
// int length = a.length();
// System.out.println(length);
// }
}
......@@ -318,7 +318,7 @@ public class Group {
}
/**
* 拉取群成员
* 拉取群成员历史消息
*
* @param groupMsgGetSimpleRequest 请求参数
* @return 结果
......
......@@ -21,7 +21,7 @@ public class AndroidInfo {
@JsonProperty("OPPOChannelID")
private String oppoChannelId;
@JsonProperty("OPPOChannelID")
@JsonProperty("GoogleChannelID")
private String googleChannelId;
@JsonProperty("VIVOClassification")
......
......@@ -13,7 +13,7 @@ public class GroupMsgGetSimpleRequest extends GenericRequest {
private String groupId;
@JsonProperty("ReqMsgSeq")
private Integer reqMsgSeq;
private Long reqMsgSeq;
@JsonProperty("ReqMsgNumber")
private Integer reqMsgNumber;
......@@ -26,7 +26,7 @@ public class GroupMsgGetSimpleRequest extends GenericRequest {
this.reqMsgNumber = reqMsgNumber;
}
public GroupMsgGetSimpleRequest(String groupId, Integer reqMsgSeq, Integer reqMsgNumber) {
public GroupMsgGetSimpleRequest(String groupId, Long reqMsgSeq, Integer reqMsgNumber) {
this.groupId = groupId;
this.reqMsgSeq = reqMsgSeq;
this.reqMsgNumber = reqMsgNumber;
......@@ -50,11 +50,11 @@ public class GroupMsgGetSimpleRequest extends GenericRequest {
this.groupId = groupId;
}
public Integer getReqMsgSeq() {
public Long getReqMsgSeq() {
return reqMsgSeq;
}
public void setReqMsgSeq(Integer reqMsgSeq) {
public void setReqMsgSeq(Long reqMsgSeq) {
this.reqMsgSeq = reqMsgSeq;
}
......@@ -69,7 +69,7 @@ public class GroupMsgGetSimpleRequest extends GenericRequest {
public static final class Builder {
private String groupId;
private Integer reqMsgSeq;
private Long reqMsgSeq;
private Integer reqMsgNumber;
private Builder() {
......@@ -84,7 +84,7 @@ public class GroupMsgGetSimpleRequest extends GenericRequest {
return this;
}
public Builder reqMsgSeq(Integer reqMsgSeq) {
public Builder reqMsgSeq(Long reqMsgSeq) {
this.reqMsgSeq = reqMsgSeq;
return this;
}
......
......@@ -2,7 +2,9 @@ package io.github.doocs.im.model.request;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.google.common.collect.Lists;
import io.github.doocs.im.model.message.TIMMsgElement;
import io.github.doocs.im.util.RandomUtil;
import java.util.List;
......@@ -16,7 +18,7 @@ public class SendGroupMsgRequest extends GenericRequest {
private String groupId;
@JsonProperty("Random")
private Integer random;
private Integer random = Integer.parseInt(RandomUtil.getRandomNum(8));
@JsonProperty("MsgPriority")
private String msgPriority;
......@@ -36,8 +38,8 @@ public class SendGroupMsgRequest extends GenericRequest {
@JsonProperty("OnlineOnlyFlag")
private Integer onlineOnlyFlag;
@JsonProperty("SendMsgControl")
private List<String> sendMsgControl;
@JsonProperty("SendMsgControl") // 如果消息中指定 SendMsgControl,设置 NoLastMsg 的情况下,表示不更新最近联系人会话;NoUnread 不计未读,只对单条消息有效
private List<String> sendMsgControl= Lists.newArrayList("NoLastMsg","NoUnread");
@JsonProperty("cloudCustomData")
private String cloudCustomData;
......
package io.github.doocs.im.model.response;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.springframework.data.annotation.Id;
import java.util.List;
......@@ -9,6 +10,9 @@ import java.util.List;
* @since 2021/08/01 13:35
*/
public class GroupMsgGetSimpleResult extends GenericResult {
@Id
private String id;
@JsonProperty("GroupId")
private String groupId;
......@@ -42,6 +46,14 @@ public class GroupMsgGetSimpleResult extends GenericResult {
this.rspMsgList = rspMsgList;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
@Override
public String toString() {
return "GroupMsgGetSimpleResult{" +
......
package io.github.doocs.im.model.response;
import java.util.List;
import org.springframework.data.annotation.Id;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.github.doocs.im.model.message.TIMMsgElement;
import java.util.List;
import io.github.doocs.im.model.message.TIMMsgElement;
/**
* @author hyh
* @since 2021/07/28 20:07
*/
public class MsgListItem {
@Id
private String id;
@JsonProperty("From_Account")
private String fromAccount;
......@@ -115,6 +121,14 @@ public class MsgListItem {
this.cloudCustomData = cloudCustomData;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
@Override
public String toString() {
return "MsgListItem{" +
......
......@@ -13,7 +13,7 @@ public class SendGroupMsgResult extends GenericResult {
/**
* 消息序列号,用于标记该条消息,数据范围 [0,4294967295]
*/
@JsonProperty("msgSeq")
@JsonProperty("MsgSeq")
private Long msgSeq;
public Integer getMsgTime() {
......
......@@ -22,10 +22,14 @@ public class AccountEntity {
// 时间
private long updateTime = System.currentTimeMillis();
public AccountEntity(String id, String nick, String faceUrl,int status) {
private String source;
public AccountEntity(String id, String nick, String faceUrl,int status,String source) {
this.id = id;
this.nick = nick;
this.faceUrl = faceUrl;
this.status = status;
this.source = source;
}
}
......@@ -99,7 +99,7 @@ public class AccountService extends GeneraService {
executor.execute(() -> {
// int i = 2 / 0; 异步线程的异常不会在主线程被捕获
AccountEntity accountEntity = new AccountEntity(accountVO.getSource() + "_" + accountVO.getOriginalId(),
accountVO.getNick(), accountVO.getFaceUrl(), 1); // 有效
accountVO.getNick(), accountVO.getFaceUrl(), 1, accountVO.getSource()); // 有效
try {
mongoTemplate.save(accountEntity);
......
......@@ -17,6 +17,8 @@ public abstract class GeneraService {
@Autowired
Executor executor;
ObjectMapper mapper = new ObjectMapper();
@Autowired
MessageRecordMongoService messageRecordMongoService;
}
......@@ -18,16 +18,24 @@ import io.github.doocs.im.core.Group;
import io.github.doocs.im.model.request.AddGroupMemberRequest;
import io.github.doocs.im.model.request.CreateGroupRequest;
import io.github.doocs.im.model.request.DeleteGroupMemberRequest;
import io.github.doocs.im.model.request.DeleteGroupMsgBySenderRequest;
import io.github.doocs.im.model.request.DestroyGroupRequest;
import io.github.doocs.im.model.request.GroupMsgGetSimpleRequest;
import io.github.doocs.im.model.request.GroupMsgRecallRequest;
import io.github.doocs.im.model.request.ModifyGroupBaseInfoRequest;
import io.github.doocs.im.model.request.SendGroupMsgRequest;
import io.github.doocs.im.model.request.SendGroupSystemNotificationRequest;
import io.github.doocs.im.model.request.SetUnreadMsgNumRequest;
import io.github.doocs.im.model.response.AddGroupMemberResult;
import io.github.doocs.im.model.response.CreateGroupResult;
import io.github.doocs.im.model.response.DeleteGroupMemberResult;
import io.github.doocs.im.model.response.DeleteGroupMsgBySenderResult;
import io.github.doocs.im.model.response.DestroyGroupResult;
import io.github.doocs.im.model.response.GroupMsgGetSimpleResult;
import io.github.doocs.im.model.response.GroupMsgRecallResult;
import io.github.doocs.im.model.response.ModifyGroupBaseInfoResult;
import io.github.doocs.im.model.response.SendGroupMsgResult;
import io.github.doocs.im.model.response.SendGroupSystemNotificationResult;
import io.github.doocs.im.model.response.SetUnreadMsgNumResult;
import lombok.extern.slf4j.Slf4j;
......@@ -50,6 +58,8 @@ public class GroupService extends GeneraService {
if (ActionStatus.OK.equalsIgnoreCase(actionStatus)) {
HashMap<String, Object> result = Maps.newHashMap();
result.put("groupId", groupResult.getGroupId());
// 这里生成mongo 群组数据 防止在发送消息的时候创建数据存在并发问题
messageRecordMongoService.saveGroup(groupResult.getGroupId());
return CommonResult.success(result);
}
return CommonResult
......@@ -163,7 +173,7 @@ public class GroupService extends GeneraService {
log.error("请求qcloud失败,参数:{}", JSON.toJSONString(groupMsgRecallRequest));
throw new BusinessException(ErrorEnum.REQUEST_ERROR);
}
log.info("返回结果:{}",groupMsgRecallResult.toString());
log.info("返回结果:{}", groupMsgRecallResult.toString());
String actionStatus = groupMsgRecallResult.getActionStatus();
if (ActionStatus.OK.equalsIgnoreCase(actionStatus)) {
return CommonResult.success(groupMsgRecallResult.getRecallRetList());
......@@ -171,4 +181,93 @@ public class GroupService extends GeneraService {
return CommonResult.fail(
new CommonError(String.valueOf(groupMsgRecallResult.getErrorCode()), groupMsgRecallResult.getErrorInfo()));
}
public CommonResult deleteGroupMsgBySender(DeleteGroupMsgBySenderRequest deleteGroupMsgBySenderRequest) {
Group group = imClient.getGroup();
DeleteGroupMsgBySenderResult deleteGroupMsgBySenderResult;
try {
deleteGroupMsgBySenderResult = group.deleteGroupMsgBySender(deleteGroupMsgBySenderRequest);
} catch (Exception e) {
log.error("请求qcloud失败,参数:{}", JSON.toJSONString(deleteGroupMsgBySenderRequest));
throw new BusinessException(ErrorEnum.REQUEST_ERROR);
}
log.info("返回结果:{}", deleteGroupMsgBySenderResult.toString());
String actionStatus = deleteGroupMsgBySenderResult.getActionStatus();
if (ActionStatus.OK.equalsIgnoreCase(actionStatus)) {
return CommonResult.success();
}
return CommonResult.fail(new CommonError(String.valueOf(deleteGroupMsgBySenderResult.getErrorCode()),
deleteGroupMsgBySenderResult.getErrorInfo()));
}
public CommonResult groupMsgGetSimple(GroupMsgGetSimpleRequest groupMsgGetSimpleRequest) {
Group group = imClient.getGroup();
GroupMsgGetSimpleResult groupMsgGetSimpleResult = null;
try {
groupMsgGetSimpleResult = group.groupMsgGetSimple(groupMsgGetSimpleRequest);
} catch (Exception e) {
log.error("请求qcloud失败,参数:{}", JSON.toJSONString(groupMsgGetSimpleResult));
throw new BusinessException(ErrorEnum.REQUEST_ERROR);
}
log.info("返回结果:{}", groupMsgGetSimpleResult.toString());
String actionStatus = groupMsgGetSimpleResult.getActionStatus();
if (ActionStatus.OK.equalsIgnoreCase(actionStatus)) {
HashMap<String, Object> objectObjectHashMap = Maps.newHashMap();
objectObjectHashMap.put("GroupId", groupMsgGetSimpleResult.getGroupId());
objectObjectHashMap.put("IsFinished", groupMsgGetSimpleResult.getIsFinished());
objectObjectHashMap.put("RspMsgList", groupMsgGetSimpleResult.getRspMsgList());
return CommonResult.success(objectObjectHashMap);
}
return CommonResult.fail(new CommonError(String.valueOf(groupMsgGetSimpleResult.getErrorCode()),
groupMsgGetSimpleResult.getErrorInfo()));
}
public CommonResult
sendGroupSystemNotification(SendGroupSystemNotificationRequest sendGroupSystemNotificationRequest) {
Group group = imClient.getGroup();
SendGroupSystemNotificationResult sendGroupSystemNotificationResult;
try {
sendGroupSystemNotificationResult = group.sendGroupSystemNotification(sendGroupSystemNotificationRequest);
} catch (Exception e) {
log.error("请求qcloud失败,参数:{}", JSON.toJSONString(sendGroupSystemNotificationRequest));
throw new BusinessException(ErrorEnum.REQUEST_ERROR);
}
log.info("返回结果:{}", sendGroupSystemNotificationResult.toString());
String actionStatus = sendGroupSystemNotificationResult.getActionStatus();
if (ActionStatus.OK.equalsIgnoreCase(actionStatus)) {
HashMap<String, Object> objectObjectHashMap = Maps.newHashMap();
return CommonResult.success(objectObjectHashMap);
}
return CommonResult.fail(new CommonError(String.valueOf(sendGroupSystemNotificationResult.getErrorCode()),
sendGroupSystemNotificationResult.getErrorInfo()));
}
public CommonResult sendGroupMsg(SendGroupMsgRequest sendGroupMsgRequest) {
Group group = imClient.getGroup();
SendGroupMsgResult sendGroupMsgResult;
try {
sendGroupMsgResult = group.sendGroupMsg(sendGroupMsgRequest);
} catch (Exception e) {
log.error("请求qcloud失败,参数:{}", JSON.toJSONString(sendGroupMsgRequest), e);
throw new BusinessException(ErrorEnum.REQUEST_ERROR);
}
log.info("返回结果:{}", sendGroupMsgResult.toString());
String actionStatus = sendGroupMsgResult.getActionStatus();
if (ActionStatus.OK.equalsIgnoreCase(actionStatus)) {
// 保存到消息记录
messageRecordMongoService.saveGroupMessageRecord(sendGroupMsgRequest.getGroupId(),
sendGroupMsgResult.getMsgSeq());
HashMap<String, Object> objectObjectHashMap = Maps.newHashMap();
// "MsgTime": 1497249503,
// "MsgSeq": 1
objectObjectHashMap.put("MsgTime", sendGroupMsgResult.getMsgTime());
objectObjectHashMap.put("MsgSeq", sendGroupMsgResult.getMsgSeq());
return CommonResult.success(objectObjectHashMap);
}
return CommonResult.fail(
new CommonError(String.valueOf(sendGroupMsgResult.getErrorCode()), sendGroupMsgResult.getErrorInfo()));
}
}
package io.github.doocs.im.servie;
import java.util.List;
import java.util.Optional;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.mongodb.client.result.UpdateResult;
import io.github.doocs.im.ImClient;
import io.github.doocs.im.config.SourceHolder;
import io.github.doocs.im.core.Group;
import io.github.doocs.im.core.Message;
import io.github.doocs.im.model.request.AdminGetRoamMsgRequest;
import io.github.doocs.im.model.request.GroupMsgGetSimpleRequest;
import io.github.doocs.im.model.response.AdminRoamMsgResult;
import io.github.doocs.im.model.response.GroupMsgGetSimpleResult;
import io.github.doocs.im.model.response.MsgListItem;
import io.github.doocs.im.model.response.RspMsgItem;
import lombok.extern.slf4j.Slf4j;
@Service
@Slf4j
public class MessageRecordMongoService extends GeneraService {
@Autowired
ImClient imClient;
public void saveMessageRecord(String msgKey, int timestamp, String fromAccount, String toAccount) {
executor.execute(() -> {
AdminGetRoamMsgRequest request = new AdminGetRoamMsgRequest();
request.setFromAccount(fromAccount);
request.setToAccount(toAccount);
request.setMinTime(timestamp - 1);
request.setMaxTime(timestamp + 1);
request.setMaxCnt(3);
Message message = imClient.getMessage();
AdminRoamMsgResult roamMsg;
try {
roamMsg = message.getRoamMsg(request);
} catch (Exception e) {
log.error("拉取单聊记录-->请求qcloud失败,参数:{}", JSON.toJSONString(request), e);
return;
}
String actionStatus = roamMsg.getActionStatus();
if ("OK".equalsIgnoreCase(actionStatus)) {
List<MsgListItem> msgList = roamMsg.getMsgList();
Optional<MsgListItem> first =
msgList.stream().filter(msgListItem -> msgKey.equals(msgListItem.getMsgKey())).findFirst();
first.map((one) -> {
one.setId(one.getMsgKey());
return mongoTemplate.save(one, "message_record" + "_" + SourceHolder.getLocal());
}).orElseGet(() -> {
log.error("msgkey:{}不存在");
return null;
});
return;
}
log.error("获取单聊消息记录失败,请求参数:{}", JSON.toJSONString(request));
});
}
public void updateMessageRecord(String msgKey) {
executor.execute(() -> {
try {
UpdateResult updateResult = mongoTemplate.updateFirst(Query.query(Criteria.where("_id").is(msgKey)),
Update.update("msgFlagBits", 8), "message_record" + "_" + SourceHolder.getLocal());
long modifiedCount = updateResult.getModifiedCount();
// 修改为0 可能是这条消息没写入数据成功,也有可能是线程调度落后于此线程 也可能已经是失效 需要保存在错误信息中 手动处理
if (modifiedCount == 0) {
JSONObject jsonObject = new JSONObject();
jsonObject.put("_id", msgKey);
jsonObject.put("msg", "撤回同步失败");
mongoTemplate.save(jsonObject, "message_record_error" + "_" + SourceHolder.getLocal());
}
} catch (Exception e) {
log.error("修改消息撤回状态失败,请求参数:{}", msgKey, e);
}
});
}
public void saveGroupMessageRecord(String groupId, long msgSeq) {
executor.execute(() -> {
Group group = imClient.getGroup();
GroupMsgGetSimpleRequest groupMsgGetSimpleRequest = new GroupMsgGetSimpleRequest();
groupMsgGetSimpleRequest.setGroupId(groupId);
// groupMsgGetSimpleRequest.setReqMsgSeq(msgSeq + 1);
groupMsgGetSimpleRequest.setReqMsgNumber(1);
GroupMsgGetSimpleResult groupMsgGetSimpleResult = null;
try {
groupMsgGetSimpleResult = group.groupMsgGetSimple(groupMsgGetSimpleRequest);
} catch (Exception e) {
log.error("拉取群聊记录-->请求qcloud失败,参数:{}", JSON.toJSONString(groupMsgGetSimpleRequest), e);
return;
}
String actionStatus = groupMsgGetSimpleResult.getActionStatus();
if ("OK".equalsIgnoreCase(actionStatus)) {
List<RspMsgItem> rspMsgList = groupMsgGetSimpleResult.getRspMsgList();
if (CollectionUtils.isNotEmpty(rspMsgList)) {
Optional<RspMsgItem> first =
rspMsgList.stream().filter(rspMsgItem -> rspMsgItem.getMsgSeq() == msgSeq).findFirst();
first.ifPresent(rspMsgItem -> {
// 群组已经创建 更新记录即可
Update update = new Update();
update.addToSet("rspMsgList", rspMsgItem);
mongoTemplate.updateFirst(Query.query(Criteria.where("_id").is(groupId)), update,
"group_record_" + SourceHolder.getLocal());
});
if (!first.isPresent()) {
log.error("查询最新消息未拉取到匹配msgseq的群组历史消息,参数:{}", JSON.toJSONString(groupMsgGetSimpleRequest));
// 说明最新的不是刚发的 这时可以通过msgseq 取到消息
groupMsgGetSimpleRequest.setReqMsgSeq(msgSeq + 1);
try {
groupMsgGetSimpleResult = group.groupMsgGetSimple(groupMsgGetSimpleRequest);
} catch (Exception e) {
log.error("拉取群聊记录-->请求qcloud失败,参数:{}", JSON.toJSONString(groupMsgGetSimpleRequest), e);
return;
}
if ("OK".equalsIgnoreCase(groupMsgGetSimpleResult.getActionStatus())) {
List<RspMsgItem> rspMsgList1 = groupMsgGetSimpleResult.getRspMsgList();
if (CollectionUtils.isNotEmpty(rspMsgList1)) {
Optional<RspMsgItem> first1 = rspMsgList1.stream()
.filter(rspMsgItem -> rspMsgItem.getMsgSeq() == msgSeq).findFirst();
first1.ifPresent(rspMsgItem -> {
// 群组已经创建 更新记录即可
Update update = new Update();
update.addToSet("rspMsgList", rspMsgItem);
mongoTemplate.updateFirst(Query.query(Criteria.where("_id").is(groupId)), update,
"group_record_" + SourceHolder.getLocal());
});
if (!first1.isPresent()) {
log.error("查询最新消息未拉取到匹配msgseq的群组历史消息,参数:{}",
JSON.toJSONString(groupMsgGetSimpleRequest));
}
} else {
// 结果集为空
log.error("拉取群组历史消息结果为空,参数:{}", JSON.toJSONString(groupMsgGetSimpleRequest));
}
} else {
// 请求返回错误结果
log.error("拉取群组历史消息返回错误信息,参数:{}", JSON.toJSONString(groupMsgGetSimpleRequest));
}
}
} else {
// 结果集为空
log.error("拉取群组历史消息结果为空,参数:{}", JSON.toJSONString(groupMsgGetSimpleRequest));
}
} else {
// 请求返回错误结果
log.error("拉取群组历史消息返回错误信息,参数:{}", JSON.toJSONString(groupMsgGetSimpleRequest));
}
});
}
public void saveGroup(String groupId) {
executor.execute(() -> {
try {
GroupMsgGetSimpleResult groupMsgGetSimpleResult = new GroupMsgGetSimpleResult();
groupMsgGetSimpleResult.setGroupId(groupId);
groupMsgGetSimpleResult.setId(groupId);
mongoTemplate.save(groupMsgGetSimpleResult, "group_record_" + SourceHolder.getLocal());
} catch (Exception e) {
log.error("记录群组生成失败,请求参数:{}", groupId, e);
}
});
}
}
......@@ -15,7 +15,15 @@ import io.github.doocs.im.config.CommonResult;
import io.github.doocs.im.config.ErrorEnum;
import io.github.doocs.im.constant.ActionStatus;
import io.github.doocs.im.core.Message;
import io.github.doocs.im.model.request.AdminGetRoamMsgRequest;
import io.github.doocs.im.model.request.AdminMsgWithdrawRequest;
import io.github.doocs.im.model.request.AdminSetMsgReadRequest;
import io.github.doocs.im.model.request.GetC2cUnreadMsgRequest;
import io.github.doocs.im.model.request.SendMsgRequest;
import io.github.doocs.im.model.response.AdminMsgWithdrawResult;
import io.github.doocs.im.model.response.AdminRoamMsgResult;
import io.github.doocs.im.model.response.AdminSetMsgReadResult;
import io.github.doocs.im.model.response.C2cUnreadMsgNumResult;
import io.github.doocs.im.model.response.SendMsgResult;
import io.github.doocs.im.util.JsonUtil;
import io.github.doocs.im.util.RandomUtil;
......@@ -45,7 +53,7 @@ public class MessageService extends GeneraService {
sendMsgResult = message.sendMsg(sendMsgRequest);
log.info("结果:{}", sendMsgResult.toString());
} catch (Exception e) {
log.error("请求qcloud失败,参数:{}", JsonUtil.obj2Str(sendMsgRequest));
log.error("请求qcloud失败,参数:{}", JsonUtil.obj2Str(sendMsgRequest),e);
throw new BusinessException(ErrorEnum.REQUEST_ERROR);
}
String actionStatus = sendMsgResult.getActionStatus();
......@@ -53,13 +61,114 @@ public class MessageService extends GeneraService {
HashMap<String, Object> result = Maps.newHashMap();
result.put("msgTime", sendMsgResult.getMsgTime());
result.put("msgKey", sendMsgResult.getMsgKey());
messageRecordMongoService.saveMessageRecord(sendMsgResult.getMsgKey(), sendMsgResult.getMsgTime(),
simpleMessageVO.getFromAccount(), simpleMessageVO.getToAccount());
return CommonResult.success(result);
}
return CommonResult
.fail(new CommonError(String.valueOf(sendMsgResult.getErrorCode()), sendMsgResult.getErrorInfo()));
}
public CommonResult getRoamMsg(AdminGetRoamMsgRequest adminGetRoamMsgRequest) throws JsonProcessingException {
Message message = imClient.getMessage();
AdminRoamMsgResult roamMsg = null;
try {
roamMsg = message.getRoamMsg(adminGetRoamMsgRequest);
log.info("结果:{}", roamMsg.toString());
} catch (Exception e) {
log.error("请求qcloud失败,参数:{}", JsonUtil.obj2Str(roamMsg), e);
throw new BusinessException(ErrorEnum.REQUEST_ERROR);
}
String actionStatus = roamMsg.getActionStatus();
if (ActionStatus.OK.equalsIgnoreCase(actionStatus)) {
HashMap<String, Object> result = Maps.newHashMap();
/**
* "Complete": 1, "MsgCnt": 5, //本次拉取返回了5条消息 "LastMsgTime": 1584669601, "LastMsgKey":
* "1456_23287_1584669601",
*/
result.put("Complete", roamMsg.getComplete());
result.put("MsgCnt", roamMsg.getMsgCnt());
result.put("LastMsgTime", roamMsg.getLastMsgTime());
result.put("LastMsgKey", roamMsg.getLastMsgKey());
result.put("MsgList", roamMsg.getMsgList());
return CommonResult.success(result);
}
return CommonResult.fail(new CommonError(String.valueOf(roamMsg.getErrorCode()), roamMsg.getErrorInfo()));
}
public CommonResult msgWithdraw(AdminMsgWithdrawRequest adminMsgWithdrawRequest) throws JsonProcessingException {
Message message = imClient.getMessage();
AdminMsgWithdrawResult adminMsgWithdrawResult;
try {
adminMsgWithdrawResult = message.msgWithdraw(adminMsgWithdrawRequest);
log.info("结果:{}", adminMsgWithdrawResult.toString());
} catch (Exception e) {
log.error("请求qcloud失败,参数:{}", JsonUtil.obj2Str(adminMsgWithdrawRequest),e);
throw new BusinessException(ErrorEnum.REQUEST_ERROR);
}
String actionStatus = adminMsgWithdrawResult.getActionStatus();
if (ActionStatus.OK.equalsIgnoreCase(actionStatus)) {
messageRecordMongoService.updateMessageRecord(adminMsgWithdrawRequest.getMsgKey());
return CommonResult.success();
}
return CommonResult.fail(new CommonError(String.valueOf(adminMsgWithdrawResult.getErrorCode()),
adminMsgWithdrawResult.getErrorInfo()));
}
public CommonResult setMsgRead(AdminSetMsgReadRequest adminSetMsgReadRequest) throws JsonProcessingException {
Message message = imClient.getMessage();
AdminSetMsgReadResult adminSetMsgReadResult = null;
try {
adminSetMsgReadResult = message.setMsgRead(adminSetMsgReadRequest);
log.info("结果:{}", adminSetMsgReadResult.toString());
} catch (Exception e) {
log.error("请求qcloud失败,参数:{}", JsonUtil.obj2Str(adminSetMsgReadResult),e);
throw new BusinessException(ErrorEnum.REQUEST_ERROR);
}
String actionStatus = adminSetMsgReadResult.getActionStatus();
if (ActionStatus.OK.equalsIgnoreCase(actionStatus)) {
return CommonResult.success();
}
return CommonResult.fail(new CommonError(String.valueOf(adminSetMsgReadResult.getErrorCode()),
adminSetMsgReadResult.getErrorInfo()));
}
public CommonResult getC2cUnreadMsgNum(GetC2cUnreadMsgRequest getC2cUnreadMsgRequest)
throws JsonProcessingException {
Message message = imClient.getMessage();
C2cUnreadMsgNumResult c2cUnreadMsgNum = null;
try {
c2cUnreadMsgNum = message.getC2cUnreadMsgNum(getC2cUnreadMsgRequest);
log.info("结果:{}", c2cUnreadMsgNum.toString());
} catch (Exception e) {
log.error("请求qcloud失败,参数:{}", JsonUtil.obj2Str(getC2cUnreadMsgRequest),e);
throw new BusinessException(ErrorEnum.REQUEST_ERROR);
}
String actionStatus = c2cUnreadMsgNum.getActionStatus();
if (ActionStatus.OK.equalsIgnoreCase(actionStatus)) {
HashMap<String, Object> objectObjectHashMap = Maps.newHashMap();
objectObjectHashMap.put("AllC2CUnreadMsgNum", c2cUnreadMsgNum.getAllC2cUnreadMsgNum());
objectObjectHashMap.put("C2CUnreadMsgNumList", c2cUnreadMsgNum.getUnreadMsgNumList());
return CommonResult.success(objectObjectHashMap);
}
return CommonResult
.fail(new CommonError(String.valueOf(c2cUnreadMsgNum.getErrorCode()), c2cUnreadMsgNum.getErrorInfo()));
}
@Autowired
private MessageRecordMongoService messageRecordMongoService;
}
......@@ -71,6 +71,7 @@ public class HttpUtil {
String param = JsonUtil.obj2Str(data);
log.info("请求参数:{}",param);
String result = post(url, param, config);
log.info("返回结果:{}",result);
return JsonUtil.str2Obj(result, cls);
}
......
sdkAppId:
1400599792
key:
cacfa51c0e3789a34b322fd1209f237ba363b8279f3ad483a302804b4e9fcab8
userId:
administrator
param:
configs:
- sdkAppId: 1400599792
key: cacfa51c0e3789a34b322fd1209f237ba363b8279f3ad483a302804b4e9fcab8
userId: administrator
source: test
- sdkAppId: 14005997921
key: cacfa51c0e3789a34b322fd1209f237ba363b8279f3ad483a302804b4e9fcab81
userId: administrator1
source: test1
mongodb:
address: 10.244.4.39:27017
authenticationDatabase: admin
......@@ -26,6 +30,7 @@ mongodb:
spring:
application:
name: im
# yml配置的优先级高于java配置;如果yml配置和java配置同时存在,则yml配置会覆盖java配置
http-client:
pool:
......@@ -47,3 +52,15 @@ spring:
# 针对不同的网址,长连接保持的存活时间,单位s,如果是频繁而持续的请求,可以设置小一点,不建议设置过大,避免大量无用连接占用内存资源
keepAliveTargetHost:
www.baidu.com: 5
weixin:
configs:
- schId: 111
appId: 11111
appSecret: 11111
templateId: 111111
- schId: 2222
appId: 222222
appSecret: 2222222
templateId: 2222222
server:
port: 8869
\ No newline at end of file
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