商品 批量操作
This commit is contained in:
@@ -63,7 +63,6 @@ public class ProductController {
|
||||
* 商品-分页
|
||||
*/
|
||||
@GetMapping("page")
|
||||
@OperationLog("商品-分页")
|
||||
//@SaAdminCheckPermission("product:page")
|
||||
public CzgResult<Map<String, Object>> getProductPage(ProductDTO param) {
|
||||
Page<ProductDTO> data = productService.getProductPage(param);
|
||||
@@ -83,7 +82,6 @@ public class ProductController {
|
||||
* 商品-列表
|
||||
*/
|
||||
@GetMapping("list")
|
||||
@OperationLog("商品-列表")
|
||||
public CzgResult<List<ProductDTO>> getProductList(@RequestParam(required = false) Long categoryId) {
|
||||
return CzgResult.success(productService.getProductCacheList(StpKit.USER.getShopId(), categoryId));
|
||||
}
|
||||
@@ -92,7 +90,6 @@ public class ProductController {
|
||||
* 商品-详情
|
||||
*/
|
||||
@GetMapping("{id}")
|
||||
@OperationLog("商品-详情")
|
||||
//@SaAdminCheckPermission("product:info")
|
||||
public CzgResult<ProductDTO> getProductById(@PathVariable("id") Long id) {
|
||||
AssertUtil.isNull(id, "{}不能为空", "id");
|
||||
@@ -242,7 +239,6 @@ public class ProductController {
|
||||
* 商品-统计
|
||||
*/
|
||||
@GetMapping("statistics")
|
||||
@OperationLog("商品-统计")
|
||||
//@SaAdminCheckPermission("product:statistics")
|
||||
public CzgResult<ProductStatisticsVo> statistics(ProductInfoParam param) {
|
||||
Long shopId = StpKit.USER.getShopId(0L);
|
||||
@@ -251,6 +247,17 @@ public class ProductController {
|
||||
return CzgResult.success(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 商品-批量操作
|
||||
*/
|
||||
@GetMapping("batchOperate")
|
||||
public CzgResult<Void> batchOperate(ProductBatchParam param) {
|
||||
Long shopId = StpKit.USER.getShopId();
|
||||
param.setShopId(shopId);
|
||||
productService.batchOperate(param);
|
||||
return CzgResult.success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 商品-报损
|
||||
*/
|
||||
|
||||
@@ -5,7 +5,10 @@ import com.alibaba.fastjson2.JSONWriter;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.data.redis.core.Cursor;
|
||||
import org.springframework.data.redis.core.RedisCallback;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.data.redis.core.ScanOptions;
|
||||
import org.springframework.data.redis.core.script.DefaultRedisScript;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
@@ -52,6 +55,34 @@ public class RedisService {
|
||||
return redisTemplate.delete(keys);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除某前缀Key
|
||||
* @param prefix
|
||||
*/
|
||||
public void deleteKeysByPrefixSafe(String prefix) {
|
||||
// 拼接匹配规则:前缀 + * → 比如传入 user → 匹配 user*
|
||||
String pattern = prefix + "*";
|
||||
|
||||
// redisTemplate.execute:使用 Redis 底层连接执行原生命令(性能更高)
|
||||
redisTemplate.execute((RedisCallback<Void>) connection -> {
|
||||
// try-with-resources:自动关闭游标,避免资源泄漏
|
||||
try (Cursor<byte[]> cursor = connection.scan(
|
||||
// SCAN 配置:匹配规则、每次扫描1000条
|
||||
ScanOptions.scanOptions().match(pattern).count(1000).build()
|
||||
)) {
|
||||
// 迭代遍历扫描到的所有 key
|
||||
while (cursor.hasNext()) {
|
||||
// 删除当前遍历到的 key
|
||||
connection.del(cursor.next());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// 异常捕获打印,避免删除失败导致程序报错
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 指定缓存失效时间
|
||||
*
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
package com.czg.product.param;
|
||||
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 商品批量操作
|
||||
*
|
||||
* @author ww
|
||||
*/
|
||||
@Data
|
||||
public class ProductBatchParam implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
/**
|
||||
* 商品id集合
|
||||
*/
|
||||
@NotNull(message = "商品id集合不能为空")
|
||||
private List<Long> ids;
|
||||
/**
|
||||
* 商品操作
|
||||
* category 修改分类
|
||||
* isSale 上下架
|
||||
* is_sold_stock 售罄
|
||||
* isAutoSoldStock 自动售罄
|
||||
*/
|
||||
@NotBlank(message = "操作类型不能为空")
|
||||
private String type;
|
||||
/**
|
||||
* 操作值
|
||||
*/
|
||||
@NotBlank(message = "操作值不能为空")
|
||||
private String value;
|
||||
/**
|
||||
* 店铺id
|
||||
*/
|
||||
private Long shopId;
|
||||
}
|
||||
@@ -110,7 +110,10 @@ public interface ProductService extends IService<Product> {
|
||||
* @param param 商品报损入参
|
||||
*/
|
||||
void reportDamage(ProductReportDamageParam param);
|
||||
|
||||
/**
|
||||
* 批量操作商品
|
||||
*/
|
||||
void batchOperate(ProductBatchParam param);
|
||||
/**
|
||||
* 商品统计
|
||||
*
|
||||
|
||||
@@ -401,6 +401,19 @@ public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> impl
|
||||
redisService.del(CacheConstant.USER_CLIENT_HOTS_PRODUCT + "::" + shopId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 清除某个商品分类的缓存
|
||||
*/
|
||||
private void clearProductAllCache(Long shopId) {
|
||||
//分类缓存
|
||||
redisService.deleteKeysByPrefixSafe(ADMIN_CLIENT_PRODUCT_LIST + "::" + shopId);
|
||||
//用户端分组缓存
|
||||
redisService.del(CacheConstant.USER_CLIENT_GROUPS_PRODUCT + "::" + shopId);
|
||||
//用户端热销缓存
|
||||
redisService.del(CacheConstant.USER_CLIENT_HOTS_PRODUCT + "::" + shopId);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 计算是否在可售时间内
|
||||
*
|
||||
@@ -778,6 +791,32 @@ public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> impl
|
||||
consStockByProduct(shopId, InOutTypeEnum.OUT, InOutItemEnum.DAMAGE_OUT, productStockList, null, "【商品报损,自动报损相关耗材】");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void batchOperate(ProductBatchParam param) {
|
||||
Product product = new Product();
|
||||
//商品操作
|
||||
//category 修改分类
|
||||
//isSale 上下架
|
||||
//is_sold_stock 售罄
|
||||
//isAutoSoldStock 自动售罄
|
||||
switch (param.getType()) {
|
||||
case "category":
|
||||
product.setCategoryId(Long.valueOf(param.getValue()));
|
||||
break;
|
||||
case "isSale":
|
||||
product.setIsSale(Integer.valueOf(param.getValue()));
|
||||
break;
|
||||
case "is_sold_stock":
|
||||
product.setIsSoldStock(Integer.valueOf(param.getValue()));
|
||||
break;
|
||||
case "isAutoSoldStock":
|
||||
product.setIsAutoSoldStock(Integer.valueOf(param.getValue()));
|
||||
break;
|
||||
}
|
||||
update(product, query().eq(Product::getShopId, param.getShopId()).in(Product::getId, param.getIds()));
|
||||
clearProductAllCache(param.getShopId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProductStatisticsVo getProductStatistics(ProductInfoParam param) {
|
||||
ProductStatisticsVo data = productStockFlowMapper.getProductStatistics(param);
|
||||
|
||||
Reference in New Issue
Block a user