|
@@ -0,0 +1,266 @@
|
|
|
|
|
+package org.dromara.order.service.impl;
|
|
|
|
|
+
|
|
|
|
|
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
|
|
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
|
|
|
|
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
|
|
|
|
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|
|
|
|
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
|
|
|
+import lombok.RequiredArgsConstructor;
|
|
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
|
|
+import org.dromara.common.core.enums.OrderStatus;
|
|
|
|
|
+import org.dromara.common.core.utils.MapstructUtils;
|
|
|
|
|
+import org.dromara.common.core.utils.StringUtils;
|
|
|
|
|
+import org.dromara.common.mybatis.core.page.PageQuery;
|
|
|
|
|
+import org.dromara.common.mybatis.core.page.TableDataInfo;
|
|
|
|
|
+import org.dromara.common.redis.utils.SequenceUtils;
|
|
|
|
|
+import org.dromara.order.domain.OrderDeliver;
|
|
|
|
|
+import org.dromara.order.domain.OrderDeliverProduct;
|
|
|
|
|
+import org.dromara.order.domain.OrderMain;
|
|
|
|
|
+import org.dromara.order.domain.bo.OrderDeliverBo;
|
|
|
|
|
+import org.dromara.order.domain.bo.OrderDeliverProductBo;
|
|
|
|
|
+import org.dromara.order.domain.vo.OrderDeliverVo;
|
|
|
|
|
+import org.dromara.order.domain.vo.OrderQuantitySummary;
|
|
|
|
|
+import org.dromara.order.mapper.OrderDeliverMapper;
|
|
|
|
|
+import org.dromara.order.mapper.OrderDeliverProductMapper;
|
|
|
|
|
+import org.dromara.order.mapper.OrderMainMapper;
|
|
|
|
|
+import org.dromara.order.mapper.OrderProductMapper;
|
|
|
|
|
+import org.dromara.order.service.IOrderDeliverService;
|
|
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
|
|
+import org.springframework.transaction.annotation.Transactional;
|
|
|
|
|
+
|
|
|
|
|
+import java.util.Collection;
|
|
|
|
|
+import java.util.List;
|
|
|
|
|
+import java.util.Map;
|
|
|
|
|
+import java.util.Optional;
|
|
|
|
|
+import java.util.stream.Collectors;
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ * 订单发货主Service业务层处理
|
|
|
|
|
+ *
|
|
|
|
|
+ * @author LionLi
|
|
|
|
|
+ * @date 2025-12-30
|
|
|
|
|
+ */
|
|
|
|
|
+@Slf4j
|
|
|
|
|
+@RequiredArgsConstructor
|
|
|
|
|
+@Service
|
|
|
|
|
+public class OrderDeliverServiceImpl extends ServiceImpl<OrderDeliverMapper, OrderDeliver> implements IOrderDeliverService {
|
|
|
|
|
+
|
|
|
|
|
+ private final OrderDeliverMapper baseMapper;
|
|
|
|
|
+
|
|
|
|
|
+ private final OrderMainMapper orderMainMapper;
|
|
|
|
|
+
|
|
|
|
|
+ private final OrderProductMapper orderProductMapper;
|
|
|
|
|
+
|
|
|
|
|
+ private final OrderDeliverProductMapper orderDeliverProductMapper;
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 查询订单发货主
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param id 主键
|
|
|
|
|
+ * @return 订单发货主
|
|
|
|
|
+ */
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public OrderDeliverVo queryById(Long id) {
|
|
|
|
|
+ OrderDeliverVo orderDeliverVo = baseMapper.selectVoById(id);
|
|
|
|
|
+ orderDeliverVo.setDeliverProductList(orderDeliverProductMapper.selectVoList(new LambdaQueryWrapper<OrderDeliverProduct>()
|
|
|
|
|
+ .eq(OrderDeliverProduct::getDeliverId, id)));
|
|
|
|
|
+ return orderDeliverVo;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 分页查询订单发货主列表
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param bo 查询条件
|
|
|
|
|
+ * @param pageQuery 分页参数
|
|
|
|
|
+ * @return 订单发货主分页列表
|
|
|
|
|
+ */
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public TableDataInfo<OrderDeliverVo> queryPageList(OrderDeliverBo bo, PageQuery pageQuery) {
|
|
|
|
|
+ LambdaQueryWrapper<OrderDeliver> lqw = buildQueryWrapper(bo);
|
|
|
|
|
+ Page<OrderDeliverVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
|
|
|
|
|
+ return TableDataInfo.build(result);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 查询符合条件的订单发货主列表
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param bo 查询条件
|
|
|
|
|
+ * @return 订单发货主列表
|
|
|
|
|
+ */
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public List<OrderDeliverVo> queryList(OrderDeliverBo bo) {
|
|
|
|
|
+ LambdaQueryWrapper<OrderDeliver> lqw = buildQueryWrapper(bo);
|
|
|
|
|
+ return baseMapper.selectVoList(lqw);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private LambdaQueryWrapper<OrderDeliver> buildQueryWrapper(OrderDeliverBo bo) {
|
|
|
|
|
+ Map<String, Object> params = bo.getParams();
|
|
|
|
|
+ LambdaQueryWrapper<OrderDeliver> lqw = Wrappers.lambdaQuery();
|
|
|
|
|
+ lqw.orderByAsc(OrderDeliver::getId);
|
|
|
|
|
+ lqw.eq(bo.getOrderId() != null, OrderDeliver::getOrderId, bo.getOrderId());
|
|
|
|
|
+ lqw.eq(StringUtils.isNotBlank(bo.getOrderCode()), OrderDeliver::getOrderCode, bo.getOrderCode());
|
|
|
|
|
+ lqw.eq(StringUtils.isNotBlank(bo.getLogisticPackNo()), OrderDeliver::getLogisticPackNo, bo.getLogisticPackNo());
|
|
|
|
|
+ lqw.eq(StringUtils.isNotBlank(bo.getDeliverMethod()), OrderDeliver::getDeliverMethod, bo.getDeliverMethod());
|
|
|
|
|
+ lqw.eq(StringUtils.isNotBlank(bo.getDeliverMan()), OrderDeliver::getDeliverMan, bo.getDeliverMan());
|
|
|
|
|
+ lqw.eq(StringUtils.isNotBlank(bo.getPhone()), OrderDeliver::getPhone, bo.getPhone());
|
|
|
|
|
+ lqw.eq(StringUtils.isNotBlank(bo.getLogisticsStatus()), OrderDeliver::getLogisticsStatus, bo.getLogisticsStatus());
|
|
|
|
|
+ lqw.eq(StringUtils.isNotBlank(bo.getDeliverRemark()), OrderDeliver::getDeliverRemark, bo.getDeliverRemark());
|
|
|
|
|
+ lqw.eq(StringUtils.isNotBlank(bo.getChecklistRemark()), OrderDeliver::getChecklistRemark, bo.getChecklistRemark());
|
|
|
|
|
+ lqw.eq(bo.getLogisticsCompany() != null, OrderDeliver::getLogisticsCompany, bo.getLogisticsCompany());
|
|
|
|
|
+ lqw.eq(StringUtils.isNotBlank(bo.getLogisticNo()), OrderDeliver::getLogisticNo, bo.getLogisticNo());
|
|
|
|
|
+ lqw.eq(StringUtils.isNotBlank(bo.getLogisticPackStatus()), OrderDeliver::getLogisticPackStatus, bo.getLogisticPackStatus());
|
|
|
|
|
+ lqw.eq(StringUtils.isNotBlank(bo.getConsigneePhone()), OrderDeliver::getConsigneePhone, bo.getConsigneePhone());
|
|
|
|
|
+ lqw.eq(StringUtils.isNotBlank(bo.getPlatformCode()), OrderDeliver::getPlatformCode, bo.getPlatformCode());
|
|
|
|
|
+ return lqw;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 新增订单发货主
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param bo 订单发货主
|
|
|
|
|
+ * @return 是否新增成功
|
|
|
|
|
+ */
|
|
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public Boolean insertByBo(OrderDeliverBo bo) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ // 1. 生成发货单号
|
|
|
|
|
+ bo.setDeliverCode(SequenceUtils.nextIdDateTimePadded(""));
|
|
|
|
|
+
|
|
|
|
|
+ Long orderId = bo.getOrderId();
|
|
|
|
|
+
|
|
|
|
|
+ // 2. 查询订单主信息(用于后续状态更新)
|
|
|
|
|
+ OrderMain orderMain = orderMainMapper.selectById(orderId);
|
|
|
|
|
+ if (orderMain == null) {
|
|
|
|
|
+ throw new RuntimeException("订单不存在: " + orderId);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 3. 获取 订单总数量 和 已发货总数量
|
|
|
|
|
+ OrderQuantitySummary summary = orderProductMapper.selectOrderAndDeliveredQuantity(orderId);
|
|
|
|
|
+ long orderTotalQty = Optional.ofNullable(summary.getOrderTotalQty()).orElse(0L);
|
|
|
|
|
+ long deliveredTotalQty = Optional.ofNullable(summary.getDeliveredTotalQty()).orElse(0L);
|
|
|
|
|
+
|
|
|
|
|
+ // 4. 新增本次发货数量(从 BO 中累加)
|
|
|
|
|
+ long currentDeliverQty = bo.getOrderDeliverProducts().stream()
|
|
|
|
|
+ .mapToLong(OrderDeliverProductBo::getDeliverNum)
|
|
|
|
|
+ .sum();
|
|
|
|
|
+
|
|
|
|
|
+ // 5. 计算发货后总量
|
|
|
|
|
+ long newDeliveredTotalQty = deliveredTotalQty + currentDeliverQty;
|
|
|
|
|
+
|
|
|
|
|
+ // 6. 判断新状态
|
|
|
|
|
+ String newStatus;
|
|
|
|
|
+ if (newDeliveredTotalQty >= orderTotalQty) {
|
|
|
|
|
+ newStatus = OrderStatus.SHIPPED.getCode(); // 已全部发货
|
|
|
|
|
+ } else if (newDeliveredTotalQty > 0) {
|
|
|
|
|
+ newStatus = OrderStatus.PARTIALLY_SHIPPED.getCode(); // 部分发货
|
|
|
|
|
+ } else {
|
|
|
|
|
+ newStatus = orderMain.getOrderStatus(); // 无发货,保持原状态
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 7. 插入发货单主表
|
|
|
|
|
+ OrderDeliver deliver = MapstructUtils.convert(bo, OrderDeliver.class);
|
|
|
|
|
+ validEntityBeforeSave(deliver);
|
|
|
|
|
+ boolean inserted = baseMapper.insert(deliver) > 0;
|
|
|
|
|
+ if (!inserted) {
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+ bo.setId(deliver.getId());
|
|
|
|
|
+
|
|
|
|
|
+ // 8. 插入发货商品明细
|
|
|
|
|
+ saveOrderDeliverProducts(deliver.getId(), bo.getOrderDeliverProducts(), false);
|
|
|
|
|
+
|
|
|
|
|
+ // 9. 更新订单主表状态
|
|
|
|
|
+ LambdaUpdateWrapper<OrderMain> updateWrapper = new LambdaUpdateWrapper<OrderMain>()
|
|
|
|
|
+ .eq(OrderMain::getId, orderId)
|
|
|
|
|
+ .set(OrderMain::getOrderStatus, newStatus);
|
|
|
|
|
+
|
|
|
|
|
+ orderMainMapper.update(null, updateWrapper);
|
|
|
|
|
+
|
|
|
|
|
+ log.info("新增订单发货单成功:{}", bo.getId());
|
|
|
|
|
+ return true;
|
|
|
|
|
+ } catch (RuntimeException e) {
|
|
|
|
|
+ log.error("新增订单发货主失败:{}", e.getMessage(), e);
|
|
|
|
|
+ throw new RuntimeException(e);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 修改订单发货主
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param bo 订单发货主
|
|
|
|
|
+ * @return 是否修改成功
|
|
|
|
|
+ */
|
|
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public Boolean updateByBo(OrderDeliverBo bo) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ OrderDeliver update = MapstructUtils.convert(bo, OrderDeliver.class);
|
|
|
|
|
+ validEntityBeforeSave(update);
|
|
|
|
|
+ boolean flag = baseMapper.updateById(update) > 0;
|
|
|
|
|
+
|
|
|
|
|
+ if (flag) {
|
|
|
|
|
+ // 保存商品明细(编辑时先删除再新增)
|
|
|
|
|
+ saveOrderDeliverProducts(bo.getId(), bo.getOrderDeliverProducts(), true);
|
|
|
|
|
+ }
|
|
|
|
|
+ log.info("修改订单发货主成功:{}", bo.getId());
|
|
|
|
|
+ return flag;
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ log.error("修改订单发货主失败:{}", e.getMessage(), e);
|
|
|
|
|
+ throw new RuntimeException(e);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 保存发货商品明细(公共方法)
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param deliverId 发货单ID
|
|
|
|
|
+ * @param productBos 商品明细列表
|
|
|
|
|
+ * @param deleteFirst 是否先删除已有明细(true=编辑,false=新增)
|
|
|
|
|
+ */
|
|
|
|
|
+ private void saveOrderDeliverProducts(Long deliverId, List<OrderDeliverProductBo> productBos, boolean deleteFirst) {
|
|
|
|
|
+ if (deliverId == null || productBos == null || productBos.isEmpty()) {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 编辑时:先删除明细
|
|
|
|
|
+ if (deleteFirst) {
|
|
|
|
|
+ orderDeliverProductMapper.deleteByDeliverId(deliverId);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 批量插入新明细
|
|
|
|
|
+ List<OrderDeliverProduct> products = productBos.stream()
|
|
|
|
|
+ .map(bo -> {
|
|
|
|
|
+ OrderDeliverProduct product = MapstructUtils.convert(bo, OrderDeliverProduct.class);
|
|
|
|
|
+ product.setDeliverId(deliverId);
|
|
|
|
|
+ return product;
|
|
|
|
|
+ })
|
|
|
|
|
+ .collect(Collectors.toList());
|
|
|
|
|
+
|
|
|
|
|
+ if (!products.isEmpty()) {
|
|
|
|
|
+ orderDeliverProductMapper.insertBatch(products);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 保存前的数据校验
|
|
|
|
|
+ */
|
|
|
|
|
+ private void validEntityBeforeSave(OrderDeliver entity) {
|
|
|
|
|
+ //TODO 做一些数据校验,如唯一约束
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 校验并批量删除订单发货主信息
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param ids 待删除的主键集合
|
|
|
|
|
+ * @param isValid 是否进行有效性校验
|
|
|
|
|
+ * @return 是否删除成功
|
|
|
|
|
+ */
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
|
|
|
|
|
+ if (isValid) {
|
|
|
|
|
+ //TODO 做一些业务上的校验,判断是否需要校验
|
|
|
|
|
+ }
|
|
|
|
|
+ return baseMapper.deleteByIds(ids) > 0;
|
|
|
|
|
+ }
|
|
|
|
|
+}
|