feat: 积分商城-完成

This commit is contained in:
2026-07-31 19:07:59 +08:00
parent 9be904bde0
commit 44cf66c570
10 changed files with 373 additions and 36 deletions
@@ -1,30 +1,124 @@
package com.budwk.app.zhgh.pointsmall.mallbridge.event.handlers;
import cn.hutool.core.bean.BeanUtil;
import com.budwk.app.sys.models.Sys_user;
import com.budwk.app.zhgh.pointsmall.mallbridge.dto.MallOrderEventDTO;
import com.budwk.app.zhgh.pointsmall.mallbridge.dto.MallOrderQueryDTO;
import com.budwk.app.zhgh.pointsmall.mallbridge.dto.OrderInfoDTO;
import com.budwk.app.zhgh.pointsmall.mallbridge.event.MallOrderEventHandler;
import com.budwk.app.zhgh.pointsmall.mallbridge.exception.MallBridgeError;
import com.budwk.app.zhgh.pointsmall.mallbridge.model.MallInboundResult;
import com.budwk.app.zhgh.pointsmall.mallbridge.service.MallInboundEventService;
import com.budwk.app.zhgh.pointsmall.mallbridge.model.MallOutboundResult;
import com.budwk.app.zhgh.pointsmall.mallbridge.service.MallOrderQueryOutboundService;
import com.budwk.app.zhgh.pointsmall.mallbridge.service.support.AbstractMallBridgeSupport;
import com.budwk.app.zhgh.pointsmall.order.enums.MallOrderStatusEnum;
import com.budwk.app.zhgh.pointsmall.order.models.PointsMallOrderExchange;
import com.budwk.app.zhgh.pointsmall.order.models.PointsMallOrderSub;
import com.budwk.app.zhgh.pointsmall.order.models.PointsMallOrderSubHistory;
import com.budwk.app.zhgh.pointsmall.order.service.PointsMallOrderSubService;
import lombok.extern.slf4j.Slf4j;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.trans.Atom;
import org.nutz.trans.Trans;
/**
* MallExchangeSubEventHandler
* orderType=5: 换货单事件处理器。
*/
@IocBean
public class MallExchangeSubEventHandler implements MallOrderEventHandler {
@Slf4j
@IocBean(args = {"refer:dao"})
public class MallExchangeSubEventHandler extends AbstractMallBridgeSupport implements MallOrderEventHandler {
@Inject
private MallInboundEventService inboundEventService;
private PointsMallOrderSubService pointsMallOrderSubService;
@Inject
private MallOrderQueryOutboundService mallOrderQueryOutboundService;
public MallExchangeSubEventHandler(Dao dao) {
super(dao);
}
@Override
public int getType() {
return 5;
}
/**
* 9.2.1 生成订单信息推送
* 订单类型为:5(换货单)时,mainOrderId 代表原子单IDorderId 代表换货单ID。
* 1. 重新调用9.2.2获取换货单详情。
* 2. 记录换货单流水记录。
* 3. 换货单状态只保存在退换货表中,不更新原子单退款积分。
*
* @param dto 请求参数
* @return 操作结果
*/
@Override
public MallInboundResult handle(MallOrderEventDTO dto) {
return inboundEventService.updateSubOrderStatus(dto, MallOrderStatusEnum.EXCHANGE);
if (!hasRequiredOrderEventFields(dto)) {
return MallInboundResult.fail(MallBridgeError.PARAM_ERROR.code(), "参数缺少");
}
Sys_user user = fetchUser(dto.getUserId());
if (user == null) {
return MallInboundResult.fail(-1, "用户不存在");
}
Integer orderStatus = MallOrderStatusEnum.EXCHANGE.getCode();
log.info("9.2.1生成订单信息推送开始:{},{}", orderStatus, dto);
// 订单类型为:5(换货单),mainOrderId 代表子单IDorderId 代表换货单ID
String subOrderId = dto.getMainOrderId();
String exchangeOrderId = dto.getOrderId();
PointsMallOrderSub sub = pointsMallOrderSubService.findBySubOrderExtId(subOrderId, dto.getSupplierId());
if (sub == null) {
log.info("9.2.1生成订单信息推送,订单不存在:{}", dto);
return MallInboundResult.fail(MallBridgeError.ORDER_NOT_EXISTS.code(), MallBridgeError.ORDER_NOT_EXISTS.message());
}
// 订单类型为:5(换货单),需限制同一个换货单只能换一次
PointsMallOrderExchange existed = dao.fetch(PointsMallOrderExchange.class, Cnd.where("orderMainId", "=", subOrderId)
.and("orderId", "=", exchangeOrderId).and("supplierId", "=", dto.getSupplierId()).and("delFlag", "=", false));
if (existed != null) {
log.info("9.2.1生成订单信息推送,该订单 已退货/已换货,请不要重复操作:{}", dto);
return MallInboundResult.fail(-1, "该订单 已退货/已换货,请不要重复操作");
}
log.info("订单类型为:4(退货单),5(换货单)时,调用 9.2.2获取订单详情接口:{}", dto);
OrderInfoDTO orderInfo;
try {
// 订单类型为:5(换货单)时,需重新调用 9.2.2获取订单详情接口
orderInfo = queryExchangeOrderInfo(dto);
} catch (Exception e) {
log.error("订单类型为:4(退货单),5(换货单)时,调用9.2.2 获取订单详情接口异常:{}", dto);
return MallInboundResult.fail(-1, "调用9.2.2获取订单详情接口异常,异常订单:" + dto.getOrderId());
}
PointsMallOrderExchange orderExchange = toExchange(dto, orderInfo, sub, orderStatus);
Trans.exec((Atom) () -> {
// 把推送过来的换货单存入退换货表
dao.insert(orderExchange);
log.info("9.2.1生成订单信息推送-记录退换货的订单流水记录");
// 记录推送的子订单流水记录
PointsMallOrderSubHistory history = BeanUtil.copyProperties(orderExchange, PointsMallOrderSubHistory.class);
history.setId(null);
history.setMainOrderId(orderExchange.getOrderMainId());
history.setOrderState(orderStatus);
dao.insert(history);
});
log.info("9.2.1生成订单信息推送结束!");
return MallInboundResult.success();
}
private OrderInfoDTO queryExchangeOrderInfo(MallOrderEventDTO dto) {
MallOrderQueryDTO queryDTO = new MallOrderQueryDTO();
queryDTO.setSupplierId(dto.getSupplierId());
queryDTO.setOrderType(dto.getOrderType());
queryDTO.setOrderId(dto.getOrderId());
MallOutboundResult result = mallOrderQueryOutboundService.queryOrderInfo(queryDTO);
if (result == null || result.getResultCode() != 0 || result.getOrderInfo() == null || result.getOrderInfo().isEmpty()) {
log.error("订单类型为:4(退货单),5(换货单)时,调用9.2.2 获取订单详情接口异常:{},{}", dto, result);
throw new RuntimeException("调用9.2.2获取订单详情接口异常");
}
return result.getOrderInfo().get(0);
}
}
@@ -1,30 +1,178 @@
package com.budwk.app.zhgh.pointsmall.mallbridge.event.handlers;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.sys.models.Sys_user;
import com.budwk.app.zhgh.pointsmall.mallbridge.dto.MallOrderEventDTO;
import com.budwk.app.zhgh.pointsmall.mallbridge.dto.MallOrderQueryDTO;
import com.budwk.app.zhgh.pointsmall.mallbridge.dto.OrderInfoDTO;
import com.budwk.app.zhgh.pointsmall.mallbridge.event.MallOrderEventHandler;
import com.budwk.app.zhgh.pointsmall.mallbridge.exception.MallBridgeError;
import com.budwk.app.zhgh.pointsmall.mallbridge.model.MallInboundResult;
import com.budwk.app.zhgh.pointsmall.mallbridge.service.MallInboundEventService;
import com.budwk.app.zhgh.pointsmall.mallbridge.model.MallOutboundResult;
import com.budwk.app.zhgh.pointsmall.mallbridge.service.MallCallPMessagePushService;
import com.budwk.app.zhgh.pointsmall.mallbridge.service.MallOrderQueryOutboundService;
import com.budwk.app.zhgh.pointsmall.mallbridge.service.support.AbstractMallBridgeSupport;
import com.budwk.app.zhgh.pointsmall.order.enums.MallOrderStatusEnum;
import com.budwk.app.zhgh.pointsmall.order.models.PointsMallOrderExchange;
import com.budwk.app.zhgh.pointsmall.order.models.PointsMallOrderSub;
import com.budwk.app.zhgh.pointsmall.order.models.PointsMallOrderSubHistory;
import com.budwk.app.zhgh.pointsmall.order.service.PointsMallOrderService;
import com.budwk.app.zhgh.pointsmall.order.service.PointsMallOrderSubService;
import com.budwk.app.zhgh.pointsmall.points.service.PointsMallPointsLockService;
import lombok.extern.slf4j.Slf4j;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.trans.Atom;
import org.nutz.trans.Trans;
import java.math.BigDecimal;
import java.util.Date;
/**
* MallSubOrderReturnEventHandler
* orderType=4: 退货单事件处理器。
*/
@IocBean
public class MallSubOrderReturnEventHandler implements MallOrderEventHandler {
@Slf4j
@IocBean(args = {"refer:dao"})
public class MallSubOrderReturnEventHandler extends AbstractMallBridgeSupport implements MallOrderEventHandler {
@Inject
private MallInboundEventService inboundEventService;
private PointsMallPointsLockService pointsMallPointsLockService;
@Inject
private PointsMallOrderService pointsMallOrderService;
@Inject
private PointsMallOrderSubService pointsMallOrderSubService;
@Inject
private MallCallPMessagePushService mallCallPMessagePushService;
@Inject
private MallOrderQueryOutboundService mallOrderQueryOutboundService;
public MallSubOrderReturnEventHandler(Dao dao) {
super(dao);
}
@Override
public int getType() {
return 4;
}
/**
* 9.2.1 生成订单信息推送
* 订单类型为:4(退货单)时,mainOrderId 代表原子单IDorderId 代表退货单ID。
* 1. 重新调用9.2.2获取退货单详情。
* 2. 记录退货单流水记录。
* 3. 退货单退回用户积分。
* 4. 判断子单是否都完成了,修改主单状态。
*
* @param dto 请求参数
* @return 操作结果
*/
@Override
public MallInboundResult handle(MallOrderEventDTO dto) {
return inboundEventService.updateSubOrderStatus(dto, MallOrderStatusEnum.REFUNDED);
if (!hasRequiredOrderEventFields(dto)) {
return MallInboundResult.fail(MallBridgeError.PARAM_ERROR.code(), "参数缺少");
}
Sys_user user = fetchUser(dto.getUserId());
if (user == null) {
return MallInboundResult.fail(-1, "用户不存在");
}
Integer orderStatus = MallOrderStatusEnum.REFUNDED.getCode();
log.info("9.2.1生成订单信息推送开始:{},{}", orderStatus, dto);
// 订单类型为:4(退货单),mainOrderId 代表子单IDorderId 代表退货单ID
String subOrderId = dto.getMainOrderId();
String exchangeOrderId = dto.getOrderId();
PointsMallOrderSub sub = pointsMallOrderSubService.findBySubOrderExtId(subOrderId, dto.getSupplierId());
if (sub == null) {
log.info("9.2.1生成订单信息推送,订单不存在:{}", dto);
return MallInboundResult.fail(MallBridgeError.ORDER_NOT_EXISTS.code(), MallBridgeError.ORDER_NOT_EXISTS.message());
}
// 订单类型为:4(退货单),需限制同一个退货单只能退一次
PointsMallOrderExchange existed = dao.fetch(PointsMallOrderExchange.class, Cnd.where("orderMainId", "=", subOrderId)
.and("orderId", "=", exchangeOrderId).and("supplierId", "=", dto.getSupplierId()).and("delFlag", "=", false));
if (existed != null) {
log.info("9.2.1生成订单信息推送,该订单 已退货/已换货,请不要重复操作:{}", dto);
return MallInboundResult.fail(-1, "该订单 已退货/已换货,请不要重复操作");
}
log.info("订单类型为:4(退货单),5(换货单)时,调用 9.2.2获取订单详情接口:{}", dto);
OrderInfoDTO orderInfo;
try {
// 订单类型为:4(退货单)时,需重新调用 9.2.2获取订单详情接口
orderInfo = queryReturnOrderInfo(dto);
} catch (Exception e) {
log.error("订单类型为:4(退货单),5(换货单)时,调用9.2.2 获取订单详情接口异常:{}", dto);
return MallInboundResult.fail(-1, "调用9.2.2获取订单详情接口异常,异常订单:" + dto.getOrderId());
}
// 订单退款积分【订单为退货单时有值】
BigDecimal refund = nvl(orderInfo.getRefund());
BigDecimal refunded = nvl(sub.getRefund());
BigDecimal pointsPrice = nvl(sub.getPointsPrice());
// 订单退货
if (pointsPrice.compareTo(refunded.add(refund)) < 0) {
// 订单退款积分 如果超过 子订单锁定积分,则校验不通过
log.info("当前子单:{},订单退款积分:{},超过子表消耗积分:{}", sub.getOrderId(), refund, pointsPrice);
return MallInboundResult.fail(-1, "该订单 已退积分超过下单积分!");
}
Date now = new Date();
PointsMallOrderExchange orderExchange = toExchange(dto, orderInfo, sub, orderStatus);
// 退货单需要更新订单子表的退款金额,对账使用;退满时更新子单状态
BigDecimal refundSum = refunded.add(refund);
PointsMallOrderSub modifySub = new PointsMallOrderSub();
modifySub.setId(sub.getId());
modifySub.setRefund(refundSum);
modifySub.setOrderUpdateTime(now);
if (modifySub.getRefund().compareTo(pointsPrice) == 0) {
modifySub.setOrderState(orderStatus);
}
// 记录推送的子订单流水记录
PointsMallOrderSubHistory history = BeanUtil.copyProperties(orderExchange, PointsMallOrderSubHistory.class);
history.setId(null);
history.setMainOrderId(orderExchange.getOrderMainId());
history.setOrderState(orderStatus);
log.info("9.2.1生成订单信息推送-记录退换货的订单流水记录");
log.info("9.2.1生成订单信息推送-订单状态为 已取消 释放积分 为 已退货 退回用户积分");
Trans.exec((Atom) () -> {
pointsMallOrderSubService.updateSubOrder(modifySub);
// 把推送过来的退货单存入退换货表
dao.insert(orderExchange);
dao.insert(history);
// 释放积分/返回用户积分
pointsMallPointsLockService.releaseOrReturnPoints(sub, orderStatus, refund);
// 更新主订单状态,所有子单退货/取消/完成后,修改主单状态
pointsMallOrderService.updateMainOrderStatus(sub.getMainOrderId(), sub.getSupplierId());
});
try {
// callP消息推送
PointsMallOrderSub notifySub = BeanUtil.copyProperties(sub, PointsMallOrderSub.class);
notifySub.setOrderId(dto.getOrderId());
notifySub.setPointsPrice(refund);
notifySub.setTotalPrice(orderInfo.getTotalPrice());
notifySub.setWPayOrAPay(orderInfo.getWPayOrAPay());
notifySub.setExtJson(orderExchange.getExtJson());
mallCallPMessagePushService.pushMessageToGlobal(StrUtil.blankToDefault(user.getUsername(), user.getLoginname()), notifySub);
} catch (Exception e) {
log.error("9.2.1 子单取消 或 退货,callP消息推送: {}, {}", dto, e.getMessage());
}
log.info("9.2.1生成订单信息推送结束!");
return MallInboundResult.success();
}
private OrderInfoDTO queryReturnOrderInfo(MallOrderEventDTO dto) {
MallOrderQueryDTO queryDTO = new MallOrderQueryDTO();
queryDTO.setSupplierId(dto.getSupplierId());
queryDTO.setOrderType(dto.getOrderType());
queryDTO.setOrderId(dto.getOrderId());
MallOutboundResult result = mallOrderQueryOutboundService.queryOrderInfo(queryDTO);
if (result == null || result.getResultCode() != 0 || result.getOrderInfo() == null || result.getOrderInfo().isEmpty()) {
log.error("订单类型为:4(退货单),5(换货单)时,调用9.2.2 获取订单详情接口异常:{},{}", dto, result);
throw new RuntimeException("调用9.2.2获取订单详情接口异常");
}
return result.getOrderInfo().get(0);
}
}
@@ -4,10 +4,13 @@ import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.budwk.app.sys.models.Sys_user;
import com.budwk.app.zhgh.pointsmall.invoice.models.PointsMallInvoiceInfo;
import com.budwk.app.zhgh.pointsmall.mallbridge.dto.InvoiceInfoDTO;
import com.budwk.app.zhgh.pointsmall.mallbridge.dto.MallOrderEventDTO;
import com.budwk.app.zhgh.pointsmall.mallbridge.dto.OrderInfoDTO;
import com.budwk.app.zhgh.pointsmall.mallbridge.dto.OrderProInfoDTO;
import com.budwk.app.zhgh.pointsmall.order.models.PointsMallOrderExchange;
import com.budwk.app.zhgh.pointsmall.order.models.PointsMallOrderMain;
import com.budwk.app.zhgh.pointsmall.order.models.PointsMallOrderSub;
import com.budwk.app.zhgh.pointsmall.order.models.PointsMallOrderSubProduct;
@@ -22,6 +25,7 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
@@ -49,6 +53,64 @@ public abstract class AbstractMallBridgeSupport {
this.dao = dao;
}
protected boolean hasRequiredOrderEventFields(MallOrderEventDTO dto) {
return dto != null && !StrUtil.hasBlank(dto.getSupplierId(), dto.getOrderId(), dto.getMainOrderId(), dto.getUserId());
}
protected Sys_user fetchUser(String userId) {
Sys_user user = dao.fetch(Sys_user.class, Cnd.where("id", "=", userId).and("disabled", "=", false).and("delFlag", "=", false));
if (user != null) {
return user;
}
return dao.fetch(Sys_user.class, Cnd.where("loginname", "=", userId).and("disabled", "=", false).and("delFlag", "=", false));
}
protected PointsMallOrderExchange toExchange(MallOrderEventDTO dto, OrderInfoDTO orderInfo, PointsMallOrderSub sub, Integer orderStatus) {
PointsMallOrderExchange exchange = new PointsMallOrderExchange();
exchange.setOrderMainId(dto.getMainOrderId());
exchange.setOrderId(dto.getOrderId());
exchange.setSupplierId(dto.getSupplierId());
exchange.setUserId(dto.getUserId());
exchange.setAplName(orderInfo.getAplName());
exchange.setOrderCreateTime(parseDate(orderInfo.getCreateTime()));
exchange.setOrderUpdateTime(parseDate(orderInfo.getUpdateTime()));
exchange.setOrderCompleteTime(parseDate(StrUtil.blankToDefault(orderInfo.getCompleteTime(), orderInfo.getOrderFinishTime())));
exchange.setDeliveryStatus(parseInteger(orderInfo.getDeliveryStatus()));
exchange.setFreightCost(orderInfo.getFreightCost());
exchange.setRefund(orderInfo.getRefund());
exchange.setLogisticsOrderId(orderInfo.getLogisticsOrderId());
exchange.setCrrgBsnNm(orderInfo.getCrrgBsnNm());
exchange.setOrderState(orderStatus);
exchange.setTotalPrice(orderInfo.getTotalPrice());
exchange.setWPayOrAPay(orderInfo.getWPayOrAPay());
exchange.setPointsPrice(orderInfo.getPointsPrice());
exchange.setInvoiceCode(orderInfo.getInvoiceCode());
// 商品信息:退换货单详情接口返回的商品信息补齐原订单中的图片和文件信息
exchange.setExtJson(JSONUtil.toJsonStr(mergeProductInfo(orderInfo.getOrderProInfos(), sub.getExtJson())));
return exchange;
}
protected List<OrderProInfoDTO> mergeProductInfo(List<OrderProInfoDTO> products, String subExtJson) {
if (products == null || products.isEmpty()) {
return Collections.emptyList();
}
List<OrderProInfoDTO> subProducts = StrUtil.isBlank(subExtJson) ? Collections.emptyList() : JSONUtil.toList(subExtJson, OrderProInfoDTO.class);
// 将原子单商品列表转换为 Map,key 为 sku;若 sku 重复,保留第一个
Map<String, OrderProInfoDTO> subProductMap = subProducts.stream()
.filter(item -> StrUtil.isNotBlank(item.getSku()))
.collect(Collectors.toMap(OrderProInfoDTO::getSku, item -> item, (left, right) -> left));
// 遍历退换货单商品,从原子单商品 Map 中获取对应图片和文件信息并赋值
products.forEach(product -> {
OrderProInfoDTO origin = subProductMap.get(product.getSku());
if (origin != null) {
product.setPicInfo(origin.getPicInfo());
product.setFileId(origin.getFileId());
product.setFilePath(origin.getFilePath());
}
});
return products;
}
protected PointsMallOrderMain toMain(String supplierId, String userId, OrderInfoDTO orderInfo, Integer state) {
PointsMallOrderMain main = new PointsMallOrderMain();
main.setOrderId(orderInfo.getOrderId());
@@ -6,6 +6,7 @@ import com.budwk.app.zhgh.pointsmall.order.models.PointsMallOrderExchange;
import com.budwk.app.zhgh.pointsmall.order.models.PointsMallOrderSub;
import com.budwk.app.zhgh.pointsmall.order.param.PointsMallOrderPageParam;
import com.budwk.app.zhgh.pointsmall.order.service.PointsMallOrderService;
import com.budwk.app.zhgh.pointsmall.order.service.PointsMallOrderSubService;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.mvc.adaptor.JsonAdaptor;
@@ -23,6 +24,8 @@ public class PointsMallOrderSubController {
@Inject
private PointsMallOrderService pointsMallOrderService;
@Inject
private PointsMallOrderSubService pointsMallOrderSubService;
@POST
@At("/page")
@@ -56,7 +59,7 @@ public class PointsMallOrderSubController {
@At("/update")
@SaCheckPermission("points.mall.order")
public Result update(@Param("..") PointsMallOrderSub orderSub) {
return result(pointsMallOrderService.updateSub(orderSub));
return result(pointsMallOrderSubService.updateSubOrder(orderSub));
}
@POST
@@ -33,8 +33,6 @@ public interface PointsMallOrderService extends BaseService<PointsMallOrderMain>
List<NutMap> listExchangeProducts(String orderId);
boolean updateSub(PointsMallOrderSub orderSub);
boolean deleteSub(String id);
boolean updateExchange(PointsMallOrderExchange exchange);
@@ -14,4 +14,9 @@ public interface PointsMallOrderSubService extends BaseService<PointsMallOrderSu
* 更新子订单状态和更新时间。
*/
boolean updateSubOrderStatus(PointsMallOrderSub orderSub);
/**
* 更新子订单非空字段和更新时间。
*/
boolean updateSubOrder(PointsMallOrderSub orderSub);
}
@@ -266,15 +266,6 @@ public class PointsMallOrderServiceImpl extends BaseServiceImpl<PointsMallOrderM
.addv("filePath", item.getString("filePath"));
}
@Override
public boolean updateSub(PointsMallOrderSub orderSub) {
if (orderSub == null || StrUtil.isBlank(orderSub.getId())) {
return false;
}
orderSub.setOrderUpdateTime(new Date());
return dao().updateIgnoreNull(orderSub) > 0;
}
@Override
public boolean deleteSub(String id) {
if (StrUtil.isBlank(id)) {
@@ -36,4 +36,13 @@ public class PointsMallOrderSubServiceImpl extends BaseServiceImpl<PointsMallOrd
.add("orderUpdateTime", orderSub.getOrderUpdateTime() == null ? new Date() : orderSub.getOrderUpdateTime());
return dao().update(PointsMallOrderSub.class, chain, Cnd.where("id", "=", orderSub.getId()).and("delFlag", "=", false)) > 0;
}
@Override
public boolean updateSubOrder(PointsMallOrderSub orderSub) {
if (orderSub == null || StrUtil.isBlank(orderSub.getId())) {
return false;
}
orderSub.setOrderUpdateTime(new Date());
return dao().updateIgnoreNull(orderSub) > 0;
}
}
@@ -1,6 +1,8 @@
package com.budwk.app.zhgh.pointsmall.points.service.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.zhgh.pointsmall.order.enums.MallOrderStatusEnum;
import com.budwk.app.zhgh.pointsmall.order.models.PointsMallOrderMain;
import com.budwk.app.zhgh.pointsmall.order.models.PointsMallOrderSub;
import com.budwk.app.zhgh.pointsmall.points.enums.PointsMallPointLockStatusEnum;
@@ -120,6 +122,7 @@ public class PointsMallPointsLockServiceImpl implements PointsMallPointsLockServ
if (subOrder == null || StrUtil.hasBlank(subOrder.getSupplierId(), subOrder.getOrderId(), subOrder.getMainOrderId())) {
return;
}
log.info("9.2.1 生成订单信息推送-订单状态为已取消或者已退货,释放积分开始执行");
PointsMallMainPointsLock mainLock = activeMainLock(subOrder.getUserId(), subOrder.getSupplierId(), subOrder.getMainOrderId());
if (mainLock == null) {
return;
@@ -128,27 +131,51 @@ public class PointsMallPointsLockServiceImpl implements PointsMallPointsLockServ
if (lastSubLock == null) {
return;
}
BigDecimal returnPoint = Integer.valueOf(7).equals(orderState) ? nvl(refund) : nvl(lastSubLock.getChangePoints()).negate();
if (returnPoint.compareTo(BigDecimal.ZERO) <= 0) {
return;
BigDecimal subLockPoint = nvl(lastSubLock.getChangePoints()).abs();
// 订单取消,判断积分有没有超过主单锁定的积分
if (Objects.equals(MallOrderStatusEnum.CANCELLED.getCode(), orderState) && nvl(mainLock.getLockAmount()).compareTo(subLockPoint) < 0) {
log.info("当前子单{}:释放的积分{},超过主表表已锁定积分{}", subOrder.getOrderId(), subLockPoint, mainLock.getLockAmount());
throw new IllegalArgumentException("积分不足,超过主表表已锁定积分");
}
// 新增一条积分记录,积分就是原订单的取反积分
PointsMallSubPointsLock insert = new PointsMallSubPointsLock();
insert.setUserId(subOrder.getUserId());
insert.setMainOrderId(subOrder.getMainOrderId());
insert.setSubOrderId(subOrder.getOrderId());
insert.setSupplierId(subOrder.getSupplierId());
BeanUtil.copyProperties(lastSubLock, insert);
// 确保是新记录
insert.setId(null);
insert.setOrderSubStatus(orderState);
// 如果是退货场景,则取值订单退款积分
BigDecimal returnPoint = Objects.equals(MallOrderStatusEnum.REFUNDED.getCode(), orderState) ? nvl(refund) : nvl(lastSubLock.getChangePoints()).negate();
insert.setChangePoints(returnPoint);
// 子单的积分没有释放或锁定状态,记录是怎么加减分的(订单状态)
insert.setOrderSubStatus(orderState);
insert.setLockTime(new Date());
dao.insert(insert);
BigDecimal after = nvl(mainLock.getLockAmount()).subtract(returnPoint);
if (after.compareTo(BigDecimal.ZERO) < 0) {
after = BigDecimal.ZERO;
// 如果订单是已妥投/取消订单,就需要把主单的锁定积分给释放掉
if (Objects.equals(subOrder.getOrderState(), MallOrderStatusEnum.RECEIVED.getCode())
|| Objects.equals(orderState, MallOrderStatusEnum.CANCELLED.getCode())) {
// 同步修改主单锁定的积分,把扣减的子单积分恢复到主单的锁定积分里面
org.nutz.dao.sql.Sql updateSql = org.nutz.dao.Sqls.create("update points_mall_main_points_lock set lockAmount = case when lockAmount - @returnPoint < 0 then 0 else lockAmount - @returnPoint end where id = @id");
updateSql.params().set("returnPoint", returnPoint);
updateSql.params().set("id", mainLock.getId());
dao.execute(updateSql);
log.info("9.2.1 生成订单信息推送-订单状态为已取消或者已退货,释放积分结束");
return;
}
dao.update(PointsMallMainPointsLock.class, Chain.make("lockAmount", after), Cnd.where("id", "=", mainLock.getId()));
log.info("积分商城子单积分释放完成,supplierId={}mainOrderId={}subOrderId={}returnPoint={}",
subOrder.getSupplierId(), subOrder.getMainOrderId(), subOrder.getOrderId(), returnPoint);
if (!Objects.equals(subOrder.getOrderState(), MallOrderStatusEnum.COMPLETED.getCode())) {
return;
}
// 如果CallP确认收货了,直接给用户加积分
/// 退货还需要给用户积分加return
PointsMallUserPoints userPoints = dao.fetch(PointsMallUserPoints.class, Cnd.where("userId", "=", subOrder.getUserId()).and("delFlag", "=", false));
if (userPoints == null) {
throw new IllegalArgumentException("用户积分不存在");
}
org.nutz.dao.sql.Sql userPointsSql = org.nutz.dao.Sqls.create("update points_mall_user_points set availablePoints = availablePoints + @returnPoint where userId = @userId");
userPointsSql.params().set("returnPoint", returnPoint);
userPointsSql.params().set("userId", subOrder.getUserId());
dao.execute(userPointsSql);
}
@Override
@@ -309,7 +309,7 @@ layout("/layouts/platform.html"){
{ value: "1", label: "已支付" },
{ value: "2", label: "进行中" },
{ value: "3", label: "已取消" },
{ value: "4", label: "已签收" },
{ value: "4", label: "已妥投" },
{ value: "5", label: "已完成" },
{ value: "6", label: "换货" },
{ value: "7", label: "退货" },