---
source: "https://weapp.eteams.cn/build/techdoc/wdoc/index.html#/public/doc/6a668e35-fe81-46a8-82fb-de11ce5e2039"
title: "电子用印二开口子说明文档"
---

最低基线支持：20241201

## 需求背景和应用场景：

目前有一些客户想要在E10中使用电子用印功能，但是使用的签章系统不是E10标准支持的，就无法正常在E10中集成使用；所以将电子用印的功能开口子出来，如果有想要集成的签章系统，不需要总部进行处理，项目或者客户也可以通过ecode二开来自行进行支持。

## 1、服务商钩子

> 钩子唯一标识code：SIGN\_PLATFORM\_TYPE\_HOOK

**1.1 功能说明：**

用于标识当前二开集成对接的签章系统类型，可以在绑定服务中选择到当前集成的服务商类型

**1.2 参数说明：**

该接口无参数

**1.3 响应说明：**

返回值是List\<SignPlatformEntity\>，SignPlatformEntity对象的定义如下：

| 参数名 | 类型 | 说明 |
| --- | --- | --- |
| id | int | 服务商id（需要保证id唯一，为保证不跟标准冲突，id需要大于1000，例如：10001） |
| type | String | 服务商类型（保证唯一，例如：qiyuesuo，esign，docusign） |
| name | String | 服务商名称（例如：契约锁，e签宝） |
| labelId | long | 服务商名称多语言id |

**1.4 示例代码：**

```
package com.weaver.seconddev.signcenter.fadada.reghook;

public class PlatformConstant {
    public static final int id = 10001;
    public static final String type = "fadada-test";
    public static final String name = "法大大-测试";
    public static final long  labelId =  0;

    public static final int  serverType =  1;//服务类型，0：公有云，1：私有云

    public static final String signUrlFieldName = "CF_signUrl_fadada";
    public static final String openUrlFieldName = "CF_openUrl_fadada";
    public static final String appIdFieldName = "CF_appId_fadada";
    public static final String secretFieldName = "CF_appKey_fadada";
    public static final String openSignFieldName = "CF_openSign_fadada";
}
```

```
package com.weaver.seconddev.signcenter.fadada.reghook.platform;

import com.alibaba.fastjson.JSON;
import com.weaver.loom.context.annotation.WeaHookReg;
import com.weaver.loom.context.domain.AppInfo;
import com.weaver.loom.context.domain.WeaHookRequest;
import com.weaver.loom.context.domain.WeaHookResponse;
import com.weaver.loom.context.register.RegHookEvent;
import com.weaver.seconddev.signcenter.fadada.reghook.PlatformConstant;
import com.weaver.signcenter.entity.platform.SignPlatformEntity;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.List;

@WeaHookReg(code = "SIGN_PLATFORM_TYPE_HOOK", order = 0)
public class SignPlatformRegHook extends RegHookEvent {
    protected static final Logger log = LoggerFactory.getLogger(SignPlatformRegHook.class);

    @Override
    public WeaHookResponse handle(WeaHookRequest request, WeaHookResponse response, AppInfo appInfo) throws Exception {

        Object result = response.getResult();
        List<SignPlatformEntity> list;
        if(result == null || !(result instanceof List)){
            list = new ArrayList<>();
        }else{
            list = (List)result;
        }
        SignPlatformEntity signPlatform = new SignPlatformEntity(PlatformConstant.id, PlatformConstant.type, PlatformConstant.name, PlatformConstant.labelId);
        list.add(signPlatform);
        response.setResult(list);
        log.info("SignPlatformRegHook--response:{}", JSON.toJSONString(response));
        return response;
    }

    @Override
    public void rollBack(WeaHookRequest request, WeaHookResponse response, AppInfo appInfo) throws Exception {
        return;
    }
}
```

## 2、绑定设置二开钩子

#### 2.1 绑定服务表单配置项钩子

> 钩子唯一标识code：SIGN\_SERVER\_FORM\_ITEM\_HOOK

**2.1.1 功能说明：**

用来配置二开的服务商绑定设置中自定义的配置项

**2.1.2 参数说明：**

该口子只传递了一个参数：items，类型是：Map\<String, WeaFormItem\>

| 参数名 | 类型 | 说明 |
| --- | --- | --- |
| items | Map\<String, WeaFormItem\> | 表单item配置信息 |

**2.1.3 响应说明：**

返回值也是Map\<String, WeaFormItem\>类型，只需要将自己新增的自定义参数加到入参的Map中，然后设置到response中即可

**2.1.4 示例代码：**

```
package com.weaver.seconddev.signcenter.fadada.reghook.server;

import com.alibaba.fastjson.JSON;
import com.weaver.common.component.form.item.WeaFormItem;
import com.weaver.common.component.form.item.WeaFormItemType;
import com.weaver.common.i18n.label.SystemEnv;
import com.weaver.loom.context.annotation.WeaHookReg;
import com.weaver.loom.context.domain.AppInfo;
import com.weaver.loom.context.domain.WeaHookRequest;
import com.weaver.loom.context.domain.WeaHookResponse;
import com.weaver.loom.context.register.RegHookEvent;
import com.weaver.seconddev.signcenter.fadada.reghook.PlatformConstant;
import com.weaver.seconddev.signcenter.fadada.reghook.callback.SignCallbackEntityRegHook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.HashMap;
import java.util.Map;

@WeaHookReg(code = "SIGN_SERVER_FORM_ITEM_HOOK", order = 0)
public class SignServerItemHook extends RegHookEvent {

    protected static final Logger log = LoggerFactory.getLogger(SignCallbackEntityRegHook.class);

    @Override
    public WeaHookResponse handle(WeaHookRequest hookRequest, WeaHookResponse response, AppInfo appInfo) throws Exception {
        Map<String, Object> params = hookRequest.getParams();
        log.info("SignServerItemHook--hookRequest:{}", JSON.toJSONString(hookRequest));

        Object result = response.getResult();
        Map<String, WeaFormItem> items;
        if(result != null && result instanceof Map){
            items = (Map<String, WeaFormItem>) result;
        }else{
            items = (Map<String, WeaFormItem>) params.get("items");
        }

        //开放平台地址
        WeaFormItem item = new WeaFormItem(WeaFormItemType.INPUT);
        item.setRequired(true);
        item.setPlaceholder(SystemEnv.getHtmlLabelName(84383, "请输入开放平台地址"));
        items.put(PlatformConstant.openUrlFieldName, item);

        //应用id
        item = new WeaFormItem(WeaFormItemType.INPUT);
        item.setRequired(true);
        item.setPlaceholder(SystemEnv.getHtmlLabelName(245894, "请输入应用ID"));
        items.put(PlatformConstant.appIdFieldName, item);

        //应用seceret
        item = new WeaFormItem(WeaFormItemType.INPUT);
        item.setRequired(true);
        item.setPlaceholder(SystemEnv.getHtmlLabelName(245895, "请输入应用seceret"));
        items.put(PlatformConstant.secretFieldName, item);

        //应用seceret
        item = new WeaFormItem(WeaFormItemType.INPUT);
        item.setRequired(true);
        item.setPlaceholder(SystemEnv.getHtmlLabelName(0, "请输入签署平台地址"));
        items.put(PlatformConstant.signUrlFieldName, item);

        Map<String, Object> otherParams = new HashMap<>();
        otherParams.put("size", "sm");
        //使用TAB页打开文件页面
        item = new WeaFormItem(WeaFormItemType.SWITCH);
        item.setOtherParams(otherParams);
        items.put(PlatformConstant.openSignFieldName, item);

        response.setResult(items);
        return response;
    }

    @Override
    public void rollBack(WeaHookRequest request, WeaHookResponse response, AppInfo appInfo) throws Exception {

    }
}
```

#### 2.2 绑定服务表单布局钩子

> 钩子唯一标识code：SIGN\_SERVER\_FORM\_LAYOUT\_HOOK

**2.2.1 功能说明：**

用来配置二开的服务商绑定设置中自定义的布局

**2.2.2 参数说明：**

该口子只传递了一个参数：layouts，类型是：List\<List\<WeaFormLayout\>\>

| 参数名 | 类型 | 说明 |
| --- | --- | --- |
| layouts | List\<List\<WeaFormLayout\>\> | 表单布局layout信息 |

**2.2.3 响应说明：**

返回值也是List\<List\<WeaFormLayout\>\>类型，只需要将自己新增的自定义参数加到入参的layouts中，然后设置到response中即可

**2.2.4 示例代码：**

```
package com.weaver.seconddev.signcenter.fadada.reghook.server;

import com.alibaba.fastjson.JSON;
import com.weaver.common.component.form.layout.WeaFormLayout;
import com.weaver.loom.context.annotation.WeaHookReg;
import com.weaver.loom.context.domain.AppInfo;
import com.weaver.loom.context.domain.WeaHookRequest;
import com.weaver.loom.context.domain.WeaHookResponse;
import com.weaver.loom.context.register.RegHookEvent;
import com.weaver.seconddev.signcenter.fadada.reghook.PlatformConstant;
import com.weaver.seconddev.signcenter.fadada.reghook.callback.SignCallbackEntityRegHook;
import com.weaver.seconddev.signcenter.fadada.util.ComponentUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Collections;
import java.util.List;
import java.util.Map;

@WeaHookReg(code = "SIGN_SERVER_FORM_LAYOUT_HOOK", order = 0)
public class SignServerLayoutHook extends RegHookEvent {

    protected static final Logger log = LoggerFactory.getLogger(SignCallbackEntityRegHook.class);

    @Override
    public WeaHookResponse handle(WeaHookRequest hookRequest, WeaHookResponse response, AppInfo appInfo) throws Exception {
        Map<String, Object> params = hookRequest.getParams();
        log.info("SignServerLayoutHook--hookRequest:{}", JSON.toJSONString(hookRequest));

        Object result = response.getResult();
        List<List<WeaFormLayout>> layouts;
        if(result != null && result instanceof List){
            layouts = (List<List<WeaFormLayout>>) result;
        }else{
            layouts = (List) params.get("layouts");
        }

        layouts.add(Collections.singletonList(ComponentUtils.createLayout(PlatformConstant.openUrlFieldName, "法大大开放平台地址", new String[]{PlatformConstant.openUrlFieldName}, 6, false, "", "", "")));
        layouts.add(Collections.singletonList(ComponentUtils.createLayout(PlatformConstant.appIdFieldName, "法大大应用ID", new String[]{PlatformConstant.appIdFieldName}, 6, false, "", "", "")));
        layouts.add(Collections.singletonList(ComponentUtils.createLayout(PlatformConstant.secretFieldName, "法大大应用seceret", new String[]{PlatformConstant.secretFieldName}, 6, false, "", "", "")));
        layouts.add(Collections.singletonList(ComponentUtils.createLayout(PlatformConstant.signUrlFieldName, "法大大签署平台地址", new String[]{PlatformConstant.signUrlFieldName}, 6, false, "", "", "")));
        layouts.add(Collections.singletonList(ComponentUtils.createLayout(PlatformConstant.openSignFieldName, "法大大是否开启", new String[]{PlatformConstant.openSignFieldName}, 6, false, "", "", "")));

        response.setResult(layouts);
        return response;
    }

    @Override
    public void rollBack(WeaHookRequest request, WeaHookResponse response, AppInfo appInfo) throws Exception {

    }
}
```

#### 2.3 绑定服务表单联动钩子

> 钩子唯一标识code：SIGN\_SERVER\_FORM\_CASCADE\_RULES\_HOOK

**2.3.1 功能说明：**

用来配置二开的服务商绑定设置中自定义的联动规则

**2.3.2 参数说明：**

该口子只传递了一个参数：rules，类型是：List\<SignCascadeRules\>

| 参数名 | 类型 | 说明 |
| --- | --- | --- |
| rules | List\<SignCascadeRules\> | 表单联动规则信息 |

**2.3.3 响应说明：**

返回值也是List\<SignCascadeRules\>类型，只需要将自己新增的自定义参数加到入参的rules中，然后设置到response中即可

**2.3.4 示例代码：**

```
package com.weaver.seconddev.signcenter.fadada.reghook.server;

import com.alibaba.fastjson.JSON;
import com.weaver.loom.context.annotation.WeaHookReg;
import com.weaver.loom.context.domain.AppInfo;
import com.weaver.loom.context.domain.WeaHookRequest;
import com.weaver.loom.context.domain.WeaHookResponse;
import com.weaver.loom.context.register.RegHookEvent;
import com.weaver.seconddev.signcenter.fadada.reghook.PlatformConstant;
import com.weaver.seconddev.signcenter.fadada.reghook.callback.SignCallbackEntityRegHook;
import com.weaver.seconddev.signcenter.fadada.util.Util;
import com.weaver.signcenter.entity.form.RuleBase;
import com.weaver.signcenter.entity.form.SignCascadeRules;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@WeaHookReg(code = "SIGN_SERVER_FORM_CASCADE_RULES_HOOK", order = 0)
public class SignServerCasecadesHook extends RegHookEvent {

    protected static final Logger log = LoggerFactory.getLogger(SignCallbackEntityRegHook.class);

    @Override
    public WeaHookResponse handle(WeaHookRequest hookRequest, WeaHookResponse response, AppInfo appInfo) throws Exception {
        Map<String, Object> params = hookRequest.getParams();
        log.info("SignServerCasecadesHook--hookRequest:{}", JSON.toJSONString(hookRequest));

        Object result = response.getResult();
        List<SignCascadeRules> rules;
        if(result != null && result instanceof List){
            rules = (List<SignCascadeRules>) result;
        }else{
            rules = (List<SignCascadeRules>) params.get("rules");
        }

        //设置规则
        SignCascadeRules signCascadeRule = new SignCascadeRules();
        List<RuleBase> conditions = new ArrayList<RuleBase>();
        List<RuleBase> actions = new ArrayList<RuleBase>();
        Map layoutProps = new HashMap();
        conditions = new ArrayList<RuleBase>();

        RuleBase condition = new RuleBase("baseInfo", "platformType", RuleBase.ATTRIBUTE_VALUE, RuleBase.CONDITIONTYPE_2, Util.null2String(PlatformConstant.id));
        conditions.add(condition);

        actions = new ArrayList<RuleBase>();

        layoutProps = new HashMap();
        layoutProps.put("hide", true);
        RuleBase action = new RuleBase("baseInfo", "", PlatformConstant.openUrlFieldName, null, layoutProps, null, null);
        actions.add(action);

        layoutProps = new HashMap();
        layoutProps.put("hide", true);
        action = new RuleBase("baseInfo", "", PlatformConstant.appIdFieldName, null, layoutProps, null, null);
        actions.add(action);

        layoutProps = new HashMap();
        layoutProps.put("hide", true);
        action = new RuleBase("baseInfo", "", PlatformConstant.secretFieldName, null, layoutProps, null, null);
        actions.add(action);

        layoutProps = new HashMap();
        layoutProps.put("hide", true);
        action = new RuleBase("baseInfo", "", PlatformConstant.signUrlFieldName, null, layoutProps, null, null);
        actions.add(action);

        layoutProps = new HashMap();
        layoutProps.put("hide", true);
        action = new RuleBase("baseInfo", "", PlatformConstant.openSignFieldName, null, layoutProps, null, null);
        actions.add(action);

        signCascadeRule.setConditions(conditions);
        signCascadeRule.setRelation(SignCascadeRules.RELATION_1);
        signCascadeRule.setActions(actions);
        signCascadeRule.setRelation("every");
        rules.add(signCascadeRule);

        response.setResult(rules);
        return response;
    }

    @Override
    public void rollBack(WeaHookRequest request, WeaHookResponse response, AppInfo appInfo) throws Exception {

    }
}
```

#### 2.4 绑定服务表单数据钩子

> 钩子唯一标识code：SIGN\_SERVER\_FORM\_DATA\_HOOK

**2.4.1 功能说明：**

用来配置二开的服务商绑定设置中自定义的数据（如果数据的格式不需要特殊处理，不用设置这个钩子的埋点）

**2.4.2 参数说明：**

该口子传递了绑定设置的所有配置的值，类型是：Map\<String, Object\>，其中key是item中定义key

**2.4.3 响应说明：**

返回值也是Map\<String, Object\>类型，只需要将需要自定义参数的处理之后，重新设置到Map中，然后设置到response中即可

**2.4.4 示例代码：**

```
package com.weaver.seconddev.signcenter.fadada.reghook.server;

import com.alibaba.fastjson.JSON;
import com.weaver.common.component.form.item.WeaFormItem;
import com.weaver.common.component.form.item.WeaFormItemType;
import com.weaver.common.i18n.label.SystemEnv;
import com.weaver.loom.context.annotation.WeaHookReg;
import com.weaver.loom.context.domain.AppInfo;
import com.weaver.loom.context.domain.WeaHookRequest;
import com.weaver.loom.context.domain.WeaHookResponse;
import com.weaver.loom.context.register.RegHookEvent;
import com.weaver.seconddev.signcenter.fadada.reghook.PlatformConstant;
import com.weaver.seconddev.signcenter.fadada.reghook.callback.SignCallbackEntityRegHook;
import com.weaver.seconddev.signcenter.fadada.util.Util;
import com.weaver.signcenter.entity.form.SignCascadeRules;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@WeaHookReg(code = "SIGN_SERVER_FORM_DATA_HOOK", order = 0)
public class SignServerDataHook extends RegHookEvent {

    protected static final Logger log = LoggerFactory.getLogger(SignCallbackEntityRegHook.class);

    @Override
    public WeaHookResponse handle(WeaHookRequest hookRequest, WeaHookResponse response, AppInfo appInfo) throws Exception {

       Object result = response.getResult();
        Map<String, Object> params;
        if(result != null && result instanceof Map){
            params = (Map<String, Object>) result;
        }else{
            params = hookRequest.getParams();
        }

        log.info("SignServerItemHook--hookRequest:{}", JSON.toJSONString(hookRequest));
        String csVal = Util.null2String(params.get(PlatformConstant.openSignFieldName));
        if("true".equals(csVal) || "1".equals(csVal)){
            params.put(PlatformConstant.openSignFieldName, 1);
        }else{
            params.put(PlatformConstant.openSignFieldName, 0);
        }
        response.setResult(params);
        return response;
    }

    @Override
    public void rollBack(WeaHookRequest request, WeaHookResponse response, AppInfo appInfo) throws Exception {

    }
}
```

## 3、电子用印集成配置表单钩子

> 钩子唯一标识code：SIGN\_ELECTRONIC\_FORM\_HOOK+ "\_" + PlatformConstant.type + "\_" + PlatformConstant.serverType

**3.1 功能说明：**

用于自定义二开服务商的电子用印集成配置表单配置项

**3.2 参数说明：**

| 参数名 | 类型 | 说明 |
| --- | --- | --- |
| settingData | Map | 配置数据，包括集成配置的数据 |
| defaultSignWeaTab | SignWeaTab | 表单配置项信息，包括每个tab页的，form，item，layout，data，cascades数据 |
| globalConfig | GlobalConfig | 当前服务商的全局配置信息 |

**3.3 响应说明：**

返回值是SignWeaTab，可以将参数中的defaultSignWeaTab对象，将其中配置项调整之后，设置到response中，SignWeaTab对象的定义如下：

| 参数名 | 类型 | 说明 |
| --- | --- | --- |
| tabId | String | tab页签的id |
| tabName | String | tab页签的名称 |
| form | ScWeaForm | tab页签中的表单信息 |
| child | List\<SignWeaTab\> | tab页签的子页签 |

**3.4 示例代码：**

```
package com.weaver.seconddev.signcenter.fadada.reghook.form;

import com.alibaba.fastjson.JSON;
import com.weaver.common.component.form.item.WeaFormItem;
import com.weaver.common.component.form.item.WeaFormItemType;
import com.weaver.common.component.form.layout.WeaFormLayout;
import com.weaver.loom.context.annotation.WeaHookReg;
import com.weaver.loom.context.domain.AppInfo;
import com.weaver.loom.context.domain.WeaHookRequest;
import com.weaver.loom.context.domain.WeaHookResponse;
import com.weaver.loom.context.register.RegHookEvent;
import com.weaver.seconddev.signcenter.fadada.reghook.PlatformConstant;
import com.weaver.seconddev.signcenter.fadada.reghook.contractList.SignContractListButtonRegHook;
import com.weaver.seconddev.signcenter.fadada.util.ComponentUtils;
import com.weaver.seconddev.signcenter.fadada.util.Util;
import com.weaver.signcenter.api.entity.component.ScWeaForm;
import com.weaver.signcenter.constants.SigncenterBrowserConstants;
import com.weaver.signcenter.entity.customfield.CustomField;
import com.weaver.signcenter.entity.form.RuleBase;
import com.weaver.signcenter.entity.form.SignCascadeRules;
import com.weaver.signcenter.entity.form.SignWeaFormItem;
import com.weaver.signcenter.entity.form.SignWeaTab;
import com.weaver.signcenter.entity.server.WfSetBaseInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;

@WeaHookReg(code = "SIGN_ELECTRONIC_FORM_HOOK" + "_" + PlatformConstant.type + "_" + "1", order = 0)
public class SignElectronicFormRegHook extends RegHookEvent {

    protected static final Logger log = LoggerFactory.getLogger(SignContractListButtonRegHook.class);

    @Override
    public WeaHookResponse handle(WeaHookRequest request, WeaHookResponse response, AppInfo appInfo) throws Exception {
        Map<String, Object> params = request.getParams();

        Object settingData = params.get("settingData");
        Map setting = (Map) settingData;
        WfSetBaseInfo wfSetBaseInfo = setting.get("baseInfo") == null ? null : (WfSetBaseInfo)setting.get("baseInfo");

        Object defaultSignWeaTab = params.get("defaultSignWeaTab");

        Long workflowId = wfSetBaseInfo.getWorkflowid();

        SignWeaTab rootWeaTab= (SignWeaTab) defaultSignWeaTab;

        List<SignWeaTab> child = rootWeaTab.getChild();

        SignWeaTab baseWeaTab = child.get(0);
        ScWeaForm baseForm = baseWeaTab.getForm();

        Map<String, WeaFormItem> baseFormItems = baseForm.getItems();
        SignWeaFormItem item = (SignWeaFormItem)baseFormItems.get("platformType");
        if(item != null){
            List<SignCascadeRules> cascadeRules = item.getCascadeRules();
            //规则1
            SignCascadeRules signCascadeRule = new SignCascadeRules();
            List<RuleBase> conditions = new ArrayList<>();
            RuleBase condition = new RuleBase("basicConfig", "platformType",RuleBase.ATTRIBUTE_VALUE,RuleBase.CONDITIONTYPE_1,Util.null2String(PlatformConstant.id));
            condition.setTabId("basicConfig");
            conditions.add(condition);
            List<RuleBase> actions = new ArrayList<>();

            Map<String, Object> groupProps = new HashMap();
            groupProps.put("hideGroupIds", new String[]{"contractPrintGroup"});//隐藏文件打印group

            RuleBase action = new RuleBase("advancedConfig", null, null, null, null, groupProps, null);
            action.setTabId("advancedConfig");
            actions.add(action);

            signCascadeRule.setConditions(conditions);
            signCascadeRule.setRelation(SignCascadeRules.RELATION_1);
            signCascadeRule.setActions(actions);
            cascadeRules.add(signCascadeRule);
        }

        SignWeaTab weaTab = child.get(1);
        ScWeaForm form = weaTab.getForm();
        Map<String, WeaFormItem> items = form.getItems();
        Map<String, Object> data = form.getData();
        Map<String, CustomField> map = new HashMap<>();
        if(wfSetBaseInfo != null && wfSetBaseInfo.getCustomFields() != null){
            wfSetBaseInfo.getCustomFields().stream().forEach(customItem ->{
                map.put(customItem.getFieldKey(), customItem);
            });
        }

        //自定义字段
        String customFieldKey = "CF_Field_fadadaField";
        item = SignWeaFormItem.getWeaFormFieldBrowserItem(workflowId)
                .appendCombinedNativeFilter(SigncenterBrowserConstants.NATIVE_FILTER_1, "Fold,ComboSelect")
                .appendCombinedFilter(SigncenterBrowserConstants.FILTER_KEY_CONTAIN_UNION, "wf_text,wf_browser,wf_ebuilder");
        items.put(customFieldKey,item);

        List<List<WeaFormLayout>> layout = form.getLayout();

        List<WeaFormLayout> childs = new ArrayList<>();
        childs.add(ComponentUtils.createLayout(customFieldKey,"自定义字段-fadada", new String[]{customFieldKey}, 6, false,"", "baseConfigGroup",""));
        layout.add(childs);

        if(map.containsKey(customFieldKey)){
            CustomField customFieldField = map.get(customFieldKey);
            List<Map<String, Object>> browserEntities = customFieldField.getBrowserEntities();
            if(browserEntities != null){
                data.put(customFieldKey, browserEntities);
            }
        }

        //自定义节点
        String customNodeKey = "CF_Node_fadadaNode";
        item = SignWeaFormItem.getWeaFormNodeBrowserItem(workflowId);
        items.put(customNodeKey,item);

        childs = new ArrayList<>();
        childs.add(ComponentUtils.createLayout(customNodeKey,"自定义节点-fadada", new String[]{customNodeKey}, 6, false,"", "baseConfigGroup",""));
        layout.add(childs);

        if(map.containsKey(customNodeKey)){
            CustomField customFieldField = map.get(customNodeKey);
            List<Map<String, Object>> browserEntities = customFieldField.getBrowserEntities();
            if(browserEntities != null){
                data.put(customNodeKey, browserEntities);
            }
        }

        SignWeaTab signWeaTab = child.get(2);
        ScWeaForm signForm = signWeaTab.getForm();
        Map<String, WeaFormItem> signItems = signForm.getItems();
        WeaFormItem signers = signItems.get("signers");
        Map<String, Object> otherParams = signers.getOtherParams();
        Map<String, Object> comConfig = (Map<String, Object>)otherParams.get("comConfig");
        ScWeaForm startOrgForm = (ScWeaForm)comConfig.get("startOrgForm");
        //签署方自定义字段
        String customSignFieldKey = "CF_Field_signField";
        item = SignWeaFormItem.getWeaFormFieldBrowserItem(workflowId)
                .appendCombinedNativeFilter(SigncenterBrowserConstants.NATIVE_FILTER_1, "Fold,ComboSelect")
                .appendCombinedFilter(SigncenterBrowserConstants.FILTER_KEY_CONTAIN_UNION, "wf_text,wf_browser,wf_ebuilder");

        startOrgForm.getItems().put(customSignFieldKey,item);

        startOrgForm.getLayout().add(Collections.singletonList(ComponentUtils.createLayout(customSignFieldKey,"自定义字段-签署方", new String[]{customSignFieldKey}, 6, false,"", "","")));

        //自定义字段
        String customSwitchFieldKey = "CF_switch_signField";
        Map<String, Object> cusParams = new HashMap<>();
        cusParams.put("size", "sm");

        item = new SignWeaFormItem(WeaFormItemType.SWITCH);
        item.setOtherParams(cusParams);
        items.put(customSwitchFieldKey, item);

        startOrgForm.getItems().put(customSwitchFieldKey,item);

        startOrgForm.getLayout().add(Collections.singletonList(ComponentUtils.createLayout(customSwitchFieldKey,"自定义switch字段-签署方", new String[]{customSwitchFieldKey}, 6, false,"", "","")));

        //设置联动
        SignWeaFormItem startAction = (SignWeaFormItem)startOrgForm.getItems().get("startAction");
        List<SignCascadeRules> cascadeRules = startAction.getCascadeRules();
        cascadeRules.addAll(getStartActionCascadeRules());

        ScWeaForm perForm =  (ScWeaForm)comConfig.get("perForm");
        //签署方自定义字段
        customSignFieldKey = "CF_Field_signField";
        item = SignWeaFormItem.getWeaFormFieldBrowserItem(workflowId)
                .appendCombinedNativeFilter(SigncenterBrowserConstants.NATIVE_FILTER_1, "Fold,ComboSelect")
                .appendCombinedFilter(SigncenterBrowserConstants.FILTER_KEY_CONTAIN_UNION, "wf_text,wf_browser,wf_ebuilder");
        perForm.getItems().put(customSignFieldKey,item);

        perForm.getLayout().add(Collections.singletonList(ComponentUtils.createLayout(customSignFieldKey,"自定义字段-签署方", new String[]{customSignFieldKey}, 6, false,"", "","")));

        //自定义字段
        customSwitchFieldKey = "CF_switch_signField";
        cusParams = new HashMap<>();
        cusParams.put("size", "sm");

        item = new SignWeaFormItem(WeaFormItemType.SWITCH);
        item.setOtherParams(cusParams);
        items.put(customSwitchFieldKey, item);

        perForm.getItems().put(customSwitchFieldKey,item);

        perForm.getLayout().add(Collections.singletonList(ComponentUtils.createLayout(customSwitchFieldKey,"自定义switch字段-签署方", new String[]{customSwitchFieldKey}, 6, false,"", "","")));

        ScWeaForm orgForm =  (ScWeaForm)comConfig.get("orgForm");
        //签署方自定义字段
        customSignFieldKey = "CF_Field_signField";
        item = SignWeaFormItem.getWeaFormFieldBrowserItem(workflowId)
                .appendCombinedNativeFilter(SigncenterBrowserConstants.NATIVE_FILTER_1, "Fold,ComboSelect")
                .appendCombinedFilter(SigncenterBrowserConstants.FILTER_KEY_CONTAIN_UNION, "wf_text,wf_browser,wf_ebuilder");
        orgForm.getItems().put(customSignFieldKey,item);

        orgForm.getLayout().add(Collections.singletonList(ComponentUtils.createLayout(customSignFieldKey,"自定义字段-签署方", new String[]{customSignFieldKey}, 6, false,"", "","")));

        //自定义字段
        customSwitchFieldKey = "CF_switch_signField";
        cusParams = new HashMap<>();
        cusParams.put("size", "sm");

        item = new SignWeaFormItem(WeaFormItemType.SWITCH);
        item.setOtherParams(cusParams);
        items.put(customSwitchFieldKey, item);

        orgForm.getItems().put(customSwitchFieldKey,item);

        orgForm.getLayout().add(Collections.singletonList(ComponentUtils.createLayout(customSwitchFieldKey,"自定义switch字段-签署方", new String[]{customSwitchFieldKey}, 6, false,"", "","")));

        //修改签署方中数据
        Map<String, Object> signFormData = signForm.getData();
        List<Map<String, Object>> signerDataList = (List<Map<String, Object>>)signFormData.get("signers");
        if(signerDataList != null){
            for (Map<String, Object> signerMap : signerDataList) {
                Map<String, Object> signerData =(Map<String, Object>)signerMap.get("data");
                if(signerData != null){
                    String csVal = Util.null2String(signerData.get(customSwitchFieldKey));
                    if("true".equals(csVal) || "1".equals(csVal)){
                        signerData.put(customSwitchFieldKey, 1);
                    }else{
                        signerData.put(customSwitchFieldKey, 0);
                    }
                }
            }
        }

        response.setResult(rootWeaTab);
        log.info("SignContractListButtonRegHook--response:{}", JSON.toJSONString(response));
        return response;
    }

    public List<SignCascadeRules> getStartActionCascadeRules(){
        String formId = "startOrgForm";

        List<SignCascadeRules> itemCascadeRules = new ArrayList<>();

        //联动1
        SignCascadeRules signCascadeRule = new SignCascadeRules();
        List<RuleBase> conditions = new ArrayList<>();
        RuleBase condition = new RuleBase(formId, "isStart", RuleBase.ATTRIBUTE_VALUE, RuleBase.CONDITIONTYPE_1,  "1");//发起方
        condition.setTabId(formId);
        conditions.add(condition);
        condition = new RuleBase(formId, "startAction", RuleBase.ATTRIBUTE_VALUE, RuleBase.CONDITIONTYPE_1,  "1");//仅发起不签署
        condition.setTabId(formId);
        conditions.add(condition);
        List<RuleBase> actions = new ArrayList<>();

        Map<String, Object> layoutProps = new HashMap();
        layoutProps.put("hide", true);
        RuleBase action = new RuleBase(formId, null, "CF_Field_signField", null, layoutProps, null, null);
        action.setTabId(formId);
        actions.add(action);

        layoutProps = new HashMap();
        layoutProps.put("hide", true);
        action = new RuleBase(formId, null, "CF_switch_signField", null, layoutProps, null, null);
        action.setTabId(formId);
        actions.add(action);

        signCascadeRule.setConditions(conditions);
        signCascadeRule.setRelation(SignCascadeRules.RELATION_1);
        signCascadeRule.setActions(actions);

        itemCascadeRules.add(signCascadeRule);

        //联动2
        signCascadeRule = new SignCascadeRules();
        conditions = new ArrayList<>();
        condition = new RuleBase(formId, "startAction", RuleBase.ATTRIBUTE_VALUE, RuleBase.CONDITIONTYPE_2,  "1");//发起且签署
        condition.setTabId(formId);
        conditions.add(condition);
        actions = new ArrayList<>();

        layoutProps = new HashMap();
        layoutProps.put("hide", false);
        action = new RuleBase(formId, null, "CF_Field_signField", null, layoutProps, null, null);
        action.setTabId(formId);
        actions.add(action);

        layoutProps = new HashMap();
        layoutProps.put("hide", false);
        action = new RuleBase(formId, null, "CF_switch_signField", null, layoutProps, null, null);
        action.setTabId(formId);
        actions.add(action);

        signCascadeRule.setConditions(conditions);
        signCascadeRule.setRelation(SignCascadeRules.RELATION_1);
        signCascadeRule.setActions(actions);

        itemCascadeRules.add(signCascadeRule);

        return itemCascadeRules;
    }

    @Override
    public void rollBack(WeaHookRequest request, WeaHookResponse response, AppInfo appInfo) throws Exception {

    }
}
```

## 4、电子签流程展示的按钮钩子

> 钩子唯一标识code："SIGN\_BUTTON\_LIST\_HOOK" + "\_" + PlatformConstant.type+"\_"+PlatformConstant.serverType

**4.1 功能说明：**

用于获取自定义二开服务商流程中展示的按钮数据

**4.2 参数说明：**

| 参数名 | 类型 | 说明 |
| --- | --- | --- |
| signContract | SignContractV2 | 合同信息 |
| businessType | BusinessTypeEnum | 按钮类型：电子，物理 |
| requestBaseEntity | SignRequestBaseEntity | 流程信息，包括：requestid，workflowid，nodeid等 |
| wfSetBaseInfo | WfSetBaseInfo | 电子用印配置信息 |
| signFieldMap | Map\<Long, SetFieldValue\> | 文件字段，模板字段配置项信息 |
| serverSetting | ServerSetting | 绑定服务配置信息 |
| employee | SimpleEmployee | 用户信息 |
| signatoryInfoList | List\<SignatoryInfo\> | 签署方配置的签署节点，签署校验，自动签署信息 |
| globalConfig | GlobalConfig | 全局配置信息 |

**4.3 响应说明：**

返回值是List\<SignButtonResult\>，SignButtonResult对象的定义如下：

| 参数名 | 类型 | 说明 |
| --- | --- | --- |
| workflowId | Long | 流程id |
| nodeId | Long | 节点id |
| requestId | Long | 请求id |
| module | String | 模块 |
| contractId | Long | 合同id |
| buttonType | SignButtonType | 按钮类型 |
| showButtonField | Long | 按钮显示字段 |
| buttonList | List\<SignButtonItem\> | 按钮集合 |
| cusMap | Map\<String, Object\> | 自定义map |

**4.4 示例代码：**

```
package com.weaver.seconddev.signcenter.fadada.reghook.button;

import com.alibaba.fastjson.JSON;
import com.weaver.loom.context.annotation.WeaHookReg;
import com.weaver.loom.context.domain.AppInfo;
import com.weaver.loom.context.domain.WeaHookRequest;
import com.weaver.loom.context.domain.WeaHookResponse;
import com.weaver.loom.context.register.RegHookEvent;
import com.weaver.seconddev.signcenter.fadada.reghook.PlatformConstant;
import com.weaver.seconddev.signcenter.fadada.util.Util;
import com.weaver.signcenter.api.entity.electronic.SignButtonItem;
import com.weaver.signcenter.api.entity.electronic.SignButtonResult;
import com.weaver.signcenter.api.enums.SignButtonType;
import com.weaver.signcenter.entity.contract2.SignContractV2;
import com.weaver.signcenter.entity.server.GlobalConfig;
import com.weaver.signcenter.entity.server.WfSetBaseInfo;
import com.weaver.signcenter.entity.workflow.SignRequestBaseEntity;
import com.weaver.teams.domain.EntityType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@WeaHookReg(code = "SIGN_BUTTON_LIST_HOOK" + "_" + PlatformConstant.type+"_"+PlatformConstant.serverType, order = 0)
public class SignButtonRegHook extends RegHookEvent {

    protected static final Logger log = LoggerFactory.getLogger(SignButtonRegHook.class);

    @Override
    public WeaHookResponse handle(WeaHookRequest request, WeaHookResponse response, AppInfo appInfo) throws Exception {
        Map<String, Object> params = request.getParams();
        log.info("SignButtonRegHook--request:{}", JSON.toJSONString(request));
        SignRequestBaseEntity requestBaseEntity = (SignRequestBaseEntity) params.get("requestBaseEntity");
        String nodeId = Util.null2String(requestBaseEntity.getNodeId());
        WfSetBaseInfo wfSetBaseInfo = (WfSetBaseInfo) params.get("wfSetBaseInfo");
        SignContractV2 contract = (SignContractV2) params.get("contract");
        GlobalConfig globalConfig = (GlobalConfig) params.get("globalConfig");

        SignButtonResult result = new SignButtonResult();
        result.setShowButtonField(Util.getLongValue(wfSetBaseInfo.getUploadSignFileField()));
        result.setButtonType(SignButtonType.ELECTRONIC);
        result.setWorkflowId(requestBaseEntity.getWorkflowId());
        result.setNodeId(requestBaseEntity.getNodeId());
        result.setRequestId(requestBaseEntity.getRequestId());
        result.setModule(EntityType.valueOf(requestBaseEntity.getModule()));
        List<SignButtonItem> buttonItems = new ArrayList<>();
        result.setButtonList(buttonItems);
        if (contract != null) {
            result.setContractId(contract.getContractId());
        }

        boolean showTopButton = Util.getIntValue(globalConfig.getShowBtnOnWorkflow()) == 1;

        buttonItems.add(new SignButtonItem(1, "指定签署位置", showTopButton));
        buttonItems.add(new SignButtonItem(2, "签署文件", showTopButton));
        buttonItems.add(new SignButtonItem(3, "查看文件", showTopButton));
        buttonItems.add(new SignButtonItem(4, "下载文件"));
        buttonItems.add(new SignButtonItem(5, "打印文件"));

        Map<String, Object> cusMap = new HashMap<>();
        Map<String, Object> electronicCfg = new HashMap<>();
        cusMap.put("electronicCfg", electronicCfg);
        cusMap.put("downloadLocal", Util.getLongValue(wfSetBaseInfo.getDownloadField()) <= 0);//是否仅下载到本地，控制下载组合按钮
        electronicCfg.put("signTabName", "法大大页签");//tab页名称
        electronicCfg.put("entityId", Util.null2String(requestBaseEntity.getRequestId()));

        boolean showTab = globalConfig.getUseTabOpenUrl() == 1 && buttonItems.stream()
                .filter(item -> item.getType() != 4 && item.getType() != 6)//除了下载合同，编辑签署方外有其他的按钮，就显示tab页
                .count() > 0;//是否显示电子签tab页
        electronicCfg.put("showTab", showTab);//存在按钮就显示tab页
        electronicCfg.put("showComponent", !buttonItems.isEmpty());//存在按钮就加载组件
        electronicCfg.put("buttonItems", buttonItems);//返回按钮，自动打开tab页用到

        electronicCfg.put("showTopButton",showTopButton);//显示顶部按钮
        electronicCfg.put("serverType", Util.getIntValue(wfSetBaseInfo.getServerType(), 0));
        if(contract != null){
            electronicCfg.put("contractId", Util.null2String(contract.getContractId()));
            result.setContractId(contract.getContractId());
        }

        result.setCusMap(cusMap);

        List<SignButtonResult> buttonResults = new ArrayList<>();
        buttonResults.add(result);
        response.setResult(buttonResults);
        return response;
    }

    @Override
    public void rollBack(WeaHookRequest request, WeaHookResponse response, AppInfo appInfo) throws Exception {

    }
}
```

## 5、电子签查看合同钩子

> 钩子唯一标识code："SIGN\_VIEW\_URL\_HOOK" + "\_" + PlatformConstant.type+"\_"+PlatformConstant.serverType

**5.1 功能说明：**

用于二开服务商，点击流程中【查看合同】按钮，获取合同的查看页面链接

**5.2 参数说明：**

| 参数名 | 类型 | 说明 |
| --- | --- | --- |
| platContractId | String | 合同id |
| wfSetBaseInfo | WfSetBaseInfo | 电子用印配置信息 |
| globalConfig | GlobalConfig | 全局配置 |
| serverSetting | ServerSetting | 绑定服务配置信息 |
| logId | Long | 日志id，用于记录接口调用日志 |
| employee | SimpleEmployee | 用户信息 |

**5.3 响应说明：**

返回值是SignBaseResult\<String\>，查看合同的链接直接设置在SignBaseResult对象的data中即可

**5.4 示例代码：**

```
package com.weaver.seconddev.signcenter.fadada.reghook.button;

import com.alibaba.fastjson.JSON;
import com.weaver.framework.rpc.annotation.RpcReference;
import com.weaver.loom.context.annotation.WeaHookReg;
import com.weaver.loom.context.domain.AppInfo;
import com.weaver.loom.context.domain.WeaHookRequest;
import com.weaver.loom.context.domain.WeaHookResponse;
import com.weaver.loom.context.register.RegHookEvent;
import com.weaver.seconddev.signcenter.fadada.entity.ServerEntity;
import com.weaver.seconddev.signcenter.fadada.reghook.PlatformConstant;
import com.weaver.seconddev.signcenter.fadada.util.TextUtil;
import com.weaver.seconddev.signcenter.fadada.util.Util;
import com.weaver.signcenter.api.constants.SignContractGroup;
import com.weaver.signcenter.api.entity.base.SignBaseResult;
import com.weaver.signcenter.api.rest.SignContractRest;
import com.weaver.signcenter.entity.server.ServerSetting;
import com.weaver.signcenter.qiyuesuo.pri.v3sdk.SdkClient;
import com.weaver.signcenter.qiyuesuo.pri.v3sdk.model.contract.request.ContractViewurlRequest;
import com.weaver.signcenter.qiyuesuo.pri.v3sdk.utils.SdkResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Map;

@WeaHookReg(code = "SIGN_VIEW_URL_HOOK" + "_" + PlatformConstant.type+"_"+PlatformConstant.serverType, order = 0)
public class SignViewRegHook extends RegHookEvent {

    protected static final Logger log = LoggerFactory.getLogger(SignViewRegHook.class);
    @RpcReference
    private SignContractRest signContractRest;

    @Override
    public WeaHookResponse handle(WeaHookRequest hookRequest, WeaHookResponse response, AppInfo appInfo) throws Exception {
        Map<String, Object> params = hookRequest.getParams();
        log.info("SignViewRegHook--hookRequest:{}", JSON.toJSONString(hookRequest));
        ServerSetting serverSetting = (ServerSetting) params.get("serverSetting");
        Long platContractId = Util.getLongValue(params.get("platContractId"));
        Long logId = Util.getLongValue(params.get("logId"));
        long startTime = System.currentTimeMillis();
        ServerEntity serverEntity = ServerEntity.getInstance(serverSetting);

        SdkClient sdkV3Client = new SdkClient(serverEntity.getOpenUrl(), serverEntity.getAppId(), serverEntity.getSecret());

        ContractViewurlRequest request = new ContractViewurlRequest();
        request.setContractId(platContractId);

        request.setPageType("CONTENT");
        request.setCanViewDetail("true");
        String url = "";
        SdkResponse<String> responseObj;
        try {
            responseObj = sdkV3Client.service(request, String.class);
        }catch (Exception e){
            response.setResult(SignBaseResult.fail(e.getMessage(), true));
            return response;
        }
        if(TextUtil.isValidLongObject(logId)){
            signContractRest.addLog(logId, Util.null2String(platContractId), 1, startTime, "290285",request, responseObj, true);
        }
        if(responseObj == null){
            response.setResult(SignBaseResult.fail("responseObj is null", true));
        }else if (responseObj.getCode() == 0) {
            url = responseObj.getResult();
            response.setResult(SignBaseResult.success(url));
        } else {
            response.setResult(SignBaseResult.fail(responseObj.getMessage(), true));
        }

        return response;
    }

    @Override
    public void rollBack(WeaHookRequest request, WeaHookResponse response, AppInfo appInfo) throws Exception {

    }
}
```

## 6、电子签签署合同钩子

> 钩子唯一标识code："SIGN\_SIGN\_URL\_HOOK" + "\_" + PlatformConstant.type+"\_"+PlatformConstant.serverType

**6.1 功能说明：**

用于二开服务商，点击流程中【签署合同】按钮，获取合同的签署页面链接

**6.2 参数说明：**

| 参数名 | 类型 | 说明 |
| --- | --- | --- |
| platContractId | String | 合同id |
| wfSetBaseInfo | WfSetBaseInfo | 电子用印配置信息 |
| globalConfig | GlobalConfig | 全局配置 |
| serverSetting | ServerSetting | 绑定服务配置信息 |
| logId | Long | 日志id，用于记录接口调用日志 |
| employee | SimpleEmployee | 用户信息 |

|  |
| --- |

**6.3 响应说明：**

返回值是SignBaseResult\<String\>，签署合同的链接直接设置在SignBaseResult对象的data中即可

**6.4 示例代码：**

```
package com.weaver.seconddev.signcenter.fadada.reghook.button;

import com.alibaba.fastjson.JSON;
import com.weaver.framework.rpc.annotation.RpcReference;
import com.weaver.loom.context.annotation.WeaHookReg;
import com.weaver.loom.context.domain.AppInfo;
import com.weaver.loom.context.domain.WeaHookRequest;
import com.weaver.loom.context.domain.WeaHookResponse;
import com.weaver.loom.context.register.RegHookEvent;
import com.weaver.seconddev.signcenter.fadada.entity.ServerEntity;
import com.weaver.seconddev.signcenter.fadada.reghook.PlatformConstant;
import com.weaver.seconddev.signcenter.fadada.util.TextUtil;
import com.weaver.seconddev.signcenter.fadada.util.Util;
import com.weaver.signcenter.api.entity.base.SignBaseResult;
import com.weaver.signcenter.api.rest.SignContractRest;
import com.weaver.signcenter.entity.server.ServerSetting;
import com.weaver.signcenter.qiyuesuo.pri.sdk.SDKClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Map;

@WeaHookReg(code = "SIGN_SIGN_URL_HOOK" + "_" + PlatformConstant.type+"_"+PlatformConstant.serverType, order = 0)
public class SignContractRegHook extends RegHookEvent {

    protected static final Logger log = LoggerFactory.getLogger(SignContractRegHook.class);

    @RpcReference
    private SignContractRest signContractRest;

    @Override
    public WeaHookResponse handle(WeaHookRequest hookRequest, WeaHookResponse response, AppInfo appInfo) throws Exception {
        Map<String, Object> params = hookRequest.getParams();
        Long logId = Util.getLongValue(params.get("logId"));
        long startTime = System.currentTimeMillis();
        log.info("SignContractRegHook--hookRequest:{}", JSON.toJSONString(hookRequest));
        Long platContractId = Util.getLongValue(params.get("platContractId"));
        ServerSetting serverSetting = (ServerSetting) params.get("serverSetting");

        ServerEntity serverEntity = ServerEntity.getInstance(serverSetting);

        String viewUrl = serverEntity.getSignUrl()+"/detail/"+platContractId;
        if(TextUtil.isValidLongObject(logId)){
            signContractRest.addLog(logId, Util.null2String(platContractId), 1, startTime, "290285",serverEntity, viewUrl, true);
        }

        response.setResult(SignBaseResult.success(viewUrl));
        return response;
    }

    @Override
    public void rollBack(WeaHookRequest request, WeaHookResponse response, AppInfo appInfo) throws Exception {

    }
}
```

## 7、电子签指定签署位置钩子

> 钩子唯一标识code："SIGN\_PRE\_SIGN\_URL\_HOOK" + "\_" + PlatformConstant.type+"\_"+PlatformConstant.serverType

**7.1 功能说明：**

用于二开服务商，点击流程中【指定签署位置】按钮，获取合同的指定签署位置链接

**7.2 参数说明：**

| 参数名 | 类型 | 说明 |
| --- | --- | --- |
| platContractId | String | 合同id |
| wfSetBaseInfo | WfSetBaseInfo | 电子用印配置信息 |
| pageType | int | 1指定签署位置 2合同填参 3指定签署位置并填参 |
| globalConfig | GlobalConfig | 全局配置 |
| serverSetting | ServerSetting | 绑定服务配置信息 |
| logId | Long | 日志id，用于记录接口调用日志 |
| employee | SimpleEmployee | 用户信息 |

**7.3 响应说明：**

返回值是SignBaseResult\<String\>，指定签署位置的链接直接设置在SignBaseResult对象的data中即可

**7.4 示例代码：**

```
package com.weaver.seconddev.signcenter.fadada.reghook.button;

import com.alibaba.fastjson.JSON;
import com.weaver.framework.rpc.annotation.RpcReference;
import com.weaver.loom.context.annotation.WeaHookReg;
import com.weaver.loom.context.domain.AppInfo;
import com.weaver.loom.context.domain.WeaHookRequest;
import com.weaver.loom.context.domain.WeaHookResponse;
import com.weaver.loom.context.register.RegHookEvent;
import com.weaver.seconddev.signcenter.fadada.entity.ServerEntity;
import com.weaver.seconddev.signcenter.fadada.reghook.PlatformConstant;
import com.weaver.seconddev.signcenter.fadada.util.TextUtil;
import com.weaver.seconddev.signcenter.fadada.util.Util;
import com.weaver.signcenter.api.entity.base.SignBaseResult;
import com.weaver.signcenter.api.rest.SignContractRest;
import com.weaver.signcenter.entity.server.ServerSetting;
import com.weaver.signcenter.qiyuesuo.pri.sdk.SDKClient;
import com.weaver.signcenter.qiyuesuo.pri.sdk.api.ContractService;
import com.weaver.signcenter.qiyuesuo.pri.sdk.bean.sign.PreSignUrlRequest;
import com.weaver.signcenter.qiyuesuo.pri.sdk.impl.ContractServiceImpl;
import com.weaver.signcenter.qiyuesuo.pri.v3sdk.SdkClient;
import com.weaver.teams.domain.user.SimpleEmployee;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Map;

@WeaHookReg(code = "SIGN_PRE_SIGN_URL_HOOK" + "_" + PlatformConstant.type+"_"+PlatformConstant.serverType, order = 0)
public class SignPresignRegHook extends RegHookEvent {

    protected static final Logger log = LoggerFactory.getLogger(SignPresignRegHook.class);

    @RpcReference
    private SignContractRest signContractRest;

    @Override
    public WeaHookResponse handle(WeaHookRequest hookRequest, WeaHookResponse response, AppInfo appInfo) throws Exception {
        Map<String, Object> params = hookRequest.getParams();

        log.info("SignPresignRegHook--hookRequest:{}", JSON.toJSONString(hookRequest));
        ServerSetting serverSetting = (ServerSetting) params.get("serverSetting");
        SimpleEmployee employee = (SimpleEmployee) params.get("employee");
        Long logId = Util.getLongValue(params.get("logId"));
        long startTime = System.currentTimeMillis();
        Long platContractId = Util.getLongValue(params.get("platContractId"));
        int pageType = Util.getIntValue(params.get("pageType"));

        ServerEntity serverEntity = ServerEntity.getInstance(serverSetting);

        SDKClient sdkClient = new SDKClient(serverEntity.getOpenUrl(), serverEntity.getAppId(), serverEntity.getSecret());

        ContractService contractService = new ContractServiceImpl(sdkClient);
        // 获取当前用户联系方式
        String operatorContact = employee.getMobile();

        log.info("getPreSignUrl--operatorContact:" + operatorContact);

        String url = "";
        PreSignUrlRequest request = new PreSignUrlRequest();
        long start = System.currentTimeMillis();
        try {
            request.setContractId(platContractId);
            request.setOperatorContact(operatorContact);
            //  1指定签署位置 2合同填参 3指定签署位置并填参
            switch (pageType) {
                case 1:
                    request.setCanSetStamper(true);
                    request.setCanSetParam(false);
                    break;
                case 2:
                    request.setCanSetStamper(false);
                    request.setCanSetParam(true);
                    break;
                case 3:
                    request.setCanSetStamper(true);
                    request.setCanSetParam(true);
                    break;
            }

            url = contractService.preSignUrl(request);
            log.info("getPreSignUrl--url:" + url);
            if(TextUtil.isValidLongObject(logId)){
                signContractRest.addLog(logId, Util.null2String(platContractId), 1, startTime, "290285",request, url, true);
            }
            response.setResult(SignBaseResult.success(url));
        } catch (Exception e) {
            log.error("获取预签署页面失败！契约锁业务ID：" + platContractId, e);
            response.setResult(SignBaseResult.fail(e.getMessage()));
        }
        return response;
    }

    @Override
    public void rollBack(WeaHookRequest request, WeaHookResponse response, AppInfo appInfo) throws Exception {

    }
}
```

## 8、电子签打印合同钩子

> 钩子唯一标识code："SIGN\_PRINT\_URL\_HOOK" + "\_" + PlatformConstant.type+"\_"+PlatformConstant.serverType

**8.1 功能说明：**

用于二开服务商，点击流程中【打印合同】按钮，获取打印合同链接

**8.2 参数说明：**

| 参数名 | 类型 | 说明 |
| --- | --- | --- |
| platContractId | String | 合同id |
| wfSetBaseInfo | WfSetBaseInfo | 电子用印配置信息 |
| globalConfig | GlobalConfig | 全局配置 |
| serverSetting | ServerSetting | 绑定服务配置信息 |
| logId | Long | 日志id，用于记录接口调用日志 |
| employee | SimpleEmployee | 用户信息 |

**8.3 响应说明：**

返回值是SignBaseResult\<String\>，打印合同的链接直接设置在SignBaseResult对象的data中即可

**8.4 示例代码：**

```
package com.weaver.seconddev.signcenter.fadada.reghook.button;

import com.alibaba.fastjson.JSON;
import com.weaver.framework.rpc.annotation.RpcReference;
import com.weaver.loom.context.annotation.WeaHookReg;
import com.weaver.loom.context.domain.AppInfo;
import com.weaver.loom.context.domain.WeaHookRequest;
import com.weaver.loom.context.domain.WeaHookResponse;
import com.weaver.loom.context.register.RegHookEvent;
import com.weaver.seconddev.signcenter.fadada.entity.ServerEntity;
import com.weaver.seconddev.signcenter.fadada.reghook.PlatformConstant;
import com.weaver.seconddev.signcenter.fadada.util.TextUtil;
import com.weaver.seconddev.signcenter.fadada.util.Util;
import com.weaver.signcenter.api.entity.base.SignBaseResult;
import com.weaver.signcenter.api.rest.SignContractRest;
import com.weaver.signcenter.entity.server.ServerSetting;
import com.weaver.signcenter.qiyuesuo.pri.sdk.SDKClient;
import com.weaver.signcenter.qiyuesuo.pri.sdk.api.ContractService;
import com.weaver.signcenter.qiyuesuo.pri.sdk.api.PrintService;
import com.weaver.signcenter.qiyuesuo.pri.sdk.bean.print.EntiFakePrintRequest;
import com.weaver.signcenter.qiyuesuo.pri.sdk.impl.ContractServiceImpl;
import com.weaver.signcenter.qiyuesuo.pri.sdk.impl.PrintServiceImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Map;

@WeaHookReg(code = "SIGN_PRINT_URL_HOOK" + "_" + PlatformConstant.type+"_"+PlatformConstant.serverType, order = 0)
public class SignPrintRegHook extends RegHookEvent {

    protected static final Logger log = LoggerFactory.getLogger(SignPrintRegHook.class);
    @RpcReference
    private SignContractRest signContractRest;

    @Override
    public WeaHookResponse handle(WeaHookRequest hookRequest, WeaHookResponse response, AppInfo appInfo) throws Exception {
        Map<String, Object> params = hookRequest.getParams();
        log.info("SignPrintRegHook--hookRequest:{}", JSON.toJSONString(hookRequest));
        ServerSetting serverSetting = (ServerSetting) params.get("serverSetting");
        Long platContractId = Util.getLongValue(params.get("platContractId"));
        long startTime = System.currentTimeMillis();
        ServerEntity serverEntity = ServerEntity.getInstance(serverSetting);

        SDKClient sdkClient = new SDKClient(serverEntity.getOpenUrl(), serverEntity.getAppId(), serverEntity.getSecret());
        Long logId = Util.getLongValue(params.get("logId"));
        PrintService printService= new PrintServiceImpl(sdkClient);
        EntiFakePrintRequest request = new EntiFakePrintRequest();
        request.setContractId(platContractId);
        request.setUseCurrentUser(false);
        try {
            String url = printService.getEntiFakePrintUrl(request);
            if(TextUtil.isValidLongObject(logId)){
                signContractRest.addLog(logId, Util.null2String(platContractId), 1, startTime, "290285",request, url, true);
            }
            response.setResult(SignBaseResult.success(url));
        } catch (Exception e) {
            log.error("printContract error", e);
            response.setResult(SignBaseResult.fail(e.getMessage()));
        }
        return response;
    }

    @Override
    public void rollBack(WeaHookRequest request, WeaHookResponse response, AppInfo appInfo) throws Exception {

    }
}
```

## 9、电子签下载合同到本地钩子

> 钩子唯一标识code："SIGN\_DOWNLOAD\_CONTRACT\_LOCAL\_HOOK" + "\_" + PlatformConstant.type+"\_"+PlatformConstant.serverType

**9.1 功能说明：**

用于二开服务商，点击流程中【下载合同】按钮下载到本地时，获取下载的合同文件

**9.2 参数说明：**

| 参数名 | 类型 | 说明 |
| --- | --- | --- |
| platContractId | String | 合同id |
| wfSetBaseInfo | WfSetBaseInfo | 电子用印配置信息 |
| globalConfig | GlobalConfig | 全局配置 |
| serverSetting | ServerSetting | 绑定服务配置信息 |
| logId | Long | 日志id，用于记录接口调用日志 |
| employee | SimpleEmployee | 用户信息 |

**9.3 响应说明：**

返回值是SignBaseResult\<DownloadDocumentDto\>，其中DownloadDocumentDto对象定义如下：

| 参数名 | 类型 | 说明 |
| --- | --- | --- |
| title | String | 文件名称 |
| file | byte\[\] | 文件字节数组 |

**9.4 示例代码：**

```
package com.weaver.seconddev.signcenter.fadada.reghook.button;

import com.alibaba.fastjson.JSON;
import com.aliyun.oss.common.utils.IOUtils;
import com.weaver.loom.context.annotation.WeaHookReg;
import com.weaver.loom.context.domain.AppInfo;
import com.weaver.loom.context.domain.WeaHookRequest;
import com.weaver.loom.context.domain.WeaHookResponse;
import com.weaver.loom.context.register.RegHookEvent;
import com.weaver.seconddev.signcenter.fadada.entity.ServerEntity;
import com.weaver.seconddev.signcenter.fadada.reghook.PlatformConstant;
import com.weaver.seconddev.signcenter.fadada.util.Util;
import com.weaver.signcenter.api.entity.base.SignBaseResult;
import com.weaver.signcenter.entity.contract2.DownloadDocumentDto;
import com.weaver.signcenter.entity.server.ServerSetting;
import com.weaver.signcenter.qiyuesuo.pri.sdk.SDKClient;
import com.weaver.signcenter.qiyuesuo.pri.sdk.api.ContractService;
import com.weaver.signcenter.qiyuesuo.pri.sdk.bean.contract.ContractDetail;
import com.weaver.signcenter.qiyuesuo.pri.sdk.bean.contract.ContractDownloadRequest;
import com.weaver.signcenter.qiyuesuo.pri.sdk.impl.ContractServiceImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.UUID;

@WeaHookReg(code = "SIGN_DOWNLOAD_CONTRACT_LOCAL_HOOK" + "_" + PlatformConstant.type+"_"+PlatformConstant.serverType, order = 0)
public class SignDownloadLocalRegHook extends RegHookEvent {

    protected static final Logger log = LoggerFactory.getLogger(SignDownloadLocalRegHook.class);

    @Override
    public WeaHookResponse handle(WeaHookRequest hookRequest, WeaHookResponse response, AppInfo appInfo) throws Exception {
        Map<String, Object> params = hookRequest.getParams();
        log.info("SignViewRegHook--hookRequest:{}", JSON.toJSONString(hookRequest));
        ServerSetting serverSetting = (ServerSetting) params.get("serverSetting");
        Long contractId = Util.getLongValue(params.get("platContractId"));

        SignBaseResult<DownloadDocumentDto> result = SignBaseResult.success();

        ServerEntity serverEntity = ServerEntity.getInstance(serverSetting);

        SDKClient sdkClient = new SDKClient(serverEntity.getOpenUrl(), serverEntity.getAppId(), serverEntity.getSecret());

        ContractService contractService = new ContractServiceImpl(sdkClient);

        ContractDetail contract = contractService.detail(contractId);

        List<String> downloadItems =  new ArrayList<>();
        downloadItems.add("NORMAL");//合同正文

        ContractDownloadRequest request = new ContractDownloadRequest();
        request.setContractId(contractId);

        File file = File.createTempFile(UUID.randomUUID().toString(), ".zip");
        OutputStream outputStream = new FileOutputStream(file);
        try {
            request.setOutputStream(outputStream);
            request.setNeedCompressForOneFile(true);
            request.setDownloadItems(downloadItems.toArray(new String[downloadItems.size()]));
            long start = System.currentTimeMillis();
            contractService.download(request);
        } catch (Exception e) {
            log.error("契约锁下载文件失败", e);
            result = SignBaseResult.fail("download error fadada", false);
            response.setResult(result);
            return response;
        }
        IOUtils.safeClose(outputStream);
        log.info("下载合同完成");

        DownloadDocumentDto dto = new DownloadDocumentDto();
        dto.setTitle(contract.getSubject()+".zip");
        dto.setFile(IOUtils.readStreamAsByteArray(new FileInputStream(file)));
        result = SignBaseResult.success(dto);
        response.setResult(result);
        return response;
    }

    @Override
    public void rollBack(WeaHookRequest request, WeaHookResponse response, AppInfo appInfo) throws Exception {

    }
}
```

## 10、电子签下载合同到表单字段钩子

> 钩子唯一标识code："SIGN\_DOWNLOAD\_CONTRACT\_HOOK" + "\_" + PlatformConstant.type+"\_"+PlatformConstant.serverType

**10.1 功能说明：**

用于二开服务商，点击流程中【下载合同】按钮下载到本地时，获取下载到表单中的合同文件

**10.2 参数说明：**

| 参数名 | 类型 | 说明 |
| --- | --- | --- |
| platContractId | String | 合同id |
| wfSetBaseInfo | WfSetBaseInfo | 电子用印配置信息 |
| globalConfig | GlobalConfig | 全局配置 |
| serverSetting | ServerSetting | 绑定服务配置信息 |
| logId | Long | 日志id，用于记录接口调用日志 |
| employee | SimpleEmployee | 用户信息 |

**10.3 响应说明：**

返回值是SignBaseResult\<List\<DownloadDocumentDto\>\>，其中DownloadDocumentDto对象定义如下：

| 参数名 | 类型 | 说明 |
| --- | --- | --- |
| title | String | 文件名称 |
| file | byte\[\] | 文件字节数组 |
| platDocumentId | String | 文档id |
| type | DocumentType | 文档类型 |

**10.4 示例代码：**

```
package com.weaver.seconddev.signcenter.fadada.reghook.button;

import com.alibaba.fastjson.JSON;
import com.aliyun.oss.common.utils.IOUtils;
import com.weaver.loom.context.annotation.WeaHookReg;
import com.weaver.loom.context.domain.AppInfo;
import com.weaver.loom.context.domain.WeaHookRequest;
import com.weaver.loom.context.domain.WeaHookResponse;
import com.weaver.loom.context.register.RegHookEvent;
import com.weaver.seconddev.signcenter.fadada.entity.ServerEntity;
import com.weaver.seconddev.signcenter.fadada.reghook.PlatformConstant;
import com.weaver.seconddev.signcenter.fadada.util.Util;
import com.weaver.signcenter.api.entity.base.SignBaseResult;
import com.weaver.signcenter.entity.contract2.DownloadDocumentDto;
import com.weaver.signcenter.entity.server.ServerSetting;
import com.weaver.signcenter.enums.contract.DocumentType;
import com.weaver.signcenter.qiyuesuo.pri.sdk.SDKClient;
import com.weaver.signcenter.qiyuesuo.pri.sdk.api.ContractService;
import com.weaver.signcenter.qiyuesuo.pri.sdk.bean.contract.ContractDetail;
import com.weaver.signcenter.qiyuesuo.pri.sdk.bean.contract.Document;
import com.weaver.signcenter.qiyuesuo.pri.sdk.bean.document.DownloadDocRequest;
import com.weaver.signcenter.qiyuesuo.pri.sdk.impl.ContractServiceImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.UUID;

@WeaHookReg(code = "SIGN_DOWNLOAD_CONTRACT_HOOK" + "_" + PlatformConstant.type+"_"+PlatformConstant.serverType, order = 0)
public class SignDownloadRegHook extends RegHookEvent {

    protected static final Logger log = LoggerFactory.getLogger(SignDownloadRegHook.class);

    @Override
    public WeaHookResponse handle(WeaHookRequest hookRequest, WeaHookResponse response, AppInfo appInfo) throws Exception {
        Map<String, Object> params = hookRequest.getParams();
        log.info("SignViewRegHook--hookRequest:{}", JSON.toJSONString(hookRequest));
        ServerSetting serverSetting = (ServerSetting) params.get("serverSetting");
        Long platContractId = Util.getLongValue(params.get("platContractId"));

        SignBaseResult<List<DownloadDocumentDto>> result = SignBaseResult.success();

        ServerEntity serverEntity = ServerEntity.getInstance(serverSetting);

        SDKClient sdkClient = new SDKClient(serverEntity.getOpenUrl(), serverEntity.getAppId(), serverEntity.getSecret());

        ContractService contractService = new ContractServiceImpl(sdkClient);

        ContractDetail contract = contractService.detail(platContractId);

        List<Document> documents = contract.getDocuments();
        List<DownloadDocumentDto> list = new ArrayList<>();
        for (Document document : documents) {
            File file = File.createTempFile(UUID.randomUUID().toString(), ".pdf");
            OutputStream outputStream = new FileOutputStream(file);
            DownloadDocRequest request = new DownloadDocRequest();
            request.setDocumentId(document.getId());
            request.setOutputStream(outputStream);
            long start = System.currentTimeMillis();
            try {
                contractService.downloadDoc(request);

            } catch (Exception e) {
                log.error("契约锁下载合同文档失败", e);
                SignBaseResult signBaseResult = SignBaseResult.fail("契约锁下载合同文档失败fadada", true);
                response.setResult(signBaseResult);
                return response;
            }finally {
                IOUtils.safeClose(outputStream);
            }
            DownloadDocumentDto dto = new DownloadDocumentDto();
            dto.setPlatDocumentId(Util.null2String(document.getId()));
            dto.setTitle(document.getTitle()+".pdf");
            dto.setType(DocumentType.CONTRACT);
            dto.setFile(IOUtils.readStreamAsByteArray(new FileInputStream(file)));
            list.add(dto);
        }
        result = SignBaseResult.success(list);
        response.setResult(result);
        return response;
    }

    @Override
    public void rollBack(WeaHookRequest request, WeaHookResponse response, AppInfo appInfo) throws Exception {

    }
}
```

## 11、电子签下载指定合同文档钩子

> 钩子唯一标识code："SIGN\_DOWNLOAD\_CONTRACT\_HOOK" + "\_" + PlatformConstant.type+"\_"+PlatformConstant.serverType

**11.1 功能说明：**

用于二开服务商，点击电子签文件列表中文档上的【下载】按钮下载到本地时，获取具体的合同文档信息

**11.2 参数说明：**

| 参数名 | 类型 | 说明 |
| --- | --- | --- |
| platContractId | String | 合同id |
| platDocumentId | String | 文档id |
| wfSetBaseInfo | WfSetBaseInfo | 电子用印配置信息 |
| globalConfig | GlobalConfig | 文件字段，模板字段配置项信息 |
| serverSetting | ServerSetting | 绑定服务配置信息 |
| logId | Long | 日志id，用于记录接口调用日志 |
| employee | SimpleEmployee | 用户信息 |

**11.3 响应说明：**

返回值是SignBaseResult\<List\<DownloadDocumentDto\>\>，其中DownloadDocumentDto对象定义如下：

| 参数名 | 类型 | 说明 |
| --- | --- | --- |
| title | String | 文件名称 |
| file | byte\[\] | 文件字节数组 |
| platDocumentId | String | 文档id |
| type | DocumentType | 文档类型 |

**11.4 示例代码：**

```
package com.weaver.seconddev.signcenter.fadada.reghook.button;

import com.alibaba.fastjson.JSON;
import com.aliyun.oss.common.utils.IOUtils;
import com.weaver.loom.context.annotation.WeaHookReg;
import com.weaver.loom.context.domain.AppInfo;
import com.weaver.loom.context.domain.WeaHookRequest;
import com.weaver.loom.context.domain.WeaHookResponse;
import com.weaver.loom.context.register.RegHookEvent;
import com.weaver.seconddev.signcenter.fadada.entity.ServerEntity;
import com.weaver.seconddev.signcenter.fadada.reghook.PlatformConstant;
import com.weaver.seconddev.signcenter.fadada.util.Util;
import com.weaver.signcenter.api.entity.base.SignBaseResult;
import com.weaver.signcenter.entity.contract2.DownloadDocumentDto;
import com.weaver.signcenter.entity.server.ServerSetting;
import com.weaver.signcenter.enums.contract.DocumentType;
import com.weaver.signcenter.qiyuesuo.pri.sdk.SDKClient;
import com.weaver.signcenter.qiyuesuo.pri.sdk.api.ContractService;
import com.weaver.signcenter.qiyuesuo.pri.sdk.bean.contract.ContractDetail;
import com.weaver.signcenter.qiyuesuo.pri.sdk.bean.contract.Document;
import com.weaver.signcenter.qiyuesuo.pri.sdk.bean.document.DownloadDocRequest;
import com.weaver.signcenter.qiyuesuo.pri.sdk.impl.ContractServiceImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.UUID;

@WeaHookReg(code = "SIGN_DOWNLOAD_CONTRACT_DOCUMENT_HOOK" + "_" + PlatformConstant.type+"_"+PlatformConstant.serverType, order = 0)
public class SignDownloadDocumentRegHook extends RegHookEvent {

    protected static final Logger log = LoggerFactory.getLogger(SignDownloadDocumentRegHook.class);

    @Override
    public WeaHookResponse handle(WeaHookRequest hookRequest, WeaHookResponse response, AppInfo appInfo) throws Exception {
        Map<String, Object> params = hookRequest.getParams();
        log.info("SignViewRegHook--hookRequest:{}", JSON.toJSONString(hookRequest));
        ServerSetting serverSetting = (ServerSetting) params.get("serverSetting");
        Long contractId = Util.getLongValue(params.get("platContractId"));
        Long documentId = Util.getLongValue(params.get("platDocumentId"));

        SignBaseResult<DownloadDocumentDto> result = SignBaseResult.success();

        ServerEntity serverEntity = ServerEntity.getInstance(serverSetting);

        SDKClient sdkClient = new SDKClient(serverEntity.getOpenUrl(), serverEntity.getAppId(), serverEntity.getSecret());

        ContractService contractService = new ContractServiceImpl(sdkClient);

        ContractDetail contract = contractService.detail(contractId);

        List<Document> documents = contract.getDocuments();
        Document document = documents.stream().filter(item-> item.getId().equals(documentId)).findFirst().orElse(null);

        if(document != null){
            File file = File.createTempFile(UUID.randomUUID().toString(), ".pdf");
            OutputStream outputStream = new FileOutputStream(file);
            DownloadDocRequest request = new DownloadDocRequest();
            request.setDocumentId(document.getId());
            request.setOutputStream(outputStream);
            long start = System.currentTimeMillis();
            try {
                contractService.downloadDoc(request);

            } catch (Exception e) {
                log.error("契约锁下载合同文档失败", e);
                SignBaseResult signBaseResult = SignBaseResult.fail("契约锁下载合同文档失败fadada", true);
                response.setResult(signBaseResult);
                return response;
            }finally {
                IOUtils.safeClose(outputStream);
            }
            DownloadDocumentDto dto = new DownloadDocumentDto();

            dto.setPlatDocumentId(Util.null2String(document.getId()));
            dto.setTitle(document.getTitle()+".pdf");
            dto.setType(DocumentType.CONTRACT);
            dto.setFile(IOUtils.readStreamAsByteArray(new FileInputStream(file)));

            result = SignBaseResult.success(dto);
            response.setResult(result);
            return response;
        }else{
            response.setResult(SignBaseResult.fail("query document is null fadada"));
            return response;
        }

    }

    @Override
    public void rollBack(WeaHookRequest request, WeaHookResponse response, AppInfo appInfo) throws Exception {

    }
}
```

## 12、电子签文件附加操作action钩子

> 钩子唯一标识code：SIGN\_ACTION\_LIST\_HOOK

**12.1 功能说明：**

用于二开服务商，电子用印集成配置中，自定义文件附加操作的action

**12.2 参数说明：**

该接口无参数

**12.3 响应说明：**

返回值是List\<ActionEntity\>，其中ActionEntity的定义如下：

| 参数名 | 类型 | 说明 |
| --- | --- | --- |
| id | String | 动作id，确保唯一值 |
| actionName | String | 动作名称 |
| platformId | int | 服务商id |
| platformType | String | 服务商type |
| businessType | BusinessTypeEnum | action对应的业务类型 |
| serverType | String | 服务类型：0\|公有云，1：私有云 |
| labelId | long | 动作名称多语言标签id |

**12.4 示例代码：**

```
package com.weaver.seconddev.signcenter.fadada.reghook.action;

import com.weaver.loom.context.annotation.WeaHookReg;
import com.weaver.loom.context.domain.AppInfo;
import com.weaver.loom.context.domain.WeaHookRequest;
import com.weaver.loom.context.domain.WeaHookResponse;
import com.weaver.loom.context.register.RegHookEvent;
import com.weaver.seconddev.signcenter.fadada.reghook.PlatformConstant;
import com.weaver.signcenter.entity.action.ActionEntity;
import com.weaver.signcenter.entity.platform.SignPlatformEntity;
import com.weaver.signcenter.enums.base.BusinessTypeEnum;

import java.util.ArrayList;
import java.util.List;

@WeaHookReg(code = "SIGN_ACTION_LIST_HOOK", order = 0)
public class SignActionListRegHook extends RegHookEvent {
    @Override
    public WeaHookResponse handle(WeaHookRequest request, WeaHookResponse response, AppInfo appInfo) throws Exception {

        Object result = response.getResult();
        List<ActionEntity> list;
        if(result == null || !(result instanceof List)){
            list = new ArrayList<>();
            response.setResult(list);
        }else{
            list = (List)result;
        }
        ActionEntity action1 = new ActionEntity("100001", "action测试1", PlatformConstant.id, PlatformConstant.type, "1", BusinessTypeEnum.ELECTRONIC, 0);
        ActionEntity action2 = new ActionEntity("100002", "action测试2", PlatformConstant.id, PlatformConstant.type, "1", BusinessTypeEnum.ELECTRONIC, 0);
        list.add(action1);
        list.add(action2);
        return response;
    }

    @Override
    public void rollBack(WeaHookRequest request, WeaHookResponse response, AppInfo appInfo) throws Exception {
        return;
    }
}
```

## 13、电子签文件附加操作action执行钩子

> 钩子唯一标识code：SIGN\_ACTION\_EXECUTE\_HOOK

**13.1 功能说明：**

用于二开服务商，电子用印集成配置中，执行自定义文件附加操作的action

**13.2 参数说明：**

| 参数名 | 类型 | 说明 |
| --- | --- | --- |
| platContractId | String | 合同id |
| requestId | Long | 请求id |
| workflowId | Long | 流程id |
| module | String | 模块 |
| nodeId | Long | 节点id |
| actionEntity | ActionEntity | 动作实体 |
| actionId | String | 动作id |
| wfSetAllFieldValue | WfSetAllFieldValue | 电子用印配置封装类信息 |
| globalConfig | GlobalConfig | 文件字段，模板字段配置项信息 |
| serverSetting | ServerSetting | 绑定服务配置信息 |
| logId | Long | 日志id，用于记录接口调用日志 |
| employee | SimpleEmployee | 用户信息 |

**13.3 响应说明：**

返回值是SignBaseResult，标识执行结果，以及返回失败信息

**13.4 示例代码：**

```
package com.weaver.seconddev.signcenter.fadada.reghook.action;

import com.alibaba.fastjson.JSON;
import com.weaver.loom.context.annotation.WeaHookReg;
import com.weaver.loom.context.domain.AppInfo;
import com.weaver.loom.context.domain.WeaHookRequest;
import com.weaver.loom.context.domain.WeaHookResponse;
import com.weaver.loom.context.register.RegHookEvent;
import com.weaver.seconddev.signcenter.fadada.reghook.PlatformConstant;
import com.weaver.signcenter.api.entity.base.SignBaseResult;
import com.weaver.signcenter.entity.action.ActionEntity;
import com.weaver.signcenter.entity.server.ServerSetting;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Map;

@WeaHookReg(code = "SIGN_ACTION_EXECUTE_HOOK" + "_" + PlatformConstant.type+"_"+PlatformConstant.serverType, order = 0)
public class SignActionExecuteRegHook extends RegHookEvent {

    protected static final Logger log = LoggerFactory.getLogger(SignActionExecuteRegHook.class);

    @Override
    public WeaHookResponse handle(WeaHookRequest hookRequest, WeaHookResponse response, AppInfo appInfo) throws Exception {
        Map<String, Object> params = hookRequest.getParams();
        log.info("SignActionExecuteRegHook--hookRequest:{}", JSON.toJSONString(hookRequest));
        ActionEntity actionEntity = (ActionEntity) params.get("actionEntity");
        SignBaseResult result = SignBaseResult.fail(actionEntity.getActionName() + ":execute fail");
        response.setResult(result);
        return response;
    }

    @Override
    public void rollBack(WeaHookRequest request, WeaHookResponse response, AppInfo appInfo) throws Exception {

    }
}
```

## 14、电子签自动签署钩子

> 钩子唯一标识code：SIGN\_NODE\_AUTO\_SIGN\_HOOK

**14.1 功能说明：**

用于二开服务商，电子用印集成配置中，签署方中勾选的自动签署，流程节点提交时会执行这个钩子

**14.2 参数说明：**

| 参数名 | 类型 | 说明 |
| --- | --- | --- |
| requestId | Long | 流程请求id |
| nodeId | Long | 节点id |
| platContractId | String | 合同id |
| globalConfig | GlobalConfig | 全局配置 |
| wfSetAllFieldValue | WfSetAllFieldValue | 电子用印封装类信息 |
| serverSetting | ServerSetting | 绑定服务配置信息 |
| logId | Long | 日志id，用于记录接口调用日志 |
| employee | SimpleEmployee | 用户信息 |

**14.3 响应说明：**

返回值是SignBaseResult，标识执行结果，以及返回失败信息

**14.4 示例代码：**

```
package com.weaver.seconddev.signcenter.fadada.reghook.action;

import com.alibaba.fastjson.JSON;
import com.weaver.loom.context.annotation.WeaHookReg;
import com.weaver.loom.context.domain.AppInfo;
import com.weaver.loom.context.domain.WeaHookRequest;
import com.weaver.loom.context.domain.WeaHookResponse;
import com.weaver.loom.context.register.RegHookEvent;
import com.weaver.seconddev.signcenter.fadada.entity.ServerEntity;
import com.weaver.seconddev.signcenter.fadada.reghook.PlatformConstant;
import com.weaver.signcenter.api.entity.base.SignBaseResult;
import com.weaver.signcenter.entity.action.ActionEntity;
import com.weaver.signcenter.entity.base.SetFieldValue;
import com.weaver.signcenter.entity.server.ServerSetting;
import com.weaver.signcenter.entity.server.SignatorySetValue;
import com.weaver.signcenter.entity.server.WfSetAllFieldValue;
import com.weaver.teams.domain.user.SimpleEmployee;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;
import java.util.Map;

@WeaHookReg(code = "SIGN_NODE_AUTO_SIGN_HOOK" + "_" + PlatformConstant.type+"_"+PlatformConstant.serverType, order = 0)
public class SignAutoSignRegHook extends RegHookEvent {

    protected static final Logger log = LoggerFactory.getLogger(SignAutoSignRegHook.class);

    @Override
    public WeaHookResponse handle(WeaHookRequest hookRequest, WeaHookResponse response, AppInfo appInfo) throws Exception {
        Map<String, Object> params = hookRequest.getParams();
        log.info("SignActionExecuteRegHook--hookRequest:{}", JSON.toJSONString(hookRequest));
        String platContractId = (String) params.get("platContractId");
        SimpleEmployee employee = (SimpleEmployee) params.get("employee");
        StringBuilder sb = new StringBuilder();
        sb.append("用户：").append(employee.getName()).append(",自动签署合同：").append(platContractId).append("签署方：");

        WfSetAllFieldValue wfSetAllFieldValue = (WfSetAllFieldValue) params.get("wfSetAllFieldValue");
        if(wfSetAllFieldValue != null){
            List<SignatorySetValue> signatoryList = wfSetAllFieldValue.getSignatories();
            if(signatoryList != null){
                for (SignatorySetValue signatory : signatoryList) {
                    SetFieldValue signatoryNameField = signatory.getSignatoryNameField();
                    if(signatoryNameField != null){
                        sb.append(signatoryNameField.getContent());
                    }
                }
            }
        }
        sb.append("失败");
        ServerSetting serverSetting = (ServerSetting) params.get("serverSetting");
        ServerEntity serverEntity = ServerEntity.getInstance(serverSetting);
        sb.append("，execute fail,serverId:"+serverSetting.getId()+"-appId:"+ serverEntity.getAppId()+"-signUrl"+serverEntity.getSignUrl());
        SignBaseResult result = SignBaseResult.fail(sb.toString());
        response.setResult(result);
        return response;
    }

    @Override
    public void rollBack(WeaHookRequest request, WeaHookResponse response, AppInfo appInfo) throws Exception {

    }
}
```

## 15、电子签签署校验钩子

> 钩子唯一标识code：SIGN\_CHECK\_CURRENT\_OPERATOR\_SIGN\_WITH\_NODE\_HOOK

**15.1 功能说明：**

用于二开服务商，签署方中勾选的签署校验，流程节点提交时会执行这个钩子

**15.2 参数说明：**

| 参数名 | 类型 | 说明 |
| --- | --- | --- |
| requestId | Long | 流程请求id |
| nodeId | Long | 节点id |
| platContractId | String | 合同id |
| globalConfig | GlobalConfig | 全局配置 |
| serverSetting | ServerSetting | 绑定服务配置信息 |
| wfSetAllFieldValue | WfSetAllFieldValue | 电子用印封装类信息 |
| logId | Long | 日志id，用于记录接口调用日志 |
| employee | SimpleEmployee | 用户信息 |

**15.3 响应说明：**

返回值是SignBaseResult，标识执行结果，以及返回失败信息

**15.4 示例代码：**

```
package com.weaver.seconddev.signcenter.fadada.reghook.action;

import com.alibaba.fastjson.JSON;
import com.weaver.loom.context.annotation.WeaHookReg;
import com.weaver.loom.context.domain.AppInfo;
import com.weaver.loom.context.domain.WeaHookRequest;
import com.weaver.loom.context.domain.WeaHookResponse;
import com.weaver.loom.context.register.RegHookEvent;
import com.weaver.seconddev.signcenter.fadada.entity.ServerEntity;
import com.weaver.seconddev.signcenter.fadada.reghook.PlatformConstant;
import com.weaver.signcenter.api.entity.base.SignBaseResult;
import com.weaver.signcenter.entity.base.SetFieldValue;
import com.weaver.signcenter.entity.server.ServerSetting;
import com.weaver.signcenter.entity.server.SignatorySetValue;
import com.weaver.signcenter.entity.server.WfSetAllFieldValue;
import com.weaver.teams.domain.user.SimpleEmployee;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;
import java.util.Map;

@WeaHookReg(code = "SIGN_CHECK_CURRENT_OPERATOR_SIGN_WITH_NODE_HOOK" + "_" + PlatformConstant.type+"_"+PlatformConstant.serverType, order = 0)
public class SignCheckSignRegHook extends RegHookEvent {

    protected static final Logger log = LoggerFactory.getLogger(SignCheckSignRegHook.class);

    @Override
    public WeaHookResponse handle(WeaHookRequest hookRequest, WeaHookResponse response, AppInfo appInfo) throws Exception {
        Map<String, Object> params = hookRequest.getParams();
        log.info("SignActionExecuteRegHook--hookRequest:{}", JSON.toJSONString(hookRequest));

        String platContractId = (String) params.get("platContractId");
        SimpleEmployee employee = (SimpleEmployee) params.get("employee");
        StringBuilder sb = new StringBuilder();
        sb.append("用户：").append(employee.getName()).append(",签署校验：").append(platContractId).append("签署方：");

        WfSetAllFieldValue wfSetAllFieldValue = (WfSetAllFieldValue) params.get("wfSetAllFieldValue");
        if(wfSetAllFieldValue != null){
            List<SignatorySetValue> signatoryList = wfSetAllFieldValue.getSignatories();
            if(signatoryList != null){
                for (SignatorySetValue signatory : signatoryList) {
                    SetFieldValue signatoryNameField = signatory.getSignatoryNameField();
                    if(signatoryNameField != null){
                        sb.append(signatoryNameField.getContent());
                    }
                }
            }
        }
        sb.append("失败");
        ServerSetting serverSetting = (ServerSetting) params.get("serverSetting");
        ServerEntity serverEntity = ServerEntity.getInstance(serverSetting);
        sb.append("，execute fail,serverId:"+serverSetting.getId()+"-appId:"+ serverEntity.getAppId()+"-signUrl"+serverEntity.getSignUrl());
        SignBaseResult result = SignBaseResult.fail(sb.toString());
        response.setResult(result);
        return response;
    }

    @Override
    public void rollBack(WeaHookRequest request, WeaHookResponse response, AppInfo appInfo) throws Exception {

    }
}
```

## 16、电子签创建合同钩子

> 钩子唯一标识code："SIGN\_CREATE\_CONTRACT\_HOOK" + "\_" + PlatformConstant.type+"\_"+PlatformConstant.serverType

**16.1 功能说明：**

用于二开服务商，执行创建合同接口时触发

**16.2 参数说明：**

| 参数名 | 类型 | 说明 |
| --- | --- | --- |
| contractBean | ContractBean | 创建合同所需要的实体信息 |
| serverSetting | ServerSetting | 绑定服务配置信息 |
| logId | Long | 日志id，用于记录接口调用日志 |

**16.3 响应说明：**

返回值是SignBaseResult\<ElectronicContractDto\>，其中ElectronicContractDto实体定义如下

| 参数名 | 类型 | 说明 |
| --- | --- | --- |
| platContractId | String | 合同id |
| status | String | 合同状态 |
| documentList | List\<SignDocument\> | 合同文档列表 |

**16.4 示例代码：**

```
package com.weaver.seconddev.signcenter.fadada.reghook.action;

import com.alibaba.fastjson.JSON;
import com.weaver.common.hrm.util.HrmCommonUtil;
import com.weaver.common.i18n.label.SystemEnv;
import com.weaver.common.i18n.tool.util.I18nLanguageUtil;
import com.weaver.eteams.file.client.file.FileData;
import com.weaver.eteams.file.client.file.FileObj;
import com.weaver.eteams.file.client.remote.FileClientService;
import com.weaver.file.ud.api.FileDownloadService;
import com.weaver.framework.rpc.annotation.RpcReference;
import com.weaver.framework.util.JsonUtil;
import com.weaver.loom.context.annotation.WeaHookReg;
import com.weaver.loom.context.domain.AppInfo;
import com.weaver.loom.context.domain.WeaHookRequest;
import com.weaver.loom.context.domain.WeaHookResponse;
import com.weaver.loom.context.register.RegHookEvent;
import com.weaver.seconddev.signcenter.fadada.entity.ServerEntity;
import com.weaver.seconddev.signcenter.fadada.reghook.PlatformConstant;
import com.weaver.seconddev.signcenter.fadada.util.*;
import com.weaver.signcenter.api.entity.base.IdName;
import com.weaver.signcenter.api.entity.base.SignBaseResult;
import com.weaver.signcenter.entity.base.SetFieldValue;
import com.weaver.signcenter.entity.base.UserFieldValue;
import com.weaver.signcenter.entity.contract2.ElectronicContractDto;
import com.weaver.signcenter.entity.contract2.SignDocument;
import com.weaver.signcenter.entity.customfield.CustomField;
import com.weaver.signcenter.entity.electronic.ContractBean;
import com.weaver.signcenter.entity.server.*;
import com.weaver.signcenter.enums.qys.QYSSignAction;
import com.weaver.signcenter.enums.qys.SignatoryType;
import com.weaver.signcenter.enums.server.AddSignatoryType;
import com.weaver.signcenter.enums.server.SelectSetType;
import com.weaver.signcenter.qiyuesuo.pri.sdk.SDKClient;
import com.weaver.signcenter.qiyuesuo.pri.sdk.api.ContractService;
import com.weaver.signcenter.qiyuesuo.pri.sdk.bean.contract.Action;
import com.weaver.signcenter.qiyuesuo.pri.sdk.bean.contract.ActionType;
import com.weaver.signcenter.qiyuesuo.pri.sdk.bean.contract.CreateContractRequest;
import com.weaver.signcenter.qiyuesuo.pri.sdk.bean.contract.Operator;
import com.weaver.signcenter.qiyuesuo.pri.sdk.bean.document.CreateDocumentRequest;
import com.weaver.signcenter.qiyuesuo.pri.sdk.bean.document.CreateDocumentResult;
import com.weaver.signcenter.qiyuesuo.pri.sdk.bean.sign.Signatory;
import com.weaver.signcenter.qiyuesuo.pri.sdk.common.http.StreamFile;
import com.weaver.signcenter.qiyuesuo.pri.sdk.impl.ContractServiceImpl;
import com.weaver.teams.domain.user.SimpleEmployee;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import java.io.InputStream;
import java.util.*;

@WeaHookReg(code = "SIGN_CREATE_CONTRACT_HOOK" + "_" + PlatformConstant.type+"_"+PlatformConstant.serverType, order = 0)
public class SignCreateContractRegHook extends RegHookEvent {

    protected static final Logger log = LoggerFactory.getLogger(SignCreateContractRegHook.class);

    @RpcReference
    private FileClientService fileClientService;

    @Autowired
    private HrmCommonUtil hrmCommonUtil;

    @Autowired
    private FileDownloadService fileDownloadService;

    @Autowired
    private QYSUserUtils qysUserUtils;

    @Override
    public WeaHookResponse handle(WeaHookRequest hookRequest, WeaHookResponse response, AppInfo appInfo) throws Exception {
        Map<String, Object> params = hookRequest.getParams();
        log.info("SignCreateContractRegHook--hookRequest:{}", JSON.toJSONString(hookRequest));
        ServerSetting serverSetting = (ServerSetting) params.get("serverSetting");
        ContractBean contractBean = (ContractBean) params.get("contractBean");
        SignBaseResult<ElectronicContractDto> result = createContract(contractBean, serverSetting);
        response.setResult(result);
        return response;
    }

    public SignBaseResult<ElectronicContractDto> createContract(ContractBean contractBean, ServerSetting serverSetting) {

        SimpleEmployee employee = contractBean.getSimpleEmployee();
        WfSetAllFieldValue wfSetAllFieldValue = contractBean.getWfSetAllFieldValue();
        int signatoryIndex = contractBean.getSignatoryIndex();
        int documentIndex = contractBean.getDocumentIndex();
        Long logId = contractBean.getLogId();

        if (wfSetAllFieldValue == null) {
            log.info("createContract--未获取到当前流程表单数据");
            return SignBaseResult.fail("wfSetAllFieldValue is null", false);
        }

        WfSetBaseInfo wfSetBaseInfo = wfSetAllFieldValue.getWfSetBaseInfo();
        Map<Long, SetFieldValue> fieldMap = wfSetAllFieldValue.getFieldMap();

        List<CustomField> customFields = wfSetBaseInfo.getCustomFields();

        Map<String, CustomField> customFieldMap = new HashMap<>();
        customFields.stream().forEach(item ->{
            customFieldMap.put(item.getFieldKey(), item);
        });
        //合同名称
        String subject = contractBean.getContractSubject();
        //自定义字段
        CustomField customField = customFieldMap.get("CF_Field_fadadaField");
        String customFieldId = customField.getFieldValue();
        SetFieldValue setFieldValue = fieldMap.get(Util.getLongValue(customFieldId));
        if(setFieldValue != null){
            String content = setFieldValue.getContent();
            subject += content;//获取自定义字段的值
        }

        ServerEntity serverEntity = ServerEntity.getInstance(serverSetting);

        SDKClient sdkClient = new SDKClient(serverEntity.getOpenUrl(), serverEntity.getAppId(), serverEntity.getSecret());

        ContractService contractService = new ContractServiceImpl(sdkClient);

        Long requestId = wfSetAllFieldValue.getRequestId();

        int index = signatoryIndex > -1 ? signatoryIndex : documentIndex;
        log.info("createContract--requestId:{}--idx:{}", requestId, index);

        int signType = com.weaver.signcenter.util.Util.getIntValue(wfSetAllFieldValue.getBatchSignType());

        log.info("createContract--subject:" + subject);

        //文件尺寸类型
        Integer documentSizeType = wfSetAllFieldValue.getDocumentSizeType();
        //文件尺寸宽度
        float documentWidth = TextUtil.getFloatValue(wfSetAllFieldValue.getDocumentSizeWith());
        //文件尺寸高度
        float documentHeight = TextUtil.getFloatValue(wfSetAllFieldValue.getDocumentSizeHeight());
        log.info("createContract--documentSizeType:"+documentSizeType+"--documentWidth:"+documentWidth+"--documentHeight:"+documentHeight);

        List<Long> documentIds = new ArrayList<>();//文档id的list

        List<SignDocument> signDocumentList = contractBean.getSignDocuments();

        for (SignDocument signDocument : signDocumentList) {
            int createType = Util.getIntValue(signDocument.getCreateDocumentType());
            if(createType == 0){//文档
                Long fileId = signDocument.getFileId();
                FileObj fileObj = fileClientService.getById(fileId);
                if(fileObj != null){
                    String extName = fileObj.getExtName();

                    CreateDocumentRequest createDocumentRequest = new CreateDocumentRequest();
                    createDocumentRequest.setTitle(fileObj.getName());
                    createDocumentRequest.setFileType(extName);
                    if (documentWidth > 0 && documentSizeType > 0) {
                        createDocumentRequest.setWidth(documentWidth);
                    }
                    if (documentHeight > 0 && documentSizeType > 0) {
                        createDocumentRequest.setHeight(documentHeight);
                    }

                    InputStream inputStream = null;
                    FileData fileData = null;
                    try {
                        fileData = fileDownloadService.downloadFile(fileId);

                        inputStream = fileData.getInputStream();
                        createDocumentRequest.setFile(new StreamFile(inputStream));
                        CreateDocumentResult createDocumentResult = contractService.createByFile(createDocumentRequest) ;
                        if (createDocumentResult == null) {
                            return null;
                        }

                        Long documentId = createDocumentResult.getDocumentId();
                        signDocument.setPlatDocumentId(Util.null2String(documentId));
                        documentIds.add(documentId);
                    } catch (Exception e) {
                        log.error("createContract--契约锁根据文件创建文档失败", e);
                        return SignBaseResult.fail("createByFile error"+ e.getMessage(), true);
                    } finally {
                        if (inputStream != null) IOUtil.safeClose(inputStream);
                        if (fileData != null) fileData.closeStream();
                    }
                }
            }else{
                //todo
            }
        }
        log.info("createContract--documentIds.size:" + documentIds.size());

        //合同编号
        SetFieldValue snField = wfSetAllFieldValue.getSnField();
        String sn = WorkflowUtil.getWorkFlowFieldContent(snField, index);
        log.info("createContract--sn:" + sn);

        //业务分类ID
        Long categoryId = null;
        String categoryName = null;
        SetFieldValue categoryField = wfSetAllFieldValue.getCategoryField();
        String category = WorkflowUtil.getWorkFlowFieldContent(categoryField, index);
        for (String categoryItem : TextUtil.splitAsStringList(category)) {
            if (!TextUtil.isNullOrEmpty(categoryItem)) {
                if (TextUtil.isNumeric(categoryItem)) {
                    categoryId = TextUtil.getLongValue(categoryItem);
                } else {
                    categoryName = categoryItem;
                }
                break;
            }
        }

        // 创建合同保存为草稿
        boolean createDraft = wfSetAllFieldValue.isCreateDraft();
        log.info("createContract--createDraft:" + createDraft);

        // 合同描述
        SetFieldValue descriptionField = wfSetAllFieldValue.getDescriptionField();
        String description = WorkflowUtil.getWorkFlowFieldContent(descriptionField, index);
        log.info("createContract--description:" + description);

        // 合同发起方名称，只支持主表字段
        SetFieldValue entityField = wfSetAllFieldValue.getEntityField();
        String tenantName = WorkflowUtil.getWorkFlowFieldContent(entityField);
        log.info("createContract--tenantName:" + tenantName);

        // 合同终止日期 yyyy-MM-dd 先不做校验
        SetFieldValue contractExpireDateField = wfSetAllFieldValue.getContractExpireDateField();
        String contractEndTime = WorkflowUtil.getWorkFlowFieldContent(contractExpireDateField, index);
        log.info("createContract--contractEndTime:" + contractEndTime);

        // 合同过期日期 yyyy-MM-dd HH:mm:ss
        SetFieldValue contractOverDateField = wfSetAllFieldValue.getContractOverDateField();
        String contractExpireTime = TimeUtil.setDefaultTime(WorkflowUtil.getWorkFlowFieldContent(contractOverDateField, index));
        log.info("createContract--contractExpireTime:" + contractExpireTime);

        List<Signatory> signatories;
        try{
            signatories = getSignatory(0L, null, requestId, wfSetAllFieldValue, documentIds, false, signatoryIndex);
        } catch(Exception e) {
            log.error("createContract--获取文件签署方失败", e);
            return SignBaseResult.fail(SystemEnv.getHtmlLabelName(187071, "获取文件签署方失败") +","+ e.getMessage(), false);
        }
        log.info("createContract--signatories.size:" + signatories.size());
        if (CollectionUtil.isNullOrEmpty(signatories) && wfSetAllFieldValue.getAddSignatoryWay() != AddSignatoryType.DYNAMIC) {
            return SignBaseResult.fail("signatories is null");
        }

        String idx = index > -1 ? String.valueOf(index) : "";
        String bizId = wfSetAllFieldValue.getTenantKey() + "-" + requestId + "-" + idx;

        CreateContractRequest createContractRequest = new CreateContractRequest();
        createContractRequest.setSystemCode(employee.getTenantKey());
        createContractRequest.setBizId(bizId);
        createContractRequest.setSubject(subject);
        createContractRequest.setSignatories(signatories);
        createContractRequest.setSn(sn);
        createContractRequest.setCategoryId(categoryId);
        createContractRequest.setCategoryName(categoryName);
        createContractRequest.setSend(!createDraft);
        createContractRequest.setTenantName(tenantName);
        createContractRequest.setDescription(description);
        Long creatorUserId = contractBean.getCreatorUserId();
        if(TextUtil.isValidLongObject(creatorUserId)){
            SimpleEmployee creator = getEmployee(creatorUserId);
            String creatorName = "";
            String creatorContact = "";
            if(creator != null){
                creatorName = creator.getName();
                creatorContact = TextUtil.isNullOrEmpty(creator.getMobile()) ? creator.getEmail() : creator.getMobile();
            }
            if (!TextUtil.isNullOrEmpty(creatorName)) {
                createContractRequest.setCreatorName(creatorName);
            }
            if (!TextUtil.isNullOrEmpty(creatorContact)) {
                createContractRequest.setCreatorContact(creatorContact);
            }
            createContractRequest.setThirdUserId(creatorUserId+"");
        }
        createContractRequest.setEndTime(contractEndTime);// 终止日期
        createContractRequest.setExpireTime(contractExpireTime);//过期时间
        createContractRequest.setDocuments(documentIds);

        Long contractId = contractService.createContractByCategory(createContractRequest);

        // 数据库操作
        ElectronicContractDto contract = new ElectronicContractDto();
        contract.setContractName(subject);
        contract.setCategoryId(categoryId);
        contract.setPlatContractId(Util.null2String(contractId));
        contract.setDocumentList(signDocumentList);
        contract.setSendCopyList(new ArrayList<>());
        log.info("createContract--end--contractId:" + contractId);
        return SignBaseResult.success(contract);
    }

    private List<Signatory> getSignatory(Long nodeId, Long contractId, Long requestId, WfSetAllFieldValue wfSetAllFieldValue, List<Long> documentIds, boolean getCurNodeSignatory, int signatoryIndex) {
        List<Signatory> signatories = new ArrayList<>();
        if (wfSetAllFieldValue == null) {
            log.info("getSignatory--wfSetAllFieldValue is null");
            return signatories;
        }
        Map<String, UserFieldValue> contactFieldValueMap = new HashMap<>();
        wfSetAllFieldValue.setContactFieldValueMap(contactFieldValueMap);
        // 动态添加签署方
        AddSignatoryType addSignatoryWay = wfSetAllFieldValue.getAddSignatoryWay();
        boolean isAdd = addSignatoryWay == AddSignatoryType.DYNAMIC;

        // 签署方信息
        List<SignatorySetValue> signatorySetValueList = CollectionUtil.null2List(wfSetAllFieldValue.getSignatories());
        if (getCurNodeSignatory && TextUtil.isValidLongObject(nodeId) && wfSetAllFieldValue.getNodeSigntories() != null && wfSetAllFieldValue.getNodeSigntories().containsKey(nodeId)) {
            signatorySetValueList = CollectionUtil.null2List(wfSetAllFieldValue.getNodeSigntories().get(nodeId));
        }
        log.info("getSignatory--signatorySetValueList:{}", JsonUtil.toJsonString(signatorySetValueList));
        for (SignatorySetValue signatorySetValue : signatorySetValueList) {
            if (signatorySetValue == null) continue;
            // 签署动作列表
            List<SignActionSetValue> actionSetValueList = CollectionUtil.null2List(signatorySetValue.getSignNodeSetList());
            // 签署方类型
            SignatoryType signatoryType = signatorySetValue.getSignatoryType();
            // 是否为个人签署方 并且允许选择多人
            boolean selectMultiPeople = signatoryType == SignatoryType.PERSONAL && com.weaver.signcenter.util.Util.getIntValue(signatorySetValue.getIsSelectMulti()) == 1;

            if (isAdd) {
                List<Long> signNodeList = new ArrayList<>();
                for (SignActionSetValue actionSetValue : actionSetValueList) {
                    if (actionSetValue == null) continue;
                    signNodeList.addAll(actionSetValue.getSignNode());
                }

                if (!signNodeList.contains(nodeId)) {
                    continue;
                }
            }

            // 签署顺序(自定义配置/表单字段)
            SelectSetType serialNoType = signatorySetValue.getOrdinalType();
            Integer serialNo = signatorySetValue.getOrdinal();
            SetFieldValue serialNoField = signatorySetValue.getOrdinalField();
            Integer remind = signatorySetValue.getIsSendMessage();
            // 经办人
            SetFieldValue receiver = signatorySetValue.getReceiver();

            // 签署方名称
            SetFieldValue signatoryNameField = signatorySetValue.getSignatoryNameField();
            // 签署方是否是明细字段
            if (signatoryNameField != null) {
                boolean isDetail = signatoryNameField.isDetailField();
                long maxIndex = WorkflowUtil.getDetailFieldMaxIndex(signatoryNameField);
                int index = signatoryIndex > -1 ? signatoryIndex : 1;
                do {
                    List<String> tenantNameList = TextUtil.splitAsStringList(WorkflowUtil.getWorkFlowFieldContent(signatoryNameField, index));
                    if (!CollectionUtil.isNullOrEmpty(tenantNameList)) {
                        for (int i = 0; i < tenantNameList.size(); i++) {
                            String tenantName = tenantNameList.get(i);
                            int signatorySerialNo = -1;
                            if (serialNoType == SelectSetType.CUSTOMIZE) {//自定义签署顺序值
                                signatorySerialNo = serialNo == null || serialNo < 0 ? 1 : serialNo;
                            } else if (serialNoType == SelectSetType.SELECT) {//签署顺序选择表单字段
                                signatorySerialNo = TextUtil.getIntValue(WorkflowUtil.getWorkFlowFieldContent(serialNoField, index));
                            }

                            //签署方
                            Signatory signatory = new Signatory();
                            signatory.setTenantName(tenantName);
                            signatory.setSerialNo(signatorySerialNo < 0 ? 1 : signatorySerialNo);
                            signatory.setTenantTypeValue(signatoryType.getType());

                            signatory.setRemind(remind == 1);
                            Map<String, String> userMap = new HashMap<>();
                            List<IdName> contactList = qysUserUtils.getUserIdContactInWfField(wfSetAllFieldValue.getTenantKey(), receiver, index);

                            if (!CollectionUtil.isNullOrEmpty(contactList)) {
                                IdName obj = contactList.get(i);
                                if (obj != null) {
                                    String contact = obj.getName();
                                    signatory.setContact(contact);
                                    signatory.setThirdUserId(TextUtil.null2String(obj.getId()));
                                    contactFieldValueMap.put(obj.getName(), new UserFieldValue(receiver, contact, userMap.get(contact)));
                                }
                            }
                            //组织签署方增加签署动作
                            if (!selectMultiPeople) {
                                for (SignActionSetValue actionSetValue : actionSetValueList) {
                                    addSignatoryActions(wfSetAllFieldValue.getTenantKey(), wfSetAllFieldValue.getServerId(), nodeId, isAdd, contractId, requestId, documentIds, signatory, actionSetValue, isDetail, index, contactFieldValueMap, signatoryIndex, wfSetAllFieldValue.getEmployee());
                                }
                            }
                            signatories.add(signatory);
                            if (!selectMultiPeople) {
                                break;
                            }
                        }
                    }
                } while (signatoryIndex == -1 && isDetail && index++ < maxIndex);
            }
        }

        // 合并签署方
        if (signatories.size() > 1) {
            mergeSignatory(signatories);
        }
        log.info("getSignatory--signatories:{}", JsonUtil.toJsonString(signatories));
        return signatories;
    }

    private void addSignatoryActions(String tenantKey, Long serverId, Long nodeId, boolean isAdd, Long contractId, Long requestId, List<Long> documentIds, Signatory signatory, SignActionSetValue actionSetValue,
                                     boolean outerDetail, int index, Map<String, UserFieldValue> contactFieldValueMap, int signatoryIndex, SimpleEmployee employee) {
        if (actionSetValue == null) return;

        int languageid = (employee == null) ? 7 : I18nLanguageUtil.getLangId(employee.getEmployeeId());

        // 动态添加签署方，不包含当前节点，直接返回
        List<Long> signNode = actionSetValue.getSignNode();
        if (isAdd && signNode != null && !signNode.contains(nodeId)) return;

        SelectSetType actionType = actionSetValue.getActionType();// 1自定义 2表单

        boolean isDetail = false;
        SetFieldValue signActionField = actionSetValue.getSignActionField();
        if (!outerDetail && SelectSetType.SELECT == actionType && signActionField != null) {
            isDetail = signActionField.isDetailField();
            if (isDetail) {
                index = 1;
            }
        }
        long maxIndex = WorkflowUtil.getDetailFieldMaxIndex(signActionField);
        index = signatoryIndex > -1 ? signatoryIndex : index;

        do {
            List<String> actionList = new ArrayList<>();
            // 签署动作类型
            String type = "CORPORATE";
            if (Objects.equals(signatory.getTenantTypeValue(), "PERSONAL")) { //个人签署方默认签署动作为个人签字
                type = "PERSONAL";
                actionList.add(type);
            } else if (Objects.equals(signatory.getTenantTypeValue(), "COMPANY")) {//组织签署方
                if (actionType == SelectSetType.CUSTOMIZE) {//自定义签署动作
                    QYSSignAction signAction = actionSetValue.getSignAction();
                    actionList.add(signAction.name());
                } else if (actionType == SelectSetType.SELECT) {//选择表单字段
                    if (signActionField != null) {
                        String actionValues = WorkflowUtil.getWorkFlowFieldContent(signActionField, index);
                        for (String actionValue : TextUtil.splitAsStringList(actionValues)) {
                            if (!TextUtil.isNullOrEmpty(actionValue)) {
                                // 先支持中英文匹配
                                // type = ActionType.valueOf(actionValue);
                                if (TextUtil.equalsIgnoreCase(actionValue, "COMPANY", "CORPORATE") || TextUtil.equals(actionValue, "企业签章", "组织签章")) {
                                    type = "CORPORATE";
                                } else if (TextUtil.equalsIgnoreCase("PERSONAL", actionValue) || TextUtil.equals("个人签字", actionValue)) {
                                    type = "PERSONAL";
                                } else if (TextUtil.equalsIgnoreCase("OPERATOR", actionValue) || TextUtil.equals("经办人签字", actionValue)) {
                                    type = "OPERATOR";
                                } else if (TextUtil.equalsIgnoreCase("LP", actionValue) || TextUtil.equals("法定代表人签字", actionValue)) {
                                    type = "LP";
                                } else if (TextUtil.equalsIgnoreCase("AUDIT", actionValue) || TextUtil.equals("审批", actionValue)) {
                                    type = "AUDIT";
                                }
                            }
                            actionList.add(type);
                        }
                    }
                }
            }

            for (String item : actionList) {
                if (item == null) continue;

                Action action = new Action();
                action.setTypeValue(item);
                action.setName(ActionType.valueOf(item).getDescription());

                // 签署顺序
                SelectSetType actionSerialNoType = actionSetValue.getOrdinalType();//签署顺序类型,自定义/选择表单字段
                Integer actionSerialNo = actionSetValue.getOrdinal();
                SetFieldValue actionSerialNoField = actionSetValue.getOrdinalField();
                if (actionSerialNoType == SelectSetType.CUSTOMIZE) {
                    actionSerialNo = actionSerialNo == null || actionSerialNo < 0 ? 1 : actionSerialNo;
                } else {
                    actionSerialNo = TextUtil.getIntValue(WorkflowUtil.getWorkFlowFieldContent(actionSerialNoField, index), 1);
                }
                action.setSerialNo(actionSerialNo);

                // 印章
                if ("CORPORATE".equals(item) || "LP".equals(item)) { // 企业签章，法人签字 传递印章
                    SetFieldValue signSealField = actionSetValue.getSignSealField();
                    if (signSealField != null) {
                        //如果签署方和签署动作都不是明细表，（如果指定印章是明细表，则获取所有的值）
                        String sealIds = WorkflowUtil.getWorkFlowField(signSealField, (outerDetail || isDetail) ? index : -1);
                        List<Long> sealIdList = TextUtil.splitAsLongList(sealIds);

                        if (sealIdList.size() == 1) {
                            action.setSealId(sealIdList.get(0));
                        } else if (sealIdList.size() > 1) {
                            Set<Long> sealIdSet = new TreeSet<>(sealIdList);
                            action.setSealIds(sealIdSet);
                        }
                    }

                }

                // 操作人
                if (TextUtil.equals(item, "CORPORATE", "PERSONAL", "AUDIT", "LP")) { //组织签章，个人签字，审批，法人签字 传操作人
                    SetFieldValue signerField = actionSetValue.getSignerField();
                    //获取到接收人联系方式，如果签署方和签署动作都不是明细表，（如果签署节点签署人是明细表，则获取所有的值）
                    Map<String, String> userMap = new HashMap<>();
                    List<IdName> userIdContactList = qysUserUtils.getUserIdContactInWfField(tenantKey, signerField, (outerDetail || isDetail) ? index : -1);
                    if (!CollectionUtil.isNullOrEmpty(userIdContactList)) {
                        for (IdName idName : userIdContactList) {
                            String operatorContact = idName.getName();
                            Operator operator = new Operator();
                            operator.setOperatorContact(operatorContact);
                            operator.setThirdUserId(TextUtil.null2String(idName.getId()));
                            contactFieldValueMap.put(operatorContact,new UserFieldValue(signerField, operatorContact,userMap.get(operatorContact)));
                            action.addOperators(operator);
                        }
                    }
                }

                signatory.addAction(action);
            }
        } while (signatoryIndex == -1 && isDetail && index++ < maxIndex);
    }

    private void mergeSignatory(List<Signatory> signatories) {
        log.info("mergeSignatory--signatories"+ JSON.toJSONString(signatories));
        Map<String, Integer> tenantNameIndexMap = new HashMap<>();
        int i = 0;
        Iterator<Signatory> iterator = signatories.iterator();
        while (iterator.hasNext()) {
            Signatory signatory = iterator.next();
            String tenantName = signatory.getTenantName();
            String tenantType = signatory.getTenantTypeValue();
            int index = TextUtil.getIntValue(TextUtil.null2String(tenantNameIndexMap.get(tenantName)));
            if (index >= 0) {
                if (!Objects.equals(tenantType, "PERSONAL")) {
                    List<Action> actions = signatory.getActions();
                    if (!CollectionUtil.isNullOrEmpty(actions)) {
                        if (signatories.get(index) != null && !CollectionUtil.isNullOrEmpty(signatories.get(index).getActions())) {
                            signatories.get(index).getActions().addAll(actions);
                        }
                    }
                }
                iterator.remove();
            } else {
                tenantNameIndexMap.put(tenantName, i);
                i++;
            }
        }
        log.info("mergeSignatory--signatories.size:" + signatories.size());
    }

    public SimpleEmployee getEmployee(Long employeeId) {
        SimpleEmployee employee = null;
        if (employeeId != null) {
            employee = hrmCommonUtil.getSimpleEmployee(employeeId);
            if (employee != null) {
                employee.setAuthorities(null);
            }
        }
        return employee;
    }

    @Override
    public void rollBack(WeaHookRequest request, WeaHookResponse response, AppInfo appInfo) throws Exception {

    }
}
```

## 17、电子签编辑合同钩子

> 钩子唯一标识code："SIGN\_EDIT\_CONTRACT\_HOOK" + "\_" + PlatformConstant.type+"\_"+PlatformConstant.serverType

**17.1 功能说明：**

用于二开服务商，开启允许编辑合同，并且合同是草稿状态，执行创建合同接口时执行

**17.2 参数说明：**

| 参数名 | 类型 | 说明 |
| --- | --- | --- |
| editContractBean | ContractBean | 创建合同所需要的实体信息 |
| serverSetting | ServerSetting | 绑定服务配置信息 |
| logId | Long | 日志id，用于记录接口调用日志 |

**17.3 响应说明：**

** **返回值是SignBaseResult\<ElectronicContractDto\>，其中ElectronicContractDto实体定义如下

| 参数名 | 类型 | 说明 |
| --- | --- | --- |
| platContractId | String | 合同id |
| status | String | 合同状态 |
| documentList | List\<SignDocument\> | 合同文档列表 |

**17.4 示例代码：**

参考16创建合同

## 18、电子签发起合同钩子

> 钩子唯一标识code："SIGN\_SEND\_CONTRACT\_HOOK" + "\_" + PlatformConstant.type+"\_"+PlatformConstant.serverType

**18.1 功能说明：**

用于二开服务商，执行发起合同接口时触发

**18.2 参数说明：**

| 参数名 | 类型 | 说明 |
| --- | --- | --- |
| platContractId | String | 合同id |
| serverSetting | ServerSetting | 绑定服务配置信息 |
| wfSetAllFieldValue | WfSetAllFieldValue | 电子用印集成配置信息封装类 |
| logId | Long | 日志id，用于记录接口调用日志 |
| employee | SimpleEmployee | 用户信息 |

**18.3 响应说明：**

返回值是SignBaseResult，标识执行结果，以及返回失败信息

**18.4 示例代码：**

```
package com.weaver.seconddev.signcenter.fadada.reghook.action;

import com.alibaba.fastjson.JSON;
import com.weaver.loom.context.annotation.WeaHookReg;
import com.weaver.loom.context.domain.AppInfo;
import com.weaver.loom.context.domain.WeaHookRequest;
import com.weaver.loom.context.domain.WeaHookResponse;
import com.weaver.loom.context.register.RegHookEvent;
import com.weaver.seconddev.signcenter.fadada.entity.ServerEntity;
import com.weaver.seconddev.signcenter.fadada.reghook.PlatformConstant;
import com.weaver.seconddev.signcenter.fadada.util.Util;
import com.weaver.signcenter.api.entity.base.SignBaseResult;
import com.weaver.signcenter.entity.action.ActionEntity;
import com.weaver.signcenter.entity.server.ServerSetting;
import com.weaver.signcenter.enums.base.BusinessTypeEnum;
import com.weaver.signcenter.qiyuesuo.pri.sdk.SDKClient;
import com.weaver.signcenter.qiyuesuo.pri.sdk.api.ContractService;
import com.weaver.signcenter.qiyuesuo.pri.sdk.bean.contract.SendContractRequest;
import com.weaver.signcenter.qiyuesuo.pri.sdk.common.exception.PrivateAppException;
import com.weaver.signcenter.qiyuesuo.pri.sdk.impl.ContractServiceImpl;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@WeaHookReg(code = "SIGN_SEND_CONTRACT_HOOK" + "_" + PlatformConstant.type+"_"+PlatformConstant.serverType, order = 0)
public class SignSendContractRegHook extends RegHookEvent {
    @Override
    public WeaHookResponse handle(WeaHookRequest hookRequest, WeaHookResponse response, AppInfo appInfo) throws Exception {

        Map<String, Object> params = hookRequest.getParams();
        log.info("SignCreateContractRegHook--hookRequest:{}", JSON.toJSONString(hookRequest));
        ServerSetting serverSetting = (ServerSetting) params.get("serverSetting");
        String platContractId = (String) params.get("platContractId");

        ServerEntity serverEntity = ServerEntity.getInstance(serverSetting);

        SDKClient sdkClient = new SDKClient(serverEntity.getOpenUrl(), serverEntity.getAppId(), serverEntity.getSecret());

        ContractService contractService = new ContractServiceImpl(sdkClient);

        SendContractRequest sendContractRequest = new SendContractRequest();
        sendContractRequest.setContractId(Util.getLongValue(platContractId));
        SignBaseResult result = SignBaseResult.success();
        try {
            contractService.send(sendContractRequest);
        } catch (PrivateAppException e) {
            log.error("发起文件失败！" + e.getLocalizedMessage() + "契约锁业务ID：" + platContractId, e);
            result = SignBaseResult.fail("send fail "+ e.getMessage());
        }
        response.setResult(result);
        return response;
    }

    @Override
    public void rollBack(WeaHookRequest request, WeaHookResponse response, AppInfo appInfo) throws Exception {
        return;
    }
}
```

## 19、电子签esb配置回调事件类型钩子

> 钩子唯一标识code："SIGN\_ESB\_CALLBACK\_EVENT\_TYPE\_LIST\_HOOK" + "\_" + PlatformConstant.type+"\_"+PlatformConstant.serverType

**19.1 功能说明：**

用于二开服务商，配置esb通用回调时，展示回调事件类型

**19.2 参数说明：**

| 参数名 | 类型 | 说明 |
| --- | --- | --- |
| serverSetting | ServerSetting | 绑定服务配置信息 |
| serverType | int | 服务类型，0：公有云，1：私有云 |
| setType | ServerSetting | 设置类型 |

**19.3 响应说明：**

返回值是SignBaseResult\<List\<CallbackEventType\>\>，其中CallbackEventType实体类型定义如下：

| 参数名 | 类型 | 说明 |
| --- | --- | --- |
| id | String | 回调事件类型id |
| name | String | 回调事件名称 |
| labelId | long | 回调事件名称多语言 |

**19.4 示例代码：**

参考16创建合同esb配置回调事件钩子

## 20、电子签esb配置回调事件钩子

> 钩子唯一标识code："SIGN\_ESB\_CALLBACK\_EVENT\_LIST\_HOOK" + "\_" + PlatformConstant.type+"\_"+PlatformConstant.serverType

**20.1 功能说明：**

用于二开服务商，配置esb通用回调时，展示回调事件

**20.2 参数说明：**

| 参数名 | 类型 | 说明 |
| --- | --- | --- |
| serverSetting | ServerSetting | 绑定服务配置信息 |
| serverType | int | 服务类型，0：公有云，1：私有云 |
| setType | ServerSetting | 设置类型 |

**20.3 响应说明：**

返回值是SignBaseResult\<List\<CallbackEvent\>\>，其中CallbackEvent实体类型定义如下：

| 参数名 | 类型 | 说明 |
| --- | --- | --- |
| id | String | 回调事件类型id |
| name | String | 回调事件名称 |
| labelId | long | 回调事件名称多语言 |
| eventTypeId | String | 回调事件类型id |

**20.4 示例代码：**

```
package com.weaver.seconddev.signcenter.fadada.reghook.callback;

import com.alibaba.fastjson.JSON;
import com.weaver.loom.context.annotation.WeaHookReg;
import com.weaver.loom.context.domain.AppInfo;
import com.weaver.loom.context.domain.WeaHookRequest;
import com.weaver.loom.context.domain.WeaHookResponse;
import com.weaver.loom.context.register.RegHookEvent;
import com.weaver.seconddev.signcenter.fadada.reghook.PlatformConstant;
import com.weaver.seconddev.signcenter.fadada.util.Util;
import com.weaver.signcenter.api.entity.base.SignBaseResult;
import com.weaver.signcenter.entity.callback.CallbackEntity;
import com.weaver.signcenter.entity.callback.CallbackEvent;
import com.weaver.signcenter.entity.server.ServerSetting;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@WeaHookReg(code = "SIGN_ESB_CALLBACK_EVENT_LIST_HOOK" + "_" + PlatformConstant.type+"_"+PlatformConstant.serverType, order = 0)
public class SignCallbackEventListRegHook extends RegHookEvent {

    protected static final Logger log = LoggerFactory.getLogger(SignCallbackEventListRegHook.class);

    @Override
    public WeaHookResponse handle(WeaHookRequest hookRequest, WeaHookResponse response, AppInfo appInfo) throws Exception {
        Map<String, Object> params = hookRequest.getParams();
        log.info("SignCallbackEventListRegHook--hookRequest:{}", JSON.toJSONString(hookRequest));
        List<CallbackEvent> list = new ArrayList<>();
        CallbackEvent callbackEvent = new CallbackEvent("1000111", "测试回调事件", 0);
        CallbackEvent callbackEvent2 = new CallbackEvent("1000112", "测试回调事件2", 0);
        list.add(callbackEvent);
        list.add(callbackEvent2);
        SignBaseResult<List<CallbackEvent>> result = SignBaseResult.success(list);
        response.setResult(result);
        return response;
    }

    @Override
    public void rollBack(WeaHookRequest request, WeaHookResponse response, AppInfo appInfo) throws Exception {

    }
}
```

## 21、电子签esb配置回调上下文参数钩子

> 钩子唯一标识code："SIGN\_ESB\_CALLBACK\_FIELD\_INFO\_LIST\_HOOK" + "\_" + PlatformConstant.type+"\_"+PlatformConstant.serverType

**21.1 功能说明：**

用于二开服务商，配置esb通用回调时，展示可配置的回调上下文信息

**21.2 参数说明：**

| 参数名 | 类型 | 说明 |
| --- | --- | --- |
| serverSetting | ServerSetting | 绑定服务配置信息 |
| setType | ServerSetting | 设置类型 |

**21.3 响应说明：**

返回值是SignBaseResult\<List\<CallbackFieldInfo\>\>，其中CallbackFieldInfo实体类型定义如下：

| 参数名 | 类型 | 说明 |
| --- | --- | --- |
| fieldKey | String | 上下文参数key |
| fieldName | String | 上下文参数名称 |
| labelId | long | 上下文参数名称多语言 |

**21.4 示例代码：**

```
package com.weaver.seconddev.signcenter.fadada.reghook.callback;

import com.alibaba.fastjson.JSON;
import com.weaver.loom.context.annotation.WeaHookReg;
import com.weaver.loom.context.domain.AppInfo;
import com.weaver.loom.context.domain.WeaHookRequest;
import com.weaver.loom.context.domain.WeaHookResponse;
import com.weaver.loom.context.register.RegHookEvent;
import com.weaver.seconddev.signcenter.fadada.reghook.PlatformConstant;
import com.weaver.seconddev.signcenter.fadada.util.Util;
import com.weaver.signcenter.api.entity.base.SignBaseResult;
import com.weaver.signcenter.entity.callback.CallbackEntity;
import com.weaver.signcenter.entity.callback.CallbackFieldInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@WeaHookReg(code = "SIGN_ESB_CALLBACK_FIELD_INFO_LIST_HOOK" + "_" + PlatformConstant.type+"_"+PlatformConstant.serverType, order = 0)
public class SignCallbackEventFieldInfoHook extends RegHookEvent {

    protected static final Logger log = LoggerFactory.getLogger(SignCallbackEventFieldInfoHook.class);

    @Override
    public WeaHookResponse handle(WeaHookRequest hookRequest, WeaHookResponse response, AppInfo appInfo) throws Exception {
        Map<String, Object> params = hookRequest.getParams();
        log.info("SignCallbackEntityRegHook--hookRequest:{}", JSON.toJSONString(hookRequest));

        List<CallbackFieldInfo> fieldInfoList = new ArrayList<>();

        CallbackFieldInfo fieldInfo1 = new CallbackFieldInfo("testParam1", "测试回调参数1", 0);
        fieldInfoList.add(fieldInfo1);

        CallbackFieldInfo fieldInfo2 = new CallbackFieldInfo("testParam1", "测试回调参数1", 0);
        fieldInfoList.add(fieldInfo2);
        SignBaseResult<List<CallbackFieldInfo>> result = SignBaseResult.success(fieldInfoList);
        response.setResult(result);
        return response;
    }

    @Override
    public void rollBack(WeaHookRequest request, WeaHookResponse response, AppInfo appInfo) throws Exception {

    }
}
```

## 22、电子签获取合同文档列表钩子

> 钩子唯一标识code："SIGN\_GET\_CONTRACT\_DOCUMENTS\_HOOK" + "\_" + PlatformConstant.type+"\_"+PlatformConstant.serverType

**22.1 功能说明：**

用于二开服务商，通过esb通用回调下载文档到表单字段时，获取合同中的文档信息

**22.2 参数说明：**

| 参数名 | 类型 | 说明 |
| --- | --- | --- |
| platContractId | String | 合同id |
| globalConfig | GlobalConfig | 全局配置 |
| serverSetting | ServerSetting | 绑定服务配置信息 |
| employee | SimpleEmployee | 用户信息 |

**22.3 响应说明：**

返回值是SignBaseResult\<List\<DownloadDocumentDto\>\>，其中DownloadDocumentDto实体类型定义如下：

| 参数名 | 类型 | 说明 |
| --- | --- | --- |
| platDocumentId | String | 合同文档id |
| title | String | 文档名称 |

**22.4 示例代码：**

```
package com.weaver.seconddev.signcenter.fadada.reghook.callback;

import com.alibaba.fastjson.JSON;
import com.weaver.loom.context.annotation.WeaHookReg;
import com.weaver.loom.context.domain.AppInfo;
import com.weaver.loom.context.domain.WeaHookRequest;
import com.weaver.loom.context.domain.WeaHookResponse;
import com.weaver.loom.context.register.RegHookEvent;
import com.weaver.seconddev.signcenter.fadada.entity.ServerEntity;
import com.weaver.seconddev.signcenter.fadada.reghook.PlatformConstant;
import com.weaver.seconddev.signcenter.fadada.util.Util;
import com.weaver.signcenter.api.entity.base.SignBaseResult;
import com.weaver.signcenter.entity.contract2.DownloadDocumentDto;
import com.weaver.signcenter.entity.server.ServerSetting;
import com.weaver.signcenter.qiyuesuo.pri.sdk.SDKClient;
import com.weaver.signcenter.qiyuesuo.pri.sdk.api.ContractService;
import com.weaver.signcenter.qiyuesuo.pri.sdk.bean.contract.ContractDetail;
import com.weaver.signcenter.qiyuesuo.pri.sdk.bean.contract.Document;
import com.weaver.signcenter.qiyuesuo.pri.sdk.impl.ContractServiceImpl;
import com.weaver.signcenter.qiyuesuo.pri.v3sdk.SdkClient;
import com.weaver.signcenter.qiyuesuo.pri.v3sdk.model.contract.request.ContractViewurlRequest;
import com.weaver.signcenter.qiyuesuo.pri.v3sdk.utils.SdkResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@WeaHookReg(code = "SIGN_GET_CONTRACT_DOCUMENTS_HOOK" + "_" + PlatformConstant.type+"_"+PlatformConstant.serverType, order = 0)
public class SignContractDocumentsRegHook extends RegHookEvent {

    protected static final Logger log = LoggerFactory.getLogger(SignContractDocumentsRegHook.class);

    @Override
    public WeaHookResponse handle(WeaHookRequest hookRequest, WeaHookResponse response, AppInfo appInfo) throws Exception {
        Map<String, Object> params = hookRequest.getParams();
        log.info("SignContractDocumentsRegHook--request:{}", JSON.toJSONString(hookRequest));
        Long platContractId = Util.getLongValue(params.get("platContractId")) ;

        ServerSetting serverSetting = (ServerSetting) params.get("serverSetting");

        ServerEntity serverEntity = ServerEntity.getInstance(serverSetting);

        SDKClient sdkClient = new SDKClient(serverEntity.getOpenUrl(), serverEntity.getAppId(), serverEntity.getSecret());

        ContractService contractService = new ContractServiceImpl(sdkClient);
        List<DownloadDocumentDto> list = new ArrayList<>();
        try {
            ContractDetail contract = contractService.detail(platContractId);
            List<Document> documents = contract.getDocuments();
            if(documents != null){
                for (Document document : documents) {
                    DownloadDocumentDto dto = new DownloadDocumentDto();
                    dto.setPlatDocumentId(Util.null2String(document.getId()));
                    dto.setTitle(document.getTitle());
                    list.add(dto);
                }
            }
            response.setResult(SignBaseResult.success(list));
        }catch (Exception e){
            response.setResult(SignBaseResult.fail(e.getMessage(), true));
        }
        return response;
    }

    @Override
    public void rollBack(WeaHookRequest request, WeaHookResponse response, AppInfo appInfo) throws Exception {

    }
}
```

## 23、电子签获取合同状态钩子

> 钩子唯一标识code："SIGN\_CONTRACT\_STATUS\_HOOK" + "\_" + PlatformConstant.type+"\_"+PlatformConstant.serverType

**23.1 功能说明：**

用于二开服务商，在创建合同，签署合同，发起合同时判断合同状态信息

**23.2 参数说明：**

| 参数名 | 类型 | 说明 |
| --- | --- | --- |
| platContractId | String | 合同id |
| globalConfig | GlobalConfig | 全局配置 |
| serverSetting | ServerSetting | 绑定服务配置信息 |
| logId | Long | 日志id，用于记录接口调用日志 |
| employee | SimpleEmployee | 用户信息 |

**23.3 响应说明：**

返回值是SignBaseResult\<ContractStatusEntity\>，其中ContractStatusEntity实体类型定义如下：

| 参数名 | 类型 | 说明 |
| --- | --- | --- |
| contractSubject | String | 合同标题 |
| contractStatus | String | 合同状态 |
| isComplete | boolean | 是否已完成 |
| isEffective | boolean | 是否有效 |
| isDraft | boolean | 是否草稿 |
| isForceEnd | boolean | 是否强制结束 |
| isTerminated | boolean | 是否终止 |

**23.4 示例代码：**

```
package com.weaver.seconddev.signcenter.fadada.reghook.contract;

import com.alibaba.fastjson.JSON;
import com.weaver.loom.context.annotation.WeaHookReg;
import com.weaver.loom.context.domain.AppInfo;
import com.weaver.loom.context.domain.WeaHookRequest;
import com.weaver.loom.context.domain.WeaHookResponse;
import com.weaver.loom.context.register.RegHookEvent;
import com.weaver.seconddev.signcenter.fadada.entity.ServerEntity;
import com.weaver.seconddev.signcenter.fadada.reghook.PlatformConstant;
import com.weaver.seconddev.signcenter.fadada.util.CollectionUtil;
import com.weaver.seconddev.signcenter.fadada.util.TextUtil;
import com.weaver.seconddev.signcenter.fadada.util.Util;
import com.weaver.signcenter.api.entity.base.SignBaseResult;
import com.weaver.signcenter.entity.contract2.ContractStatusEntity;
import com.weaver.signcenter.entity.server.ServerSetting;
import com.weaver.signcenter.qiyuesuo.pri.sdk.SDKClient;
import com.weaver.signcenter.qiyuesuo.pri.sdk.api.ContractService;
import com.weaver.signcenter.qiyuesuo.pri.sdk.bean.contract.ContractDetail;
import com.weaver.signcenter.qiyuesuo.pri.sdk.bean.contract.Document;
import com.weaver.signcenter.qiyuesuo.pri.sdk.impl.ContractServiceImpl;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@WeaHookReg(code = "SIGN_CONTRACT_STATUS_HOOK" + "_" + PlatformConstant.type+"_"+PlatformConstant.serverType, order = 0)
public class SignContractStatusRegHook extends RegHookEvent {
    @Override
    public WeaHookResponse handle(WeaHookRequest request, WeaHookResponse response, AppInfo appInfo) throws Exception {
        Map<String, Object> params = request.getParams();
        log.info("SignContractInfoRegHook--request:{}", JSON.toJSONString(request));
        Long platContractId = Util.getLongValue(params.get("platContractId"));
        ServerSetting serverSetting = (ServerSetting) params.get("serverSetting");

        ServerEntity serverEntity = ServerEntity.getInstance(serverSetting);

        SDKClient sdkClient = new SDKClient(serverEntity.getOpenUrl(), serverEntity.getAppId(), serverEntity.getSecret());

        ContractService contractService = new ContractServiceImpl(sdkClient);

        ContractDetail contract = contractService.detail(platContractId);
        //存证报告
        Document evidence = CollectionUtil.null2List(contract.getDocuments())
                .stream().filter(item-> "EVIDENCE".equals(item.getUsageValue())).findFirst().orElse(null);//存证报告文档
        boolean hasEvidence = (evidence != null);
        String evidenceType = hasEvidence ? evidence.getType() : "pdf";//存证报告文件类型
        String evidenceName = hasEvidence ? evidence.getTitle() : "";//存证报告文件名称
        //获取合同文档的数量
        List<Document> normalDocuments = CollectionUtil.null2List(contract.getDocuments())
                .stream().filter(item-> "NORMAL".equals(item.getUsageValue()))
                .collect(Collectors.toList());
        int documentNumber = normalDocuments.size();//合同文档数量
        String documentType = "pdf";
        String documentName = "";
        if(documentNumber == 1){
            Document document = normalDocuments.get(0);
            documentType = document.getType();
            documentName = document.getTitle();
        }
        String status = contract.getStatusValue();
        if (status == null) {
            log.info("getContractStatus--获取文件状态失败。契约锁业务ID：" + platContractId);
            SignBaseResult result = SignBaseResult.fail("getContractStatus--获取文件状态失败。契约锁业务ID：" + platContractId, true);
            response.setResult(result);
            return response;
        }
        log.info("getContractStatus--contractStatus:" + status);

        boolean isComplete = "COMPLETE".equals(status);
        boolean isEffective = !(TextUtil.equals(status, "RECALLED", "REJECTED", "CANCELLED", "TERMINATED", "DELETE"));
        boolean isTerminated = "TERMINATED".equals(status);//是否已作废
        boolean isDraft = "DRAFT".equals(status);//草稿
        boolean isForceEnd = "FINISHED".equals(status);//强制完成
        log.info("getContractStatus--isComplete:" + isComplete + "--isEffective:" + isEffective + "--isDraft:" + isDraft);

        ContractStatusEntity contractStatusEntity = new ContractStatusEntity();
        contractStatusEntity.setContractStatus(status);
        contractStatusEntity.setContractSubject(contract.getSubject());
        contractStatusEntity.setComplete(isComplete);
        contractStatusEntity.setEffective(isEffective);
        contractStatusEntity.setDraft(isDraft);
        contractStatusEntity.setForceEnd(isForceEnd);
        contractStatusEntity.setTerminated(isTerminated);
        contractStatusEntity.setDocumentNumber(documentNumber);
        contractStatusEntity.setDocumentName(documentName);
        contractStatusEntity.setDocumentType(TextUtil.isNullOrEmpty(documentType) ? "pdf" : documentType);
        contractStatusEntity.setHasEvidence(hasEvidence ? "1" : "0");
        contractStatusEntity.setEvidenceType(evidenceType);
        contractStatusEntity.setEvidenceName(evidenceName);

        log.info("getContractStatus--end--contractId:" + platContractId);
        SignBaseResult result =  SignBaseResult.success(contractStatusEntity);
        response.setResult(result);
        return response;
    }

    @Override
    public void rollBack(WeaHookRequest request, WeaHookResponse response, AppInfo appInfo) throws Exception {

    }
}
```

## 24、电子签获取通用合同信息钩子

> 钩子唯一标识code："SIGN\_GET\_CONTRACT\_INFO" + "\_" + PlatformConstant.type+"\_"+PlatformConstant.serverType

**24.1 功能说明：**

用于二开服务商，电子签文件列表中展示相应的合同

**24.2 参数说明：**

| 参数名 | 类型 | 说明 |
| --- | --- | --- |
| platContractId | String | 合同id |
| globalConfig | GlobalConfig | 全局配置 |
| serverSetting | ServerSetting | 绑定服务配置信息 |
| logId | Long | 日志id，用于记录接口调用日志 |
| tenantKey | String | 租户key |

**24.3 响应说明：**

返回值是SignBaseResult\<SignContractInfo\>，其中SignContractInfo实体类型定义如下：

| 参数名 | 类型 | 说明 |
| --- | --- | --- |
| platContractId | String | 合同id |
| contractSubject | String | 合同名称 |
| contractStatus | String | 合同状态 |
| tenantName | String | 发起方名称 |
| creatorEmployeeId | Long | 发起人id |
| commonStatus | int | 通用合同状态 |
| signSignatoryInfos | List\<SignSignatoryInfo\> | 签署方信息 |
| signDocumentInfos | List\<SignDocumentInfo\> | 合同文档信息 |
| contractOperateLogInfos | List\<ContractOperateLogInfo\> | 合同日志信息 |

**24.4 示例代码：**

```

package com.weaver.seconddev.signcenter.fadada.reghook.contractList;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.weaver.loom.context.annotation.WeaHookReg;
import com.weaver.loom.context.domain.AppInfo;
import com.weaver.loom.context.domain.WeaHookRequest;
import com.weaver.loom.context.domain.WeaHookResponse;
import com.weaver.loom.context.register.RegHookEvent;
import com.weaver.seconddev.signcenter.fadada.entity.ServerEntity;
import com.weaver.seconddev.signcenter.fadada.reghook.PlatformConstant;
import com.weaver.seconddev.signcenter.fadada.util.QYSUserUtils;
import com.weaver.signcenter.api.entity.base.SignBaseResult;
import com.weaver.signcenter.entity.contract2.SignContractV2;
import com.weaver.signcenter.entity.contractlist.SignActionOperatorsInfo;
import com.weaver.signcenter.entity.contractlist.SignContractInfo;
import com.weaver.signcenter.entity.contractlist.SignDocumentInfo;
import com.weaver.signcenter.entity.contractlist.SignSignatoryInfo;
import com.weaver.signcenter.entity.log.ContractOperateLogInfo;
import com.weaver.signcenter.entity.server.ServerSetting;
import com.weaver.signcenter.enums.server.QYSServerType;
import com.weaver.signcenter.qiyuesuo.pri.sdk.SDKClient;
import com.weaver.signcenter.qiyuesuo.pri.sdk.api.ContractService;
import com.weaver.signcenter.qiyuesuo.pri.sdk.bean.contract.*;
import com.weaver.signcenter.qiyuesuo.pri.sdk.bean.sign.Signatory;
import com.weaver.signcenter.qiyuesuo.pri.sdk.bean.sign.SignatoryStatus;
import com.weaver.signcenter.qiyuesuo.pri.sdk.common.exception.PrivateAppException;
import com.weaver.signcenter.qiyuesuo.pri.sdk.impl.ContractServiceImpl;
import com.weaver.signcenter.util.Util;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.*;

@WeaHookReg(code = "SIGN_GET_CONTRACT_INFO" + "_" + PlatformConstant.type+"_"+PlatformConstant.serverType, order = 0)
public class SignContractInfoRegHook extends RegHookEvent {

    protected static final Logger log = LoggerFactory.getLogger(SignContractListButtonRegHook.class);

    @Autowired
    private QYSUserUtils qysUserUtils;

    @Override
    public WeaHookResponse handle(WeaHookRequest request, WeaHookResponse response, AppInfo appInfo) throws Exception {

        Map<String, Object> params = request.getParams();
        log.info("SignContractInfoRegHook--request:{}", JSON.toJSONString(request));
        ServerSetting serverSetting = (ServerSetting) params.get("serverSetting");

        ServerEntity serverEntity = ServerEntity.getInstance(serverSetting);

        SDKClient sdkClient = new SDKClient(serverEntity.getOpenUrl(), serverEntity.getAppId(), serverEntity.getSecret());

        ContractService contractService = new ContractServiceImpl(sdkClient);
        SignContractV2 signContract = (SignContractV2) params.get("signContract");
        String tenantKey = serverSetting.getTenantKey();
        Long logId = (Long) params.get("logId");
        SignBaseResult<SignContractInfo> result = getSignContractInfo(signContract, signContract.getCreator(), tenantKey, new HashMap<>(), contractService, logId);
        response.setResult(result);
        return response;
    }

    @Override
    public void rollBack(WeaHookRequest request, WeaHookResponse response, AppInfo appInfo) throws Exception {

    }

    /**
     * 查询合同详情
     *
     * @param contractId 契约锁业务ID
     * @return 合同对象
     */
    private SignBaseResult<ContractDetail> getContractById(ContractService contractService, Long contractId, Long logId){
        log.info("getContractById--contractId:" + contractId);
        if (contractId == null || contractId <= 0) {
            return SignBaseResult.fail("contractId is null", true);
        }
        try {
            ContractDetail contract = contractService.detail(contractId);
            return SignBaseResult.success(contract);
        } catch (Exception e) {
            log.error("getContractById error", e);
            return SignBaseResult.fail(e.getMessage());
        }
    }

    public SignBaseResult<SignContractInfo> getSignContractInfo(SignContractV2 signContract, Long employeeId, String tenantKey, Map<String, Object> params, ContractService contractService, Long logId) {
        log.info("syncContractInfo---start---SignContractV2:{}---tenantKey:{}", JSON.toJSONString(signContract), tenantKey);
        Long contractId = signContract.getContractId();
        if(contractId == null || contractId <= 0){
            return SignBaseResult.fail("contractId is null", true);
        }
        SignBaseResult<ContractDetail> contractResult = getContractById(contractService, contractId, logId);
        if (!contractResult.isSuccess()) {
            return SignBaseResult.fail(contractResult.getMessage());
        }
        ContractDetail contract = contractResult.getData();
        SignContractInfo signContractInfo = new SignContractInfo();

        Date date = new Date();
        signContractInfo.setCreateTime(date);
        signContractInfo.setUpdateTime(date);
        signContractInfo.setTenantKey(tenantKey);
        signContractInfo.setPlatformType(PlatformConstant.id);//契约锁
        signContractInfo.setServerId(signContract.getServerId());
        signContractInfo.setEntityModule(signContract.getModule());
        signContractInfo.setEntitySubModule("");
        signContractInfo.setEntityId(signContract.getEntityId());
        signContractInfo.setPlatContractId(Util.null2String(contractId));
        signContractInfo.setBizId(null);
        signContractInfo.setCommonStatus(getContractCommonStatus(contract.getStatusValue()));
        signContractInfo.setContractSubject(contract.getSubject());
        signContractInfo.setContractDescription(contract.getDescription());
        int ordinal = (contract.getOrdinal() == null || !contract.getOrdinal()) ? 0 : 1;
        signContractInfo.setOrdinal(ordinal);
        signContractInfo.setSn(contract.getSn());
        String status = contract.getStatusValue();
        signContractInfo.setContractStatus(status);
        signContractInfo.setCategoryId(contract.getCategoryId());
        signContractInfo.setCategoryName(contract.getCategoryName());
        Long creatorId = contract.getCreatorId();
        signContractInfo.setCreatorId(creatorId);
        signContractInfo.setCreatorType(contract.getCreatorTypeValue());
        signContractInfo.setCreatorName(contract.getCreatorName());
        String creatorNumber = contract.getCreatorNumber();
        signContractInfo.setCreatorNumber(creatorNumber);
        //设置合同发起人对应的et用户
        Long creatorEmployeeId = employeeId;
        signContractInfo.setCreatorEmployeeId(creatorEmployeeId);
        signContractInfo.setCreator(creatorEmployeeId);
        signContractInfo.setTenantType(contract.getTenantTypeValue());
        signContractInfo.setTenantId(contract.getTenantId());
        signContractInfo.setTenantName(contract.getTenantName());
        signContractInfo.setInvalidComments(contract.getComments());
        signContractInfo.setExpireTime(contract.getExpireTime());
        signContractInfo.setEndTime(contract.getEndTime());
        if(Objects.equals(contract.getStatusValue(), "DRAFT")){
            signContractInfo.setContractCreateTime(contract.getCreateTime());//合同创建时间
        } else{
            signContractInfo.setSendTime(contract.getCreateTime());//合同发起后 创建时间为合同发起时间
        }
        signContractInfo.setContractType(contract.getTypeValue());
        signContractInfo.setServerType(QYSServerType.PRIVATE.getId());
        signContractInfo.setCreateType(signContract.getCreateType());
        signContractInfo.setSignContractId(signContract.getId());
        List<SignSignatoryInfo> signatoryInfos = new ArrayList<>();
        signContractInfo.setSignSignatoryInfos(signatoryInfos);
        List<Signatory> signatories = contract.getSignatories();
        //契约锁员工id和签署方名称的对应关系
        Map<Long, String> qysOperatorSignatoryRef = new HashMap<>();
        if(signatories!=null && !signatories.isEmpty()){
            StringJoiner receivers = new StringJoiner(",");
            //合同签署方
            for(Signatory signatory: signatories){
                SignSignatoryInfo signSignatoryInfo = new SignSignatoryInfo();
                signSignatoryInfo.setCreateTime(date);
                signSignatoryInfo.setUpdateTime(date);
                signSignatoryInfo.setCommonStatus(getSignatoryCommonStatus(signatory.getStatusValue()));
                signSignatoryInfo.setCreator(creatorEmployeeId);
                signSignatoryInfo.setTenantKey(tenantKey);
                signSignatoryInfo.setPlatSignatoryId(Util.null2String(signatory.getId()));
                signSignatoryInfo.setTenantType(signatory.getTenantTypeValue());
                signSignatoryInfo.setTenantId(Util.null2String(signatory.getTenantId()));
                String tenantName = Util.null2String(signatory.getTenantName());
                signSignatoryInfo.setTenantName(tenantName);
                signSignatoryInfo.setSignatoryStatus(signatory.getStatusValue());
                signSignatoryInfo.setReceiverType(signatory.getReceiverTypeValue());
                Long receiverId = signatory.getReceiverId();
                signSignatoryInfo.setReceiverId(receiverId);
                signSignatoryInfo.setReceiverName(signatory.getReceiverName());
                String contact = signatory.getContact();
                signSignatoryInfo.setContact(contact);
                String receiverNumber = signatory.getReceiverNumber();
                signSignatoryInfo.setReceiverNumber(receiverNumber);

                Long userIdByContact = qysUserUtils.getUserIdByContact(contact, tenantKey);

                signSignatoryInfo.setReceiverEmployeeId(userIdByContact);
                signSignatoryInfo.setSerialNo(signatory.getSerialNo());
                int sponsor = (signatory.getSponsor() == null || !signatory.getSponsor()) ? 0 : 1;
                if(sponsor == 0){
                    receivers.add(tenantName);
                }
                signSignatoryInfo.setSponsor(sponsor);
                signSignatoryInfo.setSignatoryCreateTime(signatory.getCreateTime());
                signSignatoryInfo.setSignatoryUpdateTime(signatory.getUpdateTime());
                signSignatoryInfo.setSignatoryReceiveTime(signatory.getReceiveTime());
                if(Objects.equals(signatory.getStatusValue(), "COMPLETE") || Objects.equals(signatory.getStatusValue(), "FINISHED")){
                    signSignatoryInfo.setSignatoryComplateTime(signatory.getUpdateTime());
                }
                List<Action> actions = signatory.getActions();
                List<com.weaver.signcenter.entity.contractlist.SignActionInfo> signActionInfos = new ArrayList<>();
                signSignatoryInfo.setSignActionInfos(signActionInfos);
                if(actions != null && !actions.isEmpty()){
                    //签署动作
                    for(Action action: actions){
                        com.weaver.signcenter.entity.contractlist.SignActionInfo signActionInfo = new com.weaver.signcenter.entity.contractlist.SignActionInfo();
                        signActionInfo.setCreateTime(date);
                        signActionInfo.setUpdateTime(date);
                        signActionInfo.setCreator(creatorEmployeeId);
                        signActionInfo.setTenantKey(tenantKey);
                        signActionInfo.setPlatActionId(Util.null2String(action.getId()));
                        signActionInfo.setCommonStatus(getActionCommonStatus(action.getStatusValue()));
                        signActionInfo.setActionType(action.getTypeValue());
                        signActionInfo.setActionName(action.getTypeValue());
                        signActionInfo.setActionStatus(action.getStatusValue());
                        signActionInfo.setActionCreateTime(action.getCreateTime());
                        signActionInfo.setActionCompleteTime(action.getCompleteTime());
                        signActionInfo.setSerialNo(action.getSerialNo());
                        //签署动作操作人
                        List<Operator> actionOperators = action.getActionOperators();
                        List<SignActionOperatorsInfo> signActionOperatorsInfos = new ArrayList<>();
                        signActionInfo.setSignActionOperatorsInfos(signActionOperatorsInfos);
                        if(actionOperators != null && !actionOperators.isEmpty()){
                            for (Operator operator: actionOperators){
                                SignActionOperatorsInfo operatorsInfo = new SignActionOperatorsInfo();
                                operatorsInfo.setCreateTime(date);
                                operatorsInfo.setUpdateTime(date);
                                operatorsInfo.setCreator(creatorEmployeeId);
                                operatorsInfo.setTenantKey(tenantKey);
                                operatorsInfo.setOperatorType(operator.getOperatorTypeValue());
                                Long qysOperatorId = operator.getOperatorId();
                                operatorsInfo.setOperatorId(qysOperatorId);

                                operatorsInfo.setOperatorName(operator.getOperatorName());
                                String operatorContact = operator.getOperatorContact();
                                operatorsInfo.setOperatorContact(operatorContact);
                                String operatorNumber = operator.getOperatorNumber();
                                operatorsInfo.setOperatorNumber(operatorNumber);
                                String operatorEmail = operator.getOperatorEmail();
                                operatorsInfo.setOperatorEmail(operatorEmail);
                                //operatorsInfo.setCardNo(operator.getCardNo());//暂不记录
                                operatorsInfo.setAccountNo(operator.getAccountNo());
                                operatorsInfo.setOpenUserId(operator.getOpenUserId());
                                Long operatorEmployeeId = qysUserUtils.getUserIdByContact(operatorContact, tenantKey);
                                operatorsInfo.setOperatorEmployeeId(operatorEmployeeId);
                                signActionOperatorsInfos.add(operatorsInfo);
                            }
                        }
                        signActionInfos.add(signActionInfo);
                    }
                }
                signatoryInfos.add(signSignatoryInfo);
            }
            signContractInfo.setReceiverSignatories(receivers.toString());
        }
        List<Document> documents = contract.getDocuments();
        List<SignDocumentInfo> signDocumentInfos = new ArrayList<>();
        signContractInfo.setSignDocumentInfos(signDocumentInfos);
        if(documents != null && !documents.isEmpty()){
            //合同文档
            for(Document document: documents){
                SignDocumentInfo signDocumentInfo = new SignDocumentInfo();
                signDocumentInfo.setCreateTime(date);
                signDocumentInfo.setUpdateTime(date);
                signDocumentInfo.setCreator(-1L);
                signDocumentInfo.setTenantKey(tenantKey);
                signDocumentInfo.setPlatDocumentId(Util.null2String(document.getId()));
                signDocumentInfo.setTitle(document.getTitle());
                signDocumentInfo.setPages(document.getPages());
                signDocumentInfo.setDocumentSize(document.getSize());
                signDocumentInfo.setDocumentType(document.getType());
                signDocumentInfo.setDocumentUsage(document.getUsageValue());
                signDocumentInfo.setHasParams(0);
                signDocumentInfos.add(signDocumentInfo);
            }
        }
        //记录操作日志
        List<ContractOperateLogInfo> result = getContractOperateLogs(contractId, employeeId, tenantKey);
        signContractInfo.setContractOperateLogInfos(result);
        return SignBaseResult.success(signContractInfo);
    }

    /**
     * 获取合同操作日志
     * @param contractId
     * @return
     */
    public List<ContractOperateLogInfo> getContractOperateLogs(Long contractId, Long employeeId, String tenantKey){
        log.info("getContractOperationLog--start--contractId:{}", contractId);
        List<ContractOperateLogInfo> operateLogs = new ArrayList<>();
        try {
            ContractOperateLogInfo operateLogInfo = new ContractOperateLogInfo();
            operateLogInfo.setLogType(2);
            operateLogInfo.setOperateTime(new Date());
            operateLogInfo.setOperationType(Util.null2String(290285));
            operateLogInfo.setQysOperatorId(1l);
            operateLogInfo.setLogOperatorName("张三");
            operateLogInfo.setTenantName("张三");
            operateLogInfo.setOperatorId(employeeId);
            operateLogInfo.setOperateDetail("日志详情");
            operateLogInfo.setResponseData(JSONObject.toJSONString(operateLogInfo));
            operateLogs.add(operateLogInfo);

        } catch (PrivateAppException e) {
            log.error("getContractOperationLog--获取合同操作日志失败,错误信息:{errorMessage:"+e.getMessage()+"}", e);
            return new ArrayList<>();
        }
        log.info("getContractOperationLog--end--contractId:{}", contractId);
        return operateLogs;
    }

    public int getContractCommonStatus(String status){
        int commonStatus = 0;
        if (ContractStatus.DRAFT.name().equals(status)) {
            commonStatus = 3;
        } else if (ContractStatus.FILLING.name().equals(status)) {
            commonStatus = 4;
        } else if (ContractStatus.SIGNING.name().equals(status)) {
            commonStatus = 5;
        } else if (ContractStatus.COMPLETE.name().equals(status)) {
            commonStatus = 6;
        } else if (ContractStatus.REJECTED.name().equals(status)) {
            commonStatus = 8;
        } else if (ContractStatus.RECALLED.name().equals(status)) {
            commonStatus =7;
        } else if (ContractStatus.EXPIRED.name().equals(status)) {
            commonStatus = 11;
        } else if (ContractStatus.TERMINATING.name().equals(status)) {
            commonStatus = 10;
        } else if (ContractStatus.TERMINATED.name().equals(status)) {
            commonStatus = 19;
        } else if (ContractStatus.DELETE.name().equals(status)) {
            commonStatus = 12;
        } else if (ContractStatus.FINISHED.name().equals(status)) {
            commonStatus = 13;
        } else if(ContractStatus.ENDED.name().equals(status)) {
            commonStatus = 14;
        } else{
            commonStatus = 99;
        }
        return commonStatus;
    }

    public int getSignatoryCommonStatus(String status){
        int commonStatus = 0;
        if (SignatoryStatus.DRAFT.name().equals(status) ||
                SignatoryStatus.FILLING.name().equals(status) ||
                SignatoryStatus.FILLED.name().equals(status)) {
            commonStatus = 0; //待发起
        } else if (SignatoryStatus.WAITING.name().equals(status)) {
            commonStatus = 1;//等待签署
        } else if (SignatoryStatus.SIGNING.name().equals(status)
                || SignatoryStatus.TERMINATING.name().equals(status)) {//作废确认中也算是签署中
            commonStatus = 2;//签署中
        } else if (SignatoryStatus.COMPLETE.name().equals(status)) {
            commonStatus = 3;//已完成
        } else if (
                SignatoryStatus.TERMINATED.name().equals(status) // 已作废
                        || SignatoryStatus.REJECTED.name().equals(status) // 已退回
                        || SignatoryStatus.DISABLED.name().equals(status) //  已失效
        ) {
            commonStatus = 4; //无效
        } else if (SignatoryStatus.FINISHED.name().equals(status)) {
            commonStatus = 5;//强制结束
        }else {
            commonStatus = 99;//其他。
        }
        return commonStatus;
    }

    public int getActionCommonStatus(String status){
        int commonStatus = 0;
        if(ActionStatus.FILLED.name().equals(status)){
            commonStatus = 3; //已完成
        }else if(ActionStatus.WAITING.name().equals(status)){
            commonStatus = 1;//等待签署
        }else if(ActionStatus.FILLING.name().equals(status) || ActionStatus.SIGNING.name().equals(status)){
            commonStatus = 2;//签署中
        }else if(ActionStatus.SIGNED.name().equals(status) ){
            commonStatus = 3;//已完成
        }else if(
                ActionStatus.DISCARDED.name().equals(status) // 废弃
                        || ActionStatus.REJECTED.name().equals(status) // 拒绝
                        || ActionStatus.DISABLED.name().equals(status)// 已失效
        ){
            commonStatus = 4; //无效
        }else if(ActionStatus.FINISHED.name().equals(status)){
            commonStatus = 5; //强制结束
        }else{
            commonStatus = 99;//其他
        }
        return commonStatus;
    }
}
```

## 25、电子签文件列表按钮钩子

> 钩子唯一标识code："SIGN\_CONTRACT\_LIST\_OPERATE\_BUTTON\_LIST\_HOOK" + "\_" + PlatformConstant.type+"\_"+PlatformConstant.serverType

**25.1 功能说明：**

用于二开服务商，获取电子签文件列表中，合同卡片信息中的按钮

**25.2 参数说明：**

| 参数名 | 类型 | 说明 |
| --- | --- | --- |
| signContractInfo | SignContractInfo | 通用合同信息 |
| globalConfig | GlobalConfig | 全局配置 |
| serverSetting | ServerSetting | 绑定服务配置信息 |
| isMobile | boolean | 是否移动端 |
| employee | SimpleEmployee | 用户信息 |

**25.3 响应说明：**

返回值是List\<OperateButtonEntity\>，其中OperateButtonEntity实体类型定义如下：

| 参数名 | 类型 | 说明 |
| --- | --- | --- |
| id | String | 按钮id |
| name | String | 按钮名称 |
| jumpUrl | boolean | 是否跳转链接 |
| downloadFile | boolean | 是否下载文件 |
| overrideExecute | boolean | 是否重写执行逻辑 |

**25.4 示例代码：**

```
package com.weaver.seconddev.signcenter.fadada.reghook.contractList;

import com.alibaba.fastjson.JSON;
import com.weaver.loom.context.annotation.WeaHookReg;
import com.weaver.loom.context.domain.AppInfo;
import com.weaver.loom.context.domain.WeaHookRequest;
import com.weaver.loom.context.domain.WeaHookResponse;
import com.weaver.loom.context.register.RegHookEvent;
import com.weaver.seconddev.signcenter.fadada.reghook.PlatformConstant;
import com.weaver.seconddev.signcenter.fadada.util.Util;
import com.weaver.signcenter.api.entity.base.SignBaseResult;
import com.weaver.signcenter.api.entity.electronic.SignButtonItem;
import com.weaver.signcenter.api.entity.electronic.SignButtonResult;
import com.weaver.signcenter.api.enums.SignButtonType;
import com.weaver.signcenter.entity.contract2.SignContractV2;
import com.weaver.signcenter.entity.contractlist.OperateButtonEntity;
import com.weaver.signcenter.entity.server.WfSetBaseInfo;
import com.weaver.signcenter.entity.workflow.SignRequestBaseEntity;
import com.weaver.signcenter.enums.button.ContractListButtonEnum;
import com.weaver.teams.domain.EntityType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@WeaHookReg(code = "SIGN_CONTRACT_LIST_OPERATE_BUTTON_LIST_HOOK" + "_" + PlatformConstant.type+"_"+PlatformConstant.serverType, order = 0)
public class SignContractListButtonRegHook extends RegHookEvent {

    protected static final Logger log = LoggerFactory.getLogger(SignContractListButtonRegHook.class);

    @Override
    public WeaHookResponse handle(WeaHookRequest request, WeaHookResponse response, AppInfo appInfo) throws Exception {
        Map<String, Object> params = request.getParams();
        log.info("SignContractListButtonRegHook--request:{}", JSON.toJSONString(request));

        List<OperateButtonEntity> list = new ArrayList<>();

        OperateButtonEntity result = new OperateButtonEntity();
        result.setId(PlatformConstant.type+"contractListButton1");
        result.setMainButton(true);
        result.setJumpUrl(true);
        result.setName("测试二开按钮1");
        result.setOverrideExecute(true);
        list.add(result);
        result = new OperateButtonEntity();
        result.setId(PlatformConstant.type+"contractListButton2");
        result.setMainButton(true);
        result.setJumpUrl(true);
        result.setName("测试二开按钮1");
        result.setOverrideExecute(true);
        list.add(result);
        list.add(ContractListButtonEnum.signContract.getSignButtonEntity());
        list.add(ContractListButtonEnum.downloadContract.getSignButtonEntity());

        response.setResult(list);
        return response;
    }

    @Override
    public void rollBack(WeaHookRequest request, WeaHookResponse response, AppInfo appInfo) throws Exception {

    }
}
```

## 26、电子签文件列表按钮执行钩子

> 钩子唯一标识code："SIGN\_CONTRACT\_LIST\_OPERATE\_BUTTON\_EXECUTE\_HOOK" + "\_" + PlatformConstant.type+"\_"+PlatformConstant.serverType

**26.1 功能说明：**

用于二开服务商，电子签文件列表-合同卡片信息中的按钮点击后的执行事件

**26.2 参数说明：**

| 参数名 | 类型 | 说明 |
| --- | --- | --- |
| signContractInfo | SignContractInfo | 通用合同信息 |
| buttonId | String | 按钮id |
| globalConfig | GlobalConfig | 全局配置 |
| serverSetting | ServerSetting | 绑定服务配置信息 |
| isMobile | boolean | 是否移动端 |
| employee | SimpleEmployee | 用户信息 |

**26.3 响应说明：**

返回值是SignBaseResult，用来标识执行的结果

**26.4 示例代码：**

```
package com.weaver.seconddev.signcenter.fadada.reghook.contractList;

import com.alibaba.fastjson.JSON;
import com.weaver.loom.context.annotation.WeaHookReg;
import com.weaver.loom.context.domain.AppInfo;
import com.weaver.loom.context.domain.WeaHookRequest;
import com.weaver.loom.context.domain.WeaHookResponse;
import com.weaver.loom.context.register.RegHookEvent;
import com.weaver.seconddev.signcenter.fadada.reghook.PlatformConstant;
import com.weaver.seconddev.signcenter.fadada.util.Util;
import com.weaver.signcenter.api.entity.base.SignBaseResult;
import com.weaver.signcenter.entity.contractlist.OperateButtonEntity;
import com.weaver.signcenter.entity.contractlist.SignContractInfo;
import com.weaver.signcenter.entity.server.ServerSetting;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@WeaHookReg(code = "SIGN_CONTRACT_LIST_OPERATE_BUTTON_EXECUTE_HOOK" + "_" + PlatformConstant.type+"_"+PlatformConstant.serverType, order = 0)
public class SignContractListButtonExecuteRegHook extends RegHookEvent {

    protected static final Logger log = LoggerFactory.getLogger(SignContractListButtonExecuteRegHook.class);

    @Override
    public WeaHookResponse handle(WeaHookRequest request, WeaHookResponse response, AppInfo appInfo) throws Exception {
        Map<String, Object> params = request.getParams();
        log.info("SignContractListButtonExecuteRegHook--request:{}", JSON.toJSONString(request));

        String buttonId = Util.null2String(params.get("buttonId"));
        SignContractInfo signContractInfo = (SignContractInfo)params.get("signContractInfo");
        ServerSetting serverSetting = (ServerSetting)(params.get("serverSetting"));
        Map<String, Object> data = new HashMap<>();
        String url = "";
        if((PlatformConstant.type+"contractListButton1").equals(buttonId)){
            url = "https://www.baidu.com/contractListButtonExecute/"+buttonId+"/"+serverSetting.getId()+"/"+signContractInfo.getPlatContractId();
        }else{
            //其他按钮逻辑
            url = "https://www.baidu.com/otherButton/"+buttonId+"/"+serverSetting.getId()+"/"+signContractInfo.getPlatContractId();
        }
        data.put("url",url);
        response.setResult(SignBaseResult.success(data));
        return response;
    }

    @Override
    public void rollBack(WeaHookRequest request, WeaHookResponse response, AppInfo appInfo) throws Exception {

    }
}
```

## 27、电子签全局配置钩子

> 钩子唯一标识code："SIGNCENTER\_GLOBAL\_SETTING\_HOOK" + "\_" + PlatformConstant.type

**27.1 功能说明：**

用于二开服务商，获取服务商对应的全局配置信息

**27.2 参数说明：**

| 参数名 | 类型 | 说明 |
| --- | --- | --- |
| form | WeaForm | 按钮id |

**27.3 响应说明：**

接口返回值跟入参格式一致

| 参数名 | 类型 | 说明 |
| --- | --- | --- |
| form | WeaForm | 按钮id |

**27.4 示例代码：**

```
package com.weaver.seconddev.signcenter.fadada.reghook.global;

import com.alibaba.fastjson.JSON;
import com.weaver.common.component.form.WeaForm;
import com.weaver.common.component.form.group.WeaFormGroup;
import com.weaver.common.component.form.item.WeaFormItem;
import com.weaver.common.component.form.item.WeaFormItemType;
import com.weaver.common.component.form.layout.WeaFormLayout;
import com.weaver.loom.context.annotation.WeaHookReg;
import com.weaver.loom.context.domain.AppInfo;
import com.weaver.loom.context.domain.WeaHookRequest;
import com.weaver.loom.context.domain.WeaHookResponse;
import com.weaver.loom.context.register.RegHookEvent;
import com.weaver.seconddev.signcenter.fadada.reghook.PlatformConstant;
import com.weaver.seconddev.signcenter.fadada.reghook.callback.SignCallbackEntityRegHook;
import com.weaver.seconddev.signcenter.fadada.util.ComponentUtils;
import com.weaver.seconddev.signcenter.fadada.util.Util;
import com.weaver.signcenter.entity.form.RuleBase;
import com.weaver.signcenter.entity.form.SignCascadeRules;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;

@WeaHookReg(code = "SIGNCENTER_GLOBAL_SETTING_HOOK" + "_" + PlatformConstant.type, order = 0)
public class SignGlobalConfigHook extends RegHookEvent {

    private static final String _desc = "_desc";

    protected static final Logger log = LoggerFactory.getLogger(SignCallbackEntityRegHook.class);

    @Override
    public WeaHookResponse handle(WeaHookRequest hookRequest, WeaHookResponse response, AppInfo appInfo) throws Exception {
        Map<String, Object> map = hookRequest.getParams();
        log.info("SignServerCasecadesHook--hookRequest:{}", JSON.toJSONString(hookRequest));

        WeaForm form = (WeaForm)map.get("form");
        Map<String, WeaFormItem> items = form.getItems();
        List<List<WeaFormLayout>> layouts = form.getLayout();
        List<WeaFormGroup> groups = form.getGroups();
        Map<String, Object> data = form.getData();

        Map<String, Object> otherParams = new HashMap<>();
        otherParams.put("size", "sm");
        //使用TAB页打开文件页面
        WeaFormItem item = new WeaFormItem(WeaFormItemType.SWITCH);
        item.setOtherParams(otherParams);
        items.put("CF_cs1_fadada", item);

        item = new WeaFormItem(WeaFormItemType.INPUT);
        item.setValue("这是一个测试说明");
        item.setReadOnly(true);
        items.put("CF_cs1_fadada"+_desc, item);

        WeaFormLayout layout =ComponentUtils.createLayout("CF_cs1_fadada", "测试字段", new String[]{"CF_cs1_fadada"}, 12, false, null, "CF_cs1_fadada", "");

        WeaFormLayout layoutDesc = ComponentUtils.createLayout("CF_cs1_fadada" + _desc, "", new String[]{"CF_cs1_fadada" + _desc}, 0, false, null, "CF_cs1_fadada", "");

        layouts.add(Collections.singletonList(layout));

        layouts.add(Collections.singletonList(layoutDesc));

        String csVal = Util.null2String(data.get("CF_cs1_fadada"));
        if("true".equals(csVal) || "1".equals(csVal)){
            data.put("CF_cs1_fadada", 1);
        }else{
            data.put("CF_cs1_fadada", 0);
        }

        groups.add(new WeaFormGroup("CF_cs1_fadada", "", true));

        response.setResult(map);

        return response;
    }

    @Override
    public void rollBack(WeaHookRequest request, WeaHookResponse response, AppInfo appInfo) throws Exception {

    }
}
```

## 28、电子签同步印章钩子

> 钩子唯一标识code："SIGNCENTER\_SYNC\_SEAL\_HOOK" + "\_" + PlatformConstant.type+"\_"+PlatformConstant.serverType

**28.1 功能说明：**

用于二开服务商，同步绑定服务中的印章到oa中

**28.2 参数说明：**

| 参数名 | 类型 | 说明 |
| --- | --- | --- |
| serverSetting | serverSetting | 绑定服务信息 |
| logId | Long | 日志信息 |

**28.3 响应说明：**

返回值是SignBaseResult\<List\<CommonSeal\>\>，其中CommonSeal实体定义如下

| 参数名 | 类型 | 说明 |
| --- | --- | --- |
| platSealId | String | 印章id |
| sealName | String | 印章名称 |
| sealAttribute | String | 印章形式 |
| serverId | Long | 服务id |
| serverType | int | 服务类型 |

**28.4 示例代码：**

```
package com.weaver.seconddev.signcenter.fadada.reghook.syncData;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.weaver.loom.context.annotation.WeaHookReg;
import com.weaver.loom.context.domain.AppInfo;
import com.weaver.loom.context.domain.WeaHookRequest;
import com.weaver.loom.context.domain.WeaHookResponse;
import com.weaver.loom.context.register.RegHookEvent;
import com.weaver.seconddev.signcenter.fadada.entity.ServerEntity;
import com.weaver.seconddev.signcenter.fadada.reghook.PlatformConstant;
import com.weaver.seconddev.signcenter.fadada.util.TextUtil;
import com.weaver.seconddev.signcenter.fadada.util.TimeUtil;
import com.weaver.signcenter.api.entity.base.SignBaseResult;
import com.weaver.signcenter.api.entity.base.SignEmployee;
import com.weaver.signcenter.entity.seal.CommonSeal;
import com.weaver.signcenter.entity.server.ServerSetting;
import com.weaver.signcenter.entity.template.CommonTemplate;
import com.weaver.signcenter.qiyuesuo.pri.sdk.SDKClient;
import com.weaver.signcenter.qiyuesuo.pri.sdk.api.SealService;
import com.weaver.signcenter.qiyuesuo.pri.sdk.api.TemplateService;
import com.weaver.signcenter.qiyuesuo.pri.sdk.bean.company.Company;
import com.weaver.signcenter.qiyuesuo.pri.sdk.bean.seal.Seal;
import com.weaver.signcenter.qiyuesuo.pri.sdk.bean.seal.SealCondition;
import com.weaver.signcenter.qiyuesuo.pri.sdk.bean.seal.SealPermissionGroupBean;
import com.weaver.signcenter.qiyuesuo.pri.sdk.bean.template.Template;
import com.weaver.signcenter.qiyuesuo.pri.sdk.bean.template.TemplateGroup;
import com.weaver.signcenter.qiyuesuo.pri.sdk.bean.template.TemplateGroupRequest;
import com.weaver.signcenter.qiyuesuo.pri.sdk.bean.user.User;
import com.weaver.signcenter.qiyuesuo.pri.sdk.impl.SealServiceImpl;
import com.weaver.signcenter.qiyuesuo.pri.sdk.impl.TemplateServiceImpl;
import com.weaver.signcenter.util.Util;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@WeaHookReg(code = "SIGNCENTER_SYNC_SEAL_HOOK" + "_" + PlatformConstant.type+"_"+PlatformConstant.serverType, order = 0)
public class SignSyncSealRegHook extends RegHookEvent {

    protected static final Logger log = LoggerFactory.getLogger(SignSyncSealRegHook.class);

    @Override
    public WeaHookResponse handle(WeaHookRequest hookRequest, WeaHookResponse response, AppInfo appInfo) throws Exception {
        Map<String, Object> params = hookRequest.getParams();
        log.info("SignSyncSealRegHook--request:{}", JSON.toJSONString(hookRequest));

        ServerSetting serverSetting = (ServerSetting) params.get("serverSetting");

        ServerEntity serverEntity = ServerEntity.getInstance(serverSetting);

        SDKClient sdkClient = new SDKClient(serverEntity.getOpenUrl(), serverEntity.getAppId(), serverEntity.getSecret());

        SealService sealService = new SealServiceImpl(sdkClient);

        response.setResult(getSeal(serverSetting.getTenantKey(), serverSetting.getId(), "ELECTRONIC", sealService));
        return response;
    }

    public SignBaseResult<List<CommonSeal>> getSeal(String tenantKey, Long serverId, String category, SealService sealService) {
        category = TextUtil.null2String(category).trim();

        SealCondition sealCondition = new SealCondition();
        sealCondition.setSealQueryStatus("ALL");
        String sealAttribute = "ELECTRONIC".equalsIgnoreCase(category) ? "ELECTRONIC" : "PHYSICS";
        sealCondition.setCategoryValue(sealAttribute);

        List<Company> companies = null;
        try {
            companies = sealService.innercompanySealList(sealCondition);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return SignBaseResult.fail(e.getMessage());
        }

        if (companies == null) {
            return SignBaseResult.fail("companies is null");
        }

        List<Seal> seals = new ArrayList<>();
        for (Company company : companies) {
            if (company == null) {
                continue;
            }

            List<Seal> sealList = company.getSeals();
            if (sealList == null) {
                continue;
            }

            seals.addAll(sealList);
        }

        List<CommonSeal> list = new ArrayList<>();
        for (Seal seal : seals) {
            if (seal == null) {
                continue;
            }
            CommonSeal CommonSeal = getCommonSeal(seal);
            if (CommonSeal == null) {
                continue;
            }
            CommonSeal.setSealAttribute(sealAttribute);
            list.add(CommonSeal);
        }
        return SignBaseResult.success(list);
    }

    private CommonSeal getCommonSeal(Seal seal) {
        if (seal == null) {
            return null;
        }

        CommonSeal obj = new CommonSeal();
        obj.setPlatSealId(Util.null2String(seal.getId()));
        obj.setDeviceId(seal.getDeviceId());
        obj.setOwner(seal.getOwner());
        obj.setOwnerName(seal.getOwnerName());
        obj.setSealName(seal.getName());
        obj.setType(seal.getTypeValue());
        obj.setSpec(seal.getSpec());
        obj.setSealKey(seal.getSealKey());
        obj.setStatus(TextUtil.null2String(JSONObject.parseObject(seal.getStatus()).get("key")));
        obj.setCreateDateTime(seal.getCreateTime() == null ? null : seal.getCreateTime());
        obj.setUseCount(seal.getUserCount());
        obj.setSealAttribute(Util.null2String(seal.getSealAttributeValue()));
        obj.setSealTypeName(seal.getSealCategoryName());
        obj.setCategory(seal.getCategoryValue());
        obj.setManagers(transSealUsers(seal.getSealAdminGroup()));
        obj.setUsers(transSealUsers(seal.getSealUseGroup()));
        return obj;
    }

    private CommonSeal getSealById(Long sealId, SealService sealService) {
        if (sealId == null || sealId <= 0) {
            return null;
        }

        Seal seal = getSealDetail(sealId,sealService);
        if (seal == null) {
            return null;
        }

        CommonSeal obj = new CommonSeal();
        obj.setPlatSealId(Util.null2String(seal.getId()));
        obj.setDeviceId(seal.getDeviceId());
        obj.setOwner(seal.getOwner());
        obj.setOwnerName(seal.getOwnerName());
        obj.setSealName(seal.getName());
        obj.setType(seal.getTypeValue());
        obj.setSpec(seal.getSpec());
        obj.setSealKey(seal.getSealKey());
        obj.setStatus(TextUtil.null2String(JSONObject.parseObject(seal.getStatus()).get("key")));
        obj.setCreateDateTime(seal.getCreateTime() == null ? null : seal.getCreateTime());
        obj.setUseCount(seal.getUserCount());
        obj.setSealAttribute(Util.null2String(seal.getSealAttributeValue()));
        obj.setSealTypeName(seal.getSealCategoryName());
        obj.setCategory(seal.getCategoryValue());
        obj.setManagers(transSealUsers(seal.getSealAdminGroup()));
        obj.setUsers(transSealUsers(seal.getSealUseGroup()));
        return obj;
    }

    private List<SignEmployee> transSealUsers(List<SealPermissionGroupBean> sealPermissionGroup) {
        if (sealPermissionGroup == null) {
            return null;
        }

        List<SignEmployee> list = new ArrayList<>();
        for (SealPermissionGroupBean sp : sealPermissionGroup) {
            if (sp == null) {
                continue;
            }

            List<User> users = sp.getUsers();
            if (users == null) {
                continue;
            }

            for (User user : users) {
                if (user == null) {
                    continue;
                }
                list.add(new SignEmployee(TextUtil.getLongValue(user.getThirdUserId()), user.getMobile(), user.getEmail()));
            }
        }

        return list;
    }

    /**
     * 查询印章详情
     *
     * @param sealId 印章ID
     * @return 印章对象
     */
    private Seal getSealDetail(Long sealId, SealService sealService) {
        if (sealId == null || sealId <= 0) {
            return null;
        }

        Seal seal = null;
        try {
            seal = sealService.detail(sealId);
        } catch (Exception e) {
            log.error("获取印章详情失败，印章ID："+sealId, e);
        }
        return seal;
    }

    @Override
    public void rollBack(WeaHookRequest request, WeaHookResponse response, AppInfo appInfo) throws Exception {

    }
}
```

## 29、电子签同步模板钩子

> 钩子唯一标识code："SIGNCENTER\_SYNC\_TEMPLATE\_HOOK" + "\_" + PlatformConstant.type+"\_"+PlatformConstant.serverType

**29.1 功能说明：**

用于二开服务商，同步绑定服务中的模板到oa中

**29.2 参数说明：**

| 参数名 | 类型 | 说明 |
| --- | --- | --- |
| serverSetting | serverSetting | 绑定服务信息 |
| logId | Long | 日志信息 |

**29.3 响应说明：**

返回值是SignBaseResult\<List\<CommonTemplate\>\>，其中CommonTemplate实体定义如下

| 参数名 | 类型 | 说明 |
| --- | --- | --- |
| platTemplateId | String | 模板id |
| title | String | 模板名称 |
| serverId | Long | 服务id |
| serverType | int | 服务类型 |

**29.4 示例代码：**

```
package com.weaver.seconddev.signcenter.fadada.reghook.syncData;

import com.alibaba.fastjson.JSON;
import com.weaver.loom.context.annotation.WeaHookReg;
import com.weaver.loom.context.domain.AppInfo;
import com.weaver.loom.context.domain.WeaHookRequest;
import com.weaver.loom.context.domain.WeaHookResponse;
import com.weaver.loom.context.register.RegHookEvent;
import com.weaver.seconddev.signcenter.fadada.entity.ServerEntity;
import com.weaver.seconddev.signcenter.fadada.reghook.PlatformConstant;
import com.weaver.seconddev.signcenter.fadada.util.TimeUtil;
import com.weaver.seconddev.signcenter.fadada.util.Util;
import com.weaver.signcenter.api.entity.base.IdName;
import com.weaver.signcenter.api.entity.base.SignBaseResult;
import com.weaver.signcenter.entity.contract2.DownloadDocumentDto;
import com.weaver.signcenter.entity.server.ServerSetting;
import com.weaver.signcenter.entity.template.CommonTemplate;
import com.weaver.signcenter.qiyuesuo.pri.sdk.SDKClient;
import com.weaver.signcenter.qiyuesuo.pri.sdk.api.ContractService;
import com.weaver.signcenter.qiyuesuo.pri.sdk.api.TemplateService;
import com.weaver.signcenter.qiyuesuo.pri.sdk.bean.company.Company;
import com.weaver.signcenter.qiyuesuo.pri.sdk.bean.contract.ContractDetail;
import com.weaver.signcenter.qiyuesuo.pri.sdk.bean.contract.Document;
import com.weaver.signcenter.qiyuesuo.pri.sdk.bean.template.Template;
import com.weaver.signcenter.qiyuesuo.pri.sdk.bean.template.TemplateGroup;
import com.weaver.signcenter.qiyuesuo.pri.sdk.bean.template.TemplateGroupRequest;
import com.weaver.signcenter.qiyuesuo.pri.sdk.impl.ContractServiceImpl;
import com.weaver.signcenter.qiyuesuo.pri.sdk.impl.TemplateServiceImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@WeaHookReg(code = "SIGNCENTER_SYNC_TEMPLATE_HOOK" + "_" + PlatformConstant.type+"_"+PlatformConstant.serverType, order = 0)
public class SignSyncTemplateRegHook extends RegHookEvent {

    protected static final Logger log = LoggerFactory.getLogger(SignSyncTemplateRegHook.class);

    @Override
    public WeaHookResponse handle(WeaHookRequest hookRequest, WeaHookResponse response, AppInfo appInfo) throws Exception {
        Map<String, Object> params = hookRequest.getParams();
        log.info("SignSyncTemplateRegHook--request:{}", JSON.toJSONString(hookRequest));

        ServerSetting serverSetting = (ServerSetting) params.get("serverSetting");

        ServerEntity serverEntity = ServerEntity.getInstance(serverSetting);

        SDKClient sdkClient = new SDKClient(serverEntity.getOpenUrl(), serverEntity.getAppId(), serverEntity.getSecret());

        TemplateService templateService = new TemplateServiceImpl(sdkClient);

        response.setResult(getTemplate(serverSetting.getTenantKey(), serverSetting.getId(), templateService));
        return response;
    }

    public SignBaseResult<List<CommonTemplate>> getTemplate(String tenantKey, Long serverId, TemplateService templateService) {
        String currentDateTime = TimeUtil.getCurrentTimeString();
        log.info("getTemplate--start--currentDateTime:" + currentDateTime);

        List<Company> companies = null;
        try {
            TemplateGroupRequest templateGroupRequest=new TemplateGroupRequest();
            companies = templateService.innercompanyTempalteGroup(templateGroupRequest);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return SignBaseResult.fail(e.getMessage());
        }

        if (companies == null) {
            return SignBaseResult.fail("companies is null");
        }
        log.info("getTemplate--companies.size:" + companies.size());

        // 删除templateGroup数据
        // templateGroupDao.deleteByServerId(tenantKey, serverId, new Date());

        List<CommonTemplate> list = new ArrayList<>();
        for (Company company : companies) {
            if (company == null) {
                continue;
            }

            List<CommonTemplate> templates = recursiveTemplateGroup(company.getTemplateGroup(), null, company.getId(), company.getName(), tenantKey, serverId);
            list.addAll(templates);
        }

        log.info("getTemplate--end--list.size:" + list.size());
        return SignBaseResult.success(list);
    }

    private List<CommonTemplate> recursiveTemplateGroup(TemplateGroup templateGroup, Long parentGroupId, Long companyId, String companyName, String tenantKey, Long serverId) {
        List<CommonTemplate> list = new ArrayList<>();
        if (templateGroup == null) {
            return list;
        }

        Long groupId = templateGroup.getId();
        String groupName = templateGroup.getName();

        List<Template> templates = templateGroup.getTemplateList();
        if (templates != null) {
            for (Template template : templates) {
                if (template == null) {
                    continue;
                }

                CommonTemplate CommonTemplate = new CommonTemplate();
                CommonTemplate.setPlatTemplateId(Util.null2String(template.getId()));
                CommonTemplate.setStatus(template.getStatus());
                CommonTemplate.setTemplateType(template.getTemplateTypeValue());
                CommonTemplate.setTenantId(companyId);
                CommonTemplate.setTenantName(companyName);
                CommonTemplate.setTitle(template.getTitle());
                CommonTemplate.setCreateDateTime(template.getCreateTime());
                CommonTemplate.setUpdateDateTime(template.getUpdateTime());
                CommonTemplate.setWord(template.isWord() ? 1 : 0);
                CommonTemplate.setForm(template.isForm() ? 1 : 0);
                CommonTemplate.setGroupId(groupId);
                CommonTemplate.setGroupName(groupName);
                list.add(CommonTemplate);
            }
        }

        List<TemplateGroup> childrenGroups = templateGroup.getChildren();
        if (childrenGroups == null) {
            return list;
        }

        for (TemplateGroup childrenGroup : childrenGroups) {
            list.addAll(recursiveTemplateGroup(childrenGroup, groupId, companyId, companyName, tenantKey, serverId));
        }

        return list;
    }

    @Override
    public void rollBack(WeaHookRequest request, WeaHookResponse response, AppInfo appInfo) throws Exception {

    }
}
```

## 30、电子签同步公司钩子

> 钩子唯一标识code："SIGNCENTER\_SYNC\_COMPANY\_HOOK"  + "\_" + PlatformConstant.type+"\_"+PlatformConstant.serverType

**30.1 功能说明：**

用于二开服务商，同步绑定服务中的公司信息到oa中

**30.2 参数说明：**

| 参数名 | 类型 | 说明 |
| --- | --- | --- |
| serverSetting | serverSetting | 绑定服务信息 |
| logId | Long | 日志信息 |

**30.3 响应说明：**

返回值是SignBaseResult\<List\<CommonCompany\>\>，其中CommonCompany实体定义如下

| 参数名 | 类型 | 说明 |
| --- | --- | --- |
| platCompanyId | String | 公司id |
| companyName | String | 公司名称 |
| companyType | String | 公司类型 |
| serverId | Long | 服务id |
| serverType | int | 服务类型 |

**30.4 示例代码：**

```
package com.weaver.seconddev.signcenter.fadada.reghook.syncData;

import com.alibaba.fastjson.JSON;
import com.weaver.loom.context.annotation.WeaHookReg;
import com.weaver.loom.context.domain.AppInfo;
import com.weaver.loom.context.domain.WeaHookRequest;
import com.weaver.loom.context.domain.WeaHookResponse;
import com.weaver.loom.context.register.RegHookEvent;
import com.weaver.seconddev.signcenter.fadada.entity.ServerEntity;
import com.weaver.seconddev.signcenter.fadada.reghook.PlatformConstant;
import com.weaver.seconddev.signcenter.fadada.util.TimeUtil;
import com.weaver.seconddev.signcenter.fadada.util.Util;
import com.weaver.signcenter.api.entity.base.SignBaseResult;
import com.weaver.signcenter.entity.company.CommonCompany;
import com.weaver.signcenter.entity.server.ServerSetting;
import com.weaver.signcenter.entity.template.CommonTemplate;
import com.weaver.signcenter.enums.server.QYSServerType;
import com.weaver.signcenter.qiyuesuo.pri.sdk.SDKClient;
import com.weaver.signcenter.qiyuesuo.pri.sdk.api.CompanyService;
import com.weaver.signcenter.qiyuesuo.pri.sdk.api.TemplateService;
import com.weaver.signcenter.qiyuesuo.pri.sdk.bean.company.Company;
import com.weaver.signcenter.qiyuesuo.pri.sdk.bean.company.CompanyRequest;
import com.weaver.signcenter.qiyuesuo.pri.sdk.bean.template.Template;
import com.weaver.signcenter.qiyuesuo.pri.sdk.bean.template.TemplateGroup;
import com.weaver.signcenter.qiyuesuo.pri.sdk.bean.template.TemplateGroupRequest;
import com.weaver.signcenter.qiyuesuo.pri.sdk.common.exception.PrivateAppException;
import com.weaver.signcenter.qiyuesuo.pri.sdk.impl.CompanyServiceImpl;
import com.weaver.signcenter.qiyuesuo.pri.sdk.impl.TemplateServiceImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@WeaHookReg(code = "SIGNCENTER_SYNC_COMPANY_HOOK" + "_" + PlatformConstant.type+"_"+PlatformConstant.serverType, order = 0)
public class SignSyncCompanyRegHook extends RegHookEvent {

    protected static final Logger log = LoggerFactory.getLogger(SignSyncCompanyRegHook.class);

    @Override
    public WeaHookResponse handle(WeaHookRequest hookRequest, WeaHookResponse response, AppInfo appInfo) throws Exception {
        Map<String, Object> params = hookRequest.getParams();
        log.info("SignSyncCompanyRegHook--request:{}", JSON.toJSONString(hookRequest));

        ServerSetting serverSetting = (ServerSetting) params.get("serverSetting");

        ServerEntity serverEntity = ServerEntity.getInstance(serverSetting);

        SDKClient sdkClient = new SDKClient(serverEntity.getOpenUrl(), serverEntity.getAppId(), serverEntity.getSecret());

        CompanyService companyService = new CompanyServiceImpl(sdkClient);

        response.setResult(listCommonCompany(companyService));
        return response;
    }

    public SignBaseResult<List<CommonCompany>> listCommonCompany(CompanyService companyService) {
        CompanyRequest request = new CompanyRequest();
        List<Company> companies = null;
        try {
            companies = companyService.queryList(request);
        } catch (PrivateAppException e) {
            log.error("listCommonCompany--fail", e);
            return SignBaseResult.fail(e.getCode(), e.getMessage(), true);
        }
        if(companies == null) {
            log.info("listCommonCompany--companies is null");
            return SignBaseResult.fail("companies is null");
        }
        log.info("公司数量为：{}",companies.size());

        List<CommonCompany> list = new ArrayList<>();
        for (Company company : companies) {
            if (company == null) {
                continue;
            }
            CommonCompany obj = new CommonCompany();
            obj.setServerType(QYSServerType.PRIVATE.getId());
            obj.setExecuteDateTime(company.getCreateTime());
            obj.setPlatCompanyId(Util.null2String(company.getId()));
            obj.setCompanyName(company.getName());
            obj.setCompanyType(company.getTenantTypeValue());
            obj.setCharger(company.getCharger());
            obj.setStatus(company.getStatusValue());
            obj.setParentCompanyId(company.getParentId());
            list.add(obj);
        }
        return SignBaseResult.success(list);
    }

    @Override
    public void rollBack(WeaHookRequest request, WeaHookResponse response, AppInfo appInfo) throws Exception {

    }
}
```

## 31、电子签同步用印流程钩子

> 钩子唯一标识code："SIGNCENTER\_SYNC\_CATEGORY\_HOOK"  + "\_" + PlatformConstant.type+"\_"+PlatformConstant.serverType

**31.1 功能说明：**

用于二开服务商，同步绑定服务中的用印流程到oa中

**31.2 参数说明：**

| 参数名 | 类型 | 说明 |
| --- | --- | --- |
| serverSetting | serverSetting | 绑定服务信息 |
| logId | Long | 日志信息 |

**31.3 响应说明：**

返回值是SignBaseResult\<List\<CommonCategory\>\>，其中CommonCategory实体定义如下

| 参数名 | 类型 | 说明 |
| --- | --- | --- |
| platCategoryId | String | 用印流程id |
| categoryName | String | 用印流程名称 |
| categoryType | String | 用印流程类型 |
| serverId | Long | 服务id |
| serverType | int | 服务类型 |

**31.4 示例代码：**

```
package com.weaver.seconddev.signcenter.fadada.reghook.syncData;

import com.alibaba.fastjson.JSON;
import com.weaver.loom.context.annotation.WeaHookReg;
import com.weaver.loom.context.domain.AppInfo;
import com.weaver.loom.context.domain.WeaHookRequest;
import com.weaver.loom.context.domain.WeaHookResponse;
import com.weaver.loom.context.register.RegHookEvent;
import com.weaver.seconddev.signcenter.fadada.entity.ServerEntity;
import com.weaver.seconddev.signcenter.fadada.reghook.PlatformConstant;
import com.weaver.seconddev.signcenter.fadada.util.TimeUtil;
import com.weaver.seconddev.signcenter.fadada.util.Util;
import com.weaver.signcenter.api.entity.base.IdName;
import com.weaver.signcenter.api.entity.base.SignBaseResult;
import com.weaver.signcenter.entity.category.CommonCategory;
import com.weaver.signcenter.entity.server.ServerSetting;
import com.weaver.signcenter.entity.template.CommonTemplate;
import com.weaver.signcenter.qiyuesuo.pri.sdk.SDKClient;
import com.weaver.signcenter.qiyuesuo.pri.sdk.api.CategoryService;
import com.weaver.signcenter.qiyuesuo.pri.sdk.api.TemplateService;
import com.weaver.signcenter.qiyuesuo.pri.sdk.bean.company.Company;
import com.weaver.signcenter.qiyuesuo.pri.sdk.bean.contract.Category;
import com.weaver.signcenter.qiyuesuo.pri.sdk.bean.contract.CategoryGroup;
import com.weaver.signcenter.qiyuesuo.pri.sdk.bean.template.Template;
import com.weaver.signcenter.qiyuesuo.pri.sdk.bean.template.TemplateGroup;
import com.weaver.signcenter.qiyuesuo.pri.sdk.bean.template.TemplateGroupRequest;
import com.weaver.signcenter.qiyuesuo.pri.sdk.impl.CategoryServiceImpl;
import com.weaver.signcenter.qiyuesuo.pri.sdk.impl.TemplateServiceImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@WeaHookReg(code = "SIGNCENTER_SYNC_CATEGORY_HOOK" + "_" + PlatformConstant.type+"_"+PlatformConstant.serverType, order = 0)
public class SignSyncCategoryRegHook extends RegHookEvent {

    protected static final Logger log = LoggerFactory.getLogger(SignSyncCategoryRegHook.class);

    @Override
    public WeaHookResponse handle(WeaHookRequest hookRequest, WeaHookResponse response, AppInfo appInfo) throws Exception {
        Map<String, Object> params = hookRequest.getParams();
        log.info("SignSyncCategoryRegHook--request:{}", JSON.toJSONString(hookRequest));

        ServerSetting serverSetting = (ServerSetting) params.get("serverSetting");

        ServerEntity serverEntity = ServerEntity.getInstance(serverSetting);

        SDKClient sdkClient = new SDKClient(serverEntity.getOpenUrl(), serverEntity.getAppId(), serverEntity.getSecret());

        CategoryService categoryService = new CategoryServiceImpl(sdkClient);

        response.setResult(getCategoryForSyncData(serverSetting.getTenantKey(), serverSetting.getId(), categoryService));
        return response;
    }

    public SignBaseResult<List<CommonCategory>> getCategoryForSyncData(String tenantKey, Long serverId, CategoryService categoryService) {
        String currentDateTime = TimeUtil.getCurrentTimeString();
        log.info("getCategory--start--currentDateTime:" + currentDateTime);

        List<Company> companies = null;
        try {
            companies = categoryService.categoryGroupList();
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return SignBaseResult.fail(e.getMessage());
        }

        if (companies == null) {
            return SignBaseResult.fail("companies is null");
        }

        // 删除categoryGroup数据 先注释掉，OA并没有用到group表
        // categoryGroupDao.deleteByServerId(tenantKey, serverId, new Date());

        List<CommonCategory> list = new ArrayList<>();
        for (Company company : companies) {
            if (company == null) {
                continue;
            }

            List<CategoryGroup> categoryGroups = company.getCategoryGroups();
            if (categoryGroups == null) {
                continue;
            }

            List<CommonCategory> categories = new ArrayList<>();
            for (CategoryGroup categoryGroup : categoryGroups) {
                categories.addAll(recursiveCategoryGroupForSyncData(categoryGroup, null, company.getId(), company.getName(), tenantKey, serverId));
            }

            list.addAll(categories);
        }

        log.info("getCategory--end--list.size:" + list.size());
        return SignBaseResult.success(list);
    }

    private List<CommonCategory> recursiveCategoryGroupForSyncData(CategoryGroup categoryGroup, Long parentGroupId, Long companyId, String companyName, String tenantKey, Long serverId) {
        List<CommonCategory> list = new ArrayList<>();
        if (categoryGroup == null) {
            return list;
        }

        Long groupId = categoryGroup.getId();
        String groupName = categoryGroup.getName();

        List<Category> categories = categoryGroup.getCategoryList();
        if (categories != null) {
            for (Category category : categories) {
                if (category == null) {
                    continue;
                }

                CommonCategory CommonCategory  = new CommonCategory();
                CommonCategory.setPlatCategoryId(Util.null2String(category.getId()));
                CommonCategory.setCategoryName(category.getName());
                CommonCategory.setCategoryType(category.getType());
                CommonCategory.setTenantId(companyId);
                CommonCategory.setTenantName(companyName);
                CommonCategory.setCreateDateTime(category.getCreateTime());
                CommonCategory.setExecuteDateTime(category.getUpdateTime());
                CommonCategory.setIsPrimary((category.getPrimary() != null && category.getPrimary()) ? 1 : 0);
                CommonCategory.setStatus(category.getState());
                CommonCategory.setGroupId(groupId);
                CommonCategory.setGroupName(groupName);
                list.add(CommonCategory);
            }
        }

        List<CategoryGroup> childrenGroups = categoryGroup.getChildren();
        if (childrenGroups == null) {
            return list;
        }

        for (CategoryGroup childrenGroup : childrenGroups) {
            list.addAll(recursiveCategoryGroupForSyncData(childrenGroup, groupId, companyId, companyName, tenantKey, serverId));
        }

        return list;
    }

    @Override
    public void rollBack(WeaHookRequest request, WeaHookResponse response, AppInfo appInfo) throws Exception {

    }
}
```
