This commit is contained in:
s2042968 2024-12-26 15:19:13 +08:00
commit 14b8f9e566
10 changed files with 306 additions and 138 deletions

View File

@ -5,7 +5,6 @@ import com.electromagnetic.industry.software.manage.pojo.req.FileChunkDTO;
import com.electromagnetic.industry.software.manage.pojo.req.FileInfoQueryDTO;
import com.electromagnetic.industry.software.manage.pojo.req.UpdateFileInfoDTO;
import com.electromagnetic.industry.software.manage.service.EdFileInfoService;
import io.swagger.annotations.ApiOperation;
import org.springframework.core.io.InputStreamResource;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
@ -32,9 +31,9 @@ public class EdFileInfoController {
return edFileInfoService.createFolder(parentId, newFolderName);
}
@RequestMapping("deleteFolder")
public ElectromagneticResult<?> deleteFolder(@RequestParam String id, @RequestParam Integer dataType) {
return edFileInfoService.deleteFolder(id, dataType);
@RequestMapping("delete")
public ElectromagneticResult<?> delete(@RequestParam String id) {
return edFileInfoService.delete(id);
}
@RequestMapping("info")

View File

@ -34,7 +34,6 @@ public class ProjectController {
return edPrjService.modifyPrjName(prjId, newPrjName);
}
@RequestMapping("queryAll")
public ElectromagneticResult<?> queryAll() {
return edPrjService.queryAllPrjInfo();

View File

@ -18,7 +18,7 @@ import java.util.Date;
@Accessors(chain = true)
@Data
@FieldNameConstants
public class EdFileInfo extends BaseModel {
public class EdFileInfo extends BaseModel{
public void newInit() {
String userId = UserThreadLocal.getUserId();

View File

@ -38,10 +38,9 @@ public interface EdFileInfoService {
* 删除目录
*
* @param id
* @param dataType
* @return
*/
ElectromagneticResult<?> deleteFolder(String id, Integer dataType);
ElectromagneticResult<?> delete(String id);
/**
* 下载文件

View File

@ -66,11 +66,11 @@ public interface EdPrjService {
/**
* 删除子集
*
* @param fileId
* @param id
* @param parentId
* @return
*/
ElectromagneticResult<?> deleteFolder(String fileId, String parentId);
ElectromagneticResult<?> deleteFolder(String id, String parentId);
/**
* 层级沿用

View File

@ -8,7 +8,7 @@ public interface FileSystemService {
void copyFile(String source, String destination);
void moveFile(String source, String destination);
void moveFile(String source, String destination, boolean deleteSource);
void save(InputStream inputStream, String destination);
@ -17,4 +17,8 @@ public interface FileSystemService {
void renameFile(String sourcePath, String sourceName, String newName);
boolean checkFolderExist(String newPath);
boolean writeStringToFile(String filePath, String contents);
boolean deleteFile(String filePath);
}

View File

@ -8,9 +8,7 @@ import cn.hutool.core.lang.tree.TreeUtil;
import cn.hutool.core.text.StrFormatter;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.MybatisConfiguration;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.electromagnetic.industry.software.common.enums.EffectFlagEnum;
import com.electromagnetic.industry.software.common.enums.EleDataSaveStatusEnum;
@ -30,6 +28,7 @@ import lombok.Getter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
@ -142,17 +141,11 @@ public class CommonService {
.likeRight(EdFileInfo::getFilePath, id));
}
@Transactional(rollbackFor = Exception.class)
public ElectromagneticResult<?> addFolder(String parentId, String folderName, boolean maxLengthCheck, boolean isPrjDir, String folderId) {
// 验证名称是否合法
Assert.isTrue(EleCommonUtil.isFileNameValid(folderName), "文件名不符合规范只能包含中文字符、下划线、连字符、加号、数字和英文字符且长度小于32。");
if (!EleCommonUtil.isFileNameValid(folderName)) {
String info = StrFormatter.format("子集名称{}不符合要求", folderName);
log.error(info);
return ElectromagneticResultUtil.fail("-1", info);
}
LambdaQueryWrapper<EdFileInfo> queryWrapper = Wrappers.lambdaQuery(EdFileInfo.class)
.select(EdFileInfo::getId, EdFileInfo::getFilePath)
.eq(EdFileInfo::getId, parentId);
@ -170,10 +163,11 @@ public class CommonService {
// 判断文件夹名称是否存在
List<EdFileInfo> edFileInfos = edFileInfoMapper.selectList(Wrappers.lambdaQuery(EdFileInfo.class)
.select(EdFileInfo::getId, EdFileInfo::getFileName)
.eq(EdFileInfo::getEffectFlag, EffectFlagEnum.EFFECT.code)
.eq(EdFileInfo::getParentId, parentId));
List<String> names = edFileInfos.stream().map(EdFileInfo::getFileName).collect(Collectors.toList());
if (names.contains(folderName)) {
String info = "子集名称已存在";
String info = "名称已存在";
log.error(info);
return ElectromagneticResultUtil.fail("-1", info);
}
@ -208,7 +202,7 @@ public class CommonService {
fileSystemService.createDirectory(targetFilePath);
return ElectromagneticResultUtil.success(true);
} catch (Exception e) {
String info = "添加子集失败";
String info = "添加失败";
log.error(info, e);
throw new BizException(-1, info);
}
@ -253,51 +247,58 @@ public class CommonService {
}
}
public ElectromagneticResult<?> deleteFolder(String fileId, String parentId, boolean needResort) {
public ElectromagneticResult<?> deleteFolder(String id, String parentId) {
// 如果文件夹下存在文件包括文件夹和已经逻辑删除的文件则不允许删除后面管理员选择会有物理删除文件夹和文件的功能此时MySQL和文件系统则会进行物理删除该文件
try {
// TODO 如果文件夹下存在文件不包括文件夹包括已经删除的文件则不允许删除
Long count = edFileInfoMapper.selectCount(Wrappers.lambdaQuery(EdFileInfo.class)
.like(EdFileInfo::getFilePath, MYSQL_FILE_PATH_SPLIT + fileId + MYSQL_FILE_PATH_SPLIT)
.eq(EdFileInfo::getDataType, EleDataTypeEnum.FILE.code));
if (count > 0) {
String info = "禁止删除非空文件夹";
log.info(info);
throw new BizException(-1, info);
}
LambdaQueryWrapper<EdFileInfo> queryWrapper = Wrappers.lambdaQuery(EdFileInfo.class)
.select(EdFileInfo::getId, EdFileInfo::getFilePath)
.like(EdFileInfo::getFilePath, MYSQL_FILE_PATH_SPLIT + fileId + MYSQL_FILE_PATH_SPLIT)
.eq(EdFileInfo::getEffectFlag, EffectFlagEnum.EFFECT.code);
List<EdFileInfo> edFileInfos = edFileInfoMapper.selectList(queryWrapper);
List<String> ids = edFileInfos.stream().map(EdFileInfo::getId).collect(Collectors.toList());
ids.add(fileId);
LambdaUpdateWrapper<EdFileInfo> updateWrapper = Wrappers.lambdaUpdate(EdFileInfo.class)
.set(EdFileInfo::getEffectFlag, EffectFlagEnum.NOT_EFFECTIVE.code)
.set(EdFileInfo::getSort, -1)
.set(EdFileInfo::getUpdateTime, new Date())
.set(EdFileInfo::getUpdatedBy, UserThreadLocal.getUserId())
.in(EdFileInfo::getId, ids);
edFileInfoMapper.update(null, updateWrapper);
if (!needResort) {
return ElectromagneticResultUtil.success(true);
}
// 同层级的resort
List<EdFileInfo> edFileInfos1 = edFileInfoMapper.selectList(Wrappers.lambdaQuery(EdFileInfo.class)
.select(EdFileInfo::getId, EdFileInfo::getSort)
.eq(EdFileInfo::getEffectFlag, EffectFlagEnum.EFFECT.code)
.eq(EdFileInfo::getParentId, parentId)
.orderByAsc(EdFileInfo::getSort));
Date now = new Date();
String currentUserId = UserThreadLocal.getUserId();
for (int i = 0; i < edFileInfos1.size(); i++) {
String id = edFileInfos1.get(i).getId();
edFileInfoMapper.update(null, Wrappers.lambdaUpdate(EdFileInfo.class)
.set(EdFileInfo::getSort, i + 1)
.set(EdFileInfo::getUpdatedBy, currentUserId)
.set(EdFileInfo::getUpdateTime, now)
.eq(EdFileInfo::getId, id));
// 这里要分两种情况1是删除层级目录2是删除用户创建的文件夹
EdFileInfo fileInfo = edFileInfoMapper.selectOne(Wrappers.<EdFileInfo>lambdaQuery().eq(EdFileInfo::getId, id));
if (fileInfo.getPrjDir()) { // 删除的是层级目录
long count = edFileInfoMapper.selectCount(Wrappers.<EdFileInfo>lambdaQuery()
.eq(EdFileInfo::getPrjDir, false)
.eq(EdFileInfo::getEffectFlag, EffectFlagEnum.EFFECT.code)
.like(EdFileInfo::getFilePath, MYSQL_FILE_PATH_SPLIT + id + MYSQL_FILE_PATH_SPLIT));
if (count > 0) {
String info = "禁止删除非空文件夹";
log.info(info);
return ElectromagneticResultUtil.fail("-1", info);
} else {
// 先逻辑删除文件夹
edFileInfoMapper.update(null, Wrappers.<EdFileInfo>lambdaUpdate()
.eq(EdFileInfo::getId, id)
.set(EdFileInfo::getSort, -1)
.set(EdFileInfo::getEffectFlag, EffectFlagEnum.NOT_EFFECTIVE.code));
// 层级文件夹重排序
List<EdFileInfo> edFileInfos1 = edFileInfoMapper.selectList(Wrappers.lambdaQuery(EdFileInfo.class)
.select(EdFileInfo::getId, EdFileInfo::getSort)
.eq(EdFileInfo::getEffectFlag, EffectFlagEnum.EFFECT.code)
.eq(EdFileInfo::getParentId, parentId)
.orderByAsc(EdFileInfo::getSort));
Date now = new Date();
String currentUserId = UserThreadLocal.getUserId();
for (int i = 0; i < edFileInfos1.size(); i++) {
String tmp = edFileInfos1.get(i).getId();
edFileInfoMapper.update(null, Wrappers.lambdaUpdate(EdFileInfo.class)
.set(EdFileInfo::getSort, i + 1)
.set(EdFileInfo::getUpdatedBy, currentUserId)
.set(EdFileInfo::getUpdateTime, now)
.eq(EdFileInfo::getId, tmp));
}
}
} else { // 删除的是用户自己创建的文件夹
// 检查该文件夹下是否有没有被废除的文件
long count = edFileInfoMapper.selectCount(Wrappers.<EdFileInfo>lambdaQuery()
.eq(EdFileInfo::getParentId, id)
.eq(EdFileInfo::getEffectFlag, EffectFlagEnum.EFFECT.code));
if (count > 0) {
String info = "禁止删除非空文件夹";
log.info(info);
return ElectromagneticResultUtil.fail("-1", info);
} else {
// 逻辑文件夹重排序
edFileInfoMapper.update(null, Wrappers.<EdFileInfo>lambdaUpdate()
.eq(EdFileInfo::getId, id)
.set(EdFileInfo::getEffectFlag, EffectFlagEnum.NOT_EFFECTIVE.code));
}
}
return ElectromagneticResultUtil.success(true);
} catch (Exception e) {
@ -317,4 +318,10 @@ public class CommonService {
}
return null;
}
public String getPrjNameByDbPath(String dbPath) {
List<String> paths = StrUtil.split(dbPath, MYSQL_FILE_PATH_SPLIT);
String prjId = paths.get(0);
return edFileInfoMapper.selectById(prjId).getFileName();
}
}

View File

@ -7,6 +7,7 @@ import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.text.StrFormatter;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.ZipUtil;
import cn.hutool.crypto.SecureUtil;
@ -17,6 +18,7 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.electromagnetic.industry.software.common.enums.EffectFlagEnum;
import com.electromagnetic.industry.software.common.enums.EleDataSaveStatusEnum;
import com.electromagnetic.industry.software.common.enums.EleDataTypeEnum;
import com.electromagnetic.industry.software.common.enums.PublishEnum;
import com.electromagnetic.industry.software.common.exception.BizException;
@ -42,6 +44,7 @@ import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
@ -49,7 +52,6 @@ import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.*;
@ -71,7 +73,6 @@ public class EdFileInfoServiceImpl extends ServiceImpl<EdFileInfoMapper, EdFileI
private String downloadDataDir = "";
private String uploadDataDir = "";
@Value("${file.security.passwd}")
private String password;
@ -144,15 +145,14 @@ public class EdFileInfoServiceImpl extends ServiceImpl<EdFileInfoMapper, EdFileI
/**
* 删除目录
* @param id
* @param dataType
* @return
*/
@Override
public ElectromagneticResult<?> deleteFolder(String id, Integer dataType) {
Assert.isTrue(dataType == 0 || dataType == 1, "参数错误");
if (dataType == 0) {
return commonService.deleteFolder(id, null, false);
public ElectromagneticResult<?> delete(String id) {
EdFileInfo fileInfo = this.baseMapper.selectById(id);
String parentId = fileInfo.getParentId();
if (fileInfo.getDataType() == 0) {
return commonService.deleteFolder(id, parentId);
}
this.baseMapper.update(null, Wrappers.lambdaUpdate(EdFileInfo.class)
@ -300,6 +300,9 @@ public class EdFileInfoServiceImpl extends ServiceImpl<EdFileInfoMapper, EdFileI
/**
* 合并分片
* case1: 用户上传的新文件
* case2: 用户上传的带版本号的文件
* case3: 用户上传的文件在线上已经被移动到其他目录
* @param identifier
* @param fileName
* @param totalChunks
@ -308,53 +311,177 @@ public class EdFileInfoServiceImpl extends ServiceImpl<EdFileInfoMapper, EdFileI
@Override
@Transactional(rollbackFor = Exception.class)
public ElectromagneticResult<?> mergeChunks(String identifier, String fileName, Integer totalChunks) {
String destZipPath = doSysFileMerge(identifier, fileName, totalChunks);
int index = destZipPath.lastIndexOf(".zip");
String zipDirPath = destZipPath.substring(0, index);
String currentUserId = UserThreadLocal.getUserId();
String destColibPath = doSysFileMerge(identifier, fileName, totalChunks);
String mainName = FileUtil.mainName(destColibPath);
String parentDir = FileUtil.getParent(destColibPath, 1);
String zipDirPath = parentDir + File.separator + mainName + ".zip";
AES aes = SecureUtil.aes(password.getBytes());
try(
InputStream inputStream = Files.newInputStream(Paths.get(destZipPath));
InputStream inputStream = Files.newInputStream(Paths.get(destColibPath));
OutputStream outputStream = Files.newOutputStream(Paths.get(zipDirPath));
) {
aes.decrypt(inputStream, outputStream, true);
} catch (Exception e) {
String info = "文件上传错误";
log.error(info, e);
throw new BizException(-1, e.getMessage());
}
update2Database(zipDirPath);
update2FileSystem(zipDirPath);
return null;
}
private void update2Database(String colibDirPath) {
// 首先解密该文件
AES aes = SecureUtil.aes(password.getBytes());
String zipFilePath = "";
try(
InputStream inputStream = Files.newInputStream(Paths.get(colibDirPath));
OutputStream outputStream = Files.newOutputStream(Paths.get(zipFilePath));
) {
aes.decrypt(inputStream, outputStream, true);
} catch (Exception e) {
String info = "文件上传失败";
log.error(info, e);
throw new BizException(-1, info);
}
String tmpDir = "";
// ZipUtil.unzipq
// TODO 注意 需要reversion
String uuid = IdUtil.fastSimpleUUID();
String tmpDir = uploadDataDir + currentUserId + File.separator + uuid + File.separator;
ZipUtil.unzip(zipDirPath, tmpDir);
update2Database(zipDirPath);
return ElectromagneticResultUtil.success(true);
}
private void update2FileSystem(String zipDirPath) {
@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
public void update2Database(String prjDirPath) {
List<EdFileInfo> importFileInfos = JSONUtil.toList(prjDirPath + File.separator + "mysql.info", EdFileInfo.class);
// 首先处理导入的文件夹及其下属文件
// 找出文件夹
List<EdFileInfo> needMove2FileSystemFiles = new ArrayList<>();
List<EdFileInfo> importDirs = importFileInfos.stream()
.filter(e -> e.getDataType().equals(EleDataTypeEnum.FOLDER.code))
.filter(e -> !e.getPrjDir()).collect(Collectors.toList());
for (EdFileInfo edFileInfo : importDirs) {
String fileName = edFileInfo.getFileName();
String parentId = edFileInfo.getParentId();
List<EdFileInfo> folders = queryChildFolders(parentId);
Map<String, EdFileInfo> foldersMap = folders.stream().collect(Collectors.toMap(EdFileInfo::getId, e -> e));
List<String> folderNames = folders.stream().map(EdFileInfo::getFileName).collect(Collectors.toList());
String saveSysFilePath;
if (folderNames.contains(fileName)) { // 有同名文件夹
// 判断id是否相同
if (foldersMap.get(fileName).getId().equals(edFileInfo.getId())) { // id相同不做处理
log.info("id相同不做处理");
} else { // 文件名重复导入的文件名需要添加_1
edFileInfo.setFileNote(fileName + "_1");
this.baseMapper.insert(edFileInfo);
}
} else { // 没有同名文件夹
this.saveOrUpdate(edFileInfo); // 如果导出的文件夹在线上已经被作废这里则直接恢复需要注意的是在作废文件时需要将作废文件移动到回收站
}
needMove2FileSystemFiles.add(edFileInfo);
}
// 处理文件
importFileInfos = importFileInfos.stream()
.filter(e -> e.getDataType().equals(EleDataTypeEnum.FILE.code))
.collect(Collectors.toList());
Map<String, List<EdFileInfo>> fileInfoMap = new HashMap<>();
for (EdFileInfo edFileInfo : importFileInfos) {
List<EdFileInfo> list = fileInfoMap.getOrDefault(edFileInfo.getFileId(), new ArrayList<>());
list.add(edFileInfo);
fileInfoMap.put(edFileInfo.getFileId(), list);
}
fileInfoMap.forEach((k, v) -> {
List<EdFileInfo> dbFileInfos = this.baseMapper.selectList(Wrappers.lambdaQuery(EdFileInfo.class).eq(EdFileInfo::getFileId, k).orderByAsc(EdFileInfo::getFileVersion));
if (CollUtil.isEmpty(dbFileInfos)) { // 在线上没有找到则该批文件是从线下上传的
EdFileInfo fileInfo = v.stream().filter(e -> e.getEffectFlag().equals(EffectFlagEnum.EFFECT.code)).findFirst().get();
resetFileInfoName(fileInfo);
this.saveBatch(v);
needMove2FileSystemFiles.addAll(v);
} else {
Map<String, EdFileInfo> dbIdMap = dbFileInfos.stream().collect(Collectors.toMap(EdFileInfo::getId, e -> e));
Map<String, EdFileInfo> importIdMap = v.stream().collect(Collectors.toMap(EdFileInfo::getId, e -> e));
importIdMap.putAll(dbIdMap);
List<EdFileInfo> deepCopyV = JSONUtil.toList(JSONUtil.toJsonStr(v), EdFileInfo.class);
List<EdFileInfo> deepCopyDb = JSONUtil.toList(JSONUtil.toJsonStr(dbFileInfos), EdFileInfo.class);
EdFileInfo importEffectFile = deepCopyV.stream().filter(e -> e.getEffectFlag().equals(EffectFlagEnum.EFFECT.code)).findFirst().get();
EdFileInfo dbEffectFile = deepCopyDb.stream().filter(e -> e.getEffectFlag().equals(EffectFlagEnum.EFFECT.code)).findFirst().get();
String effectId = importEffectFile.getUpdateTime().after(dbEffectFile.getUpdateTime()) ? importEffectFile.getId() : dbEffectFile.getId();
Map<String, String> importVersionRelation = getVersionRelation(deepCopyV);
Map<String, String> dbVersionRelation = getVersionRelation(deepCopyDb);
dbVersionRelation.putAll(importVersionRelation);
int start = FILE_START_VERSION;
List<EdFileInfo> saveObjs = new ArrayList<>();
for (EdFileInfo importFileInfo : v) {
if (dbIdMap.containsKey(importFileInfo.getId())) { // 该文件在数据库中存在是从线上导出的
EdFileInfo dbFileInfo = dbIdMap.get(importFileInfo.getId());
if (dbFileInfo.getUpdateTime().before(importFileInfo.getUpdateTime())) { // 线下版本的修改时间比线上的新用线下的版本
importFileInfo.setFileVersion(start);
saveObjs.add(importFileInfo);
} else { // 线上版本的修改时间比线下新用线上的版本
dbFileInfo.setFileVersion(start);
saveObjs.add(dbFileInfo);
}
} else { // 该文件是线下上传的
importFileInfo.setFileVersion(start);
saveObjs.add(importFileInfo);
needMove2FileSystemFiles.add(importFileInfo);
}
++start;
}
for (EdFileInfo saveObj : saveObjs) {
String id = saveObj.getId();
String preVersionId = dbVersionRelation.get(id);
EdFileInfo tmp = importIdMap.get(preVersionId);
saveObj.setPreVersion(tmp.getFileVersion());
int effect = Objects.equals(saveObj.getId(), effectId) ? EffectFlagEnum.EFFECT.code : EffectFlagEnum.NOT_EFFECTIVE.code;
saveObj.setEffectFlag(effect);
}
this.saveOrUpdateBatch(saveObjs);
}
});
update2FileSystem(needMove2FileSystemFiles, prjDirPath);
}
private void resetFileInfoName(EdFileInfo fileInfo) {
String fileName = fileInfo.getFileName();
String parentId = fileInfo.getParentId();
for (int i = 0; i < 1000; ++i) {
long count = this.baseMapper.selectCount(Wrappers.lambdaQuery(EdFileInfo.class)
.eq(EdFileInfo::getFileName, fileName)
.eq(EdFileInfo::getFileType, fileInfo.getFileType())
.eq(EdFileInfo::getParentId, parentId)
.eq(EdFileInfo::getDataType, EleDataTypeEnum.FILE.code)
.eq(EdFileInfo::getEffectFlag, EffectFlagEnum.EFFECT.code));
if (count > 0) {
fileName = fileName + "_1";
} else {
fileInfo.setFileName(fileName);
return;
}
}
}
private void update2FileSystem(List<EdFileInfo> needMove2FileSystemFiles, String prjDirPath) {
Map<String, String> idNameMaps = needMove2FileSystemFiles.stream().collect(Collectors.toMap(EdFileInfo::getId, EdFileInfo::getFileName));
List<EdFileInfo> files = needMove2FileSystemFiles.stream().filter(e -> e.getDataType().equals(EleDataTypeEnum.FILE.code)).collect(Collectors.toList());
for (EdFileInfo edFileInfo : files) {
String filePath = edFileInfo.getFilePath();
StringBuilder sysFilePath = new StringBuilder();
for (String id : filePath.split(MYSQL_FILE_PATH_SPLIT)) {
sysFilePath.append(idNameMaps.get(id)).append(File.separator);
}
String destPath = commonService.getEleDataPath() + File.separator + sysFilePath;
String sourcePath = prjDirPath + File.separator + sysFilePath;
fileSystemService.moveFile(sourcePath, destPath, true);
}
}
private Map<String, String> getVersionRelation(List<EdFileInfo> edFileInfos) {
Map<String, String> versionRelation = new HashMap<>();
Map<Integer, EdFileInfo> versionMap = edFileInfos.stream().collect(Collectors.toMap(EdFileInfo::getFileVersion, e -> e));
for (EdFileInfo edFileInfo : edFileInfos) {
Integer preVersion = edFileInfo.getPreVersion();
EdFileInfo fileInfo = versionMap.get(preVersion);
String preVersionId = Objects.isNull(fileInfo) ? null : fileInfo.getId();
versionRelation.put(edFileInfo.getId(), preVersionId);
}
return versionRelation;
}
private List<EdFileInfo> queryChildFolders(String parentId) {
return this.baseMapper.selectList(Wrappers.lambdaQuery(EdFileInfo.class).eq(EdFileInfo::getParentId, parentId)
.eq(EdFileInfo::getDataType, EleDataTypeEnum.FOLDER.code)
.eq(EdFileInfo::getEffectFlag, false));
}
/**
* 导出
*
* @param dataIdArr
* @return
*/
@ -368,23 +495,30 @@ public class EdFileInfoServiceImpl extends ServiceImpl<EdFileInfoMapper, EdFileI
.eq(EdFileInfo::getEffectFlag, true));
resFiles.addAll(edFileInfos);
}
String prjName = resFiles.stream().filter(e -> e.getParentId().equals(PRJ_PARENT_ID)).findFirst().get().getFileName();
List<EdFileInfo> prjFolders = this.baseMapper.selectList(Wrappers.lambdaQuery(EdFileInfo.class).eq(EdFileInfo::getPrjDir, true).eq(EdFileInfo::getEffectFlag, EffectFlagEnum.EFFECT.code));
Map<String, EdFileInfo> prjFoldersMap = prjFolders.stream().collect(Collectors.toMap(EdFileInfo::getId, e -> e));
Map<String, EdFileInfo> tmps = resFiles.stream().collect(Collectors.toMap(EdFileInfo::getId, e -> e));
resFiles.clear();
resFiles.addAll(tmps.values());
resFiles.addAll(prjFoldersMap.values());
String prjName = commonService.getPrjNameByDbPath(resFiles.get(0).getFilePath());
List<EdFileInfo> folders = resFiles.stream().filter(e -> e.getDataType().equals(EleDataTypeEnum.FOLDER.code)).collect(Collectors.toList());
List<EdFileInfo> files = resFiles.stream().filter(e -> e.getDataType().equals(EleDataTypeEnum.FILE.code)).collect(Collectors.toList());
for (EdFileInfo edFileInfo : folders) {
String destFolderPath = downloadDataDir + File.separator + commonService.getFileSysPath(edFileInfo.getFileId());
FileUtil.mkdir(destFolderPath);
String destFolderPath = downloadDataDir + File.separator + prjName + File.separator + commonService.getFileSysPath(edFileInfo.getFileId());
fileSystemService.createDirectory(destFolderPath);
}
for (EdFileInfo edFileInfo : files) {
String filePath = commonService.getFileSysPath(edFileInfo.getFileId()) + edFileInfo.getFileCode() + "." + edFileInfo.getFileCode();
String destPath = downloadDataDir + File.separator + commonService.getDbPath(edFileInfo.getFileId());
FileUtil.copy(filePath, destPath, false);
String destPath = downloadDataDir + File.separator + prjName + File.separator + commonService.getDbPath(edFileInfo.getFileId());
fileSystemService.copyFile(filePath, destPath);
}
String mysqlInfo = JSONUtil.toJsonStr(resFiles);
FileUtil.writeString(mysqlInfo, downloadDataDir + File.separator + "mysql.info", Charset.defaultCharset());
fileSystemService.writeStringToFile(downloadDataDir + File.separator + prjName + File.separator + "mysql.info", mysqlInfo);
String exportZipFile = downloadDataDir + File.separator + prjName + ".zip";
String exportColibFile = downloadDataDir + File.separator + prjName + EXPORT_FILE_SUFFIX;
ZipUtil.zip(downloadDataDir + File.separator + prjName, exportZipFile);
ZipUtil.zip(downloadDataDir + File.separator + prjName + File.separator + prjName, exportZipFile);
AES aes = SecureUtil.aes(password.getBytes());
try(
InputStream inputStream = Files.newInputStream(Paths.get(exportZipFile));
@ -396,18 +530,16 @@ public class EdFileInfoServiceImpl extends ServiceImpl<EdFileInfoMapper, EdFileI
log.error(info, e);
throw new BizException(-1, info);
} finally {
FileUtil.del(exportZipFile);
fileSystemService.deleteFile(exportZipFile);
}
File file = new File(exportColibFile);
File file = FileUtil.newFile(exportColibFile);
FileSystemResource fileSystemResource = new FileSystemResource(file);
HttpHeaders headers = new HttpHeaders();
headers.add("Cache-Control", "no-cache, no-store, must-revalidate");
String fileName = Base64.encode(fileSystemResource.getFilename());
headers.add("Pragma", "no-cache");
headers.add("Expires", "0");
response.setHeader("content-disposition","attachment;filename=" + fileName);
// 构建响应实体(可以返回<byte[]或Resource返回类型取决body入参类型)
return ResponseEntity
.ok()
@ -425,7 +557,11 @@ public class EdFileInfoServiceImpl extends ServiceImpl<EdFileInfoMapper, EdFileI
* @return
*/
@Override
@Transactional(rollbackFor = Exception.class)
public ElectromagneticResult<?> upload(String parentId, MultipartFile file, Integer strategy) {
EdFileInfo fileInfo = this.baseMapper.selectById(parentId);
Assert.isTrue(fileInfo.getDataType().equals(EleDataTypeEnum.FOLDER.code) && !fileInfo.getPrjDir(), "层级目录不允许上传文件");
// 首先检查是否是同名文件
try {
String fileName = file.getOriginalFilename();
@ -458,9 +594,10 @@ public class EdFileInfoServiceImpl extends ServiceImpl<EdFileInfoMapper, EdFileI
.setDataStatus(PublishEnum.PUBLISHED.getCode())
.setEffectFlag(EffectFlagEnum.EFFECT.code)
.setFileCode(fileCode)
.setSaveStatus(EleDataSaveStatusEnum.SUCCESS.code)
.setPrjDir(false);
this.baseMapper.insert(newEdFileInfo);
String fileDestPath = commonService.getFileSysPath(parentFolderInfo.getFileId()) + File.separator + mainName + suffix + "." + fileCode;
String fileDestPath = commonService.getFileSysPath(parentFolderInfo.getFilePath()) + File.separator + mainName + "." + suffix + "." + fileCode;
fileSystemService.save(file.getInputStream(), fileDestPath);
}
} catch (Exception e) {
@ -532,7 +669,7 @@ public class EdFileInfoServiceImpl extends ServiceImpl<EdFileInfoMapper, EdFileI
// 移动文件
String srcFileSysPath = commonService.getFileSysPath(srcFileInfo.getFilePath());
String destFileSysPath = commonService.getFileSysPath(destFolderInfo.getFilePath());
fileSystemService.moveFile(srcFileSysPath, destFileSysPath);
fileSystemService.moveFile(srcFileSysPath, destFileSysPath, deleteSrc);
}
}
@ -559,7 +696,7 @@ public class EdFileInfoServiceImpl extends ServiceImpl<EdFileInfoMapper, EdFileI
// 文件系统移动文件
String srcFilePath = commonService.getFileSysPath(srcFileInfo.getFileId()) + File.separator + srcFileInfo.getFileCode();
String destFilePath = commonService.getFileSysPath(destFolderInfo.getFileId()) + File.separator + destFolderInfo.getFileCode();
fileSystemService.moveFile(srcFilePath, destFilePath);
fileSystemService.moveFile(srcFilePath, destFilePath, deleteSrc);
} else {
handMoveConflict(targetFolderId, strategy, srcFileInfo, destFolderInfo, deleteSrc);
}
@ -585,7 +722,8 @@ public class EdFileInfoServiceImpl extends ServiceImpl<EdFileInfoMapper, EdFileI
return moveFile(id, targetFolderId, strategy, false);
}
private void handUploadRepeatFile(String parentId, MultipartFile file, Integer strategy) throws IOException {
@Transactional(rollbackFor = Exception.class)
public void handUploadRepeatFile(String parentId, MultipartFile file, Integer strategy) throws IOException {
Assert.isTrue(Arrays.asList(1, 2, 3).contains(strategy), "解决同名文件参数错误");
String fileName = file.getOriginalFilename();
String mainName = FileUtil.mainName(fileName);
@ -602,7 +740,7 @@ public class EdFileInfoServiceImpl extends ServiceImpl<EdFileInfoMapper, EdFileI
.eq(EdFileInfo::getEffectFlag, EffectFlagEnum.EFFECT.code));
Integer maxFileVersion = Collections.max(parentFileInfos, Comparator.comparing(EdFileInfo::getFileVersion)).getFileVersion();
// 找到当前展示的版本
EdFileInfo effectFileInfo = parentFileInfos.stream().filter(e -> e.getEffectFlag().equals(true)).collect(Collectors.toList()).get(0);
EdFileInfo effectFileInfo = parentFileInfos.stream().filter(e -> e.getEffectFlag().equals(EffectFlagEnum.EFFECT.code)).collect(Collectors.toList()).get(0);
String codePathByDbPath = commonService.getCodePathByDbPath(effectFileInfo.getFilePath());
String timeStr = EleCommonUtil.getNowTimeStr();
String fileCode = commonService.createFileCode(codePathByDbPath, suffix, FILE_START_VERSION, timeStr);
@ -629,10 +767,11 @@ public class EdFileInfoServiceImpl extends ServiceImpl<EdFileInfoMapper, EdFileI
.setDataStatus(PublishEnum.PUBLISHED.getCode())
.setEffectFlag(EffectFlagEnum.EFFECT.code)
.setFileCode(fileCode)
.setSaveStatus(EleDataSaveStatusEnum.SUCCESS.code)
.setPrjDir(false);
this.baseMapper.insert(newEdFileInfo);
String fileDestPath = commonService.getFileSysPath(newEdFileInfo.getFileId()) + File.separator + mainName + suffix + "." + fileCode;
FileUtil.writeFromStream(file.getInputStream(), fileDestPath);
String fileDestPath = commonService.getFileSysPath(newEdFileInfo.getFilePath()) + File.separator + mainName + "." + suffix + "." + fileCode;
fileSystemService.save(file.getInputStream(), fileDestPath);
} else if (strategy == 3) {
// 文件名加_1存为新文件
EdFileInfo parentFileInfo = this.baseMapper.selectOne(Wrappers.lambdaQuery(EdFileInfo.class)
@ -644,7 +783,7 @@ public class EdFileInfoServiceImpl extends ServiceImpl<EdFileInfoMapper, EdFileI
String fileCode = commonService.createFileCode(codePathByDbPath, suffix, FILE_START_VERSION, newEdFileInfo.getFileTime());
newEdFileInfo.setParentId(parentId)
.setFileCode(fileCode)
.setFileName(mainName + "_1")
.setFileName(mainName)
.setFileType(suffix)
.setFileVersion(FILE_START_VERSION)
.setFileTime(newEdFileInfo.getFileTime())
@ -654,10 +793,12 @@ public class EdFileInfoServiceImpl extends ServiceImpl<EdFileInfoMapper, EdFileI
.setDataStatus(PublishEnum.PUBLISHED.getCode())
.setEffectFlag(EffectFlagEnum.EFFECT.code)
.setFileCode(fileCode)
.setSaveStatus(EleDataSaveStatusEnum.SUCCESS.code)
.setPrjDir(false);
resetFileInfoName(newEdFileInfo);
this.baseMapper.insert(newEdFileInfo);
String fileDestPath = commonService.getFileSysPath(parentFileInfo.getFileId()) + File.separator + mainName + "_1." + suffix + "." + fileCode;
FileUtil.writeFromStream(file.getInputStream(), fileDestPath);
String fileDestPath = commonService.getFileSysPath(parentFileInfo.getFilePath()) + File.separator + newEdFileInfo.getFileName() + "." + suffix + "." + fileCode;
fileSystemService.save(file.getInputStream(), fileDestPath);
}
}
@ -674,21 +815,21 @@ public class EdFileInfoServiceImpl extends ServiceImpl<EdFileInfoMapper, EdFileI
}
}
// 合并分片
String destZipPath = uploadDataDir + File.separator + currentUserId + File.separator + identifier + File.separator + fileName;
String destColibPath = uploadDataDir + File.separator + currentUserId + File.separator + fileName;
File[] partFiles = FileUtil.ls(uploadDataDir + File.separator + currentUserId + File.separator + identifier);
for (File partFile : partFiles) {
try (BufferedOutputStream outputStream = FileUtil.getOutputStream(destZipPath);
try (BufferedOutputStream outputStream = FileUtil.getOutputStream(destColibPath);
BufferedInputStream inputStream = FileUtil.getInputStream(partFile)) {
IoUtil.copy(inputStream, outputStream);
} catch (Exception e) {
FileUtil.del(destZipPath);
FileUtil.del(destColibPath);
String info = "文件合并失败";
log.error(info, e);
throw new BizException(-1, info);
}
}
Arrays.stream(partFiles).forEach(e -> FileUtil.del(e.getAbsolutePath()));
return destZipPath;
return destColibPath;
}
}

View File

@ -73,9 +73,9 @@ public class EdPrjServiceImpl extends ServiceImpl<EdFileInfoMapper, EdFileInfo>
.eq(EdFileInfo::getFileName, prjName));
if (count > 0) {
String info = StrFormatter.format("{} 已经存在", prjName);
String info = StrFormatter.format("{} 项目已经存在", prjName);
log.info(info);
ElectromagneticResultUtil.fail("-1", "该项目名称已经存在。");
return ElectromagneticResultUtil.fail("-1", info);
}
try {
@ -132,16 +132,16 @@ public class EdPrjServiceImpl extends ServiceImpl<EdFileInfoMapper, EdFileInfo>
.eq(EdFileInfo::getFileName, newPrjName));
if (count > 0) {
String info = StrFormatter.format("{} 已经存在", newPrjName);
String info = StrFormatter.format("{} 项目已经存在", newPrjName);
log.info(info);
ElectromagneticResultUtil.fail("-1", "该项目名称已经存在。");
return ElectromagneticResultUtil.fail("-1", info);
}
EdFileInfo fileInfo = this.baseMapper.selectOne(Wrappers.lambdaQuery(EdFileInfo.class)
.select(EdFileInfo::getFileName)
.eq(EdFileInfo::getId, prjId));
String oldPrjName = fileInfo.getFileName();
String newPath = commonService.getEleDataPath();
String newPath = commonService.getEleDataPath() + File.separator + newPrjName;
if (fileSystemService.checkFolderExist(newPath)) {
String info = StrFormatter.format("工程名{}已经存在", newPrjName);
log.error(info);
@ -275,7 +275,7 @@ public class EdPrjServiceImpl extends ServiceImpl<EdFileInfoMapper, EdFileInfo>
@Override
@Transactional(rollbackFor = Exception.class)
public ElectromagneticResult<?> deleteFolder(String fileId, String parentId) {
return commonService.deleteFolder(fileId, parentId, true);
return commonService.deleteFolder(fileId, parentId);
}
/**
@ -363,7 +363,7 @@ public class EdPrjServiceImpl extends ServiceImpl<EdFileInfoMapper, EdFileInfo>
if (commonService.checkSameFolder(parentId, newFolderName)) {
String info = "存在同名子集,禁止修改";
log.error(info);
throw new BizException(-1, info);
return ElectromagneticResultUtil.fail("-1", info);
}
String currentUserId = UserThreadLocal.getUserId();
Date now = new Date();

View File

@ -6,6 +6,7 @@ import org.springframework.stereotype.Service;
import java.io.File;
import java.io.InputStream;
import java.nio.charset.Charset;
@Service
public class FileSystemServiceImpl implements FileSystemService {
@ -17,10 +18,16 @@ public class FileSystemServiceImpl implements FileSystemService {
@Override
public void copyFile(String source, String destination) {
moveFile(source, destination, false);
}
@Override
public void moveFile(String source, String destination) {
public void moveFile(String source, String destination, boolean deleteSource) {
if (deleteSource) {
FileUtil.move(new File(source), new File(destination), true);
return;
}
FileUtil.copy(new File(source), new File(destination), false);
}
@Override
@ -43,4 +50,16 @@ public class FileSystemServiceImpl implements FileSystemService {
public boolean checkFolderExist(String newPath) {
return FileUtil.exist(newPath);
}
@Override
public boolean writeStringToFile(String filePath, String contents) {
FileUtil.writeString(contents, filePath, Charset.defaultCharset());
return true;
}
@Override
public boolean deleteFile(String filePath) {
FileUtil.del(filePath);
return false;
}
}