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

feat(hr): 添加岗位分配功能并优化岗位删除逻辑

- 在FormConstant中添加BOS岗位实体标识常量
- 修改PositionBillServiceHelper实现HR和BOS岗位数据的删除逻辑
- 添加PositionHRConstant类定义岗位分配相关常量
- 新增PositionAssignFormPlugin实现岗位分配表单功能
- 新增PositionHRListPlugin实现岗位列表分配操作
- 修改PosBillEntryNewPositionTempSaveOpPlugin调用岗位删除方法
jtd 6 дней назад
Родитель
Сommit
8e569a4645

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

@@ -144,6 +144,8 @@ public class FormConstant {
     public static final String HAOS_ORGBATCHTREELISTF7_ENTITY = "haos_orgbatchtreelistf7";
     /** 组织快速维护实体标识 */
     public static final String HAOS_ADMINORGDETAIL_ENTITY = "haos_adminorgdetail";
+    /** 企业建模-岗位实体标识 */
+    public static final String BOS_POSITION_ENTITY = "bos_position";
 
     //====================================== 标品op ======================================
     /** 确认框确认按钮 */

+ 16 - 2
code/hrmp/nckd-jxccl-hrmp/src/main/java/nckd/jxccl/hrmp/hbpm/business/hr/service/impl/PositionBillServiceHelper.java

@@ -13,6 +13,9 @@ import kd.bos.dataentity.entity.DynamicObject;
 import kd.bos.dataentity.entity.DynamicObjectCollection;
 import kd.bos.dataentity.entity.ILocaleString;
 import kd.bos.dataentity.serialization.SerializationUtils;
+import kd.bos.db.tx.Propagation;
+import kd.bos.db.tx.TX;
+import kd.bos.db.tx.TXHandle;
 import kd.bos.entity.constant.StatusEnum;
 import kd.bos.entity.datamodel.IDataModel;
 import kd.bos.entity.operate.OperateOptionConst;
@@ -294,8 +297,19 @@ public class PositionBillServiceHelper {
 //        hisDeleteParam.setEntityNumber(PositionBillConstant.HBPM_POSITIONHR);
 //        hisDeleteParam.setDataList(Arrays.asList(HRBaseServiceHelper.create(PositionBillConstant.HBPM_POSITIONHR).loadDynamicObjectArray(positionIdList.toArray())));
 //        HisModelServiceHelper.deleteBo(hisDeleteParam);
-        HRBaseServiceHelper positionHrHelper = new HRBaseServiceHelper(PositionBillConstant.HBPM_POSITIONHR);
-        positionHrHelper.deleteByFilter(new QFilter[]{new QFilter(PositionBillConstant.BOID_KEY, QCP.in, positionIdList)});
+
+        // 删除HR岗位暂存的数据
+        HRBaseServiceHelper.create(PositionBillConstant.HBPM_POSITIONHR).deleteByFilter(new QFilter[]{new QFilter(PositionBillConstant.BOID_KEY, QCP.in, positionIdList)});
+
+        if (TX.getPropagation() != Propagation.NOT_SUPPORTED) {
+            try (TXHandle txHandle = TX.requiresNew()) {
+                // 删除BOS岗位暂存的数据
+                HRBaseServiceHelper.create(PositionBillConstant.BOS_POSITION_ENTITY).deleteByFilter(new QFilter[]{new QFilter(PositionBillConstant.ID_KEY, QCP.in, positionIdList)});
+            }
+        } else {
+            // 删除BOS岗位暂存的数据
+            HRBaseServiceHelper.create(PositionBillConstant.BOS_POSITION_ENTITY).deleteByFilter(new QFilter[]{new QFilter(PositionBillConstant.ID_KEY, QCP.in, positionIdList)});
+        }
     }
 
     public static DynamicObject getFocusEntry(String suffix, IFormView view, int row) {

+ 33 - 0
code/hrmp/nckd-jxccl-hrmp/src/main/java/nckd/jxccl/hrmp/hbpm/common/hr/PositionHRConstant.java

@@ -0,0 +1,33 @@
+package nckd.jxccl.hrmp.hbpm.common.hr;
+
+import nckd.jxccl.base.common.constant.FormConstant;
+
+/**
+ *
+ * @entity:
+ * @author: jtd
+ * @date: 2026/1/4 21:45
+ */
+public class PositionHRConstant extends FormConstant {
+    /** 岗位分配实体标识 */
+    public static final String NCKD_POSITIONASSIGN_ENTITY = "nckd_positionassign";
+    /** 岗位信息键值转换实体标识 */
+    public static final String NCKD_POSASSIGN_TRANSKEY_ENTITY = "nckd_posassign_transkey";
+
+    /** 岗位分配操作标识 */
+    public static final String POSITIONASSIGN_OP = "positionassign";
+
+    /** 选中的数据ID页面自定义参数 */
+    public static final String SELECTED_IDS_CUSTOM_PARAM = "selectedids";
+
+    /** 岗位分配回调标识 */
+    public static final String POSITIONASSIGN_CALLBACK = "positionassign";
+
+    /** 岗位分配.设立日期 */
+    public static final String NCKD_ESTABLISHMENTDATE_KEY = "nckd_establishmentdate";
+    /** 岗位.上级岗位 */
+    public static final String PARENT_KEY = "parent";
+    /** 上级岗位 */
+    public static final String NCKD_PARENT_KEY = "nckd_parent";
+
+}

+ 185 - 0
code/hrmp/nckd-jxccl-hrmp/src/main/java/nckd/jxccl/hrmp/hbpm/plugin/form/hr/PositionAssignFormPlugin.java

@@ -0,0 +1,185 @@
+package nckd.jxccl.hrmp.hbpm.plugin.form.hr;
+
+import kd.bos.dataentity.OperateOption;
+import kd.bos.dataentity.entity.DynamicObject;
+import kd.bos.dataentity.entity.DynamicObjectCollection;
+import kd.bos.entity.operate.OperateOptionConst;
+import kd.bos.entity.operate.result.IOperateInfo;
+import kd.bos.entity.operate.result.OperationResult;
+import kd.bos.entity.property.EntryProp;
+import kd.bos.form.MessageTypes;
+import kd.bos.form.control.Control;
+import kd.bos.form.plugin.AbstractFormPlugin;
+import kd.bos.servicehelper.coderule.CodeRuleServiceHelper;
+import kd.bos.servicehelper.operation.OperationServiceHelper;
+import kd.hr.hbp.business.servicehelper.HRBaseServiceHelper;
+import kd.hr.hbp.common.util.HRDateTimeUtils;
+import kd.hr.hbp.common.util.HRDynamicObjectUtils;
+import kd.hr.hbp.common.util.HRStringUtils;
+import nckd.jxccl.base.common.utils.QueryFieldBuilder;
+import nckd.jxccl.hrmp.hbpm.common.hr.PositionBillConstant;
+import nckd.jxccl.hrmp.hbpm.common.hr.PositionHRConstant;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.EventObject;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+/**
+ * 岗位分配表单插件
+ * @entity: nckd_positionassign
+ * @author: jtd
+ * @date: 2026/1/5 09:40
+ */
+public class PositionAssignFormPlugin extends AbstractFormPlugin {
+
+    /**
+     * 获取岗位分配转换键值
+     * @return 源字段: 目标字段
+     */
+    public static Map<String, String> getPosAssignTransKeyMap() {
+        String selectFields = QueryFieldBuilder.create().add(PositionHRConstant.NUMBER_KEY).add(PositionHRConstant.NAME_KEY).buildSelect();
+        DynamicObject[] transKeyDyos = HRBaseServiceHelper.create(PositionHRConstant.NCKD_POSASSIGN_TRANSKEY_ENTITY).queryOriginalArray(selectFields, null);
+        Map<String, String> transKeyMap = Arrays.stream(transKeyDyos).collect(Collectors.toMap(
+                transKeyDyo -> transKeyDyo.getString(PositionHRConstant.NUMBER_KEY),
+                transKeyDyo -> transKeyDyo.getString(PositionHRConstant.NAME_KEY),
+                (oldValue, newValue) -> newValue)
+        );
+        return transKeyMap;
+    }
+
+    @Override
+    public void afterBindData(EventObject e) {
+        super.afterBindData(e);
+
+        Object selectedIds = getView().getFormShowParameter().getCustomParam(PositionHRConstant.SELECTED_IDS_CUSTOM_PARAM);
+        if (selectedIds != null) {
+            DynamicObject[] positionHrDyns = HRBaseServiceHelper.create(PositionHRConstant.HBPM_POSITIONHR).loadDynamicObjectArray(Arrays.stream(String.valueOf(selectedIds).split(",")).map(Long::valueOf).toArray());
+            DynamicObjectCollection entryEntityDynColl = getModel().getDataEntity().getDynamicObjectCollection(PositionHRConstant.NCKD_ENTRYENTITY);
+            // 获取岗位要转换的键值
+            Map<String, String> posAssignTransKeyMap = getPosAssignTransKeyMap();
+            Map<Long, Long> oriAdminOrgData = new HashMap<Long, Long>();
+            for (DynamicObject positionHrDy : positionHrDyns) {
+                DynamicObject entryEntityDy = entryEntityDynColl.addNew();
+                HRDynamicObjectUtils.copy(positionHrDy, entryEntityDy, posAssignTransKeyMap);
+                // 设置ID
+                entryEntityDy.set(PositionHRConstant.ID_KEY, positionHrDy.getLong(PositionHRConstant.ID_KEY));
+                // 设立日期
+                entryEntityDy.set(PositionHRConstant.NCKD_ESTABLISHMENTDATE_KEY, HRDateTimeUtils.getNowDate());
+                oriAdminOrgData.put(positionHrDy.getLong(PositionHRConstant.ID_KEY), positionHrDy.getLong(String.join(".", PositionHRConstant.ADMINORG, PositionHRConstant.ID_KEY)));
+            }
+            getView().updateView(PositionHRConstant.NCKD_ENTRYENTITY);
+
+            getModel().setDataChanged(false);
+        }
+    }
+
+    @Override
+    public void registerListener(EventObject e) {
+        super.registerListener(e);
+
+        addClickListeners(PositionHRConstant.BTN_OK_OP);
+    }
+
+    @Override
+    public void click(EventObject evt) {
+        super.click(evt);
+
+        String key = ((Control) evt.getSource()).getKey();
+        if (HRStringUtils.equals(key, PositionHRConstant.BTN_OK_OP)) {
+            Object[] positionIds = getModel().getDataEntity(true).getDynamicObjectCollection(PositionHRConstant.NCKD_ENTRYENTITY).stream().map(entryEntityDy -> entryEntityDy.getLong(PositionHRConstant.ID_KEY)).toArray();
+            if (positionIds.length == 0) {
+                getView().showMessage("没有数据可执行。");
+            } else {
+                DynamicObject[] positionDyns = HRBaseServiceHelper.create(PositionHRConstant.HBPM_POSITIONHR).loadDynamicObjectArray(positionIds);
+                Map<Long, DynamicObject> positionDyMap = Arrays.stream(positionDyns).collect(Collectors.toMap(positionDy -> positionDy.getLong(PositionHRConstant.ID_KEY), Function.identity()));
+                Boolean needSave = hasDataNeedSave(positionDyMap);
+                if (needSave) {
+                    confirm(positionDyMap);
+                }
+            }
+        }
+    }
+
+    private Boolean hasDataNeedSave(Map<Long, DynamicObject> positionDyMap) {
+        DynamicObjectCollection entryEntityDynColl = getModel().getDataEntity(true).getDynamicObjectCollection(PositionHRConstant.NCKD_ENTRYENTITY);
+        // 获取分录名称
+        EntryProp entryEntityProp = (EntryProp) getModel().getDataEntityType().getProperty(PositionHRConstant.NCKD_ENTRYENTITY);
+        String entryEntityName = entryEntityProp.getDisplayName().getLocaleValue();
+        String adminOrgName = entryEntityProp.getItemType().getProperties().get(PositionHRConstant.NCKD_ADMINORG).getDisplayName().getLocaleValue();
+
+        List<String> errorMsgList = new ArrayList<String>();
+        for (int i = 0; i < entryEntityDynColl.size(); i++) {
+            DynamicObject entryEntityDy = entryEntityDynColl.get(i);
+            Long oriAdminOrg = positionDyMap.get(entryEntityDy.getLong(PositionHRConstant.ID_KEY)).getLong(String.join(".", PositionHRConstant.ADMINORG, PositionHRConstant.ID_KEY));
+            Long newAdminOrg = entryEntityDy.getLong(String.join(".", PositionHRConstant.NCKD_ADMINORG, PositionHRConstant.ID_KEY));
+            // 判断行政组织是否发生变更
+            if (oriAdminOrg.equals(newAdminOrg)) {
+                errorMsgList.add(HRStringUtils.format("请变更“{}”第{}行:“{}”。", new Object[]{entryEntityName, i+1, adminOrgName}));
+            }
+        }
+
+        if (!errorMsgList.isEmpty()) {
+            getView().showMessage(null, String.join(System.lineSeparator(), errorMsgList), MessageTypes.Default);
+            return false;
+        }
+
+        return true;
+    }
+
+    private void confirm(Map<Long, DynamicObject> positionDyMap) {
+        DynamicObjectCollection entryEntityDyoColl = getModel().getDataEntity(true).getDynamicObjectCollection(PositionHRConstant.NCKD_ENTRYENTITY);
+        List<DynamicObject> dataEntities = new ArrayList<DynamicObject>();
+        HRBaseServiceHelper positionServiceHelper = HRBaseServiceHelper.create(PositionHRConstant.HBPM_POSITIONHR);
+        String orgId = "";
+        for (DynamicObject entryEntityDy : entryEntityDyoColl) {
+            DynamicObject newDyo = positionServiceHelper.generateEmptyDynamicObject();
+            HRDynamicObjectUtils.copy(positionDyMap.get(entryEntityDy.getLong(PositionHRConstant.ID_KEY)), newDyo);
+            // 重置ID
+            newDyo.set(PositionHRConstant.ID_KEY, null);
+            newDyo.set(PositionHRConstant.BOID_KEY, null);
+            // 设置行政组织
+            newDyo.set(PositionHRConstant.ADMINORG, entryEntityDy.get(PositionHRConstant.NCKD_ADMINORG));
+            // 设置上级岗位
+            newDyo.set(PositionHRConstant.PARENT_KEY, entryEntityDy.get(PositionHRConstant.NCKD_PARENT_KEY));
+            // 设置编码
+            orgId = newDyo.getString(String.join(".", PositionHRConstant.ORG_KEY, PositionHRConstant.ID_KEY));
+            String positionNumber = CodeRuleServiceHelper.getNumber(PositionHRConstant.HBPM_POSITIONHR, newDyo, orgId);
+            newDyo.set(PositionHRConstant.NUMBER_KEY, positionNumber);
+            // 放入
+            dataEntities.add(newDyo);
+        }
+
+        OperateOption operateOption = OperateOption.create();
+        operateOption.setVariableValue(OperateOptionConst.ISHASRIGHT, Boolean.TRUE.toString());
+        operateOption.setVariableValue(OperateOptionConst.ONLY_VALIDATE, Boolean.TRUE.toString());
+        OperationResult operationResult = OperationServiceHelper.executeOperate(PositionHRConstant.SAVE_OP, PositionBillConstant.HBPM_POSITIONHR, dataEntities.toArray(new DynamicObject[0]), operateOption);
+        List<String> errorMsgList = new ArrayList<String>();
+        if (!operationResult.isSuccess()) {
+            for(IOperateInfo operateInfo : operationResult.getAllErrorOrValidateInfo()) {
+                errorMsgList.add(operateInfo.getMessage());
+            }
+
+            if (HRStringUtils.isNotBlank(operationResult.getMessage())) {
+                errorMsgList.add(operationResult.getMessage());
+            }
+
+            // 回收编码
+            String[] numbers = dataEntities.stream().map(data -> data.getString(PositionHRConstant.NUMBER_KEY)).toArray(String[]::new);
+            CodeRuleServiceHelper.recycleBatchNumber(PositionHRConstant.HBPM_POSITIONHR, dataEntities.toArray(new DynamicObject[0]), orgId, numbers);
+        }
+
+        if (!errorMsgList.isEmpty()) {
+            getView().showMessage(null ,String.join(System.lineSeparator(), errorMsgList), MessageTypes.Default);
+            return;
+        }
+
+        OperationServiceHelper.executeOperate(PositionHRConstant.SAVE_OP, PositionBillConstant.HBPM_POSITIONHR, dataEntities.toArray(new DynamicObject[0]));
+        getView().returnDataToParent("true");
+        getView().close();
+    }
+}

+ 60 - 0
code/hrmp/nckd-jxccl-hrmp/src/main/java/nckd/jxccl/hrmp/hbpm/plugin/form/hr/PositionHRListPlugin.java

@@ -0,0 +1,60 @@
+package nckd.jxccl.hrmp.hbpm.plugin.form.hr;
+
+import kd.bos.entity.datamodel.ListSelectedRow;
+import kd.bos.form.CloseCallBack;
+import kd.bos.form.FormShowParameter;
+import kd.bos.form.ShowType;
+import kd.bos.form.events.AfterDoOperationEventArgs;
+import kd.bos.form.events.ClosedCallBackEvent;
+import kd.bos.list.plugin.AbstractListPlugin;
+import nckd.jxccl.hrmp.hbpm.common.hr.PositionHRConstant;
+
+import java.util.Arrays;
+import java.util.stream.Collectors;
+
+/**
+ * 岗位信息维护列表插件
+ * @entity: hbpm_positionhr
+ * @author: jtd
+ * @date: 2026/1/4 21:37
+ */
+public class PositionHRListPlugin  extends AbstractListPlugin {
+
+    @Override
+    public void afterDoOperation(AfterDoOperationEventArgs afterDoOperationEventArgs) {
+        super.afterDoOperation(afterDoOperationEventArgs);
+
+        switch(afterDoOperationEventArgs.getOperateKey()) {
+            case PositionHRConstant.POSITIONASSIGN_OP:
+                Object[] selectedRowIds = getSelectedRows().stream().map(ListSelectedRow::getPrimaryKeyValue).toArray();
+                if (selectedRowIds.length > 0) {
+                    showPositionAssignFrom(selectedRowIds);
+                } else {
+                    getView().showTipNotification("请选择要执行的数据。");
+                }
+        }
+
+    }
+
+    private void showPositionAssignFrom(Object[] selectedRowIds) {
+        FormShowParameter formShowParameter = new FormShowParameter();
+        formShowParameter.setFormId(PositionHRConstant.NCKD_POSITIONASSIGN_ENTITY);
+        formShowParameter.getOpenStyle().setShowType(ShowType.Modal);
+        formShowParameter.setCustomParam(PositionHRConstant.SELECTED_IDS_CUSTOM_PARAM, Arrays.stream(selectedRowIds).map(String::valueOf).collect(Collectors.joining(",")));
+        formShowParameter.setCloseCallBack(new CloseCallBack(getPluginName(), PositionHRConstant.POSITIONASSIGN_CALLBACK));
+        getView().showForm(formShowParameter);
+    }
+
+    @Override
+    public void closedCallBack(ClosedCallBackEvent closedCallBackEvent) {
+        super.closedCallBack(closedCallBackEvent);
+
+        switch (closedCallBackEvent.getActionId()) {
+            case PositionHRConstant.POSITIONASSIGN_CALLBACK:
+                Object returnData = closedCallBackEvent.getReturnData();
+                if (returnData != null) {
+                    getView().showSuccessNotification("操作成功");
+                }
+        }
+    }
+}

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

@@ -24,6 +24,7 @@ import nckd.jxccl.hrmp.hbpm.common.hr.PositionBillConstant;
 
 import java.util.List;
 import java.util.Map;
+import java.util.stream.Collectors;
 
 /**
  * 岗位申请-新增岗位保存操作插件
@@ -147,6 +148,12 @@ public class PosBillEntryNewPositionTempSaveOpPlugin extends AbstractOperationSe
                 positionEntity.set(PositionBillConstant.NUMBER_KEY, dbPositionEntityDy.getString(PositionBillConstant.NUMBER_KEY));
             }
         }
+
+        // 不论成功与否,都调用岗位删除,BOS岗位不需要暂存数据
+        List<Long> positionIds = positionList.stream().map(positionDy -> positionDy.getLong(PositionBillConstant.ID_KEY)).collect(Collectors.toList());
+        //HRBaseServiceHelper.create(PositionBillConstant.BOS_POSITION_ENTITY).deleteByFilter(new QFilter[]{new QFilter(PositionBillConstant.ID_KEY, QCP.in, positionIds)});
+        PositionBillServiceHelper.delAddMaster(positionIds);
+
         if (!errorMsgList.isEmpty()) {
             throw new KDBizException(String.join(System.lineSeparator(), errorMsgList));
         } else {