diff --git a/pom.xml b/pom.xml
index 34ee4b6..f4ec57a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,316 +1,340 @@
- 4.0.0
+ 4.0.0
- com.gxwebsoft
- com-gxwebsoft-core
- 1.5.0
+ com.gxwebsoft
+ com-gxwebsoft-server
+ 1.5.2
- com-gxwebsoft-api
- WebSoftApi project for Spring Boot
+ com-gxwebsoft-api
+ WebSoftApi project for Spring Boot
-
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.5.4
+
+
+
+
+ 1.8
+ UTF-8
+ UTF-8
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-devtools
+ runtime
+ true
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-aop
+
+
+
+
+ org.springframework.boot
+ spring-boot-configuration-processor
+ true
+
+
+
+
+ org.projectlombok
+ lombok
+ true
+
+
+
+
+ mysql
+ mysql-connector-java
+ runtime
+
+
+
+
+ com.alibaba
+ druid-spring-boot-starter
+ 1.2.6
+
+
+
+
+ com.baomidou
+ mybatis-plus-boot-starter
+ 3.4.3.3
+
+
+
+
+ com.github.yulichang
+ mybatis-plus-join-boot-starter
+ 1.4.5
+
+
+
+
+ com.baomidou
+ mybatis-plus-generator
+ 3.4.1
+
+
+
+
+ cn.hutool
+ hutool-core
+ 5.8.11
+
+
+ cn.hutool
+ hutool-extra
+ 5.8.11
+
+
+ cn.hutool
+ hutool-http
+ 5.8.11
+
+
+ cn.hutool
+ hutool-crypto
+ 5.8.11
+
+
+
+
+ cn.afterturn
+ easypoi-base
+ 4.4.0
+
+
+
+
+ org.apache.tika
+ tika-core
+ 2.1.0
+
+
+
+
+ com.github.livesense
+ jodconverter-core
+ 1.0.5
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-mail
+
+
+
+
+ com.ibeetl
+ beetl
+ 3.6.1.RELEASE
+
+
+
+
+ io.springfox
+ springfox-boot-starter
+ 3.0.0
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-security
+
+
+
+
+ io.jsonwebtoken
+ jjwt-impl
+ 0.11.2
+
+
+ io.jsonwebtoken
+ jjwt-jackson
+ 0.11.2
+
+
+
+
+ com.github.whvcse
+ easy-captcha
+ 1.6.2
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-data-redis
+
+
+
+
+ com.aliyun
+ aliyun-java-sdk-core
+ 4.4.3
+
+
+
+ com.alipay.sdk
+ alipay-sdk-java
+ 4.35.0.ALL
+
+
+
+ org.bouncycastle
+ bcprov-jdk15on
+ 1.70
+
+
+
+ commons-logging
+ commons-logging
+ 1.2
+
+
+
+ com.alibaba
+ fastjson
+ 2.0.20
+
+
+
+
+ com.google.zxing
+ core
+ 3.3.3
+
+
+
+ com.google.code.gson
+ gson
+ 2.8.0
+
+
+
+ com.vaadin.external.google
+ android-json
+ 0.0.20131108.vaadin1
+ compile
+
+
+
+
+ com.corundumstudio.socketio
+ netty-socketio
+ 2.0.3
+
+
+
+
+ com.github.wechatpay-apiv3
+ wechatpay-java
+ 0.2.9
+
+
+
+ com.github.binarywang
+ weixin-java-miniapp
+ 4.5.0
+
+
+
+
+ com.aliyun.oss
+ aliyun-sdk-oss
+ 3.17.0
+
+
+
+
+ com.aliyun
+ green20220302
+ 1.0.8
+
+
+
+ org.springframework.boot
+ spring-boot-starter-freemarker
+
+
+
+
+ com.getui.push
+ restful-sdk
+ 1.0.0.14
+
+
+
+
+
+
+
+ src/main/java
+
+ **/*Mapper.xml
+
+
+
+ src/main/resources
+
+ **
+
+
+
+
+
org.springframework.boot
- spring-boot-starter-parent
+ spring-boot-maven-plugin
2.5.4
-
-
+
+
+
+ org.projectlombok
+ lombok
+
+
+
+
+
+
-
- 1.8
- UTF-8
- UTF-8
-
-
-
-
-
- org.springframework.boot
- spring-boot-devtools
- runtime
- true
-
-
-
-
- org.springframework.boot
- spring-boot-starter-test
- test
-
-
-
-
- org.springframework.boot
- spring-boot-starter-web
-
-
-
-
- org.springframework.boot
- spring-boot-starter-aop
-
-
-
-
- org.springframework.boot
- spring-boot-configuration-processor
- true
-
-
-
-
- org.projectlombok
- lombok
- true
-
-
-
-
- mysql
- mysql-connector-java
- runtime
-
-
-
-
- com.alibaba
- druid-spring-boot-starter
- 1.2.6
-
-
-
-
- com.baomidou
- mybatis-plus-boot-starter
- 3.4.3.3
-
-
-
-
- com.github.yulichang
- mybatis-plus-join-boot-starter
- 1.4.5
-
-
-
-
- com.baomidou
- mybatis-plus-generator
- 3.4.1
-
-
-
-
- cn.hutool
- hutool-core
- 5.8.11
-
-
- cn.hutool
- hutool-extra
- 5.8.11
-
-
- cn.hutool
- hutool-http
- 5.8.11
-
-
- cn.hutool
- hutool-crypto
- 5.8.11
-
-
-
-
- cn.afterturn
- easypoi-base
- 4.4.0
-
-
-
-
- org.apache.tika
- tika-core
- 2.1.0
-
-
-
-
- com.github.livesense
- jodconverter-core
- 1.0.5
-
-
-
-
- org.springframework.boot
- spring-boot-starter-mail
-
-
-
-
- com.ibeetl
- beetl
- 3.6.1.RELEASE
-
-
-
-
- io.springfox
- springfox-boot-starter
- 3.0.0
-
-
-
-
- org.springframework.boot
- spring-boot-starter-security
-
-
-
-
- io.jsonwebtoken
- jjwt-impl
- 0.11.2
-
-
- io.jsonwebtoken
- jjwt-jackson
- 0.11.2
-
-
-
-
- com.github.whvcse
- easy-captcha
- 1.6.2
-
-
-
-
- org.springframework.boot
- spring-boot-starter-data-redis
-
-
-
-
- com.aliyun
- aliyun-java-sdk-core
- 4.4.3
-
-
-
- com.alipay.sdk
- alipay-sdk-java
- 4.35.0.ALL
-
-
-
- org.bouncycastle
- bcprov-jdk15on
- 1.70
-
-
-
- commons-logging
- commons-logging
- 1.2
-
-
-
- com.alibaba
- fastjson
- 2.0.20
-
-
-
-
- com.google.zxing
- core
- 3.3.3
-
-
-
- com.google.code.gson
- gson
- 2.8.0
-
-
-
- com.vaadin.external.google
- android-json
- 0.0.20131108.vaadin1
- compile
-
-
-
-
- com.corundumstudio.socketio
- netty-socketio
- 2.0.2
-
-
-
-
- com.github.wechatpay-apiv3
- wechatpay-java
- 0.2.9
-
-
-
- com.github.binarywang
- weixin-java-miniapp
- 4.5.0
-
-
-
-
- com.aliyun.oss
- aliyun-sdk-oss
- 3.17.0
-
-
-
-
-
-
-
- src/main/java
-
- **/*Mapper.xml
-
-
-
- src/main/resources
-
- **
-
-
-
-
-
- org.springframework.boot
- spring-boot-maven-plugin
- 2.5.4
-
-
-
- org.projectlombok
- lombok
-
-
-
-
-
-
-
-
-
- aliYunMaven
- https://maven.aliyun.com/repository/public
-
-
+
+
+ aliYunMaven
+ https://maven.aliyun.com/repository/public
+
+
+ com.e-iceblue
+ e-iceblue
+ https://repo.e-iceblue.cn/repository/maven-public/
+
+
diff --git a/src/main/java/com/gxwebsoft/common/core/enums/ChatMessageType.java b/src/main/java/com/gxwebsoft/common/core/enums/ChatMessageType.java
new file mode 100644
index 0000000..9ebb38e
--- /dev/null
+++ b/src/main/java/com/gxwebsoft/common/core/enums/ChatMessageType.java
@@ -0,0 +1,25 @@
+package com.gxwebsoft.common.core.enums;
+
+public enum ChatMessageType {
+ TEXT( 1, "text"),
+ IMAGE(2, "image"),
+ VOICE(3, "voice"),
+ CARD(4, "card"),
+ ;
+
+ private int index;
+
+ private String name;
+ ChatMessageType(int i, String text) {
+ this.name = text;
+ this.index = i;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public int getIndex() {
+ return index;
+ }
+}
diff --git a/src/main/java/com/gxwebsoft/common/core/enums/GreenWebType.java b/src/main/java/com/gxwebsoft/common/core/enums/GreenWebType.java
new file mode 100644
index 0000000..d9a0a5f
--- /dev/null
+++ b/src/main/java/com/gxwebsoft/common/core/enums/GreenWebType.java
@@ -0,0 +1,52 @@
+package com.gxwebsoft.common.core.enums;
+
+public enum GreenWebType {
+ /**
+ * 用户昵称
+ */
+ nickname_detection,
+ /**
+ * 聊天互动
+ */
+ chat_detection,
+ /**
+ * 动态评论
+ */
+ comment_detection,
+ /**
+ * 教学无聊
+ */
+ pgc_detection,
+ /**
+ * 图片检测service: baselineCheck通用基线检测
+ */
+ baselineCheck,
+ /**
+ * 视频检测
+ */
+ videoDetection;
+
+ public enum ChatMessageType {
+ TEXT( 1, "text"),
+ IMAGE(2, "image"),
+ VOICE(3, "voice"),
+ CARD(4, "card"),
+ ;
+
+ private int index;
+
+ private String name;
+ ChatMessageType(int i, String text) {
+ this.name = text;
+ this.index = i;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public int getIndex() {
+ return index;
+ }
+ }
+}
diff --git a/src/main/java/com/gxwebsoft/common/core/security/SecurityConfig.java b/src/main/java/com/gxwebsoft/common/core/security/SecurityConfig.java
index c7c28fe..e105722 100644
--- a/src/main/java/com/gxwebsoft/common/core/security/SecurityConfig.java
+++ b/src/main/java/com/gxwebsoft/common/core/security/SecurityConfig.java
@@ -47,24 +47,13 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
"/v2/api-docs",
"/v3/api-docs",
"/swagger-ui/**",
- "/api/open/**",
"/hxz/v1/**",
"/api/sendSmsCaptcha",
"/api/parseToken/*",
"/api/login-alipay/*",
"/api/wx-login/loginByMpWxPhone",
- "/api/shop/payment/mp-alipay/notify",
- "/api/shop/payment/mp-alipay/test/**",
- "/api/shop/payment/mp-alipay/getPhoneNumber",
- "/api/shop/test/**",
- "/api/shop/wx-login/**",
- "/api/apps/hualala/**",
- "/api/apps/hualala-cart/**",
- "/api/apps/test-data/**",
"/api/wxWorkQrConnect",
- "/WW_verify_QMv7HoblYU6z63bb.txt",
- "/5zbYEPkyV4.txt",
- "/api/love/user-plan-log/wx-pay/**"
+ "/api/sys/user-plan-log/wx-pay/**"
)
.permitAll()
.anyRequest()
diff --git a/src/main/java/com/gxwebsoft/common/core/socketio/cache/ClientCache.java b/src/main/java/com/gxwebsoft/common/core/socketio/cache/ClientCache.java
new file mode 100644
index 0000000..399b56b
--- /dev/null
+++ b/src/main/java/com/gxwebsoft/common/core/socketio/cache/ClientCache.java
@@ -0,0 +1,75 @@
+package com.gxwebsoft.common.core.socketio.cache;
+
+import com.corundumstudio.socketio.SocketIOClient;
+import com.corundumstudio.socketio.SocketIOServer;
+import org.springframework.stereotype.Component;
+import org.springframework.util.CollectionUtils;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * @Author
+ * @Description 用户信息缓存
+ * @Date 14:00 2022/1/21
+ * @Param
+ * @return
+ **/
+@Component
+public class ClientCache {
+
+ private static Map> concurrentHashMap = new ConcurrentHashMap<>();
+
+ private static SocketIOServer socketIOServer;
+
+ public static SocketIOServer getSocketIOServer() {
+ return socketIOServer;
+ }
+
+ public static void setSocketIOServer(SocketIOServer instance) {
+ socketIOServer = instance;
+ }
+ public void saveClient(String userId,UUID sessionId,SocketIOClient socketIOClient){
+ HashMap sessionIdClientCache = concurrentHashMap.get(userId);
+ if(sessionIdClientCache == null){
+ sessionIdClientCache = new HashMap<>();
+ }
+ sessionIdClientCache.put(sessionId,socketIOClient);
+ concurrentHashMap.put(userId,sessionIdClientCache);
+ }
+
+
+ public HashMap getUserClient(String userId){
+ return concurrentHashMap.get(userId);
+ }
+
+ public void deleteSessionClientByUserId(String userId,UUID sessionId){
+ concurrentHashMap.get(userId).remove(sessionId);
+ }
+
+
+ public void deleteUserCacheByUserId(String userId){
+ concurrentHashMap.remove(userId);
+ }
+
+ public int getOnLineCount(){
+ return concurrentHashMap.size();
+ }
+
+ public void sendUserEvent(String userId,String event, Object message) {
+ // 发送到接收方
+ HashMap userClient = concurrentHashMap.get(userId);
+
+ // 查看对方是否在线
+ if(!CollectionUtils.isEmpty(userClient)){
+ for (UUID uuid : userClient.keySet()) {
+ SocketIOClient ioClient = userClient.get(uuid);
+ ioClient.sendEvent(event, message);
+
+ }
+ }
+ }
+
+}
diff --git a/src/main/java/com/gxwebsoft/common/core/socketio/config/SocketIOConfig.java b/src/main/java/com/gxwebsoft/common/core/socketio/config/SocketIOConfig.java
new file mode 100644
index 0000000..3fe7fd0
--- /dev/null
+++ b/src/main/java/com/gxwebsoft/common/core/socketio/config/SocketIOConfig.java
@@ -0,0 +1,82 @@
+package com.gxwebsoft.common.core.socketio.config;
+
+import com.corundumstudio.socketio.SocketIOServer;
+import com.gxwebsoft.common.core.config.ConfigProperties;
+import com.gxwebsoft.common.core.security.JwtSubject;
+import com.gxwebsoft.common.core.security.JwtUtil;
+import com.gxwebsoft.common.core.socketio.cache.ClientCache;
+import com.gxwebsoft.common.core.socketio.handler.SocketIOHandler;
+import com.gxwebsoft.common.system.entity.User;
+import com.gxwebsoft.common.system.service.UserService;
+import io.jsonwebtoken.Claims;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.util.StringUtils;
+
+import javax.annotation.Resource;
+import java.io.InputStream;
+
+/**
+ * socket服务配置
+ * @author machenike
+ */
+@Configuration
+public class SocketIOConfig implements InitializingBean {
+
+ private final static Logger logger = LoggerFactory.getLogger(SocketIOConfig.class);
+ @Value("${socketio.host}")
+ private String host;
+
+ @Value("${socketio.port}")
+ private Integer port;
+
+ @Resource
+ private SocketIOHandler socketIOHandler;
+
+ @Resource
+ private UserService userService;
+
+ @Resource
+ private ConfigProperties configProperties;
+
+ @Override
+ public void afterPropertiesSet() throws Exception {
+ com.corundumstudio.socketio.Configuration config = new com.corundumstudio.socketio.Configuration();
+ //设置host
+ config.setHostname(host);
+ //设置端口
+ config.setPort(port);
+ config.setBossThreads(1);
+ config.setAuthorizationListener(handshakeData -> {
+ String userId =handshakeData.getSingleUrlParam("userId");
+ String token = handshakeData.getSingleUrlParam("token");
+ logger.info("身份验证 token:{}", token);
+ if(!StringUtils.hasText(token) || !StringUtils.hasText(userId)){
+ return false;
+ }
+ // 身份验证
+ Claims claims = JwtUtil.parseToken(token, configProperties.getTokenKey());
+ JwtSubject jwtSubject = JwtUtil.getJwtSubject(claims);
+ User user = userService.getByUsername(jwtSubject.getUsername(), jwtSubject.getTenantId());
+
+ if (user == null || !user.getUserId().equals(Integer.valueOf(userId))) {
+ return false;
+ }
+ return true;
+ });
+
+ InputStream resourceAsStream = this.getClass().getResourceAsStream("/jks/love.jks"); // 读取证书文件流
+ config.setKeyStore(resourceAsStream); // 设置证书文件
+ config.setKeyStorePassword("123456"); // 设置证书密码
+
+ // 启动socket服务
+ SocketIOServer server = new SocketIOServer(config);
+ server.addListeners(socketIOHandler);
+ server.start();
+ ClientCache.setSocketIOServer(server);
+ logger.debug("Netty SocketIO启动:{}:{}",host,port);
+ }
+}
diff --git a/src/main/java/com/gxwebsoft/common/core/socketio/handler/SocketIOHandler.java b/src/main/java/com/gxwebsoft/common/core/socketio/handler/SocketIOHandler.java
new file mode 100644
index 0000000..5df67ec
--- /dev/null
+++ b/src/main/java/com/gxwebsoft/common/core/socketio/handler/SocketIOHandler.java
@@ -0,0 +1,104 @@
+package com.gxwebsoft.common.core.socketio.handler;
+
+import com.baomidou.mybatisplus.core.toolkit.StringUtils;
+import com.corundumstudio.socketio.AckRequest;
+import com.corundumstudio.socketio.SocketIOClient;
+import com.corundumstudio.socketio.annotation.OnConnect;
+import com.corundumstudio.socketio.annotation.OnDisconnect;
+import com.corundumstudio.socketio.annotation.OnEvent;
+import com.gxwebsoft.common.core.config.ConfigProperties;
+import com.gxwebsoft.common.core.socketio.cache.ClientCache;
+import com.gxwebsoft.common.system.entity.ChatMessage;
+import com.gxwebsoft.common.system.service.ChatConversationService;
+import com.gxwebsoft.common.system.service.ChatMessageService;
+import com.gxwebsoft.common.system.service.UserService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.annotation.Transactional;
+
+import javax.annotation.Resource;
+import java.util.UUID;
+
+
+/**
+ * socket处理拦截器
+ * @author machenike
+ */
+
+@Component
+public class SocketIOHandler {
+
+
+ @Resource
+ private ChatMessageService messageService;
+
+ @Resource
+ private ChatConversationService conversationService;
+
+ @Resource
+ private ClientCache clientCache;
+
+ @Resource
+ private UserService userService;
+
+ @Resource
+ private ConfigProperties configProperties;
+ /**
+ * 日志
+ */
+ private final static Logger logger = LoggerFactory.getLogger(SocketIOHandler.class);
+
+
+
+
+ /**
+ * 客户端连上socket服务器时执行此事件
+ * @param client
+ */
+ @OnConnect
+ public void onConnect(SocketIOClient client) {
+ String userId = client.getHandshakeData().getSingleUrlParam("userId");
+ logger.debug("socket client auth success [userId="+userId+"]");
+ UUID sessionId = client.getSessionId();
+
+
+ // 管理员
+ String isAdmin = client.getHandshakeData().getSingleUrlParam("isAdmin");
+ if(StringUtils.isNotBlank(isAdmin)){
+ // todo 权限验证
+ clientCache.saveClient("admin",sessionId, client);
+ }else {
+ clientCache.saveClient(userId,sessionId, client);
+ }
+
+ System.out.println("userId: "+userId+"连接建立成功 - "+sessionId);
+ logger.info("当前在线人数:{}",clientCache.getOnLineCount());
+
+ }
+
+
+ /**
+ * 客户端断开socket服务器时执行此事件
+ * @param client
+ */
+ @OnDisconnect
+ public void onDisconnect(SocketIOClient client) {
+ String userId = client.getHandshakeData().getSingleUrlParam("userId");
+ UUID sessionId = client.getSessionId();
+ clientCache.deleteSessionClientByUserId(userId,sessionId);
+ System.out.println("userId: "+userId+"连接关闭成功 - "+sessionId);
+
+ }
+
+ /**
+ *
+ * @param client
+ */
+ @OnEvent( value = "message")
+ @Transactional
+ public void onMessage(SocketIOClient client, AckRequest request, ChatMessage message) {
+
+ }
+
+}
diff --git a/src/main/java/com/gxwebsoft/common/core/utils/GreenWebUtils.java b/src/main/java/com/gxwebsoft/common/core/utils/GreenWebUtils.java
new file mode 100644
index 0000000..ea72c9f
--- /dev/null
+++ b/src/main/java/com/gxwebsoft/common/core/utils/GreenWebUtils.java
@@ -0,0 +1,317 @@
+package com.gxwebsoft.common.core.utils;
+
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson2.JSONObject;
+import com.alibaba.fastjson2.TypeReference;
+import com.aliyun.green20220302.Client;
+import com.aliyun.green20220302.models.*;
+import com.aliyun.teaopenapi.models.Config;
+import com.aliyun.teautil.models.RuntimeOptions;
+import com.gxwebsoft.common.core.enums.GreenWebType;
+import com.gxwebsoft.common.system.vo.faceId.HeadPortraitResult;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
+import org.apache.http.util.EntityUtils;
+import org.springframework.stereotype.Component;
+import org.springframework.util.StringUtils;
+
+import java.util.*;
+
+
+@Component
+public class GreenWebUtils {
+ private static Client contentGreenClient = null;
+
+ static final String accessKeyId = "LTAI5t8UTh8CTXEi2dYxobhj";
+ static final String accessKeySecret = "fNdJOT4KAjrVrzHNAcSJuUCy9ZljD9";
+
+ static final String[] badAudioLabel = {"violence", "political_content", "sexual_content", "sexual_sounds", "contraband", "profanity", "religion", "cyberbullying", "negative_content", "specified_speaking", "specified_lyrics"};
+// static final String[] badVideoLabel = {"pornographic_adultContent","pornographic_adultToys","pornographic_artwork","pornographic_adultContent_tii","sexual_suggestiveContent","sexual_breastNudity","sexual_cleavage","sexual_femaleUnderwear","sexual_maleTopless","sexual_femaleShoulder","sexual_cartoon","sexual_pregnancy","sexual_underage","political_politicalFigure_1","political_politicalFigure_2","political_politicalFigure_3","political_politicalFigure_name_tii",""};
+
+ private static class ContentGreenClientHolder {
+ private static final Client INSTANCE = createContentGreenClient();
+ }
+
+ private static Client createContentGreenClient() {
+ Config config = new Config();
+ config.setAccessKeyId(accessKeyId);
+ config.setAccessKeySecret(accessKeySecret);
+ config.setRegionId("cn-shenzhen");
+ config.setEndpoint("green-cip.cn-shenzhen.aliyuncs.com");
+ config.setReadTimeout(6000);
+ config.setConnectTimeout(3000);
+ try {
+ return new Client(config);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+
+ public static Client getContentGreenClient() {
+
+ if (contentGreenClient == null) {
+ contentGreenClient = ContentGreenClientHolder.INSTANCE;
+ }
+ return contentGreenClient;
+ }
+
+ /**
+ * 文本审核
+ *
+ * @param text
+ * @param type
+ * @return
+ */
+ public static boolean testText(String text, GreenWebType type) {
+ if (!StringUtils.hasText(text)) {
+ return false;
+ }
+
+ JSONObject serviceParameters = new JSONObject();
+ serviceParameters.put("content", text);
+
+ // 创建RuntimeObject实例并设置运行参数。
+ RuntimeOptions runtime = new RuntimeOptions();
+ runtime.readTimeout = 10000;
+ runtime.connectTimeout = 10000;
+
+ TextModerationRequest textModerationRequest = new TextModerationRequest();
+ textModerationRequest.setService(type.name());
+ textModerationRequest.setServiceParameters(serviceParameters.toJSONString());
+
+// try {
+ TextModerationResponse response = null;
+ try {
+ response = getContentGreenClient().textModerationWithOptions(textModerationRequest, runtime);
+ } catch (Exception e) {
+ e.printStackTrace();
+ return false;
+ }
+ if (response.statusCode != 200) {
+ return false;
+ }
+
+ TextModerationResponseBody result = response.getBody();
+ Integer code = result.getCode();
+ if (code != null && code == 200) {
+ TextModerationResponseBody.TextModerationResponseBodyData data = result.getData();
+ return !StringUtils.hasText(data.getReason());
+
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * 图片审核
+ *
+ * @param imgUrl
+ * @param type
+ * @return
+ */
+
+ public static boolean testImage(String imgUrl, GreenWebType type) {
+
+ if(!imgUrl.contains("?x-oss-process=image/resize")) {
+ imgUrl += "?x-oss-process=image/resize,w_750/quality,Q_90";
+ }
+
+ Map serviceParameters = new HashMap<>();
+ //公网可访问的URL。
+ serviceParameters.put("imageUrl", imgUrl);
+ serviceParameters.put("dataId", UUID.randomUUID().toString());
+
+ ImageModerationRequest request = new ImageModerationRequest();
+ // 图片检测service: baselineCheck通用基线检测。
+ request.setService(type.name());
+ request.setServiceParameters(JSON.toJSONString(serviceParameters));
+
+ RuntimeOptions runtime = new RuntimeOptions();
+ runtime.readTimeout = 10000;
+ runtime.connectTimeout = 10000;
+ ImageModerationResponse response = null;
+ try {
+ response = getContentGreenClient().imageModerationWithOptions(request, runtime);
+ System.out.println(response);
+ } catch (Exception e) {
+ e.printStackTrace();
+ return false;
+ }
+
+ ImageModerationResponseBody body = response.getBody();
+
+ String[] unSafeLabelArr = {"pornographic_adultContent_tii","pornographic_adultContent","sexual_suggestiveContent",""};
+ if (body.getCode() == 200) {
+ ImageModerationResponseBody.ImageModerationResponseBodyData data = body.getData();
+ System.out.println("dataId=" + data.getDataId());
+ List results = data.getResult();
+ for (ImageModerationResponseBody.ImageModerationResponseBodyDataResult result : results) {
+
+ if (!"nonLabel".equals(result.getLabel())) {
+ System.out.println(String.format("Label: %s,Confidence: %f",result.getLabel(),result.getConfidence()));
+ return false;
+ }
+ }
+ } else {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * 视频审核(异步)
+ *
+ * @param videoUrl
+ * @param type
+ * @return
+ */
+ public static String testVideo(String videoUrl, GreenWebType type) {
+
+ JSONObject serviceParameters = new JSONObject();
+ serviceParameters.put("url", videoUrl);
+
+ VideoModerationRequest videoModerationRequest = new VideoModerationRequest();
+ // 检测类型:videoDetection
+ videoModerationRequest.setService(type.name());
+ videoModerationRequest.setServiceParameters(serviceParameters.toJSONString());
+
+
+ try {
+ VideoModerationResponse response = getContentGreenClient().videoModeration(videoModerationRequest);
+ if (response.getStatusCode() == 200) {
+ VideoModerationResponseBody result = response.getBody();
+ System.out.println(JSON.toJSONString(result));
+ System.out.println("requestId = " + result.getRequestId());
+ System.out.println("code = " + result.getCode());
+ System.out.println("msg = " + result.getMessage());
+ Integer code = result.getCode();
+ if (200 == code) {
+ VideoModerationResponseBody.VideoModerationResponseBodyData data = result.getData();
+ return data.taskId;
+ } else {
+ return null;
+ }
+ } else {
+ return null;
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ return null;
+ }
+
+ }
+
+ /**
+ * 获取视频审核结果
+ *
+ * @param taskId
+ * @param type
+ * @return
+ */
+ public static boolean getTestVideoResult(String taskId, GreenWebType type) {
+
+
+ JSONObject serviceParameters = new JSONObject();
+ // 提交任务时返回的taskId。
+ serviceParameters.put("taskId", taskId);
+ VideoModerationResultRequest videoModerationResultRequest = new VideoModerationResultRequest();
+ videoModerationResultRequest.setService(type.name());
+ videoModerationResultRequest.setServiceParameters(serviceParameters.toJSONString());
+ try {
+ VideoModerationResultResponse response = getContentGreenClient().videoModerationResult(videoModerationResultRequest);
+ if (response.getStatusCode() == 200) {
+ VideoModerationResultResponseBody result = response.getBody();
+ System.out.println("requestId=" + result.getRequestId());
+ System.out.println("code=" + result.getCode());
+ System.out.println("msg=" + result.getMessage());
+ if (200 == result.getCode()) {
+ VideoModerationResultResponseBody.VideoModerationResultResponseBodyData data = result.getData();
+ VideoModerationResultResponseBody.VideoModerationResultResponseBodyDataAudioResult audioResult = data.getAudioResult();
+ VideoModerationResultResponseBody.VideoModerationResultResponseBodyDataFrameResult frameResult = data.getFrameResult();
+ boolean hasBadAudio = audioResult.sliceDetails.stream().filter(w -> {
+ String labels = w.getLabels();
+ String[] labelArr = labels.split(",");
+ return Arrays.stream(labelArr).filter(l -> {
+ return Arrays.stream(badAudioLabel).filter(b -> b.equals(l)).findFirst().isPresent();
+ }).findFirst().isPresent();
+ }).findFirst().isPresent();
+ if (hasBadAudio) {
+ return false;
+ }
+ boolean hasBadVideo = frameResult.getFrames().stream().filter(w -> {
+ return w.getResults().stream().filter(r -> {
+ return r.getResult().stream().filter(r2 -> {
+ return !"nonLabel".equals(r2.label);
+ }).findFirst().isPresent();
+ }).findFirst().isPresent();
+ }).findFirst().isPresent();
+ if (hasBadVideo) {
+ return false;
+ }
+ } else {
+ return false;
+ }
+ } else {
+ return false;
+ }
+ } catch (Exception e) {
+ return false;
+ }
+ return true;
+ }
+
+
+ /**
+ * 鉴别头像是否是真人头像(非卡通) 2. 鉴别图片是否有性感,色情信息 3. 鉴别头像是否有广告,敏感信息,以及二维码等 4. 鉴别头像性别。
+ *
+ * @param imageBase64
+ * @param imageType
+ * @param genter
+ * @return
+ */
+ public static boolean testAvatar(String imageBase64, String imageType, Integer genter) {
+ String host = "https://edishead.market.alicloudapi.com";
+ String path = "/faceId/headPortrait/getResult";
+ String method = "POST";
+ String appcode = "566b5786c5874464909d8c0b7f64cdc7";
+ Map headers = new HashMap();
+ //最后在header中的格式(中间是英文空格)为Authorization:APPCODE 83359fd73fe94948385f570e3c139105
+ headers.put("Authorization", "APPCODE " + appcode);
+ //根据API的要求,定义相对应的Content-Type
+ headers.put("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
+ Map querys = new HashMap();
+ Map bodys = new HashMap();
+ bodys.put("image", imageBase64);
+ bodys.put("imageType", imageType);
+ HttpResponse response = null;
+ try {
+ response = HttpUtils.doPost(host, path, method, headers, querys, bodys);
+ HttpEntity entity = response.getEntity();
+ String string = EntityUtils.toString(entity);
+ HeadPortraitResult result = JSONObject.parseObject(string, new TypeReference() {
+ });
+ if (!"0000".equals(result.getCode())) {
+ return false;
+ }
+ if (!"normal".equals(result.getPorn()) || !"normal".equals(result.getAd())) {
+ return false;
+ }
+ if (result.getFaceCount() != 1 || result.getCartoonImg()) {
+ return false;
+ }
+
+ if (!genter.equals(result.getGenterList()[0])) {
+ return false;
+ }
+
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ return false;
+ }
+ System.out.println(response.toString());
+ return true;
+ }
+}
diff --git a/src/main/java/com/gxwebsoft/common/core/utils/PushUtil.java b/src/main/java/com/gxwebsoft/common/core/utils/PushUtil.java
new file mode 100644
index 0000000..fadf410
--- /dev/null
+++ b/src/main/java/com/gxwebsoft/common/core/utils/PushUtil.java
@@ -0,0 +1,96 @@
+package com.gxwebsoft.common.core.utils;
+
+import cn.hutool.crypto.SecureUtil;
+import cn.hutool.http.HttpRequest;
+import com.alibaba.fastjson.JSONObject;
+import com.gxwebsoft.common.system.service.UserService;
+import com.gxwebsoft.common.system.vo.PushMessageVO;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * 个推推送消息工具类
+ *
+ * @author WebSoft
+ * @since 2017-06-10 10:10:39
+ */
+@Component
+public class PushUtil {
+ @Resource
+ RedisUtil redisUtil;
+
+ @Resource
+ private UserService userService;
+ private static final String url = "https://fc-mp-ba98f1e0-713d-457b-a0a4-27a7939371e6.next.bspapp.com/unipush";
+
+ /**
+ * 获取鉴权token
+ * @return
+ */
+ public String getToken() {
+ String key = "token:oOVaDtYDYQ8q3lNjhLh401";
+
+ if(redisUtil.get(key) != null){
+ return redisUtil.get(key);
+ }
+
+ HashMap map = new HashMap<>();
+ long timeMillis = System.currentTimeMillis();
+ String sign = SecureUtil.sha256("AC6IghgsUx7Mwjb7G5eqv" + timeMillis + "JVRkOCXXzA6EyE2Fi5sPr9");
+ map.put("sign",sign);
+ map.put("timestamp",timeMillis);
+ map.put("appkey","AC6IghgsUx7Mwjb7G5eqv");
+ final String body = HttpRequest.post(url.concat("/auth")).body(JSONUtil.toJSONString(map)).execute().body();
+ final JSONObject jsonObject = JSONObject.parseObject(body);
+ final String data = jsonObject.getString("data");
+ final JSONObject jsonData = JSONObject.parseObject(data);
+
+ final String token = jsonData.getString("token");
+ final Long expireTime = Long.valueOf(jsonData.getString("expire_time"));
+ // 保存token
+
+ redisUtil.set(key,token, expireTime-System.currentTimeMillis(), TimeUnit.MILLISECONDS);
+ return token;
+ }
+
+ /**
+ * 执行cid单推
+ * cid数组,只能填一个cid
+ *
+ */
+ public static boolean toSingle(PushMessageVO pushMessageVO){
+ final String body = HttpRequest.post(url).body(JSONUtil.toJSONString(pushMessageVO)).execute().body();
+ JSONObject jsonObject = JSONObject.parseObject(body);
+ if("success".equals(jsonObject.get("errMsg"))){
+ return true;
+ }
+ return false;
+ }
+
+
+ public boolean toSingle(Integer userId,String title, String content,String type, Object obj){
+ PushMessageVO.Payload payload = new PushMessageVO.Payload();
+ payload.setType(type);
+ payload.setData(obj);
+
+ String clientId = userService.getById(userId).getClientId();
+ HashSet clientIds = new HashSet<>();
+ clientIds.add(clientId);
+
+ PushMessageVO messageVO = PushMessageVO.builder().title(title).content(content).payload(payload).push_clientid(clientIds).build();
+
+ final String body = HttpRequest.post(url).body(JSONUtil.toJSONString(messageVO)).execute().body();
+
+ JSONObject jsonObject = JSONObject.parseObject(body);
+ if("success".equals(jsonObject.get("errMsg"))){
+ return true;
+ }
+ return false;
+ }
+
+
+}
diff --git a/src/main/java/com/gxwebsoft/common/system/controller/ChatConversationController.java b/src/main/java/com/gxwebsoft/common/system/controller/ChatConversationController.java
new file mode 100644
index 0000000..21d154e
--- /dev/null
+++ b/src/main/java/com/gxwebsoft/common/system/controller/ChatConversationController.java
@@ -0,0 +1,158 @@
+package com.gxwebsoft.common.system.controller;
+
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.gxwebsoft.common.core.annotation.OperationLog;
+import com.gxwebsoft.common.core.web.*;
+import com.gxwebsoft.common.system.entity.ChatConversation;
+import com.gxwebsoft.common.system.entity.User;
+import com.gxwebsoft.common.system.param.ChatConversationParam;
+import com.gxwebsoft.common.system.service.ChatConversationService;
+import com.gxwebsoft.common.system.vo.ChatConversationVO;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import java.util.List;
+
+/**
+ * 聊天消息表控制器
+ *
+ * @author 科技小王子
+ * @since 2023-06-15 21:26:48
+ */
+@Api(tags = "聊天消息表管理")
+@RestController
+@RequestMapping("/api/system/chat-conversation")
+public class ChatConversationController extends BaseController {
+ @Resource
+ private ChatConversationService chatConversationService;
+
+ @PreAuthorize("hasAuthority('sys:notice:list')")
+ @OperationLog
+ @ApiOperation("查询全部聊天消息表")
+ @GetMapping("/app")
+ public ApiResult> appList() {
+ ChatConversationParam param = new ChatConversationParam();
+ param.setUserId(getLoginUserId());
+ return success(chatConversationService.getFriendList(param));
+ }
+
+ @OperationLog
+ @ApiOperation("标记已读")
+ @PostMapping("/app/read")
+ public ApiResult read(@RequestBody ChatConversationParam param) {
+ return success(chatConversationService.update(
+ new LambdaUpdateWrapper().eq(ChatConversation::getId, param.getId()).set(ChatConversation::getUnRead, 0)
+ ));
+ // 使用关联查询
+ //return success(chatConversationService.pageRel(param));
+ }
+
+
+ @PreAuthorize("hasAuthority('sys:notice:list')")
+ @OperationLog
+ @ApiOperation("分页查询聊天消息表")
+ @GetMapping("/page")
+ public ApiResult> page(ChatConversationParam param) {
+ PageParam page = new PageParam<>(param);
+ page.setDefaultOrder("create_time desc");
+// return success(chatConversationService.page(page, page.getWrapper()));
+ // 使用关联查询
+ return success(chatConversationService.pageRel(param));
+ }
+
+ @PreAuthorize("hasAuthority('sys:notice:list')")
+ @OperationLog
+ @ApiOperation("查询全部聊天消息表")
+ @GetMapping()
+ public ApiResult> list(ChatConversationParam param) {
+ PageParam page = new PageParam<>(param);
+ page.setDefaultOrder("create_time desc");
+// return success(chatConversationService.list(page.getOrderWrapper()));
+ // 使用关联查询
+ return success(chatConversationService.listRel(param));
+ }
+
+ @PreAuthorize("hasAuthority('sys:notice:list')")
+ @OperationLog
+ @ApiOperation("根据id查询聊天消息表")
+ @GetMapping("/{id}")
+ public ApiResult get(@PathVariable("id") Integer id) {
+ return success(chatConversationService.getById(id));
+ // 使用关联查询
+ //return success(chatConversationService.getByIdRel(id));
+ }
+
+ @PreAuthorize("hasAuthority('sys:notice:save')")
+ @OperationLog
+ @ApiOperation("添加聊天消息表")
+ @PostMapping()
+ public ApiResult> save(@RequestBody ChatConversation chatConversation) {
+ // 记录当前登录用户id
+ User loginUser = getLoginUser();
+ if (loginUser != null) {
+ chatConversation.setUserId(loginUser.getUserId());
+ }
+ if (chatConversationService.save(chatConversation)) {
+ return success("添加成功");
+ }
+ return fail("添加失败");
+ }
+
+ @PreAuthorize("hasAuthority('sys:notice:update')")
+ @OperationLog
+ @ApiOperation("修改聊天消息表")
+ @PutMapping()
+ public ApiResult> update(@RequestBody ChatConversation chatConversation) {
+ if (chatConversationService.updateById(chatConversation)) {
+ return success("修改成功");
+ }
+ return fail("修改失败");
+ }
+
+ @OperationLog
+ @ApiOperation("删除聊天消息表")
+ @DeleteMapping("/{id}")
+ public ApiResult> remove(@PathVariable("id") Integer id) {
+ if (chatConversationService.removeById(id)) {
+ return success("删除成功");
+ }
+ return fail("删除失败");
+ }
+
+ @PreAuthorize("hasAuthority('sys:notice:save')")
+ @OperationLog
+ @ApiOperation("批量添加聊天消息表")
+ @PostMapping("/batch")
+ public ApiResult> saveBatch(@RequestBody List list) {
+ if (chatConversationService.saveBatch(list)) {
+ return success("添加成功");
+ }
+ return fail("添加失败");
+ }
+
+ @PreAuthorize("hasAuthority('sys:notice:update')")
+ @OperationLog
+ @ApiOperation("批量修改聊天消息表")
+ @PutMapping("/batch")
+ public ApiResult> removeBatch(@RequestBody BatchParam batchParam) {
+ if (batchParam.update(chatConversationService, "id")) {
+ return success("修改成功");
+ }
+ return fail("修改失败");
+ }
+
+ @PreAuthorize("hasAuthority('sys:notice:remove')")
+ @OperationLog
+ @ApiOperation("批量删除聊天消息表")
+ @DeleteMapping("/batch")
+ public ApiResult> removeBatch(@RequestBody List ids) {
+ if (chatConversationService.removeByIds(ids)) {
+ return success("删除成功");
+ }
+ return fail("删除失败");
+ }
+
+}
diff --git a/src/main/java/com/gxwebsoft/common/system/controller/ChatMessageController.java b/src/main/java/com/gxwebsoft/common/system/controller/ChatMessageController.java
new file mode 100644
index 0000000..3701598
--- /dev/null
+++ b/src/main/java/com/gxwebsoft/common/system/controller/ChatMessageController.java
@@ -0,0 +1,249 @@
+package com.gxwebsoft.common.system.controller;
+
+import cn.hutool.core.date.DateUtil;
+import com.gxwebsoft.common.core.annotation.OperationLog;
+import com.gxwebsoft.common.core.enums.GreenWebType;
+import com.gxwebsoft.common.core.socketio.cache.ClientCache;
+import com.gxwebsoft.common.core.utils.GreenWebUtils;
+import com.gxwebsoft.common.core.web.*;
+import com.gxwebsoft.common.system.entity.ChatConversation;
+import com.gxwebsoft.common.system.entity.User;
+import com.gxwebsoft.common.system.entity.ChatMessage;
+import com.gxwebsoft.common.system.param.ChatMessageParam;
+import com.gxwebsoft.common.system.service.ChatConversationService;
+import com.gxwebsoft.common.system.service.ChatMessageService;
+import com.gxwebsoft.common.system.service.UserService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.util.CollectionUtils;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import java.util.List;
+
+/**
+ * 聊天消息表控制器
+ *
+ * @author 科技小王子
+ * @since 2023-06-10 18:27:25
+ */
+@Api(tags = "聊天消息表管理")
+@RestController
+@RequestMapping("/api/system/chat-message")
+public class ChatMessageController extends BaseController {
+ @Resource
+ private ChatMessageService chatMessageService;
+
+ @Resource
+ private ChatConversationService chatConversationService;
+
+ @Resource
+ private UserService userService;
+
+
+ @Resource
+ private ClientCache clientCache;
+
+ @OperationLog
+ @ApiOperation("发送消息:app端使用")
+ @PostMapping("/app/send")
+ public ApiResult> sendMessage(@RequestBody ChatMessage message) {
+
+ String type = message.getType();
+ if ("text".equals(type) && !GreenWebUtils.testText(message.getContent(), GreenWebType.chat_detection)) {
+ return fail("您的内容存在违规行为,请您重新编辑!");
+ } else if ("image".equals(type) && !GreenWebUtils.testImage(message.getContent(), GreenWebType.baselineCheck)) {
+ return fail("您的内容存在违规行为,请您重新编辑!");
+ }
+
+ User loginUser = getLoginUser();
+ message.setFormUserId(getLoginUserId());
+ message.setFormUserInfo(loginUser);
+ chatMessageService.sendMessage(message);
+ return success(message.getId());
+ }
+
+ @OperationLog
+ @ApiOperation("消息列表")
+ @GetMapping("/app/list")
+ public ApiResult> listApp(Integer friendId, Integer lastMessageId) {
+
+ return success(chatMessageService.getFriendMessage(getLoginUserId(), friendId, lastMessageId));
+ }
+
+ @PreAuthorize("hasAuthority('sys:notice:list')")
+ @OperationLog
+ @ApiOperation("分页查询聊天消息表")
+ @GetMapping("/page")
+ public ApiResult> page(ChatMessageParam param) {
+ PageParam page = new PageParam<>(param);
+ page.setDefaultOrder("create_time desc");
+// return success(chatMessageService.page(page, page.getWrapper()));
+ // 使用关联查询
+ return success(chatMessageService.pageRel(param));
+ }
+
+
+ @PreAuthorize("hasAuthority('sys:notice:list')")
+ @OperationLog
+ @ApiOperation("查询全部聊天消息表")
+ @GetMapping()
+ public ApiResult> list(ChatMessageParam param) {
+ PageParam page = new PageParam<>(param);
+ page.setDefaultOrder("create_time desc");
+ return success(chatMessageService.list(page.getOrderWrapper()));
+ // 使用关联查询
+ //return success(chatMessageService.listRel(param));
+ }
+
+ @PreAuthorize("hasAuthority('sys:notice:list')")
+ @OperationLog
+ @ApiOperation("根据id查询聊天消息表")
+ @GetMapping("/{id}")
+ public ApiResult get(@PathVariable("id") Integer id) {
+ return success(chatMessageService.getById(id));
+ // 使用关联查询
+ //return success(chatMessageService.getByIdRel(id));
+ }
+
+ @PreAuthorize("hasAuthority('sys:notice:save')")
+ @OperationLog
+ @ApiOperation("添加聊天消息表 管理员使用")
+ @PostMapping()
+ public ApiResult> save(@RequestBody ChatMessage message) {
+ // 记录当前登录用户id
+ User loginUser = getLoginUser();
+ User fromUser = userService.getById(message.getFormUserId());
+ message.setFormUserInfo(fromUser);
+ if (chatMessageService.sendMessage(message)) {
+ return success("发送成功");
+ }
+ return fail("添加失败");
+ }
+
+ @PreAuthorize("hasAuthority('sys:notice:update')")
+ @OperationLog
+ @ApiOperation("修改聊天消息表")
+ @PutMapping()
+ public ApiResult> update(@RequestBody ChatMessage chatMessage) {
+ if (chatMessageService.updateById(chatMessage)) {
+ return success("修改成功");
+ }
+ return fail("修改失败");
+ }
+
+ @PreAuthorize("hasAuthority('sys:notice:remove')")
+ @OperationLog
+ @ApiOperation("删除聊天消息表")
+ @DeleteMapping("/{id}")
+ public ApiResult> remove(@PathVariable("id") Integer id) {
+ if (chatMessageService.removeById(id)) {
+ return success("删除成功");
+ }
+ return fail("删除失败");
+ }
+
+ @PreAuthorize("hasAuthority('sys:notice:save')")
+ @OperationLog
+ @ApiOperation("批量添加聊天消息表")
+ @PostMapping("/batch")
+ public ApiResult> saveBatch(@RequestBody List list) {
+ if (chatMessageService.saveBatch(list)) {
+ return success("添加成功");
+ }
+ return fail("添加失败");
+ }
+
+ @PreAuthorize("hasAuthority('sys:notice:update')")
+ @OperationLog
+ @ApiOperation("批量修改聊天消息表")
+ @PutMapping("/batch")
+ public ApiResult> removeBatch(@RequestBody BatchParam batchParam) {
+ if (batchParam.update(chatMessageService, "id")) {
+ return success("修改成功");
+ }
+ return fail("修改失败");
+ }
+
+ @PreAuthorize("hasAuthority('sys:notice:remove')")
+ @OperationLog
+ @ApiOperation("批量删除聊天消息表")
+ @DeleteMapping("/batch")
+ public ApiResult> removeBatch(@RequestBody List ids) {
+ if (chatMessageService.removeByIds(ids)) {
+ return success("删除成功");
+ }
+ return fail("删除失败");
+ }
+
+ @ApiOperation("屏蔽消息")
+ @PutMapping("/sideMessage")
+ public ApiResult> sideMessage(@RequestBody ChatMessage chatMessage) {
+ ChatMessage msg = chatMessageService.getById(chatMessage.getId());
+ Integer loginUserId = getLoginUserId();
+ Integer toUserId = chatMessage.getToUserId();
+
+ if (msg.getToUserId().equals(loginUserId)) {
+ msg.setSideTo(true);
+ } else if (msg.getFormUserId().equals(loginUserId)) {
+ msg.setSideFrom(true);
+ }
+ chatMessageService.updateById(msg);
+
+
+ ChatConversation conversation1 = chatConversationService.getByBothId(loginUserId, toUserId);
+ List friendMessage = chatMessageService.getFriendMessage(loginUserId, toUserId, null);
+ conversation1.setUpdateTime(DateUtil.date());
+ if(CollectionUtils.isEmpty(friendMessage)){
+ conversation1.setContent("");
+ }else {
+ String lastContent;
+ ChatMessage lastMessage = friendMessage.get(0);
+ if (GreenWebType.ChatMessageType.IMAGE.getName().equals(lastMessage.getType())) {
+ lastContent = "[图片]";
+ } else if (GreenWebType.ChatMessageType.VOICE.getName().equals(lastMessage.getType())) {
+ lastContent = "[语音]";
+ } else if (GreenWebType.ChatMessageType.CARD.getName().equals(lastMessage.getType())) {
+ lastContent = "[卡片]";
+ } else {
+ lastContent = lastMessage.getContent();
+ }
+ conversation1.setContent(lastContent);
+ }
+
+ return success("屏蔽成功");
+
+
+ }
+
+ @ApiOperation("撤回消息")
+ @PutMapping("/withdraw")
+ public ApiResult> withdraw(@RequestBody ChatMessage chatMessage) {
+
+
+ Integer loginUserId = getLoginUserId();
+ Integer toUserId = chatMessage.getToUserId();
+
+ chatMessage.setWithdraw(1);
+
+ if (chatMessageService.updateById(chatMessage)) {
+ clientCache.sendUserEvent(toUserId + "", "withdrawMessage", chatMessage);
+
+ }
+
+ ChatConversation conversation1 = chatConversationService.getByBothId(loginUserId, toUserId);
+ conversation1.setContent("您撤回了一条消息");
+ conversation1.setUpdateTime(DateUtil.date());
+ ChatConversation conversation2 = chatConversationService.getByBothId(toUserId, loginUserId);
+ conversation2.setContent("对方撤回了一条消息");
+ conversation2.setUpdateTime(DateUtil.date());
+
+ chatConversationService.updateById(conversation1);
+ chatConversationService.updateById(conversation2);
+
+
+ return success("您撤回了一条消息");
+ }
+
+}
diff --git a/src/main/java/com/gxwebsoft/common/system/controller/MainController.java b/src/main/java/com/gxwebsoft/common/system/controller/MainController.java
index 268bc61..e4bf617 100644
--- a/src/main/java/com/gxwebsoft/common/system/controller/MainController.java
+++ b/src/main/java/com/gxwebsoft/common/system/controller/MainController.java
@@ -136,6 +136,8 @@ public class MainController extends BaseController {
// 签发token
String access_token = JwtUtil.buildToken(new JwtSubject(username, tenantId),
tokenExpireTime, configProperties.getTokenKey());
+ // 同步redis
+ redisUtil.set("access_token:" + user.getUserId(),access_token,tokenExpireTime,TimeUnit.SECONDS);
return success("登录成功", new LoginResult(access_token, user));
}
@@ -275,19 +277,21 @@ public class MainController extends BaseController {
@PostMapping("/sendSmsCaptcha")
public ApiResult> sendSmsCaptcha(@RequestBody SmsCaptchaParam param) {
// 默认配置
- String accessKeyId = "LTAI5tBH45bs2fys3fav";
- String accessKeySecret = "FpDRt8ejUtuz0fHDkW52";
+ String accessKeyId = "LTAI5tEsyhW4GCKbds1qsopg";
+ String accessKeySecret = "zltFlQrYVAoq2KMFDWgLa3GhkMNeyO";
String userTemplateId = "SMS_257840118";
String sign = "南宁网宿科技";
// 读取租户的短信配置
- String string = redisUtil.get("setting:sms:5");
- if (string != null) {
- JSONObject jsonObject = JSONObject.parseObject(string);
- accessKeyId = jsonObject.getString("accessKeyId");
- accessKeySecret = jsonObject.getString("accessKeySecret");
- userTemplateId = jsonObject.getString("userTemplateId");
- sign = jsonObject.getString("sign");
+ if (getTenantId() != null) {
+ String string = redisUtil.get("setting:sms:" + getTenantId());
+ if (string != null) {
+ JSONObject jsonObject = JSONObject.parseObject(string);
+ accessKeyId = jsonObject.getString("accessKeyId");
+ accessKeySecret = jsonObject.getString("accessKeySecret");
+ userTemplateId = jsonObject.getString("userTemplateId");
+ sign = jsonObject.getString("sign");
+ }
}
DefaultProfile profile = DefaultProfile.getProfile("regionld", accessKeyId, accessKeySecret);
@@ -491,7 +495,7 @@ public class MainController extends BaseController {
final Company company = new Company();
company.setTenantId(tenant.getTenantId());
company.setShortName(tenantName);
- company.setCompanyLogo(tenant.getTenantId().toString().concat("/logo.svg"));
+ company.setCompanyLogo("/logo.svg");
company.setPhone(phone);
company.setMembers(20);
company.setVersion(10);
@@ -739,6 +743,14 @@ public class MainController extends BaseController {
menu.setSortNumber(7);
menuService.save(menu);
menu.setParentId(parentId);
+ menu.setTitle("模块管理");
+ menu.setPath("/system/modules");
+ menu.setComponent("/system/modules");
+ menu.setIcon("KeyOutlined");
+ menu.setAuthority("sys:modules:list");
+ menu.setSortNumber(7);
+ menuService.save(menu);
+ menu.setParentId(parentId);
menu.setTitle("秘钥管理");
menu.setPath("/system/access-key");
menu.setComponent("/system/access-key");
diff --git a/src/main/java/com/gxwebsoft/common/system/controller/ModulesController.java b/src/main/java/com/gxwebsoft/common/system/controller/ModulesController.java
new file mode 100644
index 0000000..706a3e9
--- /dev/null
+++ b/src/main/java/com/gxwebsoft/common/system/controller/ModulesController.java
@@ -0,0 +1,139 @@
+package com.gxwebsoft.common.system.controller;
+
+import com.gxwebsoft.common.core.web.BaseController;
+import com.gxwebsoft.common.system.entity.User;
+import com.gxwebsoft.common.system.service.ModulesService;
+import com.gxwebsoft.common.system.entity.Modules;
+import com.gxwebsoft.common.system.param.ModulesParam;
+import com.gxwebsoft.common.core.web.ApiResult;
+import com.gxwebsoft.common.core.web.PageResult;
+import com.gxwebsoft.common.core.web.PageParam;
+import com.gxwebsoft.common.core.web.BatchParam;
+import com.gxwebsoft.common.core.annotation.OperationLog;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import java.util.List;
+
+/**
+ * 模块管理控制器
+ *
+ * @author 科技小王子
+ * @since 2023-10-18 15:53:43
+ */
+@Api(tags = "模块管理管理")
+@RestController
+@RequestMapping("/api/system/modules")
+public class ModulesController extends BaseController {
+ @Resource
+ private ModulesService modulesService;
+
+ @PreAuthorize("hasAuthority('sys:modules:list')")
+ @OperationLog
+ @ApiOperation("分页查询模块管理")
+ @GetMapping("/page")
+ public ApiResult> page(ModulesParam param) {
+ PageParam page = new PageParam<>(param);
+// page.setDefaultOrder("create_time desc");
+ return success(modulesService.page(page, page.getWrapper()));
+ // 使用关联查询
+ //return success(modulesService.pageRel(param));
+ }
+
+ @PreAuthorize("hasAuthority('sys:modules:list')")
+ @OperationLog
+ @ApiOperation("查询全部模块管理")
+ @GetMapping()
+ public ApiResult> list(ModulesParam param) {
+ PageParam page = new PageParam<>(param);
+// page.setDefaultOrder("create_time desc");
+ return success(modulesService.list(page.getOrderWrapper()));
+ // 使用关联查询
+ //return success(modulesService.listRel(param));
+ }
+
+ @PreAuthorize("hasAuthority('sys:modules:list')")
+ @OperationLog
+ @ApiOperation("根据id查询模块管理")
+ @GetMapping("/{id}")
+ public ApiResult get(@PathVariable("id") Integer id) {
+ return success(modulesService.getById(id));
+ // 使用关联查询
+ //return success(modulesService.getByIdRel(id));
+ }
+
+ @PreAuthorize("hasAuthority('sys:modules:save')")
+ @OperationLog
+ @ApiOperation("添加模块管理")
+ @PostMapping()
+ public ApiResult> save(@RequestBody Modules modules) {
+ // 记录当前登录用户id
+ User loginUser = getLoginUser();
+ if (loginUser != null) {
+ modules.setUserId(loginUser.getUserId());
+ }
+ if (modulesService.save(modules)) {
+ return success("添加成功");
+ }
+ return fail("添加失败");
+ }
+
+ @PreAuthorize("hasAuthority('sys:modules:update')")
+ @OperationLog
+ @ApiOperation("修改模块管理")
+ @PutMapping()
+ public ApiResult> update(@RequestBody Modules modules) {
+ if (modulesService.updateById(modules)) {
+ return success("修改成功");
+ }
+ return fail("修改失败");
+ }
+
+ @PreAuthorize("hasAuthority('sys:modules:remove')")
+ @OperationLog
+ @ApiOperation("删除模块管理")
+ @DeleteMapping("/{id}")
+ public ApiResult> remove(@PathVariable("id") Integer id) {
+ if (modulesService.removeById(id)) {
+ return success("删除成功");
+ }
+ return fail("删除失败");
+ }
+
+ @PreAuthorize("hasAuthority('sys:modules:save')")
+ @OperationLog
+ @ApiOperation("批量添加模块管理")
+ @PostMapping("/batch")
+ public ApiResult> saveBatch(@RequestBody List list) {
+ if (modulesService.saveBatch(list)) {
+ return success("添加成功");
+ }
+ return fail("添加失败");
+ }
+
+ @PreAuthorize("hasAuthority('sys:modules:update')")
+ @OperationLog
+ @ApiOperation("批量修改模块管理")
+ @PutMapping("/batch")
+ public ApiResult> removeBatch(@RequestBody BatchParam batchParam) {
+ if (batchParam.update(modulesService, "id")) {
+ return success("修改成功");
+ }
+ return fail("修改失败");
+ }
+
+ @PreAuthorize("hasAuthority('sys:modules:remove')")
+ @OperationLog
+ @ApiOperation("批量删除模块管理")
+ @DeleteMapping("/batch")
+ public ApiResult> removeBatch(@RequestBody List ids) {
+ if (modulesService.removeByIds(ids)) {
+ return success("删除成功");
+ }
+ return fail("删除失败");
+ }
+
+}
diff --git a/src/main/java/com/gxwebsoft/common/system/entity/ChatConversation.java b/src/main/java/com/gxwebsoft/common/system/entity/ChatConversation.java
new file mode 100644
index 0000000..f9af3a3
--- /dev/null
+++ b/src/main/java/com/gxwebsoft/common/system/entity/ChatConversation.java
@@ -0,0 +1,64 @@
+package com.gxwebsoft.common.system.entity;
+
+import com.baomidou.mybatisplus.annotation.*;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 聊天消息表
+ *
+ * @author 科技小王子
+ * @since 2023-06-15 21:26:48
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@ApiModel(value = "ChatConversation对象", description = "聊天消息表")
+@TableName("sys_chat_conversation")
+public class ChatConversation implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ @ApiModelProperty(value = "自增ID")
+ @TableId(value = "id", type = IdType.AUTO)
+ private Integer id;
+
+ @ApiModelProperty(value = "用户ID")
+ private Integer userId;
+
+ @ApiModelProperty(value = "好友ID")
+ private Integer friendId;
+
+ @TableField(exist = false)
+ @ApiModelProperty(value = "好友信息")
+ private User friendInfo;
+
+ @ApiModelProperty(value = "消息类型")
+ private Integer type;
+
+ @ApiModelProperty(value = "消息内容")
+ private String content;
+
+ @ApiModelProperty(value = "未读消息")
+ private int unRead;
+
+ @ApiModelProperty(value = "状态, 0未读, 1已读")
+ private Integer status;
+
+ @ApiModelProperty(value = "是否删除, 0否, 1是")
+ @TableLogic
+ private Integer deleted;
+
+ @ApiModelProperty(value = "租户id")
+ private Integer tenantId;
+
+ @ApiModelProperty(value = "注册时间")
+ private Date createTime;
+
+ @ApiModelProperty(value = "修改时间")
+ private Date updateTime;
+
+}
diff --git a/src/main/java/com/gxwebsoft/common/system/entity/ChatMessage.java b/src/main/java/com/gxwebsoft/common/system/entity/ChatMessage.java
new file mode 100644
index 0000000..68d6b98
--- /dev/null
+++ b/src/main/java/com/gxwebsoft/common/system/entity/ChatMessage.java
@@ -0,0 +1,90 @@
+package com.gxwebsoft.common.system.entity;
+
+import com.baomidou.mybatisplus.annotation.*;
+import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 聊天消息表
+ *
+ * @author 科技小王子
+ * @since 2023-06-10 18:27:25
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@ApiModel(value = "ChatMessage对象", description = "聊天消息表")
+@TableName(value = "sys_chat_message",autoResultMap = true)
+public class ChatMessage implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ @ApiModelProperty(value = "自增ID")
+ @TableId(value = "id", type = IdType.AUTO)
+ private Integer id;
+
+ @ApiModelProperty(value = "发送用户ID")
+ private Integer formUserId;
+
+ @ApiModelProperty(value = "接收人ID")
+ private Integer toUserId;
+
+ @ApiModelProperty(value = "发送人")
+ @TableField(exist = false)
+ private User formUserInfo;
+
+ @ApiModelProperty(value = "接收人")
+ @TableField(exist = false)
+ private User toUserInfo;
+
+ @ApiModelProperty(value = "消息类型")
+ private String type;
+
+ @ApiModelProperty(value = "消息内容")
+ private String content;
+
+ @ApiModelProperty(value = "文件信息")
+ @TableField(typeHandler = JacksonTypeHandler.class)
+ private FileInfo fileInfo;
+
+
+ @ApiModelProperty(value = "状态, 0未读, 1已读")
+ private Integer status;
+
+
+ @ApiModelProperty(value = "撤回")
+ private Integer withdraw;
+
+ @ApiModelProperty(value = "是否删除, 0否, 1是")
+ @TableLogic
+ private Integer deleted;
+
+ @ApiModelProperty(value = "租户id")
+ private Integer tenantId;
+
+ @ApiModelProperty(value = "注册时间")
+ private Date createTime;
+
+ @ApiModelProperty(value = "修改时间")
+ private Date updateTime;
+
+ private Boolean sideTo;
+ private Boolean sideFrom;
+
+
+ @Data
+ public static class FileInfo {
+
+ private Integer width;
+ private Integer height;
+ private String type;
+
+
+ }
+
+
+}
diff --git a/src/main/java/com/gxwebsoft/common/system/entity/Company.java b/src/main/java/com/gxwebsoft/common/system/entity/Company.java
index 17715b1..ac10c78 100644
--- a/src/main/java/com/gxwebsoft/common/system/entity/Company.java
+++ b/src/main/java/com/gxwebsoft/common/system/entity/Company.java
@@ -127,6 +127,21 @@ public class Company implements Serializable {
@ApiModelProperty(value = "是否实名认证")
private Integer authentication;
+ @ApiModelProperty(value = "request合法域名")
+ private String requestUrl;
+
+ @ApiModelProperty(value = "socket合法域名")
+ private String socketUrl;
+
+ @ApiModelProperty(value = "主控端域名")
+ private String serverUrl;
+
+ @ApiModelProperty(value = "业务域名")
+ private String modulesUrl;
+
+ @ApiModelProperty(value = "应用类型")
+ private String appType;
+
@ApiModelProperty(value = "状态")
private Integer status;
diff --git a/src/main/java/com/gxwebsoft/common/system/entity/Modules.java b/src/main/java/com/gxwebsoft/common/system/entity/Modules.java
new file mode 100644
index 0000000..a8c4e7a
--- /dev/null
+++ b/src/main/java/com/gxwebsoft/common/system/entity/Modules.java
@@ -0,0 +1,60 @@
+package com.gxwebsoft.common.system.entity;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableLogic;
+import java.io.Serializable;
+import java.util.Date;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 模块管理
+ *
+ * @author 科技小王子
+ * @since 2023-10-18 15:53:43
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@ApiModel(value = "Modules对象", description = "模块管理")
+@TableName("sys_modules")
+public class Modules implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ @ApiModelProperty(value = "插件id")
+ @TableId(value = "id", type = IdType.AUTO)
+ private Integer id;
+
+ @ApiModelProperty(value = "环境编号")
+ private String modules;
+
+ @ApiModelProperty(value = "模块访问地址")
+ private String modulesUrl;
+
+ @ApiModelProperty(value = "排序号")
+ private Integer sortNumber;
+
+ @ApiModelProperty(value = "备注")
+ private String comments;
+
+ @ApiModelProperty(value = "状态, 10待审核 20已通过 30已驳回")
+ private Integer status;
+
+ @ApiModelProperty(value = "用户ID")
+ private Integer userId;
+
+ @ApiModelProperty(value = "是否删除, 0否, 1是")
+ @TableLogic
+ private Integer deleted;
+
+ @ApiModelProperty(value = "租户id")
+ private Integer tenantId;
+
+ @ApiModelProperty(value = "创建时间")
+ private Date createTime;
+
+}
diff --git a/src/main/java/com/gxwebsoft/common/system/entity/User.java b/src/main/java/com/gxwebsoft/common/system/entity/User.java
index 5d82c2a..45d4325 100644
--- a/src/main/java/com/gxwebsoft/common/system/entity/User.java
+++ b/src/main/java/com/gxwebsoft/common/system/entity/User.java
@@ -160,6 +160,9 @@ public class User implements UserDetails {
@ApiModelProperty("获赞数")
private Integer likes;
+ @ApiModelProperty("客户端ID")
+ private String clientId;
+
@ApiModelProperty("评论数")
private Integer commentNumbers;
diff --git a/src/main/java/com/gxwebsoft/common/system/mapper/ChatConversationMapper.java b/src/main/java/com/gxwebsoft/common/system/mapper/ChatConversationMapper.java
new file mode 100644
index 0000000..a9029bc
--- /dev/null
+++ b/src/main/java/com/gxwebsoft/common/system/mapper/ChatConversationMapper.java
@@ -0,0 +1,38 @@
+package com.gxwebsoft.common.system.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.github.yulichang.base.MPJBaseMapper;
+import com.gxwebsoft.common.system.entity.ChatConversation;
+import com.gxwebsoft.common.system.param.ChatConversationParam;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * 聊天消息表Mapper
+ *
+ * @author 科技小王子
+ * @since 2023-10-18 18:42:17
+ */
+public interface ChatConversationMapper extends MPJBaseMapper {
+
+ /**
+ * 分页查询
+ *
+ * @param page 分页对象
+ * @param param 查询参数
+ * @return List
+ */
+ List selectPageRel(@Param("page") IPage page,
+ @Param("param") ChatConversationParam param);
+
+ /**
+ * 查询全部
+ *
+ * @param param 查询参数
+ * @return List
+ */
+ List selectListRel(@Param("param") ChatConversationParam param);
+
+}
diff --git a/src/main/java/com/gxwebsoft/common/system/mapper/ChatMessageMapper.java b/src/main/java/com/gxwebsoft/common/system/mapper/ChatMessageMapper.java
new file mode 100644
index 0000000..8eaaa9c
--- /dev/null
+++ b/src/main/java/com/gxwebsoft/common/system/mapper/ChatMessageMapper.java
@@ -0,0 +1,37 @@
+package com.gxwebsoft.common.system.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.gxwebsoft.common.system.entity.ChatMessage;
+import com.gxwebsoft.common.system.param.ChatMessageParam;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * 聊天消息表Mapper
+ *
+ * @author 科技小王子
+ * @since 2023-10-18 18:42:17
+ */
+public interface ChatMessageMapper extends BaseMapper {
+
+ /**
+ * 分页查询
+ *
+ * @param page 分页对象
+ * @param param 查询参数
+ * @return List
+ */
+ List selectPageRel(@Param("page") IPage page,
+ @Param("param") ChatMessageParam param);
+
+ /**
+ * 查询全部
+ *
+ * @param param 查询参数
+ * @return List
+ */
+ List selectListRel(@Param("param") ChatMessageParam param);
+
+}
diff --git a/src/main/java/com/gxwebsoft/common/system/mapper/ModulesMapper.java b/src/main/java/com/gxwebsoft/common/system/mapper/ModulesMapper.java
new file mode 100644
index 0000000..f4dc531
--- /dev/null
+++ b/src/main/java/com/gxwebsoft/common/system/mapper/ModulesMapper.java
@@ -0,0 +1,37 @@
+package com.gxwebsoft.common.system.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.gxwebsoft.common.system.entity.Modules;
+import com.gxwebsoft.common.system.param.ModulesParam;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * 模块管理Mapper
+ *
+ * @author 科技小王子
+ * @since 2023-10-18 15:53:43
+ */
+public interface ModulesMapper extends BaseMapper {
+
+ /**
+ * 分页查询
+ *
+ * @param page 分页对象
+ * @param param 查询参数
+ * @return List
+ */
+ List selectPageRel(@Param("page") IPage page,
+ @Param("param") ModulesParam param);
+
+ /**
+ * 查询全部
+ *
+ * @param param 查询参数
+ * @return List
+ */
+ List selectListRel(@Param("param") ModulesParam param);
+
+}
diff --git a/src/main/java/com/gxwebsoft/common/system/mapper/xml/ChatConversationMapper.xml b/src/main/java/com/gxwebsoft/common/system/mapper/xml/ChatConversationMapper.xml
new file mode 100644
index 0000000..94c77c0
--- /dev/null
+++ b/src/main/java/com/gxwebsoft/common/system/mapper/xml/ChatConversationMapper.xml
@@ -0,0 +1,56 @@
+
+
+
+
+
+
+ SELECT a.*
+ FROM sys_chat_conversation a
+
+
+ AND a.id = #{param.id}
+
+
+ AND a.user_id = #{param.userId}
+
+
+ AND a.friend_id = #{param.friendId}
+
+
+ AND a.type = #{param.type}
+
+
+ AND a.content LIKE CONCAT('%', #{param.content}, '%')
+
+
+ AND a.un_read = #{param.unRead}
+
+
+ AND a.status = #{param.status}
+
+
+ AND a.deleted = #{param.deleted}
+
+
+ AND a.deleted = 0
+
+
+ AND a.create_time >= #{param.createTimeStart}
+
+
+ AND a.create_time <= #{param.createTimeEnd}
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/java/com/gxwebsoft/common/system/mapper/xml/ChatMessageMapper.xml b/src/main/java/com/gxwebsoft/common/system/mapper/xml/ChatMessageMapper.xml
new file mode 100644
index 0000000..8a884ef
--- /dev/null
+++ b/src/main/java/com/gxwebsoft/common/system/mapper/xml/ChatMessageMapper.xml
@@ -0,0 +1,65 @@
+
+
+
+
+
+
+ SELECT a.*
+ FROM sys_chat_message a
+
+
+ AND a.id = #{param.id}
+
+
+ AND a.form_user_id = #{param.formUserId}
+
+
+ AND a.to_user_id = #{param.toUserId}
+
+
+ AND a.type LIKE CONCAT('%', #{param.type}, '%')
+
+
+ AND a.content LIKE CONCAT('%', #{param.content}, '%')
+
+
+ AND a.side_to = #{param.sideTo}
+
+
+ AND a.side_from = #{param.sideFrom}
+
+
+ AND a.withdraw = #{param.withdraw}
+
+
+ AND a.file_info LIKE CONCAT('%', #{param.fileInfo}, '%')
+
+
+ AND a.status = #{param.status}
+
+
+ AND a.deleted = #{param.deleted}
+
+
+ AND a.deleted = 0
+
+
+ AND a.create_time >= #{param.createTimeStart}
+
+
+ AND a.create_time <= #{param.createTimeEnd}
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/java/com/gxwebsoft/common/system/mapper/xml/ModulesMapper.xml b/src/main/java/com/gxwebsoft/common/system/mapper/xml/ModulesMapper.xml
new file mode 100644
index 0000000..0f157b6
--- /dev/null
+++ b/src/main/java/com/gxwebsoft/common/system/mapper/xml/ModulesMapper.xml
@@ -0,0 +1,56 @@
+
+
+
+
+
+
+ SELECT a.*
+ FROM sys_modules a
+
+
+ AND a.id = #{param.id}
+
+
+ AND a.modules LIKE CONCAT('%', #{param.modules}, '%')
+
+
+ AND a.modules_url LIKE CONCAT('%', #{param.modulesUrl}, '%')
+
+
+ AND a.sort_number = #{param.sortNumber}
+
+
+ AND a.comments LIKE CONCAT('%', #{param.comments}, '%')
+
+
+ AND a.status = #{param.status}
+
+
+ AND a.user_id = #{param.userId}
+
+
+ AND a.deleted = #{param.deleted}
+
+
+ AND a.deleted = 0
+
+
+ AND a.create_time >= #{param.createTimeStart}
+
+
+ AND a.create_time <= #{param.createTimeEnd}
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/java/com/gxwebsoft/common/system/param/ChatConversationParam.java b/src/main/java/com/gxwebsoft/common/system/param/ChatConversationParam.java
new file mode 100644
index 0000000..7ba3cbc
--- /dev/null
+++ b/src/main/java/com/gxwebsoft/common/system/param/ChatConversationParam.java
@@ -0,0 +1,56 @@
+package com.gxwebsoft.common.system.param;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.gxwebsoft.common.core.annotation.QueryField;
+import com.gxwebsoft.common.core.annotation.QueryType;
+import com.gxwebsoft.common.core.web.BaseParam;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 聊天消息表查询参数
+ *
+ * @author 科技小王子
+ * @since 2023-06-15 21:26:48
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@ApiModel(value = "ChatConversationParam对象", description = "聊天消息表查询参数")
+public class ChatConversationParam extends BaseParam {
+ private static final long serialVersionUID = 1L;
+
+ @ApiModelProperty(value = "自增ID")
+ @QueryField(type = QueryType.EQ)
+ private Integer id;
+
+ @ApiModelProperty(value = "用户ID")
+ @QueryField(type = QueryType.EQ)
+ private Integer userId;
+
+ @ApiModelProperty(value = "好友ID")
+ @QueryField(type = QueryType.EQ)
+ private Integer friendId;
+
+ @ApiModelProperty(value = "消息类型")
+ @QueryField(type = QueryType.EQ)
+ private Integer type;
+
+ @ApiModelProperty(value = "消息内容")
+ private String content;
+
+ @ApiModelProperty(value = "状态, 0未读, 1已读")
+ @QueryField(type = QueryType.EQ)
+ private Integer status;
+
+ @ApiModelProperty(value = "是否删除, 0否, 1是")
+ @QueryField(type = QueryType.EQ)
+ private Integer deleted;
+
+ @ApiModelProperty(value = "是否只要僵尸, 0否, 1是")
+ @QueryField(type = QueryType.EQ)
+ private Boolean onlyFake;
+
+}
diff --git a/src/main/java/com/gxwebsoft/common/system/param/ChatMessageParam.java b/src/main/java/com/gxwebsoft/common/system/param/ChatMessageParam.java
new file mode 100644
index 0000000..f5af8cd
--- /dev/null
+++ b/src/main/java/com/gxwebsoft/common/system/param/ChatMessageParam.java
@@ -0,0 +1,55 @@
+package com.gxwebsoft.common.system.param;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.gxwebsoft.common.core.annotation.QueryField;
+import com.gxwebsoft.common.core.annotation.QueryType;
+import com.gxwebsoft.common.core.web.BaseParam;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 聊天消息表查询参数
+ *
+ * @author 科技小王子
+ * @since 2023-06-10 18:27:25
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@ApiModel(value = "ChatMessageParam对象", description = "聊天消息表查询参数")
+public class ChatMessageParam extends BaseParam {
+ private static final long serialVersionUID = 1L;
+
+ @ApiModelProperty(value = "自增ID")
+ @QueryField(type = QueryType.EQ)
+ private Integer id;
+
+ @ApiModelProperty(value = "发送用户ID")
+ @QueryField(type = QueryType.EQ)
+ private Integer formUserId;
+
+ @ApiModelProperty(value = "接受用户ID")
+ @QueryField(type = QueryType.EQ)
+ private Integer toUserId;
+
+ @ApiModelProperty(value = "屏蔽消息的用户")
+ private Integer sideUserId;
+
+ @ApiModelProperty(value = "消息类型")
+ @QueryField(type = QueryType.EQ)
+ private String type;
+
+ @ApiModelProperty(value = "消息内容")
+ private String content;
+
+ @ApiModelProperty(value = "状态, 0在线, 1离线")
+ @QueryField(type = QueryType.EQ)
+ private Integer status;
+
+ @ApiModelProperty(value = "是否删除, 0否, 1是")
+ @QueryField(type = QueryType.EQ)
+ private Integer deleted;
+
+}
diff --git a/src/main/java/com/gxwebsoft/common/system/param/ModulesParam.java b/src/main/java/com/gxwebsoft/common/system/param/ModulesParam.java
new file mode 100644
index 0000000..febdd80
--- /dev/null
+++ b/src/main/java/com/gxwebsoft/common/system/param/ModulesParam.java
@@ -0,0 +1,54 @@
+package com.gxwebsoft.common.system.param;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.gxwebsoft.common.core.annotation.QueryField;
+import com.gxwebsoft.common.core.annotation.QueryType;
+import com.gxwebsoft.common.core.web.BaseParam;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 模块管理查询参数
+ *
+ * @author 科技小王子
+ * @since 2023-10-18 15:53:43
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@ApiModel(value = "ModulesParam对象", description = "模块管理查询参数")
+public class ModulesParam extends BaseParam {
+ private static final long serialVersionUID = 1L;
+
+ @ApiModelProperty(value = "插件id")
+ @QueryField(type = QueryType.EQ)
+ private Integer id;
+
+ @ApiModelProperty(value = "环境编号")
+ private String modules;
+
+ @ApiModelProperty(value = "模块访问地址")
+ private String modulesUrl;
+
+ @ApiModelProperty(value = "排序号")
+ @QueryField(type = QueryType.EQ)
+ private Integer sortNumber;
+
+ @ApiModelProperty(value = "备注")
+ private String comments;
+
+ @ApiModelProperty(value = "状态, 10待审核 20已通过 30已驳回")
+ @QueryField(type = QueryType.EQ)
+ private Integer status;
+
+ @ApiModelProperty(value = "用户ID")
+ @QueryField(type = QueryType.EQ)
+ private Integer userId;
+
+ @ApiModelProperty(value = "是否删除, 0否, 1是")
+ @QueryField(type = QueryType.EQ)
+ private Integer deleted;
+
+}
diff --git a/src/main/java/com/gxwebsoft/common/system/param/SmsCaptchaParam.java b/src/main/java/com/gxwebsoft/common/system/param/SmsCaptchaParam.java
index 765b9eb..98945e6 100644
--- a/src/main/java/com/gxwebsoft/common/system/param/SmsCaptchaParam.java
+++ b/src/main/java/com/gxwebsoft/common/system/param/SmsCaptchaParam.java
@@ -28,4 +28,7 @@ public class SmsCaptchaParam implements Serializable {
@ApiModelProperty("短信模板")
private String TemplateParam;
+ @ApiModelProperty("租户ID")
+ private String tenantId;
+
}
diff --git a/src/main/java/com/gxwebsoft/common/system/service/ChatConversationService.java b/src/main/java/com/gxwebsoft/common/system/service/ChatConversationService.java
new file mode 100644
index 0000000..d4161d9
--- /dev/null
+++ b/src/main/java/com/gxwebsoft/common/system/service/ChatConversationService.java
@@ -0,0 +1,47 @@
+package com.gxwebsoft.common.system.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.gxwebsoft.common.core.web.PageResult;
+import com.gxwebsoft.common.system.entity.ChatConversation;
+import com.gxwebsoft.common.system.param.ChatConversationParam;
+import com.gxwebsoft.common.system.vo.ChatConversationVO;
+
+import java.util.List;
+
+/**
+ * 聊天消息表Service
+ *
+ * @author 科技小王子
+ * @since 2023-06-15 21:26:48
+ */
+public interface ChatConversationService extends IService {
+
+ /**
+ * 分页关联查询
+ *
+ * @param param 查询参数
+ * @return PageResult
+ */
+ PageResult pageRel(ChatConversationParam param);
+
+ /**
+ * 关联查询全部
+ *
+ * @param param 查询参数
+ * @return List
+ */
+ List listRel(ChatConversationParam param);
+
+ /**
+ * 根据id查询
+ *
+ * @param id 自增ID
+ * @return ChatConversation
+ */
+ ChatConversation getByIdRel(Integer id);
+
+ ChatConversation getByBothId(Integer formUserId, Integer toUserId);
+
+ List getFriendList(ChatConversationParam param);
+
+}
diff --git a/src/main/java/com/gxwebsoft/common/system/service/ChatMessageService.java b/src/main/java/com/gxwebsoft/common/system/service/ChatMessageService.java
new file mode 100644
index 0000000..7ad21ec
--- /dev/null
+++ b/src/main/java/com/gxwebsoft/common/system/service/ChatMessageService.java
@@ -0,0 +1,48 @@
+package com.gxwebsoft.common.system.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.gxwebsoft.common.core.web.PageResult;
+import com.gxwebsoft.common.system.entity.ChatMessage;
+import com.gxwebsoft.common.system.param.ChatMessageParam;
+
+import java.util.List;
+
+/**
+ * 聊天消息表Service
+ *
+ * @author 科技小王子
+ * @since 2023-06-10 18:27:25
+ */
+public interface ChatMessageService extends IService {
+
+ /**
+ * 分页关联查询
+ *
+ * @param param 查询参数
+ * @return PageResult
+ */
+ PageResult pageRel(ChatMessageParam param);
+
+ /**
+ * 关联查询全部
+ *
+ * @param param 查询参数
+ * @return List
+ */
+ List listRel(ChatMessageParam param);
+
+ /**
+ * 根据id查询
+ *
+ * @param id 自增ID
+ * @return ChatMessage
+ */
+ ChatMessage getByIdRel(Integer id);
+
+ List getUnreadMessage(Integer fromUserId, Integer toUserId);
+
+ boolean sendMessage(ChatMessage message);
+
+ List getFriendMessage(Integer userId, Integer friendId, Integer lastMessageId);
+
+}
diff --git a/src/main/java/com/gxwebsoft/common/system/service/ModulesService.java b/src/main/java/com/gxwebsoft/common/system/service/ModulesService.java
new file mode 100644
index 0000000..93244f1
--- /dev/null
+++ b/src/main/java/com/gxwebsoft/common/system/service/ModulesService.java
@@ -0,0 +1,42 @@
+package com.gxwebsoft.common.system.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.gxwebsoft.common.core.web.PageResult;
+import com.gxwebsoft.common.system.entity.Modules;
+import com.gxwebsoft.common.system.param.ModulesParam;
+
+import java.util.List;
+
+/**
+ * 模块管理Service
+ *
+ * @author 科技小王子
+ * @since 2023-10-18 15:53:43
+ */
+public interface ModulesService extends IService {
+
+ /**
+ * 分页关联查询
+ *
+ * @param param 查询参数
+ * @return PageResult
+ */
+ PageResult pageRel(ModulesParam param);
+
+ /**
+ * 关联查询全部
+ *
+ * @param param 查询参数
+ * @return List
+ */
+ List listRel(ModulesParam param);
+
+ /**
+ * 根据id查询
+ *
+ * @param id 插件id
+ * @return Modules
+ */
+ Modules getByIdRel(Integer id);
+
+}
diff --git a/src/main/java/com/gxwebsoft/common/system/service/impl/ChatConversationServiceImpl.java b/src/main/java/com/gxwebsoft/common/system/service/impl/ChatConversationServiceImpl.java
new file mode 100644
index 0000000..b0649db
--- /dev/null
+++ b/src/main/java/com/gxwebsoft/common/system/service/impl/ChatConversationServiceImpl.java
@@ -0,0 +1,123 @@
+package com.gxwebsoft.common.system.service.impl;
+
+import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.github.yulichang.toolkit.JoinWrappers;
+import com.github.yulichang.wrapper.MPJLambdaWrapper;
+import com.gxwebsoft.common.core.web.PageParam;
+import com.gxwebsoft.common.core.web.PageResult;
+import com.gxwebsoft.common.system.entity.ChatConversation;
+import com.gxwebsoft.common.system.entity.ChatMessage;
+import com.gxwebsoft.common.system.entity.User;
+import com.gxwebsoft.common.system.mapper.ChatConversationMapper;
+import com.gxwebsoft.common.system.param.ChatConversationParam;
+import com.gxwebsoft.common.system.service.ChatConversationService;
+import com.gxwebsoft.common.system.service.UserService;
+import com.gxwebsoft.common.system.vo.ChatConversationVO;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.util.List;
+
+/**
+ * 聊天消息表Service实现
+ *
+ * @author 科技小王子
+ * @since 2023-06-15 21:26:48
+ */
+@Service
+public class ChatConversationServiceImpl extends ServiceImpl implements ChatConversationService {
+
+ @Resource
+ private UserService userService;
+
+
+ @Override
+ public PageResult pageRel(ChatConversationParam param) {
+
+ MPJLambdaWrapper wrapper = JoinWrappers.lambda("t",ChatConversation.class)
+ .selectAll(ChatConversation.class)
+ // 查询用户
+// .eq(ObjectUtils.isNotEmpty(param.getUserId()), ChatConversation::getUserId, param.getUserId())
+ .and(ObjectUtils.isNotEmpty(param.getUserId()), w2-> {
+ w2.eq(ChatConversation::getUserId, param.getUserId()).or(w3->{
+ w3.eq(ChatConversation::getFriendId, param.getUserId());
+ });
+ } )
+ // 查询未读
+ .gt(param.getStatus()!= null &¶m.getStatus() == 1, ChatConversation::getUnRead, 0)
+ //
+ .selectAssociation("t1",User.class, ChatConversationVO::getFriendInfo)
+ .selectAssociation("t2",User.class, ChatConversationVO::getUserInfo)
+ .innerJoin(User.class,"t1", User::getUserId, ChatConversation::getFriendId)
+ .innerJoin(User.class, "t2", wrapper1 -> wrapper1.notLike(param.getOnlyFake(),User::getUsername, "wx_%").eq(User::getUserId, ChatConversation::getUserId))
+ // 消息列表 影响分页 暂时无解User::getUserId, ChatConversation::getUserId,
+// .selectCollection(ChatMessage.class, ChatConversationVO::getMessages)
+// .leftJoin(ChatMessage.class, on ->
+// on.and(w -> {
+// w.eq(ChatMessage::getFormUserId, ChatConversation::getUserId).eq(ChatMessage::getToUserId, ChatConversation::getFriendId);
+// })
+// .or(w -> {
+// w.eq(ChatMessage::getFormUserId, ChatConversation::getFriendId).eq(ChatMessage::getToUserId, ChatConversation::getUserId);
+// })
+// .orderByDesc(ChatMessage::getCreateTime)
+// )
+
+ .orderByDesc(ChatConversation::getUpdateTime);
+
+
+ Page chatConversationVOPage = baseMapper.selectJoinPage(new Page<>(param.getPage(), param.getLimit()), ChatConversationVO.class, wrapper);
+
+ return new PageResult<>(chatConversationVOPage.getRecords(), chatConversationVOPage.getTotal());
+ }
+
+ @Override
+ public List listRel(ChatConversationParam param) {
+ List list = baseMapper.selectListRel(param);
+ // 排序
+ PageParam page = new PageParam<>();
+ //page.setDefaultOrder("create_time desc");
+
+ return page.sortRecords(list);
+ }
+
+ @Override
+ public ChatConversation getByIdRel(Integer id) {
+ ChatConversationParam param = new ChatConversationParam();
+ param.setId(id);
+ return param.getOne(baseMapper.selectListRel(param));
+ }
+
+ @Override
+ public ChatConversation getByBothId(Integer formUserId, Integer toUserId) {
+ ChatConversationParam param = new ChatConversationParam();
+ param.setUserId(formUserId);
+ param.setFriendId(toUserId);
+ return param.getOne(baseMapper.selectListRel(param));
+ }
+
+ @Override
+ public List getFriendList(ChatConversationParam param) {
+ MPJLambdaWrapper wrapper = JoinWrappers.lambda(ChatConversation.class)
+ .selectAll(ChatConversation.class)
+ .eq(ChatConversation::getUserId, param.getUserId())
+ .selectAssociation(User.class, ChatConversationVO::getFriendInfo)
+ .leftJoin(User.class, User::getUserId, ChatConversation::getFriendId)
+ .selectCollection(ChatMessage.class, ChatConversationVO::getMessages)
+ .leftJoin(ChatMessage.class, on ->
+ on.and(w -> {
+ w.eq(ChatMessage::getFormUserId, param.getUserId()).eq(ChatMessage::getToUserId, ChatConversation::getFriendId);
+ })
+ .or(w -> {
+ w.eq(ChatMessage::getFormUserId, ChatConversation::getFriendId).eq(ChatMessage::getToUserId, param.getUserId());
+ })
+ .orderByDesc(ChatMessage::getCreateTime)
+ )
+ .orderByDesc(ChatConversation::getUpdateTime);
+
+
+ return baseMapper.selectJoinList(ChatConversationVO.class, wrapper);
+ }
+
+}
diff --git a/src/main/java/com/gxwebsoft/common/system/service/impl/ChatMessageServiceImpl.java b/src/main/java/com/gxwebsoft/common/system/service/impl/ChatMessageServiceImpl.java
new file mode 100644
index 0000000..d5ab26a
--- /dev/null
+++ b/src/main/java/com/gxwebsoft/common/system/service/impl/ChatMessageServiceImpl.java
@@ -0,0 +1,179 @@
+package com.gxwebsoft.common.system.service.impl;
+
+import cn.hutool.core.date.DateUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.gxwebsoft.common.core.enums.ChatMessageType;
+import com.gxwebsoft.common.core.socketio.cache.ClientCache;
+import com.gxwebsoft.common.core.utils.PushUtil;
+import com.gxwebsoft.common.core.web.PageParam;
+import com.gxwebsoft.common.core.web.PageResult;
+import com.gxwebsoft.common.system.entity.ChatConversation;
+import com.gxwebsoft.common.system.entity.User;
+import com.gxwebsoft.common.core.enums.GreenWebType;
+import com.gxwebsoft.common.system.entity.ChatMessage;
+import com.gxwebsoft.common.system.mapper.ChatMessageMapper;
+import com.gxwebsoft.common.system.param.ChatMessageParam;
+import com.gxwebsoft.common.system.service.ChatConversationService;
+import com.gxwebsoft.common.system.service.ChatMessageService;
+import com.gxwebsoft.common.system.service.UserService;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import javax.annotation.Resource;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/**
+ * 聊天消息表Service实现
+ *
+ * @author 科技小王子
+ * @since 2023-06-10 18:27:25
+ */
+@Service
+public class ChatMessageServiceImpl extends ServiceImpl implements ChatMessageService {
+
+ @Resource
+ private ChatConversationService conversationService;
+
+ @Resource
+ private ClientCache clientCache;
+
+ @Resource
+ private UserService userService;
+
+ @Resource
+ private PushUtil pushUtil;
+
+ @Override
+ public PageResult pageRel(ChatMessageParam param) {
+ LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>();
+ wrapper.and(w -> {
+ w.eq(ChatMessage::getFormUserId, param.getToUserId()).eq(ChatMessage::getToUserId, param.getFormUserId());
+ })
+ .or(w -> {
+ w.eq(ChatMessage::getFormUserId, param.getFormUserId()).eq(ChatMessage::getToUserId, param.getToUserId());
+ })
+ .orderByAsc(ChatMessage::getCreateTime);
+
+ Page chatMessagePage = new Page<>(param.getPage(), param.getLimit());
+ Page result = baseMapper.selectPage(chatMessagePage, wrapper);
+ List list = result.getRecords();
+ Set userIds = new HashSet<>();
+ if (param.getFormUserId() != null && param.getToUserId() != null) {
+ userIds.add(param.getToUserId());
+ userIds.add(param.getFormUserId());
+ } else {
+ list.stream().forEach(d -> {
+ userIds.add(d.getToUserId());
+ userIds.add(d.getFormUserId());
+ });
+ }
+ List users = userService.list(Wrappers.lambdaQuery(User.class).in(User::getUserId, userIds));
+ Map> collect = users.stream().collect(Collectors.groupingBy(User::getUserId));
+ list.stream().forEach(d -> {
+ d.setFormUserInfo(collect.get(d.getFormUserId()).get(0));
+ });
+ return new PageResult<>(list, result.getTotal());
+ }
+
+ @Override
+ public List listRel(ChatMessageParam param) {
+ List list = baseMapper.selectListRel(param);
+ // 排序
+ PageParam page = new PageParam<>();
+ //page.setDefaultOrder("create_time desc");
+ return page.sortRecords(list);
+ }
+
+ @Override
+ public ChatMessage getByIdRel(Integer id) {
+ ChatMessageParam param = new ChatMessageParam();
+ param.setId(id);
+ return param.getOne(baseMapper.selectListRel(param));
+ }
+
+ @Override
+ public List getUnreadMessage(Integer fromUserId, Integer toUserId) {
+ return null;
+ }
+
+ @Override
+ @Transactional
+ public boolean sendMessage(ChatMessage message) {
+ Integer userId = message.getFormUserId();
+ Integer toUserId = message.getToUserId();
+
+ User toUser = userService.getById(toUserId);
+ User fromUser = userService.getById(userId);
+ message.setToUserInfo(toUser);
+ // 判断双方是否是好友(有消息记录),没有就添加两条记录 后续可以做拉黑什么的处理
+ ChatConversation conversation1 = conversationService.getByBothId(userId, toUserId);
+ ChatConversation conversation2 = conversationService.getByBothId(toUserId, userId);
+ if (conversation1 == null) {
+ conversation1 = new ChatConversation();
+ conversation1.setUserId(Integer.valueOf(userId));
+ conversation1.setFriendId(toUserId);
+ }
+ if (conversation2 == null) {
+ conversation2 = new ChatConversation();
+ conversation2.setUserId(toUserId);
+ conversation2.setFriendId(Integer.valueOf(userId));
+ }
+ String lastContent;
+ if (ChatMessageType.IMAGE.getName().equals(message.getType())) {
+ lastContent = "[图片]";
+ } else if (ChatMessageType.VOICE.getName().equals(message.getType())) {
+ lastContent = "[语音]";
+ } else if (ChatMessageType.CARD.getName().equals(message.getType())) {
+ lastContent = "[卡片]";
+ } else {
+ lastContent = message.getContent();
+ }
+ conversation1.setContent(lastContent);
+ conversation1.setUpdateTime(DateUtil.date());
+ //未读+1
+
+ conversation2.setUnRead(conversation2.getUnRead() + 1);
+ conversation2.setContent(lastContent);
+ conversation2.setUpdateTime(DateUtil.date());
+ this.save(message);
+ // 发送到接收方
+ clientCache.sendUserEvent(message.getToUserId() + "", "message", message);
+ if(lastContent.length() > 20) {
+ lastContent = lastContent.substring(0, 20);
+ }
+ pushUtil.toSingle(message.getToUserId(),fromUser.getNickname(), lastContent,"message", message.getFormUserId());
+ // 发送到管理员
+ if (!toUser.getUsername().startsWith("wx_")) {
+ clientCache.sendUserEvent("admin", "message", message);
+ }
+
+
+ conversationService.saveOrUpdate(conversation1);
+ conversationService.saveOrUpdate(conversation2);
+ return true;
+ }
+
+ @Override
+ public List getFriendMessage(Integer userId, Integer friendId, Integer lastMessageId) {
+ LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>();
+ wrapper.lt(lastMessageId != null && lastMessageId != 0, ChatMessage::getId, lastMessageId)
+ .and(w2 -> {
+ w2
+ .or(w -> { w.eq(ChatMessage::getFormUserId, userId).eq(ChatMessage::getToUserId, friendId).ne(ChatMessage::getSideFrom, true);})
+ .or(w -> {w.eq(ChatMessage::getFormUserId, friendId).eq(ChatMessage::getToUserId, userId).ne(ChatMessage::getSideTo, true);});
+ })
+
+ .orderByDesc(ChatMessage::getCreateTime)
+ .last("limit 30");
+
+ return baseMapper.selectList(wrapper);
+ }
+
+}
diff --git a/src/main/java/com/gxwebsoft/common/system/service/impl/MenuServiceImpl.java b/src/main/java/com/gxwebsoft/common/system/service/impl/MenuServiceImpl.java
index f99a102..129eaf4 100644
--- a/src/main/java/com/gxwebsoft/common/system/service/impl/MenuServiceImpl.java
+++ b/src/main/java/com/gxwebsoft/common/system/service/impl/MenuServiceImpl.java
@@ -92,6 +92,7 @@ public class MenuServiceImpl extends ServiceImpl implements Me
menu.setTitle(d.getTitle());
menu.setPath(d.getPath());
menu.setComponent(d.getComponent());
+ menu.setModules(d.getModules());
menu.setModulesUrl(d.getModulesUrl());
menu.setMenuType(d.getMenuType());
menu.setSortNumber(d.getSortNumber());
diff --git a/src/main/java/com/gxwebsoft/common/system/service/impl/ModulesServiceImpl.java b/src/main/java/com/gxwebsoft/common/system/service/impl/ModulesServiceImpl.java
new file mode 100644
index 0000000..37e1b44
--- /dev/null
+++ b/src/main/java/com/gxwebsoft/common/system/service/impl/ModulesServiceImpl.java
@@ -0,0 +1,47 @@
+package com.gxwebsoft.common.system.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.gxwebsoft.common.system.mapper.ModulesMapper;
+import com.gxwebsoft.common.system.service.ModulesService;
+import com.gxwebsoft.common.system.entity.Modules;
+import com.gxwebsoft.common.system.param.ModulesParam;
+import com.gxwebsoft.common.core.web.PageParam;
+import com.gxwebsoft.common.core.web.PageResult;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * 模块管理Service实现
+ *
+ * @author 科技小王子
+ * @since 2023-10-18 15:53:43
+ */
+@Service
+public class ModulesServiceImpl extends ServiceImpl implements ModulesService {
+
+ @Override
+ public PageResult pageRel(ModulesParam param) {
+ PageParam page = new PageParam<>(param);
+ //page.setDefaultOrder("create_time desc");
+ List list = baseMapper.selectPageRel(page, param);
+ return new PageResult<>(list, page.getTotal());
+ }
+
+ @Override
+ public List listRel(ModulesParam param) {
+ List list = baseMapper.selectListRel(param);
+ // 排序
+ PageParam page = new PageParam<>();
+ //page.setDefaultOrder("create_time desc");
+ return page.sortRecords(list);
+ }
+
+ @Override
+ public Modules getByIdRel(Integer id) {
+ ModulesParam param = new ModulesParam();
+ param.setId(id);
+ return param.getOne(baseMapper.selectListRel(param));
+ }
+
+}
diff --git a/src/main/java/com/gxwebsoft/common/system/vo/ChatConversationVO.java b/src/main/java/com/gxwebsoft/common/system/vo/ChatConversationVO.java
new file mode 100644
index 0000000..d31eb23
--- /dev/null
+++ b/src/main/java/com/gxwebsoft/common/system/vo/ChatConversationVO.java
@@ -0,0 +1,18 @@
+package com.gxwebsoft.common.system.vo;
+
+import com.gxwebsoft.common.system.entity.ChatConversation;
+import com.gxwebsoft.common.system.entity.User;
+import com.gxwebsoft.common.system.entity.ChatMessage;
+import lombok.Data;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@Data
+public class ChatConversationVO extends ChatConversation {
+ private User friendInfo;
+ private User userInfo;
+ private List messages = new ArrayList<>();
+ private Integer messageCount;
+
+}
diff --git a/src/main/java/com/gxwebsoft/common/system/vo/PushMessageVO.java b/src/main/java/com/gxwebsoft/common/system/vo/PushMessageVO.java
new file mode 100644
index 0000000..4fb0064
--- /dev/null
+++ b/src/main/java/com/gxwebsoft/common/system/vo/PushMessageVO.java
@@ -0,0 +1,36 @@
+package com.gxwebsoft.common.system.vo;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Builder;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Set;
+
+@Data
+@Builder
+public class PushMessageVO implements Serializable {
+
+ @ApiModelProperty("推送消息")
+ private String title;
+
+ @ApiModelProperty("推送消息内容")
+ private String content;
+
+ private Set userIds;
+
+
+ @ApiModelProperty("推送透传数据obj格式")
+ private Payload payload;
+
+
+ private Set push_clientid;
+
+
+ @Data
+ public static class Payload {
+ private String type;
+ private Object data;
+ }
+
+}
diff --git a/src/main/java/com/gxwebsoft/common/system/vo/faceId/HeadPortraitResult.java b/src/main/java/com/gxwebsoft/common/system/vo/faceId/HeadPortraitResult.java
new file mode 100644
index 0000000..01dae5d
--- /dev/null
+++ b/src/main/java/com/gxwebsoft/common/system/vo/faceId/HeadPortraitResult.java
@@ -0,0 +1,17 @@
+package com.gxwebsoft.common.system.vo.faceId;
+
+
+import lombok.Data;
+
+@Data
+public class HeadPortraitResult {
+ private String code;
+ private String msg;
+ private String porn;
+ private String ad;
+ private String requestId;
+ private Integer faceCount;
+ private Boolean cartoonImg;
+ private int[] genterList;
+ private int[] ageList;
+}
diff --git a/src/main/java/com/gxwebsoft/common/system/vo/idcheck/BackRecognitionResult.java b/src/main/java/com/gxwebsoft/common/system/vo/idcheck/BackRecognitionResult.java
new file mode 100644
index 0000000..faae5b0
--- /dev/null
+++ b/src/main/java/com/gxwebsoft/common/system/vo/idcheck/BackRecognitionResult.java
@@ -0,0 +1,11 @@
+package com.gxwebsoft.common.system.vo.idcheck;
+
+import lombok.Data;
+
+@Data
+public class BackRecognitionResult {
+
+ private String startDate;
+ private String endDate;
+ private String issue;
+}
diff --git a/src/main/java/com/gxwebsoft/common/system/vo/idcheck/FrontRecognitionResult.java b/src/main/java/com/gxwebsoft/common/system/vo/idcheck/FrontRecognitionResult.java
new file mode 100644
index 0000000..f68d06d
--- /dev/null
+++ b/src/main/java/com/gxwebsoft/common/system/vo/idcheck/FrontRecognitionResult.java
@@ -0,0 +1,15 @@
+package com.gxwebsoft.common.system.vo.idcheck;
+
+import lombok.Data;
+
+@Data
+public class FrontRecognitionResult {
+ private String idcardno;
+ private String name;
+ private String nationality;
+ private String sex;
+ private String birth;
+ private String address;
+ private String imageStats;
+ private String direction;
+}
diff --git a/src/main/java/com/gxwebsoft/common/system/vo/idcheck/IdCardInfor.java b/src/main/java/com/gxwebsoft/common/system/vo/idcheck/IdCardInfor.java
new file mode 100644
index 0000000..6feb209
--- /dev/null
+++ b/src/main/java/com/gxwebsoft/common/system/vo/idcheck/IdCardInfor.java
@@ -0,0 +1,14 @@
+package com.gxwebsoft.common.system.vo.idcheck;
+
+import lombok.Data;
+
+@Data
+public class IdCardInfor {
+ private String province;
+ private String city;
+ private String district;
+ private String area;
+ private String sex;
+ private String birthday;
+}
+
diff --git a/src/main/java/com/gxwebsoft/common/system/vo/idcheck/Response.java b/src/main/java/com/gxwebsoft/common/system/vo/idcheck/Response.java
new file mode 100644
index 0000000..ec4d097
--- /dev/null
+++ b/src/main/java/com/gxwebsoft/common/system/vo/idcheck/Response.java
@@ -0,0 +1,10 @@
+package com.gxwebsoft.common.system.vo.idcheck;
+
+import lombok.Data;
+
+@Data
+public class Response {
+ private Integer error_code;
+ private String reason;
+ private T result;
+}
diff --git a/src/main/java/com/gxwebsoft/common/system/vo/idcheck/VerifyResult.java b/src/main/java/com/gxwebsoft/common/system/vo/idcheck/VerifyResult.java
new file mode 100644
index 0000000..f466341
--- /dev/null
+++ b/src/main/java/com/gxwebsoft/common/system/vo/idcheck/VerifyResult.java
@@ -0,0 +1,14 @@
+package com.gxwebsoft.common.system.vo.idcheck;
+
+import lombok.Data;
+
+@Data
+public class VerifyResult {
+ private String realname;
+ private String idcard;
+
+ private boolean isOk;
+
+ private IdCardInfor idCardInfor;
+
+}
diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml
index cfd940c..7659ea8 100644
--- a/src/main/resources/application.yml
+++ b/src/main/resources/application.yml
@@ -3,7 +3,7 @@ server:
port: 9090
# socketIo
socketio:
- port: 9190
+ port: 9191
# 多环境配置
spring:
profiles:
diff --git a/src/test/java/com/gxwebsoft/generator/SysGenerator.java b/src/test/java/com/gxwebsoft/generator/SysGenerator.java
index 5836b06..b41ff51 100644
--- a/src/test/java/com/gxwebsoft/generator/SysGenerator.java
+++ b/src/test/java/com/gxwebsoft/generator/SysGenerator.java
@@ -56,7 +56,9 @@ public class SysGenerator {
// "sys_notice"
// "sys_plug"
// "sys_plug_record",
- "sys_environment"
+// "sys_modules"
+ "sys_chat_message",
+ "sys_chat_conversation"
};
// 需要去除的表前缀
private static final String[] TABLE_PREFIX = new String[]{