Преглед на файлове

feat: 五类ERP流程补齐申请公司部门和负责人

lfx преди 3 дни
родител
ревизия
a72e3667ec

+ 12 - 1
src/main/java/com/malk/minglei/service/impl/yida/Apmt100FormPushHandler.java

@@ -55,13 +55,23 @@ public class Apmt100FormPushHandler implements YidaFormPushHandler {
     private final YidaProcessOpenApiClient yidaProcessOpenApiClient;
     private final DDConf dingTalkConfiguration;
     private final YidaApplicationsProperties applications;
+    private final LocalFormDepartmentEnricher departmentEnricher;
 
+    /**
+     * 创建供应商导入推送处理器。
+     * @param yidaProcessOpenApiClient 宜搭流程客户端
+     * @param dingTalkConfiguration 钉钉应用配置
+     * @param applications 宜搭应用配置
+     * @param departmentEnricher 部门公司和负责人填充组件
+     */
     public Apmt100FormPushHandler(YidaProcessOpenApiClient yidaProcessOpenApiClient,
                                   DDConf dingTalkConfiguration,
-                                  YidaApplicationsProperties applications) {
+                                  YidaApplicationsProperties applications,
+                                  LocalFormDepartmentEnricher departmentEnricher) {
         this.yidaProcessOpenApiClient = yidaProcessOpenApiClient;
         this.dingTalkConfiguration = dingTalkConfiguration;
         this.applications = applications;
+        this.departmentEnricher = departmentEnricher;
     }
 
     @Override
@@ -78,6 +88,7 @@ public class Apmt100FormPushHandler implements YidaFormPushHandler {
         String title = requireText(toText(firstNonBlank(mainData.get("lcbh"), mainData.get("docno"))),
                 "apmt100 requires mainData.lcbh or mainData.docno");
         Map<String, Object> formData = toYidaFormData(mainData, operatorUserId, title);
+        departmentEnricher.fill(FORM_UUID, operatorUserId, formData);
 
         Map<String, Object> body = new LinkedHashMap<String, Object>();
         body.put("appType", requireText(applications.getCoordinationOffice().getAppType(), "YIDA_COORDINATION_OFFICE_APP_TYPE is not configured"));

+ 6 - 1
src/main/java/com/malk/minglei/service/impl/yida/Aqct300FormPushHandler.java

@@ -113,6 +113,7 @@ public class Aqct300FormPushHandler implements YidaFormPushHandler {
     private final YidaProcessOpenApiClient yidaProcessOpenApiClient;
     private final DDConf dingTalkConfiguration;
     private final YidaApplicationsProperties applications;
+    private final LocalFormDepartmentEnricher departmentEnricher;
 
     /**
      * 创建检验情况审批推送处理器。
@@ -120,13 +121,16 @@ public class Aqct300FormPushHandler implements YidaFormPushHandler {
      * @param yidaProcessOpenApiClient 宜搭流程 OpenAPI 客户端
      * @param dingTalkConfiguration 钉钉应用配置
      * @param applications 宜搭应用配置
+     * @param departmentEnricher 部门公司和负责人填充组件
      */
     public Aqct300FormPushHandler(YidaProcessOpenApiClient yidaProcessOpenApiClient,
                                   DDConf dingTalkConfiguration,
-                                  YidaApplicationsProperties applications) {
+                                  YidaApplicationsProperties applications,
+                                  LocalFormDepartmentEnricher departmentEnricher) {
         this.yidaProcessOpenApiClient = yidaProcessOpenApiClient;
         this.dingTalkConfiguration = dingTalkConfiguration;
         this.applications = applications;
+        this.departmentEnricher = departmentEnricher;
     }
 
     /**
@@ -152,6 +156,7 @@ public class Aqct300FormPushHandler implements YidaFormPushHandler {
         Map<String, Object> mainData = toMainDataMap(request.getMainData());
         String operatorUserId = requireText(resolveOperatorUserId(request), "aqct300 requires mainData.tjr");
         Map<String, Object> formData = toYidaFormData(request, mainData, operatorUserId);
+        departmentEnricher.fill(FORM_UUID, operatorUserId, formData);
         String title = requireText(toText(formData.get(TITLE_FIELD_ID)), "aqct300 requires mainData.qcbadocno");
 
         Map<String, Object> body = new LinkedHashMap<String, Object>();

+ 13 - 2
src/main/java/com/malk/minglei/service/impl/yida/Asft800FormPushHandler.java

@@ -74,13 +74,23 @@ Asft800FormPushHandler implements YidaFormPushHandler {
     private final YidaProcessOpenApiClient yidaProcessOpenApiClient;
     private final DDConf dingTalkConfiguration;
     private final YidaApplicationsProperties applications;
-
+    private final LocalFormDepartmentEnricher departmentEnricher;
+
+    /**
+     * 创建包装工单变更推送处理器。
+     * @param yidaProcessOpenApiClient 宜搭流程客户端
+     * @param dingTalkConfiguration 钉钉应用配置
+     * @param applications 宜搭应用配置
+     * @param departmentEnricher 部门公司和负责人填充组件
+     */
     public Asft800FormPushHandler(YidaProcessOpenApiClient yidaProcessOpenApiClient,
                                   DDConf dingTalkConfiguration,
-                                  YidaApplicationsProperties applications) {
+                                  YidaApplicationsProperties applications,
+                                  LocalFormDepartmentEnricher departmentEnricher) {
         this.yidaProcessOpenApiClient = yidaProcessOpenApiClient;
         this.dingTalkConfiguration = dingTalkConfiguration;
         this.applications = applications;
+        this.departmentEnricher = departmentEnricher;
     }
 
     @Override
@@ -95,6 +105,7 @@ Asft800FormPushHandler implements YidaFormPushHandler {
         Map<String, Object> mainData = toMainDataMap(request.getMainData());
         String operatorUserId = requireText(resolveOperatorUserId(request, mainData), "asft800 requires mainData.ooagud004 or mainData.tjr");
         Map<String, Object> formData = toYidaFormData(request, mainData, operatorUserId);
+        departmentEnricher.fill(FORM_UUID, operatorUserId, formData);
         String title = requireText(toText(formData.get(TITLE_FIELD_ID)), "asft800 requires mainData.sfkadocno");
 
         Map<String, Object> body = new LinkedHashMap<String, Object>();

+ 6 - 1
src/main/java/com/malk/minglei/service/impl/yida/Axmt510FormPushHandler.java

@@ -118,6 +118,7 @@ public class Axmt510FormPushHandler implements YidaFormPushHandler {
     private final YidaProcessOpenApiClient yidaProcessOpenApiClient;
     private final DDConf dingTalkConfiguration;
     private final YidaApplicationsProperties applications;
+    private final LocalFormDepartmentEnricher departmentEnricher;
 
     /**
      * 创建订单变更申请推送处理器。
@@ -125,13 +126,16 @@ public class Axmt510FormPushHandler implements YidaFormPushHandler {
      * @param yidaProcessOpenApiClient 宜搭流程 OpenAPI 客户端
      * @param dingTalkConfiguration 钉钉应用配置
      * @param applications 宜搭应用配置
+     * @param departmentEnricher 部门公司和负责人填充组件
      */
     public Axmt510FormPushHandler(YidaProcessOpenApiClient yidaProcessOpenApiClient,
                                   DDConf dingTalkConfiguration,
-                                  YidaApplicationsProperties applications) {
+                                  YidaApplicationsProperties applications,
+                                  LocalFormDepartmentEnricher departmentEnricher) {
         this.yidaProcessOpenApiClient = yidaProcessOpenApiClient;
         this.dingTalkConfiguration = dingTalkConfiguration;
         this.applications = applications;
+        this.departmentEnricher = departmentEnricher;
     }
 
     /**
@@ -157,6 +161,7 @@ public class Axmt510FormPushHandler implements YidaFormPushHandler {
         Map<String, Object> mainData = toMainDataMap(request.getMainData());
         String operatorUserId = requireText(resolveOperatorUserId(request), "axmt510 requires mainData.tjr");
         Map<String, Object> formData = toYidaFormData(request, mainData, operatorUserId);
+        departmentEnricher.fill(FORM_UUID, operatorUserId, formData);
         String title = requireText(toText(formData.get(TITLE_FIELD_ID)), "axmt510 requires mainData.xmeedocno");
 
         Map<String, Object> body = new LinkedHashMap<String, Object>();

+ 101 - 0
src/main/java/com/malk/minglei/service/impl/yida/LocalFormDepartmentEnricher.java

@@ -0,0 +1,101 @@
+package com.malk.minglei.service.impl.yida;
+
+import com.malk.minglei.service.yida.MingleiDocumentService;
+import org.springframework.stereotype.Component;
+import org.springframework.util.StringUtils;
+
+import java.util.Collections;
+import java.util.Map;
+
+/**
+ * 为明磊 ERP 表单补充申请人所属部门、公司和审批矩阵负责人。
+ */
+@Component
+public class LocalFormDepartmentEnricher {
+
+    private final MingleiDocumentService documentService;
+
+    /**
+     * 创建部门字段填充组件。
+     * @param documentService 部门配置和审批矩阵查询服务
+     */
+    public LocalFormDepartmentEnricher(MingleiDocumentService documentService) {
+        this.documentService = documentService;
+    }
+
+    /**
+     * 按表单真实字段映射填入公司、申请部门及负责人;空配置清除旧值并允许继续发起。
+     * @param formUuid 宜搭表单 UUID
+     * @param userId 申请人的钉钉用户 ID
+     * @param formData 待发起流程的表单数据
+     */
+    public void fill(String formUuid, String userId, Map<String, Object> formData) {
+        String[] companyFields;
+        String[] applicantManagerFields = {null, null, null};
+        String fixedDepartmentId = null;
+        String fixedManagerField = null;
+        String fixedManagerSource = "employeeField_mszdqrl9";
+        switch (formUuid) {
+            case "FORM-4B08ADABCDAA45788C043729A855E03ED76G":
+                companyFields = new String[]{"selectField_mso1em48"};
+                applicantManagerFields = new String[]{"employeeField_mtjp3e58", "employeeField_mtjp3e59", "employeeField_mvylqnek"};
+                break;
+            case "FORM-40D6FBBBF4A94864A2AF9535AAC7924CRBH2":
+                companyFields = new String[]{"textField_mu1z5kaf", "selectField_mso1em48"};
+                applicantManagerFields = new String[]{"employeeField_mt6thsdh", "employeeField_mt6thsdi", "employeeField_mt6v6alx"};
+                fixedDepartmentId = "972685113";
+                fixedManagerField = "employeeField_mtqwsyjz";
+                break;
+            case "FORM-38C8592E7F5F45B3A388DA3FEFBA67C2GCEV":
+                companyFields = new String[]{"selectField_mtxpfhhe"};
+                fixedDepartmentId = "962219816";
+                fixedManagerField = "employeeField_mvlu7ko7";
+                break;
+            case "FORM-8F318292B70D4ED39080EE0C631DC74BG3MD":
+                companyFields = new String[]{"selectField_mso1em48"};
+                applicantManagerFields = new String[]{"employeeField_mt6thsdh", "employeeField_mt6thsdi", "employeeField_mt6v6alx"};
+                fixedDepartmentId = "962219826";
+                fixedManagerField = "employeeField_mt8162rn";
+                fixedManagerSource = "employeeField_mszdqrl8";
+                break;
+            case "FORM-9EE14CA14D8D4AEE8102944E669E6B0CFUKS":
+                companyFields = new String[]{"textField_mu1zpoe4", "selectField_mso1em48"};
+                applicantManagerFields[1] = "employeeField_mttrhcqq";
+                fixedDepartmentId = "962219816";
+                fixedManagerField = "employeeField_mttrhcqs";
+                break;
+            default:
+                throw new IllegalArgumentException("Unsupported department enrichment form: " + formUuid);
+        }
+
+        Map<String, Object> configuration = documentService.queryApplicantDepartmentConfiguration(userId);
+        replace(formData, "departmentSelectField_msh186ry", members(configuration.get("departmentId")));
+        for (String field : companyFields) {
+            replace(formData, field, configuration.get("company"));
+        }
+        String[] managerKeys = {"firstLevelManagerUserIds", "secondLevelManagerUserIds", "thirdLevelManagerUserIds"};
+        for (int level = 0; level < applicantManagerFields.length; level++) {
+            if (applicantManagerFields[level] != null) {
+                replace(formData, applicantManagerFields[level], configuration.get(managerKeys[level]));
+            }
+        }
+        if (fixedDepartmentId != null) {
+            Map<String, Object> managers = documentService.queryDepartmentManagersByDepartmentId(fixedDepartmentId);
+            replace(formData, fixedManagerField, members(managers.get(fixedManagerSource)));
+        }
+    }
+
+    private Object members(Object userOrDepartmentId) {
+        return userOrDepartmentId == null || !StringUtils.hasText(String.valueOf(userOrDepartmentId))
+                ? null : Collections.singletonList(String.valueOf(userOrDepartmentId).trim());
+    }
+
+    private void replace(Map<String, Object> formData, String field, Object value) {
+        formData.remove(field);
+        if (value == null || (value instanceof String && !StringUtils.hasText((String) value))
+                || (value instanceof Iterable && !((Iterable<?>) value).iterator().hasNext())) {
+            return;
+        }
+        formData.put(field, value);
+    }
+}

+ 6 - 1
src/main/java/com/malk/minglei/service/impl/yida/MiscReceiptIssueFormPushHandler.java

@@ -73,6 +73,7 @@ public class MiscReceiptIssueFormPushHandler implements YidaFormPushHandler {
     private final YidaProcessOpenApiClient yidaProcessOpenApiClient;
     private final DDConf dingTalkConfiguration;
     private final YidaApplicationsProperties applications;
+    private final LocalFormDepartmentEnricher departmentEnricher;
 
     /**
      * 创建杂收发料单推送处理器。
@@ -80,13 +81,16 @@ public class MiscReceiptIssueFormPushHandler implements YidaFormPushHandler {
      * @param yidaProcessOpenApiClient 宜搭流程 OpenAPI 客户端
      * @param dingTalkConfiguration 钉钉应用配置
      * @param applications 宜搭应用配置
+     * @param departmentEnricher 部门公司和负责人填充组件
      */
     public MiscReceiptIssueFormPushHandler(YidaProcessOpenApiClient yidaProcessOpenApiClient,
                                            DDConf dingTalkConfiguration,
-                                           YidaApplicationsProperties applications) {
+                                           YidaApplicationsProperties applications,
+                                           LocalFormDepartmentEnricher departmentEnricher) {
         this.yidaProcessOpenApiClient = yidaProcessOpenApiClient;
         this.dingTalkConfiguration = dingTalkConfiguration;
         this.applications = applications;
+        this.departmentEnricher = departmentEnricher;
     }
 
     /**
@@ -113,6 +117,7 @@ public class MiscReceiptIssueFormPushHandler implements YidaFormPushHandler {
         String appType = requireText(applications.getCoordinationOffice().getAppType(), "YIDA_COORDINATION_OFFICE_APP_TYPE is not configured");
         String systemToken = requireText(applications.getCoordinationOffice().getSystemToken(), "YIDA_COORDINATION_OFFICE_SYSTEM_TOKEN is not configured");
         Map<String, Object> formData = toYidaFormData(request, operatorUserId);
+        departmentEnricher.fill(FORM_UUID, operatorUserId, formData);
         String title = requireText(toText(formData.get(TITLE_FIELD_ID)), "Yida process title is not configured");
         Map<String, Object> body = new LinkedHashMap<String, Object>();
         body.put("appType", appType);

+ 14 - 1
src/test/java/com/malk/minglei/service/impl/yida/Apmt100FormPushHandlerTest.java

@@ -4,6 +4,7 @@ import com.alibaba.fastjson.JSONObject;
 import com.malk.minglei.config.YidaApplicationsProperties;
 import com.malk.minglei.dto.ErpYidaPushMainData;
 import com.malk.minglei.dto.ErpYidaPushRequest;
+import com.malk.minglei.service.yida.MingleiDocumentService;
 import com.malk.minglei.service.yida.YidaProcessOpenApiClient;
 import com.malk.server.dingtalk.DDR_New;
 import com.malk.server.dingtalk.DDConf;
@@ -11,6 +12,7 @@ import org.junit.jupiter.api.Test;
 import org.mockito.ArgumentCaptor;
 
 import java.util.Collections;
+import java.util.LinkedHashMap;
 import java.util.Map;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
@@ -65,7 +67,13 @@ class Apmt100FormPushHandlerTest {
         request.setDetailData(Collections.emptyMap());
         request.setOriginatorUserId("dingtalk-user-001");
 
-        Apmt100FormPushHandler handler = new Apmt100FormPushHandler(yidaClient, ddConf, applications);
+        MingleiDocumentService documentService = FormDepartmentTestSupport.configuredDocumentService("dingtalk-user-001");
+        Map<String, Object> qualityManagers = new LinkedHashMap<String, Object>();
+        qualityManagers.put("employeeField_mszdqrl8", "quality-first-001");
+        qualityManagers.put("employeeField_mszdqrl9", "quality-second-001");
+        when(documentService.queryDepartmentManagersByDepartmentId("962219816")).thenReturn(qualityManagers);
+        Apmt100FormPushHandler handler = new Apmt100FormPushHandler(yidaClient, ddConf, applications,
+                new LocalFormDepartmentEnricher(documentService));
 
         assertEquals(Collections.singletonList("apmt100"), handler.getTypes());
         assertEquals("process-instance-1", handler.push(request));
@@ -80,6 +88,11 @@ class Apmt100FormPushHandlerTest {
         assertEquals("dingtalk-user-001", body.get("userId"));
 
         JSONObject formData = JSONObject.parseObject(String.valueOf(body.get("formDataJson")));
+        assertEquals("Configured Company", formData.getString("textField_mu1zpoe4"));
+        assertEquals("Configured Company", formData.getString("selectField_mso1em48"));
+        assertEquals(Collections.singletonList("configured-dept-001"), formData.getJSONArray("departmentSelectField_msh186ry"));
+        assertEquals(Collections.singletonList("applicant-second-001"), formData.getJSONArray("employeeField_mttrhcqq"));
+        assertEquals(Collections.singletonList("quality-second-001"), formData.getJSONArray("employeeField_mttrhcqs"));
         assertEquals("supplier-name", formData.getString("textField_mszogjgv"));
         assertEquals("SUP-001", formData.getString("textField_mszogjgw"));
         assertEquals("1000000.50", formData.getString("textField_mszogjgy"));

+ 13 - 3
src/test/java/com/malk/minglei/service/impl/yida/Aqct300FormPushHandlerTest.java

@@ -5,6 +5,7 @@ import com.alibaba.fastjson.JSONObject;
 import com.malk.minglei.config.YidaApplicationsProperties;
 import com.malk.minglei.dto.ErpYidaPushMainData;
 import com.malk.minglei.dto.ErpYidaPushRequest;
+import com.malk.minglei.service.yida.MingleiDocumentService;
 import com.malk.minglei.service.yida.YidaProcessOpenApiClient;
 import com.malk.server.dingtalk.DDR_New;
 import com.malk.server.dingtalk.DDConf;
@@ -126,7 +127,13 @@ class Aqct300FormPushHandlerTest {
         request.setMainData(mainData);
         request.setDetailData(detailData);
 
-        Aqct300FormPushHandler handler = new Aqct300FormPushHandler(yidaClient, ddConf, applications);
+        MingleiDocumentService documentService = FormDepartmentTestSupport.configuredDocumentService("dingtalk-user-001");
+        Map<String, Object> qualityManagers = new LinkedHashMap<String, Object>();
+        qualityManagers.put("employeeField_mszdqrl8", "quality-first-001");
+        qualityManagers.put("employeeField_mszdqrl9", "quality-second-001");
+        when(documentService.queryDepartmentManagersByDepartmentId("962219816")).thenReturn(qualityManagers);
+        Aqct300FormPushHandler handler = new Aqct300FormPushHandler(yidaClient, ddConf, applications,
+                new LocalFormDepartmentEnricher(documentService));
 
         assertEquals(Collections.singletonList("aqct300"), handler.getTypes());
         assertEquals("process-instance-1", handler.push(request));
@@ -156,7 +163,9 @@ class Aqct300FormPushHandlerTest {
         assertEquals("75", formData.getString("numberField_mt87k1gc"));
         assertEquals("inspector-zhang", formData.getString("textField_mt87k1g4"));
         assertEquals("LOT-001", formData.getString("textField_mt87k1gb"));
-        assertEquals("\u660e\u78ca", formData.getString("selectField_mtxpfhhe"));
+        assertEquals("Configured Company", formData.getString("selectField_mtxpfhhe"));
+        assertEquals(Collections.singletonList("configured-dept-001"), formData.getJSONArray("departmentSelectField_msh186ry"));
+        assertEquals(Collections.singletonList("quality-second-001"), formData.getJSONArray("employeeField_mvlu7ko7"));
         assertEquals("dingtalk-user-001", formData.getJSONArray("employeeField_msh186rr").getString(0));
         // 缺口字段按约定丢弃:交易对象、料件、表头不良数
         assertNull(formData.get("qcba005"));
@@ -198,7 +207,8 @@ class Aqct300FormPushHandlerTest {
         request.setMainData(mainData);
         request.setDetailData(Collections.emptyMap());
 
-        Aqct300FormPushHandler handler = new Aqct300FormPushHandler(yidaClient, ddConf, applications);
+        Aqct300FormPushHandler handler = new Aqct300FormPushHandler(yidaClient, ddConf, applications,
+                new LocalFormDepartmentEnricher(mock(MingleiDocumentService.class)));
         assertThrows(IllegalArgumentException.class, () -> handler.push(request));
     }
 }

+ 16 - 1
src/test/java/com/malk/minglei/service/impl/yida/Asft800FormPushHandlerTest.java

@@ -5,12 +5,14 @@ import com.alibaba.fastjson.JSONObject;
 import com.malk.minglei.config.YidaApplicationsProperties;
 import com.malk.minglei.dto.ErpYidaPushMainData;
 import com.malk.minglei.dto.ErpYidaPushRequest;
+import com.malk.minglei.service.yida.MingleiDocumentService;
 import com.malk.minglei.service.yida.YidaProcessOpenApiClient;
 import com.malk.server.dingtalk.DDR_New;
 import com.malk.server.dingtalk.DDConf;
 import org.junit.jupiter.api.Test;
 import org.mockito.ArgumentCaptor;
 
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.LinkedHashMap;
 import java.util.Map;
@@ -76,7 +78,13 @@ class Asft800FormPushHandlerTest {
         request.setMainData(mainData);
         request.setDetailData(detailData);
 
-        Asft800FormPushHandler handler = new Asft800FormPushHandler(yidaClient, ddConf, applications);
+        MingleiDocumentService documentService = FormDepartmentTestSupport.configuredDocumentService("dingtalk-user-001");
+        Map<String, Object> logisticsManagers = new LinkedHashMap<String, Object>();
+        logisticsManagers.put("employeeField_mszdqrl8", "logistics-first-001");
+        logisticsManagers.put("employeeField_mszdqrl9", "logistics-second-001");
+        when(documentService.queryDepartmentManagersByDepartmentId("972685113")).thenReturn(logisticsManagers);
+        Asft800FormPushHandler handler = new Asft800FormPushHandler(yidaClient, ddConf, applications,
+                new LocalFormDepartmentEnricher(documentService));
 
         assertEquals(Collections.singletonList("asft800"), handler.getTypes());
         assertEquals("process-instance-1", handler.push(request));
@@ -91,6 +99,13 @@ class Asft800FormPushHandlerTest {
         assertEquals("\u5305\u88c5\u5de5\u5355\u53d8\u66f4\u5ba1\u6279\u6d41\u7a0b-WO-001", body.get("title"));
 
         JSONObject formData = JSONObject.parseObject(String.valueOf(body.get("formDataJson")));
+        assertEquals("Configured Company", formData.getString("textField_mu1z5kaf"));
+        assertEquals("Configured Company", formData.getString("selectField_mso1em48"));
+        assertEquals(Collections.singletonList("configured-dept-001"), formData.getJSONArray("departmentSelectField_msh186ry"));
+        assertEquals(Arrays.asList("applicant-first-001", "applicant-first-002"), formData.getJSONArray("employeeField_mt6thsdh"));
+        assertEquals(Collections.singletonList("applicant-second-001"), formData.getJSONArray("employeeField_mt6thsdi"));
+        assertEquals(Collections.singletonList("applicant-third-001"), formData.getJSONArray("employeeField_mt6v6alx"));
+        assertEquals(Collections.singletonList("logistics-second-001"), formData.getJSONArray("employeeField_mtqwsyjz"));
         assertEquals("WO-001", formData.getString("textField_msy7cb7z"));
         assertEquals("2", formData.getString("textField_msy7cb80"));
         assertEquals(Long.valueOf(1789488000000L), formData.getLong("dateField_msy7cb81"));

+ 17 - 3
src/test/java/com/malk/minglei/service/impl/yida/Axmt510FormPushHandlerTest.java

@@ -5,12 +5,14 @@ import com.alibaba.fastjson.JSONObject;
 import com.malk.minglei.config.YidaApplicationsProperties;
 import com.malk.minglei.dto.ErpYidaPushMainData;
 import com.malk.minglei.dto.ErpYidaPushRequest;
+import com.malk.minglei.service.yida.MingleiDocumentService;
 import com.malk.minglei.service.yida.YidaProcessOpenApiClient;
 import com.malk.server.dingtalk.DDR_New;
 import com.malk.server.dingtalk.DDConf;
 import org.junit.jupiter.api.Test;
 import org.mockito.ArgumentCaptor;
 
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.LinkedHashMap;
 import java.util.Map;
@@ -129,7 +131,13 @@ class Axmt510FormPushHandlerTest {
         request.setMainData(mainData);
         request.setDetailData(detailData);
 
-        Axmt510FormPushHandler handler = new Axmt510FormPushHandler(yidaClient, ddConf, applications);
+        MingleiDocumentService documentService = FormDepartmentTestSupport.configuredDocumentService("dingtalk-user-001");
+        Map<String, Object> marketingManagers = new LinkedHashMap<String, Object>();
+        marketingManagers.put("employeeField_mszdqrl8", "marketing-first-001");
+        marketingManagers.put("employeeField_mszdqrl9", "marketing-second-001");
+        when(documentService.queryDepartmentManagersByDepartmentId("962219826")).thenReturn(marketingManagers);
+        Axmt510FormPushHandler handler = new Axmt510FormPushHandler(yidaClient, ddConf, applications,
+                new LocalFormDepartmentEnricher(documentService));
 
         assertEquals(Collections.singletonList("axmt510"), handler.getTypes());
         assertEquals("process-instance-axmt510", handler.push(request));
@@ -157,7 +165,12 @@ class Axmt510FormPushHandlerTest {
         assertEquals("2", formData.getString("textField_mt82p091"));
         assertEquals("R01", formData.getString("textField_mt8747ps"));
         assertEquals("\u4ea4\u671f\u8c03\u6574", formData.getString("textField_mt82p097"));
-        assertEquals("\u660e\u78ca", formData.getString("selectField_mso1em48"));
+        assertEquals("Configured Company", formData.getString("selectField_mso1em48"));
+        assertEquals(Collections.singletonList("configured-dept-001"), formData.getJSONArray("departmentSelectField_msh186ry"));
+        assertEquals(Arrays.asList("applicant-first-001", "applicant-first-002"), formData.getJSONArray("employeeField_mt6thsdh"));
+        assertEquals(Collections.singletonList("applicant-second-001"), formData.getJSONArray("employeeField_mt6thsdi"));
+        assertEquals(Collections.singletonList("applicant-third-001"), formData.getJSONArray("employeeField_mt6v6alx"));
+        assertEquals(Collections.singletonList("marketing-first-001"), formData.getJSONArray("employeeField_mt8162rn"));
         assertEquals("dingtalk-user-001", formData.getJSONArray("employeeField_msh186rr").getString(0));
         // 表头变更事件、附件、已到物料区无 ERP 字段,推送时不填
         assertNull(formData.get("selectField_mt8747pv"));
@@ -200,7 +213,8 @@ class Axmt510FormPushHandlerTest {
         request.setMainData(mainData);
         request.setDetailData(Collections.emptyMap());
 
-        Axmt510FormPushHandler handler = new Axmt510FormPushHandler(yidaClient, ddConf, applications);
+        Axmt510FormPushHandler handler = new Axmt510FormPushHandler(yidaClient, ddConf, applications,
+                new LocalFormDepartmentEnricher(mock(MingleiDocumentService.class)));
         assertThrows(IllegalArgumentException.class, () -> handler.push(request));
     }
 }

+ 29 - 0
src/test/java/com/malk/minglei/service/impl/yida/FormDepartmentTestSupport.java

@@ -0,0 +1,29 @@
+package com.malk.minglei.service.impl.yida;
+
+import com.malk.minglei.service.yida.MingleiDocumentService;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+final class FormDepartmentTestSupport {
+
+    private FormDepartmentTestSupport() {
+    }
+
+    static MingleiDocumentService configuredDocumentService(String userId) {
+        MingleiDocumentService documentService = mock(MingleiDocumentService.class);
+        Map<String, Object> configuration = new LinkedHashMap<String, Object>();
+        configuration.put("departmentId", "configured-dept-001");
+        configuration.put("company", "Configured Company");
+        configuration.put("firstLevelManagerUserIds", Arrays.asList("applicant-first-001", "applicant-first-002"));
+        configuration.put("secondLevelManagerUserIds", Collections.singletonList("applicant-second-001"));
+        configuration.put("thirdLevelManagerUserIds", Collections.singletonList("applicant-third-001"));
+        when(documentService.queryApplicantDepartmentConfiguration(userId)).thenReturn(configuration);
+        return documentService;
+    }
+}

+ 40 - 0
src/test/java/com/malk/minglei/service/impl/yida/LocalFormDepartmentEnricherTest.java

@@ -0,0 +1,40 @@
+package com.malk.minglei.service.impl.yida;
+
+import com.malk.minglei.service.yida.MingleiDocumentService;
+import org.junit.jupiter.api.Test;
+
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+class LocalFormDepartmentEnricherTest {
+
+    @Test
+    void emptyConfigurationRemovesStaleManagedFieldsAndPreservesBusinessData() {
+        MingleiDocumentService documentService = mock(MingleiDocumentService.class);
+        when(documentService.queryApplicantDepartmentConfiguration("applicant-001"))
+                .thenReturn(Collections.emptyMap());
+        when(documentService.queryDepartmentManagersByDepartmentId("972685113"))
+                .thenReturn(Collections.emptyMap());
+        Map<String, Object> formData = new LinkedHashMap<String, Object>();
+        formData.put("textField_mu1z5kaf", "ERP Company");
+        formData.put("selectField_mso1em48", "ERP Company");
+        formData.put("departmentSelectField_msh186ry", Collections.singletonList("erp-dept"));
+        formData.put("employeeField_mt6thsdh", Collections.singletonList("stale-first"));
+        formData.put("employeeField_mt6thsdi", Collections.singletonList("stale-second"));
+        formData.put("employeeField_mt6v6alx", Collections.singletonList("stale-third"));
+        formData.put("employeeField_mtqwsyjz", Collections.singletonList("stale-logistics"));
+        formData.put("textField_msy7cb7z", "WO-001");
+
+        LocalFormDepartmentEnricher enricher = new LocalFormDepartmentEnricher(documentService);
+        assertDoesNotThrow(() -> enricher.fill("FORM-40D6FBBBF4A94864A2AF9535AAC7924CRBH2",
+                "applicant-001", formData));
+
+        assertEquals(Collections.singletonMap("textField_msy7cb7z", "WO-001"), formData);
+    }
+}

+ 10 - 3
src/test/java/com/malk/minglei/service/impl/yida/MiscReceiptIssueFormPushHandlerTest.java

@@ -5,12 +5,14 @@ import com.alibaba.fastjson.JSONObject;
 import com.malk.minglei.config.YidaApplicationsProperties;
 import com.malk.minglei.dto.ErpYidaPushMainData;
 import com.malk.minglei.dto.ErpYidaPushRequest;
+import com.malk.minglei.service.yida.MingleiDocumentService;
 import com.malk.minglei.service.yida.YidaProcessOpenApiClient;
 import com.malk.server.dingtalk.DDR_New;
 import com.malk.server.dingtalk.DDConf;
 import org.junit.jupiter.api.Test;
 import org.mockito.ArgumentCaptor;
 
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.LinkedHashMap;
 import java.util.Map;
@@ -82,7 +84,9 @@ class MiscReceiptIssueFormPushHandlerTest {
         request.setMainData(mainData);
         request.setDetailData(detailData);
 
-        MiscReceiptIssueFormPushHandler handler = new MiscReceiptIssueFormPushHandler(yidaClient, ddConf, applications);
+        MingleiDocumentService documentService = FormDepartmentTestSupport.configuredDocumentService("41603502201288023");
+        MiscReceiptIssueFormPushHandler handler = new MiscReceiptIssueFormPushHandler(yidaClient, ddConf, applications,
+                new LocalFormDepartmentEnricher(documentService));
 
         assertEquals("process-instance-1", handler.push(request));
 
@@ -101,8 +105,11 @@ class MiscReceiptIssueFormPushHandlerTest {
         assertEquals("miscReceiptIssue-MS-001", formData.getString("textField_msh27unu"));
         assertEquals("miscReceiptIssue-MS-001", formData.getString("textField_mspcpz92"));
         assertEquals("41603502201288023", formData.getJSONArray("employeeField_msh186rr").getString(0));
-        assertEquals("ML", formData.getString("selectField_mso1em48"));
-        assertEquals("dept-001", formData.getJSONArray("departmentSelectField_msh186ry").getString(0));
+        assertEquals("Configured Company", formData.getString("selectField_mso1em48"));
+        assertEquals(Collections.singletonList("configured-dept-001"), formData.getJSONArray("departmentSelectField_msh186ry"));
+        assertEquals(Arrays.asList("applicant-first-001", "applicant-first-002"), formData.getJSONArray("employeeField_mtjp3e58"));
+        assertEquals(Collections.singletonList("applicant-second-001"), formData.getJSONArray("employeeField_mtjp3e59"));
+        assertEquals(Collections.singletonList("applicant-third-001"), formData.getJSONArray("employeeField_mvylqnek"));
         assertEquals(Long.valueOf(1789401600000L), formData.getLong("dateField_msh186rs"));
         assertEquals("ERP", formData.getString("textField_mt7zi4fy"));
         assertEquals("applicant-001", formData.getString("textField_mt7zi4g0"));