package com.malk.aiwei.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.malk.aiwei.service.AWYDClient;
import com.malk.server.aliwork.YDConf;
import com.malk.server.aliwork.YDParam;
import com.malk.server.common.McException;
import com.malk.server.dingtalk.DDR_New;
import com.malk.service.aliwork.YDClient;
import com.malk.service.aliwork.YDService;
import com.malk.utils.UtilDateTime;
import com.malk.utils.UtilList;
import com.malk.utils.UtilMap;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

@Slf4j
@Service
public class AWYDImplClient implements AWYDClient {

    @Autowired
    private YDClient ydClient;

    @Autowired
    private YDService ydService;

    /// 产品需求
    String appType_pr = "APP_YQY0OH7953OKBTM57PLL";
    String systemToken_pr = "PGC66MB1H2RLXMFQ7XKW4BC3BDFJ2UDM909XL18";

    /**
     * 项目需求导入校验 [0910 更新版本]
     */
    @Override
    public Map checkImportData_projectRequirements(String charter, List<Map> dataList, boolean isSubmit) {

        /// fixme prd 0913 Charter子类不作为匹配条件, 可能存在跨情况. 引用\覆盖核心参数覆盖, 其余作为bom属性. 通过charter则全量载入
        boolean isSuccess = true;
        List<String> prList = new ArrayList<>();

        // 提交前再次校验，兼容手动新增情况【手动新增只能选择需求库】
        if (isSubmit) {
            for (Map row : dataList) {
                String code = UtilMap.getString(row, "textField_m0vvv72j");
                if (StringUtils.isNotBlank(code) && prList.contains(code)) {
                    row.put("selectField_m10k093c", "失败");
                    row.put("textareaField_m10k093a", code + "需求在当前列表已存在, 请检查数据后重新导入");
                    isSuccess = false;
                    continue;
                }
                prList.add(code);
            }
            return UtilMap.map("isSuccess, dataList", isSuccess, dataList);
        }

        // ppExt 可能存在同时新增一二三级需求, 按照层级导入, 已处理替换新增引用需求编号, 再恢复排序  [ prd 保留原导入排序 ]
        int index = 0;
        for (Map row : dataList) {
            row.put("order", index); // sort 内不仅仅循环
            index++;
        }
        dataList.sort(Comparator.comparingInt(item -> Integer.valueOf(UtilMap.getString(item, "selectField_lr4y2xcj").replace("级", ""))));

        // ‒ 关闭需求入库入口，仅需求编号、名称、描述、大类、子类不可修改，作为唯一条件，其他信息可维护
        Map condition = UtilMap.map("selectField_lronu2g3, selectField_lvy6fgqe, textField_lt2d2x7b, textareaField_lt2d2x7c", "需求大类不能为空", "需求子类不能为空", "需求名称不能为空", "需求描述不能为空");
        for (Map row : dataList) {
            // 清理导入状态标志
            row.put("selectField_m10k093c", "");
            row.put("textareaField_m10k093a", "");
            // 效验需求层级 & 父需求编号逻辑
            if (UtilMap.isBlankString(row, "selectField_lr4y2xcj")) {
                row.put("selectField_m10k093c", "失败");
                row.put("textareaField_m10k093a", "需求层级不能为空, 请检查数据后重新导入");
                isSuccess = false;
                continue;
            }
            // prd: 0914 需求层级关系不判断, 如1级需求是否有父编号, 3级需求是不是挂到了一级. 后续树形展开时兼容处理
            String level = UtilMap.getString(row, "selectField_lr4y2xcj");
            if (!"1级".equals(level)) {
                if (UtilMap.isBlankString(row, "textField_m0afm8pd")) {
                    row.put("selectField_m10k093c", "失败");
                    row.put("textareaField_m10k093a", level + "需求对应父需求编号不能为空, 请检查数据后重新导入");
                    isSuccess = false;
                    continue;
                }
                if (UtilMap.getString(row, "textField_m0vvv72j").equals(UtilMap.getString(row, "textField_m0afm8pd"))) {
                    row.put("selectField_m10k093c", "失败");
                    row.put("textareaField_m10k093a", level + "需求父编号引用了当前编号, 请检查数据后重新导入");
                    isSuccess = false;
                    continue;
                }
                // ppExt 当前导入列表必须存在对应的父需求编号, 且唯一性. [ fixme 已过滤掉引用自身情况, 且添加提交时校验需求编号不能重复, 9.19 按照层级导入, 无需记录原始编号, 已处理替换新增引用需求编号 ]
                List<Map> mList = dataList.stream().filter(item -> row.get("textField_m0afm8pd").equals(item.get("textField_m0vvv72j"))).collect(Collectors.toList());
                if (mList.size() != 1) {
                    String desc = mList.size() == 0 ? "未匹配到" : "不唯一";
                    row.put("selectField_m10k093c", "失败");
                    row.put("textareaField_m10k093a", level + "需求对应父需求编号" + desc + ", 请检查数据后重新导入");
                    isSuccess = false;
                    continue;
                }
            }
            // 根据需求编号判断需求名称与描述以及大类是否一致，如果是非一级需求需要增加校验父需求编号是否一致
            String code = UtilMap.getString(row, "textField_m0vvv72j");
            if (StringUtils.isNotBlank(code)) {

                // 重复需求编号校验
                if (prList.contains(code)) {
                    row.put("selectField_m10k093c", "失败");
                    row.put("textareaField_m10k093a", code + "需求在当前列表已存在, 请检查数据后重新导入");
                    isSuccess = false;
                    continue;
                }
                prList.add(code);

                List<Map> searchCondition = Arrays.asList(YDConf.searchCondition_TextFiled("serialNumberField_lr4xs4zi", code, "eq"));
                List<Map> tList = (List<Map>) ydClient.queryData(YDParam.builder()
                        .appType(appType_pr)
                        .systemToken(systemToken_pr)
                        .formUuid("FORM-7A52930D0E834522AD65A4CFE2C0818F1KQO")
                        .searchCondition(JSON.toJSONString(searchCondition))
                        .build(), YDConf.FORM_QUERY.retrieve_list).getData();
                if (tList.size() > 0) {
                    Map formData = UtilMap.getMap(tList.get(0), "formData");
                    // 校验父需求编号是否一致
                    if (!UtilMap.getString(formData, "textField_m0afm8pd").equals(UtilMap.getString(row, "textField_m0afm8pd"))) {
                        row.put("selectField_m10k093c", "失败");
                        row.put("textareaField_m10k093a", "父需求编号与求库内编号" + formData.get("textField_m0afm8pd") + "不一致, 请检查数据后重新导入");
                        isSuccess = false;
                        continue;
                    }
                    row.put("textField_m0vvv72j", formData.get("serialNumberField_lr4xs4zi")); // 赋值需求编号
                    // 匹配需求编号, 条件内数据以原始数据覆盖导入数据
                    for (Object key : condition.keySet()) {
                        row.put(key, UtilMap.getString(formData, String.valueOf(key)));
                    }
                    row.put("associationFormField_lvy7yjq8", YDConf.associationForm(appType_pr, "FORM-7A52930D0E834522AD65A4CFE2C0818F1KQO", UtilMap.getString(tList.get(0), "formInstanceId"), code, "", false));
                    row.put("selectField_m10k093c", "引用");
                    row.put("textareaField_m10k093a", "已匹配需求编号, 条件内数据以原始数据覆盖导入数据");
                    row.put("attachmentField_lticyied", UtilMap.getString(formData, "attachmentField_lticyied")); // 保留附件
                    continue;
                }
            }
            // 控制匹配条件 [ prd: 同时兼容, 有编号未匹配到数据, 通过填写内容识别 ppExt: 编号不清空, 可能存在同时新增一二三级需求 ]
            for (Object prop : condition.keySet()) {
                if (UtilMap.isBlankString(row, String.valueOf(prop))) {
                    row.put("selectField_m10k093c", "失败");
                    row.put("textareaField_m10k093a", condition.get(prop) + ", 请检查数据后重新导入");
                    break;
                }
            }
            if (UtilMap.isNotBlankString(row, "textareaField_m10k093a")) {
                isSuccess = false;
                continue;
            }
            // 若有，执行替换逻辑, 备注体现原始被替换编号
            List<Map> searchCondition = new ArrayList<>();
            for (Object key : condition.keySet()) {
                searchCondition.add(YDConf.searchCondition_TextFiled(String.valueOf(key), row.get(key), "eq"));
            }
            List<Map> tList = (List<Map>) ydClient.queryData(YDParam.builder()
                    .appType(appType_pr)
                    .systemToken(systemToken_pr)
                    .formUuid("FORM-7A52930D0E834522AD65A4CFE2C0818F1KQO")
                    .searchCondition(JSON.toJSONString(searchCondition))
                    .build(), YDConf.FORM_QUERY.retrieve_list).getData();
            if (tList.size() > 0) {
                Map formData = UtilMap.getMap(tList.get(0), "formData");
                String rCode = UtilMap.getString(formData, "serialNumberField_lr4xs4zi");
                // 替换新增引用需求编号
                dataList.stream().filter(item -> StringUtils.isNotBlank(code) &&
                        !"1级".equals(UtilMap.getString(item, "selectField_lr4y2xcj")) &&
                        row.get("textField_m0vvv72j").equals(item.get("textField_m0afm8pd"))).forEach(item -> item.put("textField_m0afm8pd", rCode));
                row.put("selectField_m10k093c", "替换");
                row.put("textareaField_m10k093a", code + "需求已替换, " + UtilMap.getString(formData, "serialNumberField_lr4xs4zi") + "需求库中相同条件需求");
                row.put("associationFormField_lvy7yjq8", YDConf.associationForm(appType_pr, "FORM-7A52930D0E834522AD65A4CFE2C0818F1KQO", UtilMap.getString(tList.get(0), "formInstanceId"), rCode, "", false));
                row.put("textField_m0afm8pd", UtilMap.getString(formData, "textField_m0afm8pd")); // 替换父需求编号
                row.put("attachmentField_lticyied", UtilMap.getString(formData, "attachmentField_lticyied")); // 保留附件
                row.put("textField_m0vvv72j", rCode);

            } else {
                row.put("selectField_m10k093c", "新增");
                row.put("textareaField_m10k093a", "需求编号不存在, 评审通过后需求库新增");
            }
        }
        dataList.sort(Comparator.comparingInt(item -> UtilMap.getInt(item, "order"))); // 恢复原排序
        return UtilMap.map("isSuccess, dataList", isSuccess, dataList);
    }

    /**
     * 项目需求审批通过后, 回写需求编号与关联表单, ppExt 并覆盖项目需求档案需求列表
     */
    @Override
    public void dealApprovedData_projectRequirements(String pCode, String instanceId, Map data) {

        // 项目需求数据
        DDR_New ddr_new = ydClient.queryData(YDParam.builder()
                .appType(appType_pr)
                .systemToken(systemToken_pr)
                .formInstanceId(instanceId)
                .build(), YDConf.FORM_QUERY.retrieve_id);
        Map formData = ddr_new.getFormData();

        List<Map> details = (List<Map>) formData.get("tableField_lt2d2x78");
        if (details.size() == YDConf.PAGE_SIZE_DETAILS) {
            details = ydService.queryDetails(YDParam.builder()
                    .appType(appType_pr)
                    .systemToken(systemToken_pr)
                    .formUuid("FORM-2326752634AA463EAA8AE81DD8E19E88AJ6K")
                    .formInstanceId(ddr_new.getFormInstId())
                    .tableFieldId("tableField_lt2d2x78")
                    .build());
        }
        // ppExt 编号不清空, 可能存在同时新增一二三级需求. 提取新增需求, 排序优先写入一级需求 [ prd 保留原导入排序 ]
        List<Map> ttList = new ArrayList<>();
        AtomicInteger index = new AtomicInteger();
        details = details.stream().filter((item) ->
        {
            item.put("sCode", UtilMap.getString(item, "textField_m0vvv72j"));
            item.put("order", index.intValue()); // 避免对象引用, 保留值
            index.getAndIncrement();
            boolean isCreate = "新增".equals(item.get("selectField_m10k093c"));
            if (UtilMap.isNotBlankString(item, "attachmentField_lticyied")) {
                item.put("attachmentField_lticyied", JSONObject.parse(UtilMap.getString(item, "attachmentField_lticyied")));
            }
            if (!isCreate) {
                item.put("associationFormField_lvy7yjq8", YDConf.associationForm(UtilMap.getString(item, "associationFormField_lvy7yjq8_id")));
                ttList.add(item);
            }
            return isCreate;
        }).collect(Collectors.toList());
        details.sort(Comparator.comparingInt(item -> Integer.valueOf(UtilMap.getString(item, "selectField_lr4y2xcj").replace("级", ""))));

        for (Map detail : details) {
            // 主表信息需完善
            detail.putAll(UtilMap.map("textField_lth2h04b, textField_lypq3ees, textField_lypq3eet", "charter, pdt, mpdt", data));
            detail.putAll(UtilMap.map("radioField_lroozhse, dateField_ly5ewjnf, employeeField_ly5ewjnc", "是", new Date().getTime(), Arrays.asList(data.get("userId"))));
            String formInstId = (String) ydClient.operateData(YDParam.builder()
                    .formUuid("FORM-7A52930D0E834522AD65A4CFE2C0818F1KQO")
                    .appType(appType_pr)
                    .systemToken(systemToken_pr)
                    .formDataJson(JSONObject.toJSONString(detail)) // 子表组件ID与档案一致
                    .build(), YDConf.FORM_OPERATION.create);
            // 查询新增数据后, 需求编号
            Map crData = ydClient.queryData(YDParam.builder()
                    .appType(appType_pr)
                    .systemToken(systemToken_pr)
                    .formInstanceId(formInstId)
                    .build(), YDConf.FORM_QUERY.retrieve_id).getFormData();
            String rCode = UtilMap.getString(crData, "serialNumberField_lr4xs4zi");
            // 若是引用, 导入已匹配父需求编号可过滤 [ 已按照层级导入, 更新当前父需求编号即可 ]
            if (!"1级".equals(UtilMap.getString(detail, "selectField_lr4y2xcj"))) {
                Optional optional = details.stream().filter(item -> item.get("sCode").equals(detail.get("textField_m0afm8pd"))).findAny();
                if (optional.isPresent()) {
                    detail.put("textField_m0afm8pd", ((Map) optional.get()).get("textField_m0vvv72j"));
                }
            }
            detail.put("associationFormField_lvy7yjq8", YDConf.associationForm(appType_pr, "FORM-7A52930D0E834522AD65A4CFE2C0818F1KQO", formInstId, rCode, "", false));
            detail.put("textField_m0vvv72j", rCode);
            detail.put("selectField_m10k093c", "已新增");  // 兼容重复调用
            ttList.add(detail);
        }
        ttList.sort(Comparator.comparingInt(item -> UtilMap.getInt(item, "order"))); // 恢复原排序

        ydClient.operateData(YDParam.builder()
                .appType(appType_pr)
                .systemToken(systemToken_pr)
                .formInstanceId(instanceId)
                .updateFormDataJson(JSONObject.toJSONString(UtilMap.map("tableField_lt2d2x78", ttList)))
                .build(), YDConf.FORM_OPERATION.update);

        // 覆盖项目需求档案需求列表 [最新版本]
        List<Map> searchCondition = Arrays.asList(YDConf.searchCondition_TextFiled("textField_lt6xd8lm", pCode, "eq"));
        List<Map> tList = (List<Map>) ydClient.queryData(YDParam.builder()
                .appType(appType_pr)
                .systemToken(systemToken_pr)
                .formUuid("FORM-480F7D71D1F44B9D92946BE95C1F2656JKAU")
                .searchCondition(JSON.toJSONString(searchCondition))
                .build(), YDConf.FORM_QUERY.retrieve_list).getData();
        if (tList.size() > 0) {
            ydClient.operateData(YDParam.builder()
                    .appType(appType_pr)
                    .systemToken(systemToken_pr)
                    .formInstanceId(UtilMap.getString(tList.get(0), "formInstanceId"))
                    .updateFormDataJson(JSONObject.toJSONString(UtilMap.map("tableField_lt2d2x78, radioField_m11lu528", ttList, "是")))
                    .build(), YDConf.FORM_OPERATION.update);
        }
    }

    /**
     * 覆盖项目需求档案需求列表 tmp
     */
    @Override
    @Deprecated
    public void archiveProjectRequirements(String pCode, String instanceId) {

        // 项目需求数据
        DDR_New ddr_new = ydClient.queryData(YDParam.builder()
                .appType(appType_pr)
                .systemToken(systemToken_pr)
                .formInstanceId(instanceId)
                .build(), YDConf.FORM_QUERY.retrieve_id);
        Map formData = ddr_new.getFormData();

        List<Map> details = (List<Map>) formData.get("tableField_lt2d2x78");
        if (details.size() == YDConf.PAGE_SIZE_DETAILS) {
            details = ydService.queryDetails(YDParam.builder()
                    .appType(appType_pr)
                    .systemToken(systemToken_pr)
                    .formUuid("FORM-2326752634AA463EAA8AE81DD8E19E88AJ6K")
                    .formInstanceId(ddr_new.getFormInstId())
                    .tableFieldId("tableField_lt2d2x78")
                    .build());
        }
        details = details.stream().map((item) ->
        {
            if (UtilMap.isNotBlankString(item, "attachmentField_lticyied")) {
                item.put("attachmentField_lticyied", JSONObject.parse(UtilMap.getString(item, "attachmentField_lticyied")));
            }
            item.put("associationFormField_lvy7yjq8", YDConf.associationForm(UtilMap.getString(item, "associationFormField_lvy7yjq8_id")));
            return item;
        }).collect(Collectors.toList());

        // 覆盖项目需求档案需求列表 [最新版本]
        List<Map> searchCondition = Arrays.asList(YDConf.searchCondition_TextFiled("textField_lt6xd8lm", pCode, "eq"));
        List<Map> tList = (List<Map>) ydClient.queryData(YDParam.builder()
                .appType(appType_pr)
                .systemToken(systemToken_pr)
                .formUuid("FORM-480F7D71D1F44B9D92946BE95C1F2656JKAU")
                .searchCondition(JSON.toJSONString(searchCondition))
                .build(), YDConf.FORM_QUERY.retrieve_list).getData();
        ydClient.operateData(YDParam.builder()
                .appType(appType_pr)
                .systemToken(systemToken_pr)
                .formInstanceId(UtilMap.getString(tList.get(0), "formInstanceId"))
                .updateFormDataJson(JSONObject.toJSONString(UtilMap.map("tableField_lt2d2x78, radioField_m11lu528", details, "是")))
                .build(), YDConf.FORM_OPERATION.update);
    }

    /// 产品规格
    String appType_ps = "APP_DINTFSNSIJPX533M3CQK";
    String systemToken_ps = "PTA66DA1S5QO5MDPBPN8V6CS4Q0O2LYISD91M024";

    /**
     * 项目规格导入校验 [0919 更新版本] fixme 复制\简化无层级项目需求实现逻辑
     */
    @Override
    public Map checkImportData_projectSpecification(String charter, List<Map> dataList, List<String> prList, boolean isSubmit) {

        boolean isSuccess = true;
        List<String> psList = new ArrayList<>();

        // ‒ 匹配条件，仅规格编号、分类、类型、子类、描述、条件不可修改，作为唯一条件，其他信息作为bom属性可维护
        Map condition = UtilMap.map("selectField_lti2e638, textField_lt2vdhtd, textField_lt2vdhte, textField_lt2vdhtf, textField_lt2vdhtg", "规格分类不能为空", "规格类型不能为空", "规格子类不能为空", "规格描述不能为空", "规格条件不能为空");
        for (Map row : dataList) {
            // 清理导入状态标志
            row.put("selectField_m10k093c", "");
            row.put("textareaField_m10k093a", "");

            // ppExt 需求库校验逻辑: 1. 需求编号不能为空且必须在需求列表中, 2.需求相关数据不修改, 只引用规格内容 [解决前端关联表单导出再导入后丢失问题]
            if (!prList.contains(UtilMap.getString(row, "textField_m0vvv72j"))) {
                row.put("selectField_m10k093c", "失败");
                row.put("textareaField_m10k093a", UtilMap.getString(row, "textField_m0vvv72j") + "需求在列表中不存在, 请检查数据后重新导入");
                isSuccess = false;
                continue;
            }
            // prd 10.17 [目前仅同步功能、性能需求] 测试规格调整，只校验功能、性能需求，也只是同步只写入规格库
            if (!Arrays.asList("功能需求（FUNC）", "性能需求（PFM）").contains(row.get("selectField_lronu2g3"))) {
                row.put("selectField_m10k093c", "成功");
                row.put("textareaField_m10k093a", "规格导入仅校验功能需求、性能需求强关联");
                continue;
            }

            String code = UtilMap.getString(row, "textField_m18x4yqo");
            if (StringUtils.isNotBlank(code)) {
                // 重复需求+规格编号校验
                String uCode = UtilMap.getString(row, "textField_m0vvv72j") + "_" + UtilMap.getString(row, "textField_m18x4yqo");
                if (psList.contains(uCode)) {
                    row.put("selectField_m10k093c", "失败");
                    row.put("textareaField_m10k093a", uCode + "需求+规格在当前列表已存在, 请检查数据后重新导入");
                    isSuccess = false;
                    continue;
                }
                psList.add(uCode);

                if (!isSubmit) {
                    List<Map> searchCondition = Arrays.asList(YDConf.searchCondition_TextFiled("serialNumberField_lti2e639", code, "eq"));
                    List<Map> tList = (List<Map>) ydClient.queryData(YDParam.builder()
                            .appType(appType_ps)
                            .systemToken(systemToken_ps)
                            .formUuid("FORM-F5FD52E311514AC890D4B308CFA8E8A8BH8J")
                            .searchCondition(JSON.toJSONString(searchCondition))
                            .build(), YDConf.FORM_QUERY.retrieve_list).getData();
                    if (tList.size() > 0) {
                        Map formData = UtilMap.getMap(tList.get(0), "formData");
                        row.put("textField_m18x4yqo", formData.get("serialNumberField_lti2e639")); // 赋值规格编号
                        // 匹配规格编号, 条件内数据以原始数据覆盖导入数据
                        for (Object key : condition.keySet()) {
                            row.put(key, UtilMap.getString(formData, String.valueOf(key)));
                        }
                        row.put("associationFormField_m18x4yqq", YDConf.associationForm(appType_ps, "FORM-F5FD52E311514AC890D4B308CFA8E8A8BH8J", UtilMap.getString(tList.get(0), "formInstanceId"), code, "", false));
                        row.put("selectField_m10k093c", "引用");
                        row.put("textareaField_m10k093a", "已匹配规格编号, 条件内数据以原始数据覆盖导入数据");
                        continue;
                    }
                }
            }
            // 控制匹配条件 [ prd: 同时兼容, 有编号未匹配到数据, 通过填写内容识别 ]
            for (Object prop : condition.keySet()) {
                if (UtilMap.isBlankString(row, String.valueOf(prop))) {
                    row.put("selectField_m10k093c", "失败");
                    row.put("textareaField_m10k093a", condition.get(prop) + ", 请检查数据后重新导入");
                    break;
                }
            }
            if (UtilMap.isNotBlankString(row, "textareaField_m10k093a")) {
                isSuccess = false;
                continue;
            }
            if (!isSubmit) {
                // 若有，执行替换逻辑, 备注体现原始被替换编号
                List<Map> searchCondition = new ArrayList<>();
                for (Object key : condition.keySet()) {
                    searchCondition.add(YDConf.searchCondition_TextFiled(String.valueOf(key), row.get(key), "eq"));
                }
                List<Map> tList = (List<Map>) ydClient.queryData(YDParam.builder()
                        .appType(appType_ps)
                        .systemToken(systemToken_ps)
                        .formUuid("FORM-F5FD52E311514AC890D4B308CFA8E8A8BH8J")
                        .searchCondition(JSON.toJSONString(searchCondition))
                        .build(), YDConf.FORM_QUERY.retrieve_list).getData();
                if (tList.size() > 0) {
                    Map formData = UtilMap.getMap(tList.get(0), "formData");
                    String rCode = UtilMap.getString(formData, "serialNumberField_lti2e639");
                    row.put("selectField_m10k093c", "替换");
                    row.put("textareaField_m10k093a", code + "规格已替换, " + UtilMap.getString(formData, "serialNumberField_lti2e639") + "规格库中相同条件规格");
                    row.put("associationFormField_m18x4yqq", YDConf.associationForm(appType_ps, "FORM-F5FD52E311514AC890D4B308CFA8E8A8BH8J", UtilMap.getString(tList.get(0), "formInstanceId"), rCode, "", false));
                    row.put("textField_m18x4yqo", rCode);
                } else {
                    row.put("selectField_m10k093c", "新增");
                    row.put("textareaField_m10k093a", "规格编号不存在, 评审通过后规格库新增");
                }
            }
        }
        return UtilMap.map("isSuccess, dataList", isSuccess, dataList);
    }

    /**
     * 项目规格审批通过后, 回写规格编号与关联表单
     */
    @Override
    public void dealApprovedData_projectSpecification(String instanceId, Map data) {
        // 项目需求数据
        DDR_New ddr_new = ydClient.queryData(YDParam.builder()
                .appType(appType_ps)
                .systemToken(systemToken_ps)
                .formInstanceId(instanceId)
                .build(), YDConf.FORM_QUERY.retrieve_id);
        Map formData = ddr_new.getFormData();
        List<Map> details = (List<Map>) formData.get("tableField_lt2d2x78");
        if (details.size() == YDConf.PAGE_SIZE_DETAILS) {
            details = ydService.queryDetails(YDParam.builder()
                    .appType(appType_ps)
                    .systemToken(systemToken_ps)
                    .formUuid("FORM-A1809FBB82E54CB387B372E3B15457E7IOVV")
                    .formInstanceId(ddr_new.getFormInstId())
                    .tableFieldId("tableField_lt2d2x78")
                    .build());
        }

        boolean isUpdate = false;
        for (Map detail : details) {
            if (UtilMap.isNotBlankString(detail, "attachmentField_lticyied")) {
                detail.put("attachmentField_lticyied", JSONObject.parse(UtilMap.getString(detail, "attachmentField_lticyied")));
            }
            detail.put("associationFormField_lvy7yjq8", YDConf.associationForm(UtilMap.getString(detail, "associationFormField_lvy7yjq8_id")));

            boolean isCreate = "新增".equals(detail.get("selectField_m10k093c"));
            // prd 10.17 规格仅校验功能、性能需求, 规格可能为空
            if (!isCreate && UtilMap.isNotBlankString(detail, "associationFormField_m18x4yqq_id")) {
                detail.put("associationFormField_m18x4yqq", YDConf.associationForm(UtilMap.getString(detail, "associationFormField_m18x4yqq_id")));
                continue;
            }
            // 主表信息需完善
            detail.putAll(UtilMap.map("selectField_lwq7bv4z, selectField_lwq7bv51", "charter, pdt", data));
            detail.put("radioField_lti2e636", "是");
            String formInstId = (String) ydClient.operateData(YDParam.builder()
                    .formUuid("FORM-F5FD52E311514AC890D4B308CFA8E8A8BH8J")
                    .appType(appType_ps)
                    .systemToken(systemToken_ps)
                    .formDataJson(JSONObject.toJSONString(detail)) // 子表组件ID与档案一致
                    .build(), YDConf.FORM_OPERATION.create);
            // 查询新增数据后, 规格编号
            Map crData = ydClient.queryData(YDParam.builder()
                    .appType(appType_ps)
                    .systemToken(systemToken_ps)
                    .formInstanceId(formInstId)
                    .build(), YDConf.FORM_QUERY.retrieve_id).getFormData();
            String rCode = UtilMap.getString(crData, "serialNumberField_lti2e639");
            detail.put("associationFormField_m18x4yqq", YDConf.associationForm(appType_ps, "FORM-F5FD52E311514AC890D4B308CFA8E8A8BH8J", formInstId, rCode, "", false));
            detail.put("textField_m18x4yqo", rCode);
            detail.put("selectField_m10k093c", "已新增");  // 兼容重复调用
            isUpdate = true;
        }
        if (isUpdate) {
            ydClient.operateData(YDParam.builder()
                    .appType(appType_ps)
                    .systemToken(systemToken_ps)
                    .formInstanceId(instanceId)
                    .updateFormDataJson(JSONObject.toJSONString(UtilMap.map("tableField_lt2d2x78", details)))
                    .build(), YDConf.FORM_OPERATION.update);
        }
    }


    /// 产品规格
    String appType_ts = "APP_LBOBROO4GOXH63MIROTP";
    String systemToken_ts = "GNC66E911CRLB46HBG0AWCC3ZUWZ1QDYP2AXLPF";

    /**
     * 测试规格导入校验 [10.15 更新版本] fixme 复制\简化无层级项目需求实现逻辑
     */
    @Override
    public Map checkImportData_testSpecification(String charter, List<Map> dataList, List<String> prList, boolean isSubmit) {

        boolean isSuccess = true;
        List<String> psList = new ArrayList<>();

        // ‒ 匹配条件，仅规格编号、分类、类型、子类、描述、条件不可修改，作为唯一条件，其他信息作为bom属性可维护
        Map condition = UtilMap.map("textField_m2b2mkvb, textField_m2b2mkvc, textField_m2b2mkvd", "测试类型", "验收项", "测试条件");
        for (Map row : dataList) {
            // 清理导入状态标志
            row.put("selectField_m10k093c", "");
            row.put("textareaField_m10k093a", "");

            // ppExt 测试规格库校验逻辑: 1. 需求+规格编号不能为空且必须在需求列表中, 2.需求\规格相关数据不修改, 只引用测试规格内容 [解决前端关联表单导出再导入后丢失问题]
            String prsCode = UtilMap.getString(row, "textField_m0vvv72j") + "_" + UtilMap.getString(row, "textField_m18x4yqo");
            if (!prList.contains(prsCode)) {
                row.put("selectField_m10k093c", "失败");
                row.put("textareaField_m10k093a", prsCode + "需求+规格在列表中不存在, 请检查数据后重新导入");
                isSuccess = false;
                continue;
            }
            String code = UtilMap.getString(row, "textField_m2b2vx5x");
            if (StringUtils.isNotBlank(code)) {
                // 重复需求+规格编号+测试规格校验
                String uCode = UtilMap.getString(row, "textField_m0vvv72j") + "_" + UtilMap.getString(row, "textField_m18x4yqo") + "_" + UtilMap.getString(row, "textField_m2b2vx5x");
                if (psList.contains(uCode)) {
                    row.put("selectField_m10k093c", "失败");
                    row.put("textareaField_m10k093a", uCode + "需求+规格+测试规格在当前列表已存在, 请检查数据后重新导入");
                    isSuccess = false;
                    continue;
                }
                psList.add(uCode);

                if (!isSubmit) {
                    List<Map> searchCondition = Arrays.asList(YDConf.searchCondition_TextFiled("serialNumberField_m2b2mkva", code, "eq"));
                    List<Map> tList = (List<Map>) ydClient.queryData(YDParam.builder()
                            .appType(appType_ts)
                            .systemToken(systemToken_ts)
                            .formUuid("FORM-767ECC0F8CCE4FB0BC48ECC63164F297BS77")
                            .searchCondition(JSON.toJSONString(searchCondition))
                            .build(), YDConf.FORM_QUERY.retrieve_list).getData();
                    if (tList.size() > 0) {
                        Map formData = UtilMap.getMap(tList.get(0), "formData");
                        row.put("textField_m2b2vx5x", formData.get("serialNumberField_m2b2mkva")); // 赋值规格编号
                        // 匹配规格编号, 条件内数据以原始数据覆盖导入数据
                        for (Object key : condition.keySet()) {
                            row.put(key, UtilMap.getString(formData, String.valueOf(key)));
                        }
                        row.put("associationFormField_lt6zl2fh", YDConf.associationForm(appType_ts, "FORM-767ECC0F8CCE4FB0BC48ECC63164F297BS77", UtilMap.getString(tList.get(0), "formInstanceId"), code, "", false));
                        row.put("selectField_m10k093c", "引用");
                        row.put("textareaField_m10k093a", "已匹配规格编号, 条件内数据以原始数据覆盖导入数据");
                        continue;
                    }
                }
            }
            // 控制匹配条件 [ prd: 同时兼容, 有编号未匹配到数据, 通过填写内容识别 ]
            for (Object prop : condition.keySet()) {
                if (UtilMap.isBlankString(row, String.valueOf(prop))) {
                    // prd 11.01 测试规格调整，全部字段不做校验, 功能、性能需求也会存在空情况
                    row.put("selectField_m10k093c", "成功");
                    row.put("textareaField_m10k093a", "测试规格导入全部字段不做校验, 功能、性能需求也会存在空情况");
                    break;
                }
            }
            if (!isSubmit) {
                // 若有，执行替换逻辑, 备注体现原始被替换编号
                List<Map> searchCondition = new ArrayList<>();
                for (Object key : condition.keySet()) {
                    searchCondition.add(YDConf.searchCondition_TextFiled(String.valueOf(key), row.get(key), "eq"));
                }
                List<Map> tList = (List<Map>) ydClient.queryData(YDParam.builder()
                        .appType(appType_ts)
                        .systemToken(systemToken_ts)
                        .formUuid("FORM-767ECC0F8CCE4FB0BC48ECC63164F297BS77")
                        .searchCondition(JSON.toJSONString(searchCondition))
                        .build(), YDConf.FORM_QUERY.retrieve_list).getData();
                if (tList.size() > 0) {
                    Map formData = UtilMap.getMap(tList.get(0), "formData");
                    String rCode = UtilMap.getString(formData, "serialNumberField_m2b2mkva");
                    row.put("selectField_m10k093c", "替换");
                    row.put("textareaField_m10k093a", code + "规格已替换, " + UtilMap.getString(formData, "serialNumberField_m2b2mkva") + "规格库中相同条件规格");
                    row.put("associationFormField_lt6zl2fh", YDConf.associationForm(appType_ts, "FORM-767ECC0F8CCE4FB0BC48ECC63164F297BS77", UtilMap.getString(tList.get(0), "formInstanceId"), rCode, "", false));
                    row.put("textField_m18x4yqo", rCode);
                } else {
                    row.put("selectField_m10k093c", "新增");
                    row.put("textareaField_m10k093a", "测试规格编号不存在, 评审通过后测试规格库新增");
                }
            }
        }
        return UtilMap.map("isSuccess, dataList", isSuccess, dataList);
    }

    /**
     * 测试规格审批通过后, 回写规格编号与关联表单
     */
    @Override
    public void dealApprovedData_testSpecification(String instanceId, Map data) {
        // 项目需求数据
        DDR_New ddr_new = ydClient.queryData(YDParam.builder()
                .appType(appType_ts)
                .systemToken(systemToken_ts)
                .formInstanceId(instanceId)
                .build(), YDConf.FORM_QUERY.retrieve_id);
        Map formData = ddr_new.getFormData();
        List<Map> details = (List<Map>) formData.get("tableField_lt2d2x78");
        if (details.size() == YDConf.PAGE_SIZE_DETAILS) {
            details = ydService.queryDetails(YDParam.builder()
                    .appType(appType_ts)
                    .systemToken(systemToken_ts)
                    .formUuid("FORM-A0AC3FDEF14B43D8A117A4077128AFB6EX2S")
                    .formInstanceId(ddr_new.getFormInstId())
                    .tableFieldId("tableField_lt2d2x78")
                    .build());
        }

        boolean isUpdate = false;
        for (Map detail : details) {
            // 需求库\规格库
            detail.put("associationFormField_lvy7yjq8", YDConf.associationForm(UtilMap.getString(detail, "associationFormField_lvy7yjq8_id")));
            // prd 10.17 规格仅校验功能、性能需求, 规格可能为空
            if (UtilMap.isNotBlankString(detail, "associationFormField_m18x4yqq_id")) {
                detail.put("associationFormField_m18x4yqq", YDConf.associationForm(UtilMap.getString(detail, "associationFormField_m18x4yqq_id")));
            }
            boolean isCreate = "新增".equals(detail.get("selectField_m10k093c"));
            if (!isCreate && UtilMap.isNotBlankString(detail, "associationFormField_lt6zl2fh_id")) {
                detail.put("associationFormField_lt6zl2fh", YDConf.associationForm(UtilMap.getString(detail, "associationFormField_lt6zl2fh_id")));
                continue;
            }
            // 主表信息需完善
            detail.putAll(UtilMap.map("selectField_lwq7bv4z, selectField_lwq7bv51", "charter, pdt", data));
            detail.put("radioField_lti2e636", "是");
            String formInstId = (String) ydClient.operateData(YDParam.builder()
                    .formUuid("FORM-767ECC0F8CCE4FB0BC48ECC63164F297BS77")
                    .appType(appType_ts)
                    .systemToken(systemToken_ts)
                    .formDataJson(JSONObject.toJSONString(detail)) // 子表组件ID与档案一致
                    .build(), YDConf.FORM_OPERATION.create);
            // 查询新增数据后, 规格编号
            Map crData = ydClient.queryData(YDParam.builder()
                    .appType(appType_ts)
                    .systemToken(systemToken_ts)
                    .formInstanceId(formInstId)
                    .build(), YDConf.FORM_QUERY.retrieve_id).getFormData();
            String rCode = UtilMap.getString(crData, "serialNumberField_m2b2mkva");
            detail.put("associationFormField_lt6zl2fh", YDConf.associationForm(appType_ts, "FORM-767ECC0F8CCE4FB0BC48ECC63164F297BS77", formInstId, rCode, "", false));
            detail.put("textField_m2b2vx5x", rCode);
            detail.put("selectField_m10k093c", "已新增");  // 兼容重复调用
            isUpdate = true;
        }
        if (isUpdate) {
            ydClient.operateData(YDParam.builder()
                    .appType(appType_ts)
                    .systemToken(systemToken_ts)
                    .formInstanceId(instanceId)
                    .updateFormDataJson(JSONObject.toJSONString(UtilMap.map("tableField_lt2d2x78", details)))
                    .build(), YDConf.FORM_OPERATION.update);
        }
    }

    /**
     * 提供verifier数据读取服务
     */
    @Override
    public Map syncVerifier(String projectCode, String productCode, String productVersion) {

        // 查询最新审批通过项目,规格列表
        List<Map> dataList = (List<Map>) ydClient.queryData(YDParam.builder()
                .appType(appType_ps)
                .systemToken(systemToken_ps)
                .formUuid("FORM-A1809FBB82E54CB387B372E3B15457E7IOVV")
                .searchCondition(JSON.toJSONString(UtilMap.map("textField_lt6xd8lm", projectCode)))
                .approvedResult("agree")
                .build(), YDConf.FORM_QUERY.retrieve_search_process).getData();
        dataList = dataList.stream().filter(item -> projectCode.equals(UtilMap.getMap(item, "data").get("textField_lt6xd8lm"))).collect(Collectors.toList());
        McException.assertAccessException(dataList.isEmpty(), "项目规格评审通过信息为空");
        // 按照修改时间排序, 通过修改日期排序审批通过日期
        dataList.sort(Comparator.comparingLong(item -> UtilDateTime.parse(UtilMap.getString(item, "modifiedTimeGMT"), "yyyy-MM-dd'T'HH:mm").getTime()));

        Map formData = UtilMap.getMap((Map) UtilList.getLast(dataList), "data");
        List<Map> details = (List<Map>) formData.get("tableField_lt2d2x78");
        details = details.stream().filter(item -> {
            // prd 10.17 规格仅校验功能、性能需求, 规格可能为空. 因此只传递数字/模拟
            return Arrays.asList("数字, 模拟").equals(UtilMap.getString(item, "selectField_lti2e638"));
        }).map(row -> {
            // Type, MinSpec, MaxSpec, Unit, Description 规格描述
            Map r = UtilMap.map("Type, MinSpec, MaxSpec, Unit, Description", "textField_lubo7pf2, textField_lubo7pf3, textField_lubo7pf4, textField_lubo7pf5, textField_lt2vdhtf", row);
            // ID 规格编号 + 需求编号
            r.put("ID", UtilMap.getString(row, "textField_m18x4yqo") + "_" + UtilMap.getString(row, "textField_m0vvv72j"));
            List<String> tList = UtilMap.getList(row, "employeeField_m1zxtrbz_id");
            if (!tList.isEmpty()) {
                r.put("Owner", String.join(",", tList)); // 用户人名或工号(支持多个用户，使用逗号分割)
            }
            r.put("Title", r.get("Description"));
            r.put("Domain", UtilMap.getString(UtilMap.map("数字, 模拟", "analog, digital"), UtilMap.getString(row, "selectField_lti2e638")));
            r.put("Scope", UtilMap.getString(formData, "selectField_lt6xc8eg")); // 产品型号
            r.put("Version", UtilMap.getString(formData, "selectField_lxmi8w6o")); // 产品版本
            r.put("Category", UtilMap.getString(row, "textField_lt2vdhtd")); // 规格类型
            r.put("Subclass", UtilMap.getString(row, "textField_lt2vdhte")); // 规格子类
            r.put("Condition", UtilMap.getString(row, "textField_lt2vdhtg")); // 规格条件
            return r;
        }).collect(Collectors.toList());
        return UtilMap.map("code, list", UtilMap.getString(formData, "serialNumberField_lt6xc8ef"), details);
    }

    /**
     * 提供verifier数据回传服务
     */
    @Override
    public void backVerifier(Map data) {

        List<Map> list = UtilMap.getList(data, "data");
        list.forEach(item -> {
            Map formData = UtilMap.map("textField_u3qgblp, textField_cpp0ref", "ID, Title", item);
            ydClient.operateData(YDParam.builder()
                    .appType("APP_R5EBUF2FPN3Y8DRF93M4")
                    .systemToken("ON566NC1VNIHPANP9TNVHB3TBIWS3E0TUZ5RLF3")
                    .formUuid("FORM-F390DA7B88C4470EA49503753DA6C8FBQCDN")
                    .formDataJson(JSON.toJSONString(formData))
                    .build(), YDConf.FORM_OPERATION.create);
        });
    }

    @Override
    public void test() {

//        this._test0912();

        List<Map> dataList = ydService.queryFormData_all(YDParam.builder()
                .appType(appType_ps)
                .systemToken(systemToken_ps)
                .formUuid("FORM-2C5D914DC3974745AA6F55CB916E82FEH5UA")
                .build());
        log.info("dataList, {}", JSON.toJSONString(dataList));
    }

    // 刷新排序号, 并更新数据版本
    private void _test0912() {
        String appType = "APP_YQY0OH7953OKBTM57PLL";
        String systemToken = "PGC66MB1H2RLXMFQ7XKW4BC3BDFJ2UDM909XL18";

        List<Map> dataList = ydService.queryFormData_all(YDParam.builder()
                .appType(appType)
                .systemToken(systemToken)
                .formUuid("FORM-7A52930D0E834522AD65A4CFE2C0818F1KQO")
                .build());

        dataList.forEach(item -> {
            ydClient.operateData(YDParam.builder()
                    .appType(appType)
                    .systemToken(systemToken)
                    .formInstanceId(String.valueOf(item.get("formInstanceId")))
                    .updateFormDataJson(JSON.toJSONString(UtilMap.empty()))
                    .useLatestVersion(true)
                    .build(), YDConf.FORM_OPERATION.update);
        });
    }

    /************************************* 0906 产品需求导入逻辑变革, 弃用保留 *************************************/

    @Override
    public Map checkImportData(Map data) {
        List<Map> dataList = UtilMap.getList(data, "dataList");
        String charter = UtilMap.getString(data, "charter");
        // 根据charter查询需求库
        List<Map> list = ydService.queryFormData_all(YDParam.builder()
                .appType("APP_YQY0OH7953OKBTM57PLL")
                .systemToken("PGC66MB1H2RLXMFQ7XKW4BC3BDFJ2UDM909XL18")
                .formUuid("FORM-7A52930D0E834522AD65A4CFE2C0818F1KQO")
                .searchFieldJson(JSONObject.toJSONString(UtilMap.map("textField_lth2h04b", charter))).build());
        Map<String, Map> charterMap = new HashMap();
        Map<String, String> instIdList = new HashMap<>();
        for (int j = 0; j < list.size(); j++) {
            Map item = list.get(j);
            instIdList.put(UtilMap.getString(item, "textField_lt2d2x79"), UtilMap.getString(item, "instanceId"));
            String no = getCode(UtilMap.getString(item, "textField_lt2d2x79"));
            charterMap.put(no, item);
            list.get(j).put("id", no);
        }
        Boolean flag = true;
        Map noList = new HashMap();
        // 数据校验
        for (int i = 0; i < dataList.size(); i++) {
            String errmsg = "";
            Map item = dataList.get(i);
            String category = UtilMap.getString(item, "selectField_lronu2g3");
            if (StringUtils.isBlank(category)) {
                errmsg = errmsg + "需求大类不能为空；";
            } else {
                category = category.split("（")[1].replace("）", "");
                String no = noCP(UtilMap.getString(item, "textField_lt2d2x79"), category);
                String fno = noCP(UtilMap.getString(item, "textField_m0afm8pd"), category);
                if (!isValidVersion(no)) {
                    errmsg = errmsg + "需求编号格式错误；";
                }
                if (noList.containsKey(category + no)) {
                    errmsg = errmsg + "需求编号重复；";
                }
                noList.put(category + no, category + no);
                int cj = getSize(no);
                if (cj == 1) {
                    dataList.get(i).put("textField_m0afm8pd", "");
                } else {
                    if (!isValidVersion(fno)) {
                        errmsg = errmsg + "父需求编号格式错误；";
                    }
                    if (cj - 1 != getSize(fno)) {
                        errmsg = errmsg + "父需求编号层级错误；";
                    }
                    if (StringUtils.isNotBlank(fno) && !noList.containsKey(category + fno)) {
                        // 导入数据前父需求编号不存在
                        if (!charterMap.containsKey(getCode(UtilMap.getString(item, "textField_m0afm8pd")))) {
                            errmsg = errmsg + "父需求编号数据不存在；";
                        }
                    }
                }
                if (fno == no) {
                    errmsg = errmsg + "需求编号与父需求编号不能相同；";
                }
                dataList.get(i).put("selectField_lr4y2xcj", cj + "级");
                if (String.valueOf(item.get("multiSelectField_lw678e43")).length() > 0) {
                    List multi = UtilMap.getList(item, "multiSelectField_lw678e43");
                    dataList.get(i).put("multiSelectField_lw678e43_str", multi == null || multi.size() < 1 ? "" : String.join(",", multi));
                }
            }
            if (errmsg != "") {
                dataList.get(i).put("result", errmsg);
                flag = false;
            }
        }
        if (flag) {
            for (int i = 0; i < dataList.size(); i++) {
                Map item = dataList.get(i);
                String no = UtilMap.getString(item, "textField_lt2d2x79");
                String codeNo = getCode(no);
                if (charterMap.containsKey(codeNo)) {
                    dataList.get(i).put("associationFormField_lvy7yjq8", getAss(no, instIdList.get(no)));
                    dataList.get(i).put("textField_lyqprdyf", codeNo); // 序号
                } else {
                    // 新增
                    String category = UtilMap.getString(item, "selectField_lronu2g3");
                    String categoryNew = category.split("（")[1].replace("）", "");
                    no = noCP(UtilMap.getString(item, "textField_lt2d2x79"), categoryNew);
                    String fno = "";
                    int level = getSize(no);
                    dataList.get(i).put("selectField_lr4y2xcj", level + "级");
                    // 根据层级查询序号
                    String noNew = "";
                    // 处理结果
                    if (level > 1) {
                        fno = getCodeNo(categoryNew, noCP(UtilMap.getString(item, "textField_m0afm8pd"), categoryNew));
                    }
                    Map reMap = getMaxValue(list, level + "级", category, fno);
                    if (reMap != null) {
                        String id = UtilMap.getString(reMap, "id");
                        noNew = incrementLastPart(id);
                    } else {
                        noNew = level == 1 ? categoryNew + "001" : fno + ".1";
                    }
                    codeNo = noNew;
                    fno = getFnoValue(list, fno);
                    String nowTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("MMddHHmmssS"));
                    dataList.get(i).put("textField_lt2d2x79", noNew + "_" + nowTime);
                    dataList.get(i).put("textField_m0afm8pd", fno);
                    dataList.get(i).put("textField_lyqprdyf", codeNo); // 序号
                    // 拼装数据并新增需求
                    Map mapNew = dataList.get(i);
                    mapNew.put("textField_lth2h04b", charter);
                    mapNew.put("radioField_lroozhse", "是");
                    mapNew.put("textField_m0m3dyk4", fno);
                    mapNew.put("textField_lyqpt99s", codeNo);
                    mapNew.put("radioField_m0ow50wn", "是"); // 是否草稿
                    String id = (String) ydClient.operateData(YDParam.builder().appType("APP_YQY0OH7953OKBTM57PLL")
                            .systemToken("PGC66MB1H2RLXMFQ7XKW4BC3BDFJ2UDM909XL18")
                            .formUuid("FORM-7A52930D0E834522AD65A4CFE2C0818F1KQO")
                            .formDataJson(JSONObject.toJSONString(mapNew))
                            .build(), YDConf.FORM_OPERATION.create);
                    dataList.get(i).put("associationFormField_lvy7yjq8", getAss(noNew + "_" + nowTime, id));
                    mapNew.put("instanceId", id);
                    mapNew.put("id", codeNo);
                    list.add(mapNew);
                }
            }
        }
        return UtilMap.map("data, flag", dataList, flag);
    }

    private static String incrementLastPart(String input) {
        // 查找最后一个点号的位置
        int lastDotIndex = input.lastIndexOf('.');
        // 如果没有点号，则整个字符串都需要加1
        if (lastDotIndex == -1) {
            String q = input.substring(0, input.length() - 3);
            String h = input.substring(input.length() - 3);
            return q + String.format("%03d", Integer.parseInt(h) + 1);
        }
        // 分割字符串
        String prefix = input.substring(0, lastDotIndex + 1);
        String lastPart = input.substring(lastDotIndex + 1);
        // 对最后一部分加1
        String incrementedLastPart = incrementPart(lastPart);
        // 返回拼接后的结果
        return prefix + incrementedLastPart;
    }

    private static String incrementPart(String part) {
        // 将字符串转换为整数并加1
        int number = Integer.parseInt(part);
        number++;
        // 将整数转换回字符串
        return String.valueOf(number);
    }

    private static String getCodeNo(String category, String no) {
        int dotIndex = no.indexOf('.');
        String beforeDot = dotIndex == -1 ? no : no.substring(0, dotIndex);
        String afterDot = dotIndex == -1 ? "" : no.substring(dotIndex);
        // 对第一部分进行补零
        String paddedBeforeDot = String.format("%03d", Integer.parseInt(beforeDot));
        return category + paddedBeforeDot + afterDot;
    }

    private String getFnoValue(List<Map> list, String fno) {
        if (StringUtils.isBlank(fno)) {
            return "";
        }
        List<Map> list1 = list.stream()
                .filter(map -> UtilMap.getString(map, "textField_lt2d2x79").contains(fno + "_")).collect(Collectors.toList()); // 父编号查询编号
        if (list1 != null && list1.size() > 0) {
            return UtilMap.getString(list1.get(0), "textField_lt2d2x79");
        }
        return "";
    }

    private Map getMaxValue(List<Map> list, String level, String category, String fno) {
        // 查找符合条件的最大 id
        List<Map> list1 = list.stream()
                .filter(map -> UtilMap.getString(map, "selectField_lr4y2xcj").equals(level)) // 层级
                .filter(map -> UtilMap.getString(map, "textField_lt2d2x79").contains(fno)) // 父编号查询编号
                .filter(map -> UtilMap.getString(map, "selectField_lronu2g3").equals(category)).collect(Collectors.toList()); // 前缀
        Optional<Map> maxMap = list1.stream()
                .max(Comparator.comparing(map -> UtilMap.getString(map, "id")));
        return maxMap.orElse(null);
    }

    private Object getAss(String title, String id) {
        return Arrays.asList(UtilMap.map("appType, formUuid, formType, instanceId, title, subTitle", "APP_YQY0OH7953OKBTM57PLL", "FORM-7A52930D0E834522AD65A4CFE2C0818F1KQO", "receipt", id, title, ""));
    }

    private static int getSize(String value) {
        return value.split("\\.").length;
    }

    private Boolean isValidVersion(String version) {
        Pattern pattern = Pattern.compile("^([0-9]{1,3}(\\.[0-9]{1,3}){0,2})$");
        Matcher matcher = pattern.matcher(version);
        return matcher.matches();
    }

    private String noCP(String value, String category) {
        if (value.contains(category)) {
            return getCode(value).replace(category, "").replaceAll("^0+", "");
        } else {
            return value;
        }
    }

    private String getCode(String pCode) {
        if (!pCode.contains("_")) {
            return pCode;
        }
        if (isNumeric(pCode.split("_")[0])) {
            // 时间_序号
            return pCode.split("_")[1];
        } else if (isNumeric(pCode.split("_")[1])) {
            // 序号_时间
            return pCode.split("_")[0];
        }
        return pCode;
    }

    private boolean isNumeric(String str) {
        Pattern pattern = Pattern.compile("^\\d+$");
        Matcher matcher = pattern.matcher(str);
        return matcher.matches();
    }
}
