ht 7c82ec364a 接口对接 4 dagar sedan
..
.mvn 56d0bf3d58 feat: add mjava-minglei project 1 vecka sedan
src 7c82ec364a 接口对接 4 dagar sedan
.gitignore 56d0bf3d58 feat: add mjava-minglei project 1 vecka sedan
ERP-YIDA-PUSH-API.md e5e7a12eb3 接口对接 5 dagar sedan
README.md 7c82ec364a 接口对接 4 dagar sedan
pom.xml e5e7a12eb3 接口对接 5 dagar sedan

README.md

mjava-minglei

明磊业务集成服务。项目基于 Spring Boot 2.7 构建,用于对接钉钉、宜搭、员工花名册以及明磊外部 T100 接口。

本文档说明当前工程的模块边界、配置项、REST 接口、ERP 推送规则和本地构建方式。文档中的凭证均使用占位符,真实密钥必须通过环境变量或部署配置注入。

1. 技术栈

技术 说明
Java JDK 8
Spring Boot 2.7.18
Spring MVC REST Controller、参数绑定、异常处理
Spring Validation 请求参数校验
Maven 构建和依赖管理
com.malk:mjava 钉钉、宜搭客户端和基础模型,当前版本 0.0.3
Jackson / Fastjson JSON 绑定、序列化和表单字段组装
RestTemplate 调用外部 T100 HTTP 接口
Logback + SLF4J 应用日志、错误日志和请求响应日志
JUnit 5 + Mockito 单元测试

2. 工程结构

src/main/java/com/malk/minglei
|-- MjavaMingleiApplication.java
|-- config
|   |-- DingTalkRosterConfiguration.java
|   |-- EmployeeRosterConfiguration.java
|   |-- EmployeeRosterProperties.java
|   |-- HttpRequestResponseLoggingFilter.java
|   |-- MingleiPortConfiguration.java
|   |-- MingleiPortProperties.java
|   |-- MjavaYidaConfiguration.java
|   `-- YidaApplicationsProperties.java
|-- controller
|   |-- EmployeeRosterController.java
|   |-- ErpYidaPushController.java
|   |-- GlobalExceptionHandler.java
|   |-- MingleiPortController.java
|   `-- YidaProcessController.java
|-- dto
`-- service
    |-- employee
    |-- port
    |-- yida
    `-- impl
        |-- employee
        |-- port
        `-- yida

2.1 分层职责

层级 职责
controller 暴露 HTTP 接口,处理请求校验和响应包装
dto 请求体、响应体和业务数据模型
service.employee 员工花名册同步、查询和钉钉人员数据处理
service.port 明磊外部 T100 接口转发
service.yida 宜搭流程、宜搭表单查询、ERP 推送分发
service.impl.* 各业务实现、处理器和内部辅助类

新增能力时优先放入现有业务域。只有出现清晰的新业务边界、独立生命周期或独立外部依赖时,才新增新的 Service 分类。

3. 配置说明

配置文件位于 src/main/resources/application.yml。生产环境不要使用文件中的默认示例值,应通过环境变量覆盖。

配置项 环境变量 用途
server.port SERVER_PORT HTTP 服务端口
spring.profiles.active SPRING_PROFILES_ACTIVE Spring Profile
dingtalk.agent-id DINGTALK_AGENT_ID 钉钉应用 AgentId
dingtalk.app-key DINGTALK_APP_KEY 钉钉应用 Key
dingtalk.app-secret DINGTALK_APP_SECRET 钉钉应用 Secret
minglei.yida.coordination-office.app-type YIDA_COORDINATION_OFFICE_APP_TYPE 协同办公宜搭应用编码
minglei.yida.coordination-office.system-token YIDA_COORDINATION_OFFICE_SYSTEM_TOKEN 协同办公宜搭应用 System Token
minglei.yida.master-data.app-type YIDA_MASTER_DATA_APP_TYPE 主数据宜搭应用编码
minglei.yida.master-data.system-token YIDA_MASTER_DATA_SYSTEM_TOKEN 主数据宜搭应用 System Token
minglei.port.supplier-price-approval-url MINGLEI_SUPPLIER_PRICE_APPROVAL_URL 外部 T100 接口地址
minglei.port.supplier-price-approval-key MINGLEI_SUPPLIER_PRICE_APPROVAL_KEY 外部 T100 接口接入密钥
minglei.employee-roster.datasource.url MINGLEI_EMPLOYEE_ROSTER_DATASOURCE_URL 员工花名册 MySQL JDBC 地址
minglei.employee-roster.datasource.username MINGLEI_EMPLOYEE_ROSTER_DATASOURCE_USERNAME 员工花名册数据库用户名
minglei.employee-roster.datasource.password MINGLEI_EMPLOYEE_ROSTER_DATASOURCE_PASSWORD 员工花名册数据库密码
minglei.employee-roster.datasource.driver-class-name MINGLEI_EMPLOYEE_ROSTER_DATASOURCE_DRIVER_CLASS_NAME JDBC 驱动类
logging.file.path LOGGING_FILE_PATH 日志输出目录

MjavaYidaConfiguration 注册两套宜搭客户端:

Bean 用途
coordinationOfficeYidaClient 协同办公应用,主要用于发起流程
masterDataYidaClient 主数据应用,主要用于查询主数据表单

4. REST 接口

4.1 宜搭流程发起

POST /api/yida/process-instances
Content-Type: application/json

请求示例:

{
  "type": "cpmp402",
  "userId": "41603502201288023",
  "dataTitle": "包材核价单",
  "fields": {
    "mainData": {
      "rq": "2026-09-08",
      "bm": "ML07000000",
      "tjr": "3075",
      "gs": "ML",
      "t100id": "ML",
      "ent": "87",
      "t100bm": "ML07000000"
    },
    "detailData": {
      "detailData": [
        {
          "hjdh": "MLCH326090800001",
          "gysbh": "113009",
          "gysmc": "供应商名称",
          "t100id": "ML",
          "ent": "87",
          "yy": "zh_CN"
        }
      ]
    }
  }
}

成功响应为 HTTP 201 Created

{
  "code": 200,
  "isSuccess": true,
  "result": {
    "processInstanceId": "process-instance-id"
  }
}

4.2 宜搭主数据表单查询

分页查询:

GET /api/yida/minglei/forms/instances?page=1&size=20

精确查询:

POST /api/yida/minglei/forms/instances/query
Content-Type: application/json

请求示例:

{
  "dept_id": "123456",
  "user_id": "dingTalkUserId",
  "dept_name": "明磊锂能技术部"
}

精确查询优先级为 dept_iduser_iddept_name。传入 user_id 时,服务端会先查询人员所属部门,再按部门 ID 查询主数据。

4.3 部门成员查询

POST /api/yida/minglei/departments/users
Content-Type: application/json

请求示例:

{
  "dept_Id": "123456,234567",
  "type": 0
}

dept_Id 支持单个部门 ID,或多个以英文逗号分隔的部门 ID;返回结果为各部门查询范围内人员的去重合集。

type 取值:

说明
0 查询指定部门和所有子部门
1 仅查询指定部门

4.4 员工花名册

同步指定部门:

POST /api/yida/minglei/employee-roster/sync?departmentId=1&type=0

全量同步:

POST /api/yida/minglei/employee-roster/sync-full

按钉钉用户 ID 查询花名册:

POST /api/yida/minglei/employee-roster/getUserRoster
Content-Type: application/json

4.5 外部 T100 接口转发

POST /api/minglei/ports/supplier-price-approvals
Content-Type: application/json

请求体只需要提供 headdetail,服务端会补齐外部接口协议固定字段。

{
  "head": {
    "pmdidocno": "CH3",
    "pmdi001": "N",
    "pmdi034": "605188",
    "pmdidocdt": "2026-08-06"
  },
  "detail": [
    {
      "pmdj011": "0.5000",
      "pmdj002": "524000059517022000000"
    }
  ]
}

4.6 ERP 推送宜搭

POST /api/erp/yida/push
Content-Type: application/json

请求示例:

{
  "type": "axmt140",
  "mainData": {
    "rq": "2026-09-08",
    "bm": "123456",
    "tjr": "3075",
    "gs": "ML"
  },
  "detailData": {
    "detailData1": [
      {
        "xmfyseq": "10",
        "xmfy002": "DN-001",
        "xmfy003": "2026-09-08",
        "xmfy004": "CUS-001",
        "pmaal004": "客户名称"
      }
    ]
  }
}

成功响应使用 McR.success()

{
  "success": true,
  "code": "200",
  "message": "SUCCESS"
}

5. ERP 推送规则

5.1 支持的类型

type 会去除首尾空格并转为大写后匹配,调用方传入大小写不敏感。

type 或别名 处理器 单据或流程 表单 UUID 流程编码
cpmp402 Cpmp402YidaProcessHandler 包材核价单 FORM-A3D4889187E54697A59590BE54F350E7AOO5 TPROC--98G66QB1NTF8E1R1LI0OK4D6JI9437HC92YSM1
FORM-4403B45A7F184CB79088FCDAFD2FD925LZ3K MlWorkOrderCraftPriceFormPushHandler ML-工单工艺工价审定 FORM-4403B45A7F184CB79088FCDAFD2FD925LZ3K TPROC--WG966BA1VWF8Q1K4OGF8H9KW47RR3ZREH0YSM2
axmt500 ApproveOrderFormPushHandler 客户订单审批 FORM-8454FA17732746058A2D90B1C559CC19G5SR TPROC--9VD66QA18AJ8317KK3NXM54W1HIT30C7N28TM7
axmt140 CustomerReleaseFormPushHandler 客户放行审批 FORM-3BA9FE18494F4FDD85FE6ABF7DE741BAE30C TPROC--6TG66381N8G8Y7L9GBEEY7QVXTUY2LBBGZ7TMU
cint301 MiscReceiptIssueFormPushHandler 杂收杂发审批 FORM-4B08ADABCDAA45788C043729A855E03ED76G TPROC--MQD66371C1N84FPSJZO4W79IN4BW2AE7I08TM0

5.2 mainData 规则

字段 说明
rq 申请日期,通常为 yyyy-MM-dd 或毫秒时间戳
bm 钉钉部门 ID
tjr 提交人工号,用于查询员工花名册并解析钉钉 userId
gs 公司或组织编码
t100id T100 业务标识
ent 地区或企业编号
t100bm T100 部门

顶层 bmgstjr 非空时,会覆盖写入 mainData。服务端会将 mainData 中的通用字段补入各明细行,便于表单处理器复用。

5.3 detailData 规则

detailData 外层必须是对象,内部至少包含一个数组字段。数组字段名支持:

  • detailData
  • detailData1
  • detailData2
  • 其他满足 detailData\d* 格式的字段

不同单据的约定:

类型 明细字段
cpmp402 detailData
FORM-4403B45A7F184CB79088FCDAFD2FD925LZ3K detailData
axmt500 detailData1detailData2,兼容历史 detailData
axmt140 优先 detailData1,缺失时回退到 detailData
cint301 detailData1

明细对象中可以直接传入宜搭 fieldId。服务端会保留包含 Field_ 的字段值,用于补充默认字段映射。

5.4 发起人解析

  1. ErpYidaPushServiceImpl 优先使用顶层 tjr,其次使用 mainData.tjr
  2. 服务端通过员工花名册查询工号对应的 dingtalkId
  3. dingtalkId 会作为 originatorUserIduserIdapplicant 写入请求上下文或明细行。
  4. 匹配到 YidaFormPushHandler 时,提交人工号允许为空,具体处理器可以使用默认发起人兜底。
  5. 未匹配到表单处理器并走通用 YidaProcessService 时,提交人工号不能为空。

6. 日志和异常

6.1 日志

Logback 输出:

  • 控制台日志。
  • ${LOGGING_FILE_PATH}/application.log
  • ${LOGGING_FILE_PATH}/error.log
  • archive 目录下的滚动归档日志。

HttpRequestResponseLoggingFilter 会记录 HTTP 方法、URI、状态码、耗时、请求体和响应体。单个载荷最大记录 10KB,并对 passwordsecrettokenauthorizationaccessTokensystemTokenkey 等字段脱敏。

6.2 异常响应

场景 HTTP 状态码 说明
请求体格式错误或参数校验失败 400 请求不合法
配置缺失 412 必要配置未提供
宜搭或钉钉上游业务错误 502 返回上游错误码和错误信息
外部 T100 调用失败 502 返回 MINGLEI_PORT_CALL_FAILED

7. 构建和运行

环境要求:

  • JDK 8
  • Maven 3.6+
  • 可访问项目依赖仓库和内部 malk 依赖

本地构建:

mvn clean package

本地运行:

$env:SERVER_PORT = "8080"
$env:DINGTALK_APP_KEY = "<dingTalk-app-key>"
$env:DINGTALK_APP_SECRET = "<dingTalk-app-secret>"
$env:YIDA_COORDINATION_OFFICE_APP_TYPE = "<coordination-office-app-type>"
$env:YIDA_COORDINATION_OFFICE_SYSTEM_TOKEN = "<coordination-office-system-token>"
$env:YIDA_MASTER_DATA_APP_TYPE = "<master-data-app-type>"
$env:YIDA_MASTER_DATA_SYSTEM_TOKEN = "<master-data-system-token>"

mvn spring-boot:run

运行打包产物:

java -jar target\mjava-minglei-1.0.0-SNAPSHOT.jar

8. 测试

执行完整测试:

mvn clean test

当前测试覆盖:

  • Spring Boot 上下文加载。
  • Controller 请求和响应结构。
  • 员工花名册同步、查询和字段提取。
  • 宜搭流程处理器分发。
  • ERP 推送到不同宜搭表单处理器的字段映射。
  • 外部 T100 请求组装和响应转发。

当前验证结果:

Tests run: 30, Failures: 0, Errors: 0, Skipped: 1

9. 扩展规范

9.1 新增宜搭流程处理器

新增可由 /api/yida/process-instances 触发的通用流程时:

  1. 新建 XxxYidaProcessHandler
  2. 实现 YidaProcessHandler
  3. getType() 返回业务路由编码。
  4. 在处理器中维护表单 UUID、流程编码和字段映射。
  5. 补充对应单元测试。
  6. 更新 README 的支持类型说明。

9.2 新增 ERP 表单推送处理器

新增可由 /api/erp/yida/push 路由的表单流程时:

  1. 新建 XxxFormPushHandler
  2. 实现 YidaFormPushHandler
  3. getTypes() 返回主 type 和必要别名。
  4. 在处理器中维护表单 UUID、流程编码和字段映射。
  5. src/test/java 中补充字段映射和异常测试。
  6. 更新 README 的 ERP 推送类型表。

9.3 字段映射原则

  • 业务 type 是路由键,不等于表单 UUID。
  • 应用凭证、表单 UUID、流程编码由服务端维护,调用方不传。
  • 表单处理器优先使用 ERP 原始字段名映射。
  • 调用方确需补充时,可以传入宜搭 fieldId 字段。
  • 不要在日志、文档或测试数据中写入真实密钥、Token、Cookie 或数据库密码。

10. 运维注意事项

  • 部署账号必须对 LOGGING_FILE_PATH 有写权限。
  • 宜搭和钉钉接口所需的网络连通性、权限范围、组织数据权限由部署环境保证。
  • 当前 Controller 未内置业务鉴权。如需访问控制,应在网关或统一认证层配置。
  • 发生宜搭配置不匹配时,确认应用编码、System Token 和处理器选择的客户端属于同一应用。
  • 员工花名册依赖数据库连接和数据完整性。若 mainData.tjr 无法解析,优先检查花名册同步状态和员工 dingtalkId