第三方系统如何上传附件到苍穹已有单据的附件字段原创
金蝶云社区-陈来珍
陈来珍
9人赞赏了该文章 4,719次浏览 未经作者许可,禁止转载编辑于2022年10月12日 15:26:48
summary-icon摘要由AI智能服务提供

本文档描述了如何在苍穹平台(Cosmic)上实现第三方系统上传业务单据及其附件的流程。首先,第三方系统需要将附件上传至苍穹的缓存中,通过调用`attachment/uploadFile.do`接口获得临时附件的URL。然后,将单据数据和附件信息封装成请求数据,通过自定义的OpenAPI接口上传至苍穹平台,实现单据和附件的持久化存储及字段赋值。文档详细阐述了上传附件、封装数据、调用OpenAPI上传单据及附件信息的具体实现步骤和代码示例。

关键词:OpenAPI、附件字段

一、需求

苍穹平台有一业务单据(kded_lczdemo),单据上存在一个附件字段x。第三方系统上传单据数据到苍穹系统单据a上,同时上传附件到单据a的附件字段x上。

二、思路与方案

第三方系统远程上传业务单据数据至苍穹平台内,一般的单据数据的保存可以通过苍穹平台新增一个OpenApi接口(操作服务)给第三方系统调用,但是不能上传附件,因此需要先通过平台对外提供的attachment/uploadFile.do把附件上传到苍穹的缓存中,然后通过自定义服务接口完成附件的持久化、附件字段的赋值。

q1.png

三、实现过程

下面步骤是苍穹平台相关的主要逻辑,详细代码看文章后面附件中的插件。

1、上传附件

调用苍穹的文件上传请求(uploadFile.do)将文件发送至苍穹系统缓存中,并返回临时附件的url。

       /**
        * 将文件发送到苍穹中
        * @param file
        * @param accessToken
        * @return
        * @throws Exception
        */
       private String postFileToCosmic(File file, String accessToken) throws Exception {
              // 第三方系统上传附件到苍穹的请求接口
       StringBuffer url = new StringBuffer();
        url.append(URL_COSMICHOST).append("attachment/uploadFile.do");
        // 上传可能需要传的参数
        Map<String, Object> param = new HashMap<String, Object>();
              // 上传附件,返回该附件在苍穹缓存中的临时存储路径
        return FileUploadService.getService().postFile(url.toString(), param, file, accessToken);
       }

2、封装数据要上传的附件信息到苍穹平台

private Map<String, Object> generateBizData(Map<String, List<File>> allFiles, String accessToken) throws Exception {
              Map<String, Object> allBizBillData = new HashMap<String, Object>();
              // 生成单据数据
              Map<String, Object> billData = new HashMap<String, Object>();
              billData.put("billno", billno);
              billData.put("billstatus", "A");
              allBizBillData.put("billData", billData);
              Map<String, Object> params = new HashMap<String, Object>();
              params.put("appId", KEY_APPNUMBER);
              params.put("entityName", KEY_BILL);
              allBizBillData.put("params", params);
              // 生成单据上所有的附件数据
              Map<String, Object> allAttachmentsData = new HashMap<String, Object>();
              // 单个附件面板中所有附件的信息
              List<Map<String, Object>> attachments = null;
              // 单个附件的信息
              Map<String, Object> attachmentInfo = null;
              StringBuffer uid = new StringBuffer();
              uid.append("rc-upload-").append(new Date().getTime()).append("-");
              int index = (int) (1 + Math.random()*10);
              for (String tempAttaKey : allFiles.keySet()) {
                     List<File> files = allFiles.get(tempAttaKey);
                     attachments = new ArrayList<Map<String, Object>>();
                     for (File tempFile : files) {
                            String tempAttaUrl = this.postFileToCosmic(tempFile, accessToken);
                            attachmentInfo = new HashMap<String, Object>();
                            attachmentInfo.put("entityNum", KEY_BILL);
                            attachmentInfo.put("name", tempFile.getName());
                            attachmentInfo.put("url", tempAttaUrl);
                            attachmentInfo.put("size", tempFile.length());
                            attachmentInfo.put("status", "success");
                            attachmentInfo.put("uid", uid.toString() + index++);
                            attachments.add(attachmentInfo);
                     }
                     allAttachmentsData.put(tempAttaKey, attachments);
              }
              allBizBillData.put("allAttachmentsData", allAttachmentsData);
              return allBizBillData;
       }

3、调用自定义OpenApi上传单据&附件信息到苍穹单据上

/**
     * 远程上传单据数据 & 附件文件到苍穹系统
     * @param cosmicHost               苍穹系统访问地址
     * @param accessToken
     * @param allAttachmentsData  单据数据  & 所有附件数据
     * @return
     * @throws URISyntaxException
     */
    public String bizSaveApi(String cosmicHost, String accessToken, Map<String, Object> allAttachmentsData) throws URISyntaxException {
          // 自定义开放平台接口路径
          StringBuffer url = new StringBuffer();
              url.append(cosmicHost).append(UPLOADATTAPATH);
              System.out.println(">>> " + url.toString());
          // 封装数据
          JSONObject body = new JSONObject();
          body.put("billData", allAttachmentsData.get("billData"));
          body.put("allAttachmentsData", allAttachmentsData.get("allAttachmentsData"));
          body.put("params", allAttachmentsData.get("params"));
              String responseStr = null;
              try {
                     responseStr = HttpService.getService().doGetByHttpClient(url.toString(), accessToken, body);
              } catch (Exception e) {
                     e.printStackTrace();
              }
              return responseStr;
    }

4.、开发自定义服务,插件中实现单据数据保存,并同步持久化缓存中附件到附件服务器上。

@Override
       public ApiResult doCustomService(Map<String, Object> params) {
              Map<String, Object> resultInfo = new HashMap<String, Object>();
              // 单据数据
              Map<String, Object> bizObject = (Map<String, Object>) params.get("billData");
              logger.info("单据数据: " + bizObject);
              // 附件信息
              Map<String, Object> attachmentInfo = (Map<String, Object>) params.get("allAttachmentsData");
              // 参数信息
              Map<String, Object> paramMap = (Map<String, Object>) params.get("params");
              String entityNumber = paramMap.get("entityName").toString();
              logger.info(">>> 上传附件 <<<");
              // 保存单据数据
              DynamicObject dynamicObject = BusinessDataServiceHelper.newDynamicObject(entityNumber);
              dynamicObject.set("billno", bizObject.get("billno"));
              dynamicObject.set("billstatus", bizObject.get("billstatus"));
              dynamicObject.set("createtime", new Date());
              dynamicObject.set("modifytime", new Date());
 
              List<LinkedHashMap<String, Object>> attmentInfors = (List<LinkedHashMap<java.lang.String, Object>>) attachmentInfo
                            .get("kded_attachmentfieldx");
              DynamicObjectCollection attCol = dynamicObject.getDynamicObjectCollection("kded_attachmentfieldx");
 
              for (LinkedHashMap<String, Object> attmentInfor : attmentInfors) {
                     String name = (String) attmentInfor.get("name");
                     String url = (String) attmentInfor.get("url");
                     String[] split = url.split("id=");
                     if (split.length > 1) {
                            // 参考标准源码 AttachmentFieldServiceHelper.saveTempToFileService(tempUrl, AttPk,fileName)
                            TempFileCache cache = CacheFactory.getCommonCacheFactory().getTempFileCache();
                            RequestContext requestContext = RequestContext.get();
                            // 指定上传到文件服务器的目标地址
                            String pathParam = FileNameUtils.getAttachmentFileName(requestContext.getTenantId(),
                                          requestContext.getAccountId(), "attachmentupload", name);
                            FileItem item = new FileItem(name, pathParam, cache.getInputStream(url));
                            item.setCreateNewFileWhenExists(true);
                            // 上传附件
                            FileService fileService = FileServiceFactory.getAttachmentFileService();
                            String path = fileService.upload(item);
                            // String
                            // url="http://172.20.63.42:8080/ierp/attachment/download.do?path=/ierp/1218732684788893696/202203/attachmentupload/one_1646273203365.txt";
                            String downurl = UrlService.getDomainContextUrl() + "/attachment/download.do?path=" + path;
                            attmentInfor.put("url", downurl);
                            DynamicObject att = createAttDynamic(attmentInfor);
                            DynamicObject addNew = attCol.addNew();
                            addNew.set("fbasedataid", att);
                            cache.remove(url);
                     }
 
              }
 
              OperationResult result = SaveServiceHelper.saveOperate(entityNumber, new DynamicObject[] { dynamicObject },
                            OperateOption.create());
              if (!result.isSuccess()) {
                     List<IOperateInfo> operateInfo = result.getAllErrorOrValidateInfo();
                     for (IOperateInfo tempOperateInfo : operateInfo) {
                            logger.error(tempOperateInfo.getMessage());
                     }
                     return ApiResult.fail("单据保存失败!");
              }
              // 上传附件
              String appId = paramMap.get("appId").toString();
              Object pkId = result.getSuccessPkIds().get(0);
              resultInfo.put("pkId", pkId);
              return ApiResult.success(resultInfo);
       }

5、构建附件字段对象

/**
        * 根据附件信息封装附件字段对象bd_attachment
        *
        * @param attmentInfor
        * @return
        */
       private DynamicObject createAttDynamic(Map<String, Object> attmentInfor) {
              DynamicObject attObj = BusinessDataServiceHelper.newDynamicObject("bd_attachment");
              String name = (String) attmentInfor.get("name");
              attObj.set("name", name);
              attObj.set("size", attmentInfor.get("size"));
              attObj.set("uid", attmentInfor.get("uid"));
              attObj.set("url", attmentInfor.get("url"));
              String type = name.substring(name.lastIndexOf(".") + 1);
              attObj.set("type", type);
              // tempfile=1表示持久化附件对象
              attObj.set("tempfile", 1);
              ORM orm = ORM.create();
              long id = orm.genLongId("bd_attachment");
              attObj.set("id", id);
              attObj.set("pageid", "");
              attObj.set("number", UUID.randomUUID().toString());
              attObj.set("status", "B");
              Date now = new Date();
              attObj.set("modifytime", now.getTime());
              attObj.set("creator", UserServiceHelper.getCurrentUserId());
              SaveServiceHelper.save(new DynamicObject[] { attObj });
              return attObj;
       }

6、注册自定义插件

把自定义服务插件注册到”开放平台-其他-api服务管理1.0-插件“中

image.png

四、效果图

debug调试main入口类

q2.png

进入苍穹平台打开单据,可以看到单据附件已成功上传至新增单据

q3.png

五、开发环境版本

COSMICV4.0.014.0

六、参考资料

【开发平台】指导手册

学习成长中心

开放平台(视频)

开放平台(文档)

插件开发—开放API

引入时携带引入文件到单据的附件字段

第三方系统远程上传业务单据&多个附件至苍穹的附件面板 


图标赞 9
9人点赞
还没有人点赞,快来当第一个点赞的人吧!
图标打赏
0人打赏
还没有人打赏,快来当第一个打赏的人吧!