1新增socket服务 2同步token到redis

This commit is contained in:
gxwebsoft
2023-10-19 14:44:38 +08:00
parent b7482312c6
commit 84054c853c
45 changed files with 2964 additions and 329 deletions

View File

@@ -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;
}
}

View File

@@ -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;
}
}
}

View File

@@ -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()

View File

@@ -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<String, HashMap<UUID, SocketIOClient>> 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<UUID, SocketIOClient> sessionIdClientCache = concurrentHashMap.get(userId);
if(sessionIdClientCache == null){
sessionIdClientCache = new HashMap<>();
}
sessionIdClientCache.put(sessionId,socketIOClient);
concurrentHashMap.put(userId,sessionIdClientCache);
}
public HashMap<UUID,SocketIOClient> 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<UUID, SocketIOClient> userClient = concurrentHashMap.get(userId);
// 查看对方是否在线
if(!CollectionUtils.isEmpty(userClient)){
for (UUID uuid : userClient.keySet()) {
SocketIOClient ioClient = userClient.get(uuid);
ioClient.sendEvent(event, message);
}
}
}
}

View File

@@ -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);
}
}

View File

@@ -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) {
}
}

View File

@@ -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<String, String> 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<ImageModerationResponseBody.ImageModerationResponseBodyDataResult> 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<String, String> headers = new HashMap<String, String>();
//最后在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<String, String> querys = new HashMap<String, String>();
Map<String, String> bodys = new HashMap<String, String>();
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<HeadPortraitResult>() {
});
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;
}
}

View File

@@ -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<String, Object> 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<String> 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;
}
}

View File

@@ -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<List<ChatConversationVO>> appList() {
ChatConversationParam param = new ChatConversationParam();
param.setUserId(getLoginUserId());
return success(chatConversationService.getFriendList(param));
}
@OperationLog
@ApiOperation("标记已读")
@PostMapping("/app/read")
public ApiResult<Boolean> read(@RequestBody ChatConversationParam param) {
return success(chatConversationService.update(
new LambdaUpdateWrapper<ChatConversation>().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<PageResult<ChatConversationVO>> page(ChatConversationParam param) {
PageParam<ChatConversation, ChatConversationParam> 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<ChatConversation>> list(ChatConversationParam param) {
PageParam<ChatConversation, ChatConversationParam> 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<ChatConversation> 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<ChatConversation> list) {
if (chatConversationService.saveBatch(list)) {
return success("添加成功");
}
return fail("添加失败");
}
@PreAuthorize("hasAuthority('sys:notice:update')")
@OperationLog
@ApiOperation("批量修改聊天消息表")
@PutMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody BatchParam<ChatConversation> batchParam) {
if (batchParam.update(chatConversationService, "id")) {
return success("修改成功");
}
return fail("修改失败");
}
@PreAuthorize("hasAuthority('sys:notice:remove')")
@OperationLog
@ApiOperation("批量删除聊天消息表")
@DeleteMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody List<Integer> ids) {
if (chatConversationService.removeByIds(ids)) {
return success("删除成功");
}
return fail("删除失败");
}
}

View File

@@ -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<List<ChatMessage>> listApp(Integer friendId, Integer lastMessageId) {
return success(chatMessageService.getFriendMessage(getLoginUserId(), friendId, lastMessageId));
}
@PreAuthorize("hasAuthority('sys:notice:list')")
@OperationLog
@ApiOperation("分页查询聊天消息表")
@GetMapping("/page")
public ApiResult<PageResult<ChatMessage>> page(ChatMessageParam param) {
PageParam<ChatMessage, ChatMessageParam> 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<ChatMessage>> list(ChatMessageParam param) {
PageParam<ChatMessage, ChatMessageParam> 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<ChatMessage> 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<ChatMessage> list) {
if (chatMessageService.saveBatch(list)) {
return success("添加成功");
}
return fail("添加失败");
}
@PreAuthorize("hasAuthority('sys:notice:update')")
@OperationLog
@ApiOperation("批量修改聊天消息表")
@PutMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody BatchParam<ChatMessage> batchParam) {
if (batchParam.update(chatMessageService, "id")) {
return success("修改成功");
}
return fail("修改失败");
}
@PreAuthorize("hasAuthority('sys:notice:remove')")
@OperationLog
@ApiOperation("批量删除聊天消息表")
@DeleteMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody List<Integer> 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<ChatMessage> 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("您撤回了一条消息");
}
}

View File

@@ -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");

View File

@@ -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<PageResult<Modules>> page(ModulesParam param) {
PageParam<Modules, ModulesParam> 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<Modules>> list(ModulesParam param) {
PageParam<Modules, ModulesParam> 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<Modules> 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<Modules> list) {
if (modulesService.saveBatch(list)) {
return success("添加成功");
}
return fail("添加失败");
}
@PreAuthorize("hasAuthority('sys:modules:update')")
@OperationLog
@ApiOperation("批量修改模块管理")
@PutMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody BatchParam<Modules> batchParam) {
if (batchParam.update(modulesService, "id")) {
return success("修改成功");
}
return fail("修改失败");
}
@PreAuthorize("hasAuthority('sys:modules:remove')")
@OperationLog
@ApiOperation("批量删除模块管理")
@DeleteMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody List<Integer> ids) {
if (modulesService.removeByIds(ids)) {
return success("删除成功");
}
return fail("删除失败");
}
}

View File

@@ -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;
}

View File

@@ -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;
}
}

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -160,6 +160,9 @@ public class User implements UserDetails {
@ApiModelProperty("获赞数")
private Integer likes;
@ApiModelProperty("客户端ID")
private String clientId;
@ApiModelProperty("评论数")
private Integer commentNumbers;

View File

@@ -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<ChatConversation> {
/**
* 分页查询
*
* @param page 分页对象
* @param param 查询参数
* @return List<ChatConversation>
*/
List<ChatConversation> selectPageRel(@Param("page") IPage<ChatConversation> page,
@Param("param") ChatConversationParam param);
/**
* 查询全部
*
* @param param 查询参数
* @return List<User>
*/
List<ChatConversation> selectListRel(@Param("param") ChatConversationParam param);
}

View File

@@ -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<ChatMessage> {
/**
* 分页查询
*
* @param page 分页对象
* @param param 查询参数
* @return List<ChatMessage>
*/
List<ChatMessage> selectPageRel(@Param("page") IPage<ChatMessage> page,
@Param("param") ChatMessageParam param);
/**
* 查询全部
*
* @param param 查询参数
* @return List<User>
*/
List<ChatMessage> selectListRel(@Param("param") ChatMessageParam param);
}

View File

@@ -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<Modules> {
/**
* 分页查询
*
* @param page 分页对象
* @param param 查询参数
* @return List<Modules>
*/
List<Modules> selectPageRel(@Param("page") IPage<Modules> page,
@Param("param") ModulesParam param);
/**
* 查询全部
*
* @param param 查询参数
* @return List<User>
*/
List<Modules> selectListRel(@Param("param") ModulesParam param);
}

View File

@@ -0,0 +1,56 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.gxwebsoft.common.system.mapper.ChatConversationMapper">
<!-- 关联查询sql -->
<sql id="selectSql">
SELECT a.*
FROM sys_chat_conversation a
<where>
<if test="param.id != null">
AND a.id = #{param.id}
</if>
<if test="param.userId != null">
AND a.user_id = #{param.userId}
</if>
<if test="param.friendId != null">
AND a.friend_id = #{param.friendId}
</if>
<if test="param.type != null">
AND a.type = #{param.type}
</if>
<if test="param.content != null">
AND a.content LIKE CONCAT('%', #{param.content}, '%')
</if>
<if test="param.unRead != null">
AND a.un_read = #{param.unRead}
</if>
<if test="param.status != null">
AND a.status = #{param.status}
</if>
<if test="param.deleted != null">
AND a.deleted = #{param.deleted}
</if>
<if test="param.deleted == null">
AND a.deleted = 0
</if>
<if test="param.createTimeStart != null">
AND a.create_time &gt;= #{param.createTimeStart}
</if>
<if test="param.createTimeEnd != null">
AND a.create_time &lt;= #{param.createTimeEnd}
</if>
</where>
</sql>
<!-- 分页查询 -->
<select id="selectPageRel" resultType="com.gxwebsoft.common.system.entity.ChatConversation">
<include refid="selectSql"></include>
</select>
<!-- 查询全部 -->
<select id="selectListRel" resultType="com.gxwebsoft.common.system.entity.ChatConversation">
<include refid="selectSql"></include>
</select>
</mapper>

View File

@@ -0,0 +1,65 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.gxwebsoft.common.system.mapper.ChatMessageMapper">
<!-- 关联查询sql -->
<sql id="selectSql">
SELECT a.*
FROM sys_chat_message a
<where>
<if test="param.id != null">
AND a.id = #{param.id}
</if>
<if test="param.formUserId != null">
AND a.form_user_id = #{param.formUserId}
</if>
<if test="param.toUserId != null">
AND a.to_user_id = #{param.toUserId}
</if>
<if test="param.type != null">
AND a.type LIKE CONCAT('%', #{param.type}, '%')
</if>
<if test="param.content != null">
AND a.content LIKE CONCAT('%', #{param.content}, '%')
</if>
<if test="param.sideTo != null">
AND a.side_to = #{param.sideTo}
</if>
<if test="param.sideFrom != null">
AND a.side_from = #{param.sideFrom}
</if>
<if test="param.withdraw != null">
AND a.withdraw = #{param.withdraw}
</if>
<if test="param.fileInfo != null">
AND a.file_info LIKE CONCAT('%', #{param.fileInfo}, '%')
</if>
<if test="param.status != null">
AND a.status = #{param.status}
</if>
<if test="param.deleted != null">
AND a.deleted = #{param.deleted}
</if>
<if test="param.deleted == null">
AND a.deleted = 0
</if>
<if test="param.createTimeStart != null">
AND a.create_time &gt;= #{param.createTimeStart}
</if>
<if test="param.createTimeEnd != null">
AND a.create_time &lt;= #{param.createTimeEnd}
</if>
</where>
</sql>
<!-- 分页查询 -->
<select id="selectPageRel" resultType="com.gxwebsoft.common.system.entity.ChatMessage">
<include refid="selectSql"></include>
</select>
<!-- 查询全部 -->
<select id="selectListRel" resultType="com.gxwebsoft.common.system.entity.ChatMessage">
<include refid="selectSql"></include>
</select>
</mapper>

View File

@@ -0,0 +1,56 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.gxwebsoft.common.system.mapper.ModulesMapper">
<!-- 关联查询sql -->
<sql id="selectSql">
SELECT a.*
FROM sys_modules a
<where>
<if test="param.id != null">
AND a.id = #{param.id}
</if>
<if test="param.modules != null">
AND a.modules LIKE CONCAT('%', #{param.modules}, '%')
</if>
<if test="param.modulesUrl != null">
AND a.modules_url LIKE CONCAT('%', #{param.modulesUrl}, '%')
</if>
<if test="param.sortNumber != null">
AND a.sort_number = #{param.sortNumber}
</if>
<if test="param.comments != null">
AND a.comments LIKE CONCAT('%', #{param.comments}, '%')
</if>
<if test="param.status != null">
AND a.status = #{param.status}
</if>
<if test="param.userId != null">
AND a.user_id = #{param.userId}
</if>
<if test="param.deleted != null">
AND a.deleted = #{param.deleted}
</if>
<if test="param.deleted == null">
AND a.deleted = 0
</if>
<if test="param.createTimeStart != null">
AND a.create_time &gt;= #{param.createTimeStart}
</if>
<if test="param.createTimeEnd != null">
AND a.create_time &lt;= #{param.createTimeEnd}
</if>
</where>
</sql>
<!-- 分页查询 -->
<select id="selectPageRel" resultType="com.gxwebsoft.common.system.entity.Modules">
<include refid="selectSql"></include>
</select>
<!-- 查询全部 -->
<select id="selectListRel" resultType="com.gxwebsoft.common.system.entity.Modules">
<include refid="selectSql"></include>
</select>
</mapper>

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -28,4 +28,7 @@ public class SmsCaptchaParam implements Serializable {
@ApiModelProperty("短信模板")
private String TemplateParam;
@ApiModelProperty("租户ID")
private String tenantId;
}

View File

@@ -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<ChatConversation> {
/**
* 分页关联查询
*
* @param param 查询参数
* @return PageResult<ChatConversation>
*/
PageResult<ChatConversationVO> pageRel(ChatConversationParam param);
/**
* 关联查询全部
*
* @param param 查询参数
* @return List<ChatConversation>
*/
List<ChatConversation> listRel(ChatConversationParam param);
/**
* 根据id查询
*
* @param id 自增ID
* @return ChatConversation
*/
ChatConversation getByIdRel(Integer id);
ChatConversation getByBothId(Integer formUserId, Integer toUserId);
List<ChatConversationVO> getFriendList(ChatConversationParam param);
}

View File

@@ -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<ChatMessage> {
/**
* 分页关联查询
*
* @param param 查询参数
* @return PageResult<ChatMessage>
*/
PageResult<ChatMessage> pageRel(ChatMessageParam param);
/**
* 关联查询全部
*
* @param param 查询参数
* @return List<ChatMessage>
*/
List<ChatMessage> listRel(ChatMessageParam param);
/**
* 根据id查询
*
* @param id 自增ID
* @return ChatMessage
*/
ChatMessage getByIdRel(Integer id);
List<ChatMessage> getUnreadMessage(Integer fromUserId, Integer toUserId);
boolean sendMessage(ChatMessage message);
List<ChatMessage> getFriendMessage(Integer userId, Integer friendId, Integer lastMessageId);
}

View File

@@ -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<Modules> {
/**
* 分页关联查询
*
* @param param 查询参数
* @return PageResult<Modules>
*/
PageResult<Modules> pageRel(ModulesParam param);
/**
* 关联查询全部
*
* @param param 查询参数
* @return List<Modules>
*/
List<Modules> listRel(ModulesParam param);
/**
* 根据id查询
*
* @param id 插件id
* @return Modules
*/
Modules getByIdRel(Integer id);
}

View File

@@ -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<ChatConversationMapper, ChatConversation> implements ChatConversationService {
@Resource
private UserService userService;
@Override
public PageResult<ChatConversationVO> pageRel(ChatConversationParam param) {
MPJLambdaWrapper<ChatConversation> 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 &&param.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<ChatConversationVO> chatConversationVOPage = baseMapper.selectJoinPage(new Page<>(param.getPage(), param.getLimit()), ChatConversationVO.class, wrapper);
return new PageResult<>(chatConversationVOPage.getRecords(), chatConversationVOPage.getTotal());
}
@Override
public List<ChatConversation> listRel(ChatConversationParam param) {
List<ChatConversation> list = baseMapper.selectListRel(param);
// 排序
PageParam<ChatConversation, ChatConversationParam> 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<ChatConversationVO> getFriendList(ChatConversationParam param) {
MPJLambdaWrapper<ChatConversation> 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);
}
}

View File

@@ -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<ChatMessageMapper, ChatMessage> implements ChatMessageService {
@Resource
private ChatConversationService conversationService;
@Resource
private ClientCache clientCache;
@Resource
private UserService userService;
@Resource
private PushUtil pushUtil;
@Override
public PageResult<ChatMessage> pageRel(ChatMessageParam param) {
LambdaQueryWrapper<ChatMessage> 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<ChatMessage> chatMessagePage = new Page<>(param.getPage(), param.getLimit());
Page<ChatMessage> result = baseMapper.selectPage(chatMessagePage, wrapper);
List<ChatMessage> list = result.getRecords();
Set<Integer> 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<User> users = userService.list(Wrappers.lambdaQuery(User.class).in(User::getUserId, userIds));
Map<Integer, List<User>> 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<ChatMessage> listRel(ChatMessageParam param) {
List<ChatMessage> list = baseMapper.selectListRel(param);
// 排序
PageParam<ChatMessage, ChatMessageParam> 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<ChatMessage> 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<ChatMessage> getFriendMessage(Integer userId, Integer friendId, Integer lastMessageId) {
LambdaQueryWrapper<ChatMessage> 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);
}
}

View File

@@ -92,6 +92,7 @@ public class MenuServiceImpl extends ServiceImpl<MenuMapper, Menu> 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());

View File

@@ -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<ModulesMapper, Modules> implements ModulesService {
@Override
public PageResult<Modules> pageRel(ModulesParam param) {
PageParam<Modules, ModulesParam> page = new PageParam<>(param);
//page.setDefaultOrder("create_time desc");
List<Modules> list = baseMapper.selectPageRel(page, param);
return new PageResult<>(list, page.getTotal());
}
@Override
public List<Modules> listRel(ModulesParam param) {
List<Modules> list = baseMapper.selectListRel(param);
// 排序
PageParam<Modules, ModulesParam> 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));
}
}

View File

@@ -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<ChatMessage> messages = new ArrayList<>();
private Integer messageCount;
}

View File

@@ -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<Integer> userIds;
@ApiModelProperty("推送透传数据obj格式")
private Payload payload;
private Set<String> push_clientid;
@Data
public static class Payload {
private String type;
private Object data;
}
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -0,0 +1,10 @@
package com.gxwebsoft.common.system.vo.idcheck;
import lombok.Data;
@Data
public class Response<T> {
private Integer error_code;
private String reason;
private T result;
}

View File

@@ -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;
}

View File

@@ -3,7 +3,7 @@ server:
port: 9090
# socketIo
socketio:
port: 9190
port: 9191
# 多环境配置
spring:
profiles:

View File

@@ -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[]{