committed by
Gitee
354 changed files with 4803 additions and 4382 deletions
@ -1,31 +0,0 @@ |
|||||
package com.bx.imclient.config; |
|
||||
|
|
||||
import com.alibaba.fastjson.support.spring.FastJsonRedisSerializer; |
|
||||
import org.springframework.context.annotation.Bean; |
|
||||
import org.springframework.context.annotation.Configuration; |
|
||||
import org.springframework.data.redis.connection.RedisConnectionFactory; |
|
||||
import org.springframework.data.redis.core.RedisTemplate; |
|
||||
import org.springframework.data.redis.serializer.StringRedisSerializer; |
|
||||
|
|
||||
@Configuration("IMRedisConfig") |
|
||||
public class RedisConfig { |
|
||||
|
|
||||
@Bean("IMRedisTemplate") |
|
||||
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) { |
|
||||
RedisTemplate<String, Object> redisTemplate = new RedisTemplate(); |
|
||||
redisTemplate.setConnectionFactory(redisConnectionFactory); |
|
||||
// 设置值(value)的序列化采用FastJsonRedisSerializer
|
|
||||
redisTemplate.setValueSerializer(fastJsonRedisSerializer()); |
|
||||
redisTemplate.setHashValueSerializer(fastJsonRedisSerializer()); |
|
||||
// 设置键(key)的序列化采用StringRedisSerializer。
|
|
||||
redisTemplate.setKeySerializer(new StringRedisSerializer()); |
|
||||
redisTemplate.setHashKeySerializer(new StringRedisSerializer()); |
|
||||
redisTemplate.afterPropertiesSet(); |
|
||||
return redisTemplate; |
|
||||
} |
|
||||
|
|
||||
public FastJsonRedisSerializer fastJsonRedisSerializer(){ |
|
||||
return new FastJsonRedisSerializer<>(Object.class); |
|
||||
} |
|
||||
|
|
||||
} |
|
||||
@ -1,44 +1,21 @@ |
|||||
package com.bx.imclient.task; |
package com.bx.imclient.task; |
||||
|
|
||||
import com.bx.imcommon.util.ThreadPoolExecutorFactory; |
import cn.hutool.core.util.StrUtil; |
||||
import lombok.SneakyThrows; |
import com.bx.imcommon.mq.RedisMQConsumer; |
||||
import lombok.extern.slf4j.Slf4j; |
import lombok.extern.slf4j.Slf4j; |
||||
import org.springframework.boot.CommandLineRunner; |
import org.springframework.beans.factory.annotation.Value; |
||||
|
|
||||
import javax.annotation.PreDestroy; |
|
||||
import java.util.concurrent.ExecutorService; |
|
||||
|
|
||||
@Slf4j |
@Slf4j |
||||
public abstract class AbstractMessageResultTask implements CommandLineRunner { |
public abstract class AbstractMessageResultTask<T> extends RedisMQConsumer<T> { |
||||
|
|
||||
private static final ExecutorService EXECUTOR_SERVICE = ThreadPoolExecutorFactory.getThreadPoolExecutor(); |
@Value("${spring.application.name}") |
||||
|
private String appName; |
||||
|
|
||||
@Override |
@Override |
||||
public void run(String... args) { |
public String generateKey() { |
||||
// 初始化定时器
|
return StrUtil.join(":", super.generateKey(), appName); |
||||
EXECUTOR_SERVICE.execute(new Runnable() { |
|
||||
@SneakyThrows |
|
||||
@Override |
|
||||
public void run() { |
|
||||
try { |
|
||||
pullMessage(); |
|
||||
} catch (Exception e) { |
|
||||
log.error("任务调度异常", e); |
|
||||
} |
|
||||
if (!EXECUTOR_SERVICE.isShutdown()) { |
|
||||
Thread.sleep(100); |
|
||||
EXECUTOR_SERVICE.execute(this); |
|
||||
} |
|
||||
} |
|
||||
}); |
|
||||
} |
} |
||||
|
|
||||
|
|
||||
@PreDestroy |
|
||||
public void destroy() { |
|
||||
log.info("{}线程任务关闭", this.getClass().getSimpleName()); |
|
||||
EXECUTOR_SERVICE.shutdown(); |
|
||||
} |
|
||||
|
|
||||
public abstract void pullMessage() throws InterruptedException; |
|
||||
} |
} |
||||
|
|||||
@ -1,59 +1,27 @@ |
|||||
package com.bx.imclient.task; |
package com.bx.imclient.task; |
||||
|
|
||||
import cn.hutool.core.util.StrUtil; |
|
||||
import com.alibaba.fastjson.JSONObject; |
|
||||
import com.bx.imclient.listener.MessageListenerMulticaster; |
import com.bx.imclient.listener.MessageListenerMulticaster; |
||||
import com.bx.imcommon.contant.IMRedisKey; |
import com.bx.imcommon.contant.IMRedisKey; |
||||
import com.bx.imcommon.enums.IMListenerType; |
import com.bx.imcommon.enums.IMListenerType; |
||||
import com.bx.imcommon.model.IMSendResult; |
import com.bx.imcommon.model.IMSendResult; |
||||
|
import com.bx.imcommon.mq.RedisMQListener; |
||||
import lombok.RequiredArgsConstructor; |
import lombok.RequiredArgsConstructor; |
||||
import org.springframework.beans.factory.annotation.Value; |
|
||||
import org.springframework.data.redis.core.RedisTemplate; |
|
||||
import org.springframework.stereotype.Component; |
import org.springframework.stereotype.Component; |
||||
|
|
||||
import javax.annotation.Resource; |
|
||||
import java.util.LinkedList; |
|
||||
import java.util.List; |
import java.util.List; |
||||
import java.util.Objects; |
|
||||
|
|
||||
|
|
||||
@Component |
@Component |
||||
@RequiredArgsConstructor |
@RequiredArgsConstructor |
||||
public class GroupMessageResultResultTask extends AbstractMessageResultTask { |
@RedisMQListener(queue = IMRedisKey.IM_RESULT_GROUP_QUEUE, batchSize = 100) |
||||
|
public class GroupMessageResultResultTask extends AbstractMessageResultTask<IMSendResult> { |
||||
@Resource(name = "IMRedisTemplate") |
|
||||
private RedisTemplate<String,Object> redisTemplate; |
|
||||
|
|
||||
@Value("${spring.application.name}") |
|
||||
private String appName; |
|
||||
|
|
||||
@Value("${im.result.batch:100}") |
|
||||
private int batchSize; |
|
||||
|
|
||||
private final MessageListenerMulticaster listenerMulticaster; |
private final MessageListenerMulticaster listenerMulticaster; |
||||
|
|
||||
@Override |
@Override |
||||
public void pullMessage() { |
public void onMessage(List<IMSendResult> results) { |
||||
List<IMSendResult> results; |
listenerMulticaster.multicast(IMListenerType.GROUP_MESSAGE, results); |
||||
do { |
|
||||
results = loadBatch(); |
|
||||
if(!results.isEmpty()){ |
|
||||
listenerMulticaster.multicast(IMListenerType.GROUP_MESSAGE, results); |
|
||||
} |
|
||||
} while (results.size() >= batchSize); |
|
||||
} |
} |
||||
|
|
||||
List<IMSendResult> loadBatch() { |
|
||||
String key = StrUtil.join(":", IMRedisKey.IM_RESULT_GROUP_QUEUE, appName); |
|
||||
//这个接口redis6.2以上才支持
|
|
||||
//List<Object> list = redisTemplate.opsForList().leftPop(key, batchSize);
|
|
||||
List<IMSendResult> results = new LinkedList<>(); |
|
||||
JSONObject jsonObject = (JSONObject) redisTemplate.opsForList().leftPop(key); |
|
||||
while (!Objects.isNull(jsonObject) && results.size() < batchSize) { |
|
||||
results.add(jsonObject.toJavaObject(IMSendResult.class)); |
|
||||
jsonObject = (JSONObject) redisTemplate.opsForList().leftPop(key); |
|
||||
} |
|
||||
return results; |
|
||||
} |
|
||||
|
|
||||
} |
} |
||||
|
|||||
@ -1,60 +1,26 @@ |
|||||
package com.bx.imclient.task; |
package com.bx.imclient.task; |
||||
|
|
||||
import cn.hutool.core.util.StrUtil; |
|
||||
import com.alibaba.fastjson.JSONObject; |
|
||||
import com.bx.imclient.listener.MessageListenerMulticaster; |
import com.bx.imclient.listener.MessageListenerMulticaster; |
||||
import com.bx.imcommon.contant.IMRedisKey; |
import com.bx.imcommon.contant.IMRedisKey; |
||||
import com.bx.imcommon.enums.IMListenerType; |
import com.bx.imcommon.enums.IMListenerType; |
||||
import com.bx.imcommon.model.IMSendResult; |
import com.bx.imcommon.model.IMSendResult; |
||||
|
import com.bx.imcommon.mq.RedisMQListener; |
||||
import lombok.RequiredArgsConstructor; |
import lombok.RequiredArgsConstructor; |
||||
import lombok.extern.slf4j.Slf4j; |
|
||||
import org.springframework.beans.factory.annotation.Value; |
|
||||
import org.springframework.data.redis.core.RedisTemplate; |
|
||||
import org.springframework.stereotype.Component; |
import org.springframework.stereotype.Component; |
||||
|
|
||||
import javax.annotation.Resource; |
|
||||
import java.util.LinkedList; |
|
||||
import java.util.List; |
import java.util.List; |
||||
import java.util.Objects; |
|
||||
|
|
||||
@Slf4j |
|
||||
@Component |
@Component |
||||
@RequiredArgsConstructor |
@RequiredArgsConstructor |
||||
public class PrivateMessageResultResultTask extends AbstractMessageResultTask { |
@RedisMQListener(queue = IMRedisKey.IM_RESULT_PRIVATE_QUEUE, batchSize = 100) |
||||
|
public class PrivateMessageResultResultTask extends AbstractMessageResultTask<IMSendResult> { |
||||
@Resource(name = "IMRedisTemplate") |
|
||||
private RedisTemplate<String, Object> redisTemplate; |
|
||||
|
|
||||
@Value("${spring.application.name}") |
|
||||
private String appName; |
|
||||
|
|
||||
@Value("${im.result.batch:100}") |
|
||||
private int batchSize; |
|
||||
|
|
||||
private final MessageListenerMulticaster listenerMulticaster; |
private final MessageListenerMulticaster listenerMulticaster; |
||||
|
|
||||
@Override |
@Override |
||||
public void pullMessage() { |
public void onMessage(List<IMSendResult> results) { |
||||
List<IMSendResult> results; |
listenerMulticaster.multicast(IMListenerType.PRIVATE_MESSAGE, results); |
||||
do { |
|
||||
results = loadBatch(); |
|
||||
if(!results.isEmpty()){ |
|
||||
listenerMulticaster.multicast(IMListenerType.PRIVATE_MESSAGE, results); |
|
||||
} |
|
||||
} while (results.size() >= batchSize); |
|
||||
} |
|
||||
|
|
||||
List<IMSendResult> loadBatch() { |
|
||||
String key = StrUtil.join(":", IMRedisKey.IM_RESULT_PRIVATE_QUEUE, appName); |
|
||||
//这个接口redis6.2以上才支持
|
|
||||
//List<Object> list = redisTemplate.opsForList().leftPop(key, batchSize);
|
|
||||
List<IMSendResult> results = new LinkedList<>(); |
|
||||
JSONObject jsonObject = (JSONObject) redisTemplate.opsForList().leftPop(key); |
|
||||
while (!Objects.isNull(jsonObject) && results.size() < batchSize) { |
|
||||
results.add(jsonObject.toJavaObject(IMSendResult.class)); |
|
||||
jsonObject = (JSONObject) redisTemplate.opsForList().leftPop(key); |
|
||||
} |
|
||||
return results; |
|
||||
} |
} |
||||
|
|
||||
} |
} |
||||
|
|||||
@ -0,0 +1,25 @@ |
|||||
|
package com.bx.imclient.task; |
||||
|
|
||||
|
import com.bx.imclient.listener.MessageListenerMulticaster; |
||||
|
import com.bx.imcommon.contant.IMRedisKey; |
||||
|
import com.bx.imcommon.enums.IMListenerType; |
||||
|
import com.bx.imcommon.model.IMSendResult; |
||||
|
import com.bx.imcommon.mq.RedisMQListener; |
||||
|
import lombok.RequiredArgsConstructor; |
||||
|
import org.springframework.stereotype.Component; |
||||
|
|
||||
|
import java.util.List; |
||||
|
|
||||
|
@Component |
||||
|
@RequiredArgsConstructor |
||||
|
@RedisMQListener(queue = IMRedisKey.IM_RESULT_SYSTEM_QUEUE, batchSize = 100) |
||||
|
public class SystemMessageResultResultTask extends AbstractMessageResultTask<IMSendResult> { |
||||
|
|
||||
|
private final MessageListenerMulticaster listenerMulticaster; |
||||
|
|
||||
|
@Override |
||||
|
public void onMessage(List<IMSendResult> results) { |
||||
|
listenerMulticaster.multicast(IMListenerType.SYSTEM_MESSAGE, results); |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -1,2 +0,0 @@ |
|||||
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ |
|
||||
com.bx.imclient.IMAutoConfiguration |
|
||||
@ -0,0 +1 @@ |
|||||
|
com.bx.imclient.IMAutoConfiguration |
||||
@ -0,0 +1,34 @@ |
|||||
|
package com.bx.imcommon.model; |
||||
|
|
||||
|
import com.bx.imcommon.enums.IMTerminalType; |
||||
|
import lombok.Data; |
||||
|
|
||||
|
import java.util.LinkedList; |
||||
|
import java.util.List; |
||||
|
|
||||
|
@Data |
||||
|
public class IMSystemMessage<T> { |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* 接收者id列表,为空表示向所有在线用户广播 |
||||
|
*/ |
||||
|
private List<Long> recvIds = new LinkedList<>(); |
||||
|
|
||||
|
/** |
||||
|
* 接收者终端类型,默认全部 |
||||
|
*/ |
||||
|
private List<Integer> recvTerminals = IMTerminalType.codes(); |
||||
|
|
||||
|
/** |
||||
|
* 是否需要回推发送结果,默认true |
||||
|
*/ |
||||
|
private Boolean sendResult = true; |
||||
|
|
||||
|
/** |
||||
|
* 消息内容 |
||||
|
*/ |
||||
|
private T data; |
||||
|
|
||||
|
|
||||
|
} |
||||
@ -0,0 +1,32 @@ |
|||||
|
package com.bx.imcommon.mq; |
||||
|
|
||||
|
import com.alibaba.fastjson.support.spring.FastJsonRedisSerializer; |
||||
|
import org.springframework.context.annotation.Bean; |
||||
|
import org.springframework.context.annotation.Configuration; |
||||
|
import org.springframework.data.redis.connection.RedisConnectionFactory; |
||||
|
import org.springframework.data.redis.serializer.StringRedisSerializer; |
||||
|
|
||||
|
|
||||
|
@Configuration |
||||
|
public class RedisMQConfig { |
||||
|
|
||||
|
@Bean |
||||
|
public RedisMQTemplate redisMQTemplate(RedisConnectionFactory redisConnectionFactory) { |
||||
|
RedisMQTemplate redisMQTemplate = new RedisMQTemplate(); |
||||
|
redisMQTemplate.setConnectionFactory(redisConnectionFactory); |
||||
|
// 设置值(value)的序列化采用FastJsonRedisSerializer
|
||||
|
redisMQTemplate.setValueSerializer(fastJsonRedisSerializer()); |
||||
|
redisMQTemplate.setHashValueSerializer(fastJsonRedisSerializer()); |
||||
|
// 设置键(key)的序列化采用StringRedisSerializer。
|
||||
|
redisMQTemplate.setKeySerializer(new StringRedisSerializer()); |
||||
|
redisMQTemplate.setHashKeySerializer(new StringRedisSerializer()); |
||||
|
redisMQTemplate.afterPropertiesSet(); |
||||
|
return redisMQTemplate; |
||||
|
} |
||||
|
|
||||
|
@Bean |
||||
|
public FastJsonRedisSerializer fastJsonRedisSerializer(){ |
||||
|
return new FastJsonRedisSerializer<>(Object.class); |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,35 @@ |
|||||
|
package com.bx.imcommon.mq; |
||||
|
|
||||
|
import java.util.List; |
||||
|
|
||||
|
/** |
||||
|
* redis 队列消费者抽象类 |
||||
|
*/ |
||||
|
public abstract class RedisMQConsumer<T> { |
||||
|
|
||||
|
/** |
||||
|
* 消费消息回调(单条) |
||||
|
*/ |
||||
|
public void onMessage(T data){} |
||||
|
|
||||
|
/** |
||||
|
* 消费消息回调(批量) |
||||
|
*/ |
||||
|
public void onMessage(List<T> datas){} |
||||
|
|
||||
|
/** |
||||
|
* 生成redis队列完整key |
||||
|
*/ |
||||
|
public String generateKey(){ |
||||
|
// 默认队列名就是redis的key
|
||||
|
RedisMQListener annotation = this.getClass().getAnnotation(RedisMQListener.class); |
||||
|
return annotation.queue(); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 队列是否就绪,返回true才会开始消费 |
||||
|
*/ |
||||
|
public Boolean isReady(){ |
||||
|
return true; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,29 @@ |
|||||
|
package com.bx.imcommon.mq; |
||||
|
|
||||
|
import java.lang.annotation.ElementType; |
||||
|
import java.lang.annotation.Retention; |
||||
|
import java.lang.annotation.RetentionPolicy; |
||||
|
import java.lang.annotation.Target; |
||||
|
|
||||
|
/** |
||||
|
* redis 队列消费监听注解 |
||||
|
*/ |
||||
|
@Retention(RetentionPolicy.RUNTIME) |
||||
|
@Target(ElementType.TYPE) |
||||
|
public @interface RedisMQListener { |
||||
|
|
||||
|
/** |
||||
|
* 队列,也是redis的key |
||||
|
*/ |
||||
|
String queue(); |
||||
|
|
||||
|
/** |
||||
|
* 一次性拉取的数据数量 |
||||
|
*/ |
||||
|
int batchSize() default 1; |
||||
|
|
||||
|
/** |
||||
|
* 拉取间隔周期,单位:ms |
||||
|
*/ |
||||
|
int period() default 100; |
||||
|
} |
||||
@ -0,0 +1,114 @@ |
|||||
|
package com.bx.imcommon.mq; |
||||
|
|
||||
|
import com.alibaba.fastjson.JSONObject; |
||||
|
import com.bx.imcommon.util.ThreadPoolExecutorFactory; |
||||
|
import jakarta.annotation.PreDestroy; |
||||
|
import lombok.extern.slf4j.Slf4j; |
||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||
|
import org.springframework.boot.CommandLineRunner; |
||||
|
import org.springframework.stereotype.Component; |
||||
|
|
||||
|
import java.lang.reflect.ParameterizedType; |
||||
|
import java.lang.reflect.Type; |
||||
|
import java.util.Collections; |
||||
|
import java.util.LinkedList; |
||||
|
import java.util.List; |
||||
|
import java.util.Objects; |
||||
|
import java.util.concurrent.ScheduledThreadPoolExecutor; |
||||
|
import java.util.concurrent.TimeUnit; |
||||
|
|
||||
|
/** |
||||
|
* reids 队列拉取定时任务 |
||||
|
* |
||||
|
* @author: Blue |
||||
|
* @date: 2024-07-15 |
||||
|
* @version: 1.0 |
||||
|
*/ |
||||
|
@Slf4j |
||||
|
@Component |
||||
|
public class RedisMQPullTask implements CommandLineRunner { |
||||
|
|
||||
|
private static final ScheduledThreadPoolExecutor EXECUTOR = ThreadPoolExecutorFactory.getThreadPoolExecutor(); |
||||
|
|
||||
|
@Autowired(required = false) |
||||
|
private List<RedisMQConsumer> consumers = Collections.emptyList(); |
||||
|
|
||||
|
@Autowired |
||||
|
private RedisMQTemplate redisMQTemplate; |
||||
|
|
||||
|
@Override |
||||
|
public void run(String... args) { |
||||
|
consumers.forEach((consumer -> { |
||||
|
// 注解参数
|
||||
|
RedisMQListener annotation = consumer.getClass().getAnnotation(RedisMQListener.class); |
||||
|
String queue = annotation.queue(); |
||||
|
int batchSize = annotation.batchSize(); |
||||
|
int period = annotation.period(); |
||||
|
// 获取泛型类型
|
||||
|
Type superClass = consumer.getClass().getGenericSuperclass(); |
||||
|
Type type = ((ParameterizedType)superClass).getActualTypeArguments()[0]; |
||||
|
EXECUTOR.execute(new Runnable() { |
||||
|
@Override |
||||
|
public void run() { |
||||
|
List<Object> datas = new LinkedList<>(); |
||||
|
try { |
||||
|
if(redisMQTemplate.isClose()){ |
||||
|
return; |
||||
|
} |
||||
|
if (consumer.isReady()) { |
||||
|
String key = consumer.generateKey(); |
||||
|
// 拉取一个批次的数据
|
||||
|
List<Object> objects = pullBatch(key, batchSize); |
||||
|
for (Object obj : objects) { |
||||
|
if (obj instanceof JSONObject) { |
||||
|
JSONObject jsonObject = (JSONObject)obj; |
||||
|
Object data = jsonObject.toJavaObject(type); |
||||
|
consumer.onMessage(data); |
||||
|
datas.add(data); |
||||
|
} |
||||
|
} |
||||
|
if (!datas.isEmpty()) { |
||||
|
consumer.onMessage(datas); |
||||
|
} |
||||
|
} |
||||
|
} catch (Exception e) { |
||||
|
log.error("数据消费异常,队列:{}", queue, e); |
||||
|
return; |
||||
|
} |
||||
|
// 继续消费数据
|
||||
|
if (!EXECUTOR.isShutdown()) { |
||||
|
if (datas.size() < batchSize) { |
||||
|
// 数据已经消费完,等待下一个周期继续拉取
|
||||
|
EXECUTOR.schedule(this, period, TimeUnit.MICROSECONDS); |
||||
|
} else { |
||||
|
// 数据没有消费完,直接开启下一个消费周期
|
||||
|
EXECUTOR.execute(this); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
})); |
||||
|
} |
||||
|
|
||||
|
private List<Object> pullBatch(String key, Integer batchSize) { |
||||
|
List<Object> objects = new LinkedList<>(); |
||||
|
if (redisMQTemplate.isSupportBatchPull()) { |
||||
|
// 版本大于6.2,支持批量拉取
|
||||
|
objects = redisMQTemplate.opsForList().leftPop(key, batchSize); |
||||
|
} else { |
||||
|
// 版本小于6.2,只能逐条拉取
|
||||
|
Object obj = redisMQTemplate.opsForList().leftPop(key); |
||||
|
while (!Objects.isNull(obj) && objects.size() < batchSize) { |
||||
|
objects.add(obj); |
||||
|
obj = redisMQTemplate.opsForList().leftPop(key); |
||||
|
} |
||||
|
} |
||||
|
return objects; |
||||
|
} |
||||
|
|
||||
|
@PreDestroy |
||||
|
public void destory() { |
||||
|
log.info("消费线程停止..."); |
||||
|
ThreadPoolExecutorFactory.shutDown(); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,52 @@ |
|||||
|
package com.bx.imcommon.mq; |
||||
|
|
||||
|
import org.apache.logging.log4j.util.Strings; |
||||
|
import org.springframework.data.redis.connection.RedisConnection; |
||||
|
import org.springframework.data.redis.connection.RedisConnectionFactory; |
||||
|
import org.springframework.data.redis.core.RedisTemplate; |
||||
|
|
||||
|
import java.util.Objects; |
||||
|
import java.util.Properties; |
||||
|
|
||||
|
/** |
||||
|
* @author: Blue |
||||
|
* @date: 2024-07-16 |
||||
|
* @version: 1.0 |
||||
|
*/ |
||||
|
public class RedisMQTemplate extends RedisTemplate<String, Object> { |
||||
|
|
||||
|
private String version = Strings.EMPTY; |
||||
|
|
||||
|
public String getVersion() { |
||||
|
if (version.isEmpty()) { |
||||
|
RedisConnection redisConnection = this.getConnectionFactory().getConnection(); |
||||
|
Properties properties = redisConnection.info(); |
||||
|
version = properties.getProperty("redis_version"); |
||||
|
} |
||||
|
return version; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 是否支持批量拉取,redis版本大于6.2支持批量拉取 |
||||
|
* @return |
||||
|
*/ |
||||
|
Boolean isSupportBatchPull() { |
||||
|
String version = getVersion(); |
||||
|
String[] arr = version.split("\\."); |
||||
|
if (arr.length < 2) { |
||||
|
return false; |
||||
|
} |
||||
|
Integer firVersion = Integer.valueOf(arr[0]); |
||||
|
Integer secVersion = Integer.valueOf(arr[1]); |
||||
|
return firVersion > 6 || (firVersion == 6 && secVersion >= 2); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
Boolean isClose(){ |
||||
|
try { |
||||
|
return getConnectionFactory().getConnection().isClosed(); |
||||
|
}catch (Exception e){ |
||||
|
return true; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -1,26 +0,0 @@ |
|||||
# docker 构建和部署指南 |
|
||||
|
|
||||
## 配置 |
|
||||
|
|
||||
请配置以下文件的挂载目录、端口号、环境变量、账户信息等。 |
|
||||
|
|
||||
- box-im/im-docker-compose/im-coturn/docker-compose.yml |
|
||||
- box-im/im-docker-compose/im-service/docker-compose.yml |
|
||||
- box-im/im-docker-compose/im-coturn/im-platform.env |
|
||||
- box-im/im-docker-compose/im-coturn/im-server.env |
|
||||
|
|
||||
## 构建 |
|
||||
|
|
||||
可以在部署的目标服务器上在下面两个目录下构建出 im-server 和 im-platform 的 docker images. |
|
||||
|
|
||||
- box-im/im-server/Dockerfile |
|
||||
- box-im/im-platform/Dockerfile |
|
||||
|
|
||||
## 部署 |
|
||||
|
|
||||
在部署的目标服务器上通过 docker-compose 启动所有容器, |
|
||||
|
|
||||
```bash |
|
||||
docker-compose -f im-docker-compose/im-coturn/docker-compose.yml up -d |
|
||||
docker-compose -f im-docker-compose/im-service/docker-compose.yml up -d |
|
||||
``` |
|
||||
@ -1,27 +0,0 @@ |
|||||
|
|
||||
version: "3" |
|
||||
|
|
||||
services: |
|
||||
im-coturn: |
|
||||
container_name: im-coturn |
|
||||
image: coturn/coturn:4.6.2-alpine |
|
||||
command: turnserver -v -a -c /etc/coturn/conf/coturn.conf |
|
||||
restart: always |
|
||||
ports: |
|
||||
- PORT_COTURN_LISTEN_OS:3478 |
|
||||
- PORT_COTURN_LISTEN_OS:3478/udp |
|
||||
- PORT_COTURN_LISTEN_TLS_OS:5349 |
|
||||
- PORT_COTURN_LISTEN_TLS_OS:5349/udp |
|
||||
- PORT_COTURN_RELAY_BEGIN_OS-PORT_COTURN_RELAY_END_OS:PORT_COTURN_RELAY_BEGIN_OS-PORT_COTURN_RELAY_END_OS/udp |
|
||||
# network_mode: "host" |
|
||||
environment: |
|
||||
- DETECT_EXTERNAL_IP=yes |
|
||||
- DETECT_RELAY_IP=yes |
|
||||
volumes: |
|
||||
- deploydir/docker_volumes_data/coturn/conf:/etc/coturn/conf |
|
||||
- deploydir/docker_volumes_data/coturn/certs:/etc/coturn/ssl |
|
||||
- deploydir/docker_volumes_data/coturn/log:/var/log/coturn/ |
|
||||
networks: |
|
||||
default: |
|
||||
external: |
|
||||
name: turn-network |
|
||||
@ -1,99 +0,0 @@ |
|||||
|
|
||||
version: "3" |
|
||||
|
|
||||
services: |
|
||||
im-mysql: |
|
||||
container_name: im-mysql |
|
||||
image: mysql:5.7 |
|
||||
command: --default-authentication-plugin=mysql_native_password |
|
||||
restart: always |
|
||||
environment: |
|
||||
- TZ=Asia/Shanghai |
|
||||
- MYSQL_ROOT_PASSWORD=MYSQL_ROOT_USER_PASSWORD |
|
||||
- MYSQL_ROOT_HOST=% |
|
||||
- MYSQL_IM_USERNAME=MYSQL_USERNAME |
|
||||
- MYSQL_IM_PASSWORD=MYSQL_PASSWORD |
|
||||
volumes: |
|
||||
- deploydir/docker_volumes_data/mysql/data:/var/lib/mysql |
|
||||
- deploydir/docker_volumes_data/mysql/mysql.conf.d:/etc/mysql/mysql.conf.d |
|
||||
|
|
||||
im-redis: |
|
||||
container_name: im-redis |
|
||||
image: redis:6-alpine |
|
||||
command: redis-server --requirepass REDIS_PASSWORD --appendonly yes --appendfsync everysec --auto-aof-rewrite-percentage 100 --auto-aof-rewrite-min-size 100mb |
|
||||
restart: always |
|
||||
# ports: |
|
||||
# - "127.0.0.1:6379:6379" |
|
||||
volumes: |
|
||||
- deploydir/docker_volumes_data/redis/data:/data |
|
||||
|
|
||||
im-minio: |
|
||||
container_name: im-minio |
|
||||
image: bitnami/minio:2024 |
|
||||
restart: always |
|
||||
# ports: |
|
||||
# - 9001:9001 |
|
||||
# - 9002:9002 |
|
||||
privileged: true |
|
||||
environment: |
|
||||
- MINIO_SKIP_CLIENT=yes |
|
||||
- MINIO_API_PORT_NUMBER=9001 |
|
||||
- MINIO_CONSOLE_PORT_NUMBER=9002 |
|
||||
# - MINIO_OPTS="--console-address :9002 --address :9001" |
|
||||
# - MINIO_DOMAIN=im_minio:9001 |
|
||||
- MINIO_DATA_DIR=/data/minio |
|
||||
- MINIO_ROOT_USER=MINIO_USERNAME |
|
||||
- MINIO_ROOT_PASSWORD=MINIO_PASSWORD |
|
||||
volumes: |
|
||||
- deploydir/docker_volumes_data/minio/data:/data/minio |
|
||||
|
|
||||
im-nginx: |
|
||||
container_name: im-nginx |
|
||||
image: openresty/openresty:1.21.4.1-0-alpine |
|
||||
restart: always |
|
||||
ports: |
|
||||
- PORT_NGINX_HTTP_OS:80 |
|
||||
- PORT_NGINX_HTTPS_OS:443 |
|
||||
- PORT_NGINX_WSS_OS:81 |
|
||||
depends_on: |
|
||||
im-platform: |
|
||||
condition: service_started |
|
||||
im-server: |
|
||||
condition: service_started |
|
||||
volumes: |
|
||||
- deploydir/docker_volumes_data/nginx/data/conf:/etc/nginx ## configs |
|
||||
- deploydir/docker_volumes_data/nginx/data/certs:/etc/certs ## cert files |
|
||||
- deploydir/docker_volumes_data/nginx/data/web:/usr/share/nginx ## web |
|
||||
|
|
||||
im-platform: |
|
||||
container_name: im-platform |
|
||||
image: im-platform:latest |
|
||||
restart: always |
|
||||
depends_on: |
|
||||
im-mysql: |
|
||||
condition: service_started |
|
||||
im-redis: |
|
||||
condition: service_started |
|
||||
im-minio: |
|
||||
condition: service_started |
|
||||
env_file: |
|
||||
- im-platform.env |
|
||||
|
|
||||
im-server: |
|
||||
container_name: im-server |
|
||||
image: im-server:latest |
|
||||
restart: always |
|
||||
depends_on: |
|
||||
im-mysql: |
|
||||
condition: service_started |
|
||||
im-redis: |
|
||||
condition: service_started |
|
||||
im-minio: |
|
||||
condition: service_started |
|
||||
env_file: |
|
||||
- im-server.env |
|
||||
networks: |
|
||||
default: |
|
||||
external: |
|
||||
name: im-network |
|
||||
|
|
||||
@ -1,28 +0,0 @@ |
|||||
spring_datasource_username=MYSQL_USERNAME |
|
||||
spring_datasource_password=MYSQL_PASSWORD |
|
||||
spring_redis_password=REDIS_PASSWORD |
|
||||
|
|
||||
spring_datasource_url=jdbc:mysql://im-mysql:3306/box-im?useSSL=false&useUnicode=true&characterEncoding=utf-8 |
|
||||
spring_datasource_password=MYSQL_PASSWORD |
|
||||
spring_redis_host=im-redis |
|
||||
spring_redis_port=6379 |
|
||||
spring_redis_password=REDIS_PASSWORD |
|
||||
|
|
||||
minio_accessKey=MINIO_USERNAME |
|
||||
minio_secretKey=MINIO_PASSWORD |
|
||||
minio_public=https://IM_DOMAIN:PORT_NGINX_HTTPS_EXTERNAL/file |
|
||||
minio_endpoint=http://im-minio:9001 |
|
||||
|
|
||||
ICE_SERVER_1_URL=TURN_DOMAIN:PORT_COTURN_LISTEN_EXTERNAL |
|
||||
ICE_SERVER_1_USERNAME=TURN_USERNAME |
|
||||
ICE_SERVER_1_CREDENTIAL=TURN_PASSWORD |
|
||||
|
|
||||
ICE_SERVER_2_URL=TURN_DOMAIN:PORT_COTURN_LISTEN_EXTERNAL |
|
||||
ICE_SERVER_2_USERNAME=TURN_USERNAME |
|
||||
ICE_SERVER_2_CREDENTIAL=TURN_PASSWORD |
|
||||
|
|
||||
jwt_accessToken_secret=JWT_ACCESSTOKEN_SECRET |
|
||||
jwt_accessToken_expireIn=JWT_ACCESSTOKEN_EXPIREDIN |
|
||||
jwt_refreshToken_secret=JWT_REFRESHTOKEN_SECRET |
|
||||
jwt_refreshToken_expireIn=JWT_REFRESHTOKEN_EXPIREDIN |
|
||||
|
|
||||
@ -1,4 +0,0 @@ |
|||||
spring_redis_host=im-redis |
|
||||
spring_redis_port=6379 |
|
||||
spring_redis_password=REDIS_PASSWORD |
|
||||
jwt_accessToken_secret=JWT_ACCESSTOKEN_SECRET |
|
||||
@ -1,41 +1,38 @@ |
|||||
package com.bx.implatform.config; |
package com.bx.implatform.config; |
||||
|
|
||||
import io.swagger.annotations.ApiOperation; |
|
||||
|
import io.swagger.v3.oas.models.OpenAPI; |
||||
|
import io.swagger.v3.oas.models.info.Contact; |
||||
|
import io.swagger.v3.oas.models.info.Info; |
||||
|
import io.swagger.v3.oas.models.info.License; |
||||
|
import org.springdoc.core.models.GroupedOpenApi; |
||||
import org.springframework.context.annotation.Bean; |
import org.springframework.context.annotation.Bean; |
||||
import org.springframework.context.annotation.Configuration; |
import org.springframework.context.annotation.Configuration; |
||||
import springfox.documentation.builders.ApiInfoBuilder; |
|
||||
import springfox.documentation.builders.PathSelectors; |
|
||||
import springfox.documentation.builders.RequestHandlerSelectors; |
|
||||
import springfox.documentation.service.ApiInfo; |
|
||||
import springfox.documentation.spi.DocumentationType; |
|
||||
import springfox.documentation.spring.web.plugins.Docket; |
|
||||
import springfox.documentation.swagger2.annotations.EnableSwagger2; |
|
||||
|
|
||||
@Configuration |
@Configuration |
||||
@EnableSwagger2 |
|
||||
public class SwaggerConfig { |
public class SwaggerConfig { |
||||
|
|
||||
@Bean |
@Bean |
||||
public Docket createRestApi() { |
public GroupedOpenApi userApi() { |
||||
|
String[] paths = {"/**"}; |
||||
return new Docket(DocumentationType.SWAGGER_2) |
String[] packagedToMatch = {"com.bx"}; |
||||
.apiInfo(apiInfo()) |
return GroupedOpenApi.builder().group("IM-Platform") |
||||
.select() |
.pathsToMatch(paths) |
||||
//这里采用包含注解的方式来确定要显示的接口
|
.packagesToScan(packagedToMatch).build(); |
||||
.apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class)) |
|
||||
//这里采用包扫描的方式来确定要显示的接口
|
|
||||
.paths(PathSelectors.any()) |
|
||||
.build(); |
|
||||
|
|
||||
} |
} |
||||
|
|
||||
private ApiInfo apiInfo() { |
@Bean |
||||
return new ApiInfoBuilder() |
public OpenAPI customOpenAPI() { |
||||
.title("IM Platform doc") |
Contact contact = new Contact(); |
||||
.description("盒子IM API文档") |
contact.setName("Blue"); |
||||
.termsOfServiceUrl("http://8.134.92.70/") |
return new OpenAPI().info(new Info() |
||||
.version("1.0") |
.title("盒子IM接口文档") |
||||
.build(); |
.description("盒子IM业务平台服务") |
||||
|
.contact(contact) |
||||
|
.version("3.0") |
||||
|
.termsOfService("https://www.boxim.online") |
||||
|
.license(new License().name("MIT") |
||||
|
.url("https://www.boxim.online"))); |
||||
} |
} |
||||
|
|
||||
} |
} |
||||
|
|||||
@ -1,126 +1,124 @@ |
|||||
package com.bx.implatform.controller; |
package com.bx.implatform.controller; |
||||
|
|
||||
import com.bx.implatform.config.WebrtcConfig; |
|
||||
import com.bx.implatform.dto.*; |
import com.bx.implatform.dto.*; |
||||
import com.bx.implatform.result.Result; |
import com.bx.implatform.result.Result; |
||||
import com.bx.implatform.result.ResultUtils; |
import com.bx.implatform.result.ResultUtils; |
||||
import com.bx.implatform.service.IWebrtcGroupService; |
import com.bx.implatform.service.WebrtcGroupService; |
||||
import com.bx.implatform.vo.WebrtcGroupInfoVO; |
import com.bx.implatform.vo.WebrtcGroupInfoVO; |
||||
import io.swagger.annotations.Api; |
import io.swagger.v3.oas.annotations.Operation; |
||||
import io.swagger.annotations.ApiOperation; |
import io.swagger.v3.oas.annotations.tags.Tag; |
||||
|
import jakarta.validation.Valid; |
||||
import lombok.RequiredArgsConstructor; |
import lombok.RequiredArgsConstructor; |
||||
import org.springframework.web.bind.annotation.*; |
import org.springframework.web.bind.annotation.*; |
||||
|
|
||||
import javax.validation.Valid; |
|
||||
|
|
||||
/** |
/** |
||||
* @author: Blue |
* @author: Blue |
||||
* @date: 2024-06-01 |
* @date: 2024-06-01 |
||||
* @version: 1.0 |
* @version: 1.0 |
||||
*/ |
*/ |
||||
@Api(tags = "webrtc视频多人通话") |
@Tag(name = "多人通话") |
||||
@RestController |
@RestController |
||||
@RequestMapping("/webrtc/group") |
@RequestMapping("/webrtc/group") |
||||
@RequiredArgsConstructor |
@RequiredArgsConstructor |
||||
public class WebrtcGroupController { |
public class WebrtcGroupController { |
||||
|
|
||||
private final IWebrtcGroupService webrtcGroupService; |
private final WebrtcGroupService webrtcGroupService; |
||||
|
|
||||
@ApiOperation(httpMethod = "POST", value = "发起群视频通话") |
@Operation(summary = "发起群视频通话") |
||||
@PostMapping("/setup") |
@PostMapping("/setup") |
||||
public Result setup(@Valid @RequestBody WebrtcGroupSetupDTO dto) { |
public Result setup(@Valid @RequestBody WebrtcGroupSetupDTO dto) { |
||||
webrtcGroupService.setup(dto); |
webrtcGroupService.setup(dto); |
||||
return ResultUtils.success(); |
return ResultUtils.success(); |
||||
} |
} |
||||
|
|
||||
@ApiOperation(httpMethod = "POST", value = "接受通话") |
@Operation(summary = "接受通话") |
||||
@PostMapping("/accept") |
@PostMapping("/accept") |
||||
public Result accept(@RequestParam Long groupId) { |
public Result accept(@RequestParam("groupId") Long groupId) { |
||||
webrtcGroupService.accept(groupId); |
webrtcGroupService.accept(groupId); |
||||
return ResultUtils.success(); |
return ResultUtils.success(); |
||||
} |
} |
||||
|
|
||||
@ApiOperation(httpMethod = "POST", value = "拒绝通话") |
@Operation(summary = "拒绝通话") |
||||
@PostMapping("/reject") |
@PostMapping("/reject") |
||||
public Result reject(@RequestParam Long groupId) { |
public Result reject(@RequestParam("groupId") Long groupId) { |
||||
webrtcGroupService.reject(groupId); |
webrtcGroupService.reject(groupId); |
||||
return ResultUtils.success(); |
return ResultUtils.success(); |
||||
} |
} |
||||
|
|
||||
@ApiOperation(httpMethod = "POST", value = "通话失败") |
@Operation(summary = "通话失败") |
||||
@PostMapping("/failed") |
@PostMapping("/failed") |
||||
public Result failed(@Valid @RequestBody WebrtcGroupFailedDTO dto) { |
public Result failed(@Valid @RequestBody WebrtcGroupFailedDTO dto) { |
||||
webrtcGroupService.failed(dto); |
webrtcGroupService.failed(dto); |
||||
return ResultUtils.success(); |
return ResultUtils.success(); |
||||
} |
} |
||||
|
|
||||
@ApiOperation(httpMethod = "POST", value = "进入视频通话") |
@Operation(summary = "进入视频通话") |
||||
@PostMapping("/join") |
@PostMapping("/join") |
||||
public Result join(@RequestParam Long groupId) { |
public Result join(@RequestParam("groupId") Long groupId) { |
||||
webrtcGroupService.join(groupId); |
webrtcGroupService.join(groupId); |
||||
return ResultUtils.success(); |
return ResultUtils.success(); |
||||
} |
} |
||||
|
|
||||
@ApiOperation(httpMethod = "POST", value = "取消通话") |
@Operation(summary = "取消通话") |
||||
@PostMapping("/cancel") |
@PostMapping("/cancel") |
||||
public Result cancel(@RequestParam Long groupId) { |
public Result cancel(@RequestParam("groupId") Long groupId) { |
||||
webrtcGroupService.cancel(groupId); |
webrtcGroupService.cancel(groupId); |
||||
return ResultUtils.success(); |
return ResultUtils.success(); |
||||
} |
} |
||||
|
|
||||
@ApiOperation(httpMethod = "POST", value = "离开视频通话") |
@Operation(summary = "离开视频通话") |
||||
@PostMapping("/quit") |
@PostMapping("/quit") |
||||
public Result quit(@RequestParam Long groupId) { |
public Result quit(@RequestParam("groupId") Long groupId) { |
||||
webrtcGroupService.quit(groupId); |
webrtcGroupService.quit(groupId); |
||||
return ResultUtils.success(); |
return ResultUtils.success(); |
||||
} |
} |
||||
|
|
||||
@ApiOperation(httpMethod = "POST", value = "推送offer信息") |
@Operation(summary = "推送offer信息") |
||||
@PostMapping("/offer") |
@PostMapping("/offer") |
||||
public Result offer(@Valid @RequestBody WebrtcGroupOfferDTO dto) { |
public Result offer(@Valid @RequestBody WebrtcGroupOfferDTO dto) { |
||||
webrtcGroupService.offer(dto); |
webrtcGroupService.offer(dto); |
||||
return ResultUtils.success(); |
return ResultUtils.success(); |
||||
} |
} |
||||
|
|
||||
@ApiOperation(httpMethod = "POST", value = "推送answer信息") |
@Operation(summary = "推送answer信息") |
||||
@PostMapping("/answer") |
@PostMapping("/answer") |
||||
public Result answer(@Valid @RequestBody WebrtcGroupAnswerDTO dto) { |
public Result answer(@Valid @RequestBody WebrtcGroupAnswerDTO dto) { |
||||
webrtcGroupService.answer(dto); |
webrtcGroupService.answer(dto); |
||||
return ResultUtils.success(); |
return ResultUtils.success(); |
||||
} |
} |
||||
|
|
||||
@ApiOperation(httpMethod = "POST", value = "邀请用户进入视频通话") |
@Operation(summary = "邀请用户进入视频通话") |
||||
@PostMapping("/invite") |
@PostMapping("/invite") |
||||
public Result invite(@Valid @RequestBody WebrtcGroupInviteDTO dto) { |
public Result invite(@Valid @RequestBody WebrtcGroupInviteDTO dto) { |
||||
webrtcGroupService.invite(dto); |
webrtcGroupService.invite(dto); |
||||
return ResultUtils.success(); |
return ResultUtils.success(); |
||||
} |
} |
||||
|
|
||||
@ApiOperation(httpMethod = "POST", value = "同步candidate") |
@Operation(summary = "同步candidate") |
||||
@PostMapping("/candidate") |
@PostMapping("/candidate") |
||||
public Result candidate(@Valid @RequestBody WebrtcGroupCandidateDTO dto) { |
public Result candidate(@Valid @RequestBody WebrtcGroupCandidateDTO dto) { |
||||
webrtcGroupService.candidate(dto); |
webrtcGroupService.candidate(dto); |
||||
return ResultUtils.success(); |
return ResultUtils.success(); |
||||
} |
} |
||||
|
|
||||
@ApiOperation(httpMethod = "POST", value = "设备操作") |
@Operation(summary = "设备操作") |
||||
@PostMapping("/device") |
@PostMapping("/device") |
||||
public Result device(@Valid @RequestBody WebrtcGroupDeviceDTO dto) { |
public Result device(@Valid @RequestBody WebrtcGroupDeviceDTO dto) { |
||||
webrtcGroupService.device(dto); |
webrtcGroupService.device(dto); |
||||
return ResultUtils.success(); |
return ResultUtils.success(); |
||||
} |
} |
||||
|
|
||||
@ApiOperation(httpMethod = "GET", value = "获取通话信息") |
@Operation(summary = "获取通话信息") |
||||
@GetMapping("/info") |
@GetMapping("/info") |
||||
public Result<WebrtcGroupInfoVO> info(@RequestParam Long groupId) { |
public Result<WebrtcGroupInfoVO> info(@RequestParam("groupId") Long groupId) { |
||||
return ResultUtils.success(webrtcGroupService.info(groupId)); |
return ResultUtils.success(webrtcGroupService.info(groupId)); |
||||
} |
} |
||||
|
|
||||
@ApiOperation(httpMethod = "POST", value = "获取通话信息") |
@Operation(summary = "获取通话信息") |
||||
@PostMapping("/heartbeat") |
@PostMapping("/heartbeat") |
||||
public Result heartbeat(@RequestParam Long groupId) { |
public Result heartbeat(@RequestParam("groupId") Long groupId) { |
||||
webrtcGroupService.heartbeat(groupId); |
webrtcGroupService.heartbeat(groupId); |
||||
return ResultUtils.success(); |
return ResultUtils.success(); |
||||
} |
} |
||||
|
|
||||
} |
} |
||||
|
|||||
@ -0,0 +1,21 @@ |
|||||
|
package com.bx.implatform.dto; |
||||
|
|
||||
|
|
||||
|
import io.swagger.v3.oas.annotations.media.Schema; |
||||
|
import lombok.Data; |
||||
|
|
||||
|
/** |
||||
|
* @author: Blue |
||||
|
* @date: 2024-07-14 |
||||
|
* @version: 1.0 |
||||
|
*/ |
||||
|
@Data |
||||
|
@Schema(description = "群组封禁") |
||||
|
public class GroupBanDTO { |
||||
|
|
||||
|
@Schema(description = "群组id") |
||||
|
private Long id; |
||||
|
|
||||
|
@Schema(description = "封禁原因") |
||||
|
private String reason; |
||||
|
} |
||||
@ -1,36 +1,35 @@ |
|||||
package com.bx.implatform.dto; |
package com.bx.implatform.dto; |
||||
|
|
||||
import io.swagger.annotations.ApiModel; |
import io.swagger.v3.oas.annotations.media.Schema; |
||||
import io.swagger.annotations.ApiModelProperty; |
import jakarta.validation.constraints.NotEmpty; |
||||
|
import jakarta.validation.constraints.NotNull; |
||||
|
import jakarta.validation.constraints.Size; |
||||
import lombok.Data; |
import lombok.Data; |
||||
import org.hibernate.validator.constraints.Length; |
import org.hibernate.validator.constraints.Length; |
||||
|
|
||||
import javax.validation.constraints.NotEmpty; |
|
||||
import javax.validation.constraints.NotNull; |
|
||||
import javax.validation.constraints.Size; |
|
||||
import java.util.List; |
import java.util.List; |
||||
|
|
||||
@Data |
@Data |
||||
@ApiModel("群聊消息DTO") |
@Schema(description = "群聊消息DTO") |
||||
public class GroupMessageDTO { |
public class GroupMessageDTO { |
||||
|
|
||||
@NotNull(message = "群聊id不可为空") |
@NotNull(message = "群聊id不可为空") |
||||
@ApiModelProperty(value = "群聊id") |
@Schema(description = "群聊id") |
||||
private Long groupId; |
private Long groupId; |
||||
|
|
||||
@Length(max = 1024, message = "发送内容长度不得大于1024") |
@Length(max = 1024, message = "发送内容长度不得大于1024") |
||||
@NotEmpty(message = "发送内容不可为空") |
@NotEmpty(message = "发送内容不可为空") |
||||
@ApiModelProperty(value = "发送内容") |
@Schema(description = "发送内容") |
||||
private String content; |
private String content; |
||||
|
|
||||
@NotNull(message = "消息类型不可为空") |
@NotNull(message = "消息类型不可为空") |
||||
@ApiModelProperty(value = "消息类型") |
@Schema(description = "消息类型 0:文字 1:图片 2:文件 3:语音 4:视频") |
||||
private Integer type; |
private Integer type; |
||||
|
|
||||
@ApiModelProperty(value = "是否回执消息") |
@Schema(description = "是否回执消息") |
||||
private Boolean receipt = false; |
private Boolean receipt = false; |
||||
|
|
||||
@Size(max = 20, message = "一次最多只能@20个小伙伴哦") |
@Size(max = 20, message = "一次最多只能@20个小伙伴哦") |
||||
@ApiModelProperty(value = "被@用户列表") |
@Schema(description = "被@用户列表") |
||||
private List<Long> atUserIds; |
private List<Long> atUserIds; |
||||
} |
} |
||||
|
|||||
@ -0,0 +1,18 @@ |
|||||
|
package com.bx.implatform.dto; |
||||
|
|
||||
|
import io.swagger.v3.oas.annotations.media.Schema; |
||||
|
import lombok.Data; |
||||
|
|
||||
|
/** |
||||
|
* @author: Blue |
||||
|
* @date: 2024-07-14 |
||||
|
* @version: 1.0 |
||||
|
*/ |
||||
|
@Data |
||||
|
@Schema(description = "群组解锁") |
||||
|
public class GroupUnbanDTO { |
||||
|
|
||||
|
@Schema(description = "群组id") |
||||
|
private Long id; |
||||
|
|
||||
|
} |
||||
@ -1,30 +1,28 @@ |
|||||
package com.bx.implatform.dto; |
package com.bx.implatform.dto; |
||||
|
|
||||
import io.swagger.annotations.ApiModel; |
import io.swagger.v3.oas.annotations.media.Schema; |
||||
import io.swagger.annotations.ApiModelProperty; |
import jakarta.validation.constraints.Max; |
||||
|
import jakarta.validation.constraints.Min; |
||||
|
import jakarta.validation.constraints.NotEmpty; |
||||
|
import jakarta.validation.constraints.NotNull; |
||||
import lombok.Data; |
import lombok.Data; |
||||
|
|
||||
import javax.validation.constraints.Max; |
|
||||
import javax.validation.constraints.Min; |
|
||||
import javax.validation.constraints.NotEmpty; |
|
||||
import javax.validation.constraints.NotNull; |
|
||||
|
|
||||
@Data |
@Data |
||||
@ApiModel("用户登录DTO") |
@Schema(description = "用户登录DTO") |
||||
public class LoginDTO { |
public class LoginDTO { |
||||
|
|
||||
@Max(value = 2, message = "登录终端类型取值范围:0,2") |
@Max(value = 2, message = "登录终端类型取值范围:0,2") |
||||
@Min(value = 0, message = "登录终端类型取值范围:0,2") |
@Min(value = 0, message = "登录终端类型取值范围:0,2") |
||||
@NotNull(message = "登录终端类型不可为空") |
@NotNull(message = "登录终端类型不可为空") |
||||
@ApiModelProperty(value = "登录终端 0:web 1:app 2:pc") |
@Schema(description = "登录终端 0:web 1:app 2:pc") |
||||
private Integer terminal; |
private Integer terminal; |
||||
|
|
||||
@NotEmpty(message = "用户名不可为空") |
@NotEmpty(message = "用户名不可为空") |
||||
@ApiModelProperty(value = "用户名") |
@Schema(description = "用户名") |
||||
private String userName; |
private String userName; |
||||
|
|
||||
@NotEmpty(message = "用户密码不可为空") |
@NotEmpty(message = "用户密码不可为空") |
||||
@ApiModelProperty(value = "用户密码") |
@Schema(description = "用户密码") |
||||
private String password; |
private String password; |
||||
|
|
||||
} |
} |
||||
|
|||||
@ -1,21 +1,19 @@ |
|||||
package com.bx.implatform.dto; |
package com.bx.implatform.dto; |
||||
|
|
||||
import io.swagger.annotations.ApiModel; |
import io.swagger.v3.oas.annotations.media.Schema; |
||||
import io.swagger.annotations.ApiModelProperty; |
import jakarta.validation.constraints.NotEmpty; |
||||
import lombok.Data; |
import lombok.Data; |
||||
|
|
||||
import javax.validation.constraints.NotEmpty; |
|
||||
|
|
||||
@Data |
@Data |
||||
@ApiModel("修改密码DTO") |
@Schema(description = "修改密码DTO") |
||||
public class ModifyPwdDTO { |
public class ModifyPwdDTO { |
||||
|
|
||||
@NotEmpty(message = "旧用户密码不可为空") |
@NotEmpty(message = "旧用户密码不可为空") |
||||
@ApiModelProperty(value = "旧用户密码") |
@Schema(description = "旧用户密码") |
||||
private String oldPassword; |
private String oldPassword; |
||||
|
|
||||
@NotEmpty(message = "新用户密码不可为空") |
@NotEmpty(message = "新用户密码不可为空") |
||||
@ApiModelProperty(value = "新用户密码") |
@Schema(description = "新用户密码") |
||||
private String newPassword; |
private String newPassword; |
||||
|
|
||||
} |
} |
||||
|
|||||
@ -1,29 +1,27 @@ |
|||||
package com.bx.implatform.dto; |
package com.bx.implatform.dto; |
||||
|
|
||||
import io.swagger.annotations.ApiModel; |
import io.swagger.v3.oas.annotations.media.Schema; |
||||
import io.swagger.annotations.ApiModelProperty; |
import jakarta.validation.constraints.NotEmpty; |
||||
|
import jakarta.validation.constraints.NotNull; |
||||
import lombok.Data; |
import lombok.Data; |
||||
import org.hibernate.validator.constraints.Length; |
import org.hibernate.validator.constraints.Length; |
||||
|
|
||||
import javax.validation.constraints.NotEmpty; |
|
||||
import javax.validation.constraints.NotNull; |
|
||||
|
|
||||
@Data |
@Data |
||||
@ApiModel("私聊消息DTO") |
@Schema(description = "私聊消息DTO") |
||||
public class PrivateMessageDTO { |
public class PrivateMessageDTO { |
||||
|
|
||||
@NotNull(message = "接收用户id不可为空") |
@NotNull(message = "接收用户id不可为空") |
||||
@ApiModelProperty(value = "接收用户id") |
@Schema(description = "接收用户id") |
||||
private Long recvId; |
private Long recvId; |
||||
|
|
||||
|
|
||||
@Length(max = 1024, message = "内容长度不得大于1024") |
@Length(max = 1024, message = "内容长度不得大于1024") |
||||
@NotEmpty(message = "发送内容不可为空") |
@NotEmpty(message = "发送内容不可为空") |
||||
@ApiModelProperty(value = "发送内容") |
@Schema(description = "发送内容") |
||||
private String content; |
private String content; |
||||
|
|
||||
@NotNull(message = "消息类型不可为空") |
@NotNull(message = "消息类型不可为空") |
||||
@ApiModelProperty(value = "消息类型") |
@Schema(description = "消息类型 0:文字 1:图片 2:文件 3:语音 4:视频") |
||||
private Integer type; |
private Integer type; |
||||
|
|
||||
} |
} |
||||
|
|||||
@ -0,0 +1,21 @@ |
|||||
|
package com.bx.implatform.dto; |
||||
|
|
||||
|
import io.swagger.v3.oas.annotations.media.Schema; |
||||
|
import lombok.Data; |
||||
|
|
||||
|
/** |
||||
|
* @author: Blue |
||||
|
* @date: 2024-07-14 |
||||
|
* @version: 1.0 |
||||
|
*/ |
||||
|
@Data |
||||
|
@Schema(description = "用户锁定DTO") |
||||
|
public class UserBanDTO { |
||||
|
|
||||
|
@Schema(description = "用户id") |
||||
|
private Long id; |
||||
|
|
||||
|
@Schema(description = "锁定原因") |
||||
|
private String reason; |
||||
|
|
||||
|
} |
||||
@ -1,31 +1,29 @@ |
|||||
package com.bx.implatform.dto; |
package com.bx.implatform.dto; |
||||
|
|
||||
import io.swagger.annotations.ApiModel; |
import io.swagger.v3.oas.annotations.media.Schema; |
||||
import io.swagger.annotations.ApiModelProperty; |
import jakarta.validation.constraints.NotEmpty; |
||||
|
import jakarta.validation.constraints.NotNull; |
||||
import lombok.Data; |
import lombok.Data; |
||||
|
|
||||
import javax.validation.constraints.NotEmpty; |
|
||||
import javax.validation.constraints.NotNull; |
|
||||
|
|
||||
/** |
/** |
||||
* @author: Blue |
* @author: Blue |
||||
* @date: 2024-06-01 |
* @date: 2024-06-01 |
||||
* @version: 1.0 |
* @version: 1.0 |
||||
*/ |
*/ |
||||
@Data |
@Data |
||||
@ApiModel("回复用户连接请求DTO") |
@Schema(description = "回复用户连接请求DTO") |
||||
public class WebrtcGroupAnswerDTO { |
public class WebrtcGroupAnswerDTO { |
||||
|
|
||||
@NotNull(message = "群聊id不可为空") |
@NotNull(message = "群聊id不可为空") |
||||
@ApiModelProperty(value = "群聊id") |
@Schema(description = "群聊id") |
||||
private Long groupId; |
private Long groupId; |
||||
|
|
||||
@NotNull(message = "用户id不可为空") |
@NotNull(message = "用户id不可为空") |
||||
@ApiModelProperty(value = "用户id,代表回复谁的连接请求") |
@Schema(description = "用户id,代表回复谁的连接请求") |
||||
private Long userId; |
private Long userId; |
||||
|
|
||||
@NotEmpty(message = "anwer不可为空") |
@NotEmpty(message = "anwer不可为空") |
||||
@ApiModelProperty(value = "用户本地anwer信息") |
@Schema(description = "用户本地anwer信息") |
||||
private String answer; |
private String answer; |
||||
|
|
||||
} |
} |
||||
|
|||||
@ -1,32 +1,29 @@ |
|||||
package com.bx.implatform.dto; |
package com.bx.implatform.dto; |
||||
|
|
||||
import io.swagger.annotations.ApiModel; |
import io.swagger.v3.oas.annotations.media.Schema; |
||||
import io.swagger.annotations.ApiModelProperty; |
import jakarta.validation.constraints.NotEmpty; |
||||
|
import jakarta.validation.constraints.NotNull; |
||||
import lombok.Data; |
import lombok.Data; |
||||
|
|
||||
import javax.validation.constraints.NotEmpty; |
|
||||
import javax.validation.constraints.NotNull; |
|
||||
import java.util.List; |
|
||||
|
|
||||
/** |
/** |
||||
* @author: Blue |
* @author: Blue |
||||
* @date: 2024-06-01 |
* @date: 2024-06-01 |
||||
* @version: 1.0 |
* @version: 1.0 |
||||
*/ |
*/ |
||||
@Data |
@Data |
||||
@ApiModel("发起群视频通话DTO") |
@Schema(description = "发起群视频通话DTO") |
||||
public class WebrtcGroupCandidateDTO { |
public class WebrtcGroupCandidateDTO { |
||||
|
|
||||
@NotNull(message = "群聊id不可为空") |
@NotNull(message = "群聊id不可为空") |
||||
@ApiModelProperty(value = "群聊id") |
@Schema(description = "群聊id") |
||||
private Long groupId; |
private Long groupId; |
||||
|
|
||||
@NotNull(message = "用户id不可为空") |
@NotNull(message = "用户id不可为空") |
||||
@ApiModelProperty(value = "用户id") |
@Schema(description = "用户id") |
||||
private Long userId; |
private Long userId; |
||||
|
|
||||
@NotEmpty(message = "candidate信息不可为空") |
@NotEmpty(message = "candidate信息不可为空") |
||||
@ApiModelProperty(value = "candidate信息") |
@Schema(description = "candidate信息") |
||||
private String candidate; |
private String candidate; |
||||
|
|
||||
} |
} |
||||
|
|||||
@ -1,29 +1,26 @@ |
|||||
package com.bx.implatform.dto; |
package com.bx.implatform.dto; |
||||
|
|
||||
import io.swagger.annotations.ApiModel; |
import io.swagger.v3.oas.annotations.media.Schema; |
||||
import io.swagger.annotations.ApiModelProperty; |
import jakarta.validation.constraints.NotNull; |
||||
import lombok.Data; |
import lombok.Data; |
||||
|
|
||||
import javax.validation.constraints.NotEmpty; |
|
||||
import javax.validation.constraints.NotNull; |
|
||||
|
|
||||
/** |
/** |
||||
* @author: Blue |
* @author: Blue |
||||
* @date: 2024-06-01 |
* @date: 2024-06-01 |
||||
* @version: 1.0 |
* @version: 1.0 |
||||
*/ |
*/ |
||||
@Data |
@Data |
||||
@ApiModel("用户设备操作DTO") |
@Schema(description = "用户设备操作DTO") |
||||
public class WebrtcGroupDeviceDTO { |
public class WebrtcGroupDeviceDTO { |
||||
|
|
||||
@NotNull(message = "群聊id不可为空") |
@NotNull(message = "群聊id不可为空") |
||||
@ApiModelProperty(value = "群聊id") |
@Schema(description = "群聊id") |
||||
private Long groupId; |
private Long groupId; |
||||
|
|
||||
@ApiModelProperty(value = "是否开启摄像头") |
@Schema(description = "是否开启摄像头") |
||||
private Boolean isCamera; |
private Boolean isCamera; |
||||
|
|
||||
@ApiModelProperty(value = "是否开启麦克风") |
@Schema(description = "是否开启麦克风") |
||||
private Boolean isMicroPhone; |
private Boolean isMicroPhone; |
||||
|
|
||||
} |
} |
||||
|
|||||
@ -1,25 +1,23 @@ |
|||||
package com.bx.implatform.dto; |
package com.bx.implatform.dto; |
||||
|
|
||||
import io.swagger.annotations.ApiModel; |
import io.swagger.v3.oas.annotations.media.Schema; |
||||
import io.swagger.annotations.ApiModelProperty; |
import jakarta.validation.constraints.NotNull; |
||||
import lombok.Data; |
import lombok.Data; |
||||
|
|
||||
import javax.validation.constraints.NotNull; |
|
||||
|
|
||||
/** |
/** |
||||
* @author: Blue |
* @author: Blue |
||||
* @date: 2024-06-01 |
* @date: 2024-06-01 |
||||
* @version: 1.0 |
* @version: 1.0 |
||||
*/ |
*/ |
||||
@Data |
@Data |
||||
@ApiModel("用户通话失败DTO") |
@Schema(description = "用户通话失败DTO") |
||||
public class WebrtcGroupFailedDTO { |
public class WebrtcGroupFailedDTO { |
||||
|
|
||||
@NotNull(message = "群聊id不可为空") |
@NotNull(message = "群聊id不可为空") |
||||
@ApiModelProperty(value = "群聊id") |
@Schema(description = "群聊id") |
||||
private Long groupId; |
private Long groupId; |
||||
|
|
||||
@ApiModelProperty(value = "失败原因") |
@Schema(description = "失败原因") |
||||
private String reason; |
private String reason; |
||||
|
|
||||
} |
} |
||||
|
|||||
@ -1,23 +1,20 @@ |
|||||
package com.bx.implatform.dto; |
package com.bx.implatform.dto; |
||||
|
|
||||
import io.swagger.annotations.ApiModel; |
import io.swagger.v3.oas.annotations.media.Schema; |
||||
import io.swagger.annotations.ApiModelProperty; |
import jakarta.validation.constraints.NotNull; |
||||
import lombok.Data; |
import lombok.Data; |
||||
|
|
||||
import javax.validation.constraints.NotEmpty; |
|
||||
import javax.validation.constraints.NotNull; |
|
||||
|
|
||||
/** |
/** |
||||
* @author: Blue |
* @author: Blue |
||||
* @date: 2024-06-01 |
* @date: 2024-06-01 |
||||
* @version: 1.0 |
* @version: 1.0 |
||||
*/ |
*/ |
||||
@Data |
@Data |
||||
@ApiModel("进入群视频通话DTO") |
@Schema(description = "进入群视频通话DTO") |
||||
public class WebrtcGroupJoinDTO { |
public class WebrtcGroupJoinDTO { |
||||
|
|
||||
@NotNull(message = "群聊id不可为空") |
@NotNull(message = "群聊id不可为空") |
||||
@ApiModelProperty(value = "群聊id") |
@Schema(description = "群聊id") |
||||
private Long groupId; |
private Long groupId; |
||||
|
|
||||
} |
} |
||||
|
|||||
@ -1,31 +1,29 @@ |
|||||
package com.bx.implatform.dto; |
package com.bx.implatform.dto; |
||||
|
|
||||
import io.swagger.annotations.ApiModel; |
import io.swagger.v3.oas.annotations.media.Schema; |
||||
import io.swagger.annotations.ApiModelProperty; |
import jakarta.validation.constraints.NotEmpty; |
||||
|
import jakarta.validation.constraints.NotNull; |
||||
import lombok.Data; |
import lombok.Data; |
||||
|
|
||||
import javax.validation.constraints.NotEmpty; |
|
||||
import javax.validation.constraints.NotNull; |
|
||||
|
|
||||
/** |
/** |
||||
* @author: Blue |
* @author: Blue |
||||
* @date: 2024-06-01 |
* @date: 2024-06-01 |
||||
* @version: 1.0 |
* @version: 1.0 |
||||
*/ |
*/ |
||||
@Data |
@Data |
||||
@ApiModel("回复用户连接请求DTO") |
@Schema(description = "回复用户连接请求DTO") |
||||
public class WebrtcGroupOfferDTO { |
public class WebrtcGroupOfferDTO { |
||||
|
|
||||
@NotNull(message = "群聊id不可为空") |
@NotNull(message = "群聊id不可为空") |
||||
@ApiModelProperty(value = "群聊id") |
@Schema(description = "群聊id") |
||||
private Long groupId; |
private Long groupId; |
||||
|
|
||||
@NotNull(message = "用户id不可为空") |
@NotNull(message = "用户id不可为空") |
||||
@ApiModelProperty(value = "用户id,代表回复谁的连接请求") |
@Schema(description = "用户id,代表回复谁的连接请求") |
||||
private Long userId; |
private Long userId; |
||||
|
|
||||
@NotEmpty(message = "offer不可为空") |
@NotEmpty(message = "offer不可为空") |
||||
@ApiModelProperty(value = "用户offer信息") |
@Schema(description = "用户offer信息") |
||||
private String offer; |
private String offer; |
||||
|
|
||||
} |
} |
||||
|
|||||
@ -0,0 +1,50 @@ |
|||||
|
package com.bx.implatform.entity; |
||||
|
|
||||
|
import com.baomidou.mybatisplus.annotation.FieldFill; |
||||
|
import com.baomidou.mybatisplus.annotation.TableField; |
||||
|
import com.baomidou.mybatisplus.annotation.TableId; |
||||
|
import com.baomidou.mybatisplus.annotation.TableName; |
||||
|
import lombok.Data; |
||||
|
|
||||
|
import java.time.LocalDateTime; |
||||
|
|
||||
|
/** |
||||
|
* 敏感词 |
||||
|
* |
||||
|
* @author Blue |
||||
|
* @since 1.0.0 2024-07-20 |
||||
|
*/ |
||||
|
|
||||
|
@Data |
||||
|
@TableName("im_sensitive_word") |
||||
|
public class SensitiveWord { |
||||
|
/** |
||||
|
* id |
||||
|
*/ |
||||
|
@TableId |
||||
|
private Long id; |
||||
|
|
||||
|
/** |
||||
|
* 敏感词内容 |
||||
|
*/ |
||||
|
private String content; |
||||
|
|
||||
|
/** |
||||
|
* 是否启用 |
||||
|
*/ |
||||
|
private Boolean enabled; |
||||
|
|
||||
|
/** |
||||
|
* 创建者 |
||||
|
*/ |
||||
|
@TableField(fill = FieldFill.INSERT) |
||||
|
private Long creator; |
||||
|
|
||||
|
/** |
||||
|
* 创建时间 |
||||
|
*/ |
||||
|
@TableField(fill = FieldFill.INSERT) |
||||
|
private LocalDateTime createTime; |
||||
|
|
||||
|
|
||||
|
} |
||||
@ -1,102 +0,0 @@ |
|||||
package com.bx.implatform.generator; |
|
||||
|
|
||||
import com.baomidou.mybatisplus.annotation.IdType; |
|
||||
import com.baomidou.mybatisplus.core.toolkit.StringPool; |
|
||||
import com.baomidou.mybatisplus.generator.AutoGenerator; |
|
||||
import com.baomidou.mybatisplus.generator.InjectionConfig; |
|
||||
import com.baomidou.mybatisplus.generator.config.*; |
|
||||
import com.baomidou.mybatisplus.generator.config.po.TableInfo; |
|
||||
import com.baomidou.mybatisplus.generator.config.rules.DateType; |
|
||||
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy; |
|
||||
import com.baomidou.mybatisplus.generator.engine.VelocityTemplateEngine; |
|
||||
|
|
||||
import java.util.ArrayList; |
|
||||
import java.util.List; |
|
||||
|
|
||||
|
|
||||
public class CodeGenerator { |
|
||||
public static void main(String[] args) { |
|
||||
// 代码生成器
|
|
||||
AutoGenerator mpg = new AutoGenerator(); |
|
||||
|
|
||||
// 全局配置
|
|
||||
GlobalConfig gc = new GlobalConfig(); |
|
||||
//生成的代码输出路径,自己根据需要修改
|
|
||||
String projectPath = "d:\\work\\project\\code"; |
|
||||
gc.setOutputDir(projectPath + "/src/main/java"); |
|
||||
gc.setAuthor("blue"); |
|
||||
gc.setOpen(false); |
|
||||
gc.setFileOverride(true); |
|
||||
gc.setActiveRecord(true); |
|
||||
gc.setBaseColumnList(true); |
|
||||
gc.setBaseResultMap(true); |
|
||||
gc.setIdType(IdType.AUTO); |
|
||||
gc.setDateType(DateType.ONLY_DATE); |
|
||||
mpg.setGlobalConfig(gc); |
|
||||
|
|
||||
// 数据源配置
|
|
||||
DataSourceConfig dsc = new DataSourceConfig(); |
|
||||
dsc.setUrl("jdbc:mysql://localhost:3306/box-im?useUnicode=true&characterEncoding=utf-8"); |
|
||||
dsc.setDriverName("com.mysql.jdbc.Driver"); |
|
||||
dsc.setUsername("root"); |
|
||||
dsc.setPassword("root"); |
|
||||
mpg.setDataSource(dsc); |
|
||||
|
|
||||
// 包配置
|
|
||||
PackageConfig pc = new PackageConfig(); |
|
||||
pc.setModuleName(""); |
|
||||
pc.setParent("com.bx"); |
|
||||
mpg.setPackageInfo(pc); |
|
||||
|
|
||||
// 如果模板引擎是 velocity
|
|
||||
String templatePath = "/templates/mapper.xml.vm"; |
|
||||
|
|
||||
// 自定义输出配置
|
|
||||
List<FileOutConfig> focList = new ArrayList<>(); |
|
||||
// 自定义配置会被优先输出
|
|
||||
focList.add(new FileOutConfig(templatePath) { |
|
||||
@Override |
|
||||
public String outputFile(TableInfo tableInfo) { |
|
||||
// 自定义输出文件名 , 如果你 Entity 设置了前后缀、此处注意 xml 的名称会跟着发生变化!!
|
|
||||
return projectPath + "/src/main/resources/mapper/" |
|
||||
+ tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML; |
|
||||
} |
|
||||
}); |
|
||||
|
|
||||
// 自定义配置
|
|
||||
InjectionConfig cfg = new InjectionConfig() { |
|
||||
@Override |
|
||||
public void initMap() { |
|
||||
// to do nothing
|
|
||||
} |
|
||||
}; |
|
||||
cfg.setFileOutConfigList(focList); |
|
||||
mpg.setCfg(cfg); |
|
||||
|
|
||||
// 配置模板
|
|
||||
TemplateConfig templateConfig = new TemplateConfig(); |
|
||||
templateConfig.setXml(null); |
|
||||
mpg.setTemplate(templateConfig); |
|
||||
|
|
||||
// 策略配置
|
|
||||
StrategyConfig strategy = new StrategyConfig(); |
|
||||
// 下划线转驼峰
|
|
||||
strategy.setNaming(NamingStrategy.underline_to_camel); |
|
||||
strategy.setColumnNaming(NamingStrategy.underline_to_camel); |
|
||||
strategy.setEntityTableFieldAnnotationEnable(true); |
|
||||
strategy.setVersionFieldName("version"); |
|
||||
//逻辑删除的字段
|
|
||||
strategy.setLogicDeleteFieldName("deleted"); |
|
||||
strategy.setEntityLombokModel(true); |
|
||||
strategy.setRestControllerStyle(true); |
|
||||
|
|
||||
|
|
||||
//多张表的时候直接在代码中写表名
|
|
||||
strategy.setInclude("friends"); |
|
||||
strategy.setTablePrefix(""); |
|
||||
mpg.setStrategy(strategy); |
|
||||
|
|
||||
mpg.setTemplateEngine(new VelocityTemplateEngine()); |
|
||||
mpg.execute(); |
|
||||
} |
|
||||
} |
|
||||
@ -0,0 +1,26 @@ |
|||||
|
package com.bx.implatform.listener; |
||||
|
|
||||
|
import com.bx.imclient.annotation.IMListener; |
||||
|
import com.bx.imclient.listener.MessageListener; |
||||
|
import com.bx.imcommon.enums.IMListenerType; |
||||
|
import com.bx.imcommon.enums.IMSendCode; |
||||
|
import com.bx.imcommon.model.IMSendResult; |
||||
|
import com.bx.implatform.vo.SystemMessageVO; |
||||
|
import lombok.extern.slf4j.Slf4j; |
||||
|
|
||||
|
import java.util.List; |
||||
|
|
||||
|
@Slf4j |
||||
|
@IMListener(type = IMListenerType.SYSTEM_MESSAGE) |
||||
|
public class SystemMessageListener implements MessageListener<SystemMessageVO> { |
||||
|
|
||||
|
@Override |
||||
|
public void process(List<IMSendResult<SystemMessageVO>> results) { |
||||
|
for(IMSendResult<SystemMessageVO> result : results){ |
||||
|
SystemMessageVO messageInfo = result.getData(); |
||||
|
if (result.getCode().equals(IMSendCode.SUCCESS.code())) { |
||||
|
log.info("消息送达,消息id:{},接收者:{},终端:{}", messageInfo.getId(), result.getReceiver().getId(), result.getReceiver().getTerminal()); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,16 @@ |
|||||
|
package com.bx.implatform.mapper; |
||||
|
|
||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
||||
|
import com.bx.implatform.entity.SensitiveWord; |
||||
|
import org.apache.ibatis.annotations.Mapper; |
||||
|
|
||||
|
/** |
||||
|
* 敏感词 |
||||
|
* |
||||
|
* @author Blue |
||||
|
* @since 1.0.0 2024-07-20 |
||||
|
*/ |
||||
|
@Mapper |
||||
|
public interface SensitiveWordMapper extends BaseMapper<SensitiveWord> { |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,22 @@ |
|||||
|
package com.bx.implatform.service; |
||||
|
|
||||
|
import com.baomidou.mybatisplus.extension.service.IService; |
||||
|
import com.bx.implatform.dto.LoginDTO; |
||||
|
import com.bx.implatform.dto.ModifyPwdDTO; |
||||
|
import com.bx.implatform.dto.RegisterDTO; |
||||
|
import com.bx.implatform.entity.SensitiveWord; |
||||
|
import com.bx.implatform.entity.User; |
||||
|
import com.bx.implatform.vo.LoginVO; |
||||
|
import com.bx.implatform.vo.OnlineTerminalVO; |
||||
|
import com.bx.implatform.vo.UserVO; |
||||
|
|
||||
|
import java.util.List; |
||||
|
|
||||
|
public interface SensitiveWordService extends IService<SensitiveWord> { |
||||
|
|
||||
|
/** |
||||
|
* 查询所有开启的敏感词 |
||||
|
* @return |
||||
|
*/ |
||||
|
List<String> findAllEnabledWords(); |
||||
|
} |
||||
@ -1,10 +1,9 @@ |
|||||
package com.bx.implatform.service; |
package com.bx.implatform.service; |
||||
|
|
||||
import com.bx.implatform.config.WebrtcConfig; |
|
||||
import com.bx.implatform.dto.*; |
import com.bx.implatform.dto.*; |
||||
import com.bx.implatform.vo.WebrtcGroupInfoVO; |
import com.bx.implatform.vo.WebrtcGroupInfoVO; |
||||
|
|
||||
public interface IWebrtcGroupService { |
public interface WebrtcGroupService { |
||||
|
|
||||
/** |
/** |
||||
* 发起通话 |
* 发起通话 |
||||
@ -1,15 +1,11 @@ |
|||||
package com.bx.implatform.service; |
package com.bx.implatform.service; |
||||
|
|
||||
import com.bx.implatform.config.ICEServer; |
|
||||
|
|
||||
import java.util.List; |
|
||||
|
|
||||
/** |
/** |
||||
* webrtc 通信服务 |
* webrtc 通信服务 |
||||
* |
* |
||||
* @author |
* @author |
||||
*/ |
*/ |
||||
public interface IWebrtcPrivateService { |
public interface WebrtcPrivateService { |
||||
|
|
||||
void call(Long uid, String mode,String offer); |
void call(Long uid, String mode,String offer); |
||||
|
|
||||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue