---
source: "https://weapp.eteams.cn/build/techdoc/wdoc/index.html#/public/doc/51b80439-95bf-44bd-ae6e-bd4256d748e8"
publicId: "51b80439-95bf-44bd-ae6e-bd4256d748e8"
---

# 文件服务后端二开埋点

ecode服务基于埋点实现二开说明文档：[ecode基于埋点二开](https://weapp.eteams.cn/build/techdoc/wdoc/index.html#/public/doc/e3ea1960-6285-41bb-8ba6-b3bea1666549)

### 1. 控制文件预览/下载是否有水印

**最低基线支持：2506.01，**

> **code**: FILE\_WATERMARK\_HOOK\_001

**功能说明：**

支持二开控制文件预览下载是否加水印。整体思路就是开启标准的水印让文件都有水印，然后哪些文件不需要水印在口子里面根据自身需求判断返回false即可

**参数说明：**

| 参数名 | 类型 | 描述 |
| --- | --- | --- |
| fileObj | FileObj | 文件对象 |
| operationType | OperationTypeEnum | 当前文件操作业务（PREVIEW/DOWNLOAD） |
| waterMarkId | Long | 标准要加水印的水印id |
| employee | SimpleEmployee | 当前用户对象 |

**响应说明：**

返回水印ID，返回值对标准业务有影响，如果不加水印返回null

**示例代码：**

```java
package com.weaver.teams.file.online.hook;

import cn.hutool.core.date.DateUtil;
import com.weaver.eteams.file.client.file.FileObj;
import com.weaver.file.watermark.constant.OperationTypeEnum;
import com.weaver.loom.context.annotation.WeaHookReg;
import com.weaver.loom.context.domain.AppInfo;
import com.weaver.loom.context.domain.WeaHookRequest;
import com.weaver.loom.context.domain.WeaHookResponse;
import com.weaver.loom.context.register.RegHookEvent;
import com.weaver.teams.domain.user.SimpleEmployee;

import java.util.Map;

/**
 * @Description: 水印二开拦截demo
 * @Author: 张坤鹏
 * @Date: 2024/6/27 19:40
 */
@WeaHookReg(code = "FILE_WATERMARK_HOOK_001")
public class FileWatermarkHookDemo extends RegHookEvent {

    @Override
    public WeaHookResponse handle(WeaHookRequest request, WeaHookResponse response, AppInfo appInfo) throws Exception {
        //获取标准传过来的参数
        Map<String, Object> params = request.getParams();
        //前面同一埋点多个二开，前面链路节点二开代码执行的结果
        Object result = response.getResult();
        if (result != null) {
            // 如果这个方法拦截二开过 获取上一个二开的结果 如果需要处理 也可以继续再处理
            response.setResult(result);
        } else {
            // 文件对象
            FileObj fileObj = (FileObj) params.get("fileObj");
            // 当前文件操作业务 PREVIEW("预览"),DOWNLOAD("下载")
            OperationTypeEnum operationType = (OperationTypeEnum) params.get("operationType");
            // 当前人员信息
            SimpleEmployee employee = (SimpleEmployee) params.get("employee");
            // 标准要加水印的水印id
            Long waterMarkId = (Long) params.get("waterMarkId");
            // 二开逻辑判断 返回新的水印id  如果不需要加水印设置waterMarkId = -1
            response.setResult(waterMarkId);
        }
        //返回结果
        return response;
    }

    @Override
    public void rollBack(WeaHookRequest request, WeaHookResponse response, AppInfo appInfo) throws Exception {
        //自定义二开代码异常回滚逻辑
        log.info("执行事件回滚机制 => {}, {}", DateUtil.now(), appInfo.getAppName());
    }

}
```

### 2. 文件批量下载二开拦截

**最低基线支持：2501.01**

> **code**: FILE\_PACK\_DOWNLOAD\_001

**功能说明：**

支持文件批量下载二开拦截，例如下载文件转pdf

**参数说明：**

| 参数名 | 类型 | 描述 |
| --- | --- | --- |
| fileObj | FileObj | 文件对象 |
| employee | SimpleEmployee | 当前用户对象 |

**响应说明：**

返回处理后的fileObj，返回值对标准业务有影响，如果不处理返回null

**示例代码：**

```java
package com.weaver.teams.file.e10.service.hook;

import cn.hutool.core.date.DateUtil;
import com.weaver.eteams.file.client.file.FileObj;
import com.weaver.loom.context.annotation.WeaHookReg;
import com.weaver.loom.context.domain.AppInfo;
import com.weaver.loom.context.domain.WeaHookRequest;
import com.weaver.loom.context.domain.WeaHookResponse;
import com.weaver.loom.context.register.RegHookEvent;
import com.weaver.teams.domain.user.SimpleEmployee;

import java.util.Map;

/**
 * @Description: 批量下载二开拦截demo
 * @Author: 张坤鹏
 * @Date: 2025/1/2 10:37
 */
@WeaHookReg(code = "FILE_PACK_DOWNLOAD_001")
public class PackDownloadHookDemo extends RegHookEvent {

    @Override
    public WeaHookResponse handle(WeaHookRequest request, WeaHookResponse response, AppInfo appInfo) {
        //获取标准传过来的参数
        Map<String, Object> params = request.getParams();
        //前面同一埋点多个二开，前面链路节点二开代码执行的结果
        Object result = response.getResult();
        if (result != null) {
            // 如果这个方法拦截二开过 获取上一个二开的结果 如果需要处理 也可以继续再处理
            response.setResult(result);
        } else {
            // 文件对象
            FileObj fileObj = (FileObj) params.get("fileObj");
            // 当前人员信息
            SimpleEmployee employee = (SimpleEmployee) params.get("employee");
            // 二开逻辑 例如文件转pdf等 将处理后的文件上传到系统中（tip:处理后的文件若仅是当前下载使用 上传文件时候设置为临时文件） 返回fileObj对象
            response.setResult(fileObj);
        }
        //返回结果
        return response;
    }

    @Override
    public void rollBack(WeaHookRequest request, WeaHookResponse response, AppInfo appInfo) throws Exception {
        //自定义二开代码异常回滚逻辑
        log.info("执行事件回滚机制 => {}, {}", DateUtil.now(), appInfo.getAppName());
    }

}
```

### 3. 文件预览编辑插件控制

**最低基线支持：2508.01**

> **code**: FILE\_PREVIEW\_EDIT\_PLUG\_001

**功能说明：**

支持控制文件预览编辑是否使用标准允许使用的插件。整体思路就是预览编辑插件都开启，然后哪些文件不允许使用该插件在口子里面根据自身需求判断返回false即可

**参数说明：**

| 参数名 | 类型 | 描述 |
| --- | --- | --- |
| plugId | Long | 插件id |
| clientIp | String | 用户客户端ip |
| fileObj | FileObj | 文件对象 |
| employee | SimpleEmployee | 当前用户对象 |

**响应说明：**

返回true或false，返回false页面加载将不使用该插件。返回值对标准业务有影响，如果不处理返回null

**示例代码：**

```java
package com.weaver.teams.file.online.hook;

import cn.hutool.core.date.DateUtil;
import com.weaver.eteams.file.client.file.FileObj;
import com.weaver.loom.context.annotation.WeaHookReg;
import com.weaver.loom.context.domain.AppInfo;
import com.weaver.loom.context.domain.WeaHookRequest;
import com.weaver.loom.context.domain.WeaHookResponse;
import com.weaver.loom.context.register.RegHookEvent;
import com.weaver.teams.domain.user.SimpleEmployee;

import java.util.Map;

/**
 * @Description: 控制预览编辑是否使用标准允许使用的插件二开demo
 * @Author: 张坤鹏
 * @Date: 2025/7/24 19:15
 */
@WeaHookReg(code = "FILE_PREVIEW_EDIT_PLUG_001")
public class PreviewEditPlugHookDemo extends RegHookEvent {

    @Override
    public WeaHookResponse handle(WeaHookRequest request, WeaHookResponse response, AppInfo appInfo) throws Exception {
        //获取标准传过来的参数
        Map<String, Object> params = request.getParams();
        //前面同一埋点多个二开，前面链路节点二开代码执行的结果
        Object result = response.getResult();
        if (result != null) {
            // 如果这个方法拦截二开过 获取上一个二开的结果 如果需要处理 也可以继续再处理
            response.setResult(result);
        } else {
            // 文件对象
            FileObj fileObj = (FileObj) params.get("fileObj");
            // 当前人员信息
            SimpleEmployee employee = (SimpleEmployee) params.get("employee");
            // 插件id
            Long plugId = (Long) params.get("employee");
            // 客户端id
            String clientIp = (String) params.get("clientIp");
            // 二开逻辑，例如根据客户端ip，附件id，插件id判断 是否允许使用该插件
            response.setResult(false);
        }
        //返回结果
        return response;
    }

    @Override
    public void rollBack(WeaHookRequest request, WeaHookResponse response, AppInfo appInfo) throws Exception {
        //自定义二开代码异常回滚逻辑
        log.info("执行事件回滚机制 => {}, {}", DateUtil.now(), appInfo.getAppName());
    }

}
```

### 4. 文件预览是否允许复制

**最低基线支持：2511.01**

> **code**: FILE\_PREVIEW\_PERMISSION\_COPY\_001

** 功能说明：**

自定义控制文件预览是否允许复制

**参数说明：**

| 参数名 | 类型 | 描述 |
| --- | --- | --- |
| copyPermission | boolean | 是否允许复制（标准的结果） |
| fileObj | FileObj | 文件对象 |
| employee | SimpleEmployee | 当前用户对象 |

**响应说明：**

返回true或false，返回false文件预览页面内容不可复制。返回值对标准业务有影响，如果不处理返回null

**示例代码：**

```java
package com.weaver.teams.file.online.hook;

import cn.hutool.core.date.DateUtil;
import com.weaver.eteams.file.client.file.FileObj;
import com.weaver.loom.context.annotation.WeaHookReg;
import com.weaver.loom.context.domain.AppInfo;
import com.weaver.loom.context.domain.WeaHookRequest;
import com.weaver.loom.context.domain.WeaHookResponse;
import com.weaver.loom.context.register.RegHookEvent;
import com.weaver.teams.domain.user.SimpleEmployee;

import java.util.Map;

/**
 * @Description: 自定义控制文件预览是否允许复制
 * @Author: 张坤鹏
 * @Date: 2025/10/30 11:54
 */
@WeaHookReg(code = "FILE_PREVIEW_PERMISSION_COPY_001")
public class PreviewCopyHookDemo extends RegHookEvent {

    @Override
    public WeaHookResponse handle(WeaHookRequest request, WeaHookResponse response, AppInfo appInfo) throws Exception {
        //获取标准传过来的参数
        Map<String, Object> params = request.getParams();
        //前面同一埋点多个二开，前面链路节点二开代码执行的结果
        Object result = response.getResult();
        if (result != null) {
            // 如果这个方法拦截二开过 获取上一个二开的结果 如果需要处理 也可以继续再处理
            response.setResult(result);
        } else {
            // 标准的是否允许复制的结果
            boolean copyPermission = (boolean) params.get("copyPermission");
            // 当前预览的文件
            FileObj fileObj = (FileObj) params.get("fileObj");
            // 当前人员信息
            SimpleEmployee employee = (SimpleEmployee) params.get("employee");
            // 二开逻辑，自行控制返回是否允许复制  返回值为Boolean类型。 可返回 true|false|null
            response.setResult(null);
        }
        //返回结果
        return response;
    }

    @Override
    public void rollBack(WeaHookRequest request, WeaHookResponse response, AppInfo appInfo) throws Exception {
        //自定义二开代码异常回滚逻辑
        log.info("执行事件回滚机制 => {}, {}", DateUtil.now(), appInfo.getAppName());
    }

}
```

### 5. 文件预览/编辑是否允许打印

**最低基线支持：2601.01**

> **code**: FILE\_PREVIEW\_EDIT\_PERMISSION\_PRINT\_001

** 功能说明：**

自定义控制文件预览是否允许打印

**参数说明：**

| 参数名 | 类型 | 描述 |
| --- | --- | --- |
| printPermission | boolean | 是否允许打印（标准的结果） |
| fileObj | FileObj | 文件对象 |
| employee | SimpleEmployee | 当前用户对象 |

**响应说明：**

返回true或false，返回false文件不可打印。返回值对标准业务有影响，如果不处理返回null

**示例代码：**

```java
package com.weaver.teams.file.online.hook;

import cn.hutool.core.date.DateUtil;
import com.weaver.eteams.file.client.file.FileObj;
import com.weaver.loom.context.annotation.WeaHookReg;
import com.weaver.loom.context.domain.AppInfo;
import com.weaver.loom.context.domain.WeaHookRequest;
import com.weaver.loom.context.domain.WeaHookResponse;
import com.weaver.loom.context.register.RegHookEvent;
import com.weaver.teams.domain.user.SimpleEmployee;

import java.util.Map;

/**
 * @Description:
 * @Author: 张坤鹏
 * @Date: 2026/1/4 17:44
 */
@WeaHookReg(code = "FILE_PREVIEW_EDIT_PERMISSION_PRINT_001")
public class FilePermissionPrintHookDemo extends RegHookEvent {

    @Override
    public WeaHookResponse handle(WeaHookRequest request, WeaHookResponse response, AppInfo appInfo) throws Exception {
        //获取标准传过来的参数
        Map<String, Object> params = request.getParams();
        //前面同一埋点多个二开，前面链路节点二开代码执行的结果
        Object result = response.getResult();
        if (result != null) {
            // 如果这个方法拦截二开过 获取上一个二开的结果 如果需要处理 也可以继续再处理
            response.setResult(result);
        } else {
            // 标准的是否允许打印的结果
            boolean printPermission = (boolean) params.get("printPermission");
            // 当前预览的文件
            FileObj fileObj = (FileObj) params.get("fileObj");
            // 当前人员信息
            SimpleEmployee employee = (SimpleEmployee) params.get("employee");
            // 二开逻辑，自行控制返回是否允许打印  返回值为Boolean类型。 可返回 true|false|null
            response.setResult(null);
        }
        //返回结果
        return response;
    }

    @Override
    public void rollBack(WeaHookRequest request, WeaHookResponse response, AppInfo appInfo) throws Exception {
        //自定义二开代码异常回滚逻辑
        log.info("执行事件回滚机制 => {}, {}", DateUtil.now(), appInfo.getAppName());
    }

}
```

### 6. wps在线编辑是否允许导出

**最低基线支持：2001.01**

> **code**: FILE\_PREVIEW\_EDIT\_PERMISSION\_EXPORT\_001

** 功能说明：**

自定义控制wps在线编辑页面左上角文件导出按钮是否可用

**参数说明：**

| 参数名 | 类型 | 描述 |
| --- | --- | --- |
| exportPermission | boolean | 是否允许导出（标准的结果） |
| fileObj | FileObj | 文件对象 |
| employee | SimpleEmployee | 当前用户对象 |

**响应说明：**

返回true或false，返回false文件在线编辑页面不可导出。返回值对标准业务有影响，如果不处理返回null

**示例代码：**

```java
package com.weaver.teams.file.online.hook;

import cn.hutool.core.date.DateUtil;
import com.weaver.eteams.file.client.file.FileObj;
import com.weaver.loom.context.annotation.WeaHookReg;
import com.weaver.loom.context.domain.AppInfo;
import com.weaver.loom.context.domain.WeaHookRequest;
import com.weaver.loom.context.domain.WeaHookResponse;
import com.weaver.loom.context.register.RegHookEvent;
import com.weaver.teams.domain.user.SimpleEmployee;

import java.util.Map;

/**
 * @Description:
 * @Author: 张坤鹏
 * @Date: 2026/1/4 17:44
 */
@WeaHookReg(code = "FILE_PREVIEW_EDIT_PERMISSION_EXPORT_001")
public class FilePermissionExportHookDemo extends RegHookEvent {

    @Override
    public WeaHookResponse handle(WeaHookRequest request, WeaHookResponse response, AppInfo appInfo) throws Exception {
        //获取标准传过来的参数
        Map<String, Object> params = request.getParams();
        //前面同一埋点多个二开，前面链路节点二开代码执行的结果
        Object result = response.getResult();
        if (result != null) {
            // 如果这个方法拦截二开过 获取上一个二开的结果 如果需要处理 也可以继续再处理
            response.setResult(result);
        } else {
            // 标准的是否允许导出的结果
            boolean exportPermission = (boolean) params.get("exportPermission");
            // 当前预览的文件
            FileObj fileObj = (FileObj) params.get("fileObj");
            // 当前人员信息
            SimpleEmployee employee = (SimpleEmployee) params.get("employee");
            // 二开逻辑，自行控制返回是否允许导出  返回值为Boolean类型。 可返回 true|false|null
            response.setResult(null);
        }
        //返回结果
        return response;
    }

    @Override
    public void rollBack(WeaHookRequest request, WeaHookResponse response, AppInfo appInfo) throws Exception {
        //自定义二开代码异常回滚逻辑
        log.info("执行事件回滚机制 => {}, {}", DateUtil.now(), appInfo.getAppName());
    }

}
```

### 7. 对接集成第三方预览编辑插件

参考：[https://kdocs.cn/l/ciMvDAGQsXaH](https://kdocs.cn/l/ciMvDAGQsXaH) 第二章

### 8. 上传文件获取完整物理文件处理埋点

**基线支持：2410.01  **

> **code**: FILE\_APP\_STORAGE\_HOOK\_013 ** **

**功能说明：**

（1）上传/分片上传场景中，获取上传的完整的原始文件进行处理

（2）本埋点会将文件存储到共享磁盘的目录下，要求二开服务和其他E10服务必须做共享磁盘挂载，因此只支持本地存储，云存储此埋点不支持

**参数说明：**

| 参数名 | 类型 | 描述 |
| --- | --- | --- |
| filePath | String | 完整文件的本地绝对路径 |
| simpleEmployee | SimpleEmployee | 当前用户对象 |
| secLevel | String | 密级信息 |
| createFileDoc | boolean | 上传文件是否创建文件 |
| filename | String | 文件名 |
| folderId | Long | 目录id |
| module | String | 上传文件的归属模块 |
| refId | Long | 业务id |
| filesize | Long | 文件大小 |
| upload4ModuleParam | Object | 上传参数信息 |

**响应说明：**

| 参数名 | 类型 | 描述 |
| --- | --- | --- |
| interruptMsg | String | 中断上传的提示信息，当传此值时，会中断上传请求并给出此提示 |
| interruptCode | int | 中断上传的code |

**示例代码：**

（1）、去配置文件开启埋点

配置文件： [weaver-file-service.properties](http://weaver-file-service.properties)

配置项：file.secondary.mode.hook

参数：（填入需要使用的埋点，按照逗号隔开，例如：FILE\_APP\_STORAGE\_HOOK\_003,FILE\_APP\_STORAGE\_HOOK\_004）

如何操作请参考【[https://weapp.eteams.cn/build/techdoc/wdoc/index.html#/public/doc/de3d8fe6-74fd-4a91-bbdf-a7d5ae72af75](https://weapp.eteams.cn/build/techdoc/wdoc/index.html#/public/doc/de3d8fe6-74fd-4a91-bbdf-a7d5ae72af75)】

（2）、实现埋点

```java
@WeaHookReg(code = "FILE_APP_STORAGE_HOOK_013")
public class SecondHookDemo extends RegHookEvent {

    @Override
    public WeaHookResponse handle(WeaHookRequest request, WeaHookResponse response, AppInfo appInfo) throws Exception {
        //获取标准传过来的参数
        Map<String, Object> params = request.getParams();
        //前面同一埋点多个二开，前面链路节点二开代码执行的结果
        Object result = response.getResult();
        if (result != null) {
            // 如果这个方法拦截二开过 获取上一个二开的结果 如果需要处理 也可以继续再处理
            response.setResult(result);
        } else {
            // 获取文件路径
            String filePath = (boolean) params.get("filePath");
            File file = new File(filePath);
            //开始进行逻辑
            ...............
            // 封装返回信息
             Map<String,Object> resultMap = Maps.newHashMapWithExpectedSize(1);
            resultMap.put("interruptMsg","不符合当前逻辑，无法预览");
            response.setResult(resultMap);
        }
        //返回结果
        return response;
    }

    @Override
    public void rollBack(WeaHookRequest request, WeaHookResponse response, AppInfo appInfo) throws Exception {
        //自定义二开代码异常回滚逻辑
        log.info("执行事件回滚机制 => {}, {}", DateUtil.now(), appInfo.getAppName());
    }

}
```

### 9. OfficeWeb365集成furl自定义处理

**最低基线支持：2512.01**

> **code**: FILE\_OFFICE\_WEB\_365\_001

** 功能说明：**

OfficeWeb365集成furl对接参数自定义处理

**参数说明：**

| 参数名 | 类型 | 描述 |
| --- | --- | --- |
| furl | String | 文件下载地址 |

**响应说明：**

返回自定义处理后的文件下载地址

**示例代码：**

```java
package com.weaver.teams.file.online.hook;

import cn.hutool.core.date.DateUtil;
import com.weaver.loom.context.annotation.WeaHookReg;
import com.weaver.loom.context.domain.AppInfo;
import com.weaver.loom.context.domain.WeaHookRequest;
import com.weaver.loom.context.domain.WeaHookResponse;
import com.weaver.loom.context.register.RegHookEvent;

import java.util.Map;

/**
 * @Description: 自定义对接OfficeWeb365服务的furl
 * @Author: 张坤鹏
 * @Date: 2025/12/04 9:54
 */
@WeaHookReg(code = "FILE_OFFICE_WEB_365_001")
public class OfficeWeb365HookDemo extends RegHookEvent {

    @Override
    public WeaHookResponse handle(WeaHookRequest request, WeaHookResponse response, AppInfo appInfo) throws Exception {
        //获取标准传过来的参数
        Map<String, Object> params = request.getParams();
        //前面同一埋点多个二开，前面链路节点二开代码执行的结果
        Object result = response.getResult();
        if (result != null) {
            // 如果这个方法拦截二开过 获取上一个二开的结果 如果需要处理 也可以继续再处理
            response.setResult(result);
        } else {
            // 标准的文件下载地址
            boolean furl = (boolean) params.get("furl");
            // 二开逻辑，自行处理下载地址 然后返回
            response.setResult(furl);
        }
        //返回结果
        return response;
    }

    @Override
    public void rollBack(WeaHookRequest request, WeaHookResponse response, AppInfo appInfo) throws Exception {
        //自定义二开代码异常回滚逻辑
        log.info("执行事件回滚机制 => {}, {}", DateUtil.now(), appInfo.getAppName());
    }

}
```

### 10. 文件预览单页操作按钮处理埋点

**基线支持：10.0.2511.01 以及 最新的 260301基线及后续基线**

> **code**: FILE\_APP\_STORAGE\_HOOK\_014

**功能说明：**

（1）系统中安装了第三方预览插件，当预览第三方支持预览的文件时，会出现文件预览页面，此埋点控制页面上的按钮渲染

图片附件未整合：_assets/51b80439-95bf-44bd-ae6e-bd4256d748e8/001-d018181775.png

**参数说明：**

| 参数名 | 类型 | 描述 |
| --- | --- | --- |
| currentEmployeeId | SimpleEmployee | 当前用户对象 |
| downloadInfoAuthDto | DownloadInfoAuthDto | 按钮渲染对象 |
| requestURI | String | 当前请求的 url |

downloadInfoAuthDto 参数说明

| 参数名 | 类型 | 描述 |
| --- | --- | --- |
| canDownload | Boolean | 是否可以下载，true 可以，false 不可以 |
| downloadUrl | String | 下载链接，canDownload 为 true 返回 |
| canEdit | Boolean | 是否能编辑 |
| editUrl | String | 编辑url |
| canReUpload | Boolean | 是否能重新上传 |
| commonParam | Object | 重新上传参数：Map 类型（Key 参数名，value 参数值） |
| canPrint | Boolean | 是否显示打印按钮 |
| canOpenDoc | Boolean | 是否显示打开所属文档按钮 |
| canForwardingMatters | Boolean | 是否显示事项转发按钮 |
| canHistoryVersion | Boolean | 是否显示历史版本按钮 |
| canFileCopy | Boolean | 文件是否能复制 |
| refId | Long | 业务id |
| docId | Long | 文档id |

**响应说明：**

| 参数名 | 类型 | 描述 |
| --- | --- | --- |
| interruptMsg | String | 中断上传的提示信息，当传此值时，会中断上传请求并给出此提示 |
| interruptCode | int | 中断上传的code |

**示例代码：**

（1）、去配置文件开启埋点

配置文件： [weaver-file-service.properties](http://weaver-file-service.properties)

配置项：file.secondary.mode.hook

参数：（填入需要使用的埋点，按照逗号隔开，例如：FILE\_APP\_STORAGE\_HOOK\_003,FILE\_APP\_STORAGE\_HOOK\_004）

如何操作请参考【[https://weapp.eteams.cn/build/techdoc/wdoc/index.html#/public/doc/de3d8fe6-74fd-4a91-bbdf-a7d5ae72af75](https://weapp.eteams.cn/build/techdoc/wdoc/index.html#/public/doc/de3d8fe6-74fd-4a91-bbdf-a7d5ae72af75)】

（2）、实现埋点

```java
@WeaHookReg(code = "FILE_APP_STORAGE_HOOK_013")
public class SecondHookDemo extends RegHookEvent {

    @Override
    public WeaHookResponse handle(WeaHookRequest request, WeaHookResponse response, AppInfo appInfo) throws Exception {
        //获取标准传过来的参数
        Map<String, Object> params = request.getParams();
        //前面同一埋点多个二开，前面链路节点二开代码执行的结果
        Object result = response.getResult();
        if (result != null) {
            // 如果这个方法拦截二开过 获取上一个二开的结果 如果需要处理 也可以继续再处理
            response.setResult(result);
        } else {
            // 获取文件路径
            String filePath = (boolean) params.get("filePath");
            File file = new File(filePath);
            //开始进行逻辑
            ...............
            // 封装返回信息。
             Map<String,Object> resultMap = Maps.newHashMapWithExpectedSize(1);
             Map<String,Object> opMap = new HashMap<>();
            //控制编辑按钮不显示
             opMap.put("canEdit",false)
             resultMap.put("downloadInfoAuthDto",opMap);
            response.setResult(resultMap);

        }
        //返回结果
        return response;
    }

    @Override
    public void rollBack(WeaHookRequest request, WeaHookResponse response, AppInfo appInfo) throws Exception {
        //自定义二开代码异常回滚逻辑
        log.info("执行事件回滚机制 => {}, {}", DateUtil.now(), appInfo.getAppName());
    }

}
```

### 11. 文件上传控制上传大小埋点

**基线支持：10.0.2511.01 以及 最新的 260401基线（待发布）**

> **code**: FILE\_APP\_STORAGE\_HOOK\_015

**功能说明：**

控制上传的文件大小，是否走自定义的限制还是走系统的限制 图片附件未整合：_assets/51b80439-95bf-44bd-ae6e-bd4256d748e8/002-f78275fbfb.png

**参数说明：**

| 参数名 | 类型 | 描述 |
| --- | --- | --- |
| currentEmployeeId | SimpleEmployee | 当前用户对象 |
| fileSize | Long | 文件大小 |
| requestURI | String | 当前请求的 url |
| folderId | Long | 文件所属的目录id，可能为空，注意判断 |
| remoteAddr | String | 客户端ip |

|  |  |  |
| --- | --- | --- |

**响应说明：**

| 参数名 | 类型 | 描述 |
| --- | --- | --- |
| interruptMsg | String | 中断上传的提示信息，当传此值时，会中断上传请求并给出此提示 |
| interruptCode | int | 中断上传的code |
| sysCheckFileSize | Boolean | false，表示走系统设置，true：表示不走系统的控制 |

结果实现  
1、若检测文件大小超过自定义的大小，不允许上传，则返回interruptMsg。中断上传，并自定义显示的信息  
2、若要检测文件大小符合自定义的大小，允许上传，且不在进行系统的校验，则sysCheckFileSize 返回true

3、若需要走系统的大小控制，则sysCheckFileSize返回false

**示例代码：**

（1）、去配置文件开启埋点

配置文件： [weaver-file-service.properties](http://weaver-file-service.properties)

配置项：file.secondary.mode.hook

参数：（填入需要使用的埋点，按照逗号隔开，例如：FILE\_APP\_STORAGE\_HOOK\_003,FILE\_APP\_STORAGE\_HOOK\_004）

如何操作请参考【[https://weapp.eteams.cn/build/techdoc/wdoc/index.html#/public/doc/de3d8fe6-74fd-4a91-bbdf-a7d5ae72af75](https://weapp.eteams.cn/build/techdoc/wdoc/index.html#/public/doc/de3d8fe6-74fd-4a91-bbdf-a7d5ae72af75)】

（2）、实现埋点

```java
@WeaHookReg(code = "FILE_APP_STORAGE_HOOK_015")
public class SecondHookDemo extends RegHookEvent {

    @Override
    public WeaHookResponse handle(WeaHookRequest request, WeaHookResponse response, AppInfo appInfo) throws Exception {
        //获取标准传过来的参数
        Map<String, Object> params = request.getParams();
        //前面同一埋点多个二开，前面链路节点二开代码执行的结果
        Object result = response.getResult();
        if (result != null) {
            // 如果这个方法拦截二开过 获取上一个二开的结果 如果需要处理 也可以继续再处理
            response.setResult(result);
        } else {
           
         
            //开始进行逻辑
            ...............
            // 封装返回信息。
             Map<String,Object> resultMap = Maps.newHashMapWithExpectedSize(1);
             resultMap.put("sysCheckFileSize",false);
            response.setResult(resultMap);

        }
        //返回结果
        return response;
    }

    @Override
    public void rollBack(WeaHookRequest request, WeaHookResponse response, AppInfo appInfo) throws Exception {
        //自定义二开代码异常回滚逻辑
        log.info("执行事件回滚机制 => {}, {}", DateUtil.now(), appInfo.getAppName());
    }

}
```

### 12. 文件敏感词检测-控制敏感词高亮埋点

> **code**: FILE\_SDK\_BUSINESS\_HOOK\_003

**功能说明：**

文件敏感词检测，会将检测出来的敏感词在文档中高亮显示，若需要控制敏感词是否进行高亮，则可以使用此埋点进行控制

**参数说明：**

| 参数名 | 类型 | 描述 |
| --- | --- | --- |
| wordList | List\<String\> | 需要高亮的敏感词 |
| fileObj | object | 文件对象 |

|  |
| --- |
|  |

**响应说明：**

| 参数名 | 类型 | 描述 |
| --- | --- | --- |
| heightLightEnable | Boolean | 是否进行高亮后续操作，false ：不进行高亮处理，true ： 进行高亮逻辑 |
| wordList | List\<String\> | 指定高亮那些敏感词 |

**示例代码：**

（1）、去配置文件开启埋点

**配置文件：由于敏感词检测服务是在数据安全组中，请咨询数据安全组获取具体的配置文件及路径（王智杰、吕益）**

配置项：file.secondary.mode.hook

参数：（填入需要使用的埋点，按照逗号隔开，例如：file.secondary.mode.hook=FILE\_SDK\_BUSINESS\_HOOK\_003,FILE\_APP\_STORAGE\_HOOK\_004）

（2）、实现埋点

```java
@WeaHookReg(code = "FILE_SDK_BUSINESS_HOOK_003")
public class SecondHookDemo extends RegHookEvent {

    @Override
    public WeaHookResponse handle(WeaHookRequest request, WeaHookResponse response, AppInfo appInfo) throws Exception {
        //获取标准传过来的参数
        Map<String, Object> params = request.getParams();
        //前面同一埋点多个二开，前面链路节点二开代码执行的结果
        Object result = response.getResult();
        if (result != null) {
            // 如果这个方法拦截二开过 获取上一个二开的结果 如果需要处理 也可以继续再处理
            response.setResult(result);
        } else {
          
         
            //开始进行逻辑
            ...............

            // 封装返回信息。
            SecondDevResult secondDevResult = new SecondDevResult();
            //设置是否显示敏感词高亮
            secondDevResult.setHeightLightEnable(false);
            //上面设置为true，则可以设置需要高亮的敏感词
            secondDevResult.setWordList();
            response.setResult(secondDevResult);

        }
        //返回结果
        return response;
    }

    @Override
    public void rollBack(WeaHookRequest request, WeaHookResponse response, AppInfo appInfo) throws Exception {
        //自定义二开代码异常回滚逻辑
        log.info("执行事件回滚机制 => {}, {}", DateUtil.now(), appInfo.getAppName());
    }

}
```

### 13. 文件下载-前置业务逻辑处理埋点-1

> **code**: FILE\_APP\_STORAGE\_HOOK\_003

**功能说明：**

 控制文件下载前，对文件做相关判断和处理

** 此埋点前会经过文件水印处理逻辑，若需要在水印前做相关操作，则不能使用此埋点**

**参数说明：**

| 参数名 | 类型 | 描述 |
| --- | --- | --- |
| currentEmployeeId | SimpleEmployee | 当前用户对象 |
| fileObj | Map\<String, Object\> | 文件信息对象 |
| requestURI | String | 当前请求的 url |
| downloadParam | Map\<String, Object\> downloadParamMap | 下载接口参数对象 |
| remoteAddr | String | 客户端ip |

**响应说明：**

| 参数名 | 类型 | 描述 |
| --- | --- | --- |
| interruptMsg | String | 中断上传的提示信息，当传此值时，会中断上传请求并给出此提示 |
| interruptCode | int | 中断上传的code，业务自定义值 |

**示例代码：**

（1）、去配置文件开启埋点

配置文件： [weaver-file-service.properties](http://weaver-file-service.properties)

配置项：file.secondary.mode.hook

参数：（填入需要使用的埋点，按照逗号隔开，例如：FILE\_APP\_STORAGE\_HOOK\_003,FILE\_APP\_STORAGE\_HOOK\_004）

如何操作请参考【[https://weapp.eteams.cn/build/techdoc/wdoc/index.html#/public/doc/de3d8fe6-74fd-4a91-bbdf-a7d5ae72af75](https://weapp.eteams.cn/build/techdoc/wdoc/index.html#/public/doc/de3d8fe6-74fd-4a91-bbdf-a7d5ae72af75)】

（2）、实现埋点

```java
@WeaHookReg(code = "FILE_APP_STORAGE_HOOK_003")
public class SecondHookDemo extends RegHookEvent {

    @Override
    public WeaHookResponse handle(WeaHookRequest request, WeaHookResponse response, AppInfo appInfo) throws Exception {
        //获取标准传过来的参数
        //入参，修改入参并不会影响到埋点的原始数据
        Map<String, Object> params = request.getParams();
        Map<String, Object> fileObjMap = (Map)params.get("fileObj");
        Map<String, Object> downloadParamMap = (Map)params.get("downloadParam");
        //前面同一埋点多个二开，前面链路节点二开代码执行的结果
        Object result = response.getResult();
        if (result != null) {
            // 如果这个方法拦截二开过 获取上一个二开的结果 如果需要处理 也可以继续再处理
            response.setResult(result);
        } else {
          
         
            //开始进行逻辑
            ...............

            // 封装返回信息。
            Map<String,Object> resultMap = Maps.newHashMapWithExpectedSize(1);
           // 如果满足条件codition1,就修改返回值，否则中断主线逻辑
           if (condition1) {
               // 修改fileObj的name和size，需要修改什么字段就在map中放入，不要把入参中的fileObj全部放入进去
               Map<String,Object> fileObjMap = Maps.newHashMapWithExpectedSize(2);
               fileObjMap.put("name","customName.pdf");
               fileObjMap.put("size",132323L);
               resultMap.put("fileObj",fileObjMap);
           } else {
               //中断下载请求
               resultMap.put("interruptMsg","不符合当前逻辑，无法下载");
               //自定义业务码
               resultMap.put("interruptCode",520214);
           }
           response.setResult(resultMap);
           response.success("执行成功自定义msg");
        }
        //返回结果
        return response;
    }

    @Override
    public void rollBack(WeaHookRequest request, WeaHookResponse response, AppInfo appInfo) throws Exception {
        //自定义二开代码异常回滚逻辑
        log.info("执行事件回滚机制 => {}, {}", DateUtil.now(), appInfo.getAppName());
    }

}
```

### 14. 移动端文件下载控制埋点

> **code**: FILE\_APP\_STORAGE\_HOOK\_016

**功能说明：**

移动端文件下载，自定义控制文件下载权限

 图片附件未整合：_assets/51b80439-95bf-44bd-ae6e-bd4256d748e8/003-f4fb0db55b.png

**参数说明：**

| 参数名 | 类型 | 描述 |
| --- | --- | --- |
| currentEmployee | SimpleEmployee | 当前用户对象 |
| appCanDownloadFlag | Boolean | 当前租户禁止移动端下载附件的设置状态：<br>true:  表示禁止移动端下载附件已开启<br>false: 表示禁止移动端下载附件未开启 |
| requestURI | String | 当前请求的 url |
| remoteAddr | String | 客户端ip |

**响应说明：**

| 参数名 | 类型 | 描述 |
| --- | --- | --- |
| interruptMsg | String | 中断上传的提示信息，当传此值时，会中断上传请求并给出此提示 |
| interruptCode | int | 中断上传的code，业务自定义值 |
| sysCheckAppCanDownloadFile | Boolean | null: 则走跟随系统的设置<br>true: 移动端禁止下载<br>false:  移动端不禁止下载 |

**示例代码：**

（1）、去配置文件开启埋点

配置文件： [weaver-file-service.properties](http://weaver-file-service.properties)

配置项：file.secondary.mode.hook

参数：（填入需要使用的埋点，按照逗号隔开，例如：FILE\_APP\_STORAGE\_HOOK\_003,FILE\_APP\_STORAGE\_HOOK\_004）

如何操作请参考【[https://weapp.eteams.cn/build/techdoc/wdoc/index.html#/public/doc/de3d8fe6-74fd-4a91-bbdf-a7d5ae72af75](https://weapp.eteams.cn/build/techdoc/wdoc/index.html#/public/doc/de3d8fe6-74fd-4a91-bbdf-a7d5ae72af75)】

（2）、实现埋点

```java
@WeaHookReg(code = "FILE_APP_STORAGE_HOOK_016")
public class SecondHookDemo extends RegHookEvent {

    @Override
    public WeaHookResponse handle(WeaHookRequest request, WeaHookResponse response, AppInfo appInfo) throws Exception {
        //获取标准传过来的参数
        //入参，修改入参并不会影响到埋点的原始数据
        Map<String, Object> params = request.getParams();
       
        //前面同一埋点多个二开，前面链路节点二开代码执行的结果
        Object result = response.getResult();
        if (result != null) {
            // 如果这个方法拦截二开过 获取上一个二开的结果 如果需要处理 也可以继续再处理
            response.setResult(result);
        } else {
          
         
            //开始进行逻辑
            ...............

         
            // 封装返回信息。
             Map<String,Object> resultMap = Maps.newHashMapWithExpectedSize(1);
             resultMap.put("sysCheckAppCanDownloadFile",false);
             response.setResult(resultMap);
             response.success("执行成功自定义msg");
        }
        //返回结果
        return response;
    }

    @Override
    public void rollBack(WeaHookRequest request, WeaHookResponse response, AppInfo appInfo) throws Exception {
        //自定义二开代码异常回滚逻辑
        log.info("执行事件回滚机制 => {}, {}", DateUtil.now(), appInfo.getAppName());
    }

}
```

### 15. 预览前置埋点

> **code**: FILE\_APP\_STORAGE\_HOOK\_004

**功能说明：**

文件预览功能的前置埋点

**参数说明：**

| 参数名 | 类型 | 描述 |
| --- | --- | --- |
| currentEmployeeId | SimpleEmployee | 当前用户对象 |
| fileObj | obj | 文件信息 |
| requestURI | String | 当前请求的 url |
| remoteAddr | String | 客户端ip |
| previewParam | obj | 预览参数 |

**响应说明：**

| 参数名 | 类型 | 描述 |
| --- | --- | --- |
| interruptMsg | String | 中断上传的提示信息，当传此值时，会中断上传请求并给出此提示 |
| interruptCode | int | 中断上传的code，业务自定义值 |

**示例代码：**

（1）、去配置文件开启埋点

配置文件： [weaver-file-service.properties](http://weaver-file-service.properties)

配置项：file.secondary.mode.hook

参数：（填入需要使用的埋点，按照逗号隔开，例如：FILE\_APP\_STORAGE\_HOOK\_003,FILE\_APP\_STORAGE\_HOOK\_004）

如何操作请参考【[https://weapp.eteams.cn/build/techdoc/wdoc/index.html#/public/doc/de3d8fe6-74fd-4a91-bbdf-a7d5ae72af75](https://weapp.eteams.cn/build/techdoc/wdoc/index.html#/public/doc/de3d8fe6-74fd-4a91-bbdf-a7d5ae72af75)】

（2）、实现埋点

```java
@WeaHookReg(code = "FILE_APP_STORAGE_HOOK_004")
public class SecondHookDemo extends RegHookEvent {

    @Override
    public WeaHookResponse handle(WeaHookRequest request, WeaHookResponse response, AppInfo appInfo) throws Exception {
        //获取标准传过来的参数
        //入参，修改入参并不会影响到埋点的原始数据
        Map<String, Object> params = request.getParams();
        Map<String, Object> fileObjMap = (Map)params.get("fileObj");
        Map<String, Object> previewParamMap = (Map)params.get("previewParam");
        //前面同一埋点多个二开，前面链路节点二开代码执行的结果
        Object result = response.getResult();
        if (result != null) {
            // 如果这个方法拦截二开过 获取上一个二开的结果 如果需要处理 也可以继续再处理
            response.setResult(result);
        } else {
          
         
            //开始进行逻辑
            ...............

            // 封装返回信息。
            Map<String,Object> resultMap = Maps.newHashMapWithExpectedSize(1);
           // 如果满足条件codition1,就修改返回值，否则中断主线逻辑
           if (condition1) {
               // 修改fileObj的name和size，需要修改什么字段就在map中放入，不要把入参中的fileObj全部放入进去
               Map<String,Object> fileObjMap = Maps.newHashMapWithExpectedSize(2);
               fileObjMap.put("name","customName.pdf");
               fileObjMap.put("size",132323L);
               resultMap.put("fileObj",fileObjMap);
           } else {
               //中断下载请求
               resultMap.put("interruptMsg","不符合当前逻辑，无法下载");
               //自定义业务码
               resultMap.put("interruptCode",520214);
           }
           response.setResult(resultMap);
           response.success("执行成功自定义msg");
        }
        //返回结果
        return response;
    }

    @Override
    public void rollBack(WeaHookRequest request, WeaHookResponse response, AppInfo appInfo) throws Exception {
        //自定义二开代码异常回滚逻辑
        log.info("执行事件回滚机制 => {}, {}", DateUtil.now(), appInfo.getAppName());
    }

}
```

### 16. 上传后置埋点

> **code**: FILE\_APP\_STORAGE\_HOOK\_009

**功能说明：**

 系统业务文件上传成功后的埋点，已经生成了fileobj 数据对象。此埋点对消息中的文件上传无效

**参数说明：**

| 参数名 | 类型 | 描述 |
| --- | --- | --- |
| currentEmployeeId | SimpleEmployee | 当前用户对象 |
| currentEmployeeTenantKey | String | 当前租户key |
| fileObj | obj | 文件信息 |
| storageFileDto | obj | 文件存储信息 |
| remoteAddr | String | 客户端ip |
| upload4ModuleParam | obj | 上传参数 |

**响应说明：**

| 参数名 | 类型 | 描述 |
| --- | --- | --- |
| interruptMsg | String | 中断上传的提示信息，当传此值时，会中断上传请求并给出此提示 |
| interruptCode | int | 中断上传的code，业务自定义值 |

**示例代码：**

（1）、去配置文件开启埋点

配置文件： [weaver-file-service.properties](http://weaver-file-service.properties)

配置项：file.secondary.mode.hook

参数：（填入需要使用的埋点，按照逗号隔开，例如：FILE\_APP\_STORAGE\_HOOK\_003,FILE\_APP\_STORAGE\_HOOK\_004）

如何操作请参考【[https://weapp.eteams.cn/build/techdoc/wdoc/index.html#/public/doc/de3d8fe6-74fd-4a91-bbdf-a7d5ae72af75](https://weapp.eteams.cn/build/techdoc/wdoc/index.html#/public/doc/de3d8fe6-74fd-4a91-bbdf-a7d5ae72af75)】

（2）、实现埋点

```java
@WeaHookReg(code = "FILE_APP_STORAGE_HOOK_009")
public class SecondHookDemo extends RegHookEvent {

    @Override
    public WeaHookResponse handle(WeaHookRequest request, WeaHookResponse response, AppInfo appInfo) throws Exception {
        //获取标准传过来的参数
        //入参，修改入参并不会影响到埋点的原始数据
        Map<String, Object> params = request.getParams();
        Map<String, Object> fileObjMap = (Map)params.get("fileObj");
        Map<String, Object> uploadParamMap = (Map)params.get("upload4ModuleParam");
        //前面同一埋点多个二开，前面链路节点二开代码执行的结果
        Object result = response.getResult();
        if (result != null) {
            // 如果这个方法拦截二开过 获取上一个二开的结果 如果需要处理 也可以继续再处理
            response.setResult(result);
        } else {
          
         
            //开始进行逻辑
            ...............

            // 封装返回信息。
            Map<String,Object> resultMap = Maps.newHashMapWithExpectedSize(1);
           // 如果满足条件codition1,就修改返回值，否则中断主线逻辑
           if (condition1) {
               // 修改文件然后再上传文件，并修改 fileobj 数据

               
           } else {
               //中断下载请求
               resultMap.put("interruptMsg","禁止上传");
               //自定义业务码
               resultMap.put("interruptCode",520214);
           }
           response.setResult(resultMap);
           response.success("执行成功自定义msg");
        }
        //返回结果
        return response;
    }

    @Override
    public void rollBack(WeaHookRequest request, WeaHookResponse response, AppInfo appInfo) throws Exception {
        //自定义二开代码异常回滚逻辑
        log.info("执行事件回滚机制 => {}, {}", DateUtil.now(), appInfo.getAppName());
    }

}
```

### 17. 上传文件千里聆消息发送控制埋点

> **code**: FILE\_APP\_STORAGE\_HOOK\_018

**功能说明：**

 文件上传完成后，在向千里聆知识库服务同步数据之前，通过该埋点调用二开方接口，由二开方决定是否发送消息到千里聆。

**参数说明：**

| **参数名** | **类型** | **必填** |
| --- | --- | --- |
| `fileId` | Long | 是 |
| `tenantKey` | String | 是 |
| `uploadUser` | Long | 是 |
| `opType` | String | 是 |
| `module` | String | 是 |
| `docId` | Long | 是 |

**响应说明：**

| 参数名 | 类型 | 描述 |
| --- | --- | --- |
| interruptMsg | String | 中断上传的提示信息，当传此值时，会中断上传请求并给出此提示 |
| interruptCode | int | 中断上传的code，业务自定义值 |
| `sendQianliling` | Boolean | `true`：发送到千里聆；`false`：不发送。**不返回则默认为 **`true` |

**示例代码：**

（1）、去配置文件开启埋点

配置文件： [weaver-file-service.properties](http://weaver-file-service.properties)

配置项：file.secondary.mode.hook

参数：（填入需要使用的埋点，按照逗号隔开，例如：FILE\_APP\_STORAGE\_HOOK\_003,FILE\_APP\_STORAGE\_HOOK\_004）

如何操作请参考【[https://weapp.eteams.cn/build/techdoc/wdoc/index.html#/public/doc/de3d8fe6-74fd-4a91-bbdf-a7d5ae72af75](https://weapp.eteams.cn/build/techdoc/wdoc/index.html#/public/doc/de3d8fe6-74fd-4a91-bbdf-a7d5ae72af75)】

（2）、实现埋点

```java
@WeaHookReg(code = "FILE_APP_STORAGE_HOOK_018")
public class SecondHookDemo extends RegHookEvent {

    @Override
    public WeaHookResponse handle(WeaHookRequest request, WeaHookResponse response, AppInfo appInfo) throws Exception {
       
        //前面同一埋点多个二开，前面链路节点二开代码执行的结果
        Object result = response.getResult();
        if (result != null) {
            // 如果这个方法拦截二开过 获取上一个二开的结果 如果需要处理 也可以继续再处理
            response.setResult(result);
        } else {
          
         
            Map<String, Object> params = request.getParams();
        
        Long fileId = (Long) params.get("fileId");
        String tenantKey = (String) params.get("tenantKey");
        Long uploadUser = (Long) params.get("uploadUser");
        String opType = (String) params.get("opType");
        String module = (String) params.get("module");
        Long docId = (Long) params.get("docId");
        
        // 业务判断逻辑：决定是否发送到千里聆
        boolean shouldSend = yourBusinessLogic(fileId, tenantKey, module);
        
        Map<String, Object> result = new HashMap<>();
        result.put("sendQianliling", shouldSend);
        
        return WeaHookResponse.success(result);
        }
        //返回结果
        return response;
    }

    @Override
    public void rollBack(WeaHookRequest request, WeaHookResponse response, AppInfo appInfo) throws Exception {
        //自定义二开代码异常回滚逻辑
        log.info("执行事件回滚机制 => {}, {}", DateUtil.now(), appInfo.getAppName());
    }

}
```
