diff --git a/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/entity/DatetimeOnlyEntity.java b/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/base/entity/DatetimeOnlyEntity.java similarity index 93% rename from gringotts-web/src/main/java/com/eshore/gringotts/web/domain/entity/DatetimeOnlyEntity.java rename to gringotts-web/src/main/java/com/eshore/gringotts/web/domain/base/entity/DatetimeOnlyEntity.java index c6be58a..6582aa5 100644 --- a/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/entity/DatetimeOnlyEntity.java +++ b/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/base/entity/DatetimeOnlyEntity.java @@ -1,4 +1,4 @@ -package com.eshore.gringotts.web.domain.entity; +package com.eshore.gringotts.web.domain.base.entity; import java.time.LocalDateTime; import javax.persistence.EntityListeners; diff --git a/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/entity/IdOnlyEntity.java b/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/base/entity/IdOnlyEntity.java similarity index 62% rename from gringotts-web/src/main/java/com/eshore/gringotts/web/domain/entity/IdOnlyEntity.java rename to gringotts-web/src/main/java/com/eshore/gringotts/web/domain/base/entity/IdOnlyEntity.java index 81dec1a..be4d335 100644 --- a/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/entity/IdOnlyEntity.java +++ b/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/base/entity/IdOnlyEntity.java @@ -1,22 +1,13 @@ -package com.eshore.gringotts.web.domain.entity; +package com.eshore.gringotts.web.domain.base.entity; -import com.eshore.gringotts.web.domain.user.entity.User; -import java.time.LocalDateTime; -import javax.persistence.ConstraintMode; import javax.persistence.EntityListeners; -import javax.persistence.FetchType; -import javax.persistence.ForeignKey; import javax.persistence.GeneratedValue; import javax.persistence.Id; -import javax.persistence.JoinColumn; import javax.persistence.MappedSuperclass; -import javax.persistence.OneToOne; import lombok.Getter; import lombok.Setter; import lombok.ToString; import org.hibernate.annotations.GenericGenerator; -import org.springframework.data.annotation.CreatedDate; -import org.springframework.data.annotation.LastModifiedDate; import org.springframework.data.jpa.domain.support.AuditingEntityListener; /** diff --git a/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/entity/SimpleEntity.java b/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/base/entity/SimpleEntity.java similarity index 96% rename from gringotts-web/src/main/java/com/eshore/gringotts/web/domain/entity/SimpleEntity.java rename to gringotts-web/src/main/java/com/eshore/gringotts/web/domain/base/entity/SimpleEntity.java index 5bb6523..f65d80e 100644 --- a/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/entity/SimpleEntity.java +++ b/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/base/entity/SimpleEntity.java @@ -1,4 +1,4 @@ -package com.eshore.gringotts.web.domain.entity; +package com.eshore.gringotts.web.domain.base.entity; import com.eshore.gringotts.web.domain.user.entity.User; import java.time.LocalDateTime; diff --git a/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/base/service/SimpleService.java b/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/base/service/SimpleService.java new file mode 100644 index 0000000..dfa5bdd --- /dev/null +++ b/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/base/service/SimpleService.java @@ -0,0 +1,25 @@ +package com.eshore.gringotts.web.domain.base.service; + +import cn.hutool.core.util.ObjectUtil; +import com.eshore.gringotts.web.domain.base.repository.SimpleRepository; +import org.eclipse.collections.api.factory.Lists; +import org.eclipse.collections.api.list.ImmutableList; + +/** + * @author lanyuanxiaoyao + * @date 2024-11-21 + */ +public abstract class SimpleService { + protected abstract SimpleRepository repository(); + + public ImmutableList list() { + return Lists.immutable.ofAll(repository().findAll()); + } + + public E detail(ID id) { + if (ObjectUtil.isNull(id)) { + return null; + } + return repository().findById(id).orElse(null); + } +} diff --git a/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/resource/controller/DataResourceController.java b/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/resource/controller/DataResourceController.java index e8d5616..f8c6abf 100644 --- a/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/resource/controller/DataResourceController.java +++ b/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/resource/controller/DataResourceController.java @@ -1,6 +1,10 @@ package com.eshore.gringotts.web.domain.resource.controller; import cn.hutool.core.util.EnumUtil; +import cn.hutool.core.util.ObjectUtil; +import com.eshore.gringotts.web.configuration.amis.AmisListResponse; +import com.eshore.gringotts.web.configuration.amis.AmisResponse; +import com.eshore.gringotts.web.domain.resource.entity.DataResource; import com.eshore.gringotts.web.domain.resource.entity.format.CsvResourceFormat; import com.eshore.gringotts.web.domain.resource.entity.format.JsonLineResourceFormat; import com.eshore.gringotts.web.domain.resource.entity.format.JsonResourceFormat; @@ -14,13 +18,19 @@ import com.eshore.gringotts.web.domain.resource.entity.type.FtpResourceType; import com.eshore.gringotts.web.domain.resource.entity.type.HDFSResourceType; import com.eshore.gringotts.web.domain.resource.entity.type.ResourceType; import com.eshore.gringotts.web.domain.resource.service.DataResourceService; +import com.eshore.gringotts.web.domain.upload.entity.DataFile; +import com.eshore.gringotts.web.domain.upload.service.DataFileService; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; +import java.time.LocalDateTime; import java.util.Map; import lombok.Data; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; @@ -32,90 +42,199 @@ import org.springframework.web.bind.annotation.RestController; * @author lanyuanxiaoyao * @date 2024-11-20 */ +@Slf4j @RestController @RequestMapping("/data_resource") public class DataResourceController { - private static final Logger logger = LoggerFactory.getLogger(DataResourceController.class); - private final ObjectMapper mapper; private final DataResourceService dataResourceService; + private final DataFileService dataFileService; - public DataResourceController(Jackson2ObjectMapperBuilder builder, DataResourceService dataResourceService) { + public DataResourceController(Jackson2ObjectMapperBuilder builder, DataResourceService dataResourceService, DataFileService dataFileService) { this.mapper = builder.build(); this.dataResourceService = dataResourceService; + this.dataFileService = dataFileService; } @PostMapping("/create") public void create(@RequestBody CreateRequest request) throws JsonProcessingException { - logger.info("Create request: {}", request); + log.info("Create request: {}", request); ResourceType type = null; switch (request.resourceType) { - case "api": + case API: type = new ApiResourceType(request.apiUrl, request.apiUsername, request.apiPassword); break; - case "file": - type = new FileResourceType(request.filePath); + case FILE: + DataFile dataFile = dataFileService.detail(request.fileId); + log.info("{}", dataFile); + type = new FileResourceType(dataFile); break; - case "database": + case DATABASE: type = new DatabaseResourceType( request.databaseJdbc, request.databaseUsername, request.databasePassword, - EnumUtil.fromString(DatabaseResourceType.Type.class, request.databaseType) + EnumUtil.fromString(DatabaseResourceType.DatabaseType.class, request.databaseType) ); break; - case "hdfs": - type = new HDFSResourceType(request.coreSiteFile, request.hdfsSiteFile); + case HDFS: + type = new HDFSResourceType(dataFileService.detail(request.coreSiteFileId), dataFileService.detail(request.hdfsSiteFileId)); break; - case "ftp": + case FTP: type = new FtpResourceType(request.ftpUrl, request.ftpUsername, request.ftpPassword, request.ftpPath, request.ftpRegexFilter); break; } ResourceFormat format = null; switch (request.formatType) { - case "NONE": + case NONE: format = new NoneResourceFormat(); break; - case "LINE": + case LINE: format = new LineResourceFormat(); break; - case "JSON": + case JSON: format = new JsonResourceFormat(mapper.writeValueAsString(request.jsonSchema)); break; - case "JSON_LINE": + case JSON_LINE: format = new JsonLineResourceFormat(mapper.writeValueAsString(request.jsonLineSchema)); break; - case "CSV": + case CSV: format = new CsvResourceFormat(mapper.writeValueAsString(request.csvSchema)); break; } - dataResourceService.create(request.name, request.description, format, type); + dataResourceService.create(request.name, request.description, format, type, dataFileService.detail(request.exampleFileId)); + } + + @PostMapping("/list") + public AmisListResponse list() { + return AmisResponse.responseListData(dataResourceService.list().collect(DataResourceListItem::new)); + } + + @GetMapping("/detail/{id}") + public AmisResponse detail(@PathVariable Long id) throws JsonProcessingException { + return AmisResponse.responseSuccess(new DataResourceDetail(mapper, dataResourceService.detail(id))); } @Data - public static final class CreateRequest { + public static class CreateRequest { + protected String name; + protected String description; + protected ResourceType.Type resourceType; + protected String apiUrl; + protected String apiUsername; + protected String apiPassword; + protected String fileId; + protected String databaseType; + protected String databaseJdbc; + protected String databaseUsername; + protected String databasePassword; + protected String coreSiteFileId; + protected String hdfsSiteFileId; + protected String ftpUrl; + protected String ftpUsername; + protected String ftpPassword; + protected String ftpPath; + protected String ftpRegexFilter; + protected ResourceFormat.Type formatType; + protected Map jsonSchema; + protected Map jsonLineSchema; + protected Map csvSchema; + protected String exampleFileId; + } + + @Data + public static final class DataResourceListItem { + private Long id; private String name; private String description; - private String resourceType; - private String apiUrl; - private String apiUsername; - private String apiPassword; - private String filePath; - private String databaseType; - private String databaseJdbc; - private String databaseUsername; - private String databasePassword; - private String coreSiteFile; - private String hdfsSiteFile; - private String ftpUrl; - private String ftpUsername; - private String ftpPassword; - private String ftpPath; - private String ftpRegexFilter; - private String formatType; - private Map jsonSchema; - private Map jsonLineSchema; - private Map csvSchema; - private String example; + private String type; + private String format; + private String createdUser; + private LocalDateTime createdTime; + + public DataResourceListItem(DataResource dataResource) { + this.id = dataResource.getId(); + this.name = dataResource.getName(); + this.description = dataResource.getDescription(); + this.type = dataResource.getType().getResourceType().name(); + this.format = dataResource.getFormat().getFormatType().name(); + this.createdUser = dataResource.getCreatedUser().getUsername(); + this.createdTime = dataResource.getCreatedTime(); + } + } + + @Data + @EqualsAndHashCode(callSuper = true) + @NoArgsConstructor + public static final class DataResourceDetail extends CreateRequest { + private LocalDateTime createdTime; + private String createdUsername; + private LocalDateTime modifiedTime; + private String modifiedUsername; + + public DataResourceDetail(ObjectMapper mapper, DataResource dataResource) throws JsonProcessingException { + log.info("DataResourceDetail: {}", dataResource); + this.name = dataResource.getName(); + this.description = dataResource.getDescription(); + this.resourceType = dataResource.getType().getResourceType(); + switch (dataResource.getType().getResourceType()) { + case API: + ApiResourceType apiType = (ApiResourceType) dataResource.getType(); + this.apiUrl = apiType.getUrl(); + this.apiUsername = apiType.getUsername(); + this.apiPassword = apiType.getPassword(); + break; + case FILE: + FileResourceType fileType = (FileResourceType) dataResource.getType(); + this.fileId = fileType.getFile().getFilename(); + break; + case DATABASE: + DatabaseResourceType databaseType = (DatabaseResourceType) dataResource.getType(); + this.databaseType = databaseType.getDatabaseType().name(); + this.databaseJdbc = databaseType.getJdbc(); + this.databaseUsername = databaseType.getUsername(); + this.databasePassword = databaseType.getPassword(); + break; + case HDFS: + HDFSResourceType hdfsType = (HDFSResourceType) dataResource.getType(); + this.coreSiteFileId = hdfsType.getCoreSite().getFilename(); + this.hdfsSiteFileId = hdfsType.getHdfsSite().getFilename(); + break; + case FTP: + FtpResourceType ftpType = (FtpResourceType) dataResource.getType(); + this.ftpUrl = ftpType.getUrl(); + this.ftpUsername = ftpType.getUsername(); + this.ftpPassword = ftpType.getPassword(); + this.ftpPath = ftpType.getPath(); + this.ftpRegexFilter = ftpType.getRegexFilter(); + break; + } + this.formatType = dataResource.getFormat().getFormatType(); + switch (dataResource.getFormat().getFormatType()) { + case NONE: + case LINE: + break; + case JSON: + JsonResourceFormat jsonFormat = (JsonResourceFormat) dataResource.getFormat(); + this.jsonSchema = mapper.readValue(jsonFormat.getSchema(), Map.class); + break; + case JSON_LINE: + JsonLineResourceFormat jsonLineFormat = (JsonLineResourceFormat) dataResource.getFormat(); + this.jsonLineSchema = mapper.readValue(jsonLineFormat.getSchema(), Map.class); + break; + case CSV: + CsvResourceFormat csvFormat = (CsvResourceFormat) dataResource.getFormat(); + this.jsonLineSchema = mapper.readValue(csvFormat.getSchema(), Map.class); + break; + } + if (ObjectUtil.isNotNull(dataResource.getExample())) { + this.exampleFileId = dataResource.getExample().getFilename(); + } + + this.createdUsername = dataResource.getCreatedUser().getUsername(); + this.createdTime = dataResource.getCreatedTime(); + this.modifiedUsername = dataResource.getModifiedUser().getUsername(); + this.modifiedTime = dataResource.getModifiedTime(); + } } } diff --git a/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/resource/entity/DataResource.java b/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/resource/entity/DataResource.java index bdfcf23..7b6c68c 100644 --- a/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/resource/entity/DataResource.java +++ b/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/resource/entity/DataResource.java @@ -13,6 +13,8 @@ import javax.persistence.EntityListeners; import javax.persistence.FetchType; import javax.persistence.ForeignKey; import javax.persistence.JoinColumn; +import javax.persistence.NamedAttributeNode; +import javax.persistence.NamedEntityGraph; import javax.persistence.OneToOne; import javax.persistence.Table; import lombok.Getter; @@ -28,6 +30,18 @@ import org.springframework.data.jpa.domain.support.AuditingEntityListener; @EntityListeners(AuditingEntityListener.class) @DynamicUpdate @Table(name = Constants.TABLE_PREFIX + "data_resource") +@NamedEntityGraph(name = "data_resource.list", attributeNodes = { + @NamedAttributeNode(value = "type"), + @NamedAttributeNode(value = "format"), + @NamedAttributeNode(value = "createdUser"), +}) +@NamedEntityGraph(name = "data_resource.detail", attributeNodes = { + @NamedAttributeNode(value = "type"), + @NamedAttributeNode(value = "format"), + @NamedAttributeNode(value = "example"), + @NamedAttributeNode(value = "createdUser"), + @NamedAttributeNode(value = "modifiedUser"), +}) public class DataResource extends SimpleEntity { @Column(nullable = false) private String name; diff --git a/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/resource/entity/type/FileResourceType.java b/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/resource/entity/type/FileResourceType.java index 8a81afd..2cbfc1b 100644 --- a/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/resource/entity/type/FileResourceType.java +++ b/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/resource/entity/type/FileResourceType.java @@ -4,6 +4,11 @@ import com.eshore.gringotts.core.Constants; import com.eshore.gringotts.web.domain.upload.entity.DataFile; import javax.persistence.ConstraintMode; import javax.persistence.Entity; +import javax.persistence.ForeignKey; +import javax.persistence.JoinColumn; +import javax.persistence.NamedAttributeNode; +import javax.persistence.NamedEntityGraph; +import javax.persistence.OneToOne; import javax.persistence.Table; import lombok.AllArgsConstructor; import lombok.Getter; @@ -18,6 +23,9 @@ import lombok.ToString; @NoArgsConstructor @Entity @Table(name = Constants.TABLE_PREFIX + "resource_type_file") +@NamedEntityGraph(name = "file_resource_type.detail", attributeNodes = { + @NamedAttributeNode(value = "file") +}) public class FileResourceType extends ResourceType { @OneToOne @JoinColumn(nullable = false, foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT)) diff --git a/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/resource/entity/type/HDFSResourceType.java b/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/resource/entity/type/HDFSResourceType.java index ed76e73..51f77b2 100644 --- a/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/resource/entity/type/HDFSResourceType.java +++ b/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/resource/entity/type/HDFSResourceType.java @@ -4,6 +4,11 @@ import com.eshore.gringotts.core.Constants; import com.eshore.gringotts.web.domain.upload.entity.DataFile; import javax.persistence.ConstraintMode; import javax.persistence.Entity; +import javax.persistence.ForeignKey; +import javax.persistence.JoinColumn; +import javax.persistence.NamedAttributeNode; +import javax.persistence.NamedEntityGraph; +import javax.persistence.OneToOne; import javax.persistence.Table; import lombok.AllArgsConstructor; import lombok.Getter; @@ -18,6 +23,10 @@ import lombok.ToString; @NoArgsConstructor @Entity @Table(name = Constants.TABLE_PREFIX + "resource_type_hdfs") +@NamedEntityGraph(name = "hdfs_resource_type.detail", attributeNodes = { + @NamedAttributeNode(value = "coreSite"), + @NamedAttributeNode(value = "hdfsSite"), +}) public class HDFSResourceType extends ResourceType { @OneToOne @JoinColumn(nullable = false, foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT)) diff --git a/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/resource/repository/DataResourceRepository.java b/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/resource/repository/DataResourceRepository.java index 0e4707c..5f3132c 100644 --- a/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/resource/repository/DataResourceRepository.java +++ b/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/resource/repository/DataResourceRepository.java @@ -2,8 +2,19 @@ package com.eshore.gringotts.web.domain.resource.repository; import com.eshore.gringotts.web.domain.base.repository.SimpleRepository; import com.eshore.gringotts.web.domain.resource.entity.DataResource; +import java.util.List; +import java.util.Optional; +import org.springframework.data.jpa.repository.EntityGraph; import org.springframework.stereotype.Repository; +@SuppressWarnings("NullableProblems") @Repository public interface DataResourceRepository extends SimpleRepository { + @Override + @EntityGraph(value = "data_resource.list", type = EntityGraph.EntityGraphType.FETCH) + List findAll(); + + @Override + @EntityGraph(value = "data_resource.detail", type = EntityGraph.EntityGraphType.FETCH) + Optional findById(Long id); } diff --git a/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/resource/service/DataResourceService.java b/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/resource/service/DataResourceService.java index e68a384..7469c9d 100644 --- a/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/resource/service/DataResourceService.java +++ b/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/resource/service/DataResourceService.java @@ -1,16 +1,18 @@ package com.eshore.gringotts.web.domain.resource.service; +import com.eshore.gringotts.web.domain.base.repository.SimpleRepository; +import com.eshore.gringotts.web.domain.base.service.SimpleService; import com.eshore.gringotts.web.domain.resource.entity.DataResource; import com.eshore.gringotts.web.domain.resource.entity.format.ResourceFormat; import com.eshore.gringotts.web.domain.resource.entity.type.ResourceType; import com.eshore.gringotts.web.domain.resource.repository.DataResourceRepository; import com.eshore.gringotts.web.domain.resource.repository.ResourceFormatRepository; import com.eshore.gringotts.web.domain.resource.repository.ResourceTypeRepository; +import com.eshore.gringotts.web.domain.upload.entity.DataFile; import com.eshore.gringotts.web.domain.user.entity.User; import com.eshore.gringotts.web.domain.user.service.UserService; import javax.transaction.Transactional; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; /** @@ -18,10 +20,9 @@ import org.springframework.stereotype.Service; * * @author lanyuanxiaoyao */ +@Slf4j @Service -public class DataResourceService { - private static final Logger log = LoggerFactory.getLogger(DataResourceService.class); - +public class DataResourceService extends SimpleService { private final DataResourceRepository dataResourceRepository; private final ResourceTypeRepository resourceTypeRepository; private final ResourceFormatRepository resourceFormatRepository; @@ -34,15 +35,22 @@ public class DataResourceService { this.userService = userService; } + @Override + protected SimpleRepository repository() { + return dataResourceRepository; + } + @Transactional - public void create(String name, String description, ResourceFormat format, ResourceType type) { + public void create(String name, String description, ResourceFormat format, ResourceType type, DataFile example) { resourceFormatRepository.save(format); + log.info("{}", type); resourceTypeRepository.save(type); DataResource resource = new DataResource(); resource.setName(name); resource.setDescription(description); resource.setFormat(format); resource.setType(type); + resource.setExample(example); User user = userService.currentLoginUser(); resource.setCreatedUser(user); resource.setModifiedUser(user); diff --git a/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/upload/controller/UploadController.java b/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/upload/controller/UploadController.java index df12dbd..e245ca8 100644 --- a/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/upload/controller/UploadController.java +++ b/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/upload/controller/UploadController.java @@ -5,7 +5,7 @@ import cn.hutool.core.util.StrUtil; import cn.hutool.crypto.SecureUtil; import com.eshore.gringotts.web.configuration.UploadConfiguration; import com.eshore.gringotts.web.configuration.amis.AmisResponse; -import com.eshore.gringotts.web.domain.upload.service.UploadService; +import com.eshore.gringotts.web.domain.upload.service.DataFileService; import com.fasterxml.jackson.annotation.JsonProperty; import java.io.ByteArrayInputStream; import java.io.File; @@ -37,13 +37,13 @@ import org.springframework.web.multipart.MultipartFile; public class UploadController { private static final Logger logger = LoggerFactory.getLogger(UploadController.class); - private final UploadService uploadService; + private final DataFileService dataFileService; private final String uploadFolderPath; private final String cacheFolderPath; private final String sliceFolderPath; - public UploadController(UploadConfiguration uploadConfiguration, UploadService uploadService) { - this.uploadService = uploadService; + public UploadController(UploadConfiguration uploadConfiguration, DataFileService dataFileService) { + this.dataFileService = dataFileService; this.uploadFolderPath = uploadConfiguration.getUploadPath(); this.cacheFolderPath = StrUtil.format("{}/cache", uploadFolderPath); @@ -53,7 +53,7 @@ public class UploadController { @PostMapping("/start") public AmisResponse start(@RequestBody StartRequest request) { logger.info("Request: {}", request); - Long id = uploadService.initialDataFile(request.filename); + Long id = dataFileService.initialDataFile(request.filename); return AmisResponse.responseSuccess(new StartResponse(id.toString())); } @@ -68,7 +68,6 @@ public class UploadController { @RequestParam("file") MultipartFile file ) throws IOException { - logger.info("UploadId: {}, sequence: {}, size: {}, file: {}", uploadId, sequence, size, file.getName()); byte[] bytes = file.getBytes(); String md5 = SecureUtil.md5(new ByteArrayInputStream(bytes)); String targetFilename = StrUtil.format("{}-{}", sequence, md5); @@ -84,7 +83,6 @@ public class UploadController { @PostMapping("finish") public AmisResponse finish(@RequestBody FinishRequest request) { - logger.info("Request: {}", request); if (request.partList.anySatisfy(part -> !FileUtil.exist(sliceFilePath(request.uploadId, part.eTag)))) { throw new RuntimeException("文件校验失败,请重新上传"); } @@ -104,9 +102,12 @@ public class UploadController { } } } - File targetFile = new File(StrUtil.format("{}/{}", uploadFolderPath, request.uploadId)); - FileUtil.move(cacheFile, targetFile, true); - uploadService.updateDataFile(request.uploadId, FileUtil.getAbsolutePath(targetFile), FileUtil.size(targetFile), SecureUtil.md5(targetFile)); + String md5 = SecureUtil.md5(cacheFile); + File targetFile = new File(StrUtil.format("{}/{}", uploadFolderPath, md5)); + if (!targetFile.exists()) { + FileUtil.move(cacheFile, targetFile, true); + } + dataFileService.updateDataFile(request.uploadId, FileUtil.getAbsolutePath(targetFile), FileUtil.size(targetFile), SecureUtil.md5(targetFile)); return AmisResponse.responseSuccess(new FinishResponse(request.uploadId.toString())); } else { throw new RuntimeException("合并文件失败"); @@ -114,6 +115,7 @@ public class UploadController { } catch (Throwable throwable) { throw new RuntimeException(throwable); } finally { + FileUtil.del(StrUtil.format("{}/{}", cacheFolderPath, request.uploadId)); FileUtil.del(StrUtil.format("{}/{}", sliceFolderPath, request.uploadId)); } } diff --git a/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/upload/entity/DataFile.java b/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/upload/entity/DataFile.java index 7ef02e7..0b57815 100644 --- a/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/upload/entity/DataFile.java +++ b/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/upload/entity/DataFile.java @@ -1,6 +1,6 @@ package com.eshore.gringotts.web.domain.upload.entity; -import com.eshore.gringotts.web.domain.entity.SimpleEntity; +import com.eshore.gringotts.web.domain.base.entity.SimpleEntity; import javax.persistence.Entity; import lombok.Getter; import lombok.Setter; diff --git a/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/upload/service/UploadService.java b/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/upload/service/DataFileService.java similarity index 69% rename from gringotts-web/src/main/java/com/eshore/gringotts/web/domain/upload/service/UploadService.java rename to gringotts-web/src/main/java/com/eshore/gringotts/web/domain/upload/service/DataFileService.java index 9dc78bc..4f52db4 100644 --- a/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/upload/service/UploadService.java +++ b/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/upload/service/DataFileService.java @@ -1,5 +1,7 @@ package com.eshore.gringotts.web.domain.upload.service; +import com.eshore.gringotts.web.domain.base.repository.SimpleRepository; +import com.eshore.gringotts.web.domain.base.service.SimpleService; import com.eshore.gringotts.web.domain.upload.entity.DataFile; import com.eshore.gringotts.web.domain.upload.repository.DataFileRepository; import com.eshore.gringotts.web.domain.user.entity.User; @@ -15,17 +17,29 @@ import org.springframework.stereotype.Service; * @date 2024-11-21 */ @Service -public class UploadService { - private static final Logger logger = LoggerFactory.getLogger(UploadService.class); +public class DataFileService extends SimpleService { + private static final Logger logger = LoggerFactory.getLogger(DataFileService.class); private final DataFileRepository dataFileRepository; private final UserService userService; - public UploadService(DataFileRepository dataFileRepository, UserService userService) { + public DataFileService(DataFileRepository dataFileRepository, UserService userService) { this.dataFileRepository = dataFileRepository; this.userService = userService; } + @Override + protected SimpleRepository repository() { + return dataFileRepository; + } + + public DataFile detail(String id) { + if (id == null) { + return null; + } + return detail(Long.valueOf(id)); + } + public Long initialDataFile(String filename) { DataFile dataFile = new DataFile(); dataFile.setFilename(filename); @@ -45,6 +59,12 @@ public class UploadService { dataFileRepository.save(dataFile); } + public static final class DataFileNotFoundException extends RuntimeException { + public DataFileNotFoundException() { + super("文件未找到,请重新上传"); + } + } + public static final class UpdateDataFileFailedException extends RuntimeException { public UpdateDataFileFailedException() { super("更新文件信息失败,请重新上传"); diff --git a/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/user/entity/User.java b/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/user/entity/User.java index cf6f985..a8a5eb3 100644 --- a/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/user/entity/User.java +++ b/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/user/entity/User.java @@ -1,7 +1,7 @@ package com.eshore.gringotts.web.domain.user.entity; import com.eshore.gringotts.core.Constants; -import com.eshore.gringotts.web.domain.entity.SimpleEntity; +import com.eshore.gringotts.web.domain.base.entity.SimpleEntity; import java.time.LocalDateTime; import javax.persistence.Column; import javax.persistence.ConstraintMode; @@ -11,6 +11,8 @@ import javax.persistence.Enumerated; import javax.persistence.FetchType; import javax.persistence.ForeignKey; import javax.persistence.JoinColumn; +import javax.persistence.NamedAttributeNode; +import javax.persistence.NamedEntityGraph; import javax.persistence.OneToOne; import javax.persistence.Table; import lombok.Getter; @@ -30,6 +32,14 @@ import org.hibernate.annotations.DynamicUpdate; @Entity @DynamicUpdate @Table(name = Constants.TABLE_PREFIX + "user") +@NamedEntityGraph(name = "user.list", attributeNodes = { + @NamedAttributeNode(value = "createdUser"), +}) +@NamedEntityGraph(name = "user.detail", attributeNodes = { + @NamedAttributeNode(value = "createdUser"), + @NamedAttributeNode(value = "modifiedUser"), + @NamedAttributeNode(value = "checkedUser"), +}) public class User extends SimpleEntity { @Column(unique = true, nullable = false) private String username; diff --git a/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/user/repository/UserRepository.java b/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/user/repository/UserRepository.java index 59546c4..54659d0 100644 --- a/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/user/repository/UserRepository.java +++ b/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/user/repository/UserRepository.java @@ -1,14 +1,11 @@ package com.eshore.gringotts.web.domain.user.repository; -import com.blinkfox.fenix.jpa.FenixJpaRepository; -import com.blinkfox.fenix.specification.FenixJpaSpecificationExecutor; import com.eshore.gringotts.web.domain.base.repository.SimpleRepository; import com.eshore.gringotts.web.domain.user.entity.User; +import java.util.List; import java.util.Optional; -import org.springframework.data.jpa.repository.Modifying; -import org.springframework.data.jpa.repository.Query; +import org.springframework.data.jpa.repository.EntityGraph; import org.springframework.stereotype.Repository; -import org.springframework.transaction.annotation.Transactional; /** * User操作 @@ -16,8 +13,14 @@ import org.springframework.transaction.annotation.Transactional; * @author lanyuanxiaoyao * @date 2024-11-14 */ +@SuppressWarnings("NullableProblems") @Repository public interface UserRepository extends SimpleRepository { + @Override + @EntityGraph(value = "user.list", type = EntityGraph.EntityGraphType.FETCH) + List findAll(); + Boolean existsByUsername(String username); + @EntityGraph(value = "user.detail", type = EntityGraph.EntityGraphType.FETCH) Optional findByUsername(String username); }