修改
This commit is contained in:
commit
307a21acac
@ -35,18 +35,14 @@ public class TaskStatusHolder {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// 原子性检查并标记任务开始
|
// 原子性检查并标记任务开始
|
||||||
public boolean startTaskIfAbsent(String key) {
|
public boolean startTaskIfAbsent(String key) {
|
||||||
return taskStatusMap.putIfAbsent(key, "IN_PROGRESS") == null;
|
return taskStatusMap.putIfAbsent(key, "IN_PROGRESS") == null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 标记任务结束
|
// 标记任务结束
|
||||||
public void finishTask(String key) {
|
public void finishTask(String key) {
|
||||||
taskStatusMap.remove(key);
|
taskStatusMap.remove(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取任务状态
|
// 获取任务状态
|
||||||
public String getStatus(String key) {
|
public String getStatus(String key) {
|
||||||
return taskStatusMap.getOrDefault(key, "TASK_NOT_FOUND");
|
return taskStatusMap.getOrDefault(key, "TASK_NOT_FOUND");
|
||||||
|
@ -65,11 +65,13 @@ public class TsFilesController {
|
|||||||
public ResponseResult getTsFilesPage(String id, String fileName, String startDate, String endDate, String keywords, String nodeId, String taskId, String childNode, Page<TsFiles> page) throws Exception {
|
public ResponseResult getTsFilesPage(String id, String fileName, String startDate, String endDate, String keywords, String nodeId, String taskId, String childNode, Page<TsFiles> page) throws Exception {
|
||||||
//分页查询
|
//分页查询
|
||||||
int currentPage = (int) page.getCurrent();
|
int currentPage = (int) page.getCurrent();
|
||||||
// 先尝试从缓存获取
|
// 先尝试从缓存获取 如果搜索条件为空 从Redis获取
|
||||||
if(!StrUtil.isEmpty(id)){
|
if(StrUtil.isBlank(fileName)&&StrUtil.isBlank(keywords) &&StrUtil.isBlank(startDate) &&StrUtil.isBlank(endDate)) {
|
||||||
IPage<TsFiles> cachedPage = tsFilesService.getCachedTsFilesPage(taskId, nodeId, currentPage,id);
|
if (!StrUtil.isEmpty(id)) {
|
||||||
if (cachedPage != null) {
|
IPage<TsFiles> cachedPage = tsFilesService.getCachedTsFilesPage(taskId, nodeId, currentPage, id);
|
||||||
return ResponseResult.successData(cachedPage);
|
if (cachedPage != null) {
|
||||||
|
return ResponseResult.successData(cachedPage);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Page<TsFiles> tsfilesPage = tsFilesService.getTsFilesPage(id, fileName, startDate, endDate, keywords, nodeId, taskId, fileName, childNode, page);
|
Page<TsFiles> tsfilesPage = tsFilesService.getTsFilesPage(id, fileName, startDate, endDate, keywords, nodeId, taskId, fileName, childNode, page);
|
||||||
@ -238,8 +240,6 @@ public class TsFilesController {
|
|||||||
if (StrUtil.isBlank(id)) {
|
if (StrUtil.isBlank(id)) {
|
||||||
return ResponseResult.error("参数为空");
|
return ResponseResult.error("参数为空");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return ResponseResult.success(tsFilesService.decompressionFolder(id, decompressionPath, parentId, path));
|
return ResponseResult.success(tsFilesService.decompressionFolder(id, decompressionPath, parentId, path));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
System.out.print("解压缩异常原因" + e);
|
System.out.print("解压缩异常原因" + e);
|
||||||
@ -619,14 +619,14 @@ public class TsFilesController {
|
|||||||
@Log(module = "实验数据管理", value = "文件自动备份!")
|
@Log(module = "实验数据管理", value = "文件自动备份!")
|
||||||
@PostMapping("/automaticFileBackupByIds")
|
@PostMapping("/automaticFileBackupByIds")
|
||||||
@ApiOperation("自动备份本地文件到备份空间通过ID")
|
@ApiOperation("自动备份本地文件到备份空间通过ID")
|
||||||
public ResponseResult automaticFileBackupByIds(String id) throws IOException {
|
public ResponseResult automaticFileBackupByIds(String id,String taskId, String nodeId) throws IOException {
|
||||||
if (StrUtil.isEmpty(id)) {
|
if (StrUtil.isEmpty(id)) {
|
||||||
return ResponseResult.error("参数为空");
|
return ResponseResult.error("参数为空");
|
||||||
}
|
}
|
||||||
List<String> dataset = StrUtil.split(id, ",");
|
List<String> dataset = StrUtil.split(id, ",");
|
||||||
|
|
||||||
// 生成唯一Key
|
// 生成唯一Key
|
||||||
String asyncKey = taskStatusHolder.generateKeybyId(dataset);
|
String asyncKey = taskStatusHolder.generateKey(taskId, nodeId);
|
||||||
|
|
||||||
// 检查任务是否已存在
|
// 检查任务是否已存在
|
||||||
String existingStatus = taskStatusHolder.getStatus(asyncKey);
|
String existingStatus = taskStatusHolder.getStatus(asyncKey);
|
||||||
@ -638,7 +638,7 @@ public class TsFilesController {
|
|||||||
// 原子性启动新任务
|
// 原子性启动新任务
|
||||||
if (taskStatusHolder.startTaskIfAbsent(asyncKey)) {
|
if (taskStatusHolder.startTaskIfAbsent(asyncKey)) {
|
||||||
// 直接异步执行并推送结果
|
// 直接异步执行并推送结果
|
||||||
tsFilesService.automaticFileBackupAsyncByIds(dataset);
|
tsFilesService.automaticFileBackupAsyncByIds(dataset,taskId,nodeId);
|
||||||
return ResponseResult.success("任务开始处理!");
|
return ResponseResult.success("任务开始处理!");
|
||||||
} else {
|
} else {
|
||||||
return ResponseResult.success("任务已由其他请求启动");
|
return ResponseResult.success("任务已由其他请求启动");
|
||||||
|
@ -4,6 +4,7 @@ package com.yfd.platform.modules.experimentalData.controller;
|
|||||||
import cn.hutool.core.util.ObjUtil;
|
import cn.hutool.core.util.ObjUtil;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import cn.hutool.json.JSONObject;
|
import cn.hutool.json.JSONObject;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
import com.yfd.platform.annotation.Log;
|
import com.yfd.platform.annotation.Log;
|
||||||
import com.yfd.platform.component.TaskStatusHolder;
|
import com.yfd.platform.component.TaskStatusHolder;
|
||||||
import com.yfd.platform.config.ResponseResult;
|
import com.yfd.platform.config.ResponseResult;
|
||||||
@ -183,4 +184,28 @@ public class TsNodesController {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**********************************
|
||||||
|
* 用途说明: 查询可不可以初始化试验任务扫描
|
||||||
|
* 参数说明 taskId 试验任务ID
|
||||||
|
* 返回值说明: com.yfd.platform.config.ResponseResult
|
||||||
|
***********************************/
|
||||||
|
@Log(module = "查询可不可以初始化试验任务扫描", value = "查询可不可以初始化试验任务扫描!")
|
||||||
|
@PostMapping("/selectTsNodesByTskeId")
|
||||||
|
@ApiOperation("查询可不可以初始化试验任务扫描")
|
||||||
|
@PreAuthorize("@el.check('del:tsnodes')")
|
||||||
|
public ResponseResult selectTsNodesByTskeId( String taskId) {
|
||||||
|
if (StrUtil.isBlank(taskId)) {
|
||||||
|
return ResponseResult.error("参数为空");
|
||||||
|
}
|
||||||
|
List<TsNodes> tsNodesList = tsNodesService.list(new QueryWrapper<TsNodes>().eq("task_id", taskId));
|
||||||
|
//如果节点不为空 就不能初始化了
|
||||||
|
if (tsNodesList.size()>0) {
|
||||||
|
return ResponseResult.success("该项目已经初始化完成,局部更新请选择节点上传文件!");
|
||||||
|
} else {
|
||||||
|
return ResponseResult.success("可以初始化!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -247,7 +247,7 @@ public interface ITsFilesService extends IService<TsFiles> {
|
|||||||
|
|
||||||
Object compareMd5List(List<String> dataset, String nodeId, String taskId);
|
Object compareMd5List(List<String> dataset, String nodeId, String taskId);
|
||||||
|
|
||||||
void automaticFileBackupAsyncByIds(List<String> dataset) throws IOException;
|
void automaticFileBackupAsyncByIds(List<String> dataset,String taskId, String nodeId) throws IOException;
|
||||||
|
|
||||||
IPage<TsFiles> getCachedTsFilesPage(String taskId, String nodeId, int currentPage,String id);
|
IPage<TsFiles> getCachedTsFilesPage(String taskId, String nodeId, int currentPage,String id);
|
||||||
}
|
}
|
||||||
|
@ -267,15 +267,14 @@ public class TsFilesServiceImpl extends ServiceImpl<TsFilesMapper, TsFiles> impl
|
|||||||
|
|
||||||
tsFilesPage.setRecords(records); // 同步到 tsFilesPage
|
tsFilesPage.setRecords(records); // 同步到 tsFilesPage
|
||||||
int currentPage = (int) page.getCurrent();
|
int currentPage = (int) page.getCurrent();
|
||||||
// 如果是前五页,将结果存入Redis(有效期建议30分钟)
|
// 如果是前五页,将结果存入Redis(有效期建议30分钟)如果搜索条件为空 从Redis获取
|
||||||
if (!StrUtil.isEmpty(id)) {
|
if (StrUtil.isBlank(fileName) && StrUtil.isBlank(keywords) && StrUtil.isBlank(startDate) && StrUtil.isBlank(endDate)) {
|
||||||
if (currentPage >= 1 && currentPage <= 5) {
|
if (!StrUtil.isEmpty(id)) {
|
||||||
String redisKey = "tsfiles_" + taskId + "_" + nodeId + "_parentId" + id + "_page_" + currentPage + "";
|
if (currentPage >= 1 && currentPage <= 5) {
|
||||||
redisTemplate.opsForValue().set(redisKey, tsFilesPage, 2, TimeUnit.HOURS);
|
String redisKey = "tsfiles_" + taskId + "_" + nodeId + "_parentId" + id + "_page_" + currentPage + "";
|
||||||
|
redisTemplate.opsForValue().set(redisKey, tsFilesPage, 2, TimeUnit.HOURS);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
String redisKey = "tsfiles_" + taskId + "_" + nodeId + "_page_" + currentPage;
|
|
||||||
redisTemplate.delete(redisKey);
|
|
||||||
}
|
}
|
||||||
return tsFilesPage;
|
return tsFilesPage;
|
||||||
|
|
||||||
@ -292,27 +291,50 @@ public class TsFilesServiceImpl extends ServiceImpl<TsFilesMapper, TsFiles> impl
|
|||||||
@Override
|
@Override
|
||||||
public IPage<TsFiles> getCachedTsFilesPage(String taskId, String nodeId, int currentPage, String id) {
|
public IPage<TsFiles> getCachedTsFilesPage(String taskId, String nodeId, int currentPage, String id) {
|
||||||
String redisKey = "tsfiles_" + taskId + "_" + nodeId + "_parentId" + id + "_page_" + currentPage;
|
String redisKey = "tsfiles_" + taskId + "_" + nodeId + "_parentId" + id + "_page_" + currentPage;
|
||||||
|
|
||||||
|
|
||||||
Object data = redisTemplate.opsForValue().get(redisKey);
|
Object data = redisTemplate.opsForValue().get(redisKey);
|
||||||
|
try {
|
||||||
|
if (data instanceof IPage<?>) {
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
IPage<TsFiles> page = (IPage<TsFiles>) data;
|
||||||
|
|
||||||
if (data instanceof IPage<?>) {
|
// 类型校验
|
||||||
// 由于启用了类型信息,可以直接强制转换
|
if (isValidPage(page)) {
|
||||||
@SuppressWarnings("unchecked")
|
return page;
|
||||||
IPage<TsFiles> page = (IPage<TsFiles>) data;
|
}
|
||||||
// 检查 records 是否已正确反序列化
|
|
||||||
if (page.getRecords() != null && !page.getRecords().isEmpty()
|
|
||||||
&& page.getRecords().get(0) instanceof TsFiles) {
|
|
||||||
return page;
|
|
||||||
} else {
|
|
||||||
// 处理可能的反序列化异常
|
|
||||||
throw new IllegalStateException("反序列化失败,records 类型不正确");
|
|
||||||
}
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
// 记录异常日志(关键!)
|
||||||
|
LOGGER.error("反序列化失败,删除缓存: {}", redisKey, e);
|
||||||
|
|
||||||
|
// 异步删除缓存,避免阻塞主流程
|
||||||
|
CompletableFuture.runAsync(() -> redisTemplate.delete(redisKey));
|
||||||
}
|
}
|
||||||
return null;
|
|
||||||
|
return null; // 或返回空分页对象 new Page<>(0)
|
||||||
|
|
||||||
|
// if (data instanceof IPage<?>) {
|
||||||
|
// // 由于启用了类型信息,可以直接强制转换
|
||||||
|
// @SuppressWarnings("unchecked")
|
||||||
|
// IPage<TsFiles> page = (IPage<TsFiles>) data;
|
||||||
|
// // 检查 records 是否已正确反序列化
|
||||||
|
// if (page.getRecords() != null && !page.getRecords().isEmpty()
|
||||||
|
// && page.getRecords().get(0) instanceof TsFiles) {
|
||||||
|
// return page;
|
||||||
|
// } else {
|
||||||
|
// // 处理可能的反序列化异常
|
||||||
|
// throw new IllegalStateException("反序列化失败,records 类型不正确");
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private boolean isValidPage(IPage<TsFiles> page) {
|
||||||
|
return page.getRecords() != null
|
||||||
|
&& !page.getRecords().isEmpty()
|
||||||
|
&& page.getRecords().get(0) instanceof TsFiles;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean hasValidExtension(String name, List<SysDictionaryItems> sysDictionaryItems) {
|
public boolean hasValidExtension(String name, List<SysDictionaryItems> sysDictionaryItems) {
|
||||||
// 如果传入的文件名为空,返回 false
|
// 如果传入的文件名为空,返回 false
|
||||||
if (name == null) {
|
if (name == null) {
|
||||||
@ -417,8 +439,6 @@ public class TsFilesServiceImpl extends ServiceImpl<TsFilesMapper, TsFiles> impl
|
|||||||
//todo 新增成功以后 删除redis
|
//todo 新增成功以后 删除redis
|
||||||
for (int page = 1; page <= 5; page++) {
|
for (int page = 1; page <= 5; page++) {
|
||||||
String redisKey = "tsfiles_" + tsFiles.getTaskId() + "_" + tsFiles.getNodeId() + "_parentId" + tsFiles.getParentId() + "_page_" + page;
|
String redisKey = "tsfiles_" + tsFiles.getTaskId() + "_" + tsFiles.getNodeId() + "_parentId" + tsFiles.getParentId() + "_page_" + page;
|
||||||
|
|
||||||
|
|
||||||
redisTemplate.delete(redisKey);
|
redisTemplate.delete(redisKey);
|
||||||
}
|
}
|
||||||
LOGGER.info("已清理缓存:taskid={}, node={}, pages=1-5", tsFiles.getTaskId(), tsFiles.getNodeId());
|
LOGGER.info("已清理缓存:taskid={}, node={}, pages=1-5", tsFiles.getTaskId(), tsFiles.getNodeId());
|
||||||
@ -658,7 +678,7 @@ public class TsFilesServiceImpl extends ServiceImpl<TsFilesMapper, TsFiles> impl
|
|||||||
@Transactional(rollbackFor = Exception.class)// 添加事务注解,遇到异常时回滚
|
@Transactional(rollbackFor = Exception.class)// 添加事务注解,遇到异常时回滚
|
||||||
public ResponseResult updateTsFiles(TsFiles tsFiles) {
|
public ResponseResult updateTsFiles(TsFiles tsFiles) {
|
||||||
|
|
||||||
//todo 新增成功以后 删除redis
|
//todo 修改成功以后 删除redis
|
||||||
for (int page = 1; page <= 5; page++) {
|
for (int page = 1; page <= 5; page++) {
|
||||||
String redisKey = "tsfiles_" + tsFiles.getTaskId() + "_" + tsFiles.getNodeId() + "_parentId" + tsFiles.getParentId() + "_page_" + page;
|
String redisKey = "tsfiles_" + tsFiles.getTaskId() + "_" + tsFiles.getNodeId() + "_parentId" + tsFiles.getParentId() + "_page_" + page;
|
||||||
redisTemplate.delete(redisKey);
|
redisTemplate.delete(redisKey);
|
||||||
@ -939,10 +959,19 @@ public class TsFilesServiceImpl extends ServiceImpl<TsFilesMapper, TsFiles> impl
|
|||||||
public String deleteTsFilesByIds(List<String> dataset, String type) {
|
public String deleteTsFilesByIds(List<String> dataset, String type) {
|
||||||
List<TsFiles> filesList = tsFilesMapper.selectBatchIds(dataset);
|
List<TsFiles> filesList = tsFilesMapper.selectBatchIds(dataset);
|
||||||
|
|
||||||
|
//todo 删除的时候成功以后 删除redis
|
||||||
|
for (int page = 1; page <= 5; page++) {
|
||||||
|
String redisKey = "tsfiles_" + filesList.get(0).getTaskId() + "_" + filesList.get(0).getNodeId() + "_parentId" + filesList.get(0).getParentId() + "_page_" + page;
|
||||||
|
redisTemplate.delete(redisKey);
|
||||||
|
}
|
||||||
|
LOGGER.info("已清理缓存:taskid={}, node={}, pages=1-5", filesList.get(0).getTaskId(), filesList.get(0).getNodeId());
|
||||||
|
|
||||||
|
|
||||||
int LocalSuccessCount = 0, LocalFailCount = 0, Localtotal = CollUtil.size(dataset);
|
int LocalSuccessCount = 0, LocalFailCount = 0, Localtotal = CollUtil.size(dataset);
|
||||||
//Todo 最直接的办法 循环出来 一条一条删除
|
//Todo 最直接的办法 循环出来 一条一条删除
|
||||||
for (TsFiles files : filesList) {
|
for (TsFiles files : filesList) {
|
||||||
|
|
||||||
|
|
||||||
//判断是文件还是文件夹
|
//判断是文件还是文件夹
|
||||||
if ("FOLDER".equals(files.getIsFile())) {
|
if ("FOLDER".equals(files.getIsFile())) {
|
||||||
//如果是文件夹
|
//如果是文件夹
|
||||||
@ -1233,6 +1262,15 @@ public class TsFilesServiceImpl extends ServiceImpl<TsFilesMapper, TsFiles> impl
|
|||||||
try {
|
try {
|
||||||
String finalParentId = ensureFullPathExists(compressedPath, filesList.get(0).getNodeId(), filesList.get(0).getTaskId(), path);
|
String finalParentId = ensureFullPathExists(compressedPath, filesList.get(0).getNodeId(), filesList.get(0).getTaskId(), path);
|
||||||
parentId = finalParentId;
|
parentId = finalParentId;
|
||||||
|
LOGGER.info("压缩的时候删除Redis");
|
||||||
|
//todo 压缩的时候删除Redis
|
||||||
|
if (!parentId.equals("00")) {
|
||||||
|
for (int page = 1; page <= 5; page++) {
|
||||||
|
String redisKey = "tsfiles_" + filesList.get(0).getTaskId() + "_" + filesList.get(0).getNodeId() + "_parentId" + parentId + "_page_" + page;
|
||||||
|
redisTemplate.delete(redisKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
LOGGER.info("路径已全部存在,最终目录ID: {}", finalParentId);
|
LOGGER.info("路径已全部存在,最终目录ID: {}", finalParentId);
|
||||||
} catch (RuntimeException e) {
|
} catch (RuntimeException e) {
|
||||||
LOGGER.error("路径创建失败: {}", e.getMessage());
|
LOGGER.error("路径创建失败: {}", e.getMessage());
|
||||||
@ -1840,6 +1878,16 @@ public class TsFilesServiceImpl extends ServiceImpl<TsFilesMapper, TsFiles> impl
|
|||||||
try {
|
try {
|
||||||
String finalParentId = ensureFullPathExists(decompressionPath, zipFileRecord.getNodeId(), zipFileRecord.getTaskId(), path);
|
String finalParentId = ensureFullPathExists(decompressionPath, zipFileRecord.getNodeId(), zipFileRecord.getTaskId(), path);
|
||||||
parentId = finalParentId;
|
parentId = finalParentId;
|
||||||
|
|
||||||
|
LOGGER.info("解压缩的时候删除Redis");
|
||||||
|
//todo 解压缩的时候删除Redis
|
||||||
|
if (!parentId.equals("00")) {
|
||||||
|
for (int page = 1; page <= 5; page++) {
|
||||||
|
String redisKey = "tsfiles_" + zipFileRecord.getTaskId() + "_" + zipFileRecord.getNodeId() + "_parentId" + parentId + "_page_" + page;
|
||||||
|
redisTemplate.delete(redisKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
LOGGER.info("路径已全部存在,最终目录ID: {}", finalParentId);
|
LOGGER.info("路径已全部存在,最终目录ID: {}", finalParentId);
|
||||||
} catch (RuntimeException e) {
|
} catch (RuntimeException e) {
|
||||||
LOGGER.error("路径创建失败: {}", e.getMessage());
|
LOGGER.error("路径创建失败: {}", e.getMessage());
|
||||||
@ -1910,7 +1958,7 @@ public class TsFilesServiceImpl extends ServiceImpl<TsFilesMapper, TsFiles> impl
|
|||||||
TsFiles fileRecord = createFileRecord(
|
TsFiles fileRecord = createFileRecord(
|
||||||
file.getName(),
|
file.getName(),
|
||||||
parentId,
|
parentId,
|
||||||
buildFolderPath(decompressionPath),
|
buildFolderPath(extractPath),
|
||||||
zipFileRecord.getTaskId(),
|
zipFileRecord.getTaskId(),
|
||||||
zipFileRecord.getNodeId(),
|
zipFileRecord.getNodeId(),
|
||||||
zipFileRecord.getUploader(),
|
zipFileRecord.getUploader(),
|
||||||
@ -3375,22 +3423,22 @@ public class TsFilesServiceImpl extends ServiceImpl<TsFilesMapper, TsFiles> impl
|
|||||||
String asyncKey = taskStatusHolder.generateKey(taskId, nodeId);
|
String asyncKey = taskStatusHolder.generateKey(taskId, nodeId);
|
||||||
// 无论成功失败都标记完成
|
// 无论成功失败都标记完成
|
||||||
taskStatusHolder.finishTask(asyncKey);
|
taskStatusHolder.finishTask(asyncKey);
|
||||||
WebSocketServer.sendMessageTo("文件自动备份完成", "backups");
|
WebSocketServer.sendMessageTo("文件自动备份完成", "taskId_" + taskId + "_" + "nodeId_" + nodeId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Async("asyncExecutor")
|
@Async("asyncExecutor")
|
||||||
public void automaticFileBackupAsyncByIds(List<String> dataset) throws IOException {
|
public void automaticFileBackupAsyncByIds(List<String> dataset, String taskId, String nodeId) throws IOException {
|
||||||
try {
|
try {
|
||||||
// 执行实际备份逻辑
|
// 执行实际备份逻辑
|
||||||
this.automaticFileBackupByIds(dataset);
|
this.automaticFileBackupByIds(dataset);
|
||||||
} finally {
|
} finally {
|
||||||
// 生成唯一Key
|
// 生成唯一Key
|
||||||
String asyncKey = taskStatusHolder.generateKeybyId(dataset);
|
String asyncKey = taskStatusHolder.generateKey(taskId, nodeId);
|
||||||
// 无论成功失败都标记完成
|
// 无论成功失败都标记完成
|
||||||
taskStatusHolder.finishTask(asyncKey);
|
taskStatusHolder.finishTask(asyncKey);
|
||||||
WebSocketServer.sendMessageTo("文件自动备份完成", "backups");
|
WebSocketServer.sendMessageTo("文件自动备份完成", "taskId_" + taskId + "_" + "nodeId_" + nodeId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3891,6 +3939,16 @@ public class TsFilesServiceImpl extends ServiceImpl<TsFilesMapper, TsFiles> impl
|
|||||||
*/
|
*/
|
||||||
private void updateDatabase(String parentId, String oldpaths, String fileName,
|
private void updateDatabase(String parentId, String oldpaths, String fileName,
|
||||||
String newPath, String targetFileName, String type) {
|
String newPath, String targetFileName, String type) {
|
||||||
|
TsFiles tsFilesData = tsFilesMapper.selectById(parentId);
|
||||||
|
LOGGER.info("移动的时候删除Redis");
|
||||||
|
//todo 移动的时候成功以后 删除redis
|
||||||
|
if (!parentId.equals("00")) {
|
||||||
|
for (int page = 1; page <= 5; page++) {
|
||||||
|
String redisKey = "tsfiles_" + tsFilesData.getTaskId() + "_" + tsFilesData.getNodeId() + "_parentId" + parentId + "_page_" + page;
|
||||||
|
redisTemplate.delete(redisKey);
|
||||||
|
}
|
||||||
|
LOGGER.info("已清理缓存:taskid={}, node={}, pages=1-5", tsFilesData.getTaskId(), tsFilesData.getNodeId());
|
||||||
|
}
|
||||||
// 1. 构建完整路径
|
// 1. 构建完整路径
|
||||||
String oldWorkPath = oldpaths.endsWith("/") ? oldpaths : oldpaths + "/";
|
String oldWorkPath = oldpaths.endsWith("/") ? oldpaths : oldpaths + "/";
|
||||||
String newWorkPath = newPath.endsWith("/") ? newPath : newPath + "/";
|
String newWorkPath = newPath.endsWith("/") ? newPath : newPath + "/";
|
||||||
@ -4127,6 +4185,17 @@ public class TsFilesServiceImpl extends ServiceImpl<TsFilesMapper, TsFiles> impl
|
|||||||
*/
|
*/
|
||||||
private void insertDatabaseRecord(String parentId, String oldpaths, String fileName,
|
private void insertDatabaseRecord(String parentId, String oldpaths, String fileName,
|
||||||
String newPath, String targetFileName, String type) {
|
String newPath, String targetFileName, String type) {
|
||||||
|
|
||||||
|
TsFiles tsFilesData = tsFilesMapper.selectById(parentId);
|
||||||
|
LOGGER.info("复制的时候删除Redis");
|
||||||
|
//todo 复制的时候成功以后 删除redis
|
||||||
|
if (!parentId.equals("00")) {
|
||||||
|
for (int page = 1; page <= 5; page++) {
|
||||||
|
String redisKey = "tsfiles_" + tsFilesData.getTaskId() + "_" + tsFilesData.getNodeId() + "_parentId" + parentId + "_page_" + page;
|
||||||
|
redisTemplate.delete(redisKey);
|
||||||
|
}
|
||||||
|
LOGGER.info("已清理缓存:taskid={}, node={}, pages=1-5", tsFilesData.getTaskId(), tsFilesData.getNodeId());
|
||||||
|
}
|
||||||
// 获取用户信息
|
// 获取用户信息
|
||||||
// 获取当前用户和时间
|
// 获取当前用户和时间
|
||||||
UsernamePasswordAuthenticationToken authentication =
|
UsernamePasswordAuthenticationToken authentication =
|
||||||
|
@ -477,11 +477,23 @@ public class TsNodesServiceImpl extends ServiceImpl<TsNodesMapper, TsNodes> impl
|
|||||||
|
|
||||||
//批量修改
|
//批量修改
|
||||||
LambdaUpdateWrapper<TsFiles> updateWrapper1 = new LambdaUpdateWrapper<>();
|
LambdaUpdateWrapper<TsFiles> updateWrapper1 = new LambdaUpdateWrapper<>();
|
||||||
updateWrapper1.in(TsFiles::getId,dataset).isNotNull(TsFiles::getBackupPath).ne(TsFiles::getBackupPath,"").set(TsFiles::getWorkPath, "");
|
updateWrapper1.in(TsFiles::getId, dataset).set(TsFiles::getWorkPath, "");
|
||||||
tsFilesMapper.update(null, updateWrapper1);
|
tsFilesMapper.update(null, updateWrapper1);
|
||||||
//批量删除
|
//批量删除
|
||||||
|
// LambdaQueryWrapper<TsFiles> deleteWrapper = new LambdaQueryWrapper<>();
|
||||||
|
// deleteWrapper.in(TsFiles::getId, dataset).isNull(TsFiles::getBackupPath).eq(TsFiles::getBackupPath, "").isNull(TsFiles::getWorkPath).eq(TsFiles::getWorkPath, "");
|
||||||
|
// tsFilesMapper.delete(deleteWrapper);
|
||||||
|
//
|
||||||
|
// LambdaQueryWrapper<TsFiles> deleteWrapper = new LambdaQueryWrapper<>();
|
||||||
|
// deleteWrapper.in(TsFiles::getId, dataset)
|
||||||
|
// .and(wrapper -> wrapper.isNull(TsFiles::getBackupPath).or().eq(TsFiles::getBackupPath, ""))
|
||||||
|
// .and(wrapper -> wrapper.isNull(TsFiles::getWorkPath).or().eq(TsFiles::getWorkPath, ""));
|
||||||
|
// tsFilesMapper.delete(deleteWrapper);
|
||||||
|
|
||||||
LambdaQueryWrapper<TsFiles> deleteWrapper = new LambdaQueryWrapper<>();
|
LambdaQueryWrapper<TsFiles> deleteWrapper = new LambdaQueryWrapper<>();
|
||||||
deleteWrapper.in(TsFiles::getId,dataset).isNull(TsFiles::getBackupPath).eq(TsFiles::getBackupPath,"").isNull(TsFiles::getWorkPath).eq(TsFiles::getWorkPath,"");
|
deleteWrapper.in(TsFiles::getId, dataset)
|
||||||
|
.and(wrapper -> wrapper.isNull(TsFiles::getBackupPath).or().eq(TsFiles::getBackupPath, ""))
|
||||||
|
.and(wrapper -> wrapper.isNull(TsFiles::getWorkPath).or().eq(TsFiles::getWorkPath, ""));
|
||||||
tsFilesMapper.delete(deleteWrapper);
|
tsFilesMapper.delete(deleteWrapper);
|
||||||
|
|
||||||
// //批量修改TsFiles表结构
|
// //批量修改TsFiles表结构
|
||||||
@ -777,17 +789,13 @@ public class TsNodesServiceImpl extends ServiceImpl<TsNodesMapper, TsNodes> impl
|
|||||||
LocalDateTime now = LocalDateTime.now();
|
LocalDateTime now = LocalDateTime.now();
|
||||||
// 转换为 Timestamp
|
// 转换为 Timestamp
|
||||||
Timestamp currentTime = Timestamp.valueOf(now);
|
Timestamp currentTime = Timestamp.valueOf(now);
|
||||||
|
|
||||||
|
|
||||||
// 查询本地文件路径根目录(如 E:\yun)
|
// 查询本地文件路径根目录(如 E:\yun)
|
||||||
QueryWrapper<StorageSourceConfig> queryWrapper = new QueryWrapper<>();
|
QueryWrapper<StorageSourceConfig> queryWrapper = new QueryWrapper<>();
|
||||||
queryWrapper.eq("name", "filePath");
|
queryWrapper.eq("name", "filePath");
|
||||||
queryWrapper.eq("type", "local");
|
queryWrapper.eq("type", "local");
|
||||||
StorageSourceConfig storageSourceConfig = storageSourceConfigMapper.selectOne(queryWrapper);
|
StorageSourceConfig storageSourceConfig = storageSourceConfigMapper.selectOne(queryWrapper);
|
||||||
|
|
||||||
//获取文件列表 这个地方path+name
|
//获取文件列表 这个地方path+name
|
||||||
File projectDir = new File(storageSourceConfig.getValue() + path + nodeName);
|
File projectDir = new File(storageSourceConfig.getValue() + path + nodeName);
|
||||||
|
|
||||||
// 获取所有子目录
|
// 获取所有子目录
|
||||||
List<File> allSubDirs = new ArrayList<>();
|
List<File> allSubDirs = new ArrayList<>();
|
||||||
getAllSubDirectories(projectDir, allSubDirs);
|
getAllSubDirectories(projectDir, allSubDirs);
|
||||||
@ -899,88 +907,6 @@ public class TsNodesServiceImpl extends ServiceImpl<TsNodesMapper, TsNodes> impl
|
|||||||
long costTimeFiles = endTimeFiles - startTimeFiles;
|
long costTimeFiles = endTimeFiles - startTimeFiles;
|
||||||
// 打印日志
|
// 打印日志
|
||||||
LOGGER.info("文件表中的节点ID更新完成,影响 {} 行,总耗时 {} 毫秒", affectedLevelFilesRows, costTimeFiles);
|
LOGGER.info("文件表中的节点ID更新完成,影响 {} 行,总耗时 {} 毫秒", affectedLevelFilesRows, costTimeFiles);
|
||||||
|
|
||||||
|
|
||||||
// //获取文件列表
|
|
||||||
// String absolutePath =path + "/" + nodeName + "/";
|
|
||||||
// //获取当前登录用户 上传人是当前登录人
|
|
||||||
// UsernamePasswordAuthenticationToken authentication =
|
|
||||||
// (UsernamePasswordAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
|
|
||||||
// LoginUser loginuser = null;
|
|
||||||
// if (authentication != null) {
|
|
||||||
// loginuser = (LoginUser) authentication.getPrincipal();
|
|
||||||
// }
|
|
||||||
// //登录人
|
|
||||||
// String uploader = null;
|
|
||||||
// if (loginuser != null) {
|
|
||||||
// uploader = loginuser.getUsername();
|
|
||||||
// }
|
|
||||||
// // 设置当前时间
|
|
||||||
// LocalDateTime now = LocalDateTime.now();
|
|
||||||
// // 转换为 Timestamp
|
|
||||||
// Timestamp currentTime = Timestamp.valueOf(now);
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// //获取文件列表
|
|
||||||
// FileListRequest fileListRequest = buildFileRequest(absolutePath);
|
|
||||||
// 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());
|
|
||||||
//
|
|
||||||
// for (FileItemResult item : fileItemList) {
|
|
||||||
// //思路就是 如果是文件夹 就查询一下 没有就新增, 新的的时候递归往下走
|
|
||||||
// if (item.getType() == FileTypeEnum.FOLDER) {
|
|
||||||
// //先查询有没有 如果没有就新增 条件 节点ID 任务ID 上级ID 工作空间路径 文件名称
|
|
||||||
// LambdaQueryWrapper<TsFiles> queryWrapper1 = new LambdaQueryWrapper<>();
|
|
||||||
// queryWrapper1.eq(TsFiles::getTaskId, taskId);
|
|
||||||
// queryWrapper1.eq(TsFiles::getNodeId, nodeId);
|
|
||||||
// queryWrapper1.eq(TsFiles::getParentId, parentId);
|
|
||||||
// queryWrapper1.eq(TsFiles::getFileName, item.getName());
|
|
||||||
// queryWrapper1.eq(TsFiles::getWorkPath, item.getPath());
|
|
||||||
// TsFiles tsFiles = tsFilesMapper.selectOne(queryWrapper1);
|
|
||||||
// //如果没有 新增 并且递归
|
|
||||||
// if (tsFiles == null) {
|
|
||||||
// //保存文件
|
|
||||||
// TsFiles tsFilesData = savetsFiles(taskId, nodeId, item.getName(), item.getPath(), parentId, "FOLDER", String.valueOf(item.getSize()));
|
|
||||||
// otherLevelsData(taskId, nodeId, item.getName(), item.getPath(), tsFilesData.getId());
|
|
||||||
//
|
|
||||||
// } else {
|
|
||||||
// otherLevelsData(taskId, nodeId, item.getName(), item.getPath(), tsFiles.getId());
|
|
||||||
// }
|
|
||||||
// } else {
|
|
||||||
// //todo 如果是文件 直接新增就可以了 不需要其他的操作
|
|
||||||
// //先查询有没有 如果没有就新增 条件 节点ID 任务ID 上级ID 工作空间路径 文件名称
|
|
||||||
// LambdaQueryWrapper<TsFiles> queryWrapper2 = new LambdaQueryWrapper<>();
|
|
||||||
// queryWrapper2.eq(TsFiles::getTaskId, taskId);
|
|
||||||
// queryWrapper2.eq(TsFiles::getNodeId, nodeId);
|
|
||||||
// queryWrapper2.eq(TsFiles::getParentId, parentId);
|
|
||||||
// queryWrapper2.eq(TsFiles::getFileName, item.getName());
|
|
||||||
// queryWrapper2.eq(TsFiles::getWorkPath, item.getPath());
|
|
||||||
// TsFiles tsFiles = tsFilesMapper.selectOne(queryWrapper2);
|
|
||||||
// if (tsFiles == null) {
|
|
||||||
//
|
|
||||||
// // 获取文件大小(字节)
|
|
||||||
// long fileSizeInBytes = item.getSize();
|
|
||||||
// // 转换为 MB 并保留两位小数
|
|
||||||
// double fileSizeInMB = fileSizeInBytes / (1024.0 * 1024.0);
|
|
||||||
// String fileSizeFormatted = String.format("%.2f", fileSizeInMB); // 保留两位小数
|
|
||||||
//
|
|
||||||
// //保存文件信息
|
|
||||||
// TsFiles tsFilesData = savetsFiles(taskId, nodeId, item.getName(), item.getPath(), parentId, "FILE", fileSizeFormatted);
|
|
||||||
// LOGGER.info("保存文件信息:{}", item.getPath() + item.getName());
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -56,11 +56,13 @@ public class FilesController {
|
|||||||
public ResponseResult getFilesPage(String fileName, String startDate, String endDate, String keywords, String nodeId,String projectId, Page<Files> page) throws Exception {
|
public ResponseResult getFilesPage(String fileName, String startDate, String endDate, String keywords, String nodeId,String projectId, Page<Files> page) throws Exception {
|
||||||
//分页查询
|
//分页查询
|
||||||
int currentPage = (int) page.getCurrent();
|
int currentPage = (int) page.getCurrent();
|
||||||
// 先尝试从缓存获取
|
// 先尝试从缓存获取 如果搜索条件为空 从Redis获取
|
||||||
IPage<Files> cachedFilesPage = filesService.getCachedFilesPage(projectId, nodeId,currentPage );
|
if(StrUtil.isBlank(fileName)&&StrUtil.isBlank(keywords) &&StrUtil.isBlank(startDate) &&StrUtil.isBlank(endDate)){
|
||||||
if (cachedFilesPage != null){
|
IPage<Files> cachedFilesPage = filesService.getCachedFilesPage(projectId, nodeId,currentPage);
|
||||||
return ResponseResult.successData(cachedFilesPage);
|
if (cachedFilesPage != null){
|
||||||
}
|
return ResponseResult.successData(cachedFilesPage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Page<Files> filesPage = filesService.getFilesPage(fileName, startDate, endDate, keywords, nodeId, projectId, fileName, page);
|
Page<Files> filesPage = filesService.getFilesPage(fileName, startDate, endDate, keywords, nodeId, projectId, fileName, page);
|
||||||
return ResponseResult.successData(filesPage);
|
return ResponseResult.successData(filesPage);
|
||||||
@ -71,6 +73,8 @@ public class FilesController {
|
|||||||
* 用途说明:新增专项文档管理-文档内容
|
* 用途说明:新增专项文档管理-文档内容
|
||||||
* 参数说明
|
* 参数说明
|
||||||
* Files 文档内容
|
* Files 文档内容
|
||||||
|
* sourcePath 源路径
|
||||||
|
* targetPath 目标路径
|
||||||
* 返回值说明: com.yfd.platform.config.ResponseResult 返回新增成功或者失败
|
* 返回值说明: com.yfd.platform.config.ResponseResult 返回新增成功或者失败
|
||||||
***********************************/
|
***********************************/
|
||||||
@Log(module = "专项文档管理", value = "新增专项文档管理文档内容!")
|
@Log(module = "专项文档管理", value = "新增专项文档管理文档内容!")
|
||||||
@ -78,7 +82,7 @@ public class FilesController {
|
|||||||
@ApiOperation("新增专项文档管理文档内容")
|
@ApiOperation("新增专项文档管理文档内容")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
@PreAuthorize("@el.check('add:files')")
|
@PreAuthorize("@el.check('add:files')")
|
||||||
public ResponseResult addFiles(@RequestBody Files files) {
|
public ResponseResult addFiles(@RequestBody Files files) throws Exception {
|
||||||
//对象不能为空
|
//对象不能为空
|
||||||
if (ObjUtil.isEmpty(files)) {
|
if (ObjUtil.isEmpty(files)) {
|
||||||
return ResponseResult.error("参数为空");
|
return ResponseResult.error("参数为空");
|
||||||
|
@ -5,10 +5,12 @@ import cn.hutool.core.util.ObjUtil;
|
|||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import cn.hutool.json.JSONArray;
|
import cn.hutool.json.JSONArray;
|
||||||
import cn.hutool.json.JSONObject;
|
import cn.hutool.json.JSONObject;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
import com.yfd.platform.annotation.Log;
|
import com.yfd.platform.annotation.Log;
|
||||||
import com.yfd.platform.component.TaskStatusHolder;
|
import com.yfd.platform.component.TaskStatusHolder;
|
||||||
import com.yfd.platform.component.WebSocketServer;
|
import com.yfd.platform.component.WebSocketServer;
|
||||||
import com.yfd.platform.config.ResponseResult;
|
import com.yfd.platform.config.ResponseResult;
|
||||||
|
import com.yfd.platform.modules.experimentalData.domain.TsNodes;
|
||||||
import com.yfd.platform.modules.specialDocument.domain.Nodes;
|
import com.yfd.platform.modules.specialDocument.domain.Nodes;
|
||||||
import com.yfd.platform.modules.specialDocument.service.INodesService;
|
import com.yfd.platform.modules.specialDocument.service.INodesService;
|
||||||
import io.swagger.annotations.ApiOperation;
|
import io.swagger.annotations.ApiOperation;
|
||||||
@ -246,4 +248,25 @@ public class NodesController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**********************************
|
||||||
|
* 用途说明: 查询可不可以初始化专项文档扫描
|
||||||
|
* 参数说明 projectId 所属项目ID
|
||||||
|
* 返回值说明: com.yfd.platform.config.ResponseResult
|
||||||
|
***********************************/
|
||||||
|
@Log(module = "查询可不可以初始化专项文档扫描", value = "查询可不可以初始化专项文档扫描!")
|
||||||
|
@PostMapping("/selectNodesByProjectId")
|
||||||
|
@ApiOperation("查询可不可以初始化专项文档扫描")
|
||||||
|
public ResponseResult selectNodesByProjectId( String projectId) {
|
||||||
|
if (StrUtil.isBlank(projectId)) {
|
||||||
|
return ResponseResult.error("参数为空");
|
||||||
|
}
|
||||||
|
List<Nodes> nodesList = nodesService.list(new QueryWrapper<Nodes>().eq("project_id", projectId));
|
||||||
|
//如果节点不为空 就不能初始化了
|
||||||
|
if (nodesList.size()>0) {
|
||||||
|
return ResponseResult.success("该项目已经初始化完成,局部更新请选择节点上传文件!");
|
||||||
|
} else {
|
||||||
|
return ResponseResult.success("可以初始化!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -111,4 +111,16 @@ public class Files implements Serializable {
|
|||||||
@TableField(exist = false)
|
@TableField(exist = false)
|
||||||
private String type;
|
private String type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 源路径:TODO 增加用于前端展示
|
||||||
|
*/
|
||||||
|
@TableField(exist = false)
|
||||||
|
private String sourcePath;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 目标路径:TODO 增加用于前端展示
|
||||||
|
*/
|
||||||
|
@TableField(exist = false)
|
||||||
|
private String targetPath;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -39,9 +39,11 @@ public interface IFilesService extends IService<Files> {
|
|||||||
* 用途说明:新增专项文档管理-文档内容
|
* 用途说明:新增专项文档管理-文档内容
|
||||||
* 参数说明
|
* 参数说明
|
||||||
* Files 文档内容
|
* Files 文档内容
|
||||||
|
* sourcePath 源路径
|
||||||
|
* targetPath 目标路径
|
||||||
* 返回值说明: com.yfd.platform.config.ResponseResult 返回新增成功或者失败
|
* 返回值说明: com.yfd.platform.config.ResponseResult 返回新增成功或者失败
|
||||||
***********************************/
|
***********************************/
|
||||||
ResponseResult addFiles(Files files);
|
ResponseResult addFiles(Files files) throws Exception;
|
||||||
|
|
||||||
/**********************************
|
/**********************************
|
||||||
* 用途说明: 修改专项文档管理-文档内容
|
* 用途说明: 修改专项文档管理-文档内容
|
||||||
|
@ -3,6 +3,8 @@ package com.yfd.platform.modules.specialDocument.service.impl;
|
|||||||
import cn.hutool.core.collection.CollUtil;
|
import cn.hutool.core.collection.CollUtil;
|
||||||
import cn.hutool.core.date.DateTime;
|
import cn.hutool.core.date.DateTime;
|
||||||
import cn.hutool.core.date.DateUtil;
|
import cn.hutool.core.date.DateUtil;
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import cn.hutool.json.JSONObject;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
@ -20,6 +22,8 @@ import com.yfd.platform.modules.storage.chain.FileChain;
|
|||||||
import com.yfd.platform.modules.storage.chain.FileContext;
|
import com.yfd.platform.modules.storage.chain.FileContext;
|
||||||
import com.yfd.platform.modules.storage.context.StorageSourceContext;
|
import com.yfd.platform.modules.storage.context.StorageSourceContext;
|
||||||
import com.yfd.platform.modules.storage.controller.file.FileController;
|
import com.yfd.platform.modules.storage.controller.file.FileController;
|
||||||
|
import com.yfd.platform.modules.storage.mapper.StorageSourceConfigMapper;
|
||||||
|
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.enums.FileTypeEnum;
|
||||||
import com.yfd.platform.modules.storage.model.request.BatchDeleteRequest;
|
import com.yfd.platform.modules.storage.model.request.BatchDeleteRequest;
|
||||||
import com.yfd.platform.modules.storage.model.request.RenameFileRequest;
|
import com.yfd.platform.modules.storage.model.request.RenameFileRequest;
|
||||||
@ -30,6 +34,10 @@ import com.yfd.platform.modules.storage.service.base.AbstractBaseFileService;
|
|||||||
import com.yfd.platform.system.domain.LoginUser;
|
import com.yfd.platform.system.domain.LoginUser;
|
||||||
import com.yfd.platform.utils.StringUtils;
|
import com.yfd.platform.utils.StringUtils;
|
||||||
import io.netty.channel.ChannelInboundHandlerAdapter;
|
import io.netty.channel.ChannelInboundHandlerAdapter;
|
||||||
|
import org.apache.commons.codec.binary.Hex;
|
||||||
|
import org.apache.commons.io.FileUtils;
|
||||||
|
import org.apache.commons.io.FilenameUtils;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
@ -41,8 +49,17 @@ import org.springframework.transaction.annotation.Transactional;
|
|||||||
import com.fasterxml.jackson.core.type.TypeReference;
|
import com.fasterxml.jackson.core.type.TypeReference;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.security.MessageDigest;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.sql.Timestamp;
|
import java.sql.Timestamp;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -82,6 +99,9 @@ public class FilesServiceImpl extends ServiceImpl<FilesMapper, Files> implements
|
|||||||
@Autowired
|
@Autowired
|
||||||
private RedisTemplate<String, Object> redisTemplate;
|
private RedisTemplate<String, Object> redisTemplate;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private StorageSourceConfigMapper storageSourceConfigMapper;
|
||||||
|
|
||||||
|
|
||||||
/**********************************
|
/**********************************
|
||||||
* 用途说明: 分页查询专项文档管理-文档内容
|
* 用途说明: 分页查询专项文档管理-文档内容
|
||||||
@ -189,9 +209,11 @@ public class FilesServiceImpl extends ServiceImpl<FilesMapper, Files> implements
|
|||||||
filesPage.setRecords(records);
|
filesPage.setRecords(records);
|
||||||
int currentPage = (int) page.getCurrent();
|
int currentPage = (int) page.getCurrent();
|
||||||
// 如果是前五页,将结果存入Redis(有效期建议30分钟)
|
// 如果是前五页,将结果存入Redis(有效期建议30分钟)
|
||||||
if (currentPage >= 1 && currentPage <= 5) {
|
if (StrUtil.isBlank(fileName) && StrUtil.isBlank(keywords) && StrUtil.isBlank(startDate) && StrUtil.isBlank(endDate)) {
|
||||||
String redisKey = "sdfiles_" + projectId + "_" + nodeId + "_page_" + currentPage;
|
if (currentPage >= 1 && currentPage <= 5) {
|
||||||
redisTemplate.opsForValue().set(redisKey, filesPage, 2, TimeUnit.HOURS);
|
String redisKey = "sdfiles_" + projectId + "_" + nodeId + "_page_" + currentPage;
|
||||||
|
redisTemplate.opsForValue().set(redisKey, filesPage, 2, TimeUnit.HOURS);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return filesPage;
|
return filesPage;
|
||||||
}
|
}
|
||||||
@ -229,6 +251,7 @@ public class FilesServiceImpl extends ServiceImpl<FilesMapper, Files> implements
|
|||||||
|
|
||||||
return null; // 或返回空分页对象 new Page<>(0)
|
return null; // 或返回空分页对象 new Page<>(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isValidPage(IPage<Files> page) {
|
private boolean isValidPage(IPage<Files> page) {
|
||||||
return page.getRecords() != null
|
return page.getRecords() != null
|
||||||
&& !page.getRecords().isEmpty()
|
&& !page.getRecords().isEmpty()
|
||||||
@ -240,15 +263,14 @@ public class FilesServiceImpl extends ServiceImpl<FilesMapper, Files> implements
|
|||||||
* 用途说明:新增专项文档管理-文档内容
|
* 用途说明:新增专项文档管理-文档内容
|
||||||
* 参数说明
|
* 参数说明
|
||||||
* Files 文档内容
|
* Files 文档内容
|
||||||
|
* sourcePath 源路径
|
||||||
|
* targetPath 目标路径
|
||||||
* 返回值说明: com.yfd.platform.config.ResponseResult 返回新增成功或者失败
|
* 返回值说明: com.yfd.platform.config.ResponseResult 返回新增成功或者失败
|
||||||
***********************************/
|
***********************************/
|
||||||
@Override
|
@Override
|
||||||
public ResponseResult addFiles(Files files) {
|
public ResponseResult addFiles(Files files) throws Exception {
|
||||||
Boolean value = false;
|
Boolean value = false;
|
||||||
|
|
||||||
List<String> names = Arrays.asList(files.getFileName().split(","));
|
|
||||||
List<String> sizes = Arrays.asList(files.getFileSize().split(","));
|
|
||||||
|
|
||||||
//todo 新增成功以后 删除redis
|
//todo 新增成功以后 删除redis
|
||||||
for (int page = 1; page <= 5; page++) {
|
for (int page = 1; page <= 5; page++) {
|
||||||
String redisKey = "sdfiles_" + files.getProjectId() + "_" + files.getNodeId() + "_page_" + page;
|
String redisKey = "sdfiles_" + files.getProjectId() + "_" + files.getNodeId() + "_page_" + page;
|
||||||
@ -256,73 +278,56 @@ public class FilesServiceImpl extends ServiceImpl<FilesMapper, Files> implements
|
|||||||
}
|
}
|
||||||
LOGGER.info("已清理缓存:project={}, node={}, pages=1-5", files.getProjectId(), files.getNodeId());
|
LOGGER.info("已清理缓存:project={}, node={}, pages=1-5", files.getProjectId(), files.getNodeId());
|
||||||
|
|
||||||
// 差不多的流程 就是提出来 然后判断 如果两个 中有一个是true
|
|
||||||
//获取当前登录用户 上传人是当前登录人
|
//获取当前登录用户 上传人是当前登录人
|
||||||
UsernamePasswordAuthenticationToken authentication =
|
UsernamePasswordAuthenticationToken authentication =
|
||||||
(UsernamePasswordAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
|
(UsernamePasswordAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
|
||||||
LoginUser loginuser = (LoginUser) authentication.getPrincipal();
|
LoginUser loginuser = null;
|
||||||
|
if (authentication != null) {
|
||||||
|
loginuser = (LoginUser) authentication.getPrincipal();
|
||||||
// 数据校验
|
|
||||||
if (names.size() != sizes.size()) {
|
|
||||||
return ResponseResult.error("文件名称和文件大小的列表长度不一致!");
|
|
||||||
}
|
}
|
||||||
List<Files> filesToSave = new ArrayList<>();
|
|
||||||
// 设置当前时间
|
|
||||||
LocalDateTime now = LocalDateTime.now();
|
|
||||||
// 转换为 Timestamp
|
|
||||||
Timestamp currentTime = Timestamp.valueOf(now);
|
|
||||||
files.setUploadTime(currentTime);
|
|
||||||
|
|
||||||
|
//新增之前从处理一下源路径的数据 ,String sourcePath,String targetPath
|
||||||
|
// 查询本地文件路径根目录(如 E:\yun)
|
||||||
|
QueryWrapper<StorageSourceConfig> queryWrapper = new QueryWrapper<>();
|
||||||
|
queryWrapper.eq("name", "filePath");
|
||||||
|
queryWrapper.eq("type", "sdlocal");
|
||||||
|
StorageSourceConfig storageSourceConfig = storageSourceConfigMapper.selectOne(queryWrapper);
|
||||||
|
//源路径 临时路径
|
||||||
|
String sourceFilePath = files.getSourcePath();
|
||||||
|
//目标路径
|
||||||
|
String targetFilePath = files.getTargetPath();
|
||||||
|
|
||||||
for (int i = 0; i < names.size(); i++) {
|
List<Files> filesToSave = this.documentUploadById(files, sourceFilePath, targetFilePath, storageSourceConfig.getValue());
|
||||||
String name = names.get(i).trim();
|
|
||||||
String sizeStr = sizes.get(i).trim();
|
|
||||||
|
|
||||||
// 校验文件名是否包含非法字符
|
|
||||||
if (containsInvalidCharacters(name)) {
|
|
||||||
return ResponseResult.error("文件名包含非法字符!");
|
|
||||||
}
|
|
||||||
|
|
||||||
//校验是否真正上传
|
|
||||||
String pathAndName = files.getFilePath() + "/" + name;
|
|
||||||
//准备获取文件的信息
|
|
||||||
AbstractBaseFileService<?> fileService = storageSourceContext.getByStorageKey("sdlocal");
|
|
||||||
FileItemResult fileItemResult = fileService.getFileItem(pathAndName);
|
|
||||||
if (fileItemResult == null || fileItemResult.getName() == null) {
|
|
||||||
return ResponseResult.error(name + "文件没有上传到空间,请重新选择上传!");
|
|
||||||
}
|
|
||||||
|
|
||||||
// 校验文件大小是否可以转换成数值
|
|
||||||
try {
|
|
||||||
Files files1 = new Files();
|
|
||||||
files1.setProjectId(files.getProjectId());
|
|
||||||
files1.setNodeId(files.getNodeId());
|
|
||||||
files1.setFilePath(files.getFilePath());
|
|
||||||
files1.setKeywords(files.getKeywords());
|
|
||||||
files1.setDescription(files.getDescription());
|
|
||||||
files1.setUploadTime(files.getUploadTime());
|
|
||||||
files1.setUploader(loginuser.getUsername());
|
|
||||||
files1.setFileName(name);
|
|
||||||
files1.setFileSize(sizeStr);
|
|
||||||
filesToSave.add(files1);
|
|
||||||
} catch (NumberFormatException e) {
|
|
||||||
return ResponseResult.error("文件大小必须是有效的数字!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (filesToSave.size() > 0) {
|
if (filesToSave.size() > 0) {
|
||||||
//循环新增
|
//循环新增
|
||||||
for (Files filess : filesToSave) {
|
for (Files filess : filesToSave) {
|
||||||
|
if (loginuser != null) {
|
||||||
|
filess.setUploader(loginuser.getUsername());
|
||||||
|
}
|
||||||
|
//校验是否真正上传
|
||||||
|
String pathAndName = filess.getFilePath() + filess.getFileName();
|
||||||
|
//准备获取文件的信息
|
||||||
|
AbstractBaseFileService<?> fileService = storageSourceContext.getByStorageKey("sdlocal");
|
||||||
|
FileItemResult fileItemResult = fileService.getFileItem(pathAndName);
|
||||||
|
if (fileItemResult == null || fileItemResult.getName() == null) {
|
||||||
|
return ResponseResult.error(filess.getFileName() + "文件没有上传到空间,请重新选择上传!");
|
||||||
|
}
|
||||||
int valueAdded = filesMapper.insert(filess);
|
int valueAdded = filesMapper.insert(filess);
|
||||||
if (valueAdded == 1) {
|
if (valueAdded == 1) {
|
||||||
|
|
||||||
|
|
||||||
value = true;
|
value = true;
|
||||||
} else {
|
} else {
|
||||||
value = false;
|
value = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
value = true;
|
||||||
|
LOGGER.info("文件名相同覆盖 {}", files.getFileName());
|
||||||
}
|
}
|
||||||
|
File target = new File(storageSourceConfig.getValue() + String.valueOf(sourceFilePath));
|
||||||
|
//删除临时文件
|
||||||
|
deleteDirectory(target);
|
||||||
|
|
||||||
if (value) {
|
if (value) {
|
||||||
return ResponseResult.success("新增文件成功!");
|
return ResponseResult.success("新增文件成功!");
|
||||||
} else {
|
} else {
|
||||||
@ -330,6 +335,251 @@ public class FilesServiceImpl extends ServiceImpl<FilesMapper, Files> implements
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void deleteDirectory(File directory) throws Exception {
|
||||||
|
if (!directory.exists()) {
|
||||||
|
return; // 路径不存在直接返回
|
||||||
|
}
|
||||||
|
|
||||||
|
File[] files = directory.listFiles();
|
||||||
|
if (files != null) {
|
||||||
|
for (File file : files) {
|
||||||
|
if (file.isDirectory()) {
|
||||||
|
deleteDirectory(file); // 递归删除子目录
|
||||||
|
} else {
|
||||||
|
if (!file.delete()) { // 删除文件
|
||||||
|
throw new Exception("无法删除文件: " + file.getAbsolutePath());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!directory.delete()) { // 删除空目录
|
||||||
|
throw new Exception("无法删除目录: " + directory.getAbsolutePath());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Files> documentUploadById(Files files, String sourceFilePath, String targetFilePath, String value) throws Exception {
|
||||||
|
|
||||||
|
List<Files> filesList = new ArrayList<>();
|
||||||
|
|
||||||
|
// 设置当前时间
|
||||||
|
LocalDateTime now = LocalDateTime.now();
|
||||||
|
// 转换为 Timestamp
|
||||||
|
Timestamp currentTime = Timestamp.valueOf(now);
|
||||||
|
FileListRequest sourcefileListRequest = buildFileRequest(sourceFilePath);
|
||||||
|
FileListRequest targetfileListRequest = buildFileRequest(targetFilePath);
|
||||||
|
|
||||||
|
//获取源文件列表 包含文件和文件夹
|
||||||
|
List<FileItemResult> sourceFileItemList = obtainFileItemResultData(sourcefileListRequest);
|
||||||
|
//获取目标文件列表 包含文件和文件夹
|
||||||
|
List<FileItemResult> targetFileItemList = obtainFileItemResultData(targetfileListRequest);
|
||||||
|
for (FileItemResult fileItemResult : sourceFileItemList) {
|
||||||
|
|
||||||
|
String a1 = fileItemResult.getType() + fileItemResult.getName();
|
||||||
|
FileItemResult targetFileItem = targetFileItemList.stream()
|
||||||
|
.filter(t -> (t.getType() + t.getName()).equals(a1))
|
||||||
|
.findFirst() // 获取第一个匹配项(返回 Optional)
|
||||||
|
.orElse(null);
|
||||||
|
|
||||||
|
// 检查对象存在
|
||||||
|
if (targetFileItem != null) {
|
||||||
|
// 循环处理文件 对比文件的MD5值
|
||||||
|
if (fileItemResult.getType() == FileTypeEnum.FILE) {
|
||||||
|
//源路径
|
||||||
|
String sourcePath = value + sourceFilePath + "/" + fileItemResult.getName();
|
||||||
|
//目标路径
|
||||||
|
String targetPath = value + targetFilePath + "/" + fileItemResult.getName();
|
||||||
|
//根据路径获取MD5值比较 如果相同则不进行操作 如果不同则重命名目标路径下的文件名称以及表结构 把现在源路径下的文件拷贝到目标路径下 新增数据库文件记录
|
||||||
|
// 计算源文件MD5
|
||||||
|
File sourceLocalFile = new File(sourcePath);
|
||||||
|
String sourceLocalMD5 = calculateMD5Data(new FileInputStream(sourceLocalFile));
|
||||||
|
// 计算源文件MD5
|
||||||
|
File targetLocalFile = new File(targetPath);
|
||||||
|
String targetLocalMD5 = calculateMD5Data(new FileInputStream(targetLocalFile));
|
||||||
|
|
||||||
|
// 如果MD5值不相同则进行操作 //如果一致 则直接复制源文件到目标文件
|
||||||
|
if (StringUtils.isNoneEmpty(sourceLocalMD5, targetLocalMD5) && !sourceLocalMD5.equals(targetLocalMD5)) {
|
||||||
|
//更改目标路径下的文件名称
|
||||||
|
String newTargetPath = renameFile(sourcePath);
|
||||||
|
//将源目录文件 复制到 目标目录文件
|
||||||
|
copyToDirectoryFile(newTargetPath, value + targetFilePath + "/");
|
||||||
|
String normalizedPath = newTargetPath
|
||||||
|
.replaceAll("[/\\\\]+", "/") // 将 "\" 或混合分隔符统一为 "/"
|
||||||
|
.replaceAll("/+$", "");
|
||||||
|
|
||||||
|
String fileName = normalizedPath.substring(normalizedPath.lastIndexOf("/") + 1);
|
||||||
|
Files files1 = new Files();
|
||||||
|
files1.setProjectId(files.getProjectId());
|
||||||
|
files1.setNodeId(files.getNodeId());
|
||||||
|
files1.setFileName(fileName);
|
||||||
|
//todo
|
||||||
|
files1.setFilePath(targetFilePath);
|
||||||
|
long fileSizeInBytes = fileItemResult.getSize();
|
||||||
|
// 转换为 MB 并保留两位小数
|
||||||
|
double fileSizeInMB = fileSizeInBytes / (1024.0 * 1024.0);
|
||||||
|
String fileSizeFormatted = String.format("%.2f", fileSizeInMB); // 保留两位小数
|
||||||
|
files1.setFileSize(fileSizeFormatted);
|
||||||
|
files1.setUploadTime(currentTime);
|
||||||
|
filesList.add(files1);
|
||||||
|
} else {
|
||||||
|
//将源目录文件 复制到 目标目录文件 todo这个地方是覆盖
|
||||||
|
copyWithOverride(sourcePath, targetPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//如果为空对象不存在 则直接拷贝
|
||||||
|
String sourcePath = value + sourceFilePath;
|
||||||
|
//目标路径
|
||||||
|
String targetPath = value + targetFilePath;
|
||||||
|
//将源目录文件 复制到 目标目录文件
|
||||||
|
copyFolderWithOverride(sourcePath, targetPath);
|
||||||
|
//这个时候要新增
|
||||||
|
Files files1 = new Files();
|
||||||
|
files1.setProjectId(files.getProjectId());
|
||||||
|
files1.setNodeId(files.getNodeId());
|
||||||
|
files1.setFileName(fileItemResult.getName());
|
||||||
|
//todo
|
||||||
|
files1.setFilePath(targetFilePath);
|
||||||
|
long fileSizeInBytes = fileItemResult.getSize();
|
||||||
|
// 转换为 MB 并保留两位小数
|
||||||
|
double fileSizeInMB = fileSizeInBytes / (1024.0 * 1024.0);
|
||||||
|
String fileSizeFormatted = String.format("%.2f", fileSizeInMB); // 保留两位小数
|
||||||
|
files1.setFileSize(fileSizeFormatted);
|
||||||
|
files1.setUploadTime(currentTime);
|
||||||
|
filesList.add(files1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return filesList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 确保路径格式为以 "/" 开头和结尾(例如 "/data/test/")
|
||||||
|
* 若路径为空或非法,返回根路径 "/"
|
||||||
|
*/
|
||||||
|
private String ensurePathFormat(String path) {
|
||||||
|
if (StringUtils.isBlank(path)) {
|
||||||
|
return "/";
|
||||||
|
}
|
||||||
|
// 统一替换反斜杠为斜杠(兼容 Windows 路径)
|
||||||
|
String normalized = path.replaceAll("\\\\", "/");
|
||||||
|
// 去掉多余的斜杠
|
||||||
|
normalized = normalized.replaceAll("/{2,}", "/");
|
||||||
|
// 确保以 "/" 开头
|
||||||
|
if (!normalized.startsWith("/")) {
|
||||||
|
normalized = "/" + normalized;
|
||||||
|
}
|
||||||
|
// 确保以 "/" 结尾
|
||||||
|
if (!normalized.endsWith("/")) {
|
||||||
|
normalized += "/";
|
||||||
|
}
|
||||||
|
return normalized;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 优化后的 MD5 计算方法(线程安全)
|
||||||
|
public String calculateMD5Data(InputStream inputStream) throws IOException, NoSuchAlgorithmException {
|
||||||
|
try (InputStream is = inputStream) { // 确保流关闭
|
||||||
|
MessageDigest md = MessageDigest.getInstance("MD5");
|
||||||
|
byte[] buffer = new byte[8192];
|
||||||
|
int bytesRead;
|
||||||
|
while ((bytesRead = is.read(buffer)) != -1) {
|
||||||
|
md.update(buffer, 0, bytesRead);
|
||||||
|
}
|
||||||
|
return Hex.encodeHexString(md.digest());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String renameFile(String originalPath) throws IOException {
|
||||||
|
// JSONObject jsonObject = new JSONObject()
|
||||||
|
File originalFile = new File(originalPath);
|
||||||
|
if (!originalFile.exists()) {
|
||||||
|
throw new IOException("原文件不存在: " + originalPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 生成新文件名(保留扩展名)
|
||||||
|
String baseName = FilenameUtils.getBaseName(originalPath);
|
||||||
|
String extension = FilenameUtils.getExtension(originalPath);
|
||||||
|
String timestamp = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
|
||||||
|
String newFileName = baseName + "_" + timestamp + "." + extension;
|
||||||
|
|
||||||
|
Path originalFilePath = originalFile.toPath();
|
||||||
|
Path newFilePath = Paths.get(originalFile.getParent(), newFileName);
|
||||||
|
|
||||||
|
// 处理目标文件已存在的情况
|
||||||
|
if (java.nio.file.Files.exists(newFilePath)) {
|
||||||
|
java.nio.file.Files.delete(newFilePath); // 删除已存在的目标文件
|
||||||
|
}
|
||||||
|
|
||||||
|
// 移动文件
|
||||||
|
java.nio.file.Files.move(originalFilePath, newFilePath);
|
||||||
|
System.out.println("重命名成功: " + originalPath + " → " + newFilePath.toString());
|
||||||
|
return newFilePath.toString();
|
||||||
|
// jsonObject.set("paht",newFilePath.toString());
|
||||||
|
// jsonObject.set("name",newFileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void copyWithOverride(String source, String target) throws IOException {
|
||||||
|
File srcFile = new File(source);
|
||||||
|
File destFile = new File(target);
|
||||||
|
|
||||||
|
// 强制覆盖已存在的文件
|
||||||
|
FileUtils.copyFile(srcFile, destFile, true);
|
||||||
|
System.out.println("成功覆盖文件: " + target);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void copyToDirectoryFile(String source, String targetDirectory) throws IOException {
|
||||||
|
File srcFile = new File(source);
|
||||||
|
File destDir = new File(targetDirectory);
|
||||||
|
|
||||||
|
// 确保目标目录存在,如果不存在则创建
|
||||||
|
if (!destDir.exists()) {
|
||||||
|
destDir.mkdirs();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建目标文件对象(在目标目录下使用源文件名)
|
||||||
|
File destFile = new File(destDir, srcFile.getName());
|
||||||
|
|
||||||
|
// 复制文件到目标目录
|
||||||
|
FileUtils.copyFile(srcFile, destFile);
|
||||||
|
System.out.println("成功复制文件到: " + destFile.getAbsolutePath());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void copyFolderWithOverride(String source, String target) throws IOException {
|
||||||
|
File srcDir = new File(source);
|
||||||
|
File destDir = new File(target);
|
||||||
|
|
||||||
|
|
||||||
|
// 递归拷贝文件夹及内容
|
||||||
|
FileUtils.copyDirectory(srcDir, destDir);
|
||||||
|
System.out.println("成功覆盖文件夹: " + target);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private List<FileItemResult> obtainFileItemResultData(FileListRequest fileListRequest) throws Exception {
|
||||||
|
|
||||||
|
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());
|
||||||
|
return fileItemList;
|
||||||
|
}
|
||||||
|
|
||||||
|
private FileListRequest buildFileRequest(String path) {
|
||||||
|
FileListRequest fileListRequest = new FileListRequest();
|
||||||
|
fileListRequest.setOrderBy("time");
|
||||||
|
fileListRequest.setOrderDirection("desc");
|
||||||
|
fileListRequest.setPassword("");
|
||||||
|
fileListRequest.setPath(path);
|
||||||
|
fileListRequest.setStorageKey("sdlocal");
|
||||||
|
|
||||||
|
return fileListRequest;
|
||||||
|
}
|
||||||
|
|
||||||
/**********************************
|
/**********************************
|
||||||
* 用途说明: 修改专项文档管理-文档内容
|
* 用途说明: 修改专项文档管理-文档内容
|
||||||
* 参数说明
|
* 参数说明
|
||||||
|
@ -19,6 +19,7 @@ import com.yfd.platform.modules.storage.service.base.AbstractBaseFileService;
|
|||||||
import com.yfd.platform.system.mapper.SysDictionaryItemsMapper;
|
import com.yfd.platform.system.mapper.SysDictionaryItemsMapper;
|
||||||
import com.yfd.platform.utils.StringUtils;
|
import com.yfd.platform.utils.StringUtils;
|
||||||
import io.netty.channel.ChannelInboundHandlerAdapter;
|
import io.netty.channel.ChannelInboundHandlerAdapter;
|
||||||
|
import net.bytebuddy.implementation.bytecode.Throw;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
@ -124,6 +125,15 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
|
|||||||
// 转换为 Timestamp
|
// 转换为 Timestamp
|
||||||
Timestamp currentTime = Timestamp.valueOf(now);
|
Timestamp currentTime = Timestamp.valueOf(now);
|
||||||
project.setCreateTime(currentTime);
|
project.setCreateTime(currentTime);
|
||||||
|
|
||||||
|
LambdaQueryWrapper<Project> queryWrapper = new LambdaQueryWrapper<>();
|
||||||
|
queryWrapper.eq(Project::getProjectName,project.getProjectName());
|
||||||
|
Project project1 = projectMapper.selectOne(queryWrapper);
|
||||||
|
if (project1 != null){
|
||||||
|
throw new RuntimeException("专项文档管理项目已存在!");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int valueAdded = projectMapper.insert(project);
|
int valueAdded = projectMapper.insert(project);
|
||||||
if (valueAdded == 1) {
|
if (valueAdded == 1) {
|
||||||
|
|
||||||
@ -226,7 +236,6 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
|
|||||||
if (project.getProjectTime() == null || project.getProjectTime().equals("")) {
|
if (project.getProjectTime() == null || project.getProjectTime().equals("")) {
|
||||||
project.setProjectTime(null);
|
project.setProjectTime(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
int valueUpdate = projectMapper.updateById(project);
|
int valueUpdate = projectMapper.updateById(project);
|
||||||
if (valueUpdate == 1) {
|
if (valueUpdate == 1) {
|
||||||
return true;
|
return true;
|
||||||
|
Loading…
Reference in New Issue
Block a user