From 65440ba12b9274c1a48220ffbc780102fce01bc5 Mon Sep 17 00:00:00 2001 From: luogw <3132758203@qq.com> Date: Sat, 7 Feb 2026 16:58:29 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AF=BC=E5=87=BA=E5=8A=9F=E8=83=BD=E5=BC=80?= =?UTF-8?q?=E5=8F=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 6 +++ .../appeal/application/AppealApplication.java | 8 +++- .../Impl/AppealApplicationImpl.java | 31 +++++++++++++- .../controller/AppealAdminController.java | 8 +++- .../appeal/controller/AppealController.java | 4 +- .../project/appeal/domain/dto/AppealDTO.java | 3 +- .../appeal/domain/dto/AppealExportDTO.java | 37 +++++++++++++++++ .../appeal/domain/entity/AppealEntity.java | 6 ++- .../Impl/CheckAppealDomainServiceImpl.java | 35 +++++++++++++--- .../Impl/SaveAppealDomainServiceImpl.java | 27 ++++++------- .../Impl/SearchAppealDomainServiceImpl.java | 13 +++++- .../service/SaveAppealDomainService.java | 3 +- .../advice/GlobalExceptionHandlerAdvice.java | 11 +++++ .../project/base/domain/utils/ExcelUtil.java | 40 +++++++++++++++++++ .../application/UserApplicationService.java | 2 +- .../impl/UserApplicationServiceImpl.java | 2 +- .../ding/controller/UserController.java | 2 +- .../service/SearchUserDomainService.java | 2 +- .../impl/SearchUserDomainServiceImpl.java | 2 +- .../java/com/project/ding/utils/DingUtil.java | 3 +- .../project/exam/mapper/ExamRecordMapper.java | 4 +- .../mapper/KnowledgePointMapper.java | 6 +-- .../information/mapper/ProductLineMapper.java | 18 +++++++++ .../OperationLogApplicationServiceImpl.java | 30 ++++++++++++++ .../impl/OperationLogApplicationService.java | 6 +++ .../controller/OperationLogController.java | 8 +++- .../domain/dto/OperationLogExportDTO.java | 29 ++++++++++++++ .../description/TaskDescriptionStrategy.java | 4 +- .../com/project/task/mapper/TaskMapper.java | 6 +-- 29 files changed, 304 insertions(+), 52 deletions(-) create mode 100644 src/main/java/com/project/appeal/domain/dto/AppealExportDTO.java create mode 100644 src/main/java/com/project/base/domain/utils/ExcelUtil.java create mode 100644 src/main/java/com/project/operation/domain/dto/OperationLogExportDTO.java diff --git a/pom.xml b/pom.xml index a5d0793..a527a70 100644 --- a/pom.xml +++ b/pom.xml @@ -217,6 +217,12 @@ compile + + com.alibaba + easyexcel + 3.3.4 + + diff --git a/src/main/java/com/project/appeal/application/AppealApplication.java b/src/main/java/com/project/appeal/application/AppealApplication.java index c564695..43cae4d 100644 --- a/src/main/java/com/project/appeal/application/AppealApplication.java +++ b/src/main/java/com/project/appeal/application/AppealApplication.java @@ -5,6 +5,7 @@ import com.project.appeal.domain.dto.AppealDTO; import com.project.appeal.domain.param.AppealParam; import com.project.base.domain.result.PageResult; import com.project.base.domain.result.Result; +import jakarta.servlet.http.HttpServletResponse; import java.util.List; @@ -12,10 +13,15 @@ public interface AppealApplication { /** * 保存或修改申诉 */ - Result saveOrUpdate(AppealDTO appealDTO) throws DtErrorException; + Result saveOrUpdate(AppealDTO appealDTO) throws Exception; /** * 查询申诉列表 */ Result> list(AppealParam appealParam); + + /** + * + */ + void export(AppealParam appealParam, HttpServletResponse response); } diff --git a/src/main/java/com/project/appeal/application/Impl/AppealApplicationImpl.java b/src/main/java/com/project/appeal/application/Impl/AppealApplicationImpl.java index 1129ea7..44af58f 100644 --- a/src/main/java/com/project/appeal/application/Impl/AppealApplicationImpl.java +++ b/src/main/java/com/project/appeal/application/Impl/AppealApplicationImpl.java @@ -1,18 +1,22 @@ package com.project.appeal.application.Impl; -import com.github.tingyugetc520.ali.dingtalk.error.DtErrorException; import com.project.appeal.application.AppealApplication; import com.project.appeal.domain.dto.AppealDTO; +import com.project.appeal.domain.dto.AppealExportDTO; import com.project.appeal.domain.param.AppealParam; import com.project.appeal.domain.service.CheckAppealDomainService; import com.project.appeal.domain.service.SaveAppealDomainService; import com.project.appeal.domain.service.SearchAppealDomainService; +import com.project.base.domain.exception.BusinessErrorException; import com.project.base.domain.result.PageResult; import com.project.base.domain.result.Result; +import com.project.base.domain.utils.ExcelUtil; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; +import java.util.stream.Collectors; @Service public class AppealApplicationImpl implements AppealApplication { @@ -23,11 +27,16 @@ public class AppealApplicationImpl implements AppealApplication { @Autowired private SearchAppealDomainService searchAppealDomainService; + private static final String SHEET_NAME = "申诉审批数据"; + private static final String EXCEL_FILENAME = "appeal"; + private static final Integer PAGE_MAX_SIZE = 5001; + private static final Integer PAGE_DEFAULT_CURRENT = 1; + /** * 保存申诉 */ @Override - public Result saveOrUpdate(AppealDTO appealDTO) throws DtErrorException { + public Result saveOrUpdate(AppealDTO appealDTO) throws Exception { checkAppealDomainService.checkDto(appealDTO); return saveAppealDomainService.saveOrUpdate(appealDTO); } @@ -39,4 +48,22 @@ public class AppealApplicationImpl implements AppealApplication { public Result> list(AppealParam appealParam) { return searchAppealDomainService.list(appealParam); } + + /** + * 申诉导出 + */ + @Override + public void export(AppealParam param, HttpServletResponse response) { + //获取申诉列表 + param.setSize(PAGE_MAX_SIZE); + param.setCurrent(PAGE_DEFAULT_CURRENT); + List appealExportDTOList = searchAppealDomainService.list(param).getData().getContent() + .stream().map(dto -> dto.toEntity(AppealExportDTO::new)).collect(Collectors.toList()); + if (appealExportDTOList.size() == PAGE_MAX_SIZE) { + throw new BusinessErrorException("最大条数限制5000条超过最大限制不允许导出"); + } + + ExcelUtil util = new ExcelUtil<>(); + util.exportExcel(response,appealExportDTOList,SHEET_NAME,EXCEL_FILENAME,AppealExportDTO.class); + } } diff --git a/src/main/java/com/project/appeal/controller/AppealAdminController.java b/src/main/java/com/project/appeal/controller/AppealAdminController.java index bed0a87..b5cbc20 100644 --- a/src/main/java/com/project/appeal/controller/AppealAdminController.java +++ b/src/main/java/com/project/appeal/controller/AppealAdminController.java @@ -7,6 +7,7 @@ import com.project.appeal.domain.param.AppealParam; import com.project.base.domain.result.PageResult; import com.project.base.domain.result.Result; import com.project.operation.annotation.OperationLog; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; @@ -21,7 +22,7 @@ public class AppealAdminController { @PostMapping("saveOrUpdate") @OperationLog(module = "申诉审批") - public Result saveOrUpdate(AppealDTO appealDTO) throws DtErrorException { + public Result saveOrUpdate(AppealDTO appealDTO) throws Exception { return appealApplication.saveOrUpdate(appealDTO); } @@ -29,4 +30,9 @@ public class AppealAdminController { public Result> list(AppealParam appealParam){ return appealApplication.list(appealParam); } + + @GetMapping("export") + public void export(AppealParam appealParam, HttpServletResponse response) throws DtErrorException { + appealApplication.export(appealParam,response); + } } diff --git a/src/main/java/com/project/appeal/controller/AppealController.java b/src/main/java/com/project/appeal/controller/AppealController.java index 7f8ee17..7c525e1 100644 --- a/src/main/java/com/project/appeal/controller/AppealController.java +++ b/src/main/java/com/project/appeal/controller/AppealController.java @@ -1,12 +1,10 @@ package com.project.appeal.controller; -import com.github.tingyugetc520.ali.dingtalk.error.DtErrorException; import com.project.appeal.application.AppealApplication; import com.project.appeal.domain.dto.AppealDTO; import com.project.base.domain.result.Result; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @@ -20,7 +18,7 @@ public class AppealController { private AppealApplication appealApplication; @PostMapping("saveOrUpdate") - public Result saveOrUpdate(@RequestBody AppealDTO appealDTO) throws DtErrorException { + public Result saveOrUpdate(AppealDTO appealDTO) throws Exception { return appealApplication.saveOrUpdate(appealDTO); } } diff --git a/src/main/java/com/project/appeal/domain/dto/AppealDTO.java b/src/main/java/com/project/appeal/domain/dto/AppealDTO.java index 6ba2dc1..bd06f35 100644 --- a/src/main/java/com/project/appeal/domain/dto/AppealDTO.java +++ b/src/main/java/com/project/appeal/domain/dto/AppealDTO.java @@ -21,7 +21,8 @@ public class AppealDTO extends BaseDTO { private Long id; private String userId; private String appealUserId; - private String userName; + private String username; + private String appealUsername; private Long examId; private Long taskId; private String subLineName;//关联子产品线 diff --git a/src/main/java/com/project/appeal/domain/dto/AppealExportDTO.java b/src/main/java/com/project/appeal/domain/dto/AppealExportDTO.java new file mode 100644 index 0000000..5b9d010 --- /dev/null +++ b/src/main/java/com/project/appeal/domain/dto/AppealExportDTO.java @@ -0,0 +1,37 @@ +package com.project.appeal.domain.dto; + +import com.alibaba.excel.annotation.ExcelProperty; +import com.alibaba.excel.annotation.format.DateTimeFormat; +import lombok.Data; + +import java.util.Date; + +@Data +public class AppealExportDTO{ + private Long id; + + @ExcelProperty("关联子产品线") + private String subLineName; + + @ExcelProperty("用户名") + private String username; + + @DateTimeFormat("yyyy-MM-dd HH:mm:ss") + @ExcelProperty(value = "操作时间") + private Date updateTime; + + @ExcelProperty("知识点") + private String kpContentsStr; + + @ExcelProperty("题目") + private String questionContent; + + @ExcelProperty("参考答案") + private String rightAnswer; + + @ExcelProperty("用户答案") + private String userAnswer; + + @ExcelProperty("申诉备注") + private String remark; +} diff --git a/src/main/java/com/project/appeal/domain/entity/AppealEntity.java b/src/main/java/com/project/appeal/domain/entity/AppealEntity.java index c4c613d..7e83537 100644 --- a/src/main/java/com/project/appeal/domain/entity/AppealEntity.java +++ b/src/main/java/com/project/appeal/domain/entity/AppealEntity.java @@ -33,6 +33,10 @@ public class AppealEntity extends BaseEntity { @Column(name = "appeal_user_id" , columnDefinition="varchar(50) comment '审批用户id'") private String appealUserId; + @TableField("appeal_username") + @Column(name = "appeal_username" , columnDefinition="varchar(50) comment '审批用户名称'") + private String appealUsername; + @TableField("exam_id") @Column(name = "exam_id" , columnDefinition="bigint(20) comment '考试id'") private Long examId; @@ -43,7 +47,7 @@ public class AppealEntity extends BaseEntity { @Column(name = "user_answer",columnDefinition = "varchar(255) comment '用户答案'") @TableField("user_answer") - private Long userAnswer; + private String userAnswer; @Column(name = "question_id") @Comment("题目ID") diff --git a/src/main/java/com/project/appeal/domain/service/Impl/CheckAppealDomainServiceImpl.java b/src/main/java/com/project/appeal/domain/service/Impl/CheckAppealDomainServiceImpl.java index c3634f0..3d4ac82 100644 --- a/src/main/java/com/project/appeal/domain/service/Impl/CheckAppealDomainServiceImpl.java +++ b/src/main/java/com/project/appeal/domain/service/Impl/CheckAppealDomainServiceImpl.java @@ -1,8 +1,11 @@ package com.project.appeal.domain.service.Impl; import cn.hutool.core.util.ObjectUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.project.appeal.domain.dto.AppealDTO; +import com.project.appeal.domain.entity.AppealEntity; import com.project.appeal.domain.enums.AppealStatusEnum; +import com.project.appeal.domain.service.AppealBaseService; import com.project.appeal.domain.service.CheckAppealDomainService; import com.project.base.domain.exception.BusinessErrorException; import com.project.base.domain.exception.MissingParameterException; @@ -10,24 +13,28 @@ import com.project.base.domain.exception.PermissionErrorException; import com.project.ding.domain.enums.UserRoleEnum; import com.project.ding.utils.SecurityUtils; import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; @Service public class CheckAppealDomainServiceImpl implements CheckAppealDomainService { + @Autowired + private AppealBaseService appealBaseService; + @Override public void checkDto(AppealDTO appealDTO) { - if (ObjectUtil.isEmpty(appealDTO.getExamId())){ + if (ObjectUtil.isEmpty(appealDTO.getId()) && ObjectUtil.isEmpty(appealDTO.getExamId())){ throw new MissingParameterException("缺少考试ID"); } - if (ObjectUtil.isEmpty(appealDTO.getQuestionContent())){ + if (ObjectUtil.isEmpty(appealDTO.getId()) && ObjectUtil.isEmpty(appealDTO.getQuestionId())){ throw new MissingParameterException("缺少题目ID"); } - if (StringUtils.isBlank(appealDTO.getUserAnswer())){ + if (ObjectUtil.isEmpty(appealDTO.getId()) && StringUtils.isBlank(appealDTO.getUserAnswer())){ throw new MissingParameterException("缺少用户答案"); } - if (StringUtils.isBlank(appealDTO.getRemark())){ + if (ObjectUtil.isEmpty(appealDTO.getId()) && StringUtils.isBlank(appealDTO.getRemark())){ throw new MissingParameterException("缺少申诉理由"); } if (ObjectUtil.isEmpty(appealDTO.getId()) && !appealDTO.getStatus().equals(AppealStatusEnum.PENDING_REVIEW.getValue())){ @@ -39,11 +46,29 @@ public class CheckAppealDomainServiceImpl implements CheckAppealDomainService { if (!appealDTO.getStatus().equals(AppealStatusEnum.PENDING_REVIEW.getValue()) && StringUtils.isBlank(appealDTO.getReason())){ throw new BusinessErrorException("缺少审批意见"); } + //校验题目是否以申诉过 + if (ObjectUtil.isEmpty(appealDTO.getId()) ){ + QueryWrapper entityQueryWrapper = new QueryWrapper<>(); + entityQueryWrapper.eq("exam_id", appealDTO.getExamId()); + entityQueryWrapper.eq("question_id", appealDTO.getQuestionId()); + AppealEntity appeal = appealBaseService.getOne(entityQueryWrapper); + if(appeal != null){ + throw new BusinessErrorException("题目已申诉"); + } + } + + //校验当前数据是否以审批 + if (ObjectUtil.isNotEmpty(appealDTO.getId())){ + AppealEntity entity = appealBaseService.getById(appealDTO.getId()); + if (!entity.getStatus().equals(AppealStatusEnum.PENDING_REVIEW.getValue())){ + throw new BusinessErrorException("题目已审批"); + } + } //权限校验 if (ObjectUtil.isNotEmpty(appealDTO.getId()) && !appealDTO.getStatus().equals(AppealStatusEnum.PENDING_REVIEW.getValue())){ //校验权限 List userRoles = SecurityUtils.getUserRoles(); - if(! userRoles.stream().anyMatch(UserRoleEnum.ROLE_ADMIN::equals)){ + if(!userRoles.stream().anyMatch(UserRoleEnum.ROLE_ADMIN.name()::equals)){ throw new PermissionErrorException(); } } diff --git a/src/main/java/com/project/appeal/domain/service/Impl/SaveAppealDomainServiceImpl.java b/src/main/java/com/project/appeal/domain/service/Impl/SaveAppealDomainServiceImpl.java index a5639d8..60d982d 100644 --- a/src/main/java/com/project/appeal/domain/service/Impl/SaveAppealDomainServiceImpl.java +++ b/src/main/java/com/project/appeal/domain/service/Impl/SaveAppealDomainServiceImpl.java @@ -1,8 +1,6 @@ package com.project.appeal.domain.service.Impl; -import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; -import com.github.tingyugetc520.ali.dingtalk.error.DtErrorException; import com.project.appeal.domain.dto.AppealDTO; import com.project.appeal.domain.entity.AppealEntity; import com.project.appeal.domain.enums.AppealStatusEnum; @@ -10,6 +8,7 @@ import com.project.appeal.domain.service.AppealBaseService; import com.project.appeal.domain.service.SaveAppealDomainService; import com.project.base.domain.exception.BusinessErrorException; import com.project.base.domain.result.Result; +import com.project.ding.application.UserApplicationService; import com.project.ding.domain.dto.UserDTO; import com.project.ding.utils.DingUtil; import com.project.ding.utils.SecurityUtils; @@ -28,12 +27,15 @@ import org.springframework.transaction.annotation.Transactional; import java.math.BigDecimal; import java.math.RoundingMode; import java.util.List; +import java.util.Objects; @Service public class SaveAppealDomainServiceImpl implements SaveAppealDomainService { @Autowired private AppealBaseService appealBaseService; @Autowired + private UserApplicationService userApplicationService; + @Autowired private ExamRecordMapper examRecordMapper; @Autowired private TaskUserMapper taskUserMapper; @@ -45,17 +47,19 @@ public class SaveAppealDomainServiceImpl implements SaveAppealDomainService { @Override @Transactional(rollbackFor = BusinessErrorException.class) - public Result saveOrUpdate(AppealDTO appealDTO) throws DtErrorException { + public Result saveOrUpdate(AppealDTO appealDTO) throws Exception { AppealEntity entity = appealDTO.toEntity(AppealEntity::new); //设置审批人 if (!appealDTO.getStatus().equals(AppealStatusEnum.PENDING_REVIEW.getValue())){ - appealDTO.setAppealUserId(SecurityUtils.getUserId()); + entity.setAppealUserId(SecurityUtils.getUserId()); + UserDTO user = userApplicationService.getDetail(SecurityUtils.getUserId()).getData(); + entity.setAppealUsername(user.getName()); }else{ //设置申诉人 - appealDTO.setAppealUserId(SecurityUtils.getUserId()); - UserDTO user = dingUtil.getUserById(SecurityUtils.getUserId()); - appealDTO.setUserName(user.getName()); + entity.setUserId(SecurityUtils.getUserId()); + UserDTO user = userApplicationService.getDetail(SecurityUtils.getUserId()).getData(); + entity.setUsername(user.getName()); } appealBaseService.saveOrUpdate(entity); @@ -69,6 +73,7 @@ public class SaveAppealDomainServiceImpl implements SaveAppealDomainService { return Result.success(appealDTO); } + appealDTO = appealBaseService.getById(appealDTO.getId()).toDTO(AppealDTO::new); ExamRecordEntity examRecord = examRecordMapper.selectById(appealDTO.getExamId()); if (examRecord == null){ throw new BusinessErrorException("用户未该场考试"); @@ -81,8 +86,7 @@ public class SaveAppealDomainServiceImpl implements SaveAppealDomainService { int index = -1; for (int i = 0; i < answerSnapshotDTOList.size(); i++) { ExamRecordDTO.QuestionSnapshotDTO dto = answerSnapshotDTOList.get(i); - if (appealDTO.getQuestionId() != null - && appealDTO.getQuestionId().equals(dto.getQuestionId())) { + if (Objects.equals(appealDTO.getQuestionId(), dto.getQuestionId())) { index = i; break; } @@ -94,11 +98,6 @@ public class SaveAppealDomainServiceImpl implements SaveAppealDomainService { throw new BusinessErrorException("题目不存在"); } - //已申诉题目无法再申诉 - if(questionSnapshotDTO.getHasAppealed()){ - throw new BusinessErrorException("题目已申诉"); - } - TaskEntity taskEntity = taskMapper.getTaskByTaskUserId(examRecord.getTaskUserId()); QuestionTypeEnum questionType = QuestionTypeEnum.findByValue(questionSnapshotDTO.getType()); diff --git a/src/main/java/com/project/appeal/domain/service/Impl/SearchAppealDomainServiceImpl.java b/src/main/java/com/project/appeal/domain/service/Impl/SearchAppealDomainServiceImpl.java index 08f9a12..abf0ccc 100644 --- a/src/main/java/com/project/appeal/domain/service/Impl/SearchAppealDomainServiceImpl.java +++ b/src/main/java/com/project/appeal/domain/service/Impl/SearchAppealDomainServiceImpl.java @@ -13,6 +13,7 @@ import com.project.base.domain.result.Result; import com.project.base.domain.utils.PageConverter; import com.project.information.domain.entity.KnowledgePointEntity; import com.project.information.domain.service.KnowledgePointBaseService; +import com.project.information.mapper.ProductLineMapper; import com.project.question.domain.entity.QuestionEntity; import com.project.question.domain.service.QuestionBaseService; import com.project.task.domain.dto.TaskDTO; @@ -36,6 +37,8 @@ public class SearchAppealDomainServiceImpl implements SearchAppealDomainService private TaskMapper taskMapper; @Autowired private KnowledgePointBaseService knowledgePointBaseService; + @Autowired + private ProductLineMapper productLineMapper; @Override public Result> list(AppealParam appealParam) { @@ -45,13 +48,21 @@ public class SearchAppealDomainServiceImpl implements SearchAppealDomainService if (StringUtils.isBlank(appealParam.getSubLineName())){ Page appealEntityPage = appealMapper.selectPage(PageConverter.toMpPage(appealParam), appealEntityQueryWrapper); appealDTOIPage = appealEntityPage.convert(entity -> entity.toDTO(AppealDTO::new)); + + //查询产品线相关的考试任务 + Set taskIdSet = appealDTOIPage.getRecords().stream().map(appealDTO -> appealDTO.getTaskId()).collect(Collectors.toSet()); + if (!CollectionUtils.isEmpty(taskIdSet)){ + List taskByIds = productLineMapper.getSubLineByTaskIDS(taskIdSet); + taskIdToSubLineNameMap = taskByIds.stream().collect(Collectors.toMap(TaskDTO::getId, TaskDTO::getSubLineName)); + } }else{ //查询产品线相关的考试任务 List taskBySubLineName = taskMapper.getTaskBySubLineName(appealParam.getSubLineName()); - taskIdToSubLineNameMap = taskBySubLineName.stream().collect(Collectors.toMap(TaskDTO::getId, TaskDTO::getName)); + taskIdToSubLineNameMap = taskBySubLineName.stream().collect(Collectors.toMap(TaskDTO::getId, TaskDTO::getSubLineName)); //查询申诉列表 appealEntityQueryWrapper.in("task_id",taskBySubLineName.stream().map(TaskDTO::getId).collect(Collectors.toList())); + appealEntityQueryWrapper.orderByDesc("update_time"); Page appealEntityPage = appealMapper.selectPage(PageConverter.toMpPage(appealParam), appealEntityQueryWrapper); appealDTOIPage = appealEntityPage.convert(entity -> entity.toDTO(AppealDTO::new)); } diff --git a/src/main/java/com/project/appeal/domain/service/SaveAppealDomainService.java b/src/main/java/com/project/appeal/domain/service/SaveAppealDomainService.java index a2b78ab..94bddf6 100644 --- a/src/main/java/com/project/appeal/domain/service/SaveAppealDomainService.java +++ b/src/main/java/com/project/appeal/domain/service/SaveAppealDomainService.java @@ -1,9 +1,8 @@ package com.project.appeal.domain.service; -import com.github.tingyugetc520.ali.dingtalk.error.DtErrorException; import com.project.appeal.domain.dto.AppealDTO; import com.project.base.domain.result.Result; public interface SaveAppealDomainService { - Result saveOrUpdate(AppealDTO appealDTO) throws DtErrorException; + Result saveOrUpdate(AppealDTO appealDTO) throws Exception; } diff --git a/src/main/java/com/project/base/domain/advice/GlobalExceptionHandlerAdvice.java b/src/main/java/com/project/base/domain/advice/GlobalExceptionHandlerAdvice.java index e7793e9..052cae1 100644 --- a/src/main/java/com/project/base/domain/advice/GlobalExceptionHandlerAdvice.java +++ b/src/main/java/com/project/base/domain/advice/GlobalExceptionHandlerAdvice.java @@ -3,6 +3,7 @@ package com.project.base.domain.advice; import com.project.base.domain.exception.BusinessErrorException; import com.project.base.domain.exception.MissingParameterException; +import com.project.base.domain.exception.PermissionErrorException; import com.project.base.domain.exception.ResourceNotExistException; import com.project.base.domain.result.Result; import com.project.base.domain.result.ResultCodeEnum; @@ -60,6 +61,16 @@ public class GlobalExceptionHandlerAdvice { return Result.fail(ResultCodeEnum.BUSINESS_ERROR , e.getMessage()); } + /**-------- 权限错误 --------**/ + @ExceptionHandler(PermissionErrorException.class) + @ResponseBody + @ResponseStatus(HttpStatus.OK) + public Result error(PermissionErrorException e) { + e.printStackTrace(); + log.error("全局异常捕获:" + e); + return Result.fail(ResultCodeEnum.PERMISSION_DENIED , e.getMessage()); + } + /**-------- 缺少必须参数 --------**/ @ExceptionHandler(MissingParameterException.class) @ResponseBody diff --git a/src/main/java/com/project/base/domain/utils/ExcelUtil.java b/src/main/java/com/project/base/domain/utils/ExcelUtil.java new file mode 100644 index 0000000..a1d5382 --- /dev/null +++ b/src/main/java/com/project/base/domain/utils/ExcelUtil.java @@ -0,0 +1,40 @@ +package com.project.base.domain.utils; + +import com.alibaba.excel.EasyExcel; +import org.springframework.util.CollectionUtils; + +import jakarta.servlet.http.HttpServletResponse; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.List; + + +public class ExcelUtil { + public void exportExcel(HttpServletResponse response, List list, String sheetName,String fileName,Class clazz) { + if (CollectionUtils.isEmpty(list)) { + list = new ArrayList<>(); + } + + try { + //设置响应头 + response.setContentType( + "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); + response.setCharacterEncoding("utf-8"); + + String encodeFileName = URLEncoder.encode(fileName, StandardCharsets.UTF_8); + response.setHeader( + "Content-Disposition", + "attachment;filename=" + encodeFileName + ".xlsx"); + + //写 Excel + EasyExcel.write(response.getOutputStream(), clazz) + .sheet(sheetName) + .doWrite(list); + + } catch (Exception e) { + throw new RuntimeException("导出 Excel 失败", e); + } + + } +} diff --git a/src/main/java/com/project/ding/application/UserApplicationService.java b/src/main/java/com/project/ding/application/UserApplicationService.java index 487bc5f..3580adb 100644 --- a/src/main/java/com/project/ding/application/UserApplicationService.java +++ b/src/main/java/com/project/ding/application/UserApplicationService.java @@ -12,7 +12,7 @@ public interface UserApplicationService { Result> search(UserParam param) throws Exception; - Result getDetail(Long id) throws Exception; + Result getDetail(String id) throws Exception; diff --git a/src/main/java/com/project/ding/application/impl/UserApplicationServiceImpl.java b/src/main/java/com/project/ding/application/impl/UserApplicationServiceImpl.java index 83c0739..df48cf2 100644 --- a/src/main/java/com/project/ding/application/impl/UserApplicationServiceImpl.java +++ b/src/main/java/com/project/ding/application/impl/UserApplicationServiceImpl.java @@ -28,7 +28,7 @@ public class UserApplicationServiceImpl implements UserApplicationService { } @Override - public Result getDetail(Long id) throws Exception { + public Result getDetail(String id) throws Exception { return searchUserDomainService.getDetail(id); } diff --git a/src/main/java/com/project/ding/controller/UserController.java b/src/main/java/com/project/ding/controller/UserController.java index b62571c..dcd2e24 100644 --- a/src/main/java/com/project/ding/controller/UserController.java +++ b/src/main/java/com/project/ding/controller/UserController.java @@ -30,7 +30,7 @@ public class UserController { } @GetMapping("/getDetail") - public Result getDetail(Long id) throws Exception { + public Result getDetail(String id) throws Exception { return userApplicationService.getDetail(id); } } diff --git a/src/main/java/com/project/ding/domain/service/SearchUserDomainService.java b/src/main/java/com/project/ding/domain/service/SearchUserDomainService.java index e97b828..2b0ed16 100644 --- a/src/main/java/com/project/ding/domain/service/SearchUserDomainService.java +++ b/src/main/java/com/project/ding/domain/service/SearchUserDomainService.java @@ -12,7 +12,7 @@ public interface SearchUserDomainService { Result> search(UserParam param) throws Exception; - Result getDetail(Long id) throws Exception; + Result getDetail(String id) throws Exception; List searchByIds(Set idSet); } diff --git a/src/main/java/com/project/ding/domain/service/impl/SearchUserDomainServiceImpl.java b/src/main/java/com/project/ding/domain/service/impl/SearchUserDomainServiceImpl.java index 924ac11..f8d1c7d 100644 --- a/src/main/java/com/project/ding/domain/service/impl/SearchUserDomainServiceImpl.java +++ b/src/main/java/com/project/ding/domain/service/impl/SearchUserDomainServiceImpl.java @@ -68,7 +68,7 @@ public class SearchUserDomainServiceImpl implements SearchUserDomainService { } @Override - public Result getDetail(Long id) throws Exception { + public Result getDetail(String id) throws Exception { UserEntity entity = userMapper.selectById(id); return Result.success(buildDTO(entity)); } diff --git a/src/main/java/com/project/ding/utils/DingUtil.java b/src/main/java/com/project/ding/utils/DingUtil.java index 275446c..d598ccd 100644 --- a/src/main/java/com/project/ding/utils/DingUtil.java +++ b/src/main/java/com/project/ding/utils/DingUtil.java @@ -147,7 +147,6 @@ public class DingUtil { String nowTime = LocalDateTime.now().format(formatter); boolean approved = appealDTO.getStatus() != null && appealDTO.getStatus() == 2; - UserDTO userDTO = getUserById(appealDTO.getAppealUserId()); String resultLine = approved ? "- ✅ **审核通过**" : "- ❌ **审核不通过**"; @@ -166,7 +165,7 @@ public class DingUtil { appealDTO.getRemark(), resultLine, nowTime, - userDTO.getName(), + appealDTO.getAppealUsername(), appealDTO.getReason() ); diff --git a/src/main/java/com/project/exam/mapper/ExamRecordMapper.java b/src/main/java/com/project/exam/mapper/ExamRecordMapper.java index 64da13a..a03e388 100644 --- a/src/main/java/com/project/exam/mapper/ExamRecordMapper.java +++ b/src/main/java/com/project/exam/mapper/ExamRecordMapper.java @@ -6,8 +6,6 @@ import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Update; import org.springframework.data.repository.query.Param; -import java.math.BigDecimal; - @Mapper public interface ExamRecordMapper extends BaseMapper { /** @@ -24,7 +22,7 @@ public interface ExamRecordMapper extends BaseMapper { @Update("UPDATE evaluator_exam_record SET " + "answer_snapshot = JSON_SET(answer_snapshot, '$[${index}].hasAppealed', true), " + - "score = #{score}" + + "score = #{score}, " + "update_time = NOW() " + "WHERE id = #{id}") void updateScore(@Param("index") int index, diff --git a/src/main/java/com/project/information/mapper/KnowledgePointMapper.java b/src/main/java/com/project/information/mapper/KnowledgePointMapper.java index 97e9a03..83cce17 100644 --- a/src/main/java/com/project/information/mapper/KnowledgePointMapper.java +++ b/src/main/java/com/project/information/mapper/KnowledgePointMapper.java @@ -21,9 +21,9 @@ public interface KnowledgePointMapper extends BaseMapper { "SELECT", " SUM(CASE WHEN p.knowledge_type = 0 THEN 1 ELSE 0 END) AS accurateGraspNum,", " SUM(CASE WHEN p.knowledge_type = 1 THEN 1 ELSE 0 END) AS vagueGraspNum", - "FROM evaluator_information e", - "INNER JOIN evaluator_knowledge_point p ON p.information_id = e.id", - "WHERE e.sub_line_id = #{subLineId}" + "FROM evaluator_information e ", + "INNER JOIN evaluator_knowledge_point p ON p.information_id = e.id ", + "WHERE e.sub_line_id = #{subLineId} and p.deleted = 0 and e.deleted = 0" }) KnowledgePointStatisticsDTO selectBySubLineId(@Param("subLineId") Long subLineId); } diff --git a/src/main/java/com/project/information/mapper/ProductLineMapper.java b/src/main/java/com/project/information/mapper/ProductLineMapper.java index 895cb26..bc9ef0f 100644 --- a/src/main/java/com/project/information/mapper/ProductLineMapper.java +++ b/src/main/java/com/project/information/mapper/ProductLineMapper.java @@ -2,8 +2,26 @@ package com.project.information.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.project.information.domain.entity.ProductLineEntity; +import com.project.task.domain.dto.TaskDTO; import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Select; + +import java.util.List; +import java.util.Set; @Mapper public interface ProductLineMapper extends BaseMapper { + @Select({ + "" + }) + List getSubLineByTaskIDS(@Param("taskIds") Set taskIds); } diff --git a/src/main/java/com/project/operation/application/OperationLogApplicationServiceImpl.java b/src/main/java/com/project/operation/application/OperationLogApplicationServiceImpl.java index 26b915a..6e3d83c 100644 --- a/src/main/java/com/project/operation/application/OperationLogApplicationServiceImpl.java +++ b/src/main/java/com/project/operation/application/OperationLogApplicationServiceImpl.java @@ -1,16 +1,23 @@ package com.project.operation.application; +import com.project.base.domain.exception.BusinessErrorException; import com.project.base.domain.result.PageResult; import com.project.base.domain.result.Result; +import com.project.base.domain.utils.ExcelUtil; import com.project.operation.application.impl.OperationLogApplicationService; import com.project.operation.domain.dto.OperationLogDTO; +import com.project.operation.domain.dto.OperationLogExportDTO; import com.project.operation.domain.param.OperationLogParam; import com.project.operation.domain.service.SaveOperationLogDomainService; import com.project.operation.domain.service.SearchOperationLogDomainService; +import jakarta.servlet.http.HttpServletResponse;; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; +import java.util.List; +import java.util.stream.Collectors; + @Service public class OperationLogApplicationServiceImpl implements OperationLogApplicationService { @@ -19,6 +26,11 @@ public class OperationLogApplicationServiceImpl implements OperationLogApplicati @Autowired private SearchOperationLogDomainService searchOperationLogDomainService; + private static final String SHEET_NAME = "操作日志数据"; + private static final String EXCEL_FILENAME = "operationLog"; + private static final Integer PAGE_MAX_SIZE = 5001; + private static final Integer PAGE_DEFAULT_CURRENT = 1; + /** * 保存日志 */ @@ -41,4 +53,22 @@ public class OperationLogApplicationServiceImpl implements OperationLogApplicati this.saveOperationLog(operationLogDTO); } + /** + * 导出日志 + */ + @Override + public void export(HttpServletResponse response, OperationLogParam param) { + //获取日志列表 + param.setSize(PAGE_MAX_SIZE); + param.setCurrent(PAGE_DEFAULT_CURRENT); + List operationLogExportDTOList = searchOperationLogDomainService.list(param).getData().getContent() + .stream().map(dto -> dto.toEntity(OperationLogExportDTO::new)).collect(Collectors.toList()); + if (operationLogExportDTOList.size() == PAGE_MAX_SIZE) { + throw new BusinessErrorException("最大条数限制5000条超过最大限制不允许导出"); + } + + ExcelUtil util = new ExcelUtil<>(); + util.exportExcel(response,operationLogExportDTOList,SHEET_NAME,EXCEL_FILENAME,OperationLogExportDTO.class); + } + } diff --git a/src/main/java/com/project/operation/application/impl/OperationLogApplicationService.java b/src/main/java/com/project/operation/application/impl/OperationLogApplicationService.java index 5104fd0..cb28733 100644 --- a/src/main/java/com/project/operation/application/impl/OperationLogApplicationService.java +++ b/src/main/java/com/project/operation/application/impl/OperationLogApplicationService.java @@ -4,6 +4,7 @@ import com.project.base.domain.result.PageResult; import com.project.base.domain.result.Result; import com.project.operation.domain.dto.OperationLogDTO; import com.project.operation.domain.param.OperationLogParam; +import jakarta.servlet.http.HttpServletResponse; import java.util.List; @@ -22,4 +23,9 @@ public interface OperationLogApplicationService { * 异步保存日志 */ void saveOperationLogAsync(OperationLogDTO operationLogDTO); + + /** + * 导出 + */ + void export(HttpServletResponse response, OperationLogParam param); } diff --git a/src/main/java/com/project/operation/controller/OperationLogController.java b/src/main/java/com/project/operation/controller/OperationLogController.java index a28a2b8..ddc92e9 100644 --- a/src/main/java/com/project/operation/controller/OperationLogController.java +++ b/src/main/java/com/project/operation/controller/OperationLogController.java @@ -9,8 +9,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; - -import java.util.List; +import jakarta.servlet.http.HttpServletResponse; @RestController @RequestMapping("/api/admin/operationLog") @@ -23,4 +22,9 @@ public class OperationLogController { public Result> list(OperationLogParam param) throws Exception { return operationLogApplicationService.list(param); } + + @GetMapping("/export") + public void export(HttpServletResponse response,OperationLogParam param){ + operationLogApplicationService.export(response,param); + } } diff --git a/src/main/java/com/project/operation/domain/dto/OperationLogExportDTO.java b/src/main/java/com/project/operation/domain/dto/OperationLogExportDTO.java new file mode 100644 index 0000000..d66e774 --- /dev/null +++ b/src/main/java/com/project/operation/domain/dto/OperationLogExportDTO.java @@ -0,0 +1,29 @@ +package com.project.operation.domain.dto; + +import com.alibaba.excel.annotation.ExcelProperty; +import com.alibaba.excel.annotation.format.DateTimeFormat; +import lombok.Data; + +import java.util.Date; + +@Data +public class OperationLogExportDTO { + @ExcelProperty(value = "姓名") + private String username; + + @ExcelProperty(value = "部门") + private String department; + + @ExcelProperty(value = "职位") + private String position; + + @DateTimeFormat("yyyy-MM-dd HH:mm:ss") + @ExcelProperty(value = "操作时间") + private Date createTime; + + @ExcelProperty(value = "操作") + private String action; + + @ExcelProperty(value = "详细信息") + private String description; +} diff --git a/src/main/java/com/project/operation/domain/service/impl/description/TaskDescriptionStrategy.java b/src/main/java/com/project/operation/domain/service/impl/description/TaskDescriptionStrategy.java index cc00322..1553e04 100644 --- a/src/main/java/com/project/operation/domain/service/impl/description/TaskDescriptionStrategy.java +++ b/src/main/java/com/project/operation/domain/service/impl/description/TaskDescriptionStrategy.java @@ -6,13 +6,10 @@ import com.project.operation.domain.service.DescriptionStrategy; import com.project.task.application.TaskApplicationService; import com.project.task.domain.dto.TaskDTO; import org.apache.commons.collections4.CollectionUtils; -import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; - -import java.lang.reflect.Array; import java.util.Arrays; import java.util.List; import java.util.Optional; @@ -47,6 +44,7 @@ public class TaskDescriptionStrategy implements DescriptionStrategy { if (methodName.equals("batchDelete") && ObjectUtils.isNotEmpty(args) && args[0] instanceof TaskDTO) { String taskIds = (String) args[0]; if (StringUtils.isBlank(taskIds)){ + operationLogDTO.setAction("批量删除"); return false; } List taskIdList = Arrays.asList(taskIds.split(",")).stream().map(id -> Long.valueOf(id)).collect(Collectors.toList()); diff --git a/src/main/java/com/project/task/mapper/TaskMapper.java b/src/main/java/com/project/task/mapper/TaskMapper.java index 866d592..581e6c5 100644 --- a/src/main/java/com/project/task/mapper/TaskMapper.java +++ b/src/main/java/com/project/task/mapper/TaskMapper.java @@ -30,9 +30,9 @@ public interface TaskMapper extends BaseMapper { * 查询考试任务 */ @Select({ - "select e.id,l.name as subLineName" + - "from evaluator_task e " + - "LEFT join evaluator_product_line l on e.id = l.id" + + "select e.id,l.name as subLineName " + + "FROM evaluator_task e " + + "LEFT join evaluator_product_line l on e.sub_line_id = l.id " + "where l.leaf = 1 and l.name LIKE CONCAT('%', #{subLineName}, '%')" }) List getTaskBySubLineName(@Param("subLineName") String subLineName);