Commit 4316b780 by Shadow

调整模块名

parent dbd41a7d
/target/
/classes
!.mvn/wrapper/maven-wrapper.jar
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### NetBeans ###
/nbproject/private/
/build/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
.DS_Store
*.log
logs
*.rdb
# system 项目系统模块
\ No newline at end of file
package com.wecloud.im.biz.module.message.controller.param.add;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.util.Date;
import javax.validation.constraints.NotNull;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.wecloud.can.core.base.entity.BaseEntity;
/**
* 第三方应用表
*
* @author wei
* @since 2021-04-27
*/
@Data
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = true)
@ApiModel(value = "ImApplicationAdd")
public class ImApplicationAdd extends BaseEntity {
private static final long serialVersionUID = 1L;
@NotNull(message = "应用appid不能为空")
@ApiModelProperty("应用appid")
@TableId(value = "id", type = IdType.INPUT)
private Long id;
@ApiModelProperty("创建时间")
private Date createTime;
@ApiModelProperty("修改时间")
private Date updateTime;
// @ApiModelProperty("key")
// private String appKey;
//
// @ApiModelProperty("密钥")
// private String appSecret;
@ApiModelProperty("app名称")
private String appName;
@ApiModelProperty("ios推送通道,友盟:1;firebase:2; apns原生:3")
private Integer iosPushChannel;
@ApiModelProperty("安卓推送通道,友盟:1;firebase:2; 信鸽3")
private Integer androidPushChannel;
@ApiModelProperty("友盟推送key")
private String umengKey;
@ApiModelProperty("友盟推送密钥")
private String umengSecret;
@ApiModelProperty("firebase推送密钥")
private String firebaseSecret;
private String adminPwd;
}
package com.wecloud.im.biz.module.message.controller.param.add;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.util.List;
import java.util.Map;
import javax.validation.constraints.NotNull;
import com.wecloud.can.core.base.entity.BaseEntity;
import com.wecloud.im.biz.enums.ChatTypeEnum;
/**
* 会话表
*
* @author wei
* @since 2021-05-07
*/
@Data
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = true)
@ApiModel(value = "ImConversationCreate")
public class ImConversationCreate extends BaseEntity {
private static final long serialVersionUID = 1L;
@ApiModelProperty("可选 对话的名字,可为群组命名。")
private String name;
@ApiModelProperty("string格式,可选 自定义属性,供开发者扩展使用。")
private Map<String, Object> attributes;
@ApiModelProperty("可选 邀请加入会话的客户端,如创建单聊,则填入对方的clientId")
private List<String> clientIds;
@ApiModelProperty("创建者id,sdk调用时传递该参数")
private String creatorUserId;
@ApiModelProperty("成员用户id,sdk调用时传递该参数")
private String memberUserIds;
/**
* @see ChatTypeEnum
*/
@ApiModelProperty("会话属性,1:单聊,2:普通群,3:万人群, 4:聊天室")
@NotNull(message = "会话类型不能为空")
private Integer chatType;
@ApiModelProperty("客户端平台: 1 web, 2 安卓, 3 ios, 4 pc-win, 5 pc-macOs, 需与生成sign时的值一致")
private Integer platform;
@ApiModelProperty("是否加密聊天: 1-是 0-否")
private Integer isEncrypt;
}
package com.wecloud.im.biz.module.message.controller.param.add;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.util.HashMap;
import com.wecloud.can.core.base.entity.BaseEntity;
/**
* 自定义透传内容
*
* @author wei
*/
@Data
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = true)
@ApiModel(value = "ImMsgSendToOnlineClient")
public class ImMsgSendToOnlineClient extends BaseEntity {
private static final long serialVersionUID = 1L;
// @ApiModelProperty(value = "自定义透传内容", required = true)
// private String content;
@ApiModelProperty(value = "自定义透传内容 ,为任意参数名称和类型的对象,供开发者扩展使用。", required = true)
private HashMap content;
@ApiModelProperty(value = "会话id", required = true)
private Long conversationId;
}
package com.wecloud.im.biz.module.message.controller.param.add;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.util.HashMap;
import com.wecloud.can.core.base.entity.BaseEntity;
/**
* 修改消息
*
* @author wei
* @since 2021-04-27
*/
@Data
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = true)
@ApiModel(value = "ImMsgUpdate")
public class ImMsgUpdate extends BaseEntity {
private static final long serialVersionUID = 1L;
@ApiModelProperty("消息id")
private Long msgId;
@ApiModelProperty("内容")
private HashMap content;
}
package com.wecloud.im.biz.module.message.controller.param.add;
import io.swagger.annotations.ApiModel;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.List;
import java.util.Map;
import com.wecloud.im.biz.enums.ChatTypeEnum;
import com.wecloud.im.biz.module.message.entity.ImApplication;
import com.wecloud.im.biz.module.message.entity.ImClient;
import com.wecloud.imserver.client.model.enums.DeviceTypeEnum;
/**
*
* @Author luozh
* @Date 2022年05月07日 10:13
* @Version 1.0
*/
@Data
@Accessors(chain = true)
@ApiModel(value = "ImConversationCreate")
public class ServerImConversationCreate implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 可选 对话的名字,可为群组命名。")
*/
private String name;
/**
* Map格式,可选 自定义属性,供开发者扩展使用。")
*/
private Map<String, Object> attributes;
/**
* 应用, 前端")
*/
private ImApplication application;
/**
* 创建者 前端请求不传")
*/
private ImClient creator;
/**
* 可选 成员列表
*/
private List<ImClient> members;
/**
* @see ChatTypeEnum
*/
/**
* 会话属性,1:单聊,2:普通群,3:万人群, 4:聊天室")
*/
private ChatTypeEnum chatType;
/**
* 客户端平台: 1 web, 2 安卓, 3 ios, 4 pc-win, 5 pc-macOs, 需与生成sign时的值一致")
*/
private DeviceTypeEnum platform;
}
package com.wecloud.im.biz.module.message.controller.param.group;
import lombok.Getter;
import lombok.Setter;
import javax.validation.constraints.NotBlank;
/**
* 加入群
* @Author luozh
* @Date 2022年05月10日 09:37
* @Version 1.0
*/
@Getter
@Setter
public class JoinGroupParam {
/**
* 邀请进群的用户id
*/
@NotBlank(message = "inviterUserId 不能为空")
private String inviterUserId;
/**
* 要加入群的用户 ID
*/
@NotBlank(message = "userIds 不能为空")
private String userIds;
/**
* 要加入的群的群组 ID
*/
@NotBlank(message = "groupId 不能为空")
private String groupId;
}
package com.wecloud.im.biz.module.message.controller.param.group;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* 禁言群成员入参
* @Author luozh
* @Date 2022年05月16日 19:42
* @Version 1.0
*/
@Data
public class MutedMembersParam {
@ApiModelProperty("群id")
private String groupId;
@ApiModelProperty("是否禁言")
private Boolean muted;
@ApiModelProperty("用户id多个用,隔开")
private String userIds;
}
package com.wecloud.im.biz.module.message.controller.param.rtc;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
/**
* @author wei
* @since 2021-04-29
*/
@Data
@ApiModel(value = "CandidateForwardParam")
public class CandidateForwardParam implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty("频道id")
private Long channelId;
/**
* 转发的候选者数据
*/
private String candidateData;
}
package com.wecloud.im.biz.module.message.controller.param.rtc;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
/**
* 创建频道请求参数
*
* @author wei
* @since 2021-04-29
*/
@Data
@ApiModel(value = "CreateRtcChannelParam")
public class CreateRtcChannelParam implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "被邀请的客户端ID", required = true)
private String toClient;
@ApiModelProperty(value = "客户端自定义数据", required = false)
private String attrs;
@ApiModelProperty(value = "类型: 1-video或2-voice", required = true)
private Integer callType;
@ApiModelProperty(value = "绑定的会话id,可选", required = false)
private Long conversationId;
@ApiModelProperty(value = "接收方展示的系统推送内容,可", required = false)
private String push;
@ApiModelProperty(value = "是否需要给对方发系统通知", required = true)
private Boolean pushCall;
}
package com.wecloud.im.biz.module.message.controller.param.rtc;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
/**
* 创建频道返回参数
*
* @author wei
* @since 2021-04-29
*/
@Data
@ApiModel(value = "CreateRtcChannelResult")
public class CreateRtcChannelResult implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty("频道id")
private Long channelId;
}
package com.wecloud.im.biz.module.message.controller.param.rtc;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
/**
* 加入频道请求参数
*
* @author wei
* @since 2021-04-29
*/
@Data
@ApiModel(value = "JoinRtcChannelParam")
public class JoinRtcChannelParam implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty("频道id")
private Long channelId;
}
package com.wecloud.im.biz.module.message.controller.param.rtc;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
/**
* 退出频道 请求
*
* @author wei
* @since 2021-04-29
*/
@Data
@ApiModel(value = "LeaveRtcChannelParam")
public class LeaveRtcChannelParam implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty("频道id")
private Long channelId;
}
package com.wecloud.im.biz.module.message.controller.param.rtc;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
/**
* 拒接加入频道 请求
*
* @author wei
* @since 2021-04-29
*/
@Data
@ApiModel(value = "RejectRtcChannelParam")
public class RejectRtcChannelParam implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty("频道id")
private Long channelId;
}
package com.wecloud.im.biz.module.message.controller.param.rtc;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
/**
* @author wei
* @since 2021-04-29
*/
@Data
@ApiModel(value = "SdpForwardParam")
public class SdpForwardParam implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty("频道id")
private Long channelId;
@ApiModelProperty("sdp转发的数据")
private String sdpData;
@ApiModelProperty("sdp类型: Offer或Answer")
private String sdpType;
}
package com.wecloud.im.biz.module.message.controller.param.rtc;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
import com.wecloud.im.biz.enums.CallTypeEnum;
/**
* @author nanqianhao
* @date 2022/5/23
* @apiNote
*/
@Data
@ApiModel(value = "单人rtc音视频查找记录")
public class SingleRtcRecordParam implements Serializable {
private static final long serialVersionUID = 2176804812523348248L;
/**
* 发送者id
*/
@ApiModelProperty("发送者id")
private String fromClientId;
/**
* 接受者id
*/
@ApiModelProperty("接受者id")
private String toClientId;
/**
* 房间id
*/
@ApiModelProperty("房间id")
private String channelId;
/**
* 音视频类型
* @see CallTypeEnum
*/
@ApiModelProperty("音视频类型")
private Integer callType;
/***
* 页码
*/
@ApiModelProperty("页码")
private Integer pageNum;
/**
* 每页数量
*/
@ApiModelProperty("每页数量")
private Integer pageSize;
@ApiModelProperty("开始时间")
private Date createTimeStart;
@ApiModelProperty("结束时间")
private Date createTimeEnd;
}
package com.wecloud.im.biz.module.message.controller.serverapi;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.wecloud.can.core.base.controller.BaseController;
import com.wecloud.can.core.enums.ApiCode;
import com.wecloud.can.core.util.ApiResult;
import com.wecloud.im.biz.module.message.controller.param.add.ImMsgSendToOnlineClient;
import com.wecloud.im.biz.module.message.entity.ImApplication;
import com.wecloud.im.biz.module.message.service.ImApplicationService;
import com.wecloud.im.biz.module.message.service.ImMessageService;
/**
* 消息存储表 控制器
*
* @author wei
* @since 2021-04-29
*/
@Slf4j
@RestController
@RequestMapping("/server/imMessage")
@Api(value = "服务端rest-API-消息", tags = {"服务端rest-API-消息"})
public class ApiImMessageController extends BaseController {
@Autowired
private ImApplicationService imApplicationService;
@Autowired
private ImMessageService imMessageService;
/**
* 向会话中在线client,下发透传消息
*/
@PostMapping("/sendToOnlineClient")
@ApiOperation(value = "向会话中在线client,下发透传消息", notes = "应用服务端向某会话中所有client下发透传消息, 不会保存进离线消息, 仅在线client能收到")
public ApiResult<Boolean> restApiImMessageSend(@RequestBody ImMsgSendToOnlineClient imMsgSendToOnlineClient, @RequestHeader String appkey, @RequestHeader String appSecret) throws Exception {
// return imMessageService.updateMsgWithdrawById(imMsgRecall);
// 根据appKey从数据库查询密钥
ImApplication imApplication = imApplicationService.getCacheAppByAppKey(appkey);
if (imApplication == null) {
return ApiResult.result(ApiCode.FAIL, null);
}
// 校验appkey 和appSecret
if (!imApplication.getAppSecret().equals(appSecret)) {
return ApiResult.result(ApiCode.FAIL, null);
}
return imMessageService.restApiImMessageSend(imMsgSendToOnlineClient, imApplication);
}
}
package com.wecloud.im.biz.module.message.controller.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import java.io.Serializable;
/**
* @Author wenzhida
* @Date 2022/4/27 16:47
* @Description 聊天室成员VO
*/
@Data
@Accessors(chain = true)
@ApiModel(value = "聊天室成员VO")
@AllArgsConstructor
@NoArgsConstructor
public class ChatRoomMemberVo implements Serializable {
private static final long serialVersionUID = 5417994988121322697L;
@ApiModelProperty("聊天室房间id")
private Long chatRoomId;
@ApiModelProperty("客户端id")
private String clientId;
}
package com.wecloud.im.biz.module.message.controller.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
import com.wecloud.im.biz.enums.RelationEnum;
/**
* @Author wenzhida
* @Date 2022/2/15 11:29
* @Description
*/
@Data
@Accessors(chain = true)
@ApiModel(value = "ClientInfoVo")
public class ClientInfoVo implements Serializable {
private static final long serialVersionUID = 1474979499551389791L;
@ApiModelProperty("client主键id")
private Long id;
@ApiModelProperty("会话中client的备注名")
private String clientRemarkName;
@ApiModelProperty("头像")
private String headPortrait;
@ApiModelProperty("主昵称")
private String nickname;
@ApiModelProperty("clientId")
private String clientId;
@ApiModelProperty("client自己的自定义扩展属性")
private String clientAttributes;
@ApiModelProperty("会话成员列表的自定义扩展属性")
private String memberAttributes;
/**
* 与我关系
* @see RelationEnum
*/
@ApiModelProperty("与我关系 1-陌生人 2-好友 3-被我拉黑")
private Integer relation;
}
package com.wecloud.im.biz.module.message.controller.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
import com.wecloud.im.biz.enums.GroupRoleEnum;
import com.wecloud.im.biz.enums.MutedEnum;
@Data
@Accessors(chain = true)
@ApiModel(value = "ImConversationMemberListVo")
public class ConversationMemberVo implements Serializable {
private static final long serialVersionUID = 7278014943001080361L;
@ApiModelProperty("主键id")
private Long id;
@ApiModelProperty("会话中client的备注名")
private String clientRemarkName;
@ApiModelProperty("头像")
private String headPortrait;
@ApiModelProperty("主昵称")
private String nickname;
@ApiModelProperty("clientId")
private String clientId;
@ApiModelProperty("client自己的自定义扩展属性")
private String clientAttributes;
@ApiModelProperty("会话成员列表的自定义扩展属性")
private String memberAttributes;
/**
* 群内角色
* @see GroupRoleEnum
*/
@ApiModelProperty("群内角色")
private Integer role;
/**
* 禁言开关
* @see MutedEnum
*/
@ApiModelProperty("禁言开关 1-未禁言 2-禁言")
private Integer muted;
}
package com.wecloud.im.biz.module.message.controller.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.Date;
import com.baomidou.mybatisplus.annotation.TableField;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.wecloud.im.biz.enums.MutedEnum;
/**
* <pre>
* 会话表 查询结果对象
* </pre>
*
* @author wei
* @date 2021-05-07
*/
@Data
@Accessors(chain = true)
@ApiModel(value = "MyConversationListVo")
public class ConversationVo implements Serializable {
private static final long serialVersionUID = -4330507756623541941L;
@ApiModelProperty("会话id")
private Long id;
@ApiModelProperty("创建时间")
private Date createTime;
@ApiModelProperty("创建者客户端id")
private String creator;
@ApiModelProperty("可选 对话的名字,可为群组命名。")
private String name;
@ApiModelProperty(value = "可选 自定义属性,供开发者扩展使用。", hidden = true)
@JsonIgnore
private String attribute;
@ApiModelProperty("可选 自定义属性,供开发者扩展使用。")
private String attributes;
@ApiModelProperty("可选 对话类型标志,是否是系统对话,后面会说明。")
private Boolean systemFlag;
@ApiModelProperty("未读消息条数")
private Long msgNotReadCount;
@ApiModelProperty("成员")
private String members;
@ApiModelProperty("会话属性,1:单聊,2:普通群,3:万人群 4:聊天室")
private Integer chatType;
@ApiModelProperty("群成员数")
private Integer memberCount;
@ApiModelProperty("会话最后一条消息")
private OfflineMsgDto lastMsg;
@ApiModelProperty("是否被@ true-是 false-否")
private Boolean isBeAt;
/**
* 禁言开关
* @see MutedEnum
*/
@ApiModelProperty("禁言开关 1-未禁言 2-禁言")
private Integer muted;
@ApiModelProperty("禁言开关 1-未禁言 2-禁言")
private Integer beAtCount;
@ApiModelProperty("禁止互加好友")
private Boolean forbidAddFriend;
@ApiModelProperty("禁止发图片")
private Boolean forbidSendPic;
@ApiModelProperty("禁止发链接")
private Boolean forbidSendLink;
@ApiModelProperty("群头像")
private String headPortrait;
@ApiModelProperty("免打扰开关 0-关闭 1开启")
private Boolean doNotDisturb;
@TableField("is_top")
private Boolean top;
@ApiModelProperty("是否为加密聊天 0-否 1-是")
private Integer isEncrypt;
}
package com.wecloud.im.biz.module.message.controller.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
@Data
@Accessors(chain = true)
@ApiModel(value = "GetInfoListVo")
public class GetInfoListVo implements Serializable {
@ApiModelProperty("client主键id")
private Long id;
@ApiModelProperty("会话中client的备注名")
private String clientRemarkName;
@ApiModelProperty("头像")
private String headPortrait;
@ApiModelProperty("主昵称")
private String nickname;
@ApiModelProperty("clientId")
private String clientId;
@ApiModelProperty("client自己的自定义扩展属性")
private String clientAttributes;
@ApiModelProperty("会话成员列表的自定义扩展属性")
private String memberAttributes;
}
package com.wecloud.im.biz.module.message.controller.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import com.wecloud.can.core.base.entity.BaseEntity;
/**
* 会话表
*
* @author wei
* @since 2021-05-07
*/
@Data
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = true)
@ApiModel(value = "ImConversationCreateVo")
public class ImConversationCreateVo extends BaseEntity {
private static final long serialVersionUID = 1L;
@ApiModelProperty("会话id")
private Long id;
}
package com.wecloud.im.biz.module.message.controller.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.List;
/**
* <pre>
* 离线消息列表 查询结果对象
* </pre>
*
* @author wei
* @date 2021-04-29
*/
@Data
@Accessors(chain = true)
@ApiModel(value = "ImMessageOfflineListVo")
public class ImMessageOfflineListVo implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty("会话id")
private Long conversationId;
@ApiModelProperty("消息列表")
private List<OfflineMsgDto> msgList;
}
package com.wecloud.im.biz.module.message.controller.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import com.wecloud.can.core.base.entity.BaseEntity;
/**
* 在线状态
*
* @author wei
* @since 2021-05-07
*/
@Data
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = true)
@ApiModel(value = "ImOnlineStatusVo")
public class ImOnlineStatusVo extends BaseEntity {
private static final long serialVersionUID = 1L;
@ApiModelProperty("true:在线, false 不在线")
private Boolean status;
private String clientId;
}
package com.wecloud.im.biz.module.message.controller.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.Date;
/**
* <pre>
* 会话表 查询结果对象
* </pre>
*
* @author wei
* @date 2021-05-07
*/
@Data
@Accessors(chain = true)
@ApiModel(value = "MyConversationMemberVo")
public class MyConversationMembersVo implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty("加入时间")
private Date joinTime;
@ApiModelProperty("客户端id")
private String clientId;
@ApiModelProperty("名字")
private String name;
}
package com.wecloud.im.biz.module.message.controller.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.Date;
/**
* @Author wenzhida
* @Date 2022/2/15 16:22
* @Description 我的信息
*/
@Data
@Accessors(chain = true)
@ApiModel(value = "我的信息")
public class MyInfoVo implements Serializable {
private static final long serialVersionUID = -5423843620435586377L;
@ApiModelProperty("主键id")
private Long id;
@ApiModelProperty("clientId")
private String clientId;
@ApiModelProperty("最后离线时间")
private Date lastOfflineTime;
@ApiModelProperty("头像")
private String headPortrait;
@ApiModelProperty("主昵称")
private String nickname;
@ApiModelProperty("可选 自定义属性,供开发者扩展使用。")
private String attributes;
}
package com.wecloud.im.biz.module.message.controller.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.Date;
/**
* @Author wenzhida
* @Date 2022/3/3 11:19
* @Description 离线消息内容实体
*/
@Data
@Accessors(chain = true)
@ApiModel(value = "OfflineMsgDto")
public class OfflineMsgDto implements Serializable {
private static final long serialVersionUID = -7073389493201687249L;
@ApiModelProperty("会话id")
private Long conversationId;
@ApiModelProperty("消息类型")
private Integer type;
@ApiModelProperty("消息id")
private Long msgId;
@ApiModelProperty("创建时间")
private Date createTime;
@ApiModelProperty("撤回时间")
private Date withdrawTime;
@ApiModelProperty("发送者客户端id")
private String sender;
@ApiModelProperty("内容")
private String content;
@ApiModelProperty("0未撤回; 1已撤回")
private Boolean withdraw;
@ApiModelProperty("0非事件; 1为事件")
private Boolean event;
@ApiModelProperty("0非系统通知; 1为系统通知")
private Boolean systemFlag;
@ApiModelProperty("at他人,传入客户端id数组")
private String at;
@ApiModelProperty("未读人数统计,全部人已读为0")
private Integer notReadCount;
@ApiModelProperty("未接收人数统计,全部人已接收为0")
private Integer notReceiverCount;
// @ApiModelProperty("读取时间")
// private Date readTime;
//
// @ApiModelProperty("接收时间")
// private Date receiverTime;
// @ApiModelProperty("0未接收; 1已接收")
// private Integer receiverMsgStatus;
}
package com.wecloud.im.biz.module.message.controller.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.List;
/**
* @Author wenzhida
* @Date 2022/2/15 20:54
* @Description 已读client展示VO
*/
@Data
@Accessors(chain = true)
@ApiModel(value = "已读client展示VO")
public class ReaderList implements Serializable {
private static final long serialVersionUID = 4658402570720540541L;
@ApiModelProperty("已读人员列表")
private List<ReaderVo> readList;
@ApiModelProperty("未读人员列表")
private List<ReaderVo> unReadList;
}
package com.wecloud.im.biz.module.message.controller.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
/**
* @Author wenzhida
* @Date 2022/2/15 20:54
* @Description 读者VO
*/
@Data
@Accessors(chain = true)
@ApiModel(value = "读者VO")
public class ReaderVo implements Serializable {
private static final long serialVersionUID = 4390952170006190474L;
@ApiModelProperty("client主键id")
private Long id;
@ApiModelProperty("头像")
private String headPortrait;
@ApiModelProperty("主昵称")
private String nickname;
@ApiModelProperty("clientId")
private String clientId;
@ApiModelProperty("是否已读 0-否 1-是")
private Integer readMsgStatus;
}
package com.wecloud.im.biz.module.message.controller.vo;
import lombok.Data;
/**
*
* @Author luozh
* @Date 2022年04月13日 17:14
* @Version 1.0
*/
@Data
public class RegisterClientResponse {
private static final long serialVersionUID = 1L;
private Long userId;
}
package com.wecloud.im.biz.module.message.controller.vo;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
@Data
public class TokenVo implements Serializable {
/**
* websocket登陆令牌
*/
private String token;
@ApiModelProperty("客户端id")
private Long id;
@ApiModelProperty("webSocket连接地址")
private String wsAddr;
@ApiModelProperty("加密密钥")
private String dataAesKey;
@ApiModelProperty("可选 自定义属性,供开发者扩展使用。")
private String attributes;
}
package com.wecloud.im.biz.module.message.entity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.util.Date;
import com.wecloud.can.core.base.entity.BaseEntity;
/**
* 消息在线推送
*
* @author wei
* @since 2021-04-29
*/
@Data
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = true)
@ApiModel(value = "ImApiMessageOnlineSend ")
public class ImApiMessageOnlineSend extends BaseEntity {
private static final long serialVersionUID = 1L;
@ApiModelProperty("创建时间")
private Date createTime;
@ApiModelProperty("内容")
private String content;
@ApiModelProperty("会话id")
private Long conversationId;
}
package com.wecloud.im.biz.module.message.entity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.util.Date;
import javax.validation.constraints.NotNull;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.wecloud.can.core.base.entity.BaseEntity;
import com.wecloud.can.security.signature.Application;
/**
* 第三方应用表
*
* @author wei
* @since 2021-04-27
*/
@Data
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = true)
@ApiModel(value = "ImApplication对象")
public class ImApplication extends BaseEntity implements Application {
private static final long serialVersionUID = 1L;
@NotNull(message = "应用appid不能为空")
@ApiModelProperty("应用appid")
@TableId(value = "id", type = IdType.INPUT)
private Long id;
@ApiModelProperty("创建时间")
private Date createTime;
@ApiModelProperty("修改时间")
private Date updateTime;
@ApiModelProperty("key")
private String appKey;
@ApiModelProperty("密钥")
private String appSecret;
@ApiModelProperty("app名称")
private String appName;
@ApiModelProperty("ios推送通道,友盟:1;firebase:2; apns原生:3")
private Integer iosPushChannel;
@ApiModelProperty("安卓推送通道,友盟:1;firebase:2; 信鸽3")
private Integer androidPushChannel;
@ApiModelProperty("友盟推送key")
private String umengKey;
@ApiModelProperty("友盟推送密钥")
private String umengSecret;
@ApiModelProperty("firebase推送密钥")
private String firebaseSecret;
@ApiModelProperty("是否允许创建重复会话 0不允许 1允许")
private Integer repeatSessionStatus;
@ApiModelProperty("创建会话时对比扩展字段 0不 1是")
private Integer contrastExtendedFieldStatus;
@ApiModelProperty("在线状态订阅地址")
private String onlineStatusSubscribeUrl;
@ApiModelProperty("全量消息订阅地址")
private String fullMessageSubscribeUrl;
@ApiModelProperty("租户id")
private Long ownerId;
@ApiModelProperty("公司id")
private Long companyId;
@ApiModelProperty("状态 1-正常 2-异常 3-删除")
private Integer status;
@Override
public Boolean isActive() {
return true;
}
}
package com.wecloud.im.biz.module.message.entity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.util.Date;
import javax.validation.constraints.NotNull;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.wecloud.can.core.base.entity.BaseEntity;
/**
* 终端表
*
* @author wei
* @since 2021-04-27
*/
@Data
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = true)
@ApiModel(value = "ImClient对象")
public class ImClient extends BaseEntity {
private static final long serialVersionUID = 1L;
@NotNull(message = "客户端id不能为空")
@ApiModelProperty("客户端id")
@TableId(value = "id", type = IdType.INPUT)
private Long id;
@ApiModelProperty("创建时间")
private Date createTime;
@ApiModelProperty("最后离线时间")
private Date lastOfflineTime;
@ApiModelProperty("修改时间")
private Date updateTime;
@ApiModelProperty("应用appid")
private Long fkAppid;
@ApiModelProperty("可选 自定义属性,供开发者扩展使用。")
private String attributes;
@ApiModelProperty("客户方提供的唯一id")
private String clientId;
@ApiModelProperty("头像")
private String headPortrait;
@ApiModelProperty("主昵称")
private String nickname;
}
package com.wecloud.im.biz.module.message.entity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.util.Date;
import javax.validation.constraints.NotNull;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.wecloud.can.core.base.entity.BaseEntity;
/**
* 黑名单
*
* @author wei
* @since 2021-06-17
*/
@Data
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = true)
@ApiModel(value = "ImClientBlacklist对象")
public class ImClientBlacklist extends BaseEntity {
private static final long serialVersionUID = 1L;
@NotNull(message = "客户端id不能为空")
@ApiModelProperty("客户端id")
@TableId(value = "id", type = IdType.INPUT)
private Long id;
@ApiModelProperty("创建时间")
private Date createTime;
@ApiModelProperty("修改时间")
private Date updateTime;
@ApiModelProperty("应用appid")
private Long fkAppid;
@ApiModelProperty("拉黑者")
private String clientIdPrevent;
@ApiModelProperty("被拉黑")
private String clientIdBePrevent;
}
package com.wecloud.im.biz.module.message.entity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.util.Date;
import javax.validation.constraints.NotNull;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.wecloud.can.core.base.entity.BaseEntity;
/**
* @Author wenzhida
* @Date 2022/3/2 14:52
* @Description 客户端设备
*/
@Data
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = true)
@ApiModel(value = "客户端设备")
public class ImClientDevice extends BaseEntity {
private static final long serialVersionUID = 6988763580951760226L;
@NotNull(message = "主键id不能为空")
@ApiModelProperty("主键id")
@TableId(value = "id", type = IdType.INPUT)
private Long id;
@ApiModelProperty("应用appid")
private Long fkAppid;
@ApiModelProperty("client主键id")
private Long fkClientId;
@ApiModelProperty("设备不想收到推送提醒, 1想, 0不想")
private Integer valid;
@ApiModelProperty("设备类型 1:ios; 2:android; 3:web; 4:win; 5:mac")
private Integer deviceType;
@ApiModelProperty("设备推送token")
private String deviceToken;
@ApiModelProperty("唯一id")
private String uniqueDeviceId;
@ApiModelProperty("创建时间")
private Date createTime;
@ApiModelProperty("修改时间")
private Date updateTime;
}
package com.wecloud.im.biz.module.message.entity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.util.Date;
import javax.validation.constraints.NotNull;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.wecloud.can.core.base.entity.BaseEntity;
import com.wecloud.im.biz.enums.ChatTypeEnum;
import com.wecloud.im.biz.enums.MutedEnum;
/**
* 会话表
*
* @author wei
* @since 2021-05-07
*/
@Data
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = true)
@ApiModel(value = "ImConversation对象")
public class ImConversation extends BaseEntity {
private static final long serialVersionUID = 1L;
@NotNull(message = "会话id不能为空")
@ApiModelProperty("会话id")
@TableId(value = "id", type = IdType.INPUT)
private Long id;
@ApiModelProperty("创建时间")
private Date createTime;
@ApiModelProperty("修改时间")
private Date updateTime;
@ApiModelProperty("对话中最后一条消息的发送或接收时间")
private Date lastMessage;
@ApiModelProperty("群成员数量")
private Integer memberCount;
/**
* 会话属性
* @see ChatTypeEnum
*/
@ApiModelProperty("会话属性,1:单聊,2:普通群,3:万人群,4:聊天室")
private Integer chatType;
@NotNull(message = "应用appid不能为空")
@ApiModelProperty("应用appid")
private Long fkAppid;
@NotNull(message = "创建者客户端id不能为空")
@ApiModelProperty("创建者客户端id")
private Long creator;
@ApiModelProperty("可选 对话的名字,可为群组命名。")
private String name;
@ApiModelProperty("群头像")
private String headPortrait;
@ApiModelProperty("可选 自定义属性,供开发者扩展使用。")
private String attributes;
@ApiModelProperty("可选 对话类型标志,是否是系统对话,后面会说明。")
private Boolean systemFlag;
/**
* 禁言开关
* @see MutedEnum
*/
@ApiModelProperty("禁言开关 1-未禁言 2-禁言")
private Integer muted;
@TableField("is_forbid_add_friend")
@ApiModelProperty("禁止互加好友")
private Boolean forbidAddFriend;
@TableField("is_forbid_send_pic")
@ApiModelProperty("禁止发图片")
private Boolean forbidSendPic;
@TableField("is_forbid_send_link")
@ApiModelProperty("禁止发链接")
private Boolean forbidSendLink;
@ApiModelProperty("是否为加密聊天 0-否 1-是")
private Integer isEncrypt;
}
package com.wecloud.im.biz.module.message.entity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.util.Date;
import javax.validation.constraints.NotNull;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.wecloud.can.core.base.entity.BaseEntity;
import com.wecloud.im.biz.enums.GroupRoleEnum;
import com.wecloud.im.biz.enums.MutedEnum;
/**
* 会话成员表
*
* @author wei
* @since 2021-05-07
*/
@Data
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = true)
@ApiModel(value = "ImConversationMembers对象")
public class ImConversationMembers extends BaseEntity {
private static final long serialVersionUID = 1L;
@NotNull(message = "唯一id不能为空")
@ApiModelProperty("唯一id")
@TableId(value = "id", type = IdType.INPUT)
private Long id;
@ApiModelProperty("加入时间")
private Date createTime;
@ApiModelProperty("修改时间")
private Date updateTime;
@NotNull(message = "应用appid不能为空")
@ApiModelProperty("应用appid")
private Long fkAppid;
@NotNull(message = "会话表id不能为空")
@ApiModelProperty("会话表id")
private Long fkConversationId;
@NotNull(message = "客户端id不能为空")
@ApiModelProperty("客户端id")
private Long fkClientId;
@ApiModelProperty("可选 自定义属性,供开发者扩展使用。")
private String attributes;
@NotNull(message = "单向删除(隐藏)会话, 0不显示, 1显示不能为空")
@ApiModelProperty("单向删除(隐藏)会话, 0不显示, 1显示")
private Long displayStatus;
@ApiModelProperty("会话中client的备注名")
private String clientRemarkName;
/**
* 群内角色
* @see GroupRoleEnum
*/
@ApiModelProperty("群内角色")
private Integer role;
/**
* 禁言开关
* @see MutedEnum
*/
@ApiModelProperty("禁言开关 1-未禁言 2-禁言")
private Integer muted;
/**
* 客户方提供的唯一id
*/
@ApiModelProperty("客户方提供的唯一id")
private String clientId;
@ApiModelProperty("免打扰开关 0-关闭 1开启")
@TableField("is_do_not_disturb")
private Boolean doNotDisturb;
@ApiModelProperty("置顶开关 0-关闭 1开启")
@TableField("is_top")
private Boolean top;
@ApiModelProperty("加入会话方式编码")
private String joinTypeCode;
@ApiModelProperty("加入会话方式信息")
private String joinTypeMsg;
}
package com.wecloud.im.biz.module.message.entity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.util.Date;
import javax.validation.constraints.NotNull;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.wecloud.can.core.base.entity.BaseEntity;
import com.wecloud.im.biz.enums.FriendStateEnum;
/**
* @author lixiaozhong
* 好友关系表
*/
@Data
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = true)
@ApiModel(value = "ImFriend对象")
public class ImFriend extends BaseEntity {
private static final long serialVersionUID = 1L;
@NotNull(message = "主键id不能为空")
@ApiModelProperty("主键id")
@TableId(value = "id", type = IdType.INPUT)
private Long id;
@ApiModelProperty("我的client-id")
private String clientId;
@ApiModelProperty("好友的client-id")
private String clientIdFriend;
@ApiModelProperty("申请者")
private String clientIdClaimer;
@ApiModelProperty("好友的昵称备注")
private String friendName;
@ApiModelProperty("好友拒绝原因")
private String rejectRemark;
@ApiModelProperty("好友请求说明")
private String requestRemark;
/**
* 好友关系状态
* @see FriendStateEnum
*/
@ApiModelProperty("好友关系状态")
private Integer state;
@ApiModelProperty("创建时间")
private Date createTime;
@ApiModelProperty("修改时间")
private Date updateTime;
}
package com.wecloud.im.biz.module.message.entity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.util.Date;
import javax.validation.constraints.NotNull;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.wecloud.can.core.base.entity.BaseEntity;
/**
* @author lixiaozhong
* 好友关系表
*/
@Data
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = true)
@ApiModel(value = "ImFriendRecommend好友推荐对象")
public class ImFriendRecommend extends BaseEntity {
private static final long serialVersionUID = 1L;
@NotNull(message = "主键id不能为空")
@ApiModelProperty("主键id")
@TableId(value = "id", type = IdType.INPUT)
private Long id;
@ApiModelProperty("我的client-id")
private String clientId;
@ApiModelProperty("好友的client-id")
private String clientIdFriend;
@ApiModelProperty("推荐来源")
private Integer source;
@ApiModelProperty("是否删除")
private Boolean delFlag;
@ApiModelProperty("创建时间")
private Date createTime;
@ApiModelProperty("修改时间")
private Date updateTime;
}
package com.wecloud.im.biz.module.message.entity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.util.Date;
import javax.validation.constraints.NotNull;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.wecloud.can.core.base.entity.BaseEntity;
/**
* 消息收件箱表
*
* @author wei
* @since 2021-05-06
*/
@Data
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = true)
@TableName("im_inbox")
@ApiModel(value = "ImInbox对象")
public class ImInbox extends BaseEntity {
private static final long serialVersionUID = 1L;
@NotNull(message = "收件id不能为空")
@ApiModelProperty("收件id")
@TableId(value = "id", type = IdType.INPUT)
private Long id;
@ApiModelProperty("创建时间")
private Date createTime;
@ApiModelProperty("修改时间")
private Date updateTime;
@ApiModelProperty("读取时间")
private Date readTime;
@ApiModelProperty("接收时间")
private Date receiverTime;
@NotNull(message = "应用appid不能为空")
@ApiModelProperty("应用appid")
private Long fkAppid;
@NotNull(message = "接收客户端id不能为空")
@ApiModelProperty("接收客户端id")
private Long receiver;
@NotNull(message = "消息id不能为空")
@ApiModelProperty("消息id")
private Long fkMsgId;
@ApiModelProperty("0未读; 1已读")
private Integer readMsgStatus;
@ApiModelProperty("0未接收; 1已接收")
private Integer receiverMsgStatus;
@NotNull(message = "会话id不能为空")
@ApiModelProperty("会话id")
private Long fkConversationId;
}
package com.wecloud.im.biz.module.message.entity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import javax.validation.constraints.NotNull;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.wecloud.can.core.base.entity.BaseEntity;
/**
* apns配置表
*
* @author wei
* @since 2021-09-18
*/
@Data
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = true)
@ApiModel(value = "ImIosApns对象")
public class ImIosApns extends BaseEntity {
private static final long serialVersionUID = 1L;
@NotNull(message = "id不能为空")
@ApiModelProperty("id")
@TableId(value = "id", type = IdType.INPUT)
private Long id;
@NotNull(message = "应用appid不能为空")
@ApiModelProperty("应用appid")
private Long fkAppId;
@ApiModelProperty("Base64(apns.p12)")
private String apnsFileValue;
@ApiModelProperty("环境,正式1,测试0")
private Integer env;
@ApiModelProperty("bundle_id")
private String bundleId;
@ApiModelProperty("证书密码")
private String pwd;
}
package com.wecloud.im.biz.module.message.entity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.util.Date;
import javax.validation.constraints.NotNull;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.wecloud.can.core.base.entity.BaseEntity;
/**
* 消息存储表
*
* @author wei
* @since 2021-04-29
*/
@Data
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = true)
@ApiModel(value = "ImMessage对象")
public class ImMessage extends BaseEntity {
private static final long serialVersionUID = 1L;
@NotNull(message = "消息id不能为空")
@ApiModelProperty("消息id")
@TableId(value = "id", type = IdType.INPUT)
private Long id;
@ApiModelProperty("创建时间")
private Date createTime;
@ApiModelProperty("撤回时间")
private Date withdrawTime;
@ApiModelProperty("修改时间")
private Date updateDate;
@NotNull(message = "应用appid不能为空")
@ApiModelProperty("应用appid")
private Long fkAppid;
@ApiModelProperty("发送者客户端id")
private Long sender;
@ApiModelProperty("接收人,多人用英文逗号分隔-群内指定人员可见场景")
private String receivers;
/**
* 数据库字段类型为JSON格式
* 因mysql关系型数据库非MongoDB文档类型数据库,第三方应用拓展的自定义参数名和值需使用json格式落库
*/
@ApiModelProperty("内容")
private String content;
@ApiModelProperty("0未撤回; 1已撤回")
private Boolean withdraw;
@ApiModelProperty("0非事件; 1为事件")
private Boolean event;
@ApiModelProperty("0非系统通知; 1为系统通知")
private Boolean systemFlag;
@ApiModelProperty("at他人,传入客户端id数组")
private String at;
@ApiModelProperty("1 AVIMMessageStatusSending(发送中)" +
"2 AVIMMessageStatusSent(发送成功)" +
"3 AVIMMessageStatusFailed(失败)")
private Integer sendStatus;
@ApiModelProperty("会话id")
private Long fkConversationId;
@ApiModelProperty("消息类型")
private Integer msgType;
@ApiModelProperty("是否删除 1-未删除 2-已删除")
private Integer isDelete;
}
package com.wecloud.im.biz.module.message.entity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.util.Date;
import javax.validation.constraints.NotNull;
import com.wecloud.can.core.base.entity.BaseEntity;
/**
* 消息在线推送
*
* @author wei
* @since 2021-04-29
*/
@Data
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = true)
@ApiModel(value = "ImMessageOnlineSend ")
public class ImMessageOnlineSend extends BaseEntity {
private static final long serialVersionUID = 1L;
/**
* 消息类型
* @see com.wecloud.im.server.enums.MsgTypeEnum
*/
@ApiModelProperty("消息类型")
private Integer type;
@NotNull(message = "消息id不能为空")
@ApiModelProperty("消息id")
private Long msgId;
@ApiModelProperty("创建时间")
private Date createTime;
@ApiModelProperty("撤回时间")
private Date withdrawTime;
@ApiModelProperty("发送者客户端id")
private String sender;
@ApiModelProperty("内容")
private Object content;
@ApiModelProperty("0未撤回; 1已撤回")
private Boolean withdraw;
@ApiModelProperty("0非事件; 1为事件")
private Boolean event;
@ApiModelProperty("0非系统通知; 1为系统通知")
private Boolean systemFlag;
@ApiModelProperty("at他人,传入客户端id数组")
private String at;
@ApiModelProperty("会话id")
private Long conversationId;
}
package com.wecloud.im.biz.module.message.entity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.util.Date;
import javax.validation.constraints.NotNull;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.wecloud.can.core.base.entity.BaseEntity;
import com.wecloud.im.biz.enums.MultiRtcRoomStateEnum;
/**
* @Author wenzhida
* @Date 2022/3/15 23:09
* @Description 多人音视频房间
*/
@Data
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = true)
@ApiModel(value = "多人音视频房间")
public class ImMultiRtcRoom extends BaseEntity {
private static final long serialVersionUID = -523597842194055670L;
@NotNull(message = "主键id不能为空")
@ApiModelProperty("主键id")
@TableId(value = "id", type = IdType.INPUT)
private Long id;
@ApiModelProperty("应用appid")
private Long fkAppid;
@ApiModelProperty("房间id")
private String roomId;
/**
* 多人音视频房间状态枚举
* @see MultiRtcRoomStateEnum
*/
@ApiModelProperty("房间状态,1:已创建,2:会议中,3:会议结束")
private Integer state;
@ApiModelProperty("创建时间")
private Date createTime;
@ApiModelProperty("修改时间")
private Date updateTime;
}
package com.wecloud.im.biz.module.message.entity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.util.Date;
import javax.validation.constraints.NotNull;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.wecloud.can.core.base.entity.BaseEntity;
import com.wecloud.im.biz.enums.MultiRtcMemberStateEnum;
/**
* @Author wenzhida
* @Date 2022/3/15 23:09
* @Description 多人音视频房间成员
*/
@Data
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = true)
@ApiModel(value = "多人音视频房间成员")
public class ImMultiRtcRoomMember extends BaseEntity {
private static final long serialVersionUID = -3806432271911087255L;
@NotNull(message = "主键id不能为空")
@ApiModelProperty("主键id")
@TableId(value = "id", type = IdType.INPUT)
private Long id;
@ApiModelProperty("房间id")
private String roomId;
@ApiModelProperty("im房间id")
private Long fkRtcRoomId;
@ApiModelProperty("client主键id")
private Long fkClientId;
@ApiModelProperty("客户端id")
private String clientId;
/**
* 多人音视频房间成员状态枚举
* @see MultiRtcMemberStateEnum
*/
@ApiModelProperty("房间成员状态,1:呼叫中,2:已接听,3:已拒绝,4:未接听,5:已断开")
private Integer state;
@ApiModelProperty("呼叫时间")
private Date callTime;
@ApiModelProperty("心跳时间")
private Date heartbeatTime;
@ApiModelProperty("创建时间")
private Date createTime;
@ApiModelProperty("修改时间")
private Date updateTime;
}
package com.wecloud.im.biz.module.message.entity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.util.Date;
import javax.validation.constraints.NotNull;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.wecloud.can.core.base.entity.BaseEntity;
import com.wecloud.im.biz.enums.RtcStateEnum;
/**
* @Author Future
* @Date 2022/5/22 23:40
* @Description 单人音视频记录表
*/
@Data
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = true)
@ApiModel(value = "单人音视频记录")
public class ImRtcRecord extends BaseEntity {
private static final long serialVersionUID = -523597842194055670L;
@NotNull(message = "主键id不能为空")
@ApiModelProperty("主键id")
@TableId(value = "id", type = IdType.INPUT)
private Long id;
@ApiModelProperty("应用appid")
private Long fkAppid;
@ApiModelProperty("频道id")
private Long channelId;
@ApiModelProperty("发起方clientId")
private String fromClientId;
@ApiModelProperty("接收方clientId")
private String toClientId;
@ApiModelProperty(value = "音视频类型: 1-video或2-voice")
private Integer callType;
/**
* 单人音视频状态枚举
* @see RtcStateEnum
*/
@ApiModelProperty("频道状态,1:音视频发起,2:音视频中,3:音视频结束")
private Integer state;
@ApiModelProperty("音视频开始时间")
private Date startTime;
@ApiModelProperty("音视频结束时间")
private Date endTime;
@ApiModelProperty("通话过程中离线次数统计 用于区分异常断线使用")
private Integer offlineTimes;
@ApiModelProperty("创建时间")
private Date createTime;
@ApiModelProperty("修改时间")
private Date updateTime;
}
package com.wecloud.im.biz.module.message.mapper;
import java.io.Serializable;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wecloud.im.biz.module.message.controller.param.ImApplicationPageParam;
import com.wecloud.im.biz.module.message.controller.param.ImApplicationQueryVo;
import com.wecloud.im.biz.module.message.entity.ImApplication;
/**
* 第三方应用表 Mapper 接口
*
* @author wei
* @since 2021-04-27
*/
@Repository
public interface ImApplicationMapper extends BaseMapper<ImApplication> {
/**
* 根据ID获取查询对象
*
* @param id
* @return
*/
ImApplicationQueryVo getImApplicationById(Serializable id);
/**
* 获取分页对象
*
* @param page
* @param imApplicationPageParam
* @return
*/
IPage<ImApplicationQueryVo> getImApplicationPageList(@Param("page") Page page, @Param("param") ImApplicationPageParam imApplicationPageParam);
}
package com.wecloud.im.biz.module.message.mapper;
import java.io.Serializable;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wecloud.im.biz.module.message.controller.param.ImClientBlacklistQueryVo;
import com.wecloud.im.biz.module.message.entity.ImClientBlacklist;
/**
* 黑名单 Mapper 接口
*
* @author wei
* @since 2021-06-17
*/
@Repository
public interface ImClientBlacklistMapper extends BaseMapper<ImClientBlacklist> {
/**
* 查询我的拉黑列表
* @param page
* @param clientId
* @return
*/
IPage<ImClientBlacklistQueryVo> getImClientBlacklistPageList(@Param("page") Page page, @Param("clientId") String clientId);
/**
* 根据ID获取查询对象
*
* @param id
* @return
*/
ImClientBlacklistQueryVo getImClientBlacklistById(Serializable id);
// /**
// * 获取分页对象
// *
// * @param page
// * @param imClientBlacklistPageParam
// * @return
// */
// IPage<ImClientBlacklistQueryVo> getImClientBlacklistPageList(@Param("page") Page page, @Param("param") ImClientBlacklistPageParam imClientBlacklistPageParam);
}
package com.wecloud.im.biz.module.message.mapper;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.wecloud.im.biz.module.message.entity.ImClientDevice;
/**
* @Author wenzhida
* @Date 2022/3/2 14:57
* @Description 客户端设备mapper
*/
@Repository
public interface ImClientDeviceMapper extends BaseMapper<ImClientDevice> {
/**
* 清除旧token
* @param appId
* @param deviceToken
* @return
*/
int removeOldToken(@Param("appId") Long appId, @Param("deviceToken") String deviceToken);
}
package com.wecloud.im.biz.module.message.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wecloud.im.biz.module.message.controller.param.ImClientPageParam;
import com.wecloud.im.biz.module.message.controller.param.ImClientQueryVo;
import com.wecloud.im.biz.module.message.controller.param.ImClientSimpleDto;
import com.wecloud.im.biz.module.message.controller.vo.GetInfoListVo;
import com.wecloud.im.biz.module.message.entity.ImClient;
/**
* 终端表 Mapper 接口
*
* @author wei
* @since 2021-04-27
*/
@Repository
public interface ImClientMapper extends BaseMapper<ImClient> {
/**
* 获取分页对象
*
* @param page
* @param imClientPageParam
* @return
*/
IPage<ImClientQueryVo> getImClientPageList(@Param("page") Page page, @Param("param") ImClientPageParam imClientPageParam);
List<GetInfoListVo> getInfoList(@Param("appId") Long appId, @Param("conversationId") Long conversationId, @Param("clientIds") List<String> clientIds);
List<ImClientSimpleDto> getSimpleClients(@Param("appId")Long appId, @Param("clientIds")List<String> clientIds);
List<ImClientSimpleDto> getSimpleClientsByIds(@Param("ids") List<Long> ids);
}
package com.wecloud.im.biz.module.message.mapper;
import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wecloud.im.biz.module.message.controller.param.ImConversationPageParam;
import com.wecloud.im.biz.module.message.controller.param.ImConversationQueryVo;
import com.wecloud.im.biz.module.message.controller.vo.ConversationVo;
import com.wecloud.im.biz.module.message.entity.ImConversation;
/**
* 会话表 Mapper 接口
*
* @author wei
* @since 2021-05-07
*/
@Repository
public interface ImConversationMapper extends BaseMapper<ImConversation> {
/**
* 根据ID获取查询对象
*
* @param id
* @return
*/
ImConversationQueryVo getImConversationById(Serializable id);
/**
* 获取分页对象
*
* @param page
* @param imConversationPageParam
* @return
*/
IPage<ImConversationQueryVo> getImConversationPageList(@Param("page") Page page, @Param("param") ImConversationPageParam imConversationPageParam);
/**
* 查询用户加入的所有会话 与每个会话的未读条数 成员
*
* @param currentClientId
* @return
*/
List<ConversationVo> getMyImConversationListAndMsgCount(@Param("currentClientId") Long currentClientId, @Param("clientId") String clientId, @Param("conversationId") Long conversationId);
/**
* 查询用户加入的所有会话
*
* @param clientId
* @return
*/
List<ImConversation> getMyImConversationList(@Param("clientId") Long clientId);
/**
* 查询已经存在的一对一会话信息
*
* @param clientId1
* @param clientId2
* @param isEncrypt 是否加密会话 1-是 0-否
* @return
*/
ImConversation getRepetitionConversationSingle(@Param("clientId1") Long clientId1, @Param("clientId2") Long clientId2, @Param("isEncrypt") Integer isEncrypt);
/**
* 判断重复会话中的Attributes是否一样
*
* @param clientId1
* @param clientId2
* @param attributes
* @return 大于等于1为有重复会话
*/
Long getRepetitionConversationAttributes(@Param("clientId1") Long clientId1, @Param("clientId2") Long clientId2, @Param("attributes") String attributes);
/**
* 增减成员数量
* @param appId fkAppid
* @param conversationId 会话id
* @param addCount 要增减的人数, 负数是减
* @return
*/
boolean addMemberCount(@Param("appId") Long appId, @Param("conversationId") Long conversationId, @Param("addCount") int addCount);
/**
* 升级成万人群
* @param appId fkAppId
* @param conversationId 会话id
* @return 成功则返回true
*/
boolean upgradeToThousandChat(@Param("appId") Long appId, @Param("conversationId") Long conversationId);
/**
* 获取发件人和收件人会话列表
* @Author luozh
* @Date 2022年05月06日 07:15:05
* @param senderClientId 发件人im client id
* @param receiverClientIds 收件人 im client ids
* @Return
*/
List<ImConversation> getConversationBySenderAndReceivers(@Param("senderImClientId") Long senderImClientId, @Param(
"receiverImClientIds") Collection<Long> receiverImClientIds);
}
package com.wecloud.im.biz.module.message.mapper;
import java.io.Serializable;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wecloud.im.biz.module.message.controller.param.ApiImConversationMembersQueryVo;
import com.wecloud.im.biz.module.message.controller.param.ImConversationMembersPageParam;
import com.wecloud.im.biz.module.message.controller.param.ImConversationMembersQueryVo;
import com.wecloud.im.biz.module.message.controller.param.ListConversationMembersParam;
import com.wecloud.im.biz.module.message.controller.vo.ConversationMemberVo;
import com.wecloud.im.biz.module.message.entity.ImConversationMembers;
/**
* 会话成员表 Mapper 接口
*
* @author wei
* @since 2021-05-07
*/
@Repository
public interface ImConversationMembersMapper extends BaseMapper<ImConversationMembers> {
/**
* 根据ID获取查询对象
*
* @param id
* @return
*/
ImConversationMembersQueryVo getImConversationMembersById(Serializable id);
List<ApiImConversationMembersQueryVo> getRestApiImConversationMembersList(@Param("conversationId") Long conversationId);
/**
* 获取群成员列表
* @param param 入参
* @return
*/
List<ConversationMemberVo> getImConversationMembersList(@Param("param") ListConversationMembersParam param);
/**
* 获取分页对象
*
* @param page
* @param imConversationMembersPageParam
* @return
*/
IPage<ImConversationMembersQueryVo> getImConversationMembersPageList(@Param("page") Page page, @Param("param") ImConversationMembersPageParam imConversationMembersPageParam);
List<Long> findThousandGroupsByClientId(@Param("clientId") Long clientId);
/**
* 批量设置群成员
* @param conversationId
* @param fkClientIds
*/
void setAdminsForConversation(@Param("conversationId") Long conversationId, @Param("fkClientIds") List<Long> fkClientIds, @Param("role") Integer role);
/**
* 根据会话id删除群成员
* @param conversationId
*/
void deleteByConversationId(@Param("conversationId") Long conversationId);
}
package com.wecloud.im.biz.module.message.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wecloud.im.biz.module.message.entity.ImFriend;
import com.wecloud.im.biz.module.message.param.ImFriendApplyDto;
import com.wecloud.im.biz.module.message.param.ImFriendBaseDto;
/**
* @Description 好友关系mapper
* @Author lixiaozhong
* @Date 2022/1/12 11:41 上午
*/
@Repository
public interface ImFriendMapper extends BaseMapper<ImFriend> {
IPage<ImFriendBaseDto> getImFriendPageList(@Param("page") Page<ImFriendBaseDto> page, @Param("clientId") String clientId);
/**
* 获取待验证的好友列表
* @param page
* @param clientId
* @return
*/
IPage<ImFriendApplyDto> getApplyFriendPageList(@Param("page") Page<ImFriendApplyDto> page, @Param("clientId") String clientId);
ImFriendApplyDto getFriendInfo(@Param("clientId") String clientId, @Param("friendClientId") String friendClientId);
/**
* 过滤得到真的好友,非好友的friendId将被它忽略
* @param clientId
* @param friendClientIds
* @return
*/
List<String> filterNegativeFriends(@Param("clientId") String clientId, @Param("friendClientIds") List<String> friendClientIds);
/**
* 批量删除好友
* @param clientId 删除人的clientId
* @param fkAppId
* @param friendClientIds 被删除人的clientId列表
*/
void batchDeleteFriend(@Param("clientId") String clientId, @Param("fkAppId") Long fkAppId, @Param("friendClientIds") List<String> friendClientIds);
}
package com.wecloud.im.biz.module.message.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wecloud.im.biz.module.message.entity.ImFriendRecommend;
import com.wecloud.im.biz.module.message.param.ImFriendRecommendDto;
/**
* @Description 好友推荐关系mapper
* @Author lixiaozhong
* @Date 2022/1/12 11:41 上午
*/
@Repository
public interface ImFriendRecommendMapper extends BaseMapper<ImFriendRecommend> {
IPage<ImFriendRecommendDto> getImFriendRecommendPageList(@Param("page") Page pageParam, @Param("clientId") Long clientId);
/**
* 批量删除好友推荐
* @param clientId
* @param fkAppId
* @param friendClientIds
*/
void batchDeleteRecommend(@Param("clientId") String clientId, @Param("fkAppId") Long fkAppId, @Param("friendClientIds") List<String> friendClientIds);
void batchCreateRecommend(@Param("list") List<ImFriendRecommend> list);
}
package com.wecloud.im.biz.module.message.mapper;
import java.io.Serializable;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wecloud.im.biz.module.message.controller.param.ImInboxPageParam;
import com.wecloud.im.biz.module.message.controller.param.ImInboxQueryVo;
import com.wecloud.im.biz.module.message.entity.ImInbox;
/**
* 消息收件箱表 Mapper 接口
*
* @author wei
* @since 2021-05-06
*/
@Repository
public interface ImInboxMapper extends BaseMapper<ImInbox> {
/**
* 根据ID获取查询对象
*
* @param id
* @return
*/
ImInboxQueryVo getImInboxById(Serializable id);
/**
* 获取分页对象
*
* @param page
* @param imInboxPageParam
* @return
*/
IPage<ImInboxQueryVo> getImInboxPageList(@Param("page") Page page, @Param("param") ImInboxPageParam imInboxPageParam);
Long updateImMsgReceivedByIds(@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.biz.module.message.mapper;
import java.io.Serializable;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wecloud.im.biz.module.message.controller.param.ImIosApnsPageParam;
import com.wecloud.im.biz.module.message.controller.param.ImIosApnsQueryVo;
import com.wecloud.im.biz.module.message.entity.ImIosApns;
/**
* apns配置表 Mapper 接口
*
* @author wei
* @since 2021-09-18
*/
@Repository
public interface ImIosApnsMapper extends BaseMapper<ImIosApns> {
/**
* 根据ID获取查询对象
*
* @param id
* @return
*/
ImIosApnsQueryVo getImIosApnsById(Serializable id);
/**
* 获取分页对象
*
* @param page
* @param imIosApnsPageParam
* @return
*/
IPage<ImIosApnsQueryVo> getImIosApnsPageList(@Param("page") Page page, @Param("param") ImIosApnsPageParam imIosApnsPageParam);
}
package com.wecloud.im.biz.module.message.mapper;
import java.io.Serializable;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wecloud.im.biz.module.message.controller.param.GetReadersParam;
import com.wecloud.im.biz.module.message.controller.param.ImHistoryMessagePageParam;
import com.wecloud.im.biz.module.message.controller.param.ImMessagePageParam;
import com.wecloud.im.biz.module.message.controller.param.ImMessageQueryVo;
import com.wecloud.im.biz.module.message.controller.vo.OfflineMsgDto;
import com.wecloud.im.biz.module.message.controller.vo.ReaderVo;
import com.wecloud.im.biz.module.message.entity.ImMessage;
/**
* 消息存储表 Mapper 接口
*
* @author wei
* @since 2021-04-29
*/
@Repository
public interface ImMessageMapper extends BaseMapper<ImMessage> {
/**
* 根据ID获取查询对象
*
* @param id
* @return
*/
ImMessageQueryVo getImMessageById(Serializable id);
/**
* 获取分页对象
*
* @param page
* @param imMessagePageParam
* @return
*/
IPage<ImMessageQueryVo> getImMessagePageList(@Param("page") Page page, @Param("param") ImMessagePageParam imMessagePageParam);
/**
* 查询某个会话历史消息分页列表
*
* @param page
* @param imHistoryMessagePageParam
* @return
*/
IPage<OfflineMsgDto> getHistoryMsgConversationId(@Param("page") Page page, @Param("param") ImHistoryMessagePageParam imHistoryMessagePageParam);
IPage<OfflineMsgDto> getHistoryMsgConversationIdNew(@Param("page") Page page, @Param("param") ImHistoryMessagePageParam imHistoryMessagePageParam);
/**
* 根据客户端id与会话id 查询离线消息
*
* @param clientId
* @param conversationId
* @return
*/
List<OfflineMsgDto> getOfflineListByClientAndConversation(@Param("clientId") Long clientId, @Param("conversationId") Long conversationId);
/**
* 查询会话接收的的最后一条消息
*
* @param clientId
* @param conversationId
* @return
*/
OfflineMsgDto getReceivedLastMsgByConversationId(@Param("clientId") Long clientId, @Param("conversationId") Long conversationId);
/**
* 查询会话的最后一条消息
*
* @param conversationId
* @return
*/
OfflineMsgDto getLastMsgByConversationId(@Param("conversationId") Long conversationId, @Param("currentFkClientId") Long currentFkClientId);
/**
* 获取一条消息已读人员和未读人员
* @param currentClientId
* @param param
* @return
*/
List<ReaderVo> getReaders(@Param("currentClientId") Long currentClientId, @Param("param") GetReadersParam param);
}
package com.wecloud.im.biz.module.message.mapper;
import org.springframework.stereotype.Repository;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.wecloud.im.biz.module.message.entity.ImMultiRtcRoom;
/**
* @Author wenzhida
* @Date 2022/3/16 9:19
* @Description 多人音视频房间mapper
*/
@Repository
public interface ImMultiRtcRoomMapper extends BaseMapper<ImMultiRtcRoom> {
}
package com.wecloud.im.biz.module.message.mapper;
import org.springframework.stereotype.Repository;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.wecloud.im.biz.module.message.entity.ImMultiRtcRoomMember;
/**
* @Author wenzhida
* @Date 2022/3/16 9:19
* @Description 多人音视频房间mapper
*/
@Repository
public interface ImMultiRtcRoomMemberMapper extends BaseMapper<ImMultiRtcRoomMember> {
}
package com.wecloud.im.biz.module.message.mapper;
import org.springframework.stereotype.Repository;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.wecloud.im.biz.module.message.entity.ImRtcRecord;
/**
* @Author Future
* @Date 2022/5/22 23:49
* @Description 单人音视频记录mapper
*/
@Repository
public interface ImRtcRecordMapper extends BaseMapper<ImRtcRecord> {
}
package com.wecloud.im.biz.module.message.param;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* @Description TODO
* @Author lixiaozhong
* @Date 2022/1/14 11:56 上午
*/
@Data
public class FriendApplyEventDto extends FriendBaseEventDto {
@ApiModelProperty("好友请求说明")
private String requestRemark;
}
package com.wecloud.im.biz.module.message.param;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* @Description TODO
* @Author lixiaozhong
* @Date 2022/1/14 11:56 上午
*/
@Data
public class FriendApproveEventDto extends FriendBaseEventDto {
@ApiModelProperty("是否同意接受好友,true同意,false拒绝")
private Boolean agree;
@ApiModelProperty("好友拒绝原因")
private String rejectRemark;
}
package com.wecloud.im.biz.module.message.param;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
import com.wecloud.im.biz.enums.EventResponseSubCmdEnum;
/**
* @Description TODO
* @Author lixiaozhong
* @Date 2022/1/14 11:56 上午
*/
@Data
public class FriendBaseEventDto implements Serializable {
/**
* 参考 {@link EventResponseSubCmdEnum EventResponseSubCmdEnum}
*/
@ApiModelProperty("响应命令")
private Integer subCmd;
@ApiModelProperty("申请人的client-id")
private String claimerClientId;
@ApiModelProperty("好友的client-id")
private String friendClientId;
}
package com.wecloud.im.biz.module.message.param;
import lombok.Data;
/**
* 好友备注请求
* @Author luozh
* @Date 2022年05月16日 11:09
* @Version 1.0
*/
@Data
public class FriendRemarkParam {
/**
* 用户id
*/
private String userId;
/**
* 朋友用户id
*/
private String friendUserId;
/**
* 备注
*/
private String friendRemark;
}
package com.wecloud.im.biz.module.message.param;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
/**
* @Author wenzhida
* @Date 2022/2/7 16:30
* @Description 批量创建好友推荐入参
*/
@Data
public class ImCreateRecommendParam implements Serializable {
private static final long serialVersionUID = 5228604783548712598L;
@ApiModelProperty("推荐好友列表")
private List<ImFriendRecommendDto> recommendFriends;
}
package com.wecloud.im.biz.module.message.param;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
/**
* @Author wenzhida
* @Date 2022/2/7 16:30
* @Description 删除好友入参
*/
@Data
public class ImDeleteFriendParam implements Serializable {
private static final long serialVersionUID = 5228604783548712598L;
@ApiModelProperty("好友的client-id")
private List<String> friendClientIds;
}
package com.wecloud.im.biz.module.message.param;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
/**
* @Author wenzhida
* @Date 2022/2/7 16:30
* @Description 批量删除好友推荐入参
*/
@Data
public class ImDeleteRecommendParam implements Serializable {
private static final long serialVersionUID = -2325444195601100874L;
@ApiModelProperty("推荐好友列表")
private List<String> friendClientIds;
}
package com.wecloud.im.biz.module.message.param;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* @Description 好友信息
* @Author lixiaozhong
* @Date 2022/1/12 1:59 下午
*/
@Data
public class ImFriendApplyDto extends ImFriendBaseDto {
private static final long serialVersionUID = 1L;
@ApiModelProperty("好友申请者")
private String claimerClientId;
@ApiModelProperty("好友拒绝原因")
private String rejectRemark;
@ApiModelProperty("好友请求说明")
private String requestRemark;
}
package com.wecloud.im.biz.module.message.param;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* @Description 申请好友入参
* @Author lixiaozhong
* @Date 2022/1/13 4:24 下午
*/
@Data
public class ImFriendApplyParam extends ImFriendBaseParam {
private static final long serialVersionUID = 1L;
@ApiModelProperty("会话id,群成员添加好友时传参")
private Long conversationId;
@ApiModelProperty("备注好友名称")
private String friendName;
@ApiModelProperty("请求备注")
private String requestRemark;
}
package com.wecloud.im.biz.module.message.param;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* @Description TODO
* @Author lixiaozhong
* @Date 2022/1/13 4:24 下午
*/
@Data
public class ImFriendApproveParam extends ImFriendBaseParam {
private static final long serialVersionUID = 1L;
@ApiModelProperty("是否同意接受好友,true同意,false拒绝")
private Boolean agree;
@ApiModelProperty("拒绝理由,如果是同意就不用填啦")
private String rejectRemark;
}
package com.wecloud.im.biz.module.message.param;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
/**
* @Description 好友信息
* @Author lixiaozhong
* @Date 2022/1/12 1:59 下午
*/
@Data
public class ImFriendBaseDto implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty("好友的client-id")
private String friendClientId;
@ApiModelProperty("好友的昵称备注")
private String friendName;
@ApiModelProperty("好友关系状态,1:待确定,2:已确认,3:已拒绝,4:已删除")
private Integer state;
}
package com.wecloud.im.biz.module.message.param;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
/**
* @Description 好友相关base入参
* @Author lixiaozhong
* @Date 2022/1/13 4:24 下午
*/
@Data
public class ImFriendBaseParam implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty("clientId")
private String clientId;
@ApiModelProperty("好友的client-id")
private String friendClientId;
}
package com.wecloud.im.biz.module.message.param;
import io.swagger.annotations.ApiModel;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import com.wecloud.can.datasource.mybatisplus.pagination.BasePageOrderParam;
/**
* @Description 好友分页
* @Author lixiaozhong
* @Date 2022/1/12 2:24 下午
*/
@Data
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = true)
@ApiModel(value = "好友分页")
public class ImFriendPageParam extends BasePageOrderParam {
private static final long serialVersionUID = 1L;
}
package com.wecloud.im.biz.module.message.param;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
/**
* @Description 好友信息
* @Author lixiaozhong
* @Date 2022/1/12 1:59 下午
*/
@Data
public class ImFriendRecommendDto implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty("好友的clientId")
private String friendClientId;
@ApiModelProperty("好友推荐来源,1:通讯录,2:二度人脉,3:附近的人,4:同类标签")
private Integer source;
@ApiModelProperty("是否删除")
private Boolean delFlag;
}
package com.wecloud.im.biz.module.message.param;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
*
* @Author luozh
* @Date 2022年05月16日 10:34
* @Version 1.0
*/
@Data
public class UnfriendParam {
/**
* 用户id
*/
@ApiModelProperty("用户id")
private String userId;
/**
* 朋友id 多个用,隔开
*/
@ApiModelProperty("朋友id 多个用,隔开")
private String friendUserIds;
}
package com.wecloud.im.biz.module.message.service;
import com.wecloud.im.biz.module.message.entity.ImApplication;
import com.wecloud.im.biz.module.message.entity.ImClient;
/**
* 请求上下文服务
* @Author luozh
* @Date 2022年04月02日 14:51
* @Version 1.0
*/
public interface ContextService {
/**
* 获取当前或指定clientId的ImClient 存在返回 不存在则抛出异常
* @Author luozh
* @Date 2022年04月02日 02:52:09
* @param request Ws请求
* @Return
*/
ImClient getImClientIfNotNullOrThrow();
/**
* 获取当前或指定appId的ImApplication 存在返回 不存在则抛出异常
* @Author luozh
* @Date 2022年04月02日 02:54:21
* @param appId 应用id
* @Return
*/
ImApplication getImApplicationIfNotNullOrThrow(Long appId);
}
package com.wecloud.im.biz.module.message.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.wecloud.can.core.enums.ApiCode;
import com.wecloud.can.core.util.ApiResult;
import com.wecloud.im.biz.core.rocketmq.component.MqSender;
import com.wecloud.im.biz.enums.EventResponseSubCmdEnum;
import com.wecloud.im.biz.module.message.entity.ImApplication;
import com.wecloud.im.biz.module.message.entity.ImClient;
import com.wecloud.im.biz.module.message.param.FriendApplyEventDto;
import com.wecloud.im.biz.module.message.param.FriendApproveEventDto;
import com.wecloud.im.server.enums.WsResponseCmdEnum;
import com.wecloud.im.server.model.WsResponse;
import com.wecloud.im.server.model.request.PushVO;
import com.wecloud.im.server.sender.ChannelSender;
import com.wecloud.pushserver.client.model.constant.MqConstant;
import com.wecloud.pushserver.client.model.dto.PushDTO;
/**
* @Description TODO
* @Author lixiaozhong
* @Date 2022/1/13 5:35 下午
*/
@Component
public class FriendEventSender {
@Autowired
private ChannelSender channelSender;
@Autowired
private ImApplicationService imApplicationService;
@Autowired
private MqSender mqSender;
private final static String FRIEND_APPLY_TITLE = "好友申请";
private final static String FRIEND_APPLY_TITLE_SUB = "您有好友申请待验证";
private final static String FRIEND_APPROVE_TITLE = "好友验证结果";
private final static String FRIEND_APPROVE_TITLE_AGREE = "您的好友同意了您的好友申请";
private final static String FRIEND_APPROVE_TITLE_REJECT = "您的好友拒绝了您的好友申请";
public void sendFriendApplyEventMsg(ImClient claimerClient, ImClient receiveClient, String requestRemark) {
FriendApplyEventDto applyDto = new FriendApplyEventDto();
applyDto.setSubCmd(EventResponseSubCmdEnum.FRIEND_APPLY.getCode());
applyDto.setRequestRemark(requestRemark);
applyDto.setClaimerClientId(claimerClient.getClientId());
applyDto.setFriendClientId(receiveClient.getClientId());
// 向接收方推送
WsResponse<FriendApplyEventDto> responseModel = new WsResponse<>();
responseModel.setCmd(WsResponseCmdEnum.NOTICE_EVENT_MSG.getCmdCode());
ApiResult<Boolean> result = ApiResult.result(ApiCode.SUCCESS);
responseModel.setCode(result.getCode());
responseModel.setMsg(result.getMessage());
responseModel.setData(applyDto);
responseModel.setReqId(null);
channelSender.sendMsg(responseModel, receiveClient.getId());
ImApplication app = imApplicationService.getCacheById(receiveClient.getFkAppid());
PushVO pushVO = new PushVO();
pushVO.setTitle(FRIEND_APPLY_TITLE);
pushVO.setSubTitle(FRIEND_APPLY_TITLE_SUB);
PushDTO pushDTO = mqSender.buildPushDto(pushVO, receiveClient, app);
if (pushDTO != null) {
mqSender.orderSend(MqConstant.Topic.IM_ORDER_MSG_TOPIC, MqConstant.Tag.IM_ORDER_MSG_TAG, pushDTO);
}
}
public void sendFriendApproveEventMsg(ImClient claimerClient, ImClient receiveClient, boolean isAgree, String rejectRemark) {
FriendApproveEventDto approveDto = new FriendApproveEventDto();
approveDto.setSubCmd(EventResponseSubCmdEnum.FRIEND_APPROVE.getCode());
approveDto.setAgree(isAgree);
approveDto.setRejectRemark(rejectRemark);
approveDto.setClaimerClientId(claimerClient.getClientId());
approveDto.setFriendClientId(receiveClient.getClientId());
// 向接收方推送
WsResponse<FriendApproveEventDto> responseModel = new WsResponse<>();
responseModel.setCmd(WsResponseCmdEnum.NOTICE_EVENT_MSG.getCmdCode());
ApiResult<Boolean> result = ApiResult.result(ApiCode.SUCCESS);
responseModel.setCode(result.getCode());
responseModel.setMsg(result.getMessage());
responseModel.setData(approveDto);
responseModel.setReqId(null);
channelSender.sendMsg(responseModel, receiveClient.getId());
ImApplication app = imApplicationService.getCacheById(receiveClient.getFkAppid());
PushVO pushVO = new PushVO();
pushVO.setTitle(FRIEND_APPROVE_TITLE);
pushVO.setSubTitle(isAgree ? FRIEND_APPROVE_TITLE_AGREE : FRIEND_APPROVE_TITLE_REJECT);
PushDTO pushDTO = mqSender.buildPushDto(pushVO, receiveClient, app);
if (pushDTO != null) {
mqSender.orderSend(MqConstant.Topic.IM_ORDER_MSG_TOPIC, MqConstant.Tag.IM_ORDER_MSG_TAG, pushDTO);
}
}
}
package com.wecloud.im.biz.module.message.service;
import com.wecloud.can.datasource.mybatisplus.pagination.Paging;
import com.wecloud.can.datasource.mybatisplus.service.BaseService;
import com.wecloud.im.biz.module.message.controller.param.ImApplicationPageParam;
import com.wecloud.im.biz.module.message.controller.param.ImApplicationQueryVo;
import com.wecloud.im.biz.module.message.entity.ImApplication;
/**
* 第三方应用表 服务类
*
* @author wei
* @since 2021-04-27
*/
public interface ImApplicationService extends BaseService<ImApplication> {
/**
* 根据id查询应用数据 redis缓存
*
* @param id
* @return
*/
ImApplication getCacheById(Long id);
/**
* 删除缓存
*
* @param id
*/
void deleteCacheById(Long id);
/**
* 删除缓存
*
* @param appKey
*/
void deleteCacheByAppKey(String appKey);
/**
* 根据appKey查询application
*
* @param appKey
* @return
*/
ImApplication getCacheAppByAppKey(String appKey);
/**
* 保存
*
* @param imApplication
* @return
* @throws Exception
*/
boolean saveImApplication(ImApplication imApplication) throws Exception;
// /**
// * 修改
// *
// * @param imApplication
// * @return
// * @throws Exception
// */
// boolean updateImApplication(ImApplication imApplication) throws Exception;
//
// /**
// * 删除
// *
// * @param id
// * @return
// * @throws Exception
// */
// boolean deleteImApplication(Long id) throws Exception;
/**
* 根据ID获取查询对象
*
* @param id
* @return
* @throws Exception
*/
ImApplicationQueryVo getImApplicationById(Long id) throws Exception;
/**
* 获取分页对象
*
* @param imApplicationPageParam
* @return
* @throws Exception
*/
Paging<ImApplicationQueryVo> getImApplicationPageList(ImApplicationPageParam imApplicationPageParam) throws Exception;
}
package com.wecloud.im.biz.module.message.service;
import com.wecloud.im.biz.module.message.entity.ImMessage;
/**
* sdk 回调服务
* @Author luozh
* @Date 2022年04月22日 09:08
* @Version 1.0
*/
public interface ImCallbackService {
/**
* 全量消息路由
* @Author luozh
* @Date 2022年04月22日 09:10:15
* @param
* @Return 路由结果
*/
Boolean fullMessageRouting(Long applicationId, ImMessage message);
/**
* 用户在线状态变化
* @Author luozh
* @Date 2022年04月22日 09:11:28
* @param
* @Return
*/
Boolean clientOnlineStatusChange(Long applicationId, Long clientId, Integer status,
Integer deviceType, Long time, String clientIp);
}
package com.wecloud.im.biz.module.message.service;
import com.wecloud.can.datasource.mybatisplus.pagination.Paging;
import com.wecloud.can.datasource.mybatisplus.service.BaseService;
import com.wecloud.im.biz.module.message.controller.param.ImClientBlacklistPageParam;
import com.wecloud.im.biz.module.message.controller.param.ImClientBlacklistQueryVo;
import com.wecloud.im.biz.module.message.controller.param.add.ImClientBlacklistUpdate;
import com.wecloud.im.biz.module.message.entity.ImClientBlacklist;
/**
* 黑名单 服务类
*
* @author wei
* @since 2021-06-17
*/
public interface ImClientBlacklistService extends BaseService<ImClientBlacklist> {
/**
* 当前客户端是否被拉黑
*
* @param currentClientId 当前客户端
* @param toClientId 对方客户端
* @return
*/
boolean isBeBlack(String currentClientId, String toClientId);
/**
* 拉入黑名单
*
* @param imClientBlacklistUpdate
* @return
* @throws Exception
*/
Boolean addImClientBlacklist(ImClientBlacklistUpdate imClientBlacklistUpdate);
/**
* 移出黑名单
*
* @param imClientBlacklistUpdate
* @return
* @throws Exception
*/
Boolean removeImClientBlacklist(ImClientBlacklistUpdate imClientBlacklistUpdate);
/**
* 获取分页对象
*
* @return
* @throws Exception
*/
Paging<ImClientBlacklistQueryVo> getImClientBlacklistPageList(ImClientBlacklistPageParam imClientBlacklistPageParam);
/**
* 获取分页对象
*
* @return
* @throws Exception
*/
Paging<ImClientBlacklistQueryVo> getImClientBlacklistPageListSdk(ImClientBlacklistPageParam imClientBlacklistPageParam);
}
package com.wecloud.im.biz.module.message.service;
import com.wecloud.can.datasource.mybatisplus.service.BaseService;
import com.wecloud.im.biz.module.message.entity.ImClientDevice;
/**
* @Author wenzhida
* @Date 2022/3/2 14:58
* @Description 客户端设备服务接口
*/
public interface ImClientDeviceService extends BaseService<ImClientDevice> {
/**
* 清除旧token
* @param appId
* @param deviceToken
* @return
*/
int removeOldToken(Long appId, String deviceToken);
/**
* 根据
* @Author luozh
* @Date 2022年04月18日 11:08:30
* @param appId
* @param fkClientId
* @param deviceType
* @Return
*/
ImClientDevice getOneByAppIdAndClientIdAndType(Long appId, Long fkClientId, Integer deviceType);
}
package com.wecloud.im.biz.module.message.service;
import com.alibaba.nacos.api.exception.NacosException;
import com.wecloud.can.core.util.ApiResult;
import com.wecloud.im.biz.module.message.controller.param.ImTokenVerify;
import com.wecloud.im.biz.module.message.controller.vo.TokenVo;
/**
* 终端表 服务类
*
* @author wei
* @since 2021-04-27
*/
public interface ImClientLoginService {
/**
* 根据客户方生成签名字符串 验证通过则下发token
*
* @param imTokenVerify
* @return
*/
ApiResult<TokenVo> verifySign(ImTokenVerify imTokenVerify) throws NacosException;
/**
* 获取client Token
* @Author luozh
* @Date 2022年04月18日 10:56:24
* @param
* @Return
*/
ApiResult<TokenVo> getToken(String clientId, Integer deviceType) throws NacosException;
}
package com.wecloud.im.biz.module.message.service;
import java.util.List;
import java.util.Map;
import com.wecloud.can.datasource.mybatisplus.pagination.Paging;
import com.wecloud.can.datasource.mybatisplus.service.BaseService;
import com.wecloud.im.biz.module.message.controller.param.ClientInfoParam;
import com.wecloud.im.biz.module.message.controller.param.ClientRelationVo;
import com.wecloud.im.biz.module.message.controller.param.GetClientInfoParam;
import com.wecloud.im.biz.module.message.controller.param.GetClientRelationParam;
import com.wecloud.im.biz.module.message.controller.param.ImClientPageParam;
import com.wecloud.im.biz.module.message.controller.param.ImClientQueryVo;
import com.wecloud.im.biz.module.message.controller.param.ImClientSimpleDto;
import com.wecloud.im.biz.module.message.controller.param.LogoutParam;
import com.wecloud.im.biz.module.message.controller.param.RegisterClientParam;
import com.wecloud.im.biz.module.message.controller.param.add.ClientDeviceUpdateParam;
import com.wecloud.im.biz.module.message.controller.param.add.ImClientHeadPortraitAdd;
import com.wecloud.im.biz.module.message.controller.param.add.ImClientHeadPortraitAndNicknameUpdate;
import com.wecloud.im.biz.module.message.controller.param.add.ImClientNicknameAdd;
import com.wecloud.im.biz.module.message.controller.param.add.ImClientNicknameUpdate;
import com.wecloud.im.biz.module.message.controller.vo.ClientInfoVo;
import com.wecloud.im.biz.module.message.controller.vo.GetInfoListVo;
import com.wecloud.im.biz.module.message.controller.vo.MyInfoVo;
import com.wecloud.im.biz.module.message.entity.ImClient;
/**
* 终端表 服务类
*
* @author wei
* @since 2021-04-27
*/
public interface ImClientService extends BaseService<ImClient> {
/**
* 查询我的信息
* @return
*/
MyInfoVo getMyInfo();
/**
* 更新头像
* @param imClientHeadPortraitAdd
* @return
*/
boolean updateHeadPortrait(ImClientHeadPortraitAdd imClientHeadPortraitAdd);
/**
* 修改昵称
* @param imClientNicknameUpdate
* @return
*/
boolean updateNickname(ImClientNicknameUpdate imClientNicknameUpdate);
/**
*
* @Author luozh
* @Date 2022年04月18日 07:21:27
* @param imClientHeadPortraitAndNicknameUpdate
* @Return
*/
boolean updateHeadAndNickname(ImClientHeadPortraitAndNicknameUpdate imClientHeadPortraitAndNicknameUpdate);
/**
* 根据ids获取Client的头像昵称
*
* @param getClientInfoParam
* @return
* @throws Exception
*/
List<GetInfoListVo> getInfoList(GetClientInfoParam getClientInfoParam) throws Exception;
/**
* 获取群里成员信息
* @param param
* @return
*/
ClientInfoVo getClientInfo(ClientInfoParam param);
boolean updateNickname(ImClientNicknameAdd imClientNicknameAdd) throws Exception;
/**
* 保存
*
* @param imClient
* @return
* @throws Exception
*/
boolean saveImClient(ImClient imClient) throws Exception;
/**
* 添加或修改推送设备信息
*
* @param imClientDevice
* @return
*/
boolean updateDeviceInfo(ClientDeviceUpdateParam imClientDevice);
/**
* 登出操作
* @param param
* @return
*/
boolean logout(LogoutParam param);
/**
* 修改
*
* @param imClient
* @return
* @throws Exception
*/
boolean updateImClient( ImClient imClient) throws Exception;
/**
* 删除
*
* @param id
* @return
* @throws Exception
*/
boolean deleteImClient(Long id);
/**
* 获取分页对象
*
* @param imClientPageParam
* @return
* @throws Exception
*/
Paging<ImClientQueryVo> getImClientPageList(ImClientPageParam imClientPageParam) throws Exception;
/**
* 获取当前请求的client对象
*
* @return
*/
ImClient getCurrentClient();
ImClient getCacheImClient(Long applicationId, String clientId);
void deleteCacheImClient(Long applicationId, String clientId);
/**
* 根据ID获取client对象,有缓存
*
* @param id
* @return
* @throws Exception
*/
ImClient getCacheImClient(Long id);
/**
* 获取client的简单对象,减少开销
* @param applicationId
* @param clientIds
* @return
*/
List<ImClientSimpleDto> getSimpleClients(Long applicationId, List<String> clientIds);
List<ImClientSimpleDto> getSimpleClients(List<Long> ids);
/**
* 注册客户端
* @Author luozh
* @Date 2022年04月13日 05:20:58
* @param param
* @Return
*/
Long registerClient(RegisterClientParam param);
/**
* 获取客户端关系
* @Author luozh
* @Date 2022年05月12日 07:04:04
* @param param
* @Return
*/
ClientRelationVo getClientRelation(GetClientRelationParam param);
Map<String, String> getUserAttributes(String userId);
Boolean modifyUserAttributes(String userId, Map<String, Object> attributes);
}
package com.wecloud.im.biz.module.message.service;
import java.util.List;
import org.springframework.web.bind.annotation.RequestBody;
import com.wecloud.can.core.util.ApiResult;
import com.wecloud.can.datasource.mybatisplus.pagination.Paging;
import com.wecloud.can.datasource.mybatisplus.service.BaseService;
import com.wecloud.im.biz.module.message.controller.param.ApiImConversationMembersPageParam;
import com.wecloud.im.biz.module.message.controller.param.ApiImConversationMembersQueryVo;
import com.wecloud.im.biz.module.message.controller.param.ChatSettingParam;
import com.wecloud.im.biz.module.message.controller.param.ImConvMemeClientRemarkNameParam;
import com.wecloud.im.biz.module.message.controller.param.ImConversationMembersPageParam;
import com.wecloud.im.biz.module.message.controller.param.ImConversationMembersQueryVo;
import com.wecloud.im.biz.module.message.controller.param.ListConversationMembersParam;
import com.wecloud.im.biz.module.message.controller.param.SetAdminsParam;
import com.wecloud.im.biz.module.message.controller.param.add.ImConversationMemAttrUpdate;
import com.wecloud.im.biz.module.message.controller.vo.ConversationMemberVo;
import com.wecloud.im.biz.module.message.entity.ImApplication;
import com.wecloud.im.biz.module.message.entity.ImConversationMembers;
import com.wecloud.im.biz.module.message.param.ImFriendApplyParam;
/**
* 会话成员表 服务类
*
* @author wei
* @since 2021-05-07
*/
public interface ImConversationMembersService extends BaseService<ImConversationMembers> {
/**
* 服务端api-会话成员表分页列表
*
* @param apiImConversationMembersPageParam
* @param imApplication
* @return
*/
ApiResult<List<ApiImConversationMembersQueryVo>> getRestApiImConversationMembersList(ApiImConversationMembersPageParam apiImConversationMembersPageParam, ImApplication imApplication);
/**
* 添加或修改会话成员备注
* @param param
* @return
*/
void saveOrUpdateClientRemarkName(ImConvMemeClientRemarkNameParam param);
/**
* 会话成员表分页列表
*
* @param param
* @return
* @throws Exception
*/
List<ConversationMemberVo> getImConversationMembersList(ListConversationMembersParam param);
Boolean saveOrUpdateAttr(ImConversationMemAttrUpdate imConversationMemAttrUpdate);
/**
* 保存
*
* @param imConversationMembers
* @return
* @throws Exception
*/
boolean saveImConversationMembers(ImConversationMembers imConversationMembers) throws Exception;
/**
* 修改
*
* @param imConversationMembers
* @return
* @throws Exception
*/
boolean updateImConversationMembers(ImConversationMembers imConversationMembers) throws Exception;
/**
* 删除
*
* @param id
* @return
* @throws Exception
*/
boolean deleteImConversationMembers(Long id);
/**
* 根据会话id做删除
* @param conversationId 会话id
*/
void deleteByConversationId(Long conversationId);
/**
* 根据ID获取查询对象
*
* @param id
* @return
* @throws Exception
*/
ImConversationMembersQueryVo getImConversationMembersById(Long id) throws Exception;
/**
* 获取分页对象
*
* @param imConversationMembersPageParam
* @return
* @throws Exception
*/
Paging<ImConversationMembersQueryVo> getImConversationMembersPageList(ImConversationMembersPageParam imConversationMembersPageParam) throws Exception;
/**
* 根据用户id 获取千人群id列表
* @param clientId 用户id
* @return
*/
List<Long> findThousandGroupsByClientId(Long clientId);
/**
* 批量设置群成员
* @param param
* @param fkClientIds
*/
void setAdminsForConversation(SetAdminsParam param, List<Long> fkClientIds);
/**
* 置顶
* @Author luozh
* @Date 2022年04月25日 06:24:43
* @param
* @Return
*/
Boolean chatSetting(ChatSettingParam param);
/**
* 群成员添加好友
* @Author luozh
* @Date 2022年04月28日 11:48:42
* @param param
* @Return
*/
Boolean addUser(@RequestBody ImFriendApplyParam param);
}
package com.wecloud.im.biz.module.message.service;
import java.util.List;
import com.wecloud.im.biz.module.message.controller.param.group.MutedMembersParam;
/**
* 群服务
* @Author luozh
* @Date 2022年05月10日 15:17
* @Version 1.0
*/
public interface ImGroupService {
/**
* 创建群组
* @Author luozh
* @Date 2022年05月10日 03:22:13
* @param creatorClientId
* @param groupName
* @param memberIds
* @Return
*/
Long createGroup(String creatorClientId, String groupName, List<String> memberIds);
/**
* 解散群组
* @Author luozh
* @Date 2022年05月10日 03:22:26
* @param userId
* @param groupId
* @Return
*/
Boolean dismissGroup(String userId, String groupId);
/**
* 加入群组
* @Author luozh
* @Date 2022年05月10日 03:22:35
* @param groupId
* @param memberClientIds
* @Return
*/
Integer joinGroup(String inviterUserId, String groupId, List<String> memberClientIds);
/**
* 离开群组
* @Author luozh
* @Date 2022年05月10日 03:22:44
* @param groupId
* @param memberClientIds
* @Return
*/
Integer leaveGroup(String operatorUserId, String groupId, List<String> memberClientIds);
/**
* 获取群成员列表
* @Author luozh
* @Date 2022年05月10日 03:23:09
* @param groupId
* @Return
*/
List<String> listGroupMembers(String groupId);
/**
* 禁言群成员
* @Author luozh
* @Date 2022年05月16日 07:43:41
* @param param
* @Return
*/
Boolean mutedMembers(MutedMembersParam param);
/**
* 转移群成员
* @Author luozh
* @Date 2022年05月17日 04:20:56
* @param groupId
* @param newGroupOwnerUserId
* @Return
*/
Boolean groupOwnerTransfer(String groupId, String newGroupOwnerUserId);
/**
* 添加管理员
* @Author luozh
* @Date 2022年05月17日 06:27:04
* @param groupId
* @param adminUserIds
* @Return
*/
Boolean addGroupAdmin(String groupId, String adminUserIds);
/**
* 移除管理员
* @Author luozh
* @Date 2022年05月17日 06:27:07
* @param groupId
* @param adminUserIds
* @Return
*/
Boolean removeGroupAdmin(String groupId, String adminUserIds);
}
package com.wecloud.im.biz.module.message.service;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.wecloud.can.datasource.mybatisplus.service.BaseService;
import com.wecloud.im.biz.module.message.controller.param.ImMsgReceivedStatusUpdate;
import com.wecloud.im.biz.module.message.controller.param.MsgReadStatusUpdateParam;
import com.wecloud.im.biz.module.message.controller.param.UpdateMsgReadStatusByConversationParam;
import com.wecloud.im.biz.module.message.entity.ImInbox;
/**
* 消息收件箱表 服务类
*
* @author wei
* @since 2021-05-06
*/
public interface ImInboxService extends BaseService<ImInbox> {
// /**
// * 保存
// *
// * @param imInbox
// * @return
// * @throws Exception
// */
// boolean saveImInbox(ImInbox imInbox) throws Exception;
//
// /**
// * 修改
// *
// * @param imInbox
// * @return
// * @throws Exception
// */
// boolean updateImInbox(ImInbox imInbox) throws Exception;
//
// /**
// * 删除
// *
// * @param id
// * @return
// * @throws Exception
// */
// boolean deleteImInbox(Long id) throws Exception;
//
// /**
// * 根据ID获取查询对象
// *
// * @param id
// * @return
// * @throws Exception
// */
// ImInboxQueryVo getImInboxById(Long id) throws Exception;
//
// /**
// * 获取分页对象
// *
// * @param imInboxPageParam
// * @return
// * @throws Exception
// */
// Paging<ImInboxQueryVo> getImInboxPageList(ImInboxPageParam imInboxPageParam) throws Exception;
/**
* 消息修改为已接收状态
*
* @param imMsgReceivedUpdate
* @return
*/
Boolean updateImMsgReceived(ImMsgReceivedStatusUpdate imMsgReceivedUpdate);
/**
* 统计未读消息数量
*
* @param clientId
* @return
*/
Integer countMyNotReadCount(Long clientId);
/**
* 消息修改为已读状态
*
* @return
*/
Boolean updateImMsgRead(MsgReadStatusUpdateParam msgReadStatusUpdateParam) throws JsonProcessingException;
/**
* 整个会话消息修改为已读状态
* @param param
* @return
*/
Boolean updateMsgReadStatusByConversation(UpdateMsgReadStatusByConversationParam param);
}
package com.wecloud.im.biz.module.message.service;
import com.wecloud.can.datasource.mybatisplus.service.BaseService;
import com.wecloud.im.biz.module.message.controller.param.ImIosApnsQueryVo;
import com.wecloud.im.biz.module.message.entity.ImIosApns;
/**
* apns配置表 服务类
*
* @author wei
* @since 2021-09-18
*/
public interface ImIosApnsService extends BaseService<ImIosApns> {
/**
* 保存
*
* @param imIosApns
* @return
* @throws Exception
*/
boolean saveImIosApns(ImIosApns imIosApns) throws Exception;
/**
* 修改
*
* @param imIosApns
* @return
* @throws Exception
*/
boolean updateImIosApns(ImIosApns imIosApns) throws Exception;
/**
* 删除
*
* @param id
* @return
* @throws Exception
*/
boolean deleteImIosApns(Long id) throws Exception;
/**
* 根据ID获取查询对象
*
* @param id
* @return
* @throws Exception
*/
ImIosApnsQueryVo getImIosApnsById(Long id) throws Exception;
ImIosApns getImIosApnsByAppId(Long appId);
/**
* 获取分页对象
*
* @param imIosApnsPageParam
* @return
* @throws Exception
*/
// Paging<ImIosApnsQueryVo> getImIosApnsPageList(ImIosApnsPageParam imIosApnsPageParam) throws Exception;
}
package com.wecloud.im.biz.module.message.service;
import java.util.List;
import org.springframework.transaction.annotation.Transactional;
import com.wecloud.can.core.util.ApiResult;
import com.wecloud.can.datasource.mybatisplus.pagination.Paging;
import com.wecloud.can.datasource.mybatisplus.service.BaseService;
import com.wecloud.im.biz.module.message.controller.param.ChatContentVo;
import com.wecloud.im.biz.module.message.controller.param.GetReadersParam;
import com.wecloud.im.biz.module.message.controller.param.GroupChatMessageParam;
import com.wecloud.im.biz.module.message.controller.param.GroupChatStatusMessageParam;
import com.wecloud.im.biz.module.message.controller.param.ImClientSimpleDto;
import com.wecloud.im.biz.module.message.controller.param.ImHistoryMessagePageParam;
import com.wecloud.im.biz.module.message.controller.param.MsgDeleteParam;
import com.wecloud.im.biz.module.message.controller.param.PrivateChatMessageParam;
import com.wecloud.im.biz.module.message.controller.param.PrivateChatStatusMessageParam;
import com.wecloud.im.biz.module.message.controller.param.SingleUserNotificationParam;
import com.wecloud.im.biz.module.message.controller.param.add.ImMsgRecall;
import com.wecloud.im.biz.module.message.controller.param.add.ImMsgSendToOnlineClient;
import com.wecloud.im.biz.module.message.controller.param.add.ImMsgUpdate;
import com.wecloud.im.biz.module.message.controller.vo.ImMessageOfflineListVo;
import com.wecloud.im.biz.module.message.controller.vo.OfflineMsgDto;
import com.wecloud.im.biz.module.message.controller.vo.ReaderList;
import com.wecloud.im.biz.module.message.entity.ImApplication;
import com.wecloud.im.biz.module.message.entity.ImClient;
import com.wecloud.im.biz.module.message.entity.ImMessage;
import com.wecloud.im.server.model.request.ReceiveDataVO;
import com.wecloud.im.server.model.request.ReceiveVO;
/**
* 消息存储表 服务类
*
* @author wei
* @since 2021-04-29
*/
public interface ImMessageService extends BaseService<ImMessage> {
/**
* 下发透传消息
*
* @param imMsgSendToOnlineClient
* @return
*/
ApiResult<Boolean> restApiImMessageSend(ImMsgSendToOnlineClient imMsgSendToOnlineClient, ImApplication imApplication);
ImMessage saveImMessage(ImApplication imApplication, ImClient imClientSender, long messageId, ReceiveVO receiveVO, ReceiveDataVO sysParam);
@Transactional(rollbackFor = Exception.class)
ImMessage saveImMessage(ImClientSimpleDto client, long messageId, ChatContentVo data);
/**
* 消息撤回
* @param imMsgRecall
* @param request
* @return
*/
Boolean withdrawMsg(ImMsgRecall imMsgRecall);
/**
* 删除消息
* @param param
* @return
*/
Boolean deleteMsg(MsgDeleteParam param);
/**
* 修改消息体
*
* @param imMsgUpdate
* @return
*/
Boolean updateMsgById(ImMsgUpdate imMsgUpdate);
/**
* 查询某个会话历史消息分页列表
*
* @param param
* @return
* @throws Exception
*/
Paging<OfflineMsgDto> getHistoryMsgConversationId(ImHistoryMessagePageParam param);
/**
* 查询某个会话历史消息分页列表
*
* @param param
* @return
* @throws Exception
*/
Paging<OfflineMsgDto> getHistoryMsgConversationIdNew(ImHistoryMessagePageParam param);
/**
* 查询用户所有离线消息
*
* @return
* @throws Exception
*/
List<ImMessageOfflineListVo> getOfflineList() throws Exception;
/**
* 根据客户端id与会话id 查询离线消息
*
* @param clientId
* @param conversationId
* @return
*/
List<OfflineMsgDto> getOfflineListByClientAndConversation(Long clientId, Long conversationId);
/**
* 查询会话的最后一条消息
*
* @param conversationId
* @return
*/
OfflineMsgDto getLastMsgByConversationId(Long conversationId, Long currentFkClientId);
/**
* 查询会话接收的最后一条消息
*
* @param clientId
* @param conversationId
* @return
*/
OfflineMsgDto getReceivedLastMsgByConversationId(Long clientId, Long conversationId);
/**
* 保存
*
* @param imMessage
* @return
* @throws Exception
*/
boolean saveImMessage(ImMessage imMessage) throws Exception;
/**
* 获取读取人员
* @param param
* @return
*/
ReaderList getReaders(GetReadersParam param);
/**
* 发送群聊消息
* @param param
* @return
*/
Boolean groupMessagePublish(GroupChatMessageParam param);
/**
* 发送群聊状态消息
* @Author luozh
* @Date 2022年05月05日 02:32:58
* @param param
* @Return
*/
Boolean groupStatusMessagePublish(GroupChatStatusMessageParam param);
/**
* 发送单聊消息
* @Author luozh
* @Date 2022年05月05日 02:33:26
* @param param
* @Return
*/
Boolean privateMessagePublish(PrivateChatMessageParam param);
/**
* 发送单聊状态消息
* @Author luozh
* @Date 2022年05月05日 02:33:56
* @param param
* @Return
*/
Boolean privateStatusMessagePublish(PrivateChatStatusMessageParam param);
/**
* 单个用户通知-普通消息
* @Author luozh
* @Date 2022年05月25日 10:42:31
* @param param
* @Return
*/
Boolean singleUserNotification(SingleUserNotificationParam param);
}
package com.wecloud.im.biz.module.message.service;
import com.wecloud.can.datasource.mybatisplus.service.BaseService;
import com.wecloud.im.biz.module.message.entity.ImMultiRtcRoomMember;
/**
* @Author wenzhida
* @Date 2022/3/16 9:08
* @Description 多人音视频房间成员服务接口
*/
public interface ImMultiRtcRoomMemberService extends BaseService<ImMultiRtcRoomMember> {
/**
* 改变会议成员状态
* @param fkClientId
* @param roomId
* @param state
*/
void changeRoomMemberState(Long fkClientId, String roomId, Integer state);
}
package com.wecloud.im.biz.module.message.service;
import com.wecloud.can.datasource.mybatisplus.service.BaseService;
import com.wecloud.im.biz.module.message.entity.ImMultiRtcRoom;
/**
* @Author wenzhida
* @Date 2022/3/16 9:08
* @Description 多人音视频房间服务接口
*/
public interface ImMultiRtcRoomService extends BaseService<ImMultiRtcRoom> {
/**
* 获取多人音视频房间
* @param fkAppid
* @param roomId
* @return
*/
ImMultiRtcRoom getCachedMultiRtcRoom(Long fkAppid, String roomId);
/**
* 清房间缓存
* @param fkAppid
* @param roomId
*/
void deleteMultiRtcRoomCache(Long fkAppid, String roomId);
/**
* 更新多人音视频房间状态
* @param roomId
* @param state
*/
void updateMultiRtcRoomState(String roomId, Integer state);
}
package com.wecloud.im.biz.module.message.service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wecloud.can.datasource.mybatisplus.service.BaseService;
import com.wecloud.im.biz.enums.SingleRtcOperateTypeEnum;
import com.wecloud.im.biz.module.message.controller.param.rtc.CreateRtcChannelParam;
import com.wecloud.im.biz.module.message.controller.param.rtc.SingleRtcRecordParam;
import com.wecloud.im.biz.module.message.entity.ImClient;
import com.wecloud.im.biz.module.message.entity.ImRtcRecord;
/**
* @Author wenzhida
* @Date 2022/3/16 9:08
* @Description 单人音视频房记录服务接口
*/
public interface ImRtcRecordService extends BaseService<ImRtcRecord> {
/**
* 创建rtc通话记录
* @param param
* @param channelId
*/
void createRtcRecord(CreateRtcChannelParam param, Long channelId, ImClient currentClient);
/**
* 更新音视频记录
* @param channelId
* @param type 1-同意进入频道 2-拒接进入频道 3-主动挂断(离开频道) 4-异常原因断开
* @see SingleRtcOperateTypeEnum
*/
void updateRtcRecord(Long channelId, Integer type);
/**
* 获取通话记录
*/
Page<ImRtcRecord> getPageImRtcRecords(SingleRtcRecordParam singleRtcRecordParam);
}
package com.wecloud.im.biz.module.message.service.impl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import com.wecloud.can.core.exception.BusinessException;
import com.wecloud.im.biz.module.message.entity.ImApplication;
import com.wecloud.im.biz.module.message.entity.ImClient;
import com.wecloud.im.biz.module.message.service.ContextService;
import com.wecloud.im.biz.module.message.service.ImApplicationService;
import com.wecloud.im.biz.module.message.service.ImClientService;
/**
* 请求上下文服务 impl
* @Author luozh
* @Date 2022年04月02日 14:56
* @Version 1.0
*/
@Service
public class ContextServiceImpl implements ContextService {
@Autowired
@Lazy
private ImClientService imClientService;
@Autowired
private ImApplicationService imApplicationService;
@Override
public ImClient getImClientIfNotNullOrThrow() {
ImClient currentClient = imClientService.getCurrentClient();
if (currentClient == null) {
throw new BusinessException("当前用户登录信息失效");
}
return currentClient;
}
@Override
public ImApplication getImApplicationIfNotNullOrThrow(Long appId) {
ImApplication imApplication = imApplicationService.getCacheById(appId);
if (imApplication == null) {
throw new BusinessException("查无应用信息");
}
return imApplication;
}
}
package com.wecloud.im.biz.module.message.service.impl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wecloud.can.datasource.mybatisplus.pagination.PageInfo;
import com.wecloud.can.datasource.mybatisplus.pagination.Paging;
import com.wecloud.can.datasource.mybatisplus.service.impl.BaseServiceImpl;
import com.wecloud.can.security.signature.Application;
import com.wecloud.can.security.signature.ApplicationService;
import com.wecloud.im.biz.module.message.controller.param.ImApplicationPageParam;
import com.wecloud.im.biz.module.message.controller.param.ImApplicationQueryVo;
import com.wecloud.im.biz.module.message.entity.ImApplication;
import com.wecloud.im.biz.module.message.mapper.ImApplicationMapper;
import com.wecloud.im.biz.module.message.service.ImApplicationService;
/**
* 第三方应用表 服务实现类
*
* @author wei
* @since 2021-04-27
*/
@Slf4j
@Service
@CacheConfig(cacheNames = "appl")
public class ImApplicationServiceImpl extends BaseServiceImpl<ImApplicationMapper, ImApplication> implements ImApplicationService, ApplicationService {
@Autowired
private ImApplicationMapper imApplicationMapper;
@Override
// @Cacheable(key = "'id_'+#p0")
public ImApplication getCacheById(Long id) {
return super.getById(id);
}
@Override
@CacheEvict(key = "'id_'+#p0")
public void deleteCacheById(Long id) {
}
@Override
@CacheEvict(key = "'appKey_'+#p0")
public void deleteCacheByAppKey(String appKey) {
}
@Override
@Cacheable(key = "'appKey_'+#p0")
public ImApplication getCacheAppByAppKey(String appKey) {
ImApplication imApplication = this.getOne(
new QueryWrapper<ImApplication>().lambda()
.eq(ImApplication::getAppKey, appKey)
);
return imApplication;
}
@Transactional(rollbackFor = Exception.class)
@Override
public boolean saveImApplication(ImApplication imApplication) throws Exception {
return super.save(imApplication);
}
// @Transactional(rollbackFor = Exception.class)
// @Override
// public boolean updateImApplication(ImApplication imApplication) throws Exception {
// return super.updateById(imApplication);
// }
//
// @Transactional(rollbackFor = Exception.class)
// @Override
// public boolean deleteImApplication(Long id) throws Exception {
// return super.removeById(id);
// }
@Override
public ImApplicationQueryVo getImApplicationById(Long id) throws Exception {
return imApplicationMapper.getImApplicationById(id);
}
@Override
public Paging<ImApplicationQueryVo> getImApplicationPageList(ImApplicationPageParam imApplicationPageParam) throws Exception {
Page<ImApplicationQueryVo> page = new PageInfo<>(imApplicationPageParam, OrderItem.desc(getLambdaColumn(ImApplication::getCreateTime)));
IPage<ImApplicationQueryVo> iPage = imApplicationMapper.getImApplicationPageList(page, imApplicationPageParam);
return new Paging<ImApplicationQueryVo>(iPage);
}
@Override
public Application getApplication(String appKey) {
return getCacheAppByAppKey(appKey);
}
}
package com.wecloud.im.biz.module.message.service.impl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.wecloud.can.datasource.mybatisplus.service.impl.BaseServiceImpl;
import com.wecloud.im.biz.module.message.entity.ImClientDevice;
import com.wecloud.im.biz.module.message.mapper.ImClientDeviceMapper;
import com.wecloud.im.biz.module.message.service.ImClientDeviceService;
/**
* @Author wenzhida
* @Date 2022/3/2 15:00
* @Description 客户端设备服务接口实现
*/
@Slf4j
@Service
public class ImClientDeviceServiceImpl extends BaseServiceImpl<ImClientDeviceMapper, ImClientDevice> implements ImClientDeviceService {
@Autowired
private ImClientDeviceMapper imClientDeviceMapper;
@Override
public int removeOldToken(Long appId, String deviceToken) {
return imClientDeviceMapper.removeOldToken(appId, deviceToken);
}
@Override
public ImClientDevice getOneByAppIdAndClientIdAndType(Long appId, Long fkClientId, Integer deviceType) {
return getOne(Wrappers.<ImClientDevice>lambdaQuery()
.eq(ImClientDevice::getFkAppid, appId)
.eq(ImClientDevice::getFkClientId, fkClientId)
.eq(ImClientDevice::getDeviceType, deviceType));
}
}
package com.wecloud.im.biz.module.message.service.impl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.wecloud.can.datasource.mybatisplus.service.impl.BaseServiceImpl;
import com.wecloud.im.biz.module.message.controller.param.ImIosApnsQueryVo;
import com.wecloud.im.biz.module.message.entity.ImIosApns;
import com.wecloud.im.biz.module.message.mapper.ImIosApnsMapper;
import com.wecloud.im.biz.module.message.service.ImIosApnsService;
/**
* apns配置表 服务实现类
*
* @author wei
* @since 2021-09-18
*/
@Slf4j
@Service
@CacheConfig(cacheNames = "apns")
public class ImIosApnsServiceImpl extends BaseServiceImpl<ImIosApnsMapper, ImIosApns> implements ImIosApnsService {
@Autowired
private ImIosApnsMapper imIosApnsMapper;
@Transactional(rollbackFor = Exception.class)
@Override
public boolean saveImIosApns(ImIosApns imIosApns) throws Exception {
return super.save(imIosApns);
}
@Transactional(rollbackFor = Exception.class)
@Override
public boolean updateImIosApns(ImIosApns imIosApns) throws Exception {
return super.updateById(imIosApns);
}
@Transactional(rollbackFor = Exception.class)
@Override
public boolean deleteImIosApns(Long id) throws Exception {
return super.removeById(id);
}
@Override
public ImIosApnsQueryVo getImIosApnsById(Long id) throws Exception {
return imIosApnsMapper.getImIosApnsById(id);
}
@Override
// @Cacheable(key = "#p0")
public ImIosApns getImIosApnsByAppId(Long appId) {
return this.getOne(new QueryWrapper<ImIosApns>().lambda().eq(
ImIosApns::getFkAppId, appId
));
}
// @Override
// public Paging<ImIosApnsQueryVo> getImIosApnsPageList(ImIosApnsPageParam imIosApnsPageParam) throws Exception {
// Page<ImIosApnsQueryVo> page;
// IPage<ImIosApnsQueryVo> iPage = imIosApnsMapper.getImIosApnsPageList(page, imIosApnsPageParam);
// return new Paging<ImIosApnsQueryVo>(iPage);
// }
}
package com.wecloud.im.biz.module.message.service.impl;
import lombok.extern.slf4j.Slf4j;
import java.util.Date;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.wecloud.can.datasource.mybatisplus.service.impl.BaseServiceImpl;
import com.wecloud.im.biz.module.message.entity.ImMultiRtcRoomMember;
import com.wecloud.im.biz.module.message.mapper.ImMultiRtcRoomMemberMapper;
import com.wecloud.im.biz.module.message.service.ImMultiRtcRoomMemberService;
/**
* @Author wenzhida
* @Date 2022/3/16 9:27
* @Description 多人音视频房间成员服务接口实现
*/
@Slf4j
@Service
public class ImMultiRtcRoomMemberServiceImpl extends BaseServiceImpl<ImMultiRtcRoomMemberMapper, ImMultiRtcRoomMember> implements ImMultiRtcRoomMemberService {
@Autowired
private ImMultiRtcRoomMemberMapper imMultiRtcRoomMemberMapper;
@Override
public void changeRoomMemberState(Long fkClientId, String roomId, Integer state) {
this.update(new UpdateWrapper<ImMultiRtcRoomMember>().lambda()
.eq(ImMultiRtcRoomMember::getRoomId, roomId)
.eq(ImMultiRtcRoomMember::getFkClientId, fkClientId)
.set(ImMultiRtcRoomMember::getHeartbeatTime, new Date())
.set(ImMultiRtcRoomMember::getState, state));
}
}
package com.wecloud.im.biz.module.message.service.impl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.wecloud.can.datasource.mybatisplus.service.impl.BaseServiceImpl;
import com.wecloud.im.biz.module.message.entity.ImMultiRtcRoom;
import com.wecloud.im.biz.module.message.mapper.ImMultiRtcRoomMapper;
import com.wecloud.im.biz.module.message.service.ImMultiRtcRoomService;
/**
* @Author wenzhida
* @Date 2022/3/16 9:27
* @Description 多人音视频房间服务接口实现
*/
@Slf4j
@Service
@CacheConfig(cacheNames = "multiRtc")
public class ImMultiRtcRoomServiceImpl extends BaseServiceImpl<ImMultiRtcRoomMapper, ImMultiRtcRoom> implements ImMultiRtcRoomService {
@Autowired
private ImMultiRtcRoomService imMultiRtcRoomService;
@Override
// @Cacheable(key = "'rtcRoomKey_' + #p0+#p1")
public ImMultiRtcRoom getCachedMultiRtcRoom(Long fkAppid, String roomId) {
ImMultiRtcRoom rtcRoom = imMultiRtcRoomService.getOne(new QueryWrapper<ImMultiRtcRoom>().lambda()
.eq(ImMultiRtcRoom::getFkAppid, fkAppid)
.eq(ImMultiRtcRoom::getRoomId, roomId));
return rtcRoom;
}
@Override
@CacheEvict(key = "'rtcRoomKey_' + #p0+#p1")
public void deleteMultiRtcRoomCache(Long fkAppid, String roomId) {
}
@Override
public void updateMultiRtcRoomState(String roomId, Integer state) {
imMultiRtcRoomService.update(new UpdateWrapper<ImMultiRtcRoom>().lambda()
.eq(ImMultiRtcRoom::getRoomId, roomId)
.set(ImMultiRtcRoom::getState, state));
}
}
package com.wecloud.im.biz.module.message.service.impl;
import lombok.extern.slf4j.Slf4j;
import java.util.Date;
import javax.annotation.Resource;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wecloud.can.core.exception.BusinessException;
import com.wecloud.can.core.util.SnowflakeUtil;
import com.wecloud.can.datasource.mybatisplus.service.impl.BaseServiceImpl;
import com.wecloud.im.biz.enums.RtcStateEnum;
import com.wecloud.im.biz.enums.SingleRtcOperateTypeEnum;
import com.wecloud.im.biz.module.message.controller.param.rtc.CreateRtcChannelParam;
import com.wecloud.im.biz.module.message.controller.param.rtc.SingleRtcRecordParam;
import com.wecloud.im.biz.module.message.entity.ImClient;
import com.wecloud.im.biz.module.message.entity.ImRtcRecord;
import com.wecloud.im.biz.module.message.mapper.ImRtcRecordMapper;
import com.wecloud.im.biz.module.message.service.ImClientService;
import com.wecloud.im.biz.module.message.service.ImRtcRecordService;
/**
* @Author Future
* @Date 2022/5/22 23:50
* @Description 单人音视频记录服务实现
*/
@Slf4j
@Service
public class ImRtcRecordServiceImpl extends BaseServiceImpl<ImRtcRecordMapper, ImRtcRecord> implements ImRtcRecordService {
@Resource
private ImClientService imClientService;
@Async
@Override
public void createRtcRecord(CreateRtcChannelParam param, Long channelId, ImClient currentClient) {
try {
ImRtcRecord rtcRecord = new ImRtcRecord();
rtcRecord.setId(SnowflakeUtil.getId());
rtcRecord.setFkAppid(currentClient.getFkAppid());
rtcRecord.setChannelId(channelId);
rtcRecord.setFromClientId(currentClient.getClientId());
rtcRecord.setToClientId(param.getToClient());
rtcRecord.setCallType(param.getCallType());
rtcRecord.setState(RtcStateEnum.CREATED.getCode());
rtcRecord.setCreateTime(new Date());
this.save(rtcRecord);
} catch (Exception e) {
log.info("创建rtc通话记录异常 param {} channelId {} 异常 ", JSON.toJSONString(param), channelId, e);
}
}
/**
* 更新音视频记录
*
* @param channelId
* @param type 1-同意进入频道 2-拒接进入频道 3-主动挂断(离开频道)
*/
@Async
@Override
public void updateRtcRecord(Long channelId, Integer type) {
try {
ImRtcRecord rtcRecord = this.getOne(new QueryWrapper<ImRtcRecord>().lambda()
.eq(ImRtcRecord::getChannelId, channelId));
if (rtcRecord == null) {
return;
}
if (SingleRtcOperateTypeEnum.JOIN.getCode().equals(type)) {
// 同意进入频道
rtcRecord.setState(RtcStateEnum.ING.getCode());
rtcRecord.setStartTime(new Date());
} else if (SingleRtcOperateTypeEnum.REJECT.getCode().equals(type)) {
// 拒接进入频道
rtcRecord.setState(RtcStateEnum.END.getCode());
} else if (SingleRtcOperateTypeEnum.LEAVE.getCode().equals(type)) {
// 主动挂断(离开频道)
rtcRecord.setState(RtcStateEnum.END.getCode());
rtcRecord.setEndTime(new Date());
} else if (SingleRtcOperateTypeEnum.ABNORMAL_DISCONNECT.getCode().equals(type)) {
// 异常原因(客户端已不在线)
rtcRecord.setState(RtcStateEnum.END.getCode());
rtcRecord.setEndTime(new Date());
}
this.updateById(rtcRecord);
} catch (Exception e) {
log.info("更新rtc通话记录异常, channelId {}, type {} 异常 ", channelId, type, e);
}
}
@Override
public Page<ImRtcRecord> getPageImRtcRecords(SingleRtcRecordParam param) {
if (param.getPageNum() == null) {
throw new BusinessException("页码不可为空");
}
if (param.getPageSize() == null) {
throw new BusinessException("每页数量不可为空");
}
ImClient imClient = imClientService.getCurrentClient();
LambdaQueryWrapper<ImRtcRecord> rtcRecordLambdaQueryWrapper = new LambdaQueryWrapper<>();
rtcRecordLambdaQueryWrapper.eq(ImRtcRecord::getFkAppid, imClient.getFkAppid());
rtcRecordLambdaQueryWrapper.eq(param.getFromClientId() != null, ImRtcRecord::getFromClientId, param.getFromClientId());
rtcRecordLambdaQueryWrapper.eq(param.getToClientId() != null, ImRtcRecord::getToClientId, param.getToClientId());
rtcRecordLambdaQueryWrapper.eq(param.getChannelId() != null, ImRtcRecord::getChannelId, param.getChannelId());
rtcRecordLambdaQueryWrapper.eq(param.getCallType() != null, ImRtcRecord::getCallType, param.getCallType());
rtcRecordLambdaQueryWrapper.lt(param.getCreateTimeEnd() != null, ImRtcRecord::getCreateTime, param.getCreateTimeEnd());
rtcRecordLambdaQueryWrapper.gt(param.getCreateTimeStart() != null, ImRtcRecord::getCreateTime, param.getCreateTimeStart());
rtcRecordLambdaQueryWrapper.orderByDesc(ImRtcRecord::getCreateTime);
Page<ImRtcRecord> pageParam = new Page<>(param.getPageNum(), param.getPageSize());
Page<ImRtcRecord> page = this.page(pageParam, rtcRecordLambdaQueryWrapper);
return page;
}
}
package com.wecloud.im.biz.module.multimeet.entity.dto;
import lombok.Data;
import java.io.Serializable;
import com.wecloud.im.biz.enums.MultiRtcMemberStateEnum;
/**
* @Author wenzhida
* @Date 2022/3/16 11:21
* @Description 房间成员dto
*/
@Data
public class RoomMemberDto implements Serializable {
private static final long serialVersionUID = 7634567721658236530L;
/**
* client主键id
*/
private Long fkClientId;
/**
* 客户端id
*/
private String clientId;
/**
* 多人音视频房间成员状态枚举
* @see MultiRtcMemberStateEnum
*/
private Integer state;
}
package com.wecloud.im.biz.module.multimeet.entity.response;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
/**
* @Author wenzhida
* @Date 2022/3/7 22:21
* @Description 同意进入多人音视频
*/
@EqualsAndHashCode(callSuper = true)
@Data
public class MultiMeetAgreeResponse extends MultiMeetDataBase implements Serializable {
private static final long serialVersionUID = 1623214002231302888L;
/**
* 会话id
*/
private Long conversationId;
/**
* 房间id
*/
private String roomId;
}
package com.wecloud.im.biz.module.multimeet.entity.response;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
/**
* @Author wenzhida
* @Date 2022/3/16 13:52
* @Description 占线响应
*/
@EqualsAndHashCode(callSuper = true)
@Data
public class MultiMeetBusyResponse extends MultiMeetDataBase implements Serializable {
private static final long serialVersionUID = -5692994062040333774L;
/**
* 会话id
*/
private Long conversationId;
/**
* 房间id
*/
private String roomId;
/**
* 占线人clientId
*/
private String busyClientId;
}
package com.wecloud.im.biz.module.multimeet.entity.response;
import lombok.Data;
import java.io.Serializable;
/**
* @Author wenzhida
* @Date 2022/3/7 22:01
* @Description 多人音视频会议长连接响应基类
*/
@Data
public class MultiMeetDataBase implements Serializable {
private static final long serialVersionUID = -4151469100462562164L;
/**
* 子指令
*/
private Integer subCmd;
private String clientId;
private Long timestamp;
}
package com.wecloud.im.biz.module.multimeet.entity.response;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
import java.util.List;
import com.wecloud.im.biz.module.multimeet.entity.dto.RoomMemberDto;
/**
* @Author wenzhida
* @Date 2022/3/7 22:02
* @Description 邀请加入多人音视频会议
*/
@EqualsAndHashCode(callSuper = true)
@Data
public class MultiMeetInviteResponse extends MultiMeetDataBase implements Serializable {
/**
* 会话id
*/
private Long conversationId;
/**
* 房间id
*/
private String roomId;
/**
* 成员列表dto
*/
private List<RoomMemberDto> memberDtoList;
}
package com.wecloud.im.biz.module.multimeet.entity.response;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
/**
* @Author wenzhida
* @Date 2022/3/7 22:21
* @Description 主动离开多人音视频
*/
@EqualsAndHashCode(callSuper = true)
@Data
public class MultiMeetLeaveResponse extends MultiMeetDataBase implements Serializable {
private static final long serialVersionUID = 734428267643207411L;
/**
* 会话id
*/
private Long conversationId;
/**
* 房间id
*/
private String roomId;
}
package com.wecloud.im.biz.module.multimeet.entity.response;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
/**
* @Author wenzhida
* @Date 2022/3/7 22:21
* @Description 拒绝进入多人音视频
*/
@EqualsAndHashCode(callSuper = true)
@Data
public class MultiMeetRejectResponse extends MultiMeetDataBase implements Serializable {
/**
* 会话id
*/
private Long conversationId;
/**
* 房间id
*/
private String roomId;
}
package com.wecloud.im.biz.module.multimeet.service;
import com.wecloud.im.biz.module.message.controller.param.AgreeToMultiMeetParam;
import com.wecloud.im.biz.module.message.controller.param.HeartbeatMultiMeetParam;
import com.wecloud.im.biz.module.message.controller.param.InviteToMultiMeetParam;
import com.wecloud.im.biz.module.message.controller.param.LeaveFromMultiMeetParam;
import com.wecloud.im.biz.module.message.controller.param.NotAnsweredMultiMeetParam;
import com.wecloud.im.biz.module.message.controller.param.RejectToMultiMeetParam;
/**
* @Author wenzhida
* @Date 2022/3/7 18:26
* @Description 多人音视频服务接口
*/
public interface MultiMeetService {
/**
* 发起多人音视频邀请
* @param param
* @return
*/
void invite(InviteToMultiMeetParam param);
/**
* 拒接加入会议
* @param param
*/
void reject(RejectToMultiMeetParam param);
/**
* 同意进入会议
* @param param
*/
void agree(AgreeToMultiMeetParam param);
/**
* 同意进入会议
* @param param
*/
void leave(LeaveFromMultiMeetParam param);
/**
* 拒绝接听
* @param param
*/
void notAnswered(NotAnsweredMultiMeetParam param);
/**
* 心跳接收
* @param param
*/
void heartbeat(HeartbeatMultiMeetParam param);
/**
* 是否正在被呼叫
*/
void isBeCalling();
/**
* 呼叫超时逻辑处理
*/
void callingTimeout();
/**
* 异常断线逻辑处理
*/
void disconnect();
}
package com.wecloud.im.biz.module.multimeet.service;
import com.wecloud.im.biz.module.multimeet.entity.response.MultiMeetAgreeResponse;
import com.wecloud.im.biz.module.multimeet.entity.response.MultiMeetBusyResponse;
import com.wecloud.im.biz.module.multimeet.entity.response.MultiMeetInviteResponse;
import com.wecloud.im.biz.module.multimeet.entity.response.MultiMeetLeaveResponse;
import com.wecloud.im.biz.module.multimeet.entity.response.MultiMeetRejectResponse;
/**
* @Author wenzhida
* @Date 2022/3/7 21:47
* @Description 多人音视频 webSocket下发指令数据
*/
public interface WsMultiMeetWrite {
/**
* 发送邀请
* @param multiMeetInviteResponse
* @param toFkClientId
*/
void invite(MultiMeetInviteResponse multiMeetInviteResponse, Long toFkClientId);
/**
* 拒接邀请
* @param multiMeetRejectResponse
* @param toFkClientId
*/
void reject(MultiMeetRejectResponse multiMeetRejectResponse, Long toFkClientId);
/**
* 同意进入会议
* @param multiMeetAgreeResponse
* @param toFkClientId
*/
void agree(MultiMeetAgreeResponse multiMeetAgreeResponse, Long toFkClientId);
/**
* 主动离开会议
* @param multiMeetLeaveResponse
* @param toFkClientId
*/
void leave(MultiMeetLeaveResponse multiMeetLeaveResponse, Long toFkClientId);
/**
* 被邀请方占线
* @param multiMeetBusyResponse
* @param toFkClientId
*/
void busy(MultiMeetBusyResponse multiMeetBusyResponse, Long toFkClientId);
}
package com.wecloud.im.biz.module.multimeet.service.impl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.wecloud.can.core.enums.ApiCode;
import com.wecloud.can.core.util.ApiResult;
import com.wecloud.im.biz.module.multimeet.entity.response.MultiMeetAgreeResponse;
import com.wecloud.im.biz.module.multimeet.entity.response.MultiMeetBusyResponse;
import com.wecloud.im.biz.module.multimeet.entity.response.MultiMeetInviteResponse;
import com.wecloud.im.biz.module.multimeet.entity.response.MultiMeetLeaveResponse;
import com.wecloud.im.biz.module.multimeet.entity.response.MultiMeetRejectResponse;
import com.wecloud.im.biz.module.multimeet.service.WsMultiMeetWrite;
import com.wecloud.im.server.enums.WsMultiMeetResponseSubCmdEnum;
import com.wecloud.im.server.enums.WsResponseCmdEnum;
import com.wecloud.im.server.model.WsResponse;
import com.wecloud.im.server.sender.ChannelSender;
/**
* @Author wenzhida
* @Date 2022/3/7 22:26
* @Description 多人音视频长连接下发
*/
@Service
public class WsMultiMeetWriteImpl implements WsMultiMeetWrite {
@Autowired
private ChannelSender channelSender;
@Override
public void invite(MultiMeetInviteResponse multiMeetInviteResponse, Long toFkClientId) {
multiMeetInviteResponse.setSubCmd(WsMultiMeetResponseSubCmdEnum.INVITE.getCmdCode());
// 向接收方推送
WsResponse<MultiMeetInviteResponse> responseModel = new WsResponse<>();
responseModel.setCmd(WsResponseCmdEnum.MULTI_MEET_MSG.getCmdCode());
ApiResult<Boolean> result = ApiResult.result(ApiCode.SUCCESS);
responseModel.setCode(result.getCode());
responseModel.setMsg(result.getMessage());
responseModel.setData(multiMeetInviteResponse);
responseModel.setReqId(null);
channelSender.sendMsg(responseModel, toFkClientId);
}
@Override
public void reject(MultiMeetRejectResponse multiMeetRejectResponse, Long toFkClientId) {
multiMeetRejectResponse.setSubCmd(WsMultiMeetResponseSubCmdEnum.REJECT.getCmdCode());
// 向接收方推送
WsResponse<MultiMeetRejectResponse> responseModel = new WsResponse<>();
responseModel.setCmd(WsResponseCmdEnum.MULTI_MEET_MSG.getCmdCode());
ApiResult<Boolean> result = ApiResult.result(ApiCode.SUCCESS);
responseModel.setCode(result.getCode());
responseModel.setMsg(result.getMessage());
responseModel.setData(multiMeetRejectResponse);
responseModel.setReqId(null);
channelSender.sendMsg(responseModel, toFkClientId);
}
@Override
public void agree(MultiMeetAgreeResponse multiMeetAgreeResponse, Long toFkClientId) {
multiMeetAgreeResponse.setSubCmd(WsMultiMeetResponseSubCmdEnum.AGREE.getCmdCode());
// 向接收方推送
WsResponse<MultiMeetAgreeResponse> responseModel = new WsResponse<>();
responseModel.setCmd(WsResponseCmdEnum.MULTI_MEET_MSG.getCmdCode());
ApiResult<Boolean> result = ApiResult.result(ApiCode.SUCCESS);
responseModel.setCode(result.getCode());
responseModel.setMsg(result.getMessage());
responseModel.setData(multiMeetAgreeResponse);
responseModel.setReqId(null);
channelSender.sendMsg(responseModel, toFkClientId);
}
@Override
public void leave(MultiMeetLeaveResponse multiMeetLeaveResponse, Long toFkClientId) {
multiMeetLeaveResponse.setSubCmd(WsMultiMeetResponseSubCmdEnum.LEAVE.getCmdCode());
// 向接收方推送
WsResponse<MultiMeetLeaveResponse> responseModel = new WsResponse<>();
responseModel.setCmd(WsResponseCmdEnum.MULTI_MEET_MSG.getCmdCode());
ApiResult<Boolean> result = ApiResult.result(ApiCode.SUCCESS);
responseModel.setCode(result.getCode());
responseModel.setMsg(result.getMessage());
responseModel.setData(multiMeetLeaveResponse);
responseModel.setReqId(null);
channelSender.sendMsg(responseModel, toFkClientId);
}
@Override
public void busy(MultiMeetBusyResponse multiMeetBusyResponse, Long toFkClientId) {
multiMeetBusyResponse.setSubCmd(WsMultiMeetResponseSubCmdEnum.BUSY.getCmdCode());
// 向接收方推送
WsResponse<MultiMeetBusyResponse> responseModel = new WsResponse<>();
responseModel.setCmd(WsResponseCmdEnum.MULTI_MEET_MSG.getCmdCode());
ApiResult<Boolean> result = ApiResult.result(ApiCode.SUCCESS);
responseModel.setCode(result.getCode());
responseModel.setMsg(result.getMessage());
responseModel.setData(multiMeetBusyResponse);
responseModel.setReqId(null);
channelSender.sendMsg(responseModel, toFkClientId);
}
}
package com.wecloud.im.biz.module.rtc.entity;
import java.io.Serializable;
public class RtcSubCmd implements Serializable {
/**
* subCmd子类型指令码
*/
public static final String SUB_CMD = "subCmd";
}
package com.wecloud.im.biz.module.rtc.entity.redis;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
/**
* rtc 频道信息
*/
@Data
public class RtcChannelInfo implements Serializable {
@ApiModelProperty("当前房主")
private Long owner;
@ApiModelProperty("创建时间")
private Long createTimestamp;
}
package com.wecloud.im.biz.module.rtc.entity.redis;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
/**
* rtc 频道内的用户
*/
@Data
public class RtcJoinUser implements Serializable {
@ApiModelProperty("客户端")
private String clientId;
@ApiModelProperty("加入时间")
private Long createTimestamp;
private String sdpData;
private String sdpType;
}
package com.wecloud.im.biz.module.rtc.entity.redis;
import lombok.Data;
import java.io.Serializable;
/**
* rtc 频道内所有用户
*/
@Data
public class RtcJoinUsers implements Serializable {
}
package com.wecloud.im.biz.module.rtc.entity.redis;
import java.io.Serializable;
public class RtcRedisKey implements Serializable {
/**
* 维护频道信息 (kv)
*/
public static final String RTC_CHANNEL_INFO = "r:ci:%s";
/**
* 维护用户当前在线的频道ID ( kv)
* user_join_channel = ujc
* rcu:clientA = 10001
* rcu:clientB = 10001
* rcu:clientC = 10002
* rcu:clientD = 10003
*/
public static final String USER_JOIN_CHANNEL = "r:ujc:%s";
/**
* 维护频道中存在的用户 (set 集合):
* rtc_channel_users = rcu
* rcu:10001 = clientA , clientB
* rcu:10002 = clientC
* rcu:10003 = clientD
*/
public static final String RTC_CHANNEL_USERS = "r:cu:%s";
}
package com.wecloud.im.biz.module.rtc.entity.response;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
import com.wecloud.im.biz.enums.CallTypeEnum;
@EqualsAndHashCode(callSuper = true)
@Data
public class RtcCallResponse extends RtcDataBase implements Serializable {
/**
* 类型: "video" 或 "voice"
* @see CallTypeEnum
*/
private Integer callType;
/**
* 会话id
*/
private Long conversationId;
}
package com.wecloud.im.biz.module.rtc.entity.response;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
@EqualsAndHashCode(callSuper = true)
@Data
public class RtcCandidateForwardResponse extends RtcDataBase implements Serializable {
/**
* 转发的候选者数据
*/
private String candidateData;
}
package com.wecloud.im.biz.module.rtc.entity.response;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
@EqualsAndHashCode(callSuper = true)
@Data
public class RtcClientJoinResponse extends RtcDataBase implements Serializable {
}
package com.wecloud.im.biz.module.rtc.entity.response;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
@EqualsAndHashCode(callSuper = true)
@Data
public class RtcClientLeaveResponse extends RtcDataBase implements Serializable {
}
package com.wecloud.im.biz.module.rtc.entity.response;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
@EqualsAndHashCode(callSuper = true)
@Data
public class RtcClientRejectResponse extends RtcDataBase implements Serializable {
}
package com.wecloud.im.biz.module.rtc.entity.response;
import lombok.Data;
import java.io.Serializable;
@Data
public class RtcDataBase implements Serializable {
/**
* 子指令
*/
private Integer subCmd;
private Long channelId;
private String clientId;
private Long timestamp;
}
package com.wecloud.im.biz.module.rtc.entity.response;
import lombok.Data;
import java.io.Serializable;
/**
* webRtc websocket下发数据封装类
*
* @param <T>
*/
@Data
public class RtcResponseBase<T> implements Serializable {
/**
* 子指令
*/
private Integer subCmd;
/**
* 根据不同子指令 不同的实体
*/
private T subData;
/**
* 自定义拓展字段
*/
private String attrs;
}
package com.wecloud.im.biz.module.rtc.entity.response;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
@EqualsAndHashCode(callSuper = true)
@Data
public class RtcSdpForwardResponse extends RtcDataBase implements Serializable {
/**
* channelId : 1234263457652
* clientId : 7657567
* sdpData : xxxxxxxxxxxxxxxx
* sdpType : Offer/Answer
*/
private String sdpData;
private String sdpType;
}
package com.wecloud.im.biz.module.rtc.service;
import java.util.List;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.wecloud.im.biz.module.rtc.entity.redis.RtcChannelInfo;
/**
* 管理rtc频道
*/
public interface MangerRtcCacheService {
/**
* 移除频道信息
*
* @param rtcChannelId
* @return
*/
boolean delChannelInfo(Long rtcChannelId);
/**
* 频道中客户端是否为空
*
* @param rtcChannelId
* @return
*/
boolean channelIsEmpty(Long rtcChannelId);
/**
* 获取频道信息
*
* @param rtcChannelId
* @return
* @throws JsonProcessingException
*/
RtcChannelInfo getRtcChannelInfo(Long rtcChannelId) throws JsonProcessingException;
/**
* 创建一个频道
*
* @param clientId
* @param rtcChannelId 雪花算法生成频道id
*/
void create(Long clientId, Long toClientId, Long rtcChannelId);
/**
* 加入频道
*/
void join(Long clientId, Long rtcChannelId);
/**
* 退出频道
*/
void leave(Long clientId, Long rtcChannelId);
/**
* 根据频道ID获取频道内所有client
*/
List<String> getClientListByRtcChannelId(Long rtcChannelId);
/**
* 根据客户端ID获取该客户端加入的频道ID
*/
Long getRtcChannelIdListByClientId(Long clientId);
/**
* 获取客户端忙线/空闲状态
*
* @param clientId
* @return true:忙线,false空闲
*/
boolean getBusyStatus(Long clientId);
}
package com.wecloud.im.biz.module.rtc.service;
import com.wecloud.im.biz.module.message.controller.param.rtc.CandidateForwardParam;
import com.wecloud.im.biz.module.message.controller.param.rtc.CreateRtcChannelParam;
import com.wecloud.im.biz.module.message.controller.param.rtc.CreateRtcChannelResult;
import com.wecloud.im.biz.module.message.controller.param.rtc.JoinRtcChannelParam;
import com.wecloud.im.biz.module.message.controller.param.rtc.LeaveRtcChannelParam;
import com.wecloud.im.biz.module.message.controller.param.rtc.RejectRtcChannelParam;
import com.wecloud.im.biz.module.message.controller.param.rtc.SdpForwardParam;
/**
* 管理rtc频道
*/
public interface RtcService {
/**
* 创建一个频道,并向接收方发送系统推送
*/
CreateRtcChannelResult createAndCall(CreateRtcChannelParam createRtcChannelParam);
/**
* 加入频道
*/
Boolean join(JoinRtcChannelParam joinRtcChannelParam);
/**
* 拒接加入频道
*/
Boolean reject(RejectRtcChannelParam rejectRtcChannelParam);
/**
* 退出频道
*/
Boolean leave(LeaveRtcChannelParam leaveRtcChannelParam);
/**
* SDP数据转发
*
* @param sdpForwardParam
* @return
*/
Boolean sdpForward(SdpForwardParam sdpForwardParam);
/**
* candidate候选者数据转发
*
* @param candidateForwardParam
* @return
*/
Boolean candidateForward(CandidateForwardParam candidateForwardParam);
/**
* 异常断线判断处理
*/
void abnormalDisconnect();
}
package com.wecloud.im.biz.module.rtc.service;
import com.wecloud.im.biz.module.rtc.entity.response.RtcCallResponse;
import com.wecloud.im.biz.module.rtc.entity.response.RtcCandidateForwardResponse;
import com.wecloud.im.biz.module.rtc.entity.response.RtcClientJoinResponse;
import com.wecloud.im.biz.module.rtc.entity.response.RtcClientLeaveResponse;
import com.wecloud.im.biz.module.rtc.entity.response.RtcClientRejectResponse;
import com.wecloud.im.biz.module.rtc.entity.response.RtcSdpForwardResponse;
/**
* WebRtc webSocket下发指令数据
*/
public interface WsRtcWrite {
/**
* 接收到RTC邀请
*/
void rtcCall(RtcCallResponse rtcCallResponse, Long toClientId);
/**
* 用户状态更新事件(用户加入频道)
*/
void clientJoin(RtcClientJoinResponse rtcClientJoinResponse, Long toClientId);
/**
* 用户状态更新事件(用户退出频道)
*/
void clientLeave(RtcClientLeaveResponse rtcClientLeaveResponse, Long toClientId);
/**
* 用户状态更新事件(用户拒接邀请;不同意进入频道)
*/
void clientReject(RtcClientRejectResponse rtcClientRejectResponse, Long toClientId);
/**
* SDP数据转发
*/
void sdpForward(RtcSdpForwardResponse rtcSdpForwardResponse, Long toClientId);
/**
* candidate候选者数据转发
*/
void candidateForward(RtcCandidateForwardResponse rtcCandidateForwardResponse, Long toClientId);
}
package com.wecloud.im.biz.module.rtc.service.impl;
import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.wecloud.can.core.util.JsonUtils;
import com.wecloud.im.biz.module.rtc.entity.redis.RtcChannelInfo;
import com.wecloud.im.biz.module.rtc.entity.redis.RtcRedisKey;
import com.wecloud.im.biz.module.rtc.service.MangerRtcCacheService;
import com.wecloud.im.server.utils.RedisUtils;
@Service
public class MangerRtcCacheServiceImpl implements MangerRtcCacheService {
@Autowired
private RedisUtils redisUtils;
@Override
public boolean delChannelInfo(Long rtcChannelId) {
String channelKey = String.format(RtcRedisKey.RTC_CHANNEL_INFO, rtcChannelId);
redisUtils.delKey(channelKey);
return true;
}
@Override
public boolean channelIsEmpty(Long rtcChannelId) {
List<String> clientListByRtcChannelId = getClientListByRtcChannelId(rtcChannelId);
// // 移除自己
// clientListByRtcChannelId.remove(appKey + clientId);
return clientListByRtcChannelId.isEmpty();
}
@Override
public RtcChannelInfo getRtcChannelInfo(Long rtcChannelId) throws JsonProcessingException {
// 频道信息
String channelKey = String.format(RtcRedisKey.RTC_CHANNEL_INFO, rtcChannelId);
String value = redisUtils.getKey(channelKey);
if (StringUtils.isBlank(value)) {
return null;
}
return JsonUtils.decodeJson(value, RtcChannelInfo.class);
}
@Override
public void create(Long clientId, Long toClientId, Long rtcChannelId) {
// --- 频道信息
RtcChannelInfo rtcChannelInfo = new RtcChannelInfo();
//当前房主
rtcChannelInfo.setOwner(clientId);
//创建时间
rtcChannelInfo.setCreateTimestamp(System.currentTimeMillis());
String rtcChannelInfoJson = JsonUtils.encodeJson(rtcChannelInfo);
// --- 保存频道信息
String channelKey = String.format(RtcRedisKey.RTC_CHANNEL_INFO, rtcChannelId);
redisUtils.addKey(channelKey, rtcChannelInfoJson, Duration.ofDays(10));
// 用户当前在线的频道ID
String userJoinChannelKey = String.format(RtcRedisKey.USER_JOIN_CHANNEL, clientId);
redisUtils.addKey(userJoinChannelKey, rtcChannelId.toString(), Duration.ofDays(10));
// 频道中存在的用户
String rtcChannelUsers = String.format(RtcRedisKey.RTC_CHANNEL_USERS, rtcChannelId);
redisUtils.addForSet(rtcChannelUsers, clientId + "", 10, TimeUnit.DAYS);
redisUtils.addForSet(rtcChannelUsers, toClientId + "", 10, TimeUnit.DAYS);
}
@Override
public void join(Long clientId, Long rtcChannelId) {
//用户当前在线的频道ID
String userJoinChannelKey = String.format(RtcRedisKey.USER_JOIN_CHANNEL, clientId);
redisUtils.addKey(userJoinChannelKey, rtcChannelId.toString(), Duration.ofDays(10));
}
@Override
public void leave(Long clientId, Long rtcChannelId) {
//用户当前在线的频道ID
String userJoinChannelKey = String.format(RtcRedisKey.USER_JOIN_CHANNEL, clientId);
redisUtils.delKey(userJoinChannelKey);
//频道中存在的用户
String rtcChannelUsersKey = String.format(RtcRedisKey.RTC_CHANNEL_USERS, rtcChannelId);
redisUtils.removeForSet(rtcChannelUsersKey, clientId + "");
}
@Override
public List<String> getClientListByRtcChannelId(Long rtcChannelId) {
//频道中存在的用户
String key = String.format(RtcRedisKey.RTC_CHANNEL_USERS, rtcChannelId);
Set<String> forSetMembers = redisUtils.getForSetMembers(key);
return new ArrayList<>(forSetMembers);
}
@Override
public Long getRtcChannelIdListByClientId(Long clientId) {
//用户当前在线的频道ID
String userJoinChannelKey = String.format(RtcRedisKey.USER_JOIN_CHANNEL, clientId);
String key = redisUtils.getKey(userJoinChannelKey);
if (StringUtils.isBlank(key)) {
return null;
}
return Long.valueOf(key);
}
@Override
public boolean getBusyStatus(Long clientId) {
//用户当前在线的频道ID
String userJoinChannelKey = String.format(RtcRedisKey.USER_JOIN_CHANNEL, clientId);
String key = redisUtils.getKey(userJoinChannelKey);
return key != null && !key.isEmpty();
}
}
package com.wecloud.im.biz.module.rtc.service.impl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.wecloud.can.core.enums.ApiCode;
import com.wecloud.can.core.util.ApiResult;
import com.wecloud.im.biz.module.rtc.entity.response.RtcCallResponse;
import com.wecloud.im.biz.module.rtc.entity.response.RtcCandidateForwardResponse;
import com.wecloud.im.biz.module.rtc.entity.response.RtcClientJoinResponse;
import com.wecloud.im.biz.module.rtc.entity.response.RtcClientLeaveResponse;
import com.wecloud.im.biz.module.rtc.entity.response.RtcClientRejectResponse;
import com.wecloud.im.biz.module.rtc.entity.response.RtcSdpForwardResponse;
import com.wecloud.im.biz.module.rtc.service.WsRtcWrite;
import com.wecloud.im.server.enums.WsResponseCmdEnum;
import com.wecloud.im.server.enums.WsRtcResponseSubCmdEnum;
import com.wecloud.im.server.model.WsResponse;
import com.wecloud.im.server.sender.ChannelSender;
@Service
public class WsRtcWriteImpl implements WsRtcWrite {
@Autowired
private ChannelSender channelSender;
@Override
public void rtcCall(RtcCallResponse rtcCallResponse, Long toClientId) {
rtcCallResponse.setSubCmd(WsRtcResponseSubCmdEnum.RTC_CALL.getCmdCode());
// 向接收方推送
WsResponse<RtcCallResponse> responseModel = new WsResponse<>();
responseModel.setCmd(WsResponseCmdEnum.SINGLE_RTC_MSG.getCmdCode());
ApiResult<Boolean> result = ApiResult.result(ApiCode.SUCCESS);
responseModel.setCode(result.getCode());
responseModel.setMsg(result.getMessage());
responseModel.setData(rtcCallResponse);
responseModel.setReqId(null);
channelSender.sendMsg(responseModel, toClientId);
}
@Override
public void clientJoin(RtcClientJoinResponse rtcClientJoinResponse, Long toClientId) {
rtcClientJoinResponse.setSubCmd(WsRtcResponseSubCmdEnum.CLIENT_JOIN.getCmdCode());
// 向接收方推送
WsResponse<RtcClientJoinResponse> responseModel = new WsResponse<>();
responseModel.setCmd(WsResponseCmdEnum.SINGLE_RTC_MSG.getCmdCode());
ApiResult<Boolean> result = ApiResult.result(ApiCode.SUCCESS);
responseModel.setCode(result.getCode());
responseModel.setMsg(result.getMessage());
responseModel.setData(rtcClientJoinResponse);
responseModel.setReqId(null);
channelSender.sendMsg(responseModel, toClientId);
}
@Override
public void clientLeave(RtcClientLeaveResponse rtcClientLeaveResponse, Long toClientId) {
rtcClientLeaveResponse.setSubCmd(WsRtcResponseSubCmdEnum.CLIENT_LEAVE.getCmdCode());
// 向接收方推送
WsResponse<RtcClientLeaveResponse> responseModel = new WsResponse<>();
responseModel.setCmd(WsResponseCmdEnum.SINGLE_RTC_MSG.getCmdCode());
ApiResult<Boolean> result = ApiResult.result(ApiCode.SUCCESS);
responseModel.setCode(result.getCode());
responseModel.setMsg(result.getMessage());
responseModel.setData(rtcClientLeaveResponse);
responseModel.setReqId(null);
channelSender.sendMsg(responseModel, toClientId);
}
@Override
public void clientReject(RtcClientRejectResponse rtcClientRejectResponse, Long toClientId) {
rtcClientRejectResponse.setSubCmd(WsRtcResponseSubCmdEnum.CLIENT_REJECT.getCmdCode());
// 向接收方推送
WsResponse<RtcClientRejectResponse> responseModel = new WsResponse<>();
responseModel.setCmd(WsResponseCmdEnum.SINGLE_RTC_MSG.getCmdCode());
ApiResult<Boolean> result = ApiResult.result(ApiCode.SUCCESS);
responseModel.setCode(result.getCode());
responseModel.setMsg(result.getMessage());
responseModel.setData(rtcClientRejectResponse);
responseModel.setReqId(null);
channelSender.sendMsg(responseModel, toClientId);
}
@Override
public void sdpForward(RtcSdpForwardResponse rtcSdpForwardResponse, Long toClientId) {
rtcSdpForwardResponse.setSubCmd(WsRtcResponseSubCmdEnum.SDP_FORWARD.getCmdCode());
// 向接收方推送
WsResponse<RtcSdpForwardResponse> responseModel = new WsResponse<>();
responseModel.setCmd(WsResponseCmdEnum.SINGLE_RTC_MSG.getCmdCode());
ApiResult<Boolean> result = ApiResult.result(ApiCode.SUCCESS);
responseModel.setCode(result.getCode());
responseModel.setMsg(result.getMessage());
responseModel.setData(rtcSdpForwardResponse);
responseModel.setReqId(null);
channelSender.sendMsg(responseModel, toClientId);
}
@Override
public void candidateForward(RtcCandidateForwardResponse rtcCandidateForwardResponse, Long toClientId) {
rtcCandidateForwardResponse.setSubCmd(WsRtcResponseSubCmdEnum.CANDIDATE_FORWARD.getCmdCode());
// 向接收方推送
WsResponse<RtcCandidateForwardResponse> responseModel = new WsResponse<>();
responseModel.setCmd(WsResponseCmdEnum.SINGLE_RTC_MSG.getCmdCode());
ApiResult<Boolean> result = ApiResult.result(ApiCode.SUCCESS);
responseModel.setCode(result.getCode());
responseModel.setMsg(result.getMessage());
responseModel.setData(rtcCandidateForwardResponse);
responseModel.setReqId(null);
channelSender.sendMsg(responseModel, toClientId);
}
}
package com.wecloud.im.biz.module.thousandchat.cache;
import lombok.extern.slf4j.Slf4j;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.wecloud.can.core.util.GetIpUtils;
import com.wecloud.im.biz.module.message.service.ImConversationMembersService;
import com.wecloud.im.server.cache.UserStateListener;
import com.wecloud.im.server.utils.RedisUtils;
/**
* 万人群的缓存(本地缓存待实现)
* @author lixiaozhong
* @date 2022年01月4日 17:00:00
*/
@Service
@Slf4j
public class ThousandChatCacheManager extends UserStateListener {
/**
* redis的群键 key
*/
public static final String GROUP_KEY = "gp:";
@Autowired
private RedisUtils redisUtils;
@Autowired
private ImConversationMembersService imConversationMembersService;
@Override
public void onLineEvent(Long clientId, Integer platform, String longChannelId) {
List<Long> thousandGroupIds = imConversationMembersService.findThousandGroupsByClientId(clientId);
for(Long thousandGroupId : thousandGroupIds) {
redisUtils.hashset(GROUP_KEY + thousandGroupId, clientId + RedisUtils.SPLIT + platform, GetIpUtils.getlanIp(),
150, TimeUnit.DAYS);
}
}
@Override
public void offlineEvent(Long clientId, Integer platform, String longChannelId) {
List<Long> thousandGroupIds = imConversationMembersService.findThousandGroupsByClientId(clientId);
for(Long thousandGroupId : thousandGroupIds) {
redisUtils.hashdel(GROUP_KEY + thousandGroupId, clientId + RedisUtils.SPLIT + platform);
}
}
/**
* 根据群ID 获取 万人群的 在线成员的key-val
* @param conversionId
* @return 在线成员的key-val,其中key是 client的主键id:platform, val是 ip
*/
public Map<String, String> findOnlineClientsByThousandGroupId(Long conversionId) {
return redisUtils.hashgetll(GROUP_KEY + conversionId);
}
/**
* 根据群ID 获取 万人群的 在线成员的ip以及对应的成员信息,key-vaul
* @param conversionId
* @return 在线成员的key-val,其中key是 ip地址, val是 client的主键id:platform
*/
public Map<String, List<String>> findOnlineHostsByThousandGroupId(Long conversionId) {
Map<String /** client的主键ID:platform **/, String /** ip **/> onlineClientIpMap = findOnlineClientsByThousandGroupId(conversionId);
Map<String /** ip **/, List<String /** client的主键ID:platform **/>> onlineIpClientMap = new HashMap<>();
onlineClientIpMap.forEach((clientIdAndPlatforms, ip) -> {
onlineIpClientMap.putIfAbsent(ip, new ArrayList<>());
onlineIpClientMap.get(ip).add(clientIdAndPlatforms);
});
return onlineIpClientMap;
}
}
package com.wecloud.im.biz.module.thousandchat.controller;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.wecloud.can.core.base.controller.BaseController;
import com.wecloud.im.biz.module.thousandchat.service.ThousandChatService;
/**
* 万人群消息处理controller
*/
@Slf4j
@RestController
@RequestMapping("/imState")
@Api(value = "万人群消息处理API", tags = {"万人群消息处理API"})
public class ThousandChatController extends BaseController {
@Autowired
private ThousandChatService thousandChatService;
}
package com.wecloud.im.biz.module.thousandchat.entity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.util.Date;
import javax.validation.constraints.NotNull;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.wecloud.can.core.base.entity.BaseEntity;
/**
* @author lixiaozhong
* 消息最新已读寻址表
*/
@Data
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = true)
@TableName("im_msg_read_lastest")
@ApiModel(value = "ImMsgReadLastest对象")
public class ImMsgReadLastest extends BaseEntity {
private static final long serialVersionUID = 1L;
@NotNull(message = "主键id不能为空")
@ApiModelProperty("主键id")
@TableId(value = "id", type = IdType.INPUT)
private Long id;
@ApiModelProperty("创建时间")
private Date createTime;
@ApiModelProperty("修改时间")
private Date updateTime;
@ApiModelProperty("读取时间")
private Date readTime;
@ApiModelProperty("接收时间")
private Date receiveTime;
@NotNull(message = "应用appid不能为空")
@ApiModelProperty("应用appid")
private Long fkAppid;
@NotNull(message = "接收客户端id不能为空")
@ApiModelProperty("接收客户端id")
private Long fkClientId;
@NotNull(message = "会话id不能为空")
@ApiModelProperty("会话id")
private Long fkConversationId;
@ApiModelProperty("最后一条已接收消息id")
private Long fkReceiveMsgId;
@ApiModelProperty("最后一条已读消息id")
private Long fkReadMsgId;
}
package com.wecloud.im.biz.module.thousandchat.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wecloud.im.biz.module.message.controller.param.ImInboxPageParam;
import com.wecloud.im.biz.module.message.controller.param.ImInboxQueryVo;
import com.wecloud.im.biz.module.thousandchat.entity.ImMsgReadLastest;
import com.wecloud.im.biz.module.thousandchat.param.ConversationLastestReadMsg;
import com.wecloud.im.biz.module.thousandchat.param.ThousandOffineMsgDto;
/**
* @author lixiaozhong
* 主要针对万人群的消息状态处理dao类
*/
@Repository
public interface ImMsgReadLastestMapper extends BaseMapper<ImMsgReadLastest> {
/**
* 获取分页对象
*
* @param page
* @param imInboxPageParam
* @return
*/
IPage<ImInboxQueryVo> getImInboxPageList(@Param("page") Page page, @Param("param") ImInboxPageParam imInboxPageParam);
/**
* 万人群的消息已送达的插入/更新
* @param lastestRead
* @return
*/
Long upsertImMsgReceive(ImMsgReadLastest lastestRead);
/**
* 万人群消息已读的插入/更新
* @param lastestRead
* @return
*/
Long upsertImMsgRead(ImMsgReadLastest lastestRead);
/**
* 查找最新的已读记录,如果查回来是空,表示会话消息全未读
* @param clientId
* @return
*/
List<ConversationLastestReadMsg> findLastestReadMsgs(@Param("clientId") Long clientId);
/**
* 查找万人群的离线消息
* @param allConversationOfLastestReadMsgs
*/
List<ThousandOffineMsgDto> findOfflineMsgs(@Param("lastestMsgs") List<ConversationLastestReadMsg> allConversationOfLastestReadMsgs);
}
package com.wecloud.im.biz.module.thousandchat.param;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import com.wecloud.can.core.base.entity.BaseEntity;
/**
* @author lixiaozhong
* 最新一条只读消息
*/
@Data
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = true)
@ApiModel(value = "ConversationLastestReadMsg")
public class ConversationLastestReadMsg extends BaseEntity {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "最新的一条已读消息")
private Long lastestReadMsgId;
@ApiModelProperty(value = "最新的一条已接收消息")
private Long lastestReceiveMsgId;
@ApiModelProperty(value = "会话id")
private Long conversationId;
}
package com.wecloud.im.biz.module.thousandchat.param;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
import javax.validation.constraints.NotNull;
/**
* @author lixiaozhong
* 最后一条已接收消息
*/
@Data
@Accessors(chain = true)
@ApiModel(value = "LastestReceivedMsg")
public class LastestReceivedMsg implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "消息id,只需要发送最新的一条已接收消息", required = true)
@NotNull(message = "消息ID不能为空")
private Long lastestMsgId;
@ApiModelProperty(value = "是否同时修改为已读状态", required = false)
private Boolean readStatus = false;
}
package com.wecloud.im.biz.module.thousandchat.param;
import lombok.Data;
import com.wecloud.im.biz.module.message.controller.vo.OfflineMsgDto;
/**
* @Description 万人群离线消息dto类
* @Author lixiaozhong
* @Date 2022/1/11 10:00 上午
*/
@Data
public class ThousandOffineMsgDto extends OfflineMsgDto {
}
package com.wecloud.im.biz.scheduled;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import com.wecloud.im.biz.module.multimeet.service.MultiMeetService;
/**
* @Author wenzhida
* @Date 2022/3/28 16:34
* @Description 多人音视频相关定时器
*/
@Slf4j
@Component
public class MultiMeetScheduled {
@Autowired
private MultiMeetService multiMeetService;
/**
* 呼叫超时处理
* 每5秒执行一次
*/
@Scheduled(cron = "*/5 * * * * ?")
public void callingTimeout() {
log.info("呼叫超时处理开始...");
multiMeetService.callingTimeout();
}
/**
* 接听中成员异常断线处理
* 每10秒执行一次 (5秒一次心跳 - 20秒未收到心跳,认为已经异常断开连接)
*/
@Scheduled(cron = "*/10 * * * * ?")
public void disconnect() {
log.info("异常断线处理开始...");
multiMeetService.disconnect();
}
}
package com.wecloud.im.biz.scheduled;
import lombok.extern.slf4j.Slf4j;
import javax.annotation.Resource;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import com.wecloud.im.biz.module.rtc.service.RtcService;
/**
* @Author Future
* @Date 2022/6/3 11:43
* @Description 单人rtc定时器调度
*/
@Slf4j
@Component
public class SingleRtcScheduled {
@Resource
private RtcService rtcService;
/**
* 呼叫异常停止处理 查出正在通话的记录,检测是否在线,如未在线超过5次,按断线处理
*/
@Scheduled(cron = "*/13 * * * * ?")
public void abnormalDisconnect() {
log.info("单人音视频异常断线处理开始...");
rtcService.abnormalDisconnect();
}
}
spring-boot-plus:
# 是否启用ansi控制台输出有颜色的字体,dev环境建议开启,服务器环境设置为false
enable-ansi: true
# 当前环境服务IP地址
server-ip: 127.0.0.1
# 文件上传下载配置
upload-path: /opt/upload/
aop:
log:
enable: true
log-print-type: LINE
request-log-format: false
response-log-format: false
spring:
datasource:
# url: jdbc:mysql://127.0.0.1:3306/wecloud-im?serverTimezone=UTC&useUnicode=true&characterEncoding=utf8&useSSL=false&allowPublicKeyRetrieval=true
# username: root
# password: 123456
# 测试外网
# url: jdbc:mysql://124.71.83.11:3306/wecloud_im?serverTimezone=UTC&useUnicode=true&characterEncoding=utf8&useSSL=false&allowPublicKeyRetrieval=true
url: jdbc:mysql://121.37.22.224:3306/wecloud_im_feature_cluster?serverTimezone=UTC&useUnicode=true&characterEncoding=utf8&useSSL=false&allowPublicKeyRetrieval=true
username: root
password: temple123456
# Redis配置
redis:
# database: 0
# host: 127.0.0.1
# password:
# port: 6379
database: 0
host: 121.37.22.224
password: temple123456
port: 6379
dubbo:
protocol:
port: 20882
name: dubbo
registry:
address: nacos://localhost:8848?username=nacos&password=nacos
# 打印SQL语句和结果集,本地开发环境可开启,线上注释掉
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
# 服务器负载均衡配置
load-blance:
# 服务器运营商local,aws,huawei
server-type: local
# NameServer地址 用;作为地址的分隔符
rocketmq:
namesrvAddr: 121.37.22.224:9876
# 生产者的组名
producerId: im-server
sms:
huawei:
url: https://rtcsms.cn-north-1.myhuaweicloud.com:10743/sms/batchSendSms/v1
sender: 8820122113125
appKey: FKFPgk3X6VRYAMJ9r9CIJWG2709W
appSecret: gvS2S8nD01vKCA1v45qi379gu1T5
verifyCode: 666666
spring-boot-plus:
# 是否启用ansi控制台输出有颜色的字体,dev环境建议开启,服务器环境设置为false
enable-ansi: true
# 当前环境服务IP地址
server-ip: 127.0.0.1
# 文件上传下载配置
upload-path: /opt/upload/
aop:
log:
enable: true
log-print-type: LINE
request-log-format: false
response-log-format: false
spring:
datasource:
url: jdbc:mysql://116.205.173.171:3306/wecloud_im_paas?serverTimezone=UTC&useUnicode=true&characterEncoding=utf8&useSSL=false&allowPublicKeyRetrieval=true
username: web
password: SeTLHCRhmWpizxxRpQcc
#//测试外网
# 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:
database: 0
host: 116.205.173.171
password: alfbiYAUNKgAiE9tSdH1l4idXZIaNDKkgpS84dG9dy8TlACijUTwHYlLwdd6zTng
port: 6379
cloud:
nacos:
discovery:
server-addr: 116.205.173.171:8848
dubbo:
protocol:
port: 20881
name: dubbo
registry:
address: nacos://116.205.173.171:8848?username=nacos&password=nacos
provider:
cluster: channelRouterCluster
consumer:
check: false
# 打印SQL语句和结果集,本地开发环境可开启,线上注释掉
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
# 服务器负载均衡配置
load-blance:
# 服务器运营商local,aws,huawei
server-type: local
# NameServer地址 用;作为地址的分隔符
rocketmq:
namesrvAddr: 116.205.173.171:9876
# 生产者的组名
producerId: im-server
sms:
huawei:
url: https://rtcsms.cn-north-1.myhuaweicloud.com:10743/sms/batchSendSms/v1
sender: 8820122113125
appKey: FKFPgk3X6VRYAMJ9r9CIJWG2709W
appSecret: gvS2S8nD01vKCA1v45qi379gu1T5
verifyCode: 369258
spring-boot-plus:
# 是否启用ansi控制台输出有颜色的字体,dev环境建议开启,服务器环境设置为false
enable-ansi: true
# 当前环境服务IP地址
server-ip: 127.0.0.1
# 文件上传下载配置
upload-path: /opt/upload/
aop:
log:
enable: true
log-print-type: LINE
request-log-format: false
response-log-format: false
spring:
datasource:
url: jdbc:mysql://127.0.0.1:3306/wecloud_im_feature_cluster?serverTimezone=UTC&useUnicode=true&characterEncoding=utf8&useSSL=false&allowPublicKeyRetrieval=true
username: root
password: temple123456
#//测试外网
# 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:
database: 0
host: 127.0.0.1
password: temple123456
port: 6379
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
dubbo:
protocol:
# host: 121.37.22.224
port: 20881
name: dubbo
registry:
address: nacos://127.0.0.1:8848?username=nacos&password=nacos
provider:
cluster: channelRouterCluster
consumer:
check: false
# 打印SQL语句和结果集,本地开发环境可开启,线上注释掉
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
# 服务器负载均衡配置
load-blance:
# 服务器运营商local,aws,huawei
server-type: local
# NameServer地址 用;作为地址的分隔符
rocketmq:
namesrvAddr: 127.0.0.1:9876
# 生产者的组名
producerId: im-server
sms:
huawei:
url: https://rtcsms.cn-north-1.myhuaweicloud.com:10743/sms/batchSendSms/v1
sender: 8820122113125
appKey: FKFPgk3X6VRYAMJ9r9CIJWG2709W
appSecret: gvS2S8nD01vKCA1v45qi379gu1T5
verifyCode: 666666
spring-boot-plus:
# 是否启用ansi控制台输出有颜色的字体,local环境建议开启,服务器环境设置为false
enable-ansi: false
# 当前环境服务IP地址
server-ip:
# AOP配置
aop:
log:
enable: true
log-print-type: LINE
request-log-format: false
response-log-format: false
spring:
datasource:
url:
username:
password:
# Redis配置
redis:
database:
host:
password:
port:
spring-boot-plus:
# 是否启用ansi控制台输出有颜色的字体,dev环境建议开启,服务器环境设置为false
enable-ansi: true
# 当前环境服务IP地址
server-ip: 139.159.136.86
# 文件上传下载配置
upload-path: /opt/upload/
aop:
log:
enable: true
log-print-type: LINE
request-log-format: false
response-log-format: false
spring:
datasource:
url: jdbc:mysql://mysql:3306/wecloud_im?serverTimezone=UTC&useUnicode=true&characterEncoding=utf8&useSSL=false&allowPublicKeyRetrieval=true
username: root
password: temple123456
#//测试外网
# 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:
database: 0
host: redis
# password: f242cy9DtzfKU5qT
port: 6379
cloud:
inetutils:
preferredNetworks:
- 192.168
nacos:
discovery:
server-addr: nacos:8848
dubbo:
protocol:
port: 20881
name: dubbo
registry:
address: nacos://nacos:8848?username=nacos&password=nacos
provider:
cluster: channelRouterCluster
consumer:
check: false
# 打印SQL语句和结果集,本地开发环境可开启,线上注释掉
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
# 服务器负载均衡配置
load-blance:
# 服务器运营商local,aws,huawei
server-type: local
# NameServer地址 用;作为地址的分隔符
rocketmq:
namesrvAddr: 124.71.83.11:9876
# 生产者的组名
producerId: im-server
sms:
huawei:
url: https://rtcsms.cn-north-1.myhuaweicloud.com:10743/sms/batchSendSms/v1
sender: 8820122113125
appKey: FKFPgk3X6VRYAMJ9r9CIJWG2709W
appSecret: gvS2S8nD01vKCA1v45qi379gu1T5
verifyCode: 666666
${AnsiColor.BLUE}
_ _ _ _
(_) | | | | | |
___ _ __ _ __ _ _ __ __ _ ______| |__ ___ ___ | |_ ______ _ __ | |_ _ ___
/ __| '_ \| '__| | '_ \ / _` |______| '_ \ / _ \ / _ \| __|______| '_ \| | | | / __|
\__ \ |_) | | | | | | | (_| | | |_) | (_) | (_) | |_ | |_) | | |_| \__ \
|___/ .__/|_| |_|_| |_|\__, | |_.__/ \___/ \___/ \__| | .__/|_|\__,_|___/
| | __/ | | |
|_| |___/ |_|
${AnsiColor.YELLOW} :: Spring Boot :: ${AnsiColor.WHITE}(v${spring-boot.version})
${AnsiColor.YELLOW} :: spring-boot-plus :: ${AnsiColor.WHITE}(v${project.version})
https://springboot.plus
spring:
profiles:
active: @profileActive@
---
spring:
profiles: dev
cloud:
nacos:
discovery:
server-addr: localhost:8848
userName: "nacos"
password: "nacos"
config:
server-addr: localhost:8848
userName: "nacos"
password: "nacos"
file-extension: yaml
---
spring:
profiles: test
cloud:
nacos:
discovery:
server-addr: localhost:8848
userName: "nacos"
password: "nacos"
config:
server-addr: localhost:8848
userName: "nacos"
password: "nacos"
file-extension: yaml
---
spring:
profiles: prod
cloud:
nacos:
discovery:
server-addr: localhost:8848
userName: "nacos"
password: "nacos"
config:
server-addr: localhost:8848
userName: "nacos"
password: "nacos"
file-extension: yaml
---
spring:
profiles: xhdtest
cloud:
nacos:
discovery:
server-addr: nacos:8848
userName: "nacos"
password: "nacos"
config:
server-addr: nacos:8848
userName: "nacos"
password: "nacos"
file-extension: yaml
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<property name="CONTEXT_NAME" value="spring-boot-plus"/>
<property name="LOG_PATH" value="logs"/>
<property name="MAX_FILE_SIZE" value="1000MB"/>
<property name="MAX_HISTORY" value="30"/>
<contextName>${CONTEXT_NAME}</contextName>
<!-- 彩色日志 -->
<conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter"/>
<conversionRule conversionWord="wex"
converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter"/>
<conversionRule conversionWord="wEx"
converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter"/>
<!-- 控制台日志样式 -->
<property name="CONSOLE_LOG_PATTERN"
value="${CONSOLE_LOG_PATTERN:-%clr(%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr([%15.15t]){faint} [%X{requestId}] %clr(%-40.40logger{39}){cyan} [%L] %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>
<!-- 文件日志样式 -->
<property name="FILE_LOG_PATTERN"
value="${FILE_LOG_PATTERN:-%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}} ${LOG_LEVEL_PATTERN:-%5p} [%t] [%X{requestId}] %-40.40logger{39} %L : %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>
<!-- 禁用logback自身日志输出 -->
<statusListener class="ch.qos.logback.core.status.NopStatusListener"/>
<!-- 控制台 -->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
</encoder>
</appender>
<!-- 运行日志文件 -->
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder>
<pattern>${FILE_LOG_PATTERN}</pattern>
</encoder>
<file>${LOG_PATH}/spring-boot-plus.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${LOG_PATH}/spring-boot-plus-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<maxFileSize>${MAX_FILE_SIZE}</maxFileSize>
<maxHistory>${MAX_HISTORY}</maxHistory>
</rollingPolicy>
</appender>
<!-- 错误日志文件 -->
<appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder>
<pattern>${FILE_LOG_PATTERN}</pattern>
</encoder>
<file>${LOG_PATH}/spring-boot-plus-error.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${LOG_PATH}/spring-boot-plus-error-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<maxFileSize>${MAX_FILE_SIZE}</maxFileSize>
<maxHistory>${MAX_HISTORY}</maxHistory>
</rollingPolicy>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 异步写日志 -->
<appender name="ASYNC_FILE" class="ch.qos.logback.classic.AsyncAppender">
<discardingThreshold>0</discardingThreshold>
<queueSize>1024</queueSize>
<appender-ref ref="FILE"/>
</appender>
<appender name="ASYNC_ERROR_FILE" class="ch.qos.logback.classic.AsyncAppender">
<discardingThreshold>0</discardingThreshold>
<queueSize>1024</queueSize>
<appender-ref ref="ERROR_FILE"/>
</appender>
<!-- 不同环境的日志级别配置 -->
<springProfile name="dev">
<logger name="io.geekidea.springbootplus" level="DEBUG"/>
</springProfile>
<!-- 解决SpringBootAdmin错误日志问题 -->
<logger name="org.apache.catalina.connector.CoyoteAdapter" level="OFF"/>
<root level="INFO">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="ASYNC_FILE"/>
<appender-ref ref="ASYNC_ERROR_FILE"/>
</root>
</configuration>
#
# Copyright 2019-2029 geekidea(https://github.com/geekidea)
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# 扩展mime-type
# 参考:https://svn.apache.org/viewvc/httpd/httpd/trunk/docs/conf/mime.types?revision=1752884&view=co
md=text/markdown
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.wecloud.im.biz.module.message.mapper.ImApplicationMapper">
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
id
, create_time, update_time, app_key, app_secret, app_name, ios_push_channel, android_push_channel,umeng_key,umeng_secret,firebase_secret,repeat_session_status,contrast_extended_field_status
</sql>
<select id="getImApplicationById"
resultType="com.wecloud.im.biz.module.message.controller.param.ImApplicationQueryVo">
select
<include refid="Base_Column_List"/>
from im_application where id = #{id}
</select>
<select id="getImApplicationPageList"
parameterType="com.wecloud.im.biz.module.message.controller.param.ImApplicationPageParam"
resultType="com.wecloud.im.biz.module.message.controller.param.ImApplicationQueryVo">
select
<include refid="Base_Column_List"/>
from im_application
</select>
</mapper>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.wecloud.im.biz.module.message.mapper.ImClientBlacklistMapper">
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
id
, create_time, update_time, fk_appid, client_id_prevent, client_id_be_prevent
</sql>
<select id="getImClientBlacklistById"
resultType="com.wecloud.im.biz.module.message.controller.param.ImClientBlacklistQueryVo">
select
<include refid="Base_Column_List"/>
from im_client_blacklist where id = #{id}
</select>
<select id="getImClientBlacklistPageList"
resultType="com.wecloud.im.biz.module.message.controller.param.ImClientBlacklistQueryVo">
SELECT im_client.client_id AS clientIdBePrevent
FROM im_client_blacklist
INNER JOIN im_client ON im_client.client_id = im_client_blacklist.client_id_be_prevent
WHERE im_client_blacklist.client_id_prevent = #{clientId}
ORDER BY im_client_blacklist.create_time DESC
</select>
</mapper>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.wecloud.im.biz.module.message.mapper.ImClientDeviceMapper">
<update id="removeOldToken">
UPDATE im_client_device
SET device_token = NULL
WHERE device_token = #{deviceToken}
AND fk_appid = #{appId}
</update>
</mapper>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.wecloud.im.biz.module.message.mapper.ImClientMapper">
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
id
, create_time, update_time, fk_appid, attributes,client_id,head_portrait,nickname
</sql>
<select id="getImClientPageList"
parameterType="com.wecloud.im.biz.module.message.controller.param.ImClientPageParam"
resultType="com.wecloud.im.biz.module.message.controller.param.ImClientQueryVo">
select
<include refid="Base_Column_List"/>
from im_client
</select>
<select id="getInfoList" resultType="com.wecloud.im.biz.module.message.controller.vo.GetInfoListVo">
SELECT
im_client.id AS id,
im_client.client_id AS clientId,
im_client.head_portrait AS headPortrait,
im_client.nickname,
(SELECT im_conversation_members.client_remark_name FROM im_conversation_members AS im_conversation_members WHERE
im_conversation_members.fk_conversation_id = #{conversationId} AND im_conversation_members.fk_client_id =
clientId ) AS clientRemarkName ,
(SELECT im_conversation_members.attributes FROM im_conversation_members AS im_conversation_members WHERE
im_conversation_members.fk_conversation_id = #{conversationId} AND im_conversation_members.fk_client_id =
clientId ) AS memberAttributes ,
im_client.attributes AS clientAttributes
FROM
im_client AS im_client
WHERE
im_client.fk_appid = #{appId}
AND im_client.client_id IN
<foreach collection="clientIds" item="clientId" index="index" open="(" close=")" separator=",">
#{clientId}
</foreach>
</select>
<select id="getSimpleClients" resultType="com.wecloud.im.biz.module.message.controller.param.ImClientSimpleDto">
select id, fk_appid, client_id from im_client where fk_appid = #{appId} and client_id in
<foreach collection="clientIds" item="clientId" index="index" open="(" close=")" separator=",">
#{clientId}
</foreach>
</select>
<select id="getSimpleClientsByIds"
resultType="com.wecloud.im.biz.module.message.controller.param.ImClientSimpleDto">
select id, fk_appid, client_id from im_client where id in
<foreach collection="ids" item="id" index="index" open="(" close=")" separator=",">
#{id}
</foreach>
</select>
</mapper>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.wecloud.im.biz.module.message.mapper.ImConversationMembersMapper">
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
id
, create_time, update_time, fk_appid, fk_conversation_id, fk_client_id
</sql>
<select id="getImConversationMembersById"
resultType="com.wecloud.im.biz.module.message.controller.param.ImConversationMembersQueryVo">
select
<include refid="Base_Column_List"/>
from im_conversation_members where id = #{id}
</select>
<select id="getImConversationMembersPageList"
parameterType="com.wecloud.im.biz.module.message.controller.param.ImConversationMembersPageParam"
resultType="com.wecloud.im.biz.module.message.controller.param.ImConversationMembersQueryVo">
select
<include refid="Base_Column_List"/>
from im_conversation_members
</select>
<select id="getRestApiImConversationMembersList"
resultType="com.wecloud.im.biz.module.message.controller.param.ApiImConversationMembersQueryVo">
SELECT im_client.client_id AS clientId
FROM im_conversation_members AS imConversationMembers
INNER JOIN im_client AS im_client ON im_client.id = imConversationMembers.fk_client_id
WHERE fk_conversation_id = #{conversationId}
</select>
<select id="getImConversationMembersList"
resultType="com.wecloud.im.biz.module.message.controller.vo.ConversationMemberVo">
SELECT im_client.client_id as clientId,
im_conversation_members.id as id,
im_conversation_members.client_remark_name as clientRemarkName,
im_client.head_portrait as headPortrait,
im_client.nickname,
im_conversation_members.attributes AS memberAttributes,
im_conversation_members.role AS role,
im_conversation_members.muted AS muted,
im_client.attributes AS clientAttributes
FROM im_conversation_members AS im_conversation_members
INNER JOIN im_client AS im_client ON im_client.id = im_conversation_members.fk_client_id
WHERE im_conversation_members.fk_conversation_id = #{param.conversationId}
<if test="param.roles != null and param.roles.size() > 0">
and im_conversation_members.role in
<foreach collection="param.roles" item="role" index="index" open="(" close=")" separator=",">
#{role}
</foreach>
</if>
<if test="param.clientIds != null and param.clientIds.size() > 0">
and im_client.client_id in
<foreach collection="param.clientIds" item="clientId" index="index" open="(" close=")" separator=",">
#{clientId}
</foreach>
</if>
<if test="param.muted != null">
AND im_conversation_members.muted = #{param.muted}
</if>
</select>
<select id="findThousandGroupsByClientId" resultType="java.lang.Long">
select a.id from im_conversation a
inner join im_conversation_members b on a.id = b.fk_conversation_id
where b.fk_client_id = #{clientId} and a.chat_type = 3
</select>
<update id="setAdminsForConversation">
update im_conversation_members set role = #{role}, update_time=NOW()
where fk_conversation_id = #{conversationId} and fk_client_id in
<foreach collection="fkClientIds" item="fkClientId" index="index" open="(" close=")" separator=",">
#{fkClientId}
</foreach>
</update>
<delete id="deleteByConversationId">
DELETE FROM im_conversation_members WHERE fk_conversation_id = #{conversationId}
</delete>
</mapper>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.wecloud.im.biz.module.message.mapper.ImFriendMapper">
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
id, client_id, client_id_friend, friend_name,reject_remark,request_remark,state,create_time, update_time
</sql>
<select id="getFriendInfo" resultType="com.wecloud.im.biz.module.message.param.ImFriendApplyDto">
select friend.id,
client.client_id as friendClientId,
friend.friend_name,
claimer.client_id as claimerClientId,
friend.reject_remark,
friend.request_remark,
friend.state,
friend.create_time
from im_friend friend
inner join im_client client on friend.client_id_friend = client.client_id
inner join im_client claimer on friend.client_id_claimer = claimer.client_id
where friend.client_id = #{clientId}
and client_id_friend = #{friendClientId}
and friend.state = 2
</select>
<select id="getImFriendPageList" resultType="com.wecloud.im.biz.module.message.param.ImFriendBaseDto">
select friend.id,
client.client_id as friendClientId,
friend.friend_name,
friend.state
from im_friend friend
inner join im_client client on friend.client_id_friend = client.client_id
where friend.client_id = #{clientId}
and friend.state = 2
</select>
<select id="getApplyFriendPageList" resultType="com.wecloud.im.biz.module.message.param.ImFriendApplyDto">
select friend.id,
client.client_id as friendClientId,
friend.friend_name as friendName,
claimer.client_id as claimerClientId,
friend.reject_remark,
friend.request_remark,
friend.state,
friend.update_time,
friend.create_time
from im_friend friend
inner join im_client client on friend.client_id_friend = client.client_id
inner join im_client claimer on friend.client_id_claimer = claimer.client_id
where friend.client_id = #{clientId}
and friend.client_id_claimer != #{clientId}
order by friend.update_time desc
</select>
<select id="filterNegativeFriends" resultType="java.lang.String">
select
client_id_friend
from im_friend
where client_id = #{clientId} and client_id_friend in
<foreach collection="friendClientIds" item="friendClientId" open="(" close=")" separator=",">
#{friendClientId}
</foreach>
</select>
<update id="batchDeleteFriend">
update im_friend set state = 4 where client_id = #{clientId} and client_id_friend in (
select client_id from im_client where (fk_appid, client_id) in
<foreach collection="friendClientIds" item="friendClientId" open="(" close=")" separator=",">
(#{fkAppId}, #{friendClientId})
</foreach>
)
</update>
</mapper>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.wecloud.im.biz.module.message.mapper.ImFriendRecommendMapper">
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
id, client_id, client_id_friend, source, del_flag, create_time, update_time
</sql>
<select id="getImFriendRecommendPageList" resultType="com.wecloud.im.biz.module.message.param.ImFriendRecommendDto">
select recommend.id,
client.client_id as friendClientId,
recommend.source,
recommend.del_flag
from im_friend_recommend recommend
inner join im_client client on recommend.client_id_friend = client.client_id
where client_id = #{clientId}
</select>
<update id="batchDeleteRecommend">
update im_friend_recommend set del_flag = 1 where client_id = #{clientId} and client_id_friend in (
select client_id from im_client where (fk_appid, client_id) in
<foreach collection="friendClientIds" item="friendClientId" open="(" close=")" separator=",">
(#{fkAppId}, #{friendClientId})
</foreach>
)
</update>
<insert id="batchCreateRecommend" >
insert into im_friend_recommend(id, client_id, client_id_friend, source, del_flag, create_time)
values
<foreach collection="list" item="item" separator=",">
(#{item.id},#{item.clientId},#{item.clientIdFriend},#{item.source},#{item.delFlag}, NOW())
</foreach>
ON DUPLICATE KEY UPDATE update_time = now()
</insert>
</mapper>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.wecloud.im.biz.module.message.mapper.ImInboxMapper">
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
id
, create_time, update_time, read_time, receiver_time, fk_appid, receiver, fk_msg_id, read_msg_status, receiver_msg_status, fk_conversation_id
</sql>
<update id="updateImMsgReceivedByIds">
UPDATE im_inbox
SET `im_inbox`.`update_time` = NOW(),
`im_inbox`.`receiver_msg_status` = 1,
`im_inbox`.`receiver_time` = NOW()
WHERE
im_inbox.receiver = #{clientId}
AND im_inbox.fk_msg_id IN
<foreach collection="msgIds" item="deptId" index="i" open="(" close=")" separator=",">
#{deptId}
</foreach>
</update>
<update id="updateImMsgReadByIds">
UPDATE im_inbox
SET `im_inbox`.`update_time` = NOW(),
`im_inbox`.`read_msg_status` = 1,
`im_inbox`.`read_time` = NOW()
WHERE
im_inbox.receiver = #{clientId}
AND im_inbox.fk_msg_id IN
<foreach collection="msgIds" item="deptId" index="i" open="(" close=")" separator=",">
#{deptId}
</foreach>
</update>
<select id="getImInboxById" resultType="com.wecloud.im.biz.module.message.controller.param.ImInboxQueryVo">
select
<include refid="Base_Column_List"/>
from im_Inbox where id = #{id}
</select>
<select id="getImInboxPageList" parameterType="com.wecloud.im.biz.module.message.controller.param.ImInboxPageParam"
resultType="com.wecloud.im.biz.module.message.controller.param.ImInboxQueryVo">
select
<include refid="Base_Column_List"/>
from im_Inbox
</select>
<select id="countMyNotReadCount" resultType="java.lang.Integer">
SELECT COUNT(id)
FROM im_inbox
WHERE receiver = #{clientId}
AND receiver_msg_status = 0
</select>
</mapper>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.wecloud.im.biz.module.message.mapper.ImIosApnsMapper">
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
id
, fk_app_id, apns_file_value, env, bundle_id, pwd
</sql>
<select id="getImIosApnsById" resultType="com.wecloud.im.biz.module.message.controller.param.ImIosApnsQueryVo">
select
<include refid="Base_Column_List"/>
from im_ios_apns where id = #{id}
</select>
<select id="getImIosApnsPageList"
parameterType="com.wecloud.im.biz.module.message.controller.param.ImIosApnsPageParam"
resultType="com.wecloud.im.biz.module.message.controller.param.ImIosApnsQueryVo">
select
<include refid="Base_Column_List"/>
from im_ios_apns
</select>
</mapper>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.wecloud.im.biz.module.thousandchat.mapper.ImMsgReadLastestMapper">
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
id, create_time, update_time, read_time, receive_time, fk_appid, fk_client_id, fk_conversation_id, fk_read_msg_id, fk_receive_msg_id
</sql>
<update id="upsertImMsgReceive">
insert into im_msg_read_lastest(id, create_time, read_time, receive_time, fk_appid, fk_client_id,
fk_conversation_id, fk_read_msg_id, fk_receive_msg_id)
values(#{id}, NOW(), NOW(), NOW(), #{fkAppid}, #{fkClientId}, #{fkConversationId}, #{fkReadMsgId},
#{fkReceiveMsgId})
ON DUPLICATE KEY UPDATE
<if test="fkReadMsgId">
read_time = if(fk_read_msg_id is null or fk_read_msg_id &lt; #{fkReadMsgId}, NOW(), read_time),
fk_read_msg_id = if(fk_read_msg_id is null or fk_read_msg_id &lt; #{fkReadMsgId}, #{fkReadMsgId}, fk_read_msg_id),
</if>
receive_time = if(fk_receive_msg_id is null or fk_receive_msg_id &lt; #{fkReceiveMsgId}, NOW(), receive_time),
fk_receive_msg_id = if(fk_receive_msg_id is null or fk_receive_msg_id &lt; #{fkReceiveMsgId}, #{fkReceiveMsgId}, fk_receive_msg_id)
</update>
<update id="upsertImMsgRead">
insert into im_msg_read_lastest(id, create_time, read_time, fk_appid, fk_client_id, fk_conversation_id, fk_read_msg_id)
values(#{id}, NOW(), NOW(), #{fkAppid}, #{fkClientId}, #{fkConversationId}, #{fkReadMsgId})
ON DUPLICATE KEY UPDATE
read_time = if(fk_read_msg_id is null or fk_read_msg_id &lt; #{fkReadMsgId}, NOW(), read_time),
fk_read_msg_id = if(fk_read_msg_id is null or fk_read_msg_id &lt; #{fkReadMsgId}, #{fkReadMsgId}, fk_read_msg_id)
</update>
<select id="findLastestReadMsgs"
resultType="com.wecloud.im.biz.module.thousandchat.param.ConversationLastestReadMsg">
select fk_conversation_id as conversationId,
fk_read_msg_id as lastestReadMsgId,
fk_receive_msg_id as lastestReceiveMsgId
from im_msg_read_lastest
where fk_client_id = #{clientId}
</select>
<select id="findOfflineMsgs" resultType="com.wecloud.im.biz.module.thousandchat.param.ThousandOffineMsgDto">
<foreach collection="lastestMsgs" item="lastestMsg" separator=" union all ">
select msg.id AS msgId,
msg.create_time,
msg.withdraw_time,
msg.update_date,
client.client_id AS sender,
msg.content,
msg.withdraw,
msg.`event`,
msg.system_flag,
msg.`at`,
msg.send_status,
msg.fk_conversation_id as conversationId,
(SELECT COUNT(a.id) FROM im_message a WHERE a.fk_conversation_id = msg.fk_conversation_id and a.id > #{lastestMsg.lastestReadMsgId})
AS not_read_count,
(SELECT COUNT(b.id) FROM im_message b WHERE b.fk_conversation_id = msg.fk_conversation_id and b.id >= msg.id)
AS not_receiver_count
from im_message msg INNER JOIN `im_client` client ON client.id = msg.sender
where
(and msg.is_delete = 1 and msg.fk_conversation_id = #{lastestMsg.conversationId} and msg.id > #{lastestMsg.lastestReceiveMsgId} )
</foreach>
</select>
</mapper>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.wecloud.im.biz.module.message.mapper.ImMultiRtcRoomMapper">
</mapper>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.wecloud.im.biz.module.message.mapper.ImMultiRtcRoomMemberMapper">
</mapper>
<!--
~ Copyright 2019-2029 geekidea(https://github.com/geekidea)
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>404</title>
</head>
<body>
<h1>Not Found</h1>
</body>
</html>
\ No newline at end of file
<!--
~ Copyright 2019-2029 geekidea(https://github.com/geekidea)
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>500</title>
</head>
<body>
<h1>500</h1>
</body>
</html>
\ No newline at end of file
<!--
~ Copyright 2019-2029 geekidea(https://github.com/geekidea)
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>404</title>
</head>
<body>
<h1>Error</h1>
</body>
</html>
\ No newline at end of file
#/**
#* 操作成功
#**/
api.response.code.SUCCESS=成功
#/**
#* 非法访问
#**/
api.response.code.UNAUTHORIZED=非法访问
#/**
#* 没有权限
#**/
api.response.code.NOT_PERMISSION=没有权限
#/**
#* 你请求的资源不存在
#**/
api.response.code.NOT_FOUND=你请求的资源不存在
#/**
#* 操作失败
#**/
api.response.code.FAIL=操作失败
#/**
#* 登录失败
#**/
api.response.code.LOGIN_EXCEPTION=登录失败
#/**
#* 系统异常
#**/
api.response.code.SYSTEM_EXCEPTION=系统异常
#/**
#* 请求参数校验异常
#**/
api.response.code.PARAMETER_EXCEPTION=请求参数校验异常
#/**
#* 请求参数解析异常
#**/
api.response.code.PARAMETER_PARSE_EXCEPTION=请求参数解析异常
#/**
#* HTTP内容类型异常
#**/
api.response.code.HTTP_MEDIA_TYPE_EXCEPTION=HTTP内容类型异常
#/**
#* 系统处理异常
#**/
api.response.code.SPRING_BOOT_PLUS_EXCEPTION=系统处理异常
#/**
#* 业务处理异常
#**/
api.response.code.BUSINESS_EXCEPTION=业务处理异常
#/**
#* 数据库处理异常
#**/
api.response.code.DAO_EXCEPTION=数据库处理异常
#/**
#* 验证码校验异常
#**/
api.response.code.VERIFICATION_CODE_EXCEPTION=验证码校验异常
#/**
#* 登录授权异常
#**/
api.response.code.AUTHENTICATION_EXCEPTION=登录授权异常
#/**
#* 没有访问权限
#**/
api.response.code.UNAUTHENTICATED_EXCEPTION=没有访问权限
#/**
#* 没有访问权限
#**/
api.response.code.UNAUTHORIZED_EXCEPTION=没有访问权限
#/**
#* JWT Token解析异常
#**/
api.response.code.JWTDECODE_EXCEPTION=Token解析异常
#
#/**
#* 默认的异常处理
#*/
api.response.code.HTTP_REQUEST_METHOD_NOT_SUPPORTED_EXCEPTION=默认的异常处理
api.response.code.user.PWD_OR_USERNAME_ERROR=账号或密码错误
#/**
#* 操作成功
#**/
api.response.code.SUCCESS=success
#/**
#* 非法访问
#**/
api.response.code.UNAUTHORIZED=UNAUTHORIZED
#/**
#* 没有权限
#**/
api.response.code.NOT_PERMISSION=NOT_PERMISSION
#/**
#* 你请求的资源不存在
#**/
api.response.code.NOT_FOUND=NOT_FOUND
#/**
#* 操作失败
#**/
api.response.code.FAIL=FAIL
#/**
#* 登录失败
#**/
api.response.code.LOGIN_EXCEPTION=LOGIN_EXCEPTION
#/**
#* 系统异常
#**/
api.response.code.SYSTEM_EXCEPTION=SYSTEM_EXCEPTION
#/**
#* 请求参数校验异常
#**/
api.response.code.PARAMETER_EXCEPTION=PARAMETER_EXCEPTION
#/**
#* 请求参数解析异常
#**/
api.response.code.PARAMETER_PARSE_EXCEPTION=PARAMETER_PARSE_EXCEPTION
#/**
#* HTTP内容类型异常
#**/
api.response.code.HTTP_MEDIA_TYPE_EXCEPTION=HTTP_MEDIA_TYPE_EXCEPTION
#/**
#* 系统处理异常
#**/
api.response.code.SPRING_BOOT_PLUS_EXCEPTION=SPRING_BOOT_PLUS_EXCEPTION
#/**
#* 业务处理异常
#**/
api.response.code.BUSINESS_EXCEPTION=BUSINESS_EXCEPTION
#/**
#* 数据库处理异常
#**/
api.response.code.DAO_EXCEPTION=DAO_EXCEPTION
#/**
#* 验证码校验异常
#**/
api.response.code.VERIFICATION_CODE_EXCEPTION=VERIFICATION_CODE_EXCEPTION
#/**
#* 登录授权异常
#**/
api.response.code.AUTHENTICATION_EXCEPTION=AUTHENTICATION_EXCEPTION
#/**
#* 没有访问权限
#**/
api.response.code.UNAUTHENTICATED_EXCEPTION=UNAUTHENTICATED_EXCEPTION
#/**
#* 没有访问权限
#**/
api.response.code.UNAUTHORIZED_EXCEPTION=UNAUTHORIZED_EXCEPTION
#/**
#* JWT Token解析异常
#**/
api.response.code.JWTDECODE_EXCEPTION=JWTDECODE_EXCEPTION
#
#/**
#* 默认的异常处理
#*/
api.response.code.HTTP_REQUEST_METHOD_NOT_SUPPORTED_EXCEPTION=HTTP_REQUEST_METHOD_NOT_SUPPORTED_EXCEPTION
api.response.code.user.PWD_OR_USERNAME_ERROR=password or phone number error
api.response.code.user.SMS_CODE_ERROR=sms code error
api.response.code.user.USER_NOT_FOUND=user not found
api.response.code.user.PLAIN_TYPE_NOT_FOUND=plain type not found
api.response.code.user.MC_PLANE_NOT_AVAILABLE=This type of aircraft is not available
api.response.code.user.MC_PLANE_EXISTED=This aircraft already exists
#/**
#* 操作成功
#**/
api.response.code.SUCCESS=SUCCESS
#/**
#* 非法访问
#**/
api.response.code.UNAUTHORIZED=UNAUTHORIZED
#/**
#* 没有权限
#**/
api.response.code.NOT_PERMISSION=NOT_PERMISSION
#/**
#* 你请求的资源不存在
#**/
api.response.code.NOT_FOUND=NOT_FOUND
#/**
#* 操作失败
#**/
api.response.code.FAIL=FAIL
#/**
#* 登录失败
#**/
api.response.code.LOGIN_EXCEPTION=LOGIN_EXCEPTION
#/**
#* 系统异常
#**/
api.response.code.SYSTEM_EXCEPTION=SYSTEM_EXCEPTION
#/**
#* 请求参数校验异常
#**/
api.response.code.PARAMETER_EXCEPTION=PARAMETER_EXCEPTION
#/**
#* 请求参数解析异常
#**/
api.response.code.PARAMETER_PARSE_EXCEPTION=PARAMETER_PARSE_EXCEPTION
#/**
#* HTTP内容类型异常
#**/
api.response.code.HTTP_MEDIA_TYPE_EXCEPTION=HTTP_MEDIA_TYPE_EXCEPTION
#/**
#* 系统处理异常
#**/
api.response.code.SPRING_BOOT_PLUS_EXCEPTION=SPRING_BOOT_PLUS_EXCEPTION
#/**
#* 业务处理异常
#**/
api.response.code.BUSINESS_EXCEPTION=BUSINESS_EXCEPTION
#/**
#* 数据库处理异常
#**/
api.response.code.DAO_EXCEPTION=DAO_EXCEPTION
#/**
#* 验证码校验异常
#**/
api.response.code.VERIFICATION_CODE_EXCEPTION=VERIFICATION_CODE_EXCEPTION
#/**
#* 登录授权异常
#**/
api.response.code.AUTHENTICATION_EXCEPTION=AUTHENTICATION_EXCEPTION
#/**
#* 没有访问权限
#**/
api.response.code.UNAUTHENTICATED_EXCEPTION=UNAUTHENTICATED_EXCEPTION
#/**
#* 没有访问权限
#**/
api.response.code.UNAUTHORIZED_EXCEPTION=UNAUTHORIZED_EXCEPTION
#/**
#* JWT Token解析异常
#**/
api.response.code.JWTDECODE_EXCEPTION=JWTDECODE_EXCEPTION
#
#/**
#* 默认的异常处理
#*/
api.response.code.HTTP_REQUEST_METHOD_NOT_SUPPORTED_EXCEPTION=HTTP_REQUEST_METHOD_NOT_SUPPORTED_EXCEPTION
api.response.code.user.PWD_OR_USERNAME_ERROR=password or phone number error KH
api.response.code.user.SMS_CODE_ERROR=sms code error
api.response.code.user.USER_NOT_FOUND=user not found
\ No newline at end of file
#/**
#* 操作成功
#**/
api.response.code.SUCCESS=成功
#/**
#* 非法访问
#**/
api.response.code.UNAUTHORIZED=非法访问
#/**
#* 没有权限
#**/
api.response.code.NOT_PERMISSION=没有权限
#/**
#* 你请求的资源不存在
#**/
api.response.code.NOT_FOUND=你请求的资源不存在
#/**
#* 操作失败
#**/
api.response.code.FAIL=操作失败
#/**
#* 登录失败
#**/
api.response.code.LOGIN_EXCEPTION=登录失败
#/**
#* 系统异常
#**/
api.response.code.SYSTEM_EXCEPTION=系统异常
#/**
#* 请求参数校验异常
#**/
api.response.code.PARAMETER_EXCEPTION=请求参数校验异常
#/**
#* 请求参数解析异常
#**/
api.response.code.PARAMETER_PARSE_EXCEPTION=请求参数解析异常
#/**
#* HTTP内容类型异常
#**/
api.response.code.HTTP_MEDIA_TYPE_EXCEPTION=HTTP内容类型异常
#/**
#* 系统处理异常
#**/
api.response.code.SPRING_BOOT_PLUS_EXCEPTION=系统处理异常
#/**
#* 业务处理异常
#**/
api.response.code.BUSINESS_EXCEPTION=业务处理异常
#/**
#* 数据库处理异常
#**/
api.response.code.DAO_EXCEPTION=数据库处理异常
#/**
#* 验证码校验异常
#**/
api.response.code.VERIFICATION_CODE_EXCEPTION=验证码校验异常
#/**
#* 登录授权异常
#**/
api.response.code.AUTHENTICATION_EXCEPTION=登录授权异常
#/**
#* 没有访问权限
#**/
api.response.code.UNAUTHENTICATED_EXCEPTION=没有访问权限
#/**
#* 没有访问权限
#**/
api.response.code.UNAUTHORIZED_EXCEPTION=没有访问权限
#/**
#* JWT Token解析异常
#**/
api.response.code.JWTDECODE_EXCEPTION=Token解析异常
#
#/**
#* 默认的异常处理
#*/
api.response.code.HTTP_REQUEST_METHOD_NOT_SUPPORTED_EXCEPTION=默认的异常处理
api.response.code.REPETITION_CONVERSATION=已有会话,不能重复创建会话
api.response.code.CLIENT_NOT_FOUNT=成员不存在,不能创建会话
api.response.code.IS_BE_BLACK=被对方拉黑
api.response.code.IS_TO_BLACK=你把对方拉黑
api.response.code.IS_BE_FORBID_SEND_LINK=????????
api.response.code.IS_BE_FORBID_SEND_PIC=????????
<!--
~ Copyright 2019-2029 geekidea(https://github.com/geekidea)
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>验证码</title>
</head>
<body>
<div>
<p>方式一:获取图片</p>
<img alt="" id="imageCode" onclick="changeImage()" src="http://localhost:8888/verificationCode/getImage">
<p>verifyToken:查看Responses Headers</p>
</div>
<hr>
<div>
<p>方式二:获取base64图片编码</p>
<img alt="" id="base64ImageCode" onclick="changeBase64Image()" src="">
<p id="verifyToken"></p>
</div>
<script type="text/javascript">
function changeImage() {
document.getElementById('imageCode').src = "http://localhost:8888/api/verificationCode/getImage?time=" + System.currentTimeMillis();
}
var url = "http://localhost:8888/api/verificationCode/getBase64Image";
function changeBase64Image() {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && xhr.status == 200) {
var result = JSON.parse(xhr.responseText);
document.getElementById('base64ImageCode').src = result.data.image;
document.getElementById('verifyToken').innerText = "verifyToken:" + result.data.verifyToken;
}
};
xhr.open("GET", url, true);
xhr.send(null);
}
changeBase64Image();
</script>
</body>
</html>
\ No newline at end of file
<!--
~ Copyright 2019-2029 geekidea(https://github.com/geekidea)
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Welcome to spring-boot-plus</title>
</head>
<body>
<h1>Welcome to spring-boot-plus</h1>
<h3>
<a href="https://github.com/geekidea/spring-boot-plus" target="_blank">GITHUB</a>
</h3>
<h3>
<a href="https://gitee.com/geekidea/spring-boot-plus" target="_blank">GITEE</a>
</h3>
<h2>
<a href="https://springboot.plus" target="_blank">springboot.plus</a>
</h2>
</body>
</html>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent> <parent>
<groupId>com.wecloud</groupId>
<artifactId>parent</artifactId> <artifactId>parent</artifactId>
<groupId>com.wecloud</groupId>
<version>2.0</version> <version>2.0</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>im-biz</artifactId> <artifactId>im-paas-biz</artifactId>
<name>im-biz</name> <packaging>jar</packaging>
<description>im 业务模块</description>
<properties> <properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<spring-boot.version>2.2.5.RELEASE</spring-boot.version> <spring-boot.version>2.2.5.RELEASE</spring-boot.version>
<rocket.version>4.3.2</rocket.version> <rocket.version>4.3.2</rocket.version>
</properties> </properties>
...@@ -133,12 +132,6 @@ ...@@ -133,12 +132,6 @@
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-api</artifactId>
<version>1.4.1</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>cn.hutool</groupId> <groupId>cn.hutool</groupId>
<artifactId>hutool-crypto</artifactId> <artifactId>hutool-crypto</artifactId>
</dependency> </dependency>
...@@ -228,4 +221,5 @@ ...@@ -228,4 +221,5 @@
</plugins> </plugins>
</build> </build>
</project> </project>
package com.wecloud;
import org.apache.dubbo.config.spring.context.annotation.EnableDubbo; import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
import org.mybatis.spring.annotation.MapperScan; import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
...@@ -28,9 +26,9 @@ import com.wecloud.im.biz.core.rocketmq.annotation.EnableRocketMq; ...@@ -28,9 +26,9 @@ import com.wecloud.im.biz.core.rocketmq.annotation.EnableRocketMq;
@ServletComponentScan @ServletComponentScan
@EnableCaching @EnableCaching
@EnableRocketMq @EnableRocketMq
@MapperScan({"com.wecloud.**.mapper"}) @MapperScan({"com.wecloud.im.**.mapper"})
@SpringBootApplication(scanBasePackages = {"com.wecloud"}) @SpringBootApplication(scanBasePackages = {"com.wecloud"})
public class SpringBootPlusApplication { public class ImPaasApplication {
public static void main(String[] args) { public static void main(String[] args) {
// logback 与nacos 自带的logback 冲突, nacos的logback 已经先于 项目启动, // logback 与nacos 自带的logback 冲突, nacos的logback 已经先于 项目启动,
...@@ -39,7 +37,7 @@ public class SpringBootPlusApplication { ...@@ -39,7 +37,7 @@ public class SpringBootPlusApplication {
System.setProperty("nacos.logging.default.config.enabled", "false"); System.setProperty("nacos.logging.default.config.enabled", "false");
// 启动spring-boot-plus // 启动spring-boot-plus
ConfigurableApplicationContext context = SpringApplication.run(SpringBootPlusApplication.class, args); ConfigurableApplicationContext context = SpringApplication.run(ImPaasApplication.class, args);
// 打印项目信息 // 打印项目信息
PrintApplicationInfo.print(context); PrintApplicationInfo.print(context);
// 打印项目提示 // 打印项目提示
......
package com.wecloud.im.biz.module.message.controller.param.add;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.util.Date;
import javax.validation.constraints.NotNull;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.wecloud.can.core.base.entity.BaseEntity;
/**
* 第三方应用表
*
* @author wei
* @since 2021-04-27
*/
@Data
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = true)
@ApiModel(value = "ImApplicationAdd")
public class ImApplicationAdd extends BaseEntity {
private static final long serialVersionUID = 1L;
@NotNull(message = "应用appid不能为空")
@ApiModelProperty("应用appid")
@TableId(value = "id", type = IdType.INPUT)
private Long id;
@ApiModelProperty("创建时间")
private Date createTime;
@ApiModelProperty("修改时间")
private Date updateTime;
// @ApiModelProperty("key")
// private String appKey;
//
// @ApiModelProperty("密钥")
// private String appSecret;
@ApiModelProperty("app名称")
private String appName;
@ApiModelProperty("ios推送通道,友盟:1;firebase:2; apns原生:3")
private Integer iosPushChannel;
@ApiModelProperty("安卓推送通道,友盟:1;firebase:2; 信鸽3")
private Integer androidPushChannel;
@ApiModelProperty("友盟推送key")
private String umengKey;
@ApiModelProperty("友盟推送密钥")
private String umengSecret;
@ApiModelProperty("firebase推送密钥")
private String firebaseSecret;
private String adminPwd;
}
package com.wecloud.im.biz.module.message.controller.param.add;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.util.List;
import com.wecloud.can.core.base.entity.BaseEntity;
import com.wecloud.im.biz.enums.JoinConversationTypeEnum;
/**
* @author wei
* @since 2021年11月30日16:57:03
*/
@Data
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = true)
@ApiModel(value = "ImClientToConversation")
public class ImClientToConversation extends BaseEntity {
private static final long serialVersionUID = 1L;
@ApiModelProperty("会话表id")
private Long conversationId;
@ApiModelProperty("要操作的clientId")
private List<String> clientIds;
@ApiModelProperty("加入方式 ")
private JoinConversationTypeEnum joinConversationType;
@ApiModelProperty("邀请人clientId")
private String inviterClientId;
}
package com.wecloud.im.biz.module.message.controller.param.add;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.util.List;
import java.util.Map;
import javax.validation.constraints.NotNull;
import com.wecloud.can.core.base.entity.BaseEntity;
import com.wecloud.im.biz.enums.ChatTypeEnum;
/**
* 会话表
*
* @author wei
* @since 2021-05-07
*/
@Data
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = true)
@ApiModel(value = "ImConversationCreate")
public class ImConversationCreate extends BaseEntity {
private static final long serialVersionUID = 1L;
@ApiModelProperty("可选 对话的名字,可为群组命名。")
private String name;
@ApiModelProperty("string格式,可选 自定义属性,供开发者扩展使用。")
private Map<String, Object> attributes;
@ApiModelProperty("可选 邀请加入会话的客户端,如创建单聊,则填入对方的clientId")
private List<String> clientIds;
@ApiModelProperty("创建者id,sdk调用时传递该参数")
private String creatorUserId;
@ApiModelProperty("成员用户id,sdk调用时传递该参数")
private String memberUserIds;
/**
* @see ChatTypeEnum
*/
@ApiModelProperty("会话属性,1:单聊,2:普通群,3:万人群, 4:聊天室")
@NotNull(message = "会话类型不能为空")
private Integer chatType;
@ApiModelProperty("客户端平台: 1 web, 2 安卓, 3 ios, 4 pc-win, 5 pc-macOs, 需与生成sign时的值一致")
private Integer platform;
@ApiModelProperty("是否加密聊天: 1-是 0-否")
private Integer isEncrypt;
}
package com.wecloud.im.biz.module.message.controller.param.add;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.util.List;
import com.wecloud.can.core.base.entity.BaseEntity;
/**
* 修改是否单向隐藏会话
*
* @author wei
* @since 2021-05-07
*/
@Data
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = true)
@ApiModel(value = "修改是否单向隐藏会话")
public class ImConversationDisplayUpdate extends BaseEntity {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "会话id", required = true)
private List<Long> conversationIds;
@ApiModelProperty(value = "显示状态 1显示 0不显示", required = true)
private Integer displayStatus;
}
...@@ -6,32 +6,28 @@ import lombok.Data; ...@@ -6,32 +6,28 @@ import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors; import lombok.experimental.Accessors;
import java.util.List; import java.util.HashMap;
import com.wecloud.can.core.base.entity.BaseEntity; import com.wecloud.can.core.base.entity.BaseEntity;
import com.wecloud.im.biz.enums.JoinConversationTypeEnum;
/** /**
* 会话表
*
* @author wei * @author wei
* @since 2021年11月30日16:57:03 * @since 2021-05-07
*/ */
@Data @Data
@Accessors(chain = true) @Accessors(chain = true)
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
@ApiModel(value = "ImClientToConversation") @ApiModel(value = "ImConversationMemAttrUpdate")
public class ImClientToConversation extends BaseEntity { public class ImConversationMemAttrUpdate extends BaseEntity {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@ApiModelProperty("json格式,自定义属性,供开发者扩展使用。")
private HashMap attributes;
@ApiModelProperty("会话表id") @ApiModelProperty("会话表id")
private Long conversationId; private Long conversationId;
@ApiModelProperty("要操作的clientId")
private List<String> clientIds;
@ApiModelProperty("加入方式 ")
private JoinConversationTypeEnum joinConversationType;
@ApiModelProperty("邀请人clientId")
private String inviterClientId;
} }
...@@ -6,8 +6,6 @@ import lombok.Data; ...@@ -6,8 +6,6 @@ import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors; import lombok.experimental.Accessors;
import java.util.HashMap;
import com.wecloud.can.core.base.entity.BaseEntity; import com.wecloud.can.core.base.entity.BaseEntity;
/** /**
...@@ -19,15 +17,14 @@ import com.wecloud.can.core.base.entity.BaseEntity; ...@@ -19,15 +17,14 @@ import com.wecloud.can.core.base.entity.BaseEntity;
@Data @Data
@Accessors(chain = true) @Accessors(chain = true)
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
@ApiModel(value = "ImConversationMemAttrUpdate") @ApiModel(value = "ImConversationNameUpdate")
public class ImConversationMemAttrUpdate extends BaseEntity { public class ImConversationNameUpdate extends BaseEntity {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@ApiModelProperty("json格式,自定义属性,供开发者扩展使用。") @ApiModelProperty("对话的名字,可为群组命名。")
private HashMap attributes; private String name;
@ApiModelProperty("会话表id") @ApiModelProperty("会话表id")
private Long conversationId; private Long conversationId;
} }
package com.wecloud.im.biz.module.message.controller.param.add;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import com.wecloud.can.core.base.entity.BaseEntity;
import com.wecloud.im.server.model.request.PushVO;
/**
* 撤回消息
*
* @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 PushVO push;
}
package com.wecloud.im.biz.module.message.controller.param.add;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.util.HashMap;
import com.wecloud.can.core.base.entity.BaseEntity;
/**
* 自定义透传内容
*
* @author wei
*/
@Data
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = true)
@ApiModel(value = "ImMsgSendToOnlineClient")
public class ImMsgSendToOnlineClient extends BaseEntity {
private static final long serialVersionUID = 1L;
// @ApiModelProperty(value = "自定义透传内容", required = true)
// private String content;
@ApiModelProperty(value = "自定义透传内容 ,为任意参数名称和类型的对象,供开发者扩展使用。", required = true)
private HashMap content;
@ApiModelProperty(value = "会话id", required = true)
private Long conversationId;
}
package com.wecloud.im.biz.module.message.controller.param.add;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.util.HashMap;
import com.wecloud.can.core.base.entity.BaseEntity;
/**
* 修改消息
*
* @author wei
* @since 2021-04-27
*/
@Data
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = true)
@ApiModel(value = "ImMsgUpdate")
public class ImMsgUpdate extends BaseEntity {
private static final long serialVersionUID = 1L;
@ApiModelProperty("消息id")
private Long msgId;
@ApiModelProperty("内容")
private HashMap content;
}
package com.wecloud.im.biz.module.message.controller.param.add;
import io.swagger.annotations.ApiModel;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.List;
import java.util.Map;
import com.wecloud.im.biz.enums.ChatTypeEnum;
import com.wecloud.im.biz.module.message.entity.ImApplication;
import com.wecloud.im.biz.module.message.entity.ImClient;
import com.wecloud.imserver.client.model.enums.DeviceTypeEnum;
/**
*
* @Author luozh
* @Date 2022年05月07日 10:13
* @Version 1.0
*/
@Data
@Accessors(chain = true)
@ApiModel(value = "ImConversationCreate")
public class ServerImConversationCreate implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 可选 对话的名字,可为群组命名。")
*/
private String name;
/**
* Map格式,可选 自定义属性,供开发者扩展使用。")
*/
private Map<String, Object> attributes;
/**
* 应用, 前端")
*/
private ImApplication application;
/**
* 创建者 前端请求不传")
*/
private ImClient creator;
/**
* 可选 成员列表
*/
private List<ImClient> members;
/**
* @see ChatTypeEnum
*/
/**
* 会话属性,1:单聊,2:普通群,3:万人群, 4:聊天室")
*/
private ChatTypeEnum chatType;
/**
* 客户端平台: 1 web, 2 安卓, 3 ios, 4 pc-win, 5 pc-macOs, 需与生成sign时的值一致")
*/
private DeviceTypeEnum platform;
}
package com.wecloud.im.biz.module.message.controller.param.group;
import lombok.Getter;
import lombok.Setter;
import javax.validation.constraints.NotBlank;
/**
* 加入群
* @Author luozh
* @Date 2022年05月10日 09:37
* @Version 1.0
*/
@Getter
@Setter
public class JoinGroupParam {
/**
* 邀请进群的用户id
*/
@NotBlank(message = "inviterUserId 不能为空")
private String inviterUserId;
/**
* 要加入群的用户 ID
*/
@NotBlank(message = "userIds 不能为空")
private String userIds;
/**
* 要加入的群的群组 ID
*/
@NotBlank(message = "groupId 不能为空")
private String groupId;
}
package com.wecloud.im.biz.module.message.controller.param.group;
import lombok.Data;
import javax.validation.constraints.NotBlank;
/**
* 离开(踢出)群
* @Author luozh
* @Date 2022年05月10日 09:37
* @Version 1.0
*/
@Data
public class LeaveGroupParam {
/**
* 操作人用户id
*/
@NotBlank(message = "operatorUserId 不能为空")
private String operatorUserId;
/**
* 用户Id
*/
@NotBlank(message = "userIds 不能为空")
private String userIds;
/**
* 群组id
*/
@NotBlank(message = "groupId 不能为空")
private String groupId;
}
package com.wecloud.im.biz.module.message.controller.param.group;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* 禁言群成员入参
* @Author luozh
* @Date 2022年05月16日 19:42
* @Version 1.0
*/
@Data
public class MutedMembersParam {
@ApiModelProperty("群id")
private String groupId;
@ApiModelProperty("是否禁言")
private Boolean muted;
@ApiModelProperty("用户id多个用,隔开")
private String userIds;
}
package com.wecloud.im.biz.module.message.controller.param.rtc;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
/**
* @author wei
* @since 2021-04-29
*/
@Data
@ApiModel(value = "CandidateForwardParam")
public class CandidateForwardParam implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty("频道id")
private Long channelId;
/**
* 转发的候选者数据
*/
private String candidateData;
}
package com.wecloud.im.biz.module.message.controller.param.rtc;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
/**
* 创建频道请求参数
*
* @author wei
* @since 2021-04-29
*/
@Data
@ApiModel(value = "CreateRtcChannelParam")
public class CreateRtcChannelParam implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "被邀请的客户端ID", required = true)
private String toClient;
@ApiModelProperty(value = "客户端自定义数据", required = false)
private String attrs;
@ApiModelProperty(value = "类型: 1-video或2-voice", required = true)
private Integer callType;
@ApiModelProperty(value = "绑定的会话id,可选", required = false)
private Long conversationId;
@ApiModelProperty(value = "接收方展示的系统推送内容,可", required = false)
private String push;
@ApiModelProperty(value = "是否需要给对方发系统通知", required = true)
private Boolean pushCall;
}
package com.wecloud.im.biz.module.message.controller.param.rtc;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
/**
* 创建频道返回参数
*
* @author wei
* @since 2021-04-29
*/
@Data
@ApiModel(value = "CreateRtcChannelResult")
public class CreateRtcChannelResult implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty("频道id")
private Long channelId;
}
package com.wecloud.im.biz.module.message.controller.param.rtc;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
/**
* 加入频道请求参数
*
* @author wei
* @since 2021-04-29
*/
@Data
@ApiModel(value = "JoinRtcChannelParam")
public class JoinRtcChannelParam implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty("频道id")
private Long channelId;
}
package com.wecloud.im.biz.module.message.controller.param.rtc;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
/**
* 退出频道 请求
*
* @author wei
* @since 2021-04-29
*/
@Data
@ApiModel(value = "LeaveRtcChannelParam")
public class LeaveRtcChannelParam implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty("频道id")
private Long channelId;
}
package com.wecloud.im.biz.module.message.controller.param.rtc;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
/**
* 拒接加入频道 请求
*
* @author wei
* @since 2021-04-29
*/
@Data
@ApiModel(value = "RejectRtcChannelParam")
public class RejectRtcChannelParam implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty("频道id")
private Long channelId;
}
package com.wecloud.im.biz.module.message.controller.param.rtc;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
/**
* @author wei
* @since 2021-04-29
*/
@Data
@ApiModel(value = "SdpForwardParam")
public class SdpForwardParam implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty("频道id")
private Long channelId;
@ApiModelProperty("sdp转发的数据")
private String sdpData;
@ApiModelProperty("sdp类型: Offer或Answer")
private String sdpType;
}
package com.wecloud.im.biz.module.message.controller.param.rtc;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
import com.wecloud.im.biz.enums.CallTypeEnum;
/**
* @author nanqianhao
* @date 2022/5/23
* @apiNote
*/
@Data
@ApiModel(value = "单人rtc音视频查找记录")
public class SingleRtcRecordParam implements Serializable {
private static final long serialVersionUID = 2176804812523348248L;
/**
* 发送者id
*/
@ApiModelProperty("发送者id")
private String fromClientId;
/**
* 接受者id
*/
@ApiModelProperty("接受者id")
private String toClientId;
/**
* 房间id
*/
@ApiModelProperty("房间id")
private String channelId;
/**
* 音视频类型
* @see CallTypeEnum
*/
@ApiModelProperty("音视频类型")
private Integer callType;
/***
* 页码
*/
@ApiModelProperty("页码")
private Integer pageNum;
/**
* 每页数量
*/
@ApiModelProperty("每页数量")
private Integer pageSize;
@ApiModelProperty("开始时间")
private Date createTimeStart;
@ApiModelProperty("结束时间")
private Date createTimeEnd;
}
package com.wecloud.im.biz.module.message.controller.serverapi;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.wecloud.can.core.base.controller.BaseController;
import com.wecloud.can.core.enums.ApiCode;
import com.wecloud.can.core.util.ApiResult;
import com.wecloud.im.biz.module.message.controller.param.add.ImMsgSendToOnlineClient;
import com.wecloud.im.biz.module.message.entity.ImApplication;
import com.wecloud.im.biz.module.message.service.ImApplicationService;
import com.wecloud.im.biz.module.message.service.ImMessageService;
/**
* 消息存储表 控制器
*
* @author wei
* @since 2021-04-29
*/
@Slf4j
@RestController
@RequestMapping("/server/imMessage")
@Api(value = "服务端rest-API-消息", tags = {"服务端rest-API-消息"})
public class ApiImMessageController extends BaseController {
@Autowired
private ImApplicationService imApplicationService;
@Autowired
private ImMessageService imMessageService;
/**
* 向会话中在线client,下发透传消息
*/
@PostMapping("/sendToOnlineClient")
@ApiOperation(value = "向会话中在线client,下发透传消息", notes = "应用服务端向某会话中所有client下发透传消息, 不会保存进离线消息, 仅在线client能收到")
public ApiResult<Boolean> restApiImMessageSend(@RequestBody ImMsgSendToOnlineClient imMsgSendToOnlineClient, @RequestHeader String appkey, @RequestHeader String appSecret) throws Exception {
// return imMessageService.updateMsgWithdrawById(imMsgRecall);
// 根据appKey从数据库查询密钥
ImApplication imApplication = imApplicationService.getCacheAppByAppKey(appkey);
if (imApplication == null) {
return ApiResult.result(ApiCode.FAIL, null);
}
// 校验appkey 和appSecret
if (!imApplication.getAppSecret().equals(appSecret)) {
return ApiResult.result(ApiCode.FAIL, null);
}
return imMessageService.restApiImMessageSend(imMsgSendToOnlineClient, imApplication);
}
}
package com.wecloud.im.biz.module.message.controller.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import java.io.Serializable;
/**
* @Author wenzhida
* @Date 2022/4/27 16:47
* @Description 聊天室成员VO
*/
@Data
@Accessors(chain = true)
@ApiModel(value = "聊天室成员VO")
@AllArgsConstructor
@NoArgsConstructor
public class ChatRoomMemberVo implements Serializable {
private static final long serialVersionUID = 5417994988121322697L;
@ApiModelProperty("聊天室房间id")
private Long chatRoomId;
@ApiModelProperty("客户端id")
private String clientId;
}
package com.wecloud.im.biz.module.message.controller.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
import com.wecloud.im.biz.enums.RelationEnum;
/**
* @Author wenzhida
* @Date 2022/2/15 11:29
* @Description
*/
@Data
@Accessors(chain = true)
@ApiModel(value = "ClientInfoVo")
public class ClientInfoVo implements Serializable {
private static final long serialVersionUID = 1474979499551389791L;
@ApiModelProperty("client主键id")
private Long id;
@ApiModelProperty("会话中client的备注名")
private String clientRemarkName;
@ApiModelProperty("头像")
private String headPortrait;
@ApiModelProperty("主昵称")
private String nickname;
@ApiModelProperty("clientId")
private String clientId;
@ApiModelProperty("client自己的自定义扩展属性")
private String clientAttributes;
@ApiModelProperty("会话成员列表的自定义扩展属性")
private String memberAttributes;
/**
* 与我关系
* @see RelationEnum
*/
@ApiModelProperty("与我关系 1-陌生人 2-好友 3-被我拉黑")
private Integer relation;
}
package com.wecloud.im.biz.module.message.controller.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
import com.wecloud.im.biz.enums.GroupRoleEnum;
import com.wecloud.im.biz.enums.MutedEnum;
@Data
@Accessors(chain = true)
@ApiModel(value = "ImConversationMemberListVo")
public class ConversationMemberVo implements Serializable {
private static final long serialVersionUID = 7278014943001080361L;
@ApiModelProperty("主键id")
private Long id;
@ApiModelProperty("会话中client的备注名")
private String clientRemarkName;
@ApiModelProperty("头像")
private String headPortrait;
@ApiModelProperty("主昵称")
private String nickname;
@ApiModelProperty("clientId")
private String clientId;
@ApiModelProperty("client自己的自定义扩展属性")
private String clientAttributes;
@ApiModelProperty("会话成员列表的自定义扩展属性")
private String memberAttributes;
/**
* 群内角色
* @see GroupRoleEnum
*/
@ApiModelProperty("群内角色")
private Integer role;
/**
* 禁言开关
* @see MutedEnum
*/
@ApiModelProperty("禁言开关 1-未禁言 2-禁言")
private Integer muted;
}
package com.wecloud.im.biz.module.message.controller.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.Date;
import com.baomidou.mybatisplus.annotation.TableField;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.wecloud.im.biz.enums.MutedEnum;
/**
* <pre>
* 会话表 查询结果对象
* </pre>
*
* @author wei
* @date 2021-05-07
*/
@Data
@Accessors(chain = true)
@ApiModel(value = "MyConversationListVo")
public class ConversationVo implements Serializable {
private static final long serialVersionUID = -4330507756623541941L;
@ApiModelProperty("会话id")
private Long id;
@ApiModelProperty("创建时间")
private Date createTime;
@ApiModelProperty("创建者客户端id")
private String creator;
@ApiModelProperty("可选 对话的名字,可为群组命名。")
private String name;
@ApiModelProperty(value = "可选 自定义属性,供开发者扩展使用。", hidden = true)
@JsonIgnore
private String attribute;
@ApiModelProperty("可选 自定义属性,供开发者扩展使用。")
private String attributes;
@ApiModelProperty("可选 对话类型标志,是否是系统对话,后面会说明。")
private Boolean systemFlag;
@ApiModelProperty("未读消息条数")
private Long msgNotReadCount;
@ApiModelProperty("成员")
private String members;
@ApiModelProperty("会话属性,1:单聊,2:普通群,3:万人群 4:聊天室")
private Integer chatType;
@ApiModelProperty("群成员数")
private Integer memberCount;
@ApiModelProperty("会话最后一条消息")
private OfflineMsgDto lastMsg;
@ApiModelProperty("是否被@ true-是 false-否")
private Boolean isBeAt;
/**
* 禁言开关
* @see MutedEnum
*/
@ApiModelProperty("禁言开关 1-未禁言 2-禁言")
private Integer muted;
@ApiModelProperty("禁言开关 1-未禁言 2-禁言")
private Integer beAtCount;
@ApiModelProperty("禁止互加好友")
private Boolean forbidAddFriend;
@ApiModelProperty("禁止发图片")
private Boolean forbidSendPic;
@ApiModelProperty("禁止发链接")
private Boolean forbidSendLink;
@ApiModelProperty("群头像")
private String headPortrait;
@ApiModelProperty("免打扰开关 0-关闭 1开启")
private Boolean doNotDisturb;
@TableField("is_top")
private Boolean top;
@ApiModelProperty("是否为加密聊天 0-否 1-是")
private Integer isEncrypt;
}
package com.wecloud.im.biz.module.message.controller.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
@Data
@Accessors(chain = true)
@ApiModel(value = "GetInfoListVo")
public class GetInfoListVo implements Serializable {
@ApiModelProperty("client主键id")
private Long id;
@ApiModelProperty("会话中client的备注名")
private String clientRemarkName;
@ApiModelProperty("头像")
private String headPortrait;
@ApiModelProperty("主昵称")
private String nickname;
@ApiModelProperty("clientId")
private String clientId;
@ApiModelProperty("client自己的自定义扩展属性")
private String clientAttributes;
@ApiModelProperty("会话成员列表的自定义扩展属性")
private String memberAttributes;
}
package com.wecloud.im.biz.module.message.controller.param.add; package com.wecloud.im.biz.module.message.controller.vo;
import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
...@@ -17,14 +17,11 @@ import com.wecloud.can.core.base.entity.BaseEntity; ...@@ -17,14 +17,11 @@ import com.wecloud.can.core.base.entity.BaseEntity;
@Data @Data
@Accessors(chain = true) @Accessors(chain = true)
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
@ApiModel(value = "ImConversationNameUpdate") @ApiModel(value = "ImConversationCreateVo")
public class ImConversationNameUpdate extends BaseEntity { public class ImConversationCreateVo extends BaseEntity {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@ApiModelProperty("对话的名字,可为群组命名。") @ApiModelProperty("会话id")
private String name; private Long id;
@ApiModelProperty("会话表id")
private Long conversationId;
} }
package com.wecloud.im.biz.module.message.controller.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.List;
/**
* <pre>
* 离线消息列表 查询结果对象
* </pre>
*
* @author wei
* @date 2021-04-29
*/
@Data
@Accessors(chain = true)
@ApiModel(value = "ImMessageOfflineListVo")
public class ImMessageOfflineListVo implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty("会话id")
private Long conversationId;
@ApiModelProperty("消息列表")
private List<OfflineMsgDto> msgList;
}
package com.wecloud.im.biz.module.message.controller.param.add; package com.wecloud.im.biz.module.message.controller.vo;
import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
...@@ -6,12 +6,10 @@ import lombok.Data; ...@@ -6,12 +6,10 @@ import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors; import lombok.experimental.Accessors;
import java.util.List;
import com.wecloud.can.core.base.entity.BaseEntity; import com.wecloud.can.core.base.entity.BaseEntity;
/** /**
* 修改是否单向隐藏会话 * 在线状态
* *
* @author wei * @author wei
* @since 2021-05-07 * @since 2021-05-07
...@@ -19,13 +17,11 @@ import com.wecloud.can.core.base.entity.BaseEntity; ...@@ -19,13 +17,11 @@ import com.wecloud.can.core.base.entity.BaseEntity;
@Data @Data
@Accessors(chain = true) @Accessors(chain = true)
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
@ApiModel(value = "修改是否单向隐藏会话") @ApiModel(value = "ImOnlineStatusVo")
public class ImConversationDisplayUpdate extends BaseEntity { public class ImOnlineStatusVo extends BaseEntity {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@ApiModelProperty("true:在线, false 不在线")
private Boolean status;
@ApiModelProperty(value = "会话id", required = true) private String clientId;
private List<Long> conversationIds;
@ApiModelProperty(value = "显示状态 1显示 0不显示", required = true)
private Integer displayStatus;
} }
package com.wecloud.im.biz.module.message.controller.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.Date;
/**
* <pre>
* 会话表 查询结果对象
* </pre>
*
* @author wei
* @date 2021-05-07
*/
@Data
@Accessors(chain = true)
@ApiModel(value = "MyConversationMemberVo")
public class MyConversationMembersVo implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty("加入时间")
private Date joinTime;
@ApiModelProperty("客户端id")
private String clientId;
@ApiModelProperty("名字")
private String name;
}
package com.wecloud.im.biz.module.message.controller.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.Date;
/**
* @Author wenzhida
* @Date 2022/2/15 16:22
* @Description 我的信息
*/
@Data
@Accessors(chain = true)
@ApiModel(value = "我的信息")
public class MyInfoVo implements Serializable {
private static final long serialVersionUID = -5423843620435586377L;
@ApiModelProperty("主键id")
private Long id;
@ApiModelProperty("clientId")
private String clientId;
@ApiModelProperty("最后离线时间")
private Date lastOfflineTime;
@ApiModelProperty("头像")
private String headPortrait;
@ApiModelProperty("主昵称")
private String nickname;
@ApiModelProperty("可选 自定义属性,供开发者扩展使用。")
private String attributes;
}
package com.wecloud.im.biz.module.message.controller.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.Date;
/**
* @Author wenzhida
* @Date 2022/3/3 11:19
* @Description 离线消息内容实体
*/
@Data
@Accessors(chain = true)
@ApiModel(value = "OfflineMsgDto")
public class OfflineMsgDto implements Serializable {
private static final long serialVersionUID = -7073389493201687249L;
@ApiModelProperty("会话id")
private Long conversationId;
@ApiModelProperty("消息类型")
private Integer type;
@ApiModelProperty("消息id")
private Long msgId;
@ApiModelProperty("创建时间")
private Date createTime;
@ApiModelProperty("撤回时间")
private Date withdrawTime;
@ApiModelProperty("发送者客户端id")
private String sender;
@ApiModelProperty("内容")
private String content;
@ApiModelProperty("0未撤回; 1已撤回")
private Boolean withdraw;
@ApiModelProperty("0非事件; 1为事件")
private Boolean event;
@ApiModelProperty("0非系统通知; 1为系统通知")
private Boolean systemFlag;
@ApiModelProperty("at他人,传入客户端id数组")
private String at;
@ApiModelProperty("未读人数统计,全部人已读为0")
private Integer notReadCount;
@ApiModelProperty("未接收人数统计,全部人已接收为0")
private Integer notReceiverCount;
// @ApiModelProperty("读取时间")
// private Date readTime;
//
// @ApiModelProperty("接收时间")
// private Date receiverTime;
// @ApiModelProperty("0未接收; 1已接收")
// private Integer receiverMsgStatus;
}
package com.wecloud.im.biz.module.message.controller.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.List;
/**
* @Author wenzhida
* @Date 2022/2/15 20:54
* @Description 已读client展示VO
*/
@Data
@Accessors(chain = true)
@ApiModel(value = "已读client展示VO")
public class ReaderList implements Serializable {
private static final long serialVersionUID = 4658402570720540541L;
@ApiModelProperty("已读人员列表")
private List<ReaderVo> readList;
@ApiModelProperty("未读人员列表")
private List<ReaderVo> unReadList;
}
package com.wecloud.im.biz.module.message.controller.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
/**
* @Author wenzhida
* @Date 2022/2/15 20:54
* @Description 读者VO
*/
@Data
@Accessors(chain = true)
@ApiModel(value = "读者VO")
public class ReaderVo implements Serializable {
private static final long serialVersionUID = 4390952170006190474L;
@ApiModelProperty("client主键id")
private Long id;
@ApiModelProperty("头像")
private String headPortrait;
@ApiModelProperty("主昵称")
private String nickname;
@ApiModelProperty("clientId")
private String clientId;
@ApiModelProperty("是否已读 0-否 1-是")
private Integer readMsgStatus;
}
package com.wecloud.im.biz.module.message.controller.vo;
import lombok.Data;
/**
*
* @Author luozh
* @Date 2022年04月13日 17:14
* @Version 1.0
*/
@Data
public class RegisterClientResponse {
private static final long serialVersionUID = 1L;
private Long userId;
}
package com.wecloud.im.biz.module.message.controller.vo;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
@Data
public class TokenVo implements Serializable {
/**
* websocket登陆令牌
*/
private String token;
@ApiModelProperty("客户端id")
private Long id;
@ApiModelProperty("webSocket连接地址")
private String wsAddr;
@ApiModelProperty("加密密钥")
private String dataAesKey;
@ApiModelProperty("可选 自定义属性,供开发者扩展使用。")
private String attributes;
}
package com.wecloud.im.biz.module.message.entity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.util.Date;
import com.wecloud.can.core.base.entity.BaseEntity;
/**
* 消息在线推送
*
* @author wei
* @since 2021-04-29
*/
@Data
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = true)
@ApiModel(value = "ImApiMessageOnlineSend ")
public class ImApiMessageOnlineSend extends BaseEntity {
private static final long serialVersionUID = 1L;
@ApiModelProperty("创建时间")
private Date createTime;
@ApiModelProperty("内容")
private String content;
@ApiModelProperty("会话id")
private Long conversationId;
}
package com.wecloud.im.biz.module.message.entity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.util.Date;
import javax.validation.constraints.NotNull;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.wecloud.can.core.base.entity.BaseEntity;
import com.wecloud.can.security.signature.Application;
/**
* 第三方应用表
*
* @author wei
* @since 2021-04-27
*/
@Data
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = true)
@ApiModel(value = "ImApplication对象")
public class ImApplication extends BaseEntity implements Application {
private static final long serialVersionUID = 1L;
@NotNull(message = "应用appid不能为空")
@ApiModelProperty("应用appid")
@TableId(value = "id", type = IdType.INPUT)
private Long id;
@ApiModelProperty("创建时间")
private Date createTime;
@ApiModelProperty("修改时间")
private Date updateTime;
@ApiModelProperty("key")
private String appKey;
@ApiModelProperty("密钥")
private String appSecret;
@ApiModelProperty("app名称")
private String appName;
@ApiModelProperty("ios推送通道,友盟:1;firebase:2; apns原生:3")
private Integer iosPushChannel;
@ApiModelProperty("安卓推送通道,友盟:1;firebase:2; 信鸽3")
private Integer androidPushChannel;
@ApiModelProperty("友盟推送key")
private String umengKey;
@ApiModelProperty("友盟推送密钥")
private String umengSecret;
@ApiModelProperty("firebase推送密钥")
private String firebaseSecret;
@ApiModelProperty("是否允许创建重复会话 0不允许 1允许")
private Integer repeatSessionStatus;
@ApiModelProperty("创建会话时对比扩展字段 0不 1是")
private Integer contrastExtendedFieldStatus;
@ApiModelProperty("在线状态订阅地址")
private String onlineStatusSubscribeUrl;
@ApiModelProperty("全量消息订阅地址")
private String fullMessageSubscribeUrl;
@ApiModelProperty("租户id")
private Long ownerId;
@ApiModelProperty("公司id")
private Long companyId;
@ApiModelProperty("状态 1-正常 2-异常 3-删除")
private Integer status;
@Override
public Boolean isActive() {
return true;
}
}
package com.wecloud.im.biz.module.message.entity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.util.Date;
import javax.validation.constraints.NotNull;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.wecloud.can.core.base.entity.BaseEntity;
/**
* 终端表
*
* @author wei
* @since 2021-04-27
*/
@Data
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = true)
@ApiModel(value = "ImClient对象")
public class ImClient extends BaseEntity {
private static final long serialVersionUID = 1L;
@NotNull(message = "客户端id不能为空")
@ApiModelProperty("客户端id")
@TableId(value = "id", type = IdType.INPUT)
private Long id;
@ApiModelProperty("创建时间")
private Date createTime;
@ApiModelProperty("最后离线时间")
private Date lastOfflineTime;
@ApiModelProperty("修改时间")
private Date updateTime;
@ApiModelProperty("应用appid")
private Long fkAppid;
@ApiModelProperty("可选 自定义属性,供开发者扩展使用。")
private String attributes;
@ApiModelProperty("客户方提供的唯一id")
private String clientId;
@ApiModelProperty("头像")
private String headPortrait;
@ApiModelProperty("主昵称")
private String nickname;
}
package com.wecloud.im.biz.module.message.entity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.util.Date;
import javax.validation.constraints.NotNull;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.wecloud.can.core.base.entity.BaseEntity;
/**
* 黑名单
*
* @author wei
* @since 2021-06-17
*/
@Data
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = true)
@ApiModel(value = "ImClientBlacklist对象")
public class ImClientBlacklist extends BaseEntity {
private static final long serialVersionUID = 1L;
@NotNull(message = "客户端id不能为空")
@ApiModelProperty("客户端id")
@TableId(value = "id", type = IdType.INPUT)
private Long id;
@ApiModelProperty("创建时间")
private Date createTime;
@ApiModelProperty("修改时间")
private Date updateTime;
@ApiModelProperty("应用appid")
private Long fkAppid;
@ApiModelProperty("拉黑者")
private String clientIdPrevent;
@ApiModelProperty("被拉黑")
private String clientIdBePrevent;
}
package com.wecloud.im.biz.module.message.entity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.util.Date;
import javax.validation.constraints.NotNull;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.wecloud.can.core.base.entity.BaseEntity;
/**
* @Author wenzhida
* @Date 2022/3/2 14:52
* @Description 客户端设备
*/
@Data
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = true)
@ApiModel(value = "客户端设备")
public class ImClientDevice extends BaseEntity {
private static final long serialVersionUID = 6988763580951760226L;
@NotNull(message = "主键id不能为空")
@ApiModelProperty("主键id")
@TableId(value = "id", type = IdType.INPUT)
private Long id;
@ApiModelProperty("应用appid")
private Long fkAppid;
@ApiModelProperty("client主键id")
private Long fkClientId;
@ApiModelProperty("设备不想收到推送提醒, 1想, 0不想")
private Integer valid;
@ApiModelProperty("设备类型 1:ios; 2:android; 3:web; 4:win; 5:mac")
private Integer deviceType;
@ApiModelProperty("设备推送token")
private String deviceToken;
@ApiModelProperty("唯一id")
private String uniqueDeviceId;
@ApiModelProperty("创建时间")
private Date createTime;
@ApiModelProperty("修改时间")
private Date updateTime;
}
package com.wecloud.im.biz.module.message.entity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.util.Date;
import javax.validation.constraints.NotNull;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.wecloud.can.core.base.entity.BaseEntity;
import com.wecloud.im.biz.enums.ChatTypeEnum;
import com.wecloud.im.biz.enums.MutedEnum;
/**
* 会话表
*
* @author wei
* @since 2021-05-07
*/
@Data
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = true)
@ApiModel(value = "ImConversation对象")
public class ImConversation extends BaseEntity {
private static final long serialVersionUID = 1L;
@NotNull(message = "会话id不能为空")
@ApiModelProperty("会话id")
@TableId(value = "id", type = IdType.INPUT)
private Long id;
@ApiModelProperty("创建时间")
private Date createTime;
@ApiModelProperty("修改时间")
private Date updateTime;
@ApiModelProperty("对话中最后一条消息的发送或接收时间")
private Date lastMessage;
@ApiModelProperty("群成员数量")
private Integer memberCount;
/**
* 会话属性
* @see ChatTypeEnum
*/
@ApiModelProperty("会话属性,1:单聊,2:普通群,3:万人群,4:聊天室")
private Integer chatType;
@NotNull(message = "应用appid不能为空")
@ApiModelProperty("应用appid")
private Long fkAppid;
@NotNull(message = "创建者客户端id不能为空")
@ApiModelProperty("创建者客户端id")
private Long creator;
@ApiModelProperty("可选 对话的名字,可为群组命名。")
private String name;
@ApiModelProperty("群头像")
private String headPortrait;
@ApiModelProperty("可选 自定义属性,供开发者扩展使用。")
private String attributes;
@ApiModelProperty("可选 对话类型标志,是否是系统对话,后面会说明。")
private Boolean systemFlag;
/**
* 禁言开关
* @see MutedEnum
*/
@ApiModelProperty("禁言开关 1-未禁言 2-禁言")
private Integer muted;
@TableField("is_forbid_add_friend")
@ApiModelProperty("禁止互加好友")
private Boolean forbidAddFriend;
@TableField("is_forbid_send_pic")
@ApiModelProperty("禁止发图片")
private Boolean forbidSendPic;
@TableField("is_forbid_send_link")
@ApiModelProperty("禁止发链接")
private Boolean forbidSendLink;
@ApiModelProperty("是否为加密聊天 0-否 1-是")
private Integer isEncrypt;
}
package com.wecloud.im.biz.module.message.entity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.util.Date;
import javax.validation.constraints.NotNull;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.wecloud.can.core.base.entity.BaseEntity;
import com.wecloud.im.biz.enums.GroupRoleEnum;
import com.wecloud.im.biz.enums.MutedEnum;
/**
* 会话成员表
*
* @author wei
* @since 2021-05-07
*/
@Data
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = true)
@ApiModel(value = "ImConversationMembers对象")
public class ImConversationMembers extends BaseEntity {
private static final long serialVersionUID = 1L;
@NotNull(message = "唯一id不能为空")
@ApiModelProperty("唯一id")
@TableId(value = "id", type = IdType.INPUT)
private Long id;
@ApiModelProperty("加入时间")
private Date createTime;
@ApiModelProperty("修改时间")
private Date updateTime;
@NotNull(message = "应用appid不能为空")
@ApiModelProperty("应用appid")
private Long fkAppid;
@NotNull(message = "会话表id不能为空")
@ApiModelProperty("会话表id")
private Long fkConversationId;
@NotNull(message = "客户端id不能为空")
@ApiModelProperty("客户端id")
private Long fkClientId;
@ApiModelProperty("可选 自定义属性,供开发者扩展使用。")
private String attributes;
@NotNull(message = "单向删除(隐藏)会话, 0不显示, 1显示不能为空")
@ApiModelProperty("单向删除(隐藏)会话, 0不显示, 1显示")
private Long displayStatus;
@ApiModelProperty("会话中client的备注名")
private String clientRemarkName;
/**
* 群内角色
* @see GroupRoleEnum
*/
@ApiModelProperty("群内角色")
private Integer role;
/**
* 禁言开关
* @see MutedEnum
*/
@ApiModelProperty("禁言开关 1-未禁言 2-禁言")
private Integer muted;
/**
* 客户方提供的唯一id
*/
@ApiModelProperty("客户方提供的唯一id")
private String clientId;
@ApiModelProperty("免打扰开关 0-关闭 1开启")
@TableField("is_do_not_disturb")
private Boolean doNotDisturb;
@ApiModelProperty("置顶开关 0-关闭 1开启")
@TableField("is_top")
private Boolean top;
@ApiModelProperty("加入会话方式编码")
private String joinTypeCode;
@ApiModelProperty("加入会话方式信息")
private String joinTypeMsg;
}
package com.wecloud.im.biz.module.message.entity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.util.Date;
import javax.validation.constraints.NotNull;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.wecloud.can.core.base.entity.BaseEntity;
import com.wecloud.im.biz.enums.FriendStateEnum;
/**
* @author lixiaozhong
* 好友关系表
*/
@Data
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = true)
@ApiModel(value = "ImFriend对象")
public class ImFriend extends BaseEntity {
private static final long serialVersionUID = 1L;
@NotNull(message = "主键id不能为空")
@ApiModelProperty("主键id")
@TableId(value = "id", type = IdType.INPUT)
private Long id;
@ApiModelProperty("我的client-id")
private String clientId;
@ApiModelProperty("好友的client-id")
private String clientIdFriend;
@ApiModelProperty("申请者")
private String clientIdClaimer;
@ApiModelProperty("好友的昵称备注")
private String friendName;
@ApiModelProperty("好友拒绝原因")
private String rejectRemark;
@ApiModelProperty("好友请求说明")
private String requestRemark;
/**
* 好友关系状态
* @see FriendStateEnum
*/
@ApiModelProperty("好友关系状态")
private Integer state;
@ApiModelProperty("创建时间")
private Date createTime;
@ApiModelProperty("修改时间")
private Date updateTime;
}
package com.wecloud.im.biz.module.message.entity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.util.Date;
import javax.validation.constraints.NotNull;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.wecloud.can.core.base.entity.BaseEntity;
/**
* @author lixiaozhong
* 好友关系表
*/
@Data
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = true)
@ApiModel(value = "ImFriendRecommend好友推荐对象")
public class ImFriendRecommend extends BaseEntity {
private static final long serialVersionUID = 1L;
@NotNull(message = "主键id不能为空")
@ApiModelProperty("主键id")
@TableId(value = "id", type = IdType.INPUT)
private Long id;
@ApiModelProperty("我的client-id")
private String clientId;
@ApiModelProperty("好友的client-id")
private String clientIdFriend;
@ApiModelProperty("推荐来源")
private Integer source;
@ApiModelProperty("是否删除")
private Boolean delFlag;
@ApiModelProperty("创建时间")
private Date createTime;
@ApiModelProperty("修改时间")
private Date updateTime;
}
package com.wecloud.im.biz.module.message.entity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.util.Date;
import javax.validation.constraints.NotNull;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.wecloud.can.core.base.entity.BaseEntity;
/**
* 消息收件箱表
*
* @author wei
* @since 2021-05-06
*/
@Data
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = true)
@TableName("im_inbox")
@ApiModel(value = "ImInbox对象")
public class ImInbox extends BaseEntity {
private static final long serialVersionUID = 1L;
@NotNull(message = "收件id不能为空")
@ApiModelProperty("收件id")
@TableId(value = "id", type = IdType.INPUT)
private Long id;
@ApiModelProperty("创建时间")
private Date createTime;
@ApiModelProperty("修改时间")
private Date updateTime;
@ApiModelProperty("读取时间")
private Date readTime;
@ApiModelProperty("接收时间")
private Date receiverTime;
@NotNull(message = "应用appid不能为空")
@ApiModelProperty("应用appid")
private Long fkAppid;
@NotNull(message = "接收客户端id不能为空")
@ApiModelProperty("接收客户端id")
private Long receiver;
@NotNull(message = "消息id不能为空")
@ApiModelProperty("消息id")
private Long fkMsgId;
@ApiModelProperty("0未读; 1已读")
private Integer readMsgStatus;
@ApiModelProperty("0未接收; 1已接收")
private Integer receiverMsgStatus;
@NotNull(message = "会话id不能为空")
@ApiModelProperty("会话id")
private Long fkConversationId;
}
package com.wecloud.im.biz.module.message.entity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import javax.validation.constraints.NotNull;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.wecloud.can.core.base.entity.BaseEntity;
/**
* apns配置表
*
* @author wei
* @since 2021-09-18
*/
@Data
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = true)
@ApiModel(value = "ImIosApns对象")
public class ImIosApns extends BaseEntity {
private static final long serialVersionUID = 1L;
@NotNull(message = "id不能为空")
@ApiModelProperty("id")
@TableId(value = "id", type = IdType.INPUT)
private Long id;
@NotNull(message = "应用appid不能为空")
@ApiModelProperty("应用appid")
private Long fkAppId;
@ApiModelProperty("Base64(apns.p12)")
private String apnsFileValue;
@ApiModelProperty("环境,正式1,测试0")
private Integer env;
@ApiModelProperty("bundle_id")
private String bundleId;
@ApiModelProperty("证书密码")
private String pwd;
}
package com.wecloud.im.biz.module.message.entity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.util.Date;
import javax.validation.constraints.NotNull;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.wecloud.can.core.base.entity.BaseEntity;
/**
* 消息存储表
*
* @author wei
* @since 2021-04-29
*/
@Data
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = true)
@ApiModel(value = "ImMessage对象")
public class ImMessage extends BaseEntity {
private static final long serialVersionUID = 1L;
@NotNull(message = "消息id不能为空")
@ApiModelProperty("消息id")
@TableId(value = "id", type = IdType.INPUT)
private Long id;
@ApiModelProperty("创建时间")
private Date createTime;
@ApiModelProperty("撤回时间")
private Date withdrawTime;
@ApiModelProperty("修改时间")
private Date updateDate;
@NotNull(message = "应用appid不能为空")
@ApiModelProperty("应用appid")
private Long fkAppid;
@ApiModelProperty("发送者客户端id")
private Long sender;
@ApiModelProperty("接收人,多人用英文逗号分隔-群内指定人员可见场景")
private String receivers;
/**
* 数据库字段类型为JSON格式
* 因mysql关系型数据库非MongoDB文档类型数据库,第三方应用拓展的自定义参数名和值需使用json格式落库
*/
@ApiModelProperty("内容")
private String content;
@ApiModelProperty("0未撤回; 1已撤回")
private Boolean withdraw;
@ApiModelProperty("0非事件; 1为事件")
private Boolean event;
@ApiModelProperty("0非系统通知; 1为系统通知")
private Boolean systemFlag;
@ApiModelProperty("at他人,传入客户端id数组")
private String at;
@ApiModelProperty("1 AVIMMessageStatusSending(发送中)" +
"2 AVIMMessageStatusSent(发送成功)" +
"3 AVIMMessageStatusFailed(失败)")
private Integer sendStatus;
@ApiModelProperty("会话id")
private Long fkConversationId;
@ApiModelProperty("消息类型")
private Integer msgType;
@ApiModelProperty("是否删除 1-未删除 2-已删除")
private Integer isDelete;
}
package com.wecloud.im.biz.module.message.entity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.util.Date;
import javax.validation.constraints.NotNull;
import com.wecloud.can.core.base.entity.BaseEntity;
/**
* 消息在线推送
*
* @author wei
* @since 2021-04-29
*/
@Data
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = true)
@ApiModel(value = "ImMessageOnlineSend ")
public class ImMessageOnlineSend extends BaseEntity {
private static final long serialVersionUID = 1L;
/**
* 消息类型
* @see com.wecloud.im.server.enums.MsgTypeEnum
*/
@ApiModelProperty("消息类型")
private Integer type;
@NotNull(message = "消息id不能为空")
@ApiModelProperty("消息id")
private Long msgId;
@ApiModelProperty("创建时间")
private Date createTime;
@ApiModelProperty("撤回时间")
private Date withdrawTime;
@ApiModelProperty("发送者客户端id")
private String sender;
@ApiModelProperty("内容")
private Object content;
@ApiModelProperty("0未撤回; 1已撤回")
private Boolean withdraw;
@ApiModelProperty("0非事件; 1为事件")
private Boolean event;
@ApiModelProperty("0非系统通知; 1为系统通知")
private Boolean systemFlag;
@ApiModelProperty("at他人,传入客户端id数组")
private String at;
@ApiModelProperty("会话id")
private Long conversationId;
}
package com.wecloud.im.biz.module.message.entity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.util.Date;
import javax.validation.constraints.NotNull;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.wecloud.can.core.base.entity.BaseEntity;
import com.wecloud.im.biz.enums.MultiRtcRoomStateEnum;
/**
* @Author wenzhida
* @Date 2022/3/15 23:09
* @Description 多人音视频房间
*/
@Data
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = true)
@ApiModel(value = "多人音视频房间")
public class ImMultiRtcRoom extends BaseEntity {
private static final long serialVersionUID = -523597842194055670L;
@NotNull(message = "主键id不能为空")
@ApiModelProperty("主键id")
@TableId(value = "id", type = IdType.INPUT)
private Long id;
@ApiModelProperty("应用appid")
private Long fkAppid;
@ApiModelProperty("房间id")
private String roomId;
/**
* 多人音视频房间状态枚举
* @see MultiRtcRoomStateEnum
*/
@ApiModelProperty("房间状态,1:已创建,2:会议中,3:会议结束")
private Integer state;
@ApiModelProperty("创建时间")
private Date createTime;
@ApiModelProperty("修改时间")
private Date updateTime;
}
package com.wecloud.im.biz.module.message.entity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.util.Date;
import javax.validation.constraints.NotNull;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.wecloud.can.core.base.entity.BaseEntity;
import com.wecloud.im.biz.enums.MultiRtcMemberStateEnum;
/**
* @Author wenzhida
* @Date 2022/3/15 23:09
* @Description 多人音视频房间成员
*/
@Data
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = true)
@ApiModel(value = "多人音视频房间成员")
public class ImMultiRtcRoomMember extends BaseEntity {
private static final long serialVersionUID = -3806432271911087255L;
@NotNull(message = "主键id不能为空")
@ApiModelProperty("主键id")
@TableId(value = "id", type = IdType.INPUT)
private Long id;
@ApiModelProperty("房间id")
private String roomId;
@ApiModelProperty("im房间id")
private Long fkRtcRoomId;
@ApiModelProperty("client主键id")
private Long fkClientId;
@ApiModelProperty("客户端id")
private String clientId;
/**
* 多人音视频房间成员状态枚举
* @see MultiRtcMemberStateEnum
*/
@ApiModelProperty("房间成员状态,1:呼叫中,2:已接听,3:已拒绝,4:未接听,5:已断开")
private Integer state;
@ApiModelProperty("呼叫时间")
private Date callTime;
@ApiModelProperty("心跳时间")
private Date heartbeatTime;
@ApiModelProperty("创建时间")
private Date createTime;
@ApiModelProperty("修改时间")
private Date updateTime;
}
package com.wecloud.im.biz.module.message.entity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.util.Date;
import javax.validation.constraints.NotNull;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.wecloud.can.core.base.entity.BaseEntity;
import com.wecloud.im.biz.enums.RtcStateEnum;
/**
* @Author Future
* @Date 2022/5/22 23:40
* @Description 单人音视频记录表
*/
@Data
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = true)
@ApiModel(value = "单人音视频记录")
public class ImRtcRecord extends BaseEntity {
private static final long serialVersionUID = -523597842194055670L;
@NotNull(message = "主键id不能为空")
@ApiModelProperty("主键id")
@TableId(value = "id", type = IdType.INPUT)
private Long id;
@ApiModelProperty("应用appid")
private Long fkAppid;
@ApiModelProperty("频道id")
private Long channelId;
@ApiModelProperty("发起方clientId")
private String fromClientId;
@ApiModelProperty("接收方clientId")
private String toClientId;
@ApiModelProperty(value = "音视频类型: 1-video或2-voice")
private Integer callType;
/**
* 单人音视频状态枚举
* @see RtcStateEnum
*/
@ApiModelProperty("频道状态,1:音视频发起,2:音视频中,3:音视频结束")
private Integer state;
@ApiModelProperty("音视频开始时间")
private Date startTime;
@ApiModelProperty("音视频结束时间")
private Date endTime;
@ApiModelProperty("通话过程中离线次数统计 用于区分异常断线使用")
private Integer offlineTimes;
@ApiModelProperty("创建时间")
private Date createTime;
@ApiModelProperty("修改时间")
private Date updateTime;
}
package com.wecloud.im.biz.module.message.mapper;
import java.io.Serializable;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wecloud.im.biz.module.message.controller.param.ImApplicationPageParam;
import com.wecloud.im.biz.module.message.controller.param.ImApplicationQueryVo;
import com.wecloud.im.biz.module.message.entity.ImApplication;
/**
* 第三方应用表 Mapper 接口
*
* @author wei
* @since 2021-04-27
*/
@Repository
public interface ImApplicationMapper extends BaseMapper<ImApplication> {
/**
* 根据ID获取查询对象
*
* @param id
* @return
*/
ImApplicationQueryVo getImApplicationById(Serializable id);
/**
* 获取分页对象
*
* @param page
* @param imApplicationPageParam
* @return
*/
IPage<ImApplicationQueryVo> getImApplicationPageList(@Param("page") Page page, @Param("param") ImApplicationPageParam imApplicationPageParam);
}
package com.wecloud.im.biz.module.message.mapper;
import java.io.Serializable;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wecloud.im.biz.module.message.controller.param.ImClientBlacklistQueryVo;
import com.wecloud.im.biz.module.message.entity.ImClientBlacklist;
/**
* 黑名单 Mapper 接口
*
* @author wei
* @since 2021-06-17
*/
@Repository
public interface ImClientBlacklistMapper extends BaseMapper<ImClientBlacklist> {
/**
* 查询我的拉黑列表
* @param page
* @param clientId
* @return
*/
IPage<ImClientBlacklistQueryVo> getImClientBlacklistPageList(@Param("page") Page page, @Param("clientId") String clientId);
/**
* 根据ID获取查询对象
*
* @param id
* @return
*/
ImClientBlacklistQueryVo getImClientBlacklistById(Serializable id);
// /**
// * 获取分页对象
// *
// * @param page
// * @param imClientBlacklistPageParam
// * @return
// */
// IPage<ImClientBlacklistQueryVo> getImClientBlacklistPageList(@Param("page") Page page, @Param("param") ImClientBlacklistPageParam imClientBlacklistPageParam);
}
package com.wecloud.im.biz.module.message.mapper;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.wecloud.im.biz.module.message.entity.ImClientDevice;
/**
* @Author wenzhida
* @Date 2022/3/2 14:57
* @Description 客户端设备mapper
*/
@Repository
public interface ImClientDeviceMapper extends BaseMapper<ImClientDevice> {
/**
* 清除旧token
* @param appId
* @param deviceToken
* @return
*/
int removeOldToken(@Param("appId") Long appId, @Param("deviceToken") String deviceToken);
}
package com.wecloud.im.biz.module.message.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wecloud.im.biz.module.message.controller.param.ImClientPageParam;
import com.wecloud.im.biz.module.message.controller.param.ImClientQueryVo;
import com.wecloud.im.biz.module.message.controller.param.ImClientSimpleDto;
import com.wecloud.im.biz.module.message.controller.vo.GetInfoListVo;
import com.wecloud.im.biz.module.message.entity.ImClient;
/**
* 终端表 Mapper 接口
*
* @author wei
* @since 2021-04-27
*/
@Repository
public interface ImClientMapper extends BaseMapper<ImClient> {
/**
* 获取分页对象
*
* @param page
* @param imClientPageParam
* @return
*/
IPage<ImClientQueryVo> getImClientPageList(@Param("page") Page page, @Param("param") ImClientPageParam imClientPageParam);
List<GetInfoListVo> getInfoList(@Param("appId") Long appId, @Param("conversationId") Long conversationId, @Param("clientIds") List<String> clientIds);
List<ImClientSimpleDto> getSimpleClients(@Param("appId")Long appId, @Param("clientIds")List<String> clientIds);
List<ImClientSimpleDto> getSimpleClientsByIds(@Param("ids") List<Long> ids);
}
package com.wecloud.im.biz.module.message.mapper;
import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wecloud.im.biz.module.message.controller.param.ImConversationPageParam;
import com.wecloud.im.biz.module.message.controller.param.ImConversationQueryVo;
import com.wecloud.im.biz.module.message.controller.vo.ConversationVo;
import com.wecloud.im.biz.module.message.entity.ImConversation;
/**
* 会话表 Mapper 接口
*
* @author wei
* @since 2021-05-07
*/
@Repository
public interface ImConversationMapper extends BaseMapper<ImConversation> {
/**
* 根据ID获取查询对象
*
* @param id
* @return
*/
ImConversationQueryVo getImConversationById(Serializable id);
/**
* 获取分页对象
*
* @param page
* @param imConversationPageParam
* @return
*/
IPage<ImConversationQueryVo> getImConversationPageList(@Param("page") Page page, @Param("param") ImConversationPageParam imConversationPageParam);
/**
* 查询用户加入的所有会话 与每个会话的未读条数 成员
*
* @param currentClientId
* @return
*/
List<ConversationVo> getMyImConversationListAndMsgCount(@Param("currentClientId") Long currentClientId, @Param("clientId") String clientId, @Param("conversationId") Long conversationId);
/**
* 查询用户加入的所有会话
*
* @param clientId
* @return
*/
List<ImConversation> getMyImConversationList(@Param("clientId") Long clientId);
/**
* 查询已经存在的一对一会话信息
*
* @param clientId1
* @param clientId2
* @param isEncrypt 是否加密会话 1-是 0-否
* @return
*/
ImConversation getRepetitionConversationSingle(@Param("clientId1") Long clientId1, @Param("clientId2") Long clientId2, @Param("isEncrypt") Integer isEncrypt);
/**
* 判断重复会话中的Attributes是否一样
*
* @param clientId1
* @param clientId2
* @param attributes
* @return 大于等于1为有重复会话
*/
Long getRepetitionConversationAttributes(@Param("clientId1") Long clientId1, @Param("clientId2") Long clientId2, @Param("attributes") String attributes);
/**
* 增减成员数量
* @param appId fkAppid
* @param conversationId 会话id
* @param addCount 要增减的人数, 负数是减
* @return
*/
boolean addMemberCount(@Param("appId") Long appId, @Param("conversationId") Long conversationId, @Param("addCount") int addCount);
/**
* 升级成万人群
* @param appId fkAppId
* @param conversationId 会话id
* @return 成功则返回true
*/
boolean upgradeToThousandChat(@Param("appId") Long appId, @Param("conversationId") Long conversationId);
/**
* 获取发件人和收件人会话列表
* @Author luozh
* @Date 2022年05月06日 07:15:05
* @param senderClientId 发件人im client id
* @param receiverClientIds 收件人 im client ids
* @Return
*/
List<ImConversation> getConversationBySenderAndReceivers(@Param("senderImClientId") Long senderImClientId, @Param(
"receiverImClientIds") Collection<Long> receiverImClientIds);
}
package com.wecloud.im.biz.module.message.mapper;
import java.io.Serializable;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wecloud.im.biz.module.message.controller.param.ApiImConversationMembersQueryVo;
import com.wecloud.im.biz.module.message.controller.param.ImConversationMembersPageParam;
import com.wecloud.im.biz.module.message.controller.param.ImConversationMembersQueryVo;
import com.wecloud.im.biz.module.message.controller.param.ListConversationMembersParam;
import com.wecloud.im.biz.module.message.controller.vo.ConversationMemberVo;
import com.wecloud.im.biz.module.message.entity.ImConversationMembers;
/**
* 会话成员表 Mapper 接口
*
* @author wei
* @since 2021-05-07
*/
@Repository
public interface ImConversationMembersMapper extends BaseMapper<ImConversationMembers> {
/**
* 根据ID获取查询对象
*
* @param id
* @return
*/
ImConversationMembersQueryVo getImConversationMembersById(Serializable id);
List<ApiImConversationMembersQueryVo> getRestApiImConversationMembersList(@Param("conversationId") Long conversationId);
/**
* 获取群成员列表
* @param param 入参
* @return
*/
List<ConversationMemberVo> getImConversationMembersList(@Param("param") ListConversationMembersParam param);
/**
* 获取分页对象
*
* @param page
* @param imConversationMembersPageParam
* @return
*/
IPage<ImConversationMembersQueryVo> getImConversationMembersPageList(@Param("page") Page page, @Param("param") ImConversationMembersPageParam imConversationMembersPageParam);
List<Long> findThousandGroupsByClientId(@Param("clientId") Long clientId);
/**
* 批量设置群成员
* @param conversationId
* @param fkClientIds
*/
void setAdminsForConversation(@Param("conversationId") Long conversationId, @Param("fkClientIds") List<Long> fkClientIds, @Param("role") Integer role);
/**
* 根据会话id删除群成员
* @param conversationId
*/
void deleteByConversationId(@Param("conversationId") Long conversationId);
}
package com.wecloud.im.biz.module.message.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wecloud.im.biz.module.message.entity.ImFriend;
import com.wecloud.im.biz.module.message.param.ImFriendApplyDto;
import com.wecloud.im.biz.module.message.param.ImFriendBaseDto;
/**
* @Description 好友关系mapper
* @Author lixiaozhong
* @Date 2022/1/12 11:41 上午
*/
@Repository
public interface ImFriendMapper extends BaseMapper<ImFriend> {
IPage<ImFriendBaseDto> getImFriendPageList(@Param("page") Page<ImFriendBaseDto> page, @Param("clientId") String clientId);
/**
* 获取待验证的好友列表
* @param page
* @param clientId
* @return
*/
IPage<ImFriendApplyDto> getApplyFriendPageList(@Param("page") Page<ImFriendApplyDto> page, @Param("clientId") String clientId);
ImFriendApplyDto getFriendInfo(@Param("clientId") String clientId, @Param("friendClientId") String friendClientId);
/**
* 过滤得到真的好友,非好友的friendId将被它忽略
* @param clientId
* @param friendClientIds
* @return
*/
List<String> filterNegativeFriends(@Param("clientId") String clientId, @Param("friendClientIds") List<String> friendClientIds);
/**
* 批量删除好友
* @param clientId 删除人的clientId
* @param fkAppId
* @param friendClientIds 被删除人的clientId列表
*/
void batchDeleteFriend(@Param("clientId") String clientId, @Param("fkAppId") Long fkAppId, @Param("friendClientIds") List<String> friendClientIds);
}
package com.wecloud.im.biz.module.message.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wecloud.im.biz.module.message.entity.ImFriendRecommend;
import com.wecloud.im.biz.module.message.param.ImFriendRecommendDto;
/**
* @Description 好友推荐关系mapper
* @Author lixiaozhong
* @Date 2022/1/12 11:41 上午
*/
@Repository
public interface ImFriendRecommendMapper extends BaseMapper<ImFriendRecommend> {
IPage<ImFriendRecommendDto> getImFriendRecommendPageList(@Param("page") Page pageParam, @Param("clientId") Long clientId);
/**
* 批量删除好友推荐
* @param clientId
* @param fkAppId
* @param friendClientIds
*/
void batchDeleteRecommend(@Param("clientId") String clientId, @Param("fkAppId") Long fkAppId, @Param("friendClientIds") List<String> friendClientIds);
void batchCreateRecommend(@Param("list") List<ImFriendRecommend> list);
}
package com.wecloud.im.biz.module.message.mapper;
import java.io.Serializable;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wecloud.im.biz.module.message.controller.param.ImInboxPageParam;
import com.wecloud.im.biz.module.message.controller.param.ImInboxQueryVo;
import com.wecloud.im.biz.module.message.entity.ImInbox;
/**
* 消息收件箱表 Mapper 接口
*
* @author wei
* @since 2021-05-06
*/
@Repository
public interface ImInboxMapper extends BaseMapper<ImInbox> {
/**
* 根据ID获取查询对象
*
* @param id
* @return
*/
ImInboxQueryVo getImInboxById(Serializable id);
/**
* 获取分页对象
*
* @param page
* @param imInboxPageParam
* @return
*/
IPage<ImInboxQueryVo> getImInboxPageList(@Param("page") Page page, @Param("param") ImInboxPageParam imInboxPageParam);
Long updateImMsgReceivedByIds(@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.biz.module.message.mapper;
import java.io.Serializable;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wecloud.im.biz.module.message.controller.param.ImIosApnsPageParam;
import com.wecloud.im.biz.module.message.controller.param.ImIosApnsQueryVo;
import com.wecloud.im.biz.module.message.entity.ImIosApns;
/**
* apns配置表 Mapper 接口
*
* @author wei
* @since 2021-09-18
*/
@Repository
public interface ImIosApnsMapper extends BaseMapper<ImIosApns> {
/**
* 根据ID获取查询对象
*
* @param id
* @return
*/
ImIosApnsQueryVo getImIosApnsById(Serializable id);
/**
* 获取分页对象
*
* @param page
* @param imIosApnsPageParam
* @return
*/
IPage<ImIosApnsQueryVo> getImIosApnsPageList(@Param("page") Page page, @Param("param") ImIosApnsPageParam imIosApnsPageParam);
}
package com.wecloud.im.biz.module.message.mapper;
import java.io.Serializable;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wecloud.im.biz.module.message.controller.param.GetReadersParam;
import com.wecloud.im.biz.module.message.controller.param.ImHistoryMessagePageParam;
import com.wecloud.im.biz.module.message.controller.param.ImMessagePageParam;
import com.wecloud.im.biz.module.message.controller.param.ImMessageQueryVo;
import com.wecloud.im.biz.module.message.controller.vo.OfflineMsgDto;
import com.wecloud.im.biz.module.message.controller.vo.ReaderVo;
import com.wecloud.im.biz.module.message.entity.ImMessage;
/**
* 消息存储表 Mapper 接口
*
* @author wei
* @since 2021-04-29
*/
@Repository
public interface ImMessageMapper extends BaseMapper<ImMessage> {
/**
* 根据ID获取查询对象
*
* @param id
* @return
*/
ImMessageQueryVo getImMessageById(Serializable id);
/**
* 获取分页对象
*
* @param page
* @param imMessagePageParam
* @return
*/
IPage<ImMessageQueryVo> getImMessagePageList(@Param("page") Page page, @Param("param") ImMessagePageParam imMessagePageParam);
/**
* 查询某个会话历史消息分页列表
*
* @param page
* @param imHistoryMessagePageParam
* @return
*/
IPage<OfflineMsgDto> getHistoryMsgConversationId(@Param("page") Page page, @Param("param") ImHistoryMessagePageParam imHistoryMessagePageParam);
IPage<OfflineMsgDto> getHistoryMsgConversationIdNew(@Param("page") Page page, @Param("param") ImHistoryMessagePageParam imHistoryMessagePageParam);
/**
* 根据客户端id与会话id 查询离线消息
*
* @param clientId
* @param conversationId
* @return
*/
List<OfflineMsgDto> getOfflineListByClientAndConversation(@Param("clientId") Long clientId, @Param("conversationId") Long conversationId);
/**
* 查询会话接收的的最后一条消息
*
* @param clientId
* @param conversationId
* @return
*/
OfflineMsgDto getReceivedLastMsgByConversationId(@Param("clientId") Long clientId, @Param("conversationId") Long conversationId);
/**
* 查询会话的最后一条消息
*
* @param conversationId
* @return
*/
OfflineMsgDto getLastMsgByConversationId(@Param("conversationId") Long conversationId, @Param("currentFkClientId") Long currentFkClientId);
/**
* 获取一条消息已读人员和未读人员
* @param currentClientId
* @param param
* @return
*/
List<ReaderVo> getReaders(@Param("currentClientId") Long currentClientId, @Param("param") GetReadersParam param);
}
package com.wecloud.im.biz.module.message.mapper;
import org.springframework.stereotype.Repository;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.wecloud.im.biz.module.message.entity.ImMultiRtcRoom;
/**
* @Author wenzhida
* @Date 2022/3/16 9:19
* @Description 多人音视频房间mapper
*/
@Repository
public interface ImMultiRtcRoomMapper extends BaseMapper<ImMultiRtcRoom> {
}
package com.wecloud.im.biz.module.message.mapper;
import org.springframework.stereotype.Repository;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.wecloud.im.biz.module.message.entity.ImMultiRtcRoomMember;
/**
* @Author wenzhida
* @Date 2022/3/16 9:19
* @Description 多人音视频房间mapper
*/
@Repository
public interface ImMultiRtcRoomMemberMapper extends BaseMapper<ImMultiRtcRoomMember> {
}
package com.wecloud.im.biz.module.message.mapper;
import org.springframework.stereotype.Repository;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.wecloud.im.biz.module.message.entity.ImRtcRecord;
/**
* @Author Future
* @Date 2022/5/22 23:49
* @Description 单人音视频记录mapper
*/
@Repository
public interface ImRtcRecordMapper extends BaseMapper<ImRtcRecord> {
}
package com.wecloud.im.biz.module.message.param;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* @Description TODO
* @Author lixiaozhong
* @Date 2022/1/14 11:56 上午
*/
@Data
public class FriendApplyEventDto extends FriendBaseEventDto {
@ApiModelProperty("好友请求说明")
private String requestRemark;
}
package com.wecloud.im.biz.module.message.param;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* @Description TODO
* @Author lixiaozhong
* @Date 2022/1/14 11:56 上午
*/
@Data
public class FriendApproveEventDto extends FriendBaseEventDto {
@ApiModelProperty("是否同意接受好友,true同意,false拒绝")
private Boolean agree;
@ApiModelProperty("好友拒绝原因")
private String rejectRemark;
}
package com.wecloud.im.biz.module.message.param;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
import com.wecloud.im.biz.enums.EventResponseSubCmdEnum;
/**
* @Description TODO
* @Author lixiaozhong
* @Date 2022/1/14 11:56 上午
*/
@Data
public class FriendBaseEventDto implements Serializable {
/**
* 参考 {@link EventResponseSubCmdEnum EventResponseSubCmdEnum}
*/
@ApiModelProperty("响应命令")
private Integer subCmd;
@ApiModelProperty("申请人的client-id")
private String claimerClientId;
@ApiModelProperty("好友的client-id")
private String friendClientId;
}
package com.wecloud.im.biz.module.message.controller.param.group; package com.wecloud.im.biz.module.message.param;
import lombok.Data; import lombok.Data;
import javax.validation.constraints.NotBlank;
/** /**
* 离开(踢出)群 * 好友备注请求
* @Author luozh * @Author luozh
* @Date 2022年05月10日 09:37 * @Date 2022年05月16日 11:09
* @Version 1.0 * @Version 1.0
*/ */
@Data @Data
public class LeaveGroupParam { public class FriendRemarkParam {
/** /**
* 操作人用户id * 用户id
*/ */
@NotBlank(message = "operatorUserId 不能为空") private String userId;
private String operatorUserId;
/** /**
* 用户Id * 朋友用户id
*/ */
@NotBlank(message = "userIds 不能为空") private String friendUserId;
private String userIds;
/** /**
* 群组id * 备注
*/ */
@NotBlank(message = "groupId 不能为空") private String friendRemark;
private String groupId;
} }
package com.wecloud.im.biz.module.message.param;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
/**
* @Author wenzhida
* @Date 2022/2/7 16:30
* @Description 批量创建好友推荐入参
*/
@Data
public class ImCreateRecommendParam implements Serializable {
private static final long serialVersionUID = 5228604783548712598L;
@ApiModelProperty("推荐好友列表")
private List<ImFriendRecommendDto> recommendFriends;
}
package com.wecloud.im.biz.module.message.param;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
/**
* @Author wenzhida
* @Date 2022/2/7 16:30
* @Description 删除好友入参
*/
@Data
public class ImDeleteFriendParam implements Serializable {
private static final long serialVersionUID = 5228604783548712598L;
@ApiModelProperty("好友的client-id")
private List<String> friendClientIds;
}
package com.wecloud.im.biz.module.message.param;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
/**
* @Author wenzhida
* @Date 2022/2/7 16:30
* @Description 批量删除好友推荐入参
*/
@Data
public class ImDeleteRecommendParam implements Serializable {
private static final long serialVersionUID = -2325444195601100874L;
@ApiModelProperty("推荐好友列表")
private List<String> friendClientIds;
}
package com.wecloud.im.biz.module.message.param;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* @Description 好友信息
* @Author lixiaozhong
* @Date 2022/1/12 1:59 下午
*/
@Data
public class ImFriendApplyDto extends ImFriendBaseDto {
private static final long serialVersionUID = 1L;
@ApiModelProperty("好友申请者")
private String claimerClientId;
@ApiModelProperty("好友拒绝原因")
private String rejectRemark;
@ApiModelProperty("好友请求说明")
private String requestRemark;
}
package com.wecloud.im.biz.module.message.param;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* @Description 申请好友入参
* @Author lixiaozhong
* @Date 2022/1/13 4:24 下午
*/
@Data
public class ImFriendApplyParam extends ImFriendBaseParam {
private static final long serialVersionUID = 1L;
@ApiModelProperty("会话id,群成员添加好友时传参")
private Long conversationId;
@ApiModelProperty("备注好友名称")
private String friendName;
@ApiModelProperty("请求备注")
private String requestRemark;
}
package com.wecloud.im.biz.module.message.param;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* @Description TODO
* @Author lixiaozhong
* @Date 2022/1/13 4:24 下午
*/
@Data
public class ImFriendApproveParam extends ImFriendBaseParam {
private static final long serialVersionUID = 1L;
@ApiModelProperty("是否同意接受好友,true同意,false拒绝")
private Boolean agree;
@ApiModelProperty("拒绝理由,如果是同意就不用填啦")
private String rejectRemark;
}
package com.wecloud.im.biz.module.message.param;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
/**
* @Description 好友信息
* @Author lixiaozhong
* @Date 2022/1/12 1:59 下午
*/
@Data
public class ImFriendBaseDto implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty("好友的client-id")
private String friendClientId;
@ApiModelProperty("好友的昵称备注")
private String friendName;
@ApiModelProperty("好友关系状态,1:待确定,2:已确认,3:已拒绝,4:已删除")
private Integer state;
}
package com.wecloud.im.biz.module.message.param;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
/**
* @Description 好友相关base入参
* @Author lixiaozhong
* @Date 2022/1/13 4:24 下午
*/
@Data
public class ImFriendBaseParam implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty("clientId")
private String clientId;
@ApiModelProperty("好友的client-id")
private String friendClientId;
}
package com.wecloud.im.biz.module.message.controller.param.add; package com.wecloud.im.biz.module.message.param;
import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors; import lombok.experimental.Accessors;
import com.wecloud.can.core.base.entity.BaseEntity; import com.wecloud.can.datasource.mybatisplus.pagination.BasePageOrderParam;
import com.wecloud.im.server.model.request.PushVO;
/** /**
* 撤回消息 * @Description 好友分页
* * @Author lixiaozhong
* @author wei * @Date 2022/1/12 2:24 下午
*/ */
@Data @Data
@Accessors(chain = true) @Accessors(chain = true)
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
@ApiModel(value = "ImMsgRecall") @ApiModel(value = "好友分页")
public class ImMsgRecall extends BaseEntity { public class ImFriendPageParam extends BasePageOrderParam {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@ApiModelProperty("消息id")
private Long msgId;
@ApiModelProperty("自定义推送字段")
private PushVO push;
} }
package com.wecloud.im.biz.module.message.param;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
/**
* @Description 好友信息
* @Author lixiaozhong
* @Date 2022/1/12 1:59 下午
*/
@Data
public class ImFriendRecommendDto implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty("好友的clientId")
private String friendClientId;
@ApiModelProperty("好友推荐来源,1:通讯录,2:二度人脉,3:附近的人,4:同类标签")
private Integer source;
@ApiModelProperty("是否删除")
private Boolean delFlag;
}
package com.wecloud.im.biz.module.message.param;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
*
* @Author luozh
* @Date 2022年05月16日 10:34
* @Version 1.0
*/
@Data
public class UnfriendParam {
/**
* 用户id
*/
@ApiModelProperty("用户id")
private String userId;
/**
* 朋友id 多个用,隔开
*/
@ApiModelProperty("朋友id 多个用,隔开")
private String friendUserIds;
}
package com.wecloud.im.biz.module.message.service;
import com.wecloud.im.biz.module.message.entity.ImApplication;
import com.wecloud.im.biz.module.message.entity.ImClient;
/**
* 请求上下文服务
* @Author luozh
* @Date 2022年04月02日 14:51
* @Version 1.0
*/
public interface ContextService {
/**
* 获取当前或指定clientId的ImClient 存在返回 不存在则抛出异常
* @Author luozh
* @Date 2022年04月02日 02:52:09
* @param request Ws请求
* @Return
*/
ImClient getImClientIfNotNullOrThrow();
/**
* 获取当前或指定appId的ImApplication 存在返回 不存在则抛出异常
* @Author luozh
* @Date 2022年04月02日 02:54:21
* @param appId 应用id
* @Return
*/
ImApplication getImApplicationIfNotNullOrThrow(Long appId);
}
package com.wecloud.im.biz.module.message.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.wecloud.can.core.enums.ApiCode;
import com.wecloud.can.core.util.ApiResult;
import com.wecloud.im.biz.core.rocketmq.component.MqSender;
import com.wecloud.im.biz.enums.EventResponseSubCmdEnum;
import com.wecloud.im.biz.module.message.entity.ImApplication;
import com.wecloud.im.biz.module.message.entity.ImClient;
import com.wecloud.im.biz.module.message.param.FriendApplyEventDto;
import com.wecloud.im.biz.module.message.param.FriendApproveEventDto;
import com.wecloud.im.server.enums.WsResponseCmdEnum;
import com.wecloud.im.server.model.WsResponse;
import com.wecloud.im.server.model.request.PushVO;
import com.wecloud.im.server.sender.ChannelSender;
import com.wecloud.pushserver.client.model.constant.MqConstant;
import com.wecloud.pushserver.client.model.dto.PushDTO;
/**
* @Description TODO
* @Author lixiaozhong
* @Date 2022/1/13 5:35 下午
*/
@Component
public class FriendEventSender {
@Autowired
private ChannelSender channelSender;
@Autowired
private ImApplicationService imApplicationService;
@Autowired
private MqSender mqSender;
private final static String FRIEND_APPLY_TITLE = "好友申请";
private final static String FRIEND_APPLY_TITLE_SUB = "您有好友申请待验证";
private final static String FRIEND_APPROVE_TITLE = "好友验证结果";
private final static String FRIEND_APPROVE_TITLE_AGREE = "您的好友同意了您的好友申请";
private final static String FRIEND_APPROVE_TITLE_REJECT = "您的好友拒绝了您的好友申请";
public void sendFriendApplyEventMsg(ImClient claimerClient, ImClient receiveClient, String requestRemark) {
FriendApplyEventDto applyDto = new FriendApplyEventDto();
applyDto.setSubCmd(EventResponseSubCmdEnum.FRIEND_APPLY.getCode());
applyDto.setRequestRemark(requestRemark);
applyDto.setClaimerClientId(claimerClient.getClientId());
applyDto.setFriendClientId(receiveClient.getClientId());
// 向接收方推送
WsResponse<FriendApplyEventDto> responseModel = new WsResponse<>();
responseModel.setCmd(WsResponseCmdEnum.NOTICE_EVENT_MSG.getCmdCode());
ApiResult<Boolean> result = ApiResult.result(ApiCode.SUCCESS);
responseModel.setCode(result.getCode());
responseModel.setMsg(result.getMessage());
responseModel.setData(applyDto);
responseModel.setReqId(null);
channelSender.sendMsg(responseModel, receiveClient.getId());
ImApplication app = imApplicationService.getCacheById(receiveClient.getFkAppid());
PushVO pushVO = new PushVO();
pushVO.setTitle(FRIEND_APPLY_TITLE);
pushVO.setSubTitle(FRIEND_APPLY_TITLE_SUB);
PushDTO pushDTO = mqSender.buildPushDto(pushVO, receiveClient, app);
if (pushDTO != null) {
mqSender.orderSend(MqConstant.Topic.IM_ORDER_MSG_TOPIC, MqConstant.Tag.IM_ORDER_MSG_TAG, pushDTO);
}
}
public void sendFriendApproveEventMsg(ImClient claimerClient, ImClient receiveClient, boolean isAgree, String rejectRemark) {
FriendApproveEventDto approveDto = new FriendApproveEventDto();
approveDto.setSubCmd(EventResponseSubCmdEnum.FRIEND_APPROVE.getCode());
approveDto.setAgree(isAgree);
approveDto.setRejectRemark(rejectRemark);
approveDto.setClaimerClientId(claimerClient.getClientId());
approveDto.setFriendClientId(receiveClient.getClientId());
// 向接收方推送
WsResponse<FriendApproveEventDto> responseModel = new WsResponse<>();
responseModel.setCmd(WsResponseCmdEnum.NOTICE_EVENT_MSG.getCmdCode());
ApiResult<Boolean> result = ApiResult.result(ApiCode.SUCCESS);
responseModel.setCode(result.getCode());
responseModel.setMsg(result.getMessage());
responseModel.setData(approveDto);
responseModel.setReqId(null);
channelSender.sendMsg(responseModel, receiveClient.getId());
ImApplication app = imApplicationService.getCacheById(receiveClient.getFkAppid());
PushVO pushVO = new PushVO();
pushVO.setTitle(FRIEND_APPROVE_TITLE);
pushVO.setSubTitle(isAgree ? FRIEND_APPROVE_TITLE_AGREE : FRIEND_APPROVE_TITLE_REJECT);
PushDTO pushDTO = mqSender.buildPushDto(pushVO, receiveClient, app);
if (pushDTO != null) {
mqSender.orderSend(MqConstant.Topic.IM_ORDER_MSG_TOPIC, MqConstant.Tag.IM_ORDER_MSG_TAG, pushDTO);
}
}
}
package com.wecloud.im.biz.module.message.service;
import com.wecloud.can.datasource.mybatisplus.pagination.Paging;
import com.wecloud.can.datasource.mybatisplus.service.BaseService;
import com.wecloud.im.biz.module.message.controller.param.ImApplicationPageParam;
import com.wecloud.im.biz.module.message.controller.param.ImApplicationQueryVo;
import com.wecloud.im.biz.module.message.entity.ImApplication;
/**
* 第三方应用表 服务类
*
* @author wei
* @since 2021-04-27
*/
public interface ImApplicationService extends BaseService<ImApplication> {
/**
* 根据id查询应用数据 redis缓存
*
* @param id
* @return
*/
ImApplication getCacheById(Long id);
/**
* 删除缓存
*
* @param id
*/
void deleteCacheById(Long id);
/**
* 删除缓存
*
* @param appKey
*/
void deleteCacheByAppKey(String appKey);
/**
* 根据appKey查询application
*
* @param appKey
* @return
*/
ImApplication getCacheAppByAppKey(String appKey);
/**
* 保存
*
* @param imApplication
* @return
* @throws Exception
*/
boolean saveImApplication(ImApplication imApplication) throws Exception;
// /**
// * 修改
// *
// * @param imApplication
// * @return
// * @throws Exception
// */
// boolean updateImApplication(ImApplication imApplication) throws Exception;
//
// /**
// * 删除
// *
// * @param id
// * @return
// * @throws Exception
// */
// boolean deleteImApplication(Long id) throws Exception;
/**
* 根据ID获取查询对象
*
* @param id
* @return
* @throws Exception
*/
ImApplicationQueryVo getImApplicationById(Long id) throws Exception;
/**
* 获取分页对象
*
* @param imApplicationPageParam
* @return
* @throws Exception
*/
Paging<ImApplicationQueryVo> getImApplicationPageList(ImApplicationPageParam imApplicationPageParam) throws Exception;
}
package com.wecloud.im.biz.module.message.service;
import com.wecloud.im.biz.module.message.entity.ImMessage;
/**
* sdk 回调服务
* @Author luozh
* @Date 2022年04月22日 09:08
* @Version 1.0
*/
public interface ImCallbackService {
/**
* 全量消息路由
* @Author luozh
* @Date 2022年04月22日 09:10:15
* @param
* @Return 路由结果
*/
Boolean fullMessageRouting(Long applicationId, ImMessage message);
/**
* 用户在线状态变化
* @Author luozh
* @Date 2022年04月22日 09:11:28
* @param
* @Return
*/
Boolean clientOnlineStatusChange(Long applicationId, Long clientId, Integer status,
Integer deviceType, Long time, String clientIp);
}
package com.wecloud.im.biz.module.message.service;
import com.wecloud.can.datasource.mybatisplus.pagination.Paging;
import com.wecloud.can.datasource.mybatisplus.service.BaseService;
import com.wecloud.im.biz.module.message.controller.param.ImClientBlacklistPageParam;
import com.wecloud.im.biz.module.message.controller.param.ImClientBlacklistQueryVo;
import com.wecloud.im.biz.module.message.controller.param.add.ImClientBlacklistUpdate;
import com.wecloud.im.biz.module.message.entity.ImClientBlacklist;
/**
* 黑名单 服务类
*
* @author wei
* @since 2021-06-17
*/
public interface ImClientBlacklistService extends BaseService<ImClientBlacklist> {
/**
* 当前客户端是否被拉黑
*
* @param currentClientId 当前客户端
* @param toClientId 对方客户端
* @return
*/
boolean isBeBlack(String currentClientId, String toClientId);
/**
* 拉入黑名单
*
* @param imClientBlacklistUpdate
* @return
* @throws Exception
*/
Boolean addImClientBlacklist(ImClientBlacklistUpdate imClientBlacklistUpdate);
/**
* 移出黑名单
*
* @param imClientBlacklistUpdate
* @return
* @throws Exception
*/
Boolean removeImClientBlacklist(ImClientBlacklistUpdate imClientBlacklistUpdate);
/**
* 获取分页对象
*
* @return
* @throws Exception
*/
Paging<ImClientBlacklistQueryVo> getImClientBlacklistPageList(ImClientBlacklistPageParam imClientBlacklistPageParam);
/**
* 获取分页对象
*
* @return
* @throws Exception
*/
Paging<ImClientBlacklistQueryVo> getImClientBlacklistPageListSdk(ImClientBlacklistPageParam imClientBlacklistPageParam);
}
package com.wecloud.im.biz.module.message.service;
import com.wecloud.can.datasource.mybatisplus.service.BaseService;
import com.wecloud.im.biz.module.message.entity.ImClientDevice;
/**
* @Author wenzhida
* @Date 2022/3/2 14:58
* @Description 客户端设备服务接口
*/
public interface ImClientDeviceService extends BaseService<ImClientDevice> {
/**
* 清除旧token
* @param appId
* @param deviceToken
* @return
*/
int removeOldToken(Long appId, String deviceToken);
/**
* 根据
* @Author luozh
* @Date 2022年04月18日 11:08:30
* @param appId
* @param fkClientId
* @param deviceType
* @Return
*/
ImClientDevice getOneByAppIdAndClientIdAndType(Long appId, Long fkClientId, Integer deviceType);
}
package com.wecloud.im.biz.module.message.service;
import com.alibaba.nacos.api.exception.NacosException;
import com.wecloud.can.core.util.ApiResult;
import com.wecloud.im.biz.module.message.controller.param.ImTokenVerify;
import com.wecloud.im.biz.module.message.controller.vo.TokenVo;
/**
* 终端表 服务类
*
* @author wei
* @since 2021-04-27
*/
public interface ImClientLoginService {
/**
* 根据客户方生成签名字符串 验证通过则下发token
*
* @param imTokenVerify
* @return
*/
ApiResult<TokenVo> verifySign(ImTokenVerify imTokenVerify) throws NacosException;
/**
* 获取client Token
* @Author luozh
* @Date 2022年04月18日 10:56:24
* @param
* @Return
*/
ApiResult<TokenVo> getToken(String clientId, Integer deviceType) throws NacosException;
}
package com.wecloud.im.biz.module.message.service;
import java.util.List;
import java.util.Map;
import com.wecloud.can.datasource.mybatisplus.pagination.Paging;
import com.wecloud.can.datasource.mybatisplus.service.BaseService;
import com.wecloud.im.biz.module.message.controller.param.ClientInfoParam;
import com.wecloud.im.biz.module.message.controller.param.ClientRelationVo;
import com.wecloud.im.biz.module.message.controller.param.GetClientInfoParam;
import com.wecloud.im.biz.module.message.controller.param.GetClientRelationParam;
import com.wecloud.im.biz.module.message.controller.param.ImClientPageParam;
import com.wecloud.im.biz.module.message.controller.param.ImClientQueryVo;
import com.wecloud.im.biz.module.message.controller.param.ImClientSimpleDto;
import com.wecloud.im.biz.module.message.controller.param.LogoutParam;
import com.wecloud.im.biz.module.message.controller.param.RegisterClientParam;
import com.wecloud.im.biz.module.message.controller.param.add.ClientDeviceUpdateParam;
import com.wecloud.im.biz.module.message.controller.param.add.ImClientHeadPortraitAdd;
import com.wecloud.im.biz.module.message.controller.param.add.ImClientHeadPortraitAndNicknameUpdate;
import com.wecloud.im.biz.module.message.controller.param.add.ImClientNicknameAdd;
import com.wecloud.im.biz.module.message.controller.param.add.ImClientNicknameUpdate;
import com.wecloud.im.biz.module.message.controller.vo.ClientInfoVo;
import com.wecloud.im.biz.module.message.controller.vo.GetInfoListVo;
import com.wecloud.im.biz.module.message.controller.vo.MyInfoVo;
import com.wecloud.im.biz.module.message.entity.ImClient;
/**
* 终端表 服务类
*
* @author wei
* @since 2021-04-27
*/
public interface ImClientService extends BaseService<ImClient> {
/**
* 查询我的信息
* @return
*/
MyInfoVo getMyInfo();
/**
* 更新头像
* @param imClientHeadPortraitAdd
* @return
*/
boolean updateHeadPortrait(ImClientHeadPortraitAdd imClientHeadPortraitAdd);
/**
* 修改昵称
* @param imClientNicknameUpdate
* @return
*/
boolean updateNickname(ImClientNicknameUpdate imClientNicknameUpdate);
/**
*
* @Author luozh
* @Date 2022年04月18日 07:21:27
* @param imClientHeadPortraitAndNicknameUpdate
* @Return
*/
boolean updateHeadAndNickname(ImClientHeadPortraitAndNicknameUpdate imClientHeadPortraitAndNicknameUpdate);
/**
* 根据ids获取Client的头像昵称
*
* @param getClientInfoParam
* @return
* @throws Exception
*/
List<GetInfoListVo> getInfoList(GetClientInfoParam getClientInfoParam) throws Exception;
/**
* 获取群里成员信息
* @param param
* @return
*/
ClientInfoVo getClientInfo(ClientInfoParam param);
boolean updateNickname(ImClientNicknameAdd imClientNicknameAdd) throws Exception;
/**
* 保存
*
* @param imClient
* @return
* @throws Exception
*/
boolean saveImClient(ImClient imClient) throws Exception;
/**
* 添加或修改推送设备信息
*
* @param imClientDevice
* @return
*/
boolean updateDeviceInfo(ClientDeviceUpdateParam imClientDevice);
/**
* 登出操作
* @param param
* @return
*/
boolean logout(LogoutParam param);
/**
* 修改
*
* @param imClient
* @return
* @throws Exception
*/
boolean updateImClient( ImClient imClient) throws Exception;
/**
* 删除
*
* @param id
* @return
* @throws Exception
*/
boolean deleteImClient(Long id);
/**
* 获取分页对象
*
* @param imClientPageParam
* @return
* @throws Exception
*/
Paging<ImClientQueryVo> getImClientPageList(ImClientPageParam imClientPageParam) throws Exception;
/**
* 获取当前请求的client对象
*
* @return
*/
ImClient getCurrentClient();
ImClient getCacheImClient(Long applicationId, String clientId);
void deleteCacheImClient(Long applicationId, String clientId);
/**
* 根据ID获取client对象,有缓存
*
* @param id
* @return
* @throws Exception
*/
ImClient getCacheImClient(Long id);
/**
* 获取client的简单对象,减少开销
* @param applicationId
* @param clientIds
* @return
*/
List<ImClientSimpleDto> getSimpleClients(Long applicationId, List<String> clientIds);
List<ImClientSimpleDto> getSimpleClients(List<Long> ids);
/**
* 注册客户端
* @Author luozh
* @Date 2022年04月13日 05:20:58
* @param param
* @Return
*/
Long registerClient(RegisterClientParam param);
/**
* 获取客户端关系
* @Author luozh
* @Date 2022年05月12日 07:04:04
* @param param
* @Return
*/
ClientRelationVo getClientRelation(GetClientRelationParam param);
Map<String, String> getUserAttributes(String userId);
Boolean modifyUserAttributes(String userId, Map<String, Object> attributes);
}
package com.wecloud.im.biz.module.message.service;
import java.util.List;
import org.springframework.web.bind.annotation.RequestBody;
import com.wecloud.can.core.util.ApiResult;
import com.wecloud.can.datasource.mybatisplus.pagination.Paging;
import com.wecloud.can.datasource.mybatisplus.service.BaseService;
import com.wecloud.im.biz.module.message.controller.param.ApiImConversationMembersPageParam;
import com.wecloud.im.biz.module.message.controller.param.ApiImConversationMembersQueryVo;
import com.wecloud.im.biz.module.message.controller.param.ChatSettingParam;
import com.wecloud.im.biz.module.message.controller.param.ImConvMemeClientRemarkNameParam;
import com.wecloud.im.biz.module.message.controller.param.ImConversationMembersPageParam;
import com.wecloud.im.biz.module.message.controller.param.ImConversationMembersQueryVo;
import com.wecloud.im.biz.module.message.controller.param.ListConversationMembersParam;
import com.wecloud.im.biz.module.message.controller.param.SetAdminsParam;
import com.wecloud.im.biz.module.message.controller.param.add.ImConversationMemAttrUpdate;
import com.wecloud.im.biz.module.message.controller.vo.ConversationMemberVo;
import com.wecloud.im.biz.module.message.entity.ImApplication;
import com.wecloud.im.biz.module.message.entity.ImConversationMembers;
import com.wecloud.im.biz.module.message.param.ImFriendApplyParam;
/**
* 会话成员表 服务类
*
* @author wei
* @since 2021-05-07
*/
public interface ImConversationMembersService extends BaseService<ImConversationMembers> {
/**
* 服务端api-会话成员表分页列表
*
* @param apiImConversationMembersPageParam
* @param imApplication
* @return
*/
ApiResult<List<ApiImConversationMembersQueryVo>> getRestApiImConversationMembersList(ApiImConversationMembersPageParam apiImConversationMembersPageParam, ImApplication imApplication);
/**
* 添加或修改会话成员备注
* @param param
* @return
*/
void saveOrUpdateClientRemarkName(ImConvMemeClientRemarkNameParam param);
/**
* 会话成员表分页列表
*
* @param param
* @return
* @throws Exception
*/
List<ConversationMemberVo> getImConversationMembersList(ListConversationMembersParam param);
Boolean saveOrUpdateAttr(ImConversationMemAttrUpdate imConversationMemAttrUpdate);
/**
* 保存
*
* @param imConversationMembers
* @return
* @throws Exception
*/
boolean saveImConversationMembers(ImConversationMembers imConversationMembers) throws Exception;
/**
* 修改
*
* @param imConversationMembers
* @return
* @throws Exception
*/
boolean updateImConversationMembers(ImConversationMembers imConversationMembers) throws Exception;
/**
* 删除
*
* @param id
* @return
* @throws Exception
*/
boolean deleteImConversationMembers(Long id);
/**
* 根据会话id做删除
* @param conversationId 会话id
*/
void deleteByConversationId(Long conversationId);
/**
* 根据ID获取查询对象
*
* @param id
* @return
* @throws Exception
*/
ImConversationMembersQueryVo getImConversationMembersById(Long id) throws Exception;
/**
* 获取分页对象
*
* @param imConversationMembersPageParam
* @return
* @throws Exception
*/
Paging<ImConversationMembersQueryVo> getImConversationMembersPageList(ImConversationMembersPageParam imConversationMembersPageParam) throws Exception;
/**
* 根据用户id 获取千人群id列表
* @param clientId 用户id
* @return
*/
List<Long> findThousandGroupsByClientId(Long clientId);
/**
* 批量设置群成员
* @param param
* @param fkClientIds
*/
void setAdminsForConversation(SetAdminsParam param, List<Long> fkClientIds);
/**
* 置顶
* @Author luozh
* @Date 2022年04月25日 06:24:43
* @param
* @Return
*/
Boolean chatSetting(ChatSettingParam param);
/**
* 群成员添加好友
* @Author luozh
* @Date 2022年04月28日 11:48:42
* @param param
* @Return
*/
Boolean addUser(@RequestBody ImFriendApplyParam param);
}
package com.wecloud.im.biz.module.message.service;
import java.util.List;
import com.wecloud.im.biz.module.message.controller.param.group.MutedMembersParam;
/**
* 群服务
* @Author luozh
* @Date 2022年05月10日 15:17
* @Version 1.0
*/
public interface ImGroupService {
/**
* 创建群组
* @Author luozh
* @Date 2022年05月10日 03:22:13
* @param creatorClientId
* @param groupName
* @param memberIds
* @Return
*/
Long createGroup(String creatorClientId, String groupName, List<String> memberIds);
/**
* 解散群组
* @Author luozh
* @Date 2022年05月10日 03:22:26
* @param userId
* @param groupId
* @Return
*/
Boolean dismissGroup(String userId, String groupId);
/**
* 加入群组
* @Author luozh
* @Date 2022年05月10日 03:22:35
* @param groupId
* @param memberClientIds
* @Return
*/
Integer joinGroup(String inviterUserId, String groupId, List<String> memberClientIds);
/**
* 离开群组
* @Author luozh
* @Date 2022年05月10日 03:22:44
* @param groupId
* @param memberClientIds
* @Return
*/
Integer leaveGroup(String operatorUserId, String groupId, List<String> memberClientIds);
/**
* 获取群成员列表
* @Author luozh
* @Date 2022年05月10日 03:23:09
* @param groupId
* @Return
*/
List<String> listGroupMembers(String groupId);
/**
* 禁言群成员
* @Author luozh
* @Date 2022年05月16日 07:43:41
* @param param
* @Return
*/
Boolean mutedMembers(MutedMembersParam param);
/**
* 转移群成员
* @Author luozh
* @Date 2022年05月17日 04:20:56
* @param groupId
* @param newGroupOwnerUserId
* @Return
*/
Boolean groupOwnerTransfer(String groupId, String newGroupOwnerUserId);
/**
* 添加管理员
* @Author luozh
* @Date 2022年05月17日 06:27:04
* @param groupId
* @param adminUserIds
* @Return
*/
Boolean addGroupAdmin(String groupId, String adminUserIds);
/**
* 移除管理员
* @Author luozh
* @Date 2022年05月17日 06:27:07
* @param groupId
* @param adminUserIds
* @Return
*/
Boolean removeGroupAdmin(String groupId, String adminUserIds);
}
package com.wecloud.im.biz.module.message.service;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.wecloud.can.datasource.mybatisplus.service.BaseService;
import com.wecloud.im.biz.module.message.controller.param.ImMsgReceivedStatusUpdate;
import com.wecloud.im.biz.module.message.controller.param.MsgReadStatusUpdateParam;
import com.wecloud.im.biz.module.message.controller.param.UpdateMsgReadStatusByConversationParam;
import com.wecloud.im.biz.module.message.entity.ImInbox;
/**
* 消息收件箱表 服务类
*
* @author wei
* @since 2021-05-06
*/
public interface ImInboxService extends BaseService<ImInbox> {
// /**
// * 保存
// *
// * @param imInbox
// * @return
// * @throws Exception
// */
// boolean saveImInbox(ImInbox imInbox) throws Exception;
//
// /**
// * 修改
// *
// * @param imInbox
// * @return
// * @throws Exception
// */
// boolean updateImInbox(ImInbox imInbox) throws Exception;
//
// /**
// * 删除
// *
// * @param id
// * @return
// * @throws Exception
// */
// boolean deleteImInbox(Long id) throws Exception;
//
// /**
// * 根据ID获取查询对象
// *
// * @param id
// * @return
// * @throws Exception
// */
// ImInboxQueryVo getImInboxById(Long id) throws Exception;
//
// /**
// * 获取分页对象
// *
// * @param imInboxPageParam
// * @return
// * @throws Exception
// */
// Paging<ImInboxQueryVo> getImInboxPageList(ImInboxPageParam imInboxPageParam) throws Exception;
/**
* 消息修改为已接收状态
*
* @param imMsgReceivedUpdate
* @return
*/
Boolean updateImMsgReceived(ImMsgReceivedStatusUpdate imMsgReceivedUpdate);
/**
* 统计未读消息数量
*
* @param clientId
* @return
*/
Integer countMyNotReadCount(Long clientId);
/**
* 消息修改为已读状态
*
* @return
*/
Boolean updateImMsgRead(MsgReadStatusUpdateParam msgReadStatusUpdateParam) throws JsonProcessingException;
/**
* 整个会话消息修改为已读状态
* @param param
* @return
*/
Boolean updateMsgReadStatusByConversation(UpdateMsgReadStatusByConversationParam param);
}
package com.wecloud.im.biz.module.message.service;
import com.wecloud.can.datasource.mybatisplus.service.BaseService;
import com.wecloud.im.biz.module.message.controller.param.ImIosApnsQueryVo;
import com.wecloud.im.biz.module.message.entity.ImIosApns;
/**
* apns配置表 服务类
*
* @author wei
* @since 2021-09-18
*/
public interface ImIosApnsService extends BaseService<ImIosApns> {
/**
* 保存
*
* @param imIosApns
* @return
* @throws Exception
*/
boolean saveImIosApns(ImIosApns imIosApns) throws Exception;
/**
* 修改
*
* @param imIosApns
* @return
* @throws Exception
*/
boolean updateImIosApns(ImIosApns imIosApns) throws Exception;
/**
* 删除
*
* @param id
* @return
* @throws Exception
*/
boolean deleteImIosApns(Long id) throws Exception;
/**
* 根据ID获取查询对象
*
* @param id
* @return
* @throws Exception
*/
ImIosApnsQueryVo getImIosApnsById(Long id) throws Exception;
ImIosApns getImIosApnsByAppId(Long appId);
/**
* 获取分页对象
*
* @param imIosApnsPageParam
* @return
* @throws Exception
*/
// Paging<ImIosApnsQueryVo> getImIosApnsPageList(ImIosApnsPageParam imIosApnsPageParam) throws Exception;
}
package com.wecloud.im.biz.module.message.service;
import java.util.List;
import org.springframework.transaction.annotation.Transactional;
import com.wecloud.can.core.util.ApiResult;
import com.wecloud.can.datasource.mybatisplus.pagination.Paging;
import com.wecloud.can.datasource.mybatisplus.service.BaseService;
import com.wecloud.im.biz.module.message.controller.param.ChatContentVo;
import com.wecloud.im.biz.module.message.controller.param.GetReadersParam;
import com.wecloud.im.biz.module.message.controller.param.GroupChatMessageParam;
import com.wecloud.im.biz.module.message.controller.param.GroupChatStatusMessageParam;
import com.wecloud.im.biz.module.message.controller.param.ImClientSimpleDto;
import com.wecloud.im.biz.module.message.controller.param.ImHistoryMessagePageParam;
import com.wecloud.im.biz.module.message.controller.param.MsgDeleteParam;
import com.wecloud.im.biz.module.message.controller.param.PrivateChatMessageParam;
import com.wecloud.im.biz.module.message.controller.param.PrivateChatStatusMessageParam;
import com.wecloud.im.biz.module.message.controller.param.SingleUserNotificationParam;
import com.wecloud.im.biz.module.message.controller.param.add.ImMsgRecall;
import com.wecloud.im.biz.module.message.controller.param.add.ImMsgSendToOnlineClient;
import com.wecloud.im.biz.module.message.controller.param.add.ImMsgUpdate;
import com.wecloud.im.biz.module.message.controller.vo.ImMessageOfflineListVo;
import com.wecloud.im.biz.module.message.controller.vo.OfflineMsgDto;
import com.wecloud.im.biz.module.message.controller.vo.ReaderList;
import com.wecloud.im.biz.module.message.entity.ImApplication;
import com.wecloud.im.biz.module.message.entity.ImClient;
import com.wecloud.im.biz.module.message.entity.ImMessage;
import com.wecloud.im.server.model.request.ReceiveDataVO;
import com.wecloud.im.server.model.request.ReceiveVO;
/**
* 消息存储表 服务类
*
* @author wei
* @since 2021-04-29
*/
public interface ImMessageService extends BaseService<ImMessage> {
/**
* 下发透传消息
*
* @param imMsgSendToOnlineClient
* @return
*/
ApiResult<Boolean> restApiImMessageSend(ImMsgSendToOnlineClient imMsgSendToOnlineClient, ImApplication imApplication);
ImMessage saveImMessage(ImApplication imApplication, ImClient imClientSender, long messageId, ReceiveVO receiveVO, ReceiveDataVO sysParam);
@Transactional(rollbackFor = Exception.class)
ImMessage saveImMessage(ImClientSimpleDto client, long messageId, ChatContentVo data);
/**
* 消息撤回
* @param imMsgRecall
* @param request
* @return
*/
Boolean withdrawMsg(ImMsgRecall imMsgRecall);
/**
* 删除消息
* @param param
* @return
*/
Boolean deleteMsg(MsgDeleteParam param);
/**
* 修改消息体
*
* @param imMsgUpdate
* @return
*/
Boolean updateMsgById(ImMsgUpdate imMsgUpdate);
/**
* 查询某个会话历史消息分页列表
*
* @param param
* @return
* @throws Exception
*/
Paging<OfflineMsgDto> getHistoryMsgConversationId(ImHistoryMessagePageParam param);
/**
* 查询某个会话历史消息分页列表
*
* @param param
* @return
* @throws Exception
*/
Paging<OfflineMsgDto> getHistoryMsgConversationIdNew(ImHistoryMessagePageParam param);
/**
* 查询用户所有离线消息
*
* @return
* @throws Exception
*/
List<ImMessageOfflineListVo> getOfflineList() throws Exception;
/**
* 根据客户端id与会话id 查询离线消息
*
* @param clientId
* @param conversationId
* @return
*/
List<OfflineMsgDto> getOfflineListByClientAndConversation(Long clientId, Long conversationId);
/**
* 查询会话的最后一条消息
*
* @param conversationId
* @return
*/
OfflineMsgDto getLastMsgByConversationId(Long conversationId, Long currentFkClientId);
/**
* 查询会话接收的最后一条消息
*
* @param clientId
* @param conversationId
* @return
*/
OfflineMsgDto getReceivedLastMsgByConversationId(Long clientId, Long conversationId);
/**
* 保存
*
* @param imMessage
* @return
* @throws Exception
*/
boolean saveImMessage(ImMessage imMessage) throws Exception;
/**
* 获取读取人员
* @param param
* @return
*/
ReaderList getReaders(GetReadersParam param);
/**
* 发送群聊消息
* @param param
* @return
*/
Boolean groupMessagePublish(GroupChatMessageParam param);
/**
* 发送群聊状态消息
* @Author luozh
* @Date 2022年05月05日 02:32:58
* @param param
* @Return
*/
Boolean groupStatusMessagePublish(GroupChatStatusMessageParam param);
/**
* 发送单聊消息
* @Author luozh
* @Date 2022年05月05日 02:33:26
* @param param
* @Return
*/
Boolean privateMessagePublish(PrivateChatMessageParam param);
/**
* 发送单聊状态消息
* @Author luozh
* @Date 2022年05月05日 02:33:56
* @param param
* @Return
*/
Boolean privateStatusMessagePublish(PrivateChatStatusMessageParam param);
/**
* 单个用户通知-普通消息
* @Author luozh
* @Date 2022年05月25日 10:42:31
* @param param
* @Return
*/
Boolean singleUserNotification(SingleUserNotificationParam param);
}
package com.wecloud.im.biz.module.message.service;
import com.wecloud.can.datasource.mybatisplus.service.BaseService;
import com.wecloud.im.biz.module.message.entity.ImMultiRtcRoomMember;
/**
* @Author wenzhida
* @Date 2022/3/16 9:08
* @Description 多人音视频房间成员服务接口
*/
public interface ImMultiRtcRoomMemberService extends BaseService<ImMultiRtcRoomMember> {
/**
* 改变会议成员状态
* @param fkClientId
* @param roomId
* @param state
*/
void changeRoomMemberState(Long fkClientId, String roomId, Integer state);
}
package com.wecloud.im.biz.module.message.service;
import com.wecloud.can.datasource.mybatisplus.service.BaseService;
import com.wecloud.im.biz.module.message.entity.ImMultiRtcRoom;
/**
* @Author wenzhida
* @Date 2022/3/16 9:08
* @Description 多人音视频房间服务接口
*/
public interface ImMultiRtcRoomService extends BaseService<ImMultiRtcRoom> {
/**
* 获取多人音视频房间
* @param fkAppid
* @param roomId
* @return
*/
ImMultiRtcRoom getCachedMultiRtcRoom(Long fkAppid, String roomId);
/**
* 清房间缓存
* @param fkAppid
* @param roomId
*/
void deleteMultiRtcRoomCache(Long fkAppid, String roomId);
/**
* 更新多人音视频房间状态
* @param roomId
* @param state
*/
void updateMultiRtcRoomState(String roomId, Integer state);
}
package com.wecloud.im.biz.module.message.service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wecloud.can.datasource.mybatisplus.service.BaseService;
import com.wecloud.im.biz.enums.SingleRtcOperateTypeEnum;
import com.wecloud.im.biz.module.message.controller.param.rtc.CreateRtcChannelParam;
import com.wecloud.im.biz.module.message.controller.param.rtc.SingleRtcRecordParam;
import com.wecloud.im.biz.module.message.entity.ImClient;
import com.wecloud.im.biz.module.message.entity.ImRtcRecord;
/**
* @Author wenzhida
* @Date 2022/3/16 9:08
* @Description 单人音视频房记录服务接口
*/
public interface ImRtcRecordService extends BaseService<ImRtcRecord> {
/**
* 创建rtc通话记录
* @param param
* @param channelId
*/
void createRtcRecord(CreateRtcChannelParam param, Long channelId, ImClient currentClient);
/**
* 更新音视频记录
* @param channelId
* @param type 1-同意进入频道 2-拒接进入频道 3-主动挂断(离开频道) 4-异常原因断开
* @see SingleRtcOperateTypeEnum
*/
void updateRtcRecord(Long channelId, Integer type);
/**
* 获取通话记录
*/
Page<ImRtcRecord> getPageImRtcRecords(SingleRtcRecordParam singleRtcRecordParam);
}
package com.wecloud.im.biz.module.message.service.impl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import com.wecloud.can.core.exception.BusinessException;
import com.wecloud.im.biz.module.message.entity.ImApplication;
import com.wecloud.im.biz.module.message.entity.ImClient;
import com.wecloud.im.biz.module.message.service.ContextService;
import com.wecloud.im.biz.module.message.service.ImApplicationService;
import com.wecloud.im.biz.module.message.service.ImClientService;
/**
* 请求上下文服务 impl
* @Author luozh
* @Date 2022年04月02日 14:56
* @Version 1.0
*/
@Service
public class ContextServiceImpl implements ContextService {
@Autowired
@Lazy
private ImClientService imClientService;
@Autowired
private ImApplicationService imApplicationService;
@Override
public ImClient getImClientIfNotNullOrThrow() {
ImClient currentClient = imClientService.getCurrentClient();
if (currentClient == null) {
throw new BusinessException("当前用户登录信息失效");
}
return currentClient;
}
@Override
public ImApplication getImApplicationIfNotNullOrThrow(Long appId) {
ImApplication imApplication = imApplicationService.getCacheById(appId);
if (imApplication == null) {
throw new BusinessException("查无应用信息");
}
return imApplication;
}
}
package com.wecloud.im.biz.module.message.service.impl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wecloud.can.datasource.mybatisplus.pagination.PageInfo;
import com.wecloud.can.datasource.mybatisplus.pagination.Paging;
import com.wecloud.can.datasource.mybatisplus.service.impl.BaseServiceImpl;
import com.wecloud.can.security.signature.Application;
import com.wecloud.can.security.signature.ApplicationService;
import com.wecloud.im.biz.module.message.controller.param.ImApplicationPageParam;
import com.wecloud.im.biz.module.message.controller.param.ImApplicationQueryVo;
import com.wecloud.im.biz.module.message.entity.ImApplication;
import com.wecloud.im.biz.module.message.mapper.ImApplicationMapper;
import com.wecloud.im.biz.module.message.service.ImApplicationService;
/**
* 第三方应用表 服务实现类
*
* @author wei
* @since 2021-04-27
*/
@Slf4j
@Service
@CacheConfig(cacheNames = "appl")
public class ImApplicationServiceImpl extends BaseServiceImpl<ImApplicationMapper, ImApplication> implements ImApplicationService, ApplicationService {
@Autowired
private ImApplicationMapper imApplicationMapper;
@Override
// @Cacheable(key = "'id_'+#p0")
public ImApplication getCacheById(Long id) {
return super.getById(id);
}
@Override
@CacheEvict(key = "'id_'+#p0")
public void deleteCacheById(Long id) {
}
@Override
@CacheEvict(key = "'appKey_'+#p0")
public void deleteCacheByAppKey(String appKey) {
}
@Override
@Cacheable(key = "'appKey_'+#p0")
public ImApplication getCacheAppByAppKey(String appKey) {
ImApplication imApplication = this.getOne(
new QueryWrapper<ImApplication>().lambda()
.eq(ImApplication::getAppKey, appKey)
);
return imApplication;
}
@Transactional(rollbackFor = Exception.class)
@Override
public boolean saveImApplication(ImApplication imApplication) throws Exception {
return super.save(imApplication);
}
// @Transactional(rollbackFor = Exception.class)
// @Override
// public boolean updateImApplication(ImApplication imApplication) throws Exception {
// return super.updateById(imApplication);
// }
//
// @Transactional(rollbackFor = Exception.class)
// @Override
// public boolean deleteImApplication(Long id) throws Exception {
// return super.removeById(id);
// }
@Override
public ImApplicationQueryVo getImApplicationById(Long id) throws Exception {
return imApplicationMapper.getImApplicationById(id);
}
@Override
public Paging<ImApplicationQueryVo> getImApplicationPageList(ImApplicationPageParam imApplicationPageParam) throws Exception {
Page<ImApplicationQueryVo> page = new PageInfo<>(imApplicationPageParam, OrderItem.desc(getLambdaColumn(ImApplication::getCreateTime)));
IPage<ImApplicationQueryVo> iPage = imApplicationMapper.getImApplicationPageList(page, imApplicationPageParam);
return new Paging<ImApplicationQueryVo>(iPage);
}
@Override
public Application getApplication(String appKey) {
return getCacheAppByAppKey(appKey);
}
}
package com.wecloud.im.biz.module.message.service.impl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.wecloud.can.datasource.mybatisplus.service.impl.BaseServiceImpl;
import com.wecloud.im.biz.module.message.entity.ImClientDevice;
import com.wecloud.im.biz.module.message.mapper.ImClientDeviceMapper;
import com.wecloud.im.biz.module.message.service.ImClientDeviceService;
/**
* @Author wenzhida
* @Date 2022/3/2 15:00
* @Description 客户端设备服务接口实现
*/
@Slf4j
@Service
public class ImClientDeviceServiceImpl extends BaseServiceImpl<ImClientDeviceMapper, ImClientDevice> implements ImClientDeviceService {
@Autowired
private ImClientDeviceMapper imClientDeviceMapper;
@Override
public int removeOldToken(Long appId, String deviceToken) {
return imClientDeviceMapper.removeOldToken(appId, deviceToken);
}
@Override
public ImClientDevice getOneByAppIdAndClientIdAndType(Long appId, Long fkClientId, Integer deviceType) {
return getOne(Wrappers.<ImClientDevice>lambdaQuery()
.eq(ImClientDevice::getFkAppid, appId)
.eq(ImClientDevice::getFkClientId, fkClientId)
.eq(ImClientDevice::getDeviceType, deviceType));
}
}
package com.wecloud.im.biz.module.message.service.impl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.wecloud.can.datasource.mybatisplus.service.impl.BaseServiceImpl;
import com.wecloud.im.biz.module.message.controller.param.ImIosApnsQueryVo;
import com.wecloud.im.biz.module.message.entity.ImIosApns;
import com.wecloud.im.biz.module.message.mapper.ImIosApnsMapper;
import com.wecloud.im.biz.module.message.service.ImIosApnsService;
/**
* apns配置表 服务实现类
*
* @author wei
* @since 2021-09-18
*/
@Slf4j
@Service
@CacheConfig(cacheNames = "apns")
public class ImIosApnsServiceImpl extends BaseServiceImpl<ImIosApnsMapper, ImIosApns> implements ImIosApnsService {
@Autowired
private ImIosApnsMapper imIosApnsMapper;
@Transactional(rollbackFor = Exception.class)
@Override
public boolean saveImIosApns(ImIosApns imIosApns) throws Exception {
return super.save(imIosApns);
}
@Transactional(rollbackFor = Exception.class)
@Override
public boolean updateImIosApns(ImIosApns imIosApns) throws Exception {
return super.updateById(imIosApns);
}
@Transactional(rollbackFor = Exception.class)
@Override
public boolean deleteImIosApns(Long id) throws Exception {
return super.removeById(id);
}
@Override
public ImIosApnsQueryVo getImIosApnsById(Long id) throws Exception {
return imIosApnsMapper.getImIosApnsById(id);
}
@Override
// @Cacheable(key = "#p0")
public ImIosApns getImIosApnsByAppId(Long appId) {
return this.getOne(new QueryWrapper<ImIosApns>().lambda().eq(
ImIosApns::getFkAppId, appId
));
}
// @Override
// public Paging<ImIosApnsQueryVo> getImIosApnsPageList(ImIosApnsPageParam imIosApnsPageParam) throws Exception {
// Page<ImIosApnsQueryVo> page;
// IPage<ImIosApnsQueryVo> iPage = imIosApnsMapper.getImIosApnsPageList(page, imIosApnsPageParam);
// return new Paging<ImIosApnsQueryVo>(iPage);
// }
}
package com.wecloud.im.biz.module.message.service.impl;
import lombok.extern.slf4j.Slf4j;
import java.util.Date;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.wecloud.can.datasource.mybatisplus.service.impl.BaseServiceImpl;
import com.wecloud.im.biz.module.message.entity.ImMultiRtcRoomMember;
import com.wecloud.im.biz.module.message.mapper.ImMultiRtcRoomMemberMapper;
import com.wecloud.im.biz.module.message.service.ImMultiRtcRoomMemberService;
/**
* @Author wenzhida
* @Date 2022/3/16 9:27
* @Description 多人音视频房间成员服务接口实现
*/
@Slf4j
@Service
public class ImMultiRtcRoomMemberServiceImpl extends BaseServiceImpl<ImMultiRtcRoomMemberMapper, ImMultiRtcRoomMember> implements ImMultiRtcRoomMemberService {
@Autowired
private ImMultiRtcRoomMemberMapper imMultiRtcRoomMemberMapper;
@Override
public void changeRoomMemberState(Long fkClientId, String roomId, Integer state) {
this.update(new UpdateWrapper<ImMultiRtcRoomMember>().lambda()
.eq(ImMultiRtcRoomMember::getRoomId, roomId)
.eq(ImMultiRtcRoomMember::getFkClientId, fkClientId)
.set(ImMultiRtcRoomMember::getHeartbeatTime, new Date())
.set(ImMultiRtcRoomMember::getState, state));
}
}
package com.wecloud.im.biz.module.message.service.impl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.wecloud.can.datasource.mybatisplus.service.impl.BaseServiceImpl;
import com.wecloud.im.biz.module.message.entity.ImMultiRtcRoom;
import com.wecloud.im.biz.module.message.mapper.ImMultiRtcRoomMapper;
import com.wecloud.im.biz.module.message.service.ImMultiRtcRoomService;
/**
* @Author wenzhida
* @Date 2022/3/16 9:27
* @Description 多人音视频房间服务接口实现
*/
@Slf4j
@Service
@CacheConfig(cacheNames = "multiRtc")
public class ImMultiRtcRoomServiceImpl extends BaseServiceImpl<ImMultiRtcRoomMapper, ImMultiRtcRoom> implements ImMultiRtcRoomService {
@Autowired
private ImMultiRtcRoomService imMultiRtcRoomService;
@Override
// @Cacheable(key = "'rtcRoomKey_' + #p0+#p1")
public ImMultiRtcRoom getCachedMultiRtcRoom(Long fkAppid, String roomId) {
ImMultiRtcRoom rtcRoom = imMultiRtcRoomService.getOne(new QueryWrapper<ImMultiRtcRoom>().lambda()
.eq(ImMultiRtcRoom::getFkAppid, fkAppid)
.eq(ImMultiRtcRoom::getRoomId, roomId));
return rtcRoom;
}
@Override
@CacheEvict(key = "'rtcRoomKey_' + #p0+#p1")
public void deleteMultiRtcRoomCache(Long fkAppid, String roomId) {
}
@Override
public void updateMultiRtcRoomState(String roomId, Integer state) {
imMultiRtcRoomService.update(new UpdateWrapper<ImMultiRtcRoom>().lambda()
.eq(ImMultiRtcRoom::getRoomId, roomId)
.set(ImMultiRtcRoom::getState, state));
}
}
package com.wecloud.im.biz.module.message.service.impl;
import lombok.extern.slf4j.Slf4j;
import java.util.Date;
import javax.annotation.Resource;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wecloud.can.core.exception.BusinessException;
import com.wecloud.can.core.util.SnowflakeUtil;
import com.wecloud.can.datasource.mybatisplus.service.impl.BaseServiceImpl;
import com.wecloud.im.biz.enums.RtcStateEnum;
import com.wecloud.im.biz.enums.SingleRtcOperateTypeEnum;
import com.wecloud.im.biz.module.message.controller.param.rtc.CreateRtcChannelParam;
import com.wecloud.im.biz.module.message.controller.param.rtc.SingleRtcRecordParam;
import com.wecloud.im.biz.module.message.entity.ImClient;
import com.wecloud.im.biz.module.message.entity.ImRtcRecord;
import com.wecloud.im.biz.module.message.mapper.ImRtcRecordMapper;
import com.wecloud.im.biz.module.message.service.ImClientService;
import com.wecloud.im.biz.module.message.service.ImRtcRecordService;
/**
* @Author Future
* @Date 2022/5/22 23:50
* @Description 单人音视频记录服务实现
*/
@Slf4j
@Service
public class ImRtcRecordServiceImpl extends BaseServiceImpl<ImRtcRecordMapper, ImRtcRecord> implements ImRtcRecordService {
@Resource
private ImClientService imClientService;
@Async
@Override
public void createRtcRecord(CreateRtcChannelParam param, Long channelId, ImClient currentClient) {
try {
ImRtcRecord rtcRecord = new ImRtcRecord();
rtcRecord.setId(SnowflakeUtil.getId());
rtcRecord.setFkAppid(currentClient.getFkAppid());
rtcRecord.setChannelId(channelId);
rtcRecord.setFromClientId(currentClient.getClientId());
rtcRecord.setToClientId(param.getToClient());
rtcRecord.setCallType(param.getCallType());
rtcRecord.setState(RtcStateEnum.CREATED.getCode());
rtcRecord.setCreateTime(new Date());
this.save(rtcRecord);
} catch (Exception e) {
log.info("创建rtc通话记录异常 param {} channelId {} 异常 ", JSON.toJSONString(param), channelId, e);
}
}
/**
* 更新音视频记录
*
* @param channelId
* @param type 1-同意进入频道 2-拒接进入频道 3-主动挂断(离开频道)
*/
@Async
@Override
public void updateRtcRecord(Long channelId, Integer type) {
try {
ImRtcRecord rtcRecord = this.getOne(new QueryWrapper<ImRtcRecord>().lambda()
.eq(ImRtcRecord::getChannelId, channelId));
if (rtcRecord == null) {
return;
}
if (SingleRtcOperateTypeEnum.JOIN.getCode().equals(type)) {
// 同意进入频道
rtcRecord.setState(RtcStateEnum.ING.getCode());
rtcRecord.setStartTime(new Date());
} else if (SingleRtcOperateTypeEnum.REJECT.getCode().equals(type)) {
// 拒接进入频道
rtcRecord.setState(RtcStateEnum.END.getCode());
} else if (SingleRtcOperateTypeEnum.LEAVE.getCode().equals(type)) {
// 主动挂断(离开频道)
rtcRecord.setState(RtcStateEnum.END.getCode());
rtcRecord.setEndTime(new Date());
} else if (SingleRtcOperateTypeEnum.ABNORMAL_DISCONNECT.getCode().equals(type)) {
// 异常原因(客户端已不在线)
rtcRecord.setState(RtcStateEnum.END.getCode());
rtcRecord.setEndTime(new Date());
}
this.updateById(rtcRecord);
} catch (Exception e) {
log.info("更新rtc通话记录异常, channelId {}, type {} 异常 ", channelId, type, e);
}
}
@Override
public Page<ImRtcRecord> getPageImRtcRecords(SingleRtcRecordParam param) {
if (param.getPageNum() == null) {
throw new BusinessException("页码不可为空");
}
if (param.getPageSize() == null) {
throw new BusinessException("每页数量不可为空");
}
ImClient imClient = imClientService.getCurrentClient();
LambdaQueryWrapper<ImRtcRecord> rtcRecordLambdaQueryWrapper = new LambdaQueryWrapper<>();
rtcRecordLambdaQueryWrapper.eq(ImRtcRecord::getFkAppid, imClient.getFkAppid());
rtcRecordLambdaQueryWrapper.eq(param.getFromClientId() != null, ImRtcRecord::getFromClientId, param.getFromClientId());
rtcRecordLambdaQueryWrapper.eq(param.getToClientId() != null, ImRtcRecord::getToClientId, param.getToClientId());
rtcRecordLambdaQueryWrapper.eq(param.getChannelId() != null, ImRtcRecord::getChannelId, param.getChannelId());
rtcRecordLambdaQueryWrapper.eq(param.getCallType() != null, ImRtcRecord::getCallType, param.getCallType());
rtcRecordLambdaQueryWrapper.lt(param.getCreateTimeEnd() != null, ImRtcRecord::getCreateTime, param.getCreateTimeEnd());
rtcRecordLambdaQueryWrapper.gt(param.getCreateTimeStart() != null, ImRtcRecord::getCreateTime, param.getCreateTimeStart());
rtcRecordLambdaQueryWrapper.orderByDesc(ImRtcRecord::getCreateTime);
Page<ImRtcRecord> pageParam = new Page<>(param.getPageNum(), param.getPageSize());
Page<ImRtcRecord> page = this.page(pageParam, rtcRecordLambdaQueryWrapper);
return page;
}
}
package com.wecloud.im.biz.module.multimeet.entity.dto;
import lombok.Data;
import java.io.Serializable;
import com.wecloud.im.biz.enums.MultiRtcMemberStateEnum;
/**
* @Author wenzhida
* @Date 2022/3/16 11:21
* @Description 房间成员dto
*/
@Data
public class RoomMemberDto implements Serializable {
private static final long serialVersionUID = 7634567721658236530L;
/**
* client主键id
*/
private Long fkClientId;
/**
* 客户端id
*/
private String clientId;
/**
* 多人音视频房间成员状态枚举
* @see MultiRtcMemberStateEnum
*/
private Integer state;
}
package com.wecloud.im.biz.module.multimeet.entity.response;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
/**
* @Author wenzhida
* @Date 2022/3/7 22:21
* @Description 同意进入多人音视频
*/
@EqualsAndHashCode(callSuper = true)
@Data
public class MultiMeetAgreeResponse extends MultiMeetDataBase implements Serializable {
private static final long serialVersionUID = 1623214002231302888L;
/**
* 会话id
*/
private Long conversationId;
/**
* 房间id
*/
private String roomId;
}
package com.wecloud.im.biz.module.multimeet.entity.response;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
/**
* @Author wenzhida
* @Date 2022/3/16 13:52
* @Description 占线响应
*/
@EqualsAndHashCode(callSuper = true)
@Data
public class MultiMeetBusyResponse extends MultiMeetDataBase implements Serializable {
private static final long serialVersionUID = -5692994062040333774L;
/**
* 会话id
*/
private Long conversationId;
/**
* 房间id
*/
private String roomId;
/**
* 占线人clientId
*/
private String busyClientId;
}
package com.wecloud.im.biz.module.multimeet.entity.response;
import lombok.Data;
import java.io.Serializable;
/**
* @Author wenzhida
* @Date 2022/3/7 22:01
* @Description 多人音视频会议长连接响应基类
*/
@Data
public class MultiMeetDataBase implements Serializable {
private static final long serialVersionUID = -4151469100462562164L;
/**
* 子指令
*/
private Integer subCmd;
private String clientId;
private Long timestamp;
}
package com.wecloud.im.biz.module.multimeet.entity.response;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
import java.util.List;
import com.wecloud.im.biz.module.multimeet.entity.dto.RoomMemberDto;
/**
* @Author wenzhida
* @Date 2022/3/7 22:02
* @Description 邀请加入多人音视频会议
*/
@EqualsAndHashCode(callSuper = true)
@Data
public class MultiMeetInviteResponse extends MultiMeetDataBase implements Serializable {
/**
* 会话id
*/
private Long conversationId;
/**
* 房间id
*/
private String roomId;
/**
* 成员列表dto
*/
private List<RoomMemberDto> memberDtoList;
}
package com.wecloud.im.biz.module.multimeet.entity.response;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
/**
* @Author wenzhida
* @Date 2022/3/7 22:21
* @Description 主动离开多人音视频
*/
@EqualsAndHashCode(callSuper = true)
@Data
public class MultiMeetLeaveResponse extends MultiMeetDataBase implements Serializable {
private static final long serialVersionUID = 734428267643207411L;
/**
* 会话id
*/
private Long conversationId;
/**
* 房间id
*/
private String roomId;
}
package com.wecloud.im.biz.module.multimeet.entity.response;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
/**
* @Author wenzhida
* @Date 2022/3/7 22:21
* @Description 拒绝进入多人音视频
*/
@EqualsAndHashCode(callSuper = true)
@Data
public class MultiMeetRejectResponse extends MultiMeetDataBase implements Serializable {
/**
* 会话id
*/
private Long conversationId;
/**
* 房间id
*/
private String roomId;
}
package com.wecloud.im.biz.module.multimeet.service;
import com.wecloud.im.biz.module.message.controller.param.AgreeToMultiMeetParam;
import com.wecloud.im.biz.module.message.controller.param.HeartbeatMultiMeetParam;
import com.wecloud.im.biz.module.message.controller.param.InviteToMultiMeetParam;
import com.wecloud.im.biz.module.message.controller.param.LeaveFromMultiMeetParam;
import com.wecloud.im.biz.module.message.controller.param.NotAnsweredMultiMeetParam;
import com.wecloud.im.biz.module.message.controller.param.RejectToMultiMeetParam;
/**
* @Author wenzhida
* @Date 2022/3/7 18:26
* @Description 多人音视频服务接口
*/
public interface MultiMeetService {
/**
* 发起多人音视频邀请
* @param param
* @return
*/
void invite(InviteToMultiMeetParam param);
/**
* 拒接加入会议
* @param param
*/
void reject(RejectToMultiMeetParam param);
/**
* 同意进入会议
* @param param
*/
void agree(AgreeToMultiMeetParam param);
/**
* 同意进入会议
* @param param
*/
void leave(LeaveFromMultiMeetParam param);
/**
* 拒绝接听
* @param param
*/
void notAnswered(NotAnsweredMultiMeetParam param);
/**
* 心跳接收
* @param param
*/
void heartbeat(HeartbeatMultiMeetParam param);
/**
* 是否正在被呼叫
*/
void isBeCalling();
/**
* 呼叫超时逻辑处理
*/
void callingTimeout();
/**
* 异常断线逻辑处理
*/
void disconnect();
}
package com.wecloud.im.biz.module.multimeet.service;
import com.wecloud.im.biz.module.multimeet.entity.response.MultiMeetAgreeResponse;
import com.wecloud.im.biz.module.multimeet.entity.response.MultiMeetBusyResponse;
import com.wecloud.im.biz.module.multimeet.entity.response.MultiMeetInviteResponse;
import com.wecloud.im.biz.module.multimeet.entity.response.MultiMeetLeaveResponse;
import com.wecloud.im.biz.module.multimeet.entity.response.MultiMeetRejectResponse;
/**
* @Author wenzhida
* @Date 2022/3/7 21:47
* @Description 多人音视频 webSocket下发指令数据
*/
public interface WsMultiMeetWrite {
/**
* 发送邀请
* @param multiMeetInviteResponse
* @param toFkClientId
*/
void invite(MultiMeetInviteResponse multiMeetInviteResponse, Long toFkClientId);
/**
* 拒接邀请
* @param multiMeetRejectResponse
* @param toFkClientId
*/
void reject(MultiMeetRejectResponse multiMeetRejectResponse, Long toFkClientId);
/**
* 同意进入会议
* @param multiMeetAgreeResponse
* @param toFkClientId
*/
void agree(MultiMeetAgreeResponse multiMeetAgreeResponse, Long toFkClientId);
/**
* 主动离开会议
* @param multiMeetLeaveResponse
* @param toFkClientId
*/
void leave(MultiMeetLeaveResponse multiMeetLeaveResponse, Long toFkClientId);
/**
* 被邀请方占线
* @param multiMeetBusyResponse
* @param toFkClientId
*/
void busy(MultiMeetBusyResponse multiMeetBusyResponse, Long toFkClientId);
}
package com.wecloud.im.biz.module.multimeet.service.impl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.wecloud.can.core.enums.ApiCode;
import com.wecloud.can.core.util.ApiResult;
import com.wecloud.im.biz.module.multimeet.entity.response.MultiMeetAgreeResponse;
import com.wecloud.im.biz.module.multimeet.entity.response.MultiMeetBusyResponse;
import com.wecloud.im.biz.module.multimeet.entity.response.MultiMeetInviteResponse;
import com.wecloud.im.biz.module.multimeet.entity.response.MultiMeetLeaveResponse;
import com.wecloud.im.biz.module.multimeet.entity.response.MultiMeetRejectResponse;
import com.wecloud.im.biz.module.multimeet.service.WsMultiMeetWrite;
import com.wecloud.im.server.enums.WsMultiMeetResponseSubCmdEnum;
import com.wecloud.im.server.enums.WsResponseCmdEnum;
import com.wecloud.im.server.model.WsResponse;
import com.wecloud.im.server.sender.ChannelSender;
/**
* @Author wenzhida
* @Date 2022/3/7 22:26
* @Description 多人音视频长连接下发
*/
@Service
public class WsMultiMeetWriteImpl implements WsMultiMeetWrite {
@Autowired
private ChannelSender channelSender;
@Override
public void invite(MultiMeetInviteResponse multiMeetInviteResponse, Long toFkClientId) {
multiMeetInviteResponse.setSubCmd(WsMultiMeetResponseSubCmdEnum.INVITE.getCmdCode());
// 向接收方推送
WsResponse<MultiMeetInviteResponse> responseModel = new WsResponse<>();
responseModel.setCmd(WsResponseCmdEnum.MULTI_MEET_MSG.getCmdCode());
ApiResult<Boolean> result = ApiResult.result(ApiCode.SUCCESS);
responseModel.setCode(result.getCode());
responseModel.setMsg(result.getMessage());
responseModel.setData(multiMeetInviteResponse);
responseModel.setReqId(null);
channelSender.sendMsg(responseModel, toFkClientId);
}
@Override
public void reject(MultiMeetRejectResponse multiMeetRejectResponse, Long toFkClientId) {
multiMeetRejectResponse.setSubCmd(WsMultiMeetResponseSubCmdEnum.REJECT.getCmdCode());
// 向接收方推送
WsResponse<MultiMeetRejectResponse> responseModel = new WsResponse<>();
responseModel.setCmd(WsResponseCmdEnum.MULTI_MEET_MSG.getCmdCode());
ApiResult<Boolean> result = ApiResult.result(ApiCode.SUCCESS);
responseModel.setCode(result.getCode());
responseModel.setMsg(result.getMessage());
responseModel.setData(multiMeetRejectResponse);
responseModel.setReqId(null);
channelSender.sendMsg(responseModel, toFkClientId);
}
@Override
public void agree(MultiMeetAgreeResponse multiMeetAgreeResponse, Long toFkClientId) {
multiMeetAgreeResponse.setSubCmd(WsMultiMeetResponseSubCmdEnum.AGREE.getCmdCode());
// 向接收方推送
WsResponse<MultiMeetAgreeResponse> responseModel = new WsResponse<>();
responseModel.setCmd(WsResponseCmdEnum.MULTI_MEET_MSG.getCmdCode());
ApiResult<Boolean> result = ApiResult.result(ApiCode.SUCCESS);
responseModel.setCode(result.getCode());
responseModel.setMsg(result.getMessage());
responseModel.setData(multiMeetAgreeResponse);
responseModel.setReqId(null);
channelSender.sendMsg(responseModel, toFkClientId);
}
@Override
public void leave(MultiMeetLeaveResponse multiMeetLeaveResponse, Long toFkClientId) {
multiMeetLeaveResponse.setSubCmd(WsMultiMeetResponseSubCmdEnum.LEAVE.getCmdCode());
// 向接收方推送
WsResponse<MultiMeetLeaveResponse> responseModel = new WsResponse<>();
responseModel.setCmd(WsResponseCmdEnum.MULTI_MEET_MSG.getCmdCode());
ApiResult<Boolean> result = ApiResult.result(ApiCode.SUCCESS);
responseModel.setCode(result.getCode());
responseModel.setMsg(result.getMessage());
responseModel.setData(multiMeetLeaveResponse);
responseModel.setReqId(null);
channelSender.sendMsg(responseModel, toFkClientId);
}
@Override
public void busy(MultiMeetBusyResponse multiMeetBusyResponse, Long toFkClientId) {
multiMeetBusyResponse.setSubCmd(WsMultiMeetResponseSubCmdEnum.BUSY.getCmdCode());
// 向接收方推送
WsResponse<MultiMeetBusyResponse> responseModel = new WsResponse<>();
responseModel.setCmd(WsResponseCmdEnum.MULTI_MEET_MSG.getCmdCode());
ApiResult<Boolean> result = ApiResult.result(ApiCode.SUCCESS);
responseModel.setCode(result.getCode());
responseModel.setMsg(result.getMessage());
responseModel.setData(multiMeetBusyResponse);
responseModel.setReqId(null);
channelSender.sendMsg(responseModel, toFkClientId);
}
}
package com.wecloud.im.biz.module.rtc.entity;
import java.io.Serializable;
public class RtcSubCmd implements Serializable {
/**
* subCmd子类型指令码
*/
public static final String SUB_CMD = "subCmd";
}
package com.wecloud.im.biz.module.rtc.entity.redis;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
/**
* rtc 频道信息
*/
@Data
public class RtcChannelInfo implements Serializable {
@ApiModelProperty("当前房主")
private Long owner;
@ApiModelProperty("创建时间")
private Long createTimestamp;
}
package com.wecloud.im.biz.module.rtc.entity.redis;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
/**
* rtc 频道内的用户
*/
@Data
public class RtcJoinUser implements Serializable {
@ApiModelProperty("客户端")
private String clientId;
@ApiModelProperty("加入时间")
private Long createTimestamp;
private String sdpData;
private String sdpType;
}
package com.wecloud.im.biz.module.rtc.entity.redis;
import lombok.Data;
import java.io.Serializable;
/**
* rtc 频道内所有用户
*/
@Data
public class RtcJoinUsers implements Serializable {
}
package com.wecloud.im.biz.module.rtc.entity.redis;
import java.io.Serializable;
public class RtcRedisKey implements Serializable {
/**
* 维护频道信息 (kv)
*/
public static final String RTC_CHANNEL_INFO = "r:ci:%s";
/**
* 维护用户当前在线的频道ID ( kv)
* user_join_channel = ujc
* rcu:clientA = 10001
* rcu:clientB = 10001
* rcu:clientC = 10002
* rcu:clientD = 10003
*/
public static final String USER_JOIN_CHANNEL = "r:ujc:%s";
/**
* 维护频道中存在的用户 (set 集合):
* rtc_channel_users = rcu
* rcu:10001 = clientA , clientB
* rcu:10002 = clientC
* rcu:10003 = clientD
*/
public static final String RTC_CHANNEL_USERS = "r:cu:%s";
}
package com.wecloud.im.biz.module.rtc.entity.response;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
import com.wecloud.im.biz.enums.CallTypeEnum;
@EqualsAndHashCode(callSuper = true)
@Data
public class RtcCallResponse extends RtcDataBase implements Serializable {
/**
* 类型: "video" 或 "voice"
* @see CallTypeEnum
*/
private Integer callType;
/**
* 会话id
*/
private Long conversationId;
}
package com.wecloud.im.biz.module.rtc.entity.response;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
@EqualsAndHashCode(callSuper = true)
@Data
public class RtcCandidateForwardResponse extends RtcDataBase implements Serializable {
/**
* 转发的候选者数据
*/
private String candidateData;
}
package com.wecloud.im.biz.module.rtc.entity.response;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
@EqualsAndHashCode(callSuper = true)
@Data
public class RtcClientJoinResponse extends RtcDataBase implements Serializable {
}
package com.wecloud.im.biz.module.rtc.entity.response;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
@EqualsAndHashCode(callSuper = true)
@Data
public class RtcClientLeaveResponse extends RtcDataBase implements Serializable {
}
package com.wecloud.im.biz.module.rtc.entity.response;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
@EqualsAndHashCode(callSuper = true)
@Data
public class RtcClientRejectResponse extends RtcDataBase implements Serializable {
}
package com.wecloud.im.biz.module.rtc.entity.response;
import lombok.Data;
import java.io.Serializable;
@Data
public class RtcDataBase implements Serializable {
/**
* 子指令
*/
private Integer subCmd;
private Long channelId;
private String clientId;
private Long timestamp;
}
package com.wecloud.im.biz.module.rtc.entity.response;
import lombok.Data;
import java.io.Serializable;
/**
* webRtc websocket下发数据封装类
*
* @param <T>
*/
@Data
public class RtcResponseBase<T> implements Serializable {
/**
* 子指令
*/
private Integer subCmd;
/**
* 根据不同子指令 不同的实体
*/
private T subData;
/**
* 自定义拓展字段
*/
private String attrs;
}
package com.wecloud.im.biz.module.rtc.entity.response;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
@EqualsAndHashCode(callSuper = true)
@Data
public class RtcSdpForwardResponse extends RtcDataBase implements Serializable {
/**
* channelId : 1234263457652
* clientId : 7657567
* sdpData : xxxxxxxxxxxxxxxx
* sdpType : Offer/Answer
*/
private String sdpData;
private String sdpType;
}
package com.wecloud.im.biz.module.rtc.service;
import java.util.List;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.wecloud.im.biz.module.rtc.entity.redis.RtcChannelInfo;
/**
* 管理rtc频道
*/
public interface MangerRtcCacheService {
/**
* 移除频道信息
*
* @param rtcChannelId
* @return
*/
boolean delChannelInfo(Long rtcChannelId);
/**
* 频道中客户端是否为空
*
* @param rtcChannelId
* @return
*/
boolean channelIsEmpty(Long rtcChannelId);
/**
* 获取频道信息
*
* @param rtcChannelId
* @return
* @throws JsonProcessingException
*/
RtcChannelInfo getRtcChannelInfo(Long rtcChannelId) throws JsonProcessingException;
/**
* 创建一个频道
*
* @param clientId
* @param rtcChannelId 雪花算法生成频道id
*/
void create(Long clientId, Long toClientId, Long rtcChannelId);
/**
* 加入频道
*/
void join(Long clientId, Long rtcChannelId);
/**
* 退出频道
*/
void leave(Long clientId, Long rtcChannelId);
/**
* 根据频道ID获取频道内所有client
*/
List<String> getClientListByRtcChannelId(Long rtcChannelId);
/**
* 根据客户端ID获取该客户端加入的频道ID
*/
Long getRtcChannelIdListByClientId(Long clientId);
/**
* 获取客户端忙线/空闲状态
*
* @param clientId
* @return true:忙线,false空闲
*/
boolean getBusyStatus(Long clientId);
}
package com.wecloud.im.biz.module.rtc.service;
import com.wecloud.im.biz.module.message.controller.param.rtc.CandidateForwardParam;
import com.wecloud.im.biz.module.message.controller.param.rtc.CreateRtcChannelParam;
import com.wecloud.im.biz.module.message.controller.param.rtc.CreateRtcChannelResult;
import com.wecloud.im.biz.module.message.controller.param.rtc.JoinRtcChannelParam;
import com.wecloud.im.biz.module.message.controller.param.rtc.LeaveRtcChannelParam;
import com.wecloud.im.biz.module.message.controller.param.rtc.RejectRtcChannelParam;
import com.wecloud.im.biz.module.message.controller.param.rtc.SdpForwardParam;
/**
* 管理rtc频道
*/
public interface RtcService {
/**
* 创建一个频道,并向接收方发送系统推送
*/
CreateRtcChannelResult createAndCall(CreateRtcChannelParam createRtcChannelParam);
/**
* 加入频道
*/
Boolean join(JoinRtcChannelParam joinRtcChannelParam);
/**
* 拒接加入频道
*/
Boolean reject(RejectRtcChannelParam rejectRtcChannelParam);
/**
* 退出频道
*/
Boolean leave(LeaveRtcChannelParam leaveRtcChannelParam);
/**
* SDP数据转发
*
* @param sdpForwardParam
* @return
*/
Boolean sdpForward(SdpForwardParam sdpForwardParam);
/**
* candidate候选者数据转发
*
* @param candidateForwardParam
* @return
*/
Boolean candidateForward(CandidateForwardParam candidateForwardParam);
/**
* 异常断线判断处理
*/
void abnormalDisconnect();
}
package com.wecloud.im.biz.module.rtc.service;
import com.wecloud.im.biz.module.rtc.entity.response.RtcCallResponse;
import com.wecloud.im.biz.module.rtc.entity.response.RtcCandidateForwardResponse;
import com.wecloud.im.biz.module.rtc.entity.response.RtcClientJoinResponse;
import com.wecloud.im.biz.module.rtc.entity.response.RtcClientLeaveResponse;
import com.wecloud.im.biz.module.rtc.entity.response.RtcClientRejectResponse;
import com.wecloud.im.biz.module.rtc.entity.response.RtcSdpForwardResponse;
/**
* WebRtc webSocket下发指令数据
*/
public interface WsRtcWrite {
/**
* 接收到RTC邀请
*/
void rtcCall(RtcCallResponse rtcCallResponse, Long toClientId);
/**
* 用户状态更新事件(用户加入频道)
*/
void clientJoin(RtcClientJoinResponse rtcClientJoinResponse, Long toClientId);
/**
* 用户状态更新事件(用户退出频道)
*/
void clientLeave(RtcClientLeaveResponse rtcClientLeaveResponse, Long toClientId);
/**
* 用户状态更新事件(用户拒接邀请;不同意进入频道)
*/
void clientReject(RtcClientRejectResponse rtcClientRejectResponse, Long toClientId);
/**
* SDP数据转发
*/
void sdpForward(RtcSdpForwardResponse rtcSdpForwardResponse, Long toClientId);
/**
* candidate候选者数据转发
*/
void candidateForward(RtcCandidateForwardResponse rtcCandidateForwardResponse, Long toClientId);
}
package com.wecloud.im.biz.module.rtc.service.impl;
import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.wecloud.can.core.util.JsonUtils;
import com.wecloud.im.biz.module.rtc.entity.redis.RtcChannelInfo;
import com.wecloud.im.biz.module.rtc.entity.redis.RtcRedisKey;
import com.wecloud.im.biz.module.rtc.service.MangerRtcCacheService;
import com.wecloud.im.server.utils.RedisUtils;
@Service
public class MangerRtcCacheServiceImpl implements MangerRtcCacheService {
@Autowired
private RedisUtils redisUtils;
@Override
public boolean delChannelInfo(Long rtcChannelId) {
String channelKey = String.format(RtcRedisKey.RTC_CHANNEL_INFO, rtcChannelId);
redisUtils.delKey(channelKey);
return true;
}
@Override
public boolean channelIsEmpty(Long rtcChannelId) {
List<String> clientListByRtcChannelId = getClientListByRtcChannelId(rtcChannelId);
// // 移除自己
// clientListByRtcChannelId.remove(appKey + clientId);
return clientListByRtcChannelId.isEmpty();
}
@Override
public RtcChannelInfo getRtcChannelInfo(Long rtcChannelId) throws JsonProcessingException {
// 频道信息
String channelKey = String.format(RtcRedisKey.RTC_CHANNEL_INFO, rtcChannelId);
String value = redisUtils.getKey(channelKey);
if (StringUtils.isBlank(value)) {
return null;
}
return JsonUtils.decodeJson(value, RtcChannelInfo.class);
}
@Override
public void create(Long clientId, Long toClientId, Long rtcChannelId) {
// --- 频道信息
RtcChannelInfo rtcChannelInfo = new RtcChannelInfo();
//当前房主
rtcChannelInfo.setOwner(clientId);
//创建时间
rtcChannelInfo.setCreateTimestamp(System.currentTimeMillis());
String rtcChannelInfoJson = JsonUtils.encodeJson(rtcChannelInfo);
// --- 保存频道信息
String channelKey = String.format(RtcRedisKey.RTC_CHANNEL_INFO, rtcChannelId);
redisUtils.addKey(channelKey, rtcChannelInfoJson, Duration.ofDays(10));
// 用户当前在线的频道ID
String userJoinChannelKey = String.format(RtcRedisKey.USER_JOIN_CHANNEL, clientId);
redisUtils.addKey(userJoinChannelKey, rtcChannelId.toString(), Duration.ofDays(10));
// 频道中存在的用户
String rtcChannelUsers = String.format(RtcRedisKey.RTC_CHANNEL_USERS, rtcChannelId);
redisUtils.addForSet(rtcChannelUsers, clientId + "", 10, TimeUnit.DAYS);
redisUtils.addForSet(rtcChannelUsers, toClientId + "", 10, TimeUnit.DAYS);
}
@Override
public void join(Long clientId, Long rtcChannelId) {
//用户当前在线的频道ID
String userJoinChannelKey = String.format(RtcRedisKey.USER_JOIN_CHANNEL, clientId);
redisUtils.addKey(userJoinChannelKey, rtcChannelId.toString(), Duration.ofDays(10));
}
@Override
public void leave(Long clientId, Long rtcChannelId) {
//用户当前在线的频道ID
String userJoinChannelKey = String.format(RtcRedisKey.USER_JOIN_CHANNEL, clientId);
redisUtils.delKey(userJoinChannelKey);
//频道中存在的用户
String rtcChannelUsersKey = String.format(RtcRedisKey.RTC_CHANNEL_USERS, rtcChannelId);
redisUtils.removeForSet(rtcChannelUsersKey, clientId + "");
}
@Override
public List<String> getClientListByRtcChannelId(Long rtcChannelId) {
//频道中存在的用户
String key = String.format(RtcRedisKey.RTC_CHANNEL_USERS, rtcChannelId);
Set<String> forSetMembers = redisUtils.getForSetMembers(key);
return new ArrayList<>(forSetMembers);
}
@Override
public Long getRtcChannelIdListByClientId(Long clientId) {
//用户当前在线的频道ID
String userJoinChannelKey = String.format(RtcRedisKey.USER_JOIN_CHANNEL, clientId);
String key = redisUtils.getKey(userJoinChannelKey);
if (StringUtils.isBlank(key)) {
return null;
}
return Long.valueOf(key);
}
@Override
public boolean getBusyStatus(Long clientId) {
//用户当前在线的频道ID
String userJoinChannelKey = String.format(RtcRedisKey.USER_JOIN_CHANNEL, clientId);
String key = redisUtils.getKey(userJoinChannelKey);
return key != null && !key.isEmpty();
}
}
package com.wecloud.im.biz.module.rtc.service.impl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.wecloud.can.core.enums.ApiCode;
import com.wecloud.can.core.util.ApiResult;
import com.wecloud.im.biz.module.rtc.entity.response.RtcCallResponse;
import com.wecloud.im.biz.module.rtc.entity.response.RtcCandidateForwardResponse;
import com.wecloud.im.biz.module.rtc.entity.response.RtcClientJoinResponse;
import com.wecloud.im.biz.module.rtc.entity.response.RtcClientLeaveResponse;
import com.wecloud.im.biz.module.rtc.entity.response.RtcClientRejectResponse;
import com.wecloud.im.biz.module.rtc.entity.response.RtcSdpForwardResponse;
import com.wecloud.im.biz.module.rtc.service.WsRtcWrite;
import com.wecloud.im.server.enums.WsResponseCmdEnum;
import com.wecloud.im.server.enums.WsRtcResponseSubCmdEnum;
import com.wecloud.im.server.model.WsResponse;
import com.wecloud.im.server.sender.ChannelSender;
@Service
public class WsRtcWriteImpl implements WsRtcWrite {
@Autowired
private ChannelSender channelSender;
@Override
public void rtcCall(RtcCallResponse rtcCallResponse, Long toClientId) {
rtcCallResponse.setSubCmd(WsRtcResponseSubCmdEnum.RTC_CALL.getCmdCode());
// 向接收方推送
WsResponse<RtcCallResponse> responseModel = new WsResponse<>();
responseModel.setCmd(WsResponseCmdEnum.SINGLE_RTC_MSG.getCmdCode());
ApiResult<Boolean> result = ApiResult.result(ApiCode.SUCCESS);
responseModel.setCode(result.getCode());
responseModel.setMsg(result.getMessage());
responseModel.setData(rtcCallResponse);
responseModel.setReqId(null);
channelSender.sendMsg(responseModel, toClientId);
}
@Override
public void clientJoin(RtcClientJoinResponse rtcClientJoinResponse, Long toClientId) {
rtcClientJoinResponse.setSubCmd(WsRtcResponseSubCmdEnum.CLIENT_JOIN.getCmdCode());
// 向接收方推送
WsResponse<RtcClientJoinResponse> responseModel = new WsResponse<>();
responseModel.setCmd(WsResponseCmdEnum.SINGLE_RTC_MSG.getCmdCode());
ApiResult<Boolean> result = ApiResult.result(ApiCode.SUCCESS);
responseModel.setCode(result.getCode());
responseModel.setMsg(result.getMessage());
responseModel.setData(rtcClientJoinResponse);
responseModel.setReqId(null);
channelSender.sendMsg(responseModel, toClientId);
}
@Override
public void clientLeave(RtcClientLeaveResponse rtcClientLeaveResponse, Long toClientId) {
rtcClientLeaveResponse.setSubCmd(WsRtcResponseSubCmdEnum.CLIENT_LEAVE.getCmdCode());
// 向接收方推送
WsResponse<RtcClientLeaveResponse> responseModel = new WsResponse<>();
responseModel.setCmd(WsResponseCmdEnum.SINGLE_RTC_MSG.getCmdCode());
ApiResult<Boolean> result = ApiResult.result(ApiCode.SUCCESS);
responseModel.setCode(result.getCode());
responseModel.setMsg(result.getMessage());
responseModel.setData(rtcClientLeaveResponse);
responseModel.setReqId(null);
channelSender.sendMsg(responseModel, toClientId);
}
@Override
public void clientReject(RtcClientRejectResponse rtcClientRejectResponse, Long toClientId) {
rtcClientRejectResponse.setSubCmd(WsRtcResponseSubCmdEnum.CLIENT_REJECT.getCmdCode());
// 向接收方推送
WsResponse<RtcClientRejectResponse> responseModel = new WsResponse<>();
responseModel.setCmd(WsResponseCmdEnum.SINGLE_RTC_MSG.getCmdCode());
ApiResult<Boolean> result = ApiResult.result(ApiCode.SUCCESS);
responseModel.setCode(result.getCode());
responseModel.setMsg(result.getMessage());
responseModel.setData(rtcClientRejectResponse);
responseModel.setReqId(null);
channelSender.sendMsg(responseModel, toClientId);
}
@Override
public void sdpForward(RtcSdpForwardResponse rtcSdpForwardResponse, Long toClientId) {
rtcSdpForwardResponse.setSubCmd(WsRtcResponseSubCmdEnum.SDP_FORWARD.getCmdCode());
// 向接收方推送
WsResponse<RtcSdpForwardResponse> responseModel = new WsResponse<>();
responseModel.setCmd(WsResponseCmdEnum.SINGLE_RTC_MSG.getCmdCode());
ApiResult<Boolean> result = ApiResult.result(ApiCode.SUCCESS);
responseModel.setCode(result.getCode());
responseModel.setMsg(result.getMessage());
responseModel.setData(rtcSdpForwardResponse);
responseModel.setReqId(null);
channelSender.sendMsg(responseModel, toClientId);
}
@Override
public void candidateForward(RtcCandidateForwardResponse rtcCandidateForwardResponse, Long toClientId) {
rtcCandidateForwardResponse.setSubCmd(WsRtcResponseSubCmdEnum.CANDIDATE_FORWARD.getCmdCode());
// 向接收方推送
WsResponse<RtcCandidateForwardResponse> responseModel = new WsResponse<>();
responseModel.setCmd(WsResponseCmdEnum.SINGLE_RTC_MSG.getCmdCode());
ApiResult<Boolean> result = ApiResult.result(ApiCode.SUCCESS);
responseModel.setCode(result.getCode());
responseModel.setMsg(result.getMessage());
responseModel.setData(rtcCandidateForwardResponse);
responseModel.setReqId(null);
channelSender.sendMsg(responseModel, toClientId);
}
}
package com.wecloud.im.biz.module.thousandchat.cache;
import lombok.extern.slf4j.Slf4j;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.wecloud.can.core.util.GetIpUtils;
import com.wecloud.im.biz.module.message.service.ImConversationMembersService;
import com.wecloud.im.server.cache.UserStateListener;
import com.wecloud.im.server.utils.RedisUtils;
/**
* 万人群的缓存(本地缓存待实现)
* @author lixiaozhong
* @date 2022年01月4日 17:00:00
*/
@Service
@Slf4j
public class ThousandChatCacheManager extends UserStateListener {
/**
* redis的群键 key
*/
public static final String GROUP_KEY = "gp:";
@Autowired
private RedisUtils redisUtils;
@Autowired
private ImConversationMembersService imConversationMembersService;
@Override
public void onLineEvent(Long clientId, Integer platform, String longChannelId) {
List<Long> thousandGroupIds = imConversationMembersService.findThousandGroupsByClientId(clientId);
for(Long thousandGroupId : thousandGroupIds) {
redisUtils.hashset(GROUP_KEY + thousandGroupId, clientId + RedisUtils.SPLIT + platform, GetIpUtils.getlanIp(),
150, TimeUnit.DAYS);
}
}
@Override
public void offlineEvent(Long clientId, Integer platform, String longChannelId) {
List<Long> thousandGroupIds = imConversationMembersService.findThousandGroupsByClientId(clientId);
for(Long thousandGroupId : thousandGroupIds) {
redisUtils.hashdel(GROUP_KEY + thousandGroupId, clientId + RedisUtils.SPLIT + platform);
}
}
/**
* 根据群ID 获取 万人群的 在线成员的key-val
* @param conversionId
* @return 在线成员的key-val,其中key是 client的主键id:platform, val是 ip
*/
public Map<String, String> findOnlineClientsByThousandGroupId(Long conversionId) {
return redisUtils.hashgetll(GROUP_KEY + conversionId);
}
/**
* 根据群ID 获取 万人群的 在线成员的ip以及对应的成员信息,key-vaul
* @param conversionId
* @return 在线成员的key-val,其中key是 ip地址, val是 client的主键id:platform
*/
public Map<String, List<String>> findOnlineHostsByThousandGroupId(Long conversionId) {
Map<String /** client的主键ID:platform **/, String /** ip **/> onlineClientIpMap = findOnlineClientsByThousandGroupId(conversionId);
Map<String /** ip **/, List<String /** client的主键ID:platform **/>> onlineIpClientMap = new HashMap<>();
onlineClientIpMap.forEach((clientIdAndPlatforms, ip) -> {
onlineIpClientMap.putIfAbsent(ip, new ArrayList<>());
onlineIpClientMap.get(ip).add(clientIdAndPlatforms);
});
return onlineIpClientMap;
}
}
package com.wecloud.im.biz.module.thousandchat.controller;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.wecloud.can.core.base.controller.BaseController;
import com.wecloud.im.biz.module.thousandchat.service.ThousandChatService;
/**
* 万人群消息处理controller
*/
@Slf4j
@RestController
@RequestMapping("/imState")
@Api(value = "万人群消息处理API", tags = {"万人群消息处理API"})
public class ThousandChatController extends BaseController {
@Autowired
private ThousandChatService thousandChatService;
}
package com.wecloud.im.biz.module.thousandchat.entity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.util.Date;
import javax.validation.constraints.NotNull;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.wecloud.can.core.base.entity.BaseEntity;
/**
* @author lixiaozhong
* 消息最新已读寻址表
*/
@Data
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = true)
@TableName("im_msg_read_lastest")
@ApiModel(value = "ImMsgReadLastest对象")
public class ImMsgReadLastest extends BaseEntity {
private static final long serialVersionUID = 1L;
@NotNull(message = "主键id不能为空")
@ApiModelProperty("主键id")
@TableId(value = "id", type = IdType.INPUT)
private Long id;
@ApiModelProperty("创建时间")
private Date createTime;
@ApiModelProperty("修改时间")
private Date updateTime;
@ApiModelProperty("读取时间")
private Date readTime;
@ApiModelProperty("接收时间")
private Date receiveTime;
@NotNull(message = "应用appid不能为空")
@ApiModelProperty("应用appid")
private Long fkAppid;
@NotNull(message = "接收客户端id不能为空")
@ApiModelProperty("接收客户端id")
private Long fkClientId;
@NotNull(message = "会话id不能为空")
@ApiModelProperty("会话id")
private Long fkConversationId;
@ApiModelProperty("最后一条已接收消息id")
private Long fkReceiveMsgId;
@ApiModelProperty("最后一条已读消息id")
private Long fkReadMsgId;
}
package com.wecloud.im.biz.module.thousandchat.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wecloud.im.biz.module.message.controller.param.ImInboxPageParam;
import com.wecloud.im.biz.module.message.controller.param.ImInboxQueryVo;
import com.wecloud.im.biz.module.thousandchat.entity.ImMsgReadLastest;
import com.wecloud.im.biz.module.thousandchat.param.ConversationLastestReadMsg;
import com.wecloud.im.biz.module.thousandchat.param.ThousandOffineMsgDto;
/**
* @author lixiaozhong
* 主要针对万人群的消息状态处理dao类
*/
@Repository
public interface ImMsgReadLastestMapper extends BaseMapper<ImMsgReadLastest> {
/**
* 获取分页对象
*
* @param page
* @param imInboxPageParam
* @return
*/
IPage<ImInboxQueryVo> getImInboxPageList(@Param("page") Page page, @Param("param") ImInboxPageParam imInboxPageParam);
/**
* 万人群的消息已送达的插入/更新
* @param lastestRead
* @return
*/
Long upsertImMsgReceive(ImMsgReadLastest lastestRead);
/**
* 万人群消息已读的插入/更新
* @param lastestRead
* @return
*/
Long upsertImMsgRead(ImMsgReadLastest lastestRead);
/**
* 查找最新的已读记录,如果查回来是空,表示会话消息全未读
* @param clientId
* @return
*/
List<ConversationLastestReadMsg> findLastestReadMsgs(@Param("clientId") Long clientId);
/**
* 查找万人群的离线消息
* @param allConversationOfLastestReadMsgs
*/
List<ThousandOffineMsgDto> findOfflineMsgs(@Param("lastestMsgs") List<ConversationLastestReadMsg> allConversationOfLastestReadMsgs);
}
package com.wecloud.im.biz.module.thousandchat.param;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import com.wecloud.can.core.base.entity.BaseEntity;
/**
* @author lixiaozhong
* 最新一条只读消息
*/
@Data
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = true)
@ApiModel(value = "ConversationLastestReadMsg")
public class ConversationLastestReadMsg extends BaseEntity {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "最新的一条已读消息")
private Long lastestReadMsgId;
@ApiModelProperty(value = "最新的一条已接收消息")
private Long lastestReceiveMsgId;
@ApiModelProperty(value = "会话id")
private Long conversationId;
}
package com.wecloud.im.biz.module.thousandchat.param;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
import javax.validation.constraints.NotNull;
/**
* @author lixiaozhong
* 最后一条已接收消息
*/
@Data
@Accessors(chain = true)
@ApiModel(value = "LastestReceivedMsg")
public class LastestReceivedMsg implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "消息id,只需要发送最新的一条已接收消息", required = true)
@NotNull(message = "消息ID不能为空")
private Long lastestMsgId;
@ApiModelProperty(value = "是否同时修改为已读状态", required = false)
private Boolean readStatus = false;
}
package com.wecloud.im.biz.module.thousandchat.param;
import lombok.Data;
import com.wecloud.im.biz.module.message.controller.vo.OfflineMsgDto;
/**
* @Description 万人群离线消息dto类
* @Author lixiaozhong
* @Date 2022/1/11 10:00 上午
*/
@Data
public class ThousandOffineMsgDto extends OfflineMsgDto {
}
package com.wecloud.im.biz.scheduled;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import com.wecloud.im.biz.module.multimeet.service.MultiMeetService;
/**
* @Author wenzhida
* @Date 2022/3/28 16:34
* @Description 多人音视频相关定时器
*/
@Slf4j
@Component
public class MultiMeetScheduled {
@Autowired
private MultiMeetService multiMeetService;
/**
* 呼叫超时处理
* 每5秒执行一次
*/
@Scheduled(cron = "*/5 * * * * ?")
public void callingTimeout() {
log.info("呼叫超时处理开始...");
multiMeetService.callingTimeout();
}
/**
* 接听中成员异常断线处理
* 每10秒执行一次 (5秒一次心跳 - 20秒未收到心跳,认为已经异常断开连接)
*/
@Scheduled(cron = "*/10 * * * * ?")
public void disconnect() {
log.info("异常断线处理开始...");
multiMeetService.disconnect();
}
}
package com.wecloud.im.biz.scheduled;
import lombok.extern.slf4j.Slf4j;
import javax.annotation.Resource;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import com.wecloud.im.biz.module.rtc.service.RtcService;
/**
* @Author Future
* @Date 2022/6/3 11:43
* @Description 单人rtc定时器调度
*/
@Slf4j
@Component
public class SingleRtcScheduled {
@Resource
private RtcService rtcService;
/**
* 呼叫异常停止处理 查出正在通话的记录,检测是否在线,如未在线超过5次,按断线处理
*/
@Scheduled(cron = "*/13 * * * * ?")
public void abnormalDisconnect() {
log.info("单人音视频异常断线处理开始...");
rtcService.abnormalDisconnect();
}
}
spring-boot-plus:
# 是否启用ansi控制台输出有颜色的字体,dev环境建议开启,服务器环境设置为false
enable-ansi: true
# 当前环境服务IP地址
server-ip: 127.0.0.1
# 文件上传下载配置
upload-path: /opt/upload/
aop:
log:
enable: true
log-print-type: LINE
request-log-format: false
response-log-format: false
spring:
datasource:
# url: jdbc:mysql://127.0.0.1:3306/wecloud-im?serverTimezone=UTC&useUnicode=true&characterEncoding=utf8&useSSL=false&allowPublicKeyRetrieval=true
# username: root
# password: 123456
# 测试外网
# url: jdbc:mysql://124.71.83.11:3306/wecloud_im?serverTimezone=UTC&useUnicode=true&characterEncoding=utf8&useSSL=false&allowPublicKeyRetrieval=true
url: jdbc:mysql://121.37.22.224:3306/wecloud_im_feature_cluster?serverTimezone=UTC&useUnicode=true&characterEncoding=utf8&useSSL=false&allowPublicKeyRetrieval=true
username: root
password: temple123456
# Redis配置
redis:
# database: 0
# host: 127.0.0.1
# password:
# port: 6379
database: 0
host: 121.37.22.224
password: temple123456
port: 6379
dubbo:
protocol:
port: 20882
name: dubbo
registry:
address: nacos://localhost:8848?username=nacos&password=nacos
# 打印SQL语句和结果集,本地开发环境可开启,线上注释掉
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
# 服务器负载均衡配置
load-blance:
# 服务器运营商local,aws,huawei
server-type: local
# NameServer地址 用;作为地址的分隔符
rocketmq:
namesrvAddr: 121.37.22.224:9876
# 生产者的组名
producerId: im-server
sms:
huawei:
url: https://rtcsms.cn-north-1.myhuaweicloud.com:10743/sms/batchSendSms/v1
sender: 8820122113125
appKey: FKFPgk3X6VRYAMJ9r9CIJWG2709W
appSecret: gvS2S8nD01vKCA1v45qi379gu1T5
verifyCode: 666666
spring-boot-plus:
# 是否启用ansi控制台输出有颜色的字体,dev环境建议开启,服务器环境设置为false
enable-ansi: true
# 当前环境服务IP地址
server-ip: 127.0.0.1
# 文件上传下载配置
upload-path: /opt/upload/
aop:
log:
enable: true
log-print-type: LINE
request-log-format: false
response-log-format: false
spring:
datasource:
url: jdbc:mysql://116.205.173.171:3306/wecloud_im_paas?serverTimezone=UTC&useUnicode=true&characterEncoding=utf8&useSSL=false&allowPublicKeyRetrieval=true
username: web
password: SeTLHCRhmWpizxxRpQcc
#//测试外网
# 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:
database: 0
host: 116.205.173.171
password: alfbiYAUNKgAiE9tSdH1l4idXZIaNDKkgpS84dG9dy8TlACijUTwHYlLwdd6zTng
port: 6379
cloud:
nacos:
discovery:
server-addr: 116.205.173.171:8848
dubbo:
protocol:
port: 20881
name: dubbo
registry:
address: nacos://116.205.173.171:8848?username=nacos&password=nacos
provider:
cluster: channelRouterCluster
consumer:
check: false
# 打印SQL语句和结果集,本地开发环境可开启,线上注释掉
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
# 服务器负载均衡配置
load-blance:
# 服务器运营商local,aws,huawei
server-type: local
# NameServer地址 用;作为地址的分隔符
rocketmq:
namesrvAddr: 116.205.173.171:9876
# 生产者的组名
producerId: im-server
sms:
huawei:
url: https://rtcsms.cn-north-1.myhuaweicloud.com:10743/sms/batchSendSms/v1
sender: 8820122113125
appKey: FKFPgk3X6VRYAMJ9r9CIJWG2709W
appSecret: gvS2S8nD01vKCA1v45qi379gu1T5
verifyCode: 369258
spring-boot-plus:
# 是否启用ansi控制台输出有颜色的字体,dev环境建议开启,服务器环境设置为false
enable-ansi: true
# 当前环境服务IP地址
server-ip: 127.0.0.1
# 文件上传下载配置
upload-path: /opt/upload/
aop:
log:
enable: true
log-print-type: LINE
request-log-format: false
response-log-format: false
spring:
datasource:
url: jdbc:mysql://127.0.0.1:3306/wecloud_im_feature_cluster?serverTimezone=UTC&useUnicode=true&characterEncoding=utf8&useSSL=false&allowPublicKeyRetrieval=true
username: root
password: temple123456
#//测试外网
# 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:
database: 0
host: 127.0.0.1
password: temple123456
port: 6379
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
dubbo:
protocol:
# host: 121.37.22.224
port: 20881
name: dubbo
registry:
address: nacos://127.0.0.1:8848?username=nacos&password=nacos
provider:
cluster: channelRouterCluster
consumer:
check: false
# 打印SQL语句和结果集,本地开发环境可开启,线上注释掉
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
# 服务器负载均衡配置
load-blance:
# 服务器运营商local,aws,huawei
server-type: local
# NameServer地址 用;作为地址的分隔符
rocketmq:
namesrvAddr: 127.0.0.1:9876
# 生产者的组名
producerId: im-server
sms:
huawei:
url: https://rtcsms.cn-north-1.myhuaweicloud.com:10743/sms/batchSendSms/v1
sender: 8820122113125
appKey: FKFPgk3X6VRYAMJ9r9CIJWG2709W
appSecret: gvS2S8nD01vKCA1v45qi379gu1T5
verifyCode: 666666
spring-boot-plus:
# 是否启用ansi控制台输出有颜色的字体,local环境建议开启,服务器环境设置为false
enable-ansi: false
# 当前环境服务IP地址
server-ip:
# AOP配置
aop:
log:
enable: true
log-print-type: LINE
request-log-format: false
response-log-format: false
spring:
datasource:
url:
username:
password:
# Redis配置
redis:
database:
host:
password:
port:
spring-boot-plus:
# 是否启用ansi控制台输出有颜色的字体,dev环境建议开启,服务器环境设置为false
enable-ansi: true
# 当前环境服务IP地址
server-ip: 139.159.136.86
# 文件上传下载配置
upload-path: /opt/upload/
aop:
log:
enable: true
log-print-type: LINE
request-log-format: false
response-log-format: false
spring:
datasource:
url: jdbc:mysql://mysql:3306/wecloud_im?serverTimezone=UTC&useUnicode=true&characterEncoding=utf8&useSSL=false&allowPublicKeyRetrieval=true
username: root
password: temple123456
#//测试外网
# 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:
database: 0
host: redis
# password: f242cy9DtzfKU5qT
port: 6379
cloud:
inetutils:
preferredNetworks:
- 192.168
nacos:
discovery:
server-addr: nacos:8848
dubbo:
protocol:
port: 20881
name: dubbo
registry:
address: nacos://nacos:8848?username=nacos&password=nacos
provider:
cluster: channelRouterCluster
consumer:
check: false
# 打印SQL语句和结果集,本地开发环境可开启,线上注释掉
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
# 服务器负载均衡配置
load-blance:
# 服务器运营商local,aws,huawei
server-type: local
# NameServer地址 用;作为地址的分隔符
rocketmq:
namesrvAddr: 124.71.83.11:9876
# 生产者的组名
producerId: im-server
sms:
huawei:
url: https://rtcsms.cn-north-1.myhuaweicloud.com:10743/sms/batchSendSms/v1
sender: 8820122113125
appKey: FKFPgk3X6VRYAMJ9r9CIJWG2709W
appSecret: gvS2S8nD01vKCA1v45qi379gu1T5
verifyCode: 666666
${AnsiColor.BLUE}
_ _ _ _
(_) | | | | | |
___ _ __ _ __ _ _ __ __ _ ______| |__ ___ ___ | |_ ______ _ __ | |_ _ ___
/ __| '_ \| '__| | '_ \ / _` |______| '_ \ / _ \ / _ \| __|______| '_ \| | | | / __|
\__ \ |_) | | | | | | | (_| | | |_) | (_) | (_) | |_ | |_) | | |_| \__ \
|___/ .__/|_| |_|_| |_|\__, | |_.__/ \___/ \___/ \__| | .__/|_|\__,_|___/
| | __/ | | |
|_| |___/ |_|
${AnsiColor.YELLOW} :: Spring Boot :: ${AnsiColor.WHITE}(v${spring-boot.version})
${AnsiColor.YELLOW} :: spring-boot-plus :: ${AnsiColor.WHITE}(v${project.version})
https://springboot.plus
spring:
profiles:
active: @profileActive@
---
spring:
profiles: dev
cloud:
nacos:
discovery:
server-addr: localhost:8848
userName: "nacos"
password: "nacos"
config:
server-addr: localhost:8848
userName: "nacos"
password: "nacos"
file-extension: yaml
---
spring:
profiles: test
cloud:
nacos:
discovery:
server-addr: localhost:8848
userName: "nacos"
password: "nacos"
config:
server-addr: localhost:8848
userName: "nacos"
password: "nacos"
file-extension: yaml
---
spring:
profiles: prod
cloud:
nacos:
discovery:
server-addr: localhost:8848
userName: "nacos"
password: "nacos"
config:
server-addr: localhost:8848
userName: "nacos"
password: "nacos"
file-extension: yaml
---
spring:
profiles: xhdtest
cloud:
nacos:
discovery:
server-addr: nacos:8848
userName: "nacos"
password: "nacos"
config:
server-addr: nacos:8848
userName: "nacos"
password: "nacos"
file-extension: yaml
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<property name="CONTEXT_NAME" value="spring-boot-plus"/>
<property name="LOG_PATH" value="logs"/>
<property name="MAX_FILE_SIZE" value="1000MB"/>
<property name="MAX_HISTORY" value="30"/>
<contextName>${CONTEXT_NAME}</contextName>
<!-- 彩色日志 -->
<conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter"/>
<conversionRule conversionWord="wex"
converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter"/>
<conversionRule conversionWord="wEx"
converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter"/>
<!-- 控制台日志样式 -->
<property name="CONSOLE_LOG_PATTERN"
value="${CONSOLE_LOG_PATTERN:-%clr(%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr([%15.15t]){faint} [%X{requestId}] %clr(%-40.40logger{39}){cyan} [%L] %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>
<!-- 文件日志样式 -->
<property name="FILE_LOG_PATTERN"
value="${FILE_LOG_PATTERN:-%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}} ${LOG_LEVEL_PATTERN:-%5p} [%t] [%X{requestId}] %-40.40logger{39} %L : %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>
<!-- 禁用logback自身日志输出 -->
<statusListener class="ch.qos.logback.core.status.NopStatusListener"/>
<!-- 控制台 -->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
</encoder>
</appender>
<!-- 运行日志文件 -->
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder>
<pattern>${FILE_LOG_PATTERN}</pattern>
</encoder>
<file>${LOG_PATH}/spring-boot-plus.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${LOG_PATH}/spring-boot-plus-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<maxFileSize>${MAX_FILE_SIZE}</maxFileSize>
<maxHistory>${MAX_HISTORY}</maxHistory>
</rollingPolicy>
</appender>
<!-- 错误日志文件 -->
<appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder>
<pattern>${FILE_LOG_PATTERN}</pattern>
</encoder>
<file>${LOG_PATH}/spring-boot-plus-error.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${LOG_PATH}/spring-boot-plus-error-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<maxFileSize>${MAX_FILE_SIZE}</maxFileSize>
<maxHistory>${MAX_HISTORY}</maxHistory>
</rollingPolicy>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 异步写日志 -->
<appender name="ASYNC_FILE" class="ch.qos.logback.classic.AsyncAppender">
<discardingThreshold>0</discardingThreshold>
<queueSize>1024</queueSize>
<appender-ref ref="FILE"/>
</appender>
<appender name="ASYNC_ERROR_FILE" class="ch.qos.logback.classic.AsyncAppender">
<discardingThreshold>0</discardingThreshold>
<queueSize>1024</queueSize>
<appender-ref ref="ERROR_FILE"/>
</appender>
<!-- 不同环境的日志级别配置 -->
<springProfile name="dev">
<logger name="io.geekidea.springbootplus" level="DEBUG"/>
</springProfile>
<!-- 解决SpringBootAdmin错误日志问题 -->
<logger name="org.apache.catalina.connector.CoyoteAdapter" level="OFF"/>
<root level="INFO">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="ASYNC_FILE"/>
<appender-ref ref="ASYNC_ERROR_FILE"/>
</root>
</configuration>
#
# Copyright 2019-2029 geekidea(https://github.com/geekidea)
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# 扩展mime-type
# 参考:https://svn.apache.org/viewvc/httpd/httpd/trunk/docs/conf/mime.types?revision=1752884&view=co
md=text/markdown
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.wecloud.im.biz.module.message.mapper.ImApplicationMapper">
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
id
, create_time, update_time, app_key, app_secret, app_name, ios_push_channel, android_push_channel,umeng_key,umeng_secret,firebase_secret,repeat_session_status,contrast_extended_field_status
</sql>
<select id="getImApplicationById"
resultType="com.wecloud.im.biz.module.message.controller.param.ImApplicationQueryVo">
select
<include refid="Base_Column_List"/>
from im_application where id = #{id}
</select>
<select id="getImApplicationPageList"
parameterType="com.wecloud.im.biz.module.message.controller.param.ImApplicationPageParam"
resultType="com.wecloud.im.biz.module.message.controller.param.ImApplicationQueryVo">
select
<include refid="Base_Column_List"/>
from im_application
</select>
</mapper>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.wecloud.im.biz.module.message.mapper.ImClientBlacklistMapper">
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
id
, create_time, update_time, fk_appid, client_id_prevent, client_id_be_prevent
</sql>
<select id="getImClientBlacklistById"
resultType="com.wecloud.im.biz.module.message.controller.param.ImClientBlacklistQueryVo">
select
<include refid="Base_Column_List"/>
from im_client_blacklist where id = #{id}
</select>
<select id="getImClientBlacklistPageList"
resultType="com.wecloud.im.biz.module.message.controller.param.ImClientBlacklistQueryVo">
SELECT im_client.client_id AS clientIdBePrevent
FROM im_client_blacklist
INNER JOIN im_client ON im_client.client_id = im_client_blacklist.client_id_be_prevent
WHERE im_client_blacklist.client_id_prevent = #{clientId}
ORDER BY im_client_blacklist.create_time DESC
</select>
</mapper>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.wecloud.im.biz.module.message.mapper.ImClientDeviceMapper">
<update id="removeOldToken">
UPDATE im_client_device
SET device_token = NULL
WHERE device_token = #{deviceToken}
AND fk_appid = #{appId}
</update>
</mapper>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.wecloud.im.biz.module.message.mapper.ImClientMapper">
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
id
, create_time, update_time, fk_appid, attributes,client_id,head_portrait,nickname
</sql>
<select id="getImClientPageList"
parameterType="com.wecloud.im.biz.module.message.controller.param.ImClientPageParam"
resultType="com.wecloud.im.biz.module.message.controller.param.ImClientQueryVo">
select
<include refid="Base_Column_List"/>
from im_client
</select>
<select id="getInfoList" resultType="com.wecloud.im.biz.module.message.controller.vo.GetInfoListVo">
SELECT
im_client.id AS id,
im_client.client_id AS clientId,
im_client.head_portrait AS headPortrait,
im_client.nickname,
(SELECT im_conversation_members.client_remark_name FROM im_conversation_members AS im_conversation_members WHERE
im_conversation_members.fk_conversation_id = #{conversationId} AND im_conversation_members.fk_client_id =
clientId ) AS clientRemarkName ,
(SELECT im_conversation_members.attributes FROM im_conversation_members AS im_conversation_members WHERE
im_conversation_members.fk_conversation_id = #{conversationId} AND im_conversation_members.fk_client_id =
clientId ) AS memberAttributes ,
im_client.attributes AS clientAttributes
FROM
im_client AS im_client
WHERE
im_client.fk_appid = #{appId}
AND im_client.client_id IN
<foreach collection="clientIds" item="clientId" index="index" open="(" close=")" separator=",">
#{clientId}
</foreach>
</select>
<select id="getSimpleClients" resultType="com.wecloud.im.biz.module.message.controller.param.ImClientSimpleDto">
select id, fk_appid, client_id from im_client where fk_appid = #{appId} and client_id in
<foreach collection="clientIds" item="clientId" index="index" open="(" close=")" separator=",">
#{clientId}
</foreach>
</select>
<select id="getSimpleClientsByIds"
resultType="com.wecloud.im.biz.module.message.controller.param.ImClientSimpleDto">
select id, fk_appid, client_id from im_client where id in
<foreach collection="ids" item="id" index="index" open="(" close=")" separator=",">
#{id}
</foreach>
</select>
</mapper>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.wecloud.im.biz.module.message.mapper.ImConversationMembersMapper">
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
id
, create_time, update_time, fk_appid, fk_conversation_id, fk_client_id
</sql>
<select id="getImConversationMembersById"
resultType="com.wecloud.im.biz.module.message.controller.param.ImConversationMembersQueryVo">
select
<include refid="Base_Column_List"/>
from im_conversation_members where id = #{id}
</select>
<select id="getImConversationMembersPageList"
parameterType="com.wecloud.im.biz.module.message.controller.param.ImConversationMembersPageParam"
resultType="com.wecloud.im.biz.module.message.controller.param.ImConversationMembersQueryVo">
select
<include refid="Base_Column_List"/>
from im_conversation_members
</select>
<select id="getRestApiImConversationMembersList"
resultType="com.wecloud.im.biz.module.message.controller.param.ApiImConversationMembersQueryVo">
SELECT im_client.client_id AS clientId
FROM im_conversation_members AS imConversationMembers
INNER JOIN im_client AS im_client ON im_client.id = imConversationMembers.fk_client_id
WHERE fk_conversation_id = #{conversationId}
</select>
<select id="getImConversationMembersList"
resultType="com.wecloud.im.biz.module.message.controller.vo.ConversationMemberVo">
SELECT im_client.client_id as clientId,
im_conversation_members.id as id,
im_conversation_members.client_remark_name as clientRemarkName,
im_client.head_portrait as headPortrait,
im_client.nickname,
im_conversation_members.attributes AS memberAttributes,
im_conversation_members.role AS role,
im_conversation_members.muted AS muted,
im_client.attributes AS clientAttributes
FROM im_conversation_members AS im_conversation_members
INNER JOIN im_client AS im_client ON im_client.id = im_conversation_members.fk_client_id
WHERE im_conversation_members.fk_conversation_id = #{param.conversationId}
<if test="param.roles != null and param.roles.size() > 0">
and im_conversation_members.role in
<foreach collection="param.roles" item="role" index="index" open="(" close=")" separator=",">
#{role}
</foreach>
</if>
<if test="param.clientIds != null and param.clientIds.size() > 0">
and im_client.client_id in
<foreach collection="param.clientIds" item="clientId" index="index" open="(" close=")" separator=",">
#{clientId}
</foreach>
</if>
<if test="param.muted != null">
AND im_conversation_members.muted = #{param.muted}
</if>
</select>
<select id="findThousandGroupsByClientId" resultType="java.lang.Long">
select a.id from im_conversation a
inner join im_conversation_members b on a.id = b.fk_conversation_id
where b.fk_client_id = #{clientId} and a.chat_type = 3
</select>
<update id="setAdminsForConversation">
update im_conversation_members set role = #{role}, update_time=NOW()
where fk_conversation_id = #{conversationId} and fk_client_id in
<foreach collection="fkClientIds" item="fkClientId" index="index" open="(" close=")" separator=",">
#{fkClientId}
</foreach>
</update>
<delete id="deleteByConversationId">
DELETE FROM im_conversation_members WHERE fk_conversation_id = #{conversationId}
</delete>
</mapper>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.wecloud.im.biz.module.message.mapper.ImFriendMapper">
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
id, client_id, client_id_friend, friend_name,reject_remark,request_remark,state,create_time, update_time
</sql>
<select id="getFriendInfo" resultType="com.wecloud.im.biz.module.message.param.ImFriendApplyDto">
select friend.id,
client.client_id as friendClientId,
friend.friend_name,
claimer.client_id as claimerClientId,
friend.reject_remark,
friend.request_remark,
friend.state,
friend.create_time
from im_friend friend
inner join im_client client on friend.client_id_friend = client.client_id
inner join im_client claimer on friend.client_id_claimer = claimer.client_id
where friend.client_id = #{clientId}
and client_id_friend = #{friendClientId}
and friend.state = 2
</select>
<select id="getImFriendPageList" resultType="com.wecloud.im.biz.module.message.param.ImFriendBaseDto">
select friend.id,
client.client_id as friendClientId,
friend.friend_name,
friend.state
from im_friend friend
inner join im_client client on friend.client_id_friend = client.client_id
where friend.client_id = #{clientId}
and friend.state = 2
</select>
<select id="getApplyFriendPageList" resultType="com.wecloud.im.biz.module.message.param.ImFriendApplyDto">
select friend.id,
client.client_id as friendClientId,
friend.friend_name as friendName,
claimer.client_id as claimerClientId,
friend.reject_remark,
friend.request_remark,
friend.state,
friend.update_time,
friend.create_time
from im_friend friend
inner join im_client client on friend.client_id_friend = client.client_id
inner join im_client claimer on friend.client_id_claimer = claimer.client_id
where friend.client_id = #{clientId}
and friend.client_id_claimer != #{clientId}
order by friend.update_time desc
</select>
<select id="filterNegativeFriends" resultType="java.lang.String">
select
client_id_friend
from im_friend
where client_id = #{clientId} and client_id_friend in
<foreach collection="friendClientIds" item="friendClientId" open="(" close=")" separator=",">
#{friendClientId}
</foreach>
</select>
<update id="batchDeleteFriend">
update im_friend set state = 4 where client_id = #{clientId} and client_id_friend in (
select client_id from im_client where (fk_appid, client_id) in
<foreach collection="friendClientIds" item="friendClientId" open="(" close=")" separator=",">
(#{fkAppId}, #{friendClientId})
</foreach>
)
</update>
</mapper>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.wecloud.im.biz.module.message.mapper.ImFriendRecommendMapper">
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
id, client_id, client_id_friend, source, del_flag, create_time, update_time
</sql>
<select id="getImFriendRecommendPageList" resultType="com.wecloud.im.biz.module.message.param.ImFriendRecommendDto">
select recommend.id,
client.client_id as friendClientId,
recommend.source,
recommend.del_flag
from im_friend_recommend recommend
inner join im_client client on recommend.client_id_friend = client.client_id
where client_id = #{clientId}
</select>
<update id="batchDeleteRecommend">
update im_friend_recommend set del_flag = 1 where client_id = #{clientId} and client_id_friend in (
select client_id from im_client where (fk_appid, client_id) in
<foreach collection="friendClientIds" item="friendClientId" open="(" close=")" separator=",">
(#{fkAppId}, #{friendClientId})
</foreach>
)
</update>
<insert id="batchCreateRecommend" >
insert into im_friend_recommend(id, client_id, client_id_friend, source, del_flag, create_time)
values
<foreach collection="list" item="item" separator=",">
(#{item.id},#{item.clientId},#{item.clientIdFriend},#{item.source},#{item.delFlag}, NOW())
</foreach>
ON DUPLICATE KEY UPDATE update_time = now()
</insert>
</mapper>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.wecloud.im.biz.module.message.mapper.ImInboxMapper">
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
id
, create_time, update_time, read_time, receiver_time, fk_appid, receiver, fk_msg_id, read_msg_status, receiver_msg_status, fk_conversation_id
</sql>
<update id="updateImMsgReceivedByIds">
UPDATE im_inbox
SET `im_inbox`.`update_time` = NOW(),
`im_inbox`.`receiver_msg_status` = 1,
`im_inbox`.`receiver_time` = NOW()
WHERE
im_inbox.receiver = #{clientId}
AND im_inbox.fk_msg_id IN
<foreach collection="msgIds" item="deptId" index="i" open="(" close=")" separator=",">
#{deptId}
</foreach>
</update>
<update id="updateImMsgReadByIds">
UPDATE im_inbox
SET `im_inbox`.`update_time` = NOW(),
`im_inbox`.`read_msg_status` = 1,
`im_inbox`.`read_time` = NOW()
WHERE
im_inbox.receiver = #{clientId}
AND im_inbox.fk_msg_id IN
<foreach collection="msgIds" item="deptId" index="i" open="(" close=")" separator=",">
#{deptId}
</foreach>
</update>
<select id="getImInboxById" resultType="com.wecloud.im.biz.module.message.controller.param.ImInboxQueryVo">
select
<include refid="Base_Column_List"/>
from im_Inbox where id = #{id}
</select>
<select id="getImInboxPageList" parameterType="com.wecloud.im.biz.module.message.controller.param.ImInboxPageParam"
resultType="com.wecloud.im.biz.module.message.controller.param.ImInboxQueryVo">
select
<include refid="Base_Column_List"/>
from im_Inbox
</select>
<select id="countMyNotReadCount" resultType="java.lang.Integer">
SELECT COUNT(id)
FROM im_inbox
WHERE receiver = #{clientId}
AND receiver_msg_status = 0
</select>
</mapper>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.wecloud.im.biz.module.message.mapper.ImIosApnsMapper">
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
id
, fk_app_id, apns_file_value, env, bundle_id, pwd
</sql>
<select id="getImIosApnsById" resultType="com.wecloud.im.biz.module.message.controller.param.ImIosApnsQueryVo">
select
<include refid="Base_Column_List"/>
from im_ios_apns where id = #{id}
</select>
<select id="getImIosApnsPageList"
parameterType="com.wecloud.im.biz.module.message.controller.param.ImIosApnsPageParam"
resultType="com.wecloud.im.biz.module.message.controller.param.ImIosApnsQueryVo">
select
<include refid="Base_Column_List"/>
from im_ios_apns
</select>
</mapper>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.wecloud.im.biz.module.thousandchat.mapper.ImMsgReadLastestMapper">
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
id, create_time, update_time, read_time, receive_time, fk_appid, fk_client_id, fk_conversation_id, fk_read_msg_id, fk_receive_msg_id
</sql>
<update id="upsertImMsgReceive">
insert into im_msg_read_lastest(id, create_time, read_time, receive_time, fk_appid, fk_client_id,
fk_conversation_id, fk_read_msg_id, fk_receive_msg_id)
values(#{id}, NOW(), NOW(), NOW(), #{fkAppid}, #{fkClientId}, #{fkConversationId}, #{fkReadMsgId},
#{fkReceiveMsgId})
ON DUPLICATE KEY UPDATE
<if test="fkReadMsgId">
read_time = if(fk_read_msg_id is null or fk_read_msg_id &lt; #{fkReadMsgId}, NOW(), read_time),
fk_read_msg_id = if(fk_read_msg_id is null or fk_read_msg_id &lt; #{fkReadMsgId}, #{fkReadMsgId}, fk_read_msg_id),
</if>
receive_time = if(fk_receive_msg_id is null or fk_receive_msg_id &lt; #{fkReceiveMsgId}, NOW(), receive_time),
fk_receive_msg_id = if(fk_receive_msg_id is null or fk_receive_msg_id &lt; #{fkReceiveMsgId}, #{fkReceiveMsgId}, fk_receive_msg_id)
</update>
<update id="upsertImMsgRead">
insert into im_msg_read_lastest(id, create_time, read_time, fk_appid, fk_client_id, fk_conversation_id, fk_read_msg_id)
values(#{id}, NOW(), NOW(), #{fkAppid}, #{fkClientId}, #{fkConversationId}, #{fkReadMsgId})
ON DUPLICATE KEY UPDATE
read_time = if(fk_read_msg_id is null or fk_read_msg_id &lt; #{fkReadMsgId}, NOW(), read_time),
fk_read_msg_id = if(fk_read_msg_id is null or fk_read_msg_id &lt; #{fkReadMsgId}, #{fkReadMsgId}, fk_read_msg_id)
</update>
<select id="findLastestReadMsgs"
resultType="com.wecloud.im.biz.module.thousandchat.param.ConversationLastestReadMsg">
select fk_conversation_id as conversationId,
fk_read_msg_id as lastestReadMsgId,
fk_receive_msg_id as lastestReceiveMsgId
from im_msg_read_lastest
where fk_client_id = #{clientId}
</select>
<select id="findOfflineMsgs" resultType="com.wecloud.im.biz.module.thousandchat.param.ThousandOffineMsgDto">
<foreach collection="lastestMsgs" item="lastestMsg" separator=" union all ">
select msg.id AS msgId,
msg.create_time,
msg.withdraw_time,
msg.update_date,
client.client_id AS sender,
msg.content,
msg.withdraw,
msg.`event`,
msg.system_flag,
msg.`at`,
msg.send_status,
msg.fk_conversation_id as conversationId,
(SELECT COUNT(a.id) FROM im_message a WHERE a.fk_conversation_id = msg.fk_conversation_id and a.id > #{lastestMsg.lastestReadMsgId})
AS not_read_count,
(SELECT COUNT(b.id) FROM im_message b WHERE b.fk_conversation_id = msg.fk_conversation_id and b.id >= msg.id)
AS not_receiver_count
from im_message msg INNER JOIN `im_client` client ON client.id = msg.sender
where
(and msg.is_delete = 1 and msg.fk_conversation_id = #{lastestMsg.conversationId} and msg.id > #{lastestMsg.lastestReceiveMsgId} )
</foreach>
</select>
</mapper>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.wecloud.im.biz.module.message.mapper.ImMultiRtcRoomMapper">
</mapper>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.wecloud.im.biz.module.message.mapper.ImMultiRtcRoomMemberMapper">
</mapper>
<!--
~ Copyright 2019-2029 geekidea(https://github.com/geekidea)
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>404</title>
</head>
<body>
<h1>Not Found</h1>
</body>
</html>
\ No newline at end of file
<!--
~ Copyright 2019-2029 geekidea(https://github.com/geekidea)
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>500</title>
</head>
<body>
<h1>500</h1>
</body>
</html>
\ No newline at end of file
<!--
~ Copyright 2019-2029 geekidea(https://github.com/geekidea)
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>404</title>
</head>
<body>
<h1>Error</h1>
</body>
</html>
\ No newline at end of file
#/**
#* 操作成功
#**/
api.response.code.SUCCESS=成功
#/**
#* 非法访问
#**/
api.response.code.UNAUTHORIZED=非法访问
#/**
#* 没有权限
#**/
api.response.code.NOT_PERMISSION=没有权限
#/**
#* 你请求的资源不存在
#**/
api.response.code.NOT_FOUND=你请求的资源不存在
#/**
#* 操作失败
#**/
api.response.code.FAIL=操作失败
#/**
#* 登录失败
#**/
api.response.code.LOGIN_EXCEPTION=登录失败
#/**
#* 系统异常
#**/
api.response.code.SYSTEM_EXCEPTION=系统异常
#/**
#* 请求参数校验异常
#**/
api.response.code.PARAMETER_EXCEPTION=请求参数校验异常
#/**
#* 请求参数解析异常
#**/
api.response.code.PARAMETER_PARSE_EXCEPTION=请求参数解析异常
#/**
#* HTTP内容类型异常
#**/
api.response.code.HTTP_MEDIA_TYPE_EXCEPTION=HTTP内容类型异常
#/**
#* 系统处理异常
#**/
api.response.code.SPRING_BOOT_PLUS_EXCEPTION=系统处理异常
#/**
#* 业务处理异常
#**/
api.response.code.BUSINESS_EXCEPTION=业务处理异常
#/**
#* 数据库处理异常
#**/
api.response.code.DAO_EXCEPTION=数据库处理异常
#/**
#* 验证码校验异常
#**/
api.response.code.VERIFICATION_CODE_EXCEPTION=验证码校验异常
#/**
#* 登录授权异常
#**/
api.response.code.AUTHENTICATION_EXCEPTION=登录授权异常
#/**
#* 没有访问权限
#**/
api.response.code.UNAUTHENTICATED_EXCEPTION=没有访问权限
#/**
#* 没有访问权限
#**/
api.response.code.UNAUTHORIZED_EXCEPTION=没有访问权限
#/**
#* JWT Token解析异常
#**/
api.response.code.JWTDECODE_EXCEPTION=Token解析异常
#
#/**
#* 默认的异常处理
#*/
api.response.code.HTTP_REQUEST_METHOD_NOT_SUPPORTED_EXCEPTION=默认的异常处理
api.response.code.user.PWD_OR_USERNAME_ERROR=账号或密码错误
#/**
#* 操作成功
#**/
api.response.code.SUCCESS=success
#/**
#* 非法访问
#**/
api.response.code.UNAUTHORIZED=UNAUTHORIZED
#/**
#* 没有权限
#**/
api.response.code.NOT_PERMISSION=NOT_PERMISSION
#/**
#* 你请求的资源不存在
#**/
api.response.code.NOT_FOUND=NOT_FOUND
#/**
#* 操作失败
#**/
api.response.code.FAIL=FAIL
#/**
#* 登录失败
#**/
api.response.code.LOGIN_EXCEPTION=LOGIN_EXCEPTION
#/**
#* 系统异常
#**/
api.response.code.SYSTEM_EXCEPTION=SYSTEM_EXCEPTION
#/**
#* 请求参数校验异常
#**/
api.response.code.PARAMETER_EXCEPTION=PARAMETER_EXCEPTION
#/**
#* 请求参数解析异常
#**/
api.response.code.PARAMETER_PARSE_EXCEPTION=PARAMETER_PARSE_EXCEPTION
#/**
#* HTTP内容类型异常
#**/
api.response.code.HTTP_MEDIA_TYPE_EXCEPTION=HTTP_MEDIA_TYPE_EXCEPTION
#/**
#* 系统处理异常
#**/
api.response.code.SPRING_BOOT_PLUS_EXCEPTION=SPRING_BOOT_PLUS_EXCEPTION
#/**
#* 业务处理异常
#**/
api.response.code.BUSINESS_EXCEPTION=BUSINESS_EXCEPTION
#/**
#* 数据库处理异常
#**/
api.response.code.DAO_EXCEPTION=DAO_EXCEPTION
#/**
#* 验证码校验异常
#**/
api.response.code.VERIFICATION_CODE_EXCEPTION=VERIFICATION_CODE_EXCEPTION
#/**
#* 登录授权异常
#**/
api.response.code.AUTHENTICATION_EXCEPTION=AUTHENTICATION_EXCEPTION
#/**
#* 没有访问权限
#**/
api.response.code.UNAUTHENTICATED_EXCEPTION=UNAUTHENTICATED_EXCEPTION
#/**
#* 没有访问权限
#**/
api.response.code.UNAUTHORIZED_EXCEPTION=UNAUTHORIZED_EXCEPTION
#/**
#* JWT Token解析异常
#**/
api.response.code.JWTDECODE_EXCEPTION=JWTDECODE_EXCEPTION
#
#/**
#* 默认的异常处理
#*/
api.response.code.HTTP_REQUEST_METHOD_NOT_SUPPORTED_EXCEPTION=HTTP_REQUEST_METHOD_NOT_SUPPORTED_EXCEPTION
api.response.code.user.PWD_OR_USERNAME_ERROR=password or phone number error
api.response.code.user.SMS_CODE_ERROR=sms code error
api.response.code.user.USER_NOT_FOUND=user not found
api.response.code.user.PLAIN_TYPE_NOT_FOUND=plain type not found
api.response.code.user.MC_PLANE_NOT_AVAILABLE=This type of aircraft is not available
api.response.code.user.MC_PLANE_EXISTED=This aircraft already exists
#/**
#* 操作成功
#**/
api.response.code.SUCCESS=SUCCESS
#/**
#* 非法访问
#**/
api.response.code.UNAUTHORIZED=UNAUTHORIZED
#/**
#* 没有权限
#**/
api.response.code.NOT_PERMISSION=NOT_PERMISSION
#/**
#* 你请求的资源不存在
#**/
api.response.code.NOT_FOUND=NOT_FOUND
#/**
#* 操作失败
#**/
api.response.code.FAIL=FAIL
#/**
#* 登录失败
#**/
api.response.code.LOGIN_EXCEPTION=LOGIN_EXCEPTION
#/**
#* 系统异常
#**/
api.response.code.SYSTEM_EXCEPTION=SYSTEM_EXCEPTION
#/**
#* 请求参数校验异常
#**/
api.response.code.PARAMETER_EXCEPTION=PARAMETER_EXCEPTION
#/**
#* 请求参数解析异常
#**/
api.response.code.PARAMETER_PARSE_EXCEPTION=PARAMETER_PARSE_EXCEPTION
#/**
#* HTTP内容类型异常
#**/
api.response.code.HTTP_MEDIA_TYPE_EXCEPTION=HTTP_MEDIA_TYPE_EXCEPTION
#/**
#* 系统处理异常
#**/
api.response.code.SPRING_BOOT_PLUS_EXCEPTION=SPRING_BOOT_PLUS_EXCEPTION
#/**
#* 业务处理异常
#**/
api.response.code.BUSINESS_EXCEPTION=BUSINESS_EXCEPTION
#/**
#* 数据库处理异常
#**/
api.response.code.DAO_EXCEPTION=DAO_EXCEPTION
#/**
#* 验证码校验异常
#**/
api.response.code.VERIFICATION_CODE_EXCEPTION=VERIFICATION_CODE_EXCEPTION
#/**
#* 登录授权异常
#**/
api.response.code.AUTHENTICATION_EXCEPTION=AUTHENTICATION_EXCEPTION
#/**
#* 没有访问权限
#**/
api.response.code.UNAUTHENTICATED_EXCEPTION=UNAUTHENTICATED_EXCEPTION
#/**
#* 没有访问权限
#**/
api.response.code.UNAUTHORIZED_EXCEPTION=UNAUTHORIZED_EXCEPTION
#/**
#* JWT Token解析异常
#**/
api.response.code.JWTDECODE_EXCEPTION=JWTDECODE_EXCEPTION
#
#/**
#* 默认的异常处理
#*/
api.response.code.HTTP_REQUEST_METHOD_NOT_SUPPORTED_EXCEPTION=HTTP_REQUEST_METHOD_NOT_SUPPORTED_EXCEPTION
api.response.code.user.PWD_OR_USERNAME_ERROR=password or phone number error KH
api.response.code.user.SMS_CODE_ERROR=sms code error
api.response.code.user.USER_NOT_FOUND=user not found
\ No newline at end of file
#/**
#* 操作成功
#**/
api.response.code.SUCCESS=成功
#/**
#* 非法访问
#**/
api.response.code.UNAUTHORIZED=非法访问
#/**
#* 没有权限
#**/
api.response.code.NOT_PERMISSION=没有权限
#/**
#* 你请求的资源不存在
#**/
api.response.code.NOT_FOUND=你请求的资源不存在
#/**
#* 操作失败
#**/
api.response.code.FAIL=操作失败
#/**
#* 登录失败
#**/
api.response.code.LOGIN_EXCEPTION=登录失败
#/**
#* 系统异常
#**/
api.response.code.SYSTEM_EXCEPTION=系统异常
#/**
#* 请求参数校验异常
#**/
api.response.code.PARAMETER_EXCEPTION=请求参数校验异常
#/**
#* 请求参数解析异常
#**/
api.response.code.PARAMETER_PARSE_EXCEPTION=请求参数解析异常
#/**
#* HTTP内容类型异常
#**/
api.response.code.HTTP_MEDIA_TYPE_EXCEPTION=HTTP内容类型异常
#/**
#* 系统处理异常
#**/
api.response.code.SPRING_BOOT_PLUS_EXCEPTION=系统处理异常
#/**
#* 业务处理异常
#**/
api.response.code.BUSINESS_EXCEPTION=业务处理异常
#/**
#* 数据库处理异常
#**/
api.response.code.DAO_EXCEPTION=数据库处理异常
#/**
#* 验证码校验异常
#**/
api.response.code.VERIFICATION_CODE_EXCEPTION=验证码校验异常
#/**
#* 登录授权异常
#**/
api.response.code.AUTHENTICATION_EXCEPTION=登录授权异常
#/**
#* 没有访问权限
#**/
api.response.code.UNAUTHENTICATED_EXCEPTION=没有访问权限
#/**
#* 没有访问权限
#**/
api.response.code.UNAUTHORIZED_EXCEPTION=没有访问权限
#/**
#* JWT Token解析异常
#**/
api.response.code.JWTDECODE_EXCEPTION=Token解析异常
#
#/**
#* 默认的异常处理
#*/
api.response.code.HTTP_REQUEST_METHOD_NOT_SUPPORTED_EXCEPTION=默认的异常处理
api.response.code.REPETITION_CONVERSATION=已有会话,不能重复创建会话
api.response.code.CLIENT_NOT_FOUNT=成员不存在,不能创建会话
api.response.code.IS_BE_BLACK=被对方拉黑
api.response.code.IS_TO_BLACK=你把对方拉黑
api.response.code.IS_BE_FORBID_SEND_LINK=????????
api.response.code.IS_BE_FORBID_SEND_PIC=????????
<!--
~ Copyright 2019-2029 geekidea(https://github.com/geekidea)
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>验证码</title>
</head>
<body>
<div>
<p>方式一:获取图片</p>
<img alt="" id="imageCode" onclick="changeImage()" src="http://localhost:8888/verificationCode/getImage">
<p>verifyToken:查看Responses Headers</p>
</div>
<hr>
<div>
<p>方式二:获取base64图片编码</p>
<img alt="" id="base64ImageCode" onclick="changeBase64Image()" src="">
<p id="verifyToken"></p>
</div>
<script type="text/javascript">
function changeImage() {
document.getElementById('imageCode').src = "http://localhost:8888/api/verificationCode/getImage?time=" + System.currentTimeMillis();
}
var url = "http://localhost:8888/api/verificationCode/getBase64Image";
function changeBase64Image() {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && xhr.status == 200) {
var result = JSON.parse(xhr.responseText);
document.getElementById('base64ImageCode').src = result.data.image;
document.getElementById('verifyToken').innerText = "verifyToken:" + result.data.verifyToken;
}
};
xhr.open("GET", url, true);
xhr.send(null);
}
changeBase64Image();
</script>
</body>
</html>
\ No newline at end of file
<!--
~ Copyright 2019-2029 geekidea(https://github.com/geekidea)
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Welcome to spring-boot-plus</title>
</head>
<body>
<h1>Welcome to spring-boot-plus</h1>
<h3>
<a href="https://github.com/geekidea/spring-boot-plus" target="_blank">GITHUB</a>
</h3>
<h3>
<a href="https://gitee.com/geekidea/spring-boot-plus" target="_blank">GITEE</a>
</h3>
<h2>
<a href="https://springboot.plus" target="_blank">springboot.plus</a>
</h2>
</body>
</html>
\ No newline at end of file
...@@ -32,13 +32,6 @@ ...@@ -32,13 +32,6 @@
<version>2.11.3</version> <version>2.11.3</version>
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.22</version>
<scope>compile</scope>
</dependency>
</dependencies> </dependencies>
<build> <build>
......
package com.wecloud.imserver.client.model.dto; package com.wecloud.imserver.client.model.dto;
import com.fasterxml.jackson.annotation.JsonIgnore;
import java.io.Serializable; import java.io.Serializable;
import com.fasterxml.jackson.annotation.JsonIgnore;
/** /**
* @Author wenzhida * @Author wenzhida
* @Date 2022/1/27 16:11 * @Date 2022/1/27 16:11
......
...@@ -29,8 +29,8 @@ ...@@ -29,8 +29,8 @@
<module>im-sdk</module> <module>im-sdk</module>
<module>im-server</module> <module>im-server</module>
<module>im-app</module> <module>im-app</module>
<module>im-biz</module> <module>im-paas-biz</module>
<module>im-biz-client</module> <module>im-paas-client</module>
</modules> </modules>
<dependencies> <dependencies>
......
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