Selaa lähdekoodia

refactor(hr): 优化岗位申请单和离职申请单的业务逻辑

- 修改TransferApplyBillFormPlugin中比较值的逻辑,反转HRDynamicObjectUtils.compareValues的结果
- 在QuitApplyFormPlugin中替换HRMServiceHelper为DispatchServiceHelper调用服务
- 将日期处理改为LocalDate格式并使用系统默认时区
- 在PositionBillConfirmCallBackService和PositionBillPropertyChangedService中将getPositionAllEntities替换为getPositionProperties
- 在岗位属性查询时添加positionProperties包含检查条件
- 在PositionBillServiceHelper中新增setChangeDes方法用于设置变更描述
- 新增getPositionProperties方法替代getPositionAllEntities方法
- 在PosBillEntryUpdatePlugin中添加beforeDoOperation方法调用setChangeDes
- 在PositionBillFormPlugin的保存提交操作中添加变更描述设置
- 新增AppflgConstant、IWTPCustomerService、WTPCustomerService和ServiceFactory类
- 实现工事假勤规则自定义微服务接口和工厂类
jtd 6 päivää sitten
vanhempi
säilyke
aa1a623dd2
20 muutettua tiedostoa jossa 258 lisäystä ja 21 poistoa
  1. 1 1
      code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/hdm/plugin/form/transfer/TransferApplyBillFormPlugin.java
  2. 5 9
      code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/htm/plugin/form/quitapply/QuitApplyFormPlugin.java
  3. 6 3
      code/hrmp/nckd-jxccl-hrmp/src/main/java/nckd/jxccl/hrmp/hbpm/business/hr/service/impl/PositionBillConfirmCallBackService.java
  4. 9 5
      code/hrmp/nckd-jxccl-hrmp/src/main/java/nckd/jxccl/hrmp/hbpm/business/hr/service/impl/PositionBillPropertyChangedService.java
  5. 97 3
      code/hrmp/nckd-jxccl-hrmp/src/main/java/nckd/jxccl/hrmp/hbpm/business/hr/service/impl/PositionBillServiceHelper.java
  6. 4 0
      code/hrmp/nckd-jxccl-hrmp/src/main/java/nckd/jxccl/hrmp/hbpm/common/hr/PositionBillConstant.java
  7. 8 0
      code/hrmp/nckd-jxccl-hrmp/src/main/java/nckd/jxccl/hrmp/hbpm/plugin/form/hr/PosBillEntryUpdatePlugin.java
  8. 3 0
      code/hrmp/nckd-jxccl-hrmp/src/main/java/nckd/jxccl/hrmp/hbpm/plugin/form/hr/PositionBillFormPlugin.java
  9. 0 0
      code/wtc/nckd-jxccl-wtc/src/main/java/nckd/jxccl/wtc/wtp/business/.gitkeep
  10. 22 0
      code/wtc/nckd-jxccl-wtc/src/main/java/nckd/jxccl/wtc/wtp/common/AppflgConstant.java
  11. 0 0
      code/wtc/nckd-jxccl-wtc/src/main/java/nckd/jxccl/wtc/wtp/mservice/.gitkeep
  12. 32 0
      code/wtc/nckd-jxccl-wtc/src/main/java/nckd/jxccl/wtc/wtp/mservice/WTPCustomerService.java
  13. 36 0
      code/wtc/nckd-jxccl-wtc/src/main/java/nckd/jxccl/wtc/wtp/mservice/api/IWTPCustomerService.java
  14. 0 0
      code/wtc/nckd-jxccl-wtc/src/main/java/nckd/jxccl/wtc/wtp/plugin/form/.gitkeep
  15. 0 0
      code/wtc/nckd-jxccl-wtc/src/main/java/nckd/jxccl/wtc/wtp/plugin/operate/.gitkeep
  16. 0 0
      code/wtc/nckd-jxccl-wtc/src/main/java/nckd/jxccl/wtc/wtp/plugin/other/.gitkeep
  17. 0 0
      code/wtc/nckd-jxccl-wtc/src/main/java/nckd/jxccl/wtc/wtp/plugin/report/.gitkeep
  18. 0 0
      code/wtc/nckd-jxccl-wtc/src/main/java/nckd/jxccl/wtc/wtp/plugin/workflow/.gitkeep
  19. 35 0
      code/wtc/nckd-jxccl-wtc/src/main/java/nckd/jxccl/wtc/wtp/servicehelper/ServiceFactory.java
  20. 0 0
      code/wtc/nckd-jxccl-wtc/src/main/java/nckd/jxccl/wtc/wtp/webapi/.gitkeep

+ 1 - 1
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/hdm/plugin/form/transfer/TransferApplyBillFormPlugin.java

@@ -141,7 +141,7 @@ public class TransferApplyBillFormPlugin extends AbstractFormPlugin {
         } else if ((HRObjectUtils.isEmpty(oldValue) && !HRObjectUtils.isEmpty(newValue)) || (!HRObjectUtils.isEmpty(oldValue) && HRObjectUtils.isEmpty(newValue))) {
             return true;
         } else {
-            return HRDynamicObjectUtils.compareValues(oldValue, newValue);
+            return !HRDynamicObjectUtils.compareValues(oldValue, newValue);
         }
     }
 

+ 5 - 9
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/htm/plugin/form/quitapply/QuitApplyFormPlugin.java

@@ -6,12 +6,11 @@ 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.DispatchServiceHelper;
 import kd.bos.servicehelper.QueryServiceHelper;
-import kd.hr.hbp.business.servicehelper.HRMServiceHelper;
-import kd.hr.hbp.common.util.HRDateTimeUtils;
-import kd.sdk.wtc.wtp.business.attfile.AttFileVersion;
 import nckd.jxccl.hr.htm.common.quitapply.QuitApplyConstant;
 
+import java.time.ZoneId;
 import java.util.Collections;
 import java.util.Date;
 import java.util.List;
@@ -77,17 +76,14 @@ public class QuitApplyFormPlugin extends AbstractFormPlugin {
      * @param contractEndDate 离职日期
      */
     private void setUnUsedAnnualLeave(Long employeeId, Date contractEndDate) {
-        // from: kd.sdk.wtc.wtp.business.helper.WTPServiceHelper.getAttFile
         // 获取人员考勤档案
-
-        AttFileVersion attFile = HRMServiceHelper.invokeBizService(QuitApplyConstant.WTC_CLOUD, QuitApplyConstant.WTBS_APP, "IAttFileQueryService", "attFileQuery", new Object[]{HRDateTimeUtils.getNowDate(), employeeId});
-        if (attFile == null) {
+        Long attFileBoId = DispatchServiceHelper.invokeService("nckd.jxccl.wtc.wtp.servicehelper", QuitApplyConstant.WTP_APP, "IWTPCustomerService", "getAttFileBoId", new Object[]{contractEndDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDate(), employeeId});
+        if (attFileBoId == 0L) {
             getView().showTipNotification("未获取到应休未休剩余年假,请检查离职人员是否存在离职时间内有效的考勤档案");
             return;
         }
 
-        // from: kd.sdk.wtc.wtp.business.helper.WTPServiceHelper.queryQuota
-        List<DynamicObject> quotaList = HRMServiceHelper.invokeBizService(QuitApplyConstant.WTC_CLOUD, QuitApplyConstant.WTP_APP, "IQTService", "queryQuota", new Object[]{attFile.getBoId(), Collections.singletonList(1666695290893207552L), 0, contractEndDate, contractEndDate});
+        List<DynamicObject> quotaList = DispatchServiceHelper.invokeService("nckd.jxccl.wtc.wtp.servicehelper", QuitApplyConstant.WTP_APP, "IWTPCustomerService", "queryQuota", new Object[]{attFileBoId, Collections.singletonList(1666695290893207552L), 0, contractEndDate, contractEndDate});
         if (quotaList != null && !quotaList.isEmpty()) {
             DynamicObject quotaDy = quotaList.get(0);
             getModel().setValue(QuitApplyConstant.NCKD_UNUSEDANNUALLEAVE_KEY, quotaDy.getBigDecimal(QuitApplyConstant.USABLEVALUE_KEY));

+ 6 - 3
code/hrmp/nckd-jxccl-hrmp/src/main/java/nckd/jxccl/hrmp/hbpm/business/hr/service/impl/PositionBillConfirmCallBackService.java

@@ -215,14 +215,17 @@ public class PositionBillConfirmCallBackService extends PositionBillBaseService
             // 获取岗位要转换的键值
             transKeyMap.putAll(PositionBillServiceHelper.getPositionTransKeyMap());
             // 获取岗位所有属性
-            Set<String> positionAllEntities = PositionBillServiceHelper.getPositionAllEntities();
+            Set<String> positionProperties = PositionBillServiceHelper.getPositionProperties();
 
             QueryFieldBuilder queryFieldBuilder = QueryFieldBuilder.create();
             for(IDataEntityProperty iDataEntityProperty : entryEntityInfo) {
                 String propName = iDataEntityProperty.getName();
                 if (PatternUtil.isExProperty(propName) && propName.endsWith(lineSuffix)) {
                     String selectName = PositionBillServiceHelper.getNoLineSuffixProp(propName, lineSuffix);
-                    queryFieldBuilder.add(transKeyMap.getOrDefault(selectName, selectName));
+                    selectName = transKeyMap.getOrDefault(selectName, selectName);
+                    if (positionProperties.contains(selectName)) {
+                        queryFieldBuilder.add(selectName);
+                    }
                 }
             }
 
@@ -238,7 +241,7 @@ public class PositionBillConfirmCallBackService extends PositionBillBaseService
                 if (PatternUtil.isExProperty(propName) && propName.endsWith(lineSuffix)) {
                     String selectName = PositionBillServiceHelper.getNoLineSuffixProp(propName, lineSuffix);
                     selectName = transKeyMap.getOrDefault(selectName, selectName);
-                    if (positionAllEntities.contains(selectName)) {
+                    if (positionProperties.contains(selectName)) {
                         // 原上级岗位特殊处理
                         if (HRStringUtils.equals(selectName, PositionBillConstant.NCKD_PARENT)) {
                             entryEntityDyn.set(PositionBillConstant.NCKD_ORIPARENT_KEY+lineSuffix, position.get(selectName));

+ 9 - 5
code/hrmp/nckd-jxccl-hrmp/src/main/java/nckd/jxccl/hrmp/hbpm/business/hr/service/impl/PositionBillPropertyChangedService.java

@@ -84,19 +84,23 @@ public class PositionBillPropertyChangedService extends PositionBillBaseService
         // 获取岗位要转换的键值
         transKeyMap.putAll(PositionBillServiceHelper.getPositionTransKeyMap());
         // 获取岗位所有属性
-        Set<String> positionAllEntities = PositionBillServiceHelper.getPositionAllEntities();
+        Set<String> positionProperties = PositionBillServiceHelper.getPositionProperties();
 
         StringBuilder selectSqlBuilder = new StringBuilder();
         for(IDataEntityProperty iDataEntityProperty : entryEntityInfo) {
             String propName = iDataEntityProperty.getName();
             if (PatternUtil.isExProperty(propName) && propName.endsWith(lineSuffix)) {
                 String selectName = PositionBillServiceHelper.getNoLineSuffixProp(propName, lineSuffix);
-                if (positionAllEntities.contains(selectName)) {
-                    selectSqlBuilder.append(",").append(transKeyMap.getOrDefault(selectName, selectName));
+                selectName = transKeyMap.getOrDefault(selectName, selectName);
+                if (positionProperties.contains(selectName)) {
+                    selectSqlBuilder.append(",").append(selectName);
                 }
             }
         }
-        selectSqlBuilder.deleteCharAt(0);
+
+        if (selectSqlBuilder.length() > 0) {
+            selectSqlBuilder.deleteCharAt(0);
+        }
 
         BasedataProp basedataProp = (BasedataProp) property;
         String baseEntityId = basedataProp.getBaseEntityId();
@@ -124,7 +128,7 @@ public class PositionBillPropertyChangedService extends PositionBillBaseService
                 if (PatternUtil.isExProperty(propName) && propName.endsWith(lineSuffix)) {
                     String selectName = PositionBillServiceHelper.getNoLineSuffixProp(propName, lineSuffix);
                     selectName = transKeyMap.getOrDefault(selectName, selectName);
-                    if (positionAllEntities.contains(selectName)) {
+                    if (positionProperties.contains(selectName)) {
                         // 原上级岗位特殊处理
                         if (HRStringUtils.equals(selectName, PositionBillConstant.NCKD_PARENT)) {
                             entryEntityDyn.set(PositionBillConstant.NCKD_ORIPARENT_KEY+lineSuffix, position.get(selectName));

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

@@ -11,6 +11,8 @@ import kd.bos.dataentity.OperateOption;
 import kd.bos.dataentity.entity.DynamicObject;
 import kd.bos.dataentity.entity.DynamicObjectCollection;
 import kd.bos.dataentity.entity.ILocaleString;
+import kd.bos.dataentity.metadata.IDataEntityProperty;
+import kd.bos.dataentity.metadata.dynamicobject.DynamicProperty;
 import kd.bos.dataentity.serialization.SerializationUtils;
 import kd.bos.db.tx.Propagation;
 import kd.bos.db.tx.TX;
@@ -51,13 +53,15 @@ import org.apache.commons.lang3.time.DateUtils;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Date;
+import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.function.Function;
 import java.util.stream.Collectors;
 
 /**
- * 岗位申请单帮
+ * 岗位申请单帮
  * @from: kd.hr.homs.business.domain.batchbill.repository.AdminOrgBatchChgHelper
  * @author: jtd
  * @date: 2025-10-31 14:33
@@ -65,6 +69,96 @@ import java.util.stream.Collectors;
 public class PositionBillServiceHelper {
     private static final Log log = LogFactory.getLog(PositionBillServiceHelper.class);
 
+    public static void setChangeDes(List<DynamicObject> changeDyos) {
+        setChangeDes(changeDyos, false);
+    }
+
+    public static void setChangeDes(List<DynamicObject> changeDyos, Boolean isEntry) {
+        String positionKey = isEntry ? String.format("%s_%s.%s", PositionBillConstant.NCKD_POSITION_KEY, PositionBillConstant.CHANGE_TAG, PositionBillConstant.BOID_KEY) : String.join(".", PositionBillConstant.NCKD_POSITION_KEY, PositionBillConstant.BOID_KEY);
+        List<Long> changeIds = changeDyos.stream().map(changeDyo -> changeDyo.getLong(positionKey)).collect(Collectors.toList());
+
+        // 获取要记录的变更字段
+        Map<String, String> changeFieldMap = Arrays.stream(HRBaseServiceHelper.create(PositionBillConstant.NCKD_PBENTRY_CHANGE_FIELD_ENTITY).queryOriginalArray(PositionBillConstant.NUMBER_KEY, null, PositionBillConstant.INDEX_KEY)).map(changeFieldDy -> changeFieldDy.getString(PositionBillConstant.NUMBER_KEY)).collect(Collectors.toMap(Function.identity(), Function.identity(), (oldValue, newValue) -> newValue, LinkedHashMap::new));
+        // 获取岗位要转换的键值
+        Map<String, String> positionTransKeyMap = getPositionTransKeyMap();
+        for (Map.Entry<String, String> entry : changeFieldMap.entrySet()) {
+            if (positionTransKeyMap.containsKey(entry.getKey())) {
+                changeFieldMap.put(entry.getKey(), positionTransKeyMap.get(entry.getKey()));
+            }
+        }
+
+        if (isEntry) {
+            // 获取分录要转换的键值
+            Map<String, String> posBillEntryReverseTransKeyMap = getPosBillEntryTransKeyMap().entrySet().stream().collect(Collectors.toMap(Map.Entry::getValue, Map.Entry::getKey, (oldValue, newValue) -> newValue));
+            changeFieldMap = changeFieldMap.entrySet().stream().collect(Collectors.toMap(entry -> {
+                String entryChangeField = String.join("_", entry.getKey(), PositionBillConstant.CHANGE_TAG);
+                if (posBillEntryReverseTransKeyMap.containsKey(entry.getKey())) {
+                    entryChangeField = String.join("_", posBillEntryReverseTransKeyMap.get(entry.getKey()), PositionBillConstant.CHANGE_TAG);
+                }
+                return entryChangeField;
+            }, Map.Entry::getValue, (oldValue, newValue) -> newValue, LinkedHashMap::new));
+        }
+
+        Map<String, IDataEntityProperty> positionAllFields = EntityMetadataCache.getDataEntityType(PositionBillConstant.HBPM_POSITIONHR).getAllFields();
+        Map<Long, DynamicObject> dbPositionDyMap = Arrays.stream(HRBaseServiceHelper.create(PositionBillConstant.HBPM_POSITIONHR).loadDynamicObjectArray(changeIds.toArray())).collect(Collectors.toMap(dbPositionDy -> dbPositionDy.getLong(PositionBillConstant.BOID_KEY), Function.identity()));
+        for (DynamicObject changeDyo : changeDyos) {
+            List<String> changeDesList = new ArrayList<String>();
+            DynamicObject dbPositionDyo = dbPositionDyMap.get(changeDyo.getLong(positionKey));
+            for (Map.Entry<String, String> entry : changeFieldMap.entrySet()) {
+                String positionField = entry.getValue();
+                if (!positionAllFields.containsKey(positionField)) {
+                    log.warn(HRStringUtils.format("PositionBillServiceHelper.setChangeDes not find field '{}' in position.", positionField));
+                    continue;
+                }
+
+                boolean isChange;
+                Object oldValue = dbPositionDyo.get(positionField);
+                Object newValue = changeDyo.get(entry.getKey());
+                if (HRObjectUtils.isEmpty(oldValue) && HRObjectUtils.isEmpty(newValue)) {
+                    isChange = false;
+                } else if ((HRObjectUtils.isEmpty(oldValue) && !HRObjectUtils.isEmpty(newValue)) || (!HRObjectUtils.isEmpty(oldValue) && HRObjectUtils.isEmpty(newValue))) {
+                    isChange = true;
+                } else {
+                    isChange = !HRDynamicObjectUtils.compareValues(oldValue, newValue);
+                }
+
+                if (isChange) {
+                    String fieldName = changeDyo.getDynamicObjectType().getProperty(entry.getKey()).getDisplayName().getLocaleValue();
+                    changeDesList.add(HRStringUtils.format("{}:\"{}\" -> \"{}\"", fieldName, getValue(dbPositionDyo, positionField, oldValue), getValue(changeDyo, entry.getKey(), newValue)));
+                }
+            }
+
+            changeDyo.set(isEntry ? String.join("_", PositionBillConstant.NCKD_CHANGEDES_KEY, PositionBillConstant.CHANGE_TAG) : PositionBillConstant.NCKD_CHANGEDES_KEY, changeDesList.isEmpty() ? null : String.join(System.lineSeparator(), changeDesList));
+        }
+    }
+
+    private static String getValue(DynamicObject dyo, String field, Object val) {
+        if (!HRObjectUtils.isEmpty(val)) {
+            if (val instanceof DynamicObject) {
+                return ((DynamicObject) val).getString(PositionBillConstant.NAME_KEY);
+            } else if (val instanceof DynamicObjectCollection) {
+                if (((DynamicObjectCollection) val).isEmpty()) {
+                    return " ";
+                }
+
+                List<String> list = new ArrayList<String>();
+                for (DynamicObject d : (DynamicObjectCollection) val) {
+                    DynamicProperty baseDataProp = d.getDynamicObjectType().getProperty(PositionBillConstant.FBASEDATAID_KEY);
+                    if (baseDataProp == null) {
+                        list.add(d.getString(PositionBillConstant.NAME_KEY));
+                    } else {
+                        list.add(d.getDynamicObject(PositionBillConstant.FBASEDATAID_KEY).getString(PositionBillConstant.NAME_KEY));
+                    }
+                }
+                return String.join(";", list);
+            } else {
+                return dyo.getString(field);
+            }
+        }
+
+        return " ";
+    }
+
     public static String getNoLineSuffixProp(String prop, String lineSuffix) {
         if (prop.endsWith(lineSuffix)) {
             return prop.substring(0, prop.lastIndexOf(lineSuffix));
@@ -101,8 +195,8 @@ public class PositionBillServiceHelper {
         return transKeyMap;
     }
 
-    public static Set<String> getPositionAllEntities() {
-        return EntityMetadataCache.getDataEntityType(PositionBillConstant.HBPM_POSITIONHR).getAllEntities().keySet();
+    public static Set<String> getPositionProperties() {
+        return EntityMetadataCache.getDataEntityType(PositionBillConstant.HBPM_POSITIONHR).getProperties().stream().map(IDataEntityProperty::getName).collect(Collectors.toSet());
     }
 
     /**

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

@@ -25,6 +25,8 @@ public class PositionBillConstant extends FormConstant {
     public static final String NCKD_PBENTRY_TRANSKEY_ENTITY = "nckd_pbentry_transkey";
     /** 岗位管理_应用首页实体标识 */
     public static final String NCKD_POSTMGR_APPHOME_ENTITY = "nckd_postmgr_apphome";
+    /** 岗位分录变更字段-实体标识 */
+    public static final String NCKD_PBENTRY_CHANGE_FIELD_ENTITY = "nckd_pbentry_change_field";
 
     /** 新增标识 */
     public static final String ADD_TAG = "add";
@@ -101,6 +103,8 @@ public class PositionBillConstant extends FormConstant {
     public static final String NCKD_POSBILLENTRY_KEY = "nckd_posbillentry";
     /** 岗位申请单分录 */
     public static final String NCKD_ENTRYENTITYUNDERLINE_KEY = "nckd_entryentity_";
+    /** 变更说明 */
+    public static final String NCKD_CHANGEDES_KEY = "nckd_changedes";
 
     /** 岗位生效时间页面自定义参数 */
     public static final String CP_POSITION_BSED = "position_bsed";

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

@@ -21,6 +21,7 @@ import kd.bos.form.ConfirmTypes;
 import kd.bos.form.MessageBoxOptions;
 import kd.bos.form.MessageBoxResult;
 import kd.bos.form.events.AfterDoOperationEventArgs;
+import kd.bos.form.events.BeforeDoOperationEventArgs;
 import kd.bos.form.events.MessageBoxClosedEvent;
 import kd.bos.form.field.BasedataEdit;
 import kd.bos.form.field.events.BeforeF7SelectEvent;
@@ -386,6 +387,13 @@ public class PosBillEntryUpdatePlugin extends AbstractFormPlugin implements Befo
         }
     }
 
+    @Override
+    public void beforeDoOperation(BeforeDoOperationEventArgs args) {
+        super.beforeDoOperation(args);
+
+        PositionBillServiceHelper.setChangeDes(Collections.singletonList(getModel().getDataEntity()));
+    }
+
     public void afterDoOperation(AfterDoOperationEventArgs afterDoOperationEventArgs) {
         super.afterDoOperation(afterDoOperationEventArgs);
         String key = afterDoOperationEventArgs.getOperateKey();

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

@@ -316,6 +316,9 @@ public class PositionBillFormPlugin extends AbstractFormPlugin implements Before
         }
 
         if (HRStringUtils.equalsAny(operateKey, PositionBillConstant.SAVE_OP, PositionBillConstant.SUBMIT_OP, PositionBillConstant.SUBMITEFFECT_OP)) {
+            PositionBillServiceHelper.setChangeDes(getModel().getDataEntity(true).getDynamicObjectCollection(PositionBillConstant.NCKD_ENTRYENTITY_CHANGE_KEY), true);
+            getView().updateView(PositionBillConstant.NCKD_ENTRYENTITY_CHANGE_KEY);
+
             if (HRStringUtils.equals(operateKey, PositionBillConstant.SUBMIT_OP) || HRStringUtils.equals(operateKey, PositionBillConstant.SUBMITEFFECT_OP)) {
                 if (!executeSaveOperation(operateKey, operate.getOption())) {
                     args.setCancel(true);

+ 0 - 0
code/wtc/nckd-jxccl-wtc/src/main/java/nckd/jxccl/wtc/wtp/business/.gitkeep


+ 22 - 0
code/wtc/nckd-jxccl-wtc/src/main/java/nckd/jxccl/wtc/wtp/common/AppflgConstant.java

@@ -0,0 +1,22 @@
+/**
+ * This is a kingdee cosmic template project that is automatically generated by the Kingdee cosmic development assistant plugin. 
+ * If there are any issues during the use process, you can provide feedback to the kingdee developer community website.
+ * Website: https://developer.kingdee.com/developer?productLineId=29
+ * Author: liebin.zheng
+ * Generate Date: 2025-10-23 16:09:09
+ */
+package nckd.jxccl.wtc.wtp.common;
+
+/**
+ * wtc云init应用-通用常量类<br>
+ * 代码中不能存在硬编码敏感信息,如账号、密码、http外链、ftp外链、邮箱等。<br>
+ * 标识或缓存的常量,需以"KEY_"、"FID_"、"ENTRY_"或"SUBENTRY_"作为变量的前缀。<br>
+ *
+ * @author nckd
+ * @date 2025-10-23 16:09:09
+ */
+public class AppflgConstant {
+	
+	public static final String KEY_APP_NAME = "wtc-init";
+
+}

+ 0 - 0
code/wtc/nckd-jxccl-wtc/src/main/java/nckd/jxccl/wtc/wtp/mservice/.gitkeep


+ 32 - 0
code/wtc/nckd-jxccl-wtc/src/main/java/nckd/jxccl/wtc/wtp/mservice/WTPCustomerService.java

@@ -0,0 +1,32 @@
+package nckd.jxccl.wtc.wtp.mservice;
+
+import kd.bos.dataentity.entity.DynamicObject;
+import kd.hr.hbp.business.servicehelper.HRMServiceHelper;
+import kd.hr.hbp.common.util.HRObjectUtils;
+import kd.sdk.wtc.wtp.business.attfile.AttFileVersion;
+import kd.sdk.wtc.wtp.business.helper.WTPServiceHelper;
+import nckd.jxccl.wtc.wtp.mservice.api.IWTPCustomerService;
+
+import java.time.LocalDate;
+import java.util.Date;
+import java.util.List;
+
+/**
+ *  工事假勤规则自定义微服务
+ * @author: jtd
+ * @date: 2026/1/11 18:41
+ */
+public class WTPCustomerService implements IWTPCustomerService {
+
+    @Override
+    public Long getAttFileBoId(LocalDate localDate, long employeeId) {
+        AttFileVersion attFile = WTPServiceHelper.getAttFile(localDate, employeeId);
+        return HRObjectUtils.isEmpty(attFile) ? 0L : attFile.getBoId();
+    }
+
+    @Override
+    public List<DynamicObject> queryQuota(long attFileBoId, List<Long> qtTypeIdList, int rangQueryType, Date startDate, Date endDate) {
+        return HRMServiceHelper.invokeBizService("wtc", "wtp", "IQTService", "queryQuota", new Object[]{attFileBoId, qtTypeIdList, rangQueryType, startDate, endDate});
+    }
+
+}

+ 36 - 0
code/wtc/nckd-jxccl-wtc/src/main/java/nckd/jxccl/wtc/wtp/mservice/api/IWTPCustomerService.java

@@ -0,0 +1,36 @@
+package nckd.jxccl.wtc.wtp.mservice.api;
+
+import kd.bos.dataentity.entity.DynamicObject;
+
+import java.time.LocalDate;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 工事假勤规则自定义微服务接口
+ * @author: jtd
+ * @date: 2026/1/11 18:35
+ */
+public interface IWTPCustomerService {
+    /**
+     * 获取人员考勤档案BOID
+     * @from: kd.sdk.wtc.wtp.business.helper.WTPServiceHelper.getAttFile
+     * @param localDate
+     * @param employeeId
+     * @return
+     */
+    Long getAttFileBoId(LocalDate localDate, long employeeId);
+
+    /**
+     * 查询定额明细
+     * @from: kd.sdk.wtc.wtp.business.helper.WTPServiceHelper.queryQuota
+     * @param attFileBoId
+     * @param qtTypeIdList
+     * @param rangQueryType
+     * @param startDate
+     * @param endDate
+     * @return
+     */
+    List<DynamicObject> queryQuota(long attFileBoId, List<Long> qtTypeIdList, int rangQueryType, Date startDate, Date endDate);
+
+}

+ 0 - 0
code/wtc/nckd-jxccl-wtc/src/main/java/nckd/jxccl/wtc/wtp/plugin/form/.gitkeep


+ 0 - 0
code/wtc/nckd-jxccl-wtc/src/main/java/nckd/jxccl/wtc/wtp/plugin/operate/.gitkeep


+ 0 - 0
code/wtc/nckd-jxccl-wtc/src/main/java/nckd/jxccl/wtc/wtp/plugin/other/.gitkeep


+ 0 - 0
code/wtc/nckd-jxccl-wtc/src/main/java/nckd/jxccl/wtc/wtp/plugin/report/.gitkeep


+ 0 - 0
code/wtc/nckd-jxccl-wtc/src/main/java/nckd/jxccl/wtc/wtp/plugin/workflow/.gitkeep


+ 35 - 0
code/wtc/nckd-jxccl-wtc/src/main/java/nckd/jxccl/wtc/wtp/servicehelper/ServiceFactory.java

@@ -0,0 +1,35 @@
+package nckd.jxccl.wtc.wtp.servicehelper;
+
+import kd.bos.dataentity.TypesContainer;
+import kd.bos.exception.KDBizException;
+
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+
+/**
+ * 工事假勤规则自定义微服务工厂
+ * @author: jtd
+ * @date: 2026/1/11 18:28
+ */
+public class ServiceFactory {
+
+    private static Map<String, String> serviceMap = new HashMap<>();
+
+    static {
+        serviceMap.put("IWTPCustomerService", "nckd.jxccl.wtc.wtp.mservice.WTPCustomerService");
+    }
+
+    public static <T> T getService(Class<T> clazz) {
+        return (T) getService(clazz.getSimpleName());
+    }
+
+    public static Object getService(String serviceName) {
+        String className = serviceMap.get(serviceName);
+        if (className == null) {
+            throw new KDBizException(String.format(Locale.ROOT, "未找到%s对应的服务实现。", new Object[]{serviceName}));
+        }
+        return TypesContainer.getOrRegisterSingletonInstance(className);
+    }
+
+}

+ 0 - 0
code/wtc/nckd-jxccl-wtc/src/main/java/nckd/jxccl/wtc/wtp/webapi/.gitkeep