9060 4 hónapja
szülő
commit
31b7b4c585

+ 21 - 5
js/addon/custom/js/eSign/ESignGlobalStatusOverviewList.js

@@ -53,14 +53,30 @@ shr.defineClass("shr.esign.ESignGlobalStatusOverviewList", shr.framework.List, {
             method: 'preview',
             billId: selectedIds,
             success:function (response){
-                _self.reloadPage({
-                    uipk: "com.kingdee.eas.custom.esign.app.ESignGlobalStatusOverview.view",
-                    billId: selectedIds,
-                    method: 'view'
-                });
+                if(response){
+                    setTimeout(()=>{
+                        _self.reloadPage({
+                            uipk: "com.kingdee.eas.custom.esign.app.ESignGlobalStatusOverview.view",
+                            billId: selectedIds,
+                            method: 'view'
+                        });
+                    },500);
+                }
             }
         });
     },
+    /**
+     *  审批
+     */
+    syncAttachmentsAction: function () {
+        var _self = this;
+
+        var selectedIds = this.getSelectedIds();
+        _self.doRemoteWithBatchAction({
+            method: 'syncAttachments',
+            billId: selectedIds
+        });
+    },
     /**
      * 执行远程服务端方法,适用于有批量操作的远程调用
      */

+ 4 - 1
src/com/kingdee/eas/custom/esign/app/ESignTemplateFileEntryControllerBean.java

@@ -131,7 +131,10 @@ public class ESignTemplateFileEntryControllerBean extends AbstractESignTemplateF
         FilterItemCollection filterItems = filterInfo.getFilterItems();
         filterItems.add(new FilterItemInfo("name", "%" + fileName + "%", CompareType.LIKE));
         filterItems.add(new FilterItemInfo("state", BaseItemStateEnum.ENABLE_VALUE));
-        EntityViewInfo viewInfo = EntityViewInfo.getInstance(filterInfo, null, null);
+        SelectorItemCollection sic = new SelectorItemCollection();
+        sic.add("id");
+        sic.add("attachmentCategory.componentId");
+        EntityViewInfo viewInfo = EntityViewInfo.getInstance(filterInfo, sic, null);
         ESignTemplateFileEntryCollection eSignTemplateFileEntryCol = getESignTemplateFileEntryCollection(ctx, viewInfo);
         if (!eSignTemplateFileEntryCol.isEmpty()) {
             ESignTemplateFileEntryInfo eSignTemplateFileEntryInfo = eSignTemplateFileEntryCol.get(0);

+ 8 - 3
src/com/kingdee/eas/custom/esign/util/SyncSignedFilesUtil.java

@@ -4,6 +4,7 @@ import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.kingdee.eas.base.permission.UserInfo;
+import com.kingdee.eas.framework.CoreBaseCollection;
 import org.apache.commons.lang3.StringUtils;
 import com.kingdee.bos.BOSException;
 import com.kingdee.bos.Context;
@@ -83,11 +84,14 @@ public class SyncSignedFilesUtil {
                 throw new BOSException(MessageFormat.format("电子签全域状态总览表 [{0}],员工为空!", info.getNumber()));
             }
             IFileTab iFileTab = FileTabFactory.getLocalInstance(ctx);
-            FileTabInfo fileTabInfo = iFileTab.getFileTabInfo("where person.id ='" + person.getId() + "'");
-            if (fileTabInfo == null) {
+            FileTabCollection fileTabCollection = iFileTab.getFileTabCollection("where person.id ='" + person.getId() + "'");
+            FileTabInfo  fileTabInfo = null;
+            if (fileTabCollection.isEmpty()) {
                 fileTabInfo = new FileTabInfo();
                 fileTabInfo.setPerson(person);
                 iFileTab.addnew(fileTabInfo);
+            }else {
+                fileTabInfo=fileTabCollection.get(0);
             }
             // 调用e签宝接口获取文件下载地址
             EsignHttpResponse response = EsignHttpUtil.getFile_download_url(ctx, signFlowId, 3600, info.getEfileId());
@@ -214,7 +218,8 @@ public class SyncSignedFilesUtil {
             EntityViewInfo viewInfo = EntityViewInfo.getInstance(filterInfo, null, null);
 
             //判断是否存在附件
-            if (iAttachment.exists(fileId)) {
+            if (iAttachment.exists(filterInfo)) {
+                System.out.println(filterInfo.toSql());
                 // 获取附件集合
                 AttachmentCollection attachmentCol = iAttachment.getAttachmentCollection(viewInfo);
                 ObjectUuidPK[] attachMentIds = new ObjectUuidPK[attachmentCol.size()];

+ 62 - 1
websrc/com/kingdee/eas/custom/esign/handler/ESignGlobalStatusOverviewListHandler.java

@@ -22,6 +22,7 @@ import com.kingdee.eas.custom.esign.tsign.hz.comm.EsignHttpResponse;
 import com.kingdee.eas.custom.esign.tsign.hz.exception.EsignException;
 import com.kingdee.eas.custom.esign.util.DownloaderUtil;
 import com.kingdee.eas.custom.esign.util.EsignHttpUtil;
+import com.kingdee.eas.custom.esign.util.SyncSignedFilesUtil;
 import com.kingdee.eas.hr.base.app.util.SHRBizBillAttachmentReverseUtils;
 import com.kingdee.shr.attachment.*;
 import com.kingdee.shr.attachment.AttachmentTypeEnum;
@@ -315,6 +316,14 @@ public class ESignGlobalStatusOverviewListHandler extends ListHandler {
         return null;
     }
 
+    /**
+     * 预览附件
+     * @param request
+     * @param response
+     * @param modelMap
+     * @return
+     * @throws SHRWebException
+     */
     public String previewAction(HttpServletRequest request, HttpServletResponse response, ModelMap modelMap) throws SHRWebException {
 
         BatchMessageTipsHeader batchMessageTipsHeader = new BatchMessageTipsHeader();
@@ -415,6 +424,58 @@ public class ESignGlobalStatusOverviewListHandler extends ListHandler {
         return null;
     }
 
+    /**
+     *  同步签署完成附件
+     * @param request
+     * @param response
+     * @param modelMap
+     * @return
+     * @throws SHRWebException
+     */
+    public String syncAttachmentsAction(HttpServletRequest request, HttpServletResponse response, ModelMap modelMap) throws SHRWebException {
+        BatchMessageTipsHeader batchMessageTipsHeader = new BatchMessageTipsHeader();
+        String billId = this.getBillId(request);
+        int failure = 0;
+        int success = 0;
+        try {
+            if (billId.indexOf(",") >= 0) {
+                throw new EsignException("请选择一行记录发起签署");
+            }
+            IESignGlobalStatusOverview globalStatusOverview = ESignGlobalStatusOverviewFactory.getLocalInstance(this.getCtx());
+            SelectorItemCollection selectorItemCollection = new SelectorItemCollection();
+            selectorItemCollection.add(new SelectorItemInfo("*"));
+            selectorItemCollection.add(new SelectorItemInfo("person.id"));
+            selectorItemCollection.add(new SelectorItemInfo("operator.id"));
+            ESignGlobalStatusOverviewInfo info = globalStatusOverview.getESignGlobalStatusOverviewInfo(new ObjectUuidPK(billId));
+            if (StringUtils.isBlank(info.getSignFlowId())) {
+                throw new EsignException("没有签署流程id");
+            }
+//            if (!info.isFivouchered()) {
+//                throw new EsignException("电子签全域状态总览表 [{0}],签署文件已经同步,请勿重复同步");
+//            }
+            SyncSignedFilesUtil.syncAttachmentsForEmpPage(this.getCtx(),billId);
+            BatchMessageTipsBody body = new BatchMessageTipsBody();
+            body.setMuitTipsState(Boolean.TRUE);
+            body.setMuitTipsMessage("触发同步成功");
+            body.setId(billId);
+            batchMessageTipsHeader.addResult(body);
+            success++;
+        } catch (EsignException e) {
+            e.printStackTrace();
+            throw new ShrWebBizException(e);
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw new ShrWebBizException(e);
+        }
+        batchMessageTipsHeader.setBillId(billId);
+        batchMessageTipsHeader.setFailureCount((success <= 0 ? 1 : 0));
+        batchMessageTipsHeader.setSuccessCount(success);
+        this.writeSuccessData(batchMessageTipsHeader);
+        return null;
+    }
+
+
+
     private void delAttachment(Context ctx, ESignGlobalStatusOverviewInfo info) throws BOSException, EASBizException {
         ISHRAttachmentExt SHRAttchExt = SHRAttachmentExtFactory.getLocalInstance(ctx);
         IAttachment attachment = AttachmentFactory.getLocalInstance(ctx);
@@ -466,7 +527,7 @@ public class ESignGlobalStatusOverviewListHandler extends ListHandler {
         ai.setSimpleName(extname);
         ai.setFile(content);
         ai.setIsShared(false);
-        ai.setNumber("files");
+        ai.setNumber(propertyName);
         ai.setSharedDesc(SHRWebResource.getString("com.kingdee.shr.base.syssetting.SHRSyssettingResource", "false"));
         int size = content.length;
         if (size < 1024) {

+ 3 - 0
websrc/com/kingdee/eas/custom/esign/osf/CallBackToOSFService.java

@@ -12,6 +12,7 @@ import com.kingdee.eas.custom.esign.ESignGlobalStatusOverviewFactory;
 import com.kingdee.eas.custom.esign.ESignGlobalStatusOverviewInfo;
 import com.kingdee.eas.custom.esign.IESignGlobalStatusOverview;
 import com.kingdee.eas.custom.esign.bizEnum.EsignStatusEnum;
+import com.kingdee.eas.custom.esign.util.SyncSignedFilesUtil;
 
 import java.util.Map;
 
@@ -161,11 +162,13 @@ public class CallBackToOSFService implements IHRMsfService {
             ESignGlobalStatusOverviewInfo info = collection.get(i);
             info.setEsignStatus(EsignStatusEnum.getEnum(Integer.parseInt(signFlowStatus)));
             info.setDescription(statusDescription);
+            SyncSignedFilesUtil.syncAttachmentsForEmpPage(ctx,info.getId().toString());
         }
         SelectorItemCollection selectorUpdatePartial = new SelectorItemCollection();
         selectorUpdatePartial.add(new SelectorItemInfo("esignStatus"));
         selectorUpdatePartial.add(new SelectorItemInfo("description"));
         globalStatusOverview.updatePartialBatchData(collection,selectorUpdatePartial);
+
         return map;
     }
 

+ 118 - 61
websrc/com/kingdee/eas/custom/esign/osf/Create_by_fileOSFService.java

@@ -5,11 +5,12 @@ import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
 import com.kingdee.bos.BOSException;
 import com.kingdee.bos.Context;
 import com.kingdee.bos.bsf.service.app.IHRMsfService;
 import com.kingdee.eas.common.EASBizException;
-
+import com.kingdee.eas.custom.esign.bizEnum.EsignStatusEnum;
 import com.kingdee.eas.custom.esign.tsign.hz.comm.EsignHttpResponse;
 import com.kingdee.eas.custom.esign.tsign.hz.exception.EsignException;
 import com.kingdee.eas.custom.esign.util.EsignConfig;
@@ -20,6 +21,7 @@ import java.net.URISyntaxException;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.concurrent.TimeUnit;
 
 /**
  * description: Create_by_fileOSFService <br>
@@ -28,48 +30,35 @@ import java.util.Set;
  * version: 1.0 <br>
  */
 public class Create_by_fileOSFService implements IHRMsfService {
+    private static final String SUCCESS_CODE = "0";
+    private static final String PREVIEW_OPERATION = "预览";
 
-    public static void main(String[] args) {
-        JSONObject jsonObject = JSON.parseObject("{\"tableName\":\"3-信息安全承诺书.pdf\",\"tableId\":\"4b19400154d1444e969bf69a6ce0c83c\",\"fields\":{\"49e2cabb3fff4e0090d580f7d4d6e0fc\":{\"name\":\"单行文本1\",\"dataType\":\"单行文本\",\"dataFormat\":\"undefined\",\"value\":\"大王大大\"},\"700825a785484185a6e3fd02e358792c\":{\"name\":\"工号\",\"dataType\":\"单行文本\",\"dataFormat\":\"undefined\",\"value\":\"1234534\"},\"a95f4a5d491d473cbba755a9bb84a04a\":{\"name\":\"日期1\",\"dataType\":\"Date\",\"dataFormat\":\"undefined\",\"value\":\"2024-12-03 00:00:00\"},\"35e09954d6aa41538bd27ffc42da59aa\":{\"name\":\"部门\",\"dataType\":\"String\",\"dataFormat\":\"undefined\",\"value\":\"HR产品处\"},\"df8743514be54648a1bc755cd51e315c\":{\"name\":\"多行文本1\",\"dataType\":\"String\",\"dataFormat\":\"undefined\",\"value\":\"4-1-3\"}}}");
-        for (Map.Entry<String, Object> fileEntry : jsonObject.entrySet()) {
-            JSONObject fieldObject = (JSONObject) fileEntry.getValue();
-
-        }
-    }
+    private static final int MAX_RETRY_COUNT = 20;
+    private static final int RETRY_INTERVAL_SECONDS = 3;
 
     @Override
     public Object process(Context context, Map  map) throws EASBizException, BOSException {
+
         String mack = (String) map.get("mack");
         String data = (String) map.get("data");
         Map<String, Object> resul = Maps.newHashMap();
         try {
             JSONObject jsonObject = JSON.parseObject(data);
             if ("preview".equals(mack)) {
-
                 EsignHttpResponse response = this.previewFile(context, jsonObject, "预览");
                 if (response.getStatus() >= 200 && response.getStatus() < 300) {
-                    JSONObject body = JSON.parseObject(response.getBody());
-                    if("0".equals(String.valueOf(body.get("code")))) {
-                        JSONObject jsonData = body.getJSONObject("data");
-                        String fileId = jsonData.getString("fileId");
-                        for (int i = 10; i > 0; i--) {
-                            EsignHttpResponse response1 = EsignHttpUtil.getFileStatus(context,fileId,"预览");
-                            if (response1.getStatus() >= 200 && response1.getStatus() < 300) {
-
-                            }
-                        }
-                    }
-                    resul.putAll(body);
+                    resul.putAll(this.processFileResponse(response,context));
                 } else {
                     resul.put("code", response.getStatus());
                     resul.put("message", "网络异常");
                     resul.put("data", null);
                 }
-
             } else {
                 Map<String, Object> signMap = Maps.newHashMap();
                 String sourceId = jsonObject.getString("sourceId");
                 String signFlowTitle = jsonObject.getString("signFlowTitle");
+                String personId = jsonObject.getString("personId");
+                String operatorId = jsonObject.getString("operatorId");
                 //文件
                 JSONObject templateInfo = jsonObject.getJSONObject("templateInfo");
                 //设置待签署文件信息
@@ -89,13 +78,113 @@ public class Create_by_fileOSFService implements IHRMsfService {
                 if (copiers.size() > 0) {
                     signMap.put("copiers", copiers);
                 }
+                //必须要存在签署文件才能签署
+                if(docs.size()>0) {
+                    EsignHttpResponse response = EsignHttpUtil.create_by_file(context, personId, operatorId, signFlowTitle, sourceId, JSON.toJSONString(signMap));
+                    if (response.getStatus() >= 200 && response.getStatus() < 300) {
+                        JSONObject body = JSON.parseObject(response.getBody());
+                        resul.putAll(body);
+                    } else {
+                        resul.put("code", response.getStatus());
+                        resul.put("message", "网络异常");
+                        resul.put("data", null);
+                    }
+                }
             }
-        } catch (EsignException | URISyntaxException e) {
+        } catch (EsignException | URISyntaxException  e) {
             e.printStackTrace();
         }
         return resul;
     }
 
+    /**
+     * 根据”填写模板生成文件“返回的文件id查询文件处理状态
+     * 需要阻塞等待这个状态变为2或者5才能调用发起签署接口
+     * @param response
+     * @param context
+     * @return
+     */
+    public Map<String, Object> processFileResponse(EsignHttpResponse response, Context context) {
+        Map<String, Object> result = Maps.newHashMap();
+        JSONObject body = JSON.parseObject(response.getBody());
+
+        if (!SUCCESS_CODE.equals(String.valueOf(body.get("code")))) {
+            result.putAll(body);
+            return result;
+        }
+
+        JSONObject jsonData = body.getJSONObject("data");
+        String fileId = jsonData.getString("fileId");
+        JSONObject pollData = pollFileDownloadUrl(context, fileId);
+
+        if (null!=pollData && StringUtils.isNotBlank(pollData.getString("fileDownloadUrl"))) {
+            jsonData.putAll(pollData);
+        }
+        result.putAll(body);
+        return result;
+    }
+
+    /**
+     * 阻塞循环调用获取文件信息接口
+     * @param context
+     * @param fileId
+     * @return
+     */
+    private JSONObject pollFileDownloadUrl(Context context, String fileId) {
+        for (int i = MAX_RETRY_COUNT; i > 0; i--) {
+            try {
+                JSONObject data = tryGetFileDownloadUrl(context, fileId);
+                if (null!=data && StringUtils.isNotBlank(data.getString("fileDownloadUrl"))) {
+                    return data;
+                }
+                TimeUnit.SECONDS.sleep(RETRY_INTERVAL_SECONDS);
+            } catch (InterruptedException e) {
+                Thread.currentThread().interrupt();
+                break;
+            } catch (Exception e) {
+                // 记录日志,继续重试
+               e.printStackTrace();
+            }
+        }
+        return null;
+    }
+
+    /**
+     * 等待这个状态变为2或者5才返回
+     *
+     * @param context
+     * @param fileId
+     * @return
+     */
+    private JSONObject tryGetFileDownloadUrl(Context context, String fileId)  {
+        try {
+            EsignHttpResponse response = EsignHttpUtil.getFileStatus(context, fileId, PREVIEW_OPERATION);
+
+            if (response.getStatus() < 200 || response.getStatus() >= 300) {
+                return null;
+            }
+
+            JSONObject responseBody = JSON.parseObject(response.getBody());
+            if (!SUCCESS_CODE.equals(String.valueOf(responseBody.get("code")))) {
+                return null;
+            }
+
+            JSONObject data = responseBody.getJSONObject("data");
+            String fileStatus = data.getString("fileStatus");
+            Set<String> COMPLETED_STATUS = Sets.newHashSet();
+            COMPLETED_STATUS.add("2");
+            COMPLETED_STATUS.add("5");
+            if (COMPLETED_STATUS.contains(fileStatus)) {
+                return data;
+            }
+        }catch (EsignException e){
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+
+
     /**
      * 设置待签署文件信息
      *
@@ -117,9 +206,9 @@ public class Create_by_fileOSFService implements IHRMsfService {
             String sourceId = jsonObject.getString("sourceId");
             EsignHttpResponse response = this.previewFile(context, fieldObject, sourceId);
             if (response.getStatus() >= 200 && response.getStatus() < 300) {
-                JSONObject body = JSON.parseObject(response.getBody());
+                Map<String,Object> body = this.processFileResponse(response,context);
                 if ("0".equals(String.valueOf(body.get("code")))) {
-                    JSONObject file = body.getJSONObject("data");
+                    JSONObject file = (JSONObject) body.get("data");
                     Map<String, Object> doc = Maps.newHashMap();
                     doc.put("fileId", file.get("fileId"));
                     doc.put("fileName", fileName);
@@ -159,6 +248,7 @@ public class Create_by_fileOSFService implements IHRMsfService {
     }
 
     /**
+     * 添加签署组织
      * @param context
      * @param orgSignerInfo
      * @param docs
@@ -225,6 +315,7 @@ public class Create_by_fileOSFService implements IHRMsfService {
     }
 
     /**
+     * 添加签署人
      * @param context
      * @param psnSignerInfo
      * @param docs
@@ -280,7 +371,7 @@ public class Create_by_fileOSFService implements IHRMsfService {
     }
 
     /**
-     * 签署方信息
+     * 处理签署方信息
      *
      * @param context
      * @param signs
@@ -345,38 +436,7 @@ public class Create_by_fileOSFService implements IHRMsfService {
 
 
     /**
-     * {
-     * "name": "信息安全承诺书.html",
-     * "id": "c964cb6a67dd40f4a92d4f8e67462e17",
-     * "fields": {
-     * "5b5d7563808d457ea125b000ff2a8d1d": {
-     * "name": "部门",
-     * "dataType": "单行文本",
-     * "value": null
-     * },
-     * "5fcd7b97621c4cd1a5f514e7f06cb0da": {
-     * "name": "工号",
-     * "dataType": "单行文本",
-     * "value": null
-     * }
-     * }
-     * {
-     * "docTemplateId":"8726f6b***03a56d",
-     * "fileName":"某公司的交易协议签署文件",
-     * "components":[
-     * {
-     * "componentId":"59af7766***36ef41b",
-     * "componentKey":"",
-     * "componentValue":"这里是填充的文本"
-     * },
-     * {
-     * "componentId":"7315e9af**72d2dac40",
-     * "componentKey":"",
-     * "componentValue":"2022/01/01"
-     * }
-     * ]
-     * }
-     *
+     * 根据传入数据调用 ”填写模板生成文件“ 接口
      * @param jsonObject
      * @return
      */
@@ -403,9 +463,6 @@ public class Create_by_fileOSFService implements IHRMsfService {
         }
         map.put("components", components);
         EsignHttpResponse response = EsignHttpUtil.createByDocTemplate(context, JSON.toJSONString(map), sourceId);
-        //html 文件需要等待转换完成
-
-
         return response;
     }