Commit 0f67fbc0 by Shadow

1、重新调整项目结构

parent 58f4290c

Too many changes to show.

To preserve performance only 1000 of 1000+ files are displayed.

# bootstrap 项目启动模块
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>io.geekidea.springbootplus</groupId>
<artifactId>parent</artifactId>
<version>2.0</version>
</parent>
<artifactId>bootstrap</artifactId>
<name>bootstrap</name>
<description>项目启动模块</description>
<properties>
<spring-boot.version>2.2.5.RELEASE</spring-boot.version>
</properties>
<dependencies>
<dependency>
<groupId>net.logstash.logback</groupId>
<artifactId>logstash-logback-encoder</artifactId>
<version>5.3</version>
</dependency>
<dependency>
<groupId>com.internetitem</groupId>
<artifactId>logback-elasticsearch-appender</artifactId>
<version>1.6</version>
</dependency>
<dependency>
<groupId>io.geekidea.springbootplus</groupId>
<artifactId>framework</artifactId>
</dependency>
<dependency>
<groupId>io.geekidea.springbootplus</groupId>
<artifactId>core</artifactId>
</dependency>
<dependency>
<groupId>io.geekidea.springbootplus</groupId>
<artifactId>scheduled</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<distributionManagement>
<repository>
<id>wecloud</id>
<url>http://124.71.68.175:8081/repository/maven-releases/</url>
</repository>
<snapshotRepository>
<id>wecloud</id>
<url>http://124.71.68.175:8081/repository/maven-snapshots/</url>
</snapshotRepository>
</distributionManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot.version}</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>com.wecloud</groupId>
<artifactId>classencrypt-maven-plugin</artifactId>
<version>${maven-classencrypt-plugin.version}</version>
<configuration>
<!-- 参数说明-->
<!-- -packages 加密的包名(可为空,多个用","分割)-->
<!-- -libjars jar/war包lib下要加密jar文件名(可为空,多个用","分割)-->
<!-- -cfgfiles 需要加密的配置文件,一般是classes目录下的yml或properties文件(可为空,多个用","分割)-->
<!-- -excludes 排除的类名(可为空,多个用","分割)-->
<!-- -classpath 外部依赖的jar目录,例如/tomcat/lib(可为空,多个用","分割)-->
<!-- -password 加密密码,如果是#号,则使用无密码模式加密-->
<!-- -code 机器码,在绑定的机器生成,加密后只可在此机器上运行-->
<password>wecloud#0-0</password><!--加密打包之后pom.xml会被删除,不用担心在jar包里找到此密码-->
<packages>com.wecloud,io.geekidea</packages>
<!-- <cfgfiles>application.yml</cfgfiles>-->
<!-- <excludes>io.geekidea</excludes>-->
<!-- <libjars>a.jar,b.jar</libjars> 多个之间用,分割-->
<!-- 机器绑定-->
<!-- 机器绑定只允许加密的项目在特定的机器上运行;-->
<!-- 在需要绑定的机器上执行以下命令,生成机器码-->
<!-- 在cmd目录下,执行 java -jar classencrypt-fatjar.jar -C-->
<!-- 例如我本机是: 4B1ABEBA8423DEE07469C1E38B3CF7881BBAC2F6C072365DF2297D84370991CC97E8330B0E5FB4ADFF0F87A038F4773A-->
<!-- <code>4B1ABEBA8423DEE07469C1E38B3CF7881BBAC2F6C072365DF2297D84370991CC97E8330B0E5FB4ADFF0F87A038F4773A</code>-->
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>classEncrypt</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
package io.geekidea.springbootplus.test;
import cn.hutool.core.codec.Base64;
import org.junit.Test;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
/**
* 读取系统文件目录 生成apns字符串
*/
public class ApnsTest {
@Test
public void test() throws Exception {
File file = new File("/Users/giaogiao/Library/Containers/com.tencent.xinWeChat/Data/Library/Application Support/com.tencent.xinWeChat/2.0b4.0.9/f31cd9e6d7da1d15c57c40575f5c85db/Message/MessageTemp/e1180914825140f051a87348bda5cbb5/File/hipro_test_push.p12");
InputStream certificate = new FileInputStream(file);
String encode = Base64.encode(certificate);
}
}
package io.geekidea.springbootplus.test;
import com.wecloud.im.router.RouterSendService;
import com.wecloud.im.ws.model.WsResponse;
import com.wecloud.utils.JsonUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.rpc.RpcContext;
import org.apache.dubbo.rpc.cluster.router.address.Address;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
* dubbo指定ip调用测试类
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
public class DubboRpcTest {
/*
* 解决log日志依赖冲突问题
*/
static {
System.setProperty("nacos.logging.default.config.enabled", "false");
}
/*
* 指定ip调用,router=address;
* injvm = false要设置成false,否则会调用到本地提供者
*/
@DubboReference(injvm = false, interfaceClass = RouterSendService.class, parameters = {"router", "address"})
private RouterSendService routerSendService;
@Test
public void test() {
int i = 0;
WsResponse wsResponse = new WsResponse();
wsResponse.setCmd(i);
wsResponse.setCode(200);
wsResponse.setMsg("i=" + i);
wsResponse.setData("hihi");
wsResponse.setReqId("123");
String msgJson = JsonUtils.encodeJson(wsResponse);
// 根据provider的ip,port创建Address实例
Address address = new Address("192.168.1.51", 20881);
RpcContext.getContext().setObjectAttachment("address", address);
routerSendService.sendMsgRemote(123L, 1, msgJson);
}
}
package io.geekidea.springbootplus.test;
import lombok.extern.slf4j.Slf4j;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
@Slf4j
public class FirebaseTest {
public static void main(String[] args) {
for (int i = 0; i < 1; i++) {
extracted();
}
}
private static void extracted() {
// System.set
// SOCKS 代理,支持 HTTP 和 HTTPS 请求
// 注意:如果设置了 SOCKS 代理就不要设 HTTP/HTTPS 代理
System.setProperty("socksProxyHost", "127.0.0.1");
System.setProperty("socksProxyPort", "7891");
// String to = "ck_oO93kR42WlkmzBVjzcA:APA91bGTcXlFq9_AOvGOJSIB4Z38EOqhP3_6HQ18_XIn3othxSWTeRr_IaQn-75AB9FvD5CiTig03Y56VtZDEEihismai0OOMPyxB7R4ajaFrQszEQRbCBw3iUgaAyjK7e1RFeq22tRC";
// String to = "eLOQs869208Wq5_tQINUgl:APA91bEsiSt8_RBJYQ2bLDHJF4nuE6XS6bP-kdEAt463SpW2i0Q5wUcmma3ylszr698MUIkjkwV507EV7ao347pl0XwHTDgDM1kIL4WYfX28OznML2lefnYS7oMmlt5_uqvwDO1GWone";
String to = "cu7jc8tgd0Irh7VoMXGNz4:APA91bFnOP39EKSXUaTDqERlqyfLIovLPrGXA_U1pKLs5mJRPfbLPl6BvSlLUwsBAtprE0NoEeIiRwkTwN4RskUgh39IKSqcSJ14yXtEDIGMs8HqzaF4HrQqJ_zFFUX6S0r6WenUru_8";
String key = "AAAA7PNYwIg:APA91bG2PZlTpC9sxqeIxtKDJJGzGZlh1ca13_bR4c5qkv9pEvRxcDfgO8VQqV2g-7cCTZz3oDtpWAgcQ5TyMKGdlD7Zp3bEmFkpNYDJAIcshSbyW-BtjCbknT2R5px5THmEJrlTJuDi";
String jsonStr = null;
try {
URL url = new URL("https://fcm.googleapis.com/fcm/send");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setUseCaches(false);
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setConnectTimeout(10000);
conn.setRequestMethod("POST");
//不设置默认发送文本格式。设置就是json
conn.setRequestProperty("Content-Type", "application/json");
conn.setRequestProperty("Authorization", "key=" + key);
JSONObject json = new JSONObject();
//推送到哪台客户端机器
json.put("to", to);
JSONObject info = new JSONObject();
info.put("title", "33新消息11");
info.put("body", "点击查看");
//数据消息data 通知消息 notification
json.put("notification", info);
OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
jsonStr = json.toString();
wr.write(jsonStr);
wr.flush();
InputStream inputStream = conn.getInputStream();
InputStreamReader in = new InputStreamReader(inputStream);
BufferedReader reader = new BufferedReader(in);
String line = reader.readLine();
log.info(line);
wr.close();
reader.close();
} catch (Exception e) {
log.error("FCM push failure: " + jsonStr, e);
}
}
}
/*
* Copyright 2019-2029 geekidea(https://github.com/geekidea)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.geekidea.springbootplus.test;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.NamingFactory;
import com.alibaba.nacos.api.naming.NamingService;
import com.alibaba.nacos.api.naming.pojo.Instance;
import com.wecloud.utils.GetIpUtils;
import io.geekidea.springbootplus.SpringBootPlusApplication;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.Map;
/**
* 获取一个健康实例的ip
**/
@RunWith(SpringRunner.class)
@SpringBootTest(classes = SpringBootPlusApplication.class)
public class GetIpTest {
@Autowired
private GetIpUtils publicIpUtils;
@Value("${spring.cloud.nacos.discovery.server-addr}")
private String addr;
@Test
public void test() throws NacosException {
// String s = publicIpUtils.getlanIp();
// String publicIp = publicIpUtils.getPublicIp();
// String s2 = publicIpUtils.getlanIp();
// String publicIp2 = publicIpUtils.getPublicIp();
// String serveAddr = System.getProperty("serveAddr");
NamingService naming = NamingFactory.createNamingService(addr);
Instance wecloudIm = naming.selectOneHealthyInstance("wecloud_im");
Map<String, String> metadata = wecloudIm.getMetadata();
String publicIp = metadata.get("ip.netty.public");
System.out.println(wecloudIm);
System.out.println("publicIp:" + publicIp);
// naming.subscribe("ip.netty.public", event -> {
// if (event instanceof NamingEvent) {
// System.out.println(((NamingEvent) event).getServiceName());
// System.out.println(((NamingEvent) event).getInstances());
// }
// });
// while (true){
//
// }
}
}
package io.geekidea.springbootplus.test;
import com.wecloud.utils.SnowflakeUtil;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
* Id生成 单元测试
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
public class IdTest {
@Test
public void test() {
Long id = SnowflakeUtil.getId();
}
}
package io.geekidea.springbootplus.test;
import cn.hutool.core.lang.Snowflake;
import com.wecloud.im.entity.ImApplication;
import com.wecloud.im.service.ImApplicationService;
import com.wecloud.im.service.ImConversationMembersService;
import com.wecloud.im.ws.utils.KeyGenerator;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import java.util.Date;
/**
* 生成测试appkey与appSecret对,并存入数据库
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
public class ImApplicationTest {
@Autowired
private ImConversationMembersService imConversationMembersService;
@Autowired
private ImApplicationService imApplicationService;
public static void main(String[] args) {
String appKey = KeyGenerator.getRandomString(); //定义变量接收
String appSecret = KeyGenerator.getAppSecret();
int i = 1;
System.out.println(appKey);
System.out.println(appSecret);
}
@Test
public void add() {
for (int i = 0; i < 10; i++) {
addDb(i);
}
}
private void addDb( int i) {
// 生成AppKey
String appKey = KeyGenerator.getRandomString(); //定义变量接收
// 生成appSecret
String appSecret = KeyGenerator.getAppSecret();
ImApplication imApplication = new ImApplication();
imApplication.setCreateTime(new Date());
imApplication.setUpdateTime(new Date());
imApplication.setId(new Snowflake(1L, 1L).nextId());
imApplication.setAppKey(appKey);
imApplication.setAppSecret(appSecret);
imApplication.setAppName("test" + i);
imApplicationService.save(imApplication);
}
}
package io.geekidea.springbootplus.test;
import com.wecloud.im.entity.ImConversation;
import com.wecloud.im.entity.ImConversationMembers;
import com.wecloud.im.service.ImConversationMembersService;
import com.wecloud.im.service.ImConversationService;
import com.wecloud.utils.SnowflakeUtil;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import java.util.Date;
/**
* imConversation 单元测试
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
public class ImConversationMembersTest {
@Autowired
private ImConversationMembersService imConversationMembersService;
@Autowired
private ImConversationService imConversationService;
@Test
public void addConversation() {
long creator = 1390920735408656384L;
long user2 = 1390921236443435008L;
long appid = 1387022761016299520L;
Long imConversationId = SnowflakeUtil.getId();
// 创建会话
ImConversation imConversation = new ImConversation();
imConversation.setId(imConversationId);
imConversation.setCreateTime(new Date());
imConversation.setLastMessage(null);
imConversation.setFkAppid(appid);
imConversation.setCreator(creator);
imConversation.setName("");
imConversation.setAttributes("");
imConversation.setSystemFlag(false);
imConversationService.save(imConversation);
// 将自己添加到会话
Long imConversationMembersId = SnowflakeUtil.getId();
ImConversationMembers imConversationMembers = new ImConversationMembers();
imConversationMembers.setId(imConversationMembersId);
imConversationMembers.setCreateTime(new Date());
// imConversationMembers.setUpdateTime(new Date());
imConversationMembers.setFkAppid(appid);
imConversationMembers.setFkConversationId(imConversationId);
imConversationMembers.setFkClientId(creator);
imConversationMembersService.save(imConversationMembers);
// 将他人添加到会话
Long imConversationMembersId2 = SnowflakeUtil.getId();
ImConversationMembers imConversationMembers2 = new ImConversationMembers();
imConversationMembers2.setId(imConversationMembersId2);
imConversationMembers2.setCreateTime(new Date());
imConversationMembers2.setFkAppid(appid);
imConversationMembers2.setFkConversationId(imConversationId);
imConversationMembers2.setFkClientId(user2);
imConversationMembersService.save(imConversationMembers2);
}
}
package io.geekidea.springbootplus.test;
import com.wecloud.im.entity.ImConversation;
import com.wecloud.im.mapper.ImConversationMapper;
import com.wecloud.im.vo.ConversationVo;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import java.util.List;
/**
* imConversation 单元测试
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
public class ImConversationTest {
@Autowired
private ImConversationMapper imConversationMapper;
@Test
public void listConversation() {
List<ConversationVo> myImConversationList = imConversationMapper.getMyImConversationListAndMsgCount(1394579719625773056L,"", null);
List<ImConversation> myImConversationList1 = imConversationMapper.getMyImConversationList(1394579719625773056L);
}
}
package io.geekidea.springbootplus.test;
import cn.hutool.core.codec.Base64;
import com.turo.pushy.apns.DeliveryPriority;
import com.turo.pushy.apns.PushType;
import com.wecloud.im.ws.sender.IosPush;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
public class IosApnsBase64Test {
public static void main(String[] args) throws IOException {
// apnsCertificatePath 证书
// * @param productFlag 环境
// * @param deviceToken 设备token
// * @param alertTitle 标题
// * @param alertBody 副标题
// * @param contentAvailable Boolean.FALSE
// * @param customProperty 自定义属性
// * @param badge 角标数量
// * @param priority DeliveryPriority.IMMEDIATE
// * @param pushType PushType.ALERT
// * @param topicBundleId undleId
// * @param sound rtc= "call.caf"; 否则为default
Map<String, Object> customProperty = new HashMap<String, Object>(10);
// String apnsCertificatePath = "frogsell_push_dev.p12";
String deviceToken = "5b761f954efe7493de0bc751942e1a8355853771b66a512f5687ca05e7335e99";
String alertTitle = "你好333";
String alertBody = "hi333";
int badge = 1;
String topicBundleId = "com.xteng.Hibro";
boolean contentAvailable = false;
// InputStream certificate = IosPush.getApnsCertificate(apnsCertificatePath);
// String encode = Base64.encode(certificate);
File file = new File("/Users/giaogiao/Library/Containers/com.tencent.xinWeChat/Data/Library/Application Support/com.tencent.xinWeChat/2.0b4.0.9/f31cd9e6d7da1d15c57c40575f5c85db/Message/MessageTemp/e1180914825140f051a87348bda5cbb5/File/hipro_test_push.p12");
InputStream in = new FileInputStream(file);
String encode = Base64.encode(in);
// 解码
byte[] decode = Base64.decode(encode);
InputStream inputStream2 = new ByteArrayInputStream(decode);
IosPush.push("123456", inputStream2, Boolean.FALSE, deviceToken, alertTitle, alertBody,
contentAvailable, customProperty, badge
, DeliveryPriority.IMMEDIATE, PushType.ALERT, topicBundleId,
"default");
}
// public static byte[] readInputStream(InputStream inputStream) throws IOException {
// byte[] buffer = new byte[1024];
// int len = 0;
// ByteArrayOutputStream bos = new ByteArrayOutputStream();
// while ((len = inputStream.read(buffer)) != -1) {
// bos.write(buffer, 0, len);
// }
// bos.close();
// return bos.toByteArray();
// }
// private static String inputToString(InputStream is) throws IOException {
// final int bufferSize = 1024;
// final char[] buffer = new char[bufferSize];
// final StringBuilder out = new StringBuilder();
// Reader in = new InputStreamReader(is, StandardCharsets.UTF_8);
// for (; ; ) {
// int rsz = in.read(buffer, 0, buffer.length);
// if (rsz < 0)
// break;
// out.append(buffer, 0, rsz);
// }
// return out.toString();
// }
}
package io.geekidea.springbootplus.test;
import com.turo.pushy.apns.DeliveryPriority;
import com.turo.pushy.apns.PushType;
import com.wecloud.im.ws.sender.IosPush;
import java.util.HashMap;
import java.util.Map;
public class IosApnsPushTest {
public static void main(String[] args) {
// * @param apnsCertificatePath 证书
// * @param productFlag 环境,测试=Boolean.FALSE,正式=Boolean.TRUE
// * @param deviceToken 设备token
// * @param alertTitle 标题
// * @param alertBody 副标题
// * @param contentAvailable Boolean.FALSE
// * @param customProperty 自定义属性
// * @param badge 角标数量
// * @param priority DeliveryPriority.IMMEDIATE
// * @param pushType PushType.ALERT
// * @param topicBundleId undleId
// * @param sound rtc= "call.caf"; 否则为default
Map<String, Object> customProperty = new HashMap<String, Object>(10);
String apnsCertificatePath = "frogsell_push_dev.p12";
String deviceToken = "27c93ca84bbf17d9ff8eb05df0576ac49822db2ae1c02aa0afea83b5c3861276";
String alertTitle = "你好22";
String alertBody = "hi";
int badge = 1;
String topicBundleId = "com.jdw.frogsell";
boolean contentAvailable = false;
IosPush.push(apnsCertificatePath, Boolean.FALSE, deviceToken, alertTitle, alertBody,
contentAvailable, customProperty, badge
, DeliveryPriority.IMMEDIATE, PushType.ALERT, topicBundleId,
"default");
}
}
package io.geekidea.springbootplus.test;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.wecloud.im.ws.model.request.ReceiveVO;
import com.wecloud.utils.JsonUtils;
public class JsonTest {
public static void main(String[] args) {
// jsonTest();
}
private static void jsonTest() {
String data = "{\n" +
"\"reqId\":\"123123\",\n" +
"\"cmd\":1,\n" +
"\"data\":{\n" +
" \"type\":-1,\n" +
" \"text\":\"这是一个纯文本消息\",\n" +
" \"attrs\":{\n" +
" \"a\":\"attrs是用来存储用户自定义的一些键值对\"}}\n" +
"}\n";
// json转换成对象
ReceiveVO receiveVO = JsonUtils.decodeJson(data, ReceiveVO.class);
// data对象转换成json
JsonUtils.encodeJson(receiveVO.getData());
}
}
package io.geekidea.springbootplus.test;
import io.geekidea.springbootplus.framework.shiro.util.JwtUtil;
import java.time.Duration;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import cn.hutool.core.lang.Snowflake;
import cn.hutool.crypto.digest.MD5;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.wecloud.im.entity.ImApplication;
import com.wecloud.im.entity.ImClient;
import com.wecloud.im.sdk.enums.DeviceTypeEnum;
import com.wecloud.im.service.ImApplicationService;
import com.wecloud.im.service.ImClientService;
import com.wecloud.im.ws.utils.RedisUtils;
/**
* 生成测试appkey与appSecret对,并存入数据库
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
public class LoginTest {
@Autowired
private RedisUtils redisUtils;
@Autowired
private StringRedisTemplate redisTemplate;
@Autowired
private ImApplicationService imApplicationService;
@Autowired
private ImClientService imClientService;
/**
* 根据客户方生成签名字符串 验证通过则下发token
*
* @param timestemp
* @param clientId
* @param appKey
* @param sign
* @return
* @throws Exception
*/
private String getToken(String timestemp, String clientId, String appKey, String sign) throws Exception {
// 根据appKey从数据库查询密钥
ImApplication imApplication = imApplicationService.getCacheAppByAppKey(appKey);
// 生成以数据库为准的签名
String mySign = new MD5().digestHex(timestemp + clientId + imApplication.getAppKey() + imApplication.getAppSecret());
// 验证签名
if (mySign.equals(sign)) {
System.out.println("一致" + mySign);
// return null;
} else {
System.out.println("不一致" + mySign);
return null;
}
// 判断client是否存在
ImClient client = imClientService.getOne(new QueryWrapper<ImClient>().lambda()
.eq(ImClient::getFkAppid, imApplication.getId())
.eq(ImClient::getClientId, clientId));
if (client == null) {
System.out.println("不存在");
ImClient imClient = new ImClient();
imClient.setId(new Snowflake(1L, 1L).nextId());
imClient.setFkAppid(imApplication.getId());
imClient.setClientId(clientId);
imClientService.save(imClient);
} else {
System.out.println("存在");
}
// 生成token
String generateToken = JwtUtil.generateToken(clientId, appKey, imApplication.getAppSecret(), Duration.ofDays(99999), DeviceTypeEnum.WEB.getCode());
// 保存redis
redisTemplate.opsForValue().set("client:" + imApplication.getAppKey() + ":" + clientId, generateToken);
return generateToken;
}
@Test
public void test() throws Exception {
// 时间戳
String timestamp = "1629274899016";
String clientId = "aaaaa2";
String sign = "a404fe25d383eb154b3b527f7213b35a";
String appKey = "QNtP3EjtLw26ekt0";
String token = getToken(timestamp, clientId, appKey, sign);
System.out.println("token:\n" + token);
}
}
package io.geekidea.springbootplus.test;
import cn.hutool.core.codec.Base64;
import com.wecloud.im.entity.ImIosApns;
import com.wecloud.im.service.ImIosApnsService;
import com.wecloud.im.ws.sender.IosPush;
import com.wecloud.utils.SnowflakeUtil;
import io.geekidea.springbootplus.SpringBootPlusApplication;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
/**
* 生成apns字符串 并存入数据库
*/
@SpringBootTest(classes = SpringBootPlusApplication.class)
@RunWith(SpringRunner.class)
public class SaveApnsTest {
@Autowired
private ImIosApnsService imIosApnsService;
@Test
public void test() throws Exception {
String apnsCertificatePath = "ChatSdk_ios.p12";
String topicBundleId = "com.wecloud.chatDemo";
String pwd = "123456";
// InputStream certificate = IosPush.getApnsCertificate(apnsCertificatePath);
// String encode = Base64.encode(certificate);
File file = new File("C:\\wenzhd\\res\\ios\\ChatSdk_ios.p12");
String base64 = null;
FileInputStream fin = null;
try {
fin = new FileInputStream(file);
byte[] buff = new byte[fin.available()];
fin.read(buff);
base64 = Base64.encode(buff);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fin != null) {
try {
fin.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
ImIosApns imIosApns = new ImIosApns();
imIosApns.setId(SnowflakeUtil.getId());
imIosApns.setFkAppId(1L);
imIosApns.setApnsFileValue(base64);
imIosApns.setEnv(1);
imIosApns.setBundleId(topicBundleId);
imIosApns.setPwd(pwd);
imIosApnsService.save(imIosApns);
}
}
package io.geekidea.springbootplus.test;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.wecloud.im.ws.model.request.ReceiveVO;
import com.wecloud.utils.JsonUtils;
import org.springframework.util.DigestUtils;
/**
* 客户方签名字符串生成 单元测试
*/
public class SignTest {
/**
* 获取sign,客户端sdk得到sign之后就可以进行登录,websocket连接初始化需要带上sign,验证通过才能连接成功
* <p>
* sign = MD5{timestamp + clientId + appKey + appSecret}
*
* @param appKey
* @param appSecret
*/
private static void getSign(String timestamp, String clientId, String appKey, String appSecret) {
String data = timestamp + clientId + appKey + appSecret;
// String sign = new MD5().digestHex(data);
String sign = DigestUtils.md5DigestAsHex(data.getBytes());
System.out.println("timestamp:" + timestamp);
System.out.println("sign:" + sign);
}
public static void main(String[] args) {
String clientId = "client_333";
String appKey = "elLwpel1gWCHDqZy";
String appSecret = "68809bb5a9077a83631aeb0b17b5965d6b2302faf2ab3737";
String timestamp = String.valueOf(System.currentTimeMillis());
getSign(timestamp, clientId, appKey, appSecret);
}
private static void jsonTest() throws JsonProcessingException {
String data = "{\n" +
"\"reqId\":\"123123\",\n" +
"\"cmd\":1,\n" +
"\"data\":{\n" +
" \"type\":-1,\n" +
" \"text\":\"这是一个纯文本消息\",\n" +
" \"attrs\":{\n" +
" \"a\":\"attrs是用来存储用户自定义的一些键值对\"}}\n" +
"}\n";
// json转换成对象
ReceiveVO receiveVO = JsonUtils.decodeJson(data, ReceiveVO.class);
// data对象转换成json
JsonUtils.encodeJson(receiveVO.getData());
}
}
/target/
/classes
!.mvn/wrapper/maven-wrapper.jar
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### NetBeans ###
/nbproject/private/
/build/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
.DS_Store
*.log
logs
*.rdb
# config 项目配置模块
\ No newline at end of file
/target/
/classes
!.mvn/wrapper/maven-wrapper.jar
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### NetBeans ###
/nbproject/private/
/build/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
.DS_Store
*.log
logs
*.rdb
package com.wecloud.im.externalaccess.param;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
/**
* @Author wenzhida
* @Date 2022/2/22 9:15
* @Description 用户登录成功dto
*/
@Data
public class LoginSuccessDto implements Serializable {
private static final long serialVersionUID = 7813920366165375711L;
/**
* userId
*/
@ApiModelProperty("userId")
private String userId;
@ApiModelProperty("蓝豆号")
private String idNumber;
@ApiModelProperty("手机号码")
private String phone;
@ApiModelProperty("邮箱号码")
private String email;
@ApiModelProperty("性别")
private Integer sex;
@ApiModelProperty("头像")
private String headPortrait;
@ApiModelProperty("昵称")
private String nickname;
}
package com.wecloud.im.externalaccess.param;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
import javax.validation.constraints.NotNull;
/**
* @Author wenzhida
* @Date 2022/2/23 15:20
* @Description 修改性别入参
*/
@Data
public class ModifySexParam implements Serializable {
private static final long serialVersionUID = -3340451953818782194L;
/**
* userId
*/
@NotNull(message = "userId不可为空")
@ApiModelProperty("userId")
private Long userId;
/**
* 性别
* @see com.wecloud.im.sdk.enums.SexEnum
*/
@NotNull(message = "性别不可为空不可为空")
@ApiModelProperty("性别 1-男 2-女 3-未知")
private Integer sex;
}
package com.wecloud.im.externalaccess.param;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
import javax.validation.constraints.NotNull;
/**
* 修改用户入参
* @Author luozh
* @Date 2022年04月18日 15:19
* @Version 1.0
*/
@Data
public class ModifyUserParam implements Serializable {
private static final long serialVersionUID = 1L;
/**
* userId
*/
@NotNull(message = "userId不可为空")
@ApiModelProperty("userId")
private Long userId;
/**
* 昵称
*/
@NotNull(message = "昵称不能为空")
@ApiModelProperty("昵称")
private String nickname;
/**
* 头像url
*/
@NotNull(message = "头像url不能为空")
@ApiModelProperty("头像url")
private String headPortrait;
}
package com.wecloud.im.externalaccess.param;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
/**
* @Author wenzhida
* @Date 2022/3/3 17:42
* @Description 多人音视频sign获取入参
*/
@Data
public class MultiMeetSignGetParam implements Serializable {
private static final long serialVersionUID = 1538118936608500035L;
@ApiModelProperty("时间戳")
@NotNull(message = "时间戳不能为空")
private String timestamp;
@ApiModelProperty("client客户端id")
@NotNull(message = "client客户端id不能为空")
private String clientId;
@ApiModelProperty("appKey")
@NotNull(message = "appKey不能为空")
private String appKey;
@ApiModelProperty("客户端平台: 1 web, 2 安卓, 3 ios, 4 pc-win, 5 pc-macOs")
@NotNull(message = "客户端平台不能为空")
private Integer platform;
@ApiModelProperty("密钥")
@NotNull(message = "密钥不能为空")
private String appSecret;
}
package com.wecloud.im.externalaccess.param;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
/**
* @Author wenzhida
* @Date 2022/2/21 22:57
* @Description 重置密码接口
*/
@Data
public class ResetPasswordParam implements Serializable {
private static final long serialVersionUID = 387632352343954534L;
/**
* 电话号码
*/
@NotNull(message = "电话号码不可为空")
@ApiModelProperty("电话号码")
private String phone;
/**
* 验证码
*/
@NotNull(message = "验证码不可为空")
@ApiModelProperty("验证码")
private String verifyCode;
/**
* 密码
*/
@NotNull(message = "密码不可为空")
@ApiModelProperty("密码")
private String password;
}
package com.wecloud.im.externalaccess.param;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
import javax.validation.constraints.NotNull;
/**
* @Author wenzhida
* @Date 2022/2/21 18:15
* @Description 生成验证码入参
*/
@Data
public class SendVerifyCodeParam implements Serializable {
private static final long serialVersionUID = 565144491185523650L;
/**
* 电话号码
*/
@NotNull(message = "电话号码不可为空")
@ApiModelProperty("电话号码")
private String phone;
/**
* 验证场景 1-用户注册 2-重置密码验证 3-更换手机号绑定
* @see com.wecloud.im.sdk.enums.VerifySceneEnum
*/
@NotNull(message = "验证场景不可为空")
@ApiModelProperty("验证场景 1-用户注册 2-重置密码验证 3-更换手机号绑定")
private Integer verifyScene;
}
package com.wecloud.im.externalaccess.param;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
/**
* @Author wenzhida
* @Date 2022/2/23 11:27
* @Description 用户基本信息
*/
@Data
public class UserBaseDto implements Serializable {
private static final long serialVersionUID = -6070534424163538590L;
/**
* userId
*/
@ApiModelProperty("userId")
private String userId;
@ApiModelProperty("蓝豆号")
private String idNumber;
@ApiModelProperty("手机号码")
private String phone;
/**
* 性别
* @see com.wecloud.im.sdk.enums.SexEnum
*/
@ApiModelProperty("性别 1-男 2-女 3-未知")
private Integer sex;
@ApiModelProperty("昵称")
private String nickname;
/**
* 头像路径url
*/
@ApiModelProperty("头像路径url")
private String headPortrait;
/**
* 与我关系
* @see com.wecloud.im.sdk.enums.RelationEnum
*/
@ApiModelProperty("与我关系 1-陌生人 2-好友 3-被我拉黑")
private Integer relation;
@ApiModelProperty("好友的昵称备注")
private String friendName;
}
package com.wecloud.im.externalaccess.param;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
import javax.validation.constraints.NotNull;
import com.wecloud.im.sdk.enums.DeviceTypeEnum;
/**
* @Author wenzhida
* @Date 2022/2/21 18:15
* @Description 用户登录入参
*/
@Data
public class UserLoginParam implements Serializable {
private static final long serialVersionUID = 9182337935301787778L;
/**
* 电话号码
*/
@NotNull(message = "电话号码不可为空")
@ApiModelProperty("电话号码")
private String phone;
/**
* 密码
*/
@NotNull(message = "密码不可为空")
@ApiModelProperty("密码")
private String password;
@NotNull(message = "appKey不可为空")
@ApiModelProperty("appKey")
private String appKey;
/**
* 设备类型
* @see DeviceTypeEnum
*/
@NotNull(message = "设备类型不可为空")
@ApiModelProperty("设备类型 1:ios; 2:android; 3:web; 4:win; 5:mac")
private Integer deviceType;
}
package com.wecloud.im.externalaccess.param;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
/**
* @Author wenzhida
* @Date 2022/2/21 18:15
* @Description 用户注册入参
*/
@Data
public class UserRegisterParam implements Serializable {
private static final long serialVersionUID = 6026490500445982659L;
/**
* 电话号码
*/
@NotNull(message = "电话号码不可为空")
@ApiModelProperty("电话号码")
private String phone;
/**
* 验证码
*/
@NotNull(message = "验证码不可为空")
@ApiModelProperty("验证码")
private String verifyCode;
/**
* 密码
*/
@NotNull(message = "密码不可为空")
@ApiModelProperty("密码")
private String password;
}
package com.wecloud.im.friend.entity;
import io.geekidea.springbootplus.framework.common.entity.BaseEntity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.util.Date;
import javax.validation.constraints.NotNull;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
/**
* @author lixiaozhong
* 好友关系表
*/
@Data
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = true)
@ApiModel(value = "ImFriend对象")
public class ImFriend extends BaseEntity {
private static final long serialVersionUID = 1L;
@NotNull(message = "主键id不能为空")
@ApiModelProperty("主键id")
@TableId(value = "id", type = IdType.INPUT)
private Long id;
@ApiModelProperty("我的client-id")
private String clientId;
@ApiModelProperty("好友的client-id")
private String clientIdFriend;
@ApiModelProperty("申请者")
private String clientIdClaimer;
@ApiModelProperty("好友的昵称备注")
private String friendName;
@ApiModelProperty("好友拒绝原因")
private String rejectRemark;
@ApiModelProperty("好友请求说明")
private String requestRemark;
/**
* 好友关系状态
* @see com.wecloud.im.sdk.enums.FriendStateEnum
*/
@ApiModelProperty("好友关系状态")
private Integer state;
@ApiModelProperty("创建时间")
private Date createTime;
@ApiModelProperty("修改时间")
private Date updateTime;
}
package com.wecloud.im.friend.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import io.geekidea.springbootplus.framework.common.entity.BaseEntity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import javax.validation.constraints.NotNull;
import java.util.Date;
/**
* @author lixiaozhong
* 好友关系表
*/
@Data
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = true)
@ApiModel(value = "ImFriendRecommend好友推荐对象")
public class ImFriendRecommend extends BaseEntity {
private static final long serialVersionUID = 1L;
@NotNull(message = "主键id不能为空")
@ApiModelProperty("主键id")
@TableId(value = "id", type = IdType.INPUT)
private Long id;
@ApiModelProperty("我的client-id")
private String clientId;
@ApiModelProperty("好友的client-id")
private String clientIdFriend;
@ApiModelProperty("推荐来源")
private Integer source;
@ApiModelProperty("是否删除")
private Boolean delFlag;
@ApiModelProperty("创建时间")
private Date createTime;
@ApiModelProperty("修改时间")
private Date updateTime;
}
package com.wecloud.im.friend.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wecloud.im.friend.entity.ImFriend;
import com.wecloud.im.friend.param.ImFriendApplyDto;
import com.wecloud.im.friend.param.ImFriendBaseDto;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import java.util.List;
/**
* @Description 好友关系mapper
* @Author lixiaozhong
* @Date 2022/1/12 11:41 上午
*/
@Repository
public interface ImFriendMapper extends BaseMapper<ImFriend> {
IPage<ImFriendBaseDto> getImFriendPageList(@Param("page") Page<ImFriendBaseDto> page, @Param("clientId") String clientId);
/**
* 获取待验证的好友列表
* @param page
* @param clientId
* @return
*/
IPage<ImFriendApplyDto> getApplyFriendPageList(@Param("page") Page<ImFriendApplyDto> page, @Param("clientId") String clientId);
ImFriendApplyDto getFriendInfo(@Param("clientId") String clientId, @Param("friendClientId") String friendClientId);
/**
* 过滤得到真的好友,非好友的friendId将被它忽略
* @param clientId
* @param friendClientIds
* @return
*/
List<String> filterNegativeFriends(@Param("clientId") String clientId, @Param("friendClientIds") List<String> friendClientIds);
/**
* 批量删除好友
* @param clientId 删除人的clientId
* @param fkAppId
* @param friendClientIds 被删除人的clientId列表
*/
void batchDeleteFriend(@Param("clientId") String clientId, @Param("fkAppId") Long fkAppId, @Param("friendClientIds") List<String> friendClientIds);
}
package com.wecloud.im.friend.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wecloud.im.friend.entity.ImFriendRecommend;
import com.wecloud.im.friend.param.ImFriendPageParam;
import com.wecloud.im.friend.param.ImFriendRecommendDto;
import io.geekidea.springbootplus.framework.core.pagination.Paging;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import java.util.List;
/**
* @Description 好友推荐关系mapper
* @Author lixiaozhong
* @Date 2022/1/12 11:41 上午
*/
@Repository
public interface ImFriendRecommendMapper extends BaseMapper<ImFriendRecommend> {
IPage<ImFriendRecommendDto> getImFriendRecommendPageList(@Param("page") Page pageParam, @Param("clientId") Long clientId);
/**
* 批量删除好友推荐
* @param clientId
* @param fkAppId
* @param friendClientIds
*/
void batchDeleteRecommend(@Param("clientId") String clientId, @Param("fkAppId") Long fkAppId, @Param("friendClientIds") List<String> friendClientIds);
void batchCreateRecommend(@Param("list") List<ImFriendRecommend> list);
}
package com.wecloud.im.friend.param;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
/**
* @Description TODO
* @Author lixiaozhong
* @Date 2022/1/14 11:56 上午
*/
@Data
public class FriendBaseEventDto implements Serializable {
/**
* 参考 {@link com.wecloud.im.sdk.enums.EventResponseSubCmdEnum EventResponseSubCmdEnum}
*/
@ApiModelProperty("响应命令")
private Integer subCmd;
@ApiModelProperty("申请人的client-id")
private String claimerClientId;
@ApiModelProperty("好友的client-id")
private String friendClientId;
}
package com.wecloud.im.friend.param;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
/**
* @Author wenzhida
* @Date 2022/2/7 16:30
* @Description 批量创建好友推荐入参
*/
@Data
public class ImCreateRecommendParam implements Serializable {
private static final long serialVersionUID = 5228604783548712598L;
@ApiModelProperty("推荐好友列表")
private List<ImFriendRecommendDto> recommendFriends;
}
package com.wecloud.im.friend.param;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
/**
* @Author wenzhida
* @Date 2022/2/7 16:30
* @Description 删除好友入参
*/
@Data
public class ImDeleteFriendParam implements Serializable {
private static final long serialVersionUID = 5228604783548712598L;
@ApiModelProperty("好友的client-id")
private List<String> friendClientIds;
}
package com.wecloud.im.friend.param;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
/**
* @Author wenzhida
* @Date 2022/2/7 16:30
* @Description 批量删除好友推荐入参
*/
@Data
public class ImDeleteRecommendParam implements Serializable {
private static final long serialVersionUID = -2325444195601100874L;
@ApiModelProperty("推荐好友列表")
private List<String> friendClientIds;
}
package com.wecloud.im.friend.param;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* @Description 好友信息
* @Author lixiaozhong
* @Date 2022/1/12 1:59 下午
*/
@Data
public class ImFriendApplyDto extends ImFriendBaseDto {
private static final long serialVersionUID = 1L;
@ApiModelProperty("好友申请者")
private String claimerClientId;
@ApiModelProperty("好友拒绝原因")
private String rejectRemark;
@ApiModelProperty("好友请求说明")
private String requestRemark;
}
package com.wecloud.im.friend.param;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* @Description 申请好友入参
* @Author lixiaozhong
* @Date 2022/1/13 4:24 下午
*/
@Data
public class ImFriendApplyParam extends ImFriendBaseParam {
private static final long serialVersionUID = 1L;
@ApiModelProperty("会话id,群成员添加好友时传参")
private Long conversationId;
@ApiModelProperty("备注好友名称")
private String friendName;
@ApiModelProperty("请求备注")
private String requestRemark;
}
package com.wecloud.im.friend.param;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* @Description TODO
* @Author lixiaozhong
* @Date 2022/1/13 4:24 下午
*/
@Data
public class ImFriendApproveParam extends ImFriendBaseParam {
private static final long serialVersionUID = 1L;
@ApiModelProperty("是否同意接受好友,true同意,false拒绝")
private Boolean agree;
@ApiModelProperty("拒绝理由,如果是同意就不用填啦")
private String rejectRemark;
}
package com.wecloud.im.friend.param;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
/**
* @Description 好友信息
* @Author lixiaozhong
* @Date 2022/1/12 1:59 下午
*/
@Data
public class ImFriendBaseDto implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty("好友的client-id")
private String friendClientId;
@ApiModelProperty("好友的昵称备注")
private String friendName;
@ApiModelProperty("好友关系状态,1:待确定,2:已确认,3:已拒绝,4:已删除")
private Integer state;
}
package com.wecloud.im.friend.param;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
/**
* @Description 好友相关base入参
* @Author lixiaozhong
* @Date 2022/1/13 4:24 下午
*/
@Data
public class ImFriendBaseParam implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty("clientId")
private String clientId;
@ApiModelProperty("好友的client-id")
private String friendClientId;
}
package com.wecloud.im.friend.param;
import io.geekidea.springbootplus.framework.core.pagination.BasePageOrderParam;
import io.swagger.annotations.ApiModel;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* @Description 好友分页
* @Author lixiaozhong
* @Date 2022/1/12 2:24 下午
*/
@Data
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = true)
@ApiModel(value = "好友分页")
public class ImFriendPageParam extends BasePageOrderParam {
private static final long serialVersionUID = 1L;
}
package com.wecloud.im.friend.param;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
/**
* @Description 好友信息
* @Author lixiaozhong
* @Date 2022/1/12 1:59 下午
*/
@Data
public class ImFriendRecommendDto implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty("好友的clientId")
private String friendClientId;
@ApiModelProperty("好友推荐来源,1:通讯录,2:二度人脉,3:附近的人,4:同类标签")
private Integer source;
@ApiModelProperty("是否删除")
private Boolean delFlag;
}
package com.wecloud.im.friend.service;
import io.geekidea.springbootplus.framework.common.api.ApiCode;
import io.geekidea.springbootplus.framework.common.api.ApiResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.wecloud.im.entity.ImApplication;
import com.wecloud.im.entity.ImClient;
import com.wecloud.im.friend.param.FriendApplyEventDto;
import com.wecloud.im.friend.param.FriendApproveEventDto;
import com.wecloud.im.mq.MqSender;
import com.wecloud.im.sdk.enums.EventResponseSubCmdEnum;
import com.wecloud.im.service.ImApplicationService;
import com.wecloud.im.ws.enums.WsResponseCmdEnum;
import com.wecloud.im.ws.model.WsResponse;
import com.wecloud.im.ws.model.request.PushVO;
import com.wecloud.im.ws.sender.ChannelSender;
import com.wecloud.pushserver.client.model.constant.MqConstant;
import com.wecloud.pushserver.client.model.dto.PushDTO;
/**
* @Description TODO
* @Author lixiaozhong
* @Date 2022/1/13 5:35 下午
*/
@Component
public class FriendEventSender {
@Autowired
private ChannelSender channelSender;
@Autowired
private ImApplicationService imApplicationService;
@Autowired
private MqSender mqSender;
private final static String FRIEND_APPLY_TITLE = "好友申请";
private final static String FRIEND_APPLY_TITLE_SUB = "您有好友申请待验证";
private final static String FRIEND_APPROVE_TITLE = "好友验证结果";
private final static String FRIEND_APPROVE_TITLE_AGREE = "您的好友同意了您的好友申请";
private final static String FRIEND_APPROVE_TITLE_REJECT = "您的好友拒绝了您的好友申请";
public void sendFriendApplyEventMsg(ImClient claimerClient, ImClient receiveClient, String requestRemark) {
FriendApplyEventDto applyDto = new FriendApplyEventDto();
applyDto.setSubCmd(EventResponseSubCmdEnum.FRIEND_APPLY.getCode());
applyDto.setRequestRemark(requestRemark);
applyDto.setClaimerClientId(claimerClient.getClientId());
applyDto.setFriendClientId(receiveClient.getClientId());
// 向接收方推送
WsResponse<FriendApplyEventDto> responseModel = new WsResponse<>();
responseModel.setCmd(WsResponseCmdEnum.NOTICE_EVENT_MSG.getCmdCode());
ApiResult<Boolean> result = ApiResult.result(ApiCode.SUCCESS);
responseModel.setCode(result.getCode());
responseModel.setMsg(result.getMessage());
responseModel.setData(applyDto);
responseModel.setReqId(null);
channelSender.sendMsg(responseModel, receiveClient.getId());
ImApplication app = imApplicationService.getCacheById(receiveClient.getFkAppid());
PushVO pushVO = new PushVO();
pushVO.setTitle(FRIEND_APPLY_TITLE);
pushVO.setSubTitle(FRIEND_APPLY_TITLE_SUB);
PushDTO pushDTO = mqSender.buildPushDto(pushVO, receiveClient, app);
if (pushDTO != null) {
mqSender.orderSend(MqConstant.Topic.IM_ORDER_MSG_TOPIC, MqConstant.Tag.IM_ORDER_MSG_TAG, pushDTO);
}
}
public void sendFriendApproveEventMsg(ImClient claimerClient, ImClient receiveClient, boolean isAgree, String rejectRemark) {
FriendApproveEventDto approveDto = new FriendApproveEventDto();
approveDto.setSubCmd(EventResponseSubCmdEnum.FRIEND_APPROVE.getCode());
approveDto.setAgree(isAgree);
approveDto.setRejectRemark(rejectRemark);
approveDto.setClaimerClientId(claimerClient.getClientId());
approveDto.setFriendClientId(receiveClient.getClientId());
// 向接收方推送
WsResponse<FriendApproveEventDto> responseModel = new WsResponse<>();
responseModel.setCmd(WsResponseCmdEnum.NOTICE_EVENT_MSG.getCmdCode());
ApiResult<Boolean> result = ApiResult.result(ApiCode.SUCCESS);
responseModel.setCode(result.getCode());
responseModel.setMsg(result.getMessage());
responseModel.setData(approveDto);
responseModel.setReqId(null);
channelSender.sendMsg(responseModel, receiveClient.getId());
ImApplication app = imApplicationService.getCacheById(receiveClient.getFkAppid());
PushVO pushVO = new PushVO();
pushVO.setTitle(FRIEND_APPROVE_TITLE);
pushVO.setSubTitle(isAgree ? FRIEND_APPROVE_TITLE_AGREE : FRIEND_APPROVE_TITLE_REJECT);
PushDTO pushDTO = mqSender.buildPushDto(pushVO, receiveClient, app);
if (pushDTO != null) {
mqSender.orderSend(MqConstant.Topic.IM_ORDER_MSG_TOPIC, MqConstant.Tag.IM_ORDER_MSG_TAG, pushDTO);
}
}
}
/*
* Copyright 2019-2029 geekidea(https://github.com/geekidea)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.wecloud.im.interceptor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 下载拦截器
*
* @author geekidea
* @date 2019/8/21
*/
@Slf4j
@ConditionalOnProperty(value = {"spring-boot-plus.interceptor.download.enable"}, matchIfMissing = true)
public class DownloadInterceptor extends HandlerInterceptorAdapter {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 如果访问的不是控制器,则跳出,继续执行下一个拦截器
if (!(handler instanceof HandlerMethod)) {
return true;
}
// 访问路径
String url = request.getRequestURI();
// 访问全路径
String fullUrl = request.getRequestURL().toString();
// 下载拦截器,业务处理代码
log.info("DownloadInterceptor...");
// 访问token,如果需要,可以设置参数,进行鉴权
// String token = request.getParameter(JwtTokenUtil.getTokenName());
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
// 记录实际下载日志...
}
}
/*
* Copyright 2019-2029 geekidea(https://github.com/geekidea)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.wecloud.im.interceptor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 资源拦截器
*
* @author geekidea
* @date 2019/8/20
*/
@Slf4j
@ConditionalOnProperty(value = {"spring-boot-plus.interceptor.resource.enable"}, matchIfMissing = true)
public class ResourceInterceptor extends HandlerInterceptorAdapter {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 如果访问的控制器,则跳出,继续执行下一个拦截器
if (handler instanceof HandlerMethod) {
return true;
}
// 访问路径
String url = request.getRequestURI();
// 访问全路径
String fullUrl = request.getRequestURL().toString();
// 资源拦截器,业务处理代码
log.info("ResourceInterceptor...");
// 访问token,如果需要,可以设置参数,进行鉴权
// String token = request.getParameter(JwtTokenUtil.getTokenName());
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
// 记录实际访问图片日志...
}
}
/*
* Copyright 2019-2029 geekidea(https://github.com/geekidea)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.wecloud.im.interceptor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 上传拦截器
*
* @author geekidea
* @date 2019/8/22
*/
@Slf4j
@ConditionalOnProperty(value = {"spring-boot-plus.interceptor.upload.enable"}, matchIfMissing = true)
public class UploadInterceptor extends HandlerInterceptorAdapter {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 如果访问的不是控制器,则跳出,继续执行下一个拦截器
if (!(handler instanceof HandlerMethod)) {
return true;
}
// 访问路径
String url = request.getRequestURI();
// 访问全路径
String fullUrl = request.getRequestURL().toString();
// 上传拦截器,业务处理代码
log.info("UploadInterceptor...");
// 访问token,如果需要,可以设置参数,进行鉴权
// String token = request.getParameter(JwtTokenUtil.getTokenName());
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
// 记录实际上传日志...
}
}
package com.wecloud.im.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wecloud.im.entity.ImApplication;
import com.wecloud.im.param.ImApplicationPageParam;
import com.wecloud.im.param.ImApplicationQueryVo;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import java.io.Serializable;
/**
* 第三方应用表 Mapper 接口
*
* @author wei
* @since 2021-04-27
*/
@Repository
public interface ImApplicationMapper extends BaseMapper<ImApplication> {
/**
* 根据ID获取查询对象
*
* @param id
* @return
*/
ImApplicationQueryVo getImApplicationById(Serializable id);
/**
* 获取分页对象
*
* @param page
* @param imApplicationPageParam
* @return
*/
IPage<ImApplicationQueryVo> getImApplicationPageList(@Param("page") Page page, @Param("param") ImApplicationPageParam imApplicationPageParam);
}
package com.wecloud.im.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wecloud.im.entity.ImClientBlacklist;
import com.wecloud.im.param.ImClientBlacklistQueryVo;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import java.io.Serializable;
/**
* 黑名单 Mapper 接口
*
* @author wei
* @since 2021-06-17
*/
@Repository
public interface ImClientBlacklistMapper extends BaseMapper<ImClientBlacklist> {
/**
* 查询我的拉黑列表
* @param page
* @param clientId
* @return
*/
IPage<ImClientBlacklistQueryVo> getImClientBlacklistPageList(@Param("page") Page page, @Param("clientId") String clientId);
/**
* 根据ID获取查询对象
*
* @param id
* @return
*/
ImClientBlacklistQueryVo getImClientBlacklistById(Serializable id);
// /**
// * 获取分页对象
// *
// * @param page
// * @param imClientBlacklistPageParam
// * @return
// */
// IPage<ImClientBlacklistQueryVo> getImClientBlacklistPageList(@Param("page") Page page, @Param("param") ImClientBlacklistPageParam imClientBlacklistPageParam);
}
package com.wecloud.im.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.wecloud.im.entity.ImClientDevice;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
/**
* @Author wenzhida
* @Date 2022/3/2 14:57
* @Description 客户端设备mapper
*/
@Repository
public interface ImClientDeviceMapper extends BaseMapper<ImClientDevice> {
/**
* 清除旧token
* @param appId
* @param deviceToken
* @return
*/
int removeOldToken(@Param("appId") Long appId, @Param("deviceToken") String deviceToken);
}
package com.wecloud.im.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wecloud.im.entity.ImClient;
import com.wecloud.im.param.ImClientPageParam;
import com.wecloud.im.param.ImClientQueryVo;
import com.wecloud.im.param.ImClientSimpleDto;
import com.wecloud.im.vo.GetInfoListVo;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import java.io.Serializable;
import java.util.List;
/**
* 终端表 Mapper 接口
*
* @author wei
* @since 2021-04-27
*/
@Repository
public interface ImClientMapper extends BaseMapper<ImClient> {
/**
* 获取分页对象
*
* @param page
* @param imClientPageParam
* @return
*/
IPage<ImClientQueryVo> getImClientPageList(@Param("page") Page page, @Param("param") ImClientPageParam imClientPageParam);
List<GetInfoListVo> getInfoList(@Param("appId") Long appId, @Param("conversationId") Long conversationId, @Param("clientIds") List<String> clientIds);
List<ImClientSimpleDto> getSimpleClients(@Param("appId")Long appId, @Param("clientIds")List<String> clientIds);
List<ImClientSimpleDto> getSimpleClientsByIds(@Param("ids") List<Long> ids);
}
package com.wecloud.im.mapper;
import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wecloud.im.entity.ImConversation;
import com.wecloud.im.param.ImConversationPageParam;
import com.wecloud.im.param.ImConversationQueryVo;
import com.wecloud.im.vo.ConversationVo;
/**
* 会话表 Mapper 接口
*
* @author wei
* @since 2021-05-07
*/
@Repository
public interface ImConversationMapper extends BaseMapper<ImConversation> {
/**
* 根据ID获取查询对象
*
* @param id
* @return
*/
ImConversationQueryVo getImConversationById(Serializable id);
/**
* 获取分页对象
*
* @param page
* @param imConversationPageParam
* @return
*/
IPage<ImConversationQueryVo> getImConversationPageList(@Param("page") Page page, @Param("param") ImConversationPageParam imConversationPageParam);
/**
* 查询用户加入的所有会话 与每个会话的未读条数 成员
*
* @param currentClientId
* @return
*/
List<ConversationVo> getMyImConversationListAndMsgCount(@Param("currentClientId") Long currentClientId, @Param("clientId") String clientId, @Param("conversationId") Long conversationId);
/**
* 查询用户加入的所有会话
*
* @param clientId
* @return
*/
List<ImConversation> getMyImConversationList(@Param("clientId") Long clientId);
/**
* 查询已经存在的一对一会话信息
*
* @param clientId1
* @param clientId2
* @param isEncrypt 是否加密会话 1-是 0-否
* @return
*/
ImConversation getRepetitionConversationSingle(@Param("clientId1") Long clientId1, @Param("clientId2") Long clientId2, @Param("isEncrypt") Integer isEncrypt);
/**
* 判断重复会话中的Attributes是否一样
*
* @param clientId1
* @param clientId2
* @param attributes
* @return 大于等于1为有重复会话
*/
Long getRepetitionConversationAttributes(@Param("clientId1") Long clientId1, @Param("clientId2") Long clientId2, @Param("attributes") String attributes);
/**
* 增减成员数量
* @param appId fkAppid
* @param conversationId 会话id
* @param addCount 要增减的人数, 负数是减
* @return
*/
boolean addMemberCount(@Param("appId") Long appId, @Param("conversationId") Long conversationId, @Param("addCount") int addCount);
/**
* 升级成万人群
* @param appId fkAppId
* @param conversationId 会话id
* @return 成功则返回true
*/
boolean upgradeToThousandChat(@Param("appId") Long appId, @Param("conversationId") Long conversationId);
/**
* 获取发件人和收件人会话列表
* @Author luozh
* @Date 2022年05月06日 07:15:05
* @param senderClientId 发件人im client id
* @param receiverClientIds 收件人 im client ids
* @Return
*/
List<ImConversation> getConversationBySenderAndReceivers(@Param("senderImClientId") Long senderImClientId, @Param(
"receiverImClientIds") Collection<Long> receiverImClientIds);
}
package com.wecloud.im.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wecloud.im.entity.ImConversationMembers;
import com.wecloud.im.param.ApiImConversationMembersQueryVo;
import com.wecloud.im.param.ListConversationMembersParam;
import com.wecloud.im.param.ImConversationMembersPageParam;
import com.wecloud.im.param.ImConversationMembersQueryVo;
import com.wecloud.im.vo.ConversationMemberVo;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import java.io.Serializable;
import java.util.List;
/**
* 会话成员表 Mapper 接口
*
* @author wei
* @since 2021-05-07
*/
@Repository
public interface ImConversationMembersMapper extends BaseMapper<ImConversationMembers> {
/**
* 根据ID获取查询对象
*
* @param id
* @return
*/
ImConversationMembersQueryVo getImConversationMembersById(Serializable id);
List<ApiImConversationMembersQueryVo> getRestApiImConversationMembersList(@Param("conversationId") Long conversationId);
/**
* 获取群成员列表
* @param param 入参
* @return
*/
List<ConversationMemberVo> getImConversationMembersList(@Param("param") ListConversationMembersParam param);
/**
* 获取分页对象
*
* @param page
* @param imConversationMembersPageParam
* @return
*/
IPage<ImConversationMembersQueryVo> getImConversationMembersPageList(@Param("page") Page page, @Param("param") ImConversationMembersPageParam imConversationMembersPageParam);
List<Long> findThousandGroupsByClientId(@Param("clientId") Long clientId);
/**
* 批量设置群成员
* @param conversationId
* @param fkClientIds
*/
void setAdminsForConversation(@Param("conversationId") Long conversationId, @Param("fkClientIds") List<Long> fkClientIds, @Param("role") Integer role);
/**
* 根据会话id删除群成员
* @param conversationId
*/
void deleteByConversationId(@Param("conversationId") Long conversationId);
}
package com.wecloud.im.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wecloud.im.entity.ImInbox;
import com.wecloud.im.param.ImInboxPageParam;
import com.wecloud.im.param.ImInboxQueryVo;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import java.io.Serializable;
import java.util.List;
/**
* 消息收件箱表 Mapper 接口
*
* @author wei
* @since 2021-05-06
*/
@Repository
public interface ImInboxMapper extends BaseMapper<ImInbox> {
/**
* 根据ID获取查询对象
*
* @param id
* @return
*/
ImInboxQueryVo getImInboxById(Serializable id);
/**
* 获取分页对象
*
* @param page
* @param imInboxPageParam
* @return
*/
IPage<ImInboxQueryVo> getImInboxPageList(@Param("page") Page page, @Param("param") ImInboxPageParam imInboxPageParam);
Long updateImMsgReceivedByIds(@Param("clientId") Long clientId, @Param("msgIds") List<Long> msgIds);
Long updateImMsgReadByIds(@Param("clientId") Long clientId, @Param("msgIds") List<Long> msgIds);
/**
* 统计未读消息数量
*
* @param clientId
* @return
*/
Integer countMyNotReadCount(@Param("clientId") Long clientId);
}
package com.wecloud.im.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wecloud.im.entity.ImIosApns;
import com.wecloud.im.param.ImIosApnsPageParam;
import com.wecloud.im.param.ImIosApnsQueryVo;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import java.io.Serializable;
/**
* apns配置表 Mapper 接口
*
* @author wei
* @since 2021-09-18
*/
@Repository
public interface ImIosApnsMapper extends BaseMapper<ImIosApns> {
/**
* 根据ID获取查询对象
*
* @param id
* @return
*/
ImIosApnsQueryVo getImIosApnsById(Serializable id);
/**
* 获取分页对象
*
* @param page
* @param imIosApnsPageParam
* @return
*/
IPage<ImIosApnsQueryVo> getImIosApnsPageList(@Param("page") Page page, @Param("param") ImIosApnsPageParam imIosApnsPageParam);
}
package com.wecloud.im.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wecloud.im.entity.ImMessage;
import com.wecloud.im.param.GetReadersParam;
import com.wecloud.im.param.ImHistoryMessagePageParam;
import com.wecloud.im.param.ImMessagePageParam;
import com.wecloud.im.param.ImMessageQueryVo;
import com.wecloud.im.vo.OfflineMsgDto;
import com.wecloud.im.vo.ReaderVo;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import java.io.Serializable;
import java.util.List;
/**
* 消息存储表 Mapper 接口
*
* @author wei
* @since 2021-04-29
*/
@Repository
public interface ImMessageMapper extends BaseMapper<ImMessage> {
/**
* 根据ID获取查询对象
*
* @param id
* @return
*/
ImMessageQueryVo getImMessageById(Serializable id);
/**
* 获取分页对象
*
* @param page
* @param imMessagePageParam
* @return
*/
IPage<ImMessageQueryVo> getImMessagePageList(@Param("page") Page page, @Param("param") ImMessagePageParam imMessagePageParam);
/**
* 查询某个会话历史消息分页列表
*
* @param page
* @param imHistoryMessagePageParam
* @return
*/
IPage<OfflineMsgDto> getHistoryMsgConversationId(@Param("page") Page page, @Param("param") ImHistoryMessagePageParam imHistoryMessagePageParam);
IPage<OfflineMsgDto> getHistoryMsgConversationIdNew(@Param("page") Page page, @Param("param") ImHistoryMessagePageParam imHistoryMessagePageParam);
/**
* 根据客户端id与会话id 查询离线消息
*
* @param clientId
* @param conversationId
* @return
*/
List<OfflineMsgDto> getOfflineListByClientAndConversation(@Param("clientId") Long clientId, @Param("conversationId") Long conversationId);
/**
* 查询会话接收的的最后一条消息
*
* @param clientId
* @param conversationId
* @return
*/
OfflineMsgDto getReceivedLastMsgByConversationId(@Param("clientId") Long clientId, @Param("conversationId") Long conversationId);
/**
* 查询会话的最后一条消息
*
* @param conversationId
* @return
*/
OfflineMsgDto getLastMsgByConversationId(@Param("conversationId") Long conversationId, @Param("currentFkClientId") Long currentFkClientId);
/**
* 获取一条消息已读人员和未读人员
* @param currentClientId
* @param param
* @return
*/
List<ReaderVo> getReaders(@Param("currentClientId") Long currentClientId, @Param("param") GetReadersParam param);
}
package com.wecloud.im.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.wecloud.im.entity.ImMultiRtcRoom;
import org.springframework.stereotype.Repository;
/**
* @Author wenzhida
* @Date 2022/3/16 9:19
* @Description 多人音视频房间mapper
*/
@Repository
public interface ImMultiRtcRoomMapper extends BaseMapper<ImMultiRtcRoom> {
}
package com.wecloud.im.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.wecloud.im.entity.ImMultiRtcRoomMember;
import org.springframework.stereotype.Repository;
/**
* @Author wenzhida
* @Date 2022/3/16 9:19
* @Description 多人音视频房间mapper
*/
@Repository
public interface ImMultiRtcRoomMemberMapper extends BaseMapper<ImMultiRtcRoomMember> {
}
package com.wecloud.im.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.wecloud.im.entity.ImRtcRecord;
import org.springframework.stereotype.Repository;
/**
* @Author Future
* @Date 2022/5/22 23:49
* @Description 单人音视频记录mapper
*/
@Repository
public interface ImRtcRecordMapper extends BaseMapper<ImRtcRecord> {
}
package com.wecloud.im.mq;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.common.collect.Lists;
import com.wecloud.im.entity.ImApplication;
import com.wecloud.im.entity.ImClient;
import com.wecloud.im.entity.ImClientDevice;
import com.wecloud.im.service.ImClientDeviceService;
import com.wecloud.im.service.ImInboxService;
import com.wecloud.im.ws.model.request.PushVO;
import com.wecloud.pushserver.client.model.dto.ApplicationDTO;
import com.wecloud.pushserver.client.model.dto.ClientDTO;
import com.wecloud.pushserver.client.model.dto.ClientDeviceDTO;
import com.wecloud.pushserver.client.model.dto.MessageDTO;
import com.wecloud.pushserver.client.model.dto.PushDTO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.rocketmq.client.producer.SendResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.List;
import static com.wecloud.im.ws.ImConstant.PUSH_BODY;
import static com.wecloud.im.ws.ImConstant.PUSH_TITLE;
/**
* @Author wenzhida
* @Date 2022/1/28 11:47
* @Description mq推送服务
*/
@Slf4j
@Component
public class MqSender {
@Autowired
private ImInboxService imInboxService;
@Autowired
private RocketMqProducerService rocketMqProducerService;
@Autowired
private ImClientDeviceService imClientDeviceService;
/**
* mq同步推送方法
*
* @param topic
* @param tag
* @param pushDTO
* @return
*/
public SendResult synSend(String topic, String tag, PushDTO pushDTO) {
log.info("mq同步推送topic: {} tag: {} 推送内容: {}", topic, tag, JSON.toJSONString(pushDTO));
SendResult sendResult = rocketMqProducerService.synSend(topic, tag, JSON.toJSONString(pushDTO));
log.info("mq同步推送topic: {} tag: {} 返回结果: {}", topic, tag, JSON.toJSONString(sendResult));
return sendResult;
}
/**
* mq异步推送方法
*
* @param topic
* @param tag
* @param pushDTO
* @return
*/
public void sendAsync(String topic, String tag, PushDTO pushDTO) {
log.info("mq异步推送topic: {} tag: {} 推送内容: {}", topic, tag, JSON.toJSONString(pushDTO));
rocketMqProducerService.sendAsyncDefault(topic, tag, JSON.toJSONString(pushDTO));
}
/**
* mq按顺序发送
*
* @param topic
* @param tag
* @param pushDTO
* @return
*/
public SendResult orderSend(String topic, String tag, PushDTO pushDTO) {
try {
log.info("mq按顺序发送topic: {} tag: {} 推送内容: {}", topic, tag, JSON.toJSONString(pushDTO));
SendResult sendResult = rocketMqProducerService.orderSend(topic, tag, JSON.toJSONString(pushDTO), 1);
log.info("mq按顺序发送topic: {} tag: {} 返回结果: {}", topic, tag, JSON.toJSONString(sendResult));
return sendResult;
} catch (Exception e) {
log.info("发送通知栏消息异常 ", e);
return null;
}
}
public PushDTO buildPushDto(PushVO pushVO, ImClient imClientReceiver, ImApplication imApplication) {
PushDTO pushDTO = new PushDTO();
MessageDTO messageDTO = new MessageDTO();
if (pushVO == null) {
pushVO = new PushVO();
pushVO.setTitle(PUSH_TITLE);
pushVO.setSubTitle(PUSH_BODY);
}
messageDTO.setTitle(pushVO.getTitle());
messageDTO.setSubTitle(pushVO.getSubTitle());
messageDTO.setData(pushVO.getData());
// 统计未读消息数量
int badge = imInboxService.countMyNotReadCount(imClientReceiver.getId());
messageDTO.setBadge(badge);
ClientDTO clientDTO = new ClientDTO();
clientDTO.setClientId(imClientReceiver.getClientId());
List<ImClientDevice> clientDeviceList = imClientDeviceService.list(
new QueryWrapper<ImClientDevice>().lambda()
.eq(ImClientDevice::getFkClientId, imClientReceiver.getId()));
if (CollectionUtils.isEmpty(clientDeviceList)) {
log.info("接收人信息 {} 查无推送设备", imClientReceiver.getId());
return null;
}
List<ClientDeviceDTO> deviceDTOList = Lists.newArrayList();
for (ImClientDevice imClientDevice : clientDeviceList) {
ClientDeviceDTO clientDeviceDTO = new ClientDeviceDTO();
clientDeviceDTO.setValid(imClientDevice.getValid());
clientDeviceDTO.setDeviceType(imClientDevice.getDeviceType());
clientDeviceDTO.setDeviceToken(imClientDevice.getDeviceToken());
deviceDTOList.add(clientDeviceDTO);
}
clientDTO.setDeviceDTOList(deviceDTOList);
messageDTO.setClientDTO(clientDTO);
ApplicationDTO applicationDTO = new ApplicationDTO();
applicationDTO.setId(imApplication.getId());
applicationDTO.setAppKey(imApplication.getAppKey());
applicationDTO.setAppSecret(imApplication.getAppSecret());
applicationDTO.setAppName(imApplication.getAppName());
applicationDTO.setIosPushChannel(imApplication.getIosPushChannel());
applicationDTO.setAndroidPushChannel(imApplication.getAndroidPushChannel());
applicationDTO.setUmengKey(imApplication.getUmengKey());
applicationDTO.setUmengSecret(imApplication.getUmengSecret());
applicationDTO.setFirebaseSecret(imApplication.getFirebaseSecret());
messageDTO.setApplicationDTO(applicationDTO);
pushDTO.setMessageDTOList(Lists.newArrayList(messageDTO));
return pushDTO;
}
}
package com.wecloud.im.netty.core;
import com.wecloud.im.netty.handler.NettyApiRequest;
import com.wecloud.im.ws.manager.ChannelManager;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.codec.http.FullHttpRequest;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import java.net.InetAddress;
@Component
@ChannelHandler.Sharable
@Slf4j
public class ChannelInboundHandler extends ChannelInboundHandlerAdapter {
private final NettyApiRequest nettyApiRequest;
public ChannelInboundHandler(NettyApiRequest nettyApiRequest) {
this.nettyApiRequest = nettyApiRequest;
}
/**
* 收到消息时,返回信息
*/
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) {
FullHttpRequest httpRequest = (FullHttpRequest) msg;
try {
nettyApiRequest.handle(ctx, msg, httpRequest);
} catch (Exception e) {
log.error("SingleNettyServer处理请求失败!", e);
// this.sendBad(ctx);
} finally {
//释放请求
httpRequest.release();
}
}
/**
* 发送错误信息
*
* @param ctx
*/
// private void sendBad(ChannelHandlerContext ctx) {
// String result = null;
//
// try {
// result = JsonUtil.obj2Json(ResultModel.error(ResultStatus.REQUEST_ERROR));
// } catch (IOException ex) {
// ex.printStackTrace();
// }
// FullHttpRequestUtils.send(ctx, result, HttpResponseStatus.OK);
// }
/**
* 建立连接时,返回消息
*/
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
if (log.isInfoEnabled()) {
log.info("连接的客户端地址:{}", ctx.channel().remoteAddress());
}
ctx.writeAndFlush("客户端" + InetAddress.getLocalHost().getHostName() + "成功与服务端建立连接! ");
super.channelActive(ctx);
}
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
super.channelInactive(ctx);
Long clientId = ctx.channel().attr(ChannelManager.CLIENT_ID).get();
log.info("触发channelInactive方法 clientId {}", clientId);
// ctx.channel().close();
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
throws Exception {
super.exceptionCaught(ctx, cause);
Long clientId = ctx.channel().attr(ChannelManager.CLIENT_ID).get();
log.info("触发exceptionCaught方法 clientId {}", clientId);
}
}
package com.wecloud.im.netty.core;
import com.wecloud.im.ws.model.WsConstants;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
import io.netty.handler.stream.ChunkedWriteHandler;
import io.netty.handler.timeout.IdleStateHandler;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.concurrent.TimeUnit;
import static com.wecloud.im.ws.ImConstant.READER_IDLE_TIME;
@Component
public class NettyChannelInitializer extends ChannelInitializer<SocketChannel> {
@Resource
private ChannelInboundHandler channelInboundHandler;
public static final String SINGLE_HTTP_REQUEST_HANDLER = "SingleHttpRequestHandler";
public static final String APP_WEB_SOCKET_SERVEROTOCOL_HANDLER = "appWebSocketServerotocolHandler";
public static final int MAX_CONTENT_LENGTH = 2048576000;
@Override
protected void initChannel(SocketChannel ch) {
ChannelPipeline pipeline = ch.pipeline();
// http
pipeline.addLast(new HttpServerCodec());
pipeline.addLast(new ChunkedWriteHandler());
pipeline.addLast(new HttpObjectAggregator(MAX_CONTENT_LENGTH));
// 服务端api接口
pipeline.addLast(SINGLE_HTTP_REQUEST_HANDLER, channelInboundHandler);
// 连接超时管理 (判断通道是否有数据写入)
// pipeline.addLast("readTimeoutHandler", new ReadTimeoutHandler(60));
// "/appws"路径 升级长连接
pipeline.addLast(APP_WEB_SOCKET_SERVEROTOCOL_HANDLER, new WebSocketServerProtocolHandler(WsConstants.WS_URL));
/*
* 心跳机制
* observeOutput -当评估写空闲时是否应该考虑字节的消耗。默认为false。
* readerIdleTime—状态为IdleState的IdleStateEvent。当在指定的时间内没有执行读操作时,将触发READER_IDLE。指定0禁用。
* writerIdleTime—状态为IdleState的IdleStateEvent。当在指定的时间内没有执行写操作时,会触发WRITER_IDLE。指定0禁用。
* allIdleTime—状态为IdleState的IdleStateEvent。在一定时间内不读不写会触发ALL_IDLE。指定0禁用。
* unit—readerIdleTime、writeIdleTime和allIdleTime的时间单位
*/
pipeline.addLast(new IdleStateHandler(READER_IDLE_TIME, 0, 0, TimeUnit.SECONDS));
}
}
package com.wecloud.im.netty.core;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.buffer.PooledByteBufAllocator;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
@Component
@Slf4j
public class NettyStart {
private static final EventLoopGroup BOSS = new NioEventLoopGroup(1);
private static final EventLoopGroup WORK = new NioEventLoopGroup();
private static final ServerBootstrap SERVER_BOOTSTRAP = new ServerBootstrap();
static {
SERVER_BOOTSTRAP.group(BOSS, WORK);
//Netty4使用对象池,重用缓冲区
SERVER_BOOTSTRAP.childOption(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT);
SERVER_BOOTSTRAP.option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT);
//设置 心跳保活 socket 的参数选项 keepAlive
SERVER_BOOTSTRAP.childOption(ChannelOption.SO_KEEPALIVE, true);
// 设置不延迟发送TCP_NODELAY=true
SERVER_BOOTSTRAP.childOption(ChannelOption.TCP_NODELAY, true);
// // 初始化服务端可连接队列
// serverBootstrap.option(ChannelOption.SO_BACKLOG, 1000);
// //read缓存区 256k
// serverBootstrap.option(ChannelOption.SO_RCVBUF, 256 * 1024);
// // write缓存区 256k
// serverBootstrap.option(ChannelOption.SO_SNDBUF, 256 * 1024);
// 配置io模型为nio非阻塞
SERVER_BOOTSTRAP.channel(NioServerSocketChannel.class);
}
private final NettyChannelInitializer nettyChannelInitializer;
public NettyStart(NettyChannelInitializer nettyChannelInitializer) {
this.nettyChannelInitializer = nettyChannelInitializer;
}
/**
* Netty创建全部都是实现自AbstractBootstrap。
* 客户端的是Bootstrap,服务端的则是 ServerBootstrap。
**/
public void run(int port) {
log.info("启动netty");
try {
//设置过滤器
SERVER_BOOTSTRAP.childHandler(nettyChannelInitializer);
// 服务器绑定端口监听
ChannelFuture f = SERVER_BOOTSTRAP.bind(port).sync();
f.channel().closeFuture().sync();
} catch (Exception e) {
e.printStackTrace();
} finally {
//关闭EventLoopGroup,释放掉所有资源包括创建的线程
BOSS.shutdownGracefully();
WORK.shutdownGracefully();
}
}
}
package com.wecloud.im.netty.core;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.handler.timeout.IdleStateEvent;
import lombok.extern.slf4j.Slf4j;
import javax.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Component;
import com.wecloud.dispatch.general.GeneralMessageHandler;
import com.wecloud.im.event.ClientOnlineStatusChangeEvent;
import com.wecloud.im.executor.BusinessThreadPool;
import com.wecloud.im.ws.manager.ChannelManager;
import static com.wecloud.im.ws.ImConstant.PING;
import static com.wecloud.im.ws.ImConstant.PONG;
import static com.wecloud.im.ws.ImConstant.READ_IDLE_CLOSE_COUNT;
/**
* @Description app端 长连接事件处理
* @Author hewei hwei1233@163.com
* @Date 2019-07-26
*/
@Component
@ChannelHandler.Sharable
@Slf4j
public class WsReadHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> {
@Resource
private ChannelManager channelManager;
@Resource
private GeneralMessageHandler generalMessageHandler;
@Autowired
private ApplicationEventPublisher eventPublisher;
@Override
protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame msg) {
// 读空闲的计数清零
ctx.channel().attr(ChannelManager.READ_IDLE_TIMES).set(0);
String data = msg.text();
try {
if (data.isEmpty()) {
return;
}
/*
* 在此进入耗时业务线程池, 将不再阻塞netty的I/O线程,提高网络吞吐
*/
BusinessThreadPool.BUSINESS_TASK_THREAD_POOL_EXECUTOR.execute(() ->
execute(ctx, data)
);
} catch (Exception e) {
//返回错误
ctx.channel().writeAndFlush(new TextWebSocketFrame("error=" + e + ",data=" + data));
log.error(e.getMessage() + data, e);
}
}
private void execute(ChannelHandlerContext ctx, String data) {
Long clientId = ctx.channel().attr(ChannelManager.CLIENT_ID).get();
try {
if (PING.equals(data)) {
log.info("收到心跳clientId:" + clientId);
ctx.channel().writeAndFlush(new TextWebSocketFrame(PONG));
return;
}
if (PONG.equals(data)) {
log.info("收到心跳应用Pong,clientId:" + clientId);
return;
}
// AbstractImCmdStrategy.process(clientId, ctx, data);
generalMessageHandler.doMessage(clientId, ctx, data);
} catch (Exception e) {
log.error("系统繁忙data:" + data + ",clientId:" + clientId +
",channelId:" + ctx.channel().id().asLongText(), e);
}
}
@Override
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) {
Long clientId = ctx.channel().attr(ChannelManager.CLIENT_ID).get();
//读超时计时器
Integer readIdleTimes = ctx.channel().attr(ChannelManager.READ_IDLE_TIMES).get();
IdleStateEvent event = (IdleStateEvent) evt;
String eventType = null;
switch (event.state()) {
case READER_IDLE:
eventType = "读空闲:readIdleTimes=" + readIdleTimes;
// 读空闲的计数加1
ctx.channel().attr(ChannelManager.READ_IDLE_TIMES).set(readIdleTimes + 1);
// 发ping
ctx.channel().writeAndFlush(new TextWebSocketFrame(PING));
break;
case WRITER_IDLE:
eventType = "写空闲";
// 不处理
break;
case ALL_IDLE:
eventType = "读写空闲";
// 不处理
break;
default:
}
log.info(clientId + "超时事件:" + eventType);
if (readIdleTimes >= READ_IDLE_CLOSE_COUNT) {
log.info(clientId + ".读空闲超过5次关闭连接");
ctx.channel().close();
}
}
@Override
public void handlerAdded(ChannelHandlerContext ctx) {
if(log.isInfoEnabled()) {
Long clientId = ctx.channel().attr(ChannelManager.CLIENT_ID).get();
log.info("HandlerAdded. CLIENT_ID:{}, channelId is {}", clientId, ctx.channel().id().asLongText());
}
}
/**
* 移除时触发, 不活跃的情况下会移除,会再次触发该事件
*/
@Override
public void handlerRemoved(ChannelHandlerContext ctx) {
Long appId = ctx.channel().attr(ChannelManager.APPLICATION_ID).get();
Long clientId = ctx.channel().attr(ChannelManager.CLIENT_ID).get();
Integer platform = ctx.channel().attr(ChannelManager.PLATFORM).get();
log.info("appId: {} platform: {} CLIENT_ID:{}, handlerRemoved. channelId is {}", appId, platform, clientId, ctx.channel().id().asLongText());
// 关掉连接
channelManager.offline(clientId, platform, ctx);
// 下线通知
long time = System.currentTimeMillis();
String clientIp = ctx.channel().remoteAddress().toString();
ClientOnlineStatusChangeEvent clientOnlineStatusChangeEvent = new ClientOnlineStatusChangeEvent(appId,
clientId, 0, platform, time, clientIp);
eventPublisher.publishEvent(clientOnlineStatusChangeEvent);
}
}
package com.wecloud.im.param;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
/**
* @Author wenzhida
* @Date 2022/3/7 22:18
* @Description 同意加入会议
*/
@Data
@ApiModel(value = "同意加入会议")
public class AgreeToMultiMeetParam implements Serializable {
private static final long serialVersionUID = -5450997250608231171L;
@ApiModelProperty(value = "会话id,可选", required = false)
private Long conversationId;
@ApiModelProperty(value = "多人会议房间id", required = true)
private String roomId;
}
package com.wecloud.im.param;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
/**
* <pre>
* 会话成员表 分页参数对象
* </pre>
*
* @author wei
* @date 2021-05-07
*/
@Data
@Accessors(chain = true)
@ApiModel(value = "ApiImConversationMembersPageParam")
public class ApiImConversationMembersPageParam implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "会话表id", required = true)
private Long conversationId;
}
package com.wecloud.im.param;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
/**
* <pre>
* 会话成员表 查询结果对象
* </pre>
*
* @author wei
* @date 2021-05-07
*/
@Data
@Accessors(chain = true)
@ApiModel(value = "ApiImConversationMembersQueryVo")
public class ApiImConversationMembersQueryVo implements Serializable {
private static final long serialVersionUID = 1L;
// @ApiModelProperty("唯一id")
// private Long id;
// @ApiModelProperty("加入时间")
// private Date createTime;
@ApiModelProperty("客户端id")
private String clientId;
// @ApiModelProperty("修改时间")
// private Date updateTime;
//
// @ApiModelProperty("应用appid")
// private Long fkAppid;
// @ApiModelProperty("会话表id")
// private Long fkConversationId;
}
\ No newline at end of file
package com.wecloud.im.param;
import javax.validation.constraints.NotNull;
import com.wecloud.dispatch.common.BaseRequest;
import com.wecloud.im.ws.model.request.PushVO;
import com.wecloud.utils.JsonUtils;
/**
* @Description 聊天内容
* @Author lixiaozhong
* @Date 2022/1/26 6:11 下午
*/
public class ChatContentVo extends BaseRequest {
/**
* 客户端请求id
*/
String reqId;
/**
* 推送到通知栏对象
*/
PushVO push;
/**
* 会话id
*/
@NotNull
Long toConversation;
/**
* 消息类型
*/
@NotNull
Integer type;
/**
* 发送文本
*/
String text;
/**
* 被@人clientId, 多人用英文逗号分隔; @所有人 入参为 -1
*/
String at;
public PushVO getPush() {
return JsonUtils.beanCopyDeep(this.get("push"), PushVO.class);
}
public void setPush(PushVO push) {
this.push = push;
}
public Long getToConversation() {
return Long.valueOf(this.get("toConversation") + "");
}
public void setToConversation(Long toConversation) {
this.toConversation = toConversation;
}
public Integer getType() {
return Integer.valueOf(this.get("type") + "");
}
public void setType(Integer type) {
this.type = type;
}
public String getText() {
return this.get("text") + "";
}
public void setText(String text) {
this.text = text;
}
public String getAt() {
return this.get("at") + "";
}
public void setAt(String at) {
this.at = at;
}
@Override
public String getReqId() {
return reqId;
}
@Override
public void setReqId(String reqId) {
this.reqId = reqId;
}
}
package com.wecloud.im.param;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import java.io.Serializable;
/**
* @Author wenzhida
* @Date 2022/4/27 16:42
* @Description 聊天室成员分页入参
*/
@Data
@Accessors(chain = true)
@ApiModel(value = "聊天室成员分页入参")
@NoArgsConstructor
@AllArgsConstructor
public class ChatRoomMemberPageParam implements Serializable {
private static final long serialVersionUID = 3284648263835691087L;
@ApiModelProperty("聊天室房间id")
private Long chatRoomId;
}
package com.wecloud.im.param;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* 聊天设置入参
* @Author luozh
* @Date 2022年04月26日 11:52
* @Version 1.0
*/
@Data
public class ChatSettingParam {
@ApiModelProperty("客户端id")
String clientId;
@ApiModelProperty("会话id")
Long conversationId;
@ApiModelProperty("设置类型")
ChatSettingTypeEnum type;
@ApiModelProperty("是否免打扰")
private Boolean on;
}
package com.wecloud.im.param;
import io.geekidea.springbootplus.framework.common.enums.BaseEnum;
import com.baomidou.mybatisplus.annotation.EnumValue;
import com.fasterxml.jackson.annotation.JsonValue;
/**
*
* @Author luozh
* @Date 2022年04月27日 17:26
* @Version 1.0
*/
public enum ChatSettingTypeEnum implements BaseEnum {
/**
* 1-置顶
*/
TOP("TOP", "置顶"),
/**
* 2-消息免打扰
*/
DO_NOT_DISTURB("DO_NOT_DISTURB", "消息免打扰"),
;
ChatSettingTypeEnum(String code, String desc) {
this.code = code;
this.desc = desc;
}
@JsonValue
@EnumValue
private final String code;
private final String desc;
@Override
public Integer getCode() {
return null;
}
@Override
public String getDesc() {
return null;
}
}
package com.wecloud.im.param;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
/**
* @Author wenzhida
* @Date 2022/2/15 11:14
* @Description 获取client信息入参
*/
@Data
public class ClientInfoParam implements Serializable {
private static final long serialVersionUID = 4061204250751318983L;
@ApiModelProperty("会话id")
private Long conversationId;
@ApiModelProperty("clientId")
private String clientId;
}
package com.wecloud.im.param;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
*
* @Author luozh
* @Date 2022年04月18日 10:59
* @Version 1.0
*/
@Api(value = "客户端登录入参", tags = {"客户端登录入参"})
@Data
public class ClientLoginParam {
@ApiModelProperty("客户端id")
private String clientId;
@ApiModelProperty("设备类型")
private Integer deviceType;
}
package com.wecloud.im.param;
import lombok.Builder;
import lombok.Data;
/**
*
* @Author luozh
* @Date 2022年04月22日 11:07
* @Version 1.0
*/
@Builder
@Data
public class ClientOnlineStatusChangeDto {
/**
* 用户id
*/
private String userId;
/**
* 状态:0:online 上线、1:offline 离线、2:logout 登出。
*/
private Integer status;
/**
* 操作系统:iOS、Android、Websocket、PC、MiniProgram(小程序),用户上线时同步。
*/
private String os;
/**
* 发生时间
*/
private Long time;
/**
* 用户当前的 IP 地址及端口。
*/
private String clientIp;
}
package com.wecloud.im.param;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
/**
*
* @Author luozh
* @Date 2022年05月13日 10:48
* @Version 1.0
*/
@Getter
@Setter
public class ClientRelationVo {
@ApiModelProperty("客户端id")
private String clientId;
@ApiModelProperty("朋友客户端id")
private String friendClientId;
@ApiModelProperty("是否好友")
private Boolean friend = false;
@ApiModelProperty("是否黑名单")
private Boolean blacklist = false;
@ApiModelProperty("好友备注")
private String friendName;
}
package com.wecloud.im.param;
import lombok.Data;
import java.util.Map;
import com.wecloud.im.sdk.enums.ChatTypeEnum;
/**
*
* @Author luozh
* @Date 2022年05月25日 10:35
* @Version 1.0
*/
@Data
public class ConversationExtParam {
/**
* 名称
*/
private String name;
/**
* 拓展属性
*/
private Map<String, Object> attributes;
/**
* 会话类型
*/
private ChatTypeEnum chatType;
public ConversationExtParam() {
}
}
package com.wecloud.im.param;
import io.geekidea.springbootplus.framework.common.entity.BaseEntity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* @Author wenzhida
* @Date 2022/3/9 20:54
* @Description 解散群聊入参
*/
@Data
@ApiModel(value = "解散群聊入参")
public class DisbandConversationParam extends BaseEntity {
private static final long serialVersionUID = -354476295467898641L;
@ApiModelProperty("会话表id")
private Long conversationId;
}
package com.wecloud.im.param;
import io.geekidea.springbootplus.framework.common.entity.BaseEntity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* @Author wenzhida
* @Date 2022/4/27 11:44
* @Description 用户退出聊天室入参
*/
@Data
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = true)
@ApiModel(value = "用户退出聊天室入参")
public class ExitChatRoomParam extends BaseEntity {
private static final long serialVersionUID = -3602523207000275557L;
@ApiModelProperty("聊天室id")
private Long chatRoomId;
@ApiModelProperty("离开聊天室的clientId")
private String clientId;
@ApiModelProperty("客户端平台: 1 web, 2 安卓, 3 ios, 4 pc-win, 5 pc-macOs, 需与生成sign时的值一致")
private Integer platform;
}
package com.wecloud.im.param;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
/**
* sign
*
* @author wei
* @since 2021-04-29
*/
@Data
@ApiModel(value = "GetClientInfoParam")
public class GetClientInfoParam implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty("client客户端id")
private List<String> clientIds;
@ApiModelProperty("会话id")
private Long conversationId;
}
package com.wecloud.im.param;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.List;
/**
* sign
*
* @author wei
* @since 2021-04-29
*/
@Data
@ApiModel(value = "GetOnlineStatusParam")
public class GetOnlineStatusParam {
private static final long serialVersionUID = 1L;
@ApiModelProperty("客户端ID")
List<String> clientIds;
}
package com.wecloud.im.param;
import io.geekidea.springbootplus.framework.common.entity.BaseEntity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import javax.validation.constraints.NotNull;
/**
* @Author wenzhida
* @Date 2022/2/15 20:45
* @Description 获取某条消息已读人员入参
*/
@Getter
@Setter
@ApiModel(value = "获取某条消息已读人员入参")
public class GetReadersParam extends BaseEntity {
private static final long serialVersionUID = -2415497107453497807L;
@NotNull(message = "会话id不能为空")
@ApiModelProperty("会话id")
private Long conversationId;
@NotNull(message = "消息id不能为空")
@ApiModelProperty("消息id")
private Long msgId;
}
package com.wecloud.im.param;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
/**
* sign
*
* @author wei
* @since 2021-04-29
*/
@Data
@ApiModel(value = "GetSignParam")
public class GetSignParam implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty("时间戳")
private String timestamp;
@ApiModelProperty("client客户端id")
private String clientId;
@ApiModelProperty("appKey")
private String appKey;
@ApiModelProperty("客户端平台: 1 web, 2 安卓, 3 ios, 4 pc-win, 5 pc-macOs")
private Integer platform;
@ApiModelProperty("密钥")
private String appSecret;
}
package com.wecloud.im.param;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.Map;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
/**
* 发送群聊消息入参
* @Author luozh
* @Date 2022年04月29日 16:00
* @Version 1.0
*/
@Data
public class GroupChatMessageParam {
@NotEmpty(message = "发送人id不能为空")
@ApiModelProperty("发送人id")
private String fromUserId;
@NotEmpty(message = "接收群id不能为空")
@ApiModelProperty("接收群id")
private String toGroupIds;
@ApiModelProperty("指定一个或多个用户")
private String toUserIds;
@NotEmpty(message = "消息类型不能为空")
@ApiModelProperty("消息类型")
private String messageType;
@NotNull(message = "消息不能为空")
@ApiModelProperty("消息")
private Map<String, Object> content;
@ApiModelProperty("指定离线推送通知中的推送内容")
private String pushContent;
@ApiModelProperty("是否包含发送用户")
private Boolean includeSender;
@ApiModelProperty("是否为@消息")
private Boolean mentioned;
@ApiModelProperty("是否为静默消息")
private Boolean silent;
@ApiModelProperty("推送配置")
private PushExtParam pushExt;
}
package com.wecloud.im.param;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
import com.wecloud.im.sdk.enums.GroupChatSettingTypeEnum;
/**
* 群聊设置入参
* @Author luozh
* @Date 2022年04月27日 11:20
* @Version 1.0
*/
@Data
public class GroupChatSettingParam {
@ApiModelProperty("操作人客户端Id server sdk调用传入")
private String operatorClientId;
@ApiModelProperty("设置类型FORBID_ADD_FRIEND 禁止群成员互加好友 FORBID_SEND_PIC 禁止群成员发图片 FORBID_SEND_LINK 禁止群成员发链接" +
"MUTED 群禁言 NAME修改群名 HEAD_PORTRAIT 修改群头像")
private GroupChatSettingTypeEnum type;
@NotNull
@ApiModelProperty("会话id")
private Long groupId;
@ApiModelProperty("开启 true是 false否")
private Boolean on;
@ApiModelProperty("群名称 修改群名称时传值")
private String name;
@ApiModelProperty("头像 修改群头像时传值")
private String headPortrait;
}
package com.wecloud.im.param;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.Map;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
/**
*
* @Author luozh
* @Date 2022年05月05日 10:08
* @Version 1.0
*/
@Data
public class GroupChatStatusMessageParam {
/**
* 发送人客户端id
*/
@NotEmpty(message = "发送人id不能为空")
@ApiModelProperty("发送人id")
private String fromUserId;
/**
* 接收群id
*/
@NotEmpty(message = "接收群id不能为空")
@ApiModelProperty("接收群id")
private String toGroupIds;
/**
* 指定一个或多个用户
*/
@ApiModelProperty("指定一个或多个用户")
private String toUserIds;
/**
* 消息类型
*/
@NotEmpty(message = "消息类型不能为空")
@ApiModelProperty("消息类型")
private String messageType;
/**
* 消息
*/
@NotNull(message = "消息不能为空")
@ApiModelProperty("消息")
private Map<String, Object> content;
/**
* 是否过滤黑名单
*/
@ApiModelProperty("是否过滤黑名单")
private Boolean includeBlacklist;
/**
* 发送用户是否接收
*/
@ApiModelProperty("发送用户是否接收")
private Boolean includeSender;
}
package com.wecloud.im.param;
import lombok.Data;
/**
*
* @Author luozh
* @Date 2022年05月17日 16:20
* @Version 1.0
*/
@Data
public class GroupOwnerTransferParam {
/**
* 群id
*/
private String groupId;
/**
* 新群主用户id
*/
private String newGroupOwnerUserId;
}
package com.wecloud.im.param;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
/**
* @Author wenzhida
* @Date 2022/4/1 20:09
* @Description 多人音视频会议发送心跳入参
*/
@Data
@ApiModel(value = "多人音视频会议发送心跳入参")
public class HeartbeatMultiMeetParam implements Serializable {
private static final long serialVersionUID = -5000410376842426276L;
@ApiModelProperty(value = "会话id,可选", required = false)
private Long conversationId;
@ApiModelProperty(value = "多人会议房间id", required = true)
private String roomId;
}
package com.wecloud.im.param;
import io.geekidea.springbootplus.framework.core.pagination.BasePageOrderParam;
import io.swagger.annotations.ApiModel;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* <pre>
* 第三方应用表 分页参数对象
* </pre>
*
* @author wei
* @date 2021-04-27
*/
@Data
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = true)
@ApiModel(value = "第三方应用表分页参数")
public class ImApplicationPageParam extends BasePageOrderParam {
private static final long serialVersionUID = 1L;
private String pwd;
}
package com.wecloud.im.param;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.Date;
/**
* <pre>
* 第三方应用表 查询结果对象
* </pre>
*
* @author wei
* @date 2021-04-27
*/
@Data
@Accessors(chain = true)
@ApiModel(value = "ImApplicationQueryVo对象")
public class ImApplicationQueryVo implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty("应用appid")
private Long id;
@ApiModelProperty("创建时间")
private Date createTime;
@ApiModelProperty("修改时间")
private Date updateTime;
@ApiModelProperty("key")
private String appKey;
@ApiModelProperty("密钥")
private String appSecret;
@ApiModelProperty("app名称")
private String appName;
}
\ No newline at end of file
package com.wecloud.im.param;
import io.geekidea.springbootplus.framework.core.pagination.BasePageOrderParam;
import io.swagger.annotations.ApiModel;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* <pre>
* 黑名单 分页参数对象
* </pre>
*
* @author wei
* @date 2021-06-17
*/
@Data
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = true)
@ApiModel(value = "黑名单分页参数")
public class ImClientBlacklistPageParam extends BasePageOrderParam {
private String clientId;
private static final long serialVersionUID = 1L;
}
package com.wecloud.im.param;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
/**
* <pre>
* 黑名单 查询结果对象
* </pre>
*
* @author wei
* @date 2021-06-17
*/
@Data
@Accessors(chain = true)
@ApiModel(value = "ImClientBlacklistQueryVo对象")
public class ImClientBlacklistQueryVo implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty("被拉黑者id")
private String clientIdBePrevent;
}
\ No newline at end of file
package com.wecloud.im.param;
import io.geekidea.springbootplus.framework.core.pagination.BasePageOrderParam;
import io.swagger.annotations.ApiModel;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* <pre>
* 终端表 分页参数对象
* </pre>
*
* @author wei
* @date 2021-04-27
*/
@Data
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = true)
@ApiModel(value = "终端表分页参数")
public class ImClientPageParam extends BasePageOrderParam {
private static final long serialVersionUID = 1L;
}
package com.wecloud.im.param;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.Date;
/**
* <pre>
* 终端表 查询结果对象
* </pre>
*
* @author wei
* @date 2021-04-27
*/
@Data
@Accessors(chain = true)
@ApiModel(value = "ImClientQueryVo对象")
public class ImClientQueryVo implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty("客户端id")
private Long id;
@ApiModelProperty("创建时间")
private Date createTime;
@ApiModelProperty("修改时间")
private Date updateTime;
@ApiModelProperty("应用appid")
private Long fkAppid;
@ApiModelProperty("可选 自定义属性,供开发者扩展使用。")
private String attributes;
@ApiModelProperty("ios推送证书")
private String iosPushFile;
@ApiModelProperty("安卓推送证书")
private String androidPushFile;
}
\ No newline at end of file
package com.wecloud.im.param;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import io.geekidea.springbootplus.framework.common.entity.BaseEntity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import javax.validation.constraints.NotNull;
import java.util.Date;
/**
* 终端表
*
* @author wei
* @since 2021-04-27
*/
@Data
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = true)
@ApiModel(value = "ImClientSimpleDto简单对象")
public class ImClientSimpleDto extends BaseEntity {
private static final long serialVersionUID = 1L;
@ApiModelProperty("客户端id")
@TableId(value = "id", type = IdType.INPUT)
private Long id;
@ApiModelProperty("应用appid")
private Long fkAppid;
@ApiModelProperty("客户方提供的唯一id")
private String clientId;
}
package com.wecloud.im.param;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
/**
* <pre>
* 会话成员表 分页参数对象
* </pre>
*
* @author wei
* @date 2021-05-07
*/
@Data
@Accessors(chain = true)
@ApiModel(value = "ImConvMemeClientRemarkNameParam")
public class ImConvMemeClientRemarkNameParam implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "会话中的client备注,展示给会话中其他client查看的", required = true)
private String clientRemarkName;
@ApiModelProperty("会话表id")
private Long conversationId;
}
package com.wecloud.im.param;
import io.geekidea.springbootplus.framework.core.pagination.BasePageOrderParam;
import io.swagger.annotations.ApiModel;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* <pre>
* 会话成员表 分页参数对象
* </pre>
*
* @author wei
* @date 2021-05-07
*/
@Data
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = true)
@ApiModel(value = "会话成员表分页参数")
public class ImConversationMembersPageParam extends BasePageOrderParam {
private static final long serialVersionUID = 1L;
}
package com.wecloud.im.param;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.Date;
/**
* <pre>
* 会话成员表 查询结果对象
* </pre>
*
* @author wei
* @date 2021-05-07
*/
@Data
@Accessors(chain = true)
@ApiModel(value = "ImConversationMembersQueryVo对象")
public class ImConversationMembersQueryVo implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty("唯一id")
private Long id;
@ApiModelProperty("加入时间")
private Date createTime;
@ApiModelProperty("修改时间")
private Date updateTime;
@ApiModelProperty("应用appid")
private Long fkAppid;
@ApiModelProperty("会话表id")
private Long fkConversationId;
@ApiModelProperty("客户端id")
private Long fkClientId;
}
\ No newline at end of file
package com.wecloud.im.param;
import io.geekidea.springbootplus.framework.core.pagination.BasePageOrderParam;
import io.swagger.annotations.ApiModel;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* <pre>
* 会话表 分页参数对象
* </pre>
*
* @author wei
* @date 2021-05-07
*/
@Data
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = true)
@ApiModel(value = "会话表分页参数")
public class ImConversationPageParam extends BasePageOrderParam {
private static final long serialVersionUID = 1L;
}
package com.wecloud.im.param;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
/**
* @Author wenzhida
* @Date 2022/2/14 16:52
* @Description 会话信息获取入参
*/
@Data
@Accessors(chain = true)
@ApiModel(value = "会话信息获取入参")
public class ImConversationQueryParam implements Serializable {
private static final long serialVersionUID = 302200332780152186L;
@NotNull(message = "会话id不能为空")
@ApiModelProperty("会话id")
private Long id;
@ApiModelProperty("会话属性,1:单聊,2:普通群,3:万人群 4:聊天室")
private Integer chatType;
}
package com.wecloud.im.param;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.Date;
/**
* <pre>
* 会话表 查询结果对象
* </pre>
*
* @author wei
* @date 2021-05-07
*/
@Data
@Accessors(chain = true)
@ApiModel(value = "ImConversationQueryVo对象")
public class ImConversationQueryVo implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty("会话id")
private Long id;
@ApiModelProperty("创建时间")
private Date createTime;
@ApiModelProperty("修改时间")
private Date updateTime;
@ApiModelProperty("对话中最后一条消息的发送或接收时间")
private Date lastMessage;
@ApiModelProperty("应用appid")
private Long fkAppid;
@ApiModelProperty("创建者客户端id")
private Long creator;
@ApiModelProperty("可选 对话的名字,可为群组命名。")
private String name;
@ApiModelProperty("可选 自定义属性,供开发者扩展使用。")
private String attributes;
@ApiModelProperty("可选 对话类型标志,是否是系统对话,后面会说明。")
private Boolean systemFlag;
@ApiModelProperty("群成员数量")
private Integer memberCount;
@ApiModelProperty("会话属性,1:单聊,2:普通群,3:万人群,4:聊天室")
private Integer chatType;
/**
* 禁言开关
* @see com.wecloud.im.sdk.enums.MutedEnum
*/
@ApiModelProperty("禁言开关 1-未禁言 2-禁言")
private Integer muted;
@ApiModelProperty("禁止互加好友")
private Boolean forbidAddFriend;
@ApiModelProperty("禁止发红包")
private Boolean forbidSendRedPackets;
@ApiModelProperty("禁止发图片")
private Boolean forbidSendPic;
@ApiModelProperty("禁止发链接")
private Boolean forbidSendLink;
}
This diff is collapsed. Click to expand it.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment