优化代码提交

This commit is contained in:
lilin 2025-06-23 18:02:57 +08:00
parent e88750b00c
commit 6ee6386344
17 changed files with 1007 additions and 229 deletions

View File

@ -19,11 +19,14 @@
<java.version>1.8</java.version> <java.version>1.8</java.version>
</properties> </properties>
<dependencies> <dependencies>
<!-- spring-web --> <!-- spring-web -->
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId> <artifactId>spring-boot-starter-web</artifactId>
</dependency> </dependency>
<!-- 生成二维码 --> <!-- 生成二维码 -->
<dependency> <dependency>
<groupId>com.google.zxing</groupId> <groupId>com.google.zxing</groupId>

View File

@ -8,11 +8,16 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.yfd.platform.annotation.Log; import com.yfd.platform.annotation.Log;
import com.yfd.platform.component.TaskStatusHolder; import com.yfd.platform.component.TaskStatusHolder;
import com.yfd.platform.config.ResponseResult; import com.yfd.platform.config.ResponseResult;
import com.yfd.platform.modules.experimentalData.domain.TsFiles;
import com.yfd.platform.modules.experimentalData.domain.TsNodes; import com.yfd.platform.modules.experimentalData.domain.TsNodes;
import com.yfd.platform.modules.experimentalData.domain.TsTask;
import com.yfd.platform.modules.experimentalData.service.ITsFilesService;
import com.yfd.platform.modules.experimentalData.service.ITsNodesService; import com.yfd.platform.modules.experimentalData.service.ITsNodesService;
import com.yfd.platform.modules.experimentalData.service.ITsTaskService; import com.yfd.platform.modules.experimentalData.service.ITsTaskService;
import com.yfd.platform.modules.specialDocument.domain.Files;
import com.yfd.platform.modules.specialDocument.domain.Nodes; import com.yfd.platform.modules.specialDocument.domain.Nodes;
import com.yfd.platform.system.domain.LoginUser; import com.yfd.platform.system.domain.LoginUser;
import com.yfd.platform.utils.TableNameContextHolder;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
@ -42,6 +47,14 @@ public class TsNodesController {
@Resource @Resource
private ITsNodesService tsNodesService; private ITsNodesService tsNodesService;
//试验任务节点服务类
@Resource
private ITsFilesService tsFilesService;
//试验任务节点服务类
@Resource
private ITsTaskService tsTaskService;
@Autowired @Autowired
private TaskStatusHolder taskStatusHolder; private TaskStatusHolder taskStatusHolder;
@ -164,7 +177,7 @@ public class TsNodesController {
// 原子性启动新任务 // 原子性启动新任务
if (taskStatusHolder.startTaskIfAbsent(asyncKey)) { if (taskStatusHolder.startTaskIfAbsent(asyncKey)) {
// 直接异步执行并推送结果 // 直接异步执行并推送结果
tsNodesService.testDataScanByIdAsync(id,loginuser); tsNodesService.testDataScanByIdAsync(id, loginuser);
return ResponseResult.success("验数据扫描任务开始处理!"); return ResponseResult.success("验数据扫描任务开始处理!");
} else { } else {
return ResponseResult.success("验数据扫描任务已由其他请求启动!"); return ResponseResult.success("验数据扫描任务已由其他请求启动!");
@ -206,7 +219,6 @@ public class TsNodesController {
} }
/********************************** /**********************************
* 用途说明: 查询可不可以初始化试验任务扫描 * 用途说明: 查询可不可以初始化试验任务扫描
* 参数说明 taskId 试验任务ID * 参数说明 taskId 试验任务ID
@ -216,17 +228,56 @@ public class TsNodesController {
@PostMapping("/selectTsNodesByTskeId") @PostMapping("/selectTsNodesByTskeId")
@ApiOperation("查询可不可以初始化试验任务扫描") @ApiOperation("查询可不可以初始化试验任务扫描")
@PreAuthorize("@el.check('del:tsnodes')") @PreAuthorize("@el.check('del:tsnodes')")
public ResponseResult selectTsNodesByTskeId( String taskId) { public ResponseResult selectTsNodesByTskeId(String taskId) {
if (StrUtil.isBlank(taskId)) { if (StrUtil.isBlank(taskId)) {
return ResponseResult.error("参数为空"); return ResponseResult.error("参数为空");
} }
List<TsNodes> tsNodesList = tsNodesService.list(new QueryWrapper<TsNodes>().eq("task_id", taskId)); List<TsNodes> tsNodesList = tsNodesService.list(new QueryWrapper<TsNodes>().eq("task_id", taskId));
//如果节点不为空 就不能初始化了 //如果节点不为空 就不能初始化了
if (tsNodesList.size()>0) { if (tsNodesList.size() > 0) {
return ResponseResult.success("该项目已经初始化完成,局部更新请选择节点上传文件!"); return ResponseResult.success("该项目已经初始化完成,局部更新请选择节点上传文件!");
} else { } else {
return ResponseResult.success("可以初始化!"); return ResponseResult.success("可以初始化!");
} }
} }
/**********************************
* 用途说明: 查询可不可以初始化专项文档扫描
* 参数说明 projectId 所属项目ID
* 返回值说明: com.yfd.platform.config.ResponseResult
***********************************/
@Log(module = "查询可不可以修改项目", value = "查询可不可以修改项目!")
@PostMapping("/selectTsNodesById")
@ApiOperation("查询可不可以修改项目")
public ResponseResult selectTsNodesById(String taskId) {
try {
if (StrUtil.isBlank(taskId)) {
return ResponseResult.error("参数为空");
}
TsTask tsTask = tsTaskService.getById(taskId);
TableNameContextHolder.setTaskCode(tsTask.getTaskCode());
List<TsNodes> tsNodesList = tsNodesService.list(new QueryWrapper<TsNodes>().eq("task_id", taskId));
// 如果节点不为空 就不能初始化了
if (tsNodesList.size() > 0) {
return ResponseResult.successData(false);
} else {
// 如果节点为空 就判断文件表
List<TsFiles> filesList = tsFilesService.list(new QueryWrapper<TsFiles>().eq("task_id", taskId));
if (filesList.size() > 0) {
return ResponseResult.successData(false);
} else {
return ResponseResult.successData(true);
}
}
} catch (Exception e) {
// 捕获所有异常并记录日志
// log.error("查询可不可以修改项目时发生异常: {}", e.getMessage(), e);
return ResponseResult.error("系统异常,请稍后再试");
}finally {
TableNameContextHolder.clear();
}
}
} }

View File

@ -3,6 +3,8 @@ package com.yfd.platform.modules.experimentalData.controller;
import cn.hutool.core.util.ObjUtil; import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yfd.platform.annotation.Log; import com.yfd.platform.annotation.Log;
@ -10,14 +12,20 @@ import com.yfd.platform.config.ResponseResult;
import com.yfd.platform.modules.experimentalData.domain.TsTask; import com.yfd.platform.modules.experimentalData.domain.TsTask;
import com.yfd.platform.modules.experimentalData.service.ITsTaskService; import com.yfd.platform.modules.experimentalData.service.ITsTaskService;
import com.yfd.platform.modules.specialDocument.domain.Project; import com.yfd.platform.modules.specialDocument.domain.Project;
import com.yfd.platform.utils.StringUtils;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Map;
/** /**
* <p> * <p>
@ -56,9 +64,42 @@ public class TsTaskController {
@GetMapping("/page") @GetMapping("/page")
@ApiOperation("分页查询试验数据管理试验任务管理") @ApiOperation("分页查询试验数据管理试验任务管理")
@PreAuthorize("@el.check('select:tsTask')") @PreAuthorize("@el.check('select:tsTask')")
public ResponseResult getTsTaskPage(String taskName, String startDate, String endDate, String taskPlace, String taskPerson, String taskCode, String taskType, String carrierName, String deviceCode, String testDescribe, String sensorDescribe, Page<TsTask> page) { public ResponseResult getTsTaskPage(String taskName, String startDate, String endDate, String taskPlace, String taskPerson, String taskCode, String taskType, String carrierName, String deviceCode, String testDescribe, String sensorDescribe, Page<TsTask> page, String attributeContentJson) {
// 双重解码处理
if (attributeContentJson != null) {
try {
// 第二次解码%5B [
attributeContentJson = URLDecoder.decode(attributeContentJson, StandardCharsets.UTF_8.name());
} catch (UnsupportedEncodingException e) {
return ResponseResult.error("参数解码错误");
}
}
// 将JSON字符串转换为List<Map<String, String>>
List<Map<String, String>> attributeContent = null;
if (StringUtils.isNotEmpty(attributeContentJson)) {
try {
// 使用 TypeReference 指定精确类型
attributeContent = JSON.parseObject(
attributeContentJson,
new TypeReference<List<Map<String, String>>>() {
}
);
// 遍历并移除空值字段
if (attributeContent != null) {
for (Map<String, String> item : attributeContent) {
// 遍历 Map移除值为空的键值对
item.entrySet().removeIf(entry -> entry.getValue() == null || entry.getValue().isEmpty());
}
}
} catch (Exception e) {
return ResponseResult.error("属性参数格式错误");
}
}
//分页查询 //分页查询
Page<TsTask> sdProjectPage = tsTaskService.getTsTaskPage(taskName, startDate, endDate, taskPlace, taskPerson, taskCode, taskType, carrierName, deviceCode, testDescribe, sensorDescribe, page); Page<TsTask> sdProjectPage = tsTaskService.getTsTaskPage(taskName, startDate, endDate, taskPlace, taskPerson, taskCode, taskType, carrierName, deviceCode, testDescribe, sensorDescribe, page, attributeContent);
return ResponseResult.successData(sdProjectPage); return ResponseResult.successData(sdProjectPage);
} }
@ -73,12 +114,12 @@ public class TsTaskController {
@ApiOperation("新增试验数据管理试验任务管理") @ApiOperation("新增试验数据管理试验任务管理")
@ResponseBody @ResponseBody
@PreAuthorize("@el.check('add:tsTask')") @PreAuthorize("@el.check('add:tsTask')")
public ResponseResult addtsTask(@RequestBody TsTask tsTask) { public ResponseResult addtsTask(@RequestBody TsTask tsTask) throws IOException {
//对象不能为空 //对象不能为空
if (ObjUtil.isEmpty(tsTask)) { if (ObjUtil.isEmpty(tsTask)) {
return ResponseResult.error("参数为空"); return ResponseResult.error("参数为空");
} }
Boolean isOk = tsTaskService.addSdproject(tsTask); Boolean isOk = tsTaskService.addtsTask(tsTask);
if (isOk) { if (isOk) {
return ResponseResult.success(); return ResponseResult.success();
} else { } else {
@ -96,7 +137,7 @@ public class TsTaskController {
@PostMapping("/updatetsTask") @PostMapping("/updatetsTask")
@ApiOperation("修改试验数据管理试验任务管理") @ApiOperation("修改试验数据管理试验任务管理")
@PreAuthorize("@el.check('update:tsTask')") @PreAuthorize("@el.check('update:tsTask')")
public ResponseResult updatetsTask(@RequestBody TsTask tsTask) { public ResponseResult updatetsTask(@RequestBody TsTask tsTask) throws IOException {
//对象不能为空 //对象不能为空
if (ObjUtil.isEmpty(tsTask) && StrUtil.isBlank(tsTask.getId())) { if (ObjUtil.isEmpty(tsTask) && StrUtil.isBlank(tsTask.getId())) {
return ResponseResult.error("参数为空"); return ResponseResult.error("参数为空");

View File

@ -13,5 +13,6 @@ public class MoveCopyFileFolderRequest {
private String rename; private String rename;
private String type; private String type;
private String taskId; private String taskId;
private String nodeId;
} }

View File

@ -4,7 +4,9 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yfd.platform.modules.experimentalData.domain.TsTask; import com.yfd.platform.modules.experimentalData.domain.TsTask;
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService;
import java.io.IOException;
import java.util.List; import java.util.List;
import java.util.Map;
/** /**
* <p> * <p>
@ -34,7 +36,7 @@ public interface ITsTaskService extends IService<TsTask> {
* pageNum 当前页 * pageNum 当前页
* 返回值说明: com.yfd.platform.config.ResponseResult 返回分页查询结果 * 返回值说明: com.yfd.platform.config.ResponseResult 返回分页查询结果
***********************************/ ***********************************/
Page<TsTask> getTsTaskPage(String taskName, String startDate, String endDate, String taskPlace, String taskPerson, String taskCode, String taskType,String carrierName,String deviceCode,String testDescribe,String sensorDescribe, Page<TsTask> page); Page<TsTask> getTsTaskPage(String taskName, String startDate, String endDate, String taskPlace, String taskPerson, String taskCode, String taskType,String carrierName,String deviceCode,String testDescribe,String sensorDescribe, Page<TsTask> page,List<Map<String, String>> attributeContent);
/*********************************** /***********************************
* 用途说明新增试验数据管理-试验任务管理 * 用途说明新增试验数据管理-试验任务管理
@ -42,7 +44,7 @@ public interface ITsTaskService extends IService<TsTask> {
* TsTask 试验任务管理 * TsTask 试验任务管理
* 返回值说明: com.yfd.platform.config.ResponseResult 返回新增成功或者失败 * 返回值说明: com.yfd.platform.config.ResponseResult 返回新增成功或者失败
***********************************/ ***********************************/
Boolean addSdproject(TsTask tsTask); Boolean addtsTask(TsTask tsTask) throws IOException;
/********************************** /**********************************
* 用途说明: 修改试验数据管理-试验任务管理 * 用途说明: 修改试验数据管理-试验任务管理
@ -50,7 +52,7 @@ public interface ITsTaskService extends IService<TsTask> {
* TsTask 试验任务管理 * TsTask 试验任务管理
* 返回值说明: com.yfd.platform.config.ResponseResult 返回修改成功或者失败 * 返回值说明: com.yfd.platform.config.ResponseResult 返回修改成功或者失败
***********************************/ ***********************************/
boolean updatetsTask(TsTask tsTask); boolean updatetsTask(TsTask tsTask) throws IOException;
/********************************** /**********************************
* 用途说明: 批量删除试验数据管理-试验任务管理 * 用途说明: 批量删除试验数据管理-试验任务管理

View File

@ -3333,7 +3333,10 @@ public class TsFilesServiceImpl extends ServiceImpl<TsFilesMapper, TsFiles> impl
StorageSourceConfig storageSourceConfig = getStorageSourceConfig("filePath", "local",tsTask.getLocalStorageId()); StorageSourceConfig storageSourceConfig = getStorageSourceConfig("filePath", "local",tsTask.getLocalStorageId());
StorageSourceConfig storageSourceConfig1 = getStorageSourceConfig("bucketName", "minio",tsTask.getBackupStorageId()); StorageSourceConfig storageSourceConfig1 = getStorageSourceConfig("bucketName", "minio",tsTask.getBackupStorageId());
List<ParameterList> parameterLists = parameter.getParameterLists(); List<ParameterList> parameterLists = parameter.getParameterLists();
// 设置当前时间
LocalDateTime now = LocalDateTime.now();
// 转换为 Timestamp
Timestamp currentTime = Timestamp.valueOf(now);
// 在循环前记录开始时间 // 在循环前记录开始时间
long startTime = System.currentTimeMillis(); long startTime = System.currentTimeMillis();
//循环一条一条上传 //循环一条一条上传
@ -3370,16 +3373,16 @@ public class TsFilesServiceImpl extends ServiceImpl<TsFilesMapper, TsFiles> impl
if (flag) { if (flag) {
LOGGER.info("同步本地到minio,minio文件夹创建成功"); LOGGER.info("同步本地到minio,minio文件夹创建成功");
value = true; value = true;
// currentFile.setUpdateTime(currentTime); currentFile.setUpdateTime(currentTime);
// currentFile.setBackupPath(minioPath); currentFile.setBackupPath(minioPath);
// int valueAdded = tsFilesMapper.updateById(currentFile); int valueAdded = tsFilesMapper.updateById(currentFile);
// if (valueAdded == 1) { if (valueAdded == 1) {
// LOGGER.info("同步本地到minio,minio文件夹创建成功,表结构修改成功。"); LOGGER.info("同步本地到minio,minio文件夹创建成功,表结构修改成功。");
// value = true; value = true;
// } else { } else {
// LOGGER.error("同步本地到minio,minio文件夹创建成功表结构修改失败"); LOGGER.error("同步本地到minio,minio文件夹创建成功表结构修改失败");
// value = false; value = false;
// } }
} else { } else {
LOGGER.error("同步本地到minio,minio文件夹创建失败"); LOGGER.error("同步本地到minio,minio文件夹创建失败");
@ -3421,16 +3424,151 @@ public class TsFilesServiceImpl extends ServiceImpl<TsFilesMapper, TsFiles> impl
LOGGER.info("同步本地到minio,minio文件创建成功"); LOGGER.info("同步本地到minio,minio文件创建成功");
value = true; value = true;
// currentFile.setUpdateTime(currentTime); currentFile.setUpdateTime(currentTime);
// currentFile.setBackupPath(minioPath); currentFile.setBackupPath(minioPath);
// int valueAdded = tsFilesMapper.updateById(currentFile); int valueAdded = tsFilesMapper.updateById(currentFile);
// if (valueAdded == 1) { if (valueAdded == 1) {
// LOGGER.info("同步本地到minio,minio文件创建成功,表结构修改成功。"); LOGGER.info("同步本地到minio,minio文件创建成功,表结构修改成功。");
// value = true; value = true;
// } else { } else {
// LOGGER.error("同步本地到minio,minio文件创建成功表结构修改失败"); LOGGER.error("同步本地到minio,minio文件创建成功表结构修改失败");
// value = false; value = false;
// } }
} else {
LOGGER.error("同步本地到minio,minio文件创建失败");
value = false;
}
}
}
// 计算总耗时
long endTime = System.currentTimeMillis();
long totalTime = endTime - startTime;
LOGGER.info("把本地文件放到minio循环执行耗时: {} 毫秒 (约 {} 秒)", totalTime, totalTime / 1000.0);
return value;
} catch (Exception e) {
LOGGER.error("上传到备份空间时发生异常: {}", e.getMessage(), e);
return false;
} finally {
TableNameContextHolder.clear();
}
}
/**********************************
* 用途说明: 将文件上传到备份空间 其他接口使用
* 参数说明 parameter 数据集合
* 返回值说明: com.yfd.platform.config.ResponseResult 返回成功或者失败
***********************************/
public Boolean uploadToBackupData(Parameter parameter) {
Boolean value = false;
try {
TsTask tsTask = tsTaskMapper.selectById(parameter.getTaskId());
TableNameContextHolder.setTaskCode(tsTask.getTaskCode());
StorageSource storageSourceLocal = getStorageConfig(tsTask.getLocalStorageId());
StorageSource storageSourceMinio = getStorageConfig(tsTask.getBackupStorageId());
StorageSourceConfig storageSourceConfig = getStorageSourceConfig("filePath", "local",tsTask.getLocalStorageId());
StorageSourceConfig storageSourceConfig1 = getStorageSourceConfig("bucketName", "minio",tsTask.getBackupStorageId());
List<ParameterList> parameterLists = parameter.getParameterLists();
// 在循环前记录开始时间
long startTime = System.currentTimeMillis();
//循环一条一条上传
for (ParameterList parameterListData : parameterLists) {
if ("FOLDER".equals(parameterListData.getType())) {
String name = parameterListData.getName();
// 处理路径格式
String path = normalizePath(parameterListData.getPath());
String minioPath = path;//// MinIO上传目标路径
// 使用Java NIO的Path类来构造压缩文件的完整路径存储在localPath目录下
// 查询当前文件记录
TsFiles currentFile = getFileRecord(name, path);
if (currentFile == null) return false;
// 递归创建父文件夹
boolean parentsCreated = createParentFolders(currentFile.getParentId());
if (!parentsCreated) {
LOGGER.error("父文件夹创建失败");
return false;
}
//新增节点的时候 创建文件夹
NewFolderRequest newFolderRequest = new NewFolderRequest();
newFolderRequest.setName(currentFile.getFileName());//新建的文件夹名称,示例值(/a/b/c)
newFolderRequest.setPassword("");//文件夹密码, 如果文件夹需要密码才能访问则支持请求密码,示例值(123456)
newFolderRequest.setPath(minioPath);//请求路径,示例值(/)
newFolderRequest.setStorageKey(storageSourceMinio.getKey());//存储源 key,示例值(local minio)
AbstractBaseFileService<?> fileService = storageSourceContext.getByStorageKey(newFolderRequest.getStorageKey());
boolean flag = fileService.newFolder(newFolderRequest.getPath(), newFolderRequest.getName());
LOGGER.info("同步本地到minio文件夹路径加名称" + newFolderRequest.getPath() + newFolderRequest.getName());
//如果文件夹创建成功
if (flag) {
LOGGER.info("同步本地到minio,minio文件夹创建成功");
value = true;
// currentFile.setUpdateTime(currentTime);
// currentFile.setBackupPath(minioPath);
// int valueAdded = tsFilesMapper.updateById(currentFile);
// if (valueAdded == 1) {
// LOGGER.info("同步本地到minio,minio文件夹创建成功,表结构修改成功。");
// value = true;
// } else {
// LOGGER.error("同步本地到minio,minio文件夹创建成功表结构修改失败");
// value = false;
// }
} else {
LOGGER.error("同步本地到minio,minio文件夹创建失败");
value = false;
}
} else {
String name = parameterListData.getName();
// 处理路径格式
String path = normalizePath(parameterListData.getPath());
String localPath = storageSourceConfig.getValue() + path;//localPath是本地的路径
String minioPath = path;//// MinIO上传目标路径
// 使用Java NIO的Path类来构造压缩文件的完整路径存储在localPath目录下
Path FilePath = Paths.get(localPath, name);
// 4. 上传压缩文件到MinIO
File zipFile = FilePath.toFile(); // 获取本地文件
// 查询当前文件记录
TsFiles currentFile = getFileRecord(name, path);
if (currentFile == null) {
return false;
}
// 递归创建父文件夹
boolean parentsCreated = createParentFolders(currentFile.getParentId());
if (!parentsCreated) {
LOGGER.error("父文件夹创建失败");
return false;
}
//把本地文件上传到minio
AbstractBaseFileService<?> fileService = storageSourceContext.getByStorageKey("minio");
boolean flag1 = fileService.UploadFiles(storageSourceConfig1.getValue(), minioPath + name, zipFile);
LOGGER.info("同步本地到minio文件路径加名称" + storageSourceConfig1.getValue() + minioPath + name);
//如果上传成功 修改 表结构
if (flag1) {
LOGGER.info("同步本地到minio,minio文件创建成功");
value = true;
// currentFile.setUpdateTime(currentTime);
// currentFile.setBackupPath(minioPath);
// int valueAdded = tsFilesMapper.updateById(currentFile);
// if (valueAdded == 1) {
// LOGGER.info("同步本地到minio,minio文件创建成功,表结构修改成功。");
// value = true;
// } else {
// LOGGER.error("同步本地到minio,minio文件创建成功表结构修改失败");
// value = false;
// }
} else { } else {
LOGGER.error("同步本地到minio,minio文件创建失败"); LOGGER.error("同步本地到minio,minio文件创建失败");
value = false; value = false;
@ -3603,7 +3741,7 @@ public class TsFilesServiceImpl extends ServiceImpl<TsFilesMapper, TsFiles> impl
fileParameterlist.add(parameterList); fileParameterlist.add(parameterList);
fileParameter.setParameterLists(fileParameterlist); fileParameter.setParameterLists(fileParameterlist);
fileParameter.setTaskId(taskId); fileParameter.setTaskId(taskId);
Boolean value = uploadToBackup(fileParameter); Boolean value = uploadToBackupData(fileParameter);
if (value) { if (value) {
BackupsFileCount++; BackupsFileCount++;
} }
@ -3616,7 +3754,7 @@ public class TsFilesServiceImpl extends ServiceImpl<TsFilesMapper, TsFiles> impl
FolderParameterlist.add(parameterList); FolderParameterlist.add(parameterList);
FolderParameter.setParameterLists(FolderParameterlist); FolderParameter.setParameterLists(FolderParameterlist);
FolderParameter.setTaskId(taskId); FolderParameter.setTaskId(taskId);
Boolean value = uploadToBackup(FolderParameter); Boolean value = uploadToBackupData(FolderParameter);
if (value) { if (value) {
BackupsFolderCount++; BackupsFolderCount++;
} }
@ -3711,7 +3849,7 @@ public class TsFilesServiceImpl extends ServiceImpl<TsFilesMapper, TsFiles> impl
fileParameterlist.add(parameterList); fileParameterlist.add(parameterList);
fileParameter.setParameterLists(fileParameterlist); fileParameter.setParameterLists(fileParameterlist);
fileParameter.setTaskId(taskId); fileParameter.setTaskId(taskId);
Boolean value = uploadToBackup(fileParameter); Boolean value = uploadToBackupData(fileParameter);
if (value) { if (value) {
BackupsFileCount++; BackupsFileCount++;
} }
@ -3724,7 +3862,7 @@ public class TsFilesServiceImpl extends ServiceImpl<TsFilesMapper, TsFiles> impl
FolderParameterlist.add(parameterList); FolderParameterlist.add(parameterList);
FolderParameter.setParameterLists(FolderParameterlist); FolderParameter.setParameterLists(FolderParameterlist);
FolderParameter.setTaskId(taskId); FolderParameter.setTaskId(taskId);
Boolean value = uploadToBackup(FolderParameter); Boolean value = uploadToBackupData(FolderParameter);
if (value) { if (value) {
BackupsFolderCount++; BackupsFolderCount++;
} }
@ -4005,6 +4143,7 @@ public class TsFilesServiceImpl extends ServiceImpl<TsFilesMapper, TsFiles> impl
* 参数说明 newFileName * 参数说明 newFileName
* 参数说明 Rename 重命名的文件名称 * 参数说明 Rename 重命名的文件名称
* 参数说明 type 覆盖还是重命名 0 1 * 参数说明 type 覆盖还是重命名 0 1
* 参数说明 nodeId 跨节点移动以后的节点ID
*/ */
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
@ -4022,6 +4161,7 @@ public class TsFilesServiceImpl extends ServiceImpl<TsFilesMapper, TsFiles> impl
String parentId = reques.getParentId(); String parentId = reques.getParentId();
String rename = reques.getRename(); String rename = reques.getRename();
String type = reques.getType(); String type = reques.getType();
String nodeId = reques.getNodeId();
String[] newFileNames = reques.getNewFileName().split(","); String[] newFileNames = reques.getNewFileName().split(",");
// 数组转集合 // 数组转集合
List<String> newFileNameList = Arrays.asList(newFileNames); List<String> newFileNameList = Arrays.asList(newFileNames);
@ -4063,7 +4203,7 @@ public class TsFilesServiceImpl extends ServiceImpl<TsFilesMapper, TsFiles> impl
moveFile(sourcePath, targetPath, type); moveFile(sourcePath, targetPath, type);
// 更新数据库记录 // 更新数据库记录
updateDatabase(parentId, oldpaths, fileName, newPath, targetFileName, type); updateDatabase(parentId, oldpaths, fileName, newPath, targetFileName, type,nodeId);
} }
return "移动成功"; return "移动成功";
} catch (NoSuchFileException e) { } catch (NoSuchFileException e) {
@ -4159,7 +4299,7 @@ public class TsFilesServiceImpl extends ServiceImpl<TsFilesMapper, TsFiles> impl
* 更新数据库中的父ID和路径 * 更新数据库中的父ID和路径
*/ */
private void updateDatabase(String parentId, String oldpaths, String fileName, private void updateDatabase(String parentId, String oldpaths, String fileName,
String newPath, String targetFileName, String type) { String newPath, String targetFileName, String type,String nodeId) {
TsFiles tsFilesData = tsFilesMapper.selectById(parentId); TsFiles tsFilesData = tsFilesMapper.selectById(parentId);
LOGGER.info("移动的时候删除Redis"); LOGGER.info("移动的时候删除Redis");
@ -4194,6 +4334,7 @@ public class TsFilesServiceImpl extends ServiceImpl<TsFilesMapper, TsFiles> impl
if (newfileRecord != null) { if (newfileRecord != null) {
// 更新目标记录 // 更新目标记录
newfileRecord.setParentId(parentId); newfileRecord.setParentId(parentId);
newfileRecord.setNodeId(nodeId);
newfileRecord.setWorkPath(newWorkPath); newfileRecord.setWorkPath(newWorkPath);
newfileRecord.setFileName(targetFileName); newfileRecord.setFileName(targetFileName);
newfileRecord.setUpdateTime(new Timestamp(System.currentTimeMillis())); // 更新时间 newfileRecord.setUpdateTime(new Timestamp(System.currentTimeMillis())); // 更新时间
@ -4203,7 +4344,7 @@ public class TsFilesServiceImpl extends ServiceImpl<TsFilesMapper, TsFiles> impl
} else { } else {
// 插入新记录 // 插入新记录
TsFiles newRecord = new TsFiles(); TsFiles newRecord = new TsFiles();
newRecord.setNodeId(fileRecord.getNodeId()); newRecord.setNodeId(nodeId);
newRecord.setTaskId(fileRecord.getTaskId()); newRecord.setTaskId(fileRecord.getTaskId());
newRecord.setIsFile(fileRecord.getIsFile()); newRecord.setIsFile(fileRecord.getIsFile());
newRecord.setParentId(parentId); newRecord.setParentId(parentId);
@ -4219,7 +4360,7 @@ public class TsFilesServiceImpl extends ServiceImpl<TsFilesMapper, TsFiles> impl
// 如果是文件夹递归删除子项 // 如果是文件夹递归删除子项
if ("FOLDER".equals(fileRecord.getIsFile())) { if ("FOLDER".equals(fileRecord.getIsFile())) {
// 先移动子项再删除原记录 // 先移动子项再删除原记录
moveChildrenRecords(oldWorkPath, newWorkPath + targetFileName + "/", newRecord.getId(), type, fileRecord.getId()); moveChildrenRecords(oldWorkPath, newWorkPath + targetFileName + "/", newRecord.getId(), type, fileRecord.getId(),nodeId);
} }
// 删除原记录 // 删除原记录
tsFilesMapper.deleteById(fileRecord.getId()); tsFilesMapper.deleteById(fileRecord.getId());
@ -4229,7 +4370,7 @@ public class TsFilesServiceImpl extends ServiceImpl<TsFilesMapper, TsFiles> impl
} else { } else {
// 重命名模式插入新记录 // 重命名模式插入新记录
TsFiles newRecord = new TsFiles(); TsFiles newRecord = new TsFiles();
newRecord.setNodeId(fileRecord.getNodeId()); newRecord.setNodeId(nodeId);
newRecord.setTaskId(fileRecord.getTaskId()); newRecord.setTaskId(fileRecord.getTaskId());
newRecord.setIsFile(fileRecord.getIsFile()); newRecord.setIsFile(fileRecord.getIsFile());
newRecord.setParentId(parentId); newRecord.setParentId(parentId);
@ -4250,7 +4391,7 @@ public class TsFilesServiceImpl extends ServiceImpl<TsFilesMapper, TsFiles> impl
/** /**
* 递归移动子项记录覆盖模式下先移动后删除 * 递归移动子项记录覆盖模式下先移动后删除
*/ */
private void moveChildrenRecords(String oldPrefix, String newPrefix, String parentId, String type, String oldparentId) { private void moveChildrenRecords(String oldPrefix, String newPrefix, String parentId, String type, String oldparentId,String nodeId) {
//查询原来的 //查询原来的
List<TsFiles> children = tsFilesMapper.selectList( List<TsFiles> children = tsFilesMapper.selectList(
new QueryWrapper<TsFiles>().eq("parent_id", oldparentId)); new QueryWrapper<TsFiles>().eq("parent_id", oldparentId));
@ -4268,12 +4409,13 @@ public class TsFilesServiceImpl extends ServiceImpl<TsFilesMapper, TsFiles> impl
if (existingChild != null) { if (existingChild != null) {
existingChild.setParentId(parentId); existingChild.setParentId(parentId);
existingChild.setNodeId(nodeId);
existingChild.setWorkPath(childNewPath); existingChild.setWorkPath(childNewPath);
existingChild.setUpdateTime(new Timestamp(System.currentTimeMillis())); existingChild.setUpdateTime(new Timestamp(System.currentTimeMillis()));
tsFilesMapper.updateById(existingChild); tsFilesMapper.updateById(existingChild);
} else { } else {
TsFiles newChild = new TsFiles(); TsFiles newChild = new TsFiles();
newChild.setNodeId(child.getNodeId()); newChild.setNodeId(nodeId);
newChild.setTaskId(child.getTaskId()); newChild.setTaskId(child.getTaskId());
newChild.setIsFile(child.getIsFile()); newChild.setIsFile(child.getIsFile());
newChild.setParentId(parentId); newChild.setParentId(parentId);
@ -4288,9 +4430,12 @@ public class TsFilesServiceImpl extends ServiceImpl<TsFilesMapper, TsFiles> impl
tsFilesMapper.insert(newChild); tsFilesMapper.insert(newChild);
// 递归处理子文件夹 // 递归处理子文件夹
if ("FOLDER".equals(child.getIsFile())) { if ("FOLDER".equals(child.getIsFile())) {
moveChildrenRecords(oldPrefix, newPrefix + newChild.getFileName() + "/", newChild.getId(), type, child.getId()); moveChildrenRecords(oldPrefix, newPrefix + newChild.getFileName() + "/", newChild.getId(), type, child.getId(),nodeId);
} }
// 删除原记录
tsFilesMapper.deleteById(child.getId());
} }
} }
} }
} }
@ -4331,6 +4476,7 @@ public class TsFilesServiceImpl extends ServiceImpl<TsFilesMapper, TsFiles> impl
String parentId = reques.getParentId(); String parentId = reques.getParentId();
String rename = reques.getRename(); String rename = reques.getRename();
String type = reques.getType(); String type = reques.getType();
String nodeId = reques.getNodeId();
String[] newFileNames = reques.getNewFileName().split(","); String[] newFileNames = reques.getNewFileName().split(",");
// 数组转集合 // 数组转集合
List<String> newFileNameList = Arrays.asList(newFileNames); List<String> newFileNameList = Arrays.asList(newFileNames);
@ -4369,7 +4515,7 @@ public class TsFilesServiceImpl extends ServiceImpl<TsFilesMapper, TsFiles> impl
copyPhysicalFile(sourcePath, targetPath, type); copyPhysicalFile(sourcePath, targetPath, type);
// 5. 插入新记录到数据库 // 5. 插入新记录到数据库
insertDatabaseRecord(parentId, oldpaths, fileName, newPath, targetFileName, type); insertDatabaseRecord(parentId, oldpaths, fileName, newPath, targetFileName, type,nodeId);
} }
return "复制成功"; return "复制成功";
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
@ -4417,7 +4563,7 @@ public class TsFilesServiceImpl extends ServiceImpl<TsFilesMapper, TsFiles> impl
* 插入数据库记录主记录 * 插入数据库记录主记录
*/ */
private void insertDatabaseRecord(String parentId, String oldpaths, String fileName, private void insertDatabaseRecord(String parentId, String oldpaths, String fileName,
String newPath, String targetFileName, String type) { String newPath, String targetFileName, String type,String nodeId) {
TsFiles tsFilesData = tsFilesMapper.selectById(parentId); TsFiles tsFilesData = tsFilesMapper.selectById(parentId);
LOGGER.info("复制的时候删除Redis"); LOGGER.info("复制的时候删除Redis");
@ -4460,14 +4606,15 @@ public class TsFilesServiceImpl extends ServiceImpl<TsFilesMapper, TsFiles> impl
formatDbPath(newPath), formatDbPath(newPath),
original.getId(), original.getId(),
neworiginal.getId(), neworiginal.getId(),
type type,
nodeId
); );
} }
} else { } else {
// 创建新记录 // 创建新记录
TsFiles newRecord = new TsFiles(); TsFiles newRecord = new TsFiles();
newRecord.setNodeId(original.getNodeId()); newRecord.setNodeId(nodeId);
newRecord.setTaskId(original.getTaskId()); newRecord.setTaskId(original.getTaskId());
newRecord.setIsFile(original.getIsFile()); newRecord.setIsFile(original.getIsFile());
newRecord.setParentId(parentId); newRecord.setParentId(parentId);
@ -4487,7 +4634,8 @@ public class TsFilesServiceImpl extends ServiceImpl<TsFilesMapper, TsFiles> impl
formatDbPath(newPath + newRecord.getFileName() + "/"), formatDbPath(newPath + newRecord.getFileName() + "/"),
original.getId(), original.getId(),
newRecord.getId(), newRecord.getId(),
type type,
nodeId
); );
} }
} }
@ -4499,7 +4647,7 @@ public class TsFilesServiceImpl extends ServiceImpl<TsFilesMapper, TsFiles> impl
* 递归复制子项数据库记录关键优化点 * 递归复制子项数据库记录关键优化点
*/ */
private void copyChildrenRecords(String oldPrefix, String newPrefix, private void copyChildrenRecords(String oldPrefix, String newPrefix,
String originalParentId, String newParentId, String type) { String originalParentId, String newParentId, String type,String nodeId) {
List<TsFiles> children = tsFilesMapper.selectList( List<TsFiles> children = tsFilesMapper.selectList(
new QueryWrapper<TsFiles>().eq("parent_id", originalParentId) new QueryWrapper<TsFiles>().eq("parent_id", originalParentId)
); );
@ -4512,7 +4660,7 @@ public class TsFilesServiceImpl extends ServiceImpl<TsFilesMapper, TsFiles> impl
for (TsFiles child : children) { for (TsFiles child : children) {
// 处理当前子项 // 处理当前子项
TsFiles processedChild = processChildRecord( TsFiles processedChild = processChildRecord(
child, newParentId, newPrefix, oldPrefix, type, loginuser, currentTime child, newParentId, newPrefix, oldPrefix, type, loginuser, currentTime, nodeId
); );
// 递归处理子文件夹 // 递归处理子文件夹
@ -4522,7 +4670,8 @@ public class TsFilesServiceImpl extends ServiceImpl<TsFilesMapper, TsFiles> impl
newPrefix, newPrefix,
child.getId(), child.getId(),
processedChild.getId(), // 使用新记录的ID作为父ID processedChild.getId(), // 使用新记录的ID作为父ID
type type,
nodeId
); );
} }
} }
@ -4532,7 +4681,7 @@ public class TsFilesServiceImpl extends ServiceImpl<TsFilesMapper, TsFiles> impl
* 处理单个子项记录 * 处理单个子项记录
*/ */
private TsFiles processChildRecord(TsFiles child, String newParentId, String newPrefix, private TsFiles processChildRecord(TsFiles child, String newParentId, String newPrefix,
String oldPrefix, String type, LoginUser user, Timestamp now) { String oldPrefix, String type, LoginUser user, Timestamp now,String nodeId) {
if ("0".equals(type)) { // 覆盖模式 if ("0".equals(type)) { // 覆盖模式
TsFiles existing = tsFilesMapper.selectOne( TsFiles existing = tsFilesMapper.selectOne(
new QueryWrapper<TsFiles>() new QueryWrapper<TsFiles>()
@ -4540,23 +4689,24 @@ public class TsFilesServiceImpl extends ServiceImpl<TsFilesMapper, TsFiles> impl
.eq("file_name", child.getFileName()) .eq("file_name", child.getFileName())
); );
if (existing != null) { if (existing != null) {
updateExisting(existing, child, now, user); updateExisting(existing, child, now, user,nodeId);
return existing; return existing;
} else { } else {
return insertNewChild(child, newParentId, buildNewWorkPath(child, oldPrefix, newPrefix), return insertNewChild(child, newParentId, newPrefix,
user, now, null); user, now, null, nodeId);
} }
} else { // 重命名模式 } else { // 重命名模式
return insertNewChild(child, newParentId, newPrefix, return insertNewChild(child, newParentId, newPrefix,
user, now, child.getFileName()); user, now, child.getFileName(), nodeId);
} }
} }
/** /**
* 更新现有记录覆盖模式 * 更新现有记录覆盖模式
*/ */
private void updateExisting(TsFiles existing, TsFiles source, Timestamp time, LoginUser user) { private void updateExisting(TsFiles existing, TsFiles source, Timestamp time, LoginUser user,String nodeId) {
existing.setFileSize(source.getFileSize()); existing.setFileSize(source.getFileSize());
existing.setNodeId(nodeId);
existing.setDescription(source.getDescription()); existing.setDescription(source.getDescription());
existing.setUpdateTime(time); existing.setUpdateTime(time);
existing.setUploader(user.getUsername()); existing.setUploader(user.getUsername());
@ -4567,9 +4717,9 @@ public class TsFilesServiceImpl extends ServiceImpl<TsFilesMapper, TsFiles> impl
* 插入新子项记录 * 插入新子项记录
*/ */
private TsFiles insertNewChild(TsFiles source, String parentId, String newWorkPath, private TsFiles insertNewChild(TsFiles source, String parentId, String newWorkPath,
LoginUser user, Timestamp time, String customName) { LoginUser user, Timestamp time, String customName,String nodeId) {
TsFiles newChild = new TsFiles(); TsFiles newChild = new TsFiles();
newChild.setNodeId(source.getNodeId()); newChild.setNodeId(nodeId);
newChild.setTaskId(source.getTaskId()); newChild.setTaskId(source.getTaskId());
newChild.setIsFile(source.getIsFile()); newChild.setIsFile(source.getIsFile());
newChild.setParentId(parentId); newChild.setParentId(parentId);

View File

@ -117,32 +117,39 @@ public class TsNodesServiceImpl extends ServiceImpl<TsNodesMapper, TsNodes> impl
// 查找所有根节点parentId为"00"的节点 // 查找所有根节点parentId为"00"的节点
List<Map<String, Object>> rootNodes = findRootNodes(allNodes, taskId); List<Map<String, Object>> rootNodes = findRootNodes(allNodes, taskId);
// 如果未找到根节点返回空列表
if (rootNodes.isEmpty()) {
return new ArrayList<>();
}
// 根节点的基本路径/项目名称/ // 根节点的基本路径/项目名称/
String basePath = "/" + tsTask.getTaskName() + "/"; String basePath = "/" + tsTask.getTaskName() + "/";
// 存储最终结果 // 存储最终结果
List<Map<String, Object>> result = new ArrayList<>(); List<Map<String, Object>> result = new ArrayList<>();
Map<String, Object> rootNodeData = new HashMap<>();
rootNodeData.put("nodeName", "根节点");
rootNodeData.put("path", "/"+tsTask.getTaskName()+"/");
rootNodeData.put("nodeId", tsTask.getId());
rootNodeData.put("nodeOrder", "0");
rootNodeData.put("taskId", tsTask.getId());
rootNodeData.put("parentId", "00");
result.add(rootNodeData);
// 如果 nodeName 为空返回所有根节点的完整树形结构 // 如果 nodeName 为空返回所有根节点的完整树形结构
if (StringUtils.isEmpty(nodeName)) { if (StringUtils.isEmpty(nodeName)) {
if (!rootNodes.isEmpty()) {
for (Map<String, Object> rootNode : rootNodes) { for (Map<String, Object> rootNode : rootNodes) {
rootNode.put("path", basePath); rootNode.put("path", basePath);
result.addAll(buildFullTree(rootNode, allNodes)); result.addAll(buildFullTree(rootNode, allNodes));
} }
}
return result; return result;
} }
// 否则返回从根节点到目标节点的树形结构 // 否则返回从根节点到目标节点的树形结构
for (Map<String, Object> rootNode : rootNodes) { if (!rootNodes.isEmpty()) {
rootNode.put("path", basePath); for (Map<String, Object> rootNode : rootNodes) {
List<Map<String, Object>> tree = buildTreeToTargetNode(rootNode, allNodes, nodeName); rootNode.put("path", basePath);
if (!tree.isEmpty()) { List<Map<String, Object>> tree = buildTreeToTargetNode(rootNode, allNodes, nodeName);
result.addAll(tree); if (!tree.isEmpty()) {
result.addAll(tree);
}
} }
} }
@ -174,7 +181,7 @@ public class TsNodesServiceImpl extends ServiceImpl<TsNodesMapper, TsNodes> impl
queryWrapper.eq("task_id", taskId); queryWrapper.eq("task_id", taskId);
} }
// 按节点顺序升序排序 // 按节点顺序升序排序
queryWrapper.orderByAsc("node_order"); queryWrapper.orderByAsc("node_name");
// 查询所有符合条件的节点 // 查询所有符合条件的节点
return tsNodesMapper.selectMaps(queryWrapper); return tsNodesMapper.selectMaps(queryWrapper);
@ -853,23 +860,21 @@ public class TsNodesServiceImpl extends ServiceImpl<TsNodesMapper, TsNodes> impl
} else { } else {
//todo 如果是文件 首先判断表中有没有 如果没有 就新增 到节点名称为根节点的 节点下面 //todo 如果是文件 首先判断表中有没有 如果没有 就新增 到节点名称为根节点的 节点下面
//查询节点表中 有没有根节点的节点 如果有就直接使用 如果没有就新增 //先通过名称 + 节点 + 任务 + 路径 查询 如果有就跳过 没有就继续新增
LambdaQueryWrapper<TsNodes> queryWrapper = new LambdaQueryWrapper<>(); LambdaQueryWrapper<TsFiles> queryWrapperFiles = new LambdaQueryWrapper<>();
queryWrapper.eq(TsNodes::getTaskId, taskId); queryWrapperFiles.eq(TsFiles::getNodeId, taskId);
queryWrapper.eq(TsNodes::getParentId, TOP_LEVEL_PARENT_NODE); queryWrapperFiles.eq(TsFiles::getTaskId, taskId);
queryWrapper.eq(TsNodes::getNodeName, "根节点"); queryWrapperFiles.eq(TsFiles::getWorkPath, item.getPath());
TsNodes nodeData = tsNodesMapper.selectOne(queryWrapper); queryWrapperFiles.eq(TsFiles::getFileName, item.getName());
if (nodeData == null) { TsFiles tsFiles = tsFilesMapper.selectOne(queryWrapperFiles);
//新增一个根节点 if (tsFiles == null) {
TsNodes node = savetsNodes(taskId, TOP_LEVEL_PARENT_NODE, "根节点");
String finalPath = item.getPath().replace(item.getName(), ""); String finalPath = item.getPath().replace(item.getName(), "");
//保存文件信息 //保存文件信息
TsFiles tsFiles1 = new TsFiles(); TsFiles tsFiles1 = new TsFiles();
//任务 //任务
tsFiles1.setTaskId(taskId); tsFiles1.setTaskId(taskId);
//节点 //节点
tsFiles1.setNodeId(node.getNodeId()); tsFiles1.setNodeId(taskId);
//文件 文件夹 区分 //文件 文件夹 区分
tsFiles1.setIsFile("FILE"); tsFiles1.setIsFile("FILE");
//上级ID //上级ID
@ -886,43 +891,81 @@ public class TsNodesServiceImpl extends ServiceImpl<TsNodesMapper, TsNodes> impl
String fileSizeFormatted = String.format("%.2f", fileSizeInKB); // 保留两位小数 String fileSizeFormatted = String.format("%.2f", fileSizeInKB); // 保留两位小数
tsFiles1.setFileSize(fileSizeFormatted); tsFiles1.setFileSize(fileSizeFormatted);
tsFilesMapper.insert(tsFiles1); tsFilesMapper.insert(tsFiles1);
} else { }else {
//先通过名称 + 节点 + 任务 + 路径 查询 如果有就跳过 没有就继续新增 continue;
LambdaQueryWrapper<TsFiles> queryWrapperFiles = new LambdaQueryWrapper<>();
queryWrapperFiles.eq(TsFiles::getNodeId, nodeData.getNodeId());
queryWrapperFiles.eq(TsFiles::getTaskId, taskId);
queryWrapperFiles.eq(TsFiles::getWorkPath, item.getPath());
queryWrapperFiles.eq(TsFiles::getFileName, item.getName());
TsFiles tsFiles = tsFilesMapper.selectOne(queryWrapperFiles);
if (tsFiles == null) {
String finalPath = item.getPath().replace(item.getName(), "");
//保存文件信息
TsFiles tsFiles1 = new TsFiles();
//任务
tsFiles1.setTaskId(taskId);
//节点
tsFiles1.setNodeId(nodeData.getNodeId());
//文件 文件夹 区分
tsFiles1.setIsFile("FILE");
//上级ID
tsFiles1.setParentId("00");
//文件名称
tsFiles1.setFileName(item.getName());
//工作空间路径
tsFiles1.setWorkPath(ensurePathFormat(finalPath));
tsFiles1.setUploadTime(currentTime);
tsFiles1.setUploader(loginuser.getUsername());
long bytes = item.getSize();
// 转换为 KB 并保留两位小数
double fileSizeInKB = bytes / (1024.0);
String fileSizeFormatted = String.format("%.2f", fileSizeInKB); // 保留两位小数
tsFiles1.setFileSize(fileSizeFormatted);
tsFilesMapper.insert(tsFiles1);
} else {
continue;
}
} }
// //查询节点表中 有没有根节点的节点 如果有就直接使用 如果没有就新增
// LambdaQueryWrapper<TsNodes> queryWrapper = new LambdaQueryWrapper<>();
// queryWrapper.eq(TsNodes::getTaskId, taskId);
// queryWrapper.eq(TsNodes::getParentId, TOP_LEVEL_PARENT_NODE);
// queryWrapper.eq(TsNodes::getNodeName, "根节点");
// TsNodes nodeData = tsNodesMapper.selectOne(queryWrapper);
// if (nodeData == null) {
// //新增一个根节点
// TsNodes node = savetsNodes(taskId, TOP_LEVEL_PARENT_NODE, "根节点");
//
// String finalPath = item.getPath().replace(item.getName(), "");
// //保存文件信息
// TsFiles tsFiles1 = new TsFiles();
// //任务
// tsFiles1.setTaskId(taskId);
// //节点
// tsFiles1.setNodeId(node.getNodeId());
// //文件 文件夹 区分
// tsFiles1.setIsFile("FILE");
// //上级ID
// tsFiles1.setParentId("00");
// //文件名称
// tsFiles1.setFileName(item.getName());
// //工作空间路径
// tsFiles1.setWorkPath(ensurePathFormat(finalPath));
// tsFiles1.setUploadTime(currentTime);
// tsFiles1.setUploader(loginuser.getUsername());
// long bytes = item.getSize();
// // 转换为 KB 并保留两位小数
// double fileSizeInKB = bytes / (1024.0);
// String fileSizeFormatted = String.format("%.2f", fileSizeInKB); // 保留两位小数
// tsFiles1.setFileSize(fileSizeFormatted);
// tsFilesMapper.insert(tsFiles1);
// } else {
// //先通过名称 + 节点 + 任务 + 路径 查询 如果有就跳过 没有就继续新增
// LambdaQueryWrapper<TsFiles> queryWrapperFiles = new LambdaQueryWrapper<>();
// queryWrapperFiles.eq(TsFiles::getNodeId, nodeData.getNodeId());
// queryWrapperFiles.eq(TsFiles::getTaskId, taskId);
// queryWrapperFiles.eq(TsFiles::getWorkPath, item.getPath());
// queryWrapperFiles.eq(TsFiles::getFileName, item.getName());
// TsFiles tsFiles = tsFilesMapper.selectOne(queryWrapperFiles);
// if (tsFiles == null) {
// String finalPath = item.getPath().replace(item.getName(), "");
// //保存文件信息
// TsFiles tsFiles1 = new TsFiles();
// //任务
// tsFiles1.setTaskId(taskId);
// //节点
// tsFiles1.setNodeId(nodeData.getNodeId());
// //文件 文件夹 区分
// tsFiles1.setIsFile("FILE");
// //上级ID
// tsFiles1.setParentId("00");
// //文件名称
// tsFiles1.setFileName(item.getName());
// //工作空间路径
// tsFiles1.setWorkPath(ensurePathFormat(finalPath));
// tsFiles1.setUploadTime(currentTime);
// tsFiles1.setUploader(loginuser.getUsername());
// long bytes = item.getSize();
// // 转换为 KB 并保留两位小数
// double fileSizeInKB = bytes / (1024.0);
// String fileSizeFormatted = String.format("%.2f", fileSizeInKB); // 保留两位小数
// tsFiles1.setFileSize(fileSizeFormatted);
// tsFilesMapper.insert(tsFiles1);
// } else {
// continue;
// }
//
// }
} }
} }
} }

View File

@ -7,6 +7,8 @@ import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.yfd.platform.config.ResponseResult; import com.yfd.platform.config.ResponseResult;
import com.yfd.platform.modules.experimentalData.domain.TsFiles; import com.yfd.platform.modules.experimentalData.domain.TsFiles;
import com.yfd.platform.modules.experimentalData.domain.TsNodes; import com.yfd.platform.modules.experimentalData.domain.TsNodes;
@ -18,6 +20,7 @@ import com.yfd.platform.modules.experimentalData.service.ITsFilesService;
import com.yfd.platform.modules.experimentalData.service.ITsNodesService; import com.yfd.platform.modules.experimentalData.service.ITsNodesService;
import com.yfd.platform.modules.experimentalData.service.ITsTaskService; import com.yfd.platform.modules.experimentalData.service.ITsTaskService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yfd.platform.modules.specialDocument.domain.Project;
import com.yfd.platform.modules.storage.context.StorageSourceContext; import com.yfd.platform.modules.storage.context.StorageSourceContext;
import com.yfd.platform.modules.storage.mapper.StorageSourceMapper; import com.yfd.platform.modules.storage.mapper.StorageSourceMapper;
import com.yfd.platform.modules.storage.model.entity.StorageSource; import com.yfd.platform.modules.storage.model.entity.StorageSource;
@ -35,16 +38,16 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import java.io.IOException;
import java.sql.*; import java.sql.*;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import java.util.ArrayList; import java.util.*;
import java.util.Collections;
import java.util.List;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.sql.DataSource; import javax.sql.DataSource;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.stream.Collectors;
/** /**
* <p> * <p>
@ -107,7 +110,7 @@ public class TsTaskServiceImpl extends ServiceImpl<TsTaskMapper, TsTask> impleme
* 返回值说明: com.yfd.platform.config.ResponseResult 返回分页查询结果 * 返回值说明: com.yfd.platform.config.ResponseResult 返回分页查询结果
***********************************/ ***********************************/
@Override @Override
public Page<TsTask> getTsTaskPage(String taskName, String startDate, String endDate, String taskPlace, String taskPerson, String taskCode, String taskType, String carrierName, String deviceCode, String testDescribe, String sensorDescribe, Page<TsTask> page) { public Page<TsTask> getTsTaskPage(String taskName, String startDate, String endDate, String taskPlace, String taskPerson, String taskCode, String taskType, String carrierName, String deviceCode, String testDescribe, String sensorDescribe, Page<TsTask> page,List<Map<String, String>> attributeContent) {
LambdaQueryWrapper<TsTask> queryWrapper = new LambdaQueryWrapper<>(); LambdaQueryWrapper<TsTask> queryWrapper = new LambdaQueryWrapper<>();
//如果任务名称 taskName 不为空 //如果任务名称 taskName 不为空
@ -161,6 +164,48 @@ public class TsTaskServiceImpl extends ServiceImpl<TsTaskMapper, TsTask> impleme
queryWrapper.ge(TsTask::getTaskStartdate, parseStartDate).lt(TsTask::getTaskEnddate, parseEndDate); queryWrapper.ge(TsTask::getTaskStartdate, parseStartDate).lt(TsTask::getTaskEnddate, parseEndDate);
} }
queryWrapper.orderByDesc(TsTask::getTaskStartdate); queryWrapper.orderByDesc(TsTask::getTaskStartdate);
// 处理属性过滤条件 - MySQL 5.7+ 兼容版本
if (attributeContent != null && !attributeContent.isEmpty()) {
for (Map<String, String> attr : attributeContent) {
for (Map.Entry<String, String> entry : attr.entrySet()) {
String code = entry.getKey();
String value = entry.getValue();
if (StringUtils.isEmpty(value)) {
// 检查属性存在
queryWrapper.apply(
"EXISTS (SELECT 1 FROM JSON_TABLE(task_props, '$[*]' " +
"COLUMNS (code VARCHAR(50) PATH '$.code') AS jt " +
"WHERE jt.code = {0})",
code
);
} else {
// 转义特殊字符
String safeValue = value.replace("'", "''")
.replace("%", "\\%")
.replace("_", "\\_");
// 使用 JSON_EXTRACT 实现兼容查询
queryWrapper.apply(
"EXISTS (SELECT 1 FROM (" +
" SELECT " +
" JSON_UNQUOTE(JSON_EXTRACT(t.obj, '$.code')) AS code, " +
" JSON_UNQUOTE(JSON_EXTRACT(t.obj, '$.data')) AS data " +
" FROM (" +
" SELECT JSON_EXTRACT(task_props, CONCAT('$[', idx.idx, ']')) AS obj " +
" FROM (SELECT 0 AS idx UNION SELECT 1 UNION SELECT 2 UNION SELECT 3) idx" +
" WHERE idx.idx < JSON_LENGTH(task_props)" +
" ) t" +
") jt " +
"WHERE jt.code = {0} AND jt.data LIKE CONCAT('%', {1}, '%'))",
code, value
);
}
}
}
}
//分页查询 //分页查询
Page<TsTask> tsTaskPage = tsTaskMapper.selectPage(page, queryWrapper); Page<TsTask> tsTaskPage = tsTaskMapper.selectPage(page, queryWrapper);
return tsTaskPage; return tsTaskPage;
@ -173,12 +218,25 @@ public class TsTaskServiceImpl extends ServiceImpl<TsTaskMapper, TsTask> impleme
* 返回值说明: com.yfd.platform.config.ResponseResult 返回新增成功或者失败 * 返回值说明: com.yfd.platform.config.ResponseResult 返回新增成功或者失败
***********************************/ ***********************************/
@Override @Override
public Boolean addSdproject(TsTask tsTask) { public Boolean addtsTask(TsTask tsTask) throws IOException {
//todo 新增实验任务的时候创建一个本地的文件夹 //todo 新增实验任务的时候创建一个本地的文件夹
//生成任务编号 //生成任务编号
String taskCode = generateNextTsTaskCode(); String taskCode = generateNextTsTaskCode();
tsTask.setTaskCode(taskCode); tsTask.setTaskCode(taskCode);
//处理属性
String frontEndJson = tsTask.getTaskProps();
List<TsTask> tsTasksList = tsTaskMapper.selectList(new LambdaQueryWrapper<>());
if (tsTasksList.size() > 0) {
for (TsTask tsTaskData : tsTasksList) {
String dbJson = tsTaskData.getTaskProps();
String syncData = syncData(frontEndJson, dbJson);
tsTaskData.setTaskProps(syncData);
tsTaskMapper.updateById(tsTaskData);
}
}
//生成任务名称 任务开始时间_结束时间_地点_载机名称_设备代号_编号 //生成任务名称 任务开始时间_结束时间_地点_载机名称_设备代号_编号
String taskName = buildTaskName(tsTask); String taskName = buildTaskName(tsTask);
tsTask.setTaskName(taskName); tsTask.setTaskName(taskName);
@ -222,6 +280,67 @@ public class TsTaskServiceImpl extends ServiceImpl<TsTaskMapper, TsTask> impleme
} }
} }
public static String syncData(String frontEndJson, String dbJson) throws IOException {
// 1. 如果 frontEndJson 为空则返回一个空的 dbJson
if (frontEndJson == null || frontEndJson.trim().isEmpty()) {
return "[]"; // 返回空的 JSON 数组
}
// 2. 解析前端传递的 JSON 字符串为 List<Map<String, String>>如果为空直接返回空的 dbJson
ObjectMapper objectMapper = new ObjectMapper();
List<Map<String, String>> frontEndData = objectMapper.readValue(frontEndJson, List.class);
// 3. 如果前端有数据 dbJson 为空直接使用前端数据并将 data 设置为空
if (frontEndData != null && !frontEndData.isEmpty() && (dbJson == null || dbJson.trim().isEmpty())) {
List<Map<String, String>> result = new ArrayList<>();
for (Map<String, String> item : frontEndData) {
Map<String, String> newItem = new HashMap<>();
newItem.put("code", item.get("code"));
newItem.put("name", item.get("name"));
newItem.put("data", ""); // 数据为空
result.add(newItem);
}
return objectMapper.writeValueAsString(result); // 返回填充后的结果
}
// 4. 如果 dbJson 不为空解析 dbJson
List<Map<String, String>> dbData = objectMapper.readValue(dbJson, List.class);
// 5. 根据前端数据创建一个Map以便快速查找前端的项
Map<String, Map<String, String>> frontEndMap = frontEndData.stream()
.collect(Collectors.toMap(item -> (String) item.get("name"), item -> item));
// 6. 遍历数据库中的数据进行相应的增
List<Map<String, String>> result = new ArrayList<>();
// 7. 处理数据库中的项先将前端数据对应的项保留新增的项加上空的数据
for (Map<String, String> dbItem : dbData) {
String name = dbItem.get("name");
if (frontEndMap.containsKey(name)) {
// 如果前端有该项则保留数据库中的项保持其原有的id
// 只有当前端的 data 不为空时才更新避免改变数据库中原有的 data
String frontEndDataValue = frontEndMap.get(name).get("data");
// if (frontEndDataValue != null && !frontEndDataValue.trim().isEmpty()) {
// //dbItem.put("data", frontEndDataValue); // 只在前端有值时才更新
// }
result.add(dbItem);
frontEndMap.remove(name); // 从前端map中移除已处理的项
}
}
// 8. 处理前端数据中没有在数据库中出现的项新增这些项data为空
for (Map.Entry<String, Map<String, String>> entry : frontEndMap.entrySet()) {
Map<String, String> newItem = new HashMap<>();
newItem.put("code", entry.getValue().get("code")); // 保持前端传来的id
newItem.put("name", entry.getValue().get("name"));
newItem.put("data", ""); // 如果数据库中没有该项则data为空
result.add(newItem);
}
// 9. 将结果转换为 JSON 字符串并返回
return objectMapper.writeValueAsString(result);
}
// 动态创建任务文件表 // 动态创建任务文件表
private void createTaskFileTable(String taskCode) { private void createTaskFileTable(String taskCode) {
@ -326,17 +445,63 @@ public class TsTaskServiceImpl extends ServiceImpl<TsTaskMapper, TsTask> impleme
* 返回值说明: com.yfd.platform.config.ResponseResult 返回修改成功或者失败 * 返回值说明: com.yfd.platform.config.ResponseResult 返回修改成功或者失败
***********************************/ ***********************************/
@Override @Override
public boolean updatetsTask(TsTask tsTask) { public boolean updatetsTask(TsTask tsTask) throws IOException {
Boolean value = false;
//生成任务名称 任务开始时间_结束时间_地点_载机名称_设备代号_编号 //处理属性
String taskName = buildTaskName(tsTask); String frontEndJson = tsTask.getTaskProps();
tsTask.setTaskName(taskName); List<TsTask> tsTasksList = tsTaskMapper.selectList(new LambdaQueryWrapper<>());
int valueUpdate = tsTaskMapper.updateById(tsTask); if (tsTasksList.size() > 0) {
if (valueUpdate == 1) { for (TsTask tsTaskData : tsTasksList) {
return true; String dbJson = tsTaskData.getTaskProps();
} else { String syncData = syncData(frontEndJson, dbJson);
return false; tsTaskData.setTaskProps(syncData);
tsTaskMapper.updateById(tsTaskData);
}
} }
//修改的时候判断本地存储空间是不是发生了变化 如果是的话 需要重新创建本地文件
TsTask TsTaskOld = tsTaskMapper.selectById(tsTask.getId());
StorageSource storageSource = getStorageConfig(tsTask.getLocalStorageId());
if (!TsTaskOld.getLocalStorageId().equals(tsTask.getLocalStorageId())) {
String path = "/";
//新增节点的时候 创建文件夹
NewFolderRequest newFolderRequest = new NewFolderRequest();
newFolderRequest.setName(tsTask.getTaskName());//新建的文件夹名称,示例值(/a/b/c)
newFolderRequest.setPassword("");//文件夹密码, 如果文件夹需要密码才能访问则支持请求密码,示例值(123456)
newFolderRequest.setPath(path);//请求路径,示例值(/)
newFolderRequest.setStorageKey(storageSource.getKey());//存储源 key,示例值(local minio)
AbstractBaseFileService<?> fileService = storageSourceContext.getByStorageKey(newFolderRequest.getStorageKey());
boolean flag = fileService.newFolder(newFolderRequest.getPath(), newFolderRequest.getName());
if (flag) {
String taskName = buildTaskName(tsTask);
tsTask.setTaskName(taskName);
int valueUpdate = tsTaskMapper.updateById(tsTask);
if (valueUpdate == 1) {
value = true;
} else {
value = false;
}
value = true;
} else {
LOGGER.error("节点新增成功,但是本地专项文件夹创建失败");
value = false;
}
} else {
String taskName = buildTaskName(tsTask);
tsTask.setTaskName(taskName);
int valueUpdate = tsTaskMapper.updateById(tsTask);
if (valueUpdate == 1) {
value = true;
} else {
value = false;
}
}
return value;
} }
/********************************** /**********************************
@ -381,7 +546,7 @@ public class TsTaskServiceImpl extends ServiceImpl<TsTaskMapper, TsTask> impleme
// value = false; // value = false;
// } // }
StorageSource storageSource = getStorageConfig(tsTask.getLocalStorageId()); StorageSource storageSource = getStorageConfig(tsTask.getLocalStorageId());
// 删除 local 中的文件夹 项目文件夹 // 删除 local 中的文件夹 项目文件夹
List<BatchDeleteRequest.DeleteItem> deleteItemList = new ArrayList<>(); List<BatchDeleteRequest.DeleteItem> deleteItemList = new ArrayList<>();
BatchDeleteRequest.DeleteItem deleteItemData = new BatchDeleteRequest.DeleteItem(); BatchDeleteRequest.DeleteItem deleteItemData = new BatchDeleteRequest.DeleteItem();
@ -492,8 +657,8 @@ public class TsTaskServiceImpl extends ServiceImpl<TsTaskMapper, TsTask> impleme
LambdaQueryWrapper<TsTask> queryWrapper = new LambdaQueryWrapper<>(); LambdaQueryWrapper<TsTask> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.orderByDesc(TsTask::getTaskStartdate); queryWrapper.orderByDesc(TsTask::getTaskStartdate);
List<TsTask> tsTasks = tsTaskMapper.selectList(queryWrapper); List<TsTask> tsTasks = tsTaskMapper.selectList(queryWrapper);
for (TsTask tsTask : tsTasks){ for (TsTask tsTask : tsTasks) {
StorageSource storageSource = getStorageConfig(tsTask.getLocalStorageId()); StorageSource storageSource = getStorageConfig(tsTask.getLocalStorageId());
tsTask.setKey(storageSource.getKey()); tsTask.setKey(storageSource.getKey());
} }
return tsTasks; return tsTasks;
@ -531,7 +696,7 @@ public class TsTaskServiceImpl extends ServiceImpl<TsTaskMapper, TsTask> impleme
} }
// 辅助方法获取存储配置 // 辅助方法获取存储配置
private StorageSource getStorageConfig( Integer id) { private StorageSource getStorageConfig(Integer id) {
return storageSourceMapper.selectOne(new LambdaQueryWrapper<StorageSource>().eq(StorageSource::getId, id) return storageSourceMapper.selectOne(new LambdaQueryWrapper<StorageSource>().eq(StorageSource::getId, id)
); );
} }

View File

@ -3,15 +3,16 @@ package com.yfd.platform.modules.specialDocument.controller;
import cn.hutool.core.util.ObjUtil; import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject; import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.yfd.platform.annotation.Log; import com.yfd.platform.annotation.Log;
import com.yfd.platform.component.TaskStatusHolder; import com.yfd.platform.component.TaskStatusHolder;
import com.yfd.platform.component.WebSocketServer;
import com.yfd.platform.config.ResponseResult; import com.yfd.platform.config.ResponseResult;
import com.yfd.platform.modules.experimentalData.domain.TsNodes; import com.yfd.platform.modules.specialDocument.domain.Files;
import com.yfd.platform.modules.specialDocument.domain.Nodes; import com.yfd.platform.modules.specialDocument.domain.Nodes;
import com.yfd.platform.modules.specialDocument.service.IFilesService;
import com.yfd.platform.modules.specialDocument.service.INodesService; import com.yfd.platform.modules.specialDocument.service.INodesService;
import com.yfd.platform.system.domain.LoginUser; import com.yfd.platform.system.domain.LoginUser;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
@ -22,8 +23,8 @@ import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.io.IOException;
import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -43,6 +44,10 @@ public class NodesController {
@Resource @Resource
private INodesService nodesService; private INodesService nodesService;
@Resource
private IFilesService filesService;
@Autowired @Autowired
private TaskStatusHolder taskStatusHolder; private TaskStatusHolder taskStatusHolder;
@ -185,7 +190,7 @@ public class NodesController {
jsonObject1.putOpt("scanstatus", "1"); jsonObject1.putOpt("scanstatus", "1");
jsonObject1.putOpt("scanname", "扫描"); jsonObject1.putOpt("scanname", "扫描");
} }
}else { } else {
jsonObject1.putOpt("scanstatus", "1"); jsonObject1.putOpt("scanstatus", "1");
jsonObject1.putOpt("scanname", "扫描"); jsonObject1.putOpt("scanname", "扫描");
} }
@ -203,12 +208,12 @@ public class NodesController {
jsonObject1.putOpt("uploadstatus", "1"); jsonObject1.putOpt("uploadstatus", "1");
jsonObject1.putOpt("uploadname", "上传"); jsonObject1.putOpt("uploadname", "上传");
} }
}else { } else {
jsonObject1.putOpt("uploadstatus", "1"); jsonObject1.putOpt("uploadstatus", "1");
jsonObject1.putOpt("uploadname", "上传"); jsonObject1.putOpt("uploadname", "上传");
} }
//如果都为空 //如果都为空
if (StrUtil.isEmpty(scanValue)&& StrUtil.isEmpty(uploadValue)) { if (StrUtil.isEmpty(scanValue) && StrUtil.isEmpty(uploadValue)) {
jsonObject1.putOpt("scanstatus", "1"); jsonObject1.putOpt("scanstatus", "1");
jsonObject1.putOpt("scanname", "扫描"); jsonObject1.putOpt("scanname", "扫描");
jsonObject1.putOpt("uploadstatus", "1"); jsonObject1.putOpt("uploadstatus", "1");
@ -280,4 +285,34 @@ public class NodesController {
} }
} }
/**********************************
* 用途说明: 查询可不可以初始化专项文档扫描
* 参数说明 projectId 所属项目ID
* 返回值说明: com.yfd.platform.config.ResponseResult
***********************************/
@Log(module = "查询可不可以修改项目", value = "查询可不可以修改项目!")
@PostMapping("/selectNodesById")
@ApiOperation("查询可不可以修改项目")
public ResponseResult selectNodesById(String projectId) {
if (StrUtil.isBlank(projectId)) {
return ResponseResult.error("参数为空");
}
List<Nodes> nodesList = nodesService.list(new QueryWrapper<Nodes>().eq("project_id", projectId));
//如果节点不为空 就不能初始化了 如果大于0是false 代表不能修改
if (nodesList.size() > 0) {
return ResponseResult.successData(false);
} else {
//如果节点为空 就判断文件表ew Qu
List<Files> filesList = filesService.list(new QueryWrapper<Files>().eq("project_id", projectId));
if (filesList.size() > 0) {
return ResponseResult.successData(false);
} else {
return ResponseResult.successData(true);
}
}
}
} }

View File

@ -3,6 +3,8 @@ package com.yfd.platform.modules.specialDocument.controller;
import cn.hutool.core.util.ObjUtil; import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@ -10,11 +12,16 @@ import com.yfd.platform.annotation.Log;
import com.yfd.platform.config.ResponseResult; import com.yfd.platform.config.ResponseResult;
import com.yfd.platform.modules.specialDocument.domain.Project; import com.yfd.platform.modules.specialDocument.domain.Project;
import com.yfd.platform.modules.specialDocument.service.IProjectService; import com.yfd.platform.modules.specialDocument.service.IProjectService;
import com.yfd.platform.utils.StringUtils;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
@ -48,12 +55,41 @@ public class ProjectController {
@GetMapping("/page") @GetMapping("/page")
@ApiOperation("分页查询专项文档管理项目管理") @ApiOperation("分页查询专项文档管理项目管理")
@PreAuthorize("@el.check('select:project')") @PreAuthorize("@el.check('select:project')")
public ResponseResult getSdProjectPage(String description, String projectType, String projectName, Page<Project> page) { public ResponseResult getSdProjectPage(String description, String projectType, String projectName, Page<Project> page, String attributeContentJson) {
//分页查询 // 双重解码处理
Page<Project> sdProjectPage = projectService.getSdProjectPage(description, projectType, projectName, page); if (attributeContentJson != null) {
try {
// 第二次解码%5B [
attributeContentJson = URLDecoder.decode(attributeContentJson, StandardCharsets.UTF_8.name());
} catch (UnsupportedEncodingException e) {
return ResponseResult.error("参数解码错误");
}
}
// 将JSON字符串转换为List<Map<String, String>>
List<Map<String, String>> attributeContent = null;
if (StringUtils.isNotEmpty(attributeContentJson)) {
try {
// 使用 TypeReference 指定精确类型
attributeContent = JSON.parseObject(
attributeContentJson,
new TypeReference<List<Map<String, String>>>() {
}
);
// 遍历并移除空值字段
if (attributeContent != null) {
for (Map<String, String> item : attributeContent) {
// 遍历 Map移除值为空的键值对
item.entrySet().removeIf(entry -> entry.getValue() == null || entry.getValue().isEmpty());
}
}
} catch (Exception e) {
return ResponseResult.error("属性参数格式错误");
}
}
// 分页查询
Page<Project> sdProjectPage = projectService.getSdProjectPage(description, projectType, projectName, page, attributeContent);
return ResponseResult.successData(sdProjectPage); return ResponseResult.successData(sdProjectPage);
} }
/*********************************** /***********************************
* 用途说明新增专项文档管理-项目管理 * 用途说明新增专项文档管理-项目管理
* 参数说明 * 参数说明
@ -65,7 +101,7 @@ public class ProjectController {
@ApiOperation("新增专项文档管理项目管理") @ApiOperation("新增专项文档管理项目管理")
@ResponseBody @ResponseBody
@PreAuthorize("@el.check('add:project')") @PreAuthorize("@el.check('add:project')")
public ResponseResult addSdproject(@RequestBody Project project) { public ResponseResult addSdproject(@RequestBody Project project) throws IOException{
//对象不能为空 //对象不能为空
if (ObjUtil.isEmpty(project)) { if (ObjUtil.isEmpty(project)) {
return ResponseResult.error("参数为空"); return ResponseResult.error("参数为空");
@ -89,7 +125,7 @@ public class ProjectController {
@PostMapping("/updateSdproject") @PostMapping("/updateSdproject")
@ApiOperation("修改专项文档管理项目管理") @ApiOperation("修改专项文档管理项目管理")
@PreAuthorize("@el.check('update:project')") @PreAuthorize("@el.check('update:project')")
public ResponseResult updateSdproject(@RequestBody Project project) { public ResponseResult updateSdproject(@RequestBody Project project) throws IOException {
//对象不能为空 //对象不能为空
if (ObjUtil.isEmpty(project) && StrUtil.isBlank(project.getId())) { if (ObjUtil.isEmpty(project) && StrUtil.isBlank(project.getId())) {
return ResponseResult.error("参数为空"); return ResponseResult.error("参数为空");
@ -166,4 +202,6 @@ public class ProjectController {
} }
} }

View File

@ -1,8 +1,14 @@
package com.yfd.platform.modules.specialDocument.mapper; package com.yfd.platform.modules.specialDocument.mapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yfd.platform.modules.specialDocument.domain.Project; import com.yfd.platform.modules.specialDocument.domain.Project;
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import java.util.List;
import java.util.Map;
/** /**
* <p> * <p>
@ -18,4 +24,5 @@ public interface ProjectMapper extends BaseMapper<Project> {
static int createFileTable(@Param("tableName") String tableName) { static int createFileTable(@Param("tableName") String tableName) {
return 0; return 0;
} }
} }

View File

@ -4,7 +4,9 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yfd.platform.modules.specialDocument.domain.Project; import com.yfd.platform.modules.specialDocument.domain.Project;
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService;
import java.io.IOException;
import java.util.List; import java.util.List;
import java.util.Map;
/** /**
* <p> * <p>
@ -25,7 +27,7 @@ public interface IProjectService extends IService<Project> {
* pageNum 当前页 * pageNum 当前页
* 返回值说明: com.yfd.platform.config.ResponseResult 返回分页查询结果 * 返回值说明: com.yfd.platform.config.ResponseResult 返回分页查询结果
***********************************/ ***********************************/
Page<Project> getSdProjectPage(String description, String projectType, String projectName, Page<Project> page); Page<Project> getSdProjectPage(String description, String projectType, String projectName, Page<Project> page,List<Map<String, String>> attributeContent);
/*********************************** /***********************************
* 用途说明新增专项文档管理-项目管理 * 用途说明新增专项文档管理-项目管理
@ -33,7 +35,7 @@ public interface IProjectService extends IService<Project> {
* Project 项目管理 * Project 项目管理
* 返回值说明: com.yfd.platform.config.ResponseResult 返回新增成功或者失败 * 返回值说明: com.yfd.platform.config.ResponseResult 返回新增成功或者失败
***********************************/ ***********************************/
Boolean addSdproject(Project project); Boolean addSdproject(Project project) throws IOException;
/********************************** /**********************************
* 用途说明: 修改专项文档管理-项目管理 * 用途说明: 修改专项文档管理-项目管理
@ -41,7 +43,7 @@ public interface IProjectService extends IService<Project> {
* Project 项目管理 * Project 项目管理
* 返回值说明: com.yfd.platform.config.ResponseResult 返回修改成功或者失败 * 返回值说明: com.yfd.platform.config.ResponseResult 返回修改成功或者失败
***********************************/ ***********************************/
boolean updateSdproject(Project project); boolean updateSdproject(Project project) throws IOException;
boolean deleteProjectByIds(List<String> dataset); boolean deleteProjectByIds(List<String> dataset);

View File

@ -182,7 +182,7 @@ public class FilesServiceImpl extends ServiceImpl<FilesMapper, Files> implements
} }
queryWrapperfiles.eq(Files::getProjectId, projectId);//所属项目ID queryWrapperfiles.eq(Files::getProjectId, projectId);//所属项目ID
queryWrapperfiles.eq(Files::getNodeId, nodeId);//节点ID queryWrapperfiles.eq(Files::getNodeId, nodeId);//节点ID
queryWrapperfiles.orderByDesc(Files::getFileName);//时间 queryWrapperfiles.orderByAsc(Files::getFileName);//时间
//分页查询 //分页查询
Page<Files> filesPage = filesMapper.selectPage(page, queryWrapperfiles); Page<Files> filesPage = filesMapper.selectPage(page, queryWrapperfiles);
//处理文件内容 //处理文件内容

View File

@ -133,24 +133,37 @@ public class NodesServiceImpl extends ServiceImpl<NodesMapper, Nodes> implements
List<Map<String, Object>> allNodes = getAllNodes(projectId); List<Map<String, Object>> allNodes = getAllNodes(projectId);
// 查找所有根节点parentId为"00"的节点 // 查找所有根节点parentId为"00"的节点
List<Map<String, Object>> rootNodes = findRootNodes(allNodes, projectId); List<Map<String, Object>> rootNodes = findRootNodes(allNodes, projectId);
// 如果未找到根节点返回空列表
if (rootNodes.isEmpty()) {
return new ArrayList<>();
}
// 根节点的基本路径/项目名称/ // 根节点的基本路径/项目名称/
String basePath = "/" + project.getProjectName() + "/"; String basePath = "/" + project.getProjectName() + "/";
// 存储最终结果 // 存储最终结果
List<Map<String, Object>> result = new ArrayList<>(); List<Map<String, Object>> result = new ArrayList<>();
Map<String, Object> rootNodeData = new HashMap<>();
rootNodeData.put("creator", "admin");
rootNodeData.put("id", project.getId());
rootNodeData.put("nodeName", "根节点");
rootNodeData.put("nodeOrder", 1);
rootNodeData.put("nodeType", "01");
rootNodeData.put("parentId", "00");
rootNodeData.put("path", "/"+project.getProjectName()+"/");
rootNodeData.put("projectId", project.getId());
result.add(rootNodeData);
// 如果 nodeName 为空返回所有根节点的完整树形结构 // 如果 nodeName 为空返回所有根节点的完整树形结构
if (StringUtils.isEmpty(nodeName)) { if (StringUtils.isEmpty(nodeName)) {
for (Map<String, Object> rootNode : rootNodes) { // 如果未找到根节点返回空列表
rootNode.put("path", basePath); if (!rootNodes.isEmpty()) {
result.addAll(buildFullTree(rootNode, allNodes)); for (Map<String, Object> rootNode : rootNodes) {
rootNode.put("path", basePath);
result.addAll(buildFullTree(rootNode, allNodes));
}
} }
return result; return result;
} }
// 否则返回从根节点到目标节点的树形结构 // 否则返回从根节点到目标节点的树形结构
if (!rootNodes.isEmpty()) {
for (Map<String, Object> rootNode : rootNodes) { for (Map<String, Object> rootNode : rootNodes) {
rootNode.put("path", basePath); rootNode.put("path", basePath);
List<Map<String, Object>> tree = buildTreeToTargetNode(rootNode, allNodes, nodeName); List<Map<String, Object>> tree = buildTreeToTargetNode(rootNode, allNodes, nodeName);
@ -158,6 +171,7 @@ public class NodesServiceImpl extends ServiceImpl<NodesMapper, Nodes> implements
result.addAll(tree); result.addAll(tree);
} }
} }
}
// 返回结果 // 返回结果
return result; return result;
} }
@ -294,7 +308,7 @@ public class NodesServiceImpl extends ServiceImpl<NodesMapper, Nodes> implements
queryWrapper.eq("project_id", projectId); queryWrapper.eq("project_id", projectId);
} }
// 按节点顺序升序排序 // 按节点顺序升序排序
queryWrapper.orderByAsc("node_order"); queryWrapper.orderByAsc("node_name");
// 查询所有符合条件的节点 // 查询所有符合条件的节点
return nodesMapper.selectMaps(queryWrapper); return nodesMapper.selectMaps(queryWrapper);
} }
@ -613,11 +627,13 @@ public class NodesServiceImpl extends ServiceImpl<NodesMapper, Nodes> implements
// deleteWrapper.eq("project_id", nodes.getProjectId()); // deleteWrapper.eq("project_id", nodes.getProjectId());
// filesMapper.delete(deleteWrapper); // filesMapper.delete(deleteWrapper);
// } // }
//递归删除节点
nodesMapper.deleteNodesRecursively(id);
//递归删除文件 //递归删除文件
filesMapper.deleteByNodeId(id); filesMapper.deleteByNodeId(id);
//递归删除节点
nodesMapper.deleteNodesRecursively(id);
// 删除 sdlocal 中的文件夹 // 删除 sdlocal 中的文件夹
List<BatchDeleteRequest.DeleteItem> deleteItemList = new ArrayList<>(); List<BatchDeleteRequest.DeleteItem> deleteItemList = new ArrayList<>();
BatchDeleteRequest.DeleteItem deleteItemData = new BatchDeleteRequest.DeleteItem(); BatchDeleteRequest.DeleteItem deleteItemData = new BatchDeleteRequest.DeleteItem();
@ -853,7 +869,12 @@ public class NodesServiceImpl extends ServiceImpl<NodesMapper, Nodes> implements
Files files = new Files(); Files files = new Files();
files.setId(IdUtil.fastSimpleUUID()); files.setId(IdUtil.fastSimpleUUID());
files.setProjectId(id); files.setProjectId(id);
files.setNodeId("00"); if (absolutePath.equals(ensurePathFormat(finalPath))) {
files.setNodeId(id);
}else {
files.setNodeId("00");
}
files.setFileName(file.getName()); files.setFileName(file.getName());
files.setFilePath(ensurePathFormat(finalPath)); files.setFilePath(ensurePathFormat(finalPath));

View File

@ -4,6 +4,7 @@ import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.yfd.platform.modules.specialDocument.domain.Nodes; import com.yfd.platform.modules.specialDocument.domain.Nodes;
import com.yfd.platform.modules.specialDocument.domain.Project; import com.yfd.platform.modules.specialDocument.domain.Project;
import com.yfd.platform.modules.specialDocument.mapper.ProjectMapper; import com.yfd.platform.modules.specialDocument.mapper.ProjectMapper;
@ -27,11 +28,12 @@ import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.sql.DataSource; import javax.sql.DataSource;
import java.io.IOException;
import java.sql.*; import java.sql.*;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.ArrayList; import java.util.*;
import java.util.Collections; import java.util.concurrent.atomic.AtomicInteger;
import java.util.List; import java.util.stream.Collectors;
/** /**
* <p> * <p>
@ -79,37 +81,60 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
* 返回值说明: com.yfd.platform.config.ResponseResult 返回分页查询结果 * 返回值说明: com.yfd.platform.config.ResponseResult 返回分页查询结果
***********************************/ ***********************************/
@Override @Override
public Page<Project> getSdProjectPage(String description, String projectType, String projectName, Page<Project> page) { public Page<Project> getSdProjectPage(String description, String projectType, String projectName, Page<Project> page,List<Map<String, String>> attributeContent) {
LambdaQueryWrapper<Project> queryWrapper = new LambdaQueryWrapper<>(); LambdaQueryWrapper<Project> queryWrapper = new LambdaQueryWrapper<>();
//如果项目描述 description 不为空
if (StringUtils.isNotEmpty(description)) { // 基础条件处理
if (StringUtils.isNotEmpty(description))
queryWrapper.like(Project::getDescription, description); queryWrapper.like(Project::getDescription, description);
} if (StringUtils.isNotEmpty(projectType))
//如果项目类型 projectType 不为空
if (StringUtils.isNotEmpty(projectType)) {
queryWrapper.like(Project::getProjectType, projectType); queryWrapper.like(Project::getProjectType, projectType);
// //查询字典表获取项目类型对应数据字典 if (StringUtils.isNotEmpty(projectName))
// QueryWrapper<SysDictionaryItems> queryWrapperSysDictionary = new QueryWrapper<>();
// queryWrapperSysDictionary.eq("parentcode", "zxxmlx");
// queryWrapperSysDictionary.eq("itemcode", projectType);
// queryWrapperSysDictionary.orderByAsc("orderno");
// SysDictionaryItems sysDictionaryItems = sysDictionaryItemsMapper.selectOne(queryWrapperSysDictionary);
// if(sysDictionaryItems != null){
// queryWrapper.like(Project::getProjectType, sysDictionaryItems.getDictName());
// }else {
// queryWrapper.like(Project::getProjectType, projectType);
// }
}
//如果项目名称 projectName 不为空
if (StringUtils.isNotEmpty(projectName)) {
queryWrapper.like(Project::getProjectName, projectName); queryWrapper.like(Project::getProjectName, projectName);
}
//根据创建时间排序
queryWrapper.orderByDesc(Project::getProjectTime); queryWrapper.orderByDesc(Project::getProjectTime);
//分页查询 // 处理属性过滤条件 - MySQL 5.7+ 兼容版本
Page<Project> sdProjectPage = projectMapper.selectPage(page, queryWrapper); if (attributeContent != null && !attributeContent.isEmpty()) {
return sdProjectPage; for (Map<String, String> attr : attributeContent) {
for (Map.Entry<String, String> entry : attr.entrySet()) {
String code = entry.getKey();
String value = entry.getValue();
if (StringUtils.isEmpty(value)) {
// 检查属性存在
queryWrapper.apply(
"EXISTS (SELECT 1 FROM JSON_TABLE(project_props, '$[*]' " +
"COLUMNS (code VARCHAR(50) PATH '$.code') AS jt " +
"WHERE jt.code = {0})",
code
);
} else {
// 转义特殊字符
String safeValue = value.replace("'", "''")
.replace("%", "\\%")
.replace("_", "\\_");
// 使用 JSON_EXTRACT 实现兼容查询
queryWrapper.apply(
"EXISTS (SELECT 1 FROM (" +
" SELECT " +
" JSON_UNQUOTE(JSON_EXTRACT(t.obj, '$.code')) AS code, " +
" JSON_UNQUOTE(JSON_EXTRACT(t.obj, '$.data')) AS data " +
" FROM (" +
" SELECT JSON_EXTRACT(project_props, CONCAT('$[', idx.idx, ']')) AS obj " +
" FROM (SELECT 0 AS idx UNION SELECT 1 UNION SELECT 2 UNION SELECT 3) idx" +
" WHERE idx.idx < JSON_LENGTH(project_props)" +
" ) t" +
") jt " +
"WHERE jt.code = {0} AND jt.data LIKE CONCAT('%', {1}, '%'))",
code, value
);
}
}
}
}
return projectMapper.selectPage(page, queryWrapper);
} }
/*********************************** /***********************************
@ -119,12 +144,24 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
* 返回值说明: com.yfd.platform.config.ResponseResult 返回新增成功或者失败 * 返回值说明: com.yfd.platform.config.ResponseResult 返回新增成功或者失败
***********************************/ ***********************************/
@Override @Override
public Boolean addSdproject(Project project) { public Boolean addSdproject(Project project) throws IOException {
//创建项目的时候要创建一个本地的文件夹 路径的话去找专项的存储路径 //创建项目的时候要创建一个本地的文件夹 路径的话去找专项的存储路径
//生成项目编号 //生成项目编号
String projectCode = generateNextProjectCode(); String projectCode = generateNextProjectCode();
project.setProjectCode(projectCode); project.setProjectCode(projectCode);
String frontEndJson = project.getProjectProps();
List<Project> projectList = projectMapper.selectList(new LambdaQueryWrapper<>());
if (projectList.size()>0){
for (Project projectData : projectList) {
String dbJson = projectData.getProjectProps();
String syncData = syncData(frontEndJson, dbJson);
projectData.setProjectProps(syncData);
projectMapper.updateById(projectData);
}
}
// 设置当前时间 // 设置当前时间
LocalDateTime now = LocalDateTime.now(); LocalDateTime now = LocalDateTime.now();
// 转换为 Timestamp // 转换为 Timestamp
@ -270,25 +307,119 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
* 返回值说明: com.yfd.platform.config.ResponseResult 返回修改成功或者失败 * 返回值说明: com.yfd.platform.config.ResponseResult 返回修改成功或者失败
***********************************/ ***********************************/
@Override @Override
public boolean updateSdproject(Project project) { public boolean updateSdproject(Project project) throws IOException {
//查询字典表获取项目类型对应数据字典 Boolean value = true;
// QueryWrapper<SysDictionaryItems> queryWrapperSysDictionary = new QueryWrapper<>();
// queryWrapperSysDictionary.eq("parentcode", "zxxmlx");
// queryWrapperSysDictionary.eq("itemcode", project.getProjectType());
// queryWrapperSysDictionary.orderByAsc("orderno");
// SysDictionaryItems sysDictionaryItems = sysDictionaryItemsMapper.selectOne(queryWrapperSysDictionary);
// if(sysDictionaryItems != null){
// project.setProjectType(sysDictionaryItems.getDictName());
// }
if (project.getProjectTime() == null || project.getProjectTime().equals("")) { if (project.getProjectTime() == null || project.getProjectTime().equals("")) {
project.setProjectTime(null); project.setProjectTime(null);
} }
int valueUpdate = projectMapper.updateById(project); String frontEndJson = project.getProjectProps();
if (valueUpdate == 1) { List<Project> projectList = projectMapper.selectList(new LambdaQueryWrapper<>());
return true; if (projectList.size()>0){
} else { for (Project projectData : projectList) {
return false; String dbJson = projectData.getProjectProps();
String syncData = syncData(frontEndJson, dbJson);
projectData.setProjectProps(syncData);
projectMapper.updateById(projectData);
}
} }
//修改的时候判断本地存储空间是不是发生了变化 如果是的话 需要重新创建本地文件
Project projectOld = projectMapper.selectById(project.getId());
StorageSource storageSource = getStorageConfig(project.getLocalStorageId());
if (!projectOld.getLocalStorageId().equals(project.getLocalStorageId())){
String path = "/";
//新增节点的时候 创建文件夹
NewFolderRequest newFolderRequest = new NewFolderRequest();
newFolderRequest.setName(project.getProjectName());//新建的文件夹名称,示例值(/a/b/c)
newFolderRequest.setPassword("");//文件夹密码, 如果文件夹需要密码才能访问则支持请求密码,示例值(123456)
newFolderRequest.setPath(path);//请求路径,示例值(/)
newFolderRequest.setStorageKey(storageSource.getKey());//存储源 key,示例值(local minio)
AbstractBaseFileService<?> fileService = storageSourceContext.getByStorageKey(newFolderRequest.getStorageKey());
boolean flag = fileService.newFolder(newFolderRequest.getPath(), newFolderRequest.getName());
if (flag) {
int valueUpdate = projectMapper.updateById(project);
if (valueUpdate == 1) {
value = true;
} else {
value = false;
}
value = true;
} else {
LOGGER.error("节点新增成功,但是本地专项文件夹创建失败");
value = false;
}
}else {
int valueUpdate = projectMapper.updateById(project);
if (valueUpdate == 1) {
value = true;
} else {
value = false;
}
}
return value;
}
public static String syncData(String frontEndJson, String dbJson) throws IOException {
// 1. 如果 frontEndJson 为空则返回一个空的 dbJson
if (frontEndJson == null || frontEndJson.trim().isEmpty()) {
return "[]"; // 返回空的 JSON 数组
}
// 2. 解析前端传递的 JSON 字符串为 List<Map<String, String>>如果为空直接返回空的 dbJson
ObjectMapper objectMapper = new ObjectMapper();
List<Map<String, String>> frontEndData = objectMapper.readValue(frontEndJson, List.class);
// 3. 如果前端有数据 dbJson 为空直接使用前端数据并将 data 设置为空
if (frontEndData != null && !frontEndData.isEmpty() && (dbJson == null || dbJson.trim().isEmpty())) {
List<Map<String, String>> result = new ArrayList<>();
for (Map<String, String> item : frontEndData) {
Map<String, String> newItem = new HashMap<>();
newItem.put("code", item.get("code"));
newItem.put("name", item.get("name"));
newItem.put("data", ""); // 数据为空
result.add(newItem);
}
return objectMapper.writeValueAsString(result); // 返回填充后的结果
}
// 4. 如果 dbJson 不为空解析 dbJson
List<Map<String, String>> dbData = objectMapper.readValue(dbJson, List.class);
// 5. 根据前端数据创建一个Map以便快速查找前端的项
Map<String, Map<String, String>> frontEndMap = frontEndData.stream()
.collect(Collectors.toMap(item -> (String) item.get("name"), item -> item));
// 6. 遍历数据库中的数据进行相应的增
List<Map<String, String>> result = new ArrayList<>();
// 7. 处理数据库中的项先将前端数据对应的项保留新增的项加上空的数据
for (Map<String, String> dbItem : dbData) {
String name = dbItem.get("name");
if (frontEndMap.containsKey(name)) {
// 如果前端有该项则保留数据库中的项保持其原有的id
// 只有当前端的 data 不为空时才更新避免改变数据库中原有的 data
String frontEndDataValue = frontEndMap.get(name).get("data");
// if (frontEndDataValue != null && !frontEndDataValue.trim().isEmpty()) {
// //dbItem.put("data", frontEndDataValue); // 只在前端有值时才更新
// }
result.add(dbItem);
frontEndMap.remove(name); // 从前端map中移除已处理的项
}
}
// 8. 处理前端数据中没有在数据库中出现的项新增这些项data为空
for (Map.Entry<String, Map<String, String>> entry : frontEndMap.entrySet()) {
Map<String, String> newItem = new HashMap<>();
newItem.put("code", entry.getValue().get("code")); // 保持前端传来的id
newItem.put("name", entry.getValue().get("name"));
newItem.put("data", ""); // 如果数据库中没有该项则data为空
result.add(newItem);
}
// 9. 将结果转换为 JSON 字符串并返回
return objectMapper.writeValueAsString(result);
} }
/********************************** /**********************************

View File

@ -17,10 +17,15 @@ import com.yfd.platform.modules.storage.model.entity.StorageSourceConfig;
import com.yfd.platform.modules.storage.model.result.StorageSourceAdminResult; import com.yfd.platform.modules.storage.model.result.StorageSourceAdminResult;
import com.yfd.platform.modules.storage.model.result.StorageSourceConfigResult; import com.yfd.platform.modules.storage.model.result.StorageSourceConfigResult;
import com.yfd.platform.modules.storage.model.result.StorageSourceResult; import com.yfd.platform.modules.storage.model.result.StorageSourceResult;
import com.yfd.platform.utils.StringUtils;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.io.File; import java.io.File;
import java.nio.file.FileStore;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.text.DecimalFormat; import java.text.DecimalFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
@ -135,8 +140,10 @@ public class StorageSourceConvertImpl implements StorageSourceConvert {
String value = storageSourceConfigMapper.selectOne(queryWrapperData).getValue(); String value = storageSourceConfigMapper.selectOne(queryWrapperData).getValue();
storageSource.setValueData(value); storageSource.setValueData(value);
//空间使用率 if(StringUtils.isNotBlank(value)){
storageSource.setSpaceOccupancyRatio(calculateLocalStorageUsage(value)); //空间使用率
storageSource.setSpaceOccupancyRatio(calculateLocalStorageUsage(value));
}
}else { }else {
LambdaQueryWrapper<TsTask> queryWrapper1 = new LambdaQueryWrapper<>(); LambdaQueryWrapper<TsTask> queryWrapper1 = new LambdaQueryWrapper<>();
@ -151,7 +158,18 @@ public class StorageSourceConvertImpl implements StorageSourceConvert {
} }
} }
storageSource.setStoreContent(String.valueOf(result)); storageSource.setStoreContent(String.valueOf(result));
storageSource.setValueData(null); //存储路径
LambdaQueryWrapper<StorageSourceConfig> queryWrapperData = new LambdaQueryWrapper<>();
queryWrapperData.eq(StorageSourceConfig::getStorageId, storageSource.getId());
queryWrapperData.eq(StorageSourceConfig::getName, "filePath");
String value = storageSourceConfigMapper.selectOne(queryWrapperData).getValue();
storageSource.setValueData(value);
if(StringUtils.isNotBlank(value)){
//空间使用率
storageSource.setSpaceOccupancyRatio(calculateLocalStorageUsage(value));
}
} }
} }
@ -180,22 +198,48 @@ public class StorageSourceConvertImpl implements StorageSourceConvert {
// 计算本地路径的空间使用率 // 计算本地路径的空间使用率
public static String calculateLocalStorageUsage(String path) { public static String calculateLocalStorageUsage(String path) {
File file = new File(path);
if (!file.exists()) { try {
throw new IllegalArgumentException("路径不存在: " + path); Path target = Paths.get(path);
// 处理符号链接获取实际挂载点
if (Files.isSymbolicLink(target)) {
target = Files.readSymbolicLink(target);
}
// 获取文件存储信息
FileStore store = Files.getFileStore(target);
long totalSpace = store.getTotalSpace();
long usableSpace = store.getUsableSpace();
if (totalSpace <= 0) {
return "0%"; // 特殊文件系统处理
}
double usagePercentage = (double) (totalSpace - usableSpace) / totalSpace * 100;
DecimalFormat df = new DecimalFormat("#.##");
return df.format(usagePercentage) + "%";
} catch (Exception e) {
throw new IllegalArgumentException("无法获取磁盘空间: " + e.getMessage());
} }
// File file = new File(path);
// 获取磁盘空间信息 // if (!file.exists()) {
long totalSpace = file.getTotalSpace(); // throw new IllegalArgumentException("路径不存在: " + path);
long freeSpace = file.getFreeSpace(); // }
// 计算使用率 //
long usedSpace = totalSpace - freeSpace; // // 获取磁盘空间信息
double usagePercentage = (double) usedSpace / totalSpace * 100; // long totalSpace = file.getTotalSpace();
// long freeSpace = file.getFreeSpace();
// 格式化输出 // // 计算使用率
DecimalFormat df = new DecimalFormat("#.##"); // long usedSpace = totalSpace - freeSpace;
// double usagePercentage = (double) usedSpace / totalSpace * 100;
return df.format(usagePercentage) + "%"; //
// // 格式化输出
// DecimalFormat df = new DecimalFormat("#.##");
//
// return df.format(usagePercentage) + "%";
} }

View File

@ -3,6 +3,7 @@ package com.yfd.platform.modules.storage.service;
import cn.hutool.core.convert.Convert; import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ReflectUtil; import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yfd.platform.exception.BadRequestException; import com.yfd.platform.exception.BadRequestException;
@ -10,6 +11,10 @@ import com.yfd.platform.exception.StorageSourceException;
import com.yfd.platform.exception.file.InvalidStorageSourceException; import com.yfd.platform.exception.file.InvalidStorageSourceException;
import com.yfd.platform.modules.config.model.request.SaveStorageSourceRequest; import com.yfd.platform.modules.config.model.request.SaveStorageSourceRequest;
import com.yfd.platform.modules.config.model.request.UpdateStorageSortRequest; import com.yfd.platform.modules.config.model.request.UpdateStorageSortRequest;
import com.yfd.platform.modules.experimentalData.domain.TsTask;
import com.yfd.platform.modules.experimentalData.mapper.TsTaskMapper;
import com.yfd.platform.modules.specialDocument.domain.Project;
import com.yfd.platform.modules.specialDocument.mapper.ProjectMapper;
import com.yfd.platform.modules.storage.context.StorageSourceContext; import com.yfd.platform.modules.storage.context.StorageSourceContext;
import com.yfd.platform.modules.storage.convert.StorageSourceConvert; import com.yfd.platform.modules.storage.convert.StorageSourceConvert;
import com.yfd.platform.modules.storage.mapper.StorageSourceMapper; import com.yfd.platform.modules.storage.mapper.StorageSourceMapper;
@ -55,6 +60,13 @@ public class StorageSourceService {
@Resource @Resource
private StorageSourceConvert storageSourceConvert; private StorageSourceConvert storageSourceConvert;
//专项项目表Mapper
@Resource
private ProjectMapper projectMapper;
//试验任务Mapper
@Resource
private TsTaskMapper tsTaskMapper;
/** /**
* 获取所有存储源列表 * 获取所有存储源列表
@ -244,6 +256,37 @@ public class StorageSourceService {
public StorageSource deleteById(Integer id) { public StorageSource deleteById(Integer id) {
log.info("删除 id 为 {} 的存储源", id); log.info("删除 id 为 {} 的存储源", id);
StorageSource storageSource = findById(id); StorageSource storageSource = findById(id);
String type = storageSource.getType().getKey();
if ("local".equals(type)) {
//获取关联的存储内容 先获取专项文档
LambdaQueryWrapper<Project> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(Project::getLocalStorageId, storageSource.getId());
List<Project> projects = projectMapper.selectList(queryWrapper);
if (projects.size()>0){
throw new BadRequestException("存在存储内容不能删除");
}
LambdaQueryWrapper<TsTask> queryWrapper1 = new LambdaQueryWrapper<>();
queryWrapper1.eq(TsTask::getLocalStorageId, storageSource.getId());
List<TsTask> tsTasks = tsTaskMapper.selectList(queryWrapper1);
if (tsTasks.size()>0){
throw new BadRequestException("存在存储内容不能删除");
}
}else {
LambdaQueryWrapper<TsTask> queryWrapper1 = new LambdaQueryWrapper<>();
queryWrapper1.eq(TsTask::getBackupStorageId, storageSource.getId());
List<TsTask> tsTasks = tsTaskMapper.selectList(queryWrapper1);
if (tsTasks.size()>0){
throw new BadRequestException("存在存储内容不能删除");
}
}
if (storageSource == null) { if (storageSource == null) {
String msg = StrUtil.format("删除存储源时检测到 id 为 {} 的存储源不存在", id); String msg = StrUtil.format("删除存储源时检测到 id 为 {} 的存储源不存在", id);
@ -316,7 +359,7 @@ public class StorageSourceService {
saveStorageSourceRequest.getKey(), saveStorageSourceRequest.getType().getDescription()); saveStorageSourceRequest.getKey(), saveStorageSourceRequest.getType().getDescription());
StorageSource storageSourceData = storageSourceMapper.findByStorageKey(saveStorageSourceRequest.getKey()); StorageSource storageSourceData = storageSourceMapper.findByStorageKey(saveStorageSourceRequest.getKey());
if (storageSourceData != null ){ if (storageSourceData != null && saveStorageSourceRequest.getId() == null ){
throw new BadRequestException("填充存储源别名已存在"); throw new BadRequestException("填充存储源别名已存在");
} }
@ -338,6 +381,7 @@ public class StorageSourceService {
storageSourceConfigService.toStorageSourceConfigList(storageId, storageSourceConfigService.toStorageSourceConfigList(storageId,
dbSaveResult.getType(), dbSaveResult.getType(),
saveStorageSourceRequest.getStorageSourceAllParam()); saveStorageSourceRequest.getStorageSourceAllParam());
storageSourceConfigService.saveBatch(storageId, storageSourceConfigList); storageSourceConfigService.saveBatch(storageId, storageSourceConfigList);
log.info("保存存储源参数成功,尝试根据参数初始化存储源, id: {}, name: {}, config size: {}", log.info("保存存储源参数成功,尝试根据参数初始化存储源, id: {}, name: {}, config size: {}",
dbSaveResult.getId(), dbSaveResult.getName(), storageSourceConfigList.size()); dbSaveResult.getId(), dbSaveResult.getName(), storageSourceConfigList.size());