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 selectTransportList(Page page, TransportQueryDTO dto){ List ls = transportMapper.selectTransportList(page, dto); page.setRecords(ls); return page; } public void deleteTransport(Long id){ transportMapper.deleteById(id); } public List getTransportFees(Long id){ List ls = feeMapper.selectList(new QueryWrapper().eq("transport_id", id)); List areaAll = feeAreaMapper.selectList(new QueryWrapper().eq("transport_id", id)); Map> map = new HashMap<>(); if(ls != null){ for(TransportFeeArea fa : areaAll){ AreaDTO a = new AreaDTO(); BeanUtils.copyProperties(fa, a); List areas = map.computeIfAbsent(fa.getTransportFeeId(), k -> new ArrayList<>()); areas.add(a); } } List 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 areas){ feeAreaMapper.delete(new QueryWrapper().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 ls = feeAreaMapper.selectList(new QueryWrapper().eq("transport_fee_id", id)); List 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().eq("transport_fee_id", id)); } public List getPreOrderTransportList(Long addressId, Double weight){ Address address = addressMapper.selectById(addressId); return getPreOrderTransportList(address, weight, null); } public List getPreOrderTransportList(Address address, Double weight, Long transportId){ if(address == null){ throw new ValidationException("收货地址不存在"); } Customer customer = getCurrentCustomer(); Long partnerId = customer.getPartnerId(); List result = new ArrayList<>(); if(partnerId != null){ log.info("合伙人店铺购买不需要物流"); return result; } double w = weight == null ? 0 : weight; List tfLs = feeMapper.selectFeeList(address.getProvince(), address.getCity(), transportId); List 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; } }