Explorar el Código

feat(hrmp): 新增岗位申请相关功能模块

- 在基础常量类中增加消息中心应用ID和标准列表实体标识
- 修改行政组织保存插件,调整操作事务执行时机
- 新增岗位申请单基础服务类及回调服务类
- 重构岗位申请单服务帮助类,优化代码结构和逻辑
- 新增岗位变动类型枚举类,统一管理变动类型
- 更新岗位申请单常量定义,完善实体标识和操作标签
- 调整岗位申请单插件类引用的服务帮助类名称
jtd hace 2 semanas
padre
commit
8345fdfb40
Se han modificado 14 ficheros con 810 adiciones y 292 borrados
  1. 5 0
      code/base/nckd-jxccl-base-common/src/main/java/nckd/jxccl/base/common/constant/FormConstant.java
  2. 4 3
      code/hrmp/nckd-jxccl-hrmp/src/main/java/nckd/jxccl/hrmp/haos/plugin/operate/adminorg/AdminOrgDetailSaveOpPlugin.java
  3. 29 0
      code/hrmp/nckd-jxccl-hrmp/src/main/java/nckd/jxccl/hrmp/hbpm/business/hr/PositionBillBaseService.java
  4. 116 0
      code/hrmp/nckd-jxccl-hrmp/src/main/java/nckd/jxccl/hrmp/hbpm/business/hr/PositionBillClosedCallBackService.java
  5. 148 0
      code/hrmp/nckd-jxccl-hrmp/src/main/java/nckd/jxccl/hrmp/hbpm/business/hr/PositionBillConfirmCallBackService.java
  6. 100 47
      code/hrmp/nckd-jxccl-hrmp/src/main/java/nckd/jxccl/hrmp/hbpm/business/hr/PositionBillServiceHelper.java
  7. 36 36
      code/hrmp/nckd-jxccl-hrmp/src/main/java/nckd/jxccl/hrmp/hbpm/common/hr/PositionBillConstant.java
  8. 65 0
      code/hrmp/nckd-jxccl-hrmp/src/main/java/nckd/jxccl/hrmp/hbpm/common/hr/PositionChangeTypeEnum.java
  9. 107 88
      code/hrmp/nckd-jxccl-hrmp/src/main/java/nckd/jxccl/hrmp/hbpm/plugin/form/hr/PosBillEntryAddFormPlugin.java
  10. 111 36
      code/hrmp/nckd-jxccl-hrmp/src/main/java/nckd/jxccl/hrmp/hbpm/plugin/form/hr/PositionBillEntryFormPlugin.java
  11. 82 68
      code/hrmp/nckd-jxccl-hrmp/src/main/java/nckd/jxccl/hrmp/hbpm/plugin/form/hr/PositionBillFormPlugin.java
  12. 5 12
      code/hrmp/nckd-jxccl-hrmp/src/main/java/nckd/jxccl/hrmp/hbpm/plugin/operate/hr/PosBillEntryAddSaveOpPlugin.java
  13. 1 1
      cosmic.json
  14. 1 1
      cosmic.properties

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

@@ -14,6 +14,9 @@ public class FormConstant {
     public static final String HR_INVOKER_PARAM_INVOKER = "hrInvokerParam#invoker";
     public static final String DATA_MIGRATION = "dataMigration";
 
+    //====================================== 标品应用ID ======================================
+    /** 消息中心应用ID */
+    public static final String WFTASK_APP = "wftask";
 
     //====================================== 标品实体标识(需要小写) ======================================
     /**学历-实体标识*/
@@ -129,6 +132,8 @@ public class FormConstant {
     public static final String NCKD_HRPI_SPECWRKLOG = "nckd_hrpi_specwrklog";
     /** 员工待定调薪清单 实体标识 */
     public static final String NCKD_PENDINGSALARYADJ = "nckd_pendingsalaryadj";
+    /** 标准列表 */
+    public static final String BOS_LIST_ENTITY = "bos_list";
 
     //====================================== 标品op ======================================
     /** 确认框确认按钮 */

+ 4 - 3
code/hrmp/nckd-jxccl-hrmp/src/main/java/nckd/jxccl/hrmp/haos/plugin/operate/adminorg/AdminOrgDetailSaveOpPlugin.java

@@ -3,6 +3,7 @@ package nckd.jxccl.hrmp.haos.plugin.operate.adminorg;
 import kd.bos.dataentity.entity.DynamicObject;
 import kd.bos.dataentity.entity.DynamicObjectCollection;
 import kd.bos.entity.plugin.AbstractOperationServicePlugIn;
+import kd.bos.entity.plugin.args.BeforeOperationArgs;
 import kd.bos.entity.plugin.args.BeginOperationTransactionArgs;
 import kd.bos.orm.query.QCP;
 import kd.bos.orm.query.QFilter;
@@ -22,8 +23,8 @@ import java.util.Arrays;
 public class AdminOrgDetailSaveOpPlugin extends AbstractOperationServicePlugIn {
 
     @Override
-    public void beginOperationTransaction(BeginOperationTransactionArgs e) {
-        super.beginOperationTransaction(e);
+    public void beforeExecuteOperationTransaction(BeforeOperationArgs e) {
+        super.beforeExecuteOperationTransaction(e);
 
         DynamicObject[] dataEntities = e.getDataEntities();
         if (dataEntities != null) {
@@ -40,7 +41,7 @@ public class AdminOrgDetailSaveOpPlugin extends AbstractOperationServicePlugIn {
         DynamicObjectCollection adminOrgColl = QueryServiceHelper.query(AdminOrgConstant.ADMINORG_ENTITYID, AdminOrgConstant.ID_KEY, qFilters, AdminOrgConstant.LEVEL);
         for (int i = 0; i < AdminOrgConstant.ADMINORG_STRUCT_FIELDS.length; i++) {
             if (i < adminOrgColl.size() && adminOrgColl.get(i) != null) {
-            dataEntity.set(AdminOrgConstant.ADMINORG_STRUCT_FIELDS[i], adminOrgColl.get(i).getLong(AdminOrgConstant.ID_KEY));
+                dataEntity.set(AdminOrgConstant.ADMINORG_STRUCT_FIELDS[i], adminOrgColl.get(i).getLong(AdminOrgConstant.ID_KEY));
             } else if (i == adminOrgColl.size()) {
                 dataEntity.set(AdminOrgConstant.ADMINORG_STRUCT_FIELDS[i], dataEntity.getLong(AdminOrgConstant.ID_KEY));
             } else {

+ 29 - 0
code/hrmp/nckd-jxccl-hrmp/src/main/java/nckd/jxccl/hrmp/hbpm/business/hr/PositionBillBaseService.java

@@ -0,0 +1,29 @@
+package nckd.jxccl.hrmp.hbpm.business.hr;
+
+import kd.bos.entity.datamodel.IDataModel;
+import kd.bos.form.IFormView;
+
+/**
+ * 岗位申请单基础服务类
+ * @author: jtd
+ * @date: 2025/12/20 17:47
+ */
+public class PositionBillBaseService {
+
+    private IFormView view;
+    private IDataModel model;
+
+    public IFormView getView() {
+        return this.view;
+    }
+
+    public IDataModel getModel() {
+        return this.model;
+    }
+
+    public PositionBillBaseService(IFormView view) {
+        this.view = view;
+        this.model = this.view.getModel();
+    }
+
+}

+ 116 - 0
code/hrmp/nckd-jxccl-hrmp/src/main/java/nckd/jxccl/hrmp/hbpm/business/hr/PositionBillClosedCallBackService.java

@@ -0,0 +1,116 @@
+package nckd.jxccl.hrmp.hbpm.business.hr;
+
+import com.google.common.collect.Lists;
+import kd.bos.dataentity.entity.DynamicObject;
+import kd.bos.dataentity.metadata.IDataEntityProperty;
+import kd.bos.dataentity.metadata.IMetadata;
+import kd.bos.dataentity.metadata.clr.DataEntityPropertyCollection;
+import kd.bos.entity.EntityMetadataCache;
+import kd.bos.entity.MainEntityType;
+import kd.bos.entity.datamodel.AbstractFormDataModel;
+import kd.bos.entity.datamodel.TableValueSetter;
+import kd.bos.form.IFormView;
+import kd.bos.form.events.ClosedCallBackEvent;
+import kd.bos.orm.query.QCP;
+import kd.bos.orm.query.QFilter;
+import kd.hr.hbp.business.servicehelper.HRBaseServiceHelper;
+import nckd.jxccl.hrmp.hbpm.common.hr.PositionBillConstant;
+import nckd.jxccl.hrmp.hbpm.common.hr.PositionChangeTypeEnum;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+/**
+ * 岗位申请单关闭回调服务类
+ * @author: jtd
+ * @date: 2025/12/20 17:29
+ */
+public class PositionBillClosedCallBackService extends PositionBillBaseService {
+
+    public PositionBillClosedCallBackService(IFormView view) {
+        super(view);
+    }
+
+    public void closedCallBack(ClosedCallBackEvent closedCallBackEvent) {
+        switch (closedCallBackEvent.getActionId()) {
+            case PositionBillConstant.ADD_TAG:
+                if (onlyForView(closedCallBackEvent)) {
+                    return;
+                }
+                updateAddEntryEntity();
+                break;
+            case PositionBillConstant.CHANGE_TAG:
+
+        }
+    }
+
+    private boolean onlyForView(ClosedCallBackEvent closedCallBackEvent) {
+        return closedCallBackEvent.getReturnData() == null;
+    }
+
+    private void updateAddEntryEntity() {
+        DataEntityPropertyCollection entryEntityInfo = getModel().getDataEntity(true).getDynamicObjectCollection(PositionBillConstant.NCKD_ENTRYENTITY_ADD_KEY).getDynamicObjectType().getProperties();
+        MainEntityType entityType = EntityMetadataCache.getDataEntityType(PositionBillConstant.NCKD_POSBILLENTRYADD_ENTITY);
+        DataEntityPropertyCollection addEntityInfo = entityType.getProperties();
+        Map<String, IDataEntityProperty> addNamePropMap = addEntityInfo.stream().collect(Collectors.toMap(IMetadata::getName, Function.identity()));
+        List<String> selectPropList = new ArrayList<String>();
+        Set<String> toSetValueEntryPropList = new HashSet<String>();
+
+        String suffix = "_"+PositionBillConstant.ADD_TAG;
+        for(IDataEntityProperty iDataEntityProperty : entryEntityInfo) {
+            String entryPropName = iDataEntityProperty.getName();
+            if (entryPropName.endsWith(suffix)) {
+                String entryPropNameSub = entryPropName.replace(suffix, "");
+                if (addNamePropMap.containsKey(entryPropNameSub)) {
+                    selectPropList.add(entryPropNameSub);
+                    toSetValueEntryPropList.add(entryPropName);
+                }
+            }
+        }
+
+        toSetValueEntryPropList.add(PositionBillConstant.ID_KEY);
+        HRBaseServiceHelper posBillEntryAddServiceHelper = new HRBaseServiceHelper(PositionBillConstant.NCKD_POSBILLENTRYADD_ENTITY);
+        Long billId = getModel().getDataEntity().getLong(PositionBillConstant.ID_KEY);
+        QFilter qFilter = (new QFilter(PositionBillConstant.NCKD_BILLID, QCP.equals, billId)).and(new QFilter(String.join(".", PositionBillConstant.NCKD_CHANGETYPE, PositionBillConstant.NUMBER_KEY), QCP.equals, PositionChangeTypeEnum.ADD.getNumber()));
+        DynamicObject[] addPositionDyArr = posBillEntryAddServiceHelper.load(String.join(",", selectPropList), qFilter.toArray(), PositionBillConstant.NCKD_SEQUENCE);
+
+        getModel().deleteEntryData(PositionBillConstant.NCKD_ENTRYENTITY_ADD_KEY);
+        TableValueSetter vs = new TableValueSetter();
+        toSetValueEntryPropList.forEach((prop) -> vs.addField(prop, new Object[0]));
+
+        for(DynamicObject addPositionDy : addPositionDyArr) {
+            List<Object> values = Lists.newArrayListWithCapacity(addPositionDyArr.length);
+
+            for(String entryPropName : toSetValueEntryPropList) {
+                if (entryPropName.equals(PositionBillConstant.ID_KEY)) {
+                    values.add(addPositionDy.getLong(PositionBillConstant.ID_KEY));
+                } else if (entryPropName.equals(PositionBillConstant.NCKD_NUMBER_KEY)) {
+                    values.add(addPositionDy.get(PositionBillConstant.NUMBER_KEY));
+                } else if (entryPropName.equals(PositionBillConstant.NCKD_NAME_KEY)) {
+                    values.add(addPositionDy.get(PositionBillConstant.NAME_KEY));
+                }else {
+                    String propName = entryPropName.replace(suffix, "");
+                    if (addPositionDy.get(propName) instanceof DynamicObject) {
+                        values.add(((DynamicObject)addPositionDy.get(propName)).getLong(PositionBillConstant.ID_KEY));
+                    } else {
+                        values.add(addPositionDy.get(propName));
+                    }
+                }
+            }
+
+            vs.addRow(values.toArray());
+        }
+
+        AbstractFormDataModel model = (AbstractFormDataModel) getModel();
+        model.beginInit();
+        model.batchCreateNewEntryRow(PositionBillConstant.NCKD_ENTRYENTITY_ADD_KEY, vs);
+        model.endInit();
+        getView().updateView(PositionBillConstant.NCKD_ENTRYENTITY_ADD_KEY);
+    }
+
+}

+ 148 - 0
code/hrmp/nckd-jxccl-hrmp/src/main/java/nckd/jxccl/hrmp/hbpm/business/hr/PositionBillConfirmCallBackService.java

@@ -0,0 +1,148 @@
+package nckd.jxccl.hrmp.hbpm.business.hr;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+import kd.bos.dataentity.entity.DynamicObject;
+import kd.bos.dataentity.entity.DynamicObjectCollection;
+import kd.bos.entity.operate.result.OperateErrorInfo;
+import kd.bos.entity.operate.result.OperationResult;
+import kd.bos.entity.validate.ErrorLevel;
+import kd.bos.form.IFormView;
+import kd.bos.form.MessageBoxResult;
+import kd.bos.form.control.EntryGrid;
+import kd.bos.form.events.MessageBoxClosedEvent;
+import kd.bos.orm.query.QCP;
+import kd.bos.orm.query.QFilter;
+import kd.hr.hbp.business.servicehelper.HRBaseServiceHelper;
+import nckd.jxccl.hrmp.hbpm.common.hr.PositionBillConstant;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Locale;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/**
+ * 岗位申请单确认回调服务类
+ * @author: jtd
+ * @date: 2025/12/21 21:59
+ */
+public class PositionBillConfirmCallBackService extends PositionBillBaseService {
+
+    public PositionBillConfirmCallBackService(IFormView view) {
+        super(view);
+    }
+
+    public void confirmCallBack(MessageBoxClosedEvent event) {
+        String callBackId = event.getCallBackId();
+        if (callBackId.startsWith(PositionBillConstant.DELETE_ROWS_PREFIX)) {
+            if (event.getResult() == MessageBoxResult.Cancel) {
+                return;
+            }
+
+            EntryGrid coopRelEntryGrid = getView().getControl(PositionBillConstant.NCKD_ENTRYENTITY_ADD_KEY);
+            int[] selectRows = coopRelEntryGrid.getSelectRows();
+            HRBaseServiceHelper hrBaseServiceHelper = new HRBaseServiceHelper(PositionBillConstant.NCKD_POSITIONBILLENTRY_ENTITY);
+            List<Long> entryIdList = Lists.newArrayListWithExpectedSize(selectRows.length);
+            if (PositionBillConstant.DELETE_ROWS_ADD_OP.equals(callBackId)) {
+                List<Long> positionIds = Lists.newArrayListWithExpectedSize(selectRows.length);
+                int[] deleteRows = validateHasChildOrgAndDelete();
+                if (deleteRows.length == 0) {
+                    return;
+                }
+
+                for(int i = 0; i < deleteRows.length; ++i) {
+                    int row = deleteRows[i];
+                    entryIdList.add(getModel().getEntryEntity(PositionBillConstant.NCKD_ENTRYENTITY_ADD_KEY).get(row).getLong(PositionBillConstant.ID_KEY));
+                    positionIds.add(getModel().getEntryEntity(PositionBillConstant.NCKD_ENTRYENTITY_ADD_KEY).get(row).getLong(String.join("_", PositionBillConstant.NCKD_POSITION, PositionBillConstant.ADD_TAG)));
+                }
+
+                getModel().deleteEntryRows(PositionBillConstant.NCKD_ENTRYENTITY_ADD_KEY, deleteRows);
+                PositionBillServiceHelper.delAddMaster(positionIds);
+            } else if (PositionBillConstant.DELETE_ROWS_CHANGE_OP.equals(callBackId)) {
+                entryIdList = getModel().getEntryEntity(PositionBillConstant.NCKD_ENTRYENTITY_CHANGE_KEY).stream().map((entry) -> entry.getLong(PositionBillConstant.ID_KEY)).collect(Collectors.toList());
+                getModel().deleteEntryRows(PositionBillConstant.NCKD_ENTRYENTITY_CHANGE_KEY, selectRows);
+            }
+
+            getView().showSuccessNotification("删除成功");
+            hrBaseServiceHelper.delete(entryIdList.toArray(new Long[0]));
+        }
+    }
+
+    private int[] validateHasChildOrgAndDelete() {
+        EntryGrid strategyEntryGrid = getView().getControl(PositionBillConstant.NCKD_ENTRYENTITY_ADD_KEY);
+        int[] rows = strategyEntryGrid.getSelectRows();
+        // 要删除的岗位
+        List<Long> toBeDeletePositionIdList = Lists.newArrayListWithExpectedSize(rows.length);
+        List<DynamicObject> toBeDeletePositionDynList = Lists.newArrayListWithExpectedSize(rows.length);
+        // 新增岗位单据体中未选中的岗位数据,视作上级岗位,避免新增岗位中的上级岗位选择了该单据体中的其他未被选中的岗位
+        List<Long> otherPositionIdList = Lists.newArrayListWithExpectedSize(rows.length);
+        int count = getModel().getEntryEntity(PositionBillConstant.NCKD_ENTRYENTITY_ADD_KEY).getRowCount();
+        List<Integer> rowList = Arrays.stream(rows).boxed().collect(Collectors.toList());
+
+        // 岗位标识-新增岗位
+        String positionAddKey = String.join("_", PositionBillConstant.NCKD_POSITION, PositionBillConstant.ADD_TAG);
+        for(int i = 0; i < count; ++i) {
+            DynamicObject dynamicObject = getModel().getEntryEntity(PositionBillConstant.NCKD_ENTRYENTITY_ADD_KEY).get(i);
+            long positionId = dynamicObject.getLong(positionAddKey);
+            if (rowList.contains(i)) {
+                toBeDeletePositionIdList.add(positionId);
+                toBeDeletePositionDynList.add(dynamicObject);
+            } else {
+                otherPositionIdList.add(positionId);
+            }
+        }
+
+        HRBaseServiceHelper positionServiceHelper = new HRBaseServiceHelper(PositionBillConstant.HBPM_POSITIONHR);
+        // 获取变更信息单据体中岗位的上级岗位
+        DynamicObjectCollection parentEntryEntity = getModel().getEntryEntity(PositionBillConstant.NCKD_ENTRYENTITY_CHANGE_KEY);
+        List<Long> positionParentIdList = parentEntryEntity.stream().map((entryEntity) -> entryEntity.getLong(String.format("%s_%s.%s",  PositionBillConstant.NCKD_PARENT, PositionBillConstant.CHANGE_TAG, PositionBillConstant.ID_KEY))).collect(Collectors.toList());
+        QFilter idFilter = new QFilter(PositionBillConstant.ID_KEY, QCP.in, positionParentIdList);
+        DynamicObject[] positionParentDyns = positionServiceHelper.query(String.join(",", PositionBillConstant.ID_KEY, PositionBillConstant.BOID_KEY), new QFilter[]{idFilter});
+        Set<Long> parentPositionBoIdList = Arrays.stream(positionParentDyns).map((dyn) -> dyn.getLong(PositionBillConstant.BOID_KEY)).collect(Collectors.toSet());
+        // 要校验的上级岗位数据包含变更信息中岗位的上级岗位和新增岗位单据体中未被选中的岗位的上级岗位
+        parentPositionBoIdList.addAll(otherPositionIdList);
+        // 不能被删除的岗位
+        Set<Long> doNotdeletePositionIdSet = Sets.newHashSetWithExpectedSize(toBeDeletePositionIdList.size());
+
+        // 判断要删除的岗位是否为其他岗位的上级岗位
+        for(Long toBeDeletePositionId : toBeDeletePositionIdList) {
+           if (parentPositionBoIdList.contains(toBeDeletePositionId)) {
+                doNotdeletePositionIdSet.add(toBeDeletePositionId);
+            }
+        }
+
+        OperationResult operationResult = new OperationResult();
+        operationResult.setSuccess(true);
+        operationResult.setBillCount(rows.length);
+
+        for(DynamicObject toBeDeletePositionDyn : toBeDeletePositionDynList) {
+            long toBeDeletePositionId = toBeDeletePositionDyn.getLong(positionAddKey);
+            if (doNotdeletePositionIdSet.contains(toBeDeletePositionId)) {
+                OperateErrorInfo operateInfo = new OperateErrorInfo("100000", ErrorLevel.Error, toBeDeletePositionId);
+                operateInfo.setErrorLevel(ErrorLevel.FatalError.name());
+                operateInfo.setMessage(String.format(Locale.ROOT, "%s在本单有下层组织,不允许删除。", toBeDeletePositionDyn.getString(String.join("_", PositionBillConstant.NCKD_NAME_KEY, PositionBillConstant.ADD_TAG))));
+                operationResult.setSuccess(false);
+                operationResult.addErrorInfo(operateInfo);
+            } else {
+                operationResult.addSuccessPkId(toBeDeletePositionId);
+            }
+        }
+
+        if (!operationResult.isSuccess()) {
+            getView().showOperationResult(operationResult, "删除");
+        }
+
+        List<Integer> deleteRowIndexList = Lists.newArrayListWithExpectedSize(toBeDeletePositionDynList.size());
+        DynamicObjectCollection addEntryEntity = getModel().getEntryEntity(PositionBillConstant.NCKD_ENTRYENTITY_ADD_KEY);
+
+        for(int i = 0; i < addEntryEntity.size(); ++i) {
+            long positionId = addEntryEntity.get(i).getLong(positionAddKey);
+            if (toBeDeletePositionIdList.contains(positionId) && !doNotdeletePositionIdSet.contains(positionId)) {
+                deleteRowIndexList.add(i);
+            }
+        }
+
+        return deleteRowIndexList.stream().mapToInt(Integer::intValue).toArray();
+    }
+}

+ 100 - 47
code/hrmp/nckd-jxccl-hrmp/src/main/java/nckd/jxccl/hrmp/hbpm/business/hr/PositionBillService.java → code/hrmp/nckd-jxccl-hrmp/src/main/java/nckd/jxccl/hrmp/hbpm/business/hr/PositionBillServiceHelper.java

@@ -1,57 +1,56 @@
 package nckd.jxccl.hrmp.hbpm.business.hr;
 
-import com.google.common.collect.Maps;
 import com.kingdee.util.StringUtils;
 import kd.bos.bill.BillShowParameter;
 import kd.bos.bill.OperationStatus;
+import kd.bos.common.enums.EnableEnum;
 import kd.bos.dataentity.entity.DynamicObject;
+import kd.bos.entity.constant.StatusEnum;
 import kd.bos.entity.datamodel.IDataModel;
 import kd.bos.form.CloseCallBack;
 import kd.bos.form.IFormView;
 import kd.bos.form.ShowType;
 import kd.bos.form.control.EntryGrid;
-import kd.bos.list.ListShowParameter;
-import kd.bos.org.utils.DynamicObjectUtils;
 import kd.bos.orm.query.QCP;
 import kd.bos.orm.query.QFilter;
 import kd.bos.servicehelper.MetadataServiceHelper;
 import kd.hr.hbp.business.servicehelper.HRBaseServiceHelper;
+import kd.hr.hbp.common.constants.history.HisModelDataStatusEnum;
 import kd.hr.hbp.common.util.HRDateTimeUtils;
+import kd.hr.hbp.common.util.HRDynamicObjectUtils;
 import kd.hr.hbp.common.util.HRStringUtils;
 import kd.sdk.hr.hdm.common.enums.reg.RegBillStatusEnum;
+import nckd.jxccl.base.common.utils.QueryFieldBuilder;
 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.stream.Collectors;
 
 /**
- * 岗位申请单服务
+ * 岗位申请单帮组
  * @author: jtd
  * @date: 2025-10-31 14:33
  */
-public class PositionBillService {
-
-    private static final Map<String, String> changeTypeToLocaleMap = Maps.newHashMapWithExpectedSize(2);
-
-    static {
-        changeTypeToLocaleMap.put("add", "新增岗位");
-        changeTypeToLocaleMap.put("change", "变更信息");
-    }
+public class PositionBillServiceHelper {
 
     /**
      * 获取分录序号
      * @param iDataModel
-     * @param changeType
+     * @param changeTypeNumber
      * @return
      */
-    public static int getEntrySeq(IDataModel iDataModel, Long changeType) {
+    public static int getEntrySeq(IDataModel iDataModel, String changeTypeNumber) {
         Long billId = iDataModel.getDataEntity().getLong(PositionBillConstant.ID_KEY);
-        HRBaseServiceHelper hrBaseServiceHelper = new HRBaseServiceHelper(PositionBillConstant.NCKD_POSITIONBILLENTRY);
+        HRBaseServiceHelper positionBillEntryServiceHelper = new HRBaseServiceHelper(PositionBillConstant.NCKD_POSITIONBILLENTRY_ENTITY);
         QFilter qFilter = new QFilter(PositionBillConstant.NCKD_BILLID, QCP.equals, billId);
-        qFilter.and(PositionBillConstant.NCKD_CHANGETYPE, QCP.equals, changeType);
-        String selectProps = String.join(",", new String[]{PositionBillConstant.ID_KEY, PositionBillConstant.NCKD_SEQUENCE});
+        qFilter.and(String.join(".", PositionBillConstant.NCKD_CHANGETYPE, PositionBillConstant.NUMBER_KEY), QCP.equals, changeTypeNumber);
+        String selectProps = String.join(",", PositionBillConstant.ID_KEY, PositionBillConstant.NCKD_SEQUENCE);
         String order = String.format("%s desc", PositionBillConstant.NCKD_SEQUENCE);
-        DynamicObject dynamicObject = hrBaseServiceHelper.queryOne(selectProps, qFilter.toArray(), order);
+        DynamicObject dynamicObject = positionBillEntryServiceHelper.queryOne(selectProps, qFilter.toArray(), order);
         return dynamicObject == null ? 1 : dynamicObject.getInt(PositionBillConstant.NCKD_SEQUENCE) + 1;
     }
 
@@ -62,16 +61,16 @@ public class PositionBillService {
      * @param pluginName
      */
     public static void openViewForm(IFormView iFormView, String operation, String pluginName) {
-        if (iFormView.getModel().getValue("org") == null) {// 179
+        if (iFormView.getModel().getValue(PositionBillConstant.ORG_KEY) == null) {
             iFormView.showTipNotification("请先填写组织体系管理组织。");
         } else {
-            HRBaseServiceHelper positionBillHelper = new HRBaseServiceHelper(PositionBillConstant.NCKD_POSITIONBILL);
+            HRBaseServiceHelper positionBillHelper = new HRBaseServiceHelper(PositionBillConstant.NCKD_POSITIONBILL_ENTITY);
             QFilter idFilter = new QFilter(PositionBillConstant.ID_KEY, "=", iFormView.getModel().getDataEntity().getLong(PositionBillConstant.ID_KEY));
             DynamicObject dynamicObject = positionBillHelper.loadDynamicObject(idFilter);
             if (dynamicObject != null) {
                 String billStatus = dynamicObject.getString(PositionBillConstant.BILL_STATUS_KEY);
-                if (!billStatus.equals(RegBillStatusEnum.TEMPSTORAGE.getCode()) && !billStatus.equals(RegBillStatusEnum.WAITRESUBMIT.getCode()) && !billStatus.equals(RegBillStatusEnum.APPROVING.getCode()) && (!billStatus.equals(RegBillStatusEnum.ALREADYSUBMIT.getCode()) || !StringUtils.equals(iFormView.getFormShowParameter().getAppId(), "wftask"))) {
-                    String operateLocaleName = changeTypeToLocaleMap.get(operation);
+                if (!billStatus.equals(RegBillStatusEnum.TEMPSTORAGE.getCode()) && !billStatus.equals(RegBillStatusEnum.WAITRESUBMIT.getCode()) && !billStatus.equals(RegBillStatusEnum.APPROVING.getCode()) && (!billStatus.equals(RegBillStatusEnum.ALREADYSUBMIT.getCode()) || !StringUtils.equals(iFormView.getFormShowParameter().getAppId(), PositionBillConstant.WFTASK_APP))) {
+                    String operateLocaleName = PositionChangeTypeEnum.getTipByTag(operation);
                     String auditstatusName = RegBillStatusEnum.getName(dynamicObject.getString(PositionBillConstant.BILL_STATUS_KEY));
                     iFormView.showErrorNotification(String.format("“%1$s”的单据不能“%2$s”。", auditstatusName, operateLocaleName));
                     return;
@@ -80,27 +79,69 @@ public class PositionBillService {
 
             BillShowParameter formShowParameter = new BillShowParameter();
             switch (operation) {
-                case PositionBillConstant.NEWENTRY_ADD:
-                    formShowParameter.setFormId(PositionBillConstant.NCKD_POSBILLENTRYADD);
+                case PositionBillConstant.ADD_TAG:
+                    formShowParameter.setFormId(PositionBillConstant.NCKD_POSBILLENTRYADD_ENTITY);
                     break;
-                case PositionBillConstant.NEWENTRY_CHANGE:
-                    formShowParameter.setFormId(PositionBillConstant.NCKD_POSBILLENTRYCHANGE);
+                case PositionBillConstant.CHANGE_TAG:
+                    formShowParameter.setFormId(PositionBillConstant.NCKD_POSBILLENTRYCHANGE_ENTITY);
             }
             formShowParameter.setCustomParam("position_bsed", iFormView.getModel().getValue(PositionBillConstant.NCKD_EFFDT) == null ? HRDateTimeUtils.getNowDateTime().getTime() : ((Date)iFormView.getModel().getValue(PositionBillConstant.NCKD_EFFDT)).getTime());
             formShowParameter.getOpenStyle().setShowType(ShowType.Modal);
             formShowParameter.setCustomParam("billid", iFormView.getModel().getDataEntity().getLong(PositionBillConstant.ID_KEY));
             formShowParameter.setCustomParam("billBsed", iFormView.getModel().getDataEntity().getDate(PositionBillConstant.NCKD_EFFDT));
             formShowParameter.setCloseCallBack(new CloseCallBack(pluginName, operation));
-            if (HRStringUtils.equals(iFormView.getFormShowParameter().getAppId(), "wftask")) {
+            if (HRStringUtils.equals(iFormView.getFormShowParameter().getAppId(), PositionBillConstant.WFTASK_APP)) {
                 formShowParameter.setHasRight(true);
             }
             formShowParameter.setCustomParam("org", iFormView.getModel().getDataEntity().getLong(String.join(".", PositionBillConstant.ORG_KEY, PositionBillConstant.ID_KEY)));
-            int sequence = getEntrySeq(iFormView.getModel(), PositionBillConstant.CHANGE_TYPE_ADD);
+            int sequence = getEntrySeq(iFormView.getModel(), PositionChangeTypeEnum.ADD.getNumber());
             formShowParameter.setCustomParam("sequence", sequence);
             iFormView.showForm(formShowParameter);
         }
     }
 
+    public static void delAddMaster(List<Long> positionIdList) {
+        HRBaseServiceHelper positionHrHelper = new HRBaseServiceHelper(PositionBillConstant.HBPM_POSITIONHR);
+        positionHrHelper.deleteByFilter(new QFilter[]{new QFilter(PositionBillConstant.ID_KEY, QCP.in, positionIdList)});
+    }
+
+    public static Map<String, String> getTransKeyMap() {
+        // 查询需要转换的键值
+        String selectFields = QueryFieldBuilder.create().add(PositionBillConstant.NUMBER_KEY).add(PositionBillConstant.NAME_KEY).buildSelect();
+        DynamicObject[] transKeyDyos = HRBaseServiceHelper.create(PositionBillConstant.NCKD_POSITION_TRANSKEY_ENTITY).queryOriginalArray(selectFields, null);
+        // key->目标字段 value->源字段
+        Map<String, String> transKeyMap = Arrays.stream(transKeyDyos).collect(Collectors.toMap(transKeyDyo -> transKeyDyo.getString(PositionBillConstant.NAME_KEY), transKeyDyo -> transKeyDyo.getString(PositionBillConstant.NUMBER_KEY), (oldValue, newValue) -> newValue));
+        return transKeyMap;
+    }
+
+    public static DynamicObject getPositionHrDy(DynamicObject addDy) {
+        return getPositionHrDy(addDy, getTransKeyMap());
+    }
+
+    public static DynamicObject getPositionHrDy(DynamicObject addDy, Map<String, String> transKeyMap) {
+        DynamicObject positionHrDy = new DynamicObject(MetadataServiceHelper.getDataEntityType(PositionBillConstant.HBPM_POSITIONHR));
+        // 将表单中的信息赋值到岗位信息中
+        HRDynamicObjectUtils.copy(addDy, positionHrDy, transKeyMap);
+        // 设置 行政组织
+        positionHrDy.set(PositionBillConstant.ADMINORG, HRBaseServiceHelper.create(PositionBillConstant.ADMINORG_ENTITYID).loadSingle(addDy.getLong(PositionBillConstant.NCKD_ADMINORGBOID_KEY)));
+        // 设置 上级岗位
+        DynamicObject parentPositionVersionDy = addDy.getDynamicObject(PositionBillConstant.NCKD_PARENT);
+        if (parentPositionVersionDy != null) {
+            positionHrDy.set(PositionBillConstant.PARENT_KEY, HRBaseServiceHelper.create(PositionBillConstant.HBPM_POSITIONHR).loadSingle(parentPositionVersionDy.getLong(PositionBillConstant.BOID_KEY)));
+        } else {
+            positionHrDy.set(PositionBillConstant.PARENT_KEY, null);
+        }
+        // 设置 数据状态
+        positionHrDy.set(PositionBillConstant.STATUS, StatusEnum.A);
+        // 设置 业务状态
+        positionHrDy.set(PositionBillConstant.ENABLE, EnableEnum.YES.getCode());
+        // 设置 是否标准岗位
+        positionHrDy.set(PositionBillConstant.ISSTANDARDPOS_KEY, EnableEnum.NO.getCode());
+        // 设置 数据版本状态
+        positionHrDy.set(PositionBillConstant.DATA_STATUS, HisModelDataStatusEnum.TEMP.getStatus());
+        return positionHrDy;
+    }
+
     public static void entryEntityMore(IDataModel iDataModel, IFormView iFormView, String tag, OperationStatus status, String pluginName) {
         /*EntryGrid entryEntity = iFormView.getControl(ENTRY_ENTITY_PREFIX + tag);
         int row = entryEntity.getEntryState().getFocusRow();
@@ -140,37 +181,49 @@ public class PositionBillService {
         Long id = dynamicObject.getLong(PositionBillConstant.ID_KEY);
         BillShowParameter formShowParameter = new BillShowParameter();
         formShowParameter.setCustomParam("position_bsed", iFormView.getModel().getValue(PositionBillConstant.NCKD_EFFDT) == null ? HRDateTimeUtils.getNowDateTime().getTime() : ((Date)iFormView.getModel().getValue(PositionBillConstant.NCKD_EFFDT)).getTime());
-        if ("add".equals(tag)) {
-            formShowParameter.setFormId(PositionBillConstant.NCKD_POSBILLENTRYADD);
-        } else if ("change".equals(tag)) {
-            formShowParameter.setFormId(PositionBillConstant.NCKD_POSBILLENTRYCHANGE);
+        if (PositionBillConstant.ADD_TAG.equals(tag)) {
+            formShowParameter.setFormId(PositionBillConstant.NCKD_POSBILLENTRYADD_ENTITY);
+        } else if (PositionBillConstant.CHANGE_TAG.equals(tag)) {
+            formShowParameter.setFormId(PositionBillConstant.NCKD_POSBILLENTRYCHANGE_ENTITY);
         }
         formShowParameter.setPkId(id);
         formShowParameter.setStatus(status);
-        if (HRStringUtils.equals(iFormView.getFormShowParameter().getAppId(), "wftask")) {
+        if (HRStringUtils.equals(iFormView.getFormShowParameter().getAppId(), PositionBillConstant.WFTASK_APP)) {
             formShowParameter.setHasRight(true);
         }
 
         if (!status.equals(OperationStatus.VIEW)) {
-            formShowParameter.setCloseCallBack(new CloseCallBack(pluginName, entryEntityId));
+            formShowParameter.setCloseCallBack(new CloseCallBack(pluginName, tag));
         }
         formShowParameter.getOpenStyle().setShowType(ShowType.Modal);
         iFormView.showForm(formShowParameter);
     }
 
+    public static void openEditPage(IDataModel iDataModel, IFormView iFormView, String tag, OperationStatus status) {
+        String entryEntityKey = String.join("_", PositionBillConstant.NCKD_ENTRYENTITY, tag);
+        EntryGrid strategyEntryGrid = iFormView.getControl(entryEntityKey);
+        int row = strategyEntryGrid.getEntryState().getFocusRow();
+        DynamicObject dynamicObject = iDataModel.getDataEntity(true).getDynamicObjectCollection(entryEntityKey).get(row);
+        Long id = dynamicObject.getLong(PositionBillConstant.ID_KEY);
+        BillShowParameter formShowParameter = new BillShowParameter();
+        if (PositionBillConstant.ADD_TAG.equals(tag)) {
+            formShowParameter.setFormId(PositionBillConstant.NCKD_POSBILLENTRYADD_ENTITY);
+        } else if (PositionBillConstant.CHANGE_TAG.equals(tag)) {
+            formShowParameter.setFormId(PositionBillConstant.NCKD_POSBILLENTRYCHANGE_ENTITY);
+        }
+        formShowParameter.setCustomParam("position_bsed", iDataModel.getValue(PositionBillConstant.NCKD_EFFDT) == null ? HRDateTimeUtils.getNowDateTime().getTime() : ((Date) iDataModel.getValue(PositionBillConstant.NCKD_EFFDT)).getTime());
+        formShowParameter.setPkId(id);
+        formShowParameter.setStatus(status);
+        formShowParameter.setCustomParam("billid", iDataModel.getDataEntity().getLong(PositionBillConstant.ID_KEY));
+        if (HRStringUtils.equals(iFormView.getFormShowParameter().getAppId(), PositionBillConstant.WFTASK_APP)) {
+            formShowParameter.setHasRight(true);
+        }
 
-    /**
-     * 获取岗位信息维护对象
-     * @param addDy
-     * @return
-     */
-    public static DynamicObject getPositionHrDy(DynamicObject addDy) {
-        DynamicObject positionHrDy = new DynamicObject(MetadataServiceHelper.getDataEntityType(PositionBillConstant.HBPM_POSITIONHR));
-        DynamicObjectUtils.copy(addDy, positionHrDy);
-        positionHrDy.set("id", addDy.getLong(PositionBillConstant.ID_KEY));
-        positionHrDy.set("parent", addDy.get(PositionBillConstant.NCKD_PARENT));
-        positionHrDy.set("adminorg", addDy.get(PositionBillConstant.NCKD_ADMINORG));
-        return positionHrDy;
-    }
+        if (!status.equals(OperationStatus.VIEW)) {
+            formShowParameter.setCloseCallBack(new CloseCallBack("nckd.jxccl.hrmp.hbpm.plugin.form.hr.PositionBillFormPlugin", tag));
+        }
 
+        formShowParameter.getOpenStyle().setShowType(ShowType.Modal);
+        iFormView.showForm(formShowParameter);
+    }
 }

+ 36 - 36
code/hrmp/nckd-jxccl-hrmp/src/main/java/nckd/jxccl/hrmp/hbpm/common/hr/PositionBillConstant.java

@@ -2,9 +2,6 @@ package nckd.jxccl.hrmp.hbpm.common.hr;
 
 import nckd.jxccl.base.common.constant.FormConstant;
 
-import java.util.HashMap;
-import java.util.Map;
-
 /**
  * 岗位申请常量
  * @author: jtd
@@ -16,46 +13,38 @@ public class PositionBillConstant extends FormConstant {
     public static final String NCKD_HBPM_POSORGTREELISTF_ENTITY = "nckd_hbpm_posorgtreelistf";
     /** 岗位信息键值转换实体标识 */
     public static final String NCKD_POSITION_TRANSKEY_ENTITY = "nckd_position_transkey";
+    /** 行政组织树实体标识 */
+    public static final String HAOS_ORGTREELISTF7_ENTITY = "haos_orgtreelistf7";
+    /** 岗位申请单实体标识 */
+    public static final String NCKD_POSITIONBILL_ENTITY = "nckd_positionbill";
+    /** 岗位申请单分录实体标识 */
+    public static final String NCKD_POSITIONBILLENTRY_ENTITY = "nckd_positionbillentry";
+    /** 岗位申请-新增岗位实体标识 */
+    public static final String NCKD_POSBILLENTRYADD_ENTITY = "nckd_posbillentryadd";
+    /** 岗位申请-变更信息实体标识 */
+    public static final String NCKD_POSBILLENTRYCHANGE_ENTITY = "nckd_posbillentrychange";
+
+    /** 新增标识 */
+    public static final String ADD_TAG = "add";
+    /** 变更标识 */
+    public static final String CHANGE_TAG = "change";
 
-    /** 行政组织树表单ID */
-    public static final String HAOS_ORGTREELISTF7 = "haos_orgtreelistf7";
-    /** 岗位变动类型表单ID */
-    public static final String NCKD_POSITION_CHANGETYPE = "nckd_position_changetype";
     /** 变动类型 */
     public static final String NCKD_CHANGETYPE = "nckd_changetype";
-    /** 变动类型-岗位新设 */
-    public static final Long CHANGE_TYPE_ADD = 1010L;
-    /** 变动类型-岗位变更 */
-    public static final Long CHANGE_TYPE_CHANGE = 1020L;
-    /** 变动类型Map */
-    public static final Map<String, Long> CHANGE_TYPE_MAP = new HashMap(){{
-        put("add", CHANGE_TYPE_ADD);
-        put("change", CHANGE_TYPE_CHANGE);
-    }};
-    /** 岗位信息维护表单ID */
-    public static final String HBPM_POSITIONHR = "hbpm_positionhr";
-    /** 岗位申请单表单ID */
-    public static final String NCKD_POSITIONBILL = "nckd_positionbill";
-    /** 岗位申请单分录表单ID */
-    public static final String NCKD_POSITIONBILLENTRY = "nckd_positionbillentry";
-    /** 岗位申请-新增岗位表单ID */
-    public static final String NCKD_POSBILLENTRYADD = "nckd_posbillentryadd";
-    /** 岗位申请-变更信息表单ID */
-    public static final String NCKD_POSBILLENTRYCHANGE = "nckd_posbillentrychange";
-    /** 岗位职责分录ID */
-    public static final String NCKD_POSDUTYENTRYENTITY = "nckd_posdutyentryentity";
     /** 新增分录-岗位新设OP */
-    public static final String NEWENTRY_ADD = "newentry_add";
+    public static final String NEWENTRY_ADD_OP = "newentry_add";
     /** 新增分录-岗位变更OP */
-    public static final String NEWENTRY_CHANGE = "newentry_change";
-    /** 删除分录-岗位新设OP */
-    public static final String DELETEENTRY_ADD = "deleteentry_add";
-    /** 删除分录-岗位变更OP */
-    public static final String DELETEENTRY_CHANGE = "deleteentry_change";
+    public static final String NEWENTRY_CHANGE_OP = "newentry_change";
+    /** 分录删多行-前缀 */
+    public static final String DELETE_ROWS_PREFIX = "delete_rows_";
+    /** 分录删多行-新增OP */
+    public static final String DELETE_ROWS_ADD_OP = DELETE_ROWS_PREFIX+ADD_TAG;
+    /** 分录删多行-变更OP */
+    public static final String DELETE_ROWS_CHANGE_OP = DELETE_ROWS_PREFIX+CHANGE_TAG;
     /** 编辑-岗位新设OP */
-    public static final String EDIT_ADD = "edit_add";
+    public static final String EDIT_ADD_OP = "edit_add";
     /** 编辑-岗位变更OP */
-    public static final String EDIT_CHANGE = "edit_change";
+    public static final String EDIT_CHANGE_OP = "edit_change";
     /** 岗位申请单内码 */
     public static final String NCKD_BILLID = "nckd_billid";
     /** 生效日期 */
@@ -82,4 +71,15 @@ public class PositionBillConstant extends FormConstant {
     public static final String NCKD_ADMINORGBOID_KEY = "nckd_adminorgboid";
     /** 岗位业务ID */
     public static final String NCKD_POSITIONBOID_KEY = "nckd_positionboid";
+    /** 单据体-新增岗位 */
+    public static final String NCKD_ENTRYENTITY_ADD_KEY = "nckd_entryentity_add";
+    /** 单据体-变更信息 */
+    public static final String NCKD_ENTRYENTITY_CHANGE_KEY = "nckd_entryentity_change";
+    /** 岗位职责分录 */
+    public static final String NCKD_POSDUTY_ENTRY_ENTITY_KEY = "nckd_posduty_entry";
+    /** 编码 */
+    public static final String NCKD_NUMBER_KEY = "nckd_number";
+    /** 名称 */
+    public static final String NCKD_NAME_KEY = "nckd_name";
+
 }

+ 65 - 0
code/hrmp/nckd-jxccl-hrmp/src/main/java/nckd/jxccl/hrmp/hbpm/common/hr/PositionChangeTypeEnum.java

@@ -0,0 +1,65 @@
+package nckd.jxccl.hrmp.hbpm.common.hr;
+
+import kd.hr.hbp.common.util.HRStringUtils;
+
+/**
+ * 岗位变动类型枚举
+ * @author: jtd
+ * @date: 2025/12/20 16:42
+ */
+public enum PositionChangeTypeEnum {
+    ADD("1010", "岗位新设", PositionBillConstant.ADD_TAG, "新增岗位"),
+    CHANGE("1020", "岗位变更", PositionBillConstant.CHANGE_TAG, "变更信息");
+
+    private String number;
+    private String name;
+    private String tag;
+    private String tip;
+
+    private PositionChangeTypeEnum(String number, String name, String tag, String tip) {
+        this.number = number;
+        this.name = name;
+        this.tag = tag;
+        this.tip = tip;
+    }
+
+    public static String getNumberByTag(String tag) {
+        if (tag == null) {
+            return null;
+        }
+        for (PositionChangeTypeEnum value : values()) {
+            if (HRStringUtils.equals(value.getTag(), tag)) {
+                return value.getNumber();
+            }
+        }
+        return null;
+    }
+
+    public static String getTipByTag(String tag) {
+        if (tag == null) {
+            return null;
+        }
+        for (PositionChangeTypeEnum value : values()) {
+            if (HRStringUtils.equals(value.getTag(), tag)) {
+                return value.getTip();
+            }
+        }
+        return null;
+    }
+
+    public String getNumber() {
+        return number;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public String getTag() {
+        return tag;
+    }
+
+    public String getTip() {
+        return tip;
+    }
+}

+ 107 - 88
code/hrmp/nckd-jxccl-hrmp/src/main/java/nckd/jxccl/hrmp/hbpm/plugin/form/hr/PosBillEntryAddFormPlugin.java

@@ -1,7 +1,9 @@
 package nckd.jxccl.hrmp.hbpm.plugin.form.hr;
 
 import kd.bos.common.enums.EnableEnum;
+import kd.bos.dataentity.entity.DataEntityState;
 import kd.bos.dataentity.entity.DynamicObject;
+import kd.bos.dataentity.metadata.dynamicobject.DynamicProperty;
 import kd.bos.dataentity.utils.ObjectUtils;
 import kd.bos.dataentity.utils.StringUtils;
 import kd.bos.entity.datamodel.events.PropertyChangedArgs;
@@ -20,8 +22,9 @@ import kd.bos.orm.query.QCP;
 import kd.bos.orm.query.QFilter;
 import kd.bos.servicehelper.coderule.CodeRuleServiceHelper;
 import kd.hr.hbp.business.servicehelper.HRBaseServiceHelper;
+import kd.hr.hbp.common.util.HRObjectUtils;
 import kd.hr.hbp.common.util.HRStringUtils;
-import nckd.jxccl.hrmp.hbpm.business.hr.PositionBillService;
+import nckd.jxccl.hrmp.hbpm.business.hr.PositionBillServiceHelper;
 import nckd.jxccl.hrmp.hbpm.common.hr.PositionBillConstant;
 
 import java.util.Date;
@@ -65,7 +68,7 @@ public class PosBillEntryAddFormPlugin extends AbstractFormPlugin {
 
         // 设置岗位编码
         if (HRStringUtils.isEmpty(getModel().getDataEntity().getString(PositionBillConstant.NUMBER_KEY))) {
-            setPositionNumber(PositionBillService.getPositionHrDy(getModel().getDataEntity()));
+            setPositionNumber(PositionBillServiceHelper.getPositionHrDy(getModel().getDataEntity()), true);
         } else {
             setPositionNumberEnable();
         }
@@ -86,14 +89,19 @@ public class PosBillEntryAddFormPlugin extends AbstractFormPlugin {
             return;
         }
         long orgid = org.getLong(PositionBillConstant.ID_KEY);
-        DynamicObject positionHrDy = PositionBillService.getPositionHrDy(getModel().getDataEntity());
+        DynamicObject positionHrDy = PositionBillServiceHelper.getPositionHrDy(getModel().getDataEntity());
         boolean cudeRule = CodeRuleServiceHelper.isExist(PositionBillConstant.HBPM_POSITIONHR, positionHrDy, String.valueOf(orgid));
         if (cudeRule && !CodeRuleServiceHelper.isModifiable(PositionBillConstant.HBPM_POSITIONHR, positionHrDy, String.valueOf(org.getLong(PositionBillConstant.ID_KEY)))) {
-            getView().setEnable(Boolean.valueOf(false), PositionBillConstant.NUMBER_KEY);
+            getView().setEnable(false, PositionBillConstant.NUMBER_KEY);
+            String orgNumber = getModel().getDataEntity().getString(PositionBillConstant.NUMBER_KEY);
+            if (HRStringUtils.isNotEmpty(orgNumber)) {
+                getView().getPageCache().put("codeRuleNumber", orgNumber);
+                getView().getPageCache().put("notModifiable", Boolean.TRUE.toString());
+            }
         }
     }
 
-    private void setPositionNumber(DynamicObject positionHrDy) {
+    private void setPositionNumber(DynamicObject positionHrDy, Boolean init) {
         DynamicObject dataEntity = getModel().getDataEntity();// 157
         // 组织体系管理组织
         DynamicObject org = dataEntity.getDynamicObject(PositionBillConstant.NCKD_ORG);
@@ -103,7 +111,7 @@ public class PosBillEntryAddFormPlugin extends AbstractFormPlugin {
         }
 
         String number = dataEntity.getString(PositionBillConstant.NUMBER_KEY);
-        if (HRStringUtils.isNotEmpty(number) && !HRStringUtils.equals(number, getView().getPageCache().get(CODERULE_NUMBER))) {
+        if (HRStringUtils.isNotEmpty(number) && !HRStringUtils.equals(number, getView().getPageCache().get("codeRuleNumber"))) {
             return;
         }
 
@@ -112,26 +120,66 @@ public class PosBillEntryAddFormPlugin extends AbstractFormPlugin {
         if (cudeRule) {
             boolean fromDatabase = dataEntity.getDataEntityState().getFromDatabase();
             boolean modifiable = CodeRuleServiceHelper.isModifiable(PositionBillConstant.HBPM_POSITIONHR, positionHrDy, String.valueOf(org.getLong(PositionBillConstant.ID_KEY)));
-            if (modifiable || fromDatabase) {
+            if (modifiable || fromDatabase && !init) {
                 String positionNumber = CodeRuleServiceHelper.getNumber(PositionBillConstant.HBPM_POSITIONHR, positionHrDy, String.valueOf(org.getLong(PositionBillConstant.ID_KEY)));
                 HRBaseServiceHelper hrBaseServiceHelper = new HRBaseServiceHelper(PositionBillConstant.HBPM_POSITIONHR);
                 QFilter qFilter = new QFilter(PositionBillConstant.NUMBER_KEY, QCP.equals, positionNumber);
                 if (!hrBaseServiceHelper.isExists(qFilter)) {
                     getModel().setValue(PositionBillConstant.NUMBER_KEY, positionNumber);
-                    getView().getPageCache().put(CODERULE_NUMBER, positionNumber);
+                    getView().getPageCache().put("codeRuleNumber", positionNumber);
                 } else {
-                    setPositionNumber(positionHrDy);
+                    setPositionNumber(positionHrDy, init);
                 }
             } else {
                 getView().setEnable(Boolean.FALSE, PositionBillConstant.NUMBER_KEY);
             }
         } else {
             getModel().setValue(PositionBillConstant.NUMBER_KEY, null);
-            getView().getPageCache().put(CODERULE_NUMBER, "");
+            getView().getPageCache().put("codeRuleNumber", "");
             getView().setEnable(Boolean.TRUE, PositionBillConstant.NUMBER_KEY);
         }
     }
 
+    @Override
+    public void beforeClosed(BeforeClosedEvent event) {
+        super.beforeClosed(event);
+
+        String isCancelOverFlag = getView().getPageCache().get("isclose");
+        if (HRStringUtils.isNotEmpty(isCancelOverFlag) && Boolean.TRUE.toString().equals(isCancelOverFlag)) {
+            getModel().setDataChanged(false);
+            getView().getPageCache().put("isclose", Boolean.FALSE.toString());
+        } else {
+            boolean dataChanged = getModel().getDataChanged();
+            if (dataChanged) {
+                event.setCancel(true);
+                ConfirmCallBackListener confirmCallBacks = new ConfirmCallBackListener(String.join("_", PositionBillConstant.CLOSE_OP, PositionBillConstant.ADD_TAG), this);
+                Map<Integer, String> btnNameMaps = new HashMap<>();
+                btnNameMaps.put(MessageBoxResult.Cancel.getValue(), "返回编辑");
+                btnNameMaps.put(MessageBoxResult.Yes.getValue(), "直接退出");
+                MessageBoxOptions options = MessageBoxOptions.OKCancel;
+                String msg = "检测到您有更改内容,是否不保存直接退出?若不保存,将丢失这些更改。";
+                getView().showConfirm(msg, getModel().getChangeDesc(), options, ConfirmTypes.Save, confirmCallBacks, btnNameMaps);
+            } else {
+                String codeRuleNumber = getView().getPageCache().get("codeRuleNumber");
+                String notModifiable = getView().getPageCache().get("notModifiable");
+                if (!StringUtils.isEmpty(codeRuleNumber) && !Boolean.TRUE.toString().equals(notModifiable)) {
+                    DynamicObject org = getModel().getDataEntity().getDynamicObject(PositionBillConstant.NCKD_ORG);
+                    if (org == null) {
+                        return;
+                    }
+
+                    String saveResult = getView().getPageCache().get("saveResult");
+                    if (!Boolean.TRUE.toString().equals(saveResult)) {
+                        long orgId = org.getLong(PositionBillConstant.ID_KEY);
+                        DynamicObject positionHrDy = PositionBillServiceHelper.getPositionHrDy(getModel().getDataEntity());
+                        CodeRuleServiceHelper.recycleNumber(PositionBillConstant.HBPM_POSITIONHR, positionHrDy, String.valueOf(orgId), codeRuleNumber);
+                    }
+                }
+            }
+        }
+
+    }
+
     @Override
     public void afterBindData(EventObject e) {
         super.afterBindData(e);
@@ -152,6 +200,38 @@ public class PosBillEntryAddFormPlugin extends AbstractFormPlugin {
         getModel().setDataChanged(false);
     }
 
+    @Override
+    public void propertyChanged(PropertyChangedArgs changedArgs) {
+        String fieldKey = changedArgs.getProperty().getName();
+        if (PositionBillConstant.NCKD_ESTDATE.equals(fieldKey)) {
+            setEstablishmentDateToBsed((Date)changedArgs.getChangeSet()[0].getNewValue());
+        }
+    }
+
+    /**
+     * 设置设立日期到生效日期
+     * @param date
+     */
+    private void setEstablishmentDateToBsed(Date date) {
+        if (date != null) {
+            getModel().setValue(PositionBillConstant.NCKD_BSED, date);
+            DynamicProperty property = this.getModel().getDataEntityType().getProperty(PositionBillConstant.NCKD_BSED);
+            DataEntityState dataEntityState = this.getModel().getDataEntity().getDataEntityState();
+            dataEntityState.setBizChanged(property.getOrdinal(), false);
+        }
+    }
+
+    @Override
+    public void confirmCallBack(MessageBoxClosedEvent event) {
+        super.confirmCallBack(event);
+
+        if (String.join("_", PositionBillConstant.CLOSE_OP, PositionBillConstant.ADD_TAG).equals(event.getCallBackId()) && event.getResult() != MessageBoxResult.Cancel) {
+            recycleNumber();
+            getView().getPageCache().put("isclose", Boolean.TRUE.toString());
+            getView().invokeOperation(PositionBillConstant.CLOSE_OP);
+        }
+    }
+
     @Override
     public void afterDoOperation(AfterDoOperationEventArgs eventArgs) {
         super.afterDoOperation(eventArgs);
@@ -166,16 +246,16 @@ public class PosBillEntryAddFormPlugin extends AbstractFormPlugin {
             String addPositionParentChange = Boolean.FALSE.toString();
             DynamicObject parentPosition = getModel().getDataEntity().getDynamicObject(PositionBillConstant.NCKD_PARENT);
             if (parentPosition != null) {
-                String afterParentOrgId = parentPosition.getString(PositionBillConstant.ID_KEY);
-                if (!HRStringUtils.equals(beforeParentPositionId, afterParentOrgId)) {
+                String afterParentPositionId = parentPosition.getString(PositionBillConstant.ID_KEY);
+                if (!HRStringUtils.equals(beforeParentPositionId, afterParentPositionId)) {
                     addPositionParentChange = Boolean.TRUE.toString();
                 }
                 parentPageCache.put("addPositionParentChange", addPositionParentChange);
-                parentPageCache.put("parentId", afterParentOrgId);
+                parentPageCache.put("parentId", afterParentPositionId);
             }
             Map<String, String> map = new HashMap<>();
             DynamicObject dataEntity = getModel().getDataEntity();
-            map.put("positionId", dataEntity.getString(String.format("%s_id", PositionBillConstant.NCKD_POSITION)));
+            map.put("positionId", dataEntity.getString(String.join("_", PositionBillConstant.NCKD_POSITION, PositionBillConstant.ID_KEY)));
             map.put("name", dataEntity.getString(PositionBillConstant.NAME_KEY));
             map.put("id", dataEntity.getString(PositionBillConstant.ID_KEY));
             getView().getPageCache().put("saveResult", Boolean.TRUE.toString());
@@ -183,83 +263,22 @@ public class PosBillEntryAddFormPlugin extends AbstractFormPlugin {
         }
     }
 
-    @Override
-    public void beforeClosed(BeforeClosedEvent event) {
-        super.beforeClosed(event);
-
-        String isCancelOverFlag = getView().getPageCache().get("isclose");
-        if (HRStringUtils.isNotEmpty(isCancelOverFlag) && Boolean.TRUE.toString().equals(isCancelOverFlag)) {
-            getModel().setDataChanged(false);
-            getView().getPageCache().put("isclose", Boolean.FALSE.toString());
-            return;
-        }
-
-        boolean dataChanged = getModel().getDataChanged();
-        if (dataChanged) {
-            event.setCancel(true);
-            ConfirmCallBackListener confirmCallBacks = new ConfirmCallBackListener("close_addbill", this);
-            Map<Integer, String> btnNameMaps = new HashMap<>();
-            btnNameMaps.put(MessageBoxResult.Cancel.getValue(), "返回编辑");
-            btnNameMaps.put(MessageBoxResult.Yes.getValue(), "直接退出");
-            MessageBoxOptions options = MessageBoxOptions.OKCancel;
-            String msg = "检测到您有更改内容,是否不保存直接退出?若不保存,将丢失这些更改。";
-            getView().showConfirm(msg, getModel().getChangeDesc(), options, ConfirmTypes.Save, confirmCallBacks, btnNameMaps);
-        } else {
-            String codeRuleNumber = getView().getPageCache().get(CODERULE_NUMBER);
-            if (!StringUtils.isEmpty(codeRuleNumber)) {
-                DynamicObject org = getModel().getDataEntity().getDynamicObject(PositionBillConstant.ORG_KEY);
-                if (org == null) {
-                    return;
-                }
-                String saveResult = getView().getPageCache().get(SAVE_RESULT);
-                if (!Boolean.TRUE.toString().equals(saveResult)) {
-                    long orgId = org.getLong(PositionBillConstant.ID_KEY);
-                    DynamicObject positionHrDy = PositionBillService.getPositionHrDy(getModel().getDataEntity());
-                    CodeRuleServiceHelper.recycleNumber(PositionBillConstant.HBPM_POSITIONHR, positionHrDy, String.valueOf(orgId), codeRuleNumber);
-                }
+    private void recycleNumber() {
+        String codeRuleNumber = getView().getPageCache().get(CODERULE_NUMBER);
+        if (!StringUtils.isEmpty(codeRuleNumber)) {
+            DynamicObject org = getModel().getDataEntity().getDynamicObject(PositionBillConstant.NCKD_ORG);
+            if (HRObjectUtils.isEmpty(org)) {
+                return;
             }
-        }
-    }
-
-    @Override
-    public void confirmCallBack(MessageBoxClosedEvent event) {
-        super.confirmCallBack(event);
-        if ("close_addbill".equals(event.getCallBackId()) && event.getResult() != MessageBoxResult.Cancel) {
-            String codeRuleNumber = getView().getPageCache().get(CODERULE_NUMBER);
-            if (!StringUtils.isEmpty(codeRuleNumber)) {
-                DynamicObject org = getModel().getDataEntity().getDynamicObject(PositionBillConstant.ORG_KEY);
-                if (org == null) {
-                    return;
-                }
-                String saveResult = getView().getPageCache().get(SAVE_RESULT);
-                if (!Boolean.TRUE.toString().equals(saveResult)) {
-                    long orgId = org.getLong(PositionBillConstant.ID_KEY);
-                    DynamicObject positionHrDy = PositionBillService.getPositionHrDy(getModel().getDataEntity());
-                    CodeRuleServiceHelper.recycleNumber(PositionBillConstant.HBPM_POSITIONHR, positionHrDy, String.valueOf(orgId), codeRuleNumber);
-                }
+            String saveResult = getView().getPageCache().get(SAVE_RESULT);
+            if (!Boolean.TRUE.toString().equals(saveResult)) {
+                long orgId = org.getLong(PositionBillConstant.ID_KEY);
+                DynamicObject positionHrDy = PositionBillServiceHelper.getPositionHrDy(getModel().getDataEntity());
+                CodeRuleServiceHelper.recycleNumber(PositionBillConstant.HBPM_POSITIONHR, positionHrDy, String.valueOf(orgId), codeRuleNumber);
             }
-            getView().getPageCache().put("isclose", Boolean.TRUE.toString());
-            getView().invokeOperation(PositionBillConstant.CLOSE_OP);
-        }
-    }
-
-    @Override
-    public void propertyChanged(PropertyChangedArgs changedArgs) {
-        String fieldKey = changedArgs.getProperty().getName();
-        boolean isGetNumber = true;
-        if (PositionBillConstant.NCKD_ESTDATE.equals(fieldKey)) {
-            setEstablishmentDateToBsed((Date)changedArgs.getChangeSet()[0].getNewValue());
-        }
-    }
-
-    /**
-     * 设置设立日期到生效日期
-     * @param date
-     */
-    private void setEstablishmentDateToBsed(Date date) {
-        if (date != null) {
-            getModel().setValue(PositionBillConstant.NCKD_BSED, date);
         }
+        getView().getPageCache().put("isclose", Boolean.TRUE.toString());
+        getView().invokeOperation(PositionBillConstant.CLOSE_OP);
     }
 
 }

+ 111 - 36
code/hrmp/nckd-jxccl-hrmp/src/main/java/nckd/jxccl/hrmp/hbpm/plugin/form/hr/PositionBillEntryFormPlugin.java

@@ -1,18 +1,28 @@
 package nckd.jxccl.hrmp.hbpm.plugin.form.hr;
 
+import com.alibaba.fastjson.JSONObject;
+import com.google.common.collect.Maps;
 import kd.bos.bill.OperationStatus;
 import kd.bos.common.enums.EnableEnum;
+import kd.bos.dataentity.entity.DynamicObject;
+import kd.bos.dataentity.entity.ILocaleString;
+import kd.bos.dataentity.utils.ObjectUtils;
+import kd.bos.entity.operate.result.OperationResult;
 import kd.bos.form.FormShowParameter;
+import kd.bos.form.IFormView;
+import kd.bos.form.events.AfterDoOperationEventArgs;
 import kd.bos.form.events.BeforeDoOperationEventArgs;
 import kd.bos.form.field.BasedataEdit;
 import kd.bos.form.field.events.BeforeF7SelectEvent;
 import kd.bos.form.field.events.BeforeF7SelectListener;
+import kd.bos.form.operate.AbstractOperate;
 import kd.bos.form.plugin.AbstractFormPlugin;
 import kd.bos.list.ListShowParameter;
 import kd.hr.hbp.common.util.HRStringUtils;
 import nckd.jxccl.hrmp.hbpm.common.hr.PositionBillConstant;
 
 import java.util.EventObject;
+import java.util.Map;
 
 /**
  * 岗位申请单分录表单插件
@@ -21,20 +31,6 @@ import java.util.EventObject;
  */
 public class PositionBillEntryFormPlugin extends AbstractFormPlugin implements BeforeF7SelectListener {
 
-    @Override
-    public void registerListener(EventObject e) {
-        super.registerListener(e);
-
-        BasedataEdit adminorg = getView().getControl(PositionBillConstant.NCKD_ADMINORG);
-        adminorg.addBeforeF7SelectListener(this);
-
-        BasedataEdit position = getView().getControl(PositionBillConstant.NCKD_POSITION);
-        position.addBeforeF7SelectListener(this);
-
-        BasedataEdit parent = getView().getControl(PositionBillConstant.NCKD_PARENT);
-        parent.addBeforeF7SelectListener(this);
-    }
-
     @Override
     public void beforeBindData(EventObject e) {
         super.beforeBindData(e);
@@ -47,20 +43,13 @@ public class PositionBillEntryFormPlugin extends AbstractFormPlugin implements B
         }
     }
 
-    /**
-     * 设置组织体系管理组织
-     */
-    private void setOrg() {
-        String entityId = getView().getEntityId();
-        if (PositionBillConstant.NCKD_POSBILLENTRYADD.equals(entityId) || PositionBillConstant.NCKD_POSBILLENTRYCHANGE.equals(entityId)) {
-            Object orgParam = getView().getFormShowParameter().getCustomParam(PositionBillConstant.ORG_KEY);
-            String isInit = getPageCache().get("isInit");
-            if (orgParam != null && HRStringUtils.isEmpty(isInit)) {
-                getModel().beginInit();
-                getModel().setValue(PositionBillConstant.NCKD_ORG, orgParam);
-                getModel().endInit();
-                getPageCache().put("isInit", EnableEnum.YES.getCode());
-            }
+    public void afterBindData(EventObject e) {
+        super.afterBindData(e);
+
+        getModel().setDataChanged(false);
+        OperationStatus status = getView().getFormShowParameter().getStatus();
+        if (OperationStatus.ADDNEW.equals(status) || OperationStatus.EDIT.equals(status)) {
+            getView().setEnable(Boolean.TRUE, PositionBillConstant.ORG_KEY);
         }
     }
 
@@ -74,14 +63,18 @@ public class PositionBillEntryFormPlugin extends AbstractFormPlugin implements B
         }
     }
 
-    public void afterBindData(EventObject e) {
-        super.afterBindData(e);
+    @Override
+    public void registerListener(EventObject e) {
+        super.registerListener(e);
 
-        getModel().setDataChanged(false);
-        OperationStatus status = getView().getFormShowParameter().getStatus();
-        if (OperationStatus.ADDNEW.equals(status) || OperationStatus.EDIT.equals(status)) {
-            getView().setEnable(Boolean.TRUE, PositionBillConstant.ORG_KEY);
-        }
+        BasedataEdit adminorg = getView().getControl(PositionBillConstant.NCKD_ADMINORG);
+        adminorg.addBeforeF7SelectListener(this);
+
+        BasedataEdit position = getView().getControl(PositionBillConstant.NCKD_POSITION);
+        position.addBeforeF7SelectListener(this);
+
+        BasedataEdit parent = getView().getControl(PositionBillConstant.NCKD_PARENT);
+        parent.addBeforeF7SelectListener(this);
     }
 
     @Override
@@ -90,7 +83,7 @@ public class PositionBillEntryFormPlugin extends AbstractFormPlugin implements B
         // 替换组织F7模板
         if (PositionBillConstant.NCKD_ADMINORG.equals(fieldKey)) {
             ListShowParameter showParameter = (ListShowParameter) beforeF7SelectEvent.getFormShowParameter();
-            showParameter.setFormId(PositionBillConstant.HAOS_ORGTREELISTF7);
+            showParameter.setFormId(PositionBillConstant.HAOS_ORGTREELISTF7_ENTITY);
             //showParameter.setCaption("行政组织");
         }
 
@@ -109,10 +102,92 @@ public class PositionBillEntryFormPlugin extends AbstractFormPlugin implements B
         }
     }
 
+    @Override
+    public void afterDoOperation(AfterDoOperationEventArgs afterDoOperationEventArgs) {
+        super.afterDoOperation(afterDoOperationEventArgs);
+
+
+        OperationResult result = afterDoOperationEventArgs.getOperationResult();
+        if (ObjectUtils.isEmpty(result) || result.isSuccess()) {
+            if (HRStringUtils.equals(afterDoOperationEventArgs.getOperateKey(), PositionBillConstant.SAVE_OP) || HRStringUtils.equals(afterDoOperationEventArgs.getOperateKey(), PositionBillConstant.SAVE_AND_NEW_OP)) {
+                getView().returnDataToParent(getModel().getDataEntity().getLong(PositionBillConstant.ID_KEY));
+            }
+        }
+    }
+
+    /**
+     * 设置组织体系管理组织
+     */
+    private void setOrg() {
+        String entityId = getView().getEntityId();
+        if (PositionBillConstant.NCKD_POSBILLENTRYADD_ENTITY.equals(entityId) || PositionBillConstant.NCKD_POSBILLENTRYCHANGE_ENTITY.equals(entityId)) {
+            Object orgParam = getView().getFormShowParameter().getCustomParam(PositionBillConstant.ORG_KEY);
+            String isInit = getPageCache().get("isInit");
+            if (orgParam != null && HRStringUtils.isEmpty(isInit)) {
+                getModel().beginInit();
+                getModel().setValue(PositionBillConstant.NCKD_ORG, orgParam);
+                getModel().endInit();
+                getPageCache().put("isInit", EnableEnum.YES.getCode());
+            }
+        }
+    }
+
     @Override
     public void beforeDoOperation(BeforeDoOperationEventArgs args) {
         super.beforeDoOperation(args);
 
 
+        AbstractOperate operate = (AbstractOperate) args.getSource();
+        String operateKey = operate.getOperateKey();
+        if (HRStringUtils.equals(operateKey, PositionBillConstant.SAVE_OP) || HRStringUtils.equals(operateKey, PositionBillConstant.SAVE_AND_NEW_OP)) {
+
+            IFormView parentView = getBillFormView(getView());
+            Map<String, Map<String, ILocaleString>> parentBoIdToChildNameMap = Maps.newHashMapWithExpectedSize(16);
+            Map<String, String> numberMap = Maps.newHashMapWithExpectedSize(16);
+            if (parentView != null) {
+                setValidateData(parentView, PositionBillConstant.ADD_TAG, parentBoIdToChildNameMap, numberMap);
+                setValidateData(parentView, PositionBillConstant.CHANGE_TAG, parentBoIdToChildNameMap, numberMap);
+            }
+
+            operate.getOption().setVariableValue("OP_BILL_CHILD_NAMES_MAP", JSONObject.toJSONString(parentBoIdToChildNameMap));
+            operate.getOption().setVariableValue("OP_BILL_NUMBER_MAP", JSONObject.toJSONString(numberMap));
+            operate.getOption().setVariableValue("OP_VALIDATOR_BILL_POSITION_ALL_CHANGE_POSITION_KEY", getView().getFormShowParameter().getCustomParam("OP_VALIDATOR_BILL_POSITION_ALL_CHANGE_POSITION_KEY"));
+        }
+    }
+
+    private IFormView getBillFormView(IFormView formView) {
+        if (formView != null) {
+            IFormView parentView = formView.getParentViewNoPlugin();
+            return parentView != null && PositionBillConstant.NCKD_POSITIONBILL_ENTITY.equals(parentView.getFormShowParameter().getFormId()) ? parentView : getBillFormView(parentView);
+        } else {
+            return null;
+        }
+    }
+
+
+    private void setValidateData(IFormView parentView, String suffix, Map<String, Map<String, ILocaleString>> parentBoIdToChildNameMap, Map<String, String> numberMap) {
+        for(DynamicObject addEntryDy : parentView.getModel().getDataEntity(true).getDynamicObjectCollection(String.join("_", PositionBillConstant.NCKD_ENTRYENTITY, suffix))) {
+            DynamicObject parentPositionDy = addEntryDy.getDynamicObject(String.join("_", PositionBillConstant.NCKD_PARENT, suffix));
+            String positionKey = String.join("_", PositionBillConstant.NCKD_POSITION_KEY, suffix);
+            String positionIdKey = String.join(".", positionKey, PositionBillConstant.ID_KEY);
+            if (PositionBillConstant.ADD_TAG.equals(suffix)) {
+                positionIdKey = positionKey;
+            }
+
+            long positionId = addEntryDy.getLong(positionIdKey);
+            if (parentPositionDy != null) {
+                long boId = parentPositionDy.getLong(PositionBillConstant.BOID_KEY);
+                Map<String, ILocaleString> childNameMap = parentBoIdToChildNameMap.get(String.valueOf(boId));
+                if (childNameMap == null) {
+                    childNameMap = Maps.newHashMapWithExpectedSize(16);
+                }
+
+                childNameMap.put(String.valueOf(positionId), addEntryDy.getLocaleString(String.join("_", PositionBillConstant.NAME_KEY, suffix)));
+                parentBoIdToChildNameMap.put(String.valueOf(boId), childNameMap);
+            }
+
+            numberMap.put(String.valueOf(positionId), addEntryDy.getString(String.join("_", PositionBillConstant.NUMBER_KEY, suffix)));
+        }
+
     }
 }

+ 82 - 68
code/hrmp/nckd-jxccl-hrmp/src/main/java/nckd/jxccl/hrmp/hbpm/plugin/form/hr/PositionBillFormPlugin.java

@@ -1,24 +1,34 @@
 package nckd.jxccl.hrmp.hbpm.plugin.form.hr;
 
+import kd.bos.bill.BillOperationStatus;
+import kd.bos.bill.BillShowParameter;
 import kd.bos.bill.OperationStatus;
+import kd.bos.dataentity.entity.DynamicObject;
+import kd.bos.entity.BillEntityType;
 import kd.bos.entity.operate.result.OperationResult;
 import kd.bos.form.ConfirmCallBackListener;
+import kd.bos.form.ConfirmTypes;
 import kd.bos.form.MessageBoxOptions;
-import kd.bos.form.MessageBoxResult;
 import kd.bos.form.control.EntryGrid;
-import kd.bos.form.control.events.ItemClickEvent;
 import kd.bos.form.events.AfterDoOperationEventArgs;
 import kd.bos.form.events.ClosedCallBackEvent;
 import kd.bos.form.events.MessageBoxClosedEvent;
-import kd.bos.form.field.events.BeforeF7SelectEvent;
 import kd.bos.form.plugin.AbstractFormPlugin;
-import kd.bos.form.plugin.IFormPlugin;
-import kd.bos.list.ListShowParameter;
+import kd.bos.mvc.bill.BillView;
 import kd.bos.orm.ORM;
-import nckd.jxccl.hrmp.hbpm.business.hr.PositionBillService;
+import kd.bos.orm.query.QCP;
+import kd.bos.orm.query.QFilter;
+import kd.hr.hbp.business.servicehelper.HRBaseServiceHelper;
+import kd.hr.hbp.common.util.HRStringUtils;
+import kd.hr.homs.business.domain.batchbill.repository.AdminOrgBatchChgHelper;
+import kd.hr.homs.business.domain.batchbill.service.impl.AdminOrgBatchBillConfirmCallBackService;
+import kd.sdk.hr.hdm.common.enums.reg.RegBillStatusEnum;
+import nckd.jxccl.hrmp.hbpm.business.hr.PositionBillClosedCallBackService;
+import nckd.jxccl.hrmp.hbpm.business.hr.PositionBillServiceHelper;
 import nckd.jxccl.hrmp.hbpm.common.hr.PositionBillConstant;
 
 import java.util.EventObject;
+import java.util.Objects;
 
 /**
  * 岗位申请单表单插件
@@ -27,56 +37,23 @@ import java.util.EventObject;
  */
 public class PositionBillFormPlugin extends AbstractFormPlugin {
 
-    private static final String NCKD_ENTRYENTITY_ADD = "nckd_entrtyentity_add";
-    private static final String NCKD_ENTRYENTITY_INFO = "nckd_entrtyentity_info";
-    private static final String NCKD_CHANGETYPE = "nckd_chagetype";
-
     @Override
     public void afterBindData(EventObject e) {
         super.afterBindData(e);
 
         // 生成临时单据ID
         genBillIdIfNotExist();
-        this.getModel().setDataChanged(false);
+        getModel().setDataChanged(false);
     }
 
     /**
      * 生成临时单据ID
      */
     private void genBillIdIfNotExist() {
-        long billId = this.getModel().getDataEntity().getLong("id");
+        long billId = getModel().getDataEntity().getLong(PositionBillConstant.ID_KEY);
         if (billId == 0L) {
-            billId = ORM.create().genLongId(this.getView().getEntityId());
-            this.getModel().setValue("id", billId);
-        }
-    }
-
-    @Override
-    public void itemClick(ItemClickEvent evt) {
-        super.itemClick(evt);
-
-        if ("tb_del".equals(evt.getItemKey())) {
-            EntryGrid posdutyEntryGrid = getView().getControl(PositionBillConstant.NCKD_POSDUTYENTRYENTITY);
-            int length = (posdutyEntryGrid.getSelectRows()).length;
-            if (length > 0) {
-                ConfirmCallBackListener deleteEntryCallBackListener = new ConfirmCallBackListener("del_row", this);
-                getView().showConfirm(String.format("你已选中%s条记录,删除后将不可恢复,是否继续?", length), MessageBoxOptions.OKCancel, deleteEntryCallBackListener);
-            } else {
-                getView().showTipNotification("请选中需要操作的行。");
-            }
-        }
-    }
-
-
-
-    @Override
-    public void confirmCallBack(MessageBoxClosedEvent event) {
-        super.confirmCallBack(event);
-
-        if ("del_row".equals(event.getCallBackId()) && event.getResult().getValue() == MessageBoxResult.Yes.getValue()) {
-            EntryGrid strategyEntryGrid = (EntryGrid)getView().getControl("cooprelentryentity");
-            int[] rows = strategyEntryGrid.getSelectRows();
-            getModel().deleteEntryRows("cooprelentryentity", rows);
+            billId = ORM.create().genLongId(getView().getEntityId());
+            getModel().setValue(PositionBillConstant.ID_KEY, billId);
         }
     }
 
@@ -84,6 +61,16 @@ public class PositionBillFormPlugin extends AbstractFormPlugin {
     public void afterDoOperation(AfterDoOperationEventArgs afterDoOperationEventArgs) {
         super.afterDoOperation(afterDoOperationEventArgs);
 
+        OperationStatus status = getView().getFormShowParameter().getStatus();
+        if (HRStringUtils.equals(getView().getFormShowParameter().getAppId(), PositionBillConstant.WFTASK_APP)) {
+            ((BillView) getView()).setBillStatus(BillOperationStatus.EDIT);
+            getView().getFormShowParameter().setStatus(OperationStatus.EDIT);
+            ((BillShowParameter) getView().getFormShowParameter()).setBillStatus(BillOperationStatus.EDIT);
+            String billStatus = ((BillEntityType) getModel().getDataEntityType()).getBillStatus();
+            getModel().setValue(billStatus, "A");
+            getModel().setDataChanged(Boolean.FALSE);
+        }
+
         OperationResult afterOperationResult = afterDoOperationEventArgs.getOperationResult();
         if (!(afterOperationResult == null || afterOperationResult.isSuccess())) {
             return;
@@ -91,44 +78,71 @@ public class PositionBillFormPlugin extends AbstractFormPlugin {
 
         String opKey = afterDoOperationEventArgs.getOperateKey();
         switch (opKey) {
-            case PositionBillConstant.NEWENTRY_ADD:
-                PositionBillService.openViewForm(this.getView(), opKey, this.getPluginName());
+            case PositionBillConstant.NEWENTRY_ADD_OP:
+                PositionBillServiceHelper.openViewForm(getView(), PositionBillConstant.ADD_TAG, getPluginName());
                 break;
-            case PositionBillConstant.NEWENTRY_CHANGE:
-                PositionBillService.openViewForm(this.getView(), opKey, this.getPluginName());
+            case PositionBillConstant.NEWENTRY_CHANGE_OP:
+                PositionBillServiceHelper.openViewForm(getView(), PositionBillConstant.CHANGE_TAG, getPluginName());
                 break;
-            case "deleteentry_add":
-                PositionBillService.openViewForm(this.getView(), "add", this.getPluginName());
+            case PositionBillConstant.EDIT_ADD_OP:
+                PositionBillServiceHelper.openEditPage(getModel(), getView(), PositionBillConstant.ADD_TAG, status);
                 break;
-            case "deleteentry_change":
-                PositionBillService.openViewForm(this.getView(), "add", this.getPluginName());
-                break;
-            case "edit_add":
-                PositionBillService.openViewForm(this.getView(), "add", this.getPluginName());
-                break;
-            case "edit_change":
-                PositionBillService.openViewForm(this.getView(), "add", this.getPluginName());
+            case PositionBillConstant.DELETE_ROWS_ADD_OP:
+            case PositionBillConstant.DELETE_ROWS_CHANGE_OP:
+                deleteRowsConfirm(opKey);
                 break;
+
         }
     }
 
+    public void confirmCallBack(MessageBoxClosedEvent event) {
+        super.confirmCallBack(event);
+
+        AdminOrgBatchBillConfirmCallBackService confirmCallBackService = new AdminOrgBatchBillConfirmCallBackService(getView());
+        confirmCallBackService.confirmCallBack(event);
+    }
+
     @Override
     public void closedCallBack(ClosedCallBackEvent closedCallBackEvent) {
         super.closedCallBack(closedCallBackEvent);
 
-        switch (closedCallBackEvent.getActionId()) {
-            case "add":
-                PositionBillService.openViewForm(this.getView(), "add", this.getPluginName());
-                break;
-            case "change":
-                PositionBillService.openViewForm(this.getView(), "change", this.getPluginName());
-                break;
-            case "delete":
-                PositionBillService.openViewForm(this.getView(), "delete", this.getPluginName());
-                break;
-            case "edit":
+        PositionBillClosedCallBackService closedCallBackService = new PositionBillClosedCallBackService(getView());
+        closedCallBackService.closedCallBack(closedCallBackEvent);
+    }
+
+    private void deleteRowsConfirm(String callBackId) {
+        long id = getModel().getDataEntity().getLong(PositionBillConstant.ID_KEY);
+        HRBaseServiceHelper helper = new HRBaseServiceHelper(PositionBillConstant.HBPM_POSITIONHR);
+        QFilter idFilter = new QFilter(PositionBillConstant.ID_KEY, QCP.equals, id);
+        DynamicObject dyn = helper.queryOne(String.join(",", PositionBillConstant.ID_KEY, PositionBillConstant.BILL_STATUS_KEY), new QFilter[]{idFilter});
+        String billstatus;
+        if (Objects.isNull(dyn)) {
+            billstatus = "A";
+        } else {
+            billstatus = dyn.getString(PositionBillConstant.BILL_STATUS_KEY);
         }
 
+        boolean enableDeleteForUserPage = billstatus.equals(RegBillStatusEnum.TEMPSTORAGE.getCode()) || billstatus.equals(RegBillStatusEnum.WAITRESUBMIT.getCode());
+        boolean enableDeleteForAuditPage = HRStringUtils.equals(getView().getFormShowParameter().getAppId(), PositionBillConstant.WFTASK_APP) && billstatus.equals(RegBillStatusEnum.ALREADYSUBMIT.getCode());
+        if (!enableDeleteForUserPage && !enableDeleteForAuditPage) {
+            String auditStatusName = AdminOrgBatchChgHelper.getAuditstatusName(billstatus);
+            getView().showErrorNotification(String.format("%s的单据不能删除调整明细。", auditStatusName));
+        } else {
+            EntryGrid coopRelEntryGrid = getView().getControl(PositionBillConstant.NCKD_ENTRYENTITY_ADD_KEY);
+            if (null == coopRelEntryGrid) {
+                getView().showTipNotification("请选中需要删除的行。");
+            } else {
+                int[] selectRows = coopRelEntryGrid.getSelectRows();
+                int length = selectRows.length;
+                if (selectRows.length > 0) {
+                    ConfirmCallBackListener deleteEntryCallBackListener = new ConfirmCallBackListener(callBackId, this);
+                    getView().showConfirm(String.format("删除选中的数据后将无法恢复(选中条数:%s),确定要删除吗?", length), MessageBoxOptions.OKCancel, ConfirmTypes.Delete, deleteEntryCallBackListener);
+                } else {
+                    getView().showTipNotification("请选中需要操作的行。");
+                }
+
+            }
+        }
     }
 
 }

+ 5 - 12
code/hrmp/nckd-jxccl-hrmp/src/main/java/nckd/jxccl/hrmp/hbpm/plugin/operate/hr/PosBillEntryAddSaveOpPlugin.java

@@ -20,14 +20,11 @@ import kd.hr.hbp.business.servicehelper.HRBaseServiceHelper;
 import kd.hr.hbp.common.constants.history.HisModelDataStatusEnum;
 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.business.hr.PositionBillServiceHelper;
 import nckd.jxccl.hrmp.hbpm.common.hr.PositionBillConstant;
 
-import java.util.Arrays;
 import java.util.List;
 import java.util.Map;
-import java.util.function.Function;
-import java.util.stream.Collectors;
 
 /**
  * 岗位申请-新增岗位保存OP
@@ -79,11 +76,8 @@ public class PosBillEntryAddSaveOpPlugin extends AbstractOperationServicePlugIn
         // 构建岗位对象
         OperateOption operateOption = OperateOption.create();
         List<DynamicObject> positionList = Lists.newArrayListWithExpectedSize(positionEntities.length);
-        // 查询需要转换的键值
-        String selectFields = QueryFieldBuilder.create().add(PositionBillConstant.NUMBER_KEY).add(PositionBillConstant.NAME_KEY).buildSelect();
-        DynamicObject[] transKeyDyos = HRBaseServiceHelper.create(PositionBillConstant.NCKD_POSITION_TRANSKEY_ENTITY).queryOriginalArray(selectFields, null);
-        // key->目标字段 value->源字段
-        Map<String, String> transKeyMap = Arrays.stream(transKeyDyos).map(Function.identity()).collect(Collectors.toMap(transKeyDyo -> transKeyDyo.getString(PositionBillConstant.NAME_KEY), transKeyDyo -> transKeyDyo.getString(PositionBillConstant.NUMBER_KEY), (oldValue, newValue) -> newValue));
+        // 需要转换的键值
+        Map<String, String> transKeyMap = PositionBillServiceHelper.getTransKeyMap();
 
         for (DynamicObject positionEntity : positionEntities) {
             long positionId = positionEntity.getLong(String.join("_", PositionBillConstant.NCKD_POSITION, PositionBillConstant.ID_KEY));
@@ -113,9 +107,9 @@ public class PosBillEntryAddSaveOpPlugin extends AbstractOperationServicePlugIn
             // 设置 是否标准岗位
             positionDyo.set(PositionBillConstant.ISSTANDARDPOS_KEY, EnableEnum.NO.getCode());
             // 设置 数据版本状态
-            //positionDyo.set(PositionBillConstant.DATA_STATUS, HisModelDataStatusEnum.TEMP.getStatus());
+            positionDyo.set(PositionBillConstant.DATA_STATUS, HisModelDataStatusEnum.TEMP.getStatus());
             positionList.add(positionDyo);
-            String number = positionDyo.getString("number");
+            String number = positionDyo.getString(PositionBillConstant.NUMBER_KEY);
             // 设置 编码为已变更
             if (HRStringUtils.isNotEmpty(number)) {
                 operateOption.setVariableValue(positionId + "coderule_billno_from_initAbstractCodeRule", PAGECACHE_KEY_BILLNO_FROM_INIT_VALUE_OF_OPERATION);
@@ -125,7 +119,6 @@ public class PosBillEntryAddSaveOpPlugin extends AbstractOperationServicePlugIn
         operateOption.setVariableValue(OperateOptionConst.ISHASRIGHT, Boolean.TRUE.toString());
         // 跳过数据权限校验
         operateOption.setVariableValue(OperateOptionConst.SKIPCHECKPERMISSION, Boolean.TRUE.toString());
-        StringBuilder errorMsg = new StringBuilder();
         List<String> errorMsgList = Lists.newArrayList();
         List successPkIds = Lists.newArrayList();
         for (int index = 0; index < positionList.size(); ++index) {

+ 1 - 1
cosmic.json

@@ -1,5 +1,5 @@
 {
   "COSMIC_DEVELOPER_FLAG": "nckd",
   "COSMIC_PROJECT_FLAG": "jxccl",
-  "COSMIC_RES_URL": "http://10.99.186.147:8090/appstore/dev_env/"
+  "COSMIC_RES_URL": "http://10.99.190.94:8090/appstore/dev_env/"
 }

+ 1 - 1
cosmic.properties

@@ -1 +1 @@
-MCServerURL=http://10.99.186.147:8090/appstore/dev_env/
+MCServerURL=http://10.99.190.94:8090/appstore/dev_env/