完成 FileApi 的 feign 支持
This commit is contained in:
parent
4c6e915def
commit
9b3092b3fd
@ -1,23 +1,32 @@
|
|||||||
package cn.iocoder.yudao.module.infra.api.file;
|
package cn.iocoder.yudao.module.infra.api.file;
|
||||||
|
|
||||||
import cn.hutool.core.util.IdUtil;
|
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||||
|
import cn.iocoder.yudao.module.infra.api.file.dto.FileCreateReqDTO;
|
||||||
|
import cn.iocoder.yudao.module.infra.enums.ApiConstants;
|
||||||
|
import io.swagger.annotations.Api;
|
||||||
|
import io.swagger.annotations.ApiOperation;
|
||||||
|
import org.springframework.cloud.openfeign.FeignClient;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
|
||||||
/**
|
import javax.validation.Valid;
|
||||||
* 文件 API 接口
|
|
||||||
*
|
@FeignClient(name = ApiConstants.NAME) // TODO 芋艿:fallbackFactory =
|
||||||
* @author 芋道源码
|
@Api(tags = "RPC 服务 - 文件")
|
||||||
*/
|
|
||||||
public interface FileApi {
|
public interface FileApi {
|
||||||
|
|
||||||
|
String PREFIX = ApiConstants.PREFIX + "/file";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 保存文件,并返回文件的访问路径
|
* 保存文件,并返回文件的访问路径
|
||||||
*
|
*
|
||||||
* @param content 文件内容
|
* @param content 文件内容
|
||||||
* @return 文件路径
|
* @return 文件路径
|
||||||
*/
|
*/
|
||||||
default String createFile(byte[] content) throws Exception {
|
default String createFile(byte[] content) {
|
||||||
return createFile(IdUtil.fastUUID(), content);
|
return createFile(null, null, content);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 保存文件,并返回文件的访问路径
|
* 保存文件,并返回文件的访问路径
|
||||||
@ -26,6 +35,28 @@ public interface FileApi {
|
|||||||
* @param content 文件内容
|
* @param content 文件内容
|
||||||
* @return 文件路径
|
* @return 文件路径
|
||||||
*/
|
*/
|
||||||
String createFile(String path, byte[] content) throws Exception;
|
default String createFile(String path, byte[] content) {
|
||||||
|
return createFile(null, path, content);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 保存文件,并返回文件的访问路径
|
||||||
|
*
|
||||||
|
* @param name 原文件名称
|
||||||
|
* @param path 文件路径
|
||||||
|
* @param content 文件内容
|
||||||
|
* @return 文件路径
|
||||||
|
*/
|
||||||
|
default String createFile(@RequestParam("name") String name,
|
||||||
|
@RequestParam("path") String path,
|
||||||
|
@RequestParam("content") byte[] content) {
|
||||||
|
CommonResult<String> result = createFile(new FileCreateReqDTO().setName(name).setPath(path).setContent(content));
|
||||||
|
result.checkError();
|
||||||
|
return result.getData();
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping(PREFIX + "/create")
|
||||||
|
@ApiOperation("保存文件,并返回文件的访问路径")
|
||||||
|
CommonResult<String> createFile(@Valid @RequestBody FileCreateReqDTO createReqDTO);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,23 @@
|
|||||||
|
package cn.iocoder.yudao.module.infra.api.file.dto;
|
||||||
|
|
||||||
|
import io.swagger.annotations.ApiModel;
|
||||||
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotEmpty;
|
||||||
|
|
||||||
|
@ApiModel("RPC 服务 - 文件创建 Request DTO")
|
||||||
|
@Data
|
||||||
|
public class FileCreateReqDTO {
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "原文件名称", example = "xxx.png")
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "文件路径", example = "xxx.png")
|
||||||
|
private String path;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "文件内容", required = true)
|
||||||
|
@NotEmpty(message = "文件内容不能为空")
|
||||||
|
private byte[] content;
|
||||||
|
|
||||||
|
}
|
@ -7,7 +7,7 @@ import lombok.Data;
|
|||||||
import javax.validation.constraints.NotNull;
|
import javax.validation.constraints.NotNull;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
@ApiModel("API 错误日志创建 Request DTO")
|
@ApiModel("RPC 服务 - API 错误日志创建 Request DTO")
|
||||||
@Data
|
@Data
|
||||||
public class ApiErrorLogCreateReqDTO {
|
public class ApiErrorLogCreateReqDTO {
|
||||||
|
|
||||||
|
@ -1,17 +1,22 @@
|
|||||||
package cn.iocoder.yudao.module.infra.api.file;
|
package cn.iocoder.yudao.module.infra.api.file;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||||
|
import cn.iocoder.yudao.module.infra.api.file.dto.FileCreateReqDTO;
|
||||||
import cn.iocoder.yudao.module.infra.service.file.FileService;
|
import cn.iocoder.yudao.module.infra.service.file.FileService;
|
||||||
|
import org.apache.commons.fileupload.FileItem;
|
||||||
|
import org.apache.dubbo.config.annotation.DubboService;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
import org.springframework.web.multipart.commons.CommonsMultipartFile;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
|
|
||||||
/**
|
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||||
* 文件 API 实现类
|
import static cn.iocoder.yudao.module.system.enums.ApiConstants.VERSION;
|
||||||
*
|
|
||||||
* @author 芋道源码
|
@RestController // 提供 RESTful API 接口,给 Feign 调用
|
||||||
*/
|
@DubboService(version = VERSION) // 提供 Dubbo RPC 接口,给 Dubbo Consumer 调用
|
||||||
@Service
|
|
||||||
@Validated
|
@Validated
|
||||||
public class FileApiImpl implements FileApi {
|
public class FileApiImpl implements FileApi {
|
||||||
|
|
||||||
@ -19,8 +24,9 @@ public class FileApiImpl implements FileApi {
|
|||||||
private FileService fileService;
|
private FileService fileService;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String createFile(String path, byte[] content) throws Exception {
|
public CommonResult<String> createFile(FileCreateReqDTO createReqDTO) {
|
||||||
return fileService.createFile(path, content);
|
return success(fileService.createFile(createReqDTO.getName(), createReqDTO.getPath(),
|
||||||
|
createReqDTO.getContent()));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -46,7 +46,7 @@ public class FileController {
|
|||||||
@OperateLog(logArgs = false) // 上传文件,没有记录操作日志的必要
|
@OperateLog(logArgs = false) // 上传文件,没有记录操作日志的必要
|
||||||
public CommonResult<String> uploadFile(@RequestParam("file") MultipartFile file,
|
public CommonResult<String> uploadFile(@RequestParam("file") MultipartFile file,
|
||||||
@RequestParam(value = "path", required = false) String path) throws Exception {
|
@RequestParam(value = "path", required = false) String path) throws Exception {
|
||||||
return success(fileService.createFile(path, IoUtil.readBytes(file.getInputStream())));
|
return success(fileService.createFile(file.getOriginalFilename(), path, IoUtil.readBytes(file.getInputStream())));
|
||||||
}
|
}
|
||||||
|
|
||||||
@DeleteMapping("/delete")
|
@DeleteMapping("/delete")
|
||||||
|
@ -33,6 +33,10 @@ public class FileDO extends BaseDO {
|
|||||||
* 关联 {@link FileConfigDO#getId()}
|
* 关联 {@link FileConfigDO#getId()}
|
||||||
*/
|
*/
|
||||||
private Long configId;
|
private Long configId;
|
||||||
|
/**
|
||||||
|
* 原文件名
|
||||||
|
*/
|
||||||
|
private String name;
|
||||||
/**
|
/**
|
||||||
* 路径,即文件名
|
* 路径,即文件名
|
||||||
*/
|
*/
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package cn.iocoder.yudao.module.infra.service.file;
|
package cn.iocoder.yudao.module.infra.service.file;
|
||||||
|
|
||||||
import cn.iocoder.yudao.module.infra.controller.admin.file.vo.file.FilePageReqVO;
|
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
|
import cn.iocoder.yudao.module.infra.controller.admin.file.vo.file.FilePageReqVO;
|
||||||
import cn.iocoder.yudao.module.infra.dal.dataobject.file.FileDO;
|
import cn.iocoder.yudao.module.infra.dal.dataobject.file.FileDO;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -22,11 +22,12 @@ public interface FileService {
|
|||||||
/**
|
/**
|
||||||
* 保存文件,并返回文件的访问路径
|
* 保存文件,并返回文件的访问路径
|
||||||
*
|
*
|
||||||
|
* @param name 原文件名称
|
||||||
* @param path 文件路径
|
* @param path 文件路径
|
||||||
* @param content 文件内容
|
* @param content 文件内容
|
||||||
* @return 文件路径
|
* @return 文件路径
|
||||||
*/
|
*/
|
||||||
String createFile(String path, byte[] content) throws Exception;
|
String createFile(String name, String path, byte[] content);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 删除文件
|
* 删除文件
|
||||||
|
@ -9,6 +9,7 @@ import cn.iocoder.yudao.framework.file.core.client.FileClient;
|
|||||||
import cn.iocoder.yudao.module.infra.controller.admin.file.vo.file.FilePageReqVO;
|
import cn.iocoder.yudao.module.infra.controller.admin.file.vo.file.FilePageReqVO;
|
||||||
import cn.iocoder.yudao.module.infra.dal.dataobject.file.FileDO;
|
import cn.iocoder.yudao.module.infra.dal.dataobject.file.FileDO;
|
||||||
import cn.iocoder.yudao.module.infra.dal.mysql.file.FileMapper;
|
import cn.iocoder.yudao.module.infra.dal.mysql.file.FileMapper;
|
||||||
|
import lombok.SneakyThrows;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
@ -37,12 +38,17 @@ public class FileServiceImpl implements FileService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String createFile(String path, byte[] content) throws Exception {
|
@SneakyThrows
|
||||||
|
public String createFile(String name, String path, byte[] content) {
|
||||||
// 计算默认的 path 名
|
// 计算默认的 path 名
|
||||||
String type = FileTypeUtil.getType(new ByteArrayInputStream(content), path);
|
String type = FileTypeUtil.getType(new ByteArrayInputStream(content), name);
|
||||||
if (StrUtil.isEmpty(path)) {
|
if (StrUtil.isEmpty(path)) {
|
||||||
path = DigestUtil.md5Hex(content) + '.' + type;
|
path = DigestUtil.md5Hex(content) + '.' + type;
|
||||||
}
|
}
|
||||||
|
// 如果 name 为空,则使用 path 填充
|
||||||
|
if (StrUtil.isEmpty(name)) {
|
||||||
|
name = path;
|
||||||
|
}
|
||||||
|
|
||||||
// 上传到文件存储器
|
// 上传到文件存储器
|
||||||
FileClient client = fileConfigService.getMasterFileClient();
|
FileClient client = fileConfigService.getMasterFileClient();
|
||||||
@ -52,6 +58,7 @@ public class FileServiceImpl implements FileService {
|
|||||||
// 保存到数据库
|
// 保存到数据库
|
||||||
FileDO file = new FileDO();
|
FileDO file = new FileDO();
|
||||||
file.setConfigId(client.getId());
|
file.setConfigId(client.getId());
|
||||||
|
file.setName(name);
|
||||||
file.setPath(path);
|
file.setPath(path);
|
||||||
file.setUrl(url);
|
file.setUrl(url);
|
||||||
file.setType(type);
|
file.setType(type);
|
||||||
|
@ -80,9 +80,9 @@ public class FileServiceTest extends BaseDbUnitTest {
|
|||||||
String url = randomString();
|
String url = randomString();
|
||||||
when(client.upload(same(content), same(path))).thenReturn(url);
|
when(client.upload(same(content), same(path))).thenReturn(url);
|
||||||
when(client.getId()).thenReturn(10L);
|
when(client.getId()).thenReturn(10L);
|
||||||
|
String name = "单测文件名";
|
||||||
// 调用
|
// 调用
|
||||||
String result = fileService.createFile(path, content);
|
String result = fileService.createFile(name, path, content);
|
||||||
// 断言
|
// 断言
|
||||||
assertEquals(result, url);
|
assertEquals(result, url);
|
||||||
// 校验数据
|
// 校验数据
|
||||||
|
@ -9,7 +9,7 @@ import javax.validation.constraints.NotNull;
|
|||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@ApiModel("操作日志创建 Request DTO")
|
@ApiModel("RPC 服务 - 操作日志创建 Request DTO")
|
||||||
@Data
|
@Data
|
||||||
public class OperateLogCreateReqDTO {
|
public class OperateLogCreateReqDTO {
|
||||||
|
|
||||||
|
@ -1,44 +0,0 @@
|
|||||||
package cn.iocoder.yudao.module.system.framework;
|
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.apilog.core.service.ApiAccessLog;
|
|
||||||
import cn.iocoder.yudao.framework.apilog.core.service.ApiAccessLogFrameworkService;
|
|
||||||
import cn.iocoder.yudao.framework.apilog.core.service.ApiErrorLog;
|
|
||||||
import cn.iocoder.yudao.framework.apilog.core.service.ApiErrorLogFrameworkService;
|
|
||||||
import cn.iocoder.yudao.module.infra.api.file.FileApi;
|
|
||||||
import org.springframework.context.annotation.Bean;
|
|
||||||
import org.springframework.context.annotation.Configuration;
|
|
||||||
|
|
||||||
@Configuration
|
|
||||||
public class TmpConfiguration {
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public FileApi fileApi() {
|
|
||||||
return new FileApi() {
|
|
||||||
@Override
|
|
||||||
public String createFile(String path, byte[] content) throws Exception {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public ApiAccessLogFrameworkService apiAccessLogFrameworkService() {
|
|
||||||
return new ApiAccessLogFrameworkService() {
|
|
||||||
@Override
|
|
||||||
public void createApiAccessLog(ApiAccessLog apiAccessLog) {
|
|
||||||
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public ApiErrorLogFrameworkService apiErrorLogFrameworkService() {
|
|
||||||
return new ApiErrorLogFrameworkService() {
|
|
||||||
@Override
|
|
||||||
public void createApiErrorLog(ApiErrorLog apiErrorLog) {
|
|
||||||
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -0,0 +1,11 @@
|
|||||||
|
package cn.iocoder.yudao.module.system.framework.rpc.config;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.module.infra.api.file.FileApi;
|
||||||
|
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
|
||||||
|
import org.springframework.cloud.openfeign.EnableFeignClients;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
@Configuration(proxyBeanMethods = false)
|
||||||
|
@EnableFeignClients(clients = FileApi.class)
|
||||||
|
public class RpcConfiguration {
|
||||||
|
}
|
@ -0,0 +1,4 @@
|
|||||||
|
/**
|
||||||
|
* 占位
|
||||||
|
*/
|
||||||
|
package cn.iocoder.yudao.module.system.framework.rpc;
|
Loading…
Reference in New Issue
Block a user