From ccefddf89bae188faad02ed845c5f9756f121591 Mon Sep 17 00:00:00 2001
From: Administrator <15274802129@163.com>
Date: Wed, 30 Jul 2025 17:02:45 +0800
Subject: [PATCH] feat(ai): 添加 AI 用户答题记录和角色选择相关实体、Mapper 和 Service

---
 src/main/resources/mapper/modules/AiMemberAnswerItemMapper.xml                     |    4 
 src/main/java/cc/mrbird/febs/ai/service/impl/AiProductRoleServiceImpl.java         |  135 +
 src/main/resources/mapper/modules/AiMemberRoleCategoryMapper.xml                   |    4 
 src/main/java/cc/mrbird/febs/ai/mapper/AiMemberRoleProductMapper.java              |   14 
 src/main/java/cc/mrbird/febs/ai/mapper/AiMemberAnswerItemMapper.java               |   14 
 src/main/resources/mapper/modules/AiProductQuestionMapper.xml                      |    4 
 src/main/java/cc/mrbird/febs/ai/mapper/AiProductRoleMapper.java                    |   14 
 src/main/java/cc/mrbird/febs/ai/service/impl/AiMemberTalkServiceImpl.java          |  121 +
 src/main/resources/mapper/modules/AiMemberTalkItemMapper.xml                       |    4 
 src/main/resources/mapper/modules/AiProductQuestionLinkMapper.xml                  |    4 
 src/main/java/cc/mrbird/febs/ai/mapper/AiMemberRoleCategoryMapper.java             |   14 
 src/main/java/cc/mrbird/febs/ai/mapper/AiProductMapper.java                        |   14 
 src/main/java/cc/mrbird/febs/ai/mapper/AiProductQuestionLinkMapper.java            |   14 
 src/main/java/cc/mrbird/febs/ai/service/AiMemberRoleProductService.java            |  100 +
 src/main/java/cc/mrbird/febs/ai/entity/AiMemberRoleCategory.java                   |   31 
 src/main/resources/mapper/modules/AiProductPointMapper.xml                         |    4 
 src/main/java/cc/mrbird/febs/ai/service/AiProductPointService.java                 |  106 +
 src/main/java/cc/mrbird/febs/ai/service/impl/AiProductPointServiceImpl.java        |  153 ++
 src/main/java/cc/mrbird/febs/ai/entity/AiMemberRoleProduct.java                    |   30 
 src/main/java/cc/mrbird/febs/ai/mapper/AiMemberAnswerMapper.java                   |   14 
 src/main/java/cc/mrbird/febs/ai/service/impl/AiMemberRoleProductServiceImpl.java   |  145 ++
 src/main/java/cc/mrbird/febs/ai/entity/AiMemberTalkItem.java                       |   40 
 src/main/java/cc/mrbird/febs/ai/service/AiMemberTalkItemService.java               |   77 +
 src/main/java/cc/mrbird/febs/ai/service/AiProductQuestionService.java              |  128 +
 src/main/java/cc/mrbird/febs/ai/service/AiProductService.java                      |  114 +
 src/main/java/cc/mrbird/febs/ai/service/AiProductCategoryService.java              |  113 +
 src/main/java/cc/mrbird/febs/ai/service/impl/AiProductQuestionLinkServiceImpl.java |  180 ++
 src/main/java/cc/mrbird/febs/ai/entity/AiMemberAnswer.java                         |   51 
 src/main/java/cc/mrbird/febs/ai/entity/AiProduct.java                              |   80 +
 src/main/java/cc/mrbird/febs/ai/service/impl/AiMemberRoleServiceImpl.java          |  129 +
 src/main/java/cc/mrbird/febs/ai/entity/AiProductPoint.java                         |   45 
 src/main/resources/mapper/modules/AiMemberRoleProductMapper.xml                    |    4 
 src/main/resources/mapper/modules/AiProductCategoryMapper.xml                      |    4 
 src/main/resources/mapper/modules/AiProductMapper.xml                              |    4 
 src/main/java/cc/mrbird/febs/ai/service/impl/AiProductServiceImpl.java             |  161 ++
 src/main/java/cc/mrbird/febs/ai/mapper/AiProductPointMapper.java                   |   14 
 src/main/java/cc/mrbird/febs/ai/mapper/AiMemberTalkMapper.java                     |   14 
 src/main/java/cc/mrbird/febs/ai/mapper/AiProductQuestionMapper.java                |   14 
 src/main/resources/mapper/modules/AiMemberAnswerMapper.xml                         |    4 
 src/main/java/cc/mrbird/febs/ai/service/impl/AiMemberRoleCategoryServiceImpl.java  |  145 ++
 src/main/java/cc/mrbird/febs/ai/entity/AiProductQuestionLink.java                  |   30 
 src/main/java/cc/mrbird/febs/ai/mapper/AiProductCategoryMapper.java                |   14 
 src/main/java/cc/mrbird/febs/ai/service/impl/AiMemberAnswerServiceImpl.java        |  148 ++
 src/main/java/cc/mrbird/febs/ai/service/AiProductQuestionLinkService.java          |  123 +
 src/main/java/cc/mrbird/febs/ai/entity/AiProductCategory.java                      |   55 
 src/main/resources/mapper/modules/AiMemberTalkMapper.xml                           |    4 
 src/main/java/cc/mrbird/febs/common/entity/AiBaseEntity.java                       |   35 
 src/main/java/cc/mrbird/febs/ai/service/AiMemberAnswerService.java                 |  108 +
 src/main/java/cc/mrbird/febs/ai/entity/AiProductQuestion.java                      |   61 
 src/main/java/cc/mrbird/febs/ai/service/AiMemberTalkService.java                   |   84 +
 src/main/java/cc/mrbird/febs/ai/service/impl/AiProductQuestionServiceImpl.java     |  176 ++
 src/main/java/cc/mrbird/febs/ai/service/impl/AiMemberAnswerItemServiceImpl.java    |  154 ++
 src/main/java/cc/mrbird/febs/ai/entity/AiProductRole.java                          |   45 
 src/main/java/cc/mrbird/febs/ai/service/AiProductRoleService.java                  |   92 +
 src/main/java/cc/mrbird/febs/ai/service/AiMemberRoleService.java                   |   92 +
 src/main/java/cc/mrbird/febs/ai/service/impl/AiMemberTalkItemServiceImpl.java      |  113 +
 src/main/java/cc/mrbird/febs/ai/service/impl/AiProductCategoryServiceImpl.java     |  161 ++
 src/main/java/cc/mrbird/febs/ai/service/AiMemberAnswerItemService.java             |  113 +
 src/main/java/cc/mrbird/febs/ai/entity/AiMemberAnswerItem.java                     |   86 +
 src/main/java/cc/mrbird/febs/ai/mapper/AiMemberRoleMapper.java                     |   14 
 src/main/java/cc/mrbird/febs/ai/entity/AiMemberTalk.java                           |   36 
 src/main/java/cc/mrbird/febs/ai/mapper/AiMemberTalkItemMapper.java                 |   14 
 src/main/java/cc/mrbird/febs/ai/service/AiMemberRoleCategoryService.java           |  100 +
 src/main/resources/mapper/modules/AiProductRoleMapper.xml                          |    4 
 src/main/java/cc/mrbird/febs/ai/entity/AiMemberRole.java                           |   41 
 65 files changed, 4,167 insertions(+), 0 deletions(-)

diff --git a/src/main/java/cc/mrbird/febs/ai/entity/AiMemberAnswer.java b/src/main/java/cc/mrbird/febs/ai/entity/AiMemberAnswer.java
new file mode 100644
index 0000000..9802f21
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/ai/entity/AiMemberAnswer.java
@@ -0,0 +1,51 @@
+package cc.mrbird.febs.ai.entity;
+
+import cc.mrbird.febs.common.entity.AiBaseEntity;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+/**
+ * AI用户答题记录
+ *
+ * @author yourname
+ * @date 2025-07-29
+ */
+@Data
+@TableName("ai_member_answer")
+public class AiMemberAnswer extends AiBaseEntity {
+
+    /**
+     * 公司ID (UUID)
+     */
+    private String companyId;
+
+    /**
+     * AI产品ID (UUID)
+     */
+    private String productId;
+
+    /**
+     * 用户ID (UUID)
+     */
+    private String memberId;
+
+    /**
+     * 状态 0-进行中 1-已结束
+     */
+    private Integer state;
+
+    /**
+     * 评分
+     */
+    private Integer score;
+
+    /**
+     * 题目数量
+     */
+    private Integer questionCnt;
+
+    /**
+     * 正确数量
+     */
+    private Integer correctCnt;
+}
diff --git a/src/main/java/cc/mrbird/febs/ai/entity/AiMemberAnswerItem.java b/src/main/java/cc/mrbird/febs/ai/entity/AiMemberAnswerItem.java
new file mode 100644
index 0000000..e040fa6
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/ai/entity/AiMemberAnswerItem.java
@@ -0,0 +1,86 @@
+package cc.mrbird.febs.ai.entity;
+
+import cc.mrbird.febs.common.entity.AiBaseEntity;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+/**
+ * AI用户答题记录子表
+ *
+ * @author yourname
+ * @date 2025-07-29
+ */
+@Data
+@TableName("ai_member_answer_item")
+public class AiMemberAnswerItem extends AiBaseEntity {
+
+    /**
+     * AI用户答题记录ID (UUID)
+     */
+    private String answerId;
+
+    /**
+     * 公司ID (UUID)
+     */
+    private String companyId;
+
+    /**
+     * AI产品ID (UUID)
+     */
+    private String productId;
+
+    /**
+     * 用户ID (UUID)
+     */
+    private String memberId;
+
+    /**
+     * AI产品题目父ID,父ID相同,表示是同一个题目 (UUID)
+     */
+    private String productQuestionParentId;
+
+    /**
+     * AI产品题目ID (UUID)
+     */
+    private String productQuestionId;
+
+    /**
+     * 题目
+     */
+    private String title;
+
+    /**
+     * 答案
+     */
+    private String answer;
+
+    /**
+     * 是否是正确答案 0-否 1-是
+     */
+    private Integer correctAnswer;
+
+    /**
+     * 答案解析
+     */
+    private String answerAnalysis;
+
+    /**
+     * 难度:1-简单,2-中等,3-困难
+     */
+    private Integer difficulty;
+
+    /**
+     * 用户回答的答案(问题ID) (UUID)
+     */
+    private String memberAnswerQuestionId;
+
+    /**
+     * 用户回答状态 0-未回答 1-答对了 2-答错了
+     */
+    private Integer memberAnswerState;
+
+    /**
+     * 是否加入错题集:0-否,1-是
+     */
+    private Integer isCollected;
+}
diff --git a/src/main/java/cc/mrbird/febs/ai/entity/AiMemberRole.java b/src/main/java/cc/mrbird/febs/ai/entity/AiMemberRole.java
new file mode 100644
index 0000000..c169494
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/ai/entity/AiMemberRole.java
@@ -0,0 +1,41 @@
+package cc.mrbird.febs.ai.entity;
+
+import cc.mrbird.febs.common.entity.AiBaseEntity;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+/**
+ * AI用户选择角色表
+ *
+ * @author yourname
+ * @date 2025-07-29
+ */
+@Data
+@TableName("ai_member_role")
+public class AiMemberRole extends AiBaseEntity {
+
+    /**
+     * 公司ID (UUID)
+     */
+    private String companyId;
+
+    /**
+     * 编码
+     */
+    private String code;
+
+    /**
+     * 名称
+     */
+    private String name;
+
+    /**
+     * 小图标
+     */
+    private String iconImg;
+
+    /**
+     * 状态 0-禁用 1-启用 2-已删除
+     */
+    private Integer state;
+}
diff --git a/src/main/java/cc/mrbird/febs/ai/entity/AiMemberRoleCategory.java b/src/main/java/cc/mrbird/febs/ai/entity/AiMemberRoleCategory.java
new file mode 100644
index 0000000..2a94e33
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/ai/entity/AiMemberRoleCategory.java
@@ -0,0 +1,31 @@
+package cc.mrbird.febs.ai.entity;
+
+import cc.mrbird.febs.common.entity.AiBaseEntity;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+/**
+ * AI用户选择角色关联产品分类
+ *
+ * @author yourname
+ * @date 2025-07-29
+ */
+@Data
+@TableName("ai_member_role_category")
+public class AiMemberRoleCategory extends AiBaseEntity {
+
+    /**
+     * 公司ID (UUID)
+     */
+    private String companyId;
+
+    /**
+     * 角色ID (UUID)
+     */
+    private String roleId;
+
+    /**
+     * 产品分类ID (UUID)
+     */
+    private String productCategoryId;
+}
diff --git a/src/main/java/cc/mrbird/febs/ai/entity/AiMemberRoleProduct.java b/src/main/java/cc/mrbird/febs/ai/entity/AiMemberRoleProduct.java
new file mode 100644
index 0000000..fae52e5
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/ai/entity/AiMemberRoleProduct.java
@@ -0,0 +1,30 @@
+package cc.mrbird.febs.ai.entity;
+
+import cc.mrbird.febs.common.entity.AiBaseEntity;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+/**
+ * AI用户选择角色关联产品
+ *
+ * @author yourname
+ * @date 2025-07-29
+ */
+@Data
+@TableName("ai_member_role_product")
+public class AiMemberRoleProduct extends AiBaseEntity {
+    /**
+     * 公司ID (UUID)
+     */
+    private String companyId;
+
+    /**
+     * 角色ID (UUID)
+     */
+    private String roleId;
+
+    /**
+     * 产品ID (UUID)
+     */
+    private String productId;
+}
diff --git a/src/main/java/cc/mrbird/febs/ai/entity/AiMemberTalk.java b/src/main/java/cc/mrbird/febs/ai/entity/AiMemberTalk.java
new file mode 100644
index 0000000..48ae0e4
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/ai/entity/AiMemberTalk.java
@@ -0,0 +1,36 @@
+package cc.mrbird.febs.ai.entity;
+
+import cc.mrbird.febs.common.entity.AiBaseEntity;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+/**
+ * AI用户对话训练记录
+ *
+ * @author yourname
+ * @date 2025-07-29
+ */
+@Data
+@TableName("ai_member_talk")
+public class AiMemberTalk extends AiBaseEntity {
+
+    /**
+     * 公司ID (UUID)
+     */
+    private String companyId;
+
+    /**
+     * AI产品ID (UUID)
+     */
+    private String productId;
+
+    /**
+     * AI产品陪练角色ID (UUID)
+     */
+    private String productRoleId;
+
+    /**
+     * 用户ID (UUID)
+     */
+    private String memberId;
+}
diff --git a/src/main/java/cc/mrbird/febs/ai/entity/AiMemberTalkItem.java b/src/main/java/cc/mrbird/febs/ai/entity/AiMemberTalkItem.java
new file mode 100644
index 0000000..b47a36f
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/ai/entity/AiMemberTalkItem.java
@@ -0,0 +1,40 @@
+package cc.mrbird.febs.ai.entity;
+
+import cc.mrbird.febs.common.entity.AiBaseEntity;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+/**
+ * AI用户对话训练记录子表
+ *
+ * @author yourname
+ * @date 2025-07-29
+ */
+@Data
+@TableName("ai_member_talk_item")
+public class AiMemberTalkItem extends AiBaseEntity {
+    /**
+     * 用户ID (UUID)
+     */
+    private String memberId;
+
+    /**
+     * 公司ID (UUID)
+     */
+    private String companyId;
+
+    /**
+     * 用户对话ID (UUID)
+     */
+    private String memberTalkId;
+
+    /**
+     * 类型 1-AI提问 2-用户回答 3-AI分析结果
+     */
+    private Integer type;
+
+    /**
+     * 内容
+     */
+    private String context;
+}
diff --git a/src/main/java/cc/mrbird/febs/ai/entity/AiProduct.java b/src/main/java/cc/mrbird/febs/ai/entity/AiProduct.java
new file mode 100644
index 0000000..e60a2be
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/ai/entity/AiProduct.java
@@ -0,0 +1,80 @@
+package cc.mrbird.febs.ai.entity;
+
+import cc.mrbird.febs.common.entity.AiBaseEntity;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+/**
+ * AI产品表
+ *
+ * @author yourname
+ * @date 2025-07-29
+ */
+@Data
+@TableName("ai_product")
+public class AiProduct extends AiBaseEntity {
+    /**
+     * 公司ID (UUID)
+     */
+    private String companyId;
+
+    /**
+     * 编码
+     */
+    private String code;
+
+    /**
+     * 名称
+     */
+    private String name;
+
+    /**
+     * 背景图片
+     */
+    private String backImg;
+
+    /**
+     * 小图标
+     */
+    private String iconImg;
+
+    /**
+     * 排序
+     */
+    private Integer sort;
+
+    /**
+     * 状态 0-禁用 1-启用 2-已删除
+     */
+    private Integer state;
+
+    /**
+     * 是否推荐到首页 1-推荐 0-不推荐
+     */
+    private Integer hotState;
+
+    /**
+     * AI产品类别ID (UUID)
+     */
+    private String productCategoryId;
+
+    /**
+     * 场景(可以根据场景生成prompt提示词)
+     */
+    private String scene;
+
+    /**
+     * 目标
+     */
+    private String target;
+
+    /**
+     * 描述
+     */
+    private String description;
+
+    /**
+     * 每次出题数量
+     */
+    private Integer questionCount;
+}
diff --git a/src/main/java/cc/mrbird/febs/ai/entity/AiProductCategory.java b/src/main/java/cc/mrbird/febs/ai/entity/AiProductCategory.java
new file mode 100644
index 0000000..b4ca2f3
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/ai/entity/AiProductCategory.java
@@ -0,0 +1,55 @@
+package cc.mrbird.febs.ai.entity;
+
+import cc.mrbird.febs.common.entity.AiBaseEntity;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+/**
+ * AI产品类别
+ *
+ * @author yourname
+ * @date 2025-07-29
+ */
+@Data
+@TableName("ai_product_category")
+public class AiProductCategory extends AiBaseEntity {
+    /**
+     * 公司ID (UUID)
+     */
+    private String companyId;
+
+    /**
+     * 编码
+     */
+    private String code;
+
+    /**
+     * 名称
+     */
+    private String name;
+
+    /**
+     * 背景图片
+     */
+    private String backImg;
+
+    /**
+     * 小图标
+     */
+    private String iconImg;
+
+    /**
+     * 排序
+     */
+    private Integer sort;
+
+    /**
+     * 状态 0-禁用 1-启用 2-已删除
+     */
+    private Integer state;
+
+    /**
+     * 是否推荐到首页 1-推荐 0-不推荐
+     */
+    private Integer hotState;
+}
diff --git a/src/main/java/cc/mrbird/febs/ai/entity/AiProductPoint.java b/src/main/java/cc/mrbird/febs/ai/entity/AiProductPoint.java
new file mode 100644
index 0000000..b153e9b
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/ai/entity/AiProductPoint.java
@@ -0,0 +1,45 @@
+package cc.mrbird.febs.ai.entity;
+
+import cc.mrbird.febs.common.entity.AiBaseEntity;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+/**
+ * AI产品知识点
+ *
+ * @author yourname
+ * @date 2025-07-29
+ */
+@Data
+@TableName("ai_product_point")
+public class AiProductPoint extends AiBaseEntity {
+    /**
+     * 公司ID (UUID)
+     */
+    private String companyId;
+
+    /**
+     * 类型1:普通内容  2:视频号内容
+     */
+    private Integer isNormal;
+
+    /**
+     * 视频号 id,以"sph"开头的id,可在视频号助手获取
+     */
+    private String finderUserName;
+
+    /**
+     * 视频 feedId
+     */
+    private String feedId;
+
+    /**
+     * 标题
+     */
+    private String title;
+
+    /**
+     * 描述
+     */
+    private String description;
+}
diff --git a/src/main/java/cc/mrbird/febs/ai/entity/AiProductQuestion.java b/src/main/java/cc/mrbird/febs/ai/entity/AiProductQuestion.java
new file mode 100644
index 0000000..8e9cce5
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/ai/entity/AiProductQuestion.java
@@ -0,0 +1,61 @@
+package cc.mrbird.febs.ai.entity;
+
+import cc.mrbird.febs.common.entity.AiBaseEntity;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+/**
+ * AI产品题目
+ *
+ * @author yourname
+ * @date 2025-07-29
+ */
+@Data
+@TableName("ai_product_question")
+public class AiProductQuestion extends AiBaseEntity {
+
+    /**
+     * 公司ID (UUID)
+     */
+    private String companyId;
+
+    /**
+     * AI产品类别ID (UUID)
+     */
+    private String productCategoryId;
+
+    /**
+     * 题目
+     */
+    private String title;
+
+    /**
+     * 答案
+     */
+    private String answer;
+
+    /**
+     * 是否是正确答案 0-否 1-是
+     */
+    private Integer correctAnswer;
+
+    /**
+     * 父ID,相同表示是同一个题目
+     */
+    private String parentId;
+
+    /**
+     * 答案解析
+     */
+    private String answerAnalysis;
+
+    /**
+     * 难度:1-简单,2-中等,3-困难
+     */
+    private Integer difficulty;
+
+    /**
+     * 状态 0-禁用 1-启用 2-已删除
+     */
+    private Integer state;
+}
diff --git a/src/main/java/cc/mrbird/febs/ai/entity/AiProductQuestionLink.java b/src/main/java/cc/mrbird/febs/ai/entity/AiProductQuestionLink.java
new file mode 100644
index 0000000..d312794
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/ai/entity/AiProductQuestionLink.java
@@ -0,0 +1,30 @@
+package cc.mrbird.febs.ai.entity;
+
+import cc.mrbird.febs.common.entity.AiBaseEntity;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+/**
+ * 产品题目关系表
+ *
+ * @author yourname
+ * @date 2025-07-29
+ */
+@Data
+@TableName("ai_product_question_link")
+public class AiProductQuestionLink extends AiBaseEntity {
+    /**
+     * 公司ID (UUID)
+     */
+    private String companyId;
+
+    /**
+     * 产品题目ID (UUID)
+     */
+    private String productQuestionId;
+
+    /**
+     * 产品ID (UUID)
+     */
+    private String productId;
+}
diff --git a/src/main/java/cc/mrbird/febs/ai/entity/AiProductRole.java b/src/main/java/cc/mrbird/febs/ai/entity/AiProductRole.java
new file mode 100644
index 0000000..9cca31c
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/ai/entity/AiProductRole.java
@@ -0,0 +1,45 @@
+package cc.mrbird.febs.ai.entity;
+
+import cc.mrbird.febs.common.entity.AiBaseEntity;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+/**
+ * AI产品陪练角色
+ *
+ * @author yourname
+ * @date 2025-07-29
+ */
+@Data
+@TableName("ai_product_role")
+public class AiProductRole extends AiBaseEntity {
+    /**
+     * 公司ID (UUID)
+     */
+    private String companyId;
+
+    /**
+     * ai产品ID (UUID)
+     */
+    private String productId;
+
+    /**
+     * 名称
+     */
+    private String name;
+
+    /**
+     * 描述
+     */
+    private String description;
+
+    /**
+     * 提示模板
+     */
+    private String promptTemplate;
+
+    /**
+     * 小图标
+     */
+    private String iconImg;
+}
diff --git a/src/main/java/cc/mrbird/febs/ai/mapper/AiMemberAnswerItemMapper.java b/src/main/java/cc/mrbird/febs/ai/mapper/AiMemberAnswerItemMapper.java
new file mode 100644
index 0000000..f14ed3b
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/ai/mapper/AiMemberAnswerItemMapper.java
@@ -0,0 +1,14 @@
+package cc.mrbird.febs.ai.mapper;
+
+import cc.mrbird.febs.ai.entity.AiMemberAnswerItem;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * AI用户答题记录子表 Mapper接口
+ *
+ * @author yourname
+ * @date 2025-07-29
+ */
+public interface AiMemberAnswerItemMapper extends BaseMapper<AiMemberAnswerItem> {
+
+}
diff --git a/src/main/java/cc/mrbird/febs/ai/mapper/AiMemberAnswerMapper.java b/src/main/java/cc/mrbird/febs/ai/mapper/AiMemberAnswerMapper.java
new file mode 100644
index 0000000..6fa6188
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/ai/mapper/AiMemberAnswerMapper.java
@@ -0,0 +1,14 @@
+package cc.mrbird.febs.ai.mapper;
+
+import cc.mrbird.febs.ai.entity.AiMemberAnswer;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * AI用户答题记录 Mapper接口
+ *
+ * @author yourname
+ * @date 2025-07-29
+ */
+public interface AiMemberAnswerMapper extends BaseMapper<AiMemberAnswer> {
+
+}
diff --git a/src/main/java/cc/mrbird/febs/ai/mapper/AiMemberRoleCategoryMapper.java b/src/main/java/cc/mrbird/febs/ai/mapper/AiMemberRoleCategoryMapper.java
new file mode 100644
index 0000000..d1e1bbe
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/ai/mapper/AiMemberRoleCategoryMapper.java
@@ -0,0 +1,14 @@
+package cc.mrbird.febs.ai.mapper;
+
+import cc.mrbird.febs.ai.entity.AiMemberRoleCategory;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * AI用户选择角色关联产品分类 Mapper接口
+ *
+ * @author yourname
+ * @date 2025-07-29
+ */
+public interface AiMemberRoleCategoryMapper extends BaseMapper<AiMemberRoleCategory> {
+
+}
diff --git a/src/main/java/cc/mrbird/febs/ai/mapper/AiMemberRoleMapper.java b/src/main/java/cc/mrbird/febs/ai/mapper/AiMemberRoleMapper.java
new file mode 100644
index 0000000..3477aed
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/ai/mapper/AiMemberRoleMapper.java
@@ -0,0 +1,14 @@
+package cc.mrbird.febs.ai.mapper;
+
+import cc.mrbird.febs.ai.entity.AiMemberRole;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * AI用户选择角色表 Mapper接口
+ *
+ * @author yourname
+ * @date 2025-07-29
+ */
+public interface AiMemberRoleMapper extends BaseMapper<AiMemberRole> {
+
+}
diff --git a/src/main/java/cc/mrbird/febs/ai/mapper/AiMemberRoleProductMapper.java b/src/main/java/cc/mrbird/febs/ai/mapper/AiMemberRoleProductMapper.java
new file mode 100644
index 0000000..ffb935c
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/ai/mapper/AiMemberRoleProductMapper.java
@@ -0,0 +1,14 @@
+package cc.mrbird.febs.ai.mapper;
+
+import cc.mrbird.febs.ai.entity.AiMemberRoleProduct;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * AI用户选择角色关联产品 Mapper接口
+ *
+ * @author yourname
+ * @date 2025-07-29
+ */
+public interface AiMemberRoleProductMapper extends BaseMapper<AiMemberRoleProduct> {
+
+}
diff --git a/src/main/java/cc/mrbird/febs/ai/mapper/AiMemberTalkItemMapper.java b/src/main/java/cc/mrbird/febs/ai/mapper/AiMemberTalkItemMapper.java
new file mode 100644
index 0000000..e960267
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/ai/mapper/AiMemberTalkItemMapper.java
@@ -0,0 +1,14 @@
+package cc.mrbird.febs.ai.mapper;
+
+import cc.mrbird.febs.ai.entity.AiMemberTalkItem;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * AI用户对话训练记录子表 Mapper接口
+ *
+ * @author yourname
+ * @date 2025-07-29
+ */
+public interface AiMemberTalkItemMapper extends BaseMapper<AiMemberTalkItem> {
+
+}
diff --git a/src/main/java/cc/mrbird/febs/ai/mapper/AiMemberTalkMapper.java b/src/main/java/cc/mrbird/febs/ai/mapper/AiMemberTalkMapper.java
new file mode 100644
index 0000000..7ab8163
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/ai/mapper/AiMemberTalkMapper.java
@@ -0,0 +1,14 @@
+package cc.mrbird.febs.ai.mapper;
+
+import cc.mrbird.febs.ai.entity.AiMemberTalk;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * AI用户对话训练记录 Mapper接口
+ *
+ * @author yourname
+ * @date 2025-07-29
+ */
+public interface AiMemberTalkMapper extends BaseMapper<AiMemberTalk> {
+
+}
diff --git a/src/main/java/cc/mrbird/febs/ai/mapper/AiProductCategoryMapper.java b/src/main/java/cc/mrbird/febs/ai/mapper/AiProductCategoryMapper.java
new file mode 100644
index 0000000..516ec6c
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/ai/mapper/AiProductCategoryMapper.java
@@ -0,0 +1,14 @@
+package cc.mrbird.febs.ai.mapper;
+
+import cc.mrbird.febs.ai.entity.AiProductCategory;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * AI产品类别 Mapper接口
+ *
+ * @author yourname
+ * @date 2025-07-29
+ */
+public interface AiProductCategoryMapper extends BaseMapper<AiProductCategory> {
+
+}
diff --git a/src/main/java/cc/mrbird/febs/ai/mapper/AiProductMapper.java b/src/main/java/cc/mrbird/febs/ai/mapper/AiProductMapper.java
new file mode 100644
index 0000000..4f20d91
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/ai/mapper/AiProductMapper.java
@@ -0,0 +1,14 @@
+package cc.mrbird.febs.ai.mapper;
+
+import cc.mrbird.febs.ai.entity.AiProduct;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * AI产品表 Mapper接口
+ *
+ * @author yourname
+ * @date 2025-07-29
+ */
+public interface AiProductMapper extends BaseMapper<AiProduct> {
+
+}
diff --git a/src/main/java/cc/mrbird/febs/ai/mapper/AiProductPointMapper.java b/src/main/java/cc/mrbird/febs/ai/mapper/AiProductPointMapper.java
new file mode 100644
index 0000000..7750703
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/ai/mapper/AiProductPointMapper.java
@@ -0,0 +1,14 @@
+package cc.mrbird.febs.ai.mapper;
+
+import cc.mrbird.febs.ai.entity.AiProductPoint;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * AI产品知识点 Mapper接口
+ *
+ * @author yourname
+ * @date 2025-07-29
+ */
+public interface AiProductPointMapper extends BaseMapper<AiProductPoint> {
+
+}
diff --git a/src/main/java/cc/mrbird/febs/ai/mapper/AiProductQuestionLinkMapper.java b/src/main/java/cc/mrbird/febs/ai/mapper/AiProductQuestionLinkMapper.java
new file mode 100644
index 0000000..a7df64f
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/ai/mapper/AiProductQuestionLinkMapper.java
@@ -0,0 +1,14 @@
+package cc.mrbird.febs.ai.mapper;
+
+import cc.mrbird.febs.ai.entity.AiProductQuestionLink;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * 产品题目关系表 Mapper接口
+ *
+ * @author
+ * @date 2025-07-29
+ */
+public interface AiProductQuestionLinkMapper extends BaseMapper<AiProductQuestionLink> {
+
+}
diff --git a/src/main/java/cc/mrbird/febs/ai/mapper/AiProductQuestionMapper.java b/src/main/java/cc/mrbird/febs/ai/mapper/AiProductQuestionMapper.java
new file mode 100644
index 0000000..faa313b
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/ai/mapper/AiProductQuestionMapper.java
@@ -0,0 +1,14 @@
+package cc.mrbird.febs.ai.mapper;
+
+import cc.mrbird.febs.ai.entity.AiProductQuestion;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * AI产品题目 Mapper接口
+ *
+ * @author yourname
+ * @date 2025-07-29
+ */
+public interface AiProductQuestionMapper extends BaseMapper<AiProductQuestion> {
+
+}
diff --git a/src/main/java/cc/mrbird/febs/ai/mapper/AiProductRoleMapper.java b/src/main/java/cc/mrbird/febs/ai/mapper/AiProductRoleMapper.java
new file mode 100644
index 0000000..a60a63c
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/ai/mapper/AiProductRoleMapper.java
@@ -0,0 +1,14 @@
+package cc.mrbird.febs.ai.mapper;
+
+import cc.mrbird.febs.ai.entity.AiProductRole;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * AI产品陪练角色 Mapper接口
+ *
+ * @author yourname
+ * @date 2025-07-29
+ */
+public interface AiProductRoleMapper extends BaseMapper<AiProductRole> {
+
+}
diff --git a/src/main/java/cc/mrbird/febs/ai/service/AiMemberAnswerItemService.java b/src/main/java/cc/mrbird/febs/ai/service/AiMemberAnswerItemService.java
new file mode 100644
index 0000000..b449215
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/ai/service/AiMemberAnswerItemService.java
@@ -0,0 +1,113 @@
+package cc.mrbird.febs.ai.service;
+
+import cc.mrbird.febs.ai.entity.AiMemberAnswerItem;
+import com.baomidou.mybatisplus.extension.service.IService;
+import java.util.List;
+
+/**
+ * AI用户答题记录子表 Service接口
+ *
+ * @author yourname
+ * @date 2025-07-29
+ */
+public interface AiMemberAnswerItemService extends IService<AiMemberAnswerItem> {
+
+    /**
+     * 根据ID查询答题记录项
+     * @param id 答题记录项ID
+     * @return 答题记录项信息
+     */
+    AiMemberAnswerItem getById(String id);
+
+    /**
+     * 根据答题记录ID查询答题记录项列表
+     * @param answerId 答题记录ID
+     * @return 答题记录项列表
+     */
+    List<AiMemberAnswerItem> getByAnswerId(String answerId);
+
+    /**
+     * 根据用户ID查询答题记录项列表
+     * @param memberId 用户ID
+     * @return 答题记录项列表
+     */
+    List<AiMemberAnswerItem> getByMemberId(String memberId);
+
+    /**
+     * 根据产品ID查询答题记录项列表
+     * @param productId 产品ID
+     * @return 答题记录项列表
+     */
+    List<AiMemberAnswerItem> getByProductId(String productId);
+
+    /**
+     * 根据题目父ID查询答题记录项列表
+     * @param productQuestionParentId 题目父ID
+     * @return 答题记录项列表
+     */
+    List<AiMemberAnswerItem> getByProductQuestionParentId(String productQuestionParentId);
+
+    /**
+     * 根据题目ID查询答题记录项列表
+     * @param productQuestionId 题目ID
+     * @return 答题记录项列表
+     */
+    List<AiMemberAnswerItem> getByProductQuestionId(String productQuestionId);
+
+    /**
+     * 根据用户回答状态查询答题记录项列表
+     * @param memberAnswerState 用户回答状态 0-未回答 1-答对了 2-答错了
+     * @return 答题记录项列表
+     */
+    List<AiMemberAnswerItem> getByMemberAnswerState(Integer memberAnswerState);
+
+    /**
+     * 根据是否加入错题集查询答题记录项列表
+     * @param isCollected 是否加入错题集:0-否,1-是
+     * @return 答题记录项列表
+     */
+    List<AiMemberAnswerItem> getByIsCollected(Integer isCollected);
+
+    /**
+     * 根据公司ID和用户ID查询答题记录项列表
+     * @param companyId 公司ID
+     * @param memberId 用户ID
+     * @return 答题记录项列表
+     */
+    List<AiMemberAnswerItem> getByCompanyIdAndMemberId(String companyId, String memberId);
+
+    /**
+     * 保存答题记录项
+     * @param aiMemberAnswerItem 答题记录项实体
+     * @return 是否保存成功
+     */
+    boolean saveAnswerItem(AiMemberAnswerItem aiMemberAnswerItem);
+
+    /**
+     * 批量保存答题记录项
+     * @param answerItems 答题记录项列表
+     * @return 是否保存成功
+     */
+    boolean saveBatchAnswerItems(List<AiMemberAnswerItem> answerItems);
+
+    /**
+     * 更新答题记录项
+     * @param aiMemberAnswerItem 答题记录项实体
+     * @return 是否更新成功
+     */
+    boolean updateAnswerItem(AiMemberAnswerItem aiMemberAnswerItem);
+
+    /**
+     * 根据ID删除答题记录项
+     * @param id 答题记录项ID
+     * @return 是否删除成功
+     */
+    boolean deleteById(String id);
+
+    /**
+     * 根据答题记录ID删除答题记录项
+     * @param answerId 答题记录ID
+     * @return 是否删除成功
+     */
+    boolean deleteByAnswerId(String answerId);
+}
diff --git a/src/main/java/cc/mrbird/febs/ai/service/AiMemberAnswerService.java b/src/main/java/cc/mrbird/febs/ai/service/AiMemberAnswerService.java
new file mode 100644
index 0000000..0b58d28
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/ai/service/AiMemberAnswerService.java
@@ -0,0 +1,108 @@
+package cc.mrbird.febs.ai.service;
+
+import cc.mrbird.febs.ai.entity.AiMemberAnswer;
+import com.baomidou.mybatisplus.extension.service.IService;
+import java.util.List;
+
+/**
+ * AI用户答题记录 Service接口
+ *
+ * @author yourname
+ * @date 2025-07-29
+ */
+public interface AiMemberAnswerService extends IService<AiMemberAnswer> {
+
+    /**
+     * 根据ID查询答题记录
+     * @param id 答题记录ID
+     * @return 答题记录信息
+     */
+    AiMemberAnswer getById(String id);
+
+    /**
+     * 根据用户ID查询答题记录列表
+     * @param memberId 用户ID
+     * @return 答题记录列表
+     */
+    List<AiMemberAnswer> getByMemberId(String memberId);
+
+    /**
+     * 根据产品ID查询答题记录列表
+     * @param productId 产品ID
+     * @return 答题记录列表
+     */
+    List<AiMemberAnswer> getByProductId(String productId);
+
+    /**
+     * 根据公司ID查询答题记录列表
+     * @param companyId 公司ID
+     * @return 答题记录列表
+     */
+    List<AiMemberAnswer> getByCompanyId(String companyId);
+
+    /**
+     * 根据状态查询答题记录列表
+     * @param state 状态 0-进行中 1-已结束
+     * @return 答题记录列表
+     */
+    List<AiMemberAnswer> getByState(Integer state);
+
+    /**
+     * 根据用户ID和状态查询答题记录列表
+     * @param memberId 用户ID
+     * @param state 状态 0-进行中 1-已结束
+     * @return 答题记录列表
+     */
+    List<AiMemberAnswer> getByMemberIdAndState(String memberId, Integer state);
+
+    /**
+     * 根据公司ID和用户ID查询答题记录列表
+     * @param companyId 公司ID
+     * @param memberId 用户ID
+     * @return 答题记录列表
+     */
+    List<AiMemberAnswer> getByCompanyIdAndMemberId(String companyId, String memberId);
+
+    /**
+     * 根据评分范围查询答题记录列表
+     * @param minScore 最低分
+     * @param maxScore 最高分
+     * @return 答题记录列表
+     */
+    List<AiMemberAnswer> getByScoreRange(Integer minScore, Integer maxScore);
+
+    /**
+     * 保存答题记录
+     * @param aiMemberAnswer 答题记录实体
+     * @return 是否保存成功
+     */
+    boolean saveAnswer(AiMemberAnswer aiMemberAnswer);
+
+    /**
+     * 批量保存答题记录
+     * @param answers 答题记录列表
+     * @return 是否保存成功
+     */
+    boolean saveBatchAnswers(List<AiMemberAnswer> answers);
+
+    /**
+     * 更新答题记录
+     * @param aiMemberAnswer 答题记录实体
+     * @return 是否更新成功
+     */
+    boolean updateAnswer(AiMemberAnswer aiMemberAnswer);
+
+    /**
+     * 根据ID删除答题记录
+     * @param id 答题记录ID
+     * @return 是否删除成功
+     */
+    boolean deleteById(String id);
+
+    /**
+     * 根据用户ID删除答题记录
+     * @param memberId 用户ID
+     * @return 是否删除成功
+     */
+    boolean deleteByMemberId(String memberId);
+}
diff --git a/src/main/java/cc/mrbird/febs/ai/service/AiMemberRoleCategoryService.java b/src/main/java/cc/mrbird/febs/ai/service/AiMemberRoleCategoryService.java
new file mode 100644
index 0000000..728603a
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/ai/service/AiMemberRoleCategoryService.java
@@ -0,0 +1,100 @@
+package cc.mrbird.febs.ai.service;
+
+import cc.mrbird.febs.ai.entity.AiMemberRoleCategory;
+import com.baomidou.mybatisplus.extension.service.IService;
+import java.util.List;
+
+/**
+ * AI用户选择角色关联产品分类 Service接口
+ *
+ * @author yourname
+ * @date 2025-07-29
+ */
+public interface AiMemberRoleCategoryService extends IService<AiMemberRoleCategory> {
+
+    /**
+     * 根据ID查询关联记录
+     * @param id 关联记录ID
+     * @return 关联记录信息
+     */
+    AiMemberRoleCategory getById(String id);
+
+    /**
+     * 根据角色ID查询关联记录
+     * @param roleId 角色ID
+     * @return 关联记录列表
+     */
+    List<AiMemberRoleCategory> getByRoleId(String roleId);
+
+    /**
+     * 根据产品分类ID查询关联记录
+     * @param productCategoryId 产品分类ID
+     * @return 关联记录列表
+     */
+    List<AiMemberRoleCategory> getByProductCategoryId(String productCategoryId);
+
+    /**
+     * 根据公司ID查询关联记录
+     * @param companyId 公司ID
+     * @return 关联记录列表
+     */
+    List<AiMemberRoleCategory> getByCompanyId(String companyId);
+
+    /**
+     * 根据角色ID和产品分类ID查询关联记录
+     * @param roleId 角色ID
+     * @param productCategoryId 产品分类ID
+     * @return 关联记录列表
+     */
+    List<AiMemberRoleCategory> getByRoleIdAndProductCategoryId(String roleId, String productCategoryId);
+
+    /**
+     * 保存关联记录
+     * @param aiMemberRoleCategory 关联记录实体
+     * @return 是否保存成功
+     */
+    boolean saveRoleCategory(AiMemberRoleCategory aiMemberRoleCategory);
+
+    /**
+     * 批量保存关联记录
+     * @param roleCategories 关联记录列表
+     * @return 是否保存成功
+     */
+    boolean saveBatchRoleCategories(List<AiMemberRoleCategory> roleCategories);
+
+    /**
+     * 更新关联记录
+     * @param aiMemberRoleCategory 关联记录实体
+     * @return 是否更新成功
+     */
+    boolean updateRoleCategory(AiMemberRoleCategory aiMemberRoleCategory);
+
+    /**
+     * 根据ID删除关联记录
+     * @param id 关联记录ID
+     * @return 是否删除成功
+     */
+    boolean deleteById(String id);
+
+    /**
+     * 根据角色ID删除关联记录
+     * @param roleId 角色ID
+     * @return 是否删除成功
+     */
+    boolean deleteByRoleId(String roleId);
+
+    /**
+     * 根据产品分类ID删除关联记录
+     * @param productCategoryId 产品分类ID
+     * @return 是否删除成功
+     */
+    boolean deleteByProductCategoryId(String productCategoryId);
+
+    /**
+     * 根据角色ID和产品分类ID删除关联记录
+     * @param roleId 角色ID
+     * @param productCategoryId 产品分类ID
+     * @return 是否删除成功
+     */
+    boolean deleteByRoleIdAndProductCategoryId(String roleId, String productCategoryId);
+}
diff --git a/src/main/java/cc/mrbird/febs/ai/service/AiMemberRoleProductService.java b/src/main/java/cc/mrbird/febs/ai/service/AiMemberRoleProductService.java
new file mode 100644
index 0000000..8dd64b0
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/ai/service/AiMemberRoleProductService.java
@@ -0,0 +1,100 @@
+package cc.mrbird.febs.ai.service;
+
+import cc.mrbird.febs.ai.entity.AiMemberRoleProduct;
+import com.baomidou.mybatisplus.extension.service.IService;
+import java.util.List;
+
+/**
+ * AI用户选择角色关联产品 Service接口
+ *
+ * @author yourname
+ * @date 2025-07-29
+ */
+public interface AiMemberRoleProductService extends IService<AiMemberRoleProduct> {
+
+    /**
+     * 根据ID查询关联记录
+     * @param id 关联记录ID
+     * @return 关联记录信息
+     */
+    AiMemberRoleProduct getById(String id);
+
+    /**
+     * 根据角色ID查询关联记录
+     * @param roleId 角色ID
+     * @return 关联记录列表
+     */
+    List<AiMemberRoleProduct> getByRoleId(String roleId);
+
+    /**
+     * 根据产品ID查询关联记录
+     * @param productId 产品ID
+     * @return 关联记录列表
+     */
+    List<AiMemberRoleProduct> getByProductId(String productId);
+
+    /**
+     * 根据公司ID查询关联记录
+     * @param companyId 公司ID
+     * @return 关联记录列表
+     */
+    List<AiMemberRoleProduct> getByCompanyId(String companyId);
+
+    /**
+     * 根据角色ID和产品ID查询关联记录
+     * @param roleId 角色ID
+     * @param productId 产品ID
+     * @return 关联记录列表
+     */
+    List<AiMemberRoleProduct> getByRoleIdAndProductId(String roleId, String productId);
+
+    /**
+     * 保存关联记录
+     * @param aiMemberRoleProduct 关联记录实体
+     * @return 是否保存成功
+     */
+    boolean saveRoleProduct(AiMemberRoleProduct aiMemberRoleProduct);
+
+    /**
+     * 批量保存关联记录
+     * @param roleProducts 关联记录列表
+     * @return 是否保存成功
+     */
+    boolean saveBatchRoleProducts(List<AiMemberRoleProduct> roleProducts);
+
+    /**
+     * 更新关联记录
+     * @param aiMemberRoleProduct 关联记录实体
+     * @return 是否更新成功
+     */
+    boolean updateRoleProduct(AiMemberRoleProduct aiMemberRoleProduct);
+
+    /**
+     * 根据ID删除关联记录
+     * @param id 关联记录ID
+     * @return 是否删除成功
+     */
+    boolean deleteById(String id);
+
+    /**
+     * 根据角色ID删除关联记录
+     * @param roleId 角色ID
+     * @return 是否删除成功
+     */
+    boolean deleteByRoleId(String roleId);
+
+    /**
+     * 根据产品ID删除关联记录
+     * @param productId 产品ID
+     * @return 是否删除成功
+     */
+    boolean deleteByProductId(String productId);
+
+    /**
+     * 根据角色ID和产品ID删除关联记录
+     * @param roleId 角色ID
+     * @param productId 产品ID
+     * @return 是否删除成功
+     */
+    boolean deleteByRoleIdAndProductId(String roleId, String productId);
+}
diff --git a/src/main/java/cc/mrbird/febs/ai/service/AiMemberRoleService.java b/src/main/java/cc/mrbird/febs/ai/service/AiMemberRoleService.java
new file mode 100644
index 0000000..efbb525
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/ai/service/AiMemberRoleService.java
@@ -0,0 +1,92 @@
+package cc.mrbird.febs.ai.service;
+
+import cc.mrbird.febs.ai.entity.AiMemberRole;
+import com.baomidou.mybatisplus.extension.service.IService;
+import java.util.List;
+
+/**
+ * AI用户选择角色表 Service接口
+ *
+ * @author yourname
+ * @date 2025-07-29
+ */
+public interface AiMemberRoleService extends IService<AiMemberRole> {
+
+    /**
+     * 根据ID查询角色
+     * @param id 角色ID
+     * @return 角色信息
+     */
+    AiMemberRole getById(String id);
+
+    /**
+     * 根据公司ID查询角色列表
+     * @param companyId 公司ID
+     * @return 角色列表
+     */
+    List<AiMemberRole> getByCompanyId(String companyId);
+
+    /**
+     * 根据编码查询角色
+     * @param code 角色编码
+     * @return 角色信息
+     */
+    AiMemberRole getByCode(String code);
+
+    /**
+     * 根据名称查询角色列表
+     * @param name 角色名称
+     * @return 角色列表
+     */
+    List<AiMemberRole> getByName(String name);
+
+    /**
+     * 根据状态查询角色列表
+     * @param state 状态 0-禁用 1-启用 2-已删除
+     * @return 角色列表
+     */
+    List<AiMemberRole> getByState(Integer state);
+
+    /**
+     * 根据公司ID和状态查询角色列表
+     * @param companyId 公司ID
+     * @param state 状态 0-禁用 1-启用 2-已删除
+     * @return 角色列表
+     */
+    List<AiMemberRole> getByCompanyIdAndState(String companyId, Integer state);
+
+    /**
+     * 保存角色
+     * @param aiMemberRole 角色实体
+     * @return 是否保存成功
+     */
+    boolean saveRole(AiMemberRole aiMemberRole);
+
+    /**
+     * 批量保存角色
+     * @param roles 角色列表
+     * @return 是否保存成功
+     */
+    boolean saveBatchRoles(List<AiMemberRole> roles);
+
+    /**
+     * 更新角色
+     * @param aiMemberRole 角色实体
+     * @return 是否更新成功
+     */
+    boolean updateRole(AiMemberRole aiMemberRole);
+
+    /**
+     * 根据ID删除角色
+     * @param id 角色ID
+     * @return 是否删除成功
+     */
+    boolean deleteById(String id);
+
+    /**
+     * 根据公司ID删除角色
+     * @param companyId 公司ID
+     * @return 是否删除成功
+     */
+    boolean deleteByCompanyId(String companyId);
+}
diff --git a/src/main/java/cc/mrbird/febs/ai/service/AiMemberTalkItemService.java b/src/main/java/cc/mrbird/febs/ai/service/AiMemberTalkItemService.java
new file mode 100644
index 0000000..4f29e78
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/ai/service/AiMemberTalkItemService.java
@@ -0,0 +1,77 @@
+package cc.mrbird.febs.ai.service;
+
+import cc.mrbird.febs.ai.entity.AiMemberTalkItem;
+import com.baomidou.mybatisplus.extension.service.IService;
+import java.util.List;
+
+/**
+ * AI用户对话训练记录子表 Service接口
+ *
+ * @author yourname
+ * @date 2025-07-29
+ */
+public interface AiMemberTalkItemService extends IService<AiMemberTalkItem> {
+
+    /**
+     * 根据ID查询对话项
+     * @param id 对话项ID
+     * @return 对话项信息
+     */
+    AiMemberTalkItem getById(String id);
+
+    /**
+     * 根据对话ID查询所有对话项
+     * @param memberTalkId 对话ID
+     * @return 对话项列表
+     */
+    List<AiMemberTalkItem> getByMemberTalkId(String memberTalkId);
+
+    /**
+     * 根据用户ID查询对话项
+     * @param memberId 用户ID
+     * @return 对话项列表
+     */
+    List<AiMemberTalkItem> getByMemberId(String memberId);
+
+    /**
+     * 根据类型查询对话项
+     * @param type 类型 1-AI提问 2-用户回答 3-AI分析结果
+     * @return 对话项列表
+     */
+    List<AiMemberTalkItem> getByType(Integer type);
+
+    /**
+     * 保存对话项
+     * @param aiMemberTalkItem 对话项实体
+     * @return 是否保存成功
+     */
+    boolean saveTalkItem(AiMemberTalkItem aiMemberTalkItem);
+
+    /**
+     * 批量保存对话项
+     * @param talkItems 对话项列表
+     * @return 是否保存成功
+     */
+    boolean saveBatchTalkItems(List<AiMemberTalkItem> talkItems);
+
+    /**
+     * 更新对话项
+     * @param aiMemberTalkItem 对话项实体
+     * @return 是否更新成功
+     */
+    boolean updateTalkItem(AiMemberTalkItem aiMemberTalkItem);
+
+    /**
+     * 根据ID删除对话项
+     * @param id 对话项ID
+     * @return 是否删除成功
+     */
+    boolean deleteById(String id);
+
+    /**
+     * 根据对话ID删除对话项
+     * @param memberTalkId 对话ID
+     * @return 是否删除成功
+     */
+    boolean deleteByMemberTalkId(String memberTalkId);
+}
diff --git a/src/main/java/cc/mrbird/febs/ai/service/AiMemberTalkService.java b/src/main/java/cc/mrbird/febs/ai/service/AiMemberTalkService.java
new file mode 100644
index 0000000..d9d063e
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/ai/service/AiMemberTalkService.java
@@ -0,0 +1,84 @@
+package cc.mrbird.febs.ai.service;
+
+import cc.mrbird.febs.ai.entity.AiMemberTalk;
+import com.baomidou.mybatisplus.extension.service.IService;
+import java.util.List;
+
+/**
+ * AI用户对话训练记录 Service接口
+ *
+ * @author yourname
+ * @date 2025-07-29
+ */
+public interface AiMemberTalkService extends IService<AiMemberTalk> {
+
+    /**
+     * 根据ID查询对话记录
+     * @param id 对话记录ID
+     * @return 对话记录信息
+     */
+    AiMemberTalk getById(String id);
+
+    /**
+     * 根据用户ID查询对话记录
+     * @param memberId 用户ID
+     * @return 对话记录列表
+     */
+    List<AiMemberTalk> getByMemberId(String memberId);
+
+    /**
+     * 根据产品ID查询对话记录
+     * @param productId 产品ID
+     * @return 对话记录列表
+     */
+    List<AiMemberTalk> getByProductId(String productId);
+
+    /**
+     * 根据角色ID查询对话记录
+     * @param productRoleId 角色ID
+     * @return 对话记录列表
+     */
+    List<AiMemberTalk> getByProductRoleId(String productRoleId);
+
+    /**
+     * 根据公司ID查询对话记录
+     * @param companyId 公司ID
+     * @return 对话记录列表
+     */
+    List<AiMemberTalk> getByCompanyId(String companyId);
+
+    /**
+     * 保存对话记录
+     * @param aiMemberTalk 对话记录实体
+     * @return 是否保存成功
+     */
+    boolean saveTalk(AiMemberTalk aiMemberTalk);
+
+    /**
+     * 批量保存对话记录
+     * @param talks 对话记录列表
+     * @return 是否保存成功
+     */
+    boolean saveBatchTalks(List<AiMemberTalk> talks);
+
+    /**
+     * 更新对话记录
+     * @param aiMemberTalk 对话记录实体
+     * @return 是否更新成功
+     */
+    boolean updateTalk(AiMemberTalk aiMemberTalk);
+
+    /**
+     * 根据ID删除对话记录
+     * @param id 对话记录ID
+     * @return 是否删除成功
+     */
+    boolean deleteById(String id);
+
+    /**
+     * 根据用户ID删除对话记录
+     * @param memberId 用户ID
+     * @return 是否删除成功
+     */
+    boolean deleteByMemberId(String memberId);
+}
diff --git a/src/main/java/cc/mrbird/febs/ai/service/AiProductCategoryService.java b/src/main/java/cc/mrbird/febs/ai/service/AiProductCategoryService.java
new file mode 100644
index 0000000..d9081cb
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/ai/service/AiProductCategoryService.java
@@ -0,0 +1,113 @@
+package cc.mrbird.febs.ai.service;
+
+import cc.mrbird.febs.ai.entity.AiProductCategory;
+import com.baomidou.mybatisplus.extension.service.IService;
+import java.util.List;
+
+/**
+ * AI产品类别 Service接口
+ *
+ * @author yourname
+ * @date 2025-07-29
+ */
+public interface AiProductCategoryService extends IService<AiProductCategory> {
+
+    /**
+     * 根据ID查询AI产品类别
+     * @param id 类别ID
+     * @return AI产品类别信息
+     */
+    AiProductCategory getById(String id);
+
+    /**
+     * 根据公司ID查询AI产品类别列表
+     * @param companyId 公司ID
+     * @return AI产品类别列表
+     */
+    List<AiProductCategory> getByCompanyId(String companyId);
+
+    /**
+     * 根据编码查询AI产品类别
+     * @param code 类别编码
+     * @return AI产品类别信息
+     */
+    AiProductCategory getByCode(String code);
+
+    /**
+     * 根据名称查询AI产品类别列表
+     * @param name 类别名称
+     * @return AI产品类别列表
+     */
+    List<AiProductCategory> getByName(String name);
+
+    /**
+     * 根据状态查询AI产品类别列表
+     * @param state 状态 0-禁用 1-启用 2-已删除
+     * @return AI产品类别列表
+     */
+    List<AiProductCategory> getByState(Integer state);
+
+    /**
+     * 根据是否推荐查询AI产品类别列表
+     * @param hotState 是否推荐到首页 1-推荐 0-不推荐
+     * @return AI产品类别列表
+     */
+    List<AiProductCategory> getByHotState(Integer hotState);
+
+    /**
+     * 根据公司ID和状态查询AI产品类别列表
+     * @param companyId 公司ID
+     * @param state 状态 0-禁用 1-启用 2-已删除
+     * @return AI产品类别列表
+     */
+    List<AiProductCategory> getByCompanyIdAndState(String companyId, Integer state);
+
+    /**
+     * 根据公司ID和推荐状态查询AI产品类别列表
+     * @param companyId 公司ID
+     * @param hotState 是否推荐到首页 1-推荐 0-不推荐
+     * @return AI产品类别列表
+     */
+    List<AiProductCategory> getByCompanyIdAndHotState(String companyId, Integer hotState);
+
+    /**
+     * 获取启用状态下的所有AI产品类别,按排序字段升序排列
+     * @return 启用的AI产品类别列表
+     */
+    List<AiProductCategory> getEnabledCategories();
+
+    /**
+     * 保存AI产品类别
+     * @param aiProductCategory AI产品类别实体
+     * @return 是否保存成功
+     */
+    boolean saveProductCategory(AiProductCategory aiProductCategory);
+
+    /**
+     * 批量保存AI产品类别
+     * @param productCategories AI产品类别列表
+     * @return 是否保存成功
+     */
+    boolean saveBatchProductCategories(List<AiProductCategory> productCategories);
+
+    /**
+     * 更新AI产品类别
+     * @param aiProductCategory AI产品类别实体
+     * @return 是否更新成功
+     */
+    boolean updateProductCategory(AiProductCategory aiProductCategory);
+
+    /**
+     * 根据ID删除AI产品类别
+     * @param id 类别ID
+     * @return 是否删除成功
+     */
+    boolean deleteById(String id);
+
+    /**
+     * 根据公司ID删除AI产品类别
+     * @param companyId 公司ID
+     * @return 是否删除成功
+     */
+    boolean deleteByCompanyId(String companyId);
+}
diff --git a/src/main/java/cc/mrbird/febs/ai/service/AiProductPointService.java b/src/main/java/cc/mrbird/febs/ai/service/AiProductPointService.java
new file mode 100644
index 0000000..b71c7d2
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/ai/service/AiProductPointService.java
@@ -0,0 +1,106 @@
+package cc.mrbird.febs.ai.service;
+
+import cc.mrbird.febs.ai.entity.AiProductPoint;
+import com.baomidou.mybatisplus.extension.service.IService;
+import java.util.List;
+
+/**
+ * AI产品知识点 Service接口
+ *
+ * @author yourname
+ * @date 2025-07-29
+ */
+public interface AiProductPointService extends IService<AiProductPoint> {
+
+    /**
+     * 根据ID查询AI产品知识点
+     * @param id 知识点ID
+     * @return AI产品知识点信息
+     */
+    AiProductPoint getById(String id);
+
+    /**
+     * 根据公司ID查询AI产品知识点列表
+     * @param companyId 公司ID
+     * @return AI产品知识点列表
+     */
+    List<AiProductPoint> getByCompanyId(String companyId);
+
+    /**
+     * 根据类型查询AI产品知识点列表
+     * @param isNormal 类型1:普通内容 2:视频号内容
+     * @return AI产品知识点列表
+     */
+    List<AiProductPoint> getByIsNormal(Integer isNormal);
+
+    /**
+     * 根据视频号用户名查询AI产品知识点列表
+     * @param finderUserName 视频号用户名
+     * @return AI产品知识点列表
+     */
+    List<AiProductPoint> getByFinderUserName(String finderUserName);
+
+    /**
+     * 根据标题查询AI产品知识点列表
+     * @param title 标题
+     * @return AI产品知识点列表
+     */
+    List<AiProductPoint> getByTitle(String title);
+
+    /**
+     * 根据公司ID和类型查询AI产品知识点列表
+     * @param companyId 公司ID
+     * @param isNormal 类型1:普通内容 2:视频号内容
+     * @return AI产品知识点列表
+     */
+    List<AiProductPoint> getByCompanyIdAndIsNormal(String companyId, Integer isNormal);
+
+    /**
+     * 模糊查询标题或描述包含关键字的AI产品知识点列表
+     * @param keyword 关键字
+     * @return AI产品知识点列表
+     */
+    List<AiProductPoint> searchByKeyword(String keyword);
+
+    /**
+     * 保存AI产品知识点
+     * @param aiProductPoint AI产品知识点实体
+     * @return 是否保存成功
+     */
+    boolean saveProductPoint(AiProductPoint aiProductPoint);
+
+    /**
+     * 批量保存AI产品知识点
+     * @param productPoints AI产品知识点列表
+     * @return 是否保存成功
+     */
+    boolean saveBatchProductPoints(List<AiProductPoint> productPoints);
+
+    /**
+     * 更新AI产品知识点
+     * @param aiProductPoint AI产品知识点实体
+     * @return 是否更新成功
+     */
+    boolean updateProductPoint(AiProductPoint aiProductPoint);
+
+    /**
+     * 根据ID删除AI产品知识点
+     * @param id 知识点ID
+     * @return 是否删除成功
+     */
+    boolean deleteById(String id);
+
+    /**
+     * 根据公司ID删除AI产品知识点
+     * @param companyId 公司ID
+     * @return 是否删除成功
+     */
+    boolean deleteByCompanyId(String companyId);
+
+    /**
+     * 根据视频号FeedID删除AI产品知识点
+     * @param feedId 视频号FeedID
+     * @return 是否删除成功
+     */
+    boolean deleteByFeedId(String feedId);
+}
diff --git a/src/main/java/cc/mrbird/febs/ai/service/AiProductQuestionLinkService.java b/src/main/java/cc/mrbird/febs/ai/service/AiProductQuestionLinkService.java
new file mode 100644
index 0000000..78853bd
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/ai/service/AiProductQuestionLinkService.java
@@ -0,0 +1,123 @@
+package cc.mrbird.febs.ai.service;
+
+import cc.mrbird.febs.ai.entity.AiProductQuestionLink;
+import com.baomidou.mybatisplus.extension.service.IService;
+import java.util.List;
+
+/**
+ * 产品题目关系表 Service接口
+ *
+ * @author yourname
+ * @date 2025-07-29
+ */
+public interface AiProductQuestionLinkService extends IService<AiProductQuestionLink> {
+
+    /**
+     * 根据ID查询产品题目关系
+     * @param id 关系ID
+     * @return 产品题目关系信息
+     */
+    AiProductQuestionLink getById(String id);
+
+    /**
+     * 根据公司ID查询产品题目关系列表
+     * @param companyId 公司ID
+     * @return 产品题目关系列表
+     */
+    List<AiProductQuestionLink> getByCompanyId(String companyId);
+
+    /**
+     * 根据产品题目ID查询产品题目关系列表
+     * @param productQuestionId 产品题目ID
+     * @return 产品题目关系列表
+     */
+    List<AiProductQuestionLink> getByProductQuestionId(String productQuestionId);
+
+    /**
+     * 根据产品ID查询产品题目关系列表
+     * @param productId 产品ID
+     * @return 产品题目关系列表
+     */
+    List<AiProductQuestionLink> getByProductId(String productId);
+
+    /**
+     * 根据公司ID和产品ID查询产品题目关系列表
+     * @param companyId 公司ID
+     * @param productId 产品ID
+     * @return 产品题目关系列表
+     */
+    List<AiProductQuestionLink> getByCompanyIdAndProductId(String companyId, String productId);
+
+    /**
+     * 根据公司ID和产品题目ID查询产品题目关系列表
+     * @param companyId 公司ID
+     * @param productQuestionId 产品题目ID
+     * @return 产品题目关系列表
+     */
+    List<AiProductQuestionLink> getByCompanyIdAndProductQuestionId(String companyId, String productQuestionId);
+
+    /**
+     * 根据产品ID和产品题目ID查询产品题目关系列表
+     * @param productId 产品ID
+     * @param productQuestionId 产品题目ID
+     * @return 产品题目关系列表
+     */
+    List<AiProductQuestionLink> getByProductIdAndProductQuestionId(String productId, String productQuestionId);
+
+    /**
+     * 保存产品题目关系
+     * @param aiProductQuestionLink 产品题目关系实体
+     * @return 是否保存成功
+     */
+    boolean saveProductQuestionLink(AiProductQuestionLink aiProductQuestionLink);
+
+    /**
+     * 批量保存产品题目关系
+     * @param productQuestionLinks 产品题目关系列表
+     * @return 是否保存成功
+     */
+    boolean saveBatchProductQuestionLinks(List<AiProductQuestionLink> productQuestionLinks);
+
+    /**
+     * 更新产品题目关系
+     * @param aiProductQuestionLink 产品题目关系实体
+     * @return 是否更新成功
+     */
+    boolean updateProductQuestionLink(AiProductQuestionLink aiProductQuestionLink);
+
+    /**
+     * 根据ID删除产品题目关系
+     * @param id 关系ID
+     * @return 是否删除成功
+     */
+    boolean deleteById(String id);
+
+    /**
+     * 根据产品ID删除产品题目关系
+     * @param productId 产品ID
+     * @return 是否删除成功
+     */
+    boolean deleteByProductId(String productId);
+
+    /**
+     * 根据产品题目ID删除产品题目关系
+     * @param productQuestionId 产品题目ID
+     * @return 是否删除成功
+     */
+    boolean deleteByProductQuestionId(String productQuestionId);
+
+    /**
+     * 根据公司ID删除产品题目关系
+     * @param companyId 公司ID
+     * @return 是否删除成功
+     */
+    boolean deleteByCompanyId(String companyId);
+
+    /**
+     * 根据产品ID和产品题目ID删除产品题目关系
+     * @param productId 产品ID
+     * @param productQuestionId 产品题目ID
+     * @return 是否删除成功
+     */
+    boolean deleteByProductIdAndProductQuestionId(String productId, String productQuestionId);
+}
diff --git a/src/main/java/cc/mrbird/febs/ai/service/AiProductQuestionService.java b/src/main/java/cc/mrbird/febs/ai/service/AiProductQuestionService.java
new file mode 100644
index 0000000..1b31504
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/ai/service/AiProductQuestionService.java
@@ -0,0 +1,128 @@
+package cc.mrbird.febs.ai.service;
+
+import cc.mrbird.febs.ai.entity.AiProductQuestion;
+import com.baomidou.mybatisplus.extension.service.IService;
+import java.util.List;
+
+/**
+ * AI产品题目 Service接口
+ *
+ * @author yourname
+ * @date 2025-07-29
+ */
+public interface AiProductQuestionService extends IService<AiProductQuestion> {
+
+    /**
+     * 根据ID查询AI产品题目
+     * @param id 题目ID
+     * @return AI产品题目信息
+     */
+    AiProductQuestion getById(String id);
+
+    /**
+     * 根据公司ID查询AI产品题目列表
+     * @param companyId 公司ID
+     * @return AI产品题目列表
+     */
+    List<AiProductQuestion> getByCompanyId(String companyId);
+
+    /**
+     * 根据AI产品类别ID查询AI产品题目列表
+     * @param productCategoryId AI产品类别ID
+     * @return AI产品题目列表
+     */
+    List<AiProductQuestion> getByProductCategoryId(String productCategoryId);
+
+    /**
+     * 根据题目查询AI产品题目列表
+     * @param title 题目
+     * @return AI产品题目列表
+     */
+    List<AiProductQuestion> getByTitle(String title);
+
+    /**
+     * 根据父ID查询AI产品题目列表
+     * @param parentId 父ID
+     * @return AI产品题目列表
+     */
+    List<AiProductQuestion> getByParentId(String parentId);
+
+    /**
+     * 根据难度查询AI产品题目列表
+     * @param difficulty 难度:1-简单,2-中等,3-困难
+     * @return AI产品题目列表
+     */
+    List<AiProductQuestion> getByDifficulty(Integer difficulty);
+
+    /**
+     * 根据状态查询AI产品题目列表
+     * @param state 状态 0-禁用 1-启用 2-已删除
+     * @return AI产品题目列表
+     */
+    List<AiProductQuestion> getByState(Integer state);
+
+    /**
+     * 根据是否正确答案查询AI产品题目列表
+     * @param correctAnswer 是否是正确答案 0-否 1-是
+     * @return AI产品题目列表
+     */
+    List<AiProductQuestion> getByCorrectAnswer(Integer correctAnswer);
+
+    /**
+     * 根据公司ID和状态查询AI产品题目列表
+     * @param companyId 公司ID
+     * @param state 状态 0-禁用 1-启用 2-已删除
+     * @return AI产品题目列表
+     */
+    List<AiProductQuestion> getByCompanyIdAndState(String companyId, Integer state);
+
+    /**
+     * 根据父ID和状态查询AI产品题目列表(获取同一题目的所有选项)
+     * @param parentId 父ID
+     * @param state 状态 0-禁用 1-启用 2-已删除
+     * @return AI产品题目列表
+     */
+    List<AiProductQuestion> getByParentIdAndState(String parentId, Integer state);
+
+    /**
+     * 保存AI产品题目
+     * @param aiProductQuestion AI产品题目实体
+     * @return 是否保存成功
+     */
+    boolean saveProductQuestion(AiProductQuestion aiProductQuestion);
+
+    /**
+     * 批量保存AI产品题目
+     * @param productQuestions AI产品题目列表
+     * @return 是否保存成功
+     */
+    boolean saveBatchProductQuestions(List<AiProductQuestion> productQuestions);
+
+    /**
+     * 更新AI产品题目
+     * @param aiProductQuestion AI产品题目实体
+     * @return 是否更新成功
+     */
+    boolean updateProductQuestion(AiProductQuestion aiProductQuestion);
+
+    /**
+     * 根据ID删除AI产品题目
+     * @param id 题目ID
+     * @return 是否删除成功
+     */
+    boolean deleteById(String id);
+
+    /**
+     * 根据父ID删除AI产品题目(删除整个题目及其选项)
+     * @param parentId 父ID
+     * @return 是否删除成功
+     */
+    boolean deleteByParentId(String parentId);
+
+    /**
+     * 根据公司ID删除AI产品题目
+     * @param companyId 公司ID
+     * @return 是否删除成功
+     */
+    boolean deleteByCompanyId(String companyId);
+}
diff --git a/src/main/java/cc/mrbird/febs/ai/service/AiProductRoleService.java b/src/main/java/cc/mrbird/febs/ai/service/AiProductRoleService.java
new file mode 100644
index 0000000..384af47
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/ai/service/AiProductRoleService.java
@@ -0,0 +1,92 @@
+package cc.mrbird.febs.ai.service;
+
+import cc.mrbird.febs.ai.entity.AiProductRole;
+import com.baomidou.mybatisplus.extension.service.IService;
+import java.util.List;
+
+/**
+ * AI产品陪练角色 Service接口
+ *
+ * @author yourname
+ * @date 2025-07-29
+ */
+public interface AiProductRoleService extends IService<AiProductRole> {
+
+    /**
+     * 根据ID查询AI产品角色
+     * @param id 角色ID
+     * @return AI产品角色信息
+     */
+    AiProductRole getById(String id);
+
+    /**
+     * 根据公司ID查询AI产品角色列表
+     * @param companyId 公司ID
+     * @return AI产品角色列表
+     */
+    List<AiProductRole> getByCompanyId(String companyId);
+
+    /**
+     * 根据AI产品ID查询AI产品角色列表
+     * @param productId AI产品ID
+     * @return AI产品角色列表
+     */
+    List<AiProductRole> getByProductId(String productId);
+
+    /**
+     * 根据名称查询AI产品角色列表
+     * @param name 角色名称
+     * @return AI产品角色列表
+     */
+    List<AiProductRole> getByName(String name);
+
+    /**
+     * 根据公司ID和产品ID查询AI产品角色列表
+     * @param companyId 公司ID
+     * @param productId AI产品ID
+     * @return AI产品角色列表
+     */
+    List<AiProductRole> getByCompanyIdAndProductId(String companyId, String productId);
+
+    /**
+     * 保存AI产品角色
+     * @param aiProductRole AI产品角色实体
+     * @return 是否保存成功
+     */
+    boolean saveProductRole(AiProductRole aiProductRole);
+
+    /**
+     * 批量保存AI产品角色
+     * @param productRoles AI产品角色列表
+     * @return 是否保存成功
+     */
+    boolean saveBatchProductRoles(List<AiProductRole> productRoles);
+
+    /**
+     * 更新AI产品角色
+     * @param aiProductRole AI产品角色实体
+     * @return 是否更新成功
+     */
+    boolean updateProductRole(AiProductRole aiProductRole);
+
+    /**
+     * 根据ID删除AI产品角色
+     * @param id 角色ID
+     * @return 是否删除成功
+     */
+    boolean deleteById(String id);
+
+    /**
+     * 根据AI产品ID删除AI产品角色
+     * @param productId AI产品ID
+     * @return 是否删除成功
+     */
+    boolean deleteByProductId(String productId);
+
+    /**
+     * 根据公司ID删除AI产品角色
+     * @param companyId 公司ID
+     * @return 是否删除成功
+     */
+    boolean deleteByCompanyId(String companyId);
+}
diff --git a/src/main/java/cc/mrbird/febs/ai/service/AiProductService.java b/src/main/java/cc/mrbird/febs/ai/service/AiProductService.java
new file mode 100644
index 0000000..7e5b27a
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/ai/service/AiProductService.java
@@ -0,0 +1,114 @@
+package cc.mrbird.febs.ai.service;
+
+import cc.mrbird.febs.ai.entity.AiProduct;
+import com.baomidou.mybatisplus.extension.service.IService;
+import java.util.List;
+
+/**
+ * AI产品表 Service接口
+ *
+ * @author yourname
+ * @date 2025-07-29
+ */
+public interface AiProductService extends IService<AiProduct> {
+
+    /**
+     * 根据ID查询AI产品
+     * @param id 产品ID
+     * @return AI产品信息
+     */
+    AiProduct getById(String id);
+
+    /**
+     * 根据公司ID查询AI产品列表
+     * @param companyId 公司ID
+     * @return AI产品列表
+     */
+    List<AiProduct> getByCompanyId(String companyId);
+
+    /**
+     * 根据编码查询AI产品
+     * @param code 产品编码
+     * @return AI产品信息
+     */
+    AiProduct getByCode(String code);
+
+    /**
+     * 根据名称查询AI产品列表
+     * @param name 产品名称
+     * @return AI产品列表
+     */
+    List<AiProduct> getByName(String name);
+
+    /**
+     * 根据产品类别ID查询AI产品列表
+     * @param productCategoryId 产品类别ID
+     * @return AI产品列表
+     */
+    List<AiProduct> getByProductCategoryId(String productCategoryId);
+
+    /**
+     * 根据状态查询AI产品列表
+     * @param state 状态 0-禁用 1-启用 2-已删除
+     * @return AI产品列表
+     */
+    List<AiProduct> getByState(Integer state);
+
+    /**
+     * 根据是否推荐查询AI产品列表
+     * @param hotState 是否推荐到首页 1-推荐 0-不推荐
+     * @return AI产品列表
+     */
+    List<AiProduct> getByHotState(Integer hotState);
+
+    /**
+     * 根据公司ID和状态查询AI产品列表
+     * @param companyId 公司ID
+     * @param state 状态 0-禁用 1-启用 2-已删除
+     * @return AI产品列表
+     */
+    List<AiProduct> getByCompanyIdAndState(String companyId, Integer state);
+
+    /**
+     * 根据公司ID和推荐状态查询AI产品列表
+     * @param companyId 公司ID
+     * @param hotState 是否推荐到首页 1-推荐 0-不推荐
+     * @return AI产品列表
+     */
+    List<AiProduct> getByCompanyIdAndHotState(String companyId, Integer hotState);
+
+    /**
+     * 保存AI产品
+     * @param aiProduct AI产品实体
+     * @return 是否保存成功
+     */
+    boolean saveProduct(AiProduct aiProduct);
+
+    /**
+     * 批量保存AI产品
+     * @param products AI产品列表
+     * @return 是否保存成功
+     */
+    boolean saveBatchProducts(List<AiProduct> products);
+
+    /**
+     * 更新AI产品
+     * @param aiProduct AI产品实体
+     * @return 是否更新成功
+     */
+    boolean updateProduct(AiProduct aiProduct);
+
+    /**
+     * 根据ID删除AI产品
+     * @param id 产品ID
+     * @return 是否删除成功
+     */
+    boolean deleteById(String id);
+
+    /**
+     * 根据公司ID删除AI产品
+     * @param companyId 公司ID
+     * @return 是否删除成功
+     */
+    boolean deleteByCompanyId(String companyId);
+}
diff --git a/src/main/java/cc/mrbird/febs/ai/service/impl/AiMemberAnswerItemServiceImpl.java b/src/main/java/cc/mrbird/febs/ai/service/impl/AiMemberAnswerItemServiceImpl.java
new file mode 100644
index 0000000..22bc4e1
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/ai/service/impl/AiMemberAnswerItemServiceImpl.java
@@ -0,0 +1,154 @@
+package cc.mrbird.febs.ai.service.impl;
+
+import cc.mrbird.febs.ai.entity.AiMemberAnswerItem;
+import cc.mrbird.febs.ai.mapper.AiMemberAnswerItemMapper;
+import cc.mrbird.febs.ai.service.AiMemberAnswerItemService;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+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实现类
+ *
+ * @author yourname
+ * @date 2025-07-29
+ */
+@Slf4j
+@Service
+@RequiredArgsConstructor
+public class AiMemberAnswerItemServiceImpl extends ServiceImpl<AiMemberAnswerItemMapper, AiMemberAnswerItem> implements AiMemberAnswerItemService {
+
+    private final AiMemberAnswerItemMapper aiMemberAnswerItemMapper;
+
+    @Override
+    public AiMemberAnswerItem getById(String id) {
+        return this.getById(id);
+    }
+
+    @Override
+    public List<AiMemberAnswerItem> getByAnswerId(String answerId) {
+        LambdaQueryWrapper<AiMemberAnswerItem> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(AiMemberAnswerItem::getAnswerId, answerId);
+        queryWrapper.orderByAsc(AiMemberAnswerItem::getCreatedTime);
+        return this.list(queryWrapper);
+    }
+
+    @Override
+    public List<AiMemberAnswerItem> getByMemberId(String memberId) {
+        LambdaQueryWrapper<AiMemberAnswerItem> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(AiMemberAnswerItem::getMemberId, memberId);
+        queryWrapper.orderByDesc(AiMemberAnswerItem::getCreatedTime);
+        return this.list(queryWrapper);
+    }
+
+    @Override
+    public List<AiMemberAnswerItem> getByProductId(String productId) {
+        LambdaQueryWrapper<AiMemberAnswerItem> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(AiMemberAnswerItem::getProductId, productId);
+        queryWrapper.orderByDesc(AiMemberAnswerItem::getCreatedTime);
+        return this.list(queryWrapper);
+    }
+
+    @Override
+    public List<AiMemberAnswerItem> getByProductQuestionParentId(String productQuestionParentId) {
+        LambdaQueryWrapper<AiMemberAnswerItem> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(AiMemberAnswerItem::getProductQuestionParentId, productQuestionParentId);
+        queryWrapper.orderByAsc(AiMemberAnswerItem::getCreatedTime);
+        return this.list(queryWrapper);
+    }
+
+    @Override
+    public List<AiMemberAnswerItem> getByProductQuestionId(String productQuestionId) {
+        LambdaQueryWrapper<AiMemberAnswerItem> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(AiMemberAnswerItem::getProductQuestionId, productQuestionId);
+        queryWrapper.orderByAsc(AiMemberAnswerItem::getCreatedTime);
+        return this.list(queryWrapper);
+    }
+
+    @Override
+    public List<AiMemberAnswerItem> getByMemberAnswerState(Integer memberAnswerState) {
+        LambdaQueryWrapper<AiMemberAnswerItem> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(AiMemberAnswerItem::getMemberAnswerState, memberAnswerState);
+        queryWrapper.orderByDesc(AiMemberAnswerItem::getCreatedTime);
+        return this.list(queryWrapper);
+    }
+
+    @Override
+    public List<AiMemberAnswerItem> getByIsCollected(Integer isCollected) {
+        LambdaQueryWrapper<AiMemberAnswerItem> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(AiMemberAnswerItem::getIsCollected, isCollected);
+        queryWrapper.orderByDesc(AiMemberAnswerItem::getCreatedTime);
+        return this.list(queryWrapper);
+    }
+
+    @Override
+    public List<AiMemberAnswerItem> getByCompanyIdAndMemberId(String companyId, String memberId) {
+        LambdaQueryWrapper<AiMemberAnswerItem> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(AiMemberAnswerItem::getCompanyId, companyId);
+        queryWrapper.eq(AiMemberAnswerItem::getMemberId, memberId);
+        queryWrapper.orderByDesc(AiMemberAnswerItem::getCreatedTime);
+        return this.list(queryWrapper);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean saveAnswerItem(AiMemberAnswerItem aiMemberAnswerItem) {
+        try {
+            return this.save(aiMemberAnswerItem);
+        } catch (Exception e) {
+            log.error("保存答题记录项失败: ", e);
+            return false;
+        }
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean saveBatchAnswerItems(List<AiMemberAnswerItem> answerItems) {
+        try {
+            return this.saveBatch(answerItems);
+        } catch (Exception e) {
+            log.error("批量保存答题记录项失败: ", e);
+            return false;
+        }
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean updateAnswerItem(AiMemberAnswerItem aiMemberAnswerItem) {
+        try {
+            return this.updateById(aiMemberAnswerItem);
+        } catch (Exception e) {
+            log.error("更新答题记录项失败: ", e);
+            return false;
+        }
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean deleteById(String id) {
+        try {
+            return this.removeById(id);
+        } catch (Exception e) {
+            log.error("删除答题记录项失败: ", e);
+            return false;
+        }
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean deleteByAnswerId(String answerId) {
+        try {
+            LambdaQueryWrapper<AiMemberAnswerItem> queryWrapper = new LambdaQueryWrapper<>();
+            queryWrapper.eq(AiMemberAnswerItem::getAnswerId, answerId);
+            return this.remove(queryWrapper);
+        } catch (Exception e) {
+            log.error("根据答题记录ID删除答题记录项失败: ", e);
+            return false;
+        }
+    }
+}
diff --git a/src/main/java/cc/mrbird/febs/ai/service/impl/AiMemberAnswerServiceImpl.java b/src/main/java/cc/mrbird/febs/ai/service/impl/AiMemberAnswerServiceImpl.java
new file mode 100644
index 0000000..9a4d288
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/ai/service/impl/AiMemberAnswerServiceImpl.java
@@ -0,0 +1,148 @@
+package cc.mrbird.febs.ai.service.impl;
+
+import cc.mrbird.febs.ai.entity.AiMemberAnswer;
+import cc.mrbird.febs.ai.mapper.AiMemberAnswerMapper;
+import cc.mrbird.febs.ai.service.AiMemberAnswerService;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+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实现类
+ *
+ * @author yourname
+ * @date 2025-07-29
+ */
+@Slf4j
+@Service
+@RequiredArgsConstructor
+public class AiMemberAnswerServiceImpl extends ServiceImpl<AiMemberAnswerMapper, AiMemberAnswer> implements AiMemberAnswerService {
+
+    private final AiMemberAnswerMapper aiMemberAnswerMapper;
+
+    @Override
+    public AiMemberAnswer getById(String id) {
+        return this.getById(id);
+    }
+
+    @Override
+    public List<AiMemberAnswer> getByMemberId(String memberId) {
+        LambdaQueryWrapper<AiMemberAnswer> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(AiMemberAnswer::getMemberId, memberId);
+        queryWrapper.orderByDesc(AiMemberAnswer::getCreatedTime);
+        return this.list(queryWrapper);
+    }
+
+    @Override
+    public List<AiMemberAnswer> getByProductId(String productId) {
+        LambdaQueryWrapper<AiMemberAnswer> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(AiMemberAnswer::getProductId, productId);
+        queryWrapper.orderByDesc(AiMemberAnswer::getCreatedTime);
+        return this.list(queryWrapper);
+    }
+
+    @Override
+    public List<AiMemberAnswer> getByCompanyId(String companyId) {
+        LambdaQueryWrapper<AiMemberAnswer> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(AiMemberAnswer::getCompanyId, companyId);
+        queryWrapper.orderByDesc(AiMemberAnswer::getCreatedTime);
+        return this.list(queryWrapper);
+    }
+
+    @Override
+    public List<AiMemberAnswer> getByState(Integer state) {
+        LambdaQueryWrapper<AiMemberAnswer> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(AiMemberAnswer::getState, state);
+        queryWrapper.orderByDesc(AiMemberAnswer::getCreatedTime);
+        return this.list(queryWrapper);
+    }
+
+    @Override
+    public List<AiMemberAnswer> getByMemberIdAndState(String memberId, Integer state) {
+        LambdaQueryWrapper<AiMemberAnswer> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(AiMemberAnswer::getMemberId, memberId);
+        queryWrapper.eq(AiMemberAnswer::getState, state);
+        queryWrapper.orderByDesc(AiMemberAnswer::getCreatedTime);
+        return this.list(queryWrapper);
+    }
+
+    @Override
+    public List<AiMemberAnswer> getByCompanyIdAndMemberId(String companyId, String memberId) {
+        LambdaQueryWrapper<AiMemberAnswer> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(AiMemberAnswer::getCompanyId, companyId);
+        queryWrapper.eq(AiMemberAnswer::getMemberId, memberId);
+        queryWrapper.orderByDesc(AiMemberAnswer::getCreatedTime);
+        return this.list(queryWrapper);
+    }
+
+    @Override
+    public List<AiMemberAnswer> getByScoreRange(Integer minScore, Integer maxScore) {
+        LambdaQueryWrapper<AiMemberAnswer> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.ge(AiMemberAnswer::getScore, minScore);
+        queryWrapper.le(AiMemberAnswer::getScore, maxScore);
+        queryWrapper.orderByDesc(AiMemberAnswer::getCreatedTime);
+        return this.list(queryWrapper);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean saveAnswer(AiMemberAnswer aiMemberAnswer) {
+        try {
+            return this.save(aiMemberAnswer);
+        } catch (Exception e) {
+            log.error("保存答题记录失败: ", e);
+            return false;
+        }
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean saveBatchAnswers(List<AiMemberAnswer> answers) {
+        try {
+            return this.saveBatch(answers);
+        } catch (Exception e) {
+            log.error("批量保存答题记录失败: ", e);
+            return false;
+        }
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean updateAnswer(AiMemberAnswer aiMemberAnswer) {
+        try {
+            return this.updateById(aiMemberAnswer);
+        } catch (Exception e) {
+            log.error("更新答题记录失败: ", e);
+            return false;
+        }
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean deleteById(String id) {
+        try {
+            return this.removeById(id);
+        } catch (Exception e) {
+            log.error("删除答题记录失败: ", e);
+            return false;
+        }
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean deleteByMemberId(String memberId) {
+        try {
+            LambdaQueryWrapper<AiMemberAnswer> queryWrapper = new LambdaQueryWrapper<>();
+            queryWrapper.eq(AiMemberAnswer::getMemberId, memberId);
+            return this.remove(queryWrapper);
+        } catch (Exception e) {
+            log.error("根据用户ID删除答题记录失败: ", e);
+            return false;
+        }
+    }
+}
diff --git a/src/main/java/cc/mrbird/febs/ai/service/impl/AiMemberRoleCategoryServiceImpl.java b/src/main/java/cc/mrbird/febs/ai/service/impl/AiMemberRoleCategoryServiceImpl.java
new file mode 100644
index 0000000..e5969dc
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/ai/service/impl/AiMemberRoleCategoryServiceImpl.java
@@ -0,0 +1,145 @@
+package cc.mrbird.febs.ai.service.impl;
+
+import cc.mrbird.febs.ai.entity.AiMemberRoleCategory;
+import cc.mrbird.febs.ai.mapper.AiMemberRoleCategoryMapper;
+import cc.mrbird.febs.ai.service.AiMemberRoleCategoryService;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+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实现类
+ *
+ * @author yourname
+ * @date 2025-07-29
+ */
+@Slf4j
+@Service
+@RequiredArgsConstructor
+public class AiMemberRoleCategoryServiceImpl extends ServiceImpl<AiMemberRoleCategoryMapper, AiMemberRoleCategory> implements AiMemberRoleCategoryService {
+
+    private final AiMemberRoleCategoryMapper aiMemberRoleCategoryMapper;
+
+    @Override
+    public AiMemberRoleCategory getById(String id) {
+        return this.getById(id);
+    }
+
+    @Override
+    public List<AiMemberRoleCategory> getByRoleId(String roleId) {
+        LambdaQueryWrapper<AiMemberRoleCategory> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(AiMemberRoleCategory::getRoleId, roleId);
+        return this.list(queryWrapper);
+    }
+
+    @Override
+    public List<AiMemberRoleCategory> getByProductCategoryId(String productCategoryId) {
+        LambdaQueryWrapper<AiMemberRoleCategory> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(AiMemberRoleCategory::getProductCategoryId, productCategoryId);
+        return this.list(queryWrapper);
+    }
+
+    @Override
+    public List<AiMemberRoleCategory> getByCompanyId(String companyId) {
+        LambdaQueryWrapper<AiMemberRoleCategory> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(AiMemberRoleCategory::getCompanyId, companyId);
+        return this.list(queryWrapper);
+    }
+
+    @Override
+    public List<AiMemberRoleCategory> getByRoleIdAndProductCategoryId(String roleId, String productCategoryId) {
+        LambdaQueryWrapper<AiMemberRoleCategory> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(AiMemberRoleCategory::getRoleId, roleId);
+        queryWrapper.eq(AiMemberRoleCategory::getProductCategoryId, productCategoryId);
+        return this.list(queryWrapper);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean saveRoleCategory(AiMemberRoleCategory aiMemberRoleCategory) {
+        try {
+            return this.save(aiMemberRoleCategory);
+        } catch (Exception e) {
+            log.error("保存角色产品分类关联记录失败: ", e);
+            return false;
+        }
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean saveBatchRoleCategories(List<AiMemberRoleCategory> roleCategories) {
+        try {
+            return this.saveBatch(roleCategories);
+        } catch (Exception e) {
+            log.error("批量保存角色产品分类关联记录失败: ", e);
+            return false;
+        }
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean updateRoleCategory(AiMemberRoleCategory aiMemberRoleCategory) {
+        try {
+            return this.updateById(aiMemberRoleCategory);
+        } catch (Exception e) {
+            log.error("更新角色产品分类关联记录失败: ", e);
+            return false;
+        }
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean deleteById(String id) {
+        try {
+            return this.removeById(id);
+        } catch (Exception e) {
+            log.error("删除角色产品分类关联记录失败: ", e);
+            return false;
+        }
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean deleteByRoleId(String roleId) {
+        try {
+            LambdaQueryWrapper<AiMemberRoleCategory> queryWrapper = new LambdaQueryWrapper<>();
+            queryWrapper.eq(AiMemberRoleCategory::getRoleId, roleId);
+            return this.remove(queryWrapper);
+        } catch (Exception e) {
+            log.error("根据角色ID删除角色产品分类关联记录失败: ", e);
+            return false;
+        }
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean deleteByProductCategoryId(String productCategoryId) {
+        try {
+            LambdaQueryWrapper<AiMemberRoleCategory> queryWrapper = new LambdaQueryWrapper<>();
+            queryWrapper.eq(AiMemberRoleCategory::getProductCategoryId, productCategoryId);
+            return this.remove(queryWrapper);
+        } catch (Exception e) {
+            log.error("根据产品分类ID删除角色产品分类关联记录失败: ", e);
+            return false;
+        }
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean deleteByRoleIdAndProductCategoryId(String roleId, String productCategoryId) {
+        try {
+            LambdaQueryWrapper<AiMemberRoleCategory> queryWrapper = new LambdaQueryWrapper<>();
+            queryWrapper.eq(AiMemberRoleCategory::getRoleId, roleId);
+            queryWrapper.eq(AiMemberRoleCategory::getProductCategoryId, productCategoryId);
+            return this.remove(queryWrapper);
+        } catch (Exception e) {
+            log.error("根据角色ID和产品分类ID删除角色产品分类关联记录失败: ", e);
+            return false;
+        }
+    }
+}
diff --git a/src/main/java/cc/mrbird/febs/ai/service/impl/AiMemberRoleProductServiceImpl.java b/src/main/java/cc/mrbird/febs/ai/service/impl/AiMemberRoleProductServiceImpl.java
new file mode 100644
index 0000000..8ba2b70
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/ai/service/impl/AiMemberRoleProductServiceImpl.java
@@ -0,0 +1,145 @@
+package cc.mrbird.febs.ai.service.impl;
+
+import cc.mrbird.febs.ai.entity.AiMemberRoleProduct;
+import cc.mrbird.febs.ai.mapper.AiMemberRoleProductMapper;
+import cc.mrbird.febs.ai.service.AiMemberRoleProductService;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+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实现类
+ *
+ * @author yourname
+ * @date 2025-07-29
+ */
+@Slf4j
+@Service
+@RequiredArgsConstructor
+public class AiMemberRoleProductServiceImpl extends ServiceImpl<AiMemberRoleProductMapper, AiMemberRoleProduct> implements AiMemberRoleProductService {
+
+    private final AiMemberRoleProductMapper aiMemberRoleProductMapper;
+
+    @Override
+    public AiMemberRoleProduct getById(String id) {
+        return this.getById(id);
+    }
+
+    @Override
+    public List<AiMemberRoleProduct> getByRoleId(String roleId) {
+        LambdaQueryWrapper<AiMemberRoleProduct> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(AiMemberRoleProduct::getRoleId, roleId);
+        return this.list(queryWrapper);
+    }
+
+    @Override
+    public List<AiMemberRoleProduct> getByProductId(String productId) {
+        LambdaQueryWrapper<AiMemberRoleProduct> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(AiMemberRoleProduct::getProductId, productId);
+        return this.list(queryWrapper);
+    }
+
+    @Override
+    public List<AiMemberRoleProduct> getByCompanyId(String companyId) {
+        LambdaQueryWrapper<AiMemberRoleProduct> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(AiMemberRoleProduct::getCompanyId, companyId);
+        return this.list(queryWrapper);
+    }
+
+    @Override
+    public List<AiMemberRoleProduct> getByRoleIdAndProductId(String roleId, String productId) {
+        LambdaQueryWrapper<AiMemberRoleProduct> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(AiMemberRoleProduct::getRoleId, roleId);
+        queryWrapper.eq(AiMemberRoleProduct::getProductId, productId);
+        return this.list(queryWrapper);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean saveRoleProduct(AiMemberRoleProduct aiMemberRoleProduct) {
+        try {
+            return this.save(aiMemberRoleProduct);
+        } catch (Exception e) {
+            log.error("保存角色产品关联记录失败: ", e);
+            return false;
+        }
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean saveBatchRoleProducts(List<AiMemberRoleProduct> roleProducts) {
+        try {
+            return this.saveBatch(roleProducts);
+        } catch (Exception e) {
+            log.error("批量保存角色产品关联记录失败: ", e);
+            return false;
+        }
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean updateRoleProduct(AiMemberRoleProduct aiMemberRoleProduct) {
+        try {
+            return this.updateById(aiMemberRoleProduct);
+        } catch (Exception e) {
+            log.error("更新角色产品关联记录失败: ", e);
+            return false;
+        }
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean deleteById(String id) {
+        try {
+            return this.removeById(id);
+        } catch (Exception e) {
+            log.error("删除角色产品关联记录失败: ", e);
+            return false;
+        }
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean deleteByRoleId(String roleId) {
+        try {
+            LambdaQueryWrapper<AiMemberRoleProduct> queryWrapper = new LambdaQueryWrapper<>();
+            queryWrapper.eq(AiMemberRoleProduct::getRoleId, roleId);
+            return this.remove(queryWrapper);
+        } catch (Exception e) {
+            log.error("根据角色ID删除角色产品关联记录失败: ", e);
+            return false;
+        }
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean deleteByProductId(String productId) {
+        try {
+            LambdaQueryWrapper<AiMemberRoleProduct> queryWrapper = new LambdaQueryWrapper<>();
+            queryWrapper.eq(AiMemberRoleProduct::getProductId, productId);
+            return this.remove(queryWrapper);
+        } catch (Exception e) {
+            log.error("根据产品ID删除角色产品关联记录失败: ", e);
+            return false;
+        }
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean deleteByRoleIdAndProductId(String roleId, String productId) {
+        try {
+            LambdaQueryWrapper<AiMemberRoleProduct> queryWrapper = new LambdaQueryWrapper<>();
+            queryWrapper.eq(AiMemberRoleProduct::getRoleId, roleId);
+            queryWrapper.eq(AiMemberRoleProduct::getProductId, productId);
+            return this.remove(queryWrapper);
+        } catch (Exception e) {
+            log.error("根据角色ID和产品ID删除角色产品关联记录失败: ", e);
+            return false;
+        }
+    }
+}
diff --git a/src/main/java/cc/mrbird/febs/ai/service/impl/AiMemberRoleServiceImpl.java b/src/main/java/cc/mrbird/febs/ai/service/impl/AiMemberRoleServiceImpl.java
new file mode 100644
index 0000000..c0e8f0a
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/ai/service/impl/AiMemberRoleServiceImpl.java
@@ -0,0 +1,129 @@
+package cc.mrbird.febs.ai.service.impl;
+
+import cc.mrbird.febs.ai.entity.AiMemberRole;
+import cc.mrbird.febs.ai.mapper.AiMemberRoleMapper;
+import cc.mrbird.febs.ai.service.AiMemberRoleService;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+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实现类
+ *
+ * @author yourname
+ * @date 2025-07-29
+ */
+@Slf4j
+@Service
+@RequiredArgsConstructor
+public class AiMemberRoleServiceImpl extends ServiceImpl<AiMemberRoleMapper, AiMemberRole> implements AiMemberRoleService {
+
+    private final AiMemberRoleMapper aiMemberRoleMapper;
+
+    @Override
+    public AiMemberRole getById(String id) {
+        return this.getById(id);
+    }
+
+    @Override
+    public List<AiMemberRole> getByCompanyId(String companyId) {
+        LambdaQueryWrapper<AiMemberRole> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(AiMemberRole::getCompanyId, companyId);
+        queryWrapper.orderByDesc(AiMemberRole::getCreatedTime);
+        return this.list(queryWrapper);
+    }
+
+    @Override
+    public AiMemberRole getByCode(String code) {
+        LambdaQueryWrapper<AiMemberRole> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(AiMemberRole::getCode, code);
+        return this.getOne(queryWrapper);
+    }
+
+    @Override
+    public List<AiMemberRole> getByName(String name) {
+        LambdaQueryWrapper<AiMemberRole> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(AiMemberRole::getName, name);
+        queryWrapper.orderByDesc(AiMemberRole::getCreatedTime);
+        return this.list(queryWrapper);
+    }
+
+    @Override
+    public List<AiMemberRole> getByState(Integer state) {
+        LambdaQueryWrapper<AiMemberRole> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(AiMemberRole::getState, state);
+        queryWrapper.orderByDesc(AiMemberRole::getCreatedTime);
+        return this.list(queryWrapper);
+    }
+
+    @Override
+    public List<AiMemberRole> getByCompanyIdAndState(String companyId, Integer state) {
+        LambdaQueryWrapper<AiMemberRole> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(AiMemberRole::getCompanyId, companyId);
+        queryWrapper.eq(AiMemberRole::getState, state);
+        queryWrapper.orderByDesc(AiMemberRole::getCreatedTime);
+        return this.list(queryWrapper);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean saveRole(AiMemberRole aiMemberRole) {
+        try {
+            return this.save(aiMemberRole);
+        } catch (Exception e) {
+            log.error("保存角色失败: ", e);
+            return false;
+        }
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean saveBatchRoles(List<AiMemberRole> roles) {
+        try {
+            return this.saveBatch(roles);
+        } catch (Exception e) {
+            log.error("批量保存角色失败: ", e);
+            return false;
+        }
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean updateRole(AiMemberRole aiMemberRole) {
+        try {
+            return this.updateById(aiMemberRole);
+        } catch (Exception e) {
+            log.error("更新角色失败: ", e);
+            return false;
+        }
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean deleteById(String id) {
+        try {
+            return this.removeById(id);
+        } catch (Exception e) {
+            log.error("删除角色失败: ", e);
+            return false;
+        }
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean deleteByCompanyId(String companyId) {
+        try {
+            LambdaQueryWrapper<AiMemberRole> queryWrapper = new LambdaQueryWrapper<>();
+            queryWrapper.eq(AiMemberRole::getCompanyId, companyId);
+            return this.remove(queryWrapper);
+        } catch (Exception e) {
+            log.error("根据公司ID删除角色失败: ", e);
+            return false;
+        }
+    }
+}
diff --git a/src/main/java/cc/mrbird/febs/ai/service/impl/AiMemberTalkItemServiceImpl.java b/src/main/java/cc/mrbird/febs/ai/service/impl/AiMemberTalkItemServiceImpl.java
new file mode 100644
index 0000000..4810016
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/ai/service/impl/AiMemberTalkItemServiceImpl.java
@@ -0,0 +1,113 @@
+package cc.mrbird.febs.ai.service.impl;
+
+import cc.mrbird.febs.ai.entity.AiMemberTalkItem;
+import cc.mrbird.febs.ai.mapper.AiMemberTalkItemMapper;
+import cc.mrbird.febs.ai.service.AiMemberTalkItemService;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+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实现类
+ *
+ * @author yourname
+ * @date 2025-07-29
+ */
+@Slf4j
+@Service
+@RequiredArgsConstructor
+public class AiMemberTalkItemServiceImpl extends ServiceImpl<AiMemberTalkItemMapper, AiMemberTalkItem> implements AiMemberTalkItemService {
+
+    private final AiMemberTalkItemMapper aiMemberTalkItemMapper;
+
+    @Override
+    public AiMemberTalkItem getById(String id) {
+        return this.getById(id);
+    }
+
+    @Override
+    public List<AiMemberTalkItem> getByMemberTalkId(String memberTalkId) {
+        LambdaQueryWrapper<AiMemberTalkItem> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(AiMemberTalkItem::getMemberTalkId, memberTalkId);
+        queryWrapper.orderByAsc(AiMemberTalkItem::getCreatedTime);
+        return this.list(queryWrapper);
+    }
+
+    @Override
+    public List<AiMemberTalkItem> getByMemberId(String memberId) {
+        LambdaQueryWrapper<AiMemberTalkItem> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(AiMemberTalkItem::getMemberId, memberId);
+        queryWrapper.orderByAsc(AiMemberTalkItem::getCreatedTime);
+        return this.list(queryWrapper);
+    }
+
+    @Override
+    public List<AiMemberTalkItem> getByType(Integer type) {
+        LambdaQueryWrapper<AiMemberTalkItem> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(AiMemberTalkItem::getType, type);
+        queryWrapper.orderByAsc(AiMemberTalkItem::getCreatedTime);
+        return this.list(queryWrapper);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean saveTalkItem(AiMemberTalkItem aiMemberTalkItem) {
+        try {
+            return this.save(aiMemberTalkItem);
+        } catch (Exception e) {
+            log.error("保存对话项失败: ", e);
+            return false;
+        }
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean saveBatchTalkItems(List<AiMemberTalkItem> talkItems) {
+        try {
+            return this.saveBatch(talkItems);
+        } catch (Exception e) {
+            log.error("批量保存对话项失败: ", e);
+            return false;
+        }
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean updateTalkItem(AiMemberTalkItem aiMemberTalkItem) {
+        try {
+            return this.updateById(aiMemberTalkItem);
+        } catch (Exception e) {
+            log.error("更新对话项失败: ", e);
+            return false;
+        }
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean deleteById(String id) {
+        try {
+            return this.removeById(id);
+        } catch (Exception e) {
+            log.error("删除对话项失败: ", e);
+            return false;
+        }
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean deleteByMemberTalkId(String memberTalkId) {
+        try {
+            LambdaQueryWrapper<AiMemberTalkItem> queryWrapper = new LambdaQueryWrapper<>();
+            queryWrapper.eq(AiMemberTalkItem::getMemberTalkId, memberTalkId);
+            return this.remove(queryWrapper);
+        } catch (Exception e) {
+            log.error("根据对话ID删除对话项失败: ", e);
+            return false;
+        }
+    }
+}
diff --git a/src/main/java/cc/mrbird/febs/ai/service/impl/AiMemberTalkServiceImpl.java b/src/main/java/cc/mrbird/febs/ai/service/impl/AiMemberTalkServiceImpl.java
new file mode 100644
index 0000000..8aaa3f9
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/ai/service/impl/AiMemberTalkServiceImpl.java
@@ -0,0 +1,121 @@
+package cc.mrbird.febs.ai.service.impl;
+
+import cc.mrbird.febs.ai.entity.AiMemberTalk;
+import cc.mrbird.febs.ai.mapper.AiMemberTalkMapper;
+import cc.mrbird.febs.ai.service.AiMemberTalkService;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+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实现类
+ *
+ * @author yourname
+ * @date 2025-07-29
+ */
+@Slf4j
+@Service
+@RequiredArgsConstructor
+public class AiMemberTalkServiceImpl extends ServiceImpl<AiMemberTalkMapper, AiMemberTalk> implements AiMemberTalkService {
+
+    private final AiMemberTalkMapper aiMemberTalkMapper;
+
+    @Override
+    public AiMemberTalk getById(String id) {
+        return this.getById(id);
+    }
+
+    @Override
+    public List<AiMemberTalk> getByMemberId(String memberId) {
+        LambdaQueryWrapper<AiMemberTalk> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(AiMemberTalk::getMemberId, memberId);
+        queryWrapper.orderByDesc(AiMemberTalk::getCreatedTime);
+        return this.list(queryWrapper);
+    }
+
+    @Override
+    public List<AiMemberTalk> getByProductId(String productId) {
+        LambdaQueryWrapper<AiMemberTalk> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(AiMemberTalk::getProductId, productId);
+        queryWrapper.orderByDesc(AiMemberTalk::getCreatedTime);
+        return this.list(queryWrapper);
+    }
+
+    @Override
+    public List<AiMemberTalk> getByProductRoleId(String productRoleId) {
+        LambdaQueryWrapper<AiMemberTalk> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(AiMemberTalk::getProductRoleId, productRoleId);
+        queryWrapper.orderByDesc(AiMemberTalk::getCreatedTime);
+        return this.list(queryWrapper);
+    }
+
+    @Override
+    public List<AiMemberTalk> getByCompanyId(String companyId) {
+        LambdaQueryWrapper<AiMemberTalk> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(AiMemberTalk::getCompanyId, companyId);
+        queryWrapper.orderByDesc(AiMemberTalk::getCreatedTime);
+        return this.list(queryWrapper);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean saveTalk(AiMemberTalk aiMemberTalk) {
+        try {
+            return this.save(aiMemberTalk);
+        } catch (Exception e) {
+            log.error("保存对话记录失败: ", e);
+            return false;
+        }
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean saveBatchTalks(List<AiMemberTalk> talks) {
+        try {
+            return this.saveBatch(talks);
+        } catch (Exception e) {
+            log.error("批量保存对话记录失败: ", e);
+            return false;
+        }
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean updateTalk(AiMemberTalk aiMemberTalk) {
+        try {
+            return this.updateById(aiMemberTalk);
+        } catch (Exception e) {
+            log.error("更新对话记录失败: ", e);
+            return false;
+        }
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean deleteById(String id) {
+        try {
+            return this.removeById(id);
+        } catch (Exception e) {
+            log.error("删除对话记录失败: ", e);
+            return false;
+        }
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean deleteByMemberId(String memberId) {
+        try {
+            LambdaQueryWrapper<AiMemberTalk> queryWrapper = new LambdaQueryWrapper<>();
+            queryWrapper.eq(AiMemberTalk::getMemberId, memberId);
+            return this.remove(queryWrapper);
+        } catch (Exception e) {
+            log.error("根据用户ID删除对话记录失败: ", e);
+            return false;
+        }
+    }
+}
diff --git a/src/main/java/cc/mrbird/febs/ai/service/impl/AiProductCategoryServiceImpl.java b/src/main/java/cc/mrbird/febs/ai/service/impl/AiProductCategoryServiceImpl.java
new file mode 100644
index 0000000..ca52aa9
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/ai/service/impl/AiProductCategoryServiceImpl.java
@@ -0,0 +1,161 @@
+package cc.mrbird.febs.ai.service.impl;
+
+import cc.mrbird.febs.ai.entity.AiProductCategory;
+import cc.mrbird.febs.ai.mapper.AiProductCategoryMapper;
+import cc.mrbird.febs.ai.service.AiProductCategoryService;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+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实现类
+ *
+ * @author yourname
+ * @date 2025-07-29
+ */
+@Slf4j
+@Service
+@RequiredArgsConstructor
+public class AiProductCategoryServiceImpl extends ServiceImpl<AiProductCategoryMapper, AiProductCategory> implements AiProductCategoryService {
+
+    private final AiProductCategoryMapper aiProductCategoryMapper;
+
+    @Override
+    public AiProductCategory getById(String id) {
+        return this.getById(id);
+    }
+
+    @Override
+    public List<AiProductCategory> getByCompanyId(String companyId) {
+        LambdaQueryWrapper<AiProductCategory> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(AiProductCategory::getCompanyId, companyId);
+        queryWrapper.orderByAsc(AiProductCategory::getSort);
+        queryWrapper.orderByDesc(AiProductCategory::getCreatedTime);
+        return this.list(queryWrapper);
+    }
+
+    @Override
+    public AiProductCategory getByCode(String code) {
+        LambdaQueryWrapper<AiProductCategory> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(AiProductCategory::getCode, code);
+        return this.getOne(queryWrapper);
+    }
+
+    @Override
+    public List<AiProductCategory> getByName(String name) {
+        LambdaQueryWrapper<AiProductCategory> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.like(AiProductCategory::getName, name);
+        queryWrapper.orderByAsc(AiProductCategory::getSort);
+        queryWrapper.orderByDesc(AiProductCategory::getCreatedTime);
+        return this.list(queryWrapper);
+    }
+
+    @Override
+    public List<AiProductCategory> getByState(Integer state) {
+        LambdaQueryWrapper<AiProductCategory> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(AiProductCategory::getState, state);
+        queryWrapper.orderByAsc(AiProductCategory::getSort);
+        queryWrapper.orderByDesc(AiProductCategory::getCreatedTime);
+        return this.list(queryWrapper);
+    }
+
+    @Override
+    public List<AiProductCategory> getByHotState(Integer hotState) {
+        LambdaQueryWrapper<AiProductCategory> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(AiProductCategory::getHotState, hotState);
+        queryWrapper.orderByAsc(AiProductCategory::getSort);
+        queryWrapper.orderByDesc(AiProductCategory::getCreatedTime);
+        return this.list(queryWrapper);
+    }
+
+    @Override
+    public List<AiProductCategory> getByCompanyIdAndState(String companyId, Integer state) {
+        LambdaQueryWrapper<AiProductCategory> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(AiProductCategory::getCompanyId, companyId);
+        queryWrapper.eq(AiProductCategory::getState, state);
+        queryWrapper.orderByAsc(AiProductCategory::getSort);
+        queryWrapper.orderByDesc(AiProductCategory::getCreatedTime);
+        return this.list(queryWrapper);
+    }
+
+    @Override
+    public List<AiProductCategory> getByCompanyIdAndHotState(String companyId, Integer hotState) {
+        LambdaQueryWrapper<AiProductCategory> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(AiProductCategory::getCompanyId, companyId);
+        queryWrapper.eq(AiProductCategory::getHotState, hotState);
+        queryWrapper.orderByAsc(AiProductCategory::getSort);
+        queryWrapper.orderByDesc(AiProductCategory::getCreatedTime);
+        return this.list(queryWrapper);
+    }
+
+    @Override
+    public List<AiProductCategory> getEnabledCategories() {
+        LambdaQueryWrapper<AiProductCategory> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(AiProductCategory::getState, 1); // 1-启用
+        queryWrapper.orderByAsc(AiProductCategory::getSort);
+        queryWrapper.orderByDesc(AiProductCategory::getCreatedTime);
+        return this.list(queryWrapper);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean saveProductCategory(AiProductCategory aiProductCategory) {
+        try {
+            return this.save(aiProductCategory);
+        } catch (Exception e) {
+            log.error("保存AI产品类别失败: ", e);
+            return false;
+        }
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean saveBatchProductCategories(List<AiProductCategory> productCategories) {
+        try {
+            return this.saveBatch(productCategories);
+        } catch (Exception e) {
+            log.error("批量保存AI产品类别失败: ", e);
+            return false;
+        }
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean updateProductCategory(AiProductCategory aiProductCategory) {
+        try {
+            return this.updateById(aiProductCategory);
+        } catch (Exception e) {
+            log.error("更新AI产品类别失败: ", e);
+            return false;
+        }
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean deleteById(String id) {
+        try {
+            return this.removeById(id);
+        } catch (Exception e) {
+            log.error("删除AI产品类别失败: ", e);
+            return false;
+        }
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean deleteByCompanyId(String companyId) {
+        try {
+            LambdaQueryWrapper<AiProductCategory> queryWrapper = new LambdaQueryWrapper<>();
+            queryWrapper.eq(AiProductCategory::getCompanyId, companyId);
+            return this.remove(queryWrapper);
+        } catch (Exception e) {
+            log.error("根据公司ID删除AI产品类别失败: ", e);
+            return false;
+        }
+    }
+}
diff --git a/src/main/java/cc/mrbird/febs/ai/service/impl/AiProductPointServiceImpl.java b/src/main/java/cc/mrbird/febs/ai/service/impl/AiProductPointServiceImpl.java
new file mode 100644
index 0000000..0aae32b
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/ai/service/impl/AiProductPointServiceImpl.java
@@ -0,0 +1,153 @@
+package cc.mrbird.febs.ai.service.impl;
+
+import cc.mrbird.febs.ai.entity.AiProductPoint;
+import cc.mrbird.febs.ai.mapper.AiProductPointMapper;
+import cc.mrbird.febs.ai.service.AiProductPointService;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+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实现类
+ *
+ * @author yourname
+ * @date 2025-07-29
+ */
+@Slf4j
+@Service
+@RequiredArgsConstructor
+public class AiProductPointServiceImpl extends ServiceImpl<AiProductPointMapper, AiProductPoint> implements AiProductPointService {
+
+    private final AiProductPointMapper aiProductPointMapper;
+
+    @Override
+    public AiProductPoint getById(String id) {
+        return this.getById(id);
+    }
+
+    @Override
+    public List<AiProductPoint> getByCompanyId(String companyId) {
+        LambdaQueryWrapper<AiProductPoint> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(AiProductPoint::getCompanyId, companyId);
+        queryWrapper.orderByDesc(AiProductPoint::getCreatedTime);
+        return this.list(queryWrapper);
+    }
+
+    @Override
+    public List<AiProductPoint> getByIsNormal(Integer isNormal) {
+        LambdaQueryWrapper<AiProductPoint> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(AiProductPoint::getIsNormal, isNormal);
+        queryWrapper.orderByDesc(AiProductPoint::getCreatedTime);
+        return this.list(queryWrapper);
+    }
+
+    @Override
+    public List<AiProductPoint> getByFinderUserName(String finderUserName) {
+        LambdaQueryWrapper<AiProductPoint> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(AiProductPoint::getFinderUserName, finderUserName);
+        queryWrapper.orderByDesc(AiProductPoint::getCreatedTime);
+        return this.list(queryWrapper);
+    }
+
+    @Override
+    public List<AiProductPoint> getByTitle(String title) {
+        LambdaQueryWrapper<AiProductPoint> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.like(AiProductPoint::getTitle, title);
+        queryWrapper.orderByDesc(AiProductPoint::getCreatedTime);
+        return this.list(queryWrapper);
+    }
+
+    @Override
+    public List<AiProductPoint> getByCompanyIdAndIsNormal(String companyId, Integer isNormal) {
+        LambdaQueryWrapper<AiProductPoint> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(AiProductPoint::getCompanyId, companyId);
+        queryWrapper.eq(AiProductPoint::getIsNormal, isNormal);
+        queryWrapper.orderByDesc(AiProductPoint::getCreatedTime);
+        return this.list(queryWrapper);
+    }
+
+    @Override
+    public List<AiProductPoint> searchByKeyword(String keyword) {
+        LambdaQueryWrapper<AiProductPoint> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.and(wrapper -> wrapper.like(AiProductPoint::getTitle, keyword)
+                .or()
+                .like(AiProductPoint::getDescription, keyword));
+        queryWrapper.orderByDesc(AiProductPoint::getCreatedTime);
+        return this.list(queryWrapper);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean saveProductPoint(AiProductPoint aiProductPoint) {
+        try {
+            return this.save(aiProductPoint);
+        } catch (Exception e) {
+            log.error("保存AI产品知识点失败: ", e);
+            return false;
+        }
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean saveBatchProductPoints(List<AiProductPoint> productPoints) {
+        try {
+            return this.saveBatch(productPoints);
+        } catch (Exception e) {
+            log.error("批量保存AI产品知识点失败: ", e);
+            return false;
+        }
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean updateProductPoint(AiProductPoint aiProductPoint) {
+        try {
+            return this.updateById(aiProductPoint);
+        } catch (Exception e) {
+            log.error("更新AI产品知识点失败: ", e);
+            return false;
+        }
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean deleteById(String id) {
+        try {
+            return this.removeById(id);
+        } catch (Exception e) {
+            log.error("删除AI产品知识点失败: ", e);
+            return false;
+        }
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean deleteByCompanyId(String companyId) {
+        try {
+            LambdaQueryWrapper<AiProductPoint> queryWrapper = new LambdaQueryWrapper<>();
+            queryWrapper.eq(AiProductPoint::getCompanyId, companyId);
+            return this.remove(queryWrapper);
+        } catch (Exception e) {
+            log.error("根据公司ID删除AI产品知识点失败: ", e);
+            return false;
+        }
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean deleteByFeedId(String feedId) {
+        try {
+            LambdaQueryWrapper<AiProductPoint> queryWrapper = new LambdaQueryWrapper<>();
+            queryWrapper.eq(AiProductPoint::getFeedId, feedId);
+            return this.remove(queryWrapper);
+        } catch (Exception e) {
+            log.error("根据视频号FeedID删除AI产品知识点失败: ", e);
+            return false;
+        }
+    }
+}
diff --git a/src/main/java/cc/mrbird/febs/ai/service/impl/AiProductQuestionLinkServiceImpl.java b/src/main/java/cc/mrbird/febs/ai/service/impl/AiProductQuestionLinkServiceImpl.java
new file mode 100644
index 0000000..49cc62c
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/ai/service/impl/AiProductQuestionLinkServiceImpl.java
@@ -0,0 +1,180 @@
+package cc.mrbird.febs.ai.service.impl;
+
+import cc.mrbird.febs.ai.entity.AiProductQuestionLink;
+import cc.mrbird.febs.ai.mapper.AiProductQuestionLinkMapper;
+import cc.mrbird.febs.ai.service.AiProductQuestionLinkService;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+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;
+
+/**
+ * 产品题目关系表 Service实现类
+ *
+ * @author yourname
+ * @date 2025-07-29
+ */
+@Slf4j
+@Service
+@RequiredArgsConstructor
+public class AiProductQuestionLinkServiceImpl extends ServiceImpl<AiProductQuestionLinkMapper, AiProductQuestionLink> implements AiProductQuestionLinkService {
+
+    private final AiProductQuestionLinkMapper aiProductQuestionLinkMapper;
+
+    @Override
+    public AiProductQuestionLink getById(String id) {
+        return this.getById(id);
+    }
+
+    @Override
+    public List<AiProductQuestionLink> getByCompanyId(String companyId) {
+        LambdaQueryWrapper<AiProductQuestionLink> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(AiProductQuestionLink::getCompanyId, companyId);
+        queryWrapper.orderByDesc(AiProductQuestionLink::getCreatedTime);
+        return this.list(queryWrapper);
+    }
+
+    @Override
+    public List<AiProductQuestionLink> getByProductQuestionId(String productQuestionId) {
+        LambdaQueryWrapper<AiProductQuestionLink> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(AiProductQuestionLink::getProductQuestionId, productQuestionId);
+        queryWrapper.orderByDesc(AiProductQuestionLink::getCreatedTime);
+        return this.list(queryWrapper);
+    }
+
+    @Override
+    public List<AiProductQuestionLink> getByProductId(String productId) {
+        LambdaQueryWrapper<AiProductQuestionLink> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(AiProductQuestionLink::getProductId, productId);
+        queryWrapper.orderByDesc(AiProductQuestionLink::getCreatedTime);
+        return this.list(queryWrapper);
+    }
+
+    @Override
+    public List<AiProductQuestionLink> getByCompanyIdAndProductId(String companyId, String productId) {
+        LambdaQueryWrapper<AiProductQuestionLink> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(AiProductQuestionLink::getCompanyId, companyId);
+        queryWrapper.eq(AiProductQuestionLink::getProductId, productId);
+        queryWrapper.orderByDesc(AiProductQuestionLink::getCreatedTime);
+        return this.list(queryWrapper);
+    }
+
+    @Override
+    public List<AiProductQuestionLink> getByCompanyIdAndProductQuestionId(String companyId, String productQuestionId) {
+        LambdaQueryWrapper<AiProductQuestionLink> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(AiProductQuestionLink::getCompanyId, companyId);
+        queryWrapper.eq(AiProductQuestionLink::getProductQuestionId, productQuestionId);
+        queryWrapper.orderByDesc(AiProductQuestionLink::getCreatedTime);
+        return this.list(queryWrapper);
+    }
+
+    @Override
+    public List<AiProductQuestionLink> getByProductIdAndProductQuestionId(String productId, String productQuestionId) {
+        LambdaQueryWrapper<AiProductQuestionLink> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(AiProductQuestionLink::getProductId, productId);
+        queryWrapper.eq(AiProductQuestionLink::getProductQuestionId, productQuestionId);
+        queryWrapper.orderByDesc(AiProductQuestionLink::getCreatedTime);
+        return this.list(queryWrapper);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean saveProductQuestionLink(AiProductQuestionLink aiProductQuestionLink) {
+        try {
+            return this.save(aiProductQuestionLink);
+        } catch (Exception e) {
+            log.error("保存产品题目关系失败: ", e);
+            return false;
+        }
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean saveBatchProductQuestionLinks(List<AiProductQuestionLink> productQuestionLinks) {
+        try {
+            return this.saveBatch(productQuestionLinks);
+        } catch (Exception e) {
+            log.error("批量保存产品题目关系失败: ", e);
+            return false;
+        }
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean updateProductQuestionLink(AiProductQuestionLink aiProductQuestionLink) {
+        try {
+            return this.updateById(aiProductQuestionLink);
+        } catch (Exception e) {
+            log.error("更新产品题目关系失败: ", e);
+            return false;
+        }
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean deleteById(String id) {
+        try {
+            return this.removeById(id);
+        } catch (Exception e) {
+            log.error("删除产品题目关系失败: ", e);
+            return false;
+        }
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean deleteByProductId(String productId) {
+        try {
+            LambdaQueryWrapper<AiProductQuestionLink> queryWrapper = new LambdaQueryWrapper<>();
+            queryWrapper.eq(AiProductQuestionLink::getProductId, productId);
+            return this.remove(queryWrapper);
+        } catch (Exception e) {
+            log.error("根据产品ID删除产品题目关系失败: ", e);
+            return false;
+        }
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean deleteByProductQuestionId(String productQuestionId) {
+        try {
+            LambdaQueryWrapper<AiProductQuestionLink> queryWrapper = new LambdaQueryWrapper<>();
+            queryWrapper.eq(AiProductQuestionLink::getProductQuestionId, productQuestionId);
+            return this.remove(queryWrapper);
+        } catch (Exception e) {
+            log.error("根据产品题目ID删除产品题目关系失败: ", e);
+            return false;
+        }
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean deleteByCompanyId(String companyId) {
+        try {
+            LambdaQueryWrapper<AiProductQuestionLink> queryWrapper = new LambdaQueryWrapper<>();
+            queryWrapper.eq(AiProductQuestionLink::getCompanyId, companyId);
+            return this.remove(queryWrapper);
+        } catch (Exception e) {
+            log.error("根据公司ID删除产品题目关系失败: ", e);
+            return false;
+        }
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean deleteByProductIdAndProductQuestionId(String productId, String productQuestionId) {
+        try {
+            LambdaQueryWrapper<AiProductQuestionLink> queryWrapper = new LambdaQueryWrapper<>();
+            queryWrapper.eq(AiProductQuestionLink::getProductId, productId);
+            queryWrapper.eq(AiProductQuestionLink::getProductQuestionId, productQuestionId);
+            return this.remove(queryWrapper);
+        } catch (Exception e) {
+            log.error("根据产品ID和产品题目ID删除产品题目关系失败: ", e);
+            return false;
+        }
+    }
+}
diff --git a/src/main/java/cc/mrbird/febs/ai/service/impl/AiProductQuestionServiceImpl.java b/src/main/java/cc/mrbird/febs/ai/service/impl/AiProductQuestionServiceImpl.java
new file mode 100644
index 0000000..90d990b
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/ai/service/impl/AiProductQuestionServiceImpl.java
@@ -0,0 +1,176 @@
+package cc.mrbird.febs.ai.service.impl;
+
+import cc.mrbird.febs.ai.entity.AiProductQuestion;
+import cc.mrbird.febs.ai.mapper.AiProductQuestionMapper;
+import cc.mrbird.febs.ai.service.AiProductQuestionService;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+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实现类
+ *
+ * @author yourname
+ * @date 2025-07-29
+ */
+@Slf4j
+@Service
+@RequiredArgsConstructor
+public class AiProductQuestionServiceImpl extends ServiceImpl<AiProductQuestionMapper, AiProductQuestion> implements AiProductQuestionService {
+
+    private final AiProductQuestionMapper aiProductQuestionMapper;
+
+    @Override
+    public AiProductQuestion getById(String id) {
+        return this.getById(id);
+    }
+
+    @Override
+    public List<AiProductQuestion> getByCompanyId(String companyId) {
+        LambdaQueryWrapper<AiProductQuestion> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(AiProductQuestion::getCompanyId, companyId);
+        queryWrapper.orderByDesc(AiProductQuestion::getCreatedTime);
+        return this.list(queryWrapper);
+    }
+
+    @Override
+    public List<AiProductQuestion> getByProductCategoryId(String productCategoryId) {
+        LambdaQueryWrapper<AiProductQuestion> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(AiProductQuestion::getProductCategoryId, productCategoryId);
+        queryWrapper.orderByDesc(AiProductQuestion::getCreatedTime);
+        return this.list(queryWrapper);
+    }
+
+    @Override
+    public List<AiProductQuestion> getByTitle(String title) {
+        LambdaQueryWrapper<AiProductQuestion> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.like(AiProductQuestion::getTitle, title);
+        queryWrapper.orderByDesc(AiProductQuestion::getCreatedTime);
+        return this.list(queryWrapper);
+    }
+
+    @Override
+    public List<AiProductQuestion> getByParentId(String parentId) {
+        LambdaQueryWrapper<AiProductQuestion> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(AiProductQuestion::getParentId, parentId);
+        queryWrapper.orderByAsc(AiProductQuestion::getCreatedTime);
+        return this.list(queryWrapper);
+    }
+
+    @Override
+    public List<AiProductQuestion> getByDifficulty(Integer difficulty) {
+        LambdaQueryWrapper<AiProductQuestion> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(AiProductQuestion::getDifficulty, difficulty);
+        queryWrapper.orderByDesc(AiProductQuestion::getCreatedTime);
+        return this.list(queryWrapper);
+    }
+
+    @Override
+    public List<AiProductQuestion> getByState(Integer state) {
+        LambdaQueryWrapper<AiProductQuestion> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(AiProductQuestion::getState, state);
+        queryWrapper.orderByDesc(AiProductQuestion::getCreatedTime);
+        return this.list(queryWrapper);
+    }
+
+    @Override
+    public List<AiProductQuestion> getByCorrectAnswer(Integer correctAnswer) {
+        LambdaQueryWrapper<AiProductQuestion> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(AiProductQuestion::getCorrectAnswer, correctAnswer);
+        queryWrapper.orderByDesc(AiProductQuestion::getCreatedTime);
+        return this.list(queryWrapper);
+    }
+
+    @Override
+    public List<AiProductQuestion> getByCompanyIdAndState(String companyId, Integer state) {
+        LambdaQueryWrapper<AiProductQuestion> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(AiProductQuestion::getCompanyId, companyId);
+        queryWrapper.eq(AiProductQuestion::getState, state);
+        queryWrapper.orderByDesc(AiProductQuestion::getCreatedTime);
+        return this.list(queryWrapper);
+    }
+
+    @Override
+    public List<AiProductQuestion> getByParentIdAndState(String parentId, Integer state) {
+        LambdaQueryWrapper<AiProductQuestion> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(AiProductQuestion::getParentId, parentId);
+        queryWrapper.eq(AiProductQuestion::getState, state);
+        queryWrapper.orderByAsc(AiProductQuestion::getCreatedTime);
+        return this.list(queryWrapper);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean saveProductQuestion(AiProductQuestion aiProductQuestion) {
+        try {
+            return this.save(aiProductQuestion);
+        } catch (Exception e) {
+            log.error("保存AI产品题目失败: ", e);
+            return false;
+        }
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean saveBatchProductQuestions(List<AiProductQuestion> productQuestions) {
+        try {
+            return this.saveBatch(productQuestions);
+        } catch (Exception e) {
+            log.error("批量保存AI产品题目失败: ", e);
+            return false;
+        }
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean updateProductQuestion(AiProductQuestion aiProductQuestion) {
+        try {
+            return this.updateById(aiProductQuestion);
+        } catch (Exception e) {
+            log.error("更新AI产品题目失败: ", e);
+            return false;
+        }
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean deleteById(String id) {
+        try {
+            return this.removeById(id);
+        } catch (Exception e) {
+            log.error("删除AI产品题目失败: ", e);
+            return false;
+        }
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean deleteByParentId(String parentId) {
+        try {
+            LambdaQueryWrapper<AiProductQuestion> queryWrapper = new LambdaQueryWrapper<>();
+            queryWrapper.eq(AiProductQuestion::getParentId, parentId);
+            return this.remove(queryWrapper);
+        } catch (Exception e) {
+            log.error("根据父ID删除AI产品题目失败: ", e);
+            return false;
+        }
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean deleteByCompanyId(String companyId) {
+        try {
+            LambdaQueryWrapper<AiProductQuestion> queryWrapper = new LambdaQueryWrapper<>();
+            queryWrapper.eq(AiProductQuestion::getCompanyId, companyId);
+            return this.remove(queryWrapper);
+        } catch (Exception e) {
+            log.error("根据公司ID删除AI产品题目失败: ", e);
+            return false;
+        }
+    }
+}
diff --git a/src/main/java/cc/mrbird/febs/ai/service/impl/AiProductRoleServiceImpl.java b/src/main/java/cc/mrbird/febs/ai/service/impl/AiProductRoleServiceImpl.java
new file mode 100644
index 0000000..8086d0b
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/ai/service/impl/AiProductRoleServiceImpl.java
@@ -0,0 +1,135 @@
+package cc.mrbird.febs.ai.service.impl;
+
+import cc.mrbird.febs.ai.entity.AiProductRole;
+import cc.mrbird.febs.ai.mapper.AiProductRoleMapper;
+import cc.mrbird.febs.ai.service.AiProductRoleService;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+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实现类
+ *
+ * @author yourname
+ * @date 2025-07-29
+ */
+@Slf4j
+@Service
+@RequiredArgsConstructor
+public class AiProductRoleServiceImpl extends ServiceImpl<AiProductRoleMapper, AiProductRole> implements AiProductRoleService {
+
+    private final AiProductRoleMapper aiProductRoleMapper;
+
+    @Override
+    public AiProductRole getById(String id) {
+        return this.getById(id);
+    }
+
+    @Override
+    public List<AiProductRole> getByCompanyId(String companyId) {
+        LambdaQueryWrapper<AiProductRole> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(AiProductRole::getCompanyId, companyId);
+        queryWrapper.orderByDesc(AiProductRole::getCreatedTime);
+        return this.list(queryWrapper);
+    }
+
+    @Override
+    public List<AiProductRole> getByProductId(String productId) {
+        LambdaQueryWrapper<AiProductRole> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(AiProductRole::getProductId, productId);
+        queryWrapper.orderByDesc(AiProductRole::getCreatedTime);
+        return this.list(queryWrapper);
+    }
+
+    @Override
+    public List<AiProductRole> getByName(String name) {
+        LambdaQueryWrapper<AiProductRole> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.like(AiProductRole::getName, name);
+        queryWrapper.orderByDesc(AiProductRole::getCreatedTime);
+        return this.list(queryWrapper);
+    }
+
+    @Override
+    public List<AiProductRole> getByCompanyIdAndProductId(String companyId, String productId) {
+        LambdaQueryWrapper<AiProductRole> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(AiProductRole::getCompanyId, companyId);
+        queryWrapper.eq(AiProductRole::getProductId, productId);
+        queryWrapper.orderByDesc(AiProductRole::getCreatedTime);
+        return this.list(queryWrapper);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean saveProductRole(AiProductRole aiProductRole) {
+        try {
+            return this.save(aiProductRole);
+        } catch (Exception e) {
+            log.error("保存AI产品角色失败: ", e);
+            return false;
+        }
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean saveBatchProductRoles(List<AiProductRole> productRoles) {
+        try {
+            return this.saveBatch(productRoles);
+        } catch (Exception e) {
+            log.error("批量保存AI产品角色失败: ", e);
+            return false;
+        }
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean updateProductRole(AiProductRole aiProductRole) {
+        try {
+            return this.updateById(aiProductRole);
+        } catch (Exception e) {
+            log.error("更新AI产品角色失败: ", e);
+            return false;
+        }
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean deleteById(String id) {
+        try {
+            return this.removeById(id);
+        } catch (Exception e) {
+            log.error("删除AI产品角色失败: ", e);
+            return false;
+        }
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean deleteByProductId(String productId) {
+        try {
+            LambdaQueryWrapper<AiProductRole> queryWrapper = new LambdaQueryWrapper<>();
+            queryWrapper.eq(AiProductRole::getProductId, productId);
+            return this.remove(queryWrapper);
+        } catch (Exception e) {
+            log.error("根据AI产品ID删除AI产品角色失败: ", e);
+            return false;
+        }
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean deleteByCompanyId(String companyId) {
+        try {
+            LambdaQueryWrapper<AiProductRole> queryWrapper = new LambdaQueryWrapper<>();
+            queryWrapper.eq(AiProductRole::getCompanyId, companyId);
+            return this.remove(queryWrapper);
+        } catch (Exception e) {
+            log.error("根据公司ID删除AI产品角色失败: ", e);
+            return false;
+        }
+    }
+}
diff --git a/src/main/java/cc/mrbird/febs/ai/service/impl/AiProductServiceImpl.java b/src/main/java/cc/mrbird/febs/ai/service/impl/AiProductServiceImpl.java
new file mode 100644
index 0000000..17566dc
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/ai/service/impl/AiProductServiceImpl.java
@@ -0,0 +1,161 @@
+package cc.mrbird.febs.ai.service.impl;
+
+import cc.mrbird.febs.ai.entity.AiProduct;
+import cc.mrbird.febs.ai.mapper.AiProductMapper;
+import cc.mrbird.febs.ai.service.AiProductService;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+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实现类
+ *
+ * @author yourname
+ * @date 2025-07-29
+ */
+@Slf4j
+@Service
+@RequiredArgsConstructor
+public class AiProductServiceImpl extends ServiceImpl<AiProductMapper, AiProduct> implements AiProductService {
+
+    private final AiProductMapper aiProductMapper;
+
+    @Override
+    public AiProduct getById(String id) {
+        return this.getById(id);
+    }
+
+    @Override
+    public List<AiProduct> getByCompanyId(String companyId) {
+        LambdaQueryWrapper<AiProduct> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(AiProduct::getCompanyId, companyId);
+        queryWrapper.orderByDesc(AiProduct::getSort);
+        queryWrapper.orderByDesc(AiProduct::getCreatedTime);
+        return this.list(queryWrapper);
+    }
+
+    @Override
+    public AiProduct getByCode(String code) {
+        LambdaQueryWrapper<AiProduct> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(AiProduct::getCode, code);
+        return this.getOne(queryWrapper);
+    }
+
+    @Override
+    public List<AiProduct> getByName(String name) {
+        LambdaQueryWrapper<AiProduct> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.like(AiProduct::getName, name);
+        queryWrapper.orderByDesc(AiProduct::getSort);
+        queryWrapper.orderByDesc(AiProduct::getCreatedTime);
+        return this.list(queryWrapper);
+    }
+
+    @Override
+    public List<AiProduct> getByProductCategoryId(String productCategoryId) {
+        LambdaQueryWrapper<AiProduct> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(AiProduct::getProductCategoryId, productCategoryId);
+        queryWrapper.orderByDesc(AiProduct::getSort);
+        queryWrapper.orderByDesc(AiProduct::getCreatedTime);
+        return this.list(queryWrapper);
+    }
+
+    @Override
+    public List<AiProduct> getByState(Integer state) {
+        LambdaQueryWrapper<AiProduct> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(AiProduct::getState, state);
+        queryWrapper.orderByDesc(AiProduct::getSort);
+        queryWrapper.orderByDesc(AiProduct::getCreatedTime);
+        return this.list(queryWrapper);
+    }
+
+    @Override
+    public List<AiProduct> getByHotState(Integer hotState) {
+        LambdaQueryWrapper<AiProduct> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(AiProduct::getHotState, hotState);
+        queryWrapper.orderByDesc(AiProduct::getSort);
+        queryWrapper.orderByDesc(AiProduct::getCreatedTime);
+        return this.list(queryWrapper);
+    }
+
+    @Override
+    public List<AiProduct> getByCompanyIdAndState(String companyId, Integer state) {
+        LambdaQueryWrapper<AiProduct> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(AiProduct::getCompanyId, companyId);
+        queryWrapper.eq(AiProduct::getState, state);
+        queryWrapper.orderByDesc(AiProduct::getSort);
+        queryWrapper.orderByDesc(AiProduct::getCreatedTime);
+        return this.list(queryWrapper);
+    }
+
+    @Override
+    public List<AiProduct> getByCompanyIdAndHotState(String companyId, Integer hotState) {
+        LambdaQueryWrapper<AiProduct> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(AiProduct::getCompanyId, companyId);
+        queryWrapper.eq(AiProduct::getHotState, hotState);
+        queryWrapper.orderByDesc(AiProduct::getSort);
+        queryWrapper.orderByDesc(AiProduct::getCreatedTime);
+        return this.list(queryWrapper);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean saveProduct(AiProduct aiProduct) {
+        try {
+            return this.save(aiProduct);
+        } catch (Exception e) {
+            log.error("保存AI产品失败: ", e);
+            return false;
+        }
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean saveBatchProducts(List<AiProduct> products) {
+        try {
+            return this.saveBatch(products);
+        } catch (Exception e) {
+            log.error("批量保存AI产品失败: ", e);
+            return false;
+        }
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean updateProduct(AiProduct aiProduct) {
+        try {
+            return this.updateById(aiProduct);
+        } catch (Exception e) {
+            log.error("更新AI产品失败: ", e);
+            return false;
+        }
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean deleteById(String id) {
+        try {
+            return this.removeById(id);
+        } catch (Exception e) {
+            log.error("删除AI产品失败: ", e);
+            return false;
+        }
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean deleteByCompanyId(String companyId) {
+        try {
+            LambdaQueryWrapper<AiProduct> queryWrapper = new LambdaQueryWrapper<>();
+            queryWrapper.eq(AiProduct::getCompanyId, companyId);
+            return this.remove(queryWrapper);
+        } catch (Exception e) {
+            log.error("根据公司ID删除AI产品失败: ", e);
+            return false;
+        }
+    }
+}
diff --git a/src/main/java/cc/mrbird/febs/common/entity/AiBaseEntity.java b/src/main/java/cc/mrbird/febs/common/entity/AiBaseEntity.java
new file mode 100644
index 0000000..bb438ba
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/common/entity/AiBaseEntity.java
@@ -0,0 +1,35 @@
+package cc.mrbird.febs.common.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * @author Administrator
+ */
+@Data
+public class AiBaseEntity implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    private Integer revision = 1;
+
+    private String createdBy;
+
+    private String updatedBy;
+
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date createdTime;
+
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date updatedTime;
+
+    /**
+     * 主键 (UUID)
+     */
+    @TableId(value = "id",type = IdType.ASSIGN_UUID)
+    private Long id;
+}
diff --git a/src/main/resources/mapper/modules/AiMemberAnswerItemMapper.xml b/src/main/resources/mapper/modules/AiMemberAnswerItemMapper.xml
new file mode 100644
index 0000000..3ba612b
--- /dev/null
+++ b/src/main/resources/mapper/modules/AiMemberAnswerItemMapper.xml
@@ -0,0 +1,4 @@
+<?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.AiMemberAnswerItemMapper">
+</mapper>
\ No newline at end of file
diff --git a/src/main/resources/mapper/modules/AiMemberAnswerMapper.xml b/src/main/resources/mapper/modules/AiMemberAnswerMapper.xml
new file mode 100644
index 0000000..be1b5f2
--- /dev/null
+++ b/src/main/resources/mapper/modules/AiMemberAnswerMapper.xml
@@ -0,0 +1,4 @@
+<?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.AiMemberAnswerMapper">
+</mapper>
\ No newline at end of file
diff --git a/src/main/resources/mapper/modules/AiMemberRoleCategoryMapper.xml b/src/main/resources/mapper/modules/AiMemberRoleCategoryMapper.xml
new file mode 100644
index 0000000..be11837
--- /dev/null
+++ b/src/main/resources/mapper/modules/AiMemberRoleCategoryMapper.xml
@@ -0,0 +1,4 @@
+<?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.AiMemberRoleCategoryMapper">
+</mapper>
\ No newline at end of file
diff --git a/src/main/resources/mapper/modules/AiMemberRoleProductMapper.xml b/src/main/resources/mapper/modules/AiMemberRoleProductMapper.xml
new file mode 100644
index 0000000..e2e975b
--- /dev/null
+++ b/src/main/resources/mapper/modules/AiMemberRoleProductMapper.xml
@@ -0,0 +1,4 @@
+<?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.AiMemberRoleProductMapper">
+</mapper>
\ No newline at end of file
diff --git a/src/main/resources/mapper/modules/AiMemberTalkItemMapper.xml b/src/main/resources/mapper/modules/AiMemberTalkItemMapper.xml
new file mode 100644
index 0000000..d171a0d
--- /dev/null
+++ b/src/main/resources/mapper/modules/AiMemberTalkItemMapper.xml
@@ -0,0 +1,4 @@
+<?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.AiMemberTalkItemMapper">
+</mapper>
\ No newline at end of file
diff --git a/src/main/resources/mapper/modules/AiMemberTalkMapper.xml b/src/main/resources/mapper/modules/AiMemberTalkMapper.xml
new file mode 100644
index 0000000..9017110
--- /dev/null
+++ b/src/main/resources/mapper/modules/AiMemberTalkMapper.xml
@@ -0,0 +1,4 @@
+<?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.AiMemberTalkMapper">
+</mapper>
\ No newline at end of file
diff --git a/src/main/resources/mapper/modules/AiProductCategoryMapper.xml b/src/main/resources/mapper/modules/AiProductCategoryMapper.xml
new file mode 100644
index 0000000..cb5c925
--- /dev/null
+++ b/src/main/resources/mapper/modules/AiProductCategoryMapper.xml
@@ -0,0 +1,4 @@
+<?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">
+</mapper>
\ No newline at end of file
diff --git a/src/main/resources/mapper/modules/AiProductMapper.xml b/src/main/resources/mapper/modules/AiProductMapper.xml
new file mode 100644
index 0000000..a4c1c21
--- /dev/null
+++ b/src/main/resources/mapper/modules/AiProductMapper.xml
@@ -0,0 +1,4 @@
+<?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">
+</mapper>
\ No newline at end of file
diff --git a/src/main/resources/mapper/modules/AiProductPointMapper.xml b/src/main/resources/mapper/modules/AiProductPointMapper.xml
new file mode 100644
index 0000000..6537d9a
--- /dev/null
+++ b/src/main/resources/mapper/modules/AiProductPointMapper.xml
@@ -0,0 +1,4 @@
+<?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.AiProductPointMapper">
+</mapper>
\ No newline at end of file
diff --git a/src/main/resources/mapper/modules/AiProductQuestionLinkMapper.xml b/src/main/resources/mapper/modules/AiProductQuestionLinkMapper.xml
new file mode 100644
index 0000000..fb3c595
--- /dev/null
+++ b/src/main/resources/mapper/modules/AiProductQuestionLinkMapper.xml
@@ -0,0 +1,4 @@
+<?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.AiProductQuestionLinkMapper">
+</mapper>
\ No newline at end of file
diff --git a/src/main/resources/mapper/modules/AiProductQuestionMapper.xml b/src/main/resources/mapper/modules/AiProductQuestionMapper.xml
new file mode 100644
index 0000000..a00a1a1
--- /dev/null
+++ b/src/main/resources/mapper/modules/AiProductQuestionMapper.xml
@@ -0,0 +1,4 @@
+<?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.AiProductQuestionMapper">
+</mapper>
\ No newline at end of file
diff --git a/src/main/resources/mapper/modules/AiProductRoleMapper.xml b/src/main/resources/mapper/modules/AiProductRoleMapper.xml
new file mode 100644
index 0000000..5997d0e
--- /dev/null
+++ b/src/main/resources/mapper/modules/AiProductRoleMapper.xml
@@ -0,0 +1,4 @@
+<?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.AiProductRoleMapper">
+</mapper>
\ No newline at end of file

--
Gitblit v1.9.1