本文介绍了在BOTP等业务单据转换场景中,如何将一张单据的附件字段中的附件上传到另一张单据的附件面板中的实现方法。通过苍穹系统的附件面板和附件字段的特性,利用AttachmentServiceHelper的相关方法,先加载源附件字段数据,再构造附件面板数据并上传到文件服务器,最后调用saveTempAttachments方法将数据绑定到目标附件面板,并展示了实现过程和效果图,以及开发环境版本和参考资料。
关键词:
页面开发,附件面板,附件字段
一、需求
在BOTP等有业务单据转换的场景,需要把某张单据的附件字段的附件上传到另外一张单据的附件面板中,怎么实现?
二、思路与方案
2.1 分析思路
苍穹系统附件类型有附件面板和附件字段。
附件面板是面板控件,其附件对象数据存储于bos_attachment,只有控件编程模型,没有数据模型,但我们可以通过AttachmentServiceHelper.getAttachments(String, Object, String)获取附件面板数据、
AttachmentServiceHelper.upload(String, Object, String, List<Map<String, Object>>)或者AttachmentServiceHelper.saveTempAttachments(String, Object, String, Map<String, Object>)上传附件面板数据。
附件字段继承自多选基础资料,具有数据模型,其关联的基础资料类型是bd_attachment,附件字段赋值类似多选基础资料,也可通过fbasedataid实现。
那么借助这些方法即可随心所欲实现附件面板、附件字段之间的携带转换。
2.2 实现方案
先加载源附件字段的数据值集合,通过bd_attachment附件对象里的url将附件上传到文件服务器,并自己构造附件面板数据,再调用AttachmentServiceHelper.saveTempAttachments(String, Object, String, Map<String, Object>)将数据绑定到目标附件面板。
三、实现过程
1. 获取源附件字段附件对象(bd_attachment)数据
关键代码:
//获取源附件字段的值 DynamicObject sourceBill3 = BusinessDataServiceHelper.loadSingle("kded_sourcebill", "id,kded_attachment", qFilter3.toArray()); DynamicObjectCollection sourceAttachCol3 = (DynamicObjectCollection) sourceBill3.get("kded_attachment");
2. 根据附件字段数据构造附件面板数据,通过FileServiceFactory获取AttachmentFileService,并通过附件字段附件对象数据获取源附件文件流上传到文件服务器,拿到返回的url构造附件面板数据集。
关键代码:
//根据附件字段数据构造附件面板数据 Map<String, Object> attachemnts = new HashMap<>(); List<Map<String, Object>> attachmentData3 = buildAttachmentDataFromEdit(sourceAttachCol3); //key:目标附件面板标识,value:目标附件面板附件数据 attachemnts.put("attachmentpanel", attachmentData3); /** * 根据附件字段数据构造附件面板数据 * @param sourceAttachCol * @return */ private List<Map<String, Object>> buildAttachmentDataFromEdit(DynamicObjectCollection sourceAttachCol) { List<Map<String, Object>> attachDataList = new ArrayList<>(); sourceAttachCol.forEach(attach -> { DynamicObject attachObj = attach.getDynamicObject("fbasedataid"); Map<String, Object> attachMap = new HashMap<>(); //description attachMap.put("description", attachObj.getString("description")); attachMap.put("type", attachObj.getString("type")); //获取附件inputstream上传到缓存服务 InputStream inputStream = FileServiceFactory.getAttachmentFileService().getInputStream(attachObj.getString("url")); String saveUrl = CacheFactory.getCommonCacheFactory().getTempFileCache().saveAsFullUrl(attachObj.getString("name"), new BufferedInputStream(inputStream), 2*3600); //url attachMap.put("url", saveUrl); //uid attachMap.put("uid", getUid()); //name attachMap.put("name", attachObj.getString("name")); //size attachMap.put("size", attachObj.get("size")); attachMap.put("fattachmentpanel", "attachmentpanel"); //entityNum attachMap.put("entityNum", getView().getEntityId()); attachMap.put("billPkId", String.valueOf(getModel().getValue("id"))); //lastModified attachMap.put("lastModified", new Date().getTime()); attachMap.put("status", "success"); //client attachMap.put("client", null); attachDataList.add(attachMap); }); return attachDataList; } /** * 获取附件uid * @return */ private StringBuffer getUid() { StringBuffer uid = new StringBuffer("rc-upload-"); uid.append((new Date()).getTime()); uid.append("-"); int index = (int)(1.0D + Math.random() * 10.0D); uid.append(index); return uid; }
3. 调用AttachmentServiceHelper.saveTempAttachments(String, Object, String, Map<String, Object>)将数据绑定到目标附件面板。
关键代码:
AttachmentServiceHelper.saveTempAttachments(getView().getEntityId(), getModel().getValue("id"), "kded_clztest", attachemnts); //刷新页面 getView().updateView("attachmentpanel");
四、效果图
1. 如图1-图3。
图 1 源单据附件字段上传图片
图 2 通过插件将源附件字段图片上传到目标附件面板
图 3 目标附件面板图片可正常浏览
五、开发环境版本
COSMICV4.0.014.0
六、参考资料
七、附件
插件实现附件面板和附件字段的携带转换_代码.zip(2.74KB)
插件实现附件面板和附件字段的携带转换_元数据.zip(16.25KB)
推荐阅读