REQ-3345: 群成员
This commit is contained in:
parent
9e63599dac
commit
2a0b772a12
@ -4,8 +4,11 @@ import cn.axzo.framework.domain.web.result.ApiResult;
|
||||
import cn.axzo.im.center.api.vo.req.GroupAddMembersRequest;
|
||||
import cn.axzo.im.center.api.vo.req.GroupCreateRequest;
|
||||
import cn.axzo.im.center.api.vo.req.GroupDismissRequest;
|
||||
import cn.axzo.im.center.api.vo.req.GroupGetMembersRequest;
|
||||
import cn.axzo.im.center.api.vo.req.GroupRemoveMembersRequest;
|
||||
import cn.axzo.im.center.api.vo.resp.GroupAddMembersResponse;
|
||||
import cn.axzo.im.center.api.vo.resp.GroupCreateResponse;
|
||||
import cn.axzo.im.center.api.vo.resp.GroupGetMembersResponse;
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
@ -19,13 +22,34 @@ public interface GroupApi {
|
||||
|
||||
String INTRODUCE_MESSAGE = "邀请您加入群聊";
|
||||
|
||||
/**
|
||||
* 创建群
|
||||
*/
|
||||
@PostMapping("/api/im/group/createGroup")
|
||||
ApiResult<GroupCreateResponse> createGroup(@RequestBody @Validated GroupCreateRequest request);
|
||||
|
||||
/**
|
||||
* 解散群
|
||||
*/
|
||||
@PostMapping("/api/im/group/dismissGroup")
|
||||
ApiResult<Void> dismissGroup(@RequestBody @Validated GroupDismissRequest request);
|
||||
|
||||
/**
|
||||
* 添加群成员
|
||||
*/
|
||||
@PostMapping("/api/im/group/addMembers")
|
||||
ApiResult<GroupAddMembersResponse> addMembers(@RequestBody @Validated GroupAddMembersRequest request);
|
||||
|
||||
/**
|
||||
* 移除群成员
|
||||
*/
|
||||
@PostMapping("/api/im/group/removeMembers")
|
||||
ApiResult<Void> removeMembers(@RequestBody @Validated GroupRemoveMembersRequest request);
|
||||
|
||||
/**
|
||||
* 获取群成员列表
|
||||
*/
|
||||
@PostMapping("/api/im/group/getMembers")
|
||||
ApiResult<GroupGetMembersResponse> getMembers(@RequestBody @Validated GroupGetMembersRequest request);
|
||||
|
||||
}
|
||||
@ -76,12 +76,14 @@ public class PersonAccountAttribute {
|
||||
public boolean equals(Object o) {
|
||||
if (!(o instanceof PersonAccountAttribute)) return false;
|
||||
PersonAccountAttribute that = (PersonAccountAttribute) o;
|
||||
return Objects.equals(personId, that.personId) && Objects.equals(ouId, that.ouId) && appType == that.appType;
|
||||
return Objects.equals(personId, that.personId)
|
||||
&& Objects.equals(ouIdOrDefault(), that.ouIdOrDefault())
|
||||
&& appType == that.appType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(personId, ouId, appType);
|
||||
return Objects.hash(personId, ouIdOrDefault(), appType);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -0,0 +1,64 @@
|
||||
package cn.axzo.im.center.api.vo.group;
|
||||
|
||||
import cn.axzo.im.center.common.enums.GroupType;
|
||||
import cn.axzo.im.center.common.enums.YesOrNo;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* @author yanglin
|
||||
*/
|
||||
@Setter
|
||||
@Getter
|
||||
public class GroupInfo {
|
||||
/**
|
||||
* 群id
|
||||
*/
|
||||
private Long tid;
|
||||
/**
|
||||
* 群名称
|
||||
*/
|
||||
private String name;
|
||||
/**
|
||||
* 群业务id
|
||||
*/
|
||||
private String bizCode;
|
||||
/**
|
||||
* 群类型. VISA: 变洽签, WORKSPACE: 项目群, WORKSPACE_OU: 项目单位群, WORKSPACE_TEAM: 项目班组群
|
||||
*/
|
||||
private GroupType type;
|
||||
/**
|
||||
* 群头像
|
||||
*/
|
||||
private String avatar;
|
||||
/**
|
||||
* 群成员数量
|
||||
*/
|
||||
private Long memberCount;
|
||||
/**
|
||||
* 群成员上限
|
||||
*/
|
||||
private Long memberLimit;
|
||||
/**
|
||||
* 群主账号
|
||||
*/
|
||||
private String ownerAccount;
|
||||
/**
|
||||
* 群主personId
|
||||
*/
|
||||
private Long ownerPersonId;
|
||||
/**
|
||||
* 群创建人ouId
|
||||
*/
|
||||
private Long createPersonId;
|
||||
/**
|
||||
* 是否解散
|
||||
*/
|
||||
private YesOrNo isDismissed;
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
private Date createAt;
|
||||
}
|
||||
@ -0,0 +1,25 @@
|
||||
package cn.axzo.im.center.api.vo.group;
|
||||
|
||||
import cn.axzo.im.center.common.enums.AppTypeEnum;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* @author yanglin
|
||||
*/
|
||||
@Setter
|
||||
@Getter
|
||||
public class GroupMemberInfo {
|
||||
/**
|
||||
* 群成员personId
|
||||
*/
|
||||
private Long personId;
|
||||
/**
|
||||
* 群成员ouId
|
||||
*/
|
||||
private Long personOuId;
|
||||
/**
|
||||
* 群成员端类型
|
||||
*/
|
||||
private AppTypeEnum appType;
|
||||
}
|
||||
@ -1,13 +1,10 @@
|
||||
package cn.axzo.im.center.api.vo.mq;
|
||||
|
||||
import cn.axzo.im.center.common.enums.AppTypeEnum;
|
||||
import cn.axzo.im.center.common.enums.GroupType;
|
||||
import cn.axzo.im.center.common.enums.YesOrNo;
|
||||
import cn.axzo.im.center.api.vo.group.GroupInfo;
|
||||
import cn.axzo.im.center.api.vo.group.GroupMemberInfo;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* @author yanglin
|
||||
*/
|
||||
@ -17,41 +14,11 @@ public class GroupMembersChangeMessage extends MqMessage {
|
||||
/**
|
||||
* 群信息
|
||||
*/
|
||||
private GroupInfo groupInfo;
|
||||
private GroupInfo group;
|
||||
|
||||
/**
|
||||
* 账号信息
|
||||
* 群成员信息
|
||||
*/
|
||||
private AccountInfo account;
|
||||
private GroupMemberInfo member;
|
||||
|
||||
@Setter @Getter
|
||||
public static class GroupInfo {
|
||||
private Long id;
|
||||
private Long tid;
|
||||
private String name;
|
||||
private String bizCode;
|
||||
private GroupType type;
|
||||
private String avatar;
|
||||
private Long memberCount;
|
||||
private Long memberLimit;
|
||||
private String ownerAccount;
|
||||
private Long ownerPersonId;
|
||||
private Long createPersonId;
|
||||
private YesOrNo isDismissed;
|
||||
private Date createAt;
|
||||
private Date updateAt;
|
||||
}
|
||||
|
||||
@Setter @Getter
|
||||
public static class AccountInfo {
|
||||
private Long id;
|
||||
private Long tid;
|
||||
private String imAccount;
|
||||
private Long personId;
|
||||
private Long personOuId;
|
||||
private AppTypeEnum appType;
|
||||
private YesOrNo isRobot;
|
||||
private Date createAt;
|
||||
private Date updateAt;
|
||||
}
|
||||
}
|
||||
@ -1,12 +1,10 @@
|
||||
package cn.axzo.im.center.api.vo.req;
|
||||
|
||||
import cn.axzo.im.center.api.feign.GroupApi;
|
||||
import cn.axzo.im.center.api.vo.PersonAccountAttribute;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.HashSet;
|
||||
@ -22,12 +20,6 @@ public class GroupAddMembersRequest {
|
||||
@NotNull(message = "群ID不能为空")
|
||||
private Long tid;
|
||||
|
||||
/**
|
||||
* 邀请发送的文字,最大长度 150 位字符
|
||||
*/
|
||||
@NotBlank(message = "邀请发送的文字不能为空")
|
||||
private String introduceMessage = GroupApi.INTRODUCE_MESSAGE;
|
||||
|
||||
/**
|
||||
* 群成员, 不包含群主. members数量不能超过199
|
||||
*/
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
package cn.axzo.im.center.api.vo.req;
|
||||
|
||||
import cn.axzo.im.center.api.feign.GroupApi;
|
||||
import cn.axzo.im.center.api.vo.PersonAccountAttribute;
|
||||
import cn.axzo.im.center.common.enums.GroupType;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
@ -55,12 +54,6 @@ public class GroupCreateRequest {
|
||||
*/
|
||||
private Long memberLimit;
|
||||
|
||||
/**
|
||||
* 邀请发送的文字,最大长度 150 位字符
|
||||
*/
|
||||
@NotBlank(message = "邀请发送的文字不能为空")
|
||||
private String introduceMessage = GroupApi.INTRODUCE_MESSAGE;
|
||||
|
||||
/**
|
||||
* 群头像,最大长度 1024 位字符
|
||||
*/
|
||||
|
||||
@ -0,0 +1,18 @@
|
||||
package cn.axzo.im.center.api.vo.req;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* @author yanglin
|
||||
*/
|
||||
@Setter
|
||||
@Getter
|
||||
public class GroupGetMembersRequest {
|
||||
|
||||
@NotNull(message = "群ID不能为空")
|
||||
private Long tid;
|
||||
|
||||
}
|
||||
@ -0,0 +1,27 @@
|
||||
package cn.axzo.im.center.api.vo.req;
|
||||
|
||||
import cn.axzo.im.center.api.vo.PersonAccountAttribute;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author yanglin
|
||||
*/
|
||||
@Setter
|
||||
@Getter
|
||||
public class GroupRemoveMembersRequest {
|
||||
|
||||
@NotNull(message = "群ID不能为空")
|
||||
private Long tid;
|
||||
|
||||
/**
|
||||
* 一次性最多传200个
|
||||
*/
|
||||
@NotEmpty(message = "群成员不能为空")
|
||||
private Set<PersonAccountAttribute> members;
|
||||
|
||||
}
|
||||
@ -93,7 +93,7 @@ public class SendTemplateMessageParam {
|
||||
|
||||
public Long determineSenderOuId() {
|
||||
if (sender != null)
|
||||
return sender.getOuId();
|
||||
return sender.ouIdOrDefault();
|
||||
return 0L;
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,19 @@
|
||||
package cn.axzo.im.center.api.vo.resp;
|
||||
|
||||
import cn.axzo.im.center.api.vo.group.GroupMemberInfo;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author yanglin
|
||||
*/
|
||||
@Setter
|
||||
@Getter
|
||||
public class GroupGetMembersResponse {
|
||||
/**
|
||||
* 群成员信息列表
|
||||
*/
|
||||
private List<GroupMemberInfo> member;
|
||||
}
|
||||
@ -12,6 +12,8 @@ import cn.axzo.im.channel.netease.dto.NimGroupDismissRequest;
|
||||
import cn.axzo.im.channel.netease.dto.NimGroupDismissResponse;
|
||||
import cn.axzo.im.channel.netease.dto.NimGroupGetInfoRequest;
|
||||
import cn.axzo.im.channel.netease.dto.NimGroupGetInfoResponse;
|
||||
import cn.axzo.im.channel.netease.dto.NimGroupRemoveMembersRequest;
|
||||
import cn.axzo.im.channel.netease.dto.NimGroupRemoveMembersResponse;
|
||||
import cn.axzo.im.channel.netease.dto.NimQueryEventRequest;
|
||||
import cn.axzo.im.channel.netease.dto.NimQueryEventResponse;
|
||||
import cn.axzo.im.channel.netease.dto.NimQueryMessageRequest;
|
||||
@ -76,6 +78,9 @@ public interface NimClient {
|
||||
@PostMapping(value = "/team/add.action")
|
||||
NimGroupAddMembersResponse addMembers(NimGroupAddMembersRequest request);
|
||||
|
||||
@PostMapping(value = "/team/kick.action")
|
||||
NimGroupRemoveMembersResponse removeMembers(NimGroupRemoveMembersRequest request);
|
||||
|
||||
@Data
|
||||
class NimCodeResponse {
|
||||
private Integer code;
|
||||
|
||||
@ -0,0 +1,27 @@
|
||||
package cn.axzo.im.channel.netease.dto;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* @author yanglin
|
||||
*/
|
||||
@Setter
|
||||
@Getter
|
||||
public class GroupMemberRequest {
|
||||
|
||||
private String members;
|
||||
|
||||
public void addMembers(Collection<String> members) {
|
||||
if (StringUtils.isBlank(this.members))
|
||||
this.members = "[]";
|
||||
this.members = JSON.parseArray(this.members)
|
||||
.fluentAddAll(members)
|
||||
.toJSONString();
|
||||
}
|
||||
|
||||
}
|
||||
@ -2,31 +2,21 @@ package cn.axzo.im.channel.netease.dto;
|
||||
|
||||
import cn.axzo.im.channel.netease.client.FormRequest;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import lombok.Data;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.Collection;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* @author yanglin
|
||||
*/
|
||||
@Data
|
||||
@Setter
|
||||
@Getter
|
||||
@FormRequest
|
||||
public class NimGroupAddMembersRequest {
|
||||
public class NimGroupAddMembersRequest extends GroupMemberRequest {
|
||||
|
||||
private Long tid;
|
||||
private String owner;
|
||||
private String members;
|
||||
private String msg;
|
||||
|
||||
public void addMembers(Collection<String> members) {
|
||||
if (StringUtils.isBlank(this.members))
|
||||
this.members = "[]";
|
||||
this.members = JSON.parseArray(this.members)
|
||||
.fluentAddAll(members)
|
||||
.toJSONString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return JSON.toJSONString(this);
|
||||
|
||||
@ -3,17 +3,16 @@ package cn.axzo.im.channel.netease.dto;
|
||||
import cn.axzo.im.channel.netease.client.FormRequest;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.annotation.JSONField;
|
||||
import lombok.Data;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* @author yanglin
|
||||
*/
|
||||
@Data
|
||||
@Setter @Getter
|
||||
@FormRequest
|
||||
public class NimGroupCreateRequest {
|
||||
public class NimGroupCreateRequest extends GroupMemberRequest {
|
||||
|
||||
/**
|
||||
* 群名称,最大长度 64 位字符
|
||||
@ -26,12 +25,6 @@ public class NimGroupCreateRequest {
|
||||
*/
|
||||
private String owner;
|
||||
|
||||
/**
|
||||
* 邀请的群成员列表,\["aaa","bbb"\](JSONArray 对应的 accid,如果解析出错会报 414)
|
||||
* members 与 owner 总和上限为 200。members 中无需再加 owner 自己的账号
|
||||
*/
|
||||
private String members;
|
||||
|
||||
/**
|
||||
* 群描述,最大长度 512 位字符
|
||||
*/
|
||||
@ -93,14 +86,6 @@ public class NimGroupCreateRequest {
|
||||
*/
|
||||
private String attach;
|
||||
|
||||
public void addMembers(Collection<String> members) {
|
||||
if (StringUtils.isBlank(this.members))
|
||||
this.members = "[]";
|
||||
this.members = JSON.parseArray(this.members)
|
||||
.fluentAddAll(members)
|
||||
.toJSONString();
|
||||
}
|
||||
|
||||
public void addAttachment(String key, Object value) {
|
||||
if (StringUtils.isBlank(this.attach))
|
||||
this.attach = "{}";
|
||||
|
||||
@ -0,0 +1,22 @@
|
||||
package cn.axzo.im.channel.netease.dto;
|
||||
|
||||
import cn.axzo.im.channel.netease.client.FormRequest;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* @author yanglin
|
||||
*/
|
||||
@Setter
|
||||
@Getter
|
||||
@FormRequest
|
||||
public class NimGroupRemoveMembersRequest extends GroupMemberRequest {
|
||||
private Long tid;
|
||||
private String owner;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return JSON.toJSONString(this);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,21 @@
|
||||
package cn.axzo.im.channel.netease.dto;
|
||||
|
||||
import cn.axzo.im.channel.netease.client.NimClient;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* @author yanglin
|
||||
*/
|
||||
@Setter
|
||||
@Getter
|
||||
public class NimGroupRemoveMembersResponse extends NimClient.NimCodeResponse {
|
||||
private JSONObject faccid;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return JSON.toJSONString(this);
|
||||
}
|
||||
}
|
||||
@ -1,12 +1,16 @@
|
||||
package cn.axzo.im.controller;
|
||||
|
||||
import cn.axzo.im.center.api.vo.req.GroupAddMembersRequest;
|
||||
import cn.axzo.im.center.api.vo.req.GroupCreateRequest;
|
||||
import cn.axzo.im.center.api.vo.req.GroupDismissRequest;
|
||||
import cn.axzo.im.center.api.vo.req.GroupRemoveMembersRequest;
|
||||
import cn.axzo.im.center.api.vo.req.SendMessageParam;
|
||||
import cn.axzo.im.channel.netease.client.NimClient;
|
||||
import cn.axzo.im.channel.netease.dto.NimGroupDismissRequest;
|
||||
import cn.axzo.im.channel.netease.dto.NimGroupGetInfoRequest;
|
||||
import cn.axzo.im.channel.netease.dto.NimQueryEventRequest;
|
||||
import cn.axzo.im.channel.netease.dto.NimQueryMessageRequest;
|
||||
import cn.axzo.im.channel.netease.dto.NimRevokeMessageRequest;
|
||||
import cn.axzo.im.group.GroupManager;
|
||||
import cn.axzo.im.job.CreateMessageHistoryJob;
|
||||
import cn.axzo.im.job.ExpungeImTaskJob;
|
||||
import cn.axzo.im.job.RevokeAllMessagesJob;
|
||||
@ -34,6 +38,7 @@ public class PrivateController {
|
||||
private final CreateMessageHistoryJob createMessageHistoryJob;
|
||||
private final MessageController messageController;
|
||||
private final ExpungeImTaskJob expungeImTaskJob;
|
||||
private final GroupManager groupManager;
|
||||
|
||||
@PostMapping("/private/revoke")
|
||||
public Object revoke(@Valid @RequestBody NimRevokeMessageRequest request) {
|
||||
@ -76,9 +81,27 @@ public class PrivateController {
|
||||
return CommonResponse.success(count);
|
||||
}
|
||||
|
||||
@PostMapping("/private/group/createGroup")
|
||||
public Object createGroup(@Valid @RequestBody GroupCreateRequest request) {
|
||||
return CommonResponse.success(groupManager.createGroup(request));
|
||||
}
|
||||
|
||||
@PostMapping("/private/group/dismissGroup")
|
||||
public Object dismissGroup(@Valid @RequestBody NimGroupDismissRequest request) {
|
||||
return CommonResponse.success(nimClient.dismissGroup(request));
|
||||
public Object dismissGroup(@Valid @RequestBody GroupDismissRequest request) {
|
||||
groupManager.dismissGroup(request);
|
||||
return CommonResponse.success();
|
||||
}
|
||||
|
||||
@PostMapping("/private/group/addMembers")
|
||||
public Object addMembers(@Valid @RequestBody GroupAddMembersRequest request) {
|
||||
groupManager.addMembers(request);
|
||||
return CommonResponse.success();
|
||||
}
|
||||
|
||||
@PostMapping("/private/group/removeMembers")
|
||||
public Object removeMembers(@Valid @RequestBody GroupRemoveMembersRequest request) {
|
||||
groupManager.removeMembers(request);
|
||||
return CommonResponse.success();
|
||||
}
|
||||
|
||||
@PostMapping("/private/group/getGroupInfo")
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
package cn.axzo.im.dao.mapper;
|
||||
|
||||
import cn.axzo.im.entity.GroupAccount;
|
||||
import cn.axzo.im.entity.GroupMember;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
|
||||
/**
|
||||
* @author yanglin
|
||||
*/
|
||||
public interface GroupAccountMapper extends BaseMapper<GroupAccount> {
|
||||
public interface GroupMapperMapper extends BaseMapper<GroupMember> {
|
||||
}
|
||||
@ -1,28 +0,0 @@
|
||||
package cn.axzo.im.dao.repository;
|
||||
|
||||
import cn.axzo.im.dao.mapper.GroupAccountMapper;
|
||||
import cn.axzo.im.entity.GroupAccount;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author yanglin
|
||||
*/
|
||||
@Repository("groupAccountDao")
|
||||
public class GroupAccountDao extends ServiceImpl<GroupAccountMapper, GroupAccount> {
|
||||
|
||||
public List<GroupAccount> getByTid(Long tid) {
|
||||
return lambdaQuery()
|
||||
.eq(GroupAccount::getTid, tid)
|
||||
.list();
|
||||
}
|
||||
|
||||
public void deleteAccounts(Long tid) {
|
||||
lambdaUpdate()
|
||||
.eq(GroupAccount::getTid, tid)
|
||||
.remove();
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,64 @@
|
||||
package cn.axzo.im.dao.repository;
|
||||
|
||||
import cn.axzo.im.center.api.vo.PersonAccountAttribute;
|
||||
import cn.axzo.im.dao.mapper.GroupMapperMapper;
|
||||
import cn.axzo.im.entity.GroupMember;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import static java.util.stream.Collectors.toSet;
|
||||
|
||||
/**
|
||||
* @author yanglin
|
||||
*/
|
||||
@Repository("groupMemberDao")
|
||||
public class GroupMemberDao extends ServiceImpl<GroupMapperMapper, GroupMember> {
|
||||
|
||||
public void deleteAccounts(Long tid) {
|
||||
lambdaUpdate()
|
||||
.eq(GroupMember::getTid, tid)
|
||||
.remove();
|
||||
}
|
||||
|
||||
public Set<PersonAccountAttribute> getGroupPersons(Long tid) {
|
||||
return getByTid(tid).stream()
|
||||
.map(account -> {
|
||||
PersonAccountAttribute person = new PersonAccountAttribute();
|
||||
person.setPersonId(account.getPersonId() + "");
|
||||
person.setOuId(account.getPersonOuId());
|
||||
person.setAppType(account.getAppType());
|
||||
return person;
|
||||
})
|
||||
.collect(toSet());
|
||||
}
|
||||
|
||||
public List<GroupMember> getByTid(Long tid) {
|
||||
return lambdaQuery()
|
||||
.eq(GroupMember::getTid, tid)
|
||||
.list();
|
||||
}
|
||||
|
||||
public List<GroupMember> getByPersons(
|
||||
Long tid, Collection<PersonAccountAttribute> persons) {
|
||||
if (CollectionUtils.isEmpty(persons))
|
||||
return Collections.emptyList();
|
||||
return lambdaQuery()
|
||||
.eq(GroupMember::getTid, tid)
|
||||
.nested(wrapper -> {
|
||||
for (PersonAccountAttribute person : persons) {
|
||||
wrapper.or()
|
||||
.eq(GroupMember::getPersonId, Long.parseLong(person.getPersonId()))
|
||||
.eq(GroupMember::getPersonOuId, person.ouIdOrDefault())
|
||||
.eq(GroupMember::getAppType, person.getAppType());
|
||||
}
|
||||
})
|
||||
.list();
|
||||
}
|
||||
|
||||
}
|
||||
@ -13,8 +13,8 @@ import java.util.Date;
|
||||
*/
|
||||
@Setter
|
||||
@Getter
|
||||
@TableName(value = "im_group_account", autoResultMap = true)
|
||||
public class GroupAccount {
|
||||
@TableName(value = "im_group_member", autoResultMap = true)
|
||||
public class GroupMember {
|
||||
private Long id;
|
||||
private Long tid;
|
||||
private String imAccount;
|
||||
@ -3,12 +3,13 @@ package cn.axzo.im.group;
|
||||
import cn.axzo.basics.common.BeanMapper;
|
||||
import cn.axzo.framework.rocketmq.Event;
|
||||
import cn.axzo.im.center.api.vo.mq.GroupMembersChangeMessage;
|
||||
import cn.axzo.im.center.api.vo.req.GroupInfo;
|
||||
import cn.axzo.im.center.api.vo.mq.GroupMembersChangeMessage.MemberInfo;
|
||||
import cn.axzo.im.config.MqProducer;
|
||||
import cn.axzo.im.dao.repository.GroupDao;
|
||||
import cn.axzo.im.entity.Group;
|
||||
import cn.axzo.im.entity.GroupAccount;
|
||||
import cn.axzo.im.entity.GroupMember;
|
||||
import cn.axzo.im.event.inner.EventTypeEnum;
|
||||
import cn.axzo.im.group.domain.GroupMembersDiff;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@ -24,27 +25,26 @@ class GroupBroadcaster {
|
||||
private final MqProducer mqProducer;
|
||||
private final GroupDao groupDao;
|
||||
|
||||
void fireMembersAdded(Group group, GroupMembersDiff diff) {
|
||||
diff.diff();
|
||||
fireMembersChanged(group, diff.getAdded(), EventTypeEnum.GROUP_ADD_MEMBERS);
|
||||
void fireMembersAdded(Group group, Collection<GroupMember> accounts) {
|
||||
fireMembersChanged(group, accounts, EventTypeEnum.GROUP_ADD_MEMBERS);
|
||||
}
|
||||
|
||||
void fireMembersRemoved(Group group, GroupMembersDiff diff) {
|
||||
diff.diff();
|
||||
fireMembersChanged(group, diff.getRemoved(), EventTypeEnum.GROUP_REMOVE_MEMBERS);
|
||||
void fireMembersRemoved(Group group, Collection<GroupMember> accounts) {
|
||||
fireMembersChanged(group, accounts, EventTypeEnum.GROUP_REMOVE_MEMBERS);
|
||||
}
|
||||
|
||||
private void fireMembersChanged(Group group, Collection<GroupAccount> accounts, EventTypeEnum eventType) {
|
||||
private void fireMembersChanged(Group group, Collection<GroupMember> accounts, EventTypeEnum eventType) {
|
||||
if (accounts.isEmpty()) return;
|
||||
Group effectiveGroup = groupDao.getById(group.getId());
|
||||
for (GroupAccount account : accounts) {
|
||||
for (GroupMember account : accounts) {
|
||||
GroupMembersChangeMessage message = new GroupMembersChangeMessage();
|
||||
message.setGroupInfo(BeanMapper.copyBean(effectiveGroup, GroupMembersChangeMessage.GroupInfo.class));
|
||||
message.setAccount(BeanMapper.copyBean(account, GroupMembersChangeMessage.AccountInfo.class));
|
||||
message.setGroup(BeanMapper.copyBean(effectiveGroup, GroupInfo.class));
|
||||
message.setMember(BeanMapper.copyBean(account, MemberInfo.class));
|
||||
Event event = Event.builder()
|
||||
.targetId(account.getImAccount())
|
||||
.targetId(String.format("%d:%d", group.getTid(), account.getPersonId()))
|
||||
.targetType(eventType.getModel())
|
||||
.eventCode(eventType.getEventCode())
|
||||
.shardingKey(group.getId() + "")
|
||||
.data(message)
|
||||
.build();
|
||||
mqProducer.send(event);
|
||||
|
||||
@ -1,16 +1,25 @@
|
||||
package cn.axzo.im.group;
|
||||
|
||||
import cn.axzo.basics.common.BeanMapper;
|
||||
import cn.axzo.framework.domain.web.result.ApiResult;
|
||||
import cn.axzo.im.center.api.feign.GroupApi;
|
||||
import cn.axzo.im.center.api.vo.group.GroupMemberInfo;
|
||||
import cn.axzo.im.center.api.vo.req.GroupAddMembersRequest;
|
||||
import cn.axzo.im.center.api.vo.req.GroupCreateRequest;
|
||||
import cn.axzo.im.center.api.vo.req.GroupDismissRequest;
|
||||
import cn.axzo.im.center.api.vo.req.GroupGetMembersRequest;
|
||||
import cn.axzo.im.center.api.vo.req.GroupRemoveMembersRequest;
|
||||
import cn.axzo.im.center.api.vo.resp.GroupAddMembersResponse;
|
||||
import cn.axzo.im.center.api.vo.resp.GroupCreateResponse;
|
||||
import cn.axzo.im.center.api.vo.resp.GroupGetMembersResponse;
|
||||
import cn.axzo.im.dao.repository.GroupMemberDao;
|
||||
import cn.axzo.im.entity.GroupMember;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author yanglin
|
||||
*/
|
||||
@ -20,6 +29,7 @@ import org.springframework.web.bind.annotation.RestController;
|
||||
public class GroupController implements GroupApi {
|
||||
|
||||
private final GroupManager groupManager;
|
||||
private final GroupMemberDao groupMemberDao;
|
||||
|
||||
@Override
|
||||
public ApiResult<GroupCreateResponse> createGroup(GroupCreateRequest request) {
|
||||
@ -37,4 +47,18 @@ public class GroupController implements GroupApi {
|
||||
return ApiResult.ok(groupManager.addMembers(request));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ApiResult<Void> addMembers(GroupRemoveMembersRequest request) {
|
||||
groupManager.removeMembers(request);
|
||||
return ApiResult.ok();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ApiResult<GroupGetMembersResponse> getMembers(GroupGetMembersRequest request) {
|
||||
List<GroupMember> members = groupMemberDao.getByTid(request.getTid());
|
||||
GroupGetMembersResponse response = new GroupGetMembersResponse();
|
||||
response.setMember(BeanMapper.copyList(members, GroupMemberInfo.class));
|
||||
return ApiResult.ok(response);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,8 @@
|
||||
package cn.axzo.im.group;
|
||||
|
||||
/**
|
||||
* @author yanglin
|
||||
*/
|
||||
public interface GroupLogger {
|
||||
void log(String message, Object... args);
|
||||
}
|
||||
@ -5,6 +5,7 @@ import cn.axzo.im.center.api.vo.PersonAccountAttribute;
|
||||
import cn.axzo.im.center.api.vo.req.GroupAddMembersRequest;
|
||||
import cn.axzo.im.center.api.vo.req.GroupCreateRequest;
|
||||
import cn.axzo.im.center.api.vo.req.GroupDismissRequest;
|
||||
import cn.axzo.im.center.api.vo.req.GroupRemoveMembersRequest;
|
||||
import cn.axzo.im.center.api.vo.resp.GroupAddMembersResponse;
|
||||
import cn.axzo.im.center.api.vo.resp.GroupCreateResponse;
|
||||
import cn.axzo.im.channel.netease.client.NimClient;
|
||||
@ -17,15 +18,15 @@ import cn.axzo.im.channel.netease.dto.NimGroupDismissResponse;
|
||||
import cn.axzo.im.channel.netease.dto.NimGroupGetInfoRequest;
|
||||
import cn.axzo.im.channel.netease.dto.NimGroupGetInfoResponse;
|
||||
import cn.axzo.im.channel.netease.dto.NimGroupInfo;
|
||||
import cn.axzo.im.dao.repository.GroupAccountDao;
|
||||
import cn.axzo.im.channel.netease.dto.NimGroupRemoveMembersRequest;
|
||||
import cn.axzo.im.channel.netease.dto.NimGroupRemoveMembersResponse;
|
||||
import cn.axzo.im.dao.repository.GroupDao;
|
||||
import cn.axzo.im.dao.repository.GroupMemberDao;
|
||||
import cn.axzo.im.entity.Group;
|
||||
import cn.axzo.im.entity.GroupAccount;
|
||||
import cn.axzo.im.group.domain.GroupMembersDiff;
|
||||
import cn.axzo.im.entity.GroupMember;
|
||||
import cn.axzo.im.service.AccountService;
|
||||
import cn.axzo.im.service.domain.PersonImAccounts;
|
||||
import cn.axzo.im.service.domain.ImAccounts;
|
||||
import cn.axzo.im.utils.BizAssertions;
|
||||
import cn.hutool.core.map.MapUtil;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@ -39,45 +40,49 @@ import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
import static java.util.stream.Collectors.toList;
|
||||
|
||||
/**
|
||||
* @author yanglin
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
class GroupManager {
|
||||
public class GroupManager {
|
||||
|
||||
private final NimClient nimClient;
|
||||
private final GroupDao groupDao;
|
||||
private final GroupAccountDao groupAccountDao;
|
||||
private final GroupMemberDao groupMemberDao;
|
||||
private final GroupSupport groupSupport;
|
||||
private final AccountService accountService;
|
||||
private final GroupBroadcaster groupBroadcaster;
|
||||
|
||||
@Transactional
|
||||
public GroupCreateResponse createGroup(GroupCreateRequest request) {
|
||||
PersonImAccounts accounts = accountService.findPersonAccounts(request.getOwnerAndMembers());
|
||||
Group group = groupSupport.buildNewGroup(request, accounts);
|
||||
BizAssertions.assertTrue(request.getOwnerAndMembers().size() > 1, "群成员数量(含群主)不能少于2");
|
||||
ImAccounts imAccounts = accountService.getAccountsByPersons(request.getOwnerAndMembers());
|
||||
Group group = groupSupport.buildNewGroup(request, imAccounts);
|
||||
BizAssertions.assertFalse(group.isMemberLimitReached(
|
||||
request.getOwnerAndMembers().size()), "无法创建群, 群成员数量超过上限" + group.getMemberLimit());
|
||||
try {
|
||||
groupDao.save(group);
|
||||
} catch (DuplicateKeyException e) {
|
||||
log.warn("重复创建群, request={}", request, e);
|
||||
throw new ServiceException(403, String.format("群已经存在: %s", request.getName()));
|
||||
}
|
||||
NimGroupCreateRequest nimRequest = groupSupport.buildNimCreateGroupRequest(request, group, accounts);
|
||||
NimGroupCreateRequest nimRequest = groupSupport
|
||||
.buildNimCreateGroupRequest(request, imAccounts);
|
||||
NimGroupCreateResponse nimResponse = nimClient.createGroup(nimRequest);
|
||||
log.info("创建群, request={}, response={}", nimRequest, nimResponse);
|
||||
BizAssertions.assertTrue(nimResponse.isSuccess(), "创建群失败: {}", nimResponse.getDesc());
|
||||
groupDao.updateTid(group.getId(), nimResponse.getTid());
|
||||
GroupMembersDiff memberDiff = createMembersDiff(nimResponse.getTid());
|
||||
syncGroupAccounts(group);
|
||||
groupBroadcaster.fireMembersAdded(group, memberDiff);
|
||||
group = groupDao.getById(group.getId());
|
||||
syncGroupMembers(group);
|
||||
groupBroadcaster.fireMembersAdded(group, groupMemberDao.getByTid(nimResponse.getTid()));
|
||||
GroupCreateResponse response = new GroupCreateResponse();
|
||||
response.setTid(nimResponse.getTid());
|
||||
Set<PersonAccountAttribute> notFound = accounts.getAccountNotFoundPersons(request.getMembers());
|
||||
if (!notFound.isEmpty())
|
||||
groupSupport.log("创建群[TID:{}], IM账号不存在列表: {}", group.getTid(), JSON.toJSONString(notFound));
|
||||
response.setAccountsNotFound(notFound);
|
||||
response.setAccountsNotFound(imAccounts.getAccountNotFoundPersons(
|
||||
groupSupport, "创建群", group, request.getMembers()));
|
||||
return response;
|
||||
}
|
||||
|
||||
@ -98,37 +103,61 @@ class GroupManager {
|
||||
public GroupAddMembersResponse addMembers(GroupAddMembersRequest request) {
|
||||
Group group = findGroupForUpdateOrThrow(request.getTid());
|
||||
BizAssertions.assertFalse(group.isDismissed(), "群已经解散: {}", group.getTid());
|
||||
NimGroupInfo groupInfo = fetchGroupInfo(group).orElse(null);
|
||||
BizAssertions.assertNotNull(groupInfo, "[NIM] 群不存在: {}", group.getTid());
|
||||
PersonImAccounts accounts = accountService.findPersonAccounts(request.getMembers());
|
||||
// sync members 1
|
||||
syncGroupMembers(group);
|
||||
// prepare add members
|
||||
Set<PersonAccountAttribute> preMembers = groupMemberDao.getGroupPersons(group.getTid());
|
||||
List<PersonAccountAttribute> toAddMembers = request.getMembers().stream()
|
||||
.filter(member -> !preMembers.contains(member))
|
||||
.collect(toList());
|
||||
if (group.isMemberLimitReached(preMembers.size() + toAddMembers.size()))
|
||||
throw new ServiceException("群聊人数上限" + group.getMemberLimit() +"人, 请删除部分已选人员");
|
||||
ImAccounts imAccounts = accountService.getAccountsByPersons(toAddMembers);
|
||||
if (imAccounts.isAccountEmpty()) {
|
||||
groupSupport.log("添加群成员[TID:{}], 有效群成员IM账号列表为空. 请求成员信息: {}",
|
||||
group.getTid(), JSON.toJSONString(request.getMembers()));
|
||||
return new GroupAddMembersResponse();
|
||||
}
|
||||
NimGroupAddMembersRequest nimRequest = groupSupport
|
||||
.buildAddMembersRequest(request, group, groupInfo.getOwner().getAccid(), accounts);
|
||||
GroupMembersDiff memberDiff = createMembersDiff(group.getTid());
|
||||
.buildAddMembersRequest(group, group.getOwnerAccount(), imAccounts);
|
||||
// add members
|
||||
NimGroupAddMembersResponse nimResponse = nimClient.addMembers(nimRequest);
|
||||
log.info("添加群成员, request={}, response={}", nimRequest, nimResponse);
|
||||
BizAssertions.assertTrue(nimResponse.isSuccess(), "添加群成员失败: {}", nimResponse.getDesc());
|
||||
if (MapUtil.isNotEmpty(nimResponse.getFaccid()))
|
||||
groupSupport.log("添加群成员[TID:{}], 错误信息: {}",
|
||||
group.getTid(), JSON.toJSONString(nimResponse.getFaccid()));
|
||||
syncGroupAccounts(group);
|
||||
groupBroadcaster.fireMembersAdded(group, memberDiff);
|
||||
// sync members 2
|
||||
syncGroupMembers(group);
|
||||
groupBroadcaster.fireMembersAdded(group, groupMemberDao
|
||||
.getByPersons(group.getTid(), toAddMembers));
|
||||
GroupAddMembersResponse response = new GroupAddMembersResponse();
|
||||
Set<PersonAccountAttribute> notFound = accounts.getAccountNotFoundPersons(request.getMembers());
|
||||
if (!notFound.isEmpty())
|
||||
groupSupport.log("创建群[TID:{}], IM账号不存在列表: {}", group.getTid(), JSON.toJSONString(notFound));
|
||||
response.setAccountsNotFound(notFound);
|
||||
response.setAccountsNotFound(imAccounts.getAccountNotFoundPersons(
|
||||
groupSupport, "添加群成员", group, request.getMembers()));
|
||||
return response;
|
||||
}
|
||||
|
||||
private void syncGroupAccounts(Group group) {
|
||||
NimGroupInfo groupInfo = fetchGroupInfo(group).orElse(null);
|
||||
if (groupInfo == null) return;
|
||||
groupAccountDao.deleteAccounts(group.getTid());
|
||||
List<GroupAccount> accounts = groupSupport
|
||||
.parseGroupAccounts(group, groupInfo.getOwnerAndMembers());
|
||||
if (CollectionUtils.isNotEmpty(accounts))
|
||||
groupAccountDao.saveBatch(accounts);
|
||||
groupDao.updateMembersCount(group.getTid(), accounts.size());
|
||||
@Transactional
|
||||
public void removeMembers(GroupRemoveMembersRequest request) {
|
||||
Group group = findGroupForUpdateOrThrow(request.getTid());
|
||||
BizAssertions.assertFalse(group.isDismissed(), "群已经解散: {}", group.getTid());
|
||||
ImAccounts imAccounts = accountService.getAccountsByPersons(request.getMembers());
|
||||
if (imAccounts.isAccountEmpty()) {
|
||||
groupSupport.log("添加群成员[TID:{}], 有效群成员IM账号列表为空. 请求成员信息: {}",
|
||||
group.getTid(), JSON.toJSONString(request.getMembers()));
|
||||
return;
|
||||
}
|
||||
syncGroupMembers(group);
|
||||
List<GroupMember> toRemoveMembers = groupMemberDao.getByPersons(
|
||||
group.getTid(), request.getMembers());
|
||||
if (CollectionUtils.isEmpty(toRemoveMembers))
|
||||
return;
|
||||
NimGroupRemoveMembersRequest nimRequest = groupSupport
|
||||
.buildRemoveMembersRequest(group, group.getOwnerAccount(), imAccounts);
|
||||
NimGroupRemoveMembersResponse nimResponse = nimClient.removeMembers(nimRequest);
|
||||
log.info("移除群成员, request={}, response={}", nimRequest, nimResponse);
|
||||
if (nimResponse.isSuccess()) {
|
||||
syncGroupMembers(group);
|
||||
// 不比较直接发消息
|
||||
groupBroadcaster.fireMembersAdded(group, toRemoveMembers);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@ -138,6 +167,17 @@ class GroupManager {
|
||||
return group;
|
||||
}
|
||||
|
||||
private void syncGroupMembers(Group group) {
|
||||
NimGroupInfo groupInfo = fetchGroupInfo(group).orElse(null);
|
||||
if (groupInfo == null) return;
|
||||
groupMemberDao.deleteAccounts(group.getTid());
|
||||
List<GroupMember> accounts = groupSupport
|
||||
.parseGroupMembers(group, groupInfo.getOwnerAndMembers());
|
||||
if (CollectionUtils.isNotEmpty(accounts))
|
||||
groupMemberDao.saveBatch(accounts);
|
||||
groupDao.updateMembersCount(group.getTid(), accounts.size());
|
||||
}
|
||||
|
||||
private Optional<NimGroupInfo> fetchGroupInfo(Group group) {
|
||||
NimGroupGetInfoRequest nimRequest = new NimGroupGetInfoRequest();
|
||||
nimRequest.setTid(group.getTid());
|
||||
@ -152,7 +192,4 @@ class GroupManager {
|
||||
return Optional.of(nimResponse.getTinfo());
|
||||
}
|
||||
|
||||
private GroupMembersDiff createMembersDiff(Long tid) {
|
||||
return new GroupMembersDiff(() -> groupAccountDao.getByTid(tid));
|
||||
}
|
||||
}
|
||||
@ -1,17 +1,18 @@
|
||||
package cn.axzo.im.group;
|
||||
|
||||
import cn.axzo.im.center.api.feign.GroupApi;
|
||||
import cn.axzo.im.center.api.vo.PersonAccountAttribute;
|
||||
import cn.axzo.im.center.api.vo.req.GroupAddMembersRequest;
|
||||
import cn.axzo.im.center.api.vo.req.GroupCreateRequest;
|
||||
import cn.axzo.im.center.common.enums.YesOrNo;
|
||||
import cn.axzo.im.channel.netease.dto.NimGroupAddMembersRequest;
|
||||
import cn.axzo.im.channel.netease.dto.NimGroupCreateRequest;
|
||||
import cn.axzo.im.channel.netease.dto.NimGroupDismissRequest;
|
||||
import cn.axzo.im.channel.netease.dto.NimGroupMemberInfo;
|
||||
import cn.axzo.im.channel.netease.dto.NimGroupRemoveMembersRequest;
|
||||
import cn.axzo.im.entity.Group;
|
||||
import cn.axzo.im.entity.GroupAccount;
|
||||
import cn.axzo.im.entity.GroupMember;
|
||||
import cn.axzo.im.service.ChatGroupService;
|
||||
import cn.axzo.im.service.domain.PersonImAccounts;
|
||||
import cn.axzo.im.service.domain.ImAccounts;
|
||||
import cn.axzo.im.utils.BizAssertions;
|
||||
import cn.axzo.im.utils.ImAccountParser;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
@ -29,11 +30,11 @@ import java.util.Set;
|
||||
@Slf4j
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
class GroupSupport {
|
||||
public class GroupSupport implements GroupLogger {
|
||||
|
||||
private final ChatGroupService chatGroupService;
|
||||
|
||||
Group buildNewGroup(GroupCreateRequest request, PersonImAccounts accounts) {
|
||||
Group buildNewGroup(GroupCreateRequest request, ImAccounts accounts) {
|
||||
String owner = accounts.findAccount(request.getOwner()).orElse(null);
|
||||
BizAssertions.assertNotNull(owner, "群主没有IM账号, 无法创建群. {}", request.getOwner());
|
||||
Group group = new Group();
|
||||
@ -52,18 +53,16 @@ class GroupSupport {
|
||||
}
|
||||
|
||||
NimGroupCreateRequest buildNimCreateGroupRequest(
|
||||
GroupCreateRequest request, Group group, PersonImAccounts accounts) {
|
||||
BizAssertions.assertFalse(group.isMemberLimitReached(
|
||||
accounts.getAccountSize()), "无法创建群, 群成员数量超过上限");
|
||||
String owner = accounts.findAccount(request.getOwner()).orElse(null);
|
||||
GroupCreateRequest request, ImAccounts imAccounts) {
|
||||
String owner = imAccounts.findAccount(request.getOwner()).orElse(null);
|
||||
BizAssertions.assertNotNull(owner, "群主没有IM账号, 无法创建群. {}", request.getOwner());
|
||||
BizAssertions.assertTrue(accounts.getAccountSize() > 1, "无法创建群. 存在的群成员IM账号数量需要大于等于2");
|
||||
BizAssertions.assertTrue(imAccounts.getAccountSize() > 1, "无法创建群. 存在的群成员IM账号数量需要大于等于2");
|
||||
|
||||
NimGroupCreateRequest nimRequest = new NimGroupCreateRequest();
|
||||
nimRequest.setName(request.getName());
|
||||
nimRequest.setOwner(owner);
|
||||
nimRequest.addMembers(accounts.filterAccounts(account -> !account.equals(owner)));
|
||||
nimRequest.setIntroduceMessage(request.getIntroduceMessage());
|
||||
nimRequest.addMembers(imAccounts.filterAccounts(account -> !account.equals(owner)));
|
||||
nimRequest.setIntroduceMessage(GroupApi.INTRODUCE_MESSAGE);
|
||||
nimRequest.setIcon(request.getAvatar());
|
||||
nimRequest.addAttachment(Group.ATTACHMENT_GROUP_TYPE, request.getGroupType());
|
||||
return nimRequest;
|
||||
@ -77,16 +76,27 @@ class GroupSupport {
|
||||
}
|
||||
|
||||
NimGroupAddMembersRequest buildAddMembersRequest(
|
||||
GroupAddMembersRequest request, Group group, String owner, PersonImAccounts accounts) {
|
||||
Group group, String owner, ImAccounts accounts) {
|
||||
BizAssertions.assertNotEmpty(accounts.getAccounts(), "有效群成员IM账号列表为空");
|
||||
NimGroupAddMembersRequest nimRequest = new NimGroupAddMembersRequest();
|
||||
nimRequest.setTid(group.getTid());
|
||||
nimRequest.setOwner(owner);
|
||||
nimRequest.setMsg(request.getIntroduceMessage());
|
||||
nimRequest.setMsg(GroupApi.INTRODUCE_MESSAGE);
|
||||
nimRequest.addMembers(accounts.getAccounts());
|
||||
return nimRequest;
|
||||
}
|
||||
|
||||
void log(String message, Object... args) {
|
||||
NimGroupRemoveMembersRequest buildRemoveMembersRequest(
|
||||
Group group, String owner, ImAccounts accounts) {
|
||||
BizAssertions.assertNotEmpty(accounts.getAccounts(), "有效群成员IM账号列表为空");
|
||||
NimGroupRemoveMembersRequest nimRequest = new NimGroupRemoveMembersRequest();
|
||||
nimRequest.setTid(group.getTid());
|
||||
nimRequest.setOwner(owner);
|
||||
nimRequest.addMembers(accounts.getAccounts());
|
||||
return nimRequest;
|
||||
}
|
||||
|
||||
public void log(String message, Object... args) {
|
||||
try {
|
||||
chatGroupService.sendDingRobot(MessageFormatter.arrayFormat(message, args).getMessage());
|
||||
} catch (Exception e) {
|
||||
@ -94,11 +104,11 @@ class GroupSupport {
|
||||
}
|
||||
}
|
||||
|
||||
List<GroupAccount> parseGroupAccounts(Group group, Set<NimGroupMemberInfo> members) {
|
||||
ArrayList<GroupAccount> accounts = new ArrayList<>();
|
||||
List<GroupMember> parseGroupMembers(Group group, Set<NimGroupMemberInfo> members) {
|
||||
ArrayList<GroupMember> accounts = new ArrayList<>();
|
||||
for (NimGroupMemberInfo member : members) {
|
||||
PersonAccountAttribute person = ImAccountParser.parsePerson(member.getAccid()).orElse(null);
|
||||
GroupAccount account = new GroupAccount();
|
||||
GroupMember account = new GroupMember();
|
||||
accounts.add(account);
|
||||
account.setTid(group.getTid());
|
||||
account.setImAccount(member.getAccid());
|
||||
@ -116,4 +126,5 @@ class GroupSupport {
|
||||
}
|
||||
return accounts;
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,57 +0,0 @@
|
||||
package cn.axzo.im.group.domain;
|
||||
|
||||
import cn.axzo.im.entity.GroupAccount;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author yanglin
|
||||
*/
|
||||
@SuppressWarnings("DuplicatedCode")
|
||||
public class GroupMembersDiff {
|
||||
|
||||
private final Supplier<List<GroupAccount>> accountsProvider;
|
||||
private final Map<String, GroupAccount> before;
|
||||
private Map<String, GroupAccount> after;
|
||||
|
||||
public GroupMembersDiff(Supplier<List<GroupAccount>> accountsProvider) {
|
||||
this.accountsProvider = accountsProvider;
|
||||
this.before = reload();
|
||||
}
|
||||
|
||||
public void diff() {
|
||||
if (after == null)
|
||||
after = reload();
|
||||
}
|
||||
|
||||
public Collection<GroupAccount> getAdded() {
|
||||
HashMap<String, GroupAccount> accounts = new HashMap<>();
|
||||
for (GroupAccount account : after.values()) {
|
||||
String imAccount = account.getImAccount();
|
||||
if (!before.containsKey(imAccount) && !accounts.containsKey(imAccount))
|
||||
accounts.put(imAccount, account);
|
||||
}
|
||||
return accounts.values();
|
||||
}
|
||||
|
||||
public Collection<GroupAccount> getRemoved() {
|
||||
HashMap<String, GroupAccount> accounts = new HashMap<>();
|
||||
for (GroupAccount account : before.values()) {
|
||||
String imAccount = account.getImAccount();
|
||||
if (!after.containsKey(imAccount) && !accounts.containsKey(imAccount))
|
||||
accounts.put(imAccount, account);
|
||||
}
|
||||
return accounts.values();
|
||||
}
|
||||
|
||||
private Map<String, GroupAccount> reload() {
|
||||
return accountsProvider.get().stream()
|
||||
.collect(Collectors.toMap(GroupAccount::getImAccount, account -> account));
|
||||
}
|
||||
|
||||
}
|
||||
@ -32,7 +32,7 @@ import cn.axzo.im.entity.AccountRegister;
|
||||
import cn.axzo.im.entity.RobotInfo;
|
||||
import cn.axzo.im.entity.bo.AccountQueryParam;
|
||||
import cn.axzo.im.gateway.ProfilesApiGateway;
|
||||
import cn.axzo.im.service.domain.PersonImAccounts;
|
||||
import cn.axzo.im.service.domain.ImAccounts;
|
||||
import cn.axzo.im.utils.MiscUtils;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
@ -580,9 +580,9 @@ public class AccountService {
|
||||
AccountTypeEnum.CUSTOM, AppTypeEnum.SYSTEM, appKey);
|
||||
}
|
||||
|
||||
public PersonImAccounts findPersonAccounts(Collection<PersonAccountAttribute> persons) {
|
||||
public ImAccounts getAccountsByPersons(Collection<PersonAccountAttribute> persons) {
|
||||
if (CollectionUtils.isEmpty(persons))
|
||||
return new PersonImAccounts(Collections.emptyList());
|
||||
return new ImAccounts(Collections.emptyList());
|
||||
List<AccountRegister> accounts = accountRegisterDao.lambdaQuery()
|
||||
.nested(wrapper -> {
|
||||
for (PersonAccountAttribute person : persons) {
|
||||
@ -593,7 +593,7 @@ public class AccountService {
|
||||
}
|
||||
})
|
||||
.list();
|
||||
return new PersonImAccounts(accounts);
|
||||
return new ImAccounts(accounts);
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,7 +1,10 @@
|
||||
package cn.axzo.im.service.domain;
|
||||
|
||||
import cn.axzo.framework.jackson.utility.JSON;
|
||||
import cn.axzo.im.center.api.vo.PersonAccountAttribute;
|
||||
import cn.axzo.im.entity.AccountRegister;
|
||||
import cn.axzo.im.entity.Group;
|
||||
import cn.axzo.im.group.GroupLogger;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.Setter;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
@ -20,17 +23,25 @@ import static java.util.stream.Collectors.toSet;
|
||||
*/
|
||||
@Setter
|
||||
@RequiredArgsConstructor
|
||||
public class PersonImAccounts {
|
||||
public class ImAccounts {
|
||||
|
||||
private final List<AccountRegister> imAccounts;
|
||||
|
||||
public Set<PersonAccountAttribute>
|
||||
getAccountNotFoundPersons(Set<PersonAccountAttribute> persons) {
|
||||
public boolean isAccountEmpty() {
|
||||
return imAccounts.isEmpty();
|
||||
}
|
||||
|
||||
public Set<PersonAccountAttribute> getAccountNotFoundPersons(
|
||||
GroupLogger logger, String operation,
|
||||
Group group, Set<PersonAccountAttribute> persons) {
|
||||
if (CollectionUtils.isEmpty(persons))
|
||||
return Collections.emptySet();
|
||||
return persons.stream()
|
||||
Set<PersonAccountAttribute> notFound = persons.stream()
|
||||
.filter(person -> !findAccount(person).isPresent())
|
||||
.collect(toSet());
|
||||
if (!notFound.isEmpty())
|
||||
logger.log("{}[TID:{}], IM账号不存在列表: {}", operation, group.getTid(), JSON.toJSONString(notFound));
|
||||
return notFound;
|
||||
}
|
||||
|
||||
public Set<String> filterAccounts(Predicate<String> filter) {
|
||||
@ -24,7 +24,7 @@ public class ImAccountParser {
|
||||
|
||||
PersonAccountAttribute person = new PersonAccountAttribute();
|
||||
person.setPersonId(personId);
|
||||
person.setOuId(ouId != null ? Long.parseLong(ouId.substring(1)) : null);
|
||||
person.setOuId(ouId != null ? Long.parseLong(ouId) : null);
|
||||
person.setAppType(appType);
|
||||
return Optional.of(person);
|
||||
}
|
||||
|
||||
@ -24,10 +24,11 @@ class GroupManagerTest {
|
||||
|
||||
@Test
|
||||
void createGroup() {
|
||||
int idx = 6;
|
||||
GroupCreateRequest request = new GroupCreateRequest();
|
||||
request.setGroupType(GroupType.VISA);
|
||||
request.setBizCode("yl-group-2");
|
||||
request.setName("杨林测试群2");
|
||||
request.setBizCode("yl-group-" + idx);
|
||||
request.setName("杨林测试群" + idx);
|
||||
request.setOwner(PersonAccountAttribute.cmp(9000399522L, 10616L));
|
||||
request.addMember(PersonAccountAttribute.cm(9000399522L));
|
||||
request.setAvatar("https://axzo-app.oss-cn-chengdu.aliyuncs.com/dev/common/92c412eb7e62542998cc10059fa7619e6.jpg");
|
||||
@ -38,14 +39,14 @@ class GroupManagerTest {
|
||||
@Test
|
||||
void dismissGroup() {
|
||||
GroupDismissRequest request = new GroupDismissRequest();
|
||||
request.setTid(32504762462L);
|
||||
request.setTid(32543625538L);
|
||||
groupManager.dismissGroup(request);
|
||||
}
|
||||
|
||||
@Test
|
||||
void addMembers() {
|
||||
GroupAddMembersRequest request = new GroupAddMembersRequest();
|
||||
request.setTid(32505385179L);
|
||||
request.setTid(32544969049L);
|
||||
request.addMember(PersonAccountAttribute.cmp(13335L, 8507L));
|
||||
request.addMember(PersonAccountAttribute.cmp(13335000000L, 8507L));
|
||||
GroupAddMembersResponse response = groupManager.addMembers(request);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user