| 
					
				 | 
			
			
				@@ -12,12 +12,13 @@ import nckd.jxccl.base.common.constant.FormConstant; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import nckd.jxccl.base.common.utils.DateUtil; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import nckd.jxccl.base.common.utils.QueryFieldBuilder; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import nckd.jxccl.base.orm.helper.QFilterCommonHelper; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-import nckd.jxccl.hr.psms.common.ContributionEvaluationConstant; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import nckd.jxccl.hr.psms.common.ContributionConstant; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import java.math.BigDecimal; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import java.time.LocalDateTime; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import java.util.ArrayList; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import java.util.Date; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import java.util.HashMap; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import java.util.List; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import java.util.Map; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import java.util.Objects; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -35,7 +36,7 @@ public class ContributionHelper { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				      * 根据人员获取积分项目有效分数 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				      * 依据人员某年度已获得的积分(含在途单据)+积分配置的最高分计算出可获得的分数 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				      * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     * @param scoreItemValidScoreList 待计算列表 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @param scoreItemValidScoreList 待计算列表(人员不能重复) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				      * @param year 年份 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				      * @param excludeBillId 排除的单据ID(计算有效分数不含当前单据),可为空 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				      * @return: ScoreItemValidScore 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -121,33 +122,43 @@ public class ContributionHelper { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         List<ScoreItemValidScore> result = getScoreItemValidScore(inputList, year, excludeBillId); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				      * 根据人员和年度获取积分项目已累计分数 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				      * @param personIds 人员 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				      * @param year 年度 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				      * @param excludeBillId 排除的单据ID(计算有效分数不含当前单据),可为空 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @param approvedOnly 是否只查询已审批通过的记录 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				      * @return: List<ScoreItemValidScore> 积分项目已累计分数 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				      * @author W.Y.C 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				      * @date: 2025/10/26 16:20 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				      */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    public static List<ScoreItemValidScore> getScoreItemAccumulateScore(Long[] personIds, Date year, Long excludeBillId) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    public static List<ScoreItemValidScore> getScoreItemAccumulateScore(Long[] personIds, Date year, Long excludeBillId, boolean approvedOnly) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         if (personIds == null || personIds.length == 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             return new ArrayList<>(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         LocalDateTime yearStarDateTime = DateUtil.beginOfYear(DateUtil.toLocalDateTime(year)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         QueryFieldBuilder scoreItemConfFieldBuilder = QueryFieldBuilder.create() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                .add(ContributionEvaluationConstant.NCKD_YEAR) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                .addIdNumberName(ContributionEvaluationConstant.NCKD_SCOREITEM) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                .addIdNumberName(ContributionEvaluationConstant.NCKD_SCOREITEMSUB) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                .addGroup(new String[]{FormConstant.NCKD_ENTRYENTITY,ContributionEvaluationConstant.NCKD_PERSON},FormConstant.ID_KEY) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                .addGroup(new String[]{FormConstant.NCKD_ENTRYENTITY}, ContributionEvaluationConstant.NCKD_SCORE,ContributionEvaluationConstant.NCKD_ORISCORE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        //查询非"审批不通过"、"已废弃"年度贡献积分 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        QFilter filter = new QFilter(FormConstant.BILL_STATUS_KEY, QCP.not_in, new String[]{"E", "F"}) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                .and(ContributionEvaluationConstant.NCKD_YEAR,QCP.large_equals,DateUtil.beginOfDay(yearStarDateTime)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                .and(ContributionEvaluationConstant.NCKD_YEAR,QCP.less_equals, DateUtil.endOfDay(yearStarDateTime)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                .and(String.join( ".",FormConstant.NCKD_ENTRYENTITY,ContributionEvaluationConstant.NCKD_PERSON),QCP.in,personIds); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                .add(ContributionConstant.NCKD_YEAR) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                .addIdNumberName(ContributionConstant.NCKD_SCOREITEM) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                .addIdNumberName(ContributionConstant.NCKD_SCOREITEMSUB) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                .addGroup(new String[]{FormConstant.NCKD_ENTRYENTITY, ContributionConstant.NCKD_PERSON},FormConstant.ID_KEY) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                .addGroup(new String[]{FormConstant.NCKD_ENTRYENTITY}, ContributionConstant.NCKD_SCORE, ContributionConstant.NCKD_ORISCORE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        //构建查询条件 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        QFilter filter; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (approvedOnly) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            //只查询"已审批通过"年度贡献积分 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            filter = QFilterCommonHelper.getBillStatusFilter(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            //查询非"审批不通过"、"已废弃"年度贡献积分 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            filter = new QFilter(FormConstant.BILL_STATUS_KEY, QCP.not_in, new String[]{"E", "F"}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        filter.and(ContributionConstant.NCKD_YEAR,QCP.large_equals,DateUtil.beginOfDay(yearStarDateTime)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                .and(ContributionConstant.NCKD_YEAR,QCP.less_equals, DateUtil.endOfDay(yearStarDateTime)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                .and(String.join( ".",FormConstant.NCKD_ENTRYENTITY, ContributionConstant.NCKD_PERSON),QCP.in,personIds); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         if(excludeBillId != null && excludeBillId > 0){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             filter.and(FormConstant.ID_KEY,QCP.not_equals,excludeBillId); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -156,31 +167,59 @@ public class ContributionHelper { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         List<ScoreItemValidScore> scoreItemValidScoreList = new ArrayList<>(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         try(AlgoContext context = Algo.newContext()) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             DataSet dateSet = QueryServiceHelper.queryDataSet(ContributionHelper.class.getName(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    ContributionEvaluationConstant.CONTRIBBILL_ENTITYID, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    ContributionConstant.CONTRIBBILL_ENTITYID, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     scoreItemConfFieldBuilder.buildSelect(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     new QFilter[]{filter}, null, 5000); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             DataSet sumDateSet = dateSet.copy() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     // 按人员、积分项目、积分项目子项进行分组 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    .groupBy(new String[]{String.join(".", ContributionEvaluationConstant.NCKD_ENTRYENTITY, ContributionEvaluationConstant.NCKD_PERSON, FormConstant.ID_KEY), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                            String.join(".", ContributionEvaluationConstant.NCKD_SCOREITEM, FormConstant.ID_KEY), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                            String.join(".", ContributionEvaluationConstant.NCKD_SCOREITEMSUB, FormConstant.ID_KEY)}) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    .sum(String.join(".", ContributionEvaluationConstant.NCKD_ENTRYENTITY, FormConstant.NCKD_SCORE),"sumScore").finish(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    .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)}) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    .sum(String.join(".", ContributionConstant.NCKD_ENTRYENTITY, FormConstant.NCKD_SCORE),"sumScore").finish(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             while (sumDateSet.hasNext()) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 Row row = sumDateSet.next(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                Long personId = row.getLong(String.join(".", ContributionEvaluationConstant.NCKD_ENTRYENTITY, ContributionEvaluationConstant.NCKD_PERSON, FormConstant.ID_KEY)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                Long scoreItemId = row.getLong(String.join(".", ContributionEvaluationConstant.NCKD_SCOREITEM, FormConstant.ID_KEY)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                Long scoreItemSubId = row.getLong(String.join(".", ContributionEvaluationConstant.NCKD_SCOREITEMSUB, FormConstant.ID_KEY)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                Long personId = row.getLong(String.join(".", ContributionConstant.NCKD_ENTRYENTITY, ContributionConstant.NCKD_PERSON, FormConstant.ID_KEY)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                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)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 //已获得的累计积分 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 BigDecimal sumScore = row.getBigDecimal("sumScore"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                ScoreItemValidScore scoreItemValidScore = new ScoreItemValidScore(personId, scoreItemId, scoreItemSubId, sumScore); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                ScoreItemValidScore scoreItemValidScore = new ScoreItemValidScore(personId, scoreItemId,scoreItemNumber, scoreItemSubId, sumScore); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 scoreItemValidScoreList.add(scoreItemValidScore); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         return scoreItemValidScoreList; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * 根据人员和年度获取积分项目已累计分数(包含所有未废弃记录) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @param personIds 人员 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @param year 年度 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @param excludeBillId 排除的单据ID(计算有效分数不含当前单据),可为空 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @return: List<ScoreItemValidScore> 积分项目已累计分数 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @author W.Y.C 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @date: 2025/10/26 16:20 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    public static List<ScoreItemValidScore> getScoreItemAccumulateScore(Long[] personIds, Date year, Long excludeBillId) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return getScoreItemAccumulateScore(personIds, year, excludeBillId, false); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * 根据人员和年度获取已审批通过的积分项目累计分数 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @param personIds 人员 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @param year 年度 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @return: List<ScoreItemValidScore> 积分项目已累计分数(仅包含已审批通过的记录) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @author W.Y.C 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @date: 2025/10/26 16:20 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    public static List<ScoreItemValidScore> getApprovedScoreItemAccumulateScore(Long[] personIds, Date year) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return getScoreItemAccumulateScore(personIds, year, null, true); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				      * 计算可获得的有效分数 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				      * 基于累计总分和限制分数,计算还可以获得多少分数(不超过限制) 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -188,7 +227,7 @@ public class ContributionHelper { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				      * @param scoreConfMap 分数配置映射表,key为配置ID,value为限分数值 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				      * @param scoreItemId 积分项目ID 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				      * @param scoreItemSubId 具体积分项目ID 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     * @param accumulatedScore 累计总分 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @param accumulatedScore 已累计总分 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				      * @return 可获得的有效分数 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				      *         如果没有任何限制返回null 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				      *         如果已超过限制返回BigDecimal.ZERO 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -245,6 +284,92 @@ public class ContributionHelper { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         return availableScore; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * 计算最多可得的分数 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * 根据累计积分和分数配置映射表,如果超过配置的限制分数则返回限制分最大分数, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * 计算每个积分大项在考虑双重限制条件下的最大可获得分数: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * 1. 子项限制:每个具体积分项目子项可能有分数上限 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * 2. 大项限制:整个积分大项可能有总分上限 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @param scoreItemValidScoreList 某个人员所有积分项目的累计积分(personId、scoreItemId、scoreItemSubId、sumScore有值) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @return 最多可得的分数列表(按大项维度聚合) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @author W.Y.C 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @date: 2025/10/27 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    public static List<ScoreItemValidScore> calculateMaxAllowedScore(List<ScoreItemValidScore> scoreItemValidScoreList) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        //获取积分限分配置 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Map<Long, BigDecimal> scoreConfMap = ContributionHelper.getScoreConf(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        List<ScoreItemValidScore> result = new ArrayList<>(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 按大类分组 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Map<Long, List<ScoreItemValidScore>> groupedByScoreItemId = scoreItemValidScoreList.stream() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                .collect(Collectors.groupingBy(ScoreItemValidScore::getScoreItemId)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        for (Map.Entry<Long, List<ScoreItemValidScore>> entry : groupedByScoreItemId.entrySet()) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Long scoreItemId = entry.getKey(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            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 actualTotalScore = BigDecimal.ZERO; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            for (BigDecimal subItemScore : subItemSumMap.values()) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                actualTotalScore = actualTotalScore.add(subItemScore); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // 计算每个子项的有效分数并求和 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            BigDecimal totalAllowedScore = BigDecimal.ZERO; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            for (Map.Entry<Long, BigDecimal> subEntry : subItemSumMap.entrySet()) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                Long subItemId = subEntry.getKey(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                BigDecimal subItemSumScore = subEntry.getValue(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                // 获取子项限制分数 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                BigDecimal scoreItemSubMaxScore = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if (subItemId != null && subItemId > 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    scoreItemSubMaxScore = scoreConfMap.get(subItemId); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                // 子项限制后的分数(优先考虑子项限制) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                BigDecimal allowedSubScore = subItemSumScore; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if (scoreItemSubMaxScore != null && scoreItemSubMaxScore.compareTo(BigDecimal.ZERO) > 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    allowedSubScore = subItemSumScore.min(scoreItemSubMaxScore); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                totalAllowedScore = totalAllowedScore.add(allowedSubScore); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // 如果大项有限制,需要检查是否超过大项限制 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (scoreItemMaxScore != null && scoreItemMaxScore.compareTo(BigDecimal.ZERO) > 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                totalAllowedScore = totalAllowedScore.min(scoreItemMaxScore); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // 创建结果对象,只包含scoreItemId和validScore 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ScoreItemValidScore resultItem = new ScoreItemValidScore(null, scoreItemId, null); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            String scoreItemNumber = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (!valueList.isEmpty() && valueList.get(0) != null) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                scoreItemNumber = valueList.get(0).getScoreItemNumber(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            resultItem.setScoreItemNumber(scoreItemNumber); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            resultItem.setValidScore(totalAllowedScore); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            resultItem.setSumScore(actualTotalScore); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            result.add(resultItem); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return result; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				      * 决定使用哪种累计分数 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				      * @param scoreConfMap 分数配置映射 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -274,25 +399,25 @@ public class ContributionHelper { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     public static Map<Long, BigDecimal> getScoreConf() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         //查询积分项目分数配置 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         QueryFieldBuilder scoreItemConfFieldBuilder = QueryFieldBuilder.create() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                .addIdNumberName(FormConstant.NCKD_ENTRYENTITY, ContributionEvaluationConstant.NCKD_SCOREITEM) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                .addIdNumberName(FormConstant.NCKD_ENTRYENTITY, ContributionEvaluationConstant.NCKD_SCOREITEMSUB) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                .addGroup(new String[]{FormConstant.NCKD_ENTRYENTITY}, ContributionEvaluationConstant.NCKD_MAXSCORE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                .addIdNumberName(FormConstant.NCKD_ENTRYENTITY, ContributionConstant.NCKD_SCOREITEM) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                .addIdNumberName(FormConstant.NCKD_ENTRYENTITY, ContributionConstant.NCKD_SCOREITEMSUB) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                .addGroup(new String[]{FormConstant.NCKD_ENTRYENTITY}, ContributionConstant.NCKD_MAXSCORE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        DynamicObjectCollection scoreItemConfQuery = QueryServiceHelper.query(ContributionEvaluationConstant.SCOREITEMCONF_ENTITYID, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        DynamicObjectCollection scoreItemConfQuery = QueryServiceHelper.query(ContributionConstant.SCOREITEMCONF_ENTITYID, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 scoreItemConfFieldBuilder.buildSelect(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 new QFilter[]{QFilterCommonHelper.getEnableFilter()}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         //scoreMap:key为积分项目子项ID(项目子项为空时key为项目大项),value为积分项目对应的最大分数 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         Map<Long, BigDecimal> scoreMap = scoreItemConfQuery.stream().collect(Collectors.toMap( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 item -> { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    long scoreItemSubId = item.getLong(String.join(".", FormConstant.NCKD_ENTRYENTITY, ContributionEvaluationConstant.NCKD_SCOREITEMSUB, 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, ContributionEvaluationConstant.NCKD_SCOREITEM, FormConstant.ID_KEY)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        return item.getLong(String.join(".", FormConstant.NCKD_ENTRYENTITY, ContributionConstant.NCKD_SCOREITEM, FormConstant.ID_KEY)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                         return scoreItemSubId; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                item -> item.getBigDecimal(String.join(".", FormConstant.NCKD_ENTRYENTITY, ContributionEvaluationConstant.NCKD_MAXSCORE)), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                item -> item.getBigDecimal(String.join(".", FormConstant.NCKD_ENTRYENTITY, ContributionConstant.NCKD_MAXSCORE)), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 //处理重复key的情况,取最大值 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 (existing, replacement) -> existing.max(replacement) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         )); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -302,6 +427,7 @@ public class ContributionHelper { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     public static class ScoreItemValidScore{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         private Long personId; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         private Long scoreItemId; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        private String scoreItemNumber; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         private Long scoreItemSubId; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         /**本次积分*/ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         private BigDecimal currentScore; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -317,9 +443,10 @@ public class ContributionHelper { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             this.scoreItemSubId = scoreItemSubId; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        public ScoreItemValidScore(Long personId, Long scoreItemId, Long scoreItemSubId, BigDecimal sumScore) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        public ScoreItemValidScore(Long personId, Long scoreItemId,String scoreItemNumber, Long scoreItemSubId, BigDecimal sumScore) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             this.personId = personId; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             this.scoreItemId = scoreItemId; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            this.scoreItemNumber = scoreItemNumber; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             this.scoreItemSubId = scoreItemSubId; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             this.sumScore = sumScore; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -348,6 +475,13 @@ public class ContributionHelper { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             this.scoreItemId = scoreItemId; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        public String getScoreItemNumber() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return scoreItemNumber; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        public void setScoreItemNumber(String scoreItemNumber) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            this.scoreItemNumber = scoreItemNumber; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         public Long getScoreItemSubId() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             return scoreItemSubId; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 |