package nckd.jxccl.hr.psms.helper;

import kd.bos.common.enums.EnableEnum;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.dataentity.entity.DynamicObjectCollection;
import kd.bos.orm.query.QCP;
import kd.bos.orm.query.QFilter;
import kd.bos.servicehelper.BusinessDataServiceHelper;
import kd.bos.servicehelper.QueryServiceHelper;
import kd.bos.servicehelper.operation.SaveServiceHelper;
import nckd.jxccl.base.common.constant.FormConstant;
import nckd.jxccl.base.common.utils.QueryFieldBuilder;
import nckd.jxccl.base.orm.helper.QFilterCommonHelper;
import nckd.jxccl.hr.psms.common.PerfRankMgmtConstant;
import nckd.jxccl.hr.psms.common.PositionStructureConstant;
import nckd.jxccl.hr.psms.common.bo.PositionAppointmentBO;
import nckd.jxccl.hr.psms.helper.data.JobLevelRuleConfig;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 职位体系帮助类
 *
 * @author W.Y.C
 * @version 1.0
 * @date 2025/9/13 14:07
 */
public class PositionFileHelper {


    /**
     * 判断是否已经初定
     * @param personId 人员ID
     * @return: boolean
     * @author W.Y.C
     * @date: 2025/09/13 15:40
     */
    public static boolean isInitial(Long personId) {
        QFilter filter = new QFilter(String.join(".", FormConstant.NCKD_PERSON, FormConstant.ID_KEY), QCP.equals, personId)
                .and(new QFilter(PositionStructureConstant.NCKD_DISABLE,QCP.equals, EnableEnum.NO.getCode()))
                .and(new QFilter(PositionStructureConstant.NCKD_FIRSTRANK,QCP.equals,EnableEnum.YES.getCode()));
        return QueryServiceHelper.exists(PositionStructureConstant.PERSONPOSFILE_ENTITYID, new QFilter[]{filter});
    }

    /**
     * 获取最新人员档案
     * @param personId 人员ID
     * @return: kd.bos.dataentity.entity.DynamicObject[]
     * @author W.Y.C
     * @date: 2025/10/20 21:56
     */
    public static DynamicObject[] getNewestPersonPosFileByPerson(Long... personId) {
        QFilter filer = new QFilter(String.join(".", FormConstant.NCKD_PERSON, FormConstant.ID_KEY), QCP.in, personId)
                .and(PositionStructureConstant.NCKD_DISABLE, QCP.equals, EnableEnum.NO.getCode())
                .and(PositionStructureConstant.NCKD_ISCURRENTNEWEST, QCP.equals, EnableEnum.YES.getCode());
        QueryFieldBuilder queryFieldBuilder = QueryFieldBuilder.create()
                .add(FormConstant.ID_KEY)
                .add(PositionStructureConstant.NCKD_BEGINDATE)
                .add(PositionStructureConstant.NCKD_EXECUTEYEAR)
                .add(PositionStructureConstant.NCKD_TYPESTATE)
                .add(PositionStructureConstant.NCKD_FIRSTRANK)
                .add(PositionStructureConstant.NCKD_DIPLOMASCORE)
                .add(PositionStructureConstant.NCKD_RANKSCORE)
                .add(PositionStructureConstant.NCKD_JOBSTATUSSCORE)
                .addIdNumberName(PositionStructureConstant.NCKD_APPRAISALRESULT)
                .addIdNumberName(PositionStructureConstant.NCKD_PERSON)
                .add(PositionStructureConstant.NCKD_ALLOWANCERANKPCT)
                .add(PositionStructureConstant.NCKD_ALLOWANCERANKSEL)
                .add(PositionStructureConstant.NCKD_ALLOWANCERANKMARK)
                .add(PositionStructureConstant.NCKD_ALLSUMSCORE)
                .add(PositionStructureConstant.NCKD_SUMSCORE)
                .add(PositionStructureConstant.NCKD_JOBLEVELHR)
                .add(PositionStructureConstant.NCKD_RANKNAME)
                .addIdNumberName(PositionStructureConstant.NCKD_PROTITLELEVEL)
                .add(PositionStructureConstant.NCKD_JOBSTATUSNAME)
                .addIdNumberName(PositionStructureConstant.NCKD_OCPQUALLEVEL)
                .addIdNumberNameWithExtras(
                        new String[]{PositionStructureConstant.NCKD_JOBLEVELHR},
                        FormConstant.JOBLEVELSEQ
                )
                .addIdNumberNameWithExtras(
                        new String[]{PositionStructureConstant.NCKD_DIPLOMA},
                        FormConstant.NCKD_SCORE
                )
                .addIdNumberName(PositionStructureConstant.NCKD_JOBSEQHR);
        DynamicObject[] load = BusinessDataServiceHelper.load(
                PositionStructureConstant.PERSONPOSFILE_ENTITYID,
                queryFieldBuilder.buildSelect(),
                new QFilter[]{filer},
                queryFieldBuilder.buildOrder()
        );
        return load;
    }

    /**
     * 根据人员和状态过滤职位档案
     * @param personId 人员ID
     * @param typeState 类型状态（新入职人员初定1;在职人员初定2;年度调整3;职位调动4;管理序列的聘任5;高级职称的聘任6）
     * @param adjustType 调整类别（升级2;保级1;降级0;首次聘任3;序列变化4;聘任下调5;总分不足6;无聘任7;无考核结果8）
     * @param otherFilter
     * @return: kd.bos.dataentity.entity.DynamicObject[]
     * @author W.Y.C
     * @date: 2025/09/23 21:08
     */

    public static DynamicObject[] getPersonPosFileByPersonAndState(Long personId,String[] typeState,String[] adjustType,QFilter otherFilter) {
        return getPersonPosFileByPersonAndState(personId,typeState,adjustType,otherFilter, new String[0]);
    }

    /**
     * 根据人员和状态过滤职位档案
     * @param personId 人员ID
     * @param typeState 类型状态（新入职人员初定1;在职人员初定2;年度调整3;职位调动4;管理序列的聘任5;高级职称的聘任6）
     * @param adjustType 调整类别（升级2;保级1;降级0;首次聘任3;序列变化4;聘任下调5;总分不足6;无聘任7;无考核结果8）
     * @param otherFilter
     * @return: kd.bos.dataentity.entity.DynamicObject[]
     * @author W.Y.C
     * @date: 2025/09/23 21:08
     */

    public static DynamicObject[] getPersonPosFileByPersonAndState(Long personId,String[] typeState,String[] adjustType,QFilter otherFilter,String... orderBy) {

        QFilter filer = new QFilter(String.join(".", FormConstant.NCKD_PERSON, FormConstant.ID_KEY), QCP.equals, personId)
                .and(new QFilter(PositionStructureConstant.NCKD_DISABLE, QCP.equals, EnableEnum.NO.getCode()));
        if(typeState != null){
            filer.and(new QFilter(PositionStructureConstant.NCKD_TYPESTATE, QCP.in, typeState));
        }
        if(adjustType != null){
            filer.and(new QFilter(PositionStructureConstant.NCKD_ADJUSSTATUS, QCP.in, adjustType));
        }
        if(otherFilter != null){
            filer.and(otherFilter);
        }
        QueryFieldBuilder queryFieldBuilder = QueryFieldBuilder.create()
                .add(FormConstant.ID_KEY)
                .add(PositionStructureConstant.NCKD_BEGINDATE)
                .add(PositionStructureConstant.NCKD_EXECUTEYEAR)
                .add(PositionStructureConstant.NCKD_TYPESTATE)
                .add(PositionStructureConstant.NCKD_FIRSTRANK)
                .add(PositionStructureConstant.NCKD_DIPLOMASCORE)
                .add(PositionStructureConstant.NCKD_RANKSCORE)
                .add(PositionStructureConstant.NCKD_JOBSTATUSSCORE)
                .addIdNumberName(PositionStructureConstant.NCKD_APPRAISALRESULT)
                .add(PositionStructureConstant.NCKD_ALLOWANCERANKPCT)
                .add(PositionStructureConstant.NCKD_ALLOWANCERANKSEL)
                .add(PositionStructureConstant.NCKD_ALLOWANCERANKMARK)
                .add(PositionStructureConstant.NCKD_ALLSUMSCORE)
                .add(PositionStructureConstant.NCKD_SUMSCORE)
                .add(PositionStructureConstant.NCKD_JOBLEVELHR)
                .add(PositionStructureConstant.NCKD_RANKNAME)
                .addIdNumberName(PositionStructureConstant.NCKD_PROTITLELEVEL)
                .add(PositionStructureConstant.NCKD_JOBSTATUSNAME)
                .addIdNumberName(PositionStructureConstant.NCKD_OCPQUALLEVEL)
                .addIdNumberNameWithExtras(
                        new String[]{PositionStructureConstant.NCKD_JOBLEVELHR},
                        FormConstant.JOBLEVELSEQ
                )
                .addIdNumberNameWithExtras(
                        new String[]{PositionStructureConstant.NCKD_DIPLOMA},
                        FormConstant.NCKD_SCORE
                )
                .addIdNumberName(PositionStructureConstant.NCKD_JOBSEQHR);
        if(orderBy != null && orderBy.length > 0){
            queryFieldBuilder.orderBy(orderBy);
        }else{
            queryFieldBuilder.orderDesc(PositionStructureConstant.NCKD_BEGINDATE);
        }


        return BusinessDataServiceHelper.load(
                PositionStructureConstant.PERSONPOSFILE_ENTITYID,
                queryFieldBuilder.buildSelect(),
                new QFilter[]{filer},
                queryFieldBuilder.buildOrder()
        );


    }

    /**
     * 获取人员最新的职位档案（初定 或者 （年度调整 并且 已生效） 或者 (动态调整) 生效时间为最新的那一条）
     * @param personId 人员ID
     * @return: kd.bos.dataentity.entity.DynamicObject
     * @author W.Y.C
     * @date: 2025/09/20 20:09
     */
    public static DynamicObject getLatsPersonPosFileByPerson(Long personId) {
        List<DynamicObject> latsPersonPosFileByPerson = getLatsPersonPosFileByPerson(null, personId);
        return !latsPersonPosFileByPerson.isEmpty() ? latsPersonPosFileByPerson.get(0) : null;
    }

    /**
     * 获取人员最新的职位档案（初定 或者 （年度调整 并且 已生效） 或者 (动态调整) 生效时间为最新的那一条）
     * @param personId 人员ID
     * @param otherFilter 其他条件
     * @return: kd.bos.dataentity.entity.DynamicObject
     * @author W.Y.C
     * @date: 2025/10/13 11:10
     */
    public static DynamicObject getLatsPersonPosFileByPerson(Long personId,QFilter otherFilter) {
        List<DynamicObject> latsPersonPosFileByPerson = getLatsPersonPosFileByPerson(otherFilter,personId);
        return !latsPersonPosFileByPerson.isEmpty() ? latsPersonPosFileByPerson.get(0) : null;
    }

    /**
     * 获取该人员最新的职位档案（初定 或者 （年度调整 并且 已生效） 或者 (动态调整) 生效时间为最新的那一条）
     * @param personIds 人员ID
     * @param otherFilter 其他条件
     * @return: kd.bos.dataentity.entity.DynamicObject 树形结构
     * @author W.Y.C
     * @date: 2025/09/20 20:09
     */
    public static List<DynamicObject> getLatsPersonPosFileByPerson(QFilter otherFilter,Long... personIds) {
        QFilter filer = new QFilter(String.join(".", FormConstant.NCKD_PERSON, FormConstant.ID_KEY), QCP.in, personIds)
                // .and(new QFilter(PositionStructureConstant.NCKD_ISCURRENTNEWEST, QCP.equals, EnableEnum.YES.getCode()))
                .and(new QFilter(PositionStructureConstant.NCKD_DISABLE, QCP.equals, EnableEnum.NO.getCode()))
                // 只有状态为：【初定】、【年度调整】和【动态调整】的职位档案才是有效档案；
                // 条件：（初定 或者 （年度调整 并且 已生效） 或者 (动态调整 并且 已生效)）
                .and(
                        new QFilter(PositionStructureConstant.NCKD_FIRSTRANK, QCP.equals, EnableEnum.YES.getCode())
                                .or(
                                        new QFilter(PositionStructureConstant.NCKD_TYPESTATE, QCP.equals, "3")
                                                .and(new QFilter(PositionStructureConstant.NCKD_ADJUSSTATUS, QCP.in, new String[]{"1", "2"})
                                                )
                                )
                                .or(
                                        new QFilter(PositionStructureConstant.NCKD_TYPESTATE, QCP.equals, "4")
                                )
                );
        if(otherFilter != null){
            filer.and(otherFilter);
        }
        QueryFieldBuilder queryFieldBuilder = QueryFieldBuilder.create()
                .add(FormConstant.ID_KEY)
                .addIdNumberName(FormConstant.NCKD_PERSON)
                .add(PositionStructureConstant.NCKD_BEGINDATE)
                .add(PositionStructureConstant.NCKD_EXECUTEYEAR)
                .add(PositionStructureConstant.NCKD_TYPESTATE)
                .add(PositionStructureConstant.NCKD_FIRSTRANK)
                .add(PositionStructureConstant.NCKD_DIPLOMASCORE)
                .add(PositionStructureConstant.NCKD_RANKSCORE)
                .add(PositionStructureConstant.NCKD_JOBSTATUSSCORE)
                .addIdNumberName(PositionStructureConstant.NCKD_APPRAISALRESULT)
                .add(PositionStructureConstant.NCKD_ALLOWANCERANKPCT)
                .add(PositionStructureConstant.NCKD_ALLOWANCERANKSEL)
                .add(PositionStructureConstant.NCKD_ALLOWANCERANKMARK)
                .add(PositionStructureConstant.NCKD_ALLSUMSCORE)
                .add(PositionStructureConstant.NCKD_SUMSCORE)
                .add(PositionStructureConstant.NCKD_JOBLEVELHR)
                .add(PositionStructureConstant.NCKD_RANKNAME)
                .addIdNumberName(PositionStructureConstant.NCKD_PROTITLELEVEL)
                .add(PositionStructureConstant.NCKD_JOBSTATUSNAME)
                .addIdNumberName(PositionStructureConstant.NCKD_OCPQUALLEVEL)
                .addIdNumberNameWithExtras(
                        new String[]{PositionStructureConstant.NCKD_JOBLEVELHR},
                        FormConstant.JOBLEVELSEQ
                )
                // 学历
                .addIdNumberNameWithExtras(
                        new String[]{PositionStructureConstant.NCKD_DIPLOMA},
                        FormConstant.NCKD_SCORE
                )
                // 职位序列
                .addIdNumberName(PositionStructureConstant.NCKD_JOBSEQHR)
                // 岗位
                .addIdNumberName(PositionStructureConstant.NCKD_POSITIONHR)
                //其他字段
                .add(PositionStructureConstant.NCKD_RESULTSCORE)
                //.add(PositionStructureConstant.NCKD_DISABLE)
                .add(PositionStructureConstant.NCKD_ADJUSTTYPE)
                .add(PositionStructureConstant.NCKD_ADJUSTINT)
                .add(PositionStructureConstant.NCKD_ALLOWANCERANK)
                .add(PositionStructureConstant.NCKD_TOPRANK)
                .add(PositionStructureConstant.NCKD_TOPRANKPERCENT)

                /*.add(PositionStructureConstant.KEY_NCKD_CAUSEREMARK)
                .add(PositionStructureConstant.NCKD_WHYDIPLOMASCORE)*/

                .add(PositionStructureConstant.NCKD_ISCURRENTNEWEST)
                .add(PositionStructureConstant.NCKD_LASTPERSONPOSFILE)
                .add(PositionStructureConstant.NCKD_EMPLOYMENTSTATUS)
                .add(PositionStructureConstant.NCKD_EMPLOYMENTYEARS)
                .add(PositionStructureConstant.NCKD_ORGINSSCORE)
                .add(PositionStructureConstant.NCKD_LYRCONTRIBSCORE)
                .add(PositionStructureConstant.NCKD_ENDDATE)
                .add(PositionStructureConstant.NCKD_APPOINTSTATUS)
                .add(PositionStructureConstant.NCKD_ADJUSSTATUS)
                .add(PositionStructureConstant.NCKD_YEARSCORESUMA)
                .add(PositionStructureConstant.NCKD_YEARSCORESUMB)
                .add(PositionStructureConstant.NCKD_YEARSCORESUMC)
                .add(PositionStructureConstant.NCKD_YEARSCORESUMD)
                .add(PositionStructureConstant.NCKD_YEARSCORESUME)
                .add(PositionStructureConstant.NCKD_YEARSCORESUMF)
                .add(PositionStructureConstant.NCKD_YEARSCORESUMG)
                .add(PositionStructureConstant.NCKD_YEARSCORESUMH)
                .add(PositionStructureConstant.NCKD_YEARSCORESUMI)
                .add(PositionStructureConstant.NCKD_ALLYEARSCORESUM)
                .add(PositionStructureConstant.NCKD_ADDYCONTRIBSCORE)
                //排序
                .orderDesc(PositionStructureConstant.NCKD_BEGINDATE);

        DynamicObject[] load = BusinessDataServiceHelper.load(
                PositionStructureConstant.PERSONPOSFILE_ENTITYID,
                queryFieldBuilder.buildSelect(),
                new QFilter[]{filer},
                queryFieldBuilder.buildOrder()
        );

        //只取每个人员最新记录（根据NCKD_BEGINDATE）
        Map<Long, DynamicObject> latestRecordMap = new HashMap<>();
        for (DynamicObject dynamicObject : load) {
            DynamicObject person = dynamicObject.getDynamicObject(FormConstant.NCKD_PERSON);
            Date beginDate = dynamicObject.getDate(PositionStructureConstant.NCKD_BEGINDATE);
            long personId = person.getLong(FormConstant.ID_KEY);
            // 如果map中没有该personId的记录，或者当前记录的beginDate更晚，则更新记录
            if (!latestRecordMap.containsKey(personId) ||
                    beginDate.after(latestRecordMap.get(personId).getDate(PositionStructureConstant.NCKD_BEGINDATE))) {
                latestRecordMap.put(personId, dynamicObject);
            }
        }
        return new ArrayList<>(latestRecordMap.values());

    }

    /**
     * 获取首次初定的职位档案
     * @param personId 人员ID
     * @return: kd.bos.dataentity.entity.DynamicObject
     * @author W.Y.C
     * @date: 2025/09/20 18:57
     */

    public static DynamicObject getFirstRank(Long personId) {
        QFilter filer = new QFilter(String.join(".", FormConstant.NCKD_PERSON, FormConstant.ID_KEY), QCP.equals, personId)
                .and(new QFilter(PositionStructureConstant.NCKD_DISABLE, QCP.equals, EnableEnum.NO.getCode()))
                .and(new QFilter(PositionStructureConstant.NCKD_FIRSTRANK, QCP.equals, EnableEnum.YES.getCode()));
        QueryFieldBuilder queryFieldBuilder = QueryFieldBuilder.create()
                .add(FormConstant.ID_KEY)
                .add(PositionStructureConstant.NCKD_BEGINDATE)
                .add(PositionStructureConstant.NCKD_EXECUTEYEAR)
                .add(PositionStructureConstant.NCKD_TYPESTATE)
                .add(PositionStructureConstant.NCKD_FIRSTRANK)
                .add(PositionStructureConstant.NCKD_DIPLOMASCORE)
                .add(PositionStructureConstant.NCKD_RANKSCORE)
                .add(PositionStructureConstant.NCKD_JOBSTATUSSCORE)
                .addIdNumberName(PositionStructureConstant.NCKD_APPRAISALRESULT)
                .add(PositionStructureConstant.NCKD_ALLOWANCERANKPCT)
                .add(PositionStructureConstant.NCKD_ALLOWANCERANKSEL)
                .add(PositionStructureConstant.NCKD_ALLOWANCERANKMARK)
                .add(PositionStructureConstant.NCKD_ALLSUMSCORE)
                .add(PositionStructureConstant.NCKD_SUMSCORE)
                .add(PositionStructureConstant.NCKD_JOBLEVELHR)
                .add(PositionStructureConstant.NCKD_RANKNAME)
                .addIdNumberName(PositionStructureConstant.NCKD_PROTITLELEVEL)
                .add(PositionStructureConstant.NCKD_JOBSTATUSNAME)
                .addIdNumberName(PositionStructureConstant.NCKD_OCPQUALLEVEL)
                .addIdNumberNameWithExtras(
                        new String[]{PositionStructureConstant.NCKD_JOBLEVELHR},
                        FormConstant.JOBLEVELSEQ
                )
                .addIdNumberNameWithExtras(
                        new String[]{PositionStructureConstant.NCKD_DIPLOMA},
                        FormConstant.NCKD_SCORE
                )
                .addIdNumberName(PositionStructureConstant.NCKD_JOBSEQHR)
                .orderDesc(PositionStructureConstant.NCKD_BEGINDATE);

        DynamicObject[] load = BusinessDataServiceHelper.load(
                PositionStructureConstant.PERSONPOSFILE_ENTITYID,
                queryFieldBuilder.buildSelect(),
                new QFilter[]{filer},
                queryFieldBuilder.buildOrder()
        );
        return load.length > 0 ? load[0] : null;
    }

    /**
     * 根据时间获取员工任职（所属公司、岗位、职位序列）、聘任信息（职称等级、技能等级）和学历
     * @param personId 员工id
     * @param date 需查询的时间（任职经历：查询该时间范围内的任职。职称等级或技能等级：查询该时间聘任的等级。学历：查询毕业时间小于等于该时间的学历）
     * @return: kd.bos.dataentity.entity.DynamicObject 平铺结构（PlainObject）
     * @author W.Y.C
     * @date: 2025/09/17 10:27
     */
    public static PositionAppointmentBO positionAppointmentQuery(Long personId, Date date) {
        QueryFieldBuilder queryFieldBuilder = QueryFieldBuilder.create()
                .add(FormConstant.ID_KEY)
                .addIdNumberName(FormConstant.EMPLOYEE_KEY)
                // 组织分配
                .addGroup(new String[]{FormConstant.ASSIGNMENT}, FormConstant.ID_KEY)
                // 所属公司
                .addIdNumberName(FormConstant.COMPANY_KEY)
                // 行政组织（部门）
                .addIdNumberName(FormConstant.ADMINORG)
                // 岗位
                .addIdNumberName(FormConstant.POSITION_KEY)
                // 职位序列
                .addIdNumberName(new String[]{FormConstant.HBPM_POSITIONHR, FormConstant.NCKD_JOBSEQ})
                // 服务年限
                .addGroup(new String[]{FormConstant.HRPI_PERSERLEN},
                        FormConstant.JOINCOMDATE_KEY,
                        FormConstant.FIRSTJOINCOMDATE_KEY
                )
                .orderDesc(FormConstant.STARTDATE)
                .orderDesc(FormConstant.ENDDATE);

        //获取时间范围内的任职信息
        QFilter filer = new QFilter(String.join(".", FormConstant.EMPLOYEE_KEY,FormConstant.ID_KEY),QCP.equals,personId)
                .and(new QFilter(String.join(".", FormConstant.IS_PRIMARY),QCP.equals,EnableEnum.YES.getCode()))
                .and(new QFilter(String.join(".", FormConstant.IS_DELETED),QCP.equals,EnableEnum.NO.getCode()))
                .and(new QFilter(String.join(".", FormConstant.ASSIGNMENT,FormConstant.IS_PRIMARY),QCP.equals,EnableEnum.YES.getCode()))
                .and(new QFilter(String.join(".", FormConstant.STARTDATE),QCP.less_equals,date))
                .and(new QFilter(String.join(".", FormConstant.ENDDATE),QCP.large_equals,date));


        // 1、查询任职经历（取调整时间范围内的主任职）
        DynamicObjectCollection empPosOrgRelDynamicObject = QueryServiceHelper.query(PositionStructureConstant.POSITIONAPPOINTMENTQUERY, 
                queryFieldBuilder.buildSelect(), 
                new QFilter[]{filer}, 
                queryFieldBuilder.buildOrder(), 
                1);

        // 2、查询学历（取毕业时间小于等于调整时间内的学历）
        QueryFieldBuilder perEduExpQueryFieldBuilder = QueryFieldBuilder.create()
                .addIdNumberName(FormConstant.EMPLOYEE_KEY)
                .addIdNumberNameWithExtras(
                        new String[]{FormConstant.EDUCATION_KEY},
                        FormConstant.NCKD_SCORE
                )
                .orderDesc(FormConstant.GRADUTIONDATE);
        QFilter perEduExpFilter = new QFilter(FormConstant.EMPLOYEE_KEY,QCP.equals,personId)
                .and(new QFilter(FormConstant.GRADUTIONDATE, QCP.less_equals,date))
                .and(new QFilter(FormConstant.GRADUTIONDATE, QCP.is_notnull,null))
                .and(new QFilter(FormConstant.ISHIGHESTDEGREE, QCP.equals,EnableEnum.YES.getCode()));
        DynamicObjectCollection perEduExpDynamicObject = QueryServiceHelper.query(
                FormConstant.HRPI_PEREDUEXP, perEduExpQueryFieldBuilder.buildSelect(), new QFilter[]{perEduExpFilter}, perEduExpQueryFieldBuilder.buildOrder(), 1);


        // 3、查询职称
        QueryFieldBuilder perProTitleQueryFieldBuilder = QueryFieldBuilder.create()
                .addIdNumberName(FormConstant.EMPLOYEE_KEY)
                .addGroup(new String[]{FormConstant.PROFESSIONAL_KEY}, FormConstant.NAME_KEY)
                .addIdNumberNameWithExtras(
                        new String[]{FormConstant.PROLEVEL_KEY},
                        FormConstant.NCKD_SCORE
                )
                .orderDesc("awardtime");
        QFilter perProTitleFilter = new QFilter(FormConstant.EMPLOYEE_KEY,QCP.equals,personId)
                .and(new QFilter("awardtime", QCP.less_equals,date))
                .and(new QFilter("awardtime", QCP.is_notnull,null))
                .and(new QFilter("iscompany", QCP.equals,EnableEnum.YES.getCode()));
        DynamicObjectCollection perProTitleDynamicObject = QueryServiceHelper.query(
                FormConstant.HRPI_PERPROTITLE, perProTitleQueryFieldBuilder.buildSelect(), new QFilter[]{perProTitleFilter}, perProTitleQueryFieldBuilder.buildOrder(), 1);

        // 4、查询技能
        QueryFieldBuilder perOcpQualQueryFieldBuilder = QueryFieldBuilder.create()
                .addGroup(new String[]{FormConstant.QUALIFICATION_KEY}, FormConstant.NAME_KEY)
                .addIdNumberNameWithExtras(
                        new String[]{FormConstant.QUALEVEL_KEY},
                        FormConstant.NCKD_SCORE
                )
            .orderDesc("registratedate");
        QFilter perOcpQualFilter = new QFilter(FormConstant.EMPLOYEE_KEY,QCP.equals,personId)
                .and(new QFilter("registratedate", QCP.less_equals,date))
                .and(new QFilter("registratedate", QCP.is_notnull,null))
                .and(new QFilter("ismajor", QCP.equals, EnableEnum.YES.getCode()));
        DynamicObjectCollection perOcpQualDynamicObject = QueryServiceHelper.query(
                FormConstant.HRPI_PEROCPQUAL, perOcpQualQueryFieldBuilder.buildSelect(), new QFilter[]{perOcpQualFilter}, perOcpQualQueryFieldBuilder.buildOrder(), 1);

        PositionAppointmentBO positionAppointmentBO = new PositionAppointmentBO();
        if (empPosOrgRelDynamicObject != null && !empPosOrgRelDynamicObject.isEmpty()) {
            positionAppointmentBO.setEmpPosOrgRel(empPosOrgRelDynamicObject.get(0));
        }
        if (perEduExpDynamicObject != null && !perEduExpDynamicObject.isEmpty()) {
            positionAppointmentBO.setPerEduExp(perEduExpDynamicObject.get(0));
        }
        if (perProTitleDynamicObject != null && !perProTitleDynamicObject.isEmpty()) {
            positionAppointmentBO.setPerProTitle(perProTitleDynamicObject.get(0));
        }
        if (perOcpQualDynamicObject != null && !perOcpQualDynamicObject.isEmpty()) {
            positionAppointmentBO.setPerOcpQual(perOcpQualDynamicObject.get(0));
        }

        //5.是否优秀生
        QueryFieldBuilder topStudentQueryFieldBuilder = QueryFieldBuilder.create().add(FormConstant.ID_KEY);
        QFilter topStudentFilter = new QFilter(FormConstant.EMPLOYEE_KEY,QCP.equals,personId)
                .and("nckd_honortype",QCP.is_notnull,null);
        DynamicObjectCollection topStudentDynamicObject = QueryServiceHelper.query("nckd_hrpi_topstudent", topStudentQueryFieldBuilder.buildSelect(), new QFilter[]{topStudentFilter});
        if(!topStudentDynamicObject.isEmpty()){
            positionAppointmentBO.setExcellent(true);
        }
        return positionAppointmentBO;
    }



    /**
     * 根据人员将所有IsCurrentNewest更新为非最新的
     * @param personId 人员ID（可传多个）
     * @return: void
     * @author W.Y.C
     * @date: 2025/09/28 21:18
     */
    public static void markAsNotCurrentNewest(Long... personId) {
        QFilter filter = new QFilter(String.join(".", FormConstant.NCKD_PERSON, FormConstant.ID_KEY), QCP.in, personId)
                .and(new QFilter(PositionStructureConstant.NCKD_DISABLE, QCP.equals, EnableEnum.NO.getCode()));
        QueryFieldBuilder queryField = QueryFieldBuilder.create()
                .add(FormConstant.ID_KEY)
                .add(PositionStructureConstant.NCKD_ISCURRENTNEWEST);
        DynamicObject[] personPosFileColl = BusinessDataServiceHelper.load(PositionStructureConstant.PERSONPOSFILE_ENTITYID,queryField.buildSelect(), new QFilter[]{filter});
        for (DynamicObject personPosFile : personPosFileColl) {
            personPosFile.set(PositionStructureConstant.NCKD_ISCURRENTNEWEST, Boolean.FALSE);
        }
        SaveServiceHelper.update(personPosFileColl);
    }

    /**
     * 将当前人员最新档案标记为最新的
     * @param personId 人员ID（可传多个）
     * @return: void
     * @author W.Y.C
     * @date: 2025/09/28 21:18
     */
    public static void markAsCurrentNewest(QFilter otherFilter,Long... personId) {
        List<DynamicObject> personPosFileColl = getLatsPersonPosFileByPerson(otherFilter, personId);
        DynamicObject[] updatePersonPosFileColl = new DynamicObject[personPosFileColl.size()];
        for (int i = 0; i < personPosFileColl.size(); i++) {
            DynamicObject dynamicObject = personPosFileColl.get(i);
            dynamicObject.set(PositionStructureConstant.NCKD_ISCURRENTNEWEST, Boolean.TRUE);
            updatePersonPosFileColl[i] = dynamicObject;
        }
        SaveServiceHelper.update(updatePersonPosFileColl);
    }

    /**
     * 获取升保降级条件配置
     * @return: kd.bos.dataentity.entity.DynamicObject
     * @author W.Y.C
     * @date: 2025/11/02 21:32
     */
    public static List<JobLevelRuleConfig> getLevelConditionConf() {
        return getLevelConditionConf(null);
    }

    /**
     * 获取升保降级条件配置
     * @return: kd.bos.dataentity.entity.DynamicObject
     * @author W.Y.C
     * @date: 2025/11/02 21:32
     */
    public static List<JobLevelRuleConfig> getLevelConditionConf(QFilter otherFilter) {
        // 查询条件：启用状态的规则，按职位序列和职级范围排序
        QFilter filter = QFilterCommonHelper.getEnableFilter()
                .and(QFilterCommonHelper.getValidDateFilter(FormConstant.NCKD_STARTDATE,FormConstant.NCKD_ENDDATE));
        if(otherFilter != null){
            filter = filter.and(otherFilter);
        }

        QueryFieldBuilder queryFieldBuilder = QueryFieldBuilder.create()
                .add(FormConstant.ID_KEY)
                .add(FormConstant.NAME_KEY)
                .add(FormConstant.DESCRIPTION_KEY)
                .addIdNumberName(FormConstant.NCKD_JOBSEQ)
                .addIdNumberNameWithExtras(new String[]{PerfRankMgmtConstant.NCKD_MINJOBLEVEL}, FormConstant.JOBLEVELSEQ)
                .addIdNumberNameWithExtras(new String[]{PerfRankMgmtConstant.NCKD_MAXJOBLEVEL}, FormConstant.JOBLEVELSEQ)
                .add(PerfRankMgmtConstant.NCKD_UPGRADETHRESHOLD)
                .add(PerfRankMgmtConstant.NCKD_DOWNGRADETHRESHOLD);



        DynamicObject[] dynamicObjects = BusinessDataServiceHelper.load(
                PerfRankMgmtConstant.LEVELCONDITIONCON_ENTITYID,
                queryFieldBuilder.buildSelect(),
                new QFilter[]{filter},
                queryFieldBuilder.buildOrder()
        );

        // 转换为实体对象列表
        List<JobLevelRuleConfig> ruleConfigs = new ArrayList<>();
        for (DynamicObject dynamicObject : dynamicObjects) {
            JobLevelRuleConfig config = new JobLevelRuleConfig();
            DynamicObject jobSeq = dynamicObject.getDynamicObject(FormConstant.NCKD_JOBSEQ);
            DynamicObject minJobLevel = dynamicObject.getDynamicObject(PerfRankMgmtConstant.NCKD_MINJOBLEVEL);
            DynamicObject maxJobLevel = dynamicObject.getDynamicObject(PerfRankMgmtConstant.NCKD_MAXJOBLEVEL);
            String name = dynamicObject.getString(FormConstant.NAME_KEY);
            String description = dynamicObject.getString(FormConstant.DESCRIPTION_KEY);
            int upGradeThreshold = dynamicObject.getInt(PerfRankMgmtConstant.NCKD_UPGRADETHRESHOLD);
            int downGradeThreshold = dynamicObject.getInt(PerfRankMgmtConstant.NCKD_DOWNGRADETHRESHOLD);
            config.setName(name);
            config.setDescription(description);
            config.setJobSeqNumber(jobSeq.getString(FormConstant.NUMBER_KEY));
            config.setMinJobLevel(minJobLevel);
            config.setMinJobLevelSeq(minJobLevel.getInt(FormConstant.JOBLEVELSEQ));
            config.setMaxJobLevel(maxJobLevel);
            config.setMaxJobLevelSeq(maxJobLevel != null ? maxJobLevel.getInt(FormConstant.JOBLEVELSEQ) : Integer.MAX_VALUE);
            config.setUpGradeThreshold(upGradeThreshold);
            config.setDownGradeThreshold(downGradeThreshold);
            ruleConfigs.add(config);
        }

        return ruleConfigs;
    }


}