package com.oying.modules.pc.product.service.impl;
|
|
import cn.hutool.core.collection.CollectionUtil;
|
import cn.hutool.core.util.ObjUtil;
|
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
import com.oying.exception.BadRequestException;
|
import com.oying.exception.EntityNotFoundException;
|
import com.oying.modules.pc.common.core.constrant.AuditStatusEnum;
|
import com.oying.modules.pc.product.converter.ProductImageAssembler;
|
import com.oying.modules.pc.product.converter.ProductLabelAssembler;
|
import com.oying.modules.pc.product.domain.Product;
|
import com.oying.modules.pc.product.domain.ProductAudit;
|
import com.oying.modules.pc.product.domain.ProductImage;
|
import com.oying.modules.pc.product.domain.ProductLabel;
|
import com.oying.modules.pc.product.domain.dto.ProductImageCreateRequest;
|
import com.oying.modules.pc.product.domain.dto.ProductMerchantCreateRequest;
|
import com.oying.modules.pc.product.domain.dto.ProductMerchantUpdateRequest;
|
import com.oying.modules.pc.product.domain.enums.ProductChangeTypeEnum;
|
import com.oying.modules.pc.product.domain.enums.ProductStatusEnum;
|
import com.oying.modules.pc.product.events.ProductAuditVerdictEvent;
|
import com.oying.modules.pc.product.service.*;
|
import com.oying.modules.pc.utils.ImageUtils;
|
import lombok.RequiredArgsConstructor;
|
import lombok.extern.slf4j.Slf4j;
|
import org.springframework.beans.BeanUtils;
|
import org.springframework.context.event.EventListener;
|
import org.springframework.stereotype.Service;
|
import org.springframework.transaction.annotation.Transactional;
|
|
import java.util.List;
|
import java.util.Optional;
|
import java.util.Set;
|
import java.util.stream.Collectors;
|
|
@Slf4j
|
@Service
|
@RequiredArgsConstructor
|
public class ProductMerchantServiceImpl implements ProductMerchantService {
|
|
private final ProductService productService;
|
private final ProductImageService productImageService;
|
private final ProductLabelService productLabelService;
|
private final ProductAuditService productAuditService;
|
|
@Override
|
@Transactional(rollbackFor = Exception.class)
|
public void create(ProductMerchantCreateRequest request) {
|
Product product = new Product();
|
BeanUtils.copyProperties(request, product);
|
request.getImages().stream().findFirst().map(ProductImageCreateRequest::getUploadFileId)
|
.ifPresent(id -> {
|
product.setMainImageId(id.toString());
|
product.setMainImageUrl(ImageUtils.getPublicObjectUrl(id));
|
});
|
product.setStatus(ProductStatusEnum.DRAFT.getValue());
|
productService.create(product);
|
|
List<ProductImage> productImages = request.getImages().stream().map(i -> {
|
i.setProductId(product.getProductId());
|
return ProductImageAssembler.to(i);
|
}).collect(Collectors.toList());
|
if (CollectionUtil.isNotEmpty(productImages)) {
|
productImageService.saveBatch(productImages);
|
}
|
|
List<ProductLabel> productLabels = request.getLabels().stream().map(i -> {
|
i.setProductId(product.getProductId());
|
return ProductLabelAssembler.to(i);
|
}).collect(Collectors.toList());
|
if (CollectionUtil.isNotEmpty(productLabels)) {
|
productLabelService.saveBatch(productLabels);
|
}
|
}
|
|
@Override
|
@Transactional(rollbackFor = Exception.class)
|
public void update(ProductMerchantUpdateRequest request) {
|
Product existingProduct = this.findOrThrow(request.getProductId());
|
this.validateApprovedStatus(existingProduct.getStatus());
|
this.processImagesUpdate(request);
|
this.processLabelsUpdate(request);
|
BeanUtils.copyProperties(request, existingProduct);
|
productService.update(existingProduct);
|
}
|
|
@Override
|
@Transactional(rollbackFor = Exception.class)
|
public void updateImages(ProductMerchantUpdateRequest request) {
|
Product existingProduct = this.findOrThrow(request.getProductId());
|
this.validateApprovedStatus(existingProduct.getStatus());
|
this.findOrThrow(request.getProductId());
|
this.processImagesUpdate(request);
|
}
|
|
@Override
|
@Transactional(rollbackFor = Exception.class)
|
public void updateLabels(ProductMerchantUpdateRequest request) {
|
Product existingProduct = this.findOrThrow(request.getProductId());
|
this.validateApprovedStatus(existingProduct.getStatus());
|
this.findOrThrow(request.getProductId());
|
this.processImagesUpdate(request);
|
}
|
|
@Transactional
|
@Override
|
public void batchDelete(List<Long> ids) {
|
productService.deleteAll(ids);
|
}
|
|
@Override
|
public void putOnShelf(Long productId) {
|
ProductAudit audit = new ProductAudit();
|
audit.setProductId(productId);
|
audit.setType(ProductChangeTypeEnum.PUT_ON_SHELF.name());
|
audit.setStatus(AuditStatusEnum.PENDING.getValue());
|
productAuditService.create(audit);
|
LambdaUpdateWrapper<Product> wrapper = new LambdaUpdateWrapper<Product>()
|
.eq(Product::getProductId, productId)
|
.set(Product::getStatus, ProductStatusEnum.PENDING.getValue());
|
productService.update(wrapper);
|
}
|
|
@Override
|
public void takeOffShelf(Long productId) {
|
LambdaUpdateWrapper<Product> wrapper = new LambdaUpdateWrapper<Product>()
|
.eq(Product::getProductId, productId)
|
.set(Product::getStatus, ProductStatusEnum.NO_AVAILABLE.getValue());
|
productService.update(wrapper);
|
}
|
|
@Override
|
@EventListener
|
@Transactional(rollbackFor = Exception.class)
|
public void handleAuditVerdictEvent(ProductAuditVerdictEvent event) {
|
try {
|
ProductAudit audit = productAuditService.getById(event.getAuditId());
|
ProductChangeTypeEnum changeType = ProductChangeTypeEnum.valueOf(audit.getType());
|
if (changeType == ProductChangeTypeEnum.PUT_ON_SHELF) {
|
this.handlePutOnShelfAuditEvent(audit);
|
}
|
} catch (Exception e) {
|
log.error("处理商品审核结果异常", e);
|
}
|
}
|
|
private Product findOrThrow(Long productId) {
|
Product existingProduct = productService.getById(productId);
|
if (ObjUtil.isEmpty(existingProduct)) {
|
throw new EntityNotFoundException(Product.class, "id", Optional.ofNullable(productId).map(Object::toString).orElse("null"));
|
}
|
return existingProduct;
|
}
|
|
private void processImagesUpdate(ProductMerchantUpdateRequest request) {
|
if (CollectionUtil.isNotEmpty(request.getDeletedImageIds())) {
|
productImageService.deleteAll(request.getDeletedImageIds());
|
}
|
if (CollectionUtil.isNotEmpty(request.getUpdatedImages())) {
|
productImageService.batchUpdate(request.getUpdatedImages());
|
}
|
if (CollectionUtil.isNotEmpty(request.getNewImages())) {
|
List<ProductImageCreateRequest> newImages = request.getNewImages().stream().peek(i-> i.setProductId(request.getProductId())).collect(Collectors.toList());
|
productImageService.batchCreate(newImages);
|
}
|
}
|
|
private void processLabelsUpdate(ProductMerchantUpdateRequest request) {
|
if (CollectionUtil.isNotEmpty(request.getDeletedLabelIds())) {
|
productLabelService.deleteAll(request.getDeletedLabelIds());
|
}
|
if (CollectionUtil.isNotEmpty(request.getUpdatedLabels())) {
|
productLabelService.batchUpdate(request.getUpdatedLabels());
|
}
|
if (CollectionUtil.isNotEmpty(request.getNewLabels())) {
|
List<ProductLabel> newLabels = request.getNewLabels().stream().peek(i-> i.setProductId(request.getProductId())).collect(Collectors.toList());
|
productLabelService.batchCreate(newLabels);
|
}
|
}
|
|
private void handlePutOnShelfAuditEvent(ProductAudit audit) {
|
AuditStatusEnum auditStatus = AuditStatusEnum.get(audit.getStatus());
|
if (AuditStatusEnum.APPROVED.equals(auditStatus)) {
|
Product existingProduct = productService.getById(audit.getProductId());
|
existingProduct.setStatus(auditStatus.getValue());
|
productService.updateById(existingProduct);
|
}
|
}
|
|
private void validateApprovedStatus(Integer status) {
|
Set<ProductStatusEnum> statusEnumSet = CollectionUtil.newHashSet(ProductStatusEnum.PENDING,
|
ProductStatusEnum.UNDER_REVIEW, ProductStatusEnum.AVAILABLE);
|
ProductStatusEnum existingStatus = ProductStatusEnum.getOrDefault(status, ProductStatusEnum.DRAFT);
|
if (statusEnumSet.contains(existingStatus)) {
|
throw new BadRequestException("在售商品无法修改");
|
}
|
}
|
}
|