mirror of https://gitee.com/stylefeng/roses
【file】更新file
parent
1e318b4faf
commit
5f7fb1f1ad
|
@ -92,7 +92,7 @@ public enum FileExceptionEnum implements AbstractExceptionEnum {
|
||||||
/**
|
/**
|
||||||
* 文件不允许被访问
|
* 文件不允许被访问
|
||||||
*/
|
*/
|
||||||
FILE_DENIED_ACCESS(RuleConstants.USER_OPERATION_ERROR_TYPE_CODE + FileConstants.FILE_EXCEPTION_STEP_CODE + "16", "文件不允许被访问!");
|
FILE_DENIED_ACCESS(RuleConstants.USER_OPERATION_ERROR_TYPE_CODE + FileConstants.FILE_EXCEPTION_STEP_CODE + "16", "文件不允许被访问,文件加密等级不符合");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 错误编码
|
* 错误编码
|
||||||
|
|
|
@ -1,38 +1,44 @@
|
||||||
package cn.stylefeng.roses.kernel.file.modular.controller;
|
package cn.stylefeng.roses.kernel.file.modular.controller;
|
||||||
|
|
||||||
import cn.hutool.core.codec.Base64;
|
|
||||||
import cn.hutool.core.util.ObjectUtil;
|
|
||||||
import cn.hutool.core.util.StrUtil;
|
|
||||||
import cn.stylefeng.roses.kernel.file.exception.FileException;
|
|
||||||
import cn.stylefeng.roses.kernel.file.exception.enums.FileExceptionEnum;
|
|
||||||
import cn.stylefeng.roses.kernel.file.expander.FileConfigExpander;
|
|
||||||
import cn.stylefeng.roses.kernel.file.modular.service.SysFileInfoService;
|
import cn.stylefeng.roses.kernel.file.modular.service.SysFileInfoService;
|
||||||
import cn.stylefeng.roses.kernel.file.pojo.request.SysFileInfoRequest;
|
import cn.stylefeng.roses.kernel.file.pojo.request.SysFileInfoRequest;
|
||||||
import cn.stylefeng.roses.kernel.file.util.DownloadUtil;
|
import cn.stylefeng.roses.kernel.file.pojo.response.SysFileInfoResponse;
|
||||||
import cn.stylefeng.roses.kernel.resource.api.annotation.ApiResource;
|
import cn.stylefeng.roses.kernel.resource.api.annotation.ApiResource;
|
||||||
import cn.stylefeng.roses.kernel.resource.api.annotation.GetResource;
|
import cn.stylefeng.roses.kernel.resource.api.annotation.GetResource;
|
||||||
import cn.stylefeng.roses.kernel.resource.api.annotation.PostResource;
|
import cn.stylefeng.roses.kernel.resource.api.annotation.PostResource;
|
||||||
import cn.stylefeng.roses.kernel.rule.pojo.request.BaseRequest;
|
import cn.stylefeng.roses.kernel.rule.enums.YesOrNotEnum;
|
||||||
import cn.stylefeng.roses.kernel.rule.pojo.response.ResponseData;
|
import cn.stylefeng.roses.kernel.rule.pojo.response.ResponseData;
|
||||||
import cn.stylefeng.roses.kernel.rule.pojo.response.SuccessResponseData;
|
import cn.stylefeng.roses.kernel.rule.pojo.response.SuccessResponseData;
|
||||||
import cn.stylefeng.roses.kernel.rule.util.HttpServletUtil;
|
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
import org.springframework.web.bind.annotation.RequestBody;
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
import org.springframework.web.bind.annotation.RequestPart;
|
import org.springframework.web.bind.annotation.RequestPart;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import static cn.stylefeng.roses.kernel.file.constants.FileConstants.DEFAULT_AVATAR_FILE_OBJ_NAME;
|
|
||||||
import static cn.stylefeng.roses.kernel.file.constants.FileConstants.FILE_PRIVATE_PREVIEW_URL;
|
import static cn.stylefeng.roses.kernel.file.constants.FileConstants.FILE_PRIVATE_PREVIEW_URL;
|
||||||
|
import static cn.stylefeng.roses.kernel.file.constants.FileConstants.FILE_PUBLIC_PREVIEW_URL;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 文件信息管理
|
* 文件信息管理
|
||||||
|
* <p>
|
||||||
|
* 该模块简要说明:
|
||||||
|
* 1.文件支持版本朔源,每次操作均会产生数据
|
||||||
|
* 2.文件支持版本回滚,升级后可选择某一版本进行回退
|
||||||
|
* <p>
|
||||||
|
* 文件管理接口有两种使用方式:
|
||||||
|
* 1.合同文件场景:文件必须保持原样,合同内容升级不影响已签署合同,业务需要关联文件ID<br>
|
||||||
|
* 文件升级不会对之前的数据造成影响
|
||||||
|
* 2.UI文件场景:文件升级后业务所有关联的文件全部升级,业务需要关联文件CODE<br>
|
||||||
|
* <p>
|
||||||
|
* 可能你今天上线,昨天很丑的banner图变好看了~
|
||||||
*
|
*
|
||||||
* @author fengshuonan
|
* @author majianguo
|
||||||
* @date 2020/11/29 11:17
|
* @date 2020/12/27 13:39
|
||||||
*/
|
*/
|
||||||
@RestController
|
@RestController
|
||||||
@ApiResource(name = "文件信息相关接口")
|
@ApiResource(name = "文件信息相关接口")
|
||||||
|
@ -44,77 +50,160 @@ public class SysFileInfoController {
|
||||||
/**
|
/**
|
||||||
* 上传文件
|
* 上传文件
|
||||||
*
|
*
|
||||||
* @author fengshuonan
|
* @author majianguo
|
||||||
* @date 2020/11/29 11:17
|
* @date 2020/12/27 13:17
|
||||||
*/
|
*/
|
||||||
@PostResource(name = "上传文件", path = "/sysFileInfo/upload")
|
@PostResource(name = "上传文件", path = "/sysFileInfo/upload")
|
||||||
public ResponseData upload(@RequestPart("file") MultipartFile file) {
|
public ResponseData upload(@RequestPart("file") MultipartFile file, @Validated(SysFileInfoRequest.add.class) SysFileInfoRequest sysFileInfoRequest) {
|
||||||
Long fileId = sysFileInfoService.uploadFile(file);
|
SysFileInfoResponse fileUploadInfoResult = this.sysFileInfoService.uploadFile(file, sysFileInfoRequest);
|
||||||
return new SuccessResponseData(fileId);
|
return new SuccessResponseData(fileUploadInfoResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 下载文件
|
* 替换文件
|
||||||
|
* <p>
|
||||||
|
* 注意:调用本接口之后还需要调用确认接口,本次替换操作才会生效
|
||||||
|
*
|
||||||
|
* @author majianguo
|
||||||
|
* @date 2020/12/16 15:34
|
||||||
|
*/
|
||||||
|
@PostResource(name = "替换文件", path = "/sysFileInfo/update")
|
||||||
|
public ResponseData update(@RequestPart("file") MultipartFile file, @Validated(SysFileInfoRequest.edit.class) SysFileInfoRequest sysFileInfoRequest) {
|
||||||
|
SysFileInfoResponse fileUploadInfoResult = this.sysFileInfoService.updateFile(file, sysFileInfoRequest);
|
||||||
|
return new SuccessResponseData(fileUploadInfoResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 版本回退
|
||||||
|
*
|
||||||
|
* @author majianguo
|
||||||
|
* @date 2020/12/16 15:34
|
||||||
|
*/
|
||||||
|
@PostResource(name = "替换文件", path = "/sysFileInfo/versionBack")
|
||||||
|
public ResponseData versionBack(@Validated(SysFileInfoRequest.versionBack.class) SysFileInfoRequest sysFileInfoRequest) {
|
||||||
|
SysFileInfoResponse fileUploadInfoResult = this.sysFileInfoService.versionBack(sysFileInfoRequest);
|
||||||
|
return new SuccessResponseData(fileUploadInfoResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 私有文件预览
|
||||||
*
|
*
|
||||||
* @author fengshuonan
|
* @author fengshuonan
|
||||||
* @date 2020/11/29 11:29
|
* @date 2020/11/29 11:29
|
||||||
*/
|
*/
|
||||||
@GetResource(name = "下载文件", path = "/sysFileInfo/download")
|
@GetResource(name = "私有文件预览", path = FILE_PRIVATE_PREVIEW_URL)
|
||||||
public void download(@Validated(BaseRequest.detail.class) SysFileInfoRequest sysFileInfoRequest, HttpServletResponse response) {
|
public void priPreview(@Validated(SysFileInfoRequest.detail.class) SysFileInfoRequest sysFileInfoRequest, HttpServletResponse response) {
|
||||||
sysFileInfoService.download(sysFileInfoRequest, response);
|
sysFileInfoRequest.setSecretFlag(YesOrNotEnum.Y.getCode());
|
||||||
|
this.sysFileInfoService.preview(sysFileInfoRequest, response);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 删除文件信息
|
* 公有文件预览
|
||||||
|
*
|
||||||
|
* @author majianguo
|
||||||
|
* @date 2020/12/27 13:17
|
||||||
|
*/
|
||||||
|
@GetResource(name = "公有文件预览", path = FILE_PUBLIC_PREVIEW_URL, requiredPermission = false, requiredLogin = false)
|
||||||
|
public void pubPreview(@Validated(SysFileInfoRequest.detail.class) SysFileInfoRequest sysFileInfoRequest, HttpServletResponse response) {
|
||||||
|
sysFileInfoRequest.setSecretFlag(YesOrNotEnum.N.getCode());
|
||||||
|
this.sysFileInfoService.preview(sysFileInfoRequest, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 私有文件下载
|
||||||
|
*
|
||||||
|
* @author majianguo
|
||||||
|
* @date 2020/12/27 13:17
|
||||||
|
*/
|
||||||
|
@GetResource(name = "私有文件下载", path = "/sysFileInfo/privateDownload")
|
||||||
|
public void privateDownload(@Validated(SysFileInfoRequest.detail.class) SysFileInfoRequest sysFileInfoRequest, HttpServletResponse response) {
|
||||||
|
sysFileInfoRequest.setSecretFlag(YesOrNotEnum.Y.getCode());
|
||||||
|
this.sysFileInfoService.download(sysFileInfoRequest, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 公有文件下载
|
||||||
|
*
|
||||||
|
* @author majianguo
|
||||||
|
* @date 2020/12/27 13:17
|
||||||
|
*/
|
||||||
|
@GetResource(name = "公有文件下载", path = "/sysFileInfo/publicDownload", requiredLogin = false, requiredPermission = false)
|
||||||
|
public void publicDownload(@Validated(SysFileInfoRequest.detail.class) SysFileInfoRequest sysFileInfoRequest, HttpServletResponse response) {
|
||||||
|
sysFileInfoRequest.setSecretFlag(YesOrNotEnum.N.getCode());
|
||||||
|
this.sysFileInfoService.download(sysFileInfoRequest, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据附件IDS查询附件信息
|
||||||
|
*
|
||||||
|
* @param fileIds 附件IDS
|
||||||
|
* @return 附件返回类
|
||||||
|
* @author majianguo
|
||||||
|
* @date 2020/12/27 13:17
|
||||||
|
*/
|
||||||
|
@GetResource(name = "根据附件IDS查询附件信息", path = "/sysFileInfo/getFileInfoListByFileIds")
|
||||||
|
public ResponseData getFileInfoListByFileIds(@RequestParam(value = "fileIds") String fileIds) {
|
||||||
|
List<SysFileInfoResponse> list = this.sysFileInfoService.getFileInfoListByFileIds(fileIds);
|
||||||
|
return new SuccessResponseData(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 公有打包下载文件
|
||||||
|
*
|
||||||
|
* @author majianguo
|
||||||
|
* @date 2020/12/27 13:17
|
||||||
|
*/
|
||||||
|
@GetResource(name = "公有打包下载文件", path = "/sysFileInfo/publicPackagingDownload", requiredPermission = false, requiredLogin = false)
|
||||||
|
public void publicPackagingDownload(@RequestParam(value = "fileIds") String fileIds, HttpServletResponse response) {
|
||||||
|
this.sysFileInfoService.packagingDownload(fileIds, YesOrNotEnum.N.getCode(), response);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 私有打包下载文件
|
||||||
|
*
|
||||||
|
* @author majianguo
|
||||||
|
* @date 2020/12/27 13:18
|
||||||
|
*/
|
||||||
|
@GetResource(name = "私有打包下载文件", path = "/sysFileInfo/privatePackagingDownload")
|
||||||
|
public void privatePackagingDownload(@RequestParam(value = "fileIds") String fileIds, HttpServletResponse response) {
|
||||||
|
this.sysFileInfoService.packagingDownload(fileIds, YesOrNotEnum.Y.getCode(), response);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除文件信息(真删除文件信息)
|
||||||
*
|
*
|
||||||
* @author fengshuonan
|
* @author fengshuonan
|
||||||
* @date 2020/11/29 11:19
|
* @date 2020/11/29 11:19
|
||||||
*/
|
*/
|
||||||
@PostResource(name = "删除文件信息", path = "/sysFileInfo/delete")
|
@PostResource(name = "删除文件信息(真删除文件信息)", path = "/sysFileInfo/deleteReally")
|
||||||
public ResponseData delete(@RequestBody @Validated(SysFileInfoRequest.delete.class) SysFileInfoRequest sysFileInfoRequest) {
|
public ResponseData deleteReally(@RequestBody @Validated(SysFileInfoRequest.delete.class) SysFileInfoRequest sysFileInfoRequest) {
|
||||||
sysFileInfoService.delete(sysFileInfoRequest);
|
this.sysFileInfoService.deleteReally(sysFileInfoRequest);
|
||||||
return new SuccessResponseData();
|
return new SuccessResponseData();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 文件预览
|
* 分页查询文件信息表
|
||||||
* <p>
|
|
||||||
* 支持通过文件id预览,也支持直接通过bucket和obj名称预览
|
|
||||||
*
|
*
|
||||||
* @author fengshuonan
|
* @author fengshuonan
|
||||||
* @date 2020/11/29 11:29
|
* @date 2020/11/29 11:29
|
||||||
*/
|
*/
|
||||||
@GetResource(name = "文件预览", path = FILE_PRIVATE_PREVIEW_URL)
|
@GetResource(name = "分页查询文件信息表", path = "/sysFileInfo/fileInfoListPage")
|
||||||
public void preview(SysFileInfoRequest sysFileInfoRequest) {
|
public ResponseData fileInfoListPage(SysFileInfoRequest sysFileInfoRequest) {
|
||||||
HttpServletResponse response = HttpServletUtil.getResponse();
|
return new SuccessResponseData(this.sysFileInfoService.fileInfoListPage(sysFileInfoRequest));
|
||||||
|
|
||||||
// 请求参数不能为空
|
|
||||||
if (sysFileInfoRequest == null) {
|
|
||||||
String userTip = StrUtil.format(FileExceptionEnum.PREVIEW_EMPTY_ERROR.getUserTip(), "");
|
|
||||||
throw new FileException(FileExceptionEnum.PREVIEW_EMPTY_ERROR, userTip);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 文件是-1则返回系统默认头像
|
/**
|
||||||
if (DEFAULT_AVATAR_FILE_OBJ_NAME.equals(sysFileInfoRequest.getFileObjectName())) {
|
* 确认替换附件
|
||||||
DownloadUtil.renderPreviewFile(response, Base64.decode(FileConfigExpander.getDefaultAvatarBase64()));
|
* <p>
|
||||||
return;
|
* 在替换接口替换文件以后,需要调用本接口替换操作才会生效
|
||||||
}
|
*
|
||||||
|
* @author majianguo
|
||||||
// 文件id不为空,则根据文件id预览
|
* @date 2020/12/27 13:18
|
||||||
if (ObjectUtil.isNotEmpty(sysFileInfoRequest.getFileId())) {
|
*/
|
||||||
sysFileInfoService.previewByFileId(sysFileInfoRequest, response);
|
@PostResource(name = "确认替换附件", path = "/sysFileInfo/confirmReplaceFile")
|
||||||
return;
|
public ResponseData confirmReplaceFile(@RequestBody List<Long> fileIdList) {
|
||||||
}
|
this.sysFileInfoService.confirmReplaceFile(fileIdList);
|
||||||
|
return new SuccessResponseData();
|
||||||
// 文件bucketName和objectName不为空,则根据bucket预览
|
|
||||||
if (ObjectUtil.isAllNotEmpty(sysFileInfoRequest.getFileBucket(), sysFileInfoRequest.getFileObjectName())) {
|
|
||||||
sysFileInfoService.previewByBucketAndObjName(sysFileInfoRequest, response);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 提示用户信息不全
|
|
||||||
String userTip = StrUtil.format(FileExceptionEnum.PREVIEW_EMPTY_ERROR.getUserTip(), sysFileInfoRequest);
|
|
||||||
throw new FileException(FileExceptionEnum.PREVIEW_EMPTY_ERROR, userTip);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -128,26 +217,46 @@ public class SysFileInfoController {
|
||||||
return new SuccessResponseData(sysFileInfoService.detail(sysFileInfoRequest));
|
return new SuccessResponseData(sysFileInfoService.detail(sysFileInfoRequest));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 分页查询文件信息表
|
|
||||||
*
|
|
||||||
* @author fengshuonan
|
|
||||||
* @date 2020/11/29 11:29
|
|
||||||
*/
|
|
||||||
@GetResource(name = "分页查询文件信息表", path = "/sysFileInfo/page")
|
|
||||||
public ResponseData page(SysFileInfoRequest sysFileInfoRequest) {
|
|
||||||
return new SuccessResponseData(sysFileInfoService.page(sysFileInfoRequest));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
// /**
|
||||||
* 获取全部文件信息表
|
// * 文件预览
|
||||||
*
|
// * <p>
|
||||||
* @author fengshuonan
|
// * 支持通过文件id预览,也支持直接通过bucket和obj名称预览
|
||||||
* @date 2020/11/29 11:29
|
// *
|
||||||
*/
|
// * @author fengshuonan
|
||||||
@GetResource(name = "获取全部文件信息表", path = "/sysFileInfo/list")
|
// * @date 2020/11/29 11:29
|
||||||
public ResponseData list(SysFileInfoRequest sysFileInfoRequest) {
|
// */
|
||||||
return new SuccessResponseData(sysFileInfoService.list(sysFileInfoRequest));
|
// @GetResource(name = "文件预览", path = FILE_PRIVATE_PREVIEW_URL)
|
||||||
}
|
// public void preview(SysFileInfoRequest sysFileInfoRequest) {
|
||||||
|
// HttpServletResponse response = HttpServletUtil.getResponse();
|
||||||
|
//
|
||||||
|
// // 请求参数不能为空
|
||||||
|
// if (sysFileInfoRequest == null) {
|
||||||
|
// String userTip = StrUtil.format(FileExceptionEnum.PREVIEW_EMPTY_ERROR.getUserTip(), "");
|
||||||
|
// throw new FileException(FileExceptionEnum.PREVIEW_EMPTY_ERROR, userTip);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // 文件是-1则返回系统默认头像
|
||||||
|
// if (DEFAULT_AVATAR_FILE_OBJ_NAME.equals(sysFileInfoRequest.getFileObjectName())) {
|
||||||
|
// DownloadUtil.renderPreviewFile(response, Base64.decode(FileConfigExpander.getDefaultAvatarBase64()));
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // 文件id不为空,则根据文件id预览
|
||||||
|
// if (ObjectUtil.isNotEmpty(sysFileInfoRequest.getFileId())) {
|
||||||
|
// sysFileInfoService.previewByFileId(sysFileInfoRequest, response);
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // 文件bucketName和objectName不为空,则根据bucket预览
|
||||||
|
// if (ObjectUtil.isAllNotEmpty(sysFileInfoRequest.getFileBucket(), sysFileInfoRequest.getFileObjectName())) {
|
||||||
|
// sysFileInfoService.previewByBucketAndObjName(sysFileInfoRequest, response);
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // 提示用户信息不全
|
||||||
|
// String userTip = StrUtil.format(FileExceptionEnum.PREVIEW_EMPTY_ERROR.getUserTip(), sysFileInfoRequest);
|
||||||
|
// throw new FileException(FileExceptionEnum.PREVIEW_EMPTY_ERROR, userTip);
|
||||||
|
// }
|
||||||
|
|
||||||
}
|
}
|
|
@ -28,11 +28,25 @@ public class SysFileInfo extends BaseEntity {
|
||||||
private Long fileId;
|
private Long fileId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 文件编码,解决一个文件多个版本问题,多次上传文件编码不变
|
* 文件编码,本号升级的依据
|
||||||
|
* <p>
|
||||||
|
* 解决一个文件多个版本问题,多次上传文件编码不变
|
||||||
*/
|
*/
|
||||||
@TableField(value = "file_code")
|
@TableField("file_code")
|
||||||
private Long fileCode;
|
private Long fileCode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件版本,从1开始
|
||||||
|
*/
|
||||||
|
@TableField("file_version")
|
||||||
|
private Integer fileVersion;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 当前状态:0-历史版,1-最新版
|
||||||
|
*/
|
||||||
|
@TableField("file_status")
|
||||||
|
private String fileStatus;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 文件存储位置:1-阿里云,2-腾讯云,3-minio,4-本地
|
* 文件存储位置:1-阿里云,2-腾讯云,3-minio,4-本地
|
||||||
*/
|
*/
|
||||||
|
@ -63,6 +77,12 @@ public class SysFileInfo extends BaseEntity {
|
||||||
@TableField("file_size_kb")
|
@TableField("file_size_kb")
|
||||||
private Long fileSizeKb;
|
private Long fileSizeKb;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件大小信息,计算后的
|
||||||
|
*/
|
||||||
|
@TableField("file_size_info")
|
||||||
|
private String fileSizeInfo;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 存储到bucket中的名称,主键id+.后缀
|
* 存储到bucket中的名称,主键id+.后缀
|
||||||
*/
|
*/
|
||||||
|
@ -75,6 +95,12 @@ public class SysFileInfo extends BaseEntity {
|
||||||
@TableField("file_path")
|
@TableField("file_path")
|
||||||
private String filePath;
|
private String filePath;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否为机密文件
|
||||||
|
*/
|
||||||
|
@TableField("secret_flag")
|
||||||
|
private String secretFlag;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 是否删除:Y-被删除,N-未删除
|
* 是否删除:Y-被删除,N-未删除
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -0,0 +1,90 @@
|
||||||
|
package cn.stylefeng.roses.kernel.file.modular.factory;
|
||||||
|
|
||||||
|
import cn.hutool.core.convert.Convert;
|
||||||
|
import cn.hutool.core.io.FileUtil;
|
||||||
|
import cn.hutool.core.util.NumberUtil;
|
||||||
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import cn.hutool.extra.spring.SpringUtil;
|
||||||
|
import cn.stylefeng.roses.kernel.file.FileOperatorApi;
|
||||||
|
import cn.stylefeng.roses.kernel.file.enums.FileLocationEnum;
|
||||||
|
import cn.stylefeng.roses.kernel.file.enums.FileStatusEnum;
|
||||||
|
import cn.stylefeng.roses.kernel.file.exception.FileException;
|
||||||
|
import cn.stylefeng.roses.kernel.file.exception.enums.FileExceptionEnum;
|
||||||
|
import cn.stylefeng.roses.kernel.file.modular.entity.SysFileInfo;
|
||||||
|
import cn.stylefeng.roses.kernel.file.pojo.request.SysFileInfoRequest;
|
||||||
|
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
|
import static cn.stylefeng.roses.kernel.file.constants.FileConstants.DEFAULT_BUCKET_NAME;
|
||||||
|
import static cn.stylefeng.roses.kernel.file.constants.FileConstants.FILE_POSTFIX_SEPARATOR;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件信息组装工厂
|
||||||
|
*
|
||||||
|
* @author fengshuonan
|
||||||
|
* @date 2020/12/30 22:16
|
||||||
|
*/
|
||||||
|
public class FileInfoFactory {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 封装附件信息
|
||||||
|
*
|
||||||
|
* @author majianguo
|
||||||
|
* @date 2020/12/27 12:55
|
||||||
|
*/
|
||||||
|
public static SysFileInfo createSysFileInfo(MultipartFile file, SysFileInfoRequest sysFileInfoRequest) {
|
||||||
|
|
||||||
|
FileOperatorApi fileOperatorApi = SpringUtil.getBean(FileOperatorApi.class);
|
||||||
|
|
||||||
|
// 生成文件的唯一id
|
||||||
|
Long fileId = IdWorker.getId();
|
||||||
|
|
||||||
|
// 获取文件原始名称
|
||||||
|
String originalFilename = file.getOriginalFilename();
|
||||||
|
|
||||||
|
// 获取文件后缀(不包含点)
|
||||||
|
String fileSuffix = null;
|
||||||
|
if (ObjectUtil.isNotEmpty(originalFilename)) {
|
||||||
|
fileSuffix = StrUtil.subAfter(originalFilename, FILE_POSTFIX_SEPARATOR, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 生成文件的最终名称
|
||||||
|
String finalFileName = fileId + FILE_POSTFIX_SEPARATOR + fileSuffix;
|
||||||
|
|
||||||
|
// 存储文件
|
||||||
|
byte[] bytes;
|
||||||
|
try {
|
||||||
|
bytes = file.getBytes();
|
||||||
|
fileOperatorApi.storageFile(DEFAULT_BUCKET_NAME, finalFileName, bytes);
|
||||||
|
} catch (IOException e) {
|
||||||
|
String userTip = StrUtil.format(FileExceptionEnum.ERROR_FILE.getUserTip(), e.getMessage());
|
||||||
|
throw new FileException(FileExceptionEnum.ERROR_FILE, userTip);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算文件大小kb
|
||||||
|
long fileSizeKb = Convert.toLong(NumberUtil.div(new BigDecimal(file.getSize()), BigDecimal.valueOf(1024)).setScale(0, BigDecimal.ROUND_HALF_UP));
|
||||||
|
|
||||||
|
// 计算文件大小信息
|
||||||
|
String fileSizeInfo = FileUtil.readableFileSize(file.getSize());
|
||||||
|
|
||||||
|
// 封装存储文件信息(上传替换公共信息)
|
||||||
|
SysFileInfo sysFileInfo = new SysFileInfo();
|
||||||
|
sysFileInfo.setFileLocation(FileLocationEnum.LOCAL.getCode());
|
||||||
|
sysFileInfo.setFileBucket(DEFAULT_BUCKET_NAME);
|
||||||
|
sysFileInfo.setFileObjectName(finalFileName);
|
||||||
|
sysFileInfo.setFileOriginName(originalFilename);
|
||||||
|
sysFileInfo.setFileSuffix(fileSuffix);
|
||||||
|
sysFileInfo.setFileSizeKb(fileSizeKb);
|
||||||
|
sysFileInfo.setFileSizeInfo(fileSizeInfo);
|
||||||
|
sysFileInfo.setFileStatus(FileStatusEnum.NEW.getCode());
|
||||||
|
sysFileInfo.setSecretFlag(sysFileInfoRequest.getSecretFlag());
|
||||||
|
|
||||||
|
// 返回结果
|
||||||
|
return sysFileInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,7 +1,14 @@
|
||||||
package cn.stylefeng.roses.kernel.file.modular.mapper;
|
package cn.stylefeng.roses.kernel.file.modular.mapper;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
|
||||||
import cn.stylefeng.roses.kernel.file.modular.entity.SysFileInfo;
|
import cn.stylefeng.roses.kernel.file.modular.entity.SysFileInfo;
|
||||||
|
import cn.stylefeng.roses.kernel.file.pojo.request.SysFileInfoRequest;
|
||||||
|
import cn.stylefeng.roses.kernel.file.pojo.response.SysFileInfoListResponse;
|
||||||
|
import cn.stylefeng.roses.kernel.file.pojo.response.SysFileInfoResponse;
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
|
@ -13,4 +20,50 @@ import cn.stylefeng.roses.kernel.file.modular.entity.SysFileInfo;
|
||||||
*/
|
*/
|
||||||
public interface SysFileInfoMapper extends BaseMapper<SysFileInfo> {
|
public interface SysFileInfoMapper extends BaseMapper<SysFileInfo> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据附件IDS查询附件信息
|
||||||
|
*
|
||||||
|
* @param fileIdList 文件ID列表
|
||||||
|
* @author majianguo
|
||||||
|
* @date 2020/12/27 12:57
|
||||||
|
*/
|
||||||
|
List<SysFileInfoResponse> getFileInfoListByFileIds(@Param("fileIdList") List<Long> fileIdList);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 附件列表(有分页)
|
||||||
|
*
|
||||||
|
* @author majianguo
|
||||||
|
* @date 2020/12/27 12:57
|
||||||
|
*/
|
||||||
|
List<SysFileInfoListResponse> fileInfoList(@Param("page") Page<SysFileInfoListResponse> page, @Param("sysFileInfoRequest") SysFileInfoRequest sysFileInfoRequest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取所有附件信息的code集合
|
||||||
|
*
|
||||||
|
* @param fileIdList 文件ID列表
|
||||||
|
* @author majianguo
|
||||||
|
* @date 2020/12/27 12:57
|
||||||
|
*/
|
||||||
|
List<Long> getFileCodeByFileIds(@Param("fileIdList") List<Long> fileIdList);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修改fielCodes下所有附件状态
|
||||||
|
*
|
||||||
|
* @param fileCodeList 文件CODE列表
|
||||||
|
* @param delFlag 是否删除
|
||||||
|
* @author majianguo
|
||||||
|
* @date 2020/12/27 12:56
|
||||||
|
*/
|
||||||
|
void updateDelFlagByFileCodes(@Param("fileCodeList") List<Long> fileCodeList, @Param("delFlag") String delFlag);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修改fileIds下所有附件状态
|
||||||
|
*
|
||||||
|
* @param fileIdList 文件ID列表
|
||||||
|
* @param delFlag 是否删除
|
||||||
|
* @author majianguo
|
||||||
|
* @date 2020/12/27 12:56
|
||||||
|
*/
|
||||||
|
void updateDelFlagByFileIds(@Param("fileIdList") List<Long> fileIdList, @Param("delFlag") String delFlag);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,4 +2,89 @@
|
||||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
<mapper namespace="cn.stylefeng.roses.kernel.file.modular.mapper.SysFileInfoMapper">
|
<mapper namespace="cn.stylefeng.roses.kernel.file.modular.mapper.SysFileInfoMapper">
|
||||||
|
|
||||||
|
<!-- 根据附件IDS查询附件信息 -->
|
||||||
|
<select id="getFileInfoListByFileIds"
|
||||||
|
resultType="cn.stylefeng.roses.kernel.file.pojo.response.SysFileInfoResponse">
|
||||||
|
SELECT file.file_id AS fileId,
|
||||||
|
file.file_code AS fileCode,
|
||||||
|
file.file_app_code AS fileAppCode,
|
||||||
|
file.file_version AS fileVersion,
|
||||||
|
file.file_status AS fileStatus,
|
||||||
|
file.file_origin_name AS fileOriginName,
|
||||||
|
file.file_suffix AS fileSuffix,
|
||||||
|
file.file_size_kb AS fileSizeKb,
|
||||||
|
file.file_size_info AS fileSizeInfo,
|
||||||
|
file.secret_flag AS secretFlag,
|
||||||
|
file.file_object_name AS fileObjectName,
|
||||||
|
file.create_time AS createTime
|
||||||
|
FROM sys_file_info file
|
||||||
|
WHERE file.del_flag = "N"
|
||||||
|
AND file.file_id IN
|
||||||
|
<foreach collection="fileIdList" separator="," open="(" close=")" item="fileId">
|
||||||
|
#{fileId}
|
||||||
|
</foreach>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<!-- 附件列表 -->
|
||||||
|
<select id="fileInfoList" resultType="cn.stylefeng.roses.kernel.file.pojo.response.SysFileInfoListResponse">
|
||||||
|
SELECT file.file_id AS fileId,
|
||||||
|
file.file_app_code AS fileAppCode,
|
||||||
|
app.app_name AS fileAppCodeName,
|
||||||
|
file.file_origin_name AS fileOriginName,
|
||||||
|
file.file_suffix AS fileSuffix,
|
||||||
|
file.file_size_info AS fileSizeInfo,
|
||||||
|
file.file_version AS fileVersion,
|
||||||
|
file.create_account_id AS createAccountId,
|
||||||
|
file.create_dept_id AS createDeptId,
|
||||||
|
emp.emp_full_name_cn AS createUserName,
|
||||||
|
file.create_time AS createTime,
|
||||||
|
file.del_flag AS delFlag
|
||||||
|
FROM sys_file_info file
|
||||||
|
LEFT JOIN sys_app app ON file.file_app_code = app.app_code
|
||||||
|
LEFT JOIN sys_account account ON account.account_id = file.create_account_id
|
||||||
|
LEFT JOIN hr_emp_main emp ON account.emp_main_id = emp.emp_main_id
|
||||||
|
<where>
|
||||||
|
<if test="sysFileInfoRequest.fileAppCode != null and sysFileInfoRequest.fileAppCode != '' ">
|
||||||
|
AND file.file_app_code = #{sysFileInfoRequest.fileAppCode}
|
||||||
|
</if>
|
||||||
|
<if test="sysFileInfoRequest.fileOriginName != null and sysFileInfoRequest.fileOriginName != '' ">
|
||||||
|
AND file.file_app_code LIKE CONCAT('%',#{fileOriginName},'%')
|
||||||
|
</if>
|
||||||
|
</where>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<!-- 获取所有附件信息的code集合 -->
|
||||||
|
<select id="getFileCodeByFileIds" resultType="java.lang.Long">
|
||||||
|
SELECT
|
||||||
|
file.file_code
|
||||||
|
FROM
|
||||||
|
sys_file_info file
|
||||||
|
WHERE
|
||||||
|
file.file_id IN
|
||||||
|
<foreach collection="fileIdList" open="(" close=")" separator="," item="fileId">
|
||||||
|
#{fileId}
|
||||||
|
</foreach>
|
||||||
|
GROUP BY file.file_code
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<!-- 修改fileCodes下所有附件状态 -->
|
||||||
|
<update id="updateDelFlagByFileCodes">
|
||||||
|
UPDATE sys_file_info file
|
||||||
|
SET file.del_flag = #{delFlag}
|
||||||
|
WHERE file.file_code IN
|
||||||
|
<foreach collection="fileCodeList" open="(" close=")" separator="," item="fileCode">
|
||||||
|
#{fileCode}
|
||||||
|
</foreach>
|
||||||
|
</update>
|
||||||
|
|
||||||
|
<!-- 修改fileIds下所有附件状态 -->
|
||||||
|
<update id="updateDelFlagByFileIds">
|
||||||
|
UPDATE sys_file_info file
|
||||||
|
SET file.del_flag = #{delFlag}
|
||||||
|
WHERE file.file_id IN
|
||||||
|
<foreach collection="fileIdList" open="(" close=")" separator="," item="fileId">
|
||||||
|
#{fileId}
|
||||||
|
</foreach>
|
||||||
|
</update>
|
||||||
|
|
||||||
</mapper>
|
</mapper>
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
package cn.stylefeng.roses.kernel.file.modular.service;
|
package cn.stylefeng.roses.kernel.file.modular.service;
|
||||||
|
|
||||||
import cn.stylefeng.roses.kernel.file.pojo.request.SysFileInfoRequest;
|
|
||||||
import cn.stylefeng.roses.kernel.file.pojo.response.SysFileInfoResponse;
|
|
||||||
import com.baomidou.mybatisplus.extension.service.IService;
|
|
||||||
import cn.stylefeng.roses.kernel.db.api.pojo.page.PageResult;
|
import cn.stylefeng.roses.kernel.db.api.pojo.page.PageResult;
|
||||||
import cn.stylefeng.roses.kernel.file.modular.entity.SysFileInfo;
|
import cn.stylefeng.roses.kernel.file.modular.entity.SysFileInfo;
|
||||||
|
import cn.stylefeng.roses.kernel.file.pojo.request.SysFileInfoRequest;
|
||||||
|
import cn.stylefeng.roses.kernel.file.pojo.response.SysFileInfoListResponse;
|
||||||
|
import cn.stylefeng.roses.kernel.file.pojo.response.SysFileInfoResponse;
|
||||||
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
@ -18,15 +19,36 @@ import java.util.List;
|
||||||
*/
|
*/
|
||||||
public interface SysFileInfoService extends IService<SysFileInfo> {
|
public interface SysFileInfoService extends IService<SysFileInfo> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取文件信息结果集
|
||||||
|
*
|
||||||
|
* @param fileId 文件id
|
||||||
|
* @return 文件信息结果集
|
||||||
|
* @author fengshuonan
|
||||||
|
* @date 2020/11/29 14:16
|
||||||
|
*/
|
||||||
|
SysFileInfoResponse getFileInfoResult(Long fileId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 上传文件,返回文件的唯一标识
|
* 上传文件,返回文件的唯一标识
|
||||||
*
|
*
|
||||||
* @param file 要上传的文件
|
* @param file 要上传的文件
|
||||||
* @return 文件id
|
* @return 文件上传信息体
|
||||||
* @author fengshuonan
|
* @author majianguo
|
||||||
* @date 2020/11/29 13:38
|
* @date 2020/12/16 15:47
|
||||||
*/
|
*/
|
||||||
Long uploadFile(MultipartFile file);
|
SysFileInfoResponse uploadFile(MultipartFile file, SysFileInfoRequest sysFileInfoRequest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新文件,返回文件的唯一标识
|
||||||
|
*
|
||||||
|
* @param file 要上传的文件
|
||||||
|
* @param sysFileInfoRequest 如果是替换,需带上code以便版本升级
|
||||||
|
* @return 文件上传返回体
|
||||||
|
* @author majianguo
|
||||||
|
* @date 2020/12/16 15:46
|
||||||
|
*/
|
||||||
|
SysFileInfoResponse updateFile(MultipartFile file, SysFileInfoRequest sysFileInfoRequest);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 文件下载
|
* 文件下载
|
||||||
|
@ -39,23 +61,68 @@ public interface SysFileInfoService extends IService<SysFileInfo> {
|
||||||
void download(SysFileInfoRequest sysFileInfoRequest, HttpServletResponse response);
|
void download(SysFileInfoRequest sysFileInfoRequest, HttpServletResponse response);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 删除文件信息表
|
* 删除文件信息(真删除文件信息)
|
||||||
*
|
*
|
||||||
* @param sysFileInfoRequest 删除参数
|
* @param sysFileInfoRequest 删除参数
|
||||||
* @author fengshuonan
|
* @author fengshuonan
|
||||||
* @date 2020/11/29 13:44
|
* @date 2020/11/29 13:44
|
||||||
*/
|
*/
|
||||||
void delete(SysFileInfoRequest sysFileInfoRequest);
|
void deleteReally(SysFileInfoRequest sysFileInfoRequest);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 文件预览,通过参数中传递文件id
|
* 分页查询文件信息表
|
||||||
*
|
*
|
||||||
* @param sysFileInfoRequest 文件预览参数
|
* @param sysFileInfoRequest 查询参数
|
||||||
* @param response 响应结果
|
* @return 查询分页结果
|
||||||
* @author fengshuonan
|
* @author fengshuonan
|
||||||
* @date 2020/11/29 13:45
|
* @date 2020/11/29 14:09
|
||||||
*/
|
*/
|
||||||
void previewByFileId(SysFileInfoRequest sysFileInfoRequest, HttpServletResponse response);
|
PageResult<SysFileInfoListResponse> fileInfoListPage(SysFileInfoRequest sysFileInfoRequest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 打包下载文件
|
||||||
|
*
|
||||||
|
* @param fileIds 文件ID集合,使用,号分割
|
||||||
|
* @param secretFlag 是否私有文件
|
||||||
|
* @param response 响应结果
|
||||||
|
* @author majianguo
|
||||||
|
* @date 2020/12/7 下午4:47
|
||||||
|
*/
|
||||||
|
void packagingDownload(String fileIds, String secretFlag, HttpServletResponse response);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据附件IDS查询附件信息
|
||||||
|
*
|
||||||
|
* @param fileIds 附件IDS
|
||||||
|
* @author majianguo
|
||||||
|
* @date 2020/12/27 12:52
|
||||||
|
*/
|
||||||
|
List<SysFileInfoResponse> getFileInfoListByFileIds(String fileIds);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件预览
|
||||||
|
*
|
||||||
|
* @author fengshuonan
|
||||||
|
* @date 2020/11/29 11:29
|
||||||
|
*/
|
||||||
|
void preview(SysFileInfoRequest sysFileInfoRequest, HttpServletResponse response);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 替换附件回调
|
||||||
|
*
|
||||||
|
* @param fileIdList 文件id列表
|
||||||
|
* @author majianguo
|
||||||
|
* @date 2020/12/27 12:52
|
||||||
|
*/
|
||||||
|
void confirmReplaceFile(List<Long> fileIdList);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 版本回退
|
||||||
|
*
|
||||||
|
* @author majianguo
|
||||||
|
* @date 2020/12/27 13:49
|
||||||
|
*/
|
||||||
|
SysFileInfoResponse versionBack(SysFileInfoRequest sysFileInfoRequest);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 文件预览,通过参数中传递fileBucket和fileObjectName
|
* 文件预览,通过参数中传递fileBucket和fileObjectName
|
||||||
|
@ -77,34 +144,4 @@ public interface SysFileInfoService extends IService<SysFileInfo> {
|
||||||
*/
|
*/
|
||||||
SysFileInfo detail(SysFileInfoRequest sysFileInfoRequest);
|
SysFileInfo detail(SysFileInfoRequest sysFileInfoRequest);
|
||||||
|
|
||||||
/**
|
|
||||||
* 分页查询文件信息表
|
|
||||||
*
|
|
||||||
* @param sysFileInfoRequest 查询参数
|
|
||||||
* @return 查询分页结果
|
|
||||||
* @author fengshuonan
|
|
||||||
* @date 2020/11/29 14:09
|
|
||||||
*/
|
|
||||||
PageResult<SysFileInfo> page(SysFileInfoRequest sysFileInfoRequest);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 查询所有文件信息表
|
|
||||||
*
|
|
||||||
* @param sysFileInfoRequest 查询参数
|
|
||||||
* @return 文件信息列表
|
|
||||||
* @author fengshuonan
|
|
||||||
* @date 2020/11/29 14:15
|
|
||||||
*/
|
|
||||||
List<SysFileInfo> list(SysFileInfoRequest sysFileInfoRequest);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取文件信息结果集
|
|
||||||
*
|
|
||||||
* @param fileId 文件id
|
|
||||||
* @return 文件信息结果集
|
|
||||||
* @author fengshuonan
|
|
||||||
* @date 2020/11/29 14:16
|
|
||||||
*/
|
|
||||||
SysFileInfoResponse getFileInfoResult(Long fileId);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
package cn.stylefeng.roses.kernel.file.modular.service.impl;
|
package cn.stylefeng.roses.kernel.file.modular.service.impl;
|
||||||
|
|
||||||
import cn.hutool.core.bean.BeanUtil;
|
import cn.hutool.core.bean.BeanUtil;
|
||||||
import cn.hutool.core.convert.Convert;
|
import cn.hutool.core.date.DateUtil;
|
||||||
import cn.hutool.core.util.NumberUtil;
|
import cn.hutool.core.io.FileUtil;
|
||||||
|
import cn.hutool.core.io.IoUtil;
|
||||||
import cn.hutool.core.util.ObjectUtil;
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import cn.stylefeng.roses.kernel.db.api.factory.PageFactory;
|
import cn.stylefeng.roses.kernel.db.api.factory.PageFactory;
|
||||||
|
@ -10,15 +11,18 @@ import cn.stylefeng.roses.kernel.db.api.factory.PageResultFactory;
|
||||||
import cn.stylefeng.roses.kernel.db.api.pojo.page.PageResult;
|
import cn.stylefeng.roses.kernel.db.api.pojo.page.PageResult;
|
||||||
import cn.stylefeng.roses.kernel.file.FileInfoApi;
|
import cn.stylefeng.roses.kernel.file.FileInfoApi;
|
||||||
import cn.stylefeng.roses.kernel.file.FileOperatorApi;
|
import cn.stylefeng.roses.kernel.file.FileOperatorApi;
|
||||||
import cn.stylefeng.roses.kernel.file.enums.FileLocationEnum;
|
import cn.stylefeng.roses.kernel.file.enums.FileStatusEnum;
|
||||||
import cn.stylefeng.roses.kernel.file.exception.FileException;
|
import cn.stylefeng.roses.kernel.file.exception.FileException;
|
||||||
import cn.stylefeng.roses.kernel.file.exception.enums.FileExceptionEnum;
|
import cn.stylefeng.roses.kernel.file.exception.enums.FileExceptionEnum;
|
||||||
import cn.stylefeng.roses.kernel.file.modular.entity.SysFileInfo;
|
import cn.stylefeng.roses.kernel.file.modular.entity.SysFileInfo;
|
||||||
|
import cn.stylefeng.roses.kernel.file.modular.factory.FileInfoFactory;
|
||||||
import cn.stylefeng.roses.kernel.file.modular.mapper.SysFileInfoMapper;
|
import cn.stylefeng.roses.kernel.file.modular.mapper.SysFileInfoMapper;
|
||||||
import cn.stylefeng.roses.kernel.file.modular.service.SysFileInfoService;
|
import cn.stylefeng.roses.kernel.file.modular.service.SysFileInfoService;
|
||||||
import cn.stylefeng.roses.kernel.file.pojo.request.SysFileInfoRequest;
|
import cn.stylefeng.roses.kernel.file.pojo.request.SysFileInfoRequest;
|
||||||
|
import cn.stylefeng.roses.kernel.file.pojo.response.SysFileInfoListResponse;
|
||||||
import cn.stylefeng.roses.kernel.file.pojo.response.SysFileInfoResponse;
|
import cn.stylefeng.roses.kernel.file.pojo.response.SysFileInfoResponse;
|
||||||
import cn.stylefeng.roses.kernel.file.util.DownloadUtil;
|
import cn.stylefeng.roses.kernel.file.util.DownloadUtil;
|
||||||
|
import cn.stylefeng.roses.kernel.file.util.PdfFileTypeUtil;
|
||||||
import cn.stylefeng.roses.kernel.file.util.PicFileTypeUtil;
|
import cn.stylefeng.roses.kernel.file.util.PicFileTypeUtil;
|
||||||
import cn.stylefeng.roses.kernel.rule.enums.YesOrNotEnum;
|
import cn.stylefeng.roses.kernel.rule.enums.YesOrNotEnum;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
|
@ -27,18 +31,25 @@ import com.baomidou.mybatisplus.core.toolkit.IdWorker;
|
||||||
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 lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
|
import javax.servlet.ServletOutputStream;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.math.BigDecimal;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.zip.ZipEntry;
|
||||||
|
import java.util.zip.ZipOutputStream;
|
||||||
|
|
||||||
import static cn.stylefeng.roses.kernel.file.constants.FileConstants.DEFAULT_BUCKET_NAME;
|
import static cn.stylefeng.roses.kernel.file.constants.FileConstants.DEFAULT_BUCKET_NAME;
|
||||||
import static cn.stylefeng.roses.kernel.file.constants.FileConstants.FILE_POSTFIX_SEPARATOR;
|
import static cn.stylefeng.roses.kernel.file.constants.FileConstants.FILE_POSTFIX_SEPARATOR;
|
||||||
|
import static cn.stylefeng.roses.kernel.file.exception.enums.FileExceptionEnum.FILE_NOT_FOUND;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 文件信息表 服务实现类
|
* 文件信息表 服务实现类
|
||||||
|
@ -53,139 +64,9 @@ public class SysFileInfoServiceImpl extends ServiceImpl<SysFileInfoMapper, SysFi
|
||||||
@Resource
|
@Resource
|
||||||
private FileOperatorApi fileOperatorApi;
|
private FileOperatorApi fileOperatorApi;
|
||||||
|
|
||||||
@Override
|
|
||||||
public Long uploadFile(MultipartFile file) {
|
|
||||||
|
|
||||||
// 生成文件的唯一id
|
|
||||||
Long fileId = IdWorker.getId();
|
|
||||||
|
|
||||||
// 获取文件原始名称
|
|
||||||
String originalFilename = file.getOriginalFilename();
|
|
||||||
|
|
||||||
// 获取文件后缀,不包含点
|
|
||||||
String fileSuffix = null;
|
|
||||||
if (ObjectUtil.isNotEmpty(originalFilename)) {
|
|
||||||
fileSuffix = StrUtil.subAfter(originalFilename, FILE_POSTFIX_SEPARATOR, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 生成文件的最终名称
|
|
||||||
String finalFileName = fileId + FILE_POSTFIX_SEPARATOR + fileSuffix;
|
|
||||||
|
|
||||||
// 存储文件
|
|
||||||
byte[] bytes;
|
|
||||||
try {
|
|
||||||
bytes = file.getBytes();
|
|
||||||
fileOperatorApi.storageFile(DEFAULT_BUCKET_NAME, finalFileName, bytes);
|
|
||||||
} catch (IOException e) {
|
|
||||||
String userTip = StrUtil.format(FileExceptionEnum.ERROR_FILE.getUserTip(), e.getMessage());
|
|
||||||
throw new FileException(FileExceptionEnum.ERROR_FILE, userTip);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 计算文件大小kb
|
|
||||||
long fileSizeKb = Convert.toLong(NumberUtil.div(new BigDecimal(file.getSize()), BigDecimal.valueOf(1024))
|
|
||||||
.setScale(0, BigDecimal.ROUND_HALF_UP));
|
|
||||||
|
|
||||||
// 存储文件信息
|
|
||||||
SysFileInfo sysFileInfo = new SysFileInfo();
|
|
||||||
sysFileInfo.setFileId(fileId);
|
|
||||||
sysFileInfo.setFileLocation(FileLocationEnum.LOCAL.getCode());
|
|
||||||
sysFileInfo.setFileBucket(DEFAULT_BUCKET_NAME);
|
|
||||||
sysFileInfo.setFileObjectName(finalFileName);
|
|
||||||
sysFileInfo.setFileOriginName(originalFilename);
|
|
||||||
sysFileInfo.setFileSuffix(fileSuffix);
|
|
||||||
sysFileInfo.setFileSizeKb(fileSizeKb);
|
|
||||||
this.save(sysFileInfo);
|
|
||||||
|
|
||||||
// 返回文件id
|
|
||||||
return fileId;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void download(SysFileInfoRequest sysFileInfoRequest, HttpServletResponse response) {
|
|
||||||
SysFileInfoResponse sysFileInfoResult = this.getFileInfoResult(sysFileInfoRequest.getFileId());
|
|
||||||
String fileName = sysFileInfoResult.getFileOriginName();
|
|
||||||
byte[] fileBytes = sysFileInfoResult.getFileBytes();
|
|
||||||
DownloadUtil.download(fileName, fileBytes, response);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Transactional(rollbackFor = Exception.class)
|
|
||||||
@Override
|
|
||||||
public void delete(SysFileInfoRequest sysFileInfoRequest) {
|
|
||||||
// 逻辑删除
|
|
||||||
LambdaUpdateWrapper<SysFileInfo> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
|
|
||||||
lambdaUpdateWrapper.set(SysFileInfo::getDelFlag, YesOrNotEnum.Y.getCode());
|
|
||||||
lambdaUpdateWrapper.eq(SysFileInfo::getFileId, sysFileInfoRequest.getFileId());
|
|
||||||
this.update(lambdaUpdateWrapper);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void previewByFileId(SysFileInfoRequest sysFileInfoRequest, HttpServletResponse response) {
|
|
||||||
|
|
||||||
byte[] fileBytes;
|
|
||||||
|
|
||||||
// 根据文件id获取文件信息结果集
|
|
||||||
SysFileInfoResponse sysFileInfoResult = this.getFileInfoResult(sysFileInfoRequest.getFileId());
|
|
||||||
|
|
||||||
// 获取文件后缀
|
|
||||||
String fileSuffix = sysFileInfoResult.getFileSuffix().toLowerCase();
|
|
||||||
|
|
||||||
// 获取文件字节码
|
|
||||||
fileBytes = sysFileInfoResult.getFileBytes();
|
|
||||||
|
|
||||||
// 如果是图片类型,则直接输出
|
|
||||||
if (PicFileTypeUtil.getFileImgTypeFlag(fileSuffix)) {
|
|
||||||
DownloadUtil.renderPreviewFile(response, fileBytes);
|
|
||||||
} else {
|
|
||||||
// 不支持别的文件预览
|
|
||||||
throw new FileException(FileExceptionEnum.PREVIEW_ERROR_NOT_SUPPORT);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void previewByBucketAndObjName(SysFileInfoRequest sysFileInfoRequest, HttpServletResponse response) {
|
|
||||||
|
|
||||||
// 获取文件字节码
|
|
||||||
byte[] fileBytes;
|
|
||||||
try {
|
|
||||||
fileBytes = fileOperatorApi.getFileBytes(sysFileInfoRequest.getFileBucket(), sysFileInfoRequest.getFileObjectName());
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error(">>> 获取文件流异常,具体信息为:{}", e.getMessage());
|
|
||||||
throw new FileException(FileExceptionEnum.FILE_STREAM_ERROR);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 如果是图片类型,则直接输出
|
|
||||||
if (PicFileTypeUtil.getFileImgTypeFlag(sysFileInfoRequest.getFileObjectName())) {
|
|
||||||
DownloadUtil.renderPreviewFile(response, fileBytes);
|
|
||||||
} else {
|
|
||||||
// 不支持别的文件预览
|
|
||||||
throw new FileException(FileExceptionEnum.PREVIEW_ERROR_NOT_SUPPORT);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SysFileInfo detail(SysFileInfoRequest sysFileInfoRequest) {
|
|
||||||
return this.querySysFileInfo(sysFileInfoRequest);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public PageResult<SysFileInfo> page(SysFileInfoRequest sysFileInfoRequest) {
|
|
||||||
LambdaQueryWrapper<SysFileInfo> queryWrapper = createWrapper(sysFileInfoRequest);
|
|
||||||
Page<SysFileInfo> page = this.page(PageFactory.defaultPage(), queryWrapper);
|
|
||||||
return PageResultFactory.createPageResult(page);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<SysFileInfo> list(SysFileInfoRequest sysFileInfoRequest) {
|
|
||||||
LambdaQueryWrapper<SysFileInfo> queryWrapper = new LambdaQueryWrapper<>();
|
|
||||||
queryWrapper.eq(SysFileInfo::getDelFlag, YesOrNotEnum.N.getCode());
|
|
||||||
return this.list(queryWrapper);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SysFileInfoResponse getFileInfoResult(Long fileId) {
|
public SysFileInfoResponse getFileInfoResult(Long fileId) {
|
||||||
|
|
||||||
SysFileInfoResponse sysFileInfoResult = new SysFileInfoResponse();
|
|
||||||
|
|
||||||
// 查询库中文件信息
|
// 查询库中文件信息
|
||||||
SysFileInfoRequest sysFileInfoRequest = new SysFileInfoRequest();
|
SysFileInfoRequest sysFileInfoRequest = new SysFileInfoRequest();
|
||||||
sysFileInfoRequest.setFileId(fileId);
|
sysFileInfoRequest.setFileId(fileId);
|
||||||
|
@ -201,12 +82,257 @@ public class SysFileInfoServiceImpl extends ServiceImpl<SysFileInfoMapper, SysFi
|
||||||
}
|
}
|
||||||
|
|
||||||
// 设置文件字节码
|
// 设置文件字节码
|
||||||
|
SysFileInfoResponse sysFileInfoResult = new SysFileInfoResponse();
|
||||||
BeanUtil.copyProperties(sysFileInfo, sysFileInfoResult);
|
BeanUtil.copyProperties(sysFileInfo, sysFileInfoResult);
|
||||||
sysFileInfoResult.setFileBytes(fileBytes);
|
sysFileInfoResult.setFileBytes(fileBytes);
|
||||||
|
|
||||||
return sysFileInfoResult;
|
return sysFileInfoResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public SysFileInfoResponse uploadFile(MultipartFile file, SysFileInfoRequest sysFileInfoRequest) {
|
||||||
|
|
||||||
|
// 文件请求转换存入数据库的附件信息
|
||||||
|
SysFileInfo sysFileInfo = FileInfoFactory.createSysFileInfo(file, sysFileInfoRequest);
|
||||||
|
|
||||||
|
// 默认版本号从1开始
|
||||||
|
sysFileInfo.setFileVersion(1);
|
||||||
|
|
||||||
|
// 文件编码生成
|
||||||
|
sysFileInfo.setFileCode(IdWorker.getId());
|
||||||
|
|
||||||
|
// 保存附件到附件信息表
|
||||||
|
this.save(sysFileInfo);
|
||||||
|
|
||||||
|
// 返回文件信息体
|
||||||
|
SysFileInfoResponse fileUploadInfoResult = new SysFileInfoResponse();
|
||||||
|
BeanUtil.copyProperties(sysFileInfo, fileUploadInfoResult);
|
||||||
|
return fileUploadInfoResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SysFileInfoResponse updateFile(MultipartFile file, SysFileInfoRequest sysFileInfoRequest) {
|
||||||
|
|
||||||
|
Long fileCode = sysFileInfoRequest.getFileCode();
|
||||||
|
|
||||||
|
// 转换存入数据库的附件信息
|
||||||
|
SysFileInfo sysFileInfo = FileInfoFactory.createSysFileInfo(file, sysFileInfoRequest);
|
||||||
|
sysFileInfo.setDelFlag(YesOrNotEnum.Y.getCode());
|
||||||
|
sysFileInfo.setFileCode(fileCode);
|
||||||
|
|
||||||
|
// 查询该code下的最新版本号附件信息
|
||||||
|
LambdaQueryWrapper<SysFileInfo> queryWrapper = new LambdaQueryWrapper<>();
|
||||||
|
queryWrapper.eq(SysFileInfo::getFileCode, fileCode);
|
||||||
|
queryWrapper.eq(SysFileInfo::getDelFlag, YesOrNotEnum.N.getCode());
|
||||||
|
queryWrapper.eq(SysFileInfo::getFileStatus, FileStatusEnum.NEW.getCode());
|
||||||
|
SysFileInfo fileInfo = this.getOne(queryWrapper);
|
||||||
|
if (ObjectUtil.isEmpty(fileInfo)) {
|
||||||
|
throw new FileException(FileExceptionEnum.NOT_EXISTED);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置版本号在原本的基础上加一
|
||||||
|
sysFileInfo.setFileVersion(fileInfo.getFileVersion() + 1);
|
||||||
|
|
||||||
|
// 存储新版本文件信息
|
||||||
|
this.save(sysFileInfo);
|
||||||
|
|
||||||
|
// 返回文件信息体
|
||||||
|
SysFileInfoResponse fileUploadInfoResult = new SysFileInfoResponse();
|
||||||
|
BeanUtil.copyProperties(sysFileInfo, fileUploadInfoResult);
|
||||||
|
return fileUploadInfoResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void download(SysFileInfoRequest sysFileInfoRequest, HttpServletResponse response) {
|
||||||
|
|
||||||
|
// 根据文件id获取文件信息结果集
|
||||||
|
SysFileInfoResponse sysFileInfoResponse = this.getFileInfoResult(sysFileInfoRequest.getFileId());
|
||||||
|
|
||||||
|
// 如果文件加密等级不符合,文件不允许被访问
|
||||||
|
if (!sysFileInfoRequest.getSecretFlag().equals(sysFileInfoResponse.getSecretFlag())) {
|
||||||
|
throw new FileException(FileExceptionEnum.FILE_DENIED_ACCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
DownloadUtil.download(sysFileInfoResponse.getFileOriginName(), sysFileInfoResponse.getFileBytes(), response);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
@Override
|
||||||
|
public void deleteReally(SysFileInfoRequest sysFileInfoRequest) {
|
||||||
|
|
||||||
|
// 查询该Code的所有历史版本
|
||||||
|
LambdaQueryWrapper<SysFileInfo> lqw = new LambdaQueryWrapper<>();
|
||||||
|
lqw.eq(SysFileInfo::getFileCode, sysFileInfoRequest.getFileCode());
|
||||||
|
List<SysFileInfo> fileInfos = this.list(lqw);
|
||||||
|
|
||||||
|
// 批量删除
|
||||||
|
this.removeByIds(fileInfos.stream().map(SysFileInfo::getFileId).collect(Collectors.toList()));
|
||||||
|
|
||||||
|
// 删除具体文件
|
||||||
|
for (SysFileInfo fileInfo : fileInfos) {
|
||||||
|
this.fileOperatorApi.deleteFile(fileInfo.getFileBucket(), fileInfo.getFileObjectName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PageResult<SysFileInfoListResponse> fileInfoListPage(SysFileInfoRequest sysFileInfoRequest) {
|
||||||
|
Page<SysFileInfoListResponse> page = PageFactory.defaultPage();
|
||||||
|
List<SysFileInfoListResponse> list = this.baseMapper.fileInfoList(page, sysFileInfoRequest);
|
||||||
|
return PageResultFactory.createPageResult(page.setRecords(list));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void packagingDownload(String fileIds, String secretFlag, HttpServletResponse response) {
|
||||||
|
|
||||||
|
// 获取文件信息
|
||||||
|
List<Long> fileIdList = Arrays.stream(fileIds.split(",")).map(s -> Long.parseLong(s.trim())).collect(Collectors.toList());
|
||||||
|
List<SysFileInfoResponse> fileInfoResponseList = this.baseMapper.getFileInfoListByFileIds(fileIdList);
|
||||||
|
|
||||||
|
// 输出流等信息
|
||||||
|
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||||
|
ZipOutputStream zip = new ZipOutputStream(bos);
|
||||||
|
|
||||||
|
try {
|
||||||
|
for (int i = 0; i < fileInfoResponseList.size(); i++) {
|
||||||
|
SysFileInfoResponse sysFileInfoResponse = fileInfoResponseList.get(i);
|
||||||
|
if (ObjectUtil.isNotEmpty(sysFileInfoResponse)) {
|
||||||
|
String fileOriginName = sysFileInfoResponse.getFileOriginName();
|
||||||
|
// 判断公有文件下载时是否包含私有文件
|
||||||
|
if (secretFlag.equals(YesOrNotEnum.N.getCode()) && !secretFlag.equals(sysFileInfoResponse.getSecretFlag())) {
|
||||||
|
String userTip = StrUtil.format(FileExceptionEnum.SECRET_FLAG_INFO_ERROR.getUserTip(), fileOriginName);
|
||||||
|
throw new FileException(FileExceptionEnum.SECRET_FLAG_INFO_ERROR, userTip);
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] fileBytes = fileOperatorApi.getFileBytes(DEFAULT_BUCKET_NAME, sysFileInfoResponse.getFileObjectName());
|
||||||
|
ZipEntry entry = new ZipEntry(i + 1 + "." + fileOriginName);
|
||||||
|
entry.setSize(fileBytes.length);
|
||||||
|
zip.putNextEntry(entry);
|
||||||
|
zip.write(fileBytes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
zip.finish();
|
||||||
|
|
||||||
|
// 下载文件
|
||||||
|
DownloadUtil.download(DateUtil.now() + "-打包下载" + FILE_POSTFIX_SEPARATOR + "zip", bos.toByteArray(), response);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error(">>> 获取文件流异常,具体信息为:{}", e.getMessage());
|
||||||
|
throw new FileException(FileExceptionEnum.FILE_STREAM_ERROR);
|
||||||
|
} finally {
|
||||||
|
try {
|
||||||
|
zip.closeEntry();
|
||||||
|
zip.close();
|
||||||
|
bos.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.error(">>> 关闭数据流失败,具体信息为:{}", e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<SysFileInfoResponse> getFileInfoListByFileIds(String fileIds) {
|
||||||
|
List<Long> fileIdList = Arrays.stream(fileIds.split(",")).map(s -> Long.parseLong(s.trim())).collect(Collectors.toList());
|
||||||
|
return this.baseMapper.getFileInfoListByFileIds(fileIdList);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void preview(SysFileInfoRequest sysFileInfoRequest, HttpServletResponse response) {
|
||||||
|
|
||||||
|
// 根据文件id获取文件信息结果集
|
||||||
|
SysFileInfoResponse sysFileInfoResponse = this.getFileInfoResult(sysFileInfoRequest.getFileId());
|
||||||
|
|
||||||
|
// 如果文件加密等级不符合,文件不允许被访问
|
||||||
|
if (!sysFileInfoRequest.getSecretFlag().equals(sysFileInfoResponse.getSecretFlag())) {
|
||||||
|
throw new FileException(FileExceptionEnum.FILE_DENIED_ACCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取文件后缀
|
||||||
|
String fileSuffix = sysFileInfoResponse.getFileSuffix().toLowerCase();
|
||||||
|
|
||||||
|
// 获取文件字节码
|
||||||
|
byte[] fileBytes = sysFileInfoResponse.getFileBytes();
|
||||||
|
|
||||||
|
// 附件预览
|
||||||
|
this.renderPreviewFile(response, fileSuffix, fileBytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public void confirmReplaceFile(List<Long> fileIdList) {
|
||||||
|
|
||||||
|
// 获取所有附件信息的code集合
|
||||||
|
if (fileIdList == null || fileIdList.size() == 0) {
|
||||||
|
throw new FileException(FileExceptionEnum.FILE_IDS_EMPTY);
|
||||||
|
}
|
||||||
|
List<Long> fileCodeList = this.baseMapper.getFileCodeByFileIds(fileIdList);
|
||||||
|
if (fileCodeList == null || fileCodeList.size() == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 修改该codes下所有附件删除状态为Y
|
||||||
|
this.baseMapper.updateDelFlagByFileCodes(fileCodeList, YesOrNotEnum.Y.getCode());
|
||||||
|
|
||||||
|
// 修改当前fileIds下所有附件删除状态为N
|
||||||
|
this.baseMapper.updateDelFlagByFileIds(fileIdList, YesOrNotEnum.N.getCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public SysFileInfoResponse versionBack(SysFileInfoRequest sysFileInfoRequest) {
|
||||||
|
|
||||||
|
LambdaQueryWrapper<SysFileInfo> queryWrapper = new LambdaQueryWrapper<>();
|
||||||
|
queryWrapper.eq(SysFileInfo::getFileId, sysFileInfoRequest.getFileId());
|
||||||
|
SysFileInfo fileInfo = this.getOne(queryWrapper);
|
||||||
|
|
||||||
|
// 判断有没有这个文件
|
||||||
|
if (ObjectUtil.isEmpty(fileInfo)) {
|
||||||
|
String userTip = FileExceptionEnum.FILE_NOT_FOUND.getUserTip();
|
||||||
|
String errorMessage = StrUtil.format(userTip, "文件:" + fileInfo.getFileId() + "未找到!");
|
||||||
|
throw new FileException(FILE_NOT_FOUND.getErrorCode(), errorMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 把之前的文件刷回
|
||||||
|
LambdaUpdateWrapper<SysFileInfo> oldFileInfoLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
|
||||||
|
oldFileInfoLambdaUpdateWrapper.eq(SysFileInfo::getFileCode, fileInfo.getFileCode());
|
||||||
|
oldFileInfoLambdaUpdateWrapper.eq(SysFileInfo::getFileStatus, FileStatusEnum.NEW.getCode());
|
||||||
|
oldFileInfoLambdaUpdateWrapper.set(SysFileInfo::getFileStatus, FileStatusEnum.OLD.getCode());
|
||||||
|
this.update(oldFileInfoLambdaUpdateWrapper);
|
||||||
|
|
||||||
|
// 修改文件状态
|
||||||
|
LambdaUpdateWrapper<SysFileInfo> newFileInfoLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
|
||||||
|
newFileInfoLambdaUpdateWrapper.eq(SysFileInfo::getFileId, sysFileInfoRequest.getFileId());
|
||||||
|
newFileInfoLambdaUpdateWrapper.set(SysFileInfo::getFileStatus, FileStatusEnum.NEW.getCode());
|
||||||
|
newFileInfoLambdaUpdateWrapper.set(SysFileInfo::getDelFlag, YesOrNotEnum.N.getCode());
|
||||||
|
this.update(newFileInfoLambdaUpdateWrapper);
|
||||||
|
|
||||||
|
// 返回
|
||||||
|
return BeanUtil.toBean(fileInfo, SysFileInfoResponse.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void previewByBucketAndObjName(SysFileInfoRequest sysFileInfoRequest, HttpServletResponse response) {
|
||||||
|
|
||||||
|
// 获取文件字节码
|
||||||
|
byte[] fileBytes;
|
||||||
|
try {
|
||||||
|
fileBytes = fileOperatorApi.getFileBytes(sysFileInfoRequest.getFileBucket(), sysFileInfoRequest.getFileObjectName());
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error(">>> 获取文件流异常,具体信息为:{}", e.getMessage());
|
||||||
|
throw new FileException(FileExceptionEnum.FILE_STREAM_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取文件后缀
|
||||||
|
String fileSuffix = FileUtil.getSuffix(sysFileInfoRequest.getFileObjectName());
|
||||||
|
|
||||||
|
// 附件预览
|
||||||
|
this.renderPreviewFile(response, fileSuffix, fileBytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SysFileInfo detail(SysFileInfoRequest sysFileInfoRequest) {
|
||||||
|
return this.querySysFileInfo(sysFileInfoRequest);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SysFileInfoResponse getFileInfoWithoutContent(Long fileId) {
|
public SysFileInfoResponse getFileInfoWithoutContent(Long fileId) {
|
||||||
|
|
||||||
|
@ -223,6 +349,39 @@ public class SysFileInfoServiceImpl extends ServiceImpl<SysFileInfoMapper, SysFi
|
||||||
return sysFileInfoResponse;
|
return sysFileInfoResponse;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 渲染被预览的文件到servlet的response流中
|
||||||
|
*
|
||||||
|
* @author fengshuonan
|
||||||
|
* @date 2020/11/29 17:13
|
||||||
|
*/
|
||||||
|
private void renderPreviewFile(HttpServletResponse response, String fileSuffix, byte[] fileBytes) {
|
||||||
|
|
||||||
|
// 如果文件后缀是图片或者pdf,则直接输出流
|
||||||
|
if (PicFileTypeUtil.getFileImgTypeFlag(fileSuffix) || PdfFileTypeUtil.getFilePdfTypeFlag(fileSuffix)) {
|
||||||
|
try {
|
||||||
|
// 设置contentType
|
||||||
|
if (PicFileTypeUtil.getFileImgTypeFlag(fileSuffix)) {
|
||||||
|
response.setContentType(MediaType.IMAGE_PNG_VALUE);
|
||||||
|
} else if (PdfFileTypeUtil.getFilePdfTypeFlag(fileSuffix)) {
|
||||||
|
response.setContentType(MediaType.APPLICATION_PDF_VALUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取outputStream
|
||||||
|
ServletOutputStream outputStream = response.getOutputStream();
|
||||||
|
|
||||||
|
// 输出字节流
|
||||||
|
IoUtil.write(outputStream, true, fileBytes);
|
||||||
|
} catch (IOException e) {
|
||||||
|
String userTip = StrUtil.format(FileExceptionEnum.WRITE_BYTES_ERROR.getUserTip(), e.getMessage());
|
||||||
|
throw new FileException(FileExceptionEnum.WRITE_BYTES_ERROR, userTip);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 不支持别的文件预览
|
||||||
|
throw new FileException(FileExceptionEnum.PREVIEW_ERROR_NOT_SUPPORT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取文件信息表
|
* 获取文件信息表
|
||||||
*
|
*
|
||||||
|
@ -238,41 +397,4 @@ public class SysFileInfoServiceImpl extends ServiceImpl<SysFileInfoMapper, SysFi
|
||||||
return sysFileInfo;
|
return sysFileInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建组织架构的通用条件查询wrapper
|
|
||||||
*
|
|
||||||
* @author fengshuonan
|
|
||||||
* @date 2020/11/6 10:16
|
|
||||||
*/
|
|
||||||
private LambdaQueryWrapper<SysFileInfo> createWrapper(SysFileInfoRequest sysFileInfoRequest) {
|
|
||||||
LambdaQueryWrapper<SysFileInfo> queryWrapper = new LambdaQueryWrapper<>();
|
|
||||||
if (ObjectUtil.isNotNull(sysFileInfoRequest)) {
|
|
||||||
|
|
||||||
// 拼接文件存储位置条件
|
|
||||||
if (ObjectUtil.isNotEmpty(sysFileInfoRequest.getFileLocation())) {
|
|
||||||
queryWrapper.like(SysFileInfo::getFileLocation, sysFileInfoRequest.getFileLocation());
|
|
||||||
}
|
|
||||||
|
|
||||||
// 拼接文件仓库条件
|
|
||||||
if (ObjectUtil.isNotEmpty(sysFileInfoRequest.getFileBucket())) {
|
|
||||||
queryWrapper.like(SysFileInfo::getFileBucket, sysFileInfoRequest.getFileBucket());
|
|
||||||
}
|
|
||||||
|
|
||||||
// 拼接文件名称(上传时候的文件名)
|
|
||||||
if (ObjectUtil.isNotEmpty(sysFileInfoRequest.getFileOriginName())) {
|
|
||||||
queryWrapper.like(SysFileInfo::getFileOriginName, sysFileInfoRequest.getFileOriginName());
|
|
||||||
}
|
|
||||||
|
|
||||||
// 拼接文件名称(存储到系统的文件名)
|
|
||||||
if (ObjectUtil.isNotEmpty(sysFileInfoRequest.getFileObjectName())) {
|
|
||||||
queryWrapper.like(SysFileInfo::getFileObjectName, sysFileInfoRequest.getFileObjectName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 查询没被删除的
|
|
||||||
queryWrapper.eq(SysFileInfo::getDelFlag, YesOrNotEnum.N.getCode());
|
|
||||||
|
|
||||||
return queryWrapper;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue