用户端商品缓存+商品信息修改缓存自动清空
This commit is contained in:
parent
af56a1e9ea
commit
4b5f62705d
|
|
@ -5,12 +5,14 @@ import org.mybatis.spring.annotation.MapperScan;
|
|||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
|
||||
import org.springframework.transaction.annotation.EnableTransactionManagement;
|
||||
|
||||
/**
|
||||
* @author ww
|
||||
*/
|
||||
@SpringBootApplication
|
||||
@EnableDiscoveryClient
|
||||
@EnableTransactionManagement
|
||||
@EnableDubbo
|
||||
@MapperScan("com.czg.service.product.mapper")
|
||||
public class ProductApplication {
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import com.czg.product.param.ProductIsSoldOutParam;
|
|||
import com.czg.product.service.ProdConsRelationService;
|
||||
import com.czg.product.service.ProductService;
|
||||
import com.czg.resp.CzgResult;
|
||||
import com.czg.sa.StpKit;
|
||||
import com.czg.utils.AssertUtil;
|
||||
import com.czg.validator.ValidatorUtil;
|
||||
import com.czg.validator.group.DefaultGroup;
|
||||
|
|
@ -70,6 +71,8 @@ public class ProductController {
|
|||
for (ProdSkuDTO prodSkuDTO : dto.getSkuList()) {
|
||||
ValidatorUtil.validateEntity(prodSkuDTO, DefaultGroup.class);
|
||||
}
|
||||
Long shopId = StpKit.USER.getShopId(0L);
|
||||
dto.setShopId(shopId);
|
||||
productService.addProduct(dto);
|
||||
return CzgResult.success();
|
||||
}
|
||||
|
|
@ -78,6 +81,8 @@ public class ProductController {
|
|||
@OperationLog("商品-修改")
|
||||
//@SaAdminCheckPermission("product:update")
|
||||
public CzgResult<Void> updateProduct(@RequestBody @Validated({UpdateGroup.class, DefaultGroup.class}) ProductDTO dto) {
|
||||
Long shopId = StpKit.USER.getShopId(0L);
|
||||
dto.setShopId(shopId);
|
||||
productService.updateProduct(dto);
|
||||
return CzgResult.success();
|
||||
}
|
||||
|
|
@ -88,7 +93,8 @@ public class ProductController {
|
|||
public CzgResult<Void> deleteProduct(@PathVariable("id") Long id) {
|
||||
//效验数据
|
||||
AssertUtil.isNull(id, "{}不能为空", "id");
|
||||
productService.deleteProduct(id);
|
||||
Long shopId = StpKit.USER.getShopId(0L);
|
||||
productService.deleteProduct(shopId, id);
|
||||
return CzgResult.success();
|
||||
}
|
||||
|
||||
|
|
@ -99,6 +105,8 @@ public class ProductController {
|
|||
@OperationLog("商品-上下架")
|
||||
//@SaAdminCheckPermission("product:on-off")
|
||||
public CzgResult<Void> onOffProduct(@RequestBody @Validated({DefaultGroup.class}) ProductIsSaleParam param) {
|
||||
Long shopId = StpKit.USER.getShopId(0L);
|
||||
param.setShopId(shopId);
|
||||
productService.onOffProduct(param);
|
||||
return CzgResult.success();
|
||||
}
|
||||
|
|
@ -110,6 +118,8 @@ public class ProductController {
|
|||
@OperationLog("商品-标记售罄")
|
||||
//@SaAdminCheckPermission("product:markIsSoldOut")
|
||||
public CzgResult<Void> markIsSoldOutProduct(@RequestBody @Validated({DefaultGroup.class}) ProductIsSoldOutParam param) {
|
||||
Long shopId = StpKit.USER.getShopId(0L);
|
||||
param.setShopId(shopId);
|
||||
productService.markProductIsSoldOut(param);
|
||||
return CzgResult.success();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import com.czg.product.vo.ShopProductInfoVo;
|
|||
import com.czg.product.vo.ShopProductSkuInfoVo;
|
||||
import com.czg.product.vo.ShopProductVo;
|
||||
import com.czg.resp.CzgResult;
|
||||
import com.czg.sa.StpKit;
|
||||
import com.czg.utils.AssertUtil;
|
||||
import com.czg.validator.ValidatorUtil;
|
||||
import com.czg.validator.group.DefaultGroup;
|
||||
|
|
@ -36,7 +37,8 @@ public class UProductController {
|
|||
*/
|
||||
@GetMapping("/miniApp/hots/query")
|
||||
public CzgResult<List<ShopProductVo>> queryHotsProductList() {
|
||||
List<ShopProductVo> list = uProductService.queryHotsProductList();
|
||||
Long shopId = StpKit.USER.getShopId(0L);
|
||||
List<ShopProductVo> list = uProductService.queryHotsProductList(shopId);
|
||||
return CzgResult.success(list);
|
||||
}
|
||||
|
||||
|
|
@ -45,7 +47,8 @@ public class UProductController {
|
|||
*/
|
||||
@GetMapping("/miniApp/group/query")
|
||||
public CzgResult<List<ShopGroupProductVo>> queryGroupProductList() {
|
||||
List<ShopGroupProductVo> list = uProductService.queryGroupProductList();
|
||||
Long shopId = StpKit.USER.getShopId(0L);
|
||||
List<ShopGroupProductVo> list = uProductService.queryGroupProductList(shopId);
|
||||
return CzgResult.success(list);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package com.czg.product.param;
|
||||
|
||||
import com.alibaba.fastjson2.annotation.JSONField;
|
||||
import com.czg.validator.group.DefaultGroup;
|
||||
import jakarta.validation.constraints.Max;
|
||||
import jakarta.validation.constraints.Min;
|
||||
|
|
@ -34,4 +35,11 @@ public class ProdRefundToStockParam implements Serializable {
|
|||
@Min(value = 0, message = "是否退回库存值必须是0或1", groups = DefaultGroup.class)
|
||||
@Max(value = 1, message = "是否退回库存值必须是0或1", groups = DefaultGroup.class)
|
||||
private Integer isReturn;
|
||||
|
||||
/**
|
||||
* 店铺id
|
||||
*/
|
||||
@JSONField(serialize = false)
|
||||
private Long shopId;
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package com.czg.product.param;
|
||||
|
||||
import com.alibaba.fastjson2.annotation.JSONField;
|
||||
import com.czg.validator.group.DefaultGroup;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
|
|
@ -39,4 +40,10 @@ public class ProductIsSaleParam implements Serializable {
|
|||
@NotNull(message = "是否上下架不能为空", groups = DefaultGroup.class)
|
||||
private Integer isSale;
|
||||
|
||||
/**
|
||||
* 店铺id
|
||||
*/
|
||||
@JSONField(serialize = false)
|
||||
private Long shopId;
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package com.czg.product.param;
|
||||
|
||||
import com.alibaba.fastjson2.annotation.JSONField;
|
||||
import com.czg.validator.group.DefaultGroup;
|
||||
import jakarta.validation.constraints.Max;
|
||||
import jakarta.validation.constraints.Min;
|
||||
|
|
@ -43,4 +44,10 @@ public class ProductIsSoldOutParam implements Serializable {
|
|||
@Max(value = 1, message = "是否售罄必须是0或1", groups = DefaultGroup.class)
|
||||
private Integer isSoldOut;
|
||||
|
||||
/**
|
||||
* 店铺id
|
||||
*/
|
||||
@JSONField(serialize = false)
|
||||
private Long shopId;
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,16 +14,18 @@ public interface ProductRpcService {
|
|||
/**
|
||||
* 订单支付成功扣减库存
|
||||
*
|
||||
* @param shopId 店铺ID
|
||||
* @param orderId 订单ID
|
||||
* @param dataList 库存扣减数据
|
||||
*/
|
||||
void paySuccessSubtractStock(Long orderId, List<Map<String, Object>> dataList);
|
||||
void paySuccessSubtractStock(Long shopId, Long orderId, List<Map<String, Object>> dataList);
|
||||
|
||||
/**
|
||||
* 订单取消后恢复库存
|
||||
*
|
||||
* @param shopId 店铺id
|
||||
* @param orderId 订单ID
|
||||
* @param dataList 库存恢复数据
|
||||
*/
|
||||
void orderCancelRecoverStock(Long orderId, List<Map<String, Object>> dataList);
|
||||
void orderCancelRecoverStock(Long shopId, Long orderId, List<Map<String, Object>> dataList);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -58,9 +58,10 @@ public interface ProductService extends IService<Product> {
|
|||
/**
|
||||
* 删除商品
|
||||
*
|
||||
* @param shopId 店铺ID
|
||||
* @param id 商品ID
|
||||
*/
|
||||
void deleteProduct(Long id);
|
||||
void deleteProduct(Long shopId, Long id);
|
||||
|
||||
/**
|
||||
* 上架/下架商品
|
||||
|
|
|
|||
|
|
@ -20,15 +20,17 @@ public interface UProductService extends IService<Product> {
|
|||
/**
|
||||
* 用户端获取热门商品
|
||||
*
|
||||
* @param shopId 店铺ID
|
||||
* @return 热门商品
|
||||
*/
|
||||
List<ShopProductVo> queryHotsProductList();
|
||||
List<ShopProductVo> queryHotsProductList(Long shopId);
|
||||
|
||||
/**
|
||||
* 用户端获取分组商品
|
||||
* @param shopId 店铺ID
|
||||
* @return 分组商品
|
||||
*/
|
||||
List<ShopGroupProductVo> queryGroupProductList();
|
||||
List<ShopGroupProductVo> queryGroupProductList(Long shopId);
|
||||
|
||||
/**
|
||||
* 用户端获取商品详情
|
||||
|
|
|
|||
|
|
@ -0,0 +1,22 @@
|
|||
package com.czg.constant;
|
||||
|
||||
/**
|
||||
* 缓存的key 常量
|
||||
*
|
||||
* @author tankaikai
|
||||
* @since 2025-03-01 16:59
|
||||
*/
|
||||
public interface CacheConstant {
|
||||
/**
|
||||
* 用户端商品信息
|
||||
*/
|
||||
String USER_CLIENT_PRODUCT_INFO = "user_client_product_info:";
|
||||
/**
|
||||
* 热销商品
|
||||
*/
|
||||
String USER_CLIENT_HOTS_PRODUCT = USER_CLIENT_PRODUCT_INFO + "hots";
|
||||
/**
|
||||
* 分组商品
|
||||
*/
|
||||
String USER_CLIENT_GROUPS_PRODUCT = USER_CLIENT_PRODUCT_INFO + "groups";
|
||||
}
|
||||
|
|
@ -112,8 +112,6 @@ public class OrderInfoRpcServiceImpl implements OrderInfoRpcService {
|
|||
}
|
||||
|
||||
@Override
|
||||
@GlobalTransactional
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void paySuccessCallback(Long orderId) {
|
||||
// 下单后商品库存扣减,耗材扣减,流水记录
|
||||
OrderInfo orderInfo = orderInfoMapper.selectOneById(orderId);
|
||||
|
|
@ -139,7 +137,7 @@ public class OrderInfoRpcServiceImpl implements OrderInfoRpcService {
|
|||
dataList.add(data);
|
||||
}
|
||||
// 调用商品服务扣减库存
|
||||
productRpcService.paySuccessSubtractStock(orderId, dataList);
|
||||
productRpcService.paySuccessSubtractStock(shopId, orderId, dataList);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -170,7 +168,7 @@ public class OrderInfoRpcServiceImpl implements OrderInfoRpcService {
|
|||
dataList.add(data);
|
||||
}
|
||||
// 调用商品服务恢复库存
|
||||
productRpcService.orderCancelRecoverStock(orderId, dataList);
|
||||
productRpcService.orderCancelRecoverStock(shopId, orderId, dataList);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package com.czg.service.product.service.impl;
|
|||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.util.NumberUtil;
|
||||
import com.czg.constant.CacheConstant;
|
||||
import com.czg.product.dto.ProductStockSubtractDTO;
|
||||
import com.czg.product.entity.ConsInfo;
|
||||
import com.czg.product.entity.ConsStockFlow;
|
||||
|
|
@ -18,6 +19,7 @@ import com.czg.service.product.mapper.ProductMapper;
|
|||
import com.mybatisflex.core.query.QueryWrapper;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.apache.dubbo.config.annotation.DubboService;
|
||||
import org.springframework.cache.annotation.CacheEvict;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
|
|
@ -50,7 +52,8 @@ public class ProductRpcServiceImpl implements ProductRpcService {
|
|||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void paySuccessSubtractStock(Long orderId, List<Map<String, Object>> dataList) {
|
||||
@CacheEvict(value = {CacheConstant.USER_CLIENT_HOTS_PRODUCT, CacheConstant.USER_CLIENT_GROUPS_PRODUCT}, key = "#shopId", allEntries = true, beforeInvocation = true)
|
||||
public void paySuccessSubtractStock(Long shopId, Long orderId, List<Map<String, Object>> dataList) {
|
||||
List<ProductStockSubtractDTO> list = BeanUtil.copyToList(dataList, ProductStockSubtractDTO.class);
|
||||
if (CollUtil.isEmpty(list)) {
|
||||
return;
|
||||
|
|
@ -81,7 +84,6 @@ public class ProductRpcServiceImpl implements ProductRpcService {
|
|||
// 更新耗材库存数量
|
||||
consInfoMapper.update(consInfo);
|
||||
// 插入耗材流水记录
|
||||
Long shopId = consInfo.getShopId();
|
||||
ConsStockFlow consStockFlow = new ConsStockFlow();
|
||||
consStockFlow.setShopId(shopId);
|
||||
consStockFlow.setVendorId(null);
|
||||
|
|
@ -109,7 +111,8 @@ public class ProductRpcServiceImpl implements ProductRpcService {
|
|||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void orderCancelRecoverStock(Long orderId, List<Map<String, Object>> dataList) {
|
||||
@CacheEvict(value = {CacheConstant.USER_CLIENT_HOTS_PRODUCT, CacheConstant.USER_CLIENT_GROUPS_PRODUCT}, key = "#shopId", allEntries = true, beforeInvocation = true)
|
||||
public void orderCancelRecoverStock(Long shopId, Long orderId, List<Map<String, Object>> dataList) {
|
||||
List<ProductStockSubtractDTO> list = BeanUtil.copyToList(dataList, ProductStockSubtractDTO.class);
|
||||
if (CollUtil.isEmpty(list)) {
|
||||
return;
|
||||
|
|
@ -140,7 +143,6 @@ public class ProductRpcServiceImpl implements ProductRpcService {
|
|||
// 更新耗材库存数量
|
||||
consInfoMapper.update(consInfo);
|
||||
// 插入耗材流水记录
|
||||
Long shopId = consInfo.getShopId();
|
||||
ConsStockFlow consStockFlow = new ConsStockFlow();
|
||||
consStockFlow.setShopId(shopId);
|
||||
consStockFlow.setInOutType(InOutTypeEnum.IN.value());
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import cn.hutool.core.util.ObjUtil;
|
|||
import cn.hutool.core.util.StrUtil;
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.alibaba.fastjson2.JSONWriter;
|
||||
import com.czg.constant.CacheConstant;
|
||||
import com.czg.enums.DeleteEnum;
|
||||
import com.czg.enums.YesNoEnum;
|
||||
import com.czg.exception.CzgException;
|
||||
|
|
@ -37,6 +38,7 @@ import com.mybatisflex.spring.service.impl.ServiceImpl;
|
|||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.dubbo.config.annotation.DubboService;
|
||||
import org.springframework.cache.annotation.CacheEvict;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
|
|
@ -171,6 +173,7 @@ public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> impl
|
|||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@CacheEvict(value = {CacheConstant.USER_CLIENT_HOTS_PRODUCT, CacheConstant.USER_CLIENT_GROUPS_PRODUCT}, key = "#dto.shopId", allEntries = true)
|
||||
public void addProduct(ProductDTO dto) {
|
||||
Long shopId = StpKit.USER.getShopId(0L);
|
||||
boolean exists = super.exists(query().eq(Product::getName, dto.getName()).eq(Product::getShopId, shopId));
|
||||
|
|
@ -210,6 +213,7 @@ public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> impl
|
|||
}
|
||||
|
||||
@Override
|
||||
@CacheEvict(value = {CacheConstant.USER_CLIENT_HOTS_PRODUCT, CacheConstant.USER_CLIENT_GROUPS_PRODUCT}, key = "#dto.shopId", allEntries = true)
|
||||
public void updateProduct(ProductDTO dto) {
|
||||
Long shopId = StpKit.USER.getShopId(0L);
|
||||
dto.setShopId(shopId);
|
||||
|
|
@ -264,8 +268,8 @@ public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> impl
|
|||
}
|
||||
|
||||
@Override
|
||||
public void deleteProduct(Long id) {
|
||||
Long shopId = StpKit.USER.getShopId(0L);
|
||||
@CacheEvict(value = {CacheConstant.USER_CLIENT_HOTS_PRODUCT, CacheConstant.USER_CLIENT_GROUPS_PRODUCT}, key = "#shopId", allEntries = true)
|
||||
public void deleteProduct(Long shopId, Long id) {
|
||||
UpdateChain.of(Product.class)
|
||||
.set(Product::getIsDel, DeleteEnum.DELETED.value())
|
||||
.eq(Product::getId, id)
|
||||
|
|
@ -275,6 +279,7 @@ public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> impl
|
|||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@CacheEvict(value = {CacheConstant.USER_CLIENT_HOTS_PRODUCT, CacheConstant.USER_CLIENT_GROUPS_PRODUCT}, key = "#param.shopId", allEntries = true, beforeInvocation = true)
|
||||
public void onOffProduct(ProductIsSaleParam param) {
|
||||
Long shopId = StpKit.USER.getShopId(0L);
|
||||
String type = param.getType();
|
||||
|
|
@ -296,6 +301,7 @@ public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> impl
|
|||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@CacheEvict(value = {CacheConstant.USER_CLIENT_HOTS_PRODUCT, CacheConstant.USER_CLIENT_GROUPS_PRODUCT}, key = "#param.shopId", allEntries = true, beforeInvocation = true)
|
||||
public void markProductIsSoldOut(ProductIsSoldOutParam param) {
|
||||
Long shopId = StpKit.USER.getShopId(0L);
|
||||
String type = param.getType();
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package com.czg.service.product.service.impl;
|
|||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.util.ObjUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.czg.constant.CacheConstant;
|
||||
import com.czg.enums.DeleteEnum;
|
||||
import com.czg.enums.StatusEnum;
|
||||
import com.czg.enums.YesNoEnum;
|
||||
|
|
@ -26,6 +27,7 @@ import com.czg.service.product.mapper.ProductMapper;
|
|||
import com.mybatisflex.spring.service.impl.ServiceImpl;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.time.DayOfWeek;
|
||||
|
|
@ -55,8 +57,8 @@ public class UProductServiceImpl extends ServiceImpl<ProductMapper, Product> imp
|
|||
private final ProdGroupRelationMapper prodGroupRelationMapper;
|
||||
|
||||
@Override
|
||||
public List<ShopProductVo> queryHotsProductList() {
|
||||
Long shopId = StpKit.USER.getShopId(0L);
|
||||
@Cacheable(value = CacheConstant.USER_CLIENT_HOTS_PRODUCT, key = "#shopId", unless = "#result.isEmpty()")
|
||||
public List<ShopProductVo> queryHotsProductList(Long shopId) {
|
||||
List<ShopProductVo> list = productMapper.selectHotsProductList(shopId);
|
||||
list.forEach(item -> {
|
||||
item.setIsSaleTime(calcIsSaleTime(item.getDays(), item.getStartTime(), item.getEndTime()));
|
||||
|
|
@ -67,8 +69,8 @@ public class UProductServiceImpl extends ServiceImpl<ProductMapper, Product> imp
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<ShopGroupProductVo> queryGroupProductList() {
|
||||
Long shopId = StpKit.USER.getShopId(0L);
|
||||
@Cacheable(value = CacheConstant.USER_CLIENT_GROUPS_PRODUCT, key = "#shopId", unless = "#result.isEmpty()")
|
||||
public List<ShopGroupProductVo> queryGroupProductList(Long shopId) {
|
||||
List<ShopGroupProductVo> groupList = prodGroupMapper.selectListByQueryAs(query().select(ProdGroup::getId, ProdGroup::getName).eq(ProdGroup::getShopId, shopId).eq(ProdGroup::getStatus, StatusEnum.ENABLED.value()).orderBy(ProdGroup::getSort, true), ShopGroupProductVo.class);
|
||||
List<ShopProductVo> productAllList = productMapper.selectGroupProductList(shopId);
|
||||
productAllList.forEach(item -> {
|
||||
|
|
|
|||
Loading…
Reference in New Issue