yangyb 1 ay önce
ebeveyn
işleme
1f320847fb

+ 4 - 0
mall-api/pom.xml

@@ -39,6 +39,10 @@
             <groupId>javax.validation</groupId>
             <artifactId>validation-api</artifactId>
         </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-annotations</artifactId>
+        </dependency>
         <!--        <dependency>-->
 <!--            <groupId>org.springframework.data</groupId>-->
 <!--            <artifactId>spring-data-redis</artifactId>-->

+ 79 - 0
mall-api/src/main/java/com/txz/mall/dto/CategoryDTO.java

@@ -0,0 +1,79 @@
+/*
+ *
+ * CategoryDTO.java
+ * Copyright(C) 2017-2020 fendo公司
+ * @date 2025-07-11
+ */
+package com.txz.mall.dto;
+
+import java.io.Serializable;
+import java.util.Date;
+
+public class CategoryDTO implements Serializable {
+    private Long id;
+
+    /**
+     * 父级ID
+     */
+    private Long pid;
+
+    /**
+     * 路径
+     */
+    private String path;
+
+    /**
+     * 分类名称
+     */
+    private String name;
+
+    /**
+     * 类型,1 产品分类,2 附件分类,3 文章分类, 4 设置分类, 5 菜单分类,6 配置分类, 7 秒杀配置
+     */
+    private Integer type;
+
+    /**
+     * 地址
+     */
+    private String url;
+
+    /**
+     * 状态, 1正常,0失效
+     */
+    private Integer status;
+
+    /**
+     * 排序
+     */
+    private Integer sort;
+
+    /**
+     * 创建时间
+     */
+    private Date createTime;
+
+    /**
+     * 更新时间
+     */
+    private Date updateTime;
+
+    /**
+     * 扩展字段 Jsos格式
+     */
+    private String extra;
+
+    /**
+     * 创建人id
+     */
+    private Long createUserId;
+
+    /**
+     * 更新人id
+     */
+    private Long updateUserId;
+
+    /**
+     * 是否删除
+     */
+    private Integer isDelete;
+}

+ 44 - 0
mall-api/src/main/java/com/txz/mall/vo/CategoryTreeVo.java

@@ -0,0 +1,44 @@
+package com.txz.mall.vo;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+@Data
+public class CategoryTreeVo implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    private Integer id;
+
+    @ApiModelProperty(value = "父级ID")
+    private Integer pid;
+
+    @ApiModelProperty(value = "路径")
+    private String path;
+
+    @ApiModelProperty(value = "分类名称")
+    private String name;
+
+    @ApiModelProperty(value = "类型,类型,1 产品分类,2 附件分类,3 文章分类, 4 设置分类, 5 菜单分类, 6 配置分类, 7 秒杀配置")
+    private Integer type;
+
+    @ApiModelProperty(value = "地址")
+    private String url;
+
+    @ApiModelProperty(value = "扩展字段")
+    private String extra;
+
+    @ApiModelProperty(value = "状态, 0正常,1失效")
+    private Boolean status;
+
+    @ApiModelProperty(value = "排序")
+    private Integer sort;
+
+    @JsonInclude(JsonInclude.Include.NON_EMPTY) //属性为 空("")[] 或者为 NULL 都不序列化
+    private List<CategoryTreeVo> child = new ArrayList<>();
+}

+ 27 - 0
mall-interface/src/main/java/com/txz/mall/service/CategoryServiceClient.java

@@ -0,0 +1,27 @@
+package com.txz.mall.service;
+
+
+import com.txz.mall.dto.*;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.*;
+import java.util.List;
+
+
+@FeignClient("mall")
+public interface CategoryServiceClient {
+
+	@RequestMapping( value = {"/category/add"}, method = {RequestMethod.POST} )
+    public Result add(@RequestBody CategoryDPO category,@RequestParam("userId") Long userId);
+
+	@RequestMapping( value = {"/category/delete"}, method = {RequestMethod.POST} )
+	public Result delete(@RequestParam("id") Integer id,@RequestParam("userId") Long userId);
+
+	@RequestMapping( value = {"/category/update"}, method = {RequestMethod.POST} )
+	public Result update(@RequestBody CategoryDPO category,@RequestParam("userId") Long userId);
+
+	@RequestMapping( value = {"/category/detail"}, method = {RequestMethod.POST} )
+	public Result<CategoryDPO> detail(@RequestParam("id") Integer id,@RequestParam("userId") Long userId);
+
+	@RequestMapping( value = {"/category/list"}, method = {RequestMethod.POST} )
+	public Result<List<CategoryDPO>> list(@RequestBody CategoryDPO category, @RequestParam("page") Integer page, @RequestParam("size") Integer size,@RequestParam("userId") Long userId);
+}

+ 153 - 0
mall-service/src/main/java/com/txz/mall/controller/CategoryController.java

@@ -0,0 +1,153 @@
+package com.txz.mall.controller;
+
+import com.github.pagehelper.PageHelper;
+import com.github.pagehelper.PageInfo;
+import com.txz.mall.core.Result;
+import com.txz.mall.core.ResultCode;
+import com.txz.mall.model.Category;
+import com.txz.mall.service.CategoryService;
+import com.txz.mall.vo.CategoryTreeVo;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.web.bind.annotation.*;
+import tk.mybatis.mapper.entity.Condition;
+
+import javax.annotation.Resource;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * Created by CodeGenerator on 2025/07/11.
+ */
+@Api(tags = "[后台]类目管理")
+@RestController
+@RequestMapping("/category")
+public class CategoryController {
+
+    private static Logger log = LoggerFactory.getLogger(CategoryController.class);
+
+    @Resource
+    private CategoryService categoryService;
+
+    @PostMapping("/add")
+    @ApiOperation(value = "类目新增", httpMethod = "POST")
+    public Result add(@RequestBody Category category, Long userId) {
+        if (category == null) {
+            return Result.fail(ResultCode.OBJECT_IS_NULL);
+        }
+        if (userId == null) {
+            return Result.fail(ResultCode.USERID_IS_NULL);
+        }
+        try {
+            category.setCreateTime(new Date());
+            category.setCreateUserId(userId);
+            categoryService.save(category);
+        } catch (Exception e) {
+            log.error("新增对象操作异常e:{}", e);
+            return Result.fail(ResultCode.INTERNAL_SERVER_ERROR);
+        }
+        return Result.success();
+    }
+
+    @PostMapping("/delete")
+    @ApiOperation(value = "类目删除", httpMethod = "POST")
+    public Result delete(@RequestParam Long id, Long userId) {
+        if (id == null) {
+            return Result.fail(ResultCode.ID_IS_NULL);
+        }
+        if (userId == null) {
+            return Result.fail(ResultCode.USERID_IS_NULL);
+        }
+        try {
+            Category category = new Category();
+            category.setIsDelete(1);
+            categoryService.update(category);
+        } catch (Exception e) {
+            log.error("删除对象操作异常e:{}", e);
+            return Result.fail(ResultCode.INTERNAL_SERVER_ERROR);
+        }
+        return Result.success();
+    }
+
+    @PostMapping("/update")
+    @ApiOperation(value = "类目更新", httpMethod = "POST")
+    public Result update(@RequestBody Category category, Long userId) {
+        if (category == null) {
+            return Result.fail(ResultCode.OBJECT_IS_NULL);
+        }
+        if (category.getId() == null) {
+            return Result.fail(ResultCode.ID_IS_NULL);
+        }
+        if (userId == null) {
+            return Result.fail(ResultCode.USERID_IS_NULL);
+        }
+        try {
+            category.setUpdateTime(new Date());
+            category.setUpdateUserId(userId);
+            categoryService.update(category);
+        } catch (Exception e) {
+            log.error("更新对象操作异常e:{}", e);
+            return Result.fail(ResultCode.INTERNAL_SERVER_ERROR);
+        }
+        return Result.success();
+    }
+
+    @PostMapping("/detail")
+    @ApiOperation(value = "类目获取详情", httpMethod = "POST")
+    public Result<Category> detail(@RequestParam Long id, Long userId) {
+        if (id == null) {
+            return Result.fail(ResultCode.ID_IS_NULL);
+        }
+        if (userId == null) {
+            return Result.fail(ResultCode.USERID_IS_NULL);
+        }
+        Category category = null;
+        try {
+            category = categoryService.findById(id);
+        } catch (Exception e) {
+            log.error("查询对象操作异常e:{}", e);
+            return Result.fail(ResultCode.INTERNAL_SERVER_ERROR);
+        }
+        return Result.success(category);
+    }
+
+    @PostMapping("/list")
+    @ApiOperation(value = "类目获取列表", httpMethod = "POST")
+    public Result<List<Category>> list(@RequestBody Category category, @RequestParam(defaultValue = "0") Integer page, @RequestParam(defaultValue = "0") Integer size, Long userId) {
+        if (userId == null) {
+            return Result.fail(ResultCode.USERID_IS_NULL);
+        }
+        PageHelper.startPage(page, size);
+
+        Condition condition = new Condition(category.getClass());
+//        Criteria criteria = condition.createCriteria();
+//        criteria.andEqualTo("name", city.getName());
+        PageInfo pageInfo = null;
+        try {
+            List<Category> list = categoryService.findByCondition(condition);
+            pageInfo = new PageInfo(list);
+        } catch (Exception e) {
+            log.error("查询对象操作异常e:{}", e);
+            return Result.fail(ResultCode.INTERNAL_SERVER_ERROR);
+        }
+        return Result.success(pageInfo);
+    }
+
+    @ApiOperation(value = "获取tree结构的列表")
+    @GetMapping(value = "/list/tree")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "type", value = "类型ID | 类型,1 产品分类,2 附件分类,3 文章分类, 4 设置分类, 5 菜单分类, 6 配置分类, 7 秒杀配置", example = "1"),
+            @ApiImplicitParam(name = "status", value = "-1=全部,0=未生效,1=已生效", example = "1"),
+            @ApiImplicitParam(name = "name", value = "模糊搜索", example = "电视")
+    })
+    public Result<List<CategoryTreeVo>> getListTree(@RequestParam(name = "type") Integer type,
+                                                    @RequestParam(name = "status") Integer status,
+                                                    @RequestParam(name = "name", required = false) String name) {
+        List<CategoryTreeVo> listTree = categoryService.getListTree(type, status, name);
+        return Result.success(listTree);
+    }
+}

+ 1 - 1
mall-service/src/main/java/com/txz/mall/controller/StoreProductController.java

@@ -126,7 +126,7 @@ public class StoreProductController {
 
     @PostMapping("/updateShowStatus")
     @ApiOperation(value = "商品上下架", httpMethod = "POST")
-    public Result updateShowStatus(@RequestParam Long id, @RequestParam Boolean ShowStatus, Long userId) {
+    public Result updateShowStatus(@RequestParam Long id, @RequestParam Integer ShowStatus, Long userId) {
         if (ShowStatus == null) {
             return Result.fail(ResultCode.OBJECT_IS_NULL);
         }

+ 7 - 0
mall-service/src/main/java/com/txz/mall/dao/CategoryMapper.java

@@ -0,0 +1,7 @@
+package com.txz.mall.dao;
+
+import com.txz.mall.core.Mapper;
+import com.txz.mall.model.Category;
+
+public interface CategoryMapper extends Mapper<Category> {
+}

+ 85 - 0
mall-service/src/main/java/com/txz/mall/model/Category.java

@@ -0,0 +1,85 @@
+package com.txz.mall.model;
+
+import lombok.Data;
+
+import javax.persistence.*;
+import java.util.Date;
+
+@Data
+@Table(name = "m_category")
+public class Category {
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private Long id;
+
+    /**
+     * 父级ID
+     */
+    private Long pid;
+
+    /**
+     * 路径
+     */
+    private String path;
+
+    /**
+     * 分类名称
+     */
+    private String name;
+
+    /**
+     * 类型,1 产品分类,2 附件分类,3 文章分类, 4 设置分类, 5 菜单分类,6 配置分类, 7 秒杀配置
+     */
+    private Integer type;
+
+    /**
+     * 地址
+     */
+    private String url;
+
+    /**
+     * 状态, 1正常,0失效
+     */
+    private Integer status;
+
+    /**
+     * 排序
+     */
+    private Integer sort;
+
+    /**
+     * 创建时间
+     */
+    @Column(name = "create_time")
+    private Date createTime;
+
+    /**
+     * 更新时间
+     */
+    @Column(name = "update_time")
+    private Date updateTime;
+
+    /**
+     * 扩展字段 Jsos格式
+     */
+    @Column(name = "extra")
+    private String extra;
+
+    /**
+     * 创建人id
+     */
+    @Column(name = "create_user_id")
+    private Long createUserId;
+
+    /**
+     * 更新人id
+     */
+    @Column(name = "update_user_id")
+    private Long updateUserId;
+
+    /**
+     * 是否删除
+     */
+    @Column(name = "is_delete")
+    private Integer isDelete;
+}

+ 9 - 9
mall-service/src/main/java/com/txz/mall/model/StoreProduct.java

@@ -97,31 +97,31 @@ public class StoreProduct {
      * 状态(0:未上架,1:上架)
      */
     @Column(name = "is_show")
-    private Boolean isShow;
+    private Integer isShow;
 
     /**
      * 是否热卖
      */
     @Column(name = "is_hot")
-    private Boolean isHot;
+    private Integer isHot;
 
     /**
      * 是否优惠
      */
     @Column(name = "is_benefit")
-    private Boolean isBenefit;
+    private Integer isBenefit;
 
     /**
      * 是否精品
      */
     @Column(name = "is_best")
-    private Boolean isBest;
+    private Integer isBest;
 
     /**
      * 是否新品
      */
     @Column(name = "is_new")
-    private Boolean isNew;
+    private Integer isNew;
 
     /**
      * 添加时间
@@ -168,13 +168,13 @@ public class StoreProduct {
      * 是否优品推荐
      */
     @Column(name = "is_good")
-    private Boolean isGood;
+    private Integer isGood;
 
     /**
      * 是否单独分佣
      */
     @Column(name = "is_sub")
-    private Boolean isSub;
+    private Integer isSub;
 
     /**
      * 虚拟销量
@@ -202,7 +202,7 @@ public class StoreProduct {
      * 规格 0单 1多
      */
     @Column(name = "spec_type")
-    private Boolean specType;
+    private Integer specType;
 
     /**
      * 活动显示排序0=默认, 1=秒杀,2=砍价,3=拼团
@@ -213,7 +213,7 @@ public class StoreProduct {
      * 是否回收站
      */
     @Column(name = "is_recycle")
-    private Boolean isRecycle;
+    private Integer isRecycle;
 
     /**
      * 创建人id

+ 24 - 0
mall-service/src/main/java/com/txz/mall/service/CategoryService.java

@@ -0,0 +1,24 @@
+package com.txz.mall.service;
+
+import com.txz.mall.core.Service;
+import com.txz.mall.model.Category;
+import com.txz.mall.vo.CategoryTreeVo;
+
+import java.util.List;
+
+
+/**
+ * Created by CodeGenerator on 2025/07/11.
+ */
+public interface CategoryService extends Service<Category> {
+
+    /**
+     * 获取树结构
+     *
+     * @param type   分类类型
+     * @param status 状态
+     * @param name   名称
+     * @return
+     */
+    List<CategoryTreeVo> getListTree(Integer type, Integer status, String name);
+}

+ 114 - 0
mall-service/src/main/java/com/txz/mall/service/impl/CategoryServiceImpl.java

@@ -0,0 +1,114 @@
+package com.txz.mall.service.impl;
+
+import cn.hutool.core.collection.CollUtil;
+import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
+import com.baomidou.mybatisplus.core.toolkit.StringUtils;
+import com.txz.mall.core.AbstractService;
+import com.txz.mall.dao.CategoryMapper;
+import com.txz.mall.model.Category;
+import com.txz.mall.service.CategoryService;
+import com.txz.mall.vo.CategoryTreeVo;
+import org.springframework.beans.BeanUtils;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import tk.mybatis.mapper.entity.Condition;
+import tk.mybatis.mapper.entity.Example;
+
+import javax.annotation.Resource;
+import java.util.*;
+import java.util.stream.Collectors;
+
+
+/**
+ * Created by CodeGenerator on 2025/07/11.
+ */
+@Service
+@Transactional
+public class CategoryServiceImpl extends AbstractService<Category> implements CategoryService {
+    @Resource
+    private CategoryMapper categoryMapper;
+
+    @Override
+    public List<CategoryTreeVo> getListTree(Integer type, Integer status, String name) {
+        return getTree(type, status, name, null);
+    }
+
+    /**
+     * 带结构的无线级分类
+     *
+     * @author Mr.Zhang
+     * @since 2020-04-16
+     */
+    private List<CategoryTreeVo> getTree(Integer type, Integer status, String name, List<Integer> categoryIdList) {
+        //循环数据,把数据对象变成带list结构的vo
+        List<CategoryTreeVo> treeList = new ArrayList<>();
+        Condition condition = new Condition(Category.class);
+        Example.Criteria criteria = condition.createCriteria();
+        criteria.andEqualTo("type", type);
+
+        if (null != categoryIdList && categoryIdList.size() > 0) {
+            criteria.andIn("id", categoryIdList);
+        }
+
+        if (status >= 0) {
+            criteria.andEqualTo("status", status);
+        }
+        // 根据名称模糊搜索
+        if (StringUtils.isNotBlank(name)) {
+            criteria.andLike("name", name);
+        }
+
+        criteria.andEqualTo("isDelete", 0);
+        List<Category> allTree = this.findByCondition(condition);
+        if (CollectionUtils.isEmpty(allTree)) {
+            return null;
+        }
+        allTree = allTree.stream()
+                .sorted(Comparator
+                        .comparing(Category::getSort, Comparator.reverseOrder())
+                        .thenComparing(Comparator.comparing(Category::getId))
+                )
+                .collect(Collectors.toList());
+        // 根据名称搜索特殊处理 这里仅仅处理两层搜索后有子父级关系的数据
+        if (StringUtils.isNotBlank(name) && allTree.size() > 0) {
+            List<Category> searchCategory = new ArrayList<>();
+            List<Long> categoryIds = allTree.stream().map(Category::getId).collect(Collectors.toList());
+
+            List<Long> pidList = allTree.stream().filter(c -> c.getPid() > 0 && !categoryIds.contains(c.getPid()))
+                    .map(Category::getPid).distinct().collect(Collectors.toList());
+            if (CollUtil.isNotEmpty(pidList)) {
+                pidList.forEach(pid -> {
+                    searchCategory.add(this.findById(pid));
+                });
+            }
+            allTree.addAll(searchCategory);
+        }
+
+        for (Category category : allTree) {
+            CategoryTreeVo categoryTreeVo = new CategoryTreeVo();
+            BeanUtils.copyProperties(category, categoryTreeVo);
+            treeList.add(categoryTreeVo);
+        }
+
+
+        //返回
+        Map<Integer, CategoryTreeVo> map = new HashMap<>();
+        //ID 为 key 存储到map 中
+        for (CategoryTreeVo categoryTreeVo1 : treeList) {
+            map.put(categoryTreeVo1.getId(), categoryTreeVo1);
+        }
+
+        List<CategoryTreeVo> list = new ArrayList<>();
+        for (CategoryTreeVo tree : treeList) {
+            //子集ID返回对象,有则添加。
+            CategoryTreeVo tree1 = map.get(tree.getPid());
+            if (tree1 != null) {
+                tree1.getChild().add(tree);
+            } else {
+                list.add(tree);
+            }
+        }
+        return list;
+    }
+
+}

+ 23 - 0
mall-service/src/main/resources/mapper/CategoryMapper.xml

@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.txz.mall.dao.CategoryMapper">
+    <resultMap id="BaseResultMap" type="com.txz.mall.model.Category">
+        <!--
+          WARNING - @mbg.generated
+        -->
+        <id column="id" jdbcType="BIGINT" property="id"/>
+        <id column="pid" jdbcType="BIGINT" property="pid"/>
+        <result column="path" jdbcType="VARCHAR" property="path"/>
+        <result column="name" jdbcType="VARCHAR" property="name"/>
+        <result column="type" jdbcType="INTEGER" property="type"/>
+        <result column="url" jdbcType="VARCHAR" property="url"/>
+        <result column="status" jdbcType="INTEGER" property="status"/>
+        <result column="sort" jdbcType="INTEGER" property="sort"/>
+        <result column="create_time" jdbcType="TIMESTAMP" property="createTime"/>
+        <result column="update_time" jdbcType="TIMESTAMP" property="updateTime"/>
+        <result column="extra" jdbcType="VARCHAR" property="extra"/>
+        <result column="create_user_id" jdbcType="BIGINT" property="createUserId"/>
+        <result column="update_user_id" jdbcType="BIGINT" property="updateUserId"/>
+        <result column="is_delete" jdbcType="INTEGER" property="isDelete"/>
+    </resultMap>
+</mapper>