李旭 4 years ago
parent 67d5bae222
commit 191d72f8ea

@ -0,0 +1,71 @@
package com.anjiplus.template.gaea.business.modules.file.controller;
import com.anji.plus.gaea.bean.ResponseBean;
import com.anji.plus.gaea.curd.service.GaeaBaseService;
import com.anjiplus.template.gaea.business.base.BaseController;
import com.anjiplus.template.gaea.business.modules.file.controller.dto.GaeaFileDTO;
import com.anjiplus.template.gaea.business.modules.file.controller.param.GaeaFileParam;
import com.anjiplus.template.gaea.business.modules.file.entity.GaeaFile;
import com.anjiplus.template.gaea.business.modules.file.service.GaeaFileService;
import io.swagger.annotations.Api;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* (GaeaFile)
*
* @author peiyanni
* @since 2021-02-18 14:48:33
*/
@RestController
@RequestMapping("/file")
@Api(value = "/file", tags = "")
public class GaeaFileController extends BaseController<GaeaFileParam, GaeaFile, GaeaFileDTO> {
@Autowired
private GaeaFileService gaeaFileService;
@PostMapping("/upload")
public ResponseBean upload(@RequestParam("file") MultipartFile file) {
return ResponseBean.builder().message("success").data((gaeaFileService.upload(file))).build();
}
@GetMapping(value = "/download/{fileId}")
public ResponseEntity<byte[]> download(HttpServletRequest request, HttpServletResponse response, @PathVariable("fileId") String fileId) {
return gaeaFileService.download(request, response, fileId);
}
/**
*
*
* @return
*/
@Override
public GaeaBaseService<GaeaFileParam, GaeaFile> getService() {
return gaeaFileService;
}
/**
* ControllerEntity
*
* @return
*/
@Override
public GaeaFile getEntity() {
return new GaeaFile();
}
/**
* ControllerDTO
*
* @return
*/
@Override
public GaeaFileDTO getDTO() {
return new GaeaFileDTO();
}
}

@ -0,0 +1,67 @@
package com.anjiplus.template.gaea.business.modules.file.controller.dto;
import com.anji.plus.gaea.curd.dto.GaeaBaseDTO;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
/**
* (GaeaFile)
*
* @author peiyanni
* @since 2021-02-18 14:48:27
*/
@ApiModel(value = "")
public class GaeaFileDTO extends GaeaBaseDTO {
/**
* uuid
*/
private String fileId;
/**
* linux/app/dist/export/excel/${fileid}.xlsx
*/
@ApiModelProperty(value = "文件在linux中的完整目录比如/app/dist/export/excel/${fileid}.xlsx")
private String filePath;
/**
* http
*/
@ApiModelProperty(value = "通过接口的下载完整http路径")
private String urlPath;
/**
* (202001~202012)
*/
@ApiModelProperty(value = "文件内容说明,比如 对账单(202001~202012)")
private String fileInstruction;
public String getFilePath() {
return filePath;
}
public void setFilePath(String filePath) {
this.filePath = filePath;
}
public String getUrlPath() {
return urlPath;
}
public void setUrlPath(String urlPath) {
this.urlPath = urlPath;
}
public String getFileInstruction() {
return fileInstruction;
}
public void setFileInstruction(String fileInstruction) {
this.fileInstruction = fileInstruction;
}
public String getFileId() {
return fileId;
}
public void setFileId(String fileId) {
this.fileId = fileId;
}
}

@ -0,0 +1,31 @@
package com.anjiplus.template.gaea.business.modules.file.controller.param;
import com.anji.plus.gaea.annotation.Query;
import com.anji.plus.gaea.constant.QueryEnum;
import com.anji.plus.gaea.curd.params.PageParam;
import java.io.Serializable;
/**
* (GaeaFile)param
*
* @author peiyanni
* @since 2021-02-18 14:48:29
*/
public class GaeaFileParam extends PageParam implements Serializable {
/**
* linux/app/dist/export/excel/${fileid}.xlsx
*/
@Query(QueryEnum.LIKE)
private String filePath;
public String getFilePath() {
return filePath;
}
public void setFilePath(String filePath) {
this.filePath = filePath;
}
}

@ -0,0 +1,17 @@
package com.anjiplus.template.gaea.business.modules.file.dao;
import com.anji.plus.gaea.curd.mapper.GaeaBaseMapper;
import com.anjiplus.template.gaea.business.modules.file.entity.GaeaFile;
import org.apache.ibatis.annotations.Mapper;
/**
* (GaeaFile)Mapper
*
* @author peiyanni
* @since 2021-02-18 14:48:24
*/
@Mapper
public interface GaeaFileMapper extends GaeaBaseMapper<GaeaFile> {
}

@ -0,0 +1,65 @@
package com.anjiplus.template.gaea.business.modules.file.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import com.anji.plus.gaea.curd.entity.GaeaBaseEntity;
import java.io.Serializable;
/**
* (GaeaFile)
*
* @author peiyanni
* @since 2021-02-18 14:48:20
*/
@TableName("gaea_file")
public class GaeaFile extends GaeaBaseEntity implements Serializable {
/**
* uuid
*/
private String fileId;
/**
* linux/app/dist/export/excel/${fileid}.xlsx
*/
private String filePath;
/**
* http
*/
private String urlPath;
/**
* (202001~202012)
*/
private String fileInstruction;
public String getFilePath() {
return filePath;
}
public void setFilePath(String filePath) {
this.filePath = filePath;
}
public String getUrlPath() {
return urlPath;
}
public void setUrlPath(String urlPath) {
this.urlPath = urlPath;
}
public String getFileInstruction() {
return fileInstruction;
}
public void setFileInstruction(String fileInstruction) {
this.fileInstruction = fileInstruction;
}
public String getFileId() {
return fileId;
}
public void setFileId(String fileId) {
this.fileId = fileId;
}
}

@ -0,0 +1,38 @@
package com.anjiplus.template.gaea.business.modules.file.service;
import com.anji.plus.gaea.curd.service.GaeaBaseService;
import com.anjiplus.template.gaea.business.modules.file.entity.GaeaFile;
import com.anjiplus.template.gaea.business.modules.file.controller.param.GaeaFileParam;
import org.springframework.http.ResponseEntity;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* (GaeaFile)Service
*
* @author peiyanni
* @since 2021-02-18 14:48:25
*/
public interface GaeaFileService extends GaeaBaseService<GaeaFileParam, GaeaFile> {
/**
*
*
* @param file
* @return 访
*/
String upload(MultipartFile file);
/**
* fileId
*
* @param request
* @param response
* @param fileId
* @return
*/
ResponseEntity<byte[]> download(HttpServletRequest request, HttpServletResponse response, String fileId);
}

@ -0,0 +1,187 @@
package com.anjiplus.template.gaea.business.modules.file.service.impl;
import com.anji.plus.gaea.constant.BaseOperationEnum;
import com.anji.plus.gaea.exception.BusinessException;
import com.anjiplus.template.gaea.business.modules.file.dao.GaeaFileMapper;
import com.anjiplus.template.gaea.business.modules.file.entity.GaeaFile;
import com.anjiplus.template.gaea.business.modules.file.service.GaeaFileService;
import com.anjiplus.template.gaea.business.modules.export.dao.GaeaExportMapper;
import com.anjiplus.template.gaea.business.modules.export.dao.entity.GaeaExport;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.anjiplus.template.gaea.common.RespCommonCode;
import com.anji.plus.gaea.curd.mapper.GaeaBaseMapper;
import com.anji.plus.gaea.exception.BusinessExceptionBuilder;
import com.anjiplus.template.gaea.common.util.StringPatternUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.CacheControl;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;
/**
* (GaeaFile)ServiceImpl
*
* @author peiyanni
* @since 2021-02-18 14:48:26
*/
@Service
@Slf4j
public class GaeaFileServiceImpl implements GaeaFileService {
@Value("${file.dist-path:''}")
private String dictPath;
@Value("${file.white-list:''}")
private String whiteList;
@Value("${file.excelSuffix:''}")
private String excelSuffix;
@Value("${file.downloadPath:''}")
private String fileDownloadPath;
@Autowired
private GaeaFileMapper gaeaFileMapper;
@Autowired
private GaeaExportMapper gaeaExportMapper;
@Override
public GaeaBaseMapper<GaeaFile> getMapper() {
return gaeaFileMapper;
}
@Override
@Transactional(rollbackFor = Exception.class)
public String upload(MultipartFile file) {
try {
String fileName = file.getOriginalFilename();
if (StringUtils.isBlank(fileName)) {
throw BusinessExceptionBuilder.build(RespCommonCode.FILE_EMPTY_FILENAME);
}
String suffixName = fileName.substring(fileName.lastIndexOf("."));
//白名单校验(不区分大小写)
List<String> list = new ArrayList<String>(Arrays.asList(whiteList.split("\\|")));
list.addAll(list.stream().map(String::toUpperCase).collect(Collectors.toList()));
if (!list.contains(suffixName)) {
throw BusinessExceptionBuilder.build(RespCommonCode.FILE_SUFFIX_UNSUPPORTED);
}
// 生成文件唯一性标识
String fileId = UUID.randomUUID().toString();
String newFileName = fileId + suffixName;
// 本地文件保存路径
String filePath = dictPath + newFileName;
String urlPath = fileDownloadPath + File.separator + fileId;
GaeaFile gaeaFile = new GaeaFile();
gaeaFile.setFilePath(filePath);
gaeaFile.setFileId(fileId);
gaeaFile.setUrlPath(urlPath);
gaeaFileMapper.insert(gaeaFile);
//写文件 将文件保存/app/dictPath/upload/下
File dest = new File(dictPath + newFileName);
file.transferTo(dest);
// 将完整的http访问路径返回
return urlPath;
} catch (Exception e) {
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
log.error("file upload error: {}", e);
throw BusinessExceptionBuilder.build(RespCommonCode.FILE_UPLOAD_ERROR);
}
}
@Override
public ResponseEntity<byte[]> download(HttpServletRequest request, HttpServletResponse response, String fileId) {
try {
String userAgent = request.getHeader("User-Agent");
boolean isIEBrowser = userAgent.indexOf("MSIE") > 0;
//根据fileId从gaea_file中读出filePath
LambdaQueryWrapper<GaeaFile> queryWrapper = Wrappers.lambdaQuery();
queryWrapper.eq(GaeaFile::getFileId, fileId);
GaeaFile gaeaFile = gaeaFileMapper.selectOne(queryWrapper);
if (null == gaeaFile) {
throw BusinessExceptionBuilder.build(RespCommonCode.FILE_ONT_EXSIT);
}
//解析文件路径、文件名和后缀
String filePath = gaeaFile.getFilePath();
if (StringUtils.isBlank(filePath)) {
throw BusinessExceptionBuilder.build(RespCommonCode.FILE_ONT_EXSIT);
}
String filename = filePath.substring(filePath.lastIndexOf(File.separator));
String fileSuffix = filename.substring(filename.lastIndexOf("."));
//特殊处理如果是excel文件则从t_export表中查询文件名
List list = Arrays.asList(excelSuffix.split("\\|"));
if (list.contains(fileSuffix)) {
LambdaQueryWrapper<GaeaExport> exportWrapper = Wrappers.lambdaQuery();
exportWrapper.eq(GaeaExport::getFileId, fileId);
GaeaExport exportPO = gaeaExportMapper.selectOne(exportWrapper);
if (null != exportPO) {
filename = exportPO.getFileTitle() + fileSuffix;
}
}
//根据文件后缀来判断,是显示图片\视频\音频,还是下载文件
File file = new File(filePath);
ResponseEntity.BodyBuilder builder = ResponseEntity.ok();
builder.contentLength(file.length());
if (StringPatternUtil.StringMatchIgnoreCase(fileSuffix, "(.png|.jpg|.jpeg|.bmp|.gif|.icon)")) {
builder.cacheControl(CacheControl.noCache()).contentType(MediaType.IMAGE_PNG);
} else if (StringPatternUtil.StringMatchIgnoreCase(fileSuffix, "(.flv|.swf|.mkv|.avi|.rm|.rmvb|.mpeg|.mpg|.ogg|.ogv|.mov|.wmv|.mp4|.webm|.wav|.mid|.mp3|.aac)")) {
builder.header("Content-Type", "video/mp4; charset=UTF-8");
} else {
//application/octet-stream 二进制数据流(最常见的文件下载)
builder.contentType(MediaType.APPLICATION_OCTET_STREAM);
filename = URLEncoder.encode(filename, "UTF-8");
if (isIEBrowser) {
builder.header("Content-Disposition", "attachment; filename=" + filename);
} else {
builder.header("Content-Disposition", "attacher; filename*=UTF-8''" + filename);
}
}
return builder.body(FileUtils.readFileToByteArray(file));
} catch (Exception e) {
log.error("file download error: {}", e);
return null;
}
}
/**
*
*
*
* @param entities
* @param operationEnum
* @throws BusinessException
*/
@Override
public void processBatchAfterOperation(List<GaeaFile> entities, BaseOperationEnum operationEnum) throws BusinessException {
if (operationEnum.equals(BaseOperationEnum.DELETE_BATCH)) {
// 删除本地文件
entities.forEach(gaeaFile -> {
String filePath = gaeaFile.getFilePath();
File file = new File(filePath);
if (file.exists()) {
file.delete();
}
});
}
}
}
Loading…
Cancel
Save