package nckd.jimin.jyyy.bd.plugin.msg.ecology;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import kd.bos.context.RequestContext;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.dataentity.entity.DynamicObjectCollection;
import kd.bos.dataentity.resource.ResManager;
import kd.bos.exception.ErrorCode;
import kd.bos.exception.KDException;
import kd.bos.logging.Log;
import kd.bos.logging.LogFactory;
import kd.bos.orm.query.QCP;
import kd.bos.orm.query.QFilter;
import kd.bos.sdk.util.KHttpClientUtils;
import kd.bos.servicehelper.BusinessDataServiceHelper;
import kd.bos.servicehelper.operation.SaveServiceHelper;
import kd.bos.util.StringUtils;
import kd.bos.workflow.engine.WfConfigurationUtil;
import kd.bos.workflow.engine.msg.MessageServiceUtil;
import kd.bos.workflow.engine.msg.ctx.MessageContext;
import kd.bos.workflow.engine.msg.info.MessageInfo;
import kd.bos.workflow.engine.msg.info.ToDoInfo;
import kd.bos.workflow.exception.WFErrorCode;
import kd.bos.workflow.exception.WFMessageServiceException;
import nckd.base.helper.CommonHelperUtils;
import org.apache.commons.lang3.ObjectUtils;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.stream.Collectors;

/**
 * 消息待办实现工具类
 * @author wanghaiwu_kd
 * @date 2025/04/16
 */
public final class FanweiCommonUtil {
    private static Log logger = LogFactory.getLog(FanweiCommonUtil.class);
    private static String KEY_ENTITY_LOG = "nckd_ecology";
    //
    private static String param_url = "";
    private static String param_msgurl = "";
    //注册企业id
    private static String param_cropid = "";
    private static String param_responsetype = "";
    private static String param_state = "";
    private static String param_appkey = "";
    private static String param_appsecret = "";
    private static String param_granttype = "";
    private static String param_secretkey = "";
    private static String param_syscode = "";
    private static String param_getcode = "";
    private static String param_gettoken = "";
    private static String param_sendflow = "";
    private static String param_receiver_dev = "";

    /**
     * 获取公共参数中的泛微相关参数配置
     */
    private static void setParmamValue(){
        String selectField = "nckd_entryentity.nckd_key, nckd_entryentity.nckd_value";

        QFilter qFilter = new QFilter("number", QCP.equals, "fanwei");
        DynamicObject commonParam = BusinessDataServiceHelper.loadSingle("nckd_commonparams", selectField, qFilter.toArray());
        if (ObjectUtils.isEmpty(commonParam)) {
            return;
        }

        DynamicObjectCollection entryentity = commonParam.getDynamicObjectCollection("nckd_entryentity");
        Map<String, String> mapentity = entryentity.stream().collect(Collectors.toMap(k -> k.getString("nckd_key"), v -> v.getString("nckd_value")));
        if(mapentity != null ){
            param_url = mapentity.get("url");
            param_msgurl = mapentity.get("msgurl");
            param_cropid = mapentity.get("corpid");
            param_responsetype = mapentity.get("response_type");
            param_state = mapentity.get("state");
            param_appkey = mapentity.get("app_key");
            param_appsecret = mapentity.get("app_secret");
            param_granttype = mapentity.get("grant_type");
            param_secretkey = mapentity.get("secret_key");
            param_syscode = mapentity.get("syscode");
            param_getcode = mapentity.get("getcode");

            param_gettoken = mapentity.get("gettoken");
            param_sendflow = mapentity.get("sendflow");
            param_receiver_dev = mapentity.get("receiver_dev");
        }
    }

    /**
     * 创建待办
     * @param ctx
     * @param info
     * @param params
     */
    public static void createUserToDo(MessageContext ctx, ToDoInfo info, Map<String, String> params) {
        if (WfConfigurationUtil.isEnabled("fanwei")) {
            setParmamValue();
            if(StringUtils.isEmpty(param_sendflow)){
                logger.info("泛微createToDo is fail :未配置泛微参数sendflow!");
                return;
            }

            try {
                JSONObject fanweiBodyData = buildToDoBodyData(ctx, info, params);
                DynamicObject taskInfo =  BusinessDataServiceHelper.loadSingleFromCache(info.getTaskId() ,"wf_task");
                //驳回
                String handlestate = (taskInfo == null) ? "" : taskInfo.getString("handlestate");
                if("dismissed".equals(handlestate)){
                    fanweiBodyData.put("requestname", "被驳回 " + fanweiBodyData.getString("requestname"));
                }

                logger.info("待办发送消息:" + fanweiBodyData.toString());

                String receiverLong = fanweiBodyData.getString("receiverLong");
                String title = fanweiBodyData.getString("requestname");
                String oaId = fanweiBodyData.getString("flowid");
                String uuid = saveLogData(receiverLong, title, oaId, info.getContent(), fanweiBodyData.toString(), "1", param_sendflow);

                logger.info("泛微推送数据日志保存成功");

                String token = getFanWeiToken(false);
                String bodyString = "";
                String url = "";
                String result = "";

                Map<String, String> header = new HashMap<>();
                header.put("Content-Type", "application/json; charset=UTF-8");

                //获取token
                try {
                    url = param_sendflow + "?access_token=" + token + "&secret_key=" + param_secretkey;
                    logger.info("泛微发送消息接口地址：" + url);

                    bodyString = CommonHelperUtils.buildEsbApiBodyJSON(fanweiBodyData);
                    result = KHttpClientUtils.postjson(url, header, bodyString);
                } catch (IOException e) {
                    logger.info(e.getMessage());

                    String message = ResManager.loadKDString("创建泛微待办失败，原因:%s", "WFErrorCode_10001", "bos-wf-engine", new Object[0]);
                    ErrorCode error = new ErrorCode("bos.wf.rpa.", message);
                    throw new WFMessageServiceException(e, error, new Object[]{e.getMessage()});
                }

                if(StringUtils.isEmpty(result)){
                    logger.info("创建泛微待办异常: 接口返回为空");
                    throw new WFMessageServiceException("创建泛微待办异常: 接口返回为空");
                }

                JSONObject msgObj = JSONObject.parseObject(result);
                if(msgObj.get("message") == null){
                    logger.info("创建泛微待办异常: 接口返回message为空");
//                    throw new WFMessageServiceException("创建泛微待办异常: 接口返回为空");
                }

                JSONObject message = msgObj.getJSONObject("message");

                if(message.get("errcode") == null){
                    logger.info("创建泛微待办异常: 接口返回errorcode为空");
//                    throw new WFMessageServiceException("创建泛微待办异常: 接口返回为空");
                }

                String sendStatus = "fail";
                String code = message.getString("errcode");

                if(StringUtils.isNotEmpty(code) && "200".equals(code)){
                    sendStatus = "success";
                } else {
                    String errCode = message.getString("errcode") == null ? "" : message.getString("errcode");
                    String errMsg = message.getString("errmsg") == null ? "" : message.getString("errmsg");

                    logger.info("创建泛微待办异常: " + errMsg + "(" + errCode + ")");
//                    throw new WFMessageServiceException("创建泛微待办异常: " + errMsg + "(" + errCode + ")");
                }


                updateLogData(uuid, result, sendStatus);

                logger.info("泛微门户消息发送成功，发送消息：{}, 结果：{}", fanweiBodyData.toJSONString(), result);
            } catch (Exception var15) {
                logger.info(var15.getMessage());
                String message = ResManager.loadKDString("泛微创建待办失败，原因:%s", "WFErrorCode_10001", "bos-wf-engine", new Object[0]);
                ErrorCode error = new ErrorCode("bos.wf.rpa.", message);
                throw new WFMessageServiceException(var15, error, new Object[]{var15.getMessage()});
            } finally {
            }
        }
    }



    /**
     * 处理待办
     * @param ctx
     * @param info
     * @param params
     */
    public static void dealUserToDo(MessageContext ctx, ToDoInfo info, Map<String, String> params) {
        if (WfConfigurationUtil.isEnabled("fanwei")) {
            setParmamValue();
            if(StringUtils.isEmpty(param_sendflow)){
                logger.info("泛微dealToDo is fail :未配置泛微参数sendflow!");
                return;
            }
            try {
                JSONObject fanweiBodyData = buildToDoBodyData(ctx, info, params);

                logger.info("待办发送消息:" + fanweiBodyData.toString());

                String receiverLong = fanweiBodyData.getString("receiverLong");
                String title = fanweiBodyData.getString("requestname");
                String oaId = fanweiBodyData.getString("flowid");
                String uuid = saveLogData(receiverLong, title, oaId, info.getContent(), fanweiBodyData.toString(), "5", param_sendflow);
                logger.info("泛微推送数据日志保存成功");

                String token = getFanWeiToken(false);
                String bodyString = "";
                String url = "";
                String result = "";

                Map<String, String> header = new HashMap<>();
                header.put("Content-Type", "application/json; charset=UTF-8");

                //获取token
                try {
                    url = param_sendflow + "?access_token=" + token + "&secret_key=" + param_secretkey;
                    logger.info("泛微发送消息接口地址：" + url);

                    bodyString = CommonHelperUtils.buildEsbApiBodyJSON(fanweiBodyData);
                    result = KHttpClientUtils.postjson(url, header, bodyString);
                } catch (IOException e) {
                    logger.info(e.getMessage());

                    String message = ResManager.loadKDString("创建泛微待办失败，原因:%s", "WFErrorCode_10001", "bos-wf-engine", new Object[0]);
                    ErrorCode error = new ErrorCode("bos.wf.rpa.", message);
                    throw new WFMessageServiceException(e, error, new Object[]{e.getMessage()});
                }

                if(StringUtils.isEmpty(result)){
                    logger.info("创建泛微待办异常: 接口返回为空");
                    throw new WFMessageServiceException("创建泛微待办异常: 接口返回为空");
                }

                JSONObject msgObj = JSONObject.parseObject(result);
                if(msgObj.get("message") == null){
                    logger.info("创建泛微待办异常: 接口返回message为空");
//                    throw new WFMessageServiceException("创建泛微待办异常: 接口返回为空");
                }

                JSONObject message = msgObj.getJSONObject("message");
                if(message.get("errcode") == null){
                    logger.info("创建泛微待办异常: 接口返回errorcode为空");
//                    throw new WFMessageServiceException("创建泛微待办异常: 接口返回为空");
                }

                String sendStatus = "fail";
                String code = message.getString("errcode");
                if(StringUtils.isNotEmpty(code) && "200".equals(code)){
                    sendStatus = "success";
                } else {
                    String errCode = message.getString("errcode") == null ? "" : message.getString("errcode");
                    String errMsg = message.getString("errmsg") == null ? "" : message.getString("errmsg");

                    logger.info("创建泛微待办异常: " + errMsg + "(" + errCode + ")");
//                    throw new WFMessageServiceException("创建泛微待办异常: " + errMsg + "(" + errCode + ")");
                }

                updateLogData(uuid, result, sendStatus);

                logger.info("泛微门户消息发送成功，发送消息：{}, 结果：{}", fanweiBodyData.toJSONString(), result);
            } catch (Exception var15) {
                logger.info(var15.getMessage());
                String message = ResManager.loadKDString("泛微处理待办失败，原因:%s", "WFErrorCode_10001", "bos-wf-engine", new Object[0]);
                ErrorCode error = new ErrorCode("bos.wf.rpa.", message);
                throw new WFMessageServiceException(var15, error, new Object[]{var15.getMessage()});
            } finally {
            }
        }
    }

    /**
     * 撤销待办、转交、加签等
     * @param ctx
     * @param info
     * @param params
     */
    public static void deleteUserToDo(MessageContext ctx, ToDoInfo info, Map<String, String> params) {
        if (WfConfigurationUtil.isEnabled("fanwei")) {
            setParmamValue();
            if(StringUtils.isEmpty(param_sendflow)){
                logger.info("泛微dealToDo is fail :未配置泛微参数sendflow!");
                return;
            }
            try {
                JSONObject fanweiBodyData = buildToDoBodyData(ctx, info, params);

                logger.info("待办发送消息:" + fanweiBodyData.toString());

                String receiverLong = fanweiBodyData.getString("receiverLong");
                String title = fanweiBodyData.getString("requestname");
                String oaId = fanweiBodyData.getString("flowid");
                String uuid = saveLogData(receiverLong, title, oaId, info.getContent(), fanweiBodyData.toString(), "5", param_sendflow);
                logger.info("泛微推送数据日志保存成功");

                String token = getFanWeiToken(false);
                String bodyString = "";
                String url = "";
                String result = "";

                Map<String, String> header = new HashMap<>();
                header.put("Content-Type", "application/json; charset=UTF-8");

                //获取token
                try {
                    url = param_sendflow + "?access_token=" + token + "&secret_key=" + param_secretkey;
                    logger.info("泛微发送消息接口地址：" + url);

                    bodyString = CommonHelperUtils.buildEsbApiBodyJSON(fanweiBodyData);
                    result = KHttpClientUtils.postjson(url, header, bodyString);
                } catch (IOException e) {
                    logger.info(e.getMessage());

                    String message = ResManager.loadKDString("创建泛微待办失败，原因:%s", "WFErrorCode_10001", "bos-wf-engine", new Object[0]);
                    ErrorCode error = new ErrorCode("bos.wf.rpa.", message);
                    throw new WFMessageServiceException(e, error, new Object[]{e.getMessage()});
                }

                if(StringUtils.isEmpty(result)){
                    logger.info("创建泛微待办异常: 接口返回为空");
                    throw new WFMessageServiceException("创建泛微待办异常: 接口返回为空");
                }

                JSONObject msgObj = JSONObject.parseObject(result);
                if(msgObj.get("message") == null){
                    logger.info("创建泛微待办异常: 接口返回message为空");
//                    throw new WFMessageServiceException("创建泛微待办异常: 接口返回为空");
                }

                JSONObject message = msgObj.getJSONObject("message");
                if(message.get("errcode") == null){
                    logger.info("创建泛微待办异常: 接口返回errorcode为空");
//                    throw new WFMessageServiceException("创建泛微待办异常: 接口返回为空");
                }

                String sendStatus = "fail";
                String code = message.getString("errcode");
                if(StringUtils.isNotEmpty(code) && "200".equals(code)){
                    sendStatus = "success";
                } else {
                    String errCode = message.getString("errcode") == null ? "" : message.getString("errcode");
                    String errMsg = message.getString("errmsg") == null ? "" : message.getString("errmsg");

                    logger.info("创建泛微待办异常: " + errMsg + "(" + errCode + ")");
//                    throw new WFMessageServiceException("创建泛微待办异常: " + errMsg + "(" + errCode + ")");
                }

                updateLogData(uuid, result, sendStatus);

                logger.info("泛微门户消息发送成功，发送消息：{}, 结果：{}", fanweiBodyData.toJSONString(), result);
            } catch (Exception var15) {
                logger.info(var15.getMessage());
                String message = ResManager.loadKDString("泛微处理待办失败，原因:%s", "WFErrorCode_10001", "bos-wf-engine", new Object[0]);
                ErrorCode error = new ErrorCode("bos.wf.rpa.", message);
                throw new WFMessageServiceException(var15, error, new Object[]{var15.getMessage()});
            } finally {
            }
        }
    }

    /**
     * 发送消息
     * @param ctx
     * @param info
     * @param params
     */
    public static void sendMessage(MessageContext ctx, MessageInfo info, Map<String, String> params) {
        if (WfConfigurationUtil.isEnabled("fanwei")) {
            setParmamValue();
            if(StringUtils.isEmpty(param_sendflow)){
                logger.info("泛微createToDo is fail :未配置泛微服务器地址!");
                return;
            }
            //发送传阅消息
            if("circulation".equals(info.getTplScene())) {
                sendFlowMessage(ctx, info, params);
            } else {
                sendCustomMessage(ctx, info, params);
            }
        }
    }

    /**
     * 发送传阅消息
     * @param ctx
     * @param info
     * @param params
     */
    private static void sendFlowMessage(MessageContext ctx, MessageInfo info, Map<String, String> params){
        if (WfConfigurationUtil.isEnabled("fanwei")) {
            setParmamValue();
            if (StringUtils.isEmpty(param_sendflow)) {
                logger.info("泛微dealToDo is fail :未配置泛微参数sendflow!");
                return;
            }
            try {
                JSONObject fanweiBodyData = buildMessageBodyData(ctx, info, params);

                logger.info("发送传阅消息到泛微:" + fanweiBodyData.toString());

                String receiverLong = fanweiBodyData.getString("receiverLong");
                String title = fanweiBodyData.getString("requestname");
                String oaId = fanweiBodyData.getString("flowid");
                String uuid = saveLogData(receiverLong, title, oaId, info.getContent(), fanweiBodyData.toString(), "2", param_sendflow);
                logger.info("泛微推送数据日志保存成功");

                String token = getFanWeiToken(false);
                String bodyString = "";
                String url = "";
                String result = "";

                Map<String, String> header = new HashMap<>();
                header.put("Content-Type", "application/json; charset=UTF-8");

                //获取token
                try {
                    url = param_sendflow + "?access_token=" + token + "&secret_key=" + param_secretkey;
                    logger.info("泛微发送消息接口地址：" + url);
                    bodyString = CommonHelperUtils.buildEsbApiBodyJSON(fanweiBodyData);
                    result = KHttpClientUtils.postjson(url, header, bodyString);
                } catch (IOException e) {
                    logger.info(e.getMessage());

                    String message = ResManager.loadKDString("创建泛微待办失败，原因:%s", "WFErrorCode_10001", "bos-wf-engine", new Object[0]);
                    ErrorCode error = new ErrorCode("bos.wf.rpa.", message);
                    throw new WFMessageServiceException(e, error, new Object[]{e.getMessage()});
                }

                if(StringUtils.isEmpty(result)){
                    logger.info("创建泛微待办异常: 接口返回为空");
                    throw new WFMessageServiceException("创建泛微待办异常: 接口返回为空");
                }

                JSONObject msgObj = JSONObject.parseObject(result);
                if(msgObj.get("message") == null){
                    logger.info("创建泛微待办异常: 接口返回message为空");
//                    throw new WFMessageServiceException("创建泛微待办异常: 接口返回为空");
                }

                JSONObject message = msgObj.getJSONObject("message");
                if(message.get("errcode") == null){
                    logger.info("创建泛微待办异常: 接口返回errorcode为空");
//                    throw new WFMessageServiceException("创建泛微待办异常: 接口返回为空");
                }

                String sendStatus = "fail";
                String code = message.getString("errcode");
                if(StringUtils.isNotEmpty(code) && "200".equals(code)){
                    sendStatus = "success";
                } else {
                    String errCode = message.getString("errcode") == null ? "" : message.getString("errcode");
                    String errMsg = message.getString("errmsg") == null ? "" : message.getString("errmsg");

                    logger.info("创建泛微待办异常: " + errMsg + "(" + errCode + ")");
//                    throw new WFMessageServiceException("创建泛微待办异常: " + errMsg + "(" + errCode + ")");
                }

                updateLogData(uuid, result, sendStatus);

                logger.info("泛微门户消息发送成功，发送消息：{}, 结果：{}", fanweiBodyData.toJSONString(), result);
            } catch (Exception var15) {
                logger.info(var15.getMessage());
                String message = ResManager.loadKDString("泛微创建待办失败，原因:%s", "WFErrorCode_10001", "bos-wf-engine", new Object[0]);
                ErrorCode error = new ErrorCode("bos.wf.rpa.", message);
                throw new WFMessageServiceException(var15, error, new Object[]{var15.getMessage()});
            } finally {
            }
        }
    }

    /**
     * 发送消息
     */
    private static void sendCustomMessage(MessageContext ctx, MessageInfo info, Map<String, String> params){
//        try {
//            Map<String,String> fanweiBodyData = buildCustomMessageBodyData(ctx, info, params);
//
//            logger.info("发送传阅消息到泛微:" + fanweiBodyData.toString());
//
//            String receiverLong = fanweiBodyData.get("createrLong");
//            String title = fanweiBodyData.get("title");
//            String context = fanweiBodyData.get("context");
//            String oaId = fanweiBodyData.get("targetId");
//            String uuid = saveLogData(receiverLong, title, oaId, context, fanweiBodyData.toString(), "3", param_msgurl);
//            logger.info("泛微推送数据日志保存成功");
//
//            String url = param_msgurl + "/api/ec/dev/message/sendCustomMessageSingle";
//            Map<String, String> heads = getHttpHeads();
//
//            String data = doPostByHttpClient(url, fanweiBodyData, heads);
//
//            if (data != null && data.contains("消息发送至OA异常")) {
//                updateLogData(uuid, data, "fail");
//                return;
//            }
//
//            JSONObject result = JSONObject.parseObject(data);
//            if (result == null) {
//                throw new KDException(WFErrorCode.httpRequestWrongResponse(), new Object[]{result != null ? result.toJSONString() : "result is null!"});
//            }
//
//            //失败
//            if("true".equals(result.getString("status"))){
//                logger.info("泛微createToDo is ok , url is:" + info.getContentUrl() + ",mobileurl:" + info.getMobContentUrl());
//            } else {
//                logger.info("泛微createToDo is fail :" + result.getString("message"));
//            }
//
//            updateLogData(uuid, result.toJSONString(), "success");
//
//            logger.info("泛微门户消息发送成功，发送消息：{}, 结果：{}", fanweiBodyData.toString(), result.toJSONString());
//        } catch (Exception var15) {
//            logger.info(var15.getMessage());
//            String message = ResManager.loadKDString("泛微发送消息失败，原因:%s", "WFErrorCode_10001", "bos-wf-engine", new Object[0]);
//            ErrorCode error = new ErrorCode("bos.wf.rpa.", message);
//            throw new WFMessageServiceException(var15, error, new Object[]{var15.getMessage()});
//        } finally {
//        }
    }

    /**
     * 组装消息发送
     * @param ctx
     * @param info
     * @param params
     * @return
     */
    public static Map<String,String> buildCustomMessageBodyData(MessageContext ctx, MessageInfo info, Map<String, String> params) {
        Map<String, String> map = new HashMap<>();

//        DynamicObject msgInfo = BusinessDataServiceHelper.loadSingleFromCache(info.getId(), "wf_msg_message");
//
//        //发送人员
//        Long createUserId = 0L;
////        if(taskInfo != null){
////            createUserId = taskInfo.getLong("starterid");
////        }
//        if(ctx != null){
//            createUserId = ctx.getStartUserId();
//        }
//
//        DynamicObject createUser = BusinessDataServiceHelper.loadSingleFromCache(createUserId, "bos_user");
//        String creator = createUser == null ? "admin" : createUser.getString("number");
//
//        Long userId = Long.valueOf(params.get("userId"));
//        //接收人员
//        DynamicObject user = BusinessDataServiceHelper.loadSingleFromCache(userId, "bos_user");
//        String personNo = user.getString("number");
//        String personNoLong = user.getString("name") + "(" + user.getString("number") + ")";
//        String title = info.getTitle() == null ? "" : info.getTitle();
//        String content = info.getContent() == null ? "" : info.getContent();
//
//        String linkUrl = info.getContentUrl();
//        String linkMobileUrl = info.getMobContentUrl();
//
//        if(msgInfo != null) {
//            if(StringUtils.isNotEmpty(msgInfo.getString("contenturl"))){
//                linkUrl = msgInfo.getString("contenturl");
//            }
//            if(StringUtils.isNotEmpty(msgInfo.getString("contenturl"))){
//                linkMobileUrl = msgInfo.getString("mobcontenturl");
//            }
//            if(StringUtils.isNotEmpty(linkMobileUrl)){
//                linkMobileUrl = linkUrl;
//            }
//        }
//
//        logger.info("消息pcurl:" + linkUrl + ", moburl" + linkMobileUrl);
//
//        String targetId = FANWEI_MSGCODE + "|KD-" + info.getChannelMsgId().toString() + "-" + personNo;
//
//        if(StringUtils.isNotEmpty(linkMobileUrl)){
//            //移动端需要走外网，将地址替换成外网地址
//            String curUrl = "";//ParamsUtil.getCommonParamsField("nckd_url");
//            String mobileUrl = "";//ParamsUtil.getCommonParamsField("nckd_mobileurl");
//
//            linkUrl = linkUrl.replace(mobileUrl, curUrl);
//            linkMobileUrl = linkMobileUrl.replace(curUrl, mobileUrl);
//        }
//
//        try {
//            linkUrl = URLEncoder.encode(linkUrl, "utf-8");
//            linkMobileUrl = URLEncoder.encode(linkMobileUrl, "utf-8");
//        } catch (UnsupportedEncodingException e) {
//            throw new RuntimeException(e);
//        }
//
//        map.put("code", FANWEI_MSGCODE); // 消息来源,新建消息来源获取code 请查看文档第四大点补充
//        map.put("workCodeList", personNo);
//        map.put("creater", creator);
//        map.put("createrLong", personNoLong);
//        map.put("title", title);
//        map.put("context", content);
//        map.put("linkUrl", linkUrl);
//        map.put("linkMobileUrl", linkMobileUrl);
//        map.put("targetId", targetId); //消息来源code +“|”+业务id  消息需要打上已处理标记
////        map.put("bizState","0"); //0 表示消息初始状态是待处理  消息需要打上已处理标记
        return map;
    }


    /**
     * 组装传阅消息
     * @param ctx
     * @param info
     * @param params
     * @return
     */
    public static JSONObject buildMessageBodyData(MessageContext ctx, MessageInfo info, Map<String, String> params) {
        JSONObject bodyData = new JSONObject();
        Long userId = Long.valueOf(params.get("userId"));
        String isremark = params.get("isremark").toString();
        String viewtype = params.get("viewtype").toString();
        String content = info.getContent() == null ? info.getTitle() : info.getContent();

        if(content == null){
            content = info.getMessageTitle() == null ? "" : info.getMessageTitle().getLocaleValue_zh_CN();
        }

        if(content.indexOf("<br>意见：") >= 0) {
            content = content.substring(content.indexOf("<br>意见：") + 7);
        }

        //发送人员
        Long createUserId = 0L;
        if(info != null && info.getSenderId() != null){
            createUserId = info.getSenderId();
        }

        DynamicObject createUser = BusinessDataServiceHelper.loadSingleFromCache(createUserId, "bos_user");
        String creator = createUser == null ? "" : createUser.getString("number");


//        String requestname = info.getTitle() + ", 发送人：" + creator + ", " + content;

        String requestname = content;

        String nodename = info.getOperation() == null ? "circulation" : info.getOperation();
        String workflowname = "费控人力审批流";
        String workflowcode = "nobill";

        if(info.getParams() != null){
            Map<String, Object> config = info.getParams();
            if(config != null) {
                if(config.get("messageContext") != null){
                    JSONObject messageContext = JSONObject.parseObject(config.get("messageContext").toString());
                    if(messageContext.get("taskId") != null){
                        DynamicObject taskInfo = BusinessDataServiceHelper.loadSingleFromCache(Long.valueOf(messageContext.getString("taskId")), "wf_task");
                        if(taskInfo != null){
                            nodename = taskInfo.getString("name");
                            if(taskInfo.getLong("processdefinitionid") > 0){
                                QFilter qFilter = new QFilter("id", QCP.equals, taskInfo.getLong("processdefinitionid"));
                                DynamicObject processdef = BusinessDataServiceHelper.loadSingle("wf_processdefinition", qFilter.toArray());
                                if(processdef != null){
                                    workflowcode = processdef.getString("key");
                                    workflowname = processdef.getString("name");
                                }
                            }

                            if("费控人力审批流".equals(workflowname) && taskInfo.getString("entityname") != null){
                                workflowcode = taskInfo.getString("entityname");
                                workflowname = taskInfo.getString("entityname") + "审批流程";
                            }
                        }
                    }
                }
            }
        }

        //接收人员
        DynamicObject user = BusinessDataServiceHelper.loadSingleFromCache(userId, "bos_user");
        String personNo = user.getString("number");
        String receiverLong = user.getString("name") + "(" + user.getString("number") + ")";

        //创建时间
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String createTime = sdf.format(new Date());
        String curTimestamp = String.valueOf(System.currentTimeMillis());
        String flowid = "KD-" + info.getChannelMsgId().toString() + "-" + personNo;

        String pcUrl = info.getContentUrl() == null ? "" : info.getContentUrl();
        String mobUrl = info.getMobContentUrl() == null ? pcUrl : info.getMobContentUrl();

        String contextUrl = System.getProperty("domain.contextUrl").replace("/ierp", "");
        pcUrl = pcUrl.replace("http://127.0.0.1:8080", "").replace(contextUrl, "");
        mobUrl = mobUrl.replace("http://127.0.0.1:8080", "").replace(contextUrl, "");

        logger.info("消息pcurl:" + pcUrl + ", moburl:" + mobUrl);

        //移动端需要走外网，将地址替换成外网地址
        String curUrl = "";//ParamsUtil.getCommonParamsField("nckd_url");
        String mobileUrl = "";//ParamsUtil.getCommonParamsField("nckd_mobileurl");

        if(StringUtils.isNotEmpty(pcUrl)){
            pcUrl = pcUrl.replace(mobileUrl, curUrl);
        }

        if(StringUtils.isNotEmpty(mobUrl)){
            mobUrl = mobUrl.replace(curUrl, mobileUrl);
        }

        if("".equals(pcUrl)||pcUrl==null){
            pcUrl = System.getProperty("domain.contextUrl")+"/index.html?formId=wf_msg_center";
        }

        try {
            pcUrl = pcUrl + "&closeType=closeWin";
            mobUrl = mobUrl + "&closeType=closeWin";

            pcUrl = URLEncoder.encode(pcUrl, "utf-8");
            mobUrl = URLEncoder.encode(mobUrl, "utf-8");
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }

        //异构系统标识
        bodyData.put("syscode", param_syscode);
        //流程实例id
        bodyData.put("flowid", flowid);
        //标题
        bodyData.put("requestname", requestname);
        //流程类型编码
        bodyData.put("workflowcode", workflowcode);
        //流程类型名称
        bodyData.put("workflowname", workflowname);
        //接收人所属节点
        bodyData.put("receivenodename", "");
        //节点名称
        bodyData.put("nodename", nodename);
        //PC地址
        bodyData.put("pcurl", pcUrl);
        //APP地址
        bodyData.put("appurl", mobUrl);
        //创建人
        bodyData.put("creator", creator);
        //创建时间
        bodyData.put("createdatetime", createTime);
        //接收人
        bodyData.put("receiver", personNo);

        //测试人员
        if(StringUtils.isNotEmpty(param_receiver_dev)) {
            bodyData.put("receiver", param_receiver_dev);
        }

        //接收时间
        bodyData.put("receivedatetime", createTime);
        //流程处理状态：0：待办，2：已办，4：办结，8：抄送（待阅）
        bodyData.put("isremark", isremark);
        //流程查看状态：0：未读，1：已读
        bodyData.put("viewtype", viewtype);
        //接收时间戳
        bodyData.put("receivets", curTimestamp);
        //接收人+编码，保存日志使用，oa接口不需要此字段。
        bodyData.put("receiverLong", receiverLong);

        return bodyData;
    }

    /**
     * 组装待办
     * @param todoInfo
     * @return
     */
    public static JSONObject buildToDoBodyData(MessageContext ctx, ToDoInfo todoInfo, Map<String, String> params) {

        DynamicObject taskInfo =  BusinessDataServiceHelper.loadSingleFromCache(todoInfo.getTaskId() ,"wf_task");

        //add by wnaghaiwu_kd 2024/04/28
        //如果任务中找不到，就找历史任务
        if(taskInfo == null){
            taskInfo =  BusinessDataServiceHelper.loadSingleFromCache(todoInfo.getTaskId() ,"wf_hitaskinst");
        }

        JSONObject bodyData = new JSONObject();
        Long userId = Long.valueOf(params.get("userId"));
        String isremark = params.get("isremark").toString();
        String viewtype = params.get("viewtype").toString();

        //发送人员
        Long createUserId = 0L;
        if(taskInfo != null){
            createUserId = taskInfo.getLong("starterid");
        }
        if(createUserId.compareTo(0L) == 0){
            createUserId = ctx.getStartUserId();
        }

        DynamicObject createUser = BusinessDataServiceHelper.loadSingleFromCache(createUserId, "bos_user");
        String creator = createUser == null ? "" : createUser.getString("number");

        String title = todoInfo.getTitle();
        if(todoInfo.getParams() != null && todoInfo.getParams().get("subject") != null){
            JSONObject subject = JSONObject.parseObject(todoInfo.getParams().get("subject").toString());
            title = subject.getString("zh_CN");
        }

        if(StringUtils.isEmpty(title) && taskInfo != null){
            if(StringUtils.isNotEmpty(taskInfo.getString("subject"))){
                title = taskInfo.getString("subject");
            } else {
                title = "请处理" + taskInfo.getString("startname")
                        + "提交的" + taskInfo.getString("entityname") + taskInfo.getString("billno");
            }
        }

        String requestname = title;
        String nodename = todoInfo.getCategory();
        String workflowname = "费控人力审批流";
        String workflowcode = "nobill";

        if(taskInfo != null){
            nodename = taskInfo.getString("name");

            if(taskInfo.getLong("processdefinitionid") > 0) {
                QFilter qFilter = new QFilter("id", QCP.equals, taskInfo.getLong("processdefinitionid"));
                DynamicObject processdef = BusinessDataServiceHelper.loadSingle("wf_processdefinition", qFilter.toArray());
                if (processdef != null) {
                    workflowcode = processdef.getString("key");
                    workflowname = processdef.getString("name");
                }
            }

            if("费控人力审批流".equals(workflowname) && taskInfo.getString("entityname") != null){
                workflowcode = taskInfo.getString("entityname");
                workflowname = taskInfo.getString("entityname") + "审批流程";
            }
        }

        //接收人员
        DynamicObject user = BusinessDataServiceHelper.loadSingleFromCache(userId, "bos_user");
        String personNo = user.getString("number");
        String receiverLong = user.getString("name") + "(" + user.getString("number") + ")";

        //创建时间
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String createTime = sdf.format(new Date());
        String curTimestamp = String.valueOf(System.currentTimeMillis());
        String flowid = "KD-" + todoInfo.getTaskId().toString() + "-" + personNo;

        //add by wanghaiw_kd 2024/04/28
        //如果获取的任务对象为空，则获取flowid相同的待办消息中的发送参数，修改状态、接收时间，做为待办处理的发送参数
        if(taskInfo == null){
            QFilter qFilter = new QFilter("nckd_oaid", QCP.equals, flowid);
            qFilter.and(new QFilter("nckd_logtype", QCP.equals, "1"));

            DynamicObject ecologyLog = BusinessDataServiceHelper.loadSingle("nckd_ecology", qFilter.toArray());

            if(ecologyLog != null && StringUtils.isEmpty(ecologyLog.getString("nckd_senddata_tag"))){
                JSONObject fanweiBodyData = JSONObject.parseObject(ecologyLog.getString("nckd_senddata_tag"));

                //流程处理状态：0：待办，2：已办，4：办结，8：抄送（待阅）
                fanweiBodyData.put("isremark", "2");
                //流程查看状态：0：未读，1：已读
                fanweiBodyData.put("viewtype", "1");
                //接收时间
                fanweiBodyData.put("receivedatetime", createTime);
                //接收时间戳
                fanweiBodyData.put("receivets", curTimestamp);

                return fanweiBodyData;
            }
        }

//        String url = MessageServiceUtil.buildWebPageUrlForMyApplyed(ctx.getProcessInstanceId());
        String url = todoInfo.getUrl();
        logger.info("消息url:" + url);

        String pcUrl = "";
        String mobUrl = "";

        if(StringUtils.isNotEmpty(url)){
            String contextUrl = System.getProperty("domain.contextUrl").replace("/ierp", "");
            url = url.replace("http://127.0.0.1:8080", "").replace(contextUrl, "");
            pcUrl = url;
            mobUrl = url;

            //移动端需要走外网，将地址替换成外网地址
            String curUrl = "";//ParamsUtil.getCommonParamsField("nckd_url");
            String mobileUrl = "";//ParamsUtil.getCommonParamsField("nckd_mobileurl");
            pcUrl = pcUrl.replace(mobileUrl, curUrl);
            mobUrl = mobUrl.replace(curUrl, mobileUrl);

            try {

                pcUrl = pcUrl + "&closeType=closeWin";
                mobUrl = mobUrl + "&closeType=closeWin";

                pcUrl = URLEncoder.encode(pcUrl, "utf-8");
                mobUrl = URLEncoder.encode(mobUrl, "utf-8");
            } catch (UnsupportedEncodingException e) {
                throw new RuntimeException(e);
            }
        }

        //异构系统标识
        bodyData.put("syscode", param_syscode);
        //流程实例id
        bodyData.put("flowid", flowid);
        //标题
        bodyData.put("requestname", requestname);
        //流程类型编码
        bodyData.put("workflowcode", workflowcode);
        //流程类型名称
        bodyData.put("workflowname", workflowname);
        //接收人所属节点
        bodyData.put("receivenodename", "");
        //节点名称
        bodyData.put("nodename", nodename);
        //PC地址
        bodyData.put("pcurl", pcUrl);
        //APP地址
        bodyData.put("appurl", mobUrl);
        //创建人
        bodyData.put("creator", creator);
        //创建时间
        bodyData.put("createdatetime", createTime);
        //接收人
        bodyData.put("receiver", personNo);

        if(StringUtils.isNotEmpty(param_receiver_dev)) {
            //测试人员
            bodyData.put("receiver", param_receiver_dev);
        }

        //接收时间
        bodyData.put("receivedatetime", createTime);
        //流程处理状态：0：待办，2：已办，4：办结，8：抄送（待阅）
        bodyData.put("isremark", isremark);
        //流程查看状态：0：未读，1：已读
        bodyData.put("viewtype", viewtype);
        //接收时间戳
        bodyData.put("receivets", curTimestamp);
        //接收人+编码，保存日志使用，oa接口不需要此字段。
        bodyData.put("receiverLong", receiverLong);

        return bodyData;
    }


    /**
     * 获取泛微OA的accesstoken
     * @return
     */
    public static String getFanWeiToken(boolean isSerchParam) {
        if(isSerchParam){
            setParmamValue();
        }

        String bodyString = "";
        String token = "";
        String result = "";
        String url = "";

        Map<String, String> header = new HashMap<>();
        header.put("Content-Type", "application/json; charset=UTF-8");


        try {
            url = param_getcode + "?corpid=" + param_cropid + "&response_type=" + param_responsetype + "&state=" + param_state;

            logger.info("获取泛微code接口地址：" + url);
            //获取code
            bodyString = CommonHelperUtils.buildEsbApiBodyJSON(null);
            result = KHttpClientUtils.postjson(url, header, bodyString);
        } catch (Exception e) {
            logger.info(e.getMessage());

            String message = ResManager.loadKDString("获取泛微code失败，原因:%s", "WFErrorCode_10001", "bos-wf-engine", new Object[0]);
            ErrorCode error = new ErrorCode("bos.wf.rpa.", message);
            throw new WFMessageServiceException(e, error, new Object[]{e.getMessage()});
        }

        if(StringUtils.isEmpty(result)){
            throw new WFMessageServiceException("获取泛微code异常: 接口返回为空");
        }

        JSONObject codeObj = JSONObject.parseObject(result);
        String errcode = codeObj.getString("errcode");

        if(!"0".equals(errcode)) {
            String errCode = codeObj.getString("errcode") == null ? "" : codeObj.getString("errcode");
            String errMsg = codeObj.getString("errmsg") == null ? "" : codeObj.getString("errmsg");

            throw new WFMessageServiceException("获取泛微code异常: " + errMsg + "(" + errCode + ")");
        }
        String code = codeObj.getString("code");

        //获取token
        try {
            url = param_gettoken + "?app_key=" + param_appkey + "&app_secret=" + param_appsecret + "&grant_type=" + param_granttype + "&code=" + code;
            logger.info("获取泛微token接口地址：" + url);

            bodyString = CommonHelperUtils.buildEsbApiBodyJSON(null);

            result = KHttpClientUtils.postjson(url, header, bodyString);
        } catch (IOException e) {
            logger.info(e.getMessage());

            String message = ResManager.loadKDString("获取泛微token失败，原因:%s", "WFErrorCode_10001", "bos-wf-engine", new Object[0]);
            ErrorCode error = new ErrorCode("bos.wf.rpa.", message);
            throw new WFMessageServiceException(e, error, new Object[]{e.getMessage()});
        }

        if(StringUtils.isEmpty(result)){
            throw new WFMessageServiceException("获取泛微token异常: 接口返回为空");
        }

        JSONObject tokenObj = JSONObject.parseObject(result);
        errcode = tokenObj.getString("errcode");

        if(!"0".equals(errcode)) {
            String errCode = codeObj.getString("errcode") == null ? "" : codeObj.getString("errcode");
            String errMsg = codeObj.getString("errmsg") == null ? "" : codeObj.getString("errmsg");

            throw new WFMessageServiceException("获取泛微code异常: " + errMsg + "(" + errCode + ")");
        }
        token = tokenObj.getString("accessToken");

        return token;
    }



    /**
     * 保存日志
     * @param userid
     * @param title
     * @param msgContent
     * @param sendData
     * @return
     */
    private static String saveLogData(String userid, String title, String oaId, String msgContent, String sendData, String logType, String url) {
        try {
            logger.info("记录新增泛微推送数据日志");

            msgContent = msgContent == null ? "" : msgContent;
            sendData = sendData == null ? "" : sendData;

            String uuid = UUID.randomUUID().toString().replace("-", "");

            uuid = uuid == null ? "uuid" + String.valueOf(System.currentTimeMillis()) : uuid;
            DynamicObject dynamicObject = BusinessDataServiceHelper.newDynamicObject(KEY_ENTITY_LOG);

            dynamicObject.set("enable", "1");
            dynamicObject.set("status", "C");
            dynamicObject.set("number", uuid);
            dynamicObject.set("nckd_logtype", logType);
            dynamicObject.set("nckd_sendurl", url);
            dynamicObject.set("nckd_receiver", userid);
            dynamicObject.set("nckd_title", title);
            dynamicObject.set("nckd_oaid", oaId);

            dynamicObject.set("nckd_sendtime", new Date());
            if (sendData.length() < 200) {
                dynamicObject.set("nckd_senddata", sendData);
            } else {
                dynamicObject.set("nckd_senddata", sendData.substring(0, 200) + "...");
            }
            dynamicObject.set("nckd_senddata_tag", sendData);

            if (msgContent.length() < 200) {
                dynamicObject.set("nckd_msgcontent", msgContent);
            } else {
                dynamicObject.set("nckd_msgcontent", msgContent.substring(0, 200) + "...");
            }
            dynamicObject.set("nckd_msgcontent_tag", msgContent);

            SaveServiceHelper.save(new DynamicObject[]{dynamicObject});
            logger.info("记录新增泛微推送数据日志成功:{}", uuid);
            return uuid;
        } catch (Exception e) {
            logger.info("记录新增泛微推送数据日志异常:" + e.getMessage());
            e.printStackTrace();
        }
        return null;
    }


    /**
     * 更新日志
     * @param uuid
     * @param response
     */
    private static void updateLogData(String uuid, String response, String sendStatus) {
        try {
            logger.info("记录更新泛微推送结果数据日志");
            response = response == null ? "" : response;

            QFilter qFilterCas = new QFilter("number", QCP.equals, uuid);
            DynamicObject[] dynamicObjects = BusinessDataServiceHelper.load(KEY_ENTITY_LOG, "id", new QFilter[]{qFilterCas});
            if (dynamicObjects != null && dynamicObjects.length > 0) {
                String id = dynamicObjects[0].getPkValue().toString();
                DynamicObject dynamicObject = BusinessDataServiceHelper.loadSingle(id, KEY_ENTITY_LOG);
                if (response.length() < 200) {
                    dynamicObject.set("nckd_resultdata", response);
                } else {
                    dynamicObject.set("nckd_resultdata", response.substring(0, 200) + "...");
                }
                dynamicObject.set("nckd_resultdata_tag", response);
                dynamicObject.set("nckd_sendstatus", sendStatus);

                SaveServiceHelper.update(dynamicObject);

                logger.info("记录更新泛微推送结果数据日志成功");
            }
        } catch (Exception e) {
            logger.info("记录更新泛微推送结果数据日志异常:" + e.getMessage());
            e.printStackTrace();
        }

    }

    /**
     *
     * @param url
     * @param bodyData
     * @return
     */
    public static JSONObject doPostByHttpClient(String url, JSONObject bodyData) {
        try {
            Map<String, String> headers = new HashMap();
            headers.put("Content-Type", "application/json; charset=utf-8");
            headers.put("Accept", "application/json");
            logger.info(String.format("url[%s],data[%s]", url, bodyData.toJSONString()));
            System.out.println(String.format("url[%s],data[%s]", url, bodyData.toJSONString()));

            String responseEntify = HttpUtils.postjson(url, headers, bodyData.toJSONString());
            JSONObject result = (JSONObject)JSONObject.parse(responseEntify);
            return result;
        } catch (IOException var5) {
            throw new KDException(var5, WFErrorCode.httpRequestException(), new Object[]{var5.getMessage()});
        }
    }

    /**
     * 发送普通消息到泛微OA
     * @param path
     * @param params
     * @param data
     * @return
     */
    public static String doPostByHttpClient(String path, Map<String, String> params, Map<String, String> data) {
        if(path.toLowerCase().startsWith("https")){
            return doPostByHttps(path, params, data);
        }
        return doPostByHttp(path, params, data);
    }

    /**
     * http服务
     * @param path
     * @param params
     * @param data
     * @return
     */
    public static String doPostByHttp(String path, Map<String, String> params, Map<String, String> data) {
        String errMsg = "";
        try {
            String str = "";
            URL url = new URL(path);
            //打开和url之间的连接
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            // 请求参数 编码为 utf-8
            //请求方式
            conn.setRequestMethod("POST");
            //设置通用的请求属性
            conn.setRequestProperty("accept", "*/*");
            conn.setRequestProperty("connection", "Keep-Alive");
            conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");
            if (data != null) {
                for (Map.Entry<String, String> entry : data.entrySet()) {
                    conn.setRequestProperty(entry.getKey(), entry.getValue());
                }
            }
            //设置是否向httpUrlConnection输出，设置是否从httpUrlConnection读入，此外发送post请求必须设置这两个
            //最常用的Http请求无非是get和post，get请求可以获取静态页面，也可以把参数放在URL字串后面，传递给servlet，
            //post与get的 不同之处在于post的参数不是放在URL字串里面，而是放在http请求的正文内。
            conn.setDoOutput(true);
            conn.setDoInput(true);
            OutputStreamWriter out = new OutputStreamWriter(conn.getOutputStream(), "utf-8");
            if (params != null) {
                out.write(mapToStr(params));
            }
            //缓冲数据
            out.flush();
            out.close();
            //获取URLConnection对象对应的输入流
            InputStream is = conn.getInputStream();
            //构造一个字符流缓存
            BufferedReader br = new BufferedReader(new InputStreamReader(is,"utf-8"));
            String result = "";
            while ((str = br.readLine()) != null) {
                result = str;
            }
            //关闭流
            is.close();
            //断开连接，最好写上，disconnect是在底层tcp socket链接空闲时才切断。如果正在被其他线程使用就不切断。
            //固定多线程的话，如果不disconnect，链接会增多，直到收发不出信息。写上disconnect后正常一些。
            conn.disconnect();
            return result;
        } catch (Exception e) {
            errMsg = "消息发送至OA异常：" + e;
            logger.warn("消息发送至OA异常:", e);
            //e.printStackTrace();
//            return errMsg;
        }
        return errMsg;
    }

    /**
     * htts服务
     * @param path
     * @param params
     * @param data
     * @return
     */
    public static String doPostByHttps(String path, Map<String, String> params, Map<String, String> data) {
        String errMsg = "";
        try {
            String str = "";
            TrustManager[] tm = { new MyX509TrustManager() };
            SSLContext sslContext = SSLContext.getInstance("TLS");
            sslContext.init(null, tm, new java.security.SecureRandom());
            // 从上述SSLContext对象中得到SSLSocketFactory对象
            SSLSocketFactory ssf = sslContext.getSocketFactory();
            HttpsURLConnection.setDefaultSSLSocketFactory(ssf);
            // 打开和URL之间的连接
            URL realUrl = new URL(path);
            HttpsURLConnection conn = (HttpsURLConnection) realUrl.openConnection();
            // 避免只要域名提交
            conn.setHostnameVerifier(new TrustAnyHostnameVerifier());
            // 请求参数 编码为 utf-8
            //请求方式
            conn.setRequestMethod("POST");
            //设置通用的请求属性
            conn.setRequestProperty("accept", "*/*");
            conn.setRequestProperty("connection", "Keep-Alive");
            conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");
            if (data != null) {
                for (Map.Entry<String, String> entry : data.entrySet()) {
                    conn.setRequestProperty(entry.getKey(), entry.getValue());
                }
            }
            //设置是否向httpUrlConnection输出，设置是否从httpUrlConnection读入，此外发送post请求必须设置这两个
            //最常用的Http请求无非是get和post，get请求可以获取静态页面，也可以把参数放在URL字串后面，传递给servlet，
            //post与get的 不同之处在于post的参数不是放在URL字串里面，而是放在http请求的正文内。
            conn.setDoOutput(true);
            conn.setDoInput(true);
            OutputStreamWriter out = new OutputStreamWriter(conn.getOutputStream(), "utf-8");
            if (params != null) {
                out.write(mapToStr(params));
            }
            //缓冲数据
            out.flush();
            out.close();
            //获取URLConnection对象对应的输入流
            InputStream is = conn.getInputStream();
            //构造一个字符流缓存
            BufferedReader br = new BufferedReader(new InputStreamReader(is,"utf-8"));
            String result = "";
            while ((str = br.readLine()) != null) {
                result = str;
            }
            //关闭流
            is.close();
            //断开连接，最好写上，disconnect是在底层tcp socket链接空闲时才切断。如果正在被其他线程使用就不切断。
            //固定多线程的话，如果不disconnect，链接会增多，直到收发不出信息。写上disconnect后正常一些。
            conn.disconnect();
            return result;
        } catch (Exception e) {
            errMsg = "消息发送至OA异常：" + e;
            logger.warn("消息发送至OA异常:", e);
            //e.printStackTrace();
//            return errMsg;
        }
        return errMsg;
    }

    /**
     * 将Map转换成字符串参数，用于POST GET 请求
     * @param map
     * @return
     */
    public static String mapToStr(Map<String, String> map) {
        StringBuilder stringBuilder = new StringBuilder();
        if (map != null) {
            for (Map.Entry<String, String> entry : map.entrySet()) {
                stringBuilder.append(entry.getKey());
                if (entry.getValue() != null) {
                    stringBuilder.append("=").append(entry.getValue());
                }
                stringBuilder.append("&");
            }
        }
        if (stringBuilder.length() > 0) {
            return stringBuilder.substring(0, stringBuilder.length() - 1);
        }
        return null;
    }
}
