记得上下班打卡 | git大法好,push需谨慎

Commit 929a7e41 authored by 姜秀龙's avatar 姜秀龙

Merge branch 'refs/heads/dev-1.6-shouqianba' into container-test

parents 80b75dbb 7c8b5759
package com.liquidnet.service.goblin.dto.manage;
import com.liquidnet.common.third.sqb.param.response.data.MallProductsQueryData;
import com.liquidnet.common.third.sqb.util.SqbAmountUtils;
import com.liquidnet.commons.lang.constant.LnsRegex;
import com.liquidnet.commons.lang.util.CollectionUtil;
import com.liquidnet.commons.lang.util.IDGenerator;
......@@ -195,8 +196,8 @@ public class GoblinStoreMgtGoodsSqbAddParam implements Serializable {
skuInfoVo.setSkuIsbn("");
skuInfoVo.setStock(999);
skuInfoVo.setSkuStock(999);
skuInfoVo.setPrice(BigDecimal.valueOf(sku.getPrice()));
skuInfoVo.setPriceMember(BigDecimal.valueOf(sku.getPrice()));
skuInfoVo.setPrice(SqbAmountUtils.fenToYuan(sku.getPrice()));
skuInfoVo.setPriceMember(SqbAmountUtils.fenToYuan(sku.getPrice()));
skuInfoVo.setBuyFactor("0");
skuInfoVo.setBuyLimit(0);
skuInfoVo.setStoreId(goodsInfoVo.getStoreId());
......
......@@ -270,7 +270,7 @@ public class SqbBiz {
/**
* @param sn 单号(前置操作后拿到)
* @param signature 密码(前置操作后拿到)
* @param applyAmount 金额
* @param applyAmount 退款金额(分),须与订单实付/收单金额口径一致
* @param type 退款类型(1商品 2金额)
* @param item
* @param refundReason 退款原因
......
......@@ -52,7 +52,7 @@ public class CouponRefundRequest {
@NoArgsConstructor
public static class RefundInfo {
/**
* 金额
* 申请退款金额(单位:分)
*/
private Long applyAmount;
......
......@@ -35,7 +35,7 @@ public class CashierQueryData {
private String seq;
/**
* 收单金额
* 收单金额(单位:分)
*/
private Long amount;
......
......@@ -73,7 +73,7 @@ public class MallProductsQueryData {
private String skuName;
/**
* 价格
* 单价(单位:分,与收钱吧开放平台商品/订单金额一致)
*/
private Long price;
}
......
package com.liquidnet.common.third.sqb.util;
import java.math.BigDecimal;
import java.math.RoundingMode;
/**
* 收钱吧金额换算:与开放平台一致,接口里 Long 型金额字段一般为人民币「分」。
*/
public final class SqbAmountUtils {
private SqbAmountUtils() {
}
/**
* 分 → 元(商城 SKU {@code price}、订单总价等均以「元」存储)
*/
public static BigDecimal fenToYuan(Long fen) {
if (fen == null) {
return BigDecimal.ZERO;
}
return BigDecimal.valueOf(fen).divide(new BigDecimal("100"), 4, RoundingMode.HALF_UP);
}
}
......@@ -69,14 +69,9 @@ public class GoblinSqbServiceImpl implements IGoblinSqbService {
return ResponseDto.failure("订单未支付,无法获取券码");
}
GoblinSqbOrderVo orderVo = goblinSqbRedisUtils.getSqbOrder(orderId);
GoblinSqbOrderVo orderVo = getSqbOrderVoOrLoadFromDb(orderId);
if (orderVo == null) {
orderVo = loadSqbOrderVoFromDb(orderId);
if (orderVo != null) {
goblinSqbRedisUtils.setSqbOrderForever(orderId, orderVo);
} else {
return ResponseDto.failure("订单不存在");
}
return ResponseDto.failure("订单不存在");
}
// 兜底:以商城订单的 userId 为准,这里仅防御脏数据
if (orderVo.getUserId() != null && !userId.equals(orderVo.getUserId())) return ResponseDto.failure("无权限访问该订单");
......@@ -119,15 +114,46 @@ public class GoblinSqbServiceImpl implements IGoblinSqbService {
public ResponseDto<Boolean> refund(String userId, String orderId, String reason) {
log.info("[收钱吧退款] 开始 userId={}, orderId={}", userId, orderId);
GoblinSqbOrderVo orderVo = goblinSqbRedisUtils.getSqbOrder(orderId);
if (orderVo == null) return ResponseDto.failure("订单不存在");
if (!userId.equals(orderVo.getUserId())) return ResponseDto.failure("无权限访问该订单");
// 与详情接口一致:先主单 store + 商品,再收钱吧扩展;避免扩展单缺失却提示「订单不存在」
GoblinStoreOrderVo storeOrderVo = goblinRedisUtils.getGoblinOrder(orderId);
if (storeOrderVo == null
|| !Integer.valueOf(GoblinStatusConst.Status.ORDER_STATUS_2.getValue()).equals(storeOrderVo.getStatus())) {
if (storeOrderVo == null) {
return ResponseDto.failure("订单不存在");
}
if (!userId.equals(storeOrderVo.getUserId())) {
return ResponseDto.failure("无权限访问该订单");
}
Integer storeSt = storeOrderVo.getStatus();
if (Integer.valueOf(GoblinStatusConst.Status.ORDER_STATUS_4.getValue()).equals(storeSt)) {
return ResponseDto.failure("订单已完成(含券已核销),不可退款");
}
if (Integer.valueOf(GoblinStatusConst.Status.ORDER_STATUS_6.getValue()).equals(storeSt)) {
return ResponseDto.failure("订单已退款,不可重复退款");
}
if (!Integer.valueOf(GoblinStatusConst.Status.ORDER_STATUS_2.getValue()).equals(storeSt)) {
return ResponseDto.failure("订单状态不可退款");
}
if (Integer.valueOf(1).equals(orderVo.getCouponUsedStatus())) return ResponseDto.failure("券码已核销,不可退款");
List<String> orderSkuVoIds = storeOrderVo.getOrderSkuVoIds();
if (CollectionUtils.isEmpty(orderSkuVoIds)) {
return ResponseDto.failure("订单数据异常");
}
GoblinOrderSkuVo firstSkuVo = goblinRedisUtils.getGoblinOrderSkuVo(orderSkuVoIds.get(0));
if (firstSkuVo == null) {
return ResponseDto.failure("订单商品数据异常");
}
if (!Integer.valueOf(33).equals(firstSkuVo.getSkuType())) {
return ResponseDto.failure("该订单非收钱吧订单");
}
GoblinSqbOrderVo orderVo = getSqbOrderVoOrLoadFromDb(orderId);
if (orderVo == null) {
return ResponseDto.failure("收钱吧扩展订单未找到,无法退款");
}
if (!userId.equals(orderVo.getUserId())) {
return ResponseDto.failure("无权限访问该订单");
}
if (Integer.valueOf(1).equals(orderVo.getCouponUsedStatus())) {
return ResponseDto.failure("券码已核销,不可退款");
}
// 更新状态为退款中
String now = LocalDateTime.now().format(DTF);
......@@ -135,14 +161,8 @@ public class GoblinSqbServiceImpl implements IGoblinSqbService {
goblinSqbRedisUtils.setSqbOrder(orderId, orderVo);
syncOrderStatus(orderId, 4);
GoblinStoreOrderVo goblinStoreOrderVo = goblinRedisUtils.getGoblinOrder(orderId);
if (null == goblinStoreOrderVo) {
log.error("[收钱吧] 现场商品退款失败, orderId: {}, userId: {}", orderId, userId);
return ResponseDto.failure("退款失败");
}
List<GoblinOrderSkuVo> orderSkuVos = new ArrayList<>();
for (String skuVoId : goblinStoreOrderVo.getOrderSkuVoIds()) {
for (String skuVoId : storeOrderVo.getOrderSkuVoIds()) {
GoblinOrderSkuVo goblinOrderSkuVo = goblinRedisUtils.getGoblinOrderSkuVo(skuVoId);
if (null != goblinOrderSkuVo) {
orderSkuVos.add(goblinOrderSkuVo);
......@@ -215,8 +235,10 @@ public class GoblinSqbServiceImpl implements IGoblinSqbService {
public ResponseDto<Boolean> syncCouponStatus(String userId, String orderId) {
log.info("[收钱吧核销同步] 开始 userId={}, orderId={}", userId, orderId);
GoblinSqbOrderVo orderVo = goblinSqbRedisUtils.getSqbOrder(orderId);
if (orderVo == null) return ResponseDto.failure("订单不存在");
GoblinSqbOrderVo orderVo = getSqbOrderVoOrLoadFromDb(orderId);
if (orderVo == null) {
return ResponseDto.failure("收钱吧扩展订单未找到");
}
if (!userId.equals(orderVo.getUserId())) return ResponseDto.failure("无权限访问该订单");
boolean couponUsed = sqbBiz.syncCouponStatus(sqbBiz.getSqbConfig().getMerchantId(),
......@@ -296,13 +318,7 @@ public class GoblinSqbServiceImpl implements IGoblinSqbService {
// 过滤:只处理 skuType=33 的收钱吧订单
if (!Integer.valueOf(33).equals(skuVo.getSkuType())) continue;
GoblinSqbOrderVo sqbOrderVo = goblinSqbRedisUtils.getSqbOrder(orderId);
if (sqbOrderVo == null) {
sqbOrderVo = loadSqbOrderVoFromDb(orderId);
if (sqbOrderVo != null) {
goblinSqbRedisUtils.setSqbOrderForever(orderId, sqbOrderVo);
}
}
GoblinSqbOrderVo sqbOrderVo = getSqbOrderVoOrLoadFromDb(orderId);
result.add(buildDetailVo(storeOrderVo, skuVo, sqbOrderVo));
}
......@@ -337,13 +353,7 @@ public class GoblinSqbServiceImpl implements IGoblinSqbService {
return ResponseDto.failure("该订单非收钱吧订单");
}
GoblinSqbOrderVo sqbOrderVo = goblinSqbRedisUtils.getSqbOrder(orderId);
if (sqbOrderVo == null) {
sqbOrderVo = loadSqbOrderVoFromDb(orderId);
if (sqbOrderVo != null) {
goblinSqbRedisUtils.setSqbOrderForever(orderId, sqbOrderVo);
}
}
GoblinSqbOrderVo sqbOrderVo = getSqbOrderVoOrLoadFromDb(orderId);
GoblinSqbOrderDetailVo detailVo = buildDetailVo(storeOrderVo, skuVo, sqbOrderVo);
log.info("[收钱吧订单详情] 查询成功,orderId={}", orderId);
......@@ -386,6 +396,20 @@ public class GoblinSqbServiceImpl implements IGoblinSqbService {
return detailVo;
}
/**
* 与列表/详情/查券码一致:Redis 无扩展单时从库加载并回写,避免仅因缓存未命中误判「订单不存在」。
*/
private GoblinSqbOrderVo getSqbOrderVoOrLoadFromDb(String orderId) {
GoblinSqbOrderVo orderVo = goblinSqbRedisUtils.getSqbOrder(orderId);
if (orderVo == null) {
orderVo = loadSqbOrderVoFromDb(orderId);
if (orderVo != null) {
goblinSqbRedisUtils.setSqbOrderForever(orderId, orderVo);
}
}
return orderVo;
}
private GoblinSqbOrderVo loadSqbOrderVoFromDb(String orderId) {
if (orderId == null || orderId.trim().isEmpty()) {
return null;
......
......@@ -5,6 +5,7 @@ import com.liquidnet.common.third.sqb.biz.SqbBiz;
import com.liquidnet.common.third.sqb.param.request.CommonRequest;
import com.liquidnet.common.third.sqb.param.request.MallListQueryRequest;
import com.liquidnet.common.third.sqb.param.request.MallProductsQueryRequest;
import com.liquidnet.common.third.sqb.util.SqbAmountUtils;
import com.liquidnet.common.third.sqb.param.response.data.MallListQueryData;
import com.liquidnet.common.third.sqb.param.response.data.MallProductsQueryData;
import com.liquidnet.commons.lang.util.CollectionUtil;
......@@ -414,8 +415,8 @@ public class GoblinStoreMgtSqbGoodsServiceImpl implements IGoblinStoreMgtSqbGood
}
skuInfoVo.setName(sqbSku.getSkuName());
if (sqbSku.getPrice() != null) {
skuInfoVo.setPrice(BigDecimal.valueOf(sqbSku.getPrice()));
skuInfoVo.setPriceMember(BigDecimal.valueOf(sqbSku.getPrice()));
skuInfoVo.setPrice(SqbAmountUtils.fenToYuan(sqbSku.getPrice()));
skuInfoVo.setPriceMember(SqbAmountUtils.fenToYuan(sqbSku.getPrice()));
}
skuInfoVo.setUpdatedBy(uid);
skuInfoVo.setUpdatedAt(nowTime);
......
......@@ -6,14 +6,15 @@ import java.math.RoundingMode;
/**
* 收钱吧参数转换工具类
* 1. 金额转换:元(BigDecimal) -> 分(Long)
* <p>商城侧 SKU 单价、订单总价等使用「元」;调用收钱吧结算/退款等接口时需转为「分」。</p>
* <p>收钱吧 queryMallProducts 等接口返回的 sku.price(Long)为「分」,落库/写 Redis 为「元」时请用 {@code com.liquidnet.common.third.sqb.util.SqbAmountUtils.fenToYuan}。</p>
*/
public class GoblinSqbConvertUtils {
/**
* 元转分 (BigDecimal -> Long)
* 元转分 (BigDecimal -> Long),用于结算条目、扩展单 {@code amount} 等与收钱吧对齐
*
* @param amount 元
* @return 分
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment