Administrator
2025-08-04 3bfb50eb7a505c634f0d76ec12ffa68d3f281e85
feat(ai): 添加 AI 产品相关接口和功能

- 新增 AiProductCategory、AiProduct、AiProductPoint 相关的 Controller、Service 和 Mapper
- 实现了产品分类、产品列表、产品详情、知识点详情等接口
- 优化了成员角色列表接口
- 调整了 WebMvc 配置,允许特定的 AI 相关请求
16 files modified
12 files added
750 ■■■■■ changed files
src/main/java/cc/mrbird/febs/ai/controller/memberRole/ApiMemberRoleController.java 4 ●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/ai/controller/product/ApiProductController.java 54 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/ai/controller/productCategory/ApiProductCategoryController.java 48 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/ai/controller/productPoint/ApiProductPointController.java 44 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/ai/mapper/AiProductCategoryMapper.java 5 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/ai/mapper/AiProductMapper.java 5 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/ai/req/product/ApiProductInfoDto.java 20 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/ai/req/product/ApiProductPageDto.java 29 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/ai/req/productCategory/ApiProductCategoryPageDto.java 27 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/ai/req/productPoint/ApiProductPointInfoDto.java 20 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/ai/res/product/ApiProductInfoVo.java 68 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/ai/res/product/ApiProductVo.java 28 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/ai/res/productCategory/ApiProductCategoryVo.java 35 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/ai/res/productPoint/ApiProductPointInfoVo.java 45 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/ai/res/productPoint/ApiProductPointVo.java 22 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/ai/service/AiMemberRoleService.java 2 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/ai/service/AiProductCategoryService.java 15 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/ai/service/AiProductPointLinkService.java 6 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/ai/service/AiProductPointService.java 9 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/ai/service/AiProductService.java 15 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/ai/service/impl/AiMemberRoleServiceImpl.java 15 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/ai/service/impl/AiProductCategoryServiceImpl.java 62 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/ai/service/impl/AiProductPointLinkServiceImpl.java 9 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/ai/service/impl/AiProductPointServiceImpl.java 61 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/ai/service/impl/AiProductServiceImpl.java 64 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/common/configure/WebMvcConfigure.java 4 ●●● patch | view | raw | blame | history
src/main/resources/mapper/modules/AiProductCategoryMapper.xml 12 ●●●●● patch | view | raw | blame | history
src/main/resources/mapper/modules/AiProductMapper.xml 22 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/ai/controller/memberRole/ApiMemberRoleController.java
@@ -29,8 +29,8 @@
    @ApiResponses({
            @ApiResponse(code = 200, message = "success", response = ApiMemberRoleVo.class)
    })
    @GetMapping(value = "/memberRoleList")
    public FebsResponse memberRoleList() {
    @GetMapping(value = "/list")
    public FebsResponse list() {
        return aiMemberRoleService.memberRoleList();
    }
}
src/main/java/cc/mrbird/febs/ai/controller/product/ApiProductController.java
New file
@@ -0,0 +1,54 @@
package cc.mrbird.febs.ai.controller.product;
import cc.mrbird.febs.ai.req.product.ApiProductInfoDto;
import cc.mrbird.febs.ai.req.product.ApiProductPageDto;
import cc.mrbird.febs.ai.res.product.ApiProductInfoVo;
import cc.mrbird.febs.ai.res.product.ApiProductVo;
import cc.mrbird.febs.ai.service.AiProductService;
import cc.mrbird.febs.common.entity.FebsResponse;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
 * @author Administrator
 */
@Slf4j
@Validated
@RestController
@RequiredArgsConstructor
@RequestMapping(value = "/api/ai/product")
@Api(value = "ApiProductController", tags = "AI-产品")
public class ApiProductController {
    private final AiProductService aiProductService;
    @ApiOperation(value = "产品列表", notes = "产品列表")
    @ApiResponses({
            @ApiResponse(code = 200, message = "success", response = ApiProductVo.class)
    })
    @PostMapping(value = "/list")
    public FebsResponse list(@RequestBody @Validated ApiProductPageDto dto) {
        return aiProductService.productList(dto);
    }
    @ApiOperation(value = "产品详情", notes = "产品详情")
    @ApiResponses({
            @ApiResponse(code = 200, message = "success", response = ApiProductInfoVo.class)
    })
    @PostMapping(value = "/info")
    public FebsResponse info(@RequestBody @Validated ApiProductInfoDto dto) {
        return aiProductService.productInfo(dto);
    }
}
src/main/java/cc/mrbird/febs/ai/controller/productCategory/ApiProductCategoryController.java
New file
@@ -0,0 +1,48 @@
package cc.mrbird.febs.ai.controller.productCategory;
import cc.mrbird.febs.ai.req.productCategory.ApiProductCategoryPageDto;
import cc.mrbird.febs.ai.res.productCategory.ApiProductCategoryVo;
import cc.mrbird.febs.ai.service.AiProductCategoryService;
import cc.mrbird.febs.common.entity.FebsResponse;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
/**
 * @author Administrator
 */
@Slf4j
@Validated
@RestController
@RequiredArgsConstructor
@RequestMapping(value = "/api/ai/productCategory")
@Api(value = "ApiProductCategoryController", tags = "AI-产品分类")
public class ApiProductCategoryController {
    private final AiProductCategoryService aiProductCategoryService;
    @ApiOperation(value = "首页推荐", notes = "首页推荐")
    @ApiResponses({
            @ApiResponse(code = 200, message = "success", response = ApiProductCategoryVo.class)
    })
    @GetMapping(value = "/hot")
    public FebsResponse hot() {
        return aiProductCategoryService.hot();
    }
    @ApiOperation(value = "分类列表", notes = "分类列表")
    @ApiResponses({
            @ApiResponse(code = 200, message = "success", response = ApiProductCategoryVo.class)
    })
    @PostMapping(value = "/list")
    public FebsResponse list(@RequestBody @Validated ApiProductCategoryPageDto dto) {
        return aiProductCategoryService.categoryList(dto);
    }
}
src/main/java/cc/mrbird/febs/ai/controller/productPoint/ApiProductPointController.java
New file
@@ -0,0 +1,44 @@
package cc.mrbird.febs.ai.controller.productPoint;
import cc.mrbird.febs.ai.req.product.ApiProductInfoDto;
import cc.mrbird.febs.ai.req.productPoint.ApiProductPointInfoDto;
import cc.mrbird.febs.ai.res.product.ApiProductInfoVo;
import cc.mrbird.febs.ai.res.productPoint.ApiProductPointInfoVo;
import cc.mrbird.febs.ai.service.AiProductPointService;
import cc.mrbird.febs.common.entity.FebsResponse;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
 * @author Administrator
 */
@Slf4j
@Validated
@RestController
@RequiredArgsConstructor
@RequestMapping(value = "/api/ai/productPoint")
@Api(value = "ApiProductPointController", tags = "AI-产品知识点")
public class ApiProductPointController {
    private final AiProductPointService aiProductPointService;
    @ApiOperation(value = "知识点详情", notes = "知识点详情")
    @ApiResponses({
            @ApiResponse(code = 200, message = "success", response = ApiProductPointInfoVo.class)
    })
    @PostMapping(value = "/info")
    public FebsResponse info(@RequestBody @Validated ApiProductPointInfoDto dto) {
        return aiProductPointService.productPointInfo(dto);
    }
}
src/main/java/cc/mrbird/febs/ai/mapper/AiProductCategoryMapper.java
@@ -1,7 +1,11 @@
package cc.mrbird.febs.ai.mapper;
import cc.mrbird.febs.ai.entity.AiProductCategory;
import cc.mrbird.febs.ai.req.productCategory.ApiProductCategoryPageDto;
import cc.mrbird.febs.ai.res.productCategory.ApiProductCategoryVo;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.ibatis.annotations.Param;
/**
 * AI产品类别 Mapper接口
@@ -11,4 +15,5 @@
 */
public interface AiProductCategoryMapper extends BaseMapper<AiProductCategory> {
    Page<ApiProductCategoryVo> selectPageListByQuery(Page<ApiProductCategoryVo> page, @Param("record")ApiProductCategoryPageDto dto);
}
src/main/java/cc/mrbird/febs/ai/mapper/AiProductMapper.java
@@ -1,7 +1,11 @@
package cc.mrbird.febs.ai.mapper;
import cc.mrbird.febs.ai.entity.AiProduct;
import cc.mrbird.febs.ai.req.product.ApiProductPageDto;
import cc.mrbird.febs.ai.res.product.ApiProductVo;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.ibatis.annotations.Param;
/**
 * AI产品表 Mapper接口
@@ -11,4 +15,5 @@
 */
public interface AiProductMapper extends BaseMapper<AiProduct> {
    Page<ApiProductVo> selectPageListByQuery(Page<ApiProductVo> page, @Param("record") ApiProductPageDto dto);
}
src/main/java/cc/mrbird/febs/ai/req/product/ApiProductInfoDto.java
New file
@@ -0,0 +1,20 @@
package cc.mrbird.febs.ai.req.product;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
/**
 * @author Administrator
 */
@Data
@ApiModel(value = "ApiProductInfoDto", description = "参数")
public class ApiProductInfoDto {
    @NotBlank(message = "ID不能为空")
    @ApiModelProperty(value = "产品ID", example = "10")
    private String id;
}
src/main/java/cc/mrbird/febs/ai/req/product/ApiProductPageDto.java
New file
@@ -0,0 +1,29 @@
package cc.mrbird.febs.ai.req.product;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
/**
 * @author Administrator
 */
@Data
@ApiModel(value = "ApiProductPageDto", description = "参数")
public class ApiProductPageDto {
    @NotNull(message = "页码不能为空")
    @ApiModelProperty(value = "页码", example = "1")
    private Integer pageNow;
    @NotNull(message = "每页数量不能为空")
    @ApiModelProperty(value = "每页数量", example = "10")
    private Integer pageSize;
    @ApiModelProperty(value = "分类ID", example = "123")
    private String categoryId;
    @ApiModelProperty(value = "角色ID", example = "123")
    private String memberRoleId;
}
src/main/java/cc/mrbird/febs/ai/req/productCategory/ApiProductCategoryPageDto.java
New file
@@ -0,0 +1,27 @@
package cc.mrbird.febs.ai.req.productCategory;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
/**
 * @author Administrator
 */
@Data
@ApiModel(value = "ApiProductCategoryPageDto", description = "参数")
public class ApiProductCategoryPageDto {
    @NotNull(message = "页码不能为空")
    @ApiModelProperty(value = "页码", example = "1")
    private Integer pageNow;
    @NotNull(message = "每页数量不能为空")
    @ApiModelProperty(value = "每页数量", example = "10")
    private Integer pageSize;
    @ApiModelProperty(value = "查询名称", example = "123")
    private String query;
}
src/main/java/cc/mrbird/febs/ai/req/productPoint/ApiProductPointInfoDto.java
New file
@@ -0,0 +1,20 @@
package cc.mrbird.febs.ai.req.productPoint;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotBlank;
/**
 * @author Administrator
 */
@Data
@ApiModel(value = "ApiProductPointInfoDto", description = "参数")
public class ApiProductPointInfoDto {
    @NotBlank(message = "ID不能为空")
    @ApiModelProperty(value = "产品知识点ID", example = "10")
    private String id;
}
src/main/java/cc/mrbird/febs/ai/res/product/ApiProductInfoVo.java
New file
@@ -0,0 +1,68 @@
package cc.mrbird.febs.ai.res.product;
import cc.mrbird.febs.ai.res.productPoint.ApiProductPointVo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.List;
/**
 * @author Administrator
 */
@Data
@ApiModel(value = "ApiProductInfoVo", description = "参数")
public class ApiProductInfoVo {
    @ApiModelProperty(value = "ID")
    private String id;
    @ApiModelProperty(value = "分类ID")
    private String productCategoryId;
    /**
     * 名称
     */
    @ApiModelProperty(value = "ID")
    private String name;
    /**
     * 场景(可以根据场景生成prompt提示词)
     */
    @ApiModelProperty(value = "场景")
    private String scene;
    /**
     * 目标
     */
    @ApiModelProperty(value = "目标")
    private String target;
    /**
     * 背景图片
     */
    @ApiModelProperty(value = "背景图片")
    private String backImg;
    /**
     * 小图标
     */
    @ApiModelProperty(value = "小图标")
    private String iconImg;
    /**
     * 描述
     */
    @ApiModelProperty(value = "描述")
    private String description;
    /**
     * 每次出题数量
     */
    @ApiModelProperty(value = "每次出题数量")
    private Integer questionCount;
    @ApiModelProperty(value = "知识点")
    private List<ApiProductPointVo> productPointList;
}
src/main/java/cc/mrbird/febs/ai/res/product/ApiProductVo.java
New file
@@ -0,0 +1,28 @@
package cc.mrbird.febs.ai.res.product;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
 * @author Administrator
 */
@Data
@ApiModel(value = "ApiProductVo", description = "参数")
public class ApiProductVo {
    @ApiModelProperty(value = "ID")
    private String id;
    /**
     * 名称
     */
    @ApiModelProperty(value = "ID")
    private String name;
    /**
     * 目标
     */
    @ApiModelProperty(value = "ID")
    private String target;
}
src/main/java/cc/mrbird/febs/ai/res/productCategory/ApiProductCategoryVo.java
New file
@@ -0,0 +1,35 @@
package cc.mrbird.febs.ai.res.productCategory;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
 * @author Administrator
 */
@Data
@ApiModel(value = "ApiProductCategoryVo", description = "参数")
public class ApiProductCategoryVo {
    @ApiModelProperty(value = "ID")
    private String id;
    /**
     * 名称
     */
    @ApiModelProperty(value = "名称")
    private String name;
    /**
     * 背景图片
     */
    @ApiModelProperty(value = "背景图片")
    private String backImg;
    /**
     * 小图标
     */
    @ApiModelProperty(value = "小图标")
    private String iconImg;
}
src/main/java/cc/mrbird/febs/ai/res/productPoint/ApiProductPointInfoVo.java
New file
@@ -0,0 +1,45 @@
package cc.mrbird.febs.ai.res.productPoint;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
 * @author Administrator
 */
@Data
@ApiModel(value = "ApiProductPointInfoVo", description = "参数")
public class ApiProductPointInfoVo {
    /**
     * 类型1:普通内容  2:视频号内容
     */
    @ApiModelProperty(value = "类型1:普通内容  2:视频号内容")
    private Integer isNormal;
    /**
     * 视频号 id,以"sph"开头的id,可在视频号助手获取
     */
    @ApiModelProperty(value = "视频号 id")
    private String finderUserName;
    /**
     * 视频 feedId
     */
    @ApiModelProperty(value = "视频 feedId")
    private String feedId;
    /**
     * 标题
     */
    @ApiModelProperty(value = "标题")
    private String title;
    /**
     * 描述
     */
    @ApiModelProperty(value = "描述")
    private String description;
}
src/main/java/cc/mrbird/febs/ai/res/productPoint/ApiProductPointVo.java
New file
@@ -0,0 +1,22 @@
package cc.mrbird.febs.ai.res.productPoint;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
 * @author Administrator
 */
@Data
@ApiModel(value = "ApiProductPointVo", description = "参数")
public class ApiProductPointVo {
    @ApiModelProperty(value = "知识点ID")
    private String id;
    /**
     * 名称
     */
    @ApiModelProperty(value = "名称")
    private String title;
}
src/main/java/cc/mrbird/febs/ai/service/AiMemberRoleService.java
@@ -18,4 +18,6 @@
    List<AiMemberRole> getListByQuery(LambdaQueryWrapper<AiMemberRole> query);
    FebsResponse memberRoleList();
    String getDefaultMemberRoleId();
}
src/main/java/cc/mrbird/febs/ai/service/AiProductCategoryService.java
@@ -1,6 +1,12 @@
package cc.mrbird.febs.ai.service;
import cc.mrbird.febs.ai.entity.AiProductCategory;
import cc.mrbird.febs.ai.req.productCategory.ApiProductCategoryPageDto;
import cc.mrbird.febs.ai.res.productCategory.ApiProductCategoryVo;
import cc.mrbird.febs.common.entity.FebsResponse;
import cc.mrbird.febs.mall.vo.ApiActivityInfoVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;
@@ -13,4 +19,13 @@
public interface AiProductCategoryService extends IService<AiProductCategory> {
    List<AiProductCategory> getListByQuery(LambdaQueryWrapper<AiProductCategory> query);
    Page<ApiProductCategoryVo> getPageListByQuery(Page<ApiProductCategoryVo> page , ApiProductCategoryPageDto dto);
    FebsResponse hot();
    FebsResponse categoryList(ApiProductCategoryPageDto dto);
    String getDefaultProductCategoryId();
}
src/main/java/cc/mrbird/febs/ai/service/AiProductPointLinkService.java
@@ -1,10 +1,16 @@
package cc.mrbird.febs.ai.service;
import cc.mrbird.febs.ai.entity.AiProductPointLink;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;
/**
 * @author Administrator
 */
public interface AiProductPointLinkService extends IService<AiProductPointLink> {
    List<AiProductPointLink> getListByProductId(LambdaQueryWrapper<AiProductPointLink> pointLinkQUery);
}
src/main/java/cc/mrbird/febs/ai/service/AiProductPointService.java
@@ -1,8 +1,12 @@
package cc.mrbird.febs.ai.service;
import cc.mrbird.febs.ai.entity.AiProductPoint;
import cc.mrbird.febs.ai.req.productPoint.ApiProductPointInfoDto;
import cc.mrbird.febs.ai.res.productPoint.ApiProductPointVo;
import cc.mrbird.febs.common.entity.FebsResponse;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;
import java.util.Set;
/**
 * AI产品知识点 Service接口
@@ -11,6 +15,11 @@
 * @date 2025-07-29
 */
public interface AiProductPointService extends IService<AiProductPoint> {
    AiProductPoint getById(String id);
    List<AiProductPoint> getListByPointIds(Set<String> collect);
    List<ApiProductPointVo> listByProductId(String productId);
    FebsResponse productPointInfo(ApiProductPointInfoDto dto);
}
src/main/java/cc/mrbird/febs/ai/service/AiProductService.java
@@ -1,6 +1,13 @@
package cc.mrbird.febs.ai.service;
import cc.mrbird.febs.ai.entity.AiProduct;
import cc.mrbird.febs.ai.req.product.ApiProductInfoDto;
import cc.mrbird.febs.ai.req.product.ApiProductPageDto;
import cc.mrbird.febs.ai.req.productCategory.ApiProductCategoryPageDto;
import cc.mrbird.febs.ai.res.product.ApiProductVo;
import cc.mrbird.febs.ai.res.productCategory.ApiProductCategoryVo;
import cc.mrbird.febs.common.entity.FebsResponse;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;
@@ -11,4 +18,12 @@
 * @date 2025-07-29
 */
public interface AiProductService extends IService<AiProduct> {
    AiProduct getById(String id);
    Page<ApiProductVo> getPageListByQuery(Page<ApiProductVo> page , ApiProductPageDto dto);
    FebsResponse productList(ApiProductPageDto dto);
    FebsResponse productInfo(ApiProductInfoDto dto);
}
src/main/java/cc/mrbird/febs/ai/service/impl/AiMemberRoleServiceImpl.java
@@ -55,4 +55,19 @@
        }
        return new FebsResponse().success().data(list);
    }
    @Override
    public String getDefaultMemberRoleId() {
        LambdaQueryWrapper<AiMemberRole> queryWrapper = Wrappers.lambdaQuery(AiMemberRole.class);
        queryWrapper.eq(AiMemberRole::getState, 1);
        queryWrapper.orderByAsc(AiMemberRole::getCreatedTime);
        queryWrapper.last("limit 1");
        List<AiMemberRole> listByQuery = this.getListByQuery(queryWrapper);
        if (CollUtil.isNotEmpty(listByQuery)){
            for (AiMemberRole aiMemberRole : listByQuery){
                    return aiMemberRole.getId();
            }
        }
        return null;
    }
}
src/main/java/cc/mrbird/febs/ai/service/impl/AiProductCategoryServiceImpl.java
@@ -2,14 +2,22 @@
import cc.mrbird.febs.ai.entity.AiProductCategory;
import cc.mrbird.febs.ai.mapper.AiProductCategoryMapper;
import cc.mrbird.febs.ai.req.productCategory.ApiProductCategoryPageDto;
import cc.mrbird.febs.ai.res.productCategory.ApiProductCategoryVo;
import cc.mrbird.febs.ai.service.AiProductCategoryService;
import cc.mrbird.febs.common.entity.FebsResponse;
import cc.mrbird.febs.mall.vo.ApiActivityInfoVo;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.List;
/**
@@ -26,4 +34,58 @@
    private final AiProductCategoryMapper aiProductCategoryMapper;
    @Override
    public List<AiProductCategory> getListByQuery(LambdaQueryWrapper<AiProductCategory> query) {
        return aiProductCategoryMapper.selectList(query);
    }
    @Override
    public Page<ApiProductCategoryVo> getPageListByQuery(Page<ApiProductCategoryVo> page , ApiProductCategoryPageDto dto) {
        return aiProductCategoryMapper.selectPageListByQuery(page,dto);
    }
    @Override
    public FebsResponse hot() {
        List<ApiProductCategoryVo> list = new ArrayList<>();
        LambdaQueryWrapper<AiProductCategory> query = Wrappers.lambdaQuery(AiProductCategory.class);
        query.eq(AiProductCategory::getState, 1);
        query.eq(AiProductCategory::getHotState, 1);
        query.orderByAsc(AiProductCategory::getSort);
        List<AiProductCategory> listByQuery = this.getListByQuery(query);
        if (CollUtil.isNotEmpty(listByQuery)){
            for (AiProductCategory aiProductCategory : listByQuery){
                ApiProductCategoryVo apiProductCategoryVo = new ApiProductCategoryVo();
                apiProductCategoryVo.setId(aiProductCategory.getId());
                apiProductCategoryVo.setName(aiProductCategory.getName());
                apiProductCategoryVo.setBackImg(aiProductCategory.getBackImg());
                apiProductCategoryVo.setIconImg(aiProductCategory.getIconImg());
                list.add(apiProductCategoryVo);
            }
        }
        return new FebsResponse().success().data(list);
    }
    @Override
    public FebsResponse categoryList(ApiProductCategoryPageDto dto) {
        // 创建分页对象,传入当前页和每页大小
        Page<ApiProductCategoryVo> page = new Page<>(dto.getPageNow(), dto.getPageSize());
        Page<ApiProductCategoryVo> pageListByQuery = this.getPageListByQuery(page, dto);
        return new FebsResponse().success().data(pageListByQuery);
    }
    @Override
    public String getDefaultProductCategoryId() {
        LambdaQueryWrapper<AiProductCategory> query = Wrappers.lambdaQuery(AiProductCategory.class);
        query.eq(AiProductCategory::getState, 1);
        query.eq(AiProductCategory::getHotState, 1);
        query.orderByAsc(AiProductCategory::getSort);
        query.last("limit 1");
        List<AiProductCategory> listByQuery = this.getListByQuery(query);
        if (CollUtil.isNotEmpty(listByQuery)){
            return listByQuery.get(0).getId();
        }
        return null;
    }
}
src/main/java/cc/mrbird/febs/ai/service/impl/AiProductPointLinkServiceImpl.java
@@ -3,10 +3,13 @@
import cc.mrbird.febs.ai.entity.AiProductPointLink;
import cc.mrbird.febs.ai.mapper.AiProductPointLinkMapper;
import cc.mrbird.febs.ai.service.AiProductPointLinkService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
/**
 * @author Administrator
@@ -16,4 +19,10 @@
@Transactional
public class AiProductPointLinkServiceImpl extends ServiceImpl<AiProductPointLinkMapper, AiProductPointLink> implements AiProductPointLinkService {
    private final AiProductPointLinkMapper aiProductPointLinkMapper;
    @Override
    public List<AiProductPointLink> getListByProductId(LambdaQueryWrapper<AiProductPointLink> pointLinkQUery) {
        return aiProductPointLinkMapper.selectList(pointLinkQUery);
    }
}
src/main/java/cc/mrbird/febs/ai/service/impl/AiProductPointServiceImpl.java
@@ -1,16 +1,28 @@
package cc.mrbird.febs.ai.service.impl;
import cc.mrbird.febs.ai.entity.AiProductPoint;
import cc.mrbird.febs.ai.entity.AiProductPointLink;
import cc.mrbird.febs.ai.mapper.AiProductPointMapper;
import cc.mrbird.febs.ai.req.productPoint.ApiProductPointInfoDto;
import cc.mrbird.febs.ai.res.productPoint.ApiProductPointInfoVo;
import cc.mrbird.febs.ai.res.productPoint.ApiProductPointVo;
import cc.mrbird.febs.ai.service.AiProductPointLinkService;
import cc.mrbird.febs.ai.service.AiProductPointService;
import cc.mrbird.febs.common.entity.FebsResponse;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
/**
 * AI产品知识点 Service实现类
@@ -24,6 +36,55 @@
public class AiProductPointServiceImpl extends ServiceImpl<AiProductPointMapper, AiProductPoint> implements AiProductPointService {
    private final AiProductPointMapper aiProductPointMapper;
    private final AiProductPointLinkService aiProductPointLinkService;
    @Override
    public AiProductPoint getById(String id) {
        return aiProductPointMapper.selectById( id);
    }
    @Override
    public List<AiProductPoint> getListByPointIds(Set<String> collect) {
        return aiProductPointMapper.selectBatchIds( collect);
    }
    @Override
    public List<ApiProductPointVo> listByProductId(String productId) {
        List<ApiProductPointVo> vos = new ArrayList<>();
        LambdaQueryWrapper<AiProductPointLink> pointLinkQUery = Wrappers.lambdaQuery(AiProductPointLink.class);
        pointLinkQUery.eq(AiProductPointLink::getProductId, productId);
        List<AiProductPointLink> linkList = aiProductPointLinkService.getListByProductId(pointLinkQUery);
        if (CollUtil.isEmpty(linkList)){
            return vos;
        }
        Set<String> collect = linkList.stream().map(AiProductPointLink::getProductPointId).collect(Collectors.toSet());
        List<AiProductPoint> list = this.getListByPointIds(collect);
        if (CollUtil.isEmpty(list)){
            return vos;
        }
        for (AiProductPoint point : list){
            ApiProductPointVo vo = new ApiProductPointVo();
            vo.setId(point.getId());
            vo.setTitle(point.getTitle());
            vos.add(vo);
        }
        return vos;
    }
    @Override
    public FebsResponse productPointInfo(ApiProductPointInfoDto dto) {
        ApiProductPointInfoVo apiProductPointInfoVo = new ApiProductPointInfoVo();
        String id = dto.getId();
        AiProductPoint entity = this.getById(id);
        if (ObjectUtil.isNotNull( entity)){
            apiProductPointInfoVo.setIsNormal(entity.getIsNormal());
            apiProductPointInfoVo.setFinderUserName(entity.getFinderUserName());
            apiProductPointInfoVo.setFeedId(entity.getFeedId());
            apiProductPointInfoVo.setTitle(entity.getTitle());
            apiProductPointInfoVo.setDescription(entity.getDescription());
        }
        return new FebsResponse().success().data(apiProductPointInfoVo);
    }
}
src/main/java/cc/mrbird/febs/ai/service/impl/AiProductServiceImpl.java
@@ -1,16 +1,20 @@
package cc.mrbird.febs.ai.service.impl;
import cc.mrbird.febs.ai.entity.AiProduct;
import cc.mrbird.febs.ai.entity.AiProductPoint;
import cc.mrbird.febs.ai.mapper.AiProductMapper;
import cc.mrbird.febs.ai.service.AiProductService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import cc.mrbird.febs.ai.req.product.ApiProductInfoDto;
import cc.mrbird.febs.ai.req.product.ApiProductPageDto;
import cc.mrbird.febs.ai.res.product.ApiProductInfoVo;
import cc.mrbird.febs.ai.res.product.ApiProductVo;
import cc.mrbird.febs.ai.service.*;
import cc.mrbird.febs.common.entity.FebsResponse;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
/**
 * AI产品表 Service实现类
@@ -24,6 +28,56 @@
public class AiProductServiceImpl extends ServiceImpl<AiProductMapper, AiProduct> implements AiProductService {
    private final AiProductMapper aiProductMapper;
    private final AiMemberRoleService aiMemberRoleService;
    private final AiProductCategoryService aiProductCategoryService;
    private final AiProductPointService aiProductPointService;
    @Override
    public AiProduct getById(String id) {
        return aiProductMapper.selectById( id);
    }
    @Override
    public Page<ApiProductVo> getPageListByQuery(Page<ApiProductVo> page, ApiProductPageDto dto) {
        return aiProductMapper.selectPageListByQuery(page, dto);
    }
    @Override
    public FebsResponse productList(ApiProductPageDto dto) {
        if(StrUtil.isEmpty(dto.getMemberRoleId())){
            String memberRoleId = aiMemberRoleService.getDefaultMemberRoleId();
            dto.setMemberRoleId(memberRoleId);
        }
        if(StrUtil.isEmpty(dto.getCategoryId())){
            String categoryId = aiProductCategoryService.getDefaultProductCategoryId();
            dto.setCategoryId(categoryId);
        }
        // 创建分页对象,传入当前页和每页大小
        Page<ApiProductVo> page = new Page<>(dto.getPageNow(), dto.getPageSize());
        Page<ApiProductVo> pageListByQuery = this.getPageListByQuery(page, dto);
        return new FebsResponse().success().data(pageListByQuery);
    }
    @Override
    public FebsResponse productInfo(ApiProductInfoDto dto) {
        String id = dto.getId();
        AiProduct entity = this.getById(id);
        ApiProductInfoVo vo = new ApiProductInfoVo();
        vo.setId(entity.getId());
        vo.setProductCategoryId(entity.getProductCategoryId());
        vo.setName(entity.getName());
        vo.setScene(entity.getScene());
        vo.setTarget(entity.getTarget());
        vo.setBackImg(entity.getBackImg());
        vo.setIconImg(entity.getIconImg());
        vo.setDescription(entity.getDescription());
        vo.setQuestionCount(entity.getQuestionCount());
        vo.setProductPointList(aiProductPointService.listByProductId(id));
        return new FebsResponse().success().data(vo);
    }
}
src/main/java/cc/mrbird/febs/common/configure/WebMvcConfigure.java
@@ -47,6 +47,8 @@
        registration.excludePathPatterns("/api/clothes/social/allComment");
        registration.excludePathPatterns("/api/clothes/social/socialInfo");
        registration.excludePathPatterns("/api/clothes/clothesType");
        registration.excludePathPatterns("/api/ai/**");
        registration.excludePathPatterns("/api/ai/memberRole/**");
        registration.excludePathPatterns("/api/ai/productCategory/**");
        registration.excludePathPatterns("/api/ai/product/**");
    }
}
src/main/resources/mapper/modules/AiProductCategoryMapper.xml
@@ -1,4 +1,16 @@
<?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="cc.mrbird.febs.ai.mapper.AiProductCategoryMapper">
    <select id="selectPageListByQuery" resultType="cc.mrbird.febs.ai.res.productCategory.ApiProductCategoryVo">
        select
            a.id as id,
            a.name as name,
            a.back_img as backImg,
            a.icon_img as iconImg
        from ai_product_category a
        where
            a.state = 1
        order by a.sort asc
    </select>
</mapper>
src/main/resources/mapper/modules/AiProductMapper.xml
@@ -1,4 +1,26 @@
<?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="cc.mrbird.febs.ai.mapper.AiProductMapper">
    <select id="selectPageListByQuery" resultType="cc.mrbird.febs.ai.res.product.ApiProductVo">
        select
            a.id as id,
            a.name as name,
            a.target as target
        from ai_product a
        <where>
            a.state = 1
            <if test="record != null">
                <if test="record.categoryId != null and record.categoryId != ''">
                    and a.product_category_id=#{record.categoryId}
                </if>
                <if test="record.memberRoleId != null and record.memberRoleId != ''">
                    and a.id in (
                        select product_id from ai_member_role_product where role_id = #{record.memberRoleId}
                    )
                </if>
            </if>
        </where>
        order by a.sort asc
    </select>
</mapper>