明磊中间键代码仓库

admin 6978288fb0 feat: aqct300 补编号翻译与检验员映射,并增加订单项次字典与双斜杠过滤 3 days ago
.mvn db8939c1db chore: sync minglei project 1 month ago
sql 7425adce51 接口开发10.30 6 days ago
src 6978288fb0 feat: aqct300 补编号翻译与检验员映射,并增加订单项次字典与双斜杠过滤 3 days ago
.gitignore db8939c1db chore: sync minglei project 1 month ago
DATA-DICTIONARY-API.md 6978288fb0 feat: aqct300 补编号翻译与检验员映射,并增加订单项次字典与双斜杠过滤 3 days ago
ERP-YIDA-PUSH-API.md 0005c8062f 接口开发10.30 6 days ago
README.md af3c6d477e test: 补充见知制单账户类型说明和透传验证 3 days ago
SKILL.md be33582068 lzq-1 1 month ago
pom.xml 17338c8d8f fix: 杂收发改为 aint302,并修复花名册银行字段合并重复 4 days ago

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;该文件保留本地和测试环境的 ERP/T100 默认值。ERP/T100 环境配置位于 application-test.yml 与 application-prod.yml,其中生产配置会覆盖基础默认值。默认启用 test Profile,生产部署必须设置 SPRING_PROFILES_ACTIVE=prod。为兼容原有本地启动配置,显式启用 dev Profile 时会自动同时启用 test Profile。

配置项 环境变量 用途
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.coordination-office.process-instance-query-user-id YIDA_COORDINATION_OFFICE_PROCESS_INSTANCE_QUERY_USER_ID 查询宜搭流程实例时使用的钉钉用户 ID
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.erp-t100.request.service-id - T100 报文 service.id;测试为 toptst,生产为 topprd
minglei.erp-t100.request.default-ent-id - T100 报文 datakey.EntId;测试为 87,生产为 86
minglei.erp-t100.enterprise-code-by-alias - 企业别名映射;测试“明磊/国内”->87,生产->86,“越南”->60
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 宜搭数据查询

流程实例查询

按流程实例 ID 查询宜搭实例数据:

GET /api/yida/process-instances/{processInstanceId}

服务端使用协同办公宜搭应用的配置查询实例,并以统一响应结构返回宜搭原始实例数据。

主数据表单查询

分页查询:

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_id、user_id、dept_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

响应体的 result 包含花名册基础信息和银行信息:

{
  "employeeNo": "2601010001",
  "username": "张三",
  "bank_card_no": "6222000000000000",
  "bank_name": "示例银行"
}

bank_card_no 为银行卡号,bank_name 为开户行名称。

4.5 外部 T100 接口转发

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

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

{
  "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"
}

4.7 见知单笔支付制单

以下 POST 接口的 JSON 请求体均支持 toAccountType:

  • /api/banking/payments
  • /api/v2/payment/commonPay(制单接口别名)
  • /api/banking/payments/submit-and-query-status(制单后查询支付状态)
字段 类型 是否必传 说明
toAccountType String 否 "0" 对公账号,"1" 对私账号;未传、null、空字符串或纯空格时默认 "0"

对私制单请求示例:

{
  "businessTransNo": "PAY-EXAMPLE-001",
  "payAmount": 1.00,
  "fromAccountNo": "<付款账号>",
  "fromAccountName": "<付款户名>",
  "toAccountNo": "<收款账号>",
  "toAccountName": "<收款户名>",
  "toAccountType": "1",
  "toBankName": "<收款开户行全称>"
}

服务端将最终账户类型以字符串形式写入见知 /api/v2/payment/commonPay 报文;开启国密加密时,该字段包含在加密、签名的支付报文中。

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
aint302 MiscReceiptIssueFormPushHandler 杂收杂发审批 FORM-4B08ADABCDAA45788C043729A855E03ED76G TPROC--MQD66371C1N84FPSJZO4W79IN4BW2AE7I08TM0

5.2 mainData 规则

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

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

5.3 detailData 规则

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

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

不同单据的约定:

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

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

5.4 发起人解析

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

6. 日志和异常

6.1 日志

/api/dictionary 数据字典查询接口不记录请求/响应访问日志,避免高频查询占用应用日志;接口异常仍按原有异常处理链路记录。

Logback 输出:

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

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

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。