diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/controller/MallDeliveryOrderController.java b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/controller/MallDeliveryOrderController.java index cc723e42..d0e653c0 100644 --- a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/controller/MallDeliveryOrderController.java +++ b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/controller/MallDeliveryOrderController.java @@ -105,8 +105,8 @@ public class MallDeliveryOrderController { @PostMapping("/countOrderByStatus") @ApiOperation(value = "查询当前配送员指派单和已接单数量") - public Result>> countOrderByStatus(@RequestParam String workerId) { - return new ResultUtil>>().setData(mallDeliveryOrderService.countOrdersByStatus(workerId)); + public Result>> countOrderByStatus(@RequestParam String workerId) { + return new ResultUtil>>().setData(mallDeliveryOrderService.countOrdersByStatus(workerId)); } @PostMapping("/pagebyworker") diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/controller/MallRefundRecordController.java b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/controller/MallRefundRecordController.java index 77cc0996..70b667c7 100644 --- a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/controller/MallRefundRecordController.java +++ b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/controller/MallRefundRecordController.java @@ -3,7 +3,9 @@ package cc.hiver.mall.controller; import cc.hiver.core.common.utils.ResultUtil; import cc.hiver.core.common.vo.Result; import cc.hiver.mall.entity.MallRefundRecord; +import cc.hiver.mall.pojo.query.MallRefundRecordPageQuery; import cc.hiver.mall.service.mybatis.MallRefundRecordService; +import com.baomidou.mybatisplus.core.metadata.IPage; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; @@ -50,4 +52,24 @@ public class MallRefundRecordController { } } + @PostMapping("/page") + @ApiOperation(value = "分页查询退款售后列表") + public Result> page(@RequestBody MallRefundRecordPageQuery q) { + return new ResultUtil>().setData(mallRefundRecordService.selectPageVO(q)); + } + + /** + * 商家配送员、处理退款/售后 + */ + @PostMapping("/allowOrReject") + @ApiOperation(value = "处理退款/售后") + public Result allowOrReject(@RequestBody MallRefundRecord mallRefundRecord) { + try { + mallRefundRecordService.updateStatus(mallRefundRecord); + return ResultUtil.success("处理成功"); + } catch (Exception e) { + log.error("处理失败: {}", e.getMessage(), e); + return ResultUtil.error(e.getMessage()); + } + } } diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/dao/mapper/MallDeliveryOrderMapper.java b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/dao/mapper/MallDeliveryOrderMapper.java index 9a5a8426..71fc0edb 100644 --- a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/dao/mapper/MallDeliveryOrderMapper.java +++ b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/dao/mapper/MallDeliveryOrderMapper.java @@ -33,6 +33,6 @@ public interface MallDeliveryOrderMapper extends BaseMapper { List> countOrdersByType(@Param("regionId") String regionId); - List> countOrdersByStatus(@Param("workerId") String workerId); + List> countOrdersByStatus(@Param("workerId") String workerId); } diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/dao/mapper/MallRefundRecordMapper.java b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/dao/mapper/MallRefundRecordMapper.java index 45f8c715..f2c01a38 100644 --- a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/dao/mapper/MallRefundRecordMapper.java +++ b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/dao/mapper/MallRefundRecordMapper.java @@ -1,7 +1,10 @@ package cc.hiver.mall.dao.mapper; import cc.hiver.mall.entity.MallRefundRecord; +import cc.hiver.mall.pojo.query.MallRefundRecordPageQuery; import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import org.apache.ibatis.annotations.Param; import org.springframework.stereotype.Repository; /** @@ -9,4 +12,5 @@ import org.springframework.stereotype.Repository; */ @Repository public interface MallRefundRecordMapper extends BaseMapper { + IPage selectPageVO(IPage page, @Param("q") MallRefundRecordPageQuery q); } diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/entity/MallRefundRecord.java b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/entity/MallRefundRecord.java index 52d29bd1..1f5649fa 100644 --- a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/entity/MallRefundRecord.java +++ b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/entity/MallRefundRecord.java @@ -21,7 +21,7 @@ import java.util.List; @Entity @Table(name = "mall_refund_record") @TableName("mall_refund_record") -@ApiModel(value = "退款记录表") +@ApiModel(value = "退款或售后记录表") public class MallRefundRecord implements Serializable { @Id @TableId @@ -38,7 +38,7 @@ public class MallRefundRecord implements Serializable { private String reason; @ApiModelProperty(value = "退款图片") private String pictures; - @ApiModelProperty(value = "退款状态 0:退款处理中 1:退款成功 2:商家拒绝退款 退款失败 3售后中 4已售后 5 拒绝售后 6 商家拒绝售后 7 配送员拒绝售后") + @ApiModelProperty(value = "退款状态 0:退款处理中 1:同意退款 2:(商家或者配送员)拒绝退款 退款失败 3售后中 4同意售后 5 (商家或者配送员)拒绝售后") private Integer status; @ApiModelProperty(value = "退款类型 1 退商品 2退配送费 3 全额退款") private Integer refundType; @@ -53,6 +53,16 @@ public class MallRefundRecord implements Serializable { @TableField(exist = false) private List items; + @ApiModelProperty("售后订单详情") + @Transient + @TableField(exist = false) + private MallOrder mallOrder; + + @ApiModelProperty("订单是否配送") + @Transient + @TableField(exist = false) + private Integer deliveryType; + @ApiModelProperty("店铺id") @Transient @TableField(exist = false) diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/pojo/query/MallRefundRecordPageQuery.java b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/pojo/query/MallRefundRecordPageQuery.java new file mode 100644 index 00000000..79b85b73 --- /dev/null +++ b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/pojo/query/MallRefundRecordPageQuery.java @@ -0,0 +1,25 @@ +package cc.hiver.mall.pojo.query; + +import cc.hiver.core.base.HiverBasePageQuery; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.List; + +/** + * 退款售后分页查询对象 + */ +@ApiModel("退款售后分页查询对象") +@Data +public class MallRefundRecordPageQuery extends HiverBasePageQuery { + + @ApiModelProperty("退款或售后状态 0:退款处理中 1:退款成功 2:(商家或者配送员)拒绝退款 退款失败 3售后中 4已售后成功 5 (商家或者配送员)拒绝售后") + private Integer status; + + @ApiModelProperty(value = "关联的商家或者配送员ID 如果 refundType = 3 && refundTypeStatus == 3 MallRefundRecord存两条记录") + private String linkId; + + @ApiModelProperty("多种状态查") + private List statusList; +} diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/service/mybatis/MallDeliveryOrderService.java b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/service/mybatis/MallDeliveryOrderService.java index 7678204a..2530686f 100644 --- a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/service/mybatis/MallDeliveryOrderService.java +++ b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/service/mybatis/MallDeliveryOrderService.java @@ -56,5 +56,5 @@ public interface MallDeliveryOrderService extends IService { List> countOrdersByType(String regionId); - List> countOrdersByStatus(String workerId); + List> countOrdersByStatus(String workerId); } diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/service/mybatis/MallRefundRecordService.java b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/service/mybatis/MallRefundRecordService.java index bbab750f..0a249c97 100644 --- a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/service/mybatis/MallRefundRecordService.java +++ b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/service/mybatis/MallRefundRecordService.java @@ -1,6 +1,8 @@ package cc.hiver.mall.service.mybatis; import cc.hiver.mall.entity.MallRefundRecord; +import cc.hiver.mall.pojo.query.MallRefundRecordPageQuery; +import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.service.IService; import java.util.List; @@ -12,5 +14,9 @@ public interface MallRefundRecordService extends IService { void create(MallRefundRecord mallRefundRecord); + void updateStatus(MallRefundRecord mallRefundRecord); + List selectByLinkId(MallRefundRecord mallRefundRecord); + + IPage selectPageVO(MallRefundRecordPageQuery q); } diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/mybatis/MallDeliveryOrderServiceImpl.java b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/mybatis/MallDeliveryOrderServiceImpl.java index 8d6a2e2e..f6bd22aa 100644 --- a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/mybatis/MallDeliveryOrderServiceImpl.java +++ b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/mybatis/MallDeliveryOrderServiceImpl.java @@ -3,13 +3,12 @@ package cc.hiver.mall.serviceimpl.mybatis; import cc.hiver.mall.dao.mapper.MallDeliveryOrderMapper; import cc.hiver.mall.dao.mapper.MallOrderGoodsMapper; import cc.hiver.mall.dao.mapper.MallOrderGroupMapper; -import cc.hiver.mall.entity.MallDeliveryOrder; -import cc.hiver.mall.entity.MallOrder; -import cc.hiver.mall.entity.MallOrderGoods; -import cc.hiver.mall.entity.MallOrderGroup; +import cc.hiver.mall.entity.*; import cc.hiver.mall.pojo.query.MallDeliveryOrderPageQuery; +import cc.hiver.mall.pojo.query.MallRefundRecordPageQuery; import cc.hiver.mall.service.mybatis.MallDeliveryOrderService; import cc.hiver.mall.service.mybatis.MallOrderService; +import cc.hiver.mall.service.mybatis.MallRefundRecordService; import cc.hiver.mall.utils.MerchantOrderSeqUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; @@ -23,10 +22,7 @@ import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import java.util.Arrays; -import java.util.Date; -import java.util.List; -import java.util.Map; +import java.util.*; /** * 配送订单 Service 实现 @@ -48,6 +44,8 @@ public class MallDeliveryOrderServiceImpl extends ServiceImpl pageDelivery(MallDeliveryOrderPageQuery q) { if (Boolean.TRUE.equals(q.getHallOnly())) { - q.setPageSize(20); + q.setPageSize(PAGE_SIZE_TWENTY); } IPage page = new Page<>(q.getPageNum(), q.getPageSize()); page = this.baseMapper.selectPageVO(page, q); @@ -75,26 +77,8 @@ public class MallDeliveryOrderServiceImpl extends ServiceImpl records = page.getRecords(); - if (records != null && !records.isEmpty()) { - // 1. 收集所有订单ID - List orderIds = records.stream() - .map(MallDeliveryOrder::getOrderId) - .collect(java.util.stream.Collectors.toList()); - - // 2. 一次 IN 查询所有商品明细 - List allGoods = mallOrderGoodsMapper.selectByOrderIds(orderIds); - - // 3. 按 orderId 分组 - java.util.Map> goodsMap = allGoods.stream() - .collect(java.util.stream.Collectors.groupingBy(MallOrderGoods::getOrderId)); - - // 4. 组装到每个 VO - for (MallDeliveryOrder vo : records) { - vo.setGoodsList(goodsMap.getOrDefault(vo.getOrderId(), java.util.Collections.emptyList())); - } - } + // 批量查询订单商品明细,避免 N+1 问题,处理面对面拼团子订单 + assembleOrderGoodsForDeliveries(page.getRecords()); return page; } @@ -103,26 +87,8 @@ public class MallDeliveryOrderServiceImpl extends ServiceImpl pageDeliveryByStatus(MallDeliveryOrderPageQuery q) { IPage page = new Page<>(q.getPageNum(), q.getPageSize()); page = this.baseMapper.selectPageVOByStatus(page,q); - // 批量查询订单商品明细,避免 N+1 问题 - List records = page.getRecords(); - if (records != null && !records.isEmpty()) { - // 1. 收集所有订单ID - List orderIds = records.stream() - .map(MallDeliveryOrder::getOrderId) - .collect(java.util.stream.Collectors.toList()); - - // 2. 一次 IN 查询所有商品明细 - List allGoods = mallOrderGoodsMapper.selectByOrderIds(orderIds); - - // 3. 按 orderId 分组 - java.util.Map> goodsMap = allGoods.stream() - .collect(java.util.stream.Collectors.groupingBy(MallOrderGoods::getOrderId)); - - // 4. 组装到每个 - for (MallDeliveryOrder vo : records) { - vo.setGoodsList(goodsMap.getOrDefault(vo.getOrderId(), java.util.Collections.emptyList())); - } - } + // 批量查询订单商品明细,避免 N+1 问题,处理面对面拼团子订单 + assembleOrderGoodsForDeliveries(page.getRecords()); return page; } @@ -305,6 +271,74 @@ public class MallDeliveryOrderServiceImpl extends ServiceImpl records) { + if (records == null || records.isEmpty()) { + return; + } + + // 1. 收集所有基本的订单ID,使用 Set 防止重复查询 + java.util.Set allOrderIdsToQuery = new java.util.HashSet<>(); + for (MallDeliveryOrder record : records) { + if (StringUtils.isNotBlank(record.getOrderId())) { + allOrderIdsToQuery.add(record.getOrderId()); + } + } + + // 2. 收集所有包含 groupId 的记录(针对面对面拼团情况) + List groupIds = records.stream() + .map(MallDeliveryOrder::getGroupId) + .filter(StringUtils::isNotBlank) + .distinct() + .collect(java.util.stream.Collectors.toList()); + + java.util.Map groupMap = new java.util.HashMap<>(); + if (!groupIds.isEmpty()) { + List groups = mallOrderGroupMapper.selectBatchIds(groupIds); + if (groups != null) { + for (MallOrderGroup group : groups) { + groupMap.put(group.getId(), group); + // 仅当是面对面拼团时,统一获取该团下的所有商品明细 + if (group.getIsFace() != null && group.getIsFace() == 1 && StringUtils.isNotBlank(group.getGroupOrderIds())) { + allOrderIdsToQuery.addAll(Arrays.asList(group.getGroupOrderIds().split(","))); + } + } + } + } + + if (allOrderIdsToQuery.isEmpty()) { + return; + } + + // 3. 一次 IN 查询所有商品明细 + List allGoods = mallOrderGoodsMapper.selectByOrderIds(new java.util.ArrayList<>(allOrderIdsToQuery)); + + // 4. 按 orderId 分组 + java.util.Map> goodsMap = allGoods.stream() + .collect(java.util.stream.Collectors.groupingBy(MallOrderGoods::getOrderId)); + + // 5. 将商品明细组装到每个配送单 (MallDeliveryOrder) + for (MallDeliveryOrder vo : records) { + java.util.Set targetOrderIds = new java.util.HashSet<>(); + if (StringUtils.isNotBlank(vo.getOrderId())) { + targetOrderIds.add(vo.getOrderId()); + } + if (StringUtils.isNotBlank(vo.getGroupId()) && groupMap.containsKey(vo.getGroupId())) { + MallOrderGroup group = groupMap.get(vo.getGroupId()); + if (group.getIsFace() != null && group.getIsFace() == 1 && StringUtils.isNotBlank(group.getGroupOrderIds())) { + targetOrderIds.addAll(Arrays.asList(group.getGroupOrderIds().split(","))); + } + } + + List voGoodsList = new java.util.ArrayList<>(); + for (String oid : targetOrderIds) { + if (StringUtils.isNotBlank(oid)) { + voGoodsList.addAll(goodsMap.getOrDefault(oid, java.util.Collections.emptyList())); + } + } + vo.setGoodsList(voGoodsList); + } + } + @Override public long countWaitGrabOrders(int deliveryType) { com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper query = new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<>(); @@ -320,7 +354,24 @@ public class MallDeliveryOrderServiceImpl extends ServiceImpl> countOrdersByStatus(String workerId) { - return this.baseMapper.countOrdersByStatus(workerId); + public List> countOrdersByStatus(String workerId) { + List> returnList = this.baseMapper.countOrdersByStatus(workerId); + MallRefundRecordPageQuery q = new MallRefundRecordPageQuery(); + q.setPageSize(PAGE_SIZE); + IPage page = new Page<>(q.getPageNum(), q.getPageSize()); + q.setLinkId(workerId); + List statusList = new ArrayList<>(); + //查待售后待退款数 + statusList.add(STATUS_WAIT_ACCEPT); + statusList.add(STATUS_DONE); + q.setStatusList(statusList); + IPage result = mallRefundRecordService.selectPageVO(q); + if(result != null){ + Map newRecord = new HashMap<>(); + newRecord.put("status", STATUS_DONE); // 状态 + newRecord.put("orderCount", result.getRecords().size()); + returnList.add(newRecord); + } + return returnList; } } diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/mybatis/MallOrderGroupServiceImpl.java b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/mybatis/MallOrderGroupServiceImpl.java index add7c0bf..9a119fbf 100644 --- a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/mybatis/MallOrderGroupServiceImpl.java +++ b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/mybatis/MallOrderGroupServiceImpl.java @@ -234,7 +234,7 @@ public class MallOrderGroupServiceImpl extends ServiceImpl goodsList = mallOrderGoodsMapper.selectByOrderId(order.getId()); if (goodsList == null || goodsList.isEmpty()) return; List returnList = goodsList.stream() diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/mybatis/MallOrderServiceImpl.java b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/mybatis/MallOrderServiceImpl.java index 469a7a19..a8739534 100644 --- a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/mybatis/MallOrderServiceImpl.java +++ b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/mybatis/MallOrderServiceImpl.java @@ -1282,7 +1282,7 @@ public class MallOrderServiceImpl extends ServiceImpl goodsList = mallOrderGoodsMapper.selectByOrderId(order.getId()); if (goodsList == null || goodsList.isEmpty()) return; List returnList = goodsList.stream() diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/mybatis/MallRefundRecordServiceImpl.java b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/mybatis/MallRefundRecordServiceImpl.java index 974305a3..f2779b37 100644 --- a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/mybatis/MallRefundRecordServiceImpl.java +++ b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/mybatis/MallRefundRecordServiceImpl.java @@ -1,18 +1,27 @@ package cc.hiver.mall.serviceimpl.mybatis; import cc.hiver.core.common.utils.SnowFlakeUtil; +import cc.hiver.mall.dao.mapper.MallDeliveryOrderMapper; +import cc.hiver.mall.dao.mapper.MallOrderMapper; import cc.hiver.mall.dao.mapper.MallRefundRecordMapper; import cc.hiver.mall.dao.mapper.MallReturnOrderGoodsMapper; +import cc.hiver.mall.entity.MallDeliveryOrder; import cc.hiver.mall.entity.MallOrder; import cc.hiver.mall.entity.MallRefundRecord; import cc.hiver.mall.entity.MallReturnOrderGoods; +import cc.hiver.mall.pojo.query.MallRefundRecordPageQuery; import cc.hiver.mall.service.mybatis.MallOrderService; import cc.hiver.mall.service.mybatis.MallRefundRecordService; +import cc.hiver.mall.utils.WechatPayUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import java.math.BigDecimal; import java.util.Date; import java.util.List; @@ -23,6 +32,21 @@ import java.util.List; public class MallRefundRecordServiceImpl extends ServiceImpl implements MallRefundRecordService { + // 订单状态常量数据库存储为 "01",用数字10代替 + private static final int STATUS_WAIT_SHOP = 1; + private static final int STATUS_WAIT_PICKUP = 3; + private static final int STATUS_DELIVERING = 4; + private static final int STATUS_END = 5; + private static final int STATUS_REFUNDED = 8; + private static final int STATUS_LAST_REFUNDED = 12; + + // 配送方式常量// 外卖 + private static final int DELIVERY_TYPE_SELF = 2;// 外 + private static final int DELIVERY_TYPE_PEISONG = 1; + + private static final int PAGESIZE = 10; + private static final int PAGENUM = 1; + @Autowired private MallRefundRecordMapper mallRefundRecordMapper; @@ -32,6 +56,18 @@ public class MallRefundRecordServiceImpl extends ServiceImpl uw = new LambdaUpdateWrapper<>(); + uw.eq(MallRefundRecord::getId, mallRefundRecord.getId()) + .set(MallRefundRecord::getSuccessTime, new Date()) + .set(MallRefundRecord::getStatus, mallRefundRecord.getStatus()); + this.update(null, uw); + Boolean isTuiKuan = true; + if(mallRefundRecord.getStatus() > 3){ + //处理售后 + isTuiKuan = false; + } + //更新订单status、 配送单isReturn + if(mallRefundRecord.getRefundTypeStatus() != null && mallRefundRecord.getRefundTypeStatus() == 3){ + //商家和配送员都有原因,需要判断另外角色处理了没再判断是否更新订单的状态 + IPage page = new Page<>(PAGENUM, PAGESIZE); + MallRefundRecordPageQuery q = new MallRefundRecordPageQuery(); + q.setOrder(mallRefundRecord.getOrderId()); + IPage result = this.baseMapper.selectPageVO(page, q); + boolean hasEnd = result.getRecords().stream() + .anyMatch(item -> item.getStatus() == 3 || item.getStatus() == 0); + boolean hasReject = result.getRecords().stream() + .anyMatch(item -> item.getStatus() == 2 || item.getStatus() == 5); + if(isTuiKuan){ + //都处理了 + if(!hasEnd){ + //都同意退款 + if(!hasReject){ + //同意退款 + //MallOrder order = mallOrderService.getById(mallRefundRecord.getOrderId()); + updateOrderStatus(mallRefundRecord.getOrderId(), STATUS_REFUNDED); + if(mallRefundRecord.getDeliveryType() == DELIVERY_TYPE_PEISONG){ + //更新配送单 + LambdaUpdateWrapper duw = new LambdaUpdateWrapper<>(); + duw.eq(MallDeliveryOrder::getOrderId, mallRefundRecord.getOrderId()) + .set(MallDeliveryOrder::getStatus, 4); + mallDeliveryOrderMapper.update(null, duw); + } + BigDecimal totalRefund = result.getRecords().stream() + .map(item -> item.getRefundAmount()) // 提取 BigDecimal 金额 + .reduce(BigDecimal.ZERO, BigDecimal::add); + wechatPayUtil.refund(mallRefundRecord.getOrderId(), totalRefund.multiply(new BigDecimal(100)).longValue(), totalRefund.multiply(new BigDecimal(100)).longValue()); + }else{ + //拒绝退款 + //MallOrder order = mallOrderService.getById(mallRefundRecord.getOrderId()); + //如果是自取订单,则恢复待消费状态 + if(mallRefundRecord.getDeliveryType() == DELIVERY_TYPE_SELF){ + updateOrderStatusAndReturn(mallRefundRecord.getOrderId(), STATUS_WAIT_PICKUP); + }else{ + MallDeliveryOrder delivery = findDeliveryByOrderId(mallRefundRecord.getOrderId()); + if(delivery == null){ + //去查团长的配送单 + } + if(delivery.getStatus() == STATUS_WAIT_SHOP){ + updateOrderStatusAndReturn(mallRefundRecord.getOrderId(), STATUS_WAIT_PICKUP); + }else if(delivery.getStatus() == DELIVERY_TYPE_SELF){ + updateOrderStatusAndReturn(mallRefundRecord.getOrderId(), STATUS_DELIVERING); + } + //更新配送单isReturn + LambdaUpdateWrapper duw = new LambdaUpdateWrapper<>(); + duw.eq(MallDeliveryOrder::getOrderId, mallRefundRecord.getOrderId()) + .set(MallDeliveryOrder::getIsReturn, 0); + mallDeliveryOrderMapper.update(null, duw); + } + } + } + }else{ + //售后 + if(mallRefundRecord.getStatus() == 4){ + //同意售后 + MallOrder order = mallOrderService.getById(mallRefundRecord.getOrderId()); + wechatPayUtil.refund(mallRefundRecord.getOrderId(),order.getTotalAmount().multiply(new BigDecimal(100)).longValue(), mallRefundRecord.getRefundAmount().multiply(new BigDecimal(100)).longValue()); + } + //都处理了 + if(!hasEnd){ + //更新订单状态已售后 + updateOrderStatus(mallRefundRecord.getOrderId(), STATUS_LAST_REFUNDED); + } + } + }else{ + if(isTuiKuan){ + //拒绝退款 + if(mallRefundRecord.getStatus() == 2){ + //MallOrder order = mallOrderService.getById(mallRefundRecord.getOrderId()); + //如果是自取订单,则恢复待消费状态 + if(mallRefundRecord.getDeliveryType() == DELIVERY_TYPE_SELF){ + updateOrderStatusAndReturn(mallRefundRecord.getOrderId(), STATUS_WAIT_PICKUP); + }else{ + MallDeliveryOrder delivery = findDeliveryByOrderId(mallRefundRecord.getOrderId()); + if(delivery == null){ + //去查团长的配送单 + } + if(delivery.getStatus() == STATUS_WAIT_SHOP){ + updateOrderStatusAndReturn(mallRefundRecord.getOrderId(), STATUS_WAIT_PICKUP); + }else if(delivery.getStatus() == DELIVERY_TYPE_SELF){ + updateOrderStatusAndReturn(mallRefundRecord.getOrderId(), STATUS_DELIVERING); + } + //更新配送单isReturn + LambdaUpdateWrapper duw = new LambdaUpdateWrapper<>(); + duw.eq(MallDeliveryOrder::getOrderId, mallRefundRecord.getOrderId()) + .set(MallDeliveryOrder::getIsReturn, 0); + mallDeliveryOrderMapper.update(null, duw); + } + }else{ + //同意退款 + //MallOrder order = mallOrderService.getById(mallRefundRecord.getOrderId()); + updateOrderStatus(mallRefundRecord.getOrderId(), STATUS_REFUNDED); + if(mallRefundRecord.getDeliveryType() == DELIVERY_TYPE_PEISONG){ + //更新配送单 + LambdaUpdateWrapper duw = new LambdaUpdateWrapper<>(); + duw.eq(MallDeliveryOrder::getOrderId, mallRefundRecord.getOrderId()) + .set(MallDeliveryOrder::getStatus, 4); + mallDeliveryOrderMapper.update(null, duw); + } + wechatPayUtil.refund(mallRefundRecord.getOrderId(), mallRefundRecord.getRefundAmount().multiply(new BigDecimal(100)).longValue(), mallRefundRecord.getRefundAmount().multiply(new BigDecimal(100)).longValue()); + } + }else{ + //售后 + if(mallRefundRecord.getStatus() == 4){ + //同意售后 + MallOrder order = mallOrderService.getById(mallRefundRecord.getOrderId()); + updateOrderStatus(mallRefundRecord.getOrderId(), STATUS_LAST_REFUNDED); + wechatPayUtil.refund(mallRefundRecord.getOrderId(), order.getTotalAmount().multiply(new BigDecimal(100)).longValue(), mallRefundRecord.getRefundAmount().multiply(new BigDecimal(100)).longValue()); + }else{ + //订单还是变成已完成状态 + updateOrderStatus(mallRefundRecord.getOrderId(), STATUS_END); + } + } + } + } + + /** + * 更新订单状态 + */ + private void updateOrderStatus(String orderId, int status) { + LambdaUpdateWrapper uw = new LambdaUpdateWrapper<>(); + uw.eq(MallOrder::getId, orderId).set(MallOrder::getStatus, status); + mallOrderMapper.update(null, uw); + } + + private void updateOrderStatusAndReturn(String orderId, int status) { + LambdaUpdateWrapper uw = new LambdaUpdateWrapper<>(); + uw.eq(MallOrder::getId, orderId).set(MallOrder::getStatus, status); + mallOrderMapper.update(null, uw); + } + + /** + * 根据订单ID查找配送单 + */ + private MallDeliveryOrder findDeliveryByOrderId(String orderId) { + LambdaQueryWrapper dq = new LambdaQueryWrapper<>(); + dq.eq(MallDeliveryOrder::getOrderId, orderId).last("LIMIT 1"); + return mallDeliveryOrderMapper.selectOne(dq); + } + @Override public List selectByLinkId(MallRefundRecord mallRefundRecord) { LambdaUpdateWrapper uw = new LambdaUpdateWrapper<>(); @@ -86,4 +277,41 @@ public class MallRefundRecordServiceImpl extends ServiceImpl mallRefundRecords = this.list(uw); return mallRefundRecords; } + + @Override + public IPage selectPageVO(MallRefundRecordPageQuery q) { + IPage page = new Page<>(q.getPageNum(), q.getPageSize()); + IPage result = this.baseMapper.selectPageVO(page, q); + // 批量查询售后商品明细,避免 N+1 问题 + List records = result.getRecords(); + if (records != null && !records.isEmpty()) { + // 1. 收集所有订单ID + List orderIds = records.stream() + .map(MallRefundRecord::getOrderId) + .collect(java.util.stream.Collectors.toList()); + + // 2. 一次 IN 查询所有商品明细 + LambdaQueryWrapper qw = new LambdaQueryWrapper<>(); + qw.in(MallReturnOrderGoods::getOrderId, orderIds); + List allGoods = mallReturnOrderGoodsMapper.selectList(qw); + + // 3. 按 orderId 分组 + java.util.Map> goodsMap = allGoods.stream() + .collect(java.util.stream.Collectors.groupingBy(MallReturnOrderGoods::getOrderId)); + + // 4. 批量查询订单商品明细,避免 N+1 问题 + LambdaQueryWrapper qwOrder = new LambdaQueryWrapper<>(); + qwOrder.in(MallOrder::getId, orderIds); + List allOrders = mallOrderMapper.selectList(qwOrder); + + java.util.Map> orderMap = allOrders.stream() + .collect(java.util.stream.Collectors.groupingBy(MallOrder::getId)); + // 4. 组装到每个 VO + for (MallRefundRecord vo : records) { + vo.setItems(goodsMap.getOrDefault(vo.getOrderId(), java.util.Collections.emptyList())); + vo.setMallOrder(orderMap.getOrDefault(vo.getOrderId(), new java.util.ArrayList<>()).get(0)); + } + } + return result; + } } diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/utils/WechatPayUtil.java b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/utils/WechatPayUtil.java index 10fce1ed..8268cf99 100644 --- a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/utils/WechatPayUtil.java +++ b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/utils/WechatPayUtil.java @@ -27,7 +27,7 @@ public class WechatPayUtil { private final OkHttpClient httpClient = new OkHttpClient(); private final ObjectMapper objectMapper = new ObjectMapper(); - public Boolean refund(String orderId,long totalFee) { + public Boolean refund(String orderId,long totalFee,long refundFee) { try { // 2. 构建退款请求参数 // 原支付交易号(与下单时一致,带 ORDER_ 前缀) @@ -44,7 +44,7 @@ public class WechatPayUtil { reqBody.put("reason", reason); Map amountMap = new HashMap<>(); - amountMap.put("refund", totalFee); + amountMap.put("refund", refundFee); amountMap.put("total", totalFee); amountMap.put("currency", "CNY"); reqBody.put("amount", amountMap); diff --git a/hiver-modules/hiver-mall/src/main/resources/mapper/MallRefundRecordMapper.xml b/hiver-modules/hiver-mall/src/main/resources/mapper/MallRefundRecordMapper.xml index 14c000c5..c9c52418 100644 --- a/hiver-modules/hiver-mall/src/main/resources/mapper/MallRefundRecordMapper.xml +++ b/hiver-modules/hiver-mall/src/main/resources/mapper/MallRefundRecordMapper.xml @@ -18,4 +18,23 @@ + +