| package com.mzl.flower.service.flower; | 
|   | 
| import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; | 
| import com.baomidou.mybatisplus.extension.plugins.pagination.Page; | 
| import com.mzl.flower.config.exception.ValidationException; | 
| 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.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; | 
| import com.mzl.flower.entity.supplier.Station; | 
| import com.mzl.flower.entity.supplier.Supplier; | 
| import com.mzl.flower.entity.supplier.SupplierType; | 
| import com.mzl.flower.mapper.customer.CollectMapper; | 
| import com.mzl.flower.mapper.flower.*; | 
| import com.mzl.flower.mapper.payment.CartMapper; | 
| import com.mzl.flower.mapper.payment.OrderItemMapper; | 
| import com.mzl.flower.mapper.supplier.StationMapper; | 
| 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; | 
| import org.springframework.beans.factory.annotation.Autowired; | 
| 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.*; | 
| import java.util.concurrent.atomic.AtomicInteger; | 
| import java.util.stream.Collectors; | 
|   | 
| @Slf4j | 
| @Service | 
| @Transactional | 
| public class FlowerService extends BaseService { | 
|   | 
|     @Autowired | 
|     private FlowerMapper flowerMapper; | 
|   | 
|     @Autowired | 
|     private FlowerCategoryMapper categoryMapper; | 
|   | 
|     @Autowired | 
|     private FlowerParamService paramService; | 
|   | 
|     @Autowired | 
|     private SupplierTypeMapper supplierTypeMapper; | 
|   | 
|     @Autowired | 
|     private StationMapper stationMapper; | 
|   | 
|     @Autowired | 
|     private FlowerCategoryDailyMapper categoryDailyMapper; | 
|   | 
|     @Autowired | 
|     private BrowseService browseService; | 
|   | 
|     @Autowired | 
|     private FlowerZoneMapper flowerZoneMapper; | 
|   | 
|     @Autowired | 
|     private CollectMapper collectMapper; | 
|   | 
|     @Autowired | 
|     private FlowerZoneMapMapper flowerZoneMapMapper; | 
|   | 
|     @Autowired | 
|     private CartMapper cartMapper; | 
|   | 
|     @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>() | 
|                 .eq("order_id", order.getId())); | 
|         if(items != null && items.size() > 0){ | 
|             for(OrderItem oi : items){ | 
|                 flowerMapper.updateFlowerSales(oi.getFlowerId(), oi.getNum()); | 
|             } | 
|         } | 
|     } | 
|   | 
|     @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,""); | 
|         } | 
|   | 
|     } | 
|   | 
|   | 
|   | 
|   | 
|     /** | 
|      * 花农(供应商)提交商品 | 
|      * | 
|      * @param dto | 
|      * @return | 
|      */ | 
|     public Long commitFlower(FlowerCreateDTO dto){ | 
|         Supplier s = getCurrentSupplier(); | 
|         if(!"P".equals(s.getStatus())){ | 
|             throw new ValidationException("审核未通过,无法操作!"); | 
|         } | 
|   | 
|         Flower g = new Flower(); | 
|   | 
|         BeanUtils.copyProperties(dto, g); | 
|   | 
|         String userId = SecurityUtils.getUserId(); | 
|         g.create(userId); | 
|         g.setBanners(toJSONString(dto.getBannerList())); | 
|         g.setStatus(Constants.FLOWER_STATUS.PENDING.name()); | 
|         g.setSupplierId(s.getId()); | 
|   | 
|         flowerMapper.insert(g); | 
|   | 
|         FlowerCategory fc = categoryMapper.selectById(g.getCategory()); | 
|         if(fc.getParamId() != null){ | 
|             List<ParamDTO> params = dto.getParams(); | 
|             paramService.insertTableData(fc.getParamId(), g.getId(), params); | 
|         } | 
|   | 
|         // 更新商品价格在这里的分类 | 
|         updateFlowTypeRank(null,g.getCategory(),g.getLevel()); | 
|         return g.getId(); | 
|     } | 
|   | 
|     public Long editFlower(FlowerUpdateDTO dto){ | 
|         Flower g = flowerMapper.selectById(dto.getId()); | 
|         if(Constants.FLOWER_STATUS.PENDING.name().equals(g.getStatus()) | 
|             || Constants.FLOWER_STATUS.REJECT.name().equals(g.getStatus()) | 
|             || Constants.FLOWER_STATUS.DRAFT.name().equals(g.getStatus()) | 
|             || Constants.FLOWER_STATUS.FORCE_OFF.name().equals(g.getStatus()) | 
|         ){ | 
|             BeanUtils.copyProperties(dto, g); | 
|             g.setBanners(toJSONString(dto.getBannerList())); | 
|         } else { | 
|             g.setPrice(dto.getPrice()); | 
|             g.setStock(dto.getStock()); | 
|             g.setLimited(dto.getLimited()); | 
|         } | 
|   | 
|         g.update(SecurityUtils.getUserId()); | 
|         if(Constants.FLOWER_STATUS.DRAFT.name().equals(g.getStatus()) | 
|                 || Constants.FLOWER_STATUS.REJECT.name().equals(g.getStatus()) | 
|                 || Constants.FLOWER_STATUS.FORCE_OFF.name().equals(g.getStatus()) | 
|         ){ | 
|             g.setStatus(Constants.FLOWER_STATUS.PENDING.name()); | 
|         } | 
|         flowerMapper.updateById(g); | 
|   | 
|         FlowerCategory fc = categoryMapper.selectById(g.getCategory()); | 
|         if(fc.getParamId() != null){ | 
|             List<ParamDTO> params = dto.getParams(); | 
|             Map m = paramService.getTableDataById(fc.getParamId(), g.getId()); | 
|             if(m == null) { | 
|                 paramService.insertTableData(fc.getParamId(), g.getId(), params); | 
|             } else { | 
|                 paramService.updateTableData(fc.getParamId(), g.getId(), params); | 
|             } | 
|         } | 
|   | 
|         // 更新商品价格在这里的分类 | 
|         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); | 
|   | 
|         FlowerCategory fc = categoryMapper.selectById(g.getCategory()); | 
|         if(fc.getParamId() != null){ | 
|             List<ParamDTO> params = dto.getParams(); | 
|             Map m = paramService.getTableDataById(fc.getParamId(), g.getId()); | 
|             if(m == null) { | 
|                 paramService.insertTableData(fc.getParamId(), g.getId(), params); | 
|             } else { | 
|                 paramService.updateTableData(fc.getParamId(), g.getId(), params); | 
|             } | 
|         } | 
|   | 
|         return g.getId(); | 
|     } | 
|   | 
|     /** | 
|      * 花农(供应商)商品列表 | 
|      * | 
|      * @param page | 
|      * @param dto | 
|      * @return | 
|      */ | 
|     public Page<FlowerSupplierListDTO> selectFlowerSupplierList(Page page, FlowerQueryDTO dto, int deleted){ | 
|         Supplier s = getCurrentSupplier(); | 
|         dto.setStatusList(splitParam(dto.getStatus())); | 
|         List<FlowerSupplierListDTO> ls = flowerMapper.selectFlowerSupplierList(page, deleted, s.getId(), dto); | 
|         page.setRecords(ls); | 
|   | 
|         return page; | 
|     } | 
|   | 
|     /** | 
|      * 花农(供应商)商品详情 | 
|      * | 
|      * @param id | 
|      * @return | 
|      */ | 
|     public FlowerSupplierDTO getFlowerSupplierDetail(Long id){ | 
|         FlowerSupplierDTO dto = new FlowerSupplierDTO(); | 
|         Flower f = flowerMapper.selectById(id); | 
|   | 
|         setFlowerInfo(f, dto); | 
|   | 
|         return dto; | 
|     } | 
|   | 
|     private void setFlowerInfo(Flower f, FlowerSupplierDTO dto){ | 
|         if(f == null){ | 
|             throw new ValidationException("商品未找到"); | 
|         } | 
|         BeanUtils.copyProperties(f, dto); | 
|         dto.setBannerList(parseArray(f.getBanners(), String.class)); | 
|   | 
|         FlowerCategory fc = categoryMapper.selectById(f.getCategory()); | 
|         dto.setCategoryStr(fc.getName()); | 
|   | 
|         dto.setParams(getFlowerParams(fc.getParamId(), f.getId())); | 
|     } | 
|   | 
|     private List<ParamItemDTO> getFlowerParams(Long paramId, Long fId){ | 
|         List<ParamItemDTO> result = new ArrayList<>(); | 
|         if(paramId != null) { | 
|             List<ParamItemDTO> params = paramService.getParamItemListByParamId(paramId); | 
|             setParamResult(paramId, fId, params, result); | 
|         } | 
|   | 
|         return result; | 
|     } | 
|   | 
|     private void setParamResult(Long paramId, Long fId, List<ParamItemDTO> params, List<ParamItemDTO> result){ | 
|         Map map = paramService.getTableDataById(paramId, fId); | 
|         if(params != null && params.size() > 0 && map != null){ | 
|             for(ParamItemDTO p : params){ | 
|                 ParamItemDTO it = new ParamItemDTO(); | 
|                 BeanUtils.copyProperties(p, it); | 
|                 it.setValue(map.get(p.getColumn())); | 
|                 result.add(it); | 
|             } | 
|         } | 
|     } | 
|   | 
|     public List<ParamItemDTO> getFlowerParams(Long paramId, Long fId | 
|             , Map<Long, List<ParamItemDTO>> paramMap){ | 
|         List<ParamItemDTO> result = new ArrayList<>(); | 
|         if(paramId != null) { | 
|             List<ParamItemDTO> params = paramMap.get(paramId); | 
|             if(params == null){ | 
|                 params = paramService.getParamItemListByParamId(paramId); | 
|                 paramMap.put(paramId, params); | 
|             } | 
|             setParamResult(paramId, fId, params, result); | 
|         } | 
|   | 
|         return result; | 
|     } | 
|   | 
|     public void setFlowerShown(Long id, Boolean shown){ | 
|         Flower f = flowerMapper.selectById(id); | 
|         if(f == null){ | 
|             throw new ValidationException("商品不存在"); | 
|         } | 
|         f.setShown(shown); | 
|   | 
|         flowerMapper.updateById(f); | 
|     } | 
|   | 
|     /** | 
|      * 运营端 商品列表 | 
|      * | 
|      * @param page | 
|      * @param dto | 
|      * @return | 
|      */ | 
|     public Page<FlowerListDTO> selectFlowerList(Page page, FlowerQueryDTO dto){ | 
|         List<String> statusList = splitParam(dto.getStatus()); | 
|         dto.setStatusList(statusList); | 
|         if(statusList != null && statusList.contains(Constants.FLOWER_STATUS.OFF.name())){ | 
|             statusList.add(Constants.FLOWER_STATUS.FORCE_OFF.name()); | 
|         } | 
|         List<FlowerListDTO> ls = flowerMapper.selectFlowerList(page, dto); | 
|         page.setRecords(ls); | 
|   | 
|         return page; | 
|     } | 
|   | 
|     public FlowerDTO getFlowerDetail(Long id){ | 
|         FlowerDTO dto = new FlowerDTO(); | 
|         Flower f = flowerMapper.selectById(id); | 
|   | 
|         setFlowerInfo(f, dto); | 
|   | 
|         Supplier s = supplierMapper.selectById(f.getSupplierId()); | 
|         dto.setSupplierName(s.getName()); | 
|         dto.setSupplierTel(s.getContactTel()); | 
|   | 
|         SupplierType t = supplierTypeMapper.selectById(s.getTypeId()); | 
|         dto.setSupplierType(t != null ? t.getName() : ""); | 
|   | 
|         Station a = stationMapper.selectById(s.getStationId()); | 
|         dto.setSupplierStation(a != null ? a.getName() : ""); | 
|   | 
|         List<FlowerZoneMap> ls = flowerZoneMapMapper.selectList(new QueryWrapper<FlowerZoneMap>() | 
|                 .eq("flower_id", id).orderByAsc("zone_id")); | 
|         List<Long> zoneIdLs = new ArrayList<>(); | 
|         if(ls != null && ls.size() > 0){ | 
|             for(FlowerZoneMap fzm : ls){ | 
|                 zoneIdLs.add(fzm.getZoneId()); | 
|             } | 
|             List<FlowerZone> zLs = flowerZoneMapper.selectBatchIds(zoneIdLs); | 
|             List<String> zoneIdStrLs = new ArrayList<>(); | 
|             List<String> zoneNameLs = new ArrayList<>(); | 
|             for(FlowerZone fz : zLs){ | 
|                 zoneIdStrLs.add(fz.getId() + ""); | 
|                 zoneNameLs.add(fz.getName()); | 
|             } | 
|             dto.setZoneId(String.join(",", zoneIdStrLs)); | 
|             dto.setZoneName(String.join(",", zoneNameLs)); | 
|         } | 
|   | 
|         return dto; | 
|     } | 
|   | 
|     public void auditFlower(Long id, String auditRemarks, String status){ | 
|         Flower f = flowerMapper.selectById(id); | 
|         if(f == null){ | 
|             throw new ValidationException("商品未找到"); | 
|         } | 
|         f.setAuditRemarks(auditRemarks); | 
|         f.setAuditTime(LocalDateTime.now()); | 
|         f.setStatus(status); | 
|         flowerMapper.updateById(f); | 
|   | 
|         /*if(Constants.FLOWER_STATUS.REJECT.name().equals(status)){ | 
|             //通知花农。只是说花农在小程序可以查看驳回的商品,已包含驳回字段 | 
|         }*/ | 
|     } | 
|   | 
|     public void auditFlowers(FlowerAuditMultipleDTO dto, String status){ | 
|         List<Long> ids = dto.getIds(); | 
|         if(ids == null || ids.size() == 0){ | 
|             throw new ValidationException("请选择商品"); | 
|         } | 
|         for(Long id : ids){ | 
|             auditFlower(id, dto.getAuditRemarks(), status); | 
|         } | 
|     } | 
|   | 
|     public void setOffOn(Long id, String status){ | 
|         Flower f = flowerMapper.selectById(id); | 
|         if(f == null){ | 
|             throw new ValidationException("商品未找到"); | 
|         } | 
|         String s = f.getStatus(); | 
|         if(Constants.FLOWER_STATUS.FORCE_OFF.name().equals(s)){ | 
|             throw new ValidationException("强制下架商品请编辑提交重新审核"); | 
|         } | 
|         if(!Constants.FLOWER_STATUS.UP.name().equals(s) | 
|                 && !Constants.FLOWER_STATUS.OFF.name().equals(s)){ | 
|             throw new ValidationException("无法上下架"); | 
|         } | 
|   | 
|         f.setStatus(status); | 
|         flowerMapper.updateById(f); | 
|   | 
|         if(Constants.FLOWER_STATUS.OFF.name().equals(f.getStatus())){ | 
|             //清除购物车商品 | 
|             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){ | 
|         Flower f = flowerMapper.selectById(id); | 
|         if(f == null){ | 
|             throw new ValidationException("商品未找到"); | 
|         } | 
|         f.setDeleted(false); | 
|         f.setStatus(Constants.FLOWER_STATUS.DRAFT.name()); | 
|         flowerMapper.updateById(f); | 
|     } | 
|   | 
|     public void editFlowerPrice(FlowerPriceDTO dto){ | 
|         Flower f = flowerMapper.selectById(dto.getId()); | 
|         if(f == null){ | 
|             throw new ValidationException("商品未找到"); | 
|         } | 
|         f.setPrice(dto.getPrice()); | 
|         flowerMapper.updateById(f); | 
|         // 更新商品价格在这里的分类 | 
|         updateFlowTypeRank(null,f.getCategory(),f.getLevel()); | 
|     } | 
|   | 
|     public void editFlowerStock(FlowerStockDTO dto){ | 
|         Flower f = flowerMapper.selectById(dto.getId()); | 
|         if(f == null){ | 
|             throw new ValidationException("商品未找到"); | 
|         } | 
|         f.setStock(dto.getStock()); | 
|         flowerMapper.updateById(f); | 
|     } | 
|   | 
|     public void setFlowersTags(FlowerTagMultipleDTO dto){ | 
|         List<Long> ids = dto.getIds(); | 
|         if(ids == null || ids.size() == 0){ | 
|             throw new ValidationException("请选择商品"); | 
|         } | 
|   | 
|         for(Long id : ids) { | 
|             Flower f = flowerMapper.selectById(id); | 
|             f.setTags(dto.getTags()); | 
|             flowerMapper.updateById(f); | 
|         } | 
|     } | 
|   | 
|     public void setFlowersForceOff(FlowerOffDTO dto){ | 
|         List<Long> ids = dto.getIds(); | 
|         if(ids == null || ids.size() == 0){ | 
|             throw new ValidationException("请选择商品"); | 
|         } | 
|   | 
|         for(Long id : ids) { | 
|             Flower f = flowerMapper.selectById(id); | 
|             f.setStatus(Constants.FLOWER_STATUS.FORCE_OFF.name()); | 
|             flowerMapper.updateById(f); | 
|   | 
|             //清除购物车商品 | 
|             cartMapper.delete(new QueryWrapper<Cart>().eq("flower_id", id)); | 
|         } | 
|     } | 
|   | 
|     /** | 
|      * 花店交易大厅商品列表 | 
|      * | 
|      * @param page | 
|      * @param dto | 
|      * @return | 
|      */ | 
|     public Page<FlowerShowListDTO> selectShowFlowerList(Page page, FlowerShowQueryDTO dto) { | 
|         /*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); | 
|         }*/ | 
|         dto.setUserId(SecurityUtils.getUserId()); | 
|         dto.setParamId(paramService.getParamIdByCategoryId(dto.getCategory())); | 
|         List<FlowerShowListDTO> ls = flowerMapper.selectFlowerShowList(page, dto); | 
|         prepareShowList(ls); | 
|   | 
|         page.setRecords(ls); | 
|   | 
|         return page; | 
|     } | 
|   | 
|     public FlowerShowDTO getShowFlowerDetail(Long id, Long partnerId){ | 
|         FlowerShowDTO dto = new FlowerShowDTO(); | 
|         Flower f = flowerMapper.selectById(id); | 
|   | 
|         setFlowerInfo(f, dto); | 
|   | 
|         Supplier s = supplierMapper.selectById(f.getSupplierId()); | 
|         dto.setSupplierName(s.getName()); | 
|         dto.setSupplierCover(s.getCover()); | 
|   | 
|         SupplierType t = supplierTypeMapper.selectById(s.getTypeId()); | 
|         dto.setSupplierType(t != null ? t.getName() : ""); | 
|   | 
|         Station a = stationMapper.selectById(s.getStationId()); | 
|         dto.setSupplierStation(a != null ? a.getName() : ""); | 
|   | 
|         Long pId = partnerId; | 
|         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() | 
|                 , dto.getId(), dto.getPrice(), dto.getLevel()); | 
|         dto.setPrice(price); | 
|         dto.setPriceMember(calculateMemberPrice(price, member)); | 
|   | 
|         String userId = SecurityUtils.getUserId(); | 
|         if(StringUtils.isNotEmpty(userId)) { | 
|             int count = collectMapper.selectCount(new QueryWrapper<Collect>() | 
|                     .eq("user_id", userId) | 
|                     .eq("flower_id", id) | 
|             ); | 
|             dto.setCollection(count > 0); | 
|   | 
|             Integer num = cartMapper.getCartFlowerCount(userId, id); | 
|             dto.setShopnum(num == null ? 0 : num); | 
|   | 
|             //添加浏览历史日志 | 
|             browseService.addBrowseHistory(userId, f.getId()); | 
|         } | 
|   | 
|         if(dto.getSales() != null && dto.getRealSales() != null){ | 
|             dto.setSales(dto.getSales() + dto.getRealSales()); | 
|         } | 
|   | 
|         return dto; | 
|     } | 
|   | 
|     private FlowerCategoryDaily getCategoryDaily(Long categoryId, Long partnerId, LocalDate day){ | 
|         QueryWrapper<FlowerCategoryDaily> q = new QueryWrapper<FlowerCategoryDaily>() | 
|                 .eq("category_id", categoryId).eq("day", day); | 
|         if(partnerId == null){ | 
|             q = q.isNull("partner_id"); | 
|         } else { | 
|             q = q.eq("partner_id", partnerId); | 
|         } | 
|         return categoryDailyMapper.selectOne(q); | 
|     } | 
|   | 
|     public void calculateCategoryDaily(Long categoryId, Long partnerId){ | 
|         List<Flower> ls = flowerMapper.selectList(new QueryWrapper<Flower>() | 
|                 .eq("category", categoryId).eq("status", Constants.FLOWER_STATUS.UP.name())); | 
|         if(ls != null && ls.size() > 0){ | 
|             LocalDate preDay = LocalDate.now().plusDays(-1); | 
|             FlowerCategoryDaily pre = getCategoryDaily(categoryId, partnerId, preDay); | 
|   | 
|             int total = ls.size(); | 
|             BigDecimal totalAmount = new BigDecimal(0); | 
|             for(Flower f : ls){ | 
|                 BigDecimal price = getFinalPrice(partnerId, categoryId, f.getId(), f.getPrice(), f.getLevel()); | 
|                 totalAmount = totalAmount.add(price); | 
|             } | 
|             BigDecimal avePrice = totalAmount.divide(new BigDecimal(total), 2, RoundingMode.HALF_UP);//均价 | 
|             BigDecimal avePriceDifference = new BigDecimal(0);//比前一天差价 | 
|             double avePriceDifferenceRate = 0D;//差价百分比 | 
|             if(pre != null){ | 
|                 avePriceDifference = avePrice.subtract(pre.getAvePrice()); | 
|                 if(pre.getAvePrice() != null && pre.getAvePrice().doubleValue() != 0) { | 
|                     BigDecimal rate = avePriceDifference.divide(pre.getAvePrice(), 2, RoundingMode.HALF_UP); | 
|                     avePriceDifferenceRate = rate.doubleValue(); | 
|                 } | 
|             } | 
|   | 
|             FlowerCategoryDaily cd = getCategoryDaily(categoryId, partnerId, LocalDate.now()); | 
|             if (cd == null) { | 
|                 cd = new FlowerCategoryDaily(); | 
|                 cd.setCategoryId(categoryId); | 
|                 cd.setPartnerId(partnerId); | 
|                 cd.setDay(LocalDate.now()); | 
|                 cd.create(); | 
|                 cd.setAvePrice(avePrice); | 
|                 cd.setAvePriceDifference(avePriceDifference); | 
|                 cd.setAvePriceDifferenceRate(avePriceDifferenceRate); | 
|   | 
|                 categoryDailyMapper.insert(cd); | 
|             } else { | 
|                 cd.setUpdateTime(LocalDateTime.now()); | 
|                 cd.setAvePrice(avePrice); | 
|                 cd.setAvePriceDifference(avePriceDifference); | 
|                 cd.setAvePriceDifferenceRate(avePriceDifferenceRate); | 
|                 categoryDailyMapper.updateById(cd); | 
|             } | 
|         } | 
|     } | 
|   | 
|     public Page<FlowerCategoryDailyDTO> getHomeCategoryDaily(Page page){ | 
|         Customer c = getCurrentCustomerWithoutCheck(); | 
|         Long partnerId = c == null ? null : c.getPartnerId(); | 
|         List<FlowerCategoryDailyDTO> ls = categoryMapper.selectHomeCategoryDaily(page, partnerId, LocalDate.now()); | 
|   | 
|         page.setRecords(ls); | 
|         return page; | 
|     } | 
|   | 
|     public Page<FlowerShowListDTO> myCollect(Page page, FlowerShowQueryDTO dto) { | 
|         dto.setUserId(SecurityUtils.getUserId()); | 
|         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) { | 
|         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); | 
|         }*/ | 
|         dto.setParamId(paramService.getParamIdByCategoryId(dto.getCategory())); | 
|         List<FlowerShowListDTO> flowerShowListDTOS = flowerMapper.myBrowseHistory(page, dto); | 
|         prepareShowList(flowerShowListDTOS); | 
|   | 
|         page.setRecords(flowerShowListDTOS); | 
|         return page; | 
|     } | 
|   | 
|     public void setFlowerZone(FlowerZoneBatchDTO dto) { | 
|         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)); | 
|                     if(fzp==null){ | 
|                         fzp = new FlowerZoneMap(); | 
|                         fzp.setFlowerId(flowerId); | 
|                         fzp.setZoneId(zoneId); | 
|                         fzp.create(SecurityUtils.getUserId()); | 
|                         flowerZoneMapMapper.insert(fzp); | 
|                     } | 
|                 } | 
|             } | 
|         }else{ //移除专区 | 
|             flowerZoneMapMapper.delete(new QueryWrapper<FlowerZoneMap>().in("flower_id", dto.getIds())); | 
|         } | 
|     } | 
|   | 
|     public void clearInvalid(String userId) { | 
|         List<Long> ids = flowerMapper.searchInvalidCollect(userId); | 
|         if(ids!=null && ids.size()>0){ | 
|             collectMapper.deleteBatchIds(ids); | 
|         } | 
|     } | 
|   | 
|     public void setFlowerRecommend(FlowerRecommendMultipleDTO dto) { | 
|         List<Long> ids = dto.getIds(); | 
|         if(ids == null || ids.size() == 0){ | 
|             throw new ValidationException("请选择商品"); | 
|         } | 
|   | 
|         for(Long id : ids) { | 
|             Flower f = flowerMapper.selectById(id); | 
|             f.setRecommend(true); | 
|             flowerMapper.updateById(f); | 
|         } | 
|     } | 
|   | 
|     public void cancelFlowerRecommend(FlowerRecommendMultipleDTO dto) { | 
|         List<Long> ids = dto.getIds(); | 
|         if(ids == null || ids.size() == 0){ | 
|             throw new ValidationException("请选择商品"); | 
|         } | 
|   | 
|         for(Long id : ids) { | 
|             Flower f = flowerMapper.selectById(id); | 
|             f.setRecommend(false); | 
|             flowerMapper.updateById(f); | 
|         } | 
|     } | 
|   | 
|     public Integer getUpFlowerStock(){ | 
|         Integer c = flowerMapper.getUpFlowerStock(); | 
|         return c == null ? 0 : c; | 
|     } | 
|   | 
|     public void setFlowerRecommendRank(FlowerRecommendRankDTO dto) { | 
|         Flower f = flowerMapper.selectById(dto.getId()); | 
|         if(f==null){ | 
|             throw new ValidationException("商品不存在"); | 
|         } | 
|         f.setRecommendRank(dto.getRecommendRank()); | 
|         flowerMapper.updateById(f); | 
|     } | 
|   | 
|     public Page<FlowerListDTO> selectZoneFlowerList(Page page, FlowerZoneQueryDTO dto) { | 
|         List<FlowerListDTO> ls = flowerMapper.selectZoneFlowerList(page, dto); | 
|         page.setRecords(ls); | 
|   | 
|         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); | 
|         } | 
|     } | 
|   | 
|   | 
| } |