商品 批量操作
This commit is contained in:
@@ -63,7 +63,6 @@ public class ProductController {
|
|||||||
* 商品-分页
|
* 商品-分页
|
||||||
*/
|
*/
|
||||||
@GetMapping("page")
|
@GetMapping("page")
|
||||||
@OperationLog("商品-分页")
|
|
||||||
//@SaAdminCheckPermission("product:page")
|
//@SaAdminCheckPermission("product:page")
|
||||||
public CzgResult<Map<String, Object>> getProductPage(ProductDTO param) {
|
public CzgResult<Map<String, Object>> getProductPage(ProductDTO param) {
|
||||||
Page<ProductDTO> data = productService.getProductPage(param);
|
Page<ProductDTO> data = productService.getProductPage(param);
|
||||||
@@ -83,7 +82,6 @@ public class ProductController {
|
|||||||
* 商品-列表
|
* 商品-列表
|
||||||
*/
|
*/
|
||||||
@GetMapping("list")
|
@GetMapping("list")
|
||||||
@OperationLog("商品-列表")
|
|
||||||
public CzgResult<List<ProductDTO>> getProductList(@RequestParam(required = false) Long categoryId) {
|
public CzgResult<List<ProductDTO>> getProductList(@RequestParam(required = false) Long categoryId) {
|
||||||
return CzgResult.success(productService.getProductCacheList(StpKit.USER.getShopId(), categoryId));
|
return CzgResult.success(productService.getProductCacheList(StpKit.USER.getShopId(), categoryId));
|
||||||
}
|
}
|
||||||
@@ -92,7 +90,6 @@ public class ProductController {
|
|||||||
* 商品-详情
|
* 商品-详情
|
||||||
*/
|
*/
|
||||||
@GetMapping("{id}")
|
@GetMapping("{id}")
|
||||||
@OperationLog("商品-详情")
|
|
||||||
//@SaAdminCheckPermission("product:info")
|
//@SaAdminCheckPermission("product:info")
|
||||||
public CzgResult<ProductDTO> getProductById(@PathVariable("id") Long id) {
|
public CzgResult<ProductDTO> getProductById(@PathVariable("id") Long id) {
|
||||||
AssertUtil.isNull(id, "{}不能为空", "id");
|
AssertUtil.isNull(id, "{}不能为空", "id");
|
||||||
@@ -242,7 +239,6 @@ public class ProductController {
|
|||||||
* 商品-统计
|
* 商品-统计
|
||||||
*/
|
*/
|
||||||
@GetMapping("statistics")
|
@GetMapping("statistics")
|
||||||
@OperationLog("商品-统计")
|
|
||||||
//@SaAdminCheckPermission("product:statistics")
|
//@SaAdminCheckPermission("product:statistics")
|
||||||
public CzgResult<ProductStatisticsVo> statistics(ProductInfoParam param) {
|
public CzgResult<ProductStatisticsVo> statistics(ProductInfoParam param) {
|
||||||
Long shopId = StpKit.USER.getShopId(0L);
|
Long shopId = StpKit.USER.getShopId(0L);
|
||||||
@@ -251,6 +247,17 @@ public class ProductController {
|
|||||||
return CzgResult.success(data);
|
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 jakarta.annotation.Resource;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
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.RedisTemplate;
|
||||||
|
import org.springframework.data.redis.core.ScanOptions;
|
||||||
import org.springframework.data.redis.core.script.DefaultRedisScript;
|
import org.springframework.data.redis.core.script.DefaultRedisScript;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import org.springframework.util.CollectionUtils;
|
import org.springframework.util.CollectionUtils;
|
||||||
@@ -52,6 +55,34 @@ public class RedisService {
|
|||||||
return redisTemplate.delete(keys);
|
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 商品报损入参
|
* @param param 商品报损入参
|
||||||
*/
|
*/
|
||||||
void reportDamage(ProductReportDamageParam 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);
|
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, "【商品报损,自动报损相关耗材】");
|
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
|
@Override
|
||||||
public ProductStatisticsVo getProductStatistics(ProductInfoParam param) {
|
public ProductStatisticsVo getProductStatistics(ProductInfoParam param) {
|
||||||
ProductStatisticsVo data = productStockFlowMapper.getProductStatistics(param);
|
ProductStatisticsVo data = productStockFlowMapper.getProductStatistics(param);
|
||||||
|
|||||||
Reference in New Issue
Block a user