---
source: "https://weapp.eteams.cn/build/techdoc/wdoc/index.html#/public/doc/cd16e1dc-75be-4848-88ae-092fe1d0f8ee"
publicId: "cd16e1dc-75be-4848-88ae-092fe1d0f8ee"
---

# 文件服务SDK能力

# 1、应用场景

以jar的形式依赖在业务模块中，提供封装好文件处理能力 api，在文件上传，下载等功能方面性能较好。

** 使用前：**

** 引入SDK依赖**

```java
 <dependency>
   <groupId>com.weaver</groupId>
   <artifactId>weaver-file-upload-download</artifactId>
</dependency>
```

**注意事项：**  
**调用方模块调用文件服务SDK进行上传下载时不要使用事务逻辑包裹上传下载的方法**，因为上传下载方法内存在数据库查询逻辑如果调用方事务在上传逻辑后不提交则会影响到后续下载功能。

# 2、上传功能&替换附件功能

 说明：

 1、替换附件还是属于上传

 2、区别是，替换附件是**基于某个附件id进行替换操作，会生成文件版本，****附件id不变**

## ** 2.1、 没有统一返回结果类包装的接口**

 **引入api**

```java
@Autowired
private FileUploadService fileUploadService;
```

** 具体的API：**

```java
/**
 * 通过文件字节流上传
 * @param file 文件字节流，注意：文件很大的情况下，会严重消耗内存，严重会导致 oom 风险，大文件上传不推荐使用，建议上传不超过5M 的文件使用
 * @param employeeId 用户id
 * @param contentType 文件类型，参考下面的参数说明
 * @param remoteUploadParam 文件上传参数，参考下面的参数说明
 * @return FileObj 附件对象
 */
FileObj uploadLocalFile(byte[] file, Long employeeId, String contentType, RemoteUploadParam remoteUploadParam);

/**
 * 通过文件对象File 上传
 * @param file 文件对象，注意：文件对象会占用磁盘物理空间，上传完后，不会自动删除此文件对象，请自行删除，避免文件积累导致磁盘空间不足。同时
请注意，不正确的删除，也会导致文件句柄不释放，导致文件句柄被打满，或者磁盘物理空间不释放导致空间不足。
 * @param employeeId 用户id
 * @param contentType 文件类型，参考下面的参数说明
 * @param remoteUploadParam 文件上传参数，参考下面的参数说明
 * @return FileObj 附件对象
 */
FileObj uploadLocalFile(File file, Long employeeId, String contentType, RemoteUploadParam remoteUploadParam);

/**
 * 通过文件流上传
 * @param inputStream 文件流
 * @param employeeId 用户id
 * @param contentType 文件类型
 * @param remoteUploadParam 文件上传参数
 * @return FileObj
 */
FileObj uploadLocalFile(InputStream inputStream, Long employeeId, String contentType, RemoteUploadParam remoteUploadParam);

/**
 * 通过下载链接上传
 * @param loadUrl 下载链接，请注意，需要保证下载链接，能在所依赖服务的服务器上能正常访问。
 * @param employeeId 用户id
 * @param contentType 文件类型
 * @param remoteUploadParam 文件上传参数
 * @return FileObj
 */
FileObj uploadLocalFile(String loadUrl, Long employeeId, String contentType, RemoteUploadParam remoteUploadParam);

/**
 * 将 test 文本进行转换设定的文件类型并上传 rpc 接口
 * @param text 文本字符串码
 * @param convertType 转换类型，目前仅支持转 .doc
 * @param employeeId 用户id
 * @param contentType 文件类型
 * @param remoteUploadParam 文件上传参数
 * @return FileObj
 */
FileObj convertFileUploadWithText(String text, String convertType,Long employeeId, String contentType, RemoteUploadParam remoteUploadParam);
/**
 * 通过 base64 编码上传
 * @param base64Url base64 码，如果base64编码过大，也会导致内存异常，只适合上传小文件
 * @param employeeId 用户id
 * @param contentType 文件类型
 * @param remoteUploadParam 文件上传参数
 * @return FileObj
 */
FileObj uploadLocalFileWithBase64(String base64Url, Long employeeId, String contentType, RemoteUploadParam remoteUploadParam);

/**
 * 通过文件对象File 替换附件
 * @param file 文件对象，注意：文件对象会占用磁盘物理空间，上传完后，不会自动删除此文件对象，请自行删除，避免文件积累导致磁盘空间不足。同时
请注意，不正确的删除，也会导致文件句柄不释放，导致文件句柄被打满，或者磁盘物理空间不释放导致空间不足。
 * @param employeeId 用户id
 * @param contentType 文件类型
 * @param remoteReUploadParam 替换文件上传参数
 * @return FileObj
 */
FileObj reUploadLocalFile(File file, Long employeeId, String contentType, RemoteReUploadParam remoteReUploadParam);

/**
 * 通过文件流替换附件
 * @param inputStream 文件流
 * @param employeeId 用户id
 * @param contentType 文件类型
 * @param remoteReUploadParam 文件上传参数
 * @return FileObj
 */
FileObj reUploadLocalFile(InputStream inputStream, Long employeeId, String contentType, RemoteReUploadParam remoteReUploadParam);

/**
 * 通过下载链接替换附件
 * @param loadUrl 下载链接，请注意，需要保证下载链接，能在所依赖服务的服务器上能正常访问。
 * @param employeeId 用户id
 * @param contentType 文件类型
 * @param remoteReUploadParam 文件上传参数
 * @return FileObj
 */
FileObj reUploadLocalFile(String loadUrl, Long employeeId, String contentType, RemoteReUploadParam remoteReUploadParam);
```

## ** ****2.2、用统一返回结果类包装的接口（推荐）**

** **** 引入 api**

```java
@Autowired
private WeaverFileUploadService weaverFileUploadService;
```

```java
/**
 * 上传接口，支持各类型上传，支持批量
 * @return WeaApiResult<List<UploadBatchDto>>
 */
WeaApiResult<List<UploadBatchDto>> upload(List<UploadParam> uploadParams);

/** (具体说明，参考第四章 文件服务临时文件能力)
 * 临时文件上传
 * @param uploadParams 临时文件上传参数 
 * @return WeaApiResult<List<UploadBatchDto>>
 */
WeaApiResult<List<UploadBatchDto>> uploadTempFile(List<UploadParam> uploadParams);

   /**
     * 根据字节替换附件
     * @param file 文件字节流
     * @param employeeId 用户id
     * @param contentType 文件类型
     * @param remoteReUploadParam 文件上传参数
     * @return FileObj
     */
    WeaApiResult<FileObj> reUpload(byte[] file, Long employeeId, String contentType, RemoteReUploadParam remoteReUploadParam);

    /**
     * 根据下载地址替换附件
     * @param loadUrl 下载地址
     * @param employeeId 用户id
     * @param contentType 文件类型
     * @param remoteReUploadParam 文件上传参数
     * @return FileObj
     */
    WeaApiResult<FileObj> reUpload(String loadUrl, Long employeeId, String contentType, RemoteReUploadParam remoteReUploadParam);
```

## **2.3、请求参数说明**

** 上传主要参数：**

| **参数名** | **必选** | **类型** | **说明** |
| --- | --- | --- | --- |
| employeeId | 是 | Long | E10 系统里面有效的人员id |
| contentType | 否 | string | 附件上传类型 可参考此链接 [https://blog.csdn.net/qq\_35957643/article/details/119203983](https://blog.csdn.net/qq_35957643/article/details/119203983) |
| RemoteUploadParam | 是 | Object | 上传需要的其他参数 |
| RemoteReUploadParam | 是 | Object | 替换附件需要的其他参数 |
| FtpFileParam | 是 | Object | ftp 获取附件的参数 |
| uploadParams | 是 | Object | 批量上传主要参数 |

** ****UploadParam 参数**

| **参数名** | **必选** | **类型** | **说明** |
| --- | --- | --- | --- |
| uploadType | 是 | String | 指定上传类型 使用 UploadTypeConstant 进行上传类型的指定，必传 |
| keyId | 否 | Long | 指定上传的唯一标识，在返回参数中原样返回此参数，不是必传 |
| keyStrId | 否 | String | 指定上传的唯一标识，在返回参数中原样返回此参数，不是必传 |
| employeeId | 否 | Long | 上传人员id，进行免登录的话，不是必传，但是 employeeId 和 tenantKey 必须传一个 |
| contentType | 否 | String | 文件上传类型，不是必传，[https://blog.csdn.net/qq\_35957643/article/details/119203983](https://blog.csdn.net/qq_35957643/article/details/119203983) |
| remoteUploadParam | 是 | RemoteUploadParam | 上传参数集合，参考下面的说明 |
| loadUrl | 否 | String | 下载链接参数，UploadTypeConstant.loadUrl 上传类型的必传参数，下载链接，请注意，需要保证下载链接，能在所依赖服务的服务器上能正常访问 |
| ftpFileParam | 否 | FtpFileParam | ftp 下载参数，UploadTypeConstant.ftp 上传类型的必传参数 |
| base64Url | 否 | String | base64 上传方法，UploadTypeConstant.base64Url 上传类型的必传参数， base64 码，如果base64编码过大，也会导致内存异常，只适合上传小文件 |
| byteFile | 否 | byte\[\] | 字节上传，UploadTypeConstant.byteFile 上传类型的必传参数，文件字节流，注意：文件很大的情况下，会严重消耗内存，严重会导致 oom 风险，大文件上传不推荐使用，建议上传不超过5M 的文件使用 |
| file | 否 | File | 本地文件类型，UploadTypeConstant.file 上传类型的必传参数，文件对象，注意：文件对象会占用磁盘物理空间，上传完后，不会自动删除此文件对象，请自行删除，避免文件积累导致磁盘空间不足。同时 请注意，不正确的删除，也会导致文件句柄不释放，导致文件句柄被打满，或者磁盘物理空间不释放导致空间不足。 |
| inputStream | 否 | InputStream | 文件流上传，UploadTypeConstant.inputStream 上传类型的必传参数 |
| text | 否 | String | 将 test 文本进行转换设定的文件类型并上传，UploadTypeConstant.convertText 上传类型的必传参数，按照下面文档说明传参 |
| convertType | 否 | String | UploadTypeConstant.convertText 上传类型的必传参数,按照下面文档说明传参 |
| fileId | 否 | Long | 源文件id，UploadTypeConstant.convertById 上传类型的比传参数，会复制此文件id对应的文件 |
| StorageLinkParam | 否 | String | UploadTypeConstant.storeLink此类型为,需要传此参数，此上传类型将直接绑定存储的路径生成完整的文件数据。例如，直接将第三方存储中 /test/11111 文件和E10系统绑定并生成FIleobj 对象，但不需要直接上传实体文件。<br>前提：需要提前维护好存储规则，并获取到存储规则id，若不传存储id，则会默认走系统设置的存储<br>此对象详细说明请参考下面的说明 |

** ****RemoteUploadParam 参数说明**

| **参数名** | **必选** | **类型** | **说明** |
| --- | --- | --- | --- |
| name | 是 | String | 文件名（包含文件后缀），如 test.docx |
| lastModified | 否 | String | 文件最后修改时间，毫秒时间戳,推荐使用：System.currentTimeMillis(); 获取 |
| module | 是 | string | 模块名，需要和 EntityType 中保持一致 ([常见module列表](https://i18n-test-1301503941.cos.ap-shanghai.myqcloud.com/visitstatic/test/document/%E6%A8%A1%E5%9D%97%E6%A0%87%E8%AF%86.docx)）请一定要首先确认好文件上传的模块，错误的模块将会导致附件后续的鉴权异常。<br>如：文件是在邮件内上传，则联系邮件模块负责人确认模块标识<br>若需要新增模块，请确认 weaver-common-simple-bean.jar  的维护人。并在com.weaver.teams.domain.EntityType 中新增模块，新增后，请对接好模块的[权限](https://weapp.eteams.cn/build/techdoc/wdoc/index.html#/public/doc/621ea340-1914-4184-b05a-b09fe49ea9ed) |
| size | 否 | Long | 文件大小 |
| refId | 否 | Long | 关联的业务id，如，在邮件中上传附件，refId 可以传邮件id，后续可以通过邮件id查询到关联的附件 |
| commentFlag | 否 | Boolean | 标识是不是评论组件，用于获取契约锁的按钮信息，默认false |
| MD5 | 否 | String | 文件的MD5值，可用于秒传 |
| folderId | 否 | Long | 目录id |
| folderType | 否 | String | 目录类型 |
| mainlineId | 否 | Long | 项目id |
| moduleFolderId | 否 | Long | 项目文件夹id |
| source | 否 | String | 操作来源（用于标识，文件是从哪里操作上传，便于特殊业务逻辑处理）目前有4个取值， 1. comment ：来源于评论的附件；2. form 来源表单自定义附件字段；3.relation 来源关联附件字段 4.richText 来源富文本 5. fileAuth 主要用于记录鉴权参数 |
| createDoc | 否 | boolean | 是否创建文档，默认true，创建文档 |
| tempFileFlag | 否 | boolean | 是否是临时文件存储 |
| tempFileTime | 否 | boolean | 临时文件的保存时间 时间单位 小时 |
| commonText | 否 | String | 附件自定义关联信息 |
| createDocContent | 否 | boolean | 默认false ，上传的文件是否生成为正文文档 |
| tenantKey | 否 | String | 租户标识，进行免登录的话，不是必传，但是 employeeId 和 tenantKey 必须传一个 |

**FtpFileParam 参数说明**

| **参数名** | **必选** | **类型** | **说明** |
| --- | --- | --- | --- |
| ftpIp | 是 | String | ip地址 |
| ftpPort | 否 | int | 端口，不填会用默认端口 |
| ftpUserName | 否 | string | 用户名 |
| ftpPassword | 否 | string | 密码 |
| localPath | 是 | string | 文件路径（目录地址） |
| fileName | 是 | String | 文件名 |
| charset | 否 | object | 字符编码，不填取系统默认字符 |
| ftpMode | 否 | String | ftp 模式，值为：ftp,和 Sftp，不填默认走 sftp 模式 |
| ftpLinkMode | 否 | FtpMode | 链接模式，：<br>Active：  主动模式<br>Passive：被动模式 |
| ftpPathDtoList | 是 | List\<FtpPathDto\> ftpPathDtoList | 要下载的文件路径信息<br>FtpPathDto：<br>ftpPath：文件路径，如/opt/doc/2025<br>fileName：文件名，test.doc<br>ftpPathKey：自定义指定此文件的唯一标识，用于后续使用，自己定义。<br>json 示例：<br>```json<br>"ftpPathDtoList":[ {<br>"fileName" : "dsdssds.doc",<br>"ftpPath" : "/ftp/doc1",<br>"ftpPathKey" : "ftp"<br>},<br>{<br>"fileName" :"dsdsseweds.doc",<br>"ftpPath" : "/ftp/doc2",<br>"ftpPathKey" : "ftp"<br>} ]<br>``` |

**  ****remoteReUploadParam 参数说明（同 RemoteUploadParam 参数，只列出不一样的参数）**

| **必选** | **类型** | **说明** |  |
| --- | --- | --- | --- |
| oldFileId | 是 | Long | 文件id(被替换的文件id) |

** StorageLinkParam 参数说明：**

| **必选** | **类型** | **说明** |  |
| --- | --- | --- | --- |
| ruleVersionId | 否 | Long | 存储规则id<br>在后台管理中心-文件设置-存储设置-存储实例中，新建好第三方的存储实例，并在存储规则中进行绑定，然后获取存储规则id |
| filePath | 是 | String | 文件存储路径，如 在第三方中完整的存储路径为：/oabucket/tj02iu5kla/2024/01/09/09c110e5-7d8e-41f5-b989-7b3c484e4d42<br>则 filePath 的值为 /oabucket/tj02iu5kla/2024/01/09 |
| fileUrl | 是 | String | 文件存储标识，如 在第三方中完整的存储路径为：/oabucket/tj02iu5kla/2024/01/09/09c110e5-7d8e-41f5-b989-7b3c484e4d42<br>则 fileUrl 的值为 ：09c110e5-7d8e-41f5-b989-7b3c484e4d42<br>**注意：fileUrl 需要保证其唯一性** |

## 2.4、返回参数说明：

**1、**[**FileObj 对象说明**](https://weapp.eteams.cn/build/techdoc/wdoc/index.html#/public/doc/9dadc9db-4743-4253-be7d-fdd38e5b1597)

**2、UploadBatchDto 返回参数说明**

| **必选** | **类型** | **说明** |
| --- | --- | --- |
| url | String | 只有通过文件下载链接上传文件时，会原样返回此下载链接 |
| keyId | Long | 指定上传的唯一标识，在返回参数中原样返回此参数，不是必传 |
| keyStrId | String | 指定上传的唯一标识，在返回参数中原样返回此参数，不是必传 |
| fileObj | FileObj | 参考fileobj文件对象说明 |
| ftpPath | String | ftp文件路径 ，只有通过ftp类型上传的情况会返回 |

# 3、下载功能

** ****引入api**

```java
@Autowired
private FileDownloadService fileDownloadService;
```

```java
  /**
     * 通过附件id 获取文件信息及文件字节码
     * @param fileId 附件id
     * @return FileData，参考下面的说明
     */
    FileData downloadFile(Long fileId);

    /**
 * 通过 url 进行附件下载
 * @param url 关联附件得 url
 * @param tenantKey 租户 key
 * @param fileName 文件名
 * @return 下载链接
 */
String getDownloadUrl(String url,String tenantKey,String fileName);

    /**
     * 针对密标加解密提供的非加密方法
     * @param url
     * @param tenantKey
     * @param fileName
     * @return 下载链接
     */
    String getDownloadUrlNoThirdEncrypt(String url,String tenantKey,String fileName);

    /**
 * 下载静态文件
 * @return FileData 封装的下载对象
    *eg.
    * 下载ecode模块的静态资源入参示例：
    * filePath: /ecodestatic/test/json
    * flieName: global.json
    * module: ecode

    * 下载公共组件的静态资源入参示例：
    * filePath: /icons/svgs
    * fileName: iconMap.js
    * module: iconfont

    * 下载国际化的静态资源入参示例：
    * filePath: /en_US
    * fileName: integration.json
    * module: i18n
 */
public FileData downloadStatic(String filePath, String fileName, String module);

    /**
     * 根据文件key获取临时文件流
     * @param url 文件key
     * @return InputStream
     */
    InputStream getTempFileStream(String url);

    /**
     * 获取临时的文件下载链接，或者文件流
     * @param fileOpParam 请求参数
     * @return FileOpInfoDto
     */
    FileOpInfoDto getTempFileUrl(FileOpParam fileOpParam);
```

## **3.1、FileData 功能说明**

（1）使用 ： com.weaver.eteams.file.client.file.FileData#getData 获取文件字节（byte）

**注意：当大文件时，有oom风险，适用于小文件**

（2）使用：com.weaver.eteams.file.client.file.FileData#getInputStream 获取文件流

**注意：使用此方法，必须严格手动关闭文件流，关闭示例如下：**

```java
        
        InputStream inputStream = null;
        try{
            inputStream = fileData.getInputStream();
            .....
        }finally {
            IoUtil.close(inputStream);
            fileData.closeStream();
        }
```

（3）使用：com.weaver.eteams.file.client.file.FileData#getFileObj  获取文件信息，[Fileobj 对象字段说明](https://weapp.eteams.cn/build/techdoc/wdoc/index.html#/public/doc/9dadc9db-4743-4253-be7d-fdd38e5b1597)

- 

# 4、复制功能

**引入api**

```java
//注入依赖
@Autowired
private WeaverFileUploadService weaverFileUploadService;
```

```java

    /**
     * 批量复制接口
     * 1、支持跨租户复制
     * 2、支持多线程复制
     * @param copyFileSdkParamList 复制文件参数列表
     * @return CopyFileSdkDto
     */
    WeaApiResult<CopyFileSdkDto> copyFileBatch(List<CopyFileSdkParam> copyFileSdkParamList);
```

## 4.1 请求参数说明：

**CopyFileSdkParam 参数说明**

| 参数名 | 类型 | 是否必传 | 说明 |
| --- | --- | --- | --- |
| copyKey | String | 否 | 用于标记数据的唯一标识，和生成的附件对象一起返回 |
| fileId | Long | 是 | 需要复制的文件id |
| copyFileParam | CopyFileParam | 否 | 复制的参数 |

** copyFileParam 参数说明**

| 参数名 | 类型 | 是否必传 | 说明 |
| --- | --- | --- | --- |
| employeeId | Long | 否 | 指定复制的人员id，不传和原附件保持一致 |
| module | String | 否 | 指定目标模块，不传则和原附件保持一致 |
| refId | Long | 否 | 指定关联的业务id，不传，新的附件不会关联任何业务 |
| createDoc | Boolean | 否 | 是否生成文档，默认不生成， |
| folderId | Long | 否 | 目录id，生成文档时可指定生成到指定的目录下 |
| tenantKey | String | 否 | 租户标识，当不传 employeeId 时，会以这个为主 |

## 4.2、返回参数说明：

**CopyFileSdkDto 参数说明**

| 参数 | 类型 | 说明 |
| --- | --- | --- |
| copyFileSdkResultList | List\<CopyFileSdkResult\> | 复制成功的结果集 |
| errorMap | Map\<Long, String\> | 复制异常的文件结果集合 |

** CopyFileSdkResult 参数说明**

| 参数 | 类型 | 说明 |
| --- | --- | --- |
| copyKey | String | 用于标记数据的唯一标识，和生成的附件对象一起返回 |
| oldFileId | Long | 旧文件id |
| newFileObj | FileObj | 新的文件对象 |
