Преглед изворни кода

Merge branch 'feature/0803-im' of http://git.dayaedu.com/yonge/cooleshow into feature/0803-im

liujc пре 2 година
родитељ
комит
41ba78874c

+ 4 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/ImGroupService.java

@@ -171,6 +171,10 @@ public interface ImGroupService extends IService<ImGroup> {
      */
     void importUser();
 
+    /**
+     * 计算未导入数据的总条数
+     * @return
+     */
     int queryCount();
 
     /**

+ 223 - 11
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/ImGroupServiceImpl.java

@@ -6,6 +6,7 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.toolkit.IdWorker;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.google.common.collect.Lists;
+import com.microsvc.toolkit.middleware.common.http.ImageUtil;
 import com.microsvc.toolkit.middleware.im.ImPluginContext;
 import com.microsvc.toolkit.middleware.im.message.GroupMemberWrapper;
 import com.microsvc.toolkit.middleware.im.message.MessageWrapper;
@@ -35,8 +36,10 @@ import com.yonge.cooleshow.biz.dal.service.*;
 import com.yonge.cooleshow.biz.dal.support.IMHelper;
 import com.yonge.cooleshow.biz.dal.vo.StudentVo;
 import com.yonge.cooleshow.biz.dal.vo.TeacherVo;
+import com.yonge.cooleshow.biz.dal.wrapper.ImHistoryMessageWrapper;
 import com.yonge.cooleshow.biz.dal.wrapper.im.ImGroupWrapper;
 import com.yonge.cooleshow.common.constant.SysConfigConstant;
+import com.yonge.cooleshow.common.entity.UploadReturnBean;
 import com.yonge.toolset.base.exception.BizException;
 import com.yonge.toolset.base.util.ThreadPool;
 import com.yonge.toolset.mybatis.support.PageUtil;
@@ -45,6 +48,7 @@ import io.rong.methods.message.history.History;
 import io.rong.models.Result;
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.lang3.StringUtils;
+import org.checkerframework.checker.units.qual.A;
 import org.redisson.api.RBucket;
 import org.redisson.api.RedissonClient;
 import org.slf4j.Logger;
@@ -56,11 +60,7 @@ import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
 import javax.annotation.Resource;
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStreamReader;
+import java.io.*;
 import java.nio.charset.StandardCharsets;
 import java.text.MessageFormat;
 import java.text.ParseException;
@@ -127,6 +127,9 @@ public class ImGroupServiceImpl extends ServiceImpl<ImGroupDao, ImGroup> impleme
     @Autowired
     private RTCRoomPluginContext rtcRoomPluginContext;
 
+    @Autowired
+    private UploadFileService uploadFileService;
+
 
     @Value("${cn.rongcloud.im.appkey}")
     private String appKey;
@@ -722,11 +725,53 @@ public class ImGroupServiceImpl extends ServiceImpl<ImGroupDao, ImGroup> impleme
 
                 JSONObject jsonObject = JSONObject.parseObject(i.getContent());
                 if (i.getClassname().equals("RC:TxtMsg")) {
+                    //文本
                     TencentRequest.MessageBody body1 = CustomerServiceBatchSendingServiceImpl.getTimTextElem(jsonObject.getString("content"));
                     list.add(body1);
-                } else if (i.getClassname().equals("RC:ImgMsg")) {
+                } else if (i.getClassname().equals("RC:ImgMsg") || i.getClassname().equals("RC:GIFMsg")) {
+                    //图片  GIf
                     TencentRequest.MessageBody body1 = CustomerServiceBatchSendingServiceImpl.getTimImageElem(jsonObject.getString("imageUri"));
                     list.add(body1);
+                } else if (i.getClassname().equals("RC:HQVCMsg")){
+                    //语音
+                    String remoteUrl = jsonObject.getString("remoteUrl");
+                    int duration = jsonObject.getInteger("duration");
+                    TencentRequest.MessageBody body1 = getTimSoundElem(remoteUrl,duration);
+                    list.add(body1);
+                } else if(i.getClassname().equals("RC:FileMsg")){
+                    //文件
+                    String fileUrl = jsonObject.getString("fileUrl");
+                    String size = jsonObject.getString("size");
+                    String name = jsonObject.getString("name");
+
+                    TencentRequest.MessageBody body1 = getTimFileElem(fileUrl,size,name);
+                    list.add(body1);
+                } else if(i.getClassname().equals("RC:SightMsg")){
+                    //视频
+                    String sightUrl = jsonObject.getString("sightUrl");
+                    String size = jsonObject.getString("size");
+                    int duration = jsonObject.getInteger("duration");
+                    String content = jsonObject.getString("content");
+                    TencentRequest.MessageBody body1 = null;
+                    try {
+                        body1 = getTimVideoFileElem(sightUrl,size,duration,content);
+                    } catch (IOException e) {
+                        e.printStackTrace();
+                    }
+                    list.add(body1);
+                } else if(i.getClassname().equals("RC:LBSMsg")) {
+                    //位置
+                    int latitude = jsonObject.getInteger("latitude");
+                    int longitude = jsonObject.getInteger("longitude");
+                    String poi = jsonObject.getString("poi");
+                    TencentRequest.MessageBody body1 = getTimLocationElem(latitude, longitude, poi);
+                    list.add(body1);
+                } else if (i.getClassname().equals("RC:ImgTextMsg")){
+                    //图文
+                    TencentRequest.MessageBody body1 = CustomerServiceBatchSendingServiceImpl.getTimTextElem(jsonObject.getString("content"));
+                    TencentRequest.MessageBody body2 = CustomerServiceBatchSendingServiceImpl.getTimImageElem(jsonObject.getString("imageUri"));
+                    list.add(body1);
+                    list.add(body2);
                 } else {
                     return;
                 }
@@ -739,13 +784,14 @@ public class ImGroupServiceImpl extends ServiceImpl<ImGroupDao, ImGroup> impleme
                     item.setMsgContent(i.getContent());
                     item.setMsgType(i.getClassname());
                 });*/
-                if (list.stream().map(TencentRequest.MessageBody::getMsgType).collect(Collectors.toList()).get(0).equals("RC:TxtMsg")) {
+
+               /* if (list.stream().map(TencentRequest.MessageBody::getMsgType).collect(Collectors.toList()).get(0).equals("RC:TxtMsg")) {
                     //文本对象
                     list.forEach(item -> item.setMsgType("TIMTextElem"));
                 } else if (list.stream().map(TencentRequest.MessageBody::getMsgType).collect(Collectors.toList()).get(0).equals("RC:ImgMsg")) {
                     //图文对象
                     list.forEach(item -> item.setMsgType("TIMImageElem"));
-                }
+                }*/
                 privateImportMessage.setTencentMessageBody(list);
                 try {
                     imPluginContext.getPluginService().importPrivateMessage(privateImportMessage);
@@ -796,11 +842,58 @@ public class ImGroupServiceImpl extends ServiceImpl<ImGroupDao, ImGroup> impleme
                         });*/
                 JSONObject jsonObject = JSONObject.parseObject(i.getContent());
                 if (i.getClassname().equals("RC:TxtMsg")) {
+                    //文本
                     TencentRequest.MessageBody body1 = CustomerServiceBatchSendingServiceImpl.getTimTextElem(jsonObject.getString("content"));
                     bodyList.add(body1);
-                } else if (i.getClassname().equals("RC:ImgMsg")) {
+                } else if (i.getClassname().equals("RC:ImgMsg") || i.getClassname().equals("RC:GIFMsg")) {
+                    //图片  GIf
                     TencentRequest.MessageBody body1 = CustomerServiceBatchSendingServiceImpl.getTimImageElem(jsonObject.getString("imageUri"));
                     bodyList.add(body1);
+                } else if (i.getClassname().equals("RC:HQVCMsg")){
+                    //语音
+                    String remoteUrl = jsonObject.getString("remoteUrl");
+                    int duration = jsonObject.getInteger("duration");
+                    TencentRequest.MessageBody body1 = getTimSoundElem(remoteUrl,duration);
+                    bodyList.add(body1);
+                } else if(i.getClassname().equals("RC:FileMsg")){
+                    //文件
+                    String fileUrl = jsonObject.getString("fileUrl");
+                    String size = jsonObject.getString("size");
+                    String name = jsonObject.getString("name");
+
+                    TencentRequest.MessageBody body1 = getTimFileElem(fileUrl,size,name);
+                    bodyList.add(body1);
+                } else if(i.getClassname().equals("RC:SightMsg")){
+                    //视频
+                    String sightUrl = jsonObject.getString("sightUrl");
+                    String size = jsonObject.getString("size");
+                    int duration = jsonObject.getInteger("duration");
+                    String content = jsonObject.getString("content");
+                    TencentRequest.MessageBody body1 = null;
+                    try {
+                        body1 = getTimVideoFileElem(sightUrl,size,duration,content);
+                    } catch (IOException e) {
+                        e.printStackTrace();
+                    }
+                    bodyList.add(body1);
+                } else if(i.getClassname().equals("RC:LBSMsg")) {
+                    //位置
+                    int latitude = jsonObject.getInteger("latitude");
+                    int longitude = jsonObject.getInteger("longitude");
+                    String poi = jsonObject.getString("poi");
+                    TencentRequest.MessageBody body1 = getTimLocationElem(latitude, longitude, poi);
+                    bodyList.add(body1);
+                } else if (i.getClassname().equals("RC:ImgTextMsg")){
+                    //图文
+                    TencentRequest.MessageBody body1 = CustomerServiceBatchSendingServiceImpl.getTimTextElem(jsonObject.getString("content"));
+                    TencentRequest.MessageBody body2 = CustomerServiceBatchSendingServiceImpl.getTimImageElem(jsonObject.getString("imageUri"));
+                    bodyList.add(body1);
+                    bodyList.add(body2);
+                } else if (i.getClassname().equals("RC:CombineMsg")){
+                    //合并转发
+                    String remoteUrl = jsonObject.getString("remoteUrl");
+                    int conversationType = jsonObject.getInteger("conversationType");
+                    getTimRelayElem();
                 } else {
                     return;
                 }
@@ -808,12 +901,12 @@ public class ImGroupServiceImpl extends ServiceImpl<ImGroupDao, ImGroup> impleme
                 body.setMsgType(i.getClassname());*/
 
                 //文本对象
-                if (bodyList.stream().map(TencentRequest.MessageBody::getMsgType).collect(Collectors.toList()).get(0).equals("RC:TxtMsg")) {
+                /*if (bodyList.stream().map(TencentRequest.MessageBody::getMsgType).collect(Collectors.toList()).get(0).equals("RC:TxtMsg")) {
                     bodyList.forEach(item -> item.setMsgType("TIMTextElem"));
                 } else if (bodyList.stream().map(TencentRequest.MessageBody::getMsgType).collect(Collectors.toList()).get(0).equals("RC:ImgMsg")) {
                     //暂未支持图文对象
                     bodyList.forEach(item -> item.setMsgType("TIMCustomElem"));
-                }
+                }*/
 
                 data1.setTencentMessageBody(bodyList);
 
@@ -829,6 +922,125 @@ public class ImGroupServiceImpl extends ServiceImpl<ImGroupDao, ImGroup> impleme
         });
     }
 
+    //构建合并转发请求体
+    private TencentRequest.MessageBody getTimRelayElem() {
+        ImHistoryMessageWrapper.TimRelayElem timRelayElem = new ImHistoryMessageWrapper.TimRelayElem();
+        //todo
+        //timRelayElem.setMsgNum();
+
+        TencentRequest.MessageBody messageBody = new TencentRequest.MessageBody();
+        messageBody.setMsgType("TIMRelayElem");
+        messageBody.setMsgContent(timRelayElem);
+        return  messageBody;
+    }
+
+    //构建位置请求体
+    private TencentRequest.MessageBody getTimLocationElem(int latitude, int longitude, String poi) {
+        if (latitude == 0 && longitude == 0 &&  StringUtils.isEmpty(poi)) {
+            return null;
+        }
+        ImHistoryMessageWrapper.TimLocationElem timLocationElem = new ImHistoryMessageWrapper.TimLocationElem();
+        timLocationElem.setDesc(poi);
+        timLocationElem.setLatitude(latitude);
+        timLocationElem.setLongitude(longitude);
+
+        TencentRequest.MessageBody messageBody = new TencentRequest.MessageBody();
+        messageBody.setMsgType("TIMLocationElem");
+        messageBody.setMsgContent(timLocationElem);
+        return  messageBody;
+    }
+
+    //构建视频请求体
+    public  TencentRequest.MessageBody getTimVideoFileElem(String sightUrl, String size, int duration, String content) throws IOException {
+        if (StringUtils.isEmpty(sightUrl) && StringUtils.isEmpty(sightUrl) && duration == 0) {
+            return null;
+        }
+        ByteArrayInputStream bais = null;
+        String  format = "";
+        //判断是否有前缀
+        if (content.contains(",")){
+            String[] split = content.split(",");
+            String s = split[0];
+            format = s.substring(s.indexOf("/")+ 1,s.indexOf(";"));
+            content = split[1];
+        } else {
+            format = "JPG";
+        }
+
+        //获取JDK8里的解码器Base64.Decoder,将base64字符串转为字节数组
+        byte[] bytes = Base64.getDecoder().decode(content);
+        //构建字节数组输入流
+        bais = new ByteArrayInputStream(bytes);
+
+        UploadReturnBean uploadReturnBean = uploadFileService.uploadFile(bais, format);
+        String url = uploadReturnBean.getUrl();
+        //BufferedImage read = ImageIO.read(bais);
+
+
+
+        ImageUtil.ImageInfo imageReq = ImageUtil.ImageInfo.builder()
+                .imgUrl(url)
+                .suffix(format)
+                .build();
+
+
+        ImHistoryMessageWrapper.TimVideoFileElem timVideoFileElem = new ImHistoryMessageWrapper.TimVideoFileElem();
+        timVideoFileElem.setVideoUrl(sightUrl);
+        timVideoFileElem.setVideoUUID(UUID.randomUUID().toString());
+        timVideoFileElem.setVideoSize(Integer.valueOf(size));
+        timVideoFileElem.setVideoSecond(duration);
+        timVideoFileElem.setVideoFormat("mp4");
+        timVideoFileElem.setVideoDownloadFlag(2);
+        timVideoFileElem.setThumbUrl(url);
+        timVideoFileElem.setThumbUUID(imageReq.getMd5());
+        timVideoFileElem.setThumbWidth(imageReq.getWidth());
+        timVideoFileElem.setThumbHeight(imageReq.getHeight());
+        timVideoFileElem.setThumbSize((imageReq.getSize().intValue()));
+        timVideoFileElem.setThumbDownloadFlag(2);
+        timVideoFileElem.setThumbFormat(format);
+
+        TencentRequest.MessageBody messageBody = new TencentRequest.MessageBody();
+        messageBody.setMsgType("TIMVideoFileElem");
+        messageBody.setMsgContent(timVideoFileElem);
+        return  messageBody;
+    }
+
+    //构建文件请求体
+    public static TencentRequest.MessageBody getTimFileElem(String fileUrl, String size, String name) {
+        if (StringUtils.isEmpty(fileUrl) && StringUtils.isEmpty(size) &&  StringUtils.isEmpty(name)) {
+            return null;
+        }
+        ImHistoryMessageWrapper.TimFileElem timFileElem = new ImHistoryMessageWrapper.TimFileElem();
+        timFileElem.setUrl(fileUrl);
+        timFileElem.setUUID(UUID.randomUUID().toString());
+        timFileElem.setFileName(name);
+        timFileElem.setFileSize(Integer.valueOf(size));
+        timFileElem.setDownload_Flag(2);
+
+        TencentRequest.MessageBody messageBody = new TencentRequest.MessageBody();
+        messageBody.setMsgType("TIMFileElem");
+        messageBody.setMsgContent(timFileElem);
+        return  messageBody;
+    }
+
+    //构造语音请求体
+    public static TencentRequest.MessageBody getTimSoundElem(String remoteUrl,int duration) {
+        if (StringUtils.isEmpty(remoteUrl) && duration == 0) {
+            return null;
+        }
+
+        ImHistoryMessageWrapper.TimSoundElem timSoundElem = new ImHistoryMessageWrapper.TimSoundElem();
+        timSoundElem.setUrl(remoteUrl);
+        timSoundElem.setUUID(UUID.randomUUID().toString());
+        timSoundElem.setSecond(duration);
+        timSoundElem.setDownload_Flag(2);
+
+        TencentRequest.MessageBody messageBody = new TencentRequest.MessageBody();
+        messageBody.setMsgType("TIMSoundElem");
+        messageBody.setMsgContent(timSoundElem);
+        return  messageBody;
+    }
+
 
     private History getHistory() {
         RongCloud rongCloud = RongCloud.getInstance(appKey, appSecret);

+ 183 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/wrapper/ImHistoryMessageWrapper.java

@@ -0,0 +1,183 @@
+package com.yonge.cooleshow.biz.dal.wrapper;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.List;
+
+public class ImHistoryMessageWrapper {
+
+
+    @Data
+    @ApiModel("ImHistoryMessage-iM语音消息")
+    public static class TimSoundElem {
+
+        @ApiModelProperty("语音下载地址,可通过该 URL 地址直接下载相应语音。")
+        private String Url;
+
+        @ApiModelProperty("语音的唯一标识,客户端用于索引语音的键值")
+        private String UUID;
+
+        @ApiModelProperty("语音数据大小,单位:字节。")
+        private Integer Size;
+
+        @ApiModelProperty("语音时长,单位:秒。")
+        private Integer Second;
+
+        @ApiModelProperty("语音下载方式标记。目前 Download_Flag 取值只能为2,表示可通过Url字段值的 URL 地址直接下载语音。")
+        private Integer Download_Flag;
+
+    }
+
+    @Data
+    @ApiModel("ImHistoryMessage-iM文件")
+    public static class TimFileElem {
+
+        @ApiModelProperty("文件下载地址,可通过该 URL 地址直接下载相应文件。")
+        private String Url;
+
+        @ApiModelProperty("文件的唯一标识,客户端用于索引文件的键值。")
+        private String UUID;
+
+        @ApiModelProperty("文件数据大小,单位:字节。")
+        private Integer FileSize;
+
+        @ApiModelProperty("文件名称。")
+        private String FileName;
+
+        @ApiModelProperty("文件下载方式标记。目前 Download_Flag 取值只能为2,表示可通过Url字段值的 URL 地址直接下载文件。")
+        private Integer Download_Flag;
+
+    }
+
+    @Data
+    @ApiModel("ImHistoryMessage-iM视频")
+    public static class TimVideoFileElem {
+
+        @ApiModelProperty("视频下载地址。可通过该 URL 地址直接下载相应视频。")
+        private String VideoUrl;
+
+        @ApiModelProperty("文视频的唯一标识,客户端用于索引视频的键值。")
+        private String VideoUUID;
+
+        @ApiModelProperty("视频数据大小,单位:字节。")
+        private Integer VideoSize;
+
+        @ApiModelProperty("视频时长,单位:秒。Web 端不支持获取视频时长,值为0")
+        private Integer VideoSecond;
+
+        @ApiModelProperty("视频格式,例如 mp4")
+        private String VideoFormat;
+
+        @ApiModelProperty("视频下载方式标记。目前 VideoDownloadFlag 取值只能为2,表示可通过 VideoUrl 字段值的 URL 地址直接下载视频。")
+        private Integer VideoDownloadFlag;
+
+        @ApiModelProperty("视频缩略图下载地址。可通过该 URL 地址直接下载相应视频缩略图。")
+        private String ThumbUrl;
+
+        @ApiModelProperty("视频缩略图的唯一标识,客户端用于索引视频缩略图的键值")
+        private String ThumbUUID;
+
+        @ApiModelProperty("缩略图大小,单位:字节。")
+        private Integer ThumbSize;
+
+        @ApiModelProperty("缩略图宽度,单位为像素。")
+        private Integer ThumbWidth;
+
+        @ApiModelProperty("缩略图高度,单位为像素。")
+        private Integer ThumbHeight;
+
+        @ApiModelProperty("缩略图格式,例如 JPG、BMP 等。")
+        private String ThumbFormat;
+
+        @ApiModelProperty("视频缩略图下载方式标记。目前 ThumbDownloadFlag 取值只能为2,表示可通过 ThumbUrl 字段值的 URL 地址直接下载视频缩略图。")
+        private Integer ThumbDownloadFlag;
+    }
+
+
+    @Data
+    @ApiModel("ImHistoryMessage-iM位置")
+    public static class TimLocationElem {
+
+        @ApiModelProperty("地理位置描述信息。")
+        private String Desc;
+
+        @ApiModelProperty("纬度。")
+        private Integer Latitude;
+
+        @ApiModelProperty("经度。")
+        private Integer Longitude;
+    }
+
+    @Data
+    @ApiModel("ImHistoryMessage-iM合并转发")
+    public static class TimRelayElem {
+
+        @ApiModelProperty("合并转发消息的标题。")
+        private String Title;
+
+        @ApiModelProperty("被转发的消息条数。")
+        private Integer MsgNum;
+
+        @ApiModelProperty("兼容文本。当不支持合并转发消息的老版本 SDK 收到此类消息时,IM 后台会将该消息转化成兼容文本再下发。")
+        private String CompatibleText;
+
+        @ApiModelProperty("合并消息的摘要列表,是一个 String 数组")
+        private String[] AbstractList;
+
+        @ApiModelProperty("消息列表。当被转发的消息长度之和小于等于12K时才会有此字段,此时不会有 JsonMsgKey 字段。")
+        private List<TimRelayElemList> MsgList;
+
+        @ApiModelProperty("合并转发的消息列表 Key。当被转发的消息长度之和大于12K时才会有此字段,此时不会有 MsgList 字段。")
+        private String JsonMsgKey;
+
+
+    }
+
+
+    @Data
+    @ApiModel("ImHistoryMessage-iM合并转发消息列表")
+    public static class TimRelayElemList {
+
+        @ApiModelProperty("消息发送方 UserID。被转发的消息为单聊或群聊时都有此字段。")
+        private String From_Account;
+
+        @ApiModelProperty("消息接收方 UserID。被转发的消息为单聊才有此字段。")
+        private String To_Account;
+
+        @ApiModelProperty("群 ID。被转发的消息为群聊才有此字段。")
+        private String GroupId;
+
+        @ApiModelProperty("消息序列号(32位无符号整数)。")
+        private Integer MsgSeq;
+
+        @ApiModelProperty("消息随机数(32位无符号整数)。")
+        private Integer MsgRandom;
+
+        @ApiModelProperty("消息的秒级时间戳。")
+        private Integer MsgTimeStamp;
+
+        @ApiModelProperty("消息内容")
+        private List<TimRelayElemMessage> MsgBody;
+
+        @ApiModelProperty("消息自定义数据(云端保存,会发送到对端,程序卸载重装后还能拉取到)。")
+        private String CloudCustomData;
+
+    }
+
+    @Data
+    @ApiModel("ImHistoryMessage-iM合并转发消息内容体")
+    public static class TimRelayElemMessage {
+
+        @ApiModelProperty("消息类型")
+        private String msgType;
+
+        @ApiModelProperty("消息内容")
+        private Object msgContent;
+
+    }
+
+
+
+}

+ 2 - 1
cooleshow-user/user-biz/src/main/resources/config/mybatis/ImGroupMapper.xml

@@ -134,10 +134,11 @@
                appId_           AS appId
 
         from im_history_message
+        where status_ = 0
         limit #{result},#{size}
 
     </select>
     <select id="queryCount" resultType="java.lang.Integer">
-        SELECT COUNT(*) FROM im_history_message
+        SELECT COUNT(*) FROM im_history_message where status_ = 0
     </select>
 </mapper>