收音机 / 客户端 商品列表

This commit is contained in:
2026-04-09 16:54:57 +08:00
parent caec6b2d0f
commit 3448331b31
4 changed files with 32 additions and 78 deletions

View File

@@ -56,9 +56,6 @@ public class ProductController {
@Resource
private ShopSyncService shopSyncService;
@Resource
private UProductService uProductService;
@Resource
private ShopInfoService shopInfoService;
@@ -87,12 +84,8 @@ public class ProductController {
*/
@GetMapping("list")
@OperationLog("商品-列表")
//@SaAdminCheckPermission("product:list")
public CzgResult<List<ProductDTO>> getProductList(ProductDTO param) {
Long shopId = StpKit.USER.getShopId();
param.setShopId(shopId);
List<ProductDTO> productList = productService.getProductCacheList(param);
productList.forEach(prod -> prod.setIsSaleTime(uProductService.calcIsSaleTime(prod.getDays(), prod.getStartTime(), prod.getEndTime())));
public CzgResult<List<ProductDTO>> getProductList(@RequestParam Long categoryId) {
List<ProductDTO> productList = productService.getProductCacheList(StpKit.USER.getShopId(), categoryId);
return CzgResult.success(productList);
}

View File

@@ -5,6 +5,7 @@ import cn.hutool.core.convert.Convert;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.annotation.JSONField;
import com.czg.product.entity.ProdConsRelation;
import com.czg.product.vo.ProductGroupVo;
import com.czg.validator.group.DefaultGroup;
import com.czg.validator.group.InsertGroup;
@@ -217,6 +218,8 @@ public class ProductDTO implements Serializable {
* 商品关联耗材列表
*/
private List<ProdConsRelationDTO> consList;
//
private List<ProdConsRelation> prodConsRelations;
/**
* 耗材信息
*/
@@ -240,13 +243,6 @@ public class ProductDTO implements Serializable {
return JSON.parseArray(Convert.toStr(images, "[]"));
}
/**
* {"口味":[{"甜度":["少甜","中甜","多甜"]},{"辣度":["微辣","重辣","变态辣"]},{"小料":["葱花","香菜","折耳根"]}]}
*/
public Object getSelectSpecInfo() {
return JSON.parseObject(Convert.toStr(selectSpecInfo, "{}"));
}
public Object getGroupSnap() {
return JSON.parseArray(Convert.toStr(groupSnap, "[]"));
}

View File

@@ -38,10 +38,11 @@ public interface ProductService extends IService<Product> {
/**
* 从缓存里面获取商品列表
*
* @param param 查询参数
* @param shopId 店铺ID
* @param categoryId 商品分类ID
* @return 商品列表数据
*/
List<ProductDTO> getProductCacheList(ProductDTO param);
List<ProductDTO> getProductCacheList(Long shopId, Long categoryId);
/**
* 清除某个商品分类的缓存

View File

@@ -27,10 +27,8 @@ import com.czg.service.product.mapper.*;
import com.czg.utils.PageUtil;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.core.row.DbChain;
import com.mybatisflex.core.update.UpdateChain;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletResponse;
import lombok.AllArgsConstructor;
@@ -46,7 +44,6 @@ import java.time.LocalDate;
import java.time.LocalTime;
import java.time.format.TextStyle;
import java.util.*;
import java.util.stream.Collectors;
import static com.czg.constant.CacheConstant.ADMIN_CLIENT_PRODUCT_LIST;
import static com.czg.product.entity.table.ProductTableDef.PRODUCT;
@@ -172,9 +169,20 @@ public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> impl
@Override
public List<ProductDTO> getProductList(ProductDTO param) {
QueryWrapper queryWrapper = buildFullQueryWrapper(param);
//queryWrapper.eq(Product::getIsSale, SystemConstants.OneZero.ONE);
List<ProductDTO> records = super.listAs(queryWrapper, ProductDTO.class);
buildProductExtInfo(records);
records.forEach(record -> {
record.setProGroupVo(JSONArray.parseArray(record.getGroupSnap().toString(), ProductGroupVo.class));
List<ProdSkuDTO> skuList = prodSkuMapper.selectListByQueryAs(query().eq(ProdSku::getProductId, record.getId()).eq(ProdSku::getIsDel, SystemConstants.OneZero.ZERO), ProdSkuDTO.class);
if (CollUtil.isNotEmpty(skuList)) {
Optional<BigDecimal> lowPriceIsPresent = skuList.stream().map(obj -> NumberUtil.nullToZero(obj.getSalePrice())).min(BigDecimal::compareTo);
lowPriceIsPresent.ifPresent(record::setLowPrice);
Optional<BigDecimal> lowMemberPriceIsPresent = skuList.stream().map(obj -> NumberUtil.nullToZero(obj.getMemberPrice())).min(BigDecimal::compareTo);
lowMemberPriceIsPresent.ifPresent(record::setLowMemberPrice);
}
record.setSkuList(skuList);
record.setProdConsRelations(prodConsRelationMapper.selectListByQuery(query().eq(ProdConsRelation::getProductId, record.getId()).eq(ProdConsRelation::getShopId, record.getShopId())));
});
return records;
}
@@ -326,27 +334,14 @@ public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> impl
}
@Override
public List<ProductDTO> getProductCacheList(ProductDTO param) {
Long shopId = param.getShopId();
initProductCache(shopId);
String prefix = ADMIN_CLIENT_PRODUCT_LIST + "::" + shopId + "::";
public List<ProductDTO> getProductCacheList(Long shopId, Long categoryId) {
String key = ADMIN_CLIENT_PRODUCT_LIST + "::" + shopId + "::" + categoryId;
List<ProductDTO> list;
if (param.getCategoryId() == null) {
list = new ArrayList<>();
Set<String> keys = redisService.rightLikeKey(prefix);
for (String key : keys) {
List<ProductDTO> prodList = redisService.getJsonToBeanList(key, ProductDTO.class);
if(CollUtil.isNotEmpty(prodList)) {
list.addAll(prodList);
}
}
if (!redisService.hasKey(key)) {
list = initProductCacheByCategoryId(shopId, categoryId);
} else {
String key = prefix + param.getCategoryId();
list = redisService.getJsonToBeanList(key, ProductDTO.class);
}
if (StrUtil.isNotEmpty(param.getName())) {
list = list.stream().filter(obj -> StrUtil.contains(obj.getName(), param.getName())).toList();
}
// 重新进行排序
list = list.stream()
.sorted(Comparator.comparingInt(ProductDTO::getIsSoldStock))
@@ -360,28 +355,14 @@ public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> impl
/**
* 初始化商品缓存数据
*/
private void initProductCache(Long shopId) {
private List<ProductDTO> initProductCacheByCategoryId(Long shopId, Long categoryId) {
ProductDTO param = new ProductDTO();
param.setShopId(shopId);
param.setCategoryId(categoryId);
List<ProductDTO> productList = getProductList(param);
Map<Long, List<ProductDTO>> categoryMap = productList.stream().filter(item -> item.getCategoryId() != null).collect(Collectors.groupingBy(ProductDTO::getCategoryId));
ShopProdCategoryDTO dto = new ShopProdCategoryDTO();
dto.setShopId(shopId);
List<ShopProdCategoryDTO> categoryList = shopProdCategoryService.getShopProdCategoryList(dto);
String prefix = ADMIN_CLIENT_PRODUCT_LIST + "::" + shopId + "::";
for (ShopProdCategoryDTO category : categoryList) {
String key = prefix + category.getId();
boolean b = redisService.hasKey(key);
if (!b) {
List<ProductDTO> list = categoryMap.get(category.getId());
if (CollUtil.isNotEmpty(list)) {
redisService.setJsonStr(key, list);
} else {
List<ProductDTO> empty = new ArrayList<>();
redisService.setJsonStr(key, empty);
}
}
}
String key = ADMIN_CLIENT_PRODUCT_LIST + "::" + shopId + "::" + categoryId;
redisService.setJsonStr(key, productList);
return productList;
}
/**
@@ -396,23 +377,6 @@ public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> impl
}
}
/**
* 系统启动会一次性加载商品缓存数据,防止首次访问时加载缓慢的问题
*/
@PostConstruct
public void initProductListCache() {
log.info("系统启动后初始化商品列表缓存,开始...");
List<Long> shopIdList = DbChain.table("tb_shop_info").select("id").listAs(Long.class);
for (Long shopId : shopIdList) {
log.info("商品列表缓存>>当前店铺:{}", shopId);
ProductDTO dto = new ProductDTO();
dto.setShopId(shopId);
getProductCacheList(dto);
log.info("商品列表缓存>>当前店铺:{},初始化结束", shopId);
}
log.info("系统启动后初始化商品列表缓存,结束。");
}
/**
* 计算是否在可售时间内
*
@@ -625,7 +589,7 @@ public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> impl
.eq(Product::getId, prodSku.getProductId())
.eq(Product::getShopId, shopId)
.update();
}else if(normalCount > 0 && product.getIsSale() == SystemConstants.OneZero.ZERO) {
} else if (normalCount > 0 && product.getIsSale() == SystemConstants.OneZero.ZERO) {
UpdateChain.of(Product.class)
.set(Product::getIsSale, SystemConstants.OneZero.ONE)
.eq(Product::getId, prodSku.getProductId())
@@ -634,7 +598,7 @@ public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> impl
}
sensitiveOperation = sensitiveOperation + "商品:" + product.getName() + " 规格:" + prodSku.getSpecInfo();
} else if (ProductIsSaleTypeEnum.PRODUCT.value().equals(type)) {
if("sale".equals(param.getOptType())){
if ("sale".equals(param.getOptType())) {
UpdateChain.of(Product.class)
.set(Product::getIsSale, isSale)
.eq(Product::getId, id)