Kaynağa Gözat

- WPS审核功能基本完成
- 小程序接口基本完善

Huanyi 3 ay önce
ebeveyn
işleme
8bad6913db
30 değiştirilmiş dosya ile 1269 ekleme ve 161 silme
  1. 17 0
      ruoyi-modules/ruoyi-system/src/main/java/com/yingpaipay/system/domain/vo/FolderPermissionVo.java
  2. 3 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysOssService.java
  3. 9 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysUserService.java
  4. 33 4
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysOssServiceImpl.java
  5. 42 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysUserServiceImpl.java
  6. 105 0
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/controller/DocumentQualityControlTaskController.java
  7. 194 58
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/controller/WpsController.java
  8. 37 0
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/controller/applet/AppletMyInfoController.java
  9. 8 0
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/controller/applet/AppletMyTaskController.java
  10. 31 5
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/controller/applet/AppletScanController.java
  11. 74 0
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/domain/DocumentQualityControlTask.java
  12. 10 0
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/domain/bo/AppletMyInfoEditAvatarBo.java
  13. 10 0
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/domain/bo/AppletMyInfoEditGenderBo.java
  14. 10 0
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/domain/bo/AppletMyInfoEditNicknameBo.java
  15. 27 0
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/domain/bo/AppletUploadNewBo.java
  16. 73 0
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/domain/bo/DocumentQualityControlTaskBo.java
  17. 19 0
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/domain/dto/WpsGetVersionsDto.java
  18. 24 0
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/domain/dto/WpsVersionControlDto.java
  19. 26 0
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/domain/dto/WpsVersionDto.java
  20. 18 0
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/domain/vo/AppletGetRejectionVo.java
  21. 2 0
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/domain/vo/AppletMyTaskDocumentVo.java
  22. 111 0
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/domain/vo/DocumentQualityControlTaskVo.java
  23. 2 0
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/domain/vo/TaskCenterAuditListVo.java
  24. 15 0
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/mapper/DocumentQualityControlTaskMapper.java
  25. 68 0
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/service/IDocumentQualityControlTaskService.java
  26. 4 0
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/service/IDocumentService.java
  27. 7 0
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/service/impl/CommonDocumentService.java
  28. 145 0
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/service/impl/DocumentQualityControlTaskServiceImpl.java
  29. 118 67
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/service/impl/DocumentServiceImpl.java
  30. 27 27
      script/sql/business/create.sql

+ 17 - 0
ruoyi-modules/ruoyi-system/src/main/java/com/yingpaipay/system/domain/vo/FolderPermissionVo.java

@@ -0,0 +1,17 @@
+package com.yingpaipay.system.domain.vo;
+
+import lombok.AllArgsConstructor;import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+
+@Data
+@AllArgsConstructor
+public class FolderPermissionVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    private String content;
+
+}

+ 3 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysOssService.java

@@ -79,4 +79,7 @@ public interface ISysOssService {
      */
     Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
 
+    boolean updateUrlByOssId(Long ossId, String url);
+
+    SysOssVo insertByUrl(String fileName, String originalFileName, String url);
 }

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

@@ -2,6 +2,7 @@ package org.dromara.system.service;
 
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.yingpaipay.system.domain.bo.ListOnNameNotJoinProjectBo;
+import com.yingpaipay.system.domain.vo.FolderPermissionVo;
 import com.yingpaipay.system.domain.vo.SysUserSignatureVo;
 import org.dromara.common.mybatis.core.page.PageQuery;
 import org.dromara.common.mybatis.core.page.TableDataInfo;
@@ -243,4 +244,12 @@ public interface ISysUserService {
     IPage<SysUser> selectPageByNameAndIds(String name, List<Long> userIds, PageQuery pageQuery);
 
     SysUserSignatureVo getSignature();
+
+    FolderPermissionVo selectUserFolderPermissionByProjectId(Long projectId);
+
+    boolean updateNickname(String nickname);
+
+    boolean updateGender(String gender);
+
+    boolean updateAvatar(Long avatar);
 }

+ 33 - 4
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysOssServiceImpl.java

@@ -24,6 +24,8 @@ import org.dromara.common.oss.core.OssClient;
 import org.dromara.common.oss.entity.UploadResult;
 import org.dromara.common.oss.enums.AccessPolicyType;
 import org.dromara.common.oss.factory.OssFactory;
+import org.dromara.common.satoken.utils.LoginHelper;
+import org.dromara.common.tenant.helper.TenantHelper;
 import org.dromara.system.domain.SysOss;
 import org.dromara.system.domain.SysOssExt;
 import org.dromara.system.domain.bo.SysOssBo;
@@ -39,10 +41,7 @@ import org.springframework.web.multipart.MultipartFile;
 import java.io.File;
 import java.io.IOException;
 import java.time.Duration;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
 
 /**
  * 文件上传 服务层实现
@@ -268,6 +267,36 @@ public class SysOssServiceImpl implements ISysOssService, OssService {
         return baseMapper.deleteByIds(ids) > 0;
     }
 
+    @Override
+    public boolean updateUrlByOssId(Long ossId, String url) {
+        return baseMapper.update(
+            Wrappers.lambdaUpdate(SysOss.class)
+                .eq(SysOss::getOssId, ossId)
+                .set(SysOss::getUrl, url)
+        ) == 0;
+    }
+
+    @Override
+    public SysOssVo insertByUrl(String fileName, String originalFileName, String url) {
+        SysOss oss = new SysOss();
+        oss.setFileName(fileName);
+        oss.setOriginalName(originalFileName);
+        oss.setFileSuffix("\\." + originalFileName.split("\\.")[1]);
+        oss.setUrl(url);
+        oss.setService(OssFactory.instance().getConfigKey());
+        oss.setTenantId(TenantHelper.getTenantId());
+        oss.setCreateDept(LoginHelper.getDeptId());
+        oss.setCreateBy(LoginHelper.getUserId());
+        oss.setCreateTime(new Date());
+        oss.setUpdateBy(LoginHelper.getUserId());
+        oss.setUpdateTime(new Date());
+        boolean flag = baseMapper.insert(oss) == 0;
+        if (flag) {
+            throw new RuntimeException("插入OSS数据库失败");
+        }
+        return MapstructUtils.convert(oss, SysOssVo.class);
+    }
+
     /**
      * 桶类型为 private 的URL 修改为临时URL时长为120s
      *

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

@@ -12,9 +12,12 @@ import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.yingpaipay.system.domain.SysUserFolders;
 import com.yingpaipay.system.domain.SysUserProjects;
 import com.yingpaipay.system.domain.bo.ListOnNameNotJoinProjectBo;
+import com.yingpaipay.system.domain.vo.FolderPermissionVo;
 import com.yingpaipay.system.domain.vo.SysUserSignatureVo;
+import com.yingpaipay.system.mapper.SysUserFoldersMapper;
 import com.yingpaipay.system.mapper.SysUserProjectsMapper;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
@@ -58,6 +61,7 @@ public class SysUserServiceImpl implements ISysUserService, UserService {
     private final SysUserRoleMapper userRoleMapper;
     private final SysUserPostMapper userPostMapper;
     private final SysUserProjectsMapper userProjectsMapper;
+    private final SysUserFoldersMapper userFoldersMapper;
     private final SysOssMapper ossMapper;
 
     @Override
@@ -651,6 +655,44 @@ public class SysUserServiceImpl implements ISysUserService, UserService {
         );
     }
 
+    @Override
+    public FolderPermissionVo selectUserFolderPermissionByProjectId(Long projectId) {
+        return new FolderPermissionVo(
+            userFoldersMapper.selectOne(
+                Wrappers.lambdaQuery(SysUserFolders.class)
+                    .eq(SysUserFolders::getUserId, LoginHelper.getUserId())
+                    .eq(SysUserFolders::getProjectId, projectId)
+            ).getFolders()
+        );
+    }
+
+    @Override
+    public boolean updateNickname(String nickname) {
+        return baseMapper.update(
+            Wrappers.lambdaUpdate(SysUser.class)
+                .eq(SysUser::getUserId, LoginHelper.getUserId())
+                .set(SysUser::getNickName, nickname)
+        ) > 0;
+    }
+
+    @Override
+    public boolean updateGender(String gender) {
+        return baseMapper.update(
+            Wrappers.lambdaUpdate(SysUser.class)
+                .eq(SysUser::getUserId, LoginHelper.getUserId())
+                .set(SysUser::getSex, gender)
+        ) > 0;
+    }
+
+    @Override
+    public boolean updateAvatar(Long avatar) {
+        return baseMapper.update(
+            Wrappers.lambdaUpdate(SysUser.class)
+                .eq(SysUser::getUserId, LoginHelper.getUserId())
+                .set(SysUser::getAvatar, avatar)
+        ) > 0;
+    }
+
     /**
      * 通过用户ID查询用户账户
      *

+ 105 - 0
ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/controller/DocumentQualityControlTaskController.java

@@ -0,0 +1,105 @@
+package com.yingpaipay.business.controller;
+
+import java.util.List;
+
+import lombok.RequiredArgsConstructor;
+import jakarta.servlet.http.HttpServletResponse;
+import jakarta.validation.constraints.*;
+import cn.dev33.satoken.annotation.SaCheckPermission;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.validation.annotation.Validated;
+import org.dromara.common.idempotent.annotation.RepeatSubmit;
+import org.dromara.common.log.annotation.Log;
+import org.dromara.common.web.core.BaseController;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.core.domain.R;
+import org.dromara.common.core.validate.AddGroup;
+import org.dromara.common.core.validate.EditGroup;
+import org.dromara.common.log.enums.BusinessType;
+import org.dromara.common.excel.utils.ExcelUtil;
+import com.yingpaipay.business.domain.vo.DocumentQualityControlTaskVo;
+import com.yingpaipay.business.domain.bo.DocumentQualityControlTaskBo;
+import com.yingpaipay.business.service.IDocumentQualityControlTaskService;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+
+/**
+ * 文档质控任务
+ *
+ * @author Huanyi
+ * @date 2026-01-06
+ */
+@Validated
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/qc/task")
+public class DocumentQualityControlTaskController extends BaseController {
+
+    private final IDocumentQualityControlTaskService documentQualityControlTaskService;
+
+    /**
+     * 查询文档质控任务列表
+     */
+    @SaCheckPermission("qc:task:list")
+    @GetMapping("/list")
+    public TableDataInfo<DocumentQualityControlTaskVo> list(DocumentQualityControlTaskBo bo, PageQuery pageQuery) {
+        return documentQualityControlTaskService.queryPageList(bo, pageQuery);
+    }
+
+    /**
+     * 导出文档质控任务列表
+     */
+    @SaCheckPermission("qc:task:export")
+    @Log(title = "文档质控任务", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(DocumentQualityControlTaskBo bo, HttpServletResponse response) {
+        List<DocumentQualityControlTaskVo> list = documentQualityControlTaskService.queryList(bo);
+        ExcelUtil.exportExcel(list, "文档质控任务", DocumentQualityControlTaskVo.class, response);
+    }
+
+    /**
+     * 获取文档质控任务详细信息
+     *
+     * @param id 主键
+     */
+    @SaCheckPermission("qc:task:query")
+    @GetMapping("/{id}")
+    public R<DocumentQualityControlTaskVo> getInfo(@NotNull(message = "主键不能为空")
+                                     @PathVariable Long id) {
+        return R.ok(documentQualityControlTaskService.queryById(id));
+    }
+
+    /**
+     * 新增文档质控任务
+     */
+    @SaCheckPermission("qc:task:add")
+    @Log(title = "文档质控任务", businessType = BusinessType.INSERT)
+    @RepeatSubmit()
+    @PostMapping()
+    public R<Void> add(@Validated(AddGroup.class) @RequestBody DocumentQualityControlTaskBo bo) {
+        return toAjax(documentQualityControlTaskService.insertByBo(bo));
+    }
+
+    /**
+     * 修改文档质控任务
+     */
+    @SaCheckPermission("qc:task:edit")
+    @Log(title = "文档质控任务", businessType = BusinessType.UPDATE)
+    @RepeatSubmit()
+    @PutMapping()
+    public R<Void> edit(@Validated(EditGroup.class) @RequestBody DocumentQualityControlTaskBo bo) {
+        return toAjax(documentQualityControlTaskService.updateByBo(bo));
+    }
+
+    /**
+     * 删除文档质控任务
+     *
+     * @param ids 主键串
+     */
+    @SaCheckPermission("qc:task:remove")
+    @Log(title = "文档质控任务", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{ids}")
+    public R<Void> remove(@NotEmpty(message = "主键不能为空")
+                          @PathVariable Long[] ids) {
+        return toAjax(documentQualityControlTaskService.deleteWithValidByIds(List.of(ids), true));
+    }
+}

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

@@ -1,22 +1,29 @@
 package com.yingpaipay.business.controller;
 
 import com.yingpaipay.business.domain.Document;
+import com.yingpaipay.business.domain.dto.WpsGetVersionsDto;
 import com.yingpaipay.business.domain.dto.WpsR;
+import com.yingpaipay.business.domain.dto.WpsVersionControlDto;
+import com.yingpaipay.business.domain.dto.WpsVersionDto;
 import com.yingpaipay.business.service.impl.CommonDocumentService;
 import jakarta.servlet.http.HttpServletRequest;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.dromara.common.core.domain.R;
+import org.dromara.common.core.exception.BusinessException;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.json.utils.JsonUtils;
+import org.dromara.common.oss.core.OssClient;
+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.vo.SysOssVo;
 import org.dromara.system.domain.vo.SysUserVo;
 import org.dromara.system.service.ISysOssService;
 import org.dromara.system.service.ISysUserService;
-import org.springframework.http.HttpMethod;
 import org.springframework.http.MediaType;
-import org.springframework.http.ResponseEntity;
 import org.springframework.web.bind.annotation.*;
-import org.springframework.web.client.RestTemplate;
 
 import java.io.File;
 import java.io.FileOutputStream;
@@ -31,18 +38,23 @@ import java.util.concurrent.ConcurrentHashMap;
 @Slf4j
 public class WpsController extends BaseController {
 
-    private static final Map<Long, Long> DOCUMENT_MAP = new ConcurrentHashMap<>();
+    /**
+     * 这里为版本控制缓存
+     */
+    private static final Map<Long, WpsVersionControlDto> DOCUMENT_MAP = new ConcurrentHashMap<>();
 
     private final ISysOssService ossService;
     private final CommonDocumentService documentService;
     private final ISysUserService userService;
 
     @PutMapping(value = "/upload/file/{documentId}", consumes = MediaType.APPLICATION_OCTET_STREAM_VALUE)
-    public void upload(@PathVariable Long documentId, HttpServletRequest request) {
+    public void upload(@PathVariable String documentId, HttpServletRequest request) {
+        String[] ids = documentId.split("_");
+        WpsVersionControlDto dto = DOCUMENT_MAP.get(Long.valueOf(ids[0]));
         File tempFile = null;
         try {
 
-            tempFile = File.createTempFile("upload_doc_" + documentId + "_", ".tmp");
+            tempFile = File.createTempFile(dto.getFileName() + "_", dto.getSuffix());
 
             try (InputStream in = request.getInputStream();
                  FileOutputStream out = new FileOutputStream(tempFile)) {
@@ -53,8 +65,22 @@ public class WpsController extends BaseController {
                 }
             }
 
-            SysOssVo vo = ossService.upload(tempFile);
-            DOCUMENT_MAP.put(documentId, vo.getOssId());
+            // TODO 防止自增ID过早炸掉,这里采用更新操作,不使用自带的图片上传
+            String originalfileName = tempFile.getName();
+            String suffix = StringUtils.substring(originalfileName, originalfileName.lastIndexOf("."));
+            OssClient storage = OssFactory.instance();
+            UploadResult uploadResult = storage.uploadSuffix(tempFile, suffix, originalfileName);
+            dto.setCurrentVersion(Long.parseLong(ids[1]));
+            List<WpsVersionDto> versions = dto.getVersions();
+            for (WpsVersionDto version : versions) {
+                if (Objects.equals(version.getVersion(), Long.valueOf(ids[1]))) {
+                    version.setFileName(uploadResult.getFilename());
+                    version.setUrl(uploadResult.getUrl());
+                    version.setUpdateTime(new Date());
+                }
+            }
+//            dto.getVersions().get(Integer.parseInt(ids[1])).setFileName(uploadResult.getFilename());
+//            dto.getVersions().get(Integer.parseInt(ids[1])).setUrl(uploadResult.getUrl());
 
         } catch (IOException e) {
             log.error("文件写入失败, documentId={}", documentId, e);
@@ -76,11 +102,11 @@ public class WpsController extends BaseController {
     ) {}
 
     @PostMapping("/files/{documentId}/upload/complete")
-    public WpsR complete(@PathVariable Long documentId, @RequestBody WpsFilesCompleteRequestDto dto) {
+    public WpsR complete(@PathVariable String documentId, @RequestBody WpsFilesCompleteRequestDto dto) {
         Map<String, Object> request = (LinkedHashMap<String, Object>) dto.request;
         return WpsR.ok(
             new WpsFilesCompleteResponseDto(
-                String.valueOf(request.get("file_id")), String.valueOf(request.get("name")), 2, Integer.valueOf(String.valueOf(request.get("size"))), Math.toIntExact(new Date().getTime() / 1000L), Math.toIntExact(new Date().getTime() / 1000L), "1", "1"
+                String.valueOf(request.get("file_id")), String.valueOf(request.get("name")), 1, Integer.valueOf(String.valueOf(request.get("size"))), Math.toIntExact(System.currentTimeMillis() / 1000L), Math.toIntExact(System.currentTimeMillis() / 1000L), "1", "1"
             )
         );
     }
@@ -88,7 +114,7 @@ public class WpsController extends BaseController {
     private record WpsUplaodPrepareDto(String[] digest_types) {}
 
     @GetMapping("/files/{documentId}/upload/prepare")
-    public WpsR<WpsUplaodPrepareDto> uploadPrepare(@PathVariable Long documentId) {
+    public WpsR<WpsUplaodPrepareDto> uploadPrepare(@PathVariable String documentId) {
         String[] types = {"md5"};
         return WpsR.ok(new WpsUplaodPrepareDto(types));
     }
@@ -100,7 +126,7 @@ public class WpsController extends BaseController {
     private record WpsUploadAddressResponseDto(String method, String url) {}
 
     @PostMapping("/files/{documentId}/upload/address")
-    public WpsR uploadAddress(@PathVariable Long documentId, @RequestBody WpsUploadAddressRequestDto dto) {
+    public WpsR uploadAddress(@PathVariable String documentId, @RequestBody WpsUploadAddressRequestDto dto) {
         return WpsR.ok(new WpsUploadAddressResponseDto("PUT", "http://yp1.yingpaipay.com:9029/wps/callback/v3/3rd/upload/file/" + documentId));
     }
 
@@ -109,48 +135,29 @@ public class WpsController extends BaseController {
     ) {}
 
     @GetMapping("/files/{documentId}")
-    public WpsR<WpsGetFileInfoDto> getFileInfo(@PathVariable Long documentId) {
-        Document document = documentService.getById(documentId);
-        SysOssVo ossVo = ossService.getById(document.getOssId());
-        String url = ossVo.getUrl();
-
-        RestTemplate restTemplate = new RestTemplate();
-        ResponseEntity<Void> response = restTemplate.exchange(
-            url,
-            HttpMethod.HEAD,
-            null,
-            Void.class
-        );
-
-        int fileSize = 0;
-        if (response.getHeaders().getContentLength() > 0) {
-            fileSize = (int) response.getHeaders().getContentLength();
-        } else {
-            log.warn("无法通过 HEAD 获取文件大小,fileUrl: {}", url);
+    public WpsR<WpsGetFileInfoDto> getFileInfo(@PathVariable String documentId) {
+        String[] ids = documentId.split("_");
+        long id = Long.parseLong(ids[0]);
+        long version = Long.parseLong(ids[1]);
+
+        if (DOCUMENT_MAP.containsKey(id)) {
+            WpsVersionControlDto dto = DOCUMENT_MAP.get(id);
+            return WpsR.ok(new WpsGetFileInfoDto(
+                documentId, dto.getFileName(), 1, dto.getSize(), Math.toIntExact(new Date().getTime() / 1000L), Math.toIntExact(new Date().getTime() / 1000L), dto.getCreator(), dto.getUpdator()
+            ));
         }
-
+        WpsVersionControlDto dto = initDocument(id);
         return WpsR.ok(new WpsGetFileInfoDto(
-            String.valueOf(documentId), ossVo.getOriginalName(),
-            1,
-            fileSize,
-            Math.toIntExact(document.getCreateTime().getTime() / 1000L),
-            Math.toIntExact(document.getUpdateTime().getTime() / 1000L),
-            String.valueOf(document.getCreateBy()),
-            String.valueOf(document.getUpdateBy())
+            documentId, dto.getFileName(), 1, dto.getSize(), Math.toIntExact(new Date().getTime() / 1000L), Math.toIntExact(new Date().getTime() / 1000L), dto.getCreator(), dto.getUpdator()
         ));
     }
 
-    @GetMapping("/files/{documentId}/watermark")
-    public WpsR watermark(@PathVariable Long documentId) {
-        return WpsR.ok();
-    }
-
     private record WpsFilesPermissionDto(
         String user_id, Integer read, Integer update, Integer download, Integer rename, Integer history, Integer copy, Integer print, Integer saves, Integer comment
     ) {}
 
     @GetMapping("/files/{documentId}/permission")
-    public WpsR permission(@PathVariable Long documentId) {
+    public WpsR permission(@PathVariable String documentId) {
         return WpsR.ok(
             new WpsFilesPermissionDto(
                 "1", 1, 1, 1, 1, 1, 1, 1, 1, 1
@@ -161,14 +168,40 @@ public class WpsController extends BaseController {
     private record WpsGetUrlDto(String url) {}
 
     @GetMapping("/files/{documentId}/download")
-    public WpsR getUrl(@PathVariable Long documentId) {
-        if (DOCUMENT_MAP.containsKey(documentId)) {
-            return WpsR.ok(new WpsGetUrlDto(ossService.getById(DOCUMENT_MAP.get(documentId)).getUrl()));
+    public WpsR getUrl(@PathVariable String documentId) {
+        String[] ids = documentId.split("_");
+        long id = Long.parseLong(ids[0]);
+        long version = Long.parseLong(ids[1]);
+
+        if (DOCUMENT_MAP.containsKey(id)) {
+            WpsVersionControlDto dto = DOCUMENT_MAP.get(id);
+            List<WpsVersionDto> versions = dto.getVersions();
+            for (WpsVersionDto versionDto : versions) {
+                if (versionDto.getVersion() == version) {
+                    return WpsR.ok(new WpsGetUrlDto(versionDto.getUrl()));
+                }
+            }
+            return WpsR.ok(new WpsGetUrlDto(dto.getVersions().get(0).getUrl()));
+        }
+
+        WpsVersionControlDto dto = initDocument(id);
+        List<WpsVersionDto> versions = dto.getVersions();
+        for (WpsVersionDto versionDto : versions) {
+            if (Objects.equals(versionDto.getVersion(), dto.getCurrentVersion())) {
+                return WpsR.ok(new WpsGetUrlDto(versionDto.getUrl()));
+            }
+        }
+        return WpsR.ok(new WpsGetUrlDto(dto.getVersions().get(0).getUrl()));
+    }
+
+    @GetMapping("/files/{documentId}/versions/{version}/download")
+    public WpsR getUrlByVersion(@PathVariable String documentId, @PathVariable Integer version) {
+        if (DOCUMENT_MAP.containsKey(Long.valueOf(documentId.split("_")[0]))) {
+            WpsVersionControlDto dto = DOCUMENT_MAP.get(Long.valueOf(documentId.split("_")[0]));
+            return WpsR.ok(new WpsGetUrlDto(dto.getVersions().get(Integer.parseInt(documentId.split("_")[1])).getUrl()));
         }
-        Document document = documentService.getById(documentId);
-        SysOssVo ossVo = ossService.getById(document.getOssId());
-        String url = ossVo.getUrl();
-        return WpsR.ok(new WpsGetUrlDto(url));
+        WpsVersionControlDto dto = initDocument(Long.valueOf(documentId.split("_")[0]));
+        return WpsR.ok(new WpsGetUrlDto(dto.getVersions().get(0).getUrl()));
     }
 
     private record WpsGetUsersDto(String id, String name, String avatar_url) {}
@@ -195,15 +228,118 @@ public class WpsController extends BaseController {
         return WpsR.ok(dtos);
     }
 
-    @GetMapping("/{documentId}")
-    public R<Long> getOssId(@PathVariable Long documentId) {
-        return R.ok(DOCUMENT_MAP.remove(documentId));
+    @PostMapping(value = "/init/{documentId}")
+    public R init(@PathVariable Long documentId) {
+        if (DOCUMENT_MAP.containsKey(documentId)) {
+            throw new BusinessException("已有其他人正在审核该文件");
+        }
+        initDocument(documentId);
+        return R.ok(DOCUMENT_MAP.get(documentId).getCurrentVersion());
+    }
+
+    private WpsVersionControlDto initDocument(Long ossId) {
+        SysOssVo ossVo = ossService.getById(ossId);
+        Document document = documentService.getByOssId(ossId);
+        if (DOCUMENT_MAP.containsKey(document.getId())) {
+            throw new BusinessException("已有其他人正在审核该文件");
+        }
+        long currentVersion = System.currentTimeMillis();
+        List<WpsVersionDto> list = new ArrayList<>();
+        list.add(new WpsVersionDto(ossVo.getFileName(), 0L, ossVo.getUrl(), new Date(), new Date(), Math.toIntExact(document.getCreateTime().getTime() / 1000L), Math.toIntExact(document.getUpdateTime().getTime() / 1000L)));
+        list.add(new WpsVersionDto(ossVo.getFileName(), currentVersion, ossVo.getUrl(), new Date(), new Date(), Math.toIntExact(document.getCreateTime().getTime() / 1000L), Math.toIntExact(document.getUpdateTime().getTime() / 1000L)));
+        WpsVersionControlDto dto = new WpsVersionControlDto();
+        dto.setCurrentVersion(currentVersion);
+        dto.setVersions(list);
+        dto.setSuffix(ossVo.getFileSuffix());
+        dto.setCreator(String.valueOf(document.getCreateBy()));
+        dto.setUpdator(String.valueOf(document.getUpdateBy()));
+        dto.setFileName(ossVo.getOriginalName());
+        SysOssExt ext = JsonUtils.parseObject(ossVo.getExt1(), SysOssExt.class);
+        long size = ext.getFileSize();
+        dto.setSize((int) size);
+        DOCUMENT_MAP.put(ossId, dto);
+        return dto;
+    }
+
+    @PutMapping("/clean/{documentId}")
+    public R clean(@PathVariable Long documentId) {
+        WpsVersionControlDto dto = DOCUMENT_MAP.get(documentId);
+        long currentVersion = System.currentTimeMillis();
+        dto.getVersions().add(new WpsVersionDto(
+            dto.getVersions().get(0).getFileName(), currentVersion, dto.getVersions().get(0).getUrl(), new Date(), new Date(), Math.toIntExact(new Date().getTime() / 1000L), Math.toIntExact(new Date().getTime() / 1000L)
+        ));
+        dto.setCurrentVersion(currentVersion);
+        log.info("自行进行刷新版本");
+        dto.getVersions().forEach(e -> log.info("{}", JsonUtils.toJsonString(e)));
+        return R.ok();
+    }
+
+    @GetMapping("/files/{documentId}/versions")
+    public WpsR getVersions(@PathVariable Long documentId, @RequestParam(value = "offset", required = false) Integer offset, @RequestParam(value = "limit", required = false) Integer size) {
+        WpsVersionControlDto dto = DOCUMENT_MAP.get(documentId);
+        List<WpsVersionDto> versions = dto.getVersions();
+
+        List<WpsVersionDto> reversed = new ArrayList<>(versions);
+        Collections.reverse(reversed);
+
+        if (offset == null || size == null) {
+            return WpsR.ok(reversed);
+        }
+
+        int fromIndex = Math.min(offset, reversed.size());
+        int toIndex = Math.min(offset + size, reversed.size());
+
+        List<WpsVersionDto> paginated = reversed.subList(fromIndex, toIndex);
+
+        List<WpsGetVersionsDto> list = new ArrayList<>();
+        paginated.forEach(e -> list.add(new WpsGetVersionsDto(
+            String.valueOf(documentId), dto.getFileName(), Math.toIntExact(e.getVersion() / 1000L), dto.getSize(), e.getCreate_time(), e.getUpdate_time(), dto.getCreator(), dto.getUpdator()
+        )));
+
+        WpsR<List<WpsGetVersionsDto>> r = WpsR.ok(list);
+        String str = JsonUtils.toJsonString(r);
+        log.warn(str);
+        return r;
+    }
+
+    @GetMapping("/files/{documentId}/versions/{version}")
+    public WpsR getFileByVersion(@PathVariable Long documentId, @PathVariable Integer version) {
+        WpsVersionControlDto dto = DOCUMENT_MAP.get(documentId);
+        WpsVersionDto current = dto.getVersions().get(version - 1);
+        return WpsR.ok(new WpsGetVersionsDto(
+            String.valueOf(documentId), dto.getFileName(), Math.toIntExact(current.getVersion() / 1000L), dto.getSize(), current.getCreate_time(), current.getUpdate_time(), dto.getCreator(), dto.getUpdator()
+        ));
+    }
+
+    @GetMapping("/files/list")
+    public R<List<WpsVersionDto>> getVersionList(@RequestParam("ossId") Long ossId) {
+        List<WpsVersionDto> list = DOCUMENT_MAP.get(ossId).getVersions();
+        list.forEach(e -> log.info("{}", JsonUtils.toJsonString(e)));
+        return R.ok(list.stream().filter(e -> e.getVersion() != 0L).sorted((e1, e2) -> Math.toIntExact(e2.getVersion() - e1.getVersion())).toList());
+    }
+
+    @GetMapping("/getFinal")
+    public R<SysOssVo> getFinal(@RequestParam("id") String id) {
+        String[] ids = id.split("_");
+        long documentId = Long.parseLong(ids[0]);
+        long version = Long.parseLong(ids[1]);
+
+        WpsVersionControlDto dto = DOCUMENT_MAP.get(documentId);
+        List<WpsVersionDto> versions = dto.getVersions();
+        for (WpsVersionDto versionDto : versions) {
+            if (versionDto.getVersion() == version) {
+                String url = versionDto.getUrl();
+                SysOssVo vo = ossService.insertByUrl(versionDto.getFileName(), dto.getFileName(), url);
+                DOCUMENT_MAP.remove(documentId);
+                return R.ok(vo);
+            }
+        }
+        throw new BusinessException("审核内容保存失败");
     }
 
-    @PutMapping("/refresh/{documentId}")
-    public R<Void> refresh(@PathVariable Long documentId) {
-        Document document = documentService.getById(documentId);
-        DOCUMENT_MAP.put(documentId, document.getOssId());
+    @DeleteMapping("/cancel/{documentId}")
+    public R<Void> cancel(@PathVariable Long documentId) {
+        DOCUMENT_MAP.remove(documentId);
         return R.ok();
     }
 

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

@@ -0,0 +1,37 @@
+package com.yingpaipay.business.controller.applet;
+
+import com.yingpaipay.business.domain.bo.AppletMyInfoEditAvatarBo;
+import com.yingpaipay.business.domain.bo.AppletMyInfoEditGenderBo;
+import com.yingpaipay.business.domain.bo.AppletMyInfoEditNicknameBo;
+import lombok.RequiredArgsConstructor;
+import org.dromara.common.core.domain.R;
+import org.dromara.common.web.core.BaseController;
+import org.dromara.system.service.ISysUserService;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequestMapping("/applet/my/info")
+@RequiredArgsConstructor
+public class AppletMyInfoController extends BaseController {
+
+    private final ISysUserService userService;
+
+    @PutMapping("/edit/nickname")
+    public R<Void> editNickname(@RequestBody AppletMyInfoEditNicknameBo bo) {
+        return toAjax(userService.updateNickname(bo.getNickname()));
+    }
+
+    @PutMapping("/edit/gender")
+    public R<Void> editGender(@RequestBody AppletMyInfoEditGenderBo bo) {
+        return toAjax(userService.updateGender(bo.getGender()));
+    }
+
+    @PutMapping("/edit/avatar")
+    public R<Void> editAvatar(@RequestBody AppletMyInfoEditAvatarBo bo) {
+        return toAjax(userService.updateAvatar(bo.getAvatar()));
+    }
+
+}

+ 8 - 0
ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/controller/applet/AppletMyTaskController.java

@@ -1,14 +1,17 @@
 package com.yingpaipay.business.controller.applet;
 
 import com.yingpaipay.business.domain.bo.AppletMyTaskDocumentBo;
+import com.yingpaipay.business.domain.vo.AppletGetRejectionVo;
 import com.yingpaipay.business.domain.vo.AppletMyTaskDocumentVo;
 import com.yingpaipay.business.service.IDocumentService;
 import lombok.RequiredArgsConstructor;
+import org.dromara.common.core.domain.R;
 import org.dromara.common.mybatis.core.page.PageQuery;
 import org.dromara.common.mybatis.core.page.TableDataInfo;
 import org.dromara.common.web.core.BaseController;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.RestController;
 
 @RestController
@@ -23,4 +26,9 @@ public class AppletMyTaskController extends BaseController {
         return documentService.listDocument(bo, pageQuery);
     }
 
+    @GetMapping("/getRejection")
+    public R<AppletGetRejectionVo> getRejection(@RequestParam Long documentId) {
+        return R.ok(documentService.getRejection(documentId));
+    }
+
 }

+ 31 - 5
ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/controller/applet/AppletScanController.java

@@ -1,20 +1,23 @@
 package com.yingpaipay.business.controller.applet;
 
-import com.yingpaipay.business.domain.bo.AppletDocumentScanSubmitBo;
-import com.yingpaipay.business.domain.bo.AppletScanBo;
-import com.yingpaipay.business.domain.bo.AppletUploadOnSubmitBo;
-import com.yingpaipay.business.domain.vo.AppletDocumentScanSubmitVo;
-import com.yingpaipay.business.domain.vo.AppletScanVo;
+import com.yingpaipay.business.domain.bo.*;
+import com.yingpaipay.business.domain.vo.*;
 import com.yingpaipay.business.service.IDocumentService;
+import com.yingpaipay.business.service.IFolderService;
+import com.yingpaipay.business.service.IProjectService;
 import com.yingpaipay.business.service.ITextInService;
+import com.yingpaipay.system.domain.vo.FolderPermissionVo;
 import lombok.RequiredArgsConstructor;
 import org.dromara.common.core.domain.R;
 import org.dromara.common.mybatis.core.page.PageQuery;
 import org.dromara.common.mybatis.core.page.TableDataInfo;
 import org.dromara.common.web.core.BaseController;
+import org.dromara.system.service.ISysUserService;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
 
+import java.util.List;
+
 @Validated
 @RestController
 @RequestMapping("/applet/scan")
@@ -23,6 +26,9 @@ public class AppletScanController extends BaseController {
 
     private final ITextInService textInService;
     private final IDocumentService documentService;
+    private final IFolderService folderService;
+    private final IProjectService projectService;
+    private final ISysUserService userService;
 
     @PostMapping("/scan")
     public R<AppletScanVo> scan(@RequestBody AppletScanBo bo) {
@@ -39,4 +45,24 @@ public class AppletScanController extends BaseController {
         return toAjax(documentService.uploadOnSubmit(bo));
     }
 
+    @GetMapping("/listProject")
+    public TableDataInfo<ProjectVo> listProject(ProjectBo bo, PageQuery pageQuery) {
+        return projectService.queryPageList(bo, pageQuery);
+    }
+
+    @GetMapping("/listFolder")
+    public R<List<FolderListVo>> listFolder(@RequestParam("projectId") Long projectId) {
+        return R.ok(folderService.selectList(projectId));
+    }
+
+    @GetMapping("/listFolderPermission")
+    public R<FolderPermissionVo> listFolderPermission(@RequestParam("projectId") Long projectId) {
+        return R.ok(userService.selectUserFolderPermissionByProjectId(projectId));
+    }
+
+    @PostMapping("/uploadNew")
+    public R<Void> uploadNew(@Validated @RequestBody AppletUploadNewBo bo) {
+        return toAjax(documentService.uploadNew(bo));
+    }
+
 }

+ 74 - 0
ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/domain/DocumentQualityControlTask.java

@@ -0,0 +1,74 @@
+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_quality_control_task
+ *
+ * @author Huanyi
+ * @date 2026-01-06
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("document_quality_control_task")
+public class DocumentQualityControlTask extends TenantEntity {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 序号
+     */
+    @TableId(value = "id")
+    private Long id;
+
+    /**
+     * 质控名称
+     */
+    private String name;
+
+    /**
+     * 发起人
+     */
+    private Long initiator;
+
+    /**
+     * 质控项目
+     */
+    private Long projectId;
+
+    /**
+     * 开始时间
+     */
+    private Date startDate;
+
+    /**
+     * 截止时间
+     */
+    private Date deadline;
+
+    /**
+     * 状态
+     */
+    private Integer status;
+
+    /**
+     * 备注
+     */
+    private String note;
+
+    /**
+     * 删除标志(0代表存在 1代表删除)
+     */
+    @TableLogic
+    private String delFlag;
+
+
+}

+ 10 - 0
ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/domain/bo/AppletMyInfoEditAvatarBo.java

@@ -0,0 +1,10 @@
+package com.yingpaipay.business.domain.bo;
+
+import lombok.Data;
+
+@Data
+public class AppletMyInfoEditAvatarBo {
+
+    private Long avatar;
+
+}

+ 10 - 0
ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/domain/bo/AppletMyInfoEditGenderBo.java

@@ -0,0 +1,10 @@
+package com.yingpaipay.business.domain.bo;
+
+import lombok.Data;
+
+@Data
+public class AppletMyInfoEditGenderBo {
+
+    private String gender;
+
+}

+ 10 - 0
ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/domain/bo/AppletMyInfoEditNicknameBo.java

@@ -0,0 +1,10 @@
+package com.yingpaipay.business.domain.bo;
+
+import lombok.Data;
+
+@Data
+public class AppletMyInfoEditNicknameBo {
+
+    private String nickname;
+
+}

+ 27 - 0
ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/domain/bo/AppletUploadNewBo.java

@@ -0,0 +1,27 @@
+package com.yingpaipay.business.domain.bo;
+
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotEmpty;
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class AppletUploadNewBo {
+
+    @NotNull
+    private Long folderId;
+
+    @NotBlank
+    private String fileName;
+
+    @NotNull
+    private Long projectId;
+
+    private String note;
+
+    @NotEmpty
+    private List<String> files;
+
+}

+ 73 - 0
ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/domain/bo/DocumentQualityControlTaskBo.java

@@ -0,0 +1,73 @@
+package com.yingpaipay.business.domain.bo;
+
+import com.yingpaipay.business.domain.DocumentQualityControlTask;
+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_quality_control_task
+ *
+ * @author Huanyi
+ * @date 2026-01-06
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@AutoMapper(target = DocumentQualityControlTask.class, reverseConvertGenerate = false)
+public class DocumentQualityControlTaskBo extends BaseEntity {
+
+    /**
+     * 序号
+     */
+    @NotNull(message = "序号不能为空", groups = { EditGroup.class })
+    private Long id;
+
+    /**
+     * 质控名称
+     */
+    @NotBlank(message = "质控名称不能为空", groups = { AddGroup.class, EditGroup.class })
+    private String name;
+
+    /**
+     * 发起人
+     */
+    @NotNull(message = "发起人不能为空", groups = { AddGroup.class, EditGroup.class })
+    private Long initiator;
+
+    /**
+     * 质控项目
+     */
+    @NotNull(message = "质控项目不能为空", groups = { AddGroup.class, EditGroup.class })
+    private Long projectId;
+
+    /**
+     * 开始时间
+     */
+    @NotNull(message = "开始时间不能为空", groups = { AddGroup.class, EditGroup.class })
+    private Date startDate;
+
+    /**
+     * 截止时间
+     */
+    @NotNull(message = "截止时间不能为空", groups = { AddGroup.class, EditGroup.class })
+    private Date deadline;
+
+    /**
+     * 状态
+     */
+    @NotNull(message = "状态不能为空", groups = { AddGroup.class, EditGroup.class })
+    private Integer status;
+
+    /**
+     * 备注
+     */
+    private String note;
+
+
+}

+ 19 - 0
ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/domain/dto/WpsGetVersionsDto.java

@@ -0,0 +1,19 @@
+package com.yingpaipay.business.domain.dto;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+
+@Data
+@AllArgsConstructor
+public class WpsGetVersionsDto {
+
+    private String id;
+    private String name;
+    private Integer version;
+    private Integer size;
+    private Integer create_time;
+    private Integer modify_time;
+    private String creator_id;
+    private String modifier_id;
+
+}

+ 24 - 0
ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/domain/dto/WpsVersionControlDto.java

@@ -0,0 +1,24 @@
+package com.yingpaipay.business.domain.dto;
+
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class WpsVersionControlDto {
+
+    private String fileName;
+
+    private Integer size;
+
+    private String suffix;
+
+    private Long currentVersion;
+
+    private String creator;
+
+    private String updator;
+
+    private List<WpsVersionDto> versions;
+
+}

+ 26 - 0
ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/domain/dto/WpsVersionDto.java

@@ -0,0 +1,26 @@
+package com.yingpaipay.business.domain.dto;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+
+import java.util.Date;
+
+@Data
+@AllArgsConstructor
+public class WpsVersionDto {
+
+    private String fileName;
+
+    private Long version;
+
+    private String url;
+
+    private Date createTime;
+
+    private Date updateTime;
+
+    private Integer create_time;
+
+    private Integer update_time;
+
+}

+ 18 - 0
ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/domain/vo/AppletGetRejectionVo.java

@@ -0,0 +1,18 @@
+package com.yingpaipay.business.domain.vo;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+
+@Data
+@AllArgsConstructor
+public class AppletGetRejectionVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    private String rejection;
+
+}

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

@@ -32,4 +32,6 @@ public class AppletMyTaskDocumentVo implements Serializable {
     private String submitter;
     private Long submitterId;
 
+    private Integer status;
+
 }

+ 111 - 0
ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/domain/vo/DocumentQualityControlTaskVo.java

@@ -0,0 +1,111 @@
+package com.yingpaipay.business.domain.vo;
+
+import java.util.Date;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.yingpaipay.business.domain.DocumentQualityControlTask;
+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 java.io.Serial;
+import java.io.Serializable;
+import java.util.Date;
+
+
+
+/**
+ * 文档质控任务视图对象 document_quality_control_task
+ *
+ * @author Huanyi
+ * @date 2026-01-06
+ */
+@Data
+@ExcelIgnoreUnannotated
+@AutoMapper(target = DocumentQualityControlTask.class)
+public class DocumentQualityControlTaskVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 序号
+     */
+    @ExcelProperty(value = "序号")
+    private Long id;
+
+    /**
+     * 质控名称
+     */
+    @ExcelProperty(value = "质控名称")
+    private String name;
+
+    /**
+     * 发起人
+     */
+    @ExcelProperty(value = "发起人")
+    @Translation(type = TransConstant.USER_ID_TO_NICKNAME, mapper = "initiator  ")
+    private Long initiator;
+
+    /**
+     * 质控项目
+     */
+    @ExcelProperty(value = "质控项目")
+    private Long projectId;
+
+    /**
+     * 开始时间
+     */
+    @ExcelProperty(value = "开始时间")
+    private Date startDate;
+
+    /**
+     * 截止时间
+     */
+    @ExcelProperty(value = "截止时间")
+    private Date deadline;
+
+    /**
+     * 状态
+     */
+    @ExcelProperty(value = "状态")
+    private Integer status;
+
+    /**
+     * 备注
+     */
+    @ExcelProperty(value = "备注")
+    private String note;
+
+    /**
+     * 创建者
+     */
+    @ExcelProperty(value = "创建者")
+    @Translation(type = TransConstant.USER_ID_TO_NICKNAME, mapper = "createBy")
+    private Long createBy;
+
+    /**
+     * 创建时间
+     */
+    @ExcelProperty(value = "创建时间")
+    private Date createTime;
+
+    /**
+     * 更新者
+     */
+    @ExcelProperty(value = "更新者")
+    @Translation(type = TransConstant.USER_ID_TO_NICKNAME, mapper = "updateBy")
+    private Long updateBy;
+
+    /**
+     * 更新时间
+     */
+    @ExcelProperty(value = "更新时间")
+    private Date updateTime;
+
+
+}

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

@@ -35,6 +35,8 @@ public class TaskCenterAuditListVo implements Serializable {
 
     private Long ossId;
 
+    private String fileName;
+
     private String ossUrl;
 
     private Integer type;

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

@@ -0,0 +1,15 @@
+package com.yingpaipay.business.mapper;
+
+import com.yingpaipay.business.domain.DocumentQualityControlTask;
+import com.yingpaipay.business.domain.vo.DocumentQualityControlTaskVo;
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+
+/**
+ * 文档质控任务Mapper接口
+ *
+ * @author Huanyi
+ * @date 2026-01-06
+ */
+public interface DocumentQualityControlTaskMapper extends BaseMapperPlus<DocumentQualityControlTask, DocumentQualityControlTaskVo> {
+
+}

+ 68 - 0
ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/service/IDocumentQualityControlTaskService.java

@@ -0,0 +1,68 @@
+package com.yingpaipay.business.service;
+
+import com.yingpaipay.business.domain.vo.DocumentQualityControlTaskVo;
+import com.yingpaipay.business.domain.bo.DocumentQualityControlTaskBo;
+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-06
+ */
+public interface IDocumentQualityControlTaskService {
+
+    /**
+     * 查询文档质控任务
+     *
+     * @param id 主键
+     * @return 文档质控任务
+     */
+    DocumentQualityControlTaskVo queryById(Long id);
+
+    /**
+     * 分页查询文档质控任务列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 文档质控任务分页列表
+     */
+    TableDataInfo<DocumentQualityControlTaskVo> queryPageList(DocumentQualityControlTaskBo bo, PageQuery pageQuery);
+
+    /**
+     * 查询符合条件的文档质控任务列表
+     *
+     * @param bo 查询条件
+     * @return 文档质控任务列表
+     */
+    List<DocumentQualityControlTaskVo> queryList(DocumentQualityControlTaskBo bo);
+
+    /**
+     * 新增文档质控任务
+     *
+     * @param bo 文档质控任务
+     * @return 是否新增成功
+     */
+    Boolean insertByBo(DocumentQualityControlTaskBo bo);
+
+    /**
+     * 修改文档质控任务
+     *
+     * @param bo 文档质控任务
+     * @return 是否修改成功
+     */
+    Boolean updateByBo(DocumentQualityControlTaskBo bo);
+
+    /**
+     * 校验并批量删除文档质控任务信息
+     *
+     * @param ids     待删除的主键集合
+     * @param isValid 是否进行有效性校验
+     * @return 是否删除成功
+     */
+    Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
+}

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

@@ -101,4 +101,8 @@ public interface IDocumentService {
     TableDataInfo<AppletDocumentScanSubmitVo> listToSubmit(AppletDocumentScanSubmitBo bo, PageQuery pageQuery);
 
     boolean uploadOnSubmit(AppletUploadOnSubmitBo bo);
+
+    boolean uploadNew(AppletUploadNewBo bo);
+
+    AppletGetRejectionVo getRejection(Long documentId);
 }

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

@@ -28,4 +28,11 @@ public class CommonDocumentService {
     public Document getById(Long documentId) {
         return baseMapper.selectById(documentId);
     }
+
+    public Document getByOssId(Long ossId) {
+        return baseMapper.selectOne(
+            Wrappers.lambdaQuery(Document.class)
+                .eq(Document::getOssId, ossId)
+        );
+    }
 }

+ 145 - 0
ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/service/impl/DocumentQualityControlTaskServiceImpl.java

@@ -0,0 +1,145 @@
+package com.yingpaipay.business.service.impl;
+
+import org.dromara.common.core.utils.MapstructUtils;
+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.DocumentQualityControlTaskBo;
+import com.yingpaipay.business.domain.vo.DocumentQualityControlTaskVo;
+import com.yingpaipay.business.domain.DocumentQualityControlTask;
+import com.yingpaipay.business.mapper.DocumentQualityControlTaskMapper;
+import com.yingpaipay.business.service.IDocumentQualityControlTaskService;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Collection;
+
+/**
+ * 文档质控任务Service业务层处理
+ *
+ * @author Huanyi
+ * @date 2026-01-06
+ */
+@Slf4j
+@RequiredArgsConstructor
+@Service
+public class DocumentQualityControlTaskServiceImpl implements IDocumentQualityControlTaskService {
+
+    private final DocumentQualityControlTaskMapper baseMapper;
+
+    /**
+     * 查询文档质控任务
+     *
+     * @param id 主键
+     * @return 文档质控任务
+     */
+    @Override
+    public DocumentQualityControlTaskVo queryById(Long id){
+        return baseMapper.selectVoById(id);
+    }
+
+    /**
+     * 分页查询文档质控任务列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 文档质控任务分页列表
+     */
+    @Override
+    public TableDataInfo<DocumentQualityControlTaskVo> queryPageList(DocumentQualityControlTaskBo bo, PageQuery pageQuery) {
+        LambdaQueryWrapper<DocumentQualityControlTask> lqw = buildQueryWrapper(bo);
+        Page<DocumentQualityControlTaskVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
+        return TableDataInfo.build(result);
+    }
+
+    /**
+     * 查询符合条件的文档质控任务列表
+     *
+     * @param bo 查询条件
+     * @return 文档质控任务列表
+     */
+    @Override
+    public List<DocumentQualityControlTaskVo> queryList(DocumentQualityControlTaskBo bo) {
+        LambdaQueryWrapper<DocumentQualityControlTask> lqw = buildQueryWrapper(bo);
+        return baseMapper.selectVoList(lqw);
+    }
+
+    private LambdaQueryWrapper<DocumentQualityControlTask> buildQueryWrapper(DocumentQualityControlTaskBo bo) {
+        Map<String, Object> params = bo.getParams();
+        LambdaQueryWrapper<DocumentQualityControlTask> lqw = Wrappers.lambdaQuery();
+        lqw.orderByAsc(DocumentQualityControlTask::getId);
+        lqw.like(StringUtils.isNotBlank(bo.getName()), DocumentQualityControlTask::getName, bo.getName());
+        lqw.eq(bo.getInitiator() != null, DocumentQualityControlTask::getInitiator, bo.getInitiator());
+        lqw.eq(bo.getProjectId() != null, DocumentQualityControlTask::getProjectId, bo.getProjectId());
+        lqw.between(params.get("beginStartDate") != null && params.get("endStartDate") != null,
+            DocumentQualityControlTask::getStartDate ,params.get("beginStartDate"), params.get("endStartDate"));
+        lqw.between(params.get("beginDeadline") != null && params.get("endDeadline") != null,
+            DocumentQualityControlTask::getDeadline ,params.get("beginDeadline"), params.get("endDeadline"));
+        lqw.eq(bo.getStatus() != null, DocumentQualityControlTask::getStatus, bo.getStatus());
+        lqw.eq(bo.getCreateBy() != null, DocumentQualityControlTask::getCreateBy, bo.getCreateBy());
+        lqw.between(params.get("beginCreateTime") != null && params.get("endCreateTime") != null,
+            DocumentQualityControlTask::getCreateTime ,params.get("beginCreateTime"), params.get("endCreateTime"));
+        lqw.eq(bo.getUpdateBy() != null, DocumentQualityControlTask::getUpdateBy, bo.getUpdateBy());
+        lqw.between(params.get("beginUpdateTime") != null && params.get("endUpdateTime") != null,
+            DocumentQualityControlTask::getUpdateTime ,params.get("beginUpdateTime"), params.get("endUpdateTime"));
+        return lqw;
+    }
+
+    /**
+     * 新增文档质控任务
+     *
+     * @param bo 文档质控任务
+     * @return 是否新增成功
+     */
+    @Override
+    public Boolean insertByBo(DocumentQualityControlTaskBo bo) {
+        DocumentQualityControlTask add = MapstructUtils.convert(bo, DocumentQualityControlTask.class);
+        validEntityBeforeSave(add);
+        boolean flag = baseMapper.insert(add) > 0;
+        if (flag) {
+            bo.setId(add.getId());
+        }
+        return flag;
+    }
+
+    /**
+     * 修改文档质控任务
+     *
+     * @param bo 文档质控任务
+     * @return 是否修改成功
+     */
+    @Override
+    public Boolean updateByBo(DocumentQualityControlTaskBo bo) {
+        DocumentQualityControlTask update = MapstructUtils.convert(bo, DocumentQualityControlTask.class);
+        validEntityBeforeSave(update);
+        return baseMapper.updateById(update) > 0;
+    }
+
+    /**
+     * 保存前的数据校验
+     */
+    private void validEntityBeforeSave(DocumentQualityControlTask entity){
+        //TODO 做一些数据校验,如唯一约束
+    }
+
+    /**
+     * 校验并批量删除文档质控任务信息
+     *
+     * @param ids     待删除的主键集合
+     * @param isValid 是否进行有效性校验
+     * @return 是否删除成功
+     */
+    @Override
+    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
+        if(isValid){
+            //TODO 做一些业务上的校验,判断是否需要校验
+        }
+        return baseMapper.deleteByIds(ids) > 0;
+    }
+}

+ 118 - 67
ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/service/impl/DocumentServiceImpl.java

@@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.yingpaipay.business.constant.DictTypeConst;
 import com.yingpaipay.business.constant.DocumentAuditorTypeConst;
 import com.yingpaipay.business.constant.DocumentStatusConst;
+import com.yingpaipay.business.constant.DocumentTypeConst;
 import com.yingpaipay.business.domain.DocumentAuditLog;
 import com.yingpaipay.business.domain.Folder;
 import com.yingpaipay.business.domain.Project;
@@ -74,7 +75,7 @@ public class DocumentServiceImpl implements IDocumentService {
      * @return 文档
      */
     @Override
-    public DocumentVo queryById(Long id){
+    public DocumentVo queryById(Long id) {
         return baseMapper.selectVoById(id);
     }
 
@@ -103,11 +104,11 @@ public class DocumentServiceImpl implements IDocumentService {
         Map<String, String> centerFileSpecificationMap = new HashMap<>();
         Map<String, String> projectFileSpecificationMap = new HashMap<>();
         dictTypeService.selectDictDataByType(DictTypeConst.PLAN_DOCUMENT_TYPE)
-                .forEach(e -> planDocumentTypeMap.put(e.getDictValue(), e.getDictLabel()));
+            .forEach(e -> planDocumentTypeMap.put(e.getDictValue(), e.getDictLabel()));
         dictTypeService.selectDictDataByType(DictTypeConst.CENTER_FILE_SPECIFICATION)
-                .forEach(e -> centerFileSpecificationMap.put(e.getDictValue(), e.getDictLabel()));
+            .forEach(e -> centerFileSpecificationMap.put(e.getDictValue(), e.getDictLabel()));
         dictTypeService.selectDictDataByType(DictTypeConst.PROJECT_FILE_SPECIFICATION)
-                .forEach(e -> projectFileSpecificationMap.put(e.getDictValue(), e.getDictLabel()));
+            .forEach(e -> projectFileSpecificationMap.put(e.getDictValue(), e.getDictLabel()));
         documents.forEach(e -> {
             ossIds.add(e.getOssId());
             folderIds.add(e.getFolderId());
@@ -148,11 +149,11 @@ public class DocumentServiceImpl implements IDocumentService {
         lqw.like(StringUtils.isNotBlank(bo.getName()), Document::getName, bo.getName());
         lqw.eq(bo.getStatus() != null, Document::getStatus, bo.getStatus());
         lqw.between(params.get("beginSubmitDeadline") != null && params.get("endSubmitDeadline") != null,
-            Document::getSubmitDeadline ,params.get("beginSubmitDeadline"), params.get("endSubmitDeadline"));
+            Document::getSubmitDeadline, params.get("beginSubmitDeadline"), params.get("endSubmitDeadline"));
         lqw.between(params.get("beginCreateTime") != null && params.get("endCreateTime") != null,
-            Document::getCreateTime ,params.get("beginCreateTime"), params.get("endCreateTime"));
+            Document::getCreateTime, params.get("beginCreateTime"), params.get("endCreateTime"));
         lqw.between(params.get("beginUpdateTime") != null && params.get("endUpdateTime") != null,
-            Document::getUpdateTime ,params.get("beginUpdateTime"), params.get("endUpdateTime"));
+            Document::getUpdateTime, params.get("beginUpdateTime"), params.get("endUpdateTime"));
         return lqw;
     }
 
@@ -192,7 +193,7 @@ public class DocumentServiceImpl implements IDocumentService {
     /**
      * 保存前的数据校验
      */
-    private void validEntityBeforeSave(Document entity){
+    private void validEntityBeforeSave(Document entity) {
         //TODO 做一些数据校验,如唯一约束
     }
 
@@ -205,7 +206,7 @@ public class DocumentServiceImpl implements IDocumentService {
      */
     @Override
     public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
-        if(isValid){
+        if (isValid) {
             //TODO 做一些业务上的校验,判断是否需要校验
         }
         return baseMapper.deleteByIds(ids) > 0;
@@ -346,9 +347,9 @@ public class DocumentServiceImpl implements IDocumentService {
         LambdaQueryWrapper<Document> wrapper = buildAuditListWrapper(bo, folderIds);
         IPage<Document> page = baseMapper.selectPage(pageQuery.build(), wrapper);
         List<Long> ossIds = new ArrayList<>();
-        Map<Long, String> ossMap = new HashMap<>();
+        Map<Long, SysOssVo> ossMap = new HashMap<>();
         page.getRecords().forEach(e -> ossIds.add(e.getOssId()));
-        ossService.queryListByIds(ossIds).forEach(e -> ossMap.put(e.getOssId(), e.getUrl()));
+        ossService.queryListByIds(ossIds).forEach(e -> ossMap.put(e.getOssId(), e));
         return TableDataInfo.build(page.convert(e -> {
             TaskCenterAuditListVo vo = new TaskCenterAuditListVo();
             vo.setId(e.getId());
@@ -359,7 +360,8 @@ public class DocumentServiceImpl implements IDocumentService {
             vo.setSubmitTime(e.getSubmitTime());
             vo.setCreateTime(e.getCreateTime());
             vo.setOssId(e.getOssId());
-            vo.setOssUrl(ossMap.get(e.getOssId()));
+            vo.setFileName(ossMap.get(e.getOssId()).getOriginalName());
+            vo.setOssUrl(ossMap.get(e.getOssId()).getUrl());
             vo.setType(e.getType());
             vo.setDocumentType(e.getPlanType());
             return vo;
@@ -411,7 +413,14 @@ public class DocumentServiceImpl implements IDocumentService {
     private String buildRemark(Long ossId) {
         Document document = baseMapper.selectOne(Wrappers.lambdaQuery(Document.class).eq(Document::getOssId, ossId));
         if (document == null) {
-            throw new BusinessException(MessageUtils.message("document.document.download.notfound"));
+            DocumentAuditLog log = auditLogMapper.selectOne(
+                Wrappers.lambdaQuery(DocumentAuditLog.class)
+                    .eq(DocumentAuditLog::getOssId, ossId)
+            );
+            if (log == null) {
+                throw new BusinessException(MessageUtils.message("document.document.download.notfound"));
+            }
+            document = baseMapper.selectById(log.getDocumentId());
         }
         Project project = projectService.queryById(document.getProjectId());
         return project.getCode() + ":" + document.getId();
@@ -480,28 +489,20 @@ public class DocumentServiceImpl implements IDocumentService {
         AppletMineCountVo vo = new AppletMineCountVo();
         List<Document> documentList = baseMapper.selectList(
             Wrappers.lambdaQuery(Document.class)
-                .and(wrapper -> wrapper
-                    .eq(Document::getCreateBy, LoginHelper.getUserId()))
-                .or()
-                .eq(Document::getSubmitterId, LoginHelper.getUserId()
-                )
-                .in(Document::getStatus, List.of(DocumentStatusConst.UN_UPLOAD, DocumentStatusConst.UN_AUDIT))
+                .eq(Document::getSubmitterId, LoginHelper.getUserId())
+                .in(Document::getStatus, List.of(DocumentStatusConst.UN_UPLOAD, DocumentStatusConst.UN_AUDIT, DocumentStatusConst.AUDIT_REJECT))
         );
         vo.setToSubmit(
             documentList
                 .stream()
                 .filter(e ->
-                    e.getSubmitterId().equals(LoginHelper.getUserId())
-                    &&
-                    (e.getStatus().equals(DocumentStatusConst.UN_UPLOAD) || e.getStatus().equals(DocumentStatusConst.AUDIT_REJECT))
+                    e.getStatus().equals(DocumentStatusConst.UN_UPLOAD) || e.getStatus().equals(DocumentStatusConst.AUDIT_REJECT)
                 ).toList().size()
         );
         vo.setToAudit(
             documentList
                 .stream()
                 .filter(e ->
-                    e.getCreateBy().equals(LoginHelper.getUserId())
-                    &&
                     e.getStatus().equals(DocumentStatusConst.UN_AUDIT)
                 ).toList().size()
         );
@@ -514,19 +515,15 @@ public class DocumentServiceImpl implements IDocumentService {
             pageQuery.build(),
             Wrappers.lambdaQuery(Document.class)
                 .like(StringUtils.isNotBlank(bo.getName()), Document::getName, bo.getName())
-                .and(
-                    wrapper -> wrapper
-                        .eq(Document::getSubmitterId, LoginHelper.getUserId())
-                        .or()
-                        .eq(Document::getCreateBy, LoginHelper.getUserId())
-                )
+                .eq(Document::getSubmitterId, LoginHelper.getUserId())
+                .ne(Document::getStatus, DocumentStatusConst.UN_UPLOAD)
                 .orderByDesc(Document::getId)
         );
         return TableDataInfo.build(page.convert(e -> {
             AppletRecentDocumentVo vo = new AppletRecentDocumentVo();
             vo.setId(e.getId());
             vo.setName(e.getName());
-            vo.setCreateTime(e.getCreateTime());
+            vo.setCreateTime(e.getSubmitTime());
             vo.setOssId(e.getOssId());
             return vo;
         }));
@@ -537,15 +534,8 @@ public class DocumentServiceImpl implements IDocumentService {
         IPage<Document> page = baseMapper.selectPage(
             pageQuery.build(),
             Wrappers.lambdaQuery(Document.class)
-                .eq(bo.getStatus() != null && bo.getStatus().equals(DocumentStatusConst.UN_UPLOAD), Document::getSubmitterId, LoginHelper.getUserId())
-                .eq(bo.getStatus() != null && bo.getStatus().equals(DocumentStatusConst.UN_AUDIT), Document::getCreateBy, LoginHelper.getUserId())
+                .eq(Document::getSubmitterId, LoginHelper.getUserId())
                 .eq(bo.getStatus() != null, Document::getStatus, bo.getStatus())
-                .and(bo.getStatus() == null,
-                    wrapper -> wrapper
-                    .eq(Document::getSubmitterId, LoginHelper.getUserId())
-                    .or()
-                    .eq(Document::getCreateBy, LoginHelper.getUserId())
-                )
                 .like(StringUtils.isNotBlank(bo.getName()), Document::getName, bo.getName())
                 .orderByDesc(Document::getId)
         );
@@ -557,6 +547,7 @@ public class DocumentServiceImpl implements IDocumentService {
             vo.setOssId(e.getOssId());
             vo.setCreateBy(e.getCreateBy());
             vo.setSubmitterId(e.getSubmitterId());
+            vo.setStatus(e.getStatus());
             return vo;
         }));
     }
@@ -567,7 +558,7 @@ public class DocumentServiceImpl implements IDocumentService {
             pageQuery.build(),
             Wrappers.lambdaQuery(Document.class)
                 .eq(Document::getSubmitterId, LoginHelper.getUserId())
-                .eq(Document::getStatus, List.of(DocumentStatusConst.UN_UPLOAD, DocumentStatusConst.AUDIT_REJECT))
+                .in(Document::getStatus, List.of(DocumentStatusConst.UN_UPLOAD, DocumentStatusConst.AUDIT_REJECT))
                 .like(StringUtils.isNotBlank(bo.getName()), Document::getName, bo.getName())
                 .orderByDesc(Document::getId)
         );
@@ -614,46 +605,106 @@ public class DocumentServiceImpl implements IDocumentService {
             throw new BusinessException("提交的文件列表为空");
         }
 
-        List<File> files = new ArrayList<>();
-
-        File finalFile;
+        File file;
         try {
+            file = convertToFile(fileBase64List, document.getName());
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+        SysOssVo ossVo = ossService.upload(file);
 
-            for (int i = 0; i < fileBase64List.size(); i++) {
-                String base64Str = fileBase64List.get(i);
-                if (base64Str == null || base64Str.trim().isEmpty()) {
-                    continue;
-                }
+        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::getSubmitTime, new Date())
+        ) > 0;
+    }
 
-                String cleanBase64 = base64Str;
-                if (base64Str.contains(",")) {
-                    cleanBase64 = base64Str.split(",", 2)[1];
-                }
+    private File convertToFile(List<String> fileBase64List, String fileName) throws IOException {
 
-                byte[] pdfBytes = Base64.getDecoder().decode(cleanBase64);
+        List<File> files = new ArrayList<>();
 
-                Path tempPath = Files.createTempFile("document_", "_" + i + ".pdf");
-                Files.write(tempPath, pdfBytes);
-                files.add(tempPath.toFile());
+        File finalFile;
+
+        for (int i = 0; i < fileBase64List.size(); i++) {
+            String base64Str = fileBase64List.get(i);
+            if (base64Str == null || base64Str.trim().isEmpty()) {
+                continue;
             }
 
-            if (files.isEmpty()) {
-                throw new BusinessException("未解析到有效的 PDF 文件数据");
+            String cleanBase64 = base64Str;
+            if (base64Str.contains(",")) {
+                cleanBase64 = base64Str.split(",", 2)[1];
             }
 
-            finalFile = PdfUtils.merge(files, document.getName());
+            byte[] pdfBytes = Base64.getDecoder().decode(cleanBase64);
+
+            Path tempPath = Files.createTempFile("document_", "_" + i + ".pdf");
+            Files.write(tempPath, pdfBytes);
+            files.add(tempPath.toFile());
+        }
+
+        if (files.isEmpty()) {
+            throw new BusinessException("未解析到有效的 PDF 文件数据");
+        }
+
+        finalFile = PdfUtils.merge(files, fileName);
+
+        return finalFile;
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean uploadNew(AppletUploadNewBo bo) {
+
+        List<String> fileBase64List = bo.getFiles();
+
+        if (fileBase64List == null || fileBase64List.isEmpty()) {
+            throw new BusinessException("提交的文件列表为空");
+        }
+
+        File file;
+        try {
+            file = convertToFile(fileBase64List, bo.getFileName());
         } catch (IOException e) {
             throw new RuntimeException(e);
         }
-        SysOssVo ossVo = ossService.upload(finalFile);
+        SysOssVo ossVo = ossService.upload(file);
+
+        Document document = new Document();
+        document.setFolderId(bo.getFolderId());
+        document.setName(bo.getFileName());
+        document.setStatus(DocumentStatusConst.UN_AUDIT);
+        document.setOssId(ossVo.getOssId());
+        document.setNote(bo.getNote());
+        document.setType(DocumentTypeConst.NOT_PLAN);
+        document.setSubmitterId(LoginHelper.getUserId());
+        document.setSubmitTime(new Date());
+        document.setProjectId(bo.getProjectId());
+        document.setSendFlag(false);
+        document.setSendStatus(false);
+        document.setTenantId(TenantHelper.getTenantId());
+        document.setCreateDept(LoginHelper.getDeptId());
+        document.setCreateBy(LoginHelper.getUserId());
+        document.setCreateTime(new Date());
+        document.setUpdateBy(LoginHelper.getUserId());
+        document.setUpdateTime(new Date());
+
+        return baseMapper.insert(document) > 0;
+    }
 
-        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::getSubmitTime, new Date())
-        ) > 0;
+    @Override
+    public AppletGetRejectionVo getRejection(Long documentId) {
+        return new AppletGetRejectionVo(
+            auditLogMapper.selectOne(
+                Wrappers.lambdaQuery(DocumentAuditLog.class)
+                    .eq(DocumentAuditLog::getDocumentId, documentId)
+                    .orderByDesc(DocumentAuditLog::getId)
+                    .last("LIMIT 1")
+            ).getRejectReason()
+        );
     }
 
     private LambdaQueryWrapper<Document> buildFilingListWrapper(TaskCenterFilingListBo bo, List<Long> folderIds) {

+ 27 - 27
script/sql/business/create.sql

@@ -101,21 +101,21 @@ CREATE TABLE `document_audit_log`
 
 CREATE TABLE `document_quality_control_task`
 (
-    `id`           bigint unsigned PRIMARY KEY NOT NULL AUTO_INCREMENT COMMENT '序号',
-    `name`         varchar(128)                NOT NULL COMMENT '质控名称',
-    `initiator`    bigint unsigned             NOT NULL COMMENT '发起人',
-    `project_id`   bigint unsigned             NOT NULL COMMENT '质控项目',
-    `start_date`   date COMMENT '开始时间',
-    `deadline`     date COMMENT '截止时间',
-    `status`       tinyint(1)                  NOT NULL DEFAULT 0 COMMENT '状态',
-    `note`         varchar(255) 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 '序号',
+    `name`        varchar(128)                NOT NULL COMMENT '质控名称',
+    `initiator`   bigint unsigned             NOT NULL COMMENT '发起人',
+    `project_id`  bigint unsigned             NOT NULL COMMENT '质控项目',
+    `start_date`  date                        NOT NULL COMMENT '开始时间',
+    `deadline`    date                        NOT NULL COMMENT '截止时间',
+    `status`      tinyint(1)                  NOT NULL DEFAULT 0 COMMENT '状态',
+    `note`        varchar(255) 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 ='文档质控任务';
 
@@ -123,7 +123,7 @@ CREATE TABLE `document_quality_control_task_detail`
 (
     `id`          bigint unsigned PRIMARY KEY NOT NULL AUTO_INCREMENT COMMENT '序号',
     `task_id`     bigint unsigned             NOT NULL COMMENT '所属任务',
-    `document_id` bigint unsigned             NOT NULL COMMENT '控文件',
+    `document_id` bigint unsigned             NOT NULL COMMENT '控文件',
     `status`      tinyint(1)                  NOT NULL DEFAULT 0 COMMENT '状态',
     `note`        varchar(255) COMMENT '备注',
     `create_dept` bigint(20) COMMENT '创建部门',
@@ -189,16 +189,16 @@ CREATE TABLE `ai_setting`
 
 CREATE TABLE `carousel_setting`
 (
-    `id`           bigint unsigned PRIMARY KEY NOT NULL AUTO_INCREMENT COMMENT '序号',
-    `ossId`        bigint unsigned             NOT NULL COMMENT '图片',
-    `sort`         int    unsigned             NOT NULL DEFAULT 0 COMMENT '排序',
-    `note`         varchar(255)                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 '序号',
+    `ossId`       bigint unsigned             NOT NULL COMMENT '图片',
+    `sort`        int unsigned                NOT NULL DEFAULT 0 COMMENT '排序',
+    `note`        varchar(255) 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 ='轮播图设置';