Selaa lähdekoodia

feat(hrmp): 添加岗位申请单生效服务和操作插件

- 实现 PositionBillEffectService 提供岗位申请单生效核心功能
- 添加岗位新增、变更、审核等业务逻辑处理
- 实现岗位数据复制、状态更新、权限控制等功能
- 创建 PositionBillEffectOpPlugin 操作插件进行流程集成
- 集成历史数据模型复制工具和动态对象处理
- 实现批量操作和事务管理机制
jtd 1 viikko sitten
vanhempi
säilyke
4037ed1bb8

+ 228 - 0
code/hrmp/nckd-jxccl-hrmp/src/main/java/nckd/jxccl/hrmp/hbpm/business/hr/service/impl/PositionBillEffectService.java

@@ -0,0 +1,228 @@
+package nckd.jxccl.hrmp.hbpm.business.hr.service.impl;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+import kd.bos.common.enums.EnableEnum;
+import kd.bos.dataentity.OperateOption;
+import kd.bos.dataentity.entity.DynamicObject;
+import kd.bos.dataentity.metadata.IDataEntityProperty;
+import kd.bos.dataentity.metadata.clr.DataEntityPropertyCollection;
+import kd.bos.entity.operate.OperateOptionConst;
+import kd.bos.entity.operate.result.IOperateInfo;
+import kd.bos.entity.operate.result.OperationResult;
+import kd.bos.exception.KDBizException;
+import kd.bos.logging.Log;
+import kd.bos.logging.LogFactory;
+import kd.bos.orm.query.QCP;
+import kd.bos.orm.query.QFilter;
+import kd.bos.service.operation.OperationServiceImpl;
+import kd.hr.hbp.business.service.history.util.HisModelCopyUtil;
+import kd.hr.hbp.business.servicehelper.HRBaseServiceHelper;
+import kd.hr.hbp.common.util.HRDynamicObjectUtils;
+import kd.sdk.hr.hdm.common.enums.reg.RegBillStatusEnum;
+import nckd.jxccl.hrmp.hbpm.common.hr.PositionBillConstant;
+import nckd.jxccl.hrmp.hbpm.common.hr.PositionChangeTypeEnum;
+
+import java.util.Arrays;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+/**
+ * 岗位申请单生效服务
+ * @from: kd.hr.homs.business.service.batcheffect.OrgBillBatchEffectService
+ * @author: jtd
+ * @date: 2026/1/10 15:49
+ */
+public class PositionBillEffectService {
+    private static final Log log = LogFactory.getLog(PositionBillEffectService.class);
+
+    HRBaseServiceHelper positionHelper = new HRBaseServiceHelper(PositionBillConstant.HBPM_POSITIONHR);
+
+    public void billEffect(DynamicObject[] bills) {
+        for (DynamicObject bill : bills) {
+            Date effDate = bill.getDate(PositionBillConstant.NCKD_EFFDT);
+            if (effDate == null) {
+                throw new KDBizException("生效日期不能为空");
+            }
+
+            long billId = bill.getLong(PositionBillConstant.ID_KEY);
+            Map<String, List<DynamicObject>> billEntryPositionDyMap = getBillEntryPositionDyMap(billId);
+            Map<Long, DynamicObject> positionBoIdMap = getAllCurrentVersionParentDyMap(billEntryPositionDyMap);
+            newAddPositionEffect(billEntryPositionDyMap.get(PositionChangeTypeEnum.ADD.getName()), billId, effDate);
+            confirmChangePositionEffect(billEntryPositionDyMap.get(PositionChangeTypeEnum.CHANGE.getName()), positionBoIdMap, billId, effDate);
+            auditBill(billId);
+        }
+    }
+
+    private void confirmChangePositionEffect(List<DynamicObject> confirmChangePositionEntity, Map<Long, DynamicObject> positionBoIdMap, long billId, Date effDate) {
+        if (confirmChangePositionEntity != null && !confirmChangePositionEntity.isEmpty()) {
+            Map<Long, DynamicObject> dbPositionMap = getDbDyMap(confirmChangePositionEntity);
+            List<DynamicObject> confirmChangePositionDys = Lists.newArrayListWithExpectedSize(confirmChangePositionEntity.size());
+            HisModelCopyUtil hisModelCopyUtil = new HisModelCopyUtil();
+
+            // 获取岗位要转换的键值
+            Map<String, String> positionTransKeyMap = PositionBillServiceHelper.getPositionTransKeyMap();
+            for(DynamicObject confirmChangePosition : confirmChangePositionEntity) {
+                DynamicObject positionDy = confirmChangePosition.getDynamicObject(PositionBillConstant.NCKD_POSITION_KEY);
+                long positionId = positionDy.getLong(PositionBillConstant.BOID_KEY);
+                DynamicObject dbPositionDy = dbPositionMap.get(positionId);
+                if (dbPositionDy != null) {
+                    DynamicObject copyDy = hisModelCopyUtil.copyTempVersionData(dbPositionDy, positionHelper);
+                    HRDynamicObjectUtils.copy(confirmChangePosition, copyDy, positionTransKeyMap);
+                    DynamicObject parentOrgVersionDy = confirmChangePosition.getDynamicObject(PositionBillConstant.NCKD_PARENT);
+                    if (parentOrgVersionDy != null) {
+                        copyDy.set(PositionBillConstant.PARENT_KEY, positionBoIdMap.get(parentOrgVersionDy.getLong(PositionBillConstant.BOID_KEY)));
+                    } else {
+                        copyDy.set(PositionBillConstant.PARENT_KEY, null);
+                    }
+
+                    copyDy.set(PositionBillConstant.BSED_KEY, effDate);
+                    copyDy.set(PositionBillConstant.ENABLE, EnableEnum.YES.getCode());
+                    confirmChangePositionDys.add(copyDy);
+                }
+            }
+
+            if (!confirmChangePositionDys.isEmpty()) {
+                OperateOption operateOption = OperateOption.create();
+                operateOption.setVariableValue(OperateOptionConst.ISHASRIGHT, "true");
+                OperationServiceImpl opImpl = new OperationServiceImpl();
+                operateOption.setVariableValue(OperateOptionConst.SKIPCHECKPERMISSION, "true");
+                OperationResult operationResult = opImpl.localInvokeOperation(PositionBillConstant.CONFIRMCHANGE_OP, confirmChangePositionDys.toArray(new DynamicObject[0]), operateOption);
+                if (!operationResult.isSuccess()) {
+                    StringBuilder errorMsg = new StringBuilder();
+
+                    for(IOperateInfo operateInfo : operationResult.getAllErrorOrValidateInfo()) {
+                        errorMsg.append(operateInfo.getMessage());
+                    }
+
+                    throw new KDBizException(errorMsg.toString());
+                }
+            }
+
+        }
+    }
+
+    private void newAddPositionEffect(List<DynamicObject> newAddPositionEntity, long billId, Date effDate) {
+        if (newAddPositionEntity != null && !newAddPositionEntity.isEmpty()) {
+            Map<Long, DynamicObject> dbPositionMap = getDbDyMap(newAddPositionEntity);
+            List<DynamicObject> addPositionDys = Lists.newArrayListWithExpectedSize(newAddPositionEntity.size());
+
+            for(DynamicObject addPositionEntry : newAddPositionEntity) {
+                DynamicObject positionDy = addPositionEntry.getDynamicObject(PositionBillConstant.NCKD_POSITION_KEY);
+                if (positionDy == null) {
+                    log.error("PositionBillEffectService.newAddPositionEffect positionDy is empty");
+                } else {
+                    long positionId = positionDy.getLong(PositionBillConstant.ID_KEY);
+                    DynamicObject dbPositionDy = dbPositionMap.get(positionId);
+                    if (dbPositionDy == null) {
+                        log.error("PositionBillEffectService.newAddPositionEffect dbPositionDy is empty");
+                    } else {
+                        dbPositionDy.set(PositionBillConstant.BSED_KEY, effDate);
+                        dbPositionDy.set(PositionBillConstant.ISSTANDARDPOS_KEY, "0");
+                        addPositionDys.add(dbPositionDy);
+                    }
+                }
+            }
+
+            if (!addPositionDys.isEmpty()) {
+                OperateOption operateOption = OperateOption.create();
+                operateOption.setVariableValue(OperateOptionConst.ISHASRIGHT, "true");
+                OperationServiceImpl opImpl = new OperationServiceImpl();
+                operateOption.setVariableValue(OperateOptionConst.SKIPCHECKPERMISSION, "true");
+                OperationResult submitResult = opImpl.localInvokeOperation(PositionBillConstant.SAVE_OP, addPositionDys.toArray(new DynamicObject[0]), operateOption);
+                if (!submitResult.isSuccess()) {
+                    StringBuilder errorMsg = new StringBuilder();
+
+                    for(IOperateInfo operateInfo : submitResult.getAllErrorOrValidateInfo()) {
+                        errorMsg.append(operateInfo.getMessage());
+                    }
+
+                    throw new KDBizException(errorMsg.toString());
+                }
+            }
+
+        }
+    }
+
+    private Map<Long, DynamicObject> getDbDyMap(List<DynamicObject> entryDys) {
+        Set<Long> positionIds = Sets.newHashSetWithExpectedSize(entryDys.size());
+
+        for(DynamicObject entryOrg : entryDys) {
+            long positionId = getDyBdPropId(entryOrg, PositionBillConstant.NCKD_POSITION_KEY);
+            positionIds.add(positionId);
+        }
+
+        List<Long> boIds = Arrays.stream(positionHelper.queryOriginalArray(PositionBillConstant.BOID_KEY, new QFilter[]{new QFilter(PositionBillConstant.ID_KEY, QCP.in, positionIds)})).map((dy) -> dy.getLong(PositionBillConstant.BOID_KEY)).collect(Collectors.toList());
+        DynamicObject[] dbPositionDys = positionHelper.loadDynamicObjectArray(new QFilter[]{new QFilter(PositionBillConstant.ID_KEY, QCP.in, boIds)});
+        return Arrays.stream(dbPositionDys).collect(Collectors.toMap((dy) -> dy.getLong(PositionBillConstant.ID_KEY), Function.identity()));
+    }
+
+    // from: kd.hr.haos.business.util.PropertyGetUtils.getDyBdPropId
+    private long getDyBdPropId(DynamicObject dy, String property) {
+        DataEntityPropertyCollection properties = dy.getDataEntityType().getProperties();
+        IDataEntityProperty propertyType = properties.get(property);
+        if (propertyType == null) {
+            if (property.endsWith(".id")) {
+                property = property.substring(0, property.lastIndexOf("."));
+                propertyType = properties.get(property);
+                if (propertyType == null) {
+                    return 0L;
+                }
+            } else {
+                if (!property.endsWith("_id")) {
+                    return 0L;
+                }
+
+                property = property.substring(0, property.lastIndexOf("_"));
+                propertyType = properties.get(property);
+                if (propertyType == null) {
+                    return 0L;
+                }
+            }
+        }
+
+        Object propObj = dy.get(property);
+        if (propObj instanceof Long) {
+            return (Long) propObj;
+        } else {
+            return propObj instanceof DynamicObject ? ((DynamicObject) propObj).getLong("id") : 0L;
+        }
+    }
+
+    private Map<String, List<DynamicObject>> getBillEntryPositionDyMap(Long billId) {
+        HRBaseServiceHelper helper = new HRBaseServiceHelper(PositionBillConstant.NCKD_POSITIONBILLENTRY_ENTITY);
+        QFilter filter = new QFilter(PositionBillConstant.NCKD_BILLID, QCP.equals, billId);
+        DynamicObject[] entries = helper.loadDynamicObjectArray(new QFilter[]{filter});
+        return Arrays.stream(entries).collect(Collectors.groupingBy((dy) -> dy.getString(String.join(".", PositionBillConstant.NCKD_CHANGETYPE, PositionBillConstant.NUMBER_KEY))));
+    }
+
+    private Map<Long, DynamicObject> getAllCurrentVersionParentDyMap(Map<String, List<DynamicObject>> entryValues) {
+        List<Long> parentPositionBoIds = Lists.newArrayListWithExpectedSize(10);
+
+        for(Map.Entry<String, List<DynamicObject>> entry : entryValues.entrySet()) {
+            for(DynamicObject entryValue : entry.getValue()) {
+                DynamicObject parentPositionDy = entryValue.getDynamicObject(PositionBillConstant.NCKD_PARENT);
+                if (parentPositionDy != null) {
+                    parentPositionBoIds.add(parentPositionDy.getLong(PositionBillConstant.BOID_KEY));
+                }
+            }
+        }
+
+        DynamicObject[] dbPositionDys = positionHelper.loadDynamicObjectArray(new QFilter[]{new QFilter(PositionBillConstant.ID_KEY, QCP.equals, parentPositionBoIds)});
+        return Arrays.stream(dbPositionDys).collect(Collectors.toMap((dy) -> dy.getLong(PositionBillConstant.ID_KEY), Function.identity()));
+    }
+
+    public void auditBill(long billId) {
+        HRBaseServiceHelper serviceHelper = new HRBaseServiceHelper(PositionBillConstant.NCKD_POSITIONBILL_ENTITY);
+        DynamicObject billDy = serviceHelper.loadOne(PositionBillConstant.BILL_STATUS_KEY, (new QFilter(PositionBillConstant.ID_KEY, QCP.equals, billId)).toArray());
+        if (billDy != null) {
+            billDy.set(PositionBillConstant.BILL_STATUS_KEY, RegBillStatusEnum.APPROVEPASSED.getCode());
+            serviceHelper.updateOne(billDy);
+        }
+
+    }
+}

+ 47 - 0
code/hrmp/nckd-jxccl-hrmp/src/main/java/nckd/jxccl/hrmp/hbpm/plugin/operate/hr/PositionBillEffectOpPlugin.java

@@ -0,0 +1,47 @@
+package nckd.jxccl.hrmp.hbpm.plugin.operate.hr;
+
+import kd.bos.dataentity.entity.DynamicObject;
+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.logging.Log;
+import kd.bos.logging.LogFactory;
+import nckd.jxccl.hrmp.hbpm.business.hr.service.impl.PositionBillEffectService;
+import nckd.jxccl.hrmp.hbpm.common.hr.PositionBillConstant;
+
+/**
+ * 岗位申请单生效操作插件
+ * @from: kd.hr.homs.opplugin.web.orgbatch.OrgBatchChgBillEffectOp
+ * @operate: audit
+ * @author: jtd
+ * @date: 2026/1/10 15:39
+ */
+public class PositionBillEffectOpPlugin extends AbstractOperationServicePlugIn {
+    private static final Log log = LogFactory.getLog(PositionBillEffectOpPlugin.class);
+
+    @Override
+    public void onPreparePropertys(PreparePropertysEventArgs e) {
+        super.onPreparePropertys(e);
+
+        e.getFieldKeys().addAll(billEntityType.getAllFields().keySet());
+    }
+
+    @Override
+    public void onAddValidators(AddValidatorsEventArgs e) {
+        super.onAddValidators(e);
+    }
+
+    @Override
+    public void beginOperationTransaction(BeginOperationTransactionArgs e) {
+        super.beginOperationTransaction(e);
+
+        log.info("PositionBillEffectOpPlugin.beginOperationTransaction start.");
+        String operationKey = e.getOperationKey();
+        DynamicObject[] bills = e.getDataEntities();
+        if (PositionBillConstant.AUDIT_OP.equals(operationKey) || PositionBillConstant.SUBMITEFFECT_OP.equals(operationKey)) {
+            PositionBillEffectService positionBillEffectService = new PositionBillEffectService();
+            positionBillEffectService.billEffect(bills);
+        }
+    }
+}