附件二开常见问题汇总

栏目:云苍穹知识作者:金蝶来源:金蝶云社区发布:2024-09-23浏览:1

附件二开常见问题汇总

# 1. 如何获取附件或图片的文件流? 答:请调用如下接口(请遵守参数规范),返回值即为附件或图片的文件流。 ## 1.1 缓存服务器的附件,获取文件流方式 返回值即为临时附件的文件流。 ```java //临时文件path适用 InputStream in = CacheFactory.getCommonCacheFactory().getTempFileCache().getInputStream(String path); ``` 参数规范1:**path必须为附件的临时路径**,示例:https://feature.kingdee.com:1026/feature_sit/tempfile/download.do?configKey=redis.serversForCache&id=tempfile-1722520531024072704 参数规范2:**参数中的path必须在缓存中存在**(检查方法:直接访问这个链接,能下载即说明缓存中存在这个附件。),否则会返回空文件流,进而导致一系列二开问题。 ## 1.2 文件服务器的附件,获取文件流方式 返回值即为持久化附件的文件流。 ```java //持久化附件path适用 InputStream in = FileServiceFactory.getAttachmentFileService().getInputStream(String path); ``` 参数规范1:**path必须为附件的非加密相对路径**,示例:/tenant_devcore_dev/1402323749146986496/202305/1683569603244172288/5b3c272f9d5a42fdbecddf2d84bcdd56/Word文档.docx。(加密路径转换成明文路径的方法请见下文) 参数规范2:**参数中的path必须在文件服务器中存在**(检查方法,加上download前缀,直接访问这个链接,能下载即说明文件服务器中存在这个附件),否则会返回空文件流,进而导致一系列二开问题。 ## 1.3 图片服务器的图片,获取文件流方式 返回值即为图片服务器中的图片的文件流。 ```java //图片服务器中的图片文件适用 InputStream in = FileServiceFactory.getImageFileService().getInputStream(String path); ``` 参数规范1:**path必须为图片的非加密相对路径**,示例:/tenant_devcore_dev/1402323749146986496/202305/202305/yby_test/myattachment/images/DYaVqVPU1lX4bRzlGM/附件jpg测试图片.webp。(加密路径转换成明文路径的方法请见下文) 参数规范2:**参数中的path必须在图片服务器中存在**(检查方法,加上downloadImage前缀,直接访问这个链接,能下载即说明图片服务器中存在这个图片),否则会返回空文件流,进而导致一系列二开问题。 **注:** **1. 附件download前缀和图片downloadImage前缀如何确认?** 方法1:F12调出控制台,然后在系统的任意页面刷新浏览器,找到getConfig.do请求,找到该请求的响应,响应中的attachmentserver参数的值即为附件的download前缀,fileserver为图片的downloadImage前缀。 ![image-20230720104558212.webp](/download/0100c72f066b787d4c0c812625174d6f3e95.webp) 方法2:附件的download前缀,F12调出控制台,去单据任意下载一个附件,如图即为附件的download前缀。 ![image-20230720105016163.webp](/download/01004568479533674edb88a0d30d1c0e8be8.webp) 图片的downloadImage前缀,F12调出控制台,去单据的**图片字段**任意上传一个图片,如图即为图片的downloadImage前缀。 ![image-20230720105115797.webp](/download/010067bfbeee1a3144e39da32335b551bd6f.webp) **2. 如果确认path已经在文件服务器或图片服务器中存在,但是在二开代码拿不到这个流,请在容器中执行curl命令访问该链接,检查是否能访问,如果不能访问,即说明容器的配置有问题。** # 2. 如何通过附件的相对路径获取其全路径? 答:请调用如下接口(请遵守参数规范),返回值即为全路径url。 ```java //从文件服务器获取全路径 UrlService.getAttachmentFullUrl(String url); //从图片服务器获取全路径 UrlService.getImageFullUrl(String url); ``` 参数规范:**参数均为附件相对路径**,示例:/tenant_devcore_dev/1402323749146986496/202305/1683569603244172288/5b3c272f9d5a42fdbecddf2d84bcdd56/Word文档.docx。 # 3.如何获取临时文件url(将附件保存到==临时==文件服务器)? 答:请调用如下接口(请遵守参数规范) ## 3.1 获取临时附件相对地址 返回值为临时附件==相对==地址。(如:`tempfile/download.do?configKey=redis.serversForCache&id=tempfile-1722520531024072704`) ```java /** * @description 将附件存到到临时文件服务器 * @param fileName 文件名 * @param InputStream 附件文件流 * @param timeout 文件过期时间(单位为秒) * @return 临时附件url */ kd.bos.cache.TempFileCache#saveAsUrl(String filename, InputStream in, int timeout); ``` 参数规范1:filename为文件名,示例:测试文档.pdf 参数规范2:in为文件流,传入前请确保文件流为正确的文件流,例如可以用in.available()获取文件流大小来判断 参数规范3:timeout为临时文件过期时间,单位为秒,示例:7200,标准产品过期时间为7200秒,即2小时。 ## 3.1 获取临时附件绝对地址 返回值为临时附件==绝对==地址。(如`https://feature.kingdee.com:1026/feature_sit/tempfile/download.do?configKey=redis.serversForCache&id=tempfile-1722520531024072704`) ```java /** * @description 将附件存到到临时文件服务器 * @param fileName 文件名 * @param InputStream 附件文件流 * @param timeout 临时文件过期时间(单位为秒) * @return 临时附件url */ kd.bos.cache.TempFileCache#saveAsFullUrl(String filename, InputStream in, int timeout); ``` 参数规范1:filename为文件名,示例:测试文档.pdf 参数规范2:in为文件流,传入前请确保文件流为正确的文件流,例如可以用in.available()获取文件流大小来判断 参数规范3:timeout为临时文件过期时间,单位为秒,示例:7200,标准产品过期时间为7200秒,即2小时。 # 4.如何获取持久化文件url(如何将附件保存到文件服务器)? 答:请调用如下接口(请遵守参数规范) 场景描述:单据中由二开绑定的附件,下载地址可能是一个临时下载链接,如果不将临时下载链接转换成持久化链接,绑定附件2小时过后,附件下载链接将会失效,导致无法下载。 ## 4.1 附件面板适用 返回值即为持久化url。 ```java /** * @description 把系统缓存中的临时附件上传到远程服务器 * @param tempUrl 缓存中临时附件url * @param appId 应用编码 * @param formId 表单标识 * @param pkId 单据pkid * @param fileName 文件名 * @param isDeleteTempFile 是否删除缓存中的临时文件 * @param createNewFileWhenExists 当文件存在时新建文件 * @return 文件相对于文件服务器的相对路径 */ kd.bos.servicehelper.AttachmentServiceHelper#saveTempToFileService(String tempUrl, String appId, String formId, Object pkId, String fileName, boolean isDeleteTempFile, boolean createNewFileWhenExists) ``` 参数规范1:tempUrl 为缓存中临时附件url,示例:https://feature.kingdee.com:1026/feature_sit/tempfile/download.do?configKey=redis.serversForCache&id=tempfile-1722520531024072704 参数规范2:appId 为应用编码,示例:yby_test_app 参数规范3:formId 为表单标识,示例:yby_test_formId 参数规范4:pkId 为单据主键,示例:1723102865825785856 参数规范5:fileName 为文件名,示例:测试文档.pdf 参数规范6:isDeleteTempFile 代表是否设置是否删除缓存中的临时文件,示例:true 或 false 参数规范7:createNewFileWhenExists 代表是否设置当文件存在时新建文件,示例:true 或 false ## 4.2 附件字段适用 返回值即为持久化url。 ```java /** * @description 把系统缓存中的临时附件上传到远程服务器 * @param tempUrl 缓存中临时附件url * @param AttPk 附件id * @param fileName 附件文件名 * @return 文件相对于文件服务器的相对路径 */ kd.bos.servicehelper.attachment.AttachmentFieldServiceHelper#saveTempToFileService(String tempUrl, Object AttPk, String fileName) ``` 参数规范1:tempUrl 为缓存中临时附件url,示例:https://feature.kingdee.com:1026/feature_sit/tempfile/download.do?configKey=redis.serversForCache&id=tempfile-1722520531024072704 参数规范4:AttPk 为单据主键,示例:1723102865825785856 参数规范5: fileName 为文件名,示例:测试文档.pdf # 5. 如何将附件绑定到单据上的附件字段或附件面板? 答:请参考文档 [附件绑定单据接口](https://vip.kingdee.com/article/126693402527067136?productLineId=29&isKnowledge=2) # 6. 如何获取预览url? 答:请调用如下接口(请遵守参数规范) ## 6.1 获取临时文件预览url 返回值为临时文件预览url。 ```java /** * 获取临时附件的预览url * * @param path 临时附件的downloadUrl全路径 * @return 临时附件的预览url * * 入参示例:http://localhost:8080/ierp/tempfile/download.do? * configKey=redis.serversForCache&id=tempfile-1688297935936176128 */ kd.bos.entity.datamodel.IAttachmentModel#getTempFilePreviewUrl(String path) ``` 参数规范:path为临时附件的downloadUrl**绝对路径**,示例:`http://localhost:8080/ierp/tempfile/download.do?configKey=redis.serversForCache&id=tempfile-1688297935936176128` ## 6.2 获取持久化文件预览url 返回值为持久化文件预览url。 ```java /** * 获取持久化附件的预览url * * @param path 持久化附件的downloadUrl相对路径 * @return 持久化附件的预览url * * 入参示例: /tenant_devcore_dev/1402323749146986496/202305/1683569603244172288/5b3c272f9d5a42fdbecddf2d84bcdd56/Wo rd文档.docx */ kd.bos.url.UrlService#getAttachmentPreviewUrl(String path) ``` 参数规范:path为持久化附件的downloadUrl相对路径,示例:`/tenant_devcore_dev/1402323749146986496/202305/1683569603244172288/5b3c272f9d5a42fdbecddf2d84bcdd56/Wo rd文档.docx` # 7.在文件服务器中附件的标准路径规则是什么? ## 7.1 附件面板标准路径规则 答:租户id/账户id/日期/应用编码/单据编码/单据主键/attachments/uuid/文件名 ## 7.2 附件字段标准路径规则 答:租户id/账户id/日期/附件id/uuid/文件名 # 8.标准附件路径的各个层级分别代表什么? 答:附件字段和附件面板的标准附件路径不同,下面结合示例进行讲解。 ## 8.1 附件面板 示例:`/tenant_devcore_dev/1402323749146986496/202304/kd_test_app/kd_test_bill/1641415906691197952/attachments/d0b288fae63e44aca6a3ff9a60f04017/test.txt` `tenant_devcore_dev`:租户id `1402323749146986496`:账套id/数据中心id `202304`:年月 `kd_test_app`:应用标识 `kd_test_bill`:业务对象标识 `1641415906691197952`:单据内码 `attachments`:常量(固定为attachments) `d0b288fae63e44aca6a3ff9a60f04017`:uuid `test.txt`:文件名 ## 8.2 附件字段 示例:`/tenant_devcore_dev/1402323749146986496/202205/1413819776135974912/c7db175fd32a42cfbc2ad3e907daca66/test.txt` `tenant_devcore_dev`:租户id `1402323749146986496`:账套id/数据中心id `202205`:年月 `1413819776135974912`:附件id(附件字段详情表t_bd_attachment中附件对应的id) `c7db175fd32a42cfbc2ad3e907daca66`:uuid `test.txt`:文件名 # 9. 如何生成附件的标准路径? 答:请调用如下接口(请遵守参数规范) ## 9.1 附件面板 ```java /** * 根据提供的参数生成附件存储在文件服务器的相对路径(用于附件面板) * @param tenantId 租户id * @param accountId 账户id * @param appId 应用编码 * @param formId 单据编码 * @param pkId 单据主键 * @param filename 文件名 * @return 存入文件服务器的相对路径 */ kd.bos.util.FileNameUtils#getAttachmentFileName(String tenantId,String accountId,String appId, String formId, Object pkId ,String filename) ``` 参数规范1:tenantId 为租户id,示例:tenant_devcore_dev 参数规范2:accountId 为账户id,示例:1402323749146986496 参数规范3:appId 为应用编码,示例:kd_test_app 参数规范4:formId 为业务对象标识,示例:kd_test_bill 参数规范5:pkId为单据主键,示例:1641415906691197952 参数规范6:filename 为文件名,示例:test.txt ## 9.2 附件字段 ```java /** * 根据提供的参数生成附件存储在文件服务器的相对路径(用于附件字段) * @param tenantId 租户id * @param accountId 账户id * @param AttPk 附件id * @param filename 文件名 * @return 存入文件服务器的相对路径 */ kd.bos.util.FileNameUtils#getAttachmentFileName(String tenantId,String accountId,Object AttPk,String filename) ``` 参数规范1:tenantId 为租户id,示例:tenant_devcore_dev 参数规范2:accountId 为账户id,示例:1402323749146986496 参数规范3:AttPk 为附件id,示例:1413819776135974912 参数规范4:filename 为文件名,示例:test.txt # 10.附件和图片的加密路径和明文路径有什么区别与联系? 考虑到系统安全,附件的url在系统中默认是加密的。每一个加密路径对应着一个明文路径,明文路径即为该附件(或图片)在文件服务器(或图片服务器)上的路径。加密路径和明文路径的区别如下: 附件加密路径:`f5446a9fbe684fdd8e41556ef846c1ae` 附件明文路径: `/tenant_devcore_dev/1402323749146986496/202305/1683569603244172288/5b3c272f9d5a42fdbecddf2d84bcdd56/Word文档.docx` 图片加密路径:`f57bcc8b47914b3387d9399dedfe257b.webp` 图片明文路径: `/tenant_devcore_dev/1402323749146986496/202305/202305/yby_test/myattachment/images/DYaVqVPU1lX4bRzlGM/附件jpg测试图片.webp` # 11. 如何通过加密路径去查明文路径? ## 11.1 附件加密路径 1)通过接口查询(请遵守参数规范) 附件加密路径可以调用`kd.bos.fileservice.extension.FileServiceExt#getRealPath`,转换成明文路径,代码示例如下。 ```java String encryptPath = "c402cc4809d84f2a9d88f98f550a7944"; path = FileServiceExtFactory.getAttachFileServiceExt().getRealPath(encryptPath); ``` 参数规范:**encryptPath为附件加密路径**,示例:c402cc4809d84f2a9d88f98f550a7944。 2)数据库查询 附件加密路径与明文路径的映射关系存在t_bas_filepathmapping表中,ffileid代表附件的加密路径,fpath代表附件的明文路径。 ## 11.2 图片加密路径 1)通过接口查询(请遵守参数规范) 图片加密路径可以调用`kd.bos.fileservice.extension.FileServiceExt#getRealPath`,转换成明文路径,代码示例如下。 ```java String encryptPath = "954042e18a274f7f8f9cccbea0094bde.webp"; String path = FileServiceExtFactory.getImageFileServiceExt().getRealPath(encryptPath); ``` 参数规范:**encryptPath为图片加密路径**,示例:954042e18a274f7f8f9cccbea0094bde.webp。 2)数据库查询 附件加密路径与明文路径的映射关系存在t_bas_imagefilepathmapping表中,,ffileid代表附件的加密路径,fpath代表附件的明文路径。 # 12.如何自定义附件面板的按钮及修改按钮可见性? 答:请参考文档[《自定义附件面板的按钮及修改按钮可见性》](https://vip.kingdee.com/article/236196563457491968?productLineId=29&isKnowledge=2)。 # 13.如何控制附件面板按钮锁定性? 答:请参考文档[《附件面板和附件字段按钮可见性、锁定性控制说明》](https://vip.kingdee.com/article/447440450748881408 )。 # 14.单据中,如何以时分秒的格式显示附件上传的时间? 答:二开方案如下: ```java public class TestPlugin extends AbstractFormPlugin { //附件面板的标识 private static final String ATTACHMENTPanel = "attachmentpanel"; @Override public void afterBindData(EventObject e) { Map<String, Object> meta = new HashMap<>(); meta.put("attachdf", "datetime"); //更新控件的元数据 this.getView().updateControlMetadata(ATTACHMENTPanel, meta); } } ``` ![01096df70359322446cc91642c8c98e81e6c.webp](/download/01008adc4a30d5d4468491f65e7f254b1f8d.webp) # 15.如何通过二开取消附件上传? 答:请参考文档[《beforeUpload取消上传插件示例介绍》](https://vip.kingdee.com/article/447439699649393920)。 # 16.如何获取文件一次性下载链接? ```java /** * @param disposableUrlParam 参数对象 * @return 返回一次性下载链接 */ kd.bos.servicehelper.AttachmentServiceHelper#genCustomAttachUrl(DisposableUrlParam disposableUrlParam) { ``` **DisposableUrlParam构造函数传参规范** - **path:持久化文件相对路径,或临时文件全路径。** - path为附件的**临时**路径时,路径格式示例:`https://feature.kingdee.com:1026/feature_sit/tempfile/download.do?configKey=redis.serversForCache&id=tempfile-1722520531024072704`。 - path为附件的**持久化**路径时,路径格式示例:`/tenant_devcore_dev/1402323749146986496/202305/1683569603244172288/5b3c272f9d5a42fdbecddf2d84bcdd56/Word文档.docx`。 - **entityNum:单据标识,如:"testBill"。** - **pkId:单据的pkId。** 如果需要验特殊数据权限,需要传对应单据的pkid;**若不需要验特殊数据权限,pkid传0L即可**。 - **permItem:权限项编码。** permItem参数需要传在系统中已经预置的权限项的编码(在权限项列表能找到,说明已预置)。编码是指在表T_PERM_PERMITEM中的FID字段,权限项列表入口以及权限项编码查看方式如下图。 ![20231205162607086.webp](/download/0100eccce810b3c34e01ae9efe2452ff05fe.webp) ![20231205162619317.webp](/download/01003776bda2858f47de9c512cb82ff6c266.webp) # 17.附件下载如何二开设置自定义验权? 答:kd.bos.service.attachment.extend.permission.IFilePermissionExtension 二开实现此接口,然后配置mc参数file.permission.ext.impl.classname为实现类的全路径,分别重写dealPermissionParam、checkPermission方法实现。文件验权扩展接口逻辑:先走苍穹验权,苍穹验证通过,则通过,苍穹验证不通过,再走接口,接口验证通过则通过。 # 18.附件存于分录行上,自定义验权中如何获取分录信息? 答:实现IFilePermissionExtension接口之后会传递一个path参数到实现类的checkPermission方法,获取之后查询t_bd_attachment表,查询条件为furl=path,查询字段为主键fid,然后再通过这个fid查询t_bas_bill_file_mapping这个表,查询条件是fattpkid,billentrypkid字段为对应的分录id。 # 19.在5.0.005及之前的版本,二开修改按钮可见性不生效,如何处理? 答:5.0.005及之前的版本,由于前端代码存在bug,故修改无效,请提单通过私包或者升级的方式来处理。 # 20.新系统初始化时如何导入原系统的附件并绑定表单? 答:请参考文档[《第三方系统如何上传附件到苍穹已有单据的附件字段》](https://vip.kingdee.com/knowledge/specialDetail/294832938980257024?category=294833149400665344&id=594589694923631360&productLineId=29&lang=zh-CN)。 # 21.调用AttachmentServiceHelper.upload方法绑定附件信息时,url过长导致数据保存失败,如何解决? 答:因为传入了url的全路径,而数据库需要保存的参数是path,需要通过UrlUtil.getParam(url,"path")获取到对应的path参数,覆盖原url参数。 # 常见误区 ## 1. AttachmentServiceHelper的upload方法 AttachmentServiceHelper.upload 方法。此方法的方法名虽然叫upload,但实际上的**作用只是将传入的附件信息存到附件面板详情表t_bas_attachment中,也就是将附件信息绑定到单据**,**没有将附件上传的文件服务器的功能**,为防止误用,此处特别指出。 ```java /** * @description 保存附件数据到数据库,注意此方法没有将附件上传的文件服务器的功能 * @param formId 单据编码 * @param pkId 单据主键 * @param attachments 附件信息集合 */ kd.bos.servicehelper.AttachmentServiceHelper#upload(String formId, Object pkId, String attachKey, List<Map<String, Object>> attachments) ```

附件二开常见问题汇总

# 1. 如何获取附件或图片的文件流?答:请调用如下接口(请遵守参数规范),返回值即为附件或图片的文件流。## 1.1 缓存服务器的附件,...
点击下载文档
确认删除?
回到顶部
客服QQ
  • 客服QQ点击这里给我发消息