package nckd.jxccl.opmc.pm.plugin.operate.cycle;

import kd.bos.common.enums.EnableEnum;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.dataentity.entity.DynamicObjectCollection;
import kd.bos.entity.ExtendedDataEntity;
import kd.bos.entity.operate.OperateOptionConst;
import kd.bos.entity.operate.interaction.InteractionConfirmResult;
import kd.bos.entity.operate.interaction.InteractionContext;
import kd.bos.entity.operate.interaction.KDInteractionException;
import kd.bos.entity.operate.result.OperateErrorInfo;
import kd.bos.entity.plugin.AbstractOperationServicePlugIn;
import kd.bos.entity.plugin.AddValidatorsEventArgs;
import kd.bos.entity.plugin.args.BeforeOperationArgs;
import kd.bos.entity.plugin.args.BeginOperationTransactionArgs;
import kd.bos.entity.plugin.args.EndOperationTransactionArgs;
import kd.bos.entity.validate.AbstractValidator;
import kd.bos.entity.validate.ErrorLevel;
import kd.bos.form.MessageBoxResult;
import kd.bos.orm.query.QCP;
import kd.bos.orm.query.QFilter;
import kd.bos.servicehelper.QueryServiceHelper;
import kd.bos.servicehelper.operation.SaveServiceHelper;
import kd.sdk.plugin.Plugin;
import nckd.jxccl.base.common.constant.FormConstant;
import nckd.jxccl.base.common.enums.AppraisalResultEnum;
import nckd.jxccl.base.common.utils.ConvertUtil;
import nckd.jxccl.base.common.utils.DateUtil;
import nckd.jxccl.base.common.utils.QueryFieldBuilder;
import nckd.jxccl.base.common.utils.StrFormatter;
import nckd.jxccl.base.hrpi.helper.EmpPosOrgRelHelper;
import nckd.jxccl.opmc.pm.common.PerfManagerFormConstant;
import nckd.jxccl.opmc.pm.helper.PerfManagerHelper;
import org.apache.commons.lang3.StringUtils;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.StringJoiner;
import java.util.stream.Collectors;
import kd.bos.dataentity.utils.ObjectUtils;

/**
 * 考核周期保存OP
 * 实体标识：nckd_perfmanager
 * @author W.Y.C
 * @date 2025/11/4 12:29
 * @version 1.0
 */
public class PerfManagerSaveOpPlugin extends AbstractOperationServicePlugIn implements Plugin {



    Map<Long, Date> personBeginYearMap = new HashMap<>();
    private  List<Long> ids = new ArrayList<>();
    //分录ID
    private  List<Long> entryIds = new ArrayList<>();

    private final static String INTERACTION_SPONORE = PerfManagerSaveOpPlugin.class.getName();


    @Override
    public void onAddValidators(AddValidatorsEventArgs e) {
        boolean dataMigration;
        Object invoker = this.getOption().getVariables().get(FormConstant.HR_INVOKER_PARAM_INVOKER);
        if(ObjectUtils.isEmpty(invoker)){
            Object invoker1 = this.getOption().getVariables().get("hr_hrdmvalidatetag_of_datasource");
            Object invoker2 = this.getOption().getVariables().get("hr_hrdmsynctag_of_datasource");
            if(!ObjectUtils.isEmpty(invoker1) || !ObjectUtils.isEmpty(invoker2)){
                dataMigration = true;
            } else {
                dataMigration = false;
            }
        } else{
            dataMigration = FormConstant.DATA_MIGRATION.equalsIgnoreCase(invoker.toString());
        }
        boolean isUpdate = ConvertUtil.toBoolean(this.getOption().getVariableValue("isUpdate",StringUtils.EMPTY),Boolean.FALSE);
        e.addValidator(new AbstractValidator() {
            @Override
            public void validate() {
                Boolean isCycleGenerate = ConvertUtil.toBoolean(this.getOption().getVariableValue("cyclegenerate", StringUtils.EMPTY), Boolean.FALSE);
                //第一个循环先获取表单数据，这里需要兼容单人和批量的数据包
                Map<Long, List<PersonPerfInfo>> currentBatchData = new HashMap<>();
                for (ExtendedDataEntity rowDataEntity : getDataEntities()) {
                    DynamicObject data = rowDataEntity.getDataEntity();
                    int dataEntityIndex = rowDataEntity.getDataEntityIndex();
                    long id = data.getLong(FormConstant.ID_KEY);
                    DynamicObject person = data.getDynamicObject(FormConstant.NCKD_PERSON);
                    person = person == null ? data.getDynamicObject(FormConstant.NCKD_EMPPOSORGREL).getDynamicObject(FormConstant.EMPLOYEE_KEY) : person;
                    data.set(FormConstant.NCKD_PERSON, person);
                    Date beginYear = data.getDate(PerfManagerFormConstant.NCKD_BEGINYEAR);
                    Date endYear = data.getDate(PerfManagerFormConstant.NCKD_ENDYEAR);
                    String description = data.getString(FormConstant.DESCRIPTION_KEY);
                    Long personId = person.getLong(FormConstant.ID_KEY);
                    if (beginYear != null) {
                        personBeginYearMap.put(personId, beginYear);
                    }
                    if (id > 0) {
                        ids.add(id);
                    }
                    DynamicObjectCollection perfManagerEntry = data.getDynamicObjectCollection(PerfManagerFormConstant.NCKD_PERFMANAGERENTRY);
                    if(!perfManagerEntry.isEmpty()){
                        for (DynamicObject entry : perfManagerEntry) {
                            long entryId = entry.getLong(FormConstant.ID_KEY);
                            entryIds.add(entryId);
                        }
                    }

                    PersonPerfInfo perfInfo = new PersonPerfInfo(person, null,null,
                            data.getDate(PerfManagerFormConstant.NCKD_BEGINYEAR),
                            data.getDate(PerfManagerFormConstant.NCKD_ENDYEAR),
                            data.getString(FormConstant.DESCRIPTION_KEY),
                            rowDataEntity.getDataEntityIndex());

                    currentBatchData.computeIfAbsent(personId, k -> new ArrayList<>()).add(perfInfo);
                }
                if(!isUpdate) {
                    if (!dataMigration) {
                        if (!isCycleGenerate) {
                            //检查同一批次内同一人员的周期重叠
                            for (Map.Entry<Long, List<PersonPerfInfo>> entry : currentBatchData.entrySet()) {
                                List<PersonPerfInfo> personPerfList = entry.getValue();
                                if (personPerfList.size() > 1) {
                                    // 对同一人员的多个周期进行相互比较
                                    for (int i = 0; i < personPerfList.size(); i++) {
                                        PersonPerfInfo info1 = personPerfList.get(i);
                                        for (int j = i + 1; j < personPerfList.size(); j++) {
                                            PersonPerfInfo info2 = personPerfList.get(j);
                                            String personName = info2.getPerson().getString(FormConstant.NAME_KEY);

                                            // 检查开始年份是否相同
                                            if (isSameYear(info1.getBeginYear(), info2.getBeginYear())) {
                                                addFatalErrorMessage(getDataEntities()[info1.getDataEntityIndex()],
                                                        StrFormatter.format("同批次数据中，人员【{}】存在相同的周期开始年份：{}",
                                                                personName, info1.getBeginYear().getYear()));
                                            } else {
                                                // 只有开始年份不相同时才检查重叠
                                                // 检查周期是否重叠
                                                String overlapInfo = getCycleOverlapInfo(
                                                        info1.getBeginYear(), info1.getEndYear(), null,
                                                        info2.getBeginYear(), info2.getEndYear(), null);

                                                if (StringUtils.isNotBlank(overlapInfo)) {
                                                    addFatalErrorMessage(getDataEntities()[info1.getDataEntityIndex()],
                                                            StrFormatter.format("同批次数据中，人员【{}】存在重叠周期：{}", personName, overlapInfo));
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }

                //获取已归档人员，已归档人员不能修改考核结果
                QueryFieldBuilder perfArchiveRecordQueryFieldBuilder = QueryFieldBuilder.create()
                        .addIdNumberName(FormConstant.NCKD_PERSON)
                        .add(PerfManagerFormConstant.NCKD_YEAR);
                QFilter perfArchiveRecordFilter = new QFilter(FormConstant.NCKD_PERSON, QCP.in, personBeginYearMap.keySet());
                //查找已归档的记录（状态为1）
                perfArchiveRecordFilter = perfArchiveRecordFilter.and(new QFilter(PerfManagerFormConstant.NCKD_ARCHIVESTATUS, QCP.equals, "1"));
                DynamicObjectCollection perfArchiveRecordQuery = QueryServiceHelper.query(PerfManagerFormConstant.PERFARCHIVERECORD_ENTITYID, perfArchiveRecordQueryFieldBuilder.buildSelect(), new QFilter[]{perfArchiveRecordFilter});
                // 创建已归档人员ID和年度的映射集合
                Map<Long, List<Date>> archivedPersonYearPairs = perfArchiveRecordQuery.stream()
                        .collect(Collectors.groupingBy(
                                obj -> obj.getLong(String.join(".", FormConstant.NCKD_PERSON, FormConstant.ID_KEY)),
                                Collectors.mapping(obj -> obj.getDate(PerfManagerFormConstant.NCKD_YEAR), Collectors.toList())
                        ));
                //加载数据库中考核结果（用于后续判断是否变更）
                Map<Long,List<DynamicObject>> entryResultMap = new HashMap<>();
                if(!archivedPersonYearPairs.isEmpty()){
                    QueryFieldBuilder perfManagerEntryQueryFieldBuilder = QueryFieldBuilder.create()
                            .add(FormConstant.ID_KEY)
                            .add(PerfManagerFormConstant.NCKD_BEGINYEAR)
                            .add(PerfManagerFormConstant.NCKD_ENDYEAR)
                            .add(PerfManagerFormConstant.NCKD_SALARYADJUSTGENFLAG)
                            .add(PerfManagerFormConstant.NCKD_PERFMANAGERENTRY,FormConstant.ID_KEY)
                            .add(PerfManagerFormConstant.NCKD_PERFMANAGERENTRY,PerfManagerFormConstant.NCKD_APPRAISALYEAR)
                            .addIdNumberName(PerfManagerFormConstant.NCKD_PERFMANAGERENTRY,PerfManagerFormConstant.NCKD_APPRAISALRESULT);
                    QFilter perfManagerEntryFilter = new QFilter(FormConstant.ID_KEY, QCP.in, ids);
                    DynamicObjectCollection query = QueryServiceHelper.query(PerfManagerFormConstant.PERFMANAGER_ENTITYID, perfManagerEntryQueryFieldBuilder.buildSelect(), new QFilter[]{perfManagerEntryFilter});
                    entryResultMap = query.stream()
                            .collect(Collectors.groupingBy(
                                    obj -> obj.getLong(FormConstant.ID_KEY))
                            );

                }
                Map<Long, DynamicObject> dbMap = new HashMap<>();
                if(isUpdate){
                    //如果是更新则查询数据库中是否生成调档
                    QueryFieldBuilder queryFieldBuilder = QueryFieldBuilder.create()
                            .add(FormConstant.ID_KEY)
                            .add(PerfManagerFormConstant.NCKD_SALARYADJUSTGENFLAG);
                    QFilter filter = new QFilter(FormConstant.ID_KEY, QCP.in, ids);
                    DynamicObjectCollection query = QueryServiceHelper.query(PerfManagerFormConstant.PERFMANAGER_ENTITYID, queryFieldBuilder.buildSelect(), new QFilter[]{filter});
                    dbMap = query.stream()
                            .collect(Collectors.toMap(
                                    dynamicObject -> dynamicObject.getLong(FormConstant.ID_KEY),
                                    dynamicObject -> dynamicObject
                            ));
                }


                QueryFieldBuilder queryFieldBuilder = QueryFieldBuilder.create()
                        .addIdNumberName(FormConstant.NCKD_PERSON)
                        .add(PerfManagerFormConstant.NCKD_BEGINYEAR)
                        .add(PerfManagerFormConstant.NCKD_ENDYEAR)
                        .add(PerfManagerFormConstant.NCKD_ACTENDYEAR);
                QFilter filter = new QFilter(FormConstant.NCKD_PERSON, QCP.in, personBeginYearMap.keySet());
                if(!ids.isEmpty()) {
                    filter = filter.and(new QFilter(FormConstant.ID_KEY, QCP.not_in, ids));
                }
                //根据人员查询出当前自己之外的其他考核周期
                DynamicObjectCollection query = QueryServiceHelper.query(PerfManagerFormConstant.PERFMANAGER_ENTITYID, queryFieldBuilder.buildSelect(), new QFilter[]{filter});
                //按人员分组
                Map<Long, List<DynamicObject>> groupedQueryResults = query.stream()
                        .collect(Collectors.groupingBy(
                                dynamicObject -> dynamicObject.getLong(String.join(".", FormConstant.NCKD_PERSON, FormConstant.ID_KEY))
                        ));
                for (ExtendedDataEntity rowDataEntity : getDataEntities()) {
                    DynamicObject data = rowDataEntity.getDataEntity();
                    long id = data.getLong(FormConstant.ID_KEY);
                    DynamicObject person = data.getDynamicObject(FormConstant.NCKD_PERSON);
                    person = person == null ? data.getDynamicObject(FormConstant.NCKD_EMPPOSORGREL).getDynamicObject(FormConstant.EMPLOYEE_KEY) : person;
                    long personId = person.getLong(FormConstant.ID_KEY);
                    String personName = person.getString(FormConstant.NAME_KEY);
                    LocalDateTime beginYear = ConvertUtil.toLocalDateTime(data.getDate(PerfManagerFormConstant.NCKD_BEGINYEAR));
                    LocalDateTime endYear = ConvertUtil.toLocalDateTime(data.getDate(PerfManagerFormConstant.NCKD_ENDYEAR));

                    // 判断beginYear和endYear是不是间隔3年，例如：开始2025年，结束必须为2027年
                   /* if (beginYear != null && endYear != null) {
                        int beginYearValue = beginYear.getYear();
                        int endYearValue = endYear.getYear();
                        if (endYearValue - beginYearValue != 2) {
                            addFatalErrorMessage(rowDataEntity,
                                    StrFormatter.format("周期开始年份【{}】与结束年份【{}】必须间隔3年，请检查！",
                                            beginYearValue, endYearValue));
                        }
                    }*/

                    //校验是否存在相同周期开始年的记录 begin
                    List<DynamicObject> personRecords = groupedQueryResults.getOrDefault(personId, Collections.emptyList());
                    for (DynamicObject dynamicObject : personRecords) {
                        LocalDateTime dbBeginYear = DateUtil.toLocalDateTime(dynamicObject.getDate(PerfManagerFormConstant.NCKD_BEGINYEAR));
                        LocalDateTime dbEndYear = DateUtil.toLocalDateTime(dynamicObject.getDate(PerfManagerFormConstant.NCKD_ENDYEAR));
                        Date actEndYear = dynamicObject.getDate(PerfManagerFormConstant.NCKD_ACTENDYEAR);
                        LocalDateTime dbActEndYear = actEndYear != null ? DateUtil.toLocalDateTime(actEndYear) : null;
                        if(!isUpdate) {
                            if (!dataMigration) {
                                if (!isCycleGenerate) {
                                    // 判断周期是否重叠并获取重叠信息，已结束周期使用实际结束时间
                                    String overlapInfo = getCycleOverlapInfo(beginYear, endYear, null, dbBeginYear, dbEndYear, dbActEndYear);
                                    if (StringUtils.isNotBlank(overlapInfo)) {
                                        addFatalErrorMessage(rowDataEntity,
                                                StrFormatter.format("人员【{}】的考核周期与已有周期在{}重叠，请检查！",
                                                        personName, overlapInfo));
                                    }
                                }


                                //判断beginYear和dbBeginYear的年份是否相同
                                if (isSameYear(beginYear, dbBeginYear)) {
                                    addFatalErrorMessage(rowDataEntity,
                                            StrFormatter.format("人员【{}】已经存在周期开始年份【{}】的周期，无需进行创建。",
                                                    personName,
                                                    beginYear.getYear()));
                                }
                            }
                        }

                        //当前周期必须大于之前周期的开始时间
                        /*if (beginYear != null && beginYear.isBefore(dbBeginYear)) {
                            addFatalErrorMessage(rowDataEntity,
                                    StrFormatter.format("人员【{}】当前周期开始时间【{}】必须大于之前周期开始时间【{}】。",
                                            personName,
                                            beginYear.getYear(),
                                            dbBeginYear.getYear()));
                        }*/
                    }

                    //校验是否存在相同周期开始年的记录 end
                    DynamicObjectCollection entrys = data.getDynamicObjectCollection(PerfManagerFormConstant.NCKD_PERFMANAGERENTRY);
                    if(!dataMigration) {
                        if (entrys != null) {
                            List<Date> dateList = entrys.stream().map(entry -> entry.getDate(PerfManagerFormConstant.NCKD_APPRAISALYEAR)).collect(Collectors.toList());
                            if (beginYear != null && endYear != null) {
                                // 校验考核年份是否在周期内
                                List<String> outOfRangeYears = entrys.stream()
                                        .map(entry -> entry.getDate(PerfManagerFormConstant.NCKD_APPRAISALYEAR))
                                        .filter(Objects::nonNull)
                                        .filter(date -> !DateUtil.isInRange(DateUtil.toLocalDateTime(date), beginYear, endYear))
                                        .map(date -> String.valueOf(DateUtil.getYear(DateUtil.toLocalDateTime(date))))
                                        .distinct()
                                        .collect(Collectors.toList());

                                if (!outOfRangeYears.isEmpty()) {
                                    String outOfRangeYearsStr = String.join(",", outOfRangeYears);
                                    addFatalErrorMessage(rowDataEntity,
                                            StrFormatter.format("考评年份【{}】不在周期范围内，请检查！", outOfRangeYearsStr));
                                }
                            }
                            // 校验考核年份是否重复
                            List<String> duplicateYears = getDuplicateYears(dateList);
                            if (!duplicateYears.isEmpty()) {
                                String duplicateYearsStr = String.join(",", duplicateYears);
                                addFatalErrorMessage(rowDataEntity,
                                        StrFormatter.format("考评结果存在重复的考核年份【{}】，请检查！", duplicateYearsStr));
                            }

                            //如果是更新则需要校验是否更改已归档的考核结果
                            if (isUpdate) {


                           /* if(!entryIds.isEmpty() && !entryResultMap.isEmpty()) {
                                for (DynamicObject entry : entrys) {
                                    long entryId = entry.getLong(FormConstant.ID_KEY);
                                    if (entryId > 0) {
                                        DynamicObject appraisalResult = entry.getDynamicObject(PerfManagerFormConstant.NCKD_APPRAISALRESULT);
                                        LocalDateTime appraisalYear = DateUtil.toLocalDateTime(entry.getDate(PerfManagerFormConstant.NCKD_APPRAISALYEAR));
                                        String appraisalResultNumber = appraisalResult != null ? appraisalResult.getString(FormConstant.NUMBER_KEY) : null;
                                        String dbAppraisalResultNumber = entryResultMap.get(entryId);
                                        String appraisalResultName = StringUtils.isNotBlank(dbAppraisalResultNumber) ? AppraisalResultEnum.getByCode(dbAppraisalResultNumber).getName() : "空";
                                        if (!Objects.equals(appraisalResultNumber, dbAppraisalResultNumber) && archivedPersonIds.contains(personId)) {
                                            addFatalErrorMessage(rowDataEntity,
                                                    StrFormatter.format("人员【{}】考核周期已归档，不能修改【{}】年的考核结果，修改前考核结果【{}】。",
                                                            personName,
                                                            appraisalYear.getYear(),
                                                            appraisalResultName));
                                        }
                                    }
                                }
                            }*/
                                if (!dbMap.isEmpty()) {
                                    DynamicObject dbPerManager = dbMap.get(id);
                                    boolean salaryAdjustGenFlag = dbPerManager.getBoolean(PerfManagerFormConstant.NCKD_SALARYADJUSTGENFLAG);
                                    if (salaryAdjustGenFlag) {
                                        addFatalErrorMessage(rowDataEntity,
                                                StrFormatter.format("人员【{}】已生成调档，不能修改。", personName));
                                    }
                                }
                            }

                        }
                    }

                    if(isUpdate){
                        //如果已归档则不能修改考核周期和考核结果
                        List<DynamicObject> dbPefList = entryResultMap.get(id);
                        if(dbPefList != null) {
                            boolean isArchived = false;
                            for (DynamicObject dbPef : dbPefList) {
                                LocalDateTime dbBeginYear = DateUtil.toLocalDateTime(dbPef.getDate(PerfManagerFormConstant.NCKD_BEGINYEAR));
                                LocalDateTime dbEndDate = DateUtil.toLocalDateTime(dbPef.getDate(PerfManagerFormConstant.NCKD_ENDYEAR));
                                List<Date> dates = archivedPersonYearPairs.get(personId);
                                // 获取dates中年份最大的日期
                                if(dates != null) {
                                    Date maxDate = dates.stream()
                                            .filter(Objects::nonNull)
                                            .max(Comparator.comparing(date -> DateUtil.toLocalDateTime(date).getYear()))
                                            .orElse(null);
                                    if (maxDate != null) {
                                        LocalDateTime maxLocalDate = DateUtil.toLocalDateTime(maxDate);
                                        if (maxLocalDate.getYear() >= dbBeginYear.getYear() || maxLocalDate.getYear() >= dbEndDate.getYear()) {
                                            //判断本次是否有变更，如果有变更返回错误
                                            if (!isArchived) {
                                                if (dbBeginYear.getYear() != beginYear.getYear() || dbEndDate.getYear() != endYear.getYear()) {
                                                    addFatalErrorMessage(rowDataEntity,
                                                            StrFormatter.format("人员【{}】考核周期已归档，不能修改【{}】年及之前的考核周期范围。",
                                                                    personName,
                                                                    maxLocalDate.getYear()));
                                                }
                                                isArchived = true;
                                            }
                                        }

                                        Date appraisalYear = dbPef.getDate(String.join(".", PerfManagerFormConstant.NCKD_PERFMANAGERENTRY, PerfManagerFormConstant.NCKD_APPRAISALYEAR));
                                        if (appraisalYear != null) {
                                            LocalDateTime appraisalYearLocalDate = DateUtil.toLocalDateTime(appraisalYear);
                                            String dbAppraisalResultNumber = dbPef.getString(String.join(".", PerfManagerFormConstant.NCKD_PERFMANAGERENTRY, PerfManagerFormConstant.NCKD_APPRAISALRESULT, FormConstant.NUMBER_KEY));
                                            String dbAppraisalResultName = dbPef.getString(String.join(".", PerfManagerFormConstant.NCKD_PERFMANAGERENTRY, PerfManagerFormConstant.NCKD_APPRAISALRESULT, FormConstant.NAME_KEY));
                                            if (entrys != null && !entrys.isEmpty()) {
                                                for (DynamicObject entry : entrys) {
                                                    DynamicObject appraisalResult = entry.getDynamicObject(PerfManagerFormConstant.NCKD_APPRAISALRESULT);
                                                    String appraisalResultNumber = appraisalResult != null ? appraisalResult.getString(FormConstant.NUMBER_KEY) : null;
                                                    if (maxLocalDate.getYear() >= appraisalYearLocalDate.getYear()) {
                                                        if (!Objects.equals(appraisalResultNumber, dbAppraisalResultNumber)) {
                                                            addFatalErrorMessage(rowDataEntity,
                                                                    StrFormatter.format("人员【{}】考核周期已归档，不能修改【{}】年的考核结果，修改前考核结果【{}】。",
                                                                            personName,
                                                                            appraisalYearLocalDate.getYear(),
                                                                            dbAppraisalResultName));
                                                        }
                                                    }
                                                }
                                            }
                                        } else {
                                            if (entrys != null && !entrys.isEmpty()) {
                                                //原来没有考核结果
                                                addFatalErrorMessage(rowDataEntity,
                                                        StrFormatter.format("人员【{}】考核周期已归档，不能修改【{}】年及之前的考核结果。",
                                                                personName,
                                                                maxLocalDate.getYear()));
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }

                    //规则: 如果年度排名管理中已存在某年度的考核结果，则不允许在人员考评管理中修改该年度的考核结果。
                    //规则: 对于已处理的调薪情况，不允许修改或删除相关的年度考核结果。
                }
            }

            private boolean isSameYear(LocalDateTime date1, LocalDateTime date2) {
                return date1 != null && date2 != null && date1.getYear() == date2.getYear();
            }
        });
    }

    /**
     * 判断两个考核周期是否重叠，并返回重叠描述
     *
     * @param beginYear1 第一个周期开始年份
     * @param endYear1 第一个周期结束年份
     * @param actEndYear1 第一个周期实际结束年份（如果已结束）
     * @param beginYear2 第二个周期开始年份
     * @param endYear2 第二个周期结束年份
     * @param actEndYear2 第二个周期实际结束年份（如果已结束）
     * @return 如果周期重叠返回重叠描述，否则返回空字符串
     */
    private String getCycleOverlapInfo(LocalDateTime beginYear1, LocalDateTime endYear1, LocalDateTime actEndYear1,
                                       LocalDateTime beginYear2, LocalDateTime endYear2, LocalDateTime actEndYear2) {
        if (beginYear1 == null || endYear1 == null || beginYear2 == null || endYear2 == null) {
            return "";
        }

        // 如果周期已结束，使用实际结束时间，否则使用计划结束时间
        LocalDateTime realEndYear1 = actEndYear1 != null ? actEndYear1 : endYear1;
        LocalDateTime realEndYear2 = actEndYear2 != null ? actEndYear2 : endYear2;

        // 两个区间重叠的条件是：一个区间的开始时间小于等于另一个区间的结束时间，
        // 且该区间的结束时间大于等于另一个区间的开始时间
        if (!beginYear1.isAfter(realEndYear2) && !realEndYear1.isBefore(beginYear2)) {
            // 计算重叠区间
            LocalDateTime overlapStart = beginYear1.isAfter(beginYear2) ? beginYear1 : beginYear2;
            LocalDateTime overlapEnd = realEndYear1.isBefore(realEndYear2) ? realEndYear1 : realEndYear2;

            if (overlapStart.equals(overlapEnd)) {
                return StrFormatter.format("{}年", overlapStart.getYear());
            } else {
                return StrFormatter.format("{}年~{}年", overlapStart.getYear(), overlapEnd.getYear());
            }
        }

        return "";
    }

    @Override
    public void beforeExecuteOperationTransaction(BeforeOperationArgs e) {

        boolean dataMigration;
        Object invoker = this.getOption().getVariables().get(FormConstant.HR_INVOKER_PARAM_INVOKER);
        if(ObjectUtils.isEmpty(invoker)){
            Object invoker1 = this.getOption().getVariables().get("hr_hrdmvalidatetag_of_datasource");
            Object invoker2 = this.getOption().getVariables().get("hr_hrdmsynctag_of_datasource");
            if(!ObjectUtils.isEmpty(invoker1) || !ObjectUtils.isEmpty(invoker2)){
                dataMigration = true;
            } else {
                dataMigration = false;
            }
        } else{
            dataMigration = FormConstant.DATA_MIGRATION.equalsIgnoreCase(invoker.toString());
        }
        if(!dataMigration) {
            if(!this.getOperationResult().isSuccess()){
                e.setCancel(true);
                return;
            }
            String ignoreInteraction = this.getOption().getVariableValue(OperateOptionConst.IGNOREINTERACTION, StringUtils.EMPTY);
            if (StringUtils.isBlank(ignoreInteraction) || !"true".equalsIgnoreCase(ignoreInteraction)) {
                StringJoiner confirmMsg = new StringJoiner("，");
                for (DynamicObject dataEntity : e.getDataEntities()) {
                    long id = dataEntity.getLong(FormConstant.ID_KEY);
                    Date date = dataEntity.getDate(PerfManagerFormConstant.NCKD_BEGINYEAR);
                    long personId = dataEntity.getDynamicObject(FormConstant.NCKD_PERSON).getLong(FormConstant.ID_KEY);
                    QFilter filter = null;
                    if (id > 0) {
                        filter = new QFilter(FormConstant.ID_KEY, QCP.not_in, id);
                    }
                    DynamicObject[] lastPerfManagerArray = PerfManagerHelper.getBeforeBeginYear(date, Collections.singletonList(personId), filter);
                    for (DynamicObject lastPerfManager : lastPerfManagerArray) {
                        String personName = lastPerfManager.getDynamicObject(FormConstant.NCKD_PERSON).getString(FormConstant.NAME_KEY);
                        LocalDateTime beginYear = DateUtil.toLocalDateTime(lastPerfManager.getDate(PerfManagerFormConstant.NCKD_BEGINYEAR));
                        LocalDateTime endYear = DateUtil.toLocalDateTime(lastPerfManager.getDate(PerfManagerFormConstant.NCKD_ENDYEAR));
                        confirmMsg.add(StrFormatter.format("{}（周期：{}~{}）", personName, beginYear.getYear(), endYear.getYear()));
                    }
                }
                if (confirmMsg.length() > 0) {
                    e.cancel = !this.showInteractionMessage(confirmMsg.toString());
                }
            }
        }

    }
    @Override
    public void beginOperationTransaction(BeginOperationTransactionArgs e) {
        //事务开始之后将其他考核周期设置为非最新
        PerfManagerHelper.markAsNotCurrentNewest(personBeginYearMap.keySet().toArray(new Long[0]));

        boolean dataMigration;
        Object invoker = this.getOption().getVariables().get(FormConstant.HR_INVOKER_PARAM_INVOKER);
        if(ObjectUtils.isEmpty(invoker)){
            Object invoker1 = this.getOption().getVariables().get("hr_hrdmvalidatetag_of_datasource");
            Object invoker2 = this.getOption().getVariables().get("hr_hrdmsynctag_of_datasource");
            if(!ObjectUtils.isEmpty(invoker1) || !ObjectUtils.isEmpty(invoker2)){
                dataMigration = true;
            } else {
                dataMigration = false;
            }
        } else{
            dataMigration = FormConstant.DATA_MIGRATION.equalsIgnoreCase(invoker.toString());
        }
        Map<Long, DynamicObject> empPosOrgRelMap = new HashMap<>();
        if(dataMigration){
            List<Long> personIds = new ArrayList<>();
            for (DynamicObject dataEntity : e.getDataEntities()) {
                DynamicObject person = dataEntity.getDynamicObject(FormConstant.NCKD_PERSON);
                if(person != null){
                    personIds.add(person.getLong(FormConstant.ID_KEY));
                }
            }
            empPosOrgRelMap = EmpPosOrgRelHelper.queryEmpPosOrgRelWithOutPostByEmployeesMap(personIds);
        }

        Boolean isCycleGenerate = ConvertUtil.toBoolean(this.getOption().getVariableValue("cyclegenerate",StringUtils.EMPTY),Boolean.FALSE);
        Boolean isUpdate = ConvertUtil.toBoolean(this.getOption().getVariableValue("isUpdate",StringUtils.EMPTY),Boolean.FALSE);
        List<DynamicObject> updatePerManager = new ArrayList<>();


        for (DynamicObject dataEntity : e.getDataEntities()) {
            long id = dataEntity.getLong(FormConstant.ID_KEY);
            DynamicObject person = dataEntity.getDynamicObject(FormConstant.NCKD_PERSON);
            if(dataMigration) {
                long personId = person.getLong(FormConstant.ID_KEY);
                DynamicObject empPosOrgRel = empPosOrgRelMap.get(personId);
                dataEntity.set(FormConstant.NCKD_EMPPOSORGREL,empPosOrgRel);
            }
            DynamicObject empPosOrgRel = dataEntity.getDynamicObject(FormConstant.NCKD_EMPPOSORGREL);
            if(empPosOrgRel == null){
                continue;
            }

            person = person == null ? empPosOrgRel.getDynamicObject(FormConstant.EMPLOYEE_KEY) : person;
            dataEntity.set(FormConstant.NCKD_PERSON, person);
            LocalDateTime beginYear = DateUtil.toLocalDateTime(dataEntity.getDate(PerfManagerFormConstant.NCKD_BEGINYEAR));
            LocalDateTime endYear = DateUtil.toLocalDateTime(dataEntity.getDate(PerfManagerFormConstant.NCKD_ENDYEAR));
            long personId = person.getLong(FormConstant.ID_KEY);
            String personName = person.getString(FormConstant.NAME_KEY);
            String theStatus = dataEntity.getString(PerfManagerFormConstant.NCKD_THESTATUS);
            if(StringUtils.isBlank(theStatus)) {
                dataEntity.set(PerfManagerFormConstant.NCKD_THESTATUS, EnableEnum.YES.getCode());
            }
            // dataEntity.set(FormConstant.NCKD_ISCURRENTNEWEST, EnableEnum.YES.getCode());
            String name = dataEntity.getString(FormConstant.NAME_KEY);
            if(StringUtils.isBlank(name)){
                dataEntity.set(FormConstant.NAME_KEY, StrFormatter.format("【{}】{}~{}的考核周期",personName,beginYear.getYear(),endYear.getYear()));
            }
            DynamicObject dep = dataEntity.getDynamicObject(FormConstant.NCKD_DEP);
            if(dep == null){
                dataEntity.set(FormConstant.NCKD_DEP, empPosOrgRel.getDynamicObject(FormConstant.ADMINORG));
            }

            long depId = dataEntity.getLong(String.join(".", FormConstant.NCKD_DEP, FormConstant.ID_KEY));
            if(depId <= 0){
                dataEntity.set(FormConstant.NCKD_DEP, empPosOrgRel.getDynamicObject(FormConstant.ADMINORG));
            }
            if(dataEntity.containsProperty(FormConstant.CREATEORG_KEY)){
                dataEntity.set(FormConstant.CREATEORG_KEY, null);
            }
            if(dataEntity.containsProperty(FormConstant.USEORG_KEY)){
                dataEntity.set(FormConstant.USEORG_KEY, null);
            }
            if(dataEntity.containsProperty(FormConstant.ORG_KEY)){
                dataEntity.set(FormConstant.ORG_KEY, null);
            }


            /*DynamicObject lastPerfManager = lastPerfManagerMap.get(personId);
            if(lastPerfManager != null) {
                LocalDateTime date = DateUtil.toLocalDateTime(lastPerfManager.getDate(PerfManagerFormConstant.NCKD_BEGINYEAR));
                if("1".equalsIgnoreCase(lastPerfManager.getString(PerfManagerFormConstant.NCKD_THESTATUS)) && date.getYear() >= beginYear.getYear()) {

                }

               LocalDateTime lastBeginYear = DateUtil.toLocalDateTime(lastPerfManager.getDate(PerfManagerFormConstant.NCKD_BEGINYEAR));
                LocalDateTime lastEndYear = DateUtil.toLocalDateTime(lastPerfManager.getDate(PerfManagerFormConstant.NCKD_ENDYEAR));
                if(!Objects.equals(lastBeginYear, beginYear) || !Objects.equals(lastEndYear, endYear)) {
                    //当周期范围发生变化，需要保障数据连续性：若新旧考评周期存在重叠年份，且该年份在旧周期中已存在来源于【年度绩效排名】的考核结果，则新周期将自动继承该结果。
                    DynamicObjectCollection lastPerfManagerEntrys = lastPerfManager.getDynamicObjectCollection(PerfManagerFormConstant.NCKD_PERFMANAGERENTRY);
                    DynamicObjectCollection perfManagerEntrys = dataEntity.getDynamicObjectCollection(PerfManagerFormConstant.NCKD_PERFMANAGERENTRY);
                    for (DynamicObject lastPerfManagerEntry : lastPerfManagerEntrys) {
                        Date lastAppraisalYear = lastPerfManagerEntry.getDate(PerfManagerFormConstant.NCKD_APPRAISALYEAR);
                        DynamicObject appraisalResult = lastPerfManagerEntry.getDynamicObject(PerfManagerFormConstant.NCKD_APPRAISALRESULT);
                        if (lastAppraisalYear != null && appraisalResult != null) {
                            boolean isAllRankSource = lastPerfManagerEntry.getBoolean(PerfManagerFormConstant.NCKD_ISALLRANKSOURCE);
                            if (isAllRankSource) {
                                LocalDateTime lastAppraisalYearLocalDateTime = DateUtil.toLocalDateTime(lastAppraisalYear);
                                //判断appraisalYearLocalDateTime是不是在beginYear和endYear之间
                                if (DateUtil.isInRange(lastAppraisalYearLocalDateTime, beginYear, endYear)) {
                                    boolean isExist = false;
                                    for (DynamicObject perfManager : perfManagerEntrys) {
                                        Date appraisalYear = perfManager.getDate(PerfManagerFormConstant.NCKD_APPRAISALYEAR);
                                        if(appraisalYear != null){
                                            //如果分录存在相同年份则更新
                                            LocalDateTime appraisalYearLocalDateTime = DateUtil.toLocalDateTime(appraisalYear);
                                            if(appraisalYearLocalDateTime.getYear() == lastAppraisalYearLocalDateTime.getYear()){
                                                perfManager.set(PerfManagerFormConstant.NCKD_APPRAISALRESULT, appraisalResult);
                                                isExist = true;
                                            }
                                        }
                                    }
                                    if(!isExist) {
                                        //分录不存在当前年份，则添加
                                        DynamicObject dynamicObject = perfManagerEntrys.addNew();
                                        dynamicObject.set(PerfManagerFormConstant.NCKD_APPRAISALYEAR, lastAppraisalYear);
                                        dynamicObject.set(PerfManagerFormConstant.NCKD_APPRAISALRESULT, appraisalResult);
                                        dynamicObject.set(PerfManagerFormConstant.NCKD_ISALLRANKSOURCE, true);
                                    }
                                }
                            }
                        }
                    }
                }
            }*/


            //分录考核结果写入到表头 begin
            dataEntity.set(PerfManagerFormConstant.NCKD_FIRSTYEARRESULT, null);
            dataEntity.set(PerfManagerFormConstant.NCKD_SECONDYEARRESULT, null);
            dataEntity.set(PerfManagerFormConstant.NCKD_THIRDYEARRESULT, null);
            DynamicObjectCollection entrys = dataEntity.getDynamicObjectCollection(PerfManagerFormConstant.NCKD_PERFMANAGERENTRY);
            for (DynamicObject entry : entrys) {
                boolean isAllRankSource = entry.getBoolean(PerfManagerFormConstant.NCKD_ISALLRANKSOURCE);
                Date appraisalYear = entry.getDate(PerfManagerFormConstant.NCKD_APPRAISALYEAR);
                DynamicObject appraisalResult = entry.getDynamicObject(PerfManagerFormConstant.NCKD_APPRAISALRESULT);

                if (appraisalYear != null && appraisalResult != null) {
                    LocalDateTime appraisalLocalDate = DateUtil.toLocalDateTime(appraisalYear);
                    LocalDateTime beginLocalDate = beginYear;

                    // 计算是第几年（分录中的年份-(周期开始时间 + 1)）
                    long yearsDiff = appraisalLocalDate.getYear() - beginLocalDate.getYear() + 1;
                    // 根据年份差异设置表头对应的考核结果字段
                    switch ((int) yearsDiff) {
                        case 1:
                            dataEntity.set(PerfManagerFormConstant.NCKD_FIRSTYEARRESULT, appraisalResult);
                            break;
                        case 2:
                            dataEntity.set(PerfManagerFormConstant.NCKD_SECONDYEARRESULT, appraisalResult);
                            break;
                        case 3:
                            dataEntity.set(PerfManagerFormConstant.NCKD_THIRDYEARRESULT, appraisalResult);
                            break;
                    }
                }
            }
            //分录考核结果写入到表头 end
        }

    }

    /**
     * 查找给定日期之后的第一个考核周期
     *
     * @param allPerfManagerList 该人员的所有考核周期列表
     * @param currentDate 当前周期的开始日期
     * @return 下一个考核周期，如果不存在则返回null
     */
    private DynamicObject findNextCycle(List<DynamicObject> allPerfManagerList, Date currentDate) {
        if (allPerfManagerList == null || allPerfManagerList.isEmpty() || currentDate == null) {
            return null;
        }

        LocalDateTime currentLocalDate = DateUtil.toLocalDateTime(currentDate);

        return allPerfManagerList.stream()
                .filter(Objects::nonNull)
                .filter(perfManager -> {
                    Date beginYear = perfManager.getDate(PerfManagerFormConstant.NCKD_BEGINYEAR);
                    if (beginYear != null) {
                        LocalDateTime beginYearLocal = DateUtil.toLocalDateTime(beginYear);
                        return beginYearLocal.isAfter(currentLocalDate);
                    }
                    return false;
                })
                .min((perf1, perf2) -> {
                    LocalDateTime begin1 = DateUtil.toLocalDateTime(perf1.getDate(PerfManagerFormConstant.NCKD_BEGINYEAR));
                    LocalDateTime begin2 = DateUtil.toLocalDateTime(perf2.getDate(PerfManagerFormConstant.NCKD_BEGINYEAR));
                    return begin1.compareTo(begin2);
                })
                .orElse(null);
    }

    /**
     * 查找给定日期之前的最后一个考核周期
     *
     * @param allPerfManagerList 该人员的所有考核周期列表
     * @param currentDate 当前周期的开始日期
     * @return 上一个考核周期，如果不存在则返回null
     */
    private DynamicObject findPreviousCycle(List<DynamicObject> allPerfManagerList, Date currentDate) {
        if (allPerfManagerList == null || allPerfManagerList.isEmpty() || currentDate == null) {
            return null;
        }

        LocalDateTime currentLocalDate = DateUtil.toLocalDateTime(currentDate);

        return allPerfManagerList.stream()
                .filter(Objects::nonNull)
                .filter(perfManager -> {
                    Date beginYear = perfManager.getDate(PerfManagerFormConstant.NCKD_BEGINYEAR);
                    if (beginYear != null) {
                        LocalDateTime beginYearLocal = DateUtil.toLocalDateTime(beginYear);
                        return beginYearLocal.isBefore(currentLocalDate);
                    }
                    return false;
                })
                .max((perf1, perf2) -> {
                    LocalDateTime begin1 = DateUtil.toLocalDateTime(perf1.getDate(PerfManagerFormConstant.NCKD_BEGINYEAR));
                    LocalDateTime begin2 = DateUtil.toLocalDateTime(perf2.getDate(PerfManagerFormConstant.NCKD_BEGINYEAR));
                    return begin1.compareTo(begin2);
                })
                .orElse(null);
    }

    @Override
    public void endOperationTransaction(EndOperationTransactionArgs e) {
        PerfManagerHelper.markAsCurrentNewest(personBeginYearMap.keySet(),null);

        //上一周期标记为“已结束”并设置“实际结束时间” begin
        Set<Long> personIds = new HashSet<>();
        for (DynamicObject dataEntity : e.getDataEntities()) {
            DynamicObject person = dataEntity.getDynamicObject(FormConstant.NCKD_PERSON);
            person = person == null ? dataEntity.getDynamicObject(FormConstant.NCKD_EMPPOSORGREL).getDynamicObject(FormConstant.EMPLOYEE_KEY) : person;
            long personId = person.getLong(FormConstant.ID_KEY);
            personIds.add(personId);
        }


        Boolean isCycleGenerate = ConvertUtil.toBoolean(this.getOption().getVariableValue("cyclegenerate",StringUtils.EMPTY),Boolean.FALSE);
        Boolean isUpdate = ConvertUtil.toBoolean(this.getOption().getVariableValue("isUpdate",StringUtils.EMPTY),Boolean.FALSE);
        DynamicObject[] beforeBeginYearList = null;
        if(!isUpdate){
            beforeBeginYearList = PerfManagerHelper.getByPersonId(personIds, null);
        }
        List<DynamicObject> updatePerManager = new ArrayList<>();
        List<DynamicObject> updateDataEntity = new ArrayList<>();
        for (DynamicObject dataEntity : e.getDataEntities()) {
            long id = dataEntity.getLong(FormConstant.ID_KEY);
            DynamicObject person = dataEntity.getDynamicObject(FormConstant.NCKD_PERSON);
            person = person == null ? dataEntity.getDynamicObject(FormConstant.NCKD_EMPPOSORGREL).getDynamicObject(FormConstant.EMPLOYEE_KEY) : person;
            dataEntity.set(FormConstant.NCKD_PERSON, person);
            LocalDateTime beginYear = DateUtil.toLocalDateTime(dataEntity.getDate(PerfManagerFormConstant.NCKD_BEGINYEAR));
            LocalDateTime endYear = DateUtil.toLocalDateTime(dataEntity.getDate(PerfManagerFormConstant.NCKD_ENDYEAR));
            long personId = person.getLong(FormConstant.ID_KEY);

            if(!isUpdate) {
                //找出当前周期前还未结束的考核周期
                QFilter filter = null;
                if (id > 0) {
                    filter = new QFilter(FormConstant.ID_KEY, QCP.not_in, id);
                }
//                DynamicObject[] beforeBeginYear = PerfManagerHelper.getBeforeBeginYear(DateUtil.toDate(beginYear), Collections.singletonList(personId), filter);
                List<DynamicObject> beforeBeginYear = Arrays.stream(beforeBeginYearList)
                        .filter(obj -> {
                            Date dbBeginYear = obj.getDate(PerfManagerFormConstant.NCKD_BEGINYEAR);
                            Long dbPersonId = obj.getDynamicObject(FormConstant.NCKD_PERSON).getLong(FormConstant.ID_KEY);
                            Long dbId = obj.getLong(FormConstant.ID_KEY);
                            String theStatus = obj.getString(PerfManagerFormConstant.NCKD_THESTATUS);
                            return dbBeginYear != null && dbBeginYear.compareTo(DateUtil.toDate(beginYear)) <= 0 && dbPersonId.equals(personId) && !dbId.equals(id) && (theStatus.equalsIgnoreCase(EnableEnum.YES.getCode()));
                        })
                        .collect(Collectors.toList());
                if (!beforeBeginYear.isEmpty()) {
//                    DynamicObject[] allPerfManagerArray = PerfManagerHelper.getByPersonId(Collections.singletonList(personId), filter);
                    List<DynamicObject> allPerfManagerList = Arrays.stream(beforeBeginYearList)
                            .filter(obj -> {
                                Long dbPersonId = obj.getDynamicObject(FormConstant.NCKD_PERSON).getLong(FormConstant.ID_KEY);
                                Long dbId = obj.getLong(FormConstant.ID_KEY);
                                return  dbPersonId.equals(personId) && !dbId.equals(id);
                            })
                            .collect(Collectors.toList());
                    allPerfManagerList.add(dataEntity);
                    for (DynamicObject lastPerfManager : beforeBeginYear) {
                        lastPerfManager.set(PerfManagerFormConstant.NCKD_THESTATUS, "3");
                        //找到当前周期的下一周期
                        Date currentBeginYear = lastPerfManager.getDate(PerfManagerFormConstant.NCKD_BEGINYEAR);
                        Date currentEndYear = lastPerfManager.getDate(PerfManagerFormConstant.NCKD_ENDYEAR);

                        DynamicObject nextCycle = findNextCycle(allPerfManagerList, currentBeginYear);
                        if (nextCycle != null) {
                            // 获取下一周期的开始年份
                            Date nextBeginYear = nextCycle.getDate(PerfManagerFormConstant.NCKD_BEGINYEAR);
                            LocalDateTime nextBeginLocalDateTime = DateUtil.toLocalDateTime(nextBeginYear);
                            // 计算预期的实际结束年份：下一周期开始时间-1年
                            LocalDateTime expectedActEndYear = DateUtil.minusYears(nextBeginLocalDateTime, 1);
                            LocalDateTime currentEndLocalDateTime = DateUtil.toLocalDateTime(currentEndYear);
                            // 如果预期结束时间大于等于当前周期的结束时间，说明中间有断层
                            // 则实际结束时间设置为当前周期的结束时间
                            // 否则设置为预期的实际结束时间（下一周期开始时间-1年）
                            LocalDateTime actEndYear = expectedActEndYear.isAfter(currentEndLocalDateTime) ?
                                    currentEndLocalDateTime : expectedActEndYear;
                            lastPerfManager.set(PerfManagerFormConstant.NCKD_ACTENDYEAR, DateUtil.toDate(actEndYear));
                        } else {
                            // 如果没有找到下一周期，则实际结束时间设置为当前周期的结束时间
                            lastPerfManager.set(PerfManagerFormConstant.NCKD_ACTENDYEAR, currentEndYear);
                        }
                        String str = isCycleGenerate ? "周期生成" : "手动/导入新增周期";
                        lastPerfManager.set(PerfManagerFormConstant.NCKD_WHYEND, StrFormatter.format("{}（{}~{}），系统自动结束前周期", str, beginYear.getYear(), endYear.getYear()));
                        updatePerManager.add(lastPerfManager);
                    }
                    //找到当前周期的上一周期
                    DynamicObject previousCycle = findPreviousCycle(allPerfManagerList, DateUtil.toDate(beginYear));
                    if (previousCycle != null) {
                        dataEntity.set(PerfManagerFormConstant.NCKD_LASTPERFMANAGER, previousCycle);
                        updateDataEntity.add(dataEntity);
                    }
                }
            }

        }
        if(!updatePerManager.isEmpty()) {
            DynamicObject[] lastPerfManagerArray = updatePerManager.toArray(new DynamicObject[0]);
            SaveServiceHelper.update(lastPerfManagerArray);
        }
        if(!updateDataEntity.isEmpty()) {
            //如果跟上面更新的是同一条，则需要将上面更新的字段赋给当前数据实体。不然上面更新的字段将丢失
            for (DynamicObject dynamicObject : updateDataEntity) {
                long id = dynamicObject.getLong(FormConstant.ID_KEY);
                for (DynamicObject object : updatePerManager) {
                    long id1 = object.getLong(FormConstant.ID_KEY);
                    if(id == id1){
                        dynamicObject.set(PerfManagerFormConstant.NCKD_THESTATUS, object.get(PerfManagerFormConstant.NCKD_THESTATUS));
                        dynamicObject.set(PerfManagerFormConstant.NCKD_ACTENDYEAR, object.get(PerfManagerFormConstant.NCKD_ACTENDYEAR));
                        dynamicObject.set(PerfManagerFormConstant.NCKD_WHYEND, object.get(PerfManagerFormConstant.NCKD_WHYEND));
                    }
                }
            }
            SaveServiceHelper.update(updateDataEntity.toArray(new DynamicObject[0]));
        }
        //上一周期标记为“已结束”并设置“实际结束时间” end
    }

    private boolean showInteractionMessage(String confirMmsg) {
        //交互式操作提示
        // 检查是否为回调：避免死循环
        String confirmResultString = this.getOption().getVariableValue(OperateOptionConst.INTERACTIONCONFIRMRESULT, "");
        InteractionConfirmResult confirmResult = InteractionConfirmResult.fromJsonString(confirmResultString);
        if (confirmResult.getResults().containsKey(INTERACTION_SPONORE)) {
            // 已是回调，直接返回结果
            MessageBoxResult result = MessageBoxResult.valueOf(confirmResult.getResults().get(INTERACTION_SPONORE));
            return result == MessageBoxResult.Yes;
        }

        // 首次执行：抛出交互异常
        InteractionContext interactionContext = new InteractionContext();
        interactionContext.setSimpleMessage("存在【未结束】的考核周期");
        OperateErrorInfo errorInfo = new OperateErrorInfo();
        errorInfo.setMessage(StrFormatter.format("检测到本次新增的人员中存在【未结束】的考核周期，新周期新增成功后会自动结束上一周期，并将上一周期结束时间更新为当前新周期开始年前一年。{}", confirMmsg));
        errorInfo.setLevel(ErrorLevel.Warning);

        Map<String, String> custInfos = new HashMap<>();
        custInfos.put("source", "business validation");
        custInfos.put("validator", "SampleValidator");
        errorInfo.setErrorCustInfos(custInfos);

        interactionContext.addOperateInfo(errorInfo);
        throw new KDInteractionException(INTERACTION_SPONORE, interactionContext);
    }

    /**
     * 获取日期列表中的重复年份
     *
     * @param dateList 日期列表
     * @return 重复年份的字符串列表
     */
    public static List<String> getDuplicateYears(List<Date> dateList) {
        if (dateList == null || dateList.isEmpty()) {
            return Collections.emptyList();
        }

        Map<Integer, Long> yearCountMap = dateList.stream()
                .filter(Objects::nonNull)
                .map(date -> DateUtil.getYear(DateUtil.toLocalDateTime(date)))
                .collect(Collectors.groupingBy(year -> year, Collectors.counting()));

        return yearCountMap.entrySet().stream()
                .filter(entry -> entry.getValue() > 1)
                .map(entry -> String.valueOf(entry.getKey()))
                .collect(Collectors.toList());
    }

    public static class PersonPerfInfo {
        private  Long id;
        private final DynamicObject person;
        private final DynamicObject empPosOrgRel;
        private final DynamicObject adminOrg;
        private final LocalDateTime beginYear;
        private final LocalDateTime endYear;
        private final String description;
        private int dataEntityIndex;
        private DynamicObjectCollection entrys;
        private String whyEnd;
        private LocalDateTime actEndYear;


        public PersonPerfInfo(DynamicObject person,DynamicObject empPosOrgRel,DynamicObject adminOrg, Date beginYear, Date endYear, String description) {
            this.person = person;
            this.empPosOrgRel = empPosOrgRel;
            this.adminOrg = adminOrg;
            this.beginYear = DateUtil.toLocalDateTime(beginYear);
            this.endYear = DateUtil.toLocalDateTime(endYear);
            this.description = description;
        }

        public PersonPerfInfo(DynamicObject person, DynamicObject empPosOrgRel,DynamicObject adminOrg, Date beginYear, Date endYear, String description, int dataEntityIndex) {
            this.person = person;
            this.empPosOrgRel = empPosOrgRel;
            this.adminOrg = adminOrg;
            this.beginYear = DateUtil.toLocalDateTime(beginYear);
            this.endYear = DateUtil.toLocalDateTime(endYear);
            this.description = description;
            this.dataEntityIndex = dataEntityIndex;
        }

        public PersonPerfInfo(DynamicObject person, DynamicObject empPosOrgRel,DynamicObject adminOrg, Date beginYear, Date endYear, String description, int dataEntityIndex, DynamicObjectCollection entrys) {
            this.person = person;
            this.empPosOrgRel = empPosOrgRel;
            this.adminOrg = adminOrg;
            this.beginYear = DateUtil.toLocalDateTime(beginYear);
            this.endYear = DateUtil.toLocalDateTime(endYear);
            this.description = description;
            this.dataEntityIndex = dataEntityIndex;
            this.entrys = entrys;
        }

        public LocalDateTime getBeginYear() {
            return beginYear;
        }

        public int getDataEntityIndex() {
            return dataEntityIndex;
        }

        public String getDescription() {
            return description;
        }

        public LocalDateTime getEndYear() {
            return endYear;
        }

        public DynamicObject getPerson() {
            return person;
        }

        public DynamicObject getEmpPosOrgRel() {
            return empPosOrgRel;
        }

        public DynamicObjectCollection getEntrys() {
            return entrys;
        }

        public DynamicObject getAdminOrg() {
            return adminOrg;
        }
        public Long getId() {
            return id;
        }
        public void setId(Long id) {
            this.id = id;
        }

        public String getWhyEnd() {
            return whyEnd;
        }

        public void setWhyEnd(String whyEnd) {
            this.whyEnd = whyEnd;
        }

        public LocalDateTime getActEndYear() {
            return actEndYear;
        }

        public void setActEndYear(LocalDateTime actEndYear) {
            this.actEndYear = actEndYear;
        }
    }

    /**
     * 从日期对象中提取年份
     *
     * @param date 日期对象
     * @return 年份
     */
    private int getYearFromDate(Object date) {
        if (date == null) {
            return 0;
        }
        if (date instanceof LocalDate) {
            return ((LocalDate) date).getYear();
        }
        // 如果是其他日期类型，可以添加相应的处理逻辑
        return 0;
    }
}
