1、商城项目商品服务三级分类缓存优化
This commit is contained in:
parent
09132426e4
commit
7495a0eca1
|
|
@ -8,7 +8,7 @@ package com.xjs.consts;
|
||||||
*/
|
*/
|
||||||
public class RedisConst {
|
public class RedisConst {
|
||||||
|
|
||||||
//----------------------key------------------------
|
//----------------------bussiness-key------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 翻译字典常量key
|
* 翻译字典常量key
|
||||||
|
|
@ -59,7 +59,25 @@ public class RedisConst {
|
||||||
* 爬虫记录循环次数常量信息:weixin.link
|
* 爬虫记录循环次数常量信息:weixin.link
|
||||||
*/
|
*/
|
||||||
public static final String REPTILE_WEIXIN_LINK_COUNT = "reptile:weixin.link.count";
|
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; //小时
|
public static final Integer TRAN_DICT_EXPIRE = 1; //小时
|
||||||
|
|
|
||||||
|
|
@ -10,12 +10,16 @@ import com.xjs.validation.group.UpdateGroup;
|
||||||
import io.swagger.annotations.Api;
|
import io.swagger.annotations.Api;
|
||||||
import io.swagger.annotations.ApiOperation;
|
import io.swagger.annotations.ApiOperation;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
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 {
|
public class CategoryController {
|
||||||
@Autowired
|
@Autowired
|
||||||
private CategoryService categoryService;
|
private CategoryService categoryService;
|
||||||
|
@Autowired
|
||||||
|
private StringRedisTemplate stringRedisTemplate;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 列表--树形结构
|
* 列表--树形结构
|
||||||
|
|
@ -84,6 +90,8 @@ public class CategoryController {
|
||||||
@Log(title = "商品分类", businessType = BusinessType.UPDATE)
|
@Log(title = "商品分类", businessType = BusinessType.UPDATE)
|
||||||
public R updateSort(@RequestBody CategoryEntity[] categoryEntities) {
|
public R updateSort(@RequestBody CategoryEntity[] categoryEntities) {
|
||||||
categoryService.updateBatchById(Arrays.asList(categoryEntities));
|
categoryService.updateBatchById(Arrays.asList(categoryEntities));
|
||||||
|
//删除缓存
|
||||||
|
stringRedisTemplate.delete(Arrays.asList(CATALOG_BEFORE,CATALOG_AFTER));
|
||||||
return R.ok();
|
return R.ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,6 @@ package com.xjs.mall.product.controller.web;
|
||||||
import com.xjs.mall.product.entity.CategoryEntity;
|
import com.xjs.mall.product.entity.CategoryEntity;
|
||||||
import com.xjs.mall.product.service.CategoryService;
|
import com.xjs.mall.product.service.CategoryService;
|
||||||
import com.xjs.mall.product.vo.Catelog2Vo;
|
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.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
import org.springframework.ui.Model;
|
import org.springframework.ui.Model;
|
||||||
|
|
@ -15,13 +13,12 @@ import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 首页控制器
|
* 商城-商品首页控制器
|
||||||
*
|
*
|
||||||
* @author xiejs
|
* @author xiejs
|
||||||
* @since 2022-04-07
|
* @since 2022-04-07
|
||||||
*/
|
*/
|
||||||
@Controller
|
@Controller
|
||||||
@Api(tags = "商城-商品-首页")
|
|
||||||
public class IndexController {
|
public class IndexController {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
|
|
@ -37,7 +34,6 @@ public class IndexController {
|
||||||
|
|
||||||
@GetMapping("/index/json/catalog.json")
|
@GetMapping("/index/json/catalog.json")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
@ApiOperation("获取三级分类")
|
|
||||||
public Map<String,List<Catelog2Vo>> getCatalogJson() {
|
public Map<String,List<Catelog2Vo>> getCatalogJson() {
|
||||||
return categoryService.getCatalogJson();
|
return categoryService.getCatalogJson();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,24 @@
|
||||||
package com.xjs.mall.product.service.impl;
|
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.core.conditions.query.LambdaQueryWrapper;
|
||||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
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.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.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.CategoryBrandRelationService;
|
||||||
import com.xjs.mall.product.service.CategoryService;
|
import com.xjs.mall.product.service.CategoryService;
|
||||||
import com.xjs.mall.product.vo.Catelog2Vo;
|
import com.xjs.mall.product.vo.Catelog2Vo;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
|
@ -15,6 +26,9 @@ import javax.annotation.Resource;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import static com.xjs.consts.RedisConst.CATALOG_AFTER;
|
||||||
|
import static com.xjs.consts.RedisConst.CATALOG_BEFORE;
|
||||||
|
|
||||||
|
|
||||||
@Service("categoryService")
|
@Service("categoryService")
|
||||||
@Transactional
|
@Transactional
|
||||||
|
|
@ -26,26 +40,78 @@ public class CategoryServiceImpl extends ServiceImpl<CategoryDao, CategoryEntity
|
||||||
@Autowired
|
@Autowired
|
||||||
private CategoryBrandRelationService categoryBrandRelationService;
|
private CategoryBrandRelationService categoryBrandRelationService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private StringRedisTemplate stringRedisTemplate;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private AttrGroupService attrGroupService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private AttrService attrService;
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<CategoryEntity> listWithTree() {
|
public List<CategoryEntity> listWithTree() {
|
||||||
|
//查缓存
|
||||||
|
String cache = stringRedisTemplate.opsForValue().get(CATALOG_AFTER);
|
||||||
|
|
||||||
|
if (StringUtils.isEmpty(cache)) {
|
||||||
//1、查询所有分类
|
//1、查询所有分类
|
||||||
List<CategoryEntity> entities = categoryDao.selectList(null);
|
List<CategoryEntity> entities = categoryDao.selectList(null);
|
||||||
|
|
||||||
//2、找到所有一级分类
|
//2、找到所有一级分类
|
||||||
return entities.stream().filter(categoryEntity ->
|
List<CategoryEntity> collect = entities.stream()
|
||||||
categoryEntity.getParentCid() == 0)
|
.filter(categoryEntity -> categoryEntity.getParentCid() == 0)
|
||||||
.peek(menu -> menu.setChildren(this.getChildrens(menu, entities)))
|
.peek(menu -> menu.setChildren(this.getChildrens(menu, entities)))
|
||||||
.sorted(Comparator.comparingInt(menu -> (menu.getSort() == null ? 0 : menu.getSort())))
|
.sorted(Comparator.comparingInt(menu -> (menu.getSort() == null ? 0 : menu.getSort())))
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
//存入缓存
|
||||||
|
String jsonString = JSON.toJSONString(collect);
|
||||||
|
stringRedisTemplate.opsForValue().set(CATALOG_AFTER, jsonString);
|
||||||
|
|
||||||
|
return collect;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
return JSON.parseObject(cache, new TypeReference<List<CategoryEntity>>() {
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removeMenuByIds(List<Long> asList) {
|
public void removeMenuByIds(List<Long> asList) {
|
||||||
// todo 检查当前要删除的菜单是否被其他的地方引用
|
//检查当前要删除的菜单是否被其他的地方引用
|
||||||
|
|
||||||
|
for (Long id : asList) {
|
||||||
|
// 1、品牌关联
|
||||||
|
LambdaQueryWrapper<CategoryBrandRelationEntity> wrapperBrand = new LambdaQueryWrapper<CategoryBrandRelationEntity>()
|
||||||
|
.eq(CategoryBrandRelationEntity::getCatelogId, id);
|
||||||
|
List<CategoryBrandRelationEntity> relationEntityList = categoryBrandRelationService.list(wrapperBrand);
|
||||||
|
if (CollUtil.isNotEmpty(relationEntityList)) {
|
||||||
|
throw new MallException("请先删除关联品牌信息");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2、属性分组关联
|
||||||
|
LambdaQueryWrapper<AttrGroupEntity> wrapperAttrGroup = new LambdaQueryWrapper<AttrGroupEntity>()
|
||||||
|
.eq(AttrGroupEntity::getCatelogId, id);
|
||||||
|
List<AttrGroupEntity> groupEntityList = attrGroupService.list(wrapperAttrGroup);
|
||||||
|
if (CollUtil.isNotEmpty(groupEntityList)) {
|
||||||
|
throw new MallException("请先删除关联属性分组信息");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3、销售属性/规格参数
|
||||||
|
LambdaQueryWrapper<AttrEntity> wrapperAttr = new LambdaQueryWrapper<AttrEntity>()
|
||||||
|
.eq(AttrEntity::getCatelogId, id);
|
||||||
|
List<AttrEntity> attrEntityList = attrService.list(wrapperAttr);
|
||||||
|
if (CollUtil.isNotEmpty(attrEntityList)) {
|
||||||
|
throw new MallException("请先删除关联销售属性/规格参数信息");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
categoryDao.deleteBatchIds(asList);
|
categoryDao.deleteBatchIds(asList);
|
||||||
|
|
||||||
|
//删除后清除缓存
|
||||||
|
stringRedisTemplate.delete(Arrays.asList(CATALOG_BEFORE,CATALOG_AFTER));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -66,6 +132,9 @@ public class CategoryServiceImpl extends ServiceImpl<CategoryDao, CategoryEntity
|
||||||
|
|
||||||
//更新关联表
|
//更新关联表
|
||||||
categoryBrandRelationService.updateCategory(category.getCatId(), category.getName());
|
categoryBrandRelationService.updateCategory(category.getCatId(), category.getName());
|
||||||
|
|
||||||
|
//删除缓存
|
||||||
|
stringRedisTemplate.delete(Arrays.asList(CATALOG_BEFORE,CATALOG_AFTER));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -77,13 +146,28 @@ public class CategoryServiceImpl extends ServiceImpl<CategoryDao, CategoryEntity
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<String, List<Catelog2Vo>> getCatalogJson() {
|
public Map<String, List<Catelog2Vo>> getCatalogJson() {
|
||||||
|
//先查缓存
|
||||||
|
String catalogJSON = stringRedisTemplate.opsForValue().get(CATALOG_BEFORE);
|
||||||
|
if (StringUtils.isEmpty(catalogJSON)) {
|
||||||
|
//缓存没有查数据库并且放入
|
||||||
|
Map<String, List<Catelog2Vo>> catalogJsonFormDb = this.getCatalogJsonFormDb();
|
||||||
|
String jsonString = JSON.toJSONString(catalogJsonFormDb);
|
||||||
|
stringRedisTemplate.opsForValue().set(CATALOG_BEFORE, jsonString);
|
||||||
|
return catalogJsonFormDb;
|
||||||
|
} else {
|
||||||
|
return JSON.parseObject(catalogJSON, new TypeReference<Map<String, List<Catelog2Vo>>>() {
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//可优化
|
||||||
|
private Map<String, List<Catelog2Vo>> getCatalogJsonFormDb() {
|
||||||
//查出所有1级分类
|
//查出所有1级分类
|
||||||
List<CategoryEntity> level1Categorys = getLevel1Categorys();
|
List<CategoryEntity> level1Categorys = getLevel1Categorys();
|
||||||
|
|
||||||
//封装数据
|
//封装数据
|
||||||
return level1Categorys.stream().collect(Collectors.toMap(
|
return level1Categorys.stream().collect(Collectors.toMap(k -> k.getCatId().toString(), v -> {
|
||||||
k -> k.getCatId().toString(),
|
|
||||||
v -> {
|
|
||||||
//每一个的一级分类,查到这个一级分类的二级分类
|
//每一个的一级分类,查到这个一级分类的二级分类
|
||||||
List<CategoryEntity> categoryEntities = super.baseMapper.selectList(new LambdaQueryWrapper<CategoryEntity>().eq(CategoryEntity::getParentCid, v.getCatId()));
|
List<CategoryEntity> categoryEntities = super.baseMapper.selectList(new LambdaQueryWrapper<CategoryEntity>().eq(CategoryEntity::getParentCid, v.getCatId()));
|
||||||
|
|
||||||
|
|
@ -110,8 +194,7 @@ public class CategoryServiceImpl extends ServiceImpl<CategoryDao, CategoryEntity
|
||||||
}
|
}
|
||||||
|
|
||||||
return catelog2Vos;
|
return catelog2Vos;
|
||||||
}
|
}));
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//225,25,2
|
//225,25,2
|
||||||
|
|
@ -139,10 +222,7 @@ public class CategoryServiceImpl extends ServiceImpl<CategoryDao, CategoryEntity
|
||||||
//-----------peek和map区别---------------//
|
//-----------peek和map区别---------------//
|
||||||
//map有返回值,peek没有返回值
|
//map有返回值,peek没有返回值
|
||||||
|
|
||||||
return all.stream().filter(categoryEntity -> Objects.equals(categoryEntity.getParentCid(), root.getCatId()))
|
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());
|
||||||
.peek(categoryEntity -> categoryEntity.setChildren(getChildrens(categoryEntity, all)))
|
|
||||||
.sorted(Comparator.comparingInt(menu -> (menu.getSort() == null ? 0 : menu.getSort())))
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -619,7 +619,7 @@
|
||||||
<script type="text/javascript" src="index/js/header.js"></script>
|
<script type="text/javascript" src="index/js/header.js"></script>
|
||||||
<script type="text/javascript" src="index/js/secend.js"></script>
|
<script type="text/javascript" src="index/js/secend.js"></script>
|
||||||
<script type="text/javascript" src="index/js/zz.js"></script>
|
<script type="text/javascript" src="index/js/zz.js"></script>
|
||||||
<script type="text/javascript" src="index/jsindex.js"></script>
|
<script type="text/javascript" src="index/js/index.js"></script>
|
||||||
<script type="text/javascript" src="index/js/left,top.js"></script>
|
<script type="text/javascript" src="index/js/left,top.js"></script>
|
||||||
<script type="text/javascript" src="index/js/catalogLoader.js"></script>
|
<script type="text/javascript" src="index/js/catalogLoader.js"></script>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue