新增安全教育培训题库列表相关接口,批量上传、下载线下考试文件接口;优化,修改HSE管理相关代码逻辑
This commit is contained in:
@ -6,6 +6,7 @@ import jakarta.validation.constraints.NotNull;
|
|||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.dromara.common.core.domain.R;
|
import org.dromara.common.core.domain.R;
|
||||||
import org.dromara.common.excel.utils.ExcelUtil;
|
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.annotation.Log;
|
||||||
import org.dromara.common.log.enums.BusinessType;
|
import org.dromara.common.log.enums.BusinessType;
|
||||||
import org.dromara.common.web.core.BaseController;
|
import org.dromara.common.web.core.BaseController;
|
||||||
@ -59,6 +60,7 @@ public class BusConstructionUserFileController extends BaseController {
|
|||||||
*/
|
*/
|
||||||
@SaCheckPermission("project:constructionUserFile:export")
|
@SaCheckPermission("project:constructionUserFile:export")
|
||||||
@Log(title = "施工人员文件存储", businessType = BusinessType.EXPORT)
|
@Log(title = "施工人员文件存储", businessType = BusinessType.EXPORT)
|
||||||
|
@RepeatSubmit()
|
||||||
@PostMapping("/exportFileTemplate")
|
@PostMapping("/exportFileTemplate")
|
||||||
public void exportFileTemplate(ConstructionUserFileTemplateReq req, HttpServletResponse response) {
|
public void exportFileTemplate(ConstructionUserFileTemplateReq req, HttpServletResponse response) {
|
||||||
busConstructionUserFileService.downloadFileTemplate(req, response);
|
busConstructionUserFileService.downloadFileTemplate(req, response);
|
||||||
@ -69,6 +71,7 @@ public class BusConstructionUserFileController extends BaseController {
|
|||||||
*/
|
*/
|
||||||
@SaCheckPermission("project:constructionUserFile:edit")
|
@SaCheckPermission("project:constructionUserFile:edit")
|
||||||
@Log(title = "施工人员文件存储", businessType = BusinessType.INSERT)
|
@Log(title = "施工人员文件存储", businessType = BusinessType.INSERT)
|
||||||
|
@RepeatSubmit()
|
||||||
@PostMapping("/upload/zip")
|
@PostMapping("/upload/zip")
|
||||||
public R<Boolean> uploadFileZip(@RequestParam("file") MultipartFile file) {
|
public R<Boolean> uploadFileZip(@RequestParam("file") MultipartFile file) {
|
||||||
Boolean result = busConstructionUserFileService.batchUploadFileByZip(file);
|
Boolean result = busConstructionUserFileService.batchUploadFileByZip(file);
|
||||||
|
@ -48,10 +48,10 @@ public interface IBusConstructionUserFileService extends IService<BusConstructio
|
|||||||
/**
|
/**
|
||||||
* 通过zip文件批量上传施工人员文件
|
* 通过zip文件批量上传施工人员文件
|
||||||
*
|
*
|
||||||
* @param file zip文件
|
* @param multipartFile zip文件
|
||||||
* @return 是否上传成功
|
* @return 是否上传成功
|
||||||
*/
|
*/
|
||||||
Boolean batchUploadFileByZip(MultipartFile file);
|
Boolean batchUploadFileByZip(MultipartFile multipartFile);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 保存施工人员文件存储
|
* 保存施工人员文件存储
|
||||||
|
@ -126,12 +126,14 @@ public class BusAttendanceServiceImpl extends ServiceImpl<BusAttendanceMapper, B
|
|||||||
.eq(StringUtils.isNotEmpty(req.getUserName()), BusAttendance::getUserName, req.getUserName())
|
.eq(StringUtils.isNotEmpty(req.getUserName()), BusAttendance::getUserName, req.getUserName())
|
||||||
.between(BusAttendance::getClockDate, startDate, endDate)
|
.between(BusAttendance::getClockDate, startDate, endDate)
|
||||||
.orderByDesc(BusAttendance::getClockDate);
|
.orderByDesc(BusAttendance::getClockDate);
|
||||||
|
// 获取黑名单用户列表
|
||||||
|
List<Long> blackList = constructionBlacklistService.queryIdListByProjectId(projectId);
|
||||||
// 构建查询用户相关信息查询条件
|
// 构建查询用户相关信息查询条件
|
||||||
List<Long> userIdList = constructionUserService.lambdaQuery()
|
List<Long> userIdList = constructionUserService.lambdaQuery()
|
||||||
.eq(BusConstructionUser::getProjectId, projectId)
|
.eq(BusConstructionUser::getProjectId, projectId)
|
||||||
.eq(req.getTeamId() != null, BusConstructionUser::getTeamId, req.getTeamId())
|
.eq(req.getTeamId() != null, BusConstructionUser::getTeamId, req.getTeamId())
|
||||||
.eq(req.getTypeOfWork() != null, BusConstructionUser::getTypeOfWork, req.getTypeOfWork())
|
.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();
|
.list().stream().map(BusConstructionUser::getId).toList();
|
||||||
lqw.in(CollUtil.isNotEmpty(userIdList), BusAttendance::getUserId, userIdList);
|
lqw.in(CollUtil.isNotEmpty(userIdList), BusAttendance::getUserId, userIdList);
|
||||||
Map<Date, List<BusAttendance>> dateListMap = this.list(lqw)
|
Map<Date, List<BusAttendance>> dateListMap = this.list(lqw)
|
||||||
|
@ -13,10 +13,19 @@ public interface DocumentSafetyMeetingConstant {
|
|||||||
*/
|
*/
|
||||||
String TOP_FOLDER_PREFIX = "/doc/safety/meeting/";
|
String TOP_FOLDER_PREFIX = "/doc/safety/meeting/";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取顶级目录前缀
|
||||||
|
*
|
||||||
|
* @param projectId 项目id
|
||||||
|
* @return 顶级目录前缀
|
||||||
|
*/
|
||||||
static String getTopFolderPrefix(Long projectId) {
|
static String getTopFolderPrefix(Long projectId) {
|
||||||
return String.format("%s%s/", TOP_FOLDER_PREFIX, projectId);
|
return String.format("%s%s/", TOP_FOLDER_PREFIX, projectId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 图片后缀列表
|
||||||
|
*/
|
||||||
List<String> PICTURE_SUFFIX_LIST = List.of("jpeg", "jpg", "png", "webp");
|
List<String> PICTURE_SUFFIX_LIST = List.of("jpeg", "jpg", "png", "webp");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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.PageQuery;
|
||||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||||
import org.dromara.common.web.core.BaseController;
|
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.QuestionUserAnswerCreateReq;
|
||||||
import org.dromara.safety.domain.req.questionuseranswer.QuestionUserAnswerQueryReq;
|
import org.dromara.safety.domain.req.questionuseranswer.QuestionUserAnswerQueryReq;
|
||||||
import org.dromara.safety.domain.req.questionuseranswer.QuestionUserAnswerUpdateReq;
|
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.dromara.safety.service.IBusQuestionUserAnswerService;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@ -59,6 +61,18 @@ public class BusQuestionUserAnswerController extends BaseController {
|
|||||||
ExcelUtil.exportExcel(list, "用户试卷存储", BusQuestionUserAnswerVo.class, response);
|
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));
|
return R.ok(busQuestionUserAnswerService.insertByBo(req));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 上传线下考试试卷存储
|
||||||
|
*/
|
||||||
|
@SaCheckPermission("safety:questionUserAnswer:add")
|
||||||
|
@Log(title = "用户试卷存储", businessType = BusinessType.INSERT)
|
||||||
|
@RepeatSubmit()
|
||||||
|
@PostMapping("/upload/zip")
|
||||||
|
public R<Boolean> batchUploadFileByZip(@RequestParam("file") MultipartFile multipartFile,
|
||||||
|
Long projectId) {
|
||||||
|
return R.ok(busQuestionUserAnswerService.batchUploadFileByZip(multipartFile, projectId));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 修改用户试卷存储
|
* 修改用户试卷存储
|
||||||
*/
|
*/
|
||||||
|
@ -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<BusQuestionsCategoryVo> 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<BusQuestionsCategoryVo> list = busQuestionsCategoryService.queryList(req);
|
||||||
|
ExcelUtil.exportExcel(list, "题库类别", BusQuestionsCategoryVo.class, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取题库类别详细信息
|
||||||
|
*
|
||||||
|
* @param id 主键
|
||||||
|
*/
|
||||||
|
@SaCheckPermission("safety:questionsCategory:query")
|
||||||
|
@GetMapping("/{id}")
|
||||||
|
public R<BusQuestionsCategoryVo> 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<Long> 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<Void> 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<Void> remove(@NotEmpty(message = "主键不能为空")
|
||||||
|
@PathVariable Long[] ids) {
|
||||||
|
return toAjax(busQuestionsCategoryService.deleteWithValidByIds(List.of(ids), true));
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,7 @@
|
|||||||
package org.dromara.safety.domain;
|
package org.dromara.safety.domain;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.annotation.TableId;
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.EqualsAndHashCode;
|
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删除)
|
* 是否删除(0正常 1删除)
|
||||||
*/
|
*/
|
||||||
|
@TableLogic
|
||||||
private Long isDelete;
|
private Long isDelete;
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package org.dromara.safety.domain;
|
package org.dromara.safety.domain;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.annotation.TableId;
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
@ -54,6 +55,11 @@ public class BusQuestionUserAnswer extends BaseEntity {
|
|||||||
*/
|
*/
|
||||||
private Long score;
|
private Long score;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 考试时间(时间戳/秒)
|
||||||
|
*/
|
||||||
|
private Long examTime;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用时时间(时间戳/秒)
|
* 用时时间(时间戳/秒)
|
||||||
*/
|
*/
|
||||||
@ -69,6 +75,11 @@ public class BusQuestionUserAnswer extends BaseEntity {
|
|||||||
*/
|
*/
|
||||||
private String file;
|
private String file;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 考试类型(1线上考试 2线下考试)
|
||||||
|
*/
|
||||||
|
private String examType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 删除时间
|
* 删除时间
|
||||||
*/
|
*/
|
||||||
@ -77,6 +88,7 @@ public class BusQuestionUserAnswer extends BaseEntity {
|
|||||||
/**
|
/**
|
||||||
* 是否删除(0正常 1删除)
|
* 是否删除(0正常 1删除)
|
||||||
*/
|
*/
|
||||||
|
@TableLogic
|
||||||
private Long isDelete;
|
private Long isDelete;
|
||||||
|
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
}
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -24,7 +24,7 @@ public class QuestionBankCreateReq implements Serializable {
|
|||||||
/**
|
/**
|
||||||
* 题目类别
|
* 题目类别
|
||||||
*/
|
*/
|
||||||
private String categoryType;
|
private Long categoryId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 题目类型
|
* 题目类型
|
||||||
|
@ -29,7 +29,7 @@ public class QuestionBankQueryReq implements Serializable {
|
|||||||
/**
|
/**
|
||||||
* 题目类别
|
* 题目类别
|
||||||
*/
|
*/
|
||||||
private String categoryType;
|
private Long categoryId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 题目类型
|
* 题目类型
|
||||||
|
@ -24,7 +24,7 @@ public class QuestionBankUpdateReq implements Serializable {
|
|||||||
/**
|
/**
|
||||||
* 题目类别
|
* 题目类别
|
||||||
*/
|
*/
|
||||||
private String categoryType;
|
private Long categoryId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 题目类型
|
* 题目类型
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
}
|
@ -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;
|
||||||
|
|
||||||
|
}
|
@ -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;
|
||||||
|
|
||||||
|
}
|
@ -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<Long> userIdList;
|
||||||
|
|
||||||
|
}
|
@ -4,7 +4,6 @@ import lombok.Data;
|
|||||||
|
|
||||||
import java.io.Serial;
|
import java.io.Serial;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author lcj
|
* @author lcj
|
||||||
@ -16,43 +15,19 @@ public class QuestionUserAnswerQueryReq implements Serializable {
|
|||||||
@Serial
|
@Serial
|
||||||
private static final long serialVersionUID = -7056242109124074218L;
|
private static final long serialVersionUID = -7056242109124074218L;
|
||||||
|
|
||||||
/**
|
|
||||||
* 主键id
|
|
||||||
*/
|
|
||||||
private Long id;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 项目id
|
* 项目id
|
||||||
*/
|
*/
|
||||||
private Long projectId;
|
private Long projectId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用户id
|
* 用户名
|
||||||
*/
|
*/
|
||||||
private Long userId;
|
private String userName;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 题库id列表
|
* 班组id
|
||||||
*/
|
*/
|
||||||
private List<Long> bankIdList;
|
private Long teamId;
|
||||||
|
|
||||||
/**
|
|
||||||
* 答案列表
|
|
||||||
*/
|
|
||||||
private List<String> answerList;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 得分
|
|
||||||
*/
|
|
||||||
private Long score;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 用时时间(时间戳/秒)
|
|
||||||
*/
|
|
||||||
private Long takeTime;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 及格线/总分(格式:60,100)
|
|
||||||
*/
|
|
||||||
private String pass;
|
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
}
|
@ -10,6 +10,7 @@ import org.dromara.safety.domain.BusQuestionBank;
|
|||||||
|
|
||||||
import java.io.Serial;
|
import java.io.Serial;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
|
||||||
@ -40,11 +41,15 @@ public class BusQuestionBankVo implements Serializable {
|
|||||||
private Long projectId;
|
private Long projectId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 题目类别
|
* 题目类别id
|
||||||
*/
|
*/
|
||||||
@ExcelProperty(value = "题目类别", converter = ExcelDictConvert.class)
|
private Long categoryId;
|
||||||
@ExcelDictFormat(dictType = "safety_question_category_type")
|
|
||||||
private String categoryType;
|
/**
|
||||||
|
* 题目类别名称
|
||||||
|
*/
|
||||||
|
@ExcelProperty(value = "题目类别名称")
|
||||||
|
private String categoryName;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 题目类型
|
* 题目类型
|
||||||
@ -71,5 +76,9 @@ public class BusQuestionBankVo implements Serializable {
|
|||||||
@ExcelProperty(value = "正确答案")
|
@ExcelProperty(value = "正确答案")
|
||||||
private String correctAnswer;
|
private String correctAnswer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建时间
|
||||||
|
*/
|
||||||
|
private Date createTime;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,7 @@ import org.dromara.safety.domain.BusQuestionUserAnswer;
|
|||||||
|
|
||||||
import java.io.Serial;
|
import java.io.Serial;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
|
||||||
@ -30,13 +31,11 @@ public class BusQuestionUserAnswerVo implements Serializable {
|
|||||||
/**
|
/**
|
||||||
* 主键id
|
* 主键id
|
||||||
*/
|
*/
|
||||||
@ExcelProperty(value = "主键id")
|
|
||||||
private Long id;
|
private Long id;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 项目id
|
* 项目id
|
||||||
*/
|
*/
|
||||||
@ExcelProperty(value = "项目id")
|
|
||||||
private Long projectId;
|
private Long projectId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -45,6 +44,12 @@ public class BusQuestionUserAnswerVo implements Serializable {
|
|||||||
@ExcelProperty(value = "用户id")
|
@ExcelProperty(value = "用户id")
|
||||||
private Long userId;
|
private Long userId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户名称
|
||||||
|
*/
|
||||||
|
@ExcelProperty(value = "用户名称")
|
||||||
|
private String userName;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 题库id列表
|
* 题库id列表
|
||||||
*/
|
*/
|
||||||
@ -63,11 +68,16 @@ public class BusQuestionUserAnswerVo implements Serializable {
|
|||||||
@ExcelProperty(value = "得分")
|
@ExcelProperty(value = "得分")
|
||||||
private Long score;
|
private Long score;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 考试时间(时间戳/秒)
|
||||||
|
*/
|
||||||
|
@ExcelProperty(value = "考试时间")
|
||||||
|
private Long examTime;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用时时间(时间戳/秒)
|
* 用时时间(时间戳/秒)
|
||||||
*/
|
*/
|
||||||
@ExcelProperty(value = "用时时间", converter = ExcelDictConvert.class)
|
@ExcelProperty(value = "用时时间")
|
||||||
@ExcelDictFormat(readConverterExp = "时=间戳/秒")
|
|
||||||
private Long takeTime;
|
private Long takeTime;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -82,5 +92,22 @@ public class BusQuestionUserAnswerVo implements Serializable {
|
|||||||
@ExcelProperty(value = "文件地址")
|
@ExcelProperty(value = "文件地址")
|
||||||
private String file;
|
private String file;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件地址列表
|
||||||
|
*/
|
||||||
|
private List<String> fileUrl;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 考试类型
|
||||||
|
*/
|
||||||
|
@ExcelProperty(value = "考试类型", converter = ExcelDictConvert.class)
|
||||||
|
@ExcelDictFormat(dictType = "user_exam_type")
|
||||||
|
private String examType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建时间
|
||||||
|
*/
|
||||||
|
@ExcelProperty(value = "创建时间")
|
||||||
|
private Date createTime;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
}
|
@ -36,8 +36,7 @@ public class BusSafetyInspectionVo implements Serializable {
|
|||||||
/**
|
/**
|
||||||
* 父id(默认为0)
|
* 父id(默认为0)
|
||||||
*/
|
*/
|
||||||
@ExcelProperty(value = "父id", converter = ExcelDictConvert.class)
|
@ExcelProperty(value = "父id")
|
||||||
@ExcelDictFormat(readConverterExp = "默=认为0")
|
|
||||||
private Long pid;
|
private Long pid;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -80,8 +79,7 @@ public class BusSafetyInspectionVo implements Serializable {
|
|||||||
/**
|
/**
|
||||||
* 整改人(班组长)id
|
* 整改人(班组长)id
|
||||||
*/
|
*/
|
||||||
@ExcelProperty(value = "整改人", converter = ExcelDictConvert.class)
|
@ExcelProperty(value = "整改人")
|
||||||
@ExcelDictFormat(readConverterExp = "班=组长")
|
|
||||||
private Long correctorId;
|
private Long correctorId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -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<BusQuestionsCategory, BusQuestionsCategoryVo> {
|
||||||
|
|
||||||
|
}
|
@ -3,13 +3,16 @@ package org.dromara.safety.service;
|
|||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import com.baomidou.mybatisplus.extension.service.IService;
|
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.PageQuery;
|
||||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||||
import org.dromara.safety.domain.BusQuestionUserAnswer;
|
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.QuestionUserAnswerCreateReq;
|
||||||
import org.dromara.safety.domain.req.questionuseranswer.QuestionUserAnswerQueryReq;
|
import org.dromara.safety.domain.req.questionuseranswer.QuestionUserAnswerQueryReq;
|
||||||
import org.dromara.safety.domain.req.questionuseranswer.QuestionUserAnswerUpdateReq;
|
import org.dromara.safety.domain.req.questionuseranswer.QuestionUserAnswerUpdateReq;
|
||||||
import org.dromara.safety.domain.vo.BusQuestionUserAnswerVo;
|
import org.dromara.safety.domain.vo.BusQuestionUserAnswerVo;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -55,6 +58,15 @@ public interface IBusQuestionUserAnswerService extends IService<BusQuestionUserA
|
|||||||
*/
|
*/
|
||||||
Long insertByBo(QuestionUserAnswerCreateReq req);
|
Long insertByBo(QuestionUserAnswerCreateReq req);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过zip文件批量上传用户试卷存储
|
||||||
|
*
|
||||||
|
* @param multipartFile zip文件
|
||||||
|
* @param projectId 项目id
|
||||||
|
* @return 是否上传成功
|
||||||
|
*/
|
||||||
|
Boolean batchUploadFileByZip(MultipartFile multipartFile, Long projectId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 修改用户试卷存储
|
* 修改用户试卷存储
|
||||||
*
|
*
|
||||||
@ -95,4 +107,13 @@ public interface IBusQuestionUserAnswerService extends IService<BusQuestionUserA
|
|||||||
* @return 用户试卷存储分页对象视图
|
* @return 用户试卷存储分页对象视图
|
||||||
*/
|
*/
|
||||||
Page<BusQuestionUserAnswerVo> getVoPage(Page<BusQuestionUserAnswer> questionUserAnswerPage);
|
Page<BusQuestionUserAnswerVo> getVoPage(Page<BusQuestionUserAnswer> questionUserAnswerPage);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量下载用户试卷存储文件
|
||||||
|
*
|
||||||
|
* @param req 用户试卷存储文件下载请求
|
||||||
|
* @param response 设置响应头和向客户端发送文件内容
|
||||||
|
*/
|
||||||
|
void batchDownloadFile(QuestionUserAnswerBatchDownloadFileReq req, HttpServletResponse response);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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<BusQuestionsCategory> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询题库类别
|
||||||
|
*
|
||||||
|
* @param id 主键
|
||||||
|
* @return 题库类别
|
||||||
|
*/
|
||||||
|
BusQuestionsCategoryVo queryById(Long id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页查询题库类别列表
|
||||||
|
*
|
||||||
|
* @param req 查询条件
|
||||||
|
* @param pageQuery 分页参数
|
||||||
|
* @return 题库类别分页列表
|
||||||
|
*/
|
||||||
|
TableDataInfo<BusQuestionsCategoryVo> queryPageList(QuestionsCategoryQueryReq req, PageQuery pageQuery);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询符合条件的题库类别列表
|
||||||
|
*
|
||||||
|
* @param req 查询条件
|
||||||
|
* @return 题库类别列表
|
||||||
|
*/
|
||||||
|
List<BusQuestionsCategoryVo> 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<Long> ids, Boolean isValid);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取题库类别视图对象
|
||||||
|
*
|
||||||
|
* @param questionsCategory 题库类别对象
|
||||||
|
* @return 题库类别视图对象
|
||||||
|
*/
|
||||||
|
BusQuestionsCategoryVo getVo(BusQuestionsCategory questionsCategory);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取题库类别查询条件封装
|
||||||
|
*
|
||||||
|
* @param req 题库类别查询条件
|
||||||
|
* @return 题库类别查询条件封装
|
||||||
|
*/
|
||||||
|
LambdaQueryWrapper<BusQuestionsCategory> buildQueryWrapper(QuestionsCategoryQueryReq req);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取题库类别分页对象视图
|
||||||
|
*
|
||||||
|
* @param questionsCategoryPage 题库类别分页对象
|
||||||
|
* @return 题库类别分页对象视图
|
||||||
|
*/
|
||||||
|
Page<BusQuestionsCategoryVo> getVoPage(Page<BusQuestionsCategory> questionsCategoryPage);
|
||||||
|
|
||||||
|
}
|
@ -18,18 +18,23 @@ import org.dromara.common.redis.utils.RedisUtils;
|
|||||||
import org.dromara.common.satoken.utils.LoginHelper;
|
import org.dromara.common.satoken.utils.LoginHelper;
|
||||||
import org.dromara.project.service.IBusProjectService;
|
import org.dromara.project.service.IBusProjectService;
|
||||||
import org.dromara.safety.domain.BusQuestionBank;
|
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.QuestionBankCreateReq;
|
||||||
import org.dromara.safety.domain.req.questionbank.QuestionBankQueryReq;
|
import org.dromara.safety.domain.req.questionbank.QuestionBankQueryReq;
|
||||||
import org.dromara.safety.domain.req.questionbank.QuestionBankUpdateReq;
|
import org.dromara.safety.domain.req.questionbank.QuestionBankUpdateReq;
|
||||||
import org.dromara.safety.domain.vo.BusQuestionBankVo;
|
import org.dromara.safety.domain.vo.BusQuestionBankVo;
|
||||||
import org.dromara.safety.mapper.BusQuestionBankMapper;
|
import org.dromara.safety.mapper.BusQuestionBankMapper;
|
||||||
import org.dromara.safety.service.IBusQuestionBankService;
|
import org.dromara.safety.service.IBusQuestionBankService;
|
||||||
|
import org.dromara.safety.service.IBusQuestionsCategoryService;
|
||||||
import org.springframework.beans.BeanUtils;
|
import org.springframework.beans.BeanUtils;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 题库Service业务层处理
|
* 题库Service业务层处理
|
||||||
@ -44,6 +49,9 @@ public class BusQuestionBankServiceImpl extends ServiceImpl<BusQuestionBankMappe
|
|||||||
@Resource
|
@Resource
|
||||||
private IBusProjectService projectService;
|
private IBusProjectService projectService;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private IBusQuestionsCategoryService questionsCategoryService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询题库
|
* 查询题库
|
||||||
*
|
*
|
||||||
@ -137,12 +145,12 @@ public class BusQuestionBankServiceImpl extends ServiceImpl<BusQuestionBankMappe
|
|||||||
*/
|
*/
|
||||||
private void validEntityBeforeSave(BusQuestionBank entity, Boolean create) {
|
private void validEntityBeforeSave(BusQuestionBank entity, Boolean create) {
|
||||||
// TODO 做一些数据校验,如唯一约束
|
// TODO 做一些数据校验,如唯一约束
|
||||||
String categoryType = entity.getCategoryType();
|
Long categoryId = entity.getCategoryId();
|
||||||
String questionType = entity.getQuestionType();
|
String questionType = entity.getQuestionType();
|
||||||
String questionContent = entity.getQuestionContent();
|
String questionContent = entity.getQuestionContent();
|
||||||
Long projectId = entity.getProjectId();
|
Long projectId = entity.getProjectId();
|
||||||
if (create) {
|
if (create) {
|
||||||
if (StringUtils.isEmpty(categoryType)) {
|
if (categoryId == null) {
|
||||||
throw new ServiceException("分类类型不能为空", HttpStatus.BAD_REQUEST);
|
throw new ServiceException("分类类型不能为空", HttpStatus.BAD_REQUEST);
|
||||||
}
|
}
|
||||||
if (StringUtils.isEmpty(questionType)) {
|
if (StringUtils.isEmpty(questionType)) {
|
||||||
@ -158,6 +166,9 @@ public class BusQuestionBankServiceImpl extends ServiceImpl<BusQuestionBankMappe
|
|||||||
if (projectId != null && projectService.getById(projectId) == null) {
|
if (projectId != null && projectService.getById(projectId) == null) {
|
||||||
throw new ServiceException("对应项目不存在", HttpStatus.NOT_FOUND);
|
throw new ServiceException("对应项目不存在", HttpStatus.NOT_FOUND);
|
||||||
}
|
}
|
||||||
|
if (categoryId != null && questionsCategoryService.getById(categoryId) == null) {
|
||||||
|
throw new ServiceException("对应题目分类类型不存在", HttpStatus.NOT_FOUND);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -194,6 +205,12 @@ public class BusQuestionBankServiceImpl extends ServiceImpl<BusQuestionBankMappe
|
|||||||
return questionBankVo;
|
return questionBankVo;
|
||||||
}
|
}
|
||||||
BeanUtils.copyProperties(questionBank, questionBankVo);
|
BeanUtils.copyProperties(questionBank, questionBankVo);
|
||||||
|
// 获取题目分类名称
|
||||||
|
Long categoryId = questionBank.getCategoryId();
|
||||||
|
BusQuestionsCategory category = questionsCategoryService.getById(categoryId);
|
||||||
|
if (category != null) {
|
||||||
|
questionBankVo.setCategoryName(category.getCategoryName());
|
||||||
|
}
|
||||||
return questionBankVo;
|
return questionBankVo;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -211,7 +228,7 @@ public class BusQuestionBankServiceImpl extends ServiceImpl<BusQuestionBankMappe
|
|||||||
}
|
}
|
||||||
Long id = req.getId();
|
Long id = req.getId();
|
||||||
Long projectId = req.getProjectId();
|
Long projectId = req.getProjectId();
|
||||||
String categoryType = req.getCategoryType();
|
Long categoryId = req.getCategoryId();
|
||||||
String questionType = req.getQuestionType();
|
String questionType = req.getQuestionType();
|
||||||
String questionContent = req.getQuestionContent();
|
String questionContent = req.getQuestionContent();
|
||||||
List<String> optionList = req.getOptionList();
|
List<String> optionList = req.getOptionList();
|
||||||
@ -228,7 +245,7 @@ public class BusQuestionBankServiceImpl extends ServiceImpl<BusQuestionBankMappe
|
|||||||
// 精准查询
|
// 精准查询
|
||||||
lqw.eq(ObjectUtils.isNotEmpty(id), BusQuestionBank::getId, id);
|
lqw.eq(ObjectUtils.isNotEmpty(id), BusQuestionBank::getId, id);
|
||||||
lqw.eq(ObjectUtils.isNotEmpty(projectId), BusQuestionBank::getProjectId, projectId);
|
lqw.eq(ObjectUtils.isNotEmpty(projectId), BusQuestionBank::getProjectId, projectId);
|
||||||
lqw.eq(StringUtils.isNotBlank(categoryType), BusQuestionBank::getCategoryType, categoryType);
|
lqw.eq(ObjectUtils.isNotEmpty(categoryId), BusQuestionBank::getCategoryId, categoryId);
|
||||||
lqw.eq(StringUtils.isNotBlank(questionType), BusQuestionBank::getQuestionType, questionType);
|
lqw.eq(StringUtils.isNotBlank(questionType), BusQuestionBank::getQuestionType, questionType);
|
||||||
return lqw;
|
return lqw;
|
||||||
}
|
}
|
||||||
@ -252,8 +269,26 @@ public class BusQuestionBankServiceImpl extends ServiceImpl<BusQuestionBankMappe
|
|||||||
if (CollUtil.isEmpty(questionBankList)) {
|
if (CollUtil.isEmpty(questionBankList)) {
|
||||||
return questionBankVoPage;
|
return questionBankVoPage;
|
||||||
}
|
}
|
||||||
|
// 关联查询题目分类信息
|
||||||
|
Set<Long> categoryIdList = questionBankList.stream().map(BusQuestionBank::getCategoryId)
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
Map<Long, List<BusQuestionsCategory>> questionCategoryMap = questionsCategoryService.listByIds(categoryIdList)
|
||||||
|
.stream().collect(Collectors.groupingBy(BusQuestionsCategory::getId));
|
||||||
// 对象列表 => 封装对象列表
|
// 对象列表 => 封装对象列表
|
||||||
List<BusQuestionBankVo> questionBankVoList = questionBankList.stream().map(this::getVo).toList();
|
List<BusQuestionBankVo> 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);
|
questionBankVoPage.setRecords(questionBankVoList);
|
||||||
return questionBankVoPage;
|
return questionBankVoPage;
|
||||||
}
|
}
|
||||||
|
@ -1,31 +1,55 @@
|
|||||||
package org.dromara.safety.service.impl;
|
package org.dromara.safety.service.impl;
|
||||||
|
|
||||||
import cn.hutool.core.collection.CollUtil;
|
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 cn.hutool.json.JSONUtil;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
import jakarta.annotation.Resource;
|
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.constant.HttpStatus;
|
||||||
import org.dromara.common.core.exception.ServiceException;
|
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.ObjectUtils;
|
||||||
import org.dromara.common.core.utils.StringUtils;
|
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.PageQuery;
|
||||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
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.IBusProjectService;
|
||||||
|
import org.dromara.project.service.IBusProjectTeamMemberService;
|
||||||
import org.dromara.safety.domain.BusQuestionUserAnswer;
|
import org.dromara.safety.domain.BusQuestionUserAnswer;
|
||||||
import org.dromara.safety.domain.req.questionuseranswer.QuestionUserAnswerCreateReq;
|
import org.dromara.safety.domain.enums.SafetyExamTypeEnum;
|
||||||
import org.dromara.safety.domain.req.questionuseranswer.QuestionUserAnswerQueryReq;
|
import org.dromara.safety.domain.req.questionuseranswer.*;
|
||||||
import org.dromara.safety.domain.req.questionuseranswer.QuestionUserAnswerUpdateReq;
|
|
||||||
import org.dromara.safety.domain.vo.BusQuestionUserAnswerVo;
|
import org.dromara.safety.domain.vo.BusQuestionUserAnswerVo;
|
||||||
import org.dromara.safety.mapper.BusQuestionUserAnswerMapper;
|
import org.dromara.safety.mapper.BusQuestionUserAnswerMapper;
|
||||||
import org.dromara.safety.service.IBusQuestionUserAnswerService;
|
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.beans.BeanUtils;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.io.File;
|
||||||
import java.util.List;
|
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业务层处理
|
* 用户试卷存储Service业务层处理
|
||||||
@ -33,6 +57,7 @@ import java.util.List;
|
|||||||
* @author lcj
|
* @author lcj
|
||||||
* @date 2025-03-24
|
* @date 2025-03-24
|
||||||
*/
|
*/
|
||||||
|
@Slf4j
|
||||||
@Service
|
@Service
|
||||||
public class BusQuestionUserAnswerServiceImpl extends ServiceImpl<BusQuestionUserAnswerMapper, BusQuestionUserAnswer>
|
public class BusQuestionUserAnswerServiceImpl extends ServiceImpl<BusQuestionUserAnswerMapper, BusQuestionUserAnswer>
|
||||||
implements IBusQuestionUserAnswerService {
|
implements IBusQuestionUserAnswerService {
|
||||||
@ -40,6 +65,15 @@ public class BusQuestionUserAnswerServiceImpl extends ServiceImpl<BusQuestionUse
|
|||||||
@Resource
|
@Resource
|
||||||
private IBusProjectService projectService;
|
private IBusProjectService projectService;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private ISysOssService ossService;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private IBusConstructionUserService constructionUserService;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private IBusProjectTeamMemberService projectTeamMemberService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询用户试卷存储
|
* 查询用户试卷存储
|
||||||
*
|
*
|
||||||
@ -112,6 +146,151 @@ public class BusQuestionUserAnswerServiceImpl extends ServiceImpl<BusQuestionUse
|
|||||||
return questionUserAnswer.getId();
|
return questionUserAnswer.getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过zip文件批量上传用户试卷存储
|
||||||
|
*
|
||||||
|
* @param multipartFile zip文件
|
||||||
|
* @return 是否上传成功
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public Boolean batchUploadFileByZip(MultipartFile multipartFile, Long projectId) {
|
||||||
|
// 1. 校验
|
||||||
|
String originalFilename = multipartFile.getOriginalFilename();
|
||||||
|
if (originalFilename == null) {
|
||||||
|
throw new ServiceException("文件名不存在", HttpStatus.BAD_REQUEST);
|
||||||
|
}
|
||||||
|
// 校验是否为压缩包zip格式
|
||||||
|
String suffix = FileUtil.getSuffix(originalFilename);
|
||||||
|
if (!suffix.equals("zip")) {
|
||||||
|
throw new ServiceException("请上传zip格式的文件", HttpStatus.BAD_REQUEST);
|
||||||
|
}
|
||||||
|
// 2. 临时存储文件路径
|
||||||
|
// 2.1 压缩包临时文件路径
|
||||||
|
File tempZipFile = null;
|
||||||
|
String randomStr = RandomUtil.randomString(16);
|
||||||
|
String tempZipFilePath = randomStr + "-" + originalFilename;
|
||||||
|
// 2.2 解压后的文件夹路径
|
||||||
|
File destDir = null;
|
||||||
|
String basePath = "unzip_path";
|
||||||
|
String destDirPath = String.format("%s/%s/%s/%s", basePath, DateUtils.getDate(), projectId, randomStr);
|
||||||
|
// 3. 构建临时存储对象
|
||||||
|
List<QuestionUserAnswerUploadTemp> 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<Long> 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<String> idCardList = tempList.stream().map(QuestionUserAnswerUploadTemp::getUserIdCard)
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
// 8.2 根据用户身份证列表查询用户信息
|
||||||
|
Map<String, List<BusConstructionUser>> userIdMap = constructionUserService.lambdaQuery()
|
||||||
|
.in(BusConstructionUser::getSfzNumber, idCardList).list()
|
||||||
|
.stream().collect(Collectors.groupingBy(BusConstructionUser::getSfzNumber));
|
||||||
|
// 8.3 遍历临时对象,构造用户试卷存储对象
|
||||||
|
List<BusQuestionUserAnswer> 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<BusQuestionUse
|
|||||||
return questionUserAnswerVo;
|
return questionUserAnswerVo;
|
||||||
}
|
}
|
||||||
BeanUtils.copyProperties(questionUserAnswer, questionUserAnswerVo);
|
BeanUtils.copyProperties(questionUserAnswer, questionUserAnswerVo);
|
||||||
|
// 获取用户试卷题库列表
|
||||||
String bankId = questionUserAnswer.getBankId();
|
String bankId = questionUserAnswer.getBankId();
|
||||||
if (StringUtils.isNotBlank(bankId)) {
|
if (StringUtils.isNotBlank(bankId)) {
|
||||||
questionUserAnswerVo.setBankIdList(JSONUtil.toList(bankId, Long.class));
|
questionUserAnswerVo.setBankIdList(JSONUtil.toList(bankId, Long.class));
|
||||||
}
|
}
|
||||||
|
// 获取用户试卷答案列表
|
||||||
String answer = questionUserAnswer.getAnswer();
|
String answer = questionUserAnswer.getAnswer();
|
||||||
if (StringUtils.isNotBlank(answer)) {
|
if (StringUtils.isNotBlank(answer)) {
|
||||||
questionUserAnswerVo.setAnswerList(JSONUtil.toList(answer, String.class));
|
questionUserAnswerVo.setAnswerList(JSONUtil.toList(answer, String.class));
|
||||||
}
|
}
|
||||||
|
// 获取用户姓名
|
||||||
|
Long userId = questionUserAnswer.getUserId();
|
||||||
|
if (userId != null) {
|
||||||
|
BusConstructionUser constructionUser = constructionUserService.getById(userId);
|
||||||
|
questionUserAnswerVo.setUserName(constructionUser.getUserName());
|
||||||
|
}
|
||||||
|
// 获取用户试卷文件地址
|
||||||
|
String file = questionUserAnswer.getFile();
|
||||||
|
if (StringUtils.isNotBlank(file)) {
|
||||||
|
List<Long> fileIdList = Arrays.stream(file.split(",")).map(Long::parseLong).toList();
|
||||||
|
List<String> fileUrlList = ossService.listByIds(fileIdList).stream().map(SysOssVo::getUrl).toList();
|
||||||
|
questionUserAnswerVo.setFileUrl(fileUrlList);
|
||||||
|
}
|
||||||
return questionUserAnswerVo;
|
return questionUserAnswerVo;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -213,33 +407,36 @@ public class BusQuestionUserAnswerServiceImpl extends ServiceImpl<BusQuestionUse
|
|||||||
if (req == null) {
|
if (req == null) {
|
||||||
return lqw;
|
return lqw;
|
||||||
}
|
}
|
||||||
Long id = req.getId();
|
|
||||||
Long projectId = req.getProjectId();
|
Long projectId = req.getProjectId();
|
||||||
Long userId = req.getUserId();
|
String userName = req.getUserName();
|
||||||
List<Long> bankIdList = req.getBankIdList();
|
Long teamId = req.getTeamId();
|
||||||
List<String> answerList = req.getAnswerList();
|
// 联表查询
|
||||||
Long score = req.getScore();
|
if (StringUtils.isNotBlank(userName)) {
|
||||||
Long takeTime = req.getTakeTime();
|
List<BusConstructionUser> constructionUserList = constructionUserService.lambdaQuery()
|
||||||
String pass = req.getPass();
|
.select(BusConstructionUser::getId)
|
||||||
// JSON 数组查询
|
.like(BusConstructionUser::getUserName, userName)
|
||||||
if (CollUtil.isNotEmpty(bankIdList)) {
|
.list();
|
||||||
for (Long bankId : bankIdList) {
|
if (CollUtil.isNotEmpty(constructionUserList)) {
|
||||||
lqw.like(BusQuestionUserAnswer::getBankId, "\"" + bankId + "\"");
|
List<Long> userIdList = constructionUserList.stream().map(BusConstructionUser::getId).toList();
|
||||||
|
lqw.in(BusQuestionUserAnswer::getUserId, userIdList);
|
||||||
|
} else {
|
||||||
|
lqw.eq(BusQuestionUserAnswer::getUserId, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (CollUtil.isNotEmpty(answerList)) {
|
if (ObjectUtils.isNotEmpty(teamId)) {
|
||||||
for (String answer : answerList) {
|
List<BusProjectTeamMember> projectTeamMemberList = projectTeamMemberService.lambdaQuery()
|
||||||
lqw.like(BusQuestionUserAnswer::getAnswer, "\"" + answer + "\"");
|
.select(BusProjectTeamMember::getMemberId)
|
||||||
|
.eq(BusProjectTeamMember::getTeamId, teamId)
|
||||||
|
.list();
|
||||||
|
if (CollUtil.isNotEmpty(projectTeamMemberList)) {
|
||||||
|
List<Long> 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(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;
|
return lqw;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -262,10 +459,123 @@ public class BusQuestionUserAnswerServiceImpl extends ServiceImpl<BusQuestionUse
|
|||||||
if (CollUtil.isEmpty(questionUserAnswerList)) {
|
if (CollUtil.isEmpty(questionUserAnswerList)) {
|
||||||
return questionUserAnswerVoPage;
|
return questionUserAnswerVoPage;
|
||||||
}
|
}
|
||||||
|
// 获取用户名
|
||||||
|
Set<Long> userIdList = questionUserAnswerList.stream().map(BusQuestionUserAnswer::getUserId).collect(Collectors.toSet());
|
||||||
|
List<BusConstructionUser> constructionUserList = constructionUserService.lambdaQuery()
|
||||||
|
.select(BusConstructionUser::getId, BusConstructionUser::getUserName)
|
||||||
|
.in(BusConstructionUser::getId, userIdList)
|
||||||
|
.list();
|
||||||
|
Map<Long, String> userNameMap = constructionUserList.stream()
|
||||||
|
.collect(Collectors.toMap(BusConstructionUser::getId, BusConstructionUser::getUserName));
|
||||||
|
// 获取用户文件
|
||||||
|
Set<Long> fileIdList = questionUserAnswerList.stream().map(BusQuestionUserAnswer::getFile).filter(StringUtils::isNotBlank)
|
||||||
|
.flatMap(fileId -> Arrays.stream(fileId.split(",")).map(Long::parseLong)).collect(Collectors.toSet());
|
||||||
|
Map<Long, List<SysOssVo>> ossMap = ossService.listByIds(fileIdList)
|
||||||
|
.stream().collect(Collectors.groupingBy(SysOssVo::getOssId));
|
||||||
// 对象列表 => 封装对象列表
|
// 对象列表 => 封装对象列表
|
||||||
List<BusQuestionUserAnswerVo> questionUserAnswerVoList = questionUserAnswerList.stream().map(this::getVo).toList();
|
List<BusQuestionUserAnswerVo> 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<Long> ossIdList = Arrays.stream(file.split(",")).map(Long::parseLong).toList();
|
||||||
|
List<String> 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);
|
questionUserAnswerVoPage.setRecords(questionUserAnswerVoList);
|
||||||
return questionUserAnswerVoPage;
|
return questionUserAnswerVoPage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量下载用户试卷存储文件
|
||||||
|
*
|
||||||
|
* @param req 用户试卷存储文件下载请求
|
||||||
|
* @param response 设置响应头和向客户端发送文件内容
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void batchDownloadFile(QuestionUserAnswerBatchDownloadFileReq req, HttpServletResponse response) {
|
||||||
|
// 获取用户试卷存储文件
|
||||||
|
List<Long> userIdList = req.getUserIdList();
|
||||||
|
List<BusQuestionUserAnswer> questionUserAnswerList = lambdaQuery()
|
||||||
|
.in(BusQuestionUserAnswer::getUserId, userIdList)
|
||||||
|
.list();
|
||||||
|
if (CollUtil.isEmpty(questionUserAnswerList)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 查询对应施工人员信息
|
||||||
|
Map<Long, List<BusConstructionUser>> 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<Long> ossIdList = Arrays.stream(file.split(",")).map(Long::parseLong).toList();
|
||||||
|
List<SysOssVo> 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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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<BusQuestionsCategoryMapper, BusQuestionsCategory>
|
||||||
|
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<BusQuestionsCategoryVo> queryPageList(QuestionsCategoryQueryReq req, PageQuery pageQuery) {
|
||||||
|
Page<BusQuestionsCategory> result = this.page(pageQuery.build(), buildQueryWrapper(req));
|
||||||
|
return TableDataInfo.build(this.getVoPage(result));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询符合条件的题库类别列表
|
||||||
|
*
|
||||||
|
* @param req 查询条件
|
||||||
|
* @return 题库类别列表
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public List<BusQuestionsCategoryVo> queryList(QuestionsCategoryQueryReq req) {
|
||||||
|
LambdaQueryWrapper<BusQuestionsCategory> 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<Long> ids, Boolean isValid) {
|
||||||
|
Long userId = LoginHelper.getUserId();
|
||||||
|
List<BusQuestionsCategory> questionsCategoryList = this.listByIds(ids);
|
||||||
|
if (isValid) {
|
||||||
|
// TODO 做一些业务上的校验,判断是否需要校验
|
||||||
|
List<Long> 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<BusQuestionsCategory> buildQueryWrapper(QuestionsCategoryQueryReq req) {
|
||||||
|
LambdaQueryWrapper<BusQuestionsCategory> 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<BusQuestionsCategoryVo> getVoPage(Page<BusQuestionsCategory> questionsCategoryPage) {
|
||||||
|
// 获取分页数据
|
||||||
|
List<BusQuestionsCategory> questionsCategoryList = questionsCategoryPage.getRecords();
|
||||||
|
// 添加分页信息
|
||||||
|
Page<BusQuestionsCategoryVo> questionsCategoryVoPage = new Page<>(
|
||||||
|
questionsCategoryPage.getCurrent(),
|
||||||
|
questionsCategoryPage.getSize(),
|
||||||
|
questionsCategoryPage.getTotal()
|
||||||
|
);
|
||||||
|
if (CollUtil.isEmpty(questionsCategoryList)) {
|
||||||
|
return questionsCategoryVoPage;
|
||||||
|
}
|
||||||
|
// 对象列表 => 封装对象列表
|
||||||
|
List<BusQuestionsCategoryVo> questionsCategoryVoList = questionsCategoryList.stream().map(this::getVo).toList();
|
||||||
|
questionsCategoryVoPage.setRecords(questionsCategoryVoList);
|
||||||
|
return questionsCategoryVoPage;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
<?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="org.dromara.safety.mapper.BusQuestionsCategoryMapper">
|
||||||
|
|
||||||
|
</mapper>
|
@ -678,3 +678,15 @@ CREATE TABLE `bus_document_safety_meeting`
|
|||||||
INDEX `idx_pid` (`pid` ASC) USING BTREE,
|
INDEX `idx_pid` (`pid` ASC) USING BTREE,
|
||||||
INDEX `idx_project_id` (`project_id` ASC) USING BTREE
|
INDEX `idx_project_id` (`project_id` ASC) USING BTREE
|
||||||
) comment = '安全会议纪要' COLLATE = utf8mb4_unicode_ci;
|
) 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;
|
||||||
|
Reference in New Issue
Block a user