导入数据库表和音视频demo

This commit is contained in:
2023-09-14 14:59:57 +08:00
parent c0ca154d31
commit 736c5376e0
157 changed files with 11044 additions and 0 deletions

View File

View File

@@ -0,0 +1,101 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>im-system</artifactId>
<groupId>com.lld</groupId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<description>lld-im-service project</description>
<properties>
<java.version>1.8</java.version>
</properties>
<artifactId>service</artifactId>
<dependencies>
<!-- rabbitmq -->
<!-- <dependency>-->
<!-- <groupId>org.springframework.boot</groupId>-->
<!-- <artifactId>spring-boot-starter-amqp</artifactId>-->
<!-- </dependency>-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<!-- <dependency>-->
<!-- <groupId>com.github.sgroschupf</groupId>-->
<!-- <artifactId>zkclient</artifactId>-->
<!-- </dependency>-->
<!-- redis -->
<!-- <dependency>-->
<!-- <groupId>org.springframework.boot</groupId>-->
<!-- <artifactId>spring-boot-starter-data-redis</artifactId>-->
<!-- </dependency>-->
<!-- spring boot web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- <dependency>-->
<!-- <groupId>com.lld</groupId>-->
<!-- <artifactId>codec</artifactId>-->
<!-- <version>1.0.0-SNAPSHOT</version>-->
<!-- </dependency>-->
<!-- hutool -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
</dependency>
<!--MySQL JDBC驱动 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<!--MySQL -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<!-- mybatis plus -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.github.jeffreyning</groupId>
<artifactId>mybatisplus-plus</artifactId>
<version>1.5.1-RELEASE</version>
</dependency>
<!-- common -->
<dependency>
<groupId>com.lld</groupId>
<artifactId>common</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

View File

@@ -0,0 +1,20 @@
package com.lld.im.service;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@MapperScan("com.lld.im.service.*.dao.mapper")
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}

View File

@@ -0,0 +1,13 @@
package com.lld.im.service.config;
import org.springframework.context.annotation.Configuration;
/**
* @description:
* @author: lld
* @version: 1.0
*/
@Configuration
public class BeanConfig {
}

View File

@@ -0,0 +1,26 @@
package com.lld.im.service.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* @description:
* @author: lld
* @version: 1.0
*/
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowedMethods("GET", "HEAD", "POST", "PUT", "DELETE", "OPTIONS")
.allowCredentials(true)
.maxAge(3600)
.allowedHeaders("*");
}
}

View File

@@ -0,0 +1,110 @@
package com.lld.im.service.exception;
import com.lld.im.common.BaseErrorCode;
import com.lld.im.common.ResponseVO;
import com.lld.im.common.exception.ApplicationException;
import org.hibernate.validator.internal.engine.path.PathImpl;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.util.Set;
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(value=Exception.class)
@ResponseBody
public ResponseVO unknowException(Exception e){
e.printStackTrace();
ResponseVO resultBean =new ResponseVO();
resultBean.setCode(BaseErrorCode.SYSTEM_ERROR.getCode());
resultBean.setMsg(BaseErrorCode.SYSTEM_ERROR.getError());
/**
* 未知异常的话,这里写逻辑,发邮件,发短信都可以、、
*/
return resultBean;
}
/**
* Validator 参数校验异常处理
*
* @param ex
* @return
*/
@ExceptionHandler(value = ConstraintViolationException.class)
@ResponseBody
public Object handleMethodArgumentNotValidException(ConstraintViolationException ex) {
Set<ConstraintViolation<?>> constraintViolations = ex.getConstraintViolations();
ResponseVO resultBean =new ResponseVO();
resultBean.setCode(BaseErrorCode.PARAMETER_ERROR.getCode());
for (ConstraintViolation<?> constraintViolation : constraintViolations) {
PathImpl pathImpl = (PathImpl) constraintViolation.getPropertyPath();
// 读取参数字段constraintViolation.getMessage() 读取验证注解中的message值
String paramName = pathImpl.getLeafNode().getName();
String message = "参数{".concat(paramName).concat("}").concat(constraintViolation.getMessage());
resultBean.setMsg(message);
return resultBean;
}
resultBean.setMsg(BaseErrorCode.PARAMETER_ERROR.getError() + ex.getMessage());
return resultBean;
}
@ExceptionHandler(ApplicationException.class)
@ResponseBody
public Object applicationExceptionHandler(ApplicationException e) {
// 使用公共的结果类封装返回结果, 这里我指定状态码为
ResponseVO resultBean =new ResponseVO();
resultBean.setCode(e.getCode());
resultBean.setMsg(e.getError());
return resultBean;
}
/**
* Validator 参数校验异常处理
*
* @param ex
* @return
*/
@ExceptionHandler(value = BindException.class)
@ResponseBody
public Object handleException2(BindException ex) {
FieldError err = ex.getFieldError();
String message = "参数{".concat(err.getField()).concat("}").concat(err.getDefaultMessage());
ResponseVO resultBean =new ResponseVO();
resultBean.setCode(BaseErrorCode.PARAMETER_ERROR.getCode());
resultBean.setMsg(message);
return resultBean;
}
//json格式
@ExceptionHandler(value = MethodArgumentNotValidException.class)
@ResponseBody
public Object handleException1(MethodArgumentNotValidException ex) {
StringBuilder errorMsg = new StringBuilder();
BindingResult re = ex.getBindingResult();
for (ObjectError error : re.getAllErrors()) {
errorMsg.append(error.getDefaultMessage()).append(",");
}
errorMsg.delete(errorMsg.length() - 1, errorMsg.length());
ResponseVO resultBean =new ResponseVO();
resultBean.setCode(BaseErrorCode.PARAMETER_ERROR.getCode());
resultBean.setMsg(BaseErrorCode.PARAMETER_ERROR.getError() + " : " + errorMsg.toString());
return resultBean;
}
}

View File

@@ -0,0 +1,86 @@
package com.lld.im.service.friendship.controller;
import com.lld.im.common.ResponseVO;
import com.lld.im.service.friendship.model.req.*;
import com.lld.im.service.friendship.service.ImFriendService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("v1/friendship")
public class ImFriendShipController {
@Autowired
ImFriendService imFriendShipService;
@RequestMapping("/importFriendShip")
public ResponseVO importFriendShip(@RequestBody @Validated ImporFriendShipReq req, Integer appId){
req.setAppId(appId);
return imFriendShipService.importFriendShip(req);
}
@RequestMapping("/addFriend")
public ResponseVO addFriend(@RequestBody @Validated AddFriendReq req, Integer appId){
req.setAppId(appId);
return imFriendShipService.addFriend(req);
}
@RequestMapping("/updateFriend")
public ResponseVO updateFriend(@RequestBody @Validated UpdateFriendReq req, Integer appId){
req.setAppId(appId);
return imFriendShipService.updateFriend(req);
}
@RequestMapping("/deleteFriend")
public ResponseVO deleteFriend(@RequestBody @Validated DeleteFriendReq req, Integer appId){
req.setAppId(appId);
return imFriendShipService.deleteFriend(req);
}
@RequestMapping("/deleteAllFriend")
public ResponseVO deleteAllFriend(@RequestBody @Validated DeleteFriendReq req, Integer appId){
req.setAppId(appId);
return imFriendShipService.deleteAllFriend(req);
}
@RequestMapping("/getAllFriendShip")
public ResponseVO getAllFriendShip(@RequestBody @Validated GetAllFriendShipReq req, Integer appId){
req.setAppId(appId);
return imFriendShipService.getAllFriendShip(req);
}
@RequestMapping("/getRelation")
public ResponseVO getRelation(@RequestBody @Validated GetRelationReq req, Integer appId){
req.setAppId(appId);
return imFriendShipService.getRelation(req);
}
@RequestMapping("/checkFriend")
public ResponseVO checkFriend(@RequestBody @Validated CheckFriendShipReq req, Integer appId){
req.setAppId(appId);
return imFriendShipService.checkFriendship(req);
}
@RequestMapping("/addBlack")
public ResponseVO addBlack(@RequestBody @Validated AddFriendShipBlackReq req, Integer appId){
req.setAppId(appId);
return imFriendShipService.addBlack(req);
}
@RequestMapping("/deleteBlack")
public ResponseVO deleteBlack(@RequestBody @Validated DeleteBlackReq req, Integer appId){
req.setAppId(appId);
return imFriendShipService.deleteBlack(req);
}
@RequestMapping("/checkBlck")
public ResponseVO checkBlck(@RequestBody @Validated CheckFriendShipReq req, Integer appId){
req.setAppId(appId);
return imFriendShipService.checkBlck(req);
}
}

View File

@@ -0,0 +1,56 @@
package com.lld.im.service.friendship.controller;
import com.lld.im.common.ResponseVO;
import com.lld.im.service.friendship.model.req.AddFriendShipGroupMemberReq;
import com.lld.im.service.friendship.model.req.AddFriendShipGroupReq;
import com.lld.im.service.friendship.model.req.DeleteFriendShipGroupMemberReq;
import com.lld.im.service.friendship.model.req.DeleteFriendShipGroupReq;
import com.lld.im.service.friendship.service.ImFriendShipGroupMemberService;
import com.lld.im.service.friendship.service.ImFriendShipGroupService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author: Chackylee
* @description:
**/
@RestController
@RequestMapping("v1/friendship/group")
public class ImFriendShipGroupController {
@Autowired
ImFriendShipGroupService imFriendShipGroupService;
@Autowired
ImFriendShipGroupMemberService imFriendShipGroupMemberService;
@RequestMapping("/add")
public ResponseVO add(@RequestBody @Validated AddFriendShipGroupReq req, Integer appId) {
req.setAppId(appId);
return imFriendShipGroupService.addGroup(req);
}
@RequestMapping("/del")
public ResponseVO del(@RequestBody @Validated DeleteFriendShipGroupReq req, Integer appId) {
req.setAppId(appId);
return imFriendShipGroupService.deleteGroup(req);
}
@RequestMapping("/member/add")
public ResponseVO memberAdd(@RequestBody @Validated AddFriendShipGroupMemberReq req, Integer appId) {
req.setAppId(appId);
return imFriendShipGroupMemberService.addGroupMember(req);
}
@RequestMapping("/member/del")
public ResponseVO memberdel(@RequestBody @Validated DeleteFriendShipGroupMemberReq req, Integer appId) {
req.setAppId(appId);
return imFriendShipGroupMemberService.delGroupMember(req);
}
}

View File

@@ -0,0 +1,42 @@
package com.lld.im.service.friendship.controller;
import com.lld.im.common.ResponseVO;
import com.lld.im.service.friendship.model.req.ApproverFriendRequestReq;
import com.lld.im.service.friendship.model.req.GetFriendShipRequestReq;
import com.lld.im.service.friendship.model.req.ReadFriendShipRequestReq;
import com.lld.im.service.friendship.service.ImFriendShipRequestService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("v1/friendshipRequest")
public class ImFriendShipRequestController {
@Autowired
ImFriendShipRequestService imFriendShipRequestService;
@RequestMapping("/approveFriendRequest")
public ResponseVO approveFriendRequest(@RequestBody @Validated
ApproverFriendRequestReq req, Integer appId, String identifier){
req.setAppId(appId);
req.setOperater(identifier);
return imFriendShipRequestService.approverFriendRequest(req);
}
@RequestMapping("/getFriendRequest")
public ResponseVO getFriendRequest(@RequestBody @Validated GetFriendShipRequestReq req, Integer appId){
req.setAppId(appId);
return imFriendShipRequestService.getFriendRequest(req.getFromId(),req.getAppId());
}
@RequestMapping("/readFriendShipRequestReq")
public ResponseVO readFriendShipRequestReq(@RequestBody @Validated ReadFriendShipRequestReq req, Integer appId){
req.setAppId(appId);
return imFriendShipRequestService.readFriendShipRequestReq(req);
}
}

View File

@@ -0,0 +1,46 @@
package com.lld.im.service.friendship.dao;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.github.jeffreyning.mybatisplus.anno.AutoMap;
import lombok.Data;
/**
* @author: Chackylee
* @description:
**/
@Data
@TableName("im_friendship")
@AutoMap
public class ImFriendShipEntity {
@TableField(value = "app_id")
private Integer appId;
@TableField(value = "from_id")
private String fromId;
@TableField(value = "to_id")
private String toId;
/** 备注*/
private String remark;
/** 状态 1正常 2删除*/
private Integer status;
/** 状态 1正常 2拉黑*/
private Integer black;
// @TableField(updateStrategy = FieldStrategy.IGNORED)
private Long createTime;
/** 好友关系序列号*/
// @TableField(updateStrategy = FieldStrategy.IGNORED)
private Long friendSequence;
/** 黑名单关系序列号*/
private Long blackSequence;
/** 好友来源*/
// @TableField(updateStrategy = FieldStrategy.IGNORED)
private String addSource;
private String extra;
}

View File

@@ -0,0 +1,32 @@
package com.lld.im.service.friendship.dao;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
@Data
@TableName("im_friendship_group")
public class ImFriendShipGroupEntity {
@TableId(value = "group_id",type = IdType.AUTO)
private Long groupId;
private String fromId;
private Integer appId;
private String groupName;
/** 备注*/
private Long createTime;
/** 备注*/
private Long updateTime;
/** 序列号*/
private Long sequence;
private int delFlag;
}

View File

@@ -0,0 +1,17 @@
package com.lld.im.service.friendship.dao;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
@Data
@TableName("im_friendship_group_member")
public class ImFriendShipGroupMemberEntity {
@TableId(value = "group_id")
private Long groupId;
private String toId;
}

View File

@@ -0,0 +1,49 @@
package com.lld.im.service.friendship.dao;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
@Data
@TableName("im_friendship_request")
public class ImFriendShipRequestEntity {
@TableId(type = IdType.AUTO)
private Long id;
private Integer appId;
private String fromId;
private String toId;
/** 备注*/
// @TableField(updateStrategy = FieldStrategy.IGNORED)
private String remark;
//是否已读 1已读
private Integer readStatus;
/** 好友来源*/
// @TableField(updateStrategy = FieldStrategy.IGNORED)
private String addSource;
// @TableField(updateStrategy = FieldStrategy.IGNORED)
private String addWording;
//审批状态 1同意 2拒绝
private Integer approveStatus;
// @TableField(updateStrategy = FieldStrategy.IGNORED)
private Long createTime;
private Long updateTime;
/** 序列号*/
private Long sequence;
}

View File

@@ -0,0 +1,9 @@
package com.lld.im.service.friendship.dao.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.lld.im.service.friendship.dao.ImFriendShipGroupEntity;
public interface ImFriendShipGroupMapper extends BaseMapper<ImFriendShipGroupEntity> {
}

View File

@@ -0,0 +1,9 @@
package com.lld.im.service.friendship.dao.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.lld.im.service.friendship.dao.ImFriendShipGroupMemberEntity;
public interface ImFriendShipGroupMemberMapper extends BaseMapper<ImFriendShipGroupMemberEntity> {
}

View File

@@ -0,0 +1,91 @@
package com.lld.im.service.friendship.dao.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.lld.im.service.friendship.dao.ImFriendShipEntity;
import com.lld.im.service.friendship.model.req.CheckFriendShipReq;
import com.lld.im.service.friendship.model.resp.CheckFriendShipResp;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import java.util.List;
@Mapper
public interface ImFriendShipMapper extends BaseMapper<ImFriendShipEntity> {
@Select("<script>"+
"select from_id as fromId , to_id as toId ,if(status = 1,1,0) as status from im_friendship where from_id = #{fromId} and to_id in " +
"<foreach collection='toIds' index='index' item='id' separator=',' close = ')' open='(' > " +
"#{id}" +
"</foreach>" +
"</script>")
public List<CheckFriendShipResp> checkFriendShip(CheckFriendShipReq req);
@Select("<script>" +
" select a.fromId,a.toId , ( \n" +
" case \n" +
" when a.status = 1 and b.status = 1 then 1 \n" +
" when a.status = 1 and b.status != 1 then 2 \n" +
" when a.status != 1 and b.status = 1 then 3 \n" +
" when a.status != 1 and b.status != 1 then 4 \n" +
" end \n" +
" ) \n " +
" as status from "+
" (select from_id AS fromId , to_id AS toId , if(status = 1,1,0) as status from im_friendship where app_id = #{appId} and from_id = #{fromId} AND to_id in " +
"<foreach collection='toIds' index='index' item='id' separator=',' close=')' open='('>" +
" #{id} " +
"</foreach>" +
" ) as a INNER join" +
" (select from_id AS fromId, to_id AS toId , if(status = 1,1,0) as status from im_friendship where app_id = #{appId} and to_id = #{fromId} AND from_id in " +
"<foreach collection='toIds' index='index' item='id' separator=',' close=')' open='('>" +
" #{id} " +
"</foreach>" +
" ) as b " +
" on a.fromId = b.toId AND b.fromId = a.toId "+
"</script>"
)
List<CheckFriendShipResp> checkFriendShipBoth(CheckFriendShipReq toId);
@Select("<script>" +
" select from_id AS fromId, to_id AS toId , if(black = 1,1,0) as status from im_friendship where app_id = #{appId} and from_id = #{fromId} and to_id in " +
"<foreach collection='toIds' index='index' item='id' separator=',' close=')' open='('>" +
" #{id} " +
"</foreach>" +
"</script>"
)
List<CheckFriendShipResp> checkFriendShipBlack(CheckFriendShipReq req);
@Select("<script>" +
" select a.fromId,a.toId , ( \n" +
" case \n" +
" when a.black = 1 and b.black = 1 then 1 \n" +
" when a.black = 1 and b.black != 1 then 2 \n" +
" when a.black != 1 and b.black = 1 then 3 \n" +
" when a.black != 1 and b.black != 1 then 4 \n" +
" end \n" +
" ) \n " +
" as status from "+
" (select from_id AS fromId , to_id AS toId , if(black = 1,1,0) as black from im_friendship where app_id = #{appId} and from_id = #{fromId} AND to_id in " +
"<foreach collection='toIds' index='index' item='id' separator=',' close=')' open='('>" +
" #{id} " +
"</foreach>" +
" ) as a INNER join" +
" (select from_id AS fromId, to_id AS toId , if(black = 1,1,0) as black from im_friendship where app_id = #{appId} and to_id = #{fromId} AND from_id in " +
"<foreach collection='toIds' index='index' item='id' separator=',' close=')' open='('>" +
" #{id} " +
"</foreach>" +
" ) as b " +
" on a.fromId = b.toId AND b.fromId = a.toId "+
"</script>"
)
List<CheckFriendShipResp> checkFriendShipBlackBoth(CheckFriendShipReq toId);
}

View File

@@ -0,0 +1,9 @@
package com.lld.im.service.friendship.dao.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.lld.im.service.friendship.dao.ImFriendShipRequestEntity;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface ImFriendShipRequestMapper extends BaseMapper<ImFriendShipRequestEntity> {
}

View File

@@ -0,0 +1,19 @@
package com.lld.im.service.friendship.model.req;
import com.lld.im.common.model.RequestBase;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
@Data
public class AddFriendReq extends RequestBase {
@NotBlank(message = "fromId不能为空")
private String fromId;
@NotNull(message = "toItem不能为空")
private FriendDto toItem;
}

View File

@@ -0,0 +1,16 @@
package com.lld.im.service.friendship.model.req;
import com.lld.im.common.model.RequestBase;
import lombok.Data;
import javax.validation.constraints.NotBlank;
@Data
public class AddFriendShipBlackReq extends RequestBase {
@NotBlank(message = "用户id不能为空")
private String fromId;
private String toId;
}

View File

@@ -0,0 +1,24 @@
package com.lld.im.service.friendship.model.req;
import com.lld.im.common.model.RequestBase;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotEmpty;
import java.util.List;
@Data
public class AddFriendShipGroupMemberReq extends RequestBase {
@NotBlank(message = "fromId不能为空")
private String fromId;
@NotBlank(message = "分组名称不能为空")
private String groupName;
@NotEmpty(message = "请选择用户")
private List<String> toIds;
}

View File

@@ -0,0 +1,21 @@
package com.lld.im.service.friendship.model.req;
import com.lld.im.common.model.RequestBase;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import java.util.List;
@Data
public class AddFriendShipGroupReq extends RequestBase {
@NotBlank(message = "fromId不能为空")
public String fromId;
@NotBlank(message = "分组名称不能为空")
private String groupName;
private List<String> toIds;
}

View File

@@ -0,0 +1,14 @@
package com.lld.im.service.friendship.model.req;
import com.lld.im.common.model.RequestBase;
import lombok.Data;
@Data
public class ApproverFriendRequestReq extends RequestBase {
private Long id;
//1同意 2拒绝
private Integer status;
}

View File

@@ -0,0 +1,27 @@
package com.lld.im.service.friendship.model.req;
import com.lld.im.common.model.RequestBase;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.List;
/**
* @description:
* @author: lld
* @version: 1.0
*/
@Data
public class CheckFriendShipReq extends RequestBase {
@NotBlank(message = "fromId不能为空")
private String fromId;
@NotEmpty(message = "toIds不能为空")
private List<String> toIds;
@NotNull(message = "checkType不能为空")
private Integer checkType;
}

View File

@@ -0,0 +1,19 @@
package com.lld.im.service.friendship.model.req;
import com.lld.im.common.model.RequestBase;
import lombok.Data;
import javax.validation.constraints.NotBlank;
@Data
public class DeleteBlackReq extends RequestBase {
@NotBlank(message = "用户id不能为空")
private String fromId;
@NotBlank(message = "好友id不能为空")
private String toId;
}

View File

@@ -0,0 +1,18 @@
package com.lld.im.service.friendship.model.req;
import com.lld.im.common.model.RequestBase;
import lombok.Data;
import javax.validation.constraints.NotBlank;
@Data
public class DeleteFriendReq extends RequestBase {
@NotBlank(message = "fromId不能为空")
private String fromId;
@NotBlank(message = "toId不能为空")
private String toId;
}

View File

@@ -0,0 +1,27 @@
package com.lld.im.service.friendship.model.req;
import com.lld.im.common.model.RequestBase;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotEmpty;
import java.util.List;
/**
* @author: Chackylee
* @description:
**/
@Data
public class DeleteFriendShipGroupMemberReq extends RequestBase {
@NotBlank(message = "fromId不能为空")
private String fromId;
@NotBlank(message = "分组名称不能为空")
private String groupName;
@NotEmpty(message = "请选择用户")
private List<String> toIds;
}

View File

@@ -0,0 +1,23 @@
package com.lld.im.service.friendship.model.req;
import com.lld.im.common.model.RequestBase;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotEmpty;
import java.util.List;
/**
* @author: Chackylee
* @description: 删除分组,同时删除分组下的成员
**/
@Data
public class DeleteFriendShipGroupReq extends RequestBase {
@NotBlank(message = "fromId不能为空")
private String fromId;
@NotEmpty(message = "分组名称不能为空")
private List<String> groupName;
}

View File

@@ -0,0 +1,19 @@
package com.lld.im.service.friendship.model.req;
import lombok.Data;
@Data
public class FriendDto {
private String toId;
private String remark;
private String addSource;
private String extra;
private String addWording;
}

View File

@@ -0,0 +1,14 @@
package com.lld.im.service.friendship.model.req;
import com.lld.im.common.model.RequestBase;
import lombok.Data;
import javax.validation.constraints.NotBlank;
@Data
public class GetAllFriendShipReq extends RequestBase {
@NotBlank(message = "用户id不能为空")
private String fromId;
}

View File

@@ -0,0 +1,19 @@
package com.lld.im.service.friendship.model.req;
import com.lld.im.common.model.RequestBase;
import lombok.Data;
import javax.validation.constraints.NotBlank;
/**
* @description:
* @author: lld
* @version: 1.0
*/
@Data
public class GetFriendShipRequestReq extends RequestBase {
@NotBlank(message = "用户id不能为空")
private String fromId;
}

View File

@@ -0,0 +1,16 @@
package com.lld.im.service.friendship.model.req;
import com.lld.im.common.model.RequestBase;
import lombok.Data;
import javax.validation.constraints.NotBlank;
@Data
public class GetRelationReq extends RequestBase {
@NotBlank(message = "fromId不能为空")
private String fromId;
@NotBlank(message = "toId不能为空")
private String toId;
}

View File

@@ -0,0 +1,33 @@
package com.lld.im.service.friendship.model.req;
import com.lld.im.common.enums.FriendShipStatusEnum;
import com.lld.im.common.model.RequestBase;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import java.util.List;
@Data
public class ImporFriendShipReq extends RequestBase {
@NotBlank(message = "fromId不能为空")
private String fromId;
private List<ImportFriendDto> friendItem;
@Data
public static class ImportFriendDto{
private String toId;
private String remark;
private String addSource;
private Integer status = FriendShipStatusEnum.FRIEND_STATUS_NO_FRIEND.getCode();
private Integer black = FriendShipStatusEnum.BLACK_STATUS_NORMAL.getCode();
}
}

View File

@@ -0,0 +1,14 @@
package com.lld.im.service.friendship.model.req;
import com.lld.im.common.model.RequestBase;
import lombok.Data;
import javax.validation.constraints.NotBlank;
@Data
public class ReadFriendShipRequestReq extends RequestBase {
@NotBlank(message = "用户id不能为空")
private String fromId;
}

View File

@@ -0,0 +1,18 @@
package com.lld.im.service.friendship.model.req;
import com.lld.im.common.model.RequestBase;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
@Data
public class UpdateFriendReq extends RequestBase {
@NotBlank(message = "fromId不能为空")
private String fromId;
@NotNull(message = "toItem不能为空")
private FriendDto toItem;
}

View File

@@ -0,0 +1,30 @@
package com.lld.im.service.friendship.model.resp;
import lombok.Data;
@Data
public class CheckFriendShipResp {
private String fromId;
private String toId;
//校验状态根据双向校验和单向校验有不同的status
//单向校验1 from添加了to不确定to是否添加了from CheckResult_single_Type_AWithB
// 0 from没有添加to也不确定to有没有添加from CheckResult_single_Type_NoRelation
//双向校验 1 from添加了toto也添加了from CheckResult_Type_BothWay
// 2 from添加了t0to没有添加from CheckResult_Both_Type_AWithB
// 3 from没有添加toto添加了from CheckResult_Both_Type_BWithA
// 4 双方都没有添加 CheckResult_Both_Type_NoRelation
//单向校验黑名单1 from没有拉黑to不确定to是否拉黑了from CheckResult_singe_Type_AWithB
// 0 from拉黑to不确定to是佛拉黑from CheckResult_singe_Type_NoRelation
//双向校验黑名单 1 from没有拉黑toto也没有拉黑from CheckResult_Type_BothWay
// 2 from没有拉黑toto拉黑from CheckResult_Both_Type_AWithB
// 3 from拉黑了toto没有拉黑from CheckResult_Both_Type_BWithA
// 4 双方都拉黑 CheckResult_Both_Type_NoRelation
private Integer status;
}

View File

@@ -0,0 +1,14 @@
package com.lld.im.service.friendship.model.resp;
import lombok.Data;
import java.util.List;
@Data
public class ImportFriendShipResp {
private List<String> successId;
private List<String> errorId;
}

View File

@@ -0,0 +1,40 @@
package com.lld.im.service.friendship.service;
import com.lld.im.common.ResponseVO;
import com.lld.im.common.model.RequestBase;
import com.lld.im.service.friendship.model.req.*;
import java.util.List;
/**
* @description:
* @author: lld
* @version: 1.0
*/
public interface ImFriendService {
public ResponseVO importFriendShip(ImporFriendShipReq req);
public ResponseVO addFriend(AddFriendReq req);
public ResponseVO updateFriend(UpdateFriendReq req);
public ResponseVO deleteFriend(DeleteFriendReq req);
public ResponseVO deleteAllFriend(DeleteFriendReq req);
public ResponseVO getAllFriendShip(GetAllFriendShipReq req);
public ResponseVO getRelation(GetRelationReq req);
public ResponseVO doAddFriend(RequestBase requestBase,String fromId, FriendDto dto, Integer appId);
public ResponseVO checkFriendship(CheckFriendShipReq req);
public ResponseVO addBlack(AddFriendShipBlackReq req);
public ResponseVO deleteBlack(DeleteBlackReq req);
public ResponseVO checkBlck(CheckFriendShipReq req);
}

View File

@@ -0,0 +1,20 @@
package com.lld.im.service.friendship.service;
import com.lld.im.common.ResponseVO;
import com.lld.im.service.friendship.model.req.AddFriendShipGroupMemberReq;
import com.lld.im.service.friendship.model.req.DeleteFriendShipGroupMemberReq;
/**
* @author: Chackylee
* @description:
**/
public interface ImFriendShipGroupMemberService {
public ResponseVO addGroupMember(AddFriendShipGroupMemberReq req);
public ResponseVO delGroupMember(DeleteFriendShipGroupMemberReq req);
public int doAddGroupMember(Long groupId, String toId);
public int clearGroupMember(Long groupId);
}

View File

@@ -0,0 +1,21 @@
package com.lld.im.service.friendship.service;
import com.lld.im.common.ResponseVO;
import com.lld.im.service.friendship.dao.ImFriendShipGroupEntity;
import com.lld.im.service.friendship.model.req.AddFriendShipGroupReq;
import com.lld.im.service.friendship.model.req.DeleteFriendShipGroupReq;
/**
* @author: Chackylee
* @description:
**/
public interface ImFriendShipGroupService {
public ResponseVO addGroup(AddFriendShipGroupReq req);
public ResponseVO deleteGroup(DeleteFriendShipGroupReq req);
public ResponseVO<ImFriendShipGroupEntity> getGroup(String fromId, String groupName, Integer appId);
}

View File

@@ -0,0 +1,18 @@
package com.lld.im.service.friendship.service;
import com.lld.im.common.ResponseVO;
import com.lld.im.service.friendship.model.req.ApproverFriendRequestReq;
import com.lld.im.service.friendship.model.req.FriendDto;
import com.lld.im.service.friendship.model.req.ReadFriendShipRequestReq;
public interface ImFriendShipRequestService {
public ResponseVO addFienshipRequest(String fromId, FriendDto dto, Integer appId);
public ResponseVO approverFriendRequest(ApproverFriendRequestReq req);
public ResponseVO readFriendShipRequestReq(ReadFriendShipRequestReq req);
public ResponseVO getFriendRequest(String fromId, Integer appId);
}

View File

@@ -0,0 +1,439 @@
package com.lld.im.service.friendship.service.impl;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.lld.im.common.ResponseVO;
import com.lld.im.common.enums.AllowFriendTypeEnum;
import com.lld.im.common.enums.CheckFriendShipTypeEnum;
import com.lld.im.common.enums.FriendShipErrorCode;
import com.lld.im.common.enums.FriendShipStatusEnum;
import com.lld.im.common.exception.ApplicationException;
import com.lld.im.common.model.RequestBase;
import com.lld.im.service.friendship.dao.ImFriendShipEntity;
import com.lld.im.service.friendship.dao.mapper.ImFriendShipMapper;
import com.lld.im.service.friendship.model.req.*;
import com.lld.im.service.friendship.model.resp.CheckFriendShipResp;
import com.lld.im.service.friendship.model.resp.ImportFriendShipResp;
import com.lld.im.service.friendship.service.ImFriendService;
import com.lld.im.service.friendship.service.ImFriendShipRequestService;
import com.lld.im.service.user.dao.ImUserDataEntity;
import com.lld.im.service.user.service.ImUserService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
* @description:
* @author: lld
* @version: 1.0
*/
@Service
public class ImFriendServiceImpl implements ImFriendService {
@Autowired
ImFriendShipMapper imFriendShipMapper;
@Autowired
ImUserService imUserService;
@Autowired
ImFriendService imFriendService;
@Autowired
ImFriendShipRequestService imFriendShipRequestService;
@Override
public ResponseVO importFriendShip(ImporFriendShipReq req) {
if(req.getFriendItem().size() > 100){
return ResponseVO.errorResponse(FriendShipErrorCode.IMPORT_SIZE_BEYOND);
}
ImportFriendShipResp resp = new ImportFriendShipResp();
List<String> successId = new ArrayList<>();
List<String> errorId = new ArrayList<>();
for (ImporFriendShipReq.ImportFriendDto dto:
req.getFriendItem()) {
ImFriendShipEntity entity = new ImFriendShipEntity();
BeanUtils.copyProperties(dto,entity);
entity.setAppId(req.getAppId());
entity.setFromId(req.getFromId());
try {
int insert = imFriendShipMapper.insert(entity);
if(insert == 1){
successId.add(dto.getToId());
}else{
errorId.add(dto.getToId());
}
}catch (Exception e){
e.printStackTrace();
errorId.add(dto.getToId());
}
}
resp.setErrorId(errorId);
resp.setSuccessId(successId);
return ResponseVO.successResponse(resp);
}
@Override
public ResponseVO addFriend(AddFriendReq req) {
ResponseVO<ImUserDataEntity> fromInfo = imUserService.getSingleUserInfo(req.getFromId(), req.getAppId());
if(!fromInfo.isOk()){
return fromInfo;
}
ResponseVO<ImUserDataEntity> toInfo = imUserService.getSingleUserInfo(req.getToItem().getToId(), req.getAppId());
if(!toInfo.isOk()){
return toInfo;
}
ImUserDataEntity data = toInfo.getData();
if(data.getFriendAllowType() != null && data.getFriendAllowType() == AllowFriendTypeEnum.NOT_NEED.getCode()){
return this.doAddFriend(req,req.getFromId(), req.getToItem(), req.getAppId());
}else{
QueryWrapper<ImFriendShipEntity> query = new QueryWrapper<>();
query.eq("app_id",req.getAppId());
query.eq("from_id",req.getFromId());
query.eq("to_id",req.getToItem().getToId());
ImFriendShipEntity fromItem = imFriendShipMapper.selectOne(query);
if(fromItem == null || fromItem.getStatus()
!= FriendShipStatusEnum.FRIEND_STATUS_NORMAL.getCode()){
//插入一条好友申请的数据
ResponseVO responseVO = imFriendShipRequestService.addFienshipRequest(req.getFromId(), req.getToItem(), req.getAppId());
if(!responseVO.isOk()){
return responseVO;
}
}else{
return ResponseVO.errorResponse(FriendShipErrorCode.TO_IS_YOUR_FRIEND);
}
}
return ResponseVO.successResponse();
}
@Override
public ResponseVO updateFriend(UpdateFriendReq req) {
ResponseVO<ImUserDataEntity> fromInfo = imUserService.getSingleUserInfo(req.getFromId(), req.getAppId());
if(!fromInfo.isOk()){
return fromInfo;
}
ResponseVO<ImUserDataEntity> toInfo = imUserService.getSingleUserInfo(req.getToItem().getToId(), req.getAppId());
if(!toInfo.isOk()){
return toInfo;
}
ResponseVO responseVO = this.doUpdate(req.getFromId(), req.getToItem(), req.getAppId());
return responseVO;
}
@Transactional
public ResponseVO doUpdate(String fromId, FriendDto dto,Integer appId){
UpdateWrapper<ImFriendShipEntity> updateWrapper = new UpdateWrapper<>();
updateWrapper.lambda().set(ImFriendShipEntity::getAddSource,dto.getAddSource())
.set(ImFriendShipEntity::getExtra,dto.getExtra())
.set(ImFriendShipEntity::getRemark,dto.getRemark())
.eq(ImFriendShipEntity::getAppId,appId)
.eq(ImFriendShipEntity::getToId,dto.getToId())
.eq(ImFriendShipEntity::getFromId,fromId);
int update = imFriendShipMapper.update(null, updateWrapper);
if(update == 1){
return ResponseVO.successResponse();
}
return ResponseVO.errorResponse();
}
@Override
@Transactional
public ResponseVO doAddFriend(RequestBase requestBase,String fromId, FriendDto dto, Integer appId){
//A-B
//Friend表插入A 和 B 两条记录
//查询是否有记录存在,如果存在则判断状态,如果是已添加,则提示已添加,如果是未添加,则修改状态
QueryWrapper<ImFriendShipEntity> query = new QueryWrapper<>();
query.eq("app_id",appId);
query.eq("from_id",fromId);
query.eq("to_id",dto.getToId());
ImFriendShipEntity fromItem = imFriendShipMapper.selectOne(query);
if(fromItem == null){
//走添加逻辑。
fromItem = new ImFriendShipEntity();
fromItem.setAppId(appId);
fromItem.setFromId(fromId);
// entity.setToId(to);
BeanUtils.copyProperties(dto,fromItem);
fromItem.setStatus(FriendShipStatusEnum.FRIEND_STATUS_NORMAL.getCode());
fromItem.setCreateTime(System.currentTimeMillis());
int insert = imFriendShipMapper.insert(fromItem);
if(insert != 1){
return ResponseVO.errorResponse(FriendShipErrorCode.ADD_FRIEND_ERROR);
}
} else{
//如果存在则判断状态,如果是已添加,则提示已添加,如果是未添加,则修改状态
if(fromItem.getStatus() == FriendShipStatusEnum.FRIEND_STATUS_NORMAL.getCode()){
return ResponseVO.errorResponse(FriendShipErrorCode.TO_IS_YOUR_FRIEND);
} else{
ImFriendShipEntity update = new ImFriendShipEntity();
if(StringUtils.isNotBlank(dto.getAddSource())){
update.setAddSource(dto.getAddSource());
}
if(StringUtils.isNotBlank(dto.getRemark())){
update.setRemark(dto.getRemark());
}
if(StringUtils.isNotBlank(dto.getExtra())){
update.setExtra(dto.getExtra());
}
update.setStatus(FriendShipStatusEnum.FRIEND_STATUS_NORMAL.getCode());
int result = imFriendShipMapper.update(update, query);
if(result != 1){
return ResponseVO.errorResponse(FriendShipErrorCode.ADD_FRIEND_ERROR);
}
}
}
QueryWrapper<ImFriendShipEntity> toQuery = new QueryWrapper<>();
toQuery.eq("app_id",appId);
toQuery.eq("from_id",dto.getToId());
toQuery.eq("to_id",fromId);
ImFriendShipEntity toItem = imFriendShipMapper.selectOne(toQuery);
if(toItem == null){
toItem = new ImFriendShipEntity();
toItem.setAppId(appId);
toItem.setFromId(dto.getToId());
BeanUtils.copyProperties(dto,toItem);
toItem.setToId(fromId);
toItem.setStatus(FriendShipStatusEnum.FRIEND_STATUS_NORMAL.getCode());
toItem.setCreateTime(System.currentTimeMillis());
// toItem.setBlack(FriendShipStatusEnum.BLACK_STATUS_NORMAL.getCode());
int insert = imFriendShipMapper.insert(toItem);
}else{
if(FriendShipStatusEnum.FRIEND_STATUS_NORMAL.getCode() !=
toItem.getStatus()){
ImFriendShipEntity update = new ImFriendShipEntity();
update.setStatus(FriendShipStatusEnum.FRIEND_STATUS_NORMAL.getCode());
imFriendShipMapper.update(update,toQuery);
}
}
return ResponseVO.successResponse();
}
@Override
public ResponseVO deleteFriend(DeleteFriendReq req) {
QueryWrapper<ImFriendShipEntity> query = new QueryWrapper<>();
query.eq("app_id",req.getAppId());
query.eq("from_id",req.getFromId());
query.eq("to_id",req.getToId());
ImFriendShipEntity fromItem = imFriendShipMapper.selectOne(query);
if(fromItem == null){
return ResponseVO.errorResponse(FriendShipErrorCode.TO_IS_NOT_YOUR_FRIEND);
}else{
if(fromItem.getStatus() != null && fromItem.getStatus() == FriendShipStatusEnum.FRIEND_STATUS_NORMAL.getCode()){
ImFriendShipEntity update = new ImFriendShipEntity();
update.setStatus(FriendShipStatusEnum.FRIEND_STATUS_DELETE.getCode());
imFriendShipMapper.update(update,query);
}else{
return ResponseVO.errorResponse(FriendShipErrorCode.FRIEND_IS_DELETED);
}
}
return ResponseVO.successResponse();
}
@Override
public ResponseVO deleteAllFriend(DeleteFriendReq req) {
QueryWrapper<ImFriendShipEntity> query = new QueryWrapper<>();
query.eq("app_id",req.getAppId());
query.eq("from_id",req.getFromId());
query.eq("status",FriendShipStatusEnum.FRIEND_STATUS_NORMAL.getCode());
ImFriendShipEntity update = new ImFriendShipEntity();
update.setStatus(FriendShipStatusEnum.FRIEND_STATUS_DELETE.getCode());
imFriendShipMapper.update(update,query);
return ResponseVO.successResponse();
}
@Override
public ResponseVO getAllFriendShip(GetAllFriendShipReq req) {
QueryWrapper<ImFriendShipEntity> query = new QueryWrapper<>();
query.eq("app_id",req.getAppId());
query.eq("from_id",req.getFromId());
return ResponseVO.successResponse(imFriendShipMapper.selectList(query));
}
@Override
public ResponseVO getRelation(GetRelationReq req) {
QueryWrapper<ImFriendShipEntity> query = new QueryWrapper<>();
query.eq("app_id",req.getAppId());
query.eq("from_id",req.getFromId());
query.eq("to_id",req.getToId());
ImFriendShipEntity entity = imFriendShipMapper.selectOne(query);
if(entity == null){
return ResponseVO.errorResponse(FriendShipErrorCode.REPEATSHIP_IS_NOT_EXIST);
}
return ResponseVO.successResponse(entity);
}
@Override
public ResponseVO checkBlck(CheckFriendShipReq req) {
Map<String, Integer> toIdMap
= req.getToIds().stream().collect(Collectors
.toMap(Function.identity(), s -> 0));
List<CheckFriendShipResp> result = new ArrayList<>();
if (req.getCheckType() == CheckFriendShipTypeEnum.SINGLE.getType()) {
result = imFriendShipMapper.checkFriendShipBlack(req);
} else {
result = imFriendShipMapper.checkFriendShipBlackBoth(req);
}
Map<String, Integer> collect = result.stream()
.collect(Collectors
.toMap(CheckFriendShipResp::getToId,
CheckFriendShipResp::getStatus));
for (String toId:
toIdMap.keySet()) {
if(!collect.containsKey(toId)){
CheckFriendShipResp checkFriendShipResp = new CheckFriendShipResp();
checkFriendShipResp.setToId(toId);
checkFriendShipResp.setFromId(req.getFromId());
checkFriendShipResp.setStatus(toIdMap.get(toId));
result.add(checkFriendShipResp);
}
}
return ResponseVO.successResponse(result);
}
@Override
public ResponseVO addBlack(AddFriendShipBlackReq req) {
ResponseVO<ImUserDataEntity> fromInfo = imUserService.getSingleUserInfo(req.getFromId(), req.getAppId());
if(!fromInfo.isOk()){
return fromInfo;
}
ResponseVO<ImUserDataEntity> toInfo = imUserService.getSingleUserInfo(req.getToId(), req.getAppId());
if(!toInfo.isOk()){
return toInfo;
}
QueryWrapper<ImFriendShipEntity> query = new QueryWrapper<>();
query.eq("app_id",req.getAppId());
query.eq("from_id",req.getFromId());
query.eq("to_id",req.getToId());
ImFriendShipEntity fromItem = imFriendShipMapper.selectOne(query);
if(fromItem == null){
//走添加逻辑。
fromItem = new ImFriendShipEntity();
fromItem.setFromId(req.getFromId());
fromItem.setToId(req.getToId());
fromItem.setAppId(req.getAppId());
fromItem.setBlack(FriendShipStatusEnum.BLACK_STATUS_BLACKED.getCode());
fromItem.setCreateTime(System.currentTimeMillis());
int insert = imFriendShipMapper.insert(fromItem);
if(insert != 1){
return ResponseVO.errorResponse(FriendShipErrorCode.ADD_FRIEND_ERROR);
}
} else{
//如果存在则判断状态,如果是拉黑,则提示已拉黑,如果是未拉黑,则修改状态
if(fromItem.getBlack() != null && fromItem.getBlack() == FriendShipStatusEnum.BLACK_STATUS_BLACKED.getCode()){
return ResponseVO.errorResponse(FriendShipErrorCode.FRIEND_IS_BLACK);
} else {
ImFriendShipEntity update = new ImFriendShipEntity();
update.setBlack(FriendShipStatusEnum.BLACK_STATUS_BLACKED.getCode());
int result = imFriendShipMapper.update(update, query);
if(result != 1){
return ResponseVO.errorResponse(FriendShipErrorCode.ADD_BLACK_ERROR);
}
}
}
return ResponseVO.successResponse();
}
@Override
public ResponseVO deleteBlack(DeleteBlackReq req) {
QueryWrapper queryFrom = new QueryWrapper<>()
.eq("from_id", req.getFromId())
.eq("app_id", req.getAppId())
.eq("to_id", req.getToId());
ImFriendShipEntity fromItem = imFriendShipMapper.selectOne(queryFrom);
if (fromItem.getBlack() != null && fromItem.getBlack() == FriendShipStatusEnum.BLACK_STATUS_NORMAL.getCode()) {
throw new ApplicationException(FriendShipErrorCode.FRIEND_IS_NOT_YOUR_BLACK);
}
ImFriendShipEntity update = new ImFriendShipEntity();
update.setBlack(FriendShipStatusEnum.BLACK_STATUS_NORMAL.getCode());
int update1 = imFriendShipMapper.update(update, queryFrom);
if(update1 == 1){
return ResponseVO.successResponse();
}
return ResponseVO.errorResponse();
}
@Override
public ResponseVO checkFriendship(CheckFriendShipReq req) {
Map<String, Integer> result
= req.getToIds().stream()
.collect(Collectors.toMap(Function.identity(), s -> 0));
List<CheckFriendShipResp> resp = new ArrayList<>();
if(req.getCheckType() == CheckFriendShipTypeEnum.SINGLE.getType()){
resp =imFriendShipMapper.checkFriendShip(req);
}else {
resp =imFriendShipMapper.checkFriendShipBoth(req);
}
Map<String, Integer> collect = resp.stream()
.collect(Collectors.toMap(CheckFriendShipResp::getToId
, CheckFriendShipResp::getStatus));
for (String toId : result.keySet()){
if(!collect.containsKey(toId)){
CheckFriendShipResp checkFriendShipResp = new CheckFriendShipResp();
checkFriendShipResp.setFromId(req.getFromId());
checkFriendShipResp.setToId(toId);
checkFriendShipResp.setStatus(result.get(toId));
resp.add(checkFriendShipResp);
}
}
return ResponseVO.successResponse(resp);
}
}

View File

@@ -0,0 +1,122 @@
package com.lld.im.service.friendship.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.lld.im.common.ResponseVO;
import com.lld.im.service.friendship.dao.ImFriendShipGroupEntity;
import com.lld.im.service.friendship.dao.ImFriendShipGroupMemberEntity;
import com.lld.im.service.friendship.dao.mapper.ImFriendShipGroupMemberMapper;
import com.lld.im.service.friendship.model.req.AddFriendShipGroupMemberReq;
import com.lld.im.service.friendship.model.req.DeleteFriendShipGroupMemberReq;
import com.lld.im.service.friendship.service.ImFriendShipGroupMemberService;
import com.lld.im.service.friendship.service.ImFriendShipGroupService;
import com.lld.im.service.user.dao.ImUserDataEntity;
import com.lld.im.service.user.service.ImUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.List;
/**
* @author: Chackylee
* @description:
**/
@Service
public class ImFriendShipGroupMemberServiceImpl
implements ImFriendShipGroupMemberService {
@Autowired
ImFriendShipGroupMemberMapper imFriendShipGroupMemberMapper;
@Autowired
ImFriendShipGroupService imFriendShipGroupService;
@Autowired
ImUserService imUserService;
@Autowired
ImFriendShipGroupMemberService thisService;
@Override
@Transactional
public ResponseVO addGroupMember(AddFriendShipGroupMemberReq req) {
ResponseVO<ImFriendShipGroupEntity> group = imFriendShipGroupService
.getGroup(req.getFromId(),req.getGroupName(),req.getAppId());
if(!group.isOk()){
return group;
}
List<String> successId = new ArrayList<>();
for (String toId : req.getToIds()) {
ResponseVO<ImUserDataEntity> singleUserInfo = imUserService.getSingleUserInfo(toId, req.getAppId());
if(singleUserInfo.isOk()){
int i = thisService.doAddGroupMember(group.getData().getGroupId(), toId);
if(i == 1){
successId.add(toId);
}
}
}
return ResponseVO.successResponse(successId);
}
@Override
public ResponseVO delGroupMember(DeleteFriendShipGroupMemberReq req) {
ResponseVO<ImFriendShipGroupEntity> group = imFriendShipGroupService
.getGroup(req.getFromId(),req.getGroupName(),req.getAppId());
if(!group.isOk()){
return group;
}
ArrayList list = new ArrayList();
for (String toId : req.getToIds()) {
ResponseVO<ImUserDataEntity> singleUserInfo = imUserService.getSingleUserInfo(toId, req.getAppId());
if(singleUserInfo.isOk()){
int i = deleteGroupMember(group.getData().getGroupId(), toId);
if(i == 1){
list.add(toId);
}
}
}
return ResponseVO.successResponse(list);
}
@Override
public int doAddGroupMember(Long groupId, String toId) {
ImFriendShipGroupMemberEntity imFriendShipGroupMemberEntity = new ImFriendShipGroupMemberEntity();
imFriendShipGroupMemberEntity.setGroupId(groupId);
imFriendShipGroupMemberEntity.setToId(toId);
try {
int insert = imFriendShipGroupMemberMapper.insert(imFriendShipGroupMemberEntity);
return insert;
}catch (Exception e){
e.printStackTrace();
return 0;
}
}
public int deleteGroupMember(Long groupId, String toId) {
QueryWrapper<ImFriendShipGroupMemberEntity> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("group_id",groupId);
queryWrapper.eq("to_id",toId);
try {
int delete = imFriendShipGroupMemberMapper.delete(queryWrapper);
// int insert = imFriendShipGroupMemberMapper.insert(imFriendShipGroupMemberEntity);
return delete;
}catch (Exception e){
e.printStackTrace();
return 0;
}
}
@Override
public int clearGroupMember(Long groupId) {
QueryWrapper<ImFriendShipGroupMemberEntity> query = new QueryWrapper<>();
query.eq("group_id",groupId);
int delete = imFriendShipGroupMemberMapper.delete(query);
return delete;
}
}

View File

@@ -0,0 +1,119 @@
package com.lld.im.service.friendship.service.impl;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.lld.im.common.ResponseVO;
import com.lld.im.common.enums.DelFlagEnum;
import com.lld.im.common.enums.FriendShipErrorCode;
import com.lld.im.service.friendship.dao.ImFriendShipGroupEntity;
import com.lld.im.service.friendship.dao.mapper.ImFriendShipGroupMapper;
import com.lld.im.service.friendship.model.req.AddFriendShipGroupMemberReq;
import com.lld.im.service.friendship.model.req.AddFriendShipGroupReq;
import com.lld.im.service.friendship.model.req.DeleteFriendShipGroupReq;
import com.lld.im.service.friendship.service.ImFriendShipGroupMemberService;
import com.lld.im.service.friendship.service.ImFriendShipGroupService;
import com.lld.im.service.user.service.ImUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
public class ImFriendShipGroupServiceImpl implements ImFriendShipGroupService {
@Autowired
ImFriendShipGroupMapper imFriendShipGroupMapper;
@Autowired
ImFriendShipGroupMemberService imFriendShipGroupMemberService;
@Autowired
ImUserService imUserService;
@Override
@Transactional
public ResponseVO addGroup(AddFriendShipGroupReq req) {
QueryWrapper<ImFriendShipGroupEntity> query = new QueryWrapper<>();
query.eq("group_name", req.getGroupName());
query.eq("app_id", req.getAppId());
query.eq("from_id", req.getFromId());
query.eq("del_flag", DelFlagEnum.NORMAL.getCode());
ImFriendShipGroupEntity entity = imFriendShipGroupMapper.selectOne(query);
if (entity != null) {
return ResponseVO.errorResponse(FriendShipErrorCode.FRIEND_SHIP_GROUP_IS_EXIST);
}
//写入db
ImFriendShipGroupEntity insert = new ImFriendShipGroupEntity();
insert.setAppId(req.getAppId());
insert.setCreateTime(System.currentTimeMillis());
insert.setDelFlag(DelFlagEnum.NORMAL.getCode());
insert.setGroupName(req.getGroupName());
insert.setFromId(req.getFromId());
try {
int insert1 = imFriendShipGroupMapper.insert(insert);
if (insert1 != 1) {
return ResponseVO.errorResponse(FriendShipErrorCode.FRIEND_SHIP_GROUP_CREATE_ERROR);
}
if (insert1 == 1 && CollectionUtil.isNotEmpty(req.getToIds())) {
AddFriendShipGroupMemberReq addFriendShipGroupMemberReq = new AddFriendShipGroupMemberReq();
addFriendShipGroupMemberReq.setFromId(req.getFromId());
addFriendShipGroupMemberReq.setGroupName(req.getGroupName());
addFriendShipGroupMemberReq.setToIds(req.getToIds());
addFriendShipGroupMemberReq.setAppId(req.getAppId());
imFriendShipGroupMemberService.addGroupMember(addFriendShipGroupMemberReq);
return ResponseVO.successResponse();
}
} catch (DuplicateKeyException e) {
e.getStackTrace();
return ResponseVO.errorResponse(FriendShipErrorCode.FRIEND_SHIP_GROUP_IS_EXIST);
}
return ResponseVO.successResponse();
}
@Override
@Transactional
public ResponseVO deleteGroup(DeleteFriendShipGroupReq req) {
for (String groupName : req.getGroupName()) {
QueryWrapper<ImFriendShipGroupEntity> query = new QueryWrapper<>();
query.eq("group_name", groupName);
query.eq("app_id", req.getAppId());
query.eq("from_id", req.getFromId());
query.eq("del_flag", DelFlagEnum.NORMAL.getCode());
ImFriendShipGroupEntity entity = imFriendShipGroupMapper.selectOne(query);
if (entity != null) {
ImFriendShipGroupEntity update = new ImFriendShipGroupEntity();
update.setGroupId(entity.getGroupId());
update.setDelFlag(DelFlagEnum.DELETE.getCode());
imFriendShipGroupMapper.updateById(update);
imFriendShipGroupMemberService.clearGroupMember(entity.getGroupId());
}
}
return ResponseVO.successResponse();
}
@Override
public ResponseVO getGroup(String fromId, String groupName, Integer appId) {
QueryWrapper<ImFriendShipGroupEntity> query = new QueryWrapper<>();
query.eq("group_name", groupName);
query.eq("app_id", appId);
query.eq("from_id", fromId);
query.eq("del_flag", DelFlagEnum.NORMAL.getCode());
ImFriendShipGroupEntity entity = imFriendShipGroupMapper.selectOne(query);
if (entity == null) {
return ResponseVO.errorResponse(FriendShipErrorCode.FRIEND_SHIP_GROUP_IS_NOT_EXIST);
}
return ResponseVO.successResponse(entity);
}
}

View File

@@ -0,0 +1,140 @@
package com.lld.im.service.friendship.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.lld.im.common.ResponseVO;
import com.lld.im.common.enums.ApproverFriendRequestStatusEnum;
import com.lld.im.common.enums.FriendShipErrorCode;
import com.lld.im.common.exception.ApplicationException;
import com.lld.im.service.friendship.dao.ImFriendShipRequestEntity;
import com.lld.im.service.friendship.dao.mapper.ImFriendShipRequestMapper;
import com.lld.im.service.friendship.model.req.ApproverFriendRequestReq;
import com.lld.im.service.friendship.model.req.FriendDto;
import com.lld.im.service.friendship.model.req.ReadFriendShipRequestReq;
import com.lld.im.service.friendship.service.ImFriendService;
import com.lld.im.service.friendship.service.ImFriendShipRequestService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@Service
public class ImFriendShipRequestServiceImpl implements ImFriendShipRequestService {
@Autowired
ImFriendShipRequestMapper imFriendShipRequestMapper;
@Autowired
ImFriendService imFriendShipService;
@Override
public ResponseVO getFriendRequest(String fromId, Integer appId) {
QueryWrapper<ImFriendShipRequestEntity> query = new QueryWrapper();
query.eq("app_id", appId);
query.eq("to_id", fromId);
List<ImFriendShipRequestEntity> requestList = imFriendShipRequestMapper.selectList(query);
return ResponseVO.successResponse(requestList);
}
//A + B
@Override
public ResponseVO addFienshipRequest(String fromId, FriendDto dto, Integer appId) {
QueryWrapper<ImFriendShipRequestEntity> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("app_id",appId);
queryWrapper.eq("from_id",fromId);
queryWrapper.eq("to_id",dto.getToId());
ImFriendShipRequestEntity request = imFriendShipRequestMapper.selectOne(queryWrapper);
if(request == null){
request = new ImFriendShipRequestEntity();
request.setAddSource(dto.getAddSource());
request.setAddWording(dto.getAddWording());
request.setAppId(appId);
request.setFromId(fromId);
request.setToId(dto.getToId());
request.setReadStatus(0);
request.setApproveStatus(0);
request.setRemark(dto.getRemark());
request.setCreateTime(System.currentTimeMillis());
imFriendShipRequestMapper.insert(request);
}else {
//修改记录内容 和更新时间
if(StringUtils.isNotBlank(dto.getAddSource())){
request.setAddWording(dto.getAddWording());
}
if(StringUtils.isNotBlank(dto.getRemark())){
request.setRemark(dto.getRemark());
}
if(StringUtils.isNotBlank(dto.getAddWording())){
request.setAddWording(dto.getAddWording());
}
request.setApproveStatus(0);
request.setReadStatus(0);
imFriendShipRequestMapper.updateById(request);
}
return ResponseVO.successResponse();
}
@Override
@Transactional
public ResponseVO approverFriendRequest(ApproverFriendRequestReq req) {
ImFriendShipRequestEntity imFriendShipRequestEntity = imFriendShipRequestMapper.selectById(req.getId());
if(imFriendShipRequestEntity == null){
throw new ApplicationException(FriendShipErrorCode.FRIEND_REQUEST_IS_NOT_EXIST);
}
if(!req.getOperater().equals(imFriendShipRequestEntity.getToId())){
//只能审批发给自己的好友请求
throw new ApplicationException(FriendShipErrorCode.NOT_APPROVER_OTHER_MAN_REQUEST);
}
ImFriendShipRequestEntity update = new ImFriendShipRequestEntity();
update.setApproveStatus(req.getStatus());
update.setUpdateTime(System.currentTimeMillis());
update.setId(req.getId());
imFriendShipRequestMapper.updateById(update);
if(ApproverFriendRequestStatusEnum.AGREE.getCode() == req.getStatus()){
//同意 ===> 去执行添加好友逻辑
FriendDto dto = new FriendDto();
dto.setAddSource(imFriendShipRequestEntity.getAddSource());
dto.setAddWording(imFriendShipRequestEntity.getAddWording());
dto.setRemark(imFriendShipRequestEntity.getRemark());
dto.setToId(imFriendShipRequestEntity.getToId());
ResponseVO responseVO = imFriendShipService.doAddFriend(req,imFriendShipRequestEntity.getFromId(), dto,req.getAppId());
// if(!responseVO.isOk()){
//// TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
// return responseVO;
// }
if(!responseVO.isOk() && responseVO.getCode() != FriendShipErrorCode.TO_IS_YOUR_FRIEND.getCode()){
return responseVO;
}
}
return ResponseVO.successResponse();
}
@Override
public ResponseVO readFriendShipRequestReq(ReadFriendShipRequestReq req) {
QueryWrapper<ImFriendShipRequestEntity> query = new QueryWrapper<>();
query.eq("app_id", req.getAppId());
query.eq("to_id", req.getFromId());
ImFriendShipRequestEntity update = new ImFriendShipRequestEntity();
update.setReadStatus(1);
imFriendShipRequestMapper.update(update, query);
return ResponseVO.successResponse();
}
}

View File

@@ -0,0 +1,80 @@
package com.lld.im.service.group.controller;
import com.lld.im.common.ResponseVO;
import com.lld.im.service.group.model.req.*;
import com.lld.im.service.group.service.ImGroupService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @description:
* @author: lld
* @version: 1.0
*/
@RestController
@RequestMapping("v1/group")
public class ImGroupController {
@Autowired
ImGroupService groupService;
@RequestMapping("/importGroup")
public ResponseVO importGroup(@RequestBody @Validated ImportGroupReq req, Integer appId, String identifier) {
req.setAppId(appId);
req.setOperater(identifier);
return groupService.importGroup(req);
}
@RequestMapping("/createGroup")
public ResponseVO createGroup(@RequestBody @Validated CreateGroupReq req, Integer appId, String identifier) {
req.setAppId(appId);
req.setOperater(identifier);
return groupService.createGroup(req);
}
@RequestMapping("/getGroupInfo")
public ResponseVO getGroupInfo(@RequestBody @Validated GetGroupReq req, Integer appId) {
req.setAppId(appId);
return groupService.getGroup(req);
}
@RequestMapping("/update")
public ResponseVO update(@RequestBody @Validated UpdateGroupReq req, Integer appId, String identifier) {
req.setAppId(appId);
req.setOperater(identifier);
return groupService.updateBaseGroupInfo(req);
}
@RequestMapping("/getJoinedGroup")
public ResponseVO getJoinedGroup(@RequestBody @Validated GetJoinedGroupReq req, Integer appId, String identifier) {
req.setAppId(appId);
req.setOperater(identifier);
return groupService.getJoinedGroup(req);
}
@RequestMapping("/destroyGroup")
public ResponseVO destroyGroup(@RequestBody @Validated DestroyGroupReq req, Integer appId, String identifier) {
req.setAppId(appId);
req.setOperater(identifier);
return groupService.destroyGroup(req);
}
@RequestMapping("/transferGroup")
public ResponseVO transferGroup(@RequestBody @Validated TransferGroupReq req, Integer appId, String identifier) {
req.setAppId(appId);
req.setOperater(identifier);
return groupService.transferGroup(req);
}
@RequestMapping("/forbidSendMessage")
public ResponseVO forbidSendMessage(@RequestBody @Validated MuteGroupReq req, Integer appId, String identifier) {
req.setAppId(appId);
req.setOperater(identifier);
return groupService.muteGroup(req);
}
}

View File

@@ -0,0 +1,59 @@
package com.lld.im.service.group.controller;
import com.lld.im.common.ResponseVO;
import com.lld.im.service.group.model.req.*;
import com.lld.im.service.group.service.ImGroupMemberService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @description:
* @author: lld
* @version: 1.0
*/
@RestController
@RequestMapping("v1/group/member")
public class ImGroupMemberController {
@Autowired
ImGroupMemberService groupMemberService;
@RequestMapping("/importGroupMember")
public ResponseVO importGroupMember(@RequestBody @Validated ImportGroupMemberReq req, Integer appId, String identifier) {
req.setAppId(appId);
req.setOperater(identifier);
return groupMemberService.importGroupMember(req);
}
@RequestMapping("/add")
public ResponseVO addMember(@RequestBody @Validated AddGroupMemberReq req, Integer appId, String identifier) {
req.setAppId(appId);
req.setOperater(identifier);
return groupMemberService.addMember(req);
}
@RequestMapping("/remove")
public ResponseVO removeMember(@RequestBody @Validated RemoveGroupMemberReq req, Integer appId, String identifier) {
req.setAppId(appId);
req.setOperater(identifier);
return groupMemberService.removeMember(req);
}
@RequestMapping("/update")
public ResponseVO updateGroupMember(@RequestBody @Validated UpdateGroupMemberReq req, Integer appId, String identifier) {
req.setAppId(appId);
req.setOperater(identifier);
return groupMemberService.updateGroupMember(req);
}
@RequestMapping("/speak")
public ResponseVO speak(@RequestBody @Validated SpeaMemberReq req, Integer appId, String identifier) {
req.setAppId(appId);
req.setOperater(identifier);
return groupMemberService.speak(req);
}
}

View File

@@ -0,0 +1,54 @@
package com.lld.im.service.group.dao;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
/**
* @description:
* @author: lld
* @version: 1.0
*/
@Data
@TableName("im_group")
public class ImGroupEntity {
@TableId(value = "group_id")
private String groupId;
private Integer appId;
//群主id
private String ownerId;
//群类型 1私有群类似微信 2公开群(类似qq
private Integer groupType;
private String groupName;
private Integer mute;// 是否全员禁言0 不禁言1 全员禁言。
// 申请加群选项包括如下几种:
// 0 表示禁止任何人申请加入
// 1 表示需要群主或管理员审批
// 2 表示允许无需审批自由加入群组
private Integer applyJoinType;
private String introduction;//群简介
private String notification;//群公告
private String photo;//群头像
private Integer maxMemberCount;//群成员上限
private Integer status;//群状态 0正常 1解散
private Long sequence;
private Long createTime;
private Long updateTime;
private String extra;
}

View File

@@ -0,0 +1,44 @@
package com.lld.im.service.group.dao;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
/**
* @description:
* @author: lld
* @version: 1.0
*/
@Data
@TableName("im_group_member")
public class ImGroupMemberEntity {
@TableId(type = IdType.AUTO)
private Long groupMemberId;
private Integer appId;
private String groupId;
//成员id
private String memberId;
//群成员类型0 普通成员, 1 管理员, 2 群主, 3 禁言4 已经移除的成员
private Integer role;
private Long speakDate;
//群昵称
private String alias;
//加入时间
private Long joinTime;
//离开时间
private Long leaveTime;
private String joinType;
private String extra;
}

View File

@@ -0,0 +1,32 @@
package com.lld.im.service.group.dao;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
/**
* @author: Chackylee
* @description:
**/
@Data
@TableName("im_group_message_history")
public class ImGroupMessageHistoryEntity {
private Integer appId;
private String fromId;
private String groupId;
/** messageBodyId*/
private Long messageKey;
/** 序列号*/
private Long sequence;
private String messageRandom;
private Long messageTime;
private Long createTime;
}

View File

@@ -0,0 +1,13 @@
package com.lld.im.service.group.dao.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.lld.im.service.group.dao.ImGroupEntity;
import org.apache.ibatis.annotations.Select;
import org.springframework.stereotype.Repository;
import java.util.Collection;
@Repository
public interface ImGroupMapper extends BaseMapper<ImGroupEntity> {
}

View File

@@ -0,0 +1,65 @@
package com.lld.im.service.group.dao.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.lld.im.service.group.dao.ImGroupMemberEntity;
import com.lld.im.service.group.model.req.GroupMemberDto;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface ImGroupMemberMapper extends BaseMapper<ImGroupMemberEntity> {
@Select("select group_id from im_group_member where app_id = #{appId} AND member_id = #{memberId} ")
public List<String> getJoinedGroupId(Integer appId, String memberId);
@Results({
@Result(column = "member_id", property = "memberId"),
// @Result(column = "speak_flag", property = "speakFlag"),
@Result(column = "speak_date", property = "speakDate"),
@Result(column = "role", property = "role"),
@Result(column = "alias", property = "alias"),
@Result(column = "join_time", property = "joinTime"),
@Result(column = "join_type", property = "joinType")
})
@Select("select " +
" member_id, " +
// " speak_flag, " +
" speak_date, " +
" role, " +
" alias, " +
" join_time ," +
" join_type " +
" from im_group_member where app_id = #{appId} AND group_id = #{groupId} ")
public List<GroupMemberDto> getGroupMember(Integer appId, String groupId);
@Select("select " +
" member_id " +
" from im_group_member where app_id = #{appId} AND group_id = #{groupId} and role != 3")
public List<String> getGroupMemberId(Integer appId, String groupId);
@Results({
@Result(column = "member_id", property = "memberId"),
// @Result(column = "speak_flag", property = "speakFlag"),
@Result(column = "role", property = "role")
// @Result(column = "alias", property = "alias"),
// @Result(column = "join_time", property = "joinTime"),
// @Result(column = "join_type", property = "joinType")
})
@Select("select " +
" member_id, " +
// " speak_flag, " +
" role " +
// " alias, " +
// " join_time ," +
// " join_type " +
" from im_group_member where app_id = #{appId} AND group_id = #{groupId} and role in (1,2) ")
public List<GroupMemberDto> getGroupManager(String groupId, Integer appId);
}

View File

@@ -0,0 +1,11 @@
package com.lld.im.service.group.dao.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.lld.im.service.group.dao.ImGroupMessageHistoryEntity;
import org.springframework.stereotype.Repository;
@Repository
public interface ImGroupMessageHistoryMapper extends BaseMapper<ImGroupMessageHistoryEntity> {
}

View File

@@ -0,0 +1,24 @@
package com.lld.im.service.group.model.req;
import com.lld.im.common.model.RequestBase;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotEmpty;
import java.util.List;
/**
* @description:
* @author: lld
* @version: 1.0
*/
@Data
public class AddGroupMemberReq extends RequestBase {
@NotBlank(message = "群id不能为空")
private String groupId;
@NotEmpty(message = "群成员不能为空")
private List<GroupMemberDto> members;
}

View File

@@ -0,0 +1,41 @@
package com.lld.im.service.group.model.req;
import com.lld.im.common.model.RequestBase;
import lombok.Data;
import java.util.List;
/**
* @description:
* @author: lld
* @version: 1.0
*/
@Data
public class CreateGroupReq extends RequestBase {
private String groupId;
//群主id
private String ownerId;
//群类型 1私有群类似微信 2公开群(类似qq
private Integer groupType;
private String groupName;
private Integer mute;// 是否全员禁言0 不禁言1 全员禁言。
private Integer applyJoinType;//加入群权限0 所有人可以加入1 群成员可以拉人2 群管理员或群组可以拉人。
private String introduction;//群简介
private String notification;//群公告
private String photo;//群头像
private Integer MaxMemberCount;
private List<GroupMemberDto> member;
private String extra;
}

View File

@@ -0,0 +1,18 @@
package com.lld.im.service.group.model.req;
import com.lld.im.common.model.RequestBase;
import lombok.Data;
import javax.validation.constraints.NotNull;
/**
* @author: Chackylee
* @description:
**/
@Data
public class DestroyGroupReq extends RequestBase {
@NotNull(message = "群id不能为空")
private String groupId;
}

View File

@@ -0,0 +1,15 @@
package com.lld.im.service.group.model.req;
import com.lld.im.common.model.RequestBase;
import lombok.Data;
/**
* @author: Chackylee
* @description:
**/
@Data
public class GetGroupReq extends RequestBase {
private String groupId;
}

View File

@@ -0,0 +1,29 @@
package com.lld.im.service.group.model.req;
import com.lld.im.common.model.RequestBase;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import java.util.List;
/**
* @author: Chackylee
* @description:
**/
@Data
public class GetJoinedGroupReq extends RequestBase {
@NotBlank(message = "用户id不能为空")
private String memberId;
//群类型
private List<Integer> groupType;
//单次拉取的群组数量,如果不填代表所有群组
private Integer limit;
//第几页
private Integer offset;
}

View File

@@ -0,0 +1,18 @@
package com.lld.im.service.group.model.req;
import com.lld.im.common.model.RequestBase;
import lombok.Data;
import java.util.List;
/**
* @author: Chackylee
* @description:
**/
@Data
public class GetRoleInGroupReq extends RequestBase {
private String groupId;
private List<String> memberId;
}

View File

@@ -0,0 +1,28 @@
package com.lld.im.service.group.model.req;
import lombok.Data;
/**
* @description:
* @author: lld
* @version: 1.0
*/
@Data
public class GroupMemberDto {
private String memberId;
private String alias;
private Integer role;//群成员类型0 普通成员, 1 管理员, 2 群主, 3 已经移除的成员当修改群成员信息时只能取值0/1其他值由其他接口实现暂不支持3
// private Integer speakFlag;
private Long speakDate;
private String joinType;
private Long joinTime;
}

View File

@@ -0,0 +1,22 @@
package com.lld.im.service.group.model.req;
import com.lld.im.common.model.RequestBase;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import java.util.List;
/**
* @description:
* @author: lld
* @version: 1.0
*/
@Data
public class ImportGroupMemberReq extends RequestBase {
@NotBlank(message = "群id不能为空")
private String groupId;
private List<GroupMemberDto> members;
}

View File

@@ -0,0 +1,42 @@
package com.lld.im.service.group.model.req;
import com.lld.im.common.model.RequestBase;
import lombok.Data;
import javax.validation.constraints.NotBlank;
/**
* @description:
* @author: lld
* @version: 1.0
*/
@Data
public class ImportGroupReq extends RequestBase {
private String groupId;
//群主id
private String ownerId;
//群类型 1私有群类似微信 2公开群(类似qq
private Integer groupType;
@NotBlank(message = "群名称不能为空")
private String groupName;
private Integer mute;// 是否全员禁言0 不禁言1 全员禁言。
private Integer applyJoinType;//加入群权限0 所有人可以加入1 群成员可以拉人2 群管理员或群组可以拉人。
private String introduction;//群简介
private String notification;//群公告
private String photo;//群头像
private Integer MaxMemberCount;
private Long createTime;
private String extra;
}

View File

@@ -0,0 +1,22 @@
package com.lld.im.service.group.model.req;
import com.lld.im.common.model.RequestBase;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
/**
* @author: Chackylee
* @description:
**/
@Data
public class MuteGroupReq extends RequestBase {
@NotBlank(message = "groupId不能为空")
private String groupId;
@NotNull(message = "mute不能为空")
private Integer mute;
}

View File

@@ -0,0 +1,20 @@
package com.lld.im.service.group.model.req;
import com.lld.im.common.model.RequestBase;
import lombok.Data;
import javax.validation.constraints.NotBlank;
/**
* @author: Chackylee
* @description:
**/
@Data
public class RemoveGroupMemberReq extends RequestBase {
@NotBlank(message = "群id不能为空")
private String groupId;
private String memberId;
}

View File

@@ -0,0 +1,35 @@
package com.lld.im.service.group.model.req;
import com.lld.im.common.model.RequestBase;
import lombok.Data;
/**
* @description:
* @author: lld
* @version: 1.0
*/
@Data
public class SendGroupMessageReq extends RequestBase {
//客户端传的messageId
private String messageId;
private String fromId;
private String groupId;
private int messageRandom;
private long messageTime;
private String messageBody;
/**
* 这个字段缺省或者为 0 表示需要计数,为 1 表示本条消息不需要计数,即右上角图标数字不增加
*/
private int badgeMode;
private Long messageLifeTime;
private Integer appId;
}

View File

@@ -0,0 +1,25 @@
package com.lld.im.service.group.model.req;
import com.lld.im.common.model.RequestBase;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
/**
* @author: Chackylee
* @description:
**/
@Data
public class SpeaMemberReq extends RequestBase {
@NotBlank(message = "群id不能为空")
private String groupId;
@NotBlank(message = "memberId不能为空")
private String memberId;
//禁言时间,单位毫秒
@NotNull(message = "禁言时间不能为空")
private Long speakDate;
}

View File

@@ -0,0 +1,17 @@
package com.lld.im.service.group.model.req;
import com.lld.im.common.model.RequestBase;
import lombok.Data;
import javax.validation.constraints.NotNull;
@Data
public class TransferGroupReq extends RequestBase {
@NotNull(message = "群id不能为空")
private String groupId;
private String ownerId;
}

View File

@@ -0,0 +1,27 @@
package com.lld.im.service.group.model.req;
import com.lld.im.common.model.RequestBase;
import lombok.Data;
import javax.validation.constraints.NotBlank;
/**
* @author: Chackylee
* @description:
**/
@Data
public class UpdateGroupMemberReq extends RequestBase {
@NotBlank(message = "群id不能为空")
private String groupId;
@NotBlank(message = "memberId不能为空")
private String memberId;
private String alias;
private Integer role;
private String extra;
}

View File

@@ -0,0 +1,34 @@
package com.lld.im.service.group.model.req;
import com.lld.im.common.model.RequestBase;
import lombok.Data;
import javax.validation.constraints.NotBlank;
/**
* @author: Chackylee
* @description:
**/
@Data
public class UpdateGroupReq extends RequestBase {
@NotBlank(message = "群id不能为空")
private String groupId;
private String groupName;
private Integer mute;// 是否全员禁言0 不禁言1 全员禁言。
private Integer applyJoinType;//加入群权限0 所有人可以加入1 群成员可以拉人2 群管理员或群组可以拉人。
private String introduction;//群简介
private String notification;//群公告
private String photo;//群头像
private Integer maxMemberCount;//群成员上限
private String extra;
}

View File

@@ -0,0 +1,19 @@
package com.lld.im.service.group.model.resp;
import lombok.Data;
/**
* @description:
* @author: lld
* @version: 1.0
*/
@Data
public class AddMemberResp {
private String memberId;
// 加人结果0 为成功1 为失败2 为已经是群成员
private Integer result;
private String resultMessage;
}

View File

@@ -0,0 +1,48 @@
package com.lld.im.service.group.model.resp;
import com.lld.im.service.group.model.req.GroupMemberDto;
import lombok.Data;
import java.util.List;
/**
* @author: Chackylee
* @description:
**/
@Data
public class GetGroupResp {
private String groupId;
private Integer appId;
//群主id
private String ownerId;
//群类型 1私有群类似微信 2公开群(类似qq
private Integer groupType;
private String groupName;
private Integer mute;// 是否全员禁言0 不禁言1 全员禁言。
// 申请加群选项包括如下几种:
// 0 表示禁止任何人申请加入
// 1 表示需要群主或管理员审批
// 2 表示允许无需审批自由加入群组
private Integer applyJoinType;
private Integer privateChat; //是否禁止私聊0 允许群成员发起私聊1 不允许群成员发起私聊。
private String introduction;//群简介
private String notification;//群公告
private String photo;//群头像
private Integer maxMemberCount;//群成员上限
private Integer status;//群状态 0正常 1解散
private List<GroupMemberDto> memberList;
}

View File

@@ -0,0 +1,19 @@
package com.lld.im.service.group.model.resp;
import com.lld.im.service.group.dao.ImGroupEntity;
import lombok.Data;
import java.util.List;
/**
* @author: Chackylee
* @description:
**/
@Data
public class GetJoinedGroupResp {
private Integer totalCount;
private List<ImGroupEntity> groupList;
}

View File

@@ -0,0 +1,20 @@
package com.lld.im.service.group.model.resp;
import lombok.Data;
/**
* @author: Chackylee
* @description:
**/
@Data
public class GetRoleInGroupResp {
private Long groupMemberId;
private String memberId;
private Integer role;
private Long speakDate;
}

View File

@@ -0,0 +1,43 @@
package com.lld.im.service.group.service;
import com.lld.im.common.ResponseVO;
import com.lld.im.service.group.model.req.*;
import com.lld.im.service.group.model.resp.GetRoleInGroupResp;
import java.util.Collection;
import java.util.List;
/**
* @description:
* @author: lld
* @version: 1.0
*/
public interface ImGroupMemberService {
public ResponseVO importGroupMember(ImportGroupMemberReq req);
public ResponseVO addMember(AddGroupMemberReq req);
public ResponseVO removeMember(RemoveGroupMemberReq req);
public ResponseVO addGroupMember(String groupId, Integer appId, GroupMemberDto dto);
public ResponseVO removeGroupMember(String groupId, Integer appId, String memberId);
public ResponseVO<GetRoleInGroupResp> getRoleInGroupOne(String groupId, String memberId, Integer appId);
public ResponseVO<Collection<String>> getMemberJoinedGroup(GetJoinedGroupReq req);
public ResponseVO<List<GroupMemberDto>> getGroupMember(String groupId, Integer appId);
public List<String> getGroupMemberId(String groupId, Integer appId);
public List<GroupMemberDto> getGroupManager(String groupId, Integer appId);
public ResponseVO updateGroupMember(UpdateGroupMemberReq req);
public ResponseVO transferGroupMember(String owner, String groupId, Integer appId);
public ResponseVO speak(SpeaMemberReq req);
}

View File

@@ -0,0 +1,32 @@
package com.lld.im.service.group.service;
import com.lld.im.common.ResponseVO;
import com.lld.im.service.group.dao.ImGroupEntity;
import com.lld.im.service.group.model.req.*;
/**
* @description:
* @author: lld
* @version: 1.0
*/
public interface ImGroupService {
public ResponseVO importGroup(ImportGroupReq req);
public ResponseVO createGroup(CreateGroupReq req);
public ResponseVO updateBaseGroupInfo(UpdateGroupReq req);
public ResponseVO getJoinedGroup(GetJoinedGroupReq req);
public ResponseVO destroyGroup(DestroyGroupReq req);
public ResponseVO transferGroup(TransferGroupReq req);
public ResponseVO<ImGroupEntity> getGroup(String groupId, Integer appId);
public ResponseVO getGroup(GetGroupReq req);
public ResponseVO muteGroup(MuteGroupReq req);
}

View File

@@ -0,0 +1,537 @@
package com.lld.im.service.group.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.lld.im.common.ResponseVO;
import com.lld.im.common.enums.GroupErrorCode;
import com.lld.im.common.enums.GroupMemberRoleEnum;
import com.lld.im.common.enums.GroupStatusEnum;
import com.lld.im.common.enums.GroupTypeEnum;
import com.lld.im.common.exception.ApplicationException;
import com.lld.im.service.group.dao.ImGroupEntity;
import com.lld.im.service.group.dao.ImGroupMemberEntity;
import com.lld.im.service.group.dao.mapper.ImGroupMemberMapper;
import com.lld.im.service.group.model.req.*;
import com.lld.im.service.group.model.resp.AddMemberResp;
import com.lld.im.service.group.model.resp.GetRoleInGroupResp;
import com.lld.im.service.group.service.ImGroupMemberService;
import com.lld.im.service.group.service.ImGroupService;
import com.lld.im.service.user.dao.ImUserDataEntity;
import com.lld.im.service.user.service.ImUserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.*;
/**
* @description:
* @author: lld
* @version: 1.0
*/
@Service
@Slf4j
public class ImGroupMemberServiceImpl implements ImGroupMemberService {
@Autowired
ImGroupMemberMapper imGroupMemberMapper;
@Autowired
ImGroupService groupService;
@Autowired
ImGroupMemberService groupMemberService;
@Autowired
ImUserService imUserService;
@Override
public ResponseVO importGroupMember(ImportGroupMemberReq req) {
List<AddMemberResp> resp = new ArrayList<>();
ResponseVO<ImGroupEntity> groupResp = groupService.getGroup(req.getGroupId(), req.getAppId());
if (!groupResp.isOk()) {
return groupResp;
}
for (GroupMemberDto memberId :
req.getMembers()) {
ResponseVO responseVO = null;
try {
responseVO = groupMemberService.addGroupMember(req.getGroupId(), req.getAppId(), memberId);
} catch (Exception e) {
e.printStackTrace();
responseVO = ResponseVO.errorResponse();
}
AddMemberResp addMemberResp = new AddMemberResp();
addMemberResp.setMemberId(memberId.getMemberId());
if (responseVO.isOk()) {
addMemberResp.setResult(0);
} else if (responseVO.getCode() == GroupErrorCode.USER_IS_JOINED_GROUP.getCode()) {
addMemberResp.setResult(2);
} else {
addMemberResp.setResult(1);
}
resp.add(addMemberResp);
}
return ResponseVO.successResponse(resp);
}
/**
* @param
* @return com.lld.im.common.ResponseVO
* @description: 添加群成员,内部调用
* @author lld
*/
@Override
@Transactional
public ResponseVO addGroupMember(String groupId, Integer appId, GroupMemberDto dto) {
ResponseVO<ImUserDataEntity> singleUserInfo = imUserService.getSingleUserInfo(dto.getMemberId(), appId);
if (!singleUserInfo.isOk()) {
return singleUserInfo;
}
if (dto.getRole() != null && GroupMemberRoleEnum.OWNER.getCode() == dto.getRole()) {
QueryWrapper<ImGroupMemberEntity> queryOwner = new QueryWrapper<>();
queryOwner.eq("group_id", groupId);
queryOwner.eq("app_id", appId);
queryOwner.eq("role", GroupMemberRoleEnum.OWNER.getCode());
Integer ownerNum = imGroupMemberMapper.selectCount(queryOwner);
if (ownerNum > 0) {
return ResponseVO.errorResponse(GroupErrorCode.GROUP_IS_HAVE_OWNER);
}
}
QueryWrapper<ImGroupMemberEntity> query = new QueryWrapper<>();
query.eq("group_id", groupId);
query.eq("app_id", appId);
query.eq("member_id", dto.getMemberId());
ImGroupMemberEntity memberDto = imGroupMemberMapper.selectOne(query);
long now = System.currentTimeMillis();
if (memberDto == null) {
//初次加群
memberDto = new ImGroupMemberEntity();
BeanUtils.copyProperties(dto, memberDto);
memberDto.setGroupId(groupId);
memberDto.setAppId(appId);
memberDto.setJoinTime(now);
int insert = imGroupMemberMapper.insert(memberDto);
if (insert == 1) {
return ResponseVO.successResponse();
}
return ResponseVO.errorResponse(GroupErrorCode.USER_JOIN_GROUP_ERROR);
} else if (GroupMemberRoleEnum.LEAVE.getCode() == memberDto.getRole()) {
//重新进群
memberDto = new ImGroupMemberEntity();
BeanUtils.copyProperties(dto, memberDto);
memberDto.setJoinTime(now);
int update = imGroupMemberMapper.update(memberDto, query);
if (update == 1) {
return ResponseVO.successResponse();
}
return ResponseVO.errorResponse(GroupErrorCode.USER_JOIN_GROUP_ERROR);
}
return ResponseVO.errorResponse(GroupErrorCode.USER_IS_JOINED_GROUP);
}
/**
* @param
* @return com.lld.im.common.ResponseVO
* @description: 删除群成员,内部调用
* @author lld
*/
@Override
public ResponseVO removeGroupMember(String groupId, Integer appId, String memberId) {
ResponseVO<ImUserDataEntity> singleUserInfo = imUserService.getSingleUserInfo(memberId, appId);
if (!singleUserInfo.isOk()) {
return singleUserInfo;
}
ResponseVO<GetRoleInGroupResp> roleInGroupOne = getRoleInGroupOne(groupId, memberId, appId);
if (!roleInGroupOne.isOk()) {
return roleInGroupOne;
}
GetRoleInGroupResp data = roleInGroupOne.getData();
ImGroupMemberEntity imGroupMemberEntity = new ImGroupMemberEntity();
imGroupMemberEntity.setRole(GroupMemberRoleEnum.LEAVE.getCode());
imGroupMemberEntity.setLeaveTime(System.currentTimeMillis());
imGroupMemberEntity.setGroupMemberId(data.getGroupMemberId());
imGroupMemberMapper.updateById(imGroupMemberEntity);
return ResponseVO.successResponse();
}
/**
* @param [groupId, memberId, appId]
* @return com.lld.im.common.ResponseVO<com.lld.im.service.group.model.resp.GetRoleInGroupResp>
* @description 查询用户在群内的角色
* @author chackylee
*/
@Override
public ResponseVO<GetRoleInGroupResp> getRoleInGroupOne(String groupId, String memberId, Integer appId) {
GetRoleInGroupResp resp = new GetRoleInGroupResp();
QueryWrapper<ImGroupMemberEntity> queryOwner = new QueryWrapper<>();
queryOwner.eq("group_id", groupId);
queryOwner.eq("app_id", appId);
queryOwner.eq("member_id", memberId);
ImGroupMemberEntity imGroupMemberEntity = imGroupMemberMapper.selectOne(queryOwner);
if (imGroupMemberEntity == null || imGroupMemberEntity.getRole() == GroupMemberRoleEnum.LEAVE.getCode()) {
return ResponseVO.errorResponse(GroupErrorCode.MEMBER_IS_NOT_JOINED_GROUP);
}
resp.setSpeakDate(imGroupMemberEntity.getSpeakDate());
resp.setGroupMemberId(imGroupMemberEntity.getGroupMemberId());
resp.setMemberId(imGroupMemberEntity.getMemberId());
resp.setRole(imGroupMemberEntity.getRole());
return ResponseVO.successResponse(resp);
}
@Override
public ResponseVO<Collection<String>> getMemberJoinedGroup(GetJoinedGroupReq req) {
if (req.getLimit() != null) {
Page<ImGroupMemberEntity> objectPage = new Page<>(req.getOffset(), req.getLimit());
QueryWrapper<ImGroupMemberEntity> query = new QueryWrapper<>();
query.eq("app_id", req.getAppId());
query.eq("member_id", req.getMemberId());
IPage<ImGroupMemberEntity> imGroupMemberEntityPage = imGroupMemberMapper.selectPage(objectPage, query);
Set<String> groupId = new HashSet<>();
List<ImGroupMemberEntity> records = imGroupMemberEntityPage.getRecords();
records.forEach(e -> {
groupId.add(e.getGroupId());
});
return ResponseVO.successResponse(groupId);
} else {
return ResponseVO.successResponse(imGroupMemberMapper.getJoinedGroupId(req.getAppId(), req.getMemberId()));
}
}
/**
* @param
* @return com.lld.im.common.ResponseVO
* @description: 添加群成员,拉人入群的逻辑,直接进入群聊。如果是后台管理员,则直接拉入群,
* 否则只有私有群可以调用本接口,并且群成员也可以拉人入群.只有私有群可以调用本接口
* @author lld
*/
@Override
public ResponseVO addMember(AddGroupMemberReq req) {
List<AddMemberResp> resp = new ArrayList<>();
boolean isAdmin = false;
ResponseVO<ImGroupEntity> groupResp = groupService.getGroup(req.getGroupId(), req.getAppId());
if (!groupResp.isOk()) {
return groupResp;
}
List<GroupMemberDto> memberDtos = req.getMembers();
ImGroupEntity group = groupResp.getData();
/**
* 私有群private 类似普通微信群,创建后仅支持已在群内的好友邀请加群,且无需被邀请方同意或群主审批
* 公开群Public 类似 QQ 群,创建后群主可以指定群管理员,需要群主或管理员审批通过才能入群
* 群类型 1私有群类似微信 2公开群(类似qq
*/
if (!isAdmin && GroupTypeEnum.PUBLIC.getCode() == group.getGroupType()) {
throw new ApplicationException(GroupErrorCode.THIS_OPERATE_NEED_APPMANAGER_ROLE);
}
List<String> successId = new ArrayList<>();
for (GroupMemberDto memberId :
memberDtos) {
ResponseVO responseVO = null;
try {
responseVO = groupMemberService.addGroupMember(req.getGroupId(), req.getAppId(), memberId);
} catch (Exception e) {
e.printStackTrace();
responseVO = ResponseVO.errorResponse();
}
AddMemberResp addMemberResp = new AddMemberResp();
addMemberResp.setMemberId(memberId.getMemberId());
if (responseVO.isOk()) {
successId.add(memberId.getMemberId());
addMemberResp.setResult(0);
} else if (responseVO.getCode() == GroupErrorCode.USER_IS_JOINED_GROUP.getCode()) {
addMemberResp.setResult(2);
addMemberResp.setResultMessage(responseVO.getMsg());
} else {
addMemberResp.setResult(1);
addMemberResp.setResultMessage(responseVO.getMsg());
}
resp.add(addMemberResp);
}
return ResponseVO.successResponse(resp);
}
@Override
public ResponseVO removeMember(RemoveGroupMemberReq req) {
boolean isAdmin = false;
ResponseVO<ImGroupEntity> groupResp = groupService.getGroup(req.getGroupId(), req.getAppId());
if (!groupResp.isOk()) {
return groupResp;
}
ImGroupEntity group = groupResp.getData();
if (!isAdmin) {
if (GroupTypeEnum.PUBLIC.getCode() == group.getGroupType()) {
//获取操作人的权限 是管理员or群主or群成员
ResponseVO<GetRoleInGroupResp> role = getRoleInGroupOne(req.getGroupId(), req.getOperater(), req.getAppId());
if (!role.isOk()) {
return role;
}
GetRoleInGroupResp data = role.getData();
Integer roleInfo = data.getRole();
boolean isOwner = roleInfo == GroupMemberRoleEnum.OWNER.getCode();
boolean isManager = roleInfo == GroupMemberRoleEnum.MAMAGER.getCode();
if (!isOwner && !isManager) {
throw new ApplicationException(GroupErrorCode.THIS_OPERATE_NEED_MANAGER_ROLE);
}
//私有群必须是群主才能踢人
if (!isOwner && GroupTypeEnum.PRIVATE.getCode() == group.getGroupType()) {
throw new ApplicationException(GroupErrorCode.THIS_OPERATE_NEED_OWNER_ROLE);
}
//公开群管理员和群主可踢人,但管理员只能踢普通群成员
if (GroupTypeEnum.PUBLIC.getCode() == group.getGroupType()) {
// throw new ApplicationException(GroupErrorCode.THIS_OPERATE_NEED_MANAGER_ROLE);
//获取被踢人的权限
ResponseVO<GetRoleInGroupResp> roleInGroupOne = this.getRoleInGroupOne(req.getGroupId(), req.getMemberId(), req.getAppId());
if (!roleInGroupOne.isOk()) {
return roleInGroupOne;
}
GetRoleInGroupResp memberRole = roleInGroupOne.getData();
if (memberRole.getRole() == GroupMemberRoleEnum.OWNER.getCode()) {
throw new ApplicationException(GroupErrorCode.GROUP_OWNER_IS_NOT_REMOVE);
}
//是管理员并且被踢人不是群成员,无法操作
if (isManager && memberRole.getRole() != GroupMemberRoleEnum.ORDINARY.getCode()) {
throw new ApplicationException(GroupErrorCode.THIS_OPERATE_NEED_OWNER_ROLE);
}
}
}
}
ResponseVO responseVO = groupMemberService.removeGroupMember(req.getGroupId(), req.getAppId(), req.getMemberId());
return responseVO;
}
@Override
public ResponseVO<List<GroupMemberDto>> getGroupMember(String groupId, Integer appId) {
List<GroupMemberDto> groupMember = imGroupMemberMapper.getGroupMember(appId, groupId);
return ResponseVO.successResponse(groupMember);
}
@Override
public List<String> getGroupMemberId(String groupId, Integer appId) {
return imGroupMemberMapper.getGroupMemberId(appId, groupId);
}
@Override
public List<GroupMemberDto> getGroupManager(String groupId, Integer appId) {
return imGroupMemberMapper.getGroupManager(groupId, appId);
}
@Override
public ResponseVO updateGroupMember(UpdateGroupMemberReq req) {
boolean isadmin = false;
ResponseVO<ImGroupEntity> group = groupService.getGroup(req.getGroupId(), req.getAppId());
if (!group.isOk()) {
return group;
}
ImGroupEntity groupData = group.getData();
if (groupData.getStatus() == GroupStatusEnum.DESTROY.getCode()) {
throw new ApplicationException(GroupErrorCode.GROUP_IS_DESTROY);
}
//是否是自己修改自己的资料
boolean isMeOperate = req.getOperater().equals(req.getMemberId());
if (!isadmin) {
//昵称只能自己修改 权限只能群主或管理员修改
if (StringUtils.isBlank(req.getAlias()) && !isMeOperate) {
return ResponseVO.errorResponse(GroupErrorCode.THIS_OPERATE_NEED_ONESELF);
}
//如果要修改权限相关的则走下面的逻辑
if (req.getRole() != null) {
//私有群不能设置管理员
if (groupData.getGroupType() == GroupTypeEnum.PRIVATE.getCode() &&
req.getRole() != null && (req.getRole() == GroupMemberRoleEnum.MAMAGER.getCode() ||
req.getRole() == GroupMemberRoleEnum.OWNER.getCode())) {
return ResponseVO.errorResponse(GroupErrorCode.THIS_OPERATE_NEED_APPMANAGER_ROLE);
}
//获取被操作人的是否在群内
ResponseVO<GetRoleInGroupResp> roleInGroupOne = this.getRoleInGroupOne(req.getGroupId(), req.getMemberId(), req.getAppId());
if (!roleInGroupOne.isOk()) {
return roleInGroupOne;
}
//获取操作人权限
ResponseVO<GetRoleInGroupResp> operateRoleInGroupOne = this.getRoleInGroupOne(req.getGroupId(), req.getOperater(), req.getAppId());
if (!operateRoleInGroupOne.isOk()) {
return operateRoleInGroupOne;
}
GetRoleInGroupResp data = operateRoleInGroupOne.getData();
Integer roleInfo = data.getRole();
boolean isOwner = roleInfo == GroupMemberRoleEnum.OWNER.getCode();
boolean isManager = roleInfo == GroupMemberRoleEnum.MAMAGER.getCode();
//不是管理员不能修改权限
if (req.getRole() != null && !isOwner && !isManager) {
return ResponseVO.errorResponse(GroupErrorCode.THIS_OPERATE_NEED_MANAGER_ROLE);
}
//管理员只有群主能够设置
if (req.getRole() != null && req.getRole() == GroupMemberRoleEnum.MAMAGER.getCode() && !isOwner) {
return ResponseVO.errorResponse(GroupErrorCode.THIS_OPERATE_NEED_OWNER_ROLE);
}
}
}
ImGroupMemberEntity update = new ImGroupMemberEntity();
if (StringUtils.isNotBlank(req.getAlias())) {
update.setAlias(req.getAlias());
}
//不能直接修改为群主
if(req.getRole() != null && req.getRole() != GroupMemberRoleEnum.OWNER.getCode()){
update.setRole(req.getRole());
}
UpdateWrapper<ImGroupMemberEntity> objectUpdateWrapper = new UpdateWrapper<>();
objectUpdateWrapper.eq("app_id", req.getAppId());
objectUpdateWrapper.eq("member_id", req.getMemberId());
objectUpdateWrapper.eq("group_id", req.getGroupId());
imGroupMemberMapper.update(update, objectUpdateWrapper);
return ResponseVO.successResponse();
}
@Override
@Transactional
public ResponseVO transferGroupMember(String owner, String groupId, Integer appId) {
//更新旧群主
ImGroupMemberEntity imGroupMemberEntity = new ImGroupMemberEntity();
imGroupMemberEntity.setRole(GroupMemberRoleEnum.ORDINARY.getCode());
UpdateWrapper<ImGroupMemberEntity> updateWrapper = new UpdateWrapper<>();
updateWrapper.eq("app_id", appId);
updateWrapper.eq("group_id", groupId);
updateWrapper.eq("role", GroupMemberRoleEnum.OWNER.getCode());
imGroupMemberMapper.update(imGroupMemberEntity, updateWrapper);
//更新新群主
ImGroupMemberEntity newOwner = new ImGroupMemberEntity();
newOwner.setRole(GroupMemberRoleEnum.OWNER.getCode());
UpdateWrapper<ImGroupMemberEntity> ownerWrapper = new UpdateWrapper<>();
ownerWrapper.eq("app_id", appId);
ownerWrapper.eq("group_id", groupId);
ownerWrapper.eq("member_id", owner);
imGroupMemberMapper.update(newOwner, ownerWrapper);
return ResponseVO.successResponse();
}
@Override
public ResponseVO speak(SpeaMemberReq req) {
ResponseVO<ImGroupEntity> groupResp = groupService.getGroup(req.getGroupId(), req.getAppId());
if (!groupResp.isOk()) {
return groupResp;
}
boolean isadmin = false;
boolean isOwner = false;
boolean isManager = false;
GetRoleInGroupResp memberRole = null;
if (!isadmin) {
//获取操作人的权限 是管理员or群主or群成员
ResponseVO<GetRoleInGroupResp> role = getRoleInGroupOne(req.getGroupId(), req.getOperater(), req.getAppId());
if (!role.isOk()) {
return role;
}
GetRoleInGroupResp data = role.getData();
Integer roleInfo = data.getRole();
isOwner = roleInfo == GroupMemberRoleEnum.OWNER.getCode();
isManager = roleInfo == GroupMemberRoleEnum.MAMAGER.getCode();
if (!isOwner && !isManager) {
throw new ApplicationException(GroupErrorCode.THIS_OPERATE_NEED_MANAGER_ROLE);
}
//获取被操作的权限
ResponseVO<GetRoleInGroupResp> roleInGroupOne = this.getRoleInGroupOne(req.getGroupId(), req.getMemberId(), req.getAppId());
if (!roleInGroupOne.isOk()) {
return roleInGroupOne;
}
memberRole = roleInGroupOne.getData();
//被操作人是群主只能app管理员操作
if (memberRole.getRole() == GroupMemberRoleEnum.OWNER.getCode()) {
throw new ApplicationException(GroupErrorCode.THIS_OPERATE_NEED_APPMANAGER_ROLE);
}
//是管理员并且被操作人不是群成员,无法操作
if (isManager && memberRole.getRole() != GroupMemberRoleEnum.ORDINARY.getCode()) {
throw new ApplicationException(GroupErrorCode.THIS_OPERATE_NEED_OWNER_ROLE);
}
}
ImGroupMemberEntity imGroupMemberEntity = new ImGroupMemberEntity();
if (memberRole == null) {
//获取被操作的权限
ResponseVO<GetRoleInGroupResp> roleInGroupOne = this.getRoleInGroupOne(req.getGroupId(), req.getMemberId(), req.getAppId());
if (!roleInGroupOne.isOk()) {
return roleInGroupOne;
}
memberRole = roleInGroupOne.getData();
}
imGroupMemberEntity.setGroupMemberId(memberRole.getGroupMemberId());
if (req.getSpeakDate() > 0) {
imGroupMemberEntity.setSpeakDate(System.currentTimeMillis() + req.getSpeakDate());
} else {
imGroupMemberEntity.setSpeakDate(req.getSpeakDate());
}
int i = imGroupMemberMapper.updateById(imGroupMemberEntity);
return ResponseVO.successResponse();
}
}

View File

@@ -0,0 +1,393 @@
package com.lld.im.service.group.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.lld.im.common.ResponseVO;
import com.lld.im.common.enums.GroupErrorCode;
import com.lld.im.common.enums.GroupMemberRoleEnum;
import com.lld.im.common.enums.GroupStatusEnum;
import com.lld.im.common.enums.GroupTypeEnum;
import com.lld.im.common.exception.ApplicationException;
import com.lld.im.common.model.ClientInfo;
import com.lld.im.service.group.dao.ImGroupEntity;
import com.lld.im.service.group.dao.mapper.ImGroupMapper;
import com.lld.im.service.group.model.req.*;
import com.lld.im.service.group.model.resp.GetGroupResp;
import com.lld.im.service.group.model.resp.GetJoinedGroupResp;
import com.lld.im.service.group.model.resp.GetRoleInGroupResp;
import com.lld.im.service.group.service.ImGroupMemberService;
import com.lld.im.service.group.service.ImGroupService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.UUID;
/**
* @description:
* @author: lld
* @version: 1.0
*/
@Service
public class ImGroupServiceImpl implements ImGroupService {
@Autowired
ImGroupMapper imGroupDataMapper;
@Autowired
ImGroupMemberService groupMemberService;
@Override
public ResponseVO importGroup(ImportGroupReq req) {
//1.判断群id是否存在
QueryWrapper<ImGroupEntity> query = new QueryWrapper<>();
if (StringUtils.isEmpty(req.getGroupId())) {
req.setGroupId(UUID.randomUUID().toString().replace("-", ""));
} else {
query.eq("group_id", req.getGroupId());
query.eq("app_id", req.getAppId());
Integer integer = imGroupDataMapper.selectCount(query);
if (integer > 0) {
throw new ApplicationException(GroupErrorCode.GROUP_IS_EXIST);
}
}
ImGroupEntity imGroupEntity = new ImGroupEntity();
if (req.getGroupType() == GroupTypeEnum.PUBLIC.getCode() && StringUtils.isBlank(req.getOwnerId())) {
throw new ApplicationException(GroupErrorCode.PUBLIC_GROUP_MUST_HAVE_OWNER);
}
if (req.getCreateTime() == null) {
imGroupEntity.setCreateTime(System.currentTimeMillis());
}
imGroupEntity.setStatus(GroupStatusEnum.NORMAL.getCode());
BeanUtils.copyProperties(req, imGroupEntity);
int insert = imGroupDataMapper.insert(imGroupEntity);
if (insert != 1) {
throw new ApplicationException(GroupErrorCode.IMPORT_GROUP_ERROR);
}
return ResponseVO.successResponse();
}
@Override
@Transactional
public ResponseVO createGroup(CreateGroupReq req) {
boolean isAdmin = false;
if (!isAdmin) {
req.setOwnerId(req.getOperater());
}
//1.判断群id是否存在
QueryWrapper<ImGroupEntity> query = new QueryWrapper<>();
if (StringUtils.isEmpty(req.getGroupId())) {
req.setGroupId(UUID.randomUUID().toString().replace("-", ""));
} else {
query.eq("group_id", req.getGroupId());
query.eq("app_id", req.getAppId());
Integer integer = imGroupDataMapper.selectCount(query);
if (integer > 0) {
throw new ApplicationException(GroupErrorCode.GROUP_IS_EXIST);
}
}
if (req.getGroupType() == GroupTypeEnum.PUBLIC.getCode() && StringUtils.isBlank(req.getOwnerId())) {
throw new ApplicationException(GroupErrorCode.PUBLIC_GROUP_MUST_HAVE_OWNER);
}
ImGroupEntity imGroupEntity = new ImGroupEntity();
imGroupEntity.setCreateTime(System.currentTimeMillis());
imGroupEntity.setStatus(GroupStatusEnum.NORMAL.getCode());
BeanUtils.copyProperties(req, imGroupEntity);
int insert = imGroupDataMapper.insert(imGroupEntity);
GroupMemberDto groupMemberDto = new GroupMemberDto();
groupMemberDto.setMemberId(req.getOwnerId());
groupMemberDto.setRole(GroupMemberRoleEnum.OWNER.getCode());
groupMemberDto.setJoinTime(System.currentTimeMillis());
groupMemberService.addGroupMember(req.getGroupId(), req.getAppId(), groupMemberDto);
//插入群成员
for (GroupMemberDto dto : req.getMember()) {
groupMemberService.addGroupMember(req.getGroupId(), req.getAppId(), dto);
}
return ResponseVO.successResponse();
}
/**
* @param [req]
* @return com.lld.im.common.ResponseVO
* @description 修改群基础信息,如果是后台管理员调用,则不检查权限,如果不是则检查权限,如果是私有群(微信群)任何人都可以修改资料,公开群只有管理员可以修改
* 如果是群主或者管理员可以修改其他信息。
* @author chackylee
*/
@Override
@Transactional
public ResponseVO updateBaseGroupInfo(UpdateGroupReq req) {
//1.判断群id是否存在
QueryWrapper<ImGroupEntity> query = new QueryWrapper<>();
query.eq("group_id", req.getGroupId());
query.eq("app_id", req.getAppId());
ImGroupEntity imGroupEntity = imGroupDataMapper.selectOne(query);
if (imGroupEntity == null) {
throw new ApplicationException(GroupErrorCode.GROUP_IS_EXIST);
}
if(imGroupEntity.getStatus() == GroupStatusEnum.DESTROY.getCode()){
throw new ApplicationException(GroupErrorCode.GROUP_IS_DESTROY);
}
boolean isAdmin = false;
if (!isAdmin) {
//不是后台调用需要检查权限
ResponseVO<GetRoleInGroupResp> role = groupMemberService.getRoleInGroupOne(req.getGroupId(), req.getOperater(), req.getAppId());
if (!role.isOk()) {
return role;
}
GetRoleInGroupResp data = role.getData();
Integer roleInfo = data.getRole();
boolean isManager = roleInfo == GroupMemberRoleEnum.MAMAGER.getCode() || roleInfo == GroupMemberRoleEnum.OWNER.getCode();
//公开群只能群主修改资料
if (!isManager && GroupTypeEnum.PUBLIC.getCode() == imGroupEntity.getGroupType()) {
throw new ApplicationException(GroupErrorCode.THIS_OPERATE_NEED_MANAGER_ROLE);
}
}
ImGroupEntity update = new ImGroupEntity();
BeanUtils.copyProperties(req, update);
update.setUpdateTime(System.currentTimeMillis());
int row = imGroupDataMapper.update(update, query);
if (row != 1) {
throw new ApplicationException(GroupErrorCode.THIS_OPERATE_NEED_MANAGER_ROLE);
}
return ResponseVO.successResponse();
}
/**
* @param [req]
* @return com.lld.im.common.ResponseVO
* @description 获取用户加入的群组
* @author chackylee
*/
@Override
public ResponseVO getJoinedGroup(GetJoinedGroupReq req) {
ResponseVO<Collection<String>> memberJoinedGroup = groupMemberService.getMemberJoinedGroup(req);
if (memberJoinedGroup.isOk()) {
GetJoinedGroupResp resp = new GetJoinedGroupResp();
if (CollectionUtils.isEmpty(memberJoinedGroup.getData())) {
resp.setTotalCount(0);
resp.setGroupList(new ArrayList<>());
return ResponseVO.successResponse(resp);
}
QueryWrapper<ImGroupEntity> query = new QueryWrapper<>();
query.eq("app_id", req.getAppId());
query.in("group_id", memberJoinedGroup.getData());
if (CollectionUtils.isNotEmpty(req.getGroupType())) {
query.in("group_type", req.getGroupType());
}
List<ImGroupEntity> groupList = imGroupDataMapper.selectList(query);
resp.setGroupList(groupList);
if (req.getLimit() == null) {
resp.setTotalCount(groupList.size());
} else {
resp.setTotalCount(imGroupDataMapper.selectCount(query));
}
return ResponseVO.successResponse(resp);
} else {
return memberJoinedGroup;
}
}
/**
* @param [req]
* @return com.lld.im.common.ResponseVO
* @description 解散群组,只支持后台管理员和群主解散
* @author chackylee
*/
@Override
@Transactional
public ResponseVO destroyGroup(DestroyGroupReq req) {
boolean isAdmin = false;
QueryWrapper<ImGroupEntity> objectQueryWrapper = new QueryWrapper<>();
objectQueryWrapper.eq("group_id", req.getGroupId());
objectQueryWrapper.eq("app_id", req.getAppId());
ImGroupEntity imGroupEntity = imGroupDataMapper.selectOne(objectQueryWrapper);
if (imGroupEntity == null) {
throw new ApplicationException(GroupErrorCode.PRIVATE_GROUP_CAN_NOT_DESTORY);
}
if(imGroupEntity.getStatus() == GroupStatusEnum.DESTROY.getCode()){
throw new ApplicationException(GroupErrorCode.GROUP_IS_DESTROY);
}
if (!isAdmin) {
if (imGroupEntity.getGroupType() == GroupTypeEnum.PUBLIC.getCode()) {
throw new ApplicationException(GroupErrorCode.THIS_OPERATE_NEED_OWNER_ROLE);
}
if (imGroupEntity.getGroupType() == GroupTypeEnum.PUBLIC.getCode() &&
!imGroupEntity.getOwnerId().equals(req.getOperater())) {
throw new ApplicationException(GroupErrorCode.THIS_OPERATE_NEED_OWNER_ROLE);
}
}
ImGroupEntity update = new ImGroupEntity();
update.setStatus(GroupStatusEnum.DESTROY.getCode());
int update1 = imGroupDataMapper.update(update, objectQueryWrapper);
if (update1 != 1) {
throw new ApplicationException(GroupErrorCode.UPDATE_GROUP_BASE_INFO_ERROR);
}
return ResponseVO.successResponse();
}
@Override
@Transactional
public ResponseVO transferGroup(TransferGroupReq req) {
ResponseVO<GetRoleInGroupResp> roleInGroupOne = groupMemberService.getRoleInGroupOne(req.getGroupId(), req.getOperater(), req.getAppId());
if (!roleInGroupOne.isOk()) {
return roleInGroupOne;
}
if (roleInGroupOne.getData().getRole() != GroupMemberRoleEnum.OWNER.getCode()) {
return ResponseVO.errorResponse(GroupErrorCode.THIS_OPERATE_NEED_OWNER_ROLE);
}
ResponseVO<GetRoleInGroupResp> newOwnerRole = groupMemberService.getRoleInGroupOne(req.getGroupId(), req.getOwnerId(), req.getAppId());
if (!newOwnerRole.isOk()) {
return newOwnerRole;
}
QueryWrapper<ImGroupEntity> objectQueryWrapper = new QueryWrapper<>();
objectQueryWrapper.eq("group_id", req.getGroupId());
objectQueryWrapper.eq("app_id", req.getAppId());
ImGroupEntity imGroupEntity = imGroupDataMapper.selectOne(objectQueryWrapper);
if(imGroupEntity.getStatus() == GroupStatusEnum.DESTROY.getCode()){
throw new ApplicationException(GroupErrorCode.GROUP_IS_DESTROY);
}
ImGroupEntity updateGroup = new ImGroupEntity();
updateGroup.setOwnerId(req.getOwnerId());
UpdateWrapper<ImGroupEntity> updateGroupWrapper = new UpdateWrapper<>();
updateGroupWrapper.eq("app_id", req.getAppId());
updateGroupWrapper.eq("group_id", req.getGroupId());
imGroupDataMapper.update(updateGroup, updateGroupWrapper);
groupMemberService.transferGroupMember(req.getOwnerId(), req.getGroupId(), req.getAppId());
return ResponseVO.successResponse();
}
@Override
public ResponseVO getGroup(String groupId, Integer appId) {
QueryWrapper<ImGroupEntity> query = new QueryWrapper<>();
query.eq("app_id", appId);
query.eq("group_id", groupId);
ImGroupEntity imGroupEntity = imGroupDataMapper.selectOne(query);
if (imGroupEntity == null) {
return ResponseVO.errorResponse(GroupErrorCode.GROUP_IS_NOT_EXIST);
}
return ResponseVO.successResponse(imGroupEntity);
}
@Override
public ResponseVO getGroup(GetGroupReq req) {
ResponseVO group = this.getGroup(req.getGroupId(), req.getAppId());
if(!group.isOk()){
return group;
}
GetGroupResp getGroupResp = new GetGroupResp();
BeanUtils.copyProperties(group.getData(), getGroupResp);
try {
ResponseVO<List<GroupMemberDto>> groupMember = groupMemberService.getGroupMember(req.getGroupId(), req.getAppId());
if (groupMember.isOk()) {
getGroupResp.setMemberList(groupMember.getData());
}
} catch (Exception e) {
e.printStackTrace();
}
return ResponseVO.successResponse(getGroupResp);
}
@Override
public ResponseVO muteGroup(MuteGroupReq req) {
ResponseVO<ImGroupEntity> groupResp = getGroup(req.getGroupId(), req.getAppId());
if (!groupResp.isOk()) {
return groupResp;
}
if(groupResp.getData().getStatus() == GroupStatusEnum.DESTROY.getCode()){
throw new ApplicationException(GroupErrorCode.GROUP_IS_DESTROY);
}
boolean isadmin = false;
if (!isadmin) {
//不是后台调用需要检查权限
ResponseVO<GetRoleInGroupResp> role = groupMemberService.getRoleInGroupOne(req.getGroupId(), req.getOperater(), req.getAppId());
if (!role.isOk()) {
return role;
}
GetRoleInGroupResp data = role.getData();
Integer roleInfo = data.getRole();
boolean isManager = roleInfo == GroupMemberRoleEnum.MAMAGER.getCode() || roleInfo == GroupMemberRoleEnum.OWNER.getCode();
//公开群只能群主修改资料
if (!isManager) {
throw new ApplicationException(GroupErrorCode.THIS_OPERATE_NEED_MANAGER_ROLE);
}
}
ImGroupEntity update = new ImGroupEntity();
update.setMute(req.getMute());
UpdateWrapper<ImGroupEntity> wrapper = new UpdateWrapper<>();
wrapper.eq("group_id",req.getGroupId());
wrapper.eq("app_id",req.getAppId());
imGroupDataMapper.update(update,wrapper);
return ResponseVO.successResponse();
}
}

View File

@@ -0,0 +1,35 @@
package com.lld.im.service.user.controller;
import com.lld.im.common.ResponseVO;
import com.lld.im.service.user.model.req.*;
import com.lld.im.service.user.service.ImUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @description:
* @author: lld
* @version: 1.0
*/
@RestController
@RequestMapping("v1/user")
public class ImUserController {
@Autowired
ImUserService imUserService;
@RequestMapping("importUser")
public ResponseVO importUser(@RequestBody ImportUserReq req, Integer appId) {
return imUserService.importUser(req);
}
@RequestMapping("/deleteUser")
public ResponseVO deleteUser(@RequestBody @Validated DeleteUserReq req, Integer appId) {
req.setAppId(appId);
return imUserService.deleteUser(req);
}
}

View File

@@ -0,0 +1,47 @@
package com.lld.im.service.user.controller;
import com.lld.im.common.ResponseVO;
import com.lld.im.service.user.model.req.GetUserInfoReq;
import com.lld.im.service.user.model.req.ModifyUserInfoReq;
import com.lld.im.service.user.model.req.UserId;
import com.lld.im.service.user.service.ImUserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @description:
* @author: lld
* @version: 1.0
*/
@RestController
@RequestMapping("v1/user/data")
public class ImUserDataController {
private static Logger logger = LoggerFactory.getLogger(ImUserDataController.class);
@Autowired
ImUserService imUserService;
@RequestMapping("/getUserInfo")
public ResponseVO getUserInfo(@RequestBody GetUserInfoReq req, Integer appId){//@Validated
req.setAppId(appId);
return imUserService.getUserInfo(req);
}
@RequestMapping("/getSingleUserInfo")
public ResponseVO getSingleUserInfo(@RequestBody @Validated UserId req, Integer appId){
req.setAppId(appId);
return imUserService.getSingleUserInfo(req.getUserId(),req.getAppId());
}
@RequestMapping("/modifyUserInfo")
public ResponseVO modifyUserInfo(@RequestBody @Validated ModifyUserInfoReq req, Integer appId){
req.setAppId(appId);
return imUserService.modifyUserInfo(req);
}
}

View File

@@ -0,0 +1,60 @@
package com.lld.im.service.user.dao;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
/**
* @author: Chackylee
* @description: 数据库用户数据实体类
**/
@Data
@TableName("im_user_data")
public class ImUserDataEntity {
// 用户id
private String userId;
// 用户名称
private String nickName;
//位置
private String location;
//生日
private String birthDay;
private String password;
// 头像
private String photo;
// 性别
private Integer userSex;
// 个性签名
private String selfSignature;
// 加好友验证类型Friend_AllowType 1需要验证
private Integer friendAllowType;
// 管理员禁止用户添加加好友0 未禁用 1 已禁用
private Integer disableAddFriend;
// 禁用标识(0 未禁用 1 已禁用)
private Integer forbiddenFlag;
// 禁言标识
private Integer silentFlag;
/**
* 用户类型 1普通用户 2客服 3机器人
*/
private Integer userType;
private Integer appId;
private Integer delFlag;
private String extra;
}

View File

@@ -0,0 +1,9 @@
package com.lld.im.service.user.dao.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.lld.im.service.user.dao.ImUserDataEntity;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface ImUserDataMapper extends BaseMapper<ImUserDataEntity> {
}

View File

@@ -0,0 +1,22 @@
package com.lld.im.service.user.model;
import com.lld.im.common.model.ClientInfo;
import lombok.Data;
/**
* @description: status区分是上线还是下线
* @author: lld
* @version: 1.0
*/
@Data
public class UserStatusChangeNotifyContent extends ClientInfo {
private String userId;
//服务端状态 1上线 2离线
private Integer status;
}

View File

@@ -0,0 +1,15 @@
package com.lld.im.service.user.model.req;
import com.lld.im.common.model.RequestBase;
import lombok.Data;
import javax.validation.constraints.NotEmpty;
import java.util.List;
@Data
public class DeleteUserReq extends RequestBase {
@NotEmpty(message = "用户id不能为空")
private List<String> userId;
}

View File

@@ -0,0 +1,15 @@
package com.lld.im.service.user.model.req;
import com.lld.im.common.model.RequestBase;
import lombok.Data;
import java.util.List;
@Data
public class GetUserInfoReq extends RequestBase {
private List<String> userIds;
}

View File

@@ -0,0 +1,16 @@
package com.lld.im.service.user.model.req;
import com.lld.im.common.model.RequestBase;
import lombok.Data;
/**
* @description:
* @author: lld
* @version: 1.0
*/
@Data
public class GetUserSequenceReq extends RequestBase {
private String userId;
}

View File

@@ -0,0 +1,16 @@
package com.lld.im.service.user.model.req;
import com.lld.im.common.model.RequestBase;
import com.lld.im.service.user.dao.ImUserDataEntity;
import lombok.Data;
import java.util.List;
@Data
public class ImportUserReq extends RequestBase {
private List<ImUserDataEntity> userData;
}

View File

@@ -0,0 +1,46 @@
package com.lld.im.service.user.model.req;
import com.lld.im.common.model.RequestBase;
import lombok.Data;
import javax.validation.constraints.NotEmpty;
/**
* @description:
* @author: lld
* @version: 1.0
*/
@Data
public class ModifyUserInfoReq extends RequestBase {
// 用户id
@NotEmpty(message = "用户id不能为空")
private String userId;
// 用户名称
private String nickName;
//位置
private String location;
//生日
private String birthDay;
private String password;
// 头像
private String photo;
// 性别
private String userSex;
// 个性签名
private String selfSignature;
// 加好友验证类型Friend_AllowType 1需要验证
private Integer friendAllowType;
private String extra;
}

View File

@@ -0,0 +1,15 @@
package com.lld.im.service.user.model.req;
import com.lld.im.common.model.RequestBase;
import lombok.Data;
/**
* @author: Chackylee
* @description:
**/
@Data
public class UserId extends RequestBase {
private String userId;
}

View File

@@ -0,0 +1,20 @@
package com.lld.im.service.user.model.resp;
import com.lld.im.service.user.dao.ImUserDataEntity;
import lombok.Data;
import java.util.List;
/**
* @author: Chackylee
* @description:
**/
@Data
public class GetUserInfoResp {
private List<ImUserDataEntity> userDataItem;
private List<String> failUser;
}

View File

@@ -0,0 +1,18 @@
package com.lld.im.service.user.model.resp;
import lombok.Data;
import java.util.List;
/**
* @author: Chackylee
* @description:
**/
@Data
public class ImportUserResp {
private List<String> successId;
private List<String> errorId;
}

View File

@@ -0,0 +1,22 @@
package com.lld.im.service.user.model.resp;
import com.lld.im.common.model.UserSession;
import lombok.Data;
import java.util.List;
/**
* @description:
* @author: lld
* @version: 1.0
*/
@Data
public class UserOnlineStatusResp {
private List<UserSession> session;
private String customText;
private Integer customStatus;
}

View File

@@ -0,0 +1,26 @@
package com.lld.im.service.user.service;
import com.lld.im.common.ResponseVO;
import com.lld.im.service.user.dao.ImUserDataEntity;
import com.lld.im.service.user.model.req.*;
import com.lld.im.service.user.model.resp.GetUserInfoResp;
/**
* @description:
* @author: lld
* @version: 1.0
*/
public interface ImUserService {
public ResponseVO importUser(ImportUserReq req);
public ResponseVO<GetUserInfoResp> getUserInfo(GetUserInfoReq req);
public ResponseVO<ImUserDataEntity> getSingleUserInfo(String userId , Integer appId);
public ResponseVO deleteUser(DeleteUserReq req);
public ResponseVO modifyUserInfo(ModifyUserInfoReq req);
}

View File

@@ -0,0 +1,173 @@
package com.lld.im.service.user.service.impl;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.lld.im.common.ResponseVO;
import com.lld.im.common.enums.DelFlagEnum;
import com.lld.im.common.enums.UserErrorCode;
import com.lld.im.common.exception.ApplicationException;
import com.lld.im.service.group.service.ImGroupService;
import com.lld.im.service.user.dao.ImUserDataEntity;
import com.lld.im.service.user.dao.mapper.ImUserDataMapper;
import com.lld.im.service.user.model.req.*;
import com.lld.im.service.user.model.resp.GetUserInfoResp;
import com.lld.im.service.user.model.resp.ImportUserResp;
import com.lld.im.service.user.service.ImUserService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @description:
* @author: lld
* @version: 1.0
*/
@Service
public class ImUserviceImpl implements ImUserService {
@Autowired
ImUserDataMapper imUserDataMapper;
@Autowired
ImGroupService imGroupService;
@Override
public ResponseVO importUser(ImportUserReq req) {
if(req.getUserData().size() > 100){
return ResponseVO.errorResponse(UserErrorCode.IMPORT_SIZE_BEYOND);
}
ImportUserResp resp = new ImportUserResp();
List<String> successId = new ArrayList<>();
List<String> errorId = new ArrayList<>();
for (ImUserDataEntity data:
req.getUserData()) {
try {
data.setAppId(req.getAppId());
int insert = imUserDataMapper.insert(data);
if(insert == 1){
successId.add(data.getUserId());
}
}catch (Exception e){
e.printStackTrace();
errorId.add(data.getUserId());
}
}
resp.setErrorId(errorId);
resp.setSuccessId(successId);
return ResponseVO.successResponse(resp);
}
@Override
public ResponseVO<GetUserInfoResp> getUserInfo(GetUserInfoReq req) {
QueryWrapper<ImUserDataEntity> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("app_id",req.getAppId());
queryWrapper.in("user_id",req.getUserIds());
queryWrapper.eq("del_flag", DelFlagEnum.NORMAL.getCode());
List<ImUserDataEntity> userDataEntities = imUserDataMapper.selectList(queryWrapper);
HashMap<String, ImUserDataEntity> map = new HashMap<>();
for (ImUserDataEntity data:
userDataEntities) {
map.put(data.getUserId(),data);
}
List<String> failUser = new ArrayList<>();
for (String uid:
req.getUserIds()) {
if(!map.containsKey(uid)){
failUser.add(uid);
}
}
GetUserInfoResp resp = new GetUserInfoResp();
resp.setUserDataItem(userDataEntities);
resp.setFailUser(failUser);
return ResponseVO.successResponse(resp);
}
@Override
public ResponseVO<ImUserDataEntity> getSingleUserInfo(String userId, Integer appId) {
QueryWrapper objectQueryWrapper = new QueryWrapper<>();
objectQueryWrapper.eq("app_id",appId);
objectQueryWrapper.eq("user_id",userId);
objectQueryWrapper.eq("del_flag", DelFlagEnum.NORMAL.getCode());
ImUserDataEntity ImUserDataEntity = imUserDataMapper.selectOne(objectQueryWrapper);
if(ImUserDataEntity == null){
return ResponseVO.errorResponse(UserErrorCode.USER_IS_NOT_EXIST);
}
return ResponseVO.successResponse(ImUserDataEntity);
}
@Override
public ResponseVO deleteUser(DeleteUserReq req) {
ImUserDataEntity entity = new ImUserDataEntity();
entity.setDelFlag(DelFlagEnum.DELETE.getCode());
List<String> errorId = new ArrayList();
List<String> successId = new ArrayList();
for (String userId:
req.getUserId()) {
QueryWrapper wrapper = new QueryWrapper();
wrapper.eq("app_id",req.getAppId());
wrapper.eq("user_id",userId);
wrapper.eq("del_flag",DelFlagEnum.NORMAL.getCode());
int update = 0;
try {
update = imUserDataMapper.update(entity, wrapper);
if(update > 0){
successId.add(userId);
}else{
errorId.add(userId);
}
}catch (Exception e){
errorId.add(userId);
}
}
ImportUserResp resp = new ImportUserResp();
resp.setSuccessId(successId);
resp.setErrorId(errorId);
return ResponseVO.successResponse(resp);
}
@Override
@Transactional
public ResponseVO modifyUserInfo(ModifyUserInfoReq req) {
QueryWrapper query = new QueryWrapper<>();
query.eq("app_id",req.getAppId());
query.eq("user_id",req.getUserId());
query.eq("del_flag",DelFlagEnum.NORMAL.getCode());
ImUserDataEntity user = imUserDataMapper.selectOne(query);
if(user == null){
throw new ApplicationException(UserErrorCode.USER_IS_NOT_EXIST);
}
ImUserDataEntity update = new ImUserDataEntity();
BeanUtils.copyProperties(req,update);
update.setAppId(null);
update.setUserId(null);
int update1 = imUserDataMapper.update(update, query);
if(update1 == 1){
return ResponseVO.successResponse();
}
throw new ApplicationException(UserErrorCode.MODIFY_USER_ERROR);
}
}

View File

@@ -0,0 +1,38 @@
spring:
profiles:
active: dev
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
password: beAs0LHX2GyTxMw4
url: jdbc:mysql://192.168.2.201:3306/im-core?serverTimezone=UTC&useSSL=false&characterEncoding=UTF8
username: root
application:
name: im-core
# logger 配置
logging:
config: classpath:logback-spring.xml
server:
port: 8000
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
mapper-locations: classpath*:mapper/*.xml
global-config:
db-config:
update-strategy: NOT_EMPTY
#mybatis:
# configuration:
# log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
httpclient:
maxTotal: 100
defaultMaxPerRoute: 50
connectTimeout: 2000
connectionRequestTimeout: 2000
socketTimeout: 5000
staleConnectionCheckEnabled: true

View File

@@ -0,0 +1,88 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!-- 日志级别从低到高分为TRACE < DEBUG < INFO < WARN < ERROR < FATAL如果设置为WARN则低于WARN的信息都不会输出 -->
<!-- scan:当此属性设置为true时配置文件如果发生改变将会被重新加载默认值为true -->
<!-- scanPeriod:设置监测配置文件是否有修改的时间间隔如果没有给出时间单位默认单位是毫秒。当scan为true时此属性生效。默认的时间间隔为1分钟。 -->
<!-- debug:当此属性设置为true时将打印出logback内部日志信息实时查看logback运行状态。默认值为false。 -->
<configuration scan="true" scanPeriod="10 seconds" >
<include resource="org/springframework/boot/logging/logback/defualts.xml"/>
<springProperty scope="context" name="springAppName" source="spring.application.name"/>
<springProperty scope="context" name="springAppEnv" source="spring.profiles.active"/>
<!-- <springProperty scope="context" name="logFile" source="logging.file"/> -->
<property name="logFile" value="logs/mylog.log"/>
<!--日志在工程中的输出位置-->
<property name="LOG_FILE" value="${logFile}"/>
<!-- 彩色日志依赖的渲染类 -->
<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{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>
<!--控制台 Appender-->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>DEBUG</level>
</filter>
<encoder>
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
<charset>utf8</charset>
</encoder>
</appender>
<!--隐藏服务发现后输出的日志-->
<logger name="com.netflix.discovery.shared.resolver.aws.ConfigClusterResolver" level="WARN"/>
<logger name="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping" level="WARN"/>
<springProfile name="test,dev">
<!--文件-->
<appender name="fileAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
<Prudent>true</Prudent>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<FileNamePattern>
${logFile}.%d{yyyy-MM-dd}.log
</FileNamePattern>
</rollingPolicy>
<layout class="ch.qos.logback.classic.PatternLayout">
<Pattern>
%d{yyyy-MM-dd HH:mm:ss} -%msg%n
</Pattern>
</layout>
</appender>
<root level="INFO">
<appender-ref ref="console"/>
<appender-ref ref="fileAppender"/>
</root>
</springProfile>
<springProfile name="prod">
<!--文件-->
<appender name="fileAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
<Prudent>true</Prudent>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<FileNamePattern>
${logFile}.%d{yyyy-MM-dd}.log
</FileNamePattern>
</rollingPolicy>
<layout class="ch.qos.logback.classic.PatternLayout">
<Pattern>
%d{yyyy-MM-dd HH:mm:ss} -%msg%n
</Pattern>
</layout>
</appender>
<root level="WARN">
<appender-ref ref="console"/>
<appender-ref ref="fileAppender"/>
</root>
</springProfile>
</configuration>