diff --git a/pom.xml b/pom.xml
index e78337b..52e743f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -37,6 +37,11 @@
1.18.30
+
+ io.minio
+ minio
+ ${minio.version}
+
com.jayway.jsonpath
json-path
diff --git a/src/main/java/com/project/base/domain/dto/BaseDTO.java b/src/main/java/com/project/base/domain/dto/BaseDTO.java
index 8b9023d..044db63 100644
--- a/src/main/java/com/project/base/domain/dto/BaseDTO.java
+++ b/src/main/java/com/project/base/domain/dto/BaseDTO.java
@@ -2,6 +2,7 @@ package com.project.base.domain.dto;
import cn.hutool.core.bean.BeanUtil;
+import com.project.base.domain.enums.StatusEnum;
import lombok.Data;
import java.util.Date;
@@ -20,7 +21,7 @@ public class BaseDTO {
private Date updateTime;
- private Boolean deleted;
+ private Boolean deleted = StatusEnum.Normal.getValue();
public T toEntity(Supplier supplier) {
diff --git a/src/main/java/com/project/information/application/ProductLineApplicationService.java b/src/main/java/com/project/information/application/ProductLineApplicationService.java
new file mode 100644
index 0000000..3632dc3
--- /dev/null
+++ b/src/main/java/com/project/information/application/ProductLineApplicationService.java
@@ -0,0 +1,17 @@
+package com.project.information.application;
+
+import com.project.base.domain.result.Result;
+import com.project.information.domain.dto.ProductLineDTO;
+import com.project.information.domain.param.ProductLineParam;
+
+import java.util.List;
+
+public interface ProductLineApplicationService {
+ Result save(ProductLineDTO dto) throws Exception;
+
+ Result> treeList(ProductLineParam param) throws Exception;
+
+ Result rename(ProductLineDTO dto) throws Exception;
+
+ Result delete(Long id) throws Exception;
+}
diff --git a/src/main/java/com/project/information/application/impl/ProductLineApplicationServiceImpl.java b/src/main/java/com/project/information/application/impl/ProductLineApplicationServiceImpl.java
new file mode 100644
index 0000000..c64f1a9
--- /dev/null
+++ b/src/main/java/com/project/information/application/impl/ProductLineApplicationServiceImpl.java
@@ -0,0 +1,44 @@
+package com.project.information.application.impl;
+
+import com.project.base.domain.result.Result;
+import com.project.information.application.ProductLineApplicationService;
+import com.project.information.domain.dto.ProductLineDTO;
+import com.project.information.domain.param.ProductLineParam;
+import com.project.information.domain.service.GetTreeListProductLineDomainService;
+import com.project.information.domain.service.SaveProductLineDomainService;
+import com.project.information.domain.service.UpdateProductLineDomainService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+@Service
+public class ProductLineApplicationServiceImpl implements ProductLineApplicationService {
+ @Autowired
+ private SaveProductLineDomainService saveProductLineDomainService;
+
+ @Autowired
+ private GetTreeListProductLineDomainService treeListProductLineDomainService;
+
+ @Autowired
+ private UpdateProductLineDomainService updateProductLineDomainService;
+ @Override
+ public Result save(ProductLineDTO dto) throws Exception {
+ return saveProductLineDomainService.save(dto);
+ }
+
+ @Override
+ public Result> treeList(ProductLineParam param) throws Exception {
+ return treeListProductLineDomainService.treeList(param);
+ }
+
+ @Override
+ public Result rename(ProductLineDTO dto) throws Exception {
+ return updateProductLineDomainService.rename(dto);
+ }
+
+ @Override
+ public Result delete(Long id) throws Exception {
+ return updateProductLineDomainService.delete(id);
+ }
+}
diff --git a/src/main/java/com/project/information/config/CustomMinioClient.java b/src/main/java/com/project/information/config/CustomMinioClient.java
new file mode 100644
index 0000000..34478eb
--- /dev/null
+++ b/src/main/java/com/project/information/config/CustomMinioClient.java
@@ -0,0 +1,35 @@
+package com.project.information.config;
+import com.google.common.collect.Multimap;
+import io.minio.CreateMultipartUploadResponse;
+import io.minio.MinioClient;
+import io.minio.ObjectWriteResponse;
+import io.minio.ListPartsResponse;
+import io.minio.errors.*;
+import io.minio.messages.Part;
+
+import java.io.IOException;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+
+
+public class CustomMinioClient extends MinioClient {
+
+ public CustomMinioClient(MinioClient client) {
+ super(client);
+ }
+
+ public String initMultiPartUpload(String bucket, String region, String object, Multimap headers, Multimap extraQueryParams) throws IOException, InvalidKeyException, NoSuchAlgorithmException, InsufficientDataException, ServerException, InternalException, XmlParserException, InvalidResponseException, ErrorResponseException, ServerException, InsufficientDataException, ErrorResponseException, XmlParserException, InvalidResponseException {
+ CreateMultipartUploadResponse response = this.createMultipartUpload(bucket, region, object, headers, extraQueryParams);
+
+ return response.result().uploadId();
+ }
+
+ public ObjectWriteResponse mergeMultipartUpload(String bucketName, String region, String objectName, String uploadId, Part[] parts, Multimap extraHeaders, Multimap extraQueryParams) throws IOException, InvalidKeyException, NoSuchAlgorithmException, InsufficientDataException, ServerException, InternalException, XmlParserException, InvalidResponseException, ErrorResponseException {
+
+ return this.completeMultipartUpload(bucketName, region, objectName, uploadId, parts, extraHeaders, extraQueryParams);
+ }
+
+ public ListPartsResponse listMultipart(String bucketName, String region, String objectName, Integer maxParts, Integer partNumberMarker, String uploadId, Multimap extraHeaders, Multimap extraQueryParams) throws NoSuchAlgorithmException, InsufficientDataException, IOException, InvalidKeyException, ServerException, XmlParserException, ErrorResponseException, InternalException, InvalidResponseException {
+ return this.listParts(bucketName, region, objectName, maxParts, partNumberMarker, uploadId, extraHeaders, extraQueryParams);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/project/information/config/MinioProperties.java b/src/main/java/com/project/information/config/MinioProperties.java
new file mode 100644
index 0000000..d31e2dd
--- /dev/null
+++ b/src/main/java/com/project/information/config/MinioProperties.java
@@ -0,0 +1,24 @@
+package com.project.information.config;
+
+import lombok.Getter;
+import lombok.Setter;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+/**
+ * @Description: minio配置类
+ */
+@Component
+@ConfigurationProperties(prefix = "minio")
+@Getter
+@Setter
+public class MinioProperties {
+
+ private String endpoint;
+
+ private String accessKey;
+
+ private String secretKey;
+
+ private String bucket;
+}
\ No newline at end of file
diff --git a/src/main/java/com/project/information/controller/InformationController.java b/src/main/java/com/project/information/controller/InformationController.java
new file mode 100644
index 0000000..72b9066
--- /dev/null
+++ b/src/main/java/com/project/information/controller/InformationController.java
@@ -0,0 +1,13 @@
+package com.project.information.controller;
+
+
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@Slf4j
+@RequestMapping("/information")
+public class InformationController {
+
+}
diff --git a/src/main/java/com/project/information/controller/ProductLineController.java b/src/main/java/com/project/information/controller/ProductLineController.java
new file mode 100644
index 0000000..11f1426
--- /dev/null
+++ b/src/main/java/com/project/information/controller/ProductLineController.java
@@ -0,0 +1,45 @@
+package com.project.information.controller;
+
+
+import com.project.base.domain.result.Result;
+import com.project.information.application.ProductLineApplicationService;
+import com.project.information.domain.dto.ProductLineDTO;
+import com.project.information.domain.param.ProductLineParam;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+
+
+@RestController
+@Slf4j
+@RequestMapping("/productLine")
+public class ProductLineController {
+
+ @Autowired
+ private ProductLineApplicationService productLineApplicationService;
+
+ @PostMapping("/save")
+ public Result save(ProductLineDTO dto) throws Exception {
+ return productLineApplicationService.save(dto);
+ }
+
+ @GetMapping("/treeList")
+ public Result> treeList(ProductLineParam param) throws Exception {
+ return productLineApplicationService.treeList(param);
+ }
+
+ @PostMapping("/rename")
+ public Result rename(ProductLineDTO dto) throws Exception {
+ return productLineApplicationService.rename(dto);
+ }
+
+ @PostMapping("/delete")
+ public Result delete(Long id) throws Exception {
+ return productLineApplicationService.delete(id);
+ }
+}
diff --git a/src/main/java/com/project/information/domain/dto/FileDTO.java b/src/main/java/com/project/information/domain/dto/FileDTO.java
new file mode 100644
index 0000000..7069d6d
--- /dev/null
+++ b/src/main/java/com/project/information/domain/dto/FileDTO.java
@@ -0,0 +1,31 @@
+package com.project.information.domain.dto;
+
+import lombok.Data;
+
+@Data
+public class FileDTO {
+ /**
+ * 文件ID
+ */
+ private Long id;
+ /**
+ * 文件名
+ */
+ private String fileName;
+ /**
+ * 分片数量
+ */
+ private Integer partCount = 1;
+ /**
+ * minIO文件完整路径
+ */
+ private String objectName;
+ /**
+ * 单次传输Id
+ */
+ private String uploadId;
+ /**
+ * 子产品线id
+ */
+ private String subLineId;
+}
\ No newline at end of file
diff --git a/src/main/java/com/project/information/domain/dto/InformationDTO.java b/src/main/java/com/project/information/domain/dto/InformationDTO.java
index 9290fa8..ed98ea0 100644
--- a/src/main/java/com/project/information/domain/dto/InformationDTO.java
+++ b/src/main/java/com/project/information/domain/dto/InformationDTO.java
@@ -10,5 +10,8 @@ public class InformationDTO extends BaseDTO {
private String name;
private String filePath;
private Integer parseStatus;
+ private Integer partCount;
+ private String uploadId;
+
}
diff --git a/src/main/java/com/project/information/domain/dto/InitMultipartDTO.java b/src/main/java/com/project/information/domain/dto/InitMultipartDTO.java
new file mode 100644
index 0000000..f9fb8cc
--- /dev/null
+++ b/src/main/java/com/project/information/domain/dto/InitMultipartDTO.java
@@ -0,0 +1,16 @@
+package com.project.information.domain.dto;
+
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class InitMultipartDTO {
+ private String uploadId;
+
+ private List uploadUrls;
+
+ private String objectName;
+
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/project/information/domain/dto/ProductLineDTO.java b/src/main/java/com/project/information/domain/dto/ProductLineDTO.java
index a9acfd1..7de7023 100644
--- a/src/main/java/com/project/information/domain/dto/ProductLineDTO.java
+++ b/src/main/java/com/project/information/domain/dto/ProductLineDTO.java
@@ -1,14 +1,20 @@
package com.project.information.domain.dto;
+import com.project.base.domain.dto.BaseDTO;
import lombok.Data;
+import java.util.ArrayList;
+import java.util.List;
+
@Data
-public class ProductLineDTO {
+public class ProductLineDTO extends BaseDTO {
private String name;
- private Integer sort;
+ private Integer sort = 0;
private Boolean leaf;
private String business;
private Long parentId;
private String parentName;
+ private List childrenList = new ArrayList<>();
+
}
diff --git a/src/main/java/com/project/information/domain/dto/StreamInfoDTO.java b/src/main/java/com/project/information/domain/dto/StreamInfoDTO.java
new file mode 100644
index 0000000..8432e9c
--- /dev/null
+++ b/src/main/java/com/project/information/domain/dto/StreamInfoDTO.java
@@ -0,0 +1,21 @@
+package com.project.information.domain.dto;
+
+import java.io.InputStream;
+
+public class StreamInfoDTO {
+ private long size;
+ private InputStream stream;
+
+ public StreamInfoDTO(long size, InputStream stream) {
+ this.size = size;
+ this.stream = stream;
+ }
+
+ public long getSize() {
+ return size;
+ }
+
+ public InputStream getStream() {
+ return stream;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/project/information/domain/entity/InformationEntity.java b/src/main/java/com/project/information/domain/entity/InformationEntity.java
index bd8209a..2b348c5 100644
--- a/src/main/java/com/project/information/domain/entity/InformationEntity.java
+++ b/src/main/java/com/project/information/domain/entity/InformationEntity.java
@@ -29,6 +29,9 @@ public class InformationEntity extends BaseEntity {
@Column(name = "name" , columnDefinition="varchar(550) comment '文件名称'")
private String name;
+ @Column(name = "file_suffix" , columnDefinition="varchar(50) comment '文件后缀'")
+ @TableField("file_suffix")
+ private String fileSuffix;
@Column(name = "file_path" , columnDefinition="varchar(550) comment '文件存储路径'")
@TableField("file_path")
diff --git a/src/main/java/com/project/information/domain/param/ProductLineParam.java b/src/main/java/com/project/information/domain/param/ProductLineParam.java
index 1623fd2..1af30ac 100644
--- a/src/main/java/com/project/information/domain/param/ProductLineParam.java
+++ b/src/main/java/com/project/information/domain/param/ProductLineParam.java
@@ -5,4 +5,6 @@ import lombok.Data;
@Data
public class ProductLineParam extends BaseParam {
+ private String business;
+
}
diff --git a/src/main/java/com/project/information/domain/service/GetTreeListProductLineDomainService.java b/src/main/java/com/project/information/domain/service/GetTreeListProductLineDomainService.java
new file mode 100644
index 0000000..6dfbc2e
--- /dev/null
+++ b/src/main/java/com/project/information/domain/service/GetTreeListProductLineDomainService.java
@@ -0,0 +1,11 @@
+package com.project.information.domain.service;
+
+import com.project.base.domain.result.Result;
+import com.project.information.domain.dto.ProductLineDTO;
+import com.project.information.domain.param.ProductLineParam;
+
+import java.util.List;
+
+public interface GetTreeListProductLineDomainService {
+ Result> treeList(ProductLineParam param) throws Exception;
+}
diff --git a/src/main/java/com/project/information/domain/service/InformationBaseService.java b/src/main/java/com/project/information/domain/service/InformationBaseService.java
new file mode 100644
index 0000000..1c87f8a
--- /dev/null
+++ b/src/main/java/com/project/information/domain/service/InformationBaseService.java
@@ -0,0 +1,7 @@
+package com.project.information.domain.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.project.information.domain.entity.InformationEntity;
+
+public interface InformationBaseService extends IService {
+}
diff --git a/src/main/java/com/project/information/domain/service/ProductLineBaseService.java b/src/main/java/com/project/information/domain/service/ProductLineBaseService.java
new file mode 100644
index 0000000..b0d62ec
--- /dev/null
+++ b/src/main/java/com/project/information/domain/service/ProductLineBaseService.java
@@ -0,0 +1,7 @@
+package com.project.information.domain.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.project.information.domain.entity.ProductLineEntity;
+
+public interface ProductLineBaseService extends IService {
+}
diff --git a/src/main/java/com/project/information/domain/service/SaveProductLineDomainService.java b/src/main/java/com/project/information/domain/service/SaveProductLineDomainService.java
new file mode 100644
index 0000000..3cef714
--- /dev/null
+++ b/src/main/java/com/project/information/domain/service/SaveProductLineDomainService.java
@@ -0,0 +1,9 @@
+package com.project.information.domain.service;
+
+import com.project.base.domain.result.Result;
+import com.project.information.domain.dto.ProductLineDTO;
+
+public interface SaveProductLineDomainService {
+
+ Result save(ProductLineDTO dto) throws Exception;
+}
diff --git a/src/main/java/com/project/information/domain/service/UpdateProductLineDomainService.java b/src/main/java/com/project/information/domain/service/UpdateProductLineDomainService.java
new file mode 100644
index 0000000..de6eb7a
--- /dev/null
+++ b/src/main/java/com/project/information/domain/service/UpdateProductLineDomainService.java
@@ -0,0 +1,10 @@
+package com.project.information.domain.service;
+
+import com.project.base.domain.result.Result;
+import com.project.information.domain.dto.ProductLineDTO;
+
+public interface UpdateProductLineDomainService {
+ Result rename(ProductLineDTO dto) throws Exception;
+
+ Result delete(Long id) throws Exception;
+}
diff --git a/src/main/java/com/project/information/domain/service/UploadInformationDomainService.java b/src/main/java/com/project/information/domain/service/UploadInformationDomainService.java
new file mode 100644
index 0000000..4754cb7
--- /dev/null
+++ b/src/main/java/com/project/information/domain/service/UploadInformationDomainService.java
@@ -0,0 +1,11 @@
+package com.project.information.domain.service;
+
+import com.project.base.domain.result.Result;
+import com.project.information.domain.dto.FileDTO;
+import com.project.information.domain.dto.InformationDTO;
+import com.project.information.domain.dto.InitMultipartDTO;
+
+public interface UploadInformationDomainService {
+
+ Result initMultiPartUpload(InformationDTO dto) throws Exception;
+}
diff --git a/src/main/java/com/project/information/domain/service/UploadService.java b/src/main/java/com/project/information/domain/service/UploadService.java
new file mode 100644
index 0000000..d00e743
--- /dev/null
+++ b/src/main/java/com/project/information/domain/service/UploadService.java
@@ -0,0 +1,28 @@
+package com.project.information.domain.service;
+
+import com.project.information.domain.dto.StreamInfoDTO;
+
+import java.util.Map;
+
+public interface UploadService {
+
+ /**
+ * 分片上传初始化
+ *
+ * @param path 路径
+ * @param filename 文件名
+ * @param partCount 分片数量
+ * @param contentType /
+ * @return /
+ */
+ Map initMultiPartUpload(String path, String filename, Integer partCount, String contentType);
+
+ /**
+ * 完成分片上传
+ *
+ * @param objectName 文件名
+ * @param uploadId 标识
+ * @return /
+ */
+ StreamInfoDTO mergeMultipartUpload(String objectName, String uploadId);
+}
\ No newline at end of file
diff --git a/src/main/java/com/project/information/domain/service/impl/GetTreeListProductLineDomainServiceImpl.java b/src/main/java/com/project/information/domain/service/impl/GetTreeListProductLineDomainServiceImpl.java
new file mode 100644
index 0000000..b68d68e
--- /dev/null
+++ b/src/main/java/com/project/information/domain/service/impl/GetTreeListProductLineDomainServiceImpl.java
@@ -0,0 +1,37 @@
+package com.project.information.domain.service.impl;
+
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.project.base.domain.exception.BusinessErrorException;
+import com.project.base.domain.result.Result;
+import com.project.base.domain.utils.TreeUtils;
+import com.project.information.domain.dto.ProductLineDTO;
+import com.project.information.domain.entity.ProductLineEntity;
+import com.project.information.domain.param.ProductLineParam;
+import com.project.information.domain.service.GetTreeListProductLineDomainService;
+import com.project.information.domain.service.ProductLineBaseService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+@Service
+public class GetTreeListProductLineDomainServiceImpl implements GetTreeListProductLineDomainService {
+ @Autowired
+ private ProductLineBaseService productLineBaseService;
+ @Override
+ public Result> treeList(ProductLineParam param) throws Exception {
+ if (StrUtil.isBlank(param.getBusiness())) {
+ throw new BusinessErrorException("所属 BG 不能为空");
+ }
+ LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>();
+ queryWrapper.eq(ProductLineEntity::getBusiness , param.getBusiness());
+ List res = productLineBaseService.list(queryWrapper)
+ .stream().map(entity -> entity.toDTO(ProductLineDTO::new))
+ .collect(Collectors.toList());
+ return Result.success(TreeUtils.buildLongTree(res , ProductLineDTO::getId , ProductLineDTO::getParentId ,
+ ProductLineDTO::setChildrenList));
+
+ }
+}
diff --git a/src/main/java/com/project/information/domain/service/impl/InformationBaseServiceImpl.java b/src/main/java/com/project/information/domain/service/impl/InformationBaseServiceImpl.java
new file mode 100644
index 0000000..0edadb5
--- /dev/null
+++ b/src/main/java/com/project/information/domain/service/impl/InformationBaseServiceImpl.java
@@ -0,0 +1,11 @@
+package com.project.information.domain.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.project.information.domain.entity.InformationEntity;
+import com.project.information.domain.service.InformationBaseService;
+import com.project.information.mapper.InformationMapper;
+import org.springframework.stereotype.Service;
+
+@Service
+public class InformationBaseServiceImpl extends ServiceImpl implements InformationBaseService {
+}
diff --git a/src/main/java/com/project/information/domain/service/impl/ProductLineBaseServiceImpl.java b/src/main/java/com/project/information/domain/service/impl/ProductLineBaseServiceImpl.java
new file mode 100644
index 0000000..c3650e0
--- /dev/null
+++ b/src/main/java/com/project/information/domain/service/impl/ProductLineBaseServiceImpl.java
@@ -0,0 +1,12 @@
+package com.project.information.domain.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.project.information.domain.entity.ProductLineEntity;
+import com.project.information.domain.service.ProductLineBaseService;
+import com.project.information.mapper.ProductLineMapper;
+import org.springframework.stereotype.Service;
+
+
+@Service
+public class ProductLineBaseServiceImpl extends ServiceImpl implements ProductLineBaseService {
+}
diff --git a/src/main/java/com/project/information/domain/service/impl/SaveProductLineDomainServiceImpl.java b/src/main/java/com/project/information/domain/service/impl/SaveProductLineDomainServiceImpl.java
new file mode 100644
index 0000000..47c208f
--- /dev/null
+++ b/src/main/java/com/project/information/domain/service/impl/SaveProductLineDomainServiceImpl.java
@@ -0,0 +1,63 @@
+package com.project.information.domain.service.impl;
+
+import cn.hutool.core.util.BooleanUtil;
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.project.base.domain.exception.BusinessErrorException;
+import com.project.base.domain.result.Result;
+import com.project.information.domain.dto.ProductLineDTO;
+import com.project.information.domain.entity.ProductLineEntity;
+import com.project.information.domain.service.ProductLineBaseService;
+import com.project.information.domain.service.SaveProductLineDomainService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.Objects;
+
+@Service
+public class SaveProductLineDomainServiceImpl implements SaveProductLineDomainService {
+ @Autowired
+ private ProductLineBaseService productLineBaseService;
+ @Override
+ public Result save(ProductLineDTO dto) throws Exception {
+ // 校验
+ if (StrUtil.isBlank(dto.getBusiness())) {
+ throw new BusinessErrorException("所属 BG 不能为空");
+ }
+ if (Objects.isNull(dto.getLeaf())) {
+ throw new BusinessErrorException("产品线/子产品线类别不能为空");
+ }
+ if (BooleanUtil.isTrue(dto.getLeaf()) && Objects.isNull(dto.getParentId())) {
+ throw new BusinessErrorException("子产品线所属产品线id不能为空");
+ }
+ if (BooleanUtil.isTrue(dto.getLeaf()) && Objects.isNull(dto.getParentName())) {
+ throw new BusinessErrorException("子产品线所属产品线名称不能为空");
+ }
+
+ if (BooleanUtil.isTrue(dto.getLeaf())) {
+ ProductLineEntity parentProductLine = productLineBaseService.getById(dto.getParentId());
+ if (Objects.isNull(parentProductLine)) {
+ throw new BusinessErrorException("不存在的子产品线所属产品线id");
+ }
+
+ }
+ // 校验名称是否重复
+ LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>();
+ queryWrapper.eq(ProductLineEntity::getBusiness , dto.getBusiness());
+ queryWrapper.eq(ProductLineEntity::getLeaf , dto.getLeaf());
+ queryWrapper.eq(ProductLineEntity::getName , dto.getName());
+ ProductLineEntity existOne = productLineBaseService.getOne(queryWrapper);
+ if (Objects.nonNull(existOne)) {
+ if (BooleanUtil.isFalse(dto.getLeaf())) {
+ throw new BusinessErrorException("同一 BG 下产品线名称不能重复");
+ } else {
+ throw new BusinessErrorException("同一产品线下子产品线名称不能重复");
+ }
+ }
+ // 保存
+ ProductLineEntity entity = dto.toEntity(ProductLineEntity::new);
+ productLineBaseService.save(entity);
+
+ return Result.success(entity.toDTO(ProductLineDTO::new));
+ }
+}
diff --git a/src/main/java/com/project/information/domain/service/impl/UpdateProductLineDomainServiceImpl.java b/src/main/java/com/project/information/domain/service/impl/UpdateProductLineDomainServiceImpl.java
new file mode 100644
index 0000000..ff4248e
--- /dev/null
+++ b/src/main/java/com/project/information/domain/service/impl/UpdateProductLineDomainServiceImpl.java
@@ -0,0 +1,53 @@
+package com.project.information.domain.service.impl;
+
+import cn.hutool.core.util.BooleanUtil;
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.project.base.domain.exception.BusinessErrorException;
+import com.project.base.domain.result.Result;
+import com.project.information.domain.dto.ProductLineDTO;
+import com.project.information.domain.entity.ProductLineEntity;
+import com.project.information.domain.service.ProductLineBaseService;
+import com.project.information.domain.service.UpdateProductLineDomainService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.Objects;
+
+@Service
+public class UpdateProductLineDomainServiceImpl implements UpdateProductLineDomainService {
+ @Autowired
+ private ProductLineBaseService productLineBaseService;
+
+ @Override
+ public Result rename(ProductLineDTO dto) throws Exception {
+ if (Objects.isNull(dto.getId())) {
+ throw new BusinessErrorException("重命名id不能为空");
+ }
+ if (StrUtil.isBlank(dto.getName())) {
+ throw new BusinessErrorException("名称不能为空");
+ }
+ ProductLineEntity entity = productLineBaseService.getById(dto.getId());
+ LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>();
+ queryWrapper.eq(ProductLineEntity::getBusiness , entity.getBusiness());
+ queryWrapper.eq(ProductLineEntity::getLeaf , entity.getLeaf());
+ queryWrapper.eq(ProductLineEntity::getName , dto.getName());
+ ProductLineEntity existOne = productLineBaseService.getOne(queryWrapper);
+ if (Objects.nonNull(existOne)) {
+ if (BooleanUtil.isFalse(entity.getLeaf())) {
+ throw new BusinessErrorException("同一 BG 下产品线名称不能重复");
+ } else {
+ throw new BusinessErrorException("同一产品线下子产品线名称不能重复");
+ }
+ }
+ entity.setName(dto.getName());
+ productLineBaseService.updateById(entity);
+ return Result.success(entity.toDTO(ProductLineDTO::new));
+ }
+
+ @Override
+ public Result delete(Long id) throws Exception {
+ productLineBaseService.removeById(id);
+ return Result.success("删除成功");
+ }
+}
diff --git a/src/main/java/com/project/information/domain/service/impl/UploadInformationDomainServiceImpl.java b/src/main/java/com/project/information/domain/service/impl/UploadInformationDomainServiceImpl.java
new file mode 100644
index 0000000..f99172c
--- /dev/null
+++ b/src/main/java/com/project/information/domain/service/impl/UploadInformationDomainServiceImpl.java
@@ -0,0 +1,56 @@
+package com.project.information.domain.service.impl;
+
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.bean.copier.CopyOptions;
+import cn.hutool.core.util.RandomUtil;
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.project.base.domain.exception.MissingParameterException;
+import com.project.base.domain.result.Result;
+import com.project.base.domain.result.ResultCodeEnum;
+import com.project.information.domain.dto.FileDTO;
+import com.project.information.domain.dto.InformationDTO;
+import com.project.information.domain.dto.InitMultipartDTO;
+import com.project.information.domain.entity.InformationEntity;
+import com.project.information.domain.service.InformationBaseService;
+import com.project.information.domain.service.UploadInformationDomainService;
+import com.project.information.domain.service.UploadService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.Map;
+import java.util.Objects;
+
+
+@Service
+public class UploadInformationDomainServiceImpl implements UploadInformationDomainService {
+
+ @Autowired
+ private UploadService uploadService;
+
+ @Autowired
+ private InformationBaseService informationBaseService;
+
+
+
+ @Override
+ public Result initMultiPartUpload(InformationDTO dto) throws Exception {
+ if (StrUtil.isBlank(dto.getName()) || Objects.isNull(dto.getPartCount()) || Objects.isNull(dto.getSubLineId())) {
+ throw new MissingParameterException(ResultCodeEnum.MISSING_PARAMETER.getMessage());
+ }
+ String path = dto.getSubLineId().toString();
+
+ LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>();
+ queryWrapper.eq(InformationEntity::getSubLineId , dto.getSubLineId());
+ queryWrapper.eq(InformationEntity::getName , dto.getName());
+ InformationEntity existOne = informationBaseService.getOne(queryWrapper);
+ if (Objects.nonNull(existOne)) {
+
+ }
+
+ Map stringObjectMap = uploadService.initMultiPartUpload(path, dto.getName() , dto.getPartCount() , "application/octet-stream");
+ InitMultipartDTO initMultipartDTO = BeanUtil.mapToBean(stringObjectMap, InitMultipartDTO.class, true, CopyOptions.create());
+ initMultipartDTO.setObjectName(path + "/" + dto.getName());
+ return Result.success(initMultipartDTO);
+ }
+}
diff --git a/src/main/java/com/project/information/domain/service/impl/UploadServiceImpl.java b/src/main/java/com/project/information/domain/service/impl/UploadServiceImpl.java
new file mode 100644
index 0000000..85e641b
--- /dev/null
+++ b/src/main/java/com/project/information/domain/service/impl/UploadServiceImpl.java
@@ -0,0 +1,43 @@
+package com.project.information.domain.service.impl;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.project.information.domain.dto.StreamInfoDTO;
+import com.project.information.domain.service.UploadService;
+import com.project.information.utils.MinIoUtils;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+
+import java.util.Map;
+
+@Service
+@RequiredArgsConstructor
+public class UploadServiceImpl implements UploadService {
+
+ private final MinIoUtils minIoUtils;
+
+ @Override
+ public Map initMultiPartUpload(String path, String filename, Integer partCount, String contentType) {
+ path = path.replaceAll("/+", "/");
+ if (path.indexOf("/") == 0) {
+ path = path.substring(1);
+ }
+ String filePath = path + "/" + filename;
+
+ Map result;
+ // 单文件,直接上传
+ if (partCount == 1) {
+ String uploadObjectUrl = minIoUtils.getUploadObjectUrl(filePath);
+ result = ImmutableMap.of("uploadUrls", ImmutableList.of(uploadObjectUrl));
+ } else {//多文件,分片上传
+ result = minIoUtils.initMultiPartUpload(filePath, partCount, contentType);
+ }
+
+ return result;
+ }
+
+ @Override
+ public StreamInfoDTO mergeMultipartUpload(String objectName, String uploadId) {
+ return minIoUtils.mergeMultipartUpload(objectName, uploadId);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/project/information/utils/MinIoUtils.java b/src/main/java/com/project/information/utils/MinIoUtils.java
new file mode 100644
index 0000000..fa37d12
--- /dev/null
+++ b/src/main/java/com/project/information/utils/MinIoUtils.java
@@ -0,0 +1,127 @@
+package com.project.information.utils;
+
+import cn.hutool.core.util.StrUtil;
+import com.google.common.collect.HashMultimap;
+import com.project.information.config.CustomMinioClient;
+import com.project.information.config.MinioProperties;
+import com.project.information.domain.dto.StreamInfoDTO;
+import io.minio.GetObjectArgs;
+import io.minio.GetPresignedObjectUrlArgs;
+import io.minio.ListPartsResponse;
+import io.minio.MinioClient;
+import io.minio.http.Method;
+import io.minio.messages.Part;
+import jakarta.annotation.PostConstruct;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.stereotype.Component;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+@Slf4j
+@Configuration
+@EnableConfigurationProperties({MinioProperties.class})
+public class MinIoUtils {
+ private final MinioProperties minioProperties;
+ private CustomMinioClient customMinioClient;
+
+ public MinIoUtils(MinioProperties minioProperties) {
+ this.minioProperties = minioProperties;
+ }
+
+ @PostConstruct
+ public void init() {
+ MinioClient minioClient = MinioClient.builder()
+ .endpoint(minioProperties.getEndpoint())
+ .credentials(minioProperties.getAccessKey(), minioProperties.getSecretKey())
+ .build();
+ customMinioClient = new CustomMinioClient(minioClient);
+ }
+
+ public String getUploadObjectUrl(String objectName) {
+ try {
+ String url = customMinioClient.getPresignedObjectUrl(
+ GetPresignedObjectUrlArgs.builder()
+ .method(Method.PUT)
+ .bucket(minioProperties.getBucket())
+ .object(objectName)
+ .expiry(1, TimeUnit.HOURS)
+ //.extraHeaders(headers)
+ .build()
+ );
+
+
+ return url;
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ return null;
+ }
+ }
+
+ public Map initMultiPartUpload(String objectName, int partCount, String contentType) {
+ Map result = new HashMap<>();
+ try {
+ if (StrUtil.isBlank(contentType)) {
+ contentType = "application/octet-stream";
+ }
+ HashMultimap headers = HashMultimap.create();
+ headers.put("Content-Type", contentType);
+ String uploadId = customMinioClient.initMultiPartUpload(minioProperties.getBucket(), null, objectName, headers, null);
+
+ result.put("uploadId", uploadId);
+ List partList = new ArrayList<>();
+
+ Map reqParams = new HashMap<>();
+ //reqParams.put("response-content-type", "application/json");
+ reqParams.put("uploadId", uploadId);
+ for (int i = 1; i <= partCount; i++) {
+ reqParams.put("partNumber", String.valueOf(i));
+ String uploadUrl = customMinioClient.getPresignedObjectUrl(
+ GetPresignedObjectUrlArgs.builder()
+ .method(Method.PUT)
+ .bucket(minioProperties.getBucket())
+ .object(objectName)
+ .expiry(1, TimeUnit.HOURS)
+ .extraQueryParams(reqParams)
+ .build());
+ partList.add(uploadUrl);
+ }
+ result.put("uploadUrls", partList);
+ } catch (Exception e) {
+ e.printStackTrace();
+ return null;
+ }
+
+ return result;
+ }
+
+ public StreamInfoDTO mergeMultipartUpload(String objectName, String uploadId) {
+ try {
+ //单文件,不需要合并
+ if (StrUtil.isNotBlank(uploadId)) {
+ //TODO目前仅做了最大1000分片
+ Part[] parts = new Part[1000];
+ ListPartsResponse partResult = customMinioClient.listMultipart(minioProperties.getBucket(), null, objectName, 1000, 0, uploadId, null, null);
+ int partNumber = 1;
+ for (Part part : partResult.result().partList()) {
+ parts[partNumber - 1] = new Part(partNumber, part.etag());
+ partNumber++;
+ }
+ customMinioClient.mergeMultipartUpload(minioProperties.getBucket(), null, objectName, uploadId, parts, null, null);
+ }
+ return StreamUtils.getInputStreamSizeAndCopy(customMinioClient.getObject(GetObjectArgs.builder()
+ .bucket(minioProperties.getBucket())
+ .object(objectName).build()));
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ return null;
+ }
+ }
+}
diff --git a/src/main/java/com/project/information/utils/StreamUtils.java b/src/main/java/com/project/information/utils/StreamUtils.java
new file mode 100644
index 0000000..7771630
--- /dev/null
+++ b/src/main/java/com/project/information/utils/StreamUtils.java
@@ -0,0 +1,46 @@
+package com.project.information.utils;
+
+import com.project.information.domain.dto.StreamInfoDTO;
+
+import java.io.InputStream;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+
+
+
+public class StreamUtils {
+
+ /**
+ * 获取 InputStream 的大小,并返回一个可重复读取的新 InputStream。
+ * 这个方法会消耗原始的输入流。
+ *
+ * @param originalStream 原始的、一次性的输入流。
+ * @return 包含大小和新的、可重复读取的流的 StreamInfo 对象。
+ * @throws IOException 如果读取时发生错误。
+ */
+ public static StreamInfoDTO getInputStreamSizeAndCopy(InputStream originalStream) throws IOException {
+ if (originalStream == null) {
+ return new StreamInfoDTO(0, new ByteArrayInputStream(new byte[0]));
+ }
+
+ // 使用 ByteArrayOutputStream 作为内存中的缓冲区
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ byte[] buffer = new byte[4096];
+ int bytesRead;
+
+ // 将原始流的所有内容读取并写入到 ByteArrayOutputStream 中
+ while ((bytesRead = originalStream.read(buffer)) != -1) {
+ baos.write(buffer, 0, bytesRead);
+ }
+
+ // 现在 baos 中包含了流的全部内容
+ byte[] allBytes = baos.toByteArray();
+ long size = allBytes.length;
+
+ // 创建一个新的 ByteArrayInputStream,它可以被重复读取
+ InputStream newStream = new ByteArrayInputStream(allBytes);
+
+ return new StreamInfoDTO(size, newStream);
+ }
+}
\ No newline at end of file