feat(ai): 添加 AI 产品相关接口和功能
- 新增 AiProductCategory、AiProduct、AiProductPoint 相关的 Controller、Service 和 Mapper
- 实现了产品分类、产品列表、产品详情、知识点详情等接口
- 优化了成员角色列表接口
- 调整了 WebMvc 配置,允许特定的 AI 相关请求
16 files modified
12 files added
| | |
| | | @ApiResponses({ |
| | | @ApiResponse(code = 200, message = "success", response = ApiMemberRoleVo.class) |
| | | }) |
| | | @GetMapping(value = "/memberRoleList") |
| | | public FebsResponse memberRoleList() { |
| | | @GetMapping(value = "/list") |
| | | public FebsResponse list() { |
| | | return aiMemberRoleService.memberRoleList(); |
| | | } |
| | | } |
New file |
| | |
| | | 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); |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | 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); |
| | | } |
| | | } |
New file |
| | |
| | | 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); |
| | | } |
| | | |
| | | } |
| | |
| | | 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接口 |
| | |
| | | */ |
| | | public interface AiProductCategoryMapper extends BaseMapper<AiProductCategory> { |
| | | |
| | | Page<ApiProductCategoryVo> selectPageListByQuery(Page<ApiProductCategoryVo> page, @Param("record")ApiProductCategoryPageDto dto); |
| | | } |
| | |
| | | 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接口 |
| | |
| | | */ |
| | | public interface AiProductMapper extends BaseMapper<AiProduct> { |
| | | |
| | | Page<ApiProductVo> selectPageListByQuery(Page<ApiProductVo> page, @Param("record") ApiProductPageDto dto); |
| | | } |
New file |
| | |
| | | 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; |
| | | } |
New file |
| | |
| | | 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; |
| | | } |
New file |
| | |
| | | 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; |
| | | |
| | | } |
New file |
| | |
| | | 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; |
| | | } |
New file |
| | |
| | | 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; |
| | | |
| | | } |
New file |
| | |
| | | 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; |
| | | |
| | | } |
New file |
| | |
| | | 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; |
| | | |
| | | } |
New file |
| | |
| | | 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; |
| | | |
| | | } |
New file |
| | |
| | | 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; |
| | | } |
| | |
| | | List<AiMemberRole> getListByQuery(LambdaQueryWrapper<AiMemberRole> query); |
| | | |
| | | FebsResponse memberRoleList(); |
| | | |
| | | String getDefaultMemberRoleId(); |
| | | } |
| | |
| | | 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; |
| | | |
| | |
| | | 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(); |
| | | } |
| | |
| | | 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); |
| | | } |
| | |
| | | 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接口 |
| | |
| | | * @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); |
| | | } |
| | |
| | | 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; |
| | | |
| | |
| | | * @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); |
| | | } |
| | |
| | | } |
| | | 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; |
| | | } |
| | | } |
| | |
| | | |
| | | 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; |
| | | |
| | | /** |
| | |
| | | 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; |
| | | } |
| | | } |
| | |
| | | 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 |
| | |
| | | @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); |
| | | } |
| | | } |
| | |
| | | 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实现类 |
| | |
| | | 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); |
| | | } |
| | | } |
| | |
| | | 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实现类 |
| | |
| | | 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); |
| | | } |
| | | } |
| | |
| | | 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/**");
|
| | | }
|
| | | }
|
| | |
| | | <?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> |
| | |
| | | <?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> |