feat: 已实现订单基本逻辑,到完成,却订单售后

This commit is contained in:
2026-07-30 15:55:00 +08:00
parent 1cbacf987d
commit 5de4d6f9f4
15 changed files with 781 additions and 176 deletions
@@ -50,8 +50,10 @@ public class SysV4MsgController {
m.title,
m.content,
m.type,
m.sendTime,
r.isRead,
r.readTime
r.readTime,
r.createdAt
FROM
global_message m
INNER JOIN global_message_receiver r ON m.id = r.messageId
@@ -69,7 +71,7 @@ public class SysV4MsgController {
cnd.andEX("m.type", "=", type);
cnd.desc("m.sendTime");
cnd.desc("m.sendTime").desc("r.createdAt");
sql.setCondition(cnd);
String title = "审批待办";
@@ -45,4 +45,24 @@ public class GlobalMessageSendRequest {
*/
private List<String> receiverIds;
/**
* 是否系统发送
*/
private Boolean systemSend;
/**
* 发送人ID
*/
private String senderId;
/**
* 发送人名称
*/
private String senderName;
/**
* 发送人工号
*/
private String senderLoginName;
}
@@ -97,6 +97,66 @@ public class GlobalMessageSendService {
sendMessage(request);
}
/**
* 发送系统消息(不依赖当前登录token)
*/
public void sendSystemMessage(String title, String content, Integer type, List<String> receiverIds, JSONObject config) {
GlobalMessageSendRequest request = new GlobalMessageSendRequest();
request.setTitle(title);
request.setContent(content);
request.setType(type);
request.setReceiverIds(receiverIds);
request.setConfig(config);
request.setSystemSend(true);
request.setSenderId("system");
request.setSenderName("系统");
request.setSenderLoginName("system");
sendMessage(request);
}
/**
* 发送本地系统消息(不依赖当前登录token)
*/
public void sendLocalSystemMessage(String title, String content, Integer type, List<String> receiverIds, JSONObject config) {
GlobalMessageSendRequest request = new GlobalMessageSendRequest();
request.setTitle(title);
request.setContent(content);
request.setType(type);
request.setReceiverIds(receiverIds);
request.setConfig(config);
request.setSystemSend(true);
request.setSenderId("system");
request.setSenderName("系统");
request.setSenderLoginName("system");
sendLocalMessage(request);
}
/**
* 发送本地消息(使用请求对象)
*/
public void sendLocalMessage(GlobalMessageSendRequest request) {
try {
log.info("开始发送本地全局消息,标题:{},接收人数量:{}", request.getTitle(),
request.getReceiverIds() != null ? request.getReceiverIds().size() : 0);
validateRequest(request);
applySystemSenderConfig(request);
if (localStrategy == null) {
throw new RuntimeException("本地消息发送策略未找到,系统无法正常工作");
}
localStrategy.send(request.getTitle(), request.getContent(), request.getType(),
request.getReceiverIds(), request.getConfig());
log.info("本地全局消息发送完成,标题:{}", request.getTitle());
} catch (Exception e) {
log.error("本地全局消息发送失败,标题:{},错误:{}", request.getTitle(), e.getMessage(), e);
throw new RuntimeException("本地消息发送失败:" + e.getMessage(), e);
}
}
/**
* 发送消息(使用请求对象)
*/
@@ -107,6 +167,7 @@ public class GlobalMessageSendService {
// 参数校验
validateRequest(request);
applySystemSenderConfig(request);
// 获取启用的策略
List<GlobalMessageSendStrategy> enabledStrategies = getEnabledStrategies();
@@ -161,6 +222,21 @@ public class GlobalMessageSendService {
}
}
private void applySystemSenderConfig(GlobalMessageSendRequest request) {
if (!Boolean.TRUE.equals(request.getSystemSend())) {
return;
}
JSONObject config = request.getConfig();
if (config == null) {
config = new JSONObject();
request.setConfig(config);
}
config.set("systemSend", true);
config.set("senderId", request.getSenderId());
config.set("senderName", request.getSenderName());
config.set("senderLoginName", request.getSenderLoginName());
}
/**
* 参数校验
*/
@@ -13,6 +13,7 @@ import org.nutz.dao.Dao;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import java.util.Date;
import java.util.List;
/**
@@ -56,9 +57,15 @@ public class LocalMessageSendStrategy implements GlobalMessageSendStrategy {
globalMessage.setTitle(title);
globalMessage.setContent(content);
globalMessage.setType(type);
globalMessage.setSenderId(SecurityUtil.getUserId());
globalMessage.setSenderName(SecurityUtil.getUserUsername());
globalMessage.setSenderLoginName(SecurityUtil.getUserLoginname());
if (config != null && Boolean.TRUE.equals(config.getBool("systemSend"))) {
globalMessage.setSenderId(config.getStr("senderId"));
globalMessage.setSenderName(config.getStr("senderName"));
globalMessage.setSenderLoginName(config.getStr("senderLoginName"));
} else {
globalMessage.setSenderId(SecurityUtil.getUserId());
globalMessage.setSenderName(SecurityUtil.getUserUsername());
globalMessage.setSenderLoginName(SecurityUtil.getUserLoginname());
}
globalMessage.setStatus(1); // 草稿状态
globalMessage.setSendSuccess(false);
dao.insert(globalMessage);
@@ -77,6 +84,7 @@ public class LocalMessageSendStrategy implements GlobalMessageSendStrategy {
// 更新消息状态为已发送
globalMessage.setStatus(2);
globalMessage.setSendTime(new Date());
globalMessage.setSendSuccess(true);
globalMessage.setSendResult("本地消息发送成功");
dao.update(globalMessage);
@@ -10,5 +10,9 @@ public class MallOrderEventDTO {
private String orderId;
private String mainOrderId;
private String userId;
private Integer deliveryStatus;
private String deliveryTime;
private String logisticsOrderId;
private String crrgBsnNm;
private Long time;
}
@@ -0,0 +1,29 @@
package com.budwk.app.zhgh.pointsmall.mallbridge.event.handlers;
import com.budwk.app.zhgh.pointsmall.mallbridge.dto.MallOrderEventDTO;
import com.budwk.app.zhgh.pointsmall.mallbridge.event.MallOrderEventHandler;
import com.budwk.app.zhgh.pointsmall.mallbridge.model.MallInboundResult;
import com.budwk.app.zhgh.pointsmall.mallbridge.service.MallInboundEventService;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
/**
* MallShipOrderEventHandler
* orderType=99: 供应商已发货 / 更新发货状态。
*/
@IocBean
public class MallShipOrderEventHandler implements MallOrderEventHandler {
@Inject
private MallInboundEventService inboundEventService;
@Override
public int getType() {
return 99;
}
@Override
public MallInboundResult handle(MallOrderEventDTO dto) {
return inboundEventService.updateDeliveryStatus(dto);
}
}
@@ -0,0 +1,32 @@
package com.budwk.app.zhgh.pointsmall.mallbridge.exception;
/**
* MallBridgeError
* 说明: 商城桥接的统一错误码枚举, 包含HTTP风格的resultCode与默认提示文案。
* 用于抛出MallBridgeException时传递标准化的错误信息。
*/
public enum MallBridgeError {
ERROR(-1, "校验失败"),
AUTH_FAIL(401, "鉴权失败"),
PARAM_ERROR(400, "参数错误"),
ORDER_EXISTS(409, "订单已存在"),
ORDER_NOT_EXISTS(410, "订单不存在"),
NOT_FOUND(404, "资源不存在"),
SERVER_ERROR(500, "服务器内部错误");
private final int code;
private final String message;
MallBridgeError(int code, String message) {
this.code = code;
this.message = message;
}
public int code() {
return code;
}
public String message() {
return message;
}
}
@@ -14,6 +14,7 @@ import com.budwk.app.zhgh.pointsmall.mallbridge.event.handlers.MallCancelSubOrde
import com.budwk.app.zhgh.pointsmall.mallbridge.event.handlers.MallConfirmReceiptEventHandler;
import com.budwk.app.zhgh.pointsmall.mallbridge.event.handlers.MallExchangeSubEventHandler;
import com.budwk.app.zhgh.pointsmall.mallbridge.event.handlers.MallInvoiceInfoEventHandler;
import com.budwk.app.zhgh.pointsmall.mallbridge.event.handlers.MallShipOrderEventHandler;
import com.budwk.app.zhgh.pointsmall.mallbridge.event.handlers.MallSplitSubOrderEventHandler;
import com.budwk.app.zhgh.pointsmall.mallbridge.event.handlers.MallSubOrderReturnEventHandler;
import com.budwk.app.zhgh.pointsmall.mallbridge.model.MallInboundResult;
@@ -69,6 +70,8 @@ public class MallInboundEventService extends AbstractMallBridgeSupport {
private MallAbolishSubOrderEventHandler mallAbolishSubOrderEventHandler;
@Inject
private MallInvoiceInfoEventHandler mallInvoiceInfoEventHandler;
@Inject
private MallShipOrderEventHandler mallShipOrderEventHandler;
public MallInboundEventService(Dao dao) {
super(dao);
@@ -105,6 +108,7 @@ public class MallInboundEventService extends AbstractMallBridgeSupport {
register(handlerRegistry, mallCancelPayedMainOrderEventHandler);
register(handlerRegistry, mallAbolishSubOrderEventHandler);
register(handlerRegistry, mallInvoiceInfoEventHandler);
register(handlerRegistry, mallShipOrderEventHandler);
return handlerRegistry;
}
@@ -346,6 +350,66 @@ public class MallInboundEventService extends AbstractMallBridgeSupport {
}
}
public MallInboundResult updateDeliveryStatus(MallOrderEventDTO dto) {
if (StrUtil.isBlank(dto.getSupplierId()) || StrUtil.isBlank(dto.getOrderId())) {
return MallInboundResult.fail(400, "供应商或订单不能为空");
}
List<String> orderIds = splitIds(dto.getOrderId());
if (orderIds.isEmpty()) {
return MallInboundResult.fail(400, "订单信息不能为空");
}
Date deliveryTime = parseDate(dto.getDeliveryTime());
if (deliveryTime == null) {
deliveryTime = new Date();
}
Cnd subCnd = Cnd.where("supplierId", "=", dto.getSupplierId())
.and("orderId", "in", orderIds)
.and("delFlag", "=", false);
if (StrUtil.isNotBlank(dto.getUserId())) {
subCnd.and("userId", "=", dto.getUserId());
}
List<PointsMallOrderSub> subs = dao.query(PointsMallOrderSub.class, subCnd);
if (subs.isEmpty()) {
return MallInboundResult.fail(404, "订单不存在");
}
Date finalDeliveryTime = deliveryTime;
Integer deliveredStatus = 1;
Trans.exec((Atom) () -> {
Chain subChain = Chain.make("deliveryStatus", deliveredStatus)
.add("deliveryTime", finalDeliveryTime);
if (StrUtil.isNotBlank(dto.getLogisticsOrderId())) {
subChain.add("logisticsOrderId", dto.getLogisticsOrderId());
}
if (StrUtil.isNotBlank(dto.getCrrgBsnNm())) {
subChain.add("crrgBsnNm", dto.getCrrgBsnNm());
}
dao.update(PointsMallOrderSub.class, subChain, subCnd);
String mainOrderId = StrUtil.blankToDefault(dto.getMainOrderId(), subs.get(0).getMainOrderId());
if (StrUtil.isNotBlank(mainOrderId)) {
Chain mainChain = Chain.make("deliveryStatus", String.valueOf(deliveredStatus))
.add("deliveryTime", finalDeliveryTime);
if (StrUtil.isNotBlank(dto.getLogisticsOrderId())) {
mainChain.add("logisticsOrderId", dto.getLogisticsOrderId());
}
if (StrUtil.isNotBlank(dto.getCrrgBsnNm())) {
mainChain.add("crrgBsnNm", dto.getCrrgBsnNm());
}
dao.update(PointsMallOrderMain.class, mainChain, Cnd.where("supplierId", "=", dto.getSupplierId())
.and("orderId", "=", mainOrderId).and("delFlag", "=", false));
}
});
log.info("供应商已发货事件处理完成,supplierId={}mainOrderId={}orderIds={}deliveryStatus={}",
dto.getSupplierId(), dto.getMainOrderId(), orderIds, deliveredStatus);
return MallInboundResult.success();
}
public MallInboundResult invoiceInfo(MallOrderEventDTO dto) {
String mainOrderId = StrUtil.blankToDefault(dto.getMainOrderId(), dto.getOrderId());
if (StrUtil.isBlank(mainOrderId)) {
@@ -1,10 +1,20 @@
package com.budwk.app.zhgh.pointsmall.mallbridge.service;
import cn.hutool.core.bean.BeanUtil;
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.dayofficework.message.service.GlobalMessageSendService;
import com.budwk.app.zhgh.pointsmall.mallbridge.dto.MallPurchaseResultDTO;
import com.budwk.app.zhgh.pointsmall.mallbridge.dto.OrderProInfoDTO;
import com.budwk.app.zhgh.pointsmall.mallbridge.exception.MallBridgeError;
import com.budwk.app.zhgh.pointsmall.mallbridge.model.MallInboundResult;
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.order.models.PointsMallOrderMainHistory;
import com.budwk.app.zhgh.pointsmall.points.service.PointsMallPointsLockService;
import com.budwk.app.zhgh.pointsmall.supplier.models.PointsMallSupplier;
import lombok.extern.slf4j.Slf4j;
import org.nutz.dao.Chain;
import org.nutz.dao.Cnd;
@@ -14,10 +24,14 @@ import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.trans.Atom;
import org.nutz.trans.Trans;
import java.util.Date;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
/**
* 商城桥接购买结果通知服务。
* 9.2.14 支付结果通知接口
*/
@Slf4j
@IocBean(args = {"refer:dao"})
@@ -25,45 +39,105 @@ public class MallInboundPurchaseResultService {
private final Dao dao;
@Inject
private MallInboundConfirmPurchaseService mallInboundConfirmPurchaseService;
@Inject
private PointsMallPointsLockService pointsMallPointsLockService;
@Inject
private GlobalMessageSendService globalMessageSendService;
public MallInboundPurchaseResultService(Dao dao) {
this.dao = dao;
}
/**
* 接收购买结果。支付成功只同步现金支付状态;支付失败取消主单并释放锁定积分。
*/
public MallInboundResult purchaseResult(MallPurchaseResultDTO dto) {
log.info("积分商城购买结果通知,supplierId={}orderId={}purchaseResult={}", dto.getSupplierId(), dto.getOrderId(), dto.getPurchaseResult());
PointsMallOrderMain main = dao.fetch(PointsMallOrderMain.class, Cnd.where("supplierId", "=", dto.getSupplierId())
log.info("9.2.14 支付结果通知接口 调用开始:{}", dto);
// 查询订单是否存在
PointsMallOrderMain orderMain = dao.fetch(PointsMallOrderMain.class, Cnd.where("supplierId", "=", dto.getSupplierId())
.and("orderId", "=", dto.getOrderId()).and("delFlag", "=", false));
if (main == null) {
return MallInboundResult.fail(404, "订单不存在");
if (null == orderMain) {
return MallInboundResult.fail(MallBridgeError.ORDER_NOT_EXISTS.code(), "订单不存在");
}
if (Boolean.TRUE.equals(dto.getPurchaseResult())) {
Integer cashPaid = main.getWPayOrAPay() != null && main.getWPayOrAPay().signum() > 0 ? 2 : 0;
return mallInboundConfirmPurchaseService.updateMainOrderPay(dto.getSupplierId(), dto.getOrderId(), cashPaid,
dto.getTotalPrice(), dto.getWPayOrAPay(), dto.getPointsPrice());
// 支付结果
if (dto.getPurchaseResult()) {
log.info("9.2.14 支付结果通知接口,支付成功");
if (BigDecimal.ZERO.compareTo(orderMain.getWPayOrAPay()) != 0) {
dao.update(PointsMallOrderMain.class, Chain.make("cashPaid", 2), Cnd.where("id", "=", orderMain.getId()));
}
try {
// callP消息推送
pushMessageToCallP(orderMain);
} catch (Exception e) {
log.error("9.2.14 支付结果通知接口,callP消息推送:{},{}", dto, e.getMessage());
}
return MallInboundResult.success();
}
if (Objects.equals(orderMain.getOrderState(), MallOrderStatusEnum.CANCELLED.getCode())) {
return MallInboundResult.fail(MallBridgeError.PARAM_ERROR.code(), "订单已取消,请不要重复推送");
}
log.info("9.2.14 支付结果通知接口,支付失败,1.修改主订单支付状态为已取消 2.释放积分");
// 支付失败,修改主订单支付状态为已取消
Trans.exec((Atom) () -> {
dao.update(PointsMallOrderMain.class,
Chain.make("orderState", 3)
.add("cashPaid", main.getWPayOrAPay() != null && main.getWPayOrAPay().signum() > 0 ? 3 : main.getCashPaid())
.add("totalPrice", dto.getTotalPrice())
.add("pointsPrice", dto.getPointsPrice())
.add("wPayOrAPay", dto.getWPayOrAPay())
.add("orderUpdateTime", new Date()),
Cnd.where("id", "=", main.getId()));
dao.update(PointsMallOrderSub.class,
Chain.make("orderState", 3).add("orderUpdateTime", new Date()),
Cnd.where("supplierId", "=", dto.getSupplierId()).and("mainOrderId", "=", dto.getOrderId()).and("delFlag", "=", false));
pointsMallPointsLockService.releaseMain(main.getUserId(), main.getSupplierId(), main.getOrderId());
Chain mainOrderUpdate = Chain.make("totalPrice", dto.getTotalPrice())
.add("pointsPrice", dto.getPointsPrice())
.add("wPayOrAPay", dto.getWPayOrAPay())
.add("orderState", MallOrderStatusEnum.CANCELLED.getCode());
if (BigDecimal.ZERO.compareTo(orderMain.getWPayOrAPay()) != 0) {
// 取消现金支付
mainOrderUpdate.add("cashPaid", 3);
}
dao.update(PointsMallOrderMain.class, mainOrderUpdate, Cnd.where("id", "=", orderMain.getId()));
// 支付失败,释放积分
pointsMallPointsLockService.releaseMain(orderMain.getUserId(), orderMain.getSupplierId(), orderMain.getOrderId());
// 添加历史记录
PointsMallOrderMainHistory orderMainHistory = BeanUtil.copyProperties(orderMain, PointsMallOrderMainHistory.class);
// id 主键
orderMainHistory.setId(null);
log.info("9.2.14 支付结果通知接口,保存订单主表流水记录");
dao.insert(orderMainHistory);
});
log.info("积分商城购买失败处理完成,supplierId={}orderId={}", dto.getSupplierId(), dto.getOrderId());
log.info("9.2.14 支付结果通知接口 调用结束");
return MallInboundResult.success();
}
/**
* callP消息推送
*
* @param mainOrder 订单信息
*/
public void pushMessageToCallP(PointsMallOrderMain mainOrder) {
Sys_user user = dao.fetch(Sys_user.class, Cnd.where("id", "=", mainOrder.getUserId()).or("loginname", "=", mainOrder.getUserId()));
PointsMallSupplier supplier = dao.fetch(PointsMallSupplier.class, Cnd.where("supplierId", "=", mainOrder.getSupplierId()).and("delFlag", "=", false));
String supplierName = supplier == null || StrUtil.isBlank(supplier.getSupplierName()) ? mainOrder.getSupplierId() : supplier.getSupplierName();
StringBuilder sb = new StringBuilder();
sb.append("商品列表:<ol>");
List<OrderProInfoDTO> productList = StrUtil.isBlank(mainOrder.getExtJson())
? Collections.emptyList()
: JSONUtil.toList(mainOrder.getExtJson(), OrderProInfoDTO.class);
productList.forEach(product ->
sb.append("<li>商品名称:").append(product.getName()).append(",商品价格:").append(formatMoney(product.getPrice())).append("元</li>")
);
sb.append("</ol>");
String userName = user == null || StrUtil.isBlank(user.getUsername()) ? mainOrder.getUserId() : user.getUsername();
String content = "尊敬的" + userName + ",您的积分商城订单已支付成功。"
+ "<br>"
+ "订单时间:" + DateUtil.formatDateTime(mainOrder.getOrderCreateTime())
+ "<br>"
+ "消费积分:" + mainOrder.getPointsPrice()
+ "<br>"
+ "供应商:" + supplierName
+ "<br>"
+ "订单总金额:" + mainOrder.getTotalPrice()
+ "<br>"
+ "现金金额:" + mainOrder.getWPayOrAPay()
+ "<br>"
+ sb;
globalMessageSendService.sendLocalSystemMessage("积分商城支付成功", content, 1, Collections.singletonList(mainOrder.getUserId()), null);
}
private String formatMoney(BigDecimal value) {
return (value == null ? BigDecimal.ZERO : value).setScale(2, RoundingMode.HALF_UP).toPlainString();
}
}
@@ -0,0 +1,136 @@
package com.budwk.app.zhgh.pointsmall.order.models;
import com.budwk.app.base.model.BaseModel;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.nutz.dao.entity.annotation.ColDefine;
import org.nutz.dao.entity.annotation.ColType;
import org.nutz.dao.entity.annotation.Column;
import org.nutz.dao.entity.annotation.Comment;
import org.nutz.dao.entity.annotation.Name;
import org.nutz.dao.entity.annotation.Table;
import org.nutz.dao.interceptor.annotation.PrevInsert;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
/**
* 商城主订单历史记录 当主单数据变化时 落库到历史表
*/
@Data
@EqualsAndHashCode(callSuper = true)
@Table("points_mall_order_main_history")
@Comment("积分商城主订单历史记录")
public class PointsMallOrderMainHistory extends BaseModel implements Serializable {
@Name
@Column
@Comment("ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
@PrevInsert(uu32 = true)
private String id;
@Column
@Comment("主订单ID")
@ColDefine(type = ColType.VARCHAR, width = 64)
private String orderId;
@Column
@Comment("供应商编码")
@ColDefine(type = ColType.VARCHAR, width = 64)
private String supplierId;
@Column
@Comment("订单编号")
@ColDefine(type = ColType.VARCHAR, width = 64)
private String orderNumberId;
@Column
@Comment("用户ID")
@ColDefine(type = ColType.VARCHAR, width = 64)
private String userId;
@Column
@Comment("应用名称")
@ColDefine(type = ColType.VARCHAR, width = 100)
private String aplName;
@Column
@Comment("订单创建时间")
private Date orderCreateTime;
@Column
@Comment("订单更新时间")
private Date orderUpdateTime;
@Column
@Comment("发货时间")
private Date deliveryTime;
@Column
@Comment("确认收货时间")
private Date orderFinishTime;
@Column
@Comment("完成时间")
private Date orderCompleteTime;
@Column
@Comment("发货状态")
@ColDefine(type = ColType.VARCHAR, width = 20)
private String deliveryStatus;
@Column
@Comment("运费积分")
@ColDefine(type = ColType.FLOAT, width = 18, precision = 2)
private BigDecimal freightCost;
@Column
@Comment("退款积分")
@ColDefine(type = ColType.FLOAT, width = 18, precision = 2)
private BigDecimal refund;
@Column
@Comment("物流单号")
@ColDefine(type = ColType.VARCHAR, width = 100)
private String logisticsOrderId;
@Column
@Comment("物流承运商")
@ColDefine(type = ColType.VARCHAR, width = 100)
private String crrgBsnNm;
@Column
@Comment("订单状态")
private Integer orderState;
@Column
@Comment("订单总金额")
@ColDefine(type = ColType.FLOAT, width = 18, precision = 2)
private BigDecimal totalPrice;
@Column
@Comment("现金金额")
@ColDefine(type = ColType.FLOAT, width = 18, precision = 2)
private BigDecimal wPayOrAPay;
@Column
@Comment("消费积分")
@ColDefine(type = ColType.FLOAT, width = 18, precision = 2)
private BigDecimal pointsPrice;
@Column
@Comment("发票代码")
@ColDefine(type = ColType.VARCHAR, width = 100)
private String invoiceCode;
@Column
@Comment("商品扩展信息JSON")
@ColDefine(type = ColType.TEXT)
private String extJson;
@Column
@Comment("现金支付状态")
private Integer cashPaid;
}
@@ -11,6 +11,7 @@ import com.budwk.app.zhgh.pointsmall.supplier.models.PointsMallSupplier;
import com.budwk.app.zhgh.pointsmall.order.param.PointsMallOrderPageParam;
import com.budwk.app.zhgh.pointsmall.order.vo.PointsMallMobileOrderVO;
import org.nutz.dao.entity.Record;
import org.nutz.lang.util.NutMap;
import java.util.List;
@@ -28,9 +29,9 @@ public interface PointsMallOrderService extends BaseService<PointsMallOrderMain>
List<Record> listExchange(String mainOrderId);
List<Record> listSubProducts(String orderId);
List<NutMap> listSubProducts(String orderId);
List<Record> listExchangeProducts(String orderId);
List<NutMap> listExchangeProducts(String orderId);
boolean updateSub(PointsMallOrderSub orderSub);
@@ -6,6 +6,7 @@ import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.budwk.app.base.page.Pagination;
import com.budwk.app.base.service.impl.BaseServiceImpl;
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;
@@ -28,6 +29,7 @@ import org.nutz.dao.sql.Sql;
import org.nutz.dao.util.Daos;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.util.NutMap;
import org.nutz.trans.Atom;
import org.nutz.trans.Trans;
@@ -198,7 +200,26 @@ public class PointsMallOrderServiceImpl extends BaseServiceImpl<PointsMallOrderM
}
@Override
public List<Record> listSubProducts(String orderId) {
public List<NutMap> listSubProducts(String orderId) {
PointsMallOrderSub orderSub = dao().fetch(PointsMallOrderSub.class, Cnd.where("orderId", "=", orderId).and("delFlag", "=", false));
List<NutMap> extProducts = parseProductExtJson(orderId, orderSub == null ? null : orderSub.getExtJson());
if (!extProducts.isEmpty()) {
return extProducts;
}
return listProductTable(orderId);
}
@Override
public List<NutMap> listExchangeProducts(String orderId) {
PointsMallOrderExchange orderExchange = dao().fetch(PointsMallOrderExchange.class, Cnd.where("orderId", "=", orderId).and("delFlag", "=", false));
List<NutMap> extProducts = parseProductExtJson(orderId, orderExchange == null ? null : orderExchange.getExtJson());
if (!extProducts.isEmpty()) {
return extProducts;
}
return listProductTable(orderId);
}
private List<NutMap> listProductTable(String orderId) {
Cnd cnd = Cnd.where("delFlag", "=", false);
if (StrUtil.isNotBlank(orderId)) {
cnd.and("orderSubId", "=", orderId);
@@ -206,12 +227,43 @@ public class PointsMallOrderServiceImpl extends BaseServiceImpl<PointsMallOrderM
cnd.asc("createdAt");
Sql sql = Sqls.create("select * from points_mall_order_sub_product $condition");
sql.setCondition(cnd);
return list(sql);
return list(sql).stream().map(this::toProductRecord).collect(Collectors.toList());
}
@Override
public List<Record> listExchangeProducts(String orderId) {
return listSubProducts(orderId);
private List<NutMap> parseProductExtJson(String orderId, String extJson) {
if (StrUtil.isBlank(extJson) || "null".equalsIgnoreCase(extJson)) {
return Collections.emptyList();
}
try {
return JSONUtil.toList(extJson, OrderProInfoDTO.class).stream().map(product -> {
return NutMap.NEW()
.addv("orderId", orderId)
.addv("sku", product.getSku())
.addv("number", product.getNumber())
.addv("price", product.getPrice())
.addv("name", product.getName())
.addv("taxRate", product.getTaxRate())
.addv("picInfo", product.getPicInfo())
.addv("fileId", product.getFileId())
.addv("filePath", product.getFilePath());
}).collect(Collectors.toList());
} catch (Exception e) {
log.warn("解析订单商品扩展信息失败,orderId={}extJson={}", orderId, extJson, e);
return Collections.emptyList();
}
}
private NutMap toProductRecord(Record item) {
return NutMap.NEW()
.addv("orderId", item.getString("orderSubId"))
.addv("sku", item.getString("sku"))
.addv("number", item.get("number"))
.addv("price", item.get("price"))
.addv("name", item.getString("name"))
.addv("taxRate", item.get("taxRate"))
.addv("picInfo", item.getString("picInfo"))
.addv("fileId", item.getString("fileId"))
.addv("filePath", item.getString("filePath"));
}
@Override