| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487 |
- package com.kingdee.eas.custom.esign.osf;
- import com.alibaba.fastjson.JSON;
- 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;
- import com.kingdee.eas.custom.esign.util.EsignHttpUtil;
- import org.apache.commons.lang3.StringUtils;
- 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>
- * date: 28/11/2025 上午 9:46 <br>
- * author: lhbj <br>
- * version: 1.0 <br>
- */
- public class Create_by_fileOSFService implements IHRMsfService {
- private static final String SUCCESS_CODE = "0";
- private static final String PREVIEW_OPERATION = "预览";
- 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)) {
- for (Map.Entry<String, Object> fileEntry : jsonObject.entrySet()) {
- JSONObject fieldObject = (JSONObject) fileEntry.getValue();
- EsignHttpResponse response = this.previewFile(context, fieldObject, "预览");
- if (response.getStatus() >= 200 && response.getStatus() < 300) {
- 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");
- //设置待签署文件信息
- try {
- List<Map<String, Object>> docs = this.addDocs(context, jsonObject, templateInfo);
- signMap.put("docs", docs);
- }catch (EsignException e){
- e.printStackTrace();
- resul.putAll(JSON.parseObject(e.getMessage()));
- }
- List<Map<String, Object>> docs = (List<Map<String, Object>>) signMap.get("docs");
- if(null!=docs) {
- //签署流程配置项
- Map<String, Object> signFlowConfig = this.addSignFlowConfig(context, signFlowTitle, jsonObject);
- signMap.put("signFlowConfig", signFlowConfig);
- //签署方信息
- JSONObject signInfo = jsonObject.getJSONObject("signInfo");
- JSONArray signs = signInfo.getJSONArray("signers");
- List<Map<String, Object>> signers = this.addSigners(context, signs, docs, sourceId);
- signMap.put("signers", signers);
- //抄送方信息
- JSONArray copis = signInfo.getJSONArray("copiers");
- List<Map<String, Object>> copiers = this.addCopiers(context, copis);
- if (copiers.size() > 0) {
- signMap.put("copiers", copiers);
- }
- //必须要存在签署文件才能签署
- if ( docs.size() > 0) {
- EsignHttpResponse response = EsignHttpUtil.create_by_file(context, personId, signFlowTitle,operatorId , 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) {
- 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;
- }
- /**
- * 设置待签署文件信息
- *
- * @param context
- * @param jsonObject
- * @param templateInfo
- * @return
- * @throws EsignException
- */
- public List<Map<String, Object>> addDocs(Context context, JSONObject jsonObject, JSONObject templateInfo) throws EsignException {
- //设置待签署文件信息
- Map<String, Object> resul = Maps.newHashMap();
- List<Map<String, Object>> docs = Lists.newArrayList();
- for (Map.Entry<String, Object> fileEntry : templateInfo.entrySet()) {
- JSONObject fieldObject = (JSONObject) fileEntry.getValue();
- String docTemplateId = fieldObject.getString("id");
- String fileName = fieldObject.getString("name");
- Object order = fieldObject.get("order");
- String sourceId = jsonObject.getString("sourceId");
- EsignHttpResponse response = this.previewFile(context, fieldObject, sourceId);
- resul.put("id",docTemplateId);
- resul.put("name",fileName);
- if (response.getStatus() >= 200 && response.getStatus() < 300) {
- Map<String,Object> body = this.processFileResponse(response,context);
- if ("0".equals(String.valueOf(body.get("code")))) {
- JSONObject file = (JSONObject) body.get("data");
- Map<String, Object> doc = Maps.newHashMap();
- doc.put("fileId", file.get("fileId"));
- doc.put("fileName", fileName);
- if (null != order) {
- doc.put("order", Integer.parseInt(String.valueOf(order)));
- }
- docs.add(doc);
- } else {
- //文件模板生成失败
- resul.putAll(body);
- throw new EsignException(JSON.toJSONString(resul));
- }
- } else {
- throw new EsignException(JSON.toJSONString(response));
- }
- }
- return docs;
- }
- /**
- * 抄送方信息
- *
- * @param copis
- * @return
- */
- public List<Map<String, Object>> addCopiers(Context context, JSONArray copis) {
- List<Map<String, Object>> copiers = Lists.newArrayList();
- for (int i = 0; i < copis.size(); i++) {
- JSONObject cop = copis.getJSONObject(i);
- Map<String, Object> copierPsn = Maps.newHashMap();
- Map<String, Object> copierPsnInfo = Maps.newHashMap();
- copierPsnInfo.put("psnAccount", cop.getString("psnAccount"));
- copierPsn.put("copierPsnInfo", copierPsnInfo);
- copiers.add(copierPsn);
- }
- return copiers;
- }
- /**
- * 添加签署组织
- * @param context
- * @param orgSignerInfo
- * @param docs
- * @param sourceId
- * @return
- * @throws EsignException
- * @throws URISyntaxException
- */
- public Map<String, Object> addOrgSignerInfo(Context context, JSONObject orgSignerInfo, List<Map<String, Object>> docs, String sourceId) throws EsignException, URISyntaxException {
- Map<String, Object> resul = Maps.newHashMap();
- Map<String, Object> signMapInfo = Maps.newHashMap();
- Map<String, Object> orgPsnSignMap = Maps.newHashMap();
- String orgName = orgSignerInfo.getString("orgName");
- EsignHttpResponse response = EsignHttpUtil.getOrgIdentity_infoByOrgName(context, orgName);
- if (response.getStatus() >= 200 && response.getStatus() < 300) {
- JSONObject body = JSON.parseObject(response.getBody());
- if ("0".equals(String.valueOf(body.get("code")))) {
- JSONObject orgPsn = body.getJSONObject("data");
- String orgId = orgPsn.getString("orgId");
- orgName = orgPsn.getString("orgName");
- orgPsnSignMap.put("orgId", orgId);
- orgPsnSignMap.put("orgName", orgName);
- orgPsnSignMap.put("orgInfo", orgPsn.getJSONObject("orgInfo"));
- } else {
- //失败
- resul.putAll(body);
- throw new EsignException(JSON.toJSONString(resul));
- }
- } else {
- throw new EsignException("网络异常:" + JSON.toJSONString(response));
- }
- Integer signOrder = orgSignerInfo.getInteger("signOrder");
- //设置签署方的签署顺序
- if (null != signOrder) {
- Map<String, Object> signConfig = Maps.newHashMap();
- signConfig.put("signOrder", signOrder);
- signMapInfo.put("signConfig", signConfig);
- }
- signMapInfo.put("orgSignerInfo", orgPsnSignMap);
- //设置签署方的通知方式
- String noticeTypes = orgSignerInfo.getString("noticeTypes");
- Map<String, String> noticeConfig = Maps.newHashMap();
- if (StringUtils.isNotBlank(noticeTypes)) {
- noticeConfig.put("noticeTypes", noticeTypes);
- } else {
- noticeConfig.put("noticeTypes", "1,2");
- }
- signMapInfo.put("noticeConfig", noticeConfig);
- //签署区信息
- List<Map<String, Object>> signFields = Lists.newArrayList();
- for (Map<String, Object> doc : docs) {
- Map<String, Object> field = Maps.newHashMap();
- field.put("fileId", doc.get("fileId"));
- field.put("customBizNum", sourceId);
- field.put("signFieldType", 0);
- //签章区配置项(指定signFieldType为 0 - 签章区时,该参数为必传项)
- Map<String, Object> normalSignFieldConfig = Maps.newHashMap();
- normalSignFieldConfig.put("freeMode", true);
- field.put("normalSignFieldConfig", normalSignFieldConfig);
- signFields.add(field);
- }
- signMapInfo.put("signFields", signFields);
- signMapInfo.put("signerType", 1);
- return signMapInfo;
- }
- /**
- * 添加签署人
- * @param context
- * @param psnSignerInfo
- * @param docs
- * @param sourceId
- * @return
- * @throws EsignException
- * @throws URISyntaxException
- */
- public Map<String, Object> addPsnSignerInfo(Context context, JSONObject psnSignerInfo, List<Map<String, Object>> docs, String sourceId) throws EsignException, URISyntaxException {
- Map<String, Object> resul = Maps.newHashMap();
- Map<String, Object> signMapInfo = Maps.newHashMap();
- Map<String, Object> orgPsnSignMap = Maps.newHashMap();
- //个人签署方信息
- String psnAccount = psnSignerInfo.getString("psnAccount");
- String psnName = psnSignerInfo.getString("psnName");
- Integer signOrder = psnSignerInfo.getInteger("signOrder");
- //设置签署方的签署顺序
- if (null != signOrder) {
- Map<String, Object> signConfig = Maps.newHashMap();
- signConfig.put("signOrder", signOrder);
- signMapInfo.put("signConfig", signConfig);
- }
- orgPsnSignMap.put("psnAccount", psnAccount);
- Map<String, String> psnInfo = Maps.newHashMap();
- psnInfo.put("psnName", psnName);
- orgPsnSignMap.put("psnInfo", psnInfo);
- //个人签署方信息
- signMapInfo.put("psnSignerInfo", orgPsnSignMap);
- //设置签署方的通知方式
- String noticeTypes = psnSignerInfo.getString("noticeTypes");
- Map<String, String> noticeConfig = Maps.newHashMap();
- if (StringUtils.isNotBlank(noticeTypes)) {
- noticeConfig.put("noticeTypes", noticeTypes);
- } else {
- noticeConfig.put("noticeTypes", "1,2");
- }
- signMapInfo.put("noticeConfig", noticeConfig);
- //签署区信息
- List<Map<String, Object>> signFields = Lists.newArrayList();
- for (Map<String, Object> doc : docs) {
- Map<String, Object> field = Maps.newHashMap();
- field.put("fileId", doc.get("fileId"));
- field.put("customBizNum", sourceId);
- field.put("signFieldType", 0);
- //签章区配置项(指定signFieldType为 0 - 签章区时,该参数为必传项)
- Map<String, Object> normalSignFieldConfig = Maps.newHashMap();
- normalSignFieldConfig.put("freeMode", true);
- field.put("normalSignFieldConfig", normalSignFieldConfig);
- signFields.add(field);
- }
- signMapInfo.put("signFields", signFields);
- signMapInfo.put("signerType", 0);
- return signMapInfo;
- }
- /**
- * 处理签署方信息
- *
- * @param context
- * @param signs
- * @param docs
- * @param sourceId
- * @return
- * @throws EsignException
- * @throws URISyntaxException
- */
- public List<Map<String, Object>> addSigners(Context context, JSONArray signs, List<Map<String, Object>> docs, String sourceId) throws EsignException, URISyntaxException {
- List<Map<String, Object>> signers = Lists.newArrayList();
- for (int i = 0; i < signs.size(); i++) {
- Map<String, Object> signMapInfo = Maps.newHashMap();
- JSONObject sign = signs.getJSONObject(i);
- Map<String, Object> orgPsnSignMap = Maps.newHashMap();
- JSONObject orgSignerInfo = sign.getJSONObject("orgSignerInfo");
- JSONObject psnSignerInfo = sign.getJSONObject("psnSignerInfo");
- //企业/机构签署方信息
- if (null != orgSignerInfo) {
- signMapInfo = addOrgSignerInfo(context, orgSignerInfo, docs, sourceId);
- } else {
- //个人签署方信息
- signMapInfo = addPsnSignerInfo(context, psnSignerInfo, docs, sourceId);
- }
- signers.add(signMapInfo);
- }
- return signers;
- }
- /**
- * 签署流程配置项
- *
- * @param context
- * @param signFlowTitle
- * @param jsonObject
- * @return
- */
- public Map<String, Object> addSignFlowConfig(Context context, String signFlowTitle, JSONObject jsonObject) {
- Map<String, Object> signFlowConfig = Maps.newHashMap();
- signFlowConfig.put("signFlowTitle", signFlowTitle);
- Boolean autoStart = jsonObject.getBoolean("autoStart");
- if (null != autoStart) {
- signFlowConfig.put("autoStart", autoStart);
- } else {
- signFlowConfig.put("autoStart", true);
- }
- Boolean autoFinish = jsonObject.getBoolean("autoFinish");
- if (null != autoFinish) {
- signFlowConfig.put("autoFinish", autoFinish);
- } else {
- signFlowConfig.put("autoFinish", true);
- }
- String notifyUrl = jsonObject.getString("notifyUrl");
- if (null != notifyUrl) {
- signFlowConfig.put("notifyUrl", notifyUrl);
- } else {
- notifyUrl = EsignConfig.getInstance().get("notifyUrl");
- signFlowConfig.put("notifyUrl", notifyUrl);
- }
- return signFlowConfig;
- }
- /**
- * 根据传入数据调用 ”填写模板生成文件“ 接口
- * @param jsonObject
- * @return
- */
- public EsignHttpResponse previewFile(Context context, JSONObject jsonObject, String sourceId) throws EsignException {
- String docTemplateId = jsonObject.getString("id");
- String fileName = jsonObject.getString("name");
- if (StringUtils.isBlank(docTemplateId)) {
- docTemplateId = jsonObject.getString("tableId");
- }
- if (StringUtils.isBlank(fileName)) {
- fileName = jsonObject.getString("tableName");
- }
- Map<String, Object> map = Maps.newHashMap();
- map.put("docTemplateId", docTemplateId);
- map.put("fileName", fileName);
- List<Map<String, Object>> components = Lists.newArrayList();
- JSONObject fields = jsonObject.getJSONObject("fields");
- for (Map.Entry<String, Object> field : fields.entrySet()) {
- Map<String, Object> component = Maps.newHashMap();
- component.put("componentId", field.getKey());
- JSONObject fieldInfo = (JSONObject) field.getValue();
- component.put("componentValue", fieldInfo.get("value"));
- components.add(component);
- }
- map.put("components", components);
- EsignHttpResponse response = EsignHttpUtil.createByDocTemplate(context, JSON.toJSONString(map), sourceId);
- return response;
- }
- }
|