diff --git a/xjs-business/xjs-business-common/src/main/java/com/xjs/consts/RedisConst.java b/xjs-business/xjs-business-common/src/main/java/com/xjs/consts/RedisConst.java index 342e20c4..7ea12ed0 100644 --- a/xjs-business/xjs-business-common/src/main/java/com/xjs/consts/RedisConst.java +++ b/xjs-business/xjs-business-common/src/main/java/com/xjs/consts/RedisConst.java @@ -8,7 +8,7 @@ package com.xjs.consts; */ public class RedisConst { - //----------------------key------------------------ + //----------------------bussiness-key------------------------ /** * 翻译字典常量key @@ -59,7 +59,25 @@ public class RedisConst { * 爬虫记录循环次数常量信息:weixin.link */ public static final String REPTILE_WEIXIN_LINK_COUNT = "reptile:weixin.link.count"; - ; + + + //--------------------------mall-key----------------------------------- + + /** + * mallKey前缀 + */ + public static final String MALL_PREFIX = "mall:"; + + /** + * 三级分类后台key + */ + public static final String CATALOG_AFTER = MALL_PREFIX + "catalog:after"; + + /** + * 三级分类前台key + */ + public static final String CATALOG_BEFORE = MALL_PREFIX + "catalog:before"; + //-------------------有效时间----------------------- public static final Integer TRAN_DICT_EXPIRE = 1; //小时 diff --git a/xjs-business/xjs-project-mall/mall-product/src/main/java/com/xjs/mall/product/controller/CategoryController.java b/xjs-business/xjs-project-mall/mall-product/src/main/java/com/xjs/mall/product/controller/CategoryController.java index e0ff60c5..46f3096b 100644 --- a/xjs-business/xjs-project-mall/mall-product/src/main/java/com/xjs/mall/product/controller/CategoryController.java +++ b/xjs-business/xjs-project-mall/mall-product/src/main/java/com/xjs/mall/product/controller/CategoryController.java @@ -10,12 +10,16 @@ import com.xjs.validation.group.UpdateGroup; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import java.util.Arrays; import java.util.List; +import static com.xjs.consts.RedisConst.CATALOG_AFTER; +import static com.xjs.consts.RedisConst.CATALOG_BEFORE; + /** * 商品三级分类 @@ -30,6 +34,8 @@ import java.util.List; public class CategoryController { @Autowired private CategoryService categoryService; + @Autowired + private StringRedisTemplate stringRedisTemplate; /** * 列表--树形结构 @@ -84,6 +90,8 @@ public class CategoryController { @Log(title = "商品分类", businessType = BusinessType.UPDATE) public R updateSort(@RequestBody CategoryEntity[] categoryEntities) { categoryService.updateBatchById(Arrays.asList(categoryEntities)); + //删除缓存 + stringRedisTemplate.delete(Arrays.asList(CATALOG_BEFORE,CATALOG_AFTER)); return R.ok(); } diff --git a/xjs-business/xjs-project-mall/mall-product/src/main/java/com/xjs/mall/product/controller/web/IndexController.java b/xjs-business/xjs-project-mall/mall-product/src/main/java/com/xjs/mall/product/controller/web/IndexController.java index ea90d411..2336ac44 100644 --- a/xjs-business/xjs-project-mall/mall-product/src/main/java/com/xjs/mall/product/controller/web/IndexController.java +++ b/xjs-business/xjs-project-mall/mall-product/src/main/java/com/xjs/mall/product/controller/web/IndexController.java @@ -3,8 +3,6 @@ package com.xjs.mall.product.controller.web; import com.xjs.mall.product.entity.CategoryEntity; import com.xjs.mall.product.service.CategoryService; import com.xjs.mall.product.vo.Catelog2Vo; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; @@ -15,13 +13,12 @@ import java.util.List; import java.util.Map; /** - * 首页控制器 + * 商城-商品首页控制器 * * @author xiejs * @since 2022-04-07 */ @Controller -@Api(tags = "商城-商品-首页") public class IndexController { @Autowired @@ -37,7 +34,6 @@ public class IndexController { @GetMapping("/index/json/catalog.json") @ResponseBody - @ApiOperation("获取三级分类") public Map> getCatalogJson() { return categoryService.getCatalogJson(); } diff --git a/xjs-business/xjs-project-mall/mall-product/src/main/java/com/xjs/mall/product/service/impl/CategoryServiceImpl.java b/xjs-business/xjs-project-mall/mall-product/src/main/java/com/xjs/mall/product/service/impl/CategoryServiceImpl.java index d7689906..21125d57 100644 --- a/xjs-business/xjs-project-mall/mall-product/src/main/java/com/xjs/mall/product/service/impl/CategoryServiceImpl.java +++ b/xjs-business/xjs-project-mall/mall-product/src/main/java/com/xjs/mall/product/service/impl/CategoryServiceImpl.java @@ -1,13 +1,24 @@ package com.xjs.mall.product.service.impl; +import cn.hutool.core.collection.CollUtil; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.TypeReference; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.ruoyi.common.core.utils.StringUtils; +import com.xjs.exception.MallException; import com.xjs.mall.product.dao.CategoryDao; +import com.xjs.mall.product.entity.AttrEntity; +import com.xjs.mall.product.entity.AttrGroupEntity; +import com.xjs.mall.product.entity.CategoryBrandRelationEntity; import com.xjs.mall.product.entity.CategoryEntity; +import com.xjs.mall.product.service.AttrGroupService; +import com.xjs.mall.product.service.AttrService; import com.xjs.mall.product.service.CategoryBrandRelationService; import com.xjs.mall.product.service.CategoryService; import com.xjs.mall.product.vo.Catelog2Vo; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -15,6 +26,9 @@ import javax.annotation.Resource; import java.util.*; import java.util.stream.Collectors; +import static com.xjs.consts.RedisConst.CATALOG_AFTER; +import static com.xjs.consts.RedisConst.CATALOG_BEFORE; + @Service("categoryService") @Transactional @@ -26,26 +40,78 @@ public class CategoryServiceImpl extends ServiceImpl listWithTree() { - //1、查询所有分类 - List entities = categoryDao.selectList(null); + //查缓存 + String cache = stringRedisTemplate.opsForValue().get(CATALOG_AFTER); + + if (StringUtils.isEmpty(cache)) { + //1、查询所有分类 + List entities = categoryDao.selectList(null); + + //2、找到所有一级分类 + List collect = entities.stream() + .filter(categoryEntity -> categoryEntity.getParentCid() == 0) + .peek(menu -> menu.setChildren(this.getChildrens(menu, entities))) + .sorted(Comparator.comparingInt(menu -> (menu.getSort() == null ? 0 : menu.getSort()))) + .collect(Collectors.toList()); + + //存入缓存 + String jsonString = JSON.toJSONString(collect); + stringRedisTemplate.opsForValue().set(CATALOG_AFTER, jsonString); - //2、找到所有一级分类 - return entities.stream().filter(categoryEntity -> - categoryEntity.getParentCid() == 0) - .peek(menu -> menu.setChildren(this.getChildrens(menu, entities))) - .sorted(Comparator.comparingInt(menu -> (menu.getSort() == null ? 0 : menu.getSort()))) - .collect(Collectors.toList()); + return collect; + } else { + return JSON.parseObject(cache, new TypeReference>() { + }); + } } @Override public void removeMenuByIds(List asList) { - // todo 检查当前要删除的菜单是否被其他的地方引用 + //检查当前要删除的菜单是否被其他的地方引用 + + for (Long id : asList) { + // 1、品牌关联 + LambdaQueryWrapper wrapperBrand = new LambdaQueryWrapper() + .eq(CategoryBrandRelationEntity::getCatelogId, id); + List relationEntityList = categoryBrandRelationService.list(wrapperBrand); + if (CollUtil.isNotEmpty(relationEntityList)) { + throw new MallException("请先删除关联品牌信息"); + } + + // 2、属性分组关联 + LambdaQueryWrapper wrapperAttrGroup = new LambdaQueryWrapper() + .eq(AttrGroupEntity::getCatelogId, id); + List groupEntityList = attrGroupService.list(wrapperAttrGroup); + if (CollUtil.isNotEmpty(groupEntityList)) { + throw new MallException("请先删除关联属性分组信息"); + } + + // 3、销售属性/规格参数 + LambdaQueryWrapper wrapperAttr = new LambdaQueryWrapper() + .eq(AttrEntity::getCatelogId, id); + List attrEntityList = attrService.list(wrapperAttr); + if (CollUtil.isNotEmpty(attrEntityList)) { + throw new MallException("请先删除关联销售属性/规格参数信息"); + } + } categoryDao.deleteBatchIds(asList); + + //删除后清除缓存 + stringRedisTemplate.delete(Arrays.asList(CATALOG_BEFORE,CATALOG_AFTER)); } @Override @@ -66,6 +132,9 @@ public class CategoryServiceImpl extends ServiceImpl> getCatalogJson() { + //先查缓存 + String catalogJSON = stringRedisTemplate.opsForValue().get(CATALOG_BEFORE); + if (StringUtils.isEmpty(catalogJSON)) { + //缓存没有查数据库并且放入 + Map> catalogJsonFormDb = this.getCatalogJsonFormDb(); + String jsonString = JSON.toJSONString(catalogJsonFormDb); + stringRedisTemplate.opsForValue().set(CATALOG_BEFORE, jsonString); + return catalogJsonFormDb; + } else { + return JSON.parseObject(catalogJSON, new TypeReference>>() { + }); + } + + } + + //可优化 + private Map> getCatalogJsonFormDb() { //查出所有1级分类 List level1Categorys = getLevel1Categorys(); //封装数据 - return level1Categorys.stream().collect(Collectors.toMap( - k -> k.getCatId().toString(), - v -> { - //每一个的一级分类,查到这个一级分类的二级分类 - List categoryEntities = super.baseMapper.selectList(new LambdaQueryWrapper().eq(CategoryEntity::getParentCid, v.getCatId())); - - //封装上面的结果 - List catelog2Vos = null; - if (categoryEntities != null) { - catelog2Vos = categoryEntities.stream().map(l2 -> { - Catelog2Vo catelog2Vo = new Catelog2Vo(v.getCatId().toString(), null, l2.getCatId().toString(), l2.getName()); - - // 找当前二级分类的三级分类封装成vo - List level3Catelog = super.baseMapper.selectList(new LambdaQueryWrapper().eq(CategoryEntity::getParentCid, l2.getCatId())); - if (level3Catelog != null) { - - List catelog3Vos = level3Catelog.stream().map(l3 -> { - //封装成指定格式 - return new Catelog2Vo.Catelog3Vo(l2.getCatId().toString(), l3.getCatId().toString(), l3.getName()); - }).collect(Collectors.toList()); - - catelog2Vo.setCatalog3List(catelog3Vos); - } - - return catelog2Vo; + return level1Categorys.stream().collect(Collectors.toMap(k -> k.getCatId().toString(), v -> { + //每一个的一级分类,查到这个一级分类的二级分类 + List categoryEntities = super.baseMapper.selectList(new LambdaQueryWrapper().eq(CategoryEntity::getParentCid, v.getCatId())); + + //封装上面的结果 + List catelog2Vos = null; + if (categoryEntities != null) { + catelog2Vos = categoryEntities.stream().map(l2 -> { + Catelog2Vo catelog2Vo = new Catelog2Vo(v.getCatId().toString(), null, l2.getCatId().toString(), l2.getName()); + + // 找当前二级分类的三级分类封装成vo + List level3Catelog = super.baseMapper.selectList(new LambdaQueryWrapper().eq(CategoryEntity::getParentCid, l2.getCatId())); + if (level3Catelog != null) { + + List catelog3Vos = level3Catelog.stream().map(l3 -> { + //封装成指定格式 + return new Catelog2Vo.Catelog3Vo(l2.getCatId().toString(), l3.getCatId().toString(), l3.getName()); }).collect(Collectors.toList()); + + catelog2Vo.setCatalog3List(catelog3Vos); } - return catelog2Vos; - } - )); + return catelog2Vo; + }).collect(Collectors.toList()); + } + + return catelog2Vos; + })); } //225,25,2 @@ -139,10 +222,7 @@ public class CategoryServiceImpl extends ServiceImpl Objects.equals(categoryEntity.getParentCid(), root.getCatId())) - .peek(categoryEntity -> categoryEntity.setChildren(getChildrens(categoryEntity, all))) - .sorted(Comparator.comparingInt(menu -> (menu.getSort() == null ? 0 : menu.getSort()))) - .collect(Collectors.toList()); + return all.stream().filter(categoryEntity -> Objects.equals(categoryEntity.getParentCid(), root.getCatId())).peek(categoryEntity -> categoryEntity.setChildren(getChildrens(categoryEntity, all))).sorted(Comparator.comparingInt(menu -> (menu.getSort() == null ? 0 : menu.getSort()))).collect(Collectors.toList()); } diff --git a/xjs-business/xjs-project-mall/mall-product/src/main/resources/templates/index.html b/xjs-business/xjs-project-mall/mall-product/src/main/resources/templates/index.html index d9efa394..c17bb6e7 100644 --- a/xjs-business/xjs-project-mall/mall-product/src/main/resources/templates/index.html +++ b/xjs-business/xjs-project-mall/mall-product/src/main/resources/templates/index.html @@ -619,7 +619,7 @@ - +