diff --git a/ccic-entity/src/main/java/com/ccic/safeliab/entity/ExamPapers.java b/ccic-entity/src/main/java/com/ccic/safeliab/entity/ExamPapers.java
new file mode 100644
index 0000000..508bdc6
--- /dev/null
+++ b/ccic-entity/src/main/java/com/ccic/safeliab/entity/ExamPapers.java
@@ -0,0 +1,73 @@
+package com.ccic.safeliab.entity;
+
+import com.baomidou.mybatisplus.annotation.*;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+
+/**
+ *
+ * 试卷管理表
+ *
+ *
+ * @author testjava
+ * @since 2025-02-26
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@TableName("ex_exam_papers")
+public class ExamPapers extends BaseEntity implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * ID
+ */
+ @TableId(value = "id", type = IdType.ID_WORKER)
+ @JsonFormat(shape = JsonFormat.Shape.STRING)
+ private Long id;
+
+ /**
+ * 试卷名称
+ */
+ private String paperName;
+
+ /**
+ * 监管行业 ID
+ */
+ private Long industryId;
+
+ /**
+ * 题目数量
+ */
+ private Integer questionCount;
+
+ /**
+ * 总分值
+ */
+ private Integer totalScore;
+
+ /**
+ * 考试时长
+ */
+ private Long examDuration;
+
+ /**
+ * 时长类型
+ */
+ private Integer durationType;
+
+ /**
+ * 试卷内容
+ */
+ private String paperContent;
+
+ /**
+ * 试卷状态
+ */
+ private Integer paperStatus;
+}
\ No newline at end of file
diff --git a/ccic-entity/src/main/java/com/ccic/safeliab/entity/PaperQuestion.java b/ccic-entity/src/main/java/com/ccic/safeliab/entity/PaperQuestion.java
new file mode 100644
index 0000000..7de3670
--- /dev/null
+++ b/ccic-entity/src/main/java/com/ccic/safeliab/entity/PaperQuestion.java
@@ -0,0 +1,43 @@
+package com.ccic.safeliab.entity;
+
+import com.baomidou.mybatisplus.annotation.*;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+
+/**
+ *
+ * 试卷题目关联表
+ *
+ *
+ * @author testjava
+ * @since 2025-02-21
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@TableName("ex_paper_questions")
+public class PaperQuestion extends BaseEntity implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * ID
+ */
+ @TableId(value = "id", type = IdType.ID_WORKER)
+ @JsonFormat(shape = JsonFormat.Shape.STRING)
+ private Long id;
+
+ /**
+ * 试卷 ID,外键关联试卷管理表(ex_exam_papers.id)
+ */
+ private Long paperId;
+
+ /**
+ * 题目 ID,外键关联题库管理表(ex_question_categories.id)
+ */
+ private Long questionId;
+}
\ No newline at end of file
diff --git a/ccic-entity/src/main/java/com/ccic/safeliab/entity/QuestionCategories.java b/ccic-entity/src/main/java/com/ccic/safeliab/entity/QuestionCategories.java
new file mode 100644
index 0000000..02df016
--- /dev/null
+++ b/ccic-entity/src/main/java/com/ccic/safeliab/entity/QuestionCategories.java
@@ -0,0 +1,63 @@
+package com.ccic.safeliab.entity;
+
+import com.baomidou.mybatisplus.annotation.*;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+
+/**
+ *
+ * 题库管理表
+ *
+ *
+ * @author java
+ * @since 2025-02-26
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@TableName("ex_question_categories")
+public class QuestionCategories extends BaseEntity implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * ID
+ */
+ @TableId(value = "id", type = IdType.ID_WORKER)
+ @JsonFormat(shape = JsonFormat.Shape.STRING)
+ private Long id;
+
+ /**
+ * 题目类型(单选、多选)
+ */
+ private Integer questionTypes;
+
+ /**
+ * 监管行业ID
+ */
+ private Long industryId;
+
+ /**
+ * 服务类型ID
+ */
+ private Long serviceTypeId;
+
+ /**
+ * 题干
+ */
+ private String questionContent;
+
+ /**
+ * 答案
+ */
+ private String answer;
+
+ /**
+ * 答题选项
+ */
+ private String options;
+}
\ No newline at end of file
diff --git a/ccic-exam/src/main/java/com/ccic/safeliab/dao/QuestionMapper.java b/ccic-exam/src/main/java/com/ccic/safeliab/dao/QuestionMapper.java
new file mode 100644
index 0000000..d853c09
--- /dev/null
+++ b/ccic-exam/src/main/java/com/ccic/safeliab/dao/QuestionMapper.java
@@ -0,0 +1,69 @@
+package com.ccic.safeliab.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.ccic.safeliab.entity.ExDict;
+import com.ccic.safeliab.entity.Industry;
+import com.ccic.safeliab.entity.QuestionCategories;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * Mapper 接口
+ *
+ * @author Chill
+ */
+@Mapper
+public interface QuestionMapper extends BaseMapper {
+
+ /**
+ * 主键查询
+ */
+ QuestionCategories selectQuestionById(Integer questionId);
+
+ /**
+ * 查询当前页数据
+ *
+ * @param industryId 监管行业
+ * @param serviceTypeId 服务类型
+ * @param questionContent 题干条件
+ * @param offset 偏移量
+ * @param num 每页显示的记录数
+ * @return 当前页数据
+ */
+ List getList(
+ @Param("industryId") Long industryId,
+ @Param("serviceTypeId") Long serviceTypeId,
+ @Param("questionContent") String questionContent,
+ @Param("offset") int offset,
+ @Param("num") int num);
+
+ /**
+ * 查询总数量
+ *
+ * @param industryId 监管行业
+ * @param serviceTypeId 服务类型
+ * @param questionContent 题干条件
+ * @return 总数量
+ */
+ int getListSize(
+ @Param("industryId") Long industryId,
+ @Param("serviceTypeId") Long serviceTypeId,
+ @Param("questionContent") String questionContent);
+
+ /**
+ * 获取行业
+ *
+ * @return 行业
+ */
+ List getIndustry();
+
+ /**
+ * 查询当题目详情
+ *
+ * @param id 监管行业
+ * @return 题目详情
+ */
+ QuestionCategories getDetail(@Param("id") Long id);
+}
diff --git a/ccic-exam/src/main/java/com/ccic/safeliab/service/QuestionService.java b/ccic-exam/src/main/java/com/ccic/safeliab/service/QuestionService.java
new file mode 100644
index 0000000..fcf89ff
--- /dev/null
+++ b/ccic-exam/src/main/java/com/ccic/safeliab/service/QuestionService.java
@@ -0,0 +1,64 @@
+package com.ccic.safeliab.service;
+
+import com.ccic.safeliab.entity.Industry;
+import com.ccic.safeliab.entity.QuestionCategories;
+import com.ccic.safeliab.support.BaseService;
+import com.ccic.safeliab.vo.InsQuestionVO;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+import java.util.Map;
+
+@Service
+public interface QuestionService extends BaseService {
+ /**
+ * 获取题库列表
+ * @param page 页码
+ * @param num 每页数量
+ * @param entity 题库表
+ * @return 题库列表
+ */
+ Map getList(int page, int num, QuestionCategories entity);
+
+
+ /**
+ * 根据主键删除题库记录
+ * @param id 题库记录的主键
+ * @return 删除操作是否成功
+ */
+ boolean deleteQuestionById(Long id);
+
+ /**
+ * 根据主键批量删除题库记录
+ * @param ids 题库记录的主键列表
+ * @return 删除操作是否成功
+ */
+ boolean deleteQuestionListByIds(List ids);
+
+ /**
+ * 添加试题
+ * @param vo 试题 VO 列表
+ * @return 添加是否成功
+ */
+ int add(List vo);
+
+ /**
+ * 修改试题
+ * @param vo 试题 VO 列表
+ * @return 添加是否成功
+ */
+ boolean update(InsQuestionVO vo);
+
+ /**
+ * 获取行业
+ * @return 行业
+ */
+ List getDictionary();
+
+ /**
+ * 获取题库列表
+ * @param id 题目ID
+ * @return 题目详情
+ */
+ QuestionCategories getDetail(String id);
+}
diff --git a/ccic-exam/src/main/java/com/ccic/safeliab/service/QuestionServiceImpl.java b/ccic-exam/src/main/java/com/ccic/safeliab/service/QuestionServiceImpl.java
new file mode 100644
index 0000000..d1d6e2c
--- /dev/null
+++ b/ccic-exam/src/main/java/com/ccic/safeliab/service/QuestionServiceImpl.java
@@ -0,0 +1,111 @@
+package com.ccic.safeliab.service;
+
+import com.ccic.safeliab.dao.QuestionMapper;
+import com.ccic.safeliab.entity.*;
+import com.ccic.safeliab.support.BaseServiceImpl;
+import com.ccic.safeliab.vo.InsQuestionVO;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@Service
+public class QuestionServiceImpl extends BaseServiceImpl implements QuestionService {
+
+ @Override
+ public Map getList(int page,int num, QuestionCategories entity) {
+ int offset = (page - 1) * num;
+ Map map = new HashMap<>();
+ List data = baseMapper.getList(
+ entity.getIndustryId(),
+ entity.getServiceTypeId(),
+ entity.getQuestionContent(),
+ offset,
+ num);
+
+ int total = baseMapper.getListSize(
+ entity.getIndustryId(),
+ entity.getServiceTypeId(),
+ entity.getQuestionContent());
+ map.put("data", data);
+ map.put("total", total);
+ return map;
+ }
+
+ @Override
+ public boolean deleteQuestionById(Long id) {
+ List ids = new ArrayList<>();
+ ids.add(id);
+ return deleteLogic(ids);
+ }
+
+ @Override
+ public boolean deleteQuestionListByIds(List ids) {
+ return deleteLogic(ids);
+ }
+
+ @Override
+ public int add(List vo) {
+ int count =0;
+ for(InsQuestionVO item :vo){
+ save(convertToEntity(item));
+ count ++;
+ }
+ return count;
+ }
+
+ @Override
+ public boolean update(InsQuestionVO vo) {
+ return updateById(convertToEntity(vo));
+ }
+
+ @Override
+ public List getDictionary() {
+ return baseMapper.getIndustry();
+ }
+
+ @Override
+ public QuestionCategories getDetail(String id){
+ return baseMapper.getDetail(Long.valueOf(id));
+ }
+
+ /**
+ * 将 VO 转换为实体类
+ * @param vo 试题 VO
+ * @return 试题实体类
+ */
+ private QuestionCategories convertToEntity(InsQuestionVO vo) {
+ QuestionCategories entity = new QuestionCategories();
+
+ // 赋值从父类继承的属性
+ entity.setId(vo.getId());
+ entity.setQuestionTypes(vo.getQuestionTypes());
+ entity.setIndustryId(vo.getIndustryId());
+ entity.setServiceTypeId(vo.getServiceTypeId());
+ entity.setQuestionContent(vo.getQuestionContent());
+ entity.setAnswer(vo.getAnswer());
+
+ // 处理答题选项,拼接成字符串
+ InsQuestionVO.AnswerOptions answerOptions = vo.getAnswerOptions();
+ if (answerOptions != null) {
+ StringBuilder optionsBuilder = new StringBuilder();
+ if (answerOptions.A != null) {
+ optionsBuilder.append("A:").append(answerOptions.A).append(";");
+ }
+ if (answerOptions.B != null) {
+ optionsBuilder.append("B:").append(answerOptions.B).append(";");
+ }
+ if (answerOptions.C != null) {
+ optionsBuilder.append("C:").append(answerOptions.C).append(";");
+ }
+ if (answerOptions.D != null) {
+ optionsBuilder.append("D:").append(answerOptions.D).append(";");
+ }
+ String options = optionsBuilder.toString();
+ entity.setOptions(options);
+ }
+ return entity;
+ }
+}
diff --git a/ccic-exam/src/main/java/com/ccic/safeliab/vo/InsQuestionVO.java b/ccic-exam/src/main/java/com/ccic/safeliab/vo/InsQuestionVO.java
new file mode 100644
index 0000000..b4c0aaf
--- /dev/null
+++ b/ccic-exam/src/main/java/com/ccic/safeliab/vo/InsQuestionVO.java
@@ -0,0 +1,29 @@
+package com.ccic.safeliab.vo;
+
+import com.ccic.safeliab.entity.QuestionCategories;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * 值对象(VO),用于在不同层之间传递题目相关数据。
+ * 该类的属性与数据库中题目表的字段相对应,以满足数据传输需求。
+ */
+@Getter
+@Setter
+public class InsQuestionVO extends QuestionCategories {
+ // 每页数量
+ private int num;
+ // 页码
+ private int page;
+ // 答案
+ AnswerOptions answerOptions;
+
+ public static class AnswerOptions {
+ public String A;
+ public String B;
+ public String C;
+ public String D;
+ }
+}
+
+
diff --git a/ccic-exam/src/main/java/com/ccic/safeliab/web/QuestionController.java b/ccic-exam/src/main/java/com/ccic/safeliab/web/QuestionController.java
new file mode 100644
index 0000000..0a4aaee
--- /dev/null
+++ b/ccic-exam/src/main/java/com/ccic/safeliab/web/QuestionController.java
@@ -0,0 +1,97 @@
+package com.ccic.safeliab.web;
+
+import com.ccic.safeliab.entity.Industry;
+import com.ccic.safeliab.entity.QuestionCategories;
+import com.ccic.safeliab.service.QuestionService;
+import com.ccic.safeliab.util.R;
+import com.ccic.safeliab.vo.InsQuestionVO;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+import java.util.Map;
+
+@RestController
+@RequestMapping("/ex/question")
+public class QuestionController {
+
+ @Autowired
+ private QuestionService questionService;
+
+ /**
+ * 获取题库
+ * @param vo 题库对象(VO)
+ * @return 查询结果
+ */
+ @PostMapping("/list")
+ public R list(@RequestBody InsQuestionVO vo) {
+ QuestionCategories entity = new QuestionCategories();
+ entity.setIndustryId(vo.getIndustryId());
+ entity.setServiceTypeId(vo.getServiceTypeId());
+ entity.setQuestionContent(vo.getQuestionContent());
+ Map map = questionService.getList(vo.getPage(), vo.getNum(), entity);
+ return R.ok().data(map);
+ }
+
+ /**
+ * 删除单个试题
+ */
+ @GetMapping("/delete")
+ public R delete(String id) {
+ boolean resultFlg = questionService.deleteQuestionById(Long.valueOf((id)));
+ return R.ok().data(resultFlg);
+ }
+
+ /**
+ * 删除多个试题
+ */
+ @PostMapping("/deleteList")
+ public R deleteList(@RequestBody List ids) {
+ boolean resultFlg = questionService.deleteQuestionListByIds(ids);
+ return R.ok().data(resultFlg);
+ }
+
+ /**
+ * 添加试题
+ */
+ @PostMapping("/add")
+ public R add(@RequestBody List vo) {
+ return R.ok().data(questionService.add(vo));
+ }
+
+ /**
+ * 修改试题
+ */
+ @PostMapping("/update")
+ public R add(@RequestBody InsQuestionVO vo) {
+ return R.ok().data(questionService.update(vo));
+ }
+
+ /**
+ * 更新试题
+ */
+ @GetMapping("/update")
+ public boolean update(@RequestParam InsQuestionVO vo) {
+// return questionService.updateQuestion(add);
+ return true;
+ }
+
+ /**
+ * 行业查询
+ * @return 行业
+ */
+ @GetMapping("/findIndustry")
+ public R findIndustry() {
+ List tree = questionService.getDictionary();
+ return R.ok().data(tree);
+ }
+
+ /**
+ * 题目详情
+ */
+ @GetMapping("/getDetail")
+ public R getDetail(String id) {
+ QuestionCategories data = questionService.getDetail(id);
+ return R.ok().data(data);
+ }
+}
diff --git a/ccic-exam/src/main/resources/mappers/QuestionMapper.xml b/ccic-exam/src/main/resources/mappers/QuestionMapper.xml
new file mode 100644
index 0000000..7c64868
--- /dev/null
+++ b/ccic-exam/src/main/resources/mappers/QuestionMapper.xml
@@ -0,0 +1,90 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+