From 20e778a1a7cc4f90912a24c8c6383935670c976b Mon Sep 17 00:00:00 2001 From: lcj <2331845269@qq.com> Date: Tue, 15 Apr 2025 21:40:37 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E5=AE=89=E5=85=A8=E6=95=99?= =?UTF-8?q?=E8=82=B2=E5=9F=B9=E8=AE=AD=E9=A2=98=E5=BA=93=E5=88=97=E8=A1=A8?= =?UTF-8?q?=E7=9B=B8=E5=85=B3=E6=8E=A5=E5=8F=A3=EF=BC=8C=E6=89=B9=E9=87=8F?= =?UTF-8?q?=E4=B8=8A=E4=BC=A0=E3=80=81=E4=B8=8B=E8=BD=BD=E7=BA=BF=E4=B8=8B?= =?UTF-8?q?=E8=80=83=E8=AF=95=E6=96=87=E4=BB=B6=E6=8E=A5=E5=8F=A3=EF=BC=9B?= =?UTF-8?q?=E4=BC=98=E5=8C=96=EF=BC=8C=E4=BF=AE=E6=94=B9HSE=E7=AE=A1?= =?UTF-8?q?=E7=90=86=E7=9B=B8=E5=85=B3=E4=BB=A3=E7=A0=81=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../BusConstructionUserFileController.java | 3 + .../IBusConstructionUserFileService.java | 4 +- .../impl/BusAttendanceServiceImpl.java | 4 +- .../DocumentSafetyMeetingConstant.java | 9 + .../BusQuestionUserAnswerController.java | 26 ++ .../BusQuestionsCategoryController.java | 108 ++++++ .../safety/domain/BusQuestionBank.java | 4 +- .../safety/domain/BusQuestionUserAnswer.java | 12 + .../safety/domain/BusQuestionsCategory.java | 50 +++ .../domain/enums/SafetyExamTypeEnum.java | 24 ++ .../questionbank/QuestionBankCreateReq.java | 2 +- .../questionbank/QuestionBankQueryReq.java | 2 +- .../questionbank/QuestionBankUpdateReq.java | 2 +- .../QuestionsCategoryCreateReq.java | 28 ++ .../QuestionsCategoryQueryReq.java | 28 ++ .../QuestionsCategoryUpdateReq.java | 33 ++ ...uestionUserAnswerBatchDownloadFileReq.java | 24 ++ .../QuestionUserAnswerQueryReq.java | 33 +- .../QuestionUserAnswerUploadTemp.java | 47 +++ .../safety/domain/vo/BusQuestionBankVo.java | 17 +- .../domain/vo/BusQuestionUserAnswerVo.java | 35 +- .../domain/vo/BusQuestionsCategoryVo.java | 39 ++ .../domain/vo/BusSafetyInspectionVo.java | 6 +- .../mapper/BusQuestionsCategoryMapper.java | 15 + .../IBusQuestionUserAnswerService.java | 21 + .../service/IBusQuestionsCategoryService.java | 99 +++++ .../impl/BusQuestionBankServiceImpl.java | 45 ++- .../BusQuestionUserAnswerServiceImpl.java | 362 ++++++++++++++++-- .../impl/BusQuestionsCategoryServiceImpl.java | 225 +++++++++++ .../safety/BusQuestionsCategoryMapper.xml | 7 + RuoYi-Vue-Plus/script/sql/xinnengyuan.sql | 12 + 31 files changed, 1247 insertions(+), 79 deletions(-) create mode 100644 RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/controller/BusQuestionsCategoryController.java create mode 100644 RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/BusQuestionsCategory.java create mode 100644 RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/enums/SafetyExamTypeEnum.java create mode 100644 RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/req/questionscategory/QuestionsCategoryCreateReq.java create mode 100644 RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/req/questionscategory/QuestionsCategoryQueryReq.java create mode 100644 RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/req/questionscategory/QuestionsCategoryUpdateReq.java create mode 100644 RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/req/questionuseranswer/QuestionUserAnswerBatchDownloadFileReq.java create mode 100644 RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/req/questionuseranswer/QuestionUserAnswerUploadTemp.java create mode 100644 RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/vo/BusQuestionsCategoryVo.java create mode 100644 RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/mapper/BusQuestionsCategoryMapper.java create mode 100644 RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/service/IBusQuestionsCategoryService.java create mode 100644 RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/service/impl/BusQuestionsCategoryServiceImpl.java create mode 100644 RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/resources/mapper/safety/BusQuestionsCategoryMapper.xml diff --git a/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/controller/BusConstructionUserFileController.java b/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/controller/BusConstructionUserFileController.java index 8ad209eb..1c424a53 100644 --- a/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/controller/BusConstructionUserFileController.java +++ b/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/controller/BusConstructionUserFileController.java @@ -6,6 +6,7 @@ import jakarta.validation.constraints.NotNull; import lombok.RequiredArgsConstructor; import org.dromara.common.core.domain.R; import org.dromara.common.excel.utils.ExcelUtil; +import org.dromara.common.idempotent.annotation.RepeatSubmit; import org.dromara.common.log.annotation.Log; import org.dromara.common.log.enums.BusinessType; import org.dromara.common.web.core.BaseController; @@ -59,6 +60,7 @@ public class BusConstructionUserFileController extends BaseController { */ @SaCheckPermission("project:constructionUserFile:export") @Log(title = "施工人员文件存储", businessType = BusinessType.EXPORT) + @RepeatSubmit() @PostMapping("/exportFileTemplate") public void exportFileTemplate(ConstructionUserFileTemplateReq req, HttpServletResponse response) { busConstructionUserFileService.downloadFileTemplate(req, response); @@ -69,6 +71,7 @@ public class BusConstructionUserFileController extends BaseController { */ @SaCheckPermission("project:constructionUserFile:edit") @Log(title = "施工人员文件存储", businessType = BusinessType.INSERT) + @RepeatSubmit() @PostMapping("/upload/zip") public R uploadFileZip(@RequestParam("file") MultipartFile file) { Boolean result = busConstructionUserFileService.batchUploadFileByZip(file); diff --git a/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/service/IBusConstructionUserFileService.java b/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/service/IBusConstructionUserFileService.java index 5434def4..2273aa6c 100644 --- a/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/service/IBusConstructionUserFileService.java +++ b/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/service/IBusConstructionUserFileService.java @@ -48,10 +48,10 @@ public interface IBusConstructionUserFileService extends IService blackList = constructionBlacklistService.queryIdListByProjectId(projectId); // 构建查询用户相关信息查询条件 List userIdList = constructionUserService.lambdaQuery() .eq(BusConstructionUser::getProjectId, projectId) .eq(req.getTeamId() != null, BusConstructionUser::getTeamId, req.getTeamId()) .eq(req.getTypeOfWork() != null, BusConstructionUser::getTypeOfWork, req.getTypeOfWork()) - .notIn(BusConstructionUser::getId, constructionBlacklistService.queryIdListByProjectId(projectId)) + .notIn(CollUtil.isNotEmpty(blackList), BusConstructionUser::getId, blackList) .list().stream().map(BusConstructionUser::getId).toList(); lqw.in(CollUtil.isNotEmpty(userIdList), BusAttendance::getUserId, userIdList); Map> dateListMap = this.list(lqw) diff --git a/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/constant/DocumentSafetyMeetingConstant.java b/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/constant/DocumentSafetyMeetingConstant.java index 0bdab13f..1734f80d 100644 --- a/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/constant/DocumentSafetyMeetingConstant.java +++ b/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/constant/DocumentSafetyMeetingConstant.java @@ -13,10 +13,19 @@ public interface DocumentSafetyMeetingConstant { */ String TOP_FOLDER_PREFIX = "/doc/safety/meeting/"; + /** + * 获取顶级目录前缀 + * + * @param projectId 项目id + * @return 顶级目录前缀 + */ static String getTopFolderPrefix(Long projectId) { return String.format("%s%s/", TOP_FOLDER_PREFIX, projectId); } + /** + * 图片后缀列表 + */ List PICTURE_SUFFIX_LIST = List.of("jpeg", "jpg", "png", "webp"); } diff --git a/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/controller/BusQuestionUserAnswerController.java b/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/controller/BusQuestionUserAnswerController.java index 073ef67f..ae7ef921 100644 --- a/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/controller/BusQuestionUserAnswerController.java +++ b/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/controller/BusQuestionUserAnswerController.java @@ -15,6 +15,7 @@ import org.dromara.common.log.enums.BusinessType; import org.dromara.common.mybatis.core.page.PageQuery; import org.dromara.common.mybatis.core.page.TableDataInfo; import org.dromara.common.web.core.BaseController; +import org.dromara.safety.domain.req.questionuseranswer.QuestionUserAnswerBatchDownloadFileReq; import org.dromara.safety.domain.req.questionuseranswer.QuestionUserAnswerCreateReq; import org.dromara.safety.domain.req.questionuseranswer.QuestionUserAnswerQueryReq; import org.dromara.safety.domain.req.questionuseranswer.QuestionUserAnswerUpdateReq; @@ -22,6 +23,7 @@ import org.dromara.safety.domain.vo.BusQuestionUserAnswerVo; import org.dromara.safety.service.IBusQuestionUserAnswerService; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; import java.util.List; @@ -59,6 +61,18 @@ public class BusQuestionUserAnswerController extends BaseController { ExcelUtil.exportExcel(list, "用户试卷存储", BusQuestionUserAnswerVo.class, response); } + /** + * 批量下载用户试卷存储 + */ + @SaCheckPermission("safety:questionUserAnswer:export") + @Log(title = "用户试卷存储", businessType = BusinessType.EXPORT) + @RepeatSubmit() + @PostMapping("/exportFile") + public void exportFile(QuestionUserAnswerBatchDownloadFileReq req, + HttpServletResponse response) { + busQuestionUserAnswerService.batchDownloadFile(req, response); + } + /** * 获取用户试卷存储详细信息 * @@ -82,6 +96,18 @@ public class BusQuestionUserAnswerController extends BaseController { return R.ok(busQuestionUserAnswerService.insertByBo(req)); } + /** + * 上传线下考试试卷存储 + */ + @SaCheckPermission("safety:questionUserAnswer:add") + @Log(title = "用户试卷存储", businessType = BusinessType.INSERT) + @RepeatSubmit() + @PostMapping("/upload/zip") + public R batchUploadFileByZip(@RequestParam("file") MultipartFile multipartFile, + Long projectId) { + return R.ok(busQuestionUserAnswerService.batchUploadFileByZip(multipartFile, projectId)); + } + /** * 修改用户试卷存储 */ diff --git a/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/controller/BusQuestionsCategoryController.java b/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/controller/BusQuestionsCategoryController.java new file mode 100644 index 00000000..d8766558 --- /dev/null +++ b/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/controller/BusQuestionsCategoryController.java @@ -0,0 +1,108 @@ +package org.dromara.safety.controller; + +import cn.dev33.satoken.annotation.SaCheckPermission; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotNull; +import lombok.RequiredArgsConstructor; +import org.dromara.common.core.domain.R; +import org.dromara.common.core.validate.AddGroup; +import org.dromara.common.core.validate.EditGroup; +import org.dromara.common.excel.utils.ExcelUtil; +import org.dromara.common.idempotent.annotation.RepeatSubmit; +import org.dromara.common.log.annotation.Log; +import org.dromara.common.log.enums.BusinessType; +import org.dromara.common.mybatis.core.page.PageQuery; +import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.common.web.core.BaseController; +import org.dromara.safety.domain.req.questionscategory.QuestionsCategoryCreateReq; +import org.dromara.safety.domain.req.questionscategory.QuestionsCategoryQueryReq; +import org.dromara.safety.domain.req.questionscategory.QuestionsCategoryUpdateReq; +import org.dromara.safety.domain.vo.BusQuestionsCategoryVo; +import org.dromara.safety.service.IBusQuestionsCategoryService; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +/** + * 题库类别 + * + * @author lcj + * @date 2025-04-15 + */ +@Validated +@RequiredArgsConstructor +@RestController +@RequestMapping("/safety/questionsCategory") +public class BusQuestionsCategoryController extends BaseController { + + private final IBusQuestionsCategoryService busQuestionsCategoryService; + + /** + * 查询题库类别列表 + */ + @SaCheckPermission("safety:questionsCategory:list") + @GetMapping("/list") + public TableDataInfo list(QuestionsCategoryQueryReq req, PageQuery pageQuery) { + return busQuestionsCategoryService.queryPageList(req, pageQuery); + } + + /** + * 导出题库类别列表 + */ + @SaCheckPermission("safety:questionsCategory:export") + @Log(title = "题库类别", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(QuestionsCategoryQueryReq req, HttpServletResponse response) { + List list = busQuestionsCategoryService.queryList(req); + ExcelUtil.exportExcel(list, "题库类别", BusQuestionsCategoryVo.class, response); + } + + /** + * 获取题库类别详细信息 + * + * @param id 主键 + */ + @SaCheckPermission("safety:questionsCategory:query") + @GetMapping("/{id}") + public R getInfo(@NotNull(message = "主键不能为空") + @PathVariable Long id) { + return R.ok(busQuestionsCategoryService.queryById(id)); + } + + /** + * 新增题库类别 + */ + @SaCheckPermission("safety:questionsCategory:add") + @Log(title = "题库类别", businessType = BusinessType.INSERT) + @RepeatSubmit() + @PostMapping() + public R add(@Validated(AddGroup.class) @RequestBody QuestionsCategoryCreateReq req) { + return R.ok(busQuestionsCategoryService.insertByBo(req)); + } + + /** + * 修改题库类别 + */ + @SaCheckPermission("safety:questionsCategory:edit") + @Log(title = "题库类别", businessType = BusinessType.UPDATE) + @RepeatSubmit() + @PutMapping() + public R edit(@Validated(EditGroup.class) @RequestBody QuestionsCategoryUpdateReq req) { + return toAjax(busQuestionsCategoryService.updateByBo(req)); + } + + /** + * 删除题库类别 + * + * @param ids 主键串 + */ + @SaCheckPermission("safety:questionsCategory:remove") + @Log(title = "题库类别", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public R remove(@NotEmpty(message = "主键不能为空") + @PathVariable Long[] ids) { + return toAjax(busQuestionsCategoryService.deleteWithValidByIds(List.of(ids), true)); + } +} diff --git a/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/BusQuestionBank.java b/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/BusQuestionBank.java index b2d2e2e4..11c9a9a5 100644 --- a/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/BusQuestionBank.java +++ b/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/BusQuestionBank.java @@ -1,6 +1,7 @@ package org.dromara.safety.domain; import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableLogic; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; import lombok.EqualsAndHashCode; @@ -37,7 +38,7 @@ public class BusQuestionBank extends BaseEntity { /** * 题目类别 */ - private String categoryType; + private Long categoryId; /** * 题目类型 @@ -72,6 +73,7 @@ public class BusQuestionBank extends BaseEntity { /** * 是否删除(0正常 1删除) */ + @TableLogic private Long isDelete; diff --git a/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/BusQuestionUserAnswer.java b/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/BusQuestionUserAnswer.java index d830412b..ae73edf9 100644 --- a/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/BusQuestionUserAnswer.java +++ b/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/BusQuestionUserAnswer.java @@ -1,6 +1,7 @@ package org.dromara.safety.domain; import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableLogic; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; import lombok.EqualsAndHashCode; @@ -54,6 +55,11 @@ public class BusQuestionUserAnswer extends BaseEntity { */ private Long score; + /** + * 考试时间(时间戳/秒) + */ + private Long examTime; + /** * 用时时间(时间戳/秒) */ @@ -69,6 +75,11 @@ public class BusQuestionUserAnswer extends BaseEntity { */ private String file; + /** + * 考试类型(1线上考试 2线下考试) + */ + private String examType; + /** * 删除时间 */ @@ -77,6 +88,7 @@ public class BusQuestionUserAnswer extends BaseEntity { /** * 是否删除(0正常 1删除) */ + @TableLogic private Long isDelete; diff --git a/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/BusQuestionsCategory.java b/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/BusQuestionsCategory.java new file mode 100644 index 00000000..7fb8295d --- /dev/null +++ b/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/BusQuestionsCategory.java @@ -0,0 +1,50 @@ +package org.dromara.safety.domain; + +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; +import java.util.Date; + +/** + * 题库类别对象 bus_questions_category + * + * @author lcj + * @date 2025-04-15 + */ +@Data +@TableName("bus_questions_category") +public class BusQuestionsCategory implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 主键id + */ + @TableId(value = "id") + private Long id; + + /** + * 项目id + */ + private Long projectId; + + /** + * 题库类别 + */ + private String categoryName; + + /** + * 创建时间 + */ + private Date createTime; + + /** + * 更新时间 + */ + private Date updateTime; + +} diff --git a/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/enums/SafetyExamTypeEnum.java b/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/enums/SafetyExamTypeEnum.java new file mode 100644 index 00000000..a97ac879 --- /dev/null +++ b/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/enums/SafetyExamTypeEnum.java @@ -0,0 +1,24 @@ +package org.dromara.safety.domain.enums; + +import lombok.Getter; + +/** + * @author lcj + * @date 2025/4/15 14:56 + */ +@Getter +public enum SafetyExamTypeEnum { + + ONLINE("线上考试", "1"), + OFFLINE("线下考试", "2"); + + private final String text; + + private final String value; + + SafetyExamTypeEnum(String text, String value) { + this.text = text; + this.value = value; + } + +} diff --git a/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/req/questionbank/QuestionBankCreateReq.java b/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/req/questionbank/QuestionBankCreateReq.java index 292c6bd6..040ef534 100644 --- a/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/req/questionbank/QuestionBankCreateReq.java +++ b/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/req/questionbank/QuestionBankCreateReq.java @@ -24,7 +24,7 @@ public class QuestionBankCreateReq implements Serializable { /** * 题目类别 */ - private String categoryType; + private Long categoryId; /** * 题目类型 diff --git a/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/req/questionbank/QuestionBankQueryReq.java b/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/req/questionbank/QuestionBankQueryReq.java index 040bd580..33fc8cdb 100644 --- a/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/req/questionbank/QuestionBankQueryReq.java +++ b/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/req/questionbank/QuestionBankQueryReq.java @@ -29,7 +29,7 @@ public class QuestionBankQueryReq implements Serializable { /** * 题目类别 */ - private String categoryType; + private Long categoryId; /** * 题目类型 diff --git a/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/req/questionbank/QuestionBankUpdateReq.java b/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/req/questionbank/QuestionBankUpdateReq.java index 9724e42b..dd87a5e7 100644 --- a/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/req/questionbank/QuestionBankUpdateReq.java +++ b/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/req/questionbank/QuestionBankUpdateReq.java @@ -24,7 +24,7 @@ public class QuestionBankUpdateReq implements Serializable { /** * 题目类别 */ - private String categoryType; + private Long categoryId; /** * 题目类型 diff --git a/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/req/questionscategory/QuestionsCategoryCreateReq.java b/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/req/questionscategory/QuestionsCategoryCreateReq.java new file mode 100644 index 00000000..cf82b77f --- /dev/null +++ b/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/req/questionscategory/QuestionsCategoryCreateReq.java @@ -0,0 +1,28 @@ +package org.dromara.safety.domain.req.questionscategory; + +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; + +/** + * @author lcj + * @date 2025/4/15 9:39 + */ +@Data +public class QuestionsCategoryCreateReq implements Serializable { + + @Serial + private static final long serialVersionUID = -3517465472029929723L; + + /** + * 项目id + */ + private Long projectId; + + /** + * 题库类别 + */ + private String categoryName; + +} diff --git a/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/req/questionscategory/QuestionsCategoryQueryReq.java b/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/req/questionscategory/QuestionsCategoryQueryReq.java new file mode 100644 index 00000000..467ec485 --- /dev/null +++ b/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/req/questionscategory/QuestionsCategoryQueryReq.java @@ -0,0 +1,28 @@ +package org.dromara.safety.domain.req.questionscategory; + +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; + +/** + * @author lcj + * @date 2025/4/15 9:39 + */ +@Data +public class QuestionsCategoryQueryReq implements Serializable { + + @Serial + private static final long serialVersionUID = 8543449238477998979L; + + /** + * 项目id + */ + private Long projectId; + + /** + * 题库类别 + */ + private String categoryName; + +} diff --git a/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/req/questionscategory/QuestionsCategoryUpdateReq.java b/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/req/questionscategory/QuestionsCategoryUpdateReq.java new file mode 100644 index 00000000..542698e2 --- /dev/null +++ b/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/req/questionscategory/QuestionsCategoryUpdateReq.java @@ -0,0 +1,33 @@ +package org.dromara.safety.domain.req.questionscategory; + +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; + +/** + * @author lcj + * @date 2025/4/15 9:39 + */ +@Data +public class QuestionsCategoryUpdateReq implements Serializable { + + @Serial + private static final long serialVersionUID = -6588543841396112020L; + + /** + * 主键id + */ + private Long id; + + /** + * 项目id + */ + private Long projectId; + + /** + * 题库类别 + */ + private String categoryName; + +} diff --git a/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/req/questionuseranswer/QuestionUserAnswerBatchDownloadFileReq.java b/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/req/questionuseranswer/QuestionUserAnswerBatchDownloadFileReq.java new file mode 100644 index 00000000..7073787f --- /dev/null +++ b/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/req/questionuseranswer/QuestionUserAnswerBatchDownloadFileReq.java @@ -0,0 +1,24 @@ +package org.dromara.safety.domain.req.questionuseranswer; + +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; +import java.util.List; + +/** + * @author lcj + * @date 2025/4/15 16:35 + */ +@Data +public class QuestionUserAnswerBatchDownloadFileReq implements Serializable { + + @Serial + private static final long serialVersionUID = 5011807834768249135L; + + /** + * 用户id列表 + */ + private List userIdList; + +} diff --git a/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/req/questionuseranswer/QuestionUserAnswerQueryReq.java b/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/req/questionuseranswer/QuestionUserAnswerQueryReq.java index aee8df6c..463e0768 100644 --- a/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/req/questionuseranswer/QuestionUserAnswerQueryReq.java +++ b/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/req/questionuseranswer/QuestionUserAnswerQueryReq.java @@ -4,7 +4,6 @@ import lombok.Data; import java.io.Serial; import java.io.Serializable; -import java.util.List; /** * @author lcj @@ -16,43 +15,19 @@ public class QuestionUserAnswerQueryReq implements Serializable { @Serial private static final long serialVersionUID = -7056242109124074218L; - /** - * 主键id - */ - private Long id; - /** * 项目id */ private Long projectId; /** - * 用户id + * 用户名 */ - private Long userId; + private String userName; /** - * 题库id列表 + * 班组id */ - private List bankIdList; + private Long teamId; - /** - * 答案列表 - */ - private List answerList; - - /** - * 得分 - */ - private Long score; - - /** - * 用时时间(时间戳/秒) - */ - private Long takeTime; - - /** - * 及格线/总分(格式:60,100) - */ - private String pass; } diff --git a/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/req/questionuseranswer/QuestionUserAnswerUploadTemp.java b/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/req/questionuseranswer/QuestionUserAnswerUploadTemp.java new file mode 100644 index 00000000..336b5c3b --- /dev/null +++ b/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/req/questionuseranswer/QuestionUserAnswerUploadTemp.java @@ -0,0 +1,47 @@ +package org.dromara.safety.domain.req.questionuseranswer; + +import lombok.Data; + +/** + * @author lcj + * @date 2025/4/15 14:34 + */ +@Data +public class QuestionUserAnswerUploadTemp { + + /** + * 项目id + */ + private Long projectId; + + /** + * 用户身份证 + */ + private String userIdCard; + + /** + * 用户姓名 + */ + private String userName; + + /** + * 满分 + */ + private Long fullScore; + + /** + * 得分 + */ + private Long score; + + /** + * 及格分数 + */ + private Long passScore; + + /** + * 文件地址 + */ + private String file; + +} diff --git a/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/vo/BusQuestionBankVo.java b/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/vo/BusQuestionBankVo.java index 5713cd1c..a72757a0 100644 --- a/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/vo/BusQuestionBankVo.java +++ b/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/vo/BusQuestionBankVo.java @@ -10,6 +10,7 @@ import org.dromara.safety.domain.BusQuestionBank; import java.io.Serial; import java.io.Serializable; +import java.util.Date; import java.util.List; @@ -40,11 +41,15 @@ public class BusQuestionBankVo implements Serializable { private Long projectId; /** - * 题目类别 + * 题目类别id */ - @ExcelProperty(value = "题目类别", converter = ExcelDictConvert.class) - @ExcelDictFormat(dictType = "safety_question_category_type") - private String categoryType; + private Long categoryId; + + /** + * 题目类别名称 + */ + @ExcelProperty(value = "题目类别名称") + private String categoryName; /** * 题目类型 @@ -71,5 +76,9 @@ public class BusQuestionBankVo implements Serializable { @ExcelProperty(value = "正确答案") private String correctAnswer; + /** + * 创建时间 + */ + private Date createTime; } diff --git a/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/vo/BusQuestionUserAnswerVo.java b/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/vo/BusQuestionUserAnswerVo.java index 6c9c2a22..c7f81776 100644 --- a/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/vo/BusQuestionUserAnswerVo.java +++ b/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/vo/BusQuestionUserAnswerVo.java @@ -10,6 +10,7 @@ import org.dromara.safety.domain.BusQuestionUserAnswer; import java.io.Serial; import java.io.Serializable; +import java.util.Date; import java.util.List; @@ -30,13 +31,11 @@ public class BusQuestionUserAnswerVo implements Serializable { /** * 主键id */ - @ExcelProperty(value = "主键id") private Long id; /** * 项目id */ - @ExcelProperty(value = "项目id") private Long projectId; /** @@ -45,6 +44,12 @@ public class BusQuestionUserAnswerVo implements Serializable { @ExcelProperty(value = "用户id") private Long userId; + /** + * 用户名称 + */ + @ExcelProperty(value = "用户名称") + private String userName; + /** * 题库id列表 */ @@ -63,11 +68,16 @@ public class BusQuestionUserAnswerVo implements Serializable { @ExcelProperty(value = "得分") private Long score; + /** + * 考试时间(时间戳/秒) + */ + @ExcelProperty(value = "考试时间") + private Long examTime; + /** * 用时时间(时间戳/秒) */ - @ExcelProperty(value = "用时时间", converter = ExcelDictConvert.class) - @ExcelDictFormat(readConverterExp = "时=间戳/秒") + @ExcelProperty(value = "用时时间") private Long takeTime; /** @@ -82,5 +92,22 @@ public class BusQuestionUserAnswerVo implements Serializable { @ExcelProperty(value = "文件地址") private String file; + /** + * 文件地址列表 + */ + private List fileUrl; + + /** + * 考试类型 + */ + @ExcelProperty(value = "考试类型", converter = ExcelDictConvert.class) + @ExcelDictFormat(dictType = "user_exam_type") + private String examType; + + /** + * 创建时间 + */ + @ExcelProperty(value = "创建时间") + private Date createTime; } diff --git a/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/vo/BusQuestionsCategoryVo.java b/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/vo/BusQuestionsCategoryVo.java new file mode 100644 index 00000000..42a57869 --- /dev/null +++ b/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/vo/BusQuestionsCategoryVo.java @@ -0,0 +1,39 @@ +package org.dromara.safety.domain.vo; + +import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; +import com.alibaba.excel.annotation.ExcelProperty; +import io.github.linpeilie.annotations.AutoMapper; +import lombok.Data; +import org.dromara.safety.domain.BusQuestionsCategory; + +import java.io.Serial; +import java.io.Serializable; + + +/** + * 题库类别视图对象 bus_questions_category + * + * @author lcj + * @date 2025-04-15 + */ +@Data +@ExcelIgnoreUnannotated +@AutoMapper(target = BusQuestionsCategory.class) +public class BusQuestionsCategoryVo implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 主键id + */ + @ExcelProperty(value = "主键id") + private Long id; + + /** + * 题库类别 + */ + @ExcelProperty(value = "题库类别") + private String categoryName; + +} diff --git a/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/vo/BusSafetyInspectionVo.java b/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/vo/BusSafetyInspectionVo.java index 6b205a3e..f6123378 100644 --- a/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/vo/BusSafetyInspectionVo.java +++ b/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/vo/BusSafetyInspectionVo.java @@ -36,8 +36,7 @@ public class BusSafetyInspectionVo implements Serializable { /** * 父id(默认为0) */ - @ExcelProperty(value = "父id", converter = ExcelDictConvert.class) - @ExcelDictFormat(readConverterExp = "默=认为0") + @ExcelProperty(value = "父id") private Long pid; /** @@ -80,8 +79,7 @@ public class BusSafetyInspectionVo implements Serializable { /** * 整改人(班组长)id */ - @ExcelProperty(value = "整改人", converter = ExcelDictConvert.class) - @ExcelDictFormat(readConverterExp = "班=组长") + @ExcelProperty(value = "整改人") private Long correctorId; /** diff --git a/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/mapper/BusQuestionsCategoryMapper.java b/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/mapper/BusQuestionsCategoryMapper.java new file mode 100644 index 00000000..8b20d54e --- /dev/null +++ b/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/mapper/BusQuestionsCategoryMapper.java @@ -0,0 +1,15 @@ +package org.dromara.safety.mapper; + +import org.dromara.safety.domain.BusQuestionsCategory; +import org.dromara.safety.domain.vo.BusQuestionsCategoryVo; +import org.dromara.common.mybatis.core.mapper.BaseMapperPlus; + +/** + * 题库类别Mapper接口 + * + * @author lcj + * @date 2025-04-15 + */ +public interface BusQuestionsCategoryMapper extends BaseMapperPlus { + +} diff --git a/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/service/IBusQuestionUserAnswerService.java b/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/service/IBusQuestionUserAnswerService.java index f938815f..c71cc430 100644 --- a/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/service/IBusQuestionUserAnswerService.java +++ b/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/service/IBusQuestionUserAnswerService.java @@ -3,13 +3,16 @@ package org.dromara.safety.service; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.IService; +import jakarta.servlet.http.HttpServletResponse; import org.dromara.common.mybatis.core.page.PageQuery; import org.dromara.common.mybatis.core.page.TableDataInfo; import org.dromara.safety.domain.BusQuestionUserAnswer; +import org.dromara.safety.domain.req.questionuseranswer.QuestionUserAnswerBatchDownloadFileReq; import org.dromara.safety.domain.req.questionuseranswer.QuestionUserAnswerCreateReq; import org.dromara.safety.domain.req.questionuseranswer.QuestionUserAnswerQueryReq; import org.dromara.safety.domain.req.questionuseranswer.QuestionUserAnswerUpdateReq; import org.dromara.safety.domain.vo.BusQuestionUserAnswerVo; +import org.springframework.web.multipart.MultipartFile; import java.util.Collection; import java.util.List; @@ -55,6 +58,15 @@ public interface IBusQuestionUserAnswerService extends IService getVoPage(Page questionUserAnswerPage); + + /** + * 批量下载用户试卷存储文件 + * + * @param req 用户试卷存储文件下载请求 + * @param response 设置响应头和向客户端发送文件内容 + */ + void batchDownloadFile(QuestionUserAnswerBatchDownloadFileReq req, HttpServletResponse response); + } diff --git a/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/service/IBusQuestionsCategoryService.java b/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/service/IBusQuestionsCategoryService.java new file mode 100644 index 00000000..7fba5f86 --- /dev/null +++ b/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/service/IBusQuestionsCategoryService.java @@ -0,0 +1,99 @@ +package org.dromara.safety.service; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.IService; +import org.dromara.common.mybatis.core.page.PageQuery; +import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.safety.domain.BusQuestionsCategory; +import org.dromara.safety.domain.req.questionscategory.QuestionsCategoryCreateReq; +import org.dromara.safety.domain.req.questionscategory.QuestionsCategoryQueryReq; +import org.dromara.safety.domain.req.questionscategory.QuestionsCategoryUpdateReq; +import org.dromara.safety.domain.vo.BusQuestionsCategoryVo; + +import java.util.Collection; +import java.util.List; + +/** + * 题库类别Service接口 + * + * @author lcj + * @date 2025-04-15 + */ +public interface IBusQuestionsCategoryService extends IService { + + /** + * 查询题库类别 + * + * @param id 主键 + * @return 题库类别 + */ + BusQuestionsCategoryVo queryById(Long id); + + /** + * 分页查询题库类别列表 + * + * @param req 查询条件 + * @param pageQuery 分页参数 + * @return 题库类别分页列表 + */ + TableDataInfo queryPageList(QuestionsCategoryQueryReq req, PageQuery pageQuery); + + /** + * 查询符合条件的题库类别列表 + * + * @param req 查询条件 + * @return 题库类别列表 + */ + List queryList(QuestionsCategoryQueryReq req); + + /** + * 新增题库类别 + * + * @param req 题库类别 + * @return 新增题库类别组件 + */ + Long insertByBo(QuestionsCategoryCreateReq req); + + /** + * 修改题库类别 + * + * @param req 题库类别 + * @return 是否修改成功 + */ + Boolean updateByBo(QuestionsCategoryUpdateReq req); + + /** + * 校验并批量删除题库类别信息 + * + * @param ids 待删除的主键集合 + * @param isValid 是否进行有效性校验 + * @return 是否删除成功 + */ + Boolean deleteWithValidByIds(Collection ids, Boolean isValid); + + /** + * 获取题库类别视图对象 + * + * @param questionsCategory 题库类别对象 + * @return 题库类别视图对象 + */ + BusQuestionsCategoryVo getVo(BusQuestionsCategory questionsCategory); + + /** + * 获取题库类别查询条件封装 + * + * @param req 题库类别查询条件 + * @return 题库类别查询条件封装 + */ + LambdaQueryWrapper buildQueryWrapper(QuestionsCategoryQueryReq req); + + /** + * 获取题库类别分页对象视图 + * + * @param questionsCategoryPage 题库类别分页对象 + * @return 题库类别分页对象视图 + */ + Page getVoPage(Page questionsCategoryPage); + +} diff --git a/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/service/impl/BusQuestionBankServiceImpl.java b/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/service/impl/BusQuestionBankServiceImpl.java index 1c28648b..412a2d9e 100644 --- a/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/service/impl/BusQuestionBankServiceImpl.java +++ b/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/service/impl/BusQuestionBankServiceImpl.java @@ -18,18 +18,23 @@ import org.dromara.common.redis.utils.RedisUtils; import org.dromara.common.satoken.utils.LoginHelper; import org.dromara.project.service.IBusProjectService; import org.dromara.safety.domain.BusQuestionBank; +import org.dromara.safety.domain.BusQuestionsCategory; import org.dromara.safety.domain.req.questionbank.QuestionBankCreateReq; import org.dromara.safety.domain.req.questionbank.QuestionBankQueryReq; import org.dromara.safety.domain.req.questionbank.QuestionBankUpdateReq; import org.dromara.safety.domain.vo.BusQuestionBankVo; import org.dromara.safety.mapper.BusQuestionBankMapper; import org.dromara.safety.service.IBusQuestionBankService; +import org.dromara.safety.service.IBusQuestionsCategoryService; import org.springframework.beans.BeanUtils; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.Collection; import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; /** * 题库Service业务层处理 @@ -44,6 +49,9 @@ public class BusQuestionBankServiceImpl extends ServiceImpl optionList = req.getOptionList(); @@ -228,7 +245,7 @@ public class BusQuestionBankServiceImpl extends ServiceImpl categoryIdList = questionBankList.stream().map(BusQuestionBank::getCategoryId) + .collect(Collectors.toSet()); + Map> questionCategoryMap = questionsCategoryService.listByIds(categoryIdList) + .stream().collect(Collectors.groupingBy(BusQuestionsCategory::getId)); // 对象列表 => 封装对象列表 - List questionBankVoList = questionBankList.stream().map(this::getVo).toList(); + List questionBankVoList = questionBankList.stream().map(questionBank -> { + BusQuestionBankVo questionBankVo = new BusQuestionBankVo(); + BeanUtils.copyProperties(questionBank, questionBankVo); + // 获取题目分类名称 + Long categoryId = questionBank.getCategoryId(); + String categoryName = null; + if (questionCategoryMap.containsKey(categoryId)) { + BusQuestionsCategory category = questionCategoryMap.get(categoryId).get(0); + categoryName = category.getCategoryName(); + } + questionBankVo.setCategoryName(categoryName); + // 返回封装对象 + return questionBankVo; + }).toList(); questionBankVoPage.setRecords(questionBankVoList); return questionBankVoPage; } diff --git a/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/service/impl/BusQuestionUserAnswerServiceImpl.java b/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/service/impl/BusQuestionUserAnswerServiceImpl.java index e16472e4..af865a1e 100644 --- a/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/service/impl/BusQuestionUserAnswerServiceImpl.java +++ b/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/service/impl/BusQuestionUserAnswerServiceImpl.java @@ -1,31 +1,55 @@ package org.dromara.safety.service.impl; import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.io.FileUtil; +import cn.hutool.core.util.RandomUtil; +import cn.hutool.core.util.ZipUtil; import cn.hutool.json.JSONUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import jakarta.annotation.Resource; +import jakarta.servlet.http.HttpServletResponse; +import lombok.extern.slf4j.Slf4j; import org.dromara.common.core.constant.HttpStatus; import org.dromara.common.core.exception.ServiceException; +import org.dromara.common.core.utils.DateUtils; import org.dromara.common.core.utils.ObjectUtils; import org.dromara.common.core.utils.StringUtils; +import org.dromara.common.core.utils.file.FileUtils; import org.dromara.common.mybatis.core.page.PageQuery; import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.common.oss.core.OssClient; +import org.dromara.common.oss.exception.OssException; +import org.dromara.common.oss.factory.OssFactory; +import org.dromara.project.domain.BusConstructionUser; +import org.dromara.project.domain.BusProjectTeamMember; +import org.dromara.project.service.IBusConstructionUserService; import org.dromara.project.service.IBusProjectService; +import org.dromara.project.service.IBusProjectTeamMemberService; import org.dromara.safety.domain.BusQuestionUserAnswer; -import org.dromara.safety.domain.req.questionuseranswer.QuestionUserAnswerCreateReq; -import org.dromara.safety.domain.req.questionuseranswer.QuestionUserAnswerQueryReq; -import org.dromara.safety.domain.req.questionuseranswer.QuestionUserAnswerUpdateReq; +import org.dromara.safety.domain.enums.SafetyExamTypeEnum; +import org.dromara.safety.domain.req.questionuseranswer.*; import org.dromara.safety.domain.vo.BusQuestionUserAnswerVo; import org.dromara.safety.mapper.BusQuestionUserAnswerMapper; import org.dromara.safety.service.IBusQuestionUserAnswerService; +import org.dromara.system.domain.vo.SysOssVo; +import org.dromara.system.service.ISysOssService; import org.springframework.beans.BeanUtils; +import org.springframework.http.MediaType; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.multipart.MultipartFile; -import java.util.Collection; -import java.util.List; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.*; +import java.util.stream.Collectors; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; /** * 用户试卷存储Service业务层处理 @@ -33,6 +57,7 @@ import java.util.List; * @author lcj * @date 2025-03-24 */ +@Slf4j @Service public class BusQuestionUserAnswerServiceImpl extends ServiceImpl implements IBusQuestionUserAnswerService { @@ -40,6 +65,15 @@ public class BusQuestionUserAnswerServiceImpl extends ServiceImpl tempList = new ArrayList<>(); + try { + // 4. 创建临时文件 + tempZipFile = File.createTempFile(tempZipFilePath, null); + multipartFile.transferTo(tempZipFile); + // 5. 解压 zip + destDir = new File(destDirPath); + ZipUtil.unzip(tempZipFile, destDir); + // 4. 遍历最外层文件夹 + File[] userFolders = destDir.listFiles(); + if (userFolders != null) { + for (File userFolder : userFolders) { + if (userFolder.isDirectory()) { + // 5. 获取文件名,格式为 姓名-身份证-满分-得分-及格分,例如 小明-500106200101011234-100-61-60 + String userFolderName = userFolder.getName(); + String[] userParts = userFolderName.split("-"); + // 6. 继续遍历获取每个用户子文件夹里的文件 + File[] docFolders = userFolder.listFiles(); + String fileIdStr = null; + if (docFolders != null) { + // 6.1 遍历文件 + List fileIdList = new ArrayList<>(); + for (File docFolder : docFolders) { + if (docFolder.isFile()) { + // 6.2 上传文件 + SysOssVo upload = ossService.upload(docFolder); + if (upload != null) { + fileIdList.add(upload.getOssId()); + } + } + } + // 6.3 跳过空文件 + if (fileIdList.isEmpty()) { + continue; + } + fileIdStr = fileIdList.stream() + .map(String::valueOf) + .collect(Collectors.joining(",")); + } + // 7. 创建临时对象 + QuestionUserAnswerUploadTemp temp = new QuestionUserAnswerUploadTemp(); + temp.setProjectId(projectId); + temp.setUserName(userParts[0]); + temp.setUserIdCard(userParts[1]); + temp.setFullScore(Long.parseLong(userParts[2])); + temp.setScore(Long.parseLong(userParts[3])); + temp.setPassScore(Long.parseLong(userParts[4])); + temp.setFile(fileIdStr); + tempList.add(temp); + } + } + } + } catch (Exception e) { + throw new ServiceException("文件上传失败", HttpStatus.ERROR); + } finally { + if (tempZipFile != null) { + // 删除临时文件 + boolean delete = tempZipFile.delete(); + if (!delete) { + log.error("临时文件删除失败,路径:{}", tempZipFilePath); + } + } + if (destDir != null) { + Path dirPath = Paths.get(basePath); + try { + FileUtils.deleteDirectory(dirPath); + } catch (IOException e) { + log.error("解压文件删除失败,路径:{}", destDirPath, e); + } + } + } + // 8. 遍历临时对象,进行存储 + if (CollUtil.isEmpty(tempList)) { + return true; + } + // 8.1 获取用户身份证列表 + Set idCardList = tempList.stream().map(QuestionUserAnswerUploadTemp::getUserIdCard) + .collect(Collectors.toSet()); + // 8.2 根据用户身份证列表查询用户信息 + Map> userIdMap = constructionUserService.lambdaQuery() + .in(BusConstructionUser::getSfzNumber, idCardList).list() + .stream().collect(Collectors.groupingBy(BusConstructionUser::getSfzNumber)); + // 8.3 遍历临时对象,构造用户试卷存储对象 + List questionUserAnswerList = tempList.stream().map(temp -> { + BusQuestionUserAnswer questionUserAnswer = new BusQuestionUserAnswer(); + // 8.4 获取对应用户id + String userIdCard = temp.getUserIdCard(); + Long userId = null; + if (userIdMap.containsKey(userIdCard)) { + BusConstructionUser constructionUser = userIdMap.get(userIdCard).get(0); + userId = constructionUser.getId(); + } + // 8.5 判断用户是否存在 + if (userId == null) { + String userName = temp.getUserName(); + String message = String.format("用户[%s:%s]不存在", userName, userIdCard); + throw new ServiceException(message, HttpStatus.NOT_FOUND); + } + questionUserAnswer.setUserId(userId); + // 8.6 设置其他属性 + questionUserAnswer.setProjectId(temp.getProjectId()); + questionUserAnswer.setScore(temp.getScore()); + String pass = String.format("%s,%s", temp.getPassScore(), temp.getFullScore()); + questionUserAnswer.setPass(pass); + questionUserAnswer.setFile(temp.getFile()); + questionUserAnswer.setExamType(SafetyExamTypeEnum.OFFLINE.getValue()); + return questionUserAnswer; + }).toList(); + // 9. 保存 + boolean result = this.saveBatch(questionUserAnswerList); + if (!result) { + throw new ServiceException("数据库操作失败", HttpStatus.ERROR); + } + return true; + } + /** * 修改用户试卷存储 * @@ -190,14 +369,29 @@ public class BusQuestionUserAnswerServiceImpl extends ServiceImpl fileIdList = Arrays.stream(file.split(",")).map(Long::parseLong).toList(); + List fileUrlList = ossService.listByIds(fileIdList).stream().map(SysOssVo::getUrl).toList(); + questionUserAnswerVo.setFileUrl(fileUrlList); + } return questionUserAnswerVo; } @@ -213,33 +407,36 @@ public class BusQuestionUserAnswerServiceImpl extends ServiceImpl bankIdList = req.getBankIdList(); - List answerList = req.getAnswerList(); - Long score = req.getScore(); - Long takeTime = req.getTakeTime(); - String pass = req.getPass(); - // JSON 数组查询 - if (CollUtil.isNotEmpty(bankIdList)) { - for (Long bankId : bankIdList) { - lqw.like(BusQuestionUserAnswer::getBankId, "\"" + bankId + "\""); + String userName = req.getUserName(); + Long teamId = req.getTeamId(); + // 联表查询 + if (StringUtils.isNotBlank(userName)) { + List constructionUserList = constructionUserService.lambdaQuery() + .select(BusConstructionUser::getId) + .like(BusConstructionUser::getUserName, userName) + .list(); + if (CollUtil.isNotEmpty(constructionUserList)) { + List userIdList = constructionUserList.stream().map(BusConstructionUser::getId).toList(); + lqw.in(BusQuestionUserAnswer::getUserId, userIdList); + } else { + lqw.eq(BusQuestionUserAnswer::getUserId, null); } } - if (CollUtil.isNotEmpty(answerList)) { - for (String answer : answerList) { - lqw.like(BusQuestionUserAnswer::getAnswer, "\"" + answer + "\""); + if (ObjectUtils.isNotEmpty(teamId)) { + List projectTeamMemberList = projectTeamMemberService.lambdaQuery() + .select(BusProjectTeamMember::getMemberId) + .eq(BusProjectTeamMember::getTeamId, teamId) + .list(); + if (CollUtil.isNotEmpty(projectTeamMemberList)) { + List userIdList = projectTeamMemberList.stream().map(BusProjectTeamMember::getMemberId).toList(); + lqw.in(BusQuestionUserAnswer::getUserId, userIdList); + } else { + lqw.eq(BusQuestionUserAnswer::getUserId, null); } } - // 模糊查询 - lqw.like(StringUtils.isNotBlank(pass), BusQuestionUserAnswer::getPass, pass); // 精准查询 - lqw.eq(ObjectUtils.isNotEmpty(id), BusQuestionUserAnswer::getId, id); lqw.eq(ObjectUtils.isNotEmpty(projectId), BusQuestionUserAnswer::getProjectId, projectId); - lqw.eq(ObjectUtils.isNotEmpty(userId), BusQuestionUserAnswer::getUserId, userId); - lqw.eq(ObjectUtils.isNotEmpty(score), BusQuestionUserAnswer::getScore, score); - lqw.eq(ObjectUtils.isNotEmpty(takeTime), BusQuestionUserAnswer::getTakeTime, takeTime); return lqw; } @@ -262,10 +459,123 @@ public class BusQuestionUserAnswerServiceImpl extends ServiceImpl userIdList = questionUserAnswerList.stream().map(BusQuestionUserAnswer::getUserId).collect(Collectors.toSet()); + List constructionUserList = constructionUserService.lambdaQuery() + .select(BusConstructionUser::getId, BusConstructionUser::getUserName) + .in(BusConstructionUser::getId, userIdList) + .list(); + Map userNameMap = constructionUserList.stream() + .collect(Collectors.toMap(BusConstructionUser::getId, BusConstructionUser::getUserName)); + // 获取用户文件 + Set fileIdList = questionUserAnswerList.stream().map(BusQuestionUserAnswer::getFile).filter(StringUtils::isNotBlank) + .flatMap(fileId -> Arrays.stream(fileId.split(",")).map(Long::parseLong)).collect(Collectors.toSet()); + Map> ossMap = ossService.listByIds(fileIdList) + .stream().collect(Collectors.groupingBy(SysOssVo::getOssId)); // 对象列表 => 封装对象列表 - List questionUserAnswerVoList = questionUserAnswerList.stream().map(this::getVo).toList(); + List questionUserAnswerVoList = questionUserAnswerList.stream().map(questionUserAnswer -> { + BusQuestionUserAnswerVo questionUserAnswerVo = new BusQuestionUserAnswerVo(); + BeanUtils.copyProperties(questionUserAnswer, questionUserAnswerVo); + // 获取获取用户名 + Long userId = questionUserAnswer.getUserId(); + if (userId != null) { + questionUserAnswerVo.setUserName(userNameMap.get(userId)); + } + // 获取用户文件 + String file = questionUserAnswer.getFile(); + if (StringUtils.isNotBlank(file)) { + List ossIdList = Arrays.stream(file.split(",")).map(Long::parseLong).toList(); + List fileUrlList = ossIdList.stream().map(ossId -> { + String url = ""; + if (ossMap.containsKey(ossId)) { + url = ossMap.get(ossId).get(0).getUrl(); + } + return url; + }).toList(); + questionUserAnswerVo.setFileUrl(fileUrlList); + } + // 获取用户试卷题库列表 + String bankId = questionUserAnswer.getBankId(); + if (StringUtils.isNotBlank(bankId)) { + questionUserAnswerVo.setBankIdList(JSONUtil.toList(bankId, Long.class)); + } + // 获取用户试卷答案列表 + String answer = questionUserAnswer.getAnswer(); + if (StringUtils.isNotBlank(answer)) { + questionUserAnswerVo.setAnswerList(JSONUtil.toList(answer, String.class)); + } + return questionUserAnswerVo; + }).toList(); questionUserAnswerVoPage.setRecords(questionUserAnswerVoList); return questionUserAnswerVoPage; } + /** + * 批量下载用户试卷存储文件 + * + * @param req 用户试卷存储文件下载请求 + * @param response 设置响应头和向客户端发送文件内容 + */ + @Override + public void batchDownloadFile(QuestionUserAnswerBatchDownloadFileReq req, HttpServletResponse response) { + // 获取用户试卷存储文件 + List userIdList = req.getUserIdList(); + List questionUserAnswerList = lambdaQuery() + .in(BusQuestionUserAnswer::getUserId, userIdList) + .list(); + if (CollUtil.isEmpty(questionUserAnswerList)) { + return; + } + // 查询对应施工人员信息 + Map> userMap = constructionUserService.lambdaQuery() + .select(BusConstructionUser::getId, BusConstructionUser::getUserName) + .in(BusConstructionUser::getId, userIdList).list() + .stream().collect(Collectors.groupingBy(BusConstructionUser::getId)); + if (CollUtil.isEmpty(userMap)) { + return; + } + // 设置响应头 + response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE + "; charset=UTF-8"); + try (ZipOutputStream zos = new ZipOutputStream(response.getOutputStream())) { + // 遍历所有用户文件 + for (BusQuestionUserAnswer questionUserAnswer : questionUserAnswerList) { + String file = questionUserAnswer.getFile(); + if (StringUtils.isBlank(file)) { + continue; + } + Long userId = questionUserAnswer.getUserId(); + BusConstructionUser constructionUser = userMap.get(userId).get(0); + String userFolder = constructionUser.getUserName() + "-" + constructionUser.getId() + "/"; + // 写入个人文件夹条目 + zos.putNextEntry(new ZipEntry(userFolder)); + zos.closeEntry(); + List ossIdList = Arrays.stream(file.split(",")).map(Long::parseLong).toList(); + List ossVoList = ossService.listByIds(ossIdList); + // 遍历用户文件 + for (SysOssVo ossVo : ossVoList) { + // 获取文件输入流 + OssClient storage = OssFactory.instance(ossVo.getService()); + String path = ossVo.getUrl(); + try (InputStream is = storage.getObjectContent(path)) { + // 从路径中提取文件名(可以根据业务规则调整) + String fileName = userFolder + "/" + ossVo.getOriginalName(); + zos.putNextEntry(new ZipEntry(fileName)); + byte[] buffer = new byte[4096]; + int len; + while ((len = is.read(buffer)) != -1) { + zos.write(buffer, 0, len); + } + zos.closeEntry(); + } catch (IOException e) { + // 针对单个文件处理异常,可以选择记录日志或终止处理 + throw new OssException("处理文件[" + path + "]失败,错误信息: " + e.getMessage()); + } + } + } + zos.finish(); + } catch (IOException e) { + throw new OssException("生成ZIP文件失败,错误信息: " + e.getMessage()); + } + } + } diff --git a/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/service/impl/BusQuestionsCategoryServiceImpl.java b/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/service/impl/BusQuestionsCategoryServiceImpl.java new file mode 100644 index 00000000..cf44cc86 --- /dev/null +++ b/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/service/impl/BusQuestionsCategoryServiceImpl.java @@ -0,0 +1,225 @@ +package org.dromara.safety.service.impl; + +import cn.hutool.core.collection.CollUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import jakarta.annotation.Resource; +import org.dromara.common.core.constant.HttpStatus; +import org.dromara.common.core.exception.ServiceException; +import org.dromara.common.core.utils.ObjectUtils; +import org.dromara.common.core.utils.StringUtils; +import org.dromara.common.mybatis.core.page.PageQuery; +import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.common.satoken.utils.LoginHelper; +import org.dromara.project.service.IBusProjectService; +import org.dromara.safety.domain.BusQuestionsCategory; +import org.dromara.safety.domain.req.questionscategory.QuestionsCategoryCreateReq; +import org.dromara.safety.domain.req.questionscategory.QuestionsCategoryQueryReq; +import org.dromara.safety.domain.req.questionscategory.QuestionsCategoryUpdateReq; +import org.dromara.safety.domain.vo.BusQuestionsCategoryVo; +import org.dromara.safety.mapper.BusQuestionsCategoryMapper; +import org.dromara.safety.service.IBusQuestionsCategoryService; +import org.springframework.beans.BeanUtils; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.Collection; +import java.util.List; + +/** + * 题库类别Service业务层处理 + * + * @author lcj + * @date 2025-04-15 + */ +@Service +public class BusQuestionsCategoryServiceImpl extends ServiceImpl + implements IBusQuestionsCategoryService { + + @Resource + private IBusProjectService projectService; + + /** + * 查询题库类别 + * + * @param id 主键 + * @return 题库类别 + */ + @Override + public BusQuestionsCategoryVo queryById(Long id) { + BusQuestionsCategory questionsCategory = this.getById(id); + if (questionsCategory == null) { + throw new ServiceException("题库类别信息不存在", HttpStatus.NOT_FOUND); + } + return this.getVo(questionsCategory); + } + + /** + * 分页查询题库类别列表 + * + * @param req 查询条件 + * @param pageQuery 分页参数 + * @return 题库类别分页列表 + */ + @Override + public TableDataInfo queryPageList(QuestionsCategoryQueryReq req, PageQuery pageQuery) { + Page result = this.page(pageQuery.build(), buildQueryWrapper(req)); + return TableDataInfo.build(this.getVoPage(result)); + } + + /** + * 查询符合条件的题库类别列表 + * + * @param req 查询条件 + * @return 题库类别列表 + */ + @Override + public List queryList(QuestionsCategoryQueryReq req) { + LambdaQueryWrapper lqw = this.buildQueryWrapper(req); + return this.list(lqw).stream().map(this::getVo).toList(); + } + + /** + * 新增题库类别 + * + * @param req 题库类别 + * @return 新增题库类别主键 + */ + @Override + public Long insertByBo(QuestionsCategoryCreateReq req) { + // 将实体类和 DTO 进行转换 + BusQuestionsCategory questionsCategory = new BusQuestionsCategory(); + BeanUtils.copyProperties(req, questionsCategory); + // 数据校验 + validEntityBeforeSave(questionsCategory, true); + // 写入数据库 + boolean save = this.save(questionsCategory); + if (!save) { + throw new ServiceException("新增题库类别失败,数据库异常", HttpStatus.ERROR); + } + // 返回新写入的数据 + return questionsCategory.getId(); + } + + /** + * 修改题库类别 + * + * @param req 题库类别 + * @return 是否修改成功 + */ + @Override + public Boolean updateByBo(QuestionsCategoryUpdateReq req) { + // 将实体类和 DTO 进行转换 + BusQuestionsCategory questionsCategory = new BusQuestionsCategory(); + BeanUtils.copyProperties(req, questionsCategory); + // 数据校验 + validEntityBeforeSave(questionsCategory, false); + // 判断是否存在 + BusQuestionsCategory oldQuestionsCategory = this.getById(questionsCategory.getId()); + if (oldQuestionsCategory == null) { + throw new ServiceException("修改题库类别失败,数据不存在", HttpStatus.NOT_FOUND); + } + // 操作数据库 + return this.updateById(questionsCategory); + } + + /** + * 保存前的数据校验 + */ + private void validEntityBeforeSave(BusQuestionsCategory entity, Boolean create) { + // TODO 做一些数据校验,如唯一约束 + Long projectId = entity.getProjectId(); + if (create) { + if (projectId == null) { + throw new ServiceException("项目id不能为空", HttpStatus.BAD_REQUEST); + } + } + if (projectId != null && projectService.getById(projectId) == null) { + throw new ServiceException("对应项目不存在", HttpStatus.NOT_FOUND); + } + } + + /** + * 校验并批量删除题库类别信息 + * + * @param ids 待删除的主键集合 + * @param isValid 是否进行有效性校验 + * @return 是否删除成功 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Boolean deleteWithValidByIds(Collection ids, Boolean isValid) { + Long userId = LoginHelper.getUserId(); + List questionsCategoryList = this.listByIds(ids); + if (isValid) { + // TODO 做一些业务上的校验,判断是否需要校验 + List projectId = questionsCategoryList.stream().map(BusQuestionsCategory::getProjectId).toList(); + projectService.validAuth(projectId, userId); + } + return this.removeBatchByIds(ids); + } + + /** + * 获取题库类别视图对象 + * + * @param questionsCategory 题库类别对象 + * @return 题库类别视图对象 + */ + @Override + public BusQuestionsCategoryVo getVo(BusQuestionsCategory questionsCategory) { + // 对象转封装类 + BusQuestionsCategoryVo questionsCategoryVo = new BusQuestionsCategoryVo(); + if (questionsCategory == null) { + return questionsCategoryVo; + } + BeanUtils.copyProperties(questionsCategory, questionsCategoryVo); + return questionsCategoryVo; + } + + /** + * 获取题库类别查询条件封装 + * + * @param req 题库类别查询条件 + * @return 题库类别查询条件封装 + */ + @Override + public LambdaQueryWrapper buildQueryWrapper(QuestionsCategoryQueryReq req) { + LambdaQueryWrapper lqw = new LambdaQueryWrapper<>(); + if (req == null) { + return lqw; + } + Long projectId = req.getProjectId(); + String categoryName = req.getCategoryName(); + // 模糊查询 + lqw.like(StringUtils.isNotBlank(categoryName), BusQuestionsCategory::getCategoryName, categoryName); + // 精确查询 + lqw.eq(ObjectUtils.isNotEmpty(projectId), BusQuestionsCategory::getProjectId, projectId); + return lqw; + } + + /** + * 获取题库类别分页对象视图 + * + * @param questionsCategoryPage 题库类别分页对象 + * @return 题库类别分页对象视图 + */ + @Override + public Page getVoPage(Page questionsCategoryPage) { + // 获取分页数据 + List questionsCategoryList = questionsCategoryPage.getRecords(); + // 添加分页信息 + Page questionsCategoryVoPage = new Page<>( + questionsCategoryPage.getCurrent(), + questionsCategoryPage.getSize(), + questionsCategoryPage.getTotal() + ); + if (CollUtil.isEmpty(questionsCategoryList)) { + return questionsCategoryVoPage; + } + // 对象列表 => 封装对象列表 + List questionsCategoryVoList = questionsCategoryList.stream().map(this::getVo).toList(); + questionsCategoryVoPage.setRecords(questionsCategoryVoList); + return questionsCategoryVoPage; + } +} diff --git a/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/resources/mapper/safety/BusQuestionsCategoryMapper.xml b/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/resources/mapper/safety/BusQuestionsCategoryMapper.xml new file mode 100644 index 00000000..c5727486 --- /dev/null +++ b/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-system/src/main/resources/mapper/safety/BusQuestionsCategoryMapper.xml @@ -0,0 +1,7 @@ + + + + + diff --git a/RuoYi-Vue-Plus/script/sql/xinnengyuan.sql b/RuoYi-Vue-Plus/script/sql/xinnengyuan.sql index b3e0b0a5..0daf84ad 100644 --- a/RuoYi-Vue-Plus/script/sql/xinnengyuan.sql +++ b/RuoYi-Vue-Plus/script/sql/xinnengyuan.sql @@ -678,3 +678,15 @@ CREATE TABLE `bus_document_safety_meeting` INDEX `idx_pid` (`pid` ASC) USING BTREE, INDEX `idx_project_id` (`project_id` ASC) USING BTREE ) comment = '安全会议纪要' COLLATE = utf8mb4_unicode_ci; + +DROP TABLE IF EXISTS `bus_questions_category`; +CREATE TABLE `bus_questions_category` +( + `id` bigint not null auto_increment comment '主键id', + `project_id` bigint not null comment '项目id', + `category_name` varchar(255) not null comment '题库类别', + `create_time` datetime default CURRENT_TIMESTAMP null comment '创建时间', + `update_time` datetime default CURRENT_TIMESTAMP null on update CURRENT_TIMESTAMP comment '更新时间', + PRIMARY KEY (`id`) USING BTREE, + INDEX `idx_project_id` (`project_id` ASC) USING BTREE +) comment = '题库类别' COLLATE = utf8mb4_unicode_ci;