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

Commit 8fc01068 authored by 姜秀龙's avatar 姜秀龙

收钱吧 admin autoOffline改单独存放

parent a38c138c
......@@ -67,3 +67,13 @@ CREATE TABLE `goblin_sqb_order` (
KEY `idx_performances_id` (`performances_id`),
KEY `idx_sqb_acquiring_sn` (`sqb_acquiring_sn`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='收钱吧订单';
CREATE TABLE `goblin_sqb_performance_config` (
`mid` bigint(20) NOT NULL AUTO_INCREMENT,
`performances_id` varchar(64) NOT NULL COMMENT '演出ID',
`auto_offline` tinyint(4) DEFAULT '0' COMMENT '演出结束自动下架 0-否 1-是',
`created_at` datetime DEFAULT CURRENT_TIMESTAMP,
`updated_at` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`mid`),
UNIQUE KEY `uk_perf_id` (`performances_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='收钱吧演出级全局配置';
......@@ -17,8 +17,6 @@ public class GoblinSqbPerfGoodsVo implements Serializable {
private Integer sort;
/** 换购价格(为 null 时按售价) */
private BigDecimal settlementPrice;
/** 演出结束自动下架 0-否 1-是 */
private Integer autoOffline;
/** 商品库存(管理后台展示用) */
private Integer stock;
/** 商品状态(管理后台展示用) */
......
package com.liquidnet.service.goblin.dto.vo;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
@Data
public class GoblinSqbPerfListRespVo implements Serializable {
private static final long serialVersionUID = 1L;
/** 演出结束自动下架 0-否 1-是(全局配置) */
private Integer autoOffline;
/** 关联商品列表 */
private List<GoblinSqbPerfGoodsVo> goodsList;
}
......@@ -6,6 +6,7 @@ import com.liquidnet.client.admin.zhengzai.goblin.dto.SqbPerfGoodsBindItemParam;
import com.liquidnet.client.admin.zhengzai.goblin.service.ISqbPerformanceGoodsService;
import com.liquidnet.service.base.ResponseDto;
import com.liquidnet.service.goblin.dto.vo.GoblinSqbPerfGoodsVo;
import com.liquidnet.service.goblin.dto.vo.GoblinSqbPerfListRespVo;
import io.swagger.annotations.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
......@@ -60,13 +61,15 @@ public class SqbPerformanceGoodsController extends BaseController {
*/
@PostMapping("bind")
@ResponseBody
@ApiOperation("批量绑定演出与商品(含换购价、自动下架配置)")
@ApiOperation("批量绑定演出与商品(含换购价、演出级自动下架全局配置)")
@ApiImplicitParams({
@ApiImplicitParam(type = "form", 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-是"),
})
public AjaxResult bind(@RequestParam("performancesId") String performancesId,
@RequestParam(value = "autoOffline", required = false, defaultValue = "0") Integer autoOffline,
@RequestBody List<SqbPerfGoodsBindItemParam> items) {
ResponseDto<Boolean> resp = sqbPerformanceGoodsService.bind(performancesId, items);
ResponseDto<Boolean> resp = sqbPerformanceGoodsService.bind(performancesId, items, autoOffline);
if (resp.isSuccess()) {
return AjaxResult.success("保存成功");
}
......@@ -97,12 +100,12 @@ public class SqbPerformanceGoodsController extends BaseController {
*/
@GetMapping("list")
@ResponseBody
@ApiOperation("查询演出关联商品列表(管理后台)")
@ApiOperation("查询演出关联商品列表(含全局配置)")
@ApiImplicitParams({
@ApiImplicitParam(type = "query", required = true, dataType = "String", name = "performancesId", value = "演出ID"),
})
public AjaxResult list(@RequestParam("performancesId") String performancesId) {
ResponseDto<List<GoblinSqbPerfGoodsVo>> resp = sqbPerformanceGoodsService.list(performancesId);
ResponseDto<GoblinSqbPerfListRespVo> resp = sqbPerformanceGoodsService.list(performancesId);
if (resp.isSuccess()) {
return AjaxResult.success(resp.getData());
}
......
......@@ -52,13 +52,12 @@
<th>商品售价(元)</th>
<th>换购价(元)</th>
<th>商品库存</th>
<th>自动下架</th>
<th>操作</th>
</tr>
</thead>
<tbody id="linkedGoodsBody">
<tr id="emptyRow">
<td colspan="8" style="text-align:center;color:#999;">暂无关联商品</td>
<td colspan="7" style="text-align:center;color:#999;">暂无关联商品</td>
</tr>
</tbody>
</table>
......@@ -148,13 +147,18 @@
// 加载已关联商品
function loadLinkedGoods() {
$.get(prefix + '/list', { performancesId: performancesId }, function (resp) {
if (resp.code === 0 && resp.data && resp.data.length > 0) {
linkedGoods = resp.data.map(function (item) {
if (resp.code === 0 && resp.data) {
// 设置全局开关状态
var globalAuto = resp.data.autoOffline === 1;
$('#globalAutoOffline').prop('checked', globalAuto);
var list = resp.data.goodsList || [];
linkedGoods = list.map(function (item) {
return {
skuId: item.skuId, spuId: item.spuId,
spuName: item.spuName || item.skuName, skuName: item.skuName,
coverPic: item.coverPic || '', price: item.price, stock: item.stock,
settlementPrice: item.settlementPrice || '', autoOffline: item.autoOffline || 0
settlementPrice: item.settlementPrice || ''
};
});
renderLinkedGoods();
......@@ -165,14 +169,13 @@
function renderLinkedGoods() {
var tbody = document.getElementById('linkedGoodsBody');
if (linkedGoods.length === 0) {
tbody.innerHTML = '<tr id="emptyRow"><td colspan="8" style="text-align:center;color:#999;">暂无关联商品</td></tr>';
tbody.innerHTML = '<tr id="emptyRow"><td colspan="7" style="text-align:center;color:#999;">暂无关联商品</td></tr>';
return;
}
var html = '';
linkedGoods.forEach(function (item, idx) {
var priceYuan = item.price ? (item.price / 100).toFixed(2) : '-';
var settlementVal = item.settlementPrice || '';
var autoChecked = item.autoOffline == 1 ? 'checked' : '';
var imgHtml = item.coverPic
? '<img src="' + item.coverPic + '" class="img-thumb"/>'
: '<span style="color:#ccc;font-size:12px;">无图</span>';
......@@ -184,7 +187,6 @@
html += '<td><input type="number" class="form-control settlement-input" value="' + settlementVal
+ '" placeholder="不填按售价" onchange="updateSettlement(' + idx + ', this.value)" min="0" step="0.01"/></td>';
html += '<td>' + (item.stock != null ? item.stock : '-') + '</td>';
html += '<td><input type="checkbox" ' + autoChecked + ' onchange="updateAutoOffline(' + idx + ', this)"/></td>';
html += '<td><button type="button" class="btn btn-xs btn-danger" onclick="removeLinked(' + idx + ')">取消关联</button></td>';
html += '</tr>';
});
......@@ -217,9 +219,8 @@
}
function toggleGlobalAutoOffline(checkbox) {
var val = checkbox.checked ? 1 : 0;
linkedGoods.forEach(function (item) { item.autoOffline = val; });
renderLinkedGoods();
// 全局开关,无需在 linkedGoods 中逐个维护 autoOffline
// 只需在保存时通过 checkbox.checked 获取
}
function removeLinked(idx) {
......@@ -242,15 +243,15 @@
}
function saveConfig() {
var autoOffline = $('#globalAutoOffline').is(':checked') ? 1 : 0;
var items = linkedGoods.map(function (item) {
return {
skuId: item.skuId, sort: 0,
settlementPrice: item.settlementPrice || null,
autoOffline: item.autoOffline || 0
settlementPrice: item.settlementPrice || null
};
});
$.ajax({
url: prefix + '/bind?performancesId=' + encodeURIComponent(performancesId),
url: prefix + '/bind?performancesId=' + encodeURIComponent(performancesId) + '&autoOffline=' + autoOffline,
type: 'POST',
contentType: 'application/json',
data: JSON.stringify(items),
......
......@@ -19,7 +19,4 @@ public class SqbPerfGoodsBindItemParam implements Serializable {
/** 换购价格(null 表示不设置换购价,按原价售卖) */
private BigDecimal settlementPrice;
/** 演出结束自动下架 0-否 1-是 */
private Integer autoOffline;
}
......@@ -3,6 +3,7 @@ package com.liquidnet.client.admin.zhengzai.goblin.service;
import com.liquidnet.client.admin.zhengzai.goblin.dto.SqbPerfGoodsBindItemParam;
import com.liquidnet.service.base.ResponseDto;
import com.liquidnet.service.goblin.dto.vo.GoblinSqbPerfGoodsVo;
import com.liquidnet.service.goblin.dto.vo.GoblinSqbPerfListRespVo;
import java.util.List;
......@@ -12,13 +13,14 @@ import java.util.List;
public interface ISqbPerformanceGoodsService {
/**
* 关联演出与商品(批量,支持换购价/自动下架配置)
* 关联演出与商品(批量,支持换购价/演出级自动下架全局配置)
*
* @param performancesId 演出ID
* @param items 绑定项列表(含配置)
* @param items 绑定项列表(仅含 SKU ID、排序、换购价)
* @param autoOffline 演出结束自动下架 0-否 1-是(全局配置)
* @return 操作结果
*/
ResponseDto<Boolean> bind(String performancesId, List<SqbPerfGoodsBindItemParam> items);
ResponseDto<Boolean> bind(String performancesId, List<SqbPerfGoodsBindItemParam> items, Integer autoOffline);
/**
* 解除演出与商品关联
......@@ -30,12 +32,12 @@ public interface ISqbPerformanceGoodsService {
ResponseDto<Boolean> unbind(String performancesId, String skuId);
/**
* 查询演出关联的收钱吧商品列表
* 查询演出关联的收钱吧商品列表(包含全局配置)
*
* @param performancesId 演出ID
* @return 商品列表
* @return 商品列表及配置
*/
ResponseDto<List<GoblinSqbPerfGoodsVo>> list(String performancesId);
ResponseDto<GoblinSqbPerfListRespVo> list(String performancesId);
/**
* 搜索收钱吧商品(skuType=33,供关联候选)
......
package com.liquidnet.service.goblin.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
/**
* <p>
* 演出-收钱吧配置
* </p>
*
* @author liquidnet
* @since 2025-03-27
*/
@Data
@EqualsAndHashCode(callSuper = false)
@TableName("goblin_sqb_performance_config")
public class GoblinSqbPerformanceConfig implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 演出ID
*/
@TableId(value = "performances_id", type = IdType.INPUT)
private String performancesId;
/**
* 演出结束自动下架 0-否 1-是
*/
private Integer autoOffline;
private String createdAt;
private String updatedAt;
}
......@@ -52,11 +52,6 @@ public class GoblinSqbPerformanceGoods implements Serializable {
*/
private BigDecimal settlementPrice;
/**
* 演出结束自动下架 0-否 1-是
*/
private Integer autoOffline;
/**
* 状态 0-禁用 1-启用
*/
......
package com.liquidnet.service.goblin.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.liquidnet.service.goblin.entity.GoblinSqbPerformanceConfig;
import org.apache.ibatis.annotations.Mapper;
/**
* <p>
* 演出-收钱吧配置 Mapper 接口
* </p>
*
* @author liquidnet
* @since 2025-03-27
*/
@Mapper
public interface GoblinSqbPerformanceConfigMapper extends BaseMapper<GoblinSqbPerformanceConfig> {
}
......@@ -13,6 +13,8 @@ import com.liquidnet.service.goblin.mapper.GoblinGoodsMapper;
import com.liquidnet.service.goblin.mapper.GoblinGoodsSkuMapper;
import com.liquidnet.service.goblin.mapper.GoblinSqbGoodsExtMapper;
import com.liquidnet.service.goblin.mapper.GoblinSqbPerformanceGoodsMapper;
import com.liquidnet.service.goblin.mapper.GoblinSqbPerformanceConfigMapper;
import com.liquidnet.service.goblin.entity.GoblinSqbPerformanceConfig;
import com.liquidnet.service.goblin.param.shouqianba.request.CommonRequest;
import com.liquidnet.service.goblin.param.shouqianba.request.MallListQueryRequest;
import com.liquidnet.service.goblin.param.shouqianba.request.MallProductsQueryRequest;
......@@ -21,6 +23,8 @@ import com.liquidnet.service.goblin.param.shouqianba.response.data.MallProductsQ
import com.liquidnet.service.goblin.param.shouqianba.request.GoblinSqbGoodsSyncParam;
import com.liquidnet.service.goblin.service.IGoblinShouQianBaService;
import com.liquidnet.service.goblin.service.IGoblinSqbGoodsService;
import com.liquidnet.service.goblin.util.GoblinMongoUtils;
import com.liquidnet.service.goblin.dto.vo.GoblinSelfMarketingVo;
import com.liquidnet.service.goblin.util.GoblinRedisUtils;
import com.liquidnet.service.goblin.util.GoblinSqbRedisUtils;
import lombok.extern.slf4j.Slf4j;
......@@ -75,6 +79,12 @@ public class GoblinSqbGoodsServiceImpl implements IGoblinSqbGoodsService {
@Autowired
private GoblinRedisUtils goblinRedisUtils;
@Autowired
private GoblinSqbPerformanceConfigMapper goblinSqbPerformanceConfigMapper;
@Autowired
private GoblinMongoUtils goblinMongoUtils;
@Autowired
private IGoblinstoreMgtGoodsService goblinstoreMgtGoodsService;
......@@ -400,6 +410,21 @@ public class GoblinSqbGoodsServiceImpl implements IGoblinSqbGoodsService {
@Override
public ResponseDto<List<GoblinSqbPerfGoodsVo>> getPerfGoods(String performancesId) {
// 1. 获取演出级全局配置
GoblinSqbPerformanceConfig config = goblinSqbPerformanceConfigMapper.selectOne(
new LambdaQueryWrapper<GoblinSqbPerformanceConfig>()
.eq(GoblinSqbPerformanceConfig::getPerformancesId, performancesId)
);
// 2. 如果开启了自动下架,检查演出状态
if (config != null && Integer.valueOf(1).equals(config.getAutoOffline())) {
// 通过 Mongo 营销活动或者 Redis 查询演出详情判断是否结束
if (isPerformanceEnded(performancesId)) {
log.info("[收钱吧] 演出已结束,且开启了自动下架,返回空列表, performancesId={}", performancesId);
return ResponseDto.success(new ArrayList<>());
}
}
List<GoblinSqbPerfGoodsVo> cached = goblinSqbRedisUtils.getPerfGoods(performancesId);
if (cached != null) return ResponseDto.success(cached);
try {
......@@ -435,6 +460,23 @@ public class GoblinSqbGoodsServiceImpl implements IGoblinSqbGoodsService {
}
}
private boolean isPerformanceEnded(String performancesId) {
try {
// 借鉴 GoblinMongoUtils 中的逻辑,通过关联的官方营销活动状态判断演出状态
// status: 2 表示活动结束, 7 表示停用
List<GoblinSelfMarketingVo> marketingList = goblinMongoUtils.getSelfMarketingByPerformanceId(performancesId);
if (!CollectionUtils.isEmpty(marketingList)) {
GoblinSelfMarketingVo marketing = marketingList.get(0);
if (Integer.valueOf(2).equals(marketing.getStatus()) || Integer.valueOf(7).equals(marketing.getStatus())) {
return true;
}
}
} catch (Exception e) {
log.error("[收钱吧] 校验演出自动下架状态异常, performancesId={}", performancesId, e);
}
return false;
}
private CommonRequest.Seller buildSeller() {
CommonRequest.Seller seller = new CommonRequest.Seller();
seller.setMerchantId(SQB_MERCHANT_ID);
......
......@@ -1150,6 +1150,13 @@ public class GoblinMongoUtils {
}
//获取全部正在下单的活动
/* ---------------------------------------- 官方营销数据源 ---------------------------------------- */
public List<GoblinSelfMarketingVo> getSelfMarketingByPerformanceId(String performanceId) {
Query query = Query.query(Criteria.where("performanceId").is(performanceId).and("status").ne(7));
return mongoTemplate.find(query, GoblinSelfMarketingVo.class, GoblinSelfMarketingVo.class.getSimpleName());
}
public List<GoblinSelfMarketingVo> getGoblinSelfMarketingVoList() {
String nowStr = DateUtil.getNowTime();
List<GoblinSelfMarketingVo> voList = mongoTemplate.find(Query.query(Criteria.where("type").is(2).and("status").ne(7).and("endTime").gte(nowStr).and("startTime").lte(nowStr)), GoblinSelfMarketingVo.class, GoblinSelfMarketingVo.class.getSimpleName());
......
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