APP订单列表显示未支付取消的订单 库存管理一些问题修改
This commit is contained in:
@@ -161,6 +161,9 @@ public class InventoryManagementController {
|
|||||||
titleRow.createCell(5).setCellValue("订单编号");
|
titleRow.createCell(5).setCellValue("订单编号");
|
||||||
titleRow.createCell(6).setCellValue("出库时间");
|
titleRow.createCell(6).setCellValue("出库时间");
|
||||||
titleRow.createCell(7).setCellValue("come");
|
titleRow.createCell(7).setCellValue("come");
|
||||||
|
titleRow.createCell(8).setCellValue("套书名称");
|
||||||
|
titleRow.createCell(9).setCellValue("套书商品ID");
|
||||||
|
titleRow.createCell(10).setCellValue("出库记录ID");
|
||||||
int rowIndex = 1;
|
int rowIndex = 1;
|
||||||
for (Map<String, Object> map : maps) {
|
for (Map<String, Object> map : maps) {
|
||||||
Row row = sheet.createRow(rowIndex++);
|
Row row = sheet.createRow(rowIndex++);
|
||||||
@@ -172,6 +175,9 @@ public class InventoryManagementController {
|
|||||||
row.createCell(5).setCellValue(cellStr(map.get("orderSn")));
|
row.createCell(5).setCellValue(cellStr(map.get("orderSn")));
|
||||||
row.createCell(6).setCellValue(cellStr(map.get("createTime")));
|
row.createCell(6).setCellValue(cellStr(map.get("createTime")));
|
||||||
row.createCell(7).setCellValue(cellStr(map.get("come")));
|
row.createCell(7).setCellValue(cellStr(map.get("come")));
|
||||||
|
row.createCell(8).setCellValue(cellStr(map.get("setProductName")));
|
||||||
|
row.createCell(9).setCellValue(cellStr(map.get("setProductId")));
|
||||||
|
row.createCell(10).setCellValue(cellStr(map.get("stockRecordId")));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -44,7 +44,6 @@ import java.util.HashSet;
|
|||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@@ -231,8 +230,10 @@ public class InventoryManagementServiceImpl extends ServiceImpl<InvStockRecordDa
|
|||||||
String outboundType = resolveOutboundType(dto.getOutboundType());
|
String outboundType = resolveOutboundType(dto.getOutboundType());
|
||||||
List<CostSplit> splits = deductPurchaseStockFifo(dto.getProductId(), dto.getMerchantId(), dto.getQuantity());
|
List<CostSplit> splits = deductPurchaseStockFifo(dto.getProductId(), dto.getMerchantId(), dto.getQuantity());
|
||||||
for (CostSplit split : splits) {
|
for (CostSplit split : splits) {
|
||||||
|
BigDecimal saleUnitCost = (dto.getUnitCost() != null && dto.getUnitCost().compareTo(BigDecimal.ZERO) > 0)
|
||||||
|
? dto.getUnitCost() : split.unitCost;
|
||||||
insertSaleRecord(dto.getProductId(), dto.getMerchantId(), outboundType,
|
insertSaleRecord(dto.getProductId(), dto.getMerchantId(), outboundType,
|
||||||
-split.quantity, split.unitCost, dto.getRemark(), null, null, null, split.purchaseRecordId);
|
-split.quantity, saleUnitCost, dto.getRemark(), null, null, null, split.purchaseRecordId);
|
||||||
}
|
}
|
||||||
adjustShopProductStock(dto.getProductId(), -dto.getQuantity());
|
adjustShopProductStock(dto.getProductId(), -dto.getQuantity());
|
||||||
return;
|
return;
|
||||||
@@ -244,12 +245,13 @@ public class InventoryManagementServiceImpl extends ServiceImpl<InvStockRecordDa
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 采购:跨商户调拨 = 来源方按成本批次多条出库 + 本商户一条采购(成本取接口传值)
|
// 采购:跨商户调拨 = 来源方按成本批次多条出库 + 本商户一条采购(成本取接口传值)
|
||||||
|
// 灵枢→众秒:灵枢出库 outbound_type=zm;众秒→灵枢:众秒出库 outbound_type=ls
|
||||||
if (isCrossMerchantTransfer(dto.getMerchantId(), dto.getSource())) {
|
if (isCrossMerchantTransfer(dto.getMerchantId(), dto.getSource())) {
|
||||||
int sourceMerchantId = sourceToMerchantId(dto.getSource());
|
int sourceMerchantId = sourceToMerchantId(dto.getSource());
|
||||||
String saleTargetSource = merchantIdToSource(dto.getMerchantId());
|
String saleTargetSource = merchantIdToSource(dto.getMerchantId());
|
||||||
List<CostSplit> splits = deductPurchaseStockFifo(dto.getProductId(), sourceMerchantId, dto.getQuantity());
|
List<CostSplit> splits = deductPurchaseStockFifo(dto.getProductId(), sourceMerchantId, dto.getQuantity());
|
||||||
for (CostSplit split : splits) {
|
for (CostSplit split : splits) {
|
||||||
insertRecord(dto.getProductId(), sourceMerchantId, saleTargetSource, null,
|
insertRecord(dto.getProductId(), sourceMerchantId, saleTargetSource, saleTargetSource,
|
||||||
InvStockRecord.BIZ_TYPE_SALE, -split.quantity, split.unitCost, dto.getRemark(),
|
InvStockRecord.BIZ_TYPE_SALE, -split.quantity, split.unitCost, dto.getRemark(),
|
||||||
null, null, null, split.purchaseRecordId, null);
|
null, null, null, split.purchaseRecordId, null);
|
||||||
}
|
}
|
||||||
@@ -1166,7 +1168,6 @@ public class InventoryManagementServiceImpl extends ServiceImpl<InvStockRecordDa
|
|||||||
return new ArrayList<>();
|
return new ArrayList<>();
|
||||||
}
|
}
|
||||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||||
Map<Long, Integer> setPurchaseQtyCache = new HashMap<>();
|
|
||||||
Map<Long, List<InvStockRecord>> bindCache = new HashMap<>();
|
Map<Long, List<InvStockRecord>> bindCache = new HashMap<>();
|
||||||
List<Map<String, Object>> result = new ArrayList<>();
|
List<Map<String, Object>> result = new ArrayList<>();
|
||||||
for (Map<String, Object> item : list) {
|
for (Map<String, Object> item : list) {
|
||||||
@@ -1175,10 +1176,11 @@ public class InventoryManagementServiceImpl extends ServiceImpl<InvStockRecordDa
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (recordBizType == InvStockRecord.BIZ_TYPE_SALE) {
|
if (recordBizType == InvStockRecord.BIZ_TYPE_SALE) {
|
||||||
|
// 套书绑定内部出库不进入售出明细导出
|
||||||
if (isSetBookBindOutbound(item.get("outboundType"))) {
|
if (isSetBookBindOutbound(item.get("outboundType"))) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
result.addAll(expandSaleRecordForExport(item, sdf, setPurchaseQtyCache, bindCache));
|
result.addAll(expandSaleRecordForExport(item, sdf, bindCache));
|
||||||
} else if (recordBizType == InvStockRecord.BIZ_TYPE_PURCHASE) {
|
} else if (recordBizType == InvStockRecord.BIZ_TYPE_PURCHASE) {
|
||||||
result.add(buildPurchaseExportRow(item, sdf));
|
result.add(buildPurchaseExportRow(item, sdf));
|
||||||
}
|
}
|
||||||
@@ -1209,50 +1211,93 @@ public class InventoryManagementServiceImpl extends ServiceImpl<InvStockRecordDa
|
|||||||
row.put("orderSn", item.get("orderSn") == null ? "" : item.get("orderSn"));
|
row.put("orderSn", item.get("orderSn") == null ? "" : item.get("orderSn"));
|
||||||
row.put("createTime", formatExportTime(item.get("createTime"), sdf));
|
row.put("createTime", formatExportTime(item.get("createTime"), sdf));
|
||||||
row.put("come", item.get("come"));
|
row.put("come", item.get("come"));
|
||||||
|
row.put("setProductId", "");
|
||||||
|
row.put("setProductName", "");
|
||||||
|
row.put("stockRecordId", item.get("id"));
|
||||||
return row;
|
return row;
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<Map<String, Object>> expandSaleRecordForExport(Map<String, Object> item, SimpleDateFormat sdf,
|
private List<Map<String, Object>> expandSaleRecordForExport(Map<String, Object> item, SimpleDateFormat sdf,
|
||||||
Map<Long, Integer> setPurchaseQtyCache,
|
|
||||||
Map<Long, List<InvStockRecord>> bindCache) {
|
Map<Long, List<InvStockRecord>> bindCache) {
|
||||||
Integer productId = toIntegerSafe(item.get("productId"));
|
Integer productId = toIntegerSafe(item.get("productId"));
|
||||||
Long purchaseRecordId = toLongSafe(item.get("purchaseRecordId"));
|
if (productId == null || !isSetBookProductByProductId(productId)) {
|
||||||
if (productId != null && purchaseRecordId != null && isSetBookProductByProductId(productId)) {
|
return Collections.singletonList(buildSaleExportRow(item, sdf));
|
||||||
List<InvStockRecord> binds = bindCache.computeIfAbsent(purchaseRecordId, this::listSetBookComponentOutbounds);
|
|
||||||
if (!binds.isEmpty()) {
|
|
||||||
int saleQty = Math.abs(toIntValue(item.get("quantity")));
|
|
||||||
int setPurchaseQty = setPurchaseQtyCache.computeIfAbsent(purchaseRecordId, this::resolveSetPurchaseQuantity);
|
|
||||||
return buildSetBookExpandedSaleRows(item, binds, saleQty, setPurchaseQty, sdf);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return Collections.singletonList(buildSaleExportRow(item, sdf));
|
List<ShopProduct> components = listSetBookComponentProducts(productId);
|
||||||
|
if (components.isEmpty()) {
|
||||||
|
return Collections.singletonList(buildSaleExportRow(item, sdf));
|
||||||
|
}
|
||||||
|
int saleQty = Math.abs(toIntValue(item.get("quantity")));
|
||||||
|
Integer merchantId = toIntegerSafe(item.get("merchantId"));
|
||||||
|
// 套书售出流水的 purchase_record_id = 套书采购流水 id,对应单品出库的 set_purchase_record_id
|
||||||
|
Long setPurchaseRecordId = toLongSafe(item.get("purchaseRecordId"));
|
||||||
|
Map<Integer, BigDecimal> costByProductId = Collections.emptyMap();
|
||||||
|
if (setPurchaseRecordId != null) {
|
||||||
|
List<InvStockRecord> binds = bindCache.computeIfAbsent(setPurchaseRecordId, this::listSetBookComponentOutbounds);
|
||||||
|
costByProductId = resolveComponentCostFromBinds(binds);
|
||||||
|
}
|
||||||
|
String setProductName = item.get("productName") == null ? "" : item.get("productName").toString();
|
||||||
|
return buildSetBookExpandedSaleRows(item, components, saleQty, merchantId, costByProductId,
|
||||||
|
productId, setProductName, sdf);
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<Map<String, Object>> buildSetBookExpandedSaleRows(Map<String, Object> parent,
|
/** 套书关联图书 → 只取「只绑了 1 本书」的单品商品 */
|
||||||
List<InvStockRecord> binds,
|
private List<ShopProduct> listSetBookComponentProducts(Integer setProductId) {
|
||||||
int saleQty, int setPurchaseQty,
|
List<Integer> bookIds = listBookIdsByProductId(setProductId);
|
||||||
SimpleDateFormat sdf) {
|
if (bookIds.isEmpty()) {
|
||||||
Map<Integer, String> productNames = loadProductNameMap(
|
return Collections.emptyList();
|
||||||
binds.stream().map(InvStockRecord::getProductId).filter(Objects::nonNull).collect(Collectors.toSet()));
|
}
|
||||||
List<Map<String, Object>> rows = new ArrayList<>();
|
List<ShopProduct> components = new ArrayList<>();
|
||||||
for (InvStockRecord bind : binds) {
|
Set<Integer> seen = new HashSet<>();
|
||||||
int bindQty = bind.getQuantity() == null ? 0 : Math.abs(bind.getQuantity());
|
for (Integer bookId : bookIds) {
|
||||||
int exportQty = setPurchaseQty > 0
|
ShopProduct component = findComponentProductByBookId(bookId, setProductId);
|
||||||
? (int) Math.round(bindQty * (double) saleQty / setPurchaseQty)
|
if (component == null || component.getProductId() == null) {
|
||||||
: saleQty;
|
|
||||||
if (exportQty <= 0) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
// findComponentProductByBookId 已优先只绑 1 本书;再兜底确认
|
||||||
|
if (listBookIdsByProductId(component.getProductId()).size() != 1) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (seen.add(component.getProductId())) {
|
||||||
|
components.add(component);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return components;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 套书售出导出:按套内单品展开,数量=套书出库数量;
|
||||||
|
* 成本优先:单品 books 出库.purchase_record_id → 入库记录.unit_cost;
|
||||||
|
* 无 set_purchase_record_id / 无绑定时:inv_product_cost.cost_price。
|
||||||
|
*/
|
||||||
|
private List<Map<String, Object>> buildSetBookExpandedSaleRows(Map<String, Object> parent,
|
||||||
|
List<ShopProduct> components,
|
||||||
|
int saleQty,
|
||||||
|
Integer merchantId,
|
||||||
|
Map<Integer, BigDecimal> costByProductId,
|
||||||
|
Integer setProductId,
|
||||||
|
String setProductName,
|
||||||
|
SimpleDateFormat sdf) {
|
||||||
|
List<Map<String, Object>> rows = new ArrayList<>();
|
||||||
|
for (ShopProduct component : components) {
|
||||||
|
Integer componentId = component.getProductId();
|
||||||
|
BigDecimal unitCost = costByProductId == null ? null : costByProductId.get(componentId);
|
||||||
|
if (unitCost == null) {
|
||||||
|
unitCost = lookupInvProductCostPrice(componentId, merchantId);
|
||||||
|
}
|
||||||
Map<String, Object> row = new LinkedHashMap<>();
|
Map<String, Object> row = new LinkedHashMap<>();
|
||||||
row.put("exportCategory", "sale");
|
row.put("exportCategory", "sale");
|
||||||
row.put("productId", bind.getProductId());
|
row.put("productId", componentId);
|
||||||
row.put("productName", productNames.getOrDefault(bind.getProductId(), ""));
|
row.put("productName", component.getProductName() == null ? "" : component.getProductName());
|
||||||
row.put("outboundTypeLabel", parent.get("outboundTypeLabel"));
|
row.put("outboundTypeLabel", parent.get("outboundTypeLabel"));
|
||||||
row.put("unitCost", bind.getUnitCost());
|
row.put("unitCost", unitCost);
|
||||||
row.put("quantity", exportQty);
|
row.put("quantity", saleQty);
|
||||||
row.put("orderSn", parent.get("orderSn") == null ? "" : parent.get("orderSn"));
|
row.put("orderSn", parent.get("orderSn") == null ? "" : parent.get("orderSn"));
|
||||||
row.put("createTime", formatExportTime(parent.get("createTime"), sdf));
|
row.put("createTime", formatExportTime(parent.get("createTime"), sdf));
|
||||||
row.put("come", parent.get("come"));
|
row.put("come", parent.get("come"));
|
||||||
|
row.put("setProductId", setProductId);
|
||||||
|
row.put("setProductName", setProductName == null ? "" : setProductName);
|
||||||
|
row.put("stockRecordId", parent.get("id"));
|
||||||
rows.add(row);
|
rows.add(row);
|
||||||
}
|
}
|
||||||
if (rows.isEmpty()) {
|
if (rows.isEmpty()) {
|
||||||
@@ -1261,15 +1306,76 @@ public class InventoryManagementServiceImpl extends ServiceImpl<InvStockRecordDa
|
|||||||
return rows;
|
return rows;
|
||||||
}
|
}
|
||||||
|
|
||||||
private int resolveSetPurchaseQuantity(Long setPurchaseRecordId) {
|
/**
|
||||||
if (setPurchaseRecordId == null) {
|
* 根据套书绑定的单品出库流水:purchase_record_id → 入库记录取 unit_cost;
|
||||||
return 0;
|
* 同一单品多条 FIFO 按数量加权平均。
|
||||||
|
*/
|
||||||
|
private Map<Integer, BigDecimal> resolveComponentCostFromBinds(List<InvStockRecord> binds) {
|
||||||
|
if (binds == null || binds.isEmpty()) {
|
||||||
|
return Collections.emptyMap();
|
||||||
}
|
}
|
||||||
InvStockRecord purchase = invStockRecordDao.selectById(setPurchaseRecordId);
|
Map<Integer, BigDecimal> costSum = new HashMap<>();
|
||||||
if (purchase == null || purchase.getQuantity() == null) {
|
Map<Integer, Integer> qtySum = new HashMap<>();
|
||||||
return 0;
|
Map<Long, BigDecimal> purchaseCostCache = new HashMap<>();
|
||||||
|
for (InvStockRecord bind : binds) {
|
||||||
|
Integer componentId = bind.getProductId();
|
||||||
|
if (componentId == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
int qty = bind.getQuantity() == null ? 0 : Math.abs(bind.getQuantity());
|
||||||
|
if (qty <= 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
BigDecimal unitCost = resolveInboundUnitCost(bind.getPurchaseRecordId(), purchaseCostCache);
|
||||||
|
if (unitCost == null) {
|
||||||
|
unitCost = bind.getUnitCost();
|
||||||
|
}
|
||||||
|
if (unitCost == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
costSum.merge(componentId, unitCost.multiply(BigDecimal.valueOf(qty)), BigDecimal::add);
|
||||||
|
qtySum.merge(componentId, qty, Integer::sum);
|
||||||
}
|
}
|
||||||
return Math.abs(purchase.getQuantity());
|
Map<Integer, BigDecimal> result = new HashMap<>();
|
||||||
|
for (Map.Entry<Integer, BigDecimal> entry : costSum.entrySet()) {
|
||||||
|
int qty = qtySum.getOrDefault(entry.getKey(), 0);
|
||||||
|
if (qty <= 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
result.put(entry.getKey(),
|
||||||
|
entry.getValue().divide(BigDecimal.valueOf(qty), 2, java.math.RoundingMode.HALF_UP));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private BigDecimal resolveInboundUnitCost(Long purchaseRecordId, Map<Long, BigDecimal> cache) {
|
||||||
|
if (purchaseRecordId == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (cache.containsKey(purchaseRecordId)) {
|
||||||
|
return cache.get(purchaseRecordId);
|
||||||
|
}
|
||||||
|
InvStockRecord purchase = invStockRecordDao.selectById(purchaseRecordId);
|
||||||
|
BigDecimal unitCost = null;
|
||||||
|
if (purchase != null && purchase.getBizType() != null
|
||||||
|
&& purchase.getBizType() == InvStockRecord.BIZ_TYPE_PURCHASE) {
|
||||||
|
unitCost = purchase.getUnitCost();
|
||||||
|
}
|
||||||
|
cache.put(purchaseRecordId, unitCost);
|
||||||
|
return unitCost;
|
||||||
|
}
|
||||||
|
|
||||||
|
private BigDecimal lookupInvProductCostPrice(Integer productId, Integer merchantId) {
|
||||||
|
if (productId == null || merchantId == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
InvProductCost cost = invProductCostDao.selectOne(
|
||||||
|
new LambdaQueryWrapper<InvProductCost>()
|
||||||
|
.eq(InvProductCost::getProductId, productId)
|
||||||
|
.eq(InvProductCost::getMerchantId, merchantId)
|
||||||
|
.last("LIMIT 1")
|
||||||
|
);
|
||||||
|
return cost == null ? null : cost.getCostPrice();
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<InvStockRecord> listSetBookComponentOutbounds(Long setPurchaseRecordId) {
|
private List<InvStockRecord> listSetBookComponentOutbounds(Long setPurchaseRecordId) {
|
||||||
@@ -1290,26 +1396,6 @@ public class InventoryManagementServiceImpl extends ServiceImpl<InvStockRecordDa
|
|||||||
return listBookIdsByProductId(productId).size() > 1;
|
return listBookIdsByProductId(productId).size() > 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Map<Integer, String> loadProductNameMap(Set<Integer> productIds) {
|
|
||||||
if (productIds == null || productIds.isEmpty()) {
|
|
||||||
return Collections.emptyMap();
|
|
||||||
}
|
|
||||||
List<ShopProduct> products = shopProductDao.selectList(
|
|
||||||
new LambdaQueryWrapper<ShopProduct>()
|
|
||||||
.select(ShopProduct::getProductId, ShopProduct::getProductName)
|
|
||||||
.in(ShopProduct::getProductId, productIds)
|
|
||||||
);
|
|
||||||
Map<Integer, String> map = new HashMap<>();
|
|
||||||
if (products != null) {
|
|
||||||
for (ShopProduct product : products) {
|
|
||||||
if (product.getProductId() != null) {
|
|
||||||
map.put(product.getProductId(), product.getProductName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
|
|
||||||
private String formatExportTime(Object createTime, SimpleDateFormat sdf) {
|
private String formatExportTime(Object createTime, SimpleDateFormat sdf) {
|
||||||
if (createTime instanceof Date) {
|
if (createTime instanceof Date) {
|
||||||
return sdf.format((Date) createTime);
|
return sdf.format((Date) createTime);
|
||||||
|
|||||||
@@ -61,11 +61,11 @@ public class OrderCancelConsumer {
|
|||||||
if (!Constants.ORDER_STATUS_TO_BE_PAID.equals(buyOrder.getOrderStatus())) {
|
if (!Constants.ORDER_STATUS_TO_BE_PAID.equals(buyOrder.getOrderStatus())) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// TODO 上线全量后删除此测试账号限制
|
/* // TODO 上线全量后删除此测试账号限制
|
||||||
if (!isTesterOrder(buyOrder)) {
|
if (!isTesterOrder(buyOrder)) {
|
||||||
log.info("订单超时取消跳过:非测试账号, orderId={}, userId={}", buyOrder.getOrderId(), buyOrder.getUserId());
|
log.info("订单超时取消跳过:非测试账号, orderId={}, userId={}", buyOrder.getOrderId(), buyOrder.getUserId());
|
||||||
return;
|
return;
|
||||||
}
|
}*/
|
||||||
buyOrder.setOrderStatus(Constants.ORDER_STATUS_OUT_OF_TIME);
|
buyOrder.setOrderStatus(Constants.ORDER_STATUS_OUT_OF_TIME);
|
||||||
|
|
||||||
// 回滚优惠券(buy_order.coupon_id 存的是 coupon_history.id),保留订单 couponId 便于查单
|
// 回滚优惠券(buy_order.coupon_id 存的是 coupon_history.id),保留订单 couponId 便于查单
|
||||||
|
|||||||
Reference in New Issue
Block a user