package com.malk.huagao.service.impl;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import com.google.gson.Gson;
import com.kingdee.bos.webapi.entity.IdentifyInfo;
import com.kingdee.bos.webapi.entity.RepoRet;
import com.kingdee.bos.webapi.sdk.K3CloudApi;
import com.malk.huagao.KdEntity.BillQuery;
import com.malk.huagao.KdEntity.View;
import com.malk.huagao.config.KDWebApiConf;
import com.malk.huagao.service.KdHuaGaoService;
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.dingtalk.DDClient;
import com.malk.utils.UtilHttp;
import com.malk.utils.UtilMap;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.util.Strings;
import org.slf4j.MDC;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.temporal.TemporalAdjusters;
import java.time.temporal.WeekFields;
import java.util.*;
import java.util.stream.Collectors;

import static org.junit.Assert.fail;

@Slf4j
@Service
public class KdHuaGaoServiceImpl implements KdHuaGaoService {
    @Autowired
    private KDWebApiConf kdWebApiConf;

    @Autowired
    private YDClient ydClient;

    @Autowired
    private DDClient ddClient;

    @Autowired
    private DDConf ddConf;

    //在库状态
    private static final Map<String,String> STOCK_STATUS = new HashMap<>();
    static{
        STOCK_STATUS.put("0","待入库");
        STOCK_STATUS.put("1","在库");
        STOCK_STATUS.put("2","待出库");
        STOCK_STATUS.put("3","出库");
        STOCK_STATUS.put("4","待售出");
        STOCK_STATUS.put("5","售出");
        STOCK_STATUS.put("6","待退料");
        STOCK_STATUS.put("7","退料");
    }

    @Override
    public void syncBDSerialMainFile(String userId) {
        MDC.put("MDC_KEY_PID","1002");

        //创建看板更新记录
        if (Strings.isBlank(userId)){
            userId = "yida_pub_account";
        }

        String formInstId = retryOperateData(YDParam.builder()
                .formUuid("FORM-0BEA655A36724D509A2CF21C4BA38D367YF7")
                .formDataJson(JSONObject.toJSONString(UtilMap.map("selectField_mfmhvkey, selectField_mhsjnn2r, dateField_mhsjnn2s, employeeField_mhswy0xy", "成品库存天数看板", "更新中", System.currentTimeMillis(),Arrays.asList(userId))))
                .build(), YDConf.FORM_OPERATION.create).toString();

        /*String formInstId = ydClient.operateData(YDParam.builder()
                .formUuid("FORM-0BEA655A36724D509A2CF21C4BA38D367YF7")
                .formDataJson(JSONObject.toJSONString(UtilMap.map("selectField_mfmhvkey, selectField_mhsjnn2r, dateField_mhsjnn2s, employeeField_mhswy0xy", "成品库存天数看板", "更新中", System.currentTimeMillis(),Arrays.asList(userId))))
                .build(), YDConf.FORM_OPERATION.create).toString();*/

        // 获取当前日期
        LocalDate today = LocalDate.now();

        int year = today.getYear();//获取当前年份
        int month = today.getMonthValue();//当前月份
        WeekFields weekFields = WeekFields.of(Locale.getDefault());
        int weekOfMonth = today.get(weekFields.weekOfMonth());//当前日期是当月的第几周

        /*int year = 2026;//获取当前年份
        int month = 1;//当前月份
        int weekOfMonth = 4;//当前日期是当月的第几周*/

        try {
            //删除宜搭当周序列号主档数据
            log.info("开始删除序列号主档数据：{}年,{}月,{}周",year,month,weekOfMonth);
            List<List<String>> formInstanceIdListList = new ArrayList<>();//实例id集合，每100条

            DDR_New ddrNew = new DDR_New();
            int pageSize = 50;
            int pageNumber = 0;
            do {
                pageNumber++;

                ddrNew = retryQueryData(YDParam.builder()
                        .formUuid("FORM-3B2E5C93D7E6494B9AD920B48A90159F7DZ4")
                        .searchFieldJson(JSONObject.toJSONString(UtilMap.map("numberField_mev270x6, numberField_mev270x5, textField_mev2ers5", Arrays.asList(year,year), Arrays.asList(month,month), weekOfMonth)))
                        .pageNumber(pageNumber)
                        .pageSize(pageSize)
                        .build(), YDConf.FORM_QUERY.retrieve_search_form_id);

                formInstanceIdListList.addAll(Collections.singleton((List<String>) ddrNew.getData()));

                Thread.sleep(1000);
            }while (ddrNew.getPageNumber() * pageSize < ddrNew.getTotalCount());

            for (List<String> formInstanceIdList : formInstanceIdListList) {
                if (!formInstanceIdList.isEmpty()){
                    retryOperateData(YDParam.builder()
                            .formUuid("FORM-3B2E5C93D7E6494B9AD920B48A90159F7DZ4")
                            .formInstanceIdList(formInstanceIdList)
                            .build(), YDConf.FORM_OPERATION.delete_batch);
                    /*ydClient.operateData(YDParam.builder()
                            .formUuid("FORM-3B2E5C93D7E6494B9AD920B48A90159F7DZ4")
                            .formInstanceIdList(formInstanceIdList)
                            .build(), YDConf.FORM_OPERATION.delete_batch);*/
                }
//                Thread.sleep(1000);
            }
            log.info("删除序列号主档数据完成：{}年,{}月,{}周",year,month,weekOfMonth);

            K3CloudApi client = new K3CloudApi(initIden());

            int startRow = 0;
            int limit = 2000;

            BillQuery billQuery = new BillQuery();

            billQuery.setLimit(limit);
            billQuery.setFormId("BD_SerialMainFile");
            billQuery.setFieldKeys("FNumber,FMaterialID.FNumber,FMaterialID.FName,FMaterialID.FSpecification,FMaterialID.F_QUXZ_Assistant,FZKTS,FStockStatus,FStockId.FName,FStockLocID.FF100001.FName,FCustId.FName");
            List<Map> filterString = new ArrayList<>();
            //仓库等于成品仓 仓位等于默认仓位或样机仓位 在库状态等于待入库或在库
            filterString.add(UtilMap.map("FieldName, Compare, Value, Left, Right, Logic","FStockId.FName","67","成品仓","","","0"));//仓库名称等于XX
            filterString.add(UtilMap.map("FieldName, Compare, Value, Left, Right, Logic","FStockLocId.FF100001.FName","67","默认仓位","(","","1"));//仓位等于XX
            filterString.add(UtilMap.map("FieldName, Compare, Value, Left, Right, Logic","FStockLocId.FF100001.FName","67","样机仓位","",")","0"));//仓位等于XX
            filterString.add(UtilMap.map("FieldName, Compare, Value, Left, Right, Logic","FStockStatus","29","0","(","","1"));//在库状态等于XX
            filterString.add(UtilMap.map("FieldName, Compare, Value, Left, Right, Logic","FStockStatus","29","1","",")","0"));//在库状态等于XX

            billQuery.setFilterString(filterString);

            List<Map> result = new ArrayList<>();
            List<Map> list = new ArrayList<>();

            do {
                billQuery.setStartRow(startRow);
                String s = client.billQuery(JSONObject.toJSONString(billQuery));
                result = (List<Map>)JSONObject.parse(s);
                list.addAll(result);

                startRow += limit;
            }while (result.size() == limit);

            List<Map> originList = new ArrayList<>();

            for (Map map : list) {
                Map formData = new HashMap();

                formData.put("textField_mev1n46z",UtilMap.getString(map,"FNumber"));//序列号
                formData.put("textField_mev1n470",UtilMap.getString(map,"FMaterialID.FNumber"));//物料编码
                formData.put("textField_mev1n471",UtilMap.getString(map,"FMaterialID.FName"));//物料名称
                formData.put("textField_mev1n472",UtilMap.getString(map,"FMaterialID.FSpecification"));//规格型号

                String ssxl = UtilMap.getString(map, "FMaterialID.F_QUXZ_Assistant");
                formData.put("textField_mev1n477", ssxl);//所属系列

                Double zkts = UtilMap.getDouble(map, "FZKTS");
                formData.put("numberField_mev1n478", zkts);//在库天数

                String stockStatus = STOCK_STATUS.get(UtilMap.getString(map, "FStockStatus"));
                formData.put("textField_mev1n476", stockStatus);//在库状态

                formData.put("textField_mev1n473",UtilMap.getString(map,"FStockId.FName"));//仓库

                String cw = UtilMap.getString(map, "FStockLocID.FF100001.FName");
                formData.put("textField_mev1n474", cw);//仓位

                formData.put("textField_mev1n475",UtilMap.getString(map,"FCustId.FName"));//客户

                //在库天数分类
                int zktsfl = 1;
                if ("待入库".equals(stockStatus)){
                    zktsfl = 1;
                }else {
                    if (zkts <= 30){
                        zktsfl = 2;
                    }else if (zkts <= 60){
                        zktsfl = 3;
                    }else if (zkts <= 90){
                        zktsfl = 4;
                    }else {
                        zktsfl = 5;
                    }
                }

                formData.put("selectField_mf205zr0",zktsfl);
                formData.put("numberField_mev270x6",year);
                formData.put("numberField_mev270x5",month);
                formData.put("textField_mev2ers5",weekOfMonth);

                formData.put("numberField_mfat6egj",1);//统计数值，默认1

                retryOperateData(YDParam.builder()
                        .formUuid("FORM-3B2E5C93D7E6494B9AD920B48A90159F7DZ4")
                        .formDataJson(JSONObject.toJSONString(formData))
                        .build(), YDConf.FORM_OPERATION.create);

                Map origin = new HashMap();
                origin.put("cw",cw);
                origin.put("ssxl",ssxl);
                origin.put("zktsfl",zktsfl);
                origin.put("value",1);

                originList.add(origin);
            }

            //删除宜搭历史最新库存信息
            List<Map> data = (List<Map>) retryQueryData(YDParam.builder()
                    .formUuid("FORM-4CB51E04B8344622BE880C9D573F68CANKWU")
                    .searchFieldJson(JSONObject.toJSONString(UtilMap.map("numberField_mev270x6, numberField_mev270x5",Arrays.asList(year,year), Arrays.asList(month,month))))
                    .build(), YDConf.FORM_QUERY.retrieve_list).getData();

            List<String> formInstanceIdList = new ArrayList<>();

            for (Map datum : data) {
                formInstanceIdList.add(UtilMap.getString(datum,"formInstanceId"));
            }

            if (!formInstanceIdList.isEmpty()){
                retryOperateData(YDParam.builder()
                        .formUuid("FORM-4CB51E04B8344622BE880C9D573F68CANKWU")
                        .formInstanceIdList(formInstanceIdList)
                        .build(), YDConf.FORM_OPERATION.delete_batch);
            }

            List<Map> data2 = (List<Map>) retryQueryData(YDParam.builder()
                    .formUuid("FORM-5764CC3F6D964FD3A165BD7D4D75999FO8NQ")
                    .searchFieldJson(JSONObject.toJSONString(UtilMap.map("numberField_mev270x6",Arrays.asList(year,year))))
                    .build(), YDConf.FORM_QUERY.retrieve_list).getData();

            List<String> formInstanceIdList2 = new ArrayList<>();

            for (Map datum : data2) {
                formInstanceIdList2.add(UtilMap.getString(datum,"formInstanceId"));
            }

            if (!formInstanceIdList2.isEmpty()){
                retryOperateData(YDParam.builder()
                        .formUuid("FORM-5764CC3F6D964FD3A165BD7D4D75999FO8NQ")
                        .formInstanceIdList(formInstanceIdList2)
                        .build(), YDConf.FORM_OPERATION.delete_batch);
            }

            //将最新库存信息写入宜搭
            List<Map> grouprList = originList.stream()
                    .collect(Collectors.groupingBy(
                            item -> Arrays.asList(
                                    item.get("cw"),
                                    item.get("ssxl"),
                                    item.get("zktsfl")
                            ),
                            Collectors.summingInt(item -> UtilMap.getInt(item, "value"))
                    )).entrySet()
                    .stream()
                    .map(entry -> {
                        // 将分组键（List<Object>）和汇总值转换为 Map
                        List<Object> key = entry.getKey();
                        Map<String, Object> groupedItem = new LinkedHashMap<>();
                        groupedItem.put("textField_mev1n474", key.get(0));
                        groupedItem.put("textField_mev1n477", key.get(1));
                        groupedItem.put("selectField_mf205zr0", key.get(2));
                        groupedItem.put("numberField_mev270x6", year);
                        groupedItem.put("numberField_mev270x5", month);
                        groupedItem.put("numberField_mfat6egj", entry.getValue());
                        return groupedItem;
                    }).collect(Collectors.toList());

            for (Map groupMap : grouprList) {
                retryOperateData(YDParam.builder()
                        .formUuid("FORM-4CB51E04B8344622BE880C9D573F68CANKWU")
                        .formDataJson(JSONObject.toJSONString(groupMap))
                        .build(), YDConf.FORM_OPERATION.create);

                retryOperateData(YDParam.builder()
                        .formUuid("FORM-5764CC3F6D964FD3A165BD7D4D75999FO8NQ")
                        .formDataJson(JSONObject.toJSONString(groupMap))
                        .build(), YDConf.FORM_OPERATION.create);
            }

            //更新看板更新记录
            retryOperateData(YDParam.builder()
                    .formInstId(formInstId)
                    .updateFormDataJson(JSONObject.toJSONString(UtilMap.map("selectField_mhsjnn2r, dateField_mhsjnn2t", "已完成", System.currentTimeMillis())))
                    .build(), YDConf.FORM_OPERATION.update);

        }catch (Exception e){
            //更新看板更新记录
            retryOperateData(YDParam.builder()
                    .formInstId(formInstId)
                    .updateFormDataJson(JSONObject.toJSONString(UtilMap.map("selectField_mhsjnn2r, dateField_mhsjnn2t, textareaField_mir0zmpo", "异常", System.currentTimeMillis(),e.getMessage())))
                    .build(), YDConf.FORM_OPERATION.update);

            throw new RuntimeException(e);
        }
    }

    @Override
    public void syncSTKInventory(String userId) {
        MDC.put("MDC_KEY_PID","1002");

        //创建看板更新记录
        if (Strings.isBlank(userId)){
            userId = "yida_pub_account";
        }

        String formInstId = ydClient.operateData(YDParam.builder()
                .formUuid("FORM-0BEA655A36724D509A2CF21C4BA38D367YF7")
                .formDataJson(JSONObject.toJSONString(UtilMap.map("selectField_mfmhvkey, selectField_mhsjnn2r, dateField_mhsjnn2s, employeeField_mhswy0xy", "成品/组件库存看板", "更新中", System.currentTimeMillis(),Arrays.asList(userId))))
                .build(), YDConf.FORM_OPERATION.create).toString();

        // 获取当前日期
        LocalDate today = LocalDate.now();
        int year = today.getYear();//获取当前年份
        int month = today.getMonthValue();//当前月份
        WeekFields weekFields = WeekFields.of(Locale.getDefault());
        int weekOfMonth = today.get(weekFields.weekOfMonth());//当前日期是当月的第几周

        try {
            //删除宜搭当周库存信息
            log.info("开始删除即时库存数据：{}年,{}月,{}周",year,month,weekOfMonth);
            List<List<String>> formInstanceIdListList = new ArrayList<>();//实例id集合，每100条

            DDR_New ddrNew = new DDR_New();
            int pageSize = 50;
            int pageNumber = 0;
            do {
                pageNumber++;

                ddrNew = ydClient.queryData(YDParam.builder()
                        .formUuid("FORM-06C833A3B1804929987033DD6B0E7B2F73JP")
                        .searchFieldJson(JSONObject.toJSONString(UtilMap.map("numberField_mev270x6, numberField_mev270x5, textField_mev2ers5", Arrays.asList(year,year), Arrays.asList(month,month), weekOfMonth)))
                        .pageNumber(pageNumber)
                        .pageSize(pageSize)
                        .build(), YDConf.FORM_QUERY.retrieve_search_form_id);

                formInstanceIdListList.addAll(Collections.singleton((List<String>) ddrNew.getData()));
            }while (ddrNew.getPageNumber() * pageSize < ddrNew.getTotalCount());

            for (List<String> formInstanceIdList : formInstanceIdListList) {
                if (!formInstanceIdList.isEmpty()){
                    ydClient.operateData(YDParam.builder()
                            .formUuid("FORM-06C833A3B1804929987033DD6B0E7B2F73JP")
                            .formInstanceIdList(formInstanceIdList)
                            .build(), YDConf.FORM_OPERATION.delete_batch);
                }
                Thread.sleep(1000);
            }
            log.info("删除即时库存数据完成：{}年,{}月,{}周",year,month,weekOfMonth);

            log.info("开始同步即时库存数据：{}年,{}月,{}周",year,month,weekOfMonth);

            K3CloudApi client = new K3CloudApi(initIden());

            int startRow = 0;
            int limit = 2000;

            BillQuery billQuery = new BillQuery();

            billQuery.setLimit(limit);
            billQuery.setFormId("STK_Inventory");
            billQuery.setFieldKeys("FMaterialID.FNumber,FMaterialID.FName,FMaterialID.FSpecification,FMaterialID.F_QUXZ_Assistant,FMaterialID.FSTOREURNOM,FMaterialID.FSTOREURNUM,FMaterialID.FZJ,FStockId,FStockId.FName,FLot,FLot.FName,FStockUnitId,FStockUnitId.FName,FBaseQty,FStockStatusId.FName");
            List<Map> filterString = new ArrayList<>();
            //仓库等于成品仓或组装半成品仓
            filterString.add(UtilMap.map("FieldName, Compare, Value, Left, Right, Logic","FStockName","338","成品仓,组装半成品仓","","","0"));//仓库名称 IN XX
            filterString.add(UtilMap.map("FieldName, Compare, Value, Left, Right, Logic","FBaseQty","21",0,"","","0"));//库存量(主单位) > 0

            billQuery.setFilterString(filterString);

            List<Map> result = new ArrayList<>();
            List<Map> list = new ArrayList<>();

            do {
                billQuery.setStartRow(startRow);
                String s = client.billQuery(JSONObject.toJSONString(billQuery));
                result = (List<Map>)JSONObject.parse(s);
                list.addAll(result);

                startRow += limit;
            }while (result.size() == limit);

            List<Map> originList = new ArrayList<>();

            for (Map map : list) {
                Map formData = new HashMap();

                String FMaterialNumber = UtilMap.getString(map,"FMaterialID.FNumber");//物料编码
                String FMaterialName = UtilMap.getString(map,"FMaterialID.FName");//物料名称
                String FMaterialSpecification = UtilMap.getString(map,"FMaterialID.FSpecification");//物料规格
                String FQUXZAssistant = Objects.nonNull(map.get("FMaterialID.F_QUXZ_Assistant")) ? UtilMap.getString(map,"FMaterialID.F_QUXZ_Assistant") : "--";//所属系列
                String Fzj = UtilMap.getString(map,"FMaterialID.FZJ");//组件
                String FStockName = UtilMap.getString(map,"FStockId.FName");//仓库名称
                String FLotName = UtilMap.getString(map,"FLot.FName");//批号
                String FStockUnitName = UtilMap.getString(map,"FStockUnitId.FName");//库存主单位
                Double FBaseQty = UtilMap.getDouble(map,"FBaseQty");//库存数量
                String FStockStatusName = UtilMap.getString(map,"FStockStatusId.FName");//库存状态

                Double FSTOREURNOM = UtilMap.getDouble(map, "FMaterialID.FSTOREURNOM");
                Double FSTOREURNUM = UtilMap.getDouble(map, "FMaterialID.FSTOREURNUM");

                if ("组装半成品仓".equals(FStockName)){
                    if (FMaterialName.contains("组件") && !FMaterialName.contains("面板") && !FMaterialName.contains("包装")){

                    }else {
                        continue;
                    }
                }

                Double FQty = FBaseQty * FSTOREURNOM / FSTOREURNUM;//库存量(主单位)

                formData.put("textField_mfarr0ei",FMaterialNumber);
                formData.put("textField_mfarr0en",FMaterialName);
                formData.put("textField_mfarr0eo",FMaterialSpecification);
                formData.put("textField_mflwgj61", FQUXZAssistant);
                formData.put("textField_mipr1qrc", Fzj);
                formData.put("textField_mfarr0et",FStockName);
                formData.put("textField_mfarr0eu",FLotName);
                formData.put("textField_mfarr0ev",FStockUnitName);
                formData.put("numberField_mfarr0f2",FQty);
                formData.put("textField_mfarr0f4",FStockStatusName);

                formData.put("numberField_mev270x6",year);
                formData.put("numberField_mev270x5",month);
                formData.put("textField_mev2ers5",weekOfMonth);

                ydClient.operateData(YDParam.builder()
                        .formUuid("FORM-06C833A3B1804929987033DD6B0E7B2F73JP")
                        .formDataJson(JSONObject.toJSONString(formData))
                        .build(), YDConf.FORM_OPERATION.create);

                Map origin = new HashMap();
                origin.put("ck",FStockName);
                origin.put("ssxl",FQUXZAssistant);
                origin.put("value",FQty);

                originList.add(origin);
            }

            log.info("同步即时库存数据结束：{}年,{}月,{}周",year,month,weekOfMonth);

            //删除宜搭历史最新库存信息
            List<Map> data = (List<Map>) ydClient.queryData(YDParam.builder()
                    .formUuid("FORM-35A70C47B4904437B05935AC0B23F981TR4B")
                    .searchFieldJson(JSONObject.toJSONString(UtilMap.map("numberField_mev270x6, numberField_mev270x5",Arrays.asList(year,year), Arrays.asList(month,month))))
                    .build(), YDConf.FORM_QUERY.retrieve_list).getData();

            List<String> formInstanceIdList = new ArrayList<>();

            for (Map datum : data) {
                formInstanceIdList.add(UtilMap.getString(datum,"formInstanceId"));
            }

            if (!formInstanceIdList.isEmpty()){
                ydClient.operateData(YDParam.builder()
                        .formUuid("FORM-35A70C47B4904437B05935AC0B23F981TR4B")
                        .formInstanceIdList(formInstanceIdList)
                        .build(), YDConf.FORM_OPERATION.delete_batch);
            }

            List<Map> data2 = (List<Map>) ydClient.queryData(YDParam.builder()
                    .formUuid("FORM-842BAB01084747E5B7E0811A16BE6AA56FUH")
                    .searchFieldJson(JSONObject.toJSONString(UtilMap.map("numberField_mev270x6",Arrays.asList(year,year))))
                    .build(), YDConf.FORM_QUERY.retrieve_list).getData();

            List<String> formInstanceIdList2 = new ArrayList<>();

            for (Map datum : data2) {
                formInstanceIdList2.add(UtilMap.getString(datum,"formInstanceId"));
            }

            if (!formInstanceIdList2.isEmpty()){
                ydClient.operateData(YDParam.builder()
                        .formUuid("FORM-842BAB01084747E5B7E0811A16BE6AA56FUH")
                        .formInstanceIdList(formInstanceIdList2)
                        .build(), YDConf.FORM_OPERATION.delete_batch);
            }

            //将最新库存信息写入宜搭
            List<Map> grouprList = originList.stream()
                    .collect(Collectors.groupingBy(
                            item -> Arrays.asList(
                                    item.get("ck"),
                                    item.get("ssxl")
                            ),
                            Collectors.summingDouble(item -> UtilMap.getDouble(item, "value"))
                    )).entrySet()
                    .stream()
                    .map(entry -> {
                        // 将分组键（List<Object>）和汇总值转换为 Map
                        List<Object> key = entry.getKey();
                        Map<String, Object> groupedItem = new LinkedHashMap<>();
                        groupedItem.put("textField_mfarr0et", key.get(0));
                        groupedItem.put("textField_mflwgj61", key.get(1));
                        groupedItem.put("numberField_mev270x6", year);
                        groupedItem.put("numberField_mev270x5", month);
                        groupedItem.put("numberField_mfarr0f2", entry.getValue());
                        return groupedItem;
                    }).collect(Collectors.toList());

            for (Map groupMap : grouprList) {
                ydClient.operateData(YDParam.builder()
                        .formUuid("FORM-35A70C47B4904437B05935AC0B23F981TR4B")
                        .formDataJson(JSONObject.toJSONString(groupMap))
                        .build(), YDConf.FORM_OPERATION.create);

                ydClient.operateData(YDParam.builder()
                        .formUuid("FORM-842BAB01084747E5B7E0811A16BE6AA56FUH")
                        .formDataJson(JSONObject.toJSONString(groupMap))
                        .build(), YDConf.FORM_OPERATION.create);
            }

            //更新看板更新记录
            ydClient.operateData(YDParam.builder()
                    .formInstId(formInstId)
                    .updateFormDataJson(JSONObject.toJSONString(UtilMap.map("selectField_mhsjnn2r, dateField_mhsjnn2t", "已完成", System.currentTimeMillis())))
                    .build(), YDConf.FORM_OPERATION.update);

        }catch (Exception e){
            //更新看板更新记录
            ydClient.operateData(YDParam.builder()
                    .formInstId(formInstId)
                    .updateFormDataJson(JSONObject.toJSONString(UtilMap.map("selectField_mhsjnn2r, dateField_mhsjnn2t, textareaField_mir0zmpo", "异常", System.currentTimeMillis(),e.getMessage())))
                    .build(), YDConf.FORM_OPERATION.update);

            throw new RuntimeException(e);
        }

    }

    //定时同步昨日到今天的
    @Override
    public void syncPRDReturnMtrl(String userId) {
        MDC.put("MDC_KEY_PID","1002");

        log.info("开始同步生产退料明细");

        //创建看板更新记录
        if (Strings.isBlank(userId)){
            userId = "yida_pub_account";
        }

        //创建看板更新记录
        String formInstId = ydClient.operateData(YDParam.builder()
                .formUuid("FORM-0BEA655A36724D509A2CF21C4BA38D367YF7")
                .formDataJson(JSONObject.toJSONString(UtilMap.map("selectField_mfmhvkey, selectField_mhsjnn2r, dateField_mhsjnn2s, employeeField_mhswy0xy", "不良物料退库统计看板", "更新中", System.currentTimeMillis(),Arrays.asList(userId))))
                .build(), YDConf.FORM_OPERATION.create).toString();

        try {
            K3CloudApi client = new K3CloudApi(initIden());

            int startRow = 0;
            int limit = 2000;

            BillQuery billQuery = new BillQuery();

            billQuery.setLimit(limit);
            billQuery.setFormId("PRD_ReturnMtrl");
            billQuery.setFieldKeys("FBillNo,FDate,FPPBOMEntryId,FMaterialId.FNumber,FMaterialId.FName,FMaterialId.FSpecification,FMaterialId.FDefaultVendor,FReturnType,FQty");
            List<Map> filterString = new ArrayList<>();
            //审核日期为昨日到现在且单据状态等于已审核
            filterString.add(UtilMap.map("FieldName, Compare, Value, Left, Right, Logic","FApproveDate","265",1,"","","0"));//审核日期在今天之前XX天之后
            filterString.add(UtilMap.map("FieldName, Compare, Value, Left, Right, Logic","FDocumentStatus","105","C","","","0"));//单据状态等于XX
//        filterString.add(UtilMap.map("FieldName, Compare, Value, Left, Right, Logic","FApproveDate","420","2025-01-01","","","0"));//审核日期等于XX年

            billQuery.setFilterString(filterString);

            List<Map> result = new ArrayList<>();
            List<Map> list = new ArrayList<>();

            do {
                billQuery.setStartRow(startRow);

                result = (List<Map>)JSONObject.parse(client.billQuery(JSONObject.toJSONString(billQuery)));

                list.addAll(result);

                startRow += limit;
            }while (result.size() == limit);

            for (Map map : list) {
                Map formData = new HashMap();
                String fBillNo = UtilMap.getString(map, "FBillNo");
                formData.put("textField_mfm7o4wb", fBillNo);//单据编号

                String fDate = UtilMap.getString(map, "FDate");
                // 解析字符串为 LocalDateTime
                LocalDateTime localDateTime = LocalDateTime.parse(fDate);
                // 将 LocalDateTime 转换为 ZonedDateTime
                ZonedDateTime zonedDateTime = localDateTime.atZone(ZoneId.systemDefault());
                formData.put("dateField_mfm7o4wc", zonedDateTime.toInstant().toEpochMilli());//单据日期

                String fppbomEntryId = UtilMap.getString(map, "FPPBOMEntryId");
                formData.put("textField_mfmaqppu", fppbomEntryId);//分录明细id
                formData.put("textField_mfm7o4we", UtilMap.getString(map,"FMaterialId.FNumber"));//物料编码

                formData.put("textField_mfm7o4wf", UtilMap.getString(map,"FMaterialId.FName"));//物料名称
                formData.put("textField_mfm7o4wg", UtilMap.getString(map,"FMaterialId.FSpecification"));//物料规格
                formData.put("textField_mfq6bwfl", UtilMap.getString(map,"FMaterialId.FDefaultVendor"));//默认供应商

                //退料类型
                String type = UtilMap.getString(map, "FReturnType");
                String typeValue = "";
                switch (type){
                    case "1": typeValue = "良品退料";break;
                    case "2": typeValue = "来料不良退料";break;
                    case "3": typeValue = "作业不良退料";break;
                    default:break;
                }
                formData.put("textField_mfm7o4wh", typeValue);

                formData.put("numberField_mfm7o4wj", UtilMap.getDouble(map,"FQty"));//退料数量

                ydClient.operateData(YDParam.builder()
                        .formUuid("FORM-D21383AF87AC48BEB577485C37F46E8FUAIK")
                        .searchCondition(JSONObject.toJSONString(UtilMap.map("textField_mfm7o4wb, textField_mfmaqppu, textField_mfm7o4wh",fBillNo,fppbomEntryId,typeValue)))
                        .formDataJson(JSONObject.toJSONString(formData))
                        .build(), YDConf.FORM_OPERATION.upsert);
            }

            //更新看板更新记录
            ydClient.operateData(YDParam.builder()
                    .formInstId(formInstId)
                    .updateFormDataJson(JSONObject.toJSONString(UtilMap.map("selectField_mhsjnn2r, dateField_mhsjnn2t", "已完成", System.currentTimeMillis())))
                    .build(), YDConf.FORM_OPERATION.update);

        }catch (Exception e){
            //更新看板更新记录
            ydClient.operateData(YDParam.builder()
                    .formInstId(formInstId)
                    .updateFormDataJson(JSONObject.toJSONString(UtilMap.map("selectField_mhsjnn2r, dateField_mhsjnn2t, textareaField_mir0zmpo", "异常", System.currentTimeMillis(),e.getMessage())))
                    .build(), YDConf.FORM_OPERATION.update);

            throw new RuntimeException(e);
        }
    }

    @Async
    @Override
    public void syncReport(String type,String userId) {
        MDC.put("MDC_KEY_PID","1002");

        try {
            switch (type){
                case "成品库存天数看板": syncBDSerialMainFile(userId);break;
                case "成品/组件库存看板": syncSTKInventory(userId);break;
                case "不良物料退库统计看板": syncPRDReturnMtrl(userId);break;
                case "成品/样机出库看板": syncDLVNotice(userId);break;
                default:break;
            }

            //发送工作通知
            if (Objects.nonNull(userId)){
                sendDdMsg(ddClient.getAccessToken(),ddConf.getAgentId(),userId,"更新" + type + "完成  时间：" + DateUtil.format(new Date(),"yyyy-MM-dd HH:mm:ss"));
            }

        }catch (Exception e){
            //发送工作通知
            if (Objects.nonNull(userId)){
                sendDdMsg(ddClient.getAccessToken(),ddConf.getAgentId(),userId,"更新" + type + "异常：" + e.getMessage() + "  时间：" + DateUtil.format(new Date(),"yyyy-MM-dd HH:mm:ss"));
            }
            throw new RuntimeException(e);
        }
    }

    @Override
    public void syncPendingProducts() {
        MDC.put("MDC_KEY_PID","1002");

        // 获取当前日期
        LocalDate today = LocalDate.now();
        int year = today.getYear();//获取当前年份
        int month = today.getMonthValue();//当前月份
        WeekFields weekFields = WeekFields.of(Locale.getDefault());
        int weekOfMonth = today.get(weekFields.weekOfMonth());//当前日期是当月的第几周

        /*int year = 2025;//获取当前年份
        int month = 12;//当前月份
        int weekOfMonth = 4;//当前日期是当月的第几周*/

        DDR_New ddrNew = new DDR_New();
        int pageSize = 100;
        int pageNumber = 0;

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

        do {
            pageNumber++;

            ddrNew = ydClient.queryData(YDParam.builder()
                    .formUuid("FORM-C4751EF730D74299A0449E40C2601AE5L2BU")
                    .searchCondition(JSONObject.toJSONString(UtilMap.map("numberField_mev270x6, numberField_mev270x5, textField_mev2ers5", Arrays.asList(year,year), Arrays.asList(month,month), weekOfMonth)))
                    .pageNumber(pageNumber)
                    .pageSize(pageSize)
                    .build(), YDConf.FORM_QUERY.retrieve_list);

            List<Map> data = (List<Map>) ddrNew.getData();

            for (Map datum : data) {
                list.add(UtilMap.getMap(datum,"formData"));
            }
        }while (ddrNew.getPageNumber() * pageSize < ddrNew.getTotalCount());

        //删除宜搭历史最新库存信息
        List<Map> data = (List<Map>) ydClient.queryData(YDParam.builder()
                .formUuid("FORM-BC40899D61134DDFB80E6C693E9EA930Y6NW")
                .searchFieldJson(JSONObject.toJSONString(UtilMap.map("numberField_mev270x6, numberField_mev270x5",Arrays.asList(year,year), Arrays.asList(month,month))))
                .build(), YDConf.FORM_QUERY.retrieve_list).getData();

        List<String> formInstanceIdList = new ArrayList<>();

        for (Map datum : data) {
            formInstanceIdList.add(UtilMap.getString(datum,"formInstanceId"));
        }

        if (!formInstanceIdList.isEmpty()){
            ydClient.operateData(YDParam.builder()
                    .formUuid("FORM-BC40899D61134DDFB80E6C693E9EA930Y6NW")
                    .formInstanceIdList(formInstanceIdList)
                    .build(), YDConf.FORM_OPERATION.delete_batch);
        }

        List<Map> data2 = (List<Map>) ydClient.queryData(YDParam.builder()
                .formUuid("FORM-28F9CA5CEBFA488A83B1A20721692B6CD3P8")
                .searchFieldJson(JSONObject.toJSONString(UtilMap.map("numberField_mev270x6",Arrays.asList(year,year))))
                .build(), YDConf.FORM_QUERY.retrieve_list).getData();

        List<String> formInstanceIdList2 = new ArrayList<>();

        for (Map datum : data2) {
            formInstanceIdList2.add(UtilMap.getString(datum,"formInstanceId"));
        }

        if (!formInstanceIdList2.isEmpty()){
            ydClient.operateData(YDParam.builder()
                    .formUuid("FORM-28F9CA5CEBFA488A83B1A20721692B6CD3P8")
                    .formInstanceIdList(formInstanceIdList2)
                    .build(), YDConf.FORM_OPERATION.delete_batch);
        }

        //将最新库存信息写入宜搭
        List<Map> grouprList = list.stream()
                .collect(Collectors.groupingBy(
                        item -> Arrays.asList(
                                item.get("textField_mfes8fg5")
                        ),
                        Collectors.summingDouble(item -> UtilMap.getDouble(item, "numberField_mfes8fg7"))
                )).entrySet()
                .stream()
                .map(entry -> {
                    // 将分组键（List<Object>）和汇总值转换为 Map
                    List<Object> key = entry.getKey();
                    Map<String, Object> groupedItem = new LinkedHashMap<>();
                    groupedItem.put("textField_mfes8fg5", key.get(0));
                    groupedItem.put("numberField_mev270x6", year);
                    groupedItem.put("numberField_mev270x5", month);
                    groupedItem.put("numberField_mfes8fg7", entry.getValue());
                    return groupedItem;
                }).collect(Collectors.toList());

        for (Map groupMap : grouprList) {
            ydClient.operateData(YDParam.builder()
                    .formUuid("FORM-BC40899D61134DDFB80E6C693E9EA930Y6NW")
                    .formDataJson(JSONObject.toJSONString(groupMap))
                    .build(), YDConf.FORM_OPERATION.create);

            ydClient.operateData(YDParam.builder()
                    .formUuid("FORM-28F9CA5CEBFA488A83B1A20721692B6CD3P8")
                    .formDataJson(JSONObject.toJSONString(groupMap))
                    .build(), YDConf.FORM_OPERATION.create);
        }

    }

    @Override
    public void syncDLVNotice(String userId) {
        MDC.put("MDC_KEY_PID","1002");

        log.info("开始同步发货通知单");

        //创建看板更新记录
        if (Strings.isBlank(userId)){
            userId = "yida_pub_account";
        }

        //创建看板更新记录
        String formInstId = ydClient.operateData(YDParam.builder()
                .formUuid("FORM-0BEA655A36724D509A2CF21C4BA38D367YF7")
                .formDataJson(JSONObject.toJSONString(UtilMap.map("selectField_mfmhvkey, selectField_mhsjnn2r, dateField_mhsjnn2s, employeeField_mhswy0xy", "成品/样机出库看板", "更新中", System.currentTimeMillis(),Arrays.asList(userId))))
                .build(), YDConf.FORM_OPERATION.create).toString();

        try {
            K3CloudApi client = new K3CloudApi(initIden());

            int startRow = 0;
            int limit = 2000;

            BillQuery billQuery = new BillQuery();

            billQuery.setLimit(limit);
            billQuery.setFormId("SAL_DELIVERYNOTICE");
            billQuery.setFieldKeys("FBillNo,FDate,FCustomerID.FName,F_QUXZ_Assistant.FNumber,FEntity_FEntryID,FMaterialId.FNumber,FMaterialId.FName,FMaterialId.FSpecification,FMaterialId.F_QUXZ_Assistant,FUnitID.FName,FQty,FIsFree,FHGZBDay.FNumber,FStockID.FName");
            List<Map> filterString = new ArrayList<>();
            //审核日期为昨日到现在且单据状态等于已审核且明细收件人电话不为空
            filterString.add(UtilMap.map("FieldName, Compare, Value, Left, Right, Logic","FApproveDate","265",1,"","","0"));//审核日期在今天之前XX天之后
            filterString.add(UtilMap.map("FieldName, Compare, Value, Left, Right, Logic","FDocumentStatus","105","C","","","0"));//单据状态等于XX
//        filterString.add(UtilMap.map("FieldName, Compare, Value, Left, Right, Logic","FHGReceiveDZ","52","","","","0"));//明细收件人地址不为空
            filterString.add(UtilMap.map("FieldName, Compare, Value, Left, Right, Logic","FHGReceiveDh","52","","","","0"));//明细收件人电话不为空
//        filterString.add(UtilMap.map("FieldName, Compare, Value, Left, Right, Logic","FApproveDate","420","2025-01-01","","","0"));//审核日期等于XX年
//        filterString.add(UtilMap.map("FieldName, Compare, Value, Left, Right, Logic","FApproveDate","63","","","","0"));//审核日期等于本月

            billQuery.setFilterString(filterString);

            List<Map> result = new ArrayList<>();
            List<Map> list = new ArrayList<>();

            do {
                billQuery.setStartRow(startRow);

                result = (List<Map>)JSONObject.parse(client.billQuery(JSONObject.toJSONString(billQuery)));

                list.addAll(result);

                startRow += limit;
            }while (result.size() == limit);

            for (Map map : list) {
                Map formData = new HashMap();
                String fBillNo = UtilMap.getString(map, "FBillNo");
                formData.put("textField_mfqf1fj5", fBillNo);//单据编号

                String fDate = UtilMap.getString(map, "FDate");
                // 解析字符串为 LocalDateTime
                LocalDateTime localDateTime = LocalDateTime.parse(fDate);
                // 将 LocalDateTime 转换为 ZonedDateTime
                ZonedDateTime zonedDateTime = localDateTime.atZone(ZoneId.systemDefault());

                //localDateTime是当月的第几周
                int week = localDateTime.get(WeekFields.ISO.weekOfWeekBasedYear());

                formData.put("dateField_mfqf1fj4", zonedDateTime.toInstant().toEpochMilli());//单据日期
                formData.put("textField_mfqf1fj6",UtilMap.getString(map,"FCustomerID.FName"));//客户名称

                String F_QUXZ_AssistantFNumber = UtilMap.getString(map, "F_QUXZ_Assistant.FNumber");
                String F_QUXZ_Assistant = "";
                switch (F_QUXZ_AssistantFNumber){
                    case "01": F_QUXZ_Assistant = "正常订单";break;
                    case "02": F_QUXZ_Assistant = "样机订单";break;
                    case "03": F_QUXZ_Assistant = "租赁订单";break;
                    case "04": F_QUXZ_Assistant = "维修订单";break;
                    case "05": F_QUXZ_Assistant = "研发订单";break;
                    case "06": F_QUXZ_Assistant = "服务订单";break;
                    case "10": F_QUXZ_Assistant = "营销支持";break;
                    case "JD": F_QUXZ_Assistant = "京东订单";break;
                    case "SHZY": F_QUXZ_Assistant = "售后专用";break;
                    case "TM": F_QUXZ_Assistant = "天猫订单";break;
                    default:break;
                }
                formData.put("textField_mfqhmwpu", F_QUXZ_Assistant);//销售类型

                String fEntityFEntryID = UtilMap.getString(map, "FEntity_FEntryID");
                formData.put("textField_mfqf1fjm", fEntityFEntryID);//销售订单分录id
                formData.put("textField_mfqf1fj7", UtilMap.getString(map,"FMaterialId.FNumber"));//物料编码
                formData.put("textField_mfqf1fj8", UtilMap.getString(map,"FMaterialId.FName"));//物料名称
                formData.put("textField_mfqf1fj9", UtilMap.getString(map,"FMaterialId.FSpecification"));//物料规格
                formData.put("textField_mfqf1fk3", UtilMap.getString(map,"FMaterialId.F_QUXZ_Assistant"));//所属系列
                formData.put("textField_mfqf1fjb", UtilMap.getString(map,"FUnitID.FName"));//销售单位
                formData.put("numberField_mfqf1fjd", UtilMap.getDouble(map,"FQty"));//销售数量
                formData.put("textField_mfqf1fjh", UtilMap.getBoolean(map,"FIsFree") ? "是" : "否");//是否赠品
                formData.put("textField_mfqf1fjj", UtilMap.getString(map,"FStockID.FName"));//出货仓库

                String FHGZBDayFNumber = UtilMap.getString(map, "FHGZBDay.FNumber");
                String FHGZBDay = "";
                switch (FHGZBDayFNumber){
                    case "01": FHGZBDay = "1年";break;
                    case "02": FHGZBDay = "2年";break;
                    case "03": FHGZBDay = "3年";break;
                    case "04": FHGZBDay = "4年";break;
                    case "05": FHGZBDay = "5年";break;
                    case "06": FHGZBDay = "15";break;
                    case "07": FHGZBDay = "27";break;
                    default:break;
                }
                formData.put("textField_mfqhmwpv", FHGZBDay);//质保期

                formData.put("textField_mfqithiv",getWeekOfMonth(localDateTime));//所属周

                ydClient.operateData(YDParam.builder()
                        .formUuid("FORM-F7DB6FC6E47949A98BDD3DC344B3CBC1V7HY")
                        .searchCondition(JSONObject.toJSONString(UtilMap.map("textField_mfqf1fj5, textField_mfqf1fjm",fBillNo,fEntityFEntryID)))
                        .formDataJson(JSONObject.toJSONString(formData))
                        .build(), YDConf.FORM_OPERATION.upsert);
            }

            //更新看板更新记录
            ydClient.operateData(YDParam.builder()
                    .formInstId(formInstId)
                    .updateFormDataJson(JSONObject.toJSONString(UtilMap.map("selectField_mhsjnn2r, dateField_mhsjnn2t", "已完成", System.currentTimeMillis())))
                    .build(), YDConf.FORM_OPERATION.update);
        }catch (Exception e){
            //更新看板更新记录
            ydClient.operateData(YDParam.builder()
                    .formInstId(formInstId)
                    .updateFormDataJson(JSONObject.toJSONString(UtilMap.map("selectField_mhsjnn2r, dateField_mhsjnn2t, textareaField_mir0zmpo", "异常", System.currentTimeMillis(),e.getMessage())))
                    .build(), YDConf.FORM_OPERATION.update);

            throw new RuntimeException(e);
        }
    }

    @Override
    public void syncPUROrder(String userId) {
        MDC.put("MDC_KEY_PID","1003");

        log.info("开始同步采购订单");

        try {
            K3CloudApi client = new K3CloudApi(initIden());

            int startRow = 0;
            int limit = 2000;

            BillQuery billQuery = new BillQuery();

            billQuery.setLimit(limit);
            billQuery.setFormId("PUR_PurchaseOrder");
            billQuery.setFieldKeys("FBillNo,FBillTypeID.FName,FBusinessType,FDate,FSupplierId.FName,FSupplierId.FADDRESS,FProviderContactId.FName,FProviderContactId.FPost,FProviderContactId.FMobile,FPurchaserId.FName,FPurchaseDeptId.FName,FHGDBLX.FDataValue,FACCTYPE,FHGDBLX1.FDataValue,FHGFkJhDate,FChangeReason,FMaterialId.FNumber,FMaterialId.FName,FMaterialId.FSpecification,FUnitId.FName,FQty,FPriceUnitId.FName,FPriceUnitQty,FDeliveryDate,FPrice,FTaxPrice,FEntryTaxRate,FEntryTaxAmount,FAllAmount,FEntryAmount,FEntryNote");
            List<Map> filterString = new ArrayList<>();
            //单据状态等于已审核且修改日期为昨天至今天
            filterString.add(UtilMap.map("FieldName, Compare, Value, Left, Right, Logic","FDocumentStatus","105","C","","","0"));//单据状态等于XX
            filterString.add(UtilMap.map("FieldName, Compare, Value, Left, Right, Logic","FModifyDate","265",1,"","","0"));//修改日期在今天之前XX天之后


            billQuery.setFilterString(filterString);

            List<Map> result = new ArrayList<>();
            List<Map> list = new ArrayList<>();

            do {
                billQuery.setStartRow(startRow);

                result = (List<Map>)JSONObject.parse(client.billQuery(JSONObject.toJSONString(billQuery)));

                list.addAll(result);

                startRow += limit;
            }while (result.size() == limit);

            System.out.println(list);

            List<Map<String,Object>> data = new ArrayList<>();

            for (Map map : list) {
                Map formData = new HashMap();

                String fBillNo = UtilMap.getString(map,"FBillNo");//单据编号
                String fBillType = UtilMap.getString(map,"FBillTypeID.FName");//单据类型
                String fBusinessType = UtilMap.getString(map, "FBusinessType");//业务类型
                String fBusinessTypeValue = "";
                switch (fBusinessType){
                    case "DRPCG": fBusinessTypeValue = "分销购销";break;
                    case "WW": fBusinessTypeValue = "标准委外";break;
                    case "FYCG": fBusinessTypeValue = "费用采购";break;
                    case "ZCCG": fBusinessTypeValue = "资产采购";break;
                    case "ZYCG": fBusinessTypeValue = "直运采购";break;
                    case "VMICG": fBusinessTypeValue = "VMI采购";break;
                    case "cscg": fBusinessTypeValue = "测试采购";break;
                    case "CG": fBusinessTypeValue = "标准采购";break;
                    default:break;
                }
                long fDate = convertKdDate(UtilMap.getString(map, "FDate"));//采购日期
                String fSupplier = UtilMap.getString(map, "FSupplierId.FName");//供应商
                String fSupplierAddress = UtilMap.getString(map, "FSupplierId.FADDRESS");//供应商地址
                String fProviderContact = UtilMap.getString(map, "FProviderContactId.FName");//供应商联系人
                String fProviderContactPost = UtilMap.getString(map, "FProviderContactId.FPost");//供应商联系人职务
                String fProviderContactMobile = UtilMap.getString(map, "FProviderContactId.FMobile");//供应商联系人电话
                String fPurchaser = UtilMap.getString(map, "FPurchaserId.FName");//采购员
                String fPurchaseDept = UtilMap.getString(map, "FPurchaseDeptId.FName");//采购部门
                String fHGDBLX = UtilMap.getString(map, "FHGDBLX.FDataValue");//订单类型
                String fACCTYPE = UtilMap.getString(map, "FACCTYPE");//验收方式
                String fACCTYPEValue = "";
                switch (fACCTYPE){
                    case "A": fACCTYPEValue = "金额验收";break;
                    case "Q": fACCTYPEValue = "数量验收";break;
                    case "R": fACCTYPEValue = "比例验收";break;
                }
                String fHGDBLX1 = UtilMap.getString(map, "FHGDBLX1.FDataValue");//采购类型


//                long fHGFkJhDate = convertKdDate(UtilMap.getString(map, "FHGFkJhDate"));//付款计划日期
                String fChangeReason = UtilMap.getString(map, "FChangeReason");//变更原因

                formData.put("textField_mizdd3p4",fBillNo);
                formData.put("textField_mizdd3p0",fBillType);
                formData.put("textField_mizdd3p3",fBusinessTypeValue);
                formData.put("textField_mizdd3p2",fPurchaser);
                formData.put("textField_mizdd3p5",fPurchaseDept);
                formData.put("dateField_mizdd3p6",fDate);
                formData.put("textField_mizdd3p7",fHGDBLX);
                formData.put("textField_mizdd3p8",fHGDBLX1);
                formData.put("textField_mizdd3p9",fACCTYPEValue);
                formData.put("dateField_mizdd3pa",Objects.nonNull(map.get("FHGFkJhDate")) ? convertKdDate(UtilMap.getString(map,"FHGFkJhDate")) : null);
                formData.put("textareaField_mizdd3pb",fChangeReason);
                formData.put("textField_mizdd3p1",fSupplier);
                formData.put("textField_mizdd3pg",fProviderContact);
                formData.put("textField_mizdd3pi",fProviderContactPost);
                formData.put("textField_mizdd3pk",fProviderContactMobile);
                formData.put("textField_mizdd3pm",fSupplierAddress);


                Map detail = new HashMap();
                detail.put("textField_mizdd3qg",UtilMap.getString(map,"FMaterialId.FNumber"));
                detail.put("textField_mizdd3qh",UtilMap.getString(map,"FMaterialId.FName"));
                detail.put("textField_mizdd3qi",UtilMap.getString(map,"FMaterialId.FSpecification"));
                detail.put("textField_mizdd3qj",UtilMap.getString(map,"FUnitId.FName"));
                detail.put("numberField_mizdd3ql",UtilMap.getDouble(map,"FQty"));
                detail.put("textField_mizdd3qk",UtilMap.getString(map,"FPriceUnitId.FName"));
                detail.put("numberField_mizdd3qn",UtilMap.getDouble(map,"FPriceUnitQty"));
                detail.put("dateField_mizdd3qp",Objects.nonNull(map.get("FDeliveryDate")) ? convertKdDate(UtilMap.getString(map,"FDeliveryDate")) : null);
                detail.put("numberField_mizdd3qr",UtilMap.getDouble(map,"FPrice"));
                detail.put("numberField_mizdd3qs",UtilMap.getDouble(map,"FTaxPrice"));
                detail.put("numberField_mizdd3qv",UtilMap.getDouble(map,"FEntryTaxRate"));
                detail.put("numberField_mizdd3qw",UtilMap.getDouble(map,"FEntryTaxAmount"));
                detail.put("numberField_mizdd3qx",UtilMap.getDouble(map,"FAllAmount"));
                detail.put("numberField_mizdd3qy",UtilMap.getDouble(map,"FEntryAmount"));
                detail.put("textField_mizdd3r0",UtilMap.getString(map,"FEntryNote"));

                List<Map> details = new ArrayList<>();
                details.add(detail);

                formData.put("tableField_mizdd3qf",details);


                data.add(formData);
            }

            List<Map<String, Object>> data2 = mergeListMap(data, "textField_mizdd3p4", "tableField_mizdd3qf");

            for (Map<String, Object> objectMap : data2) {
                String fbillNo = UtilMap.getString(objectMap, "textField_mizdd3p4");
                ydClient.operateData(YDParam.builder()
                        .formUuid("FORM-1F4DC1A20E86452699AEEC682CBBEB4CS9DF")
                        .formDataJson(JSONObject.toJSONString(objectMap))
                        .searchCondition(JSONObject.toJSONString(UtilMap.map("textField_mizdd3p4",fbillNo))).build(), YDConf.FORM_OPERATION.upsert);
            }


            //发送工作通知
            if (Objects.nonNull(userId)){
                sendDdMsg(ddClient.getAccessToken(),ddConf.getAgentId(),userId,"更新采购订单完成  时间：" + DateUtil.format(new Date(),"yyyy-MM-dd HH:mm:ss"));
            }

        }catch (Exception e){
            throw new RuntimeException(e);
        }
    }

    public static int getWeekOfMonth(LocalDateTime dateTime) {
        LocalDateTime date = dateTime.toLocalDate().atStartOfDay();

        // 获取当月第一天
        LocalDateTime firstDayOfMonth = date.with(TemporalAdjusters.firstDayOfMonth());

        // 获取当月第一天是星期几（1-7，周一到周日）
        int firstDayOfWeek = firstDayOfMonth.getDayOfWeek().getValue();

        // 计算当前日期是当月的第几天
        int dayOfMonth = date.getDayOfMonth();

        // 计算周数（ISO标准，周一为一周开始）
        // 第一周从1号开始，即使1号不是周一
        int week = ((dayOfMonth + firstDayOfWeek - 2) / 7) + 1;

        return week;
    }

    //发送工作通知
    public void sendDdMsg(String access_token,Number agent_id, String userid_list, String content){
        if (Objects.nonNull(userid_list)){
            Map param2 = new HashMap();
            param2.put("access_token",access_token);
            Map body3 = new HashMap();
            body3.put("agent_id",agent_id);
            body3.put("userid_list",userid_list);
            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, aa",content,""));
            body3.put("msg",msg);
            UtilHttp.doPost("https://oapi.dingtalk.com/topapi/message/corpconversation/asyncsend_v2",null,param2,body3);
        }
    }

    private IdentifyInfo initIden(){
        //注意 1：此处不再使用参数形式传入用户名及密码等敏感信息，改为在登录配置文件中设置。
        //注意 2：必须先配置第三方系统登录授权信息后，再进行业务操作，详情参考各语言版本SDK介绍中的登录配置文件说明。
        //读取配置，初始化SDK
        IdentifyInfo iden = new IdentifyInfo();
        iden.setUserName(kdWebApiConf.getXKDApiUserName());
        iden.setAppId(kdWebApiConf.getXKDApiAppID());
        iden.setdCID(kdWebApiConf.getXKDApiAcctID());
        iden.setAppSecret(kdWebApiConf.getXKDApiAppSec());
        iden.setServerUrl(kdWebApiConf.getXKDApiServerUrl());

        return iden;
    }

    private boolean isTrue(RepoRet repoRet){
        Gson gson = new Gson();

        if (repoRet.getResult().getResponseStatus().isIsSuccess()) {
            System.out.printf("接口返回结果: %s%n", gson.toJson(repoRet.getResult()));
            return true;
        } else {
            fail("接口返回结果: " + gson.toJson(repoRet.getResult().getResponseStatus()));
            return false;
        }
    }

    private String getMultiLanguageTextName(Object object){
        if (Objects.nonNull(object)){
            Map map = (Map) object;
            List<Map> multiLanguageText = (List<Map>) map.get("MultiLanguageText");
            String value = UtilMap.getString(multiLanguageText.get(0),"Name");

            return value;
        }
        return null;
    }

    private String getMultiLanguageTextSpecification(Object object){
        if (Objects.nonNull(object)){
            Map map = (Map) object;
            List<Map> multiLanguageText = (List<Map>) map.get("MultiLanguageText");
            String value = UtilMap.getString(multiLanguageText.get(0),"Specification");

            return value;
        }
        return null;
    }

    private String getNumber(Object object){
        if (Objects.nonNull(object)){
            Map map = (Map) object;

            String value = UtilMap.getString(map,"Number");

            return value;
        }
        return null;
    }

    public static List<Map<String, Object>> mergeListMap(List<Map<String, Object>> originalList,String key,String list) {
        // 使用 Map 来临时存储合并后的结果，key 为 code，value 为合并后的 Map
        Map<String, Map<String, Object>> mergedMap = new HashMap<>();

        for (Map<String, Object> item : originalList) {
            String code = (String) item.get(key);
            @SuppressWarnings("unchecked")
            List<Map<String, Object>> details = (List<Map<String, Object>>) item.get(list);

            if (mergedMap.containsKey(code)) {
                // 如果已存在该 code，只合并 details
                Map<String, Object> existingItem = mergedMap.get(code);
                @SuppressWarnings("unchecked")
                List<Map<String, Object>> existingDetails = (List<Map<String, Object>>) existingItem.get(list);
                existingDetails.addAll(details);
            } else {
                // 如果不存在该 key，保存整个 Map（包括其他 key）
                // 但需要深拷贝 list，避免后续修改影响原始数据
                Map<String, Object> newItem = new HashMap<>();
                for (Map.Entry<String, Object> entry : item.entrySet()) {
                    if ("details".equals(entry.getKey())) {
                        // 深拷贝 details 列表
                        @SuppressWarnings("unchecked")
                        List<Map<String, Object>> originalDetails = (List<Map<String, Object>>) entry.getValue();
                        newItem.put(entry.getKey(), new ArrayList<>(originalDetails));
                    } else {
                        newItem.put(entry.getKey(), entry.getValue());
                    }
                }
                mergedMap.put(code, newItem);
            }
        }

        // 转换回 List
        return new ArrayList<>(mergedMap.values());
    }

    private long convertKdDate(String fDate){
        // 解析字符串为 LocalDateTime
        LocalDateTime localDateTime = LocalDateTime.parse(fDate);
        // 将 LocalDateTime 转换为 ZonedDateTime
        ZonedDateTime zonedDateTime = localDateTime.atZone(ZoneId.systemDefault());
        long epochMilli = zonedDateTime.toInstant().toEpochMilli();

        return epochMilli;
    }

    //自带重试的operateData方法
    private Object retryOperateData(YDParam param, YDConf.FORM_OPERATION formOperation) {
        int maxAttempts = 3; // 尝试的最大次数
        int attempt = 0;

        Object result = null;

        while (attempt < maxAttempts) {
            try {
                result = ydClient.operateData(param, formOperation);

                return result;
            } catch (McException e) {
                log.info("错误信息：{}",e.getMessage());
                if (e.getMessage().equals("The request has failed due to a temporary failure of the server.")) {
                    attempt++;
                    // 线程睡眠3秒
                    try {
                        Thread.sleep(5000);
                        log.info("尝试第{}次,param:{},FORM_OPERATION:{},异常信息:{}", attempt, JSONObject.toJSONString(param), formOperation,e.getMessage());
                    } catch (InterruptedException ie) {
                        Thread.currentThread().interrupt(); // 重新设置中断状态
                        System.err.println("Sleep interrupted: " + ie.getMessage());
                    }
                }
            } catch (Exception e) {
                log.error("操作失败,param:{},FORM_OPERATION:{},异常信息:{}", JSONObject.toJSONString(param), formOperation,e.getMessage());

                throw new RuntimeException(e);
            }

        }

        throw new RuntimeException("超出最大重试次数,param:"+JSONObject.toJSONString(param)+",FORM_OPERATION:{}"+formOperation);
    }


    //自带重试的queryData方法
    private DDR_New retryQueryData(YDParam param, YDConf.FORM_QUERY formQuery) {
        int maxAttempts = 3; // 尝试的最大次数
        int attempt = 0;

        DDR_New result = null;

        while (attempt < maxAttempts) {
            try {
                result = ydClient.queryData(param, formQuery);

                return result;
            } catch (McException e) {
                log.info("错误信息：{}",e.getMessage());
                if (e.getMessage().equals("The request has failed due to a temporary failure of the server.")) {
                    attempt++;
                    // 线程睡眠3秒
                    try {
                        Thread.sleep(5000);
                        log.info("尝试第{}次,param:{},FORM_QUERY:{},异常信息:{}", attempt, JSONObject.toJSONString(param), formQuery,e.getMessage());
                    } catch (InterruptedException ie) {
                        Thread.currentThread().interrupt(); // 重新设置中断状态
                        System.err.println("Sleep interrupted: " + ie.getMessage());
                    }
                }
            } catch (Exception e) {
                log.error("操作失败,param:{},FORM_QUERY:{},异常信息:{}", JSONObject.toJSONString(param), formQuery,e.getMessage());

                throw new RuntimeException(e);
            }

        }

        throw new RuntimeException("超出最大重试次数,param:"+JSONObject.toJSONString(param)+",FORM_QUERY:{}"+formQuery);
    }
}
