Browse Source

导出功能开发

master
luogw 1 month ago
parent
commit
65440ba12b
  1. 6
      pom.xml
  2. 8
      src/main/java/com/project/appeal/application/AppealApplication.java
  3. 31
      src/main/java/com/project/appeal/application/Impl/AppealApplicationImpl.java
  4. 8
      src/main/java/com/project/appeal/controller/AppealAdminController.java
  5. 4
      src/main/java/com/project/appeal/controller/AppealController.java
  6. 3
      src/main/java/com/project/appeal/domain/dto/AppealDTO.java
  7. 37
      src/main/java/com/project/appeal/domain/dto/AppealExportDTO.java
  8. 6
      src/main/java/com/project/appeal/domain/entity/AppealEntity.java
  9. 35
      src/main/java/com/project/appeal/domain/service/Impl/CheckAppealDomainServiceImpl.java
  10. 27
      src/main/java/com/project/appeal/domain/service/Impl/SaveAppealDomainServiceImpl.java
  11. 13
      src/main/java/com/project/appeal/domain/service/Impl/SearchAppealDomainServiceImpl.java
  12. 3
      src/main/java/com/project/appeal/domain/service/SaveAppealDomainService.java
  13. 11
      src/main/java/com/project/base/domain/advice/GlobalExceptionHandlerAdvice.java
  14. 40
      src/main/java/com/project/base/domain/utils/ExcelUtil.java
  15. 2
      src/main/java/com/project/ding/application/UserApplicationService.java
  16. 2
      src/main/java/com/project/ding/application/impl/UserApplicationServiceImpl.java
  17. 2
      src/main/java/com/project/ding/controller/UserController.java
  18. 2
      src/main/java/com/project/ding/domain/service/SearchUserDomainService.java
  19. 2
      src/main/java/com/project/ding/domain/service/impl/SearchUserDomainServiceImpl.java
  20. 3
      src/main/java/com/project/ding/utils/DingUtil.java
  21. 4
      src/main/java/com/project/exam/mapper/ExamRecordMapper.java
  22. 6
      src/main/java/com/project/information/mapper/KnowledgePointMapper.java
  23. 18
      src/main/java/com/project/information/mapper/ProductLineMapper.java
  24. 30
      src/main/java/com/project/operation/application/OperationLogApplicationServiceImpl.java
  25. 6
      src/main/java/com/project/operation/application/impl/OperationLogApplicationService.java
  26. 8
      src/main/java/com/project/operation/controller/OperationLogController.java
  27. 29
      src/main/java/com/project/operation/domain/dto/OperationLogExportDTO.java
  28. 4
      src/main/java/com/project/operation/domain/service/impl/description/TaskDescriptionStrategy.java
  29. 6
      src/main/java/com/project/task/mapper/TaskMapper.java

6
pom.xml

@ -217,6 +217,12 @@
<scope>compile</scope> <scope>compile</scope>
</dependency> </dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>3.3.4</version>
</dependency>
</dependencies> </dependencies>
<build> <build>
<plugins> <plugins>

8
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.appeal.domain.param.AppealParam;
import com.project.base.domain.result.PageResult; import com.project.base.domain.result.PageResult;
import com.project.base.domain.result.Result; import com.project.base.domain.result.Result;
import jakarta.servlet.http.HttpServletResponse;
import java.util.List; import java.util.List;
@ -12,10 +13,15 @@ public interface AppealApplication {
/** /**
* 保存或修改申诉 * 保存或修改申诉
*/ */
Result<AppealDTO> saveOrUpdate(AppealDTO appealDTO) throws DtErrorException; Result<AppealDTO> saveOrUpdate(AppealDTO appealDTO) throws Exception;
/** /**
* 查询申诉列表 * 查询申诉列表
*/ */
Result<PageResult<AppealDTO>> list(AppealParam appealParam); Result<PageResult<AppealDTO>> list(AppealParam appealParam);
/**
*
*/
void export(AppealParam appealParam, HttpServletResponse response);
} }

31
src/main/java/com/project/appeal/application/Impl/AppealApplicationImpl.java

@ -1,18 +1,22 @@
package com.project.appeal.application.Impl; package com.project.appeal.application.Impl;
import com.github.tingyugetc520.ali.dingtalk.error.DtErrorException;
import com.project.appeal.application.AppealApplication; import com.project.appeal.application.AppealApplication;
import com.project.appeal.domain.dto.AppealDTO; 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.param.AppealParam;
import com.project.appeal.domain.service.CheckAppealDomainService; import com.project.appeal.domain.service.CheckAppealDomainService;
import com.project.appeal.domain.service.SaveAppealDomainService; import com.project.appeal.domain.service.SaveAppealDomainService;
import com.project.appeal.domain.service.SearchAppealDomainService; 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.PageResult;
import com.project.base.domain.result.Result; 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.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.List; import java.util.List;
import java.util.stream.Collectors;
@Service @Service
public class AppealApplicationImpl implements AppealApplication { public class AppealApplicationImpl implements AppealApplication {
@ -23,11 +27,16 @@ public class AppealApplicationImpl implements AppealApplication {
@Autowired @Autowired
private SearchAppealDomainService searchAppealDomainService; 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 @Override
public Result<AppealDTO> saveOrUpdate(AppealDTO appealDTO) throws DtErrorException { public Result<AppealDTO> saveOrUpdate(AppealDTO appealDTO) throws Exception {
checkAppealDomainService.checkDto(appealDTO); checkAppealDomainService.checkDto(appealDTO);
return saveAppealDomainService.saveOrUpdate(appealDTO); return saveAppealDomainService.saveOrUpdate(appealDTO);
} }
@ -39,4 +48,22 @@ public class AppealApplicationImpl implements AppealApplication {
public Result<PageResult<AppealDTO>> list(AppealParam appealParam) { public Result<PageResult<AppealDTO>> list(AppealParam appealParam) {
return searchAppealDomainService.list(appealParam); return searchAppealDomainService.list(appealParam);
} }
/**
* 申诉导出
*/
@Override
public void export(AppealParam param, HttpServletResponse response) {
//获取申诉列表
param.setSize(PAGE_MAX_SIZE);
param.setCurrent(PAGE_DEFAULT_CURRENT);
List<AppealExportDTO> 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<AppealExportDTO> util = new ExcelUtil<>();
util.exportExcel(response,appealExportDTOList,SHEET_NAME,EXCEL_FILENAME,AppealExportDTO.class);
}
} }

8
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.PageResult;
import com.project.base.domain.result.Result; import com.project.base.domain.result.Result;
import com.project.operation.annotation.OperationLog; import com.project.operation.annotation.OperationLog;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
@ -21,7 +22,7 @@ public class AppealAdminController {
@PostMapping("saveOrUpdate") @PostMapping("saveOrUpdate")
@OperationLog(module = "申诉审批") @OperationLog(module = "申诉审批")
public Result<AppealDTO> saveOrUpdate(AppealDTO appealDTO) throws DtErrorException { public Result<AppealDTO> saveOrUpdate(AppealDTO appealDTO) throws Exception {
return appealApplication.saveOrUpdate(appealDTO); return appealApplication.saveOrUpdate(appealDTO);
} }
@ -29,4 +30,9 @@ public class AppealAdminController {
public Result<PageResult<AppealDTO>> list(AppealParam appealParam){ public Result<PageResult<AppealDTO>> list(AppealParam appealParam){
return appealApplication.list(appealParam); return appealApplication.list(appealParam);
} }
@GetMapping("export")
public void export(AppealParam appealParam, HttpServletResponse response) throws DtErrorException {
appealApplication.export(appealParam,response);
}
} }

4
src/main/java/com/project/appeal/controller/AppealController.java

@ -1,12 +1,10 @@
package com.project.appeal.controller; package com.project.appeal.controller;
import com.github.tingyugetc520.ali.dingtalk.error.DtErrorException;
import com.project.appeal.application.AppealApplication; import com.project.appeal.application.AppealApplication;
import com.project.appeal.domain.dto.AppealDTO; import com.project.appeal.domain.dto.AppealDTO;
import com.project.base.domain.result.Result; import com.project.base.domain.result.Result;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping; 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.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
@ -20,7 +18,7 @@ public class AppealController {
private AppealApplication appealApplication; private AppealApplication appealApplication;
@PostMapping("saveOrUpdate") @PostMapping("saveOrUpdate")
public Result<AppealDTO> saveOrUpdate(@RequestBody AppealDTO appealDTO) throws DtErrorException { public Result<AppealDTO> saveOrUpdate(AppealDTO appealDTO) throws Exception {
return appealApplication.saveOrUpdate(appealDTO); return appealApplication.saveOrUpdate(appealDTO);
} }
} }

3
src/main/java/com/project/appeal/domain/dto/AppealDTO.java

@ -21,7 +21,8 @@ public class AppealDTO extends BaseDTO {
private Long id; private Long id;
private String userId; private String userId;
private String appealUserId; private String appealUserId;
private String userName; private String username;
private String appealUsername;
private Long examId; private Long examId;
private Long taskId; private Long taskId;
private String subLineName;//关联子产品线 private String subLineName;//关联子产品线

37
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;
}

6
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'") @Column(name = "appeal_user_id" , columnDefinition="varchar(50) comment '审批用户id'")
private String appealUserId; private String appealUserId;
@TableField("appeal_username")
@Column(name = "appeal_username" , columnDefinition="varchar(50) comment '审批用户名称'")
private String appealUsername;
@TableField("exam_id") @TableField("exam_id")
@Column(name = "exam_id" , columnDefinition="bigint(20) comment '考试id'") @Column(name = "exam_id" , columnDefinition="bigint(20) comment '考试id'")
private Long examId; private Long examId;
@ -43,7 +47,7 @@ public class AppealEntity extends BaseEntity {
@Column(name = "user_answer",columnDefinition = "varchar(255) comment '用户答案'") @Column(name = "user_answer",columnDefinition = "varchar(255) comment '用户答案'")
@TableField("user_answer") @TableField("user_answer")
private Long userAnswer; private String userAnswer;
@Column(name = "question_id") @Column(name = "question_id")
@Comment("题目ID") @Comment("题目ID")

35
src/main/java/com/project/appeal/domain/service/Impl/CheckAppealDomainServiceImpl.java

@ -1,8 +1,11 @@
package com.project.appeal.domain.service.Impl; package com.project.appeal.domain.service.Impl;
import cn.hutool.core.util.ObjectUtil; 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.dto.AppealDTO;
import com.project.appeal.domain.entity.AppealEntity;
import com.project.appeal.domain.enums.AppealStatusEnum; import com.project.appeal.domain.enums.AppealStatusEnum;
import com.project.appeal.domain.service.AppealBaseService;
import com.project.appeal.domain.service.CheckAppealDomainService; import com.project.appeal.domain.service.CheckAppealDomainService;
import com.project.base.domain.exception.BusinessErrorException; import com.project.base.domain.exception.BusinessErrorException;
import com.project.base.domain.exception.MissingParameterException; 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.domain.enums.UserRoleEnum;
import com.project.ding.utils.SecurityUtils; import com.project.ding.utils.SecurityUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.List; import java.util.List;
@Service @Service
public class CheckAppealDomainServiceImpl implements CheckAppealDomainService { public class CheckAppealDomainServiceImpl implements CheckAppealDomainService {
@Autowired
private AppealBaseService appealBaseService;
@Override @Override
public void checkDto(AppealDTO appealDTO) { public void checkDto(AppealDTO appealDTO) {
if (ObjectUtil.isEmpty(appealDTO.getExamId())){ if (ObjectUtil.isEmpty(appealDTO.getId()) && ObjectUtil.isEmpty(appealDTO.getExamId())){
throw new MissingParameterException("缺少考试ID"); throw new MissingParameterException("缺少考试ID");
} }
if (ObjectUtil.isEmpty(appealDTO.getQuestionContent())){ if (ObjectUtil.isEmpty(appealDTO.getId()) && ObjectUtil.isEmpty(appealDTO.getQuestionId())){
throw new MissingParameterException("缺少题目ID"); throw new MissingParameterException("缺少题目ID");
} }
if (StringUtils.isBlank(appealDTO.getUserAnswer())){ if (ObjectUtil.isEmpty(appealDTO.getId()) && StringUtils.isBlank(appealDTO.getUserAnswer())){
throw new MissingParameterException("缺少用户答案"); throw new MissingParameterException("缺少用户答案");
} }
if (StringUtils.isBlank(appealDTO.getRemark())){ if (ObjectUtil.isEmpty(appealDTO.getId()) && StringUtils.isBlank(appealDTO.getRemark())){
throw new MissingParameterException("缺少申诉理由"); throw new MissingParameterException("缺少申诉理由");
} }
if (ObjectUtil.isEmpty(appealDTO.getId()) && !appealDTO.getStatus().equals(AppealStatusEnum.PENDING_REVIEW.getValue())){ 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())){ if (!appealDTO.getStatus().equals(AppealStatusEnum.PENDING_REVIEW.getValue()) && StringUtils.isBlank(appealDTO.getReason())){
throw new BusinessErrorException("缺少审批意见"); throw new BusinessErrorException("缺少审批意见");
} }
//校验题目是否以申诉过
if (ObjectUtil.isEmpty(appealDTO.getId()) ){
QueryWrapper<AppealEntity> 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())){ if (ObjectUtil.isNotEmpty(appealDTO.getId()) && !appealDTO.getStatus().equals(AppealStatusEnum.PENDING_REVIEW.getValue())){
//校验权限 //校验权限
List<String> userRoles = SecurityUtils.getUserRoles(); List<String> userRoles = SecurityUtils.getUserRoles();
if(! userRoles.stream().anyMatch(UserRoleEnum.ROLE_ADMIN::equals)){ if(!userRoles.stream().anyMatch(UserRoleEnum.ROLE_ADMIN.name()::equals)){
throw new PermissionErrorException(); throw new PermissionErrorException();
} }
} }

27
src/main/java/com/project/appeal/domain/service/Impl/SaveAppealDomainServiceImpl.java

@ -1,8 +1,6 @@
package com.project.appeal.domain.service.Impl; 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.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.dto.AppealDTO;
import com.project.appeal.domain.entity.AppealEntity; import com.project.appeal.domain.entity.AppealEntity;
import com.project.appeal.domain.enums.AppealStatusEnum; 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.appeal.domain.service.SaveAppealDomainService;
import com.project.base.domain.exception.BusinessErrorException; import com.project.base.domain.exception.BusinessErrorException;
import com.project.base.domain.result.Result; import com.project.base.domain.result.Result;
import com.project.ding.application.UserApplicationService;
import com.project.ding.domain.dto.UserDTO; import com.project.ding.domain.dto.UserDTO;
import com.project.ding.utils.DingUtil; import com.project.ding.utils.DingUtil;
import com.project.ding.utils.SecurityUtils; import com.project.ding.utils.SecurityUtils;
@ -28,12 +27,15 @@ import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.math.RoundingMode; import java.math.RoundingMode;
import java.util.List; import java.util.List;
import java.util.Objects;
@Service @Service
public class SaveAppealDomainServiceImpl implements SaveAppealDomainService { public class SaveAppealDomainServiceImpl implements SaveAppealDomainService {
@Autowired @Autowired
private AppealBaseService appealBaseService; private AppealBaseService appealBaseService;
@Autowired @Autowired
private UserApplicationService userApplicationService;
@Autowired
private ExamRecordMapper examRecordMapper; private ExamRecordMapper examRecordMapper;
@Autowired @Autowired
private TaskUserMapper taskUserMapper; private TaskUserMapper taskUserMapper;
@ -45,17 +47,19 @@ public class SaveAppealDomainServiceImpl implements SaveAppealDomainService {
@Override @Override
@Transactional(rollbackFor = BusinessErrorException.class) @Transactional(rollbackFor = BusinessErrorException.class)
public Result<AppealDTO> saveOrUpdate(AppealDTO appealDTO) throws DtErrorException { public Result<AppealDTO> saveOrUpdate(AppealDTO appealDTO) throws Exception {
AppealEntity entity = appealDTO.toEntity(AppealEntity::new); AppealEntity entity = appealDTO.toEntity(AppealEntity::new);
//设置审批人 //设置审批人
if (!appealDTO.getStatus().equals(AppealStatusEnum.PENDING_REVIEW.getValue())){ 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{ }else{
//设置申诉人 //设置申诉人
appealDTO.setAppealUserId(SecurityUtils.getUserId()); entity.setUserId(SecurityUtils.getUserId());
UserDTO user = dingUtil.getUserById(SecurityUtils.getUserId()); UserDTO user = userApplicationService.getDetail(SecurityUtils.getUserId()).getData();
appealDTO.setUserName(user.getName()); entity.setUsername(user.getName());
} }
appealBaseService.saveOrUpdate(entity); appealBaseService.saveOrUpdate(entity);
@ -69,6 +73,7 @@ public class SaveAppealDomainServiceImpl implements SaveAppealDomainService {
return Result.success(appealDTO); return Result.success(appealDTO);
} }
appealDTO = appealBaseService.getById(appealDTO.getId()).toDTO(AppealDTO::new);
ExamRecordEntity examRecord = examRecordMapper.selectById(appealDTO.getExamId()); ExamRecordEntity examRecord = examRecordMapper.selectById(appealDTO.getExamId());
if (examRecord == null){ if (examRecord == null){
throw new BusinessErrorException("用户未该场考试"); throw new BusinessErrorException("用户未该场考试");
@ -81,8 +86,7 @@ public class SaveAppealDomainServiceImpl implements SaveAppealDomainService {
int index = -1; int index = -1;
for (int i = 0; i < answerSnapshotDTOList.size(); i++) { for (int i = 0; i < answerSnapshotDTOList.size(); i++) {
ExamRecordDTO.QuestionSnapshotDTO dto = answerSnapshotDTOList.get(i); ExamRecordDTO.QuestionSnapshotDTO dto = answerSnapshotDTOList.get(i);
if (appealDTO.getQuestionId() != null if (Objects.equals(appealDTO.getQuestionId(), dto.getQuestionId())) {
&& appealDTO.getQuestionId().equals(dto.getQuestionId())) {
index = i; index = i;
break; break;
} }
@ -94,11 +98,6 @@ public class SaveAppealDomainServiceImpl implements SaveAppealDomainService {
throw new BusinessErrorException("题目不存在"); throw new BusinessErrorException("题目不存在");
} }
//已申诉题目无法再申诉
if(questionSnapshotDTO.getHasAppealed()){
throw new BusinessErrorException("题目已申诉");
}
TaskEntity taskEntity = taskMapper.getTaskByTaskUserId(examRecord.getTaskUserId()); TaskEntity taskEntity = taskMapper.getTaskByTaskUserId(examRecord.getTaskUserId());
QuestionTypeEnum questionType = QuestionTypeEnum.findByValue(questionSnapshotDTO.getType()); QuestionTypeEnum questionType = QuestionTypeEnum.findByValue(questionSnapshotDTO.getType());

13
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.base.domain.utils.PageConverter;
import com.project.information.domain.entity.KnowledgePointEntity; import com.project.information.domain.entity.KnowledgePointEntity;
import com.project.information.domain.service.KnowledgePointBaseService; 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.entity.QuestionEntity;
import com.project.question.domain.service.QuestionBaseService; import com.project.question.domain.service.QuestionBaseService;
import com.project.task.domain.dto.TaskDTO; import com.project.task.domain.dto.TaskDTO;
@ -36,6 +37,8 @@ public class SearchAppealDomainServiceImpl implements SearchAppealDomainService
private TaskMapper taskMapper; private TaskMapper taskMapper;
@Autowired @Autowired
private KnowledgePointBaseService knowledgePointBaseService; private KnowledgePointBaseService knowledgePointBaseService;
@Autowired
private ProductLineMapper productLineMapper;
@Override @Override
public Result<PageResult<AppealDTO>> list(AppealParam appealParam) { public Result<PageResult<AppealDTO>> list(AppealParam appealParam) {
@ -45,13 +48,21 @@ public class SearchAppealDomainServiceImpl implements SearchAppealDomainService
if (StringUtils.isBlank(appealParam.getSubLineName())){ if (StringUtils.isBlank(appealParam.getSubLineName())){
Page<AppealEntity> appealEntityPage = appealMapper.selectPage(PageConverter.toMpPage(appealParam), appealEntityQueryWrapper); Page<AppealEntity> appealEntityPage = appealMapper.selectPage(PageConverter.toMpPage(appealParam), appealEntityQueryWrapper);
appealDTOIPage = appealEntityPage.convert(entity -> entity.toDTO(AppealDTO::new)); appealDTOIPage = appealEntityPage.convert(entity -> entity.toDTO(AppealDTO::new));
//查询产品线相关的考试任务
Set<Long> taskIdSet = appealDTOIPage.getRecords().stream().map(appealDTO -> appealDTO.getTaskId()).collect(Collectors.toSet());
if (!CollectionUtils.isEmpty(taskIdSet)){
List<TaskDTO> taskByIds = productLineMapper.getSubLineByTaskIDS(taskIdSet);
taskIdToSubLineNameMap = taskByIds.stream().collect(Collectors.toMap(TaskDTO::getId, TaskDTO::getSubLineName));
}
}else{ }else{
//查询产品线相关的考试任务 //查询产品线相关的考试任务
List<TaskDTO> taskBySubLineName = taskMapper.getTaskBySubLineName(appealParam.getSubLineName()); List<TaskDTO> 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.in("task_id",taskBySubLineName.stream().map(TaskDTO::getId).collect(Collectors.toList()));
appealEntityQueryWrapper.orderByDesc("update_time");
Page<AppealEntity> appealEntityPage = appealMapper.selectPage(PageConverter.toMpPage(appealParam), appealEntityQueryWrapper); Page<AppealEntity> appealEntityPage = appealMapper.selectPage(PageConverter.toMpPage(appealParam), appealEntityQueryWrapper);
appealDTOIPage = appealEntityPage.convert(entity -> entity.toDTO(AppealDTO::new)); appealDTOIPage = appealEntityPage.convert(entity -> entity.toDTO(AppealDTO::new));
} }

3
src/main/java/com/project/appeal/domain/service/SaveAppealDomainService.java

@ -1,9 +1,8 @@
package com.project.appeal.domain.service; package com.project.appeal.domain.service;
import com.github.tingyugetc520.ali.dingtalk.error.DtErrorException;
import com.project.appeal.domain.dto.AppealDTO; import com.project.appeal.domain.dto.AppealDTO;
import com.project.base.domain.result.Result; import com.project.base.domain.result.Result;
public interface SaveAppealDomainService { public interface SaveAppealDomainService {
Result<AppealDTO> saveOrUpdate(AppealDTO appealDTO) throws DtErrorException; Result<AppealDTO> saveOrUpdate(AppealDTO appealDTO) throws Exception;
} }

11
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.BusinessErrorException;
import com.project.base.domain.exception.MissingParameterException; 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.exception.ResourceNotExistException;
import com.project.base.domain.result.Result; import com.project.base.domain.result.Result;
import com.project.base.domain.result.ResultCodeEnum; import com.project.base.domain.result.ResultCodeEnum;
@ -60,6 +61,16 @@ public class GlobalExceptionHandlerAdvice {
return Result.fail(ResultCodeEnum.BUSINESS_ERROR , e.getMessage()); 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) @ExceptionHandler(MissingParameterException.class)
@ResponseBody @ResponseBody

40
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<T> {
public void exportExcel(HttpServletResponse response, List<T> list, String sheetName,String fileName,Class<T> 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);
}
}
}

2
src/main/java/com/project/ding/application/UserApplicationService.java

@ -12,7 +12,7 @@ public interface UserApplicationService {
Result<PageResult<UserDTO>> search(UserParam param) throws Exception; Result<PageResult<UserDTO>> search(UserParam param) throws Exception;
Result<UserDTO> getDetail(Long id) throws Exception; Result<UserDTO> getDetail(String id) throws Exception;

2
src/main/java/com/project/ding/application/impl/UserApplicationServiceImpl.java

@ -28,7 +28,7 @@ public class UserApplicationServiceImpl implements UserApplicationService {
} }
@Override @Override
public Result<UserDTO> getDetail(Long id) throws Exception { public Result<UserDTO> getDetail(String id) throws Exception {
return searchUserDomainService.getDetail(id); return searchUserDomainService.getDetail(id);
} }

2
src/main/java/com/project/ding/controller/UserController.java

@ -30,7 +30,7 @@ public class UserController {
} }
@GetMapping("/getDetail") @GetMapping("/getDetail")
public Result<UserDTO> getDetail(Long id) throws Exception { public Result<UserDTO> getDetail(String id) throws Exception {
return userApplicationService.getDetail(id); return userApplicationService.getDetail(id);
} }
} }

2
src/main/java/com/project/ding/domain/service/SearchUserDomainService.java

@ -12,7 +12,7 @@ public interface SearchUserDomainService {
Result<PageResult<UserDTO>> search(UserParam param) throws Exception; Result<PageResult<UserDTO>> search(UserParam param) throws Exception;
Result<UserDTO> getDetail(Long id) throws Exception; Result<UserDTO> getDetail(String id) throws Exception;
List<UserDTO> searchByIds(Set<String> idSet); List<UserDTO> searchByIds(Set<String> idSet);
} }

2
src/main/java/com/project/ding/domain/service/impl/SearchUserDomainServiceImpl.java

@ -68,7 +68,7 @@ public class SearchUserDomainServiceImpl implements SearchUserDomainService {
} }
@Override @Override
public Result<UserDTO> getDetail(Long id) throws Exception { public Result<UserDTO> getDetail(String id) throws Exception {
UserEntity entity = userMapper.selectById(id); UserEntity entity = userMapper.selectById(id);
return Result.success(buildDTO(entity)); return Result.success(buildDTO(entity));
} }

3
src/main/java/com/project/ding/utils/DingUtil.java

@ -147,7 +147,6 @@ public class DingUtil {
String nowTime = LocalDateTime.now().format(formatter); String nowTime = LocalDateTime.now().format(formatter);
boolean approved = appealDTO.getStatus() != null && appealDTO.getStatus() == 2; boolean approved = appealDTO.getStatus() != null && appealDTO.getStatus() == 2;
UserDTO userDTO = getUserById(appealDTO.getAppealUserId());
String resultLine = approved String resultLine = approved
? "- ✅ **审核通过**" ? "- ✅ **审核通过**"
: "- ❌ **审核不通过**"; : "- ❌ **审核不通过**";
@ -166,7 +165,7 @@ public class DingUtil {
appealDTO.getRemark(), appealDTO.getRemark(),
resultLine, resultLine,
nowTime, nowTime,
userDTO.getName(), appealDTO.getAppealUsername(),
appealDTO.getReason() appealDTO.getReason()
); );

4
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.apache.ibatis.annotations.Update;
import org.springframework.data.repository.query.Param; import org.springframework.data.repository.query.Param;
import java.math.BigDecimal;
@Mapper @Mapper
public interface ExamRecordMapper extends BaseMapper<ExamRecordEntity> { public interface ExamRecordMapper extends BaseMapper<ExamRecordEntity> {
/** /**
@ -24,7 +22,7 @@ public interface ExamRecordMapper extends BaseMapper<ExamRecordEntity> {
@Update("UPDATE evaluator_exam_record SET " + @Update("UPDATE evaluator_exam_record SET " +
"answer_snapshot = JSON_SET(answer_snapshot, '$[${index}].hasAppealed', true), " + "answer_snapshot = JSON_SET(answer_snapshot, '$[${index}].hasAppealed', true), " +
"score = #{score}" + "score = #{score}, " +
"update_time = NOW() " + "update_time = NOW() " +
"WHERE id = #{id}") "WHERE id = #{id}")
void updateScore(@Param("index") int index, void updateScore(@Param("index") int index,

6
src/main/java/com/project/information/mapper/KnowledgePointMapper.java

@ -21,9 +21,9 @@ public interface KnowledgePointMapper extends BaseMapper<KnowledgePointEntity> {
"SELECT", "SELECT",
" SUM(CASE WHEN p.knowledge_type = 0 THEN 1 ELSE 0 END) AS accurateGraspNum,", " 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", " SUM(CASE WHEN p.knowledge_type = 1 THEN 1 ELSE 0 END) AS vagueGraspNum",
"FROM evaluator_information e", "FROM evaluator_information e ",
"INNER JOIN evaluator_knowledge_point p ON p.information_id = e.id", "INNER JOIN evaluator_knowledge_point p ON p.information_id = e.id ",
"WHERE e.sub_line_id = #{subLineId}" "WHERE e.sub_line_id = #{subLineId} and p.deleted = 0 and e.deleted = 0"
}) })
KnowledgePointStatisticsDTO selectBySubLineId(@Param("subLineId") Long subLineId); KnowledgePointStatisticsDTO selectBySubLineId(@Param("subLineId") Long subLineId);
} }

18
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.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.project.information.domain.entity.ProductLineEntity; 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.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import java.util.List;
import java.util.Set;
@Mapper @Mapper
public interface ProductLineMapper extends BaseMapper<ProductLineEntity> { public interface ProductLineMapper extends BaseMapper<ProductLineEntity> {
@Select({
"<script>",
"select t.id, e.name as subLineName ",
"from evaluator_product_line e ",
"inner join evaluator_task t on e.id = t.sub_line_id ",
"where t.id in ",
"<foreach collection='taskIds' item='id' open='(' separator=',' close=')'>",
"#{id}",
"</foreach>",
"</script>"
})
List<TaskDTO> getSubLineByTaskIDS(@Param("taskIds") Set<Long> taskIds);
} }

30
src/main/java/com/project/operation/application/OperationLogApplicationServiceImpl.java

@ -1,16 +1,23 @@
package com.project.operation.application; 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.PageResult;
import com.project.base.domain.result.Result; 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.application.impl.OperationLogApplicationService;
import com.project.operation.domain.dto.OperationLogDTO; 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.param.OperationLogParam;
import com.project.operation.domain.service.SaveOperationLogDomainService; import com.project.operation.domain.service.SaveOperationLogDomainService;
import com.project.operation.domain.service.SearchOperationLogDomainService; import com.project.operation.domain.service.SearchOperationLogDomainService;
import jakarta.servlet.http.HttpServletResponse;;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async; import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.List;
import java.util.stream.Collectors;
@Service @Service
public class OperationLogApplicationServiceImpl implements OperationLogApplicationService { public class OperationLogApplicationServiceImpl implements OperationLogApplicationService {
@ -19,6 +26,11 @@ public class OperationLogApplicationServiceImpl implements OperationLogApplicati
@Autowired @Autowired
private SearchOperationLogDomainService searchOperationLogDomainService; 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); this.saveOperationLog(operationLogDTO);
} }
/**
* 导出日志
*/
@Override
public void export(HttpServletResponse response, OperationLogParam param) {
//获取日志列表
param.setSize(PAGE_MAX_SIZE);
param.setCurrent(PAGE_DEFAULT_CURRENT);
List<OperationLogExportDTO> 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<OperationLogExportDTO> util = new ExcelUtil<>();
util.exportExcel(response,operationLogExportDTOList,SHEET_NAME,EXCEL_FILENAME,OperationLogExportDTO.class);
}
} }

6
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.base.domain.result.Result;
import com.project.operation.domain.dto.OperationLogDTO; import com.project.operation.domain.dto.OperationLogDTO;
import com.project.operation.domain.param.OperationLogParam; import com.project.operation.domain.param.OperationLogParam;
import jakarta.servlet.http.HttpServletResponse;
import java.util.List; import java.util.List;
@ -22,4 +23,9 @@ public interface OperationLogApplicationService {
* 异步保存日志 * 异步保存日志
*/ */
void saveOperationLogAsync(OperationLogDTO operationLogDTO); void saveOperationLogAsync(OperationLogDTO operationLogDTO);
/**
* 导出
*/
void export(HttpServletResponse response, OperationLogParam param);
} }

8
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.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import jakarta.servlet.http.HttpServletResponse;
import java.util.List;
@RestController @RestController
@RequestMapping("/api/admin/operationLog") @RequestMapping("/api/admin/operationLog")
@ -23,4 +22,9 @@ public class OperationLogController {
public Result<PageResult<OperationLogDTO>> list(OperationLogParam param) throws Exception { public Result<PageResult<OperationLogDTO>> list(OperationLogParam param) throws Exception {
return operationLogApplicationService.list(param); return operationLogApplicationService.list(param);
} }
@GetMapping("/export")
public void export(HttpServletResponse response,OperationLogParam param){
operationLogApplicationService.export(response,param);
}
} }

29
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;
}

4
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.application.TaskApplicationService;
import com.project.task.domain.dto.TaskDTO; import com.project.task.domain.dto.TaskDTO;
import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.lang.reflect.Array;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
@ -47,6 +44,7 @@ public class TaskDescriptionStrategy implements DescriptionStrategy {
if (methodName.equals("batchDelete") && ObjectUtils.isNotEmpty(args) && args[0] instanceof TaskDTO) { if (methodName.equals("batchDelete") && ObjectUtils.isNotEmpty(args) && args[0] instanceof TaskDTO) {
String taskIds = (String) args[0]; String taskIds = (String) args[0];
if (StringUtils.isBlank(taskIds)){ if (StringUtils.isBlank(taskIds)){
operationLogDTO.setAction("批量删除");
return false; return false;
} }
List<Long> taskIdList = Arrays.asList(taskIds.split(",")).stream().map(id -> Long.valueOf(id)).collect(Collectors.toList()); List<Long> taskIdList = Arrays.asList(taskIds.split(",")).stream().map(id -> Long.valueOf(id)).collect(Collectors.toList());

6
src/main/java/com/project/task/mapper/TaskMapper.java

@ -30,9 +30,9 @@ public interface TaskMapper extends BaseMapper<TaskEntity> {
* 查询考试任务 * 查询考试任务
*/ */
@Select({ @Select({
"select e.id,l.name as subLineName" + "select e.id,l.name as subLineName " +
"from evaluator_task e " + "FROM evaluator_task e " +
"LEFT join evaluator_product_line l on e.id = l.id" + "LEFT join evaluator_product_line l on e.sub_line_id = l.id " +
"where l.leaf = 1 and l.name LIKE CONCAT('%', #{subLineName}, '%')" "where l.leaf = 1 and l.name LIKE CONCAT('%', #{subLineName}, '%')"
}) })
List<TaskDTO> getTaskBySubLineName(@Param("subLineName") String subLineName); List<TaskDTO> getTaskBySubLineName(@Param("subLineName") String subLineName);

Loading…
Cancel
Save