Commit 459640a222dfd336e5211b6219c22e351d293767
1 parent
c5f29f18
revert: file
Showing
2 changed files
with
190 additions
and
0 deletions
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/FileController.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.infra.controller.admin.file; | |
| 2 | + | |
| 3 | +import cn.hutool.core.io.IoUtil; | |
| 4 | +import cn.hutool.core.util.StrUtil; | |
| 5 | +import cn.iocoder.yudao.framework.common.pojo.CommonResult; | |
| 6 | +import cn.iocoder.yudao.framework.common.pojo.PageResult; | |
| 7 | +import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils; | |
| 8 | +import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; | |
| 9 | +import cn.iocoder.yudao.module.infra.controller.admin.file.vo.file.FilePageReqVO; | |
| 10 | +import cn.iocoder.yudao.module.infra.controller.admin.file.vo.file.FileRespVO; | |
| 11 | +import cn.iocoder.yudao.module.infra.controller.admin.file.vo.file.FileUploadReqVO; | |
| 12 | +import cn.iocoder.yudao.module.infra.convert.file.FileConvert; | |
| 13 | +import cn.iocoder.yudao.module.infra.dal.dataobject.file.FileDO; | |
| 14 | +import cn.iocoder.yudao.module.infra.service.file.FileService; | |
| 15 | +import io.swagger.annotations.Api; | |
| 16 | +import io.swagger.annotations.ApiImplicitParam; | |
| 17 | +import io.swagger.annotations.ApiOperation; | |
| 18 | +import lombok.extern.slf4j.Slf4j; | |
| 19 | +import org.springframework.http.HttpStatus; | |
| 20 | +import org.springframework.security.access.prepost.PreAuthorize; | |
| 21 | +import org.springframework.validation.annotation.Validated; | |
| 22 | +import org.springframework.web.bind.annotation.*; | |
| 23 | +import org.springframework.web.multipart.MultipartFile; | |
| 24 | + | |
| 25 | +import javax.annotation.Resource; | |
| 26 | +import javax.annotation.security.PermitAll; | |
| 27 | +import javax.servlet.http.HttpServletRequest; | |
| 28 | +import javax.servlet.http.HttpServletResponse; | |
| 29 | +import javax.validation.Valid; | |
| 30 | + | |
| 31 | +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; | |
| 32 | + | |
| 33 | +@Api(tags = "管理后台 - 文件存储") | |
| 34 | +@RestController | |
| 35 | +@RequestMapping("/infra/file") | |
| 36 | +@Validated | |
| 37 | +@Slf4j | |
| 38 | +public class FileController { | |
| 39 | + | |
| 40 | + @Resource | |
| 41 | + private FileService fileService; | |
| 42 | + | |
| 43 | + @PostMapping("/upload") | |
| 44 | + @ApiOperation("上传文件") | |
| 45 | + @OperateLog(logArgs = false) // 上传文件,没有记录操作日志的必要 | |
| 46 | + public CommonResult<String> uploadFile(FileUploadReqVO uploadReqVO) throws Exception { | |
| 47 | + MultipartFile file = uploadReqVO.getFile(); | |
| 48 | + String path = uploadReqVO.getPath(); | |
| 49 | + return success(fileService.createFile(file.getOriginalFilename(), path, IoUtil.readBytes(file.getInputStream()))); | |
| 50 | + } | |
| 51 | + | |
| 52 | + @DeleteMapping("/delete") | |
| 53 | + @ApiOperation("删除文件") | |
| 54 | + @ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class) | |
| 55 | + @PreAuthorize("@ss.hasPermission('infra:file:delete')") | |
| 56 | + public CommonResult<Boolean> deleteFile(@RequestParam("id") Long id) throws Exception { | |
| 57 | + fileService.deleteFile(id); | |
| 58 | + return success(true); | |
| 59 | + } | |
| 60 | + | |
| 61 | + @GetMapping("/{configId}/get/**") | |
| 62 | + @PermitAll | |
| 63 | + @ApiOperation("下载文件") | |
| 64 | + @ApiImplicitParam(name = "configId", value = "配置编号", required = true, dataTypeClass = Long.class) | |
| 65 | + public void getFileContent(HttpServletRequest request, | |
| 66 | + HttpServletResponse response, | |
| 67 | + @PathVariable("configId") Long configId) throws Exception { | |
| 68 | + // 获取请求的路径 | |
| 69 | + String path = StrUtil.subAfter(request.getRequestURI(), "/get/", false); | |
| 70 | + if (StrUtil.isEmpty(path)) { | |
| 71 | + throw new IllegalArgumentException("结尾的 path 路径必须传递"); | |
| 72 | + } | |
| 73 | + | |
| 74 | + // 读取内容 | |
| 75 | + byte[] content = fileService.getFileContent(configId, path); | |
| 76 | + if (content == null) { | |
| 77 | + log.warn("[getFileContent][configId({}) path({}) 文件不存在]", configId, path); | |
| 78 | + response.setStatus(HttpStatus.NOT_FOUND.value()); | |
| 79 | + return; | |
| 80 | + } | |
| 81 | + ServletUtils.writeAttachment(response, path, content); | |
| 82 | + } | |
| 83 | + | |
| 84 | + @GetMapping("/page") | |
| 85 | + @ApiOperation("获得文件分页") | |
| 86 | + @PreAuthorize("@ss.hasPermission('infra:file:query')") | |
| 87 | + public CommonResult<PageResult<FileRespVO>> getFilePage(@Valid FilePageReqVO pageVO) { | |
| 88 | + PageResult<FileDO> pageResult = fileService.getFilePage(pageVO); | |
| 89 | + return success(FileConvert.INSTANCE.convertPage(pageResult)); | |
| 90 | + } | |
| 91 | + | |
| 92 | +} | ... | ... |
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/file/FileServiceImpl.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.infra.service.file; | |
| 2 | + | |
| 3 | +import cn.hutool.core.lang.Assert; | |
| 4 | +import cn.hutool.core.util.StrUtil; | |
| 5 | +import cn.iocoder.yudao.framework.common.pojo.PageResult; | |
| 6 | +import cn.iocoder.yudao.framework.common.util.io.FileUtils; | |
| 7 | +import cn.iocoder.yudao.framework.file.core.client.FileClient; | |
| 8 | +import cn.iocoder.yudao.framework.file.core.utils.FileTypeUtils; | |
| 9 | +import cn.iocoder.yudao.module.infra.controller.admin.file.vo.file.FilePageReqVO; | |
| 10 | +import cn.iocoder.yudao.module.infra.dal.dataobject.file.FileDO; | |
| 11 | +import cn.iocoder.yudao.module.infra.dal.mysql.file.FileMapper; | |
| 12 | +import lombok.SneakyThrows; | |
| 13 | +import org.springframework.stereotype.Service; | |
| 14 | + | |
| 15 | +import javax.annotation.Resource; | |
| 16 | + | |
| 17 | +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | |
| 18 | +import static cn.iocoder.yudao.module.infra.enums.ErrorCodeConstants.FILE_NOT_EXISTS; | |
| 19 | + | |
| 20 | +/** | |
| 21 | + * 文件 Service 实现类 | |
| 22 | + * | |
| 23 | + * @author 芋道源码 | |
| 24 | + */ | |
| 25 | +@Service | |
| 26 | +public class FileServiceImpl implements FileService { | |
| 27 | + | |
| 28 | + @Resource | |
| 29 | + private FileConfigService fileConfigService; | |
| 30 | + | |
| 31 | + @Resource | |
| 32 | + private FileMapper fileMapper; | |
| 33 | + | |
| 34 | + @Override | |
| 35 | + public PageResult<FileDO> getFilePage(FilePageReqVO pageReqVO) { | |
| 36 | + return fileMapper.selectPage(pageReqVO); | |
| 37 | + } | |
| 38 | + | |
| 39 | + @Override | |
| 40 | + @SneakyThrows | |
| 41 | + public String createFile(String name, String path, byte[] content) { | |
| 42 | + // 计算默认的 path 名 | |
| 43 | + String type = FileTypeUtils.getMineType(content, name); | |
| 44 | + if (StrUtil.isEmpty(path)) { | |
| 45 | + path = FileUtils.generatePath(content, name); | |
| 46 | + } | |
| 47 | + // 如果 name 为空,则使用 path 填充 | |
| 48 | + if (StrUtil.isEmpty(name)) { | |
| 49 | + name = path; | |
| 50 | + } | |
| 51 | + | |
| 52 | + // 上传到文件存储器 | |
| 53 | + FileClient client = fileConfigService.getMasterFileClient(); | |
| 54 | + Assert.notNull(client, "客户端(master) 不能为空"); | |
| 55 | + String url = client.upload(content, path, type); | |
| 56 | + | |
| 57 | + // 保存到数据库 | |
| 58 | + FileDO file = new FileDO(); | |
| 59 | + file.setConfigId(client.getId()); | |
| 60 | + file.setName(name); | |
| 61 | + file.setPath(path); | |
| 62 | + file.setUrl(url); | |
| 63 | + file.setType(type); | |
| 64 | + file.setSize(content.length); | |
| 65 | + fileMapper.insert(file); | |
| 66 | + return url; | |
| 67 | + } | |
| 68 | + | |
| 69 | + @Override | |
| 70 | + public void deleteFile(Long id) throws Exception { | |
| 71 | + // 校验存在 | |
| 72 | + FileDO file = this.validateFileExists(id); | |
| 73 | + | |
| 74 | + // 从文件存储器中删除 | |
| 75 | + FileClient client = fileConfigService.getFileClient(file.getConfigId()); | |
| 76 | + Assert.notNull(client, "客户端({}) 不能为空", file.getConfigId()); | |
| 77 | + client.delete(file.getPath()); | |
| 78 | + | |
| 79 | + // 删除记录 | |
| 80 | + fileMapper.deleteById(id); | |
| 81 | + } | |
| 82 | + | |
| 83 | + private FileDO validateFileExists(Long id) { | |
| 84 | + FileDO fileDO = fileMapper.selectById(id); | |
| 85 | + if (fileDO == null) { | |
| 86 | + throw exception(FILE_NOT_EXISTS); | |
| 87 | + } | |
| 88 | + return fileDO; | |
| 89 | + } | |
| 90 | + | |
| 91 | + @Override | |
| 92 | + public byte[] getFileContent(Long configId, String path) throws Exception { | |
| 93 | + FileClient client = fileConfigService.getFileClient(configId); | |
| 94 | + Assert.notNull(client, "客户端({}) 不能为空", configId); | |
| 95 | + return client.getContent(path); | |
| 96 | + } | |
| 97 | + | |
| 98 | +} | ... | ... |