package com.malk.kuaikeli.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.malk.kuaikeli.service.KKLService;
import com.malk.server.aliwork.YDConf;
import com.malk.server.aliwork.YDParam;
import com.malk.server.aliwork.YDSearch;
import com.malk.server.common.McException;
import com.malk.server.common.McR;
import com.malk.server.dingtalk.DDConf;
import com.malk.server.dingtalk.DDR_New;
import com.malk.service.aliwork.YDClient;
import com.malk.service.aliwork.YDService;
import com.malk.service.dingtalk.DDClient;
import com.malk.utils.*;
import lombok.SneakyThrows;
import lombok.Synchronized;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.logging.log4j.util.Strings;
import org.apache.xmlbeans.impl.xb.xsdschema.Public;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
public class KKLImplService implements KKLService {

    //供应商原材料档案表
    private static final String SUPPLIER_MATERIALS = "FORM-12EB6BCE3C264630824721E7BBABCC03L8U9";
    private static final String SUPPLIER_CHANGE = "FORM-C939E9F486124464B17A6910D66A2425EWPX";
    //定价单明细中间表
    private static final String PRICE_DETAIL_MIDDLE = "FORM-E6766M811CKD2PIXEAKOM9S2DKBM2PBQU1MLL5";
    //菜品管理
    private static final String FOOD = "FORM-GP666M71DIGDE0ZADDLZ85VEFBD128OUH1MLLF";

    @Autowired
    private YDService ydService;

    @Autowired
    private YDClient ydClient;

    @Autowired
    private DDClient ddClient;

    @Autowired
    private DDConf ddConf;

    /**
     * [动态] 发起单据, 分供应商进行流程推送
     */
    @Override
    public void matchSupplier(Map data) {

        // ppExt: 供应商区分发起: 当前表：供应供子表组件ID，子表内供应商编号，名称，负责人
        String[] compIds_supplier = String.valueOf(data.get("compId_supplier")).split(", ");
        String compId_supplier = compIds_supplier[1];

        Map formData = (Map) JSON.parse(String.valueOf(data.get("formData")));
        List<Map> details = (List<Map>) formData.get(compIds_supplier[0]);

        // 供应商编号, 数据去重: 提取数据区分供应商发起
        List<Map> suppliers = UtilMc.distinctByKey(details, compId_supplier);
        for (Map supplier : suppliers) {
            List<Map> dataList = details.stream().filter(item -> supplier.get(compId_supplier).equals(item.get(compId_supplier))).collect(Collectors.toList());
            formData.put(compIds_supplier[0], dataList);
            // ppExt: 参数传递, 目标表组件ID, 对照当前表子表内的子表内供应商编号，名称，负责人已放置主表字段, 此处公共内容提前首条数据进行赋值
            for (int i = 1; i < compIds_supplier.length; i++) {
                formData.put(compIds_supplier[i], YDConf.getDataByCompId(dataList.get(0), compIds_supplier[i]));
            }
            data.put("formData", JSON.toJSONString(formData));
            ydService.copyFormData(data); // 发起流程
        }
    }

    /**
     * 菜单计划, 编辑校验
     * -
     * 前端提交动作: 校验是否审批通过, 是否当日之前计划, 是否当日且在16点及以后时间, 均不允许提交
     * 后端校验返回、加任何产品都要走审批，减少20%以内直接过，每一个原材料
     */
    @Override
    public boolean validateApprove(Map data) {
        boolean approve =UtilMap.getBoolean(data,"approveFlag");
//        boolean approve = false;
        List<Map> dataList = UtilMap.getList(data, "list");
//        for (Map row : dataList) {
//             匹配切配工作单, 采购
//            List<Map> formList = (List<Map>) ydClient.queryData(YDParam.builder()
//                            .formUuid("FORM-RK966E71T0LDSTW39WFHE9OQ5GU23FKRRDNLL2")
//                            .searchFieldJson(JSON.toJSONString(UtilMap.map("textField_lmsuq8am, textField_lm8zta2z, textField_ln1ez5li, textField_llndm599", data.get("name"), data.get("area"), row.get("textField_ln1ez5li"), row.get("textField_llndm599"))))
//                            .build(),
//                    YDConf.FORM_QUERY.retrieve_search_form).getData();
//
//            if (formList.size() == 0) {
//                approve = true;// 添加原材料  判断条件是否有对应的切配工作单
//                break;
//            }
//            Map formData = (Map) formList.get(0).get("formData");
//            float cur = UtilMap.getFloat(row, "numberField_lmym5628");// 计划数量
//            float src = UtilMap.getFloat(formData, "numberField_lln477o2");// 切配工作单数量
//            if (cur > src || (src - cur) / src > 0.2f) {
//                approve = true;
//                break;
//            }
//        }
        String poid=UtilMap.getString(data,"poid");
        if (approve) {
            // 发起菜单审批
            log.info("发起菜单审批");
            // 保存数据到备份表单
            String id=(String) ydService.mirrorFormData(poid,"FORM-1FD63CF820F3444D994F0486CA95F6E6UZ2E","",new HashMap(),"");
            Map form=UtilMap.getMap(data,"form");
            form.put("textField_lx2l5l2s",poid);
            form.put("textField_lx2l5l2t",id);
            form.put("textField_lx2omku4",data.get("user").toString());
            ydClient.operateData(YDParam.builder()
                    .formUuid("FORM-UP96637100HD036TA1M05B74GHLV3DRS54NLLC")
                    .processCode("TPROC--UP96637100HD036TA1M05B74GHLV3ERS54NLLD")
                    .formDataJson(JSON.toJSONString(form)) // 前端数据组装
                    .userId(data.get("user").toString())
                    .build(), YDConf.FORM_OPERATION.start);
        }else{
            log.info("未触发审批 执行业务逻辑-编辑前后更新计划采购单");
            planUpdate(poid,dataList,data.get("user").toString());
        }
        return approve;
    }

    @Override
    public void planApproval(Map data) {
        String fid=UtilMap.getString(data,"fid");
        String backFid=UtilMap.getString(data,"backFid");
        String results=UtilMap.getString(data,"results");
        String userId=UtilMap.getString(data,"userId");
        if(results.equals("通过")){
            log.info("审批通过 保存变更信息");
            // 新数据
            Map formData=(Map) ydClient.queryData(YDParam.builder().formInstId(fid).build(), YDConf.FORM_QUERY.retrieve_id).getFormData();
            // 旧数据
            Map backData=(Map) ydClient.queryData(YDParam.builder().formInstId(backFid).build(), YDConf.FORM_QUERY.retrieve_id).getFormData();
            List<Map> list=UtilMap.getList(backData,"tableField_lln477nw");
            saveData(list,formData,false,userId);// -
            list=UtilMap.getList(formData,"tableField_lln477nw");
            saveData(list,formData,true,userId);// +

        }else{
            log.info("审批拒绝 还原备份数据");
            ydService.mirrorFormData(backFid,"FORM-IH966T61XJZDNT4D9N6D189RJ2CK3Q27NZ5ML0","",new HashMap(),fid);
        }
    }

    @Override
    public void updateState(String id) {
        try {
            log.info("异步修改状态，休眠3s");
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        // 更新计划状态
        ydService.operateData(YDParam.builder()
                .formInstanceId(id)
                .updateFormDataJson(JSON.toJSONString(UtilMap.map("textField_lm8znr9n", "执行中")))
                .build(), YDConf.FORM_OPERATION.update);
    }

    private void planUpdate(String poid,List<Map> dataList,String userId){
        Map formData=(Map) ydClient.queryData(YDParam.builder().formInstId(poid).build(), YDConf.FORM_QUERY.retrieve_id).getFormData();
        List<Map> list=UtilMap.getList(formData,"tableField_lln477nw");
        saveData(list,formData,false,userId);// -
        saveData(dataList,formData,true,userId);// +
    }

    /***
     * 保存数据
     * @param list true:新数据 false:老数据
     * @param formData 菜单计划数据
     * @param isAdd true 加数据 false 减数据
     * @param userId 新增操作的用户编号
     */
    private void saveData(List<Map> list,Map formData,boolean isAdd,String userId){
        String formUuid="FORM-XHA66881J8KDA6V3FM6LZBUP9PDE37VESDNLL6";// 计划采购单
        for(Map map:list){
            Map queryMap=new HashMap();
            queryMap.put("dateField_llndtdwl", Arrays.asList(map.get("dateField_ln1ez5lg"),map.get("dateField_ln1ez5lg")));// 日期
            queryMap.put("textField_llq9x6ov",formData.get("textField_lln477nh"));// 项目编号
            queryMap.put("textField_lmk97m1v",map.get("textField_lmk97m1v"));// 原材料编号
            Map upMap=new HashMap();
            upMap.put("numberField_llojyfy3",map.get("numberField_lmsvfftq"));// 成本单价
            upMap.put("numberField_llojyfy4",map.get("numberField_lmsvfftr"));// 服务费率
            upMap.put("dateField_llndtdwl",map.get("dateField_ln1ez5lg"));// 计划日期
            upMap.put("textField_llndm599",map.get("textField_llndm599"));// 原材料名称
            upMap.put("textField_lluj4hu1",map.get("textField_lln3lmn2"));// 单位
            upMap.put("textField_llq9x6ov",formData.get("textField_lln477nh"));// 项目编号
            upMap.put("textField_lm5z7kvo",map.get("textField_ln1ez5li"));// 计划日期（文本）
            upMap.put("textField_lm5z4ioi",formData.get("textField_lmsvfftp"));// 项目名称
            upMap.put("textField_lmk97m1v",map.get("textField_lmk97m1v"));// 原材料编号
            upMap.put("selectField_lmqclyx9",map.get("selectField_lmqclyx9"));// 第一分类
            upMap.put("numberField_lmqclyxa",map.get("numberField_lmqclyxa"));// 供货价
            upMap.put("textField_lnsmha2j",map.get("textField_lnwxz9ji"));// 品牌
            upMap.put("textField_lpjet322",formData.get("textField_lpjet322"));// 档口名称
            upMap.put("textField_lpjet321",formData.get("textField_lpjet321"));// 档口编号
            upMap.put("textField_loe04txb",map.get("textField_lptgvips"));// 采购单位
            List<Map> list2=(List<Map>) ydClient.queryData(YDParam.builder().formUuid(formUuid).searchFieldJson(JSONObject.toJSONString(queryMap)).build(), YDConf.FORM_QUERY.retrieve_list).getData();
            if(list2==null||list2.size()<1){
                if(!isAdd){
                    log.info("未找到对应的计划采购单,退出");
                    continue;
                }
                upMap.put("numberField_lln477o2", map.get("numberField_lmym5628"));// 初始采购数量（kg）
                upMap.put("numberField_lm9008fq", map.get("numberField_lmym5628"));// 实际采购数量（kg）
                upMap.put("numberField_lns0dkzv", map.get("numberField_lns0dkzv"));// 投料数量（kg）
                upMap.put("numberField_loe04txa", map.get("numberField_lomyf89l"));// 采购量
                ydClient.operateData(YDParam.builder().formUuid(formUuid).formDataJson(JSONObject.toJSONString(upMap)).userId(userId).build(), YDConf.FORM_OPERATION.create);
            }else{
                Map oldMap=UtilMap.getMap(list2.get(0),"formData");
                if(isAdd){
                    upMap.put("numberField_lln477o2", NumberUtil.add(UtilMap.getString(oldMap,"numberField_lln477o2"),UtilMap.getString(map,"numberField_lmym5628")));// 初始采购数量（kg）
                    upMap.put("numberField_lm9008fq", NumberUtil.add(UtilMap.getString(oldMap,"numberField_lm9008fq"),UtilMap.getString(map,"numberField_lmym5628")));// 实际采购数量（kg）
                    upMap.put("numberField_lns0dkzv", NumberUtil.add(UtilMap.getString(oldMap,"numberField_lns0dkzv"),UtilMap.getString(map,"numberField_lns0dkzv")));// 投料数量
                    upMap.put("numberField_loe04txa", NumberUtil.add(UtilMap.getString(oldMap,"numberField_loe04txa"),UtilMap.getString(map,"numberField_lomyf89l")));// 采购量
                }else {
                    upMap.put("numberField_lln477o2", NumberUtil.sub(UtilMap.getString(oldMap, "numberField_lln477o2"), UtilMap.getString(map, "numberField_lmym5628")));// 初始采购数量（kg）
                    upMap.put("numberField_lm9008fq", NumberUtil.sub(UtilMap.getString(oldMap, "numberField_lm9008fq"), UtilMap.getString(map, "numberField_lmym5628")));// 实际采购数量（kg）
                    upMap.put("numberField_lns0dkzv", NumberUtil.sub(UtilMap.getString(oldMap, "numberField_lns0dkzv"), UtilMap.getString(map, "numberField_lns0dkzv")));// 投料数量
                    upMap.put("numberField_loe04txa", NumberUtil.sub(UtilMap.getString(oldMap,"numberField_loe04txa"),UtilMap.getString(map,"numberField_lomyf89l")));// 采购量
                }
                ydClient.operateData(YDParam.builder().formInstanceId(UtilMap.getString(list2.get(0),"formInstanceId")).updateFormDataJson(JSONObject.toJSONString(upMap)).build(), YDConf.FORM_OPERATION.update);
            }
            String formUuid2="FORM-RK966E71T0LDSTW39WFHE9OQ5GU23FKRRDNLL2";
            Map qMap=new HashMap();
            qMap.put("textField_lmsuq8am",formData.get("textField_lln477nh"));// 项目编号
            qMap.put("dateField_llndtdwl",Arrays.asList(map.get("dateField_ln1ez5lg"),map.get("dateField_ln1ez5lg")));// 日期
            qMap.put("textField_lm8zta2z",formData.get("selectField_llm1i9yl"));// 餐次
            qMap.put("selectField_lln3lmn5",map.get("textField_lm4m83rv"));// 切配类型
            qMap.put("textField_llndm599",map.get("textField_llndm599"));// 原材料名称
            Map addMap=new HashMap();
            addMap.putAll(qMap);
            String data=String.valueOf(formData.get("associationFormField_lln477nb_id"));
            addMap.put("associationFormField_llndtdwg",JSONObject.parseArray(data.substring(1,data.length()-1).replaceAll("\\\\","")));// 项目点
            addMap.put("textField_ln1ez5li",map.get("textField_ln1ez5li"));// 计划日期（文本）
            addMap.put("dateField_llndtdwl",map.get("dateField_ln1ez5lg"));// 日期
            List<Map> list3=(List<Map>) ydClient.queryData(YDParam.builder().formUuid(formUuid2).searchFieldJson(JSONObject.toJSONString(qMap)).build(),
                    YDConf.FORM_QUERY.retrieve_list).getData();
            if(list3==null||list3.size()<1){
                if(!isAdd){
                    log.info("未找到对应的切配工作单,退出");
                    continue;
                }
                addMap.put("numberField_lln477o2",map.get("numberField_lmym5628"));// 数量(kg)
                addMap.put("numberField_lnrkgimz",map.get("numberField_lomyf89l"));// 初始采购数量
                ydClient.operateData(YDParam.builder().formUuid(formUuid2)
                        .formDataJson(JSONObject.toJSONString(addMap))
                        .userId(userId)
                        .build(), YDConf.FORM_OPERATION.create);
            }else{
                Map oldMap=UtilMap.getMap(list3.get(0),"formData");
                if(isAdd){
                    addMap.put("numberField_lln477o2", NumberUtil.add(UtilMap.getString(oldMap,"numberField_lln477o2"),UtilMap.getString(map,"numberField_lmym5628")));// 数量(kg)
                    addMap.put("numberField_lnrkgimz", NumberUtil.add(UtilMap.getString(oldMap,"numberField_lnrkgimz"),UtilMap.getString(map,"numberField_lomyf89l")));// 初始采购数量
                }else {
                    addMap.put("numberField_lln477o2", NumberUtil.sub(UtilMap.getString(oldMap,"numberField_lln477o2"), UtilMap.getString(map, "numberField_lmym5628")));// 数量(kg)
                    addMap.put("numberField_lnrkgimz", NumberUtil.sub(UtilMap.getString(oldMap,"numberField_lnrkgimz"), UtilMap.getString(map, "numberField_lomyf89l")));// 初始采购数量
                }
                ydClient.operateData(YDParam.builder().formInstanceId(UtilMap.getString(list3.get(0),"formInstanceId"))
                        .updateFormDataJson(JSONObject.toJSONString(addMap))
                        .build(), YDConf.FORM_OPERATION.update);
            }
        }
    }

    /**
     * 定价单: 项目点 & 供应商大类, 数据匹配
     */
    @Override
    @SneakyThrows
    @Synchronized
    public void serviceRate(Map data) {

        // todo2: 宜搭更新，校验的超时等待在3s, 因此方法修改为异步. 容错定时任务？匹配不一致数据
        String supperCode = String.valueOf(data.get("code"));
        List<String> types = (List<String>) JSON.parse(String.valueOf(data.get("type")));
        List<String> rates = (List<String>) JSON.parse(String.valueOf(data.get("rate")));
        List<String> rates2 = (List<String>) JSON.parse(String.valueOf(data.get("rate2")));
        List<String> status = (List<String>) JSON.parse(String.valueOf(data.get("status")));
        String oldSupId=String.valueOf(data.get("oldSupId"));

        for (int i = 0; i < types.size(); i++) {

            List<Map> materials = supperMaterials(supperCode, types.get(i));
            List<Map> records = projectMaterials(supperCode, types.get(i));
            log.info("定价单同步, {}, {}", materials.size(), records.size());
            for (Map material : materials) {

                // 数据处理: 服务费率与供货价, 项目信息
                double rate = Double.valueOf(rates.get(i));
                double rate2 = Double.valueOf(rates2.get(i));
                material.putAll(UtilMap.map("numberField_llkb7kcy, numberField_lpalgz04, textField_lm4lxur8", rate, rate2, status.get(i)));
                double price1 = UtilNumber.formatPrecisionValue(UtilMap.getDouble(material, "numberField_llkknd6g") * (rate + 100) / 100f);
                double price2 = UtilNumber.formatPrecisionValue(UtilMap.getDouble(material, "numberField_lpalgz05") * (100 + rate2) / 100f);
                material.putAll(UtilMap.map("numberField_llkknd6h, numberField_lpalgz0a", price1, price2));
                material.putAll(UtilMap.map("textField_llm1vtjm, textField_loy1ep8r", data.get("proCode"), data.get("proName")));

                YDParam ydParam = YDParam.builder()
                        .formUuid("FORM-E6766M811CKD2PIXEAKOM9S2DKBM2PBQU1MLL5")
                        .formDataJson(JSON.toJSONString(material))
                        .build();
                YDConf.FORM_OPERATION operation = YDConf.FORM_OPERATION.create;
                // ppExt: 提交校验逻辑, 匹配定价单数若存在则匹配服务费率, 不一致执行更新
                if (records.size() > 0) {
                    Optional optional = records.stream().filter(item -> item.get("textField_llkb7kd2").equals(material.get("textField_llkb7kd2")) && // 物品编号
                            item.get("textField_llm1vtjm").equals(material.get("textField_llm1vtjm"))// 项目编号)
                    ).findAny();
                    if (optional.isPresent()) {
                        ydParam.setUpdateFormDataJson(JSON.toJSONString(material));
                        ydParam.setFormInstanceId(String.valueOf(((Map) optional.get()).get("formInstanceId")));
                        operation = YDConf.FORM_OPERATION.update;
                    }
                }
                ydClient.operateData(ydParam, operation);
            }
        }
    }



    /// 原材料: 供应商第一分类下物料
    List<Map> supperMaterials(String code, String type) {
        List<Map> dataList = ydService.queryFormData_all(YDParam.builder()
                .formUuid("FORM-12EB6BCE3C264630824721E7BBABCC03L8U9")
                .searchFieldJson(JSON.toJSONString(UtilMap.map("textField_llzzbyj1, selectField_llkk6cms", code, type)))
                .build());
        log.info("supperMaterials, {}", dataList.size());
        return dataList;
    }

    /// 定价单: 供应商第一分类下物料
    List<Map> projectMaterials(String code, String type) {
        List<Map> dataList = ydService.queryFormData_all(YDParam.builder()
                .formUuid("FORM-E6766M811CKD2PIXEAKOM9S2DKBM2PBQU1MLL5")
                .searchFieldJson(JSON.toJSONString(UtilMap.map("textField_llzzbyj1, selectField_llkk6cms", code, type)))
                .build());
        log.info("projectMaterials, {}", dataList.size());
        return dataList;
    }


    /**
     * 物料档案: 价格调整
     */
    @Override
    @Async
    public void adjustCost(Map data) {

        double cost1 = UtilMap.getDouble(data, "costPrice");
        double cost2 = UtilMap.getDouble(data, "nextCostPrice");
        String cost3 = UtilMap.getString(data,"timeLimit");
        String cost4 = UtilMap.getString(data,"packNumber");// 包装数量
        String cost5 = UtilMap.getString(data,"packUnit");// 包装单位
        String cost6 = UtilMap.getString(data,"state");// 原材料状态
        String supId = UtilMap.getString(data,"supId");// 供应商编号  2024/12/9 添加 （类型变更需求）
        String typeOne = UtilMap.getString(data,"typeOne");// 一级分类  2024/12/9 添加 （类型变更需求）
        String typeTwo = UtilMap.getString(data,"typeTwo");// 二级分类  2024/12/9 添加 （类型变更需求）

        //todo2: 服务执行, 周日凌晨更新价格前, 是否重新匹配数据?
        List<Map> jsonString = new ArrayList<>();
        jsonString.add(UtilMap.map("key, value, type, operator, componentName", "textField_llkb7kd2",data.get("itemNumber"),"TEXT","eq","TextField"));
        String searchCondition = JSONObject.toJSONString(jsonString);
        List<Map> dataList = ydService.queryFormData_all(YDParam.builder()
                .formUuid("FORM-E6766M811CKD2PIXEAKOM9S2DKBM2PBQU1MLL5")
//                .searchFieldJson(JSON.toJSONString(UtilMap.map("textField_llkb7kd2", data.get("itemNumber"))))//模糊匹配
                .searchFieldJson(searchCondition)//精准匹配
                .build());
        log.info("adjustCost, {}", dataList.size());

        Map<String,Integer> resultValue=new HashMap(); // 项目编号:下标
        for (int i = 0; i < dataList.size(); i++) {
            resultValue.putIfAbsent(String.valueOf(dataList.get(i).get("textField_llm1vtjm")),i);
        }

        // 中间表不存在数据，新增数据
        List<Map> goodList = ydService.queryFormData_all(YDParam.builder()
                .formUuid("FORM-12EB6BCE3C264630824721E7BBABCC03L8U9")
                .searchFieldJson(JSON.toJSONString(UtilMap.map("textField_llkb7kd2", data.get("itemNumber"))))
                .build());
        Map goodMap = goodList.get(0);

        List<Map> djdList = ydService.queryFormData_all(YDParam.builder() // 定价单数据
                .formUuid("FORM-W2A66Z91B4KDWDIAA7SI1BRBRTKM3XL87BKLL0")
                .searchFieldJson(JSONObject.toJSONString(Arrays.asList(new YDSearch("textField_llzzbai8",supId,"供应商编号", YDSearch.Type.TEXT_FIELD,YDSearch.Operator.EQ))))//精准匹配
                .build());
        List<String> yclData=new ArrayList<>();
        djdList.forEach(dataItem -> {
            List<Map> mapList = (List<Map>) dataItem.get("tableField_llq74mwk");
            if(mapList.size()==50){
                mapList=ydService.queryDetails(YDParam.builder().formInstanceId(String.valueOf(dataItem.get("formInstanceId"))).formUuid("FORM-W2A66Z91B4KDWDIAA7SI1BRBRTKM3XL87BKLL0")
                        .tableFieldId("tableField_llq74mwk")
                        .build());
            }
            String projectId=UtilMap.getString(dataItem,"textField_lllovku7"); // 定价但中项目编号
            // 这里对比第二分类  selectField_llq74mwl ==> selectField_lv3v3911
            List<Map> maps =  mapList.stream().filter(items -> items.get("selectField_lv3v3911").equals(typeTwo)).collect(Collectors.toList());
            if(maps.size()>0){
                // 存在
                if(resultValue.containsKey(projectId)){
                    // 中间表存在数据，更新数据
                    Map record=dataList.get(resultValue.get(projectId));
                    yclData.add(String.valueOf(record.get("formInstanceId")));
//                    double rate = UtilMap.getDouble(record, "numberField_llkb7kcy");
//                    double rate2 = UtilMap.getDouble(record, "numberField_lpalgz04");
                    double rate = UtilMap.getDouble(maps.get(0), "numberField_llq74mwm");  //本周费率
                    double rate2 = UtilMap.getDouble(maps.get(0), "numberField_lpplr3im"); //下周费率
                    double price1 = UtilNumber.formatPrecisionValue(cost1 * (rate + 100) / 100f);
                    double price2 = UtilNumber.formatPrecisionValue(cost2 * (100 + rate2) / 100f);
                    String state= cost6.equals("已启用") && Long.parseLong(cost3) > UtilDateTime.getLocalDateTimeTimeStamp()?"已启用":"已停用";
                    Map update = UtilMap.map("numberField_llkknd6h, numberField_lpalgz0a, selectField_llkb7kd5, selectField_llkk6cms, numberField_llkb7kcy, numberField_lpalgz04", price1, price2, typeOne, typeTwo, rate, rate2);
                    update.putAll(UtilMap.map("numberField_llkknd6g, numberField_lpalgz05, dateField_lm4lxur7, numberField_lnrzzg03, textField_lnrzzg04, textField_lm4lxur8", cost1, cost2, cost3, cost4, cost5,state ));
                    update.put("textField_llkb7kd3",goodMap.get("textField_llkb7kd3"));  //单位
                    update.put("textField_llkb7kd4",goodMap.get("textField_llkb7kd4"));  //规格
                    ydClient.operateData(YDParam.builder()
                            .formInstanceId(String.valueOf(record.get("formInstanceId")))
                            .updateFormDataJson(JSON.toJSONString(update))
                            .build(), YDConf.FORM_OPERATION.update);
                }else{
                    Map hashMap = new HashMap();
                    hashMap.put("textField_llzzbyj1",supId);   //供应商编号
                    hashMap.put("textField_lmsli3bq",dataItem.get("textField_lmsli3bq")); //供应商名称
                    hashMap.put("textField_llm1vtjm",dataItem.get("textField_lllovku7"));  //项目编号
                    hashMap.put("textField_loy1ep8r",dataItem.get("textField_loy1ep8r"));//项目名称
                    hashMap.put("textField_llkb7kd2",data.get("itemNumber"));   //物品编号
                    hashMap.put("textField_llkb7kd1",goodMap.get("textField_llkb7kd1"));  //物品名称
                    hashMap.put("textField_llkb7kd3",goodMap.get("textField_llkb7kd3"));  //单位
                    hashMap.put("textField_llkb7kd4",goodMap.get("textField_llkb7kd4"));  //规格
                    hashMap.put("selectField_llkb7kd5",goodMap.get("selectField_llkb7kd5"));              //第一分类
                    hashMap.put("selectField_llkk6cms",goodMap.get("selectField_llkk6cms"));              //第二分类
                    double rate = UtilMap.getDouble(maps.get(0), "numberField_llq74mwm");  //本周费率
                    double rate2 = UtilMap.getDouble(maps.get(0), "numberField_lpplr3im"); //下周费率
                    double pce1 = UtilMap.getDouble(goodMap, "numberField_llkknd6g");  //成本单价
                    double pce2 = UtilMap.getDouble(goodMap, "numberField_lpalgz05");   //下周成本单价
                    double price1 = UtilNumber.formatPrecisionValue(pce1 * (rate + 100) / 100f);  //下周成本价
                    double price2 = UtilNumber.formatPrecisionValue(pce2 * (rate2 + 100 ) / 100f); //下周供货价
                    hashMap.put("numberField_llkb7kcy",rate);       //服务费率
                    hashMap.put("numberField_lpalgz04",rate2);   //下周服务费率
                    hashMap.put("numberField_llkknd6g",pce1);   //成本单价
                    hashMap.put("numberField_lpalgz05",pce2);   //下周成本单价
                    hashMap.put("numberField_llkknd6h",price1);  //供货价
                    hashMap.put("numberField_lpalgz0a",price2); //下周供货价
                    hashMap.put("dateField_lm4lxur7",goodMap.get("dateField_lm4lxur7"));  //期限
                    hashMap.put("textField_lm4lxur8","已启用");  //状态
                    hashMap.put("numberField_lnrzzg03",goodMap.get("numberField_lnrzzg03")); //包装数量
                    hashMap.put("textField_lnrzzg04",goodMap.get("textField_lnrzzg04")); //包装单位
                    log.info("hashMap,{}", JSON.toJSONString(hashMap));
                    try {
                        ydClient.operateData(YDParam.builder()
                                .formUuid("FORM-E6766M811CKD2PIXEAKOM9S2DKBM2PBQU1MLL5")
                                .formDataJson(JSON.toJSONString(hashMap))
                                .build(), YDConf.FORM_OPERATION.create);
                        Thread.sleep(200);
                    }catch (Exception e){
                        e.printStackTrace();
                    }
                }
            }else{
                // 不存在
//                if(resultValue.containsKey(projectId)){
//
//                }
            }
        });
        for (Map record : dataList) {
            if(yclData.contains(String.valueOf(record.get("formInstanceId")))){
                continue;
            }
            // 明细表存在数据，更新为 已停用
            Map update = UtilMap.map("textField_lm4lxur8", "已停用");
            ydClient.operateData(YDParam.builder()
                    .formInstanceId(String.valueOf(record.get("formInstanceId")))
                    .updateFormDataJson(JSON.toJSONString(update))
                    .build(), YDConf.FORM_OPERATION.update);
        }

//        for (Map record : dataList) {
////            if (cost1 == UtilMap.getDouble(record, "numberField_llkknd6g") && cost2 == UtilMap.getDouble(record, "numberField_lpalgz05")) {
////                continue;
////            }
//            double rate = UtilMap.getDouble(record, "numberField_llkb7kcy");
//            double rate2 = UtilMap.getDouble(record, "numberField_lpalgz04");
//            double price1 = UtilNumber.formatPrecisionValue(cost1 * (rate + 100) / 100f);
//            double price2 = UtilNumber.formatPrecisionValue(cost2 * (100 + rate2) / 100f);
//
//
//            String state= cost6.equals("已启用") && Long.parseLong(cost3) > UtilDateTime.getLocalDateTimeTimeStamp()?"已启用":"已停用";
//
//            Map update = UtilMap.map("numberField_llkknd6h, numberField_lpalgz0a", price1, price2);
//            update.putAll(UtilMap.map("numberField_llkknd6g, numberField_lpalgz05, dateField_lm4lxur7, numberField_lnrzzg03, textField_lnrzzg04, textField_lm4lxur8", cost1, cost2, cost3, cost4, cost5,state ));
//            ydClient.operateData(YDParam.builder()
//                    .formInstanceId(String.valueOf(record.get("formInstanceId")))
//                    .updateFormDataJson(JSON.toJSONString(update))
//                    .build(), YDConf.FORM_OPERATION.update);
//        }
    }

    /**
     * 供应商原材料档案: 新增匹配
     */
    @Override
    @Synchronized
    public void additionMaterial(Map data) {

        // 通过供应商编号 查询项目
        List<Map> dataList = ydService.queryFormData_all(YDParam.builder()
                .formUuid("FORM-W2A66Z91B4KDWDIAA7SI1BRBRTKM3XL87BKLL0")
                .searchFieldJson(JSON.toJSONString(UtilMap.map("textField_llzzbai8", data.get("gysNumber"))))
                .build());
        dataList.forEach(dataItem -> {
            List<Map> mapList = (List<Map>) dataItem.get("tableField_llq74mwk");
            if(mapList.size()==50){
                mapList=ydService.queryDetails(YDParam.builder().formInstanceId(String.valueOf(dataItem.get("formInstanceId"))).formUuid("FORM-W2A66Z91B4KDWDIAA7SI1BRBRTKM3XL87BKLL0")
                        .tableFieldId("tableField_llq74mwk")
                        .build());
            }

            // 这里对比第二分类  selectField_llq74mwl ==> selectField_lv3v3911
            List<Map> maps =  mapList.stream().filter(items -> items.get("selectField_lv3v3911").equals(data.get("firstName"))).collect(Collectors.toList());
            if(maps.size()>0){

                List<Map> goodList = ydService.queryFormData_all(YDParam.builder()
                        .formUuid("FORM-12EB6BCE3C264630824721E7BBABCC03L8U9")
                        .searchFieldJson(JSON.toJSONString(UtilMap.map("textField_llkb7kd2", data.get("goodNumber"))))
                        .build());
                Map goodMap = goodList.get(0);

                Map hashMap = new HashMap();
                hashMap.put("textField_llzzbyj1",data.get("gysNumber"));   //供应商编号
                hashMap.put("textField_lmsli3bq",dataItem.get("textField_lmsli3bq")); //供应商名称
                hashMap.put("textField_llm1vtjm",dataItem.get("textField_lllovku7"));  //项目编号
                hashMap.put("textField_loy1ep8r",dataItem.get("textField_loy1ep8r"));//项目名称
                hashMap.put("textField_llkb7kd2",data.get("goodNumber"));   //物品编号
                hashMap.put("textField_llkb7kd1",goodMap.get("textField_llkb7kd1"));  //物品名称

                hashMap.put("textField_llkb7kd3",goodMap.get("textField_llkb7kd3"));  //单位
                hashMap.put("textField_llkb7kd4",goodMap.get("textField_llkb7kd4"));  //规格
                hashMap.put("selectField_llkb7kd5",goodMap.get("selectField_llkb7kd5"));              //第一分类
                hashMap.put("selectField_llkk6cms",goodMap.get("selectField_llkk6cms"));              //第二分类


                double rate = UtilMap.getDouble(maps.get(0), "numberField_llq74mwm");  //本周费率
                double rate2 = UtilMap.getDouble(maps.get(0), "numberField_lpplr3im"); //下周费率

                double pce1 = UtilMap.getDouble(goodMap, "numberField_llkknd6g");  //成本单价
                double pce2 = UtilMap.getDouble(goodMap, "numberField_lpalgz05");   //下周成本单价

                double price1 = UtilNumber.formatPrecisionValue(pce1 * (rate + 100) / 100f);  //下周成本价
                double price2 = UtilNumber.formatPrecisionValue(pce2 * (rate2 + 100 ) / 100f); //下周供货价

                hashMap.put("numberField_llkb7kcy",rate);       //服务费率
                hashMap.put("numberField_lpalgz04",rate2);   //下周服务费率

                hashMap.put("numberField_llkknd6g",pce1);   //成本单价
                hashMap.put("numberField_lpalgz05",pce2);   //下周成本单价

                hashMap.put("numberField_llkknd6h",price1);  //供货价
                hashMap.put("numberField_lpalgz0a",price2); //下周供货价

                hashMap.put("dateField_lm4lxur7",goodMap.get("dateField_lm4lxur7"));  //期限
                hashMap.put("textField_lm4lxur8","已启用");  //状态
                hashMap.put("numberField_lnrzzg03",goodMap.get("numberField_lnrzzg03")); //包装数量
                hashMap.put("textField_lnrzzg04",goodMap.get("textField_lnrzzg04")); //包装单位


                log.info("hashMap,{}", JSON.toJSONString(hashMap));

                try {
                    ydClient.operateData(YDParam.builder()
                            .formUuid("FORM-E6766M811CKD2PIXEAKOM9S2DKBM2PBQU1MLL5")
                            .formDataJson(JSON.toJSONString(hashMap))
                            .build(), YDConf.FORM_OPERATION.create);
                    Thread.sleep(200);
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
        });




    }

    /**
     * 周日同步更新价格
     */
    @Override
    @SneakyThrows
    public void syncPrice() {
        // 项目表
        List<Map> djdList = ydService.queryFormData_all(YDParam.builder()
                .formUuid("FORM-MP966K81PGGD51ZUEU29Q6YVKSOE3SDK29KLL9")
                .build());
        for (Map djdInfo:djdList){
            log.info("同步定价单明细表，项目：{}",djdInfo.get("serialNumberField_llk93psu"));
            // 定价单明细表
            List<Map> dataList = ydService.queryFormData_all(YDParam.builder()
                    .formUuid("FORM-E6766M811CKD2PIXEAKOM9S2DKBM2PBQU1MLL5")
                    .searchFieldJson(JSON.toJSONString(UtilMap.map("textField_llm1vtjm", djdInfo.get("serialNumberField_llk93psu"))))
                    .build());
            int i=1;
            for (Map record : dataList) {
                log.info("{}项目进度：{}/{}",djdInfo.get("serialNumberField_llk93psu"),i,dataList.size());
                i++;
                double price1 = UtilMap.getDouble(record, "numberField_llkknd6h");
                double price2 = UtilMap.getDouble(record, "numberField_lpalgz0a");
                if (price1 == price2) {
                    continue;
                }
                log.info("有不同，");
                // 本质上是对比供货价差异, 下周全覆盖
                Map update = UtilMap.map("numberField_llkknd6h, numberField_llkb7kcy, numberField_llkknd6g", price2, record.get("numberField_lpalgz04"), record.get("numberField_lpalgz05"));
                ydClient.operateData(YDParam.builder()
                        .formInstanceId(String.valueOf(record.get("formInstanceId")))
                        .updateFormDataJson(JSON.toJSONString(update))
                        .build(), YDConf.FORM_OPERATION.update);
            }
        }

        // 供应商表
        List<Map> supList = ydService.queryFormData_all(YDParam.builder()
                .formUuid("FORM-L8966281A3LDP5UX77OYM6LBPEUM3TODBOLLL0")
                .build());
        for (Map supInfo:supList){
            log.info("同步供应商原材料表，项目：{}",supInfo.get("serialNumberField_lllodwgz"));
            // 供应商原材料表
            List<Map> dataList2 = ydService.queryFormData_all(YDParam.builder()
                    .formUuid("FORM-12EB6BCE3C264630824721E7BBABCC03L8U9")
                    .searchFieldJson(JSON.toJSONString(UtilMap.map("textField_llzzbyj1", supInfo.get("serialNumberField_lllodwgz"))))
                    .build());
            int i=0;
            for (Map record : dataList2) {
                log.info("{}项目进度：{}/{}",supInfo.get("serialNumberField_lllodwgz"),i,dataList2.size());
                i++;
                double cost1 = UtilMap.getDouble(record, "numberField_llkknd6g");
                double cost2 = UtilMap.getDouble(record, "numberField_lpalgz05");
                if (cost1 == cost2) {
                    continue;
                }
                Map update = UtilMap.map("numberField_llkknd6g", cost2);
                ydClient.operateData(YDParam.builder()
                        .formInstanceId(String.valueOf(record.get("formInstanceId")))
                        .updateFormDataJson(JSON.toJSONString(update))
                        .build(), YDConf.FORM_OPERATION.update);
            }
        }
    }

    @Override
    public List<Map<String, String>> getDiffMatchingSuppliers(String oldSupplierCode,String newSupplierCode) {
        List<Map<String,String>> diffList = new ArrayList<>();

        //获取旧供应商原材料信息
        List<Map> oldSupplierMaterials = getYdFormDataList(SUPPLIER_MATERIALS, JSON.toJSONString(UtilMap.map("textField_llzzbyj1", oldSupplierCode)), YDConf.FORM_QUERY.retrieve_list);
        List<Map<String,String>> oldSupplierMaterialsFormData = oldSupplierMaterials.stream()
                .map(item -> {
                    Map<String, String> map = new HashMap<>();
                    map.put("textField_lywr2qcq", String.valueOf(((Map) item.get("formData")).get("textField_llkb7kd1")));//物品名称
                    map.put("textField_lyxr5c44", String.valueOf(((Map) item.get("formData")).get("textField_llkb7kd2")));//物品编号
                    map.put("textField_lyxr5c46", String.valueOf(((Map) item.get("formData")).get("textField_llkb7kd4")));//物品规格
                    return map;
                }).collect(Collectors.toList());
        //按物品名称进行分组
        Map<String, List<Map<String, String>>> groupOldSupplierMaterials = oldSupplierMaterialsFormData.stream()
                .collect(Collectors.groupingBy(map -> map.get("textField_lywr2qcq")));
        //物品名称重复的物品
        List<String> oldRepeatNames = new ArrayList<>();
        //物品名称未重复的物品
        List<String> oldNames = new ArrayList<>();
        groupOldSupplierMaterials.forEach((name, value) -> {
            if (value.size() > 1) {
                diffList.addAll(value);
                oldRepeatNames.add(name);
            }else {
                oldNames.add(name);
            }
        });
        //待匹配的物品
        oldSupplierMaterialsFormData = oldSupplierMaterialsFormData.stream().filter(item -> !oldRepeatNames.contains(item.get("name"))).collect(Collectors.toList());


        //获取新供应商原材料信息
        List<Map> newSupplierMaterials = getYdFormDataList(SUPPLIER_MATERIALS, JSON.toJSONString(UtilMap.map("textField_llzzbyj1", newSupplierCode)), YDConf.FORM_QUERY.retrieve_list);
        List<Map<String,String>> newSupplierMaterialsFormData = newSupplierMaterials.stream()
                .map(item -> {
                    Map<String, String> map = new HashMap<>();
                    map.put("textField_lywr2qcq", String.valueOf(((Map) item.get("formData")).get("textField_llkb7kd1")));//物品名称
                    map.put("textField_lyxr5c44", String.valueOf(((Map) item.get("formData")).get("textField_llkb7kd2")));//物品编号
                    map.put("textField_lyxr5c46", String.valueOf(((Map) item.get("formData")).get("textField_llkb7kd4")));//物品规格
                    return map;
                }).collect(Collectors.toList());
        //按物品名称进行分组
        Map<String, List<Map<String, String>>> groupNewSupplierMaterials = newSupplierMaterialsFormData.stream()
                .collect(Collectors.groupingBy(map -> map.get("textField_lywr2qcq")));
        //物品名称重复的物品
        List<String> newRepeatNames = new ArrayList<>();
        //物品名称未重复的物品
        List<String> newNames = new ArrayList<>();
        groupNewSupplierMaterials.forEach((name, value) -> {
            if (value.size() > 1) {
//                diffList.addAll(value);
                newRepeatNames.add(name);
            }else {
                newNames.add(name);
            }
        });
        //待匹配的物品
//        newSupplierMaterialsFormData = newSupplierMaterialsFormData.stream().filter(item -> !newRepeatNames.contains(item.get("name"))).collect(Collectors.toList());
        List<String> matchNameList = new ArrayList<>();
        matchNameList.addAll(oldNames);
        matchNameList.retainAll(newNames);

        List<String> diffNameList = new ArrayList<>();
        diffNameList.addAll(oldNames);
        diffNameList.removeAll(newNames);

//        oldNames.removeAll(newNames);

        oldSupplierMaterialsFormData.forEach(item -> {
            if (diffNameList.contains(item.get("textField_lywr2qcq"))){
                diffList.add(item);
            }
        });


        return diffList;
    }

    @Override
    public List<Map<String, String>> getDiffMatchingSuppliers2(String projectCode,String oldSupplierCode, String newSupplierCode) {
        List<Map<String,String>> diffList = new ArrayList<>();

        //获取旧供应商定价单明细中间表
        List<Map> oldSupplierMaterials = getYdFormDataList(PRICE_DETAIL_MIDDLE, JSON.toJSONString(UtilMap.map("textField_llzzbyj1, textField_llm1vtjm", oldSupplierCode,projectCode)), YDConf.FORM_QUERY.retrieve_list);

        List<Map<String,String>> oldSupplierMaterialsFormData = oldSupplierMaterials.stream()
                .map(item -> {
                    Map<String, String> map = new HashMap<>();
                    map.put("textField_lywr2qcq", String.valueOf(((Map) item.get("formData")).get("textField_llkb7kd1")));//物品名称
                    map.put("textField_lyxr5c44", String.valueOf(((Map) item.get("formData")).get("textField_llkb7kd2")));//物品编号
                    map.put("textField_lyxr5c46", String.valueOf(((Map) item.get("formData")).get("textField_llkb7kd4")));//物品规格
                    return map;
                }).collect(Collectors.toList());
        //按物品名称进行分组
        Map<String, List<Map<String, String>>> groupOldSupplierMaterials = oldSupplierMaterialsFormData.stream()
                .collect(Collectors.groupingBy(map -> map.get("textField_lywr2qcq")));
        //物品名称重复的物品
        List<String> oldRepeatNames = new ArrayList<>();
        //物品名称未重复的物品
        List<String> oldNames = new ArrayList<>();
        groupOldSupplierMaterials.forEach((name, value) -> {
            if (value.size() > 1) {
                diffList.addAll(value);
                oldRepeatNames.add(name);
            }else {
                oldNames.add(name);
            }
        });
        //待匹配的物品
        oldSupplierMaterialsFormData = oldSupplierMaterialsFormData.stream().filter(item -> !oldRepeatNames.contains(item.get("name"))).collect(Collectors.toList());


        //获取新供应商原材料信息
        List<Map> newSupplierMaterials = getYdFormDataList(SUPPLIER_MATERIALS, JSON.toJSONString(UtilMap.map("textField_llzzbyj1", newSupplierCode)), YDConf.FORM_QUERY.retrieve_list);
        List<Map<String,String>> newSupplierMaterialsFormData = newSupplierMaterials.stream()
                .map(item -> {
                    Map<String, String> map = new HashMap<>();
                    map.put("textField_lywr2qcq", String.valueOf(((Map) item.get("formData")).get("textField_llkb7kd1")));//物品名称
                    map.put("textField_lyxr5c44", String.valueOf(((Map) item.get("formData")).get("textField_llkb7kd2")));//物品编号
                    map.put("textField_lyxr5c46", String.valueOf(((Map) item.get("formData")).get("textField_llkb7kd4")));//物品规格
                    return map;
                }).collect(Collectors.toList());
        //按物品名称进行分组
        Map<String, List<Map<String, String>>> groupNewSupplierMaterials = newSupplierMaterialsFormData.stream()
                .collect(Collectors.groupingBy(map -> map.get("textField_lywr2qcq")));
        //物品名称重复的物品
        List<String> newRepeatNames = new ArrayList<>();
        //物品名称未重复的物品
        List<String> newNames = new ArrayList<>();
        groupNewSupplierMaterials.forEach((name, value) -> {
            if (value.size() > 1) {
//                diffList.addAll(value);
                newRepeatNames.add(name);
            }else {
                newNames.add(name);
            }
        });
        //待匹配的物品
//        newSupplierMaterialsFormData = newSupplierMaterialsFormData.stream().filter(item -> !newRepeatNames.contains(item.get("name"))).collect(Collectors.toList());
        List<String> matchNameList = new ArrayList<>();
        matchNameList.addAll(oldNames);
        matchNameList.retainAll(newNames);

        List<String> diffNameList = new ArrayList<>();
        diffNameList.addAll(oldNames);
        diffNameList.removeAll(newNames);

//        oldNames.removeAll(newNames);

        oldSupplierMaterialsFormData.forEach(item -> {
            if (diffNameList.contains(item.get("textField_lywr2qcq"))){
                diffList.add(item);
            }
        });


        return diffList;
    }

    @Override
    public void purchaseConfirmation(String formInstId) {
        Map data=ydClient.queryData(YDParam.builder().formInstId(formInstId).build(), YDConf.FORM_QUERY.retrieve_id).getFormData();
        log.info("data：{}",JSONObject.toJSONString(data));
        List<Map> list=UtilMap.getList(data,"tableField_llq9pqlu");
        String totalAmt="0"; // 小计
        String totalAmt2="0";// 成本小计
        Map<String,Map> typeAmt=new HashMap<>();
        for (Map map:list){
            String amt=UtilMap.getString(map,"numberField_lrafqg9w_value");
            totalAmt=NumberUtil.add(amt,totalAmt).toString();
            String amt2=UtilMap.getString(map,"numberField_m2448gru_value");
            totalAmt2=NumberUtil.add(amt2,totalAmt2).toString();
            String type=UtilMap.getString(map,"selectField_llkb7kd5");
            Map typeAmtMap=typeAmt.containsKey(type)?typeAmt.get(type):new HashMap();
            typeAmtMap.put("textField_lrhhan54",type); // 第一分类
            typeAmtMap.put("numberField_lrhhan58",UtilMap.getString(map,"numberField_lmjzdeh2_value")); // 预算
            typeAmtMap.put("numberField_lrhhan59",NumberUtil.add(amt,UtilMap.getString(typeAmtMap,"numberField_lrhhan59")).toString());// 采购
            typeAmt.put(type,typeAmtMap);
        }
        List typeTable=new ArrayList();
        for (String str:typeAmt.keySet()){
            typeTable.add(typeAmt.get(str));
        }
        Map upmap=UtilMap.map("numberField_m2448grv, numberField_lrafqg9v, tableField_lrhhan53",totalAmt2, totalAmt,typeTable);
        log.info("upmap：{}",JSONObject.toJSONString(upmap));
        ydClient.operateData(YDParam.builder().formInstanceId(formInstId).updateFormDataJson(JSONObject.toJSONString(upmap)).build(), YDConf.FORM_OPERATION.update);
    }

    private List<Map> getYdFormDataList(String formUuid, String searchCondition, YDConf.FORM_QUERY formQuery) {
        List<Map> list = new ArrayList<>();
        DDR_New ddrNew;
        int pageNumber = 1;
        int pageSize = 100;
        do {
            ddrNew = ydClient.queryData(YDParam.builder().formUuid(formUuid)
                    .searchCondition(searchCondition)
                    .pageNumber(pageNumber)
                    .pageSize(pageSize).build(), formQuery);

            list.addAll((List<Map>) ddrNew.getData());
            pageNumber++;
        }while (ddrNew.getTotalCount() > ddrNew.getPageNumber() * pageSize);
        return list;
    }

    private List<Map> getYdInnerTableList(String formUuid,String formInstId,String tableFieldId) {
        List<Map> list = new ArrayList<>();
        DDR_New ddrNew;
        int pageNumber = 1;
        int pageSize = 50;
        do {
            ddrNew = ydClient.queryData(YDParam.builder()
                    .formUuid(formUuid)
                    .formInstanceId(formInstId)
                    .tableFieldId(tableFieldId)
                    .pageNumber(pageNumber)
                    .pageSize(pageSize).build(), YDConf.FORM_QUERY.retrieve_details);

            list.addAll((List<Map>) ddrNew.getData());
            pageNumber++;
        }while (ddrNew.getTotalCount() > ddrNew.getPageNumber() * pageSize);
        return list;
    }


    @Async
    @Override
    public void updateSuppliers(String formInstId) {
        //获取当前时间戳
        long beginTimestamp = System.currentTimeMillis();
        log.info("开始更新定价单供应商：{}",DateUtil.format(new Date(beginTimestamp), "yyyy-MM-dd HH:mm:ss"));

        //查询定价单供应商变更实例
        DDR_New ddrNew = ydClient.queryData(YDParam.builder()
                .formInstanceId(formInstId).build(), YDConf.FORM_QUERY.retrieve_id);
        String userId = ((Map) ddrNew.getOriginator()).get("userId").toString();
        Map formData = ddrNew.getFormData();

        String oldSupplierCode = String.valueOf(formData.get("textField_lv3w1k1l"));//旧供应商编号
        String newSupplierCode = String.valueOf(formData.get("textField_llzzbai8"));//新供应商编号
        String newSupplierName = String.valueOf(formData.get("textField_lmsli3bq"));//新供应商名称
        String jsonString = formData.get("associationFormField_llkb7kct_id").toString();
        String supplierJsonString = StringEscapeUtils.unescapeJava(jsonString.substring(1, jsonString.length() - 1));//新供应商（关联表单）
        List<Map> supplier =(List<Map>) JSONArray.parse(supplierJsonString);

        String jsonString2 = formData.get("associationFormField_llkb7kcs_id").toString();
        String orderJsonString = StringEscapeUtils.unescapeJava(jsonString2.substring(1, jsonString2.length() - 1));//定价单（关联表单）
        List<Map> order =(List<Map>) JSONArray.parse(orderJsonString);

        String projectCode = String.valueOf(formData.get("textField_lllovku7"));//定价单编号

        //新供应商未匹配原材料编号
//        List<String> newDiffSupplierMaterialCodes = new ArrayList<>();
        //新供应商匹配原材料编号
        List<String> newMatchSupplierMaterialCodes = new ArrayList<>();
        //新供应商匹配原材料名称
        List<String> newMatchSupplierMaterialNames = new ArrayList<>();

        //老供应商未匹配原材料编号
        List<String> oldNotMatchSupplierMaterialCodes = new ArrayList<>();
        //老供应商匹配原材料编号
        List<String> oldMatchSupplierMaterialCodes = new ArrayList<>();


        //校验新供应商原材料是否存在
        List<Map> newSupplierMaterials = getYdFormDataList(SUPPLIER_MATERIALS, JSON.toJSONString(UtilMap.map("textField_llzzbyj1", newSupplierCode)), YDConf.FORM_QUERY.retrieve_list);
        List<String> newSupplierMaterialCodes = newSupplierMaterials.stream()
                .map(item -> String.valueOf(((Map)item.get("formData")).get("textField_llkb7kd2")))
                .collect(Collectors.toList());

        //获取差异子表所有数据（可能超过50条）
        List<Map> diffList = getYdInnerTableList(SUPPLIER_CHANGE, formInstId, "tableField_lywr2qcp");


//        List<Map> diffList = (List<Map>) formData.get("tableField_lywr2qcp");

        for (Map diff : diffList) {
            String oldCode = String.valueOf(diff.get("textField_lyxr5c44"));//老供应商原材料编号
            String newCode = String.valueOf(diff.get("textField_lywr2qcv"));//新供应商原材料编号
            String newName = String.valueOf(diff.get("textField_lz70gmob"));//新供应商原材料名称
            //选择新供应商原材料且新供应商原材料编号存在
            if ((Objects.nonNull(diff.get("associationFormField_lywr2qcr_id")) && newSupplierMaterialCodes.contains(newCode))){
                oldMatchSupplierMaterialCodes.add(oldCode);
                newMatchSupplierMaterialCodes.add(newCode);
                newMatchSupplierMaterialNames.add(newName);
            }
            //未选择新供应商原材料
            if (Objects.isNull(diff.get("associationFormField_lywr2qcr_id"))){
                oldNotMatchSupplierMaterialCodes.add(oldCode);
//                newDiffSupplierMaterialCodes.add(newCode);
            }
        }

        //校验已选择的新供应商原材料编号是否重复
        HashSet<String> set = new HashSet<>(newMatchSupplierMaterialCodes);
        if (set.size() != newMatchSupplierMaterialCodes.size()){
            log.info("新供应商原材料编号存在重复！");
            return;
        }

        /*for (Map diff : diffList) {
            String oldCode = String.valueOf(diff.get("textField_lyxr5c44"));//老供应商原材料编号
            String newCode = String.valueOf(diff.get("textField_lywr2qcv"));//新供应商原材料编号

            if (!newMatchSupplierMaterialCodes.contains(newCode)){
                //查询旧供应商原材料信息
                List<Map> data = (List<Map>) ydClient.queryData(YDParam.builder()
                        .formUuid(SUPPLIER_MATERIALS)
                        .searchCondition(JSON.toJSONString(UtilMap.map("textField_llkb7kd2, textField_llzzbyj1", oldCode, oldSupplierCode)))
                        .build(), YDConf.FORM_QUERY.retrieve_list).getData();
                //复制旧供应商原材料信息到新供应商
                if (Objects.nonNull(data) && !data.isEmpty()){
                    Map diffFormData = (Map) data.get(0).get("formData");
                    diffFormData.put("associationFormField_lphya7cq",supplierJsonString);//供应商（关联表单）
                    diffFormData.put("textField_llzzbyj1", newSupplierCode);//供应商编号
                    diffFormData.put("textField_lmsli3bq", newSupplierName);//供应商名称
                    diffFormData.put("textField_llkb7kd2", newCode);//物品编号

                    ydClient.operateData(YDParam.builder().formUuid(SUPPLIER_MATERIALS)
                            .formDataJson(JSON.toJSONString(diffFormData)).build(), YDConf.FORM_OPERATION.create);
                }
            }
        }*/

        //未匹配上的原材料
//        List<String> notMatchCodes = new ArrayList<>();

        //获取旧供应商定价单明细中间表
        List<Map> oldSupplierMaterials = getYdFormDataList(PRICE_DETAIL_MIDDLE, JSON.toJSONString(UtilMap.map("textField_llzzbyj1, textField_llm1vtjm", oldSupplierCode,projectCode)), YDConf.FORM_QUERY.retrieve_list);
        //处理旧供应商定价单明细中间表
        handleOldSupplierPriceDetailMiddle(oldSupplierMaterials,newSupplierName,newSupplierCode,oldNotMatchSupplierMaterialCodes,oldMatchSupplierMaterialCodes,newMatchSupplierMaterialCodes,newMatchSupplierMaterialNames,newSupplierMaterials);

        //更新定价单
        String supplierInstanceId = supplier.get(0).get("instanceId").toString();
        Map supplierMap = ydClient.queryData(YDParam.builder()
                .formInstId(supplierInstanceId).build(), YDConf.FORM_QUERY.retrieve_id).getFormData();
        List<Map> employee = (List<Map>) supplierMap.get("employeeField_lllodwha_id");

        String orderInstanceId = order.get(0).get("instanceId").toString();
        Map updateFormData = new HashMap<>();
        updateFormData.put("associationFormField_llkb7kct",supplierJsonString);//供应商（关联表单）
        updateFormData.put("textField_llzzbai8", newSupplierCode);//供应商编号
        updateFormData.put("textField_lmsli3bq", newSupplierName);//供应商名称
        updateFormData.put("textField_lv3w1k1l", oldSupplierCode);//历史供应商编号
        updateFormData.put("employeeField_lmsli3br", employee);//供应商负责人

        ydClient.operateData(YDParam.builder()
                .formInstId(orderInstanceId)
                .updateFormDataJson(JSON.toJSONString(updateFormData))
                .build(), YDConf.FORM_OPERATION.update);

        //更新菜品
        List<Map> data = (List<Map>) ydClient.queryData(YDParam.builder()
                .formUuid(FOOD)
                .searchCondition(JSON.toJSONString(UtilMap.map("textField_lln3lmn1", projectCode)))
                .build(), YDConf.FORM_QUERY.retrieve_list_all).getData();
        for (Map datum : data) {
            //获取菜品管理信息
            Map foodFormData = (Map) datum.get("formData");
            List<Map> materialList = (List<Map>) foodFormData.get("tableField_llm1i9yy");
            List<String> errorCodes = new ArrayList<>();

//            Map foodFormData = ydClient.queryData(YDParam.builder().formInstanceId(formInstId).build(), YDConf.FORM_QUERY.retrieve_id).getFormData();
//            List<Map> materialList = (List<Map>) foodFormData.get("tableField_llm1i9yy");
            for (Map material : materialList) {
                String code = material.get("textField_lmk94yf5").toString();
                //如果明细被删除
                if (oldNotMatchSupplierMaterialCodes.contains(code)){
                    errorCodes.add(code);
                    continue;
                }
                String jsonString3 = material.get("associationFormField_lln3lmmv_id").toString();
                String materialJsonString = StringEscapeUtils.unescapeJava(jsonString3.substring(1, jsonString3.length() - 1));//新供应商原材料（关联表单）

                Map materialMap =(((List<Map>) JSONArray.parse(materialJsonString))).get(0);
                String instanceId = materialMap.get("instanceId").toString();

                //获取定价单明细中间表信息
                Map formData1 = ydClient.queryData(YDParam.builder().formInstanceId(instanceId).build(), YDConf.FORM_QUERY.retrieve_id).getFormData();

                materialMap.put("title",formData1.get("textField_llkb7kd1").toString());
                materialMap.put("subTitle",formData1.get("textField_lmkfg67e"));
                List<Map> list = new ArrayList<>();
                list.add(materialMap);
                material.put("associationFormField_lln3lmmv",list);//原材料（关联表单）
                material.put("textField_lln3lmn2",formData1.get("textField_llkb7kd3"));//单位
                material.put("textField_llyy3khw",formData1.get("textField_lmkfg67e"));//品牌
                material.put("textField_lz0ve9ct",formData1.get("textField_llkb7kd4"));//规格
                material.put("numberField_lnrzzg03",formData1.get("numberField_lnrzzg03"));//整包装数量
                material.put("textField_lnrzzg04",formData1.get("textField_lnrzzg04"));//整包装单位
                material.put("textField_llndm599",formData1.get("textField_llkb7kd1"));//原材料名称
                material.put("textField_lmk94yf5",formData1.get("textField_llkb7kd2"));//原材料编号
                material.put("selectField_lmqclyx9",formData1.get("selectField_llkb7kd5"));//第一分类
                material.put("numberField_lmqclyxa",formData1.get("numberField_llkknd6h"));//供货价
                material.put("numberField_lmsvffts",formData1.get("numberField_llkknd6g"));//成本单价
                material.put("numberField_lmsvfftt",formData1.get("numberField_llkb7kcy"));//服务费率
            }

            if (!errorCodes.isEmpty()){
                foodFormData.put("selectField_lzaq9r7i","异常");
                foodFormData.put("textField_lzaq9r7n",String.join(",",errorCodes));
            }

            foodFormData.put("tableField_llm1i9yy",materialList);

            ydClient.operateData(YDParam.builder()
                    .formInstanceId(formInstId)
                    .updateFormDataJson(JSON.toJSONString(foodFormData))
                    .build(), YDConf.FORM_OPERATION.update);

            /*for (Map material : materialList) {
                String code = material.get("textField_lmk94yf5").toString();//老供应商原材料编号
                if (changeCodeMap.containsKey(code)){
                    material.put("textField_lmk94yf5", changeCodeMap.get(code));//新供应商原材料编号
                }

            }

            foodFormData.put("tableField_llm1i9yy",materialList);
            ydClient.operateData(YDParam.builder()
                    .formInstanceId(datum.get("formInstanceId").toString())
                    .updateFormDataJson(JSON.toJSONString(foodFormData))
                    .build(),YDConf.FORM_OPERATION.update);*/
        }

        long endTimestamp = System.currentTimeMillis();
        log.info("更新供应商结束：{}",DateUtil.format(new Date(endTimestamp), "yyyy-MM-dd HH:mm:ss"));
        log.info("耗时：{}秒",(endTimestamp - beginTimestamp)/1000);
        //发送工作通知给发起人
        if (Objects.nonNull(userId)){
            Map param2 = new HashMap();
            param2.put("access_token",ddClient.getAccessToken("dingtydw7atg0yzh2trz","x47ctlj-H4frFAcJbWQ0jz8rBlvKp4BmSML3nXYgB99Br2MrVQsV6RGUxHBTN-m7"));
            Map body3 = new HashMap();
            body3.put("agent_id","3205833281");
            body3.put("userid_list",userId);
            Map msg = new HashMap();
            msg.put("msgtype","text");
            //获取当前时间 精确到秒
            String time = DateUtil.format(new Date(),"yyyy-MM-dd HH:mm:ss");
            msg.put("text",UtilMap.map("content","定价单供应商变更完成，时间：" + time + "，耗时：" + (endTimestamp - beginTimestamp)/1000 + "秒"));
            body3.put("msg",msg);
            String s = UtilHttp.doPost("https://oapi.dingtalk.com/topapi/message/corpconversation/asyncsend_v2", null, param2, body3);

            log.info("发送工作通知给发起人：{}",s);
        }
    }


    //处理旧供应商定价单中间表
    private void handleOldSupplierPriceDetailMiddle(List<Map> oldSupplierMaterials,String newSupplierName, String newSupplierCode,
                                            List<String> oldNotMatchSupplierMaterialCodes,List<String> oldMatchSupplierMaterialCodes,
                                            List<String> newMatchSupplierMaterialCodes,List<String> newMatchSupplierMaterialNames,
                                            List<Map> newSupplierMaterials) {

        int maxAttempts = 5; // 尝试的最大次数
        int attempt = 0;
        for (Map oldSupplierMaterial : oldSupplierMaterials) {
            boolean success = false;
            attempt = 0; // 重置当前迭代的尝试次数

            Map oldSupplierMaterialFormData = (Map) oldSupplierMaterial.get("formData");
            String code = String.valueOf(oldSupplierMaterialFormData.get("textField_llkb7kd2"));
            String name = String.valueOf(oldSupplierMaterialFormData.get("textField_llkb7kd1"));
            String formInstanceId = String.valueOf(oldSupplierMaterial.get("formInstanceId"));

            String newCode = "";

            //更新定价单明细中间表
            oldSupplierMaterialFormData.put("textField_lmsli3bq", newSupplierName);//供应商名称
            oldSupplierMaterialFormData.put("textField_llzzbyj1", newSupplierCode);//供应商编号

            while (!success && attempt < maxAttempts){
                try {
                    int index1 = oldNotMatchSupplierMaterialCodes.indexOf(code);
                    int index2 = oldMatchSupplierMaterialCodes.indexOf(code);

                    //未匹配上的原材料  将明细删除
                    if (index1 != -1){
                        /*ydClient.operateData(YDParam.builder().formUuid(PRICE_DETAIL_MIDDLE)
                        .formInstanceId(formInstanceId)
                        .updateFormDataJson(JSON.toJSONString(UtilMap.map("textField_lm4lxur8","已停用"))).build(), YDConf.FORM_OPERATION.update);*/
                        ydClient.operateData(YDParam.builder().formUuid(PRICE_DETAIL_MIDDLE)
                                .formInstanceId(formInstanceId)
                                .build(), YDConf.FORM_OPERATION.delete);
                    }else if (index2 != -1){
                        //手动匹配上的原材料
                        newCode = newMatchSupplierMaterialCodes.get(index2);
                        oldSupplierMaterialFormData.put("textField_llkb7kd2", newCode);//物品编号
                        oldSupplierMaterialFormData.put("textField_llkb7kd1",newMatchSupplierMaterialNames.get(index2));//物品名称
                        ydClient.operateData(YDParam.builder().formUuid(PRICE_DETAIL_MIDDLE)
                                .formInstanceId(formInstanceId)
                                .updateFormDataJson(JSON.toJSONString(oldSupplierMaterialFormData)).build(), YDConf.FORM_OPERATION.update);
                    }else {
                        //自动匹配上的原材料
                        for (Map newSupplierMaterial : newSupplierMaterials) {
                            Map newSupplierMaterialFormData = (Map) newSupplierMaterial.get("formData");
                            if (String.valueOf(newSupplierMaterialFormData.get("textField_llkb7kd1")).equals(name)){
                                newCode = newSupplierMaterialFormData.get("textField_llkb7kd2").toString();
                                oldSupplierMaterialFormData.put("textField_llkb7kd2", newCode);//物品编号
                                ydClient.operateData(YDParam.builder().formUuid(PRICE_DETAIL_MIDDLE)
                                        .formInstanceId(formInstanceId)
                                        .updateFormDataJson(JSON.toJSONString(oldSupplierMaterialFormData)).build(), YDConf.FORM_OPERATION.update);
                                break;
                            }
                        }
                    }
                    success = true;
                }catch (McException e){
                    if (e.getMessage().equals("The request has failed due to a temporary failure of the server.")){
                        attempt++;
                        // 线程睡眠3秒
                        try {
                            Thread.sleep(3000);
                        } catch (InterruptedException ie) {
                            Thread.currentThread().interrupt(); // 重新设置中断状态
                            System.err.println("Sleep interrupted: " + ie.getMessage());
                        }
                    }
                }catch (Exception e){
                    log.error("处理旧供应商定价单中间表失败,实例id:{},物料名称:{},物料编号:{},异常信息:{}", formInstanceId, name,code, e.getMessage());
                    success = true;
                }
            }
            if (!success) {
                // 如果达到最大尝试次数后仍未成功，可以选择退出循环或做其他处理
                log.info("处理旧供应商定价单中间表失败,实例id:{},物料名称:{},物料编号:{},尝试次数:{}", formInstanceId, name,code, attempt);
            }

        }
    }

}
