package com.oying.modules.pc.product.service.impl; import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.bean.copier.CopyOptions; import cn.hutool.core.collection.CollectionUtil; import com.alibaba.fastjson2.JSON; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.oying.exception.BadRequestException; import com.oying.modules.pc.common.core.constrant.AuditStatusEnum; 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.*; import com.oying.modules.pc.product.domain.enums.ProductAuditTypeEnum; import com.oying.modules.pc.product.domain.enums.ProductCreationType; import com.oying.modules.pc.product.domain.enums.ProductStatusEnum; import com.oying.modules.pc.product.service.*; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.BeanUtils; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.List; import java.util.Set; @Slf4j @Service @RequiredArgsConstructor public class ProductMerchantServiceImpl implements ProductMerchantService { private final ProductService productService; private final ProductImageService productImageService; private final ProductLabelService productLabelService; private final ProductAuditService productAuditService; private final ProductCreationContext productCreationService; private final ProductMerchantImagesUpdateProcessor productMerchantImagesUpdateProcessor; private final ProductMerchantLabelUpdateProcessor productMerchantLabelUpdateProcessor; @Override @Transactional(rollbackFor = Exception.class) public void create(ProductMerchantCreateRequest request) { productCreationService.createProduct(request, ProductCreationType.DIRECT); } @Override @Transactional(rollbackFor = Exception.class) public void createWithAudit(ProductMerchantCreateRequest request) { productCreationService.createProduct(request, ProductCreationType.WITH_AUDIT); } @Override @Transactional(rollbackFor = Exception.class) public void submitToAudit(Long productId, ProductAuditTypeEnum productAuditType) { Product existingProduct = productService.getById(productId); if (!ProductStatusEnum.DRAFT.getValue().equals(existingProduct.getStatus())) { throw new BadRequestException("无法提交,该商品已提交审核或已上架"); } List productImages = productImageService.queryImagesByProductId(existingProduct.getProductId()); existingProduct.setImages(productImages); List productLabels = productLabelService.queryLabelsByProductId(existingProduct.getProductId()); existingProduct.setLabels(productLabels); ProductAudit audit = new ProductAudit(); audit.setProductId(existingProduct.getProductId()); audit.setType(productAuditType.name()); audit.setStatus(AuditStatusEnum.PENDING.getValue()); ProductAuditData auditData = new ProductAuditData(); auditData.setProduct(existingProduct); audit.setData(JSON.toJSONString(auditData)); productAuditService.create(audit); } @Override @Transactional(rollbackFor = Exception.class) public void update(ProductMerchantUpdateRequest request) { Product existingProduct = productService.getProduct(request.getProductId()); this.validateAuditStatus(existingProduct.getStatus()); productMerchantImagesUpdateProcessor.processImagesUpdate(request); productMerchantLabelUpdateProcessor.processLabelsUpdate(request); BeanUtils.copyProperties(request, existingProduct); existingProduct.setStatus(ProductStatusEnum.PENDING.getValue()); existingProduct.setShelfStatus(ProductStatusEnum.NO_AVAILABLE.getValue()); productService.update(existingProduct); ProductAudit audit = new ProductAudit(); audit.setProductId(existingProduct.getProductId()); audit.setType(ProductAuditTypeEnum.FULL_UPDATE.name()); audit.setStatus(AuditStatusEnum.PENDING.getValue()); ProductAuditData auditData = new ProductAuditData(); auditData.setOriginalProduct(existingProduct); Product newProduct = new Product(); BeanUtil.copyProperties(request, newProduct, CopyOptions.create().setIgnoreNullValue(true)); auditData.setProduct(existingProduct); ProductRevisionRecord revisionRecord = new ProductRevisionRecord(); BeanUtil.copyProperties(request, revisionRecord, CopyOptions.create().setIgnoreNullValue(true)); auditData.setRevisionRecord(revisionRecord); audit.setData(JSON.toJSONString(auditData)); productAuditService.create(audit); } @Override @Transactional(rollbackFor = Exception.class) public void updatePrice(ProductPriceUpdateRequest request) { Product existingProduct = productService.getProduct(request.getProductId()); existingProduct.setPrice(request.getPrice()); productService.update(existingProduct, true); } @Override @Transactional(rollbackFor = Exception.class) public void updateImages(ProductMerchantUpdateRequest request) { Product existingProduct = productService.getProduct(request.getProductId()); this.validateAuditStatus(existingProduct.getStatus()); productMerchantImagesUpdateProcessor.processImagesUpdate(request); ProductAudit audit = new ProductAudit(); audit.setProductId(existingProduct.getProductId()); audit.setType(ProductAuditTypeEnum.IMAGE_UPDATE.name()); audit.setStatus(AuditStatusEnum.PENDING.getValue()); ProductAuditData auditData = new ProductAuditData(); auditData.setOriginalProduct(existingProduct); Product newProduct = new Product(); BeanUtil.copyProperties(request, newProduct, CopyOptions.create().setIgnoreNullValue(true)); auditData.setProduct(existingProduct); ProductRevisionRecord revisionRecord = new ProductRevisionRecord(); BeanUtil.copyProperties(request, revisionRecord, CopyOptions.create().setIgnoreNullValue(true)); auditData.setRevisionRecord(revisionRecord); audit.setData(JSON.toJSONString(auditData)); productAuditService.create(audit); } @Override @Transactional(rollbackFor = Exception.class) public void updateLabels(ProductMerchantUpdateRequest request) { Product existingProduct = productService.getProduct(request.getProductId()); this.validateAuditStatus(existingProduct.getStatus()); productMerchantLabelUpdateProcessor.processLabelsUpdate(request); ProductAudit audit = new ProductAudit(); audit.setProductId(existingProduct.getProductId()); audit.setType(ProductAuditTypeEnum.LABEL_UPDATE.name()); audit.setStatus(AuditStatusEnum.PENDING.getValue()); ProductAuditData auditData = new ProductAuditData(); auditData.setOriginalProduct(existingProduct); Product newProduct = new Product(); BeanUtil.copyProperties(request, newProduct, CopyOptions.create().setIgnoreNullValue(true)); auditData.setProduct(existingProduct); ProductRevisionRecord revisionRecord = new ProductRevisionRecord(); BeanUtil.copyProperties(request, revisionRecord, CopyOptions.create().setIgnoreNullValue(true)); auditData.setRevisionRecord(revisionRecord); audit.setData(JSON.toJSONString(auditData)); productAuditService.create(audit); } @Transactional @Override public void batchDelete(List ids) { productService.deleteAll(ids); } @Override public void putOnShelf(Long productId) { Product existingProduct = productService.getById(productId); if (ProductStatusEnum.AVAILABLE.getValue().equals(existingProduct.getStatus())) { return; } if (!(ProductStatusEnum.APPROVED.getValue().equals(existingProduct.getStatus()) || ProductStatusEnum.NO_AVAILABLE.getValue().equals(existingProduct.getStatus()))) { throw new BadRequestException("无法上架,商品未审核"); } LambdaUpdateWrapper wrapper = new LambdaUpdateWrapper() .eq(Product::getProductId, productId) .set(Product::getStatus, ProductStatusEnum.AVAILABLE.getValue()) .set(Product::getShelfStatus, ProductStatusEnum.AVAILABLE.getValue()); productService.update(wrapper); } @Override public void takeOffShelf(Long productId) { Product existingProduct = productService.getById(productId); if (ProductStatusEnum.NO_AVAILABLE.getValue().equals(existingProduct.getShelfStatus())) { return; } if (!ProductStatusEnum.AVAILABLE.getValue().equals(existingProduct.getShelfStatus())) { return; } LambdaUpdateWrapper wrapper = new LambdaUpdateWrapper() .eq(Product::getProductId, productId) .set(Product::getStatus, ProductStatusEnum.NO_AVAILABLE.getValue()) .set(Product::getShelfStatus, ProductStatusEnum.NO_AVAILABLE.getValue()); productService.update(wrapper); } private void validateAuditStatus(Integer status) { Set statusEnumSet = CollectionUtil.newHashSet(ProductStatusEnum.PENDING, ProductStatusEnum.UNDER_REVIEW); ProductStatusEnum existingStatus = ProductStatusEnum.getOrDefault(status, ProductStatusEnum.DRAFT); if (statusEnumSet.contains(existingStatus)) { throw new BadRequestException("商品已在审核流程中无法修改"); } } }