From 00f032db3737e27c1dc834b85615ddcbeaca871d Mon Sep 17 00:00:00 2001 From: wangfukang <15630117759@163.com> Date: Sun, 12 Jul 2026 17:53:10 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AF=B9=E6=8E=A5=E6=8B=BC=E5=9B=A2=E6=95=B0?= =?UTF-8?q?=E6=8D=AE1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hiver-admin/test-output/test-report.html | 16 +- .../constant/DealingsRecordConstant.java | 2 +- .../mall/bill/vo/CustomerBillQueryVo.java | 5 +- .../controller/AdminSettlementController.java | 216 +++++++++++- .../cc/hiver/mall/entity/DealingsRecord.java | 9 +- .../hiver/mall/entity/MallRefundRecord.java | 2 + .../mall/entity/MallSettlementRecord.java | 5 + .../mall/quartz/MerchantSettlementTask.java | 228 +++++++------ .../mybatis/MallDeliveryOrderServiceImpl.java | 26 +- .../mybatis/MallOrderServiceImpl.java | 133 +++++--- .../mybatis/MallRefundRecordServiceImpl.java | 313 ++++++++++-------- .../MallSettlementRecordServiceImpl.java | 53 +-- .../mall_refund_record_settlement_amount.sql | 2 + .../resources/mapper/DealingsRecordMapper.xml | 19 +- .../mapper/MallRefundRecordMapper.xml | 1 + 15 files changed, 715 insertions(+), 315 deletions(-) create mode 100644 hiver-modules/hiver-mall/src/main/resources/db/mall_refund_record_settlement_amount.sql diff --git a/hiver-admin/test-output/test-report.html b/hiver-admin/test-output/test-report.html index 143b4939..a59f206d 100644 --- a/hiver-admin/test-output/test-report.html +++ b/hiver-admin/test-output/test-report.html @@ -35,7 +35,7 @@ Hiver
  • -ÆßÔÂ 08, 2026 11:47:38 +ÆßÔÂ 12, 2026 14:35:40
  • @@ -84,7 +84,7 @@

    passTest

    -

    11:47:39 ÉÏÎç / 0.029 secs

    +

    14:35:40 ÏÂÎç / 0.022 secs

    @@ -92,9 +92,9 @@
    #test-id=1
    passTest
    -07.08.2026 11:47:39 -07.08.2026 11:47:39 -0.029 secs +07.12.2026 14:35:40 +07.12.2026 14:35:40 +0.022 secs
    @@ -104,7 +104,7 @@ Pass - 11:47:39 + 14:35:40 Test passed @@ -128,13 +128,13 @@

    Started

    -

    ÆßÔÂ 08, 2026 11:47:38

    +

    ÆßÔÂ 12, 2026 14:35:40

    Ended

    -

    ÆßÔÂ 08, 2026 11:47:39

    +

    ÆßÔÂ 12, 2026 14:35:40

    diff --git a/hiver-core/src/main/java/cc/hiver/core/common/constant/DealingsRecordConstant.java b/hiver-core/src/main/java/cc/hiver/core/common/constant/DealingsRecordConstant.java index dd0a7b53..fd68f378 100644 --- a/hiver-core/src/main/java/cc/hiver/core/common/constant/DealingsRecordConstant.java +++ b/hiver-core/src/main/java/cc/hiver/core/common/constant/DealingsRecordConstant.java @@ -15,7 +15,7 @@ public interface DealingsRecordConstant { /** * */ - String[] TYPE_REMARK = {"é…é€è®¢å•佣金","å”®åŽé€€æ¬¾","é…逿ޒå奖励","商家æçް","é…é€å‘˜æçް","å…å•奖励","商家结算","用户æçް","白嫖中奖","学院排ä½èµ›æŽ’å奖励"}; + String[] TYPE_REMARK = {"é…é€è®¢å•佣金","å”®åŽé€€æ¬¾","é…逿ޒå奖励","商家æçް","é…é€å‘˜æçް","å…å•奖励","商家结算","用户æçް","白嫖中奖","学院排ä½èµ›æŽ’å奖励","é…é€å‘˜åŽŸå› é€€æ¬¾æ‰£æ¬¾","商家原因退款补å‘é…é€ä½£é‡‘","商家退款/å”®åŽæ‰£æ¬¾"}; /** *交易类型:0:增加 1 æçް 2消费 3å”®åŽ diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/bill/vo/CustomerBillQueryVo.java b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/bill/vo/CustomerBillQueryVo.java index ffccd6ed..6548e756 100644 --- a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/bill/vo/CustomerBillQueryVo.java +++ b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/bill/vo/CustomerBillQueryVo.java @@ -30,6 +30,9 @@ public class CustomerBillQueryVo extends HiverBasePageQuery { @ApiModelProperty(value = "ç»“æŸæ—¶é—´") private String endDate; - @ApiModelProperty(value = "ç»“æŸæ—¶é—´") + @ApiModelProperty(value = "交易方å¼/附言") private String dealingsWay; + + @ApiModelProperty(value = "排除的交易方å¼/附言") + private String excludeDealingsWay; } diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/controller/AdminSettlementController.java b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/controller/AdminSettlementController.java index 811a26cc..b2e238f7 100644 --- a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/controller/AdminSettlementController.java +++ b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/controller/AdminSettlementController.java @@ -2,9 +2,11 @@ package cc.hiver.mall.controller; import cc.hiver.core.common.utils.ResultUtil; import cc.hiver.core.common.vo.Result; +import cc.hiver.mall.entity.MallOrder; import cc.hiver.mall.entity.MallSettlementRecord; import cc.hiver.mall.entity.Shop; import cc.hiver.mall.service.ShopService; +import cc.hiver.mall.service.mybatis.MallOrderService; import cc.hiver.mall.service.mybatis.MallSettlementRecordService; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; @@ -22,8 +24,10 @@ import org.springframework.web.bind.annotation.RestController; import java.math.BigDecimal; import java.util.ArrayList; +import java.util.Comparator; import java.util.List; import java.util.Map; +import java.util.function.Function; import java.util.stream.Collectors; @Slf4j @@ -38,6 +42,9 @@ public class AdminSettlementController { @Autowired private ShopService shopService; + @Autowired + private MallOrderService mallOrderService; + @Data public static class SettlementQuery { private String shopId; @@ -93,6 +100,16 @@ public class AdminSettlementController { private String regionId; @ApiModelProperty(value = "结算日期,格å¼yyyy-MM-dd") private String settlementDate; + @ApiModelProperty(value = "ç»“ç®—çŠ¶æ€ 0待结算 1已结算") + private Integer status = 0; + @ApiModelProperty(value = "开始日期,格å¼yyyy-MM-dd") + private String startDate; + @ApiModelProperty(value = "ç»“æŸæ—¥æœŸï¼Œæ ¼å¼yyyy-MM-dd") + private String endDate; + @ApiModelProperty(value = "页ç ") + private int pageNumber = 1; + @ApiModelProperty(value = "æ¯é¡µæ¡æ•°") + private int pageSize = 10; } @Data @@ -109,24 +126,45 @@ public class AdminSettlementController { private BigDecimal totalSettlementAmount; @ApiModelProperty(value = "记录数") private Integer recordCount; + @ApiModelProperty(value = "è´¦å•æ—¥æœŸ") + private String billTime; + @ApiModelProperty(value = "æ­£å‘结算记录数") + private Integer positiveCount; + @ApiModelProperty(value = "退款/å”®åŽæ‰£æ¬¾è®°å½•æ•°") + private Integer negativeCount; + @ApiModelProperty(value = "æ­£å‘结算金é¢") + private BigDecimal positiveSettlementAmount; + @ApiModelProperty(value = "扣款结算金é¢") + private BigDecimal negativeSettlementAmount; + @ApiModelProperty(value = "待结算金é¢") + private BigDecimal pendingSettlementAmount; + @ApiModelProperty(value = "已结算金é¢") + private BigDecimal confirmedSettlementAmount; + @ApiModelProperty(value = "记录状æ€") + private Integer status; } @PostMapping("/summaryList") @ApiOperation(value = "按区域和日期获å–商家结算汇总") - public Result> summaryList(@RequestBody SummaryQuery query) { + public Result> summaryList(@RequestBody SummaryQuery query) { if (StringUtils.isBlank(query.getRegionId()) || StringUtils.isBlank(query.getSettlementDate())) { return ResultUtil.error("区域ID或日期ä¸èƒ½ä¸ºç©º"); } LambdaQueryWrapper qw = new LambdaQueryWrapper<>(); qw.eq(MallSettlementRecord::getRegionId, query.getRegionId()); - qw.eq(MallSettlementRecord::getStatus, 0); + qw.eq(MallSettlementRecord::getStatus, query.getStatus() == null ? 0 : query.getStatus()); qw.apply("DATE(create_time) = {0}", query.getSettlementDate()); List list = mallSettlementRecordService.list(qw); // Group by shopId Map> map = list.stream().collect(Collectors.groupingBy(MallSettlementRecord::getShopId)); + List shopIds = map.keySet().stream() + .filter(StringUtils::isNotBlank) + .collect(Collectors.toList()); + Map shopMap = shopIds.isEmpty() ? new java.util.HashMap<>() : shopService.getRepository().findAllById(shopIds).stream() + .collect(Collectors.toMap(Shop::getId, Function.identity(), (a, b) -> a)); List result = new ArrayList<>(); for (Map.Entry> entry : map.entrySet()) { @@ -136,7 +174,7 @@ public class AdminSettlementController { SettlementSummaryVo vo = new SettlementSummaryVo(); vo.setShopId(shopId); - Shop shop = shopService.findById(shopId); + Shop shop = shopMap.get(shopId); if (shop != null) { vo.setShopName(shop.getShopName()); } @@ -144,20 +182,190 @@ public class AdminSettlementController { BigDecimal totalBase = BigDecimal.ZERO; BigDecimal totalComm = BigDecimal.ZERO; BigDecimal totalSettlement = BigDecimal.ZERO; + BigDecimal positiveSettlement = BigDecimal.ZERO; + BigDecimal negativeSettlement = BigDecimal.ZERO; + int positiveCount = 0; + int negativeCount = 0; for (MallSettlementRecord r : shopRecords) { if (r.getBaseAmount() != null) totalBase = totalBase.add(r.getBaseAmount()); if (r.getCommissionAmount() != null) totalComm = totalComm.add(r.getCommissionAmount()); if (r.getSettlementAmount() != null) totalSettlement = totalSettlement.add(r.getSettlementAmount()); + if (r.getType() != null && r.getType() == 2) { + negativeCount++; + if (r.getSettlementAmount() != null) negativeSettlement = negativeSettlement.add(r.getSettlementAmount()); + } else { + positiveCount++; + if (r.getSettlementAmount() != null) positiveSettlement = positiveSettlement.add(r.getSettlementAmount()); + } } + vo.setBillTime(query.getSettlementDate()); vo.setTotalBaseAmount(totalBase); vo.setTotalCommissionAmount(totalComm); vo.setTotalSettlementAmount(totalSettlement); vo.setRecordCount(shopRecords.size()); + vo.setPositiveCount(positiveCount); + vo.setNegativeCount(negativeCount); + vo.setPositiveSettlementAmount(positiveSettlement); + vo.setNegativeSettlementAmount(negativeSettlement); + vo.setStatus(query.getStatus() == null ? 0 : query.getStatus()); + if (vo.getStatus() == 0) { + vo.setPendingSettlementAmount(totalSettlement); + vo.setConfirmedSettlementAmount(BigDecimal.ZERO); + } else { + vo.setPendingSettlementAmount(BigDecimal.ZERO); + vo.setConfirmedSettlementAmount(totalSettlement); + } + + result.add(vo); + } + result.sort(Comparator.comparing(vo -> StringUtils.defaultString(vo.getShopName(), vo.getShopId()))); + return new ResultUtil>().setData(buildPage(result, query)); + } + + @Data + public static class DateSummaryVo { + @ApiModelProperty(value = "è´¦å•æ—¥æœŸ") + private String billTime; + @ApiModelProperty(value = "商家数") + private Integer shopCount; + @ApiModelProperty(value = "结算记录数") + private Integer recordCount; + @ApiModelProperty(value = "结算基数") + private BigDecimal totalBaseAmount; + @ApiModelProperty(value = "平尿н佣") + private BigDecimal totalCommissionAmount; + @ApiModelProperty(value = "商家结算净é¢") + private BigDecimal totalSettlementAmount; + @ApiModelProperty(value = "æ­£å‘结算金é¢") + private BigDecimal positiveSettlementAmount; + @ApiModelProperty(value = "退款/å”®åŽæ‰£æ¬¾é‡‘é¢") + private BigDecimal negativeSettlementAmount; + @ApiModelProperty(value = "状æ€") + private Integer status; + } + @PostMapping("/dateSummaryList") + @ApiOperation(value = "按日期获å–结算汇总") + public Result> dateSummaryList(@RequestBody SummaryQuery query) { + if (StringUtils.isBlank(query.getRegionId())) { + return ResultUtil.error("区域IDä¸èƒ½ä¸ºç©º"); + } + LambdaQueryWrapper qw = new LambdaQueryWrapper<>(); + qw.eq(MallSettlementRecord::getRegionId, query.getRegionId()); + qw.eq(MallSettlementRecord::getStatus, query.getStatus() == null ? 0 : query.getStatus()); + if (StringUtils.isNotBlank(query.getStartDate())) { + qw.apply("DATE(create_time) >= {0}", query.getStartDate()); + } + if (StringUtils.isNotBlank(query.getEndDate())) { + qw.apply("DATE(create_time) <= {0}", query.getEndDate()); + } + List list = mallSettlementRecordService.list(qw); + Map> byDate = list.stream() + .collect(Collectors.groupingBy(r -> new java.text.SimpleDateFormat("yyyy-MM-dd").format(r.getCreateTime()))); + List result = new ArrayList<>(); + for (Map.Entry> entry : byDate.entrySet()) { + DateSummaryVo vo = new DateSummaryVo(); + vo.setBillTime(entry.getKey()); + vo.setStatus(query.getStatus() == null ? 0 : query.getStatus()); + vo.setShopCount((int) entry.getValue().stream().map(MallSettlementRecord::getShopId).distinct().count()); + vo.setRecordCount(entry.getValue().size()); + fillAmounts(vo, entry.getValue()); result.add(vo); } - return new ResultUtil>().setData(result); + result.sort(Comparator.comparing(DateSummaryVo::getBillTime).reversed()); + return new ResultUtil>().setData(buildPage(result, query)); + } + + private Page buildPage(List list, SummaryQuery query) { + int pageNumber = Math.max(query.getPageNumber(), 1); + int pageSize = Math.max(query.getPageSize(), 10); + int fromIndex = Math.min((pageNumber - 1) * pageSize, list.size()); + int toIndex = Math.min(fromIndex + pageSize, list.size()); + Page page = new Page<>(pageNumber, pageSize, list.size()); + page.setRecords(list.subList(fromIndex, toIndex)); + return page; + } + + @Data + public static class DetailQuery { + private String regionId; + private String settlementDate; + private String shopId; + private Integer status; + } + + @PostMapping("/detailList") + @ApiOperation(value = "按日期/商家获å–结算明细") + public Result> detailList(@RequestBody DetailQuery query) { + LambdaQueryWrapper qw = new LambdaQueryWrapper<>(); + if (StringUtils.isNotBlank(query.getRegionId())) { + qw.eq(MallSettlementRecord::getRegionId, query.getRegionId()); + } + if (StringUtils.isNotBlank(query.getShopId())) { + qw.eq(MallSettlementRecord::getShopId, query.getShopId()); + } + if (query.getStatus() != null) { + qw.eq(MallSettlementRecord::getStatus, query.getStatus()); + } + if (StringUtils.isNotBlank(query.getSettlementDate())) { + qw.apply("DATE(create_time) = {0}", query.getSettlementDate()); + } + qw.orderByDesc(MallSettlementRecord::getCreateTime); + List list = mallSettlementRecordService.list(qw); + List shopIds = list.stream() + .map(MallSettlementRecord::getShopId) + .filter(StringUtils::isNotBlank) + .distinct() + .collect(Collectors.toList()); + Map shopMap = shopIds.isEmpty() ? new java.util.HashMap<>() : shopService.getRepository().findAllById(shopIds).stream() + .collect(Collectors.toMap(Shop::getId, Function.identity(), (a, b) -> a)); + + List orderIds = list.stream() + .map(MallSettlementRecord::getOrderId) + .filter(StringUtils::isNotBlank) + .distinct() + .collect(Collectors.toList()); + Map orderMap = orderIds.isEmpty() ? new java.util.HashMap<>() : mallOrderService.listByIds(orderIds).stream() + .collect(Collectors.toMap(MallOrder::getId, Function.identity(), (a, b) -> a)); + + for (MallSettlementRecord record : list) { + Shop shop = shopMap.get(record.getShopId()); + if (shop != null) { + record.setShopName(shop.getShopName()); + } + MallOrder order = orderMap.get(record.getOrderId()); + if (order != null) { + record.setOrderNumber(order.getNumberCode()); + record.setPayTime(order.getPayTime()); + } + } + return new ResultUtil>().setData(list); + } + + private void fillAmounts(DateSummaryVo vo, List records) { + BigDecimal totalBase = BigDecimal.ZERO; + BigDecimal totalComm = BigDecimal.ZERO; + BigDecimal totalSettlement = BigDecimal.ZERO; + BigDecimal positiveSettlement = BigDecimal.ZERO; + BigDecimal negativeSettlement = BigDecimal.ZERO; + for (MallSettlementRecord r : records) { + if (r.getBaseAmount() != null) totalBase = totalBase.add(r.getBaseAmount()); + if (r.getCommissionAmount() != null) totalComm = totalComm.add(r.getCommissionAmount()); + if (r.getSettlementAmount() != null) { + totalSettlement = totalSettlement.add(r.getSettlementAmount()); + if (r.getType() != null && r.getType() == 2) { + negativeSettlement = negativeSettlement.add(r.getSettlementAmount()); + } else { + positiveSettlement = positiveSettlement.add(r.getSettlementAmount()); + } + } + } + vo.setTotalBaseAmount(totalBase); + vo.setTotalCommissionAmount(totalComm); + vo.setTotalSettlementAmount(totalSettlement); + vo.setPositiveSettlementAmount(positiveSettlement); + vo.setNegativeSettlementAmount(negativeSettlement); } @Data diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/entity/DealingsRecord.java b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/entity/DealingsRecord.java index 32ce2930..dfad5aca 100644 --- a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/entity/DealingsRecord.java +++ b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/entity/DealingsRecord.java @@ -1,6 +1,7 @@ package cc.hiver.mall.entity; import cc.hiver.core.base.HiverBaseEntity; +import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableName; import com.fasterxml.jackson.annotation.JsonFormat; import io.swagger.annotations.ApiModel; @@ -13,6 +14,7 @@ import org.springframework.format.annotation.DateTimeFormat; import javax.persistence.Entity; import javax.persistence.Table; +import javax.persistence.Transient; import java.math.BigDecimal; import java.util.Date; @@ -49,7 +51,7 @@ public class DealingsRecord extends HiverBaseEntity { @ApiModelProperty(value = "金é¢") private BigDecimal amount; - @ApiModelProperty(value = "交易类型:0:增加 1 æçް 2消费") + @ApiModelProperty(value = "交易类型:0:增加 1 æçް 2消费 3å”®åŽ") private Integer dealingsType; @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") @@ -60,4 +62,9 @@ public class DealingsRecord extends HiverBaseEntity { @ApiModelProperty(value = "备注") private String remark; + @Transient + @TableField(exist = false) + @ApiModelProperty(value = "å…³è”用户手机å·") + private String mobile; + } 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 5c1a0989..659b1a8d 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 @@ -34,6 +34,8 @@ public class MallRefundRecord implements Serializable { private String linkId; @ApiModelProperty(value = "退款金é¢") private BigDecimal refundAmount; + @ApiModelProperty(value = "责任方结算/展示金é¢") + private BigDecimal settlementAmount; @ApiModelProperty(value = "退款原因") private String reason; @ApiModelProperty(value = "æ‹’ç»åŽŸå› ") diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/entity/MallSettlementRecord.java b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/entity/MallSettlementRecord.java index 83b66ff4..a1e97444 100644 --- a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/entity/MallSettlementRecord.java +++ b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/entity/MallSettlementRecord.java @@ -70,6 +70,11 @@ public class MallSettlementRecord implements Serializable { @ApiModelProperty(value = "订å•ç¼–å·(å¿«ç…§)") private String orderNumber; + @Transient + @TableField(exist = false) + @ApiModelProperty(value = "支付时间") + private Date payTime; + @Transient @TableField(exist = false) @ApiModelProperty(value = "店铺åç§°(å¿«ç…§)") diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/quartz/MerchantSettlementTask.java b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/quartz/MerchantSettlementTask.java index 772ac5aa..ba381768 100644 --- a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/quartz/MerchantSettlementTask.java +++ b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/quartz/MerchantSettlementTask.java @@ -3,7 +3,10 @@ package cc.hiver.mall.quartz; import cc.hiver.core.entity.Worker; import cc.hiver.core.serviceimpl.WorkerServiceImpl; import cc.hiver.mall.dao.mapper.MallReturnOrderGoodsMapper; -import cc.hiver.mall.entity.*; +import cc.hiver.mall.entity.MallOrder; +import cc.hiver.mall.entity.MallRefundRecord; +import cc.hiver.mall.entity.MallSettlementRecord; +import cc.hiver.mall.entity.ShopTakeaway; import cc.hiver.mall.service.ShopService; import cc.hiver.mall.service.ShopTakeawayService; import cc.hiver.mall.service.mybatis.MallOrderService; @@ -46,7 +49,7 @@ public class MerchantSettlementTask { LambdaQueryWrapper qw = new LambdaQueryWrapper<>(); qw.in(MallOrder::getStatus, 5, 12); qw.eq(MallOrder::getSettlementStatus, 0); - qw.ne(MallOrder::getOtherOrder, 1); + qw.and(w -> w.isNull(MallOrder::getOtherOrder).or().in(MallOrder::getOtherOrder, 2, 3)); List orders = mallOrderService.list(qw); for (MallOrder order : orders) { @@ -60,15 +63,15 @@ public class MerchantSettlementTask { log.error("[MerchantSettlementTask] Error processing unsettled orders", e); } - // 2. Process Already Settled Orders with New Refunds + // 2. Process Approved Refunds / After-sales try { LambdaQueryWrapper refundQw = new LambdaQueryWrapper<>(); - refundQw.eq(MallRefundRecord::getStatus, 4); + refundQw.in(MallRefundRecord::getStatus, 1, 4); List refundRecords = mallRefundRecordService.list(refundQw); for (MallRefundRecord refund : refundRecords) { try { - processSettledRefund(refund); + processApprovedRefund(refund); } catch (Exception e) { log.error("[MerchantSettlementTask] Failed to process settled refund {}", refund.getId(), e); } @@ -100,97 +103,117 @@ public class MerchantSettlementTask { } private void processUnsettledOrder(MallOrder order) { + if (!isMerchantSettlementOrder(order)) { + return; + } LambdaQueryWrapper existsQw = new LambdaQueryWrapper<>(); existsQw.eq(MallSettlementRecord::getOrderId, order.getId()); existsQw.eq(MallSettlementRecord::getType, 1); + existsQw.isNull(MallSettlementRecord::getRefundId); long count = mallSettlementRecordService.count(existsQw); if (count > 0) return; // Skip if already pending confirmation - LambdaQueryWrapper shopQw = new LambdaQueryWrapper<>(); - shopQw.eq(ShopTakeaway::getShopId, order.getShopId()); - ShopTakeaway takeaway = shopTakeawayService.getOne(shopQw); - - BigDecimal commissionRate = BigDecimal.ZERO; - if (takeaway != null) { - if (order.getOrderType() != null && order.getOrderType() == 1) { - commissionRate = takeaway.getCommissionRateOne(); - } else if (order.getOrderType() != null && (order.getOrderType() == 2 || order.getOrderType() == 3)) { - commissionRate = takeaway.getCommissionRateMore(); - } + saveMerchantSettlement(order, null, 1, goodsPackageAmount(order), false); + } + + private void processApprovedRefund(MallRefundRecord refund) { + MallOrder order = mallOrderService.getById(refund.getOrderId()); + if (order == null || isRunnerOrder(order)) { + return; } - if (commissionRate == null) { - commissionRate = BigDecimal.ZERO; + + if (refund.getStatus() != null && refund.getStatus() == 4) { + processAfterSaleSettlement(order, refund); + return; } - LambdaQueryWrapper refQw = new LambdaQueryWrapper<>(); - refQw.eq(MallRefundRecord::getOrderId, order.getId()); - refQw.eq(MallRefundRecord::getStatus, 4); - List refunds = mallRefundRecordService.list(refQw); - - BigDecimal refundAmount = BigDecimal.ZERO; - for (MallRefundRecord r : refunds) { - String linkId = r.getLinkId(); - // åªæœ‰å•†å®¶è´Ÿè´£çš„å”®åŽï¼ˆlinkIdä¸ä¸ºW开头)æ‰éœ€è¦ä»Žå•†å®¶çš„结算基准中扣除 - if (linkId == null || !linkId.toUpperCase().startsWith("W")) { - if (r.getRefundAmount() != null) { - refundAmount = refundAmount.add(r.getRefundAmount()); - } - } + if (refund.getStatus() != null && refund.getStatus() == 1) { + processRefundSettlement(order, refund); } + } - BigDecimal goodsAmount = order.getGoodsAmount() != null ? order.getGoodsAmount() : BigDecimal.ZERO; - BigDecimal packageFee = order.getPackageFee() != null ? order.getPackageFee() : BigDecimal.ZERO; - - BigDecimal baseAmount = goodsAmount.add(packageFee).subtract(refundAmount); - - BigDecimal actualCommission = BigDecimal.ZERO; - if (baseAmount.compareTo(BigDecimal.ZERO) > 0) { - actualCommission = baseAmount.multiply(commissionRate.divide(BigDecimal.TEN.multiply(BigDecimal.TEN))); - } else { - baseAmount = BigDecimal.ZERO; + private void processAfterSaleSettlement(MallOrder order, MallRefundRecord refund) { + if (isWorkerRecord(refund) || !isMerchantSettlementOrder(order)) { + return; } - + BigDecimal settlementBase = safeAmount(refund.getSettlementAmount()); + if (settlementBase.compareTo(BigDecimal.ZERO) <= 0) { + settlementBase = safeAmount(refund.getRefundAmount()); + } + if (settlementBase.compareTo(BigDecimal.ZERO) <= 0 || existsSettlement(refund.getId(), 2)) { + return; + } + + boolean includesDeliveryFee = Integer.valueOf(3).equals(refund.getRefundType()) + && Integer.valueOf(1).equals(refund.getRefundTypeStatus()) + && isMerchantDeliveryOrder(order); + saveMerchantSettlement(order, refund.getId(), 2, settlementBase, includesDeliveryFee); + } + + private void processRefundSettlement(MallOrder order, MallRefundRecord refund) { + if (!isMerchantSettlementOrder(order)) { + return; + } + if (Integer.valueOf(2).equals(refund.getRefundTypeStatus()) && isWorkerRecord(refund)) { + saveMerchantSettlement(order, refund.getId(), 1, goodsPackageAmount(order), false); + } else if (Integer.valueOf(1).equals(refund.getRefundTypeStatus()) && isMerchantDeliveryOrder(order) && !isWorkerRecord(refund)) { + saveMerchantSettlement(order, refund.getId(), 2, deliveryAmount(order), true); + } + } + + private void saveMerchantSettlement(MallOrder order, String refundId, Integer type, BigDecimal baseAmount, boolean deliveryFeeIncluded) { + if (baseAmount == null || baseAmount.compareTo(BigDecimal.ZERO) <= 0 || existsSettlement(refundId, type, order.getId())) { + return; + } + BigDecimal commissionRate = getCommissionRate(order); + BigDecimal commissionBase = deliveryFeeIncluded ? baseAmount.subtract(deliveryAmount(order)) : baseAmount; + if (commissionBase.compareTo(BigDecimal.ZERO) < 0) { + commissionBase = BigDecimal.ZERO; + } + BigDecimal actualCommission = commissionBase.multiply(rateDecimal(commissionRate)).setScale(2, BigDecimal.ROUND_HALF_UP); BigDecimal settlementAmount = baseAmount.subtract(actualCommission); - + if (type != null && type == 2) { + settlementAmount = settlementAmount.negate(); + } + MallSettlementRecord record = new MallSettlementRecord(); record.setOrderId(order.getId()); record.setShopId(order.getShopId()); - record.setType(1); + record.setRefundId(refundId); + record.setType(type); + record.setRegionId(order.getRegionId()); record.setBaseAmount(baseAmount); record.setCommissionRate(commissionRate); record.setCommissionAmount(actualCommission); - record.setRegionId(order.getRegionId()); record.setSettlementAmount(settlementAmount); record.setStatus(0); record.setCreateTime(new Date()); - mallSettlementRecordService.save(record); } - - private void processSettledRefund(MallRefundRecord refund) { - String linkId = refund.getLinkId(); - // é…é€å‘˜è´Ÿè´£çš„å”®åŽï¼ˆlinkId为Wå¼€å¤´ï¼‰ï¼Œä¸æ‰£å•†å®¶çš„æ¬¾ - if (linkId != null && linkId.toUpperCase().startsWith("W")) { - return; - } - MallOrder order = mallOrderService.getById(refund.getOrderId()); - if (order == null || order.getSettlementStatus() == null || order.getSettlementStatus() == 0) { - return; - } - + private boolean existsSettlement(String refundId, Integer type) { + return existsSettlement(refundId, type, null); + } + + private boolean existsSettlement(String refundId, Integer type, String orderId) { LambdaQueryWrapper existsQw = new LambdaQueryWrapper<>(); - existsQw.eq(MallSettlementRecord::getRefundId, refund.getId()); - existsQw.eq(MallSettlementRecord::getType, 2); - long count = mallSettlementRecordService.count(existsQw); - if (count > 0) { - return; + if (refundId == null) { + existsQw.isNull(MallSettlementRecord::getRefundId); + } else { + existsQw.eq(MallSettlementRecord::getRefundId, refundId); } - + if (orderId != null) { + existsQw.eq(MallSettlementRecord::getOrderId, orderId); + } + existsQw.eq(MallSettlementRecord::getType, type); + return mallSettlementRecordService.count(existsQw) > 0; + } + + private BigDecimal getCommissionRate(MallOrder order) { LambdaQueryWrapper shopQw = new LambdaQueryWrapper<>(); shopQw.eq(ShopTakeaway::getShopId, order.getShopId()); ShopTakeaway takeaway = shopTakeawayService.getOne(shopQw); - + BigDecimal commissionRate = BigDecimal.ZERO; if (takeaway != null) { if (order.getOrderType() != null && order.getOrderType() == 1) { @@ -202,39 +225,46 @@ public class MerchantSettlementTask { if (commissionRate == null) { commissionRate = BigDecimal.ZERO; } - - LambdaQueryWrapper goodsQw = new LambdaQueryWrapper<>(); - goodsQw.eq(MallReturnOrderGoods::getOrderId, refund.getId()); - List returnGoods = mallReturnOrderGoodsMapper.selectList(goodsQw); - - BigDecimal totalReturnPice = BigDecimal.ZERO; - if (returnGoods != null) { - for (MallReturnOrderGoods g : returnGoods) { - BigDecimal price = g.getPrice() != null ? g.getPrice() : BigDecimal.ZERO; - BigDecimal quantity = g.getQuantity() != null ? new BigDecimal(g.getQuantity()) : BigDecimal.ZERO; - totalReturnPice = totalReturnPice.add(price.multiply(quantity)); - } - } - - if (totalReturnPice.compareTo(BigDecimal.ZERO) == 0) { - return; + return commissionRate; + } + + private BigDecimal rateDecimal(BigDecimal commissionRate) { + return safeAmount(commissionRate).divide(new BigDecimal("100"), 6, BigDecimal.ROUND_HALF_UP); + } + + private BigDecimal safeAmount(BigDecimal amount) { + return amount == null ? BigDecimal.ZERO : amount; + } + + private BigDecimal goodsPackageAmount(MallOrder order) { + if (order == null) { + return BigDecimal.ZERO; } - - BigDecimal deductionAmount = totalReturnPice.multiply(BigDecimal.ONE.subtract(commissionRate)); - - MallSettlementRecord record = new MallSettlementRecord(); - record.setOrderId(order.getId()); - record.setShopId(order.getShopId()); - record.setRefundId(refund.getId()); - record.setType(2); - record.setRegionId(order.getRegionId()); - record.setBaseAmount(totalReturnPice); - record.setCommissionRate(commissionRate); - record.setCommissionAmount(totalReturnPice.multiply(commissionRate)); - record.setSettlementAmount(deductionAmount.negate()); - record.setStatus(0); - record.setCreateTime(new Date()); - - mallSettlementRecordService.save(record); + return safeAmount(order.getGoodsAmount()).add(safeAmount(order.getPackageFee())); + } + + private BigDecimal deliveryAmount(MallOrder order) { + return order == null ? BigDecimal.ZERO : safeAmount(order.getDeliveryFee()); + } + + private boolean isRunnerOrder(MallOrder order) { + return order != null && Integer.valueOf(1).equals(order.getOtherOrder()); + } + + private boolean isMerchantSettlementOrder(MallOrder order) { + return order != null + && (order.getOtherOrder() == null + || Integer.valueOf(2).equals(order.getOtherOrder()) + || Integer.valueOf(3).equals(order.getOtherOrder())); + } + + private boolean isMerchantDeliveryOrder(MallOrder order) { + return order != null + && order.getOtherOrder() == null + && Integer.valueOf(1).equals(order.getDeliveryType()); + } + + private boolean isWorkerRecord(MallRefundRecord refund) { + return refund != null && refund.getLinkId() != null && refund.getLinkId().toUpperCase().startsWith("W"); } } 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 0a31c6ef..14154da6 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 @@ -39,6 +39,7 @@ import org.springframework.transaction.support.TransactionSynchronizationManager import java.math.BigDecimal; import java.math.RoundingMode; import java.text.DecimalFormat; +import java.time.LocalDate; import java.time.LocalDateTime; import java.time.ZoneId; import java.util.*; @@ -1389,8 +1390,31 @@ public class MallDeliveryOrderServiceImpl extends ServiceImpl countOrdersWorkerIndex(String workerId) { - return this.baseMapper.countOrdersWorkerIndex(workerId); + HashMap workerIndex = this.baseMapper.countOrdersWorkerIndex(workerId); + if (workerIndex == null) { + workerIndex = new HashMap<>(); + } + LocalDate date = LocalDate.now(); + Date startTime = Date.from(date.atStartOfDay(ZoneId.systemDefault()).toInstant()); + Date endTime = Date.from(date.atTime(23, 59, 59).atZone(ZoneId.systemDefault()).toInstant()); + LambdaQueryWrapper refundWrapper = new LambdaQueryWrapper<>(); + refundWrapper.eq(MallRefundRecord::getLinkId, workerId) + .in(MallRefundRecord::getStatus, 1, 4) + .ge(MallRefundRecord::getSuccessTime, startTime) + .le(MallRefundRecord::getSuccessTime, endTime); + List refundRecords = mallRefundRecordService.list(refundWrapper); + List agreedRefundRecords = refundRecords == null ? Collections.emptyList() : refundRecords; + BigDecimal afterSaleAmount = agreedRefundRecords.stream() + .map(record -> safeAmount(record.getSettlementAmount())) + .reduce(BigDecimal.ZERO, BigDecimal::add); + workerIndex.put("afterSaleCount", agreedRefundRecords.size()); + workerIndex.put("afterSaleAmount", afterSaleAmount); + return workerIndex; } } 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 5bebbafd..b5371b4f 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 @@ -38,6 +38,7 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.stereotype.Service; @@ -1662,7 +1663,7 @@ public class MallOrderServiceImpl extends ServiceImpl revenueOrders = this.baseMapper.selectOrderRevenueAndCount(shopId,startTime,endTime); - HashMap orderRevenueAndCount = buildOrderRevenueAndCount(shopId, revenueOrders); + HashMap orderRevenueAndCount = buildOrderRevenueAndCount(shopId, revenueOrders, startTime, endTime); result.put("orderRevenueAndCount", orderRevenueAndCount); //待处ç†å·®è¯„è®¢å•æ•° Integer pendingBadReviewCount = this.baseMapper.selectPendingBadReviewCount(shopId); @@ -1679,57 +1680,28 @@ public class MallOrderServiceImpl extends ServiceImpl buildOrderRevenueAndCount(String shopId, List revenueOrders) { + private HashMap buildOrderRevenueAndCount(String shopId, List revenueOrders, LocalDateTime startTime, LocalDateTime endTime) { HashMap orderRevenueAndCount = new HashMap<>(); List orders = revenueOrders == null ? Collections.emptyList() : revenueOrders; BigDecimal amount = orders.stream() .map(order -> safeAmount(order.getGoodsAmount()).add(safeAmount(order.getPackageFee()))) .reduce(BigDecimal.ZERO, BigDecimal::add); - Map orderMap = orders.stream() - .filter(order -> StringUtils.isNotBlank(order.getId())) - .collect(Collectors.toMap(MallOrder::getId, order -> order, (left, right) -> left)); orderRevenueAndCount.put("count", orders.size()); orderRevenueAndCount.put("amount", amount); - orderRevenueAndCount.put("afterSaleCount", 0); - orderRevenueAndCount.put("afterSaleAmount", BigDecimal.ZERO); - - List orderIds = orders.stream() - .map(MallOrder::getId) - .filter(StringUtils::isNotBlank) - .distinct() - .collect(Collectors.toList()); - if (orderIds.isEmpty()) { - return orderRevenueAndCount; - } LambdaQueryWrapper refundWrapper = new LambdaQueryWrapper<>(); refundWrapper.eq(MallRefundRecord::getLinkId, shopId) - .eq(MallRefundRecord::getStatus, REFUND_STATUS_AFTER_SALE_AGREED) - .in(MallRefundRecord::getOrderId, orderIds); + .in(MallRefundRecord::getStatus, 1, REFUND_STATUS_AFTER_SALE_AGREED) + .ge(MallRefundRecord::getSuccessTime, Timestamp.valueOf(startTime)) + .le(MallRefundRecord::getSuccessTime, Timestamp.valueOf(endTime)); List refundRecords = mallRefundRecordMapper.selectList(refundWrapper); - if (refundRecords == null || refundRecords.isEmpty()) { - return orderRevenueAndCount; - } - - List refundOrderIds = refundRecords.stream() - .map(MallRefundRecord::getOrderId) - .filter(StringUtils::isNotBlank) - .distinct() - .collect(Collectors.toList()); - if (refundOrderIds.isEmpty()) { - orderRevenueAndCount.put("afterSaleCount", refundRecords.size()); - return orderRevenueAndCount; - } - - LambdaQueryWrapper goodsWrapper = new LambdaQueryWrapper<>(); - goodsWrapper.in(MallReturnOrderGoods::getOrderId, refundOrderIds); - List returnGoodsList = mallReturnOrderGoodsMapper.selectList(goodsWrapper); - BigDecimal afterSaleAmount = returnGoodsList == null ? BigDecimal.ZERO : returnGoodsList.stream() - .map(goods -> calculateReturnGoodsAmount(goods, orderMap.get(goods.getOrderId()))) + List agreedRefundRecords = refundRecords == null ? Collections.emptyList() : refundRecords; + BigDecimal afterSaleAmount = agreedRefundRecords.stream() + .map(record -> safeAmount(record.getSettlementAmount())) .reduce(BigDecimal.ZERO, BigDecimal::add); - orderRevenueAndCount.put("afterSaleCount", refundRecords.size()); + orderRevenueAndCount.put("afterSaleCount", agreedRefundRecords.size()); orderRevenueAndCount.put("afterSaleAmount", afterSaleAmount); return orderRevenueAndCount; } @@ -2444,6 +2416,59 @@ public class MallOrderServiceImpl extends ServiceImpl shopQw = new LambdaQueryWrapper<>(); + shopQw.eq(ShopTakeaway::getShopId, order.getShopId()).last("LIMIT 1"); + ShopTakeaway takeaway = shopTakeawayMapper.selectOne(shopQw); + BigDecimal rate = BigDecimal.ZERO; + if (takeaway != null) { + if (Integer.valueOf(ORDER_TYPE_NORMAL).equals(order.getOrderType())) { + rate = takeaway.getCommissionRateOne(); + } else if (Integer.valueOf(ORDER_TYPE_GROUP).equals(order.getOrderType()) + || Integer.valueOf(ORDER_TYPE_FACETOFACE).equals(order.getOrderType())) { + rate = takeaway.getCommissionRateMore(); + } + } + return safeAmount(rate).divide(new BigDecimal("100"), 6, RoundingMode.HALF_UP); + } + + private BigDecimal calculateMerchantNetSettlement(MallOrder order) { + BigDecimal rate = commissionRateDecimal(order); + return goodsPackageAmount(order) + .multiply(BigDecimal.ONE.subtract(rate)) + .setScale(2, RoundingMode.HALF_UP); + } + + private MallRefundRecord copyRefundRecord(MallRefundRecord source) { + MallRefundRecord target = new MallRefundRecord(); + BeanUtils.copyProperties(source, target); + return target; + } + /** * 创建退款记录 */ @@ -2501,7 +2526,15 @@ public class MallOrderServiceImpl extends ServiceImpl 0){ shopRefund = order.getGoodsAmount().add(order.getPackageFee()).subtract(order.getGoodsAmount().add(order.getPackageFee()).multiply(ratio)).setScale(2, RoundingMode.UP); @@ -2550,9 +2600,10 @@ public class MallOrderServiceImpl extends ServiceImpl 0){ mallRefundRecord1.setRefundAmount(order.getTotalAmount().subtract(shopRefund)); }else{ 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 1a682588..b11683e9 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 @@ -22,6 +22,7 @@ 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.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.stereotype.Service; @@ -127,6 +128,131 @@ public class MallRefundRecordServiceImpl extends ServiceImpl 0 ? amount : safeAmount(refundRecord == null ? null : refundRecord.getRefundAmount()); + } + + private void deductWorkerBalance(MallRefundRecord refundRecord, Integer dealingsType) { + if (refundRecord == null || refundRecord.getLinkId() == null || !refundRecord.getLinkId().toUpperCase().startsWith("W")) { + return; + } + Worker worker = workerServiceImpl.findByWorkerId(refundRecord.getLinkId()); + if (worker == null) { + return; + } + BigDecimal amount = settlementAmountOrRefundAmount(refundRecord); + if (amount.compareTo(BigDecimal.ZERO) <= 0) { + return; + } + BigDecimal currentDepoBal = safeAmount(worker.getDepoBal()); + BigDecimal currentDepoBalRel = safeAmount(worker.getDepoBalRel()); + if (currentDepoBal.compareTo(amount) >= 0) { + worker.setDepoBal(currentDepoBal.subtract(amount)); + worker.setDepoBalRel(currentDepoBalRel); + } else { + worker.setDepoBal(BigDecimal.ZERO); + worker.setDepoBalRel(currentDepoBalRel.subtract(amount.subtract(currentDepoBal))); + } + workerServiceImpl.update(worker); + saveWorkerDealingsRecord( + worker, + refundRecord.getId(), + amount, + refundRecord.getStatus() != null && refundRecord.getStatus() > 3 + ? DealingsRecordConstant.TYPE_REMARK[1] + : DealingsRecordConstant.TYPE_REMARK[10], + dealingsType + ); + } + + private void addWorkerCommissionForMerchantRefund(MallOrder order, MallRefundRecord refundRecord) { + if (order == null || refundRecord == null || !isMerchantDeliveryOrder(order)) { + return; + } + MallDeliveryOrder delivery = order.getOrderType() == ORDER_TYPE_FACETOFACE + ? mallDeliveryOrderMapper.selectByGroupId(order.getId()) + : findDeliveryByOrderId(order.getId()); + if (delivery == null || delivery.getWorkerId() == null) { + return; + } + LambdaQueryWrapper existsQw = new LambdaQueryWrapper<>(); + existsQw.eq(DealingsRecord::getLinkId, refundRecord.getId()) + .eq(DealingsRecord::getLinkUserId, delivery.getWorkerId()) + .eq(DealingsRecord::getDealingsWay, DealingsRecordConstant.TYPE_REMARK[11]); + if (dealingsRecordService.count(existsQw) > 0) { + return; + } + Worker worker = workerServiceImpl.findByWorkerId(delivery.getWorkerId()); + if (worker == null) { + return; + } + BigDecimal commission = safeAmount(delivery.getDeliveryFee()).add(safeAmount(delivery.getDeliveryFeeMarketplace())).setScale(2, RoundingMode.UP); + if (commission.compareTo(BigDecimal.ZERO) <= 0) { + return; + } + worker.setDepoBal(safeAmount(worker.getDepoBal()).add(commission)); + workerServiceImpl.update(worker); + saveWorkerDealingsRecord(worker, refundRecord.getId(), commission, DealingsRecordConstant.TYPE_REMARK[11], DealingsRecordConstant.DEALINGS_TYPE[0]); + } + + private void saveWorkerDealingsRecord(Worker worker, String linkId, BigDecimal amount, String dealingsWay, Integer dealingsType) { + DealingsRecord dealingsRecord = new DealingsRecord(); + dealingsRecord.setDealingsWay(dealingsWay); + dealingsRecord.setAmount(amount); + dealingsRecord.setDealingsTime(new Date()); + dealingsRecord.setLinkUserId(worker.getWorkerId()); + dealingsRecord.setLinkId(linkId); + dealingsRecord.setLinkType(DealingsRecordConstant.TYPE[1]); + dealingsRecord.setDealingsType(dealingsType); + dealingsRecord.setCreateBy(worker.getWorkerId()); + dealingsRecordService.save(dealingsRecord); + } + @Override @Transactional(rollbackFor = Exception.class) public void create(MallRefundRecord mallRefundRecord) { @@ -180,6 +306,7 @@ public class MallRefundRecordServiceImpl extends ServiceImpl 0){ mallRefundRecord.setRefundAmount(mallRefundRecord.getRefundAmount() .subtract(mallRefundRecord.getRefundAmount().multiply(ratio)).setScale(2, RoundingMode.UP)); @@ -200,6 +327,7 @@ public class MallRefundRecordServiceImpl extends ServiceImpl 0){ mallRefundRecord.setRefundAmount(mallRefundRecord.getRefundAmount() .subtract(mallRefundRecord.getRefundAmount().multiply(ratio)).setScale(2, RoundingMode.UP)); @@ -218,16 +346,31 @@ public class MallRefundRecordServiceImpl extends ServiceImpl 0){ @@ -250,9 +406,10 @@ public class MallRefundRecordServiceImpl extends ServiceImpl 0){ mallRefundRecord1.setRefundAmount(order.getTotalAmount().subtract(shopRefund)); @@ -263,9 +420,10 @@ public class MallRefundRecordServiceImpl extends ServiceImpl page = new Page<>(PAGENUM, PAGESIZE); + IPage page = new Page<>(PAGENUM, 2); MallRefundRecordPageQuery q = new MallRefundRecordPageQuery(); q.setOrderId(mallRefundRecord.getOrderId()); + q.setOrderDesc(true); IPage result = this.baseMapper.selectPageVO(page, q); - boolean hasEnd = result.getRecords().stream() + List latestRecords = result.getRecords(); + boolean hasEnd = latestRecords != null && latestRecords.stream() .anyMatch(item -> item.getStatus() == 3 || item.getStatus() == 0); - boolean hasReject = result.getRecords().stream() + boolean hasReject = latestRecords != null && latestRecords.stream() .anyMatch(item -> item.getStatus() == 2 || item.getStatus() == 5); if(isTuiKuan){ //都处ç†äº† @@ -365,31 +525,7 @@ public class MallRefundRecordServiceImpl extends ServiceImpl= 0) { - // 情况一:待结算金é¢è¶³å¤Ÿå…¨é¢æŠµæ‰£é€€æ¬¾ - worker.setDepoBal(currentDepoBal.subtract(refundAmount)); - // å¯æçŽ°é‡‘é¢ä¿æŒä¸å˜ - worker.setDepoBalRel(currentDepoBalRel); - } else { - // 情况二:待结算金é¢ä¸è¶³ï¼Œéœ€è¦è”åˆæ‰£æ¬¾ - // å…ˆæŠŠå¾…ç»“ç®—é‡‘é¢æ‰£æˆ 0 - worker.setDepoBal(BigDecimal.ZERO); - - // 计算还需è¦ä»Žå¯æçް金é¢ä¸­æ‰£é™¤çš„部分 - BigDecimal remainingRefund = refundAmount.subtract(currentDepoBal); - // ç”¨å¯æçŽ°é‡‘é¢å‡åŽ»å‰©ä½™é€€æ¬¾ - worker.setDepoBalRel(currentDepoBalRel.subtract(remainingRefund)); - } - // 执行更新 - workerServiceImpl.update(worker); + deductWorkerBalance(mallRefundRecord, DealingsRecordConstant.DEALINGS_TYPE[2]); } }else{ //æ‹’ç»é€€æ¬¾ @@ -426,7 +562,7 @@ public class MallRefundRecordServiceImpl extends ServiceImpl duw = new LambdaUpdateWrapper<>(); - duw.eq(MallDeliveryOrder::getOrderId, mallRefundRecord.getOrderId()) + duw.eq(MallDeliveryOrder::getId, delivery.getId()) .set(MallDeliveryOrder::getIsReturn, 0); mallDeliveryOrderMapper.update(null, duw); @@ -457,9 +593,16 @@ public class MallRefundRecordServiceImpl extends ServiceImpl duw = new LambdaUpdateWrapper<>(); - duw.eq(MallDeliveryOrder::getOrderId, mallRefundRecord.getOrderId()) + duw.eq(MallDeliveryOrder::getId, delivery.getId()) .set(MallDeliveryOrder::getIsReturn, 0); mallDeliveryOrderMapper.update(null, duw); + + //更新缓存 + MallDeliveryOrder delivery1 = workerOrderCacheUtil.get(delivery.getWorkerId(),delivery.getId()); + if(delivery1 != null){ + delivery1.setIsReturn(0); + workerOrderCacheUtil.update(delivery.getWorkerId(),delivery1); + } } } } @@ -483,43 +626,7 @@ public class MallRefundRecordServiceImpl extends ServiceImpl= 0) { - // 情况一:待结算金é¢è¶³å¤Ÿå…¨é¢æŠµæ‰£é€€æ¬¾ - worker.setDepoBal(currentDepoBal.subtract(refundAmount)); - // å¯æçŽ°é‡‘é¢ä¿æŒä¸å˜ - worker.setDepoBalRel(currentDepoBalRel); - } else { - // 情况二:待结算金é¢ä¸è¶³ï¼Œéœ€è¦è”åˆæ‰£æ¬¾ - // å…ˆæŠŠå¾…ç»“ç®—é‡‘é¢æ‰£æˆ 0 - worker.setDepoBal(BigDecimal.ZERO); - - // 计算还需è¦ä»Žå¯æçް金é¢ä¸­æ‰£é™¤çš„部分 - BigDecimal remainingRefund = refundAmount.subtract(currentDepoBal); - // ç”¨å¯æçŽ°é‡‘é¢å‡åŽ»å‰©ä½™é€€æ¬¾ - worker.setDepoBalRel(currentDepoBalRel.subtract(remainingRefund)); - } - // 执行更新 - workerServiceImpl.update(worker); - - //增加余é¢å˜åŠ¨è®°å½• - DealingsRecord dealingsRecord = new DealingsRecord(); - dealingsRecord.setDealingsWay(DealingsRecordConstant.TYPE_REMARK[1]); - dealingsRecord.setAmount(refundAmount); - dealingsRecord.setDealingsTime(new Date()); - dealingsRecord.setLinkUserId(worker.getWorkerId()); - dealingsRecord.setLinkId(mallRefundRecord.getId()); - dealingsRecord.setLinkType(DealingsRecordConstant.TYPE[1]); - dealingsRecord.setDealingsType(DealingsRecordConstant.DEALINGS_TYPE[3]); - dealingsRecord.setCreateBy(worker.getWorkerId()); - dealingsRecordService.save(dealingsRecord); + deductWorkerBalance(mallRefundRecord, DealingsRecordConstant.DEALINGS_TYPE[3]); } } //都处ç†äº† @@ -646,30 +753,9 @@ public class MallRefundRecordServiceImpl extends ServiceImpl= 0) { - // 情况一:待结算金é¢è¶³å¤Ÿå…¨é¢æŠµæ‰£é€€æ¬¾ - worker.setDepoBal(currentDepoBal.subtract(refundAmount)); - // å¯æçŽ°é‡‘é¢ä¿æŒä¸å˜ - worker.setDepoBalRel(currentDepoBalRel); - } else { - // 情况二:待结算金é¢ä¸è¶³ï¼Œéœ€è¦è”åˆæ‰£æ¬¾ - // å…ˆæŠŠå¾…ç»“ç®—é‡‘é¢æ‰£æˆ 0 - worker.setDepoBal(BigDecimal.ZERO); - - // 计算还需è¦ä»Žå¯æçް金é¢ä¸­æ‰£é™¤çš„部分 - BigDecimal remainingRefund = refundAmount.subtract(currentDepoBal); - // ç”¨å¯æçŽ°é‡‘é¢å‡åŽ»å‰©ä½™é€€æ¬¾ - worker.setDepoBalRel(currentDepoBalRel.subtract(remainingRefund)); - } - // 执行更新 - workerServiceImpl.update(worker); + deductWorkerBalance(mallRefundRecord, DealingsRecordConstant.DEALINGS_TYPE[2]); + } else if (Integer.valueOf(1).equals(mallRefundRecord.getRefundTypeStatus())) { + addWorkerCommissionForMerchantRefund(order, mallRefundRecord); } } }else{ @@ -680,41 +766,7 @@ public class MallRefundRecordServiceImpl extends ServiceImpl= 0) { - // 情况一:待结算金é¢è¶³å¤Ÿå…¨é¢æŠµæ‰£é€€æ¬¾ - worker.setDepoBal(currentDepoBal.subtract(refundAmount)); - // å¯æçŽ°é‡‘é¢ä¿æŒä¸å˜ - worker.setDepoBalRel(currentDepoBalRel); - } else { - // 情况二:待结算金é¢ä¸è¶³ï¼Œéœ€è¦è”åˆæ‰£æ¬¾ - // å…ˆæŠŠå¾…ç»“ç®—é‡‘é¢æ‰£æˆ 0 - worker.setDepoBal(BigDecimal.ZERO); - - // 计算还需è¦ä»Žå¯æçް金é¢ä¸­æ‰£é™¤çš„部分 - BigDecimal remainingRefund = refundAmount.subtract(currentDepoBal); - // ç”¨å¯æçŽ°é‡‘é¢å‡åŽ»å‰©ä½™é€€æ¬¾ - worker.setDepoBalRel(currentDepoBalRel.subtract(remainingRefund)); - } - // 执行更新 - workerServiceImpl.update(worker); - //增加余é¢å˜åŠ¨è®°å½• - DealingsRecord dealingsRecord = new DealingsRecord(); - dealingsRecord.setDealingsWay(DealingsRecordConstant.TYPE_REMARK[1]); - dealingsRecord.setAmount(refundAmount); - dealingsRecord.setLinkUserId(worker.getWorkerId()); - dealingsRecord.setDealingsTime(new Date()); - dealingsRecord.setLinkId(mallRefundRecord.getId()); - dealingsRecord.setLinkType(DealingsRecordConstant.TYPE[1]); - dealingsRecord.setDealingsType(DealingsRecordConstant.DEALINGS_TYPE[2]); - dealingsRecord.setCreateBy(worker.getWorkerId()); - dealingsRecordService.save(dealingsRecord); + deductWorkerBalance(mallRefundRecord, DealingsRecordConstant.DEALINGS_TYPE[2]); } }else{ //订å•è¿˜æ˜¯å˜æˆå·²å®ŒæˆçŠ¶æ€ @@ -765,6 +817,7 @@ public class MallRefundRecordServiceImpl extends ServiceImpl existsQw = new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<>(); existsQw.eq(MallSettlementRecord::getRefundId, refund.getId()); existsQw.eq(MallSettlementRecord::getType, 2); @@ -118,25 +125,25 @@ public class MallSettlementRecordServiceImpl extends ServiceImpl goodsQw = new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<>(); - goodsQw.eq(cc.hiver.mall.entity.MallReturnOrderGoods::getOrderId, refund.getId()); - List returnGoods = mallReturnOrderGoodsMapper.selectList(goodsQw); - - BigDecimal totalReturnPice = BigDecimal.ZERO; - if (returnGoods != null) { - for (cc.hiver.mall.entity.MallReturnOrderGoods g : returnGoods) { - BigDecimal price = g.getPrice() != null ? g.getPrice() : BigDecimal.ZERO; - BigDecimal quantity = g.getQuantity() != null ? new BigDecimal(g.getQuantity()) : BigDecimal.ZERO; - totalReturnPice = totalReturnPice.add(price.multiply(quantity)); - } - } - - if (totalReturnPice.compareTo(BigDecimal.ZERO) == 0) { + + BigDecimal totalReturnPice = refund.getSettlementAmount() != null ? refund.getSettlementAmount() : refund.getRefundAmount(); + if (totalReturnPice == null || totalReturnPice.compareTo(BigDecimal.ZERO) <= 0) { return; } - - BigDecimal deductionAmount = totalReturnPice.multiply(BigDecimal.ONE.subtract(commissionRate)); + + BigDecimal deliveryFee = order.getDeliveryFee() != null ? order.getDeliveryFee() : BigDecimal.ZERO; + boolean includesDeliveryFee = refund.getRefundType() != null && refund.getRefundType() == 3 + && refund.getRefundTypeStatus() != null && refund.getRefundTypeStatus() == 1 + && order.getOtherOrder() == null + && order.getDeliveryType() != null && order.getDeliveryType() == 1; + BigDecimal commissionBase = includesDeliveryFee ? totalReturnPice.subtract(deliveryFee) : totalReturnPice; + if (commissionBase.compareTo(BigDecimal.ZERO) < 0) { + commissionBase = BigDecimal.ZERO; + } + BigDecimal commissionAmount = commissionBase + .multiply(commissionRate.divide(new BigDecimal("100"), 6, BigDecimal.ROUND_HALF_UP)) + .setScale(2, BigDecimal.ROUND_HALF_UP); + BigDecimal deductionAmount = totalReturnPice.subtract(commissionAmount); MallSettlementRecord record = new MallSettlementRecord(); record.setOrderId(order.getId()); @@ -145,7 +152,7 @@ public class MallSettlementRecordServiceImpl extends ServiceImpl + @@ -184,20 +185,26 @@