优化代码提交
This commit is contained in:
parent
f7a3023629
commit
e2ea3338f1
@ -2,10 +2,16 @@ package com.yfd.platform.config;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.DbType;
|
||||
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
|
||||
import com.baomidou.mybatisplus.extension.plugins.handler.TableNameHandler;
|
||||
import com.baomidou.mybatisplus.extension.plugins.inner.DynamicTableNameInnerInterceptor;
|
||||
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
|
||||
import com.yfd.platform.utils.TableNameContextHolder;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/******************************
|
||||
* 用途说明:
|
||||
* 作者姓名: pcj
|
||||
@ -16,11 +22,36 @@ public class MybitsPlusConfig {
|
||||
|
||||
@Bean
|
||||
public MybatisPlusInterceptor mybatisPlusInterceptor() {
|
||||
MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
|
||||
mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
|
||||
return mybatisPlusInterceptor;
|
||||
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
|
||||
|
||||
// 创建动态表名拦截器
|
||||
DynamicTableNameInnerInterceptor dynamicInterceptor = new DynamicTableNameInnerInterceptor();
|
||||
|
||||
// 创建表名处理器映射
|
||||
Map<String, TableNameHandler> handlerMap = new HashMap<>();
|
||||
|
||||
// 为 ts_files 表添加处理器
|
||||
handlerMap.put("ts_files", new TableNameHandler() {
|
||||
@Override
|
||||
public String dynamicTableName(String sql, String tableName) {
|
||||
String taskCode = TableNameContextHolder.getTaskCode();
|
||||
if (taskCode == null || taskCode.isEmpty()) {
|
||||
throw new IllegalArgumentException("任务编码不能为空");
|
||||
}
|
||||
return "ts_files_" + taskCode;
|
||||
}
|
||||
});
|
||||
|
||||
// 设置处理器映射
|
||||
dynamicInterceptor.setTableNameHandlerMap(handlerMap);
|
||||
// 添加动态表名拦截器
|
||||
interceptor.addInnerInterceptor(dynamicInterceptor);
|
||||
// 添加分页拦截器
|
||||
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
|
||||
return interceptor;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -167,12 +167,12 @@ public class TsFilesController {
|
||||
@PostMapping("/deleteTsFilesById")
|
||||
@ApiOperation("根据ID删除试验数据管理文档内容")
|
||||
@PreAuthorize("@el.check('del:tsFiles')")
|
||||
public ResponseResult deleteTsFilesById(@RequestParam String id, @RequestParam String type) {
|
||||
if (StrUtil.isBlank(id)) {
|
||||
public ResponseResult deleteTsFilesById(@RequestParam String id, @RequestParam String type,@RequestParam String taskId) {
|
||||
if (StrUtil.isBlank(id) || StrUtil.isBlank(taskId)) {
|
||||
return ResponseResult.error("参数为空");
|
||||
}
|
||||
List<String> dataset = Arrays.asList(id);
|
||||
return ResponseResult.success(tsFilesService.deleteTsFilesByIds(dataset, type));
|
||||
return ResponseResult.success(tsFilesService.deleteTsFilesByIds(dataset, type,taskId));
|
||||
}
|
||||
|
||||
/**********************************
|
||||
@ -185,14 +185,14 @@ public class TsFilesController {
|
||||
@PostMapping("/deleteTsFilesByIds")
|
||||
@ApiOperation("批量删除试验数据管理文档内容")
|
||||
@PreAuthorize("@el.check('del:tsFiles')")
|
||||
public ResponseResult deleteTsFilesByIds(@RequestParam String ids, @RequestParam String type) {
|
||||
if (StrUtil.isBlank(ids)) {
|
||||
public ResponseResult deleteTsFilesByIds(@RequestParam String ids, @RequestParam String type,@RequestParam String taskId) {
|
||||
if (StrUtil.isBlank(ids) || StrUtil.isBlank(taskId)) {
|
||||
return ResponseResult.error("参数为空");
|
||||
}
|
||||
String[] splitIds = ids.split(",");
|
||||
// 数组转集合
|
||||
List<String> dataset = Arrays.asList(splitIds);
|
||||
return ResponseResult.success(tsFilesService.deleteTsFilesByIds(dataset, type));
|
||||
return ResponseResult.success(tsFilesService.deleteTsFilesByIds(dataset, type,taskId));
|
||||
}
|
||||
|
||||
/**************************压缩 解压缩********************************/
|
||||
@ -211,13 +211,13 @@ public class TsFilesController {
|
||||
@Log(module = "实验数据管理", value = "压缩文件夹接口!")
|
||||
@PostMapping("/compress")
|
||||
@ApiOperation("压缩文件夹接口")
|
||||
public ResponseResult compressFolder(String ids, String compressedFormat, String compressedName, String compressedPath, String covered, String parentId, String path) {
|
||||
public ResponseResult compressFolder(String ids, String compressedFormat, String compressedName, String compressedPath, String covered, String parentId, String path,String taskId) {
|
||||
try {
|
||||
if (StrUtil.isBlank(ids) && StrUtil.isBlank(compressedFormat) && StrUtil.isBlank(compressedName) && StrUtil.isBlank(compressedPath) && StrUtil.isBlank(path)) {
|
||||
if (StrUtil.isBlank(ids) && StrUtil.isBlank(compressedFormat) && StrUtil.isBlank(compressedName) && StrUtil.isBlank(compressedPath) && StrUtil.isBlank(path) && StrUtil.isBlank(taskId)) {
|
||||
return ResponseResult.error("参数为空");
|
||||
}
|
||||
|
||||
return ResponseResult.success(tsFilesService.compressFolder(ids, compressedFormat, compressedName, compressedPath, covered, parentId, path));
|
||||
return ResponseResult.success(tsFilesService.compressFolder(ids, compressedFormat, compressedName, compressedPath, covered, parentId, path,taskId));
|
||||
} catch (Exception e) {
|
||||
System.out.print("压缩异常原因" + e);
|
||||
return ResponseResult.error("压缩失败");
|
||||
@ -235,12 +235,12 @@ public class TsFilesController {
|
||||
@Log(module = "实验数据管理", value = "解压缩接口!")
|
||||
@PostMapping("/decompression")
|
||||
@ApiOperation("解压缩接口")
|
||||
public ResponseResult decompressionFolder(String id, String decompressionPath, String parentId, String path) {
|
||||
public ResponseResult decompressionFolder(String id, String decompressionPath, String parentId, String path,String taskId) {
|
||||
try {
|
||||
if (StrUtil.isBlank(id)) {
|
||||
if (StrUtil.isBlank(id)|| StrUtil.isBlank(taskId)) {
|
||||
return ResponseResult.error("参数为空");
|
||||
}
|
||||
return ResponseResult.success(tsFilesService.decompressionFolder(id, decompressionPath, parentId, path));
|
||||
return ResponseResult.success(tsFilesService.decompressionFolder(id, decompressionPath, parentId, path,taskId));
|
||||
} catch (Exception e) {
|
||||
System.out.print("解压缩异常原因" + e);
|
||||
return ResponseResult.error("解压缩失败");
|
||||
@ -654,12 +654,12 @@ public class TsFilesController {
|
||||
@Log(module = "实验数据管理", value = "实时获取轨迹数据!")
|
||||
@PostMapping("/startSimpleNavi")
|
||||
@ApiOperation("实时获取轨迹数据")
|
||||
public ResponseResult startSimpleNavi(String id, int samTimes, String token) {
|
||||
public ResponseResult startSimpleNavi(String id, int samTimes, String token,String taskId) {
|
||||
try {
|
||||
// 使用线程池异步执行任务
|
||||
CompletableFuture.runAsync(() -> {
|
||||
try {
|
||||
tsFilesService.batchSendNaviOutDataJob(id, samTimes, token);
|
||||
tsFilesService.batchSendNaviOutDataJob(id, samTimes, token,taskId);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
@ -694,12 +694,12 @@ public class TsFilesController {
|
||||
@Log(module = "实验数据管理", value = "查询文件内容!")
|
||||
@GetMapping("/api/files/content")
|
||||
@ApiOperation("查询文件内容")
|
||||
public ResponseResult getFileContent(@RequestParam String id) {
|
||||
public ResponseResult getFileContent(@RequestParam String id,String taskId) {
|
||||
try {
|
||||
if (StrUtil.isBlank(id)) {
|
||||
if (StrUtil.isBlank(id) && StrUtil.isBlank(taskId)) {
|
||||
return ResponseResult.error("参数为空");
|
||||
}
|
||||
String content = tsFilesService.readFileContent(id);
|
||||
String content = tsFilesService.readFileContent(id, taskId);
|
||||
return ResponseResult.successData(content);
|
||||
} catch (SecurityException | IOException e) {
|
||||
return ResponseResult.error("非法操作: " + e.getMessage());
|
||||
@ -715,12 +715,12 @@ public class TsFilesController {
|
||||
@Log(module = "实验数据管理", value = "保存文件内容!")
|
||||
@PostMapping("/save/files/content")
|
||||
@ApiOperation("保存文件内容")
|
||||
public ResponseResult saveFileContent(String id, String content) {
|
||||
public ResponseResult saveFileContent(String id, String content,String taskId) {
|
||||
try {
|
||||
if (StrUtil.isBlank(id) && StrUtil.isBlank(content)) {
|
||||
if (StrUtil.isBlank(id) && StrUtil.isBlank(content) && StrUtil.isBlank(taskId)) {
|
||||
return ResponseResult.error("参数为空");
|
||||
}
|
||||
tsFilesService.saveFileContent(id, content);
|
||||
tsFilesService.saveFileContent(id, content, taskId);
|
||||
return ResponseResult.success("文件保存成功");
|
||||
} catch (SecurityException | IOException e) {
|
||||
return ResponseResult.error("非法操作: " + e.getMessage());
|
||||
@ -737,7 +737,7 @@ public class TsFilesController {
|
||||
@PostMapping("/batchModify")
|
||||
@ApiOperation("批量修改文件中多行多列的内容")
|
||||
public ResponseResult batchModifyFile(@RequestBody BatchModifyRequest request) throws IOException {
|
||||
tsFilesService.batchUpdateFile(request.getId(), request.getModifications());
|
||||
tsFilesService.batchUpdateFile(request.getId(), request.getModifications(),request.getTaskId());
|
||||
return ResponseResult.success("文件保存成功");
|
||||
}
|
||||
|
||||
@ -749,12 +749,12 @@ public class TsFilesController {
|
||||
@Log(module = "实验数据管理", value = "获取文件url!")
|
||||
@PostMapping("/obtainUrl")
|
||||
@ApiOperation("获取文件url")
|
||||
public ResponseResult obtainUrl(String id, String type) {
|
||||
if (StrUtil.isBlank(id) && StrUtil.isBlank(type)) {
|
||||
public ResponseResult obtainUrl(String id, String type,String taskId) {
|
||||
if (StrUtil.isBlank(id) && StrUtil.isBlank(type) && StrUtil.isBlank(type)) {
|
||||
return ResponseResult.error("参数为空");
|
||||
}
|
||||
//查询本地树和minio树
|
||||
FileItemResult fileItemResult = tsFilesService.obtainUrl(id, type);
|
||||
FileItemResult fileItemResult = tsFilesService.obtainUrl(id, type,taskId);
|
||||
return ResponseResult.successData(fileItemResult);
|
||||
}
|
||||
}
|
||||
|
@ -184,9 +184,7 @@ public class TsTaskController {
|
||||
@ResponseBody
|
||||
//@PreAuthorize("@el.check('select:devicesignal')")
|
||||
public ResponseResult listTsTask() {
|
||||
LambdaQueryWrapper<TsTask> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.orderByDesc(TsTask::getTaskStartdate);
|
||||
List<TsTask> tsTasks = tsTaskService.list(queryWrapper);
|
||||
List<TsTask> tsTasks = tsTaskService.listTsTask();
|
||||
return ResponseResult.successData(tsTasks);
|
||||
}
|
||||
}
|
||||
|
@ -13,6 +13,9 @@ public class BatchModifyRequest {
|
||||
@NotBlank
|
||||
private String id; // 文件ID
|
||||
|
||||
@NotBlank
|
||||
private String taskId; // 任务ID
|
||||
|
||||
@NotEmpty
|
||||
private List<ModifyCommand> modifications;
|
||||
}
|
||||
|
@ -12,5 +12,6 @@ public class MoveCopyFileFolderRequest {
|
||||
private String newFileName;
|
||||
private String rename;
|
||||
private String type;
|
||||
private String taskId;
|
||||
|
||||
}
|
||||
|
@ -7,5 +7,6 @@ import java.util.List;
|
||||
@Data
|
||||
public class Parameter {
|
||||
public List<ParameterList> parameterLists;
|
||||
public String taskId;
|
||||
// public String parameterLists;
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package com.yfd.platform.modules.experimentalData.domain;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
|
||||
@ -138,7 +139,21 @@ public class TsTask implements Serializable {
|
||||
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
|
||||
private LocalDate taskEnddate;
|
||||
|
||||
/**
|
||||
* 本地存储空间id
|
||||
*/
|
||||
private Integer localStorageId;
|
||||
|
||||
/**
|
||||
* 备份存储空间id
|
||||
*/
|
||||
private Integer backupStorageId;
|
||||
|
||||
/**
|
||||
* 上传用到KEY:TODO 增加用于前端展示
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
private String key;
|
||||
|
||||
|
||||
}
|
||||
|
@ -21,4 +21,7 @@ public interface TsFilesMapper extends BaseMapper<TsFiles> {
|
||||
int updateParentIdByPathHierarchy(@Param("taskId") String taskId, @Param("nodeId") String nodeId);
|
||||
|
||||
int countFiles(@Param("id") String id);
|
||||
|
||||
|
||||
void updateTsFileByPath(@Param("taskId") String taskId,@Param("oldBasePath") String oldBasePath,@Param("newBasePath") String newBasePath);
|
||||
}
|
||||
|
@ -60,7 +60,7 @@ public interface ITsFilesService extends IService<TsFiles> {
|
||||
* 参数说明 type local还是minio
|
||||
* 返回值说明: com.yfd.platform.config.ResponseResult 返回批量删除成功或失败
|
||||
***********************************/
|
||||
String deleteTsFilesByIds(List<String> dataset, String type);
|
||||
String deleteTsFilesByIds(List<String> dataset, String type, String taskId);
|
||||
|
||||
/**********************************
|
||||
* 用途说明: 压缩文件夹接口
|
||||
@ -73,7 +73,7 @@ public interface ITsFilesService extends IService<TsFiles> {
|
||||
* 参数说明 path 根目录 /项目名/节点名称/
|
||||
* 返回值说明: com.yfd.platform.config.ResponseResult
|
||||
***********************************/
|
||||
String compressFolder(String ids, String compressedFormat, String compressedName, String compressedPath, String covered, String parentId,String path) throws FileNotFoundException;
|
||||
String compressFolder(String ids, String compressedFormat, String compressedName, String compressedPath, String covered, String parentId,String path,String taskId) throws FileNotFoundException;
|
||||
|
||||
/**********************************
|
||||
* 用途说明: 解压缩接口
|
||||
@ -83,7 +83,7 @@ public interface ITsFilesService extends IService<TsFiles> {
|
||||
* 参数说明 path 根目录 /项目名/节点名称/
|
||||
* 返回值说明: com.yfd.platform.config.ResponseResult
|
||||
***********************************/
|
||||
String decompressionFolder(String id, String decompressionPath, String parentId, String path);
|
||||
String decompressionFolder(String id, String decompressionPath, String parentId, String path,String taskId);
|
||||
|
||||
/**********************************
|
||||
* 用途说明: 将文件上传到备份空间
|
||||
@ -144,7 +144,7 @@ public interface ITsFilesService extends IService<TsFiles> {
|
||||
* 参数说明 token SSE连接的token
|
||||
* 返回值说明: com.yfd.platform.config.ResponseResult
|
||||
***********************************/
|
||||
void batchSendNaviOutDataJob(String id, int samTimes, String token);
|
||||
void batchSendNaviOutDataJob(String id, int samTimes, String token,String taskId);
|
||||
|
||||
/**
|
||||
* 查询文件内容接口
|
||||
@ -152,7 +152,7 @@ public interface ITsFilesService extends IService<TsFiles> {
|
||||
* @param id 文件的id
|
||||
* @return 文件内容的纯文本(UTF-8 编码)
|
||||
*/
|
||||
String readFileContent(String id) throws IOException;
|
||||
String readFileContent(String id,String taskId) throws IOException;
|
||||
|
||||
/**********************************
|
||||
* 用途说明: 保存文件内容接口
|
||||
@ -160,14 +160,14 @@ public interface ITsFilesService extends IService<TsFiles> {
|
||||
* 参数说明 content 新的文件内容(HTML/文本)
|
||||
* 返回值说明: com.yfd.platform.config.ResponseResult操作结果
|
||||
***********************************/
|
||||
void saveFileContent(String id, String content) throws IOException;
|
||||
void saveFileContent(String id, String content,String taskId) throws IOException;
|
||||
|
||||
/**********************************
|
||||
* 用途说明: 批量修改文件中多行多列的内容
|
||||
* 参数说明 request 要修改的文件信息
|
||||
* 返回值说明: com.yfd.platform.config.ResponseResult操作结果
|
||||
***********************************/
|
||||
void batchUpdateFile(String id, List<ModifyCommand> modifications) throws IOException;
|
||||
void batchUpdateFile(String id, List<ModifyCommand> modifications,String taskId) throws IOException;
|
||||
|
||||
/**********************************
|
||||
* 用途说明: 文件自动备份
|
||||
@ -198,7 +198,7 @@ public interface ITsFilesService extends IService<TsFiles> {
|
||||
* 参数说明 id 文件夹ID
|
||||
* 返回值说明: com.yfd.platform.config.ResponseResult 返回文件信息
|
||||
***********************************/
|
||||
FileItemResult obtainUrl(String id, String type);
|
||||
FileItemResult obtainUrl(String id, String type,String taskId);
|
||||
|
||||
/**********************************
|
||||
* 用途说明: 对比本地有minio没有的文件差异
|
||||
|
@ -64,4 +64,6 @@ public interface ITsTaskService extends IService<TsTask> {
|
||||
* 返回值说明: com.yfd.platform.config.ResponseResult 返回删除成功或者失败
|
||||
***********************************/
|
||||
Object confirmDeleteTask(List<String> dataset);
|
||||
|
||||
List<TsTask> listTsTask();
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -22,21 +22,27 @@ import com.yfd.platform.modules.experimentalData.mapper.TsTaskMapper;
|
||||
import com.yfd.platform.modules.experimentalData.service.ITsFilesService;
|
||||
import com.yfd.platform.modules.experimentalData.service.ITsNodesService;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.yfd.platform.modules.specialDocument.domain.Nodes;
|
||||
import com.yfd.platform.modules.storage.context.StorageSourceContext;
|
||||
import com.yfd.platform.modules.storage.mapper.StorageSourceConfigMapper;
|
||||
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.StorageSourceConfig;
|
||||
import com.yfd.platform.modules.storage.model.enums.FileTypeEnum;
|
||||
import com.yfd.platform.modules.storage.model.request.BatchDeleteRequest;
|
||||
import com.yfd.platform.modules.storage.model.request.NewFolderRequest;
|
||||
import com.yfd.platform.modules.storage.model.request.RenameFolderRequest;
|
||||
import com.yfd.platform.modules.storage.model.result.FileItemResult;
|
||||
import com.yfd.platform.modules.storage.service.StorageSourceService;
|
||||
import com.yfd.platform.modules.storage.service.base.AbstractBaseFileService;
|
||||
import com.yfd.platform.system.domain.LoginUser;
|
||||
import com.yfd.platform.utils.StringUtils;
|
||||
import com.yfd.platform.utils.TableNameContextHolder;
|
||||
import io.netty.channel.ChannelInboundHandlerAdapter;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
@ -93,6 +99,11 @@ public class TsNodesServiceImpl extends ServiceImpl<TsNodesMapper, TsNodes> impl
|
||||
@Resource
|
||||
private StorageSourceConfigMapper storageSourceConfigMapper;
|
||||
|
||||
@Resource
|
||||
private StorageSourceMapper storageSourceMapper;
|
||||
|
||||
@Autowired
|
||||
private RedisTemplate<String, Object> redisTemplate;
|
||||
|
||||
//顶级父节点 Top level parent node
|
||||
public static final String TOP_LEVEL_PARENT_NODE = "00";
|
||||
@ -289,76 +300,93 @@ public class TsNodesServiceImpl extends ServiceImpl<TsNodesMapper, TsNodes> impl
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class) // 添加事务注解,遇到异常时回滚
|
||||
public ResponseResult addTsNodes(TsNodes tsnodes) {
|
||||
|
||||
//查询文件表 如果有一样的名称不能新增
|
||||
List<TsFiles> tsFiles = tsFilesMapper.selectList(new QueryWrapper<TsFiles>()
|
||||
.eq("task_id", tsnodes.getTaskId())
|
||||
.eq("parent_id", "00")
|
||||
.eq("file_name", tsnodes.getNodeName())
|
||||
.eq("is_file", "FOLDER"));
|
||||
if (tsFiles.size() > 0) {
|
||||
return ResponseResult.error("数据管理中存在该文件夹!");
|
||||
}
|
||||
// 校验文件名是否包含非法字符
|
||||
String nodeName = tsnodes.getNodeName();
|
||||
if (containsInvalidCharacters(nodeName)) {
|
||||
return ResponseResult.error("文件名包含非法字符(<>:\"/\\|?*)!");
|
||||
}
|
||||
// 差不多的流程 就是提出来 然后判断 如果两个 中有一个是true
|
||||
//获取当前登录用户
|
||||
UsernamePasswordAuthenticationToken authentication =
|
||||
(UsernamePasswordAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
|
||||
LoginUser loginuser = (LoginUser) authentication.getPrincipal();
|
||||
//创建人是当前登录人
|
||||
tsnodes.setCreator(loginuser.getUsername());
|
||||
|
||||
//当前操作时间
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
// 转换为 Timestamp
|
||||
Timestamp currentTime = Timestamp.valueOf(now);
|
||||
tsnodes.setCreateTime(currentTime);
|
||||
|
||||
//通过获取上级节点的条数 设置节点顺序
|
||||
QueryWrapper<TsNodes> queryWrapperNodeOrder = new QueryWrapper<>();
|
||||
int orderno = this.count(queryWrapperNodeOrder.eq("parent_id", tsnodes.getParentId())) + 1;
|
||||
//判断节点名称是否存在
|
||||
QueryWrapper<TsNodes> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("node_name", tsnodes.getNodeName());//名称
|
||||
queryWrapper.eq("task_id", tsnodes.getTaskId());//所属任务ID
|
||||
queryWrapper.eq("parent_id", tsnodes.getParentId());//所属任务ID
|
||||
int count = tsNodesMapper.selectCount(queryWrapper);
|
||||
// 大于0说明 区域名称重复
|
||||
if (count > 0) {
|
||||
return ResponseResult.error("节点名称已存在!");
|
||||
}
|
||||
//序号
|
||||
tsnodes.setNodeOrder(orderno);
|
||||
// 初始化变量
|
||||
ResponseResult result = ResponseResult.error();
|
||||
|
||||
|
||||
int valueAdded = tsNodesMapper.insert(tsnodes);
|
||||
if (valueAdded == 1) {
|
||||
LOGGER.info("tsnodes表结构增加成功");
|
||||
try {
|
||||
TsTask tsTask = tsTaskMapper.selectById(tsnodes.getTaskId());
|
||||
TableNameContextHolder.setTaskCode(tsTask.getTaskCode());
|
||||
StorageSource storageSource = getStorageConfig(tsTask.getLocalStorageId());
|
||||
//查询文件表 如果有一样的名称不能新增
|
||||
List<TsFiles> tsFiles = tsFilesMapper.selectList(new QueryWrapper<TsFiles>()
|
||||
.eq("task_id", tsnodes.getTaskId())
|
||||
.eq("parent_id", "00")
|
||||
.eq("file_name", tsnodes.getNodeName())
|
||||
.eq("is_file", "FOLDER"));
|
||||
if (tsFiles.size() > 0) {
|
||||
return ResponseResult.error("数据管理中存在该文件夹!");
|
||||
}
|
||||
// 校验文件名是否包含非法字符
|
||||
String nodeName = tsnodes.getNodeName();
|
||||
if (containsInvalidCharacters(nodeName)) {
|
||||
return ResponseResult.error("文件名包含非法字符(<>:\"/\\|?*)!");
|
||||
}
|
||||
// 差不多的流程 就是提出来 然后判断 如果两个 中有一个是true
|
||||
//获取当前登录用户
|
||||
UsernamePasswordAuthenticationToken authentication =
|
||||
(UsernamePasswordAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
|
||||
LoginUser loginuser = (LoginUser) authentication.getPrincipal();
|
||||
//创建人是当前登录人
|
||||
tsnodes.setCreator(loginuser.getUsername());
|
||||
|
||||
//当前操作时间
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
// 转换为 Timestamp
|
||||
Timestamp currentTime = Timestamp.valueOf(now);
|
||||
tsnodes.setCreateTime(currentTime);
|
||||
|
||||
//通过获取上级节点的条数 设置节点顺序
|
||||
QueryWrapper<TsNodes> queryWrapperNodeOrder = new QueryWrapper<>();
|
||||
int orderno = this.count(queryWrapperNodeOrder.eq("parent_id", tsnodes.getParentId())) + 1;
|
||||
//判断节点名称是否存在
|
||||
QueryWrapper<TsNodes> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("node_name", tsnodes.getNodeName());//名称
|
||||
queryWrapper.eq("task_id", tsnodes.getTaskId());//所属任务ID
|
||||
queryWrapper.eq("parent_id", tsnodes.getParentId());//所属任务ID
|
||||
int count = tsNodesMapper.selectCount(queryWrapper);
|
||||
// 大于0说明 区域名称重复
|
||||
if (count > 0) {
|
||||
return ResponseResult.error("节点名称已存在!");
|
||||
}
|
||||
//序号
|
||||
tsnodes.setNodeOrder(orderno);
|
||||
|
||||
|
||||
//新增节点的时候 创建文件夹
|
||||
NewFolderRequest newFolderRequest = new NewFolderRequest();
|
||||
newFolderRequest.setName(tsnodes.getNodeName());//新建的文件夹名称,示例值(/a/b/c)
|
||||
newFolderRequest.setPassword("");//文件夹密码, 如果文件夹需要密码才能访问,则支持请求密码,示例值(123456)
|
||||
newFolderRequest.setPath(tsnodes.getPath());//请求路径,示例值(/)
|
||||
newFolderRequest.setStorageKey("local");//存储源 key,示例值(local minio sdlocal)
|
||||
AbstractBaseFileService<?> fileService = storageSourceContext.getByStorageKey(newFolderRequest.getStorageKey());
|
||||
boolean flag = fileService.newFolder(newFolderRequest.getPath(), newFolderRequest.getName());
|
||||
if (flag) {
|
||||
return ResponseResult.success();
|
||||
int valueAdded = tsNodesMapper.insert(tsnodes);
|
||||
if (valueAdded == 1) {
|
||||
LOGGER.info("tsnodes表结构增加成功");
|
||||
|
||||
|
||||
//新增节点的时候 创建文件夹
|
||||
NewFolderRequest newFolderRequest = new NewFolderRequest();
|
||||
newFolderRequest.setName(tsnodes.getNodeName());//新建的文件夹名称,示例值(/a/b/c)
|
||||
newFolderRequest.setPassword("");//文件夹密码, 如果文件夹需要密码才能访问,则支持请求密码,示例值(123456)
|
||||
newFolderRequest.setPath(tsnodes.getPath());//请求路径,示例值(/)
|
||||
newFolderRequest.setStorageKey(storageSource.getKey());//存储源 key,示例值(local minio sdlocal)
|
||||
AbstractBaseFileService<?> fileService = storageSourceContext.getByStorageKey(newFolderRequest.getStorageKey());
|
||||
boolean flag = fileService.newFolder(newFolderRequest.getPath(), newFolderRequest.getName());
|
||||
if (flag) {
|
||||
result = ResponseResult.success();
|
||||
} else {
|
||||
LOGGER.error("节点新增成功,但是local创建文件失败");
|
||||
result = ResponseResult.error("物理文件夹创建失败");
|
||||
}
|
||||
return result;
|
||||
} else {
|
||||
LOGGER.error("节点新增成功,但是local创建文件失败");
|
||||
LOGGER.error("tsnodes表结构增加失败");
|
||||
return ResponseResult.error();
|
||||
}
|
||||
} else {
|
||||
LOGGER.error("tsnodes表结构增加失败");
|
||||
return ResponseResult.error();
|
||||
} catch (Exception e) {
|
||||
// 异常处理
|
||||
LOGGER.error("添加节点时发生异常: {}", e.getMessage(), e);
|
||||
return ResponseResult.error("系统错误: " + e.getMessage());
|
||||
} finally {
|
||||
TableNameContextHolder.clear();
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -380,45 +408,99 @@ public class TsNodesServiceImpl extends ServiceImpl<TsNodesMapper, TsNodes> impl
|
||||
@Override
|
||||
public ResponseResult updateTsNodes(TsNodes tsnodes) {
|
||||
|
||||
// 校验文件名是否包含非法字符
|
||||
String nodeName = tsnodes.getNodeName();
|
||||
if (containsInvalidCharacters(nodeName)) {
|
||||
return ResponseResult.error("文件名包含非法字符(<>:\"/\\|?*)!");
|
||||
}
|
||||
|
||||
//查询没改之前的节点名称
|
||||
TsNodes nodesold = tsNodesMapper.selectById(tsnodes.getNodeId());
|
||||
try {
|
||||
TsTask tsTask = tsTaskMapper.selectById(tsnodes.getTaskId());
|
||||
TableNameContextHolder.setTaskCode(tsTask.getTaskCode());
|
||||
StorageSource storageSource = getStorageConfig(tsTask.getLocalStorageId());
|
||||
|
||||
//老的节点名称
|
||||
String nodeNameOld = null;
|
||||
if (ObjUtil.isNotEmpty(nodesold)) {
|
||||
nodeNameOld = nodesold.getNodeName();
|
||||
}
|
||||
// 校验文件名是否包含非法字符
|
||||
String nodeName = tsnodes.getNodeName();
|
||||
if (containsInvalidCharacters(nodeName)) {
|
||||
return ResponseResult.error("文件名包含非法字符(<>:\"/\\|?*)!");
|
||||
}
|
||||
|
||||
//获取当前登录用户
|
||||
UsernamePasswordAuthenticationToken authentication =
|
||||
(UsernamePasswordAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
|
||||
LoginUser loginuser = (LoginUser) authentication.getPrincipal();
|
||||
//创建人是当前登录人
|
||||
tsnodes.setCreator(loginuser.getUsername());
|
||||
// 查询旧节点名称
|
||||
TsNodes nodesold = tsNodesMapper.selectById(tsnodes.getNodeId());
|
||||
String nodeNameOld = ObjUtil.isNotEmpty(nodesold) ? nodesold.getNodeName() : null;
|
||||
|
||||
//判断节点名称是否存在
|
||||
QueryWrapper<TsNodes> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("node_name", tsnodes.getNodeName());//名称
|
||||
queryWrapper.eq("task_id", tsnodes.getTaskId());//所属任务ID
|
||||
queryWrapper.eq("parent_id", tsnodes.getParentId());//所属任务ID
|
||||
int count = tsNodesMapper.selectCount(queryWrapper);
|
||||
// 大于0说明 区域名称重复
|
||||
if (count > 0) {
|
||||
return ResponseResult.error("节点名称已存在!");
|
||||
}
|
||||
int valueAdded = tsNodesMapper.updateById(tsnodes);
|
||||
if (valueAdded == 1) {
|
||||
LOGGER.info("tsnodes表结构修改成功");
|
||||
return ResponseResult.success();
|
||||
} else {
|
||||
LOGGER.error("tsnodes表结构修改失败");
|
||||
return ResponseResult.error();
|
||||
// 获取当前登录用户
|
||||
UsernamePasswordAuthenticationToken authentication =
|
||||
(UsernamePasswordAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
|
||||
LoginUser loginuser = (LoginUser) authentication.getPrincipal();
|
||||
|
||||
// 设置创建人
|
||||
tsnodes.setCreator(loginuser.getUsername());
|
||||
|
||||
// 判断节点名称是否存在
|
||||
QueryWrapper<TsNodes> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("node_name", tsnodes.getNodeName())
|
||||
.eq("task_id", tsnodes.getTaskId())
|
||||
.eq("parent_id", tsnodes.getParentId());
|
||||
int count = tsNodesMapper.selectCount(queryWrapper);
|
||||
|
||||
if (count > 0) {
|
||||
return ResponseResult.error("节点名称已存在!");
|
||||
}
|
||||
|
||||
// 更新节点信息
|
||||
int valueAdded = tsNodesMapper.updateById(tsnodes);
|
||||
|
||||
// 2. 构建新旧路径
|
||||
String oldBasePath = tsnodes.getPath() + nodeNameOld + "/";
|
||||
String newBasePath = tsnodes.getPath() + nodeName + "/";
|
||||
|
||||
|
||||
//4.更新文件表ts_files表 根据所属项目ID 老路径 和新路径
|
||||
tsFilesMapper.updateTsFileByPath(tsnodes.getTaskId(), oldBasePath, newBasePath);
|
||||
|
||||
//获取项目下面的所有子节点 都清除缓存
|
||||
List<TsNodes> nodesList = tsNodesMapper.selectList(new QueryWrapper<TsNodes>().eq("task_id", tsnodes.getTaskId()));
|
||||
if ((nodesList != null) && (nodesList.size() > 0)) {
|
||||
for (TsNodes node : nodesList) {
|
||||
//todo 修改节点成功以后 删除redis
|
||||
for (int page = 1; page <= 5; page++) {
|
||||
String redisKey = "tsfiles_" + node.getTaskId() + "_" + node.getNodeId() + "_parentId" + node.getParentId() + "_page_" + page;
|
||||
redisTemplate.delete(redisKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//判断如果更新了节点名称
|
||||
if (!nodeName.equals(nodeNameOld)) {
|
||||
if (valueAdded == 1) {
|
||||
//修改文件名称
|
||||
RenameFolderRequest renameFolderRequest = new RenameFolderRequest();
|
||||
renameFolderRequest.setName(nodeNameOld);//重命名的原文件夹名称,示例值(movie)
|
||||
renameFolderRequest.setNewName(nodeName);// 重命名后的文件名称,示例值(music)
|
||||
renameFolderRequest.setPassword("");//文件夹密码, 如果文件夹需要密码才能访问,则支持请求密码,示例值(123456)
|
||||
renameFolderRequest.setPath(tsnodes.getPath());//请求路径,示例值(/)
|
||||
renameFolderRequest.setStorageKey(storageSource.getKey());//存储源 key,示例值(local minio sdlocal)
|
||||
AbstractBaseFileService<?> fileService = storageSourceContext.getByStorageKey(renameFolderRequest.getStorageKey());
|
||||
boolean flag = fileService.renameFolder(renameFolderRequest.getPath(), renameFolderRequest.getName(), renameFolderRequest.getNewName());
|
||||
if (flag) {
|
||||
return ResponseResult.success("重命名成功");
|
||||
} else {
|
||||
LOGGER.error("节点修改成功,但是本地修改文件名失败");
|
||||
return ResponseResult.error("重命名失败");
|
||||
}
|
||||
} else {
|
||||
LOGGER.error("节点修改失败");
|
||||
return ResponseResult.error();
|
||||
}
|
||||
|
||||
} else {
|
||||
if (valueAdded == 1) {
|
||||
return ResponseResult.success("重命名成功");
|
||||
} else {
|
||||
return ResponseResult.error("重命名失败");
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("更新试验任务节点时发生异常: {}", e.getMessage(), e);
|
||||
return ResponseResult.error("系统错误,请稍后重试");
|
||||
} finally {
|
||||
TableNameContextHolder.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@ -430,80 +512,92 @@ public class TsNodesServiceImpl extends ServiceImpl<TsNodesMapper, TsNodes> impl
|
||||
***********************************/
|
||||
@Override
|
||||
public boolean deleteTsNodesById(String id, String path) {
|
||||
//根据ID 查询当前数据
|
||||
TsNodes tsNodes = tsNodesMapper.selectById(id);
|
||||
//删除之前 先拼路径 然后删除本地和minio的文件夹 最后删除表结构
|
||||
//查询所有的子节点
|
||||
List<TsNodes> tsNodesList = selectChildrentsNodes(tsNodes.getNodeId(), tsNodes.getTaskId());
|
||||
// 提取所有节点的 ID
|
||||
List<String> nodeIds = tsNodesList.stream()
|
||||
.map(TsNodes::getNodeId) // 获取每个节点的 ID
|
||||
.collect(Collectors.toList());
|
||||
//修改项目ID 和所有节点id的workPath字段为空
|
||||
if (CollectionUtils.isNotEmpty(nodeIds)) {
|
||||
// 4. 批量更新:将这些节点的文件工作路径置空
|
||||
LambdaUpdateWrapper<TsFiles> updateWrapper1 = new LambdaUpdateWrapper<>();
|
||||
updateWrapper1.in(TsFiles::getNodeId, nodeIds).eq(TsFiles::getTaskId, tsNodes.getTaskId()).set(TsFiles::getWorkPath, "");
|
||||
tsFilesMapper.update(null, updateWrapper1);
|
||||
try {
|
||||
//根据ID 查询当前数据
|
||||
TsNodes tsNodes = tsNodesMapper.selectById(id);
|
||||
TsTask tsTask = tsTaskMapper.selectById(tsNodes.getTaskId());
|
||||
TableNameContextHolder.setTaskCode(tsTask.getTaskCode());
|
||||
StorageSource storageSource = getStorageConfig(tsTask.getLocalStorageId());
|
||||
//删除之前 先拼路径 然后删除本地和minio的文件夹 最后删除表结构
|
||||
//查询所有的子节点
|
||||
List<TsNodes> tsNodesList = selectChildrentsNodes(tsNodes.getNodeId(), tsNodes.getTaskId());
|
||||
// 提取所有节点的 ID
|
||||
List<String> nodeIds = tsNodesList.stream()
|
||||
.map(TsNodes::getNodeId) // 获取每个节点的 ID
|
||||
.collect(Collectors.toList());
|
||||
//修改项目ID 和所有节点id的workPath字段为空
|
||||
if (CollectionUtils.isNotEmpty(nodeIds)) {
|
||||
// 4. 批量更新:将这些节点的文件工作路径置空
|
||||
LambdaUpdateWrapper<TsFiles> updateWrapper1 = new LambdaUpdateWrapper<>();
|
||||
updateWrapper1.in(TsFiles::getNodeId, nodeIds).eq(TsFiles::getTaskId, tsNodes.getTaskId()).set(TsFiles::getWorkPath, "");
|
||||
tsFilesMapper.update(null, updateWrapper1);
|
||||
|
||||
|
||||
// 5. 删除符合条件的文件记录
|
||||
LambdaQueryWrapper<TsFiles> deleteWrapper = new LambdaQueryWrapper<>();
|
||||
deleteWrapper.in(TsFiles::getNodeId, nodeIds)
|
||||
.eq(TsFiles::getTaskId, tsNodes.getTaskId())
|
||||
.and(wrapper -> wrapper.isNull(TsFiles::getBackupPath).or().eq(TsFiles::getBackupPath, ""))
|
||||
.and(wrapper -> wrapper.isNull(TsFiles::getWorkPath).or().eq(TsFiles::getWorkPath, ""));
|
||||
tsFilesMapper.delete(deleteWrapper);
|
||||
}
|
||||
// 5. 删除符合条件的文件记录
|
||||
LambdaQueryWrapper<TsFiles> deleteWrapper = new LambdaQueryWrapper<>();
|
||||
deleteWrapper.in(TsFiles::getNodeId, nodeIds)
|
||||
.eq(TsFiles::getTaskId, tsNodes.getTaskId())
|
||||
.and(wrapper -> wrapper.isNull(TsFiles::getBackupPath).or().eq(TsFiles::getBackupPath, ""))
|
||||
.and(wrapper -> wrapper.isNull(TsFiles::getWorkPath).or().eq(TsFiles::getWorkPath, ""));
|
||||
tsFilesMapper.delete(deleteWrapper);
|
||||
}
|
||||
|
||||
//删除当前节点的文件夹 todo 这个地方改动
|
||||
// 删除 sdlocal 中的文件夹
|
||||
List<BatchDeleteRequest.DeleteItem> deleteItemList = new ArrayList<>();
|
||||
BatchDeleteRequest.DeleteItem deleteItemData = new BatchDeleteRequest.DeleteItem();
|
||||
deleteItemData.setName(tsNodes.getNodeName());
|
||||
deleteItemData.setPassword("");
|
||||
deleteItemData.setPath(path);
|
||||
deleteItemData.setType(FileTypeEnum.FOLDER);
|
||||
deleteItemList.add(deleteItemData);
|
||||
//删除当前节点的文件夹 todo 这个地方改动
|
||||
// 删除 sdlocal 中的文件夹
|
||||
List<BatchDeleteRequest.DeleteItem> deleteItemList = new ArrayList<>();
|
||||
BatchDeleteRequest.DeleteItem deleteItemData = new BatchDeleteRequest.DeleteItem();
|
||||
deleteItemData.setName(tsNodes.getNodeName());
|
||||
deleteItemData.setPassword("");
|
||||
deleteItemData.setPath(path);
|
||||
deleteItemData.setType(FileTypeEnum.FOLDER);
|
||||
deleteItemList.add(deleteItemData);
|
||||
|
||||
BatchDeleteRequest batchDeleteRequest = new BatchDeleteRequest();
|
||||
batchDeleteRequest.setDeleteItems(deleteItemList);
|
||||
batchDeleteRequest.setStorageKey("local");
|
||||
AbstractBaseFileService<?> fileService = storageSourceContext.getByStorageKey(batchDeleteRequest.getStorageKey());
|
||||
BatchDeleteRequest batchDeleteRequest = new BatchDeleteRequest();
|
||||
batchDeleteRequest.setDeleteItems(deleteItemList);
|
||||
batchDeleteRequest.setStorageKey(storageSource.getKey());
|
||||
AbstractBaseFileService<?> fileService = storageSourceContext.getByStorageKey(batchDeleteRequest.getStorageKey());
|
||||
|
||||
int deleteSuccessCount = 0, deleteFailCount = 0, totalCount = CollUtil.size(deleteItemList);
|
||||
for (BatchDeleteRequest.DeleteItem deleteItem : deleteItemList) {
|
||||
boolean flag = false;
|
||||
try {
|
||||
if (deleteItem.getType() == FileTypeEnum.FILE) {
|
||||
flag = fileService.deleteFile(deleteItem.getPath(), deleteItem.getName());
|
||||
} else if (deleteItem.getType() == FileTypeEnum.FOLDER) {
|
||||
flag = fileService.deleteFolder(deleteItem.getPath(), deleteItem.getName());
|
||||
}
|
||||
int deleteSuccessCount = 0, deleteFailCount = 0, totalCount = CollUtil.size(deleteItemList);
|
||||
for (BatchDeleteRequest.DeleteItem deleteItem : deleteItemList) {
|
||||
boolean flag = false;
|
||||
try {
|
||||
if (deleteItem.getType() == FileTypeEnum.FILE) {
|
||||
flag = fileService.deleteFile(deleteItem.getPath(), deleteItem.getName());
|
||||
} else if (deleteItem.getType() == FileTypeEnum.FOLDER) {
|
||||
flag = fileService.deleteFolder(deleteItem.getPath(), deleteItem.getName());
|
||||
}
|
||||
|
||||
if (flag) {
|
||||
deleteSuccessCount++;
|
||||
} else {
|
||||
if (flag) {
|
||||
deleteSuccessCount++;
|
||||
} else {
|
||||
deleteFailCount++;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("删除文件/文件夹失败, 文件路径: {}, 文件名称: {}", deleteItem.getPath(), deleteItem.getName(), e);
|
||||
deleteFailCount++;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("删除文件/文件夹失败, 文件路径: {}, 文件名称: {}", deleteItem.getPath(), deleteItem.getName(), e);
|
||||
deleteFailCount++;
|
||||
}
|
||||
}
|
||||
if (deleteSuccessCount >= 1) {
|
||||
// 删除当前节点
|
||||
int deleteCount = tsNodesMapper.deleteBatchIds(nodeIds);
|
||||
if (deleteCount >= 1) {
|
||||
LOGGER.info("tsnodes表结删除改成功");
|
||||
return true;
|
||||
if (deleteSuccessCount >= 1) {
|
||||
// 删除当前节点
|
||||
int deleteCount = tsNodesMapper.deleteBatchIds(nodeIds);
|
||||
if (deleteCount >= 1) {
|
||||
LOGGER.info("tsnodes表结删除改成功");
|
||||
return true;
|
||||
} else {
|
||||
LOGGER.error("tsnodes表结构删除失败");
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
LOGGER.error("tsnodes表结构删除失败");
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("删除试验任务节点时发生异常: {}", e.getMessage(), e);
|
||||
return false;
|
||||
} finally {
|
||||
TableNameContextHolder.clear();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private List<TsNodes> selectChildrentsNodes(String parentId, String taskId) {
|
||||
@ -559,7 +653,7 @@ public class TsNodesServiceImpl extends ServiceImpl<TsNodesMapper, TsNodes> impl
|
||||
}
|
||||
//批量删除TsFiles表数据
|
||||
if (dataset.size() > 0) {
|
||||
tsFilesService.deleteTsFilesByIds(dataset, "local");
|
||||
tsFilesService.deleteTsFilesByIds(dataset, "local", taskId);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -580,6 +674,9 @@ public class TsNodesServiceImpl extends ServiceImpl<TsNodesMapper, TsNodes> impl
|
||||
if (tsNodesList.size() == 0) {
|
||||
return true;
|
||||
}
|
||||
TsTask tsTask = tsTaskMapper.selectById(taskId);
|
||||
StorageSource storageSource = getStorageConfig(tsTask.getLocalStorageId());
|
||||
|
||||
|
||||
for (TsNodes tsNodes : tsNodesList) {
|
||||
//删除文件表
|
||||
@ -595,7 +692,7 @@ public class TsNodesServiceImpl extends ServiceImpl<TsNodesMapper, TsNodes> impl
|
||||
|
||||
BatchDeleteRequest batchDeleteRequest = new BatchDeleteRequest();
|
||||
batchDeleteRequest.setDeleteItems(deleteItemList);
|
||||
batchDeleteRequest.setStorageKey("local");
|
||||
batchDeleteRequest.setStorageKey(storageSource.getKey());
|
||||
AbstractBaseFileService<?> fileService = storageSourceContext.getByStorageKey(batchDeleteRequest.getStorageKey());
|
||||
|
||||
int deleteSuccessCount = 0, deleteFailCount = 0, totalCount = CollUtil.size(deleteItemList);
|
||||
@ -643,10 +740,10 @@ public class TsNodesServiceImpl extends ServiceImpl<TsNodesMapper, TsNodes> impl
|
||||
***********************************/
|
||||
@Override
|
||||
@Async("asyncExecutor")
|
||||
public void testDataScanByIdAsync(String id,LoginUser loginuser) throws Exception {
|
||||
public void testDataScanByIdAsync(String id, LoginUser loginuser) throws Exception {
|
||||
try {
|
||||
// 执行扫描并且插入数据库
|
||||
this.testDataScanById(id,loginuser);
|
||||
this.testDataScanById(id, loginuser);
|
||||
} finally {
|
||||
// 生成唯一Key
|
||||
String asyncKey = taskStatusHolder.testDatascanKey(id);
|
||||
@ -663,48 +760,64 @@ public class TsNodesServiceImpl extends ServiceImpl<TsNodesMapper, TsNodes> impl
|
||||
***********************************/
|
||||
@Override
|
||||
public Object confirmDeleteNodes(String id) {
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
TsNodes tsNodes = tsNodesMapper.selectById(id);
|
||||
if (tsNodes == null) {
|
||||
jsonObject.putOpt("status", "1");
|
||||
try {
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
TsNodes tsNodes = tsNodesMapper.selectById(id);
|
||||
TsTask tsTask = tsTaskMapper.selectById(tsNodes.getTaskId());
|
||||
TableNameContextHolder.setTaskCode(tsTask.getTaskCode());
|
||||
if (tsNodes == null) {
|
||||
jsonObject.putOpt("status", "1");
|
||||
return ResponseResult.successData(jsonObject);
|
||||
}
|
||||
//SQL通过节点ID 递归查询节点下面的所有子节点 以及files表中 backup_path IS NOT NULL
|
||||
int count = tsFilesService.countFiles(id);
|
||||
//如果大于0不让删
|
||||
if (count > 0) {
|
||||
jsonObject.putOpt("status", "0");
|
||||
} else {
|
||||
jsonObject.putOpt("status", "1");
|
||||
}
|
||||
return ResponseResult.successData(jsonObject);
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("检查节点是否允许删除时发生异常: {}", e.getMessage(), e);
|
||||
return ResponseResult.error("系统错误,请稍后重试");
|
||||
} finally {
|
||||
TableNameContextHolder.clear();
|
||||
}
|
||||
//SQL通过节点ID 递归查询节点下面的所有子节点 以及files表中 backup_path IS NOT NULL
|
||||
int count = tsFilesService.countFiles(id);
|
||||
//如果大于0不让删
|
||||
if (count > 0) {
|
||||
jsonObject.putOpt("status", "0");
|
||||
} else {
|
||||
jsonObject.putOpt("status", "1");
|
||||
}
|
||||
return ResponseResult.successData(jsonObject);
|
||||
}
|
||||
|
||||
private String testDataScanById(String id,LoginUser loginuser) throws Exception {
|
||||
private String testDataScanById(String id, LoginUser loginuser) throws Exception {
|
||||
try {
|
||||
//查询试验任务信息
|
||||
TsTask tsTask = tsTaskMapper.selectById(id);
|
||||
TableNameContextHolder.setTaskCode(tsTask.getTaskCode());
|
||||
//文件的第一层是节点 下面的层级是文件夹
|
||||
//获取文件列表
|
||||
String absolutePath = "/" + tsTask.getTaskName() + "/";
|
||||
FileListRequest fileListRequest = buildFileRequest(absolutePath, tsTask);
|
||||
String storageKey = fileListRequest.getStorageKey();
|
||||
Integer storageId = storageSourceService.findIdByKey(storageKey);
|
||||
if (storageId == null) {
|
||||
throw new InvalidStorageSourceException("通过存储源 key 未找到存储源, key: " + storageKey);
|
||||
}
|
||||
// 处理请求参数默认值
|
||||
fileListRequest.handleDefaultValue();
|
||||
AbstractBaseFileService<?> fileService = storageSourceContext.getByStorageId(storageId);
|
||||
//todo 首先获取两个集合 对比出数据库中没有的文件夹以及文件,递归增加
|
||||
List<FileItemResult> fileItemList = fileService.fileList(fileListRequest.getPath());
|
||||
|
||||
//查询试验任务信息
|
||||
TsTask tsTask = tsTaskMapper.selectById(id);
|
||||
//文件的第一层是节点 下面的层级是文件夹
|
||||
//获取文件列表
|
||||
String absolutePath = "/" + tsTask.getTaskName() + "/";
|
||||
FileListRequest fileListRequest = buildFileRequest(absolutePath);
|
||||
String storageKey = fileListRequest.getStorageKey();
|
||||
Integer storageId = storageSourceService.findIdByKey(storageKey);
|
||||
if (storageId == null) {
|
||||
throw new InvalidStorageSourceException("通过存储源 key 未找到存储源, key: " + storageKey);
|
||||
if (fileItemList.size() == 0) {
|
||||
throw new Exception("该试验任务管理项目目录不存在或没有项目文档,请先建立项目目录和文档。");
|
||||
}
|
||||
firstLayerData(fileItemList, id, loginuser);
|
||||
|
||||
return "扫描完成";
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("执行试验数据扫描时发生未知异常: {}", e.getMessage(), e);
|
||||
return "扫描失败:" + e.getMessage();
|
||||
} finally {
|
||||
TableNameContextHolder.clear();
|
||||
}
|
||||
// 处理请求参数默认值
|
||||
fileListRequest.handleDefaultValue();
|
||||
AbstractBaseFileService<?> fileService = storageSourceContext.getByStorageId(storageId);
|
||||
//todo 首先获取两个集合 对比出数据库中没有的文件夹以及文件,递归增加
|
||||
List<FileItemResult> fileItemList = fileService.fileList(fileListRequest.getPath());
|
||||
|
||||
if (fileItemList.size() == 0) {
|
||||
throw new Exception("该试验任务管理项目目录不存在或没有项目文档,请先建立项目目录和文档。");
|
||||
}
|
||||
firstLayerData(fileItemList, id, loginuser);
|
||||
|
||||
return "扫描完成";
|
||||
}
|
||||
|
||||
/**
|
||||
@ -714,8 +827,11 @@ public class TsNodesServiceImpl extends ServiceImpl<TsNodesMapper, TsNodes> impl
|
||||
* @param taskId 所属任务ID
|
||||
* @throws Exception
|
||||
*/
|
||||
public void firstLayerData(List<FileItemResult> fileItemList, String taskId,LoginUser loginuser) throws Exception {
|
||||
|
||||
public void firstLayerData(List<FileItemResult> fileItemList, String taskId, LoginUser loginuser) throws Exception {
|
||||
// 设置当前时间
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
// 转换为 Timestamp
|
||||
Timestamp currentTime = Timestamp.valueOf(now);
|
||||
for (FileItemResult item : fileItemList) {
|
||||
//思路就是 如果是文件夹 就查询一下 没有就新增, 新的的时候递归往下走
|
||||
if (item.getType() == FileTypeEnum.FOLDER) {
|
||||
@ -730,9 +846,83 @@ public class TsNodesServiceImpl extends ServiceImpl<TsNodesMapper, TsNodes> impl
|
||||
TsNodes node = savetsNodes(taskId, TOP_LEVEL_PARENT_NODE, item.getName());
|
||||
otherLevelsData(taskId, node.getNodeId(), item.getName(), item.getPath(), TOP_LEVEL_PARENT_NODE, loginuser);
|
||||
} else {
|
||||
otherLevelsData(taskId, nodeData.getNodeId(), item.getName(), item.getPath(), TOP_LEVEL_PARENT_NODE, loginuser);
|
||||
//otherLevelsData(taskId, nodeData.getNodeId(), item.getName(), item.getPath(), TOP_LEVEL_PARENT_NODE, loginuser);
|
||||
continue;
|
||||
}
|
||||
|
||||
} else {
|
||||
//todo 如果是文件 首先判断表中有没有 如果没有 就新增 到节点名称为根节点的 节点下面
|
||||
|
||||
//查询节点表中 有没有根节点的节点 如果有就直接使用 如果没有就新增
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -745,7 +935,7 @@ public class TsNodesServiceImpl extends ServiceImpl<TsNodesMapper, TsNodes> impl
|
||||
* @param parentId 父级ID
|
||||
* @return
|
||||
*/
|
||||
private void otherLevelsData(String taskId, String nodeId, String nodeName, String path, String parentId,LoginUser loginuser) throws Exception {
|
||||
private void otherLevelsData(String taskId, String nodeId, String nodeName, String path, String parentId, LoginUser loginuser) throws Exception {
|
||||
|
||||
// 存储所有目录和文件的列表
|
||||
List<TsFiles> tsFilesToCreate = new ArrayList<>();
|
||||
@ -757,6 +947,7 @@ public class TsNodesServiceImpl extends ServiceImpl<TsNodesMapper, TsNodes> impl
|
||||
// 查询本地文件路径根目录(如 E:\yun)
|
||||
QueryWrapper<StorageSourceConfig> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("name", "filePath");
|
||||
queryWrapper.eq("storage_id", "1");
|
||||
queryWrapper.eq("type", "local");
|
||||
StorageSourceConfig storageSourceConfig = storageSourceConfigMapper.selectOne(queryWrapper);
|
||||
//获取文件列表 这个地方path+name
|
||||
@ -984,15 +1175,21 @@ public class TsNodesServiceImpl extends ServiceImpl<TsNodesMapper, TsNodes> impl
|
||||
return node;
|
||||
}
|
||||
|
||||
private FileListRequest buildFileRequest(String path) {
|
||||
private FileListRequest buildFileRequest(String path, TsTask tsTask) {
|
||||
StorageSource storageSource = getStorageConfig(tsTask.getLocalStorageId());
|
||||
FileListRequest fileListRequest = new FileListRequest();
|
||||
fileListRequest.setOrderBy("time");
|
||||
fileListRequest.setOrderDirection("desc");
|
||||
fileListRequest.setPassword("");
|
||||
fileListRequest.setPath(path);
|
||||
fileListRequest.setStorageKey("local");
|
||||
fileListRequest.setStorageKey(storageSource.getKey());
|
||||
|
||||
return fileListRequest;
|
||||
}
|
||||
|
||||
// 辅助方法:获取存储配置
|
||||
private StorageSource getStorageConfig(Integer id) {
|
||||
return storageSourceMapper.selectOne(new LambdaQueryWrapper<StorageSource>().eq(StorageSource::getId, id)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -18,13 +18,16 @@ import com.yfd.platform.modules.experimentalData.service.ITsFilesService;
|
||||
import com.yfd.platform.modules.experimentalData.service.ITsNodesService;
|
||||
import com.yfd.platform.modules.experimentalData.service.ITsTaskService;
|
||||
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.mapper.StorageSourceMapper;
|
||||
import com.yfd.platform.modules.storage.model.entity.StorageSource;
|
||||
import com.yfd.platform.modules.storage.model.entity.StorageSourceConfig;
|
||||
import com.yfd.platform.modules.storage.model.enums.FileTypeEnum;
|
||||
import com.yfd.platform.modules.storage.model.request.BatchDeleteRequest;
|
||||
import com.yfd.platform.modules.storage.model.request.NewFolderRequest;
|
||||
import com.yfd.platform.modules.storage.service.base.AbstractBaseFileService;
|
||||
import com.yfd.platform.utils.StringUtils;
|
||||
import com.yfd.platform.utils.TableNameContextHolder;
|
||||
import io.netty.channel.ChannelInboundHandlerAdapter;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@ -32,12 +35,17 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.sql.Timestamp;
|
||||
import java.time.LocalDateTime;
|
||||
import java.sql.*;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.sql.DataSource;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 试验任务表 服务实现类
|
||||
@ -72,6 +80,11 @@ public class TsTaskServiceImpl extends ServiceImpl<TsTaskMapper, TsTask> impleme
|
||||
@Resource
|
||||
private StorageSourceContext storageSourceContext;
|
||||
|
||||
@Resource
|
||||
private StorageSourceMapper storageSourceMapper;
|
||||
|
||||
@Autowired
|
||||
private DataSource dataSource;
|
||||
|
||||
private static final String INITIAL_CODE = "00001";
|
||||
private static final int MAX_CODE_VALUE = 99999;
|
||||
@ -169,15 +182,15 @@ public class TsTaskServiceImpl extends ServiceImpl<TsTaskMapper, TsTask> impleme
|
||||
//生成任务名称 任务开始时间_结束时间_地点_载机名称_设备代号_编号
|
||||
String taskName = buildTaskName(tsTask);
|
||||
tsTask.setTaskName(taskName);
|
||||
|
||||
|
||||
LambdaQueryWrapper<TsTask> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(TsTask::getTaskName,tsTask.getTaskName());
|
||||
queryWrapper.eq(TsTask::getTaskName, tsTask.getTaskName());
|
||||
TsTask tsTask1 = tsTaskMapper.selectOne(queryWrapper);
|
||||
if (tsTask1 != null){
|
||||
if (tsTask1 != null) {
|
||||
throw new RuntimeException("试验任务管理项目已存在!");
|
||||
}
|
||||
|
||||
StorageSource storageSource = getStorageConfig(tsTask.getLocalStorageId());
|
||||
|
||||
// 设置当前时间
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
// 转换为 Timestamp
|
||||
@ -193,10 +206,12 @@ public class TsTaskServiceImpl extends ServiceImpl<TsTaskMapper, TsTask> impleme
|
||||
newFolderRequest.setName(tsTask.getTaskName());//新建的文件夹名称,示例值(/a/b/c)
|
||||
newFolderRequest.setPassword("");//文件夹密码, 如果文件夹需要密码才能访问,则支持请求密码,示例值(123456)
|
||||
newFolderRequest.setPath(path);//请求路径,示例值(/)
|
||||
newFolderRequest.setStorageKey("local");//存储源 key,示例值(local minio)
|
||||
newFolderRequest.setStorageKey(storageSource.getKey());//存储源 key,示例值(local minio)
|
||||
AbstractBaseFileService<?> fileService = storageSourceContext.getByStorageKey(newFolderRequest.getStorageKey());
|
||||
boolean flag = fileService.newFolder(newFolderRequest.getPath(), newFolderRequest.getName());
|
||||
if (flag) {
|
||||
// 动态创建数据表
|
||||
createTaskFileTable(taskCode);
|
||||
return true;
|
||||
} else {
|
||||
LOGGER.error("试验任务增加成功,但是本地试验任务文件夹创建失败");
|
||||
@ -208,12 +223,74 @@ public class TsTaskServiceImpl extends ServiceImpl<TsTaskMapper, TsTask> impleme
|
||||
}
|
||||
|
||||
|
||||
// 动态创建任务文件表
|
||||
private void createTaskFileTable(String taskCode) {
|
||||
|
||||
// 添加表名校验(重要!防止SQL注入)
|
||||
if (!taskCode.matches("^\\d{5}$")) { // 假设任务编号是5位数字
|
||||
throw new IllegalArgumentException("非法任务编号格式: " + taskCode);
|
||||
}
|
||||
|
||||
String tableName = "ts_files_" + taskCode;
|
||||
String sql = String.format(
|
||||
"CREATE TABLE IF NOT EXISTS `%s` LIKE `ts_files`",
|
||||
tableName
|
||||
);
|
||||
try (Connection conn = dataSource.getConnection();
|
||||
Statement stmt = conn.createStatement()) {
|
||||
// 1. 记录要执行的SQL
|
||||
LOGGER.info("执行DDL: {}", sql);
|
||||
// 2. 执行SQL
|
||||
boolean result = stmt.execute(sql);
|
||||
// 3. 验证结果
|
||||
LOGGER.debug("执行结果: {}", result);
|
||||
// 4. 二次验证
|
||||
if (!tableExists(tableName)) {
|
||||
throw new RuntimeException("表创建后验证失败: " + tableName);
|
||||
}
|
||||
|
||||
} catch (SQLException e) {
|
||||
// 提取MySQL错误信息
|
||||
String errorMsg = extractMysqlError(e);
|
||||
LOGGER.error("创建表失败: {} - {}", tableName, errorMsg);
|
||||
throw new RuntimeException("创建表失败: " + errorMsg, e);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean tableExists(String tableName) {
|
||||
try (Connection conn = dataSource.getConnection()) {
|
||||
DatabaseMetaData meta = conn.getMetaData();
|
||||
// 获取当前数据库信息
|
||||
String catalog = conn.getCatalog();
|
||||
String schema = conn.getSchema();
|
||||
// 查询表是否存在
|
||||
try (ResultSet rs = meta.getTables(catalog, schema, tableName, new String[]{"TABLE"})) {
|
||||
return rs.next();
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
LOGGER.error("检查表存在失败: {}", tableName, e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private String extractMysqlError(SQLException e) {
|
||||
// 提取MySQL特有的错误信息
|
||||
while (e != null) {
|
||||
if (e.getMessage().contains("MySQL")) {
|
||||
return String.format("MySQL 错误 [%d]: %s", e.getErrorCode(), e.getMessage());
|
||||
}
|
||||
e = e.getNextException();
|
||||
}
|
||||
return "未知数据库错误";
|
||||
}
|
||||
|
||||
public static String buildTaskName(TsTask tsTask) {
|
||||
List<String> parts = new ArrayList<>();
|
||||
|
||||
// 定义日期格式化模板
|
||||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
|
||||
// 按顺序添加非空字段
|
||||
addIfNotEmpty(parts, String.valueOf(tsTask.getTaskStartdate()));
|
||||
addIfNotEmpty(parts, String.valueOf(tsTask.getTaskEnddate()));
|
||||
addIfNotEmpty(parts, formatDate(tsTask.getTaskStartdate(), formatter));
|
||||
addIfNotEmpty(parts, formatDate(tsTask.getTaskEnddate(), formatter));
|
||||
addIfNotEmpty(parts, tsTask.getTaskPlace());
|
||||
addIfNotEmpty(parts, tsTask.getCarrierName());
|
||||
addIfNotEmpty(parts, tsTask.getDeviceCode());
|
||||
@ -222,6 +299,15 @@ public class TsTaskServiceImpl extends ServiceImpl<TsTaskMapper, TsTask> impleme
|
||||
return String.join("_", parts);
|
||||
}
|
||||
|
||||
// 格式化日期的方法
|
||||
private static String formatDate(Object date, DateTimeFormatter formatter) {
|
||||
if (date != null) {
|
||||
return ((java.time.LocalDate) date).format(formatter);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
private static void addIfNotEmpty(List<String> list, String value) {
|
||||
if (StringUtils.isNotBlank(value)) { // 使用Apache Commons Lang的空判断
|
||||
list.add(value.trim()); // 去除首尾空格
|
||||
@ -262,21 +348,27 @@ public class TsTaskServiceImpl extends ServiceImpl<TsTaskMapper, TsTask> impleme
|
||||
public boolean deleteTstaskByIds(List<String> dataset) {
|
||||
Boolean value = false;
|
||||
|
||||
//循环所有的ID
|
||||
for (String taskId : dataset) {
|
||||
//删除项目
|
||||
try {
|
||||
|
||||
// 删除节点表
|
||||
LambdaQueryWrapper<TsNodes> deleteWrapper = new LambdaQueryWrapper<>();
|
||||
deleteWrapper.eq(TsNodes::getTaskId, taskId);
|
||||
tsNodesMapper.delete(deleteWrapper);
|
||||
|
||||
// 删除文件表
|
||||
LambdaQueryWrapper<TsFiles> deleteWrapperFiles = new LambdaQueryWrapper<>();
|
||||
deleteWrapperFiles.eq(TsFiles::getTaskId, taskId);
|
||||
tsFilesMapper.delete(deleteWrapperFiles);
|
||||
//循环所有的ID
|
||||
for (String taskId : dataset) {
|
||||
//删除项目
|
||||
TsTask tsTask = tsTaskMapper.selectById(taskId);
|
||||
TableNameContextHolder.setTaskCode(tsTask.getTaskCode());
|
||||
// 删除节点表
|
||||
LambdaQueryWrapper<TsNodes> deleteWrapper = new LambdaQueryWrapper<>();
|
||||
deleteWrapper.eq(TsNodes::getTaskId, taskId);
|
||||
tsNodesMapper.delete(deleteWrapper);
|
||||
|
||||
// 删除文件表
|
||||
LambdaQueryWrapper<TsFiles> deleteWrapperFiles = new LambdaQueryWrapper<>();
|
||||
deleteWrapperFiles.eq(TsFiles::getTaskId, taskId);
|
||||
tsFilesMapper.delete(deleteWrapperFiles);
|
||||
//todo 删除文件表数据
|
||||
// tsFilesMapper.deleteSdFilesBytaskId(taskId);
|
||||
|
||||
|
||||
TsTask tsTask = tsTaskMapper.selectById(taskId);
|
||||
// String path = "/" + tsTask.getTaskName() + "/";
|
||||
// //调用删除节点 根据任务ID
|
||||
// Boolean deleteTsnodes = tsNodesService.deleteTsNodesByTaskId(taskId, path);
|
||||
@ -289,59 +381,65 @@ public class TsTaskServiceImpl extends ServiceImpl<TsTaskMapper, TsTask> impleme
|
||||
// value = false;
|
||||
// }
|
||||
|
||||
StorageSource storageSource = getStorageConfig(tsTask.getLocalStorageId());
|
||||
// 删除 local 中的文件夹 项目文件夹
|
||||
List<BatchDeleteRequest.DeleteItem> deleteItemList = new ArrayList<>();
|
||||
BatchDeleteRequest.DeleteItem deleteItemData = new BatchDeleteRequest.DeleteItem();
|
||||
deleteItemData.setName(tsTask.getTaskName());
|
||||
deleteItemData.setPassword("");
|
||||
deleteItemData.setPath("/");
|
||||
deleteItemData.setType(FileTypeEnum.FOLDER);
|
||||
deleteItemList.add(deleteItemData);
|
||||
|
||||
// 删除 local 中的文件夹 项目文件夹
|
||||
List<BatchDeleteRequest.DeleteItem> deleteItemList = new ArrayList<>();
|
||||
BatchDeleteRequest.DeleteItem deleteItemData = new BatchDeleteRequest.DeleteItem();
|
||||
deleteItemData.setName(tsTask.getTaskName());
|
||||
deleteItemData.setPassword("");
|
||||
deleteItemData.setPath("/");
|
||||
deleteItemData.setType(FileTypeEnum.FOLDER);
|
||||
deleteItemList.add(deleteItemData);
|
||||
BatchDeleteRequest batchDeleteRequest = new BatchDeleteRequest();
|
||||
batchDeleteRequest.setDeleteItems(deleteItemList);
|
||||
batchDeleteRequest.setStorageKey(storageSource.getKey());
|
||||
AbstractBaseFileService<?> fileService = storageSourceContext.getByStorageKey(batchDeleteRequest.getStorageKey());
|
||||
int deleteSuccessCount = 0, deleteFailCount = 0, totalCount = CollUtil.size(deleteItemList);
|
||||
|
||||
BatchDeleteRequest batchDeleteRequest = new BatchDeleteRequest();
|
||||
batchDeleteRequest.setDeleteItems(deleteItemList);
|
||||
batchDeleteRequest.setStorageKey("local");
|
||||
AbstractBaseFileService<?> fileService = storageSourceContext.getByStorageKey(batchDeleteRequest.getStorageKey());
|
||||
int deleteSuccessCount = 0, deleteFailCount = 0, totalCount = CollUtil.size(deleteItemList);
|
||||
for (BatchDeleteRequest.DeleteItem deleteItem : deleteItemList) {
|
||||
boolean flag = false;
|
||||
try {
|
||||
if (deleteItem.getType() == FileTypeEnum.FILE) {
|
||||
flag = fileService.deleteFile(deleteItem.getPath(), deleteItem.getName());
|
||||
} else if (deleteItem.getType() == FileTypeEnum.FOLDER) {
|
||||
flag = fileService.deleteFolder(deleteItem.getPath(), deleteItem.getName());
|
||||
}
|
||||
|
||||
for (BatchDeleteRequest.DeleteItem deleteItem : deleteItemList) {
|
||||
boolean flag = false;
|
||||
try {
|
||||
if (deleteItem.getType() == FileTypeEnum.FILE) {
|
||||
flag = fileService.deleteFile(deleteItem.getPath(), deleteItem.getName());
|
||||
} else if (deleteItem.getType() == FileTypeEnum.FOLDER) {
|
||||
flag = fileService.deleteFolder(deleteItem.getPath(), deleteItem.getName());
|
||||
}
|
||||
|
||||
if (flag) {
|
||||
deleteSuccessCount++;
|
||||
} else {
|
||||
if (flag) {
|
||||
deleteSuccessCount++;
|
||||
} else {
|
||||
deleteFailCount++;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("删除文件/文件夹失败, 文件路径: {}, 文件名称: {}", deleteItem.getPath(), deleteItem.getName(), e);
|
||||
deleteFailCount++;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("删除文件/文件夹失败, 文件路径: {}, 文件名称: {}", deleteItem.getPath(), deleteItem.getName(), e);
|
||||
deleteFailCount++;
|
||||
}
|
||||
}
|
||||
|
||||
if (deleteSuccessCount >= 1) {
|
||||
// 删除当前项目
|
||||
int deleteCount = tsTaskMapper.deleteById(taskId);
|
||||
if (deleteCount == 1) {
|
||||
LOGGER.info("tstask表结删除改成功");
|
||||
value = true;
|
||||
if (deleteSuccessCount >= 1) {
|
||||
// 删除当前项目
|
||||
int deleteCount = tsTaskMapper.deleteById(taskId);
|
||||
if (deleteCount == 1) {
|
||||
LOGGER.info("tstask表结删除改成功");
|
||||
value = true;
|
||||
} else {
|
||||
LOGGER.error("tstask表结构删除失败");
|
||||
value = false;
|
||||
}
|
||||
} else {
|
||||
LOGGER.error("tstask表结构删除失败");
|
||||
value = false;
|
||||
}
|
||||
} else {
|
||||
value = false;
|
||||
|
||||
|
||||
}
|
||||
|
||||
return value;
|
||||
} catch (Exception e) {
|
||||
|
||||
} finally {
|
||||
TableNameContextHolder.clear();
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
@ -352,20 +450,53 @@ public class TsTaskServiceImpl extends ServiceImpl<TsTaskMapper, TsTask> impleme
|
||||
***********************************/
|
||||
@Override
|
||||
public Object confirmDeleteTask(List<String> dataset) {
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
// 删除 getBackupPath 和 getWorkPath 都为空的记录
|
||||
LambdaQueryWrapper<TsFiles> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.in(TsFiles::getTaskId, dataset)
|
||||
.and(wrapper -> wrapper.isNotNull(TsFiles::getBackupPath)
|
||||
.or().ne(TsFiles::getBackupPath, ""));
|
||||
int count = tsFilesService.count(queryWrapper);
|
||||
//如果大于0不让删
|
||||
if (count > 0) {
|
||||
jsonObject.putOpt("status", "0");
|
||||
} else {
|
||||
jsonObject.putOpt("status", "1");
|
||||
try {
|
||||
LambdaQueryWrapper<TsTask> queryWrapperTsk = new LambdaQueryWrapper<>();
|
||||
queryWrapperTsk.in(TsTask::getId, dataset);
|
||||
List<TsTask> tsTasks = tsTaskMapper.selectList(queryWrapperTsk);
|
||||
|
||||
JSONObject result = new JSONObject();
|
||||
boolean allDeletable = true;
|
||||
|
||||
for (TsTask tsTask : tsTasks) {
|
||||
TableNameContextHolder.setTaskCode(tsTask.getTaskCode());
|
||||
|
||||
// 查询是否有备份路径或非空路径的文件
|
||||
LambdaQueryWrapper<TsFiles> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(TsFiles::getTaskId, tsTask.getId())
|
||||
.and(wrapper -> wrapper.isNotNull(TsFiles::getBackupPath)
|
||||
.or().ne(TsFiles::getBackupPath, ""));
|
||||
|
||||
int count = tsFilesService.count(queryWrapper);
|
||||
|
||||
if (count > 0) {
|
||||
allDeletable = false;
|
||||
break; // 一旦发现不可删除项,提前终止循环
|
||||
}
|
||||
}
|
||||
|
||||
result.putOpt("status", allDeletable ? "1" : "0");
|
||||
return ResponseResult.successData(result);
|
||||
|
||||
} catch (Exception e) {
|
||||
// 使用日志框架代替 printStackTrace
|
||||
LOGGER.error("确认删除实验任务时发生异常", e);
|
||||
return ResponseResult.error("查询失败");
|
||||
} finally {
|
||||
TableNameContextHolder.clear();
|
||||
}
|
||||
return ResponseResult.successData(jsonObject);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<TsTask> listTsTask() {
|
||||
LambdaQueryWrapper<TsTask> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.orderByDesc(TsTask::getTaskStartdate);
|
||||
List<TsTask> tsTasks = tsTaskMapper.selectList(queryWrapper);
|
||||
for (TsTask tsTask : tsTasks){
|
||||
StorageSource storageSource = getStorageConfig(tsTask.getLocalStorageId());
|
||||
tsTask.setKey(storageSource.getKey());
|
||||
}
|
||||
return tsTasks;
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@ -398,4 +529,10 @@ public class TsTaskServiceImpl extends ServiceImpl<TsTaskMapper, TsTask> impleme
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 辅助方法:获取存储配置
|
||||
private StorageSource getStorageConfig( Integer id) {
|
||||
return storageSourceMapper.selectOne(new LambdaQueryWrapper<StorageSource>().eq(StorageSource::getId, id)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -161,9 +161,7 @@ public class ProjectController {
|
||||
@ResponseBody
|
||||
//@PreAuthorize("@el.check('select:devicesignal')")
|
||||
public ResponseResult listSdproject() {
|
||||
LambdaQueryWrapper<Project> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.orderByDesc(Project::getProjectTime);
|
||||
List<Project> projects = projectService.list(queryWrapper);
|
||||
List<Project> projects = projectService.listProject();
|
||||
return ResponseResult.successData(projects);
|
||||
}
|
||||
|
||||
|
@ -6,6 +6,7 @@ import java.sql.Timestamp;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import lombok.Data;
|
||||
@ -91,4 +92,22 @@ public class Project implements Serializable {
|
||||
private String custom3;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 本地存储空间id
|
||||
*/
|
||||
private Integer localStorageId;
|
||||
|
||||
/**
|
||||
* 上传用到KEY:TODO 增加用于前端展示
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
private String key;
|
||||
|
||||
/**
|
||||
* 上传用到type:TODO 增加用于前端展示
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
private String type;
|
||||
|
||||
}
|
||||
|
@ -1,9 +1,11 @@
|
||||
package com.yfd.platform.modules.specialDocument.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.yfd.platform.modules.specialDocument.domain.Files;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@ -22,4 +24,33 @@ public interface FilesMapper extends BaseMapper<Files> {
|
||||
|
||||
//根据节点删除文件(递归子节点文件)
|
||||
int deleteByNodeId(@Param("nodeId")String nodeId);
|
||||
|
||||
void updateFileByPath(@Param("projectId") String projectId,@Param("oldBasePath") String oldBasePath,@Param("newBasePath") String newBasePath);
|
||||
|
||||
//分页查询文件表
|
||||
Page<Files> selectFilesPage(@Param("page") Page<Files> page,
|
||||
@Param("fileName") String fileName,
|
||||
@Param("keywords") String keywords,
|
||||
@Param("startDate") Date startDate,
|
||||
@Param("endDate") Date endDate,
|
||||
@Param("projectId") String projectId,
|
||||
@Param("nodeId") String nodeId,
|
||||
@Param("fileName1") String fileName1,
|
||||
@Param("tableName") String tableName
|
||||
);
|
||||
|
||||
//插入文件表
|
||||
int insertSdFilesTable(@Param("tableName") String tableName, @Param("files") Files filess);
|
||||
|
||||
//更新文件表
|
||||
int updateSdFiles(@Param("tableName") String tableName, @Param("files") Files files);
|
||||
|
||||
//批量查询文件表
|
||||
List<Files> selectSdFilesBatchIds(@Param("dataset") List<String> dataset,@Param("tableName") String tableName);
|
||||
|
||||
//删除文件表
|
||||
int deleteSdFiles(@Param("tableName") String tableName, @Param("files") Files files);
|
||||
|
||||
//查询文件表根据ID
|
||||
Files selectSdFilesById(@Param("tableName") String tableName, @Param("id") String id);
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package com.yfd.platform.modules.specialDocument.mapper;
|
||||
|
||||
import com.yfd.platform.modules.specialDocument.domain.Nodes;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@ -20,4 +21,6 @@ public interface NodesMapper extends BaseMapper<Nodes> {
|
||||
int updateParentIdByPathHierarchy();
|
||||
|
||||
int deleteNodesRecursively(String nodeId);
|
||||
|
||||
void updateNodesByPath(@Param("projectId") String projectId,@Param("oldBasePath") String oldBasePath,@Param("newBasePath") String newBasePath);
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package com.yfd.platform.modules.specialDocument.mapper;
|
||||
|
||||
import com.yfd.platform.modules.specialDocument.domain.Project;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
@ -13,4 +14,8 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
*/
|
||||
public interface ProjectMapper extends BaseMapper<Project> {
|
||||
|
||||
// 新增动态建表方法
|
||||
static int createFileTable(@Param("tableName") String tableName) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -46,4 +46,6 @@ public interface IProjectService extends IService<Project> {
|
||||
boolean deleteProjectByIds(List<String> dataset);
|
||||
|
||||
String generateNextProjectCode();
|
||||
|
||||
List<Project> listProject();
|
||||
}
|
||||
|
@ -11,16 +11,18 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.yfd.platform.config.ResponseResult;
|
||||
import com.yfd.platform.exception.file.InvalidStorageSourceException;
|
||||
import com.yfd.platform.modules.config.model.request.FileListRequest;
|
||||
import com.yfd.platform.modules.experimentalData.domain.TsFiles;
|
||||
import com.yfd.platform.modules.specialDocument.domain.Files;
|
||||
import com.yfd.platform.modules.specialDocument.domain.Project;
|
||||
import com.yfd.platform.modules.specialDocument.mapper.FilesMapper;
|
||||
import com.yfd.platform.modules.specialDocument.mapper.ProjectMapper;
|
||||
import com.yfd.platform.modules.specialDocument.service.IFilesService;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.yfd.platform.modules.storage.chain.FileChain;
|
||||
import com.yfd.platform.modules.storage.chain.FileContext;
|
||||
import com.yfd.platform.modules.storage.context.StorageSourceContext;
|
||||
import com.yfd.platform.modules.storage.controller.file.FileController;
|
||||
import com.yfd.platform.modules.storage.mapper.StorageSourceConfigMapper;
|
||||
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.StorageSourceConfig;
|
||||
import com.yfd.platform.modules.storage.model.enums.FileTypeEnum;
|
||||
import com.yfd.platform.modules.storage.model.request.BatchDeleteRequest;
|
||||
@ -81,7 +83,9 @@ public class FilesServiceImpl extends ServiceImpl<FilesMapper, Files> implements
|
||||
private FilesMapper filesMapper;
|
||||
|
||||
@Autowired
|
||||
private FileController fileController;
|
||||
private ProjectMapper projectMapper;
|
||||
@Resource
|
||||
private StorageSourceMapper storageSourceMapper;
|
||||
|
||||
@Resource
|
||||
private StorageSourceContext storageSourceContext;
|
||||
@ -223,9 +227,11 @@ public class FilesServiceImpl extends ServiceImpl<FilesMapper, Files> implements
|
||||
public FileItemResult sdLocalUrl(String id) {
|
||||
FileItemResult fileItemResult = new FileItemResult();
|
||||
Files files = filesMapper.selectById(id);
|
||||
Project project = projectMapper.selectById(files.getProjectId());
|
||||
StorageSource storageSource = storageSourceMapper.selectById(project.getLocalStorageId());
|
||||
String pathAndName = files.getFilePath() + files.getFileName();
|
||||
//准备获取文件的信息
|
||||
AbstractBaseFileService<?> fileService = storageSourceContext.getByStorageKey("sdlocal");
|
||||
AbstractBaseFileService<?> fileService = storageSourceContext.getByStorageKey(storageSource.getKey());
|
||||
fileItemResult = fileService.getFileItem(pathAndName);
|
||||
return fileItemResult;
|
||||
}
|
||||
@ -299,13 +305,13 @@ public class FilesServiceImpl extends ServiceImpl<FilesMapper, Files> implements
|
||||
if (authentication != null) {
|
||||
loginuser = (LoginUser) authentication.getPrincipal();
|
||||
}
|
||||
Project project = projectMapper.selectById(files.getProjectId());
|
||||
StorageSource storageSource = getStorageConfig(project.getLocalStorageId());
|
||||
|
||||
|
||||
//新增之前从处理一下源路径的数据 ,String sourcePath,String targetPath
|
||||
// 查询本地文件路径根目录(如 E:\yun)
|
||||
QueryWrapper<StorageSourceConfig> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("name", "filePath");
|
||||
queryWrapper.eq("type", "sdlocal");
|
||||
StorageSourceConfig storageSourceConfig = storageSourceConfigMapper.selectOne(queryWrapper);
|
||||
StorageSourceConfig storageSourceConfig = getStorageSourceConfig("filePath","local",project.getLocalStorageId());
|
||||
//源路径 临时路径
|
||||
String sourceFilePath = files.getSourcePath();
|
||||
//目标路径
|
||||
@ -322,7 +328,7 @@ public class FilesServiceImpl extends ServiceImpl<FilesMapper, Files> implements
|
||||
//校验是否真正上传
|
||||
String pathAndName = filess.getFilePath() + filess.getFileName();
|
||||
//准备获取文件的信息
|
||||
AbstractBaseFileService<?> fileService = storageSourceContext.getByStorageKey("sdlocal");
|
||||
AbstractBaseFileService<?> fileService = storageSourceContext.getByStorageKey(storageSource.getKey());
|
||||
FileItemResult fileItemResult = fileService.getFileItem(pathAndName);
|
||||
if (fileItemResult == null || fileItemResult.getName() == null) {
|
||||
return ResponseResult.error(filess.getFileName() + "文件没有上传到空间,请重新选择上传!");
|
||||
@ -380,8 +386,8 @@ public class FilesServiceImpl extends ServiceImpl<FilesMapper, Files> implements
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
// 转换为 Timestamp
|
||||
Timestamp currentTime = Timestamp.valueOf(now);
|
||||
FileListRequest sourcefileListRequest = buildFileRequest(sourceFilePath);
|
||||
FileListRequest targetfileListRequest = buildFileRequest(targetFilePath);
|
||||
FileListRequest sourcefileListRequest = buildFileRequest(sourceFilePath,files.getProjectId());
|
||||
FileListRequest targetfileListRequest = buildFileRequest(targetFilePath,files.getProjectId());
|
||||
|
||||
//获取源文件列表 包含文件和文件夹
|
||||
List<FileItemResult> sourceFileItemList = obtainFileItemResultData(sourcefileListRequest);
|
||||
@ -583,13 +589,16 @@ public class FilesServiceImpl extends ServiceImpl<FilesMapper, Files> implements
|
||||
return fileItemList;
|
||||
}
|
||||
|
||||
private FileListRequest buildFileRequest(String path) {
|
||||
private FileListRequest buildFileRequest(String path,String projectId) {
|
||||
Project project = projectMapper.selectById(projectId);
|
||||
StorageSource storageSource = getStorageConfig(project.getLocalStorageId());
|
||||
|
||||
FileListRequest fileListRequest = new FileListRequest();
|
||||
fileListRequest.setOrderBy("time");
|
||||
fileListRequest.setOrderDirection("desc");
|
||||
fileListRequest.setPassword("");
|
||||
fileListRequest.setPath(path);
|
||||
fileListRequest.setStorageKey("sdlocal");
|
||||
fileListRequest.setStorageKey(storageSource.getKey());
|
||||
|
||||
return fileListRequest;
|
||||
}
|
||||
@ -673,6 +682,8 @@ public class FilesServiceImpl extends ServiceImpl<FilesMapper, Files> implements
|
||||
redisTemplate.delete(redisKey);
|
||||
}
|
||||
int SuccessCount = 0, FailCount = 0, total = CollUtil.size(dataset);
|
||||
Project project = projectMapper.selectById(filesList.get(0).getProjectId());
|
||||
StorageSource storageSource = getStorageConfig(project.getLocalStorageId());
|
||||
//Todo 最直接的办法 循环出来 一条一条删除
|
||||
for (Files files : filesList) {
|
||||
|
||||
@ -689,7 +700,7 @@ public class FilesServiceImpl extends ServiceImpl<FilesMapper, Files> implements
|
||||
|
||||
BatchDeleteRequest batchDeleteRequest = new BatchDeleteRequest();
|
||||
batchDeleteRequest.setDeleteItems(deleteItemList);
|
||||
batchDeleteRequest.setStorageKey("sdlocal");
|
||||
batchDeleteRequest.setStorageKey(storageSource.getKey());
|
||||
|
||||
AbstractBaseFileService<?> fileService = storageSourceContext.getByStorageKey(batchDeleteRequest.getStorageKey());
|
||||
List<BatchDeleteRequest.DeleteItem> deleteItems = batchDeleteRequest.getDeleteItems();
|
||||
@ -745,12 +756,15 @@ public class FilesServiceImpl extends ServiceImpl<FilesMapper, Files> implements
|
||||
// 修改 sdlocal 文件名的方法
|
||||
private boolean updateMinioFileName(Files filesData, Files files) {
|
||||
try {
|
||||
Project project = projectMapper.selectById(files.getProjectId());
|
||||
StorageSource storageSource = getStorageConfig(project.getLocalStorageId());
|
||||
|
||||
RenameFileRequest renameFileRequest = new RenameFileRequest();
|
||||
renameFileRequest.setName(filesData.getFileName());
|
||||
renameFileRequest.setNewName(files.getFileName());
|
||||
renameFileRequest.setPassword("");
|
||||
renameFileRequest.setPath(filesData.getFilePath());
|
||||
renameFileRequest.setStorageKey("sdlocal");
|
||||
renameFileRequest.setStorageKey(storageSource.getKey());
|
||||
|
||||
AbstractBaseFileService<?> fileService = storageSourceContext.getByStorageKey(renameFileRequest.getStorageKey());
|
||||
return fileService.renameFile(renameFileRequest.getPath(), renameFileRequest.getName(), renameFileRequest.getNewName());
|
||||
@ -759,4 +773,17 @@ public class FilesServiceImpl extends ServiceImpl<FilesMapper, Files> implements
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// 辅助方法:获取存储配置
|
||||
private StorageSource getStorageConfig(Integer id) {
|
||||
return storageSourceMapper.selectOne(new LambdaQueryWrapper<StorageSource>().eq(StorageSource::getId, id)
|
||||
);
|
||||
}
|
||||
|
||||
// 辅助方法:获取存储配置
|
||||
private StorageSourceConfig getStorageSourceConfig(String name, String type,Integer id) {
|
||||
return storageSourceConfigMapper.selectOne(
|
||||
new LambdaQueryWrapper<StorageSourceConfig>().eq(StorageSourceConfig::getName, name).eq(StorageSourceConfig::getType, type).eq(StorageSourceConfig::getStorageId,id)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -3,8 +3,6 @@ package com.yfd.platform.modules.specialDocument.service.impl;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.util.IdUtil;
|
||||
import cn.hutool.core.util.ObjUtil;
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import com.amazonaws.util.IOUtils;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.yfd.platform.component.TaskStatusHolder;
|
||||
@ -23,6 +21,8 @@ import com.yfd.platform.modules.specialDocument.service.INodesService;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.yfd.platform.modules.storage.context.StorageSourceContext;
|
||||
import com.yfd.platform.modules.storage.mapper.StorageSourceConfigMapper;
|
||||
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.StorageSourceConfig;
|
||||
import com.yfd.platform.modules.storage.model.enums.FileTypeEnum;
|
||||
import com.yfd.platform.modules.storage.model.request.BatchDeleteRequest;
|
||||
@ -41,6 +41,7 @@ import org.apache.commons.io.FilenameUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
@ -100,10 +101,17 @@ public class NodesServiceImpl extends ServiceImpl<NodesMapper, Nodes> implements
|
||||
@Autowired
|
||||
private TaskStatusHolder taskStatusHolder;
|
||||
|
||||
|
||||
@Resource
|
||||
private StorageSourceMapper storageSourceMapper;
|
||||
|
||||
//专项项目表Mapper
|
||||
@Resource
|
||||
private ProjectMapper projectMapper;
|
||||
|
||||
@Autowired
|
||||
private RedisTemplate<String, Object> redisTemplate;
|
||||
|
||||
//顶级父节点 Top level parent node
|
||||
public static final String TOP_LEVEL_PARENT_NODE = "00";
|
||||
|
||||
@ -301,6 +309,9 @@ public class NodesServiceImpl extends ServiceImpl<NodesMapper, Nodes> implements
|
||||
@Transactional(rollbackFor = Exception.class) // 添加事务注解,遇到异常时回滚
|
||||
public ResponseResult addNodes(Nodes nodes) {
|
||||
|
||||
Project project = projectMapper.selectById(nodes.getProjectId());
|
||||
StorageSource storageSource = getStorageConfig(project.getLocalStorageId());
|
||||
|
||||
// 校验文件名是否包含非法字符
|
||||
String nodeName = nodes.getNodeName();
|
||||
if (containsInvalidCharacters(nodeName)) {
|
||||
@ -362,7 +373,7 @@ public class NodesServiceImpl extends ServiceImpl<NodesMapper, Nodes> implements
|
||||
newFolderRequest.setName(nodes.getNodeName());//新建的文件夹名称,示例值(/a/b/c)
|
||||
newFolderRequest.setPassword("");//文件夹密码, 如果文件夹需要密码才能访问,则支持请求密码,示例值(123456)
|
||||
newFolderRequest.setPath(nodes.getPath());//请求路径,示例值(/)
|
||||
newFolderRequest.setStorageKey("sdlocal");//存储源 key,示例值(local minio sdlocal)
|
||||
newFolderRequest.setStorageKey(storageSource.getKey());//存储源 key,示例值(local minio sdlocal)
|
||||
AbstractBaseFileService<?> fileService = storageSourceContext.getByStorageKey(newFolderRequest.getStorageKey());
|
||||
boolean flag = fileService.newFolder(newFolderRequest.getPath(), newFolderRequest.getName());
|
||||
if (flag) {
|
||||
@ -392,6 +403,9 @@ public class NodesServiceImpl extends ServiceImpl<NodesMapper, Nodes> implements
|
||||
if (containsInvalidCharacters(nodeName)) {
|
||||
return ResponseResult.error("文件名包含非法字符(<>:\"/\\|?*)!");
|
||||
}
|
||||
Project project = projectMapper.selectById(nodes.getProjectId());
|
||||
StorageSource storageSource = getStorageConfig(project.getLocalStorageId());
|
||||
|
||||
|
||||
//查询没改之前的节点名称
|
||||
Nodes nodesold = nodesMapper.selectById(nodes.getId());
|
||||
@ -401,9 +415,6 @@ public class NodesServiceImpl extends ServiceImpl<NodesMapper, Nodes> implements
|
||||
nodeNameOld = nodesold.getNodeName();
|
||||
}
|
||||
|
||||
//获取专项文档项目
|
||||
Project project = projectMapper.selectById(nodes.getProjectId());
|
||||
|
||||
//获取当前登录用户
|
||||
UsernamePasswordAuthenticationToken authentication =
|
||||
(UsernamePasswordAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
|
||||
@ -424,49 +435,84 @@ public class NodesServiceImpl extends ServiceImpl<NodesMapper, Nodes> implements
|
||||
if (count > 0) {
|
||||
return ResponseResult.error("节点名称已存在!");
|
||||
}
|
||||
//更新当前数据
|
||||
int valueUpdate = nodesMapper.updateById(nodes);
|
||||
|
||||
// 4. 递归获取所有子节点ID(包含当前节点)
|
||||
List<String> affectedNodeIds = getAllChildNodeIds(nodes.getId());
|
||||
// 2. 构建新旧路径
|
||||
String oldBasePath = nodes.getPath() + nodeNameOld + "/";
|
||||
String newBasePath = nodes.getPath() + nodeName + "/";
|
||||
|
||||
// 5. 更新相关文件路径
|
||||
updateFilePaths(affectedNodeIds, nodes.getProjectId(), nodeNameOld, nodeName);
|
||||
//3.跟新节点表sd_nodes表 根据所属项目ID 老路径 和新路径
|
||||
nodesMapper.updateNodesByPath(nodes.getProjectId(), oldBasePath, newBasePath);
|
||||
|
||||
if (valueUpdate == 1) {
|
||||
List<String> pathNodes = new ArrayList<>();
|
||||
Nodes nodesData = nodesMapper.selectById(nodes.getParentId());
|
||||
// 从当前节点向上遍历,直到根节点
|
||||
while (nodesData != null) {
|
||||
pathNodes.add(nodesData.getNodeName());
|
||||
// 如果父节点是 "00",说明已经到了根节点,停止遍历
|
||||
if ("00".equals(nodesData.getParentId())) {
|
||||
break;
|
||||
//4.更新文件表sd_files表 根据所属项目ID 老路径 和新路径
|
||||
filesMapper.updateFileByPath(nodes.getProjectId(), oldBasePath, newBasePath);
|
||||
|
||||
//获取项目下面的所有子节点 都清除缓存
|
||||
List<Nodes> nodesList = nodesMapper.selectList(new QueryWrapper<Nodes>().eq("project_id", nodes.getProjectId()));
|
||||
if ((nodesList != null) && (nodesList.size() > 0)) {
|
||||
for (Nodes node : nodesList) {
|
||||
//todo 修改节点成功以后 删除redis
|
||||
for (int page = 1; page <= 5; page++) {
|
||||
String redisKey = "sdfiles_" + node.getProjectId() + "_" + node.getId() + "_page_" + page;
|
||||
redisTemplate.delete(redisKey);
|
||||
}
|
||||
// 获取父节点
|
||||
nodesData = nodesMapper.selectById(nodesData.getParentId()); // 修正:从 nodesData 中获取 parentId
|
||||
LOGGER.info("已清理缓存:project={}, node={}, pages=1-5", nodes.getProjectId(), nodes.getId());
|
||||
}
|
||||
// 反转路径,使其从根节点到当前节点
|
||||
Collections.reverse(pathNodes);
|
||||
String path = String.join("/", pathNodes);
|
||||
}
|
||||
|
||||
//修改文件名称
|
||||
RenameFolderRequest renameFolderRequest = new RenameFolderRequest();
|
||||
renameFolderRequest.setName(nodeNameOld);//重命名的原文件夹名称,示例值(movie)
|
||||
renameFolderRequest.setNewName(nodeName);// 重命名后的文件名称,示例值(music)
|
||||
renameFolderRequest.setPassword("");//文件夹密码, 如果文件夹需要密码才能访问,则支持请求密码,示例值(123456)
|
||||
renameFolderRequest.setPath(nodes.getPath());//请求路径,示例值(/)
|
||||
renameFolderRequest.setStorageKey("sdlocal");//存储源 key,示例值(local minio sdlocal)
|
||||
AbstractBaseFileService<?> fileService = storageSourceContext.getByStorageKey(renameFolderRequest.getStorageKey());
|
||||
boolean flag = fileService.renameFolder(renameFolderRequest.getPath(), renameFolderRequest.getName(), renameFolderRequest.getNewName());
|
||||
if (flag) {
|
||||
|
||||
//判断如果更新了节点名称
|
||||
if (!nodeName.equals(nodeNameOld)) {
|
||||
// // 4. 递归获取所有子节点ID(包含当前节点)
|
||||
// List<String> affectedNodeIds = getAllChildNodeIds(nodes.getId());
|
||||
//
|
||||
// // 5. 更新相关文件路径
|
||||
// updateFilePaths(affectedNodeIds, nodes.getProjectId(), nodeNameOld, nodeName);
|
||||
|
||||
if (valueUpdate == 1) {
|
||||
// List<String> pathNodes = new ArrayList<>();
|
||||
// Nodes nodesData = nodesMapper.selectById(nodes.getParentId());
|
||||
// // 从当前节点向上遍历,直到根节点
|
||||
// while (nodesData != null) {
|
||||
// pathNodes.add(nodesData.getNodeName());
|
||||
// // 如果父节点是 "00",说明已经到了根节点,停止遍历
|
||||
// if ("00".equals(nodesData.getParentId())) {
|
||||
// break;
|
||||
// }
|
||||
// // 获取父节点
|
||||
// nodesData = nodesMapper.selectById(nodesData.getParentId()); // 修正:从 nodesData 中获取 parentId
|
||||
// }
|
||||
// // 反转路径,使其从根节点到当前节点
|
||||
// Collections.reverse(pathNodes);
|
||||
// String path = String.join("/", pathNodes);
|
||||
|
||||
//修改文件名称
|
||||
RenameFolderRequest renameFolderRequest = new RenameFolderRequest();
|
||||
renameFolderRequest.setName(nodeNameOld);//重命名的原文件夹名称,示例值(movie)
|
||||
renameFolderRequest.setNewName(nodeName);// 重命名后的文件名称,示例值(music)
|
||||
renameFolderRequest.setPassword("");//文件夹密码, 如果文件夹需要密码才能访问,则支持请求密码,示例值(123456)
|
||||
renameFolderRequest.setPath(nodes.getPath());//请求路径,示例值(/)
|
||||
renameFolderRequest.setStorageKey(storageSource.getKey());//存储源 key,示例值(local minio sdlocal)
|
||||
AbstractBaseFileService<?> fileService = storageSourceContext.getByStorageKey(renameFolderRequest.getStorageKey());
|
||||
boolean flag = fileService.renameFolder(renameFolderRequest.getPath(), renameFolderRequest.getName(), renameFolderRequest.getNewName());
|
||||
if (flag) {
|
||||
return ResponseResult.success("重命名成功");
|
||||
} else {
|
||||
LOGGER.error("节点修改成功,但是sdlocal修改文件名失败");
|
||||
return ResponseResult.error("重命名失败");
|
||||
}
|
||||
} else {
|
||||
LOGGER.error("节点修改失败");
|
||||
return ResponseResult.error();
|
||||
}
|
||||
|
||||
} else {
|
||||
if (valueUpdate == 1) {
|
||||
return ResponseResult.success("重命名成功");
|
||||
} else {
|
||||
LOGGER.error("节点修改成功,但是sdlocal修改文件名失败");
|
||||
return ResponseResult.error("重命名失败");
|
||||
}
|
||||
} else {
|
||||
LOGGER.error("节点修改失败");
|
||||
return ResponseResult.error();
|
||||
}
|
||||
}
|
||||
|
||||
@ -545,6 +591,8 @@ public class NodesServiceImpl extends ServiceImpl<NodesMapper, Nodes> implements
|
||||
if (nodes == null) {
|
||||
return false; // 节点不存在
|
||||
}
|
||||
Project project = projectMapper.selectById(nodes.getProjectId());
|
||||
StorageSource storageSource = getStorageConfig(project.getLocalStorageId());
|
||||
// //递归获取当前节点和它下面的所有节点
|
||||
// List<Nodes> nodesList = selectChildrenNodes(id, nodes.getProjectId());
|
||||
// // 提取所有节点的 ID
|
||||
@ -581,7 +629,7 @@ public class NodesServiceImpl extends ServiceImpl<NodesMapper, Nodes> implements
|
||||
|
||||
BatchDeleteRequest batchDeleteRequest = new BatchDeleteRequest();
|
||||
batchDeleteRequest.setDeleteItems(deleteItemList);
|
||||
batchDeleteRequest.setStorageKey("sdlocal");
|
||||
batchDeleteRequest.setStorageKey(storageSource.getKey());
|
||||
AbstractBaseFileService<?> fileService = storageSourceContext.getByStorageKey(batchDeleteRequest.getStorageKey());
|
||||
|
||||
int deleteSuccessCount = 0, deleteFailCount = 0, totalCount = CollUtil.size(deleteItemList);
|
||||
@ -699,12 +747,13 @@ public class NodesServiceImpl extends ServiceImpl<NodesMapper, Nodes> implements
|
||||
|
||||
//查询项目信息
|
||||
Project project = projectMapper.selectById(id);
|
||||
|
||||
StorageSource storageSource = getStorageConfig(project.getLocalStorageId());
|
||||
|
||||
// 查询本地文件路径根目录(如 E:\yun)
|
||||
QueryWrapper<StorageSourceConfig> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("name", "filePath");
|
||||
queryWrapper.eq("type", "sdlocal");
|
||||
queryWrapper.eq("storage_id", project.getLocalStorageId());
|
||||
queryWrapper.eq("type", storageSource.getType());
|
||||
StorageSourceConfig storageSourceConfig = storageSourceConfigMapper.selectOne(queryWrapper);
|
||||
|
||||
//获取文件列表
|
||||
@ -944,7 +993,7 @@ public class NodesServiceImpl extends ServiceImpl<NodesMapper, Nodes> implements
|
||||
|
||||
String absolutePath = path + nodeName + "/";
|
||||
//获取文件列表
|
||||
FileListRequest fileListRequest = buildFileRequest(absolutePath);
|
||||
FileListRequest fileListRequest = buildFileRequest(absolutePath,projectId);
|
||||
String storageKey = fileListRequest.getStorageKey();
|
||||
Integer storageId = storageSourceService.findIdByKey(storageKey);
|
||||
if (storageId == null) {
|
||||
@ -1012,13 +1061,15 @@ public class NodesServiceImpl extends ServiceImpl<NodesMapper, Nodes> implements
|
||||
return map.get(adjustedIndex);
|
||||
}
|
||||
|
||||
private FileListRequest buildFileRequest(String path) {
|
||||
private FileListRequest buildFileRequest(String path,String projectId) {
|
||||
Project project = projectMapper.selectById(projectId);
|
||||
StorageSource storageSource = getStorageConfig(project.getLocalStorageId());
|
||||
FileListRequest fileListRequest = new FileListRequest();
|
||||
fileListRequest.setOrderBy("time");
|
||||
fileListRequest.setOrderDirection("desc");
|
||||
fileListRequest.setPassword("");
|
||||
fileListRequest.setPath(path);
|
||||
fileListRequest.setStorageKey("sdlocal");
|
||||
fileListRequest.setStorageKey(storageSource.getKey());
|
||||
|
||||
return fileListRequest;
|
||||
}
|
||||
@ -1123,14 +1174,14 @@ public class NodesServiceImpl extends ServiceImpl<NodesMapper, Nodes> implements
|
||||
try {
|
||||
// 1. 优化:合并重复的异常捕获
|
||||
//------------------------------------------
|
||||
// 查询存储配置
|
||||
StorageSourceConfig config = getStorageConfig();
|
||||
if (config == null) throw new RuntimeException("未找到本地存储路径配置");
|
||||
|
||||
|
||||
// 优化:提前验证项目存在性(避免后续无效操作)
|
||||
Project project = projectMapper.selectById(id);
|
||||
if (project == null) throw new RuntimeException("项目不存在: " + id);
|
||||
|
||||
// 查询存储配置 wrapper.eq("name", "filePath").eq("type", "sdlocal");
|
||||
StorageSourceConfig config = getStorageSourceConfig("filePath", "local", project.getLocalStorageId());
|
||||
if (config == null) throw new RuntimeException("未找到本地存储路径配置");
|
||||
// 优化:解压路径统一构建逻辑
|
||||
final String tempDir = "temporary";
|
||||
final String zipName = getFileNameWithoutExtension(fileName);
|
||||
@ -1172,12 +1223,7 @@ public class NodesServiceImpl extends ServiceImpl<NodesMapper, Nodes> implements
|
||||
}
|
||||
}
|
||||
|
||||
// 新增辅助方法:解耦核心逻辑 --------------------------------------------------
|
||||
private StorageSourceConfig getStorageConfig() {
|
||||
QueryWrapper<StorageSourceConfig> wrapper = new QueryWrapper<>();
|
||||
wrapper.eq("name", "filePath").eq("type", "sdlocal");
|
||||
return storageSourceConfigMapper.selectOne(wrapper);
|
||||
}
|
||||
|
||||
|
||||
private void transferProjectFiles(String projectId, String basePath, String sourceDir, String targetDir) throws Exception {
|
||||
String sourcePath = "/temporary/" + sourceDir + "/";
|
||||
@ -1201,78 +1247,7 @@ public class NodesServiceImpl extends ServiceImpl<NodesMapper, Nodes> implements
|
||||
}
|
||||
}
|
||||
|
||||
// public void documentUploadByIdAsync(String id, String fileName, LoginUser loginuser) throws IOException {
|
||||
// try {
|
||||
//
|
||||
// // 查询本地文件路径根目录(如 E:\yun)
|
||||
// QueryWrapper<StorageSourceConfig> queryWrapper = new QueryWrapper<>();
|
||||
// queryWrapper.eq("name", "filePath");
|
||||
// queryWrapper.eq("type", "sdlocal");
|
||||
// StorageSourceConfig storageSourceConfig = storageSourceConfigMapper.selectOne(queryWrapper);
|
||||
//
|
||||
// if (storageSourceConfig == null) {
|
||||
// throw new RuntimeException("未找到本地存储路径配置");
|
||||
// }
|
||||
//
|
||||
// //解压以后的文件夹名称
|
||||
// String zipName = getFileNameWithoutExtension(fileName); // 示例:222
|
||||
//
|
||||
// //查询项目信息
|
||||
// Project project = projectMapper.selectById(id);
|
||||
// if (project == null) {
|
||||
// throw new RuntimeException("项目不存在");
|
||||
// }
|
||||
//
|
||||
// if (!project.getProjectName().equals(zipName)) {
|
||||
// throw new RuntimeException("压缩包名称需要和项目名称保持一致");
|
||||
// }
|
||||
//
|
||||
// String decompressionPath = "/" + "temporary";
|
||||
// //构建要解压的zip文件路径 例如 D:\yun\temporary\111.zip
|
||||
// Path zipFilePath = Paths.get(storageSourceConfig.getValue(), decompressionPath, fileName);
|
||||
// // 4. 构建解压目标路径 例如 D:\yun\temporary\111
|
||||
// Path destRoot = Paths.get(storageSourceConfig.getValue(), decompressionPath);
|
||||
//
|
||||
// LOGGER.info("要解压文件路径:{}", zipFilePath);
|
||||
// LOGGER.info("解压以后文件路径:{}", destRoot);
|
||||
//
|
||||
//
|
||||
// //todo 如果项目不存在 直接拷贝到目标路径下 拷贝完成以后 然后新增一个项目结构 然后走一遍扫描
|
||||
//
|
||||
// //源文件夹路径
|
||||
// String sourceFolderPath = "/" + "temporary" + "/" + zipName + "/";
|
||||
// //目标文件夹路径
|
||||
// String targetFolderPath = "/" + project.getProjectName() + "/";
|
||||
//
|
||||
// //首先执行解压缩
|
||||
// unzipToTemp(zipFilePath, String.valueOf(destRoot));
|
||||
// // 执行上传并且插入数据库
|
||||
// this.documentUploadById(id, sourceFolderPath, targetFolderPath, storageSourceConfig.getValue());
|
||||
// //开始执行更新表数据 名称是去掉后缀以后的
|
||||
// uploadProject(zipName, loginuser);
|
||||
// LOGGER.info("开始更新表数据:{}", zipName);
|
||||
//
|
||||
// //获取文件路径
|
||||
// Path destRootPath = Paths.get(storageSourceConfig.getValue(), decompressionPath, zipName);
|
||||
// File targetZip = new File(String.valueOf(zipFilePath));
|
||||
// File target = new File(String.valueOf(destRootPath));
|
||||
// //删除临时文件ZIP
|
||||
// deleteDirectory(targetZip);
|
||||
// //删除临时文件
|
||||
// deleteDirectory(target);
|
||||
// } catch (IOException e) {
|
||||
// throw new RuntimeException(e);
|
||||
// } catch (Exception e) {
|
||||
// throw new RuntimeException(e);
|
||||
// } finally {
|
||||
// // 生成唯一Key
|
||||
// String asyncKey = taskStatusHolder.documentUploadKey(id);
|
||||
// // 无论成功失败都标记完成
|
||||
// taskStatusHolder.finishTask(asyncKey);
|
||||
// WebSocketServer.sendMessageTo("专项文档上传任务处理完成!", "projectId_" + id);
|
||||
//
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
public static void deleteDirectory(File directory) throws Exception {
|
||||
if (!directory.exists()) {
|
||||
@ -1317,8 +1292,8 @@ public class NodesServiceImpl extends ServiceImpl<NodesMapper, Nodes> implements
|
||||
return null;
|
||||
}
|
||||
|
||||
FileListRequest sourcefileListRequest = buildFileRequest(sourceFolderPath);
|
||||
FileListRequest targetfileListRequest = buildFileRequest(targetFolderPath);
|
||||
FileListRequest sourcefileListRequest = buildFileRequest(sourceFolderPath, id);
|
||||
FileListRequest targetfileListRequest = buildFileRequest(targetFolderPath, id);
|
||||
|
||||
//获取源文件列表 包含文件和文件夹
|
||||
List<FileItemResult> sourceFileItemList = obtainFileItemResultData(sourcefileListRequest);
|
||||
@ -1415,8 +1390,10 @@ public class NodesServiceImpl extends ServiceImpl<NodesMapper, Nodes> implements
|
||||
LambdaQueryWrapper<Project> projectLambdaQueryWrapper = new LambdaQueryWrapper<>();
|
||||
projectLambdaQueryWrapper.eq(Project::getProjectName, projectName);
|
||||
Project project = projectMapper.selectOne(projectLambdaQueryWrapper);
|
||||
|
||||
//如果项目不存在
|
||||
if (project == null) {
|
||||
StorageSource storageSource = getStorageConfig(project.getLocalStorageId());
|
||||
String projectCode = this.generateNextProjectCode();
|
||||
project.setProjectCode("1");
|
||||
|
||||
@ -1435,7 +1412,7 @@ public class NodesServiceImpl extends ServiceImpl<NodesMapper, Nodes> implements
|
||||
newFolderRequest.setName(project.getProjectName());//新建的文件夹名称,示例值(/a/b/c)
|
||||
newFolderRequest.setPassword("");//文件夹密码, 如果文件夹需要密码才能访问,则支持请求密码,示例值(123456)
|
||||
newFolderRequest.setPath(path);//请求路径,示例值(/)
|
||||
newFolderRequest.setStorageKey("sdlocal");//存储源 key,示例值(local minio)
|
||||
newFolderRequest.setStorageKey(storageSource.getKey());//存储源 key,示例值(local minio)
|
||||
AbstractBaseFileService<?> fileService = storageSourceContext.getByStorageKey(newFolderRequest.getStorageKey());
|
||||
boolean flag = fileService.newFolder(newFolderRequest.getPath(), newFolderRequest.getName());
|
||||
}
|
||||
@ -1748,5 +1725,21 @@ public class NodesServiceImpl extends ServiceImpl<NodesMapper, Nodes> implements
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// 辅助方法:获取存储配置
|
||||
private StorageSource getStorageConfig( Integer id) {
|
||||
return storageSourceMapper.selectOne(new LambdaQueryWrapper<StorageSource>().eq(StorageSource::getId, id)
|
||||
);
|
||||
}
|
||||
|
||||
// 辅助方法:获取存储配置
|
||||
private StorageSourceConfig getStorageSourceConfig(String name, String type,Integer id) {
|
||||
return storageSourceConfigMapper.selectOne(
|
||||
new LambdaQueryWrapper<StorageSourceConfig>().eq(StorageSourceConfig::getName, name).eq(StorageSourceConfig::getType, type).eq(StorageSourceConfig::getStorageId,id)
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -4,7 +4,6 @@ import cn.hutool.core.collection.CollUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.yfd.platform.modules.specialDocument.domain.Files;
|
||||
import com.yfd.platform.modules.specialDocument.domain.Nodes;
|
||||
import com.yfd.platform.modules.specialDocument.domain.Project;
|
||||
import com.yfd.platform.modules.specialDocument.mapper.ProjectMapper;
|
||||
@ -12,23 +11,26 @@ import com.yfd.platform.modules.specialDocument.service.INodesService;
|
||||
import com.yfd.platform.modules.specialDocument.service.IProjectService;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.yfd.platform.modules.storage.context.StorageSourceContext;
|
||||
import com.yfd.platform.modules.storage.mapper.StorageSourceMapper;
|
||||
import com.yfd.platform.modules.storage.model.entity.StorageSource;
|
||||
import com.yfd.platform.modules.storage.model.enums.FileTypeEnum;
|
||||
import com.yfd.platform.modules.storage.model.request.BatchDeleteRequest;
|
||||
import com.yfd.platform.modules.storage.model.request.NewFolderRequest;
|
||||
import com.yfd.platform.modules.storage.service.base.AbstractBaseFileService;
|
||||
import com.yfd.platform.system.mapper.SysDictionaryItemsMapper;
|
||||
import com.yfd.platform.utils.StringUtils;
|
||||
import io.netty.channel.ChannelInboundHandlerAdapter;
|
||||
import net.bytebuddy.implementation.bytecode.Throw;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.sql.Timestamp;
|
||||
import javax.sql.DataSource;
|
||||
import java.sql.*;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@ -57,13 +59,16 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
|
||||
@Resource
|
||||
private INodesService nodesService;
|
||||
|
||||
//字典表Mapper
|
||||
@Resource
|
||||
private SysDictionaryItemsMapper sysDictionaryItemsMapper;
|
||||
|
||||
@Resource
|
||||
private StorageSourceContext storageSourceContext;
|
||||
|
||||
@Resource
|
||||
private StorageSourceMapper storageSourceMapper;
|
||||
|
||||
@Autowired
|
||||
private DataSource dataSource;
|
||||
|
||||
/**********************************
|
||||
* 用途说明: 分页查询专项文档管理-项目管理
|
||||
* 参数说明
|
||||
@ -125,6 +130,7 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
|
||||
// 转换为 Timestamp
|
||||
Timestamp currentTime = Timestamp.valueOf(now);
|
||||
project.setCreateTime(currentTime);
|
||||
StorageSource storageSource = getStorageConfig(project.getLocalStorageId());
|
||||
|
||||
LambdaQueryWrapper<Project> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(Project::getProjectName,project.getProjectName());
|
||||
@ -144,10 +150,13 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
|
||||
newFolderRequest.setName(project.getProjectName());//新建的文件夹名称,示例值(/a/b/c)
|
||||
newFolderRequest.setPassword("");//文件夹密码, 如果文件夹需要密码才能访问,则支持请求密码,示例值(123456)
|
||||
newFolderRequest.setPath(path);//请求路径,示例值(/)
|
||||
newFolderRequest.setStorageKey("sdlocal");//存储源 key,示例值(local minio)
|
||||
newFolderRequest.setStorageKey(storageSource.getKey());//存储源 key,示例值(local minio)
|
||||
AbstractBaseFileService<?> fileService = storageSourceContext.getByStorageKey(newFolderRequest.getStorageKey());
|
||||
boolean flag = fileService.newFolder(newFolderRequest.getPath(), newFolderRequest.getName());
|
||||
if (flag) {
|
||||
|
||||
// 动态创建数据表
|
||||
//createTaskFileTable(projectCode);
|
||||
return true;
|
||||
} else {
|
||||
LOGGER.error("节点新增成功,但是本地专项文件夹创建失败");
|
||||
@ -158,31 +167,67 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// //查询字典表获取项目类型对应数据字典
|
||||
// QueryWrapper<SysDictionaryItems> queryWrapperSysDictionary = new QueryWrapper<>();
|
||||
// queryWrapperSysDictionary.eq("parentcode", "compressType");
|
||||
// queryWrapperSysDictionary.orderByAsc("orderno");
|
||||
// SysDictionaryItems sysDictionaryItems = sysDictionaryItemsMapper.selectOne(queryWrapperSysDictionary);
|
||||
// if(sysDictionaryItems != null){
|
||||
// project.setProjectType(sysDictionaryItems.getDictName());
|
||||
// }
|
||||
// 动态创建任务文件表
|
||||
private void createTaskFileTable(String taskCode) {
|
||||
|
||||
// 添加表名校验(重要!防止SQL注入)
|
||||
if (!taskCode.matches("^\\d{5}$")) { // 假设任务编号是5位数字
|
||||
throw new IllegalArgumentException("非法任务编号格式: " + taskCode);
|
||||
}
|
||||
|
||||
//TODO 01.21沟通以后说是先不用管重复校验问题
|
||||
// //通过项目名称 项目编号查询 查看是否存在
|
||||
// QueryWrapper<Project> queryWrapper = new QueryWrapper<>();
|
||||
// if(project.getProjectCode() != null){
|
||||
// queryWrapper.eq("project_code",project.getProjectCode());
|
||||
// }
|
||||
// if(project.getProjectName() != null){
|
||||
// queryWrapper.eq("project_name",project.getProjectName());
|
||||
// }
|
||||
// List<Project> projects = projectMapper.selectList(queryWrapper);
|
||||
// if(){
|
||||
//
|
||||
// }
|
||||
String tableName = "sd_files_" + taskCode;
|
||||
String sql = String.format(
|
||||
"CREATE TABLE IF NOT EXISTS `%s` LIKE `sd_files`",
|
||||
tableName
|
||||
);
|
||||
try (Connection conn = dataSource.getConnection();
|
||||
Statement stmt = conn.createStatement()) {
|
||||
// 1. 记录要执行的SQL
|
||||
LOGGER.info("执行DDL: {}", sql);
|
||||
// 2. 执行SQL
|
||||
boolean result = stmt.execute(sql);
|
||||
// 3. 验证结果
|
||||
LOGGER.debug("执行结果: {}", result);
|
||||
// 4. 二次验证
|
||||
if (!tableExists(tableName)) {
|
||||
throw new RuntimeException("表创建后验证失败: " + tableName);
|
||||
}
|
||||
|
||||
} catch (SQLException e) {
|
||||
// 提取MySQL错误信息
|
||||
String errorMsg = extractMysqlError(e);
|
||||
LOGGER.error("创建表失败: {} - {}", tableName, errorMsg);
|
||||
throw new RuntimeException("创建表失败: " + errorMsg, e);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean tableExists(String tableName) {
|
||||
try (Connection conn = dataSource.getConnection()) {
|
||||
DatabaseMetaData meta = conn.getMetaData();
|
||||
// 获取当前数据库信息
|
||||
String catalog = conn.getCatalog();
|
||||
String schema = conn.getSchema();
|
||||
// 查询表是否存在
|
||||
try (ResultSet rs = meta.getTables(catalog, schema, tableName, new String[]{"TABLE"})) {
|
||||
return rs.next();
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
LOGGER.error("检查表存在失败: {}", tableName, e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private String extractMysqlError(SQLException e) {
|
||||
// 提取MySQL特有的错误信息
|
||||
while (e != null) {
|
||||
if (e.getMessage().contains("MySQL")) {
|
||||
return String.format("MySQL 错误 [%d]: %s", e.getErrorCode(), e.getMessage());
|
||||
}
|
||||
e = e.getNextException();
|
||||
}
|
||||
return "未知数据库错误";
|
||||
}
|
||||
|
||||
// 编号生成工具方法
|
||||
@ -216,6 +261,8 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**********************************
|
||||
* 用途说明: 修改专项文档管理-项目管理
|
||||
* 参数说明
|
||||
@ -256,6 +303,8 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
|
||||
//循环所有的ID
|
||||
for (String id : dataset) {
|
||||
Project project = projectMapper.selectById(id);
|
||||
StorageSource storageSource = getStorageConfig(project.getLocalStorageId());
|
||||
|
||||
String path = "/" + project.getProjectName() + "/";
|
||||
QueryWrapper<Nodes> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("project_id", id);
|
||||
@ -288,7 +337,7 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
|
||||
|
||||
BatchDeleteRequest batchDeleteRequest = new BatchDeleteRequest();
|
||||
batchDeleteRequest.setDeleteItems(deleteItemList);
|
||||
batchDeleteRequest.setStorageKey("sdlocal");
|
||||
batchDeleteRequest.setStorageKey(storageSource.getKey());
|
||||
AbstractBaseFileService<?> fileService = storageSourceContext.getByStorageKey(batchDeleteRequest.getStorageKey());
|
||||
int deleteSuccessCount = 0, deleteFailCount = 0, totalCount = CollUtil.size(deleteItemList);
|
||||
|
||||
@ -330,4 +379,23 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Project> listProject() {
|
||||
LambdaQueryWrapper<Project> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.orderByDesc(Project::getProjectTime);
|
||||
List<Project> projects = projectMapper.selectList(queryWrapper);
|
||||
for (Project project : projects){
|
||||
StorageSource storageSource = getStorageConfig(project.getLocalStorageId());
|
||||
project.setKey(storageSource.getKey());
|
||||
project.setType(String.valueOf(storageSource.getType()));
|
||||
}
|
||||
return projects;
|
||||
}
|
||||
|
||||
// 辅助方法:获取存储配置
|
||||
private StorageSource getStorageConfig(Integer id) {
|
||||
return storageSourceMapper.selectOne(new LambdaQueryWrapper<StorageSource>().eq(StorageSource::getId, id)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -13,6 +13,8 @@ import com.yfd.platform.modules.storage.model.entity.StorageSource;
|
||||
import com.yfd.platform.modules.storage.model.entity.StorageSourceConfig;
|
||||
import com.yfd.platform.modules.storage.model.enums.StorageTypeEnum;
|
||||
import com.yfd.platform.modules.storage.model.param.IStorageParam;
|
||||
import com.yfd.platform.modules.storage.service.StorageSourceConfigService;
|
||||
import com.yfd.platform.modules.storage.service.StorageSourceService;
|
||||
import com.yfd.platform.modules.storage.service.base.AbstractBaseFileService;
|
||||
import com.yfd.platform.modules.storage.support.StorageSourceSupport;
|
||||
import com.yfd.platform.utils.ClassUtils;
|
||||
@ -176,12 +178,23 @@ public class StorageSourceContext {
|
||||
*
|
||||
* @return 存储源对应未初始化的 Service
|
||||
*/
|
||||
private AbstractBaseFileService<IStorageParam> getInitStorageBeanByStorageId(Integer storageId) {
|
||||
String keyById = storageSourceMapper.findKeyById(storageId);
|
||||
StorageSource storageSource = storageSourceMapper.findByStorageKey(keyById);
|
||||
String type = String.valueOf(storageSource.getType());
|
||||
// private AbstractBaseFileService<IStorageParam> getInitStorageBeanByStorageId(Integer storageId) {
|
||||
// String keyById = storageSourceMapper.findKeyById(storageId);
|
||||
//// StorageSource storageSource = storageSourceMapper.findByStorageKey(keyById);
|
||||
// storageSourceMapper
|
||||
//// String type = String.valueOf(storageSource.getType());
|
||||
//
|
||||
// StorageTypeEnum storageTypeEnum = Optional.ofNullable(storageSourceMapper.findByStorageKey(keyById)).map(StorageSource::getType).orElse(null);
|
||||
// for (AbstractBaseFileService<?> value : storageTypeEnumFileServiceMap.values()) {
|
||||
// if (Objects.equals(value.getStorageTypeEnum(), storageTypeEnum)) {
|
||||
// return SpringUtil.getBean(value.getClass());
|
||||
// }
|
||||
// }
|
||||
// return null;
|
||||
// }
|
||||
|
||||
StorageTypeEnum storageTypeEnum = Optional.ofNullable(storageSourceMapper.findByStorageKey(keyById)).map(StorageSource::getType).orElse(null);
|
||||
private AbstractBaseFileService<IStorageParam> getInitStorageBeanByStorageId(Integer storageId) {
|
||||
StorageTypeEnum storageTypeEnum = Optional.ofNullable(this.findById(storageId)).map(StorageSource::getType).orElse(null);;
|
||||
for (AbstractBaseFileService<?> value : storageTypeEnumFileServiceMap.values()) {
|
||||
if (Objects.equals(value.getStorageTypeEnum(), storageTypeEnum)) {
|
||||
return SpringUtil.getBean(value.getClass());
|
||||
@ -190,6 +203,9 @@ public class StorageSourceContext {
|
||||
return null;
|
||||
}
|
||||
|
||||
public StorageSource findById(Integer id) {
|
||||
return storageSourceMapper.selectById(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定存储源的初始化参数.
|
||||
|
@ -1,14 +1,17 @@
|
||||
package com.yfd.platform.modules.storage.controller.base;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
|
||||
import com.github.xiaoymin.knife4j.annotations.ApiSort;
|
||||
import com.yfd.platform.config.ResponseResult;
|
||||
import com.yfd.platform.modules.config.model.request.SaveStorageSourceRequest;
|
||||
import com.yfd.platform.modules.config.model.request.UpdateStorageSortRequest;
|
||||
import com.yfd.platform.modules.experimentalData.domain.TsFiles;
|
||||
import com.yfd.platform.modules.storage.convert.StorageSourceConvert;
|
||||
import com.yfd.platform.modules.storage.model.dto.StorageSourceDTO;
|
||||
import com.yfd.platform.modules.storage.model.entity.StorageSource;
|
||||
import com.yfd.platform.modules.storage.model.enums.SearchModeEnum;
|
||||
import com.yfd.platform.modules.storage.model.result.StorageSourceAdminResult;
|
||||
import com.yfd.platform.modules.storage.service.StorageSourceService;
|
||||
import io.swagger.annotations.Api;
|
||||
@ -48,6 +51,33 @@ public class StorageSourceController {
|
||||
return ResponseResult.successData(storageSourceAdminResults);
|
||||
}
|
||||
|
||||
@ApiOperationSupport(order = 11)
|
||||
@ApiOperation(value = "根据类型获取所有存储源列表", notes = "根据类型获取所有添加的存储源列表,按照排序值由小到大排序")
|
||||
@GetMapping("/storagesBytype")
|
||||
public ResponseResult storageListBytype(String type) {
|
||||
List<StorageSource> list = storageSourceService.findAllOrderByOrderNumByType(type);
|
||||
List<StorageSourceAdminResult> storageSourceAdminResults = storageSourceConvert.entityToAdminResultList(list);
|
||||
return ResponseResult.successData(storageSourceAdminResults);
|
||||
}
|
||||
|
||||
@ApiOperationSupport(order = 10)
|
||||
@ApiOperation(value = "分页获取所有存储源列表", notes = "分页获取所有添加的存储源列表,按照排序值由小到大排序")
|
||||
@GetMapping("/storagesPage")
|
||||
public ResponseResult storagePage(Page<StorageSource> page,String type,String name) {
|
||||
Page<StorageSource> pageResult = storageSourceService.findAllOrderByOrderNumPage(page, type,name);
|
||||
|
||||
Page<StorageSourceAdminResult> storageSourceAdminResults = storageSourceConvert.entityToAdminResultPage(pageResult);
|
||||
return ResponseResult.successData(storageSourceAdminResults);
|
||||
}
|
||||
@ApiOperationSupport(order = 12)
|
||||
@ApiOperation(value = "通过key查询type", notes = "通过key查询type")
|
||||
@GetMapping("/storagesType")
|
||||
public ResponseResult storagesType(String key) {
|
||||
StorageSource storageSource = storageSourceService.findAllOrderBystoragesType(key);
|
||||
return ResponseResult.successData(storageSource);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ApiOperationSupport(order = 2)
|
||||
@ApiOperation(value = "获取指定存储源参数", notes = "获取指定存储源基本信息及其参数")
|
||||
@ -63,6 +93,10 @@ public class StorageSourceController {
|
||||
@ApiOperation(value = "保存存储源参数", notes = "保存存储源的所有参数")
|
||||
@PostMapping("/storage")
|
||||
public ResponseResult saveStorageItem(@RequestBody SaveStorageSourceRequest saveStorageSourceRequest) {
|
||||
saveStorageSourceRequest.setEnable( true);
|
||||
saveStorageSourceRequest.setEnableFileOperator( true);
|
||||
saveStorageSourceRequest.setSearchMode(SearchModeEnum.SEARCH_CACHE_MODE);
|
||||
saveStorageSourceRequest.setEnableFileAnnoOperator(false);
|
||||
Integer id = storageSourceService.saveStorageSource(saveStorageSourceRequest);
|
||||
return ResponseResult.successData(id);
|
||||
}
|
||||
@ -78,6 +112,7 @@ public class StorageSourceController {
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ApiOperationSupport(order = 5)
|
||||
@ApiOperation(value = "启用存储源", notes = "开启存储源后可在前台显示")
|
||||
@ApiImplicitParam(paramType = "path", name = "storageId", value = "存储源 id", required = true, dataTypeClass = Integer.class)
|
||||
|
@ -1,5 +1,6 @@
|
||||
package com.yfd.platform.modules.storage.convert;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.yfd.platform.modules.config.model.request.SaveStorageSourceRequest;
|
||||
import com.yfd.platform.modules.readme.model.entity.ReadmeConfig;
|
||||
import com.yfd.platform.modules.storage.model.dto.StorageSourceAllParamDTO;
|
||||
@ -53,6 +54,7 @@ public interface StorageSourceConvert {
|
||||
*/
|
||||
List<StorageSourceAdminResult> entityToAdminResultList(List<StorageSource> list);
|
||||
|
||||
Page<StorageSourceAdminResult> entityToAdminResultPage(Page<StorageSource> pageResult);
|
||||
|
||||
StorageSourceDTO entityToDTO(StorageSource storageSource, StorageSourceAllParamDTO storageSourceAllParam);
|
||||
|
||||
@ -68,4 +70,5 @@ public interface StorageSourceConvert {
|
||||
StorageSource saveRequestToEntity(SaveStorageSourceRequest saveStorageSourceRequest);
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@ -1,18 +1,31 @@
|
||||
package com.yfd.platform.modules.storage.convert.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.yfd.platform.modules.config.model.request.SaveStorageSourceRequest;
|
||||
import com.yfd.platform.modules.experimentalData.domain.TsTask;
|
||||
import com.yfd.platform.modules.experimentalData.mapper.TsTaskMapper;
|
||||
import com.yfd.platform.modules.readme.model.entity.ReadmeConfig;
|
||||
import com.yfd.platform.modules.specialDocument.domain.Project;
|
||||
import com.yfd.platform.modules.specialDocument.mapper.ProjectMapper;
|
||||
import com.yfd.platform.modules.storage.convert.StorageSourceConvert;
|
||||
import com.yfd.platform.modules.storage.mapper.StorageSourceConfigMapper;
|
||||
import com.yfd.platform.modules.storage.model.dto.StorageSourceAllParamDTO;
|
||||
import com.yfd.platform.modules.storage.model.dto.StorageSourceDTO;
|
||||
import com.yfd.platform.modules.storage.model.entity.StorageSource;
|
||||
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.StorageSourceConfigResult;
|
||||
import com.yfd.platform.modules.storage.model.result.StorageSourceResult;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.io.File;
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @Date: 2025/1/10 12:44
|
||||
@ -21,6 +34,18 @@ import java.util.List;
|
||||
@Service
|
||||
public class StorageSourceConvertImpl implements StorageSourceConvert {
|
||||
|
||||
@Resource
|
||||
private StorageSourceConfigMapper storageSourceConfigMapper;
|
||||
|
||||
//专项项目表Mapper
|
||||
@Resource
|
||||
private ProjectMapper projectMapper;
|
||||
|
||||
//试验任务Mapper
|
||||
@Resource
|
||||
private TsTaskMapper tsTaskMapper;
|
||||
|
||||
|
||||
@Override
|
||||
public List<StorageSourceResult> entityToResultList(List<StorageSource> list) {
|
||||
if ( list == null ) {
|
||||
@ -57,18 +82,127 @@ public class StorageSourceConvertImpl implements StorageSourceConvert {
|
||||
|
||||
@Override
|
||||
public List<StorageSourceAdminResult> entityToAdminResultList(List<StorageSource> list) {
|
||||
if ( list == null ) {
|
||||
return null;
|
||||
if (list == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
List<StorageSourceAdminResult> list1 = new ArrayList<StorageSourceAdminResult>( list.size() );
|
||||
for ( StorageSource storageSource : list ) {
|
||||
list1.add( storageSourceToStorageSourceAdminResult( storageSource ) );
|
||||
}
|
||||
|
||||
return list1;
|
||||
return list.stream()
|
||||
.map(this::storageSourceToStorageSourceAdminResult)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page<StorageSourceAdminResult> entityToAdminResultPage(Page<StorageSource> sourcePage) {
|
||||
if (sourcePage == null) {
|
||||
return new Page<>();
|
||||
}
|
||||
List<StorageSource> recordData = sourcePage.getRecords();
|
||||
for (StorageSource storageSource : recordData) {
|
||||
StringBuilder result = new StringBuilder(); // 用于拼接结果
|
||||
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){
|
||||
for (Project project : projects) {
|
||||
if (result.length() > 0) {
|
||||
result.append(", "); // 如果结果不为空,加上逗号分隔
|
||||
}
|
||||
result.append(project.getProjectName()); // 添加项目名称
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
LambdaQueryWrapper<TsTask> queryWrapper1 = new LambdaQueryWrapper<>();
|
||||
queryWrapper1.eq(TsTask::getLocalStorageId, storageSource.getId());
|
||||
List<TsTask> tsTasks = tsTaskMapper.selectList(queryWrapper1);
|
||||
if (tsTasks.size()>0){
|
||||
for (TsTask task : tsTasks) {
|
||||
if (result.length() > 0) {
|
||||
result.append(", "); // 如果结果不为空,加上逗号分隔
|
||||
}
|
||||
result.append(task.getTaskName()); // 添加任务名称
|
||||
}
|
||||
}
|
||||
|
||||
storageSource.setStoreContent(String.valueOf(result));
|
||||
//存储路径
|
||||
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);
|
||||
|
||||
//空间使用率
|
||||
storageSource.setSpaceOccupancyRatio(calculateLocalStorageUsage(value));
|
||||
|
||||
}else {
|
||||
LambdaQueryWrapper<TsTask> queryWrapper1 = new LambdaQueryWrapper<>();
|
||||
queryWrapper1.eq(TsTask::getBackupStorageId, storageSource.getId());
|
||||
List<TsTask> tsTasks = tsTaskMapper.selectList(queryWrapper1);
|
||||
if (tsTasks.size()>0){
|
||||
for (TsTask task : tsTasks) {
|
||||
if (result.length() > 0) {
|
||||
result.append(", "); // 如果结果不为空,加上逗号分隔
|
||||
}
|
||||
result.append(task.getTaskName()); // 添加任务名称
|
||||
}
|
||||
}
|
||||
storageSource.setStoreContent(String.valueOf(result));
|
||||
storageSource.setValueData(null);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 转换记录列表
|
||||
List<StorageSourceAdminResult> records = entityToAdminResultList(sourcePage.getRecords());
|
||||
|
||||
// 创建目标分页对象并复制所有分页属性
|
||||
Page<StorageSourceAdminResult> resultPage = new Page<>();
|
||||
|
||||
// 复制分页属性
|
||||
resultPage.setRecords(records);
|
||||
resultPage.setTotal(sourcePage.getTotal());
|
||||
resultPage.setSize(sourcePage.getSize());
|
||||
resultPage.setCurrent(sourcePage.getCurrent());
|
||||
resultPage.setOrders(sourcePage.getOrders());
|
||||
resultPage.setOptimizeCountSql(sourcePage.optimizeCountSql());
|
||||
resultPage.setSearchCount(sourcePage.isSearchCount());
|
||||
resultPage.setCountId(sourcePage.getCountId());
|
||||
resultPage.setMaxLimit(sourcePage.getMaxLimit());
|
||||
|
||||
|
||||
|
||||
return resultPage;
|
||||
}
|
||||
|
||||
// 计算本地路径的空间使用率
|
||||
public static String calculateLocalStorageUsage(String path) {
|
||||
File file = new File(path);
|
||||
if (!file.exists()) {
|
||||
throw new IllegalArgumentException("路径不存在: " + path);
|
||||
}
|
||||
|
||||
// 获取磁盘空间信息
|
||||
long totalSpace = file.getTotalSpace();
|
||||
long freeSpace = file.getFreeSpace();
|
||||
// 计算使用率
|
||||
long usedSpace = totalSpace - freeSpace;
|
||||
double usagePercentage = (double) usedSpace / totalSpace * 100;
|
||||
|
||||
// 格式化输出
|
||||
DecimalFormat df = new DecimalFormat("#.##");
|
||||
|
||||
return df.format(usagePercentage) + "%";
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public StorageSourceDTO entityToDTO(StorageSource storageSource, StorageSourceAllParamDTO storageSourceAllParam) {
|
||||
if ( storageSource == null && storageSourceAllParam == null ) {
|
||||
@ -178,7 +312,9 @@ public class StorageSourceConvertImpl implements StorageSourceConvert {
|
||||
storageSourceAdminResult.setOrderNum( storageSource.getOrderNum() );
|
||||
storageSourceAdminResult.setDefaultSwitchToImgMode( storageSource.getDefaultSwitchToImgMode() );
|
||||
storageSourceAdminResult.setCompatibilityReadme( storageSource.getCompatibilityReadme() );
|
||||
|
||||
storageSourceAdminResult.setStoreContent( storageSource.getStoreContent());
|
||||
storageSourceAdminResult.setSpaceOccupancyRatio( storageSource.getSpaceOccupancyRatio());
|
||||
storageSourceAdminResult.setValueData( storageSource.getValueData());
|
||||
return storageSourceAdminResult;
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package com.yfd.platform.modules.storage.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.yfd.platform.modules.storage.model.entity.StorageSource;
|
||||
import com.yfd.platform.modules.storage.model.enums.StorageTypeEnum;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
@ -96,4 +97,7 @@ public interface StorageSourceMapper extends BaseMapper<StorageSource> {
|
||||
*/
|
||||
String findKeyById(@Param("id") Integer id);
|
||||
|
||||
Page<StorageSource> findAllOrderByOrderNumPage(@Param("page") Page<StorageSource> page,@Param("type") String type,@Param("name") String name);
|
||||
|
||||
List<StorageSource> findAllOrderByOrderNumByType(@Param("type") String type);
|
||||
}
|
||||
|
@ -102,5 +102,13 @@ public class StorageSource implements Serializable {
|
||||
@ApiModelProperty(value = "兼容 readme 模式", example = "true", notes = "兼容模式, 目录文档读取 readme.md 文件")
|
||||
private Boolean compatibilityReadme;
|
||||
|
||||
|
||||
//存储内容
|
||||
@TableField(exist = false)
|
||||
private String storeContent;
|
||||
//存储空间使用率
|
||||
@TableField(exist = false)
|
||||
private String spaceOccupancyRatio;
|
||||
//存储路径
|
||||
@TableField(exist = false)
|
||||
private String valueData;
|
||||
}
|
||||
|
@ -2,8 +2,10 @@ package com.yfd.platform.modules.storage.model.enums;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.EnumValue;
|
||||
import com.baomidou.mybatisplus.annotation.IEnum;
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import com.fasterxml.jackson.annotation.JsonValue;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
|
||||
import java.util.HashMap;
|
||||
@ -59,6 +61,12 @@ public enum StorageTypeEnum implements IEnum {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
// 添加反序列化方法
|
||||
@JsonCreator // 告诉Jackson用此方法反序列化
|
||||
public static StorageTypeEnum fromKey(String key) {
|
||||
return ENUM_MAP.get(key);
|
||||
}
|
||||
@JsonValue // 告诉Jackson序列化时使用此字段
|
||||
public String getKey() {
|
||||
return key;
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
package com.yfd.platform.modules.storage.model.result;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.yfd.platform.modules.storage.model.enums.SearchModeEnum;
|
||||
import com.yfd.platform.modules.storage.model.enums.StorageTypeEnum;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
@ -81,4 +82,14 @@ public class StorageSourceAdminResult {
|
||||
@ApiModelProperty(value = "兼容 readme 模式", example = "true", notes = "兼容模式, 目录文档读取 readme.md 文件")
|
||||
private Boolean compatibilityReadme;
|
||||
|
||||
//存储内容
|
||||
@TableField(exist = false)
|
||||
private String storeContent;
|
||||
//存储空间使用率
|
||||
@TableField(exist = false)
|
||||
private String spaceOccupancyRatio;
|
||||
//存储路径
|
||||
@TableField(exist = false)
|
||||
private String valueData;
|
||||
|
||||
}
|
||||
|
@ -3,6 +3,9 @@ package com.yfd.platform.modules.storage.service;
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import cn.hutool.core.util.ReflectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.yfd.platform.exception.BadRequestException;
|
||||
import com.yfd.platform.exception.StorageSourceException;
|
||||
import com.yfd.platform.exception.file.InvalidStorageSourceException;
|
||||
import com.yfd.platform.modules.config.model.request.SaveStorageSourceRequest;
|
||||
@ -15,6 +18,7 @@ import com.yfd.platform.modules.storage.model.dto.StorageSourceDTO;
|
||||
import com.yfd.platform.modules.storage.model.entity.StorageSource;
|
||||
import com.yfd.platform.modules.storage.model.entity.StorageSourceConfig;
|
||||
import com.yfd.platform.modules.storage.model.enums.StorageTypeEnum;
|
||||
import com.yfd.platform.modules.storage.model.param.QiniuParam;
|
||||
import com.yfd.platform.utils.CodeMsg;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.cache.annotation.CacheConfig;
|
||||
@ -61,6 +65,14 @@ public class StorageSourceService {
|
||||
return storageSourceMapper.findAllOrderByOrderNum();
|
||||
}
|
||||
|
||||
public List<StorageSource> findAllOrderByOrderNumByType(String type) {
|
||||
return storageSourceMapper.findAllOrderByOrderNumByType(type);
|
||||
}
|
||||
|
||||
public Page<StorageSource> findAllOrderByOrderNumPage(Page<StorageSource> page,String type,String name) {
|
||||
return storageSourceMapper.findAllOrderByOrderNumPage(page,type,name);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取所有已启用的存储源列表,按照存储源的排序号排序
|
||||
@ -132,7 +144,21 @@ public class StorageSourceService {
|
||||
*
|
||||
* @return 存储源 DTO
|
||||
*/
|
||||
@Cacheable(key = "'dto-' + #id", unless = "#result == null")
|
||||
// @Cacheable(key = "'dto-' + #id", unless = "#result == null")
|
||||
// public StorageSourceDTO findDTOById(Integer id) {
|
||||
// // 将参数列表通过反射写入到 StorageSourceAllParam 中.
|
||||
// StorageSourceAllParamDTO storageSourceAllParam = new StorageSourceAllParamDTO();
|
||||
// storageSourceConfigService.selectStorageConfigByStorageId(id)
|
||||
// .forEach(storageSourceConfig ->
|
||||
// ReflectUtil.setFieldValue(storageSourceAllParam, storageSourceConfig.getName(), storageSourceConfig.getValue())
|
||||
// );
|
||||
//
|
||||
// // 获取数据库对象,转为 dto 对象返回
|
||||
// StorageSource storageSource = findById(id);
|
||||
// return storageSourceConvert.entityToDTO(storageSource, storageSourceAllParam);
|
||||
// }
|
||||
|
||||
//从表中直接获取 不从缓存
|
||||
public StorageSourceDTO findDTOById(Integer id) {
|
||||
// 将参数列表通过反射写入到 StorageSourceAllParam 中.
|
||||
StorageSourceAllParamDTO storageSourceAllParam = new StorageSourceAllParamDTO();
|
||||
@ -289,6 +315,11 @@ public class StorageSourceService {
|
||||
saveStorageSourceRequest.getId(), saveStorageSourceRequest.getName(),
|
||||
saveStorageSourceRequest.getKey(), saveStorageSourceRequest.getType().getDescription());
|
||||
|
||||
StorageSource storageSourceData = storageSourceMapper.findByStorageKey(saveStorageSourceRequest.getKey());
|
||||
if (storageSourceData != null ){
|
||||
throw new BadRequestException("填充存储源别名已存在");
|
||||
}
|
||||
|
||||
// 转换为存储源 entity 对象
|
||||
StorageSource storageSource = storageSourceConvert.saveRequestToEntity(saveStorageSourceRequest);
|
||||
|
||||
@ -319,4 +350,8 @@ public class StorageSourceService {
|
||||
return storageId;
|
||||
}
|
||||
|
||||
|
||||
public StorageSource findAllOrderBystoragesType(String storageKey) {
|
||||
return storageSourceMapper.findByStorageKey(storageKey);
|
||||
}
|
||||
}
|
||||
|
@ -57,6 +57,7 @@ public class CodeMsg {
|
||||
public static CodeMsg STORAGE_SOURCE_INIT_FAIL = new CodeMsg("50100", "初始化存储源失败");
|
||||
public static CodeMsg STORAGE_SOURCE_INIT_STORAGE_CONFIG_FAIL = new CodeMsg("50101", "初始化存储源参数失败");
|
||||
public static CodeMsg STORAGE_SOURCE_INIT_STORAGE_PARAM_FIELD_FAIL = new CodeMsg("50102", "填充存储源字段失败");
|
||||
public static CodeMsg STORAGE_SOURCE_INIT_REPEAT = new CodeMsg("50103", "填充存储源别名重复");
|
||||
|
||||
|
||||
// 文件操作相关错误
|
||||
|
@ -0,0 +1,18 @@
|
||||
package com.yfd.platform.utils;
|
||||
|
||||
public class TableNameContextHolder {
|
||||
|
||||
private static final ThreadLocal<String> TASK_CODE = new ThreadLocal<>();
|
||||
|
||||
public static void setTaskCode(String taskCode) {
|
||||
TASK_CODE.set(taskCode);
|
||||
}
|
||||
|
||||
public static String getTaskCode() {
|
||||
return TASK_CODE.get();
|
||||
}
|
||||
|
||||
public static void clear() {
|
||||
TASK_CODE.remove();
|
||||
}
|
||||
}
|
@ -38,7 +38,16 @@
|
||||
SELECT count(*)
|
||||
FROM ts_files
|
||||
WHERE node_id IN (SELECT node_id FROM node_tree)
|
||||
AND backup_path IS NOT NULL
|
||||
AND (backup_path IS NOT NULL AND backup_path != '')
|
||||
</select>
|
||||
|
||||
<update id="updateTsFileByPath">
|
||||
UPDATE ts_files
|
||||
SET work_path = REPLACE (
|
||||
work_path,#{oldBasePath}, #{newBasePath})
|
||||
|
||||
WHERE
|
||||
task_id = #{taskId}
|
||||
AND work_path LIKE CONCAT(#{oldBasePath}, '%')
|
||||
</update>
|
||||
</mapper>
|
||||
|
@ -37,4 +37,120 @@
|
||||
DELETE FROM sd_files WHERE node_id IN (SELECT id FROM node_tree)
|
||||
</delete>
|
||||
|
||||
|
||||
<update id="updateFileByPath">
|
||||
UPDATE sd_files
|
||||
SET file_path = REPLACE (
|
||||
file_path,#{oldBasePath}, #{newBasePath})
|
||||
|
||||
WHERE
|
||||
project_id = #{projectId}
|
||||
AND file_path LIKE CONCAT(#{oldBasePath}, '%')
|
||||
</update>
|
||||
|
||||
|
||||
<select id="selectFilesPage" resultType="com.yfd.platform.modules.specialDocument.domain.Files">
|
||||
<!-- 使用反引号包裹动态表名 -->
|
||||
SELECT * FROM `${tableName}`
|
||||
<where>
|
||||
<!-- 文件名称不为空 -->
|
||||
<if test="fileName != null and fileName != ''">
|
||||
AND file_name LIKE CONCAT('%', #{fileName}, '%')
|
||||
</if>
|
||||
|
||||
<!-- 关键字不为空 -->
|
||||
<if test="keywords != null and keywords != ''">
|
||||
AND keywords LIKE CONCAT('%', #{keywords}, '%')
|
||||
</if>
|
||||
|
||||
<!-- 开始时间和结束时间 -->
|
||||
<if test="startDate != null">
|
||||
AND upload_time >= #{startDate}
|
||||
</if>
|
||||
<if test="endDate != null">
|
||||
AND upload_time < #{endDate}
|
||||
</if>
|
||||
|
||||
<!-- 项目ID和节点ID -->
|
||||
<if test="projectId != null">
|
||||
AND project_id = #{projectId}
|
||||
</if>
|
||||
<if test="nodeId != null">
|
||||
AND node_id = #{nodeId}
|
||||
</if>
|
||||
</where>
|
||||
ORDER BY upload_time DESC
|
||||
</select>
|
||||
|
||||
<insert id="insertSdFilesTable">
|
||||
INSERT INTO `${tableName}` (
|
||||
id,
|
||||
project_id,
|
||||
node_id,
|
||||
file_name,
|
||||
file_path,
|
||||
keywords,
|
||||
file_size,
|
||||
upload_time,
|
||||
uploader
|
||||
<!-- 其他字段 -->
|
||||
) VALUES (
|
||||
#{files.id},
|
||||
#{files.projectId},
|
||||
#{files.nodeId},
|
||||
#{files.fileName},
|
||||
#{files.filePath},
|
||||
#{files.keywords},
|
||||
#{files.fileSize},
|
||||
#{files.uploadTime},
|
||||
#{files.uploader}
|
||||
<!-- 其他值 -->
|
||||
)
|
||||
</insert>
|
||||
|
||||
<update id="updateSdFiles">
|
||||
UPDATE `${tableName}`
|
||||
SET
|
||||
file_name = #{files.fileName},
|
||||
file_path = #{files.filePath},
|
||||
keywords = #{files.keywords},
|
||||
file_size = #{files.fileSize},
|
||||
upload_time = #{files.uploadTime},
|
||||
uploader = #{files.uploader}
|
||||
<!-- 其他字段 -->
|
||||
WHERE id = #{files.id}
|
||||
</update>
|
||||
|
||||
<select id="selectSdFilesBatchIds" resultType="com.yfd.platform.modules.specialDocument.domain.Files">
|
||||
<!-- 动态表名 -->
|
||||
SELECT *
|
||||
FROM `${tableName}`
|
||||
<where>
|
||||
<!-- 动态条件:ID 集合 -->
|
||||
<if test="dataset != null and dataset.size() > 0">
|
||||
AND id IN
|
||||
<foreach item="id" collection="dataset" open="(" close=")" separator=",">
|
||||
#{id}
|
||||
</foreach>
|
||||
</if>
|
||||
</where>
|
||||
</select>
|
||||
|
||||
|
||||
<select id="selectSdFilesById" resultType="com.yfd.platform.modules.specialDocument.domain.Files">
|
||||
SELECT *
|
||||
FROM `${tableName}`
|
||||
WHERE id = #{id}
|
||||
</select>
|
||||
|
||||
<delete id="deleteSdFiles">
|
||||
<!-- 删除动态表 -->
|
||||
DELETE FROM `${tableName}`
|
||||
<where>
|
||||
<!-- 删除条件 -->
|
||||
<if test="files.id != null">
|
||||
AND id = #{files.id}
|
||||
</if>
|
||||
</where>
|
||||
</delete>
|
||||
</mapper>
|
||||
|
@ -37,4 +37,16 @@
|
||||
DELETE FROM sd_nodes WHERE id IN (SELECT id FROM node_tree)
|
||||
</delete>
|
||||
|
||||
|
||||
<update id="updateNodesByPath">
|
||||
UPDATE sd_nodes
|
||||
SET custom3 = REPLACE (
|
||||
custom3,#{oldBasePath}, #{newBasePath})
|
||||
|
||||
WHERE
|
||||
project_id = #{projectId}
|
||||
|
||||
AND custom3 LIKE CONCAT(#{oldBasePath}, '%')
|
||||
</update>
|
||||
|
||||
</mapper>
|
||||
|
@ -2,4 +2,8 @@
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.yfd.platform.modules.specialDocument.mapper.ProjectMapper">
|
||||
|
||||
<update id="createFileTable">
|
||||
CREATE TABLE IF NOT EXISTS `${tableName}` LIKE `sd_files`
|
||||
</update>
|
||||
|
||||
</mapper>
|
||||
|
@ -74,4 +74,37 @@
|
||||
from fi_storage_source
|
||||
where `id`=#{id,jdbcType=INTEGER}
|
||||
</select>
|
||||
|
||||
<!--auto generated by MybatisCodeHelper on 2021-07-15-->
|
||||
<select id="findAllOrderByOrderNumPage" resultMap="BaseResultMap">
|
||||
select
|
||||
<include refid="Base_Column_List"/>
|
||||
from fi_storage_source
|
||||
<where>
|
||||
<!-- 存储空间名称不为空 -->
|
||||
<if test="name != null and name != ''">
|
||||
AND name LIKE CONCAT('%', #{name}, '%')
|
||||
</if>
|
||||
<!-- 存储策略不为空 -->
|
||||
<if test="type != null and type != ''">
|
||||
AND type =#{type}
|
||||
</if>
|
||||
</where>
|
||||
|
||||
order by ifnull(order_num, -1), id desc
|
||||
</select>
|
||||
|
||||
<select id="findAllOrderByOrderNumByType" resultMap="BaseResultMap">
|
||||
select
|
||||
<include refid="Base_Column_List"/>
|
||||
from fi_storage_source
|
||||
<where>
|
||||
<!-- 存储策略不为空 -->
|
||||
<if test="type != null and type != ''">
|
||||
AND type =#{type}
|
||||
</if>
|
||||
</where>
|
||||
|
||||
order by ifnull(order_num, -1), id desc
|
||||
</select>
|
||||
</mapper>
|
||||
|
Loading…
Reference in New Issue
Block a user