实时通讯
This commit is contained in:
11
pom.xml
11
pom.xml
@@ -21,11 +21,6 @@
|
|||||||
<version>4.9.0</version>
|
<version>4.9.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.boot</groupId>
|
|
||||||
<artifactId>spring-boot-starter-websocket</artifactId>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>commons-fileupload</groupId>
|
<groupId>commons-fileupload</groupId>
|
||||||
<artifactId>commons-fileupload</artifactId>
|
<artifactId>commons-fileupload</artifactId>
|
||||||
@@ -63,11 +58,7 @@
|
|||||||
<version>3.0.2</version>
|
<version>3.0.2</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<!-- 音频处理(格式转换) -->
|
<!-- 音频处理(格式转换) -->
|
||||||
<dependency>
|
|
||||||
<groupId>org.bytedeco</groupId>
|
|
||||||
<artifactId>javacv-platform</artifactId>
|
|
||||||
<version>1.5.9</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>mysql</groupId>
|
<groupId>mysql</groupId>
|
||||||
<artifactId>mysql-connector-java</artifactId>
|
<artifactId>mysql-connector-java</artifactId>
|
||||||
|
|||||||
@@ -1,90 +1,90 @@
|
|||||||
package com.realtime.config;
|
//package com.realtime.config;
|
||||||
|
//
|
||||||
import com.realtime.service.DoubaoVoiceService;
|
//import com.realtime.service.DoubaoVoiceService;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
//import lombok.extern.slf4j.Slf4j;
|
||||||
import org.bytedeco.javacv.FFmpegFrameGrabber;
|
//import org.bytedeco.javacv.FFmpegFrameGrabber;
|
||||||
import org.bytedeco.javacv.FFmpegFrameRecorder;
|
//import org.bytedeco.javacv.FFmpegFrameRecorder;
|
||||||
import org.bytedeco.javacv.Frame;
|
//import org.bytedeco.javacv.Frame;
|
||||||
import org.springframework.stereotype.Component;
|
//import org.springframework.stereotype.Component;
|
||||||
import org.springframework.web.socket.BinaryMessage;
|
//import org.springframework.web.socket.BinaryMessage;
|
||||||
import org.springframework.web.socket.CloseStatus;
|
//import org.springframework.web.socket.CloseStatus;
|
||||||
import org.springframework.web.socket.WebSocketSession;
|
//import org.springframework.web.socket.WebSocketSession;
|
||||||
import org.springframework.web.socket.handler.BinaryWebSocketHandler;
|
//import org.springframework.web.socket.handler.BinaryWebSocketHandler;
|
||||||
|
//
|
||||||
import java.io.ByteArrayInputStream;
|
//import java.io.ByteArrayInputStream;
|
||||||
import java.io.ByteArrayOutputStream;
|
//import java.io.ByteArrayOutputStream;
|
||||||
import java.io.EOFException;
|
//import java.io.EOFException;
|
||||||
@Slf4j
|
//@Slf4j
|
||||||
@Component
|
//@Component
|
||||||
public class ClientVoiceHandler extends BinaryWebSocketHandler {
|
//public class ClientVoiceHandler extends BinaryWebSocketHandler {
|
||||||
private final DoubaoVoiceService doubaoVoiceService;
|
// private final DoubaoVoiceService doubaoVoiceService;
|
||||||
|
//
|
||||||
public ClientVoiceHandler(DoubaoVoiceService doubaoVoiceService) {
|
// public ClientVoiceHandler(DoubaoVoiceService doubaoVoiceService) {
|
||||||
this.doubaoVoiceService = doubaoVoiceService;
|
// this.doubaoVoiceService = doubaoVoiceService;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@Override
|
// @Override
|
||||||
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
|
// public void afterConnectionEstablished(WebSocketSession session) throws Exception {
|
||||||
// 客户端会话
|
// // 客户端会话
|
||||||
// 建立与豆包 API 的连接
|
// // 建立与豆包 API 的连接
|
||||||
|
//
|
||||||
System.out.println(session);
|
// System.out.println(session);
|
||||||
doubaoVoiceService.connect(session);
|
// doubaoVoiceService.connect(session);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@Override
|
// @Override
|
||||||
protected void handleBinaryMessage(WebSocketSession session, BinaryMessage message) throws Exception {
|
// protected void handleBinaryMessage(WebSocketSession session, BinaryMessage message) throws Exception {
|
||||||
System.out.println("2");
|
// System.out.println("2");
|
||||||
// 接收客户端的音频数据(如 PCM 片段)
|
// // 接收客户端的音频数据(如 PCM 片段)
|
||||||
byte[] audioData = message.getPayload().array();
|
// byte[] audioData = message.getPayload().array();
|
||||||
// 预处理:确保格式符合豆包 API 要求(如采样率、位深)
|
// // 预处理:确保格式符合豆包 API 要求(如采样率、位深)
|
||||||
byte[] processedData = preprocessAudio(audioData);
|
// byte[] processedData = preprocessAudio(audioData);
|
||||||
// 发送给豆包 API
|
// // 发送给豆包 API
|
||||||
doubaoVoiceService.sendAudio(processedData);
|
// doubaoVoiceService.sendAudio(processedData);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@Override
|
// @Override
|
||||||
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
|
// public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
|
||||||
// 关闭与豆包 API 的连接
|
// // 关闭与豆包 API 的连接
|
||||||
doubaoVoiceService.close();
|
// doubaoVoiceService.close();
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
private byte[] preprocessAudio(byte[] audioData) {
|
// private byte[] preprocessAudio(byte[] audioData) {
|
||||||
if (audioData == null || audioData.length == 0) {
|
// if (audioData == null || audioData.length == 0) {
|
||||||
log.warn("接收到空的音频数据,跳过处理");
|
// log.warn("接收到空的音频数据,跳过处理");
|
||||||
return new byte[0]; // 返回空数组,避免后续错误
|
// return new byte[0]; // 返回空数组,避免后续错误
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
// ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||||
|
//
|
||||||
try (FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(new ByteArrayInputStream(audioData));
|
// try (FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(new ByteArrayInputStream(audioData));
|
||||||
FFmpegFrameRecorder recorder = new FFmpegFrameRecorder(outputStream, 1)) {
|
// FFmpegFrameRecorder recorder = new FFmpegFrameRecorder(outputStream, 1)) {
|
||||||
|
//
|
||||||
grabber.start();
|
// grabber.start();
|
||||||
// 打印输入音频信息(调试用)
|
// // 打印输入音频信息(调试用)
|
||||||
log.debug("输入音频格式:{},采样率:{},声道:{}",
|
// log.debug("输入音频格式:{},采样率:{},声道:{}",
|
||||||
grabber.getFormat(), grabber.getSampleRate(), grabber.getAudioChannels());
|
// grabber.getFormat(), grabber.getSampleRate(), grabber.getAudioChannels());
|
||||||
|
//
|
||||||
recorder.setFormat("s16le");
|
// recorder.setFormat("s16le");
|
||||||
recorder.setSampleRate(16000);
|
// recorder.setSampleRate(16000);
|
||||||
recorder.setAudioChannels(1);
|
// recorder.setAudioChannels(1);
|
||||||
recorder.start();
|
// recorder.start();
|
||||||
|
//
|
||||||
Frame frame;
|
// Frame frame;
|
||||||
int frameCount = 0;
|
// int frameCount = 0;
|
||||||
while ((frame = grabber.grab()) != null) {
|
// while ((frame = grabber.grab()) != null) {
|
||||||
recorder.record(frame);
|
// recorder.record(frame);
|
||||||
frameCount++;
|
// frameCount++;
|
||||||
}
|
// }
|
||||||
log.debug("成功处理 {} 帧音频", frameCount);
|
// log.debug("成功处理 {} 帧音频", frameCount);
|
||||||
|
//
|
||||||
recorder.stop();
|
// recorder.stop();
|
||||||
grabber.stop();
|
// grabber.stop();
|
||||||
return outputStream.toByteArray();
|
// return outputStream.toByteArray();
|
||||||
|
//
|
||||||
} catch (Exception e) {
|
// } catch (Exception e) {
|
||||||
log.error("音频预处理失败", e);
|
// log.error("音频预处理失败", e);
|
||||||
return new byte[0];
|
// return new byte[0];
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
|
|||||||
18
src/main/java/com/realtime/config/CloudApiConfig.java
Normal file
18
src/main/java/com/realtime/config/CloudApiConfig.java
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
package com.realtime.config;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 云端API配置
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Configuration
|
||||||
|
public class CloudApiConfig {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 云端API基础URL
|
||||||
|
*/
|
||||||
|
private String baseUrl = "http://www.yuxindazhineng.com:3001/cloud_api";
|
||||||
|
}
|
||||||
21
src/main/java/com/realtime/config/RestTemplateConfig.java
Normal file
21
src/main/java/com/realtime/config/RestTemplateConfig.java
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
package com.realtime.config;
|
||||||
|
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.http.client.SimpleClientHttpRequestFactory;
|
||||||
|
import org.springframework.web.client.RestTemplate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* RestTemplate配置
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
public class RestTemplateConfig {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public RestTemplate restTemplate() {
|
||||||
|
SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
|
||||||
|
factory.setConnectTimeout(10000); // 连接超时10秒
|
||||||
|
factory.setReadTimeout(30000); // 读取超时30秒
|
||||||
|
return new RestTemplate(factory);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,83 @@
|
|||||||
|
package com.realtime.controller;
|
||||||
|
|
||||||
|
import com.realtime.model.query.*;
|
||||||
|
import com.realtime.service.CloudFileService;
|
||||||
|
import com.realtime.sysconst.Result;
|
||||||
|
import com.realtime.vo.CloudFileDownloadVo;
|
||||||
|
import com.realtime.vo.CloudFileListVo;
|
||||||
|
import com.realtime.vo.CloudFileOperationVo;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 云端文件管理控制器
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/cloud_api/file")
|
||||||
|
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
|
||||||
|
public class CloudFileController {
|
||||||
|
|
||||||
|
private final CloudFileService cloudFileService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量上传云端文件
|
||||||
|
*/
|
||||||
|
@PostMapping("/upload")
|
||||||
|
public Result<CloudFileOperationVo> batchUpload(
|
||||||
|
@RequestPart("files") List<MultipartFile> files,
|
||||||
|
@RequestParam("path") String path,
|
||||||
|
@RequestParam("type") String type,
|
||||||
|
@RequestParam(value = "team_id", required = false) String teamId) {
|
||||||
|
|
||||||
|
CloudFileUploadReq request = new CloudFileUploadReq();
|
||||||
|
request.setPath(path);
|
||||||
|
request.setType(type);
|
||||||
|
request.setTeamId(teamId);
|
||||||
|
|
||||||
|
// TODO: 从Session或Token获取当前用户ID
|
||||||
|
String userId = "current_user_id";
|
||||||
|
|
||||||
|
return Result.success(cloudFileService.batchUpload(files, request, userId));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过URL批量上传云端文件
|
||||||
|
*/
|
||||||
|
@PostMapping("/upload/url")
|
||||||
|
public Result<CloudFileOperationVo> batchUploadByUrl(@RequestBody CloudFileUploadByUrlReq request) {
|
||||||
|
// TODO: 从Session或Token获取当前用户ID
|
||||||
|
String userId = "current_user_id";
|
||||||
|
|
||||||
|
return Result.success(cloudFileService.batchUploadByUrl(request, userId));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 下载文件
|
||||||
|
*/
|
||||||
|
@PostMapping("/download")
|
||||||
|
public Result<CloudFileDownloadVo> downloadFile(@RequestBody CloudFileDownloadReq request) {
|
||||||
|
return Result.success(cloudFileService.downloadFile(request));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查看文件列表
|
||||||
|
*/
|
||||||
|
@PostMapping("/list")
|
||||||
|
public Result<CloudFileListVo> listFiles(@RequestBody CloudFileListReq request) {
|
||||||
|
return Result.success(cloudFileService.listFiles(request));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除文件
|
||||||
|
*/
|
||||||
|
@PostMapping("/delete")
|
||||||
|
public Result<CloudFileOperationVo> deleteFile(@RequestBody CloudFileDeleteReq request) {
|
||||||
|
return Result.success(cloudFileService.deleteFile(request));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -72,8 +72,8 @@ public class GroupController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("/saveInvent")
|
@PostMapping("/saveInvent")
|
||||||
Result<String> saveInvent(@RequestBody List<GroupMember> groupMembers,@RequestParam("launchContactId")String launchContactId) {
|
Result<String> saveInvent(@RequestBody List<GroupMember> groupMembers, @RequestParam("launchContactId") String launchContactId) {
|
||||||
return groupMemberService.saveInvent(groupMembers,launchContactId);
|
return groupMemberService.saveInvent(groupMembers, launchContactId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("/disband")
|
@PostMapping("/disband")
|
||||||
@@ -85,4 +85,6 @@ public class GroupController {
|
|||||||
Result<String> quit(@RequestBody RemoveGroupReq removeGroupReq) {
|
Result<String> quit(@RequestBody RemoveGroupReq removeGroupReq) {
|
||||||
return groupMemberService.quit(removeGroupReq);
|
return groupMemberService.quit(removeGroupReq);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
112
src/main/java/com/realtime/controller/TeamController.java
Normal file
112
src/main/java/com/realtime/controller/TeamController.java
Normal file
@@ -0,0 +1,112 @@
|
|||||||
|
package com.realtime.controller;
|
||||||
|
|
||||||
|
import com.realtime.model.query.*;
|
||||||
|
import com.realtime.service.TeamService;
|
||||||
|
import com.realtime.sysconst.Result;
|
||||||
|
import com.realtime.vo.*;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 团队管理控制器
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/cloud_api/team")
|
||||||
|
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
|
||||||
|
public class TeamController {
|
||||||
|
|
||||||
|
private final TeamService teamService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取用户可访问的团队列表
|
||||||
|
* @param request 团队列表查询请求
|
||||||
|
* @return 团队列表
|
||||||
|
*/
|
||||||
|
@PostMapping("/list")
|
||||||
|
public Result<TeamListVo> getTeamList(@RequestBody TeamListReq request) {
|
||||||
|
return Result.success(teamService.getTeamList(request));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建团队
|
||||||
|
* @param request 创建团队请求
|
||||||
|
* @return 创建结果
|
||||||
|
*/
|
||||||
|
@PostMapping("/create")
|
||||||
|
public Result<TeamOperationVo> createTeam(@RequestBody TeamCreateReq request) {
|
||||||
|
return Result.success(teamService.createTeam(request));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除团队
|
||||||
|
* @param request 删除团队请求
|
||||||
|
* @return 删除结果
|
||||||
|
*/
|
||||||
|
@PostMapping("/delete")
|
||||||
|
public Result<TeamOperationVo> deleteTeam(@RequestBody TeamDeleteReq request) {
|
||||||
|
return Result.success(teamService.deleteTeam(request));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修改团队信息
|
||||||
|
* @param request 修改团队请求
|
||||||
|
* @return 修改结果
|
||||||
|
*/
|
||||||
|
@PostMapping("/update")
|
||||||
|
public Result<TeamOperationVo> updateTeam(@RequestBody TeamUpdateReq request) {
|
||||||
|
return Result.success(teamService.updateTeam(request));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查看全部成员
|
||||||
|
* @param request 查看成员请求
|
||||||
|
* @return 成员列表
|
||||||
|
*/
|
||||||
|
@PostMapping("/get_all_member")
|
||||||
|
public Result<TeamMemberListVo> getAllMembers(@RequestBody TeamGetAllMemberReq request) {
|
||||||
|
return Result.success(teamService.getAllMembers(request));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量添加团队成员
|
||||||
|
* @param request 添加成员请求
|
||||||
|
* @return 添加结果
|
||||||
|
*/
|
||||||
|
@PostMapping("/add_member")
|
||||||
|
public Result<TeamOperationVo> addMembers(@RequestBody TeamAddMemberReq request) {
|
||||||
|
return Result.success(teamService.addMembers(request));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量删除团队成员
|
||||||
|
* @param request 删除成员请求
|
||||||
|
* @return 删除结果
|
||||||
|
*/
|
||||||
|
@PostMapping("/remove_member")
|
||||||
|
public Result<TeamOperationVo> removeMembers(@RequestBody TeamRemoveMemberReq request) {
|
||||||
|
return Result.success(teamService.removeMembers(request));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 调整团队成员身份
|
||||||
|
* @param request 调整身份请求
|
||||||
|
* @return 调整结果
|
||||||
|
*/
|
||||||
|
@PostMapping("/adjust_member_role")
|
||||||
|
public Result<TeamOperationVo> adjustMemberRole(@RequestBody TeamAdjustMemberRoleReq request) {
|
||||||
|
return Result.success(teamService.adjustMemberRole(request));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取部门结构
|
||||||
|
* @param request 获取部门结构请求
|
||||||
|
* @return 部门结构
|
||||||
|
*/
|
||||||
|
@PostMapping("/get_department")
|
||||||
|
public Result<TeamDepartmentVo> getDepartment(@RequestBody TeamGetDepartmentReq request) {
|
||||||
|
return Result.success(teamService.getDepartment(request));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -10,4 +10,7 @@ import lombok.EqualsAndHashCode;
|
|||||||
public class BaseQueryModel<T> extends Page<T> {
|
public class BaseQueryModel<T> extends Page<T> {
|
||||||
private Long id;
|
private Long id;
|
||||||
private String contactId;
|
private String contactId;
|
||||||
|
private String accessToken;
|
||||||
|
private String teamType;
|
||||||
|
private String path;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,6 +37,11 @@ public class GroupList implements Serializable {
|
|||||||
*/
|
*/
|
||||||
private Integer type;
|
private Integer type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 团队ID
|
||||||
|
*/
|
||||||
|
private String teamId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 是否需要邀请才能加入 1 = 是 0 = 否
|
* 是否需要邀请才能加入 1 = 是 0 = 否
|
||||||
*/
|
*/
|
||||||
|
|||||||
19
src/main/java/com/realtime/model/query/BaseTeamReq.java
Normal file
19
src/main/java/com/realtime/model/query/BaseTeamReq.java
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
package com.realtime.model.query;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 团队请求基类
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class BaseTeamReq implements Serializable {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 访问令牌
|
||||||
|
*/
|
||||||
|
@JsonProperty("access_token")
|
||||||
|
private String accessToken = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjoiNjhlNzY0ZjBmOTU0ODg3MWMyMmY5M2I4IiwibGFzdExvZ2luIjoiMTc2NTQzNDMyNy41MjA5ODYifQ.Vj0ovpCsziFzeR2qroYnN-3KevR78krx-rDFQ9BKlgU";
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package com.realtime.model.query;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 云端文件删除请求
|
||||||
|
*/
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@Data
|
||||||
|
public class CloudFileDeleteReq extends BaseTeamReq implements Serializable {
|
||||||
|
|
||||||
|
@JsonProperty("file_id")
|
||||||
|
private String fileId;
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package com.realtime.model.query;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 云端文件下载请求
|
||||||
|
*/
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@Data
|
||||||
|
public class CloudFileDownloadReq extends BaseTeamReq implements Serializable {
|
||||||
|
|
||||||
|
@JsonProperty("file_id")
|
||||||
|
private String fileId;
|
||||||
|
}
|
||||||
31
src/main/java/com/realtime/model/query/CloudFileListReq.java
Normal file
31
src/main/java/com/realtime/model/query/CloudFileListReq.java
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
package com.realtime.model.query;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 云端文件列表查询请求
|
||||||
|
*/
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@Data
|
||||||
|
public class CloudFileListReq extends BaseTeamReq implements Serializable {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询路径,默认根目录 /
|
||||||
|
*/
|
||||||
|
private String path = "/";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件类型:user/team
|
||||||
|
*/
|
||||||
|
private String type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 团队ID(type为team时必填)
|
||||||
|
*/
|
||||||
|
@JsonProperty("team_id")
|
||||||
|
private String teamId;
|
||||||
|
}
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
package com.realtime.model.query;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过URL批量上传云端文件请求
|
||||||
|
*/
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@Data
|
||||||
|
public class CloudFileUploadByUrlReq extends BaseTeamReq implements Serializable {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 上传路径
|
||||||
|
*/
|
||||||
|
private String path;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 上传类型:user/team
|
||||||
|
*/
|
||||||
|
private String type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 团队ID(type为team时必填)
|
||||||
|
*/
|
||||||
|
@JsonProperty("team_id")
|
||||||
|
private String teamId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件URL列表
|
||||||
|
*/
|
||||||
|
private List<String> urls;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件名列表
|
||||||
|
*/
|
||||||
|
private List<String> filename;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件大小列表
|
||||||
|
*/
|
||||||
|
private List<Long> size;
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
package com.realtime.model.query;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 云端文件上传请求
|
||||||
|
*/
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@Data
|
||||||
|
public class CloudFileUploadReq extends BaseTeamReq implements Serializable {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 上传路径
|
||||||
|
*/
|
||||||
|
private String path;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 上传类型:user/team
|
||||||
|
*/
|
||||||
|
private String type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 团队ID(type为team时必填)
|
||||||
|
*/
|
||||||
|
private String teamId;
|
||||||
|
}
|
||||||
@@ -9,4 +9,5 @@ import lombok.EqualsAndHashCode;
|
|||||||
@Data
|
@Data
|
||||||
public class GroupDetailQueryReq extends BaseQueryModel<GroupDetailQueryReq> {
|
public class GroupDetailQueryReq extends BaseQueryModel<GroupDetailQueryReq> {
|
||||||
private Long groupId;
|
private Long groupId;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
34
src/main/java/com/realtime/model/query/TeamAddMemberReq.java
Normal file
34
src/main/java/com/realtime/model/query/TeamAddMemberReq.java
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
package com.realtime.model.query;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量添加团队成员请求
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
public class TeamAddMemberReq extends BaseTeamReq {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 团队ID
|
||||||
|
*/
|
||||||
|
@JsonProperty("team_id")
|
||||||
|
private String teamId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户ID列表
|
||||||
|
*/
|
||||||
|
@JsonProperty("user_ids")
|
||||||
|
private List<String> userIds;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 角色:admin、member
|
||||||
|
*/
|
||||||
|
@JsonProperty("role")
|
||||||
|
private String role;
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
package com.realtime.model.query;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 调整团队成员身份请求
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
public class TeamAdjustMemberRoleReq extends BaseTeamReq {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 团队ID
|
||||||
|
*/
|
||||||
|
@JsonProperty("team_id")
|
||||||
|
private String teamId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户ID
|
||||||
|
*/
|
||||||
|
@JsonProperty("user_id")
|
||||||
|
private String userId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 角色:admin、member
|
||||||
|
*/
|
||||||
|
@JsonProperty("role")
|
||||||
|
private String role;
|
||||||
|
}
|
||||||
46
src/main/java/com/realtime/model/query/TeamCreateReq.java
Normal file
46
src/main/java/com/realtime/model/query/TeamCreateReq.java
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
package com.realtime.model.query;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建团队请求
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
public class TeamCreateReq extends BaseTeamReq {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 团队名称
|
||||||
|
*/
|
||||||
|
@JsonProperty("team_name")
|
||||||
|
private String teamName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 团队描述
|
||||||
|
*/
|
||||||
|
@JsonProperty("team_description")
|
||||||
|
private String teamDescription;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 团队类型
|
||||||
|
*/
|
||||||
|
@JsonProperty("team_type")
|
||||||
|
private String teamType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 父团队ID(可选)
|
||||||
|
*/
|
||||||
|
@JsonProperty("parent_id")
|
||||||
|
private String parentId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 群ID
|
||||||
|
*/
|
||||||
|
@JsonProperty("group")
|
||||||
|
private String group;
|
||||||
|
|
||||||
|
}
|
||||||
21
src/main/java/com/realtime/model/query/TeamDeleteReq.java
Normal file
21
src/main/java/com/realtime/model/query/TeamDeleteReq.java
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
package com.realtime.model.query;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除团队请求
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
public class TeamDeleteReq extends BaseTeamReq {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 团队ID
|
||||||
|
*/
|
||||||
|
@JsonProperty("team_id")
|
||||||
|
private String teamId;
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package com.realtime.model.query;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查看全部成员请求
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
public class TeamGetAllMemberReq extends BaseTeamReq {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 团队ID
|
||||||
|
*/
|
||||||
|
@JsonProperty("team_id")
|
||||||
|
private String teamId;
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package com.realtime.model.query;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取部门结构请求
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
public class TeamGetDepartmentReq extends BaseTeamReq {
|
||||||
|
// 空请求体
|
||||||
|
}
|
||||||
21
src/main/java/com/realtime/model/query/TeamListReq.java
Normal file
21
src/main/java/com/realtime/model/query/TeamListReq.java
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
package com.realtime.model.query;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 团队列表查询请求
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
public class TeamListReq extends BaseTeamReq {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 团队名称(可选,用于搜索)
|
||||||
|
*/
|
||||||
|
@JsonProperty("team_name")
|
||||||
|
private String teamName;
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
package com.realtime.model.query;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量删除团队成员请求
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
public class TeamRemoveMemberReq extends BaseTeamReq {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 团队ID
|
||||||
|
*/
|
||||||
|
@JsonProperty("team_id")
|
||||||
|
private String teamId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户ID列表
|
||||||
|
*/
|
||||||
|
@JsonProperty("user_ids")
|
||||||
|
private List<String> userIds;
|
||||||
|
}
|
||||||
45
src/main/java/com/realtime/model/query/TeamUpdateReq.java
Normal file
45
src/main/java/com/realtime/model/query/TeamUpdateReq.java
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
package com.realtime.model.query;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修改团队信息请求
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
public class TeamUpdateReq extends BaseTeamReq {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 团队ID
|
||||||
|
*/
|
||||||
|
@JsonProperty("team_id")
|
||||||
|
private String teamId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 团队名称
|
||||||
|
*/
|
||||||
|
@JsonProperty("team_name")
|
||||||
|
private String teamName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 团队描述
|
||||||
|
*/
|
||||||
|
@JsonProperty("team_description")
|
||||||
|
private String teamDescription;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 团队类型
|
||||||
|
*/
|
||||||
|
@JsonProperty("team_type")
|
||||||
|
private String teamType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 父团队ID(可选)
|
||||||
|
*/
|
||||||
|
@JsonProperty("parent_id")
|
||||||
|
private String parentId;
|
||||||
|
}
|
||||||
@@ -11,11 +11,7 @@ import java.util.List;
|
|||||||
@EqualsAndHashCode(callSuper = true)
|
@EqualsAndHashCode(callSuper = true)
|
||||||
@Data
|
@Data
|
||||||
public class AutoSoftwarePacket extends BasePackets {
|
public class AutoSoftwarePacket extends BasePackets {
|
||||||
private String url;
|
private String merMessage;
|
||||||
private String body;
|
|
||||||
private String method;
|
|
||||||
private String commandLine;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Byte getCommand() {
|
public Byte getCommand() {
|
||||||
return Command.SOFT_CALL_MSG;
|
return Command.SOFT_CALL_MSG;
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package com.realtime.packets;
|
package com.realtime.packets;
|
||||||
|
|
||||||
|
|
||||||
|
import com.realtime.model.query.TeamCreateReq;
|
||||||
import com.realtime.packets.basePackets.BasePackets;
|
import com.realtime.packets.basePackets.BasePackets;
|
||||||
import com.realtime.packets.command.Command;
|
import com.realtime.packets.command.Command;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
@@ -14,6 +15,7 @@ public class GroupPacket extends BasePackets {
|
|||||||
private List<String> userIds;
|
private List<String> userIds;
|
||||||
private Integer type = 2;
|
private Integer type = 2;
|
||||||
private String groupName;
|
private String groupName;
|
||||||
|
private TeamCreateReq teamCreateReq;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Byte getCommand() {
|
public Byte getCommand() {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.realtime.packets.server.handler;
|
package com.realtime.packets.server.handler;
|
||||||
|
|
||||||
|
import com.realtime.utils.SessionUtils;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.channel.ChannelDuplexHandler;
|
import io.netty.channel.ChannelDuplexHandler;
|
||||||
import io.netty.channel.ChannelHandler.Sharable;
|
import io.netty.channel.ChannelHandler.Sharable;
|
||||||
@@ -7,6 +8,7 @@ import io.netty.channel.ChannelHandlerContext;
|
|||||||
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
|
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
@@ -22,12 +24,29 @@ public class ExceptionHandler extends ChannelDuplexHandler {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
|
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
|
||||||
|
// 处理连接重置异常(客户端断开连接)
|
||||||
|
if (cause instanceof IOException) {
|
||||||
|
log.warn("连接异常: {}, 通道: {}", cause.getMessage(), ctx.channel().id().asShortText());
|
||||||
|
// 清理会话信息
|
||||||
|
SessionUtils.unbind(ctx.channel());
|
||||||
|
// 关闭连接
|
||||||
|
ctx.channel().close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理运行时异常
|
||||||
if (cause instanceof RuntimeException) {
|
if (cause instanceof RuntimeException) {
|
||||||
|
log.error("运行时异常: ", cause);
|
||||||
ByteBuf byteBuf = ctx.alloc().buffer();
|
ByteBuf byteBuf = ctx.alloc().buffer();
|
||||||
map.put("errorCode",-10000);
|
map.put("errorCode",-10000);
|
||||||
map.put("errorMessage",cause.getMessage());
|
map.put("errorMessage",cause.getMessage());
|
||||||
byteBuf.writeBytes(map.toString().getBytes(StandardCharsets.UTF_8));
|
byteBuf.writeBytes(map.toString().getBytes(StandardCharsets.UTF_8));
|
||||||
ctx.channel().writeAndFlush(new TextWebSocketFrame(byteBuf));
|
ctx.channel().writeAndFlush(new TextWebSocketFrame(byteBuf));
|
||||||
|
} else {
|
||||||
|
// 其他异常
|
||||||
|
log.error("未处理的异常: ", cause);
|
||||||
|
SessionUtils.unbind(ctx.channel());
|
||||||
|
ctx.channel().close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ package com.realtime.packets.server.handler;
|
|||||||
|
|
||||||
|
|
||||||
import com.alibaba.fastjson2.JSONObject;
|
import com.alibaba.fastjson2.JSONObject;
|
||||||
|
import com.realtime.exception.BusinessException;
|
||||||
import com.realtime.model.pojo.GroupMessage;
|
import com.realtime.model.pojo.GroupMessage;
|
||||||
import com.realtime.packets.GroupSendPacket;
|
import com.realtime.packets.GroupSendPacket;
|
||||||
import com.realtime.service.GroupMessageService;
|
import com.realtime.service.GroupMessageService;
|
||||||
@@ -33,8 +34,11 @@ public class GroupMessageHandler extends SimpleChannelInboundHandler<GroupSendPa
|
|||||||
@Override
|
@Override
|
||||||
protected void channelRead0(ChannelHandlerContext channelHandlerContext, GroupSendPacket groupSendPacket) throws Exception {
|
protected void channelRead0(ChannelHandlerContext channelHandlerContext, GroupSendPacket groupSendPacket) throws Exception {
|
||||||
ChannelGroup group = SessionUtils.getChannelGroup(groupSendPacket.getGroupId());
|
ChannelGroup group = SessionUtils.getChannelGroup(groupSendPacket.getGroupId());
|
||||||
|
if (group == null) {
|
||||||
|
log.warn("群组不存在或未初始化: groupId={}", groupSendPacket.getGroupId());
|
||||||
|
throw new BusinessException("群组通道未初始化");
|
||||||
|
}
|
||||||
ByteBuf buff = getBuff(channelHandlerContext, groupSendPacket);
|
ByteBuf buff = getBuff(channelHandlerContext, groupSendPacket);
|
||||||
assert group != null;
|
|
||||||
group.writeAndFlush(new TextWebSocketFrame(buff));
|
group.writeAndFlush(new TextWebSocketFrame(buff));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,9 +4,12 @@ package com.realtime.packets.server.handler;
|
|||||||
|
|
||||||
|
|
||||||
import com.alibaba.fastjson2.JSONObject;
|
import com.alibaba.fastjson2.JSONObject;
|
||||||
|
import com.realtime.model.query.TeamCreateReq;
|
||||||
import com.realtime.packets.GroupPacket;
|
import com.realtime.packets.GroupPacket;
|
||||||
import com.realtime.service.GroupListService;
|
import com.realtime.service.GroupListService;
|
||||||
|
import com.realtime.service.TeamService;
|
||||||
import com.realtime.utils.SessionUtils;
|
import com.realtime.utils.SessionUtils;
|
||||||
|
import com.realtime.vo.TeamOperationVo;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.channel.Channel;
|
import io.netty.channel.Channel;
|
||||||
import io.netty.channel.ChannelHandler;
|
import io.netty.channel.ChannelHandler;
|
||||||
@@ -30,6 +33,8 @@ public class JoinGroupHandler extends SimpleChannelInboundHandler<GroupPacket> {
|
|||||||
|
|
||||||
private final GroupListService groupListService;
|
private final GroupListService groupListService;
|
||||||
|
|
||||||
|
private final TeamService teamService;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void channelRead0(ChannelHandlerContext channelHandlerContext, GroupPacket groupPacket) throws Exception {
|
protected void channelRead0(ChannelHandlerContext channelHandlerContext, GroupPacket groupPacket) throws Exception {
|
||||||
ChannelGroup channels = new DefaultChannelGroup(channelHandlerContext.executor());
|
ChannelGroup channels = new DefaultChannelGroup(channelHandlerContext.executor());
|
||||||
@@ -52,7 +57,14 @@ public class JoinGroupHandler extends SimpleChannelInboundHandler<GroupPacket> {
|
|||||||
groupPacket.setGroupId(groupId);
|
groupPacket.setGroupId(groupId);
|
||||||
byte[] bytes = JSONObject.toJSONString(groupPacket).getBytes(StandardCharsets.UTF_8);
|
byte[] bytes = JSONObject.toJSONString(groupPacket).getBytes(StandardCharsets.UTF_8);
|
||||||
byteBuf.writeBytes(bytes);
|
byteBuf.writeBytes(bytes);
|
||||||
groupListService.saveGroupList(groupPacket, groupId);
|
TeamCreateReq teamCreateReq = new TeamCreateReq();
|
||||||
|
teamCreateReq.setTeamName(groupPacket.getGroupName()+System.currentTimeMillis()+"_的团队");
|
||||||
|
teamCreateReq.setTeamDescription("默认介绍");
|
||||||
|
teamCreateReq.setTeamType("company");
|
||||||
|
teamCreateReq.setParentId("");
|
||||||
|
teamCreateReq.setGroup(groupId.toString());
|
||||||
|
TeamOperationVo team = teamService.createTeam(teamCreateReq);
|
||||||
|
groupListService.saveGroupList(groupPacket, groupId,team);
|
||||||
return byteBuf;
|
return byteBuf;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import com.alibaba.fastjson2.JSONObject;
|
|||||||
import com.realtime.config.NettyConfig;
|
import com.realtime.config.NettyConfig;
|
||||||
import com.realtime.packets.basePackets.BasePackets;
|
import com.realtime.packets.basePackets.BasePackets;
|
||||||
import com.realtime.packets.strategy.PacketService;
|
import com.realtime.packets.strategy.PacketService;
|
||||||
|
import com.realtime.utils.SessionUtils;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.channel.ChannelHandler;
|
import io.netty.channel.ChannelHandler;
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
@@ -16,6 +17,7 @@ import lombok.extern.slf4j.Slf4j;
|
|||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@@ -62,6 +64,10 @@ public class MessageSocketHandler extends SimpleChannelInboundHandler<TextWebSoc
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void channelInactive(ChannelHandlerContext ctx) {
|
public void channelInactive(ChannelHandlerContext ctx) {
|
||||||
|
log.info("连接断开: {}", ctx.channel().id().asShortText());
|
||||||
|
// 清理会话信息
|
||||||
|
SessionUtils.unbind(ctx.channel());
|
||||||
|
// 从通道组移除
|
||||||
NettyConfig.group.remove(ctx.channel());
|
NettyConfig.group.remove(ctx.channel());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -72,7 +78,15 @@ public class MessageSocketHandler extends SimpleChannelInboundHandler<TextWebSoc
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
|
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
|
||||||
cause.printStackTrace();
|
// 处理连接重置异常
|
||||||
// ctx.close();
|
if (cause instanceof IOException) {
|
||||||
|
log.warn("连接IO异常: {}, 通道: {}", cause.getMessage(), ctx.channel().id().asShortText());
|
||||||
|
} else {
|
||||||
|
log.error("处理消息异常: ", cause);
|
||||||
|
}
|
||||||
|
// 清理会话信息
|
||||||
|
SessionUtils.unbind(ctx.channel());
|
||||||
|
// 关闭连接
|
||||||
|
ctx.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
40
src/main/java/com/realtime/service/CloudFileService.java
Normal file
40
src/main/java/com/realtime/service/CloudFileService.java
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
package com.realtime.service;
|
||||||
|
|
||||||
|
import com.realtime.model.query.*;
|
||||||
|
import com.realtime.vo.CloudFileDownloadVo;
|
||||||
|
import com.realtime.vo.CloudFileListVo;
|
||||||
|
import com.realtime.vo.CloudFileOperationVo;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 云端文件服务接口
|
||||||
|
*/
|
||||||
|
public interface CloudFileService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量上传云端文件
|
||||||
|
*/
|
||||||
|
CloudFileOperationVo batchUpload(List<MultipartFile> files, CloudFileUploadReq request, String userId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过URL批量上传云端文件
|
||||||
|
*/
|
||||||
|
CloudFileOperationVo batchUploadByUrl(CloudFileUploadByUrlReq request, String userId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 下载文件
|
||||||
|
*/
|
||||||
|
CloudFileDownloadVo downloadFile(CloudFileDownloadReq request);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查看文件列表
|
||||||
|
*/
|
||||||
|
CloudFileListVo listFiles(CloudFileListReq request);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除文件
|
||||||
|
*/
|
||||||
|
CloudFileOperationVo deleteFile(CloudFileDeleteReq request);
|
||||||
|
}
|
||||||
@@ -13,13 +13,14 @@ import com.realtime.packets.GroupPacket;
|
|||||||
import com.realtime.sysconst.Result;
|
import com.realtime.sysconst.Result;
|
||||||
import com.realtime.vo.GroupDetailVo;
|
import com.realtime.vo.GroupDetailVo;
|
||||||
import com.realtime.vo.GroupListVo;
|
import com.realtime.vo.GroupListVo;
|
||||||
|
import com.realtime.vo.TeamOperationVo;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public interface GroupListService extends IService<GroupList> {
|
public interface GroupListService extends IService<GroupList> {
|
||||||
|
|
||||||
void saveGroupList(GroupPacket groupPacket, Long groupId);
|
void saveGroupList(GroupPacket groupPacket, Long groupId, TeamOperationVo teamOperationVo);
|
||||||
|
|
||||||
Result<IPage<GroupListVo>> getGroup(GroupListQueryReq groupDetailQueryReq);
|
Result<IPage<GroupListVo>> getGroup(GroupListQueryReq groupDetailQueryReq);
|
||||||
|
|
||||||
|
|||||||
73
src/main/java/com/realtime/service/TeamService.java
Normal file
73
src/main/java/com/realtime/service/TeamService.java
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
package com.realtime.service;
|
||||||
|
|
||||||
|
import com.realtime.model.query.*;
|
||||||
|
import com.realtime.vo.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 团队管理服务接口
|
||||||
|
*/
|
||||||
|
public interface TeamService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取用户可访问的团队列表
|
||||||
|
* @param request 团队列表查询请求
|
||||||
|
* @return 团队列表
|
||||||
|
*/
|
||||||
|
TeamListVo getTeamList(TeamListReq request);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建团队
|
||||||
|
* @param request 创建团队请求
|
||||||
|
* @return 创建结果
|
||||||
|
*/
|
||||||
|
TeamOperationVo createTeam(TeamCreateReq request);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除团队
|
||||||
|
* @param request 删除团队请求
|
||||||
|
* @return 删除结果
|
||||||
|
*/
|
||||||
|
TeamOperationVo deleteTeam(TeamDeleteReq request);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修改团队信息
|
||||||
|
* @param request 修改团队请求
|
||||||
|
* @return 修改结果
|
||||||
|
*/
|
||||||
|
TeamOperationVo updateTeam(TeamUpdateReq request);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查看全部成员
|
||||||
|
* @param request 查看成员请求
|
||||||
|
* @return 成员列表
|
||||||
|
*/
|
||||||
|
TeamMemberListVo getAllMembers(TeamGetAllMemberReq request);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量添加团队成员
|
||||||
|
* @param request 添加成员请求
|
||||||
|
* @return 添加结果
|
||||||
|
*/
|
||||||
|
TeamOperationVo addMembers(TeamAddMemberReq request);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量删除团队成员
|
||||||
|
* @param request 删除成员请求
|
||||||
|
* @return 删除结果
|
||||||
|
*/
|
||||||
|
TeamOperationVo removeMembers(TeamRemoveMemberReq request);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 调整团队成员身份
|
||||||
|
* @param request 调整身份请求
|
||||||
|
* @return 调整结果
|
||||||
|
*/
|
||||||
|
TeamOperationVo adjustMemberRole(TeamAdjustMemberRoleReq request);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取部门结构
|
||||||
|
* @param request 获取部门结构请求
|
||||||
|
* @return 部门结构
|
||||||
|
*/
|
||||||
|
TeamDepartmentVo getDepartment(TeamGetDepartmentReq request);
|
||||||
|
}
|
||||||
@@ -0,0 +1,167 @@
|
|||||||
|
package com.realtime.service.impl;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import com.realtime.config.CloudApiConfig;
|
||||||
|
import com.realtime.exception.BusinessException;
|
||||||
|
import com.realtime.model.query.*;
|
||||||
|
import com.realtime.service.CloudFileService;
|
||||||
|
import com.realtime.vo.*;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.core.io.FileSystemResource;
|
||||||
|
import org.springframework.http.*;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.util.LinkedMultiValueMap;
|
||||||
|
import org.springframework.util.MultiValueMap;
|
||||||
|
import org.springframework.web.client.RestTemplate;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 云端文件服务实现类
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Service
|
||||||
|
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
|
||||||
|
public class CloudFileServiceImpl implements CloudFileService {
|
||||||
|
|
||||||
|
private final CloudApiConfig cloudApiConfig;
|
||||||
|
private final RestTemplate restTemplate;
|
||||||
|
private final ObjectMapper objectMapper;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CloudFileOperationVo batchUpload(List<MultipartFile> files, CloudFileUploadReq request, String userId) {
|
||||||
|
if (files == null || files.isEmpty()) {
|
||||||
|
throw new BusinessException("文件列表不能为空");
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
String url = cloudApiConfig.getBaseUrl() + "/file/upload";
|
||||||
|
|
||||||
|
// 构建multipart请求
|
||||||
|
HttpHeaders headers = new HttpHeaders();
|
||||||
|
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
|
||||||
|
|
||||||
|
MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
|
||||||
|
|
||||||
|
// 添加文件
|
||||||
|
for (MultipartFile file : files) {
|
||||||
|
body.add("files", file.getResource());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加其他参数
|
||||||
|
body.add("path", request.getPath());
|
||||||
|
body.add("type", request.getType());
|
||||||
|
if (request.getTeamId() != null) {
|
||||||
|
body.add("team_id", request.getTeamId());
|
||||||
|
}
|
||||||
|
|
||||||
|
HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(body, headers);
|
||||||
|
|
||||||
|
// 调用外部API
|
||||||
|
ResponseEntity<CloudFileOperationVo> response = restTemplate.postForEntity(
|
||||||
|
url, requestEntity, CloudFileOperationVo.class);
|
||||||
|
|
||||||
|
return response.getBody();
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("批量上传文件失败", e);
|
||||||
|
throw new BusinessException("批量上传文件失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CloudFileOperationVo batchUploadByUrl(CloudFileUploadByUrlReq request, String userId) {
|
||||||
|
if (request.getUrls() == null || request.getUrls().isEmpty()) {
|
||||||
|
throw new BusinessException("URL列表不能为空");
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
String url = cloudApiConfig.getBaseUrl() + "/file/upload/url";
|
||||||
|
|
||||||
|
// 构建请求
|
||||||
|
HttpHeaders headers = new HttpHeaders();
|
||||||
|
headers.setContentType(MediaType.APPLICATION_JSON);
|
||||||
|
|
||||||
|
HttpEntity<CloudFileUploadByUrlReq> requestEntity = new HttpEntity<>(request, headers);
|
||||||
|
|
||||||
|
// 调用外部API
|
||||||
|
ResponseEntity<CloudFileOperationVo> response = restTemplate.postForEntity(
|
||||||
|
url, requestEntity, CloudFileOperationVo.class);
|
||||||
|
|
||||||
|
return response.getBody();
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("批量URL上传文件失败", e);
|
||||||
|
throw new BusinessException("批量URL上传文件失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CloudFileDownloadVo downloadFile(CloudFileDownloadReq request) {
|
||||||
|
try {
|
||||||
|
String url = cloudApiConfig.getBaseUrl() + "/file/download";
|
||||||
|
|
||||||
|
// 构建请求
|
||||||
|
HttpHeaders headers = new HttpHeaders();
|
||||||
|
headers.setContentType(MediaType.APPLICATION_JSON);
|
||||||
|
|
||||||
|
HttpEntity<CloudFileDownloadReq> requestEntity = new HttpEntity<>(request, headers);
|
||||||
|
|
||||||
|
// 调用外部API
|
||||||
|
ResponseEntity<CloudFileDownloadVo> response = restTemplate.postForEntity(
|
||||||
|
url, requestEntity, CloudFileDownloadVo.class);
|
||||||
|
|
||||||
|
return response.getBody();
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("生成下载链接失败", e);
|
||||||
|
throw new BusinessException("生成下载链接失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CloudFileListVo listFiles(CloudFileListReq request) {
|
||||||
|
try {
|
||||||
|
String url = cloudApiConfig.getBaseUrl() + "/file/list";
|
||||||
|
|
||||||
|
// 构建请求
|
||||||
|
HttpHeaders headers = new HttpHeaders();
|
||||||
|
headers.setContentType(MediaType.APPLICATION_JSON);
|
||||||
|
|
||||||
|
HttpEntity<CloudFileListReq> requestEntity = new HttpEntity<>(request, headers);
|
||||||
|
|
||||||
|
// 调用外部API
|
||||||
|
ResponseEntity<CloudFileListVo> response = restTemplate.postForEntity(
|
||||||
|
url, requestEntity, CloudFileListVo.class);
|
||||||
|
|
||||||
|
return response.getBody();
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("查询文件列表失败", e);
|
||||||
|
throw new BusinessException("查询文件列表失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CloudFileOperationVo deleteFile(CloudFileDeleteReq request) {
|
||||||
|
try {
|
||||||
|
String url = cloudApiConfig.getBaseUrl() + "/file/delete";
|
||||||
|
|
||||||
|
// 构建请求
|
||||||
|
HttpHeaders headers = new HttpHeaders();
|
||||||
|
headers.setContentType(MediaType.APPLICATION_JSON);
|
||||||
|
|
||||||
|
HttpEntity<CloudFileDeleteReq> requestEntity = new HttpEntity<>(request, headers);
|
||||||
|
|
||||||
|
// 调用外部API
|
||||||
|
ResponseEntity<CloudFileOperationVo> response = restTemplate.postForEntity(
|
||||||
|
url, requestEntity, CloudFileOperationVo.class);
|
||||||
|
|
||||||
|
return response.getBody();
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("删除文件失败", e);
|
||||||
|
throw new BusinessException("删除文件失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -25,6 +25,7 @@ import java.math.BigDecimal;
|
|||||||
import java.math.RoundingMode;
|
import java.math.RoundingMode;
|
||||||
import java.security.InvalidKeyException;
|
import java.security.InvalidKeyException;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.time.Instant;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
@@ -51,7 +52,7 @@ public class FileServiceImpl implements FileService {
|
|||||||
throw new BusinessException(ResultEnum.FILE_FORMAT_ERROR);
|
throw new BusinessException(ResultEnum.FILE_FORMAT_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
UploadVo vo = generateFileName(file,fileSuffix);
|
UploadVo vo = generateFileName(file, fileSuffix);
|
||||||
InputStream inputStream = file.getInputStream();
|
InputStream inputStream = file.getInputStream();
|
||||||
minioClient.putObject(PutObjectArgs.builder()
|
minioClient.putObject(PutObjectArgs.builder()
|
||||||
.bucket(minioConfig.getBucketName())
|
.bucket(minioConfig.getBucketName())
|
||||||
@@ -64,26 +65,25 @@ public class FileServiceImpl implements FileService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private UploadVo generateFileName(MultipartFile file,String fileSuffix) {
|
private UploadVo generateFileName(MultipartFile file, String fileSuffix) {
|
||||||
String originalFilename = file.getOriginalFilename();
|
String originalFilename = file.getOriginalFilename();
|
||||||
assert originalFilename != null;
|
assert originalFilename != null;
|
||||||
UploadVo uploadVo = new UploadVo();
|
UploadVo uploadVo = new UploadVo();
|
||||||
String storeFileName = UUID.randomUUID() + "_" + originalFilename;
|
String storeFileName = originalFilename + Instant.now().getEpochSecond();
|
||||||
String url = generateFileUrl(storeFileName);
|
String url = generateFileUrl(storeFileName);
|
||||||
uploadVo.setName(originalFilename);
|
uploadVo.setName(originalFilename);
|
||||||
uploadVo.setUrl(url);
|
uploadVo.setUrl(url);
|
||||||
uploadVo.setExtendName(fileSuffix);
|
uploadVo.setExtendName(fileSuffix);
|
||||||
uploadVo.setNewFileName(storeFileName);
|
uploadVo.setNewFileName(storeFileName);
|
||||||
uploadVo.setFileSize(BigDecimal.valueOf(file.getSize()).divide(BigDecimal.valueOf(1048576)).setScale(3, RoundingMode.HALF_UP)); // MB
|
uploadVo.setFileSize(BigDecimal.valueOf(file.getSize()).divide(BigDecimal.valueOf(1048576), 3, RoundingMode.HALF_UP)); // MB
|
||||||
uploadVo.setFileNameCode(Base64.encode(originalFilename));
|
uploadVo.setFileNameCode(Base64.encode(originalFilename));
|
||||||
return uploadVo;
|
return uploadVo;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private String generateFileUrl(String fileName) {
|
|
||||||
return
|
String generateFileUrl(String fileName) {
|
||||||
minioConfig.getEndpoint()+"/real/" + fileName;
|
return new StringBuilder().append(minioConfig.getEndpoint()).append("/").append(minioConfig.getBucketName()).append("/").append(fileName).toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
package com.realtime.service.impl;
|
package com.realtime.service.impl;
|
||||||
|
|
||||||
|
|
||||||
|
import com.alibaba.fastjson2.JSON;
|
||||||
|
import com.alibaba.fastjson2.JSONObject;
|
||||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
import com.google.zxing.BarcodeFormat;
|
import com.google.zxing.BarcodeFormat;
|
||||||
@@ -12,17 +14,22 @@ import com.realtime.exception.BusinessException;
|
|||||||
import com.realtime.mappers.GroupListMapper;
|
import com.realtime.mappers.GroupListMapper;
|
||||||
import com.realtime.model.pojo.GroupList;
|
import com.realtime.model.pojo.GroupList;
|
||||||
import com.realtime.model.pojo.GroupMember;
|
import com.realtime.model.pojo.GroupMember;
|
||||||
|
import com.realtime.model.query.CloudFileListReq;
|
||||||
import com.realtime.model.query.GroupDetailQueryReq;
|
import com.realtime.model.query.GroupDetailQueryReq;
|
||||||
import com.realtime.model.query.GroupListQueryReq;
|
import com.realtime.model.query.GroupListQueryReq;
|
||||||
import com.realtime.model.remove.DisbandGroupReq;
|
import com.realtime.model.remove.DisbandGroupReq;
|
||||||
import com.realtime.model.update.GroupInventUpdateReq;
|
import com.realtime.model.update.GroupInventUpdateReq;
|
||||||
import com.realtime.packets.GroupPacket;
|
import com.realtime.packets.GroupPacket;
|
||||||
|
import com.realtime.service.CloudFileService;
|
||||||
import com.realtime.service.GroupListService;
|
import com.realtime.service.GroupListService;
|
||||||
import com.realtime.service.GroupMemberService;
|
import com.realtime.service.GroupMemberService;
|
||||||
|
import com.realtime.service.TeamService;
|
||||||
import com.realtime.sysconst.Result;
|
import com.realtime.sysconst.Result;
|
||||||
import com.realtime.utils.SessionUtils;
|
import com.realtime.utils.SessionUtils;
|
||||||
|
import com.realtime.vo.CloudFileListVo;
|
||||||
import com.realtime.vo.GroupDetailVo;
|
import com.realtime.vo.GroupDetailVo;
|
||||||
import com.realtime.vo.GroupListVo;
|
import com.realtime.vo.GroupListVo;
|
||||||
|
import com.realtime.vo.TeamOperationVo;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
@@ -33,10 +40,7 @@ import javax.imageio.ImageIO;
|
|||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.Base64;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Service
|
@Service
|
||||||
@@ -46,13 +50,21 @@ public class GroupListServiceImpl extends ServiceImpl<GroupListMapper, GroupList
|
|||||||
|
|
||||||
private final GroupMemberService groupMemberService;
|
private final GroupMemberService groupMemberService;
|
||||||
|
|
||||||
|
private final TeamService teamService;
|
||||||
|
|
||||||
|
private final CloudFileService cloudFileService;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public void saveGroupList(GroupPacket groupPacket, Long groupId) {
|
public void saveGroupList(GroupPacket groupPacket, Long groupId, TeamOperationVo teamOperationVo) {
|
||||||
GroupList groupList = new GroupList();
|
GroupList groupList = new GroupList();
|
||||||
groupList.setId(groupId);
|
groupList.setId(groupId);
|
||||||
groupList.setCreator(groupPacket.getSender());
|
groupList.setCreator(groupPacket.getSender());
|
||||||
groupList.setOwner(1);
|
groupList.setOwner(1);
|
||||||
|
|
||||||
|
Map<String,Object> teamData = (Map<String, Object>) teamOperationVo.getTeam().get("team");
|
||||||
|
|
||||||
|
groupList.setTeamId(teamData.get("id").toString());
|
||||||
groupList.setName(groupPacket.getGroupName());
|
groupList.setName(groupPacket.getGroupName());
|
||||||
save(groupList);
|
save(groupList);
|
||||||
|
|
||||||
@@ -78,7 +90,14 @@ public class GroupListServiceImpl extends ServiceImpl<GroupListMapper, GroupList
|
|||||||
byte[] bytes = baos.toByteArray();
|
byte[] bytes = baos.toByteArray();
|
||||||
String qrcode = "data:image/png;base64,"+ Base64.getEncoder().encodeToString(bytes);
|
String qrcode = "data:image/png;base64,"+ Base64.getEncoder().encodeToString(bytes);
|
||||||
GroupDetailVo groupDetail = baseMapper.getGroupDetail(queryReq);
|
GroupDetailVo groupDetail = baseMapper.getGroupDetail(queryReq);
|
||||||
|
CloudFileListReq cloudFileListReq = new CloudFileListReq();
|
||||||
|
cloudFileListReq.setAccessToken(queryReq.getAccessToken());
|
||||||
|
cloudFileListReq.setTeamId(groupDetail.getTeamId());
|
||||||
|
cloudFileListReq.setType("user");
|
||||||
|
cloudFileListReq.setPath("/");
|
||||||
|
CloudFileListVo cloudFileListVo = cloudFileService.listFiles(cloudFileListReq);
|
||||||
groupDetail.setQrCode(qrcode);
|
groupDetail.setQrCode(qrcode);
|
||||||
|
groupDetail.setTeamFileData(cloudFileListVo);
|
||||||
return Result.success(groupDetail);
|
return Result.success(groupDetail);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
278
src/main/java/com/realtime/service/impl/TeamServiceImpl.java
Normal file
278
src/main/java/com/realtime/service/impl/TeamServiceImpl.java
Normal file
@@ -0,0 +1,278 @@
|
|||||||
|
package com.realtime.service.impl;
|
||||||
|
|
||||||
|
import com.realtime.config.CloudApiConfig;
|
||||||
|
import com.realtime.exception.BusinessException;
|
||||||
|
import com.realtime.model.query.*;
|
||||||
|
import com.realtime.service.TeamService;
|
||||||
|
import com.realtime.vo.*;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.http.*;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.web.client.RestTemplate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 团队管理服务实现类
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Service
|
||||||
|
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
|
||||||
|
public class TeamServiceImpl implements TeamService {
|
||||||
|
|
||||||
|
private final CloudApiConfig cloudApiConfig;
|
||||||
|
private final RestTemplate restTemplate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取用户可访问的团队列表
|
||||||
|
*
|
||||||
|
* @param request 团队列表查询请求
|
||||||
|
* @return 团队列表
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public TeamListVo getTeamList(TeamListReq request) {
|
||||||
|
try {
|
||||||
|
String url = cloudApiConfig.getBaseUrl() + "/team/list";
|
||||||
|
|
||||||
|
// 构建请求
|
||||||
|
HttpHeaders headers = new HttpHeaders();
|
||||||
|
headers.setContentType(MediaType.APPLICATION_JSON);
|
||||||
|
|
||||||
|
HttpEntity<TeamListReq> requestEntity = new HttpEntity<>(request, headers);
|
||||||
|
|
||||||
|
// 调用外部API
|
||||||
|
ResponseEntity<TeamListVo> response = restTemplate.postForEntity(
|
||||||
|
url, requestEntity, TeamListVo.class);
|
||||||
|
|
||||||
|
return response.getBody();
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("获取团队列表失败", e);
|
||||||
|
throw new BusinessException("获取团队列表失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建团队
|
||||||
|
*
|
||||||
|
* @param request 创建团队请求
|
||||||
|
* @return 创建结果
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public TeamOperationVo createTeam(TeamCreateReq request) {
|
||||||
|
try {
|
||||||
|
String url = cloudApiConfig.getBaseUrl() + "/team/create";
|
||||||
|
|
||||||
|
// 构建请求
|
||||||
|
HttpHeaders headers = new HttpHeaders();
|
||||||
|
headers.setContentType(MediaType.APPLICATION_JSON);
|
||||||
|
|
||||||
|
HttpEntity<TeamCreateReq> requestEntity = new HttpEntity<>(request, headers);
|
||||||
|
|
||||||
|
// 调用外部API
|
||||||
|
ResponseEntity<TeamOperationVo> response = restTemplate.postForEntity(
|
||||||
|
url, requestEntity, TeamOperationVo.class);
|
||||||
|
|
||||||
|
return response.getBody();
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("创建团队失败", e);
|
||||||
|
throw new BusinessException("创建团队失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除团队
|
||||||
|
*
|
||||||
|
* @param request 删除团队请求
|
||||||
|
* @return 删除结果
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public TeamOperationVo deleteTeam(TeamDeleteReq request) {
|
||||||
|
try {
|
||||||
|
String url = cloudApiConfig.getBaseUrl() + "/team/delete";
|
||||||
|
|
||||||
|
// 构建请求
|
||||||
|
HttpHeaders headers = new HttpHeaders();
|
||||||
|
headers.setContentType(MediaType.APPLICATION_JSON);
|
||||||
|
|
||||||
|
HttpEntity<TeamDeleteReq> requestEntity = new HttpEntity<>(request, headers);
|
||||||
|
|
||||||
|
// 调用外部API
|
||||||
|
ResponseEntity<TeamOperationVo> response = restTemplate.postForEntity(
|
||||||
|
url, requestEntity, TeamOperationVo.class);
|
||||||
|
|
||||||
|
return response.getBody();
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("删除团队失败", e);
|
||||||
|
throw new BusinessException("删除团队失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修改团队信息
|
||||||
|
*
|
||||||
|
* @param request 修改团队请求
|
||||||
|
* @return 修改结果
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public TeamOperationVo updateTeam(TeamUpdateReq request) {
|
||||||
|
try {
|
||||||
|
String url = cloudApiConfig.getBaseUrl() + "/team/update";
|
||||||
|
|
||||||
|
// 构建请求
|
||||||
|
HttpHeaders headers = new HttpHeaders();
|
||||||
|
headers.setContentType(MediaType.APPLICATION_JSON);
|
||||||
|
|
||||||
|
HttpEntity<TeamUpdateReq> requestEntity = new HttpEntity<>(request, headers);
|
||||||
|
|
||||||
|
// 调用外部API
|
||||||
|
ResponseEntity<TeamOperationVo> response = restTemplate.postForEntity(
|
||||||
|
url, requestEntity, TeamOperationVo.class);
|
||||||
|
|
||||||
|
return response.getBody();
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("修改团队信息失败", e);
|
||||||
|
throw new BusinessException("修改团队信息失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查看全部成员
|
||||||
|
*
|
||||||
|
* @param request 查看成员请求
|
||||||
|
* @return 成员列表
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public TeamMemberListVo getAllMembers(TeamGetAllMemberReq request) {
|
||||||
|
try {
|
||||||
|
String url = cloudApiConfig.getBaseUrl() + "/team/get_all_member";
|
||||||
|
|
||||||
|
// 构建请求
|
||||||
|
HttpHeaders headers = new HttpHeaders();
|
||||||
|
headers.setContentType(MediaType.APPLICATION_JSON);
|
||||||
|
|
||||||
|
HttpEntity<TeamGetAllMemberReq> requestEntity = new HttpEntity<>(request, headers);
|
||||||
|
|
||||||
|
// 调用外部API
|
||||||
|
ResponseEntity<TeamMemberListVo> response = restTemplate.postForEntity(
|
||||||
|
url, requestEntity, TeamMemberListVo.class);
|
||||||
|
|
||||||
|
return response.getBody();
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("查看团队成员失败", e);
|
||||||
|
throw new BusinessException("查看团队成员失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量添加团队成员
|
||||||
|
*
|
||||||
|
* @param request 添加成员请求
|
||||||
|
* @return 添加结果
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public TeamOperationVo addMembers(TeamAddMemberReq request) {
|
||||||
|
try {
|
||||||
|
String url = cloudApiConfig.getBaseUrl() + "/team/add_member";
|
||||||
|
|
||||||
|
// 构建请求
|
||||||
|
HttpHeaders headers = new HttpHeaders();
|
||||||
|
headers.setContentType(MediaType.APPLICATION_JSON);
|
||||||
|
|
||||||
|
HttpEntity<TeamAddMemberReq> requestEntity = new HttpEntity<>(request, headers);
|
||||||
|
|
||||||
|
// 调用外部API
|
||||||
|
ResponseEntity<TeamOperationVo> response = restTemplate.postForEntity(
|
||||||
|
url, requestEntity, TeamOperationVo.class);
|
||||||
|
|
||||||
|
return response.getBody();
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("添加团队成员失败", e);
|
||||||
|
throw new BusinessException("添加团队成员失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量删除团队成员
|
||||||
|
*
|
||||||
|
* @param request 删除成员请求
|
||||||
|
* @return 删除结果
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public TeamOperationVo removeMembers(TeamRemoveMemberReq request) {
|
||||||
|
try {
|
||||||
|
String url = cloudApiConfig.getBaseUrl() + "/team/remove_member";
|
||||||
|
|
||||||
|
// 构建请求
|
||||||
|
HttpHeaders headers = new HttpHeaders();
|
||||||
|
headers.setContentType(MediaType.APPLICATION_JSON);
|
||||||
|
|
||||||
|
HttpEntity<TeamRemoveMemberReq> requestEntity = new HttpEntity<>(request, headers);
|
||||||
|
|
||||||
|
// 调用外部API
|
||||||
|
ResponseEntity<TeamOperationVo> response = restTemplate.postForEntity(
|
||||||
|
url, requestEntity, TeamOperationVo.class);
|
||||||
|
|
||||||
|
return response.getBody();
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("删除团队成员失败", e);
|
||||||
|
throw new BusinessException("删除团队成员失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 调整团队成员身份
|
||||||
|
*
|
||||||
|
* @param request 调整身份请求
|
||||||
|
* @return 调整结果
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public TeamOperationVo adjustMemberRole(TeamAdjustMemberRoleReq request) {
|
||||||
|
try {
|
||||||
|
String url = cloudApiConfig.getBaseUrl() + "/team/adjust_member_role";
|
||||||
|
|
||||||
|
// 构建请求
|
||||||
|
HttpHeaders headers = new HttpHeaders();
|
||||||
|
headers.setContentType(MediaType.APPLICATION_JSON);
|
||||||
|
|
||||||
|
HttpEntity<TeamAdjustMemberRoleReq> requestEntity = new HttpEntity<>(request, headers);
|
||||||
|
|
||||||
|
// 调用外部API
|
||||||
|
ResponseEntity<TeamOperationVo> response = restTemplate.postForEntity(
|
||||||
|
url, requestEntity, TeamOperationVo.class);
|
||||||
|
|
||||||
|
return response.getBody();
|
||||||
|
} catch (Exception e) {
|
||||||
|
|
||||||
|
log.error("调整团队成员身份失败", e);
|
||||||
|
throw new BusinessException("调整团队成员身份失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取部门结构
|
||||||
|
*
|
||||||
|
* @param request 获取部门结构请求
|
||||||
|
* @return 部门结构
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public TeamDepartmentVo getDepartment(TeamGetDepartmentReq request) {
|
||||||
|
try {
|
||||||
|
String url = cloudApiConfig.getBaseUrl() + "/team/get_department";
|
||||||
|
|
||||||
|
// 构建请求
|
||||||
|
HttpHeaders headers = new HttpHeaders();
|
||||||
|
headers.setContentType(MediaType.APPLICATION_JSON);
|
||||||
|
|
||||||
|
HttpEntity<TeamGetDepartmentReq> requestEntity = new HttpEntity<>(request, headers);
|
||||||
|
|
||||||
|
// 调用外部API
|
||||||
|
ResponseEntity<TeamDepartmentVo> response = restTemplate.postForEntity(
|
||||||
|
url, requestEntity, TeamDepartmentVo.class);
|
||||||
|
|
||||||
|
return response.getBody();
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("获取部门结构失败", e);
|
||||||
|
throw new BusinessException("获取部门结构失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,11 +3,13 @@ package com.realtime.utils;
|
|||||||
import com.realtime.packets.basePackets.BasePackets;
|
import com.realtime.packets.basePackets.BasePackets;
|
||||||
import io.netty.channel.Channel;
|
import io.netty.channel.Channel;
|
||||||
import io.netty.channel.group.ChannelGroup;
|
import io.netty.channel.group.ChannelGroup;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
public class SessionUtils {
|
public class SessionUtils {
|
||||||
|
|
||||||
public static final Map<String, Channel> userIdChannelMap = new ConcurrentHashMap<>();
|
public static final Map<String, Channel> userIdChannelMap = new ConcurrentHashMap<>();
|
||||||
@@ -27,7 +29,22 @@ public class SessionUtils {
|
|||||||
|
|
||||||
public static void unbind(Channel channel) {
|
public static void unbind(Channel channel) {
|
||||||
if (hasLogin(channel)) {
|
if (hasLogin(channel)) {
|
||||||
userIdChannelMap.remove(getUser(channel).getSender());
|
BasePackets user = getUser(channel);
|
||||||
|
if (user != null && user.getSender() != null) {
|
||||||
|
log.info("清理用户会话: userId={}, channel={}", user.getSender(), channel.id().asShortText());
|
||||||
|
// 从用户-通道映射中移除
|
||||||
|
userIdChannelMap.remove(user.getSender());
|
||||||
|
// 从会话用户映射中移除
|
||||||
|
sessionUser.remove(user.getSender());
|
||||||
|
// 从所有群组中移除该通道
|
||||||
|
groupIdChannelGroupMap.values().forEach(channelGroup -> {
|
||||||
|
if (channelGroup != null && channelGroup.contains(channel)) {
|
||||||
|
channelGroup.remove(channel);
|
||||||
|
log.debug("从群组中移除通道: {}", channel.id().asShortText());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// 清除通道属性
|
||||||
channel.attr(Attributes.SESSION).set(null);
|
channel.attr(Attributes.SESSION).set(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
29
src/main/java/com/realtime/vo/CloudFileDownloadVo.java
Normal file
29
src/main/java/com/realtime/vo/CloudFileDownloadVo.java
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
package com.realtime.vo;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 云端文件下载响应VO
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class CloudFileDownloadVo implements Serializable {
|
||||||
|
|
||||||
|
private Boolean success;
|
||||||
|
|
||||||
|
private DownloadData data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public static class DownloadData implements Serializable {
|
||||||
|
@JsonProperty("download_url")
|
||||||
|
private String downloadUrl;
|
||||||
|
}
|
||||||
|
}
|
||||||
24
src/main/java/com/realtime/vo/CloudFileListVo.java
Normal file
24
src/main/java/com/realtime/vo/CloudFileListVo.java
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
package com.realtime.vo;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 云端文件列表响应VO
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class CloudFileListVo implements Serializable {
|
||||||
|
|
||||||
|
private Boolean success;
|
||||||
|
|
||||||
|
private List<CloudFileVo> data;
|
||||||
|
|
||||||
|
private Integer count;
|
||||||
|
}
|
||||||
22
src/main/java/com/realtime/vo/CloudFileOperationVo.java
Normal file
22
src/main/java/com/realtime/vo/CloudFileOperationVo.java
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
package com.realtime.vo;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 云端文件操作响应VO
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class CloudFileOperationVo implements Serializable {
|
||||||
|
|
||||||
|
private Boolean success;
|
||||||
|
|
||||||
|
private String message;
|
||||||
|
|
||||||
|
private String error;
|
||||||
|
}
|
||||||
49
src/main/java/com/realtime/vo/CloudFileVo.java
Normal file
49
src/main/java/com/realtime/vo/CloudFileVo.java
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
package com.realtime.vo;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 云端文件VO
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class CloudFileVo implements Serializable {
|
||||||
|
|
||||||
|
private String id;
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
private String path;
|
||||||
|
|
||||||
|
@JsonProperty("full_path")
|
||||||
|
private String fullPath;
|
||||||
|
|
||||||
|
private Long size;
|
||||||
|
|
||||||
|
private String type;
|
||||||
|
|
||||||
|
@JsonProperty("owner_id")
|
||||||
|
private String ownerId;
|
||||||
|
|
||||||
|
@JsonProperty("owner_type")
|
||||||
|
private String ownerType;
|
||||||
|
|
||||||
|
@JsonProperty("updated_id")
|
||||||
|
private String updatedId;
|
||||||
|
|
||||||
|
@JsonProperty("created_at")
|
||||||
|
private LocalDateTime createdAt;
|
||||||
|
|
||||||
|
@JsonProperty("updated_at")
|
||||||
|
private LocalDateTime updatedAt;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 子文件/文件夹列表
|
||||||
|
*/
|
||||||
|
private List<CloudFileVo> children = new ArrayList<>();
|
||||||
|
}
|
||||||
@@ -2,6 +2,8 @@ package com.realtime.vo;
|
|||||||
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
public class GroupDetailVo {
|
public class GroupDetailVo {
|
||||||
private Long id;
|
private Long id;
|
||||||
@@ -10,4 +12,7 @@ public class GroupDetailVo {
|
|||||||
private Integer isInvent;
|
private Integer isInvent;
|
||||||
private String creator;
|
private String creator;
|
||||||
private String qrCode;
|
private String qrCode;
|
||||||
|
private String teamId;
|
||||||
|
private CloudFileListVo teamFileData;
|
||||||
|
private String teamInfo;
|
||||||
}
|
}
|
||||||
|
|||||||
20
src/main/java/com/realtime/vo/TeamDepartmentVo.java
Normal file
20
src/main/java/com/realtime/vo/TeamDepartmentVo.java
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
package com.realtime.vo;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 部门结构响应VO
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class TeamDepartmentVo implements Serializable {
|
||||||
|
|
||||||
|
private Boolean success;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 部门结构数据
|
||||||
|
*/
|
||||||
|
private Map<String, Object> data;
|
||||||
|
}
|
||||||
21
src/main/java/com/realtime/vo/TeamListVo.java
Normal file
21
src/main/java/com/realtime/vo/TeamListVo.java
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
package com.realtime.vo;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 团队列表响应VO
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class TeamListVo implements Serializable {
|
||||||
|
|
||||||
|
private Boolean success;
|
||||||
|
|
||||||
|
private List<TeamVo> teams;
|
||||||
|
|
||||||
|
@JsonProperty("total_count")
|
||||||
|
private Integer totalCount;
|
||||||
|
}
|
||||||
21
src/main/java/com/realtime/vo/TeamMemberListVo.java
Normal file
21
src/main/java/com/realtime/vo/TeamMemberListVo.java
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
package com.realtime.vo;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 团队成员列表响应VO
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class TeamMemberListVo implements Serializable {
|
||||||
|
|
||||||
|
private Boolean success;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 嵌套的团队成员数据
|
||||||
|
*/
|
||||||
|
private Map<String, Object> team;
|
||||||
|
}
|
||||||
34
src/main/java/com/realtime/vo/TeamMemberUserVo.java
Normal file
34
src/main/java/com/realtime/vo/TeamMemberUserVo.java
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
package com.realtime.vo;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 团队成员用户信息VO
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class TeamMemberUserVo implements Serializable {
|
||||||
|
|
||||||
|
@JsonProperty("_id")
|
||||||
|
private String id;
|
||||||
|
|
||||||
|
private String username;
|
||||||
|
|
||||||
|
private String email;
|
||||||
|
|
||||||
|
@JsonProperty("is_beta")
|
||||||
|
private Boolean isBeta;
|
||||||
|
|
||||||
|
@JsonProperty("trial_end_date")
|
||||||
|
private String trialEndDate;
|
||||||
|
|
||||||
|
@JsonProperty("trial_start_date")
|
||||||
|
private String trialStartDate;
|
||||||
|
|
||||||
|
@JsonProperty("lastLogin")
|
||||||
|
private String lastLogin;
|
||||||
|
|
||||||
|
private String role;
|
||||||
|
}
|
||||||
38
src/main/java/com/realtime/vo/TeamMemberVo.java
Normal file
38
src/main/java/com/realtime/vo/TeamMemberVo.java
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
package com.realtime.vo;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 团队成员VO
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class TeamMemberVo implements Serializable {
|
||||||
|
|
||||||
|
@JsonProperty("_id")
|
||||||
|
private String id;
|
||||||
|
|
||||||
|
@JsonProperty("team_id")
|
||||||
|
private String teamId;
|
||||||
|
|
||||||
|
@JsonProperty("user_id")
|
||||||
|
private String userId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 角色:admin、member
|
||||||
|
*/
|
||||||
|
private String role;
|
||||||
|
|
||||||
|
@JsonProperty("created_at")
|
||||||
|
private String createdAt;
|
||||||
|
|
||||||
|
@JsonProperty("updated_at")
|
||||||
|
private String updatedAt;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户信息
|
||||||
|
*/
|
||||||
|
private TeamMemberUserVo user;
|
||||||
|
}
|
||||||
22
src/main/java/com/realtime/vo/TeamOperationVo.java
Normal file
22
src/main/java/com/realtime/vo/TeamOperationVo.java
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
package com.realtime.vo;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 团队操作响应VO
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class TeamOperationVo implements Serializable {
|
||||||
|
|
||||||
|
private Boolean success;
|
||||||
|
|
||||||
|
private String message;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 嵌套的团队数据
|
||||||
|
*/
|
||||||
|
private Map<String, Object> team;
|
||||||
|
}
|
||||||
31
src/main/java/com/realtime/vo/TeamVo.java
Normal file
31
src/main/java/com/realtime/vo/TeamVo.java
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
package com.realtime.vo;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 团队VO
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class TeamVo implements Serializable {
|
||||||
|
|
||||||
|
@JsonProperty("_id")
|
||||||
|
private String id;
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
@JsonProperty("created_at")
|
||||||
|
private String createdAt;
|
||||||
|
|
||||||
|
@JsonProperty("updated_at")
|
||||||
|
private String updatedAt;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户在该团队的角色:admin、member
|
||||||
|
*/
|
||||||
|
private String role;
|
||||||
|
}
|
||||||
@@ -6,7 +6,7 @@ minio:
|
|||||||
endpoint: https://database.yuxindazhineng.com
|
endpoint: https://database.yuxindazhineng.com
|
||||||
access-key: yuxinda_admin
|
access-key: yuxinda_admin
|
||||||
secret-key: yuxinda_admin01
|
secret-key: yuxinda_admin01
|
||||||
bucket-name: real
|
bucket-name: team-bucket
|
||||||
file:
|
file:
|
||||||
picMaxSize: 104857600 # 100MB
|
picMaxSize: 104857600 # 100MB
|
||||||
picMaxCount: 1
|
picMaxCount: 1
|
||||||
@@ -22,7 +22,7 @@ spring:
|
|||||||
url: jdbc:mysql://8.134.75.237:3309/real_time?serverTimezone=Asia/Shanghai
|
url: jdbc:mysql://8.134.75.237:3309/real_time?serverTimezone=Asia/Shanghai
|
||||||
username: root
|
username: root
|
||||||
password: zhengfei_2024
|
password: zhengfei_2024
|
||||||
type: com.alibaba.druid.pool.DruidDataSource
|
type: com.zaxxer.hikari.HikariDataSource
|
||||||
mybatis-plus:
|
mybatis-plus:
|
||||||
configuration:
|
configuration:
|
||||||
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
|
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
id
|
id
|
||||||
,name,creator,
|
,name,creator,
|
||||||
created_time,picture,type,
|
created_time,picture,type,
|
||||||
is_invent
|
is_invent,team_id
|
||||||
</sql>
|
</sql>
|
||||||
|
|
||||||
<select id="getGroup" resultType="groupListVo">
|
<select id="getGroup" resultType="groupListVo">
|
||||||
|
|||||||
Reference in New Issue
Block a user