31 changed files with 800 additions and 3 deletions
@ -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<ProductLineDTO> save(ProductLineDTO dto) throws Exception; |
||||
|
|
||||
|
Result<List<ProductLineDTO>> treeList(ProductLineParam param) throws Exception; |
||||
|
|
||||
|
Result<ProductLineDTO> rename(ProductLineDTO dto) throws Exception; |
||||
|
|
||||
|
Result<String> delete(Long id) throws Exception; |
||||
|
} |
||||
@ -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<ProductLineDTO> save(ProductLineDTO dto) throws Exception { |
||||
|
return saveProductLineDomainService.save(dto); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public Result<List<ProductLineDTO>> treeList(ProductLineParam param) throws Exception { |
||||
|
return treeListProductLineDomainService.treeList(param); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public Result<ProductLineDTO> rename(ProductLineDTO dto) throws Exception { |
||||
|
return updateProductLineDomainService.rename(dto); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public Result<String> delete(Long id) throws Exception { |
||||
|
return updateProductLineDomainService.delete(id); |
||||
|
} |
||||
|
} |
||||
@ -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<String, String> headers, Multimap<String, String> 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<String, String> extraHeaders, Multimap<String, String> 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<String, String> extraHeaders, Multimap<String, String> extraQueryParams) throws NoSuchAlgorithmException, InsufficientDataException, IOException, InvalidKeyException, ServerException, XmlParserException, ErrorResponseException, InternalException, InvalidResponseException { |
||||
|
return this.listParts(bucketName, region, objectName, maxParts, partNumberMarker, uploadId, extraHeaders, extraQueryParams); |
||||
|
} |
||||
|
} |
||||
@ -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; |
||||
|
} |
||||
@ -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 { |
||||
|
|
||||
|
} |
||||
@ -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<ProductLineDTO> save(ProductLineDTO dto) throws Exception { |
||||
|
return productLineApplicationService.save(dto); |
||||
|
} |
||||
|
|
||||
|
@GetMapping("/treeList") |
||||
|
public Result<List<ProductLineDTO>> treeList(ProductLineParam param) throws Exception { |
||||
|
return productLineApplicationService.treeList(param); |
||||
|
} |
||||
|
|
||||
|
@PostMapping("/rename") |
||||
|
public Result<ProductLineDTO> rename(ProductLineDTO dto) throws Exception { |
||||
|
return productLineApplicationService.rename(dto); |
||||
|
} |
||||
|
|
||||
|
@PostMapping("/delete") |
||||
|
public Result<String> delete(Long id) throws Exception { |
||||
|
return productLineApplicationService.delete(id); |
||||
|
} |
||||
|
} |
||||
@ -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; |
||||
|
} |
||||
@ -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<String> uploadUrls; |
||||
|
|
||||
|
private String objectName; |
||||
|
|
||||
|
|
||||
|
} |
||||
@ -1,14 +1,20 @@ |
|||||
package com.project.information.domain.dto; |
package com.project.information.domain.dto; |
||||
|
|
||||
|
import com.project.base.domain.dto.BaseDTO; |
||||
import lombok.Data; |
import lombok.Data; |
||||
|
|
||||
|
import java.util.ArrayList; |
||||
|
import java.util.List; |
||||
|
|
||||
@Data |
@Data |
||||
public class ProductLineDTO { |
public class ProductLineDTO extends BaseDTO { |
||||
private String name; |
private String name; |
||||
private Integer sort; |
private Integer sort = 0; |
||||
private Boolean leaf; |
private Boolean leaf; |
||||
private String business; |
private String business; |
||||
private Long parentId; |
private Long parentId; |
||||
private String parentName; |
private String parentName; |
||||
|
|
||||
|
private List<ProductLineDTO> childrenList = new ArrayList<>(); |
||||
|
|
||||
} |
} |
||||
|
|||||
@ -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; |
||||
|
} |
||||
|
} |
||||
@ -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<List<ProductLineDTO>> treeList(ProductLineParam param) throws Exception; |
||||
|
} |
||||
@ -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<InformationEntity> { |
||||
|
} |
||||
@ -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<ProductLineEntity> { |
||||
|
} |
||||
@ -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<ProductLineDTO> save(ProductLineDTO dto) throws Exception; |
||||
|
} |
||||
@ -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<ProductLineDTO> rename(ProductLineDTO dto) throws Exception; |
||||
|
|
||||
|
Result<String> delete(Long id) throws Exception; |
||||
|
} |
||||
@ -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<InitMultipartDTO> initMultiPartUpload(InformationDTO dto) throws Exception; |
||||
|
} |
||||
@ -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<String, Object> initMultiPartUpload(String path, String filename, Integer partCount, String contentType); |
||||
|
|
||||
|
/** |
||||
|
* 完成分片上传 |
||||
|
* |
||||
|
* @param objectName 文件名 |
||||
|
* @param uploadId 标识 |
||||
|
* @return / |
||||
|
*/ |
||||
|
StreamInfoDTO mergeMultipartUpload(String objectName, String uploadId); |
||||
|
} |
||||
@ -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<List<ProductLineDTO>> treeList(ProductLineParam param) throws Exception { |
||||
|
if (StrUtil.isBlank(param.getBusiness())) { |
||||
|
throw new BusinessErrorException("所属 BG 不能为空"); |
||||
|
} |
||||
|
LambdaQueryWrapper<ProductLineEntity> queryWrapper = new LambdaQueryWrapper<>(); |
||||
|
queryWrapper.eq(ProductLineEntity::getBusiness , param.getBusiness()); |
||||
|
List<ProductLineDTO> 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)); |
||||
|
|
||||
|
} |
||||
|
} |
||||
@ -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<InformationMapper, InformationEntity> implements InformationBaseService { |
||||
|
} |
||||
@ -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<ProductLineMapper, ProductLineEntity> implements ProductLineBaseService { |
||||
|
} |
||||
@ -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<ProductLineDTO> 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<ProductLineEntity> 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)); |
||||
|
} |
||||
|
} |
||||
@ -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<ProductLineDTO> 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<ProductLineEntity> 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<String> delete(Long id) throws Exception { |
||||
|
productLineBaseService.removeById(id); |
||||
|
return Result.success("删除成功"); |
||||
|
} |
||||
|
} |
||||
@ -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<InitMultipartDTO> 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<InformationEntity> 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<String, Object> 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); |
||||
|
} |
||||
|
} |
||||
@ -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<String, Object> 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<String, Object> 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); |
||||
|
} |
||||
|
} |
||||
@ -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<String, Object> initMultiPartUpload(String objectName, int partCount, String contentType) { |
||||
|
Map<String, Object> result = new HashMap<>(); |
||||
|
try { |
||||
|
if (StrUtil.isBlank(contentType)) { |
||||
|
contentType = "application/octet-stream"; |
||||
|
} |
||||
|
HashMultimap<String, String> headers = HashMultimap.create(); |
||||
|
headers.put("Content-Type", contentType); |
||||
|
String uploadId = customMinioClient.initMultiPartUpload(minioProperties.getBucket(), null, objectName, headers, null); |
||||
|
|
||||
|
result.put("uploadId", uploadId); |
||||
|
List<String> partList = new ArrayList<>(); |
||||
|
|
||||
|
Map<String, String> 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; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -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); |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue