Merge branch 'develop' of http://139.196.179.195:3000/chenxudong/electromagnetic-data-new into develop
This commit is contained in:
commit
ea0e0948c4
|
|
@ -1,14 +1,15 @@
|
||||||
package com.electromagnetic.industry.software.manage.controller;
|
package com.electromagnetic.industry.software.manage.controller;
|
||||||
|
|
||||||
import com.electromagnetic.industry.software.common.resp.ElectromagneticResult;
|
import com.electromagnetic.industry.software.common.resp.ElectromagneticResult;
|
||||||
|
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.FileInfoQueryDTO;
|
||||||
|
import com.electromagnetic.industry.software.manage.pojo.req.UpdateFileInfoDTO;
|
||||||
import com.electromagnetic.industry.software.manage.service.EdFileInfoService;
|
import com.electromagnetic.industry.software.manage.service.EdFileInfoService;
|
||||||
|
import io.swagger.annotations.ApiOperation;
|
||||||
import org.springframework.core.io.InputStreamResource;
|
import org.springframework.core.io.InputStreamResource;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.RequestBody;
|
import org.springframework.web.bind.annotation.*;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import org.springframework.web.bind.annotation.RequestParam;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
@ -42,8 +43,10 @@ public class EdFileInfoController {
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping("upload")
|
@RequestMapping("upload")
|
||||||
public ElectromagneticResult<?> upload() {
|
public ElectromagneticResult<?> upload(@RequestParam("parentId") String parentId,
|
||||||
return null;
|
@RequestParam("file") MultipartFile file,
|
||||||
|
@RequestParam("strategy") Integer strategy) {
|
||||||
|
return edFileInfoService.upload(parentId, file, strategy);
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping("download")
|
@RequestMapping("download")
|
||||||
|
|
@ -52,37 +55,53 @@ public class EdFileInfoController {
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping("updateFileInfo")
|
@RequestMapping("updateFileInfo")
|
||||||
public ElectromagneticResult<?> updateFileInfo() {
|
public ElectromagneticResult<?> updateFileInfo(@RequestBody UpdateFileInfoDTO updateFileInfoDTO) {
|
||||||
return null;
|
return edFileInfoService.updateFileInfo(updateFileInfoDTO);
|
||||||
}
|
|
||||||
|
|
||||||
@RequestMapping("deleteFile")
|
|
||||||
public ElectromagneticResult<?> deleteFile() {
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping("moveFile")
|
@RequestMapping("moveFile")
|
||||||
public ElectromagneticResult<?> moveFile() {
|
public ElectromagneticResult<?> moveFile(@RequestParam("id") String id,
|
||||||
return null;
|
@RequestParam("targetFolderId") String targetFolderId,
|
||||||
|
@RequestParam("strategy") Integer strategy) {
|
||||||
|
return edFileInfoService.moveFile(id, targetFolderId, strategy);
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping("copyFile")
|
@RequestMapping("copyFile")
|
||||||
public ElectromagneticResult<?> copyFile() {
|
public ElectromagneticResult<?> copyFile(@RequestParam("id") String id,
|
||||||
return null;
|
@RequestParam("targetFolderId") String targetFolderId,
|
||||||
|
@RequestParam("strategy") Integer strategy) {
|
||||||
|
return edFileInfoService.copyFile(id, targetFolderId, strategy);
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping("versionView")
|
@RequestMapping("versionView")
|
||||||
public ElectromagneticResult<?> versionView() {
|
public ElectromagneticResult<?> versionView(@RequestParam String fileId) {
|
||||||
return null;
|
return edFileInfoService.versionView(fileId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping("versionBack")
|
@RequestMapping("versionBack")
|
||||||
public ElectromagneticResult<?> versionBack() {
|
public ElectromagneticResult<?> versionBack(@RequestParam String fileId, @RequestParam int targetVersion) {
|
||||||
return null;
|
return edFileInfoService.versionBack(fileId, targetVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping("batchExport")
|
@RequestMapping("batchExport")
|
||||||
public ElectromagneticResult<?> batchExport() {
|
public ResponseEntity<InputStreamResource> batchExport(@RequestParam String dataIdArr, HttpServletResponse response) throws IOException {
|
||||||
return null;
|
return edFileInfoService.batchExport(dataIdArr, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequestMapping(value = "/mergeChunks",method = RequestMethod.GET)
|
||||||
|
public ElectromagneticResult<?> mergeChunks(@RequestParam String identifier,
|
||||||
|
@RequestParam String fileName,
|
||||||
|
@RequestParam Integer totalChunks) {
|
||||||
|
return edFileInfoService.mergeChunks(identifier, fileName, totalChunks);
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequestMapping(value = "/batchImport",method = RequestMethod.POST)
|
||||||
|
public ElectromagneticResult<?> batchImport(FileChunkDTO fileChunkDTO) {
|
||||||
|
return edFileInfoService.batchImport(fileChunkDTO);
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequestMapping(value = "/batchImport",method = RequestMethod.GET)
|
||||||
|
public ElectromagneticResult<?> checkChunkExist(FileChunkDTO fileChunkDTO) {
|
||||||
|
return edFileInfoService.checkChunkExist(fileChunkDTO);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,17 +2,39 @@ package com.electromagnetic.industry.software.manage.pojo.models;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.annotation.TableField;
|
import com.baomidou.mybatisplus.annotation.TableField;
|
||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import com.electromagnetic.industry.software.common.enums.EffectFlagEnum;
|
||||||
|
import com.electromagnetic.industry.software.common.util.EleCommonUtil;
|
||||||
|
import com.electromagnetic.industry.software.common.util.IdWorker;
|
||||||
|
import com.electromagnetic.industry.software.common.util.UserThreadLocal;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
import lombok.experimental.Accessors;
|
import lombok.experimental.Accessors;
|
||||||
import lombok.experimental.FieldNameConstants;
|
import lombok.experimental.FieldNameConstants;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
@EqualsAndHashCode(callSuper = true)
|
@EqualsAndHashCode(callSuper = true)
|
||||||
@TableName("ed_file_info")
|
@TableName("ed_file_info")
|
||||||
@Accessors(chain = true)
|
@Accessors(chain = true)
|
||||||
@Data
|
@Data
|
||||||
@FieldNameConstants
|
@FieldNameConstants
|
||||||
public class EdFileInfo extends BaseModel {
|
public class EdFileInfo extends BaseModel {
|
||||||
|
|
||||||
|
public void newInit() {
|
||||||
|
String userId = UserThreadLocal.getUserId();
|
||||||
|
String newFileDbId = IdWorker.getSnowFlakeIdString();
|
||||||
|
String fileTime = EleCommonUtil.getNowTimeStr();
|
||||||
|
Date now = new Date();
|
||||||
|
this.setUpdatedBy(userId);
|
||||||
|
this.setId(newFileDbId);
|
||||||
|
this.setUpdateTime(now);
|
||||||
|
this.setCreatedTime(now);
|
||||||
|
this.setFileTime(fileTime);
|
||||||
|
this.setCreatedBy(userId);
|
||||||
|
this.setFileId(newFileDbId);
|
||||||
|
this.setEffectFlag(EffectFlagEnum.EFFECT.code);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 主键ID
|
* 主键ID
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
package com.electromagnetic.industry.software.manage.pojo.req;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class UpdateFileInfoDTO {
|
||||||
|
|
||||||
|
private String id;
|
||||||
|
private String fileName;
|
||||||
|
private String fileNote;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
package com.electromagnetic.industry.software.manage.pojo.resp;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class FileVersionViewVO {
|
||||||
|
private String id;
|
||||||
|
private String fileName;
|
||||||
|
private Integer fileVersion;
|
||||||
|
private Integer preVersion;
|
||||||
|
private String fileCode;
|
||||||
|
private Integer effectFlag;
|
||||||
|
}
|
||||||
|
|
@ -1,9 +1,12 @@
|
||||||
package com.electromagnetic.industry.software.manage.service;
|
package com.electromagnetic.industry.software.manage.service;
|
||||||
|
|
||||||
import com.electromagnetic.industry.software.common.resp.ElectromagneticResult;
|
import com.electromagnetic.industry.software.common.resp.ElectromagneticResult;
|
||||||
|
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.FileInfoQueryDTO;
|
||||||
|
import com.electromagnetic.industry.software.manage.pojo.req.UpdateFileInfoDTO;
|
||||||
import org.springframework.core.io.InputStreamResource;
|
import org.springframework.core.io.InputStreamResource;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
@ -46,4 +49,80 @@ public interface EdFileInfoService {
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
ResponseEntity<InputStreamResource> download(String id, HttpServletResponse response);
|
ResponseEntity<InputStreamResource> download(String id, HttpServletResponse response);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新文件信息
|
||||||
|
* @param updateFileInfoDTO
|
||||||
|
*/
|
||||||
|
ElectromagneticResult<?> updateFileInfo(UpdateFileInfoDTO updateFileInfoDTO);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 版本回退
|
||||||
|
* @param fileId
|
||||||
|
* @param targetVersion
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
ElectromagneticResult<?> versionBack(String fileId, int targetVersion);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查看分片是否存在
|
||||||
|
* @param fileChunkDTO
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
ElectromagneticResult<?> checkChunkExist(FileChunkDTO fileChunkDTO);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量导入
|
||||||
|
* @param fileChunkDTO
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
ElectromagneticResult<?> batchImport(FileChunkDTO fileChunkDTO);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 合并分片
|
||||||
|
* @param identifier
|
||||||
|
* @param fileName
|
||||||
|
* @param totalChunks
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
ElectromagneticResult<?> mergeChunks(String identifier, String fileName, Integer totalChunks);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出
|
||||||
|
* @param dataIdArr
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
ResponseEntity<InputStreamResource> batchExport(String dataIdArr, HttpServletResponse response) throws IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件上传
|
||||||
|
* @param parentId
|
||||||
|
* @param file
|
||||||
|
* @param strategy
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
ElectromagneticResult<?> upload(String parentId, MultipartFile file, Integer strategy);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 版本查看
|
||||||
|
* @param fileId
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
ElectromagneticResult<?> versionView(String fileId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 移动文件
|
||||||
|
* @param id
|
||||||
|
* @param targetFolderId
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
ElectromagneticResult<?> moveFile(String id, String targetFolderId, Integer strategy);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 复制文件
|
||||||
|
* @param id
|
||||||
|
* @param targetFolderId
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
ElectromagneticResult<?> copyFile(String id, String targetFolderId, Integer strategy);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,9 @@ import cn.hutool.core.lang.tree.Tree;
|
||||||
import cn.hutool.core.lang.tree.TreeNodeConfig;
|
import cn.hutool.core.lang.tree.TreeNodeConfig;
|
||||||
import cn.hutool.core.lang.tree.TreeUtil;
|
import cn.hutool.core.lang.tree.TreeUtil;
|
||||||
import cn.hutool.core.text.StrFormatter;
|
import cn.hutool.core.text.StrFormatter;
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
import cn.hutool.json.JSONUtil;
|
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.query.LambdaQueryWrapper;
|
||||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||||
|
|
@ -33,6 +35,7 @@ import javax.annotation.PostConstruct;
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import static com.electromagnetic.industry.software.common.cons.ElectromagneticConstants.*;
|
import static com.electromagnetic.industry.software.common.cons.ElectromagneticConstants.*;
|
||||||
|
|
@ -42,6 +45,9 @@ public class CommonService {
|
||||||
|
|
||||||
private final EleLog log = new EleLog(CommonService.class);
|
private final EleLog log = new EleLog(CommonService.class);
|
||||||
private static final Map<String, String> FILE_TYPE_ENUM = new HashMap<>();
|
private static final Map<String, String> FILE_TYPE_ENUM = new HashMap<>();
|
||||||
|
|
||||||
|
private static final Map<String, String> ID_NAME = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
@Value("${prj.folder.max.length}")
|
@Value("${prj.folder.max.length}")
|
||||||
private int prjFolderMaxLength;
|
private int prjFolderMaxLength;
|
||||||
|
|
||||||
|
|
@ -98,11 +104,19 @@ public class CommonService {
|
||||||
|
|
||||||
public String getFileSysPath(String dbPath) {
|
public String getFileSysPath(String dbPath) {
|
||||||
ArrayList<String> paths = CollUtil.newArrayList(dbPath.split(MYSQL_FILE_PATH_SPLIT));
|
ArrayList<String> paths = CollUtil.newArrayList(dbPath.split(MYSQL_FILE_PATH_SPLIT));
|
||||||
String path = getPath(paths);
|
String path = getDbPath(paths);
|
||||||
return eleDataPath + File.separator + path;
|
return eleDataPath + File.separator + path;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getPath(List<String> ids) {
|
public String getDbPath(String dbPath) {
|
||||||
|
List<String> paths = CollUtil.newArrayList(dbPath.split(MYSQL_FILE_PATH_SPLIT));
|
||||||
|
return getDbPath(paths);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDbPath(List<String> ids) {
|
||||||
|
|
||||||
|
// TODO cache
|
||||||
|
|
||||||
LambdaQueryWrapper<EdFileInfo> queryWrapper = Wrappers.lambdaQuery(EdFileInfo.class)
|
LambdaQueryWrapper<EdFileInfo> queryWrapper = Wrappers.lambdaQuery(EdFileInfo.class)
|
||||||
.select(EdFileInfo::getId, EdFileInfo::getFileName)
|
.select(EdFileInfo::getId, EdFileInfo::getFileName)
|
||||||
.in(EdFileInfo::getId, ids);
|
.in(EdFileInfo::getId, ids);
|
||||||
|
|
@ -128,7 +142,7 @@ public class CommonService {
|
||||||
.likeRight(EdFileInfo::getFilePath, id));
|
.likeRight(EdFileInfo::getFilePath, id));
|
||||||
}
|
}
|
||||||
|
|
||||||
public ElectromagneticResult<?> addFolder(String parentId, String folderName, boolean maxLengthCheck, boolean isPrjDir) {
|
public ElectromagneticResult<?> addFolder(String parentId, String folderName, boolean maxLengthCheck, boolean isPrjDir, String folderId) {
|
||||||
|
|
||||||
// 验证名称是否合法
|
// 验证名称是否合法
|
||||||
Assert.isTrue(EleCommonUtil.isFileNameValid(folderName), "文件名不符合规范,只能包含中文字符、下划线、连字符、加号、数字和英文字符且长度小于32。");
|
Assert.isTrue(EleCommonUtil.isFileNameValid(folderName), "文件名不符合规范,只能包含中文字符、下划线、连字符、加号、数字和英文字符且长度小于32。");
|
||||||
|
|
@ -165,15 +179,13 @@ public class CommonService {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
int id = Integer.parseInt(edFileInfoMapper.maxPrjId());
|
|
||||||
Date now = new Date();
|
Date now = new Date();
|
||||||
String currentUserId = UserThreadLocal.getUserId();
|
String currentUserId = UserThreadLocal.getUserId();
|
||||||
String newFolderId = String.valueOf(id + 1);
|
String path = currentPath + MYSQL_FILE_PATH_SPLIT + folderId;
|
||||||
String path = currentPath + MYSQL_FILE_PATH_SPLIT + newFolderId;
|
|
||||||
EdFileInfo fileInfo = new EdFileInfo();
|
EdFileInfo fileInfo = new EdFileInfo();
|
||||||
String nowTimeStr = EleCommonUtil.getNowTimeStr();
|
String nowTimeStr = EleCommonUtil.getNowTimeStr();
|
||||||
fileInfo.setId(newFolderId)
|
fileInfo.setId(folderId)
|
||||||
.setFileId(newFolderId)
|
.setFileId(folderId)
|
||||||
.setFileName(folderName)
|
.setFileName(folderName)
|
||||||
.setFileVersion(FILE_START_VERSION)
|
.setFileVersion(FILE_START_VERSION)
|
||||||
.setParentId(parentId)
|
.setParentId(parentId)
|
||||||
|
|
@ -192,7 +204,7 @@ public class CommonService {
|
||||||
.setUpdatedBy(currentUserId);
|
.setUpdatedBy(currentUserId);
|
||||||
edFileInfoMapper.insert(fileInfo);
|
edFileInfoMapper.insert(fileInfo);
|
||||||
// 保存到文件系统
|
// 保存到文件系统
|
||||||
String targetFilePath = getEleDataPath() + File.separator + getPath(paths) + File.separator + folderName;
|
String targetFilePath = getEleDataPath() + File.separator + getDbPath(paths) + File.separator + folderName;
|
||||||
fileSystemService.createDirectory(targetFilePath);
|
fileSystemService.createDirectory(targetFilePath);
|
||||||
return ElectromagneticResultUtil.success(true);
|
return ElectromagneticResultUtil.success(true);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
|
@ -294,4 +306,15 @@ public class CommonService {
|
||||||
throw new BizException(-1, info);
|
throw new BizException(-1, info);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getCodePathByDbPath(String dbPath) {
|
||||||
|
List<String> paths = StrUtil.split(dbPath, MYSQL_FILE_PATH_SPLIT);
|
||||||
|
List<String> reversePaths = CollUtil.reverse(paths);
|
||||||
|
for (String path : reversePaths) {
|
||||||
|
if (path.length() == 6) {
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,44 +2,86 @@ package com.electromagnetic.industry.software.manage.service.serviceimpl;
|
||||||
|
|
||||||
import cn.hutool.core.bean.BeanUtil;
|
import cn.hutool.core.bean.BeanUtil;
|
||||||
import cn.hutool.core.codec.Base64;
|
import cn.hutool.core.codec.Base64;
|
||||||
|
import cn.hutool.core.collection.CollUtil;
|
||||||
import cn.hutool.core.io.FileUtil;
|
import cn.hutool.core.io.FileUtil;
|
||||||
|
import cn.hutool.core.io.IoUtil;
|
||||||
import cn.hutool.core.lang.Assert;
|
import cn.hutool.core.lang.Assert;
|
||||||
|
import cn.hutool.core.text.StrFormatter;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import cn.hutool.core.util.ZipUtil;
|
||||||
|
import cn.hutool.crypto.SecureUtil;
|
||||||
|
import cn.hutool.crypto.symmetric.AES;
|
||||||
|
import cn.hutool.json.JSONUtil;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
|
import com.electromagnetic.industry.software.common.enums.EffectFlagEnum;
|
||||||
|
import com.electromagnetic.industry.software.common.enums.EleDataTypeEnum;
|
||||||
|
import com.electromagnetic.industry.software.common.enums.PublishEnum;
|
||||||
import com.electromagnetic.industry.software.common.exception.BizException;
|
import com.electromagnetic.industry.software.common.exception.BizException;
|
||||||
import com.electromagnetic.industry.software.common.resp.ElectromagneticResult;
|
import com.electromagnetic.industry.software.common.resp.ElectromagneticResult;
|
||||||
import com.electromagnetic.industry.software.common.util.EleLog;
|
import com.electromagnetic.industry.software.common.util.*;
|
||||||
import com.electromagnetic.industry.software.common.util.ElectromagneticResultUtil;
|
|
||||||
import com.electromagnetic.industry.software.manage.mapper.EdFileInfoMapper;
|
import com.electromagnetic.industry.software.manage.mapper.EdFileInfoMapper;
|
||||||
import com.electromagnetic.industry.software.manage.pojo.models.EdFileInfo;
|
import com.electromagnetic.industry.software.manage.pojo.models.EdFileInfo;
|
||||||
import com.electromagnetic.industry.software.manage.pojo.other.FileInfoDTO;
|
import com.electromagnetic.industry.software.manage.pojo.other.FileInfoDTO;
|
||||||
|
import com.electromagnetic.industry.software.manage.pojo.req.FileChunkDTO;
|
||||||
|
import com.electromagnetic.industry.software.manage.pojo.req.FileChunkResultDTO;
|
||||||
import com.electromagnetic.industry.software.manage.pojo.req.FileInfoQueryDTO;
|
import com.electromagnetic.industry.software.manage.pojo.req.FileInfoQueryDTO;
|
||||||
|
import com.electromagnetic.industry.software.manage.pojo.req.UpdateFileInfoDTO;
|
||||||
import com.electromagnetic.industry.software.manage.pojo.resp.FileInfoQueryPageVO;
|
import com.electromagnetic.industry.software.manage.pojo.resp.FileInfoQueryPageVO;
|
||||||
|
import com.electromagnetic.industry.software.manage.pojo.resp.FileVersionViewVO;
|
||||||
import com.electromagnetic.industry.software.manage.service.EdFileInfoService;
|
import com.electromagnetic.industry.software.manage.service.EdFileInfoService;
|
||||||
|
import com.electromagnetic.industry.software.manage.service.FileSystemService;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.core.env.Environment;
|
||||||
import org.springframework.core.io.FileSystemResource;
|
import org.springframework.core.io.FileSystemResource;
|
||||||
import org.springframework.core.io.InputStreamResource;
|
import org.springframework.core.io.InputStreamResource;
|
||||||
import org.springframework.http.HttpHeaders;
|
import org.springframework.http.HttpHeaders;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import javax.annotation.PostConstruct;
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import java.io.IOException;
|
import java.io.*;
|
||||||
import java.net.BindException;
|
import java.nio.charset.Charset;
|
||||||
import java.util.List;
|
import java.nio.file.Files;
|
||||||
import java.util.Objects;
|
import java.nio.file.Paths;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import static com.electromagnetic.industry.software.common.cons.ElectromagneticConstants.*;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class EdFileInfoServiceImpl extends ServiceImpl<EdFileInfoMapper, EdFileInfo> implements EdFileInfoService {
|
public class EdFileInfoServiceImpl extends ServiceImpl<EdFileInfoMapper, EdFileInfo> implements EdFileInfoService {
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private CommonService commonService;
|
private CommonService commonService;
|
||||||
|
|
||||||
private EleLog log = new EleLog(EdFileInfoServiceImpl.class);
|
private EleLog log = new EleLog(EdFileInfoServiceImpl.class);
|
||||||
|
@Autowired
|
||||||
|
private FileSystemService fileSystemService;
|
||||||
|
@Resource
|
||||||
|
private Environment environment;
|
||||||
|
|
||||||
|
private String downloadDataDir = "";
|
||||||
|
private String uploadDataDir = "";
|
||||||
|
|
||||||
|
|
||||||
|
@Value("${file.security.passwd}")
|
||||||
|
private String password;
|
||||||
|
|
||||||
|
|
||||||
|
@PostConstruct
|
||||||
|
public void init() {
|
||||||
|
String osName = System.getProperty("os.name").toLowerCase();
|
||||||
|
uploadDataDir = osName.startsWith("win") ? environment.getProperty("data.upload.windows.tmp.path") : environment.getProperty("data.upload.linux.tmp.path");
|
||||||
|
downloadDataDir = osName.startsWith("win") ? environment.getProperty("data.download.windows.tmp.path") : environment.getProperty("data.download.linux.tmp.path");
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询文件列表
|
* 查询文件列表
|
||||||
|
|
@ -86,12 +128,12 @@ public class EdFileInfoServiceImpl extends ServiceImpl<EdFileInfoMapper, EdFileI
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public ElectromagneticResult<?> createFolder(String parentId, String newFolderName) {
|
public ElectromagneticResult<?> createFolder(String parentId, String newFolderName) {
|
||||||
return commonService.addFolder(parentId, newFolderName, false, false);
|
String folderId = IdWorker.getSnowFlakeIdString();
|
||||||
|
return commonService.addFolder(parentId, newFolderName, false, false, folderId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 项目层级结构查询
|
* 项目层级结构查询
|
||||||
*
|
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -121,7 +163,6 @@ public class EdFileInfoServiceImpl extends ServiceImpl<EdFileInfoMapper, EdFileI
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 下载文件
|
* 下载文件
|
||||||
*
|
|
||||||
* @param id
|
* @param id
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
|
|
@ -130,7 +171,7 @@ public class EdFileInfoServiceImpl extends ServiceImpl<EdFileInfoMapper, EdFileI
|
||||||
|
|
||||||
try {
|
try {
|
||||||
EdFileInfo fileInfo = this.baseMapper.selectOne(Wrappers.<EdFileInfo>lambdaQuery().eq(EdFileInfo::getId, id));
|
EdFileInfo fileInfo = this.baseMapper.selectOne(Wrappers.<EdFileInfo>lambdaQuery().eq(EdFileInfo::getId, id));
|
||||||
String fileSysPath = commonService.getFileSysPath(fileInfo.getFilePath());
|
String fileSysPath = commonService.getFileSysPath(fileInfo.getFilePath()) + "." + fileInfo.getFileCode();
|
||||||
Assert.isTrue(FileUtil.exist(fileSysPath), "下载文件不存在。");
|
Assert.isTrue(FileUtil.exist(fileSysPath), "下载文件不存在。");
|
||||||
FileSystemResource fileSystemResource = new FileSystemResource(fileSysPath);
|
FileSystemResource fileSystemResource = new FileSystemResource(fileSysPath);
|
||||||
HttpHeaders headers = new HttpHeaders();
|
HttpHeaders headers = new HttpHeaders();
|
||||||
|
|
@ -152,4 +193,502 @@ public class EdFileInfoServiceImpl extends ServiceImpl<EdFileInfoMapper, EdFileI
|
||||||
throw new BizException(-1, info);
|
throw new BizException(-1, info);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新文件信息
|
||||||
|
* @param updateFileInfoDTO
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public ElectromagneticResult<?> updateFileInfo(UpdateFileInfoDTO updateFileInfoDTO) {
|
||||||
|
try {
|
||||||
|
EdFileInfo fileInfo = this.baseMapper.selectById(updateFileInfoDTO.getId());
|
||||||
|
this.baseMapper.update(null, Wrappers.lambdaUpdate(EdFileInfo.class)
|
||||||
|
.eq(EdFileInfo::getId, updateFileInfoDTO.getId())
|
||||||
|
.set(EdFileInfo::getFileName, updateFileInfoDTO.getFileName())
|
||||||
|
.set(EdFileInfo::getFileNote, updateFileInfoDTO.getFileNote()));
|
||||||
|
String sysFilePath = commonService.getFileSysPath(fileInfo.getFilePath());
|
||||||
|
fileSystemService.renameFile(sysFilePath, updateFileInfoDTO.getFileName());
|
||||||
|
return ElectromagneticResultUtil.success(true);
|
||||||
|
} catch (Exception e) {
|
||||||
|
String info = "更新文件信息失败。";
|
||||||
|
log.error(info, e);
|
||||||
|
throw new BizException(-1, e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 版本回退
|
||||||
|
*
|
||||||
|
* @param fileId
|
||||||
|
* @param targetVersion
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public ElectromagneticResult<?> versionBack(String fileId, int targetVersion) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
this.baseMapper.update(null, Wrappers.lambdaUpdate(EdFileInfo.class)
|
||||||
|
.set(EdFileInfo::getFileId, fileId)
|
||||||
|
.set(EdFileInfo::getEffectFlag, false));
|
||||||
|
this.baseMapper.update(null, Wrappers.lambdaUpdate(EdFileInfo.class)
|
||||||
|
.set(EdFileInfo::getEffectFlag, true)
|
||||||
|
.eq(EdFileInfo::getFileId, fileId)
|
||||||
|
.eq(EdFileInfo::getFileVersion, targetVersion));
|
||||||
|
} catch (Exception e) {
|
||||||
|
String info = "版本回退失败。";
|
||||||
|
log.error(info, e);
|
||||||
|
throw new BizException(-1, info);
|
||||||
|
}
|
||||||
|
return ElectromagneticResultUtil.success(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查看分片是否存在
|
||||||
|
* @param fileChunkDTO
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public ElectromagneticResult<?> checkChunkExist(FileChunkDTO fileChunkDTO) {
|
||||||
|
String currentUserId = UserThreadLocal.getUserId();
|
||||||
|
String userUploadFolder = uploadDataDir + File.separator + currentUserId;
|
||||||
|
String identifier = fileChunkDTO.getIdentifier();
|
||||||
|
List<Integer> uploadedChunks = getUploadedChunks(identifier, userUploadFolder);
|
||||||
|
return ElectromagneticResultUtil.success(new FileChunkResultDTO(false, new HashSet<>(uploadedChunks)));
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<Integer> getUploadedChunks(String identifier, String destPath) {
|
||||||
|
String filePath = destPath + File.separator + identifier;
|
||||||
|
if (!FileUtil.exist(new File(filePath))) {
|
||||||
|
return new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
return FileUtil.listFileNames(destPath)
|
||||||
|
.stream()
|
||||||
|
.map(e -> e.replace(UPLOAD_FILE_CHUNK_SUFFIX, ""))
|
||||||
|
.map(Integer::parseInt)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量导入
|
||||||
|
* @param fileChunkDTO
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public ElectromagneticResult<?> batchImport(FileChunkDTO fileChunkDTO) {
|
||||||
|
String currentUserId = UserThreadLocal.getUserId();
|
||||||
|
String identifier = fileChunkDTO.getIdentifier();
|
||||||
|
// 首先检查该分片有没被上传,如果有则禁止上传
|
||||||
|
String destPath = uploadDataDir + File.separator + currentUserId + File.separator + identifier + fileChunkDTO.getChunkNumber() + UPLOAD_FILE_CHUNK_SUFFIX;
|
||||||
|
boolean exist = FileUtil.exist(destPath);
|
||||||
|
if (exist) {
|
||||||
|
return ElectromagneticResultUtil.fail("-1", "文件已经存在,请勿重复上传");
|
||||||
|
}
|
||||||
|
try (
|
||||||
|
InputStream inputStream = fileChunkDTO.getFile().getInputStream();
|
||||||
|
FileOutputStream fileOutputStream = new FileOutputStream(destPath);
|
||||||
|
) {
|
||||||
|
IoUtil.copy(inputStream, fileOutputStream);
|
||||||
|
} catch (IOException ioException) {
|
||||||
|
log.error("上传文件失败...", ioException);
|
||||||
|
throw new BizException(-1, "上传文件失败");
|
||||||
|
}
|
||||||
|
return ElectromagneticResultUtil.success(fileChunkDTO.getIdentifier());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 合并分片
|
||||||
|
* @param identifier
|
||||||
|
* @param fileName
|
||||||
|
* @param totalChunks
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@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);
|
||||||
|
AES aes = SecureUtil.aes(password.getBytes());
|
||||||
|
try(
|
||||||
|
InputStream inputStream = Files.newInputStream(Paths.get(destZipPath));
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
private void update2FileSystem(String zipDirPath) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出
|
||||||
|
*
|
||||||
|
* @param dataIdArr
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public ResponseEntity<InputStreamResource> batchExport(String dataIdArr, HttpServletResponse response) throws IOException {
|
||||||
|
String[] ids = dataIdArr.split(",");
|
||||||
|
List<EdFileInfo> resFiles = new ArrayList<>();
|
||||||
|
for (String id : ids) {
|
||||||
|
List<EdFileInfo> edFileInfos = this.baseMapper.selectList(Wrappers.lambdaQuery(EdFileInfo.class)
|
||||||
|
.like(EdFileInfo::getFilePath, MYSQL_FILE_PATH_SPLIT + id + MYSQL_FILE_PATH_SPLIT)
|
||||||
|
.eq(EdFileInfo::getEffectFlag, true));
|
||||||
|
resFiles.addAll(edFileInfos);
|
||||||
|
}
|
||||||
|
String prjName = resFiles.stream().filter(e -> e.getParentId().equals(PRJ_PARENT_ID)).findFirst().get().getFileName();
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
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 mysqlInfo = JSONUtil.toJsonStr(resFiles);
|
||||||
|
FileUtil.writeString(mysqlInfo, downloadDataDir + File.separator + "mysql.info", Charset.defaultCharset());
|
||||||
|
String exportZipFile = downloadDataDir + File.separator + prjName + ".zip";
|
||||||
|
String exportColibFile = downloadDataDir + File.separator + prjName + EXPORT_FILE_SUFFIX;
|
||||||
|
ZipUtil.zip(downloadDataDir + File.separator + prjName, exportZipFile);
|
||||||
|
AES aes = SecureUtil.aes(password.getBytes());
|
||||||
|
try(
|
||||||
|
InputStream inputStream = Files.newInputStream(Paths.get(exportZipFile));
|
||||||
|
OutputStream outputStream = Files.newOutputStream(Paths.get(exportColibFile));
|
||||||
|
) {
|
||||||
|
aes.encrypt(inputStream, outputStream, true);
|
||||||
|
} catch (Exception e) {
|
||||||
|
String info = "导出失败。";
|
||||||
|
log.error(info, e);
|
||||||
|
throw new BizException(-1, info);
|
||||||
|
} finally {
|
||||||
|
FileUtil.del(exportZipFile);
|
||||||
|
}
|
||||||
|
File file = new File(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()
|
||||||
|
.headers(headers)
|
||||||
|
.contentLength(fileSystemResource.contentLength())
|
||||||
|
.contentType(MediaType.parseMediaType("application/octet-stream"))
|
||||||
|
.body(new InputStreamResource(fileSystemResource.getInputStream()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件上传
|
||||||
|
* @param parentId
|
||||||
|
* @param file
|
||||||
|
* @param strategy 1-跳过冲突文件 2-做版本更新 3-重命名,文件名加“_1"
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public ElectromagneticResult<?> upload(String parentId, MultipartFile file, Integer strategy) {
|
||||||
|
// 首先检查是否是同名文件
|
||||||
|
try {
|
||||||
|
String fileName = file.getOriginalFilename();
|
||||||
|
String mainName = FileUtil.mainName(fileName);
|
||||||
|
String suffix = FileUtil.getSuffix(fileName);
|
||||||
|
Assert.isTrue(EleCommonUtil.isFileNameValid(fileName), "文件名不符合规范,只能包含中文字符、下划线、连字符、加号、数字和英文字符且长度小于32。");
|
||||||
|
Long count = this.baseMapper.selectCount(Wrappers.lambdaQuery(EdFileInfo.class)
|
||||||
|
.eq(EdFileInfo::getParentId, parentId)
|
||||||
|
.eq(EdFileInfo::getFileName, mainName)
|
||||||
|
.eq(EdFileInfo::getEffectFlag, EffectFlagEnum.EFFECT.code)
|
||||||
|
.eq(EdFileInfo::getFileType, suffix));
|
||||||
|
if (count > 0) {
|
||||||
|
handUploadRepeatFile(parentId, file, strategy);
|
||||||
|
} else {
|
||||||
|
EdFileInfo parentFolderInfo = this.baseMapper.selectOne(Wrappers.lambdaQuery(EdFileInfo.class)
|
||||||
|
.eq(EdFileInfo::getId, parentId)
|
||||||
|
.eq(EdFileInfo::getEffectFlag, EffectFlagEnum.EFFECT.code));
|
||||||
|
EdFileInfo newEdFileInfo = new EdFileInfo();
|
||||||
|
newEdFileInfo.newInit();
|
||||||
|
String codePathByDbPath = commonService.getCodePathByDbPath(parentFolderInfo.getFilePath());
|
||||||
|
String fileCode = commonService.createFileCode(codePathByDbPath, suffix, FILE_START_VERSION, newEdFileInfo.getFileTime());
|
||||||
|
newEdFileInfo.setParentId(parentId)
|
||||||
|
.setFileCode(fileCode)
|
||||||
|
.setFileName(mainName)
|
||||||
|
.setFileType(suffix)
|
||||||
|
.setFileVersion(FILE_START_VERSION)
|
||||||
|
.setFileSize(file.getSize())
|
||||||
|
.setFilePath(parentFolderInfo.getFilePath() + MYSQL_FILE_PATH_SPLIT + newEdFileInfo.getId())
|
||||||
|
.setDataType(EleDataTypeEnum.FILE.code)
|
||||||
|
.setDataStatus(PublishEnum.PUBLISHED.getCode())
|
||||||
|
.setEffectFlag(EffectFlagEnum.EFFECT.code)
|
||||||
|
.setFileCode(fileCode)
|
||||||
|
.setPrjDir(false);
|
||||||
|
this.baseMapper.insert(newEdFileInfo);
|
||||||
|
String fileDestPath = commonService.getFileSysPath(parentFolderInfo.getFileId()) + File.separator + mainName + suffix + "." + fileCode;
|
||||||
|
fileSystemService.save(file.getInputStream(), fileDestPath);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
String info = "上传文件失败";
|
||||||
|
log.error(info, e);
|
||||||
|
throw new BizException(-1, info);
|
||||||
|
}
|
||||||
|
return ElectromagneticResultUtil.success(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 版本查看
|
||||||
|
*
|
||||||
|
* @param fileId
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public ElectromagneticResult<?> versionView(String fileId) {
|
||||||
|
List<EdFileInfo> edFileInfos = this.baseMapper.selectList(Wrappers.lambdaQuery(EdFileInfo.class)
|
||||||
|
.select(EdFileInfo::getId, EdFileInfo::getFileId, EdFileInfo::getFileVersion, EdFileInfo::getPreVersion, EdFileInfo::getFileCode, EdFileInfo::getEffectFlag)
|
||||||
|
.eq(EdFileInfo::getFileId, fileId));
|
||||||
|
List<FileVersionViewVO> fileVersionViewVOS = BeanUtil.copyToList(edFileInfos, FileVersionViewVO.class);
|
||||||
|
return ElectromagneticResultUtil.success(fileVersionViewVOS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 移动文件
|
||||||
|
*
|
||||||
|
* @param id
|
||||||
|
* @param targetFolderId
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public ElectromagneticResult<?> moveFile(String id, String targetFolderId, Integer strategy) {
|
||||||
|
return moveFile(id, targetFolderId, strategy, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handMoveConflict(String targetFolderId, Integer strategy, EdFileInfo srcFileInfo, EdFileInfo destFolderInfo, boolean deleteSrc) {
|
||||||
|
if (strategy == 2) {
|
||||||
|
// 做版本更新
|
||||||
|
List<EdFileInfo> sameFileInfos = this.baseMapper.selectList(Wrappers.lambdaQuery(EdFileInfo.class)
|
||||||
|
.eq(EdFileInfo::getParentId, targetFolderId)
|
||||||
|
.eq(EdFileInfo::getFileName, srcFileInfo.getFileName())
|
||||||
|
.eq(EdFileInfo::getFileType, srcFileInfo.getFileType()));
|
||||||
|
Integer maxFileVersion = Collections.max(sameFileInfos, Comparator.comparing(EdFileInfo::getFileVersion)).getFileVersion();
|
||||||
|
String newFileDbId = IdWorker.getSnowFlakeIdString();
|
||||||
|
String fileTime = EleCommonUtil.getNowTimeStr();
|
||||||
|
String fileCode = commonService.createFileCode(targetFolderId, srcFileInfo.getFileType(), maxFileVersion + 1, fileTime);
|
||||||
|
EdFileInfo destSaveFileInfo = BeanUtil.copyProperties(sameFileInfos.get(0), EdFileInfo.class);
|
||||||
|
destSaveFileInfo.newInit();
|
||||||
|
destSaveFileInfo.setFileVersion(maxFileVersion + 1)
|
||||||
|
.setFilePath(destSaveFileInfo + MYSQL_FILE_PATH_SPLIT + newFileDbId)
|
||||||
|
.setPreVersion(maxFileVersion)
|
||||||
|
.setEffectFlag(EffectFlagEnum.EFFECT.code)
|
||||||
|
.setFileCode(fileCode);
|
||||||
|
this.baseMapper.insert(destSaveFileInfo);
|
||||||
|
} else if (strategy == 3) {
|
||||||
|
// 文件名加“_1”,版本号从100开始
|
||||||
|
// 处理MySQL相关逻辑
|
||||||
|
EdFileInfo newEdFileInfo = BeanUtil.copyProperties(srcFileInfo, EdFileInfo.class);
|
||||||
|
newEdFileInfo.newInit();
|
||||||
|
newEdFileInfo.setParentId(targetFolderId)
|
||||||
|
.setFileVersion(FILE_START_VERSION)
|
||||||
|
.setFileName(srcFileInfo.getFileName() + "_1")
|
||||||
|
.setFileCode(commonService.createFileCode(targetFolderId, srcFileInfo.getFileType(), FILE_START_VERSION, newEdFileInfo.getFileTime()))
|
||||||
|
.setFilePath(destFolderInfo.getFilePath() + MYSQL_FILE_PATH_SPLIT + newEdFileInfo.getId());
|
||||||
|
this.baseMapper.insert(newEdFileInfo);
|
||||||
|
// 移动文件
|
||||||
|
String srcFileSysPath = commonService.getFileSysPath(srcFileInfo.getFilePath());
|
||||||
|
String destFileSysPath = commonService.getFileSysPath(destFolderInfo.getFilePath());
|
||||||
|
fileSystemService.moveFile(srcFileSysPath, destFileSysPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private ElectromagneticResult<?> moveFile(String id, String targetFolderId, Integer strategy, boolean deleteSrc) {
|
||||||
|
// 获取原文件mysql模型
|
||||||
|
EdFileInfo srcFileInfo = this.baseMapper.selectById(id);
|
||||||
|
// 判断目标路径下是否有同名文件,如果所有的同名文件:1)如果所有文件都已经被作废,则该文件为新文件,版本号从100开始。2)如果有没有被作废的文件,则冲突处理方式按---1-跳过冲突文件 2-做版本更新 3-重命名,文件名加"_1"
|
||||||
|
List<EdFileInfo> destFolderFiles = this.baseMapper.selectList(Wrappers.lambdaQuery(EdFileInfo.class).eq(EdFileInfo::getParentId, targetFolderId));
|
||||||
|
EdFileInfo destFolderInfo = this.baseMapper.selectOne(Wrappers.lambdaQuery(EdFileInfo.class).eq(EdFileInfo::getId, targetFolderId));
|
||||||
|
List<EdFileInfo> effectFileInfos = destFolderFiles.stream().filter(e -> Objects.equals(e.getEffectFlag(), EffectFlagEnum.EFFECT.code)).collect(Collectors.toList());
|
||||||
|
if (CollUtil.isEmpty(effectFileInfos) || CollUtil.isEmpty(destFolderFiles)) {
|
||||||
|
// 没有同名文件
|
||||||
|
// 首先将信息保存到MySQL
|
||||||
|
EdFileInfo destSaveFileInfo = BeanUtil.copyProperties(srcFileInfo, EdFileInfo.class);
|
||||||
|
destSaveFileInfo.newInit();
|
||||||
|
String fileTime = EleCommonUtil.getNowTimeStr();
|
||||||
|
String newFileCode = commonService.createFileCode(targetFolderId, srcFileInfo.getFileType(), FILE_START_VERSION, fileTime);
|
||||||
|
destSaveFileInfo.setParentId(targetFolderId)
|
||||||
|
.setFileVersion(FILE_START_VERSION)
|
||||||
|
.setFileTime(fileTime)
|
||||||
|
.setFilePath(destFolderInfo.getFilePath() + MYSQL_FILE_PATH_SPLIT + destSaveFileInfo.getId())
|
||||||
|
.setFileCode(newFileCode);
|
||||||
|
this.baseMapper.insert(destSaveFileInfo);
|
||||||
|
// 文件系统移动文件
|
||||||
|
String srcFilePath = commonService.getFileSysPath(srcFileInfo.getFileId()) + File.separator + srcFileInfo.getFileCode();
|
||||||
|
String destFilePath = commonService.getFileSysPath(destFolderInfo.getFileId()) + File.separator + destFolderInfo.getFileCode();
|
||||||
|
fileSystemService.moveFile(srcFilePath, destFilePath);
|
||||||
|
} else {
|
||||||
|
handMoveConflict(targetFolderId, strategy, srcFileInfo, destFolderInfo, deleteSrc);
|
||||||
|
}
|
||||||
|
// 将以前的版本effect全部置为false,删除原目录下的同名文件
|
||||||
|
if (deleteSrc) {
|
||||||
|
this.baseMapper.update(null, Wrappers.lambdaUpdate(EdFileInfo.class)
|
||||||
|
.set(EdFileInfo::getEffectFlag, EffectFlagEnum.NOT_EFFECTIVE.code)
|
||||||
|
.eq(EdFileInfo::getParentId, srcFileInfo.getParentId())
|
||||||
|
.eq(EdFileInfo::getFileName, srcFileInfo.getFileName())
|
||||||
|
.eq(EdFileInfo::getFileType, srcFileInfo.getFileType()));
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 复制文件
|
||||||
|
* @param id
|
||||||
|
* @param targetFolderId
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public ElectromagneticResult<?> copyFile(String id, String targetFolderId, Integer strategy) {
|
||||||
|
return moveFile(id, targetFolderId, strategy, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private 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);
|
||||||
|
String suffix = FileUtil.getSuffix(fileName);
|
||||||
|
if (strategy == 2) {
|
||||||
|
// 版本更新
|
||||||
|
// step1:找到同名文件的MySQL对象
|
||||||
|
List<EdFileInfo> parentFileInfos = this.baseMapper.selectList(Wrappers.lambdaQuery(EdFileInfo.class)
|
||||||
|
.eq(EdFileInfo::getParentId, parentId)
|
||||||
|
.eq(EdFileInfo::getFileName, mainName)
|
||||||
|
.eq(EdFileInfo::getFileType, suffix));
|
||||||
|
EdFileInfo parentFileInfo = this.baseMapper.selectOne(Wrappers.lambdaQuery(EdFileInfo.class)
|
||||||
|
.eq(EdFileInfo::getId, parentId)
|
||||||
|
.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);
|
||||||
|
String codePathByDbPath = commonService.getCodePathByDbPath(effectFileInfo.getFilePath());
|
||||||
|
String timeStr = EleCommonUtil.getNowTimeStr();
|
||||||
|
String fileCode = commonService.createFileCode(codePathByDbPath, suffix, FILE_START_VERSION, timeStr);
|
||||||
|
// 将原有效的版本置为false
|
||||||
|
this.baseMapper.update(null, Wrappers.lambdaUpdate(EdFileInfo.class)
|
||||||
|
.set(EdFileInfo::getEffectFlag, EffectFlagEnum.NOT_EFFECTIVE.code)
|
||||||
|
.eq(EdFileInfo::getId, effectFileInfo.getId()));
|
||||||
|
// 新增文件
|
||||||
|
EdFileInfo newEdFileInfo = new EdFileInfo();
|
||||||
|
newEdFileInfo.newInit();
|
||||||
|
newEdFileInfo.setFileId(effectFileInfo.getFileId())
|
||||||
|
.setParentId(parentId)
|
||||||
|
.setFileCode(fileCode)
|
||||||
|
.setFileName(mainName)
|
||||||
|
.setFileType(suffix)
|
||||||
|
.setFileContent("")
|
||||||
|
.setFileVersion(maxFileVersion + 1)
|
||||||
|
.setPreVersion(maxFileVersion)
|
||||||
|
.setFileNote("")
|
||||||
|
.setFileTime(timeStr)
|
||||||
|
.setFileSize(file.getSize())
|
||||||
|
.setFilePath(parentFileInfo.getFilePath() + MYSQL_FILE_PATH_SPLIT + newEdFileInfo.getId())
|
||||||
|
.setDataType(EleDataTypeEnum.FILE.code)
|
||||||
|
.setDataStatus(PublishEnum.PUBLISHED.getCode())
|
||||||
|
.setEffectFlag(EffectFlagEnum.EFFECT.code)
|
||||||
|
.setFileCode(fileCode)
|
||||||
|
.setPrjDir(false);
|
||||||
|
this.baseMapper.insert(newEdFileInfo);
|
||||||
|
String fileDestPath = commonService.getFileSysPath(newEdFileInfo.getFileId()) + File.separator + mainName + suffix + "." + fileCode;
|
||||||
|
FileUtil.writeFromStream(file.getInputStream(), fileDestPath);
|
||||||
|
} else if (strategy == 3) {
|
||||||
|
// 文件名加”_1“,存为新文件
|
||||||
|
EdFileInfo parentFileInfo = this.baseMapper.selectOne(Wrappers.lambdaQuery(EdFileInfo.class)
|
||||||
|
.eq(EdFileInfo::getId, parentId)
|
||||||
|
.eq(EdFileInfo::getEffectFlag, EffectFlagEnum.EFFECT.code));
|
||||||
|
String codePathByDbPath = commonService.getCodePathByDbPath(parentFileInfo.getFilePath());
|
||||||
|
EdFileInfo newEdFileInfo = new EdFileInfo();
|
||||||
|
newEdFileInfo.newInit();
|
||||||
|
String fileCode = commonService.createFileCode(codePathByDbPath, suffix, FILE_START_VERSION, newEdFileInfo.getFileTime());
|
||||||
|
newEdFileInfo.setParentId(parentId)
|
||||||
|
.setFileCode(fileCode)
|
||||||
|
.setFileName(mainName + "_1")
|
||||||
|
.setFileType(suffix)
|
||||||
|
.setFileVersion(FILE_START_VERSION)
|
||||||
|
.setFileTime(newEdFileInfo.getFileTime())
|
||||||
|
.setFileSize(file.getSize())
|
||||||
|
.setFilePath(parentFileInfo.getFilePath() + MYSQL_FILE_PATH_SPLIT + newEdFileInfo.getId())
|
||||||
|
.setDataType(EleDataTypeEnum.FILE.code)
|
||||||
|
.setDataStatus(PublishEnum.PUBLISHED.getCode())
|
||||||
|
.setEffectFlag(EffectFlagEnum.EFFECT.code)
|
||||||
|
.setFileCode(fileCode)
|
||||||
|
.setPrjDir(false);
|
||||||
|
this.baseMapper.insert(newEdFileInfo);
|
||||||
|
String fileDestPath = commonService.getFileSysPath(parentFileInfo.getFileId()) + File.separator + mainName + "_1." + suffix + "." + fileCode;
|
||||||
|
FileUtil.writeFromStream(file.getInputStream(), fileDestPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private String doSysFileMerge(String identifier, String fileName, Integer totalChunks) {
|
||||||
|
String currentUserId = UserThreadLocal.getUserId();
|
||||||
|
for (int i = 1; i <= totalChunks; i++) {
|
||||||
|
String tmpPath = uploadDataDir + File.separator + currentUserId + identifier + File.separator + i + UPLOAD_FILE_CHUNK_SUFFIX;
|
||||||
|
if (!FileUtil.exist(new File(tmpPath))) {
|
||||||
|
String info = StrFormatter.format("第{}个分片没有上传完成,请上传完成后再合并。", i);
|
||||||
|
log.error(info);
|
||||||
|
throw new BizException(-1, info);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 合并分片
|
||||||
|
String destZipPath = uploadDataDir + File.separator + currentUserId + File.separator + identifier + File.separator + fileName;
|
||||||
|
File[] partFiles = FileUtil.ls(uploadDataDir + File.separator + currentUserId + File.separator + identifier);
|
||||||
|
|
||||||
|
for (File partFile : partFiles) {
|
||||||
|
try (BufferedOutputStream outputStream = FileUtil.getOutputStream(destZipPath);
|
||||||
|
BufferedInputStream inputStream = FileUtil.getInputStream(partFile)) {
|
||||||
|
IoUtil.copy(inputStream, outputStream);
|
||||||
|
} catch (Exception e) {
|
||||||
|
FileUtil.del(destZipPath);
|
||||||
|
String info = "文件合并失败";
|
||||||
|
log.error(info, e);
|
||||||
|
throw new BizException(-1, info);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Arrays.stream(partFiles).forEach(e -> FileUtil.del(e.getAbsolutePath()));
|
||||||
|
return destZipPath;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -198,7 +198,6 @@ public class EdPrjServiceImpl extends ServiceImpl<EdFileInfoMapper, EdFileInfo>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 添加子集
|
* 添加子集
|
||||||
*
|
|
||||||
* @param parentId
|
* @param parentId
|
||||||
* @param folderName
|
* @param folderName
|
||||||
* @return
|
* @return
|
||||||
|
|
@ -206,12 +205,13 @@ public class EdPrjServiceImpl extends ServiceImpl<EdFileInfoMapper, EdFileInfo>
|
||||||
@Override
|
@Override
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public ElectromagneticResult<?> addFolder(String parentId, String folderName) {
|
public ElectromagneticResult<?> addFolder(String parentId, String folderName) {
|
||||||
return commonService.addFolder(parentId, folderName, true, true);
|
int id = Integer.parseInt(this.baseMapper.maxPrjId());
|
||||||
|
String folderId = String.valueOf(id + 1);
|
||||||
|
return commonService.addFolder(parentId, folderName, true, true, folderId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询所有项目
|
* 查询所有项目
|
||||||
*
|
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ public class FileSystemServiceImpl implements FileSystemService {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void save(InputStream inputStream, String destination) {
|
public void save(InputStream inputStream, String destination) {
|
||||||
|
FileUtil.writeFromStream(inputStream, destination);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -13,8 +13,13 @@ spring.servlet.multipart.max-request-size=10MB
|
||||||
pagehelper.helperDialect=mysql
|
pagehelper.helperDialect=mysql
|
||||||
pagehelper.reasonable=false
|
pagehelper.reasonable=false
|
||||||
server.port=12395
|
server.port=12395
|
||||||
|
file.security.passwd=adknfhkj87654knd
|
||||||
#windows文件存储目录,用于测试
|
#windows文件存储目录,用于测试
|
||||||
data.windows.path=E:/tmp/eleData/
|
data.windows.path=D:/tmp/eleData/project/
|
||||||
data.linux.path=/szsd/data/eleData
|
data.linux.path=/szsd/data/eleData/project/
|
||||||
|
data.upload.windows.tmp.path=D:/tmp/eleData/upload/
|
||||||
|
data.upload.linux.tmp.path=/szsd/data/eleData/upload/
|
||||||
|
data.download.windows.tmp.path=D:/tmp/eleData/download/
|
||||||
|
data.download.linux.tmp.path=/szsd/data/eleData/download/
|
||||||
prj.folder.max.length=6
|
prj.folder.max.length=6
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,4 +9,6 @@ public interface ElectromagneticConstants {
|
||||||
int FILE_START_VERSION = 100;
|
int FILE_START_VERSION = 100;
|
||||||
|
|
||||||
String PRJ_PARENT_ID = "0";
|
String PRJ_PARENT_ID = "0";
|
||||||
|
|
||||||
|
String UPLOAD_FILE_CHUNK_SUFFIX = ".part";
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
package com.electromagnetic.industry.software.common.util;
|
package com.electromagnetic.industry.software.common.util;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
@ -35,7 +37,7 @@ public final class EleCommonUtil {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isFileNameValid(String fileFullName) {
|
public static boolean isFileNameValid(String fileFullName) {
|
||||||
if (fileFullName.length() > 32) {
|
if (StrUtil.isEmpty(fileFullName) || fileFullName.length() > 32) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return pattern.matcher(fileFullName).matches();
|
return pattern.matcher(fileFullName).matches();
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue