Bläddra i källkod

Merge remote-tracking branch 'origin/master'

jtd 5 dagar sedan
förälder
incheckning
88d1908196

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

@@ -121,6 +121,8 @@ public class FormConstant {
     public static final String HSBS_CALFREQUENCY = "hsbs_calfrequency";
     /** 考核结果实体标识 */
     public static final String NCKD_APPRAISALRESULT = "nckd_appraisalresult";
+    /** 政策公告实体标识 */
+    public static final String NCKD_ANNOUNCEMENTS = "nckd_announcements";
     /**
      * 定调薪类型 默认值  用于  定调薪清单处理
      * */

+ 60 - 0
code/base/nckd-jxccl-base-common/src/main/java/nckd/jxccl/base/common/enums/ijp/TalentTypeEnum.java

@@ -0,0 +1,60 @@
+package nckd.jxccl.base.common.enums.ijp;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+* 【内部人力资源市场】-人员类别
+* @author W.Y.C
+* @date 2025/7/14 14:25
+* @version 1.0
+*/
+public enum TalentTypeEnum {
+
+    /*优秀员工	A
+    富余员工	B
+    绩效末等员工	C*/
+    /*优秀员工*/
+    EXCELLENT_EMPLOYEE("A", "优秀员工"),
+    /*富余员工*/
+    RICH_EMPLOYEE("B", "富余员工"),
+    /*绩效末等员工*/
+    PERFORMANCE_LAST_EMPLOYEE("C", "绩效末等员工");
+    private final String code;
+    private final String name;
+
+    TalentTypeEnum(String code, String name) {
+        this.code = code;
+        this.name = name;
+    }
+
+    private static final Map<String, TalentTypeEnum> CODE_MAP = new HashMap<>();
+
+    static {
+        for (TalentTypeEnum value : TalentTypeEnum.values()) {
+            CODE_MAP.put(value.code, value);
+        }
+    }
+
+    /**
+     * 根据编码获取枚举
+     * @param code 编码
+     * @return: nckd.jxccl.base.common.enums.AppraisalResultEnum
+     * @author W.Y.C
+     * @date: 2025/09/11 14:39
+     */
+    public static TalentTypeEnum getByCode(String code) {
+        if (code == null) {
+            return null;
+        }
+        return CODE_MAP.get(code);
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+    public String getName() {
+        return name;
+    }
+}

+ 11 - 0
code/base/nckd-jxccl-base-common/src/main/java/nckd/jxccl/base/common/utils/DateUtil.java

@@ -156,6 +156,17 @@ public class DateUtil {
         return dateTime.plusYears(years);
     }
 
+    /**
+     * 加年
+     *
+     * @param date 原始日期时间
+     * @param years    要加的年数(可为负数)
+     * @return 计算后的日期时间
+     */
+    public static Date addYears(Date date, int years) {
+        return toDate(addYears(toLocalDateTime(date), years));
+    }
+
     /**
      * 减年
      *

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

@@ -244,7 +244,7 @@ public class SWCHelper {
         QFilter filter = new QFilter("iscurrentdata", QCP.equals, "1"); // 启用
         filter.and(new QFilter("employee.id", QCP.in, employeeId));
 
-        String selectFields1 = "employee.id,adminorg.id,adminorg.belongcompany.id";
+        String selectFields1 = "employee.id,adminorg.id,adminorg.belongcompany.id,company.id";
         DynamicObject[] empposorgreDyns = BusinessDataServiceHelper.load("hrpi_empposorgrel", selectFields1, filter.toArray());
 
         return empposorgreDyns;

+ 58 - 0
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/ijp/common/IntJobPostConstant.java

@@ -32,4 +32,62 @@ public class IntJobPostConstant extends FormConstant {
     public static final String NCKD_ISJOG = "nckd_isjog";
     /** 获取员工 */
     public static final String FETCHEMP_OP = "fetchemp";
+
+
+
+
+    /** 市场管理-实体标识 */
+    public static final String INTJOBPOSTRECORD_ENTITYID = "nckd_intjobpostrecord";
+    /** 员工状态 */
+    public static final String NCKD_STATE = "nckd_state";
+    /** 进入市场时间 */
+    public static final String NCKD_BEGINDATE = "nckd_begindate";
+    /** 转待岗培训时间 */
+    public static final String NCKD_TOTWODATE = "nckd_totwodate";
+    /** 转待岗时间 */
+    public static final String NCKD_TOTHREEDATE = "nckd_tothreedate";
+    /** 退出市场时间 */
+    public static final String NCKD_TOFOURDATE = "nckd_tofourdate";
+    /** 预计退出市场时间 */
+    public static final String NCKD_PREDICTTOFOURDATE = "nckd_predicttofourdate";
+    /** 三类人员记录分录 */
+    public static final String NCKD_INTJOBPOSTENTRY = "nckd_intjobpostentry";
+    /** 原退出市场时间 */
+    public static final String NCKD_OLDTOFOURDATE = "nckd_oldtofourdate";
+    /** 退出市场原因 */
+    public static final String NCKD_BACKUP = "nckd_backup";
+    /** 员工状态 */
+    public static final String NCKD_OLDSTATE = "nckd_oldstate";
+    /** 操作来源 */
+    public static final String NCKD_HOWFROM = "nckd_howfrom";
+    /** 竞聘时间 */
+    public static final String NCKD_COMPDATE = "nckd_compdate";
+
+
+    /** 内部人力资源市场变动记录-实体标识 */
+    public static final String INTJOBPOSTLOCUS_ENTITYID = "nckd_intjobpostlocus";
+    /** 开始时间 */
+    public static final String NCKD_STARTDATE = "nckd_startdate";
+    /** 结束时间 */
+    public static final String NCKD_ENDDATE = "nckd_enddate";
+    /** 内部人力资源市场记录 */
+    public static final String NCKD_INTJOBPOSTRECORD = "nckd_intjobpostrecord";
+    /** 原结束时间 */
+    public static final String NCKD_OLDENDDAY = "nckd_oldendday";
+    /** 历史退出市场时间 */
+    public static final String NCKD_HISTOFOURDATE = "nckd_histofourdate";
+    /** 历史转待岗时间 */
+    public static final String NCKD_HISTOTHREEDATE = "nckd_histothreedate";
+    /** 历史转待岗培训时间 */
+    public static final String NCKD_HISTOTWODATE = "nckd_histotwodate";
+    /** 员工类别 */
+    public static final String NCKD_HISTALENTTYPE = "nckd_histalenttype";
+    /** 员工状态 */
+    public static final String NCKD_HISSTATE = "nckd_hisstate";
+    /** 历史退出市场原因 */
+    public static final String NCKD_HISBACKUP = "nckd_hisbackup";
+    /** 部门(冗余) */
+    public static final String NCKD_ADMINORG = "nckd_adminorg";
+    /** 是否最新记录(人员) */
+    public static final String NCKD_ISCURRENTNEWEST = "nckd_iscurrentnewest";
 }

+ 233 - 1
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/ijp/plugin/operate/IntJobPostAuditedOpPlugin.java

@@ -1,11 +1,42 @@
 package nckd.jxccl.hr.ijp.plugin.operate;
 
+import kd.bos.context.RequestContext;
+import kd.bos.dataentity.OperateOption;
 import kd.bos.dataentity.entity.DynamicObject;
 import kd.bos.dataentity.entity.DynamicObjectCollection;
+import kd.bos.entity.EntityMetadataCache;
+import kd.bos.entity.ExtendedDataEntity;
+import kd.bos.entity.MainEntityType;
+import kd.bos.entity.operate.result.OperationResult;
 import kd.bos.entity.plugin.AbstractOperationServicePlugIn;
+import kd.bos.entity.plugin.AddValidatorsEventArgs;
 import kd.bos.entity.plugin.args.BeginOperationTransactionArgs;
+import kd.bos.entity.validate.AbstractValidator;
+import kd.bos.orm.query.QCP;
+import kd.bos.orm.query.QFilter;
+import kd.bos.servicehelper.BusinessDataServiceHelper;
+import kd.bos.servicehelper.QueryServiceHelper;
+import kd.bos.servicehelper.operation.SaveServiceHelper;
 import kd.sdk.plugin.Plugin;
 import nckd.jxccl.base.common.constant.FormConstant;
+import nckd.jxccl.base.common.enums.ijp.TalentTypeEnum;
+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.hrpi.helper.EmpPosOrgRelHelper;
+import nckd.jxccl.hr.ijp.common.IntJobPostConstant;
+import nckd.jxccl.hr.psms.common.PositionStructureConstant;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
 
 /**
 * 内部人力资源市场-三类人员记录生成-审批通过
@@ -16,12 +47,151 @@ import nckd.jxccl.base.common.constant.FormConstant;
 */
 public class IntJobPostAuditedOpPlugin extends AbstractOperationServicePlugIn implements Plugin {
 
+    @Override
+    public void onAddValidators(AddValidatorsEventArgs e) {
+        e.addValidator(new AbstractValidator(){
+            @Override
+            public void validate() {
+                List<Long> personIds = new ArrayList<>();
+                for (ExtendedDataEntity rowDataEntity : getDataEntities()) {
+                    DynamicObject data = rowDataEntity.getDataEntity();
+                    DynamicObject person = data.getDynamicObject(PositionStructureConstant.NCKD_PERSON);
+                    if(person == null){
+                        this.addFatalErrorMessage(rowDataEntity,"请选择人员");
+                    }else{
+                        long personId = person.getLong(FormConstant.ID_KEY);
+                        personIds.add(personId);
+                    }
+                }
+                Map<Long, DynamicObject> empPosOrgRelMap = EmpPosOrgRelHelper.queryEmpPosOrgRelByEmployeesMap(personIds);
+                for (ExtendedDataEntity rowDataEntity : getDataEntities()) {
+                    DynamicObject data = rowDataEntity.getDataEntity();
+                    DynamicObject person = data.getDynamicObject(PositionStructureConstant.NCKD_PERSON);
+                    if(person != null){
+                        long personId = person.getLong(FormConstant.ID_KEY);
+                        if(empPosOrgRelMap.get(personId) == null){
+                            this.addFatalErrorMessage(rowDataEntity,StrFormatter.format("人员【{}】没有在岗状态的任职经历",person.getString(FormConstant.NAME_KEY)));
+                        }
+                    }
+                }
+            }
+        });
+    }
+
     @Override
     public void beginOperationTransaction(BeginOperationTransactionArgs e) {
 
+        List<Long> personIds = new ArrayList<>();
+        List<Long> entityIds = new ArrayList<>();
+        for (DynamicObject dataEntity : e.getDataEntities()) {
+            DynamicObjectCollection entryEntity = dataEntity.getDynamicObjectCollection(FormConstant.NCKD_ENTRYENTITY);
+            for (DynamicObject entry : entryEntity) {
+                boolean isEnter = entry.getBoolean(IntJobPostConstant.NCKD_ISENTER);
+                if(isEnter){
+                    personIds.add(entry.getLong(IntJobPostConstant.NCKD_PERSON));
+                }
+                entityIds.add(entry.getLong(IntJobPostConstant.ID_KEY));
+            }
+        }
+        Map<Long, DynamicObject> empPosOrgRelMap = EmpPosOrgRelHelper.queryEmpPosOrgRelByEmployeesMap(personIds);
+
+        // --- A. 处理旧记录 ---
+        // 1. 查询该员工最近的一条记录(排除当前单据产生的记录,按创建时间倒序取第一条)
+        long currUserId = RequestContext.get().getCurrUserId();
+        List<DynamicObject> savedRecords = new ArrayList<>();
+        //由于轨迹需要关联本次新增的记录,需要等记录保存成功后再set内部人力资源市场记录。 以分录id作为key,记录待新增的轨迹。
+        Map<Long, DynamicObject> savedLocusMap = new HashMap<>();
+        List<DynamicObject> savedLocus = new ArrayList<>();
+        Map<Long, DynamicObject> latestRecordMap = getLatestRecordIdsByPersons(personIds, entityIds);
+        Map<Long, DynamicObject> latestLocusMap = findLatestLocusByPerson(personIds);
         for (DynamicObject dataEntity : e.getDataEntities()) {
-            DynamicObjectCollection dynamicObjectCollection = dataEntity.getDynamicObjectCollection(FormConstant.NCKD_ENTRYENTITY);
+            Date auditDate = dataEntity.getDate(IntJobPostConstant.AUDIT_DATE_KEY);
+            long personId = dataEntity.getLong(String.join(".", IntJobPostConstant.NCKD_PERSON, IntJobPostConstant.ID_KEY));
+            String talentType = dataEntity.getString(IntJobPostConstant.NCKD_TALENTTYPE);
+            TalentTypeEnum talentTypeEnum = TalentTypeEnum.getByCode(talentType);
+            DynamicObjectCollection entryEntity = dataEntity.getDynamicObjectCollection(FormConstant.NCKD_ENTRYENTITY);
+
+            for (DynamicObject entry : entryEntity) {
+                long id = entry.getLong(IntJobPostConstant.ID_KEY);
+                boolean isEnter = entry.getBoolean(IntJobPostConstant.NCKD_ISENTER);
+                if(isEnter){
+                    DynamicObject latestRecord = latestRecordMap.get(personId);
+                    if(latestRecord != null) {
+                        // 2. 备份旧值
+                        latestRecord.set(IntJobPostConstant.NCKD_OLDTOFOURDATE, latestRecord.get(IntJobPostConstant.NCKD_TOFOURDATE));
+                        latestRecord.set(IntJobPostConstant.NCKD_OLDSTATE, latestRecord.get(IntJobPostConstant.NCKD_STATE));
+                        //退出市场时间
+                        latestRecord.set(IntJobPostConstant.NCKD_TOFOURDATE, auditDate);
+                        //标记上一条为退出市场
+                        latestRecord.set(IntJobPostConstant.NCKD_STATE, "4");
+                        latestRecord.set(IntJobPostConstant.NCKD_ISCURRENTNEWEST, Boolean.FALSE);
+                        latestRecord.set(IntJobPostConstant.NCKD_BACKUP, StrFormatter.format("以【{}】身份新进入市场,退出原市场。",talentTypeEnum.getName()));
+                        savedRecords.add(latestRecord);
+                    }
+
+                    // --- B. 插入新记录 ---
+                    DynamicObject newRecord = EntityHelper.newEntity(IntJobPostConstant.INTJOBPOSTRECORD_ENTITYID);
+                    DynamicObject empPosOrgRel = empPosOrgRelMap.get(personId);
+                    newRecord.set(IntJobPostConstant.HRPI_EMPPOSORGREL, empPosOrgRel);
+                    newRecord.set(IntJobPostConstant.NCKD_ADMINORG,empPosOrgRel.get(IntJobPostConstant.ADMINORG));
+                    newRecord.set(IntJobPostConstant.NCKD_ISCURRENTNEWEST, Boolean.TRUE);
+                    //初始状态:进入市场
+                    newRecord.set(IntJobPostConstant.NCKD_STATE,"1");
+                    newRecord.set(IntJobPostConstant.NCKD_TALENTTYPE,dataEntity.get(IntJobPostConstant.NCKD_TALENTTYPE));
+                    newRecord.set(IntJobPostConstant.NCKD_BEGINDATE,dataEntity.get(IntJobPostConstant.NCKD_BIZDAY));
+                    newRecord.set(IntJobPostConstant.NCKD_YEAR,dataEntity.get(IntJobPostConstant.NCKD_YEAR));
+                    //分录
+                    newRecord.set(IntJobPostConstant.NCKD_INTJOBPOSTENTRY,latestRecord);
+                    newRecord.set(IntJobPostConstant.NCKD_APPRAISALRESULT,entry.get(IntJobPostConstant.NCKD_APPRAISALRESULT));
+                    newRecord.set(IntJobPostConstant.NCKD_BEFORELAST,entry.get(IntJobPostConstant.NCKD_BEFORELAST));
+                    newRecord.set(FormConstant.CREATOR_KEY,currUserId);
+                    if ("A".equals(dataEntity.getString(IntJobPostConstant.NCKD_TALENTTYPE))) {
+                        //优秀员工-预计退出时间
+                        Date date = DateUtil.addYears(auditDate, 1);
+                        newRecord.set(IntJobPostConstant.NCKD_PREDICTTOFOURDATE, date);
+                    }
+                    savedRecords.add(newRecord);
+
+                    // --- C. 处理轨迹 (Locus) ---
+                    // 1. 查询最近的轨迹
+                    DynamicObject latestLocus = latestLocusMap.get(personId);
+                    if(latestLocus != null){
+                        latestLocus.set(IntJobPostConstant.NCKD_OLDENDDAY, latestLocus.get(IntJobPostConstant.ENDDATE));
+                        latestLocus.set(IntJobPostConstant.ENDDATE, auditDate);
+                        latestLocus.set(IntJobPostConstant.NCKD_ISCURRENTNEWEST, Boolean.FALSE);
+                        savedLocus.add(latestLocus);
+                    }
+                    // 2. 插入新轨迹
+                    DynamicObject newLocus = EntityHelper.newEntity(IntJobPostConstant.INTJOBPOSTLOCUS_ENTITYID);
+                    newLocus.set(IntJobPostConstant.HRPI_EMPPOSORGREL, empPosOrgRel);
+                    newLocus.set(IntJobPostConstant.NCKD_ADMINORG,empPosOrgRel.get(IntJobPostConstant.ADMINORG));
+                    newLocus.set(IntJobPostConstant.NCKD_ISCURRENTNEWEST, Boolean.TRUE);
+                    newLocus.set(IntJobPostConstant.NCKD_INTJOBPOSTRECORD, newRecord);
+                    newLocus.set(IntJobPostConstant.NCKD_STARTDATE, dataEntity.get(IntJobPostConstant.NCKD_BIZDAY));
+                    newLocus.set(IntJobPostConstant.NCKD_TALENTTYPE, dataEntity.get(IntJobPostConstant.NCKD_TALENTTYPE));
+                    newLocus.set(IntJobPostConstant.NCKD_STATE, "1");
+                    newLocus.set(FormConstant.CREATOR_KEY,currUserId);
+                    savedLocusMap.put(id, newLocus);
+                }
+            }
+        }
+        if(!savedRecords.isEmpty()){
+            OperationResult operationResult = SaveServiceHelper.saveOperate(IntJobPostConstant.INTJOBPOSTRECORD_ENTITYID, savedRecords.toArray(new DynamicObject[0]), OperateOption.create());
+            if(operationResult.isSuccess()){
+                //新增实体
+//                OperationResult operationResult = SaveServiceHelper.saveOperate(IntJobPostConstant.INTJOBPOSTLOCUS_ENTITYID, savedRecords.toArray(new DynamicObject[0]), OperateOption.create());
+            }
+
         }
+
+
+
+
+
+        // --- A. 处理旧记录 ---
+        // 1. 查询该员工最近的一条记录(排除当前单据产生的记录,按创建时间倒序取第一条)
+
+
         //1、阶段1:备份原有记录
         // 条件:单据中要进入市场(CFIsenter=1)的员工 + 他们最新的记录 + 记录来源不是当前单据
         //目的:为反审批时恢复数据做准备
@@ -37,7 +207,69 @@ public class IntJobPostAuditedOpPlugin extends AbstractOperationServicePlugIn im
         //A类员工:有预计退出时间(1年后)
         //非A类员工:预计退出时间为null
 
+    }
 
+    /**
+     * 获取每个人员最新一条记录
+     * @param personIds 人员ID
+     * @param entityIds 分录ID
+     * @return: java.util.Map<java.lang.Long, java.util.List < kd.bos.dataentity.entity.DynamicObject>>
+     * @author W.Y.C
+     * @date: 2026/01/13 15:56
+     */
+    public Map<Long, DynamicObject> getLatestRecordIdsByPersons(List<Long> personIds,List<Long> entityIds) {
+        QueryFieldBuilder intJobPostRecord = QueryFieldBuilder.create().add(IntJobPostConstant.ID_KEY)
+                .add(FormConstant.NCKD_EMPPOSORGREL, FormConstant.EMPLOYEE_KEY,FormConstant.ID_KEY)
+                .add(IntJobPostConstant.NCKD_ISCURRENTNEWEST)
+                .orderDesc(IntJobPostConstant.CREATE_TIME_KEY);
+        QFilter filter = new QFilter(String.join(".",FormConstant.NCKD_EMPPOSORGREL, FormConstant.EMPLOYEE_KEY, FormConstant.ID_KEY), QCP.in, personIds)
+                .and(IntJobPostConstant.NCKD_INTJOBPOSTENTRY,QCP.not_in,entityIds);
+        DynamicObjectCollection records = QueryServiceHelper.query(IntJobPostConstant.INTJOBPOSTRECORD_ENTITYID, intJobPostRecord.buildSelect(), new QFilter[]{filter});
+        Set<Long> uniquePersonIds = new HashSet<>();
+        List<Long> result = new ArrayList<>();
+        for (DynamicObject record : records) {
+            Long personId = record.getLong(String.join(".",FormConstant.NCKD_EMPPOSORGREL, FormConstant.EMPLOYEE_KEY, FormConstant.ID_KEY));
+            if (uniquePersonIds.add(personId)) { // 如果是新的personId,添加到结果中
+                result.add(record.getLong(IntJobPostConstant.ID_KEY));
+            }
+        }
+        MainEntityType intJobPostRecordEntityType = EntityMetadataCache.getDataEntityType(IntJobPostConstant.INTJOBPOSTRECORD_ENTITYID);
+        DynamicObject[] load = BusinessDataServiceHelper.load(result.toArray(new Long[0]), intJobPostRecordEntityType);
+        return Arrays.stream(load)
+                .collect(Collectors.toMap(
+                        obj -> obj.getLong(String.join(".", FormConstant.NCKD_EMPPOSORGREL, FormConstant.EMPLOYEE_KEY, FormConstant.ID_KEY)),
+                        obj -> obj
+                ));
+    }
 
+    /**
+     * 查询最近的轨迹
+     * @param personIds 人员ID
+     * @return: java.util.Map<java.lang.Long, java.util.List < kd.bos.dataentity.entity.DynamicObject>>
+     * @author W.Y.C
+     * @date: 2026/01/13 15:56
+     */
+    public Map<Long, DynamicObject> findLatestLocusByPerson(List<Long> personIds) {
+        QueryFieldBuilder intJobPostLocus = QueryFieldBuilder.create().add(IntJobPostConstant.ID_KEY)
+                .add(FormConstant.NCKD_EMPPOSORGREL, FormConstant.EMPLOYEE_KEY,FormConstant.ID_KEY)
+                .add(IntJobPostConstant.NCKD_ISCURRENTNEWEST)
+                .orderDesc(IntJobPostConstant.CREATE_TIME_KEY);
+        QFilter filter = new QFilter(String.join(".",FormConstant.NCKD_EMPPOSORGREL, FormConstant.EMPLOYEE_KEY, FormConstant.ID_KEY), QCP.in, personIds);
+        DynamicObjectCollection records = QueryServiceHelper.query(IntJobPostConstant.INTJOBPOSTLOCUS_ENTITYID, intJobPostLocus.buildSelect(), new QFilter[]{filter});
+        Set<Long> uniquePersonIds = new HashSet<>();
+        List<Long> result = new ArrayList<>();
+        for (DynamicObject record : records) {
+            Long personId = record.getLong(String.join(".",FormConstant.NCKD_EMPPOSORGREL, FormConstant.EMPLOYEE_KEY, FormConstant.ID_KEY));
+            if (uniquePersonIds.add(personId)) { // 如果是新的personId,添加到结果中
+                result.add(record.getLong(IntJobPostConstant.ID_KEY));
+            }
+        }
+        MainEntityType intJobPostLocusEntityType = EntityMetadataCache.getDataEntityType(IntJobPostConstant.INTJOBPOSTLOCUS_ENTITYID);
+        DynamicObject[] load = BusinessDataServiceHelper.load(result.toArray(new Long[0]), intJobPostLocusEntityType);
+        return Arrays.stream(load)
+                .collect(Collectors.toMap(
+                        obj -> obj.getLong(String.join(".",FormConstant.NCKD_EMPPOSORGREL, FormConstant.EMPLOYEE_KEY, FormConstant.ID_KEY)),
+                        obj -> obj
+                ));
     }
 }

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

@@ -17,7 +17,6 @@ import kd.bos.form.MessageBoxResult;
 import kd.sdk.plugin.Plugin;
 import nckd.jxccl.base.common.constant.FormConstant;
 import nckd.jxccl.base.common.enums.psms.ScoreItemEnum;
-import nckd.jxccl.base.common.utils.ConvertUtil;
 import nckd.jxccl.base.common.utils.StrFormatter;
 import nckd.jxccl.hr.psms.common.ContributionConstant;
 import nckd.jxccl.hr.psms.helper.ContributionHelper;
@@ -25,11 +24,8 @@ import org.apache.commons.lang3.StringUtils;
 
 import java.math.BigDecimal;
 import java.math.RoundingMode;
-import java.util.ArrayList;
 import java.util.Date;
-import java.util.List;
 import java.util.Map;
-import java.util.Objects;
 
 /**
  * 年度积分贡献单据保存/提交插件

+ 68 - 0
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/tsc/plugin/form/AnnouncementsBasePlugin.java

@@ -0,0 +1,68 @@
+package nckd.jxccl.hr.tsc.plugin.form;
+
+import kd.bos.dataentity.entity.DynamicObject;
+import kd.bos.entity.datamodel.events.BizDataEventArgs;
+import kd.bos.form.events.BeforeDoOperationEventArgs;
+import kd.bos.form.operate.FormOperate;
+import kd.bos.servicehelper.user.UserServiceHelper;
+import kd.hr.hbp.business.servicehelper.HRBaseServiceHelper;
+import kd.sdk.plugin.Plugin;
+import kd.hr.hbp.formplugin.web.template.HRBaseDataTplEdit;
+import nckd.jxccl.base.common.constant.FormConstant;
+import nckd.jxccl.base.swc.helper.SWCHelper;
+import java.util.List;
+
+/**
+ * 政策公告插件
+ * @author turborao
+ * 时间 2026/1/13 16:05
+ */
+public class AnnouncementsBasePlugin extends HRBaseDataTplEdit implements Plugin {
+
+    @Override
+    public void createNewData(BizDataEventArgs e) {
+        super.createNewData(e);
+
+        Long userId = UserServiceHelper.getCurrentUserId();
+
+        DynamicObject personUserDyn = SWCHelper.queryOne(FormConstant.HRPI_PERSONUSERREL, "employee.id","user",userId);
+
+        Long empId = 0L;
+        if(personUserDyn == null){
+            /**
+             * 没有员工信息时,返回常量,用于测试
+             */
+            //KEY_EMPID = 2313784485549715456L;
+            this.getView().showMessage("未找到员工!");
+            return;
+        }else {
+            empId = personUserDyn.getLong("employee.id");
+        }
+        List<Long> employeeIds = new java.util.ArrayList<>();
+        employeeIds.add(empId);
+        DynamicObject[] empDyns = SWCHelper.queryEmpPosOrgRelDyns(employeeIds);
+        if(empDyns != null && empDyns.length > 0){
+            Long companyId = empDyns[0].getLong("company.id");
+            this.getModel().setValue("nckd_hradminorg", companyId);
+        }
+
+    }
+
+    @Override
+    public void beforeDoOperation(BeforeDoOperationEventArgs args) {
+        FormOperate source = (FormOperate)args.getSource();
+        String formOp = source.getOperateKey();
+        DynamicObject data = this.getModel().getDataEntity();
+        HRBaseServiceHelper hrBaseServiceHelper = new HRBaseServiceHelper(FormConstant.NCKD_ANNOUNCEMENTS);
+        if ("publish".equals(formOp)) {
+            data.set("nckd_billstatus", "C");
+            data.set("nckd_publishdate", new java.util.Date());
+            data.set("nckd_publishuser", UserServiceHelper.getCurrentUserId());
+            Object billPk = hrBaseServiceHelper.saveOne(data);
+        }
+        if("withdraw".equals(formOp)){
+            data.set("nckd_billstatus", "A");
+            Object billPk = hrBaseServiceHelper.saveOne(data);
+        }
+    }
+}

+ 270 - 20
code/opmc/nckd-jxccl-opmc/src/main/java/nckd/jxccl/opmc/pm/plugin/form/ExaminProjectResultListPlugin.java

@@ -2,22 +2,66 @@ package nckd.jxccl.opmc.pm.plugin.form;
 
 import kd.bos.dataentity.entity.DynamicObject;
 import kd.bos.dataentity.entity.DynamicObjectCollection;
-import kd.bos.entity.datamodel.events.PackageDataEvent;
+import kd.bos.dataentity.entity.LocaleString;
+import kd.bos.dataentity.metadata.dynamicobject.DynamicObjectType;
+import kd.bos.dataentity.metadata.dynamicobject.DynamicSimpleProperty;
+import kd.bos.dataentity.resource.ResManager;
+import kd.bos.dataentity.serialization.SerializationUtils;
+import kd.bos.entity.EntityMetadataCache;
+import kd.bos.entity.EntityType;
+import kd.bos.entity.MainEntityType;
+import kd.bos.entity.datamodel.ListField;
+import kd.bos.entity.datamodel.events.GetEntityTypeEventArgs;
+import kd.bos.entity.property.DateProp;
+import kd.bos.entity.property.TextProp;
+import kd.bos.exception.ErrorCode;
+import kd.bos.exception.KDBizException;
+import kd.bos.exception.KDException;
 import kd.bos.form.CloseCallBack;
 import kd.bos.form.FormShowParameter;
 import kd.bos.form.ShowType;
+import kd.bos.form.container.Container;
+import kd.bos.form.control.Control;
 import kd.bos.form.events.BeforeCreateListColumnsArgs;
+import kd.bos.form.events.BeforeCreateListDataProviderArgs;
 import kd.bos.form.events.BeforeDoOperationEventArgs;
 import kd.bos.form.events.ClosedCallBackEvent;
+import kd.bos.form.events.OnGetControlArgs;
 import kd.bos.form.operate.FormOperate;
+import kd.bos.list.DynamicTextListColumn;
+import kd.bos.list.IListColumn;
 import kd.bos.list.ListColumn;
 import kd.bos.list.plugin.AbstractListPlugin;
+import kd.bos.logging.Log;
+import kd.bos.logging.LogFactory;
+import kd.bos.mvc.list.ListDataProvider;
+import kd.bos.mvc.list.ListView;
 import kd.bos.orm.query.QCP;
 import kd.bos.orm.query.QFilter;
 import kd.bos.servicehelper.BusinessDataServiceHelper;
-import org.apache.commons.lang3.ObjectUtils;
+import kd.hr.hbp.business.servicehelper.HRBaseServiceHelper;
+import kd.hr.hbp.common.cache.HRAppCache;
+import kd.hr.hbp.common.cache.IHRAppCache;
+import nckd.jxccl.base.common.utils.DateTimeUtils;
+import nckd.jxccl.base.swc.helper.SWCHelper;
+import nckd.jxccl.opmc.pm.helper.PerfManagerHelper;
+import org.apache.commons.lang.exception.ExceptionUtils;
 import org.apache.commons.lang3.StringUtils;
 
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.text.ParseException;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import java.util.stream.Collectors;
+
 /**
  * @ClassName: ExaminProjectResultListPlugin
  * @Description: 绩效结果列表插件
@@ -26,9 +70,12 @@ import org.apache.commons.lang3.StringUtils;
  * @Version: 1.0
  */
 public class ExaminProjectResultListPlugin extends AbstractListPlugin {
+//    private ExaminProjectResultBillList billList;
+    private static final Log logger = LogFactory.getLog(ExaminProjectResultListPlugin.class);
+
     @Override
     public void beforeDoOperation(BeforeDoOperationEventArgs args) {
-            super.beforeDoOperation(args);
+        super.beforeDoOperation(args);
         FormOperate source = (FormOperate) args.getSource();
         String operateKey = source.getOperateKey();
         if (StringUtils.equals(operateKey, "import")) {
@@ -48,34 +95,237 @@ public class ExaminProjectResultListPlugin extends AbstractListPlugin {
     public void closedCallBack(ClosedCallBackEvent e) {
         super.closedCallBack(e);
         String actionId = e.getActionId();
-        if( StringUtils.equals(actionId, "importData") ){
-            Object returnData = e.getReturnData();
-            if( ObjectUtils.isNotEmpty(returnData) ){
+//        if (StringUtils.equals(actionId, "importData")) {
+//            Object returnData = e.getReturnData();
+//            if (ObjectUtils.isNotEmpty(returnData)) {
+//                this.getView().invokeOperation("refresh");
+//            }
+//        }
+
+
+        Map returnData;
+        if ("importData".equals(actionId)) {
+            returnData = (Map) e.getReturnData();
+            if (returnData == null) {
+                return;
+            }
+            if ((Boolean) returnData.get("isOk")) {
+                int totalCount = Integer.parseInt(returnData.get("totalCount").toString());
+                Long importTaskId = (Long) returnData.get("importTaskId");
+                String cacheKey = (String) returnData.get("cacheKey");
+                String caption = ResManager.loadKDString("导入看板", "ImportTaskGuideOpereateBillList_33", "swc-hsas-formplugin", new Object[0]);
+                this.openProgressPage(totalCount, importTaskId, "22", "importingData", caption, cacheKey);
+            }
+        } else if ("importingData".equals(actionId)) {
+            returnData = (Map) e.getReturnData();
+            if (returnData != null && !returnData.isEmpty()) {
+                this.openImportingView(returnData);
+            } else {
                 this.getView().invokeOperation("refresh");
             }
+        } else {
+            this.getView().invokeOperation("refresh");
         }
     }
 
+    private void openProgressPage(int totalCount, Long importTaskId, String progressType, String closeCalBackId, String caption, String verifyId) {
+        FormShowParameter formShowParameter = new FormShowParameter();
+        formShowParameter.setFormId("hsas_datacheckprogress");
+        formShowParameter.getOpenStyle().setShowType(ShowType.Modal);
+        formShowParameter.setCaption(caption);
+        formShowParameter.setCustomParam("importTaskId", importTaskId);
+        formShowParameter.setCustomParam("totalCount", totalCount);
+        formShowParameter.setCustomParam("verifyId", verifyId);
+        formShowParameter.setCustomParam("startTime", DateTimeUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss"));
+        formShowParameter.setCustomParam("progressType", progressType);
+        formShowParameter.setCloseCallBack(new CloseCallBack(this, closeCalBackId));
+        this.getView().showForm(formShowParameter);
+    }
+
+    private void openImportingView(Map<String, Object> dataMap) {
+        FormShowParameter formShowParameter = new FormShowParameter();
+        formShowParameter.setFormId("hsas_taskguideimportret");
+        formShowParameter.getOpenStyle().setShowType(ShowType.Modal);
+        formShowParameter.setCustomParam("importTaskId", dataMap.get("importTaskId"));
+        formShowParameter.setCustomParam("successCout", dataMap.get("successCout"));
+        formShowParameter.setCustomParam("failCout", dataMap.get("failCout"));
+        formShowParameter.setCustomParam("cacheKey", dataMap.get("cacheKey"));
+        formShowParameter.setCloseCallBack(new CloseCallBack(this, "importErrorData"));
+        this.getView().showForm(formShowParameter);
+    }
+
+    /**
+     * 创建列表列前触发
+     *
+     * @param args 创建列表前事件参数 {@link BeforeCreateListColumnsArgs}
+     */
     @Override
     public void beforeCreateListColumns(BeforeCreateListColumnsArgs args) {
         super.beforeCreateListColumns(args);
-        //添加动态列
-        FormShowParameter formShowParameter = this.getView().getFormShowParameter();
-        Object customParam = formShowParameter.getCustomParam("");
-        DynamicObject dynamicObject = BusinessDataServiceHelper.loadSingle("", "", new QFilter[]{new QFilter("", QCP.equals, customParam)});
-        DynamicObjectCollection dynamicObjectCollection = dynamicObject.getDynamicObjectCollection("");
-        for (DynamicObject object : dynamicObjectCollection) {
-//            DynamicObject dynamicObject1 = object.getDynamicObject("");
-//            dynamicObject1.getString("");
-//            ListColumn listColumn = new ListColumn();
-//            listColumn.setListFieldKey("nckd_kpi_select");
-//            listColumn.set
+        // 获取设计器预置的列集合
+        List<IListColumn> columns = args.getListColumns();
+        int seq = 6;
+        Long templateId = this.getView().getFormShowParameter().getCustomParam("template");
+        // 添加考勤项目列表字段
+        DynamicObjectCollection dynamicObjects = queryData(templateId);
+        for (DynamicObject obj : dynamicObjects) {
+            DynamicObject item = obj.getDynamicObject("nckd_examine_dimension");
+            String number = item.getString("number");
+            if (StringUtils.equalsAny(number, "JT-00001", "JT-00002", "JT-00003", "JT-00004", "JT-00005", "JT-00006", "JT-00007", "JT-00018")) {
+                continue;
+            }
+            columns.add(seq++, createListColumn(getItemPropKey(item), item.getString("name"), columns.get(0)));
+        }
+    }
+
+    private String getItemPropKey(DynamicObject item) {
+        return item.getString("number").toLowerCase();
+    }
+
+    /**
+     * 创建列对象返回
+     *
+     * @param columnKey   新列映射的单据字段
+     * @param columnName  新列列名
+     * @param firstColumn 新列的父容器
+     * @return
+     */
+    private ListColumn createListColumn(String columnKey, String columnName, IListColumn firstColumn) {
+        ListColumn col = new ListColumn();
+        // 设置映射字段
+        col.setListFieldKey(columnKey);
+        col.setKey(columnKey);
+        col.setCaption(new LocaleString(columnName));
+        col.setParent(firstColumn.getParent());
+        col.setParentViewKey(firstColumn.getParent().getKey());
+        col.setSeq(2);
+        col.setVisible(11);
+        return col;
+    }
+
+
+    @Override
+    public void billListGetEntityType(GetEntityTypeEventArgs args) {
+        super.billListGetEntityType(args);
+        // 取原始的主实体
+        MainEntityType oldMainType = args.getOriginalEntityType();
+        // 复制主实体 单例对象不允许修改
+        MainEntityType newMainType = null;
+        try {
+            newMainType = (MainEntityType) oldMainType.clone();
+        } catch (CloneNotSupportedException exp) {
+            throw new KDException(exp, new ErrorCode("ExaminProjectResultListPlugin", exp.getMessage()));
+        }
+        // 为自定义的文本字段,向主实体注册文本属性
+        this.registDynamicProps(newMainType);
+        // 回传主实体给系统
+        args.setNewEntityType(newMainType);
+    }
+
+
+    /**
+     * 向主实体注册动态添加的属性
+     */
+    private void registDynamicProps(MainEntityType newMainType) {
+        // 添加考勤项目列表字段
+        Long templateId = this.getView().getFormShowParameter().getCustomParam("template");
+        DynamicObjectCollection dynamicObjects = queryData(templateId);
+        for (DynamicObject obj : dynamicObjects) {
+            DynamicObject item = obj.getDynamicObject("nckd_examine_dimension");
+            // 向单据头动态注册一个新的文本属性
+            TextProp textProp = new TextProp();
+
+            textProp.setName(getItemPropKey(item)); // 标识
+            textProp.setDisplayName(new LocaleString(item.getString("name")));     // 标题
+
+            textProp.setDbIgnore(true);  // 此字段不需到物理表格取数
+//            textProp.setAlias("F" + getItemPropKey(item));           // 物理字段名
+
+            // 把新字段,注册到单据头
+            newMainType.registerSimpleProperty(textProp);
         }
     }
 
+    /**
+     * 查询导入模板数据
+     * @param template
+     * @return
+     */
+    public static DynamicObjectCollection queryData(Long template){
+        DynamicObject dynamicObject = BusinessDataServiceHelper.loadSingle("nckd_import_kpi_template", "id,number,name,nckd_outimptplentry.nckd_examine_dimension", new QFilter[]{new QFilter("id", QCP.equals, template)});
+        DynamicObjectCollection dynamicObjectCollection = dynamicObject.getDynamicObjectCollection("nckd_outimptplentry");
+        return dynamicObjectCollection;
+    }
+
     @Override
-    public void packageData(PackageDataEvent e) {
-        super.packageData(e);
-        //组装动态列数据
+    public void beforeCreateListDataProvider(BeforeCreateListDataProviderArgs args) {
+        super.beforeCreateListDataProvider(args);
+        FormShowParameter formShowParameter = this.getView().getFormShowParameter();
+        Long templateId = formShowParameter.getCustomParam("template");
+        Long importPlanId = formShowParameter.getCustomParam("importplan");
+        args.setListDataProvider(new ExaminProjectResultListPlugin.ImportItemDataResultImpl(templateId,importPlanId));
+    }
+
+    public class ImportItemDataResultImpl extends ListDataProvider {
+        private Long templateId;
+        private Long importPlanId;
+
+        public ImportItemDataResultImpl(Long templateId,Long importPlanId) {
+            this.templateId = templateId;
+            this.importPlanId = importPlanId;
+        }
+
+        @Override
+        public DynamicObjectCollection getData(int start, int limit) {
+            // 隐藏动态添加字段(数据库中查不到)
+            List<ListField> listFields = getListFields();
+            List<ListField> newListFields = listFields.stream().filter(e -> !e.getKey().contains("jt-")).collect(Collectors.toList());
+            setListFields(newListFields);
+
+            DynamicObjectCollection rows = super.getData(start, limit);
+            if (rows.isEmpty()) {
+                return rows;
+            }
+
+            // 添加考核维度列表字段
+            DynamicObjectCollection dynamicObjects = ExaminProjectResultListPlugin.this.queryData(templateId);
+
+            // 注册属性
+            DynamicObjectType dt = rows.getDynamicObjectType();
+            for (DynamicObject obj : dynamicObjects) {
+                DynamicObject item = obj.getDynamicObject("nckd_examine_dimension");
+                String number = item.getString("number");
+                if (StringUtils.equalsAny(number, "JT-00001", "JT-00002", "JT-00003", "JT-00004", "JT-00005", "JT-00006", "JT-00007", "JT-00018")) {
+                    continue;
+                }
+                DynamicSimpleProperty property = new DynamicSimpleProperty(ExaminProjectResultListPlugin.this.getItemPropKey(item), String.class, item.getString("name"));
+                dt.registerSimpleProperty(property);
+            }
+
+            DynamicObject[] load = BusinessDataServiceHelper.load("nckd_examinproject_result", "id,nckd_entryentity.nckd_examine_dimension,nckd_entryentity.nckd_result", new QFilter[]{new QFilter("nckd_importplan", QCP.equals, importPlanId)});
+
+            // 设置值
+            for (DynamicObject row : rows) {
+                for (DynamicObject dynamicObject : load) {
+                    long resultId = dynamicObject.getLong("id");
+                    long rowId = row.getLong("id");
+                    if( resultId == rowId ){
+                        DynamicObjectCollection entry = dynamicObject.getDynamicObjectCollection("nckd_entryentity");
+                        for (DynamicObject obj : entry) {
+                            DynamicObject item = obj.getDynamicObject("nckd_examine_dimension");
+                            String number = item.getString("number");
+                            if (StringUtils.equalsAny(number, "JT-00001", "JT-00002", "JT-00003", "JT-00004", "JT-00005", "JT-00006", "JT-00007", "JT-00018")) {
+                                continue;
+                            }
+                            row.set(number, obj.getString("nckd_result"));
+                        }
+                    }
+                }
+            }
+
+            // 设置可见(不设置,则上述注册字段默认不展示)
+            setVisibleSelectFieldList(listFields);
+            return rows;
+        }
     }
 }

+ 4 - 3
code/swc/nckd-jxccl-swc/src/main/java/nckd/jxccl/swc/mas/plugin/form/empmgt/SubCoHeadServiceListPlugin.java

@@ -371,9 +371,10 @@ public class SubCoHeadServiceListPlugin extends AbstractListPlugin implements Pl
                     }else{
                         newSubCoHeadService.set(MasConstant.NCKD_ENDDATE, DateUtil.getMaxDateAsDate());
                     }
-                    //【变动时间】的次月到当年年底的月数
-                    LocalDateTime newMonths = DateUtil.addMonths(DateUtil.toLocalDateTime(changeTime), 1);
-                    long between = DateUtil.between(newMonths, endYear, ChronoUnit.MONTHS);
+                    //【变动时间】的次月到当年年底的月数(ChronoUnit.MONTHS是从0开始的,所以不用加月份)
+//                    LocalDateTime newMonths = DateUtil.addMonths(DateUtil.toLocalDateTime(changeTime), 1);
+                    Date endChangeTime = DateUtil.endOfYear(changeTime);
+                    long between = DateUtil.between(DateUtil.toLocalDateTime(changeTime), DateUtil.toLocalDateTime(endChangeTime), ChronoUnit.MONTHS);
                     newSubCoHeadService.set(MasConstant.NCKD_SERVICEMONTHS,between);
                 }
 

+ 4 - 3
code/swc/nckd-jxccl-swc/src/main/java/nckd/jxccl/swc/mas/plugin/form/empmgt/TenurePersonListListPlugin.java

@@ -312,9 +312,10 @@ public class TenurePersonListListPlugin extends AbstractListPlugin implements Pl
                     }else{
                         newSubCoHeadService.set(MasConstant.NCKD_ENDDATE, DateUtil.getMaxDateAsDate());
                     }
-                    //【变动时间】的次月到当年年底的月数
-                    LocalDateTime newMonths = DateUtil.addMonths(DateUtil.toLocalDateTime(changeTime), 1);
-                    long between = DateUtil.between(newMonths, endYear, ChronoUnit.MONTHS);
+                    //【变动时间】的次月到当年年底的月数(ChronoUnit.MONTHS是从0开始的,所以不用加月份)
+//                    LocalDateTime newMonths = DateUtil.addMonths(DateUtil.toLocalDateTime(changeTime), 1);
+                    Date endChangeTime = DateUtil.endOfYear(changeTime);
+                    long between = DateUtil.between(DateUtil.toLocalDateTime(changeTime), DateUtil.toLocalDateTime(endChangeTime), ChronoUnit.MONTHS);
                     newSubCoHeadService.set(MasConstant.NCKD_SERVICEMONTHS,between);
                 }
 

+ 6 - 1
code/swc/nckd-jxccl-swc/src/main/java/nckd/jxccl/swc/mas/plugin/form/structappr/EntleaderAnlSalStdFormPlugin.java

@@ -145,8 +145,13 @@ public class EntleaderAnlSalStdFormPlugin extends AbstractStructApprFormPlugin i
                         DynamicObjectCollection dbEntryColl = dbSubCorpSalary.getDynamicObjectCollection(MasConstant.NCKD_ENTRYENTITY);
                         for (DynamicObject dbEntryEntity : dbEntryColl) {
                             DynamicObject projectCategory = dbEntryEntity.getDynamicObject(MasConstant.NCKD_PROJECTCATEGORY);
+                            DynamicObject parent = null;
+                            if(projectCategory.containsProperty("parent")) {
+                                parent = projectCategory.getDynamicObject("parent");
+                            }
                             String projectCategoryNumber = projectCategory.getString(FormConstant.NUMBER_KEY);
-                            if(projectCategoryNumber.equalsIgnoreCase(ProjectCategoryEnum.YEARLY_SALARY.getCode())) {
+                            //只取分类为"年度薪酬"的数据
+                            if(projectCategoryNumber.equalsIgnoreCase(ProjectCategoryEnum.YEARLY_SALARY.getCode()) || (parent != null && (parent.getString(FormConstant.NUMBER_KEY).equalsIgnoreCase(ProjectCategoryEnum.YEARLY_SALARY.getCode())))) {
                                 DynamicObject entry = entryEntities.addNew();
                                 boolean deferredPayItem = dbEntryEntity.getBoolean(MasConstant.NCKD_DEFERREDPAYITEM);
                                 entry.set(MasConstant.NCKD_PROJECTCATEGORY, dbEntryEntity.getDynamicObject(MasConstant.NCKD_PROJECTCATEGORY));

+ 5 - 1
code/swc/nckd-jxccl-swc/src/main/java/nckd/jxccl/swc/mas/plugin/form/structappr/SubcorpChiefSalStdFormPlugin.java

@@ -134,9 +134,13 @@ public class SubcorpChiefSalStdFormPlugin extends AbstractStructApprFormPlugin i
                     DynamicObjectCollection dbEntryColl = dbSubCorpSalary.getDynamicObjectCollection(MasConstant.NCKD_ENTRYENTITY);
                     for (DynamicObject dbEntryEntity : dbEntryColl) {
                         DynamicObject projectCategory = dbEntryEntity.getDynamicObject(MasConstant.NCKD_PROJECTCATEGORY);
+                        DynamicObject parent = null;
+                        if(projectCategory.containsProperty("parent")) {
+                            parent = projectCategory.getDynamicObject("parent");
+                        }
                         String projectCategoryNumber = projectCategory.getString(FormConstant.NUMBER_KEY);
                         //只取分类为"年度薪酬"的数据
-                        if(projectCategoryNumber.equalsIgnoreCase(ProjectCategoryEnum.YEARLY_SALARY.getCode())) {
+                        if(projectCategoryNumber.equalsIgnoreCase(ProjectCategoryEnum.YEARLY_SALARY.getCode()) || (parent != null && (parent.getString(FormConstant.NUMBER_KEY).equalsIgnoreCase(ProjectCategoryEnum.YEARLY_SALARY.getCode())))) {
                             DynamicObject entry = entryEntities.addNew();
                             boolean deferredPayItem = dbEntryEntity.getBoolean(MasConstant.NCKD_DEFERREDPAYITEM);
                             entry.set(MasConstant.NCKD_PROJECTCATEGORY, dbEntryEntity.getDynamicObject(MasConstant.NCKD_PROJECTCATEGORY));