| package com.mzl.flower.service.transport; | 
|   | 
| 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.dto.AreaDTO; | 
| import com.mzl.flower.dto.request.transport.*; | 
| import com.mzl.flower.dto.response.transport.*; | 
| import com.mzl.flower.entity.customer.Address; | 
| import com.mzl.flower.entity.customer.Customer; | 
| import com.mzl.flower.entity.transport.Transport; | 
| import com.mzl.flower.entity.transport.TransportFee; | 
| import com.mzl.flower.entity.transport.TransportFeeArea; | 
| import com.mzl.flower.mapper.customer.AddressMapper; | 
| import com.mzl.flower.mapper.transport.TransportFeeAreaMapper; | 
| import com.mzl.flower.mapper.transport.TransportFeeMapper; | 
| import com.mzl.flower.mapper.transport.TransportMapper; | 
| import com.mzl.flower.service.BaseService; | 
| import lombok.extern.slf4j.Slf4j; | 
| import org.springframework.beans.BeanUtils; | 
| import org.springframework.beans.factory.annotation.Autowired; | 
| import org.springframework.stereotype.Service; | 
| import org.springframework.transaction.annotation.Transactional; | 
|   | 
| import java.math.BigDecimal; | 
| import java.util.ArrayList; | 
| import java.util.HashMap; | 
| import java.util.List; | 
| import java.util.Map; | 
|   | 
| @Slf4j | 
| @Service | 
| @Transactional | 
| public class TransportService extends BaseService { | 
|   | 
|     @Autowired | 
|     private TransportMapper transportMapper; | 
|   | 
|     @Autowired | 
|     private TransportFeeMapper feeMapper; | 
|   | 
|     @Autowired | 
|     private TransportFeeAreaMapper feeAreaMapper; | 
|   | 
|     @Autowired | 
|     private AddressMapper addressMapper; | 
|   | 
|     public Long addTransport(TransportCreateDTO dto){ | 
|         Transport g = new Transport(); | 
|   | 
|         BeanUtils.copyProperties(dto, g); | 
|         g.create(SecurityUtils.getUserId()); | 
|   | 
|         transportMapper.insert(g); | 
|   | 
|         return g.getId(); | 
|     } | 
|   | 
|     public Long updateTransport(TransportUpdateDTO dto){ | 
|         Long id = dto.getId(); | 
|         Transport g = transportMapper.selectById(id); | 
|   | 
|         BeanUtils.copyProperties(dto, g); | 
|         g.update(SecurityUtils.getUserId()); | 
|   | 
|         transportMapper.updateById(g); | 
|   | 
|         return id; | 
|     } | 
|   | 
|     public TransportDTO getTransport(Long id){ | 
|         TransportDTO dto = new TransportDTO(); | 
|         Transport d = transportMapper.selectById(id); | 
|         BeanUtils.copyProperties(d, dto); | 
|   | 
|         return dto; | 
|     } | 
|   | 
|     public Page<TransportDTO> selectTransportList(Page page, TransportQueryDTO dto){ | 
|         List<TransportDTO> ls = transportMapper.selectTransportList(page, dto); | 
|   | 
|         page.setRecords(ls); | 
|   | 
|         return page; | 
|     } | 
|   | 
|     public void deleteTransport(Long id){ | 
|         transportMapper.deleteById(id); | 
|     } | 
|   | 
|     public List<TransportFeeListDTO> getTransportFees(Long id){ | 
|         List<TransportFee> ls = feeMapper.selectList(new QueryWrapper<TransportFee>().eq("transport_id", id)); | 
|   | 
|         List<TransportFeeArea> areaAll = feeAreaMapper.selectList(new QueryWrapper<TransportFeeArea>().eq("transport_id", id)); | 
|         Map<Long, List<AreaDTO>> map = new HashMap<>(); | 
|         if(ls != null){ | 
|             for(TransportFeeArea fa : areaAll){ | 
|                 AreaDTO a = new AreaDTO(); | 
|                 BeanUtils.copyProperties(fa, a); | 
|                 List<AreaDTO> areas = map.computeIfAbsent(fa.getTransportFeeId(), k -> new ArrayList<>()); | 
|                 areas.add(a); | 
|             } | 
|         } | 
|   | 
|         List<TransportFeeListDTO> result = new ArrayList<>(); | 
|         if(ls != null && ls.size() > 0){ | 
|             for(TransportFee f : ls){ | 
|                 TransportFeeListDTO dto = new TransportFeeListDTO(); | 
|                 BeanUtils.copyProperties(f, dto); | 
|                 dto.setAreas(map.get(f.getId())); | 
|                 result.add(dto); | 
|             } | 
|         } | 
|   | 
|         return result; | 
|     } | 
|   | 
|     public Long addFee(TransportFeeCreateDTO dto){ | 
|         TransportFee f = new TransportFee(); | 
|         BeanUtils.copyProperties(dto, f); | 
|         f.create(SecurityUtils.getUserId()); | 
|   | 
|         feeMapper.insert(f); | 
|   | 
|         saveFeeArea(f.getTransportId(), f.getId(), dto.getAreas()); | 
|   | 
|         return f.getId(); | 
|     } | 
|   | 
|     private void saveFeeArea(Long tId, Long feeId, List<AreaDTO> areas){ | 
|         feeAreaMapper.delete(new QueryWrapper<TransportFeeArea>().eq("transport_fee_id", feeId)); | 
|         feeAreaMapper.clearTransportArea(tId, areas); | 
|         if(areas != null){ | 
|             for(AreaDTO a : areas){ | 
|                 TransportFeeArea fa = new TransportFeeArea(); | 
|                 BeanUtils.copyProperties(a, fa); | 
|                 fa.setTransportFeeId(feeId); | 
|                 fa.setTransportId(tId); | 
|                 feeAreaMapper.insert(fa); | 
|             } | 
|         } | 
|     } | 
|   | 
|     public Long updateFee(TransportFeeUpdateDTO dto){ | 
|         TransportFee f = feeMapper.selectById(dto.getId()); | 
|         BeanUtils.copyProperties(dto, f); | 
|         f.update(SecurityUtils.getUserId()); | 
|   | 
|         feeMapper.updateById(f); | 
|   | 
|         saveFeeArea(f.getTransportId(), f.getId(), dto.getAreas()); | 
|   | 
|         return f.getId(); | 
|     } | 
|   | 
|     public TransportFeeDTO getFee(Long id){ | 
|         TransportFeeDTO dto = new TransportFeeDTO(); | 
|         TransportFee f = feeMapper.selectById(id); | 
|         BeanUtils.copyProperties(f, dto); | 
|   | 
|         List<TransportFeeArea> ls = feeAreaMapper.selectList(new QueryWrapper<TransportFeeArea>().eq("transport_fee_id", id)); | 
|         List<AreaDTO> areas = new ArrayList<>(); | 
|         if(ls != null){ | 
|             for(TransportFeeArea fa : ls){ | 
|                 AreaDTO a = new AreaDTO(); | 
|                 BeanUtils.copyProperties(fa, a); | 
|                 areas.add(a); | 
|             } | 
|         } | 
|         dto.setAreas(areas); | 
|   | 
|         return dto; | 
|     } | 
|   | 
|     public void deleteFee(Long id){ | 
|         feeMapper.deleteById(id); | 
|         feeAreaMapper.delete(new QueryWrapper<TransportFeeArea>().eq("transport_fee_id", id)); | 
|     } | 
|   | 
|     public List<TransportOrderDTO> getPreOrderTransportList(Long addressId, Double weight){ | 
|         Address address = addressMapper.selectById(addressId); | 
|         return getPreOrderTransportList(address, weight, null); | 
|     } | 
|   | 
|     public List<TransportOrderDTO> getPreOrderTransportList(Address address, Double weight, Long transportId){ | 
|         if(address == null){ | 
|             throw new ValidationException("收货地址不存在"); | 
|         } | 
|   | 
|         Customer customer = getCurrentCustomer(); | 
|         Long partnerId = customer.getPartnerId(); | 
|   | 
|         List<TransportOrderDTO> result = new ArrayList<>(); | 
|         if(partnerId != null){ | 
|             log.info("合伙人店铺购买不需要物流"); | 
|             return result; | 
|         } | 
|         double w = weight == null ? 0 : weight; | 
|         List<TransportFeeMListDTO> tfLs = feeMapper.selectFeeList(address.getProvince(), address.getCity(), transportId); | 
|         List<Long> tList = new ArrayList<>(); | 
|         if(tfLs != null && tfLs.size() > 0){ | 
|             for (TransportFeeMListDTO tf : tfLs) { | 
|                 Long tId = tf.getTransportId(); | 
|                 if(tList.contains(tId)){ | 
|                     continue; | 
|                 } | 
|                 tList.add(transportId); | 
|                 TransportOrderDTO o = new TransportOrderDTO(); | 
|                 o.setId(tId); | 
|                 o.setName(tf.getName()); | 
|                 o.setEnName(tf.getEnName()); | 
|                 o.setFee(getFee(w, tf.getFirstWeight(), tf.getAddedWeight() | 
|                         , tf.getFirstWeightFee(), tf.getAddedWeightFee())); | 
|                 result.add(o); | 
|             } | 
|         } | 
|         return result; | 
|     } | 
|   | 
|     private BigDecimal getFee(double w, Double firstWeight, Double addedWeight | 
|             , BigDecimal firstWeightFee, BigDecimal addedWeightFee){ | 
|         double f = firstWeight == null ? 0 : firstWeight; | 
|         double a = addedWeight == null ? 0 : addedWeight; | 
|         BigDecimal fee = firstWeightFee == null ? new BigDecimal(0) : firstWeightFee; | 
|         BigDecimal af = addedWeightFee == null ? new BigDecimal(0) : addedWeightFee; | 
|         if(a > 0){ | 
|             double wd = w - f; | 
|             if(wd > 0){ | 
|                 double num = Math.ceil(wd / a); | 
|                 fee = fee.add(af.multiply(new BigDecimal(num))); | 
|             } | 
|         } | 
|   | 
|         return fee; | 
|     } | 
| } |