Ver código fonte

- 文档管理基本完成
- 工作区开始进行

Huanyi 6 dias atrás
pai
commit
f0a9a52e38
17 arquivos alterados com 309 adições e 43 exclusões
  1. 9 0
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/constant/DocumentTypeConst.java
  2. 11 0
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/constant/QualityControlTaskStatusConst.java
  3. 12 0
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/controller/DashboardController.java
  4. 1 1
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/controller/FolderController.java
  5. 0 16
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/controller/ProjectController.java
  6. 38 0
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/controller/TaskCenterController.java
  7. 28 0
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/controller/WorkbenchController.java
  8. 4 0
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/domain/Document.java
  9. 3 0
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/domain/bo/DocumentBo.java
  10. 1 1
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/domain/vo/ProjectInDashboardWorkbenchVo.java
  11. 2 0
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/service/IFolderService.java
  12. 1 2
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/service/IProjectService.java
  13. 27 0
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/service/impl/CommonDocumentService.java
  14. 2 1
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/service/impl/DocumentServiceImpl.java
  15. 98 0
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/service/impl/FolderServiceImpl.java
  16. 32 21
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/service/impl/ProjectServiceImpl.java
  17. 40 1
      script/sql/business/create.sql

+ 9 - 0
ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/constant/DocumentTypeConst.java

@@ -0,0 +1,9 @@
+package com.yingpaipay.business.constant;
+
+public interface DocumentTypeConst {
+
+    Integer NOT_PLAN = 0;
+
+    Integer PLAN = 1;
+
+}

+ 11 - 0
ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/constant/QualityControlTaskStatusConst.java

@@ -0,0 +1,11 @@
+package com.yingpaipay.business.constant;
+
+public interface QualityControlTaskStatusConst {
+
+    Integer NON_EXECUTION = 0;
+
+    Integer IN_EXECUTION = 1;
+
+    Integer COMPLETE = 2;
+
+}

+ 12 - 0
ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/controller/DashboardController.java

@@ -0,0 +1,12 @@
+package com.yingpaipay.business.controller;
+
+import lombok.RequiredArgsConstructor;
+import org.dromara.common.web.core.BaseController;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequestMapping("/dashboard")
+@RequiredArgsConstructor
+public class DashboardController extends BaseController {
+}

+ 1 - 1
ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/controller/FolderController.java

@@ -56,7 +56,7 @@ public class FolderController extends BaseController {
 
     @GetMapping("/listOnProject")
     public R<List<FolderListVo>> listOnProject(Long projectId) {
-        return R.ok(folderService.selectList(projectId));
+        return R.ok(folderService.selectAllList(projectId));
     }
 
     @SaCheckPermission("document:folder:add")

+ 0 - 16
ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/controller/ProjectController.java

@@ -9,8 +9,6 @@ import lombok.RequiredArgsConstructor;
 import jakarta.servlet.http.HttpServletResponse;
 import jakarta.validation.constraints.*;
 import cn.dev33.satoken.annotation.SaCheckPermission;
-import org.dromara.common.core.service.UserService;
-import org.dromara.system.service.ISysUserService;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.validation.annotation.Validated;
 import org.dromara.common.idempotent.annotation.RepeatSubmit;
@@ -49,12 +47,6 @@ public class ProjectController extends BaseController {
         return projectService.queryPageList(bo, pageQuery);
     }
 
-    @SaCheckPermission("dashboard:workbench:index")
-    @GetMapping("/listOnDashboardWorkbench")
-    public TableDataInfo<ProjectInDashboardWorkbenchVo> listOnDashboardWorkbench(ProjectListOnDashboardWorkbenchBo bo, PageQuery pageQuery) {
-        return projectService.queryPageListOnDashboardWorkbench(bo, pageQuery);
-    }
-
     /**
      * 导出项目管理列表
      */
@@ -149,14 +141,6 @@ public class ProjectController extends BaseController {
         return folderService.queryCenterInfo(bo, pageQuery);
     }
 
-//    @SaCheckPermission("project:management:queryCenterInfoInviteMember")
-//    @Log(title = "项目管理", businessType = BusinessType.INSERT)
-//    @RepeatSubmit()
-//    @PostMapping("/queryCenterInfoInviteMember")
-//    public R<Void> inviteCenterMember(@RequestBody ProjectInviteCenterMemberBo bo) {
-//        return toAjax(projectService.inviteCenterMember(bo));
-//    }
-
     @SaCheckPermission("project:management:queryProjectMemberAddMember")
     @Log(title = "项目管理", businessType = BusinessType.INSERT)
     @PostMapping("/queryProjectMemberAddMember")

+ 38 - 0
ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/controller/TaskCenterController.java

@@ -0,0 +1,38 @@
+package com.yingpaipay.business.controller;
+
+import cn.dev33.satoken.annotation.SaCheckPermission;
+import com.yingpaipay.business.domain.bo.DocumentAuditBo;
+import com.yingpaipay.business.domain.bo.DocumentSubmitBo;
+import com.yingpaipay.business.service.IDocumentService;
+import lombok.RequiredArgsConstructor;
+import org.dromara.common.core.domain.R;
+import org.dromara.common.log.annotation.Log;
+import org.dromara.common.log.enums.BusinessType;
+import org.dromara.common.web.core.BaseController;
+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
+@RequiredArgsConstructor
+@RequestMapping("/workArea/taskCenter")
+public class TaskCenterController extends BaseController {
+
+    private final IDocumentService documentService;
+
+    @SaCheckPermission("taskCenter:submission:submit")
+    @Log(title = "文档", businessType = BusinessType.UPDATE)
+    @PutMapping("/submit")
+    public R<Void> submit(@RequestBody DocumentSubmitBo bo) {
+        return toAjax(documentService.submit(bo));
+    }
+
+    @SaCheckPermission("taskCenter:audit:audit")
+    @Log(title = "任务中心", businessType = BusinessType.UPDATE)
+    @PutMapping("/audit")
+    public R<Void> audit(@RequestBody DocumentAuditBo bo) {
+        return toAjax(documentService.audit(bo));
+    }
+
+}

+ 28 - 0
ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/controller/WorkbenchController.java

@@ -0,0 +1,28 @@
+package com.yingpaipay.business.controller;
+
+import cn.dev33.satoken.annotation.SaCheckPermission;
+import com.yingpaipay.business.domain.bo.ProjectListOnDashboardWorkbenchBo;
+import com.yingpaipay.business.domain.vo.ProjectInDashboardWorkbenchVo;
+import com.yingpaipay.business.service.IProjectService;
+import lombok.RequiredArgsConstructor;
+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.RestController;
+
+@RestController
+@RequestMapping("/workArea/workbench")
+@RequiredArgsConstructor
+public class WorkbenchController extends BaseController {
+
+    private final IProjectService projectService;
+
+    @SaCheckPermission("workArea:workbench:index")
+    @GetMapping("/list")
+    public TableDataInfo<ProjectInDashboardWorkbenchVo> listOnDashboardWorkbench(ProjectListOnDashboardWorkbenchBo bo, PageQuery pageQuery) {
+        return projectService.queryPageListOnDashboardWorkbench(bo, pageQuery);
+    }
+
+}

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

@@ -79,4 +79,8 @@ public class Document extends TenantEntity {
 
     private Long submitterId;
 
+    private Date submitTime;
+
+    private Long projectId;
+
 }

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

@@ -74,6 +74,7 @@ public class DocumentBo extends BaseEntity {
     /**
      * 递交时间
      */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
     private Date submitTime;
 
     /**
@@ -83,4 +84,6 @@ public class DocumentBo extends BaseEntity {
 
     private Integer status;
 
+    private Long projectId;
+
 }

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

@@ -15,7 +15,7 @@ public class ProjectInDashboardWorkbenchVo {
 
     private Double onTimeSubmissionRate;
 
-    private Integer lateSubmissionCount;
+    private Long lateSubmissionCount;
 
     private Double submissionProgress;
 

+ 2 - 0
ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/service/IFolderService.java

@@ -24,6 +24,8 @@ public interface IFolderService {
 
     List<FolderListVo> selectList(Long projectId);
 
+    List<FolderListVo> selectAllList(Long projectId);
+
     boolean insertByBo(FolderBo bo);
 
     boolean deleteWithValidIds(Collection<Long> ids, Boolean isValid);

+ 1 - 2
ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/service/IProjectService.java

@@ -76,8 +76,6 @@ public interface IProjectService {
 
     TableDataInfo<ProjectOnDocumentVo> listOnDocument(ProjectOnDocumentBo bo, PageQuery pageQuery);
 
-//    boolean inviteCenterMember(ProjectInviteCenterMemberBo bo);
-
     TableDataInfo<ProjectMemberNotInCenterVo> queryMemberNotInCenter(Long projectId, Long folderId, String name, PageQuery pageQuery);
 
     TableDataInfo<ProjectInDashboardWorkbenchVo> queryPageListOnDashboardWorkbench(ProjectListOnDashboardWorkbenchBo bo, PageQuery pageQuery);
@@ -87,4 +85,5 @@ public interface IProjectService {
     ProjectFolderVo getFoldersByUserId(Long userId, Long projectId);
 
     boolean updateFolders(ProjectMemberUpdateFoldersBo bo);
+
 }

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

@@ -0,0 +1,27 @@
+package com.yingpaipay.business.service.impl;
+
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.yingpaipay.business.domain.Document;
+import com.yingpaipay.business.mapper.DocumentMapper;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+@Service
+@RequiredArgsConstructor
+public class CommonDocumentService {
+
+    private final DocumentMapper baseMapper;
+
+
+    public List<Document> queryListByProjectIds(List<Long> projectIds) {
+        if (projectIds.isEmpty()) {
+            return List.of();
+        }
+        return baseMapper.selectList(
+            Wrappers.lambdaQuery(Document.class)
+                .in(Document::getProjectId, projectIds)
+        );
+    }
+}

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

@@ -198,7 +198,7 @@ public class DocumentServiceImpl implements IDocumentService {
         return baseMapper.update(
             Wrappers.lambdaUpdate(Document.class)
                 .eq(Document::getId, bo.getId())
-                .set(Document::getType, bo.getType())
+                .set(Document::getSpecification, bo.getType())
         ) > 0;
     }
 
@@ -208,6 +208,7 @@ public class DocumentServiceImpl implements IDocumentService {
             Wrappers.lambdaUpdate(Document.class)
                 .eq(Document::getId, bo.getDocumentId())
                 .set(Document::getOssId, bo.getOssId())
+                .set(Document::getSubmitTime, new Date())
                 .set(Document::getSubmitterId, LoginHelper.getUserId())
                 .set(Document::getStatus, DocumentStatusConst.UN_AUDIT)
         ) > 0;

+ 98 - 0
ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/service/impl/FolderServiceImpl.java

@@ -24,6 +24,7 @@ import org.dromara.common.core.utils.StringUtils;
 import org.dromara.common.json.utils.JsonUtils;
 import org.dromara.common.mybatis.core.page.PageQuery;
 import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.satoken.utils.LoginHelper;
 import org.dromara.system.domain.SysUser;
 import org.dromara.system.domain.vo.SysUserVo;
 import org.dromara.system.service.ISysDeptService;
@@ -35,6 +36,7 @@ import org.springframework.transaction.annotation.Transactional;
 
 import java.util.*;
 import java.util.concurrent.atomic.AtomicInteger;
+import java.util.function.Function;
 import java.util.stream.Collectors;
 
 /**
@@ -56,6 +58,102 @@ public class FolderServiceImpl implements IFolderService {
 
     @Override
     public List<FolderListVo> selectList(Long projectId) {
+        List<Folder> allFolders = baseMapper.selectList(
+            Wrappers.lambdaQuery(Folder.class).eq(Folder::getProjectId, projectId)
+        );
+
+        if (allFolders.isEmpty()) {
+            return Collections.emptyList();
+        }
+
+        SysUserFolders userFolderRecord = userFoldersMapper.selectOne(
+            Wrappers.lambdaQuery(SysUserFolders.class)
+                .eq(SysUserFolders::getProjectId, projectId)
+                .eq(SysUserFolders::getUserId, LoginHelper.getUserId())
+        );
+
+        List<Folder> retainedFolders;
+
+        if (userFolderRecord != null && "*".equals(userFolderRecord.getFolders())) {
+            retainedFolders = allFolders;
+        } else {
+            if (userFolderRecord == null || StringUtils.isBlank(userFolderRecord.getFolders())) {
+                return Collections.emptyList();
+            }
+
+            Set<Long> directPermissionIds = Arrays.stream(userFolderRecord.getFolders().split(","))
+                .map(String::trim)
+                .filter(StringUtils::isNotBlank)
+                .map(Long::valueOf)
+                .collect(Collectors.toSet());
+
+            Map<Long, Folder> folderMap = allFolders.stream()
+                .collect(Collectors.toMap(Folder::getId, f -> f));
+
+            Map<Long, List<Folder>> fullChildrenMap = allFolders.stream()
+                .filter(f -> f.getParentId() != null)
+                .collect(Collectors.groupingBy(Folder::getParentId));
+
+            Set<Long> retainedIds = new HashSet<>();
+
+            for (Long seedId : directPermissionIds) {
+                Long current = seedId;
+                while (current != null) {
+                    if (!folderMap.containsKey(current)) break;
+                    retainedIds.add(current);
+                    current = folderMap.get(current).getParentId();
+                }
+
+                collectAllDescendants(seedId, fullChildrenMap, retainedIds);
+            }
+
+            retainedFolders = allFolders.stream()
+                .filter(f -> retainedIds.contains(f.getId()))
+                .collect(Collectors.toList());
+        }
+
+        Map<Long, List<Folder>> childrenMap = retainedFolders.stream()
+            .filter(f -> f.getParentId() != null)
+            .collect(Collectors.groupingBy(Folder::getParentId));
+
+        List<Folder> roots = retainedFolders.stream()
+            .filter(f -> f.getParentId() == null)
+            .toList();
+
+        return roots.stream()
+            .map(root -> buildVoTree(root, childrenMap))
+            .collect(Collectors.toList());
+    }
+
+    private void collectAllDescendants(Long parentId, Map<Long, List<Folder>> childrenMap, Set<Long> result) {
+        List<Folder> children = childrenMap.get(parentId);
+        if (children != null) {
+            for (Folder child : children) {
+                result.add(child.getId());
+                collectAllDescendants(child.getId(), childrenMap, result);
+            }
+        }
+    }
+
+    private FolderListVo buildVoTree(Folder folder, Map<Long, List<Folder>> childrenMap) {
+        FolderListVo vo = new FolderListVo();
+        vo.setId(folder.getId());
+        vo.setName(folder.getName());
+        vo.setType(folder.getType());
+
+        List<Folder> children = childrenMap.get(folder.getId());
+        if (children != null && !children.isEmpty()) {
+            vo.setChildren(children.stream()
+                .map(child -> buildVoTree(child, childrenMap))
+                .collect(Collectors.toList()));
+        } else {
+            vo.setChildren(Collections.emptyList());
+        }
+        return vo;
+    }
+
+    @Override
+    public List<FolderListVo> selectAllList(Long projectId) {
         List<Folder> folders = baseMapper.selectList(Wrappers.lambdaQuery(Folder.class).eq(Folder::getProjectId, projectId));
         Map<Long, List<Folder>> childrenMap = folders.stream()
             .filter(this::isNotRoot)

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

@@ -2,10 +2,13 @@ package com.yingpaipay.business.service.impl;
 
 import cn.hutool.crypto.digest.BCrypt;
 import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.yingpaipay.business.constant.DocumentTypeConst;
 import com.yingpaipay.business.constant.UserAppletStatusConst;
+import com.yingpaipay.business.domain.Document;
 import com.yingpaipay.business.domain.bo.*;
 import com.yingpaipay.business.domain.vo.*;
 import com.yingpaipay.business.enumeration.ProjectStatusEnum;
+import com.yingpaipay.business.mapper.DocumentMapper;
 import com.yingpaipay.system.domain.SysUserFolders;
 import com.yingpaipay.system.domain.SysUserProjects;
 import com.yingpaipay.system.mapper.SysUserFoldersMapper;
@@ -35,6 +38,7 @@ import com.yingpaipay.business.service.IProjectService;
 import org.springframework.transaction.annotation.Transactional;
 
 import java.util.*;
+import java.util.stream.Collectors;
 
 /**
  * 项目管理Service业务层处理
@@ -55,6 +59,7 @@ public class ProjectServiceImpl implements IProjectService {
     private final ISysOssService ossService;
     private final ISysDeptService deptService;
     private final ISysUserService userService;
+    private final CommonDocumentService documentService;
 
     /**
      * 查询项目管理
@@ -84,11 +89,9 @@ public class ProjectServiceImpl implements IProjectService {
         Page<ProjectVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
         List<Long> iconIds = new ArrayList<>();
         result.getRecords().forEach(e -> iconIds.add(e.getIcon()));
-        if (!iconIds.isEmpty()) {
-            Map<Long, String> iconMap = new HashMap<>();
-            ossService.listByIds(iconIds).forEach(e -> iconMap.put(e.getOssId(), e.getUrl()));
-            result.getRecords().forEach(e -> e.setIconUrl(iconMap.get(e.getIcon())));
-        }
+        Map<Long, String> iconMap = new HashMap<>();
+        ossService.queryListByIds(iconIds).forEach(e -> iconMap.put(e.getOssId(), e.getUrl()));
+        result.getRecords().forEach(e -> e.setIconUrl(iconMap.get(e.getIcon())));
         return TableDataInfo.build(result);
     }
 
@@ -293,18 +296,6 @@ public class ProjectServiceImpl implements IProjectService {
         }));
     }
 
-//    @Override
-//    public boolean inviteCenterMember(ProjectInviteCenterMemberBo bo) {
-//        List<SysUserFolder> userFolder = new ArrayList<>();
-//        bo.getUserIds().forEach(e -> {
-//            SysUserFolder entity = new SysUserFolder();
-//            entity.setUserId(e);
-//            entity.setFolderId(bo.getFolderId());
-//            userFolder.add(entity);
-//        });
-//        return userFolderMapper.insertBatch(userFolder);
-//    }
-
     @Override
     public TableDataInfo<ProjectMemberNotInCenterVo> queryMemberNotInCenter(Long projectId, Long folderId, String name, PageQuery pageQuery) {
         // TODO 只能是项目中的人
@@ -359,14 +350,34 @@ public class ProjectServiceImpl implements IProjectService {
                 .like(StringUtils.isNotBlank(bo.getContent()), Project::getCtaGcta, bo.getContent())
                 .orderByDesc(Project::getId)
         );
+        List<Long> projectIds = new ArrayList<>();
+        page.getRecords().forEach(e -> projectIds.add(e.getId()));
+        List<Document> documents = documentService.queryListByProjectIds(projectIds);
+        Map<Long, List<Document>> documentMap = documents.stream().collect(Collectors.groupingBy(Document::getProjectId));
         return TableDataInfo.build(page.convert(e -> {
+            List<Document> documentList = documentMap.get(e.getId());
             ProjectInDashboardWorkbenchVo vo = new ProjectInDashboardWorkbenchVo();
             vo.setId(e.getId());
             vo.setCode(e.getCode());
             vo.setName(e.getName());
-            vo.setOnTimeSubmissionRate(0.00D);
-            vo.setLateSubmissionCount(0);
-            vo.setSubmissionProgress(0.00D);
+            int total = documentList.size();
+            List<Document> planDocuments = documentList.stream()
+                .filter(item -> item.getType().equals(DocumentTypeConst.PLAN))
+                .toList();
+            long onTimeSubmit = planDocuments.stream()
+                .filter(item -> item.getOssId() != null && item.getSubmitTime().before(item.getSubmitDeadline()))
+                .count();
+            long lateSubmit = planDocuments.stream()
+                .filter(item -> item.getOssId() != null)
+                .filter(item -> item.getSubmitDeadline().before(item.getSubmitTime()))
+                .count();
+            long unsubmit = planDocuments.stream()
+                .filter(item -> item.getOssId() == null)
+                .filter(item -> item.getSubmitDeadline().before(new Date()))
+                .count();
+            vo.setOnTimeSubmissionRate(Double.valueOf(String.format("%.2f", (double) onTimeSubmit / total * 100)));
+            vo.setLateSubmissionCount(lateSubmit);
+            vo.setSubmissionProgress(Double.valueOf(String.format("%.2f", (double) unsubmit / total * 100)));
             vo.setPdGpd(e.getPdGpd());
             vo.setPmGpm(e.getPmGpm());
             vo.setCtaGcta(e.getCtaGcta());
@@ -444,7 +455,7 @@ public class ProjectServiceImpl implements IProjectService {
         user.setStatus(SystemConstants.NORMAL);
         user.setAppletStatus(UserAppletStatusConst.NORMAL);
         user.setRoleIds(bo.getRoleIds());
-        user.setProjects(bo.getProjectId().toString() + ",");
+        user.setProjects(bo.getProjectId().toString());
         user.setCreateDept(LoginHelper.getDeptId());
         user.setCreateBy(LoginHelper.getUserId());
         user.setCreateTime(new Date());

+ 40 - 1
script/sql/business/create.sql

@@ -83,7 +83,7 @@ CREATE TABLE `document_audit_log`
 (
     `id`            bigint unsigned PRIMARY KEY NOT NULL AUTO_INCREMENT COMMENT '序号',
     `document_id`   bigint unsigned             NOT NULL COMMENT '审核文档',
-    `oss_id`        bigint unique               NOT NULL COMMENT '历史版本',
+    `oss_id`        bigint unsigned             NOT NULL COMMENT '历史版本',
     `auditor_type`  char(1)                     NOT NULL COMMENT '审核人类型',
     `auditor_id`    bigint unsigned             NOT NULL COMMENT '审核人',
     `result`        tinyint(1)                  NOT NULL COMMENT '审核结果(0 -> 通过; 1 -> 驳回)',
@@ -99,6 +99,45 @@ CREATE TABLE `document_audit_log`
 ) ENGINE = InnoDB
   DEFAULT CHARSET = utf8mb4 COMMENT ='文档审核记录';
 
+CREATE TABLE `document_quality_control_task`
+(
+    `id`           bigint unsigned PRIMARY KEY NOT NULL AUTO_INCREMENT COMMENT '序号',
+    `name`         varchar(128)                NOT NULL COMMENT '质控名称',
+    `initiator_id` 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'
+) ENGINE = InnoDB
+  DEFAULT CHARSET = utf8mb4 COMMENT ='文档质控任务';
+
+CREATE TABLE `document_quality_control_task_detail`
+(
+    `id`                bigint unsigned PRIMARY KEY NOT NULL AUTO_INCREMENT COMMENT '序号',
+    `task_id`           bigint unsigned             NOT NULL COMMENT '所属任务',
+    `executor_id`       bigint unsigned             NOT NULL COMMENT '执行人',
+    `plan_execute_time` bigint COMMENT '预期执行时间',
+    `execute_time`      datetime 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 ='文档质控细节';
+
 CREATE TABLE `project_setting`
 (
     `id`          bigint unsigned PRIMARY KEY NOT NULL AUTO_INCREMENT COMMENT '序号',