Bladeren bron

refactor(incentive): 抽象激励核定表单插件逻辑

- 创建抽象基类 AbstractIncentiveApprFormPlugin 统一处理数据加载逻辑
- 重构企业负责人中长期激励核定表插件继承抽象类
- 重构企业负责人任期激励核定表插件继承抽象类
- 抽象薪酬标准变更表单插件逻辑到 AbstractSalaryStdChgFormPlugin
- 重构企业负责人年度薪酬标准变更插件继承抽象类
wyc 2 weken geleden
bovenliggende
commit
ef68c963c3
13 gewijzigde bestanden met toevoegingen van 936 en 1267 verwijderingen
  1. 121 0
      code/swc/nckd-jxccl-swc/src/main/java/nckd/jxccl/swc/mas/plugin/form/incentivemgmt/AbstractIncentiveApprFormPlugin.java
  2. 13 78
      code/swc/nckd-jxccl-swc/src/main/java/nckd/jxccl/swc/mas/plugin/form/incentivemgmt/EntldrMidlongApprFormPlugin.java
  3. 19 77
      code/swc/nckd-jxccl-swc/src/main/java/nckd/jxccl/swc/mas/plugin/form/incentivemgmt/EntldrTermBonusApprFormPlugin.java
  4. 336 0
      code/swc/nckd-jxccl-swc/src/main/java/nckd/jxccl/swc/mas/plugin/form/structappr/AbstractStructApprFormPlugin.java
  5. 3 3
      code/swc/nckd-jxccl-swc/src/main/java/nckd/jxccl/swc/mas/plugin/form/structappr/EntLdrItemWageApprFormPlugin.java
  6. 18 259
      code/swc/nckd-jxccl-swc/src/main/java/nckd/jxccl/swc/mas/plugin/form/structappr/EntleaderAnlSalStdFormPlugin.java
  7. 17 262
      code/swc/nckd-jxccl-swc/src/main/java/nckd/jxccl/swc/mas/plugin/form/structappr/SubcorpChiefSalStdFormPlugin.java
  8. 233 0
      code/swc/nckd-jxccl-swc/src/main/java/nckd/jxccl/swc/mas/plugin/form/structappr/change/AbstractSalaryStdChgFormPlugin.java
  9. 2 219
      code/swc/nckd-jxccl-swc/src/main/java/nckd/jxccl/swc/mas/plugin/form/structappr/change/EntldrAnlSalStdChgFormPlugin.java
  10. 2 217
      code/swc/nckd-jxccl-swc/src/main/java/nckd/jxccl/swc/mas/plugin/form/structappr/change/SubcpChfSalStdChgFormPlugin.java
  11. 128 0
      code/swc/nckd-jxccl-swc/src/main/java/nckd/jxccl/swc/mas/plugin/operate/structappr/change/AbstractSalaryStdChgOpPlugin.java
  12. 22 77
      code/swc/nckd-jxccl-swc/src/main/java/nckd/jxccl/swc/mas/plugin/operate/structappr/change/EntldrAnlSalStdChgOpPlugin.java
  13. 22 75
      code/swc/nckd-jxccl-swc/src/main/java/nckd/jxccl/swc/mas/plugin/operate/structappr/change/SubcpChfSalstdChgBackOpPlugin.java

+ 121 - 0
code/swc/nckd-jxccl-swc/src/main/java/nckd/jxccl/swc/mas/plugin/form/incentivemgmt/AbstractIncentiveApprFormPlugin.java

@@ -0,0 +1,121 @@
+package nckd.jxccl.swc.mas.plugin.form.incentivemgmt;
+
+import kd.bos.dataentity.entity.DynamicObject;
+import kd.bos.dataentity.entity.DynamicObjectCollection;
+import kd.bos.entity.constant.StatusEnum;
+import kd.bos.entity.datamodel.events.ChangeData;
+import kd.bos.entity.datamodel.events.PropertyChangedArgs;
+import kd.bos.form.plugin.AbstractFormPlugin;
+import kd.bos.orm.query.QCP;
+import kd.bos.orm.query.QFilter;
+import kd.bos.servicehelper.BusinessDataServiceHelper;
+import kd.bos.servicehelper.operation.SaveServiceHelper;
+import kd.sdk.plugin.Plugin;
+import nckd.jxccl.base.common.constant.FormConstant;
+import nckd.jxccl.base.common.utils.ConvertUtil;
+import nckd.jxccl.base.common.utils.QueryFieldBuilder;
+import nckd.jxccl.swc.mas.common.MasConstant;
+
+import java.util.Objects;
+import java.util.stream.Stream;
+
+/**
+ * 激励核定表单插件抽象基类
+ *
+ * @author W.Y.C
+ * @date 2025/12/03
+ */
+public abstract class AbstractIncentiveApprFormPlugin extends AbstractFormPlugin implements Plugin {
+
+    /**
+     * 获取提示信息文本
+     * @return 提示信息
+     */
+    protected abstract String getNotificationMessage();
+
+    /**
+     * 初始化行选项(如果需要)
+     * @param installmentYears 分期年数
+     * @param rowIndex 行索引
+     */
+    protected void initOperateOption(int installmentYears, int rowIndex) {
+        // 默认空实现,子类可根据需要重写
+    }
+
+    @Override
+    public void propertyChanged(PropertyChangedArgs e) {
+        String fieldKey = e.getProperty().getName();
+        ChangeData[] changeSet = e.getChangeSet();
+        Object oldValue = changeSet[0].getOldValue();
+        Object newValue = changeSet[0].getNewValue();
+        
+        if (isTriggerField(fieldKey) && !Objects.equals(oldValue, newValue)) {
+            load();
+        }
+    }
+
+    /**
+     * 判断是否为触发加载数据的字段
+     * @param fieldKey 字段名
+     * @return 是否为触发字段
+     */
+    protected boolean isTriggerField(String fieldKey) {
+        return Stream.of(MasConstant.NCKD_PAYUNIT, MasConstant.NCKD_LAWENTITY, MasConstant.NCKD_TERM)
+                .anyMatch(op -> op.equalsIgnoreCase(fieldKey));
+    }
+
+    protected void load() {
+        DynamicObject payUnit = ConvertUtil.toDynamicObjectOrNull(this.getModel().getValue(MasConstant.NCKD_PAYUNIT));
+        DynamicObject lawEntity = ConvertUtil.toDynamicObjectOrNull(this.getModel().getValue(MasConstant.NCKD_LAWENTITY));
+        DynamicObject term = ConvertUtil.toDynamicObjectOrNull(this.getModel().getValue(MasConstant.NCKD_TERM));
+
+        if (payUnit != null && lawEntity != null && term != null) {
+            QueryFieldBuilder queryFieldBuilder = QueryFieldBuilder.create()
+                    .addIdNumberName(MasConstant.NCKD_PAYUNIT)
+                    .addIdNumberName(MasConstant.NCKD_LAWENTITY)
+                    .addIdNumberName(MasConstant.NCKD_TERM)
+                    .addIdNumberName(MasConstant.NCKD_EMPLOYEE)
+                    .add(FormConstant.NCKD_STARTDATE)
+                    .add(FormConstant.NCKD_ENDDATE)
+                    .add(MasConstant.NCKD_POSNAME)
+                    .add(MasConstant.NCKD_SERVICEMONTHS);
+
+            QFilter qFilter = new QFilter(MasConstant.NCKD_PAYUNIT, QCP.equals, payUnit.getLong(FormConstant.ID_KEY))
+                    .and(MasConstant.NCKD_LAWENTITY, QCP.equals, lawEntity.getLong(FormConstant.ID_KEY))
+                    .and(MasConstant.NCKD_TERM, QCP.equals, term.getLong(FormConstant.ID_KEY))
+                    .and(FormConstant.STATUS, QCP.in, new String[]{StatusEnum.C.toString(), StatusEnum.B.toString()});
+                    
+            DynamicObject[] tenurePersonList = BusinessDataServiceHelper.load(
+                    MasConstant.TENUREPERSONLIST_ENTITYID, 
+                    queryFieldBuilder.buildSelect(), 
+                    new QFilter[]{qFilter});
+                    
+            DynamicObjectCollection entryEntities = getModel().getEntryEntity(FormConstant.NCKD_ENTRYENTITY);
+            entryEntities.clear();
+            
+            if (tenurePersonList != null && tenurePersonList.length > 0) {
+                for (DynamicObject person : tenurePersonList) {
+                    DynamicObject entry = entryEntities.addNew();
+                    entry.set(MasConstant.NCKD_EMPLOYEE, person.get(MasConstant.NCKD_EMPLOYEE));
+                    entry.set(MasConstant.NCKD_POSNAME, person.get(MasConstant.NCKD_POSNAME));
+                    entry.set(MasConstant.NCKD_STARTDATE, person.get(MasConstant.NCKD_STARTDATE));
+                    entry.set(MasConstant.NCKD_ENDDATE, person.get(MasConstant.NCKD_ENDDATE));
+                    entry.set(MasConstant.NCKD_SERVICEMONTHS, person.get(MasConstant.NCKD_SERVICEMONTHS));
+                }
+                this.getView().showSuccessNotification("数据加载成功!");
+            } else {
+                this.getView().showTipNotification(getNotificationMessage());
+            }
+            
+            // 初始化行选项(如果有需要)
+            for (int rowIndex = 0; rowIndex < entryEntities.size(); rowIndex++) {
+                DynamicObject entry = entryEntities.get(rowIndex);
+                int installmentYears = entry.getInt(MasConstant.NCKD_INSTALLMENTYEARS);
+                initOperateOption(installmentYears, rowIndex);
+            }
+            
+            getModel().updateEntryCache(entryEntities);
+            getView().updateView(FormConstant.NCKD_ENTRYENTITY);
+        }
+    }
+}

+ 13 - 78
code/swc/nckd-jxccl-swc/src/main/java/nckd/jxccl/swc/mas/plugin/form/incentivemgmt/EntldrMidlongApprFormPlugin.java

@@ -1,88 +1,23 @@
 package nckd.jxccl.swc.mas.plugin.form.incentivemgmt;
 
-import kd.bos.dataentity.entity.DynamicObject;
-import kd.bos.dataentity.entity.DynamicObjectCollection;
-import kd.bos.entity.constant.StatusEnum;
-import kd.bos.entity.datamodel.events.ChangeData;
-import kd.bos.entity.datamodel.events.PropertyChangedArgs;
-import kd.bos.form.plugin.AbstractFormPlugin;
-import kd.bos.orm.query.QCP;
-import kd.bos.orm.query.QFilter;
-import kd.bos.servicehelper.BusinessDataServiceHelper;
 import kd.sdk.plugin.Plugin;
-import nckd.jxccl.base.common.constant.FormConstant;
-import nckd.jxccl.base.common.utils.ConvertUtil;
-import nckd.jxccl.base.common.utils.QueryFieldBuilder;
-import nckd.jxccl.swc.mas.common.MasConstant;
-
-import java.util.Objects;
-import java.util.stream.Stream;
 
 /**
-* 企业负责人中长期激励核定表
-* 实体标识:nckd_entldrmidlongappr
-* @author W.Y.C
-* @date 2025/12/1 9:30
-* @version 1.0
-*/
-public class EntldrMidlongApprFormPlugin extends AbstractFormPlugin implements Plugin {
-
+ * 企业负责人中长期激励核定表
+ * 实体标识:nckd_entldrmidlongappr
+ * @author W.Y.C
+ * @date 2025/12/1 9:30
+ * @version 1.0
+ */
+public class EntldrMidlongApprFormPlugin extends AbstractIncentiveApprFormPlugin implements Plugin {
 
     @Override
-    public void propertyChanged(PropertyChangedArgs e) {
-        String fieldKey = e.getProperty().getName();
-        ChangeData[] changeSet = e.getChangeSet();
-        int rowIndex = changeSet[0].getRowIndex();
-        Object oldValue = changeSet[0].getOldValue();
-        Object newValue = changeSet[0].getNewValue();
-        if(Stream.of(MasConstant.NCKD_PAYUNIT, MasConstant.NCKD_LAWENTITY, MasConstant.NCKD_TERM)
-                .anyMatch(op -> op.equalsIgnoreCase(fieldKey))){
-            if(!Objects.equals(oldValue, newValue)){
-                DynamicObjectCollection entryEntities = getModel().getEntryEntity(FormConstant.NCKD_ENTRYENTITY);
-                load();
-            }
-        }
+    protected String getNotificationMessage() {
+        return "未加载到数据,根据【所属二级单位】、【法人组织】及【任期区间】未加载到对应\"子企业负责人薪酬结构\"数据!";
     }
-
-    private void load(){
-        DynamicObject payUnit = ConvertUtil.toDynamicObjectOrNull(this.getModel().getValue(MasConstant.NCKD_PAYUNIT));
-        DynamicObject lawEntity =  ConvertUtil.toDynamicObjectOrNull(this.getModel().getValue(MasConstant.NCKD_LAWENTITY));
-        DynamicObject term =  ConvertUtil.toDynamicObjectOrNull(this.getModel().getValue(MasConstant.NCKD_TERM));
-        if(payUnit != null && lawEntity != null && term != null){
-            QueryFieldBuilder queryFieldBuilder = QueryFieldBuilder.create()
-                    .addIdNumberName(MasConstant.NCKD_PAYUNIT)
-                    .addIdNumberName(MasConstant.NCKD_LAWENTITY)
-                    .addIdNumberName(MasConstant.NCKD_TERM)
-                    .addIdNumberName(MasConstant.NCKD_EMPLOYEE)
-                    .add(FormConstant.NCKD_STARTDATE)
-                    .add(FormConstant.NCKD_ENDDATE)
-                    .add(MasConstant.NCKD_POSNAME)
-                    .add(MasConstant.NCKD_SERVICEMONTHS);
-
-            QFilter qFilter = new QFilter(MasConstant.NCKD_PAYUNIT, QCP.equals, payUnit.getLong(FormConstant.ID_KEY))
-                    .and(MasConstant.NCKD_LAWENTITY, QCP.equals, lawEntity.getLong(FormConstant.ID_KEY))
-                    .and(MasConstant.NCKD_TERM, QCP.equals, term.getLong(FormConstant.ID_KEY))
-                    .and(FormConstant.STATUS, QCP.in, new String[]{StatusEnum.C.toString(), StatusEnum.B.toString()});
-            DynamicObject[] dbSubCorpSalaryArray = BusinessDataServiceHelper.load(MasConstant.TENUREPERSONLIST_ENTITYID, queryFieldBuilder.buildSelect(), new QFilter[]{qFilter});
-            DynamicObjectCollection entryEntities = getModel().getEntryEntity(FormConstant.NCKD_ENTRYENTITY);
-            entryEntities.clear();
-            if(dbSubCorpSalaryArray != null && dbSubCorpSalaryArray.length > 0) {
-                for (DynamicObject dbSubCorpSalary : dbSubCorpSalaryArray) {
-                    DynamicObject entry = entryEntities.addNew();
-                    entry.set(MasConstant.NCKD_EMPLOYEE, dbSubCorpSalary.get(MasConstant.NCKD_EMPLOYEE));
-                    entry.set(MasConstant.NCKD_POSNAME, dbSubCorpSalary.get(MasConstant.NCKD_POSNAME));
-                    entry.set(MasConstant.NCKD_STARTDATE, dbSubCorpSalary.get(MasConstant.NCKD_STARTDATE));
-                    entry.set(MasConstant.NCKD_ENDDATE, dbSubCorpSalary.get(MasConstant.NCKD_ENDDATE));
-                    entry.set(MasConstant.NCKD_SERVICEMONTHS, dbSubCorpSalary.get(MasConstant.NCKD_SERVICEMONTHS));
-                }
-                this.getView().showSuccessNotification("数据加载成功!");
-            }else{
-                this.getView().showTipNotification("未加载到数据,根据【所属二级单位】、【法人组织】及【任期区间】未加载到对应“子企业负责人薪酬结构”数据!");
-            }
-            getModel().updateEntryCache(entryEntities);
-            getView().updateView(FormConstant.NCKD_ENTRYENTITY);
-
-        }
+    
+    @Override
+    protected boolean isTriggerField(String fieldKey) {
+        return super.isTriggerField(fieldKey);
     }
-
 }

+ 19 - 77
code/swc/nckd-jxccl-swc/src/main/java/nckd/jxccl/swc/mas/plugin/form/incentivemgmt/EntldrTermBonusApprFormPlugin.java

@@ -2,33 +2,27 @@ package nckd.jxccl.swc.mas.plugin.form.incentivemgmt;
 
 import kd.bos.dataentity.entity.DynamicObject;
 import kd.bos.dataentity.entity.DynamicObjectCollection;
-import kd.bos.entity.constant.StatusEnum;
 import kd.bos.entity.datamodel.RowDataEntity;
 import kd.bos.entity.datamodel.events.AfterAddRowEventArgs;
 import kd.bos.entity.datamodel.events.ChangeData;
 import kd.bos.entity.datamodel.events.PropertyChangedArgs;
 import kd.bos.form.plugin.AbstractFormPlugin;
-import kd.bos.orm.query.QCP;
-import kd.bos.orm.query.QFilter;
-import kd.bos.servicehelper.BusinessDataServiceHelper;
 import kd.sdk.plugin.Plugin;
 import nckd.jxccl.base.common.constant.FormConstant;
 import nckd.jxccl.base.common.utils.ConvertUtil;
-import nckd.jxccl.base.common.utils.QueryFieldBuilder;
 import nckd.jxccl.swc.mas.common.MasConstant;
 
 import java.util.EventObject;
 import java.util.Objects;
-import java.util.stream.Stream;
 
 /**
-* 企业负责人任期激励核定表-表单插件
-* 实体标识:nckd_entldrtermbonusappr
-* @author W.Y.C
-* @date 2025/11/30 21:18
-* @version 1.0
-*/
-public class EntldrTermBonusApprFormPlugin extends AbstractFormPlugin implements Plugin {
+ * 企业负责人任期激励核定表-表单插件
+ * 实体标识:nckd_entldrtermbonusappr
+ * @author W.Y.C
+ * @date 2025/11/30 21:18
+ * @version 1.0
+ */
+public class EntldrTermBonusApprFormPlugin extends AbstractIncentiveApprFormPlugin implements Plugin {
 
 
     @Override
@@ -37,7 +31,7 @@ public class EntldrTermBonusApprFormPlugin extends AbstractFormPlugin implements
         for (int rowIndex = 0; rowIndex < entryCollection.size(); rowIndex++) {
             DynamicObject entry = entryCollection.get(rowIndex);
             int installmentYears = entry.getInt(MasConstant.NCKD_INSTALLMENTYEARS);
-            initOperateOption(installmentYears,rowIndex);
+            initOperateOption(installmentYears, rowIndex);
         }
     }
 
@@ -51,80 +45,29 @@ public class EntldrTermBonusApprFormPlugin extends AbstractFormPlugin implements
 
     @Override
     public void propertyChanged(PropertyChangedArgs e) {
+        super.propertyChanged(e);
+        
         String fieldKey = e.getProperty().getName();
         ChangeData[] changeSet = e.getChangeSet();
         int rowIndex = changeSet[0].getRowIndex();
         Object oldValue = changeSet[0].getOldValue();
         Object newValue = changeSet[0].getNewValue();
-        if(MasConstant.NCKD_INSTALLMENTYEARS.equalsIgnoreCase(fieldKey)){
+        
+        if (MasConstant.NCKD_INSTALLMENTYEARS.equalsIgnoreCase(fieldKey)) {
             if(!Objects.equals(oldValue, newValue)){
-                initOperateOption(ConvertUtil.toInt(newValue),rowIndex);
-            }
-        }else if(Stream.of(MasConstant.NCKD_PAYUNIT, MasConstant.NCKD_LAWENTITY, MasConstant.NCKD_TERM)
-                .anyMatch(op -> op.equalsIgnoreCase(fieldKey))){
-            if(!Objects.equals(oldValue, newValue)){
-                DynamicObjectCollection entryEntities = getModel().getEntryEntity(FormConstant.NCKD_ENTRYENTITY);
-                load();
+                initOperateOption(ConvertUtil.toInt(newValue), rowIndex);
             }
         }
     }
 
-    private void load(){
-        DynamicObject payUnit = ConvertUtil.toDynamicObjectOrNull(this.getModel().getValue(MasConstant.NCKD_PAYUNIT));
-        DynamicObject lawEntity =  ConvertUtil.toDynamicObjectOrNull(this.getModel().getValue(MasConstant.NCKD_LAWENTITY));
-        DynamicObject term =  ConvertUtil.toDynamicObjectOrNull(this.getModel().getValue(MasConstant.NCKD_TERM));
-        if(payUnit != null && lawEntity != null && term != null){
-            QueryFieldBuilder queryFieldBuilder = QueryFieldBuilder.create()
-                    .addIdNumberName(MasConstant.NCKD_PAYUNIT)
-                    .addIdNumberName(MasConstant.NCKD_LAWENTITY)
-                    .addIdNumberName(MasConstant.NCKD_TERM)
-                    .addIdNumberName(MasConstant.NCKD_EMPLOYEE)
-                    .add(FormConstant.NCKD_STARTDATE)
-                    .add(FormConstant.NCKD_ENDDATE)
-                    .add(MasConstant.NCKD_POSNAME)
-                    .add(MasConstant.NCKD_SERVICEMONTHS);
-
-            QFilter qFilter = new QFilter(MasConstant.NCKD_PAYUNIT, QCP.equals, payUnit.getLong(FormConstant.ID_KEY))
-                    .and(MasConstant.NCKD_LAWENTITY, QCP.equals, lawEntity.getLong(FormConstant.ID_KEY))
-                    .and(MasConstant.NCKD_TERM, QCP.equals, term.getLong(FormConstant.ID_KEY))
-                    .and(FormConstant.STATUS, QCP.in, new String[]{StatusEnum.C.toString(), StatusEnum.B.toString()});
-            DynamicObject[] dbSubCorpSalaryArray = BusinessDataServiceHelper.load(MasConstant.TENUREPERSONLIST_ENTITYID, queryFieldBuilder.buildSelect(), new QFilter[]{qFilter});
-            DynamicObjectCollection entryEntities = getModel().getEntryEntity(FormConstant.NCKD_ENTRYENTITY);
-            entryEntities.clear();
-            if(dbSubCorpSalaryArray != null && dbSubCorpSalaryArray.length > 0) {
-                for (DynamicObject dbSubCorpSalary : dbSubCorpSalaryArray) {
-                    DynamicObject entry = entryEntities.addNew();
-                    entry.set(MasConstant.NCKD_EMPLOYEE, dbSubCorpSalary.get(MasConstant.NCKD_EMPLOYEE));
-                    entry.set(MasConstant.NCKD_POSNAME, dbSubCorpSalary.get(MasConstant.NCKD_POSNAME));
-                    entry.set(MasConstant.NCKD_STARTDATE, dbSubCorpSalary.get(MasConstant.NCKD_STARTDATE));
-                    entry.set(MasConstant.NCKD_ENDDATE, dbSubCorpSalary.get(MasConstant.NCKD_ENDDATE));
-                    entry.set(MasConstant.NCKD_SERVICEMONTHS, dbSubCorpSalary.get(MasConstant.NCKD_SERVICEMONTHS));
-                }
-                this.getView().showSuccessNotification("数据加载成功!");
-            }else{
-                this.getView().showTipNotification("未加载到数据,根据【所属二级单位】、【法人组织】及【任期区间】未加载到对应“任期人员名单”数据!");
-            }
-            for (int rowIndex = 0; rowIndex < entryEntities.size(); rowIndex++) {
-                DynamicObject entry = entryEntities.get(rowIndex);
-                int installmentYears = entry.getInt(MasConstant.NCKD_INSTALLMENTYEARS);
-                initOperateOption(installmentYears,rowIndex);
-            }
-            getModel().updateEntryCache(entryEntities);
-            getView().updateView(FormConstant.NCKD_ENTRYENTITY);
-
-        }
+    @Override
+    protected String getNotificationMessage() {
+        return "未加载到数据,根据【所属二级单位】、【法人组织】及【任期区间】未加载到对应\"任期人员名单\"数据!";
     }
 
-    /**
-     * 设置支付N锁定或解锁
-     * @param installmentYears 分期支付年
-     * @param rowIndex 行索引
-     * @return: void
-     * @author W.Y.C
-     * @date: 2025/11/29 20:48
-     */
-    private void initOperateOption(int installmentYears, int rowIndex) {
-        if(rowIndex > -1) {
+    @Override
+    protected void initOperateOption(int installmentYears, int rowIndex) {
+        if (rowIndex > -1) {
             for (int i = 1; i <= 10; i++) {
                 this.getView().setEnable(false, rowIndex, MasConstant.NCKD_PAYYEAR + i);
                 this.getView().setEnable(false, rowIndex, MasConstant.NCKD_PAYAMOUNT + i);
@@ -133,7 +76,6 @@ public class EntldrTermBonusApprFormPlugin extends AbstractFormPlugin implements
                 this.getView().setEnable(true, rowIndex, MasConstant.NCKD_PAYYEAR + i);
                 this.getView().setEnable(true, rowIndex, MasConstant.NCKD_PAYAMOUNT + i);
             }
-//            getView().updateView(FormConstant.NCKD_ENTRYENTITY);
         }
     }
 }

+ 336 - 0
code/swc/nckd-jxccl-swc/src/main/java/nckd/jxccl/swc/mas/plugin/form/structappr/AbstractStructApprFormPlugin.java

@@ -0,0 +1,336 @@
+package nckd.jxccl.swc.mas.plugin.form.structappr;
+
+import kd.bos.bill.BillShowParameter;
+import kd.bos.dataentity.OperateOption;
+import kd.bos.dataentity.entity.DynamicObject;
+import kd.bos.dataentity.entity.DynamicObjectCollection;
+import kd.bos.dataentity.metadata.IDataEntityProperty;
+import kd.bos.dataentity.metadata.clr.DataEntityPropertyCollection;
+import kd.bos.entity.datamodel.events.AfterAddRowEventArgs;
+import kd.bos.entity.datamodel.events.ChangeData;
+import kd.bos.entity.datamodel.events.PropertyChangedArgs;
+import kd.bos.entity.operate.result.OperationResult;
+import kd.bos.entity.validate.BillStatus;
+import kd.bos.form.ConfirmCallBackListener;
+import kd.bos.form.ConfirmTypes;
+import kd.bos.form.IFormView;
+import kd.bos.form.IPageCache;
+import kd.bos.form.MessageBoxOptions;
+import kd.bos.form.MessageBoxResult;
+import kd.bos.form.ShowType;
+import kd.bos.form.events.AfterDoOperationEventArgs;
+import kd.bos.form.events.MessageBoxClosedEvent;
+import kd.bos.form.plugin.AbstractFormPlugin;
+import kd.bos.mvc.SessionManager;
+import kd.bos.orm.query.QCP;
+import kd.bos.orm.query.QFilter;
+import kd.bos.servicehelper.BusinessDataServiceHelper;
+import kd.bos.servicehelper.QueryServiceHelper;
+import kd.bos.servicehelper.operation.SaveServiceHelper;
+import kd.drp.mem.er.BillStatusEnum;
+import kd.hr.hbp.common.util.HRDynamicObjectUtils;
+import kd.sdk.plugin.Plugin;
+import nckd.jxccl.base.common.constant.FormConstant;
+import nckd.jxccl.base.common.exception.ValidationException;
+import nckd.jxccl.base.common.utils.ConvertUtil;
+import nckd.jxccl.base.common.utils.DateUtil;
+import nckd.jxccl.base.common.utils.QueryFieldBuilder;
+import nckd.jxccl.base.common.utils.ShowOperExecuteResult;
+import nckd.jxccl.base.common.utils.StrFormatter;
+import nckd.jxccl.base.entity.helper.EntityHelper;
+import nckd.jxccl.base.orm.helper.QFilterCommonHelper;
+import nckd.jxccl.swc.mas.common.MasConstant;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.time.LocalDateTime;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+/**
+ * 结构化考核审批表单插件抽象基类
+ * 用于提取子企业负责人薪酬标准核定相关表单插件的公共逻辑
+ *
+ * @author W.Y.C
+ * @date 2025/12/03
+ * @version 1.0
+ */
+public abstract class AbstractStructApprFormPlugin extends AbstractFormPlugin implements Plugin {
+
+    @Override
+    public void afterAddRow(AfterAddRowEventArgs e) {
+        initOperateOption(0, e.getInsertRow());
+    }
+
+    @Override
+    public void propertyChanged(PropertyChangedArgs e) {
+        String fieldKey = e.getProperty().getName();
+        ChangeData[] changeSet = e.getChangeSet();
+        int rowIndex = changeSet[0].getRowIndex();
+        Object oldValue = changeSet[0].getOldValue();
+        Object newValue = changeSet[0].getNewValue();
+
+        if (MasConstant.NCKD_INSTALLMENTYEARS.equalsIgnoreCase(fieldKey)) {
+            if (!Objects.equals(oldValue, newValue)) {
+                initOperateOption(ConvertUtil.toInt(newValue), rowIndex);
+            }
+        } else if (Stream.of(MasConstant.NCKD_PAYUNIT, MasConstant.NCKD_LAWENTITY, MasConstant.NCKD_YEAR)
+                .anyMatch(op -> op.equalsIgnoreCase(fieldKey))) {
+            if (!Objects.equals(oldValue, newValue)) {
+                load();
+            }
+        } else if (MasConstant.NCKD_APPRSTD.equalsIgnoreCase(fieldKey)) {
+            handleApprStdChanged(oldValue, newValue, rowIndex);
+        }
+    }
+
+    /**
+     * 处理核定标准字段变化事件
+     *
+     * @param oldValue 旧值
+     * @param newValue 新值
+     * @param rowIndex 行索引
+     */
+    protected void handleApprStdChanged(Object oldValue, Object newValue, int rowIndex) {
+        DynamicObject payUnit = ConvertUtil.toDynamicObjectOrNull(this.getModel().getValue(MasConstant.NCKD_PAYUNIT));
+        DynamicObject lawEntity = ConvertUtil.toDynamicObjectOrNull(this.getModel().getValue(MasConstant.NCKD_LAWENTITY));
+        DynamicObject projectCategory = ConvertUtil.toDynamicObjectOrNull(this.getModel().getValue(MasConstant.NCKD_PROJECTCATEGORY));
+        Date year = ConvertUtil.toDate(this.getModel().getValue(MasConstant.NCKD_YEAR));
+        // 判断"核定标准"是否大于0
+        BigDecimal apprStd = ConvertUtil.toBigDecimal(newValue);
+        if (apprStd != null && apprStd.compareTo(BigDecimal.ZERO) > 0) {
+            if (payUnit != null && lawEntity != null && year != null && projectCategory != null) {
+                if (!Objects.equals(oldValue, newValue)) {
+                    // 计算:延期支付总金额、支付年份1、支付年份1....
+                    // ====================================== 获取延期支付比例 begin ======================================
+                    LocalDateTime localDateTime = DateUtil.toLocalDateTime(year);
+                    LocalDateTime beginOfYear = DateUtil.beginOfYear(localDateTime);
+                    LocalDateTime endOfYear = DateUtil.endOfYear(localDateTime);
+
+                    QueryFieldBuilder deferPayRatoConfQueryFieldBuilder = QueryFieldBuilder.create()
+                            .add(MasConstant.NCKD_PROJECTCATEGORY)
+                            .addIdNumberName(MasConstant.NCKD_PAYUNIT)
+                            .addIdNumberName(MasConstant.NCKD_DEFERPAYMONEY)
+                            .add(MasConstant.NCKD_DEFERPAYRATIO)
+                            .add(MasConstant.NCKD_DEFERPAYRATIO)
+                            .add(MasConstant.NCKD_PAYOUTTIMES)
+                            .add(MasConstant.NCKD_YEAR)
+                            .add(FormConstant.NCKD_ENTRYENTITY)
+                            .add(FormConstant.NCKD_ENTRYENTITY, MasConstant.NCKD_TIMES)
+                            .add(FormConstant.NCKD_ENTRYENTITY, MasConstant.NCKD_PAYOUTRATIO)
+                            .add(FormConstant.NCKD_ENTRYENTITY, MasConstant.NCKD_PAYOUTMONEY)
+                            .add(FormConstant.NCKD_ENTRYENTITY, MasConstant.NCKD_DEFERREDPAYITEM)
+                            .add(FormConstant.NCKD_ENTRYENTITY, MasConstant.NCKD_DEFERREDPAYDESC)
+                            .add(FormConstant.NCKD_ENTRYENTITY, MasConstant.NCKD_TERMPAYDESC)
+                            .orderDesc(MasConstant.CREATE_TIME_KEY)
+                            .orderAsc(String.join(".", FormConstant.NCKD_ENTRYENTITY, MasConstant.NCKD_TIMES));
+                    QFilter deferPayRatoConfFilter = new QFilter(MasConstant.NCKD_PAYUNIT, QCP.equals, payUnit.getLong(FormConstant.ID_KEY))
+                            .and(MasConstant.NCKD_LAWENTITY, QCP.equals, lawEntity.getLong(FormConstant.ID_KEY))
+                            .and(MasConstant.NCKD_YEAR, QCP.large_equals, DateUtil.toDate(beginOfYear))
+                            .and(MasConstant.NCKD_YEAR, QCP.less_equals, DateUtil.toDate(endOfYear))
+                            .and(QFilterCommonHelper.getEnableFilter());
+                    DynamicObject[] dbDeferPayRatoConfArray = BusinessDataServiceHelper.load(MasConstant.DEFERPAYRATOCONF_ENTITYID, deferPayRatoConfQueryFieldBuilder.buildSelect(), new QFilter[]{deferPayRatoConfFilter});
+                    Map<String, List<DynamicObject>> dbDeferPayRatoConfMap = Arrays.stream(dbDeferPayRatoConfArray)
+                            .collect(Collectors.groupingBy(obj -> {
+                                DynamicObject dbProjectCategory = obj.getDynamicObject(MasConstant.NCKD_PROJECTCATEGORY);
+                                if (dbProjectCategory != null) {
+                                    return dbProjectCategory.getString(FormConstant.NUMBER_KEY);
+                                }
+                                return ""; // 处理无项目分类的情况
+                            }));
+                    List<DynamicObject> dbDeferPayRatoConfList = dbDeferPayRatoConfMap.get(projectCategory.getString(FormConstant.NUMBER_KEY));
+
+                    if (dbDeferPayRatoConfList != null && !dbDeferPayRatoConfList.isEmpty()) {
+                        DynamicObject deferPayRatoConf = dbDeferPayRatoConfList.get(0);
+                        // 延期支付比例(%)
+                        BigDecimal deferPayRatio = deferPayRatoConf.getBigDecimal(MasConstant.NCKD_DEFERPAYRATIO);
+                        // 延期支付金额
+                        BigDecimal deferPayMoney = deferPayRatoConf.getBigDecimal(MasConstant.NCKD_DEFERPAYMONEY);
+                        LocalDateTime beginYear = DateUtil.toLocalDateTime(deferPayRatoConf.getDate(MasConstant.NCKD_YEAR));
+                        BigDecimal deferPayTotalAmt;
+                        if (deferPayMoney != null && deferPayMoney.compareTo(BigDecimal.ZERO) > 0) {
+                            // 优先使用【延期支付金额】
+                            deferPayTotalAmt = deferPayMoney;
+                        } else {
+                            // 核算标准*延期支付比例/100
+                            deferPayTotalAmt = apprStd.multiply(deferPayRatio.divide(new BigDecimal(100), 2, RoundingMode.DOWN));
+                        }
+                        this.getModel().setValue(MasConstant.NCKD_DEFERPAYTOTALAMT, deferPayTotalAmt, rowIndex);
+                        DynamicObjectCollection entryColl = deferPayRatoConf.getDynamicObjectCollection(FormConstant.NCKD_ENTRYENTITY);
+                        int i = 0;
+                        for (DynamicObject entry : entryColl) {
+                            int times = entry.getInt(MasConstant.NCKD_TIMES);
+                            // 兑现比例(%)
+                            BigDecimal payoutRatio = entry.getBigDecimal(MasConstant.NCKD_PAYOUTRATIO);
+                            // 兑现金额
+                            BigDecimal payoutMoney = entry.getBigDecimal(MasConstant.NCKD_PAYOUTMONEY);
+                            BigDecimal payaMount;
+                            if (payoutMoney != null && payoutMoney.compareTo(BigDecimal.ZERO) > 0) {
+                                // 优先使用【兑现金额】
+                                payaMount = payoutMoney;
+                            } else {
+                                // 延期支付总金额*兑现比例
+                                payaMount = deferPayTotalAmt.multiply(payoutRatio.divide(new BigDecimal(100), 2, RoundingMode.DOWN));
+                            }
+                            if (i != 0) {
+                                beginYear = DateUtil.addYears(beginYear, 1);
+                            }
+                            this.getModel().setValue(MasConstant.NCKD_PAYYEAR + (i + 1), DateUtil.toDate(beginYear), rowIndex);
+                            this.getModel().setValue(MasConstant.NCKD_PAYAMOUNT + (i + 1), payaMount, rowIndex);
+                            i++;
+                        }
+
+                    }
+                    // ====================================== 获取延期支付比例 end ======================================
+
+                }
+            }
+        } else {
+            this.getModel().setValue(MasConstant.NCKD_DEFERPAYTOTALAMT, null);
+        }
+    }
+
+    /**
+     * 设置支付N锁定或解锁
+     *
+     * @param installmentYears 分期支付年
+     * @param rowIndex         行索引
+     */
+    protected void initOperateOption(int installmentYears, int rowIndex) {
+        if (rowIndex > -1) {
+            for (int i = 1; i <= 10; i++) {
+                this.getView().setEnable(false, rowIndex, MasConstant.NCKD_PAYYEAR + i);
+                this.getView().setEnable(false, rowIndex, MasConstant.NCKD_PAYAMOUNT + i);
+            }
+            for (int i = 1; i <= installmentYears; i++) {
+                this.getView().setEnable(true, rowIndex, MasConstant.NCKD_PAYYEAR + i);
+                this.getView().setEnable(true, rowIndex, MasConstant.NCKD_PAYAMOUNT + i);
+            }
+        }
+    }
+
+    /**
+     * 处理变更操作
+     *
+     * @param afterDoOperationEventArgs 操作事件参数
+     * @param entityName 变更实体名
+     * @param entityId 当前实体ID字段名
+     * @param changeEntityId 变更单实体ID
+     * @param changeEntityFormId 变更单表单ID
+     */
+    protected void handleDoChangeOperation(
+            AfterDoOperationEventArgs afterDoOperationEventArgs,
+            String entityName,
+            String entityId,
+            String changeEntityId,
+            String changeEntityFormId) {
+        
+        if (afterDoOperationEventArgs.getOperationResult() != null && afterDoOperationEventArgs.getOperationResult().isSuccess()) {
+            String operateKey = afterDoOperationEventArgs.getOperateKey();
+            if (operateKey.equalsIgnoreCase("change")) {
+                DynamicObject data = this.getModel().getDataEntity();
+                // 校验有没有暂存或进行中的审批单
+                QueryFieldBuilder queryFieldBuilder = QueryFieldBuilder.create()
+                        .add(FormConstant.BILL_NO_KEY);
+                QFilter filter = new QFilter(FormConstant.BILL_STATUS_KEY, QCP.not_equals, BillStatus.C.toString())
+                        .and(String.join(".", entityName, FormConstant.ID_KEY), QCP.in, data.getLong(FormConstant.ID_KEY));
+                DynamicObjectCollection query = QueryServiceHelper.query(changeEntityId, queryFieldBuilder.buildSelect(), new QFilter[]{filter});
+                if (!query.isEmpty()) {
+                    String number = query.get(0).getString(FormConstant.BILL_NO_KEY);
+                    throw new ValidationException(StrFormatter.format("已存在暂存或进行中的变更单【单据号:{}】,请勿重复申请。", number));
+                }
+
+                DynamicObjectCollection entryColl = data.getDynamicObjectCollection(FormConstant.NCKD_ENTRYENTITY);
+                DynamicObject newChangeEntity = EntityHelper.newEntity(changeEntityId);
+                HRDynamicObjectUtils.copy(data, newChangeEntity);
+                newChangeEntity.set(FormConstant.NCKD_DESCRIPTION, data.getString(FormConstant.DESCRIPTION_KEY));
+                newChangeEntity.set(entityId, data);
+                newChangeEntity.set(FormConstant.BILL_STATUS_KEY, BillStatusEnum.SAVED.getValue());
+
+                // 变更前
+                DynamicObjectCollection newEntryColl = newChangeEntity.getDynamicObjectCollection(FormConstant.NCKD_ENTRYENTITY);
+                DynamicObjectCollection newOldEntryColl = newChangeEntity.getDynamicObjectCollection("nckd_oldentryentity");
+                for (DynamicObject newEntry : newEntryColl) {
+                    // 设置源id
+                    int seq = newEntry.getInt(FormConstant.SEQ_KEY);
+                    List<DynamicObject> filteredEntries = entryColl.stream().filter(entry -> entry.getInt(FormConstant.SEQ_KEY) == seq).collect(Collectors.toList());
+                    long originId = 0L;
+                    if (!filteredEntries.isEmpty()) {
+                        originId = filteredEntries.get(0).getLong(FormConstant.ID_KEY);
+                    }
+                    newEntry.set("nckd_originid", originId);
+
+                    DynamicObject newOldEntry = newOldEntryColl.addNew();
+                    DataEntityPropertyCollection properties = newOldEntry.getDynamicObjectType().getProperties();
+                    for (IDataEntityProperty property : properties) {
+                        String oldName = property.getName();
+                        String name = oldName.replace("old", "");
+                        newOldEntry.set(oldName, newEntry.get(name));
+                    }
+                    newOldEntry.set("nckd_originidold", originId);
+                }
+                OperationResult operationResult = SaveServiceHelper.saveOperate(changeEntityId, new DynamicObject[]{newChangeEntity}, OperateOption.create());
+                if (!operationResult.isSuccess()) {
+                    String parentPageId = this.getView().getFormShowParameter().getPageId();
+                    IFormView parentView = SessionManager.getCurrent().getViewNoPlugin(parentPageId);
+                    IPageCache pageCache = (IPageCache) parentView.getService(IPageCache.class);
+                    Map<String, String> customData = operationResult.getCustomData();
+                    // 成功的记录
+                    Map<Object, Object> successMap = new HashMap<>();
+                    for (Object successPkId : operationResult.getSuccessPkIds()) {
+                        successMap.put(successPkId, customData.get(successPkId.toString()));
+                    }
+                    this.getView().showForm(ShowOperExecuteResult.getOperResultForm("载入党政职务履历", successMap, pageCache, operationResult));
+                    this.getView().invokeOperation(FormConstant.REFRESH_OP);
+                } else {
+                    // 自定义确认框按钮名称
+                    Map<Integer, String> btnNameMaps = new HashMap<Integer, String>();
+                    btnNameMaps.put(2, "我知道了");
+                    btnNameMaps.put(6, "进入变更单");
+                    ConfirmCallBackListener confirmCallBackListener =
+                            new ConfirmCallBackListener("openchange", this);
+                    List<Object> successPkIds = operationResult.getSuccessPkIds();
+                    this.getPageCache().put("changeid", ConvertUtil.toStr(successPkIds.get(0)));
+                    this.getView().showConfirm("提示", "发起暂存状态「变更单」成功,点击\"进入变更单\"按钮或在列表页面点击\"查看变更单\"即可进行数据变更并提交审批。", MessageBoxOptions.OKCancel, ConfirmTypes.Default, confirmCallBackListener, btnNameMaps);
+                }
+            }
+        }
+    }
+
+    @Override
+    public void confirmCallBack(MessageBoxClosedEvent messageBoxClosedEvent) {
+        if ("openchange".equals(messageBoxClosedEvent.getCallBackId())
+                && messageBoxClosedEvent.getResult() == MessageBoxResult.Yes) {
+            String changeEntityFormId = getChangeEntityFormId();
+            if (changeEntityFormId != null) {
+                BillShowParameter billShowParameter = new BillShowParameter();
+                billShowParameter.setFormId(changeEntityFormId);
+                billShowParameter.getOpenStyle().setShowType(ShowType.MainNewTabPage);
+                String id = this.getPageCache().get("changeid");
+                // 设置单据主键ID(关键步骤)
+                billShowParameter.setPkId(id);
+                this.getView().showForm(billShowParameter);
+            }
+        }
+    }
+
+    /**
+     * 获取变更单表单ID
+     * 子类需要重写此方法提供具体的变更单表单ID
+     *
+     * @return 变更单表单ID
+     */
+    protected abstract String getChangeEntityFormId();
+
+    /**
+     * 加载数据
+     * 子类必须实现此方法以提供具体的数据加载逻辑
+     */
+    protected abstract void load();
+}

+ 3 - 3
code/swc/nckd-jxccl-swc/src/main/java/nckd/jxccl/swc/mas/plugin/form/structappr/EntLdrItemWageApprFormPlugin.java

@@ -47,7 +47,7 @@ public class EntLdrItemWageApprFormPlugin  extends AbstractFormPlugin implements
 
     @Override
     public void afterBindingData(AfterBindingDataEvent evt) {
-        //修改“单项奖项目”,F7显示字段
+        //修改"单项奖项目",F7显示字段
         BasedataEdit edit = (BasedataEdit) evt.getSource();
         Object v = evt.getDataEntity();
         Object editSearchProp = null;
@@ -157,7 +157,7 @@ public class EntLdrItemWageApprFormPlugin  extends AbstractFormPlugin implements
                     .add(MasConstant.NCKD_SALCALCPOST);
             DynamicObject[] dbSubCoHeadServiceArray = BusinessDataServiceHelper.load(MasConstant.SUBCOHEADSERVICE_ENTITYID, subCoHeadServiceQueryFieldBuilder.buildSelect(), new QFilter[]{filter});
             if(dbSubCoHeadServiceArray == null || dbSubCoHeadServiceArray.length == 0){
-                this.getView().showTipNotification("未加载到数据,根据【所属二级单位】、【法人组织】及【年度】未加载到对应“子企业负责人任职情况”数据!");
+                this.getView().showTipNotification("未加载到数据,根据【所属二级单位】、【法人组织】及【年度】未加载到对应\"子企业负责人任职情况\"数据!");
             }
             //====================================== 获取子企业负责人任职情况 end ======================================
 
@@ -179,4 +179,4 @@ public class EntLdrItemWageApprFormPlugin  extends AbstractFormPlugin implements
 
         }
     }
-}
+}

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

@@ -1,61 +1,29 @@
 package nckd.jxccl.swc.mas.plugin.form.structappr;
 
-import kd.bos.bill.BillShowParameter;
-import kd.bos.dataentity.OperateOption;
 import kd.bos.dataentity.entity.DynamicObject;
 import kd.bos.dataentity.entity.DynamicObjectCollection;
-import kd.bos.dataentity.metadata.IDataEntityProperty;
-import kd.bos.dataentity.metadata.clr.DataEntityPropertyCollection;
 import kd.bos.entity.constant.StatusEnum;
 import kd.bos.entity.datamodel.events.AfterAddRowEventArgs;
-import kd.bos.entity.datamodel.events.ChangeData;
 import kd.bos.entity.datamodel.events.PropertyChangedArgs;
-import kd.bos.entity.operate.result.OperationResult;
-import kd.bos.entity.validate.BillStatus;
-import kd.bos.form.ConfirmCallBackListener;
-import kd.bos.form.ConfirmTypes;
-import kd.bos.form.IFormView;
-import kd.bos.form.IPageCache;
-import kd.bos.form.MessageBoxOptions;
-import kd.bos.form.MessageBoxResult;
-import kd.bos.form.ShowType;
 import kd.bos.form.events.AfterDoOperationEventArgs;
-import kd.bos.form.events.MessageBoxClosedEvent;
-import kd.bos.form.plugin.AbstractFormPlugin;
-import kd.bos.mvc.SessionManager;
 import kd.bos.orm.query.QCP;
 import kd.bos.orm.query.QFilter;
-import kd.bos.servicehelper.AttachmentServiceHelper;
 import kd.bos.servicehelper.BusinessDataServiceHelper;
-import kd.bos.servicehelper.QueryServiceHelper;
-import kd.bos.servicehelper.operation.SaveServiceHelper;
-import kd.drp.mem.er.BillStatusEnum;
-import kd.hr.hbp.common.util.HRDynamicObjectUtils;
 import kd.sdk.plugin.Plugin;
 import nckd.jxccl.base.common.constant.FormConstant;
 import nckd.jxccl.base.common.enums.mas.ProjectCategoryEnum;
-import nckd.jxccl.base.common.exception.ValidationException;
 import nckd.jxccl.base.common.utils.ConvertUtil;
 import nckd.jxccl.base.common.utils.DateUtil;
 import nckd.jxccl.base.common.utils.QueryFieldBuilder;
-import nckd.jxccl.base.common.utils.ShowOperExecuteResult;
-import nckd.jxccl.base.common.utils.StrFormatter;
-import nckd.jxccl.base.entity.helper.EntityHelper;
 import nckd.jxccl.base.orm.helper.QFilterCommonHelper;
 import nckd.jxccl.swc.mas.common.MasConstant;
 
-import java.math.BigDecimal;
-import java.math.RoundingMode;
 import java.time.LocalDateTime;
 import java.util.Arrays;
 import java.util.Date;
-import java.util.EventObject;
-import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.Objects;
 import java.util.stream.Collectors;
-import java.util.stream.Stream;
 
 /**
 * 企业负责人个人年度薪酬标准核定表-表单插件
@@ -64,10 +32,10 @@ import java.util.stream.Stream;
 * @date 2025/11/30 14:54
 * @version 1.0
 */
-public class EntleaderAnlSalStdFormPlugin extends AbstractFormPlugin implements Plugin {
+public class EntleaderAnlSalStdFormPlugin extends AbstractStructApprFormPlugin implements Plugin {
 
     @Override
-    public void afterBindData(EventObject e) {
+    public void afterBindData(java.util.EventObject e) {
         DynamicObjectCollection entryCollection = this.getModel().getEntryEntity(FormConstant.NCKD_ENTRYENTITY);
         for (int rowIndex = 0; rowIndex < entryCollection.size(); rowIndex++) {
             DynamicObject entry = entryCollection.get(rowIndex);
@@ -78,126 +46,21 @@ public class EntleaderAnlSalStdFormPlugin extends AbstractFormPlugin implements
 
     @Override
     public void afterAddRow(AfterAddRowEventArgs e) {
-        initOperateOption(0,e.getInsertRow());
+        super.afterAddRow(e);
     }
+
     @Override
     public void propertyChanged(PropertyChangedArgs e) {
-        String fieldKey = e.getProperty().getName();
-        ChangeData[] changeSet = e.getChangeSet();
-        int rowIndex = changeSet[0].getRowIndex();
-        Object oldValue = changeSet[0].getOldValue();
-        Object newValue = changeSet[0].getNewValue();
-        if(MasConstant.NCKD_INSTALLMENTYEARS.equalsIgnoreCase(fieldKey)){
-            if(!Objects.equals(oldValue, newValue)){
-                initOperateOption(ConvertUtil.toInt(newValue),rowIndex);
-            }
-        }else if(Stream.of(MasConstant.NCKD_PAYUNIT, MasConstant.NCKD_LAWENTITY, MasConstant.NCKD_YEAR)
-                .anyMatch(op -> op.equalsIgnoreCase(fieldKey))){
-            if(!Objects.equals(oldValue, newValue)){
-                DynamicObjectCollection entryEntities = getModel().getEntryEntity(FormConstant.NCKD_ENTRYENTITY);
-                load();
-            }
-        }else if(MasConstant.NCKD_APPRSTD.equalsIgnoreCase(fieldKey)){
-            DynamicObject payUnit = ConvertUtil.toDynamicObjectOrNull(this.getModel().getValue(MasConstant.NCKD_PAYUNIT));
-            DynamicObject lawEntity =  ConvertUtil.toDynamicObjectOrNull(this.getModel().getValue(MasConstant.NCKD_LAWENTITY));
-            DynamicObject projectCategory =  ConvertUtil.toDynamicObjectOrNull(this.getModel().getValue(MasConstant.NCKD_PROJECTCATEGORY));
-            Date year = ConvertUtil.toDate(this.getModel().getValue(MasConstant.NCKD_YEAR));
-            //判断“核定标准”是否大于0
-            BigDecimal apprStd = ConvertUtil.toBigDecimal(newValue);
-            if(apprStd != null && apprStd.compareTo(BigDecimal.ZERO) > 0) {
-                if (payUnit != null && lawEntity != null && year != null && projectCategory != null) {
-                    if (!Objects.equals(oldValue, newValue)) {
-                        //计算:延期支付总金额、支付年份1、支付年份1....
-                        //====================================== 获取延期支付比例 begin ======================================
-                        LocalDateTime localDateTime = DateUtil.toLocalDateTime(year);
-                        LocalDateTime beginOfYear = DateUtil.beginOfYear(localDateTime);
-                        LocalDateTime endOfYear = DateUtil.endOfYear(localDateTime);
-
-                        QueryFieldBuilder deferPayRatoConfQueryFieldBuilder = QueryFieldBuilder.create()
-                                .add(MasConstant.NCKD_PROJECTCATEGORY)
-                                .addIdNumberName(MasConstant.NCKD_PAYUNIT)
-                                .addIdNumberName(MasConstant.NCKD_DEFERPAYMONEY)
-                                .add(MasConstant.NCKD_DEFERPAYRATIO)
-                                .add(MasConstant.NCKD_DEFERPAYRATIO)
-                                .add(MasConstant.NCKD_PAYOUTTIMES)
-                                .add(MasConstant.NCKD_YEAR)
-                                .add(FormConstant.NCKD_ENTRYENTITY)
-                                .add(FormConstant.NCKD_ENTRYENTITY, MasConstant.NCKD_TIMES)
-                                .add(FormConstant.NCKD_ENTRYENTITY, MasConstant.NCKD_PAYOUTRATIO)
-                                .add(FormConstant.NCKD_ENTRYENTITY, MasConstant.NCKD_PAYOUTMONEY)
-                                .add(FormConstant.NCKD_ENTRYENTITY, MasConstant.NCKD_DEFERREDPAYITEM)
-                                .add(FormConstant.NCKD_ENTRYENTITY, MasConstant.NCKD_DEFERREDPAYDESC)
-                                .add(FormConstant.NCKD_ENTRYENTITY, MasConstant.NCKD_TERMPAYDESC)
-                                .orderDesc(MasConstant.CREATE_TIME_KEY)
-                                .orderAsc(String.join(".",FormConstant.NCKD_ENTRYENTITY, MasConstant.NCKD_TIMES));
-                        QFilter deferPayRatoConfFilter = new QFilter(MasConstant.NCKD_PAYUNIT, QCP.equals, payUnit.getLong(FormConstant.ID_KEY))
-                                .and(MasConstant.NCKD_LAWENTITY, QCP.equals, lawEntity.getLong(FormConstant.ID_KEY))
-                                .and(MasConstant.NCKD_YEAR, QCP.large_equals, DateUtil.toDate(beginOfYear))
-                                .and(MasConstant.NCKD_YEAR, QCP.less_equals, DateUtil.toDate(endOfYear))
-                                .and(QFilterCommonHelper.getEnableFilter());
-                        DynamicObject[] dbDeferPayRatoConfArray = BusinessDataServiceHelper.load(MasConstant.DEFERPAYRATOCONF_ENTITYID, deferPayRatoConfQueryFieldBuilder.buildSelect(), new QFilter[]{deferPayRatoConfFilter});
-                        Map<String, List<DynamicObject>> dbDeferPayRatoConfMap = Arrays.stream(dbDeferPayRatoConfArray)
-                                .collect(Collectors.groupingBy(obj -> {
-                                    DynamicObject dbProjectCategory = obj.getDynamicObject(MasConstant.NCKD_PROJECTCATEGORY);
-                                    if (dbProjectCategory != null) {
-                                        return dbProjectCategory.getString(FormConstant.NUMBER_KEY);
-                                    }
-                                    return ""; // 处理无项目分类的情况
-                                }));
-                        List<DynamicObject> dbDeferPayRatoConfList = dbDeferPayRatoConfMap.get(projectCategory.getString(FormConstant.NUMBER_KEY));
-
-                        if (dbDeferPayRatoConfList != null && !dbDeferPayRatoConfList.isEmpty()) {
-                            DynamicObject deferPayRatoConf = dbDeferPayRatoConfList.get(0);
-                            //延期支付比例(%)
-                            BigDecimal deferPayRatio = deferPayRatoConf.getBigDecimal(MasConstant.NCKD_DEFERPAYRATIO);
-                            //延期支付金额
-                            BigDecimal deferPayMoney = deferPayRatoConf.getBigDecimal(MasConstant.NCKD_DEFERPAYMONEY);
-                            LocalDateTime beginYear = DateUtil.toLocalDateTime(deferPayRatoConf.getDate(MasConstant.NCKD_YEAR));
-                            BigDecimal deferPayTotalAmt;
-                            if(deferPayMoney != null && deferPayMoney.compareTo(BigDecimal.ZERO) > 0){
-                                //优先使用【延期支付金额】
-                                deferPayTotalAmt = deferPayMoney;
-                            }else {
-                                //核算标准*延期支付比例/100
-                                deferPayTotalAmt = apprStd.multiply(deferPayRatio.divide(new BigDecimal(100), 2, RoundingMode.DOWN));
-                            }
-                            this.getModel().setValue(MasConstant.NCKD_DEFERPAYTOTALAMT, deferPayTotalAmt,rowIndex);
-                            DynamicObjectCollection entryColl = deferPayRatoConf.getDynamicObjectCollection(FormConstant.NCKD_ENTRYENTITY);
-                            int i = 0;
-                            for (DynamicObject entry : entryColl) {
-                                int times = entry.getInt(MasConstant.NCKD_TIMES);
-                                //兑现比例(%)
-                                BigDecimal payoutRatio = entry.getBigDecimal(MasConstant.NCKD_PAYOUTRATIO);
-                                //兑现金额
-                                BigDecimal payoutMoney = entry.getBigDecimal(MasConstant.NCKD_PAYOUTMONEY);
-                                BigDecimal payaMount;
-                                if(payoutMoney != null && payoutMoney.compareTo(BigDecimal.ZERO) > 0){
-                                    //优先使用【兑现金额】
-                                    payaMount = payoutMoney;
-                                }else{
-                                    //延期支付总金额*兑现比例
-                                    payaMount = deferPayTotalAmt.multiply(payoutRatio.divide(new BigDecimal(100), 2, RoundingMode.DOWN));
-                                }
-                                if(i != 0){
-                                    beginYear = DateUtil.addYears(beginYear, 1);
-                                }
-                                this.getModel().setValue(MasConstant.NCKD_PAYYEAR+(i+1), DateUtil.toDate(beginYear),rowIndex);
-                                this.getModel().setValue(MasConstant.NCKD_PAYAMOUNT+(i+1), payaMount,rowIndex);
-                                i++;
-                            }
-
-                        }
-                        //====================================== 获取延期支付比例 end ======================================
+        super.propertyChanged(e);
+    }
 
-                    }
-                }
-            }else{
-                this.getModel().setValue(MasConstant.NCKD_DEFERPAYTOTALAMT, null);
-            }
-        }
+    @Override
+    protected String getChangeEntityFormId() {
+        return MasConstant.ENTLDRANLSALSTDCHG_ENTITYID;
     }
 
-    private void load(){
+    @Override
+    protected void load(){
         DynamicObject payUnit = ConvertUtil.toDynamicObjectOrNull(this.getModel().getValue(MasConstant.NCKD_PAYUNIT));
         DynamicObject lawEntity =  ConvertUtil.toDynamicObjectOrNull(this.getModel().getValue(MasConstant.NCKD_LAWENTITY));
         Date year = ConvertUtil.toDate(this.getModel().getValue(MasConstant.NCKD_YEAR));
@@ -224,7 +87,7 @@ public class EntleaderAnlSalStdFormPlugin extends AbstractFormPlugin implements
                     .add(MasConstant.NCKD_SALNEGOT);
             DynamicObject[] dbSubCoHeadServiceArray = BusinessDataServiceHelper.load(MasConstant.SUBCOHEADSERVICE_ENTITYID, subCoHeadServiceQueryFieldBuilder.buildSelect(), new QFilter[]{filter});
             if(dbSubCoHeadServiceArray == null || dbSubCoHeadServiceArray.length == 0){
-                this.getView().showTipNotification("未加载到数据,根据【所属二级单位】、【法人组织】及【年度】未加载到对应“子企业负责人任职情况”数据!");
+                this.getView().showTipNotification("未加载到数据,根据【所属二级单位】、【法人组织】及【年度】未加载到对应\"子企业负责人任职情况\"数据!");
             }
             //====================================== 获取子企业负责人任职情况 end ======================================
 
@@ -242,7 +105,7 @@ public class EntleaderAnlSalStdFormPlugin extends AbstractFormPlugin implements
                     .add(FormConstant.NCKD_ENTRYENTITY, MasConstant.NCKD_TERMPAYDESC);
             DynamicObject[] dbSubCorpSalaryArray = BusinessDataServiceHelper.load(MasConstant.SUBCORPSALARY_ENTITYID, queryFieldBuilder.buildSelect(), new QFilter[]{filter});
             if(dbSubCorpSalaryArray == null || dbSubCorpSalaryArray.length == 0){
-                this.getView().showTipNotification("未加载到数据,根据【所属二级单位】、【法人组织】及【年度】未加载到对应“子企业负责人薪酬结构”数据!");
+                this.getView().showTipNotification("未加载到数据,根据【所属二级单位】、【法人组织】及【年度】未加载到对应\"子企业负责人薪酬结构\"数据!");
             }
             //====================================== 获取子企业负责人薪酬结构 end ======================================
             //====================================== 获取延期支付比例 begin ======================================
@@ -321,114 +184,10 @@ public class EntleaderAnlSalStdFormPlugin extends AbstractFormPlugin implements
 
     @Override
     public void afterDoOperation(AfterDoOperationEventArgs afterDoOperationEventArgs) {
-        if(afterDoOperationEventArgs.getOperationResult() != null && afterDoOperationEventArgs.getOperationResult().isSuccess()){
-            String operateKey = afterDoOperationEventArgs.getOperateKey();
-            if(operateKey.equalsIgnoreCase("change")){
-                DynamicObject data = this.getModel().getDataEntity();
-                //校验有没有暂存或进行中的审批单
-                QueryFieldBuilder queryFieldBuilder = QueryFieldBuilder.create()
-                        .add(FormConstant.BILL_NO_KEY);
-                QFilter filter = new QFilter(FormConstant.BILL_STATUS_KEY, QCP.not_equals, BillStatus.C.toString())
-                        .and(String.join(".", MasConstant.SUBCORPCHIEFSALSTD_ENTITYID,  FormConstant.ID_KEY), QCP.in, data.getLong(FormConstant.ID_KEY));
-                DynamicObjectCollection query = QueryServiceHelper.query(MasConstant.SUBCPCHFSALSTDCHG_ENTITYID, queryFieldBuilder.buildSelect(), new QFilter[]{filter});
-                if(!query.isEmpty()){
-                    String number = query.get(0).getString(FormConstant.BILL_NO_KEY);
-                    throw new ValidationException(StrFormatter.format("已存在暂存或进行中的变更单【单据号:{}】,请勿重复申请。", number));
-                }
-
-                DynamicObjectCollection entryColl = data.getDynamicObjectCollection(FormConstant.NCKD_ENTRYENTITY);
-                DynamicObject newSubcpChfSalStdChg = EntityHelper.newEntity(MasConstant.ENTLDRANLSALSTDCHG_ENTITYID);
-                HRDynamicObjectUtils.copy(data,newSubcpChfSalStdChg);
-                newSubcpChfSalStdChg.set(FormConstant.NCKD_DESCRIPTION,data.getString(FormConstant.DESCRIPTION_KEY));
-                newSubcpChfSalStdChg.set(MasConstant.ENTLEADERANLSALSTD_ENTITYID,data);
-                newSubcpChfSalStdChg.set(FormConstant.BILL_STATUS_KEY, BillStatusEnum.SAVED.getValue());
-                List<Map<String, Object>> attachments = AttachmentServiceHelper.getAttachments("nckd_subcorpchiefsalstd", data.getLong(FormConstant.ID_KEY), "nckd_attachmentpanelap");
-
-                //变更前
-                DynamicObjectCollection newEntryColl = newSubcpChfSalStdChg.getDynamicObjectCollection(FormConstant.NCKD_ENTRYENTITY);
-                DynamicObjectCollection newOldEntryColl = newSubcpChfSalStdChg.getDynamicObjectCollection("nckd_oldentryentity");
-                for (DynamicObject newEntry : newEntryColl) {
-                    //设置源id
-                    int seq = newEntry.getInt(FormConstant.SEQ_KEY);
-                    List<DynamicObject> filteredEntries = entryColl.stream().filter(entry -> entry.getInt(FormConstant.SEQ_KEY) == seq).collect(Collectors.toList());
-                    long originId = 0L;
-                    if(!filteredEntries.isEmpty()){
-                        originId = filteredEntries.get(0).getLong(FormConstant.ID_KEY);
-                    }
-                    newEntry.set("nckd_originid", originId);
-
-                    DynamicObject newOldEntry = newOldEntryColl.addNew();
-                    DataEntityPropertyCollection properties = newOldEntry.getDynamicObjectType().getProperties();
-                    for (IDataEntityProperty property : properties) {
-                        String oldName = property.getName();
-                        String name = oldName.replace("old","");
-                        newOldEntry.set(oldName, newEntry.get(name));
-                    }
-                    newOldEntry.set("nckd_originidold", originId);
-                }
-                OperationResult operationResult = SaveServiceHelper.saveOperate(MasConstant.ENTLDRANLSALSTDCHG_ENTITYID, new DynamicObject[]{newSubcpChfSalStdChg}, OperateOption.create());
-                if (!operationResult.isSuccess()) {
-                    String parentPageId = this.getView().getFormShowParameter().getPageId();
-                    IFormView parentView = SessionManager.getCurrent().getViewNoPlugin(parentPageId);
-                    IPageCache pageCache = (IPageCache) parentView.getService(IPageCache.class);
-                    Map<String, String> customData = operationResult.getCustomData();
-                    //成功的记录
-                    Map<Object, Object> successMap = new HashMap<>();
-                    for (Object successPkId : operationResult.getSuccessPkIds()) {
-                        successMap.put(successPkId, customData.get(successPkId.toString()));
-                    }
-                    this.getView().showForm(ShowOperExecuteResult.getOperResultForm("载入党政职务履历", successMap, pageCache, operationResult));
-                    this.getView().invokeOperation(FormConstant.REFRESH_OP);
-                } else {
-                    // 自定义确认框按钮名称
-                    Map<Integer, String> btnNameMaps = new HashMap<Integer, String>();
-                    btnNameMaps.put(2, "我知道了");
-                    btnNameMaps.put(6, "进入变更单");
-                    ConfirmCallBackListener confirmCallBackListener =
-                            new ConfirmCallBackListener("openchange", this);
-                    List<Object> successPkIds = operationResult.getSuccessPkIds();
-                    this.getPageCache().put("changeid", ConvertUtil.toStr(successPkIds.get(0)));
-                    this.getView().showConfirm("提示","发起暂存状态「变更单」成功,点击“进入变更单”按钮或在列表页面点击“查看变更单”即可进行数据变更并提交审批。", MessageBoxOptions.OKCancel, ConfirmTypes.Default, confirmCallBackListener,btnNameMaps);
-                }
-            }
-        }
-    }
-
-
-
-    @Override
-    public void confirmCallBack(MessageBoxClosedEvent messageBoxClosedEvent) {
-        if ("openchange".equals(messageBoxClosedEvent.getCallBackId())
-                && messageBoxClosedEvent.getResult() == MessageBoxResult.Yes) {
-            BillShowParameter billShowParameter = new BillShowParameter();
-            billShowParameter.setFormId(MasConstant.ENTLDRANLSALSTDCHG_ENTITYID);
-            billShowParameter.getOpenStyle().setShowType(ShowType.MainNewTabPage);
-            String id = this.getPageCache().get("changeid");
-            // 设置单据主键ID(关键步骤)
-            billShowParameter.setPkId(id);
-            this.getView().showForm(billShowParameter);
-        }
-    }
-
-    /**
-     * 设置支付N锁定或解锁
-     * @param installmentYears 分期支付年
-     * @param rowIndex 行索引
-     * @return: void
-     * @author W.Y.C
-     * @date: 2025/11/29 20:48
-     */
-    private void initOperateOption(int installmentYears, int rowIndex) {
-        if(rowIndex > -1) {
-            for (int i = 1; i <= 10; i++) {
-                this.getView().setEnable(false, rowIndex, MasConstant.NCKD_PAYYEAR + i);
-                this.getView().setEnable(false, rowIndex, MasConstant.NCKD_PAYAMOUNT + i);
-            }
-            for (int i = 1; i <= installmentYears; i++) {
-                this.getView().setEnable(true, rowIndex, MasConstant.NCKD_PAYYEAR + i);
-                this.getView().setEnable(true, rowIndex, MasConstant.NCKD_PAYAMOUNT + i);
-
-            }
-        }
+        handleDoChangeOperation(afterDoOperationEventArgs,
+                              MasConstant.ENTLEADERANLSALSTD_ENTITYID,
+                              MasConstant.ENTLEADERANLSALSTD_ENTITYID,
+                              MasConstant.ENTLDRANLSALSTDCHG_ENTITYID,
+                              MasConstant.ENTLDRANLSALSTDCHG_ENTITYID);
     }
 }

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

@@ -1,61 +1,29 @@
 package nckd.jxccl.swc.mas.plugin.form.structappr;
 
-import kd.bos.bill.BillShowParameter;
-import kd.bos.dataentity.OperateOption;
 import kd.bos.dataentity.entity.DynamicObject;
 import kd.bos.dataentity.entity.DynamicObjectCollection;
-import kd.bos.dataentity.metadata.IDataEntityProperty;
-import kd.bos.dataentity.metadata.clr.DataEntityPropertyCollection;
 import kd.bos.entity.constant.StatusEnum;
 import kd.bos.entity.datamodel.events.AfterAddRowEventArgs;
-import kd.bos.entity.datamodel.events.ChangeData;
 import kd.bos.entity.datamodel.events.PropertyChangedArgs;
-import kd.bos.entity.operate.result.OperationResult;
-import kd.bos.entity.validate.BillStatus;
-import kd.bos.form.ConfirmCallBackListener;
-import kd.bos.form.ConfirmTypes;
-import kd.bos.form.IFormView;
-import kd.bos.form.IPageCache;
-import kd.bos.form.MessageBoxOptions;
-import kd.bos.form.MessageBoxResult;
-import kd.bos.form.ShowType;
 import kd.bos.form.events.AfterDoOperationEventArgs;
-import kd.bos.form.events.MessageBoxClosedEvent;
-import kd.bos.form.plugin.AbstractFormPlugin;
-import kd.bos.mvc.SessionManager;
 import kd.bos.orm.query.QCP;
 import kd.bos.orm.query.QFilter;
-import kd.bos.servicehelper.AttachmentServiceHelper;
 import kd.bos.servicehelper.BusinessDataServiceHelper;
-import kd.bos.servicehelper.QueryServiceHelper;
-import kd.bos.servicehelper.operation.SaveServiceHelper;
-import kd.drp.mem.er.BillStatusEnum;
-import kd.hr.hbp.common.util.HRDynamicObjectUtils;
 import kd.sdk.plugin.Plugin;
 import nckd.jxccl.base.common.constant.FormConstant;
 import nckd.jxccl.base.common.enums.mas.ProjectCategoryEnum;
-import nckd.jxccl.base.common.exception.ValidationException;
 import nckd.jxccl.base.common.utils.ConvertUtil;
 import nckd.jxccl.base.common.utils.DateUtil;
 import nckd.jxccl.base.common.utils.QueryFieldBuilder;
-import nckd.jxccl.base.common.utils.ShowOperExecuteResult;
-import nckd.jxccl.base.common.utils.StrFormatter;
-import nckd.jxccl.base.entity.helper.EntityHelper;
 import nckd.jxccl.base.orm.helper.QFilterCommonHelper;
 import nckd.jxccl.swc.mas.common.MasConstant;
 
-import java.math.BigDecimal;
-import java.math.RoundingMode;
 import java.time.LocalDateTime;
 import java.util.Arrays;
 import java.util.Date;
-import java.util.EventObject;
-import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.Objects;
 import java.util.stream.Collectors;
-import java.util.stream.Stream;
 
 /**
 * 子企业负责人正职年度薪酬核定标准-表单插件
@@ -64,11 +32,11 @@ import java.util.stream.Stream;
 * @date 2025/11/29 16:36
 * @version 1.0
 */
-public class SubcorpChiefSalStdFormPlugin extends AbstractFormPlugin implements Plugin {
+public class SubcorpChiefSalStdFormPlugin extends AbstractStructApprFormPlugin implements Plugin {
 
 
     @Override
-    public void afterBindData(EventObject e) {
+    public void afterBindData(java.util.EventObject e) {
         DynamicObjectCollection entryCollection = this.getModel().getEntryEntity(FormConstant.NCKD_ENTRYENTITY);
         for (int rowIndex = 0; rowIndex < entryCollection.size(); rowIndex++) {
             DynamicObject entry = entryCollection.get(rowIndex);
@@ -79,130 +47,21 @@ public class SubcorpChiefSalStdFormPlugin extends AbstractFormPlugin implements
 
     @Override
     public void afterAddRow(AfterAddRowEventArgs e) {
-        initOperateOption(0,e.getInsertRow());
+        super.afterAddRow(e);
     }
 
     @Override
     public void propertyChanged(PropertyChangedArgs e) {
-        String fieldKey = e.getProperty().getName();
-        ChangeData[] changeSet = e.getChangeSet();
-        int rowIndex = changeSet[0].getRowIndex();
-        Object oldValue = changeSet[0].getOldValue();
-        Object newValue = changeSet[0].getNewValue();
-        if(MasConstant.NCKD_INSTALLMENTYEARS.equalsIgnoreCase(fieldKey)){
-            if(!Objects.equals(oldValue, newValue)){
-                initOperateOption(ConvertUtil.toInt(newValue),rowIndex);
-            }
-        }else if(Stream.of(MasConstant.NCKD_PAYUNIT, MasConstant.NCKD_LAWENTITY, MasConstant.NCKD_YEAR)
-                .anyMatch(op -> op.equalsIgnoreCase(fieldKey))){
-            if(!Objects.equals(oldValue, newValue)){
-                DynamicObjectCollection entryEntities = getModel().getEntryEntity(FormConstant.NCKD_ENTRYENTITY);
-                load();
-            }
-        }else if(MasConstant.NCKD_APPRSTD.equalsIgnoreCase(fieldKey)){
-            DynamicObject payUnit = ConvertUtil.toDynamicObjectOrNull(this.getModel().getValue(MasConstant.NCKD_PAYUNIT));
-            DynamicObject lawEntity =  ConvertUtil.toDynamicObjectOrNull(this.getModel().getValue(MasConstant.NCKD_LAWENTITY));
-            DynamicObject projectCategory =  ConvertUtil.toDynamicObjectOrNull(this.getModel().getValue(MasConstant.NCKD_PROJECTCATEGORY));
-            Date year = ConvertUtil.toDate(this.getModel().getValue(MasConstant.NCKD_YEAR));
-            //判断“核定标准”是否大于0
-            BigDecimal apprStd = ConvertUtil.toBigDecimal(newValue);
-            if(apprStd != null && apprStd.compareTo(BigDecimal.ZERO) > 0) {
-                if (payUnit != null && lawEntity != null && year != null && projectCategory != null) {
-                    if (!Objects.equals(oldValue, newValue)) {
-                        //计算:延期支付总金额、支付年份1、支付年份1....
-                        //====================================== 获取延期支付比例 begin ======================================
-                        LocalDateTime localDateTime = DateUtil.toLocalDateTime(year);
-                        LocalDateTime beginOfYear = DateUtil.beginOfYear(localDateTime);
-                        LocalDateTime endOfYear = DateUtil.endOfYear(localDateTime);
-
-                        QueryFieldBuilder deferPayRatoConfQueryFieldBuilder = QueryFieldBuilder.create()
-                                .add(MasConstant.NCKD_PROJECTCATEGORY)
-                                .addIdNumberName(MasConstant.NCKD_PAYUNIT)
-                                .addIdNumberName(MasConstant.NCKD_DEFERPAYMONEY)
-                                .add(MasConstant.NCKD_DEFERPAYRATIO)
-                                .add(MasConstant.NCKD_DEFERPAYRATIO)
-                                .add(MasConstant.NCKD_PAYOUTTIMES)
-                                .add(MasConstant.NCKD_YEAR)
-                                .add(FormConstant.NCKD_ENTRYENTITY)
-                                .add(FormConstant.NCKD_ENTRYENTITY, MasConstant.NCKD_TIMES)
-                                .add(FormConstant.NCKD_ENTRYENTITY, MasConstant.NCKD_PAYOUTRATIO)
-                                .add(FormConstant.NCKD_ENTRYENTITY, MasConstant.NCKD_PAYOUTMONEY)
-                                .add(FormConstant.NCKD_ENTRYENTITY, MasConstant.NCKD_DEFERREDPAYITEM)
-                                .add(FormConstant.NCKD_ENTRYENTITY, MasConstant.NCKD_DEFERREDPAYDESC)
-                                .add(FormConstant.NCKD_ENTRYENTITY, MasConstant.NCKD_TERMPAYDESC)
-                                .orderDesc(MasConstant.CREATE_TIME_KEY)
-                                .orderAsc(String.join(".",FormConstant.NCKD_ENTRYENTITY, MasConstant.NCKD_TIMES));
-                        QFilter deferPayRatoConfFilter = new QFilter(MasConstant.NCKD_PAYUNIT, QCP.equals, payUnit.getLong(FormConstant.ID_KEY))
-                                .and(MasConstant.NCKD_LAWENTITY, QCP.equals, lawEntity.getLong(FormConstant.ID_KEY))
-                                .and(MasConstant.NCKD_YEAR, QCP.large_equals, DateUtil.toDate(beginOfYear))
-                                .and(MasConstant.NCKD_YEAR, QCP.less_equals, DateUtil.toDate(endOfYear))
-                                .and(QFilterCommonHelper.getEnableFilter());
-                        DynamicObject[] dbDeferPayRatoConfArray = BusinessDataServiceHelper.load(MasConstant.DEFERPAYRATOCONF_ENTITYID, deferPayRatoConfQueryFieldBuilder.buildSelect(), new QFilter[]{deferPayRatoConfFilter});
-                        Map<String, List<DynamicObject>> dbDeferPayRatoConfMap = Arrays.stream(dbDeferPayRatoConfArray)
-                                .collect(Collectors.groupingBy(obj -> {
-                                    DynamicObject dbProjectCategory = obj.getDynamicObject(MasConstant.NCKD_PROJECTCATEGORY);
-                                    if (dbProjectCategory != null) {
-                                        return dbProjectCategory.getString(FormConstant.NUMBER_KEY);
-                                    }
-                                    return ""; // 处理无项目分类的情况
-                                }));
-                        List<DynamicObject> dbDeferPayRatoConfList = dbDeferPayRatoConfMap.get(projectCategory.getString(FormConstant.NUMBER_KEY));
-
-                        if (dbDeferPayRatoConfList != null && !dbDeferPayRatoConfList.isEmpty()) {
-                            DynamicObject deferPayRatoConf = dbDeferPayRatoConfList.get(0);
-                            //延期支付比例(%)
-                            BigDecimal deferPayRatio = deferPayRatoConf.getBigDecimal(MasConstant.NCKD_DEFERPAYRATIO);
-                            //延期支付金额
-                            BigDecimal deferPayMoney = deferPayRatoConf.getBigDecimal(MasConstant.NCKD_DEFERPAYMONEY);
-                            LocalDateTime beginYear = DateUtil.toLocalDateTime(deferPayRatoConf.getDate(MasConstant.NCKD_YEAR));
-                            BigDecimal deferPayTotalAmt;
-                            if(deferPayMoney != null && deferPayMoney.compareTo(BigDecimal.ZERO) > 0){
-                                //优先使用【延期支付金额】
-                                deferPayTotalAmt = deferPayMoney;
-                            }else {
-                                //核算标准*延期支付比例/100
-                                deferPayTotalAmt = apprStd.multiply(deferPayRatio.divide(new BigDecimal(100), 2, RoundingMode.DOWN));
-                            }
-                            this.getModel().setValue(MasConstant.NCKD_DEFERPAYTOTALAMT, deferPayTotalAmt,rowIndex);
-                            DynamicObjectCollection entryColl = deferPayRatoConf.getDynamicObjectCollection(FormConstant.NCKD_ENTRYENTITY);
-                            int i = 0;
-                            for (DynamicObject entry : entryColl) {
-                                int times = entry.getInt(MasConstant.NCKD_TIMES);
-                                //兑现比例(%)
-                                BigDecimal payoutRatio = entry.getBigDecimal(MasConstant.NCKD_PAYOUTRATIO);
-                                //兑现金额
-                                BigDecimal payoutMoney = entry.getBigDecimal(MasConstant.NCKD_PAYOUTMONEY);
-                                BigDecimal payaMount;
-                                if(payoutMoney != null && payoutMoney.compareTo(BigDecimal.ZERO) > 0){
-                                    //优先使用【兑现金额】
-                                    payaMount = payoutMoney;
-                                }else{
-                                    //延期支付总金额*兑现比例
-                                    payaMount = deferPayTotalAmt.multiply(payoutRatio.divide(new BigDecimal(100), 2, RoundingMode.DOWN));
-                                }
-                                if(i != 0){
-                                    beginYear = DateUtil.addYears(beginYear, 1);
-                                }
-                                this.getModel().setValue(MasConstant.NCKD_PAYYEAR+(i+1), DateUtil.toDate(beginYear),rowIndex);
-                                this.getModel().setValue(MasConstant.NCKD_PAYAMOUNT+(i+1), payaMount,rowIndex);
-                                i++;
-                            }
-
-                        }
-                        //====================================== 获取延期支付比例 end ======================================
-
-                    }
-                }
-            }else{
-                this.getModel().setValue(MasConstant.NCKD_DEFERPAYTOTALAMT, null);
-            }
-        }
-
+        super.propertyChanged(e);
     }
 
+    @Override
+    protected String getChangeEntityFormId() {
+        return MasConstant.SUBCPCHFSALSTDCHG_ENTITYID;
+    }
 
-
-    private void load(){
+    @Override
+    protected void load(){
         DynamicObject payUnit = ConvertUtil.toDynamicObjectOrNull(this.getModel().getValue(MasConstant.NCKD_PAYUNIT));
         DynamicObject lawEntity =  ConvertUtil.toDynamicObjectOrNull(this.getModel().getValue(MasConstant.NCKD_LAWENTITY));
         Date year = ConvertUtil.toDate(this.getModel().getValue(MasConstant.NCKD_YEAR));
@@ -276,7 +135,7 @@ public class SubcorpChiefSalStdFormPlugin extends AbstractFormPlugin implements
                     for (DynamicObject dbEntryEntity : dbEntryColl) {
                         DynamicObject projectCategory = dbEntryEntity.getDynamicObject(MasConstant.NCKD_PROJECTCATEGORY);
                         String projectCategoryNumber = projectCategory.getString(FormConstant.NUMBER_KEY);
-                        //只取分类为“年度薪酬”的数据
+                        //只取分类为"年度薪酬"的数据
                         if(projectCategoryNumber.equalsIgnoreCase(ProjectCategoryEnum.YEARLY_SALARY.getCode())) {
                             DynamicObject entry = entryEntities.addNew();
                             entry.set(MasConstant.NCKD_PROJECTCATEGORY, dbEntryEntity.getDynamicObject(MasConstant.NCKD_PROJECTCATEGORY));
@@ -296,7 +155,7 @@ public class SubcorpChiefSalStdFormPlugin extends AbstractFormPlugin implements
                 }
                 this.getView().showSuccessNotification("数据加载成功!");
             }else{
-                this.getView().showTipNotification("未加载到数据,根据【所属二级单位】、【法人组织】及【年度】未加载到对应“子企业负责人薪酬结构”数据!");
+                this.getView().showTipNotification("未加载到数据,根据【所属二级单位】、【法人组织】及【年度】未加载到对应\"子企业负责人薪酬结构\"数据!");
             }
             for (int rowIndex = 0; rowIndex < entryEntities.size(); rowIndex++) {
                 DynamicObject entry = entryEntities.get(rowIndex);
@@ -309,116 +168,12 @@ public class SubcorpChiefSalStdFormPlugin extends AbstractFormPlugin implements
         }
     }
 
-    /**
-     * 设置支付N锁定或解锁
-     * @param installmentYears 分期支付年
-     * @param rowIndex 行索引
-     * @return: void
-     * @author W.Y.C
-     * @date: 2025/11/29 20:48
-     */
-    private void initOperateOption(int installmentYears, int rowIndex) {
-        if(rowIndex > -1) {
-            for (int i = 1; i <= 10; i++) {
-                this.getView().setEnable(false, rowIndex, MasConstant.NCKD_PAYYEAR + i);
-                this.getView().setEnable(false, rowIndex, MasConstant.NCKD_PAYAMOUNT + i);
-            }
-            for (int i = 1; i <= installmentYears; i++) {
-                this.getView().setEnable(true, rowIndex, MasConstant.NCKD_PAYYEAR + i);
-                this.getView().setEnable(true, rowIndex, MasConstant.NCKD_PAYAMOUNT + i);
-
-            }
-        }
-    }
-
     @Override
     public void afterDoOperation(AfterDoOperationEventArgs afterDoOperationEventArgs) {
-        if(afterDoOperationEventArgs.getOperationResult() != null && afterDoOperationEventArgs.getOperationResult().isSuccess()){
-            String operateKey = afterDoOperationEventArgs.getOperateKey();
-            if(operateKey.equalsIgnoreCase("change")){
-                DynamicObject data = this.getModel().getDataEntity();
-                //校验有没有暂存或进行中的审批单
-                QueryFieldBuilder queryFieldBuilder = QueryFieldBuilder.create()
-                        .add(FormConstant.BILL_NO_KEY);
-                QFilter filter = new QFilter(FormConstant.BILL_STATUS_KEY, QCP.not_equals, BillStatus.C.toString())
-                        .and(String.join(".", MasConstant.SUBCORPCHIEFSALSTD_ENTITYID,  FormConstant.ID_KEY), QCP.in, data.getLong(FormConstant.ID_KEY));
-                DynamicObjectCollection query = QueryServiceHelper.query(MasConstant.SUBCPCHFSALSTDCHG_ENTITYID, queryFieldBuilder.buildSelect(), new QFilter[]{filter});
-                if(!query.isEmpty()){
-                    String number = query.get(0).getString(FormConstant.BILL_NO_KEY);
-                    throw new ValidationException(StrFormatter.format("已存在暂存或进行中的变更单【单据号:{}】,请勿重复申请。", number));
-                }
-
-                DynamicObjectCollection entryColl = data.getDynamicObjectCollection(FormConstant.NCKD_ENTRYENTITY);
-                DynamicObject newSubcpChfSalStdChg = EntityHelper.newEntity(MasConstant.SUBCPCHFSALSTDCHG_ENTITYID);
-                HRDynamicObjectUtils.copy(data,newSubcpChfSalStdChg);
-                newSubcpChfSalStdChg.set(FormConstant.NCKD_DESCRIPTION,data.getString(FormConstant.DESCRIPTION_KEY));
-                newSubcpChfSalStdChg.set(MasConstant.SUBCORPCHIEFSALSTD_ENTITYID,data);
-                newSubcpChfSalStdChg.set(FormConstant.BILL_STATUS_KEY, BillStatusEnum.SAVED.getValue());
-                List<Map<String, Object>> attachments = AttachmentServiceHelper.getAttachments("nckd_subcorpchiefsalstd", data.getLong(FormConstant.ID_KEY), "nckd_attachmentpanelap");
-
-                //变更前
-                DynamicObjectCollection newEntryColl = newSubcpChfSalStdChg.getDynamicObjectCollection(FormConstant.NCKD_ENTRYENTITY);
-                DynamicObjectCollection newOldEntryColl = newSubcpChfSalStdChg.getDynamicObjectCollection("nckd_oldentryentity");
-                for (DynamicObject newEntry : newEntryColl) {
-                    //设置源id
-                    int seq = newEntry.getInt(FormConstant.SEQ_KEY);
-                    List<DynamicObject> filteredEntries = entryColl.stream().filter(entry -> entry.getInt(FormConstant.SEQ_KEY) == seq).collect(Collectors.toList());
-                    long originId = 0L;
-                    if(!filteredEntries.isEmpty()){
-                        originId = filteredEntries.get(0).getLong(FormConstant.ID_KEY);
-                    }
-                    newEntry.set("nckd_originid", originId);
-
-                    DynamicObject newOldEntry = newOldEntryColl.addNew();
-                    DataEntityPropertyCollection properties = newOldEntry.getDynamicObjectType().getProperties();
-                    for (IDataEntityProperty property : properties) {
-                        String oldName = property.getName();
-                        String name = oldName.replace("old","");
-                        newOldEntry.set(oldName, newEntry.get(name));
-                    }
-                    newOldEntry.set("nckd_originidold", originId);
-                }
-                OperationResult operationResult = SaveServiceHelper.saveOperate(MasConstant.SUBCPCHFSALSTDCHG_ENTITYID, new DynamicObject[]{newSubcpChfSalStdChg}, OperateOption.create());
-                if (!operationResult.isSuccess()) {
-                    String parentPageId = this.getView().getFormShowParameter().getPageId();
-                    IFormView parentView = SessionManager.getCurrent().getViewNoPlugin(parentPageId);
-                    IPageCache pageCache = (IPageCache) parentView.getService(IPageCache.class);
-                    Map<String, String> customData = operationResult.getCustomData();
-                    //成功的记录
-                    Map<Object, Object> successMap = new HashMap<>();
-                    for (Object successPkId : operationResult.getSuccessPkIds()) {
-                        successMap.put(successPkId, customData.get(successPkId.toString()));
-                    }
-                    this.getView().showForm(ShowOperExecuteResult.getOperResultForm("载入党政职务履历", successMap, pageCache, operationResult));
-                    this.getView().invokeOperation(FormConstant.REFRESH_OP);
-                } else {
-                    // 自定义确认框按钮名称
-                    Map<Integer, String> btnNameMaps = new HashMap<Integer, String>();
-                    btnNameMaps.put(2, "我知道了");
-                    btnNameMaps.put(6, "进入变更单");
-                    ConfirmCallBackListener confirmCallBackListener =
-                            new ConfirmCallBackListener("openchange", this);
-                    List<Object> successPkIds = operationResult.getSuccessPkIds();
-                    this.getPageCache().put("changeid", ConvertUtil.toStr(successPkIds.get(0)));
-                    this.getView().showConfirm("提示","发起暂存状态「变更单」成功,点击“进入变更单”按钮或在列表页面点击“查看变更单”即可进行数据变更并提交审批。",MessageBoxOptions.OKCancel,ConfirmTypes.Default, confirmCallBackListener,btnNameMaps);
-                }
-            }
-        }
-    }
-
-
-
-    @Override
-    public void confirmCallBack(MessageBoxClosedEvent messageBoxClosedEvent) {
-        if ("openchange".equals(messageBoxClosedEvent.getCallBackId())
-                && messageBoxClosedEvent.getResult() == MessageBoxResult.Yes) {
-            BillShowParameter billShowParameter = new BillShowParameter();
-            billShowParameter.setFormId(MasConstant.SUBCPCHFSALSTDCHG_ENTITYID);
-            billShowParameter.getOpenStyle().setShowType(ShowType.MainNewTabPage);
-            String id = this.getPageCache().get("changeid");
-            // 设置单据主键ID(关键步骤)
-            billShowParameter.setPkId(id);
-            this.getView().showForm(billShowParameter);
-        }
+        handleDoChangeOperation(afterDoOperationEventArgs, 
+                              MasConstant.SUBCORPCHIEFSALSTD_ENTITYID, 
+                              MasConstant.SUBCORPCHIEFSALSTD_ENTITYID,
+                              MasConstant.SUBCPCHFSALSTDCHG_ENTITYID,
+                              MasConstant.SUBCPCHFSALSTDCHG_ENTITYID);
     }
 }

+ 233 - 0
code/swc/nckd-jxccl-swc/src/main/java/nckd/jxccl/swc/mas/plugin/form/structappr/change/AbstractSalaryStdChgFormPlugin.java

@@ -0,0 +1,233 @@
+package nckd.jxccl.swc.mas.plugin.form.structappr.change;
+
+import kd.bos.dataentity.entity.DynamicObject;
+import kd.bos.dataentity.entity.DynamicObjectCollection;
+import kd.bos.dataentity.metadata.IDataEntityProperty;
+import kd.bos.dataentity.metadata.clr.DataEntityPropertyCollection;
+import kd.bos.entity.datamodel.events.AfterAddRowEventArgs;
+import kd.bos.entity.datamodel.events.ChangeData;
+import kd.bos.entity.datamodel.events.PropertyChangedArgs;
+import kd.bos.entity.report.CellStyle;
+import kd.bos.form.control.EntryGrid;
+import kd.bos.form.plugin.AbstractFormPlugin;
+import kd.bos.orm.query.QCP;
+import kd.bos.orm.query.QFilter;
+import kd.bos.servicehelper.BusinessDataServiceHelper;
+import nckd.jxccl.base.common.constant.FormConstant;
+import nckd.jxccl.base.common.utils.ConvertUtil;
+import nckd.jxccl.base.common.utils.DateUtil;
+import nckd.jxccl.base.common.utils.QueryFieldBuilder;
+import nckd.jxccl.base.orm.helper.QFilterCommonHelper;
+import nckd.jxccl.swc.mas.common.MasConstant;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.time.LocalDateTime;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+/**
+ * 薪酬标准变更表单插件抽象基类
+ *
+ * @author W.Y.C
+ * @date 2025/12/03
+ */
+public abstract class AbstractSalaryStdChgFormPlugin extends AbstractFormPlugin {
+
+    @Override
+    public void afterBindData(java.util.EventObject e) {
+        DynamicObjectCollection entryCollection = this.getModel().getEntryEntity(FormConstant.NCKD_ENTRYENTITY);
+        for (int rowIndex = 0; rowIndex < entryCollection.size(); rowIndex++) {
+            DynamicObject entry = entryCollection.get(rowIndex);
+            int installmentYears = entry.getInt(MasConstant.NCKD_INSTALLMENTYEARS);
+            initOperateOption(installmentYears, rowIndex);
+        }
+        markChange();
+    }
+
+    @Override
+    public void afterAddRow(AfterAddRowEventArgs e) {
+        initOperateOption(0, e.getInsertRow());
+    }
+
+    @Override
+    public void propertyChanged(PropertyChangedArgs e) {
+        String fieldKey = e.getProperty().getName();
+        ChangeData[] changeSet = e.getChangeSet();
+        int rowIndex = changeSet[0].getRowIndex();
+        Object oldValue = changeSet[0].getOldValue();
+        Object newValue = changeSet[0].getNewValue();
+        
+        if (MasConstant.NCKD_INSTALLMENTYEARS.equalsIgnoreCase(fieldKey)) {
+            if (!Objects.equals(oldValue, newValue)) {
+                initOperateOption(ConvertUtil.toInt(newValue), rowIndex);
+            }
+        } else if (MasConstant.NCKD_APPRSTD.equalsIgnoreCase(fieldKey)) {
+            handleApprStdChanged(oldValue, newValue, rowIndex);
+        }
+        markChange();
+    }
+
+    /**
+     * 处理核定标准字段变化
+     * @param oldValue 旧值
+     * @param newValue 新值
+     * @param rowIndex 行索引
+     */
+    private void handleApprStdChanged(Object oldValue, Object newValue, int rowIndex) {
+        DynamicObject payUnit = ConvertUtil.toDynamicObjectOrNull(this.getModel().getValue(MasConstant.NCKD_PAYUNIT));
+        DynamicObject lawEntity = ConvertUtil.toDynamicObjectOrNull(this.getModel().getValue(MasConstant.NCKD_LAWENTITY));
+        DynamicObject projectCategory = ConvertUtil.toDynamicObjectOrNull(this.getModel().getValue(MasConstant.NCKD_PROJECTCATEGORY));
+        Date year = ConvertUtil.toDate(this.getModel().getValue(MasConstant.NCKD_YEAR));
+        //判断"核定标准"是否大于0
+        BigDecimal apprStd = ConvertUtil.toBigDecimal(newValue);
+        if (apprStd != null && apprStd.compareTo(BigDecimal.ZERO) > 0) {
+            if (payUnit != null && lawEntity != null && year != null && projectCategory != null) {
+                if (!Objects.equals(oldValue, newValue)) {
+                    //计算:延期支付总金额、支付年份1、支付年份1....
+                    //====================================== 获取延期支付比例 begin ======================================
+                    LocalDateTime localDateTime = DateUtil.toLocalDateTime(year);
+                    LocalDateTime beginOfYear = DateUtil.beginOfYear(localDateTime);
+                    LocalDateTime endOfYear = DateUtil.endOfYear(localDateTime);
+
+                    QueryFieldBuilder deferPayRatoConfQueryFieldBuilder = QueryFieldBuilder.create()
+                            .add(MasConstant.NCKD_PROJECTCATEGORY)
+                            .addIdNumberName(MasConstant.NCKD_PAYUNIT)
+                            .addIdNumberName(MasConstant.NCKD_DEFERPAYMONEY)
+                            .add(MasConstant.NCKD_DEFERPAYRATIO)
+                            .add(MasConstant.NCKD_DEFERPAYRATIO)
+                            .add(MasConstant.NCKD_PAYOUTTIMES)
+                            .add(MasConstant.NCKD_YEAR)
+                            .add(FormConstant.NCKD_ENTRYENTITY)
+                            .add(FormConstant.NCKD_ENTRYENTITY, MasConstant.NCKD_TIMES)
+                            .add(FormConstant.NCKD_ENTRYENTITY, MasConstant.NCKD_PAYOUTRATIO)
+                            .add(FormConstant.NCKD_ENTRYENTITY, MasConstant.NCKD_PAYOUTMONEY)
+                            .add(FormConstant.NCKD_ENTRYENTITY, MasConstant.NCKD_DEFERREDPAYITEM)
+                            .add(FormConstant.NCKD_ENTRYENTITY, MasConstant.NCKD_DEFERREDPAYDESC)
+                            .add(FormConstant.NCKD_ENTRYENTITY, MasConstant.NCKD_TERMPAYDESC)
+                            .orderDesc(MasConstant.CREATE_TIME_KEY)
+                            .orderAsc(String.join(".", FormConstant.NCKD_ENTRYENTITY, MasConstant.NCKD_TIMES));
+                    QFilter deferPayRatoConfFilter = new QFilter(MasConstant.NCKD_PAYUNIT, QCP.equals, payUnit.getLong(FormConstant.ID_KEY))
+                            .and(MasConstant.NCKD_LAWENTITY, QCP.equals, lawEntity.getLong(FormConstant.ID_KEY))
+                            .and(MasConstant.NCKD_YEAR, QCP.large_equals, DateUtil.toDate(beginOfYear))
+                            .and(MasConstant.NCKD_YEAR, QCP.less_equals, DateUtil.toDate(endOfYear))
+                            .and(QFilterCommonHelper.getEnableFilter());
+                    DynamicObject[] dbDeferPayRatoConfArray = BusinessDataServiceHelper.load(MasConstant.DEFERPAYRATOCONF_ENTITYID, deferPayRatoConfQueryFieldBuilder.buildSelect(), new QFilter[]{deferPayRatoConfFilter});
+                    Map<String, List<DynamicObject>> dbDeferPayRatoConfMap = Arrays.stream(dbDeferPayRatoConfArray)
+                            .collect(Collectors.groupingBy(obj -> {
+                                DynamicObject dbProjectCategory = obj.getDynamicObject(MasConstant.NCKD_PROJECTCATEGORY);
+                                if (dbProjectCategory != null) {
+                                    return dbProjectCategory.getString(FormConstant.NUMBER_KEY);
+                                }
+                                return ""; // 处理无项目分类的情况
+                            }));
+                    List<DynamicObject> dbDeferPayRatoConfList = dbDeferPayRatoConfMap.get(projectCategory.getString(FormConstant.NUMBER_KEY));
+
+                    if (dbDeferPayRatoConfList != null && !dbDeferPayRatoConfList.isEmpty()) {
+                        DynamicObject deferPayRatoConf = dbDeferPayRatoConfList.get(0);
+                        //延期支付比例(%)
+                        BigDecimal deferPayRatio = deferPayRatoConf.getBigDecimal(MasConstant.NCKD_DEFERPAYRATIO);
+                        //延期支付金额
+                        BigDecimal deferPayMoney = deferPayRatoConf.getBigDecimal(MasConstant.NCKD_DEFERPAYMONEY);
+                        LocalDateTime beginYear = DateUtil.toLocalDateTime(deferPayRatoConf.getDate(MasConstant.NCKD_YEAR));
+                        BigDecimal deferPayTotalAmt;
+                        if (deferPayMoney != null && deferPayMoney.compareTo(BigDecimal.ZERO) > 0) {
+                            //优先使用【延期支付金额】
+                            deferPayTotalAmt = deferPayMoney;
+                        } else {
+                            //核算标准*延期支付比例/100
+                            deferPayTotalAmt = apprStd.multiply(deferPayRatio.divide(new BigDecimal(100), 2, RoundingMode.DOWN));
+                        }
+                        this.getModel().setValue(MasConstant.NCKD_DEFERPAYTOTALAMT, deferPayTotalAmt, rowIndex);
+                        DynamicObjectCollection entryColl = deferPayRatoConf.getDynamicObjectCollection(FormConstant.NCKD_ENTRYENTITY);
+                        int i = 0;
+                        for (DynamicObject entry : entryColl) {
+                            int times = entry.getInt(MasConstant.NCKD_TIMES);
+                            //兑现比例(%)
+                            BigDecimal payoutRatio = entry.getBigDecimal(MasConstant.NCKD_PAYOUTRATIO);
+                            //兑现金额
+                            BigDecimal payoutMoney = entry.getBigDecimal(MasConstant.NCKD_PAYOUTMONEY);
+                            BigDecimal payaMount;
+                            if (payoutMoney != null && payoutMoney.compareTo(BigDecimal.ZERO) > 0) {
+                                //优先使用【兑现金额】
+                                payaMount = payoutMoney;
+                            } else {
+                                //延期支付总金额*兑现比例
+                                payaMount = deferPayTotalAmt.multiply(payoutRatio.divide(new BigDecimal(100), 2, RoundingMode.DOWN));
+                            }
+                            if (i != 0) {
+                                beginYear = DateUtil.addYears(beginYear, 1);
+                            }
+                            this.getModel().setValue(MasConstant.NCKD_PAYYEAR + (i + 1), DateUtil.toDate(beginYear), rowIndex);
+                            this.getModel().setValue(MasConstant.NCKD_PAYAMOUNT + (i + 1), payaMount, rowIndex);
+                            i++;
+                        }
+
+                    }
+                    //====================================== 获取延期支付比例 end ======================================
+
+                }
+            }
+        } else {
+            this.getModel().setValue(MasConstant.NCKD_DEFERPAYTOTALAMT, null);
+        }
+    }
+
+    /**
+     * 设置支付N锁定或解锁
+     * @param installmentYears 分期支付年
+     * @param rowIndex 行索引
+     */
+    private void initOperateOption(int installmentYears, int rowIndex) {
+        if (rowIndex > -1) {
+            for (int i = 1; i <= 10; i++) {
+                this.getView().setEnable(false, rowIndex, MasConstant.NCKD_PAYYEAR + i);
+                this.getView().setEnable(false, rowIndex, MasConstant.NCKD_PAYAMOUNT + i);
+            }
+            for (int i = 1; i <= installmentYears; i++) {
+                this.getView().setEnable(true, rowIndex, MasConstant.NCKD_PAYYEAR + i);
+                this.getView().setEnable(true, rowIndex, MasConstant.NCKD_PAYAMOUNT + i);
+            }
+        }
+    }
+
+    //标记变更
+    private void markChange() {
+        DynamicObjectCollection entryColl = this.getModel().getDataEntity(true).getDynamicObjectCollection(FormConstant.NCKD_ENTRYENTITY);
+        DynamicObjectCollection oldEntryColl = this.getModel().getDataEntity(true).getDynamicObjectCollection("nckd_oldentryentity");
+
+        List<CellStyle> cellStyles = new ArrayList<>();
+        int i = 0;
+        for (DynamicObject entry : entryColl) {
+            long originId = entry.getLong("nckd_originid");
+            for (DynamicObject oldEntry : oldEntryColl) {
+                long oldOriginId = oldEntry.getLong("nckd_originidold");
+                if (originId == oldOriginId) {
+                    DataEntityPropertyCollection properties = oldEntry.getDynamicObjectType().getProperties();
+                    for (IDataEntityProperty property : properties) {
+                        String oldName = property.getName();
+                        String name = oldName.replace("old", "");
+                        Object value = entry.get(name);
+                        Object oldValue = oldEntry.get(oldName);
+                        if (!Objects.equals(value, oldValue)) {
+                            CellStyle cellStyle = new CellStyle();
+                            cellStyle.setFieldKey(name);
+                            cellStyle.setRow(i);
+                            cellStyle.setForeColor("#fb2323");
+                            cellStyles.add(cellStyle);
+                        }
+
+                    }
+                }
+            }
+            i++;
+        }
+        EntryGrid entryGrid = this.getControl(FormConstant.NCKD_ENTRYENTITY);
+        entryGrid.setCellStyle(cellStyles);
+    }
+}

+ 2 - 219
code/swc/nckd-jxccl-swc/src/main/java/nckd/jxccl/swc/mas/plugin/form/structappr/change/EntldrAnlSalStdChgFormPlugin.java

@@ -1,38 +1,6 @@
 package nckd.jxccl.swc.mas.plugin.form.structappr.change;
 
-import kd.bos.dataentity.entity.DynamicObject;
-import kd.bos.dataentity.entity.DynamicObjectCollection;
-import kd.bos.dataentity.metadata.IDataEntityProperty;
-import kd.bos.dataentity.metadata.clr.DataEntityPropertyCollection;
-import kd.bos.entity.datamodel.events.AfterAddRowEventArgs;
-import kd.bos.entity.datamodel.events.ChangeData;
-import kd.bos.entity.datamodel.events.PropertyChangedArgs;
-import kd.bos.entity.report.CellStyle;
-import kd.bos.form.control.EntryGrid;
-import kd.bos.form.plugin.AbstractFormPlugin;
-import kd.bos.orm.query.QCP;
-import kd.bos.orm.query.QFilter;
-import kd.bos.servicehelper.BusinessDataServiceHelper;
 import kd.sdk.plugin.Plugin;
-import nckd.jxccl.base.common.constant.FormConstant;
-import nckd.jxccl.base.common.utils.ConvertUtil;
-import nckd.jxccl.base.common.utils.DateUtil;
-import nckd.jxccl.base.common.utils.QueryFieldBuilder;
-import nckd.jxccl.base.orm.helper.QFilterCommonHelper;
-import nckd.jxccl.swc.mas.common.MasConstant;
-
-import java.math.BigDecimal;
-import java.math.RoundingMode;
-import java.time.LocalDateTime;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Date;
-import java.util.EventObject;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
 
 /**
 * 企业负责人个人年度薪酬标准核定表_变更单
@@ -41,191 +9,6 @@ import java.util.stream.Stream;
 * @date 2025/12/3 18:41
 * @version 1.0
 */
-public class EntldrAnlSalStdChgFormPlugin extends AbstractFormPlugin implements Plugin {
-
-    @Override
-    public void afterBindData(EventObject e) {
-        DynamicObjectCollection entryCollection = this.getModel().getEntryEntity(FormConstant.NCKD_ENTRYENTITY);
-        for (int rowIndex = 0; rowIndex < entryCollection.size(); rowIndex++) {
-            DynamicObject entry = entryCollection.get(rowIndex);
-            int installmentYears = entry.getInt(MasConstant.NCKD_INSTALLMENTYEARS);
-            initOperateOption(installmentYears,rowIndex);
-        }
-        markChange();
-    }
-
-    @Override
-    public void afterAddRow(AfterAddRowEventArgs e) {
-        initOperateOption(0,e.getInsertRow());
-    }
-
-    @Override
-    public void propertyChanged(PropertyChangedArgs e) {
-        String fieldKey = e.getProperty().getName();
-        ChangeData[] changeSet = e.getChangeSet();
-        int rowIndex = changeSet[0].getRowIndex();
-        Object oldValue = changeSet[0].getOldValue();
-        Object newValue = changeSet[0].getNewValue();
-        if (MasConstant.NCKD_INSTALLMENTYEARS.equalsIgnoreCase(fieldKey)) {
-            if (!Objects.equals(oldValue, newValue)) {
-                initOperateOption(ConvertUtil.toInt(newValue), rowIndex);
-            }
-        }  else if (MasConstant.NCKD_APPRSTD.equalsIgnoreCase(fieldKey)) {
-            DynamicObject payUnit = ConvertUtil.toDynamicObjectOrNull(this.getModel().getValue(MasConstant.NCKD_PAYUNIT));
-            DynamicObject lawEntity = ConvertUtil.toDynamicObjectOrNull(this.getModel().getValue(MasConstant.NCKD_LAWENTITY));
-            DynamicObject projectCategory = ConvertUtil.toDynamicObjectOrNull(this.getModel().getValue(MasConstant.NCKD_PROJECTCATEGORY));
-            Date year = ConvertUtil.toDate(this.getModel().getValue(MasConstant.NCKD_YEAR));
-            //判断“核定标准”是否大于0
-            BigDecimal apprStd = ConvertUtil.toBigDecimal(newValue);
-            if (apprStd != null && apprStd.compareTo(BigDecimal.ZERO) > 0) {
-                if (payUnit != null && lawEntity != null && year != null && projectCategory != null) {
-                    if (!Objects.equals(oldValue, newValue)) {
-                        //计算:延期支付总金额、支付年份1、支付年份1....
-                        //====================================== 获取延期支付比例 begin ======================================
-                        LocalDateTime localDateTime = DateUtil.toLocalDateTime(year);
-                        LocalDateTime beginOfYear = DateUtil.beginOfYear(localDateTime);
-                        LocalDateTime endOfYear = DateUtil.endOfYear(localDateTime);
-
-                        QueryFieldBuilder deferPayRatoConfQueryFieldBuilder = QueryFieldBuilder.create()
-                                .add(MasConstant.NCKD_PROJECTCATEGORY)
-                                .addIdNumberName(MasConstant.NCKD_PAYUNIT)
-                                .addIdNumberName(MasConstant.NCKD_DEFERPAYMONEY)
-                                .add(MasConstant.NCKD_DEFERPAYRATIO)
-                                .add(MasConstant.NCKD_DEFERPAYRATIO)
-                                .add(MasConstant.NCKD_PAYOUTTIMES)
-                                .add(MasConstant.NCKD_YEAR)
-                                .add(FormConstant.NCKD_ENTRYENTITY)
-                                .add(FormConstant.NCKD_ENTRYENTITY, MasConstant.NCKD_TIMES)
-                                .add(FormConstant.NCKD_ENTRYENTITY, MasConstant.NCKD_PAYOUTRATIO)
-                                .add(FormConstant.NCKD_ENTRYENTITY, MasConstant.NCKD_PAYOUTMONEY)
-                                .add(FormConstant.NCKD_ENTRYENTITY, MasConstant.NCKD_DEFERREDPAYITEM)
-                                .add(FormConstant.NCKD_ENTRYENTITY, MasConstant.NCKD_DEFERREDPAYDESC)
-                                .add(FormConstant.NCKD_ENTRYENTITY, MasConstant.NCKD_TERMPAYDESC)
-                                .orderDesc(MasConstant.CREATE_TIME_KEY)
-                                .orderAsc(String.join(".", FormConstant.NCKD_ENTRYENTITY, MasConstant.NCKD_TIMES));
-                        QFilter deferPayRatoConfFilter = new QFilter(MasConstant.NCKD_PAYUNIT, QCP.equals, payUnit.getLong(FormConstant.ID_KEY))
-                                .and(MasConstant.NCKD_LAWENTITY, QCP.equals, lawEntity.getLong(FormConstant.ID_KEY))
-                                .and(MasConstant.NCKD_YEAR, QCP.large_equals, DateUtil.toDate(beginOfYear))
-                                .and(MasConstant.NCKD_YEAR, QCP.less_equals, DateUtil.toDate(endOfYear))
-                                .and(QFilterCommonHelper.getEnableFilter());
-                        DynamicObject[] dbDeferPayRatoConfArray = BusinessDataServiceHelper.load(MasConstant.DEFERPAYRATOCONF_ENTITYID, deferPayRatoConfQueryFieldBuilder.buildSelect(), new QFilter[]{deferPayRatoConfFilter});
-                        Map<String, List<DynamicObject>> dbDeferPayRatoConfMap = Arrays.stream(dbDeferPayRatoConfArray)
-                                .collect(Collectors.groupingBy(obj -> {
-                                    DynamicObject dbProjectCategory = obj.getDynamicObject(MasConstant.NCKD_PROJECTCATEGORY);
-                                    if (dbProjectCategory != null) {
-                                        return dbProjectCategory.getString(FormConstant.NUMBER_KEY);
-                                    }
-                                    return ""; // 处理无项目分类的情况
-                                }));
-                        List<DynamicObject> dbDeferPayRatoConfList = dbDeferPayRatoConfMap.get(projectCategory.getString(FormConstant.NUMBER_KEY));
-
-                        if (dbDeferPayRatoConfList != null && !dbDeferPayRatoConfList.isEmpty()) {
-                            DynamicObject deferPayRatoConf = dbDeferPayRatoConfList.get(0);
-                            //延期支付比例(%)
-                            BigDecimal deferPayRatio = deferPayRatoConf.getBigDecimal(MasConstant.NCKD_DEFERPAYRATIO);
-                            //延期支付金额
-                            BigDecimal deferPayMoney = deferPayRatoConf.getBigDecimal(MasConstant.NCKD_DEFERPAYMONEY);
-                            LocalDateTime beginYear = DateUtil.toLocalDateTime(deferPayRatoConf.getDate(MasConstant.NCKD_YEAR));
-                            BigDecimal deferPayTotalAmt;
-                            if (deferPayMoney != null && deferPayMoney.compareTo(BigDecimal.ZERO) > 0) {
-                                //优先使用【延期支付金额】
-                                deferPayTotalAmt = deferPayMoney;
-                            } else {
-                                //核算标准*延期支付比例/100
-                                deferPayTotalAmt = apprStd.multiply(deferPayRatio.divide(new BigDecimal(100), 2, RoundingMode.DOWN));
-                            }
-                            this.getModel().setValue(MasConstant.NCKD_DEFERPAYTOTALAMT, deferPayTotalAmt, rowIndex);
-                            DynamicObjectCollection entryColl = deferPayRatoConf.getDynamicObjectCollection(FormConstant.NCKD_ENTRYENTITY);
-                            int i = 0;
-                            for (DynamicObject entry : entryColl) {
-                                int times = entry.getInt(MasConstant.NCKD_TIMES);
-                                //兑现比例(%)
-                                BigDecimal payoutRatio = entry.getBigDecimal(MasConstant.NCKD_PAYOUTRATIO);
-                                //兑现金额
-                                BigDecimal payoutMoney = entry.getBigDecimal(MasConstant.NCKD_PAYOUTMONEY);
-                                BigDecimal payaMount;
-                                if (payoutMoney != null && payoutMoney.compareTo(BigDecimal.ZERO) > 0) {
-                                    //优先使用【兑现金额】
-                                    payaMount = payoutMoney;
-                                } else {
-                                    //延期支付总金额*兑现比例
-                                    payaMount = deferPayTotalAmt.multiply(payoutRatio.divide(new BigDecimal(100), 2, RoundingMode.DOWN));
-                                }
-                                if (i != 0) {
-                                    beginYear = DateUtil.addYears(beginYear, 1);
-                                }
-                                this.getModel().setValue(MasConstant.NCKD_PAYYEAR + (i + 1), DateUtil.toDate(beginYear), rowIndex);
-                                this.getModel().setValue(MasConstant.NCKD_PAYAMOUNT + (i + 1), payaMount, rowIndex);
-                                i++;
-                            }
-
-                        }
-                        //====================================== 获取延期支付比例 end ======================================
-
-                    }
-                }
-            } else {
-                this.getModel().setValue(MasConstant.NCKD_DEFERPAYTOTALAMT, null);
-            }
-        }
-        markChange();
-    }
-
-    //标记变更
-    private void markChange(){
-        DynamicObjectCollection entryColl = this.getModel().getDataEntity(true).getDynamicObjectCollection(FormConstant.NCKD_ENTRYENTITY);
-        DynamicObjectCollection oldEntryColl = this.getModel().getDataEntity(true).getDynamicObjectCollection("nckd_oldentryentity");
-
-        List<CellStyle> cellStyles = new ArrayList<>();
-        int i = 0;
-        for (DynamicObject entry : entryColl) {
-            long originId = entry.getLong("nckd_originid");
-            for (DynamicObject oldEntry : oldEntryColl) {
-                long oldOriginId = oldEntry.getLong("nckd_originidold");
-                if(originId == oldOriginId){
-                    DataEntityPropertyCollection properties = oldEntry.getDynamicObjectType().getProperties();
-                    for (IDataEntityProperty property : properties) {
-                        String oldName = property.getName();
-                        String name = oldName.replace("old","");
-                        Object value = entry.get(name);
-                        Object oldValue = oldEntry.get(oldName);
-                        if(!Objects.equals(value, oldValue)){
-                            CellStyle cellStyle = new CellStyle();
-                            cellStyle.setFieldKey(name);
-                            cellStyle.setRow(i);
-                            cellStyle.setForeColor("#fb2323");
-                            cellStyles.add(cellStyle);
-                        }
-
-                    }
-                }
-            }
-            i++;
-        }
-        EntryGrid entryGrid = this.getControl(FormConstant.NCKD_ENTRYENTITY);
-        entryGrid.setCellStyle(cellStyles);
-
-    }
-    /**
-     * 设置支付N锁定或解锁
-     * @param installmentYears 分期支付年
-     * @param rowIndex 行索引
-     * @return: void
-     * @author W.Y.C
-     * @date: 2025/11/29 20:48
-     */
-    private void initOperateOption(int installmentYears, int rowIndex) {
-        if(rowIndex > -1) {
-            for (int i = 1; i <= 10; i++) {
-                this.getView().setEnable(false, rowIndex, MasConstant.NCKD_PAYYEAR + i);
-                this.getView().setEnable(false, rowIndex, MasConstant.NCKD_PAYAMOUNT + i);
-            }
-            for (int i = 1; i <= installmentYears; i++) {
-                this.getView().setEnable(true, rowIndex, MasConstant.NCKD_PAYYEAR + i);
-                this.getView().setEnable(true, rowIndex, MasConstant.NCKD_PAYAMOUNT + i);
-
-            }
-        }
-    }
+public class EntldrAnlSalStdChgFormPlugin extends AbstractSalaryStdChgFormPlugin implements Plugin {
 
-}
+    }

+ 2 - 217
code/swc/nckd-jxccl-swc/src/main/java/nckd/jxccl/swc/mas/plugin/form/structappr/change/SubcpChfSalStdChgFormPlugin.java

@@ -1,37 +1,6 @@
 package nckd.jxccl.swc.mas.plugin.form.structappr.change;
 
-import kd.bos.dataentity.entity.DynamicObject;
-import kd.bos.dataentity.entity.DynamicObjectCollection;
-import kd.bos.dataentity.metadata.IDataEntityProperty;
-import kd.bos.dataentity.metadata.clr.DataEntityPropertyCollection;
-import kd.bos.entity.datamodel.events.AfterAddRowEventArgs;
-import kd.bos.entity.datamodel.events.ChangeData;
-import kd.bos.entity.datamodel.events.PropertyChangedArgs;
-import kd.bos.entity.report.CellStyle;
-import kd.bos.form.control.EntryGrid;
-import kd.bos.form.plugin.AbstractFormPlugin;
-import kd.bos.orm.query.QCP;
-import kd.bos.orm.query.QFilter;
-import kd.bos.servicehelper.BusinessDataServiceHelper;
 import kd.sdk.plugin.Plugin;
-import nckd.jxccl.base.common.constant.FormConstant;
-import nckd.jxccl.base.common.utils.ConvertUtil;
-import nckd.jxccl.base.common.utils.DateUtil;
-import nckd.jxccl.base.common.utils.QueryFieldBuilder;
-import nckd.jxccl.base.orm.helper.QFilterCommonHelper;
-import nckd.jxccl.swc.mas.common.MasConstant;
-
-import java.math.BigDecimal;
-import java.math.RoundingMode;
-import java.time.LocalDateTime;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Date;
-import java.util.EventObject;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.stream.Collectors;
 
 /**
 * 子企业负责人正职年度薪酬核定标准_变更单
@@ -40,191 +9,7 @@ import java.util.stream.Collectors;
 * @date 2025/12/3 10:25
 * @version 1.0
 */
-public class SubcpChfSalStdChgFormPlugin extends AbstractFormPlugin implements Plugin {
-
-    @Override
-    public void afterBindData(EventObject e) {
-        DynamicObjectCollection entryCollection = this.getModel().getEntryEntity(FormConstant.NCKD_ENTRYENTITY);
-        for (int rowIndex = 0; rowIndex < entryCollection.size(); rowIndex++) {
-            DynamicObject entry = entryCollection.get(rowIndex);
-            int installmentYears = entry.getInt(MasConstant.NCKD_INSTALLMENTYEARS);
-            initOperateOption(installmentYears,rowIndex);
-        }
-        markChange();
-    }
-
-    @Override
-    public void afterAddRow(AfterAddRowEventArgs e) {
-        initOperateOption(0,e.getInsertRow());
-    }
-
-    @Override
-    public void propertyChanged(PropertyChangedArgs e) {
-        String fieldKey = e.getProperty().getName();
-        ChangeData[] changeSet = e.getChangeSet();
-        int rowIndex = changeSet[0].getRowIndex();
-        Object oldValue = changeSet[0].getOldValue();
-        Object newValue = changeSet[0].getNewValue();
-        if (MasConstant.NCKD_INSTALLMENTYEARS.equalsIgnoreCase(fieldKey)) {
-            if (!Objects.equals(oldValue, newValue)) {
-                initOperateOption(ConvertUtil.toInt(newValue), rowIndex);
-            }
-        }else if(MasConstant.NCKD_APPRSTD.equalsIgnoreCase(fieldKey)){
-            DynamicObject payUnit = ConvertUtil.toDynamicObjectOrNull(this.getModel().getValue(MasConstant.NCKD_PAYUNIT));
-            DynamicObject lawEntity =  ConvertUtil.toDynamicObjectOrNull(this.getModel().getValue(MasConstant.NCKD_LAWENTITY));
-            DynamicObject projectCategory =  ConvertUtil.toDynamicObjectOrNull(this.getModel().getValue(MasConstant.NCKD_PROJECTCATEGORY));
-            Date year = ConvertUtil.toDate(this.getModel().getValue(MasConstant.NCKD_YEAR));
-            //判断“核定标准”是否大于0
-            BigDecimal apprStd = ConvertUtil.toBigDecimal(newValue);
-            if(apprStd != null && apprStd.compareTo(BigDecimal.ZERO) > 0) {
-                if (payUnit != null && lawEntity != null && year != null && projectCategory != null) {
-                    if (!Objects.equals(oldValue, newValue)) {
-                        //计算:延期支付总金额、支付年份1、支付年份1....
-                        //====================================== 获取延期支付比例 begin ======================================
-                        LocalDateTime localDateTime = DateUtil.toLocalDateTime(year);
-                        LocalDateTime beginOfYear = DateUtil.beginOfYear(localDateTime);
-                        LocalDateTime endOfYear = DateUtil.endOfYear(localDateTime);
-
-                        QueryFieldBuilder deferPayRatoConfQueryFieldBuilder = QueryFieldBuilder.create()
-                                .add(MasConstant.NCKD_PROJECTCATEGORY)
-                                .addIdNumberName(MasConstant.NCKD_PAYUNIT)
-                                .addIdNumberName(MasConstant.NCKD_DEFERPAYMONEY)
-                                .add(MasConstant.NCKD_DEFERPAYRATIO)
-                                .add(MasConstant.NCKD_DEFERPAYRATIO)
-                                .add(MasConstant.NCKD_PAYOUTTIMES)
-                                .add(MasConstant.NCKD_YEAR)
-                                .add(FormConstant.NCKD_ENTRYENTITY)
-                                .add(FormConstant.NCKD_ENTRYENTITY, MasConstant.NCKD_TIMES)
-                                .add(FormConstant.NCKD_ENTRYENTITY, MasConstant.NCKD_PAYOUTRATIO)
-                                .add(FormConstant.NCKD_ENTRYENTITY, MasConstant.NCKD_PAYOUTMONEY)
-                                .add(FormConstant.NCKD_ENTRYENTITY, MasConstant.NCKD_DEFERREDPAYITEM)
-                                .add(FormConstant.NCKD_ENTRYENTITY, MasConstant.NCKD_DEFERREDPAYDESC)
-                                .add(FormConstant.NCKD_ENTRYENTITY, MasConstant.NCKD_TERMPAYDESC)
-                                .orderDesc(MasConstant.CREATE_TIME_KEY)
-                                .orderAsc(String.join(".",FormConstant.NCKD_ENTRYENTITY, MasConstant.NCKD_TIMES));
-                        QFilter deferPayRatoConfFilter = new QFilter(MasConstant.NCKD_PAYUNIT, QCP.equals, payUnit.getLong(FormConstant.ID_KEY))
-                                .and(MasConstant.NCKD_LAWENTITY, QCP.equals, lawEntity.getLong(FormConstant.ID_KEY))
-                                .and(MasConstant.NCKD_YEAR, QCP.large_equals, DateUtil.toDate(beginOfYear))
-                                .and(MasConstant.NCKD_YEAR, QCP.less_equals, DateUtil.toDate(endOfYear))
-                                .and(QFilterCommonHelper.getEnableFilter());
-                        DynamicObject[] dbDeferPayRatoConfArray = BusinessDataServiceHelper.load(MasConstant.DEFERPAYRATOCONF_ENTITYID, deferPayRatoConfQueryFieldBuilder.buildSelect(), new QFilter[]{deferPayRatoConfFilter});
-                        Map<String, List<DynamicObject>> dbDeferPayRatoConfMap = Arrays.stream(dbDeferPayRatoConfArray)
-                                .collect(Collectors.groupingBy(obj -> {
-                                    DynamicObject dbProjectCategory = obj.getDynamicObject(MasConstant.NCKD_PROJECTCATEGORY);
-                                    if (dbProjectCategory != null) {
-                                        return dbProjectCategory.getString(FormConstant.NUMBER_KEY);
-                                    }
-                                    return ""; // 处理无项目分类的情况
-                                }));
-                        List<DynamicObject> dbDeferPayRatoConfList = dbDeferPayRatoConfMap.get(projectCategory.getString(FormConstant.NUMBER_KEY));
-
-                        if (dbDeferPayRatoConfList != null && !dbDeferPayRatoConfList.isEmpty()) {
-                            DynamicObject deferPayRatoConf = dbDeferPayRatoConfList.get(0);
-                            //延期支付比例(%)
-                            BigDecimal deferPayRatio = deferPayRatoConf.getBigDecimal(MasConstant.NCKD_DEFERPAYRATIO);
-                            //延期支付金额
-                            BigDecimal deferPayMoney = deferPayRatoConf.getBigDecimal(MasConstant.NCKD_DEFERPAYMONEY);
-                            LocalDateTime beginYear = DateUtil.toLocalDateTime(deferPayRatoConf.getDate(MasConstant.NCKD_YEAR));
-                            BigDecimal deferPayTotalAmt;
-                            if(deferPayMoney != null && deferPayMoney.compareTo(BigDecimal.ZERO) > 0){
-                                //优先使用【延期支付金额】
-                                deferPayTotalAmt = deferPayMoney;
-                            }else {
-                                //核算标准*延期支付比例/100
-                                deferPayTotalAmt = apprStd.multiply(deferPayRatio.divide(new BigDecimal(100), 2, RoundingMode.DOWN));
-                            }
-                            this.getModel().setValue(MasConstant.NCKD_DEFERPAYTOTALAMT, deferPayTotalAmt,rowIndex);
-                            DynamicObjectCollection entryColl = deferPayRatoConf.getDynamicObjectCollection(FormConstant.NCKD_ENTRYENTITY);
-                            int i = 0;
-                            for (DynamicObject entry : entryColl) {
-                                int times = entry.getInt(MasConstant.NCKD_TIMES);
-                                //兑现比例(%)
-                                BigDecimal payoutRatio = entry.getBigDecimal(MasConstant.NCKD_PAYOUTRATIO);
-                                //兑现金额
-                                BigDecimal payoutMoney = entry.getBigDecimal(MasConstant.NCKD_PAYOUTMONEY);
-                                BigDecimal payaMount;
-                                if(payoutMoney != null && payoutMoney.compareTo(BigDecimal.ZERO) > 0){
-                                    //优先使用【兑现金额】
-                                    payaMount = payoutMoney;
-                                }else{
-                                    //延期支付总金额*兑现比例
-                                    payaMount = deferPayTotalAmt.multiply(payoutRatio.divide(new BigDecimal(100), 2, RoundingMode.DOWN));
-                                }
-                                if(i != 0){
-                                    beginYear = DateUtil.addYears(beginYear, 1);
-                                }
-                                this.getModel().setValue(MasConstant.NCKD_PAYYEAR+(i+1), DateUtil.toDate(beginYear),rowIndex);
-                                this.getModel().setValue(MasConstant.NCKD_PAYAMOUNT+(i+1), payaMount,rowIndex);
-                                i++;
-                            }
-
-                        }
-                        //====================================== 获取延期支付比例 end ======================================
-
-                    }
-                }
-            }else{
-                this.getModel().setValue(MasConstant.NCKD_DEFERPAYTOTALAMT, null);
-            }
-        }
-        markChange();
-    }
-
-    /**
-     * 设置支付N锁定或解锁
-     * @param installmentYears 分期支付年
-     * @param rowIndex 行索引
-     * @return: void
-     * @author W.Y.C
-     * @date: 2025/11/29 20:48
-     */
-    private void initOperateOption(int installmentYears, int rowIndex) {
-        if(rowIndex > -1) {
-            for (int i = 1; i <= 10; i++) {
-                this.getView().setEnable(false, rowIndex, MasConstant.NCKD_PAYYEAR + i);
-                this.getView().setEnable(false, rowIndex, MasConstant.NCKD_PAYAMOUNT + i);
-            }
-            for (int i = 1; i <= installmentYears; i++) {
-                this.getView().setEnable(true, rowIndex, MasConstant.NCKD_PAYYEAR + i);
-                this.getView().setEnable(true, rowIndex, MasConstant.NCKD_PAYAMOUNT + i);
-
-            }
-        }
-    }
-
-    //标记变更
-    private void markChange(){
-        DynamicObjectCollection entryColl = this.getModel().getDataEntity(true).getDynamicObjectCollection(FormConstant.NCKD_ENTRYENTITY);
-        DynamicObjectCollection oldEntryColl = this.getModel().getDataEntity(true).getDynamicObjectCollection("nckd_oldentryentity");
-
-        List<CellStyle> cellStyles = new ArrayList<>();
-        int i = 0;
-        for (DynamicObject entry : entryColl) {
-            long originId = entry.getLong("nckd_originid");
-            for (DynamicObject oldEntry : oldEntryColl) {
-                long oldOriginId = oldEntry.getLong("nckd_originidold");
-                if(originId == oldOriginId){
-                    DataEntityPropertyCollection properties = oldEntry.getDynamicObjectType().getProperties();
-                    for (IDataEntityProperty property : properties) {
-                        String oldName = property.getName();
-                        String name = oldName.replace("old","");
-                        Object value = entry.get(name);
-                        Object oldValue = oldEntry.get(oldName);
-                        if(!Objects.equals(value, oldValue)){
-                            CellStyle cellStyle = new CellStyle();
-                            cellStyle.setFieldKey(name);
-                            cellStyle.setRow(i);
-                            cellStyle.setForeColor("#fb2323");
-                            cellStyles.add(cellStyle);
-                        }
-
-                    }
-                }
-            }
-            i++;
-        }
-        EntryGrid entryGrid = this.getControl(FormConstant.NCKD_ENTRYENTITY);
-        entryGrid.setCellStyle(cellStyles);
+public class SubcpChfSalStdChgFormPlugin extends AbstractSalaryStdChgFormPlugin implements Plugin {
 
-    }
+    
 }

+ 128 - 0
code/swc/nckd-jxccl-swc/src/main/java/nckd/jxccl/swc/mas/plugin/operate/structappr/change/AbstractSalaryStdChgOpPlugin.java

@@ -0,0 +1,128 @@
+package nckd.jxccl.swc.mas.plugin.operate.structappr.change;
+
+import kd.bos.dataentity.OperateOption;
+import kd.bos.dataentity.entity.DynamicObject;
+import kd.bos.dataentity.entity.DynamicObjectCollection;
+import kd.bos.dataentity.metadata.IDataEntityProperty;
+import kd.bos.dataentity.metadata.clr.DataEntityPropertyCollection;
+import kd.bos.entity.MainEntityType;
+import kd.bos.entity.operate.result.OperationResult;
+import kd.bos.entity.plugin.AbstractOperationServicePlugIn;
+import kd.bos.entity.plugin.PreparePropertysEventArgs;
+import kd.bos.entity.plugin.args.BeginOperationTransactionArgs;
+import kd.bos.servicehelper.BusinessDataServiceHelper;
+import kd.bos.servicehelper.MetadataServiceHelper;
+import kd.bos.servicehelper.operation.OperationServiceHelper;
+import kd.bos.servicehelper.operation.SaveServiceHelper;
+import kd.sdk.plugin.Plugin;
+import nckd.jxccl.base.common.constant.FormConstant;
+import nckd.jxccl.base.common.exception.ValidationException;
+import nckd.jxccl.base.common.utils.StrFormatter;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+/**
+ * 薪酬标准变更操作插件抽象基类
+ *
+ * @author W.Y.C
+ * @date 2025/12/03
+ */
+public abstract class AbstractSalaryStdChgOpPlugin extends AbstractOperationServicePlugIn implements Plugin {
+
+    /**
+     * 获取实体ID
+     * @return 实体ID
+     */
+    protected abstract String getEntityId();
+
+    /**
+     * 获取实体ID
+     * @return 实体ID
+     */
+    protected abstract String getEntityName();
+
+    /**
+     * 处理更新前的额外逻辑
+     * @param dataEntity 数据实体
+     * @param updateEntity 更新实体
+     */
+    protected abstract void processBeforeUpdate(DynamicObject dataEntity, DynamicObject updateEntity);
+
+    @Override
+    public void onPreparePropertys(PreparePropertysEventArgs e) {
+        e.getFieldKeys().addAll(this.billEntityType.getAllFields().keySet());
+    }
+
+    @Override
+    public void beginOperationTransaction(BeginOperationTransactionArgs e) {
+        List<Long> entityIdList = new ArrayList<>();
+        for (DynamicObject dataEntity : e.getDataEntities()) {
+            long entityId = dataEntity.getLong(String.join(".", getEntityId(), FormConstant.ID_KEY));
+            entityIdList.add(entityId);
+        }
+        
+        MainEntityType dataEntityType = MetadataServiceHelper.getDataEntityType(getEntityId());
+        DynamicObject[] load = BusinessDataServiceHelper.load(entityIdList.toArray(new Long[0]), dataEntityType);
+        
+        // 按ID分组
+        Map<Long, DynamicObject> groupedById = Arrays.stream(load)
+                .collect(Collectors.toMap(
+                        obj -> obj.getLong(FormConstant.ID_KEY),
+                        obj -> obj
+                ));
+                
+        for (DynamicObject dataEntity : e.getDataEntities()) {
+            long entityId = dataEntity.getLong(String.join(".", getEntityId(), FormConstant.ID_KEY));
+            DynamicObjectCollection entryColl = dataEntity.getDynamicObjectCollection(FormConstant.NCKD_ENTRYENTITY);
+
+            DynamicObject updateEntity = groupedById.get(entityId);
+            DynamicObjectCollection updateEntryColl = updateEntity.getDynamicObjectCollection(FormConstant.NCKD_ENTRYENTITY);
+
+            for (DynamicObject entry : entryColl) {
+                long originId = entry.getLong("nckd_originid");
+                for (DynamicObject updateEntry : updateEntryColl) {
+                    long id = updateEntry.getLong(FormConstant.ID_KEY);
+                    if (originId == id) {
+                        DataEntityPropertyCollection properties = entry.getDynamicObjectType().getProperties();
+                        for (IDataEntityProperty property : properties) {
+                            String name = property.getName();
+                            if (name.contains("nckd_") && !name.contains("nckd_originid")) {
+                                updateEntry.set(name, entry.get(name));
+                            }
+                        }
+                        break;
+                    }
+                }
+            }
+            
+            // 处理更新前的额外逻辑
+            processBeforeUpdate(dataEntity, updateEntity);
+        }
+
+        // 执行取消提交操作
+        OperationResult unsubmitResult = OperationServiceHelper.executeOperate("unsubmit", getEntityId(), load,OperateOption.create());
+        if (unsubmitResult.isSuccess()) {
+            OperateOption option = OperateOption.create();
+            // 跳过状态校验
+            option.setVariableValue("rmStatusControl", "true");
+            
+            // 执行保存操作
+            OperationResult saveResult = SaveServiceHelper.saveOperate(getEntityId(), load, option);
+            if (saveResult != null && !saveResult.isSuccess()) {
+                throw new ValidationException(StrFormatter.format("回写【{}】失败,原因:{}",getEntityName(),saveResult.getMessage()));
+            }
+            
+            // 执行提交操作
+            OperationResult submitResult = OperationServiceHelper.executeOperate("submit", getEntityId(), load,OperateOption.create());
+            if (submitResult != null && !submitResult.isSuccess()) {
+                throw new ValidationException(StrFormatter.format("回写【{}】失败,原因:{}",getEntityName(),submitResult.getMessage()));
+            }
+        } else {
+            throw new ValidationException(StrFormatter.format("回写【{}】失败,原因:{}",getEntityName(),unsubmitResult.getMessage()));
+        }
+    }
+}

+ 22 - 77
code/swc/nckd-jxccl-swc/src/main/java/nckd/jxccl/swc/mas/plugin/operate/structappr/change/EntldrAnlSalStdChgOpPlugin.java

@@ -1,39 +1,23 @@
 package nckd.jxccl.swc.mas.plugin.operate.structappr.change;
 
-import kd.bos.dataentity.OperateOption;
 import kd.bos.dataentity.entity.DynamicObject;
-import kd.bos.dataentity.entity.DynamicObjectCollection;
-import kd.bos.dataentity.metadata.IDataEntityProperty;
-import kd.bos.dataentity.metadata.clr.DataEntityPropertyCollection;
-import kd.bos.entity.MainEntityType;
-import kd.bos.entity.operate.result.OperationResult;
-import kd.bos.entity.plugin.AbstractOperationServicePlugIn;
 import kd.bos.entity.plugin.PreparePropertysEventArgs;
 import kd.bos.entity.plugin.args.BeginOperationTransactionArgs;
-import kd.bos.servicehelper.BusinessDataServiceHelper;
-import kd.bos.servicehelper.MetadataServiceHelper;
-import kd.bos.servicehelper.operation.OperationServiceHelper;
-import kd.bos.servicehelper.operation.SaveServiceHelper;
 import kd.sdk.plugin.Plugin;
 import nckd.jxccl.base.common.constant.FormConstant;
-import nckd.jxccl.base.common.exception.ValidationException;
 import nckd.jxccl.swc.mas.common.MasConstant;
 
-import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Date;
-import java.util.List;
-import java.util.Map;
-import java.util.stream.Collectors;
 
 /**
-* 企业负责人个人年度薪酬标准核定表_变更单-反写操作
-* 实体标识:nckd_entldranlsalstdchg
-* @author W.Y.C
-* @date 2025/12/3 19:15
-* @version 1.0
-*/
-public class EntldrAnlSalStdChgOpPlugin extends AbstractOperationServicePlugIn implements Plugin {
+ * 企业负责人个人年度薪酬标准核定表_变更单-反写操作
+ * 实体标识:nckd_entldranlsalstdchg
+ * @author W.Y.C
+ * @date 2025/12/3 19:15
+ * @version 1.0
+ */
+public class EntldrAnlSalStdChgOpPlugin extends AbstractSalaryStdChgOpPlugin implements Plugin {
+
     @Override
     public void onPreparePropertys(PreparePropertysEventArgs e) {
         e.getFieldKeys().addAll(this.billEntityType.getAllFields().keySet());
@@ -41,61 +25,22 @@ public class EntldrAnlSalStdChgOpPlugin extends AbstractOperationServicePlugIn i
 
     @Override
     public void beginOperationTransaction(BeginOperationTransactionArgs e) {
-        List<Long> subcorpChiefSalStdArray = new ArrayList<>();
-        for (DynamicObject dataEntity : e.getDataEntities()) {
-            long subcorpChiefSalStdId = dataEntity.getLong(String.join(".", MasConstant.ENTLEADERANLSALSTD_ENTITYID, FormConstant.ID_KEY));
-            subcorpChiefSalStdArray.add(subcorpChiefSalStdId);
-        }
-        MainEntityType dataEntityType = MetadataServiceHelper.getDataEntityType(MasConstant.ENTLEADERANLSALSTD_ENTITYID);
-        DynamicObject[] load = BusinessDataServiceHelper.load(subcorpChiefSalStdArray.toArray(new Long[0]), dataEntityType);
-        // 按ID分组
-        Map<Long, DynamicObject> groupedById = Arrays.stream(load)
-                .collect(Collectors.toMap(
-                        obj -> obj.getLong(FormConstant.ID_KEY),
-                        obj -> obj
-                ));
-        for (DynamicObject dataEntity : e.getDataEntities()) {
-            long subcorpChiefSalStdId = dataEntity.getLong(String.join(".",MasConstant.ENTLEADERANLSALSTD_ENTITYID, FormConstant.ID_KEY));
-            DynamicObjectCollection entryColl = dataEntity.getDynamicObjectCollection(FormConstant.NCKD_ENTRYENTITY);
+        super.beginOperationTransaction(e);
+    }
 
-            DynamicObject updateSubcorpChiefSalStd = groupedById.get(subcorpChiefSalStdId);
-            DynamicObjectCollection updateSubcorpChiefSalStdEntryColl = updateSubcorpChiefSalStd.getDynamicObjectCollection(FormConstant.NCKD_ENTRYENTITY);
+    @Override
+    protected String getEntityId() {
+        return MasConstant.ENTLEADERANLSALSTD_ENTITYID;
+    }
 
-            for (DynamicObject entry : entryColl) {
-                long originid = entry.getLong("nckd_originid");
-                for (DynamicObject updateSubcorpChiefSalStdEntry : updateSubcorpChiefSalStdEntryColl) {
-                    long id = updateSubcorpChiefSalStdEntry.getLong(FormConstant.ID_KEY);
-                    if(originid == id){
-                        DataEntityPropertyCollection properties = entry.getDynamicObjectType().getProperties();
-                        for (IDataEntityProperty property : properties) {
-                            String name = property.getName();
-                            if(name.contains("nckd_") && !name.contains("nckd_originid")) {
-                                updateSubcorpChiefSalStdEntry.set(name, entry.get(name));
-                            }
-                        }
-                        break;
-                    }
-                }
-            }
-            updateSubcorpChiefSalStd.set(FormConstant.MODIFY_TIME_KEY,new Date());
-            dataEntity.set(FormConstant.MODIFIER_KEY,dataEntity.get(FormConstant.CREATOR_KEY));
-        }
+    @Override
+    protected String getEntityName() {
+        return "企业负责人个人年度薪酬标准核定表";
+    }
 
-        OperationResult operationResult2 = OperationServiceHelper.executeOperate("unsubmit", MasConstant.ENTLEADERANLSALSTD_ENTITYID, load);
-        if(operationResult2.isSuccess()) {
-            OperateOption option = OperateOption.create();
-            //跳过状态校验
-            option.setVariableValue("rmStatusControl", "true");
-            OperationResult operationResult1 = SaveServiceHelper.saveOperate(MasConstant.ENTLEADERANLSALSTD_ENTITYID, load, option);
-            if (operationResult1 != null && !operationResult1.isSuccess()) {
-                throw new ValidationException("回写【企业负责人个人年度薪酬标准核定表】失败,原因:" + operationResult1.getMessage());
-            }
-            OperationResult operationResult3 = OperationServiceHelper.executeOperate("submit", MasConstant.ENTLEADERANLSALSTD_ENTITYID, load);
-            if (operationResult3 != null && !operationResult3.isSuccess()) {
-                throw new ValidationException("回写【企业负责人个人年度薪酬标准核定表】失败,原因:" + operationResult3.getMessage());
-            }
-        }else{
-            throw new ValidationException("回写【企业负责人个人年度薪酬标准核定表】失败,原因:" + operationResult2.getMessage());
-        }
+    @Override
+    protected void processBeforeUpdate(DynamicObject dataEntity, DynamicObject updateEntity) {
+        updateEntity.set(FormConstant.MODIFY_TIME_KEY, new Date());
+        dataEntity.set(FormConstant.MODIFIER_KEY, dataEntity.get(FormConstant.CREATOR_KEY));
     }
 }

+ 22 - 75
code/swc/nckd-jxccl-swc/src/main/java/nckd/jxccl/swc/mas/plugin/operate/structappr/change/SubcpChfSalstdChgBackOpPlugin.java

@@ -1,38 +1,22 @@
 package nckd.jxccl.swc.mas.plugin.operate.structappr.change;
 
-import kd.bos.dataentity.OperateOption;
 import kd.bos.dataentity.entity.DynamicObject;
-import kd.bos.dataentity.entity.DynamicObjectCollection;
-import kd.bos.dataentity.metadata.IDataEntityProperty;
-import kd.bos.dataentity.metadata.clr.DataEntityPropertyCollection;
-import kd.bos.entity.MainEntityType;
-import kd.bos.entity.operate.result.OperationResult;
-import kd.bos.entity.plugin.AbstractOperationServicePlugIn;
 import kd.bos.entity.plugin.PreparePropertysEventArgs;
 import kd.bos.entity.plugin.args.BeginOperationTransactionArgs;
-import kd.bos.servicehelper.BusinessDataServiceHelper;
-import kd.bos.servicehelper.MetadataServiceHelper;
-import kd.bos.servicehelper.operation.OperationServiceHelper;
-import kd.bos.servicehelper.operation.SaveServiceHelper;
 import kd.sdk.plugin.Plugin;
 import nckd.jxccl.base.common.constant.FormConstant;
-import nckd.jxccl.base.common.exception.ValidationException;
 import nckd.jxccl.swc.mas.common.MasConstant;
 
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
-import java.util.stream.Collectors;
+import java.util.Date;
 
 /**
-* 子企业负责人正职年度薪酬核定标准-回写op
-* 实体标识:nckd_subcorpchiefsalstd
-* @author W.Y.C
-* @date 2025/12/3 20:03
-* @version 1.0
-*/
-public class SubcpChfSalstdChgBackOpPlugin extends AbstractOperationServicePlugIn implements Plugin {
+ * 子企业负责人正职年度薪酬核定标准-回写op
+ * 实体标识:nckd_subcorpchiefsalstd
+ * @author W.Y.C
+ * @date 2025/12/3 20:03
+ * @version 1.0
+ */
+public class SubcpChfSalstdChgBackOpPlugin extends AbstractSalaryStdChgOpPlugin implements Plugin {
 
     @Override
     public void onPreparePropertys(PreparePropertysEventArgs e) {
@@ -41,59 +25,22 @@ public class SubcpChfSalstdChgBackOpPlugin extends AbstractOperationServicePlugI
 
     @Override
     public void beginOperationTransaction(BeginOperationTransactionArgs e) {
-        List<Long> subcorpChiefSalStdArray = new ArrayList<>();
-        for (DynamicObject dataEntity : e.getDataEntities()) {
-            long subcorpChiefSalStdId = dataEntity.getLong(String.join(".",MasConstant.SUBCORPCHIEFSALSTD_ENTITYID, FormConstant.ID_KEY));
-            subcorpChiefSalStdArray.add(subcorpChiefSalStdId);
-        }
-        MainEntityType dataEntityType = MetadataServiceHelper.getDataEntityType(MasConstant.SUBCORPCHIEFSALSTD_ENTITYID);
-        DynamicObject[] load = BusinessDataServiceHelper.load(subcorpChiefSalStdArray.toArray(new Long[0]), dataEntityType);
-        // 按ID分组
-        Map<Long, DynamicObject> groupedById = Arrays.stream(load)
-                .collect(Collectors.toMap(
-                        obj -> obj.getLong(FormConstant.ID_KEY),
-                        obj -> obj
-                ));
-        for (DynamicObject dataEntity : e.getDataEntities()) {
-            long subcorpChiefSalStdId = dataEntity.getLong(String.join(".",MasConstant.SUBCORPCHIEFSALSTD_ENTITYID, FormConstant.ID_KEY));
-            DynamicObjectCollection entryColl = dataEntity.getDynamicObjectCollection(FormConstant.NCKD_ENTRYENTITY);
+        super.beginOperationTransaction(e);
+    }
 
-            DynamicObject updateSubcorpChiefSalStd = groupedById.get(subcorpChiefSalStdId);
-            DynamicObjectCollection updateSubcorpChiefSalStdEntryColl = updateSubcorpChiefSalStd.getDynamicObjectCollection(FormConstant.NCKD_ENTRYENTITY);
+    @Override
+    protected String getEntityId() {
+        return MasConstant.SUBCORPCHIEFSALSTD_ENTITYID;
+    }
 
-            for (DynamicObject entry : entryColl) {
-                long originid = entry.getLong("nckd_originid");
-                for (DynamicObject updateSubcorpChiefSalStdEntry : updateSubcorpChiefSalStdEntryColl) {
-                    long id = updateSubcorpChiefSalStdEntry.getLong(FormConstant.ID_KEY);
-                    if(originid == id){
-                        DataEntityPropertyCollection properties = entry.getDynamicObjectType().getProperties();
-                        for (IDataEntityProperty property : properties) {
-                            String name = property.getName();
-                            if(name.contains("nckd_") && !name.contains("nckd_originid")) {
-                                updateSubcorpChiefSalStdEntry.set(name, entry.get(name));
-                            }
-                        }
-                        break;
-                    }
-                }
-            }
-        }
+    @Override
+    protected String getEntityName() {
+        return "子企业负责人正职年度薪酬核定标准";
+    }
 
-        OperationResult operationResult2 = OperationServiceHelper.executeOperate("unsubmit", MasConstant.SUBCORPCHIEFSALSTD_ENTITYID, load);
-        if(operationResult2.isSuccess()) {
-            OperateOption option = OperateOption.create();
-            //跳过状态校验
-            option.setVariableValue("rmStatusControl", "true");
-            OperationResult operationResult1 = SaveServiceHelper.saveOperate(MasConstant.SUBCORPCHIEFSALSTD_ENTITYID, load, option);
-            if (operationResult1 != null && !operationResult1.isSuccess()) {
-                throw new ValidationException("回写【企业负责人个人年度薪酬标准核定表】失败,原因:" + operationResult1.getMessage());
-            }
-            OperationResult operationResult3 = OperationServiceHelper.executeOperate("submit", MasConstant.SUBCORPCHIEFSALSTD_ENTITYID, load);
-            if (operationResult3 != null && !operationResult3.isSuccess()) {
-                throw new ValidationException("回写【企业负责人个人年度薪酬标准核定表】失败,原因:" + operationResult3.getMessage());
-            }
-        }else{
-            throw new ValidationException("回写【企业负责人个人年度薪酬标准核定表】失败,原因:" + operationResult2.getMessage());
-        }
+    @Override
+    protected void processBeforeUpdate(DynamicObject dataEntity, DynamicObject updateEntity) {
+        updateEntity.set(FormConstant.MODIFY_TIME_KEY, new Date());
+        dataEntity.set(FormConstant.MODIFIER_KEY, dataEntity.get(FormConstant.CREATOR_KEY));
     }
 }