Explorar el Código

质控创建包括审核已完成,差质控递交

Huanyi hace 3 meses
padre
commit
fccaa1801f
Se han modificado 28 ficheros con 407 adiciones y 38 borrados
  1. 1 1
      ruoyi-admin/src/main/resources/i18n/messages_en_US.properties
  2. 1 1
      ruoyi-admin/src/main/resources/i18n/messages_zh_CN.properties
  3. 1 1
      ruoyi-common/yingpaipay-common-document/src/main/java/com/yingpaipay/common/file/util/PdfUtils.java
  4. 2 2
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/constant/FolderTypeConst.java
  5. 11 0
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/controller/DocumentQcTaskDetailController.java
  6. 10 4
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/controller/TaskCenterController.java
  7. 2 2
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/controller/WpsController.java
  8. 1 1
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/domain/DocumentQcTaskLog.java
  9. 24 0
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/domain/bo/DocumentQcAuditBo.java
  10. 16 0
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/domain/bo/TaskCenterQcListBo.java
  11. 1 7
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/domain/excel/ProjectExcel.java
  12. 18 0
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/domain/excel/SearchChineseExcel.java
  13. 18 0
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/domain/excel/SearchEnglishExcel.java
  14. 1 0
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/domain/excel/SearchExcel.java
  15. 2 1
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/domain/vo/DocumentQcTaskLogVo.java
  16. 1 0
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/domain/vo/DocumentQcTaskVo.java
  17. 37 0
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/domain/vo/TaskCenterQcListVo.java
  18. 5 0
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/enumeration/DocumentQcStatusEnum.java
  19. 7 0
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/service/IDocumentQcTaskDetailService.java
  20. 3 0
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/service/IDocumentQcTaskService.java
  21. 48 0
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/service/impl/CommonDocumentService.java
  22. 1 1
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/service/impl/CommonFolderService.java
  23. 19 0
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/service/impl/CommonProjectService.java
  24. 131 4
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/service/impl/DocumentQcTaskDetailServiceImpl.java
  25. 33 7
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/service/impl/DocumentQcTaskServiceImpl.java
  26. 7 0
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/service/impl/DocumentServiceImpl.java
  27. 5 5
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/service/impl/ProjectServiceImpl.java
  28. 1 1
      ruoyi-modules/yingpaipay-setting/src/main/java/com/yingpaipay/setting/service/impl/CarouselSettingServiceImpl.java

+ 1 - 1
ruoyi-admin/src/main/resources/i18n/messages_en_US.properties

@@ -92,7 +92,7 @@ document.document.temp.specify.nowhere=No missing files or folders were specifie
 document.qc.taskdetail.notask=There are no tasks can schedule.
 document.qc.taskisinitializing=The current project has tasks that are currently in the initialization stage.
 
-search.temp=Temporary Folder
+search.temp=Pending Archiving Area
 
 textin.networkerror=Network error.
 textin.recognitionfail=Recognition failed.

+ 1 - 1
ruoyi-admin/src/main/resources/i18n/messages_zh_CN.properties

@@ -92,7 +92,7 @@ document.document.temp.specify.nowhere=未指定任何缺失文件或文件夹
 document.qc.taskdetail.notask=没有任务可以执行
 document.qc.taskisinitializing=当前项目已有任务正在初始化
 
-search.temp=临时文件夹
+search.temp=待归档区
 
 textin.networkerror=网络异常
 textin.recognitionfail=识别失败

+ 1 - 1
ruoyi-common/yingpaipay-common-document/src/main/java/com/yingpaipay/common/file/util/PdfUtils.java

@@ -67,7 +67,7 @@ public class PdfUtils {
             throw new IllegalArgumentException("Base64 PDF list is empty or null");
         }
 
-        // TODO 验证每个文件是否存在且可读
+        // 验证每个文件是否存在且可读
         for (File file : files) {
             if (file == null || !file.exists() || !file.isFile()) {
                 throw new IllegalArgumentException("Invalid PDF file: " + (file != null ? file.getAbsolutePath() : "null"));

+ 2 - 2
ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/constant/FolderTypeConst.java

@@ -3,9 +3,9 @@ package com.yingpaipay.business.constant;
 public interface FolderTypeConst {
 
     Integer NORMAL = 0;
-
     Integer COUNTRY = 1;
-
     Integer CENTER = 2;
 
+    Long UN_UPLOAD = 0L;
+
 }

+ 11 - 0
ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/controller/DocumentQcTaskDetailController.java

@@ -1,12 +1,16 @@
 package com.yingpaipay.business.controller;
 
 
+import cn.dev33.satoken.annotation.SaCheckPermission;
+import com.yingpaipay.business.domain.bo.DocumentQcAuditBo;
 import com.yingpaipay.business.domain.bo.DocumentQcTaskDetailListBo;
 import com.yingpaipay.business.domain.vo.DocumentQcGenerateVo;
 import com.yingpaipay.business.domain.vo.DocumentQcTaskDetailListVo;
 import com.yingpaipay.business.domain.vo.DocumentQcTaskDetailVo;
 import lombok.RequiredArgsConstructor;
 import org.dromara.common.core.domain.R;
+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.springframework.web.bind.annotation.*;
@@ -41,4 +45,11 @@ public class DocumentQcTaskDetailController extends BaseController {
         return documentQcTaskDetailService.listPage(bo, pageQuery);
     }
 
+    @SaCheckPermission("qc:task:audit")
+    @Log(title = "文档指控细节", businessType = BusinessType.UPDATE)
+    @PutMapping("/audit")
+    public R<Void> audit(@RequestBody DocumentQcAuditBo bo) {
+        return toAjax(documentQcTaskDetailService.audit(bo));
+    }
+
 }

+ 10 - 4
ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/controller/TaskCenterController.java

@@ -2,10 +2,9 @@ package com.yingpaipay.business.controller;
 
 import cn.dev33.satoken.annotation.SaCheckPermission;
 import com.yingpaipay.business.domain.bo.*;
-import com.yingpaipay.business.domain.vo.DocumentAuditLogVo;
-import com.yingpaipay.business.domain.vo.TaskCenterAuditListVo;
-import com.yingpaipay.business.domain.vo.TaskCenterFilingListVo;
-import com.yingpaipay.business.domain.vo.TaskCenterSubmissionListVo;
+import com.yingpaipay.business.domain.vo.*;
+import com.yingpaipay.business.service.IDocumentQcTaskDetailService;
+import com.yingpaipay.business.service.IDocumentQcTaskService;
 import com.yingpaipay.business.service.IDocumentService;
 import lombok.RequiredArgsConstructor;
 import org.dromara.common.core.domain.R;
@@ -23,6 +22,7 @@ import org.springframework.web.bind.annotation.*;
 public class TaskCenterController extends BaseController {
 
     private final IDocumentService documentService;
+    private final IDocumentQcTaskDetailService qcTaskDetailService;
 
     @SaCheckPermission("taskCenter:submission:list")
     @GetMapping("/submission/list")
@@ -76,4 +76,10 @@ public class TaskCenterController extends BaseController {
         return toAjax(documentService.filing(bo));
     }
 
+    @SaCheckPermission("taskCenter:qc:list")
+    @GetMapping("/qc/list")
+    public TableDataInfo<TaskCenterQcListVo> listQc(TaskCenterQcListBo bo, PageQuery pageQuery) {
+        return qcTaskDetailService.listOnTaskCenter(bo, pageQuery);
+    }
+
 }

+ 2 - 2
ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/controller/WpsController.java

@@ -72,7 +72,7 @@ public class WpsController extends BaseController {
                 }
             }
 
-            // TODO 防止自增ID过早炸掉,这里采用更新操作,不使用自带的图片上传
+            // 防止自增ID过早炸掉,这里采用更新操作,不使用自带的图片上传
             String originalfileName = tempFile.getName();
             String suffix = StringUtils.substring(originalfileName, originalfileName.lastIndexOf("."));
             OssClient storage = OssFactory.instance();
@@ -83,7 +83,7 @@ public class WpsController extends BaseController {
                 if (Objects.equals(version.getVersion(), Long.valueOf(ids[1]))) {
 
                     // FIXME 由于原始版本不能被删除,暂时先不实现: 每新增一个版本,就将原始版本上传一个全新的版本
-//                    // TODO 旧的版本可以不需要了,只需要新的版本
+                    // 旧的版本可以不需要了,只需要新的版本
 //                    storage.delete(version.getUrl());
 
                     version.setFileName(uploadResult.getFilename());

+ 1 - 1
ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/domain/DocumentQcTaskLog.java

@@ -62,7 +62,7 @@ public class DocumentQcTaskLog extends TenantEntity {
     /**
      * 质控意见
      */
-    private String option;
+    private String opinion;
 
     /**
      * 指定处理人

+ 24 - 0
ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/domain/bo/DocumentQcAuditBo.java

@@ -0,0 +1,24 @@
+package com.yingpaipay.business.domain.bo;
+
+import lombok.Data;
+
+import java.util.Date;
+
+@Data
+public class DocumentQcAuditBo {
+
+    private Long taskId;
+
+    private Long detailId;
+
+    private Integer result;
+
+    private String rejectionType;
+
+    private String opinion;
+
+    private Long designatedDealer;
+
+    private Date deadline;
+
+}

+ 16 - 0
ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/domain/bo/TaskCenterQcListBo.java

@@ -0,0 +1,16 @@
+package com.yingpaipay.business.domain.bo;
+
+import lombok.Data;
+
+@Data
+public class TaskCenterQcListBo {
+
+    private String taskName;
+
+    private String projectName;
+
+    private String documentName;
+
+    private Integer status;
+
+}

+ 1 - 7
ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/domain/excel/ProjectExcel.java

@@ -2,14 +2,8 @@ package com.yingpaipay.business.domain.excel;
 
 import lombok.Data;
 
-import java.io.Serial;
-import java.io.Serializable;
-
 @Data
-public class ProjectExcel implements Serializable {
-
-    @Serial
-    private static final long serialVersionUID = 1L;
+public class ProjectExcel {
 
     private Long id;
 

+ 18 - 0
ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/domain/excel/SearchChineseExcel.java

@@ -0,0 +1,18 @@
+package com.yingpaipay.business.domain.excel;
+
+import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+
+@Data
+@ExcelIgnoreUnannotated
+@AutoMapper(target = SearchExcel.class)
+public class SearchChineseExcel implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+}

+ 18 - 0
ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/domain/excel/SearchEnglishExcel.java

@@ -0,0 +1,18 @@
+package com.yingpaipay.business.domain.excel;
+
+import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+
+@Data
+@ExcelIgnoreUnannotated
+@AutoMapper(target = SearchExcel.class)
+public class SearchEnglishExcel implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+}

+ 1 - 0
ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/domain/excel/SearchExcel.java

@@ -4,4 +4,5 @@ import lombok.Data;
 
 @Data
 public class SearchExcel {
+
 }

+ 2 - 1
ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/domain/vo/DocumentQcTaskLogVo.java

@@ -46,6 +46,7 @@ public class DocumentQcTaskLogVo implements Serializable {
     /**
      * 执行人
      */
+    @Translation(type = TransConstant.USER_ID_TO_NICKNAME, mapper = "executor")
     private Long executor;
 
     /**
@@ -66,7 +67,7 @@ public class DocumentQcTaskLogVo implements Serializable {
     /**
      * 质控意见
      */
-    private String option;
+    private String opinion;
 
     /**
      * 指定处理人

+ 1 - 0
ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/domain/vo/DocumentQcTaskVo.java

@@ -46,6 +46,7 @@ public class DocumentQcTaskVo implements Serializable {
      */
     @ExcelProperty(value = "发起人")
     @Translation(type = TransConstant.USER_ID_TO_NICKNAME, mapper = "initiator")
+    private String initiatorName;
     private Long initiator;
 
     /**

+ 37 - 0
ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/domain/vo/TaskCenterQcListVo.java

@@ -0,0 +1,37 @@
+package com.yingpaipay.business.domain.vo;
+
+import lombok.Data;
+import org.dromara.common.translation.annotation.Translation;
+import org.dromara.common.translation.constant.TransConstant;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.util.Date;
+
+@Data
+public class TaskCenterQcListVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    private Long id;
+
+    private String name;
+
+    private String projectName;
+
+    private Integer status;
+
+    @Translation(type = TransConstant.USER_ID_TO_NICKNAME, mapper = "initiator")
+    private Long initiator;
+
+    @Translation(type = TransConstant.USER_ID_TO_NICKNAME, mapper = "executor")
+    private Long executor;
+
+    private String note;
+
+    private Date executeTime;
+
+    private Date createTime;
+
+}

+ 5 - 0
ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/enumeration/DocumentQcStatusEnum.java

@@ -4,6 +4,8 @@ import lombok.AccessLevel;
 import lombok.AllArgsConstructor;
 import lombok.Getter;
 
+import java.util.Objects;
+
 @Getter
 @AllArgsConstructor(access = AccessLevel.PRIVATE)
 public enum DocumentQcStatusEnum {
@@ -17,4 +19,7 @@ public enum DocumentQcStatusEnum {
     private final String textZh;
     private final String textEn;
 
+    public static boolean pass(Integer result) {
+        return Objects.equals(PASS.code, result);
+    }
 }

+ 7 - 0
ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/service/IDocumentQcTaskDetailService.java

@@ -1,8 +1,11 @@
 package com.yingpaipay.business.service;
 
+import com.yingpaipay.business.domain.bo.DocumentQcAuditBo;
 import com.yingpaipay.business.domain.bo.DocumentQcTaskDetailListBo;
+import com.yingpaipay.business.domain.bo.TaskCenterQcListBo;
 import com.yingpaipay.business.domain.vo.DocumentQcGenerateVo;
 import com.yingpaipay.business.domain.vo.DocumentQcTaskDetailListVo;
+import com.yingpaipay.business.domain.vo.TaskCenterQcListVo;
 import org.dromara.common.mybatis.core.page.PageQuery;
 import org.dromara.common.mybatis.core.page.TableDataInfo;
 
@@ -20,4 +23,8 @@ public interface IDocumentQcTaskDetailService {
     List<DocumentQcGenerateVo> generate(Long projectId);
 
     TableDataInfo<DocumentQcTaskDetailListVo> listPage(DocumentQcTaskDetailListBo bo, PageQuery pageQuery);
+
+    boolean audit(DocumentQcAuditBo bo);
+
+    TableDataInfo<TaskCenterQcListVo> listOnTaskCenter(TaskCenterQcListBo bo, PageQuery pageQuery);
 }

+ 3 - 0
ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/service/IDocumentQcTaskService.java

@@ -1,7 +1,9 @@
 package com.yingpaipay.business.service;
 
 import com.yingpaipay.business.domain.bo.DocumentQcTaskBo;
+import com.yingpaipay.business.domain.bo.TaskCenterQcListBo;
 import com.yingpaipay.business.domain.vo.DocumentQcTaskVo;
+import com.yingpaipay.business.domain.vo.TaskCenterQcListVo;
 import org.dromara.common.mybatis.core.page.TableDataInfo;
 import org.dromara.common.mybatis.core.page.PageQuery;
 
@@ -67,4 +69,5 @@ public interface IDocumentQcTaskService {
     Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
 
     boolean start(Long id);
+
 }

+ 48 - 0
ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/service/impl/CommonDocumentService.java

@@ -74,4 +74,52 @@ public class CommonDocumentService {
                 .like(StringUtils.isNotBlank(name), Document::getName, name)
         );
     }
+
+    public boolean updateByIds(List<Document> documents) {
+        return !baseMapper.updateById(documents).isEmpty();
+    }
+
+    public List<Document> selectByFolderIds(List<Long> folderIds) {
+        if (folderIds.isEmpty()) {
+            return Collections.emptyList();
+        }
+        return baseMapper.selectList(
+            Wrappers.lambdaQuery(Document.class)
+                .in(Document::getFolderId, folderIds)
+        );
+    }
+
+    public boolean deleteByIds(List<Long> documentIds) {
+        return baseMapper.deleteByIds(documentIds) > 0;
+    }
+
+    public boolean updateStatusByIds(List<Long> documentIds, DocumentStatusEnum status) {
+        if (documentIds.isEmpty()) {
+            return true;
+        }
+        return baseMapper.update(
+            Wrappers.lambdaUpdate(Document.class)
+                .in(Document::getId, documentIds)
+                .set(Document::getStatus, status.getValue())
+        ) > 0;
+    }
+
+    public Document selectById(Long documentId) {
+        return baseMapper.selectById(documentId);
+    }
+
+    public boolean updateById(Document document) {
+        return baseMapper.updateById(document) > 0;
+    }
+
+    public List<Document> selectByName(String name, List<Long> projectIds) {
+        if (projectIds.isEmpty()) {
+            return Collections.emptyList();
+        }
+        return baseMapper.selectList(
+            Wrappers.lambdaQuery(Document.class)
+                .like(StringUtils.isNotBlank(name), Document::getName, name)
+                .in(Document::getProjectId, projectIds)
+        );
+    }
 }

+ 1 - 1
ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/service/impl/CommonFolderService.java

@@ -45,7 +45,7 @@ public class CommonFolderService {
                 for (Folder folder : folders) {
                     centerIds.add(folder.getId());
                 }
-            } else {
+            } else if (!e.getFolders().isEmpty()) {
                 centerIds.addAll(Arrays.stream(e.getFolders().split(",")).map(Long::valueOf).toList());
             }
         });

+ 19 - 0
ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/service/impl/CommonProjectService.java

@@ -83,4 +83,23 @@ public class CommonProjectService {
                 .in(Project::getId, ids)
         );
     }
+
+    public List<Project> queryListByName(String name) {
+
+        SysUserProjects projects = userProjectsMapper.selectOne(Wrappers.lambdaQuery(SysUserProjects.class).eq(SysUserProjects::getUserId, LoginHelper.getUserId()));
+        if (projects == null) {
+            return Collections.emptyList();
+        }
+        if (projects.getProjects().isEmpty()) {
+            return Collections.emptyList();
+        }
+
+        List<Long> projectIds = Arrays.stream(projects.getProjects().split(",")).map(Long::valueOf).toList();
+
+        return baseMapper.selectList(
+            Wrappers.lambdaQuery(Project.class)
+                .in(Project::getId, projectIds)
+                .like(StringUtils.isNotBlank(name), Project::getName, name)
+        );
+    }
 }

+ 131 - 4
ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/service/impl/DocumentQcTaskDetailServiceImpl.java

@@ -5,11 +5,18 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
-import com.yingpaipay.business.domain.Document;
-import com.yingpaipay.business.domain.DocumentQcTaskDetail;
+import com.yingpaipay.business.constant.QcTaskStatusConst;
+import com.yingpaipay.business.domain.*;
+import com.yingpaipay.business.domain.bo.DocumentQcAuditBo;
 import com.yingpaipay.business.domain.bo.DocumentQcTaskDetailListBo;
+import com.yingpaipay.business.domain.bo.TaskCenterQcListBo;
 import com.yingpaipay.business.domain.vo.DocumentQcGenerateVo;
 import com.yingpaipay.business.domain.vo.DocumentQcTaskDetailListVo;
+import com.yingpaipay.business.domain.vo.TaskCenterQcListVo;
+import com.yingpaipay.business.enumeration.DocumentQcStatusEnum;
+import com.yingpaipay.business.enumeration.DocumentStatusEnum;
+import com.yingpaipay.business.mapper.DocumentQcTaskLogMapper;
+import com.yingpaipay.business.mapper.DocumentQcTaskMapper;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.dromara.common.core.exception.BusinessException;
@@ -17,6 +24,8 @@ import org.dromara.common.core.utils.MessageUtils;
 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.common.tenant.helper.TenantHelper;
 import org.dromara.system.domain.SysUser;
 import org.dromara.system.domain.vo.SysUserVo;
 import org.dromara.system.service.ISysUserService;
@@ -39,8 +48,11 @@ import java.util.*;
 public class DocumentQcTaskDetailServiceImpl implements IDocumentQcTaskDetailService {
 
     private final DocumentQcTaskDetailMapper baseMapper;
+    private final DocumentQcTaskLogMapper logMapper;
+    private final DocumentQcTaskMapper taskMapper;
 
     private final CommonDocumentService documentService;
+    private final CommonProjectService projectService;
     private final ISysUserService userService;
 
     /**
@@ -88,7 +100,6 @@ public class DocumentQcTaskDetailServiceImpl implements IDocumentQcTaskDetailSer
             result.add(vo);
         }
 
-        // TODO 不能创建空的质控任务
         if (result.isEmpty()) {
             throw new BusinessException("当前没有文档需要进行质控");
         }
@@ -109,11 +120,12 @@ public class DocumentQcTaskDetailServiceImpl implements IDocumentQcTaskDetailSer
         return TableDataInfo.build(page.convert(e -> {
             DocumentQcTaskDetailListVo vo = new DocumentQcTaskDetailListVo();
             vo.setId(e.getId());
-            Document document = documentMap.get(e.getDocumentId());
 
+            Document document = documentMap.get(e.getDocumentId());
             vo.setDocument(document.getId());
             vo.setDocumentName(document.getName());
             vo.setActualDocument(document.getActualDocument());
+
             vo.setExecutor(e.getExecutor());
             vo.setStatus(e.getStatus());
             vo.setNote(e.getNote());
@@ -123,6 +135,121 @@ public class DocumentQcTaskDetailServiceImpl implements IDocumentQcTaskDetailSer
         }));
     }
 
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public boolean audit(DocumentQcAuditBo bo) {
+
+        DocumentQcTaskDetail detail = baseMapper.selectById(bo.getDetailId());
+        Document document = documentService.selectById(detail.getDocumentId());
+        DocumentQcTaskLog log = new DocumentQcTaskLog();
+        log.setTaskId(detail.getTaskId());
+        log.setDetailId(detail.getId());
+        log.setExecutor(LoginHelper.getUserId());
+        log.setExecuteTime(new Date());
+        log.setResult(bo.getResult());
+        log.setQuestionType(bo.getRejectionType());
+        log.setOpinion(bo.getOpinion());
+        log.setDesignatedDealer(bo.getDesignatedDealer());
+        log.setDeadline(bo.getDeadline());
+        log.setTenantId(TenantHelper.getTenantId());
+
+        detail.setStatus(bo.getResult());
+        detail.setExecutionTime(new Date());
+
+        if (DocumentQcStatusEnum.pass(bo.getResult())) {
+            detail.setFinishTime(new Date());
+            document.setStatus(DocumentStatusEnum.QC_PASS.getValue());
+
+        } else {
+            document.setStatus(DocumentStatusEnum.QC_REJECT.getValue());
+        }
+
+        boolean detailFlag = baseMapper.updateById(detail) == 0;
+        if (detailFlag) {
+            throw new RuntimeException("修改质控细节失败");
+        }
+
+        boolean documentFlag = documentService.updateById(document);
+        if (!documentFlag) {
+            throw new RuntimeException("修改文档状态失败");
+        }
+
+        boolean logFlag = logMapper.insert(log) == 0;
+        if (logFlag) {
+            throw new RuntimeException("新增日志失败");
+        }
+
+        long count = baseMapper.selectCount(Wrappers.lambdaQuery(DocumentQcTaskDetail.class).eq(DocumentQcTaskDetail::getTaskId, detail.getTaskId()).ne(DocumentQcTaskDetail::getStatus, DocumentQcStatusEnum.PASS.getCode()));
+        if (count == 0) {
+            boolean taskFlag = taskMapper.update(Wrappers.lambdaUpdate(DocumentQcTask.class).eq(DocumentQcTask::getId, detail.getTaskId()).set(DocumentQcTask::getStatus, QcTaskStatusConst.FINISHED)) == 0;
+            if (taskFlag) {
+                throw new RuntimeException("更新质控任务状态失败");
+            }
+        }
+
+        return true;
+    }
+
+    @Override
+    public TableDataInfo<TaskCenterQcListVo> listOnTaskCenter(TaskCenterQcListBo bo, PageQuery pageQuery) {
+
+        List<Long> taskIds = new ArrayList<>();
+        List<Long> projectIds = new ArrayList<>();
+        Map<Long, DocumentQcTask> taskMap = new HashMap<>();
+        Map<Long, String> projectMap = new HashMap<>();
+        taskMapper.selectList(Wrappers.lambdaQuery(DocumentQcTask.class).like(StringUtils.isNotBlank(bo.getTaskName()), DocumentQcTask::getName, bo.getTaskName()))
+            .forEach(e -> {
+                taskIds.add(e.getId());
+                taskMap.put(e.getId(), e);
+            });
+        projectService.queryListByName(bo.getProjectName())
+            .forEach(e -> {
+                projectIds.add(e.getId());
+                projectMap.put(e.getId(), e.getName());
+            });
+
+        IPage<DocumentQcTaskDetail> page = baseMapper.selectPage(
+            pageQuery.build(),
+            buildListOnTaskCenterWrapper(bo, taskIds, projectIds)
+        );
+
+        return TableDataInfo.build(page.convert(e -> {
+            TaskCenterQcListVo vo = new TaskCenterQcListVo();
+            vo.setId(e.getId());
+            DocumentQcTask task = taskMap.get(e.getTaskId());
+            vo.setName(task.getName());
+            vo.setProjectName(projectMap.get(e.getProjectId()));
+            vo.setStatus(e.getStatus());
+            vo.setInitiator(task.getInitiator());
+            vo.setExecutor(e.getExecutor());
+            vo.setNote(e.getNote());
+            vo.setExecuteTime(e.getExecutionTime());
+            vo.setCreateTime(e.getCreateTime());
+            return vo;
+        }));
+    }
+
+    private LambdaQueryWrapper<DocumentQcTaskDetail> buildListOnTaskCenterWrapper(TaskCenterQcListBo bo, List<Long> taskIds, List<Long> projectIds) {
+
+        LambdaQueryWrapper<DocumentQcTaskDetail> wrapper = Wrappers.lambdaQuery(DocumentQcTaskDetail.class)
+            .eq(bo.getStatus() != null, DocumentQcTaskDetail::getStatus, bo.getStatus())
+            .orderByDesc(DocumentQcTaskDetail::getId);
+
+        if (StringUtils.isNotBlank(bo.getTaskName())) {
+            wrapper.in(DocumentQcTaskDetail::getTaskId, taskIds.isEmpty() ? List.of(-1L) : taskIds);
+        }
+
+        wrapper.in(StringUtils.isNotBlank(bo.getProjectName()), DocumentQcTaskDetail::getProjectId, projectIds.isEmpty() ? List.of(-1L) : projectIds);
+
+        if (StringUtils.isNotBlank(bo.getDocumentName())) {
+            List<Long> documentIds = new ArrayList<>();
+            documentService.selectByName(bo.getDocumentName(), projectIds).forEach(e -> documentIds.add(e.getId()));
+            wrapper.in(DocumentQcTaskDetail::getDocumentId, documentIds.isEmpty() ? List.of(-1L) : documentIds);
+        }
+
+        return wrapper;
+    }
+
     private LambdaQueryWrapper<DocumentQcTaskDetail> buildListPageWrapper(DocumentQcTaskDetailListBo bo, List<Long> documentIds) {
 
         return Wrappers.lambdaQuery(DocumentQcTaskDetail.class)

+ 33 - 7
ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/service/impl/DocumentQcTaskServiceImpl.java

@@ -8,8 +8,11 @@ import com.yingpaipay.business.constant.QcTaskStatusConst;
 import com.yingpaipay.business.domain.Document;
 import com.yingpaipay.business.domain.DocumentQcTask;
 import com.yingpaipay.business.domain.DocumentQcTaskDetail;
+import com.yingpaipay.business.domain.Folder;
 import com.yingpaipay.business.domain.bo.DocumentQcTaskBo;
+import com.yingpaipay.business.domain.bo.TaskCenterQcListBo;
 import com.yingpaipay.business.domain.vo.DocumentQcTaskVo;
+import com.yingpaipay.business.domain.vo.TaskCenterQcListVo;
 import com.yingpaipay.business.enumeration.DocumentStatusEnum;
 import com.yingpaipay.business.mapper.DocumentQcTaskDetailMapper;
 import org.dromara.common.core.exception.BusinessException;
@@ -49,13 +52,12 @@ public class DocumentQcTaskServiceImpl implements IDocumentQcTaskService {
     private final DocumentQcTaskDetailMapper detailMapper;
 
     private final CommonProjectService projectService;
+    private final CommonFolderService folderService;
     private final CommonDocumentService documentService;
     private final ISysUserService userService;
 
     private final LockTemplate lockTemplate;
 
-//    private static final Map<Long, Object> TASK_LOCK = new ConcurrentHashMap<>();
-
     /**
      * 查询文档质控任务
      *
@@ -171,7 +173,7 @@ public class DocumentQcTaskServiceImpl implements IDocumentQcTaskService {
         }
 
         /**
-         * TODO 避免同一个文件反复参与质控
+         * 避免同一个文件反复参与质控
          * FIXME 需要思考一个更好的方案,尽可能避免所有操作全部串行化
          */
         LockInfo lock = lockTemplate.lock("qc:" + bo.getProjectId(), 30000L, 5000L, RedissonLockExecutor.class);
@@ -188,7 +190,15 @@ public class DocumentQcTaskServiceImpl implements IDocumentQcTaskService {
                     .eq(DocumentQcTaskDetail::getProjectId, bo.getProjectId())
             ).forEach(e -> historyIds.add(e.getDocumentId()));
 
-            List<Document> documents = documentService.selectByProjectId(bo.getProjectId());
+            List<Long> folderIds = new ArrayList<>();
+            folderService.queryByProjectIds(List.of(bo.getProjectId())).forEach(e -> folderIds.add(e.getId()));
+
+            List<Document> documents = documentService.selectByFolderIds(folderIds);
+
+            if (documents.isEmpty()) {
+                throw new BusinessException(MessageUtils.message("document.qc.taskdetail.notask"));
+            }
+
             selectedDocuments = documents.stream()
                 .filter(e -> e.getStatus().equals(DocumentStatusEnum.ARCHIEVED.getValue()))
                 .filter(e -> !historyIds.contains(e.getId()))
@@ -196,10 +206,13 @@ public class DocumentQcTaskServiceImpl implements IDocumentQcTaskService {
             if (selectedDocuments.isEmpty()) {
                 throw new BusinessException(MessageUtils.message("document.qc.taskdetail.notask"));
             }
-            Collections.shuffle(selectedDocuments, new Random((long) documents.size() * bo.getProportion() / 100));
+            long count = (long) bo.getProportion() * selectedDocuments.size() / 100;
+            Collections.shuffle(selectedDocuments, new Random(count));
+            selectedDocuments = selectedDocuments.subList(0, (int) count);
 
             List<DocumentQcTaskDetail> details = new ArrayList<>();
             selectedDocuments.forEach(e -> {
+                e.setStatus(DocumentStatusEnum.UN_QC.getValue());
                 DocumentQcTaskDetail detail = new DocumentQcTaskDetail();
                 detail.setTaskId(add.getId());
                 detail.setDocumentId(e.getId());
@@ -213,6 +226,11 @@ public class DocumentQcTaskServiceImpl implements IDocumentQcTaskService {
             if (!flag) {
                 throw new RuntimeException("批量插入失败");
             }
+
+            boolean statusFlag = documentService.updateByIds(documents);
+            if (!statusFlag) {
+                throw new RuntimeException("批量修改状态失败");
+            }
         } finally {
             lockTemplate.releaseLock(lock);
         }
@@ -258,14 +276,22 @@ public class DocumentQcTaskServiceImpl implements IDocumentQcTaskService {
             throw new RuntimeException("删除主任务失败");
         }
 
-        boolean detailFlag = detailMapper.delete(
+        List<DocumentQcTaskDetail> details = detailMapper.selectList(
             Wrappers.lambdaQuery(DocumentQcTaskDetail.class)
                 .in(DocumentQcTaskDetail::getTaskId, ids)
-        ) == 0;
+        );
+
+        boolean detailFlag = detailMapper.deleteByIds(details) == 0;
         if (detailFlag) {
             throw new RuntimeException("删除细节失败");
         }
 
+        List<Long> documentIds = details.stream().map(DocumentQcTaskDetail::getDocumentId).toList();
+        boolean documentFlag = documentService.updateStatusByIds(documentIds, DocumentStatusEnum.ARCHIEVED);
+        if (!documentFlag) {
+            throw new RuntimeException("批量修改文档状态失败");
+        }
+
         return true;
     }
 

+ 7 - 0
ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/service/impl/DocumentServiceImpl.java

@@ -167,6 +167,12 @@ public class DocumentServiceImpl implements IDocumentService {
             Document::getCreateTime, params.get("beginCreateTime"), params.get("endCreateTime"));
         lqw.between(params.get("beginUpdateTime") != null && params.get("endUpdateTime") != null,
             Document::getUpdateTime, params.get("beginUpdateTime"), params.get("endUpdateTime"));
+
+        // 如果为待归档,那么就只能看到自己的上传的
+        if (bo.getFolderId().equals(FolderTypeConst.UN_UPLOAD)) {
+            lqw.eq(Document::getCreateBy, LoginHelper.getUserId());
+        }
+
         return lqw;
     }
 
@@ -1008,6 +1014,7 @@ public class DocumentServiceImpl implements IDocumentService {
 
     private LambdaQueryWrapper<Document> buildSpecifyListWrapper(DocumentListOnSpecifyBo bo, List<Long> folderIds) {
         return Wrappers.lambdaQuery(Document.class)
+            .eq(Document::getCreateBy, LoginHelper.getUserId())
             .in(Document::getFolderId, folderIds.isEmpty() ? List.of(-1L) : folderIds)
             .like(StringUtils.isNotBlank(bo.getName()), Document::getName, bo.getName())
             .in(Document::getStatus, List.of(DocumentStatusEnum.UN_UPLOAD.getValue(), DocumentStatusEnum.AUDIT_REJECT.getValue()))

+ 5 - 5
ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/service/impl/ProjectServiceImpl.java

@@ -129,7 +129,7 @@ public class ProjectServiceImpl implements IProjectService {
         lqw.between(params.get("beginUpdateTime") != null && params.get("endUpdateTime") != null,
             Project::getUpdateTime, params.get("beginUpdateTime"), params.get("endUpdateTime"));
 
-        // TODO 只有拥有该项目数据权限的人才能够在列表中看到该项目
+        // 只有拥有该项目数据权限的人才能够在列表中看到该项目
         String projects = userProjectsMapper.selectOne(
             Wrappers.lambdaQuery(SysUserProjects.class)
                 .eq(SysUserProjects::getUserId, LoginHelper.getUserId())
@@ -297,7 +297,7 @@ public class ProjectServiceImpl implements IProjectService {
 
     @Override
     public TableDataInfo<ProjectMemberNotInCenterVo> queryMemberNotInCenter(Long projectId, Long folderId, String name, PageQuery pageQuery) {
-        // TODO 只能是项目中的人
+        // 只能是项目中的人
         List<Long> userIdsInProject = new ArrayList<>();
         userProjectsMapper.selectList(
             Wrappers.lambdaQuery(SysUserProjects.class)
@@ -380,7 +380,7 @@ public class ProjectServiceImpl implements IProjectService {
                 }
             }
 
-            // TODO 如果 total == 0 , 那么计算两个比例的时候就会变为 NaN
+            // 如果 total == 0 , 那么计算两个比例的时候就会变为 NaN
             total = total > 0L ? total : 1L;
             vo.setOnTimeSubmissionRate(Double.valueOf(String.format("%.2f", (double) onTimeSubmit / total * 100L)));
             vo.setLateSubmissionCount(lateSubmit);
@@ -406,7 +406,7 @@ public class ProjectServiceImpl implements IProjectService {
             throw new RuntimeException("新增用户失败");
         }
 
-        // TODO 建立用户和文件夹之间的联系
+        // 建立用户和文件夹之间的联系
         SysUserFolders userFolders = new SysUserFolders();
         userFolders.setUserId(user.getUserId());
         userFolders.setFolders(bo.getFolders());
@@ -484,7 +484,7 @@ public class ProjectServiceImpl implements IProjectService {
         lqw.between(params.get("beginUpdateTime") != null && params.get("endUpdateTime") != null,
             Project::getUpdateTime, params.get("beginUpdateTime"), params.get("endUpdateTime"));
 
-        // TODO 只有拥有该项目数据权限的人才能够在列表中看到该项目
+        // 只有拥有该项目数据权限的人才能够在列表中看到该项目
         String projects = userProjectsMapper.selectOne(
             Wrappers.lambdaQuery(SysUserProjects.class)
                 .eq(SysUserProjects::getUserId, LoginHelper.getUserId())

+ 1 - 1
ruoyi-modules/yingpaipay-setting/src/main/java/com/yingpaipay/setting/service/impl/CarouselSettingServiceImpl.java

@@ -80,7 +80,7 @@ public class CarouselSettingServiceImpl implements ICarouselSettingService {
     private LambdaQueryWrapper<CarouselSetting> buildQueryWrapper(CarouselSettingBo bo) {
         Map<String, Object> params = bo.getParams();
         LambdaQueryWrapper<CarouselSetting> lqw = Wrappers.lambdaQuery();
-        // TODO 需要按排序从小到大
+        // 需要按排序从小到大
         lqw.orderByAsc(CarouselSetting::getSort);
         return lqw;
     }