修改文件下载模式,完善文件删除逻辑,
This commit is contained in:
parent
cb98c405f4
commit
5bb693e2b7
@ -65,8 +65,8 @@ public class FileController extends AbstractController {
|
||||
@ApiImplicitParam(name = "ids", value = "ID列表,用下划线分隔", paramType = "path", example = "1_2_3")
|
||||
})
|
||||
@ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)})
|
||||
@DeleteMapping("removearticlecategory/{isRemoveSource}/{ids}")
|
||||
public SuccessResult removeFile(@PathVariable() Integer isRemoveSource, @PathVariable("ids") String ids) throws RemoveException {
|
||||
@DeleteMapping("removefile/{isRemoveSource}/{ids}")
|
||||
public synchronized SuccessResult removeFile(@PathVariable() Integer isRemoveSource, @PathVariable("ids") String ids) throws RemoveException {
|
||||
if (isRemoveSource == 0) {
|
||||
fileService.removeFile(ids);
|
||||
}
|
||||
|
@ -46,6 +46,14 @@ public interface IFileDao {
|
||||
*/
|
||||
void deleteFile(Map<String, Object> params) throws RemoveException;
|
||||
|
||||
/**
|
||||
* 更新文件描述
|
||||
*
|
||||
* @param fileParams
|
||||
* @throws SearchException
|
||||
*/
|
||||
void updateFileSummary(Map<String, Object> fileParams) throws SearchException;
|
||||
|
||||
/**
|
||||
* 获取文件详情
|
||||
*
|
||||
@ -89,4 +97,6 @@ public interface IFileDao {
|
||||
* @throws SearchException
|
||||
*/
|
||||
List<FileInfoDTO> listFileByMd5(String fileMd5) throws SearchException;
|
||||
|
||||
|
||||
}
|
||||
|
@ -42,6 +42,9 @@ import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.*;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.channels.Channels;
|
||||
import java.nio.channels.FileChannel;
|
||||
import java.nio.channels.WritableByteChannel;
|
||||
import java.security.MessageDigest;
|
||||
import java.util.*;
|
||||
|
||||
@ -57,6 +60,14 @@ public class FileServiceImpl extends AbstractService implements IFileService {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(FileServiceImpl.class);
|
||||
private static final char[] HEX_CODE = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
|
||||
/**
|
||||
* 文件MD5值开头
|
||||
*/
|
||||
public static final String FILE_MD5_PREFIX = "MD5:";
|
||||
/**
|
||||
* 文件引用值开头
|
||||
*/
|
||||
public static final String FILE_REF_PREFIX = "REF:";
|
||||
|
||||
@Autowired
|
||||
private FileProperties fileProperties;
|
||||
@ -92,10 +103,62 @@ public class FileServiceImpl extends AbstractService implements IFileService {
|
||||
public void deleteFile(String ids) throws RemoveException {
|
||||
Map<String, Object> params = getHashMap(2);
|
||||
params.put("fileIds", Arrays.asList(ids.split("_")));
|
||||
Map<String, Object> fileParams = getHashMap(4);
|
||||
List<FileInfoWithPathDTO> fileInfoWithPathDTOs = fileDao.listFileInfoWithPath(params);
|
||||
// 删除文件
|
||||
for (FileInfoWithPathDTO fileInfoWithPathDTO : fileInfoWithPathDTOs) {
|
||||
File file = new File(fileInfoWithPathDTO.getFilePath());
|
||||
// 如果文件描述为空,可以直接删除源文件
|
||||
if (StringUtils.isBlank(fileInfoWithPathDTO.getFileSummary())) {
|
||||
deleteSourceFile(fileInfoWithPathDTO.getFilePath());
|
||||
continue;
|
||||
}
|
||||
// 文件描述不为空时,需要判断是否删除的是源文件,源文件在一个系统中只保留一份
|
||||
// 如果是引用文件的数据,不删除源文件
|
||||
if (fileInfoWithPathDTO.getFileSummary().startsWith(FILE_REF_PREFIX)) {
|
||||
continue;
|
||||
}
|
||||
// 如果不是MD5源文件,略过
|
||||
if (!fileInfoWithPathDTO.getFileSummary().startsWith(FILE_MD5_PREFIX)) {
|
||||
continue;
|
||||
}
|
||||
// 如果删除的是源文件,需要查询系统中是否还存在引用的数据
|
||||
List<FileInfoDTO> fileInfoDTOs = fileDao.listFileByMd5(FILE_REF_PREFIX + fileInfoWithPathDTO.getFileId());
|
||||
// 如果不存在对源文件引用的数据,则直接删除源文件
|
||||
if (fileInfoDTOs.size() == 0) {
|
||||
deleteSourceFile(fileInfoWithPathDTO.getFilePath());
|
||||
continue;
|
||||
}
|
||||
fileParams.clear();
|
||||
// 如果存在引用数据,取出第一个修改为源文件,并将其他的引用更新为新的源文件ID
|
||||
FileInfoDTO fileInfoDTO = fileInfoDTOs.get(0);
|
||||
fileParams.put("fileSummary", fileInfoWithPathDTO.getFileSummary());
|
||||
fileParams.put("fileId", fileInfoDTO.getFileId());
|
||||
fileDao.updateFileSummary(fileParams);
|
||||
// 获取其他的ID列表,更新文件引用关系
|
||||
List<String> otherFileIds = new ArrayList<>();
|
||||
for (int i = 1; i < fileInfoDTOs.size(); i++) {
|
||||
otherFileIds.add(fileInfoDTOs.get(i).getFileId());
|
||||
}
|
||||
// 如果不存在其它的引用,略过
|
||||
if (otherFileIds.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
fileParams.remove("fileId");
|
||||
fileParams.put("fileSummary", FILE_REF_PREFIX + fileInfoDTO.getFileId());
|
||||
fileParams.put("fileIds", otherFileIds);
|
||||
fileDao.updateFileSummary(fileParams);
|
||||
}
|
||||
// 删除记录
|
||||
fileDao.deleteFile(params);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除源文件
|
||||
*
|
||||
* @param sourceFilePath 源文件路径
|
||||
*/
|
||||
private void deleteSourceFile(String sourceFilePath) {
|
||||
File file = new File(sourceFilePath);
|
||||
if (file.exists()) {
|
||||
boolean isDelete = file.delete();
|
||||
if (isDelete) {
|
||||
@ -105,9 +168,6 @@ public class FileServiceImpl extends AbstractService implements IFileService {
|
||||
}
|
||||
}
|
||||
}
|
||||
// 删除记录
|
||||
fileDao.deleteFile(params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SuccessResultData<String> uploadSingle(MultipartFile uploadFile, UploadTypeEnum uploadTypeEnum, Map<String, Object> params) throws SystemException {
|
||||
@ -160,7 +220,7 @@ public class FileServiceImpl extends AbstractService implements IFileService {
|
||||
throw new SaveException("文件上传失败");
|
||||
}
|
||||
// 获取MD5相同的文件
|
||||
List<FileInfoDTO> fileInfoDTOs = fileDao.listFileByMd5("MD5:" + fileMd5);
|
||||
List<FileInfoDTO> fileInfoDTOs = fileDao.listFileByMd5(FILE_MD5_PREFIX + fileMd5);
|
||||
if (fileInfoDTOs.size() > 0) {
|
||||
// 删除新增的文件
|
||||
File uploadedFile = new File(uploadPath + File.separator + uploadFileName);
|
||||
@ -266,6 +326,68 @@ public class FileServiceImpl extends AbstractService implements IFileService {
|
||||
|
||||
@Override
|
||||
public void downLoadFile(HttpServletRequest request, HttpServletResponse response, Map<String, Object> params, boolean canRange) throws FileException {
|
||||
FilePO filePO = fileDao.getFile(params);
|
||||
if (null == filePO) {
|
||||
throw new SearchException("文件获取失败");
|
||||
}
|
||||
try (
|
||||
RandomAccessFile randomAccessFile = new RandomAccessFile(filePO.getFilePath(), "r");
|
||||
FileChannel fileChannel = randomAccessFile.getChannel();
|
||||
OutputStream outputStream = response.getOutputStream();
|
||||
WritableByteChannel writableByteChannel = Channels.newChannel(outputStream);
|
||||
) {
|
||||
boolean isOpen = Boolean.valueOf(params.get("isOpen").toString());
|
||||
response.setHeader("Content-Length", filePO.getFileSize());
|
||||
response.setContentType(getContentType(filePO.getFileType()));
|
||||
if (!isOpen) {
|
||||
response.setHeader("Content-Disposition", "attachment;fileName=" + URLEncoder.encode(filePO.getFileName(), "UTF-8"));
|
||||
} else {
|
||||
response.setHeader("Content-Disposition", "inline;fileName=" + URLEncoder.encode(filePO.getFileName(), "UTF-8"));
|
||||
}
|
||||
String rangeString = null;
|
||||
if (canRange && request != null) {
|
||||
rangeString = request.getHeader("Range");
|
||||
LOG.debug("range: {}", rangeString);
|
||||
}
|
||||
long contentLength = Long.valueOf(filePO.getFileSize());
|
||||
long startRange = 0;
|
||||
long endRange = contentLength - 1;
|
||||
if (!StringUtils.isBlank(rangeString)) {
|
||||
if (!isOpen) {
|
||||
response.setContentType("multipart/byteranges");
|
||||
}
|
||||
String[] rangeArray = rangeString.substring(rangeString.indexOf("=") + 1).split("-");
|
||||
startRange = Long.valueOf(rangeArray[0]);
|
||||
if (rangeArray.length > 1) {
|
||||
endRange = Long.valueOf(rangeArray[1]);
|
||||
}
|
||||
setRangeHeader(startRange, endRange, response, filePO.getFileId(), contentLength);
|
||||
randomAccessFile.seek(startRange);
|
||||
}
|
||||
LOG.debug("startRange: {}, endRange: {}", startRange, endRange);
|
||||
long totalOutputLength = endRange - startRange + 1;
|
||||
fileChannel.transferTo(startRange, totalOutputLength, writableByteChannel);
|
||||
outputStream.flush();
|
||||
} catch (Exception e) {
|
||||
if (e instanceof ClientAbortException) {
|
||||
LOG.debug("客户端断开连接");
|
||||
} else {
|
||||
throw new FileException("文件输出异常", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 同步下载文件
|
||||
*
|
||||
* @param request
|
||||
* @param response
|
||||
* @param params
|
||||
* @param canRange
|
||||
* @throws FileException
|
||||
*/
|
||||
@Deprecated
|
||||
public void downLoadFileOld(HttpServletRequest request, HttpServletResponse response, Map<String, Object> params, boolean canRange) throws FileException {
|
||||
FilePO filePO = fileDao.getFile(params);
|
||||
if (null == filePO) {
|
||||
throw new SearchException("文件获取失败");
|
||||
|
@ -87,7 +87,7 @@
|
||||
UPDATE
|
||||
sys_file
|
||||
SET
|
||||
is_delete = 0,
|
||||
is_delete = 1,
|
||||
modifier = #{modifier},
|
||||
gmt_modified = #{gmtModified}
|
||||
WHERE
|
||||
@ -108,6 +108,24 @@
|
||||
</foreach>
|
||||
</delete>
|
||||
|
||||
<!-- 更新文件描述 -->
|
||||
<update id="updateFileSummary" parameterType="map">
|
||||
UPDATE
|
||||
sys_file
|
||||
SET
|
||||
file_summary = #{fileSummary}
|
||||
WHERE
|
||||
<if test="fileId != null and fileId != ''">
|
||||
file_id = #{fileId}
|
||||
</if>
|
||||
<if test="fileIds != null and fileIds.size > 0">
|
||||
file_id IN
|
||||
<foreach collection="fileIds" index="index" open="(" separator="," close=")">
|
||||
#{fileIds[${index}]}
|
||||
</foreach>
|
||||
</if>
|
||||
</update>
|
||||
|
||||
<!-- 获取文件 -->
|
||||
<select id="getFile" parameterType="map" resultMap="filePO">
|
||||
SELECT
|
||||
|
@ -172,6 +172,29 @@
|
||||
return rowData;
|
||||
}
|
||||
},
|
||||
{field: 'fileSummary', width: 350, title: '文件描述', align:'center',
|
||||
templet: function(row) {
|
||||
var rowData = row[this.field];
|
||||
if(typeof(rowData) === 'undefined' || rowData == null || rowData == '') {
|
||||
return '-';
|
||||
}
|
||||
return rowData;
|
||||
}
|
||||
},
|
||||
{field: 'isSourceFile', width: 100, title: '保存类型', align:'center',
|
||||
templet: function(row) {
|
||||
if(!row.fileSummary) {
|
||||
return '无';
|
||||
}
|
||||
if(row.fileSummary.indexOf('MD5:') == 0) {
|
||||
return '源文件';
|
||||
}
|
||||
if(row.fileSummary.indexOf('REF:') == 0) {
|
||||
return '引用';
|
||||
}
|
||||
return '错误';
|
||||
}
|
||||
},
|
||||
]
|
||||
],
|
||||
page: true,
|
||||
@ -216,7 +239,7 @@
|
||||
// 删除
|
||||
function removeFile(isRemoveSource, ids) {
|
||||
var layIndex;
|
||||
top.restAjax.delete(top.restAjax.path('api/file/removearticlecategory/{isRemoveSource}/{ids}', [isRemoveSource, ids]), {}, null, function (code, data) {
|
||||
top.restAjax.delete(top.restAjax.path('api/file/removefile/{isRemoveSource}/{ids}', [isRemoveSource, ids]), {}, null, function (code, data) {
|
||||
top.dialog.msg(top.dataMessage.deleteSuccess, {time: 1000});
|
||||
reloadTable();
|
||||
}, function (code, data) {
|
||||
|
Loading…
Reference in New Issue
Block a user