|
@@ -20,6 +20,7 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
|
import com.google.common.collect.Lists;
|
|
|
import com.yami.shop.bean.dto.ListCategoryDTO;
|
|
|
import com.yami.shop.bean.model.Category;
|
|
|
+import com.yami.shop.bean.model.ShopCategory;
|
|
|
import com.yami.shop.bean.param.CategoryScoreConfigParam;
|
|
|
import com.yami.shop.bean.param.ScoreConfigParam;
|
|
|
import com.yami.shop.bean.vo.ListCategoryForUserVO;
|
|
@@ -27,10 +28,7 @@ import com.yami.shop.bean.vo.ListCategoryVO;
|
|
|
import com.yami.shop.common.config.Constant;
|
|
|
import com.yami.shop.common.exception.GlobalException;
|
|
|
import com.yami.shop.config.ShopConfig;
|
|
|
-import com.yami.shop.dao.CategoryBrandMapper;
|
|
|
-import com.yami.shop.dao.CategoryMapper;
|
|
|
-import com.yami.shop.dao.CategoryProdMapper;
|
|
|
-import com.yami.shop.dao.ProductMapper;
|
|
|
+import com.yami.shop.dao.*;
|
|
|
import com.yami.shop.service.CategoryService;
|
|
|
import com.yami.shop.service.SysConfigService;
|
|
|
import lombok.AllArgsConstructor;
|
|
@@ -53,136 +51,137 @@ import static java.util.stream.Collectors.groupingBy;
|
|
|
*/
|
|
|
@Service
|
|
|
@AllArgsConstructor
|
|
|
-public class CategoryServiceImpl extends ServiceImpl<CategoryMapper, Category> implements CategoryService{
|
|
|
+public class CategoryServiceImpl extends ServiceImpl<CategoryMapper, Category> implements CategoryService {
|
|
|
|
|
|
- private final CategoryMapper categoryMapper;
|
|
|
- private final ShopConfig shopConfig;
|
|
|
+ private final CategoryMapper categoryMapper;
|
|
|
+ private final ShopConfig shopConfig;
|
|
|
|
|
|
- private final CategoryBrandMapper categoryBrandMapper;
|
|
|
+ private final CategoryBrandMapper categoryBrandMapper;
|
|
|
|
|
|
- private final CategoryProdMapper categoryPropMapper;
|
|
|
+ private final CategoryProdMapper categoryPropMapper;
|
|
|
+ private final ShopCategoryMapper shopCategoryMapper;
|
|
|
|
|
|
- private final ProductMapper productMapper;
|
|
|
+ private final ProductMapper productMapper;
|
|
|
|
|
|
- private SysConfigService sysConfigService;
|
|
|
+ private SysConfigService sysConfigService;
|
|
|
|
|
|
- @Override
|
|
|
- @Transactional(rollbackFor = Exception.class)
|
|
|
+ @Override
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
// @CacheEvict(cacheNames = "CategoryListByParentIdAndShopId", key = "#category.parentId + ':' + #category.shopId")
|
|
|
- @Caching(evict = {
|
|
|
- @CacheEvict(cacheNames = "CategoryListByParentIdAndShopId", key = "#category.parentId + ':' + #category.shopId"),
|
|
|
- @CacheEvict(cacheNames = "CategoryListByShopId", key = "#category.shopId + ':category'")
|
|
|
- })
|
|
|
- public void saveCategroy(Category category) {
|
|
|
- category.setRecTime(new Date());
|
|
|
- // 保存分类信息
|
|
|
- categoryMapper.insert(category);
|
|
|
-
|
|
|
- insertBrandsAndAttributes(category);
|
|
|
-
|
|
|
- if (Objects.equals(category.getParentId(),Constant.CATEGORY_ID) && Objects.equals(category.getShopId(),Constant.PLATFORM_SHOP_ID)){
|
|
|
- this.changeScoreConfig();
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- @Transactional(rollbackFor = Exception.class)
|
|
|
+ @Caching(evict = {
|
|
|
+ @CacheEvict(cacheNames = "CategoryListByParentIdAndShopId", key = "#category.parentId + ':' + #category.shopId"),
|
|
|
+ @CacheEvict(cacheNames = "CategoryListByShopId", key = "#category.shopId + ':category'")
|
|
|
+ })
|
|
|
+ public void saveCategroy(Category category) {
|
|
|
+ category.setRecTime(new Date());
|
|
|
+ // 保存分类信息
|
|
|
+ categoryMapper.insert(category);
|
|
|
+
|
|
|
+ insertBrandsAndAttributes(category);
|
|
|
+
|
|
|
+ if (Objects.equals(category.getParentId(), Constant.CATEGORY_ID) && Objects.equals(category.getShopId(), Constant.PLATFORM_SHOP_ID)) {
|
|
|
+ this.changeScoreConfig();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
// @CacheEvict(cacheNames = "CategoryListByParentIdAndShopId", key = "#category.parentId + ':' + #category.shopId")
|
|
|
- @Caching(evict = {
|
|
|
- @CacheEvict(cacheNames = "CategoryListByParentIdAndShopId", key = "#category.parentId + ':' + #category.shopId"),
|
|
|
- @CacheEvict(cacheNames = "CategoryListByShopId", key = "#category.shopId + ':category'")
|
|
|
- })
|
|
|
- public void updateCategroy(Category category) {
|
|
|
- Category categoryDB = categoryMapper.selectById(category.getCategoryId());
|
|
|
- category.setUpdateTime(new Date());
|
|
|
-
|
|
|
- // 保存分类信息
|
|
|
- categoryMapper.updateById(category);
|
|
|
-
|
|
|
- if (Objects.equals(categoryDB.getStatus(),1) && Objects.equals(category.getStatus(),0)){
|
|
|
- if (Objects.equals(category.getParentId(), 0L)){
|
|
|
- List<Category> categorieList = categoryMapper.selectList(new LambdaQueryWrapper<Category>().eq(Category::getParentId, category.getCategoryId()));
|
|
|
- for (Category categoryByParentId: categorieList){
|
|
|
- categoryByParentId.setStatus(0);
|
|
|
- //从正常改为下线
|
|
|
- productMapper.offlineProdByCategoryId(categoryByParentId.getCategoryId());
|
|
|
- }
|
|
|
- updateBatchById(categorieList);
|
|
|
- }else {
|
|
|
- //从正常改为下线
|
|
|
- productMapper.offlineProdByCategoryId(category.getCategoryId());
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- //修改积分配置中的分类数据
|
|
|
- if (!Objects.equals(category.getCategoryName(),category.getOldCategoryName())){
|
|
|
- this.changeScoreConfig();
|
|
|
- }
|
|
|
- // 先删除后增加
|
|
|
- deleteBrandsAndAttributes(category.getCategoryId());
|
|
|
- insertBrandsAndAttributes(category);
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- @Transactional(rollbackFor = Exception.class)
|
|
|
+ @Caching(evict = {
|
|
|
+ @CacheEvict(cacheNames = "CategoryListByParentIdAndShopId", key = "#category.parentId + ':' + #category.shopId"),
|
|
|
+ @CacheEvict(cacheNames = "CategoryListByShopId", key = "#category.shopId + ':category'")
|
|
|
+ })
|
|
|
+ public void updateCategroy(Category category) {
|
|
|
+ Category categoryDB = categoryMapper.selectById(category.getCategoryId());
|
|
|
+ category.setUpdateTime(new Date());
|
|
|
+
|
|
|
+ // 保存分类信息
|
|
|
+ categoryMapper.updateById(category);
|
|
|
+
|
|
|
+ if (Objects.equals(categoryDB.getStatus(), 1) && Objects.equals(category.getStatus(), 0)) {
|
|
|
+ if (Objects.equals(category.getParentId(), 0L)) {
|
|
|
+ List<Category> categorieList = categoryMapper.selectList(new LambdaQueryWrapper<Category>().eq(Category::getParentId, category.getCategoryId()));
|
|
|
+ for (Category categoryByParentId : categorieList) {
|
|
|
+ categoryByParentId.setStatus(0);
|
|
|
+ //从正常改为下线
|
|
|
+ productMapper.offlineProdByCategoryId(categoryByParentId.getCategoryId());
|
|
|
+ }
|
|
|
+ updateBatchById(categorieList);
|
|
|
+ } else {
|
|
|
+ //从正常改为下线
|
|
|
+ productMapper.offlineProdByCategoryId(category.getCategoryId());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //修改积分配置中的分类数据
|
|
|
+ if (!Objects.equals(category.getCategoryName(), category.getOldCategoryName())) {
|
|
|
+ this.changeScoreConfig();
|
|
|
+ }
|
|
|
+ // 先删除后增加
|
|
|
+ deleteBrandsAndAttributes(category.getCategoryId());
|
|
|
+ insertBrandsAndAttributes(category);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
// @CacheEvict(cacheNames = "CategoryListByParentIdAndShopId", key = "#category.parentId + ':' + #category.shopId")
|
|
|
- @Caching(evict = {
|
|
|
- @CacheEvict(cacheNames = "CategoryListByParentIdAndShopId", key = "#category.parentId + ':' + #category.shopId"),
|
|
|
- @CacheEvict(cacheNames = "CategoryListByShopId", key = "#category.shopId + ':category'")
|
|
|
- })
|
|
|
- public void deleteCategroy(Category category) {
|
|
|
- categoryMapper.deleteById(category.getCategoryId());
|
|
|
- //修改积分配置中的分类数据
|
|
|
- if (Objects.equals(category.getParentId(),Constant.CATEGORY_ID)){
|
|
|
- this.changeScoreConfig();
|
|
|
- }
|
|
|
- deleteBrandsAndAttributes(category.getCategoryId());
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public Category getCategoryByCategoryIdAndShopId(Long categoryId, Long shopId) {
|
|
|
- Category category = categoryMapper.selectOne(new LambdaQueryWrapper<Category>().eq(Category::getCategoryId, categoryId).eq(Category::getShopId, shopId));
|
|
|
- if (category == null) {
|
|
|
- throw new GlobalException("无法获取分类信息");
|
|
|
- }
|
|
|
- return category;
|
|
|
- }
|
|
|
+ @Caching(evict = {
|
|
|
+ @CacheEvict(cacheNames = "CategoryListByParentIdAndShopId", key = "#category.parentId + ':' + #category.shopId"),
|
|
|
+ @CacheEvict(cacheNames = "CategoryListByShopId", key = "#category.shopId + ':category'")
|
|
|
+ })
|
|
|
+ public void deleteCategroy(Category category) {
|
|
|
+ categoryMapper.deleteById(category.getCategoryId());
|
|
|
+ //修改积分配置中的分类数据
|
|
|
+ if (Objects.equals(category.getParentId(), Constant.CATEGORY_ID)) {
|
|
|
+ this.changeScoreConfig();
|
|
|
+ }
|
|
|
+ deleteBrandsAndAttributes(category.getCategoryId());
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public Category getCategoryByCategoryIdAndShopId(Long categoryId, Long shopId) {
|
|
|
+ Category category = categoryMapper.selectOne(new LambdaQueryWrapper<Category>().eq(Category::getCategoryId, categoryId).eq(Category::getShopId, shopId));
|
|
|
+ if (category == null) {
|
|
|
+ throw new GlobalException("无法获取分类信息");
|
|
|
+ }
|
|
|
+ return category;
|
|
|
+ }
|
|
|
|
|
|
@Override
|
|
|
// @Cacheable(cacheNames = "CategoryListByParentIdAndShopId", key = "#parentId + ':' + #shopId")
|
|
|
public IPage<Category> listByParentIdAndShopId(Long parentId, Long shopId, Integer current, Integer size) {
|
|
|
- if (Objects.isNull(shopId)) {
|
|
|
- IPage<Category> page = page(new Page<>(current, size), new LambdaQueryWrapper<Category>()
|
|
|
- .eq(Category::getParentId, parentId)
|
|
|
- .eq(Category::getStatus, 1)
|
|
|
- .orderByDesc(Category::getSeq)
|
|
|
- .orderByDesc(Category::getCategoryId));
|
|
|
- List<Category> categories = page.getRecords();
|
|
|
- if (CollectionUtil.isNotEmpty(categories)) {
|
|
|
- for (Category category : categories) {
|
|
|
- List<Category> son = categoryMapper.selectList(new LambdaQueryWrapper<Category>()
|
|
|
- .eq(Category::getParentId, category.getCategoryId())
|
|
|
- .eq(Category::getStatus, 1)
|
|
|
- .orderByDesc(Category::getSeq));
|
|
|
- category.setCategories(son);
|
|
|
- if (CollectionUtil.isNotEmpty(son)) {
|
|
|
- for (Category item : son) {
|
|
|
- List<Category> third = categoryMapper.selectList(new LambdaQueryWrapper<Category>()
|
|
|
- .eq(Category::getParentId, item.getCategoryId())
|
|
|
- .eq(Category::getStatus, 1)
|
|
|
- .orderByDesc(Category::getSeq));
|
|
|
- item.setCategories(third);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- Page res = new Page();
|
|
|
- BeanUtils.copyProperties(page, res);
|
|
|
- res.setRecords(categories);
|
|
|
- return res;
|
|
|
- }
|
|
|
- // 如果是平台分类,则特殊处理
|
|
|
- if(shopId == 0) {
|
|
|
+ if (Objects.isNull(shopId)) {
|
|
|
+ IPage<Category> page = page(new Page<>(current, size), new LambdaQueryWrapper<Category>()
|
|
|
+ .eq(Category::getParentId, parentId)
|
|
|
+ .eq(Category::getStatus, 1)
|
|
|
+ .orderByDesc(Category::getSeq)
|
|
|
+ .orderByDesc(Category::getCategoryId));
|
|
|
+ List<Category> categories = page.getRecords();
|
|
|
+ if (CollectionUtil.isNotEmpty(categories)) {
|
|
|
+ for (Category category : categories) {
|
|
|
+ List<Category> son = categoryMapper.selectList(new LambdaQueryWrapper<Category>()
|
|
|
+ .eq(Category::getParentId, category.getCategoryId())
|
|
|
+ .eq(Category::getStatus, 1)
|
|
|
+ .orderByDesc(Category::getSeq));
|
|
|
+ category.setCategories(son);
|
|
|
+ if (CollectionUtil.isNotEmpty(son)) {
|
|
|
+ for (Category item : son) {
|
|
|
+ List<Category> third = categoryMapper.selectList(new LambdaQueryWrapper<Category>()
|
|
|
+ .eq(Category::getParentId, item.getCategoryId())
|
|
|
+ .eq(Category::getStatus, 1)
|
|
|
+ .orderByDesc(Category::getSeq));
|
|
|
+ item.setCategories(third);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ Page res = new Page();
|
|
|
+ BeanUtils.copyProperties(page, res);
|
|
|
+ res.setRecords(categories);
|
|
|
+ return res;
|
|
|
+ }
|
|
|
+ // 如果是平台分类,则特殊处理
|
|
|
+ if (shopId == 0) {
|
|
|
// List<Category> categoriesTwo = categoryMapper.listByParentId(parentId);
|
|
|
// List<Category> categoriesThree = categoryMapper.listThreeByParentId(parentId);
|
|
|
// for (Category category : categoriesThree) {
|
|
@@ -200,136 +199,137 @@ public class CategoryServiceImpl extends ServiceImpl<CategoryMapper, Category> i
|
|
|
// }
|
|
|
// }
|
|
|
// return categoriesTwo;
|
|
|
- return new Page<>();
|
|
|
- }else {
|
|
|
- IPage<Category> page2 = page(new Page<>(current, size), new LambdaQueryWrapper<Category>()
|
|
|
- .eq(Category::getShopId,shopId)
|
|
|
- .eq(Category::getParentId,parentId)
|
|
|
- .eq(Category::getStatus, 1)
|
|
|
- .orderByDesc(Category::getSeq)
|
|
|
- .orderByDesc(Category::getCategoryId));
|
|
|
+ return new Page<>();
|
|
|
+ } else {
|
|
|
+ IPage<Category> page2 = page(new Page<>(current, size), new LambdaQueryWrapper<Category>()
|
|
|
+ .eq(Category::getShopId, shopId)
|
|
|
+ .eq(Category::getParentId, parentId)
|
|
|
+ .eq(Category::getStatus, 1)
|
|
|
+ .orderByDesc(Category::getSeq)
|
|
|
+ .orderByDesc(Category::getCategoryId));
|
|
|
return page2;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- @Override
|
|
|
- @Cacheable(cacheNames = "CategoryListByShopId", key = "#shopId + ':category'")
|
|
|
- public List<Category> listByShopId(Long shopId) {
|
|
|
- return categoryMapper.selectList(new LambdaQueryWrapper<Category>().eq(Category::getShopId,shopId));
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public IPage<ListCategoryVO> listCategory(ListCategoryDTO listCategoryDTO) {
|
|
|
- IPage<ListCategoryVO> listCategoryVOIPage = categoryMapper.listCategory(new Page<>(listCategoryDTO.getCurrent(), listCategoryDTO.getSize()), listCategoryDTO);
|
|
|
- listCategoryVOIPage.getRecords().forEach(listCategoryVO -> {
|
|
|
- listCategoryVO.setGrade(0);
|
|
|
- if(listCategoryVO.getResource() == null){
|
|
|
- listCategoryVO.setResource("");
|
|
|
- }else {
|
|
|
- listCategoryVO.setResource(listCategoryVO.getResource() + "个商品");
|
|
|
- }
|
|
|
- listCategoryVO.setProductBeBound(0);
|
|
|
- listCategoryVO.setChildren(categoryMapper.listCategoryChildren(new ListCategoryDTO().setParentId(listCategoryVO.getCategoryID())));
|
|
|
- listCategoryVO.getChildren().forEach(listCategoryVO1 -> {
|
|
|
- listCategoryVO1.setGrade(1);
|
|
|
- if(listCategoryVO1.getResource() == null){
|
|
|
- listCategoryVO1.setResource("");
|
|
|
- }else {
|
|
|
- listCategoryVO1.setResource(listCategoryVO1.getResource() + "个商品");
|
|
|
- }
|
|
|
- List<ListCategoryVO> listCategoryVOS = categoryMapper.listCategoryChildren(new ListCategoryDTO().setParentId(listCategoryVO1.getCategoryID()));
|
|
|
- if (listCategoryVOS.isEmpty()){
|
|
|
- listCategoryVO1.setProductBeBound(1);
|
|
|
- listCategoryVO1.setChildren(new ArrayList<>());
|
|
|
- }else {
|
|
|
- listCategoryVO1.setProductBeBound(0);
|
|
|
- listCategoryVO1.setChildren(listCategoryVOS);
|
|
|
- listCategoryVO1.getChildren().forEach(listCategoryVO2 -> {
|
|
|
- listCategoryVO2.setGrade(2);
|
|
|
- if(listCategoryVO2.getResource() == null){
|
|
|
- listCategoryVO2.setResource("");
|
|
|
- }else {
|
|
|
- listCategoryVO2.setResource(listCategoryVO2.getResource() + "个商品");
|
|
|
- }
|
|
|
- listCategoryVO2.setProductBeBound(1);
|
|
|
- listCategoryVO2.setChildren(new ArrayList<>());
|
|
|
- });
|
|
|
- }
|
|
|
- });
|
|
|
- });
|
|
|
- return listCategoryVOIPage;
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- @Transactional(rollbackFor = Exception.class)
|
|
|
- public Integer parseCategoryFile(MultipartFile excelFile, Long shopId) throws Exception {
|
|
|
- // 1. 校验并解析Excel
|
|
|
- List<List<String>> dataRows = validateAndParseExcel(excelFile);
|
|
|
-
|
|
|
- // 2. 保存分类层级(若允许放宽主键依赖,可开启批量插入)
|
|
|
- saveCategoryHierarchy(dataRows, shopId);
|
|
|
-
|
|
|
- // 3. 返回成功导入的行数(每行对应一组三级分类)
|
|
|
- return dataRows.size();
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public List<ListCategoryForUserVO> listCategoryForUser(Long shopId) {
|
|
|
- List<Category> categories = categoryMapper.selectList(
|
|
|
- new LambdaQueryWrapper<Category>()
|
|
|
- .eq(Category::getShopId, shopId)
|
|
|
- .eq(Category::getStatus, 1)
|
|
|
- .orderByDesc(Category::getSeq)
|
|
|
- );
|
|
|
- if (CollectionUtil.isEmpty(categories)) {
|
|
|
- return Collections.emptyList();
|
|
|
- }
|
|
|
-
|
|
|
- Map<Long, List<Category>> parentMap = categories.stream()
|
|
|
- .collect(Collectors.groupingBy(Category::getParentId));
|
|
|
-
|
|
|
- // 初始层级为一级分类(grade = 1)
|
|
|
- return buildCategoryTree(parentMap.getOrDefault(0L, Collections.emptyList()), parentMap, 0);
|
|
|
- }
|
|
|
-
|
|
|
- private List<ListCategoryForUserVO> buildCategoryTree(List<Category> categories, Map<Long, List<Category>> parentMap, int currentLevel) {
|
|
|
- if (CollectionUtil.isEmpty(categories)) return Collections.emptyList();
|
|
|
- return categories.stream()
|
|
|
- .map(category -> {
|
|
|
- ListCategoryForUserVO vo = new ListCategoryForUserVO();
|
|
|
- BeanUtil.copyProperties(category, vo);
|
|
|
- vo.setCategoryId(category.getCategoryId());
|
|
|
-
|
|
|
- // 动态计算当前分类的等级(1: 一级, 2: 二级, 3: 三级)
|
|
|
- int grade = currentLevel;
|
|
|
- vo.setGrade(grade); // 如果 VO 类中需要保留 grade 字段,可保留此行
|
|
|
-
|
|
|
- // 判断是否为二级或三级分类,并设置 productBeBound 字段
|
|
|
- int productBeBound = 0;
|
|
|
- if (grade == 1 || grade == 2) {
|
|
|
- // 三级分类直接绑定商品
|
|
|
- if (grade == 2) {
|
|
|
- productBeBound = 1;
|
|
|
- }
|
|
|
- // 二级分类若无子分类(三级分类),则允许绑定商品
|
|
|
- else if (grade == 1) {
|
|
|
- List<Category> children = parentMap.getOrDefault(category.getCategoryId(), Collections.emptyList());
|
|
|
- productBeBound = children.isEmpty() ? 1 : 0;
|
|
|
- }
|
|
|
- }
|
|
|
- vo.setProductBeBound(productBeBound);
|
|
|
-
|
|
|
- // 递归构建子分类树,层级 +1
|
|
|
- List<Category> children = parentMap.getOrDefault(category.getCategoryId(), Collections.emptyList());
|
|
|
- vo.setChildren(buildCategoryTree(children, parentMap, currentLevel + 1));
|
|
|
-
|
|
|
- return vo;
|
|
|
- })
|
|
|
- .collect(Collectors.toList());
|
|
|
- }
|
|
|
-
|
|
|
- // 校验与解析分离
|
|
|
- private List<List<String>> validateAndParseExcel(MultipartFile excelFile) throws Exception {
|
|
|
+ @Override
|
|
|
+ @Cacheable(cacheNames = "CategoryListByShopId", key = "#shopId + ':category'")
|
|
|
+ public List<Category> listByShopId(Long shopId) {
|
|
|
+ return categoryMapper.selectList(new LambdaQueryWrapper<Category>().eq(Category::getShopId, shopId));
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public IPage<ListCategoryVO> listCategory(ListCategoryDTO listCategoryDTO) {
|
|
|
+ IPage<ListCategoryVO> listCategoryVOIPage = categoryMapper.listCategory(new Page<>(listCategoryDTO.getCurrent(), listCategoryDTO.getSize()), listCategoryDTO);
|
|
|
+ listCategoryVOIPage.getRecords().forEach(listCategoryVO -> {
|
|
|
+ listCategoryVO.setGrade(0);
|
|
|
+ if (listCategoryVO.getResource() == null) {
|
|
|
+ listCategoryVO.setResource("");
|
|
|
+ } else {
|
|
|
+ listCategoryVO.setResource(listCategoryVO.getResource() + "个商品");
|
|
|
+ }
|
|
|
+ listCategoryVO.setProductBeBound(0);
|
|
|
+ listCategoryVO.setChildren(categoryMapper.listCategoryChildren(new ListCategoryDTO().setParentId(listCategoryVO.getCategoryID())));
|
|
|
+ listCategoryVO.getChildren().forEach(listCategoryVO1 -> {
|
|
|
+ listCategoryVO1.setGrade(1);
|
|
|
+ if (listCategoryVO1.getResource() == null) {
|
|
|
+ listCategoryVO1.setResource("");
|
|
|
+ } else {
|
|
|
+ listCategoryVO1.setResource(listCategoryVO1.getResource() + "个商品");
|
|
|
+ }
|
|
|
+ List<ListCategoryVO> listCategoryVOS = categoryMapper.listCategoryChildren(new ListCategoryDTO().setParentId(listCategoryVO1.getCategoryID()));
|
|
|
+ if (listCategoryVOS.isEmpty()) {
|
|
|
+ listCategoryVO1.setProductBeBound(1);
|
|
|
+ listCategoryVO1.setChildren(new ArrayList<>());
|
|
|
+ } else {
|
|
|
+ listCategoryVO1.setProductBeBound(0);
|
|
|
+ listCategoryVO1.setChildren(listCategoryVOS);
|
|
|
+ listCategoryVO1.getChildren().forEach(listCategoryVO2 -> {
|
|
|
+ listCategoryVO2.setGrade(2);
|
|
|
+ if (listCategoryVO2.getResource() == null) {
|
|
|
+ listCategoryVO2.setResource("");
|
|
|
+ } else {
|
|
|
+ listCategoryVO2.setResource(listCategoryVO2.getResource() + "个商品");
|
|
|
+ }
|
|
|
+ listCategoryVO2.setProductBeBound(1);
|
|
|
+ listCategoryVO2.setChildren(new ArrayList<>());
|
|
|
+ });
|
|
|
+ }
|
|
|
+ });
|
|
|
+ });
|
|
|
+ return listCategoryVOIPage;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
+ public Integer parseCategoryFile(MultipartFile excelFile, Long shopId) throws Exception {
|
|
|
+ // 1. 校验并解析Excel
|
|
|
+ List<List<String>> dataRows = validateAndParseExcel(excelFile);
|
|
|
+
|
|
|
+ // 2. 保存分类层级(若允许放宽主键依赖,可开启批量插入)
|
|
|
+ saveCategoryHierarchy(dataRows, shopId);
|
|
|
+
|
|
|
+ // 3. 返回成功导入的行数(每行对应一组三级分类)
|
|
|
+ return dataRows.size();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public List<ListCategoryForUserVO> listCategoryForUser(Long shopId) {
|
|
|
+ List<ShopCategory> shopCategories = shopCategoryMapper.selectList(new LambdaQueryWrapper<ShopCategory>()
|
|
|
+ .eq(ShopCategory::getShopId, shopId)
|
|
|
+ .eq(ShopCategory::getIsDelete, Boolean.FALSE)
|
|
|
+ .orderByDesc(ShopCategory::getNum));
|
|
|
+ if (CollectionUtil.isEmpty(shopCategories)) {
|
|
|
+ return Collections.emptyList();
|
|
|
+ }
|
|
|
+
|
|
|
+ Map<Long, List<ShopCategory>> parentMap = shopCategories.stream()
|
|
|
+ .collect(Collectors.groupingBy(ShopCategory::getPid));
|
|
|
+
|
|
|
+ // 初始层级为一级分类(grade = 1)
|
|
|
+ return buildCategoryTree(parentMap.getOrDefault(0L, Collections.emptyList()), parentMap, 0);
|
|
|
+ }
|
|
|
+
|
|
|
+ private List<ListCategoryForUserVO> buildCategoryTree(List<ShopCategory> categories, Map<Long, List<ShopCategory>> parentMap, int currentLevel) {
|
|
|
+ if (CollectionUtil.isEmpty(categories)) return Collections.emptyList();
|
|
|
+ return categories.stream()
|
|
|
+ .map(category -> {
|
|
|
+ ListCategoryForUserVO vo = new ListCategoryForUserVO();
|
|
|
+ vo.setCategoryName(category.getName());
|
|
|
+ vo.setSeq(category.getNum());
|
|
|
+ vo.setParentId(category.getPid());
|
|
|
+ vo.setCategoryId(category.getId());
|
|
|
+ vo.setIcon(category.getIcon());
|
|
|
+
|
|
|
+ // 动态计算当前分类的等级(1: 一级, 2: 二级, 3: 三级)
|
|
|
+ int grade = currentLevel;
|
|
|
+ vo.setGrade(grade); // 如果 VO 类中需要保留 grade 字段,可保留此行
|
|
|
+
|
|
|
+ // 判断是否为二级或三级分类,并设置 productBeBound 字段
|
|
|
+ int productBeBound = 0;
|
|
|
+ if (grade == 1 || grade == 2) {
|
|
|
+ // 三级分类直接绑定商品
|
|
|
+ if (grade == 2) {
|
|
|
+ productBeBound = 1;
|
|
|
+ }
|
|
|
+ // 二级分类若无子分类(三级分类),则允许绑定商品
|
|
|
+ else if (grade == 1) {
|
|
|
+ List<ShopCategory> children = parentMap.getOrDefault(category.getId(), Collections.emptyList());
|
|
|
+ productBeBound = children.isEmpty() ? 1 : 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ vo.setProductBeBound(productBeBound);
|
|
|
+
|
|
|
+ // 递归构建子分类树,层级 +1
|
|
|
+ List<ShopCategory> children = parentMap.getOrDefault(category.getId(), Collections.emptyList());
|
|
|
+ vo.setChildren(buildCategoryTree(children, parentMap, currentLevel + 1));
|
|
|
+
|
|
|
+ return vo;
|
|
|
+ })
|
|
|
+ .collect(Collectors.toList());
|
|
|
+ }
|
|
|
+
|
|
|
+ // 校验与解析分离
|
|
|
+ private List<List<String>> validateAndParseExcel(MultipartFile excelFile) throws Exception {
|
|
|
// Workbook workBook = WorkbookFactory.create(excelFile.getInputStream());
|
|
|
//
|
|
|
// Sheet sheet = workBook.getSheetAt(0);
|
|
@@ -371,114 +371,116 @@ public class CategoryServiceImpl extends ServiceImpl<CategoryMapper, Category> i
|
|
|
// }
|
|
|
// result.add(rowData);
|
|
|
// }
|
|
|
- return new ArrayList<>( );
|
|
|
- }
|
|
|
- // 分类保存逻辑(若允许放宽主键依赖,可开启批量插入)
|
|
|
- private void saveCategoryHierarchy(List<List<String>> dataRows, Long shopId) {
|
|
|
- dataRows.forEach(row -> {
|
|
|
- String cat1Name = row.get(0);
|
|
|
- String cat2Name = row.get(1);
|
|
|
- String cat3Name = row.get(2);
|
|
|
-
|
|
|
- // 1. 处理一级分类(parent_id = 0)
|
|
|
- Category cat1 = categoryMapper.selectByNameAndParentId(cat1Name, 0L, shopId);
|
|
|
- if (cat1 == null) {
|
|
|
- cat1 = buildCategory(shopId, 0L, cat1Name, 0);
|
|
|
- categoryMapper.insert(cat1);
|
|
|
- }
|
|
|
-
|
|
|
- // 2. 处理二级分类(parent_id = cat1.id)
|
|
|
- Category cat2 = categoryMapper.selectByNameAndParentId(cat2Name, cat1.getCategoryId(), shopId);
|
|
|
- if (cat2 == null) {
|
|
|
- cat2 = buildCategory(shopId, cat1.getCategoryId(), cat2Name, 1);
|
|
|
- categoryMapper.insert(cat2);
|
|
|
- }
|
|
|
-
|
|
|
- // 3. 处理三级分类(parent_id = cat2.id,允许为空)
|
|
|
- if (!cat3Name.isEmpty()) {
|
|
|
- Category cat3 = categoryMapper.selectByNameAndParentId(cat3Name, cat2.getCategoryId(), shopId);
|
|
|
- if (cat3 == null) {
|
|
|
- cat3 = buildCategory(shopId, cat2.getCategoryId(), cat3Name, 2);
|
|
|
- categoryMapper.insert(cat3);
|
|
|
- }
|
|
|
- }
|
|
|
- });
|
|
|
- }
|
|
|
- // 构建分类实体(可复用)
|
|
|
- private Category buildCategory(Long shopId, Long parentId, String name, int grade) {
|
|
|
- return new Category()
|
|
|
- .setShopId(shopId)
|
|
|
- .setParentId(parentId)
|
|
|
- .setCategoryName(name)
|
|
|
- .setGrade(grade)
|
|
|
- .setSeq(1) // 默认 seq 值
|
|
|
- .setStatus(1) // 默认启用状态
|
|
|
- .setRecTime(new Date())
|
|
|
- .setUpdateTime(new Date());
|
|
|
- }
|
|
|
-
|
|
|
- private void deleteBrandsAndAttributes(Long categoryId) {
|
|
|
- // 删除所有分类所关联的品牌
|
|
|
- categoryBrandMapper.deleteByCategoryId(categoryId);
|
|
|
- // 删除所有分类所关联的参数
|
|
|
- categoryPropMapper.deleteByCategoryId(categoryId);
|
|
|
- }
|
|
|
-
|
|
|
- private void insertBrandsAndAttributes(Category category) {
|
|
|
- //保存分类与品牌信息
|
|
|
- if(CollUtil.isNotEmpty(category.getBrandIds())){
|
|
|
- categoryBrandMapper.insertCategoryBrand(category.getCategoryId(), category.getBrandIds());
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 刷新积分配置中的分类数据
|
|
|
- */
|
|
|
- private void changeScoreConfig(){
|
|
|
- ScoreConfigParam scoreParamDb = sysConfigService.getSysConfigObject(Constant.SCORE_CONFIG,ScoreConfigParam.class);
|
|
|
- if (Objects.isNull(scoreParamDb)){
|
|
|
- throw new GlobalException("请先前往 【会员管理】-> 【积分成长值配置】-> 【积分获取配置】 进行配置并保存 ");
|
|
|
- }
|
|
|
- //判断分类数据是否正确
|
|
|
- List<Category> categoryList = categoryMapper.selectList(new LambdaQueryWrapper<Category>()
|
|
|
- .eq(Category::getParentId,Constant.CATEGORY_ID)
|
|
|
- .eq(Category::getShopId,Constant.PLATFORM_SHOP_ID)
|
|
|
- .orderByAsc(Category::getCategoryId)
|
|
|
- );
|
|
|
- Map<Long,Category> categoryMap = categoryList.stream().collect(Collectors.toMap(Category::getCategoryId,category -> category));
|
|
|
- // 还没有分类数据时,scoreParamDb.getCategoryConfigs()为null,所以为它new一个对象
|
|
|
- if (Objects.isNull(scoreParamDb.getCategoryConfigs())) {
|
|
|
- scoreParamDb.setCategoryConfigs(Lists.newArrayList());
|
|
|
- }
|
|
|
- Iterator<CategoryScoreConfigParam> iterator = scoreParamDb.getCategoryConfigs().iterator();
|
|
|
- //更新数据并去除已删除的数据
|
|
|
- while (iterator.hasNext()){
|
|
|
- CategoryScoreConfigParam categoryScoreConfigParam = iterator.next();
|
|
|
- Category category = categoryMap.get(categoryScoreConfigParam.getCategoryId());
|
|
|
- if (Objects.isNull(category)){
|
|
|
- iterator.remove();
|
|
|
- }else {
|
|
|
- //刷新分类名称
|
|
|
- categoryScoreConfigParam.setCategoryName(categoryScoreConfigParam.getCategoryName());
|
|
|
- //删除map中已进行操作过的分类
|
|
|
- categoryMap.remove(categoryScoreConfigParam.getCategoryId());
|
|
|
- }
|
|
|
- }
|
|
|
- // 获取map中剩下的分类的id(剩下的分类为积分配置json中所没有的分类,需要新增)
|
|
|
- Set<Long> longs = categoryMap.keySet();
|
|
|
- // 新增积分配置json中的分类数据
|
|
|
- for (Long catrgoryId:longs){
|
|
|
- Category category = categoryMap.get(catrgoryId);
|
|
|
- CategoryScoreConfigParam categoryScoreConfigParam = new CategoryScoreConfigParam();
|
|
|
- categoryScoreConfigParam.setCategoryId(category.getCategoryId());
|
|
|
- categoryScoreConfigParam.setCategoryName(category.getCategoryName());
|
|
|
- categoryScoreConfigParam.setGetScoreLimit(1.00);
|
|
|
- categoryScoreConfigParam.setUseScoreLimit(1.00);
|
|
|
- scoreParamDb.getCategoryConfigs().add(categoryScoreConfigParam);
|
|
|
- }
|
|
|
- //保存数据
|
|
|
- sysConfigService.saveOrUpdateSysConfigService(scoreParamDb,Constant.SCORE_CONFIG);
|
|
|
- }
|
|
|
+ return new ArrayList<>();
|
|
|
+ }
|
|
|
+
|
|
|
+ // 分类保存逻辑(若允许放宽主键依赖,可开启批量插入)
|
|
|
+ private void saveCategoryHierarchy(List<List<String>> dataRows, Long shopId) {
|
|
|
+ dataRows.forEach(row -> {
|
|
|
+ String cat1Name = row.get(0);
|
|
|
+ String cat2Name = row.get(1);
|
|
|
+ String cat3Name = row.get(2);
|
|
|
+
|
|
|
+ // 1. 处理一级分类(parent_id = 0)
|
|
|
+ Category cat1 = categoryMapper.selectByNameAndParentId(cat1Name, 0L, shopId);
|
|
|
+ if (cat1 == null) {
|
|
|
+ cat1 = buildCategory(shopId, 0L, cat1Name, 0);
|
|
|
+ categoryMapper.insert(cat1);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 2. 处理二级分类(parent_id = cat1.id)
|
|
|
+ Category cat2 = categoryMapper.selectByNameAndParentId(cat2Name, cat1.getCategoryId(), shopId);
|
|
|
+ if (cat2 == null) {
|
|
|
+ cat2 = buildCategory(shopId, cat1.getCategoryId(), cat2Name, 1);
|
|
|
+ categoryMapper.insert(cat2);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 3. 处理三级分类(parent_id = cat2.id,允许为空)
|
|
|
+ if (!cat3Name.isEmpty()) {
|
|
|
+ Category cat3 = categoryMapper.selectByNameAndParentId(cat3Name, cat2.getCategoryId(), shopId);
|
|
|
+ if (cat3 == null) {
|
|
|
+ cat3 = buildCategory(shopId, cat2.getCategoryId(), cat3Name, 2);
|
|
|
+ categoryMapper.insert(cat3);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ // 构建分类实体(可复用)
|
|
|
+ private Category buildCategory(Long shopId, Long parentId, String name, int grade) {
|
|
|
+ return new Category()
|
|
|
+ .setShopId(shopId)
|
|
|
+ .setParentId(parentId)
|
|
|
+ .setCategoryName(name)
|
|
|
+ .setGrade(grade)
|
|
|
+ .setSeq(1) // 默认 seq 值
|
|
|
+ .setStatus(1) // 默认启用状态
|
|
|
+ .setRecTime(new Date())
|
|
|
+ .setUpdateTime(new Date());
|
|
|
+ }
|
|
|
+
|
|
|
+ private void deleteBrandsAndAttributes(Long categoryId) {
|
|
|
+ // 删除所有分类所关联的品牌
|
|
|
+ categoryBrandMapper.deleteByCategoryId(categoryId);
|
|
|
+ // 删除所有分类所关联的参数
|
|
|
+ categoryPropMapper.deleteByCategoryId(categoryId);
|
|
|
+ }
|
|
|
+
|
|
|
+ private void insertBrandsAndAttributes(Category category) {
|
|
|
+ //保存分类与品牌信息
|
|
|
+ if (CollUtil.isNotEmpty(category.getBrandIds())) {
|
|
|
+ categoryBrandMapper.insertCategoryBrand(category.getCategoryId(), category.getBrandIds());
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 刷新积分配置中的分类数据
|
|
|
+ */
|
|
|
+ private void changeScoreConfig() {
|
|
|
+ ScoreConfigParam scoreParamDb = sysConfigService.getSysConfigObject(Constant.SCORE_CONFIG, ScoreConfigParam.class);
|
|
|
+ if (Objects.isNull(scoreParamDb)) {
|
|
|
+ throw new GlobalException("请先前往 【会员管理】-> 【积分成长值配置】-> 【积分获取配置】 进行配置并保存 ");
|
|
|
+ }
|
|
|
+ //判断分类数据是否正确
|
|
|
+ List<Category> categoryList = categoryMapper.selectList(new LambdaQueryWrapper<Category>()
|
|
|
+ .eq(Category::getParentId, Constant.CATEGORY_ID)
|
|
|
+ .eq(Category::getShopId, Constant.PLATFORM_SHOP_ID)
|
|
|
+ .orderByAsc(Category::getCategoryId)
|
|
|
+ );
|
|
|
+ Map<Long, Category> categoryMap = categoryList.stream().collect(Collectors.toMap(Category::getCategoryId, category -> category));
|
|
|
+ // 还没有分类数据时,scoreParamDb.getCategoryConfigs()为null,所以为它new一个对象
|
|
|
+ if (Objects.isNull(scoreParamDb.getCategoryConfigs())) {
|
|
|
+ scoreParamDb.setCategoryConfigs(Lists.newArrayList());
|
|
|
+ }
|
|
|
+ Iterator<CategoryScoreConfigParam> iterator = scoreParamDb.getCategoryConfigs().iterator();
|
|
|
+ //更新数据并去除已删除的数据
|
|
|
+ while (iterator.hasNext()) {
|
|
|
+ CategoryScoreConfigParam categoryScoreConfigParam = iterator.next();
|
|
|
+ Category category = categoryMap.get(categoryScoreConfigParam.getCategoryId());
|
|
|
+ if (Objects.isNull(category)) {
|
|
|
+ iterator.remove();
|
|
|
+ } else {
|
|
|
+ //刷新分类名称
|
|
|
+ categoryScoreConfigParam.setCategoryName(categoryScoreConfigParam.getCategoryName());
|
|
|
+ //删除map中已进行操作过的分类
|
|
|
+ categoryMap.remove(categoryScoreConfigParam.getCategoryId());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 获取map中剩下的分类的id(剩下的分类为积分配置json中所没有的分类,需要新增)
|
|
|
+ Set<Long> longs = categoryMap.keySet();
|
|
|
+ // 新增积分配置json中的分类数据
|
|
|
+ for (Long catrgoryId : longs) {
|
|
|
+ Category category = categoryMap.get(catrgoryId);
|
|
|
+ CategoryScoreConfigParam categoryScoreConfigParam = new CategoryScoreConfigParam();
|
|
|
+ categoryScoreConfigParam.setCategoryId(category.getCategoryId());
|
|
|
+ categoryScoreConfigParam.setCategoryName(category.getCategoryName());
|
|
|
+ categoryScoreConfigParam.setGetScoreLimit(1.00);
|
|
|
+ categoryScoreConfigParam.setUseScoreLimit(1.00);
|
|
|
+ scoreParamDb.getCategoryConfigs().add(categoryScoreConfigParam);
|
|
|
+ }
|
|
|
+ //保存数据
|
|
|
+ sysConfigService.saveOrUpdateSysConfigService(scoreParamDb, Constant.SCORE_CONFIG);
|
|
|
+ }
|
|
|
}
|