Просмотр исходного кода

Merge remote-tracking branch 'origin/master'

jtd 2 недель назад
Родитель
Сommit
623416f849
26 измененных файлов с 775 добавлено и 251 удалено
  1. 12 2
      code/base/nckd-jxccl-base-common/src/main/java/nckd/jxccl/base/common/constant/FormConstant.java
  2. 77 0
      code/base/nckd-jxccl-base-helper/src/main/java/nckd/jxccl/base/swc/helper/SWCHelper.java
  3. 4 5
      code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/business/JobLevelCalculatorService.java
  4. 2 0
      code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/common/ContributionConstant.java
  5. 16 3
      code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/helper/ContributionHelper.java
  6. 46 0
      code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/plugin/form/JobLevelHrFormPlugin.java
  7. 45 50
      code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/plugin/form/contribution/ContribBillFormPlugin.java
  8. 91 23
      code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/plugin/form/performance/PerfRankMgmtFormPlugin.java
  9. 13 11
      code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/plugin/operate/contribution/ContribBillOpPlugin.java
  10. 2 0
      code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/plugin/operate/file/PersonPosFileDeleteOpPlugin.java
  11. 14 4
      code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/plugin/operate/performance/PerfRankMgmtSaveOpPlugin.java
  12. 9 5
      code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/plugin/operate/performance/validate/PerfRankMgmtSaveValidate.java
  13. 64 73
      code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/task/PsmsAdjustSalaryTask.java
  14. 7 7
      code/opmc/nckd-jxccl-opmc/src/main/java/nckd/jxccl/opmc/pm/plugin/operate/cycle/CycleGenerateOpPlugin.java
  15. 2 2
      code/opmc/nckd-jxccl-opmc/src/main/java/nckd/jxccl/opmc/pm/plugin/operate/cycle/PerfManagerSaveOpPlugin.java
  16. 53 48
      code/opmc/nckd-jxccl-opmc/src/main/java/nckd/jxccl/opmc/pm/plugin/operate/salary/PushAdjustOpPlugin.java
  17. 6 0
      code/swc/nckd-jxccl-swc/src/main/java/nckd/jxccl/swc/hcdm/formplugin/annualincome/SalAnnualIncomeBillEdit.java
  18. 38 10
      code/swc/nckd-jxccl-swc/src/main/java/nckd/jxccl/swc/hsas/business/outdata/OutImportTaskGuideExportService.java
  19. 1 1
      code/swc/nckd-jxccl-swc/src/main/java/nckd/jxccl/swc/hsas/business/outdata/OutImportTaskGuideImportService.java
  20. 28 5
      code/swc/nckd-jxccl-swc/src/main/java/nckd/jxccl/swc/hsas/business/utils/OutImportTaskUtils.java
  21. 9 0
      code/swc/nckd-jxccl-swc/src/main/java/nckd/jxccl/swc/hsas/common/OutImpPresetItem.java
  22. 6 2
      code/swc/nckd-jxccl-swc/src/main/java/nckd/jxccl/swc/hsas/formplugin/web/outdata/basedata/OutImpTemplateEdit.java
  23. 3 0
      code/swc/nckd-jxccl-swc/src/main/java/nckd/jxccl/swc/hsas/formplugin/web/outdata/basedata/OutItemSelectAddItemPlugin.java
  24. 173 0
      code/swc/nckd-jxccl-swc/src/main/java/nckd/jxccl/swc/hsas/formplugin/web/outdata/basedata/OutItemSelectTreePlugin.java
  25. 1 0
      code/swc/nckd-jxccl-swc/src/main/java/nckd/jxccl/swc/hsas/formplugin/web/outdata/helper/OutImpTemplateHelper.java
  26. 53 0
      code/swc/nckd-jxccl-swc/src/main/java/nckd/jxccl/swc/hsas/opplugin/web/OutTempDataOpPlugin.java

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

@@ -319,7 +319,7 @@ public class FormConstant {
     public static final String EMPLOYEE_KEY = "employee";
     /**职级序列*/
     public static final String JOBLEVELSEQ = "joblevelseq";
-    /**职级序列*/
+    /**入职日期*/
     public static final String ENTRYDATE = "entrydate";
     /**当前数据*/
     public static final String ISCURRENTDATA = "iscurrentdata";
@@ -442,11 +442,21 @@ public class FormConstant {
     public static final String AFFACTION_KEY = "affaction";
     /** 别名 */
     public static final String NCKD_ALIAS = "nckd_alias";
-    /** 别名 */
+    /** 是否参与 */
     public static final String NCKD_ISPARTICIPATE = "nckd_isparticipate";
 
 
     /** 岗位工资标准(jt002)*/
     public static final Long STANDARDITEM_ID_KEY = 2321899710350111744L;
 
+    /** 全职任职类型编码 */
+    public static final String FULLSERVICE_NUMBER = "1010_S";
+
+    /** 工作性质 */
+    public static final String NCKD_HBSS_WORKNATURE = "nckd_hbss_worknature";
+    /** 工作性质大类 */
+    public static final String NCKD_JOBTJOBTYPMAIN = "nckd_jobtjobtypmain";
+    /** 工作性质大类离岗编码 */
+    public static final String NCKD_JOBTJOBTYPMAIN_LEAVE_NUMBER = "05";
+
 }

+ 77 - 0
code/base/nckd-jxccl-base-helper/src/main/java/nckd/jxccl/base/swc/helper/SWCHelper.java

@@ -2,6 +2,7 @@ package nckd.jxccl.base.swc.helper;
 
 import kd.bos.dataentity.entity.DynamicObject;
 import kd.bos.dataentity.entity.DynamicObjectCollection;
+import kd.bos.entity.tree.TreeNode;
 import kd.bos.logging.Log;
 import kd.bos.logging.LogFactory;
 
@@ -11,6 +12,7 @@ import kd.bos.servicehelper.BusinessDataServiceHelper;
 import kd.bos.servicehelper.QueryServiceHelper;
 import kd.hr.hbp.business.servicehelper.HRBaseServiceHelper;
 import nckd.jxccl.base.common.constant.FormConstant;
+import nckd.jxccl.base.orm.helper.QFilterCommonHelper;
 
 import java.util.*;
 import java.util.stream.Collectors;
@@ -217,4 +219,79 @@ public class SWCHelper {
         return null == list || list.size() == 0;
     }
 
+
+    /**
+     * 将嵌套的Map结构转换为List集合
+     * @param dataMap 包含嵌套Map结构的数据映射,键为String类型,值为Map<String, Object>类型
+     * @return 返回包含Map<String, Object>元素的List集合,如果输入为空则返回空列表
+     */
+    public static List<Map<String, Object>> mapToList(Map<String, Map<String, Object>> dataMap) {
+        // 检查输入参数是否为空或空集合
+        if (dataMap == null || dataMap.isEmpty()) {
+            return Collections.emptyList();
+        }
+
+        // 提取所有非空的value值并收集为List
+        return dataMap.values().stream()
+                .filter(Objects::nonNull)
+                .collect(Collectors.toList());
+    }
+
+    /**
+     * 根据唯一编码集合筛选节点列表中的叶子节点
+     *
+     * @param nodeList 节点列表,用于遍历查找匹配的节点
+     * @param uniqueCodeSet 唯一编码集合,用于匹配叶子节点的ID
+     * @return 符合条件的叶子节点列表,如果输入参数为空则返回空列表
+     */
+    public static List<TreeNode> getCheckTreeNodeList(List<TreeNode> nodeList, Set<String> uniqueCodeSet) {
+        if (org.apache.commons.collections4.CollectionUtils.isEmpty(uniqueCodeSet) ||
+                org.apache.commons.collections4.CollectionUtils.isEmpty(nodeList)) {
+            return Collections.emptyList();
+        }
+
+        // 使用队列进行广度优先遍历所有节点
+        Queue<TreeNode> nodeQueue = new LinkedList<>(nodeList);
+        List<TreeNode> checkNodeList = new ArrayList<>();
+
+        while (!nodeQueue.isEmpty()) {
+            TreeNode currentNode = nodeQueue.poll();
+            List<TreeNode> children = currentNode.getChildren();
+
+            // 如果当前节点有子节点,则将子节点加入队列继续遍历
+            if (org.apache.commons.collections4.CollectionUtils.isNotEmpty(children)) {
+                nodeQueue.addAll(children);
+                // 如果当前节点是叶子节点且其ID在唯一编码集合中,则加入结果列表
+            } else if (uniqueCodeSet.contains(currentNode.getId())) {
+                checkNodeList.add(currentNode);
+            }
+        }
+
+        return checkNodeList;
+    }
+
+    /**
+     * 获取所有二级组织
+     *
+     * @return
+     */
+    public static DynamicObjectCollection getAllSecondOrg() {
+        QFilter filter = QFilterCommonHelper.getCurrentVersionFilter();
+        filter.and(QFilterCommonHelper.getEnableFilter(true));
+        filter.and(QFilterCommonHelper.getDataStatusFilter());
+        filter.and("adminorgtype.number", QCP.equals, "1020_S");
+        HRBaseServiceHelper helper = new HRBaseServiceHelper("haos_adminorghr");
+        return helper.queryOriginalCollection("id,name,number", filter.toArray());
+    }
+
+    public static DynamicObject getOrgByName (String name) {
+        QFilter filter = QFilterCommonHelper.getCurrentVersionFilter();
+        filter.and(QFilterCommonHelper.getEnableFilter(true));
+        filter.and(QFilterCommonHelper.getDataStatusFilter());
+        filter.and("name", QCP.equals,  name);
+        HRBaseServiceHelper helper = new HRBaseServiceHelper("haos_adminorghr");
+        return helper.loadOne(filter.toArray());
+    }
+
+
 }

+ 4 - 5
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/business/JobLevelCalculatorService.java

@@ -264,7 +264,7 @@ public class JobLevelCalculatorService {
             jobLevelResult.jobScoreInfo = jobScoreInfo;
             jobLevelResult.rankingResultInfo = rankingInfo;
             logger.info("序列转换处理完成 - 最终职级序号: {}, 调整类型: {}",
-                    jobLevel.getInt(FormConstant.JOBLEVELSEQ), jobLevelResult.adjustType);
+                    jobLevel != null ? jobLevel.getInt(FormConstant.JOBLEVELSEQ) : StringUtils.EMPTY, jobLevelResult != null ? jobLevelResult.adjustType : StringUtils.EMPTY);
             return jobLevelResult;
         } else if (jobSeqInfo.isCrossUnitTransfer) {
             logger.info("检测到跨单位调动,开始处理");
@@ -274,7 +274,7 @@ public class JobLevelCalculatorService {
             jobLevelResult.jobScoreInfo = jobScoreInfo;
             jobLevelResult.rankingResultInfo = rankingInfo;
             logger.info("跨单位调动处理完成 - 最终职级序号: {}, 调整类型: {}",
-                    jobLevel.getInt(FormConstant.JOBLEVELSEQ), jobLevelResult.adjustType);
+                    jobLevel != null ? jobLevel.getInt(FormConstant.JOBLEVELSEQ) : StringUtils.EMPTY, jobLevelResult != null ? jobLevelResult.adjustType : StringUtils.EMPTY);
             return jobLevelResult;
         }
 
@@ -1984,9 +1984,8 @@ public class JobLevelCalculatorService {
             logger.warn("无考核结果");
             isEligibleForJobLevel = Boolean.FALSE;
         }
-        if(score.compareTo(new BigDecimal(18)) < 0) {
-            //积分数小于18
-            logger.warn("积分数小于18: {}", score);
+        if(score == null || score.compareTo(BigDecimal.ZERO) <= 0) {
+            logger.warn("积分为空或小于0");
             isEligibleForJobLevel = Boolean.FALSE;
         }
 

+ 2 - 0
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/common/ContributionConstant.java

@@ -49,5 +49,7 @@ public class ContributionConstant extends FormConstant {
     public static final String SCOREITEMCONF_ENTITYID = "nckd_scoreitemconf";
     /** 最高分数 */
     public static final String NCKD_MAXSCORE = "nckd_maxscore";
+    /** 个人最高分数 */
+    public static final String NCKD_PERSONMAXSCORE = "nckd_personmaxscore";
     /*-------------------------------------- 积分项目分数配置 begin --------------------------------------*/
 }

+ 16 - 3
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/helper/ContributionHelper.java

@@ -605,6 +605,13 @@ public class ContributionHelper {
         return getScoreConf(null);
     }
 
+    public static Map<String, BigDecimal> getScoreConfByPersonMaxScore(QFilter otherFilter) {
+        return getScoreConf(otherFilter,2);
+    }
+    public static Map<String, BigDecimal> getScoreConf(QFilter otherFilter) {
+        return getScoreConf(otherFilter,1);
+    }
+
     /**
      * 获取积分配置
      * @return: java.util.Map<java.lang.String, java.math.BigDecimal>;key:根据配置的完整程度生成不同格式的字符串,
@@ -615,13 +622,13 @@ public class ContributionHelper {
      * @author W.Y.C
      * @date: 2025/10/26 13:38
      */
-    public static Map<String, BigDecimal> getScoreConf(QFilter otherFilter) {
+    public static Map<String, BigDecimal> getScoreConf(QFilter otherFilter,Integer type) {
         //查询积分项目分数配置
         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);
+                .addGroup(new String[]{FormConstant.NCKD_ENTRYENTITY}, ContributionConstant.NCKD_MAXSCORE,ContributionConstant.NCKD_PERSONMAXSCORE);
         QFilter filter = QFilterCommonHelper.getEnableFilter()
                 .and(QFilterCommonHelper.getValidDateFilter(FormConstant.NCKD_STARTDATE,FormConstant.NCKD_ENDDATE));
         if(otherFilter != null){
@@ -652,7 +659,13 @@ public class ContributionHelper {
                         return scoreItemId+"";
                     }
                 },
-                item -> item.getBigDecimal(String.join(".", FormConstant.NCKD_ENTRYENTITY, ContributionConstant.NCKD_MAXSCORE)),
+                item -> {
+                    if(type == 1){
+                        return item.getBigDecimal(String.join(".", FormConstant.NCKD_ENTRYENTITY, ContributionConstant.NCKD_MAXSCORE));
+                    }else{
+                        return item.getBigDecimal(String.join(".", FormConstant.NCKD_ENTRYENTITY, ContributionConstant.NCKD_PERSONMAXSCORE));
+                    }
+                },
                 //处理重复key的情况,取最大值
                 (existing, replacement) -> existing.max(replacement)
         ));

+ 46 - 0
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/plugin/form/JobLevelHrFormPlugin.java

@@ -0,0 +1,46 @@
+package nckd.jxccl.hr.psms.plugin.form;
+
+import kd.bos.dataentity.entity.DynamicObject;
+import kd.bos.entity.datamodel.events.ChangeData;
+import kd.bos.entity.datamodel.events.PropertyChangedArgs;
+import kd.bos.form.plugin.AbstractFormPlugin;
+import kd.sdk.plugin.Plugin;
+import nckd.jxccl.base.common.constant.FormConstant;
+import nckd.jxccl.base.common.utils.ConvertUtil;
+import nckd.jxccl.hr.hstu.common.HonorStudentConstant;
+import nckd.jxccl.hr.psms.common.PositionStructureConstant;
+
+import java.util.Objects;
+
+/**
+* 职级
+* 实体标识:hbjm_joblevelhr
+* @author W.Y.C
+* @date 2025/12/22 18:47
+* @version 1.0
+*/
+public class JobLevelHrFormPlugin extends AbstractFormPlugin implements Plugin {
+
+    @Override
+    public void propertyChanged(PropertyChangedArgs e) {
+        String fieldKey = e.getProperty().getName();
+        ChangeData[] changeSet = e.getChangeSet();
+
+        if ("nckd_joblevelscm".equalsIgnoreCase(fieldKey)) {
+            if (changeSet != null && changeSet.length > 0) {
+                Object oldValue = changeSet[0].getOldValue();
+                Object newValue = changeSet[0].getNewValue();
+                if (!Objects.equals(oldValue, newValue)) {
+                    if(newValue != null) {
+                        Object[] mulSelectOrgIds = new Object[1];
+                        mulSelectOrgIds[0] = ConvertUtil.toDynamicObjectOrNull(newValue).getLong(FormConstant.ID_KEY);
+                        this.getModel().setValue("joblevelscm", mulSelectOrgIds);
+                    }else{
+                        this.getModel().setValue("joblevelscm", null);
+                    }
+
+                }
+            }
+        }
+    }
+}

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

@@ -156,30 +156,27 @@ public class ContribBillFormPlugin extends AbstractFormPlugin implements Plugin,
         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));
-        if (date != null && scoreItem != null && scoreItemSub != null) {
-            String scoreItemNumber = scoreItem.getString(FormConstant.NUMBER_KEY);
-            if (ScoreItemEnum.RESEARCH_SCORE.getCode().equalsIgnoreCase(scoreItemNumber)) {
-                if (person != null  && oriScore != null && oriScore.compareTo(BigDecimal.ZERO) > 0) {
-                    //科研与创新需要需要匹配积分规则
-                    QFilter filter = new QFilter(String.join(".", FormConstant.NCKD_ENTRYENTITY, ContributionConstant.NCKD_SCOREITEM), QCP.equals, scoreItem.getLong(FormConstant.ID_KEY))
-                            .and(new QFilter(String.join(".", FormConstant.NCKD_ENTRYENTITY, ContributionConstant.NCKD_SCOREITEMSUB), QCP.equals, scoreItemSub.getLong(FormConstant.ID_KEY)))
-                            .and(new QFilter(String.join(".", FormConstant.NCKD_ENTRYENTITY, ContributionConstant.NCKD_SCOREITEMRANK), QCP.equals, scoreItemRank.getLong(FormConstant.ID_KEY)));
-                    Map<String, BigDecimal> scoreConf = ContributionHelper.getScoreConf(filter);
-                    String key = scoreItem.getLong(FormConstant.ID_KEY) + "-" + scoreItemSub.getLong(FormConstant.ID_KEY) + "-" + scoreItemRank.getLong(FormConstant.ID_KEY);
-                    BigDecimal validScore = oriScore;
-                    if (!scoreConf.isEmpty() && scoreConf.containsKey(key)) {
-                        BigDecimal maxScore = scoreConf.get(key);
-                        if (maxScore != null) {
-                            validScore = oriScore.compareTo(maxScore) > 0 ? maxScore : oriScore;
-                        }
+        if (date != null && scoreItem != null && scoreItemSub != null && scoreItemRank != null) {
+            if (person != null  && oriScore != null && oriScore.compareTo(BigDecimal.ZERO) > 0) {
+                //科研与创新需要需要匹配积分规则
+                QFilter filter = new QFilter(String.join(".", FormConstant.NCKD_ENTRYENTITY, ContributionConstant.NCKD_SCOREITEM), QCP.equals, scoreItem.getLong(FormConstant.ID_KEY))
+                        .and(new QFilter(String.join(".", FormConstant.NCKD_ENTRYENTITY, ContributionConstant.NCKD_SCOREITEMSUB), QCP.equals, scoreItemSub.getLong(FormConstant.ID_KEY)))
+                        .and(new QFilter(String.join(".", FormConstant.NCKD_ENTRYENTITY, ContributionConstant.NCKD_SCOREITEMRANK), QCP.equals, scoreItemRank.getLong(FormConstant.ID_KEY)));
+                Map<String, BigDecimal> scoreConf = ContributionHelper.getScoreConfByPersonMaxScore(filter);
+                String key = scoreItem.getLong(FormConstant.ID_KEY) + "-" + scoreItemSub.getLong(FormConstant.ID_KEY) + "-" + scoreItemRank.getLong(FormConstant.ID_KEY);
+                BigDecimal validScore = oriScore;
+                if (!scoreConf.isEmpty() && scoreConf.containsKey(key) &&  scoreConf.get(key) != null && scoreConf.get(key).compareTo(BigDecimal.ZERO) > 0) {
+                    BigDecimal maxScore = scoreConf.get(key);
+                    if (maxScore != null) {
+                        validScore = oriScore.compareTo(maxScore) > 0 ? maxScore : oriScore;
                     }
-                    this.getModel().setValue(ContributionConstant.NCKD_SCORE, validScore, rowIndex);
-                    this.getView().updateView(ContributionConstant.NCKD_SCORE, rowIndex);
                 }
-            } else {
-                this.getModel().setValue(ContributionConstant.NCKD_SCORE, oriScore, rowIndex);
+                this.getModel().setValue(ContributionConstant.NCKD_SCORE, validScore, rowIndex);
                 this.getView().updateView(ContributionConstant.NCKD_SCORE, rowIndex);
             }
+        }else{
+            this.getModel().setValue(ContributionConstant.NCKD_SCORE, oriScore, rowIndex);
+            this.getView().updateView(ContributionConstant.NCKD_SCORE, rowIndex);
         }
     }
 
@@ -231,40 +228,38 @@ public class ContribBillFormPlugin extends AbstractFormPlugin implements Plugin,
         DynamicObject scoreItemRank = ConvertUtil.toDynamicObjectOrNull(this.getModel().getValue(ContributionConstant.NCKD_SCOREITEMRANK));
 
 
-        if (date != null && scoreItem != null && scoreItemSub != null) {
+        if (date != null && scoreItem != null && scoreItemSub != null && scoreItemRank != null) {
 
             DynamicObjectCollection entryEntity = this.getModel().getEntryEntity(FormConstant.NCKD_ENTRYENTITY);
-            String scoreItemNumber = scoreItem.getString(FormConstant.NUMBER_KEY);
-            if(ScoreItemEnum.RESEARCH_SCORE.getCode().equalsIgnoreCase(scoreItemNumber)){
-                if(scoreItemRank != null) {
-                    //科研与创新需要需要匹配积分规则
-                    QFilter filter = new QFilter(String.join(".", FormConstant.NCKD_ENTRYENTITY, ContributionConstant.NCKD_SCOREITEM), QCP.equals, scoreItem.getLong(FormConstant.ID_KEY))
-                            .and(new QFilter(String.join(".", FormConstant.NCKD_ENTRYENTITY, ContributionConstant.NCKD_SCOREITEMSUB), QCP.equals, scoreItemSub.getLong(FormConstant.ID_KEY)))
-                            .and(new QFilter(String.join(".", FormConstant.NCKD_ENTRYENTITY, ContributionConstant.NCKD_SCOREITEMRANK), QCP.equals, scoreItemRank.getLong(FormConstant.ID_KEY)));
-                    Map<String, BigDecimal> scoreConf = ContributionHelper.getScoreConf(filter);
-                    String key = scoreItem.getLong(FormConstant.ID_KEY)+"-"+scoreItemSub.getLong(FormConstant.ID_KEY)+"-"+scoreItemRank.getLong(FormConstant.ID_KEY);
-                    for (int i = 0; i < entryEntity.size(); i++) {
-                        DynamicObject entry = entryEntity.get(i);
-                        BigDecimal oriScore = entry.getBigDecimal(ContributionConstant.NCKD_ORISCORE);
-                        BigDecimal validScore = oriScore;
-                        if(!scoreConf.isEmpty() && scoreConf.containsKey(key)){
-                            BigDecimal maxScore = scoreConf.get(key);
-                            if (maxScore != null && oriScore != null) {
-                                validScore = oriScore.compareTo(maxScore) > 0 ? maxScore : oriScore;
-                            } else {
-                                // 根据业务需求处理 null 值情况
-                                validScore = oriScore != null ? oriScore : BigDecimal.ZERO;
-                            }
-                        }
-                        this.getModel().setValue(ContributionConstant.NCKD_SCORE, validScore, i);
+
+            //科研与创新需要需要匹配积分规则
+            QFilter filter = new QFilter(String.join(".", FormConstant.NCKD_ENTRYENTITY, ContributionConstant.NCKD_SCOREITEM), QCP.equals, scoreItem.getLong(FormConstant.ID_KEY))
+                    .and(new QFilter(String.join(".", FormConstant.NCKD_ENTRYENTITY, ContributionConstant.NCKD_SCOREITEMSUB), QCP.equals, scoreItemSub.getLong(FormConstant.ID_KEY)))
+                    .and(new QFilter(String.join(".", FormConstant.NCKD_ENTRYENTITY, ContributionConstant.NCKD_SCOREITEMRANK), QCP.equals, scoreItemRank.getLong(FormConstant.ID_KEY)));
+            Map<String, BigDecimal> scoreConf = ContributionHelper.getScoreConfByPersonMaxScore(filter);
+            String key = scoreItem.getLong(FormConstant.ID_KEY)+"-"+scoreItemSub.getLong(FormConstant.ID_KEY)+"-"+scoreItemRank.getLong(FormConstant.ID_KEY);
+            for (int i = 0; i < entryEntity.size(); i++) {
+                DynamicObject entry = entryEntity.get(i);
+                BigDecimal oriScore = entry.getBigDecimal(ContributionConstant.NCKD_ORISCORE);
+                BigDecimal validScore = oriScore;
+                if(!scoreConf.isEmpty() && scoreConf.containsKey(key) &&  scoreConf.get(key) != null && scoreConf.get(key).compareTo(BigDecimal.ZERO) > 0){
+                    BigDecimal maxScore = scoreConf.get(key);
+                    if (maxScore != null && oriScore != null) {
+                        validScore = oriScore.compareTo(maxScore) > 0 ? maxScore : oriScore;
+                    } else {
+                        // 根据业务需求处理 null 值情况
+                        validScore = oriScore != null ? oriScore : BigDecimal.ZERO;
                     }
                 }
-            }else{
-                for (int i = 0; i < entryEntity.size(); i++) {
-                    DynamicObject entry = entryEntity.get(i);
-                    BigDecimal oriScore = entry.getBigDecimal(ContributionConstant.NCKD_ORISCORE);
-                    this.getModel().setValue(ContributionConstant.NCKD_SCORE, oriScore, i);
-                }
+                this.getModel().setValue(ContributionConstant.NCKD_SCORE, validScore, i);
+            }
+
+        }else{
+            DynamicObjectCollection entryEntity = this.getModel().getEntryEntity(FormConstant.NCKD_ENTRYENTITY);
+            for (int i = 0; i < entryEntity.size(); i++) {
+                DynamicObject entry = entryEntity.get(i);
+                BigDecimal oriScore = entry.getBigDecimal(ContributionConstant.NCKD_ORISCORE);
+                this.getModel().setValue(ContributionConstant.NCKD_SCORE, oriScore, i);
             }
         }
     }

+ 91 - 23
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/plugin/form/performance/PerfRankMgmtFormPlugin.java

@@ -10,9 +10,6 @@ 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.dataentity.serialization.DataEntitySerializer;
-import kd.bos.dataentity.serialization.DataEntitySerializerOption;
-import kd.bos.dtx.util.DynamicObjectSerializeUtil;
 import kd.bos.entity.EntityMetadataCache;
 import kd.bos.entity.MainEntityType;
 import kd.bos.entity.QueryEntityType;
@@ -23,12 +20,12 @@ import kd.bos.entity.datamodel.events.AfterAddRowEventArgs;
 import kd.bos.entity.datamodel.events.BeforeDeleteRowEventArgs;
 import kd.bos.entity.datamodel.events.BeforeImportEntryEventArgs;
 import kd.bos.entity.datamodel.events.ChangeData;
+import kd.bos.entity.datamodel.events.GetEntityTypeEventArgs;
 import kd.bos.entity.datamodel.events.PropertyChangedArgs;
 import kd.bos.entity.filter.CompareTypeEnum;
 import kd.bos.entity.filter.FilterValue;
 import kd.bos.entity.filter.SimpleFilterRow;
 import kd.bos.entity.operate.result.OperationResult;
-import kd.bos.entity.property.entryfilter.EntryQueryParam;
 import kd.bos.form.ConfirmCallBackListener;
 import kd.bos.form.ConfirmTypes;
 import kd.bos.form.IClientViewProxy;
@@ -36,7 +33,6 @@ import kd.bos.form.IPageCache;
 import kd.bos.form.MessageBoxOptions;
 import kd.bos.form.MessageBoxResult;
 import kd.bos.form.container.Wizard;
-import kd.bos.form.control.Control;
 import kd.bos.form.control.EntryGrid;
 import kd.bos.form.control.Steps;
 import kd.bos.form.control.events.StepEvent;
@@ -52,22 +48,20 @@ import kd.bos.orm.query.QCP;
 import kd.bos.orm.query.QFilter;
 import kd.bos.servicehelper.BusinessDataServiceHelper;
 import kd.bos.servicehelper.QueryServiceHelper;
-import kd.hdtc.hrcc.common.enums.FileImportSubTaskDealStatusEnum;
 import kd.hr.hbp.business.servicehelper.HRQueryEntityHelper;
 import nckd.jxccl.base.common.constant.FormConstant;
-import nckd.jxccl.base.common.constant.QueryConstant;
 import nckd.jxccl.base.common.enums.AppraisalResultEnum;
 import nckd.jxccl.base.common.enums.psms.JobSeqEnum;
 import nckd.jxccl.base.common.utils.ConvertUtil;
 import nckd.jxccl.base.common.utils.DateUtil;
 import nckd.jxccl.base.common.utils.QueryFieldBuilder;
 import nckd.jxccl.base.common.utils.StrFormatter;
-import nckd.jxccl.base.hrpi.helper.EmpPosOrgRelHelper;
 import nckd.jxccl.base.orm.helper.QFilterCommonHelper;
 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.jetbrains.annotations.NotNull;
 
 import java.math.BigDecimal;
 import java.math.RoundingMode;
@@ -288,6 +282,13 @@ public class PerfRankMgmtFormPlugin extends AbstractFormPlugin implements Wizard
                 args.setCancel(true);
                 return;
             }
+            int theYear = ConvertUtil.toInt(this.getModel().getValue(PerfRankMgmtConstant.NCKD_THEYEAR));
+            if(theYear <= 0){
+                this.getView().showTipNotification("请先填写“年份”");
+                args.setCancel(true);
+                return;
+            }
+
             RefObject<String> afterConfirm = new RefObject<>();
             if (!operate.getOption().tryGetVariableValue("afterConfirm", afterConfirm)) {
                 //判断是否已获取过名单,如获取过再获取提示用户数据会丢失
@@ -453,7 +454,7 @@ public class PerfRankMgmtFormPlugin extends AbstractFormPlugin implements Wizard
 
 
     @Override
-    public void afterDoOperation(AfterDoOperationEventArgs afterDoOperationEventArgs) {
+    public void afterDoOperation(@NotNull AfterDoOperationEventArgs afterDoOperationEventArgs) {
         String itemKey = afterDoOperationEventArgs.getOperateKey();
         if(PerfRankMgmtConstant.GETRANKLIST_OP.equalsIgnoreCase(itemKey)){
             /*IBillView billView = (IBillView)this.getView();
@@ -471,26 +472,36 @@ public class PerfRankMgmtFormPlugin extends AbstractFormPlugin implements Wizard
             }else{*/
                 IDataModel model = this.getModel();
                 DynamicObject adminOrg = ConvertUtil.toDynamicObjectOrNull(model.getValue(FormConstant.NCKD_ADMINORG));
+                int theYear = ConvertUtil.toInt(model.getValue(PerfRankMgmtConstant.NCKD_THEYEAR));
                 if(adminOrg != null) {
+                    Date targetDate = DateUtil.toDate(LocalDateTime.of(theYear, 12, 31, 23, 59, 59));
                     String structLongNumber = adminOrg.getString(FormConstant.STRUCTLONGNUMBER);
                     //查询所选组织下的人员
-                    QFilter qFilter = new QFilter(String.join(".", FormConstant.HRPI_EMPPOSORGREL, FormConstant.ADMINORG, FormConstant.STRUCTLONGNUMBER), QCP.like, structLongNumber + "%");
+                    //任职状态为在岗,且任职经历的任职类型为全职任职的人员((不含工作性质大类为离岗))
+                    QFilter qFilter = new QFilter(String.join(".",FormConstant.ADMINORG, FormConstant.STRUCTLONGNUMBER), QCP.like, structLongNumber + "%")
+                            .and(FormConstant.STARTDATE, QCP.less_equals, targetDate)
+                            .and(FormConstant.ENDDATE, QCP.large_equals, targetDate);
+
                     //在职人员
                     qFilter.and(String.join(".", FormConstant.HRPI_EMPENTREL, FormConstant.LABOR_REL_STATUS, FormConstant.IS_HIRED), QCP.equals, EnableEnum.YES.getCode());
                     QueryFieldBuilder queryFieldBuilder = QueryFieldBuilder.create()
-                            .addGroup(new String[]{FormConstant.HRPI_EMPPOSORGREL}, FormConstant.ID_KEY)
+                            .add(FormConstant.ID_KEY)
+                            .add(FormConstant.STARTDATE)
                             //用工关系状态.编码(1005_S	在职-试用中、1010_S	在职、1020_S	离职、1030_S	已退休),istrial:是否试用,ishired:是否在职
                             .addGroup(new String[]{FormConstant.HRPI_EMPENTREL, FormConstant.LABOR_REL_STATUS}, FormConstant.NUMBER_KEY, FormConstant.NAME_KEY, FormConstant.IS_TRIAL, FormConstant.IS_HIRED)
                             //任职状态分类(1010_S:在岗,1030_S:不在岗)
-                            .addGroup(new String[]{FormConstant.HRPI_EMPPOSORGREL, FormConstant.POS_STATUS, FormConstant.POST_STATE_CLS}, FormConstant.NUMBER_KEY)
+                            .addIdNumberName(FormConstant.POS_STATUS, FormConstant.POST_STATE_CLS)
                             //入职日期
                             .addGroup(new String[]{FormConstant.HRPI_EMPENTREL}, FormConstant.ENTRYDATE)
                             //职务级别
                             .addGroup(new String[]{FormConstant.NCKD_HRPI_PARTYPOSH, FormConstant.NCKD_POSGRADE}, FormConstant.NAME_KEY, FormConstant.NUMBER_KEY, FormConstant.NCKD_SORTNUM)
-                            .addGroup(new String[]{FormConstant.EMPLOYEE_KEY}, FormConstant.ID_KEY, FormConstant.NAME_KEY, FormConstant.EMP_NUMBER_KEY);
+                            .addGroup(new String[]{FormConstant.EMPLOYEE_KEY}, FormConstant.ID_KEY, FormConstant.NAME_KEY, FormConstant.EMP_NUMBER_KEY)
+                            //工作性质大类
+                            .addIdNumberName(FormConstant.NCKD_HBSS_WORKNATURE,FormConstant.NCKD_JOBTJOBTYPMAIN)
+                            .orderDesc(FormConstant.STARTDATE);
 
                     // -------------------------------- 1、查询组织下的在职人员 --------------------------------
-                    QueryEntityType queryEntityType = (QueryEntityType) EntityMetadataCache.getDataEntityType(QueryConstant.PERSON_QUERY);
+                    QueryEntityType queryEntityType = (QueryEntityType) EntityMetadataCache.getDataEntityType("personfilequery");
                     DynamicObjectCollection personList = HRQueryEntityHelper.getInstance().getQueryDyoColl(queryEntityType, queryFieldBuilder.buildSelect(), new QFilter[]{qFilter}, queryFieldBuilder.buildOrder());
                     //添加分录
                     DynamicObjectCollection entryEntityCols = this.getModel().getDataEntity(true).getDynamicObjectCollection(PerfRankMgmtConstant.NCKD_PERFRANKMGMTENTRY);
@@ -503,6 +514,22 @@ public class PerfRankMgmtFormPlugin extends AbstractFormPlugin implements Wizard
                     List<Long> personIds = personList.stream()
                             .map(person -> person.getLong(String.join(".", FormConstant.EMPLOYEE_KEY, FormConstant.ID_KEY)))
                             .collect(Collectors.toList());
+                    //按员工ID分组,并只取开始日期最新的任职记录
+                    Map<Long, DynamicObject> groupedByEmployee = personList.stream()
+                            .collect(Collectors.groupingBy(
+                                    person -> person.getLong(String.join(".", FormConstant.EMPLOYEE_KEY, FormConstant.ID_KEY)),
+                                    Collectors.collectingAndThen(
+                                            Collectors.maxBy((p1, p2) -> {
+                                                Date date1 = p1.getDate(FormConstant.STARTDATE);
+                                                Date date2 = p2.getDate(FormConstant.STARTDATE);
+                                                if (date1 == null && date2 == null) return 0;
+                                                if (date1 == null) return -1;
+                                                if (date2 == null) return 1;
+                                                return date2.compareTo(date1); // 降序,取最新的
+                                            }),
+                                            optional -> optional.orElse(null)
+                                    )
+                            ));
                     if (!personIds.isEmpty()) {
                         Date now = new Date();
                         // -------------------------------- 3、获取人员是否享受职位津贴 --------------------------------
@@ -511,22 +538,35 @@ public class PerfRankMgmtFormPlugin extends AbstractFormPlugin implements Wizard
                         // -------------------------------- 4、加载数据到分录 --------------------------------
                         //预加载任职经历
                         List<Long> ids = personList.stream()
-                                .map(person -> person.getLong(String.join(".", FormConstant.HRPI_EMPPOSORGREL, FormConstant.ID_KEY)))
+                                .map(person -> person.getLong(FormConstant.ID_KEY))
                                 .collect(Collectors.toList());
-                        Map<Long, DynamicObject> empPosOrgRelByEmployeesMap = EmpPosOrgRelHelper.queryEmpPosOrgRelByEmployeesMap(personIds);
+                        MainEntityType empOrgRelEntityType = EntityMetadataCache.getDataEntityType(FormConstant.HRPI_EMPPOSORGREL);
+                        DynamicObject[] empOrgRelArray = BusinessDataServiceHelper.load(ids.toArray(), empOrgRelEntityType);
+                        Map<Long, DynamicObject> empOrgRelMap = Arrays.stream(empOrgRelArray)
+                                .collect(Collectors.toMap(
+                                        obj -> obj.getLong(FormConstant.ID_KEY),
+                                        obj -> obj,
+                                        (existing, replacement) -> existing
+                                ));
                         Set<Long> addedPersonIds = new HashSet<>();
-                        for (DynamicObject person : personList) {
+                        for (Map.Entry<Long, DynamicObject> personEntry : groupedByEmployee.entrySet()) {
+                            DynamicObject person = personEntry.getValue();
+                            long id = person.getLong(FormConstant.ID_KEY);
                             long personId = person.getLong(String.join(".", FormConstant.EMPLOYEE_KEY, FormConstant.ID_KEY));
                             // 检查人员是否已经添加过,如果已存在则跳过
                             if (addedPersonIds.contains(personId)) {
                                 continue;
                             }
+                            DynamicObject empPosOrgRel = empOrgRelMap.get(id);
+                            if(empPosOrgRel == null){
+                                continue;
+                            }
                             DynamicObject entryCol = entryEntityCols.addNew();
                             addedPersonIds.add(personId); // 记录已添加的人员ID
                             String personName = person.getString(String.join(".", FormConstant.EMPLOYEE_KEY, FormConstant.NAME_KEY));
                             String personNumber = person.getString(String.join(".", FormConstant.EMPLOYEE_KEY, FormConstant.EMP_NUMBER_KEY));
 
-                            DynamicObject empPosOrgRel = empPosOrgRelByEmployeesMap.get(personId);
+
                             entryCol.set(FormConstant.NCKD_DEP, empPosOrgRel.get(FormConstant.ADMINORG));
                             entryCol.set(PositionStructureConstant.NCKD_POSITIONHR, empPosOrgRel.get(FormConstant.POSITION_KEY));
 
@@ -559,11 +599,25 @@ public class PerfRankMgmtFormPlugin extends AbstractFormPlugin implements Wizard
                             //判断是否有职位津贴
                             boolean hasAllowance = entitledToAllowance.get(personId);
                             entryCol.set(PerfRankMgmtConstant.NCKD_POSTALLOWANCE, hasAllowance);
-
                         }
-//                        this.getModel().updateEntryCache(entryEntityCols);
-                        this.getView().updateView(PerfRankMgmtConstant.NCKD_PERFRANKMGMTENTRY);
+
+                        /*this.getModel().updateEntryCache(entryEntityCols);
+                        this.getView().updateView(PerfRankMgmtConstant.NCKD_PERFRANKMGMTENTRY);*/
+
+
+                        /*for (int i = 0; i < entryEntityCols.size(); i++) {
+                            Boolean isRanking = ConvertUtil.toBoolean(this.getModel().getValue(PerfRankMgmtConstant.NCKD_ISRANKING, i));
+                            if(isRanking){
+                                this.getModel().setValue(PerfRankMgmtConstant.NCKD_ISRANKING, Boolean.FALSE,i);
+                            }else{
+                                this.getModel().setValue(PerfRankMgmtConstant.NCKD_ISRANKING, Boolean.TRUE,i);
+                            }
+                            this.getModel().setValue(PerfRankMgmtConstant.NCKD_ISRANKING, isRanking,i);
+                            this.getView().updateView(PerfRankMgmtConstant.NCKD_ISRANKING,i);
+
+                        }*/
                         this.getView().showSuccessNotification("名单获取完成");
+                        this.getView().invokeOperation(FormConstant.REFRESH_OP);
                     } else {
                         this.getView().showTipNotification("未获取到人员");
                     }
@@ -582,6 +636,8 @@ public class PerfRankMgmtFormPlugin extends AbstractFormPlugin implements Wizard
                 //控制显示隐藏
                 importResultStep();
             }
+        }else if(FormConstant.DELETEENTRY_OP.equalsIgnoreCase(itemKey)){
+
         }
         if(Arrays.asList(FormConstant.DELETEENTRY_OP, PerfRankMgmtConstant.GETRANKLIST_OP).contains(itemKey)){
             sortEntry();
@@ -590,6 +646,18 @@ public class PerfRankMgmtFormPlugin extends AbstractFormPlugin implements Wizard
         // this.getView().setStatus(OperationStatus.EDIT);
     }
 
+    @Override
+    public void getEntityType(GetEntityTypeEventArgs e) {
+        super.getEntityType(e);
+
+        MainEntityType originalEntityType = e.getOriginalEntityType();
+        try {
+            e.setNewEntityType((MainEntityType)originalEntityType.clone());
+        } catch (CloneNotSupportedException ex) {
+            throw new RuntimeException(ex);
+        }
+    }
+
     private void importResultStep() {
         this.getModel().setValue(PerfRankMgmtConstant.NCKD_STEP,1);
         this.getView().setVisible(false, FormConstant.NUMBER_KEY, PerfRankMgmtConstant.NCKD_GETRANKLIST,"nckd_advconbaritemap2","nckd_advconbaritemap3");
@@ -801,8 +869,8 @@ public class PerfRankMgmtFormPlugin extends AbstractFormPlugin implements Wizard
                 Boolean isRanking2 = o2.getBoolean(PerfRankMgmtConstant.NCKD_ISRANKING);
                 return Boolean.compare(isRanking2, isRanking1);
             });
-/*            this.getModel().updateEntryCache(entryEntityCols);
-            this.getView().updateView(PerfRankMgmtConstant.NCKD_PERFRANKMGMTENTRY);*/
+            this.getModel().updateEntryCache(entryEntityCols);
+            this.getView().updateView(PerfRankMgmtConstant.NCKD_PERFRANKMGMTENTRY);
         }
     }
 

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

@@ -68,21 +68,23 @@ public class ContribBillOpPlugin extends AbstractOperationServicePlugIn implemen
                             String scoreItemNumber = scoreItem.getString(FormConstant.NUMBER_KEY);
                             if(ScoreItemEnum.RESEARCH_SCORE.getCode().equalsIgnoreCase(scoreItemNumber)){
                                 String key = scoreItem.getLong(FormConstant.ID_KEY)+"-"+scoreItemSub.getLong(FormConstant.ID_KEY)+"-"+scoreItemRank.getLong(FormConstant.ID_KEY);
-                                if(!scoreConf.isEmpty() && scoreConf.containsKey(key)){
+                                if(!scoreConf.isEmpty() && scoreConf.containsKey(key)) {
                                     BigDecimal maxScore = scoreConf.get(key);
-                                    for (DynamicObject entry : entryEntity) {
-                                        DynamicObject person = entry.getDynamicObject(ContributionConstant.NCKD_PERSON);
-                                        long personId = person.getLong(FormConstant.ID_KEY);
-                                        BigDecimal oriScore = entry.getBigDecimal(ContributionConstant.NCKD_ORISCORE);
-                                        BigDecimal score = entry.getBigDecimal(ContributionConstant.NCKD_SCORE);
-                                        if(oriScore.compareTo(maxScore) > 0) {
-                                            this.addFatalErrorMessage(dataEntity, StrFormatter.format("参与人【{}】的原始分数【{}】超出限制积分【{}】。请重新填写“原始积分”,系统将会自动重算“录入积分”;",
-                                                    person.getString(FormConstant.NAME_KEY),
-                                                    oriScore.setScale(2, RoundingMode.HALF_UP),
+                                    if (maxScore != null && maxScore.compareTo(BigDecimal.ZERO) > 0){
+                                        BigDecimal sumScore = BigDecimal.ZERO;
+                                        for (DynamicObject entry : entryEntity) {
+                                            DynamicObject person = entry.getDynamicObject(ContributionConstant.NCKD_PERSON);
+                                            long personId = person.getLong(FormConstant.ID_KEY);
+                                            BigDecimal oriScore = entry.getBigDecimal(ContributionConstant.NCKD_ORISCORE);
+                                            BigDecimal score = entry.getBigDecimal(ContributionConstant.NCKD_SCORE);
+                                            sumScore = sumScore.add(oriScore);
+                                        }
+                                        if(sumScore.compareTo(maxScore) > 0) {
+                                            this.addFatalErrorMessage(dataEntity, StrFormatter.format("当前单据总积分【{}】超出限制积分【{}】。请重新填写;",
+                                                    sumScore.setScale(2, RoundingMode.HALF_UP),
                                                     maxScore.setScale(2, RoundingMode.HALF_UP)));
                                         }
                                     }
-
                                 }
                             }
 

+ 2 - 0
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/plugin/operate/file/PersonPosFileDeleteOpPlugin.java

@@ -73,6 +73,8 @@ public class PersonPosFileDeleteOpPlugin extends AbstractOperationServicePlugIn
                         idMaps.put(id,rowDataEntity.getDataEntityIndex());
                     }else if (TypeStateEnum.POSITION_TRANSFER.getCode().equalsIgnoreCase(typeState)) {
                         idMaps.put(id,rowDataEntity.getDataEntityIndex());
+                    }else if(typeStateEnum == TypeStateEnum.MANAGEMENT_SEQUENCE_EMPLOYMENT){
+
                     }
                     else {
                         //其他类型不能置回未生效

+ 14 - 4
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/plugin/operate/performance/PerfRankMgmtSaveOpPlugin.java

@@ -4,18 +4,17 @@ import kd.bos.common.enums.EnableEnum;
 import kd.bos.dataentity.OperateOption;
 import kd.bos.dataentity.entity.DynamicObject;
 import kd.bos.dataentity.entity.DynamicObjectCollection;
+import kd.bos.dataentity.utils.ObjectUtils;
 import kd.bos.entity.EntityMetadataCache;
 import kd.bos.entity.MainEntityType;
 import kd.bos.entity.operate.OperateOptionConst;
 import kd.bos.entity.operate.result.IOperateInfo;
-import kd.bos.entity.operate.result.OperateErrorInfo;
 import kd.bos.entity.operate.result.OperationResult;
 import kd.bos.entity.plugin.AbstractOperationServicePlugIn;
 import kd.bos.entity.plugin.AddValidatorsEventArgs;
 import kd.bos.entity.plugin.PreparePropertysEventArgs;
 import kd.bos.entity.plugin.args.BeginOperationTransactionArgs;
 import kd.bos.entity.plugin.args.EndOperationTransactionArgs;
-import kd.bos.entity.validate.ErrorLevel;
 import kd.bos.orm.query.QCP;
 import kd.bos.orm.query.QFilter;
 import kd.bos.servicehelper.BusinessDataServiceHelper;
@@ -38,10 +37,20 @@ import org.apache.commons.lang3.StringUtils;
 
 import java.time.LocalDate;
 import java.time.LocalDateTime;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.Set;
+import java.util.StringJoiner;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.stream.Collectors;
-import kd.bos.dataentity.utils.ObjectUtils;
 
 /**
 * 年度绩效排名管理-保存插件
@@ -100,6 +109,7 @@ public class PerfRankMgmtSaveOpPlugin extends AbstractOperationServicePlugIn imp
             }
         }
 
+        String deleteRow = this.getOption().getVariableValue(FormConstant.DELETEENTRY_OP, StringUtils.EMPTY);
         Boolean removedEntries = ConvertUtil.toBoolean(this.getOption().getVariableValue("removedEntries",StringUtils.EMPTY),Boolean.FALSE);
         Map<Long, List<DynamicObject>> nonRankingEntriesMap = new HashMap<>();
         if(removedEntries){

+ 9 - 5
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/plugin/operate/performance/validate/PerfRankMgmtSaveValidate.java

@@ -208,7 +208,9 @@ public class PerfRankMgmtSaveValidate extends AbstractValidator {
 
         for (int i = 0; i < entries.size(); i++) {
             DynamicObject entry = entries.get(i);
-            validateEntry(entry, rowDataEntity, i + 1, personIds, context);
+            if(entry.getBoolean(PerfRankMgmtConstant.NCKD_ISRANKING)) {
+                validateEntry(entry, rowDataEntity, i + 1, personIds, context);
+            }
         }
         context.personIds = personIds;
 
@@ -260,10 +262,12 @@ public class PerfRankMgmtSaveValidate extends AbstractValidator {
                 ));
 //        StringJoiner msgJoiner = new StringJoiner(StrFormatter.LINE_SEPARATOR);
         for (DynamicObject entry : entries) {
-            long person = entry.getDynamicObject(PerfRankMgmtConstant.NCKD_PERSON).getLong(FormConstant.ID_KEY);
-            if (!personMap.containsKey(person)) {
-                String personName = entry.getDynamicObject(PerfRankMgmtConstant.NCKD_PERSON).getString(FormConstant.NAME_KEY);
-                this.addFatalErrorMessage(rowDataEntity,StrFormatter.format("人员【{}】没有【{}】年度的考核周期;", personName,theYear));
+            if(entry.getBoolean(PerfRankMgmtConstant.NCKD_ISRANKING)) {
+                long person = entry.getDynamicObject(PerfRankMgmtConstant.NCKD_PERSON).getLong(FormConstant.ID_KEY);
+                if (!personMap.containsKey(person)) {
+                    String personName = entry.getDynamicObject(PerfRankMgmtConstant.NCKD_PERSON).getString(FormConstant.NAME_KEY);
+                    this.addFatalErrorMessage(rowDataEntity, StrFormatter.format("人员【{}】没有【{}】年度的考核周期;", personName, theYear));
+                }
             }
         }
         /*if(msgJoiner.length() > 0){

+ 64 - 73
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/task/PsmsAdjustSalaryTask.java

@@ -22,9 +22,6 @@ import kd.bos.servicehelper.QueryServiceHelper;
 import kd.bos.servicehelper.operation.SaveServiceHelper;
 import kd.sdk.plugin.Plugin;
 import kd.sdk.swc.hcdm.business.helper.HCDMApplyBillServiceHelper;
-import kd.sdk.swc.hcdm.business.helper.HCDMSalaryStdServiceHelper;
-import kd.sdk.swc.hcdm.common.dto.stdtab.match.StdTableDataMatchParam;
-import kd.sdk.swc.hcdm.common.dto.stdtab.match.StdTableDataMatchResult;
 import nckd.jxccl.base.common.constant.FormConstant;
 import nckd.jxccl.base.common.enums.psms.AdjustTypeEnum;
 import nckd.jxccl.base.common.enums.psms.TypeStateEnum;
@@ -33,7 +30,6 @@ import nckd.jxccl.base.common.utils.ConvertUtil;
 import nckd.jxccl.base.common.utils.DateUtil;
 import nckd.jxccl.base.common.utils.QueryFieldBuilder;
 import nckd.jxccl.base.common.utils.StrFormatter;
-import nckd.jxccl.base.entity.helper.EntityHelper;
 import nckd.jxccl.base.swc.helper.AdjFileServiceHelper;
 import nckd.jxccl.hr.psms.common.PositionStructureConstant;
 
@@ -65,12 +61,18 @@ public class PsmsAdjustSalaryTask extends AbstractTask implements Plugin {
 
     @Override
     public void execute(RequestContext requestContext, Map<String, Object> map) throws KDException {
+        logger.info("开始执行职位体系推送薪酬任务, 参数: {}", JSON.toJSONString(map));
+        
         //1:为本月数据,2:为上月数据
         Integer type = ConvertUtil.toInt(map.get("type"));
         Date beginDateParam = ConvertUtil.toDate(map.get("beginDateParam"));
         Date endDateParam = ConvertUtil.toDate(map.get("endDateParam"));
+        
+        logger.info("解析参数完成: type={}, beginDateParam={}, endDateParam={}", type, beginDateParam, endDateParam);
+        
         // 校验日期:要么都为空,要么都不为空
         if ((beginDateParam == null && endDateParam != null) || (beginDateParam != null && endDateParam == null)) {
+            logger.error("日期参数错误-开始日期和结束日期必须同时为空或同时不为空, beginDateParam={}, endDateParam={}", beginDateParam, endDateParam);
             throw new ValidationException("日期参数错误-开始日期和结束日期必须同时为空或同时不为空");
         }
 
@@ -81,17 +83,21 @@ public class PsmsAdjustSalaryTask extends AbstractTask implements Plugin {
         if(beginDateParam != null && endDateParam != null){
             beginDate = DateUtil.beginOfDay(beginDateParam);
             endDate = DateUtil.endOfDay(endDateParam);
+            logger.info("使用自定义日期范围: beginDate={}, endDate={}", beginDate, endDate);
         }else{
             LocalDateTime now = DateUtil.now();
             if(type == 2){
                 now = DateUtil.minusMonths(now, 1);
+                logger.info("处理上月数据");
             }else if(type == 1){
-                //本月
+                logger.info("处理本月数据");
             }else{
+                logger.error("参数错误-type,只能为1或2, 当前type={}", type);
                 throw new ValidationException("参数错误-type,只能为1或2");
             }
             beginDate = DateUtil.toDate(DateUtil.beginOfMonth(now));
             endDate = DateUtil.toDate(DateUtil.endOfMonth(now));
+            logger.info("计算日期范围: beginDate={}, endDate={}", beginDate, endDate);
         }
         filter.and(FormConstant.CREATE_TIME_KEY,QCP.large_equals,beginDate);
         filter.and(FormConstant.CREATE_TIME_KEY,QCP.less_equals,new Date());
@@ -106,11 +112,17 @@ public class PsmsAdjustSalaryTask extends AbstractTask implements Plugin {
                 .addIdNumberName(PositionStructureConstant.NCKD_LASTPERSONPOSFILE,PositionStructureConstant.NCKD_JOBLEVELHR)
                 .orderDesc(FormConstant.CREATE_TIME_KEY);
         DynamicObjectCollection personPosFileColl = QueryServiceHelper.query(PositionStructureConstant.PERSONPOSFILE_ENTITYID, queryFieldBuilder.buildSelect(), new QFilter[]{filter});
+        
+        logger.info("查询到 {} 条职位档案记录", personPosFileColl.size());
+        
         // 按人员分组,Map<Long,List<DynamicObject>>
         Map<Long, List<DynamicObject>> personPosFileMap = personPosFileColl.stream()
                 .collect(Collectors.groupingBy(
                         obj -> obj.getLong(String.join(".", PositionStructureConstant.NCKD_PERSON, FormConstant.ID_KEY))
                 ));
+        
+        logger.info("按人员分组完成,共 {} 个员工", personPosFileMap.size());
+        
         //需要推送调薪的员工档案id
         List<Long> needAdjustSalaryId = new ArrayList<>();
         List<Long> needPersonId = new ArrayList<>();
@@ -154,62 +166,19 @@ public class PsmsAdjustSalaryTask extends AbstractTask implements Plugin {
                 }
             }
         }
+        
+        logger.info("筛选出需要推送调薪的记录 {} 条", needAdjustSalaryId.size());
 
         if(!needAdjustSalaryId.isEmpty()){
+            logger.info("开始获取人员最新岗位工资标准定薪记录");
             //获取人员最新岗位工资标准定薪记录
             List<AdjFileServiceHelper.SalaryAdjustmentResult> salaryAdjustmentResultList = AdjFileServiceHelper.getLastDecAdjRecords(needPersonId, FormConstant.STANDARDITEM_ID_KEY);
-            Map<Long,AdjFileServiceHelper.SalaryAdjustmentResult> salaryAdjustmentResultMap = new HashMap<>(salaryAdjustmentResultList.size());
+            Map<Long, List<AdjFileServiceHelper.SalaryAdjustmentResult>> salaryAdjustmentResultMap = salaryAdjustmentResultList.stream()
+                    .collect(Collectors.groupingBy(result -> result.employee.getLong(FormConstant.ID_KEY)));
+            
+            logger.info("获取到 {} 条定薪记录", salaryAdjustmentResultList.size());
+            
             if (!salaryAdjustmentResultList.isEmpty()) {
-                //薪酬标准ID
-                List<Long> salaryStIds = salaryAdjustmentResultList.stream().map(result -> result.salaryStDv.getLong(FormConstant.ID_KEY)).collect(Collectors.toList());
-                QFilter salaryStandardFilter = new QFilter(FormConstant.ID_KEY, QCP.in, salaryStIds)
-                        .and(String.join(".", "rankentry", "rank", FormConstant.NUMBER_KEY), QCP.equals, "01");
-                //获取标准表中01档的薪档
-                QueryFieldBuilder salaryStandFieldBuilder = QueryFieldBuilder.create()
-                        .add(FormConstant.ID_KEY)
-                        .addIdNumberNameWithExtras(new String[]{"rankentry", "rank"},FormConstant.INDEX_KEY);
-                DynamicObjectCollection salaryStandardColl = QueryServiceHelper.query("hcdm_salarystandard", salaryStandFieldBuilder.buildSelect(), new QFilter[]{salaryStandardFilter});
-                Map<Long, DynamicObject> salaryStandardMap = salaryStandardColl.stream()
-                        .collect(Collectors.toMap(
-                                obj -> obj.getLong(FormConstant.ID_KEY),
-                                obj -> obj
-                        ));
-
-                if (!salaryStandardMap.isEmpty()) {
-                    List<StdTableDataMatchParam> matchParams = new ArrayList<>();
-                    for (AdjFileServiceHelper.SalaryAdjustmentResult result : salaryAdjustmentResultList) {
-                        StdTableDataMatchParam stdTableDataMatchParam = new StdTableDataMatchParam();
-                        stdTableDataMatchParam.setStdTableId(result.salaryStDv.getLong(FormConstant.ID_KEY));
-                        stdTableDataMatchParam.setStdItemId(FormConstant.STANDARDITEM_ID_KEY);
-                        stdTableDataMatchParam.setGradeId(result.salaryGrade.getLong(FormConstant.ID_KEY));
-                        DynamicObject dynamicObject = salaryStandardMap.get(result.salaryStDv.getLong(FormConstant.ID_KEY));
-                        if(dynamicObject != null) {
-                            long rankId = dynamicObject.getLong(String.join(".", "rankentry", "rank", FormConstant.ID_KEY));
-                            stdTableDataMatchParam.setRankId(rankId);
-                            result.salaryRank = EntityHelper.newEntity(FormConstant.HSBS_SALARYRANK, rankId);
-                            matchParams.add(stdTableDataMatchParam);
-                        }
-                    }
-                    if(!matchParams.isEmpty()) {
-                        //获取薪酬项目、薪等、薪档对应金额(入参params的数组下标和出参的数组下标一一对应)
-                        List<StdTableDataMatchResult> stdTableDataMatchResults = HCDMSalaryStdServiceHelper.matchStdTableData(matchParams);
-                        for (int i = 0; i < salaryAdjustmentResultList.size(); i++) {
-                            AdjFileServiceHelper.SalaryAdjustmentResult result = salaryAdjustmentResultList.get(i);
-                            if (i < stdTableDataMatchResults.size() && stdTableDataMatchResults.get(i) != null) {
-                                //当前薪等01档的金额
-                                result.amount = stdTableDataMatchResults.get(i).getAmount();
-                                salaryAdjustmentResultMap.put(result.employee.getLong(FormConstant.ID_KEY), result);
-                            }
-                        }
-                    }
-                } else {
-                    logger.warn("未获取薪酬标准表中01档的薪档数据,薪酬标准ID:{}",salaryStIds);
-                }
-            } else {
-                logger.warn("未获取到人员岗位工资标准定薪记录,人员ID:{}",needPersonId);
-            }
-
-            if(!salaryAdjustmentResultMap.isEmpty()){
                 Map<Long, DynamicObject> jobLevelMap = new HashMap<>(jobLevelIds.size());
                 if(!jobLevelIds.isEmpty()) {
                     MainEntityType jobLevelEntityType = EntityMetadataCache.getDataEntityType(FormConstant.HBJM_JOBLEVELHR);
@@ -220,11 +189,16 @@ public class PsmsAdjustSalaryTask extends AbstractTask implements Plugin {
                                     obj -> obj.getLong(FormConstant.ID_KEY),
                                     obj -> obj
                             ));
+                    
+                    logger.info("加载 {} 条职级信息", load.length);
                 }
 
                 List<DynamicObject> updatePersonPosFile = new ArrayList<>();
                 MainEntityType personPosFileEntityType = EntityMetadataCache.getDataEntityType(PositionStructureConstant.PERSONPOSFILE_ENTITYID);
                 DynamicObject[] personPosFileArray = BusinessDataServiceHelper.load(needAdjustSalaryId.toArray(), personPosFileEntityType);
+                
+                logger.info("加载 {} 条职位档案记录用于更新", personPosFileArray.length);
+                
                 for (DynamicObject personPosFile : personPosFileArray) {
                     long jobLevelId = personPosFile.getLong(String.join(".", PositionStructureConstant.NCKD_JOBLEVELHR, FormConstant.ID_KEY));
                     long lastJobLevelId = personPosFile.getLong(String.join(".",PositionStructureConstant.NCKD_LASTPERSONPOSFILE, PositionStructureConstant.NCKD_JOBLEVELHR, FormConstant.ID_KEY));
@@ -234,21 +208,20 @@ public class PsmsAdjustSalaryTask extends AbstractTask implements Plugin {
                     if(jobLevel != null) {
                         DynamicObject person = personPosFile.getDynamicObject(FormConstant.NCKD_PERSON);
                         Date date = personPosFile.getDate(PositionStructureConstant.NCKD_BEGINDATE);
-                        AdjFileServiceHelper.SalaryAdjustmentResult salaryAdjustmentResult = salaryAdjustmentResultMap.get(person.getLong(FormConstant.ID_KEY));
-                        if (salaryAdjustmentResult != null && salaryAdjustmentResult.amount.compareTo(BigDecimal.ZERO) > 0) {
+                        List<AdjFileServiceHelper.SalaryAdjustmentResult> salaryAdjustmentResults = salaryAdjustmentResultMap.get(person.getLong(FormConstant.ID_KEY));
+                        if (salaryAdjustmentResults != null) {
+                            AdjFileServiceHelper.SalaryAdjustmentResult salaryAdjustmentResult = salaryAdjustmentResults.get(0);
                             BigDecimal coefficient = jobLevel.getBigDecimal(PositionStructureConstant.NCKD_COEFFICIENT);
-                            BigDecimal finalAmount = BigDecimal.ZERO;
-                            if(coefficient.compareTo(BigDecimal.ZERO) > 0) {
-                                //职位津贴=职位系数 X 所在岗级岗位工资一档金额
-                                finalAmount = coefficient.multiply(salaryAdjustmentResult.amount);
-                            }
-
-
+                            
+                            logger.info("处理员工 {}, 职位档案ID: {}, 职级系数: {}", 
+                                person.getString(FormConstant.NAME_KEY), 
+                                personPosFile.getLong(FormConstant.ID_KEY), 
+                                coefficient);
+                            
                             //触发定调薪
                             Map<String, Object> applyBill = new HashMap<>();
                             applyBill.put("billname", StrFormatter.format("【{}】的职位体系调整(职位津贴)",person.getString(FormConstant.NAME_KEY)));
                             Long orgId = RequestContext.get().getOrgId();
-
                             String uniquecode = UUID.randomUUID().toString().replace("-", "");
                             applyBill.put("_uniquecode", uniquecode);
                             if(salaryAdjustmentResult.hcdmOrg != null){
@@ -256,7 +229,6 @@ public class PsmsAdjustSalaryTask extends AbstractTask implements Plugin {
                             }else{
                                 applyBill.put("org", orgId);
                             }
-
                             //定调薪明细字段显示方案   调薪明细字段
                             applyBill.put("billtype", 2215975998602655744L);
                             //国家
@@ -293,7 +265,7 @@ public class PsmsAdjustSalaryTask extends AbstractTask implements Plugin {
                                     lastJobLevel == null ? "无" : lastJobLevel.getString(FormConstant.JOBLEVELSEQ)+"级",
                                     jobLevel.getString(FormConstant.NAME_KEY),
                                     jobLevel.getString(FormConstant.JOBLEVELSEQ),
-                                     coefficient
+                                    coefficient
                             );
                             applyBill.put("description", description);
                             List<Map<String, Object>> applyBillEntryData = new ArrayList<>();
@@ -304,11 +276,11 @@ public class PsmsAdjustSalaryTask extends AbstractTask implements Plugin {
                             applyBillEntry.put("employee", employeeId);
                             applyBillEntry.put("standarditem", 2321901533681170432L);    //定调薪项目   职位系数
                             applyBillEntry.put("frequency", 1095454108284088320L);       //频度  月
-                            applyBillEntry.put("amount", finalAmount);
+                            applyBillEntry.put("amount", coefficient);
                             applyBillEntry.put("position", positionId);
                             applyBillEntry.put("joblevel", jobLevel.getLong(FormConstant.ID_KEY));
-                            applyBillEntry.put("salarygrade", salaryAdjustmentResult.salaryGrade.getLong(FormConstant.ID_KEY));
-                            applyBillEntry.put("salaryrank", salaryAdjustmentResult.salaryRank.getLong(FormConstant.ID_KEY));
+                            /*applyBillEntry.put("salarygrade", salaryAdjustmentResult.salaryGrade.getLong(FormConstant.ID_KEY));
+                            applyBillEntry.put("salaryrank", salaryAdjustmentResult.salaryRank.getLong(FormConstant.ID_KEY));*/
                             applyBillEntry.put("reason", description);
                             applyBillEntryData.add(applyBillEntry);
                             applyBill.put("applybillent", applyBillEntryData);
@@ -317,24 +289,33 @@ public class PsmsAdjustSalaryTask extends AbstractTask implements Plugin {
                             Map<String, Object> papams = new HashMap<>();
                             papams.put("data", applyBillData);
                             papams.put("isUseMatchAmount", Boolean.TRUE);
+                            
+                            logger.info("准备推送员工 {} 的定调薪申请单", person.getString(FormConstant.NAME_KEY));
                             Map<String, Object> result = HCDMApplyBillServiceHelper.saveDraftApplyBill(papams);
                             if (!ConvertUtil.toBoolean(result.get("success")) || result.get("data") == null || ConvertUtil.toList(result.get("data")).isEmpty()) {
+                                logger.error("【{}】推送定调薪失败,原因:{}", person.getString(FormConstant.NAME_KEY), JSON.toJSONString(result));
                                 throw new ValidationException("【"+person.getString(FormConstant.NAME_KEY)+"】推送定调薪失败,原因:" + JSON.toJSONString(result));
                             }else{
                                 personPosFile.set(PositionStructureConstant.NCKD_ISSALADJPUSH, Boolean.TRUE);
                                 personPosFile.set(PositionStructureConstant.NCKD_SALADJPUSHTIME, new Date());
                                 personPosFile.set(PositionStructureConstant.NCKD_SALADJID, ConvertUtil.toMap(ConvertUtil.toList(result.get("data")).get(0)).get("id"));
-                                personPosFile.set(PositionStructureConstant.NCKD_SALADJNUMBER, null);
+                                
+                                logger.info("成功推送员工 {} 的定调薪申请单,申请单ID: {}", 
+                                    person.getString(FormConstant.NAME_KEY), 
+                                    ConvertUtil.toMap(ConvertUtil.toList(result.get("data")).get(0)).get("id"));
 
                                 updatePersonPosFile.add(personPosFile);
                             }
                         } else {
-                            logger.warn("未获取到员工【{}】最新岗位工资标准定薪记录01档的薪等金额,人员ID:", person.getString(FormConstant.NAME_KEY));
+                            logger.warn("未获取到员工【{}】最新岗位工资标准定薪记录01档的薪等金额,人员ID:{}", person.getString(FormConstant.NAME_KEY), person.getLong(FormConstant.ID_KEY));
                         }
+                    } else {
+                        logger.warn("员工 {} 的职级信息为空,跳过处理", personPosFile.getDynamicObject(FormConstant.NCKD_PERSON).getString(FormConstant.NAME_KEY));
                     }
                 }
 
                 if(!updatePersonPosFile.isEmpty()){
+                    logger.info("开始保存 {} 条职位档案更新记录", updatePersonPosFile.size());
                     OperationResult operationResult = SaveServiceHelper.saveOperate(PositionStructureConstant.PERSONPOSFILE_ENTITYID, updatePersonPosFile.toArray(new DynamicObject[0]), OperateOption.create());
                     if (!operationResult.isSuccess()) {
                         StringJoiner errorMsg = new StringJoiner("\n");
@@ -344,12 +325,22 @@ public class PsmsAdjustSalaryTask extends AbstractTask implements Plugin {
                         if (!ObjectUtils.isEmpty(operationResult.getMessage())) {
                             errorMsg.add(operationResult.getMessage());
                         }
+                        logger.error("保存职位档案失败,原因:{}", errorMsg.toString());
                         throw new ValidationException("保存职位档案失败,原因:" + errorMsg.toString());
+                    } else {
+                        logger.info("成功保存 {} 条职位档案记录", updatePersonPosFile.size());
                     }
+                } else {
+                    logger.info("没有需要保存的职位档案更新记录");
                 }
+
+            } else {
+                logger.warn("未获取到人员岗位工资标准定薪记录,人员ID:{}",needPersonId);
             }
         }else{
             logger.warn("没有需要推送的调薪数据");
         }
+        
+        logger.info("职位体系推送薪酬任务执行完成");
     }
 }

+ 7 - 7
code/opmc/nckd-jxccl-opmc/src/main/java/nckd/jxccl/opmc/pm/plugin/operate/cycle/CycleGenerateOpPlugin.java

@@ -191,7 +191,7 @@ public class CycleGenerateOpPlugin extends AbstractOperationServicePlugIn implem
 
         if (!userAdminOrgWithSub.isHasAllOrgPerm()) {
             List<Long> orgIds = extractOrgIds(userAdminOrgWithSub.getHasPermOrgsWithSub());
-            newHireFilter.and(String.join(".", FormConstant.HRPI_EMPPOSORGREL, FormConstant.ADMINORG), QCP.in, orgIds);
+            newHireFilter.and(String.join( ".",FormConstant.ADMINORG,FormConstant.ID_KEY), QCP.in, orgIds);
         }
 
 
@@ -250,7 +250,7 @@ public class CycleGenerateOpPlugin extends AbstractOperationServicePlugIn implem
                 .and(String.join(".", FormConstant.HRPI_EMPENTREL, FormConstant.LABOR_REL_STATUS, FormConstant.IS_HIRED),
                         QCP.equals, EnableEnum.YES.getCode())
                 //岗位绩效工资制
-                .and(String.join(".", FormConstant.HRPI_EMPPOSORGREL, FormConstant.POSITION_KEY,FormConstant.NCKD_PAYSTDPLAN, FormConstant.NUMBER_KEY),QCP.equals,FormConstant.POST_PERF_WAGE_SYS);
+                .and(String.join(".",FormConstant.POSITION_KEY,FormConstant.NCKD_PAYSTDPLAN, FormConstant.NUMBER_KEY),QCP.equals,FormConstant.POST_PERF_WAGE_SYS);
 
     }
 
@@ -269,9 +269,9 @@ public class CycleGenerateOpPlugin extends AbstractOperationServicePlugIn implem
     private static DynamicObjectCollection queryNewHirePersons(QFilter filter) {
         QueryFieldBuilder queryFieldBuilder = QueryFieldBuilder.create()
                 .addIdNumberName(FormConstant.HRPI_EMPLOYEE)
-                .addGroup(new String[]{FormConstant.HRPI_EMPPOSORGREL},FormConstant.ID_KEY)
-                .addGroup(new String[]{FormConstant.HRPI_EMPPOSORGREL,FormConstant.ADMINORG},FormConstant.ID_KEY);
-        QueryEntityType queryEntityType = (QueryEntityType) EntityMetadataCache.getDataEntityType(QueryConstant.PERSON_QUERY);
+                .add(FormConstant.ID_KEY)
+                .addIdNumberName(FormConstant.ADMINORG);
+        QueryEntityType queryEntityType = (QueryEntityType) EntityMetadataCache.getDataEntityType("personfilequery");
         return HRQueryEntityHelper.getInstance().getQueryDyoColl(queryEntityType, queryFieldBuilder.buildSelect(), new QFilter[]{filter}, null);
     }
 
@@ -327,8 +327,8 @@ public class CycleGenerateOpPlugin extends AbstractOperationServicePlugIn implem
         logger.debug("开始为新入职员工生成考核周期,新入职员工总数: {}", newHirePersonList.size());
         for (DynamicObject person : newHirePersonList) {
             long personId = person.getLong(String.join(".", FormConstant.HRPI_EMPLOYEE, FormConstant.ID_KEY));
-            long empPosOrgRelId = person.getLong(String.join(".", FormConstant.HRPI_EMPPOSORGREL, FormConstant.ID_KEY));
-            long adminOrgId = person.getLong(String.join(".", FormConstant.HRPI_EMPPOSORGREL,FormConstant.ADMINORG, FormConstant.ID_KEY));
+            long empPosOrgRelId = person.getLong(FormConstant.ID_KEY);
+            long adminOrgId = person.getLong(String.join(".", FormConstant.ADMINORG, FormConstant.ID_KEY));
             // 判断是否已有周期,如果有则不生成
             if (!personIds.contains(personId)) {
                 DynamicObject empPosOrgRel = EntityHelper.newEntity(FormConstant.HRPI_EMPPOSORGREL);

+ 2 - 2
code/opmc/nckd-jxccl-opmc/src/main/java/nckd/jxccl/opmc/pm/plugin/operate/cycle/PerfManagerSaveOpPlugin.java

@@ -239,7 +239,7 @@ public class PerfManagerSaveOpPlugin extends AbstractOperationServicePlugIn impl
                     LocalDateTime endYear = ConvertUtil.toLocalDateTime(data.getDate(PerfManagerFormConstant.NCKD_ENDYEAR));
 
                     // 判断beginYear和endYear是不是间隔3年,例如:开始2025年,结束必须为2027年
-                    if (beginYear != null && endYear != null) {
+                   /* if (beginYear != null && endYear != null) {
                         int beginYearValue = beginYear.getYear();
                         int endYearValue = endYear.getYear();
                         if (endYearValue - beginYearValue != 2) {
@@ -247,7 +247,7 @@ public class PerfManagerSaveOpPlugin extends AbstractOperationServicePlugIn impl
                                     StrFormatter.format("周期开始年份【{}】与结束年份【{}】必须间隔3年,请检查!",
                                             beginYearValue, endYearValue));
                         }
-                    }
+                    }*/
 
                     //校验是否存在相同周期开始年的记录 begin
                     List<DynamicObject> personRecords = groupedQueryResults.getOrDefault(personId, Collections.emptyList());

+ 53 - 48
code/opmc/nckd-jxccl-opmc/src/main/java/nckd/jxccl/opmc/pm/plugin/operate/salary/PushAdjustOpPlugin.java

@@ -106,58 +106,63 @@ public class PushAdjustOpPlugin extends AbstractOperationServicePlugIn implement
                 DynamicObject person = pushAdjust.getDynamicObject(SalAdjTrackerConstant.NCKD_PERFMANAGER).getDynamicObject(FormConstant.NCKD_PERSON);
                 applyBill.put("billname", StrFormatter.format("【{}】的岗位工资动态调整(人员考评)",person.getString(FormConstant.NAME_KEY)));
 
-                Long orgId = RequestContext.get().getOrgId();
+                DynamicObject adjFileInfo = pushAdjust.getDynamicObject(SalAdjTrackerConstant.NCKD_ADJFILEINFO);
+                if(adjFileInfo != null) {
+                    Long orgId = adjFileInfo.getLong(String.join(".", FormConstant.ORG_KEY, FormConstant.ID_KEY)) > 0 ? adjFileInfo.getLong(String.join(".", FormConstant.ORG_KEY, FormConstant.ID_KEY)) : RequestContext.get().getOrgId();
 
-                String uniquecode = UUID.randomUUID().toString().replace("-", "");
-                applyBill.put("_uniquecode", uniquecode);
-                applyBill.put("org", orgId);
-                //定调薪明细字段显示方案   调薪明细字段
-                applyBill.put("billtype", 2215975998602655744L);
-                //国家
-                applyBill.put("billcountry", 1000001L);
-                //定调薪类型
-                applyBill.put("salaryadjrsn", 2352337648716103680L);
-                //默认币种
-                applyBill.put("billcurrency", 1L);
-                //定调薪方案
-                applyBill.put("salaryadjscm", 2322515162646457344L);
-                //汇率日期
-                applyBill.put("exchangeratedate", new Date());
-                //汇率表
-                applyBill.put("exctable", 2321965096026258432L);
-                //默认生效日期
-                applyBill.put("effectivedate", new Date());
-                //草稿状态
-                applyBill.put("isdraft", "1");
-                //审核状态
-                applyBill.put("auditstatus", "A");
-                //申请单数据来源   //1:手工新增  2:接口写入
-                applyBill.put("datasource", "2");
-                applyBill.put("description", pushAdjust.getString(SalAdjTrackerConstant.NCKD_WAGEEXPLAIN));
-                List<Map<String, Object>> applyBillEntryData = new ArrayList<>();
-                Map<String, Object> applyBillEntry = new HashMap<>();
-                Long employeeId = pushAdjust.getDynamicObject(SalAdjTrackerConstant.NCKD_PERFMANAGER).getDynamicObject(FormConstant.NCKD_PERSON).getLong(FormConstant.ID_KEY);
-                Long positionId = pushAdjust.getDynamicObject(SalAdjTrackerConstant.NCKD_POSITION).getLong(FormConstant.ID_KEY);
-                applyBillEntry.put("adjfile", pushAdjust.getDynamicObject(SalAdjTrackerConstant.NCKD_ADJFILEINFO).getLong(FormConstant.ID_KEY));
-                applyBillEntry.put("employee", employeeId);
-                applyBillEntry.put("standarditem", 2321899710350111744L);    //定调薪项目   岗位工资标准
-                applyBillEntry.put("frequency", 1095454108284088320L);       //频度  月
-                applyBillEntry.put("amount", pushAdjust.getBigDecimal(SalAdjTrackerConstant.NCKD_MONEY));
+                    String uniquecode = UUID.randomUUID().toString().replace("-", "");
+                    applyBill.put("_uniquecode", uniquecode);
+                    applyBill.put("org", orgId);
+                    //定调薪明细字段显示方案   调薪明细字段
+                    applyBill.put("billtype", 2215975998602655744L);
+                    //国家
+                    applyBill.put("billcountry", 1000001L);
+                    //定调薪类型
+                    applyBill.put("salaryadjrsn", 2352337648716103680L);
+                    //默认币种
+                    applyBill.put("billcurrency", 1L);
+                    //定调薪方案
+                    applyBill.put("salaryadjscm", 2322515162646457344L);
+                    //汇率日期
+                    applyBill.put("exchangeratedate", new Date());
+                    //汇率表
+                    applyBill.put("exctable", 2321965096026258432L);
+                    //默认生效日期
+                    applyBill.put("effectivedate", new Date());
+                    //草稿状态
+                    applyBill.put("isdraft", "1");
+                    //审核状态
+                    applyBill.put("auditstatus", "A");
+                    //申请单数据来源   //1:手工新增  2:接口写入
+                    applyBill.put("datasource", "2");
+                    applyBill.put("description", pushAdjust.getString(SalAdjTrackerConstant.NCKD_WAGEEXPLAIN));
+                    List<Map<String, Object>> applyBillEntryData = new ArrayList<>();
+                    Map<String, Object> applyBillEntry = new HashMap<>();
+                    Long employeeId = pushAdjust.getDynamicObject(SalAdjTrackerConstant.NCKD_PERFMANAGER).getDynamicObject(FormConstant.NCKD_PERSON).getLong(FormConstant.ID_KEY);
+                    Long positionId = pushAdjust.getDynamicObject(SalAdjTrackerConstant.NCKD_POSITION).getLong(FormConstant.ID_KEY);
+                    applyBillEntry.put("adjfile", adjFileInfo.getLong(FormConstant.ID_KEY));
+                    applyBillEntry.put("employee", employeeId);
+                    applyBillEntry.put("standarditem", 2321899710350111744L);    //定调薪项目   岗位工资标准
+                    applyBillEntry.put("frequency", 1095454108284088320L);       //频度  月
+                    applyBillEntry.put("amount", pushAdjust.getBigDecimal(SalAdjTrackerConstant.NCKD_MONEY));
 //            applyBillEntry.put("nckd_postgrade", salaryfile.getLong("position.nckd_postgrade.id"));  //岗级
-                applyBillEntry.put("position", positionId);
+                    applyBillEntry.put("position", positionId);
 
-                applyBillEntry.put("salarygrade", pushAdjust.getLong(String.join(".",SalAdjTrackerConstant.NCKD_SALARYGRADE,FormConstant.ID_KEY)));
-                applyBillEntry.put("salaryrank", pushAdjust.getLong(String.join(".",SalAdjTrackerConstant.NCKD_SALARYRANK,FormConstant.ID_KEY)));
-                applyBillEntry.put("reason", pushAdjust.getString(SalAdjTrackerConstant.NCKD_WAGEEXPLAIN));
-                applyBillEntryData.add(applyBillEntry);
-                applyBill.put("applybillent", applyBillEntryData);
-                applyBillData.add(applyBill);
+                    applyBillEntry.put("salarygrade", pushAdjust.getLong(String.join(".", SalAdjTrackerConstant.NCKD_SALARYGRADE, FormConstant.ID_KEY)));
+                    applyBillEntry.put("salaryrank", pushAdjust.getLong(String.join(".", SalAdjTrackerConstant.NCKD_SALARYRANK, FormConstant.ID_KEY)));
+                    applyBillEntry.put("reason", pushAdjust.getString(SalAdjTrackerConstant.NCKD_WAGEEXPLAIN));
+                    applyBillEntryData.add(applyBillEntry);
+                    applyBill.put("applybillent", applyBillEntryData);
+                    applyBillData.add(applyBill);
+                }
             }
-            papams.put("data", applyBillData);
-            papams.put("isUseMatchAmount", Boolean.TRUE);
-            Map<String, Object> result = HCDMApplyBillServiceHelper.saveDraftApplyBill(papams);
-            if (!ConvertUtil.toBoolean(result.get("success")) || result.get("data") == null || ConvertUtil.toList(result.get("data")).isEmpty()) {
-                throw new ValidationException("推送定调薪失败,原因:" + JSON.toJSONString(result));
+            if(!applyBillData.isEmpty()) {
+                papams.put("data", applyBillData);
+                papams.put("isUseMatchAmount", Boolean.TRUE);
+                Map<String, Object> result = HCDMApplyBillServiceHelper.saveDraftApplyBill(papams);
+                if (!ConvertUtil.toBoolean(result.get("success")) || result.get("data") == null || ConvertUtil.toList(result.get("data")).isEmpty()) {
+                    throw new ValidationException("推送定调薪失败,原因:" + JSON.toJSONString(result));
+                }
             }
         }
     }

+ 6 - 0
code/swc/nckd-jxccl-swc/src/main/java/nckd/jxccl/swc/hcdm/formplugin/annualincome/SalAnnualIncomeBillEdit.java

@@ -81,6 +81,12 @@ public class SalAnnualIncomeBillEdit extends AbstractFormPlugin implements Plugi
         // 排除薪资核算组
         List<Long> excludeGroupIds = SwcUtils.getExcludePayRollGroupIds(calYear);
         groupIds.removeAll(excludeGroupIds);
+
+        if(groupIds.size() == 0) {
+            this.getView().showMessage("当前核算组已生成过数据,请勿重复生成!");
+            return;
+        }
+
         // 获取年度最后一天
         Date endDate = SwcUtils.getLastDayOfYear(calYear);
         // 声明service

+ 38 - 10
code/swc/nckd-jxccl-swc/src/main/java/nckd/jxccl/swc/hsas/business/outdata/OutImportTaskGuideExportService.java

@@ -15,6 +15,7 @@ import kd.bos.logging.LogFactory;
 import kd.bos.orm.query.QFilter;
 import kd.bos.orm.util.CollectionUtils;
 import nckd.jxccl.base.sit.helper.SITExportDataHelper;
+import nckd.jxccl.base.swc.helper.SWCHelper;
 import nckd.jxccl.sit.hcsi.business.importtaskguide.utils.ImportTaskUtils;
 import nckd.jxccl.sit.hcsi.common.constant.enums.DataTypeEnum;
 import nckd.jxccl.sit.hcsi.common.constant.enums.SITShowType;
@@ -185,7 +186,16 @@ public class OutImportTaskGuideExportService {
                     if (options != null && options.length > 0) {
                         // 创建数据验证
                         int columnIndex = Integer.parseInt(columnHead.get("columnIndex"));
-                        setDataValidation(sheet, options, columnIndex, firstDataRowIndex);
+                        setDataValidation(sheet, options, columnIndex, firstDataRowIndex, true);
+                    }
+                }
+                // 特殊处理二级单位
+                else if (presetItem != null && presetItem.getItemNumber().equals("R1")) {
+                    String[] options = getOrgDropdownOptions();
+                    if (options != null && options.length > 0) {
+                        // 创建数据验证
+                        int columnIndex = Integer.parseInt(columnHead.get("columnIndex"));
+                        setDataValidation(sheet, options, columnIndex, firstDataRowIndex, false);
                     }
                 }
             }
@@ -219,9 +229,28 @@ public class OutImportTaskGuideExportService {
                 .toArray(String[]::new);
     }
 
-    private void setDataValidation(SXSSFSheet sheet, String[] options, int columnIndex, int firstDataRowIndex) {
+    /**
+     * 针对二级单位特殊处理,获取系统内所有二级组织
+     * @return
+     */
+    private String[] getOrgDropdownOptions() {
+        DynamicObjectCollection cols = SWCHelper.getAllSecondOrg();
+        String[] orgNames = cols.stream().map(col -> col.getString("name")).toArray(String[]::new);
+        return orgNames;
+    }
+
 
-        // 检查选项总长度是否超过限制
+    /**
+     * 为Excel工作表的指定列设置数据验证(下拉列表)约束
+     *
+     * @param sheet Excel工作表对象
+     * @param options 下拉列表的选项数组
+     * @param columnIndex 要设置下拉列表的列索引(从0开始)
+     * @param firstDataRowIndex 数据起始行索引
+     * @param isAllowOutRange 是否允许输入列表外的值,true表示允许输入自定义值,false表示只能选择列表项
+     */
+    private void setDataValidation(SXSSFSheet sheet, String[] options, int columnIndex, int firstDataRowIndex, boolean isAllowOutRange) {
+        // 检查选项总长度是否超过Excel的255字符限制
         String optionsString = String.join(",", options);
         if (optionsString.length() > 255) {
             // 如果超过255字符限制,则不创建下拉列表或采用其他方式处理
@@ -241,13 +270,12 @@ public class OutImportTaskGuideExportService {
         DataValidation validation = validationHelper.createValidation(constraint, addressList);
 
         // 允许输入列表外的文本
-        validation.setShowErrorBox(false);  // 不显示错误框
-        validation.setEmptyCellAllowed(true); // 允许空值
-
-        // 可选:添加输入提示
-        validation.setShowPromptBox(true);
-        validation.createPromptBox("输入提示", "可选择下拉选项或输入自定义值");
-
+        if(isAllowOutRange) {
+            validation.setShowErrorBox(false);  // 不显示错误框
+            validation.setEmptyCellAllowed(true); // 允许空值
+            validation.setShowPromptBox(true); // 可选:添加输入提示
+            validation.createPromptBox("输入提示", "可选择下拉选项或输入自定义值");
+        }
         // 添加到工作表
         sheet.addValidationData(validation);
     }

+ 1 - 1
code/swc/nckd-jxccl-swc/src/main/java/nckd/jxccl/swc/hsas/business/outdata/OutImportTaskGuideImportService.java

@@ -213,7 +213,7 @@ public class OutImportTaskGuideImportService {
                 temporary.set("modifier", RequestContext.get().getCurrUserId());
                 temporary.set("modifytime", new Date());
                 temporary.set("billstatus", "A");
-                temporary.set("entryentity", OutImportTaskUtils.getItemEntryList(rowMap, columnIndexMap, commonColumnIndexMap, entryType));
+                temporary.set("entryentity", OutImportTaskUtils.getItemEntryList(temporary, rowMap, columnIndexMap, commonColumnIndexMap, entryType));
                 result.add(temporary);
             }
             HRBaseServiceHelper helper = new HRBaseServiceHelper("nckd_outtempdata");

+ 28 - 5
code/swc/nckd-jxccl-swc/src/main/java/nckd/jxccl/swc/hsas/business/utils/OutImportTaskUtils.java

@@ -11,7 +11,8 @@ import kd.hr.hbp.business.bgtask.HRBackgroundTaskHelper;
 import kd.hr.hbp.business.servicehelper.HRBaseServiceHelper;
 import kd.hr.hbp.common.cache.HRAppCache;
 import kd.hr.hbp.common.cache.IHRAppCache;
-import nckd.jxccl.sit.hcsi.formplugin.web.tp.enums.SinsurPresetItemEnum;
+import nckd.jxccl.base.swc.helper.SWCHelper;
+import nckd.jxccl.swc.constants.SwcConstant;
 import nckd.jxccl.swc.hsas.common.OutImpPresetItem;
 import nckd.jxccl.swc.hsas.formplugin.web.outdata.helper.OutImpTemplateHelper;
 
@@ -21,7 +22,7 @@ public class OutImportTaskUtils {
 
     private static final String TPL_ENTITY = "nckd_outimptpl";
     private static final String SALARYITEM_ENTITY = "hsbs_salaryitem";
-
+    private static final String SECONDORG_NUMBER = "R1";
 
     public static DynamicObject getTplData(Long sinsurTplId, String fields, QFilter qFilter) {
         HRBaseServiceHelper helper = new HRBaseServiceHelper(TPL_ENTITY);
@@ -214,7 +215,7 @@ public class OutImportTaskUtils {
 
     }
 
-    public static DynamicObjectCollection getItemEntryList(Map<Integer, Object> rowMap, Map<Integer, List<Map<String, String>>> columnIndexMap, Map<Integer, List<Map<String, String>>> commonColumnIndexMap, EntityType entryType) {
+    public static DynamicObjectCollection getItemEntryList(DynamicObject temporary, Map<Integer, Object> rowMap, Map<Integer, List<Map<String, String>>> columnIndexMap, Map<Integer, List<Map<String, String>>> commonColumnIndexMap, EntityType entryType) {
         DynamicObjectCollection itemEntryList = new DynamicObjectCollection();
         int sequence = 0;
         for (Map.Entry<Integer, List<Map<String, String>>> entry : columnIndexMap.entrySet()) {
@@ -248,20 +249,33 @@ public class OutImportTaskUtils {
                 }
             }
         }
+
+        //获取二级单位这个项目的内码
+        DynamicObject secondOrgItemDyn = getSecondOrgItemId();
+        Long secondOrgItemId = secondOrgItemDyn.getLong("id");
+
         for (Map.Entry<Integer, List<Map<String, String>>> entry : commonColumnIndexMap.entrySet()) {
             Object itemValue = rowMap.get(entry.getKey());
             if (itemValue == null) {
                 continue;
             }
+
             for (Map<String, String> itemMap : entry.getValue()) {
                 try {
                     DynamicObject item = (DynamicObject) entryType.createInstance();
-
                     item.set("nckd_itemvalue", itemValue);
+                    // 所属二级单位单独处理,获取到内码写到表头,方便后续获取
+                    Long itemId = Long.valueOf(itemMap.get("id"));
+                    if(secondOrgItemId.equals(itemId)) {
+                        temporary.set("nckd_secondorg", SWCHelper.getOrgByName(String.valueOf(itemValue)));
+                    }
+
                     item.set("nckd_itemtype", itemMap.get("itemType"));
                     item.set("nckd_itemname", itemMap.get("name"));
                     item.set("seq", sequence);
 
+
+
                     String id = itemMap.get("id");
                     if (id != null) {
                         item.set("nckd_itemid", Long.valueOf(id));
@@ -293,7 +307,7 @@ public class OutImportTaskUtils {
     }
 
     public static void updateImportTaskStatus(Long importTaskId) {
-        HRBaseServiceHelper temporaryHelper = new HRBaseServiceHelper("nckd_sinsurtempdata");
+        HRBaseServiceHelper temporaryHelper = new HRBaseServiceHelper("nckd_outtempdata");
         QFilter filter = new QFilter("nckd_importtask", "=", importTaskId);
         int count = temporaryHelper.count(temporaryHelper.getEntityName(), new QFilter[]{filter});
         if (count == 0) {
@@ -423,4 +437,13 @@ public class OutImportTaskUtils {
         }
     }
 
+    /**
+     * @return
+     */
+    public static DynamicObject getSecondOrgItemId() {
+       QFilter filter = new QFilter("number", "=", SECONDORG_NUMBER);
+       return SwcConstant.OUTIMPORTITEM_ENTITY.queryOriginalOne(filter);
+    }
+
+
 }

+ 9 - 0
code/swc/nckd-jxccl-swc/src/main/java/nckd/jxccl/swc/hsas/common/OutImpPresetItem.java

@@ -6,6 +6,7 @@ public class OutImpPresetItem {
     private String itemName;
     private Long dataTypeId;
     private String comment;
+    private String itemNumber;
 
     public String getMatchColumn() {
         return this.matchColumn;
@@ -23,6 +24,14 @@ public class OutImpPresetItem {
         this.itemId = itemId;
     }
 
+    public String getItemNumber() {
+        return this.itemNumber;
+    }
+
+    public void setItemNumber(String itemNumber) {
+        this.itemNumber = itemNumber;
+    }
+
     public String getItemName() {
         return this.itemName;
     }

+ 6 - 2
code/swc/nckd-jxccl-swc/src/main/java/nckd/jxccl/swc/hsas/formplugin/web/outdata/basedata/OutImpTemplateEdit.java

@@ -159,6 +159,7 @@ public class OutImpTemplateEdit extends AbstractFormPlugin implements Plugin {
         setter.addField("nckd_datatype", new Object[0]);
         setter.addField("nckd_comment", new Object[0]);
         setter.addField("nckd_uniquecode", new Object[0]);
+        setter.addField("nckd_ispreset", new Object[0]);
         return setter;
     }
 
@@ -342,7 +343,10 @@ public class OutImpTemplateEdit extends AbstractFormPlugin implements Plugin {
         int index;
         for(index = 0; index < entryDatas.size(); ++index) {
             DynamicObject entry = (DynamicObject)entryDatas.get(index);
-            if (!StringUtils.equals(entry.getString("nckd_itemtype"), "0")) {
+//            if (!StringUtils.equals(entry.getString("nckd_itemtype"), "0")) {
+//                break;
+//            }
+            if(!entry.getBoolean("nckd_ispreset")) {
                 break;
             }
         }
@@ -355,7 +359,7 @@ public class OutImpTemplateEdit extends AbstractFormPlugin implements Plugin {
         List<OutImpPresetItem> presetItemEnumsList = OutImpTemplateHelper.getPresetItemEnumList();
         if (!CollectionUtils.isEmpty(presetItemEnumsList)) {
             for(OutImpPresetItem presetItemEnum : presetItemEnumsList) {
-                tableValueSetter.addRow(new Object[]{presetItemEnum.getMatchColumn(), "0", presetItemEnum.getItemId(), 0L, 0L, 0L, 0L, '-', presetItemEnum.getItemName(), presetItemEnum.getDataTypeId(), presetItemEnum.getComment(), ""});
+                tableValueSetter.addRow(new Object[]{presetItemEnum.getMatchColumn(), "2", presetItemEnum.getItemId(), 0L, 0L, 0L, 0L, presetItemEnum.getItemNumber(), presetItemEnum.getItemName(), presetItemEnum.getDataTypeId(), presetItemEnum.getComment(), "", true});
             }
         }
         model.beginInit();

+ 3 - 0
code/swc/nckd-jxccl-swc/src/main/java/nckd/jxccl/swc/hsas/formplugin/web/outdata/basedata/OutItemSelectAddItemPlugin.java

@@ -352,6 +352,9 @@ public class OutItemSelectAddItemPlugin extends AbstractFormPlugin implements Pl
 
         IDataModel model = this.getModel();
         for (DynamicObject matchRelationData : matchRelationDatas) {
+            if(matchRelationData.getBoolean("nckd_ispreset")) {
+                continue;
+            }
             String itemType = matchRelationData.getString("nckd_itemtype");
             String itemCategory = ITEM_TYPE_MAPPING.get(itemType);
 

+ 173 - 0
code/swc/nckd-jxccl-swc/src/main/java/nckd/jxccl/swc/hsas/formplugin/web/outdata/basedata/OutItemSelectTreePlugin.java

@@ -0,0 +1,173 @@
+package nckd.jxccl.swc.hsas.formplugin.web.outdata.basedata;
+
+import kd.bos.dataentity.entity.DynamicObjectCollection;
+import kd.bos.dataentity.resource.ResManager;
+import kd.bos.entity.tree.TreeNode;
+import kd.bos.form.control.Search;
+import kd.bos.form.control.TreeView;
+import kd.bos.form.control.events.SearchEnterEvent;
+import kd.bos.form.control.events.SearchEnterListener;
+import kd.bos.form.plugin.AbstractFormPlugin;
+import kd.hr.hbp.common.cache.HRPageCache;
+import nckd.jxccl.base.swc.helper.SWCHelper;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * Tyx 2025-12-22
+ * 外单位项目选择界面右表格搜索插件 【hsas_calitemselect】
+ */
+public class OutItemSelectTreePlugin extends AbstractFormPlugin implements SearchEnterListener {
+
+    // 常量定义
+    private static final String TREE_SEARCH_CONTROL = "nckd_treesearchap";
+    private static final String TREE_VIEW_CONTROL = "nckd_treeviewap";
+    private static final String ITEM_SELECT_ENTRY = "nckd_itemselectentry";
+    private static final String SALARY_ITEM_KEY = "salaryitemkey";
+    private static final String NO_SEARCH_RESULT_MSG = "搜索已完成,未找到搜索项。";
+
+    public OutItemSelectTreePlugin() {
+    }
+
+    public void registerListener(EventObject e) {
+        super.registerListener(e);
+        Search search = (Search)this.getView().getControl(TREE_SEARCH_CONTROL);
+        search.addEnterListener(this);
+    }
+
+    @Override
+    public void search(SearchEnterEvent arg) {
+        String searchText = arg.getText();
+        HRPageCache pageCache = new HRPageCache(this.getView());
+        Map<String, Map<String, Map<String, Object>>> dataMap =
+                (Map<String, Map<String, Map<String, Object>>>) pageCache.get("allItemData", Map.class);
+        boolean isExpend = StringUtils.isNotEmpty(searchText);
+
+        List<TreeNode> nodeItemList = new ArrayList<>();
+        nodeItemList.addAll(loadSLItemChildNode(searchText, isExpend, dataMap));
+        nodeItemList.addAll(loadBSItemChildNode(searchText, isExpend, dataMap));
+
+        if (nodeItemList.isEmpty()) {
+            showNoResultNotification();
+        } else {
+            updateTreeView(nodeItemList);
+        }
+    }
+
+    private void showNoResultNotification() {
+        this.getView().showTipNotification(
+                ResManager.loadKDString(NO_SEARCH_RESULT_MSG, "CalResultTplItemTreePlugin_0",
+                        "swc-hsas-formplugin", new Object[0]));
+    }
+
+    private void updateTreeView(List<TreeNode> nodeItemList) {
+        TreeView treeView = (TreeView) this.getView().getControl(TREE_VIEW_CONTROL);
+        treeView.deleteAllNodes();
+        treeView.addNodes(nodeItemList);
+        checkSelectedTreeNode(treeView, nodeItemList);
+    }
+
+    private void checkSelectedTreeNode(TreeView treeView, List<TreeNode> nodeList) {
+        DynamicObjectCollection selectDatas = this.getView().getModel().getEntryEntity(ITEM_SELECT_ENTRY);
+        Set<String> uniqueCodeSet = (Set)selectDatas.stream().map((selectData) -> {
+            return selectData.getString("nckd_itemunicodeid");
+        }).collect(Collectors.toSet());
+        List<TreeNode> checkNodeList = SWCHelper.getCheckTreeNodeList(nodeList, uniqueCodeSet);
+        if (CollectionUtils.isNotEmpty(checkNodeList)) {
+            treeView.checkNodes(checkNodeList);
+        }
+    }
+
+    private List<TreeNode> loadSLItemChildNode(String name, boolean isExpend, Map<String, Map<String, Map<String, Object>>> dataMap) {
+        List<TreeNode> childNodes = new ArrayList<>(10);
+        List<Map<String, Object>> salaryItemList;
+        if (StringUtils.isEmpty(name)) {
+            salaryItemList = SWCHelper.mapToList(dataMap.get("salaryitemkey"));
+        } else {
+            salaryItemList = this.findItemByName(name, "salaryitemkey", dataMap);
+        }
+
+        if (salaryItemList == null || salaryItemList.isEmpty()) {
+            return childNodes;
+        }
+        // 构建项目类型节点映射和项目节点列表映射
+        Map<String, TreeNode> itemTypeNodeMap = new LinkedHashMap<>(salaryItemList.size());
+        Map<String, List<TreeNode>> salaryItemNodeMap = new HashMap<>(16);
+        // 遍历薪酬项目列表,构建树节点
+        for (Map<String, Object> itemMap : salaryItemList) {
+            String itemTypeNum = (String) itemMap.get("group_number");
+            String itemTypeName = (String) itemMap.get("group_name");
+
+            // 获取或创建该项目类型的节点列表
+            List<TreeNode> itemNodes = salaryItemNodeMap.computeIfAbsent(itemTypeNum, k -> new ArrayList<>(10));
+
+            // 添加项目节点
+            String groupId = "SI" + itemTypeNum + "_@_";
+            String nodeId = String.valueOf(itemMap.get("id"));
+            String uniqueCode = String.valueOf(itemMap.get("uniquecode"));
+            String itemName = (String) itemMap.get("name");
+            itemNodes.add(new TreeNode(groupId, nodeId, itemName));
+
+            // 如果还没有该项目类型的父节点,则创建
+            if (!itemTypeNodeMap.containsKey(itemTypeNum)) {
+                TreeNode itemTypeNode = new TreeNode("SI", groupId, itemTypeName);
+                itemTypeNode.setExpend(isExpend);
+                itemTypeNode.setIsOpened(isExpend);
+                itemTypeNodeMap.put(itemTypeNum, itemTypeNode);
+            }
+        }
+
+        // 关联子节点到父节点
+        List<TreeNode> finalTreeNodes = new ArrayList<>(itemTypeNodeMap.size());
+        for (Map.Entry<String, TreeNode> entry : itemTypeNodeMap.entrySet()) {
+            TreeNode parentNode = entry.getValue();
+            List<TreeNode> children = salaryItemNodeMap.get(entry.getKey());
+            parentNode.setChildren(children);
+            finalTreeNodes.add(parentNode);
+        }
+
+        // 添加根节点
+        if (!finalTreeNodes.isEmpty()) {
+            TreeNode root = new TreeNode("", "SI",
+                    ResManager.loadKDString("薪酬项目-SI", "FormulaItemOrFuncTreeHelper_1",
+                            "swc-hsas-business", new Object[0]));
+            root.setChildren(finalTreeNodes);
+            root.setExpend(isExpend);
+            root.setIsOpened(isExpend);
+            childNodes.add(root);
+        }
+
+        return childNodes;
+    }
+
+    private List<TreeNode> loadBSItemChildNode(String name, boolean isExpend, Map<String, Map<String, Map<String, Object>>> dataMap) {
+        List<TreeNode> childNodes = new ArrayList<>(10);
+        return childNodes;
+    }
+
+
+    private List<Map<String, Object>> findItemByName(String name, String itemName, Map<String, Map<String, Map<String, Object>>> dataMap) {
+        Map<String, Map<String, Object>> result = dataMap.get(itemName);
+        if (result == null) {
+            return new ArrayList<>(0);
+        }
+
+        return result.entrySet().stream()
+                .filter(entry -> {
+                    Map<String, Object> itemMap = entry.getValue();
+                    if (itemMap == null || itemMap.isEmpty()) {
+                        return entry.getKey().contains(name);
+                    }
+
+                    String number = (String) itemMap.get("number");
+                    return (StringUtils.isNotEmpty(number) && number.contains(name)) ||
+                            entry.getKey().contains(name);
+                })
+                .map(Map.Entry::getValue)
+                .collect(Collectors.toList());
+    }
+
+}

+ 1 - 0
code/swc/nckd-jxccl-swc/src/main/java/nckd/jxccl/swc/hsas/formplugin/web/outdata/helper/OutImpTemplateHelper.java

@@ -225,6 +225,7 @@ public class OutImpTemplateHelper {
             item.setItemName(dyn.getString("name"));
             item.setComment(dyn.getString("nckd_presetcomment"));
             item.setDataTypeId(dyn.getLong("nckd_datatype.id"));
+            item.setItemNumber(dyn.getString("number"));
             //item.setMatchColumn(dyn.);
             outImpPresetItemEnumList.add(item);
         }

+ 53 - 0
code/swc/nckd-jxccl-swc/src/main/java/nckd/jxccl/swc/hsas/opplugin/web/OutTempDataOpPlugin.java

@@ -0,0 +1,53 @@
+package nckd.jxccl.swc.hsas.opplugin.web;
+
+import kd.bos.dataentity.entity.DynamicObject;
+import kd.bos.entity.plugin.AbstractOperationServicePlugIn;
+import kd.bos.entity.plugin.PreparePropertysEventArgs;
+import kd.bos.entity.plugin.args.EndOperationTransactionArgs;
+import kd.sdk.plugin.Plugin;
+import nckd.jxccl.swc.hsas.business.utils.OutImportTaskUtils;
+
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/**
+ * 单据操作插件
+ */
+public class OutTempDataOpPlugin extends AbstractOperationServicePlugIn implements Plugin {
+
+    @Override
+    public void onPreparePropertys(PreparePropertysEventArgs e) {
+        super.onPreparePropertys(e);
+        e.getFieldKeys().add("nckd_importtask.id");
+    }
+
+    @Override
+    public void endOperationTransaction(EndOperationTransactionArgs e) {
+        super.endOperationTransaction(e);
+        String opKey = e.getOperationKey();
+        switch(opKey) {
+            case "delete":
+                doAfterDelete(e);
+                break;
+        }
+    }
+
+    /**
+     * 删除成功后反写任务的导入数量
+     * @param e
+     */
+    public void doAfterDelete(EndOperationTransactionArgs e) {
+        DynamicObject[] temporaryDatas = e.getDataEntities();
+        Set<Long> importTaskIdSet = (Set) Arrays.stream(temporaryDatas).map((temporaryData) -> {
+            return temporaryData.getLong("nckd_importtask.id");
+        }).collect(Collectors.toSet());
+        Iterator it = importTaskIdSet.iterator();
+
+        while(it.hasNext()) {
+            Long importTaskId = (Long)it.next();
+            OutImportTaskUtils.updateImportTaskStatus(importTaskId);
+        }
+    }
+}