Browse Source

对接拼团数据1

master
wangfukang 2 weeks ago
parent
commit
00f032db37
  1. 16
      hiver-admin/test-output/test-report.html
  2. 2
      hiver-core/src/main/java/cc/hiver/core/common/constant/DealingsRecordConstant.java
  3. 5
      hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/bill/vo/CustomerBillQueryVo.java
  4. 216
      hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/controller/AdminSettlementController.java
  5. 9
      hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/entity/DealingsRecord.java
  6. 2
      hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/entity/MallRefundRecord.java
  7. 5
      hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/entity/MallSettlementRecord.java
  8. 228
      hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/quartz/MerchantSettlementTask.java
  9. 26
      hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/mybatis/MallDeliveryOrderServiceImpl.java
  10. 133
      hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/mybatis/MallOrderServiceImpl.java
  11. 313
      hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/mybatis/MallRefundRecordServiceImpl.java
  12. 53
      hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/mybatis/MallSettlementRecordServiceImpl.java
  13. 2
      hiver-modules/hiver-mall/src/main/resources/db/mall_refund_record_settlement_amount.sql
  14. 19
      hiver-modules/hiver-mall/src/main/resources/mapper/DealingsRecordMapper.xml
  15. 1
      hiver-modules/hiver-mall/src/main/resources/mapper/MallRefundRecordMapper.xml

16
hiver-admin/test-output/test-report.html

@ -35,7 +35,7 @@
<a href="#"><span class="badge badge-primary">Hiver</span></a>
</li>
<li class="m-r-10">
<a href="#"><span class="badge badge-primary">七月 08, 2026 11:47:38</span></a>
<a href="#"><span class="badge badge-primary">七月 12, 2026 14:35:40</span></a>
</li>
</ul>
</div>
@ -84,7 +84,7 @@
<div class="test-detail">
<span class="meta text-white badge badge-sm"></span>
<p class="name">passTest</p>
<p class="text-sm"><span>11:47:39 上</span> / <span>0.029 secs</span></p>
<p class="text-sm"><span>14:35:40 下</span> / <span>0.022 secs</span></p>
</div>
<div class="test-contents d-none">
<div class="detail-head">
@ -92,9 +92,9 @@
<div class="info">
<div class='float-right'><span class='badge badge-default'>#test-id=1</span></div>
<h5 class="test-status text-pass">passTest</h5>
<span class='badge badge-success'>07.08.2026 11:47:39</span>
<span class='badge badge-danger'>07.08.2026 11:47:39</span>
<span class='badge badge-default'>0.029 secs</span>
<span class='badge badge-success'>07.12.2026 14:35:40</span>
<span class='badge badge-danger'>07.12.2026 14:35:40</span>
<span class='badge badge-default'>0.022 secs</span>
</div>
<div class="m-t-10 m-l-5"></div>
</div>
@ -104,7 +104,7 @@
<tbody>
<tr class="event-row">
<td><span class="badge log pass-bg">Pass</span></td>
<td>11:47:39</td>
<td>14:35:40</td>
<td>
Test passed
</td>
@ -128,13 +128,13 @@
<div class="col-md-3">
<div class="card"><div class="card-body">
<p class="m-b-0">Started</p>
<h3>七月 08, 2026 11:47:38</h3>
<h3>七月 12, 2026 14:35:40</h3>
</div></div>
</div>
<div class="col-md-3">
<div class="card"><div class="card-body">
<p class="m-b-0">Ended</p>
<h3>七月 08, 2026 11:47:39</h3>
<h3>七月 12, 2026 14:35:40</h3>
</div></div>
</div>
<div class="col-md-3">

2
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售后

5
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;
}

216
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<List<SettlementSummaryVo>> summaryList(@RequestBody SummaryQuery query) {
public Result<Page<SettlementSummaryVo>> summaryList(@RequestBody SummaryQuery query) {
if (StringUtils.isBlank(query.getRegionId()) || StringUtils.isBlank(query.getSettlementDate())) {
return ResultUtil.error("区域ID或日期不能为空");
}
LambdaQueryWrapper<MallSettlementRecord> 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<MallSettlementRecord> list = mallSettlementRecordService.list(qw);
// Group by shopId
Map<String, List<MallSettlementRecord>> map = list.stream().collect(Collectors.groupingBy(MallSettlementRecord::getShopId));
List<String> shopIds = map.keySet().stream()
.filter(StringUtils::isNotBlank)
.collect(Collectors.toList());
Map<String, Shop> shopMap = shopIds.isEmpty() ? new java.util.HashMap<>() : shopService.getRepository().findAllById(shopIds).stream()
.collect(Collectors.toMap(Shop::getId, Function.identity(), (a, b) -> a));
List<SettlementSummaryVo> result = new ArrayList<>();
for (Map.Entry<String, List<MallSettlementRecord>> 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<Page<SettlementSummaryVo>>().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<Page<DateSummaryVo>> dateSummaryList(@RequestBody SummaryQuery query) {
if (StringUtils.isBlank(query.getRegionId())) {
return ResultUtil.error("区域ID不能为空");
}
LambdaQueryWrapper<MallSettlementRecord> 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<MallSettlementRecord> list = mallSettlementRecordService.list(qw);
Map<String, List<MallSettlementRecord>> byDate = list.stream()
.collect(Collectors.groupingBy(r -> new java.text.SimpleDateFormat("yyyy-MM-dd").format(r.getCreateTime())));
List<DateSummaryVo> result = new ArrayList<>();
for (Map.Entry<String, List<MallSettlementRecord>> 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<List<SettlementSummaryVo>>().setData(result);
result.sort(Comparator.comparing(DateSummaryVo::getBillTime).reversed());
return new ResultUtil<Page<DateSummaryVo>>().setData(buildPage(result, query));
}
private <T> Page<T> buildPage(List<T> 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<T> 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<List<MallSettlementRecord>> detailList(@RequestBody DetailQuery query) {
LambdaQueryWrapper<MallSettlementRecord> 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<MallSettlementRecord> list = mallSettlementRecordService.list(qw);
List<String> shopIds = list.stream()
.map(MallSettlementRecord::getShopId)
.filter(StringUtils::isNotBlank)
.distinct()
.collect(Collectors.toList());
Map<String, Shop> shopMap = shopIds.isEmpty() ? new java.util.HashMap<>() : shopService.getRepository().findAllById(shopIds).stream()
.collect(Collectors.toMap(Shop::getId, Function.identity(), (a, b) -> a));
List<String> orderIds = list.stream()
.map(MallSettlementRecord::getOrderId)
.filter(StringUtils::isNotBlank)
.distinct()
.collect(Collectors.toList());
Map<String, MallOrder> 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<List<MallSettlementRecord>>().setData(list);
}
private void fillAmounts(DateSummaryVo vo, List<MallSettlementRecord> 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

9
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;
}

2
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 = "拒绝原因")

5
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 = "店铺名称(快照)")

228
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<MallOrder> 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<MallOrder> 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<MallRefundRecord> refundQw = new LambdaQueryWrapper<>();
refundQw.eq(MallRefundRecord::getStatus, 4);
refundQw.in(MallRefundRecord::getStatus, 1, 4);
List<MallRefundRecord> 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<MallSettlementRecord> 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<ShopTakeaway> 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<MallRefundRecord> refQw = new LambdaQueryWrapper<>();
refQw.eq(MallRefundRecord::getOrderId, order.getId());
refQw.eq(MallRefundRecord::getStatus, 4);
List<MallRefundRecord> 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<MallSettlementRecord> 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<ShopTakeaway> 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<MallReturnOrderGoods> goodsQw = new LambdaQueryWrapper<>();
goodsQw.eq(MallReturnOrderGoods::getOrderId, refund.getId());
List<MallReturnOrderGoods> 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");
}
}

26
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<MallDeliveryOrderM
return this.baseMapper.selectByOrderIds(ids);
}
private BigDecimal safeAmount(BigDecimal amount) {
return amount == null ? BigDecimal.ZERO : amount;
}
@Override
public HashMap<String, Object> countOrdersWorkerIndex(String workerId) {
return this.baseMapper.countOrdersWorkerIndex(workerId);
HashMap<String, Object> 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<MallRefundRecord> refundWrapper = new LambdaQueryWrapper<>();
refundWrapper.eq(MallRefundRecord::getLinkId, workerId)
.in(MallRefundRecord::getStatus, 1, 4)
.ge(MallRefundRecord::getSuccessTime, startTime)
.le(MallRefundRecord::getSuccessTime, endTime);
List<MallRefundRecord> refundRecords = mallRefundRecordService.list(refundWrapper);
List<MallRefundRecord> 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;
}
}

133
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<MallOrderMapper, MallOrder
LocalDateTime endTime = date.atTime(LocalTime.MAX);
//统计营业额、订单量、已同意售后笔数和售后商品金额
List<MallOrder> revenueOrders = this.baseMapper.selectOrderRevenueAndCount(shopId,startTime,endTime);
HashMap<String, Object> orderRevenueAndCount = buildOrderRevenueAndCount(shopId, revenueOrders);
HashMap<String, Object> 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<MallOrderMapper, MallOrder
return result;
}
private HashMap<String, Object> buildOrderRevenueAndCount(String shopId, List<MallOrder> revenueOrders) {
private HashMap<String, Object> buildOrderRevenueAndCount(String shopId, List<MallOrder> revenueOrders, LocalDateTime startTime, LocalDateTime endTime) {
HashMap<String, Object> orderRevenueAndCount = new HashMap<>();
List<MallOrder> 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<String, MallOrder> 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<String> orderIds = orders.stream()
.map(MallOrder::getId)
.filter(StringUtils::isNotBlank)
.distinct()
.collect(Collectors.toList());
if (orderIds.isEmpty()) {
return orderRevenueAndCount;
}
LambdaQueryWrapper<MallRefundRecord> 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<MallRefundRecord> refundRecords = mallRefundRecordMapper.selectList(refundWrapper);
if (refundRecords == null || refundRecords.isEmpty()) {
return orderRevenueAndCount;
}
List<String> refundOrderIds = refundRecords.stream()
.map(MallRefundRecord::getOrderId)
.filter(StringUtils::isNotBlank)
.distinct()
.collect(Collectors.toList());
if (refundOrderIds.isEmpty()) {
orderRevenueAndCount.put("afterSaleCount", refundRecords.size());
return orderRevenueAndCount;
}
LambdaQueryWrapper<MallReturnOrderGoods> goodsWrapper = new LambdaQueryWrapper<>();
goodsWrapper.in(MallReturnOrderGoods::getOrderId, refundOrderIds);
List<MallReturnOrderGoods> returnGoodsList = mallReturnOrderGoodsMapper.selectList(goodsWrapper);
BigDecimal afterSaleAmount = returnGoodsList == null ? BigDecimal.ZERO : returnGoodsList.stream()
.map(goods -> calculateReturnGoodsAmount(goods, orderMap.get(goods.getOrderId())))
List<MallRefundRecord> 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<MallOrderMapper, MallOrder
return order;
}
private BigDecimal goodsPackageAmount(MallOrder order) {
if (order == null) {
return BigDecimal.ZERO;
}
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 isMerchantDeliveryOrder(MallOrder order) {
return order != null
&& order.getOtherOrder() == null
&& Integer.valueOf(DELIVERY_TYPE_EXPRESS).equals(order.getDeliveryType());
}
private BigDecimal commissionRateDecimal(MallOrder order) {
if (order == null || StringUtils.isBlank(order.getShopId())) {
return BigDecimal.ZERO;
}
LambdaQueryWrapper<ShopTakeaway> 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<MallOrderMapper, MallOrder
// 全额退款
if(refundType == 3){
if(refundTypeStatus == 1){
record.setLinkId(order.getShopId());
if (isRunnerOrder(order)) {
record.setLinkId(workerId);
record.setSettlementAmount(deliveryAmount(order));
} else {
record.setLinkId(order.getShopId());
record.setSettlementAmount(isMerchantDeliveryOrder(order)
? goodsPackageAmount(order).add(deliveryAmount(order))
: goodsPackageAmount(order));
}
/*if(ratio != null){
record.setRefundAmount(record.getRefundAmount()
.subtract(record.getRefundAmount().multiply(ratio)).setScale(2, RoundingMode.HALF_UP));
@ -2512,9 +2545,14 @@ public class MallOrderServiceImpl extends ServiceImpl<MallOrderMapper, MallOrder
//发送1小时延时MQ:超时未处理则自动同意
orderAsyncProducer.sendRefundDelayMessage(record.getId(), order.getId());
//发送商家通知
jPushService.sendPushNotification(shopService.findById(order.getShopId()).getClientId(), "您有一笔订单申请退款",order.getId());
if (!isRunnerOrder(order)) {
jPushService.sendPushNotification(shopService.findById(order.getShopId()).getClientId(), "您有一笔订单申请退款",order.getId());
}
}else if(refundTypeStatus == 2){
record.setLinkId(workerId);
record.setSettlementAmount(isRunnerOrder(order)
? deliveryAmount(order)
: calculateMerchantNetSettlement(order));
/*if(ratio != null){
record.setRefundAmount(record.getRefundAmount()
.subtract(record.getRefundAmount().multiply(ratio)).setScale(2, RoundingMode.HALF_UP));
@ -2529,8 +2567,20 @@ public class MallOrderServiceImpl extends ServiceImpl<MallOrderMapper, MallOrder
jPushService.sendPushNotification(shopService.findById(order.getShopId()).getClientId(), "您有一笔订单申请退款,配送员原因",order.getId());
}
}else if(refundTypeStatus == 3){
if (!isMerchantDeliveryOrder(order)) {
record.setLinkId(isRunnerOrder(order) ? workerId : order.getShopId());
record.setSettlementAmount(isRunnerOrder(order) ? deliveryAmount(order) : goodsPackageAmount(order));
mallRefundRecordMapper.insert(record);
refundOrderCacheUtil.put(record.getLinkId(),record);
orderAsyncProducer.sendRefundDelayMessage(record.getId(), order.getId());
if (!isRunnerOrder(order)) {
jPushService.sendPushNotification(shopService.findById(order.getShopId()).getClientId(), "您有一笔订单申请退款",order.getId());
}
return;
}
//商家、配送员都加一条
record.setLinkId(order.getShopId());
record.setSettlementAmount(goodsPackageAmount(order));
BigDecimal shopRefund = BigDecimal.ZERO;
if(ratio != null && ratio.compareTo(BigDecimal.ZERO) > 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<MallOrderMapper, MallOrder
orderAsyncProducer.sendRefundDelayMessage(record.getId(), order.getId());
//发送商家通知
jPushService.sendPushNotification(shopService.findById(order.getShopId()).getClientId(), "您有一笔订单申请退款",order.getId());
MallRefundRecord mallRefundRecord1 = record;
MallRefundRecord mallRefundRecord1 = copyRefundRecord(record);
mallRefundRecord1.setId(SnowFlakeUtil.nextId().toString());
mallRefundRecord1.setLinkId(workerId);
mallRefundRecord1.setSettlementAmount(deliveryAmount(order));
if(ratio != null && ratio.compareTo(BigDecimal.ZERO) > 0){
mallRefundRecord1.setRefundAmount(order.getTotalAmount().subtract(shopRefund));
}else{

313
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<MallRefundRecordMap
@Autowired
private WorkerServiceImpl workerServiceImpl;
private BigDecimal safeAmount(BigDecimal amount) {
return amount == null ? BigDecimal.ZERO : amount;
}
private BigDecimal goodsPackageAmount(MallOrder order) {
if (order == null) {
return BigDecimal.ZERO;
}
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 isMerchantDeliveryOrder(MallOrder order) {
return order != null
&& order.getOtherOrder() == null
&& Integer.valueOf(DELIVERY_TYPE_PEISONG).equals(order.getDeliveryType());
}
private BigDecimal selectedGoodsPackageAmount(MallRefundRecord refundRecord) {
if (refundRecord == null || refundRecord.getItems() == null || refundRecord.getItems().isEmpty()) {
return safeAmount(refundRecord == null ? null : refundRecord.getGoodsAmount())
.add(safeAmount(refundRecord == null ? null : refundRecord.getPackageFee()));
}
BigDecimal amount = BigDecimal.ZERO;
for (MallReturnOrderGoods item : refundRecord.getItems()) {
BigDecimal quantity = item.getQuantity() == null ? BigDecimal.ZERO : new BigDecimal(item.getQuantity());
amount = amount.add(safeAmount(item.getPrice()).add(safeAmount(item.getPackageFee())).multiply(quantity));
}
return amount.setScale(2, RoundingMode.HALF_UP);
}
private MallRefundRecord copyRefundRecord(MallRefundRecord source) {
MallRefundRecord target = new MallRefundRecord();
BeanUtils.copyProperties(source, target);
return target;
}
private BigDecimal settlementAmountOrRefundAmount(MallRefundRecord refundRecord) {
BigDecimal amount = safeAmount(refundRecord == null ? null : refundRecord.getSettlementAmount());
return amount.compareTo(BigDecimal.ZERO) > 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<DealingsRecord> 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<MallRefundRecordMap
if(mallRefundRecord.getRefundType() == 1){
// 退商品,和商家有关联
mallRefundRecord.setLinkId(mallRefundRecord.getShopId());
mallRefundRecord.setSettlementAmount(selectedGoodsPackageAmount(mallRefundRecord));
/*if(ratio != null && ratio.compareTo(BigDecimal.ZERO) > 0){
mallRefundRecord.setRefundAmount(mallRefundRecord.getRefundAmount()
.subtract(mallRefundRecord.getRefundAmount().multiply(ratio)).setScale(2, RoundingMode.UP));
@ -200,6 +327,7 @@ public class MallRefundRecordServiceImpl extends ServiceImpl<MallRefundRecordMap
}else if(mallRefundRecord.getRefundType() == 2){
// 退配送费和配送员有关联
mallRefundRecord.setLinkId(mallRefundRecord.getWorkerId());
mallRefundRecord.setSettlementAmount(deliveryAmount(order));
/*if(ratio != null && ratio.compareTo(BigDecimal.ZERO) > 0){
mallRefundRecord.setRefundAmount(mallRefundRecord.getRefundAmount()
.subtract(mallRefundRecord.getRefundAmount().multiply(ratio)).setScale(2, RoundingMode.UP));
@ -218,16 +346,31 @@ public class MallRefundRecordServiceImpl extends ServiceImpl<MallRefundRecordMap
// 全额退款
if(mallRefundRecord.getRefundTypeStatus() == 1){
//和商家有关联
mallRefundRecord.setLinkId(mallRefundRecord.getShopId());
if (isRunnerOrder(order)) {
mallRefundRecord.setLinkId(mallRefundRecord.getWorkerId());
mallRefundRecord.setSettlementAmount(deliveryAmount(order));
} else {
mallRefundRecord.setLinkId(mallRefundRecord.getShopId());
mallRefundRecord.setSettlementAmount(isMerchantDeliveryOrder(order)
? goodsPackageAmount(order).add(deliveryAmount(order))
: goodsPackageAmount(order));
}
mallRefundRecordMapper.insert(mallRefundRecord);
//售后放到缓存
refundOrderCacheUtil.put(mallRefundRecord.getLinkId(),mallRefundRecord);
//发送1小时延时MQ:超时未处理则自动同意
orderAsyncProducer.sendRefundDelayMessage(mallRefundRecord.getId(), mallRefundRecord.getOrderId());
sendShopAfterSaleNotice(order);
if (!isRunnerOrder(order)) {
sendShopAfterSaleNotice(order);
} else {
sendWorkerAfterSaleSms(mallRefundRecord,order);
}
}else if(mallRefundRecord.getRefundTypeStatus() == 2){
//和配送员有关联
mallRefundRecord.setLinkId(mallRefundRecord.getWorkerId());
mallRefundRecord.setSettlementAmount(isRunnerOrder(order)
? deliveryAmount(order)
: goodsPackageAmount(order).add(deliveryAmount(order)));
mallRefundRecordMapper.insert(mallRefundRecord);
//售后放到缓存
refundOrderCacheUtil.put(mallRefundRecord.getLinkId(),mallRefundRecord);
@ -235,8 +378,21 @@ public class MallRefundRecordServiceImpl extends ServiceImpl<MallRefundRecordMap
orderAsyncProducer.sendRefundDelayMessage(mallRefundRecord.getId(), mallRefundRecord.getOrderId());
sendWorkerAfterSaleSms(mallRefundRecord,order);
}else if(mallRefundRecord.getRefundTypeStatus() == 3){
if (!isMerchantDeliveryOrder(order)) {
mallRefundRecord.setLinkId(isRunnerOrder(order) ? mallRefundRecord.getWorkerId() : mallRefundRecord.getShopId());
mallRefundRecord.setSettlementAmount(isRunnerOrder(order) ? deliveryAmount(order) : goodsPackageAmount(order));
mallRefundRecordMapper.insert(mallRefundRecord);
refundOrderCacheUtil.put(mallRefundRecord.getLinkId(),mallRefundRecord);
orderAsyncProducer.sendRefundDelayMessage(mallRefundRecord.getId(), mallRefundRecord.getOrderId());
if (isRunnerOrder(order)) {
sendWorkerAfterSaleSms(mallRefundRecord,order);
} else {
sendShopAfterSaleNotice(order);
}
} else {
//商家、配送员都加一条,和商家+配送员都有关联
mallRefundRecord.setLinkId(mallRefundRecord.getShopId());
mallRefundRecord.setSettlementAmount(goodsPackageAmount(order));
mallRefundRecord.setRefundAmount(mallRefundRecord.getGoodsAmount().add(mallRefundRecord.getPackageFee()));
BigDecimal shopRefund = BigDecimal.ZERO;
if(ratio != null && ratio.compareTo(BigDecimal.ZERO) > 0){
@ -250,9 +406,10 @@ public class MallRefundRecordServiceImpl extends ServiceImpl<MallRefundRecordMap
//发送1小时延时MQ:超时未处理则自动同意(商家侧)
orderAsyncProducer.sendRefundDelayMessage(mallRefundRecord.getId(), mallRefundRecord.getOrderId());
sendShopAfterSaleNotice(order);
MallRefundRecord mallRefundRecord1 = mallRefundRecord;
MallRefundRecord mallRefundRecord1 = copyRefundRecord(mallRefundRecord);
mallRefundRecord1.setId(SnowFlakeUtil.nextId().toString());
mallRefundRecord1.setLinkId(mallRefundRecord.getWorkerId());
mallRefundRecord1.setSettlementAmount(deliveryAmount(order));
mallRefundRecord1.setRefundAmount(mallRefundRecord.getDeliveryFee());
if(ratio != null && ratio.compareTo(BigDecimal.ZERO) > 0){
mallRefundRecord1.setRefundAmount(order.getTotalAmount().subtract(shopRefund));
@ -263,9 +420,10 @@ public class MallRefundRecordServiceImpl extends ServiceImpl<MallRefundRecordMap
//发送1小时延时MQ:超时未处理则自动同意(配送员侧)
orderAsyncProducer.sendRefundDelayMessage(mallRefundRecord1.getId(), mallRefundRecord1.getOrderId());
sendWorkerAfterSaleSms(mallRefundRecord1,order);
}
}
}
if(!mallRefundRecord.getItems().isEmpty()){
if(mallRefundRecord.getItems() != null && !mallRefundRecord.getItems().isEmpty()){
for(MallReturnOrderGoods item : mallRefundRecord.getItems()){
mallReturnOrderGoodsMapper.insert(item);
}
@ -323,13 +481,15 @@ public class MallRefundRecordServiceImpl extends ServiceImpl<MallRefundRecordMap
//更新订单status、 配送单isReturn
if(mallRefundRecord.getRefundTypeStatus() != null && mallRefundRecord.getRefundTypeStatus() == 3){
//商家和配送员都有原因,需要判断另外角色处理了没再判断是否更新订单的状态
IPage<MallRefundRecord> page = new Page<>(PAGENUM, PAGESIZE);
IPage<MallRefundRecord> page = new Page<>(PAGENUM, 2);
MallRefundRecordPageQuery q = new MallRefundRecordPageQuery();
q.setOrderId(mallRefundRecord.getOrderId());
q.setOrderDesc(true);
IPage<MallRefundRecord> result = this.baseMapper.selectPageVO(page, q);
boolean hasEnd = result.getRecords().stream()
List<MallRefundRecord> 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<MallRefundRecordMap
.reduce(BigDecimal.ZERO, BigDecimal::add);*/
mallOrderDeliveryFeeRefundHelper.refundOrderWithAddedDeliveryFee(order, order.getTotalAmount());
if(mallRefundRecord.getLinkId().toUpperCase().startsWith("W")){
//配送员同意退款。扣掉余额
Worker worker = workerServiceImpl.findByWorkerId(mallRefundRecord.getLinkId());
BigDecimal refundAmount = mallRefundRecord.getRefundAmount();
// 获取当前的待结算金额(depoBal)和实际可提现金额(depoBalRel)
BigDecimal currentDepoBal = worker.getDepoBal();
BigDecimal currentDepoBalRel = worker.getDepoBalRel();
// 1. 优先从待结算金额(depoBal)中扣除
if (currentDepoBal.compareTo(refundAmount) >= 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<MallRefundRecordMap
}
//更新配送单isReturn
LambdaUpdateWrapper<MallDeliveryOrder> 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<MallRefundRecordMap
}
//更新配送单isReturn
LambdaUpdateWrapper<MallDeliveryOrder> 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<MallRefundRecordMap
}*/
refundWechatForAfterSaleWithOrderLock(order, mallRefundRecord);
if(mallRefundRecord.getLinkId().toUpperCase().startsWith("W")){
//配送员同意退款。扣掉余额
Worker worker = workerServiceImpl.findByWorkerId(mallRefundRecord.getLinkId());
BigDecimal refundAmount = mallRefundRecord.getRefundAmount();
// 获取当前的待结算金额(depoBal)和实际可提现金额(depoBalRel)
BigDecimal currentDepoBal = worker.getDepoBal();
BigDecimal currentDepoBalRel = worker.getDepoBalRel();
// 1. 优先从待结算金额(depoBal)中扣除
if (currentDepoBal.compareTo(refundAmount) >= 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<MallRefundRecordMap
}
refundWechatForRefundRecord(order, mallRefundRecord);
if(mallRefundRecord.getLinkId().toUpperCase().startsWith("W")){
Worker worker = workerServiceImpl.findByWorkerId(mallRefundRecord.getLinkId());
BigDecimal refundAmount = mallRefundRecord.getRefundAmount();
// 获取当前的待结算金额(depoBal)和实际可提现金额(depoBalRel)
BigDecimal currentDepoBal = worker.getDepoBal();
BigDecimal currentDepoBalRel = worker.getDepoBalRel();
// 1. 优先从待结算金额(depoBal)中扣除
if (currentDepoBal.compareTo(refundAmount) >= 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<MallRefundRecordMap
updateOrderStatus(mallRefundRecord.getOrderId(), STATUS_LAST_REFUNDED);
refundWechatForRefundRecord(order, mallRefundRecord);
if(mallRefundRecord.getLinkId().toUpperCase().startsWith("W")){
Worker worker = workerServiceImpl.findByWorkerId(mallRefundRecord.getLinkId());
BigDecimal refundAmount = mallRefundRecord.getRefundAmount();
// 获取当前的待结算金额(depoBal)和实际可提现金额(depoBalRel)
BigDecimal currentDepoBal = worker.getDepoBal();
BigDecimal currentDepoBalRel = worker.getDepoBalRel();
// 1. 优先从待结算金额(depoBal)中扣除
if (currentDepoBal.compareTo(refundAmount) >= 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<MallRefundRecordMap
mallRefundRecord.setOrderId(dbRecord.getOrderId());
mallRefundRecord.setLinkId(dbRecord.getLinkId());
mallRefundRecord.setRefundAmount(dbRecord.getRefundAmount());
mallRefundRecord.setSettlementAmount(dbRecord.getSettlementAmount());
mallRefundRecord.setRefundType(dbRecord.getRefundType());
mallRefundRecord.setRefundTypeStatus(dbRecord.getRefundTypeStatus());
mallRefundRecord.setRegionId(dbRecord.getRegionId());

53
hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/mybatis/MallSettlementRecordServiceImpl.java

@ -69,20 +69,27 @@ public class MallSettlementRecordServiceImpl extends ServiceImpl<MallSettlementR
shop.setBalance(balance.add(record.getSettlementAmount()));
shopService.update(shop);
//增加余额变动记录
boolean refundDeduction = isRefundDeduction(record);
DealingsRecord dealingsRecord = new DealingsRecord();
dealingsRecord.setDealingsWay(DealingsRecordConstant.TYPE_REMARK[6]);
dealingsRecord.setAmount(record.getSettlementAmount());
dealingsRecord.setDealingsWay(refundDeduction ? DealingsRecordConstant.TYPE_REMARK[12] : DealingsRecordConstant.TYPE_REMARK[6]);
dealingsRecord.setAmount(record.getSettlementAmount().abs());
dealingsRecord.setDealingsTime(new Date());
dealingsRecord.setLinkId(record.getId());
dealingsRecord.setLinkUserId(record.getShopId());
dealingsRecord.setLinkType(DealingsRecordConstant.TYPE[2]);
dealingsRecord.setDealingsType(DealingsRecordConstant.DEALINGS_TYPE[0]);
dealingsRecord.setDealingsType(refundDeduction ? DealingsRecordConstant.DEALINGS_TYPE[3] : DealingsRecordConstant.DEALINGS_TYPE[0]);
dealingsRecord.setCreateBy(record.getShopId());
dealingsRecordService.save(dealingsRecord);
}
}
}
private boolean isRefundDeduction(MallSettlementRecord record) {
return record != null
&& (Integer.valueOf(2).equals(record.getType())
|| (record.getSettlementAmount() != null && record.getSettlementAmount().compareTo(BigDecimal.ZERO) < 0));
}
@Autowired
private cc.hiver.mall.service.ShopTakeawayService shopTakeawayService;
@Autowired
@ -91,10 +98,10 @@ public class MallSettlementRecordServiceImpl extends ServiceImpl<MallSettlementR
@Override
public void processSettledRefund(cc.hiver.mall.entity.MallRefundRecord refund) {
MallOrder order = mallOrderService.getById(refund.getOrderId());
if (order == null || order.getSettlementStatus() == null || order.getSettlementStatus() == 0) {
if (order == null || refund.getLinkId() == null || refund.getLinkId().toUpperCase().startsWith("W")) {
return;
}
com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<MallSettlementRecord> 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<MallSettlementR
if (commissionRate == null) {
commissionRate = BigDecimal.ZERO;
}
com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<cc.hiver.mall.entity.MallReturnOrderGoods> goodsQw = new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<>();
goodsQw.eq(cc.hiver.mall.entity.MallReturnOrderGoods::getOrderId, refund.getId());
List<cc.hiver.mall.entity.MallReturnOrderGoods> 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<MallSettlementR
record.setType(2);
record.setBaseAmount(totalReturnPice);
record.setCommissionRate(commissionRate);
record.setCommissionAmount(totalReturnPice.multiply(commissionRate));
record.setCommissionAmount(commissionAmount);
record.setSettlementAmount(deductionAmount.negate());
record.setStatus(0);
record.setCreateTime(new Date());

2
hiver-modules/hiver-mall/src/main/resources/db/mall_refund_record_settlement_amount.sql

@ -0,0 +1,2 @@
ALTER TABLE `mall_refund_record`
ADD COLUMN `settlement_amount` decimal(10,2) DEFAULT NULL COMMENT '责任方结算/展示金额' AFTER `refund_amount`;

19
hiver-modules/hiver-mall/src/main/resources/mapper/DealingsRecordMapper.xml

@ -17,6 +17,7 @@
<result column="remark" jdbcType="VARCHAR" property="remark"/>
<result column="region_id" jdbcType="VARCHAR" property="regionId"/>
<result column="link_user_id" jdbcType="VARCHAR" property="linkUserId"/>
<result column="mobile" jdbcType="VARCHAR" property="mobile"/>
</resultMap>
<sql id="Example_Where_Clause">
<where>
@ -184,20 +185,26 @@
</select>
<select id="getDealingsRecordPageByRegionId" resultMap="BaseResultMap">
select *
select
tdr.*,
tu.mobile as mobile
from
t_dealings_record
t_dealings_record tdr
left join t_user tu on tu.id = tdr.link_user_id
where 1=1
<if test='customerBillQueryVo.regionId !=null'>
and region_id = #{customerBillQueryVo.regionId}
and tdr.region_id = #{customerBillQueryVo.regionId}
</if>
<if test='customerBillQueryVo.linkUserId !=null'>
and link_user_id = #{customerBillQueryVo.linkUserId}
and tdr.link_user_id = #{customerBillQueryVo.linkUserId}
</if>
<if test='customerBillQueryVo.dealingsWay !=null'>
and dealings_way = #{customerBillQueryVo.dealingsWay}
and tdr.dealings_way = #{customerBillQueryVo.dealingsWay}
</if>
order by create_time desc
<if test='customerBillQueryVo.excludeDealingsWay !=null and customerBillQueryVo.excludeDealingsWay != ""'>
and (tdr.dealings_way is null or tdr.dealings_way != #{customerBillQueryVo.excludeDealingsWay})
</if>
order by tdr.create_time desc
</select>
<select id="getDealingsRecordPageBySupplierId" resultType="cc.hiver.mall.bill.vo.SupplierBillPurchaseVo">

1
hiver-modules/hiver-mall/src/main/resources/mapper/MallRefundRecordMapper.xml

@ -8,6 +8,7 @@
<result column="order_id" property="orderId"/>
<result column="user_id" property="userId"/>
<result column="refund_amount" property="refundAmount"/>
<result column="settlement_amount" property="settlementAmount"/>
<result column="reason" property="reason"/>
<result column="reject_reason" property="rejectReason"/>
<result column="status" property="status"/>

Loading…
Cancel
Save