1
0

4 Коммитууд bba080bb12 ... 0fcbcf8099

Эзэн SHA1 Мессеж Огноо
  wyc 0fcbcf8099 Merge branch 'refs/heads/feat-hr-psms_1.0' 1 өдөр өмнө
  wyc f71b5c89c6 feat(hr): 实现升保降级动态配置功能 1 өдөр өмнө
  wyc 08e32b0d6c feat(hr): 新增积分项目名次维度支持及有效期过滤 2 өдөр өмнө
  wyc 570ab4414c feat(hr): 实现新入职与在职人员初定导入插件- 新增 ScoreInitialImportPlugin 插件类,支持初定导入模板筛选 3 өдөр өмнө
22 өөрчлөгдсөн 924 нэмэгдсэн , 123 устгасан
  1. 2 0
      code/base/nckd-jxccl-base-common/src/main/java/nckd/jxccl/base/common/constant/FormConstant.java
  2. 20 0
      code/base/nckd-jxccl-base-helper/src/main/java/nckd/jxccl/base/orm/helper/QFilterCommonHelper.java
  3. 2 2
      code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/business/AnnualAdjustmentService.java
  4. 61 7
      code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/business/JobLevelCalculatorService.java
  5. 13 0
      code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/common/PerfRankMgmtConstant.java
  6. 182 62
      code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/helper/ContributionHelper.java
  7. 74 0
      code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/helper/PositionFileHelper.java
  8. 126 0
      code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/helper/data/JobLevelRuleConfig.java
  9. 3 0
      code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/plugin/form/annualadjust/NewAnnualAdjustFormPlugin.java
  10. 7 2
      code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/plugin/form/contribution/ContribBillFormPlugin.java
  11. 39 4
      code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/plugin/form/contribution/ScoreItemConfFormPlugin.java
  12. 76 0
      code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/plugin/form/initial/impt/ScoreInitialImportPlugin.java
  13. 88 0
      code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/plugin/form/performance/LevelConditionConfFormPlugin.java
  14. 0 8
      code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/plugin/form/performance/PerfrankMgmtFormPlugin.java
  15. 3 1
      code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/plugin/operate/adjust/NewDynamicAdjustmentOperationPlugIn.java
  16. 4 1
      code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/plugin/operate/contribution/ContribBillOpPlugin.java
  17. 59 0
      code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/plugin/operate/contribution/validate/LevelConditionConfValidate.java
  18. 102 0
      code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/plugin/operate/contribution/validate/ScoreItemConfValidate.java
  19. 8 8
      code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/plugin/operate/initial/BaseInitialOperationPlugIn.java
  20. 25 14
      code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/plugin/operate/initial/NewHireInitialOperationPlugIn.java
  21. 23 14
      code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/plugin/operate/initial/ServingInitialOperationPlugIn.java
  22. 7 0
      code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/plugin/report/adjust/UnAdjustedReportFormPlugin.java

+ 2 - 0
code/base/nckd-jxccl-base-common/src/main/java/nckd/jxccl/base/common/constant/FormConstant.java

@@ -248,5 +248,7 @@ public class FormConstant {
     public static final String NCKD_STARTDATE = "nckd_startdate";
     /** 结束日期*/
     public static final String NCKD_ENDDATE = "nckd_enddate";
+    /** 描述*/
+    public static final String DESCRIPTION_KEY = "description";
 
 }

+ 20 - 0
code/base/nckd-jxccl-base-helper/src/main/java/nckd/jxccl/base/orm/helper/QFilterCommonHelper.java

@@ -11,6 +11,7 @@ import nckd.jxccl.base.common.constant.FormConstant;
 import nckd.jxccl.base.common.utils.ConvertUtil;
 
 import java.util.Collection;
+import java.util.Date;
 import java.util.List;
 
 /**
@@ -144,4 +145,23 @@ public final class QFilterCommonHelper {
     public static QFilter getIdInFilter(Collection<Long> idList) {
         return new QFilter(FormConstant.ID_KEY, QCP.in, idList);
     }
+
+    /**
+     * 获取有效时间范围内的QFilter实例
+     * 如果结束时间为空,则表示持续有效
+     * @param beginDateProperty 开始时间字段名
+     * @param endDateProperty 结束时间字段名
+     * @return: kd.bos.orm.query.QFilter
+     * @author W.Y.C
+     * @date: 2025/07/07
+     */
+    public static QFilter getValidDateFilter(String beginDateProperty, String endDateProperty) {
+        // 创建组合条件 (beginTime <= currentTime AND (endTime >= currentTime OR endTime IS NULL))
+        Date currentDate = new Date();
+        QFilter beginFilter = new QFilter(beginDateProperty, QCP.less_equals, currentDate);
+        QFilter endFilter = new QFilter(endDateProperty, QCP.large_equals, currentDate);
+        QFilter nullEndFilter = new QFilter(endDateProperty, QCP.is_null, null);
+
+        return beginFilter.and(endFilter.or(nullEndFilter));
+    }
 }

+ 2 - 2
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/business/AnnualAdjustmentService.java

@@ -863,10 +863,10 @@ public class AnnualAdjustmentService {
         if(ac.data.getRankingResultInfo() != null) {
             newPersonPosFile.set(PositionStructureConstant.NCKD_TOPRANK, ac.data.getRankingResultInfo().topRank);
             newPersonPosFile.set(PositionStructureConstant.NCKD_ALLOWANCERANK, ac.data.getRankingResultInfo().allowanceRank);
-            newPersonPosFile.set(PositionStructureConstant.NCKD_TOPRANKPERCENT, ac.data.getRankingResultInfo().topRankPercent);
+            newPersonPosFile.set(PositionStructureConstant.NCKD_TOPRANKPERCENT,  new BigDecimal(ac.data.getRankingResultInfo().topRankPercent.toString()));
             newPersonPosFile.set(PositionStructureConstant.NCKD_ALLOWANCERANKMARK, ac.data.getRankingResultInfo().allowanceRankMark);
             newPersonPosFile.set(PositionStructureConstant.NCKD_ALLOWANCERANKSEL, ac.data.getRankingResultInfo().allowanceRankSel);
-            newPersonPosFile.set(PositionStructureConstant.NCKD_ALLOWANCERANKPCT, ac.data.getRankingResultInfo().allowanceRankPercent);
+            newPersonPosFile.set(PositionStructureConstant.NCKD_ALLOWANCERANKPCT, new BigDecimal(ac.data.getRankingResultInfo().allowanceRankPercent.toString()));
         }
         //上年度考核结果
         newPersonPosFile.set(PositionStructureConstant.NCKD_APPRAISALRESULT, ac.data.getAppraisalResult());

+ 61 - 7
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/business/JobLevelCalculatorService.java

@@ -28,6 +28,7 @@ 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.PositionFileHelper;
+import nckd.jxccl.hr.psms.helper.data.JobLevelRuleConfig;
 import org.apache.commons.lang3.StringUtils;
 
 import java.math.BigDecimal;
@@ -1049,7 +1050,40 @@ public class JobLevelCalculatorService {
             //2、全员绩效排名位于后30%。
             jobLevelIndex--;
         }else{
-            //技术或职能序列
+
+            // 使用动态配置规则替换硬编码规则
+            List<JobLevelRuleConfig> ruleConfigs = PositionFileHelper.getLevelConditionConf();
+
+            // 查找匹配的规则
+            JobLevelRuleConfig matchingRule = ruleConfigs.stream()
+                    .filter(rule -> rule.isMatchJobSeq(jobSeqEnum.getCode()) &&
+                            rule.isMatchJobLevel(currentJobLevelIndex))
+                    .findFirst()
+                    .orElse(null);
+
+
+            if (matchingRule != null) {
+                StrFormatter.format("职位序列【{}】职级【{}】应用的升保降级规则配置为【{}】,最大职级【{}】,最小职级【{}】,升级百分比阈值【{}】,降级百分比阈值",
+                        matchingRule.getName(),matchingRule.getMaxJobLevelSeq(),matchingRule.getMinJobLevel(),matchingRule.getUpGradeThreshold(),matchingRule.getDownGradeThreshold());
+
+                int upGradeThreshold = matchingRule.getUpGradeThreshold() != null ?
+                        matchingRule.getUpGradeThreshold() : 0;
+                int downGradeThreshold = matchingRule.getDownGradeThreshold() != null ?
+                        matchingRule.getDownGradeThreshold() : 0;
+
+                // 使用配置的阈值进行判断
+                if (allowanceRank <= selMaxAllowanceRank(upGradeThreshold, countR)) {
+                    jobLevelIndex++;
+                } else if (allowanceRank >= selMinAllowanceRank(downGradeThreshold, countR) &&
+                        selMinAllowanceRank(downGradeThreshold, countR) > 0) {
+                    jobLevelIndex--;
+                }
+            }else{
+                throw new ValidationException(StrFormatter.format("未匹配到符合职位序列【{}】职级【{}】对应的升保降级规则配置,请检查配置是否正确!",
+                        jobSeqEnum.getName(), currentJobLevelIndex));
+            }
+
+           /* //技术或职能序列
             if (JobSeqEnum.TECHNICALS.getCode().equals(jobSeqEnum.getCode()) || JobSeqEnum.FUNCTIONAL.getCode().equals(jobSeqEnum.getCode())) {
 
                 if (currentJobLevelIndex > 9) {
@@ -1116,7 +1150,7 @@ public class JobLevelCalculatorService {
                         jobLevelIndex--;
                     }
                 }
-            }
+            }*/
         }
 
         if (currentJobLevelIndex > 1 && jobLevelIndex - currentJobLevelIndex > 1) {
@@ -1145,18 +1179,38 @@ public class JobLevelCalculatorService {
         return jobLevelIndex;
     }
 
-    public static int selMaxAllowanceRank(int percent, int countallowancerank) {
+    /**
+     * 计算R排名的最大允许排名(前百分之几对应的排名)
+     * 用于确定员工R排名是否在前百分之几的范围内,以判断是否符合升级条件
+     *
+     * @param percent 百分比阈值(如60表示前60%)
+     * @param countAllowanceRank 参与R排名的总人数
+     * @return int 对应百分比的最大排名位置
+     * @author W.Y.C
+     * @date: 2025/09/22 19:47
+     */
+    public static int selMaxAllowanceRank(int percent, int countAllowanceRank) {
         int maxAllowanceRank = 0;
-        double maxAllowancerRankDouble = Double.parseDouble(countallowancerank + "") / 100.0 * Double.parseDouble(percent + "");
+        double maxAllowancerRankDouble = Double.parseDouble(countAllowanceRank + "") / 100.0 * Double.parseDouble(percent + "");
         maxAllowanceRank = (int) Math.round(maxAllowancerRankDouble);
         return maxAllowanceRank;
     }
 
 
-    public static int selMinAllowanceRank(int percent, int countallowancerank) {
+    /**
+     * 计算R排名的最小允许排名(后百分之几对应的排名)
+     * 用于确定员工R排名是否在后百分之几的范围内,以判断是否符合降级条件
+     *
+     * @param percent 百分比阈值(如5表示后5%)
+     * @param countAllowanceRank 参与R排名的总人数
+     * @return int 对应百分比的最小排名位置
+     * @author W.Y.C
+     * @date: 2025/09/22 19:47
+     */
+    public static int selMinAllowanceRank(int percent, int countAllowanceRank) {
         int minAllowanceRank = 0;
-        double minAllowanceRankDouble = Double.parseDouble(countallowancerank + "") / 100.0 * Double.parseDouble(percent + "");
-        minAllowanceRank = countallowancerank - ((int) Math.round(minAllowanceRankDouble));
+        double minAllowanceRankDouble = Double.parseDouble(countAllowanceRank + "") / 100.0 * Double.parseDouble(percent + "");
+        minAllowanceRank = countAllowanceRank - ((int) Math.round(minAllowanceRankDouble));
         return minAllowanceRank;
     }
 

+ 13 - 0
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/common/PerfRankMgmtConstant.java

@@ -65,4 +65,17 @@ public class PerfRankMgmtConstant extends FormConstant {
     public static final String NCKD_PERFRANKUNLOCKENTRY = "nckd_perfrankunlockentry";
     public static final String NCKD_PERFRANKMGMT = "NCKD_PERFRANKMGMT";
     /*-------------------------------------- 年度绩效排名解锁单据 begin --------------------------------------*/
+
+    /*-------------------------------------- 升保降级条件配置 begin --------------------------------------*/
+    /** 升保降级条件配置-实体标识 */
+    public static final String LEVELCONDITIONCON_ENTITYID = "nckd_levelconditionconf";
+    /** 最小职级 */
+    public static final String NCKD_MINJOBLEVEL = "NCKD_MINJOBLEVEL";
+    /** 最大职级 */
+    public static final String NCKD_MAXJOBLEVEL = "NCKD_MAXJOBLEVEL";
+    /** 升级百分比阈值 */
+    public static final String NCKD_UPGRADETHRESHOLD = "NCKD_UPGRADETHRESHOLD";
+    /** 降级百分比阈值 */
+    public static final String NCKD_DOWNGRADETHRESHOLD = "NCKD_DOWNGRADETHRESHOLD";
+    /*-------------------------------------- 升保降级条件配置 begin --------------------------------------*/
 }

+ 182 - 62
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/helper/ContributionHelper.java

@@ -49,7 +49,7 @@ public class ContributionHelper {
         }
 
         //获取积分项目分数配置
-        Map<Long, BigDecimal> scoreConfMap = getScoreConf();
+        Map<String, BigDecimal> scoreConfMap = getScoreConf();
         //统计人员各项目已累计积分
         Long[] personIdArray = scoreItemValidScoreList.stream()
                 .map(ScoreItemValidScore::getPersonId)
@@ -71,6 +71,7 @@ public class ContributionHelper {
             Long personId = scoreItemValidScore.getPersonId();
             Long scoreItemId = scoreItemValidScore.getScoreItemId();
             Long scoreItemSubId = scoreItemValidScore.getScoreItemSubId();
+            Long scoreItemRankId = scoreItemValidScore.getScoreItemRankId();
 
             //获取该人员的累计积分数据
             List<ScoreItemValidScore> personAccumulateScores = personAccumulateScoreMap.getOrDefault(personId, new ArrayList<>());
@@ -78,23 +79,30 @@ public class ContributionHelper {
             //计算积分项目和具体项目累计分数
             BigDecimal scoreItemSumScore = BigDecimal.ZERO;
             BigDecimal scoreItemSubSumScore = BigDecimal.ZERO;
+            BigDecimal scoreItemRankSumScore = BigDecimal.ZERO;
 
             for (ScoreItemValidScore accumulateScore : personAccumulateScores) {
                 Long tempScoreItemId = accumulateScore.getScoreItemId();
                 Long tempScoreItemSubId = accumulateScore.getScoreItemSubId();
+                Long tempScoreItemRankId = accumulateScore.getScoreItemRankId();
 
                 if (Objects.equals(tempScoreItemId, scoreItemId)) {
                     scoreItemSumScore = scoreItemSumScore.add(accumulateScore.getSumScore());
                     if (Objects.equals(tempScoreItemSubId, scoreItemSubId)) {
-                        scoreItemSubSumScore = accumulateScore.getSumScore();
+                        scoreItemSubSumScore = scoreItemSubSumScore.add(accumulateScore.getSumScore());
+                    }
+                    // 添加名次维度判断
+                    if (Objects.equals(tempScoreItemRankId, scoreItemRankId)) {
+                        scoreItemRankSumScore = scoreItemRankSumScore.add(accumulateScore.getSumScore());
                     }
                 }
             }
 
             //根据配置决定使用哪种累计分数
-            BigDecimal sumScore = determineSumScore(scoreConfMap, scoreItemId, scoreItemSumScore, scoreItemSubSumScore);
+            BigDecimal sumScore = determineSumScore(scoreConfMap, scoreItemId, scoreItemSubId, scoreItemRankId,
+                    scoreItemSumScore, scoreItemSubSumScore, scoreItemRankSumScore);
 
-            BigDecimal validScore = calculateAvailableScore(scoreConfMap, scoreItemId, scoreItemSubId, sumScore);
+            BigDecimal validScore = calculateAvailableScore(scoreConfMap, scoreItemId, scoreItemSubId, scoreItemRankId, sumScore);
             scoreItemValidScore.setValidScore(validScore);
             scoreItemValidScore.setSumScore(sumScore);
         }
@@ -143,6 +151,7 @@ public class ContributionHelper {
                 .add(ContributionConstant.NCKD_YEAR)
                 .addIdNumberName(ContributionConstant.NCKD_SCOREITEM)
                 .addIdNumberName(ContributionConstant.NCKD_SCOREITEMSUB)
+                .addIdNumberName(ContributionConstant.NCKD_SCOREITEMRANK) // 添加积分项目名次字段
                 .addGroup(new String[]{FormConstant.NCKD_ENTRYENTITY, ContributionConstant.NCKD_PERSON},FormConstant.ID_KEY)
                 .addGroup(new String[]{FormConstant.NCKD_ENTRYENTITY}, ContributionConstant.NCKD_SCORE, ContributionConstant.NCKD_ORISCORE);
 
@@ -172,11 +181,12 @@ public class ContributionHelper {
                     new QFilter[]{filter}, null, 5000);
 
             DataSet sumDateSet = dateSet.copy()
-                    // 按人员、积分项目、积分项目子项进行分组
+                    // 按人员、积分项目、积分项目子项、积分项目名次进行分组
                     .groupBy(new String[]{String.join(".", ContributionConstant.NCKD_ENTRYENTITY, ContributionConstant.NCKD_PERSON, FormConstant.ID_KEY),
                             String.join(".", ContributionConstant.NCKD_SCOREITEM, FormConstant.ID_KEY),
                             String.join(".", ContributionConstant.NCKD_SCOREITEM, FormConstant.NUMBER_KEY),
-                            String.join(".", ContributionConstant.NCKD_SCOREITEMSUB, FormConstant.ID_KEY)})
+                            String.join(".", ContributionConstant.NCKD_SCOREITEMSUB, FormConstant.ID_KEY),
+                            String.join(".", ContributionConstant.NCKD_SCOREITEMRANK, FormConstant.ID_KEY)}) // 添加名次分组
                     .sum(String.join(".", ContributionConstant.NCKD_ENTRYENTITY, FormConstant.NCKD_SCORE),"sumScore").finish();
 
             while (sumDateSet.hasNext()) {
@@ -185,9 +195,10 @@ public class ContributionHelper {
                 Long scoreItemId = row.getLong(String.join(".", ContributionConstant.NCKD_SCOREITEM, FormConstant.ID_KEY));
                 String scoreItemNumber = row.getString(String.join(".", ContributionConstant.NCKD_SCOREITEM, FormConstant.NUMBER_KEY));
                 Long scoreItemSubId = row.getLong(String.join(".", ContributionConstant.NCKD_SCOREITEMSUB, FormConstant.ID_KEY));
+                Long scoreItemRankId = row.getLong(String.join(".", ContributionConstant.NCKD_SCOREITEMRANK, FormConstant.ID_KEY)); // 获取名次ID
                 //已获得的累计积分
                 BigDecimal sumScore = row.getBigDecimal("sumScore");
-                ScoreItemValidScore scoreItemValidScore = new ScoreItemValidScore(personId, scoreItemId,scoreItemNumber, scoreItemSubId, sumScore);
+                ScoreItemValidScore scoreItemValidScore = new ScoreItemValidScore(personId, scoreItemId,scoreItemNumber, scoreItemSubId, scoreItemRankId, sumScore);
                 scoreItemValidScoreList.add(scoreItemValidScore);
             }
         }
@@ -227,6 +238,7 @@ public class ContributionHelper {
      * @param scoreConfMap 分数配置映射表,key为配置ID,value为限分数值
      * @param scoreItemId 积分项目ID
      * @param scoreItemSubId 具体积分项目ID
+     * @param scoreItemRankId 积分项目名次ID
      * @param accumulatedScore 已累计总分
      * @return 可获得的有效分数
      *         如果没有任何限制返回null
@@ -235,14 +247,25 @@ public class ContributionHelper {
      * @author W.Y.C
      * @date: 2025/10/26 16:53
      */
-    private static BigDecimal calculateAvailableScore(Map<Long, BigDecimal> scoreConfMap, Long scoreItemId, Long scoreItemSubId, BigDecimal accumulatedScore) {
+    private static BigDecimal calculateAvailableScore(Map<String, BigDecimal> scoreConfMap, Long scoreItemId, Long scoreItemSubId, Long scoreItemRankId, BigDecimal accumulatedScore) {
         // 积分项目限分 - 如果没有找到则不限分
-        BigDecimal scoreItemMaxScore = scoreConfMap.get(scoreItemId);
+        String scoreItemKey = scoreItemId + "";
+        BigDecimal scoreItemMaxScore = scoreConfMap.get(scoreItemKey);
 
         // 具体积分项目限分 - 如果没有找到则不限分
+        String scoreItemSubKey = null;
         BigDecimal scoreItemSubMaxScore = null;
         if (scoreItemSubId != null && scoreItemSubId > 0) {
-            scoreItemSubMaxScore = scoreConfMap.get(scoreItemSubId);
+            scoreItemSubKey = scoreItemId + "-" + scoreItemSubId;
+            scoreItemSubMaxScore = scoreConfMap.get(scoreItemSubKey);
+        }
+
+        // 积分项目名次限分 - 如果没有找到则不限分
+        String scoreItemRankKey = null;
+        BigDecimal scoreItemRankMaxScore = null;
+        if (scoreItemRankId != null && scoreItemRankId > 0) {
+            scoreItemRankKey = scoreItemId + "-" + scoreItemSubId + "-" + scoreItemRankId;
+            scoreItemRankMaxScore = scoreConfMap.get(scoreItemRankKey);
         }
 
         // 处理累计分数的空值
@@ -251,9 +274,19 @@ public class ContributionHelper {
         // 计算实际的最大限制
         BigDecimal actualMaxScore = null;
 
+        // 检查积分项目名次限分是否存在且大于0(最高优先级)
+        if (scoreItemRankMaxScore != null && scoreItemRankMaxScore.compareTo(BigDecimal.ZERO) > 0) {
+            actualMaxScore = scoreItemRankMaxScore;
+        }
+
         // 检查具体积分项目限分是否存在且大于0
         if (scoreItemSubMaxScore != null && scoreItemSubMaxScore.compareTo(BigDecimal.ZERO) > 0) {
-            actualMaxScore = scoreItemSubMaxScore;
+            if (actualMaxScore == null) {
+                actualMaxScore = scoreItemSubMaxScore;
+            } else {
+                // 多重限制,取较小值
+                actualMaxScore = actualMaxScore.min(scoreItemSubMaxScore);
+            }
         }
 
         // 检查积分项目限分是否存在且大于0
@@ -261,7 +294,7 @@ public class ContributionHelper {
             if (actualMaxScore == null) {
                 actualMaxScore = scoreItemMaxScore;
             } else {
-                // 重限制,取较小值
+                // 重限制,取较小值
                 actualMaxScore = actualMaxScore.min(scoreItemMaxScore);
             }
         }
@@ -284,14 +317,25 @@ public class ContributionHelper {
         return availableScore;
     }
 
+    public static void main(String[] args) {
+        List<ScoreItemValidScore> list = new ArrayList<>();
+        list.add(new ScoreItemValidScore(1L, 11L, "1", 111L, 1111L, BigDecimal.valueOf(6)));
+        list.add(new ScoreItemValidScore(1L, 11L, "1", 121L, null, BigDecimal.valueOf(10)));
+        list.add(new ScoreItemValidScore(1L, 11L, "1", 131L, null, BigDecimal.valueOf(10)));
+        list.add(new ScoreItemValidScore(1L, 11L, "1", 141L, null, BigDecimal.valueOf(20)));
+        List<ScoreItemValidScore> scoreItemValidScores = calculateMaxAllowedScore(list);
+        System.out.println();
+    }
+
     /**
      * 计算最多可得的分数
      * 根据累计积分和分数配置映射表,如果超过配置的限制分数则返回限制分最大分数,
-     * 计算每个积分大项在考虑双重限制条件下的最大可获得分数:
-     * 1. 子项限制:每个具体积分项目子项可能有分数上限
-     * 2. 大项限制:整个积分大项可能有总分上限
+     * 计算每个积分大项在考虑三重限制条件下的最大可获得分数:
+     * 1. 名次限制:每个积分项目名次可能有分数上限(最高优先级)
+     * 2. 子项限制:每个具体积分项目子项可能有分数上限
+     * 3. 大项限制:整个积分大项可能有总分上限
      *
-     * @param scoreItemValidScoreList 某个人员所有积分项目的累计积分(personId、scoreItemId、scoreItemSubId、sumScore有值)
+     * @param scoreItemValidScoreList 某个人员所有积分项目的累计积分(personId、scoreItemId、scoreItemSubId、scoreItemRankId、sumScore有值)
      * @return 最多可得的分数列表(按大项维度聚合)
      * @author W.Y.C
      * @date: 2025/10/27
@@ -299,7 +343,11 @@ public class ContributionHelper {
     public static List<ScoreItemValidScore> calculateMaxAllowedScore(List<ScoreItemValidScore> scoreItemValidScoreList) {
 
         //获取积分限分配置
-        Map<Long, BigDecimal> scoreConfMap = ContributionHelper.getScoreConf();
+        Map<String, BigDecimal> scoreConfMap = ContributionHelper.getScoreConf();
+        /*Map<String, BigDecimal> scoreConfMap = Maps.newConcurrentMap();
+         scoreConfMap.put("11-111-1111",new BigDecimal(2));
+         scoreConfMap.put("11-121",new BigDecimal(5));
+         scoreConfMap.put("11",new BigDecimal(20));*/
 
         List<ScoreItemValidScore> result = new ArrayList<>();
 
@@ -312,51 +360,72 @@ public class ContributionHelper {
             List<ScoreItemValidScore> valueList = entry.getValue();
 
             // 获取大项限制分数
-            BigDecimal scoreItemMaxScore = scoreConfMap.get(scoreItemId);
-
-            // 计算大项总分(按子项分组后求和)
-            Map<Long, BigDecimal> subItemSumMap = new HashMap<>();
-            for (ScoreItemValidScore item : valueList) {
-                Long subItemId = item.getScoreItemSubId();
-                BigDecimal score = item.getSumScore() == null ? BigDecimal.ZERO : item.getSumScore();
-                subItemSumMap.merge(subItemId, score, BigDecimal::add);
-            }
+            BigDecimal scoreItemMaxScore = scoreConfMap.get(scoreItemId + "");
 
-            // 计算未受限制的实际总分
-            BigDecimal actualTotalScore = BigDecimal.ZERO;
-            for (BigDecimal subItemScore : subItemSumMap.values()) {
-                actualTotalScore = actualTotalScore.add(subItemScore);
-            }
+            // 按具体项目分组
+            Map<Long, List<ScoreItemValidScore>> groupedBySubItemId = valueList.stream()
+                    .collect(Collectors.groupingBy(ScoreItemValidScore::getScoreItemSubId));
 
-
-            // 计算每个子项的有效分数并求和
             BigDecimal totalAllowedScore = BigDecimal.ZERO;
-            for (Map.Entry<Long, BigDecimal> subEntry : subItemSumMap.entrySet()) {
+            BigDecimal actualTotalScore = BigDecimal.ZERO;
+
+            // 遍历每个具体项目
+            for (Map.Entry<Long, List<ScoreItemValidScore>> subEntry : groupedBySubItemId.entrySet()) {
                 Long subItemId = subEntry.getKey();
-                BigDecimal subItemSumScore = subEntry.getValue();
+                List<ScoreItemValidScore> subItemList = subEntry.getValue();
 
                 // 获取子项限制分数
                 BigDecimal scoreItemSubMaxScore = null;
                 if (subItemId != null && subItemId > 0) {
-                    scoreItemSubMaxScore = scoreConfMap.get(subItemId);
+                    scoreItemSubMaxScore = scoreConfMap.get(scoreItemId + "-" + subItemId);
+                }
+
+                // 按名次分组
+                Map<Long, BigDecimal> rankSumMap = new HashMap<>();
+                for (ScoreItemValidScore item : subItemList) {
+                    Long rankItemId = item.getScoreItemRankId();
+                    BigDecimal score = item.getSumScore() == null ? BigDecimal.ZERO : item.getSumScore();
+                    rankSumMap.merge(rankItemId, score, BigDecimal::add);
+                    actualTotalScore = actualTotalScore.add(score);
                 }
 
-                // 子项限制后的分数(优先考虑子项限制)
-                BigDecimal allowedSubScore = subItemSumScore;
+                BigDecimal subItemAllowedScore = BigDecimal.ZERO;
+
+                // 处理每个名次的分数限制
+                for (Map.Entry<Long, BigDecimal> rankEntry : rankSumMap.entrySet()) {
+                    Long rankItemId = rankEntry.getKey();
+                    BigDecimal rankSumScore = rankEntry.getValue();
+
+                    // 获取名次限制分数
+                    BigDecimal scoreItemRankMaxScore = null;
+                    if (rankItemId != null && rankItemId > 0) {
+                        scoreItemRankMaxScore = scoreConfMap.get(scoreItemId + "-" + subItemId + "-" + rankItemId);
+                    }
+
+                    // 名次限制后的分数
+                    BigDecimal allowedRankScore = rankSumScore;
+                    if (scoreItemRankMaxScore != null && scoreItemRankMaxScore.compareTo(BigDecimal.ZERO) > 0) {
+                        allowedRankScore = rankSumScore.min(scoreItemRankMaxScore);
+                    }
+
+                    subItemAllowedScore = subItemAllowedScore.add(allowedRankScore);
+                }
+
+                // 应用子项限制(如果设置了子项限制)
                 if (scoreItemSubMaxScore != null && scoreItemSubMaxScore.compareTo(BigDecimal.ZERO) > 0) {
-                    allowedSubScore = subItemSumScore.min(scoreItemSubMaxScore);
+                    subItemAllowedScore = subItemAllowedScore.min(scoreItemSubMaxScore);
                 }
 
-                totalAllowedScore = totalAllowedScore.add(allowedSubScore);
+                totalAllowedScore = totalAllowedScore.add(subItemAllowedScore);
             }
 
-            // 如果大项有限制,需要检查是否超过大项限制
+            // 应用大项限制(如果设置了大项限制)
             if (scoreItemMaxScore != null && scoreItemMaxScore.compareTo(BigDecimal.ZERO) > 0) {
                 totalAllowedScore = totalAllowedScore.min(scoreItemMaxScore);
             }
 
             // 创建结果对象,只包含scoreItemId和validScore
-            ScoreItemValidScore resultItem = new ScoreItemValidScore(null, scoreItemId, null);
+            ScoreItemValidScore resultItem = new ScoreItemValidScore(null, scoreItemId, null, null);
             String scoreItemNumber = null;
             if (!valueList.isEmpty() && valueList.get(0) != null) {
                 scoreItemNumber = valueList.get(0).getScoreItemNumber();
@@ -376,45 +445,84 @@ public class ContributionHelper {
      * @param scoreItemId 积分项目ID
      * @param scoreItemSumScore 积分项目累计分数
      * @param scoreItemSubSumScore 积分项目具体项目累计分数
+     * @param scoreItemRankSumScore 积分项目名次累计分数
      * @return 应该使用的累计分数
      */
-    private static BigDecimal determineSumScore(Map<Long, BigDecimal> scoreConfMap, Long scoreItemId,
-                                                BigDecimal scoreItemSumScore, BigDecimal scoreItemSubSumScore) {
-        BigDecimal scoreItemMaxScore = scoreConfMap.get(scoreItemId);
-        if (scoreItemMaxScore != null) {
-            //如果设置积分项目大类分数限制,则取大类的累计积分
-            return scoreItemSumScore;
-        } else {
-            //如果没有设置积分项目大类分数限制,则取小类的累计积分
-            return scoreItemSubSumScore;
+    private static BigDecimal determineSumScore(Map<String, BigDecimal> scoreConfMap, Long scoreItemId, Long scoreItemSubId, Long scoreItemRankId,
+                                                BigDecimal scoreItemSumScore, BigDecimal scoreItemSubSumScore,
+                                                BigDecimal scoreItemRankSumScore) {
+        // 按照优先级判断使用哪个维度的累计分数
+        // 优先级:名次 > 子项 > 大类
+
+        // 如果设置了积分项目名次限制,使用名次的累计积分
+        if (scoreItemRankSumScore != null && scoreItemRankSumScore.compareTo(BigDecimal.ZERO) > 0) {
+            String key = scoreItemId + "-" + scoreItemSubId + "-" + scoreItemRankId;
+            if (scoreConfMap.containsKey(key)) {
+                return scoreItemRankSumScore;
+            }
         }
+
+        // 如果设置了积分项目子项限制,使用子项的累计积分
+        if (scoreItemSubSumScore != null && scoreItemSubSumScore.compareTo(BigDecimal.ZERO) > 0) {
+            String key = scoreItemId + "-" + scoreItemSubId;
+            if (scoreConfMap.containsKey(key)) {
+                return scoreItemSubSumScore;
+            }
+        }
+
+        // 默认使用大类的累计积分
+        return scoreItemSumScore;
+    }
+
+    public static Map<String, BigDecimal> getScoreConf() {
+        return getScoreConf(null);
     }
 
     /**
      * 获取积分配置
-     * @return: java.util.Map<java.lang.Long, java.math.BigDecimal>;key为积分项目子项ID(项目子项为空时key为项目大项),value为积分项目对应的最大分数
+     * @return: java.util.Map<java.lang.String, java.math.BigDecimal>;key:根据配置的完整程度生成不同格式的字符串,
+     *          仅配置积分项目时为"scoreItemId",
+     *          配置积分项目和具体积分项目时为"scoreItemId-scoreItemSubId",
+     *          配置积分项目、具体积分项目和积分项目名次时为"scoreItemId-scoreItemSubId-scoreItemRankId",
+     *          value为积分项目对应的最大分数
      * @author W.Y.C
      * @date: 2025/10/26 13:38
      */
-    public static Map<Long, BigDecimal> getScoreConf() {
+    public static Map<String, BigDecimal> getScoreConf(QFilter otherFilter) {
         //查询积分项目分数配置
         QueryFieldBuilder scoreItemConfFieldBuilder = QueryFieldBuilder.create()
                 .addIdNumberName(FormConstant.NCKD_ENTRYENTITY, ContributionConstant.NCKD_SCOREITEM)
                 .addIdNumberName(FormConstant.NCKD_ENTRYENTITY, ContributionConstant.NCKD_SCOREITEMSUB)
+                .addIdNumberName(FormConstant.NCKD_ENTRYENTITY, ContributionConstant.NCKD_SCOREITEMRANK)
                 .addGroup(new String[]{FormConstant.NCKD_ENTRYENTITY}, ContributionConstant.NCKD_MAXSCORE);
+        QFilter filter = QFilterCommonHelper.getEnableFilter()
+                .and(QFilterCommonHelper.getValidDateFilter(FormConstant.NCKD_STARTDATE,FormConstant.NCKD_ENDDATE));
+        if(otherFilter != null){
+            filter = filter.and(otherFilter);
+        }
 
         DynamicObjectCollection scoreItemConfQuery = QueryServiceHelper.query(ContributionConstant.SCOREITEMCONF_ENTITYID,
                 scoreItemConfFieldBuilder.buildSelect(),
-                new QFilter[]{QFilterCommonHelper.getEnableFilter()});
+                new QFilter[]{filter});
 
-        //scoreMap:key为积分项目子项ID(项目子项为空时key为项目大项),value为积分项目对应的最大分数
-        Map<Long, BigDecimal> scoreMap = scoreItemConfQuery.stream().collect(Collectors.toMap(
+        //scoreMap:key为积分配置维度ID,value为积分项目对应的最大分数
+        //优先级顺序:NCKD_SCOREITEMRANK > NCKD_SCOREITEMSUB > NCKD_SCOREITEM
+        Map<String, BigDecimal> scoreMap = scoreItemConfQuery.stream().collect(Collectors.toMap(
                 item -> {
+                    long scoreItemRankId = item.getLong(String.join(".", FormConstant.NCKD_ENTRYENTITY, ContributionConstant.NCKD_SCOREITEMRANK, FormConstant.ID_KEY));
                     long scoreItemSubId = item.getLong(String.join(".", FormConstant.NCKD_ENTRYENTITY, ContributionConstant.NCKD_SCOREITEMSUB, FormConstant.ID_KEY));
-                    if (scoreItemSubId <= 0) {
-                        return item.getLong(String.join(".", FormConstant.NCKD_ENTRYENTITY, ContributionConstant.NCKD_SCOREITEM, FormConstant.ID_KEY));
+                    long scoreItemId = item.getLong(String.join(".", FormConstant.NCKD_ENTRYENTITY, ContributionConstant.NCKD_SCOREITEM, FormConstant.ID_KEY));
+
+                    // 按优先级顺序确定key值
+                    if (scoreItemRankId > 0) {
+                        // 优先使用NCKD_SCOREITEMRANK作为key
+                        return scoreItemId+"-"+scoreItemSubId+"-"+scoreItemRankId;
+                    } else if (scoreItemSubId > 0) {
+                        // 当NCKD_SCOREITEMRANK为空时,使用NCKD_SCOREITEMSUB作为key
+                        return scoreItemId+"-"+scoreItemSubId;
                     } else {
-                        return scoreItemSubId;
+                        // 当NCKD_SCOREITEMRANK和NCKD_SCOREITEMSUB都为空时,使用NCKD_SCOREITEM作为key
+                        return scoreItemId+"";
                     }
                 },
                 item -> item.getBigDecimal(String.join(".", FormConstant.NCKD_ENTRYENTITY, ContributionConstant.NCKD_MAXSCORE)),
@@ -429,6 +537,7 @@ public class ContributionHelper {
         private Long scoreItemId;
         private String scoreItemNumber;
         private Long scoreItemSubId;
+        private Long scoreItemRankId;
         /**本次积分*/
         private BigDecimal currentScore;
         private BigDecimal sumScore;
@@ -437,24 +546,27 @@ public class ContributionHelper {
         //没有业务含义,只用来记录分录索引号;
         private int rowIndex;
 
-        public ScoreItemValidScore(Long personId, Long scoreItemId, Long scoreItemSubId) {
+        public ScoreItemValidScore(Long personId, Long scoreItemId, Long scoreItemSubId, Long scoreItemRankId) {
             this.personId = personId;
             this.scoreItemId = scoreItemId;
             this.scoreItemSubId = scoreItemSubId;
+            this.scoreItemRankId = scoreItemRankId;
         }
 
-        public ScoreItemValidScore(Long personId, Long scoreItemId,String scoreItemNumber, Long scoreItemSubId, BigDecimal sumScore) {
+        public ScoreItemValidScore(Long personId, Long scoreItemId,String scoreItemNumber, Long scoreItemSubId, Long scoreItemRankId, BigDecimal sumScore) {
             this.personId = personId;
             this.scoreItemId = scoreItemId;
             this.scoreItemNumber = scoreItemNumber;
             this.scoreItemSubId = scoreItemSubId;
+            this.scoreItemRankId = scoreItemRankId;
             this.sumScore = sumScore;
         }
 
-        public ScoreItemValidScore(Long personId, Long scoreItemId, Long scoreItemSubId, BigDecimal sumScore, BigDecimal validScore) {
+        public ScoreItemValidScore(Long personId, Long scoreItemId, Long scoreItemSubId, Long scoreItemRankId, BigDecimal sumScore, BigDecimal validScore) {
             this.personId = personId;
             this.scoreItemId = scoreItemId;
             this.scoreItemSubId = scoreItemSubId;
+            this.scoreItemRankId = scoreItemRankId;
             this.sumScore = sumScore;
             this.validScore = validScore;
         }
@@ -490,6 +602,14 @@ public class ContributionHelper {
             this.scoreItemSubId = scoreItemSubId;
         }
 
+        public Long getScoreItemRankId() {
+            return scoreItemRankId;
+        }
+
+        public void setScoreItemRankId(Long scoreItemRankId) {
+            this.scoreItemRankId = scoreItemRankId;
+        }
+
         public BigDecimal getSumScore() {
             return sumScore;
         }

+ 74 - 0
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/helper/PositionFileHelper.java

@@ -10,8 +10,11 @@ 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;
@@ -525,4 +528,75 @@ public class PositionFileHelper {
         }
         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;
+    }
+
+
 }

+ 126 - 0
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/helper/data/JobLevelRuleConfig.java

@@ -0,0 +1,126 @@
+package nckd.jxccl.hr.psms.helper.data;
+
+import kd.bos.dataentity.entity.DynamicObject;
+
+/**
+* 获取升保降级条件配置
+* @author W.Y.C
+* @date 2025/11/2 21:39
+* @version 1.0
+*/
+public class JobLevelRuleConfig {
+    private String name;
+    private String description;
+    /**职位序列编码*/
+    private String jobSeqNumber;
+    /**最小职级*/
+    private Integer minJobLevelSeq;
+    /**最小职级*/
+    private DynamicObject minJobLevel;
+    /**最大职级*/
+    private Integer maxJobLevelSeq;
+    /**最大职级*/
+    private DynamicObject maxJobLevel;
+    /**升级百分比阈值*/
+    private Integer upGradeThreshold;
+    /**降级百分比阈值*/
+    private Integer downGradeThreshold;
+
+    /**
+     * 判断给定的职级是否在该规则的适用范围内
+     * @param jobLevelIndex 职级
+     * @return: boolean
+     * @author W.Y.C
+     * @date: 2025/11/02 21:54
+     */
+    public boolean isMatchJobLevel(int jobLevelIndex) {
+        if (minJobLevelSeq == null || maxJobLevelSeq == null) {
+            return false;
+        }
+        return jobLevelIndex >= minJobLevelSeq && jobLevelIndex <= maxJobLevelSeq;
+    }
+
+
+    /**
+     * 判断给定的职位序列是否匹配该规则
+     * @param jobSeqNumber 职位序列编码
+     * @return: boolean
+     * @author W.Y.C
+     * @date: 2025/11/02 21:54
+     */
+    public boolean isMatchJobSeq(String jobSeqNumber) {
+        return this.jobSeqNumber != null && this.jobSeqNumber.equals(jobSeqNumber);
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public Integer getDownGradeThreshold() {
+            return downGradeThreshold;
+        }
+
+        public void setDownGradeThreshold(Integer downGradeThreshold) {
+            this.downGradeThreshold = downGradeThreshold;
+        }
+
+        public String getJobSeqNumber() {
+            return jobSeqNumber;
+        }
+
+        public void setJobSeqNumber(String jobSeqNumber) {
+            this.jobSeqNumber = jobSeqNumber;
+        }
+
+        public DynamicObject getMaxJobLevel() {
+            return maxJobLevel;
+        }
+
+        public void setMaxJobLevel(DynamicObject maxJobLevel) {
+            this.maxJobLevel = maxJobLevel;
+        }
+
+        public Integer getMaxJobLevelSeq() {
+            return maxJobLevelSeq;
+        }
+
+        public void setMaxJobLevelSeq(Integer maxJobLevelSeq) {
+            this.maxJobLevelSeq = maxJobLevelSeq;
+        }
+
+        public DynamicObject getMinJobLevel() {
+            return minJobLevel;
+        }
+
+        public void setMinJobLevel(DynamicObject minJobLevel) {
+            this.minJobLevel = minJobLevel;
+        }
+
+        public Integer getMinJobLevelSeq() {
+            return minJobLevelSeq;
+        }
+
+        public void setMinJobLevelSeq(Integer minJobLevelSeq) {
+            this.minJobLevelSeq = minJobLevelSeq;
+        }
+
+        public Integer getUpGradeThreshold() {
+            return upGradeThreshold;
+        }
+
+        public void setUpGradeThreshold(Integer upGradeThreshold) {
+            this.upGradeThreshold = upGradeThreshold;
+        }
+    }

+ 3 - 0
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/plugin/form/annualadjust/NewAnnualAdjustFormPlugin.java

@@ -57,8 +57,11 @@ public class NewAnnualAdjustFormPlugin extends AbstractFormPlugin implements Plu
         if(success && PositionStructureConstant.OP_CONFIRMADJUST.equalsIgnoreCase(operateKey)){
             Map<String, String> customData = afterDoOperationEventArgs.getOperationResult().getCustomData();
             String jobLeveStr = customData.get(PositionStructureConstant.NCKD_JOBLEVELHR);
+            //刷新父级页面
+            this.getView().getParentView().invokeOperation(FormConstant.REFRESH_OP);
             this.getView().returnDataToParent("true");
             this.getView().showConfirm("提示","新建调整成功,职位档案已生成。",jobLeveStr, MessageBoxOptions.OK,null,null,null,null);
+
         }
     }
 }

+ 7 - 2
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/plugin/form/contribution/ContribBillFormPlugin.java

@@ -98,6 +98,7 @@ public class ContribBillFormPlugin extends AbstractFormPlugin implements Plugin,
                 || ContributionConstant.NCKD_PERSON.equalsIgnoreCase(fieldKey)
                 || ContributionConstant.NCKD_SCOREITEMSUB.equalsIgnoreCase(fieldKey)
                 || ContributionConstant.NCKD_SCOREITEM.equalsIgnoreCase(fieldKey)
+                || ContributionConstant.NCKD_SCOREITEMRANK.equalsIgnoreCase(fieldKey)
                 || ContributionConstant.NCKD_ORISCORE.equalsIgnoreCase(fieldKey);
     }
 
@@ -114,6 +115,7 @@ public class ContribBillFormPlugin extends AbstractFormPlugin implements Plugin,
         Date date = ConvertUtil.toDate(this.getModel().getValue(ContributionConstant.NCKD_YEAR));
         DynamicObject scoreItem = ConvertUtil.toDynamicObjectOrNull(this.getModel().getValue(ContributionConstant.NCKD_SCOREITEM));
         DynamicObject scoreItemSub = ConvertUtil.toDynamicObjectOrNull(this.getModel().getValue(ContributionConstant.NCKD_SCOREITEMSUB));
+        DynamicObject scoreItemRank = ConvertUtil.toDynamicObjectOrNull(this.getModel().getValue(ContributionConstant.NCKD_SCOREITEMRANK));
         DynamicObject person = ConvertUtil.toDynamicObjectOrNull(this.getModel().getValue(ContributionConstant.NCKD_PERSON, rowIndex));
         BigDecimal oriScore = ConvertUtil.toBigDecimal(this.getModel().getValue(ContributionConstant.NCKD_ORISCORE, rowIndex));
 
@@ -123,7 +125,8 @@ public class ContribBillFormPlugin extends AbstractFormPlugin implements Plugin,
             ContributionHelper.ScoreItemValidScore scoreItemValidScore = new ContributionHelper.ScoreItemValidScore(
                     person.getLong(FormConstant.ID_KEY),
                     scoreItem.getLong(FormConstant.ID_KEY),
-                    scoreItemSub.getLong(FormConstant.ID_KEY));
+                    scoreItemSub.getLong(FormConstant.ID_KEY),
+                    scoreItemRank != null ? scoreItemRank.getLong(FormConstant.ID_KEY) : null);
             scoreItemValidScore.setCurrentScore(oriScore);
             ContributionHelper.getScoreItemValidScore(scoreItemValidScore, date, id);
             this.getModel().setValue(ContributionConstant.NCKD_SCORE, scoreItemValidScore.getValidScore(), rowIndex);
@@ -144,6 +147,7 @@ public class ContribBillFormPlugin extends AbstractFormPlugin implements Plugin,
         Date date = ConvertUtil.toDate(this.getModel().getValue(ContributionConstant.NCKD_YEAR));
         DynamicObject scoreItem = ConvertUtil.toDynamicObjectOrNull(this.getModel().getValue(ContributionConstant.NCKD_SCOREITEM));
         DynamicObject scoreItemSub = ConvertUtil.toDynamicObjectOrNull(this.getModel().getValue(ContributionConstant.NCKD_SCOREITEMSUB));
+        DynamicObject scoreItemRank = ConvertUtil.toDynamicObjectOrNull(this.getModel().getValue(ContributionConstant.NCKD_SCOREITEMRANK));
 
         if (date != null && scoreItem != null && scoreItemSub != null) {
             //重置分录所有分录的"录用积分"字段
@@ -158,7 +162,8 @@ public class ContribBillFormPlugin extends AbstractFormPlugin implements Plugin,
                     ContributionHelper.ScoreItemValidScore scoreItemValidScore = new ContributionHelper.ScoreItemValidScore(
                             person.getLong(FormConstant.ID_KEY),
                             scoreItem.getLong(FormConstant.ID_KEY),
-                            scoreItemSub.getLong(FormConstant.ID_KEY));
+                            scoreItemSub.getLong(FormConstant.ID_KEY),
+                            scoreItemRank != null ? scoreItemRank.getLong(FormConstant.ID_KEY) : null);
                     scoreItemValidScore.setCurrentScore(oriScore);
                     scoreItemValidScore.setRowIndex(i);
                     scoreItemValidScoreList.add(scoreItemValidScore);

+ 39 - 4
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/plugin/form/contribution/ScoreItemConfFormPlugin.java

@@ -1,6 +1,8 @@
 package nckd.jxccl.hr.psms.plugin.form.contribution;
 
 import kd.bos.dataentity.entity.DynamicObject;
+import kd.bos.entity.datamodel.events.ChangeData;
+import kd.bos.entity.datamodel.events.PropertyChangedArgs;
 import kd.bos.form.field.BasedataEdit;
 import kd.bos.form.field.events.BeforeF7SelectEvent;
 import kd.bos.form.field.events.BeforeF7SelectListener;
@@ -11,8 +13,10 @@ import kd.sdk.plugin.Plugin;
 import nckd.jxccl.base.common.constant.FormConstant;
 import nckd.jxccl.base.common.utils.ConvertUtil;
 import nckd.jxccl.hr.psms.common.ContributionConstant;
+import nckd.jxccl.hr.psms.common.PerfRankMgmtConstant;
 
 import java.util.EventObject;
+import java.util.Objects;
 
 /**
 * 积分项目分数配置插件
@@ -28,12 +32,21 @@ public class ScoreItemConfFormPlugin extends AbstractFormPlugin implements Plugi
         super.registerListener(e);
 
         // 为分录中的A字段添加值变化监听
-        BasedataEdit bFieldEdit = this.getView().getControl(ContributionConstant.NCKD_SCOREITEMSUB);
-        if (bFieldEdit != null) {
-            bFieldEdit.addBeforeF7SelectListener(this);
+        BasedataEdit scoreItemSubEdit = this.getView().getControl(ContributionConstant.NCKD_SCOREITEMSUB);
+        if (scoreItemSubEdit != null) {
+            scoreItemSubEdit.addBeforeF7SelectListener(this);
+        }
+
+        BasedataEdit scoreItemRankEdit = this.getView().getControl(ContributionConstant.NCKD_SCOREITEMRANK);
+        if (scoreItemRankEdit != null) {
+            scoreItemRankEdit.addBeforeF7SelectListener(this);
         }
     }
 
+    @Override
+    public void afterBindData(EventObject e) {
+        this.getModel().setValue(FormConstant.STATUS, "A");
+    }
 
     @Override
     public void beforeF7Select(BeforeF7SelectEvent e) {
@@ -41,7 +54,7 @@ public class ScoreItemConfFormPlugin extends AbstractFormPlugin implements Plugi
 
         //基础资料联动
         // 仅处理B字段的F7事件
-        if (ContributionConstant.NCKD_SCOREITEMSUB.equalsIgnoreCase(fieldKey)) {
+        if (ContributionConstant.NCKD_SCOREITEMSUB.equalsIgnoreCase(fieldKey) || ContributionConstant.NCKD_SCOREITEMRANK.equalsIgnoreCase(fieldKey)) {
             // 获取当前分录行的行号
             int currentRow = e.getRow();
 
@@ -59,4 +72,26 @@ public class ScoreItemConfFormPlugin extends AbstractFormPlugin implements Plugi
         }
     }
 
+    @Override
+    public void propertyChanged(PropertyChangedArgs e) {
+        String name = e.getProperty().getName();
+        if (ContributionConstant.NCKD_SCOREITEMSUB.equalsIgnoreCase(name) || ContributionConstant.NCKD_SCOREITEM.equalsIgnoreCase(name)) {
+
+            ChangeData[] changeSet = e.getChangeSet();
+            Object newValue = changeSet[0].getNewValue();
+            Object oldValue = changeSet[0].getOldValue();
+            if(newValue != null && !Objects.equals(newValue, oldValue)) {
+                if(ContributionConstant.NCKD_SCOREITEMSUB.equalsIgnoreCase(name)){
+                    this.getModel().setValue(ContributionConstant.NCKD_SCOREITEMRANK, null,changeSet[0].getRowIndex());
+                    this.getView().updateView(ContributionConstant.NCKD_SCOREITEMRANK,changeSet[0].getRowIndex());
+                }else{
+                    this.getModel().setValue(ContributionConstant.NCKD_SCOREITEMRANK, null,changeSet[0].getRowIndex());
+                    this.getView().updateView(ContributionConstant.NCKD_SCOREITEMRANK,changeSet[0].getRowIndex());
+                    this.getModel().setValue(ContributionConstant.NCKD_SCOREITEMSUB, null,changeSet[0].getRowIndex());
+                    this.getView().updateView(ContributionConstant.NCKD_SCOREITEMSUB,changeSet[0].getRowIndex());
+                }
+            }
+        }
+    }
+
 }

+ 76 - 0
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/plugin/form/initial/impt/ScoreInitialImportPlugin.java

@@ -0,0 +1,76 @@
+package nckd.jxccl.hr.psms.plugin.form.initial.impt;
+
+import com.google.common.collect.Lists;
+import kd.bos.dataentity.OperateOption;
+import kd.bos.orm.query.QCP;
+import kd.bos.orm.query.QFilter;
+import kd.hr.hbp.formplugin.web.HRDataBaseList;
+import kd.hr.impt.common.dto.ImportBillData;
+import kd.hr.impt.common.dto.ImptPluginContext;
+import kd.hr.impt.common.plugin.AfterLoadStartPageEventArgs;
+import kd.hr.impt.common.plugin.BeforeCallOperationEventArgs;
+import kd.hr.impt.common.plugin.BeforeShowTemplateSelectListEventArgs;
+import kd.hr.impt.common.plugin.HRImportPlugin;
+import nckd.jxccl.base.common.constant.FormConstant;
+import nckd.jxccl.hr.psms.common.PositionStructureConstant;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+* 新入职人员初定/在职人员初定导入插件
+* 实体标识:gradedpersonquery
+* @author W.Y.C
+* @date 2025/10/31 14:04
+* @version 1.0
+*/
+public class ScoreInitialImportPlugin extends HRDataBaseList implements HRImportPlugin {
+
+    private static String SETTINGJOBGRADE_TPL = "settingjobgradetpl";
+    private static String SETTINGJOBGRADENEW_TPL = "settingjobgradenewtpl";
+    public ScoreInitialImportPlugin() {
+    }
+
+    //kd.hrmp.hbpm.formplugin.web.impt.PositionReviseHRImportPlugin,校验例子
+    //kd.hr.haos.formplugin.web.impo.OrgBatchHRImportPlugin,校验例子
+
+
+    @Override
+    public void afterLoadStartPage(AfterLoadStartPageEventArgs args) {
+        // 启用串行模式:先校验所有数据,再统一入库
+        // 开启之后如有校验失败,前端会提示:数据校验失败
+        args.setSerialModel(true);
+    }
+
+    @Override
+    public void beforeShowTemplateSelectList(BeforeShowTemplateSelectListEventArgs args) {
+        List<QFilter> fileter = args.getqFilterList();
+        if(fileter == null){
+            fileter = Lists.newArrayList();
+        }
+        //模板列表只显示:新入职人员初定/在职人员初定导入模板
+        fileter.add(new QFilter(FormConstant.NUMBER_KEY, QCP.in, new String[]{SETTINGJOBGRADE_TPL,SETTINGJOBGRADENEW_TPL}));
+        args.setqFilterList(fileter);
+    }
+
+    @Override
+    public void beforeCallOperation(BeforeCallOperationEventArgs args) {
+        String mainEntityId = ((ImportBillData)args.getImportBillDatas().get(0)).getMainEntityId();
+        OperateOption operateOption = (OperateOption)args.getOperateOptions().get(mainEntityId);
+        Map<String, String> submitOPs = args.getSubmitOPs();
+        String targetKey = PositionStructureConstant.NCKD_PERSONPOSFILE.toLowerCase();
+        //删除默认save方法
+        submitOPs.entrySet().removeIf(entry -> entry.getKey().toLowerCase().equals(targetKey));
+
+        ImptPluginContext context = args.getContext();
+        String tplNumber = context.getTplNumber();
+
+        if(tplNumber.equalsIgnoreCase(SETTINGJOBGRADE_TPL)){
+            //调用在职人员初定OP
+            submitOPs.put(PositionStructureConstant.NCKD_PERSONPOSFILE.toLowerCase(),"servinginitial");
+        }else if(tplNumber.equalsIgnoreCase(SETTINGJOBGRADENEW_TPL)){
+            //调用新入职人员初定OP
+            submitOPs.put(PositionStructureConstant.NCKD_PERSONPOSFILE.toLowerCase(),"newhireinitial");
+        }
+    }
+}

+ 88 - 0
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/plugin/form/performance/LevelConditionConfFormPlugin.java

@@ -0,0 +1,88 @@
+package nckd.jxccl.hr.psms.plugin.form.performance;
+
+import kd.bos.dataentity.entity.DynamicObject;
+import kd.bos.entity.datamodel.events.ChangeData;
+import kd.bos.entity.datamodel.events.PropertyChangedArgs;
+import kd.bos.form.field.BasedataEdit;
+import kd.bos.form.field.events.BeforeF7SelectEvent;
+import kd.bos.form.field.events.BeforeF7SelectListener;
+import kd.bos.form.plugin.AbstractFormPlugin;
+import kd.bos.orm.query.QCP;
+import kd.bos.orm.query.QFilter;
+import kd.sdk.plugin.Plugin;
+import nckd.jxccl.base.common.constant.FormConstant;
+import nckd.jxccl.base.common.utils.ConvertUtil;
+import nckd.jxccl.hr.psms.business.JobLevelCalculatorService;
+import nckd.jxccl.hr.psms.common.ContributionConstant;
+import nckd.jxccl.hr.psms.common.PerfRankMgmtConstant;
+import nckd.jxccl.hr.psms.common.PositionStructureConstant;
+
+import java.util.Arrays;
+import java.util.EventObject;
+import java.util.List;
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+/**
+* 升保降级条件配置
+* 实体标识:nckd_levelconditionconf
+* @author W.Y.C
+* @date 2025/11/2 21:01
+* @version 1.0
+*/
+public class LevelConditionConfFormPlugin extends AbstractFormPlugin implements Plugin, BeforeF7SelectListener {
+
+    @Override
+    public void registerListener(EventObject e) {
+        super.registerListener(e);
+
+        // 为分录中的A字段添加值变化监听
+        BasedataEdit minJobLevelEdit = this.getView().getControl(PerfRankMgmtConstant.NCKD_MINJOBLEVEL);
+        if (minJobLevelEdit != null) {
+            minJobLevelEdit.addBeforeF7SelectListener(this);
+        }
+
+        BasedataEdit maxJobLevelEdit = this.getView().getControl(PerfRankMgmtConstant.NCKD_MAXJOBLEVEL);
+        if (maxJobLevelEdit != null) {
+            maxJobLevelEdit.addBeforeF7SelectListener(this);
+        }
+    }
+
+    @Override
+    public void beforeF7Select(BeforeF7SelectEvent e) {
+        String fieldKey = e.getProperty().getName();
+
+        //基础资料联动
+        // 仅处理B字段的F7事件
+        if (PerfRankMgmtConstant.NCKD_MINJOBLEVEL.equalsIgnoreCase(fieldKey) || PerfRankMgmtConstant.NCKD_MAXJOBLEVEL.equalsIgnoreCase(fieldKey)) {
+            DynamicObject jobSeq = ConvertUtil.toDynamicObjectOrNull(this.getModel().getValue(PositionStructureConstant.NCKD_JOBSEQ));
+            if(jobSeq != null){
+                DynamicObject[] jobLevelByJobSeq = JobLevelCalculatorService.getJobLevelByJobSeq(jobSeq);
+                List<Long> jobLevelIds = Arrays.stream(jobLevelByJobSeq).map(dynamicObject -> dynamicObject.getLong(FormConstant.ID_KEY)).collect(Collectors.toList());
+                QFilter filter = new QFilter(ContributionConstant.ID_KEY, QCP.in, jobLevelIds);
+                e.addCustomQFilter(filter);
+
+            }else{
+                this.getView().showTipNotification("请先选择“职位序列”");
+                e.setCancel( true);
+            }
+
+        }
+    }
+
+    @Override
+    public void propertyChanged(PropertyChangedArgs e) {
+        String name = e.getProperty().getName();
+        if(FormConstant.NCKD_JOBSEQ.equalsIgnoreCase(name)){
+            ChangeData[] changeSet = e.getChangeSet();
+            Object newValue = changeSet[0].getNewValue();
+            Object oldValue = changeSet[0].getOldValue();
+            if(newValue != null && !Objects.equals(newValue, oldValue)) {
+                this.getModel().setValue(PerfRankMgmtConstant.NCKD_MINJOBLEVEL, null);
+                this.getModel().setValue(PerfRankMgmtConstant.NCKD_MAXJOBLEVEL, null);
+                this.getView().updateView(PerfRankMgmtConstant.NCKD_MINJOBLEVEL);
+                this.getView().updateView(PerfRankMgmtConstant.NCKD_MAXJOBLEVEL);
+            }
+        }
+    }
+}

+ 0 - 8
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/plugin/form/performance/PerfrankMgmtFormPlugin.java

@@ -1,14 +1,10 @@
 package nckd.jxccl.hr.psms.plugin.form.performance;
 
-import com.google.common.collect.Lists;
-import kd.bos.bill.IBillView;
-import kd.bos.bill.OperationStatus;
 import kd.bos.common.enums.EnableEnum;
 import kd.bos.dataentity.OperateOption;
 import kd.bos.dataentity.RefObject;
 import kd.bos.dataentity.entity.DynamicObject;
 import kd.bos.dataentity.entity.DynamicObjectCollection;
-import kd.bos.dataentity.metadata.IDataEntityProperty;
 import kd.bos.dataentity.metadata.dynamicobject.DynamicObjectType;
 import kd.bos.entity.EntityMetadataCache;
 import kd.bos.entity.QueryEntityType;
@@ -29,8 +25,6 @@ import kd.bos.form.events.AfterDoOperationEventArgs;
 import kd.bos.form.events.BeforeDoOperationEventArgs;
 import kd.bos.form.events.MessageBoxClosedEvent;
 import kd.bos.form.operate.FormOperate;
-import kd.bos.form.plugin.AbstractFormPlugin;
-import kd.bos.form.plugin.IFormPlugin;
 import kd.bos.logging.Log;
 import kd.bos.logging.LogFactory;
 import kd.bos.orm.query.QCP;
@@ -48,8 +42,6 @@ import nckd.jxccl.base.common.utils.QueryFieldBuilder;
 import nckd.jxccl.hr.psms.common.PerfRankMgmtConstant;
 import nckd.jxccl.hr.psms.common.PositionStructureConstant;
 import nckd.jxccl.hr.psms.helper.PositionFileHelper;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.commons.lang3.Strings;
 
 import java.time.temporal.ChronoUnit;
 import java.util.Arrays;

+ 3 - 1
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/plugin/operate/adjust/NewDynamicAdjustmentOperationPlugIn.java

@@ -256,7 +256,9 @@ public class NewDynamicAdjustmentOperationPlugIn extends AbstractOperationServic
         position.set(FormConstant.ID_KEY, positionId);
         Long jobSeqId = empPosOrgRel.getLong(String.join(".", FormConstant.HBPM_POSITIONHR, FormConstant.NCKD_JOBSEQ, FormConstant.ID_KEY));
         DynamicObject jobSeq = BusinessDataServiceHelper.newDynamicObject(FormConstant.HBJM_JOBSEQHR);
-        jobSeq.set(FormConstant.ID_KEY, jobSeqId);
+        //档案里面存储转换后的序列
+        DynamicObject newJob = JobLevelCalculatorService.handleJobSeq(jobSeq);
+        jobSeq.set(FormConstant.ID_KEY, newJob.getLong(FormConstant.ID_KEY));
         newPersonPosFile.set(PositionStructureConstant.NCKD_JOBSEQHR, jobSeq);
         newPersonPosFile.set(PositionStructureConstant.NCKD_POSITIONHR, position);
         newPersonPosFile.set(PositionStructureConstant.NCKD_RANKNAME, jobLevelResult.jobScoreInfo.rankName);

+ 4 - 1
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/plugin/operate/contribution/ContribBillOpPlugin.java

@@ -16,6 +16,7 @@ import kd.bos.entity.validate.ErrorLevel;
 import kd.bos.form.MessageBoxResult;
 import kd.sdk.plugin.Plugin;
 import nckd.jxccl.base.common.constant.FormConstant;
+import nckd.jxccl.base.common.utils.ConvertUtil;
 import nckd.jxccl.base.common.utils.StrFormatter;
 import nckd.jxccl.hr.psms.common.ContributionConstant;
 import nckd.jxccl.hr.psms.helper.ContributionHelper;
@@ -60,6 +61,7 @@ public class ContribBillOpPlugin extends AbstractOperationServicePlugIn implemen
                             Date date = data.getDate(ContributionConstant.NCKD_YEAR);
                             DynamicObject scoreItem = data.getDynamicObject(ContributionConstant.NCKD_SCOREITEM);
                             DynamicObject scoreItemSub = data.getDynamicObject(ContributionConstant.NCKD_SCOREITEMSUB);
+                            DynamicObject scoreItemRank = data.getDynamicObject(ContributionConstant.NCKD_SCOREITEMRANK);
                             List<ContributionHelper.ScoreItemValidScore> scoreItemValidScoreList = new ArrayList<>(entryEntity.size());
                             for (DynamicObject entry : entryEntity) {
                                 DynamicObject person = entry.getDynamicObject(ContributionConstant.NCKD_PERSON);
@@ -67,7 +69,8 @@ public class ContribBillOpPlugin extends AbstractOperationServicePlugIn implemen
                                 ContributionHelper.ScoreItemValidScore scoreItemValidScore = new ContributionHelper.ScoreItemValidScore(
                                         person.getLong(FormConstant.ID_KEY),
                                         scoreItem.getLong(FormConstant.ID_KEY),
-                                        scoreItemSub.getLong(FormConstant.ID_KEY));
+                                        scoreItemSub.getLong(FormConstant.ID_KEY),
+                                        scoreItemRank != null ? scoreItemRank.getLong(FormConstant.ID_KEY) : null);
                                 scoreItemValidScore.setCurrentScore(oriScore);
                                 scoreItemValidScoreList.add(scoreItemValidScore);
                             }

+ 59 - 0
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/plugin/operate/contribution/validate/LevelConditionConfValidate.java

@@ -0,0 +1,59 @@
+package nckd.jxccl.hr.psms.plugin.operate.contribution.validate;
+
+import kd.bos.dataentity.entity.DynamicObject;
+import kd.bos.entity.ExtendedDataEntity;
+import kd.bos.entity.datamodel.events.PropertyChangedArgs;
+import kd.bos.entity.validate.AbstractValidator;
+import kd.bos.form.plugin.AbstractFormPlugin;
+import kd.bos.orm.query.QCP;
+import kd.bos.orm.query.QFilter;
+import kd.sdk.plugin.Plugin;
+import nckd.jxccl.base.common.constant.FormConstant;
+import nckd.jxccl.base.common.utils.StrFormatter;
+import nckd.jxccl.hr.psms.common.PerfRankMgmtConstant;
+import nckd.jxccl.hr.psms.helper.PositionFileHelper;
+import nckd.jxccl.hr.psms.helper.data.JobLevelRuleConfig;
+
+import java.util.List;
+
+/**
+* 升保降级条件配置-校验
+* 实体标识:nckd_levelconditionconf
+* @author W.Y.C
+* @date 2025/11/3 13:05
+* @version 1.0
+*/
+public class LevelConditionConfValidate extends AbstractValidator {
+
+    @Override
+    public void validate() {
+        for (ExtendedDataEntity dataEntity : this.getDataEntities()) {
+            DynamicObject data = dataEntity.getDataEntity();
+            long id = data.getLong(FormConstant.ID_KEY);
+            List<JobLevelRuleConfig> levelConditionConf = PositionFileHelper.getLevelConditionConf(new QFilter(FormConstant.ID_KEY, QCP.not_equals, id));
+            DynamicObject jobSeq = data.getDynamicObject(FormConstant.NCKD_JOBSEQ);
+            DynamicObject minJobLevel = data.getDynamicObject(PerfRankMgmtConstant.NCKD_MINJOBLEVEL);
+            int minJobLevelSeq = minJobLevel.getInt(FormConstant.JOBLEVELSEQ);
+            DynamicObject maxJobLevel = data.getDynamicObject(PerfRankMgmtConstant.NCKD_MAXJOBLEVEL);
+            int maxJobLevelSeq = maxJobLevel != null ? maxJobLevel.getInt(FormConstant.JOBLEVELSEQ) : Integer.MAX_VALUE;
+            for (JobLevelRuleConfig jobLevelRuleConfig : levelConditionConf) {
+                String jobSeqNumber = jobLevelRuleConfig.getJobSeqNumber();
+                Integer maxJobLevelSeq1 = jobLevelRuleConfig.getMaxJobLevelSeq();
+                Integer minJobLevelSeq1 = jobLevelRuleConfig.getMinJobLevelSeq();
+                //相同序列,最大职级和最小职级不能重叠
+                if (jobSeq != null && jobSeq.getString(FormConstant.NUMBER_KEY).equals(jobSeqNumber)) {
+                    // 处理空值情况,null表示无限制
+                    int existingMaxLevel = maxJobLevelSeq1 != null ? maxJobLevelSeq1 : Integer.MAX_VALUE;
+                    int existingMinLevel = minJobLevelSeq1 != null ? minJobLevelSeq1 : Integer.MIN_VALUE;
+                    // 判断职级范围是否重叠
+                    boolean overlap = !(minJobLevelSeq > existingMaxLevel || maxJobLevelSeq < existingMinLevel);
+                    if (overlap) {
+                        this.addMessage(dataEntity, StrFormatter.format("职级范围与已有配置重叠【{}】,请调整最小职级或最大职级。", jobLevelRuleConfig.getName()));
+                    }
+                }
+            }
+
+        }
+    }
+
+}

+ 102 - 0
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/plugin/operate/contribution/validate/ScoreItemConfValidate.java

@@ -0,0 +1,102 @@
+package nckd.jxccl.hr.psms.plugin.operate.contribution.validate;
+
+import kd.bos.dataentity.entity.DynamicObject;
+import kd.bos.dataentity.entity.DynamicObjectCollection;
+import kd.bos.entity.ExtendedDataEntity;
+import kd.bos.entity.validate.AbstractValidator;
+import kd.bos.orm.query.QCP;
+import kd.bos.orm.query.QFilter;
+import nckd.jxccl.base.common.constant.FormConstant;
+import nckd.jxccl.base.common.utils.StrFormatter;
+import nckd.jxccl.hr.psms.common.ContributionConstant;
+import nckd.jxccl.hr.psms.helper.ContributionHelper;
+import org.apache.commons.lang3.StringUtils;
+
+import java.math.BigDecimal;
+import java.util.Date;
+import java.util.Map;
+import java.util.Objects;
+import java.util.StringJoiner;
+import java.util.stream.Collectors;
+
+/**
+ * 动态表单插件
+ */
+/**
+* 积分项目分数配置校验
+* 实体标识:nckd_scoreitemconf
+* @author W.Y.C
+* @date 2025/11/2 13:02
+* @version 1.0
+*/
+public class ScoreItemConfValidate extends AbstractValidator {
+
+    @Override
+    public void validate() {
+
+        //查询其他有效日期内的数据
+
+        for (ExtendedDataEntity dataEntity : this.getDataEntities()) {
+            DynamicObject data = dataEntity.getDataEntity();
+            long id = data.getLong(FormConstant.ID_KEY);
+            Date startDate = data.getDate(FormConstant.NCKD_STARTDATE);
+            Date endDate = data.getDate(FormConstant.NCKD_ENDDATE);
+
+            QFilter filter = new QFilter(FormConstant.ID_KEY, QCP.not_equals,id);
+            Map<String, BigDecimal> scoreConfMap = ContributionHelper.getScoreConf(filter);
+
+            //判定是否在有效期内,endDate为空时,默认为不失效
+            // if (startDate != null && (endDate == null || !endDate.before(new Date()))) {
+                //校验有效时间范围内有没有重复配置
+                DynamicObjectCollection dynamicObjectCollection = data.getDynamicObjectCollection(FormConstant.NCKD_ENTRYENTITY);
+                Map<String, DynamicObject> scoreMap = dynamicObjectCollection.stream()
+                .filter(Objects::nonNull)
+                .collect(Collectors.toMap(
+                        item -> {
+                            DynamicObject scoreItem = item.getDynamicObject(ContributionConstant.NCKD_SCOREITEM);
+                            DynamicObject scoreItemSub = item.getDynamicObject(ContributionConstant.NCKD_SCOREITEMSUB);
+                            DynamicObject scoreItemRank = item.getDynamicObject(ContributionConstant.NCKD_SCOREITEMRANK);
+
+                            long scoreItemId = (scoreItem != null) ? scoreItem.getLong(FormConstant.ID_KEY) : 0L;
+                            long scoreItemSubId = (scoreItemSub != null) ? scoreItemSub.getLong(FormConstant.ID_KEY) : 0L;
+                            long scoreItemRankId = (scoreItemRank != null) ? scoreItemRank.getLong(FormConstant.ID_KEY) : 0L;
+
+                            if (scoreItemRankId > 0) {
+                                return scoreItemId + "-" + scoreItemSubId + "-" + scoreItemRankId;
+                            } else if (scoreItemSubId > 0) {
+                                return scoreItemId + "-" + scoreItemSubId;
+                            } else {
+                                return String.valueOf(scoreItemId);
+                            }
+                        },
+                        item -> item,
+                        (existing, replacement) -> existing
+                ));
+                for (Map.Entry<String, DynamicObject> entry : scoreMap.entrySet()) {
+                    String key = entry.getKey();
+                    DynamicObject dynamicObject = entry.getValue();
+                    if(scoreConfMap.get(key) != null){
+                        DynamicObject scoreItem = dynamicObject.getDynamicObject(ContributionConstant.NCKD_SCOREITEM);
+                        DynamicObject scoreItemSub = dynamicObject.getDynamicObject(ContributionConstant.NCKD_SCOREITEMSUB);
+                        DynamicObject scoreItemRank = dynamicObject.getDynamicObject(ContributionConstant.NCKD_SCOREITEMRANK);
+
+                        String scoreItemName = (scoreItem != null) ? scoreItem.getString(FormConstant.NAME_KEY) : null;
+                        String scoreItemSubName = (scoreItemSub != null) ? scoreItemSub.getString(FormConstant.NAME_KEY) : null;
+                        String scoreItemRankName = (scoreItemRank != null) ? scoreItemRank.getString(FormConstant.NAME_KEY) : null;
+                        StringJoiner joiner = new StringJoiner("-");
+                        if (StringUtils.isNotEmpty(scoreItemName)) {
+                            joiner.add(scoreItemName);
+                        }
+                        if (StringUtils.isNotEmpty(scoreItemSubName)) {
+                            joiner.add(scoreItemSubName);
+                        }
+                        if (StringUtils.isNotEmpty(scoreItemRankName)) {
+                            joiner.add(scoreItemRankName);
+                        }
+                        this.addErrorMessage(dataEntity, StrFormatter.format("【{}】已存在生效中的配置。不能重复配置", joiner.toString()));
+                    }
+                }
+            // }
+        }
+    }
+}

+ 8 - 8
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/plugin/operate/initial/BaseInitialOperationPlugIn.java

@@ -1,5 +1,6 @@
 package nckd.jxccl.hr.psms.plugin.operate.initial;
 
+import com.google.common.collect.Lists;
 import kd.bos.common.enums.EnableEnum;
 import kd.bos.context.RequestContext;
 import kd.bos.dataentity.entity.DynamicObject;
@@ -43,7 +44,7 @@ public abstract class BaseInitialOperationPlugIn extends AbstractOperationServic
     
     protected final static Log logger = LogFactory.getLog(BaseInitialOperationPlugIn.class);
 
-    public List<BaseInitialData> baseInitialData;
+    public List<BaseInitialData> baseInitialData = Lists.newArrayList();
 
     /**
      * 基本信息数据对象
@@ -71,6 +72,8 @@ public abstract class BaseInitialOperationPlugIn extends AbstractOperationServic
         DynamicObject dep;
         /** 职位序列 */
         DynamicObject jobSeq;
+        /** 职位序列(转换后) */
+        DynamicObject convertJobSeq;
         /** 职位序列-编码 */
         String jobSeqNumber;
         /** 职位序列-名称 */
@@ -116,9 +119,6 @@ public abstract class BaseInitialOperationPlugIn extends AbstractOperationServic
      * @date: 2025/10/12 14:20
      */
     protected List<BaseInitialData> extractBasicInfo(DynamicObject initialData) {
-        if(baseInitialData != null){
-            return baseInitialData;
-        }
         List<BaseInitialData> dataList = new ArrayList<>();
         if(initialData.containsProperty(FormConstant.NCKD_ENTRYENTITY)){
             DynamicObjectCollection dynamicObjectCollection = initialData.getDynamicObjectCollection(FormConstant.NCKD_ENTRYENTITY);
@@ -126,14 +126,14 @@ public abstract class BaseInitialOperationPlugIn extends AbstractOperationServic
                 //批量初定
                 BaseInitialData data = getBaseInitialData(dynamicObject);
                 dataList.add(data);
+                baseInitialData.add(data);
             }
         }else{
             BaseInitialData data = getBaseInitialData(initialData);
             dataList.add(data);
+            baseInitialData.add(data);
         }
-
-        baseInitialData = dataList;
-        return baseInitialData;
+        return dataList;
     }
 
     @NotNull
@@ -366,7 +366,7 @@ public abstract class BaseInitialOperationPlugIn extends AbstractOperationServic
         personPosFile.set(PositionStructureConstant.NCKD_FIRSTRANK, EnableEnum.YES.getCode());
         personPosFile.set(PositionStructureConstant.NCKD_BEGINDATE, data.beginDate);
         personPosFile.set(PositionStructureConstant.NCKD_APPRAISALRESULT, data.lastYearAppraisalResult);
-        personPosFile.set(PositionStructureConstant.NCKD_JOBSEQHR, data.jobSeq);
+        personPosFile.set(PositionStructureConstant.NCKD_JOBSEQHR, data.convertJobSeq);
         personPosFile.set(PositionStructureConstant.NCKD_POSITIONHR, data.positionHr);
         /*personPosFile.set(PositionStructureConstant.USEORG_KEY, data.company);
         personPosFile.set(PositionStructureConstant.CREATEORG_KEY, data.dep);

+ 25 - 14
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/plugin/operate/initial/NewHireInitialOperationPlugIn.java

@@ -8,6 +8,7 @@ import kd.bos.entity.plugin.args.EndOperationTransactionArgs;
 import kd.bos.entity.plugin.args.RollbackOperationArgs;
 import kd.bos.entity.validate.AbstractValidator;
 import nckd.jxccl.base.common.constant.FormConstant;
+import nckd.jxccl.base.common.exception.ValidationException;
 import nckd.jxccl.base.common.utils.DateUtil;
 import nckd.jxccl.base.common.utils.StrFormatter;
 import nckd.jxccl.hr.psms.business.JobLevelCalculatorService;
@@ -15,9 +16,12 @@ import nckd.jxccl.hr.psms.helper.PositionFileHelper;
 
 import java.math.BigDecimal;
 import java.util.Date;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
+import java.util.StringJoiner;
 
 /**
  * 新入职人员初定-确认定级操作OP
@@ -38,26 +42,35 @@ public class NewHireInitialOperationPlugIn extends BaseInitialOperationPlugIn {
                     return;
                 }
                 Date currentDate = new Date();
+                Set<Long> personIds = new HashSet<>();
+                Map<Long,Integer> personDataEntityMap = new HashMap<>();
                 for (ExtendedDataEntity rowDataEntity : getDataEntities()) {
                     DynamicObject data = rowDataEntity.getDataEntity();
                     //提取信息
                     List<BaseInitialData> newHireInitialDataList =  extractBasicInfo(data);
 
+                    int dataEntityIndex = rowDataEntity.getDataEntityIndex();
                     // 检查人员ID重复
-                    Set<Long> personIds = new HashSet<>();
                     for (BaseInitialData newHireInitialData : newHireInitialDataList) {
                         if (newHireInitialData.person != null) {
                             Long personId = newHireInitialData.person.getLong(FormConstant.ID_KEY);
                             if (!personIds.add(personId)) {
+                                Integer i = personDataEntityMap.get(personId);
+                                if(i != null){
+                                    //将上一个重复人员也标记为错误
+                                    addFatalErrorMessage(getDataEntities()[i],
+                                            StrFormatter.format("人员【{}】在列表中重复,请保留一条信息",
+                                                    newHireInitialData.person.getString(FormConstant.NAME_KEY)));
+                                }
                                 addFatalErrorMessage(rowDataEntity,
                                         StrFormatter.format("人员【{}】在列表中重复,请保留一条信息",
                                                 newHireInitialData.person.getString(FormConstant.NAME_KEY)));
                             }
+                            personDataEntityMap.put(personId,dataEntityIndex);
                         }
                     }
-                    if(!this.getValidateResult().isSuccess()){
-                        return;
-                    }
+
+
 
                     for (BaseInitialData newHireInitialData : newHireInitialDataList) {
                         Date beginDate = newHireInitialData.beginDate;
@@ -106,9 +119,7 @@ public class NewHireInitialOperationPlugIn extends BaseInitialOperationPlugIn {
         if(this.getOperationResult().isSuccess()) {
             //对应SHR:com.kingdee.shr.customer.web.handler.ContributeScore.PersonpositionfileListHandler#addNewPersonpositionfileInfo
             logger.info("【职位体系】-新入职人员初定-开始");
-            for (DynamicObject servingInitial : e.getDataEntities()) {
-                processNewHireInitialData(servingInitial);
-            }
+            processNewHireInitialData();
         }
     }
 
@@ -124,13 +135,10 @@ public class NewHireInitialOperationPlugIn extends BaseInitialOperationPlugIn {
 
     /**
      * 处理单个在职人员初定
-     * @param newHireInitial 新入职人员初定数据对象
      */
-    private void processNewHireInitialData(DynamicObject newHireInitial) {
+    private void processNewHireInitialData() {
 
-        //提取信息
-        List<BaseInitialData> dataList =  extractBasicInfo(newHireInitial);
-        for (BaseInitialData data : dataList) {
+        for (BaseInitialData data : baseInitialData) {
 
             String logPrefix = StrFormatter.format("【职位体系】-新入职人员初定-人员【{}({})】",
                     data.person.getString(FormConstant.NAME_KEY),
@@ -159,13 +167,16 @@ public class NewHireInitialOperationPlugIn extends BaseInitialOperationPlugIn {
             // 计算职级
             //当考核结果为无时,职级定为最低级
             boolean useMinLevel = data.lastYearAppraisalResultEnum == nckd.jxccl.base.common.enums.AppraisalResultEnum.NONE;
+            // 如果是管理序列,则按职能序列进行初定
+            data.convertJobSeq = JobLevelCalculatorService.handleJobSeq(data.jobSeq);
             //【三期需求】-不满足三要素(聘任职称/技能、考核结果、积分)按"无职级"初定
             String perProTitleNumber = scoreData.dbProTitleLevel != null ? scoreData.dbProTitleLevel.getString(FormConstant.NUMBER_KEY) : null;
             String quaLevelNumber = scoreData.dbOcpQualLevel != null ? scoreData.dbOcpQualLevel.getString(FormConstant.NUMBER_KEY) : null;
-            boolean threeElementMeet = JobLevelCalculatorService.checkThreeElementsRequirement(data.jobSeq, allSumScore, scoreData.dbProTitleLevel,
+            boolean threeElementMeet = JobLevelCalculatorService.checkThreeElementsRequirement(data.convertJobSeq, allSumScore, scoreData.dbProTitleLevel,
                     scoreData.dbOcpQualLevel, data.lastYearAppraisalResultEnum);
+
             DynamicObject jobLeve = JobLevelCalculatorService.getJobLevel(
-                    data.jobSeq, allSumScore, perProTitleNumber,
+                    data.convertJobSeq, allSumScore, perProTitleNumber,
                     quaLevelNumber,data.downgradeNum,useMinLevel,!threeElementMeet);
             if(jobLeve != null) {
                 // 构建职位档案并存入数据库

+ 23 - 14
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/plugin/operate/initial/ServingInitialOperationPlugIn.java

@@ -18,8 +18,10 @@ import nckd.jxccl.hr.psms.helper.PositionFileHelper;
 import java.math.BigDecimal;
 import java.time.LocalDateTime;
 import java.util.Date;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 
 /**
@@ -40,26 +42,33 @@ public class ServingInitialOperationPlugIn extends BaseInitialOperationPlugIn {
                     return;
                 }
                 Date currentDate = new Date();
+
+                Set<Long> personIds = new HashSet<>();
+                Map<Long,Integer> personDataEntityMap = new HashMap<>();
                 for (ExtendedDataEntity rowDataEntity : getDataEntities()) {
                     DynamicObject data = rowDataEntity.getDataEntity();
                     //提取信息
                     List<BaseInitialData> servingInitialDataList = extractBasicInfo(data);
-
+                    int dataEntityIndex = rowDataEntity.getDataEntityIndex();
                     // 检查人员ID重复
-                    Set<Long> personIds = new HashSet<>();
                     for (BaseInitialData servingInitialData : servingInitialDataList) {
                         if (servingInitialData.person != null) {
                             Long personId = servingInitialData.person.getLong(FormConstant.ID_KEY);
                             if (!personIds.add(personId)) {
+                                Integer i = personDataEntityMap.get(personId);
+                                if(i != null){
+                                    //将上一个重复人员也标记为错误
+                                    addFatalErrorMessage(getDataEntities()[i],
+                                            StrFormatter.format("人员【{}】在列表中重复,请保留一条信息",
+                                                    servingInitialData.person.getString(FormConstant.NAME_KEY)));
+                                }
                                 addFatalErrorMessage(rowDataEntity,
                                         StrFormatter.format("人员【{}】在列表中重复,请保留一条信息",
                                                 servingInitialData.person.getString(FormConstant.NAME_KEY)));
-                                return;
                             }
+                            personDataEntityMap.put(personId,dataEntityIndex);
                         }
-                    }
-                    if(!this.getValidateResult().isSuccess()){
-                        return;
+
                     }
 
                     for (BaseInitialData servingInitialData : servingInitialDataList) {
@@ -117,9 +126,8 @@ public class ServingInitialOperationPlugIn extends BaseInitialOperationPlugIn {
         if(this.getOperationResult().isSuccess()) {
             //对应SHR:com.kingdee.shr.customer.web.handler.ContributeScore.PersonpositionfileListHandler#addNewPersonpositionfileInfo_older
             logger.info("【职位体系】-在职人员初定-开始");
-            for (DynamicObject servingInitial : e.getDataEntities()) {
-                processServingInitial(servingInitial);
-            }
+            processServingInitial();
+
         }
     }
 
@@ -135,12 +143,10 @@ public class ServingInitialOperationPlugIn extends BaseInitialOperationPlugIn {
 
     /**
      * 处理单个在职人员初定
-     * @param servingInitial 在职人员初定数据对象
      */
-    private void processServingInitial(DynamicObject servingInitial) {
+    private void processServingInitial() {
         // 提取基本信息
-        List<BaseInitialData> dataList = extractBasicInfo(servingInitial);
-        for (BaseInitialData data : dataList) {
+        for (BaseInitialData data : baseInitialData) {
             String logPrefix = StrFormatter.format("【职位体系】-在职人员初定-人员【{}({})】",
                     data.person.getString(FormConstant.NAME_KEY),
                     data.person.getString(FormConstant.EMP_NUMBER_KEY));
@@ -160,13 +166,16 @@ public class ServingInitialOperationPlugIn extends BaseInitialOperationPlugIn {
             // 计算累计积分池(生涯积分)
             BigDecimal sumScore = calculateSumScore(data.allSumScore, scoreData, logPrefix);
 
+            // 如果是管理序列,则按职能序列进行初定
+            data.convertJobSeq = JobLevelCalculatorService.handleJobSeq(data.jobSeq);
+
             // 计算职级
             //当考核结果为无时,职级定为最低级
             boolean useMinLevel = data.lastYearAppraisalResultEnum == nckd.jxccl.base.common.enums.AppraisalResultEnum.NONE;
             String perProTitleNumber = scoreData.dbProTitleLevel != null ? scoreData.dbProTitleLevel.getString(FormConstant.NUMBER_KEY) : null;
             String quaLevelNumber = scoreData.dbOcpQualLevel != null ? scoreData.dbOcpQualLevel.getString(FormConstant.NUMBER_KEY) : null;
             DynamicObject jobLeve = JobLevelCalculatorService.getJobLevel(
-                    data.jobSeq, data.allSumScore, perProTitleNumber,
+                    data.convertJobSeq, data.allSumScore, perProTitleNumber,
                     quaLevelNumber,  data.downgradeNum,useMinLevel,Boolean.FALSE);
 
             if(jobLeve != null) {

+ 7 - 0
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/plugin/report/adjust/UnAdjustedReportFormPlugin.java

@@ -1,6 +1,7 @@
 package nckd.jxccl.hr.psms.plugin.report.adjust;
 
 import kd.bos.dataentity.entity.DynamicObject;
+import kd.bos.entity.report.ReportQueryParam;
 import kd.bos.form.CloseCallBack;
 import kd.bos.form.FormShowParameter;
 import kd.bos.form.ShowType;
@@ -44,6 +45,12 @@ public class UnAdjustedReportFormPlugin extends AbstractReportFormPlugin impleme
         this.addItemClickListeners(FormConstant.TOOLBARAP);
     }
 
+    @Override
+    public void beforeQuery(ReportQueryParam queryParam) {
+        ReportList reportList = this.getControl("reportlistap");
+        reportList.setSelectedAll(true);
+    }
+
     @Override
     public void itemClick(ItemClickEvent evt) {
         String itemKey = evt.getItemKey();