Преглед изворни кода

- [x] 归档:一个确认
- [x] 交接:编辑账号
- [x] 审核环节:直接通过/驳回编辑即可
质控:
- [x] 加上完成度:进度条形式,任务为发起人自己完成质控,审核完即可,无需等重复递交
- [x] 任务只需要查看,新增时不管
- [x] 开始时间不需要,变成开始按钮
递交:只选择到中心,文件名、生效日期已输入形式
CRC: 递交人 != 计划递交人

Huanyi пре 3 месеци
родитељ
комит
481ab53284
46 измењених фајлова са 1170 додато и 211 уклоњено
  1. 0 2
      ruoyi-admin/src/main/java/com/yingpaipay/web/service/strategy/PasswordAppletAuthService.java
  2. 3 0
      ruoyi-admin/src/main/resources/i18n/messages_en_US.properties
  3. 3 0
      ruoyi-admin/src/main/resources/i18n/messages_zh_CN.properties
  4. 0 5
      ruoyi-common/yingpaipay-common-document/pom.xml
  5. 1 1
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysUserService.java
  6. 2 2
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysUserServiceImpl.java
  7. 0 21
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/constant/DocumentStatusConst.java
  8. 20 0
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/controller/DocumentController.java
  9. 37 0
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/controller/DocumentQcTaskLogController.java
  10. 33 7
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/controller/ProjectController.java
  11. 3 2
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/controller/WpsController.java
  12. 3 1
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/domain/Document.java
  13. 1 1
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/domain/DocumentAuditLog.java
  14. 94 0
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/domain/DocumentQcTaskLog.java
  15. 3 0
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/domain/bo/AppletUploadBo.java
  16. 3 0
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/domain/bo/AppletUploadOnSubmitBo.java
  17. 3 1
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/domain/bo/DocumentBo.java
  18. 12 0
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/domain/bo/DocumentListOnSpecifyBo.java
  19. 92 0
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/domain/bo/DocumentQcTaskLogBo.java
  20. 14 0
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/domain/bo/DocumentSpecifyBo.java
  21. 4 0
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/domain/bo/DocumentSubmitBo.java
  22. 64 0
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/domain/excel/ProjectChineseExcel.java
  23. 64 0
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/domain/excel/ProjectEnglishExcel.java
  24. 44 0
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/domain/excel/ProjectExcel.java
  25. 7 0
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/domain/excel/SearchExcel.java
  26. 2 11
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/domain/vo/DocumentAuditLogVo.java
  27. 35 0
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/domain/vo/DocumentListOnSpecifyVo.java
  28. 1 1
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/domain/vo/DocumentQcTaskDetailListVo.java
  29. 115 0
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/domain/vo/DocumentQcTaskLogVo.java
  30. 5 26
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/domain/vo/DocumentVo.java
  31. 0 9
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/domain/vo/FolderVo.java
  32. 0 16
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/domain/vo/ProjectVo.java
  33. 2 2
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/domain/vo/TaskCenterAuditListVo.java
  34. 48 0
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/enumeration/DocumentStatusEnum.java
  35. 15 0
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/mapper/DocumentQcTaskLogMapper.java
  36. 28 0
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/service/IDocumentQcTaskLogService.java
  37. 9 0
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/service/IDocumentService.java
  38. 3 4
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/service/impl/CommonDocumentService.java
  39. 8 1
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/service/impl/CommonFolderService.java
  40. 1 1
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/service/impl/CommonProjectService.java
  41. 4 3
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/service/impl/DocumentQcTaskDetailServiceImpl.java
  42. 74 0
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/service/impl/DocumentQcTaskLogServiceImpl.java
  43. 21 21
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/service/impl/DocumentQcTaskServiceImpl.java
  44. 263 49
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/service/impl/DocumentServiceImpl.java
  45. 3 3
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/service/impl/ProjectServiceImpl.java
  46. 23 21
      script/sql/business/create.sql

+ 0 - 2
ruoyi-admin/src/main/java/com/yingpaipay/web/service/strategy/PasswordAppletAuthService.java

@@ -29,8 +29,6 @@ import java.util.List;
 /**
  * @Author: Huanyi
  * @CreateTime: 2025-12-04
- * @Description:
- * @Version: 1.0
  */
 
 @Service

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

@@ -87,7 +87,10 @@ document.document.download.notfound=The document is not found.
 document.document.uploadempty=The document you upload should not be empty.
 document.document.cannotparseusablepdf=No valid PDF file was parsed.
 
+document.document.temp.specify.nowhere=No missing files or folders were specified.
+
 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
 

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

@@ -87,7 +87,10 @@ document.document.download.notfound=所属文档未找到
 document.document.uploadempty=提交的文件列表为空
 document.document.cannotparseusablepdf=未解析到有效的 PDF 文件数据
 
+document.document.temp.specify.nowhere=未指定任何缺失文件或文件夹
+
 document.qc.taskdetail.notask=没有任务可以执行
+document.qc.taskisinitializing=当前项目已有任务正在初始化
 
 search.temp=临时文件夹
 

+ 0 - 5
ruoyi-common/yingpaipay-common-document/pom.xml

@@ -24,11 +24,6 @@
             <version>7.2.5</version>
             <type>pom</type>
         </dependency>
-        <dependency>
-            <groupId>org.docx4j</groupId>
-            <artifactId>docx4j-core</artifactId>
-            <version>11.4.9</version>
-        </dependency>
         <dependency>
             <groupId>org.apache.poi</groupId>
             <artifactId>poi-ooxml</artifactId>

+ 1 - 1
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysUserService.java

@@ -90,7 +90,7 @@ public interface ISysUserService {
      */
     List<SysUserVo> selectUserByIds(List<Long> userIds, Long deptId);
 
-    List<SysUserVo> selectUserByIds(List<Long> userIds);
+    List<SysUser> selectUserByIds(List<Long> userIds);
 
     List<SysUserVo> selectUserVoByIds(List<Long> userIds);
 

+ 2 - 2
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysUserServiceImpl.java

@@ -217,11 +217,11 @@ public class SysUserServiceImpl implements ISysUserService, UserService {
     }
 
     @Override
-    public List<SysUserVo> selectUserByIds(List<Long> userIds) {
+    public List<SysUser> selectUserByIds(List<Long> userIds) {
         if (userIds.isEmpty()) {
             return List.of();
         }
-        return baseMapper.selectVoList(new LambdaQueryWrapper<SysUser>()
+        return baseMapper.selectList(new LambdaQueryWrapper<SysUser>()
                 .and(wrapper -> {
                     wrapper.eq(SysUser::getStatus, SystemConstants.NORMAL)
                         .or()

+ 0 - 21
ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/constant/DocumentStatusConst.java

@@ -1,21 +0,0 @@
-package com.yingpaipay.business.constant;
-
-public interface DocumentStatusConst {
-
-    Integer UN_UPLOAD = 0;
-
-    Integer UN_AUDIT = 1;
-
-    Integer AUDIT_REJECT = 2;
-
-    Integer UN_FILING = 3;
-
-    Integer FILING = 4;
-
-    Integer UN_QUALITY_CONTROL = 5;
-
-    Integer QUALITY_CONTROL_PASS = 6;
-
-    Integer QUALITY_CONTROL_REJECT = 7;
-
-}

+ 20 - 0
ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/controller/DocumentController.java

@@ -5,6 +5,7 @@ import java.util.List;
 
 import com.yingpaipay.business.domain.bo.*;
 import com.yingpaipay.business.domain.vo.DocumentAuditLogVo;
+import com.yingpaipay.business.domain.vo.DocumentListOnSpecifyVo;
 import lombok.RequiredArgsConstructor;
 import jakarta.servlet.http.HttpServletResponse;
 import jakarta.validation.constraints.*;
@@ -156,4 +157,23 @@ public class DocumentController extends BaseController {
         return R.ok(documentService.countTemp(projectId));
     }
 
+    @SaCheckPermission("document:document:removeTemp")
+    @Log(title = "文档", businessType = BusinessType.DELETE)
+    @DeleteMapping("/removeTemp/{documentId}")
+    public R<Void> removeTemp(@PathVariable Long documentId) {
+        return toAjax(documentService.removeTemp(documentId));
+    }
+
+    @SaCheckPermission("document:document:specify")
+    @Log(title = "文档", businessType = BusinessType.UPDATE)
+    @PutMapping("/specify")
+    public R<Void> specify(@RequestBody DocumentSpecifyBo bo) {
+        return toAjax(documentService.specify(bo));
+    }
+
+    @GetMapping("/listOnSpecify")
+    public TableDataInfo<DocumentListOnSpecifyVo> listOnSpecify(DocumentListOnSpecifyBo bo, PageQuery pageQuery) {
+        return documentService.listOnSpecify(bo, pageQuery);
+    }
+
 }

+ 37 - 0
ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/controller/DocumentQcTaskLogController.java

@@ -0,0 +1,37 @@
+package com.yingpaipay.business.controller;
+
+import lombok.RequiredArgsConstructor;
+import cn.dev33.satoken.annotation.SaCheckPermission;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.validation.annotation.Validated;
+import org.dromara.common.web.core.BaseController;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import com.yingpaipay.business.domain.vo.DocumentQcTaskLogVo;
+import com.yingpaipay.business.domain.bo.DocumentQcTaskLogBo;
+import com.yingpaipay.business.service.IDocumentQcTaskLogService;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+
+/**
+ * 文档质控日志
+ *
+ * @author Huanyi
+ * @date 2026-01-14
+ */
+@Validated
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/qcTask/log")
+public class DocumentQcTaskLogController extends BaseController {
+
+    private final IDocumentQcTaskLogService documentQcTaskLogService;
+
+    /**
+     * 查询文档质控日志列表
+     */
+    @SaCheckPermission("qcTask:log:list")
+    @GetMapping("/list")
+    public TableDataInfo<DocumentQcTaskLogVo> list(DocumentQcTaskLogBo bo, PageQuery pageQuery) {
+        return documentQcTaskLogService.queryPageList(bo, pageQuery);
+    }
+
+}

+ 33 - 7
ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/controller/ProjectController.java

@@ -1,16 +1,24 @@
 package com.yingpaipay.business.controller;
 
+import java.util.ArrayList;
 import java.util.List;
+import java.util.Locale;
 
 import com.yingpaipay.business.domain.bo.*;
+import com.yingpaipay.business.domain.excel.ProjectChineseExcel;
+import com.yingpaipay.business.domain.excel.ProjectEnglishExcel;
+import com.yingpaipay.business.domain.excel.ProjectExcel;
 import com.yingpaipay.business.domain.vo.*;
+import com.yingpaipay.business.service.IDocumentService;
 import com.yingpaipay.business.service.IFolderService;
 import lombok.RequiredArgsConstructor;
 import jakarta.servlet.http.HttpServletResponse;
 import jakarta.validation.constraints.*;
 import cn.dev33.satoken.annotation.SaCheckPermission;
+import org.dromara.common.core.utils.MapstructUtils;
 import org.dromara.system.domain.vo.SysUserVo;
 import org.dromara.system.service.ISysUserService;
+import org.springframework.context.i18n.LocaleContextHolder;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.validation.annotation.Validated;
 import org.dromara.common.idempotent.annotation.RepeatSubmit;
@@ -40,6 +48,7 @@ public class ProjectController extends BaseController {
     private final IProjectService projectService;
     private final IFolderService folderService;
     private final ISysUserService userService;
+    private final IDocumentService documentService;
 
     /**
      * 查询项目管理列表
@@ -53,13 +62,13 @@ public class ProjectController extends BaseController {
     /**
      * 导出项目管理列表
      */
-    @SaCheckPermission("project:management:export")
-    @Log(title = "项目管理", businessType = BusinessType.EXPORT)
-    @PostMapping("/export")
-    public void export(ProjectBo bo, HttpServletResponse response) {
-        List<ProjectVo> list = projectService.queryList(bo);
-        ExcelUtil.exportExcel(list, "项目管理", ProjectVo.class, response);
-    }
+//    @SaCheckPermission("project:management:export")
+//    @Log(title = "项目管理", businessType = BusinessType.EXPORT)
+//    @PostMapping("/export")
+//    public void export(ProjectBo bo, HttpServletResponse response) {
+//        List<ProjectVo> list = projectService.queryList(bo);
+//        ExcelUtil.exportExcel(list, "项目管理", ProjectVo.class, response);
+//    }
 
     /**
      * 获取项目管理详细信息
@@ -180,4 +189,21 @@ public class ProjectController extends BaseController {
         return R.ok(userService.getById(id));
     }
 
+    @SaCheckPermission("project:management:export")
+    @Log(title = "项目管理", businessType = BusinessType.EXPORT)
+    @PostMapping("/export/{projectId}")
+    public void export(@PathVariable Long projectId, HttpServletResponse response) {
+        List<ProjectExcel> list = documentService.getListByProjectId(projectId);
+        if (LocaleContextHolder.getLocale().getLanguage().equals("zh")) {
+            List<ProjectChineseExcel> excel = new ArrayList<>();
+            list.forEach(e -> excel.add(MapstructUtils.convert(e, ProjectChineseExcel.class)));
+            ExcelUtil.exportExcel(excel, "项目管理", ProjectChineseExcel.class, response);
+        } else {
+            List<ProjectEnglishExcel> excel = new ArrayList<>();
+            list.forEach(e -> excel.add(MapstructUtils.convert(e, ProjectEnglishExcel.class)));
+            ExcelUtil.exportExcel(excel, "Project Management", ProjectEnglishExcel.class, response);
+        }
+
+    }
+
 }

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

@@ -18,6 +18,7 @@ import org.dromara.common.oss.entity.UploadResult;
 import org.dromara.common.oss.factory.OssFactory;
 import org.dromara.common.web.core.BaseController;
 import org.dromara.system.domain.SysOssExt;
+import org.dromara.system.domain.SysUser;
 import org.dromara.system.domain.vo.SysOssVo;
 import org.dromara.system.domain.vo.SysUserVo;
 import org.dromara.system.service.ISysOssService;
@@ -223,12 +224,12 @@ public class WpsController extends BaseController {
         if (userIds == null || userIds.length == 0) {
             return WpsR.ok();
         }
-        List<SysUserVo> vos = userService.selectUserByIds(Arrays.stream(userIds).toList());
+        List<SysUser> vos = userService.selectUserByIds(Arrays.stream(userIds).toList());
         List<Long> ossIds = new ArrayList<>();
         vos.forEach(e -> ossIds.add(e.getAvatar()));
         List<SysOssVo> ossVos = ossService.queryListByIds(ossIds);
         List<WpsGetUsersDto> dtos = new ArrayList<>();
-        for (SysUserVo vo : vos) {
+        for (SysUser vo : vos) {
             String url = "";
             for (SysOssVo ossVo : ossVos) {
                 if (ossVo.getOssId().equals(vo.getAvatar())) {

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

@@ -62,7 +62,7 @@ public class Document extends TenantEntity {
     /**
      * 文档本体
      */
-    private Long ossId;
+    private Long actualDocument;
 
     /**
      * 备注
@@ -93,4 +93,6 @@ public class Document extends TenantEntity {
 
     private Date passTime;
 
+    private Date effectiveDate;
+
 }

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

@@ -22,7 +22,7 @@ public class DocumentAuditLog extends TenantEntity {
 
     private Long documentId;
 
-    private Long ossId;
+    private Long uploadVersion;
 
     private String auditorType;
 

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

@@ -0,0 +1,94 @@
+package com.yingpaipay.business.domain;
+
+import org.dromara.common.tenant.core.TenantEntity;
+import com.baomidou.mybatisplus.annotation.*;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import java.util.Date;
+import com.fasterxml.jackson.annotation.JsonFormat;
+
+import java.io.Serial;
+
+/**
+ * 文档质控日志对象 document_qc_task_log
+ *
+ * @author Huanyi
+ * @date 2026-01-14
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("document_qc_task_log")
+public class DocumentQcTaskLog extends TenantEntity {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 序号
+     */
+    @TableId(value = "id")
+    private Long id;
+
+    /**
+     * 质控任务
+     */
+    private Long taskId;
+
+    /**
+     * 指控环节
+     */
+    private Long detailId;
+
+    /**
+     * 执行人
+     */
+    private Long executor;
+
+    /**
+     * 执行时间
+     */
+    private Date executeTime;
+
+    /**
+     * 质控结果
+     */
+    private Integer result;
+
+    /**
+     * 问题分类
+     */
+    private String questionType;
+
+    /**
+     * 质控意见
+     */
+    private String option;
+
+    /**
+     * 指定处理人
+     */
+    private Long designatedDealer;
+
+    /**
+     * 处理截止日期
+     */
+    private Date deadline;
+
+    /**
+     * 实际处理人
+     */
+    private Long actualDealer;
+
+    /**
+     * 处理时间
+     */
+    private Date dealTime;
+
+    /**
+     * 删除标志(0代表存在 1代表删除)
+     */
+    @TableLogic
+    private String delFlag;
+
+
+}

+ 3 - 0
ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/domain/bo/AppletUploadBo.java

@@ -2,6 +2,7 @@ package com.yingpaipay.business.domain.bo;
 
 import lombok.Data;
 
+import java.util.Date;
 import java.util.List;
 
 @Data
@@ -15,6 +16,8 @@ public class AppletUploadBo {
 
     private String name;
 
+    private Date effectiveDate;
+
     private List<String> files;
 
 }

+ 3 - 0
ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/domain/bo/AppletUploadOnSubmitBo.java

@@ -2,11 +2,14 @@ package com.yingpaipay.business.domain.bo;
 
 import lombok.Data;
 
+import java.util.Date;
 import java.util.List;
 
 @Data
 public class AppletUploadOnSubmitBo {
 
+    private Date effectiveDate;
+
     private Long documentId;
 
     private List<String> fileBase64List;

+ 3 - 1
ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/domain/bo/DocumentBo.java

@@ -71,7 +71,7 @@ public class DocumentBo extends BaseEntity {
      * 文件本体
      * 使用文件上传逻辑,可参考系统设置中的OSS设置
      */
-    private Long ossId;
+    private Long actualDocument;
 
     /**
      * 递交时间
@@ -92,4 +92,6 @@ public class DocumentBo extends BaseEntity {
 
     private Boolean sendStatus;
 
+    private Date effectiveDate;
+
 }

+ 12 - 0
ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/domain/bo/DocumentListOnSpecifyBo.java

@@ -0,0 +1,12 @@
+package com.yingpaipay.business.domain.bo;
+
+import lombok.Data;
+
+@Data
+public class DocumentListOnSpecifyBo {
+
+    private Long projectId;
+
+    private String name;
+
+}

+ 92 - 0
ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/domain/bo/DocumentQcTaskLogBo.java

@@ -0,0 +1,92 @@
+package com.yingpaipay.business.domain.bo;
+
+import com.yingpaipay.business.domain.DocumentQcTaskLog;
+import org.dromara.common.mybatis.core.domain.BaseEntity;
+import org.dromara.common.core.validate.AddGroup;
+import org.dromara.common.core.validate.EditGroup;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import jakarta.validation.constraints.*;
+import java.util.Date;
+import com.fasterxml.jackson.annotation.JsonFormat;
+
+/**
+ * 文档质控日志业务对象 document_qc_task_log
+ *
+ * @author Huanyi
+ * @date 2026-01-14
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@AutoMapper(target = DocumentQcTaskLog.class, reverseConvertGenerate = false)
+public class DocumentQcTaskLogBo extends BaseEntity {
+
+    /**
+     * 序号
+     */
+    @NotNull(message = "序号不能为空", groups = { EditGroup.class })
+    private Long id;
+
+    /**
+     * 质控任务
+     */
+    @NotNull(message = "质控任务不能为空", groups = { AddGroup.class, EditGroup.class })
+    private Long taskId;
+
+    /**
+     * 指控环节
+     */
+    @NotNull(message = "指控环节不能为空", groups = { AddGroup.class, EditGroup.class })
+    private Long detailId;
+
+    /**
+     * 执行人
+     */
+    @NotNull(message = "执行人不能为空", groups = { AddGroup.class, EditGroup.class })
+    private Long executor;
+
+    /**
+     * 执行时间
+     */
+    @NotNull(message = "执行时间不能为空", groups = { AddGroup.class, EditGroup.class })
+    private Date executeTime;
+
+    /**
+     * 质控结果
+     */
+    @NotNull(message = "质控结果不能为空", groups = { AddGroup.class, EditGroup.class })
+    private Integer result;
+
+    /**
+     * 问题分类
+     */
+    private String questionType;
+
+    /**
+     * 质控意见
+     */
+    private String option;
+
+    /**
+     * 指定处理人
+     */
+    private Long designatedDealer;
+
+    /**
+     * 处理截止日期
+     */
+    private Date deadline;
+
+    /**
+     * 实际处理人
+     */
+    private Long actualDealer;
+
+    /**
+     * 处理时间
+     */
+    private Date dealTime;
+
+
+}

+ 14 - 0
ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/domain/bo/DocumentSpecifyBo.java

@@ -0,0 +1,14 @@
+package com.yingpaipay.business.domain.bo;
+
+import lombok.Data;
+
+@Data
+public class DocumentSpecifyBo {
+
+    private Long documentId;
+
+    private Long missingDocumentId;
+
+    private Long folderId;
+
+}

+ 4 - 0
ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/domain/bo/DocumentSubmitBo.java

@@ -2,6 +2,8 @@ package com.yingpaipay.business.domain.bo;
 
 import lombok.Data;
 
+import java.util.Date;
+
 @Data
 public class DocumentSubmitBo {
 
@@ -9,4 +11,6 @@ public class DocumentSubmitBo {
 
     private Long ossId;
 
+    private Date effectiveDate;
+
 }

+ 64 - 0
ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/domain/excel/ProjectChineseExcel.java

@@ -0,0 +1,64 @@
+package com.yingpaipay.business.domain.excel;
+
+import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
+import cn.idev.excel.annotation.ExcelProperty;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+
+@Data
+@ExcelIgnoreUnannotated
+@AutoMapper(target = ProjectExcel.class)
+public class ProjectChineseExcel implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    @ExcelProperty(value = "序号")
+    private Long id;
+
+    @ExcelProperty(value = "计划文件名称")
+    private String name;
+
+    @ExcelProperty(value = "状态")
+    private String status;
+
+    @ExcelProperty(value = "实际文件名称")
+    private String actualDocumentName;
+
+    @ExcelProperty(value = "中心编号")
+    private Long centerId;
+
+    @ExcelProperty(value = "计划递交人")
+    private String planSubmitter;
+
+    @ExcelProperty(value = "递交截止日期")
+    private String deadline;
+
+    @ExcelProperty(value = "递交逾期天数")
+    private Long daysOverdue;
+
+    @ExcelProperty(value = "文件所有人")
+    private String createBy;
+
+    @ExcelProperty(value = "文件路径")
+    private String path;
+
+    @ExcelProperty(value = "实际递交时间")
+    private String submitTime;
+
+    @ExcelProperty(value = "实际递交人")
+    private String submitter;
+
+    @ExcelProperty(value = "项目名称")
+    private String projectName;
+
+    @ExcelProperty(value = "中心名称")
+    private String centerName;
+
+    @ExcelProperty(value = "计划文件类型")
+    private String planType;
+
+}

+ 64 - 0
ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/domain/excel/ProjectEnglishExcel.java

@@ -0,0 +1,64 @@
+package com.yingpaipay.business.domain.excel;
+
+import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
+import cn.idev.excel.annotation.ExcelProperty;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+
+@Data
+@ExcelIgnoreUnannotated
+@AutoMapper(target = ProjectExcel.class)
+public class ProjectEnglishExcel implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    @ExcelProperty(value = "ID")
+    private Long id;
+
+    @ExcelProperty(value = "Name")
+    private String name;
+
+    @ExcelProperty(value = "Status")
+    private String status;
+
+    @ExcelProperty(value = "Actual Name")
+    private String actualDocumentName;
+
+    @ExcelProperty(value = "Center No")
+    private Long centerId;
+
+    @ExcelProperty(value = "Plan Submitter")
+    private String planSubmitter;
+
+    @ExcelProperty(value = "Deadline")
+    private String deadline;
+
+    @ExcelProperty(value = "Days of Overdue")
+    private Long daysOverdue;
+
+    @ExcelProperty(value = "Owner")
+    private String createBy;
+
+    @ExcelProperty(value = "Path")
+    private String path;
+
+    @ExcelProperty(value = "Actual Submit Time")
+    private String submitTime;
+
+    @ExcelProperty(value = "Actual Submitter")
+    private String submitter;
+
+    @ExcelProperty(value = "Project Name")
+    private String projectName;
+
+    @ExcelProperty(value = "Center Name")
+    private String centerName;
+
+    @ExcelProperty(value = "plan Type")
+    private String planType;
+
+}

+ 44 - 0
ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/domain/excel/ProjectExcel.java

@@ -0,0 +1,44 @@
+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;
+
+    private Long id;
+
+    private String name;
+
+    private String status;
+
+    private String actualDocumentName;
+
+    private Long centerId;
+
+    private String planSubmitter;
+
+    private String deadline;
+
+    private Long daysOverdue;
+
+    private String createBy;
+
+    private String path;
+
+    private String submitTime;
+
+    private String submitter;
+
+    private String projectName;
+
+    private String centerName;
+
+    private String planType;
+
+}

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

@@ -0,0 +1,7 @@
+package com.yingpaipay.business.domain.excel;
+
+import lombok.Data;
+
+@Data
+public class SearchExcel {
+}

+ 2 - 11
ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/domain/vo/DocumentAuditLogVo.java

@@ -22,34 +22,25 @@ public class DocumentAuditLogVo implements Serializable {
     @Serial
     private static final long serialVersionUID = 1L;
 
-    @ExcelProperty(value = "序号")
     private Long id;
 
-    @ExcelProperty(value = "审核文件")
     private String documentName;
     private Long documentId;
 
-    @ExcelProperty(value = "实际文件")
-    private String ossUrl;
-    private Long ossId;
+    private String uploadVersionUrl;
+    private Long uploadVersion;
 
-    @ExcelProperty(value = "审核人类型")
-    @ExcelDictFormat(dictType = DictTypeConst.AUDITOR_TYPE)
     private String auditorType;
 
-    @ExcelProperty(value = "审核人")
     @Translation(type = TransConstant.USER_ID_TO_NICKNAME, mapper = "auditor")
     private String auditorName;
     private Long auditor;
 
-    @ExcelProperty(value = "审核结果")
     private String resultLabel;
     private Integer result;
 
-    @ExcelProperty(value = "驳回理由")
     private String rejectReason;
 
-    @ExcelProperty(value = "审核日期")
     private Date auditTime;
 
 }

+ 35 - 0
ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/domain/vo/DocumentListOnSpecifyVo.java

@@ -0,0 +1,35 @@
+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 DocumentListOnSpecifyVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    private Long id;
+
+    private String name;
+
+    private String folder;
+
+    private Integer status;
+
+    private Date deadline;
+
+    @Translation(type = TransConstant.USER_ID_TO_NICKNAME, mapper = "planSubmitter")
+    private Long planSubmitter;
+
+    @Translation(type = TransConstant.USER_ID_TO_NICKNAME, mapper = "createBy")
+    private Long createBy;
+
+    private Date createTime;
+
+}

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

@@ -20,7 +20,7 @@ public class DocumentQcTaskDetailListVo implements Serializable {
 
     private String documentName;
 
-    private Long ossId;
+    private Long actualDocument;
 
     private Long executor;
 

+ 115 - 0
ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/domain/vo/DocumentQcTaskLogVo.java

@@ -0,0 +1,115 @@
+package com.yingpaipay.business.domain.vo;
+
+import java.util.Date;
+import com.yingpaipay.business.domain.DocumentQcTaskLog;
+import cn.idev.excel.annotation.ExcelProperty;
+import org.dromara.common.excel.annotation.ExcelDictFormat;
+import org.dromara.common.excel.convert.ExcelDictConvert;
+import io.github.linpeilie.annotations.AutoMapper;
+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;
+
+
+
+/**
+ * 文档质控日志视图对象 document_qc_task_log
+ *
+ * @author Huanyi
+ * @date 2026-01-14
+ */
+@Data
+@AutoMapper(target = DocumentQcTaskLog.class)
+public class DocumentQcTaskLogVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 序号
+     */
+    private Long id;
+
+    /**
+     * 质控任务
+     */
+    private Long taskId;
+
+    /**
+     * 指控环节
+     */
+    private Long detailId;
+
+    /**
+     * 执行人
+     */
+    private Long executor;
+
+    /**
+     * 执行时间
+     */
+    private Date executeTime;
+
+    /**
+     * 质控结果
+     */
+    private Integer result;
+
+    /**
+     * 问题分类
+     */
+    private String questionType;
+
+    /**
+     * 质控意见
+     */
+    private String option;
+
+    /**
+     * 指定处理人
+     */
+    @Translation(type = TransConstant.USER_ID_TO_NICKNAME, mapper = "designatedDealer")
+    private Long designatedDealer;
+
+    /**
+     * 处理截止日期
+     */
+    private Date deadline;
+
+    /**
+     * 实际处理人
+     */
+    @Translation(type = TransConstant.USER_ID_TO_NICKNAME, mapper = "actualDealer")
+    private Long actualDealer;
+
+    /**
+     * 处理时间
+     */
+    private Date dealTime;
+
+    /**
+     * 创建者
+     */
+    @Translation(type = TransConstant.USER_ID_TO_NICKNAME, mapper = "createBy")
+    private Long createBy;
+
+    /**
+     * 创建时间
+     */
+    private Date createTime;
+
+    /**
+     * 更新者
+     */
+    @Translation(type = TransConstant.USER_ID_TO_NICKNAME, mapper = "updateBy")
+    private Long updateBy;
+
+    /**
+     * 更新时间
+     */
+    private Date updateTime;
+
+}

+ 5 - 26
ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/domain/vo/DocumentVo.java

@@ -1,23 +1,15 @@
 package com.yingpaipay.business.domain.vo;
 
 import java.util.Date;
-import com.fasterxml.jackson.annotation.JsonFormat;
-import com.yingpaipay.business.constant.DictTypeConst;
 import com.yingpaipay.business.domain.Document;
 import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
-import cn.idev.excel.annotation.ExcelProperty;
-import org.dromara.common.excel.annotation.ExcelDictFormat;
-import org.dromara.common.excel.convert.ExcelDictConvert;
 import io.github.linpeilie.annotations.AutoMapper;
 import lombok.Data;
 import org.dromara.common.translation.annotation.Translation;
 import org.dromara.common.translation.constant.TransConstant;
-import org.dromara.system.domain.SysOss;
-import org.dromara.system.domain.vo.SysOssVo;
 
 import java.io.Serial;
 import java.io.Serializable;
-import java.util.Date;
 
 
 
@@ -38,75 +30,61 @@ public class DocumentVo implements Serializable {
     /**
      * 序号
      */
-    @ExcelProperty(value = "序号")
     private Long id;
 
     /**
      * 所属文件夹
      */
-    @ExcelProperty(value = "所属文件夹")
     private String folderName;
     private Long folderId;
 
     /**
      * 文档标识
      */
-    @ExcelProperty(value = "文档标识")
     private String specificationLabel;
     private String specification;
 
     /**
      * 计划名称
      */
-    @ExcelProperty(value = "计划文件名称/文件名称")
     private String name;
 
-    @ExcelProperty(value = "计划文件类型")
     private String planDocumentTypeLabel;
     private String planType;
 
     /**
      * 状态
      */
-    @ExcelProperty(value = "状态")
     private Integer status;
 
     /**
      * 计划上传时间
      */
-    @ExcelProperty(value = "递交截止时间")
     private Date submitDeadline;
 
     /**
      * 文档本体
      */
-    @ExcelProperty(value = "实际文档")
-    private String fileName;
-    private Long ossId;
+    private String actualDocumentName;
+    private Long actualDocument;
 
-    @ExcelProperty(value = "递交时间")
     private Date submitTime;
 
-
     /**
      * 备注
      */
-    @ExcelProperty(value = "备注")
     private String note;
 
     /**
      * 创建时间
      */
-    @ExcelProperty(value = "创建时间")
     private Date createTime;
 
     /**
      * 更新时间
      */
-    @ExcelProperty(value = "更新时间")
     private Date updateTime;
 
-    @ExcelProperty(value = "递交人")
     @Translation(type = TransConstant.USER_ID_TO_NICKNAME, mapper = "submitter")
     private String submitterName;
     private Long submitter;
@@ -119,8 +97,9 @@ public class DocumentVo implements Serializable {
 
     private Boolean sendStatus;
 
-    @ExcelProperty(value = "计划递交人")
-//    @Translation(type = TransConstant.USER_ID_TO_NICKNAME, mapper = "planSubmitter")
+    @Translation(type = TransConstant.USER_ID_TO_NICKNAME, mapper = "planSubmitter")
     private String planSubmitterName;
     private Long planSubmitter;
+
+    private Long createBy;
 }

+ 0 - 9
ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/domain/vo/FolderVo.java

@@ -29,51 +29,42 @@ public class FolderVo implements Serializable {
     /**
      * 序号
      */
-    @ExcelProperty(value = "序号")
     private Long id;
 
     /**
      * 所属项目
      */
-    @ExcelProperty(value = "所属项目")
     private Long projectId;
 
     /**
      * 父级
      */
-    @ExcelProperty(value = "父级")
     private Long parentId;
 
     /**
      * 类型
      */
-    @ExcelProperty(value = "类型")
     private Integer type;
 
     /**
      * 名称
      */
-    @ExcelProperty(value = "名称")
     private String name;
 
     /**
      * 状态
      */
-    @ExcelProperty(value = "状态")
     private Integer status;
 
     /**
      * 创建时间
      */
-    @ExcelProperty(value = "创建时间")
     private Date createTime;
 
     /**
      * 更新时间
      */
-    @ExcelProperty(value = "更新时间")
     private Date updateTime;
 
-    @ExcelProperty(value = "限制层级")
     private Integer restrictionLevel;
 }

+ 0 - 16
ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/domain/vo/ProjectVo.java

@@ -35,97 +35,81 @@ public class ProjectVo implements Serializable {
     /**
      * 序号
      */
-    @ExcelProperty(value = "序号")
     private Long id;
 
     /**
      * 项目编号
      */
-    @ExcelProperty(value = "项目编号")
     private String code;
 
     /**
      * 名称
      */
-    @ExcelProperty(value = "名称")
     private String name;
 
     /**
      * 项目语言
      */
-    @ExcelProperty(value = "项目语言")
     private String language;
 
     /**
      * 项目类型
      */
-    @ExcelProperty(value = "项目类型")
     private String type;
 
     /**
      * 状态
      */
-    @ExcelProperty(value = "状态")
     private Integer status;
 
     /**
      * PD/GPD
      */
-    @ExcelProperty(value = "PD/GPD")
     private String pdGpd;
 
     /**
      * PM/GPM
      */
-    @ExcelProperty(value = "PM/GPM")
     private String pmGpm;
 
     /**
      * CTA/GCTA
      */
-    @ExcelProperty(value = "CTA/GCTA")
     private String ctaGcta;
 
     /**
      * 申办方
      */
-    @ExcelProperty(value = "申办方")
     private String sponsor;
 
     /**
      * CRO
      */
-    @ExcelProperty(value = "CRO")
     private String cro;
 
     /**
      * 开始时间
      */
-    @ExcelProperty(value = "开始时间")
     private Date startTime;
 
     /**
      * 结束时间
      */
-    @ExcelProperty(value = "结束时间")
     private Date endTime;
 
     /**
      * 创建时间
      */
-    @ExcelProperty(value = "创建时间")
     private Date createTime;
 
     /**
      * 更新时间
      */
-    @ExcelProperty(value = "更新时间")
     private Date updateTime;
 
     /**
      * 图标
      */
-    @ExcelProperty(value = "图标")
     private String iconUrl;
     private Long icon;
 

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

@@ -32,11 +32,11 @@ public class TaskCenterAuditListVo implements Serializable {
 
     private Date createTime;
 
-    private Long ossId;
+    private Long actualDocument;
 
     private String fileName;
 
-    private String ossUrl;
+    private String actualDocumentUrl;
 
     private Integer type;
 

+ 48 - 0
ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/enumeration/DocumentStatusEnum.java

@@ -0,0 +1,48 @@
+package com.yingpaipay.business.enumeration;
+
+import lombok.AccessLevel;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import org.springframework.context.i18n.LocaleContextHolder;
+
+import java.util.Locale;
+
+@Getter
+@AllArgsConstructor(access = AccessLevel.PRIVATE)
+public enum DocumentStatusEnum {
+
+    UN_UPLOAD(0, "待上传", "Pending Upload"),
+    UN_AUDIT(1, "待审核", "Pending Audit"),
+    AUDIT_REJECT(2, "审核驳回", "Audit Reject"),
+    UN_ARCHIEVED(3, "待归档", "Pending Archieved"),
+    ARCHIEVED(4, "已归档", "Archieved"),
+    UN_QC(5, "待质控", "Pending QC"),
+    QC_PASS(6, "质控通过", "QC Pass"),
+    QC_REJECT(7, "质控驳回", "QC Reject"),
+    ;
+
+    private final Integer value;
+    private final String zhLabel;
+    private final String enLabel;
+
+    public static String getLabel(Integer value) {
+        if (value == null) {
+            return "";
+        }
+        DocumentStatusEnum status = null;
+        for (DocumentStatusEnum enumeration : values()) {
+            if (enumeration.getValue().equals(value)) {
+                status = enumeration;
+            }
+        }
+        if (status == null) {
+            return "";
+        }
+        Locale locale = LocaleContextHolder.getLocale();
+        if (locale.getLanguage().equals("zh")) {
+            return status.getZhLabel();
+        }
+        return status.getEnLabel();
+    }
+
+}

+ 15 - 0
ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/mapper/DocumentQcTaskLogMapper.java

@@ -0,0 +1,15 @@
+package com.yingpaipay.business.mapper;
+
+import com.yingpaipay.business.domain.DocumentQcTaskLog;
+import com.yingpaipay.business.domain.vo.DocumentQcTaskLogVo;
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+
+/**
+ * 文档质控日志Mapper接口
+ *
+ * @author Huanyi
+ * @date 2026-01-14
+ */
+public interface DocumentQcTaskLogMapper extends BaseMapperPlus<DocumentQcTaskLog, DocumentQcTaskLogVo> {
+
+}

+ 28 - 0
ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/service/IDocumentQcTaskLogService.java

@@ -0,0 +1,28 @@
+package com.yingpaipay.business.service;
+
+import com.yingpaipay.business.domain.vo.DocumentQcTaskLogVo;
+import com.yingpaipay.business.domain.bo.DocumentQcTaskLogBo;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.mybatis.core.page.PageQuery;
+
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * 文档质控日志Service接口
+ *
+ * @author Huanyi
+ * @date 2026-01-14
+ */
+public interface IDocumentQcTaskLogService {
+
+    /**
+     * 分页查询文档质控日志列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 文档质控日志分页列表
+     */
+    TableDataInfo<DocumentQcTaskLogVo> queryPageList(DocumentQcTaskLogBo bo, PageQuery pageQuery);
+
+}

+ 9 - 0
ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/service/IDocumentService.java

@@ -1,6 +1,7 @@
 package com.yingpaipay.business.service;
 
 import com.yingpaipay.business.domain.bo.*;
+import com.yingpaipay.business.domain.excel.ProjectExcel;
 import com.yingpaipay.business.domain.vo.*;
 import jakarta.servlet.http.HttpServletResponse;
 import org.dromara.common.mybatis.core.page.TableDataInfo;
@@ -109,4 +110,12 @@ public interface IDocumentService {
     boolean upload(AppletUploadBo bo);
 
     long countTemp(Long projectId);
+
+    boolean removeTemp(Long documentId);
+
+    boolean specify(DocumentSpecifyBo bo);
+
+    TableDataInfo<DocumentListOnSpecifyVo> listOnSpecify(DocumentListOnSpecifyBo bo, PageQuery pageQuery);
+
+    List<ProjectExcel> getListByProjectId(Long projectId);
 }

+ 3 - 4
ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/service/impl/CommonDocumentService.java

@@ -1,10 +1,9 @@
 package com.yingpaipay.business.service.impl;
 
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
-import com.yingpaipay.business.constant.DocumentStatusConst;
 import com.yingpaipay.business.domain.Document;
+import com.yingpaipay.business.enumeration.DocumentStatusEnum;
 import com.yingpaipay.business.mapper.DocumentMapper;
-import jakarta.validation.constraints.NotNull;
 import lombok.RequiredArgsConstructor;
 import org.dromara.common.core.utils.StringUtils;
 import org.springframework.stereotype.Service;
@@ -36,7 +35,7 @@ public class CommonDocumentService {
     public Document getByOssId(Long ossId) {
         return baseMapper.selectOne(
             Wrappers.lambdaQuery(Document.class)
-                .eq(Document::getOssId, ossId)
+                .eq(Document::getActualDocument, ossId)
         );
     }
 
@@ -46,7 +45,7 @@ public class CommonDocumentService {
         }
         return baseMapper.selectList(
             Wrappers.lambdaQuery(Document.class)
-                .eq(Document::getStatus, DocumentStatusConst.FILING)
+                .eq(Document::getStatus, DocumentStatusEnum.ARCHIEVED.getValue())
                 .notIn(Document::getId, documentIds)
         );
     }

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

@@ -23,7 +23,7 @@ public class CommonFolderService {
     private final FolderMapper baseMapper;
     private final SysUserFoldersMapper userFoldersMapper;
 
-    public List<Long> selectIdsOnSubmission(String centerName, List<Long> projectIds) {
+    public List<Long> selectIds(String centerName, List<Long> projectIds) {
         if (projectIds.isEmpty()) {
             return List.of();
         }
@@ -198,4 +198,11 @@ public class CommonFolderService {
         }
         children.forEach(e -> buildFolders(e, folders, childrenMap));
     }
+
+    public List<Folder> queryByProjectId(Long projectId) {
+        return baseMapper.selectList(
+            Wrappers.lambdaQuery(Folder.class)
+                .eq(Folder::getProjectId, projectId)
+        );
+    }
 }

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

@@ -24,7 +24,7 @@ public class CommonProjectService {
     private final ProjectMapper baseMapper;
     private final SysUserProjectsMapper userProjectsMapper;
 
-    public List<Long> queryIdsOnSubmission(String projectCode, String name) {
+    public List<Long> queryIds(String projectCode, String name) {
         List<Long> ids = new ArrayList<>();
         SysUserProjects userProjects = userProjectsMapper.selectOne(Wrappers.lambdaQuery(SysUserProjects.class).eq(SysUserProjects::getUserId, LoginHelper.getUserId()));
         if (userProjects == null) {

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

@@ -17,6 +17,7 @@ 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.system.domain.SysUser;
 import org.dromara.system.domain.vo.SysUserVo;
 import org.dromara.system.service.ISysUserService;
 import org.springframework.stereotype.Service;
@@ -68,7 +69,7 @@ public class DocumentQcTaskDetailServiceImpl implements IDocumentQcTaskDetailSer
         List<Document> selected = shuffled.subList(0, selectCount);
 
         List<Long> selectedUserIds = new ArrayList<>();
-        Map<Long, SysUserVo> selectedUserMap = new HashMap<>();
+        Map<Long, SysUser> selectedUserMap = new HashMap<>();
         selected.forEach(e -> selectedUserIds.add(e.getCreateBy()));
         userService.selectUserByIds(selectedUserIds)
             .forEach(e -> selectedUserMap.put(e.getUserId(), e));
@@ -78,7 +79,7 @@ public class DocumentQcTaskDetailServiceImpl implements IDocumentQcTaskDetailSer
             DocumentQcGenerateVo vo = new DocumentQcGenerateVo();
             vo.setDocumentId(document.getId());
             vo.setDocumentName(document.getName());
-            SysUserVo user = selectedUserMap.get(document.getCreateBy());
+            SysUser user = selectedUserMap.get(document.getCreateBy());
             if (user != null) {
                 vo.setExecutor(user.getUserId());
                 vo.setExecutorName(user.getNickName());
@@ -112,7 +113,7 @@ public class DocumentQcTaskDetailServiceImpl implements IDocumentQcTaskDetailSer
 
             vo.setDocument(document.getId());
             vo.setDocumentName(document.getName());
-            vo.setOssId(document.getOssId());
+            vo.setActualDocument(document.getActualDocument());
             vo.setExecutor(e.getExecutor());
             vo.setStatus(e.getStatus());
             vo.setNote(e.getNote());

+ 74 - 0
ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/service/impl/DocumentQcTaskLogServiceImpl.java

@@ -0,0 +1,74 @@
+package com.yingpaipay.business.service.impl;
+
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+import com.yingpaipay.business.domain.bo.DocumentQcTaskLogBo;
+import com.yingpaipay.business.domain.vo.DocumentQcTaskLogVo;
+import com.yingpaipay.business.domain.DocumentQcTaskLog;
+import com.yingpaipay.business.mapper.DocumentQcTaskLogMapper;
+import com.yingpaipay.business.service.IDocumentQcTaskLogService;
+
+import java.util.Map;
+
+/**
+ * 文档质控日志Service业务层处理
+ *
+ * @author Huanyi
+ * @date 2026-01-14
+ */
+@Slf4j
+@RequiredArgsConstructor
+@Service
+public class DocumentQcTaskLogServiceImpl implements IDocumentQcTaskLogService {
+
+    private final DocumentQcTaskLogMapper baseMapper;
+
+    /**
+     * 分页查询文档质控日志列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 文档质控日志分页列表
+     */
+    @Override
+    public TableDataInfo<DocumentQcTaskLogVo> queryPageList(DocumentQcTaskLogBo bo, PageQuery pageQuery) {
+        LambdaQueryWrapper<DocumentQcTaskLog> lqw = buildQueryWrapper(bo);
+        Page<DocumentQcTaskLogVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
+        return TableDataInfo.build(result);
+    }
+
+
+    private LambdaQueryWrapper<DocumentQcTaskLog> buildQueryWrapper(DocumentQcTaskLogBo bo) {
+        Map<String, Object> params = bo.getParams();
+        LambdaQueryWrapper<DocumentQcTaskLog> lqw = Wrappers.lambdaQuery();
+        lqw.orderByAsc(DocumentQcTaskLog::getId);
+        lqw.eq(bo.getTaskId() != null, DocumentQcTaskLog::getTaskId, bo.getTaskId());
+        lqw.eq(bo.getDetailId() != null, DocumentQcTaskLog::getDetailId, bo.getDetailId());
+        lqw.eq(bo.getExecutor() != null, DocumentQcTaskLog::getExecutor, bo.getExecutor());
+        lqw.between(params.get("beginExecuteTime") != null && params.get("endExecuteTime") != null,
+            DocumentQcTaskLog::getExecuteTime ,params.get("beginExecuteTime"), params.get("endExecuteTime"));
+        lqw.eq(bo.getResult() != null, DocumentQcTaskLog::getResult, bo.getResult());
+        lqw.eq(StringUtils.isNotBlank(bo.getQuestionType()), DocumentQcTaskLog::getQuestionType, bo.getQuestionType());
+        lqw.eq(bo.getDesignatedDealer() != null, DocumentQcTaskLog::getDesignatedDealer, bo.getDesignatedDealer());
+        lqw.between(params.get("beginDeadline") != null && params.get("endDeadline") != null,
+            DocumentQcTaskLog::getDeadline ,params.get("beginDeadline"), params.get("endDeadline"));
+        lqw.eq(bo.getActualDealer() != null, DocumentQcTaskLog::getActualDealer, bo.getActualDealer());
+        lqw.between(params.get("beginDealTime") != null && params.get("endDealTime") != null,
+            DocumentQcTaskLog::getDealTime ,params.get("beginDealTime"), params.get("endDealTime"));
+        lqw.eq(bo.getCreateBy() != null, DocumentQcTaskLog::getCreateBy, bo.getCreateBy());
+        lqw.between(params.get("beginCreateTime") != null && params.get("endCreateTime") != null,
+            DocumentQcTaskLog::getCreateTime ,params.get("beginCreateTime"), params.get("endCreateTime"));
+        lqw.eq(bo.getUpdateBy() != null, DocumentQcTaskLog::getUpdateBy, bo.getUpdateBy());
+        lqw.between(params.get("beginUpdateTime") != null && params.get("endUpdateTime") != null,
+            DocumentQcTaskLog::getUpdateTime ,params.get("beginUpdateTime"), params.get("endUpdateTime"));
+        return lqw;
+    }
+
+}

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

@@ -1,21 +1,20 @@
 package com.yingpaipay.business.service.impl;
 
-import cn.dev33.satoken.stp.StpUtil;
-import com.yingpaipay.business.constant.DocumentStatusConst;
+import com.baomidou.lock.LockInfo;
+import com.baomidou.lock.LockTemplate;
+import com.baomidou.lock.executor.RedissonLockExecutor;
 import com.yingpaipay.business.constant.QcTaskDetailStatusConst;
 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.bo.DocumentQcTaskBo;
-import com.yingpaipay.business.domain.bo.DocumentQcTaskDetailBo;
-import com.yingpaipay.business.domain.vo.DocumentQcTaskDetailVo;
 import com.yingpaipay.business.domain.vo.DocumentQcTaskVo;
+import com.yingpaipay.business.enumeration.DocumentStatusEnum;
 import com.yingpaipay.business.mapper.DocumentQcTaskDetailMapper;
 import org.dromara.common.core.exception.BusinessException;
 import org.dromara.common.core.utils.MapstructUtils;
 import org.dromara.common.core.utils.MessageUtils;
-import org.dromara.common.core.utils.SpringUtils;
 import org.dromara.common.core.utils.StringUtils;
 import org.dromara.common.mybatis.core.page.TableDataInfo;
 import org.dromara.common.mybatis.core.page.PageQuery;
@@ -26,19 +25,14 @@ import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.dromara.common.satoken.utils.LoginHelper;
 import org.dromara.common.tenant.helper.TenantHelper;
-import org.dromara.system.domain.vo.SysUserVo;
 import org.dromara.system.service.ISysUserService;
 import org.springframework.stereotype.Service;
 import com.yingpaipay.business.mapper.DocumentQcTaskMapper;
 import com.yingpaipay.business.service.IDocumentQcTaskService;
-import org.springframework.transaction.PlatformTransactionManager;
 import org.springframework.transaction.annotation.Transactional;
-import org.springframework.transaction.support.TransactionTemplate;
 
 import java.util.*;
-import java.util.concurrent.ConcurrentHashMap;
 import java.util.stream.Collectors;
-import java.util.stream.Stream;
 
 /**
  * 文档质控任务Service业务层处理
@@ -58,7 +52,9 @@ public class DocumentQcTaskServiceImpl implements IDocumentQcTaskService {
     private final CommonDocumentService documentService;
     private final ISysUserService userService;
 
-    private static final Map<Long, Object> TASK_LOCK = new ConcurrentHashMap<>();
+    private final LockTemplate lockTemplate;
+
+//    private static final Map<Long, Object> TASK_LOCK = new ConcurrentHashMap<>();
 
     /**
      * 查询文档质控任务
@@ -145,14 +141,14 @@ public class DocumentQcTaskServiceImpl implements IDocumentQcTaskService {
         lqw.eq(bo.getInitiator() != null, DocumentQcTask::getInitiator, bo.getInitiator());
         lqw.eq(bo.getProjectId() != null, DocumentQcTask::getProjectId, bo.getProjectId());
         lqw.between(params.get("beginDeadline") != null && params.get("endDeadline") != null,
-            DocumentQcTask::getDeadline ,params.get("beginDeadline"), params.get("endDeadline"));
+            DocumentQcTask::getDeadline, params.get("beginDeadline"), params.get("endDeadline"));
         lqw.eq(bo.getStatus() != null, DocumentQcTask::getStatus, bo.getStatus());
         lqw.eq(bo.getCreateBy() != null, DocumentQcTask::getCreateBy, bo.getCreateBy());
         lqw.between(params.get("beginCreateTime") != null && params.get("endCreateTime") != null,
-            DocumentQcTask::getCreateTime ,params.get("beginCreateTime"), params.get("endCreateTime"));
+            DocumentQcTask::getCreateTime, params.get("beginCreateTime"), params.get("endCreateTime"));
         lqw.eq(bo.getUpdateBy() != null, DocumentQcTask::getUpdateBy, bo.getUpdateBy());
         lqw.between(params.get("beginUpdateTime") != null && params.get("endUpdateTime") != null,
-            DocumentQcTask::getUpdateTime ,params.get("beginUpdateTime"), params.get("endUpdateTime"));
+            DocumentQcTask::getUpdateTime, params.get("beginUpdateTime"), params.get("endUpdateTime"));
         return lqw;
     }
 
@@ -178,11 +174,14 @@ public class DocumentQcTaskServiceImpl implements IDocumentQcTaskService {
          * TODO 避免同一个文件反复参与质控
          * FIXME 需要思考一个更好的方案,尽可能避免所有操作全部串行化
          */
-        Object lock = TASK_LOCK.computeIfAbsent(bo.getProjectId(), projectId -> new Object());
+        LockInfo lock = lockTemplate.lock("qc:" + bo.getProjectId(), 30000L, 5000L, RedissonLockExecutor.class);
+        if (lock == null) {
+            throw new BusinessException(MessageUtils.message("document.qc.taskisinitializing"));
+        }
 
-        List<Document> selectedDocuments;
+        try {
+            List<Document> selectedDocuments;
 
-        synchronized (lock) {
             List<Long> historyIds = new ArrayList<>();
             detailMapper.selectList(
                 Wrappers.lambdaQuery(DocumentQcTaskDetail.class)
@@ -191,7 +190,7 @@ public class DocumentQcTaskServiceImpl implements IDocumentQcTaskService {
 
             List<Document> documents = documentService.selectByProjectId(bo.getProjectId());
             selectedDocuments = documents.stream()
-                .filter(e -> e.getStatus().equals(DocumentStatusConst.FILING))
+                .filter(e -> e.getStatus().equals(DocumentStatusEnum.ARCHIEVED.getValue()))
                 .filter(e -> !historyIds.contains(e.getId()))
                 .collect(Collectors.toList());
             if (selectedDocuments.isEmpty()) {
@@ -214,7 +213,8 @@ public class DocumentQcTaskServiceImpl implements IDocumentQcTaskService {
             if (!flag) {
                 throw new RuntimeException("批量插入失败");
             }
-
+        } finally {
+            lockTemplate.releaseLock(lock);
         }
 
         return true;
@@ -236,7 +236,7 @@ public class DocumentQcTaskServiceImpl implements IDocumentQcTaskService {
     /**
      * 保存前的数据校验
      */
-    private void validEntityBeforeSave(DocumentQcTask entity){
+    private void validEntityBeforeSave(DocumentQcTask entity) {
         //TODO 做一些数据校验,如唯一约束
     }
 
@@ -250,7 +250,7 @@ public class DocumentQcTaskServiceImpl implements IDocumentQcTaskService {
     @Transactional(rollbackFor = Exception.class)
     @Override
     public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
-        if(isValid){
+        if (isValid) {
             //TODO 做一些业务上的校验,判断是否需要校验
         }
         boolean taskFlag = baseMapper.deleteByIds(ids) == 0;

+ 263 - 49
ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/service/impl/DocumentServiceImpl.java

@@ -1,13 +1,20 @@
 package com.yingpaipay.business.service.impl;
 
+import cn.hutool.core.lang.Dict;
+import cn.hutool.core.util.IdUtil;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.yingpaipay.business.constant.*;
 import com.yingpaipay.business.domain.DocumentAuditLog;
 import com.yingpaipay.business.domain.Folder;
+import com.yingpaipay.business.domain.Project;
 import com.yingpaipay.business.domain.bo.*;
+import com.yingpaipay.business.domain.excel.ProjectExcel;
 import com.yingpaipay.business.domain.vo.*;
+import com.yingpaipay.business.enumeration.DocumentStatusEnum;
 import com.yingpaipay.business.mapper.DocumentAuditLogMapper;
 import com.yingpaipay.common.file.util.PdfUtils;
+import com.yingpaipay.system.domain.SysUserFolders;
+import com.yingpaipay.system.mapper.SysUserFoldersMapper;
 import jakarta.servlet.http.HttpServletResponse;
 import org.apache.commons.io.FilenameUtils;
 import org.dromara.common.core.constant.GlobalConstants;
@@ -16,6 +23,7 @@ import org.dromara.common.core.utils.MapstructUtils;
 import org.dromara.common.core.utils.MessageUtils;
 import org.dromara.common.core.utils.StringUtils;
 import org.dromara.common.core.utils.file.FileUtils;
+import org.dromara.common.json.utils.JsonUtils;
 import org.dromara.common.mybatis.core.page.TableDataInfo;
 import org.dromara.common.mybatis.core.page.PageQuery;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@@ -28,10 +36,12 @@ import org.dromara.common.oss.factory.OssFactory;
 import org.dromara.common.redis.utils.RedisUtils;
 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.SysOssVo;
 import org.dromara.system.service.ISysDictTypeService;
 import org.dromara.system.service.ISysOssService;
 import org.dromara.system.service.ISysUserService;
+import org.springframework.context.i18n.LocaleContextHolder;
 import org.springframework.http.MediaType;
 import org.springframework.stereotype.Service;
 import com.yingpaipay.business.domain.Document;
@@ -42,6 +52,9 @@ import org.springframework.transaction.annotation.Transactional;
 import java.io.*;
 import java.nio.file.Files;
 import java.nio.file.Path;
+import java.time.LocalDate;
+import java.time.ZoneId;
+import java.time.temporal.ChronoUnit;
 import java.util.*;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.stream.Collectors;
@@ -59,6 +72,7 @@ public class DocumentServiceImpl implements IDocumentService {
 
     private final DocumentMapper baseMapper;
     private final DocumentAuditLogMapper auditLogMapper;
+    private final SysUserFoldersMapper userFoldersMapper;
 
     private final ISysDictTypeService dictTypeService;
     private final ISysOssService ossService;
@@ -105,7 +119,7 @@ public class DocumentServiceImpl implements IDocumentService {
         List<Long> userIds = new ArrayList<>();
         Map<Long, String> userMap = new HashMap<>();
         documents.forEach(e -> {
-            ossIds.add(e.getOssId());
+            ossIds.add(e.getActualDocument());
             folderIds.add(e.getFolderId());
             userIds.add(e.getSubmitter());
             userIds.add(e.getPlanSubmitter());
@@ -114,9 +128,9 @@ public class DocumentServiceImpl implements IDocumentService {
         ossService.queryListByIds(ossIds).forEach(e -> ossMap.put(e.getOssId(), e));
         userService.selectUserByIds(userIds).forEach(e -> userMap.put(e.getUserId(), e.getNickName()));
         documents.forEach(e -> {
-            SysOssVo ossVo = ossMap.get(e.getOssId());
+            SysOssVo ossVo = ossMap.get(e.getActualDocument());
             if (ossVo != null) {
-                e.setFileName(ossVo.getOriginalName());
+                e.setActualDocumentName(ossVo.getOriginalName());
             }
             e.setSubmitterName(userMap.get(e.getSubmitter()));
             e.setPlanSubmitterName(userMap.get(e.getPlanSubmitter()));
@@ -225,10 +239,11 @@ public class DocumentServiceImpl implements IDocumentService {
         return baseMapper.update(
             Wrappers.lambdaUpdate(Document.class)
                 .eq(Document::getId, bo.getDocumentId())
-                .set(Document::getOssId, bo.getOssId())
+                .set(Document::getActualDocument, bo.getOssId())
                 .set(Document::getSubmitTime, new Date())
                 .set(Document::getSubmitter, LoginHelper.getUserId())
-                .set(Document::getStatus, DocumentStatusConst.UN_AUDIT)
+                .set(Document::getEffectiveDate, bo.getEffectiveDate())
+                .set(Document::getStatus, DocumentStatusEnum.UN_AUDIT.getValue())
         ) > 0;
     }
 
@@ -241,7 +256,7 @@ public class DocumentServiceImpl implements IDocumentService {
             throw new BusinessException(MessageUtils.message("document.document.audit.documentnotfound"));
         }
 
-        if (Objects.equals(bo.getResult(), DocumentStatusConst.UN_FILING)) {
+        if (Objects.equals(bo.getResult(), DocumentStatusEnum.UN_ARCHIEVED.getValue())) {
             document.setPassTime(new Date());
         }
         document.setStatus(bo.getResult());
@@ -288,16 +303,16 @@ public class DocumentServiceImpl implements IDocumentService {
         Map<Long, SysOssVo> ossMap = new HashMap<>();
         vos.forEach(e -> {
             documentIds.add(e.getDocumentId());
-            ossIds.add(e.getOssId());
+            ossIds.add(e.getUploadVersion());
         });
         ossService.queryListByIds(ossIds).forEach(e -> ossMap.put(e.getOssId(), e));
         if (!documentIds.isEmpty()) {
             baseMapper.selectByIds(documentIds).forEach(e -> documentMap.put(e.getId(), e));
         }
         vos.forEach(e -> {
-            SysOssVo ossVo = ossMap.get(e.getOssId());
+            SysOssVo ossVo = ossMap.get(e.getUploadVersion());
             Document document = documentMap.get(e.getDocumentId());
-            e.setOssUrl(Optional.ofNullable(ossVo).map(SysOssVo::getUrl).orElse(null));
+            e.setUploadVersionUrl(Optional.ofNullable(ossVo).map(SysOssVo::getUrl).orElse(null));
             e.setDocumentName(Optional.ofNullable(document).map(Document::getName).orElse(null));
         });
     }
@@ -307,17 +322,17 @@ public class DocumentServiceImpl implements IDocumentService {
         return baseMapper.update(
             Wrappers.lambdaUpdate(Document.class)
                 .eq(Document::getId, bo.getDocumentId())
-                .set(Document::getStatus, DocumentStatusConst.FILING)
+                .set(Document::getStatus, DocumentStatusEnum.ARCHIEVED.getValue())
         ) > 0;
     }
 
     @Override
     public TableDataInfo<TaskCenterSubmissionListVo> listOnSubmission(TaskCenterSubmissionListBo bo, PageQuery pageQuery) {
-        List<Long> projectIds = projectService.queryIdsOnSubmission(bo.getProjectCode(), bo.getProjectName());
+        List<Long> projectIds = projectService.queryIds(bo.getProjectCode(), bo.getProjectName());
         if (projectIds.isEmpty()) {
             return TableDataInfo.build();
         }
-        List<Long> folderIds = folderService.selectIdsOnSubmission(bo.getCenterName(), projectIds);
+        List<Long> folderIds = folderService.selectIds(bo.getCenterName(), projectIds);
         LambdaQueryWrapper<Document> wrapper = buildSubmissionListWrapper(bo, folderIds);
         IPage<Document> page = baseMapper.selectPage(pageQuery.build(), wrapper);
         return TableDataInfo.build(page.convert(e -> {
@@ -339,16 +354,16 @@ public class DocumentServiceImpl implements IDocumentService {
 
     @Override
     public TableDataInfo<TaskCenterAuditListVo> listOnAudit(TaskCenterAuditListBo bo, PageQuery pageQuery) {
-        List<Long> projectIds = projectService.queryIdsOnSubmission(bo.getProjectCode(), bo.getProjectName());
+        List<Long> projectIds = projectService.queryIds(bo.getProjectCode(), bo.getProjectName());
         if (projectIds.isEmpty()) {
             return TableDataInfo.build();
         }
-        List<Long> folderIds = folderService.selectIdsOnSubmission(bo.getCenterName(), projectIds);
+        List<Long> folderIds = folderService.selectIds(bo.getCenterName(), projectIds);
         LambdaQueryWrapper<Document> wrapper = buildAuditListWrapper(bo, folderIds);
         IPage<Document> page = baseMapper.selectPage(pageQuery.build(), wrapper);
         List<Long> ossIds = new ArrayList<>();
         Map<Long, SysOssVo> ossMap = new HashMap<>();
-        page.getRecords().forEach(e -> ossIds.add(e.getOssId()));
+        page.getRecords().forEach(e -> ossIds.add(e.getActualDocument()));
         ossService.queryListByIds(ossIds).forEach(e -> ossMap.put(e.getOssId(), e));
         return TableDataInfo.build(page.convert(e -> {
             TaskCenterAuditListVo vo = new TaskCenterAuditListVo();
@@ -359,9 +374,9 @@ public class DocumentServiceImpl implements IDocumentService {
             vo.setSubmitter(e.getSubmitter());
             vo.setSubmitTime(e.getSubmitTime());
             vo.setCreateTime(e.getCreateTime());
-            vo.setOssId(e.getOssId());
-            vo.setFileName(ossMap.get(e.getOssId()).getOriginalName());
-            vo.setOssUrl(ossMap.get(e.getOssId()).getUrl());
+            vo.setActualDocument(e.getActualDocument());
+            vo.setFileName(ossMap.get(e.getActualDocument()).getOriginalName());
+            vo.setActualDocumentUrl(ossMap.get(e.getActualDocument()).getUrl());
             vo.setType(e.getType());
             vo.setDocumentType(e.getPlanType());
             return vo;
@@ -411,12 +426,12 @@ public class DocumentServiceImpl implements IDocumentService {
     }
 
     private String buildRemark(Long ossId) {
-        Document document = baseMapper.selectOne(Wrappers.lambdaQuery(Document.class).eq(Document::getOssId, ossId));
+        Document document = baseMapper.selectOne(Wrappers.lambdaQuery(Document.class).eq(Document::getActualDocument, ossId));
         // 也有可能直接下载审核版本
         if (document == null) {
             DocumentAuditLog log = auditLogMapper.selectOne(
                 Wrappers.lambdaQuery(DocumentAuditLog.class)
-                    .eq(DocumentAuditLog::getOssId, ossId)
+                    .eq(DocumentAuditLog::getUploadVersion, ossId)
             );
             if (log == null) {
                 throw new BusinessException(MessageUtils.message("document.document.download.notfound"));
@@ -472,7 +487,7 @@ public class DocumentServiceImpl implements IDocumentService {
         List<Long> folderIdsInDocument = new ArrayList<>();
         Map<Long, String> folderMap = new HashMap<>();
         page.getRecords().forEach(e -> {
-            ossIds.add(e.getOssId());
+            ossIds.add(e.getActualDocument());
             folderIdsInDocument.add(e.getFolderId());
         });
         folderService.listByIds(folderIdsInDocument).forEach(e -> folderMap.put(e.getId(), e.getName()));
@@ -485,8 +500,8 @@ public class DocumentServiceImpl implements IDocumentService {
             vo.setSubmitter(e.getSubmitter());
             vo.setSubmitTime(e.getSubmitTime());
             vo.setCreateTime(e.getCreateTime());
-            vo.setOssId(e.getOssId());
-            vo.setOssUrl(ossMap.get(e.getOssId()));
+            vo.setOssId(e.getActualDocument());
+            vo.setOssUrl(ossMap.get(e.getActualDocument()));
             vo.setType(e.getType());
             vo.setDocumentType(e.getPlanType());
             vo.setProjectId(e.getProjectId());
@@ -503,20 +518,20 @@ public class DocumentServiceImpl implements IDocumentService {
         List<Document> documentList = baseMapper.selectList(
             Wrappers.lambdaQuery(Document.class)
                 .eq(Document::getPlanSubmitter, LoginHelper.getUserId())
-                .in(Document::getStatus, List.of(DocumentStatusConst.UN_UPLOAD, DocumentStatusConst.UN_AUDIT, DocumentStatusConst.AUDIT_REJECT))
+                .in(Document::getStatus, List.of(DocumentStatusEnum.UN_UPLOAD.getValue(), DocumentStatusEnum.UN_AUDIT.getValue(), DocumentStatusEnum.AUDIT_REJECT.getValue()))
         );
         vo.setToSubmit(
             documentList
                 .stream()
                 .filter(e ->
-                    e.getStatus().equals(DocumentStatusConst.UN_UPLOAD) || e.getStatus().equals(DocumentStatusConst.AUDIT_REJECT)
+                    e.getStatus().equals(DocumentStatusEnum.UN_UPLOAD.getValue()) || e.getStatus().equals(DocumentStatusEnum.AUDIT_REJECT.getValue())
                 ).toList().size()
         );
         vo.setToAudit(
             documentList
                 .stream()
                 .filter(e ->
-                    e.getStatus().equals(DocumentStatusConst.UN_AUDIT)
+                    e.getStatus().equals(DocumentStatusEnum.UN_AUDIT.getValue())
                 ).toList().size()
         );
         return vo;
@@ -529,7 +544,7 @@ public class DocumentServiceImpl implements IDocumentService {
             Wrappers.lambdaQuery(Document.class)
                 .like(StringUtils.isNotBlank(bo.getName()), Document::getName, bo.getName())
                 .eq(Document::getSubmitter, LoginHelper.getUserId())
-                .ne(Document::getStatus, DocumentStatusConst.UN_UPLOAD)
+                .ne(Document::getStatus, DocumentStatusEnum.UN_UPLOAD.getValue())
                 .orderByDesc(Document::getId)
         );
         return TableDataInfo.build(page.convert(e -> {
@@ -537,7 +552,7 @@ public class DocumentServiceImpl implements IDocumentService {
             vo.setId(e.getId());
             vo.setName(e.getName());
             vo.setCreateTime(e.getSubmitTime());
-            vo.setOssId(e.getOssId());
+            vo.setOssId(e.getActualDocument());
             return vo;
         }));
     }
@@ -557,7 +572,7 @@ public class DocumentServiceImpl implements IDocumentService {
             vo.setId(e.getId());
             vo.setName(e.getName());
             vo.setCreateTime(e.getCreateTime());
-            vo.setOssId(e.getOssId());
+            vo.setOssId(e.getActualDocument());
             vo.setCreateBy(e.getCreateBy());
             vo.setSubmitter(e.getSubmitter());
             vo.setStatus(e.getStatus());
@@ -571,7 +586,7 @@ public class DocumentServiceImpl implements IDocumentService {
             pageQuery.build(),
             Wrappers.lambdaQuery(Document.class)
                 .eq(Document::getPlanSubmitter, LoginHelper.getUserId())
-                .in(Document::getStatus, List.of(DocumentStatusConst.UN_UPLOAD, DocumentStatusConst.AUDIT_REJECT))
+                .in(Document::getStatus, List.of(DocumentStatusEnum.UN_UPLOAD.getValue(), DocumentStatusEnum.AUDIT_REJECT.getValue()))
                 .like(StringUtils.isNotBlank(bo.getName()), Document::getName, bo.getName())
                 .orderByDesc(Document::getId)
         );
@@ -636,10 +651,11 @@ public class DocumentServiceImpl implements IDocumentService {
         return baseMapper.update(
             Wrappers.lambdaUpdate(Document.class)
                 .eq(Document::getId, bo.getDocumentId())
-                .set(Document::getOssId, ossVo.getOssId())
-                .set(Document::getStatus, DocumentStatusConst.UN_AUDIT)
+                .set(Document::getActualDocument, ossVo.getOssId())
+                .set(Document::getStatus, DocumentStatusEnum.UN_AUDIT.getValue())
                 .set(Document::getSubmitter, LoginHelper.getUserId())
                 .set(Document::getSubmitTime, new Date())
+                .set(Document::getEffectiveDate, bo.getEffectiveDate())
         ) > 0;
     }
 
@@ -662,7 +678,7 @@ public class DocumentServiceImpl implements IDocumentService {
 
             byte[] pdfBytes = Base64.getDecoder().decode(cleanBase64);
 
-            Path tempPath = Files.createTempFile("document_", "_" + i + ".pdf");
+            Path tempPath = Files.createTempFile(IdUtil.fastSimpleUUID(), ".pdf");
             Files.write(tempPath, pdfBytes);
             files.add(tempPath.toFile());
         }
@@ -697,8 +713,8 @@ public class DocumentServiceImpl implements IDocumentService {
         Document document = new Document();
         document.setFolderId(bo.getFolderId());
         document.setName(bo.getFileName());
-        document.setStatus(DocumentStatusConst.UN_AUDIT);
-        document.setOssId(ossVo.getOssId());
+        document.setStatus(DocumentStatusEnum.UN_AUDIT.getValue());
+        document.setActualDocument(ossVo.getOssId());
         document.setNote(bo.getNote());
         document.setType(DocumentTypeConst.NOT_PLAN);
         document.setSubmitter(LoginHelper.getUserId());
@@ -763,10 +779,11 @@ public class DocumentServiceImpl implements IDocumentService {
         );
         for (Document document : documents) {
             if (document.getName().equals(bo.getName())) {
-                document.setOssId(ossVo.getOssId());
+                document.setActualDocument(ossVo.getOssId());
                 document.setSubmitter(LoginHelper.getUserId());
                 document.setSubmitTime(new Date());
-                document.setStatus(DocumentStatusConst.UN_AUDIT);
+                document.setStatus(DocumentStatusEnum.UN_AUDIT.getValue());
+                document.setEffectiveDate(bo.getEffectiveDate());
                 return baseMapper.updateById(document) > 0;
             }
         }
@@ -774,12 +791,13 @@ public class DocumentServiceImpl implements IDocumentService {
         Document document = new Document();
         document.setFolderId(bo.getCenter() != 0L ? bo.getCenter() : bo.getCountry());
         document.setName(bo.getName());
-        document.setStatus(DocumentStatusConst.UN_AUDIT);
-        document.setOssId(ossVo.getOssId());
+        document.setStatus(DocumentStatusEnum.UN_AUDIT.getValue());
+        document.setActualDocument(ossVo.getOssId());
         document.setType(DocumentTypeConst.NOT_PLAN);
         document.setSubmitter(LoginHelper.getUserId());
         document.setSubmitTime(new Date());
         document.setProjectId(bo.getProjectId());
+        document.setEffectiveDate(bo.getEffectiveDate());
         document.setSpecificationType(bo.getCenter() != 0L ? SpecificationTypeConst.CENTER : SpecificationTypeConst.PROJECT);
         document.setTenantId(TenantHelper.getTenantId());
 
@@ -795,6 +813,207 @@ public class DocumentServiceImpl implements IDocumentService {
         );
     }
 
+    @Override
+    public boolean removeTemp(Long documentId) {
+        return baseMapper.deleteById(documentId) > 0;
+    }
+
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public boolean specify(DocumentSpecifyBo bo) {
+
+        Document originDocument = baseMapper.selectById(bo.getDocumentId());
+
+        if (bo.getMissingDocumentId() != null) {
+            Document document = baseMapper.selectById(bo.getMissingDocumentId());
+            document.setActualDocument(originDocument.getActualDocument());
+            document.setSubmitter(originDocument.getSubmitter());
+            document.setSubmitTime(originDocument.getSubmitTime());
+            document.setStatus(DocumentStatusEnum.UN_AUDIT.getValue());
+            boolean updateFlag = baseMapper.updateById(document) == 0;
+            if (updateFlag) {
+                throw new RuntimeException("修改目标文件失败");
+            }
+            boolean deleteFlag = baseMapper.deleteById(originDocument) == 0;
+            if (deleteFlag) {
+                throw new RuntimeException("删除临时文件失败");
+            }
+            return true;
+        } else {
+            if (bo.getFolderId() == null) {
+                throw new BusinessException(MessageUtils.message("document.document.temp.specify.nowhere"));
+            }
+            originDocument.setFolderId(bo.getFolderId());
+            return baseMapper.updateById(originDocument) > 0;
+        }
+
+    }
+
+    @Override
+    public TableDataInfo<DocumentListOnSpecifyVo> listOnSpecify(DocumentListOnSpecifyBo bo, PageQuery pageQuery) {
+        List<Folder> folders = folderService.queryByProjectIds(List.of(bo.getProjectId()));
+        Map<Long, Folder> folderMap = new HashMap<>();
+        List<Long> folderIds = new ArrayList<>();
+        folders.forEach(e -> {
+            folderIds.add(e.getId());
+            folderMap.put(e.getId(), e);
+        });
+        IPage<Document> page = baseMapper.selectPage(pageQuery.build(), buildSpecifyListWrapper(bo, folderIds));
+        return TableDataInfo.build(page.convert(e -> {
+            DocumentListOnSpecifyVo vo = new DocumentListOnSpecifyVo();
+            vo.setId(e.getId());
+            vo.setName(e.getName());
+            StringBuilder folder = new StringBuilder();
+            long current = e.getFolderId();
+            for (;;) {
+                Folder currentFolder = folderMap.get(current);
+                folder.insert(0, currentFolder.getName()).insert(0, "/");
+                if (currentFolder.getParentId() == null) {
+                    break;
+                }
+                current = currentFolder.getParentId();
+            }
+            vo.setFolder(folder.toString());
+            vo.setStatus(e.getStatus());
+            vo.setDeadline(e.getSubmitDeadline());
+            vo.setPlanSubmitter(e.getPlanSubmitter());
+            vo.setCreateBy(e.getCreateBy());
+            vo.setCreateTime(e.getCreateTime());
+            return vo;
+        }));
+    }
+
+    @Override
+    public List<ProjectExcel> getListByProjectId(Long projectId) {
+        List<Document> documentList = baseMapper.selectList(
+            Wrappers.lambdaQuery(Document.class)
+                .eq(Document::getProjectId, projectId)
+        );
+        List<Long> ossIds = new ArrayList<>();
+        List<Long> userIds = new ArrayList<>();
+        Map<Long, SysOssVo> ossMap = new HashMap<>();
+        Map<Long, SysUser> userMap = new HashMap<>();
+        Map<String, String> planType = new HashMap<>();
+        documentList.forEach(e -> {
+            ossIds.add(e.getActualDocument());
+            userIds.add(e.getPlanSubmitter());
+            userIds.add(e.getCreateBy());
+            userIds.add(e.getSubmitter());
+        });
+        ossService.queryListByIds(ossIds).forEach(e -> ossMap.put(e.getOssId(), e));
+        userService.selectUserByIds(userIds).forEach(e -> userMap.put(e.getUserId(), e));
+        dictTypeService.selectDictDataByType(DictTypeConst.PLAN_DOCUMENT_TYPE).forEach(e -> planType.put(e.getDictValue(), e.getDictLabel()));
+        Project project = projectService.queryById(projectId);
+        List<Folder> folders = folderService.queryByProjectId(projectId);
+        Map<Long, Folder> folderMap = new HashMap<>();
+        folders.forEach(e -> folderMap.put(e.getId(), e));
+        List<ProjectExcel> list = new ArrayList<>();
+        for (Document document : documentList) {
+            ProjectExcel excel = new ProjectExcel();
+            excel.setId(document.getId());
+            excel.setName(document.getName());
+            excel.setStatus(DocumentStatusEnum.getLabel(document.getStatus()));
+            excel.setActualDocumentName(
+                Optional.ofNullable(document.getActualDocument())
+                    .map(ossMap::get)
+                    .map(SysOssVo::getOriginalName)
+                    .orElse("-")
+            );
+            long currentFolder = document.getFolderId();
+            if (currentFolder != 0L) {
+                for (;;) {
+                    Folder folder = folderMap.get(currentFolder);
+                    if (folder.getType().equals(FolderTypeConst.CENTER)) {
+                        excel.setCenterId(currentFolder);
+                        excel.setCenterName(folder.getName());
+                        break;
+                    }
+                    if (folder.getType().equals(FolderTypeConst.NORMAL)) {
+                        if (folder.getParentId() != null) {
+                            currentFolder = folder.getParentId();
+                            continue;
+                        } else {
+                            break;
+                        }
+                    }
+                    break;
+                }
+            } else {
+                excel.setCenterName("-");
+            }
+            excel.setPlanSubmitter(
+                Optional.ofNullable(document.getPlanSubmitter())
+                    .map(userMap::get)
+                    .map(e -> e.getNickName() + "(" + e.getEmail() + ")")
+                    .orElse("-")
+            );
+            excel.setDeadline(
+                Optional.ofNullable(document.getSubmitDeadline())
+                    .map(Date::toString)
+                    .orElse("-")
+            );
+            Date submitTime = Optional.ofNullable(document.getSubmitTime()).orElse(new Date());
+            excel.setDaysOverdue(
+                Optional.ofNullable(document.getSubmitDeadline())
+                    .map(deadline -> {
+                        LocalDate dueLocalDate = deadline.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
+                        LocalDate submitLocalDate = submitTime.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
+                        if (!submitLocalDate.isAfter(dueLocalDate)) {
+                            return 0L;
+                        }
+                        return ChronoUnit.DAYS.between(dueLocalDate, submitLocalDate);
+                    })
+                    .orElse(0L)
+            );
+            excel.setCreateBy(
+                Optional.ofNullable(document.getCreateBy())
+                    .map(userMap::get)
+                    .map(SysUser::getNickName)
+                    .orElse("-")
+            );
+            StringBuilder path = new StringBuilder();
+            if (document.getFolderId() != 0L) {
+                Folder current = folderMap.get(document.getFolderId());
+                for (;;) {
+                    path.insert(0, current.getName()).insert(0, "/");
+                    if (current.getParentId() == null) {
+                        break;
+                    }
+                    current = folderMap.get(current.getParentId());
+                }
+                excel.setPath(path.toString());
+            } else {
+                excel.setName("-");
+            }
+            excel.setSubmitTime(
+                Optional.ofNullable(document.getSubmitTime())
+                    .map(Date::toString)
+                    .orElse("-")
+            );
+            excel.setSubmitter(
+                Optional.ofNullable(document.getSubmitter())
+                    .map(userMap::get)
+                    .map(SysUser::getNickName)
+                    .orElse("-")
+            );
+            excel.setProjectName(project.getName());
+            if (StringUtils.isNotBlank(document.getPlanType())) {
+                Dict label = JsonUtils.parseMap(planType.get(document.getPlanType()));
+                excel.setPlanType(LocaleContextHolder.getLocale().getLanguage().equals("zh") ? label.getStr("zh_CN") : label.getStr("en_US"));
+            }
+            list.add(excel);
+        }
+        return list;
+    }
+
+    private LambdaQueryWrapper<Document> buildSpecifyListWrapper(DocumentListOnSpecifyBo bo, List<Long> folderIds) {
+        return Wrappers.lambdaQuery(Document.class)
+            .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()))
+            .orderByDesc(Document::getId);
+    }
+
     private void buildFolders(List<Long> selected, Folder folder, Map<Long, List<Folder>> childrenMap) {
         selected.add(folder.getId());
         List<Folder> childrens = childrenMap.get(folder.getId());
@@ -809,7 +1028,7 @@ public class DocumentServiceImpl implements IDocumentService {
             .like(StringUtils.isNotBlank(bo.getName()), Document::getName, bo.getName())
             .eq(Document::getCreateBy, LoginHelper.getUserId())
             .in(!folderIds.isEmpty(), Document::getFolderId, folderIds)
-            .eq(Document::getStatus, DocumentStatusConst.UN_FILING)
+            .eq(Document::getStatus, DocumentStatusEnum.UN_ARCHIEVED.getValue())
             .orderByDesc(Document::getId);
     }
 
@@ -829,9 +1048,9 @@ public class DocumentServiceImpl implements IDocumentService {
     private LambdaQueryWrapper<Document> buildAuditListWrapper(TaskCenterAuditListBo bo, List<Long> folderIds) {
         return Wrappers.lambdaQuery(Document.class)
             .like(StringUtils.isNotBlank(bo.getName()), Document::getName, bo.getName())
-            .eq(Document::getSubmitter, LoginHelper.getUserId())
+            .eq(Document::getCreateBy, LoginHelper.getUserId())
             .in(!folderIds.isEmpty(), Document::getFolderId, folderIds)
-            .eq(Document::getStatus, DocumentStatusConst.UN_AUDIT)
+            .eq(Document::getStatus, DocumentStatusEnum.UN_AUDIT.getValue())
             .orderByDesc(Document::getId);
     }
 
@@ -841,25 +1060,20 @@ public class DocumentServiceImpl implements IDocumentService {
             .eq(bo.getStatus() != null, Document::getStatus, bo.getStatus())
             .eq(Document::getPlanSubmitter, LoginHelper.getUserId())
             .in(!folderIds.isEmpty(), Document::getFolderId, folderIds)
-            .in(Document::getStatus, List.of(DocumentStatusConst.UN_UPLOAD, DocumentStatusConst.AUDIT_REJECT))
+            .in(Document::getStatus, List.of(DocumentStatusEnum.UN_UPLOAD.getValue(), DocumentStatusEnum.AUDIT_REJECT.getValue()))
             .orderByDesc(Document::getId);
     }
 
     private DocumentAuditLog buildLog(Document document, String type, DocumentAuditBo bo) {
         DocumentAuditLog log = new DocumentAuditLog();
         log.setDocumentId(document.getId());
-        log.setOssId(document.getOssId());
+        log.setUploadVersion(document.getActualDocument());
         log.setAuditorType(type);
         log.setAuditor(LoginHelper.getUserId());
         log.setResult(bo.getResult());
         log.setRejectReason(bo.getRejectReason());
         log.setAuditTime(new Date());
         log.setTenantId(TenantHelper.getTenantId());
-        log.setCreateDept(LoginHelper.getDeptId());
-        log.setCreateBy(LoginHelper.getUserId());
-        log.setCreateTime(new Date());
-        log.setUpdateBy(LoginHelper.getUserId());
-        log.setUpdateTime(new Date());
         log.setSubmitter(document.getSubmitter());
         return log;
     }

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

@@ -367,14 +367,14 @@ public class ProjectServiceImpl implements IProjectService {
                     .toList();
                 if (total > 0L) {
                     onTimeSubmit = planDocuments.stream()
-                        .filter(item -> item.getOssId() != null && item.getSubmitTime().before(item.getSubmitDeadline()))
+                        .filter(item -> item.getActualDocument() != null && item.getSubmitTime().before(item.getSubmitDeadline()))
                         .count();
                     lateSubmit = planDocuments.stream()
-                        .filter(item -> item.getOssId() != null)
+                        .filter(item -> item.getActualDocument() != null)
                         .filter(item -> item.getSubmitDeadline().before(item.getSubmitTime()))
                         .count();
                     notSubmit = planDocuments.stream()
-                        .filter(item -> item.getOssId() == null)
+                        .filter(item -> item.getActualDocument() == null)
                         .filter(item -> item.getSubmitDeadline().before(new Date()))
                         .count();
                 }

+ 23 - 21
script/sql/business/create.sql

@@ -99,7 +99,7 @@ CREATE TABLE `document_audit_log`
 ) ENGINE = InnoDB
   DEFAULT CHARSET = utf8mb4 COMMENT ='文档审核记录';
 
-CREATE TABLE `document_quality_control_task`
+CREATE TABLE `document_qc_task`
 (
     `id`          bigint unsigned PRIMARY KEY NOT NULL AUTO_INCREMENT COMMENT '序号',
     `name`        varchar(128)                NOT NULL COMMENT '质控名称',
@@ -119,7 +119,7 @@ CREATE TABLE `document_quality_control_task`
 ) ENGINE = InnoDB
   DEFAULT CHARSET = utf8mb4 COMMENT ='文档质控任务';
 
-CREATE TABLE `document_quality_control_task_detail`
+CREATE TABLE `document_qc_task_detail`
 (
     `id`          bigint unsigned PRIMARY KEY NOT NULL AUTO_INCREMENT COMMENT '序号',
     `task_id`     bigint unsigned             NOT NULL COMMENT '所属任务',
@@ -138,25 +138,27 @@ CREATE TABLE `document_quality_control_task_detail`
 ) ENGINE = InnoDB
   DEFAULT CHARSET = utf8mb4 COMMENT ='文档质控细节';
 
-CREATE TABLE `document_quality_control_task_log`
+CREATE TABLE `document_qc_task_log`
 (
-    `id`            bigint unsigned PRIMARY KEY NOT NULL AUTO_INCREMENT COMMENT '序号',
-    `task_id`       bigint unsigned             NOT NULL COMMENT '质控任务',
-    `detail_id`     bigint unsigned             NOT NULL COMMENT '指控环节',
-    `executor`      bigint unsigned             NOT NULL COMMENT '执行人',
-    `execute_time`  datetime COMMENT '执行时间',
-    `result`        tinyint(1) unsigned COMMENT '质控结果',
-    `question_type` char(1) COMMENT '问题分类',
-    `option`        varchar(255) COMMENT '质控意见',
-    `dealer`        bigint COMMENT '指定处理人',
-    `deadline`      date COMMENT '处理截止日期',
-    `create_dept`   bigint(20) COMMENT '创建部门',
-    `create_by`     bigint(20) COMMENT '创建者',
-    `create_time`   datetime COMMENT '创建时间',
-    `update_by`     bigint(20) COMMENT '更新者',
-    `update_time`   datetime COMMENT '更新时间',
-    `del_flag`      char(1) DEFAULT '0' COMMENT '删除标志(0代表存在 1代表删除)',
-    `tenant_id`     varchar(40) COMMENT '租户id'
+    `id`                bigint unsigned PRIMARY KEY NOT NULL AUTO_INCREMENT COMMENT '序号',
+    `task_id`           bigint unsigned             NOT NULL COMMENT '质控任务',
+    `detail_id`         bigint unsigned             NOT NULL COMMENT '指控环节',
+    `executor`          bigint unsigned             NOT NULL COMMENT '执行人',
+    `execute_time`      datetime                    NOT NULL COMMENT '执行时间',
+    `result`            tinyint(1) unsigned         NOT NULL COMMENT '质控结果',
+    `question_type`     char(1) COMMENT '问题分类',
+    `option`            varchar(255) COMMENT '质控意见',
+    `designated_dealer` bigint unsigned COMMENT '指定处理人',
+    `deadline`          date COMMENT '处理截止日期',
+    `actual_dealer`     bigint unsigned COMMENT '实际处理人',
+    `deal_time`         datetime COMMENT '处理时间',
+    `create_dept`       bigint(20) COMMENT '创建部门',
+    `create_by`         bigint(20) COMMENT '创建者',
+    `create_time`       datetime COMMENT '创建时间',
+    `update_by`         bigint(20) COMMENT '更新者',
+    `update_time`       datetime COMMENT '更新时间',
+    `del_flag`          char(1) DEFAULT '0' COMMENT '删除标志(0代表存在 1代表删除)',
+    `tenant_id`         varchar(40) COMMENT '租户id'
 ) ENGINE = InnoDB
   DEFAULT CHARSET = utf8mb4 COMMENT ='文档质控日志';
 
@@ -215,7 +217,7 @@ CREATE TABLE `textin_setting`
     `create_time` datetime COMMENT '创建时间',
     `update_by`   bigint(20) COMMENT '更新者',
     `update_time` datetime COMMENT '更新时间',
-    `del_flag`    char(1)                              DEFAULT '0' COMMENT '删除标志(0代表存在 1代表删除)',
+    `del_flag`    char(1) DEFAULT '0' COMMENT '删除标志(0代表存在 1代表删除)',
     `tenant_id`   varchar(40) COMMENT '租户id'
 ) ENGINE = InnoDB
   DEFAULT CHARSET = utf8mb4 COMMENT ='合合信息科技设置';