From a1416117c7478a66971cca278e9909811e0000d5 Mon Sep 17 00:00:00 2001
From: cloudroam <cloudroam>
Date: 星期五, 20 九月 2024 17:07:14 +0800
Subject: [PATCH] fix:商品限购

---
 src/main/java/com/mzl/flower/service/flower/FlowerService.java |  271 ++++++++++++++++++++++++++++++++++++++++++++++++-----
 1 files changed, 242 insertions(+), 29 deletions(-)

diff --git a/src/main/java/com/mzl/flower/service/flower/FlowerService.java b/src/main/java/com/mzl/flower/service/flower/FlowerService.java
index 934ef42..9cc9169 100644
--- a/src/main/java/com/mzl/flower/service/flower/FlowerService.java
+++ b/src/main/java/com/mzl/flower/service/flower/FlowerService.java
@@ -6,11 +6,12 @@
 import com.mzl.flower.config.security.SecurityUtils;
 import com.mzl.flower.constant.Constants;
 import com.mzl.flower.dto.request.flower.*;
-import com.mzl.flower.dto.request.flower.FlowerTagMultipleDTO;
 import com.mzl.flower.dto.response.flower.*;
+import com.mzl.flower.entity.FlowerDeleteDO;
 import com.mzl.flower.entity.customer.Collect;
 import com.mzl.flower.entity.customer.Customer;
 import com.mzl.flower.entity.flower.*;
+import com.mzl.flower.entity.menber.Member;
 import com.mzl.flower.entity.payment.Cart;
 import com.mzl.flower.entity.payment.Order;
 import com.mzl.flower.entity.payment.OrderItem;
@@ -25,6 +26,7 @@
 import com.mzl.flower.mapper.supplier.SupplierTypeMapper;
 import com.mzl.flower.service.BaseService;
 import com.mzl.flower.service.customer.BrowseService;
+import com.mzl.flower.service.payment.RedisLockService;
 import io.micrometer.core.instrument.util.StringUtils;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.BeanUtils;
@@ -32,14 +34,15 @@
 import org.springframework.scheduling.annotation.Async;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.CollectionUtils;
 
 import java.math.BigDecimal;
 import java.math.RoundingMode;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.stream.Collectors;
 
 @Slf4j
 @Service
@@ -82,6 +85,14 @@
     @Autowired
     private OrderItemMapper orderItemMapper;
 
+    @Autowired
+    private RedisLockService lockService;
+
+    @Autowired
+    private FlowerDeleteService flowerDeleteService;
+
+    private static final String FLOWER_KEY="com:mzl:flower:service:flower:%s:%s";
+
     @Async
     public synchronized void updateFlowerSales(Order order){
         List<OrderItem> items = orderItemMapper.selectList(new QueryWrapper<OrderItem>()
@@ -92,6 +103,70 @@
             }
         }
     }
+
+    @Async
+    public synchronized void updateCategoryInfo(Long category){
+        flowerMapper.updateFlowerCategoryInfo(category);
+    }
+
+    @Async
+    public  void updateFlowTypeRank(Long id,Long category,String level){
+
+        Flower flower =null;
+        // 如果 id 不为空,则 category 和 level 可以为空
+        if (Objects.nonNull(id)) {
+            flower = flowerMapper.selectById(id);
+            if (flower == null) {
+                throw new IllegalArgumentException("Flower not found for ID: " + id);
+            }
+            category = flower.getCategory();  // 使用从数据库中检索到的 category
+            level = flower.getLevel();        // 使用从数据库中检索到的 level
+        } else {
+            // 如果 id 为空,则 category 和 level 必须提供
+            if (Objects.isNull(category) || StringUtils.isEmpty(level)) {
+                throw new IllegalArgumentException("Category and level must be provided when ID is null");
+            }
+            flower=new Flower();
+            flower.setCategory(category);
+            flower.setLevel(level);
+        }
+
+        String key=String.format(FLOWER_KEY, flower.getCategory(),flower.getLevel());
+
+        boolean lock = lockService.getObjectLock(key, "");
+        if(!lock){
+            return;
+        }
+        try{
+
+            flowerMapper.updateTypeRankNull(flower.getCategory(),flower.getLevel());
+
+            QueryWrapper<Flower> queryWrapper=new QueryWrapper<>();
+            queryWrapper.lambda().eq(Flower::getDeleted,false)
+                    .eq(Objects.nonNull(flower.getCategory()),Flower::getCategory,flower.getCategory())
+                    .eq(StringUtils.isNotEmpty(flower.getLevel()),Flower::getLevel,flower.getLevel())
+                    .eq(Flower::getStatus,"UP")
+                    .orderByAsc(Flower::getPrice);
+            final List<Flower> flowerList = flowerMapper.selectList(queryWrapper);
+
+            AtomicInteger index = new AtomicInteger(1);
+            flowerList.forEach(f -> f.setTypeRank(index.getAndIncrement()));
+
+            if(!CollectionUtils.isEmpty(flowerList)){
+                flowerMapper.updateBatchTypeRank(flowerList);
+            }
+
+
+
+
+        }finally {
+            lockService.releaseObjectLock(key,"");
+        }
+
+    }
+
+
+
 
     /**
      * 花农(供应商)提交商品
@@ -123,6 +198,8 @@
             paramService.insertTableData(fc.getParamId(), g.getId(), params);
         }
 
+        // 更新商品价格在这里的分类
+        updateFlowTypeRank(null,g.getCategory(),g.getLevel());
         return g.getId();
     }
 
@@ -138,6 +215,7 @@
         } else {
             g.setPrice(dto.getPrice());
             g.setStock(dto.getStock());
+            g.setLimited(dto.getLimited());
         }
 
         g.update(SecurityUtils.getUserId());
@@ -160,12 +238,26 @@
             }
         }
 
+        // 更新商品价格在这里的分类
+        updateFlowTypeRank(null,g.getCategory(),g.getLevel());
+
         return g.getId();
     }
 
     public Long editFlowerAdmin(FlowerUpdateAdminDTO dto){
         Flower g = flowerMapper.selectById(dto.getId());
         g.setSales(dto.getSales());
+        if (!org.springframework.util.StringUtils.isEmpty(dto.getLimited())) {
+            if (g.getStock() == 0 || org.springframework.util.StringUtils.isEmpty(g.getStock())) {
+                throw new ValidationException("库存为0或者空时不能修改限购数量");
+            }
+            if(g.getStock()<dto.getLimited()){
+                throw new ValidationException("限购数量不能大于库存");
+            }
+            g.setLimited(dto.getLimited());
+        }else{
+            g.setLimited(null);
+        }
         g.update(SecurityUtils.getUserId());
         flowerMapper.updateById(g);
 
@@ -327,8 +419,6 @@
             dto.setZoneName(String.join(",", zoneNameLs));
         }
 
-        //TODO 合伙人加价列表
-
         return dto;
     }
 
@@ -378,13 +468,25 @@
             //清除购物车商品
             cartMapper.delete(new QueryWrapper<Cart>().eq("flower_id", id));
         }
+
+        //更新排名
+        updateFlowTypeRank(null,f.getCategory(),f.getLevel());
     }
 
     public void deleteFlower(Long id){
+
+        final Flower flower = flowerMapper.selectById(id);
+        if(flower == null){
+            throw new ValidationException("商品未找到");
+        }
+
         flowerMapper.deleteById(id);
 
         //清除购物车商品
         cartMapper.delete(new QueryWrapper<Cart>().eq("flower_id", id));
+        // 更新商品价格在这里的分类
+        updateFlowTypeRank(null,flower.getCategory(),flower.getLevel());
+
     }
 
     public void restoreFlower(Long id){
@@ -404,6 +506,8 @@
         }
         f.setPrice(dto.getPrice());
         flowerMapper.updateById(f);
+        // 更新商品价格在这里的分类
+        updateFlowTypeRank(null,f.getCategory(),f.getLevel());
     }
 
     public void editFlowerStock(FlowerStockDTO dto){
@@ -462,20 +566,7 @@
         dto.setUserId(SecurityUtils.getUserId());
         dto.setParamId(paramService.getParamIdByCategoryId(dto.getCategory()));
         List<FlowerShowListDTO> ls = flowerMapper.selectFlowerShowList(page, dto);
-        if(ls != null && ls.size() > 0){
-            Long partnerId = getCurrentCustomerPartner();
-            for(FlowerShowListDTO s : ls){
-                BigDecimal price = getFinalPrice(partnerId, s.getCategory()
-                        , s.getId(), s.getPrice(), s.getLevel());
-                s.setPrice(price);
-                s.setCollection(s.getCollectCount() > 0);
-                s.setShopnum(s.getShopnum() == null ? 0 : s.getShopnum());
-
-                if(s.getSales() != null && s.getRealSales() != null){
-                    s.setSales(s.getSales() + s.getRealSales());
-                }
-            }
-        }
+        prepareShowList(ls);
 
         page.setRecords(ls);
 
@@ -502,10 +593,14 @@
         if(pId == null){
             pId = getCurrentCustomerPartner();
         }
+        Customer p = getCurrentCustomerWithoutCheck();
+        Long levelId = p == null ? null : p.getLevelId();
+        Member member = getMember(levelId);
 
         BigDecimal price = getFinalPrice(pId, dto.getCategory()
-                , s.getId(), dto.getPrice(), dto.getLevel());
+                , dto.getId(), dto.getPrice(), dto.getLevel());
         dto.setPrice(price);
+        dto.setPriceMember(calculateMemberPrice(price, member));
 
         String userId = SecurityUtils.getUserId();
         if(StringUtils.isNotEmpty(userId)) {
@@ -597,17 +692,42 @@
 
     public Page<FlowerShowListDTO> myCollect(Page page, FlowerShowQueryDTO dto) {
         dto.setUserId(SecurityUtils.getUserId());
-        /*if (StringUtils.isNotEmpty(dto.getColumn())) {
-            List<OrderItem> orders = new ArrayList<>();
-            OrderItem i = new OrderItem();
-            i.setColumn(dto.getColumn());
-            i.setAsc(dto.isAsc());
-            page.setOrders(orders);
-        }*/
+        if (StringUtils.isNotEmpty(dto.getColumn())) {
+            if(dto.getColumn().contains("sales")
+                    || dto.getColumn().contains("stock")){
+                dto.setColumn(dto.getColumn() + " desc");
+            }
+        }
+
         dto.setParamId(paramService.getParamIdByCategoryId(dto.getCategory()));
         List<FlowerShowListDTO> flowerShowListDTOS = flowerMapper.myCollect(page, dto);
+        prepareShowList(flowerShowListDTOS);
+
         page.setRecords(flowerShowListDTOS);
         return page;
+    }
+
+    private void prepareShowList(List<FlowerShowListDTO> ls){
+        if(ls != null && ls.size() > 0){
+            Customer p = getCurrentCustomerWithoutCheck();
+            Long partnerId = p == null ? null : p.getPartnerId();
+            Long levelId = p == null ? null : p.getLevelId();
+            Member member = getMember(levelId);
+
+            for(FlowerShowListDTO s : ls){
+                BigDecimal price = getFinalPrice(partnerId, s.getCategory()
+                        , s.getId(), s.getPrice(), s.getLevel());
+                s.setPrice(price);
+                s.setPriceMember(calculateMemberPrice(price, member));
+
+                s.setCollection(s.getCollectCount() > 0);
+                s.setShopnum(s.getShopnum() == null ? 0 : s.getShopnum());
+
+                if(s.getSales() != null && s.getRealSales() != null){
+                    s.setSales(s.getSales() + s.getRealSales());
+                }
+            }
+        }
     }
 
     public Page<FlowerShowListDTO> myBrowseHistory(Page page, FlowerShowQueryDTO dto) {
@@ -621,6 +741,8 @@
         }*/
         dto.setParamId(paramService.getParamIdByCategoryId(dto.getCategory()));
         List<FlowerShowListDTO> flowerShowListDTOS = flowerMapper.myBrowseHistory(page, dto);
+        prepareShowList(flowerShowListDTOS);
+
         page.setRecords(flowerShowListDTOS);
         return page;
     }
@@ -629,7 +751,8 @@
         if(dto.getZoneId()!=null && dto.getZoneId().size()>0){//添加专区
             for (Long zoneId : dto.getZoneId()) {
                 for(Long flowerId : dto.getIds()) {
-                    FlowerZoneMap fzp = flowerZoneMapMapper.selectOne(new QueryWrapper<FlowerZoneMap>().eq("flower_id", flowerId).eq("zone_id", zoneId));
+                    FlowerZoneMap fzp = flowerZoneMapMapper.selectOne(new QueryWrapper<FlowerZoneMap>()
+                            .eq("flower_id", flowerId).eq("zone_id", zoneId));
                     if(fzp==null){
                         fzp = new FlowerZoneMap();
                         fzp.setFlowerId(flowerId);
@@ -697,4 +820,94 @@
 
         return page;
     }
+
+    public void clearInvalidHistory(String userId) {
+
+        List<Long> ids = flowerMapper.searchInvalidHistory(userId);
+        if(ids!=null && ids.size()>0){
+            browseService.deleteBatchIds(ids);
+
+        }
+
+    }
+
+    @Transactional
+    public void deleteFlowerBatch(FlowerBatchDTO dto) {
+        List<Flower> flowerList = flowerMapper.getDeletdFlowByIds(dto.getIds());
+        //物理删除
+        flowerMapper.deleteBatchPhysics(dto.getIds());
+        // 备份
+        if(!CollectionUtils.isEmpty(flowerList)){
+            backupFlower(flowerList);
+        }
+    }
+
+    @Async
+    public void backupFlower(List<Flower> flowerList) {
+        // 备份
+        final List<Long> idList = flowerList.stream().map(flower -> flower.getId()).collect(Collectors.toList());
+        final List<FlowerDeleteDO> flowerDeleteList = flowerDeleteService.getBaseMapper().selectBatchIds(idList);
+        // 遍历flowerList 根据ID查找 ,如果flowerDeleteList 存在,则放入到更新列表里面去,如果flowerDeleteList不存在,则添加到新增列表里面去
+
+        // 将查询到的 flowerDeleteList 的 ID 转为 Set 以便快速查找
+        Set<Long> existingIds = flowerDeleteList.stream()
+                .map(FlowerDeleteDO::getId)
+                .collect(Collectors.toSet());
+        // 使用 Stream 进行更新和插入分类
+        List<FlowerDeleteDO> updateList = flowerList.stream()
+                .filter(flower -> existingIds.contains(flower.getId())) // 过滤出已存在的记录
+                .map(flower -> convertToFlowerDeleteDO(flower))         // 转换为 FlowerDeleteDO 对象
+                .collect(Collectors.toList());
+
+        List<FlowerDeleteDO> insertList = flowerList.stream()
+                .filter(flower -> !existingIds.contains(flower.getId())) // 过滤出不存在的记录
+                .map(flower -> convertToFlowerDeleteDO(flower))          // 转换为 FlowerDeleteDO 对象
+                .collect(Collectors.toList());
+
+        // 批量执行更新和新增操作
+        if (!updateList.isEmpty()) {
+            flowerDeleteService.updateBatchById(updateList); // 批量更新
+        }
+        if (!insertList.isEmpty()) {
+            flowerDeleteService.saveBatch(insertList); // 批量插入
+        }
+
+    }
+
+    @Transactional
+    public void restoreFlowerBatch(FlowerBatchDTO dto) {
+        flowerMapper.restoreFlowerBatch(dto.getIds());
+    }
+
+    // 方法用于将 Flower 转换为 FlowerDeleteDO
+    private FlowerDeleteDO convertToFlowerDeleteDO(Flower flower) {
+        FlowerDeleteDO flowerDeleteDO=new FlowerDeleteDO();
+        BeanUtils.copyProperties(flower,flowerDeleteDO);
+        // 其他需要备份的字段...
+        return flowerDeleteDO;
+    }
+
+    public void setFlowersLimited(FlowerLimitedDTO dto) {
+        List<Long> ids = dto.getIds();
+        if (ids == null || ids.size() == 0) {
+            throw new ValidationException("请选择商品");
+        }
+        for (Long id : ids) {
+            Flower f = flowerMapper.selectById(id);
+            if (!org.springframework.util.StringUtils.isEmpty(dto.getLimited())) {
+                if (f.getStock() == 0 || org.springframework.util.StringUtils.isEmpty(f.getStock())) {
+                    throw new ValidationException("商品" + f.getName() + "库存为0或者空时不能修改限购数量");
+                }
+                if(f.getStock()<dto.getLimited()){
+                    throw new ValidationException("商品" + f.getName() + "限购数量不能大于库存");
+                }
+                f.setLimited(dto.getLimited());
+            }else{
+                f.setLimited(null);
+            }
+            flowerMapper.updateById(f);
+        }
+    }
+
+
 }

--
Gitblit v1.9.3