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

【修改】附件上传改造

lichen пре 1 година
родитељ
комит
41bae13d01
12 измењених фајлова са 229 додато и 16 уклоњено
  1. 5 0
      yudao-module-bpm/yudao-module-bpm-biz/pom.xml
  2. 6 3
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/entry/vo/OaEntrySaveReqVO.java
  3. 17 5
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/entry/OaEntryServiceImpl.java
  4. 11 0
      yudao-module-infra/yudao-module-infra-api/src/main/java/cn/iocoder/yudao/module/infra/api/file/FileApi.java
  5. 55 0
      yudao-module-infra/yudao-module-infra-api/src/main/java/cn/iocoder/yudao/module/infra/api/file/dto/FileDTO.java
  6. 9 0
      yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/api/file/FileApiImpl.java
  7. 10 2
      yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/FileController.java
  8. 5 0
      yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/vo/file/FileRespVO.java
  9. 43 0
      yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/vo/file/FileSaveReqVO.java
  10. 10 0
      yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/dataobject/file/FileDO.java
  11. 17 3
      yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/file/FileService.java
  12. 41 3
      yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/file/FileServiceImpl.java

+ 5 - 0
yudao-module-bpm/yudao-module-bpm-biz/pom.xml

@@ -16,6 +16,11 @@
         例如说:流程定义、表单配置、审核中心(我的申请、我的待办、我的已办)等等
     </description>
     <dependencies>
+        <dependency>
+            <groupId>cn.iocoder.boot</groupId>
+            <artifactId>yudao-module-infra-api</artifactId>
+            <version>${revision}</version>
+        </dependency>
         <dependency>
             <groupId>cn.iocoder.boot</groupId>
             <artifactId>yudao-module-bpm-api</artifactId>

+ 6 - 3
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/entry/vo/OaEntrySaveReqVO.java

@@ -9,6 +9,9 @@ import javax.validation.constraints.*;
 @Data
 public class OaEntrySaveReqVO {
 
+    @Schema(description = "入职人", example = "李四")
+    private String entryName;
+
     @Schema(description = "uuid", example = "13471")
     private String entryId;
 
@@ -49,9 +52,6 @@ public class OaEntrySaveReqVO {
     @Schema(description = "入职表单主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "27428")
     private Integer id;
 
-    @Schema(description = "入职人", example = "李四")
-    private String entryName;
-
     @Schema(description = "入职日期")
     private String entryDate;
 
@@ -75,4 +75,7 @@ public class OaEntrySaveReqVO {
     @Schema(description = "发起人自选审批人 Map", example = "{taskKey1: [1, 2]}")
     private Map<String, List<Long>> startUserSelectAssignees;
 
+    @Schema(description = "附件主键id", example = "[1, 2]")
+    private List<Long> fileIdList;
+
 }

+ 17 - 5
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/entry/OaEntryServiceImpl.java

@@ -9,6 +9,10 @@ import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskApproveR
 import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.entry.OaEntryDO;
 import cn.iocoder.yudao.module.bpm.dal.mysql.oa.entry.OaEntryMapper;
 import cn.iocoder.yudao.module.bpm.service.task.BpmTaskService;
+import cn.iocoder.yudao.module.infra.api.file.dto.FileDTO;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import org.apache.poi.openxml4j.opc.PackagingURIHelper;
 import org.flowable.engine.RuntimeService;
 import org.flowable.engine.TaskService;
 import org.flowable.engine.runtime.ProcessInstance;
@@ -60,6 +64,8 @@ public class OaEntryServiceImpl implements OaEntryService {
     public Integer startOaEntry(Long userId, OaEntrySaveReqVO createReqVO) {
         //判断是否已经发起流程
         Boolean auditPass = createReqVO.getAuditPass();
+        //创建单据uuid
+        String uuid = IdUtil.fastSimpleUUID();
         // 插入
         OaEntryDO oaEntry = BeanUtils.toBean(createReqVO, OaEntryDO.class);
         oaEntryMapper.insert(oaEntry);
@@ -78,12 +84,15 @@ public class OaEntryServiceImpl implements OaEntryService {
 
             // 将工作流的编号,单据状态 表单uuid  最后一次审批时间 当前审批人  更新到 OA 入职中
             oaEntryMapper.updateById(new OaEntryDO().setId(oaEntry.getId()).setProcInstId(processInstanceId).setAuditStatus("1")
-                    .setEntryId(IdUtil.fastSimpleUUID()).setFinalAuditDate(new Date()).setCurrentAuditEmployeeId(task.getAssignee()));
+                    .setEntryId(uuid).setFinalAuditDate(new Date()).setCurrentAuditEmployeeId(task.getAssignee()));
         }else {
             // 将单据状态 表单uuid 更新到 OA入职中
-            oaEntryMapper.updateById(new OaEntryDO().setId(oaEntry.getId()).setAuditStatus("0").setEntryId(UUID.randomUUID().toString()));
+            oaEntryMapper.updateById(new OaEntryDO().setId(oaEntry.getId()).setAuditStatus("0").setEntryId(uuid));
         }
 
+        //保存附件uuid
+        LambdaUpdateWrapper<FileDTO> wrapper = new LambdaUpdateWrapper<>();
+        wrapper.in(FileDTO::getId, createReqVO.getFileIdList()).set(FileDTO::getServiceId, uuid);
         // todo 站内信发送
         // loanInfoService.sendMassage(actBaseInfo);
         // 返回
@@ -138,6 +147,11 @@ public class OaEntryServiceImpl implements OaEntryService {
                 }
             }
         }
+
+        //保存附件uuid
+        LambdaUpdateWrapper<FileDTO> wrapper = new LambdaUpdateWrapper<>();
+        wrapper.in(FileDTO::getId, createReqVO.getFileIdList()).set(FileDTO::getServiceId, createReqVO.getEntryId());
+
         // todo 站内信发送
         // loanInfoService.sendMassage(actBaseInfo);
         // 返回
@@ -158,9 +172,7 @@ public class OaEntryServiceImpl implements OaEntryService {
         // 校验存在
         validateOaEntryExists(id);
         // 删除
-//        oaEntryMapper.deleteById(id);
-        //  将单据状态 更新到 OA 入职中
-        oaEntryMapper.updateById((OaEntryDO) new OaEntryDO().setId(id).setDeleted(true));
+        oaEntryMapper.deleteById(id);
     }
 
     private void validateOaEntryExists(Integer id) {

+ 11 - 0
yudao-module-infra/yudao-module-infra-api/src/main/java/cn/iocoder/yudao/module/infra/api/file/FileApi.java

@@ -1,5 +1,7 @@
 package cn.iocoder.yudao.module.infra.api.file;
 
+import cn.iocoder.yudao.module.infra.api.file.dto.FileDTO;
+
 /**
  * 文件 API 接口
  *
@@ -38,4 +40,13 @@ public interface FileApi {
      */
     String createFile(String name, String path, byte[] content);
 
+    /**
+     * 保存文件,并返回文件的访问路径
+     *
+     * @param name    文件名称
+     * @param path    文件路径
+     * @param content 文件内容
+     * @return 文件对象
+     */
+    FileDTO uploadFile(String name, String path, byte[] content);
 }

+ 55 - 0
yudao-module-infra/yudao-module-infra-api/src/main/java/cn/iocoder/yudao/module/infra/api/file/dto/FileDTO.java

@@ -0,0 +1,55 @@
+package cn.iocoder.yudao.module.infra.api.file.dto;
+
+import lombok.*;
+
+/**
+ * 文件表
+ * 每次文件上传,都会记录一条记录到该表中
+ *
+ * @author lc
+ */
+@Data
+public class FileDTO{
+
+    /**
+     * 编号,数据库自增
+     */
+    private Long id;
+    /**
+     * 配置编号
+     *
+     * 关联 FileConfigDO#getId()
+     */
+    private Long configId;
+    /**
+     * 原文件名
+     */
+    private String name;
+    /**
+     * 路径,即文件名
+     */
+    private String path;
+    /**
+     * 访问地址
+     */
+    private String url;
+    /**
+     * 文件的 MIME 类型,例如 "application/octet-stream"
+     */
+    private String type;
+    /**
+     * 文件大小
+     */
+    private Integer size;
+
+    /**
+     * 业务uuid
+     */
+    private String serviceId;
+
+    /**
+     * 文件字典类型(0:通用类型)
+     */
+    private Integer fileDictType;
+
+}

+ 9 - 0
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/api/file/FileApiImpl.java

@@ -1,5 +1,8 @@
 package cn.iocoder.yudao.module.infra.api.file;
 
+import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
+import cn.iocoder.yudao.module.infra.api.file.dto.FileDTO;
+import cn.iocoder.yudao.module.infra.controller.admin.file.vo.file.FileRespVO;
 import cn.iocoder.yudao.module.infra.service.file.FileService;
 import org.springframework.stereotype.Service;
 import org.springframework.validation.annotation.Validated;
@@ -23,4 +26,10 @@ public class FileApiImpl implements FileApi {
         return fileService.createFile(name, path, content);
     }
 
+    @Override
+    public FileDTO uploadFile(String name, String path, byte[] content){
+        FileRespVO fileRespVO = fileService.uploadFile(name, path, content);
+        return BeanUtils.toBean(fileRespVO, FileDTO.class);
+    }
+
 }

+ 10 - 2
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/FileController.java

@@ -39,8 +39,8 @@ public class FileController {
     private FileService fileService;
 
     @PostMapping("/upload")
-    @Operation(summary = "上传文件", description = "模式一:后端上传文件")
-    public CommonResult<String> uploadFile(FileUploadReqVO uploadReqVO) throws Exception {
+    @Operation(summary = "上传文件", description = "模式一:后端上传文件,返回的为文件url")
+    public CommonResult<String> createFile(FileUploadReqVO uploadReqVO) throws Exception {
         MultipartFile file = uploadReqVO.getFile();
         String path = uploadReqVO.getPath();
         return success(fileService.createFile(file.getOriginalFilename(), path, IoUtil.readBytes(file.getInputStream())));
@@ -100,4 +100,12 @@ public class FileController {
         return success(BeanUtils.toBean(pageResult, FileRespVO.class));
     }
 
+    @PostMapping("/uploaData")
+    @Operation(summary = "上传文件", description = "模式一:后端上传文件;返回的为对象")
+    public CommonResult<FileRespVO> uploadFile(FileUploadReqVO uploadReqVO) throws Exception {
+        MultipartFile file = uploadReqVO.getFile();
+        String path = uploadReqVO.getPath();
+        return success(fileService.uploadFile(file.getOriginalFilename(), path, IoUtil.readBytes(file.getInputStream())));
+    }
+
 }

+ 5 - 0
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/vo/file/FileRespVO.java

@@ -12,6 +12,9 @@ public class FileRespVO {
     @Schema(description = "文件编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
     private Long id;
 
+    @Schema(description = "业务uuid", requiredMode = Schema.RequiredMode.REQUIRED, example = "27555")
+    private String serviceId;
+
     @Schema(description = "配置编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "11")
     private Long configId;
 
@@ -33,4 +36,6 @@ public class FileRespVO {
     @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
     private LocalDateTime createTime;
 
+    @Schema(description = "文件字典类型(0:通用类型)", example = "2")
+    private Integer fileDictType;
 }

+ 43 - 0
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/vo/file/FileSaveReqVO.java

@@ -0,0 +1,43 @@
+package cn.iocoder.yudao.module.infra.controller.admin.file.vo.file;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.*;
+import java.util.*;
+import javax.validation.constraints.*;
+
+@Schema(description = "管理后台 - 文件修改 Request VO")
+@Data
+public class FileSaveReqVO {
+
+    @Schema(description = "文件编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "11333")
+    private Long id;
+
+    @Schema(description = "配置编号", example = "11128")
+    private Long configId;
+
+    @Schema(description = "业务uuid", requiredMode = Schema.RequiredMode.REQUIRED, example = "27555")
+    @NotEmpty(message = "业务uuid不能为空")
+    private String serviceId;
+
+    @Schema(description = "文件名", example = "李四")
+    private String name;
+
+    @Schema(description = "文件路径", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotEmpty(message = "文件路径不能为空")
+    private String path;
+
+    @Schema(description = "文件 URL", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn")
+    @NotEmpty(message = "文件 URL不能为空")
+    private String url;
+
+    @Schema(description = "文件类型", example = "2")
+    private String type;
+
+    @Schema(description = "文件大小", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotNull(message = "文件大小不能为空")
+    private Integer size;
+
+    @Schema(description = "文件字典类型(0:通用类型)", example = "2")
+    private Integer fileDictType;
+
+}

+ 10 - 0
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/dataobject/file/FileDO.java

@@ -52,4 +52,14 @@ public class FileDO extends BaseDO {
      */
     private Integer size;
 
+    /**
+     * 业务uuid
+     */
+    private String serviceId;
+
+    /**
+     * 文件字典类型(0:通用类型)
+     */
+    private Integer fileDictType;
+
 }

+ 17 - 3
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/file/FileService.java

@@ -1,9 +1,7 @@
 package cn.iocoder.yudao.module.infra.service.file;
 
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
-import cn.iocoder.yudao.module.infra.controller.admin.file.vo.file.FileCreateReqVO;
-import cn.iocoder.yudao.module.infra.controller.admin.file.vo.file.FilePageReqVO;
-import cn.iocoder.yudao.module.infra.controller.admin.file.vo.file.FilePresignedUrlRespVO;
+import cn.iocoder.yudao.module.infra.controller.admin.file.vo.file.*;
 import cn.iocoder.yudao.module.infra.dal.dataobject.file.FileDO;
 
 /**
@@ -31,6 +29,15 @@ public interface FileService {
      */
     String createFile(String name, String path, byte[] content);
 
+    /**
+     * 保存文件,并返回文件的访问路径
+     *
+     * @param name    文件名称
+     * @param path    文件路径
+     * @param content 文件内容
+     * @return 文件对象
+     */
+    FileRespVO uploadFile(String name, String path, byte[] content);
     /**
      * 创建文件
      *
@@ -39,6 +46,13 @@ public interface FileService {
      */
     Long createFile(FileCreateReqVO createReqVO);
 
+    /**
+     * 更新文件
+     *
+     * @param updateReqVO 更新信息
+     */
+    void updateFile(FileSaveReqVO updateReqVO);
+
     /**
      * 删除文件
      *

+ 41 - 3
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/file/FileServiceImpl.java

@@ -5,12 +5,10 @@ import cn.hutool.core.util.StrUtil;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.common.util.io.FileUtils;
 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
+import cn.iocoder.yudao.module.infra.controller.admin.file.vo.file.*;
 import cn.iocoder.yudao.module.infra.framework.file.core.client.FileClient;
 import cn.iocoder.yudao.module.infra.framework.file.core.client.s3.FilePresignedUrlRespDTO;
 import cn.iocoder.yudao.module.infra.framework.file.core.utils.FileTypeUtils;
-import cn.iocoder.yudao.module.infra.controller.admin.file.vo.file.FileCreateReqVO;
-import cn.iocoder.yudao.module.infra.controller.admin.file.vo.file.FilePageReqVO;
-import cn.iocoder.yudao.module.infra.controller.admin.file.vo.file.FilePresignedUrlRespVO;
 import cn.iocoder.yudao.module.infra.dal.dataobject.file.FileDO;
 import cn.iocoder.yudao.module.infra.dal.mysql.file.FileMapper;
 import lombok.SneakyThrows;
@@ -77,6 +75,46 @@ public class FileServiceImpl implements FileService {
         return file.getId();
     }
 
+    @Override
+    @SneakyThrows
+    public FileRespVO uploadFile(String name, String path, byte[] content) {
+        // 计算默认的 path 名
+        String type = FileTypeUtils.getMineType(content, name);
+        if (StrUtil.isEmpty(path)) {
+            path = FileUtils.generatePath(content, name);
+        }
+        // 如果 name 为空,则使用 path 填充
+        if (StrUtil.isEmpty(name)) {
+            name = path;
+        }
+
+        // 上传到文件存储器
+        FileClient client = fileConfigService.getMasterFileClient();
+        Assert.notNull(client, "客户端(master) 不能为空");
+        String url = client.upload(content, path, type);
+
+        // 保存到数据库
+        FileDO file = new FileDO();
+        file.setConfigId(client.getId());
+        file.setName(name);
+        file.setPath(path);
+        file.setUrl(url);
+        file.setType(type);
+        file.setSize(content.length);
+        fileMapper.insert(file);
+        FileRespVO fileRespVO = BeanUtils.toBean(file, FileRespVO.class);
+        return fileRespVO;
+    }
+
+    @Override
+    public void updateFile(FileSaveReqVO updateReqVO) {
+        // 校验存在
+        validateFileExists(updateReqVO.getId());
+        // 更新
+        FileDO updateObj = BeanUtils.toBean(updateReqVO, FileDO.class);
+        fileMapper.updateById(updateObj);
+    }
+
     @Override
     public void deleteFile(Long id) throws Exception {
         // 校验存在