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

Commit e106aec9 authored by 姜秀龙's avatar 姜秀龙

sqb 功能完善。小需求改动

parent 61c9e8cb
...@@ -23,7 +23,7 @@ public class GoblinSqbOrderParam { ...@@ -23,7 +23,7 @@ public class GoblinSqbOrderParam {
@NotNull(message = "购买数量不能为空") @NotNull(message = "购买数量不能为空")
private Integer quantity; private Integer quantity;
@ApiModelProperty(required = true, value = "关联演出ID") @ApiModelProperty(required = true, value = "关联演出ID(须与后台演出-商品关联一致;有换购价时按换购价计价)")
@NotBlank(message = "关联演出ID不能为空") @NotBlank(message = "关联演出ID不能为空")
private String performancesId; private String performancesId;
......
...@@ -48,9 +48,6 @@ public class GoblinGoodsSkuInfoDetailVo implements Serializable, Cloneable { ...@@ -48,9 +48,6 @@ public class GoblinGoodsSkuInfoDetailVo implements Serializable, Cloneable {
@ApiModelProperty(position = 51, value = "是否实名[0-否|1-是,表示该商品需要实名关联]") @ApiModelProperty(position = 51, value = "是否实名[0-否|1-是,表示该商品需要实名关联]")
private Integer isTrueName; private Integer isTrueName;
@ApiModelProperty(position = 52, value = "关联演出ID")
private String performancesId;
private static final GoblinGoodsSkuInfoDetailVo obj = new GoblinGoodsSkuInfoDetailVo(); private static final GoblinGoodsSkuInfoDetailVo obj = new GoblinGoodsSkuInfoDetailVo();
public static GoblinGoodsSkuInfoDetailVo getNew() { public static GoblinGoodsSkuInfoDetailVo getNew() {
......
...@@ -8,7 +8,7 @@ import java.util.List; ...@@ -8,7 +8,7 @@ import java.util.List;
public class GoblinSqbPerfListRespVo implements Serializable { public class GoblinSqbPerfListRespVo implements Serializable {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
/** 演出结束自动下架 0-否 1-是(全局配置) */ /** 演出结束后不在前台列表展示 0-否 1-是(全局配置,仅列表隐藏) */
private Integer autoOffline; private Integer autoOffline;
/** 关联商品列表 */ /** 关联商品列表 */
......
...@@ -6,6 +6,7 @@ import lombok.Data; ...@@ -6,6 +6,7 @@ import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.List;
/** /**
* 收钱吧-演出关联商品前端展示VO * 收钱吧-演出关联商品前端展示VO
...@@ -20,4 +21,7 @@ public class GoblinSqbPerformanceGoodsInfoVo extends GoblinGoodsInfoVo { ...@@ -20,4 +21,7 @@ public class GoblinSqbPerformanceGoodsInfoVo extends GoblinGoodsInfoVo {
@ApiModelProperty(value = "换购价(不设置则按正常价)") @ApiModelProperty(value = "换购价(不设置则按正常价)")
private BigDecimal settlementPrice; private BigDecimal settlementPrice;
@ApiModelProperty(value = "已上架 SKU 明细(含 restStock、stockLess、canBuy 等,与商品详情接口字段一致)")
private List<GoblinGoodsSkuInfoDetailVo> goblinGoodsSkuInfoVolist;
} }
...@@ -65,7 +65,7 @@ public class SqbPerformanceGoodsController extends BaseController { ...@@ -65,7 +65,7 @@ public class SqbPerformanceGoodsController extends BaseController {
@ApiOperation("批量绑定演出与商品(含换购价、演出级自动下架全局配置)") @ApiOperation("批量绑定演出与商品(含换购价、演出级自动下架全局配置)")
@ApiImplicitParams({ @ApiImplicitParams({
@ApiImplicitParam(type = "query", required = true, dataType = "String", name = "performancesId", value = "演出ID"), @ApiImplicitParam(type = "query", required = true, dataType = "String", name = "performancesId", value = "演出ID"),
@ApiImplicitParam(type = "query", required = false, dataType = "int", name = "autoOffline", value = "自动下架开关 0-否 1-是"), @ApiImplicitParam(type = "query", required = false, dataType = "int", name = "autoOffline", value = "演出结束后不在前台列表展示 0-否 1-是(不取消关联、不改商品上下架)"),
}) })
public AjaxResult bind(@RequestParam("performancesId") String performancesId, public AjaxResult bind(@RequestParam("performancesId") String performancesId,
@RequestParam(value = "autoOffline", required = false, defaultValue = "0") Integer autoOffline, @RequestParam(value = "autoOffline", required = false, defaultValue = "0") Integer autoOffline,
......
...@@ -39,8 +39,9 @@ ...@@ -39,8 +39,9 @@
<div class="auto-offline-bar"> <div class="auto-offline-bar">
<label> <label>
<input type="checkbox" id="globalAutoOffline" onchange="toggleGlobalAutoOffline(this)"/> <input type="checkbox" id="globalAutoOffline" onchange="toggleGlobalAutoOffline(this)"/>
演出结束商品自动下架 演出结束后不在前台推荐列表展示
</label> </label>
<span class="tip">开启后仅隐藏 APP/小程序演出关联商品列表,不取消关联、不修改商品上下架</span>
</div> </div>
<div class="table-responsive"> <div class="table-responsive">
<table class="table table-bordered" id="linkedGoodsTable"> <table class="table table-bordered" id="linkedGoodsTable">
......
...@@ -18,7 +18,7 @@ public interface ISqbPerformanceGoodsService { ...@@ -18,7 +18,7 @@ public interface ISqbPerformanceGoodsService {
* *
* @param performancesId 演出ID * @param performancesId 演出ID
* @param items 绑定项列表(仅含 SKU ID、排序、换购价) * @param items 绑定项列表(仅含 SKU ID、排序、换购价)
* @param autoOffline 演出结束自动下架 0-否 1-是(全局配置 * @param autoOffline 演出结束后不在前台列表展示 0-否 1-是(全局配置,仅列表隐藏
* @return 操作结果 * @return 操作结果
*/ */
ResponseDto<Boolean> bind(String performancesId, List<SqbPerfGoodsBindItemParam> items, Integer autoOffline); ResponseDto<Boolean> bind(String performancesId, List<SqbPerfGoodsBindItemParam> items, Integer autoOffline);
......
...@@ -30,7 +30,7 @@ public class GoblinSqbPerformanceConfig implements Serializable { ...@@ -30,7 +30,7 @@ public class GoblinSqbPerformanceConfig implements Serializable {
private String performancesId; private String performancesId;
/** /**
* 演出结束自动下架 0-否 1-是 * 演出结束后不在前台关联商品列表展示 0-否 1-是(仅列表隐藏,不取消关联、不修改商品上下架)
*/ */
private Integer autoOffline; private Integer autoOffline;
......
...@@ -82,6 +82,12 @@ ...@@ -82,6 +82,12 @@
<version>1.0-SNAPSHOT</version> <version>1.0-SNAPSHOT</version>
<scope>compile</scope> <scope>compile</scope>
</dependency> </dependency>
<dependency>
<groupId>com.liquidnet</groupId>
<artifactId>liquidnet-service-kylin-api</artifactId>
<version>1.0-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
<dependency> <dependency>
......
...@@ -102,7 +102,7 @@ public class GoblinSqbController { ...@@ -102,7 +102,7 @@ public class GoblinSqbController {
} }
@GetMapping("/performance/selectGoods") @GetMapping("/performance/selectGoods")
@ApiOperation("按演出ID获得已关联商品列表(pageNumber从0开始)") @ApiOperation("按演出ID获得已关联商品列表(pageNumber从0开始);若后台开启「演出结束后不在前台列表展示」且演出已结束则返回空列表")
@ApiImplicitParams({ @ApiImplicitParams({
@ApiImplicitParam(paramType = "query", required = true, dataType = "String", name = "performancesId", value = "演出ID"), @ApiImplicitParam(paramType = "query", required = true, dataType = "String", name = "performancesId", value = "演出ID"),
@ApiImplicitParam(paramType = "query", required = true, dataType = "int", name = "pageSize", value = "分页大小"), @ApiImplicitParam(paramType = "query", required = true, dataType = "int", name = "pageSize", value = "分页大小"),
......
...@@ -28,9 +28,14 @@ import com.liquidnet.service.goblin.entity.GoblinSqbPerformanceGoods; ...@@ -28,9 +28,14 @@ import com.liquidnet.service.goblin.entity.GoblinSqbPerformanceGoods;
import com.liquidnet.service.goblin.mapper.GoblinBraceletOrderMapper; import com.liquidnet.service.goblin.mapper.GoblinBraceletOrderMapper;
import com.liquidnet.service.goblin.mapper.GoblinSqbPerformanceGoodsMapper; import com.liquidnet.service.goblin.mapper.GoblinSqbPerformanceGoodsMapper;
import com.liquidnet.service.goblin.service.impl.inner.GoblinNftJobServiceImpl; import com.liquidnet.service.goblin.service.impl.inner.GoblinNftJobServiceImpl;
import com.liquidnet.service.kylin.constant.KylinRedisConst;
import com.liquidnet.service.kylin.dto.vo.mongo.KylinPerformanceVo;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
import org.springframework.util.DigestUtils; import org.springframework.util.DigestUtils;
...@@ -52,6 +57,8 @@ public class GoblinRedisUtils { ...@@ -52,6 +57,8 @@ public class GoblinRedisUtils {
@Autowired @Autowired
public RedisUtil redisUtil; public RedisUtil redisUtil;
@Autowired @Autowired
private MongoTemplate mongoTemplate;
@Autowired
GoblinMongoUtils goblinMongoUtils; GoblinMongoUtils goblinMongoUtils;
@Autowired @Autowired
GoblinNftJobServiceImpl goblinNftJobService; GoblinNftJobServiceImpl goblinNftJobService;
...@@ -3064,6 +3071,27 @@ public class GoblinRedisUtils { ...@@ -3064,6 +3071,27 @@ public class GoblinRedisUtils {
/* --------------------------------收钱吧相关--------------------------------- */ /* --------------------------------收钱吧相关--------------------------------- */
/**
* 根据演出 id 获取演出详情(与 order 模块 {@code com.liquidnet.service.order.utils.DataUtils#getPerformanceVo} 逻辑一致)
*/
public KylinPerformanceVo getPerformanceVo(String performanceId) {
if (!StringUtils.hasText(performanceId)) {
return null;
}
String id = performanceId.trim();
Object obj = redisUtil.get(KylinRedisConst.PERFORMANCES + id);
if (obj != null) {
return (KylinPerformanceVo) obj;
}
KylinPerformanceVo performanceData = mongoTemplate.findOne(
Query.query(Criteria.where("performancesId").is(id)),
KylinPerformanceVo.class,
KylinPerformanceVo.class.getSimpleName());
redisUtil.set(KylinRedisConst.PERFORMANCES + id, performanceData);
return performanceData;
}
public void setSqbPerformanceGoodsListCache(String performancesId, List<GoblinSqbPerformanceGoods> relations) { public void setSqbPerformanceGoodsListCache(String performancesId, List<GoblinSqbPerformanceGoods> relations) {
String key = GoblinRedisConst.SQB_PERFORMANCE_GOODS.concat(performancesId); String key = GoblinRedisConst.SQB_PERFORMANCE_GOODS.concat(performancesId);
redisUtil.set(key, relations, RedisKeyExpireConst.SQB_PERFORMANCE_GOODS_EXPIRE); redisUtil.set(key, relations, RedisKeyExpireConst.SQB_PERFORMANCE_GOODS_EXPIRE);
......
...@@ -67,6 +67,9 @@ public class GoblinSqbOrderServiceImpl implements IGoblinSqbOrderService { ...@@ -67,6 +67,9 @@ public class GoblinSqbOrderServiceImpl implements IGoblinSqbOrderService {
String performancesId = orderParam.getPerformancesId(); String performancesId = orderParam.getPerformancesId();
Integer quantity = orderParam.getQuantity(); Integer quantity = orderParam.getQuantity();
String openId = orderParam.getOpenId(); String openId = orderParam.getOpenId();
if (StringUtil.isBlank(performancesId)) {
return ResponseDto.failure("关联演出ID不能为空");
}
if (openId == null || openId.trim().isEmpty()) { if (openId == null || openId.trim().isEmpty()) {
return ResponseDto.failure("微信 openId 不能为空"); return ResponseDto.failure("微信 openId 不能为空");
} }
...@@ -86,15 +89,15 @@ public class GoblinSqbOrderServiceImpl implements IGoblinSqbOrderService { ...@@ -86,15 +89,15 @@ public class GoblinSqbOrderServiceImpl implements IGoblinSqbOrderService {
return ResponseDto.failure("商品与演出关联不存在"); return ResponseDto.failure("商品与演出关联不存在");
} }
boolean skuIdExists = false; GoblinSqbPerformanceGoods matchedPerfRel = null;
for (GoblinSqbPerformanceGoods goblinSqbPerformanceGoods : performanceGoodsListCache) { for (GoblinSqbPerformanceGoods goblinSqbPerformanceGoods : performanceGoodsListCache) {
if (skuId.equals(goblinSqbPerformanceGoods.getSkuId())) { if (skuId.equals(goblinSqbPerformanceGoods.getSkuId())) {
skuIdExists = true; matchedPerfRel = goblinSqbPerformanceGoods;
break;
} }
} }
if (!skuIdExists) { if (matchedPerfRel == null) {
log.error("[收钱吧下单] 演出-商品关联不存在或已禁用,performancesId={}, skuId={}", performancesId, skuId); log.error("[收钱吧下单] 演出-商品关联不存在或已禁用,performancesId={}, skuId={}", performancesId, skuId);
return ResponseDto.failure("商品与演出关联不存在"); return ResponseDto.failure("商品与演出关联不存在");
} }
...@@ -121,6 +124,11 @@ public class GoblinSqbOrderServiceImpl implements IGoblinSqbOrderService { ...@@ -121,6 +124,11 @@ public class GoblinSqbOrderServiceImpl implements IGoblinSqbOrderService {
} }
log.info("[收钱吧下单] 扣减库存成功,skuId={}, 剩余库存={}", skuId, remaining); log.info("[收钱吧下单] 扣减库存成功,skuId={}, 剩余库存={}", skuId, remaining);
BigDecimal unitPriceYuan = resolveSqbUnitPriceYuan(skuVo, matchedPerfRel);
log.info("[收钱吧下单] 单价(元) performancesId={}, skuId={}, settlementPrice={}, 实际计价={}",
performancesId, skuId,
matchedPerfRel != null ? matchedPerfRel.getSettlementPrice() : null, unitPriceYuan);
// 获取该商品对应的商城的编号和密码 // 获取该商品对应的商城的编号和密码
GoblinSqbGoodsExtVo sqbGoodsExt = goblinSqbRedisUtils.getSqbGoodsExt(spuId, skuId); GoblinSqbGoodsExtVo sqbGoodsExt = goblinSqbRedisUtils.getSqbGoodsExt(spuId, skuId);
if (sqbGoodsExt == null) { if (sqbGoodsExt == null) {
...@@ -133,7 +141,7 @@ public class GoblinSqbOrderServiceImpl implements IGoblinSqbOrderService { ...@@ -133,7 +141,7 @@ public class GoblinSqbOrderServiceImpl implements IGoblinSqbOrderService {
sqbGoodsExt.getSignature(), sqbGoodsExt.getSignature(),
userId, userId,
Collections.singletonList(buildSqbCheckOutItem(skuVo, Collections.singletonList(buildSqbCheckOutItem(skuVo,
quantity, sqbGoodsExt.getSqbSkuId(), sqbGoodsExt.getSqbSpuId()))); quantity, sqbGoodsExt.getSqbSkuId(), sqbGoodsExt.getSqbSpuId(), unitPriceYuan)));
if (settlementData == null) { if (settlementData == null) {
goblinRedisUtils.incrSkuStock(null, skuId, quantity); goblinRedisUtils.incrSkuStock(null, skuId, quantity);
return ResponseDto.failure("创建结算明细失败"); return ResponseDto.failure("创建结算明细失败");
...@@ -231,10 +239,10 @@ public class GoblinSqbOrderServiceImpl implements IGoblinSqbOrderService { ...@@ -231,10 +239,10 @@ public class GoblinSqbOrderServiceImpl implements IGoblinSqbOrderService {
storeOrderVo.setUserName(""); storeOrderVo.setUserName("");
storeOrderVo.setUserMobile(""); storeOrderVo.setUserMobile("");
BigDecimal skuPrice = skuInfo != null ? skuInfo.getPrice() : BigDecimal.ZERO; BigDecimal skuPrice = unitPriceYuan;
BigDecimal priceTotal = skuPrice.multiply(new BigDecimal(quantity)); BigDecimal priceTotal = skuPrice.multiply(new BigDecimal(quantity));
storeOrderVo.setPriceTotal(priceTotal); storeOrderVo.setPriceTotal(priceTotal);
storeOrderVo.setPriceActual(priceTotal); // 收钱吧暂无运费及优惠逻辑,实际价格等于总价 storeOrderVo.setPriceActual(priceTotal); // 演出关联换购价或 SKU 售价,无额外运费/券
storeOrderVo.setPriceRefund(BigDecimal.ZERO); storeOrderVo.setPriceRefund(BigDecimal.ZERO);
storeOrderVo.setPriceExpress(BigDecimal.ZERO); storeOrderVo.setPriceExpress(BigDecimal.ZERO);
storeOrderVo.setPriceCoupon(BigDecimal.ZERO); storeOrderVo.setPriceCoupon(BigDecimal.ZERO);
...@@ -389,15 +397,40 @@ public class GoblinSqbOrderServiceImpl implements IGoblinSqbOrderService { ...@@ -389,15 +397,40 @@ public class GoblinSqbOrderServiceImpl implements IGoblinSqbOrderService {
* @param sqbSpuId * @param sqbSpuId
* @return * @return
*/ */
/**
* 演出入口下单:后台为该 SKU 配置了换购价且大于 0 时用换购价(元),否则用 SKU 销售价,再否则现价;换购价高于售价时按售价避免多收。
*/
private BigDecimal resolveSqbUnitPriceYuan(GoblinGoodsSkuInfoVo skuVo, GoblinSqbPerformanceGoods perfRel) {
if (skuVo == null) {
return BigDecimal.ZERO;
}
BigDecimal base = skuVo.getSellPrice() != null ? skuVo.getSellPrice() : skuVo.getPrice();
if (base == null) {
base = BigDecimal.ZERO;
}
if (perfRel == null || perfRel.getSettlementPrice() == null) {
return base;
}
BigDecimal sp = perfRel.getSettlementPrice();
if (sp.compareTo(BigDecimal.ZERO) <= 0) {
return base;
}
if (sp.compareTo(base) > 0) {
return base;
}
return sp;
}
private SettlementCreateRequest.CheckoutItem buildSqbCheckOutItem(GoblinGoodsSkuInfoVo skuVo, private SettlementCreateRequest.CheckoutItem buildSqbCheckOutItem(GoblinGoodsSkuInfoVo skuVo,
Integer quantity, Integer quantity,
String sqbSkuId, String sqbSkuId,
String sqbSpuId) { String sqbSpuId,
BigDecimal unitPriceYuan) {
// 获取商品与收钱吧商品对应的关联的skuId、spuId // 获取商品与收钱吧商品对应的关联的skuId、spuId
SettlementCreateRequest.CheckoutItem checkoutItem = new SettlementCreateRequest.CheckoutItem(); SettlementCreateRequest.CheckoutItem checkoutItem = new SettlementCreateRequest.CheckoutItem();
checkoutItem.setSpuId(sqbSpuId); checkoutItem.setSpuId(sqbSpuId);
checkoutItem.setSkuId(sqbSkuId); checkoutItem.setSkuId(sqbSkuId);
checkoutItem.setPrice(GoblinSqbConvertUtils.yuanToFen(skuVo.getPrice())); checkoutItem.setPrice(GoblinSqbConvertUtils.yuanToFen(unitPriceYuan));
checkoutItem.setQuantity(String.valueOf(quantity)); checkoutItem.setQuantity(String.valueOf(quantity));
checkoutItem.setType((byte) 0); checkoutItem.setType((byte) 0);
checkoutItem.setTitle(skuVo.getName()); checkoutItem.setTitle(skuVo.getName());
......
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