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

feat(hr): 添加人员变动预测功能并修复组织岗位赋值问题

- 在DateUtil中新增nowDate()方法获取当前日期时间
- 创建IPersonnelPredictionService接口提供退休和减员预测功能
- 实现PersonnelPredictionService类提供预测服务具体实现
- 添加ServiceFactory工厂类管理预测服务实例
- 修复PerfRankMgmtSaveOpPlugin中组织和岗位赋值时的空指针问题
- 添加empPosOrg非空判断确保安全赋值操作
wyc 6 дней назад
Родитель
Сommit
418a718765

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

@@ -47,6 +47,15 @@ public class DateUtil {
         return LocalDateTime.now();
     }
 
+    /**
+     * 获取当前日期时间
+     *
+     * @return 当前日期时间
+     */
+    public static Date nowDate() {
+        return toDate(LocalDateTime.now());
+    }
+
     /**
      * 转换为Date对象
      *

+ 0 - 0
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/hspm/mservice/.gitkeep


+ 24 - 0
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/hspm/mservice/PersonnelPredictionService.java

@@ -0,0 +1,24 @@
+package nckd.jxccl.hr.hspm.mservice;
+
+import nckd.jxccl.hr.hspm.mservice.api.IPersonnelPredictionService;
+
+import java.util.Date;
+
+/**
+ * TODO
+ *
+ * @author W.Y.C
+ * @version 1.0
+ * @date 2026/1/5 14:47
+ */
+public class PersonnelPredictionService implements IPersonnelPredictionService {
+    @Override
+    public Double predictRetirement(Long orgId,Date beginDate, Date endDate) {
+        return 20.0;
+    }
+
+    @Override
+    public Double predictAttrition(Long orgId,Date beginDate, Date endDate) {
+        return 10.0;
+    }
+}

+ 33 - 0
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/hspm/mservice/api/IPersonnelPredictionService.java

@@ -0,0 +1,33 @@
+package nckd.jxccl.hr.hspm.mservice.api;
+
+import java.util.Date;
+
+/**
+* 人员变动预测服务
+* 提供关于未来人员减少的预测数据,包括退休和减员。
+* @author W.Y.C
+* @date 2026/1/5 14:19
+* @version 1.0
+*/
+public interface IPersonnelPredictionService {
+
+    /**
+     * 预测单位/部门在未来某时间范围内的预计退休人数
+     * @param beginDate 查询开始日期
+     * @param endDate 查询结束日期
+     * @return: java.lang.Double
+     * @author W.Y.C
+     * @date: 2026/01/05 14:20
+     */
+    Double predictRetirement(Long orgId,Date beginDate, Date endDate);
+
+    /**
+     * 预测单位/部门在未来某时间范围内的预计减员人数
+     * @param beginDate 查询开始日期
+     * @param endDate 查询结束日期
+     * @return: java.lang.Double
+     * @author W.Y.C
+     * @date: 2026/01/05 14:21
+     */
+    Double predictAttrition(Long orgId,Date beginDate, Date endDate);
+}

+ 36 - 0
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/hspm/servicehelper/ServiceFactory.java

@@ -0,0 +1,36 @@
+package nckd.jxccl.hr.hspm.servicehelper;
+
+import kd.bos.dataentity.TypesContainer;
+
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+
+/**
+ * TODO
+ *
+ * @author W.Y.C
+ * @version 1.0
+ * @date 2026/1/5 15:22
+ */
+public class ServiceFactory {
+
+    private static final Map<String, String> SERVICE_MAP = new HashMap<String, String>() {
+        {
+            this.put("IPersonnelPredictionService", "nckd.jxccl.hr.hspm.mservice.PersonnelPredictionService");
+        }
+    };
+
+    public static <T> T getService(Class<T> clazz) {
+        return (T)getService(clazz.getSimpleName());
+    }
+
+    public static Object getService(String serviceName) {
+        String className = (String)SERVICE_MAP.get(serviceName);
+        if (className == null) {
+            throw new RuntimeException(String.format(Locale.ROOT, "%s service not find", serviceName));
+        } else {
+            return TypesContainer.getOrRegisterSingletonInstance(className);
+        }
+    }
+}

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

@@ -214,11 +214,15 @@ public class PerfRankMgmtSaveOpPlugin extends AbstractOperationServicePlugIn imp
                 DynamicObject empPosOrg = empPosOrgRelByEmployeesMap.get(person.getLong(FormConstant.ID_KEY));
                 if(entry.getDynamicObject(FormConstant.NCKD_DEP) == null){
                     //赋值组织
-                    entry.set(FormConstant.NCKD_DEP,empPosOrg.get(FormConstant.ADMINORG));
+                    if(empPosOrg != null) {
+                        entry.set(FormConstant.NCKD_DEP, empPosOrg.get(FormConstant.ADMINORG));
+                    }
                 }
                 if(entry.getDynamicObject(PositionStructureConstant.NCKD_POSITIONHR) == null){
                     //赋值岗位
-                    entry.set(PositionStructureConstant.NCKD_POSITIONHR,empPosOrg.get(FormConstant.POSITION_KEY));
+                    if(empPosOrg != null) {
+                        entry.set(PositionStructureConstant.NCKD_POSITIONHR, empPosOrg.get(FormConstant.POSITION_KEY));
+                    }
                 }
 
                 //生成R排名